软件工程的演化与不变
给软件工程画一张“跨代际地图”,重点包括:
- 用“洞察的半衰期”来区分什么值得长期深挖,什么只适合当作短期工具
- 按 七代演化 梳理软件开发从硬件、结构化、对象、网络、分布式、云原生一直到 AI 时代 的复杂性迁移
- 把不同阶段收敛到几类更底层的“永恒问题”,说明软件工程表面不断换壳,核心仍围绕复杂性、协作、抽象边界和不确定性展开
- 最后落到工程师个体:什么在变、什么不变,为什么跨代际工程师真正稀缺,以及 AI 时代仍然需要哪些稳定的工程纪律
软件工程的演化与不变
一份关于软件工程跨代际本质的整合地图
这份文档来自一次关于 AI 时代工程师工作方式的长对话。它不是教程,是一张地图——告诉你软件工程这片土地的地形,以及哪些地方值得深扎、哪些地方只是路过。
一、洞察的半衰期阶梯
任何洞察的半衰期,等于它所指向对象的变化周期。 这是判断"什么值得深度学习、什么用过即弃"的根本尺度。
| 洞察层级 | 半衰期 | 典型例子 |
|---|---|---|
| 关于人的本质属性 | 万年 | 奥斯汀对虚荣、自欺、择偶的洞察 |
| 关于人类协作和组织 | 几千年 | 《人月神话》、组织协作的根本规律 |
| 关于复杂系统的一般规律 | 几百年 | CAP、Conway's Law、复杂性守恒 |
| 关于某种工程范式 | 几十年 | OO 思想、声明式思维、不可变基础设施 |
| 关于某个具体技术栈 | 几年 | Spring Boot 最佳实践、React 模式 |
| 关于某个具体工具版本 | 几个月 | 某个 prompt 技巧、某 API 用法 |
核心判断:把注意力的大头投入到上面三层,把下面三层处理成"用完即弃的工具”,不要变成身份认同。
二、软件开发的七代演化
每一代不是工具更替,是"工程师该怎么思考"被重塑了一次。每一代都筛掉了一批没跨过去的人。
总览图
graph TB
S1["阶段一<br/>1940s-1950s<br/><b>从硬件到软件</b><br/>让机器做事"]
S2["阶段二<br/>1960s-1970s<br/><b>从过程到结构</b><br/>组织代码逻辑"]
S3["阶段三<br/>1980s-1990s<br/><b>从结构到对象</b><br/>组织大型代码库"]
S4["阶段四<br/>1990s-2000s<br/><b>从单机到网络</b><br/>处理网络不确定性"]
S5["阶段五<br/>2000s-2010s<br/><b>从集中到分布</b><br/>处理规模不确定性"]
S6["阶段六<br/>2010s-2020s<br/><b>从分布到云</b><br/>管理动态系统"]
S7["阶段七<br/>2020s 至今<br/><b>从代码到智能</b><br/>集成 AI 概率性"]
S1 --> S2 --> S3 --> S4 --> S5 --> S6 --> S7
style S1 fill:#fce4ec,stroke:#880e4f
style S2 fill:#fff3e0,stroke:#e65100
style S3 fill:#fffde7,stroke:#f57f17
style S4 fill:#f1f8e9,stroke:#33691e
style S5 fill:#e0f2f1,stroke:#004d40
style S6 fill:#e3f2fd,stroke:#0d47a1
style S7 fill:#ede7f6,stroke:#311b92
复杂性来源的演化
graph LR
A[阶段一二<br/>让机器做事] --> B[阶段三<br/>组织代码]
B --> C[阶段四五<br/>处理不确定性]
C --> D[阶段六<br/>管理动态系统]
D --> E[阶段七<br/>集成概率性 AI]
A -.关注.-> A1[硬件资源<br/>性能优化]
B -.关注.-> B1[抽象边界<br/>认知负担]
C -.关注.-> C1[网络/并发<br/>数据一致性]
D -.关注.-> D1[服务发现<br/>故障自愈]
E -.关注.-> E1[验证/约束<br/>对齐]
style A fill:#f9e,stroke:#333
style B fill:#fc9,stroke:#333
style C fill:#ff9,stroke:#333
style D fill:#9f9,stroke:#333
style E fill:#9cf,stroke:#333
阶段一:从硬件到软件(1940s-1950s)
范式转换:从直接操作硬件到用语言描述算法
复杂性主战场:如何让机器做事——硬件慢、内存小、要精打细算
具体例子:
- 早期的程序员要在打孔卡上手工编码,错一个孔整个程序作废
- 写一个排序算法要精确计算 CPU 周期和内存字节
- 内存以 KB 计算,每个变量的位置都要程序员自己规划
- 第一批 FORTRAN 程序员被 COBOL 程序员嘲笑"那个不算真编程”——因为太"高级"了
代表事件:FORTRAN(1957)、COBOL(1959)、LISP(1958)的出现
这一代被淘汰的人:拒绝从汇编/机器码迁移到高级语言的人——他们觉得高级语言"效率太低”、“不够纯粹”
跨代留下的东西:算法和数据结构的基础理论(几百年级别)。Knuth 的《计算机程序设计艺术》今天读依然有效。
阶段二:从过程到结构(1960s-1970s)
范式转换:从 GOTO 满天飞到结构化编程
复杂性主战场:依然是"让机器做事”,但开始向"如何组织代码"过渡
具体例子:
- 一个 5000 行的 FORTRAN 程序里有几百个 GOTO,每次修改都可能引发不可预测的行为——这种代码被叫做"意大利面条代码”
- Dijkstra 1968 年发表《GOTO 语句有害论》,引发持续多年的辩论
- 第一批"百万行级"软件项目(如 OS/360)出现,暴露了大型项目协作的根本难题
- Brooks 写《人月神话》(1975),讲他在 OS/360 项目上的教训——“给延期项目加人会让它更晚”
代表事件:Pascal、C 语言、结构化编程运动、第一批大型软件项目的失败
这一代被淘汰的人:习惯于"程序就是一连串机器指令"思维的人——他们写的"高级语言"代码本质上还是汇编结构
跨代留下的东西:
- 《人月神话》(1975 年至今依然字字珠玑)
- 结构化思维本身
- “本质复杂性 vs 偶然复杂性"的区分(几千年级别——因为它讲的本质是协作和认知)
阶段三:从结构到对象(1980s-1990s)
范式转换:从"功能 + 数据分离"到"对象统一”
复杂性主战场:如何组织大型代码库——百万行代码怎么不变成乱麻
具体例子:
- C 语言写 GUI 程序:每个窗口都是一堆全局函数 + 一堆全局变量,加一个新窗口要改十几个文件
- C++ 出现后:每个窗口是一个对象,封装自己的状态和行为,加新窗口只要继承基类
- Java(1995)的"Write Once, Run Anywhere"承诺,配合 JVM 让企业级开发爆发
- 第一批电商网站、银行系统用 Java/C++ 写出来,代码量从万行级跳到百万行级
- 设计模式 GoF 书(1994)出版,给"重复出现的设计问题"建立了共同词汇
代表事件:C++(1985)、Smalltalk 兴起、Java(1995)、设计模式运动
这一代被淘汰的人:写了几十年 C 的资深工程师里,相当一部分到死也没真正理解 OO——他们写的 Java 是"用 Java 语法写的 C 代码”,所有东西塞进一个 main 类的几十个 static 方法
跨代留下的东西:抽象、封装、模块化的根本思想(几十年级别)。GoF 设计模式部分过时(很多模式在动态语言里不需要),但"识别重复设计问题"的思路保留。
阶段四:从单机到网络(1990s-2000s)
范式转换:程序不再独立运行,要考虑网络、延迟、并发
复杂性主战场:如何处理不确定性——网络是不可靠的、延迟是真实的、并发是默认的
具体例子:
- 单机时代调用一个函数,要么成功要么失败,结果立即返回。网络时代调用一个 API,可能成功、可能失败、可能超时、可能成功了但响应丢了
- 第一批 Web 应用经常出现"用户点了提交,看到 loading,等了 30 秒,不知道订单到底有没有下"的尴尬
- Sun Microsystems 总结出"分布式计算的八条谬误”:网络是可靠的、延迟为零、带宽无限…每一条都是初学者的默认假设,每一条都是错的
- AJAX(2005)出现后,前端复杂度爆炸——同一个页面同时在和多个服务器异步通信
代表事件:互联网爆发、Web 开发、客户端/服务器架构、AJAX、Web 2.0
这一代被淘汰的人:做单机软件做得很好但理解不了"网络是不可靠的"的工程师——他们写的网络代码假设网络永远 OK,结果是无数生产事故
跨代留下的东西:
- 八条分布式谬误
- 对"不可靠"的本能尊重
- 异步思维的雏形(几十年到几百年级别)
阶段五:从集中到分布(2000s-2010s)
范式转换:从"数据有真相"到"数据有多个副本,永远不完全一致”
复杂性主战场:如何处理不确定性——但提升到了规模维度,整个系统永远处于部分故障状态
具体例子:
- Google 处理全球网页索引,单台机器装不下,必须分到几千台机器上——但任意时刻总有几十台机器在故障
- 双 11 期间,淘宝订单量峰值达到几十万 TPS,单个 MySQL 扛不住,必须分库分表
- CAP 定理(Brewer 2000,正式证明 2002)告诉所有人:一致性、可用性、分区容忍性三者不可兼得,必须取舍
- Amazon Dynamo 论文(2007)展示了"放弃强一致换可用性"的设计——这是个范式转换的标志
- “最终一致性"从异端变成主流——传统 DBA 接受不了"数据可能在不同时刻看起来不一样”
代表事件:MapReduce(2004 论文)、Hadoop、NoSQL 运动(2009 起)、CAP 定理形式化、Dynamo/Cassandra/Riak 等系统的出现
这一代被淘汰的人:优秀的传统 DBA——他们对 ACID 的信仰过深,过不了"放弃强一致"这一关;以及只会写单机算法的工程师,他们的算法在分布式环境下要么不正确要么不可扩展
跨代留下的东西:
- CAP 定理
- 最终一致性
- 共识算法(Paxos/Raft)
- 分布式系统设计的根本权衡(几百年级别——数学性质决定了它不会过期)
阶段六:从分布到云(2010s-2020s)
范式转换:从"我管理服务器"到"我描述意图,云替我管理”
复杂性主战场:如何管理动态系统——服务发现、自动扩缩、故障自愈
具体例子:
- 传统部署:买服务器、装系统、配网络、部署代码、配置监控——一个新服务上线要几周
- 容器时代:写一个 Dockerfile,几分钟启动一个标准化环境
- Kubernetes 时代:写一段 YAML 描述"我要 3 个副本、CPU 不够自动加、有副本挂了自动重启”——系统自己达成这个状态
- Netflix 的 Chaos Monkey 故意在生产环境随机杀掉服务器——逼迫系统设计成"故障是常态而非异常”
- Serverless 让开发者完全不用想服务器:上传一段函数代码,按调用次数付费
架构演化对比:
graph TD
subgraph "传统部署"
A1[物理服务器] --> A2[手工运维]
A2 --> A3[手工扩容]
end
subgraph "云原生"
B1[声明式描述] --> B2[控制器自动达成]
B2 --> B3[故障自愈]
B3 --> B4[自动扩缩]
end
A3 -.演化.-> B1
style A1 fill:#fcc
style A2 fill:#fcc
style A3 fill:#fcc
style B1 fill:#cfc
style B2 fill:#cfc
style B3 fill:#cfc
style B4 fill:#cfc
代表事件:Docker(2013)、Kubernetes(2014)、Serverless 概念兴起、IaC(Terraform 等)、混沌工程
这一代被淘汰的人:优秀的传统 SA/运维——他们的核心能力是"手工管理服务器”,云时代这个能力被自动化了;以及不愿意学 YAML 和声明式思维的开发者
跨代留下的东西:声明式思维、不可变基础设施、可观测性的核心思想、混沌工程理念(几十年级别)
阶段七:从代码到智能(2020s 至今)
范式转换:从"人写代码"到"人设计系统、AI 写代码、人验证”。从"确定性程序"到"包含概率性组件的系统”
复杂性主战场:如何把概率性 AI 集成进确定性系统——验证、约束、对齐
具体例子:
- 单个工程师 + Claude Code 一天产出 1700+ 行净增代码,等于过去一个团队的产出
- 个人项目从"想法到 MVP"的时间从几周压到几小时
- 但同时:AI 写出来的代码看起来整洁专业,但里面藏着隐性 bug、跨文件不一致、领域边界没考虑
- 工程师从"代码作者"变成"AI 团队的 Tech Lead”——不再写代码,而是审计、决策、建立规则
- CLAUDE.md、prompt engineering、agent 工作流——成为新的工程对象,也会过时、也需要维护
- 一个新的认知挑战:当 AI 不会真正反对你时,外部纠错机制(peer review、Pitest、用户反馈)变得空前重要
新角色对比图:
graph LR
subgraph 传统工程师
direction TB
T1[写需求] --> T2[设计]
T2 --> T3[写代码]
T3 --> T4[测试]
T4 --> T5[部署]
end
subgraph AI 时代工程师
direction TB
N1[设计架构与边界] --> N2[制定规则<br/>CLAUDE.md]
N2 --> N3[AI 写代码]
N3 --> N4[审核关键决策]
N4 --> N5[建立验证机制<br/>CI/Pitest]
N5 --> N6[漂移检测]
N6 --> N1
end
style N1 fill:#9cf
style N4 fill:#9cf
style N6 fill:#9cf
代表事件:GPT-3(2020)、Copilot(2021)、ChatGPT(2022)、Claude Code、Cursor、AI Agent 工作流、AI 原生应用兴起
这一代正在被筛选的人:
- 完全拒绝 AI 的工程师(速度跟不上)
- 完全依赖 AI 但没有工程思维的工程师(产出质量崩塌)
- 真正存活下来的:在 AI 加持下保持工程纪律的人
跨代留下的东西(预判):
- 在不可逆放大下保持工程纪律
- 在产出超过审核带宽时保证质量
- 人与概率性 agent 协作的方法论
- 这部分一旦沉淀,会是几十年到几百年级别
七代之间的连接
flowchart TD
Start([每一代都被前一代解决了某层问题<br/>所以下一代有能力关心更高层]) --> A
A[一二代<br/>解决了:把意图变成机器指令] --> B
B[三代<br/>解决了:组织大型代码库] --> C
C[四五代<br/>解决了:在不确定中协作] --> D
D[六代<br/>解决了:让系统自我维持] --> E
E[七代<br/>正在解决:与概率性 AI 协作]
E --> Pattern{每代关注焦点<br/>持续向上抽象}
Pattern --> P1[离硬件越来越远]
Pattern --> P2[离系统行为越来越近]
Pattern --> P3[离人和协作越来越近]
style Start fill:#fff,stroke:#333,stroke-width:2px
style Pattern fill:#ffd,stroke:#333,stroke-width:2px
七代的演化
阶段一:从硬件到软件(1940s-1950s)
- 范式转换:从直接操作硬件到用语言描述算法
- 复杂性主战场:如何让机器做事——硬件慢、内存小、要精打细算
- 代表事件:FORTRAN、COBOL、LISP 的出现
- 跨代留下的东西:算法和数据结构的基础理论(几百年级别)
阶段二:从过程到结构(1960s-1970s)
- 范式转换:从 GOTO 满天飞到结构化编程
- 复杂性主战场:依然是"让机器做事”,但开始向"如何组织代码"过渡
- 代表事件:Dijkstra 那场革命、第一批大型软件项目
- 跨代留下的东西:《人月神话》(1975 年至今依然有效)、结构化思维(几千年级别——因为它讲的本质是协作和认知)
阶段三:从结构到对象(1980s-1990s)
- 范式转换:从"功能 + 数据分离"到"对象统一”
- 复杂性主战场:如何组织大型代码库——百万行代码怎么不变成乱麻
- 代表事件:C++、Java、Smalltalk 的兴起
- 跨代留下的东西:抽象、封装、模块化的根本思想(几十年级别)。GoF 设计模式部分过时,但"识别重复设计问题"的思路保留
阶段四:从单机到网络(1990s-2000s)
- 范式转换:程序不再独立运行,要考虑网络、延迟、并发
- 复杂性主战场:如何处理不确定性——网络是不可靠的、延迟是真实的、并发是默认的
- 代表事件:互联网爆发、Web 开发、客户端/服务器架构
- 跨代留下的东西:八条分布式谬误、对"不可靠"的本能尊重(几十年到几百年级别)
阶段五:从集中到分布(2000s-2010s)
- 范式转换:从"数据有真相"到"数据有多个副本,永远不完全一致”
- 复杂性主战场:如何处理不确定性——但提升到了规模维度,整个系统永远处于部分故障状态
- 代表事件:MapReduce、Hadoop、NoSQL、CAP 定理形式化
- 跨代留下的东西:CAP、最终一致性、共识算法(Paxos/Raft)(几百年级别——数学性质决定了它不会过期)
阶段六:从分布到云(2010s-2020s)
- 范式转换:从"我管理服务器"到"我描述意图,云替我管理”
- 复杂性主战场:如何管理动态系统——服务发现、自动扩缩、故障自愈
- 代表事件:容器、Kubernetes、Serverless、IaC
- 跨代留下的东西:声明式思维、不可变基础设施、可观测性的核心思想(几十年级别)
阶段七:从代码到智能(2020s 至今)
- 范式转换:从"人写代码"到"人设计系统、AI 写代码、人验证”。从"确定性程序"到"包含概率性组件的系统”
- 复杂性主战场:如何把概率性 AI 集成进确定性系统——验证、约束、对齐
- 代表事件:LLM、Claude Code、AI Agent、AI 原生应用
- 跨代留下的东西(预判):在不可逆放大下保持工程纪律、在产出超过审核带宽时保证质量、人与概率性 agent 协作的方法论。这部分一旦沉淀,会是几十年到几百年级别
三、每一代真正在解决的"永恒问题”
关键发现:每一代的复杂性主战场,本质上都是某个几千年级别的问题在新载体上的新形态。
| 阶段 | 表面问题 | 底层永恒问题 |
|---|---|---|
| 一二 | 让硬件做事 | 如何把人类意图翻译成可执行的精确指令 |
| 三 | 组织大型代码库 | 在大团队里如何协调认知(《人月神话》的核心) |
| 四五 | 处理网络/分布式不确定性 | 在不确定中如何做工程决策(认识论) |
| 六 | 管理动态系统 | 如何让复杂系统具备自我维持能力(控制论) |
| 七 | 集成 AI 的概率性 | 在产出超过审核带宽时如何保证质量(组织协作) |
关键观察:每一代的"硬骨头”,往下挖一层都是几千年级别的问题。技术变了,载体变了,问题没变。
graph LR
subgraph "表面(载体)"
A1[硬件] --> A2[代码组织]
A2 --> A3[网络/分布式]
A3 --> A4[云/动态系统]
A4 --> A5[AI 协作]
end
subgraph "底层(永恒问题)"
B1[精确表达意图]
B2[协调认知]
B3[在不确定中决策]
B4[复杂系统自维持]
B5[超带宽下保质量]
end
A1 -.投影.-> B1
A2 -.投影.-> B2
A3 -.投影.-> B3
A4 -.投影.-> B4
A5 -.投影.-> B5
style B1 fill:#ffd
style B2 fill:#ffd
style B3 fill:#ffd
style B4 fill:#ffd
style B5 fill:#ffd
从七代到两个维度:一次彻底的收敛
第二、三节已经把七代往本质方向压了一次。这一节把压缩做到底——七代演化,最终可以收敛成两个维度,每个维度内部只是换了一次载体。
七代收敛成四组
七个阶段留下的"跨代内核”,去掉重复,其实只有四组:
| 分组 | 对应阶段 | 内容 |
|---|---|---|
| 1. 计算机基础 | 阶段一、二 | 算法、操作系统、编译器——大学基础课 |
| 2. 软件工程 | 阶段二、三 | 模块化、协作、项目进度——《人月神话》那一类 |
| 3. 分布式系统处理 | 阶段四、五、六 | 网络、一致性、共识、云原生 |
| 4. 人与 AI 协作 | 阶段七 | 边界、约束、质量把控、漂移检测 |
这四组今天全都没过时:1、2 一直是地基,3 一直在用,4 正在成为新地基。
四组收敛成两个维度
但这四组不是并列的。其中两组,是另两组"同一内核换了载体”。
- 第 1 组和第 3 组,是同一个东西:都是"计算的数学与物理性质”。区别只在载体——第 1 组是单机下的计算机基础,第 3 组是分布式下的计算机基础。
- 第 2 组和第 4 组,是同一个东西:都是"协作的认知与组织规律”。区别只在协作对象——第 2 组是人与人协作的软件工程,第 4 组是人与 AI 协作的软件工程。
于是四组坍缩成两个维度:
| 维度 | 内核 | 旧载体 | 新载体 |
|---|---|---|---|
| 一、计算机基础 | 计算的数学/物理性质 | 单机 | 分布式 |
| 二、软件工程 | 协作的认知/组织规律 | 人与人 | 人与 AI |
软件工程七十年,真正的长寿内核就这两个。 后面四代(网络、分布式、云、AI)增加的,不是全新的内核,而是这两个内核在新载体上的重新表达。
两次载体演化,是同一种质变
这是最深的一层。两个维度从旧载体到新载体的跨越,不是平滑延伸,而是同一种性质的质变——某个一直被默认、以至于隐形的前提,突然失效了。
维度一的质变:确定性消失
单机计算的世界里,有一个隐含的奢侈品——确定性。函数要么返回要么不返回、变量有确定的值、时间是单向且全局一致的。单机计算基础全部建立在这个确定性地基上。
分布式把这个地基抽走了。它的核心难题——CAP、共识、最终一致性、拜占庭问题——全部来自"确定性消失"这一件事:没有全局时钟、消息会丢会重复会乱序、节点会在任意时刻死掉、永远无法区分"对方没回应"和"对方死了”。
所以分布式不是"单机基础 + 网络”,而是当确定性这个前提被拿掉之后,计算变成了什么样。
维度二的质变:协作对象不再是人
人与人协作的世界里,也有一个隐含的奢侈品——对方是另一个"人”。对方有常识、会真的反对你、会说"这个需求不合理”、错误模式可预测、对你的话有真正的理解。《人月神话》《人件》全部建立在"协作对象是人"这个地基上。
人与 AI 协作把这个地基也抽走了。AI 不会真的反对你(它顺着你的框架走)、它的错误不是人类错误模式(它在你毫无防备的地方流畅地犯错)、它没有"这个需求不合理"的常识反弹、它的"理解"是另一种东西。
所以人机协作不是"人际协作 + 一个新工具”,而是当"对方是人"这个前提被拿掉之后,协作变成了什么样。
两次质变,结构完全相同:
| 维度 | 被抽走的隐含前提 | 抽走之后的新世界 |
|---|---|---|
| 一、计算机基础 | 确定性 | 分布式系统 |
| 二、软件工程 | 协作对象是人 | 人机协作 |
这就是为什么分布式难、为什么人机协作难——不是因为新东西复杂,是因为旧世界有个奢侈品你享受了太久、习以为常,直到它消失,你才发现自己所有的直觉都建立在它之上。
把这个框架推广到任何领域
软件工程的"两个维度 + 同构质变"不是软件独有的,它是任何成熟人类知识领域的通用结构。这一节把框架抽出来,变成可以用在任何领域的诊断工具。
通用结构:科学的一半 + 工程的一半
任何成熟领域,最终都是两件事的合体:
- “科学"的一半:理解世界本身的客观约束——物理规律、数学结构、生物极限、化学反应。这些是"不以人的意志为转移"的硬约束。
- “工程/协作"的一半:在客观约束下,让一群人协调地做出有用的东西。这一半的核心约束是"人的认知和协作有上限”。
软件世界里:
- 科学一半 = 计算的物理/数学性质(图灵机、香农极限、CAP)
- 工程一半 = 在认知和协作约束下交付软件(《人月神话》那一类)
这两半的约束来源完全不同,所以它们的演化逻辑、半衰期、应对方法也完全不同:
| 科学的一半 | 工程/协作的一半 | |
|---|---|---|
| 约束来源 | 宇宙 | 人 |
| 是否可变 | 不可变(除非物理学被颠覆) | 略可变(人会进化,但极慢) |
| 半衰期 | 几百年到永久 | 几千年(人变得慢) |
| 突破方式 | 找到新数学/新物理 | 找到新组织/新工具放大人 |
| 范式转换的本质 | 一个物理/数学前提失效 | 一个协作前提失效 |
两半的范式转换是结构同构的——都是"某个赖以建立直觉的隐形地基被抽走”。 这就是为什么这套思维能跨学科。
识别任何领域的四个诊断问题
进入一个新领域时,先问这四个问题,几小时到几天内就能建立一张宏观地图:
- 这个领域的客观约束是什么?(物理/生物/数学/化学的硬限制在哪?)
- 这个领域的协作约束是什么?(人是怎么组织起来做这件事的?最常见的协作难题是什么?)
- 两半之间的张力在哪?(科学说"应该这样"但工程做不到的地方是什么?)
- 历史上经历过哪几次范式转换?每次失效的隐形前提是什么?
回答完这四个问题,你拥有的就不是一堆零散名词,而是这个领域的脊椎。
迁移到其他领域
建筑
- 科学一半:结构力学、材料力学、热力学、声学、流体力学。一栋楼能不能立、抗不抗震、保不保温——被物理学硬约束。
- 工程一半:协调建筑师、结构工程师、施工方、监理、业主、政府审批——和软件项目惊人地像。
- 关键范式转换:
- 科学侧:钢筋混凝土的发明(19 世纪末)。在那之前,建筑高度被砖石材料的强度死死压制——“建筑高度有上限"这个隐形前提被材料科学抽走了,直接催生了摩天楼。
- 工程侧:现代项目管理、BIM、装配式建筑。“协作必须面对面在工地"这个前提被信息化抽走。
- 同构观察:建筑师讲"形式追随功能"和软件工程师讲"先看清需求再设计”,底下是同一回事——两边都是人在协作着造复杂的东西。
医学
- 科学一半:解剖学、生理学、药理学、病理学。人体怎么运作、疾病怎么发生——生物学硬约束。
- 工程一半:医院怎么组织、医生护士药剂师怎么协作、医患怎么沟通、医疗系统怎么运转。
- 关键范式转换:
- 科学侧:细菌理论(19 世纪中)。“疾病是瘴气/体液失衡引起"这个前提被抽走,整个医学被重构。后续抗生素、分子生物学、基因组学也是同一类质变。
- 工程侧:循证医学、临床路径、电子病历、远程医疗。“医生靠个人经验决策"这个前提被数据和流程取代了一部分。
- 同构观察:医学里有句老话——“治病的是医生,救人的是医院”。一个医生再厉害,没有系统的协作和流程也救不了大批人。翻译到软件就是"写代码的是工程师,但交付系统的是组织”。
金融
- 科学一半:概率论、统计学、博弈论、信息论、宏观经济学。市场有数学规律——风险/收益比、套利不可能、信息不对称的后果。
- 工程一半:金融机构怎么运转、监管怎么设计、市场参与者怎么协调、信任怎么建立。
- 关键范式转换:
- 科学侧:现代投资组合理论(1952)、Black-Scholes 期权定价(1973)、行为金融学(1970s 起)。“市场参与者完全理性"这个前提被行为金融学抽走。
- 工程侧:从场内交易到电子交易、从国家货币到加密货币、从中心化清算到 DeFi。“金融必须有中心化中介"这个前提正在被技术抽走。
- 同构观察:2008 年金融危机的本质——是数学算错了(科学侧),还是协作机制失灵了(工程侧)?答案是两半同时失灵且互相放大。这呼应软件——大事故几乎都不是单一原因,是科学约束被忽视 + 协作机制崩溃同时发生。
法律
- 科学一半(较弱):法律没有强物理/数学约束,但有"人性约束”——人怎么作恶、怎么钻空子、怎么在压力下变形。这一半某种意义上是社会科学的。
- 工程一半(占比特别重):法律体系怎么运作、律师法官怎么协作、立法和司法怎么衔接。
- 关键范式转换:
- “人性约束"侧:从人治到法治、从神判到证据、从个人复仇到现代刑法。
- 工程侧:成文法 vs 判例法、专业律师阶层的出现、电子取证、AI 法律助手。
- 反过来看为什么 AI 时代法律变化深:法律里"工程那一半"占比特别大——而它本质是高度形式化的协作机制,正是 AI 最擅长的东西。法律可能是 AI 时代变化最深的领域之一。
教育
- 科学一半:认知科学、神经科学、发展心理学。人怎么学习——遗忘曲线、间隔重复、心流、最近发展区。
- 工程一半:学校怎么组织、教师学生家长怎么协作、教育系统怎么运转。
- 关键范式转换:
- 科学侧:从行为主义到认知主义到建构主义。
- 工程侧:从私塾到学校、从纸笔到屏幕、从老师讲学生听到翻转课堂、AI 辅导。
- 特别有意思的观察:教育领域里科学侧多年前就告诉我们正确方法(间隔重复比集中学习好、主动回忆比被动阅读好),但工程侧——真实的学校体系——一直在做相反的事。这种"科学知道但工程做不到"的张力,是任何成熟领域都会出现的常态。
其他
往下还可以继续——农业(生物学 + 农场组织)、能源(物理学 + 电网协作)、生物制药(分子生物学 + 临床试验)、航空(空气动力学 + 飞行调度系统)——没有一个例外。
任何成熟到能称为"专业"的领域,都同时有这两半。没有任何重要领域只有科学一半或只有工程一半。
四、什么在变、什么不变
在变(短半衰期)
- 具体技术栈:每 5-10 年大洗牌一次
- 工具和工具链:每 2-3 年迭代一波
- 行业最佳实践:每代范式转换都要重写
- 工程师的具体技能组合:每次代际都需要重学
- 复杂性的载体:从硬件 → 代码 → 网络 → 分布式 → 云 → AI
不变(长半衰期)
- 复杂性本身:会以不同形态持续存在,永远不会消失(Brooks 的本质复杂性)
- 协作的根本难题:人多了如何不变成乱麻——团队、组织、跨部门
- 认知的根本限制:人脑能容纳的复杂度有限,必须靠抽象、分层、模块化
- 判断力的稀缺性:在不完整信息下做长期判断,每代都缺这种人
- 不可逆操作的危险:从 rm -rf 到 force push 到 AI 自动 merge,本质相同
- “看似简单实际复杂"的陷阱:每代都有人在没看清复杂性时拍板
- 人作为生物的需求结构:用户要的永远是被尊重、被看见、感到掌控、避免风险
在变中变出来的东西
- 可逆性敏感、边界敏感、隐性依赖敏感、可观测性、为未来读者考虑——这些工程思维在每代都有效,但每代的具体表现不同
- 可扩展性、安全性、稳定性——这三个系统层属性在每代都重要,但威胁模型在变
- 跨领域协作——产品/工程/运维/商业的边界一直在重划,但需要协作这件事不变
五、跨越代际的工程师有三种
graph TD
Start[工程师面对代际转换] --> Choice{投入方向选择}
Choice -->|加深当前技术熟练度| T1[知识型老人]
Choice -->|反思本质规律| T2[判断力型老人]
Choice -->|主动经历多次范式转换| T3[跨范式适应力型老人]
T1 --> R1[每次代际转换被淘汰<br/>典型命运:加速贬值]
T2 --> R2[失去技术熟练度<br/>但积累本质理解<br/>典型命运:每代都被需要]
T3 --> R3[既有判断力<br/>又能看到代际连接<br/>典型命运:不可替代]
style T1 fill:#fcc
style T2 fill:#cfc
style T3 fill:#9cf
style R1 fill:#fdd
style R2 fill:#dfd
style R3 fill:#ddf
知识型老人(最危险)
- 把精力投入到加深当前技术的熟练度
- 每次代际转换都打他们一耳光
- 在新代际里被新人快速超过
- 典型命运:被加速贬值
判断力型老人(有巨大优势)
- 在每代都额外投入精力反思"这代教会了我什么本质规律”
- 失去一些技术熟练度,但积累对软件本质的更深理解
- 学新范式比新人慢,但学会后判断深度高一个数量级
- 典型命运:在每代里都被需要
跨范式适应力型老人(最稀有)
- 主动经历多次范式转换,每次从零学新范式
- 保留对旧范式的尊重和理解
- 能看到代际之间的连接——为什么新范式出现、解决了什么、又会带来什么
- 典型命运:每代都有不可替代的位置
关键判断:这三种老人的差异,不是天赋,是工作方式选择的累积。判断力可以被刻意培养,但要从早做。
六、AI 时代的特殊挑战
第七代和前六代有一个根本不同——它把"代码产出"这件事的速度提升了 10 倍以上,但人类审核能力没变。
独有现象
- 正向放大:有工程思维的人产出 10 倍,质量保持
- 反向放大:没工程思维的人产出 10 倍,但质量崩塌——而且 AI 写的代码隐患更难发现,因为表面更整洁
- 隐性技术债加速积累:未来 3-5 年会有一波 AI 时代特有的大型故障显现
- 角色被动跃迁:独立工程师被推到等效 10 人团队 Tech Lead 的位置,没有传统的爬坡缓冲
- 判断力溢价:能在第三层(系统层)和第四层(演进层)做事的工程师价值飙升
AI 写代码的隐藏风险
- 表面整洁掩盖深层问题:命名规范、风格一致、有注释——但可能藏着竞态条件、隐性依赖
- 缺少"作者直觉"信号:没有 TODO、没有"这里我不太确定”——所有代码看起来都是成品
- 跨文件心智模型不一致:每段代码自己看是对的,整体看有矛盾
- bug 出现在非常规边界:常见 null 检查 AI 都做了,但领域特定的边界 AI 不知道
工程纪律的四层
graph TB
L1[第一层:代码层<br/>可读、可测试、命名规范]
L2[第二层:运行层<br/>可逆性、边界、隐性依赖、可观测性]
L3[第三层:系统层<br/>可扩展性、安全性、稳定性]
L4[第四层:演进层<br/>可维护性、技术债管理、向后兼容]
L1 -->|AI 默认做得不错| AI1[AI 主导]
L2 -->|AI 做一半,人补| AI2[AI + 人协作]
L3 -->|AI 默认不考虑,人主导| AI3[人主导]
L4 -->|AI 完全不考虑,人前置设计| AI4[人独立完成]
style L1 fill:#cfc
style L2 fill:#ffc
style L3 fill:#fc9
style L4 fill:#fcc
层级越往下,AI 越弱,人的工程思维越关键。
七、对个人的实操判断
注意力分配
- 工具层投入要快、要敏锐——必须做但要意识到半衰期短
- 范式层投入要稳——理解每代的本质转换
- 协作和认知层投入要慢、要深——这是最长寿的资产
工作方式
- 把每一个具体问题当作钻头,往本质方向钻
- 每次具体讨论都在两个层面有收获:当下问题被解决 + 更深规律被识别
- 警惕"领先感"和"智识满足代替实际产出”
- 建立外部纠错机制,因为内省不可靠
工程实践
- 先建测试网(Pitest、ArchUnit、契约测试),再让 AI 大规模写
- 核心模块自己写,外围交给 AI——保持代码肌肉,降低系统风险
- 关键 bug 亲自调,不让 AI 代劳——debug 是能力训练的最佳场景
- 定期"AI 下线日体检”:如果明天 AI 全部下线,我能做什么?
CLAUDE.md 工程化
- 主文件保持精炼,长内容拆到
.claude/rules/按需加载 - 区分硬规则(违反即错)和软指引(默认这样,有理由可例外)
- 规则要带"为什么”——便于未来判断是否过期
- 建立维护节奏:每周轻量更新、每月结构 review、每季度大检查
- 让 AI 帮你审计 CLAUDE.md(扫描差异 + 生成报告),但判断和决策必须人做
长期身份
- 不要把身份认同绑在"我会某个技术"上
- 要绑在"我能在变化中持续做出好判断"上
- 这是软件工程师能选择的最值得的长期道路
八、最深的一层
软件工程这门手艺的真正样子是:
它表面上是技术不断更替的领域——七代范式,每代都重构了"工程师该怎么思考”。
但底下,它一直是同一组永恒问题在不同载体上的反复出现——人如何在复杂性面前保持理性、在不确定中做出判断、在协作中保证质量、在变化中维持长期价值。
掌握表面的人,每代都要重学一次,每次都可能掉队。
掌握底层的人,每次新范式出现都更游刃有余——因为他认出了"这又是那个老问题,只是穿了新衣服”。
软件工程的真正主线不是技术演化,是同一组永恒问题在不同时代的新表达。能识别这条主线的人,才真正跨越代际。
这份地图的对象——人、协作、复杂性、变化——半衰期都是几千年级别。所以这份地图本身,也不会很快过期。