概述
本文探讨了软件工程文化中一个令人沮丧的现象:工程师们往往因为过度工程化而获得认可和晋升,而那些选择简洁、有效解决方案的人却被忽视。文章引用Edsger Dijkstra的名言——"简洁是一种伟大的美德,但需要努力工作才能实现,需要教育才能欣赏。更糟糕的是,复杂性卖得更好"——作为核心论点,深入剖析了这一偏见的根源,并为工程师和领导者提供了应对策略。
详细内容
核心问题:复杂性偏见
两种工程师的对比
文章通过对比两位工程师的工作成果,揭示了工程文化中的评价偏见:
工程师A:简洁方案
- 用简单有效的方法快速交付
- 代码量少,易于理解和维护
- 解决了实际问题,没有过度设计
- 结果:工作被视为"微不足道",难以在评审中展现"技术深度"
工程师B:复杂方案
- 花费数周构建一个"健壮"的系统
- 引入微服务、分布式缓存、消息队列等架构
- 即使这些对于当前需求是过度设计
- 结果:获得晋升,因为创造了关于"规模"和"架构"的引人注目的叙事
偏见的根源
1. 可见性偏见
- 复杂系统更容易被"看见"和讨论
- 简洁方案往往"隐形",因为其优雅在于不引人注目
- 评审者倾向于将代码量和工作量等同于价值
2. 叙事的力量
- 晋升评审需要故事,而复杂系统提供了更好的故事素材
- "我设计了一个支持百万并发的分布式架构"比"我写了一个简单的脚本"更有冲击力
- 这种叙事需求驱动了过度工程化
3. 风险规避心理
- 选择复杂方案可以被视为"为将来做准备"
- 如果简单方案未来出现问题,决策者会被指责考虑不周
- 如果复杂方案现在过度设计,却很少被追究
偏见的传播路径
面试环节
这种偏见从招聘阶段就开始渗透:
- 候选人的压力:面试者感到必须展示复杂的技术栈才能给面试官留下深刻印象
- 信号传递问题:简单的答案可能被视为准备不足或能力不足
- 恶性循环:面试官期待复杂性,候选人提供复杂性,入职后继续生产复杂性
典型场景
面试官问:"如何设计一个URL缩短服务?" 候选人内心:"如果我只说用一个哈希表,他们会觉得我太简单。我需要提到Redis、Kafka、分片、CDN..."
设计评审环节
在设计评审中,"未来证明"(future-proofing)成为过度设计的正当理由:
- 防御性设计:团队要求系统能够处理"未来可能"的规模
- 假设的累积:每个"万一"都增加一层复杂性
- 未赚取的复杂性:为尚未存在的需求付出代价
典型对话
"我们应该加上消息队列,万一以后需要异步处理呢?" "应该用上缓存层,虽然现在QPS只有10..." "微服务架构更好,虽然我们现在只有3个开发者..."
真正的专业素养:知道何时不使用工具
文章提出一个核心观点:
真正的资深工程师知道何时不使用工具。
专业素养的重新定义
| 常见误解 | 真正的专业素养 |
|---|---|
| 掌握尽可能多的技术栈 | 选择最合适的技术栈 |
| 能够设计复杂系统 | 能够识别何时不需要复杂系统 |
| 代码量大代表产出高 | 代码量少但解决问题代表效率高 |
| 使用最新技术 | 使用经过验证的成熟技术 |
简洁的代价
作者强调,简洁并非懒惰或能力不足:
- 简洁需要努力:识别核心问题,剥离不必要的复杂性
- 简洁需要勇气:在倡导复杂性的环境中坚持简单
- 简洁需要经验:只有经历过复杂性的痛苦,才知道简洁的价值
给工程师的建议
1. 文档化决策过程
不要只呈现最终的简洁方案,而要记录为什么选择简洁:
决策记录:
- 考虑过的方案:微服务架构 vs 单体应用
- 拒绝微服务的理由:当前团队规模5人,预期用户量<1000,微服务带来的运维成本超过收益
- 决策:采用单体应用,预留模块化接口以便未来拆分
- 复盘点:当用户量达到X时重新评估
2. 量化简洁的价值
用数据说话:
- "这个方案减少了80%的代码量"
- "部署时间从30分钟缩短到2分钟"
- "新功能开发周期从2周缩短到2天"
3. 建立个人品牌
- 成为团队里"能写出简洁代码"的人
- 在代码评审中倡导简洁
- 分享简洁设计的案例和经验
给领导者的建议
1. 改变激励机制
提问方式的转变
| 传统问法 | 更好的问法 |
|---|---|
| "这个设计能支持多大规模?" | "最简单的可行版本是什么?" |
| "用了什么技术栈?" | "为什么这些技术是必要的?" |
| "架构图有多复杂?" | "如何减少系统的复杂性?" |
2. 认可和奖励简洁
- 在团队会议上公开表扬简洁的设计
- 将"避免不必要的复杂性"纳入绩效评估
- 分享因过度设计而失败的案例
3. 建立防护机制
- YAGNI原则:You Aren't Gonna Need It(你不需要它)
- 最后责任时刻:推迟决策直到必须做出选择
- 复杂性预算:为每个项目设定复杂性上限
核心观点总结
"任何人都可以增加复杂性。需要经验和自信才能将其排除在外。"
这句话道出了软件工程的本质:
- 增加复杂性是容易的:添加新服务、新框架、新抽象不需要太多思考
- 保持简洁是困难的:需要深入理解问题,抵制诱惑,承担"看起来简单"的风险
- 经验的价值:经历过过度设计的痛苦,才能识别真正的需求
- 自信的力量:在倡导复杂的环境中坚持简洁需要勇气
观点存疑
-
是否过于简化了晋升机制?
- 现实中的晋升考量可能更加多元,包括领导力、业务影响力等
- 并非所有公司都单纯奖励复杂性,一些顶级工程文化(如Google、Stripe)确实重视简洁
- 作者可能基于特定环境(可能是创业公司或传统企业)的经验进行概括
-
复杂性的价值是否被完全否定?
- 有些复杂性确实是必要的,特别是在高规模、高可用场景下
- 文章可能低估了预判未来需求的合理性
- "过度设计"和"合理设计"的界限往往只有在事后才能清晰判断
-
对"简洁"的定义是否模糊?
- 不同人对简洁的理解可能不同
- 一个工程师眼中的"简洁"可能是另一个工程师眼中的"简陋"
- 文章没有提供判断简洁与简陋的具体标准
-
忽视了组织层面的结构性问题
- 复杂性偏见可能只是更大问题的症状,如技术债务管理不当、业务压力、人员流动等
- 单纯改变个人行为可能无法解决系统性问题
-
文化差异未被考虑
- 不同公司、不同国家的工程文化对简洁的态度可能不同
- 文章的观点可能更适用于某些特定文化背景
Tags
#软件工程 #工程文化 #简洁设计 #过度工程 #职业发展 #技术管理 #代码质量 #YAGNI #技术债务 #工程师成长