计算机与信息 · 12/14
技术债Technical Debt
技术债是用今天的省事,换取未来反复付出的维护与返工成本。
停用后没清理的旧代码,九年后让骑士资本付出了惨重代价。2012年8月1日,美股开盘后,这家位于美国新泽西州泽西市的交易商的错误程序开始向市场大量发送订单。技术人员更新软件时,漏掉了八台服务器中的一台,也没人复核。新功能沿用了旧功能的开关,漏更新的服务器于是启动了2003年已停用、却一直留着的程序。旧程序的停止条件又在后来的修改中失效,订单接连涌入市场。系统失控约45分钟,最终造成超过4.6亿美元损失。多年搁置的清理工作,在一次更新时集中找上了门。
为什么成立
省下的工作会附着在后续改动上
假设你负责客户系统,为赶上线,把同一份客户资料散放在几张表里,省下4天整理时间。此后每次改字段,都要逐表核对,额外花半天。经历20次改动后,彻底整理又要6天。累计多花的时间是:
也就是6天返工,加上10天反复核对;当初省下的4天,换来了后来16天的负担。
本金是修复工作,利息是额外负担
技术债指系统中遗留的缺陷或不合时宜的设计,让未来维护、修改更费力。本金是消除这些负担所需的工作;利息是保留它们时,多花的排查、绕行和救火成本。债既能来自有意赶工,也能来自早期认识有限:团队后来学会了更好的做法,旧设计却还留在系统里。
越多人依赖旧做法,偿还就越费力
债会变重,是因为新工作继续建立在旧做法上。更多报表引用了散乱的客户表,整理时就得一起修改,还要防止漏改。于是每次维护都更慢,彻底修复也更贵。若救火占满时间,团队又靠临时补丁赶进度,新的负担便继续留下。
借债值不值,要看提前交付换来了什么
提前交付能带来订单、现金或关键反馈时,有限的债可以值得承担。团队应写清留下了什么、谁来偿还、何时触发修复。优先处理频繁改动、反复出错的位置;修复后,同类改动耗时和故障是否下降,才说明这笔债还掉了。
出处
技术债来自软件工程。沃德·坎宁安在1992年的《WyCash投资组合管理系统》经验报告中,用债务解释先交付初版、再按新认识修订代码的做法。他把持续迁就旧代码的额外工作比作利息。出处是开发实践报告,核心依据是团队在持续修改中付出的代价。
换个领域看
商业运营
旧排班拖累复航
日常还能运转的旧流程,会把升级欠账藏起来。2022年12月,美国西南航空遭遇冬季风暴,排班技术和流程跟不上密集变动,员工转向人工处理,恢复更慢。公司取消了超过16700班航班。飞行员工会此前已警告技术和排班流程落后;压力骤增,让长期留下的负担集中显露。
投资
租金掩盖维修账
推迟维护,会让眼前收益显得更高。假设你买了一套出租房,为保住当年现金流,发现屋顶渗水后只在室内补漆。租金照收,水却继续浸坏墙体,下一次维修还要停租、换材料。这是技术债在资产维护中的类比:评估回报时,把欠下的修复费用和停租损失一起扣掉。
个人学习
跳过基础的代价
靠背答案赶过考试,会把没学懂的基础留给下一门课。假设你学统计时跳过条件概率的推导,只背题型。后来读医学检测报告,遇到换了一种问法的题,就得反复查解释,还要重学前面的知识。这是学习中的债务类比:补上那段基础,才能减少此后每次遇到它的额外绕路。
遇事时问自己
- 这条捷径今天省下了什么,又把哪项具体工作留给了以后?
- 未来哪些操作会碰到这笔债,每次要多花多少时间或钱?
- 提前交付的收益,能否覆盖预计的修复、额外维护和故障损失?
- 谁负责偿还,在下次扩张、修改或交接之前,哪个信号会触发修复?
- 如果现在只还一笔债,哪一笔能减少最多的反复返工?
边界与误用
只有当前做法让未来工作多付成本时,债务比喻才有用。一次性脚本用完即弃,未做的扩展功能也不会被用到,就没有相应利息。技术债不等于所有写得难看的代码:稳定而少改的旧实现,可以比重写更划算。利息随改动频率、依赖范围和故障风险变化,并无固定利率,也不会仅因时间过去就自动指数增长。最常见的误用是拿“以后还”替赶工开脱,却不给偿还留人和时间;另一个误用是追求零债,把本可带来收入或反馈的交付一直推迟。
练一练
你负责网店的结算系统,现在有两处代码可以整理。旧报表模块命名混乱,但近两年没改过,运行稳定,整理需半天。优惠券模块当初为赶购物节上线,把同一条规则复制到了五处。现在每次加活动,都要额外花3小时逐项核对,整理需两天。未来三个月已排定12次活动,你能拿出两天做改进。
这两天优先用在哪里,理由最站得住?
等故障发生再投入,看起来能避免无效整理。但重复核对已经在消耗时间,不必等到出错才值得处理。
接下来的12次活动预计会额外消耗36小时。用两天消除重复核对,有明确的回报,也能减少漏改机会。
混乱的命名确实会让人担心隐藏问题。但这里没有运行异常或频繁修改的证据,外观不足以压过已知的重复成本。
旧报表更容易整理,能很快看到成果。但积压时间和完成速度,不能说明它造成的后续负担更大。
当初复制规则省下了整理时间,却让此后的每次活动都要多做核对。整理模块是消除这笔负担的工作,重复核对则是保留现状时不断付出的成本。先处理哪一处,要看未来能减少多少返工。
你准备收购一家专印包装盒的印刷店。卖方为省下设备改造费,一直沿用只能手动定位的旧夹具,每换一种盒型都要额外调机两小时,还会损耗纸张。过去主要接同款大批量订单,账面利润不错。你计划改接多款小批量订单,并让旧夹具继续使用一年后再更换。
评估第一年的投资回报,哪种处理最合理?
多款小单可能带来更多收入,先接单也能获得反馈。但收入能否覆盖额外成本,需要估算,不能把新增收入直接当成回报。
第一年继续使用旧夹具的额外成本,与年底更换的支出,都要进入回报估算。订单结构改变,会让过去不显眼的负担变重。
按月预留资金有助于安排更换支出。但准备金不是调机和纸张损耗的估算,这些成本还会随换盒型的次数增加。
历史利润率和更换报价都是现成依据,便于估算。但新订单会更频繁地换盒型,旧利润率没有反映增加的调机和损耗。
沿用旧夹具省下了当时的改造费,却把额外调机和损耗留给后续订单。更换费用相当于本金,使用期间多付的成本相当于利息。换盒型越频繁,这笔利息越需要重新估算。
你给父母的金婚宴做了一张座位表。为赶印刷,姓名用了简称,排版也很乱。宴席已经结束,餐费结清,借用的物品全部归还。你只想把表夹进纪念册,不会再用它安排活动,也没有其他资料引用它。家人建议周末重做成规范模板,认为拖得越久,欠下的整理工作就越多。
对重做模板的建议,哪种判断最站得住?
把省下的工作补齐,容易让人觉得事情终于完整了。但省略过的步骤不一定需要补做,要看它是否造成后续负担。
这张表已经完成用途,也没有后续安排依赖它。排版混乱本身,并没有让未来工作反复多付成本。
提前准备模板,看起来能节省下次办宴席的时间。但这里没有复用计划,可能有用不等于已经欠下了必须补做的工作。
趁记忆清楚时整理,确实可能更容易。但没有后续使用需求,不能仅凭时间过去就推断负担不断增加。
债务比喻适用于当前做法让未来工作多付成本的情况。这张座位表已经完成用途,留存不会带来反复维护或返工。是否美化,可以按纪念价值决定。