Nobody Gets Promoted for Simplicity

We reward complexity and ignore simplicity. In interviews, design reviews, and promotions. Here’s how to fix it.

terriblesoftware.org

本文探讨了软件工程领域中一个普遍存在的悖论:尽管“简洁”是极高的美德,但在职业晋升和企业评估体系中,往往是“复杂”获得了奖赏。作者指出,工程师们经常陷入过度工程化的陷阱,因为复杂的系统更容易构建出令人印象深刻的晋升叙事(如“设计了可扩展的事件驱动架构”),而选择最简单、最有效方案的工程师由于其成果过于“隐形”,往往在评审中被忽视。这种激励错位不仅存在于晋升环节,还根植于面试筛选和设计评审中。面试官倾向于通过增加系统复杂度来考察候选人,导致开发者误以为“复杂即专业”。

作者强调,真正的资深并非掌握更多工具,而是具备“何时不使用它们”的判断力。为了扭转这一局面,工程师需要学会为简洁“正名”,将“不做什么”的决策过程文档化,并向管理者展示简洁背后的思考深度。同时,工程领导者负有更大的责任,应从制度层面改变激励结构,在评审中质疑复杂性的必要性,并公开表彰那些通过减少代码、拒绝不必要需求而创造价值的行为。最终,只有当企业文化真正开始奖励“未被构建的复杂性”时,团队才能摆脱冗余架构的泥潭,回归高效开发的本质。


主题 1:复杂性的“叙事红利”与简洁的“隐形代价”

在职业晋升的语境下,工作成果的“可见性”往往比其“正确性”更影响结果。作者通过 Engineer A 和 Engineer B 的对比,揭示了工程文化中一个残酷的现实:复杂性自带光环,而简洁性则趋于透明。

Engineer B 构建了一个包含抽象层、发布/订阅系统和配置框架的复杂结构。尽管这花费了三周时间且可能引入了过度设计,但它在晋事报告中呈现出一种“架构师”的姿态。这种叙事充满了行业术语和宏大愿景,极易被非技术背景或忙碌的高层管理者识别为“高价值贡献”。这种“叙事红利”诱导工程师去解决那些并不存在的问题,因为解决复杂问题的过程比避免问题发生的过程更容易被量化和表彰。

相比之下,Engineer A 选择了最直接的 50 行代码实现。这种方案虽然在工程质量上更优(易读、易测、低维护),但在评估体系中却面临“隐形代价”。因为她做得太好了,以至于看起来毫无难度。人们往往无法感知到那些被成功规避的故障、被节省下来的维护时间和被拒绝的冗余架构。这种评估体系的缺陷导致了“劣币驱逐良币”:追求卓越工程实践的开发者被边缘化,而制造复杂麻烦再将其解决的人却成为了英雄。要打破这一循环,企业必须意识到,代码行数和架构复杂度不应是衡量能力的尺度,真正的价值在于用最小的成本达成目标。

主题 2:从面试到评审:复杂性偏见的系统性渗透

复杂性崇拜并非偶然,而是一种从入职第一天起就被灌输的系统性偏见。作者指出,这种偏见在面试环节就已经根深蒂固。在系统设计面试中,面试官往往预设了一个“大规模分布式系统”的答案。如果候选人提出一个简单、稳健的单机数据库方案,面试官会不断通过“如果有一千万用户怎么办”来施压。这种压力迫使候选人展示他们对分片、缓存、消息队列等复杂工具的掌握,从而传递了一个错误信号:简单的方案是不专业的,只有复杂的方案才能体现水平。

进入职场后,这种偏见在设计评审(Design Review)中进一步发酵。评审会议往往变成了一种“证明自己很聪明”的竞技场。当一个简洁的方案被提出时,同行评审者为了体现自己的参与感,往往会提出“未来扩展性”或“灵活性”的问题。为了通过评审,工程师不得不添加那些“也许三年后才有用”的功能。这种“未来预测”往往是极度不准确的,但它在当下却能给评审者和开发者带来一种安全感和专业感。

这种系统性的渗透导致了“未得之利”的泛滥:工程师们在没有实际业务压力的情况下,提前引入了只有巨头公司才需要的复杂架构。这不仅降低了开发速度,还增加了系统的脆弱性。作者认为,这种文化的本质是缺乏对“不确定性”的敬畏,人们试图通过增加代码的复杂性来对抗未来的不确定性,结果却在当下制造了真实的混乱。

主题 3:重构激励机制:如何为“简洁”正名

要扭转崇拜复杂性的风气,不能仅靠口头号召,必须从工程师的自我表达和领导者的评估逻辑这两个维度进行彻底重构。

对于工程师个人而言,必须掌握“简洁的修辞学”。既然系统无法自动识别简洁的价值,开发者就必须主动将其转化为可感知的贡献。这意味着在撰写工作总结或晋升材料时,重点不应仅仅是“我做了什么”,而应是“我选择了不做哪些复杂的事情,以及为什么这种选择对公司更有利”。通过对比不同方案的成本、风险和长期维护代价,将“选择简单”包装成一种深思熟虑的战略决策,而非偷懒或能力不足。这是一种认知的转变:简洁不是结果,而是一种需要被辩护和证明的成就。

对于工程领导者(Manager/Director),他们握有改变文化的最有力杠杆。领导者需要重新定义“影响力”。影响力不应只是“管理了多少个微服务”,而应包括“通过优化架构减少了多少系统复杂性”。在评审中,领导者应扮演“奥卡姆剃刀”的角色,质疑每一处不必要的抽象。更重要的是,领导者应在公共场合公开表彰那些删减代码、合并冗余系统或通过极简方案解决重大问题的行为。当“删除代码”和“增加功能”获得同等的荣誉时,团队的价值观才会发生实质性偏移。最终,一个健康的工程组织应该能够识别并奖励那种“看起来毫不费力”的深度,因为那才是真正经验和智慧的结晶。


原文摘录

  1. “简洁是伟大的美德,但它需要艰苦的工作才能实现,需要教育才能欣赏。更糟糕的是,复杂性更好卖。” —— 引用 Dijkstra 的名言,一针见血地指出了简洁的困境。
  2. “没有人会因为规避了复杂性而获得晋升。” —— 全文的核心论点,揭示了职场评价体系的盲点。
  3. “你无法为一个你‘没有’构建的东西写出引人入胜的叙事。” —— 解释了为什么简洁的工作在晋升材料中显得苍白无力。
  4. “真正的资深之路不在于学习更多的工具和模式,而在于学习何时不使用它们。” —— 重新定义了高级工程师的核心竞争力。
  5. “任何人都能增加复杂性。只有经验和自信才能让你选择留下空白。” —— 强调了简洁背后所需的心理素质。
  6. “如果你的团队频道里所有的公开表扬都给了那些庞大、复杂的项目,那么人们就会针对这一点进行优化。” —— 提醒管理者,他们的表态决定了团队的行为导向。

核心问答

Q1:作者认为“简洁”在职场中难以获得回报的根本原因是什么?

A: 根本原因在于信息的非对称性评估体系的叙事偏见。在大多数公司中,评估者(管理者或晋升委员会)无法实时观察工程师的思考过程,只能通过最终产出的“文档”和“系统规模”来反推其贡献。 复杂性具有一种“天然的视觉冲击力”。一个拥有多层架构、分布式中间件和复杂配置系统的项目,在文字描述上显得逻辑严密、技术难度高、考虑周全,符合人们对“高级工程”的刻板印象。而简洁的方案往往只有寥寥数行代码,其背后的“权衡、调研和对过度设计的克制”是隐形的。 此外,企业往往错误地将“解决问题的难度”等同于“产出的价值”。Engineer B 制造了一个复杂的系统并解决了其中的复杂问题,这看起来像是在攻坚克难;而 Engineer A 通过巧妙的设计直接绕过了这些问题,这种“预防胜于治疗”的智慧在缺乏深度技术洞察的评估体系中,往往被误判为“任务太简单”。

Q2:在面试和设计评审中,为什么“未来预测”和“扩展性”会成为复杂性的推手?

A: 这是因为**“防御性工程”心理职业安全感的博弈。在面试或评审中,提出“如果未来用户增长 100 倍怎么办”是一个永远不会出错的“安全提问”。提问者通过这种方式展示自己的远见,而开发者为了证明自己“想得深”,被迫在方案中加入各种应对极端情况的补丁。 这种行为本质上是在用确定的当下成本**(开发时间、系统复杂度、维护难度)去对冲不确定的未来风险。大多数情况下,这种对冲是极度不划算的,因为初创功能往往在达到那种规模前就已经夭折或转型。然而,在企业政治中,如果系统因为简单而崩溃,开发者会被指责“缺乏预见性”;但如果系统因为过度复杂而导致开发缓慢或维护困难,这种责任往往被摊薄在整个团队的“技术债”中,开发者反而可能因为处理这些复杂问题而显得勤恳。这种风险规避的博弈导致了复杂性的不断堆叠。

Q3:作者建议工程师如何通过“改变叙事方式”来保护自己的职业发展?

A: 作者建议工程师将**“决策过程”**而非“最终代码”作为工作展示的核心。 具体的策略包括:

  1. 显性化权衡(Trade-offs): 在文档中详细记录你评估过的复杂方案。例如,不要只写“用了单机数据库”,而要写“评估了分片集群和 NoSQL 方案,但基于当前 QPS 预测和运维成本,选择了更稳健的单机方案,为团队节省了 X 周的部署时间”。
  2. 量化简洁的红利: 强调简洁带来的附加值,如“零线上事故”、“极短的测试周期”、“新成员仅需 10 分钟即可上手”。
  3. 定义“不做的决策”: 将拒绝某个流行技术或复杂架构定义为一种“架构决策”。在晋升材料中,将“成功规避了不必要的系统耦合”作为一项核心成就。 这种做法的逻辑延伸在于:工程师需要从单纯的“执行者”转变为“战略决策者”。你需要告诉公司,你的价值不在于写了多少代码,而在于你作为专家,如何通过判断力为公司选择了成本最低、收益最高的路径。

Q4:工程领导者应该如何从制度上设计,才能让团队真正追求简洁?

A: 领导者必须建立一套**“逆向激励”机制**,打破“大项目即大贡献”的迷信。

  1. 改变评审默认值: 在设计评审中,将“证明为什么需要复杂性”作为开发者的义务,而不是让追求简洁的人去证明为什么不需要。如果一个方案包含超过必要的组件,领导者应要求其提供具体的触发指标(例如:当延迟达到多少毫秒时,我们才引入缓存)。
  2. 奖励“负代码”: 将删除冗余代码、简化系统架构、合并重复模块作为高优先级的 KPI。如果一个工程师能把一个三层架构简化成两层且功能不变,这应该获得比开发新功能更高的荣誉。
  3. 重构晋升标准: 在晋升指南中明确加入“架构判断力”和“简洁性”维度。询问评审委员会:“这个候选人是否展示了在面对诱惑时保持系统简单的能力?”
  4. 公开表彰的导向: 领导者在全员会议上的表扬应更多地投向那些“优雅解决问题”的小而美项目,而不是那些因为架构太重而不得不反复修补的“巨型项目”。通过这种信号传递,重塑团队的审美和价值观。

Q5:这篇文章的理论边界在哪里?什么时候“复杂性”是真正必要的?

A: 作者明确指出,他反对的是**“未赚取的复杂性”(Unearned Complexity)**,而非所有复杂性。 复杂性的必要性通常由以下边界决定:

  1. 物理限制的倒逼: 当单机性能达到极限、数据库连接数耗尽或网络带宽成为瓶颈时,分片、分布式、异步化等复杂性是生存的必需。
  2. 组织规模的压力: 当一个项目有 10 个以上的团队协作时,为了解耦开发进度,引入微服务或复杂的接口契约是必要的“组织成本”,尽管它增加了技术复杂度。
  3. 业务本质的复杂: 某些领域(如金融清算、高性能计算、复杂的合规审计)其业务逻辑本身就是多维且严苛的,此时简洁的方案可能会因为覆盖不足而导致严重的业务风险。 核心逻辑的薄弱环节在于:“简洁”与“简陋”往往只有一线之隔。 缺乏经验的工程师可能会以“追求简洁”为借口,逃避必要的架构设计或编写缺乏鲁棒性的代码。因此,推崇简洁的前提是团队具备极高的技术素养,能够区分什么是“为了简单的简单”,什么是“深思熟虑后的极简”。