技术债务:一笔没人愿意承认的复利

先别把它当成一个纯粹的技术问题

前阵子和一家做支付的公司聊。他们的发布流程是这样的:每周三晚上十点,后端全员到场。一个人点发布按钮,另外五个人盯着监控大屏。谁都不敢先走。 这个仪式,持续了四年。 我问CTO,为什么不换成灰度加蓝绿?他说,改是能改。但改完之后,没人敢保证那套对账逻辑还对不对。那是2016年写的,作者早走了,注释只有一行字——“勿动”。 你看,这就是技术债务。它不在代码里。它在人的日程表里。 很多团队对技术债务的理解停留在“代码写得丑”。错得离谱。代码丑不丑,编译器根本不在乎。真正让人难受的,是每一次改动都要先做一遍考古工作——读历史提交、问离职同事、在预发环境上小心试探。这些动作不产出任何业务价值,但一个都省不掉。 把它们加起来,就是利息。

Ward Cunningham 说的其实不是烂代码

1992年,Ward Cunningham 借用了金融里的债务隐喻,描述第一次交付时那种“不成熟的代码”。他的原意相当中性:就像借钱买船出海,赚了钱再还债。债务本身是加速器。 他后来自己都抱怨过,这个隐喻被彻底曲解成了“写得烂”的同义词。 差别在哪?借债得有明确的债权人和还款计划。大部分团队有吗?没有。所以严格说,它们干的不是借债。是非法集资。 我更喜欢一个更窄的定义:技术债务是当前决策对未来变更成本的折现。关键词是“变更成本”。 这解释了一个反直觉的现象。有些团队代码质量报告很漂亮,交付速度却一直上不去。因为它们的债务压根不在可读性上。在耦合上。两个模块之间那根隐形的线,比任何一坨屎山都致命。
软件模块耦合度依赖关系可视化分析图
软件模块耦合度依赖关系可视化分析图
还有一件事得说清楚:三年没人碰的丑代码,不产生任何利息。反过来,一个抽象过度、层层封装的漂亮模块,如果处在高频变更的路径上,利息能高到让你怀疑人生。债务计息的前提是“有人在用”。没用它,它就是块石头。

为什么没人能算出一张技术债务的资产负债表

为什么没人能算出一张技术债务的资产负债表
为什么没人能算出一张技术债务的资产负债表
财务债务可以计量,因为你借的是钱。钱有单位。技术债务借的是时间,而时间的计价基准每天都在变。 所以业界的那些代理指标,基本都靠不住。 **圈复杂度**。一个塞了四十个 case 的解析器,复杂度报表爆红。但如果业务规则三年没变过,它反而比一套优雅的策略模式更安全——策略模式的抽象边界,很可能一开始就猜错了。 **测试覆盖率**。见过覆盖率 90% 的仓库,里面大量断言写的是 `expect(result).toBeDefined()`。零价值。但它让报表好看,让团队心里踏实。这是最恶劣的一种债务形态:伪装成资产的负债。 **代码异味扫描**。Sonar 这类工具给出的数字,是风险的代理指标,不是风险本身。把代理指标做成合并门禁,结果就是工程师花两周去写规则豁免——比修代码还累。 现实就是这样:技术债务目前只能做到相对排序。哪几个模块最烫手,哪条链路变更最频繁。想要绝对计价?做不到。任何宣称能算出“贵司技术债务共 XXX 万元”的产品,先问它利息率怎么定的。它多半答不上来。

AI 正在制造一种全新的债务形态

2023年之后,代码的生成成本掉了。写一个 CRUD,写一层适配,写一套脚手架,几乎免费。 但审查成本没掉。 这是最要命的不对称。生成一秒钟,审查十分钟。当生成量涨十倍、而审查带宽纹丝不动的时候,多出来的那部分代码去了哪? 被“看起来没问题”地合并了。 我们内部管它叫审查债——没人真正读过的代码,以事实资产的形式活在生产环境里。 后果长什么样?我见过好几个项目,三个月后没人能解释某个分支判断为什么存在。翻 git blame,提交者是 Copilot,提交信息写着 “refactor”。这不是科幻。这是正在发生的事。
开发团队代码评审会议白板讨论照片
开发团队代码评审会议白板讨论照片
再深一层的问题:AI 生成的代码倾向于“统计上常见”的写法。而“统计上常见”,往往意味着依赖某个流行库的某个默认行为。长期看,这会把技术选型的多样性压扁。生态层面的债务,正在以同质化的形式悄悄累积。 一旦某个被广泛依赖的包出事——xz utils 那次后门,或者 Log4Shell——冲击面比五年前大得多。

谁在为这笔债付钱

谁在为这笔债付钱
谁在为这笔债付钱
技术债务有一条很清晰的产业链,只是很少有人把它连起来看。 **上游是工具链。** 静态分析、SAST、依赖扫描、代码可视化、SRE 平台。这个市场过去十年的叙事一直是“帮你发现问题”。问题是,发现问题的边际价值正在快速衰减。多数团队不缺问题列表。缺的是“先修哪个”的判断力。 **中游是平台工程。** Kubernetes、内部开发者平台、服务网格。它们有个不太被提起的隐性卖点:容器化是偿还历史债务的一条捷径——把老系统装进新盒子,先跑起来再说。止痛效果很好。但债务只是转移了。从应用层转到配置层。现在很多公司的债,是 YAML 里的债。 **下游是人力市场。** COBOL 工程师的时薪这些年一直在涨。不是因为 COBOL 优雅,是因为银行的账还在上面跑。这是一笔非常诚实的定价——债务的利息,直接印在工资单上。

治理的目标不是清零

我的立场很明确:“技术债务清零”是个有害的目标。 理由简单。清零意味着更高的抽象、更完备的测试、更严格的规范。全都要花当期产能。而债务的产生速度,是由业务变化速度决定的。业务越快,债务越快。想清零,等于让公司别再变了。 可行的做法只有三条。 **一,标出高息债务。** 看变更频率,不看丑陋程度。git log 里一年改五十次的文件,才值得动。一年改零次的?先放着,别浪费时间。 **二,给修复配预算,而不是配口号。** 硅谷流传很久的“20% 时间”,多数公司执行不下去,因为没法验证。更实际的做法是把重构和生产需求塞进同一个迭代队列排队,让产品经理和工程师当面对吵。吵出来的优先级,比制度文件真实得多。 **三,让债务可见到能被非技术的人听懂。** 别说“这个模块圈复杂度 47”。要说“这个模块的存在,让我们每次调价都要多花三天做回归测试”。 至于把技术债务写进 OKR 或者做成考核项……我持保留意见。一旦它变成 KPI,就一定有人去刷。前面说的那种“假绿”,就是这么长出来的。

未来三到五年,我押注的三个判断

未来三到五年,我押注的三个判断
未来三到五年,我押注的三个判断
**第一,债务分析会从静态转向运行时。** 静态代码分析已经卷到底了。增量价值在“这段代码在真实流量下的变更成本是多少”。谁先能量化真实变更成本,谁拿下下一波。 **第二,AI 会让两个极端同时放大。** 强团队在 AI 加持下,能把债务维护做成常态化流程——每次合并顺手清掉相关模块的一小块。弱团队则会在生成出来的代码堆里越陷越深。因为它们的瓶颈从来不是写作速度。是判断力。 **第三,遗留系统迁移会从“重写”转向“包壳”。** 全量重写的成功率历来不高,业界这几年学乖了。用 API 网关、事件代理、数据同步把老系统围起来,让它当个黑盒继续跑,现实得多。代价是——你会得到一套崭新的、分布式的债务。只是这次的债主,比较分散。 最后说一句。 技术债务最难受的地方,不在于它存在。而在于它总是被当成一件“之后再说”的事。 而“之后”……永远不会自己到来。

作者|fawen

排版|fawen

审核|小准

免责声明:市场有风险,选择需谨慎!此文仅供参考,不作买卖依据。如有侵权请联系删除。
文章名称:技术债务:一笔没人愿意承认的复利
文章链接:https://m.lfdjt.com/info_23_31314.html