.. Kenneth Lee 版权所有 2019-2020
:Authors: Kenneth Lee :Version: 1.0
如何说谎
写小说的人擅长说谎,他们的心得特别值得学习。JK罗琳在《哈利波特》里面多次通过角 色的嘴把她的心得说出来:你要说谎,就要先想象一个真实的人,然后把自己代入这个人 ,你才能保证你的慌是没有破绽的。
罗琳自己也用一样的方法构思她的小说,为了写好《哈利波特》,她先写了《神奇动物》 ,《魔法史》等等一大堆的前置文本,而且很多人物,都用她的亲戚朋友做原形的。这样 ,到写《哈利波特》的时候,她无论怎么编故事,这些原始设定,就能保证她的故事不容 易自相矛盾了。
这种说谎方法的本质是,找到一个真实的东西,然后把其中一两个要素替换了,只圆这一 两个要素的谎,其他部分,全部用真实的逻辑来对照。这样自相矛盾的机会就会低很多, 因为真实的东西的逻辑破绽比人脑的破绽少得多。
哈利波特里哈利被抓捕队抓到的时候,第一个反应就是把自己想象为一个斯莱特林的学生 ,然后根据他看到的斯莱特林学生的行为模式来回答问题。这样,抓捕队的人互相校验逻 辑的时候,就不容易发现他说了慌了。罗恩,纳威都用过相同的方法。
软件构架其实是一样的东西,软件构架对外的承诺是你直接拍胸脯拍出来的东西,你说你 可以创建删除线程,又可以保证资源能自动释放,还可以自由选择如何分配内存,多CPU也 能跑,多核也能跑,性能还都高,每个说起来都好像挺容易。到时实现堆到一起,就知道 你瞎扯淡了。
完美的地图是世界本身,完美的谎言是事实本身。做不到说的是现实本身,就需要让它接 近事实本身。架构希望编一个完美的谎言,就需要在编这个谎言开始的时候,就确定一个“ 想象”的对象。你决定做一个线程库,你就需要先假设你眼中的硬件是什么样的,线程的组 织是怎么样的,没有这个硬件和实现的基础想象,你的谎言很快就自相矛盾,然后就编不 下去了,你认为你的线程可以随时删除,但你有10个核,在核1上你怎么删除核2上的线程 ?
为了说通这个谎,你可以假设你只有一个核,所以一个线程在执行的时候,另一个线程肯 定停着,你删掉它就顺理成章了。你也可以假设你有多个核,这样你的承诺会退化为,你 可以异步停另一个线程,并有办法等待它的退出。对这种基础设定的坚持,才能保证你的 谎是可以圆的。也正因为如此,你的谎(接口)其实并不自由,它直接左右你的大部分行 为。
架构本质就是实现,不同的是这个实现是基于抽象的现实来做的。你现在的硬件可能是只 有10个核,但下个版本可能有20个核。架构的实现要求实现在n个核这个基础上,但n等于 几呢?如果这个范围没有,架构还是能做出来,但可以优化的余地就少,如果n的范围可以 给出来,你可以优化的余地就大。
那么,我们什么时候希望把n确定出来呢?——不知道!n通常是和其他逻辑配合使用的,比 如n很大,我就需要创建一个查找树给他了,创建了查找树,查找树就会造成内存相关的逻 辑,等我们手中有一定的逻辑,我们就会看到n的定义域,比如n在1-10之内,是一种成本 模型,在10-1000是另一个成本模型,在1000以上,又是一种成本模型。换成其他接口,问 题是一样的,比如你做处理器,留多少个寄存器用来传参数?多一点当然好,但占面积和 指令空间,少了内,传参需要内存,简单应用需要传参很少,复杂应用需要传参很多,那 么这个n是多少?今天的应用这这样的要求,未来的应用可能完全不同,这个你永远不会有 非常严谨的结果。架构凭感觉,凭经验,很大程度上也是如此,它条件极多,很多时候调 查资源不足(对很多条件来说,这是常态),就要拍脑袋,但如果承认这些拍脑袋的条件 ,它的逻辑仍然是严密的。
但我关心的不是这个问题,我这里讨论这个问题,是想说明,“接口是不能人为封装的”。 不是说,你做一个线程库的实现,现在选择了这个接口,以后不喜欢了,就可以换成别的 接口。接口会在很大程度上绑定你的实现,只要你开始考虑竞争力,性能,功耗,时延, 可靠性。这些接口就一定是你的实现的反映,因为一旦你开始考虑这个问题,那堆n就变成 关键问题了,你会不断希望收窄n的范围。收到一定的程度,你就迫不得已要拉分支了——低 功耗专有分支也好,小体积分支也罢,快查慢删也有可能,慢查快加也是竞争力。世间安 得两全法,不负如来不负卿?两全不了就只有多分支。你没有办法一方面要竞争力,一方 面说“你架构控制不好,为什么不统一版本?”——竞争力不够的时候,要把架构版本踩死的 时候也没见你这么说啊。
这些都是个度的问题,架构师,管理者,不能为了自己思维的方便,在这个逻辑下要这样 ,在那个逻辑下要那样,还问:“你不同意,你说选那样?”,你要我说,选哪样都是错, 这个问题就是要具体问题具体分析的。