维修漏洞
凌晨三点,维修漏洞我盯着屏幕上的维修漏洞报错日志,咖啡杯沿凝着褐色水渍。维修漏洞第无数次,维修漏洞那个漏洞又出现了——像老屋墙角渗水的维修漏洞裂缝,补了这边,维修漏洞那边又洇开。维修漏洞这已经是维修漏洞本周第三次了。 漏洞这东西很有意思。维修漏洞它不声不响地躺在代码深处,维修漏洞平时看不见摸不着,维修漏洞非要等到某个特定的维修漏洞输入、某个巧合的维修漏洞并发,才突然咬你一口。维修漏洞上个月生产环境的维修漏洞事故,就是一行if判断里少了个等号。数据错乱,客户投诉,运维小哥半夜打电话把我从被窝里拽起来。修复只花了十分钟,但排查用了整整四个小时。那四个小时里,我盯着屏幕,感觉自己像个拿着手电筒在黑暗仓库里找一根针的人,明知针就在某处,却怎么也照不到。 后来我养成个习惯:每次修复完漏洞,都会在代码旁边留一行注释,写上“为什么这里会出错”而不是“这里修复了什么”。同事说我啰嗦,但三个月后,当另一个新人踩进同一个坑时,那行注释救了他半天时间。代码会说话,但大多数时候,它说的是谎话——表面逻辑没错,真正的问题藏在逻辑之间的缝隙里。 有些漏洞是技术问题,有些不是。上周我处理过一个“漏洞”,查了半天发现是产品经理的需求文档写反了字段含义。程序忠实地执行了错误的需求,就像一台精准的复印机,把原稿上的错别字一字不漏地放大印出来。我该修程序还是该修文档?最后两个都改了,还在团队周会上提了一句。没人接话,但会后产品经理悄悄给我发了条消息:“谢谢你没在会上点名。” 最麻烦的是那种“结构性漏洞”——修好一个,牵动三个。像老房子改电路,你想换根保险丝,结果发现整面墙的线都老化了。这时候你得退一步,别急着动手,先画张图,把数据流向、依赖关系、边界条件全摆出来。有次我花了两天画图,第三天动手只改了几十行代码,但测试通过率从91%提到了99.6%。剩下的0.4%是已知风险,我写在文档里,标了黄色高亮。领导问能不能到100%,我说能,但需要重构整个模块,周期两周。他想了想,说:“黄色可以接受。” 说到底,修漏洞修的不只是代码,是判断力——什么该补,什么该忍,什么该推倒重来。我见过有人花三天修一个边缘情况下的bug,只为了那0.01%的发生概率;也见过有人用一个临时补丁堵住大洞,然后告诉所有人“没事了”,结果半年后补丁自己生锈了,洞比原来还大。 现在凌晨四点,那个漏洞终于定位了——不是逻辑错误,是第三方接口的返回格式在我们升级后悄悄变了。对方文档写的是“可选字段”,但实际运行时偶尔会传空字符串。我的代码没处理这种情况,于是它就像个不懂变通的保安,遇到没见过的通行证就拦住所有人。 修复很简单,加一行判断。但我没立刻提交,先写了条测试用例,模拟那个空字符串的场景,然后才补上代码。运行,全绿。提交,写注释:“第三方接口返回格式存在非文档化行为,需防御性处理。”关掉电脑前,我把那行注释又看了一遍,觉得下次要是再碰到类似的事,应该能少走点弯路。 窗外天快亮了,麻雀开始在空调外机上叽叽喳喳。漏洞修完了,但我知道明天还会有新的——代码写不完,漏洞也补不完,这就是这行的日常。不过没关系,每次补完一个洞,我都会对系统多一分了解。那种感觉,有点像老中医摸脉,摸得多了,指尖就有了记忆。