乐于分享
好东西不私藏

当你把软件切开,里面还是软件——从一场群聊说起的"分形困境"

当你把软件切开,里面还是软件——从一场群聊说起的"分形困境"

前两天在"构建之法"群里,邹欣老师抛了一个问题。

大意是说,建筑上可以用预制件来大大简化流程——预制墙板、预制房间,甚至整个模块直接吊装到位,现场拼起来就行。软件世界也有"预制件"啊,各种开源库、第三方模块、npm 包,调用一个函数就搞定了,看起来没啥区别。

但邹老师话锋一转——CPU 仍然要执行每一个外部模块的每一条具体指令。

群里安静了一小会儿。

这句话乍一看像是一句技术陈述,但你仔细咂摸,会发现它里面藏着一个挺让人不舒服的事实。

我顺着这个思路往下想了很久,越想越觉得不对劲。今天把这段思考过程分享出来,顺便聊聊邹老师那篇让我反复读了三遍的文章——软件的分形维度

一、你以为你在"拆蛋糕",其实你在"测海岸线"

邹老师文章的核心概念,借的是曼德勃罗那个著名的比喻——海岸线分形

什么意思呢?你拿一把大尺子去量英国海岸线,量出来是某个数字。你换一把更小的尺子再量,海岸线的细节更多了,数字变大了。尺子越小,细节越多,数字越大——永远收敛不了

软件工程跟这个玩意儿简直一模一样。

你接手一个大项目,第一步当然是"拆"。WBS——工作分解结构,把大需求拆成模块,模块拆成子模块,子模块拆成具体任务。拆完一看,嗯,清晰了,可以干活了。

然后你开始做。做了三天发现,这个"小模块"里面照样有需求扯皮。扯完扯皮发现,还有脏数据要清洗。清洗完数据发现,测试环境又崩了。

你以为你切开了一块蛋糕,其实你切开了一段海岸线。

邹老师在文章里写了一句特别到位的话——"WBS 切开的不是蛋糕,是海岸线。"

这个比喻精准到什么程度?你去问问任何一个做过软件项目的人,哪个不是拆完之后发现工作量比预估的多了一倍?拆完再拆,拆完再拆,永远有"再往下挖一层"的必要性。这不是管理问题,不是经验不足,这是软件本身的属性。

邹老师管这个叫**"尺度的分形"**。细节之下,永远有细节。

但分形不只这一层。

二、11 行代码干翻全球

2016 年,npm 上有一个叫 left-pad 的包。

这个名字听起来就是那种谁都能写的东西——一个把字符串往左填充的函数,总共 11 行代码

然后这个包的作者跟 npm 官方闹翻了,一怒之下把自己的包全删了。

结果呢?全球几万个前端项目,构建全部失败。

你没看错。几万个项目依赖一个 11 行代码的包,包没了,全瘫了。

很多人听到这个故事第一反应是"这也太脆弱了吧",然后骂两句 npm 生态就过去了。但邹老师在文章里把这个现象放到了"分形"的框架下,问题一下子变得不一样了——

他管这个叫**"依赖的分形"**。

在物理世界里,一个零件坏了,坏的就是那个零件。你跑步机上少跑 11 步,后面的人补上 11 步就完了。影响是局部的,隔离的。

但软件世界不一样。软件的依赖是一棵树,一棵巨大的、层层嵌套的树。left-pad 看起来在树的最底层,但它长在所有人的心脏里。一个微小的局部故障,沿着依赖树一路传导,引发全局雪崩。

在跑步机上,少跑 11 步,后面的人补上就完了。在软件依赖网络里,这 11 行代码缺在所有人的心脏里。

三、CPU 根本不认你的"抽象"

第三层分形,是让我觉得最扎心的一层。

执行的分形。

你写代码的时候,调一个 saveToDB(),觉得这是一行代码,一个简单的操作。封装好的,开箱即用。

但邹老师说得明白——抽象只压缩了人脑的认知,从未压缩过机器的计算。

你在代码里写了一行 saveToDB(),以为是一步到位。但 CPU 会把这个"一步"展开成底层驱动中几万条机器指令——内存分配、字节对齐、内核态切换、磁盘 I/O 调度……一步变成了几万步。

邹老师文章里有一组对比让我印象深刻:

"人脑是越野车,CPU 是赤脚走过每一个水坑。"

你以为越野车蹚过去了,CPU 说:不好意思,水坑里的每一滴水,我都要踩一遍。

这就是"执行的分形"——你调的每一层抽象,在机器层面都会被展开、铺平、逐条执行。你省的是脑子里的带宽,机器一点也不省。

四、回到群里那个问题:预制件为什么不一样?

看到这里,你可能觉得这三层分形已经很全了。尺度、依赖、执行,该说都说清楚了。

但群聊里那段讨论让我想到了一个更底层的问题——为什么建筑的预制件是真的"简化"了,而软件的"预制件"只是在视觉上简化了?

邹老师在讨论里给了一个极其精准的回答。

建筑预制件遵循的是连续介质力学。一块混凝土墙板,内部纵有无数微观缺陷——气泡、裂纹、密度不均匀——但物理定律会自动通过应力分担把这些风险"平均化"并抵消掉。你不需要知道每一颗沙粒的精确位置,墙板照样立得住。

物理世界会帮你"抹平"微观的复杂性。

但软件运行在离散状态机上。CPU 是比特级执行器,一个 0 和 1 的偏差,一个 > 和 >= 的区别,会百分百、无损耗地传导到宏观结果。

没有"应力分担"。没有"平均化"。每一个微观差异,都是一发精确制导的子弹,直打你的结果。

邹老师原话说得更好——"软件的抽象化封装,只是用黑布遮住了微观悬崖,底层的离散分形依然在黑布下疯狂发散。"

五、一个困扰我很久的问题

读到这里的时候,我突然想到了一个困扰了自己很久的问题。

人类造的计算机,到底能不能无限模拟真实世界?

你可能觉得这是一个科幻问题。但我认真想过,答案其实挺明确的——肯定不能。

原因说出来你可能觉得"废话",但这个"废话"背后藏着一个很有意思的逻辑:

宇宙中每一个原子,都是一个计算单元。

物理规律就是算法,原子就是运算器。万有引力、电磁力、强核力、弱核力——这些不是"背景规则",它们就是每一颗原子正在执行的计算。宇宙有 10 的 80 次方个原子,每一个都在同时运行,每一个都是一个独立的运算单元。

你拿什么去模拟?

就算你造出一台跟宇宙一样大的计算机——那台计算机本身也是宇宙的一部分,它的原子也在跑物理算法。你用宇宙的一部分去模拟整个宇宙?这逻辑本身就打不圆。

所以真实世界是"分布式计算"的极端版本——每个原子就是一台计算机,自带物理规律这个操作系统,永不停机,永不崩溃。

每一个原子就是一个符合物理规律的运算单元。

回到预制件的问题——为什么建筑预制件换个环境也能跑通?因为构成预制件的每一颗原子,它自己就是一台"电脑",自带物理规律这个操作系统。你把一块预制墙板从工厂搬到工地,每一颗原子到了新环境,照样按物理规律运行,照样受力、照样分担应力、照样保持稳定。

它不需要一个"中心处理器"来告诉它该怎么工作。

但软件不一样。

软件的运算单元永远会落回 CPU。

不管你封装了多少层抽象,不管你调用了多少第三方模块,不管你用了多么优雅的设计模式——最终,每一条指令、每一个比特、每一个状态转换,都要由 CPU 来执行。

CPU 是你的"上帝"。所有的运算最终都收敛到这一个点。

这不是架构问题。这是物理底层的差异——连续的分布式计算(原子)vs 离散的集中计算(CPU)。

这也是为什么软件的分形困境几乎不可能被真正解决。因为它的根源不在工程方法上,在计算模型的本质差异上。

六、那我们该怎么办?

写到这你可能会说,说了这么多,结论就是"没救了"?

也不是。

认识到问题的本质,本身就是一种解法。

做软件之前就接受这个事实——你不可能通过"拆"来消灭复杂性,你只能通过"拆"来管理复杂性。WBS 不是帮你消灭海岸线的,是帮你认清海岸线的。

用第三方库的时候也清醒一点——它帮你省的是"写代码的时间",不是"执行的成本"。CPU 不会因为你用的是 React 就少执行几百万条指令。

抽象是一块遮羞布,不是一剂解药。

它能帮你把复杂的东西藏起来,让你暂时不用面对。但它不会让复杂消失。复杂还在那里,在黑布下面疯狂发散,只是你看不见了。

看见了,至少不会踩空。

邹老师文章的结尾有一句话,我读完之后沉默了好一会儿:

"分形不是故障,是特征。"

软件的分形困境不是一个 bug,不是某个人、某个团队的失误。它是软件这种计算形态与生俱来的属性。

就像海岸线不是大自然画歪了,它本来就没有直的。

你接受它,才能跟它共处。

你跟它较劲,它就用复杂度教做人。

这就是我读完邹老师文章、又在群里跟老师讨论之后的一些想法。说实话,很多地方我也没完全想通,尤其是"原子即运算单元"这个类比到底能推多远,我自己也在琢磨。

但有一件事是确定的——当你下次拆需求的时候,记得你不是在切蛋糕,你是在量海岸线。

尺子越小,岸线越长,永远如此。

欢迎在评论区聊聊:你有没有经历过"拆完发现更大一个坑"的时刻?

本文灵感来源:邹欣老师《软件的分形维度》,推荐原文。

往期精彩内容:

你的 DAU 只看到半个团队

给AI设计体验:一个你还没听说过的学科

AI同事已经上班了,你还在跟它聊天吗?

管理一个记性差但干得快的团队,说的就是 AI 编程

Agent特区第27期:一场真实研发团队向 AI Native 转型的完整复盘

Agent特区第26期,一份"失败"的职场复盘,让我想明白了三件事

企业AI转型,正在集体"崩老头"

我参加了一场"不写一行代码"的分享会,发现所有人都在焦虑同一件事

学习AI没有捷径

Harness 工具从夯到拉

一人成军:为什么你的AI编程不能并行开发?

我让 AI 连续写了30个小时的代码,一次都没碰过键盘

一个程序员用AI做投资的2小时:从NPC公司到流动性套利

AI给生鲜店长当助理,一个月成本不到300块,凭什么?

永恒族:被毕业的同事被蒸馏成了token和同事.skill

2023年你会写prompt就很牛,2026年你还在写prompt就完了

OpenClaw 小龙虾实战基础揭秘:一个非程序员的 AI 助手使用心得

我准备做一个"劝退"的openclaw+ai编程社群了

AI编程的原生测试,从来不是TDD
怎么让AI不偷懒:为Codex构建系统性的Wide Research能力
AI也分“动手模型”和“大脑模型”,不知道这些,AI编程多少要走些弯路
担心被AI淘汰?怕是你还不够“抽象”
《夏洛特烦恼》中的大爷,可能是最懂AI的人