加法是自然之道

写代码和数据处理有一个共同规则:只新增append/insert.不修改替换update/replace。这个原理符合自然加法规则,符合构造定律Constructal Law。

我们一直在说道法自然,那么自然之道是什么呢?我认为自然是在做加法,老子道德经说道生一,一生二,二生三,三生万物,这句话符合构造定律Constructal Law。

所谓构造定律,是由Adrian Bejan于1995创立的构造定律:

For a finite-size system to persist in time (to live), it must evolve in such a way that it provides easier access to the imposed currents that flow through it.

对于一个有限大小的持续活动的系统,它必须以这种方式发展演进:它提供了一种在自身元素之间更容易访问的流动方式。

这个定理在自然中比比皆是,典型的是树的生长,先有根,再有枝,枝上再生枝叶。这种自发性质的设计反映了这一趋势:他们允许实体或事物更容易地流动 - 以最少的能量消耗到达最远的地方,就连街道和道路这些人为地构建物体,往往也是有排序的模式,以提供最大的灵活性。

构造定律的本质是什么?是以树形结构做加法。这是我认为的自然之道。

首先从软件开发工作谈起,我们软件系统平时面对的是两个不断增长量:代码量和数据量。

代码的加法
代码一行一行在编写,当我们的代码类变得很多很多时,怎么办呢?有人说,Java的问题不是太罗嗦,而是OOP使得类的数目很多,我想不管使用什么语言,代码量增多迟早会面对,不是抱怨指责,而是要积极面对。

面向对象编程原则和GOF设计模式已经在告诉我们如何维护拓展这些类代码,宁可增加新的类代码,尽量不要去修改那些经过测试已经成熟稳定的代码,也就是说,不要去做修改替换,而是要做增加。这种增加如同树的成长,是一种枝生叶的繁茂。

我们唯一需要做的是跟随自然之道,使用树形结构去组织这些代码量,具体在软件的复杂性和构造定律中讲得很清楚。

数据的加法
当我们的系统从小到大,用户量越来越多,数据越来越大时,原来传统的关系数据库可能已经无法容纳这些大数据,我们需要增加系统规模,使用分布式系统来实现数据处理的加法。当然过去还有一种集中式的实现方式,通过小型机 大型机垂直伸缩大到处理大数据的能力,这种集成式整体式的架构正在被扁平的水平伸缩的微服务分布式架构替代。

来自LinkedIn的Kreps发布了其具有程序员史诗般的博文:日志是每个软件工程师关心的统一数据抽象

该文主要提出使用日志复制的方式来实现分布式系统之间的数据同步,而日志是一种只有新增append,没有修改替换的数据处理方式,当我们将一台服务器上业务操作日志复制到其他服务器上,是不是类似自然中一棵树将营养以最低能量的消耗方式在枝叶节点之间传输呢?我们唯一需要做的是让整个分布式系统的服务器之间关系如同树形结构一样,正如我们将代码之间使用对象或层封装隔离成一种树形结构一样。

性能和效率
函数编程之所以没有副作用,关键是因为它没有可变状态,基本都是不可变的,如果需要共享数据怎么办?那么就实现数据的复制。

状态通过修改替换的操作实现的变化称为可变状态,看来计算机系统本身比较厌恶状态修改替换,因为可变状态不仅带来副作用,更重要的是无故耗费计算机性能,为了保证一个状态的可变操作原子性,需要ACID,无论数据库还是应用服务器 或者编程语言都需要通过特别的事务机制保证原子性,特别是并发编程情况下,可变共享状态简直是并发并行的死敌。

如果我们将一个系统的可变状态尽可能缩小甚至消灭,那么无疑我们的系统处理能力就能够以纯粹线性加法方式增长。函数编程语言能够从语言层面达到这个目地,而在业务层面,我们使用EventSourcing + DDD + CQRS的方式也能缩小可变状态,使用聚合根来包裹可变状态,使用事件日志记录的追加和回放实现可变状态的切换。

是否能广泛适用?
因为我们的软件系统是人造的系统,相当于人类学习大自然一样在制造一个新的“大自然”,正如我们模拟人脑神经网络发展我们的机器学习一样,无怪乎爱因斯坦会说:看啊!看!深入研究自然,你就会明白一切。

自然规律是以树形结构方式进行加法发展,那么我们是否在做其他科学系统时也要注意到这个自然之道,而不是忽视它们,那就变成了“作”, No Zuo No Die。

比如一条新闻:中国工程院院士倪光南表示,基于应用商店的国产操作系统将有望在今年10月份推出。倪光南表示,希望在这两年完成对XP系统的替代,在这基础上,在3到5年内实现对(安卓、苹果和微软)三大智能终端操作系统的替代。

我首先想到的是:为什么我们不做新增append,而是要做替换?我们不一定要在乎是否拥有自己的发动机或操作系统(因为这些别人已经发明),而是我们是否在为世界文明添砖加瓦(做别人没有的才是做加法)。

当我们注重跟随自然之道,而不是注重“人有我无”这种人之间争夺时,我们就会垄断下一个根资源。自然是做加法,过去石油是垄断资源,我们通过科学创新做加法,我们就可能将太阳能等其他资源作为未来的垄断资源。中国一些传统文化在影响我们,常常让我们不自觉去和人抢夺现有的资源,或者做别人已经成功的作品,这些都是在做修改替换,不是在做加法。

以上纯属闲扯,仅供参考。

[该贴被admin于2018-09-07 15:32修改过]

数据库作为队列是反模式。这篇文章指出使用传统关系数据库作为消息队列是一种反模式,其实队列是一种只有append新增和查询但是没有修改的机制,而关系数据库是CRUD全能,两者从本质上是不匹配的。

该文其中提到SQL服务器虽然对于插入 修改和查询很高效,但是三者针对同一个表却无法高效,你需要索引状态,而索引会降低插入性能,这其中锁是主要问题。

总之,如果想使用修改替换,就无法逃避使用锁,或单线程,这些都是相当于休克或限制,与自然增长的加法之道是背道而驰的。

[该贴被banq于2014-09-29 19:06修改过]


同意。
宇宙只有一个数学法则:加法;加法导致宇宙只有一个主题:不等;而不等即是变化。
为什么说宇宙只有一个数学法则?我们的数学不就是仅仅基于加法这一个基础的吗?减:加的反;乘:加的简;除:加的简再反……积分的实质:加法;几何:点积点得线,线积线得面……这里的积的实质是加法;不等规律:就是因为只有一个规律加法……没有任何一个数学上研究的东西不基于加法。
为什么说加法导致不等?不等是绝对的相等是不存在的。我们可以说2>1但是说1=1是错误的!因为只有一个1,自己跟自己比较没有任何意义。
不等是我们永恒的研究主题:不管我意识到没意识到相等都仅仅是我们研究问题的方法而已再无更深层的意义!不等是绝对的如果等号左面与右面绝对相等,那么等号左面是它自己右面也是自己!

如果宇宙之外有个观察者的话,在他看来宇宙就是个零蛋,但宇宙的定义是在它之外没有任何事物。虽然宇宙是个零蛋但对于宇宙之内的我们来说所有的我们能够观察到的想象到的臆测到的事物均是存在并且会永远存在下去。
宇宙没有开始,也没有结尾。
设想一个状态:这个状态没有“物质”没有“空间”没有“能量”……总之什么也没有。让我用null来代表这个状态。 显然null不会突然间改变。因为一个空的世界怎么会‘突然’生出东西来呢?null若改变就得无缘无故地生出东西。null要保持 null的状态,null要连续,这里的“状态保持”需要时间,或者说状态保持就是时间,再或者说连续性就是时间。绝对的不变的状态不存在,时间是衡量状态改变快慢的物理量。状态不能突然改变的连续的性质使null具有了时间概念。


掰开苹果的能量来自苹果本身。

根据能量守恒(能量守恒的本质是连续性)把某个位置的"O"一分为"O1"和"O2"放在两个位置则必定耗费能量,而这个能量从哪来?也许我们会这样想:分开"O"的能量来源于机械手,机械手的动力来源于电能,电能来源于燃煤,煤炭来源于太阳,太阳来源于质量,质量来源于……一直延续下去永无止境,这不符合能量守恒因为我们如此延续下去永远找不到能量的来源。这好像是在"O"外画个圈,而圈外有更大的圈,更大的圈外还有圈……一直圈下去永无止境,即找不到能量源(确切的说是在圈外找不到能量源)。既然如此让我们回过头来则能量守恒所要求的能量必定来自"O"本身(此为数学上的反证法)。现在既然能量来自"O"本身,则"O"损失能量以使"O"分开在不同的位置,在这个过程中"O"损失能量的结果是操作前后"O"的空间位置发生了变化,分开的空间中蕴含着势能和其它未知的能量形式,它们由"O"损失的能量转化而来(保持能量守恒)。至此我们确信"O"损失了能量而所谓能量其本质是质量的变化即损失了质量。所以O1+O2!=O这是核裂变的原理是E=MC^2的本质。

掰开苹果的能量来自苹果本身。
[该贴被anycmd于2014-09-29 20:26修改过]

写得不错,提出了“积”和“自身能量”两个观点,这两种是构造定律的两个基础,是系统生长的两个规律,也是决定为什么自然界采取树形结构这种方式进行生长。

积的英文是calculus,任何可计算的函数都可以使用calculus表达和求值。

从数学思维看,五大积分式演算模型完整描述了分布式与并发计算模型: λ (lambda) calculus, π (pi) calculus, actor model, join calculus, ambient calculus.

英文文章:Formalizing Concurrency, Distribution, and Mobility

来自github内部员工的一篇英文博文:快速前进,但是不要打破成规:他倡导小心谨慎的前进(治大国如烹小鲜),构建软件是困难的,如果你快速前进你就能做更多事,也就意味着你的公司工作进程就会更快,但是有时不要打破旧事物是很重要的,当你和这些旧事物一起工作时,你能改变你的操作方式这样能从新旧两个世界获得他们的优点。

[该贴被banq于2014-10-09 10:04修改过]
[该贴被banq于2014-10-09 10:05修改过]

2014-09-29 14:42 "@banq"的内容
数据的加法 ...

呵呵,这看来是压垮骆驼的最后一根稻草了,日志最大的敌人就是加法的限制了。
其实,回到n年前的系统,岂不都是只有加法,我们对于更新的做法就是删掉再换上新的,简单粗暴才是硬道理,呵呵。
但是,减法和替换的用处,岂是加法能做到的,不然’加的反‘,’加的简‘从何而来,又为何而来,为了这根稻草而本末倒置,是进步还是退步?
至于数据库是queue的反模式,不敢苟同,queue原本就是很特别的需求,就像邮件发出去,要想挽回,通常我们会重新发sorry请忽略前一封,而很少用到那个收回功能。需求决定功能。
如果我们赋予日志过多内容,一个基于eventbus的胖服务又来了,至少结构上是这样的,一个银弹爱好者俱乐部又成立了。而业务逻辑在哪里,那么日志的audit功能是不是有点本末倒置了?仅仅是月结盘点用,还是恢复系统用?我们用日志做过月报,也用日志恢复过单据流,但是前者显然理所当然,而后者则做得胆战心惊,,,就像数据库的data和log,我通常的一个选择是,小型系统,不记录log。

2014-09-29 14:42 "@banq"的内容
只新增append/insert.不修改替换update/replace ...

再者,是不是可以换个考虑,日志其实负责的,也记录减法,不光是加法。它自己,可以是加法,是不是好点。