2010年12月30日星期四

为什么我说框架和工具不是解决安全性的良好方案

    在python-cn的maillist上,刚刚爆发了一场关于动态语言合并出错的争论。问题的起源,来自于这样一个问题。
一个程序员A,写了一个函数,function1。程序员B对函数进行了调用。现在两个人分别在svn上工作,A修改了function1,而b修改了其他内容。
由于python并不在编译时检查类别问题,因此当两人的svn merge后,运行并没有出错。现在,问题只有等上线后客户提出来了。
    几乎所有的人都同意,这问题的根源不是一个语言的问题。本质上说,这是一个工作流程问题。即使是C,也只检查参数的个数和类别,对于行为的变化和参数意义的变化还是无能为力的。
1.当你公开了一个函数,并要修改这个函数的外观行为的时候,必须向其他人通告。
2.python代码要通过unittest和黑盒检查覆盖。
3.代码应当cross review。
    争论的焦点主要是在python下如何避免这个问题。楼主Zhang Jiawei的观点是使用pydev,加上工具来检查。我,沈崴,ZQ的意见是通过行为来避免这个问题。所谓行为,主要包括以下几个。
1.互相review代码。
2.修改通告。
3.编写无检查和无处理的代码,并大量运行。如果代码中有错,程序会持续崩溃。因此当大量运行程序不崩溃时,代码就无错了。
    为什么我们并不推荐使用自动化工具来检测错误呢?主要是因为自动化工具可以*找到*问题,但是却不能*保证*是找到问题最彻底的一种。我举个最简单的例子:
网络工程师A,用了pylint,找到了自己code中的15个低级bug。他很高兴,因为工具使用起来很方便。
A向领导汇报了自己的心得,建议全公司推行这个工具。假定他的领导是项目经理B。
A:这个工具太好了,一下就找出了我15个bug,我发现用这个工具很方便,blahblahblah。
B:恩,很好,过两天你在公司里面讲讲这个工具。对了,你的code review做了么?
A:我用工具查过拉。
B:你确定他找出了你的*所有*bug么?
    问题的关键,就是*所有*。我们当然不可能找出程序中的所有bug。我所知的bug最少的程序是TeX,据说在数年的时间内只有数个bug。但是其版本号仍旧是3.1415926——正好是祖率的密率——而不是pi。我们毕竟不敢——高伯伯也不敢——保证没有bug。但是通过cross review,不处理加覆盖性检测,我们可以保证bug出现的概率在某个水平以下。
    自动化工具寻找出的bug,是在这个水准以上的。就是说,自动化工具看的出的,人应该看的出。人看的出的,自动化工具不一定看的出。如果做不到这点,说明你的水准还不足。
    所以,当我们需要一个尽量无错的code时,当你pydev/pylint,或者其他工具做了检测,问题是否解决了呢?没有,你仍旧需要review来保证没有bug。这样一来,工具的意义在哪里呢?
    当然,这并非说在做code review之前,你*不能*去做一遍代码扫描。只是说这样做并*不能替代*对错误的人工控制行为。
    除非你的目标是使用最低的成本,将错误减少到一个可接受的规模——而不是最低。就像我们在外包中常做的那样。这种情况下使用工具是比较合适的。
    而且一旦使用工具,很多程序员会产生依赖。所谓依赖,并不是讲从逻辑上他们不清楚在代码扫描外还需要独立的人工检测。但是在检测时,心里就会抱有一种放松的心态。尤其是其中某些虫族程序员让人无语叹息的行为。在中国的程序员界,有着诸多非常有创造力的bug提供者。例如擅长用str+=的java网页程序员很常见,这属于常见问题。但是自己写一套字典映射规则以完成数字到字符转换的(就是c下面的itoa).net程序员真的让我大开眼界——而且他同时犯下了str+=错误。要指望工具修正+=是可以的,要指望工具找出这类极品代码,估计下面会有更极品的人犯下更极品的错误。。。

没有评论: