引言
几年前,我跟一个瑞士来的交换生一起坐滑雪缆车。我问她有没有想过高中毕业后打算做什么。她说她打算做工程,并且已经在前一年修了编程课程。我问她你们学了些什么,她回答:“Java。”我下意识地脱口而出:“那太糟糕了。”
我为什么会这样说呢?我花了一些时间才想明白这个问题。我那么说并不是因为Java这个编程语言不好,它其实挺好的。之所以那么说,是因为现在教授Java(以及其他编程语言)的方法很糟糕,学不到任何关于计算机本身的知识。如果你也觉得这种情况有点奇怪,那这本书就是你应该看的。
Java编程语言是20世纪90年代在一个美国计算机公司Sun Microsystems由James Gosling、Mike Sheridan和Patrick Naughton发明的。它在某种程度上模仿了那时流行的C语言。C语言没有对内存的自动管理功能,而且在那时内存管理错误是一个普遍存在的问题,让人头疼。Java从设计上消除了这类程序错误。它对程序员隐藏了底层内存管理。这就是Java对初学者友好的部分原因。但是要编写优秀程序,培养优秀程序员,需要的不仅仅是一种好的编程语言。事实证明,Java引入了一类新的很难调试的编程问题,包括隐藏内存管理系统导致的性能低下问题。
就像你在书里看到的,理解内存是程序员的一个重要技能。学习编程时养成的习惯很难改掉。研究表明,在所谓的“安全”操场玩耍长大的孩子更容易受伤,大概是因为他们不知道摔倒的伤害。在编程领域也存在类似的情况。舒适的编程环境使入门不那么恐怖,但你还是需要做好准备,以面对复杂的外部环境。本书可以帮你实现这种转变。
为什么好的程序很重要
想理解为什么不包括计算机教学的编程教育存在问题,首先需要考虑到计算机已经变得多么普遍。计算机降价如此显著,很多东西用计算机建造才最便宜。举个例子,用计算机在汽车仪表盘上显示一个老式的模拟时钟比使用真的机械钟花费得少得多。计算机芯片现在很便宜,用脚踩坏一个包含数十亿元件的芯片不再是什么大不了的事。注意,我是在说计算机本身的价格,不是那些包含了计算机的东西的价格。通常,计算机芯片的成本比它们的包装运输成本更少。未来很有可能很难找到什么东西不含计算机。
让很多计算机去处理大量事情意味着需要大量的计算机程序。计算机使用如此广泛,因而编程的应用领域广泛而多样。就像在医疗领域,许多程序员成了这方面的专家。你可以在视觉处理、卡通动画、网页、手机应用、工业控制、医疗设备等更多方面成为专家。
奇怪的是,计算机编程不同于医学,在编程领域,你不用全面了解就可以成为一个专家。你可能不想让一个没学过解剖学的医生给你做心脏外科手术,但是对如今的许多程序员来说,类似的问题已经成为常态。这真的是个问题吗?事实上,大量证据表明部分程序的运行效果并不是很好,每天都有关于安全漏洞和产品召回的报告。在一些法庭案件中,被判酒驾的人赢得了对酒精测试代码进行审查的权利。事实证明代码中充满了漏洞,这导致已定罪名被推翻。近日,发生了正在进行心脏外科手术的医疗器械因杀毒软件而崩溃的事故。还有因波音737 MAX飞机设计问题致使许多人丧生的事故。许多像这样的事故让人们对程序丧失了信任。
学习编程只是一个开始
出现这种情况的部分原因是,编写看起来可以工作的计算机程序,或者大部分时间都可以工作的计算机程序并没有那么困难。我们用20世纪80年代的音乐(非disco)变化来做个类比。以前人们必须打好基础才能创作音乐,这包括学习乐理、作曲,练习演奏乐器,听音练耳,以及其他很多练习。后来,乐器数字接口(MIDI)标准出现了,任何人都可以在没有多年勤学苦练基础的情况下通过计算机创作“音乐”。我觉得,只有很小比例的计算机生成音乐称得上音乐,其余大部分只是噪音而已。音乐是被真正的音乐家创作出来的,他们可能用MIDI,但无一不拥有深厚的音乐基础。如今,编程变得非常像使用MIDI创作“音乐”。写程序不再需要付出很多汗水,不再需要花费几年的时间去练习,甚至不再需要学习理论。但是这不代表这些程序优秀或者性能可靠。
这种情况越来越严重了,起码在美国是这样。拥有既得利益的富人们,比如那些拥有软件公司的人,一直在游说立法,要求每个人都要在学校里学习编程。理论上听着不错,但在实践中并不是个好主意,因为不是每个人都有成为好程序员的天赋。我们没有要求每个人都去学足球,因为我们清楚不是每个人都适合踢足球。这一倡议的目的可能不是培养出优秀的程序员,而是通过向市场大量输入不怎么样的程序员,压低工资水平,以增加软件公司的利润。幕后推手们不关心代码质量,甚至还推动立法以减轻他们对缺陷产品所负的责任。当然,就像可以踢球踢着玩一样,你也可以编程编着玩,就是别期待会被超级碗挑中了。
2014年,美国前总统奥巴马表示,他已经学会了编程。他确实在优秀的可视化编程工具Blockly中拖动了一些东西,甚至在JavaScript(一种与Java无关的编程语言,由维护了包括火狐浏览器在内的许多软件包的Mozilla Foundation的前身Netscape公司发明)中输入了一行代码。你觉得他真的学会了编程吗?给个提示:如果你认为他学会了,那么你应该在读本书的同时努力锻炼你的批判思维能力。当然,他是学了那么一点点有关程序的知识,但是,他没有学习编程。如果能在一小时之内学会编程,那就是说编程太小菜一碟了,根本不需要在校园里开课。
底层知识的重要性
Mathematica和Wolfram语言的创造者Stephen Wolfram在一篇题为“How to Teach Computational Thinking”的博客帖子中表达了一个有趣且有些相悖的观点:他把计算思维定义为“把事件标准化得足够清晰,人可以通过一个足够系统化的方法告诉计算机怎么运行”。我完全认同这个定义。事实上,很大程度上这也是我写这本书的动力。
但我非常不认同Wolfram的一个观点,即那些学习编程的人应该使用强大的高级工具(比如他开发的那些工具)来培养计算思维能力,而不是学习底层基础技术。例如,从人们对统计学的兴趣日益超过对微积分的兴趣这一趋势中,我们可以清楚地看到,“数据整理”是一个正在发展的领域。但是,如果人们只是将大量的数据输入这些并不熟悉的程序中,又会发生什么呢?
一种可能是,它们产生的结果看起来很有趣,但没有意义或者不正确。例如,最近的一项研究(Mark Ziemann、Yotam Eren和Assam El-Osta的“Gene Name Errors Are Widespread in the Scientific Literature”)显示,五分之一已发表的遗传学论文由于电子表格使用不当而出现错误。试想一下,如果有更多人使用更强大的工具,可能会产生怎样的错误和后果!当人们的生活受到影响时,正确处理好它才是至关重要的。
理解底层技术可以帮助你了解可能出现的问题。只知道高级工具很容易提出错误的问题。在学习钉枪之前,先学会使用锤子是值得的。学习底层系统和工具的另一个原因是,它能赋予你构建新工具的能力,这一点很重要,因为永远需要工具构建者,尽管工具用户更常见。学习有关计算机的知识使你能够编写更好的代码,程序的性能状态也就不再神秘了。
目标读者
本书是为想成为优秀程序员的人准备的。是什么成就了一个优秀的程序员?首先,一个优秀的程序员应该具备良好的批判性思维和分析能力。为了解决复杂的问题,程序员需要有能力评估程序是否能正确地解决恰当的问题。这比听起来要难得多。经常会见到有经验的程序员对别人写的程序冷嘲热讽:“将简单事情复杂化了,制造了不是问题的问题。”
你可能很熟悉一个经典的魔幻故事比喻:魔法师通过了解事物的真名来获得力量,如果忘了某个细节,魔法师就会遭殃。优秀的程序员就是那种能够牢牢把握住事物的本质,不放过任何一个细节的魔法师。
优秀的程序员也应该有一定的艺术修养,就像熟练的工匠一样。遇到让人完全无法理解的代码的情形并不少见,就像许多说英语的人对詹姆斯·乔伊斯(James Joyce)的小说《芬尼根的守灵夜》很困惑一样。优秀的程序员写出的代码不仅要能正常工作,而且要很容易让别人理解和维护。
最后,优秀的程序员需要对计算机的工作原理有深刻的理解。仅凭浅薄的知识基础无法很好地解决复杂问题。本书适合那些正在学习编程,但又对现有知识深度不满意的人。本书也适合已经在学习编程,但还想要学习更多的人。
计算机是什么
一个普遍的答案是,计算机是人们用来做诸如检查电子邮件、网上购物、写论文、整理照片以及玩游戏等任务的工具。消费类产品开始和计算机结合,是这个草率定义普遍存在的部分原因。另一个常见的答案是,计算机是能使高科技玩具(比如手机和音乐播放器)运作的大脑。这种说法更接近正确答案。
发送电子邮件和玩游戏都是通过计算机上运行的程序来实现的。计算机本身就像一个新生婴儿,它并不懂很多事情的做法。我们几乎不会去考虑人类的基础运转系统,因为我们主要与运行在这个基础系统上的人格进行互动,就像计算机上运行的程序一样。例如,当你浏览网页时,你不是只用这个计算机本身去阅读,而是通过在你的计算机上运行的别人编写的程序、承载网页的计算机、构成网络的所有计算机去阅读。
什么是计算机编程
教师是训练人的基础运转系统来完成某些任务的人。同理,编程就是让程序员成为计算机的老师,教计算机做程序员要它做的事情。
知道如何去教计算机是很有用的,特别是当你想让计算机做一些它不知道该怎么做的事情,而又买不到相关程序的时候。例如,你可能认为万维网的存在是理所当然的,但它不久前才被发明,当时Tim Berners-Lee爵士需要一个更好的方法让欧洲核子研究组织(Conseil Européen pour la Recherche Nucléaire,CERN)的科学家们分享信息。而他因此被封为了爵士。
教计算机学东西很复杂,但比教人学东西容易多了,毕竟我们对计算机的工作原理了解得更多。而且计算机不大可能学到吐,它没那么容易对学习厌烦。
计算机编程是一个两步骤的过程:
1. 理解宇宙。
2. 向三岁的孩子解释宇宙。
这是什么意思呢?你无法编写计算机程序去做一些你自己都不理解的事。比如,如果你不懂拼写规则,你就无法写出拼写检查程序;如果你不懂物理学,你就无法写出好的动作电子游戏。所以,要成为一名优秀的程序员,第一步就是要尽可能多地学习其他知识。解决问题的办法往往来自意想不到的地方,不要因为某件事看起来似乎没有直接的关系就忽略了它。
这个过程的第二步需要向计算机解释你所知道的东西。计算机对世界的看法非常僵化,就像小孩子一样,在三岁左右的时候,孩子的这种僵化看法真的很明显。比如,你们想出门,你问你的孩子:“你的鞋子在哪里?”孩子说:“这里。”她确实回答了你的问题。问题是,她不明白你是在要求她穿上鞋子,这样你俩就可以出门了。灵活性和推理能力是孩子们在成长过程中才会学习到的技能。但计算机就像小飞侠彼得·潘:它们永远不会长大。
计算机也像年幼的孩子,因为它们不知道如何归纳总结。但它们还是很有用处的,因为一旦你想好了怎么向它们解释一些东西,它们就会不厌其烦、快速地去做,尽管它们没有任何常识。计算机会不知疲倦地做你要求的事情,而不去评估那是否是错误的任务,这很像1940年的电影《幻想曲》中“魔法师的学徒”片段中的魔法扫帚。要求计算机做事,就像向魔法灯笼里的精灵(不是FBI版)许愿一样,你必须非常小心你的措辞!
你可能会怀疑我所说的,因为计算机似乎比它们本身更有能力。比如,当你使用计算机时,它知道如何画图、纠正你的拼写、理解你说的话、播放音乐等。但请记住,实现这些任务的不是计算机,而是人为编写的一套复杂的旨在让计算机完成这些任务的计算机程序。计算机与运行在计算机上的程序是分开的。
就像在路上看到的汽车一样,它似乎很擅长在适当的时候停车和启动,避开障碍物,到达目的地,没油了就加油,等等。但是,这不仅仅是汽车完成的,而是汽车和驾驶员结合在一起完成的。计算机就像汽车,程序就像驾驶员。如果没有知识,你就不能分辨出什么是汽车做的以及什么是驾驶员做的。(参见May Swenson的“Southbound on the Freeway”。在不同的人生阶段,你对诗末提出的问题的答案可能会不同。)
总而言之,为了解决问题,计算机编程涉及学习你需要知道的东西,然后再把它解释给小孩子。因为解决问题的方法有很多,所以编程既是一门艺术,也是一门科学。它涉及寻找优雅的解决方案,而不是使用蛮力解决。在墙上打一个洞的确能让你走出家门,但要想走出家门可能还有更容易的方法。很多人可以用几百万行代码写出像HealthCare.gov这样的东西,但要用几千行代码来完成,那是需要技巧的。
不过在指导三岁的孩子之前,你需要先了解三岁的孩子,了解他们的理解能力。而且计算机不是真的普通三岁小孩,而是一种“外星生命体”。计算机的游戏规则和我们不一样。你可能听说过人工智能(AI),它试图让计算机表现得更像人。该领域的进展比原先预计的要缓慢得多。这主要是因为我们并不是很清楚地了解这个问题,我们对人类的思维也不够了解。你可以想象,当我们自己都不知道到底该怎么做的时候,要教会外星人像我们一样去思考这件事有多难。
人的大脑在不自主的思维情况下,就能做一些事情。你的大脑一开始只是一块硬件,然后就好像被编程了。例如,你学会了移动手指,然后就学会了抓东西。经过练习,你就可以不经思索地抓住东西,而不需要思考其中的步骤。对于这个学习过程是如何运作的,哲学家让·皮亚杰(Jean Piaget,法国心理学家)和诺姆·乔姆斯基(Noam Chomsky,1928年出生的美国语言学家)等人提出了不同的理论。大脑是一个一般的设备,还是它有特殊的硬件来实现语言等功能?这个问题还在研究中。
我们不可思议的无意识执行任务的能力使学习编程变得困难,因为编程需要将任务分解成计算机能够遵循的更小步骤。比如,你可能知道如何玩井字棋游戏。找一群人一起玩,让每名玩家各自列出应该采取的步骤。在大家都列好之后,举行一场比赛。看看谁的规则好!你的规则有多好?你错过了什么?在玩游戏时,你真的知道你在做什么吗?很有可能有很多因素你都没想出来,因为你是在凭直觉理解它们。
你可能觉得第一步比第二步更重要,即了解宇宙比向三岁孩子解释宇宙更重要。想想看:如果你不知道说什么,那知道怎么说又有什么用呢?尽管如此,目前的教育还是把重点放在了第二步。这是因为与创造性内容相比,机械原理方面的教学和打分要容易得多。而且一般情况下,教师在这方面的训练很少,都是按照别处开发的课程来进行教学。而本书则侧重第一步。虽然它不能涵盖整个宇宙,但它检查了计算机领域的问题和解决方法,而不是纠缠于实现这些解决方法需要的具体编程语法。
编码、编程、工程和计算机科学
有许多描述软件工作的术语,虽然这些术语有一些粗略的定义,但并没有确切的定义。
编码是最近相当流行的一个术语,作为“学习编码”的一部分,可以看作有点机械的翻译工作。我们把它代入医疗编码的工作中。当你去看医生时,很容易得到诊断。难的是将诊断翻译成ICD标准(在编写本书时为ICD-10)中的10万多个编码之一。学过这些编码的注册专业编码员知道,当医生提出“被牛撞了”的诊断时,应该将其分配为W55.2XA编码。这其实比编程领域中的很多编码工作都要难,因为编码的绝对数量非常大。但是,这个过程类似于指示编码员在网页上“加粗文字”,编码员知道用什么编码来完成这件事。
ICD-10标准非常复杂,以至于很少有编码员知道它的全部内容。因此,医疗编码员均在某个专业领域,如“神经系统疾病”或“精神和行为障碍”获得认证。这类似于程序员精通一门语言,比如HTML或JavaScript。
编程,也就是做一名程序员,意味着要了解的不仅仅是一两个专业领域。在这种情况下,医生就类似于程序员。医生通过对病人进行评估来诊断。这可能会相当复杂。比如,如果病人烧伤,而且浑身湿透,是“怪异的个人外观”(R46.1)还是“滑水板着火所致的烧伤,首例”(V91.07XA)?医生有了诊断,就可以制定出治疗方案。治疗方案必须是有效的:医生大概不希望看到同样的病人因为“父母的过度保护”(Z62.1)而痛苦不堪。
就像医生一样,程序员也会对问题进行评估并确定一个解决方案。例如,也许有必要建立一个网站,允许人们把ICD-10代码按质量高低进行排序。构建网站时,程序员会确定存储和处理数据的最佳算法,网络客户端和服务器之间的通信结构,用户界面,等等。这不是一个简单的“插上代码”之类的东西。
工程的复杂度进一步提升。总的来说,工程是一门利用知识完成某些事情的艺术。你可以把ICD标准的创建视为工程,它把庞大的医学诊断领域缩减为一组比医生笔记更容易跟踪和分析的编码。这样一个复杂的系统是否代表着好的工程,这是个见仁见智的问题。举个计算机工程的例子,很多年前,我参与过一个项目,建造一个低成本的医疗监护仪,比如你们在医院里看到的那些仪器。我的任务是制作一个系统,让医生或护士可以在5分钟内知道如何使用,而不需要任何文件说明。正如你可能想象的那样,这不仅仅需要编程知识。我的目标实现了,解决方案最终只需大约30秒就能学会使用。
编程常常与计算机科学混为一谈。虽然很多计算机科学家都会编程,但大多数程序员并不是计算机科学家。计算机科学是研究计算的学科。计算机科学的研究成果被工程师和程序员所使用。
编码、编程、工程和计算机科学是相互独立但又相互关联的学科,它们所需的知识类型和数量不同。做一名计算机科学家、工程师或编码员并不会自动成为一名优秀的程序员。虽然这本书能让你了解到工程师和计算机科学家的思维方式,但它并不能让你跻身其中,跻身其中通常还需要获得大学教育和一些通过勤奋得来的相关经验。工程和编程类似于音乐或绘画,它们既是技能,也是艺术。本书里这两方面的论述应该能帮助你提高程序员的技能。
计算机全景图
计算机设计和编程是一个巨大的学术领域,这里就不再赘述了。你可以像图1展示的那样分层想象计算机的结构。
图1 计算机全景图
请记住,图1是简化后的结果,在实际中,各层之间界限并没有这么清晰明显。
大多数人都是计算机系统的用户。你现在可能就属于这个阵营。有一类专门的特殊用户叫作系统管理员,他们的工作是保持计算机系统正常工作。他们需要安装软件,管理用户账户,做备份等。他们通常拥有普通用户没有的特殊权力。
编写网页、手机应用程序、音乐播放器等程序的人被称为应用程序程序员。他们使用其他人创建的块来编写软件,让用户通过这些软件与计算机交互。在大多数的“学习编程”课程中,应用程序设计中被认为需要程序员掌握的就是如何导入这些块并将其黏合在一起。虽然很多时候你都可以这样做,但能真正理解这些块和“胶水”会更好。
应用程序不会直接与计算机硬件交流,这就需要系统程序设计来处理。系统程序员做的是构建应用程序程序员要使用的块。系统程序员需要了解硬件,因为他们的代码需要与硬件进行交互。本书的目标之一就是教你成为优秀的系统程序员需要知道的东西。
计算机硬件不仅包括进行实际计算的部分,还包括该计算部分与外部的连接方式。计算机硬件是用逻辑表示的,该逻辑和编写计算机程序的逻辑是一样的,也是理解计算机工作原理的关键。逻辑在物质上的实现是各种电子电路。电路设计不在本书讨论的范围内,你可以通过学习电气工程专业来了解更多的电路设计知识。如果你想征服世界,可以考虑修电气工程和计算机科学的双学位!
当然,支撑着这一切的是基础科学,它们提供从我们对电学的理解到创造芯片所需的化学知识等各种知识。
如图1所示,每一层都是在其下面一层上建立起来的。这意味着下层的不佳设计选择或错误会影响到上面的所有层。例如,大约在1994年,Intel Pentium处理器中的一个设计错误导致一些除法运算产生了不正确的结果,影响了所有在这些处理器中使用浮点除法的软件。
正如你所看到的,系统程序设计处于软件结构层的底层。它类似于基础设施,如公路、电力和水。能不能成为一个优秀的程序员总是很重要,但如果你是系统程序员,那就更重要了,因为其他人都依赖你的基础设施。你也可以看到,系统程序设计夹在应用程序设计和计算机硬件之间,这意味着你需要学习这两方面的知识。梵语yoga的意思是“联合”,就像瑜伽修行者追求身心合一一样,系统程序员也是技术型的瑜伽师,他们需要将硬件和软件结合统一起来。
你不一定要学会系统程序设计,才能从事其他层上的工作。如果你不懂,你可以找别人帮你处理超出你擅长的领域的问题,不要自己想办法。当然对核心技术的理解会让你在更高的层上给出更好的解决方案。这不只是我的观点,2014年Ville-Matias Heikkilä的博客文章“The Resource Leak Bug of Our Civilization”中也有类似的观点。
本书的目的是涵盖大量的历史知识。因为有太多内容要学习,所以大多数程序员并没有时间或精力去学习关于技术的发展史。结果就是很多人还在犯别人曾经犯过的错误。知道一些历史,至少可以让你只犯些新的有意义的错误,而不是重复过去的错误。牢记,你今天使用的热门新技术很快就会变成明天的历史。
说到历史,本书不仅给出了很多有趣的技术,还介绍了其发明者。建议大家花点时间去了解一下这些技术和人物。本书中提到的大多数人都至少解决了一个有趣的问题,他们如何看待自己的世界,以及他们对待问题和解决问题的方式,都是值得学习的。Neal Stephenson 2008年出版的小说Anathem中有一段很精彩的对话:
“我们的对手是一艘装满原子弹的外星飞船。我们有一个量角器。”
“好吧,我回家看看能不能找一把尺子和一根绳子。”
要注意对基本面的依赖。这不是“让我们在维基百科上查一下该怎么做”,也不是“我在Stack Overflow上发个问题”或者“我在GitHub上找一些项目包”。学会解决别人没有解决过的问题是一个重要的技能。
本书中的许多例子都是基于旧技术的,比如16位计算机。这是因为你可以从它们身上学到几乎所有你需要知道的东西,而且它们更容易在纸上表达。
本书涵盖内容
本书在概念上分为三个部分。第一部分探讨计算机硬件,包括它是什么以及它是如何构建的。第二部分研究在硬件上运行的软件的行为和表现。最后一部分介绍编程的艺术——与他人合作写出好的程序。
第1章:计算机的内部语言
本章将开始探索计算机这个三岁小孩的心态。计算机是比特大玩家,它们靠“放牧”比特为生。本章将具体介绍它们是什么,可以用它们做什么,用像“过家家”一样的假想游戏来赋予比特和比特集合意义。
第2章:组合逻辑
本章将研究使用比特而不是数字的原理,并探讨数字计算机的合理性,还将讨论一些为我们现在的数字计算机出现铺平道路的旧技术。本章涵盖组合逻辑的基础知识,并介绍如何从位和逻辑实现更复杂的功能。
第3章:时序逻辑
本章将介绍如何使用逻辑构建内存,包括如何生成时间,因为内存只不过是一种随时间而存在的状态。本章涵盖时序逻辑的基础知识,并讨论各种存储器技术。
第4章:计算机剖析
本章将介绍计算机如何由前面几章讨论的逻辑和内存元素构造出来,并介绍一些不同的实现方法。
第5章:计算机架构
本章将探讨我们在第4章中看到的计算机的基础附加组件,介绍它们如何提供基本功能并提高效率。
第6章:通信故障
计算机需要与外部世界进行交互。本章将介绍输入和输出,回顾数字量和模拟量的区别,以及如何让数字计算机在模拟世界中工作。
第7章:组织数据
了解了计算机的工作原理后,我们来看看如何高效地使用它们。计算机程序对内存中的数据进行操作,重要的是将内存的使用方式映射到需要解决的问题上。
第8章:语言处理
编程语言的发明是为了让人们更容易地在计算机上写出程序。本章着眼于将语言转换成在计算机上实际运行的程序的过程。
第9章:Web浏览器
很多程序都是为Web浏览器写的。本章主要介绍Web浏览器的工作原理以及它的主要组件。
第10章:应用程序和系统程序设计
本章将编写一个程序的两个版本,分别在图1中的两个不同的层上运行。
第11章:捷径和近似法
提高程序的效率很重要。本章将探讨一些通过省去不必要的工作来让程序更有效率的方法。
第12章:死锁和竞态条件
许多系统包含不止一个计算机。本章将研究让计算机相互合作时可能会出现的一些问题。
第13章:安全性
计算机安全是一个先进主题。本章在讲解基础知识的同时,还会着重讲解难消化的数学知识。
第14章:机器智能
机器智能也是一个先进主题。大数据、人工智能和机器学习的结合带来全新的应用——从自动驾驶到把你逼疯的广告。
第15章:现实世界的考虑
编程是一个非常有条理的过程,逻辑性很强。人类会参与决定编什么、如何编程,而人类往往缺乏逻辑性。本章将讨论现实世界中关于编程的一些问题。
在阅读本书时,请记住,很多解释都是已简化的,因此细究细节可能不完全正确。要解释得完美,就需要太多分散注意力的细节。如果你在深入学习的过程中发现了这一点,请不要惊讶。你可以把这本书看成是一本可以让你在计算机的太虚世界里神奇遨游的光鲜亮丽的旅行手册。本书不可能涵盖所有的细节,当你深入阅读时,就会发现很多细微的差别。