首页 > 程序人生 > 漫谈程序员系列:无BUG不生活
2015
01-21

漫谈程序员系列:无BUG不生活

我决定谈一谈世界上最著名的虫子:BUG !

BUG 困扰了一代又代的程序员,不论是杰出的计算机科学家,还是像 Linus Torvalds(Linux内核创始人) 、Bill Joy(传说三天写出BSD的前身,vi和csh的作者)等神一样的传说,抑或你我芸芸程序猿,都是 BUG 骚扰的对象。 BUG 是绝对狂热的好战分子,具有永不停歇的战斗欲望,它潜伏在程序员的周围,一双小眼贼亮贼亮,在你百密一疏时出其不意一击奏效。而无论你是钢筋铁骨,还是羊脂玉体,只要被这只虫子袭击(看过《木乃伊》的话,对圣甲虫一定印象深刻),就得褪上三层皮,更有甚者,很可能锒铛入狱、命丧黄泉或者烟消玉损。《盘点史上最具毁灭性的的Bug》可供参考。

软件界致命的BUG事件

其实,BUG造成的悲剧天天都在上演,这里我们先举几个比较著名的例子。

许霆案

2006 年 4 月 21 日晚 10 时,许霆来到天河区黄埔大道某银行的 ATM 取款机取款。结果取出 1000 元后,他惊讶地发现银行卡账户里只被扣了 1 元,狂喜之下,许霆连续取款 5.4 万元。当晚,许霆回到住处,将此事告诉了同伴郭安山。两人随即再次前往提款,之后反复操作多次。后经警方查实,许霆先后取款 171 笔,合计 17.5 万元;郭安山则取款 1.8 万元。事后,二人各携赃款潜逃。

……

从软件的角度来讲,其实是 ATM 提款机出现了一个 BUG ,许霆作为测试人员发现了这个 BUG ,然后找来朋友做了多次复现操作。

这是一个软件 BUG 引发的悲剧,最终上升到了犯罪的高度。

2007 年底,经过一审,广州市中级人民法院判处许霆“无期徒刑,剥夺政治权利终身,并处没收全部个人财产”。

2008 年 1 月,广东省高院裁定许霆案发回重审。经过再审开庭,法院做出了有期徒刑五年的判决。

……

作为程序员,我认为开发 ATM 机的公司应当负有责任,他们应当赔偿客户(即银行)的损失,是他们的软件 BUG 导致了这个案件。但在银行这种强力机构面前,个人的声音微不足道,很难把两者放在同一个天平上来考量。这中间到底有着怎样的曲折,时过境迁,我们已无法考量。但是,作为程序猿,我们还是得引起警惕啊,很多时候, BUG 会带来直接的经济损失和严重的法律后果。虽然你可以辩称技术无罪,但子不杀伯仁,伯仁因你而死。

锤子手机预约数闹剧

2014 年国庆假期期间,锤子手机 4G 版现身天猫商城页面显示该机预计将在 10 月 18 日正式开卖,售价为 3500 元。据说备货量为 10000 台。据说很快天猫商城页面显示预约人数超过 8 万。

后来,有网友爆料称从页面源代码中发现 4G 版锤子手机的预约人数有水分,页面显示的数字是实际预约人数的三倍,从而再度把锤子手机推到了风口浪尖上。

后来,天猫对这一事件做出了正面回应。天猫表示,截至 10 月 7 日,锤子手机 4G 版的预约用户数为 62682 人,但在 10 月 8 日,系统调用一个数据端口时,意外将前端该页面动态数据显示“清零”。

为了尽可能让预约数据还原真实,天猫决定将 10 月 8 日起的新预约数,做了“乘以三”的处理,以便后期预约数能快速接近真实数据……

……

注意我标红的文字,如果天猫的回应符合实际情况,那么,其实,这是一个 BUG !

真不够老罗忙活的啊。老罗10月19日在微博上正式回应:预定数据造假的事,跟我们没有一丝一毫的关系,我们在这件事中扮演的唯一角色,就是躺枪。

这是要上演罗生门的节奏吗?亲们。

对于此事,我不能不感慨:不怕神一样的对手,就怕猪一样的队友……不怕猪一样的队友,就怕神一样的网友——据说这个造假的BUG是因为某个测试人员发现预约数总是3的倍数而发现的。

苹果 iOS 8.0.1 更新撤销

苹果,神坛上的苹果,以极致用户体验而载誉江湖的苹果,也因为 BUG 而被钉在了耻辱柱上:

(2014年)9月25日消息:苹果在今天早些时候发布了 iOS8.0.1 更新,目的是决解当前版本中的多处 Bug ,但是没想到的是更新补丁带来了更多的 Bug ,最终苹果撤回了该次升级。

据了解,本次受到影响的主要是 iPhone 6 、 iPhone 6 Plus 这两款最新的设备,后果是只能接受移动网络无信号,而且 TouchID 也不能用了。因此建议还没有升级的用户还是不要升级了,而已经悲剧了的用户目前只能等待苹果推出修复补丁。

……

有人说这是乔布斯不在的后遗症……真不知道这帮人为什么总是把乔布斯拿出来说事儿!其实,这就是一次软件 BUG ,从程序猿的角度来看,这他娘再正常不过了,和乔布斯有一毛钱关系吗!

再说了,这事儿又不是单单苹果一家才有,你看人家微软,根本都不当一回事儿,补丁一个一个一个一个又一个的发,堵的就是漏洞,改的就是 BUG ,这都是那帮程序猿惹的祸,与天上的月亮没有关系。

心脏滴血漏洞

2014年4月9日,Heartbleed(意为“心脏出血”)的重大安全漏洞被曝光,一位安全行业人士在知乎上透露,他在某著名电商网站上用这个漏洞尝试读取数据,在读取200次后,获得了40多个用户名、7个密码,用这些密码,他成功地登录了该网站。

……

Heartbleed 漏洞,这项严重缺陷(CVE-2014-0160)的产生是由于未能在 memcpy() 调用受害用户输入内容作为长度参数之前正确进行边界检查。攻击者可以追踪 OpenSSL 所分配的 64KB 缓存、将超出必要范围的字节信息复制到缓存当中再返回缓存内容,这样一来受害者的内存内容就会以每次 64KB 的速度进行泄露。

OpenSSL ,著名吧,开源吧,安全吧,它支撑的互联网站点就像天上的星星一样,数都数不过来。就这么一个知名、开源、强大的密码库,一样有 Bug 。

BUG 无处不在!

BUG 对程序猿的追逐,对软件的痴迷,比现在的死忠粉还要厉害,那简直是上穷碧落下黄泉,不论你在哪里,上天入地,我都会与你在一起,不离、亦不弃。

无BUG不生活

计算机先驱 Maurice Wikes 回忆起 1949 年他在英国剑桥工作的情形,在拖着打孔纸带上楼给雏形计算机 EDASC 装载程序时,他看到了自己的未来:

我强烈的意识到,生命中剩下的好日子,都将耗费在给自己的程序找错误上头。

Bug的定义

Bug一词的英文原意是“臭虫”或“虫子”。但对程序员来讲,Bug意味着错误、缺陷、问题、漏洞、未按需求实现、不符合需求预期或延伸等等等……那么,Bug究竟是什么呢?

我媳妇是搞测试的,软件测试这块最著名的一本书就叫做《Software Testing(软件测试)》,它里面是这么描述BUG的:

The software doesn’t do something that the product specification says it should do.

The software does something that the product specification says it shouldn’t do.

The software does something that the product specification doesn’t mention.

The software doesn’t do something that the product specification doesn’t mention but should.

The software is difficult to understand, hard to use, slow, or in the software tester’s eyes will be viewed by the end user as just plain not right.

作为开发人员,当然要看得懂E文了……

其实还有一个粗暴点儿的说法:BUG就是错误。

Bug是怎么来的

《圣经》中有“义人”这个说法,我们有“人无完人,金无足赤”的说法……

人是妈妈生出来的(女娲造人时除外)——你看我总是加各种说明以便堵住漏洞,这样写文章真是很累……这实在是和我的开发习惯有关:我总是习惯防御性编程,预先考虑各种错误,在编码期间就努力消除它们发生的条件……

我们说,人是人他妈生的,妖是妖他妈生的,而软件是程序员生的。

爸爸妈妈在备孕时,很多爸爸会戒烟戒酒戒加班,所谓封山育林也。妈妈会补叶酸测排卵期计算最佳受孕时间……总之一句话,优生优育。可是,孩子出生后依然会有毛病,随着孩子长大,各种毛病都会显现出来。有的孩子有先天缺陷,比如原发性高血压、先天性心脏病、兔唇、痴呆、智障……有的孩子长着长着有毛病了,近视、斜视、小儿麻痹、跛脚、自闭症……作为父母,这都是我们很难接受的事实,可是必须面对和接受。

软件是程序员的孩子,在生它之前,你可曾封山育林、可曾熟悉自己的生理周期?哇哈哈哈哈,太扯淡了不是!包不同(《天龙八部》中慕容复四大家臣之一,非常有趣)摇摇头说,非也非也。然也!开发软件其实也要经历这些过程,更重要的是,我们一定要意识到:

程序员在生产软件,也在生产BUG!

再牛逼的程序员,写出来的软件也有BUG。BUG就是软件与生俱来、不可脱逃的好基友,就在那场说走就走的旅行的一开始,它们就情根深种难分难舍了……

So,Bug是程序员写出来的……

不管你愿不愿意承认,事实就是这么令人沮丧。连Maurice Wikes都承认了这一点,你就别倔犟了吧亲。

程序员对Bug的态度

每个程序员都是不同的……

绝对不可能……

测试MM对阿猿说发现了一个Bug。

阿猿矢口否认:不可能,绝对不可能!

MM:真的有Bug,你过来看一下!

阿猿:我都不用看,在我这儿好好儿的。

MM:你来看一下嘛……

阿猿:看什么看,我都测过的,绝对没问题。

伴随着凳子响,阿猿不情愿的起身,脸上不耐烦的表情,心理却嘀咕着怎么回事儿呢这是……

过了一阵儿,阿猿不好意思的声音响起:真没想到是这儿的问题……你怎么测的……一般用户都不会这么用的……

耶,你找到Bug啦

测试MM袅袅婷婷地走到阿猿跟前,小声说:你来我这里看个现象。

阿猿:好,马上来。

阿猿立马起身跟MM走了,过了一会儿,响起阿猿的声音:哇,你太厉害了,这种问题都被你发现了,我测了很长时间都没测出来,太好啦!

然后大家看见阿猿脚步轻快地走回工位,边走边频频点头,两只手像得了帕金森一样来回划拉,嘴里神神叨叨的念念有词……

结果到工位上时,阿猿一拍额头,小声说:知道啦,原来是这样。

过了两分钟,阿猿找MM说:问题解决了,是这么这么回事儿……

MM一脸崇拜的看着阿猿:你太厉害了,这么快就解决了!然后小声说:大家都像你就好啦……

阿猿说:有什么问题立即叫我看。

我很忙,没空管Bug

测试MM想在jira上提个Bug,先在QQ上对阿猿说:有个Bug,你过来看下?

阿猿:忙着呢,焦头烂额的。

MM:一分钟都用不了,你来看下吧。

阿猿:思路一打断就不好恢复了,等会儿!

MM:你不看我提到jira上了啊。

阿猿:随便,你不就是爱提Bug嘛。

……

One day,团队review Bug,TL问阿猿:这个Bug怎么回事儿?

阿猿挠挠头:我也不知道啊。转身问MM:咋回事儿,提Bug也不通知我一声儿,我都不知道怎么回事儿。

MM:当时给你说你没时间看,后来……

阿猿:行啦行啦,我待会就看,以后提Bug要通知我一声。

MM无话可说,只能用满含幽怨的眼睛锁定阿猿,直到阿猿别过头去……

都是需求的错?

阿猿收到了来自jira的邮件,他被告知有一个Major级的Bug,看了之后,黎叔很生气,后果很严重——阿猿转身就喊:MM,怎么回事啊你,给我提了个Major级的Bug,明明是需求问题啊!

MM赶紧过来确认:哪个Bug?

阿猿气呼呼地一指电脑屏幕:就这个,需求问题,你仔细看看,别老给我整这种Bug。

MM:咱们找需求文档看看……

……

MM:你看,需求是这样描述的……

阿猿:需求描述有问题,实现起来太复杂了,也没意义,谁会这么用啊。

MM:我是按需求写的用例……要不咱们和产品经理一起讨论一下?

阿猿:算啦算啦,麻烦,先不管啦,到时再说!

……

还没好,怎么会!

begin:

MM:阿猿,你提交的版本有问题,Bug还没好……

阿猿满脸自信:怎么会,我都测过了,各种情况都考虑到了。

MM:真的,不信你来看。

阿猿:看就看,你告诉我你怎么测的……

MM:这样进来,这点一下,马上再点一下,趁那个按钮还没刷出来,再点,然后就报“XXX已停止运行”。

阿猿:用户不可能像你这么用!

MM:可能。

阿猿:不可能,我从来没这么用过。

MM:我先给你Reopen,你再改改吧。

阿猿:不要Reopen,根本没问题。

MM:我都遇到了……

阿猿:算啦,你别Reopen,我先改改,马上给你一个新的版本。

过了几分钟,阿猿提交了版本。

goto begin;

测试环境没问题!

经过多次延期,经过几个晚上的集体猛搞,软件终于发布了,大家都送了口气儿,第二天都休假去了,只有阿猿留了下来。

刚上班,阿猿就被气急败坏的老板叫到办公室:赶紧把版本回退回去,摊上大Bug啦!

阿猿一脸无辜:测试都没问题啊,什么Bug?

老板:两个小时,升级了800多个用户,有40多个电脑死机的!

阿猿:不可能啊,测试环境都测过了……

老板:赶紧停止升级,下线版本!

老板还说:一切皆有可能,一定不能忘记李宁。你们就是太大意了,没有好好测,都不当回事儿。

阿猿:其实大家也是蛮拼的,都搞了好几个通宵啦……

老板:赶紧下线,拼不拼不重要,没问题是目标。

阿猿:要不我们联系几个用户,升级测试一下,重现了就好定位问题!

老板:哪个客户愿意当小白鼠!赶紧下线!你们自己想办法,多用点心,别不当回事儿,我们都被告到消协啦,这样下去早晚玩儿死。

阿猿:测试环境真测不出来……

阿猿面对老板喷火的双眼,心有不甘转身出了办公室,嘴里念叨着:为毛生产环境总是出问题呢……

怎样才能告别Bug

怎样才能告别Bug?

有人说提高代码质量,参见《代码大全》。

有人说提高自我修养,参见《程序员修炼之道:从小工到专家》。

有人说提高效率,参见《高效程序员的45个习惯》。

有人说……

其实,这个问题早在唐代就被白居易盖棺定论了。《长恨歌》大家都知道吧,其实它描述的就是唐明皇的Bug引起的故事。

唐玄宗是一国之君,前几年干得很不错,软件运行正常,开创了“开元盛世”,大家都以为这款软件很不错,不会出现Bug,可是后来外部环境变化,玄宗的爱妃死了,他心伤之际被儿子的媳妇杨玉环所惊艳,终于偏离了正常运行轨迹,造成了长达八年的“安史之乱”。你看,这就是大Bug的大影响!

优秀的软件也会随着外部环境的变换而老化,最终不能满足用户需求或者无法按预期工作。

唐玄宗满足的是《Software Testing》中的这一条:

The software does something that the product specification says it shouldn’t do.

在皇帝的说明书里,爱上儿子老婆继而扒灰最终导致王朝更替这种事情是绝对不被允许的。偏偏唐明皇这么干了……这是他在经历了长达数年的运行期之后暴露出来的大Bug!有些Bug就是酱紫的,要运行N久才会出现。

根据伟大诗人白居易的描述,其实,唐明皇的遭遇也是可以理解的,因为Bug无处不在又深情款款。它对唐明皇这款软件许下了海枯石烂的誓言:

在天愿作比翼鸟,在地愿为连理枝。 天长地久有时尽,此恨绵绵无绝期。

如此深情,你怎么能拒绝呢,怕是只能溶化了吧。

编程技巧