软件行业有一个几乎没人公开承认、但人人都在默认执行的共识:
复杂 = 高级,简单 = 初级。
简历上写”主导引入 Kafka + Kubernetes + 微服务架构,支撑日均十亿请求”,看起来很厉害;写”用几个文件和一套 SQL,撑住了千万级请求”,看起来很平庸。评审时说”我引入了一层抽象来解耦这三个模块”,像在做架构;说”我把这三层抽象删了,因为根本不需要”,像在偷懒。晋升答辩里讲”我设计了 X、Y、Z 三个系统”能过,讲”我没让 X、Y、Z 被造出来”几乎一定不过。
这个共识是反的。它把工程能力的价值符号搞反了。
真正难的,从来不是造出复杂系统,那几乎是默认会发生的事。真正难的,是让系统在生长过程中始终保持简单。而简单恰恰被激励机制系统性惩罚。这不是个人品味问题,这是一场结构性的定价错误,而整个行业都在按错误的价签做决策。
一、先校正一个坐标:简单和简陋,是两件完全不同的事
要把这个话题讲透,必须先把一个最常见的混淆从脑子里清掉。否则下面所有的论证都会被一句”你说的简单,不就是写得糙吗”挡回去。
简陋和简单,字面上都带个”简”,但它们是两件方向相反的事。
简陋,是能力不足的结果。 一个人做不到复杂,只能写出粗糙、缺漏、经不起推敲的东西。简陋的天花板很低,不是他不想做复杂,是他做不出来。简陋的本质是”做不出”。
简单,是能力过剩之后克制的结果。 一个人完全有能力做复杂,但他主动选择不做,把复杂度压到解决问题所需的最小值。简单的本质是”选择不做”。它的前提,是先拥有把事情做复杂的能力。
判据很清晰:
简陋是能力的下限,简单是能力的上限。一个是够不到复杂,一个是越过了复杂。
这两件事在外表上可能看起来相似(都”没怎么用东西”),但内核完全相反。简陋背后是空白,简单背后是判断。一个简陋的系统,多加点东西就会变好;一个简单的系统,多加点东西就会变差。因为它已经处在那个”刚好”的临界点上,任何添加都是多余的。
这个区分至关重要。人们口头贬低的,其实是简陋;但激励机制真正惩罚的,却是简单。因为简陋一眼能看出来(粗糙),而简单看不出来(看起来”只是没做什么”)。于是简单被和简陋一起扫进了”不够高级”的筐里,再也没人分辨。
后面的所有论证,都建立在”简单≠简陋”之上。我们讨论的简单,是那种有能力复杂、却选择不复杂的简单。
二、为什么简单比复杂难得多
理清了定义,下一个问题是:凭什么说简单比复杂难?这听起来反直觉,做出东西难道不比不做更难吗?
答案藏在一个基本物理事实里:复杂是熵增,简单是减熵。
复杂是系统不做任何干预就会自然进入的状态。加一个功能,默认就多一份代码;多一个需求,默认就多一个分支;多一个团队,默认就多一个服务。你什么都不做,复杂度就在涨。就像房间不会自己变整洁,系统也不会自己变简单。复杂是默认路径,它不需要努力,只需要”不抵抗”。
简单则相反。它是低熵态,需要持续输入能量——判断、取舍、删减、拒绝,才能维持。你松手一秒,它就开始滑向复杂。维持简单,是一场永不结束的对抗。
把这件事落到工程的具体动作上,反差会更清楚:
- 加一个功能很容易,因为默认答案就是”加”。
- 拒绝一个功能很难,因为拒绝需要你证明”不加也行”,而证明”不加也行”比”加了试试”难得多。
- 加一层抽象很容易,因为看起来每加一层都在”解决问题”。
- 删一层抽象很难,因为你要证明这层是多余的,而证明多余需要理解它的所有调用方。
- 写出能跑的代码容易。
- 把能跑的代码删到最小、仍然能跑,极难,因为删除是减法,减法要求你证明”没有它也行”,而加法只需假设”有了它更好”。
这就是核心不对称:加法靠假设,减法靠证明。 假设永远比证明便宜,于是复杂永远比简单便宜。复杂是廉价的默认,简单是昂贵的克制。
更进一步,简单之所以难,还因为它要求一种复杂所不需要的能力:判断什么本质、什么偶然。复杂的人可以照单全收所有需求和抽象,他不需要分辨;简单的人必须每一项都分辨,这是问题本身的复杂(必须留),还是实现引入的复杂(可以删)?这种分辨需要远超”写出来”的理解深度。一个能把系统写复杂的人,未必能把它写简单;但一个能把系统写简单的人,一定能把它写复杂,他只是选择不。
所以那句老话其实应该反过来说:能做出复杂系统的人很多,能让系统保持简单的人很少。简单是能力的天花板,不是地板。
三、简单为什么被系统性低估:一个定价机制的问题
讲到这里,一个自然的疑问是:既然简单这么难、这么值钱,为什么市场不奖励它?
答案是:不是市场不识货,是简单的定价机制本身是坏的。
简单的最大成就,是”什么都没发生”,没出故障、没踩坑、没返工、没被技术债拖慢。但”什么都没发生”这件事,在任何评价体系里都无法被记功。你没法在晋升答辩里说”因为我选了简单方案,所以这半年没出事”。评委会问,那这半年你到底做了什么?
而复杂的成就,是”解决了大问题”,引入了新架构、处理了高并发、扛住了大流量。这些都能被写成故事、画成架构图、讲成战报。哪怕那个”大问题”本身常常是之前的复杂制造出来的,也没关系,解决自己制造的麻烦,依然算”做出了成绩”。
这就形成了一个残酷的价值悖论:
简单的工作产出是”避免了未来的成本”,而避免的成本是看不见的。
复杂的工作产出是”立刻解决了眼前的问题”,而解决的问题是看得见的。
人类天生高估看得见的收益,低估看不见的避免。这是认知偏差,不是偶然。简单被低估,是这种偏差在工程评价体系里的制度化体现。
具体来说,至少有三处定价失真:
简历失真。 复杂能写进简历:”使用了 Kafka、Redis、K8s、微服务”。简单不能写进简历:”我没有用 Kafka,因为不需要”–这句话不仅不是成就,反而像”没见过世面”。于是简历天然奖励堆砌技术名词,惩罚审慎的克制。
评审失真。 复杂能在评审中被讨论:”我处理了这八种边界情况、引入了重试和熔断”。简单不能被讨论:”我删掉了这八种边界处理,因为它们根本不会发生”,这话听起来像偷懒。于是评审天然奖励加法,惩罚减法。
晋升失真。 晋升需要证明”做出了什么”。简单的工作恰恰是”没做出什么”,没引入那个中间件、没设计那层抽象、没拆那个服务。于是做简单工作的人,在晋升这件事上天然吃亏,而做复杂工作的人天然占便宜。
三处失真叠加,结论很清楚:简单被惩罚不是个人偏见,是结构性激励错配。 在这个定价机制下,理性人都会选择复杂。因为复杂有回报,简单没有。这不是道德问题,是机制问题。
四、最阴险的部分:简单的人,看起来不如复杂的人
定价失真最危险的后果,不是简单不被奖励,而是简单的人被复杂的人系统性挤出。
一个让系统保持简单的工程师,他的产出是”克制”。克制的外在表现是”没做什么”。在一个缺乏深度判断的评价体系里,”没做什么”几乎等同于”不会做什么”。
一个让系统变复杂的工程师,他的产出是”堆叠”。堆叠的外在表现是”做了很多”。”做了很多”在任何浅层评价里都赢。
于是会出现一种几乎必然的逆向淘汰:
- 简单的工程师,因为看起来”没做什么”,被低估、被边缘、被淘汰,或者最终被同化,学会堆叠,因为堆叠有回报。
- 复杂的工程师,因为看起来”做了很多”,被奖励、被提拔、被树立为标杆。
- 团队逐渐被”会堆叠的人”占据。
- 系统越来越复杂,改动越来越慢,债务越来越重。
- 为了应付越来越慢的改动,团队引入更多复杂(新框架、新流程、新抽象)来”提效”。
- 复杂度进一步上升,简单的人更难生存。
这是一个正反馈的下行螺旋。系统越奖励复杂,越赶走简单的人;越赶走简单的人,系统越复杂。而螺旋的起点,只是那个看似无害的共识:”复杂=高级”。
最讽刺的是,当系统复杂到难以为继时,团队会高薪聘请”架构师”来做”重构”。而重构的本质,恰恰是把复杂压回简单。也就是说,行业花大价钱请人做的事,正是它平时不奖励的那种”简单”。它在创造阶段惩罚简单,在拯救阶段高价购买简单。简单的人一直在创造价值,只是价值被推迟到了系统快崩的时候才被定价。而那时,创造简单的人往往早已不在团队里了。
五、简单到底值多少钱:一个被隐藏的账本
要真正理解简单的价值,得换一本账本。当前那本账只记当下,而简单的回报几乎全在长期。
一个简单系统的长期收益:
- 可理解:新人能快速上手,理解成本随团队规模线性而非指数增长。
- 可修改:改一处不引发连锁,迭代速度快。
- 可排查:出问题能定位,故障时间短。
- 可替换:技术债能偿还,不被任何工具绑架。
- 可信任:行为可预测,没有隐藏的副作用。
一个复杂系统的长期成本:
- 不可理解:新人要数月才能动手,理解成本指数膨胀。
- 不可修改:牵一发动全身,每次改动都如履薄冰。
- 不可排查:出问题靠玄学和运气,故障时间长。
- 不可替换:被框架和依赖深度绑架,想换换不动。
- 不可信任:总有没被发现的隐藏行为,随时可能暴雷。
注意这两组清单的对称性:简单的每一项收益,都对应复杂的一项成本。而关键在于时间维度:简单是当下付出克制,未来持续受益;复杂是当下获得速度,未来持续还债。
简单是保险,复杂是欠债。保险的回报在”没出事”里,欠债的账单在”出事时”才寄到。人类天生偏好即时满足、厌恶延迟成本,于是天然偏向复杂。因为复杂的收益是即时的(功能很快上线),代价是延迟的(维护地狱在后面)。简单的代价是即时的(要花更多心力克制),收益是延迟的(系统长期健康)。
这本账之所以被隐藏,是因为当下的账本只看得到前者。一个系统的真正成本,是它全生命周期里所有理解、修改、排查、替换、信任的成本之和。按这个口径,简单几乎总是碾压复杂。但全生命周期的账,几乎没有团队在算,他们算的是”这个季度上线了什么”。
于是简单最大的价值:它避免了多少未来的成本,永远是个看不见的负数。而一个看不见的负数,在任何激励机制里都换不成正回报。这就是简单被低估到根子上的原因:它的价值形态(避免的未来成本)恰好落在评价体系看不见的盲区里。
六、压力测试:这个判断是不是太理想化了
反驳一:有些系统天生就是复杂的,分布式、高并发、实时系统,简单根本不可能。
这个反驳混淆了两种复杂。软件工程里有个经典区分:本质复杂(问题本身难,无法消除)和偶然复杂(实现引入的,可以消除)。
优秀的工程师不追求消除本质复杂,那是不可能的,也是不负责任的。他追求的是把偶然复杂压到零。一个分布式系统,它的本质复杂度(一致性、分区、故障恢复)是问题给的,删不掉;但它的偶然复杂度(多余的抽象层、过度的框架、不必要的中间件、为不存在的需求预留的扩展点)是可以删的。
真正”简单”的分布式系统,不是没有复杂度,是它的复杂度全部是本质的,没有一丝偶然的。这恰恰是最难的境界。所以”有些系统天生复杂”不构成反驳,越是本质复杂的领域,越需要工程师把偶然复杂榨干,否则两种复杂叠加,系统必然失控。
反驳二:K8s、Kafka 这些复杂工具确实解决了真实问题,不能因为”简单好”就否定它们。
当然不能。简单不是”不用工具”,是”用最少的工具解决最多的问题”。
K8s 本身是复杂的,但它让上层应用的部署、扩缩容、故障恢复变简单了。这种复杂是值得的,它把复杂度集中到了一个被广泛理解和维护的地方,换来了上层的大面积简单。净复杂度下降了。
问题在于:很多人引入复杂工具时,并没有换来上层的简单。他们引入 K8s,但应用还是手动部署;引入微服务,但服务间耦合比单体还重;引入消息队列,但所有调用还是同步的。这种情况下,复杂只是从一个地方搬到了另一个地方,还多加了一层要维护的东西。净复杂度上升了。
所以判据不是”用了多少工具”,是”净复杂度降了没有”。简单的标准永远是净复杂度,不是工具数量。把简单理解成”不用工具”,是把这个概念矮化了。
反驳三:业务压力下哪有时间追求简单?站着说话不腰疼。
恰恰相反。没有时间追求简单,是复杂累积的结果,不是原因。
越是不追求简单,系统越复杂;系统越复杂,每次改动越慢;改动越慢,越没有时间;越没有时间,越不追求简单。这是另一个下行螺旋。追求简单不是奢侈品,是逃生通道。越忙、越赶、越没时间的团队,越需要简单,因为只有简单能让”忙”变得可持续。
把”没时间追求简单”当成不做简单的理由,等于把”快没空气了所以不能停下来修氧气机”当成逻辑。短期看是省了时间,长期看是把整个团队推向每次改动都要付出十倍代价的境地。真正站着说话不腰疼的,是那些鼓励”先快后慢”、却从不替后续维护买单的人。
反驳四:简单到极致就是过度简化,会出大问题。
对。这是必须澄清的边界。简单不等于”少到不够”。
简单的判据是”用最少的必要复杂度解决问题”,”必要”二字是关键。删到不够,是简陋,不是简单。真正的简单恰恰需要极其精准地判断”什么是必要的”,这比无脑堆叠难得多,因为堆叠不需要判断,而删减需要对每一项的必要性做出裁决。
一个过度简化的系统,是判断失败的简单(删多了);一个堆叠的系统,是放弃判断的复杂(懒得分辨)。两者都是能力不足的表现。真正的简单,是判断到位的简单,留下的全是必要的,删掉的全是不必要的。这个精度,是工程能力的最高体现。
四个反驳接住之后,立意反而更清晰:简单不是反对复杂工具,不是追求粗糙,不是站着说话不腰疼。它是把偶然复杂榨干、只留本质复杂的能力,而且越忙越需要它。
七、那么怎么办:在一个奖励复杂的世界里,如何守住简单
既然定价机制失真,靠”等别人识货”是等不到的。需要主动策略,把简单的价值从看不见的地方打捞出来。
原则一:把”没做什么”显式记录下来。
简单的工作看不见,那就把它写出来。在 PR 描述、技术方案、季度总结里,主动记录克制决策:我拒绝了引入 X 框架,理由是 Y;我删掉了 Z 中间层,因为它在当前规模下是净负担;我用一个文件替代了三个服务,因为它们的职责本就该在一起。
把克制从”隐形的没做”变成”显式的决策”。没人会替你把这部分价值翻译成成就,得自己翻译。这不是邀功,是纠正定价。你不把简单的价值显式化,它就永远不被计入。
原则二:用长期指标对抗短期叙事。
简单系统的价值在长期可维护性上。要建立能反映这种价值的指标:改动平均耗时、新人独立上手时间、单次故障定位时长、依赖数量趋势、代码删除率。
当晋升答辩还在讲”上线了什么”时,你可以拿出一组长期指标说”过去半年,团队的改动耗时下降了 40%,因为我把系统从 12 个服务合并成了 3 个”。这是简单能被定价的方式。用可度量的长期收益,对抗不可度量的”没做什么”。
原则三:对每一个”加”的冲动,先问”能不能不加”。
默认答案是”加”,这是熵增。把默认翻转成”不加”,需要充分理由才加,而不是需要充分理由才不加。
这一个默认值的翻转,能压住大部分复杂度的增长。绝大多数不必要的复杂,都不是被深思熟虑后加进去的,而是”顺手加一下”、”以防万一”、”以后可能要用”加进去的。把”加”从默认变成例外,这些顺手就被拦下了。
原则四:定期做减法,把删当成正式工程活动。
复杂度会自然增长,必须定期清理。把”删代码””删依赖””删抽象””删不再需要的功能”当成和加功能同等重要的工程活动,排进迭代,给时间,给验收。
大多数团队从不给删减留时间,于是复杂度只增不减。给删减留时间,是承认一个事实:维持简单和制造复杂一样需要工程投入,而且更值得投入。
原则五:在团队里建立”简单”的审美。
评价一个方案时,不只问”能不能解决问题”,还问”能不能用更少的东西解决”。把”用得少”当成一种成就来肯定,而不是当成”不够先进”来怀疑。
这需要带头人以身作则。当一个资深工程师在评审里说”这个方案能跑,但能不能砍掉这两层”,并且真的砍掉了,他就在重新定义团队的评价标准。审美的建立是缓慢的,但一旦建立,就是团队最深的护城河。一个崇尚简单的团队,迭代速度会持续快于一个崇尚复杂的团队,而这个差距会随时间复利放大。
八、结论 :你拒绝了多少,才定义了你是什么水平
软件界有一个未被言说的真相:
最厉害的工程师,做出来的系统往往”看起来没什么”。
因为他们把复杂度都吸收进了自己的判断里,该不该加、该不该删、什么是本质、什么是偶然,留给系统的,只有最干净的实现。系统因此显得平淡、寻常、甚至”简陋”。但那种平淡,是能力溢出之后的留白,不是能力不足留下的空白。
而不够厉害的工程师,把复杂度留在了系统里。于是系统看起来”很厉害”,用了先进的技术、处理了棘手的边界、扛住了复杂的场景。但那个”厉害”,往往是问题没有被真正解决的证据,而不是能力被充分展现的证据。因为真正被解决的问题,是不会在系统里留下复杂痕迹的。
简单是工程能力的天花板,不是地板。能做出复杂系统的人很多,能让系统保持简单的人很少。一个奖励复杂的行业,是在用激励机制把天花板当地板踩。它得到的不会是更强的工程能力,而是更重的系统、更慢的迭代、更深的债务,以及一群越来越不会做减法的工程师。
所以,评价一个工程师真正的水平,不该问”你用了什么技术”。
该问的是:
你拒绝了多少本可以用的技术?
前者的答案,会被简历和评审轻易放大,但它区分不出能力的高下,会用工具的人太多。后者的答案,藏在那些没有被写进简历的克制里,而它才是水平的真正标尺。因为拒绝比堆叠难,证明”不需要”比假设”需要”难,把复杂压回简单比把简单推向复杂难。
简单这件事,难就难在它无法被堆叠出来,只能被判断出来。而判断,是工程能力里最稀缺、也最该被重新定价的那一种。

发表回复