技术债的接力棒

1 阅读1分钟

小娇第一次听说"技术债"这个词,是在他接手一个系统的第三天。

那天他打开代码仓库,看到一个函数,函数名叫doSomething,函数体有四百行,注释只有一行,写在最顶上:

// 这里比较复杂,暂时先这样。

暂时先这样,落款时间:2019年。

小娇当时不知道"技术债"是什么,但他知道这玩意不是好东西。他去问双吉,双吉从抽屉里翻出一个马克杯,往里面倒了点冷咖啡,说了一句话:

"技术债就是你欠下的,但要别人还的钱。"

一、遥遥领先的屎山

部门的代码库,是一个在烂的赛道上遥遥领先的存在。

这不是骂人,这是事实。小娇接手过的系统里,有一个核心模块,代码写于2011年,经历了七任开发,没有一任留下过完整的文档。每一任都在上面加了点东西,加完拍拍屁股走人,留下一层新的地质沉积。到小娇接手的时候,那个模块已经长成了一座地层丰富、结构复杂、无人敢动的文化遗址。

小娇翻了三天,找到了十四种不同风格的命名规范、五套互相冲突的配置逻辑,以及一段被注释掉但谁都不敢删的代码,注释写着:

// 不知道为什么,删了就报错,先留着。

落款时间:2015年。

那段代码到今天还在。

这不是骂人,这是事实。小娇接手过的系统里,有一个核心模块,代码写于2011年,经历了七任开发,没有一任留下过完整的文档。每一任都在上面加了点东西,加完拍拍屁股走人,留下一层新的地质沉积。到小娇接手的时候,那个模块已经长成了一座地层丰富、结构复杂、无人敢动的文化遗址。

小娇翻了三天,找到了十四种不同风格的命名规范、五套互相冲突的配置逻辑,以及一段被注释掉但谁都不敢删的代码,注释写着:

// 不知道为什么,删了就报错,先留着。

落款时间:2015年。

那段代码到今天还在。

二、有这么好的"设计"你怎么不早点告诉我

小娇接手系统的时候,前任给他留了一份文档。

文档标题叫《系统架构设计说明》,小娇打开,第一页是一张架构图,画得相当漂亮,模块清晰,箭头整齐,层次分明。他看了十分钟,越看越觉得有点不对——这个架构图上的模块,跟他这三天看到的代码,好像不是同一个系统。

他去问前任。前任说:"对,那个图是当初设计的时候画的,后来实现的时候改了一些。"

小娇问:"改了哪些?"

前任想了想:"大部分。"

小娇沉默了一会儿,心里说了一句话:卧槽有这么好的设计文档,你怎么不早点告诉我它是假的?

三、把问题留给未来的人,是一门显学

小娇后来总结,技术债的生产方式大概分三种。

第一种叫主动埋雷。开发的时候知道这里有问题,但deadline到了,先上线再说。上线之后问题没爆,就进入了一种薛定谔状态——它可能是定时炸弹,也可能永远不会爆。开发者选择相信后者,然后换了个项目。

第二种叫被动遗忘。当初写这段代码的时候完全没意识到有问题,后来意识到了,但系统已经在跑了,动起来风险太大,于是在旁边开了个新路,绕过去,把那段问题代码永久性地供奉起来。供奉的时间久了,没人记得为什么要绕,只知道不能动,动了就出事。

第三种叫创新性甩锅。这是最高境界。开发者在写代码的时候就知道这东西将来会出问题,于是精心设计了一套"扩展性极强"的架构,留下一份"后续优化空间巨大"的文档,然后在述职报告里写上:本模块采用前瞻性设计,为未来业务发展预留了充足的技术空间。

翻译成人话就是:这坨屎我帮你成型了,后续的事你看着办。

四、接棒人的五个阶段

小娇接手屎山之后,经历了标准的五个心理阶段。

第一阶段:震惊。这代码真的在跑?这系统真的在生产环境?这注释真的是人写的?

第二阶段:否认。不对,肯定是我没看懂,这里一定有什么深意,我再研究研究。研究了三天,发现真的没有深意。

第三阶段:愤怒。上一任是什么水平?这段代码是怎么过CR的?这个设计是谁拍板的?愤怒持续了大约一周,然后发现上一任已经升职了,拍板的领导还在,CR那天所有人都在开会没时间看。

第四阶段:接受。好,就这样。能跑就行,别动,动了出事是我的责任。

第五阶段:传承。deadline到了,先上线再说。这里比较复杂,暂时先这样。

于是新的一层地质沉积,悄悄形成了。

五、双吉的终极预言

小娇有一次问双吉:这个循环有没有终点?

双吉把咖啡杯放下,说:"有。"

小娇问:"什么时候?"

双吉说:"系统下线的时候。"

小娇想了想:"那如果系统一直不下线呢?"

双吉重新端起咖啡杯:"那就一直传下去。你现在还的债,是2011年的人借的。你现在借的债,2035年的人来还。生生不息,绵延不绝。"

他喝了一口,补了一句:

"这不叫技术债,这叫技术信仰。相信总有人会帮你擦屁股,而且他们真的会。"

后记

小娇后来在一次code review里,看到一段新人写的代码。逻辑清晰,命名规范,注释详细,边界条件都考虑到了。他当时有点感动,在评论区写了一句:

"写得很好。"

然后他往下翻,看到那段代码的最后一行注释:

// 这里有个边界case没处理,暂时先这样,后续优化。

小娇盯着那行注释看了很久。

他什么都没说,点了approve。

传承,就是这样完成的。