在加州山景城园区,谷歌每年夏天都会举办赛孵大会(SciFoo)。来自科学技术界的各色名流聚在一起度过一个应接不暇的周末:这里随时都有即兴报告和不期而遇的交流。我从赛孵大会学到过许多东西,最令我难忘的是几年前的一次经历,它发生在最意想不到的时刻——上卫生间时。谷歌当然不会放过这些“绝佳”的时机来教育和熏陶员工。小便器的正上方贴着很多小贴士,上面写着针对常见编程问题的善言警语。
一个常见小贴士上画着两个卡通灯泡,红灯是个哭脸,写着“排错弱爆了”(Debugging sucks);绿灯是个笑脸,写着“测试超级棒”(Testing rocks)。这个充满智慧的提示和我自己的编程经验非常吻合。当我急着想得到结果,匆忙写下一堆未经测试的语句,程序几乎从来不按我的预期工作。每当这种事情发生,我只知道某个地方某个东西出错了。由于“某个地方”是个很大的地方,错误真的很难发现。
效率更高痛苦也更少的办法,是先测试小段程序,然后再把它们连起来。这样出错的频率会降低,即使再次出错了,你也知道它是哪一小段程序的问题,非常容易修改。从某种意义上来说,谷歌的卫生间智慧不过是“欲速则不达”的现代版。但于我而言,那两个卡通灯泡就像植入脑海的种子,已经开始生根发芽。首先,灯泡警句传达的信息几乎完美地抓住了科学方法的本质。
历史上的绝大部分时间,人类主要是依靠经验规则来解决与物理世界——比如农业、冶金和建筑——打交道中遇到的难题。这些规则来自很多代人的积累(还经常会遗失),通过随机的观察来修正(debug)。现代意义上的科学则肇始于人们的领悟:更有效的方法是在简单的条件下对想法进行全面的测试,这时更容易排查错误。由此而来的发展是渐进的:前进的每一步或许都很小,但却能经受时间的考验。
受圣言的感召、亚里士多德形而上学的启示,伽利略同时代的大哲学家们建立了许多模棱两可的世界观体系。唯有伽利略仔细研究了球是如何滚下斜面的。伽利略完全理解了这个简单的运动,他的理解一直到现在还在影响人们的思考。伊萨克·牛顿说过:“最好准确地理解简单的情况,把复杂的事情留给后人。最忌试图通过建立一堆假设来理解所有的事情。”“多测试,少排错”同样能用来理解数字计算相对模拟计算的优势。
在模拟计算中,你总是试图把很多信息表达为连续变量的精确数值,比如,电压是0.423311…这当然没问题——如果你确实能精准地控制和测量这些变量,也就是,不出任何差错。与此形成鲜明对照的是,在数字计算里,变量都是离散的:一般情况下由一串串0或1组成。将数据流打包成一个个小的冗余数据包,检测它们的一致性,你就可以在错误扩大转移之前找出并纠正它们。如今,数字计算一统天下。生物进化中也存在着测试和排错。
“物竞天择”是测试,达尔文的“适者生存”是排错。大自然的测试是严格的,排错是迅速的,当然,整个流程其实是残忍而低效的。但日积月累,经过令人难以想象的漫长岁月,利用广袤的空间,自然创造出了许多令人赞叹的成果——比如一团约3斤重看起来乱糟糟的东西,人脑。它比自然更擅长测试和排错。