Chapter Content

Calculating...

哎呀,大家好。今天呢,咱们来聊点儿有意思的,关于进步这事儿。

你知道吗?我们现在科技越来越发达,想要解决的问题也就越来越难。问题难了,需要的东西也就越来越多,对吧?就好比说,要是在小河上搭个桥,那简单得很,几个核心部件就够了。但你要是在大江大河上架桥,那就完全不一样了,得有更多的地基啊,桥墩啊,还有梁啊,才能保证桥的牢固。而且还得考虑热胀冷缩,还有风啊,地震啊这些因素,对吧?

所以说,难题的本质就是这样,要考虑的因素多,需要的部件也就多。你看我们人类历史上的那些发明创造,就能看出来,现在的东西零件比以前的复杂多了。就拿现在的客机来说,光零件就上百万个!电网也是,连接点数不清。卫星上的天线、太阳能板、推进装置,那叫一个复杂。汽车也一样,各种高科技,什么性能提升啊,安全保障啊,方便舒适啊,全往上堆。还有芯片,一个芯片上就有几十亿个晶体管。总之啊,难题就是需要更多的东西来解决。

照理说,东西越复杂,我们需要的知识也就越多才对。现在造东西的人,应该比以前的人懂得多才对。你想想,两百年前的桥梁工程师要懂的东西,跟现在的桥梁工程师要懂的东西,那能一样吗?

这就产生了一个问题了。我们人类在短短几代人的时间里,怎么能创造出这么复杂的东西呢?一个人怎么能掌握这么多的知识呢?难道现在的人都比以前聪明吗?还是我们现在的人更努力呢?其实都不是。人的大脑五万年都没啥变化,而且现在的人肯定没以前的人努力。那我们到底是怎么在没有变得更聪明,也没有付出更多努力的情况下,取得这么惊人的进步的呢?

说实话,要是科技进步要求人类的知识水平跟上我们发明创造的复杂程度,那科技进步根本就不可能发生。我们之所以能不断进步,是因为每一代人都是站在前人的肩膀上,从一个更高的起点出发。我们只需要了解当前的进度就好了。人类的智慧,其实就是这么一步一个脚印积累起来的。我们不断地改进和完善我们的发明创造,把上一代的成果作为下一代的起点。进步不是靠更聪明的人,也不是靠更好的想法,而是靠把前人的工作融入到新的起点,自动地,必然地向前发展。只有把今天的解决方案打包成更容易使用的工具,人类才能不断前进。所以说,人类的进步,其实就是一个不断抽象化的过程。

就拿软件开发来说,这50年来,变化可以说是翻天覆地。其实就是用更少的代码,更容易地实现相同的功能。最开始是用机器码,那是最难的一种方式。机器码是计算机硬件直接处理的二进制指令。你想想,要用机器码来指挥一个机器人走迷宫,那得用多少0和1啊!

机器码是最接近芯片的指令,所以它是最低级的抽象。用最低级的抽象来完成任务,需要的时间最长,因为每个指令都很基础。就好像你要盖房子,不用预制件,直接从原材料开始做,那得多费劲啊!

比机器码高级一点的是汇编语言,你可以把它看成是机器码的人类可读版本。汇编语言用的是我们人类更熟悉的符号,这样就更容易阅读,也更快地指挥机器。你可以把汇编语言看成是机器码之上的一层界面。有了这层界面,程序员就能更快地完成任务。因为你在汇编语言里拉动一个“杠杆”,实际上在机器码里就拉动了好几个“杠杆”。

再往上就是过程式编程。这种语言可以用命名的过程和函数来指示机器。这就像是预先打包好的汇编语言块,抽象程度更高。把汇编语言打包成块之后,程序员就可以用可重用的模块来思考计算机的功能。现在,我们的盖房材料都已经是半成品了,盖起来就容易多了。

但是,要开发更复杂的软件,需要更大的团队,更好的沟通。各种各样的需求都要管理起来,然后融入到开发过程中。团队要探索更多的可能性,还要不断地迭代原型才能实现目标。这样一来,过程式编程对很多现代应用来说就显得太笨重了。于是,新一代的编程语言就出现了,也就是面向对象编程(OOP)。这种编程方式,把过程式编程中的那些底层细节都抽象掉了,引入了对象这样的概念,把数据和行为封装成更高级的可重用组件。

有了OOP,我们的盖房材料就更高级了。OOP引入的计算结构,更符合我们人类的思维方式。像继承、多态、封装这些概念,让软件开发上升到了一个更高的层次。想想看,有了预制的建筑材料,盖房子就成了一件更有战略性和创造性的事情,因为你不用再纠结于那些极端的细节。在工业规模上,这意味着你可以更专注于优化效率,质量控制,可扩展性和可持续性。有了OOP,从汇编语言开始的“分块”功能,现在达到了模块化和可扩展性的水平,使得计算机编程更快,而且更容易被对计算感兴趣的人所接受。

但这还没完。现在的人们想要的是动态的Web应用程序,比如在线购物网站、社交媒体平台、网上银行服务、学习和协作工具、旅游和预订网站、游戏系统、医疗保健和招聘门户网站,还有各种在线市场。这时候,脚本语言就变得非常重要了,它可以开发交互式的动态用户界面。像异步操作、事件处理、浏览器兼容性这些挑战,促使了抽象程度更高的编程语言的出现。通过简化和提高人类指示机器的可读性,像内存管理和指针运算就被抽象掉了,取而代之的是动态类型、大量的库以及一个支持快速开发的大型社区和生态系统。有了脚本语言,从想法到可用的软件之间的距离就越来越近了。

最高级的抽象是可视化和音频界面。图形用户界面(GUI)通过提供底层数据和功能的视觉表示,抽象掉了机器交互的内部细节。现在已经有了拖放式的软件组装工具,而且随着人工智能(AI)被应用到开发工具中,完全不用写代码的开发也正在成为现实。甚至残疾人都可以用语音指令来编写代码。

现在,整个应用程序都可以在几周内完成原型设计。实现这一目标的劳动组织方式,与50年前大不相同。许多非技术人员现在在使今天的软件产品成为现实方面发挥着至关重要的作用。技术和非技术专业人员之间的界限正在打破,这是因为今天的软件开发工具实现了很高的抽象水平。

这意味着,现在可以用软件解决的挑战,远远超过了前几代人所能解决的。我们现在可以分析前所未有的大量数据。我们可以制造出具有某种智能的机器,执行诸如语音识别、图像分类和自然语言处理之类的任务。我们现在可以创建先进的气候模型,分析和关联患者记录,探索遥远的行星,研究宇宙现象,并通过视频会议将全球的人们连接起来。

软件,从一个不起眼的实验,变成了我们经济中最大的参与者。软件带来了前所未有的协作和人类连接。而这一切之所以成为可能,都要归功于抽象水平的不断提高。每一代人都比前一代人更容易地组装软件,这意味着他们可以解决比前一代人更难的问题。这意味着他们能够管理和控制必须用于解决难题的越来越多的碎片。

抽象不是消除细节,而是将它们整合到更高级的结构中,从而可以用更少的杠杆来操作更多的部件。抽象使进步成为必然,因为它通过打包细节和创建界面来推动人类的智慧向前发展;这些界面是下一代的起点。

当我们环顾四周,看到摩天大楼、卫星、超级计算机、高速列车、核电站、智能手机、计算机和生物医学植入物时,很难想象人类能够创造出如此明显的复杂性。人类创造的物体的内部运作非常详细,需要精密的协调和时间安排,而且总的来说,非常可靠。但是,当我们意识到每一代人都只需要将上一代人作为其起点时,进步的发生方式就变得清晰了。一代人中的建造者不需要了解一切是如何运作的,他们只需要理解他们当前的抽象水平。

这意味着,关于事物内部运作的绝大部分知识,并没有掌握在今天活着的人手中。这种知识已经被每一代人添加到他们的创作中的不断增加的抽象水平所掩盖。对于人类创新的所有领域来说,都是如此。今天的人类并不比我们的祖先更聪明。我们并没有更加努力地工作。我们甚至不知道那么多。人类的进步最好被理解为是一个不断提高抽象化和自举进步的故事。

抽象这个词,我们通常是在认知的层面上理解的。人类创造出高级概念,这些概念是从特定例子的使用和分类中得出的。通过选择将具体的例子组合成一个类别,我们就是在实现抽象。比如说,所有犬种都属于“狗”这个类别,这就是创造了“狗”这个抽象概念。画一幅抽象画,就是只设想产生印象所必需的、没有细节的部分。大脑中的抽象,是人类理解和导航他们复杂环境的方式,通过降低在生活中穿梭于细节所需的认知负荷。

你可能会觉得,抽象只是一种信息现象。毕竟,每一代计算机程序员带来的高级结构,都是信息块,是在信息层面上进行交互的。在编程中创建一个模块,就类似于在人类语言中创建“狗”这个类别。这是一种降低驾驭软件中大量细节所需的认知负荷的活动。

但抽象也可以是物理上的。刚才那个盖房子的例子,不仅仅只是一个比喻。如果你使用更大的预制件作为起点,你就是在使用抽象。正如大脑可以将具体的例子组合成一个类别一样,物理细节也可以组合起来,以便在更高的层面上服务于单一功能。

我们可以通过人类如何使事物可用,来理解物理抽象。如果人们在挥舞石斧的时候,必须用手按住刀刃,那肯定没人会用它。用来捆绑的绳子,把刀刃和斧柄结合成一个单一的物体,从而消除了用户考虑它们连接的任何需要。只有当操作事物所需的努力,低于手动协调每个部件所需的努力时,事物才是可用的。

再说说汽车。如果司机需要手动协调内燃机、底盘和变速箱的所有内部运作,那肯定没人会开车。提供给司机的界面,其细节远少于机器的内部运作。即使是手动变速箱中的变速杆,也是一种物理抽象。它实现了所有抽象所做的事情;提供了一个减少完成任务所需拉动杠杆数量的界面。有了变速杆,司机只需移动一个杠杆和离合器,就可以选择所需的档位,而无需物理地啮合变速箱中的每个档位。清晰标记的档位位置是一个界面,它使司机无需浏览一系列内部细节即可进行选择。当然,自动变速箱将物理抽象提升到了一个新的水平,使我们可以在几乎不考虑其内部工作原理的情况下操作档位。

正如我们从思维上将不同的事物组合成单一类别一样,变速杆代表着一个包含一组内部物理细节的单一物理结构,而自动变速箱则更进一步(感谢后续的一代人)。伴随人类智慧的物理版本的抽象,是人类进步的关键组成部分。

在给定行业或职业中实施的一组最佳实践,是围绕我们创建的物理抽象来构建的。MRI技术人员不需要协调磁化、射频脉冲激励、信号检测、数据采集和图像重建。咖啡师不需要手动加热水、建立压力、研磨咖啡豆、提取风味或产生蒸汽。沥青摊铺机不需要采购石头、砾石和沙子,也不需要试验粘合剂。任何领域的专业人员,都是通过物理抽象,在先前已完成的细节之上运作的。这意味着,我们的知识和技能概念,与物理抽象完全一致,因为它们是人们用来操作其领域中系统的起点。

人类的所有进步,都是一个在不需要比前一代人更多的知识或努力的情况下,推动人类前进的故事。但是,尽管这种进步是自动和必然的,但是创建界面需要深思熟虑。进行物理抽象是一种有意的行为,需要长时间和仔细的考虑。历史上,人类创造的物理抽象是由设计实现的。

创建物理抽象最明显的方法是通过设计。我们可以就包括哪些部件、如何连接它们以及如何通过界面公开其底层功能,做出有意识的决定。在计算的例子中,过程式编程是通过就如何将机器代码片段捆绑到更高级的语法和语义中做出有意的决定而产生的。这需要经过计算的推理。一个人必须深入到他们当前抽象级别的内部,并决定如何连接这些部件并将其公开到一个更高的级别。设计通过打包对象的内部工作原理来创建物理抽象。这会将不同的功能分组到更高层次的单一结构中。正是这种捆绑,使得可以更容易地从外部协调系统内部的不同功能。

这向我们表明,抽象的信息版本和物理版本是紧密相连的。设计中使用的慎重推理使我们注意到一组不同事物之间共享的特征。变速杆之所以有效,是因为它连接到一组共享共同目的的较低级别的内部部件。这种物理结构是通过使用我们的精神能力来注意模式,并将这些模式分组到更高级的形式中来实现的。物理抽象是我们用大脑进行的有意识抽象的反映。

我们可以看到,人类通过抽象来实现其技术进步,并且可以通过设计来实现抽象。这使得设计成为我们历史进步的核心组成部分。但是,设计是有代价的,因为如果不亲眼看到系统的内部部件是如何相互碰撞的,就无法进行设计。

设计依赖于确定性。设计就是推理在较低和较高抽象级别之间建立的显式连接。这就是为什么设计依赖于确定性。只有当我们能够评估系统的输出是如何产生的时,才能进行设计,才能具有确定性的意义。除非我们能够看到不同的齿轮是如何相互影响的,否则我们无法将传输的内部工作原理捆绑到更高级的变速杆中。除非我们能够明确地看到C语言是如何工作的,否则我们就无法将C语言捆绑到C++模块中。这是设计背后的整个理由。如果我们无法推理每个内部部件是如何相互作用以产生输出的,那么我们的设计就只不过是猜测和假设。

有人可能会试图建议,设计实际上本身可以是高层次的。设计难道不能是一套指导方针,帮助引导人们朝着积极的方向努力吗?这难道不会使设计与严格意义上的确定性脱节吗?但那不是设计,那是一种方法论或框架。框架是帮助人们保持正轨以实现某些目标的总括性原则。这些东西不会深入到系统中并推理其内部结构。设计就是就不同的元素如何相互作用和关联做出有意的选择。设计完全依赖于确定性知识的前提。

确定性与系统或过程有关,这些系统或过程的行为完全可以基于其输入和控制其运作的规则来预测。如果你一次又一次地将相同的初始输入提供给一个确定性系统,它将总是产生相同的输出。这种可重复性、可预测性和不存在随机性的概念,都内置在设计概念中。设计是在假设存在一套从输入到输出的明确步骤的前提下运作的。如果不是这样,那么选择特定的部件和连接将是徒劳的。

再次强调,区分确定性系统/过程和非确定性系统/过程非常重要。非确定性系统是指其行为无法完全预测的系统。与每次都为给定的输入集产生相同输出的确定性系统不同,即使提供相同的输入和初始条件,也可以预期非确定性系统会产生不同的行为或结果。相同的一组汽车和司机,以相同的速度行驶,到达一个没有停车标志或交通信号灯的十字路口,将不会产生完全可预测的交通流量。车辆的运动顺序和流量将会有很大的变化。即使提供相同的输入,也会产生不同结果的系统,是无法设计的。

有些读者可能会在这里停顿一下,宣称前面的例子一定是错的。因为我们知道交通系统确实可以设计,而且它们显然为交通流量增加了可预测的行为。但这并不是设计交通本身,而是设计一个控制非确定性系统(交通)的外部框架。当前的交通系统并不试图控制车辆之间的具体交互,它们只是对所有车辆施加外部限制。这类似于政府创建监管自由市场的框架。任何试图设计系统本身的行为,例如规定汽车之间或客户和卖家之间的具体交互,都可以预期会干扰非确定性系统的运作。

非确定性与问题的难度直接相关。正如人们无法(在内部)设计非确定性系统一样,难题也无法通过确定性来解决。难题,正如我们将在第4章中看到的那样,是需要通过试错法和启发式方法来解决的问题。正如在引言中声明的那样,难题并不是相对于简单问题而言更具挑战性的事情,而是一种在类别上截然不同的情况,需要一种非常不同的解决方案。

当涉及到解决难题时,我们可以通过观察自然界来理解解决方案必须有多么不同。正如已经声明的那样,自然界的解决方案解决了所有最难的问题。这些天然的难题是由自然环境呈现的,并且由不会使用简单的确定性连接的部件混合将输入转换为输出的对象来解决。自然界通过实现涌现结构来解决其挑战。这意味着,自然界不会创造出在输入和输出之间有明确步骤的解决方案。这种结构无法解决天然的难题,因为自然界的情况是由无数定义它们的因素和交互作用构成的。这与收集足够的规则来解释自然界的复杂性无关;事实上,这根本就不是一个规则游戏。即使我们能够制造出一个针对每一种可能情况都有规则的对象,它也无法解决难题。

将难题视为规则系统的更难版本,类似于尝试使用经典力学来描述量子力学。经典描述与正在发生的事情相去甚远,因为量子领域根本就不是经典的。这与程度或近似无关,而是一个完全不同的东西。

自然界的解决方案具有真正的复杂性,这意味着它的输出不是总和交互或顺序过程路径的产物。自然界创造的物质配置以完全不同于基于规则的处理的方式产生所需的输出。我们稍后将研究这种不同的机制,但是现在,至关重要的是要认识到自然界的解决方案与人类产生的简单系统根本不同。自然界的解决方案不仅具有大量的非确定性,而且它们还需要非确定性才能像它们那样运作。

想想人脸识别;这是人类和高级人工智能系统自然执行的一项壮举。使人脸识别成为一个难题的,不仅仅是与该现象相关的因素数量之多,而且“解决”这个词的含义与我们通常的确定性框架有所不同。在确定性下,“解决”意味着它在数学中的含义,即找到一个特定的、明确的答案或一组答案。但是,非确定性系统更类似于概率答案的概念,具有一定程度的正确性;这是我们在确定性中看到的较软版本。

但是,虽然这种柔软的类比更接近于非确定性的精神,但它仍然将非确定性框定为我们在确定性系统中看到的近似版本。例如,大多数寻求计算上难题解决方案的计算方法,都使用诸如优化之类的技术来找到满足某些标准或目标令人满意或可接受的结果。但是,正如我稍后将论证的那样,非确定性是确定性的二流或近似版本的想法是不正确的。

在复杂性下发生的解决不是更弱或更近似的解决方案,而是完全不同类型的解决方案。此外,在复杂性下发现的解决方案类型,比精确和确定性解决方案所能提供的任何东西都强大得多,也更现实。近似的概念只是通过简单性的视角错误地思考复杂事物而产生的另一个副产品。对于难题的真正解决方案不是近似,而是通过使用根本不同的计算概念直接计算所需的答案。数学计算的运行与解决现实世界的问题之间的严重区别将在稍后进行详细说明。

复杂性核心缺乏因果机制,排除了设计能够产生使复杂性易于处理的解决方案的任何机会。没有可以创建的捆绑来向用户公开确定性连接的界面。设计对确定性的依赖意味着设计只能找到对类别上简单问题的解决方案。

这使我们来到了一个关键的十字路口,这是由我们历史上通过构建事物来解决问题的方法所提出的:1)我们需要创建物理抽象才能取得进步,2)物理抽象的创建一直是通过设计来完成的,3)设计无法解决难题,以及4)难题是我们现在必须用我们构建的事物来解决的。

我们目前创建物理抽象的方式很快就会结束。设计无法创建我们需要构建解决方案的东西。我们现在面临的固有复杂性需要设计无法提供的东西。我们无法推理部件和连接,因为自然界的解决方案解决问题的机制本质上是不同的。

总是将自然界说成是一种确定性机器,这是一种错误的具体性。有时,这只是一种看待世界的幼稚方式,另一些时候,这种违规行为在社会和政治中危险地发挥作用。但是现在,自然界类似于基于规则的机器的观念直接阻碍了进步。只有通过极大地重塑构建事物的含义,未来才能保持易于处理。

问题类别的根本变化以及解决它们所需的解决方案,巩固了在复杂性时代有效运作所需的哲学转变。挑战不仅仅是接受因果理解的退化,而是重新定义我们对知识、技能和人类创新方法的概念。我们必须以不同的方式构建。

需要抽象才能进步。无法通过设计继续取得进步并不能否定抽象是进步所必需的事实。无法通过简单地将更多的部件连接到不同的对象中来解决更困难的问题。必须将部件捆绑到更高级的结构中,以供下一代使用。这就是如何将大量部件正确地放置到更复杂的对象中。单独地、慎重地并且以正确的协调方式来安排数千或数百万个部件,在计算上过于苛刻。较低级别的部件必须找到必要的信息凝聚力才能在一个更高的级别上解决问题,而抽象是实现这种凝聚力的方式。

对于任何进步的概念来说,都是如此。想想人类的头脑是如何创造抽象来理解我们的世界的。如果不将我们所见所闻放入更高级别的实体中,我们就无法在生活中航行。如果我们不能将事物归类为威胁与机会,朋友与敌人,食物,危险,住所等,那么我们就无法生存。通过在头脑中创建心理抽象,从而将表面上不同的事物纳入单一类别中,我们大大降低了在生活中穿梭所需的认知负荷。

这种发现不同事物之间联系的能力扩展到了我们所有的创新中。从新的哲学到新的技术,一切都来自于我们可以将信息和物理事物绑定到新的实体中。正是抽象使难题在计算上可行,因为抽象是产生新的信息和物理结构的东西,这些结构可以进行计算,而不需要问题的细节与解决方案的步骤之间的一对一匹配。正是抽象安排了事物,以便必要的内部部件协调可以处理更困难的挑战中的众多因素。简而言之,没有抽象就没有进步。

对于自然界来说,正如对于人类来说一样,都是如此。自然界通过其随时间变化和发展的过程而进步。自然界的解决方案不断地针对不断变化的环境压力源解决问题。如果我们退后一步,从整体上来看待人类创新,这是一个正在由自然界解决的问题,因为人类是成群结队地互动以解决问题的有机体。但是,当涉及到我们的具体发明时,正如已经讨论过的那样,人类通过设计来创造他们的新抽象。放在一起的部件是慎重地完成的,使用的是关于这些部件如何相互作用的因果信息。这不可能是自然界创造其抽象的方式。自然界没有使用有意识的推理将部件绑定到更高级的结构中。然而,自然界解决的问题远比人类用他的桥梁和火箭发动机所解决的问题困难。

这提出了一个关键问题。如果通过抽象来取得进步是一种普遍的属性,由任何通过进化来解决更困难问题的系统所拥有,那么自然界是如何创造其抽象的呢?

在这两种情况下,物理抽象仍然是将功能捆绑到更高级别的组中并公开一个界面,但是自然界的捆绑不是一些确定性设计的聚合,而是物质的统计自动表现。如果这一切听起来太模棱两可了,请放心,本书的其余部分将描述我的意思。但是,在这一点上重要的是要承认,自然界的物理抽象虽然对于进步至关重要,但不是设计出来的。自然界没有进行有意识的努力来选择哪些部件和交互作用构成了捆绑,因此自然界中的抽象必须具有根本不同的机制。

这就提出了一个问题:如果自然界无法推理出要包括哪些部件以及如何连接它们,那么自然界如何“知道”要将哪些部件组合成更高级别的结构?自然界如何创造其捆绑?无意识的自然选择过程如何发现将一个层级的物质连接到下一个层级的相似之处?

Go Back Print Chapter