如何避免代码毁灭人类

如果你的代码能够毁灭人类,请您不要这样做。如果你不知道你的代码是否能够毁灭人类,那就请好好看看这篇文章,之后看看自己的代码是否有可能毁灭人类,请尽快修改。谢谢。

最近公司的客户遇到了大麻烦,遇到了客退,原因是设备在某天的凌晨开始不能正常工作了,重启也无效。在疫情的大环境下,这个问题可能会被放大。因为出现问题的用户是在西非某国,该国的疫情也开始爆发了,并且医疗水平都很有限。出现问题的用户都去维修站修理的话,会造成人员聚集,使得疫情更加严重,后面就不敢想象了,并且已经惊动了客户的大老板,客户的大老板直接向我司的最高领导报告了这个事情,要求尽快处理。
我司的分工是这样的,设备的研发有独立的团队,客户的支持有独立的团队,如果客户出现了问题,先会由客户支持团队负责,查找问题,帮助客户解决,负责和客户的沟通等。如果问题的确是是我司设备的问题,就由设备研发团队进行解决,内部也要合入patch,并release正式patch给客户,说白了代码是研发团队负责维护,而客户支持一般都了解代码大体的意思,对代码本身没有修改的义务,也不能进行修改。
我这边负责这个项目的客户支持,根据客户描述和trace分析,很快就定位到了问题。原因很简单,就是这个设备会保存数据到file,而保存的数据来自于网络,一个设备目前最多可以保存4个这样的网络数据,数据写到file的时候,通过“,”来区分不同网络的数据,如下:
network1data,network2data,network3data,network4data
每次收到网络数据的时候就会更新数据到file,假设更新的数据是第二个,network2data需要替换为network2newdata,更新的方法是这样的,首先定义了一个数组,数组长度是MAX_DATA,根据经验数组的长度不会超过MAX_DATA,就这样先把network1data读取到数组中,在network1data后添加一个“,”,需要替换第二个数据,就直接把network2newdata写入到数组中,添加一个“,”,之后把network3data和network4data写入到数组中。这个方法不知道什么原因,可能是为了后面设备的扩展,认为设备以后能最大处理10个网络数据,在把network4data写入到数组后,还在读取file中的数据,但是没有读取到,就会在数组的后面继续添加“,”,最后数据数组中的数据会变成下面的样子,后面会多了6个“,”
network1data,network2newdata,network3data,network4data,
函数流程会继续处理上面数组中data,从后往前删除没有数据的”,”,直到遇到数据,也就是处理完后,变成了下面的样子
network1data,network2newdata,network3data,network4data
最后才会把数组中的数据一起覆盖原先的file中。
不知道上面有没有说明白,基本意思就是用了一个数组处理数据,并且是定长的,数组的长度是根据经验来的,其实是在经验的基础上这个长度完全足够了,还有很多富余。
这段的处理方法足足运行了7年,没有发生任何问题,也从来没有人改过,就在那里默默的执行,没有任何人关注,这段代码自从被写出来后,代码所属于的module的owner都换了4,5个人,这段代码都没有任何改动。
就那么突然的出现了问题,毫不夸张地说,对公司和客户产生了很大的负面影响,在往大了说,真的有可能让西非这个国家的疫情更加严重,雪上加霜。出现问题的地方就是接收的网络数据突然包含了“,”,大家可以推断一下根据上面的逻辑。如果原始数据是
network1data,network2data,network3data,network4data
更新的还是network2data,但是这次网络数据报送的内容包含了一个逗号内容是
network2newdata,stop covid
按照上面的更新方法就变成了
network1data,network2newdata,stop covid,network3data,network4data
如果后面还要更新第二个数据,数据中还是有”,”,数据内容还是network2newdata,stop covid,那么更新后的内容就变成了
network1data,network2newdata,stop covid,stop covid,network3data,network4data
数据就会越来越长,并且其他模块想取出对应的网络数据也是不对的,直到数据达到了数组的最大长度,上面的处理过程在将数据写入数组的时候,有限制写入数据的长度,不会将数组写越界,但是再向数据末尾加“,”的时候是强制加的,没有判断数组是否已经满了(因为根据经验不可能将数据写满),就这样数组写越界了,导致NE,即使重启也没有作用,因为file的数据不会被清除,当收到网络数据的时候还是继续写数据,还是继续NE。
那问题查清了就容易解决了,这个函数的研发团队马上做了修改release patch给客户,内部合入patch,提供方法将写坏的file进行恢复,最终问题解决了,没有引起西非国家的疫情的蔓延,没有出现更危险的情况。

当我回首这个问题的时候,想了很多。
0 一个BUG造成的影响可能极其的坏,甚至是我们想象不到的,虽然只要几行代码就能改好,但是造成的问题引起的蝴蝶效应有谁又能够预料呢?
1 如果一个设备使用率很高的时候,如果这个设备突然出现了问题,产生的影响不可估量。例如汽车,如果汽车控制设备突然坏了,汽车失灵,造成交通事故,火车飞机等等都是一样的,这些案例已经很多了。如果是手机出现了问题,影响也是很严重,家人生病,不能打ECC,人命关天,这个也是有案例的。另外如果是家里的冰箱或者空调出现了故障,释放有毒物质,那也不得了呀。还有很多很多设备都有可能造成很大的灾难,医疗设备那就更不用说了。是否真的有一天人类让软件毁灭了呢?
2 一段代码即使能够无误的运行很多年,只要代码还在运行,那就有潜在风险,这个风险就不能忽略。
3 代码只要被写出来后,天然的带有作者的属性了,后面即使改动,只要不是完全重写,这个基因就不能被磨灭。
4 每个人都要为自己的代码负责,只要现在你负责这块代码,无论是否是你写的,那现在就是你负责。我们还是要能够对自己的代码熟悉,不要等到有了问题,才去看,才去关注,那时候可能真的完了。当然由于项目的增长和交接等问题,一个人很难看完所有的代码,这个时候就需要一些自动化工具来检查代码是否有潜在风险,这种工具现在还是很成熟的。
5 对于老代码,在写出来的时候可能完全符合那时的条件和情形,只不过随着时间的推移,外部条件发生了变化,老代码已经不能适应新的情况了,这个时候必须要对老代码做改动,当然要控制好引入的新问题。
6 由于代码天然的带有作者的基因,代码就是作者的孩子,那就要向对待自己的孩子那样,对待自己的代码。那就要对自己的代码负责,一定严格,来不得半点马虎,函数宁可多做保护,数据检查,多推导逻辑是否正确,是否有异常需要处理,也不要想当然。这个例子就没有考虑到数据保护“,”的情况。写完后多做一些测试,保证代码的质量。
7 多看专家的代码,了解专家这样写代码的意图,提高自身代码的质量。
8 做好代码的review工作,上面出现问题的代码,我司当时还没有review的机制。
9 公司应该形成一种风气,相互比拼代码质量,对原有代码做review,对暴露潜在风险的人员应该有奖励。
10 不要太相信经验,因为经验只是对过去的总结,而一切都在变。
11 不要不合理的过度设计。
12 不要盲目地认为自己的工作没有价值,可能我们的价值只是别人没有看到而已,没有人懂我们而已。但我们至少是懂代码的,作为程序员,这是一件多么开心的事呀。

最后希望大家不要自己挖坑,给别人还是自己,多挖矿。如果人类真的有一天毁灭了,我希望也不要是软件的BUG造成的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值