本节书摘来异步社区《高效能程序员的修炼》一书中的第3章,作者: 【美】Jeff Atwood 译者: 陆其明 , 张健 责编: 陈冀康, 更多章节内容可以访问云栖社区“异步社区”公众号查看。
第一条法则:永远都是你的错
高效能程序员的修炼
作者在Twitter上发的一条短讯:
“在怨天尤人之前,我们应该先自我反省、努力把自身的问题解决了。”
12:22 PM – 2012-5-30
你应该知道那种感觉。我们所有人都曾碰到过这样的事情:已经盯着代码看了无数遍,但还是没有发现任何问题。然而,有个故障或者错误始终挥之不去。于是你开始怀疑,可能是你开发程序所用的那台机器出了问题,也可能是操作系统的问题,或者是你使用的工具和库出了问题。肯定是它们的原因!
然而,无论你多么绝望,都不要往那条路上走。沿着那条路下去就是“伏都1”计算和靠运气编程。
总是要处理一些困难的、捉摸不透的问题,这是一件令人绝望的事情,但是不要让绝望领着你误入歧途。作为一名谦逊的程序员,最基本的要求就是要有意识:你写的代码在任何时候出了问题,那一定都是你的错。这个观点在《程序员修炼之道:从小工到专家》2一书中被巧妙地归结为“select3没有问题”:
在大多数项目中,你所调试的代码里常常混杂着这些东西:你和项目小组中的其他成员开发的应用代码、第三方的产品(数据库、链接器、图形库、特殊的通信系统或者算法等)以及平台环境(操作系统、系统库和编译器)。
操作系统、编译器或者第三方产品出问题的可能性是有的——但是,这绝对不应该是你碰到问题后的第一反应。错误出现在正在开发的应用代码中的可能性要大得多。通常情况下,假定应用程序错误地调用了库函数要比假定库本身有问题更有效益。即便问题出在第三方,你还是必须彻底排除自身代码的问题,然后再提交错误报告。
我们曾经做过一个项目,项目中的一位高级工程师确信Solaris4上的select系统调用出了问题。无数次的劝说和逻辑分析都不能改变他的主意(事实上,所有其他的网络应用程序在同样的机器上都能正常工作,但他仍然固执己见)。他花了好几个星期来做变通方案,但是因为一些诡异的原因,这些方案似乎都行不通。他最终不得不坐下来,仔细地阅读关于select的文档。终于,他找到了真正的问题,并且在几分钟内就解决了。如今,一旦我们当中有人开始为了一个很可能是我们自己造成的错误而责怪系统时,我们都会用“select有问题”这个短语作为善意的提醒。
代码产权的另一面是代码责任。无论你的软件出现什么样的问题——甚至最开始出错的地方根本就不是你的代码——你也应该总是假定问题出在你的代码里,并且根据这个假设采取行动。如果你想让世界人民接受你的软件,那你就要为它的故障承担全责。尽管——从严格意义上来说——你并不是非这么做不可。但只有这样,你才能赢得尊敬和信任。如果你不断地把问题推卸到其他人、其他公司或者其他源头上,你是无论如何也得不到尊敬和信任的。
从统计学的角度来说,软件中的故障或者错误一般都是人为的,例外的可能性可谓凤毛麟角。我想你已经明白了这一点。在《代码大全》(《Code Complete》)一书中,Steve McConnell引用了两个研究来证明这个观点:
通过1973年和1984年进行的两次研究发现,在所有报告的错误中,大约有95%是由程序员造成的,2%是由系统软件(编译器和操作系统)造成的,2%是由其他软件造成的,1%是由硬件造成的。跟20世纪70年代和80年代相比,现在的系统软件和开发工具的使用人群要大得多,所以我猜想,现如今应该有更高比例的错误是由程序员的过失造成的。
不管你的软件出了什么问题,请你负起责任来吧!从你的代码开始,深入进去,逐步向外调查,直到你找到确凿的证据证明问题之所在。如果问题出在你无法控制的代码上,你不但学会了必要的故障排除和诊断技巧,同时还获得了用来支持你指控别人的审计证据。当然,和你耸耸肩膀简单地把问题归责于操作系统、工具或者应用框架相比,这样花费的工夫要多得多——但是这也会逐步形成信任和尊敬的感觉,而这种感觉是你通过指责他人和逃避无法体会到的。
如果你真的渴望做一名谦逊的程序员,在你碰到问题的时候,你就应该很淡定地说:“嘿,这是我的错——让我把它弄个水落石出。”