软件质量控制技巧

关于软件或代码,其实之前我已经写过一篇写代码的四个境界。虽然说能写出什么样的代码这是需要长久的训练和琢磨的,但是今天讲的,是写代码人该有的心态以及一些可能是必须的外界规范。

这几天看到一篇文章《有着 1 万个全局变量的一大坨代码》,讲了这样一件事:

2013 年 10 月,丰田公司匆匆了结了“意外突然加速” 诉讼案。经过数小时的讨论,俄克拉荷马法庭陪审团得出结论:丰田汽车制造商贸然不顾用户的安全,裁定丰田公司赔偿原告 300 万美元。

而在审阅了 2005 版的丰田凯美瑞汽车的软件开发过程和源代码之后,两位软件专家得出一致结论:丰田公司的系统不但有缺陷,而且达到了危险的程度。因为故障保护机制里充斥着错误和不一致,这是导致事故的根源。

丰田公司汽车软件研发过程和源代码中的各种问题包括:位翻转(bit flips),任务终止导致的故障保护机制失效,对爆栈和内存溢出的防护机制不足,单一的故障隔离区域,滥用全局变量(全局变量达上万个之多)等等。

丰田有自己的软件过程标准,并且和工业标准多少有一些重叠。即使如此,丰田的程序员还是屡屡违反自己制定的标准。他们没能有效地跟踪他们偏离标准的程度,并且会为这种偏离行为进行辩解,认为这样做是符合实际标准的。

具体的案例讨论我就不一一引用,感兴趣的可以点击阅读原文

对此,朋友圈有朋友评论:“不仅仅是丰田,好奇其它车厂的控制软件的质量能有多少差异?各种碰撞测试,安全测试往往还是硬件的比较,在软件越来越影响安全的今天,软件的质量却被极大的忽视。大多时候,我们能依赖的只有程序猿的良心。”

很久以前,看到过一段关于工程师的英文,原文不记得了。但用中国话意译过来大概是这样的:每个工程师都应该在他已有的水平上尽全力追求完美。我们应该具有一点工匠精神 —— 为我们的工作而骄傲,不断打磨我们的工具、流程、和技术,以打造出最高品质的作品。

理想主义一点,软件质量最基本的保证应该来自于程序员的素养。比如说:

胸有 “成” 竹。即使是在面试中,也会常常遇到一些在没有把整个问题和程序的全局想清楚就开始动手写代码的人。这几乎是兵家(哦,应该是码家)第一大忌。从设计到架构到代码蓝图,前面工作做得越细致,后面省下来的功夫会是加倍的。

有效的 tracking。哪些已经做完了,哪些还需要做,一定要有个一目了然且有效的工具帮助跟踪,尤其是项目其实是多人合作写代码的情况。随时想起来什么东西需要做,一刻也别耽误,第一时间记录下来。过分相信自己的记忆力早晚会为自己的一时疏忽买单。

诚实。不管你信不信,其实程序里面可能潜在的问题,程序员自己是最清楚的。一个系统、一个模块,如何实现,里面可能会有什么坑,什么潜在的风险,稍微有经验的程序员是不可能不清楚的。而如何对待这些,如何在必需做出权衡无法追求完美的情况下(比如 deadline)准确而清楚的将程序里的 “地雷” 打上标签,不遮不藏,却也是程序员的良心了。

勤快。比如说代码里见到的 TODO。包括前面说的情况,或是一些后续完成的优化,有时我们会加一个 TODO 注释说明这个地方自己后面会解决。然而几乎所有较大的项目这样一些很重要的 TODO 在很久一段时间都还继续存在。即使早晚这里的 TODO 会被 done,但有一个很大的坏处就是后面遇到的代码重用中,这样的 TODO 可能会被扩散到另一个地方,而注释可能会丢失。所以,永远不要把垃圾扫到地毯下面。哪怕是加了标签。能解决的,尽快解决,不要遗留。

而另一个类似的情况,是当你在另一个已有文件里改动代码的时候。常常会遇到一个情况是:已有的老代码和风格其实是有你能看得出来的问题的。选择置之不理自然省事。甚至为了保证一个文件的风格一致可以照着旧代码风格写,即使这样是不完美的。而按照正确的方式插入你的代码并且重新规范已有代码会增加很多的工作量。那这个时候你是改还是不改呢?

完备的测试集。写代码的都知道,很多时候,写出可以测试所有情况的单元测试和综合测试,需要的工夫可能比写函数货程序本身要费劲的多。然而,完备的测试集是代码持续开发中保证正确性的第一道防护线,不论是后期的修改、重构、移植等,都会事半功倍的帮助发现问题。其重要性也不用我多说了。

代码审核。这里说的是 Code Review,也叫 Peer Review这可能是目前我们能有的对代码质量的保证最重要的环节(之一)了。和很多同事聊天,都有个共同感触:很多写代码的技巧、风格、或习惯都得益于以前工作中在代码审核中同事给出的建议。这比看书或者读别人代码学习来的要有效的多。在面试中也发现一些现象:有些公司的工程师一下手,从敲下的头十行代码开始,你就能看出他的好的编程习惯。而很多刚毕业,或是从毕业一直在一些不是很重视代码审核和代码规范的公司(尤其是小公司)的工程师,很多细节一下子就能暴露很多的问题。

记得上一次有个读者留言说,感觉组里大家的水平都一般,这种情况怎么办呢?代码审核还有那么大的用处么?有。首先,更多人会了解代码是做什么的。这种信息共享会保证所有合作的人对全局的代码改动有个全面的了解。其次,多一双眼晴会看到你的一个疏忽,多十双眼睛就能避免你的大部分疏忽。最后,一些语言上的技巧更容易分享,而代码模式也更容易规范化。

代码审核会最大程度受益,还需要代码被审核的人能够比较谦卑,以开放、听取的心态对待每一个评论。而参与审核的人要多存质疑的态度,不明白的或者觉得有问题的可以改进的地方都直接说出来,讨论开了,对双方都有益。代码审核中也常常出现意见不统一,产生争论的时候。有效的解决意见不一致的过程,其实也会帮助对系统或者代码更深层的考虑和了解。

然而,靠着程序员的良心和素质,对代码或软件质量的维系,对于上面说的软件质量会影响人生安全的情况,却又显得远远不够了。

对于车厂的控制软件的质量,丰田这次是因为出了事故再有人去深度调查,花费很多的时间和很牛的人力资源才找到问题的根本。试问又有多少无人察觉的软件 “地雷” 存在于我们的生活里呢?嵌入式软件因为其特有的和底层硬件的紧密耦合,各个公司一定会有自己的接口,因此都会有自己的软件质量审核标准和审核流程。这是现状。然而随着各种智能软硬件结合的机器逐步渗透到人们的衣食住行,会不会有人出来在不同领域定义业界相对比较标准的接口和测试规范,用一个统一的黑盒测试更全面的对软件的质量进行控制,以及一些程序评估模式来对程序质量进行评估(有点类似 Ruby 的 rubocops?)。在未来的十年甚至更久,这样一些有效的外界对软件或程序质量的约束,可能和程序员自己不断打造自己的 “匠心”,都是一样很重要的吧。

余下全文(1/3)
分享这篇文章:

请关注我们:

发表回复

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