程序员在代码里面“埋炸弹”这件事情其实已经屡见不鲜了,所谓“炸弹”其实就是比较严重的BUG,而我们公司最近新上的一个项目就遇到了这种事情,负责这个项目某个模块的程序员竟然一不小心埋了一个特大的“炸弹”,最后老板连夜让公司财务给程序员买机票,说什么也要在这个“炸弹”爆炸前把问题给处理掉,到底发生了什么事情呢?



先说下这个程序员老A吧,老A在运动控制领域其实已经深耕多年了,但是不代表他就不会出现比较严重的错误!

老A负责的这个模块实际上是一个运动控制模块,模块主要任务就是通过程序来操纵轴到指定位置进行生产,您可以把客户那边需要生产的东西看作“棋盘”,老A需要做的就是把“棋子”准确得放到“棋盘”的每一个格子上。

但是,理想很丰满,现实很骨感,客户在实际生产过程中,“棋子”其实很难做到100%准确落到格子的正中心,所以,老A还需要做一件事情,就是根据客户那边视觉系统的检测结果,对每次“棋子”的落点进行校正处理。

具体的做法,就是每次在“落子”之前,都要检查上一次“棋子”落的位置,然后跟“棋盘”标准点的位置进行比较,然后进行校正。

简单描述整个系统的运行过程,大致就如上所说,但是实际上这个校正逻辑是非常复杂的,需要配合算法来实现,而老A埋的“炸弹”其实就是在算法代码里!

其实,这个“炸弹”理解起来并不复杂,这需要从校正逻辑说起。

校正逻辑非常复杂,为了便于理解,我们直接跳过中间过程,看看逻辑最终需要实现的目的,而这个目的,就是要让轴在每一次生产完一个产品后都往某一个方向偏移一点,直至每个“棋子”的落点都离“格子”尽量得近位置为止。但是,在这个过程中,可能往单一方向移动,会出现判断错误的情况,因此,当移动特定次数以后,“棋子”的落点依然不标准,反而和标准点的距离越拉越大的时候,需要往反方向移动,以此类推。

老A的逻辑就是这样的,我们原定的方案是每次生产完一个产品,把轴往左边偏移指定的距离,一共移动10次,如果10次偏移完以后,检测结果还是不好的,那么就反过来,把轴往右边偏移10次。

在代码里面,处理起来也很简单,就是每次生产完的时候,往数据库存一个移动次数的值,再存一个方向的值,当次数大于等于10的时候,把次数清零,把方向值反过来即可。

那么,老A到底埋了一个怎样的“炸弹”,要让老板连夜组织人手去处理这个问题呢?

问题就出在移动次数上,简单地说,老A其实在代码里面判断得很严谨,但是最终在存储移动次数时却没存储成功,这是咋回事呢?

道理其实很简单,那就是老A在存储移动次数时,走得是更新数据库表的逻辑,但是这个移动次数表字段是后加的,而更新前需要将表数据先查出来,然后逐个字段更新,但是在数据库更新语句里并没有把这个字段的更新语句给加上去,最终导致这个字段的值始终都为0!

这会导致什么问题呢?那就是老A代码中的对于偏移次数的判断就失效了,这会导致轴会一直往一个方向偏移,最终“撞机”!

在运动控制领域,“撞机”是个很严重的问题,运动轴一般只在指定区域里作业,轴如果超过一定的区域限制,那么就会产生很严重的后果。

那么“撞机”怎么理解呢?其实我们可以把运动轴看作一条船,船只能在水域行驶,“撞机”就好比船撞到了岸边或者已经驶上了岸,这肯定是不被允许的。

我们也可以想象一下,两个都在工作的机械臂如果撞到了一起,会产生什么后果吧!所以“撞机”在很多情况下,后果非常严重。

当然了,为了防止“撞机”出现,设备在设计之初就已经设计了“防撞”功能,会增加一定的限位措施,还是以船举例子,您可以把限位措施看作有人在岸边摆上了一层轮胎或者气垫,当船要撞上岸边时,这些轮胎或者气垫可以给船起到缓冲作用,对船起到保护作用,此时船只要正确驶离岸边即可。

但是,老A的代码里面偏移次数这个变量的失效,当发生第一次“撞机”以后,设备会进行报警,但因为每次偏移都往一个方向偏移,因此,即使报警取消了,设备下一次还会“撞机”报警,最终导致设备无法进行正常生产。

好在客户那边到现在没有反馈设备有“撞机”的情况出现,就说明老A的那段有问题的代码还没被触发,说明客户生产情况良好。但是,如果一旦出现某次检测结果不好,触发了老A的那段代码逻辑,这个隐患就会出现,所以,这个问题不能等!

结语

后来,老A赶了最早的飞机飞到客户那里,随便扯了个谎把程序给更新了,这个事情到现在老A都心有余悸,如果真的出现“撞机”的情况,用老A自己的话说:“真怕晚节不保了!”。

不过说起来,老A埋的这个“炸弹”其实还是挺低级的,只要仔细测试检查就可以测试出来,也从侧面证明了,不管是多么资深的程序员,也是会写出低级错误的代码的!不出事,就是最大的幸运了!让我们引以为戒!

ad1 webp
ad2 webp
ad1 webp
ad2 webp