一、那行红色报错

凌晨一点半,整栋楼安静得只剩下我桌上那台机器在喘气。风扇的嗡嗡声很规律,像某种固执的白噪音,反而让我安心。我盯着屏幕右下角那行红色报错,已经看了快四十分钟。

不是看不懂。恰恰相反,是它太懂我了。我写的逻辑,它照单全收,一路绿灯,然后在我最意想不到的那个分支上,冷不丁给我一巴掌。年轻时候遇到这种事,我会拍桌子,会觉得这破电脑故意跟我作对。现在不会了。四十五岁的好处之一,就是慢慢明白,有些 bug 不是靠情绪解决的,是靠把一把椅子坐热,把一杯水喝凉,再把那几十行自己写的代码从头读一遍。

我也说不清从什么时候起,深夜成了我效率最高的时段。孩子睡了,消息不响了,连楼下的野猫都收了声。世界把音量调到最小,我终于能听见自己脑子里那根一直绷着的弦,慢慢松下来。旁边那杯茶是晚上十一点泡的,那时候我以为再熬半小时就能收工,结果一熬就是三个钟头。茶凉了,问题还在。

二、十年前犯过的错

问题出在一个边界条件上。用户留空的时候,我没有兜底,下游直接炸了。说起来有点可笑,这种错我十年前就犯过,当时还被带我的老大在评审里点名。十年过去,框架换了三代,语言升了两版,可我还是在同一个坑里栽了一次。

我把自己十年前的提交记录翻出来看,那行注释还在:"这里要判空。" 字是我写的,语气还是当年那种自以为是的干脆。我盯着它笑了半天。原来我不是忘了,是以为自己已经不会再忘了。其实 bug 这种东西,最怕的不是难,是熟。越熟练,越容易跳过去那行最该看的地方。我后来养成个习惯,凡是不放心的地方,一律当成会出事来写。麻烦是麻烦了点,但夜里能睡安稳。写代码十几年,我学会最贵的一课,就是别跟自己的人性较劲——你会忘,你会懒,你会想当然,所以把兜底写死,比相信记忆力靠谱。

改完,本地跑通,提交,流水线一路变绿。那一瞬间没有什么成就感,只有一种很轻的、像是终于把一口闷了很久的气缓缓吐出来的松弛。窗外的天还是黑的,但我知道,明天早上不用再为这个东西头疼了。

三、老伙计

关掉编辑器之前,我顺手把今天的进度存了盘。屏幕暗下去,房间里只剩路由器的指示灯在一闪一闪,像谁在远处眨眼睛。有人问过我,写代码这么多年,腻不腻。我说不上热爱,但也谈不上腻,更像是一种和老伙计的关系——它不完美,我也一样,我们凑合着,把一件件该做的事做完。

前两天组里来了个年轻人,看我改一个老接口,忍不住说哥你这写法太土了。我没生气,只是把十年前的那次事故讲给他听。他听完没说话,回去默默把自己的代码也加了一行判空。有些东西不靠说,靠时间自己长出来。

有时候我觉得,bug 才是程序里最诚实的部分。它不掩饰,不讨好,你哪一行漏了,它就明明白白告诉你,绝不绕弯子。人到中年,身边的人和事越来越复杂,反倒越来越欣赏这种直来直去。改完最后一个 bug,我伸了个懒腰,听见颈椎咯吱响了一声,像是也在替我下班。