与代码结缘
小时候,看见邻居哥哥在玩电脑,那时候我觉得,能控制电脑,让它乖乖服从自己的指令,是一件太酷的事情。但由于各种原因,我错过了几次学编程的机会,因此我特别羡慕那些有条件学编程的同学。
上大学后,虽然没能进入计算机系,但我们系的课程有部分涉及编码。拿到第一张课表,看到“程序设计语言”这门课时,我感觉我的眼睛都在发光。终于能有机会接触代码,我激动不已,还没等到开课,我就自学看完了第一章 。还跑去机房捣鼓“Hello world”,从此我就走上了垒码的“不归路”。
大一的暑假,我从图书馆带了一本《高质量C++编程指南》回家,这本书算是我代码生涯里里程碑意义的一本书。到今天我能清晰地记得,当时我躲在屋子里一口气看完了它,虽然当时房间开着空调,但我居然出了一身的汗。那是我第一次意识到,原来自己对于写代码的认识和理解是那么浅显。也就是在那个暑假,我的生活开始和代码绑在一起,一个“代码狂热爱好者”开始诞生了。
再开学的时候,我带着满腔热情继续投入到编程课中。老师在课上特地强调了我们的校训——“止于至善”。但那时的我,并没能理解这句话的深意。
努力,是主动找的辛苦
程序员这个行业中,女生并不多。许多人会带着“有色眼镜”看待女程序员,觉得女生不靠谱。我刚参加工作的时候,分到的也总是一些边边角角的工作,并没有太多的技术含量。那个时候的我作为新人,尽力把自己的姿态放低,我常常安慰自己说,本来我也不熟悉系统,这样的工作正好能让我有时间上手,况且这些有缺陷的模块,也确实是需要有人来完善的。所以虽然有些不服气,但我并没有抱怨,一心想着要努力做好分给我的工作。
大家都说女生做程序员太辛苦,而我始终觉得,任何工作都是辛苦的。在工作面前,性别是第二位的,我从来不认为女生应该得到一些特别的优待。而事实也证明,当我真的完美地完成任务之后,有色眼镜也就自然消失了,别人不会再强调我的性别,不会再因为我是女生而不信任我的能力。所谓的“行业性别歧视”的问题,就这样被我克服了。
工作一年后,我进入一个新的项目,开始负责一个独立模块。老代码到手时才发现这是Demo版的“神级代码”——只有堆砌的功能,没有任何容错设计,一点风吹草动就可能直接罢工。但偏偏这还是个底层模块,一出问题,整个设备都不转了。
我就像个救火队员,不是在测试部查问题,就是在去测试部的路上。历经了三个多月的扑腾,我逐渐熟悉了新模块的业务流程,对其依赖的底层系统也有了较为深入的认识。代码一天天稳定下来,问题单也收敛了,但我实在不能忍受日复一日地在没有良好设计的代码上打补丁,特别是新功能加入时,牵一发而动全身。于是我做了个很大胆的决定,进行重构。
很幸运,我得到了主管的支持,他告诉我:“如果想做,就放开手去做,模块交给你就是希望你把它给改造好。”我梳理了整个模块的业务流程,保留了所有对外接口。然后,按模块的基本功能进行子模块分层,各个层次相互之间不再干扰。特别是把复杂错乱的状态机抽象成表,避免了大量的重复逻辑判断,阅读主体代码时看到的只有清晰的业务逻辑。
就这样,我一边维护老代码,一边自己挤时间去独立完成自己的想法。重构完成时已经是版本交付的关键阶段,我的主管顶住了版本的巨大压力,力排众议坚持将我重构后的代码合入主线。代码也相当争气,在后续需求不断的情况下,两年里仅仅收到三张问题单。经过这次改造,我收获了一个拥有良好架构的模块,极大提高了后期工作的幸福感,同时也收获了一个让我受益至今的感悟:个人成长取决于做了多少重要却不紧急的事。而所谓努力,是指主动找的辛苦,如果不是主动找的,再多加班再多通宵也是没有意义的。
写得又好又快的秘诀
后来我负责了三个模块,看到隔壁组做的一个内部实现不错,就想借鉴一下,于是,问题来了。这三个模块中有一部分近似功能代码,但每个模块都有自己的一套实现和接口。一旦代码变更,就需要修改三处,这样很容易发生修改遗漏,如果后续还有其他模块需要这种功能,又要重复再去造轮子。这正是我这种“懒惰”的程序员最害怕的事情。
是拷贝粘贴快速上版本,还是一劳永逸地解决问题?我选择后者。当时的系统中没有类似的公共机制可以提供接口,我希望能够实现一个。这样不仅能自己栽树,也可以让后人承荫。虽然自己的第一个公共库的需求很简单,但我在借鉴了一些优秀公共库的想法后还是花了足足两天时间进行设计,代码也是写的无比小心,虽然简单但在版本中收到的效果却非常好。
对于程序员来说,工作的最大困难莫过于需求不断在改变。我多少是有一些“代码洁癖”的,写的不好的代码,自己会看不下去。熟悉我的同事们也经常会拿我这种不断持续优化代码的行为开玩笑,戏谑地称我是“又在那儿绣花呢”。但我认为,代码一定是要好好写的。
我所理解的“写得又好又快 ”,其实是在工程进度和代码质量两者之间进行平衡。
在同样的项目预期时间内,有些人习惯很快地写好代码,自然难避免错误会比较多,后期调试时间会很长;而写代码之前的我仿佛是站在岔路口,会先想想选哪条路能走的更好,想好架构和设计之后,再去做。我会更倾向于花费更多的时间在最初的代码上,尽量减少错误和修改,缩短后期调试时间。
因为对于工程来讲,也有一个“二八法则”,一旦越过了那条线,重新优化代码的成本会高很多。所以从总时长上来看,我的方法往往是看起来“慢”,但其实是更“快”一筹。
多思考,才能提高工作效率
我记得我的师父曾经送给我一段话:“工作中有很多问题,不要抱怨,尝试解决它。你不去解决它,换个环境你还是会遇到。怎么提高工作效率,如何尽量做到自动化,把我们从重复的工作中解脱出来,这些都是值得考虑的事情。所以不满足于现状,多思考,才能把手头的事情做得更好。”这段话我一直铭记在心,自己也一直在不断思考的路上。
2016年6月,我参与了红隼行动(即为比利时电信SIMBA项目,是Satellite虚拟接入创新方案的首个应用局点,是在城域实现竞争力突破的关键解决方案)。从前的我更像是一个“接锅侠”,一直在完善做到一半或者出现问题的项目。但从这一次项目开始,我第一次参与到带人做方案的全过程里,整个人都很兴奋,也收获和成长了很多。
当时前方业务要求某特性能够支持双机热备,虽然这项功能在我们系统已经有了,但能够实现的业务并不多。如果按照原来模块的交付要求,操作困难复杂,不仅时间上来不及,质量上也很难把握。面临这样挑战,师傅的话又一次在我心里重复着,“多思考,想想如何减少重复工作”。于是我和项目经理一起立下决断,把双机热备的功能抽象出来,做一套框架。
框架做好之后,我没有等到上设备的时候才去测试性能,而是在本地模拟环境上,用自己的数据库和小工具构建了大业务量的场景,进行自测。而测试结果却让我大跌眼镜。原本希望在20秒内传完的80M数据,用了10分钟才完成。我觉得这太不科学了,怎么会这么慢?问题到底出在哪儿呢?
我开始分析可能原因并逐个测试和排除,但令人奇怪的是,修改后的性能竟然还轻微下降了。虽然百思不得其解,但我不甘心,就和这个问题杠上了,我知道如果现在不解决,以后还是会出问题。我把数据传输过程中达到每一个点的时间都记录下来,看究竟是哪里卡慢了速度。之后终于发现,原来不是发射端和接收端的代码有问题,而是中间过程我们用的基准版本里面某个模块有问题,导致问题发生。
这个问题解决之后,自测也自然有了满意的结果。代码上线后至今主线零问题,成为DU部门首个零缺陷上车的标杆项目。而我也凭借着贡献的公共库代码,获得2016年固网金码奖。
我常常觉得,如果能够把重复的东西抽取出来重构,不去做重复的事情,才有可能达到代码零增长甚至负增长,做个有心人,勤于思考,就能够提高工作效率。这一次的双机热备框架完成,不仅高质量,而且也为后续上车的双机热备特性提供了层次化的公共库。很多需要实现这个功能的业务,都不必再写那么多代码,可以直接拿这套框架去用了。
我是一个很容易有小小自我满足感的程序员,自己做的东西能按照预期去进行,就会觉得满意。而如果能够通过我的工作和思考,最终减少了其他程序员的工作量,我内心就会有满满的成就感。
不忘初心,止于至善
数年后再回首,我才慢慢体会到自己大学的编程课中,老师提到的“止于至善”这四个字中包含了太多的真谛。
在工作最开始的几年中我都是以最挑剔的眼光来看待自己的代码:我曾经花十多分钟去纠结一个函数的命名,只为恰到好处;也曾一旦发现代码有可能腐化,就尽快进行重构,直到自己觉得已经到了极致,才可以暂时停下对这段代码的修改。再后来,我在设计的时候慢慢懂得,不去过分追求某一个方面的极致,而是更多地考虑各个维度的合理权衡,现在,我也有意识地在软件设计和编码中去思考和体会妥协和灰度的艺术,做到合理地取舍。
每当我看到自己从前的代码,都会感慨:“天啊,我当时怎么会把代码写成这个鬼样子?”这时慢慢地就能体会到,老师说的至善和完美都取决于我经验和视野的不断提升。
加入华为的五年以来,不论是获得金码奖,还是软件王,这些称号和光环一方面来说是对我努力工作的肯定,但另一方面更是在时刻提醒着我“不要因为走得太远,而忘记为什么出发。”因为人并不是仅仅在寻求结果,如果只是为了寻求结果,人很容易选择走捷径。而在走捷径的过程中,就很容易迷失真实,甚至连满腔的热忱也会逐渐丧失。我认为真正重要的是追求真实的意志,只要有了这种向真实前进的意志,即使这次失败了,我们终将会达到终点。
我自认为不算聪明,性格也相对木讷。要说优点,那就是对编码的热爱,以及热爱所带来的执着。我一直认为,把兴趣作为职业,往往是挫败感会远多于成就感。但无论怎么沮丧,在地上打几个滚又爬起来,支撑自己一直坚持走下去的正是兴趣带来的热爱。
我的内心深处依然住着那个希望能控制电脑的小女孩,仍然分分秒秒都在憧憬着有朝一日能搞定一个大型系统。
我不太清楚幸福究竟是什么,但入行数年,每天醒来我仍对工作充满热情。我相信,把这个兴趣当做职业,是正确的选择。
本文来自《华为人》,原创: 曹璐。
本页共39段,4098个字符,12149 Byte(字节)