美的程序不可能从修修补补中来。它必须完美的把握住事物的本质,否则就会有许许多多无法修补的特例(转)

 

  现在的很多公司,包括 Google 和我现在的公司 Coverity,都喜欢一种“测试驱动的开发”(test-driven development)。它的原理是,在写程序的时候同时写上自动化的“单元测试”(unit test)。在代码修改之后,这些测试可以批量的被运行,这样就可以避免不应该出现的错误。

  这不是一个坏主意。我在 Kent 的编译器课程上也使用了很多测试。它们在编译器的开发中是不可缺少的。编译器是一种极其精密的程序,微小的改动都可能带来重大的错误。所以编译器的项目一般都含有大量的测试。

  然而测试的构建,应该是在程序主体已经成形的情况下才能进行。如果程序属于创造性的设计,主体并未成形,过早的加入测试反而会大幅度的降低开发效率。所以当我给 Google 开发 Python 静态分析的时候,我几乎没有使用任何测试。虽然组里的成员催我写测试,但是我却知道那只会降低我的开发效率,因为这个程序在几个星期的过程中,被我推翻重来了好几次。要是我一开头就写上测试,这些测试就会碍手碍脚,阻碍我大幅度的修改代码。

  测试的另一个副作用是,它让很多人对测试有一种盲目的依赖心理。改了程序之后,把测试跑一遍没出错,就以为自己的代码是正确的。可是测试其实并不能保证代码的正确,即使完全“覆盖”了也是一样。覆盖只是说你的代码被测试碰到过了,可是它在什么条件下碰到的却没法判断。如果实际的条件跟测试时的条件不同,那么实际运行中仍然会出问题。测试的条件往往是“组合爆炸”的数量级,所以你不可能测试所有的情况。唯一能可靠的方法是使用严密的“逻辑推理”,证明它的正确。

  当然我并不是让你用 ACL2 或者 Coq 这样的定理证明软件。虽然它们的逻辑非常严密,但是用它们来证明复杂的软件系统,需要顶尖的程序员和大量的时间。即使如此,由于理论的限制,程序的正确性有可能根本无法证明。所以我这里说的“逻辑推理”,只是局部的,人力的,基本的逻辑推理。

  很多人写程序只是凭现象来判断,而不能精密的分析程序的逻辑,所以他们修改程序经常“治标不治本”。如果程序出问题了,他们的办法是看看哪里错了,也不怎么理解,就改一下让它不再出错,最多再把所有测试跑一遍。或者再加上一些新的测试,以保证这个地方下次不再出问题。

  这种做法的结果是,程序里出现大量的“特殊情况”和“创可贴”。把一个“虫子”按下去,另一个虫子又冒出来。忙活来忙活去,最后仍然不能让程序满足“所有情况”。其实能够“满足所有情况”的程序,往往比能够“满足特殊情况”的程序简单很多。这是一个很奇怪的事情:能做的事越多,代码量却越少。也许这就叫做程序的“美”,它跟数学的“美”其实是一回事。

  美的程序不可能从修修补补中来。它必须完美的把握住事物的本质,否则就会有许许多多无法修补的特例。其实程序员跟画家差不多,画家如果一天到头蹲在家里,肯定什么好东西也画不出来。程序员也一样,蹲在家里面对电脑,其实很难写出什么好的代码。你必须出去观察事物,寻找“灵感”,而不只是写代码。在修改代码的时候,你必须用“心灵之眼”看见代码背后所表达的事物。这也是为什么很多高明的程序员不怎么用调试器(debugger)的原因。他们只是用眼睛看着代码,然后闭上眼,脑海里浮现出其中信息的流动,所以他们经常一动手就能改到正确的地方。

http://kb.cnblogs.com/page/518955/

 

时间: 2024-10-03 18:02:13

美的程序不可能从修修补补中来。它必须完美的把握住事物的本质,否则就会有许许多多无法修补的特例(转)的相关文章

程序员如何快速准备面试中的算法

我决定写篇短文,即为此文.之所以要写这篇文章,缘于微博上常有朋友询问,要毕业找工作了,如何备战算法.尽管在微博上简单梳理过,如下图所示:        但因字数限制,特撰此文着重阐述下:程序员如何快速准备面试中的算法,顺便推荐一些相关的书籍或资料. 备战面试中算法的五个步骤 总体来说,备战面试中的算法,分为五个步骤,如下: 1.首选你得确保自己已经掌握好一门编程语言 如果是C的话,推荐Dennis M. Ritchie & Brian W. Kernighan著的<C程序设计语言>,和

php-vs2013做的c++程序,要放到windows2008中运行

问题描述 vs2013做的c++程序,要放到windows2008中运行 现在在win7下debug没啥问题,但有点担心做好后放08中会出现各种问题,有木有遇到过类似问题的朋友 解决方案 一般没有问题,如果出问题只能是dll版本问题,用VS自带的depends工具查看依赖的dll,并在windows2008中查找同名的dll,用新版本替换旧版本就可以了. 这个事情我干过. 解决方案二: 是2008还是2008R2 VS2013和2008 R2兼容性没有问题. 解决方案三: 用vc2005重新编译

日志采集-在应用程序监控系统的设计中,有没有针对应用程序埋点获取目标数据的研究?

问题描述 在应用程序监控系统的设计中,有没有针对应用程序埋点获取目标数据的研究? 怎么埋点的?埋点这个名词在业内好像并没有统一吧?有些监控信息直接从应用程序日志里面获取就行,但是客户端(PC或移动端)是不是通过埋点上传数据给服务器?这里面有没有关于埋点的方法论?或者成体系的文献之类的东西? 解决方案 有的,你可以看看万方上的论文.主要是数据分析这块.

0-android为什么调用拨号程序时向contact表中存入的数据不全

问题描述 android为什么调用拨号程序时向contact表中存入的数据不全 在模拟器通讯录中新建了联系人,设置了头像,但是这个号码,给模拟器拨打电话时,photoId和 number存到contact表中的值为0和null

ftp-java web做的网站上线,已经把域名解析到服务器IP上,把程序上传到FTP中,但是网站打不开

问题描述 java web做的网站上线,已经把域名解析到服务器IP上,把程序上传到FTP中,但是网站打不开 前几天也问过这个问题,但是问题依旧,下面是tomcat日志报的错,大神看看这是什么问题 2015-6-19 9:43:18 org.apache.catalina.core.StandardContext filterStart 严重: Exception starting filter structs2 java.lang.UnsupportedClassVersionError: co

mfc c++-一个在MFC对话框程序的PICTRUE控件中绘图的问题

问题描述 一个在MFC对话框程序的PICTRUE控件中绘图的问题 本人目前正在做一个小程序,用于在数据库中读取某个字段,然后根据读取的结果在Pictrue控件中进行绘图(由一个按钮按下的事件驱动).原理为这般:bool型变量m_bIsDraw (默认为false) 用于判断是否为首次程序,如果是第一次打开则执行在OnPaint()函数中drawCircle(void)函数(用于生成直角坐标系和圆形的底图),然后将m_bIsDraw置为true,按键按下的函数中调用void CfindHistor

android程序数据保存在单例模式中,保存在内存中,会oom吗

问题描述 android程序数据保存在单例模式中,保存在内存中,会oom吗 ```package com.amt.appstore.cache; import java.util.ArrayList; import java.util.List; import android.content.pm.PackageInfo; import com.amt.appstore.download.DownItem; import com.amt.appstore.model.AboutFirm; imp

w y f-编写一个java程序把两个文件中不同的行输出到一个文件中

问题描述 编写一个java程序把两个文件中不同的行输出到一个文件中 把两个文件中的内容不同的行输出到同一个文件中 代码:文件1:/x /x 46/m /x /x 稍/d 等/v 我/r 现在/t 去/v 写/v 上/vq 下/m?? 啊/y 去/v 协商/v 下/m 好的/l 亲爱的/n ,/w 当时/t 这个/r 图片/n 应用/v 的/u 地方/n 特别/d 多/a ,/w 就/d 像/v 全/a 用途/n 一样/u ./w 所以/c 还/d 挺/d 麻烦/a ,/w 等/v 我们/r 副总

自动获取词-有没有什么程序可以获取我输入框中出现次数最多的词

问题描述 有没有什么程序可以获取我输入框中出现次数最多的词 有没有什么程序可以自动获取我输入框中出现次数最多的词?我输入完成后,告诉我出现最多的是什么词,这样的可以有吗