程序员的“纪律性”

国庆节长假前后,我和很多业内外的朋友们展开了关于“码农”的大讨论,作为这些讨论的延伸,一篇叫做《从“码农”说起》的文章从脑海中输出,最终展现在 CSDN 官网上。在文章中,我主张年轻的技术人们不应该接受社会舆论强加的“码农”属性,自己做有创造力的事情,要相信付出和智慧一定有回报。此文一出,得到了很多朋友的批评指正,令我颇为欣喜,因为有互动才会有头脑风暴,进而产生更多的新想法。

回顾当时那场大讨论,其中很多观点其实值得深入探讨,比如在讨论中,一位名为“@不动如山_”的朋友是这么说的:

对于软件是不是劳动密集性产业,你认为怎样合理是一回事,现实如何是另一回事。作为老程序员,老 se,我参加过上千人的团队协作,数年的开发周期。所有创造性的工作在预研阶段就必须结束。一旦进入开发,就只有纪律,没有创新。当然,个别高科技产品的原型软件例外。

这席话给我很大触动,因为它触及了我进入 IT 行业之初时青涩经历的回忆。

多年前我刚刚加入的团队正在开发某个通信设备。有过开发通信设备的朋友们应该知道,其实嵌入式软件开发的技术核心是事件调度,因为通信设备总是处在繁忙的交换和命令事件处置的状态中,一个良好的事件调度机制是系统性能的灵魂,如果每次一个事件的到来都以新开一个线程的方式来应付,系统资源瞬间就会枯竭,设备也就崩溃了。

当时我们采用的是一种叫做 zebra 的架构,这是一个面向交换的开源项目,甚至有点像一个用户空间运行着的内核程序。

当时管理这个项目团队的项目经理正好是一个完全没有做过软件开发的职业文案写手,所以当主力开发人员把事件调度机制的框架整理完成之后,项目经理小眼滴溜溜一转,说道:“现在架构已经完成,下面就是大家分工,把各自的功能框架填充好了,我看了一下,一共有 19 个模块,大家分一下,一个模块每人一周时间……”

这时一个资深的程序员打断了他,资深程序员让大家每个人把手头做的东西做一下单元测试,声称下一周他会给我们一个好东西。

果然这位资深程序员拿出一周时间用脚本写成的工具,把所有原来的功能模块直接处理填充到 zebra 架构内。

每当我回忆这件事情的时候,想起外行项目经理的尴尬表情都会忍俊不禁。彼时的那位项目经理,其实也是一个年轻有为的人,但是对于软件开发的特点的确缺乏了解,想当然地以为自己抓抓纪律性就行,大家按部就班、出工出力就好。可是要知道如果真的按照他的计划,功能填充过程可能需要2-3 个月,况且数百万行规模的代码中隐藏的 Bug 又需要一个测试周期来捉虫。

我把这个故事讲给朋友们,有的朋友就问当时假如没有这个用脚本写成的工具又当如何?我就会反问,那么假如我们没有找到 zebra 架构又当如何?难不成要我们几个菜鸟来写调度机吗?软件编程,是一个能走捷径就一定要走捷径的工作——有现成的可重用或者可借鉴的东西一定要重用和借鉴的,这样工作水准和工作效率才可能有保证。有现成的东西不用,一定是万不得已;推倒重来,则一定是出现了重大问题;动不动喜欢从头再来的程序员,肯定是涉世未深、不得要领的门外汉。

我曾经将软件工作比喻成人类这个物种的又一次进化过程,每次开发工作的成果都顺理成章地成为以后阶段项目的工具。既然学习制造和使用工具正是人和动物的区别,那么在软件工作领域,对走捷径持怀疑态度,对借鉴现成成果持抗拒心理,反对宁可停下进度也要先创造工具的开发者或管理者,就如同软件世界里的大猩猩。

迷信“纪律性”的管理者,通常都以“战斗力”为口头禅,可惜开发产品毕竟不是战争,软件编程也不是你死我活的肉搏,软件工作其实就是一次又一次把自己的好想法,好创意凝结在编程语言上的过程,好的代码精辟如诗歌一般,其简练高效令人读起来拍案叫绝;好的软件架构巧夺天工,资源节约,鲁棒性强,这些都是经过反复思索和反复斟酌的结果,这样的工作状态和“纪律性”、“团结就是力量”的状态其实完全是南辕北辙。

软件的灵魂是数学和逻辑,开发过程本身就是一种创造,一种与数学逻辑的对话。纪律性的灵魂是服从,是听话,是个人意志服从集体意志,集体意志服从长官意志。这两件事情的联姻肯定不是自由恋爱,而是指腹为婚。

我觉得在团队合作中,编程规范是极为必要的,用约定的编程规矩来撰写程序是开发者应该共同维护的良好开发氛围。但这就是所谓纪律的边界了,纪律的覆盖范围,不应该逾越这个边界。

这些年敏捷开发、结对编程等新兴软件开发模式的兴起,从一个侧面强化了我的这种认识,那就是:软件工作的重要方式,就是创造一个可以酝酿好点子的环境,让好想法源源不断的产生出来,形成代码。软件活动应该回归本源,就是激发有创造力的人性。

按照这个思路,我常常建议一些嵌入式软件工程师能够在工作之余学习一下 Java,学习一下脚本语言,Awk 也行,TK 也行,Perl 也可以。很多人会很诧异,觉得自己面向硬件,甚至面向驱动,为什么要学习那么多表示层的东西?

我认为嵌入式系统软件开发常常因为设备处理能力以及开发环境限制只能使用面向过程的C,但是在软件工具已经逐渐丰富起来的现在,底层代码是完全可以通过脚本语言帮忙处理的,大量繁重的比对工作和代码迁移工作完全可以用脚本来执行,高效而且准确。

单纯从项目开发的效率来讲,团队里面有这样的软件多面手,有能够提出这样想法的人,比一个外行领导者对于开发者纪律性的要求要有意义,也有效的多。

这又要说到我曾经参与的另一个项目,也是某一种通信产品的开发工作。这一次是给设备开发北向接口。所谓北向接口,实际上就是开放给管理系统的管理监督接口。我们当时采用的是 MIB 方案,以 SNMPv2 为接口规范。同样的问题再次光临:一个带有庞大从属终端数量的局端设备,其 MIB 是非常复杂的,由于管理数据的节点已经细致到每个终端下面的每个网口的出入口速率和 VLAN 之类的细节内容,所以数据管理异常繁琐。

有了之前的经验,这一次我们也都把眼光投向脚本工具,果不其然,我们直接找到了一个开源项目,专门针对 MIB 开发了一套基于 Perl 脚本的处理工具集,把这个工具集稍加调整,就能快速生成满足 MIB 访问要求的底层数据形态,并且生成的代码有良好的可维护性,冗余度也在可接受的范围内。

我印象非常深的是,在做完这个项目的庆功宴上,项目组的技术大牛,也就是之前说到的那位资深程序员曾有这么一句感慨:“真正做可靠的嵌入式软件开发,以后就应该是架构设计配合代码生成工具,资浅程序员的工作就是一边做点小修小补,一边学习架构,这样利于成长,也对项目进展最有利。”此言听闻已有将近 8 年,言犹在耳。

前面“@不动如山_”的那段话虽然出自一人之口,但是这样的观点,在国内却绝不是少数,没有编程背景的管理人员更是对这样的观点敞开怀抱,如获至宝。很多国内的公司在软件部门里面都依然秉承着“人月”状态,就是把员工人数和工作时间的乘积作为公司的生产力,然后把具体的工作按照“人月”或者“人日”乃至“人时”进行度量,进而把一项任务切分出去。看到这里,读过《人月神话》的朋友们应该都会会心一笑。

写这篇文章,也主要是想对初入这个行业或者怀有志向即将进入这个行业的年轻技术者们说点我的心里话:堆代码永远不是软件行业的核心竞争力,设计能力才是,尽管很多公司还以代码行数作为绩效来考评;做一个听话的孩子在这个行业里也很难快速提升自我,因为创造力是要靠自己勉励自己才能不断展现的;安排很多人做重复体力活的规划,其实是因为没有人去尝试创造便捷的工具,这样的所谓的“纪律性”的团队里你肯定也学不到什么东西。多问几个为什么、一定要这样和为什么不那样,对一个年轻人,尤其对一个有技术追求的年轻人永远有好处。

阅读剩余
THE END