电话

18600577194

当前位置: 首页 > 资讯观点 > 软件开发

软件项目中技术债务大部分是糟糕管理者造成的

标签: 软件项目开发 2025-12-24 

北京心玥软件公司用了大量时间写关于技术债务的内容,宣扬整洁代码实践,倡导合理的架构设计。我曾告诉开发人员如何避免它,如何偿还它,如何与管理者协商。

但事实是:我之前部分错了。

不是关于那些实践——那些依然有效。甚至不是关于“技术债务”这个词的所有用法。而是关于不加批判地接受这个框架。

技术债务不仅被误解了;它从根本上就是一个破碎的隐喻,扭曲了我们对软件开发的认知。最糟糕的是,我们还在继续使用它,因为这是高管们唯一能理解的金融隐喻,这意味着我们不得不以那些积极掩盖事实真相的方式,向他们解释工程问题。

技术债务如何形成的

❓隐喻的问题所在

WardCunningham在1992年创造了“技术债务”这个词,用来描述一种特定场景:故意选择一个快速的实现方式,同时明白之后需要重构。就像金融债务一样,你现在借用时间,承诺未来连本带利偿还。

但大多数公司里实际发生的是这样的:

管理者:“为什么这个功能花了这么久?我以为你说两周能完成?”

工程师:“嗯,我们有很多技术债务要处理……”

管理者:“呃,你们当初为什么不写好点?”

就这样,工程师成了坏人。成了“欠债的人”。成了“走捷径的人”。成了阻碍公司发展的人。

但这完全是胡扯。

🗳债务意味着你有选择

真正的债务是这样的:你去贷款机构,协商条款,签合同,同意偿还本金加利息。你明白交易的代价。你是自愿的。

技术债务呢?实际发生的是:

管理者:“这个项目必须在周五前上线,给投资者演示用。”

工程师:“时间不够,没法做好。至少需要三周才能正确构建。”

管理者:“不管用什么方法,让它能运行就行。”

[三个月后]

管理者:“这代码库简直一团糟。”

看到了吗?工程师没有“借”任何东西。他们没有选择债务。他们是在不可能的约束下,做了能做的最好的事。现在,他们却要为“利息”负责。

这不是技术债务。这是管理决策的技术后果。

🗿所有代码都会老化(这不是债务,是熵增)

还有一件事让我抓狂:把任何旧代码都称为“技术债务”。

你用了四年的代码库,用的是React16而不是最新版本——这不是“债务”。你的API返回XML而不是GraphQL——这不是“债务”。大家都希望改成微服务的单体应用——这不是“债务”。

那只是存在于时间中的代码。

需求会变。平台会进化。最佳实践会转移。新框架会出现。你的代码写出来时的上下文,和它现在运行的上下文已经不一样了。

把这称为“债务”,意味着有人犯了错。意味着疏忽。意味着如果工程师更聪明、更有远见、更有能力,这个问题就不会发生。

但软件不是这么工作的。没有什么是能提前预测的。你不能为还不存在的需求构建。就算你能,也会过度设计,浪费时间在永远用不到的灵活性上。

💳管理者说的“债务”,工程师说的“权衡”

每一个工程决策都是权衡。不是有些,不是大多数——所有都是。

速度vs灵活性

简单vs功能

成熟技术vs前沿技术

自建vs外购

单体vs微服务

SQLvsNoSQL

测试覆盖率vs上线速度

这些问题没有“正确”答案。只有“符合我们当前上下文、约束和优先级的正确答案”。

好的管理者明白这一点。他们会参与这些决策。他们会说:

“我们现在优先考虑速度,因为需要验证市场。等产品市场契合后,我们再重新审视架构。”

糟糕的管理者会说:

“不管用什么方法,让它能运行就行。自己想办法解决。”

然后之后:

“为什么有这么多技术债务?”

🙈真正的问题:复合无知

当管理者不理解维护成本的复合增长时,就会发生以下情况:

第一年:“快速上线!别管完美的代码!”

第二年:“为什么新功能开发变慢了?我们以前上线那么快!”

第三年:“我们得停止所有功能开发,重构整个系统。”

这不是技术债务。这是管理不理解软件维护不是免费的。每一次功能添加都会增加系统的“表面积”。每一个依赖都需要更新。每一个API都需要版本控制。

工程师知道这些。他们告诉过你。但你没听,因为你只关注下一个季度的业绩。

➖好的,但真正的捷径呢?

好吧,是的。有时候工程师确实会走捷径。我们跳过写测试。我们硬编码值。我们没有正确处理错误。我们复制粘贴而不是抽象。

但你知道吗?这几乎总是外部压力导致的。

“这个演示明天就要用!”

“客户威胁说如果这周不上线就取消合作!”

“我们在大出血,现在需要收入!”

就算真的是糟糕的工程决策,也几乎都是在压力下做出的——时间有限、信息不全,而且……你猜对了,来自管理层的压力。

🔧不舒服的真相:有时候真的是糟糕的工程

好吧,我得承认一个事实——我不想让工程师们完全脱责。作为工程师,我们需要为我们的工艺负责。有时候,代码真的很烂,不是管理的问题。

有时候你雇了一个开发人员:

•不懂他们用的编程语言或框架

•复制StackOverflow的答案却不理解

•写了十二层嵌套的条件语句,因为他们从没学过提前返回

•创建了有5000行的“上帝类”,因为“把所有东西放在一起更容易”

•拒绝学习或成长,因为“我一直都是这么做的”

有时候,你们的代码审查流程烂透了,这些垃圾代码还是能上线。比如:

“橡皮图章式代码审查”:有人在周五下午4:45提交了一个PR,有847行修改,分布在23个文件里。审查者扫了一眼,没发现明显的语法错误,就点了“通过”,赶紧去度周末了。

“territorial资深工程师”:有个“资深”工程师很有领地意识,谁要是敢提重构建议,他就会写一篇2000字的文章骂你,然后接下来三周都用被动攻击的Slack消息骚扰你。

“没有标准的团队”:有些团队真的没有任何编码标准。没有风格指南。没有架构原则。没有统一的模式。每个人想怎么写就怎么写——有人用函数式编程和不可变数据结构,有人用面向对象和重度继承,有人上周刚学了依赖注入,现在什么都往里面注入,还有人只想着上线,根本不在乎这些。

结果呢?代码库像弗兰肯斯坦一样,每个模块都像不同公司写的。

💬没人愿意谈的细节

现在问题变得复杂了。因为即使代码真的因为工程失败而变烂,“技术债务”这个说法还是错的。

为什么?因为叫它“债务”还是会:

•把它描述成故意的权衡(不是)

•暗示它应该“偿还”(应该修复)

•掩盖根本原因(招聘、培训、代码审查或标准问题)

如果你雇了不够好的人,那是招聘问题。如果你的代码审查没发现问题,那是流程问题。如果你的团队没有标准,那是领导问题。如果新人写的代码无法维护,那是mentorship问题。

这些都不是“债务”。它们是组织失败,以代码质量问题的形式表现出来。

而最关键的是:即使这些失败,往往也能追溯到管理决策。是谁决定:

•雇最便宜的开发人员,而不是最好的?

•跳过面试的技术部分,因为候选人“看起来很聪明”?

•不给资深工程师留时间做代码审查和mentorship?

•从不投资建立团队标准或架构指南?

•优先考虑故事点,而不是代码质量?

看,我们又回到了管理问题。

™️工程师什么时候需要负责?

但我们也不能完全放过自己。作为工程师,我们需要为我们的工艺负责。我们需要:

•真正审查代码,而不是“橡皮图章”

•像专业人士一样给出和接受反馈

•投资学习和成长

•遇到问题时寻求帮助

•在PR中反对糟糕的代码,即使这会让你不舒服

•作为团队建立和维护标准

如果你没看PR就批准了,你要为那部分代码负责。如果你因为不想麻烦而写了糟糕的代码,那是你的问题。如果你五年都没改变糟糕的编码模式,还拒绝学习,那你就是问题所在。

区别在于:当我们为自己的失败负责时,我们才能真正解决问题。我们可以改进代码审查文化。我们可以提升技能。我们可以建立更好的实践。

但如果我们躲在“技术债务”这个模糊的借口后面,我们就无法解决问题,因为我们甚至没有识别出真正的问题。

🤔那我们应该叫它什么?

与其叫“技术债务”,不如试试这些说法:

•“过去业务决策的技术后果”——虽然冗长,但准确。让责任归属清晰。

•“维护成本”——每个代码库都有。它会随着时间增长。为它做预算。

•“上下文转移”——两年前有意义的事,现在可能没意义了。这很正常。

•“必要的重构”——软件在进化。重构是正常的。别把它当成惩罚。

•“学习的成本”——你不知道你做的东西会成功。现在你知道了。是时候优化了。

🔚底线

技术债务不是迷思,因为捷径不存在。它之所以是迷思,是因为这个隐喻被扭曲得面目全非。

它变成了管理者用来:

•把业务决策的责任推给工程师的工具

•避免为资源分配负责的借口

•把正常的软件进化说成是疏忽的手段

•逃避为不可能的截止日期负责的借口

好的管理者会承担权衡的责任。他们会说:“我们选择了速度而不是灵活性,现在需要重新优化。这需要时间和资源。我会分配这两者。”

糟糕的管理者会用后见之明攻击。他们会说:“你当初应该把它做好。为什么有这么多技术债务?”

如果你是管理者,读到这里,如果你曾经抱怨过技术债务,问问自己:你有没有给团队足够的时间和资源来“做好”?你甚至知道“做好”是什么意思吗?还是你只是想要它上线?

如果你是工程师,读到这里,别再为不是你的决策承担责任了。下次retro时,有人提到技术债务,试试这么说:

“让我们谈谈做这些决策时的约束。因为我敢肯定,我们在当时的信息和时间下,已经做了最好的选择。”

如果他们反驳?如果他们坚持说这是你“欠”的“债务”?

开始找新的软件公司吧。因为你在为一个不懂软件开发的人工作,当事情变难时,他总会责怪你。