仓库源文

思维上的洞2


听三国的故事,我们看到王允诛董卓后,没有接受李郭张樊 [1]_ 的投诚,引致了后来的 失败。但就算认为这里描述的都是事实,我们也注意到了,李郭张樊本来就是要逃跑的, 说明王允的筹码还是足够的,所以问题其实并不在这里。

.. [1] 李傕,郭汜,张济,樊稠

所以问题在哪里呢?其实我们并不知道,也许是内部军心不稳,也许是说好的支持没有来 ,谁知道呢?这需要细节。

构架设计一样的,我们进行抽象,抽象越高,丢失的信息就越多。所以如果我们丢开细节 谈抽象,得到的判断常常偏离真正的问题。

比如架构上我们可以判断如果做4P2U服务器(对比2P2U)的竞争力更强,但4P2U对板材的 要求会提高,如果你对制造过程不了解,这个只从架构逻辑上判断,你总会认为这是合情 合理的。这是因为你的高层抽象并不能正确地归纳细节的主要特征。

做战略判断,不可能基于细节,但高层抽象,永远不能离开细节。所以,越是懂架构设计 的,越不会轻易下结论,因为他们根本不相信这些抽象出来的信息。以为孔明掌握某本天 书逻辑,所以运筹帷幄,这恰恰是外行的YY。

用代码行来统计代码的规模也是个类似的问题。代码量可以说明它大(恶意生成代码不算 ),但这个方法不能用来做对比,因为代码行的工作量是不同的。

这背后的原因在于,对比人脑的理解,代码包含的信息超过字面上的行。

怎么说呢?以前我举过机器学习的例子(todo: ref)。给你一张全班考试成绩单,你拿不 到任何信息,你的脑子需要变成:这个班有多少人,平均分是总分的百分几,你家孩子在 班里排第几这种信息,你才能“认知”这个信息,所以,数据量只要大到一定的程度,你的 脑子只有抽象了才能接受它,否则它就是废信息(这就是《道德经》中的恍惚的概念:视 而不见听而不闻)。

代码也是一样,一个顺序的代码流,你要不看到一个抽象的模块间调用,要不模糊化前后 流程,看到中间一段的执行,要不看到状态机,要不看到接口上的破绽,你是“看不到”整 个代码的。

所以代码形成后,反而它原来的逻辑信息就丢失了。我们要重新理解它,修改它,我们需 要还原这些信息。这些信息的数量,才决定了代码的工作量,代码行不能代表这个工作量 。

比如我们先写一组代码,实现一个通讯会话的建立,我们写出了第一个逻辑A,包含100行 代码,这100行代码反映在我们的脑子里,只代表了“建立通讯会话”这个逻辑(假定这个逻 辑包含100行的逻辑描述吧),我们脑子其实不能确认这个建立过程,是否会产生安全漏洞 。

为了保证没有安全问题,我们需要建立另一个逻辑B,假设也产生100行的代码描述,但这 个逻辑补充到最终的代码中,可能只是增加10行代码。

然后,我们为了运行在某种芯片体系结构上,我们需要让所有的数据结构都对某种 Cacheline长度对齐,同时所有核间通讯,要兼顾弱顺序内存模型,这个逻辑C,假设也是 100行逻辑,但代码上可能也只是增加20行代码。

如此类推,一个包含1000行逻辑的设计,反映在代码上,代码行可能只有300行。越是基础 的代码,就越是如此。我们简单用代码量看这个问题,就很难看出问题的规模了。

这样一看,思维上的洞简直无处不在:我们以为我们看着代码,是看到了全部的信息,其 实我们丢失了无数的信息。