全书7
我现在正在使用着的一台2015年的计算机中的英特尔处理器就在单块集成电路芯片上集成有两个内核,而在一块芯片上集成越来越多的处理器内核,并且一台计算机上拥有多个芯片已经成为明显的趋势。随着集成电路特征尺寸变得越来越小,可以在一个芯片上封装更多的晶体管,而这些晶体管往往被用于更多的内核和更多的缓存存储器。单个处理器的速度并没有提高,但由于内核的增加,有效计算速度仍在不断提高。 笔记本电脑要求的权衡要素有了明显不同,因为空间紧张,并且在不插电源的情况下,笔记本要靠沉重又昂贵的电池供电。其他条件一样的情况下,笔记本处理器必然要相对慢一些,耗电少一些。 手机、平板以及其他高轻便设备进一步提高了设计要求,因为尺寸、重量和电源各方面都有了更多限制。在这些应用领域,单靠小范围调整设计是行不通的。虽然英特尔以及它的主要竞争者AMD是台式机和笔记本处理器的主要供应商,但大部分的手机都使用称为“ARM”的处理器设计,这是专为低功耗设计的。ARM处理器的设计是由英国的Arm Holding公司授权的。 同样是计算两个数的和并保存结果,其中一个处理器需要用三条指令,如同我们的玩具计算机。另一个处理器则可能需要两条指令,而第三个处理器可能只需要一条指令来进行同样的计算。有的处理器也许可以并行处理多条指令,或者重叠执行多条指令,从而让这些指令在不同阶段上执行。为了降低耗电量,处理器可以牺牲执行速度,甚至根据是不是电池供电动态调整速度。有些处理器有一些快的内核和一些慢的内核,分别被分配不同的任务。对于某个处理器比另一个处理器“快”的说法,你应该谨慎对待;很多情况下都要具体问题具体分析。 “因此,我们被迫认识到可能要构建一个层次性的存储,每一个都比前一个有更大的容量,但访问速度更慢。 在处理器中,缓存是一种容量小但速度快的存储器,用于存储最近使用的信息,以避免访问容量大但是慢很多的主存。通常,处理器会在短时间内连续多次访问某些数据和指令。 循环的5条指令,对每个输入值都要执行一遍。如果这些指令存储在缓存中,就不用在每次循环时都从主存中读取它们,这会让程序的速度快许多,因为处理器无需等待内存以产生指令。类似地,把Sum存储在数据缓存中也能提高访问速度,尽管这个程序的真正瓶颈在于获取数据。 典型的处理器有两到三个缓存,容量依次增大,但速度递减,一般称为一级缓存(L1)、二级缓(L2)和三级缓存(L3);最大的缓存能存储以兆字节计的数据(我的笔记本电脑每个内核有256KB的L2缓存,以及4MB的单个L3缓存)。缓存之所以很有用,是因为最近使用过的信息很可能很快被用到——而把它们存储在缓存里就意味着减少对内存的等待时间。缓存通常会一次性加载一组信息块,比如当只请求一个字节时,也会加载内存中一段连续的地址。这是因为相邻的信息也可能很快被用到,这样需要它们的时候就已经在缓存里了;换句话说,对邻近信息的引用也不需要等待。 ,只要你现在用到的东西不久还会用到,或者可能会用到与之邻近的东西,那缓存思维就会很有帮助。处理器中的多个累加器本质上也是一种缓存,只不过是高速缓存而已。内存也可以视为磁盘的缓存,而内存和磁盘又都可以视为网络数据的缓存。计算机网络经常会利用缓存加速访问来自远程服务器的信息流,而服务器本身也有缓存。 在使用浏览器上网的时候,你可能见过“清空缓存”的字眼。对于网页上的图片和其他相对较大的资源,浏览器会在本地保存一份副本,因为再次访问同一网页时,使用本地副本比重新下载速度快。缓存不能无限地增长,因此浏览器会悄悄地删除旧条目,以腾出空间给新的条目,并且也给你提供了删除所有缓存内容的方式。 ,打开Word或Firefox等大程序,看看从启动到加载完成并可以使用要花多长时间。然后退出程序,立即重新启动它。通常情况下,第二次启动的速度会明显加快,因为程序的指令还在内存里,而内存正充当磁盘的缓存。当你使用其他程序一段时间后,内存会被这些程序的指令和数据填满。原先的程序将不会再被缓存。 Word或Excel等程序中最近使用的文件列表也是缓存的一种形式。Word会记住你最近使用过的文件,并将其名称显示在菜单上,这样你就不必通过搜索来找到它们。当你打开更多的文件时,那些有一段时间没有被访问的文件的名称将被最近访问的文件名所取代。 手机和平板电脑也是计算机,它们运行操作系统并支持更加丰富的计算环境。更小的系统嵌入到日常生活里能见到的几乎所有数字设备里,包括数码相机、电子书阅读器、健身追踪器、摄像机、家电、游戏机,等等。所谓的“物联网”——联网恒温器、安全摄像头、智能灯、语音识别器等——也依赖于这种处理器。 超级计算机往往有很多数目的处理器和大量的内存,这些处理器本身可能带有一些特殊指令,在处理某种数据时比通用的处理器速度更快。今天的超级计算机通常是高速计算机集群,但仍然使用普通的处理器,并没有什么特殊的硬件。网站top500.org每六个月就重新公布一次全世界最快的500台计算机。最快速度的纪录不断被打破,几年前还能跻身排行榜前几名的计算机,今天可能已经在榜单上找不到了 。2020年11月由日本富士通建造的最快的计算机有760万个内核,每秒可以执行537×1015次数学运算。超级计算机的速度是由每秒可以进行的浮点运算的次数,或者称为flops,来衡量的,也就是它们每秒可以对带有小数部分的数字进行的算术运算次数。因此,top500.org列表的第一名是537 petaflops,第500名是2.4 petaflops。 图形处理单元(Graphics Processing Unit, GPU)是一种特殊的处理器,它执行某些图形计算的速度要比通用CPU快得多。GPU最初是为游戏所需的高速图形计算而开发的,也用于手机中的语音和信号处理。GPU还可以帮助普通处理器加速处理某些类型的工作负载。 矿工挖币,显卡越多越可以快速找到随机数从而把交易记录打包传到区块链上。 GPU可以并行处理大量的简单计算,因此,如果计算任务的某些部分涉及可以并行完成的操作,并且可以交给GPU,那么整个计算可以更快地进行。GPU对于一些机器学习(第12章)特别有用,在这些机器学习任务中,针对一个大数据集的不同部分的相同计算是独立完成的。 分布式计算是指很多更加独立的计算机——它们不共享内存,比如,它们在地理上更加分散,甚至位于世界的不同地方。这样一来,通信更加成为瓶颈,但却能够实现人们以及计算机之间的远距离协作。大规模的Web服务——搜索引擎、在线商店,社交网络,以及云计算——都是分布式计算系统。在这种系统中,数以千计的计算机协作,可以为海量用户迅速地提供结果。 。写一个模拟通用图灵机的程序很容易,写一个程序让通用图灵机模拟真实的计算机也是可能的(尽管不容易)。因此,从能够做什么计算任务的角度上讲,所有计算机都是等价的,尽管运行速度上明显不同。 1950年,图灵发表了一篇名为“计算机器与智能”(Computing Machinery and Intelligence)的论文,其中提出一个测试(即今天所谓的图灵测试),人们可以通过该测试来评估计算机是否能表现出人类的智能。设想一台计算机和一个人分别通过键盘和显示器,与另一个提问者交流。通过问答,提问者能确定哪个是人,哪个是计算机吗?图灵的想法是,如果不能可靠地将二者区分开,那么计算机就表现出了智能的行为。正如我们将在第12章中看到的那样,计算机现在在某些领域的表现已经达到或超过了人类的水平,尽管在总体智能方面肯定没有达到。 缩写词CAPTCHA(验证码)中包含图灵的名字,这个缩写词代表“Completely Automated Public Turing test to tell Computers and Humans Apart”(用以区分计算机和人的完全自动化的公共图灵测试)。CAPTCHA就是如图3.10所示的一些扭曲变形的字母,广泛用于验证网站的用户是人而非程序。CAPTCHA是一个反向图灵测试的示例,因为它利用了人比计算机更擅长识别文字这一事实,来达到区分人和计算机的目的。当然,验证码对于任何有视力障碍的人来说都是不适用的。 计算机科学领域的诺贝尔奖——图灵奖,就以图灵的名字命名以对其致敬 计算机是一种通用的机器。它从内存中读取指令,而把不同的指令放到内存中就可以改变它执行的计算。要通过使用场景区分指令和数据,一个人的指令可以是另一个人的数据。 现代计算机的芯片上几乎都有多个内核,也可能有多个处理器芯片,并且在集成电路上有大量的缓存,以使内存访问更有效。缓存本身是计算的一个基本概念,从处理器到互联网的组织方式,所有层次都用到了这个概念。在大多数情况下,它总是利用时间或空间的局部性来获得更快的访问速度。定义一台计算机的指令集架构方式很多。这涉及速度、耗电和指令本身的执行难度等因素之间的复杂权衡,这些细节对硬件设计师来说至关重要,但对大多数编程人员来说就不那么重要了,而对那些仅仅在某些设备上使用它们的人来说就根本不重要了。 事实上,任何计算机都可以通过编程来模拟其他计算机,图灵就是这样证明他的结果的。 处理器可以快速执行简单的指令,根据之前计算的结果和外界的输入来决定下一步要做什么。内存包含数据和决定如何处理数据的指令。 计算机的逻辑结构自20世纪40年代末之后并没有太大改变,但物理结构已经发生了巨大变化。摩尔定律已经应验了50多年,成为迄今为止几乎完全应验的预言。摩尔定律预言了在既定的空间和成本之下,单个组件的大小和价格呈指数级下降,而它们的计算能力呈指数级增长。几十年来,关于摩尔定律将如何终结的警告一直是科技预测的主要内容。很明显,当前的集成电路技术遇到了麻烦,因为设备的尺寸已经到了只有几个原子的大小,但人们已经多次证明了自己的创造力,也许会有新发明能让我们继续行进在既定轨道上。 。任何种类的信息都表示为比特的集合。各种类型的数字(整数、分数、科学记数法)都可以表示为1、2、4或8字节,这些是计算机硬件中可以自然处理的信息大小。这意味着在一般情况下,数字的大小和精度都是有限的。有了合适的软件,就可以支持任意大小和任意精度,不过使用这种软件的程序会运行得更慢。像自然语言中的字符这样的信息也表示为一些字节。ASCII适用于英语,每个字符使用一个字节。而Unicode的适用性较广,它具有几种编码,可以处理所有字符集,但需要使用更多的空间。UTF-8编码是一种可变长度的Unicode编码,用于在系统之间交换信息,它对于ASCII字符使用一个字节,对其他字符则使用两个或更多字节。 类似于度量这样的模拟信息被转换成数字形式,然后再转换回来。音乐、图片、电影和类似类型的信息通过特定形式的一系列采样转换成数字形式,然后再转换回来供人们使用。在这种情况下会有一些信息的丢失,我们可以利用丢失信息进行压缩。 所有一切最终都要化简为比特,单独或成组地以数字形式表示信息。这些比特的含义取决于它们的上下文。我们可以化简为比特的任何事物,都可以通过数字计算机来表示和处理。但是请记住,还是有太多太多的事物我们不知道怎么用比特来表示,更不必说怎么用计算机来处理了。这些大多数是日常生活中最重要的一些事物:创造力、真理、美、爱、荣誉和价值。我想在一定的时期内,这些事物仍将超出计算机的能力之外。你应该怀疑那些声称知道如何“用电脑”处理此类问题的人。 应用程序”是一种统称,表示以操作系统作为平台完成某种任务的各种程序或软件系统。应用程序可大可小,可以只完成特定的任务,也可以囊括大量功能。可以是购买的,也可以是免费送的。它的代码可以高度保密,也可以开放源码,甚至没有任何限制。 作为一个简单应用程序的例子,考虑一个名为date的UNIX程序,它打印当前日期和时间 date程序在所有类Unix系统中的行为完全一样。包括macOS并且Windows中也是类似的。date的实现代码很少,因为它构建在一个系统调用(time)之上,该调用以内部格式提供当前日期和时间,以及调用了格式化日期(ctime)和打印文本(printf)的库。以下就是实现它的C代码,这样你可以看到它有多短: UNIX系统有一个列出目录中文件和文件夹的程序称为ls,它是Windows资源管理器和macOS Finder的纯文本版。对文件执行复制、移动、重命名等操作的程序,在Finder和资源管理器中也都有对应的图形用户界面版。同样,这些程序也使用系统调用来提供文件夹包含内容的基本信息,也依赖于库函数去读、写、格式化和显示信息。 Word之类的应用程序比探索文件系统的程序要大得多。但很明显,Word一定包含某种类似的文件系统程序,以便用户能够在文件系统中打开文件、读取文件内容和保存文档。Word也包含复杂的算法,随着文本变化持续更新显示界面的算法就是一例。它还提供精心设计的用户界面,用于显示信息和让用户调整字号、字体、颜色、布局等。这可能是程序的主要部分。随着新特性的添加,Word以及其他具有巨大商业价值的大型程序都经历了不断改进。我不知道Word有多少行源代码,但要说它有1000万行C、C++和其他语言的代码,特别是包含针对Windows、Mac、手机和浏览器的版本,应该一点都不奇怪。 浏览器必须处理异步事件。所谓异步事件,就是在非预测时间发生、没有特定次序的事件。举个例子,你点击一个链接,浏览器就会发送一个对相应页面的请求。但发送完请求后,但它不能只是等待回复。它还得准备响应你的其他操作,比如滚动当前页面,或者在你点击“后退”按钮或另外一个链接时中断之前的请求,不管请求的页面是否已经到达。在你调整窗口大小时,它必须不断更新窗口中的内容,可能是在数据到达时你正来回调整窗口大小,它必须持续更新。如果页面中包含音频和视频,那它还要负责管理它们。编写异步系统一直是非常困难的,而浏览器就必须处理很多异步操作。 浏览器必须支持很多种内容,从静态文本到具有交互性的程序,这些程序可以动态改变网页中包含的内容。对某些内容的支持可以委托给辅助程序,这是处理PDF文档和电影的标准做法,但浏览器必须提供启动这些辅助程序的机制,为它们发送和接收数据和请求,并将它们集成到显示中。 浏览器必须管理多个标签页或窗口,每个标签页和窗口都可能需要执行前述操作。它要为每个标签页和窗口单独保留一份历史记录,还要保存书签、收藏夹等数据。它要支持访问本地文件系统,以便上传和下载,以及缓存图像。 浏览器自身还是一个平台,提供不同层次的扩展:比如,要支持QuickTime插件、运行JavaScript的虚拟机,以及诸如Adblock Plus和Ghostery的扩展程序。在底层,它必须在多个操作系统的多个版本上工作,包括移动设备。 没错,现在的浏览器非常类似操作系统。它要管理资源,控制和协调同时发生的活动,它存储和检索来自多个源的信息,并提供一个可以运行应用程序的平台。 Telnet并不提供安全措施。如果远程系统能接受没有口令的登录,那就不需要口令。如果远程系统向客户端要口令,Telnet会以明文形式将客户端的口令发送过去。因此,任何监视数据流的人都能看到口令。现在,除了不讲究安全的场合,Telnet已经很少用了,原因之一就是它毫无安全性可言。而Telnet的继任者SSH(Secure Shell)则因为双向加密了全部通信而得到广泛使用,可以用来安全地交换信息。SSH使用22端口 第二个协议是简单邮件传输协议(SMTP, Simple Mail Transfer Protocol)。我们通常使用浏览器或者独立程序来收发邮件。但就像互联网上的诸多其他应用一样,表面的应用之下还有若干层,每层都靠各自的程序和协议来支撑。邮件程序的运行涉及两种基本类型的协议。SMTP用来在不同系统之间交换邮件。它首先建立一条连接到收件人的邮件服务器25端口的TCP/IP连接,使用SMTP协议标识发件人和收件人,然后传送邮件内容。SMTP是基于文本的协议;你可以用Telnet连接25端口来运行,并观察其是如何工作的。不过,SMTP做了足够多的安全限制,因而即使把你自己的计算机当成邮件服务器进行本地操作,也会遇到麻烦。图9.8中显示了与本机系统的实际会话过程(为排版紧凑而略做编辑),其中我给自己发了一封邮件,看上去像是别人发的(实际上就是垃圾邮件)。我的输入使用粗斜体标识。 由于SMTP要求邮件消息是ASCII文本。MIME标准(多用途互联网邮件扩展,Multipurpose Internet Mail Extensions,实际上它是另一个协议了)规定如何把其他类型的数据转换成文本,以及如何把多块数据拼成一条邮件消息。当需要在邮件里附上照片、视频等附件时,就要用到MIME机制,在HTTP中也使用了它 虽然SMTP是一种端到端协议,但它的TCP/IP包从源节点到目的节点常常要经过15到20跳网关。这就意味着,沿途中的任何网关完全可能检查经过的数据包并复制下来以从容不迫地审查。而且,SMTP本身也可以复制邮件内容,邮件系统会跟踪内容和头部的传送。因此,如果不想让发送的邮件内容被别人看到,一定要从发送方就要进行加密。但有一点要记住,加密邮件内容并不会隐藏发件人和收件人的身份。流量分析能揭示是谁在与谁通信;这些元数据通常可以提供与实际内容一样重要的信息 SMTP只是将邮件从源主机传送到目的邮件服务器,然后就不管用户如何访问邮件了。一旦邮件到达目的邮件服务器,它就原地等待直到收件人取走。通常收邮件由互联网邮件访问协议(Internet Message Access Protocol, IMAP)来处理。根据IMAP协议,你的邮件保存在服务器上,你可以从好几个地方访问它。IMAP能确保即使邮箱有多个阅读者和访问者在更新使用(同时从浏览器和手机处理邮件),你的邮箱始终处于一致状态。不需要对消息进行多重复制,也不需要在计算机之间复制它们。 像Gmail和Outlook这样的“云端”邮件系统也很常见。这些系统底层也是通过SMTP传输邮件,客户端也像IMAP那样访问邮件 1999年6月,美国东北大学一年级新生肖恩·范宁(Shawn Fanning)发布了Napster,一个能让大家轻而易举地共享MP3压缩格式音乐的程序。范宁的事做得可谓恰逢其时。那时的流行音乐CD虽然到处可见,但价格昂贵。个人计算机的运算速度足以对MP3格式进行编码速度和解码,编解码算法随处可得,网络带宽也足够高,MP3格式的歌曲可以在网络上传输得相当快,使用大学里的宿舍网络就更不用说了。由于范宁的设计和实现做得很棒,Napster如野火般扩散开来。1999年中期,他组建了一家公司来经营这项服务,据称最火的时候有8000万用户。但1999年晚些时候,Napster就遭遇了第一起诉讼,被指控大范围偷窃受版权保护的音乐。2001年中期,法院判决Napster关闭其业务。两年时间,从白手起家,到8000万用户,再到一无所有,这正是后来的流行语“互联网时代”的生动写照。 当用户选择了某个共享者时,Naspter就为双方建立联系(有点像提供约会服务):提供IP地址和端口号,让用户计算机上的客户端程序直接与提供者的机器联系并检索文件。供需双方都把状态报告给Napster,但中心服务器并“不参与”文件共享的过程,因为它们从不接触音乐文件本身。 我们已经习惯了客户机-服务器模型,比如浏览器(客户机)从网站(服务器)请求页面。Napster向我们展示了另外一种模型。它提供了一个中心目录,列出了现在可共享的音乐,但音乐文件本身还是存储在我们自己的计算机上;当文件传输时,文件直接从一个Naspter用户传到另一个用户,并不经过中心系统。这样的组织方式就叫点对点,共享者就是其中的对等点(peer)。因为音乐文件本身只存在于对等点计算机上,从来不在中心服务器上,所以Napster希望据此规避版权问题,但这些细节并没有得到法院的认可。 Napster协议使用了TCP/IP,所以它实际上和HTTP、SMTP是同一层的协议。Napster是个简单的系统,范宁的成功是因为在互联网基础设施、TCP/IP、MP3和构建图形用户界面的工具这些条件都具备的情况下,做了恰逢其时的事情。这并没有贬低范宁工作的意思,因为Napster确实很巧妙 目前大多数文件共享,无论合法与否,都使用一种叫作BitTorrent的点对点协议,它是由Bram Cohen在2001年开发的。BitTorrent对于分享电影和电视节目等较大的热门文件特别有效,因为每个开始使用BitTorrent下载文件的网站,也必须开始上传文件的片段给其他想要下载的网站。文件可以通过搜索分布式目录找到,用一个小的“torrent文件”来识别一个追踪器,这个追踪器维护着谁发送和接收了哪些块的记录。BitTorrent用户很容易被检测到,因为协议要求下载者也上传,因此他们很容易在受版权保护的材料的行为中被发现。 点对点网络除了合法性存疑的文件共享之外,还可以有其他用途。比如比特币也使用点对点协议,这是一种数字货币和支付系统, 娱乐产业通过美国唱片业协会(Recording Industry Asso ciation of America, RIAA)、美国电影协会(Motion Picture Association of America, MPAA)等商业组织对共享有版权资料的行为积极追讨法律赔偿。他们的行为包括指认了众多所谓的侵权者,提出诉讼或威胁要诉诸公堂,并且积极地四处游说,试图通过立法来界定共享行为的非法性质。盗版可能会一直存在,但合理付费后向民众分发高品质音乐的做法,商家可以大大减少盗版的影响,同时还能赚钱。苹果的iTunes音乐商店就是一个很好的例子,Netflix和Spotify等流媒体服务也可以作为范例。 在美国,有关数字版权问题的最主要法律是1998年的《数字千年版权法案》(Digital Millennium Copyright Act, DMCA)。法案规定,包括在互联网上散发有版权的资料在内,任何规避数字媒体版权保护技术的行为都是违法的。其他国家也有类似法律。DMCA是娱乐业用来追究侵犯版权者的法律机制。 DMCA为互联网服务供应商提供了一条“避风港”条款:如果版权持有人通知ISP其用户在散发侵权资料,ISP因此要求侵权人删除版权资料,ISP自身则不需要对侵权行为负责。避风港条款在大学校园网里很重要,在这里大学就是学校师生的ISP。因此每所大学都有一间处理侵权举报的办公室 根据DMCA投诉很容易。我给Scribd(在线文档分享网站)发了一封关于非法上传这本书第一版副本的邮件,他们在24小时内就把它删除了。不幸的是,大多数书籍的大多数非法拷贝基本上是不可能删除的。 许多小型工具和设备都包含强大的处理器、内存,通常还包含无线网络连接。将这些设备连接到互联网的设想是很自然的,而且这也很容易做到,因为所有必要的机制都已经就绪,额外添加的成本接近于零。因此,我们看到了可以通过Wi-Fi或蓝牙上传图片的摄像头,在上传引擎遥测数据和地理位置的同时下载娱乐节目的汽车,能测量和控制环境并向不在家的房主报告的恒温器,用于监控孩子、保姆和按门铃的人的视频监视器,像Alexa这样的智能语音系统,以及上面提到的联网灯泡,所有这些都是基于互联网连接的。表示以上这些事物的流行术语是物联网(Internet of Things),或简称为IOT 黑客攻击、非法入侵、破坏等等都很可能发生,而且事实上发生的机率更大,因为我们对物联网安全和隐私的关注远远落后于个人电脑和手机的技术水平。数量惊人的设备正在“打电话回家”,即将信息发送回制造它们的国家的服务器。 一些儿童玩具可以连上互联网,这就带来了另一种潜在的危害。一项研究表明,一些玩具包含了分析代码,可以用来跟踪儿童,以及包含一些不安全机制用于允许将玩具作为攻击的载体。(其中一个玩具是一个可以联网的水瓶,显然是用来监测水合作用的。)这种潜在的追踪行为违反了《儿童在线隐私保护法》(COPPA),也违反了玩具的隐私政策。 在2019年底,一名黑客发布了50万份物联网设备的IP地址和Telnet密码,他是通过扫描端口22上有响应的设备,然后尝试“admin”和“guest”等默认账户和密码,从而发现这些有漏洞的设备的。 电力、通信、交通和许多其他的基础设施系统已经连接到互联网,但没有对保护它们给予足够的重视。举个例子,2015年12月有报道称,某家制造商的风力涡轮机有一个支持网络的管理界面,可以轻易地攻击(只需编辑URL)网络界面,就可以关闭它们正在产生的电力。 这些协议的共同之处在于,它们在计算机程序之间传送信息,利用互联网作为一个哑网络,高效地将字节从一台计算机复制到另一台计算机,而不试图解释或处理它们。这是互联网的一个重要属性:说它是“哑”的,是因为它不理会数据。不使用“哑”这样的贬义词汇的说法是“端到端”原则:智能位于终端,也就是发送和接收数据的程序。这与传统电话网络形成了鲜明对比,在传统电话网络中,所有的智能都在网络中,而终端,比如老式电话,都是真正的哑巴,基本只负责连接网络和传递语音。 “哑网络”模式一直具有很高的生产力,因为它意味着任何有好想法的人都可以创建智能端点,并依赖网络来承载字节,期待电话或有线电视公司实施或支持好的想法是行不通的。不出所料的话,运营商会乐于获得更多的控制权,尤其是在移动领域,因为大多数创新都来自于此。像iPhone和Android这样的智能手机主要是通过电话网络进行通信,而不是在互联网上进行通信的计算机。运营商希望从电话服务中赚钱,但基本上现在只能从传输数据中获得收入了。在早期,大多数手机的数据服务都是包月收费的,但至少在美国,这种收费模式很久以前就改变了,使用量越多收费就越高。对于像下载电影这样的大容量服务,提高价格和为真正的滥用设置上限可能是合理的,但对于像短信这样的服务似乎就不那么合理了,因为带宽如此之小,运营商几乎没有任何成本。 ,注意早期的协议和程序是如何信任他们的用户的。Telnet以明文方式发送密码。在很长一段时间里,SMTP将邮件从任何人转发给任何人,而不以任何方式限制发件人或收件人。这种“开放中继”服务对于垃圾邮件发送者来说非常棒——如果不需要直接回复,就可以谎报源地址,这使得欺诈和拒绝服务攻击变得容易。互联网协议和基于这些协议构建的程序是为具有诚实、合作和善意的可信各方组成的社区而设计的 在更广泛的层面上,互联网的整体结构和开放性容易受到国家防火墙的控制,这些防火墙阻止或限制信息的进出。互联网治理方面的压力也越来越大,官方控制可能会压倒技术考虑。施加其上的这些事物越多,全球网络变得巴尔干化的风险就越大,最终价值就会大大降低 路由用于寻找从源地址到目标地址的路径,因此在任何网络中,它都是核心的存在。有些网络使用静态路由表,为所有可能的目标地址提供路径的下一条地址。但在互联网中,由于网络规模太大、动态性太强,静态路由表难以应用。为此,互联网网关通过与邻近网关交换信息来持续刷新自身的路由信息,这样就能保证可能的以及理想的路径信息基本都是最新的 互联网的庞大规模要求采用分层结构来管理路由信息。在路由系统的最顶层,几万个自治系统提供了它们所包含的网络的路由信息。一个自治系统通常也对应于一个大的互联网服务提供商(ISP)。在单个自治系统内部,路由信息仅进行本地交换,但整个自治系统对外部展示统一的路由信息。 路由系统在物理上也存在某种层次结构,尽管这样说并不正式也不严格。用户通过ISP接入互联网,ISP是某个公司或组织,它再连接到其他互联网提供商。有的ISP规模很小,有的则很大(比如由电话公司或有线电视公司经营的那些ISP)。有的ISP是由公司、大学、政府部门等机构运营,而有的ISP则对公众提供收费接入服务,电话公司和有线电视公司就是典型的例子。个人通常通过有线网络(常见的住宅服务)或电话接入ISP,公司和学校则提供以太网或无线连接 大型交换中心以每秒传递TB量级的速度将数据从一个网络传到另一个网络;例如,DE-CIX法兰克福交换中心是世界上最大的交换中心之一,目前的平均交换流量接近6Tbps,峰值超过9Tbps。图9.2显示了一张5年的流量图表。你可以注意到流量的稳步增长,以及2020年初新冠危机迫使许多人远程工作,流量开始显著上升。 有些国家提供的对外连接的网关数量相对较少,这些网关可用于监视和过滤政府认为不宜出现的信息。 你可以使用UNIX系统(包括Mac)上的traceroute程序探索路由信息,在Windows上叫tracert,还有网页版的相应程序 从一个国家连接到另一个国家也可以很容易地通过第三方国家的网关进行,这第三方国家通常会包括美国;这个事实可能很令人惊讶,而且不受欢迎,这取决于传送信息的性质和所涉及的国家。 互联网有很多协议,其中最基础的有两个,一个是互联网协议(Internet Procotol, IP),定义了单个包的格式和传输方式,另一个是传输控制协议(Transmission Control Protocol,TCP),定义了IP包如何组合成数据流以及如何连接到服务。两者合起来起就叫TCP/IP。 网关对IP数据包进行路由,尽管每个物理网络都有自己的IP数据包传输格式。每个网关必须在数据包进出时在网络格式和IP之间进行转换。 想象一下,互联网就像一个巨大的快递系统,每个网站或在线服务都有自己的“地址”,这些地址就是IP地址。而数据包就像是寄往这些地址的信件。但是,互联网由许多不同的网络组成,比如你家的WiFi网络、你手机的4G网络,还有各种公司和机构的私有网络。这就好比世界上有不同的国家和地区,每个地方都有自己的邮政系统和邮寄规则。 网关在这里就像是不同国家之间的邮政转换中心。当一个数据包(信件)从一个网络(比如,你家的WiFi)发送到另一个网络(比如一个网站的服务器网络)时,它可能需要通过几个网关。每当数据包通过一个网关,这个网关就有点像是邮政工作人员,需要确保这个数据包能够顺利地从一个网络的“邮政系统”转换到另一个网络的“邮政系统”。这可能意味着更改数据包的某些外部信息,以确保它能被下一个网络正确理解和接收,就像确保信件上的地址格式对目的地国家来说是正确的。 即使每个网络内部如何传输数据(即它们的“邮政规则”)可能不同,网关确保所有这些不同网络上的数据包都能按照互联网协议(IP)这个共同的“国际邮政规则”顺利移动,这样信息就能从发送者成功到达接收者。 在IP层之上,TCP确保可靠通信。这样,用户(实际上是指程序员)就不用考虑数据包的细节问题,只要当作信息流就可以了。被我们称为“互联网”的大部分服务都使用TCP。 再往上一层是支撑万维网、邮件、文件传输之类服务的应用层协议,它们大多基于TCP协议。由此可见,互联网协议分为好几层,每层都依赖下一层的服务,并为上一层提供服务 和TCP处在同一层的协议还有用户数据报协议(User Datagram Protocol, UDP)。UDP比TCP简单得多,如果某些数据交换不要求双向流传输,只要求高效的数据包传送和少量额外的特性,那么UDP就很适合。DNS、视频流媒体、IP语音和一些在线游戏使用的都是UDP。 互联网协议(IP)提供的是不可靠、无连接的数据包传递服务。所谓“无连接”,就是每个IP包都是自包含的,和其他IP包无关。IP协议没有状态或记忆,也就是说这个协议一旦把包传给下一个网关,就不再保存关于这个包的任何信息 就像数字上相邻的美国电话区号212和213是纽约市和洛杉矶,相隔一个大陆一样,没有理由预计相邻的IP地址块代表物理上相邻的计算机;单凭IP地址本身也是无法推断出地理位置的,虽然通常可以从其他信息推断出IP地址的位置。例如,DNS支持反向查找(IP地址到名称),并报告140.180.223.42是www.princeton.edu,因此可以合理地猜测它是在新泽西州普林斯顿,尽管服务器可能根本就是在其他地方。 有时可以使用名为whois的服务来了解更多关于某个域名所对应的计算机信息,该服务可以在whois.icann.org网页上或通过UNIX命令行程序whois找到。 IPv4地址只有232个,约43亿。这样地球上平均每人分不到一个地址,所以从人们使用的通信服务数量来看,一些东西将会耗尽。事实上,情况比听起来更糟,因为IP地址是按块分配的,因此使用效率不高(普林斯顿大学真有131000台计算机同时在工作吗?)。无论如何,除了少数例外,世界上大部分地区的IPv4地址都已分配完毕 将多个主机连接到单个IP地址的技术提供了一些缓解的余地。家庭无线路由器通常使用网络地址转换(Network Address Translation, NAT),一个外部IP地址可以服务于多个内部IP地址。如果你有一个NAT设备,你所有的家庭设备在外部都显示着相同的IP地址;位于设备中的硬件和软件处理着内外地址的双向转换。例如,在我的住宅里,至少有十几台电脑和其他设备需要IP地址。它们都由一个具有单一外部地址的NAT提供服务 将多个主机连接到单个IP地址的技术提供了一些缓解的余地。家庭无线路由器通常使用网络地址转换(Network Address Translation, NAT),一个外部IP地址可以服务于多个内部IP地址。如果你有一个NAT设备,你所有的家庭设备在外部都显示着相同的IP地址;位于设备中的硬件和软件处理着内外地址的双向转换。例如,在我的住宅里,至少有十几台电脑和其他设备需要IP地址。它们都由一个具有单一外部地址的NAT提供服务 DNS的关键功能是将名称转换为IP地址。顶级域由一组根域名服务器处理,根域名服务器知道所有顶级域的IP地址,例如mit.edu。要确定www.cs.mit.edu的IP地址,需要向根服务器查询mit.edu的IP地址,这样就能访问到MIT域了。接着,从那里我们向MIT的域名服务器查询cs.mit.edu的IP地址,这样就能把你引导到一个能查询到www.cs.mit.edu的IP地址的域名服务器。 因此,DNS使用了一种高效的搜索算法:在顶级域的初始查询中,便立即把那些在下一步查询中不可能碰到的地址排除掉了。在后面每一层的搜索过程中都是如此。这与我们之前在分级文件系统中看到的思想相同。 在实践中,名称服务器会维护最近被查找和传递的名称和地址的缓存,因此通常可以用本地信息来响应新请求,而不用求助于远程服务器。如果我访问kernighan.com,很有可能最近没有其他人访问过这个小众域名,本地名称服务器可能不得不向根服务器询问IP地址。但是,如果我很快再次访问这个域名时,则IP地址被就近缓存,查询就会快很多。经我尝试,第一个查询花了1/4秒;几秒钟后,再次的查询占用的时间还不到这个时间的十分之一,几分钟后的又一次查询也是如此。 你可以用nslookup等工具来亲自体验DNS查询 根服务器在各种不同硬件上运行不同的软件系统,这样,跟单一环境比起来,遇到bug或病毒攻击时的系统健壮性就要好很多。尽管如此,根域名服务器一直还是协同攻击的目标。可以想象,如果某些具有特殊条件的情况同时出现,所有根域名服务器也可能会同时停机。 只要你想要的域名还没被别人注册过,去注册一个你自己的域名是很简单的事。ICANN全球授权了好几百个域名注册商,你只要挑一个,选择自己想要的域名,支付费用,域名就归你了(尽管你每年还需要续费)。虽然有一些限制,但似乎没有禁止淫秽内容(只要尝试几次就可以很容易地验证)或人身攻击的规定,以至于企业和公众人物被迫为了自卫而抢先购买像bigcorpsucks.com这样的域名。当然,有些具体限制:域名最多只能有63个字符,只能包含字母、数字和连字符,尽管可以使用Unicode字符;如果存在非ASCII字符,则可以使用一种称为Punycode的标准编码将其转换回只包含字母-数字-连字符的子字符集。 。当有人试图查找你网站域名的IP地址时,你还需要一个域名服务器来响应,回复你主机的IP地址。这是一个单独的组件,虽然注册商通常会提供给你这样的服务,或易于获得该服务的渠道。 竞争导致价格下降。首次注册.com这样域名的价格一般为10~20美元一年,后期续费也差不多;租用一个空间不大的日常应用的主机服务的价格每个月大约5~10美元。仅仅“占据”一个具有通用页面的域名很可能是免费的。有些主机服务是免费的;如果你只想随意做一个小型网站时,有的主机服务仅象征性收取少量费用,或给你一段免费的试用期。 域名归谁所有呢?发生纠纷如何解决?别人先注册了kernighan.com,我该怎么办?最后一个问题的答案很简单:先买先得,除非能高价买过来。至于有商业价值的域名,比如mcdonalds.com和apple.com,法庭和ICANN的纠纷调解政策则偏向于支持有影响力的一方。如果你的名字叫麦当劳或者苹果,基本不可能把域名从这些公司手中抢过来,甚至就算是你先注册的也很难保住。2003年,有个叫迈克·罗(Mike Rowe)的加拿大中学生为自己的小软件公司建了个网站mikerowesoft.com,由于读音跟某软件巨头相似,该公司威胁要为此采取法律行动。最终,案件得到解决,迈克·罗换了个域名。 在互联网协议簇中,高层协议基于IP层的不可靠服务合成可靠的通信,其中最重要的就是传输控制协议——TCP。TCP能为用户提供可靠的双向数据流:一端输入数据,另一端流出数据,延迟很小,出错率很低,仿佛是一条从一头到另一头的直连线缆。 操作系统为应用程序定义了一组操作,或称为服务,比如将数据存储至文件或者从文件中读取数据,建立网络连接,获取键盘的任何输入,报告鼠标移动和按钮点击,绘制屏幕。 操作系统以标准化的或者说协商一致的方式提供这些服务,而应用程序通过执行一种特殊的指令来请求这些服务,并将控制权移交给操作系统中特定的地址。操作系统根据请求完成计算,然后再将控制权和结果返回给应用程序。操作系统的这些入口被称为系统调用(system call),而对这些系统调用的详细规范实际上恰恰定义了操作系统是什么样子。现代操作系统通常有几百个系统调用。 考虑打印机的情形。操作系统希望发出的是标准的请求,比如“在纸张的这个位置上打印这段文本”“绘制这幅图像”“移到下一页”“描述你的能力”“报告你的状态”等。是以适合所有打印机的标准方式发出这些请求。然而,打印机的功能是有差别的,比如支不支持彩色打印、双面打印或者不同纸张大小,还有标记如何转移到纸上的机制。打印机专属的驱动程序,要负责把操作系统请求转换为特定设备完成相应任务必需的指令,比如,对于一个黑白打印机来说,需要将颜色转换为灰色。一句话,就是操作系统发送通用的请求,而具体的驱动程序为自己的硬件实现这些请求。如果给定的计算机有多个打印机,你可以看到这种机制:打印对话框为不同的打印机提供不同的选项。 通用的操作系统都包含很多驱动程序。例如,Windows为满足各种用户的可能需要,在发行时就已经带有各种各样的设备驱动程序。每个设备的制造商都有自己的网站,提供新版本或更新的驱动程序下载。 在把外部磁盘插入USB插槽后,Windows会检测到这个新设备,确认它是一个磁盘,然后加载USB磁盘驱动程序与这个磁盘通信。通常不需要寻找新的驱动程序,因为所有设备的接口都是标准化的,操作系统本身已经包含了必要的代码,而驱动设备的特殊程序也已经包含在设备自身的处理器中。 展示了操作系统、系统调用、驱动程序和应用程序之间的关系。 一部数码相机称为“一台带镜头的计算机”也不为过。随着处理能力和内存容量的增加,相机的功能也越来越多。我的廉价傻瓜相机可以录制高清视频,并通过Wi-Fi将图片和视频上传到电脑或手机上。手机本身就是另一个很好的例子,当然,手机和相机现在都已经合二为一了。今天,随便一部手机上的相机所拥有的像素解析度,都远远超出了我的第一个数码相机,尽管镜头质量则是另一回事。 它们都有强劲的处理器、大容量的内存,以及一些外围设备,比如数码相机上的镜头和显示屏。它们可能有复杂的用户界面。它们可以通过网络连接与其他系统通信,手机使用电话网络和Wi-Fi,游戏机手柄使用红外线和蓝牙,不少还提供USB接口,以支持移动硬盘的临时接入。“物联网”也是基于此:恒温器、灯光、安全系统等由嵌入式计算机控制,并与互联网相连。 除非用途特殊,否则在Linux基础上改一改是成本最低的,Linux非常稳定、容易修改、方便移植,而且免费。相对而言,自己开发一个专有系统,或者取得某个商业系统的许可,会需要很大成本。当然,改造Linux的缺点在于必须把改造后的操作系统部分代码按照GPL许可发布,由此可能引发如何保护设备中知识产权的问题。不过,从Kindle和TiVo等许多案例来看,这并不是不可逾越的障碍。 大多数读者都用过Windows的资源管理器或者macOS的Finder,这两个工具都能列出自最顶层(比如Windows中的C盘)开始的文件系统的层次结构。在这个层次结构里,一个文件夹(folder)可以包含其他文件夹和文件;点开一个文件夹,就可以看到更多文件夹和文件。[UNIX系统则一直使用目录(directory)而不是文件夹这一词汇。]文件夹提供了一种组织结构,而实际的文档内容、图片、音乐、电子表格、网页等,则保存在文件中。在计算机中,所有这些信息都存储在文件系统内,你四处浏览的时候很方便通过文件系统找到这些信息。文件系统中不光存储着你的数据,还存储着可以执行的程序,比如Word和Chrome浏览器、库文件、配置文件、设备驱动程序,以及构成操作系统自身的文件。这些文件的数量大得惊人,就说我这个普通的MacBook吧,其中存储的文件已经超过了90万个;一个朋友告知我他的Windows电脑上有超过80万个文件。图6.6显示了我的计算机上的五层层次结构的一部分,向下延伸到我的主目录中的一些图片。 文件系统管理所有这些信息,方便其他应用程序和操作系统的其他部分读写这些信息。它统筹安排所有的读写操作,确保这些操作有效进行,而不会相互干扰。它记录数据的物理位置,确保它们相互隔离,不会让你的电子邮件意外地窜到你的电子表格或纳税申报单里面去。在支持多用户的系统中,还要保证信息的隐私权和安全性,不能让一个用户在未经允许的情况下访问另一个用户的文件,并且可能还需要限制每个用户有权使用的空间量。 在底层,文件系统服务是通过系统调用来提供的。程序员通常要借助代码库来使用这些系统调用,以简化编程过程中常见的文件处理操作。 文件系统是一个很好的例子,说明了如何使各种各样的物理系统呈现统一的逻辑外观,即文件夹和文件的层次结构。 一个500GB的硬盘包含5000亿个字节,但硬盘上的软件可能会将其表示为5亿个或每个1000字节的块。(真实的计算机中,块的大小应该是2的幂。这里我使用十进制数字是为了便于说明其中的关系。)这样,一个2500字节大的文件,比如一封普通的小邮件,就需要3个这样的块来存储。因为2个块存不下,而3个块则足够了 文件系统不会在同一个块内存储不同文件的信息,因而就免不了有一些浪费。因为存储每个文件的最后一个块不会完全用完:在我们举的这个例子中,最后一个块就会闲置500字节。考虑到简化记录工作所节省的工作量,这点代价还是值得的,更何况磁盘存储器已经很便宜了。 文件夹条目可以包含一个块编号列表;也可以引用一个自身包含一个块编号列表的块;或者只包含第一个块的编号,第一个块又包含第二个块的编号,依此类推。 兆字节级别的文件需要占用上千个块,这些块通常会分散在磁盘的各个地方。尽管从这幅图中看不出来,但文件夹及块列表本身也存储在块中。 固态硬盘的物理实现会有很大的不同,但基本思想是一样的。如前所述,现在大多数计算机使用SSD,因为尽管平均下来每字节价格更昂贵,但它们体积更小,提供更大的可靠性、更小的重量和更低的功耗。从Finder或Explorer这样的程序来看,两者没有任何区别。但是SSD设备有不同的驱动程序,设备本身有复杂的代码来记住信息在设备上的位置。这是因为SSD设备受限于每个部件的使用次数。驱动器中的软件跟踪每个物理块的使用情况,并移动数据,以确保每个块的使用大致相同,这一过程称为磨损均衡。 文件夹也是一个文件,其中包含着文件夹和文件的位置信息。由于涉及文件内容和组织的信息必须精准、一致,所以文件系统保留了自己管理和维护文件夹内容的权限。用户和软件只能请求文件系统来间接地修改文件夹内容。 从某个角度来看,文件夹也是文件。从存储方式上讲,它们跟文件没有任何区别。只不过文件系统会全权负责管理文件夹内容,任何应用软件都不能直接修改该内容。但在最底层,它只保存在块中,都由相同的机制进行管理。 文件夹是一种有些特殊权限的文件 假设要在Mac中查找/Users/bwk/book/book.txt。文件系统首先要在其顶层搜索Users,然后在该文件夹里搜索bwk,接着在找到的文件夹里搜索book,最后再在找到的文件夹里搜索book.txt。在Windows中,文件名可能是C:\My Documents\book\book.txt,但搜索过程相似。 这是一种有效的策略,因为路径的每个组成部分都将搜索范围缩小到该文件夹内的文件和文件夹;其他的都被排除了。因此,对于某些组件,多个文件可以有相同的名称;唯一的要求是完整路径名是独一无二的。实际场景中,应用程序和操作系统会追踪当前正在使用的文件夹,因此,文件系统不必每次都从根开始搜索,此外,为了加快处理速度,系统还可能会缓存频繁用到的文件夹。 和网址寻址一样的思路,分层 每当应用程序请求新磁盘块,它就可以从这些空闲的块中拿出一些来满足请求。这个空闲块的列表同样也保存在文件系统的块中,但只能由操作系统访问,应用程序是访问不到的。 删除文件时,相应的文件夹条目和完整的名字将从当前文件夹被复制到名叫“回收站”或“垃圾桶”的文件夹里,然后会清除掉原来的文件夹条目。这个文件占用的块以及其中的内容没有丝毫变化!从“回收站”里还原文件的过程正好相反,就是把相应条目恢复到它原来所在的文件夹中 假设是你明确地点击“清空回收站”或者“清空垃圾”来清空垃圾。那么这个操作首先清除回收站文件夹中的条目,然后把其中文件占用的块回写到空闲块列表,但这些文件的内容并没有被删除。换句话说,原始文件的每个块的所有字节仍然保持不变。它们不会被新内容覆盖,直到该块从空闲列表中删除并留给一个新文件 。 这种延迟意味着,你认为已经删除的信息仍然存在,而且如果你知道如何找到它,就可以很容易地访问它。任何通过物理块读取驱动器的程序,也就是说,不经过文件系统层次结构,都可以看到原来的内容是什么。在2020年中期,微软发布了Windows File Recovery(文件恢复),这是一个免费的工具,可以对各种文件系统和媒介进行这种类型的恢复。 这样有一个潜在的好处。就是在硬盘出问题的情况下,还有可能恢复其中的信息,即使文件系统可能已经混乱了。可是不能保证数据真正被删除也有问题。假如你想删除的文件里包含隐私,或你在做些不希望为人所知的事情,你肯定希望它们被删除后永远销声匿迹。一个有能力的敌人或执法机构可以毫不费力地找到它。如果你正在计划一些恶作剧,或者如果你只是由于偏执而写下一些内容,那么你必须使用一个程序来彻底删除被释放的块中的信息。 命令行的应用,不太好用,可以使用图吧工具箱里面的硬盘工具来尝试恢复 在实践中,你可能需要做得更好,因为即使新信息已覆盖原有内容,一个具有大量资源并且有职业精神的对手可能能够提取信息的痕迹。军用级文件擦除会用随机的1和0对要被释放的块进行多次覆盖。更好的方法是将硬盘放在强磁铁附近,使其退磁。最好的办法是在物理上摧毁它;只有这样才能确保里面的内容都没了。 更好的方法是将硬盘放在强磁铁附近,使其退磁,真正的物理删除,前提是没有云备份😂 然而,如果你的数据一直在自动备份(就像我在工作时那样),或者你的文件保存在网络文件系统或“云”中,而不是在你自己的硬盘上,即使这样也可能不够。(如果你出售或赠送一台旧电脑或旧手机,你可能需要确保其中的任何数据都是不可恢复的。) 文件夹条目本身也存在类似的问题。删除一个文件时,文件系统会注意到相应文件夹条目不再指向有效的文件。为此,它可能只会设置一个表示“本条目不再使用”的比特位。这样就有可能恢复关于文件的原始信息,包括没有重新分配的任何块的内容,直到该文件夹条目本身被重新使用。这种机制是20世纪80年代微软MS-DOS系统商业文件恢复程序的核心,它通过将文件名的第一个字符设置为一个特殊值来标记空闲条目。这样,如果用户删除文件后不久尝试恢复文件,实现起来就会很容易。 在程序员的世界里,分层是解决复杂问题的一个核心思想。每一层都实现了一些东西,并提供了上面一层可以用于访问服务的抽象。 一般而言,计算机的最底层是硬件。它几乎可以看成固定的,除非因为总线的原因,使得即使在系统运行时也可以添加和删除设备。 接下来一层是操作系统本身,通常称为内核,以显示其核心功能。操作系统介于硬件和应用程序之间。无论底层是什么硬件,操作系统都要负责隐藏其特性,并向应用程序提供统一的接口或界面,这个接口或界面不因硬件的种种差别而变化。在接口设计得当的情况下,相同的操作系统接口可以在不同类型的处理器上使用,也可以由不同的供应商提供。 UNIX和Linux操作系统的接口就是这样的。UNIX和Linux可以在各种处理器之上运行,在每个处理器上都能提供相同的操作系统服务。实际上,操作系统已经成为一种商品;底层的硬件除了价格和性能之外,其他方面都影响不大。而且,上层的软件也不依赖于它。(一种显而易见的证据是,我经常交替使用“UNIX”和“Linux”,因为对于大多数目的来说,两者的区别是无关紧要的。)注意,将程序移动到新处理器所需要做的就是使用合适的编译器对其进行编译。当然,一个程序与特定硬件属性的联系越紧密,这项工作就越困难,但对于许多程序来说,这是非常可行的。 苹果公司在2005年到2006年,用了不到一年时间,就把它们的软件从IBM的PowerPC处理器转换到了Intel处理器上。在2020年中间,苹果宣布它将再次做同样的事情,从此在所有的手机、平板电脑和电脑上使用ARM处理器,而不是英特尔的处理器。这是软件如何在很大程度上独立于特定处理器架构的另一个演示。 对Windows来说,问题就没有那么简单了。从1978年的Intel 8086CPU开始,Windows的开发就与Intel架构紧密结合,包括后续演化过程中出现的产品。(处理器系列一般称为“x86”,是因为Intel的处理器很多年都以“86”这个编号结尾,包括80286、80386、80486等。)这种联系如此紧密,以至于在英特尔上运行的Windows有时被称为“Wintel”。然而现在Windows也可以运行在ARM处理器上了。 操作系统再往上的一层是一套函数库,它提供通用的服务,这样一来,程序员就不必各自重复实现这些功能。这些函数库是通过它们的API访问的。有些库位于底层,能够完成一些基本功能(完成数学计算,比如开方和求对数,或者像前面date命令一样计算日期和时间)。另外一些库的功能更复杂(加密、图形处理、压缩等)。用于图形用户界面的组件,包括对话框、菜单、按钮、复选框、滚动条、选项卡面板等,都需要编写很多代码。为此,只要把这些代码封装成函数库,任何人就都可以使用它们,而且还能保证统一的外观和体验。这就是为什么大多数Windows应用(至少它们的基本图形组件)看起来那么相似的原因。同样的情况在Mac上更是如此。对于大多数软件供应商来说,重新发明和重新实现的工作量太大,而且毫无意义的不同视觉外观会让用户感到困惑。 有时候,内核、函数库和应用程序之间并不像我说的那么界限分明。毕竟,编写及连接软件组件的方式多种多样。例如,内核可以提供少量服务,而依赖上层的库来完成大部分工作。或者,它也可以自己承担大部分任务,而较少地依赖于库。操作系统和应用程序之间的边界也并没有明确界定。 内存管理需要决定在程序运行的时候把它们放到内存的什么位置,它是操作系统的一部分。类似的,文件系统需要决定把信息保存到二级存储上的什么位置,是一个关键功能。设备管理也是,需要确保两个应用程序不会同时占用打印机,也不能在没有协商的情况下就向显示器输出内容。最核心的,处理器的控制是一个操作系统功能,因为这是确保所有其他属性所必需的。 浏览器不属于操作系统,因为你可以运行任意浏览器,甚至同时运行多个浏览器,都不会干扰共享的资源或者控制。这听起来像是一个技术上的关键点,但它已经产生了重大的法律后果。美国司法部从1998年开始到2011年结束的对微软的反垄断诉讼,就涉及微软的Internet Explorer浏览器到底是操作系统的一部分,还是仅仅是一个独立应用程序的问题。如果浏览器是操作系统的一部分,按照微软的主张的那样,它不能被合理地删除,微软有权要求使用IE。如果浏览器是一个独立的应用程序,那么微软就涉嫌以非法手段强迫用户在非必要情况下使用IE。当然,这个官司本身要复杂得多,但如何界定浏览器的归属问题确实非常重要。最终诉讼的结果是,法院认定浏览器是一个独立的应用程序,不属于操作系统。用法官托马斯·杰克逊(Thomas Jackson)的话说:“Web浏览器和操作系统是相互独立的产品。” 应用程序完成任务,操作系统充当协调者和“交通警察”,以确保应用程序有效而公平地共享资源——处理器时间、内存、二级存储、网络连接和其他设备,并且互不干扰。基本上今天所有的计算机都有一个操作系统,而且趋势是使用像Linux这样的通用系统,而不是专门的系统,因为除非有很特殊的情况,使用现有的代码比编写新的代码更容易、更便宜。 软件系统很大、很复杂,而且经常有bug,而不断的变化会使这些变得更糟。很难准确估计大型系统中有多少代码,但我们所依赖的主要系统往往至少涉及数百万行代码。因此不可避免地会有重大的漏洞被利用。随着我们的系统变得越来越复杂,这种情况可能会变得更糟,而不是更好