没人因简化而升职
Source: Hacker News
“简洁是一种伟大的美德,但它需要艰苦的努力才能实现,也需要教育才能欣赏。而更糟的是,复杂性更好卖。” — Edsger Dijkstra
隐藏的问题
我认为有件事正在悄悄地搞砸许多工程团队。在面试、晋升材料和设计评审中,工程师 过度构建 能获得引人注目的叙事,而交付 最简可行方案 的工程师却……什么也没有。
这当然不是有意为之。没有人会坐下来说,*“确保那些过度工程的人员得到晋升!”*但这正是公司在错误评估工作时可能发生的情况(而且一次又一次地发生过),当公司错误地评估工作时。
两位对比鲜明的工程师
工程师 A
- 被分配一个功能。
- 看问题,考虑几个选项,选择最简单的方案。
- 编写约 50 行的直接实现。
- 易于阅读,易于测试,后续人员也能轻松接手。
- 几天内交付并继续下一个任务。
工程师 B
- 被分配一个类似的功能。
- 看到构建更“稳健”系统的机会。
- 引入新的抽象层、用于组件通信的发布/订阅系统,以及面向未来可扩展性的配置框架。
- 用时三周,涉及多个 PR,在分享配套设计文档时还配上了大量兴奋的表情符号。
当晋升时机到来时,工程师 B 的工作几乎自动写进了晋升材料:
“设计并实现了可扩展的事件驱动架构,引入了被多个团队采用的可复用抽象层,并构建了支持未来可扩展性的配置框架。”
这几乎在喊出 Staff+。
对于工程师 A,叙事几乎不存在:
“实现了功能 X。”
三个字。她的工作更好,但因为她让它看起来很简单而变得不可见。没有人会因为避免了复杂性而得到晋升。
为什么复杂性会受到奖励
复杂性看起来很聪明——并不是因为它真的聪明,而是因为我们的系统被设定为奖励它。激励问题并不是在晋升时才开始的;它在你甚至还没得到这份工作之前就已经出现了。
面试
在系统设计环节,你提出一个简单的方案:单一数据库、直接的 API,或许还有一个缓存层。面试官问道,*“可扩展性怎么办?如果有一千万用户会怎样?”*于是你在白板上加入了服务、队列、分片以及更多的机器。面试官最终似乎满意了。
你得到的教训是复杂性会给人留下深刻印象。简单的答案并没有错;只是它不够有趣。(面试官有时确实有理由在规模上进行深入探讨,但如果候选人的收获是“简单不够”,那就说明有问题了。)
设计评审
一位工程师提出了一个干净、简洁的方案,却被质问*“我们不应该为将来做好准备吗?”*于是他们回去添加了目前并不需要的层次、为可能永远不会出现的问题做的抽象、为没有人提出的需求提供的灵活性。并不是因为问题本身要求这样,而是因为在场的人期待如此。
我见过工程师(我自己也曾是其中之一)为了避免重复几行代码而创建抽象,结果却得到一个比重复本身更难理解和维护的系统。每一次看起来都像是正确的做法。代码看起来更“专业”、更“工程化”。但用户并没有更快得到他们的功能,下一位工程师在进行任何修改之前必须花半天时间去理解这些抽象。
当复杂性实际上是正确的选择
现在,我要说清楚:复杂性有时是正确的选择。
- 如果你在处理数百万笔交易,可能需要分布式系统。
- 如果有十个团队在同一个产品上工作,你可能需要服务边界。
当问题复杂时,解决方案(可能)也应该如此。
问题不在于复杂性本身;而是不应有的复杂性。两者之间有区别:
- “我们已经触及数据库限制,需要分片。”
- “我们可能在三年后会触及数据库限制,所以现在就分片。”
真正的技能:知道何时 不 增加复杂性
有些工程师懂得这一点。当你看到他们的代码(以及架构)时,你会想,“嗯,是啊,当然。” 没有魔法,没有巧妙之处,也没有让你因不懂而感到愚蠢的东西。这正是重点所在。
The actual path to seniority 并不是学习更多的工具和模式;而是学习 何时不使用它们。任何人都可以增加复杂性。要有经验和自信才能不去使用它们。
我们能怎么做?
“保持简洁”说起来容易,改变激励结构却更难。
对工程师而言
-
让简洁性可见。 工作本身并不会自动说明一切,这并不是因为它不好,而是大多数系统并未被设计成能够“听见”它。
-
有策略地谈论自己的工作。
- 而不是:“实现了功能 X。”
- 说:“评估了三种方案——包括事件驱动架构和自定义抽象层——并确定直接实现能够满足所有当前及预期的需求,且在两天内交付,六个月内零事故。”
决定不构建某个东西也是一种决定,而且很重要!请相应地记录下来。
在设计评审中
当有人问,“我们不应该为此做未来兼容吗?”时,不要自动妥协去添加层。请用简明的理由回应:
“我们评估了未来兼容的选项,得出结论:当前范围不足以证明需要额外的抽象层。现在添加只会增加维护负担,却没有可衡量的收益。”
结束思考
复杂性容易展示;简洁性却容易被忽视。通过明确阐述简洁方案背后的权衡,我们可以将叙事从“越多越好”转向“恰到好处更好”。这反过来又使晋升、面试和评审与工程师真正的价值保持一致:交付可靠、可维护的软件,并保持最小必要的复杂度。
如何倡导简洁(并获得认可)
1. 用数据框定决策
“这里是如果以后需要时再添加它所需的工作量,以及现在添加它的成本。我认为我们等一等。”
- 你并不是在推脱;而是展示你已经做好了功课。
- 你已经考虑了复杂性,并且有意识地选择不承担它。
2. 与你的经理提出
“我想确保我的工作文档能够反映我的决策,而不仅仅是我写的代码。我们能否讨论一下如何在我的下次评审中表述这一点?”
- 大多数经理会欣赏这一点,因为这让他们的工作更轻松。
- 你为他们提供了可以用来为你争取的语言。
3. 解读结果
-
如果团队仍然晋升构建最复杂系统的人:
- 这是一条有用的信息。
- 它告诉你所在的文化是什么样的。
-
两种可能的文化:
- 重视简洁——良好的判断力会被认可。
- 声称重视简洁却奖励复杂——你可以继续迎合这种游戏,或者寻找一个真正认可良好判断的地方。
-
至少你会知道自己处于哪种文化中。
如果你是工程领导
你设定激励,无论你是否意识到。大多数晋升标准都是有意或无意地奖励复杂性。“影响力”往往通过某人构建的规模和范围来衡量,即使避免不必要的复杂性也应该受到重视。
A. 改变你提出的问题
-
设计评审:
- 与其问“我们考虑过规模吗?”不如问:
“我们可以交付的最简版本是什么?哪些具体信号会告诉我们需要更复杂的方案?”
这使得简洁成为默认,并将证明复杂性的责任转移到复杂方案上。
- 与其问“我们考虑过规模吗?”不如问:
B. 在晋升讨论中提出反驳
-
当晋升材料是一长串听起来很厉害的系统时,问:
“所有这些真的都有必要吗?我们真的需要在这里使用发布/订阅系统吗,还是它只是看起来很漂亮?”
-
当工程师交付了简洁且干净的东西时,帮助他们撰写叙述:
“评估了多种方案,选择了能够解决问题的最简方案。”
这确实是一个有说服力的晋升案例——前提是你把它当作晋升案例来对待。
C. 公开表彰简洁
- 如果团队频道里的每一次表扬都是针对大型、复杂的项目,那么大家就会为此进行优化。
- 开始表彰:
- 那位删除了死代码的工程师。
- 那位说“我们暂时不需要这个”,且判断正确的人。
Bottom Line
如果我们继续奖励复杂性而忽视简洁性,那么当我们得到的正是这种结果时,就不该感到惊讶。解决方案并不复杂——我想,这正是重点所在。