你能区分“古力娜扎”和“迪丽热巴”么?

从欧拉公式说起…

英国数学家伊姆雷·拉卡托斯写过一本书,证明与反驳。作者在书中虚构了教师在课堂上与学生们讨论正多面体欧拉公式V+F=E+2的猜想与发现、证明和反驳的全过程,这个过程复现了该公式演化的真实历史过程,其崎岖曲折的程度堪比……软件工程师和业务人员澄清需求。

其实,最简单的欧拉公式是指:

指对于多面体,其顶点数V、棱数E及面数F间满足:V+F=E+2。

比如下面的几个多面体,

image 图1 (正)多面体

它们都满足欧拉公式。然而,后来出现下面的这种中空的多面体,

image 图2 中空的多面体

它的顶点(V=16)、棱(E=24)、面(F=12)的数量满足:F+V=E+4,这并不满足欧拉公式。于是,我们可以修正欧拉公式,

指对于“只有一个曲面”多面体,其顶点数V、棱数E及面数F间满足:V+F=E+2。

这样,图2的这种物体就被我们除名了。然而,事情又变了,因为我们遇到了下面这些多面体,

image 图3 更加奇怪的多面体

这两个多面体的顶点、棱和面都满足V+F=E+3,都不满足欧拉公式。于是,我们要再次修正欧拉公式,

指对于只有一个曲面多面体,“其中多面体是一个以下列方式排列的多边形系统:(1)每一条棱上恰好有两个多边形相交;(2)从共顶点的一个多边形内的一点到另一多边形内的一点的连线不与任何一条棱相交是可能的,那么”,其顶点数V、棱数E及面数F间满足:V+F=E+2。

这样,我们再次除名了之前未曾考虑过的奇怪的多面体。然而,事情还没有结束,因为后来的数学家又遇到了下面的这些“奇葩”,

image 图4 更多更奇怪的多面体

是不是感到有些抓狂了?

这时,如果我们再看看最初的欧拉公式的表述,

指对于多面体,其顶点数V、棱数E及面数F间满足:V+F=E+2。

就会发现,到底什么是“多面体”,甚至到底什么是“顶点”、“棱”、“面”,这些都没有一个明确的定义,只有一个在脑子里面大致模糊的想法。

假如“多面体”这三个字是我们所用的语言,而真正符合欧拉公式的那些“多面体”(目前还无法简单地描述出来)我们称为“真相”,那么下面这个对应关系中,

“多面体” ——> “真相”

也就是通过语言来描述真相的过程中,就如上面欧拉公式不断演化所展示的,我们不得不思考两个问题,

  • “真相”本身能不能很容易被表述出来?
  • “语言”在表述“真相”的时候是否存在约束?

从“语言”到“真相”

就像上面的欧拉公式的例子里我们辗转多次也没有讲清楚“多面体”、“顶点”、“棱”到底是什么一样,在生活中,我们一直在遭受着要分辨来自各种语言(不同语种,但更多是相同语种但是不同背景的人在说)所表达的同一个真相之苦。比如,一家公司的不同业务部门可能都会谈论“客户”、“服务”、“销售机会”等等,但是他们所用的这些语言背后的真相是否一样,其实非常难分辨。

image 图5 被各种语言环绕的真相

就像图5所示,真相总是被各种语言环绕。这里语言的多样性其实主要并不是来自于不同的语种,而是来自于操持同一种语言却有着不同背景、不同立场、不同思考方式的人。曾经一度,人们会发问,是否存在一种“真语言”或者“纯语言”,或者如圣经里所讲的“上帝语言”,可以让人们沟通起来更加没有误解、没有寒暄、没有粉饰。目前来看,这无疑还只是个近似于科幻的想法,因为在用“语言”表达“真相”的过程中有三个挑战,分别是“强调”偏差“真相”的复杂性语言的二义性

“强调”偏差

人们在描述问题时,会采用反映自身思维的词来描述,所以会不断强调他们认为重要的东西,也会强调他们希望辩护或者争论的观点。比如,来自两个不同团队的架构师在绘制统一个系统的架构图时,一定会把各自熟悉的模块放在图的中央。

我个人的经验是,这个现象几乎到了无处不在的地步,甚至不能把它看作“挑战”了,只能看作是一个事实,必须接受,像空气一样。对此,我们每个人可以去做的有两点,一是自己在表述事情时,需要三思是不是在强调某些预设的立场,比如“我认为……很重要”,这个观点是来自于认真思考的结果,还是来自于自己希望直接说服别人某个观点。二是不要期待每个人说的话都没有预设立场,甚至相反,我觉得可以假设大多数人的大多数意见是有她/他背后想强调的观点的,所以要注意区分。

“真相”的复杂性

很少有简单的真相。即使像欧拉公式所涉及的“多面体”、“顶点”这些数学概念, 你认为头脑里有一个无可辩驳的清晰的概念了,但是当你表述给另一个时,还是不能保证对方可以构建出同样的概念。想想上图2-4中那些奇怪的物体吧。

产生真相的复杂性的一个原因,请先思考一下你如何去描述什么是“牛”?

image 图6 描述一头牛

也许,描述一头牛最没有歧义的方式是使用DNA序列,但是这是生物学家的语言,对农民来说毫无意义。对农民来说,“牛”的概念是和“头上长角”,“吃草”,“产奶”这些表述关联起来的,而对于厨师来说,“牛”是指牛排、红烧牛肉、牛肉汉堡等等。

几乎任何一个简单的真相,都会在不同的上下文里投射出不同的样子。当“强调”偏差存在时,这种不同上下文产生的分歧会更为强烈。

产生真相的复杂性的另一个原因,请考虑下面两个问题,什么是“全体中国人”以及什么是“太阳系行星”。

对于第一个问题,可以回答“全体中国人”是指张三、李四、赵五、……(一个包含14亿个名字的长长的单子),或者也可以说“全体中国人”是持有中国居民身份证或者护照的人。

对于第二个问题,可以回答“太阳系行星”是指水星、金星、地球、火星、木星、土星、天王星和海王星,或者也可以说“太阳系行星”是指以太阳为中心,受到太阳引力约束的天体,并且这些天体:一、必须是围绕恒星运转的天体;二、质量必须足够大,它自身的重力必须和表面力平衡,使其形状呈圆球。

对于第一个问题,我们会觉得第二个答案更有效,对于第二个问题,我们会觉得第一个答案更清晰。诚然,对这两个问题的两个回答可以看作是归纳法和演绎法的区别,但是我想强调的是,它们所描述的“真相“是有区别的,“动态”与“静态”的区别。有些真相是动态的,像“全体中国人”,有些则是静态的,像太阳系行星。

这就是“真相”复杂性的源头。

二义性

二义性是人类语言的臭名昭著的特征了。不必说复杂的句子中的二义性,且看看下面这些词汇,

  • “大多数”,“基本上”,“速度快”,“稳定”……
  • “客户”,“平台”,“产品”,“服务”,“DevOps”……
  • “他们”,“这个”,“我们”……
  • 图表中的框、线和箭头

二义性的问题不必过多赘述。很少有人会反对的它的存在和影响。

由于存在着“强调”偏差“真相”的复杂性语言的二义性,导致从语言到真相这条路很坎坷。这也激发了傲娇的人类持续不断的斗争,

image 图7 各种研究“真相”和语言的流派

从中世纪的语言哲学到十九世纪的分析哲学,无数智者尝试解决这个问题。在这个过程中,人类关于自身、关于思考的知识总量得到了极大的提升,然而这个问题并没有得到根本的解决。

你能区分“古力娜扎”和“迪丽热巴”么?

再来回看这个问题。可能不追星的同学会对“古力娜扎”和“迪丽热巴”两位演员脸盲。无论你能不能区分她们俩人,只要你的脑子在思考下面两张脸,你的大脑已经自动地把“古力娜扎”和“迪丽热巴”分别映射到两个人身上了。

image 图8 “古力娜扎”和“迪丽热巴”

但是,假如有个不懂中文的美国人,他可能觉得“古力娜扎”和“迪丽热巴”非常容易区分,因为在他看来这是两组四个汉字组成的短语,两组汉字没有一点相似的地方,所以很容易区分。这个美国人不会把这些汉字映射到两个人,因为他不知道有这样的映射,或者说他不知道这个语言背后的含义。

对策

在说了这么多的问题之后,得看一看对策。不过再强调一遍,目前并没有一个可以完美解决这个问题的方案。不过值得高兴的是,人类从没停止对这个问题的探索。我觉得这些探索就像是治疗艾滋病的鸡尾酒疗法,混合了不同领域不同背景的不同方案,把这些方案放到一起,可以给人更多的克服挑战的决心。

我总结一些自己了解的方案,它们分别从一定程度上解决了“强调”偏差“真相”的复杂性语言的二义性。这些方案包括,系统循环图系统思考限定上下文建模DDD定义分析模式

image 图9 “鸡尾酒疗法”解决方案

系统循环图和系统思考

这两个概念随着彼得·圣吉的“第五项修炼”而流行开来。不过它们并不是彼得·圣吉发明的,而是很多系统专家、流程专家共同的智慧成果。

掌握它们的价值也非常高,尤其是一个团队和组织整体掌握了之后价值非常大。不过介绍系统循环图系统思考的书和培训课程非常多,所以在此不赘述了,只强调一点,系统循环图系统思考可以帮助一个团队或组织中的不同人看到全局,打破每个竖井的强调偏差。

限定上下文

在前面聊真相的复杂性时,提到过如何描述一头牛的问题。当时我们可以看到不同的背景、不同的专业对“牛”的描述完全不同。这个现象在描述其他的事情的时候也是普遍存在的。

image 图9 概念结合不同的上下文

随着和越来越不同的人打交道增多,我已经形成条件反射,当和别人讨论问题时,我总会预先想一下对方的背景和专业,再尝试着推断一下对方的mindset,看看应该如何挑选合适的角度来谈问题。比如当你给别人解释软件架构中的“微服务”时,对方的身份可能是大数据工程师、业务专家、项目经理,那么针对每个不同的身份,都要把“微服务”放在对应的上下文中。否则就是鸡同鸭讲,对牛弹琴。

建模、DDD和分析模式

限定上下文可以分解真相的复杂性,而建模可以通过去掉额外的复杂度而简化问题。不过建模的挑战就在于,识别哪些复杂度应该被去掉而那些做为问题的核心要素要被保留。

比如,你要估计驾车从家到公司的时间,最简单的模型可以是

time = d/v

如果从家到公司的距离是20公里,平均时速是40km/h,那么路上耗时大约为30min。这个模型的结果“正确”吗?不正确。它需要太多的假设且忽略太多的现实考量,比如路况对速度的影响、距离的准确性、空气阻力对车速产生的连续变化、相对论效应中速度对时间的影响……那这个模型的结果有用吗?不一定,取决于你使用它的场景。大致估计你早上几点从家里出发,这个结果大致有用。但是如果你早上有个不能错过的会议,或者你的车速可以接近光速的一半,这个模型就很不准了。

建模是从事科学和工程的人手中的一件利器。对于软件工程师来说,重要性自然不言而喻。软件工程领域的建模技术非常繁杂,在这里我推荐两个我认为实际有效的建模方法,DDD分析模式

DDD最初的动机就直接瞄准了“软件核心复杂性应对之道”,无论是统一语言、限定上下文(和我前面说的限定上下文类似但不完全相同)、问题域和解决域空间,最终都是要得到一套有效的领域模型,来表述业务问题。

当我们建模的活动逐渐多起来,就会遇到对类似的问题进行建模,于是“这个问题和上次遇到的差不多,上次是怎么建模来着”这样的感慨会逐渐多起来。和“设计模式”类似,这些类似的建模场景可以被记录下来,变为模式。这些模式就是分析模式

分析模式听上去没有DDD这么潮,它是Martin Fowler在1995年的同名著作里引入的建模技术。我几乎是在“废纸篓”里发现了这块瑰宝。学习并几次尝试后,屡试不爽。关于分析模式,我会在其他的日记里做介绍。

最终我们希望得到的模型应该,

  • 简单
  • 正确捕捉问题本质
  • 没有二义性(形式化)

“真相”的复杂性、二义性与定义

回想前面的欧拉公式的例子,其实每次变化都是不断完善“多面体”的定义,以期望排除掉不满足“V+F=E+2”公式的多面体。其实,写下一个清晰简洁的定义非常困难,因为一个定义的陈述中需要用到更多需要进一步定义的概念,这个过程可以一直循环下去,直到止于某些能被普遍接受的概念(或公理)。

一个好的定义,可以缓解真相复杂性和二义性带来的问题。由于“真相”的复杂性,清晰的简单的定义并不容易。所以,必须首先考虑增加一个或者多个限定上下文,然后,考虑从以下两个出发点去下定义,

WHAT - 它是什么?

一般用于给成熟的或者稳定的概念下定义,比如“太阳系的行星”是指(它是什么?)水星、金星、地球、火星、木星、土星、天王星和海王星。因为太阳系的行星是足够稳定的,所以可以直接描述它是什么。但是,像“全体中国人”,就很难说是“张三、李四、王五”这样一直罗列下去。

HOW - 它是怎么来的?

一般用于给发展中或者动态的概念下定义,比如前面的例子中,“全体中国人”的定义可以是持有中国居民身份证或者护照的人。

最后强调一下,“WHAT”和“HOW”只是在下定义时的两个思路。当你和别人沟通时希望对某个概念达成一致,可以尽快给该概念下个定义。这是可以尝试从这两个角度来思考。

总结

本文从欧拉公式的历史演变开始,分析了人类使用语言表达“真相”的过程中存在的困境,最后介绍了由几种来自不同领域的解决方案组成的“鸡尾酒”对策。希望对你有用。