15 – 多读多练:如何提高编程水平?

内容纲要

课程:工程师个人发展指南
https://time.geekbang.org/column/article/759265

在软件工程领域中,编程水平是每位工程师的核心专业技能。这不仅是个体工作质效的代表,更是团队工作质效和产品质量的关键。我想你一定会认同这些观点,不过你可能会问了,提高编程水平有没有什么好的办法呢?

基于个人的成长经历,我总结为“多读多练”,下面让我用自己的经历来进一步解释这四个字。

胜任工作

1999 年我第一次成为软件开发工程师时,编程对于我来说还是相当手生的事,刚进到公司参与的软件项目,是用微软的 Visual C++,基于 MFC 框架,开发 Windows 操作系统上的一个变电站视频监控应用程序。在那之前,我根本没有商业软件的开发经验,也不知道什么是套接字、多线程、VxD 驱动、RS485 通讯、图像处理等。

好在进到公司时,那个视频监控软件的雏形已经有了。那段时间,我除了干好手头的工作,最大的精力花在阅读整个项目的源代码,掌握每个功能的具体程序实现。因为我开始的编程技能基本上是一张白纸,所以那段时期觉得个人的专业技能提高得特别快。

这段经历,我总结了提高编程水平的第一个方法——在完成日常工作任务之余,通过阅读整个软件项目的源代码来学习。这样做的好处,不只是学习新的编程知识,还能掌握整个软件项目的具体实现,当日常开发工作中碰到程序错误时,就更有查错思路。少了这样的知识储备,咱查起错来就难免低效,有时盲目试错还让人着急上火。

随着我掌握了整个软件项目的具体实现,我突然有了“慧眼”,发现那些代码写得相当乱,让人理解和维护起来相当困难,于是萌生了重写的想法。你听到这估计要会心一笑了,咱不都觉得别人写的代码烂吗!不过我的这一想法一开始没能得逞,直到我的主管觉得那些代码确实维护不动了,加上其他因素,我幸运地负责了整个软件项目的重写工作。

指责别人的代码写得差是容易的,产生重写的冲动也是自然的,当真刀实枪地干时,发现那个挑战还是很大的,毕竟这是我头一次负责项目。整个软件的架子怎么搭,大家如何分工以便齐头并进,项目的节奏如何把控,这些事都相当抽象,没那么容易。最后整个项目干下来,我后知后觉地发现,那其实是很好的一次锻炼,能力总是在我还没有准备好时的蹒跚中长出来的。头一次负责软件项目的经历,我总结了提高编程水平的第二个方法——别总在学的路上,编程水平是在挑战自己觉得驾驭不了的复杂任务中提高的。

话说,我不只是觉得别人写的代码乱,不时回头看自己写的也那感觉。不过我有一个很好的习惯,发现自己写得不满意就立即优化,大概率你也有我这样的经历。你发现了吗,优化自己以前写的代码,不仅能体会到自己的进步,还能起到夯实进步的作用。这样的工作习惯我不只是运用于编程中,还运用于工作中的其他方面,比如写文档。基于我的这一工作习惯,我总结了提高编程水平的第三个方法——别放过自己,通过持续优化自己写的代码,去看见和夯实自己的进步。

深挖与扩宽

2000 年时,所在的公司决定开发基于 AMD x86 处理器的嵌入式系统产品,我成了整个产品唯一的软件工程师,也从那时开始踏入了嵌入式软件开发领域。刚上手初期,要学的东西实在是太多了,而且都是英文资料。那时的主要学习素材有两大来源,一个是 AMD 官网所提供的处理器功能的各种示例小程序,另一个是 AMD 提供的处理器芯片使用手册和编程手册两本很厚的英文书。那时压力大也得硬上,因为活儿已经摆在那了。

一年下来,我有了移植操作系统、TCP/IP 协议栈、文件系统和编写 IDE 硬盘等各种硬件驱动的编程能力,所掌握软件技术的深度和广度有了质的进步。为此,我总结了提高编程水平的第四个方法——学习别只停留于应用软件层面,对底层技术理解得越深,越能驾驭抽象度高的技术。有些技术细节,即便知道了也就那么回事,但只要像窗户纸那样没有捅破,面对技术的不确定性就会胆怯,缺少“我一定能搞定”的霸气。

那一年所阅读的重要书籍,除了 AMD 提供的那两本大部头外,Minix 操作系统作者安德鲁·塔能鲍姆所著的《现代操作系统:原理与实现》和《TCP/IP 详解》的三卷,都是我精读并时常翻阅的。读书的同时,通过接触开源软件不仅打开了视野,还省下了很多重新造轮子的精力。比如,我所开发的嵌入式系统软件中,文件系统是从开源的 Minix 操作系统移植过来的,TCP/IP 协议栈是从开源的 Xinu 操作系统移植过来的,内核用的是 uC/OS 实时操作系统。

这就引出了我的提高编程水平的第五个方法——拥抱和借力开源软件,帮助自己打开编程视野的同时,还省去了从无到有的开发,省时又省力。

应对复杂度

2003 年我从自己服务过的第一家软件公司,跳槽到了通信行业的 UT 斯达康公司,从事企业级数字程控交换机的开发工作。刚进公司时,心气还是很高的,认为自己已玩转过整个操作系统,软件开发应当没什么难的了,可一开始工作就发现不是那么回事,意识到是自己飘了。

原因在于,通信行业的软件规模,至少高出我所接触过的两个数量级,规模越大意味着复杂度越高,对编程水平的要求也越高。这个觉醒让我有了提高编程水平的第六个方法——参与大规模软件的开发工作,才能更好地理解软件行业的复杂度,也越能锻炼自己的编程水平。

你可能会问,从事大规模软件的开发工作,锻炼的究竟是什么编程能力?好问题,我正要告诉你了。

那时的数字程控交换机使用的,是美国军方开源的 RTEMS 操作系统,它是一个类 Unix 的、非常完备的实时操作系统,软件规模远比我经历过的要大,应用软件需要使用到它的功能也丰富。基于这么一个操作系统上从事嵌入式软件开发工作,我发现要记住代码的整体流程光靠大脑是不够的,得借助 UML 这样的工具做笔记才行。

另外,通信产品有很多行业的标准通信协议要实现,开发工作不是个位数的人可以完成,在公司有很好的技术积累的情形下,还得几十号人才行,协作复杂度自然就更高。

还有,那时我注意到了 RTEMS 操作系统的类 Unix 设计,既简洁又优雅,有一天我突然问了自己一个问题,“为什么我不能设计出这么棒的系统?”我想正是这个问题,打开了我对软件设计之美的好奇与追求,不再只停留于“模块化,高内聚,低耦合”这精炼的九个字。

基于这些经历,我所总结出的提高编程水平的第七个方法是——通过工具、协作和软件设计来应对大规模软件的复杂度。

确保质效

2006 年我再一次跳槽,加入了摩托罗拉杭州研发中心。起初摩托罗拉外包给印度 Wipro 公司的软件项目,被转移到了我所在的团队,代码质量之糟糕让整个团队都感到痛苦。自然地,大胆的我又想到了通过重写软件让团队走出困境。

与当初在小公司重写一个软件所不同的是,在摩托罗拉这样的成熟企业想重写一个软件没那么简单。摆在我面前最重要的问题是,如何说服老板同意我重写,或者怎么让我的重写工作只带来好处而没有惊吓这类坏处。

为了解决这个问题,我认真将单元测试、静态分析、动态分析等质量保证方法运用到了重写工作中,并开始探索通过打造软件平台,帮助提升团队的工作质效。这块工作所积累的经验和形成的方法论,后来成了《专业嵌入式软件开发:全面走向高质高效编程》这本书中质量保证篇的核心内容。

这段经历带给了我提高编程水平的第八个方法——向工作方法论和软件开发平台要工作质效。

在提炼这八个方法时,我只是简单地罗列了几本书的名称,我担心给你带去误导,所以一定要和你说清楚。“多读多练”中的“读”和“练”,包含了代码与书籍,且两者应并重。

书籍与代码并重

不知你是否和我一样,认为编程是一门手艺,每位程序员都应是工匠。是工匠就意味着,编程不仅仅是一系列逻辑指令的排列组合,而是一种需要精心雕琢、细致打磨的艺术。正如工匠对待手艺那样,编程也要求工程师拥有对细节的专注,对质量的执着和不断追求软件设计之美的精神。当然,是工匠还意味着,工程师得有相应的行头,掌握各种有助于提高手艺的工具。

你可能会问,在提高编程水平的同时,如何更好地成为一名工匠呢?我认为,除了个人在代码层面的多读多练,另一个同样重要的是书籍层面的多读多练。

还记得我们在 11 讲中所聊到的知识管理吗?书籍是知识管理很重要的一种载体,是突破个人经历的局限性,跨越时间与空间,让同行们一起学习、探索和成长的好途径。

通过读书,我发现前人指出了我未曾思考过的问题,也碰到了与我一样让人困扰的现象并给出了解决的方法,当然还教会了我成为一名专业的工程师。

比如,《人月神话》告诉我们,1 个人 3 个月能干完的事,3 个人 1 个月是干不完的。这个场景在我们的日常项目管理中,是不是很熟悉?你身边的项目经理或主管,是不是还犯着这样的常识性错误呢?如果你打算说服他,根本不用费多少口舌,只要做简单的两个动作就行了。一,告诉他犯了行业的常识性错误;二,让他去读这本书。这就是读过这本书后,我们所收获的力量和底气。

同样是这本书,作者预言了软件行业在十年内,生产率不会有数量级的提高,这个预言如今依然成立,这就是软件行业内“没有银弹”这四个字所指。书中所提出的软件开发活动中的根本任务和次要任务,对于如今 AI 时代,程序员担心被 AI 替代这事,依然有很好的思考启发。

好书还有很多,《人件》《最后期限》《敏捷软件开发》《重构:改善既有代码的设计》《领域驱动设计精粹》《设计模式》《UNIX 编程艺术》《代码整洁之道》《程序员的自我修养》《代码大全 2》等等。

对于我来说,读书并不是一种负担,而是寻找知音、慰藉和导师的一种方法,让我在提高职业技能的道路上,从“野蛮人”变成了“文明人”。不知读书对于你又意味着什么呢?

总结时刻

是时候回顾和总结这一讲的要点了。这一讲我们共同探讨了如何提高编程水平这个话题。我基于自己的职业成长经历,总结了八个方法。虽然给出这八个方法时,我是基于自己的成长阶段的,但并不代表你也得按照我那样的成长阶段去发展。

别忘了,每个人的成长经历都是独一无二的,每个人的职业发展都是选择而非规划出来的。成为高水平的软件工程师有无数的路径,但殊途同归。为此,在日常工作中,你可以用这八个方法做对照,看自己做到了什么和要注意什么。

你注意到了吗?这八个方法的背后,都是基于做中学而来的。换句话说,提高编程水平,是学习与实践交织在一起的螺旋上升过程。

软件工程师的主要工作产物是代码,但耕耘出高质量的代码是需要有土壤的,除了从他人的代码中来,另一个同样重要的是从书籍中来。通过阅读书籍,能让我们在提升编程能力的道路上,得到前人的指引,站在他们的肩膀上更有质效地发展。

最后,我想请你思考,你有什么独特的提高编程水平的方法吗?期待你留言与我分享交流。

问答

一些技术细节,即便知道了也就那么回事,但只要像窗户纸那样没有捅破,面对技术的不确定性就会胆怯,缺少“我一定能搞定”的霸气。对这个深有体会,另外,如果没有深刻理解,过一段时间就会忘记,而深刻理解的东西,可能说一个关键字,立马就能想到xx是怎么回事。

关于深刻理解这一点,确实是,咱工程师就是喜欢原理、规则、定义什么的,而深刻理解其实是包含掌握这些内容的。另外,我在学习的过程中,总是想从根上知道为什么,所以有时得花大量的时间深入下去,直到自己觉得踏实为止,这个过程应当就是咱在学精学深的过程吧。

做技术也是需要有那些学习和解决问题的成功体验,这样能力强了胆子也就大了,霸气也就出来了。不是有“艺高则胆大”这话吗。

Leave a Comment

您的电子邮箱地址不会被公开。 必填项已用*标注

close
arrow_upward