Posts for: #技术涌现

思维软实力。从系统论、复杂科学的角度探讨技术团队管理、架构师成长路径与行业趋势前瞻。

架构师的系统论:用复杂性科学重构团队认知

做了五年架构师之后,我逐渐意识到一个事实:技术上的挑战往往不是最难的部分。真正困难的是如何让一个团队对「什么是好的架构」达成共识。这篇文章尝试从系统论和复杂性科学的角度,重新审视架构师的工作方式。

架构师不是高级程序员

很多公司在晋升到「架构师」这个职级时,默认的评判标准还是技术深度:你对某个领域的源码理解有多深?你能不能设计出高并发的系统?你熟不熟悉各种中间件?

这些能力当然重要,但它们描述的是「高级工程师」,不是「架构师」。

一个高级工程师解决的问题是:怎么把这个功能做好?

一个架构师解决的问题是:这个系统应该长什么样?为什么?

两者的区别在于:工程师在约束内寻找最优解,架构师定义约束本身。

工程师思维:
  "我们需要一个消息队列来解耦。Kafka 和 RocketMQ 哪个更好?"
  → 在已知选项中选择最优解

架构师思维:
  "我们真的需要消息队列吗?如果用事件溯源,是否可以从根本上消除对 MQ 的依赖?"
  → 重新定义问题和约束

系统是一个复杂自适应系统(CAS)

复杂自适应系统(Complex Adaptive System, CAS)是圣塔菲研究所的核心研究对象。一个软件系统——包括它的代码、基础设施、开发团队、用户——本质上就是一个 CAS。

CAS 的四个核心特征:

1. 由大量自主主体组成
   主体:微服务、开发者、团队、用户
   每个主体有自己的目标和行为规则

2. 主体之间相互作用
   服务之间的 API 调用
   团队之间的沟通协调
   用户与系统的交互

3. 涌现(Emergence)
   宏观行为无法从微观行为简单推导
   例:每个服务都是高可用的,但整个系统却可能因为级联故障而宕机

4. 自适应(Adaptation)
   系统会根据环境变化调整自身行为
   例:自动扩缩容、熔断降级、团队根据事故复盘调整流程

理解了 CAS 的特性,就会明白为什么架构设计不能是「自上而下的完全规划」:

  • 涌现不可预测:你无法预知所有微服务组合在一起后会产生什么样的宏观行为。这就是为什么混沌工程(Chaos Engineering)如此重要——你需要在生产环境中主动注入故障,观察系统的涌现行为。

  • 过度控制会扼杀适应性:如果你把每一个服务的实现细节都规定死了,团队就失去了根据实际情况做调整的能力。好的架构应该定义边界和接口,而不是规定实现。

康威定律的工程解读

康威定律:
"设计系统的组织,其产生的设计等同于组织之内、组织之间的沟通结构。"

—— Melvin Conway, 1967

这不是一句口号,而是一个被反复验证的工程事实。

反例 1:单体团队做微服务

组织架构:一个 50 人的大团队,所有人向同一个 leader 汇报
技术架构:虽然拆分了 20 个微服务,但因为沟通无障碍,服务之间的耦合越来越多
结果:分布式单体(Distributed Monolith)——有微服务的所有缺点,没有微服务的任何优点

反例 2:跨团队共享数据库

组织架构:三个独立的业务团队
技术架构:三个团队共用同一个数据库
结果:任何一个团队的 Schema 变更都会影响其他团队,沟通成本随团队数量指数增长

正确的做法是让组织架构和技术架构对齐:

[阅读全文]

技术债务的拓扑学:如何量化和治理系统熵增

Ward Cunningham 在 1992 年提出「技术债务」这个概念时,他可能没想到三十年后这个词会成为每一个技术团队的噩梦。技术债务不像金融债务那样可以精确计算,它更像是一种熵——在看不见的地方悄悄增长,直到系统变得不可维护。

技术债务不是一种债

很多人把技术债务理解为「欠下的代码质量」,觉得只要花时间重构就能还清。这个理解有一个根本性的错误:技术债务不是贷款,而是复利。

金融债务:
  借 100 万,年利率 5%,每年还 5 万利息
  债务总额是确定的,还款计划是可预测的

技术债务:
  写了一段快速但丑陋的代码来赶 deadline
  第一个月:需要在这段代码旁边加个功能 → 多花了 2 小时
  第三个月:新人入职看不懂这段代码 → 多花了 2 天
  第六个月:这段代码的 Bug 引发了线上事故 → 多花了 1 周
  第十二个月:这段代码和其他模块的耦合太深,无法重构 → 被迫放弃

技术债务的利息不是线性的,而是指数增长的

这就是为什么技术债务不能「等有空了再还」——因为等你有空的时候,利息可能已经超过了本金。

技术债务的四种类型

Martin Fowler 在《Refactoring》中把技术债务分为四个象限:

                    鲁莽的                审慎的
              ┌──────────────────┬──────────────────┐
    故意的     │ "我们不需要测试"  │ "我们知道这里耦合   │
              │ "先 copy paste  │  太紧,但现在重构   │
              │  以后再重构"     │  会延误发布,下个月  │
              │                 │  专门处理"         │
              ├──────────────────┼──────────────────┤
    无意的     │ "什么是分层?"    │ "我们现在才理解    │
              │ "把 SQL 写在     │  应该怎么做"       │
              │  Controller 里"  │(随着认知深入发现   │
              │                 │  之前的设计有问题)  │
              └──────────────────┴──────────────────┘

鲁莽且故意的债务最危险——团队明知故犯,而且不考虑后果。

[阅读全文]