《计算机思维》1:无情的计算
《计算机思维》(Computational Thinking ),作者是两位计算机科学家,美国的彼得·丹宁(Peter J. Denning)和芬兰的马蒂·泰德(Matti Tedre)。
借助这本书系统地、但同时也是快速地了解一下计算机思维 ——要理解计算机是怎么回事儿,计算机能帮我们干什么,以及怎样把计算机思维用于其他领域。
先玩一个小孩爱玩的、小小的数学游戏 ——
把你出生的月份和日期这两个数字相加,得到一个数;
把这个数乘以 18;
把所得结果的各个数字相加;
把上一步结果的各个数字再相加。
而我能猜出来,你最后得到的那个数字是什么。
这个游戏也许能让小学生感到惊奇,对大人来说就有点直白了。不过让你体会的是这一波操作的过程。
有什么感受吗?把一个两位数乘以 18 可能让你感到了一点痛苦。你必须兢兢业业准确无误地按我说的步骤操作,才能得到我想要的结果。你没有自我发挥的余地。
在这个过程中,你是一个 computer。
1.计算师
Computer 这个词,现在都翻译成“计算机”。但是这个词最初的含义,可是指人。早在十七世纪就已经出现了 computer,也许应该叫做“计算者”或者“计算师”。计算师不是数学家也不是工程师,他们是专门做计算的人。
二战期间,计算师甚至还是美军一个专门的编制。当时美军发明了射程能达到好几英里的大炮,而这个大炮怎么瞄准,就涉及到很复杂的计算。要算一个瞄准角度,你至少必须考虑目标到你的距离,目标跟你的高度差,以及当时战场上的风速。
如果你学过物理,你应该知道怎么算。但是,在战场上找个懂物理的人现场拿三角函数解方程可就太慢了。计算跟“会算”是完全不同的要求。美军必须把整个计算给流程化,变成标准操作,而且还得能让好几个计算师一起算。这就要求这个计算方法满足三个条件 ——
第一,计算过程必须被拆解成很多步骤,每一步干什么必须是简单而明确的。比如这一步就做个加法、下一步就查个三角函数表,在下一步是除法,等等。
第二,所有这些步骤要能拆分开来,分给几个计算师,各自负责其中的一部分。而这就有个交流问题,各个计算师算出来的东西得汇总在一起,形成一个最终的结果。
第三,还得有个纠错机制,让计算师们能觉察到自己哪里算错了。
按今天的概念,这其实就是“分布式并行计算”。这不但是计算机方法,而且还是超级计算机的方法。所以,我们可不是先有了计算机之后才有的计算机思维。人们早就有了计算机思维,只不过当时没有机器可用、只能用人。
这一波流程化的操作,叫做“算法”。“算法(algorithm)”这个词,也早在十七世纪就有了。
现在已知最早的一个算法,是欧几里得在公元前300年发明的计算两个整数的“最大公约数”的方法,中国人通常称之为“辗转相除法”。两个数的最大公约数,就是能同时被这两个数整除的最大的数,比如 18 和 48 的最大公约数是 6。你肯定会算最大公约数,但是你的计算方法需要自身的理解和直觉 —— 如果你仔细想想,你也许会发现自己有点说不清是怎么算出来的。
而欧几里得提出了一个得到最大公约数的标准操作。给定任何两个数,它们的最大公约数,和这两个数的差与其中较小的那个数的最大公约数是一样的。使用这个方法,你只做减法就能得到最大公约数!比如我们用 gcd 表示最大公约数,那么 ——
gcd(48,18) = gcd(30,18) = gcd(18,12) = gcd(12,6) = gcd(6,6) = 6.
欧几里得可能没想到,他发明的这套操作,到现在仍然在被计算机使用。
2.算法的妙处
能提出算法,和自己会算,完全是两码事。算法最大的好处就是它是机械化的操作。
有了欧几里得这个算法,操作者根本就不需要知道什么叫最大公约数,他甚至不需要知道我们为什么要做这个计算,他只要会算最基本的加减乘除,能够严格地执行规则就行。这就实现了可推广。
想要现场解决一个数学问题,原本你需要找个专家才行。专家有多年知识储备和技巧训练,他会用到巧妙的构思,很可能还有些说不清道不明的直觉,才能给你解决。可是专家太贵了。而如果我们能把一类通用的问题给算法化,你就不再需要请专家了。你只要雇些计算师就行。
算法化就是标准化和流程化。这其实就是整个机械化大生产的秘密!看麦当劳的食物,味道也可以,卫生也放心,价格也便宜 —— 而你去吃的那家麦当劳,可没有著名的厨师。每个麦当劳里的食物都是一样的。任何人经过简单的培训,都能给你操作出麦当劳食品来。麦当劳有自己的研发中心,它始终在测试不同的口味和营养搭配,但是因为它会算法化,它只要定型一个,就可以推广到所有。
麦当劳只恨做饭的不是机器人。人们从十七世纪开始就在琢磨怎么让机器去做计算,而且发明了构思巧妙的计算机,只是因为没有电子管晶体管这些东西,那时候的计算机不能取代计算师。
如果人类一直没有发明电子计算机,我们今天就会有一个叫做“计算师”的职业。这很可能是一个白领工作。计算师们很可能会使用中国的算盘做各种计算,还要背诵三角函数表和对数表。他们会被分成从初级到高级的职称,会有自己的职业道德和职业规范。他们可能都穿着统一的职业装,发型一丝不苟……
但是,那将是一个非常低端的工作。做计算师不需要什么聪明才智。
而要想比他们挣得多,要想领导他们,你就得掌握计算机思维。
3.计算机思维
古人对计算的钻研可不仅仅是算法,哪怕是没有计算机的时代,那些最聪明的人就已经想得很深了。十七世纪尚未发生工业革命,但是启蒙运动已经开始了,牛顿已经出来了,“理性”已经在知识分子中深入人心。
就在十七世纪,笛卡尔和莱布尼茨就有一个设想,说既然计算可以变成流程化、算法化的操作,那能不能把人的推理,也给机械化呢?
今天都爱谈论各种心理学意义上的偏见和谬误。启蒙时代的人就已经知道,让人去推理,是非常靠不住的。人会有各种主观的判断、有很多情绪化的东西。那如果我们能把一切理论的推理都给标准化、流程化、机械化,不管是谁来操作,只要你严格遵守规则,就一定能推出客观的、正确的判断,这岂不就解决了一切争论吗?这不就是通往真理之路吗?
笛卡尔和莱布尼茨想要的,是冷酷无情的计算。
这恰恰就是计算机思维的第一原则:把人的情感和主观判断排除在计算过程之外。
好消息是我们现在已经取得了很多很多进展。后世的学者发明了像“布尔代数”、“谓词逻辑”这些理论准备,信息论祖师爷香农发明了用电路实现通用逻辑运算的方法,而且我们有了速度无法想象的快的计算机……今天真的有很多理论推导,可以交给计算机去做。计算机甚至能证明数学定理。
但是,坏消息是计算机不能解决所有的问题。现代计算机的祖师爷,图灵,用“图灵停机问题”说明,哪怕在理论上,计算机也无法通过阅读一段算法来判断这个算法到底是能自动执行到停机呢,还是会永远计算下去。笛卡尔和莱布尼茨的那个梦想哪怕在数学上也是不可能实现的。
但是,我们仍然得到了一个自动化的时代!这个时代的计算机所能做的事情,一定会让十七世纪那些思想家和计算师大开眼界。
*
哲学家的思想总是领先于技术实现,而老百姓的思想则被技术所左右。
每个时代的技术,都会主导这个时代的人的思维。老一辈的人爱说“压力很大”、“动力十足”、“把压力化为动力”,这其实是一种暗喻 —— 是把人给当成了蒸汽时代的机车。而今天的年轻人则善于用计算机做暗喻,会说……“我的大脑死机了”。
计算机思维已经深入到了现代生活的方方面面。这一讲我们理解了“算法”。
《计算机思维》2:自动的机器
一个历史教训,那就是人的思想,可以领先于技术应用。人类并不是先有了计算机才有的计算机思维,而是早就有了计算机思维,在那儿等着计算机出现。借用一个佛教术语,启蒙时代以来思想家已经“照见”了计算机的可能性。
计算机产品是最容易过时的,今年买的手机明年就换代了。硬件可以被淘汰,软件可以被升级,但是,思想很难过时,数学永不过时。计算机的发展故事,是把思想实现的故事。
孜孜以求的,是一个“自动的”机器。
1.对自动的追求
下面这张图中是一个会下国际象棋的机器人,叫“土耳其行棋傀儡(Mechanical Turk)”。它在1770年出现在欧洲,能跟人类棋手对弈,而且水平相当高。它击败过拿破仑·波拿巴和本杰明·富兰克林这样的名人。很多人怀疑棋盘下面那个柜子里可能藏了一个人,可是打开柜子只能看到一堆齿轮。这个下棋机器人在欧美纵横征战了数十年。

……当然,那时候可没有“深蓝”和“AlphaGo”。一直到 1857 年这个秘密才被揭开,事实是……里面真的藏了一个人。只不过因为设计巧妙,看不出来而已。
但是你能看出来当时的人对“自动的机器”有多么着迷。人们迫切想要这个东西,而且人们认为有这个东西很正常。“土耳其行棋傀儡”是个魔术,但下面这个东西可不是魔术——

这是“作家机械人偶(The Writer)”,由瑞士钟表师皮埃尔·雅克·德罗在1768 年设计制造 [1]。它能自己拿笔蘸墨水,在纸上写字画画 ——

如果你见过这个会写字的机器人,再见到会下棋的机器人可能就不会感到那么不可思议了吧。其实下棋和写字还是有本质区别,写字只是“自动”,而下棋需要智能。但是在谈论智能之前,我们得知道,自动,已经是一个了不起的成就。
这个作家机器人偶是怎么写字画画的呢?你必须能把那些字和画的信息存储到机器里才行。而这是通过机器人后背的一个齿轮实现的,齿轮上代表不同字母的钢片的形状决定了字母写出来什么样 ——
而那些字母是可以替换的!你换一组字母,或者换一套代表绘画笔画的齿轮,作家机器人偶就可以写出别的内容。就好像我们现在玩游戏机,换个卡带就是一个新游戏一样。
十八世纪真是个蒸汽朋克式的美好时代。如果人类一直没有发明电力,今天看到的就都是这样的自动机器。像八音盒这种东西,它为什么能播放特定的乐曲?其实是一样的道理。借用威尔逊在《生命视角》中的一个说法,这是“严格的灵活性”:操作步骤是严格固定的,但是可以接受灵活的输入,产生不同的输出。
1804 年,法国人发明了一种提花织机(Jacquard loom),它能从一个长长的打孔卡上读取信息,织出特定式样的花纹。打孔卡上的孔可以让钩子穿过去,钩子控制织线。织机是同一个织机,打孔卡可以随便更换,换张卡就是不一样花纹。

打孔卡,可以说是机械化自动机器的软件。打孔卡这个技术思想在此后有广泛的应用,IBM公司最早就是靠这东西起家的……
但是,“严格的灵活性”毕竟不是真正的灵活性。打孔卡技术,距离可编程计算,还有根本性的一步。
2.第一台通用计算机
你可能不知道,第一台可编程的通用计算机,并不是电子的,而是机械的。
1820年,英国人查尔斯·巴贝奇(Charles Babbage)把“严格的灵活性”发挥到了极致,设计了一个叫做“差分机”的东西,它可以做多步骤的复杂计算。
巴贝奇的野心是用差分机计算正确的数学用表。当时公开发行的对数表、三角函数表都是人手算出来的,其中有大量的错误。巴贝奇认为人是靠不住的,这种计算应该交给机器。巴贝奇跟英国政府说,数学用表的错误会导致英国海军的计算出错,那么舰艇就出事儿,搞不好可能会沉船,现在我发明了一种机器,能做冷酷无情的计算。英国政府被说服了,真给了他一笔经费。
巴贝奇的设计包括 25000 个部件,具有强大的计算能力……但是他做了十年只完成了七分之一 ——

而这纯粹是因为硬件技术不允许。巴贝奇必须用齿轮和杠杆实现各种运算,可是这些东西没法做得特别精细,很容易这里卡壳、那里跳线,而且零件越多越容易出问题。英国政府一直看不到成果,把巴贝奇的经费停了。
巴贝奇做不出来,可是他特别能想……1830年,巴贝奇又自费发明了一个更厉害的东西,叫“分析机”。分析机,是一个可编程的通用计算机!
分析机的神来之笔在于它把操作步骤也写进了打孔卡之中,这样计算步骤就是不固定的了,就是可编程的了。不但如此,分析机还可以根据中间的计算结果,决定下一步的计算操作 —— 也就是说,它允许程序里有“If… then… ”这种条件语句,它甚至还包括循环语句!分析机有输入部分、有计算部分、有存储中间计算结果的部分,还有输出打印的部分……分析机,是真正的计算机。
巴贝奇还有一个合作者专门给分析机写程序,可以说是人类历史上第一个程序员,而且这是一个女程序员,叫埃达·洛夫莱斯(Ada Lovelace),他俩用了十余年的时间一直在研究分析机。洛夫莱斯甚至还想到,分析机不仅能用来做数值计算,还能作符号计算 —— 它不仅仅是个“计算”机,它是个能处理任何信息的机器!
……可惜的是,分析机也没做成。下面这张图是分析机的一个实验部分,来看一眼世界第一台计算机吧 ——

人的思想要是领先时代太多,是不是一个悲剧呢?巴贝奇因为发明数学表格的计算理论工具而得过英国皇家天文学会的金奖,他还是第一个提出“科学管理”的人。但是差分机和分析机被当时的人视为是巴贝奇身上的污点,什么实用成果都没拿出来,结果有一万两千个零件被溶解报废了。
1871年巴贝奇去世的时候 ,《泰晤士报》甚至还专门讽刺了他一番。
而通用计算机这种东西再次被人提出来,则是70年后的事情了。
3.现代计算机
1945年,因为电子真空管技术条件成熟和美国军方资助,世界第一台能用的通用计算机终于被做出来了,这就是著名的 ENIAC 。ENIAC 是现代计算机的鼻祖,它奠定了所谓的“冯·诺依曼架构”。而在此之前,艾伦·图灵已经提出了可编程通用计算机的完整数学理论。
约翰·冯·诺依曼是人类历史上最聪明的几个人之一。他是数学家、物理学家,是博弈论的创始人,还是现代计算机架构的提出者 —— 不过冯·诺依曼自己对此是否认的,他说这个设计是一帮人讨论的结果,他只不过负责做笔记而已。
相对于巴贝奇的设计,冯·诺依曼架构的关键改进在于它有了“内存”这个概念。负责计算的CPU速度很快,而从打孔卡读取计算步骤的速度非常慢,所以现在的设计是先一次性地把打孔卡的程序信息读进来,存到内存里,然后在计算过程中让CPU直接和内存交换信息,这就能大大加快计算速度。
从提花织机的打孔卡提供了“严格的灵活性”,到巴贝奇的可编程通用计算机,到冯·诺依曼架构的CPU和内存,这是非常清晰的演变。现在我们看到了,图灵再厉害,“编程”这个思想不是他先提出的;冯·诺依曼再神,计算机系统不是他发明的。
计算机是这么一个不断改进的东西。一代一代的工程师提出各种各样巧妙的设计 ——
要在硬件上实现信息的数字化,人们发现应该用二进制。十进制很直观,但是要用硬件实现十进制,你的电子管就得用十个级别的电压代表0-9这10个数字,这不但不容易实现,而且很容易出错。二进制只需要电子管和存储点有开和关两个状态就行,这就大大增加了可靠性。
然后香农设计了逻辑门……从硬件到软件的关键思想是分层。
然后你还要考虑CPU时钟的同步问题。如果没有“步”这个概念,各方面的计算没有协调,可能会导致两组电信号同时出现,系统就会出错。
然后你还要考虑存储信息和操作过程中可能会有各种小错误,而这就有一个自动纠错的问题……等等等等。
为什么说信息行业是个创新行业呢?因为第一,这里面的想法太密集,有太多可以改进之处;第二,改进的方向相当明确。这就是说每个参与者都知道自己能干什么……在其他领域,可没有这么好的事情。
*
从计算机思维的角度来说,这一讲的核心教训是你必须考虑硬件。永远都别忘了计算机是个机器,而机器有数学算法之外的、自己的特点和脾气。比如说,
x = 3
这个语句,在数学上的意思无非就是变量 x 的值是 3,是一个事实陈述。但是对编程来说,这不是一个陈述,而是一个动作:是把用 x 标记的那一段内存位置,赋值为 3。
机器不理解你要说的事实,机器只会按你的指令做各种动作。在编程的时候要 debug,要想办法控制内存,要提升计算性能,就必须考虑硬件自身的特点。
今天用的一切计算机,包括手机、汽车、凡是通用计算机,就都是冯·诺依曼架构。当然冯·诺依曼架构不是唯一的可能性。现在人们正在研究新的架构,比如量子计算机和神经网络计算机 —— 那些东西有自身的编程特点。
巴贝奇要是看到今天的计算机,是不会感到特别惊奇的。
网友评论