2023-05-26    2023-09-07    37381 字  75 分钟

后续章节为概念性章节,统一汇总在该章节内。

15. 阿兰·图灵

i.e. Alan Turing

(。・∀・)ノ゙嗨,我是 Carrie Anne,欢迎收看计算机科学速成课!

前几集我们聊了基础,比如函数,算法和数据结构,今天,我们来看一位对计算机理论 贡献巨大的人,计算机科学之父,长得不怎么像本尼的阿兰·图灵。

> 阿兰·图灵

阿兰·马蒂森·图灵 于 1921 年出生在伦敦, 从小就表现出惊人数学和科学能力。他对计算机科学的建树始于 1935 年,当时他是剑桥国王学院的硕士生,他开始解决德国数学家大卫·希尔伯特提出的问题 - 叫 Entscheidungsproblem (德语),即"可判定性问题": 是否存在一种算法,输入正式逻辑语句,输出准确的"是"或"否"答案?

如果这样的算法存在,可以回答比如 “是否有一个数大于所有数”?不,没有。我们知道答案,但有很多其他数学问题,我们想知道答案,所以如果这种算法存在,我们想知道。

美国数学家阿隆佐·丘奇于 1935 年 首先提出解决方法,开发了一个叫"Lambda 算子"的数学表达系统,证明了这样的算法不存在。虽然"Lambda 算子"能表示任何计算,但它使用的数学技巧难以理解和使用。同时在大西洋另一边,阿兰·图灵 想出了自己的办法来解决"可判定性问题",提出了一种假想的计算机,现在叫"图灵机"。

图灵机提供了简单又强大的数学计算模型,虽然用的数学不一样,但图灵机的计算能力和 Lambda 算子一样,同时因为图灵机更简单,所以在新兴的计算机领域更受欢迎。因为它如此简单,我现在就给你解释。

图灵机是一台理论计算设备,还有一个状态变量,保存当前状态,还有一组规则,描述机器做什么,规则是根据当前状态+读写头看到的符号,决定机器做什么,结果可能是在纸带写入一个符号,或改变状态,或把读写头移动一格,或执行这些动作的组合。

为了更好理解,讲个简单例子:让图灵机读一个以零结尾的字符串,并计算 1 的出现次数是不是偶数。如果是,在纸带上写一个 1 ;如果不是,在纸带上写一个 0 。

首先要定义"图灵机"的规则,如果当前状态是"偶数", 当前符号是 1 ,那么把状态更新为"奇数",把读写头向右移动;如果当前状态为偶数,当前符号是 0 ,意味着到了字符串结尾 。那么在纸带上写一个 1,并且把状态改成停机 (halt),状态改为"停机" 是因为图灵机已完成计算。但我们还需要 2 条规则,来处理状态为奇数的情况,一条处理奇数+纸带是 0 的情况, 一条处理奇数+纸带是 1 的情况,最后,要决定机器的初始状态,这里定成"偶数"。

:: 初始状态:偶

偶 + 1 - 状态更新为奇数,读写头向右移动一格
偶 + 0 - 状态更新为停机,在纸带上写一个 1
奇 + 1 - 状态更新为偶数,读写头向右移动一格
奇 + 0 - 在纸带上写一个 0

💡 真的是需要天赋的……

定义好了起始状态+规则,就像写好了程序,现在可以输入了。

假设把 110 放在纸带上,有两个 1,是偶数,注意,规则只让读写头向右移动,其他部分无关紧要,为了简单所以留空。

“图灵机"准备好了,开始吧。

机器起始状态为"偶数”,看到的第一个数是 1,符合最上面那条规则,所以执行对应的步骤 - 把状态更新到"奇数", 读写头向右移动一格;然后又看到 1, 但机器状态是"奇数",所以执行第三条规则,使机器状态变回"偶数",读写头向右移动一格;现在看到 0,并且机器状态是偶数,所以执行第二条规则,在纸带上写 1,表示"真" 的确有偶数个 1,然后机器停机。

这就是图灵机的原理,很简单对吧?你可能想知道有什么大不了的。

图灵证明了这个简单假想机器。如果有足够时间和内存,可以执行任何计算。它是一台通用计算机!刚才的程序就是个简单例子,只要有足够的规则,状态和纸带,可以创造任何东西 - 浏览器,魔兽世界 任何东西!当然 这样做效率很低,但理论上可行,所以图灵机是很强大的计算模型。

事实上,就可计算和不可计算而言,没有计算机比图灵机更强大。和图灵机一样强大的,叫 “图灵完备”。每个现代计算系统,比如笔记本电脑,智能手机,甚至微波炉和恒温器内部的小电脑,都是"图灵完备"的。

为了回答可判定性问题,他把图灵机用于一个有趣计算问题:“停机问题”。简单说就是,“给定图灵机描述和输入纸带,是否有算法可以确定机器会永远算下去还是到某一点会停机?” 我们知道输入 110,图灵机会停机,因为刚做过这个例子,它最后停机了,但如果是更复杂的问题呢?有没有办法在不执行的情况,弄清会不会停机?一些程序可能要运行好几年,所以在运行前知道 会不会出结果很有用,否则就要一直等啊等,忧虑到底会不会出结果,当几十年后变老了,再按强制结束。好悲伤!

图灵通过一个巧妙逻辑矛盾证明了停机问题是无法解决的。

我们来看看他的推理,想象有一个假想图灵机, 输入:问题的描述 + 纸带的数据,输出 Yes 代表会"停机",输出 No 代表不会。我要给这台机器一个有趣的名字叫 H,来自"停机"的第一个字母,不用担心它具体怎么工作,假设这样的机器存在就好,毕竟重点是推论。图灵推理说: 如果有个程序, H 无法判断是否会"停机",意味着"停机问题"无法解决。为了找到这样的程序,图灵用 H 设计了另一个图灵机。如果 H 说程序会"停机",那么新机器会永远运行(即不会停机)。如果 H 的结果为 No,代表不会停机,那么让新机器输出 No,然后"停机"。实质上是一台和 H 输出相反的机器,如果程序不停机,就停机,如果程序停机,就永远运行下去。我们还需要在机器前面加一个分离器,让机器只接收一个输入, 这个输入既是程序,也是输入,我们把这台新机器叫异魔😈。目前为止,这个机器不难理解,但接下来马上会变复杂,会有点难懂。如果把异魔的描述,作为本身的输入会怎样?意味着在问 H ,当异魔的输入是自己时会怎样,但如果 H 说异魔会停机,那么异魔会进入无限循环,因此不会停机,如果 H 说异魔不会停机,那么异魔会输出 No 然后停机,所以 H 不能正确判定停机问题,因为没有答案。这是一个悖论!意味着"停机问题"不能用图灵机解决!

还记得刚刚说: 图灵证明了图灵机可以实现任何计算。“停机问题"证明了,不是所有问题都能用计算解决。哇,好难理解!我都可能要再看一遍。

长话短说,丘奇和图灵证明了计算机的能力有极限。无论有多少时间或内存,有些问题是计算机无法解决的。丘奇和图灵证明了计算是有极限的,起步了可计算性理论,现在叫"丘奇-图灵论题”。

当时是 1936 年,图灵只有 24 岁,他的职业生涯才刚刚开始。从 1936 年到 1938 年 在丘奇指导下,他在普林斯顿拿到博士学位,毕业后回到剑桥。1939 年后不久,英国卷入第二次世界大战,图灵的才能很快被投入战争。事实上,在战争开始前一年,他已经在英国政府的密码破译学校兼职 - 位于"布莱切利园"的一个密码破译组织。他的工作内容之一是破解德国的通信加密,特别是"英格玛机"加密的信息,简单说,英格玛机会加密明文,如果输入字母 H-E-L-L-O ,机器输出 X-W-D-B-J ,这个过程叫"加密",文字不是随便打乱的。加密由"英格玛机"顶部的齿轮组合决定,每个齿轮有 26 个可能位置,机器前面还有插板,可以将两个字母互换,总共有上十亿种可能,如果你有"英格玛机",并且知道正确的齿轮和插头设置,输入 X-W-D-B-J,机器会输出 hello ,解密了这条消息。

当然,德军不会把机器设置发到微博上,盟军必须自己破译密码,有数十亿种组合,根本没法手工尝试所有组合。幸运的是,英格玛机和操作员不是完美的,一个大缺陷是:字母加密后绝不会是自己,H 加密后绝对不是 H 。图灵接着之前波兰破译专家的成果继续工作,设计了一个机电计算机,叫 Bombe,利用了这个缺陷,它对加密消息尝试多种组合。如果发现字母解密后和原先一样,我们知道英格玛机决不会这么做,这个组合会被跳过,接着试另一个组合。Bombe 大幅减少了搜索量,让破译人员把精力花在更有可能的组合,比如在解码文本中找常见的德语单词。德国人时不时会怀疑有人在破解,然后升级英格玛机,比如加一个齿轮,创造更多可能组合,他们甚至还做了全新的加密机。整个战争期间,图灵和同事在布莱切利园努力破解加密,解密得到的德国情报,为盟军赢得了很多优势,些史学家认为他们把战争减短了好几年。战后,图灵回到学术界,为许多早期计算机工作做出贡献,比如曼彻斯特 1 号,一个早期有影响力的存储程序计算机。但他最有名的战后贡献是"人工智能",这个领域很新,直到 1956 年才有名字,这个话题很大,以后再谈(第 34 集)。

1950 年,图灵设想了未来的计算机,拥有和人类一样的智力,或至少难以区分。图灵提出,如果计算机能欺骗人类相信它是人类,才算是智能,这成了智能测试的基础,如今叫"图灵测试"。想像你在和两个人沟通,不用嘴或面对面,而是来回发消息,可以问任何问题,然后会收到回答,但其中一个是计算机,如果你分不出哪个是人类,哪个是计算机,那么计算机就通过了图灵测试。这个测试的现代版叫 “公开全自动图灵测试,用于区分计算机和人类”,简称"验证码"。防止机器人发垃圾信息等,我承认 有时我都认不出那些扭曲的东西是什么字,这难道意味着我是计算机?🤔

通常这个系列我们不会深入历史人物的个人生活,但图灵与悲剧密不可分,所以他的故事值得一提。图灵那个时代,同性恋是违法的,英国和大部分国家都是。1952 年调查他家的入室盗窃案时,向当局暴露了他的性取向,被起诉 “行为严重不检点”,图灵被定罪,有 2 个选择:1. 入狱; 2. 接受激素来压制性欲。他选了后者,部分原因是为了继续学术工作,但药物改变了他的情绪和性格,虽然确切情况永远无法得知。图灵于 1954 年服毒自尽,年仅 41 岁。

:: 图灵真的是惨……看看现在西方,LGBT 都上天了快……

由于图灵对计算机科学贡献巨大,许多东西以他命名,其中最出名的是"图灵奖" - 计算机领域的最高奖项。相当于物理,化学等其它领域的诺贝尔奖。虽然英年早逝,但图灵激励了第一代计算机科学家,而且为如今便利的数字时代 做出了重要基石性工作。

我们下周见。

16. 软件工程

i.e. Software Engineering

(。・∀・)ノ゙嗨,我是 Carrie Anne,欢迎收看计算机科学速成课!

之前花了很多时间讲排序,也写了些 10 行左右的排序代码,对 1 个程序员来说很容易写。而且代码很短,不必用专门工具 - 记事本就够了。真的!但排序算法很少会是独立程序 ,更可能是大项目的一小部分,举个例子,微软的 Office 大约有 4000 万代码,4000 万!太多了,一个人不可能做到,为了写大型程序,程序员用各种工具和方法,所有这些形成了"软件工程"学科 - 这个词由工程师 Margaret Hamilton 创造,她帮助 NASA 在阿波罗计划中避免了严重问题。

She once explained it this way: 她曾说过:“有点像牙根管治疗:你总是拖到最后才做,但有些事可以预先做好。有点像预防性体检,只不过是预防软件出错。”

第 12 集提过,把大项目分解成小函数,可以让多人同时工作,不用关心整个项目,关心自己的函数就好了。如果你的任务是写排序算法,你只需要确保高效和正确就可以了,然而把代码打包成函数 依然不够。如果只是这样,微软 Office 会有几十万个函数,虽然比 4000 万行代码要好一些,但还是太多了。解决办法是:把函数打包成层级,把相关代码都放在一起,打包成对象(objects)。

例如,汽车软件中 可能有几个和定速巡航有关的函数,比如 设定速度,逐渐加速减速,停止定速巡航,因为这些函数都相关,可以包装成一个"定速巡航对象",但不止如此,我们还可以做更多。“定速巡航"只是引擎软件的一部分,可能还有 “火花塞点火” “燃油泵” 和 “散热器”,我们可以做一个"引擎对象” 来包括所有"子"对象,除了子对象,“引擎对象"可能有自己的函数,比如 开关引擎,它也会有自己的变量,比如汽车行驶了多少英里。

总的来说,对象可以包其它对象,函数和变量。

当然,“引擎对象"只是"汽车对象"的一部分,还有传动装置,车轮,门,窗等。作为程序员,如果想设"定速巡航”,要一层层向下,从最外面的对象往里找,最后找到想执行的函数:

"Car, then engine, then cruise control, then set cruise speed to 55".
Car. Engine.  CruiseControl.  setCruiseSpeed(55)

编程语言经常用类似这样的语法,把函数打包成对象的思想叫 “面向对象编程” 。这种思想和之前类似,通过封装组件,隐藏复杂度。之前把晶体管打包成了逻辑门,现在软件也这样做。

又提升了一层抽象!

把大型软件(如汽车软件) 拆成一个个更小单元,适合团队合作,一个团队负责定速巡航系统,团队里的一位程序员负责其中一些函数。类似建摩天大楼,有电工装电线、管道工配管、焊接工焊接、油漆工涂油漆,还有成百上千人做其他事情,在不同岗位同时工作,各尽其能,直到整栋楼完成。

回到定速巡航的例子,定速巡航 要用到引擎的其它函数,来保持车速。定速巡航 团队不负责这些代码,另一个团队负责,因为是其他团队的代码,定速巡航 团队需要文档 帮助理解代码都做什么,以及定义好的 “程序编程接口” -简称 API。API 帮助不同程序员合作,不用知道具体细节,只要知道怎么使用就行了。例如"点火控制"对象中,可能有"设置发动机转数"函数、“检查火花塞电压"函数、“点燃单个火花塞"函数。“设置发动机转速"非常有用,“定速巡航"团队要用到这个函数,但他们对点火系统不怎么了解,让他们调用"点燃单个火花塞"函数,不是好主意,引擎可能会炸!可能啦 !👻 API 控制哪些函数和数据让外部访问,哪些仅供内部。“面向对象"的编程语言可以指定函数是 public 或 private,来设置权限。如果函数标记成 private ,意味着 只有同一个对象内的其他函数能调用它。在这个例子里,只有内部函数比如 setRPM 才能调用 fireSparkplug 函数 ,而 setRPM 函数是 public,所以其它对象可以调用它,比如 定速巡航。

“面向对象编程"的核心是 隐藏复杂度,选择性的公布功能。因为做大型项目很有效,所以广受欢迎。计算机上几乎所有软件,游戏机里几乎所有游戏,都是 “面向对象” 编程语言写的,比如 C++, C#, Objective-C 等。其他流行 OO 语言,你可能听过 Python 和 Java 。

有一点很重要:代码在编译前就只是文字而已,前面提过,你可以用记事本或任何文字处理器,有人确实这样做。😳 但一般来说,现代软件开发者会用专门的工具来写代码,工具里集成了很多有用功能 帮助写代码,整理,编译和测代码,因为集成了所有东西,因此叫 集成开发环境,简称 IDE 。所有 IDE 都有写代码的界面,还带一些有用功能,比如代码高亮,来提高可读性。许多 IDE 提供实时检查,比如拼写。大型项目有很多源代码文件,IDE 帮助开发者整理和看代码,很多 IDE 还可以直接编译和运行代码。

如果程序崩了,因为你还没写完呢,IDE 可以定位到出错代码,还会提供信息 帮你解决问题,这叫 调试(debug)。调试很重要,大多数程序员会花 70%~80% 时间调试,而不是在写代码。好工具能极大帮助程序员防止和解决错误,很多开发者只用一款 IDE,但承认吧,VIM 才是最棒的编辑器,如果你知道怎么退出的话。

除了写代码和调试,程序员工作的另一个重要部分是给代码写文档,文档一般放在一个叫 README 的文件里,告诉其他程序员,看代码前先看这个文件。文档也可以直接写成"注释”,放在源代码里,注释是标记过的一段文字,编译代码时注释会被忽略,注释存在的唯一作用 - 就是帮助开发者理解代码。好文档能帮助开发者 ,几个月后理解自己的代码,对其他人也很重要。我想花一秒再强调一下注释很重要!最糟糕的就是拿到一堆代码,没有任何注释和文档,结果得逐行读代码,理解到底干嘛的。我是认真的,别做那种人!文档还可以提高复用性,与其让程序员一遍遍写同样的东西,可以直接用别人写好的来解决问题,读文档看怎么用就行,不用读代码,“读文档啊”!

除了 IDE,还有一个重要软件帮助团队协作,源代码管理,也叫"版本控制”!

苹果或微软这样的大型软件公司,会把代码放到一个中心服务器上,叫"代码仓库”。程序员想改一段代码时,可以 check out ,有点像从图书馆借书 。一般这种操作,可以直接在 IDE 内完成,然后开发者在自己的电脑上编辑代码,加新功能,测试。如果代码没问题了,所有测试通过了,可以把代码放回去,这叫 提交 (commit) 。当代码被 check out,而且可能被改过了,其他开发者不会动这段代码,防止代码冲突和重复劳动,这样多名程序员可以同时写代码,建立庞大的系统。重要的是,你不希望提交的代码里有问题,因为其他人可能用到了这些代码,导致他们的代码崩溃,造成困惑而且浪费时间。代码的主版本 (master),应该总是编译正常,尽可能少 bug ,但有时 bug 还是会出现 。幸运的是,源代码管理可以跟踪所有变化,如果发现 bug ,全部或部分代码,可以"回滚"到之前的稳定版 。“源代码管理” 也记录了谁改了什么代码,所以同事可以给你发 讨厌的,我是说"有帮助的” 邮件给写代码的人。

写代码和测代码密不可分,测试一般由个人或小团队完成,测试可以统称 “质量保证测试”,简称 QA 。严格测试软件的方方面面,模拟各种可能情况,看软件会不会出错,基本上就是找 bug 。解决大大小小的错误需要很多工作,但对确保软件质量至关重要,让软件在各种情况下按预期运行。你可能听过 “beta 版” 软件,意思是软件接近完成,但不是 100% 完全测试过。公司有时会向公众发布 beta 版,以帮助发现问题,用户就像免费的 QA 团队。你听过比较少的是 beta 版之前的版本:alpha 版本,alpha 版一般很粗糙,错误很多, 经常只在公司内部测试。

以上只是软件工程师用的工具和技巧的冰山一角。它们帮助软件工程师制作令人喜爱的软件,如 YouTube,GTA5 和 PPT 等等。如你所料,这些代码要强大的处理能力 才能高速速度运行。

所以下集讨论,计算机怎么发展到如今这么快。

到时见。

17. 集成电路 & 摩尔定律

i.e. Integrated Circuits & Moore’s Law

(。・∀・)ノ゙嗨,我是 Carrie Anne 欢迎收看计算机科学速成课!

过去 6 集我们聊了软件,从早期编程方式到现代软件工程。在大概 50 年里,软件从纸带打孔,变成面向对象编程语言,在集成开发环境中写程序,但如果没有硬件的大幅度进步,软件是不可能做到这些的。

为了体会硬件性能的爆炸性增长 我们要回到电子计算机的诞生年代。

大约 1940 年代~1960 年代中期这段时间里,计算机都由独立部件组成,叫"分立元件”,然后不同组件再用线连在一起。举例,ENIAC 有 1 万 7 千多个真空管,7 万个电阻,1 万个电容器,7 千个二极管,5 百万个手工焊点。如果想提升性能,就要加更多部件,这导致更多电线,更复杂,这个问题叫 “数字暴政” 。

1950 年代中期,晶体管开始商业化(市场上买得到),开始用在计算机里。晶体管比电子管更小更快更可靠,但晶体管依然是分立元件。

1959 年,IBM 把 709 计算机从原本的电子管 全部换成晶体管,诞生的新机器 IBM 7090,速度快 6 倍,价格只有一半。晶体管标志着"计算 2.0 时代"的到来。虽然更快更小 但晶体管的出现 还是没有解决"数字暴政"的问题,有几十万个独立元件的计算机不但难设计 而且难生产。

1960 年代,这个问题的严重性达到顶点 电脑内部常常一大堆电线缠绕在一起。

看看这个 1965 年 PDP-8 计算机的内部。

解决办法是引入一层新抽象,封装复杂性。

突破性进展在 1958 年 当时 Jack Killby 在德州仪器工作,演示了一个电子部件: “电路的所有组件都集成在一起”,简单说就是: 与其把多个独立部件用电线连起来,拼装出计算机,我们把多个组件包在一起,变成一个新的独立组件,这就是 集成电路(IC)。几个月后,在 1959 年 Robert Noyce 的仙童半导体 让集成电路变为现实,Kilby 用锗来做集成电路,锗很稀少而且不稳定,仙童半导体公司用硅 硅的蕴藏量丰富,占地壳四分之一,也更稳定可靠,所以 Noyce 被公认为现代集成电路之父,开创了电子时代,创造了硅谷(仙童公司所在地),之后有很多半导体企业都出现在硅谷。

起初,一个 IC 只有几个晶体管,例如这块早期样品,由西屋公司制造。即使只有几个晶体管 也可以把简单电路,第 3 集的逻辑门,能封装成单独组件。IC 就像电脑工程师的乐高积木,可以组合出无数种设计,但最终还是需要连起来, 创造更大更复杂的电路,比如整个计算机,所以工程师们再度创新:印刷电路板,简称 PCB 。PCB 可以大规模生产,无需焊接或用一大堆线。它通过蚀刻金属线的方式,把零件连接到一起,把 PCB 和 IC 结合使用 可以大幅减少独立组件和电线,但做到相同的功能,而且更小,更便宜,更可靠。三赢!

许多早期 IC 都是把很小的分立元件 封装成一个独立单元,例如这块 1964 年的 IBM 样品,不过,即使组件很小 塞 5 个以上的晶体管还是很困难。为了实现更复杂的设计,需要全新的制作工艺 “光刻"登场!简单说就是用光把复杂图案印到材料上,比如半导体,它只有几个基础操作,但可以制作出复杂电路。

下面用一个简单例子,来做一片这个!

我们从一片硅开始,叫"晶圆” 长得像薄饼干一样。美味!我们在第 2 集讨论过 硅很特别,它是半导体,它有时导电,有时不导电,我们可以控制导电时机,所以硅是做晶体管的绝佳材料。我们可以用晶圆做基础,把复杂金属电路放上面,集成所有东西,非常适合做。. 集成电路!

下一步是在硅片顶部加一层薄薄的氧化层,作为保护层,然后加一层特殊化学品,叫 “光刻胶”,光刻胶被光照射后 会变得可溶,可以用一种特殊化学药剂洗掉。单单光刻胶本身,并不是很有用,但和"光掩膜"配合使用会很强大,光掩膜就像胶片一样,只不过不是 吃墨西哥卷饼的可爱仓鼠,而是要转移到晶圆上的图案。把光掩膜盖到晶圆上,用强光照射 挡住光的地方,光刻胶不会变化,光照到的地方,光刻胶会发生化学变化 洗掉它之后,暴露出氧化层,用另一种化学物质 - 通常是一种酸 可以洗掉"氧化层"露出的部分,蚀刻到硅层。注意,氧化层被光刻胶保护住了。为了清理光刻胶,我们用另一种化学药品洗掉它,是的,光刻法用很多化学品,每种都有特定用途,现在硅又露出来了,我们想修改硅露出来的区域,让它导电性更好,所以用一种化学过程来改变它,叫"掺杂”。不是开玩笑!我们继续!“掺杂” 通常用高温气体来做,比如磷 渗透进暴露出的硅,改变电学性质。

半导体的具体物理和化学性质我们不会深究,如果你感兴趣,描述里有个视频链接 视频制作者是 Derek Muller 他的频道叫 Veritasium 。

但我们还需要几轮光刻法 来做晶体管,过程基本一样,先盖氧化层,再盖光刻胶,然后用新的光掩膜,这次图案不同 在掺杂区域上方开一个缺口,洗掉光刻胶,然后用另一种气体掺杂 把一部分硅转成另一种形式。为了控制深度,时机很重要,我们不想超过之前的区域,现在,所有需要的组件都有了。

最后一步,在氧化层上做通道 这样可以用细小金属导线,连接不同晶体管,再次用光刻胶和光掩膜蚀刻出小通道。现在用新的处理方法 叫"金属化” 放一层薄薄的金属,比如铝或铜,但我们不想用金属盖住所有东西 我们想蚀刻出具体的电路,所以又是类似的步骤 用光刻胶+光掩膜,然后溶掉暴露的光刻胶,暴露的金属。咻~

晶体管终于做好了! 它有三根线,连接着硅的三个不同区域,每个区域的掺杂方式不同,这叫双极型晶体管。这个 1962 年的真实专利,永远改变了世界!

用类似步骤,光刻可以制作其他电子元件 比如电阻和电容,都在一片硅上,而且互相连接的电路也做好了。再见了,分立元件!

之前的例子 只做了一个晶体管,但现实中 光刻法一次会做上百万个细节。芯片放大是这样的,导线上下交错,连接各个元件,尽管可以把光掩膜投影到一整片晶圆上 但光可以投射成任意大小,就像投影仪可以投满荧幕一样,我们可以把光掩膜 聚焦到极小的区域,制作出非常精细的细节。一片晶圆可以做很多 IC 整块都做完后,可以切割然后包进微型芯片,微型芯片就是在电子设备中那些小长方体,记住,芯片的核心都是一小片 IC 。

随着光刻技术(photolithography techniques)发展,晶体管变小,密度变高。1960 年代初,IC 很少超过 5 个晶体管,因为塞不下,但 1960 年代中期 市场上开始出现超过 100 个晶体管的 IC 。1965 年,戈登·摩尔看到了趋势:每两年左右,得益于材料和制造技术的发展 同样大小的空间,能塞进两倍数量的晶体管!这叫 摩尔定律 ,然而这个名字不太对 因为它不是定律,只是一种趋势,但它是对的!

芯片的价格也急剧下降 1962 年平均 50 美元,下降到 1968 年 2 美元左右。如今 几美分就能买到 IC ,晶体管更小密度更高 还有其他好处。晶体管越小,要移动的电荷量就越少 能更快切换状态,耗电更少。电路更紧凑 还意味着信号延迟更低,导致时钟速度更快。

1968 年,罗伯特·诺伊斯 和 戈登·摩尔 联手成立了一家新公司,结合 Intergrated(集成) 和 Electronics(电子) 两个词,取名 Intel, 如今最大的芯片制造商!

Intel 4004 CPU, 在第 7, 8 集介绍过 是个重要里程碑,发布于 1971 年 是第一个用 IC 做的处理器,也叫微型处理器,因为真的非常小!它有 2300 个晶体管,人们惊叹于它的整合水平 整个 CPU 在一个芯片里,而仅仅 20 年前,用分立元件会占满整个屋子。

集成电路的出现 尤其是用来做微处理器,开启了计算 3.0 。

而 Intel 4004 只是个开始,CPU 晶体管数量爆发增长。1980 年,3 万晶体管。1990 年,100 万晶体管。2000 年,3000 万个晶体管。2010 年,10 亿个晶体管! 在一个芯片里!我的天啊!

为了达到这种密度,光刻的分辨率 从大约一万纳米,大概是人类头发直径的 1/10 ,发展到如今的 14 纳米 比血红细胞小 400 倍!

当然,CPU 不是唯一受益的元件。大多数电子器件都在指数式发展: 内存,显卡,固态硬盘,摄像头感光元件,等等。如今的处理器,比如 iPhone 7 的 A10 CPU 有 33 亿个晶体管,面积仅有 1cm x 1cm,比一张邮票还小。

现代工程师设计电路时,当然不是手工一个个设计晶体管 这不是人力能做到的,1970 年代开始,超大规模集成 (VLSI) 软件 用来自动生成芯片设计,用比如 “逻辑综合” 这种技术,可以放一整个高级组件,比如内存缓存。软件会自动生成电路,做到尽可能高效,许多人认为这是计算 4.0 的开始。

坏消息是,专家们几十年来 一直在预言摩尔定律的终结,现在可能终于接近了。进一步做小,会面临 2 个大问题:

  1. 用光掩膜把图案弄到晶圆上 因为光的波长,精度已达极限。所以科学家在研制波长更短的光源,投射更小的形状;
  2. 当晶体管非常小,电极之间可能只距离几个原子,电子会跳过间隙,这叫:量子隧穿效应。

如果晶体管漏电,就不是好开关。科学家和工程师在努力找解决方法,实验室中已造出小至 1 纳米的晶体管,能不能商业量产依然未知,未来也许能解决。

我非常期待!下周见!

18. 操作系统

i.e. Operating Systems

(。・∀・)ノ゙嗨,我是 Carrie Anne,欢迎收看计算机科学速成课!

1940, 1950 年代的电脑,每次只能运行一个程序。程序员在打孔纸卡上写程序,然后拿到一个计算机房间,交给操作员,等计算机空下来了,操作员会把程序放入,然后运行,输出结果,停机。以前计算机慢,这种手动做法可以接受,运行一个程序通常要几小时,几天甚至几周。但上集说过,计算机越来越快,越来越快 - 指数级增长!很快,放程序的时间比程序运行时间还长,我们需要一种方式让计算机自动运作,于是"操作系统"诞生了。

操作系统,简称 OS(Operating systems),其实也是程序,但它有操作硬件的特殊权限,可以运行和管理其它程序。操作系统一般是开机第一个启动的程序,其他所有程序都由操作系统启动。

操作系统开始于 1950 年代,那时计算机开始变得更强大更流行。第一个操作系统加强了程序加载方式,之前只能一次给一个程序,现在可以一次多个。当计算机运行完一个程序,会自动运行下一个程序,这样就不会浪费时间找下一个程序的纸卡,这叫 批处理 。电脑变得更快更便宜,开始在出现在世界各地,特别是大学和政府办公室。很快,人们开始分享软件,但有一个问题 - 在哈佛 1 号和 ENIAC 那个时代,计算都是一次性的。程序员只需要给那"一台"机器写代码,处理器,读卡器,打印机都是已知的。但随着电脑越来越普遍,计算机配置并不总是相同的,比如计算机可能有相同 CPU,但不同的打印机。这对程序员很痛苦,不仅要担心写程序,还要担心程序怎么和不同型号打印机交互,以及计算机连着的其他设备,这些统称"外部设备" 。和早期的外部设备交互,是非常底层的,程序员要了解设备的硬件细节。加重问题的是,程序员很少能拿到所有型号的设备来测代码,所以一般是阅读手册来写代码,祈祷能正常运行。现在是"即插即用",以前是"祈祷能用"。

这很糟糕,所以为了程序员写软件更容易,操作系统充当软件和硬件之间的媒介

更具体地说,操作系统提供 API 来抽象硬件,叫 “设备驱动程序”,程序员可以用标准化机制和输入输出硬件(I/O)交互。比如,程序员只需调用 print(highscore),操作系统会处理输到纸上的具体细节。

到 1950 年代尾声,电脑已经非常快了。处理器经常闲着,等待慢的机械设备(比如打印机和读卡器)。程序阻塞在 I/O 上,而昂贵的处理器则在度假,就是放松啥也不做。50 年代后期,英国曼彻斯特大学 开始研发世界上第一台超级计算机,Atlas ,他们知道机器会超级快,所以需要一种方式来最大限度的利用它,他们的解决方案是一个程序叫 Atlas Supervisor ,于 1962 年完成。这个操作系统不仅像更早期的批处理系统那样,能自动加载程序,还能在单个 CPU 上同时运行几个程序,它通过调度来做到这一点。假设 Atlas 上有一个游戏在运行,并且我们调用一个函数 print(highscore),它让 Atlas 打印一个叫 highscore 的变量值,让朋友知道 我是最高分冠军。 print 函数运行需要一点时间,大概上千个时钟周期,但因为打印机比 CPU 慢,与其等着它完成操作,Atlas 会把程序休眠,运行另一个程序,最终,打印机会告诉 Atlas, 打印已完成,Atlas 会把程序标记成可继续运行,之后在某时刻会安排给 CPU 运行,并继续 print 语句之后的下一行代码。这样,Atlas 可以在 CPU 上运行一个程序,同时另一个程序在打印数据,同时另一个程序读数据。Atlas 的工程师做的还要多,配了 4 台纸带读取器,4 台纸带打孔机,多达 8 个磁带驱动器。

使多个程序可以同时运行,在单个 CPU 上共享时间,操作系统的这种能力叫 “多任务处理” 。同时运行多个程序有个问题,每个程序都会占一些内存,当切换到另一个程序时,我们不能丢失数据,解决办法是给每个程序分配专属内存块。

举个例子,假设计算机一共有 10000 个内存位置,程序 A 分配到内存地址 0 到 999,而程序 B 分配到内存地址 1000 到 1999,以此类推。如果一个程序请求更多内存,操作系统会决定是否同意,如果同意,分配哪些内存块。这种灵活性很好,但带来一个奇怪的后果,程序 A 可能会分配到非连续的内存块,比如内存地址 0 到 999,以及 2000 到 2999。这只是个简单例子,真正的程序可能会分配到内存中数十个地方,你可能想到了,这对程序员来说很难跟踪。也许内存里有一长串销售额,每天下班后要算销售总额,但列表 存在一堆不连续的内存块里…… 🤬

为了隐藏这种复杂性,操作系统会把内存地址进行 “虚拟化”,这叫 “虚拟内存” ,程序可以假定内存总是从地址 0 开始,简单又一致,而实际物理位置被操作系统隐藏和抽象了。

一层新的抽象!!!

用程序 B 来举例 它被分配了内存地址 1000 到 1999,对程序 B 而言,它看到的地址是 0 到 999,操作系统会自动处理 虚拟内存和物理内存之间的映射。如果程序 B 要地址 42,实际上是物理地址 1042,这种内存地址的虚拟化对程序 A 甚至更有用。在例子中,A 被分配了两块隔开的内存,程序 A 不知道这点,以 A 的视角,它有 2000 个连续地址。当程序 A 读内存地址 999 时 会刚好映射到物理内存地址 999,但如果程序 A 读下一个地址 1000 ,会映射到物理地址 2000 ,这种机制使程序的内存大小可以灵活增减 叫 “动态内存分配” 。对程序来说,内存看起来是连续的。它简化了一切,为操作系统同时运行多个程序 提供了极大的灵活性,给程序分配专用的内存范围,另一个好处是 这样隔离起来会更好。如果一个程序出错,开始写乱七八糟的数据,它只能捣乱自己的内存,不会影响到其它程序,这叫 “内存保护” 。防止恶意软件(如病毒)也很有用,例如,我们不希望其他程序有能力 读或改邮件程序的内存,如果有这种权限 恶意软件可能以你的名义发邮件,甚至窃取个人信息,一点都不好!

Atlas 既有"虚拟内存"也有"内存保护",是第一台支持这些功能的计算机和操作系统!

到 1970 年代,计算机足够快且便宜,大学会买电脑让学生用。计算机不仅能同时运行多个程序,还能让多用户能同时访问。多个用户用"终端"来访问计算机,“终端"只是键盘+屏幕,连到主计算机 终端本身没有处理能力。冰箱大小的计算机可能有 50 个终端,能让 50 个用户使用,这时操作系统不但要处理多个程序,还要处理多个用户。为了确保其中一个人不会占满计算机资源,开发了 分时操作系统 ,意思是 每个用户只能用一小部分处理器,内存等。因为电脑很快 即使拿到 1/50 的资源也足以完成许多任务。

早期分时操作系统中,最有影响力的是 Multics(多任务信息与计算系统),于 1969 年发布。Multics 是第一个,从设计时就考虑到安全的操作系统,开发人员不希望恶意用户访问不该访问的数据,比如学生假装成教授,访问期末考试的文件,这导致 Multics 的复杂度超过当时的平均水准,操作系统会占大约 1 Mb 内存,这在当时很多!可能是内存的一半,只拿来运行操作系统!

Multics 的研究人员之一 Dennis Ritchie 曾说过,“阻碍 Multics 获得商业成功的一个明显问题是 - 从某种方面来说,它被过度设计了,功能太多了” 。所以 Dennis 和另一个 Multics 研究员 Ken Thompson 联手打造新的操作系统,叫 Unix 。他们想把操作系统分成两部分:

  • 首先是操作系统的核心功能,如内存管理,多任务和输入/输出处理 这叫 “内核” ;
  • 第二部分是一堆有用的工具,但它们不是内核的一部分(比如程序和运行库)。

紧凑的内核意味着功能没有那么全面。

Multics 的另一个开发者 Tom Van Vleck 回忆说:“我对 Dennis 说,我在 Multics 写的一半代码都是错误恢复代码”。他说:“Unix 不会有这些东西,如果有错误发生,我们就让内核"恐慌”(panic),当调用它时,机器会崩溃,你得在走廊里大喊,“嘿,重启电脑”!😹

你可能听过 “内核恐慌”(kernel panic),这就是这个词的来源。内核如果崩溃,没有办法恢复,所以调用一个叫"恐慌”(panic)的函数。起初只是打印"恐慌"一词,然后无限循环,这种简单性意味着 Unix 可以在更便宜更多的硬件上运行。

Unix 在 Dennis 和 Ken 工作的贝尔实验室大受欢迎,越来越多开发人员用 Unix 写程序和运行程序,工具数量日益增长。1971 年发布后不久,就有人写了不同编程语言的编译器,甚至文字处理器,使得 Unix 迅速成为 1970~80 年代最流行的操作系统之一。

到 1980 年代早期,计算机的价格 降到普通人买得起,这些叫"个人电脑"或"家庭电脑"。这些电脑比大型主机简单得多,主机一般在大学,公司和政府,因此操作系统也得简单。举例,微软的磁盘操作系统(MS-DOS)只有 160 kB 一张磁盘就可以容纳,于 1981 年发布,成为早期家用电脑最受欢迎的操作系统,虽然缺少"多任务"和"保护内存"这样功能,意味着程序经常使系统崩溃。虽然很讨厌但还可以接受,因为用户可以重启,哪怕是微软 1985 年发布的早期 Windows 虽然在 90 年代很流行,但却缺乏"内存保护",当程序行为不当时,就会"蓝屏",代表程序崩溃的非常严重,把系统也带崩溃了…… 👻👻👻

幸运的是,新版 Windows 有更好的保护,不会经常崩溃。如今的计算机 有现代操作系统,比如 Mac OS X,Windows 10 ,Linux,iOS 和 Android 。虽然大部分设备只有一个人使用 - 你! 操作系统依然有"多任务,“虚拟内存”, “内存保护”,因此可以同时运行多个程序: 一边在浏览器看 YouTube,一边在 Photoshop 修图,用 Spotify 放音乐,同步 Dropbox 。如果没有操作系统这几十年的发展,这些都不可能,当然,我们也需要地方放程序 。

下周会讨论。

19. 内存 & 储存介质

i.e. Memory & Storage

(。・∀・)ノ゙嗨,我是 Carrie Anne,欢迎收看计算机科学速成课!

系列中 我们多次谈到内存(Memory), 甚至在第 6 集设计了一个简单内存。一般来说,电脑内存是 “非永久性”,如果 Xbox 电源线不小心拔掉了,内存里所有数据都会丢失,所以内存叫"易失性"存储器。

我们还没谈过的话题 是存储器(Storage),存储器(Storage)和内存(Memory)有点不同 - 任何写入"存储器"的数据,比如你的硬盘 数据会一直存着,直到被覆盖或删除,断电也不会丢失。存储器是"非易失性"的,以前是"易失性"的速度快,“非易失性"的速度慢。但随着技术发展,两者的差异越来越小。

如今我们认为稀松平常的技术,比如这个 U 盘能低成本+可靠+长时间 存储上 GB 的数据。但以前可不是这样的,最早的存储介质是 打孔纸卡 以及纸卡的亲戚 - 打孔纸带。到 1940 年代,纸卡标准是 80 列 x 12 行,一张卡能存 960 位数据 (80x12=960) 。据我们所知的最大纸卡程序是美国军方的"半自动地面防空系统”,简称 SAGE - 一个在 1958 年投入使用的防空系统,主程序存储在 62,500 个纸卡上,大小 5MB 左右,相当如今手机拍张照。

纸卡用了十几年,因为不用电而且便宜耐用,然而坏处是读取慢,只能写入一次,打的孔无法轻易补上。对于存临时值,纸卡不好用,我们需要更快更大更灵活的存储方式。

J. Presper Eckert 在 1944 年建造 ENIAC 时发明了一种方法,叫"延迟线存储器"(Delay Line Memory),原理如下:拿一个管子装满液体,如水银,管子一端放扬声器,另一端放麦克风,扬声器发出脉冲时会产生压力波,压力波需要时间传播到另一端的麦克风,麦克风将压力波转换回电信号。我们可以用压力波的传播延迟来存储数据!假设有压力波代表 1,没有代表 0 ,扬声器可以输出 1​​010 0111 。压力波沿管子传播,过了一会儿,撞上麦克风,将信号转换回 1 和 0 ,如果加一个电路,连接麦克风和扬声器,再加一个放大器(Amplifier)来弥补信号衰弱,就能做一个存储数据的循环。信号沿电线传播几乎是瞬时的,所以任何时间点只显示 1 bit 数据,但管子中可以存储多个位 (bit) 。忙完 ENIAC 后,Eckert 和同事 John Mauchly 着手做一个更大更好的计算机叫 EDVAC,使用了延迟线存储器,总共有 128 条延迟线,每条能存 352 位(bits),总共能存 45,000 位 (bit) ,对 1949 年来说还不错!这使得 EDVAC 成为最早的 “存储程序计算机” 之一,我们在第 10 集讨论过。

但"延迟线存储器"的一大缺点是 - 每一个时刻只能读一位 (bit) 数据,如果想访问一个特定的 bit,比如第 112 位 (bit) 你得等待它从循环中出现,所以又叫 “顺序存储器"或"循环存储器”,而我们想要的是 “随机存取存储器” 可以随时访问任何位置。增加内存密度也是一个挑战,把压力波变得更紧密,意味着更容易混在一起,所以出现了其他类型的 “延迟线存储器”,如 “磁致伸缩延迟存储器”,用金属线的振动来代表数据,通过把线卷成线圈,1 英尺× 1 英尺的面积能存储大概 1000 位 (bit),然而,延迟线存储器在 1950 年代中期就基本过时了,因为出现了新技术,性能,可靠性和成本都更好 - “磁芯存储器” 🧲 ,用了像甜甜圈的小型磁圈,如果给磁芯绕上电线,并施加电流,可以将磁化在一个方向,如果关掉电流,磁芯保持磁化;如果沿相反方向施加电流,磁化的方向(极性)会翻转,这样就可以存 1 和 0!如果只存 1 位不够有用,所以把小甜甜圈排列成网格,有电线负责选行和列,也有电线贯穿每个磁芯,用于读写一位 (bit)。我手上有一块磁芯存储器,每个黄色方格 有 32 行 x32 列的磁芯 每个磁芯存 1 位数据,所以能存 1024 位 (bit) (32x32=1024),总共 9 个黄色方格,所以这块板子最多能存 9216 位 (bit) (1024x9=9216),换算过来大约是 9 千字节 (9216 bit ~= 9 kb)。磁芯内存的第一次大规模运用是 1953 年麻省理工学院的 Whirlwind 1 计算机,磁芯排列是 32×32,用了 16 块板子,能存储大约 16000 位 (bit)。更重要的是,不像"延迟线存储器" 磁芯存储器能随时访问任何一位 (bit),这在当时非常了不起!

“磁芯存储器” 从 1950 年代中期开始成为主流 流行了 20 多年,而且一般还是手工编织的!刚开始时,存储成本大约 1 美元 1 位 (bit) 到 1970 年代,下降到 1 美分左右,不幸的是,即使每位 1 美分也不够便宜,之前提过,现代手机随便拍张照片都有 5 MB,5MB 约等于 4000 万 bit。你愿意花 40 万美元在"磁芯存储器"上存照片吗?如果你有这么多钱,你知道 Crash Course 在 Patreon 有赞助页吗?对吧?你懂的!🤑

总之,当时对存储技术进行了大量的研究。到 1951 年,Eckert 和 Mauchly 创立了自己的公司,设计了一台叫 UNIVAC 的新电脑,最早进行商业销售的电脑之一。它推出了一种新存储:磁带,磁带是纤薄柔软的一长条磁性带子 卷在轴上,磁带可以在"磁带驱动器"内前后移动,里面有一个"写头"绕了电线,电流通过产生磁场,导致磁带的一小部分被磁化。电流方向决定了极性,代表 1 和 0 。还有一个"读头",可以非破坏性地检测极性 。UNIVAC 用了半英寸宽,8 条并行的磁带,磁带每英寸可存 128 位数据,每卷有 1200 英尺长,意味着一共可以存 1500 万位左右 - 接近 2 兆字节!(2 MB) 虽然磁带驱动器很贵,但磁带又便宜又小,因此磁带至今仍用于存档。磁带的主要缺点是访问速度 - 磁带是连续的,必须倒带或快进到达特定位置,可能要几百英尺才能得到某个字节 (byte),这很慢!🐢!

1950,60 年代,有个类似技术是 “磁鼓存储器”。有金属圆筒,盖满了磁性材料以记录数据,滚筒会持续旋转,周围有数十个读写头,等滚筒转到正确的位置读写头会读或写 1 位 (bit) 数据,为了尽可能缩短延迟,鼓轮每分钟上千转!到 1953 年,磁鼓技术飞速发展,可以买到存 80,000 位的"磁鼓存储器" - 也就是 10 KB 。但到 1970 年代 “磁鼓存储器” 不再生产,然而,磁鼓导致了硬盘的发展。硬盘和磁鼓很相似

which are very similar, but use a different geometric configuration. 然而,磁鼓导致了硬盘的发展 硬盘和磁鼓很相似,不过硬盘用的是盘,不像磁鼓用圆柱体,因此得名。原理是一样的,磁盘表面有磁性,写入头和读取头,可以处理上面的 1 和 0 。硬盘的好处是薄,可以叠在一起,提供更多表面积来存数据。IBM 对世上第一台磁盘计算机就是这样做的 - RAMAC 305 ,顺便一说名字不错,它有 50 张 24 英寸直径的磁盘,总共能存 5 MB 左右…… 太棒啦!终于能存一张现代手机的照片了 🖼 !这年是 1956 年!要访问某个特定 bit ,一个读/写磁头会向上或向下移动,找到正确的磁盘,然后磁头会滑进去,就像磁鼓存储器一样,磁盘也会高速旋转,所以读写头要等到正确的部分转过来。RAMAC 305 访问任意数据,平均只要六分之一秒左右,也叫寻道时间。虽然六分之一秒对存储器来说算不错,但对内存来说还不够快,所以 RAMAC 305 还有"磁鼓存储器"和"磁芯存储器"。

这是"内存层次结构"的一个例子,一小部分高速+昂贵的内存 ,一部分稍慢+相对便宜些的内存 ,还有更慢+更便宜的内存,这种混合在成本和速度间取得平衡。

1970 年代,硬盘大幅度改进并变得普遍,如今的硬盘可以轻易容纳 1TB 的数据,能存 20 万张 5MB 的照片!网上最低 40 美元就可以买到,每 bit 成本 0.0000000005 美分,比磁芯内存 1 美分 1 bit 好多了!另外,现代硬盘的平均寻道时间低于 1/100 秒。我简单地提一下硬盘的亲戚,软盘,除了磁盘是软的,其他基本一样。你可能见过某些程序的保存图标是一个软盘,软盘曾经是真实存在的东西!软盘是为了便携,在 1970~1990 非常流行,如今当杯垫挺不错的。密度更高的软盘,如 Zip Disks,在 90 年代中期流行起来,但十年内就消失了。

光学存储器于 1972 年出现,12 英寸的"激光盘"。你可能对后来的产品更熟:光盘(Compact Disk)(简称 CD),以及 90 年代流行的 DVD,功能和硬盘软盘一样,都是存数据,但用的不是磁性。光盘表面有很多小坑,造成光的不同反射,光学传感器会捕获到,并解码为 1 和 0。如今,存储技术在朝固态前进,没有机械活动部件。比如这个硬盘,以及 U 盘,里面是集成电路,我们在第 15 集讨论过。

第一个 RAM 集成电路出现于 1972 年,成本每比特 1 美分,使"磁芯存储器"迅速过时。如今成本下降了更多,机械硬盘 被 固态硬盘 逐渐替代,简称 SSD(Solid State Drives)。由于 SSD 没有移动部件,磁头不用等磁盘转,所以 SSD 访问时间低于 1/1000 秒,这很快!🐇 但还是比 RAM 慢很多倍,所以现代计算机 仍然用存储层次结构。

我们从 1940 年代到现在进步巨大,就像在第 14 集讨论过的 晶体管数量和摩尔定律,内存和存储技术也有类似的趋势,从早期每 MB 成本上百万美元,下滑到 2000 年只要几分钱,如今远远低于 1 分钱,完全没有打孔纸卡,你能想象 SEGA 的纸卡房间风一吹会怎样吗? 62,500 张卡 …… 我想都不敢想 😂

:: 不同的介质,不同的方法,归其本质,都是为了区分两种显著的状态,分别标识 0 和 1 。有了 0 和 1 ,就有了整个数据世界。

我们下周见。

20. 文件系统

i.e. Files & File Systems

(。・∀・)ノ゙嗨,我是 Carrie Anne,欢迎收看计算机科学速成课!

上集我们讲了数据存储,磁带和硬盘这样的技术,可以在断电状态长时间存上万亿个位,非常合适存一整块有关系的数据,或者说"文件"。你肯定见过很多种文件,比如文本文件,音乐文件,照片和视频。今天,我们要讨论文件到底是什么 以及计算机怎么管理文件。

随意排列文件数据完全没问题,但按格式排会更好,这叫 “文件格式” 。你可以发明自己的文件格式,程序员偶尔会这样做,但最好用现成标准,比如 JPEG 和 MP3 。来看一些简单文件格式,最简单的是文本文件,也叫 TXT 文件,里面包含的是。.. 文字 (惊喜吧)。就像所有其它文件, 文本文件只是一长串二进制数 ,原始值看起来会像这样:

可以转成十进制看,但帮助不大,解码数据的关键是 ASCII 编码 - 一种字符编码标准,第 4 集讨论过。第一个值 72 在 ASCII 中是大写字母 H ,以此类推解码其他数字 。

来看一个更复杂的例子:波形 (Wave) 文件,也叫 WAV 它存音频数据。在正确读取数据前,需要知道一些信息,比如码率 (bit rate),以及是单声道还是立体声。关于数据的数据,叫 “元数据” (meta data) 。元数据存在文件开头,在实际数据前面,因此也叫 文件头 (Header) 。WAV 文件的前 44 个字节长这样:

有的部分总是一样的,比如写着 WAVE 的部分,其他部分的内容,会根据数据变化。音频数据紧跟在元数据后面,是一长串数字,数字代表每秒捕获多次的声音幅度。如果想学声音的基础知识,可以看物理速成课(Crash Course Physics)第 18 集,举个例子,看一下"你好"的波形,现在捕获到了一些声音,我们放大看一下。

电脑和手机麦克风,每秒可以对声音进行上千次采样,每次采样可以用一个数字表示,声压越高数字越大,也叫"振幅",WAVE 文件里存的就是这些数据!每秒上千次的振幅!播放声音文件时,扬声器会产生相同的波形 - “你好!”

现在来谈谈位图 (Bitmap),后缀 .bmp,它存图片,计算机上,图片由很多个叫"像素"的方块组成,每个像素由三种颜色组成:红,绿,蓝,叫"加色三原色",混在一起可以创造其它颜色。就像 WAV 文件一样,BMP 文件开头也是元数据有:图片宽度,图片高度,颜色深度,举例,假设元数据说图是 4 像素宽 x 4 像素高,颜色深度 24 位、8 位红色,8 位绿色,8 位蓝色,提醒一下,8 位 (bit) 和 1 字节 (byte) 是一回事。一个字节能表示的最小数是 0,最大 255 。图像数据看起来会类似这样:来看看第一个像素的颜色 - 红色是 255,绿色是 255,蓝色也是 255,这等同于全强度红色,全强度绿色和全强度蓝色,混合在一起变成白色,所以第一个像素是白色!下一个像素的红绿蓝值,或 RGB 值 255,255,0 是黄色! 下一个像素的红绿蓝值,或 RGB 值 255,255,0 是黄色! 下一个像素是 0,0,0 ,黑色 !下一个是黄色 !因为元数据说图片是 4x4 我们知道现在到了第一行结尾,所以换一行,下一个 RGB 值是 255,255,0 ,又是黄色!好,我们读完剩下的像素 - 一个低分辨率的吃豆人。

刚才显然只是一个简单例子,但这张图片也可以用 BMP 存。我想再次强调,不管是文本文件,WAV,BMP,或是我们没时间讨论的其他格式。 文件在底层全是一样的: 一长串二进制 。为了知道文件是什么,文件格式至关重要。

现在你对文件更了解了 我们接下来讨论计算机怎么存文件。

虽然硬件可能是磁带,磁鼓,磁盘或集成电路,通过软硬件抽象后,可以看成一排能存数据的桶。在很早期时,计算机只做一件事,比如算火炮射程表。整个储存器就像一整个文件,数据从头存到尾,直到占满,但随着计算能力和存储容量的提高存多个文件变得非常有用,最简单的方法是把文件连续存储。这样能用,但怎么知道文件开头和结尾在哪里?储存器没有文件的概念,只是存储大量位,所以为了存多个文件,需要一个特殊文件,记录其他文件的位置,这个特殊文件有很多名字,这里泛称 “目录文件” 🗃 。这个文件经常存在最开头,方便找 - 位置 0!目录文件里,存所有其他文件的名字,格式是 文件名 + 一个句点 + 扩展名 ,比如 BMP 或 WAV 。

扩展名帮助得知文件类型,目录文件还存文件的元数据,比如创建时间,最后修改时间,文件所有者是谁、是否能读/写、或读写都行。最重要的是,目录文件有文件起始位置和长度,如果要添加文件,删除文件,更改文件名等,必须更新目录文件。就像书的目录,如果缩短或移动了一个章节,要更新目录,不然页码对不上。

文件名 + 一个句点 + 扩展名

文件起始位置和长度
创建时间
最后修改时间
文件所有者是谁
是否能读/写、或读写都行
……

目录文件,以及对目录文件的管理,是一个非常简单的文件系统例子!文件系统专门负责管理文件!

刚刚的例子叫"平面文件系统" 因为文件都在同一个层次,平的!当然,把文件前后排在一起有个问题。如果给 todo.txt 加一点数据,会覆盖掉后面 carrie.bmp 的一部分,所以现代文件系统会做两件事:

  1. 把空间划分成一块块,导致有一些 “预留空间” 可以方便改动,同时也方便管理(用这样的方案,目录文件要记录文件在哪些块里);
  2. 拆分文件,存在多个块里。

假设打开 todo.txt 加了些内容、文件太大存不进一块里,我们不想覆盖掉隔壁的块,所以文件系统会分配 一个没使用的块,容纳额外的数据。目录文件会记录不止一个块,而是多个块,只要分配块,文件可以轻松增大缩小,如果你看了第 18 集 操作系统 这听起来很像"虚拟内存",概念上讲的确很像!假设想删掉 carrie.bmp 只需要在目录文件删掉那条记录,让一块空间变成了可用,注意这里没有擦除数据,只是把记录删了,之后某个时候,那些块会被新数据覆盖,但在此之前,数据还在原处,所以计算机取证团队可以"恢复"数据,虽然别人以为数据已经"删了", 狡猾!😈 假设往 todo.txt 加了更多数据,所以操作系统分配了一个新块,用了刚刚 carrie.bmp 的块,现在 todo.txt 在 3 个块里,隔开了,顺序也是乱的,这叫 碎片。碎片是增/删/改文件导致的,不可避免,对很多存储技术来说,碎片是坏事。如果 todo.txt 存在磁带上,读取文件要先读块 1, 然后快进到块 5,然后往回转到块 2 ,来回转个半天。现实世界中,大文件可能存在数百个块里,你可不想等五分钟才打开文件,答案是碎片整理!这个词听起来好像很复杂,但实际过程很简单。以前看计算机做碎片整理,真的很有趣!计算机会把数据来回移动,排列成正确的顺序,整理后 todo.txt 在 1 2 3,方便读取。

目前只说了平面文件系统,文件都在同一个目录里。如果存储空间不多,这可能就够用了,因为只有十几个文件。但上集说过,容量爆炸式增长,文件数量也飞速增长,很快,所有文件都存在同一层变得不切实际。就像现实世界、相关文件放在同一个文件夹会方便很多,然后文件夹套文件夹,这叫 “分层文件系统” ,你的计算机现在就在用这个。

实现方法有很多种,我们用之前的例子来讲重点好了,最大的变化是 目录文件不仅要指向文件,还要指向目录。我们需要额外元数据来区分开文件和目录,这个目录文件在最顶层,因此叫根目录,所有其他文件和文件夹,都在根目录下。

图中可以看到根目录文件有 3 个文件 2 个子文件夹:“音乐"和"照片”,如果想知道"音乐"文件夹里有什么 必须去那边读取目录文件(格式和根目录文件一样),有很多好歌啊!

除了能做无限深度的文件夹,这个方法也让我们可以轻松移动文件,如果想把 theme.wav 从根目录移到音乐目录,不用移动任何数据块,只需要改两个目录文件,一个文件里删一条记录,另一个文件里加一条记录,theme.wav 依然在块 5 。

文件系统的几个重要概念,现在介绍完了。它提供了一层新抽象!

文件系统使我们不必关心 文件在磁带或磁盘的具体位置,整理和访问文件更加方便。我们像普通用户一样直观操纵数据,比如打开和整理文件,接下来几集也会从用户角度看问题。

下周见。

21. 压缩

i.e. Compression

(。・∀・)ノ゙嗨,我是 Carrie Anne,欢迎收看计算机科学速成课!

上集我们讨论了文件格式,如何编码文字,声音,图片,还举了具体例子 .txt .wav .bmp 。这些格式虽然管用,而且现在还在用,但它们的简单性意味着效率不高。我们希望文件能小一点,这样能存大量文件,传输也会快一些。等邮件附件下载烦死人了,解决方法是 压缩,把数据占用的空间压得更小,用更少的位 (bit) 来表示数据。

听起来像魔法,但其实是计算机科学!

我们继续用上集的 吃豆人例子,图像是 4 像素 x4 像素。之前说过,图像一般存成一长串像素值,为了知道一行在哪里结束 图像要有元数据,写明尺寸等属性,但为了简单起见,今天忽略这些细节,如果红绿蓝都是 255 会得到白色,如果混合 255 红色和 255 绿色,会得到黄色,这个图像有 16 个像素 (4x4), 每个像素 3 个字节,总共占 48 个字节(16x3=48),但我们可以压缩到少于 48 个字节。

一种方法是 减少重复信息,最简单的方法叫 游程编码 (Run-Length Encoding),适合经常出现相同值的文件。比如吃豆人 有 7 个连续黄色像素,与其全存下来:黄色,黄色,黄色。.. 可以插入一个额外字节,代表有 7 个连续黄色像素,然后删掉后面的重复数据。为了让计算机能分辨哪些字节是"长度",哪些字节是"颜色",格式要一致,所以我们要给所有像素前面标上长度。有时候数据反而会变多,但就这个例子而言,我们大大减少了字节数,之前是 48 现在是 24 ,小了 50%!省了很多空间!还有,我们没有损失任何数据 我们可以轻易恢复到原来的数据,这叫 “无损压缩” ,没有丢失任何数据,解压缩后,数据和压缩前完全一样。

我们来看另一种无损压缩,它用更紧凑的方式表示数据块,有点像 “别忘了变厉害” 简写成 DFTBA ,为此,我们需要一个字典,存储"代码"和"数据"间的对应关系。我们看个例子,我们可以把图像看成一块块,而不是一个个像素。为了简单,我们把 2 个像素当成 1 块(占 6 个字节),但你也可以定成其他大小。我们只有四对: 白黄 黑黄 黄黄 白白 ,我们会为这四对 生成紧凑代码 (compact codes) 。有趣的是,这些块的出现频率不同。1950 年代 大卫·霍夫曼 发明了一种高效编码方式叫 “霍夫曼树”(Huffman Tree),当时他是麻省理工学院的学生,算法是这样的。

首先,列出所有块和出现频率,每轮选两个最低的频率,这里 黑黄 和 白白 的频率最低,它们都是 1 ,可以把它们组成一个树,总频率 2 ,现在完成了一轮算法。现在我们重复这样做,这次有 3 个可选,就像上次一样,选频率最低的两个,放在一起,并记录总频率。好,我们快完成了。这次很简单,因为只有 2 个选择,把它们组合成一棵树就完成了!

现在看起来像这样,它有一个很酷的属性:按频率排列,频率低的在下面。现在有了一棵树,你可能在想 “怎么把树变成字典?”

我们可以把每个分支用 0 和 1 标注,就像这样。现在可以生成字典,黄黄 编码成 0 ,白黄 编码成 10 ,黑黄 编码成 110 ,白白 编码成 111 。酷的地方是它们绝对不会冲突,因为树的每条路径是唯一的,意味着代码是"无前缀"的,没有代码是以另一个代码开头的,现在我们来压缩!注意是位 (bit)! 不是字节 (byte)! 14 位 (bit) 还不到 2 个字节 (byte)!但,先别急着开香槟!字典也要保存下来,否则 14 bit 毫无意义,所以我们把字典 加到 14 bit 前面,就像这样。

现在加上字典,图像是 30 个字节 (bytes) 比 48 字节好很多。

“消除冗余"和"用更紧凑的表示方法”,这两种方法通常会组合使用。几乎所有无损压缩格式都用了它们,比如 GIF, PNG, PDF, ZIP 。

游程编码 和 字典编码 都是无损压缩!压缩时不会丢失信息,解压后,数据和之前完全一样。无损对很多文件很重要,比如我给你发了个压缩的 word 文档你解压之后发现内容变了,这就很糟糕了。但其他一些文件,丢掉一些数据没什么关系,丢掉那些人类看不出区别的数据。大多数有损压缩技术,都用到了这点。实际细节比较复杂,所以我们讲概念就好。以声音为例,你的听力不是完美的,有些频率我们很擅长,其他一些我们根本听不见,比如超声波,除非你是蝙蝠。举个例子,如果录音乐,超声波数据都可以扔掉 因为人类听不到超声波,另一方面,人类对人声很敏感,所以应该尽可能保持原样。低音介于两者之间,人类听得到,但不怎么敏感,一般是感觉到震动。有损音频压缩利用这一点,用不同精度编码不同频段,听不出什么区别,不会明显影响体验,音乐发烧友估计要吐槽了!日常生活中你会经常碰到这类音频压缩,所以你在电话里的声音和现实中不一样,压缩音频是为了让更多人能同时打电话,如果网速变慢了,压缩算法会删更多数据,进一步降低声音质量,所以 Skype 通话有时听起来像机器人,和没压缩的音频格式相比,比如 WAV 或 FLAC ( 这下音乐发烧友满意了),压缩音频文件如 MP3,能小 10 倍甚至更多。省了超多空间!

所以我的旧 iPod 上有一堆超棒的歌,别批判我!

这种删掉人类无法感知的数据的方法,叫 “感知编码” 。它依赖于人类的感知模型,模型来自"心理物理学"领域,这是各种"有损压缩图像格式"的基础,最著名的是 JPEG 。就像听力一样,人的视觉系统也不是完美的。我们善于看到尖锐对比,比如物体的边缘,但我们看不出颜色的细微变化。JPEG 利用了这一点,把图像分解成 8x8 像素块,然后删掉大量高频率空间数据。举个例子,这是导演的狗,面面,超可爱!我们来看其中一个 8x8 像素,几乎每个像素都和相邻像素不同,用无损技术很难压缩,因为太多不同点了,很多小细节,但人眼看不出这些细节,因此可以删掉很多,用这样一个简单的块来代替。这看起来一样,但可能只占 10%的原始数据。我们可以对所有 8x8 块做一样的操作,图片依然可以认出是一只狗,只是更粗糙一些,以上例子比较极端,进行了高度压缩,只有原始大小的八分之一。通常你可以取得平衡,图片看起来差不多,但文件小不少。你看得出两张图的区别吗?估计看不出。

但我想提一下,视频压缩也造成了影响。毕竟你现在在看视频啊,视频只是一长串连续图片 所以图片的很多方面也适用于视频,但视频可以做一些小技巧。因为帧和帧之间很多像素一样,但视频可以做一些小技巧 因为帧和帧之间很多像素一样,比如我后面的背景!这叫 时间冗余 ,视频里不用每一帧都存这些像素,可以只存变了的部分,当帧和帧之间有小小的差异时,比如后面这个频率发生器,很多视频编码格式,只存变化的部分,这比存所有像素更有效率 - 利用了帧和帧之间的相似性。更高级的视频压缩格式会更进一步,找出帧和帧之间相似的补丁,然后用简单效果实现,比如移动和旋转,变亮和变暗。如果我这样摆手,视频压缩器会识别到相似性,用一个或多个补丁代表我的手,然后帧之间直接移动这些补丁,所以你看到的是我过去的手(不是实时的),有点可怕,但数据量少得多。MPEG-4 是常见标准,可以比原文件小 20 倍到 200 倍,但用补丁的移动和旋转来更新画面。当压缩太严重时会出错,没有足够空间更新补丁内的像素。即使补丁是错的,视频播放器也会照样播放,导致一些怪异又搞笑的结果,你肯定见过这些。

总的来说,压缩对大部分文件类型都有用

从这个角度来讲,人类不完美的视觉和听觉 也算有用。学习压缩非常重要 因为可以高效存储图片,音乐,视频。如果没有压缩,在 YouTube 看"明星拼车唱歌"几乎不可能,因为你的带宽可能不够(会很卡) 而且供应商不愿意免费传输那么多数据。现在你知道为什么打 Skype 电话,有时像在和恶魔通话。

下周见。

22. 命令行界面

i.e. Keyboards & Command Line Interfaces

(。・∀・)ノ゙嗨,我是 Carrie Anne,欢迎收看计算机科学速成课!

我们之前讨论过输入输出 ,但都是计算机组件互相输入输出,比如 RAM 输出数据,或输指令进 CPU 。我们还没讲来自人类的输入,也没讲怎么从电脑中拿出信息,除了用打孔纸卡。当然,有很多种 “输入输出设备” , 让我们和计算机交互,它们在人类和机器间提供了界面。如今有整个学科专门研究这个,叫 “人机交互”。界面对用户体验非常重要,所以是我们接下来几集的重点。

在系列开头的几集,我们提过,早期机械计算设备用齿轮,旋钮和开关等机械结构来输入输出,这些就是交互界面。甚至早期电子计算机,比如 Colossus 和 ENIAC,也是用一大堆机械面板和线来操作,输入一个程序可能要几星期,还没提运行时间。运行完毕后想拿出数据,一般是打印到纸上。打印机超有用,甚至查尔斯·巴贝奇都给差分机专门设计了一个,那可是 1820 年代!

然而,到 1950 年代,机械输入完全消失,因为出现了打孔纸卡和磁带,但输出仍然是打印到纸上,还有大量指示灯,在运行中提供实时反馈。那个时代的特点是 ,尽可能迁就机器 ,对人类好不好用是其次。打孔纸带就是个好例子,就是为了方便计算机读取,纸带是连续的,方便机器处理。纸孔可以方便地用机械或光学手段识别,纸孔可以编码程序和数据,当然,人类不是以纸孔方式思考的。所以负担放到了程序员身上,他们要花额外时间和精力转成计算机能理解的格式,一般需要额外人员和设备帮忙。要注意的是,基本上 1950 年前的早期计算机,“输入"的概念很原始,是的,的确是人类负责输入程序和数据,但计算机不会交互式回应。程序开始运行后会一直运行,直到结束。因为机器太贵了,不能等人类慢慢敲命令和给数据,要同时放入程序和数据。

这在 1950 年代晚期开始发生变化。一方面,小型计算机变得足够便宜,让人类来回和计算机交互变得可以接受,交互式就是人和计算机之间来回沟通。而另一方面,大型计算机变得更快,能同时支持多个程序和多个用户,这叫"多任务"和"分时系统”。

但交互式操作时,计算机需要某种方法来获得用户输入,所以借用了当时已经存在的数据录入机制:键盘!当时,打字机已经存在几个世纪了,但现代打字机是克里斯托弗·莱瑟姆·肖尔斯在 1868 年发明的,虽然到 1874 年才完成设计和制造,但之后取得了商业成功。肖尔斯的打字机用了不寻常的布局,QWERTY ,名字来自键盘左上角按键,为什么这么设计?有很多猜测。最流行的理论是,这样设计是为了把常见字母放得远一些,避免按键卡住。这个解释虽然省事,但可能是错的,或至少不够全面。事实上,QWERTY 把很多常见字母放在了一起,比如 TH 和 ER 。我们知道 肖尔斯和他的团队设计了很多版才进化到这个布局。总之,肖尔斯的打字机取得了成功 ,所以其它公司很快开始抄他的设计。

:: 这……

过去一个世纪有不少新的键盘布局被发明,宣称各种好处,但人们已经熟悉了 QWERTY 布局 ,根本不想学新布局,这是经济学家所说的 转换成本。所以现在都快 1 个半世纪了 ,我们还在用 QWERTY 键盘布局。我应该提一下,QWERTY 不是通用的,有很多变体,比如法国 AZERTY 布局,以及中欧常见的 QWERTZ 布局。有趣的是,肖尔斯根本没想到打字会比手写快,手写速度大约是每分钟 20 个,打字机主要为了易读性和标准化,而不是速度,然而随着打字机成为办公室标配 ,对快速打字的渴望越来越大。

有两个重大进步解放了打字的潜力。

1880 年左右,辛辛那提速记学院一名叫伊丽莎白·朗利的老师开始推广十指打字,比一个手指打字要移动的距离短得多,所以速度更快。几年后,弗兰克·爱德华·麦克格林 盐湖城的一位联邦法庭书记学会了盲打,打字时不用看键盘。1888 年,麦格高林赢了备受关注的打字速度比赛,之后"十指盲打"开始流行。专业打字员每分钟 100 字以上,比手写快多了!而且清晰又整洁!虽然人类擅长用打字机,但我们没法把打字机塞到计算机面前,让它打字,计算机又没有手指。所以早期计算机用了一种特殊打字机,是专门用来发电报的,叫电传打字机。这些打字机是强化过的,可以用电报线发送和接收文本,按一个字母,信号会通过电报线,发到另一端,另一端的电传打字机会打出来,使得两人可以长距离沟通,基本是个蒸汽朋克版聊天室。因为电传打字机有电子接口,稍作修改就能用于计算机,电传交互界面在 1960~1970 很常见,用起来很简单,输入一个命令,按回车,然后计算机会输回来。用户和计算机来回"对话",这叫 “命令行界面” 。它是最主要的人机交互方式,一直到 1980 年代,用电传打字机的命令行交互,类似这样:

> 用户可以输入各种命令
> 我们来看几个命令,先看当前目录有什么文件
> 输入命令 ls,名字来自 list 的缩写
> 然后计算机会列出 当前目录里的所有文件
> 如果想看 secretStarTrekDiscoveryCast.txt 有什么
> 要用另一个命令 显示文件内容
> unix 用 cat 命令显示文件内容 cat 是连接 (concatenate) 的缩写
> 然后指定文件名,指定的方法是写在 cat 命令后面 传给命令的值叫 参数
> 
> 如果同一个网络里有其他人
> 你可以用 finger 命令找朋友 就像是个很原始的"找朋友" App
……

电传打字机直到 1970 年代左右都是主流交互方式,尽管屏幕最早出现在 1950 年代,但对日常使用太贵而且分辨率低,然而因为针对普通消费者的电视机开始量产,同时处理器与内存也在发展。到 1970 年代,屏幕代替电传打字机变得可行,但与其为屏幕专门做全新的标准,工程师直接用现有的电传打字机协议,屏幕就像无限长度的纸,除了输入和输出字,没有其它东西。 协议是一样的,所以计算机分不出是纸还是屏幕 ,这些"虚拟电传打字机"或"玻璃电传打字机"叫 终端 。到 1971 年,美国大约有 7 万台电传打字机 以及 7 万个终端,屏幕又好又快又灵活。如果删一个错别字,会立刻消失,所以到 1970 年代末,屏幕成了标配。你也许会想,命令行界面太原始了,做不了什么有意思的事。即便只有文字,程序员也找到了一些方法,让它变得有趣一些。

早期的著名交互式文字游戏 Zork ,出现于 1977 年。早期游戏玩家需要丰富的想象力,想像自己身在虚构世界,比如"四周漆黑一片,附近可能有怪物会吃掉你"。我们用命令行玩玩看,就像之前,我们可以用 ls 命令,看当前目录有什么,然后用 cd 命令,进入游戏文件夹 cd 的意思是 “改变文件夹”(change directory),再用 ls 看有哪些游戏。超棒!我们有"冒险旅程"!(adventure)。想运行这个程序,只需要输入它的名字。在程序自行停止或我们主动退出前,它会接管命令行。

你现在看到的,是"巨大洞穴冒险"这款游戏的真实输出,由 Will Crowther 在 1976 年开发。游戏中,玩家可以输入 1 个词或 2 个词的命令来移动人物,和其他东西交互,捡物品等,然后游戏会像旁白一样,输出你的当前位置,告诉你能做什么动作,以及你的动作造成的结果,有些动作会导致死亡!原始版本只有 66 个地方可供探索,但它被广泛认为是最早的互动式小说。游戏后来从纯文字进化成多人游戏 简称 MUD,或多人地牢游戏(Multi-User Dungeons),是如今 MMORPG 的前辈 (大型多人在线角色扮演游戏, massive, multiplayer online role playing games)。如果你想了解游戏史,我们有游戏速成课 主持人 Andre Meadows 。

命令行界面虽然简单,但十分强大。

编程大部分依然是打字活, 所以用命令行比较自然,因此,即使是现在大多数程序员工作中依然用命令行界面,而且用命令行访问远程计算机 是最常见的方式, 比如服务器在另一个国家。如果你用 Windows, macOS, Linux ,你的计算机有命令行界面,但你可能从来没用过,你可以在 Windows 搜索栏中输入 cmd,或在 Mac 上搜 Terminal ,然后你可以装 Zork 玩!

现在你知道了,早期计算机的发展是如何影响到现在的。

想想要是手机没有 QWERTY 键盘 ,在 Instagram 给图片配标题可就麻烦了。但我们还有一个重要话题没讲,美妙的图形界面!这是下周的主题!

下周见。

23. 屏幕 & 2D 图形显示

i.e. Screens&2D Graphics

(。・∀・)ノ゙嗨,我是 Carrie Anne,欢迎收看计算机科学速成课!

这台 1960 年的 PDP-1 是一个早期图形计算机的好例子,你可以看到左边是柜子大小的电脑,中间是电传打字机,右边是一个圆形的屏幕,注意它们是分开的,因为当时文本任务和图形任务是分开的。事实上,早期的屏幕无法显示清晰的文字,而打印到纸上有更高的对比度和分辨率。早期屏幕的典型用途是跟踪程序的运行情况,比如寄存器的值,如果用打印机一遍又一遍打印出来没有意义,不仅费纸而且慢。另一方面,屏幕更新很快,对临时值简直完美。但屏幕很少用于输出计算结果,结果一般都打印到纸上,或其它更永久的东西上。

但屏幕超有用!到 1960 年代,人们开始用屏幕做很多酷炫的事情。几十年间出现了很多显示技术,但最早最有影响力的是阴极射线管(CRT,Cathode Ray Tubes)。原理是把电子发射到有磷光体涂层的屏幕上,当电子撞击涂层时,会发光几分之一秒,由于电子是带电粒子,路径可以用磁场控制,屏幕内用板子或线圈把电子引导到想要的位置,上下左右都行。既然可以这样控制,有 2 种方法绘制图形 :

  1. 引导电子束描绘出形状,这叫 “矢量扫描” 。因为发光只持续一小会儿,如果重复得足够快,可以得到清晰的图像;
  2. 按固定路径,一行行来,从上向下,从左到右,不断重复,只在特定的点打开电子束,以此绘制图形,这叫 “光栅扫描” 。用这种方法,可以用很多小线段绘制形状,甚至文字。

最后,因为显示技术的发展,我们终于可以在屏幕上显示清晰的点,叫"像素" 。液晶显示器,简称 LCD(Liquid Crystal Displays),和以前的技术相当不同,但 LCD 也用光栅扫描,每秒更新多次,像素里红绿蓝的颜色。有趣的是,很多早期计算机不用像素 - 不是技术做不到,而是因为像素占太多内存。 200 像素×200 像素的图像,有 40,000 个像素,哪怕每个像素只用一个 bit 表示 代表黑色或白色,连灰度都没有!会占 40,000 bit ,内存比 PDP-1 全部内存的一半还多,所以计算机科学家和工程师,得想一些技巧来渲染图形,等内存发展到足够用。所以 早期计算机不存大量像素值,而是存符号,80x25 个符号最典型,总共 2000 个字符。如果每个字符用 8 位表示,比如用 ASCII ,总共才 16000 位,这种大小更合理。为此,计算机需要额外硬件来从内存读取字符,转换成光栅图形,这样才能显示到屏幕上,这个硬件叫 “字符生成器”,基本算是第一代显卡。它内部有一小块只读存储器,简称 ROM ,存着每个字符的图形,叫 “点阵图案”。如果图形卡看到一个 8 位二进制,发现是字母 K ,那么会把字母 K 的点阵图案光栅扫描显示到屏幕的适当位置。为了显示,“字符生成器” 会访问内存中一块特殊区域,这块区域专为图形保留,叫 屏幕缓冲区 。程序想显示文字时,修改这块区域里的值就行,这个方案用的内存少得多,但也意味着只能画字符到屏幕上。即使有这样限制 ,人们用 ASCII 艺术发挥了很多创意!也有人用字符模仿图形界面,用下划线和加号来画盒子,线,和其他简单形状,但字符集实在太小,做不了什么复杂的事,因此对 ASCII 进行了各种扩展,加新字符,比如上图的 IBM CP437 字符集,用于 DOS。

:: 用来读取字符,转换成光栅图形的硬件 - 字符生成器(‘第一代显卡’) ,有一个 ROM,存储着每个字符的图形(‘点阵图案’) - 为了显示,访问内存中的一块特殊区域(‘屏幕缓冲区’)。

屏幕缓冲区,是不是类似于内存和屏幕显示光栅的映射 ❓ 也是一层抽象 ❓

某些系统上可以用额外的 bit 定义字体颜色和背景颜色,做出这样的 DOS 界面 这界面只用了刚刚提到的字符集。字符生成器是一种省内存的技巧,但没办法绘制任意形状。制任意形状很重要,因为电路设计,建筑平面图,地图,好多东西都不是文字!为了绘制任意形状,同时不吃掉所有内存,计算机科学家用 CRT 上的"矢量模式"。概念非常简单:所有东西都由线组成,没有文字这回事,只有线条,没有别的。明白了吗?好,我们举个实例吧!

假设这个视频是一个 笛卡尔平面 200 个单位宽,100 个单位高,原点 (0,0) 在左上角,我们可以画形状,用如下矢量命令,这些命令来自 Vectrex,一个早期矢量显示系统。首先,reset ,这个命令会清空屏幕,把电子枪的绘图点移动到坐标 (0,0),并把线的亮度设为 0 , MOVE_TO 50 50 把绘图点移动到坐标 (50,50) ,INTENSITY 100 把强度设为 100 ,现在亮度提高了,移动到 (100,50) 然后 (60,75) 然后 (50,50) ,最后把强度设回 0 。酷,我们画了一个三角形!这些命令占 160 bit 比存一个庞大的像素矩阵更好。就像之前的"字符生成器" 把内存里的字符转成图形一样,这些矢量指令也存在内存中,通过矢量图形卡画到屏幕上。数百个命令可以按序存在屏幕缓冲区,画出复杂图形,全是线段组成的!由于这些矢量都在内存中,程序可以更新这些值,让图形随时间变化 - 动画!

最早的电子游戏之一,Spacewar! 是 1962 年在 PDP-1 上用矢量图形制作的。它启发了许多后来的游戏,比如 爆破彗星 (Asteroids),甚至第一个商业街机游戏:太空大战 。

1962 年是一个大里程碑 - Sketchpad 诞生,一个交互式图形界面,用途是计算机辅助设计 (CAD,Computer-Aided Design),它被广泛认为是第一个完整的图形程序,发明人伊万·萨瑟兰后来因此获得图灵奖。为了与图形界面交互 ,Sketchpad 用了当时发明不久的输入设备 - 光笔,就是一个有线连着电脑的触控笔,笔尖用光线传感器,可以检测到显示器刷新,通过判断刷新时间,电脑可以知道笔的位置,有了光笔和各种按钮,用户可以画线和其他简单形状。Sketchpad 可以让线条完美平行,长度相同,完美垂直 90 度,甚至动态缩放,这些在纸上很费力,在计算机上非常简单!用户还可以保存设计结果,方便以后再次使用,甚至和其他人分享。你可以有一整个库,里面有电子元件和家具之类的,可以直接拖进来用。从如今的角度来看,好像很普通,但在 1962 年 计算机还是吃纸带的大怪兽,有柜子般大小,Sketchpad 和光笔让人大开眼界,它们代表了人机交互方式的关键转折点 - 电脑不再是关在门后负责算数的机器了,可以当助手帮人类做事。

最早用真正像素的计算机和显示器出现于 1960 年代末,内存中的位 (Bit) 对应屏幕上的像素,这叫 位图显示。现在我们可以绘制任意图形了,你可以把图形想成一个巨大像素值矩阵。就像之前,计算机把像素数据存在内存中一个特殊区域 叫 “帧缓冲区”。早期时,这些数据存在内存里,后来存在高速视频内存里,简称 VRAM 。VRAM 在显卡上,这样访问更快,如今就是这样做的。在 8 位灰度屏幕上,我们可用的颜色范围是 0 强度(黑色),到 255 强度(白色)。其实更像绿色或橙色 ,因为许多早期显示器不能显示白色。我们假设这个视频在低分辨率的位图屏幕上,分辨率 60x35 像素。如果我们想把 (10,10) 的像素设为白色 可以用这样的代码,…… ,如果想画一条线,假设从 (30,0) 到 (30,35) 可以用这样一个循环,……,把整列像素变成白色,如果想画更复杂的图形,比如矩形,那么需要四个值:

1. 起始点 X 坐标    2. 起始点 Y 坐标    3. 宽度    4. 高度

目前只试了白色,这次画矩形试下灰色,灰色介于 0 到 255 中间 所以我们用 127 (255/2=127.5),然后用两个循环,一个套另一个,这样外部每跑一次,内部会循环多次 ,可以画一个矩形。计算机绘图时会用指定的颜色 127 ,我们来包装成 “画矩形函数”,就像这样:

……

假设要在屏幕的另一边,画第二个矩形,这次可能是黑色矩形,可以直接调用 “画矩形函数”, 超棒!

就像之前说的其他方案,程序可以操纵"帧缓冲区"中的像素数据,实现交互式图形。当然,程序员不会浪费时间从零写绘图函数 而是用预先写好的函数来做,画直线,曲线,图形,文字等

一层新抽象!

位图的灵活性,为交互式开启了全新可能,但它的高昂成本持续了十几年,上集提到,1971 年 整个美国也只有大约 7 万个电传打字机和 7 万个终端,令人惊讶的是 只有大约 1000 台电脑有交互式图形屏幕,这可不多!

Sketchpad 和 太空大战 这样的先驱,推动了图形界面发展,帮助普及了计算机显示器 由此,图形界面的曙光初现,帮助普及了计算机显示器 由此,图形界面的曙光初现。

接下来讲图形界面。

下周见。

24. 冷战和消费主义

i.e. The Cold War and Consumerism

(。・∀・)ノ゙嗨,我是 Carrie Anne 欢迎收看计算机科学速成课!

之前介绍了计算机历史 从人类文明的曙光开始 (第 1 集),一直到 1940 年代中期电子计算机诞生,过去 23 集里讲的很多东西,比如编程语言和编译器,算法和集成电路,软盘(Floppy disks)和操作系统,电报机和屏幕,全都是 1940~1970 年代,大概这 30 年间里出现的。那时苹果和微软还不存在,也没有推特,谷歌或者 Uber 。还没到个人电脑时代,而万维网,无人驾驶汽车,虚拟现实等主题,这个系列的后半部分会讲。

今天,我们不管电路和算法 来聊聊这个影响力巨大的时代!

我们会把重点放在 冷战,太空竞赛,全球化,消费主义的兴起。1945 年二战结束后不久,两个超级大国的关系越发紧张,美国和苏联开始了冷战,因此政府往科学和工程学 投入大量资金。计算机在战时已经证明了自身的价值, 比如曼哈顿计划 和 破解纳粹通讯加密,所以政府大量投入资源 各种雄心勃勃的项目得以进行,比如之前提过的 ENIAC, EDVAC, Atlas, Whirlwind ,这种高速发展,如果仅靠商业运作是根本无法做到的 - 要依靠销售收回开发成本。

1950 年代,事情开始发生变化,特别是 Univac 1,它是第一台取得商业成功的电脑,不像 ENIAC 或 Atlas Univanc 1 不是一台机器,而是一个型号,一共造了 40 多台,大部分 Univac 去了政府或大公司,成为美国日益增长的军事工业综合体的一部分,因为政府有钱承担这些尖端科技。一个著名的例子是,一台给 美国原子能委员会 生产的 Univac 1 ,被 CBS 用来预测 1952 年美国总统大选的结果,仅用 1%的选票,Univac 1 正确预测了结果。艾森豪威尔 获得压倒性胜利,而专家预测 史蒂文森 会赢,这次事件把计算机推到了公众面前。

计算机和以前的机器不一样,以前的机器 增强人类的物理能力,比如卡车能带更多东西,自动织布机更快,机床更精确 等等。这些东西代表了工业革命。而计算机增强的是人类智力,范内瓦·布什 看到了这种潜力。他在 1945 年发表了一篇文章,描述了一种假想计算设备叫 Memex。可以用这个设备 存自己所有的书,其他资料 以及和别人沟通,而且数据是按照格式存储,所以可以快速查询,有很大灵活性,可以辅助我们的记忆。他还预测会出现新的百科全书形式,信息之间相互链接,听起来是不是很熟悉?(维基百科)

Memex 启发了之后几个重要里程碑,比如上集 伊万·萨瑟兰 的 Sketchpad(画板),以及后面很快会讲到 Dough Engelbart 的 oN-LINE 系统(第 26 集)。

范内瓦·布什 做过"美国科学研究与开发办公室"的头头,这个部门负责在二战期间 资助和安排科学研究。冷战时, 范内瓦·布什 到处游说,想建立一个职责类似,但是在和平时期运作的部门,因此 国家科学基金会 于 1950 年成立,至今,国家科学基金会 依然负责给科学研究 提供政府资金。美国的科技领先全球,主要原因之一就是这个机构。

1950 年代,消费者开始买晶体管设备,其中值得注意的是 收音机,它又小又耐用,用电池就够了,而且便携,不像 1940 年代之前的收音机,用的是真空管。收音机非常成功,卖的像"菲比精灵"和 iPhone 一样畅销。日本政府也在寻求工业机会,想振兴战后经济,他们很快动手从贝尔实验室 取得晶体管的授权,帮助振兴日本的半导体和电子行业。1955 年,索尼的第一款产品面世 - TR-55 晶体管收音机。他们把重心放在质量和价格,因此日本公司在短短 5 年内,就占有了美国便携式收音机市场的一半。这为日本成为美国的强大工业对手,埋下伏笔。

1953 年,整个地球大概有 100 台计算机,苏联这时的计算机科技只比西方落后几年。苏联在 1950 年 ,完成了第一个可编程电子计算机,但苏联在太空竞赛远远领先。

我们进入思想泡泡

苏联在 1957 年 把第一个卫星送上轨道,史波尼克 1 号。不久,在 1961 年,苏联宇航员 尤里·加加林 第一个进入太空,美国民众对此不满,使得肯尼迪总统 在加加林太空任务一个月后,提出要登陆月球。登月很贵的!NASA 的预算增长了几乎十倍,在 1966 年达到顶峰,占了政府预算的 4.5% ,如今,NASA 的预算只占 0.5% 。NASA 用这笔钱资助各种科学研究,阿波罗计划花的钱最多,雇了 40 万人左右,而且有 2 万多家大学和公司参与。其中一个挑战是 怎样在太空中导航,NASA 需要电脑计算复杂的轨道来引导太空船,因此,他们造了 “阿波罗导航计算机”,有 3 个重要要求:

  1. 计算机要快,这在意料之中;
  2. 计算机要又小又轻。太空船里的空间不多,而且要飞去月球,能轻一点是一点;
  3. 要超级可靠。

这对太空船非常重要,因为太空中有很多震动,辐射,极端温度变化。如果东西坏掉了,可没办法去"百思买"买新的。那时的主流科技 真空管和晶体管 无法胜任这些要求,所以 NASA 用全新科技:集成电路。

我们几集前聊过,阿波罗导航计算机 首先使用了集成电路,NASA 是唯一负担得起集成电路的组织。最初,一个芯片差不多 50 美金,导航计算机需要上千个芯片,但美国也因此成功登月,打败苏联。

谢了 思想泡泡

虽然人们经常把集成电路的发展 归功于阿波罗导航计算机,但它们的产量很低,一共只有 17 次阿波罗任务。实际上是军事 大大推进了集成电路发展,特别是洲际导弹和核弹,使集成电路大规模生产。美国建造强大计算机时,也进一步推进了集成电路,一般叫"超级计算机",因为它们经常比全球最快电脑还快 10 倍以上,但 CDC,Cray,IBM 制造的计算机非常昂贵,几乎只有政府负担得起,这些计算机用于政府机构,比如美国国家安全局,以及实验室比如 劳伦斯·利弗莫尔 实验室 、 洛斯·阿拉莫斯 国家实验室。

最初,美国的半导体行业 靠高利润政府合同起步,因此忽略了消费者市场,因为利润小。因此日本半导体行业在 1950 和 1960 年代 靠低利润率占领了消费者市场,日本人投入大量资金,大量制造以达到规模经济,同时研究技术,提高质量和产量 以及用自动化来降低成本。1970 年代,太空竞赛和冷战逐渐消退 高利润的政府合同变少,美国的半导体和电子设备公司发现更难竞争了。虽然很多计算机组件商品化了,但并没有什么帮助。DRAM 就是 DRAM ,能从日立买便宜的,干嘛要从英特尔买贵的? 1970 年代 美国公司开始缩小,合并,或直接倒闭 。1974 年 英特尔不得不裁员三分之一 ,知名的仙童半导体也在 1979 年濒临倒闭 ,被其他公司收购了。为了生存,很多公司把生产外包出去,降低成本。英特尔不再把精力放在 内存集成电路, 而是把精力放在处理器,这个决定最后挽救了公司。美国公司的无力 ,导致 夏普 和 卡西欧 这样的日本公司占领了 1970 年代的主流产品 - 手持计算器。因为集成电路,计算机又小又便宜。,取代了办公室里昂贵的桌面计算器。对大多数人 这是他们第一次不必用纸笔和计算尺来做计算,手持计算机因此大卖,进一步降低了集成电路的成本,使得微处理器被广泛使用,比如之前讨论过的 Intel 4004 。Intel 在 1971 年 应日本计算器公司 Busicom 的要求做了这个芯片,很快,日本电子产品到处都是,从电视到手表到随身听,而廉价的微处理器,也催生了全新的产品,比如街机游戏。1972 年诞生了 Pong,1976 年诞生了打砖块。因为成本不断下降,很快,普通人也买得起计算机了,这段期间,第一批家用电脑开始出现,比如 1975 年的 Altair 8800,以及第一款家用游戏机,比如 1977 年的 Atari 2600 。家用!我再说一遍 家用!如今没什么大不了的,但那时是计算机的全新时代!

在短短三十年内,计算机从大到人类可以在 CPU 里走来走去(当然,你要有政府许可你这样做),发展到小到小孩都能拿住的手持玩具,而且微处理器还快得多。这种巨大变化是由两种力量推动的:政府和消费者!政府资金,比如冷战期间美国投入的钱,推动了计算机的早期发展,并且让计算机行业活得足够久,使得技术成熟到可以商用。然后是公司,最后是消费者,把计算机变成了主流。冷战虽然结束了,但这种关系今天仍在继续。政府依然在资助科学研究,情报机构依然在超级计算机,人类仍然被发射到太空里,而你依然在买电视,Xbox,Playstation,笔记本电脑和手机。

因此,计算机会继续飞速发展。

我们下周见。

25. 个人计算机革命

i.e. The Personal Computer Revolution

(。・∀・)ノ゙嗨,我是 Carrie Anne 欢迎收看计算机科学速成课!

上周说过"个人计算机"的概念 ,在计算机发展的头 30 年难以想象,如果只让一个人用,成本实在太高。但到 70 年代初,各种组件的成本都下降了 可以做出低成本 同时性能足够强大的计算机。不是玩具级计算机,是真正能用的计算机。这个转变中 最有影响力的是 单芯片 CPU 的出现,强大 + 体积小 + 便宜 ,集成电路的进步,也提供了低成本固态存储器,可以用于计算机的 RAM 和 ROM 。忽然间 把整台计算机做到一张电路板上成为可能,大大地降低了制造成本,而且,那时有便宜可靠的储存介质, 比如磁带和软盘,最后是 低成本的显示器 ,通常是电视机稍作改装而成。如果在 1970 年代 将这四种原料混在一起,就得到了"微型计算机"。因为和那个时代的"普通"计算机相比 ,这些计算机很小,“普通"计算机就是公司或大学里的那种。但比大小更重要的是成本,这是有史以来第一次,计算机的价格足够低,“一个人专用"的想法变得可行,不用划分时间和别人公用计算机,没有多用户登录,计算机只属于一个人,只有一个用户,个人计算机时代到来!

计算机成本下降+性能提升,让个人计算机成为可能,但这个时间点很难准确定义,并没有一个具体时间点,因此"第一台个人计算机"这个名号,有很多竞争者,比如 Kenback-1 和 MCM/70 。不过第一台取得商业成功的个人计算机 争议较小:Altair 8800,首次亮相在 1975 年《Popular Electronics》封面,售价 $439 美元,需要自己组装。计算通货膨胀后,相当如今的 2000 美元左右,不算小钱,但比起 1975 年的其它计算机,算是非常便宜了!

各种需要自己组装的组件包卖给了计算机爱好者,因为买的人多,很快相关产品出现了,比如内存,纸带读取器,甚至电传接口,让你可以从纸带上读取更长更复杂的程序,然后用电传终端交互,但程序还是要用 机器码 写,写起来很麻烦,即使计算机爱好者也讨厌写,这没有吓跑年轻的比尔·盖茨和保罗·艾伦!他们当时是 19 岁和 22 岁,他们联系了制造 Altair 8800 的 MITS 公司,建议说,如果能运行 BASIC 程序 会对爱好者更有吸引力。BASIC 是一门更受欢迎更简单的编程语言,为此,他们需要一个程序 把 BASIC 代码转成可执行机器码,这叫 解释器 (interpreter)。“解释器"和"编译器"类似,区别是"解释器"运行时转换, 而"编译器"提前转换。

让我们进入思想泡泡!

MITS 表示感兴趣,同意与 Bill 和 Paul 见个面,让他们演示一下。问题是,他们还没写好解释器,所以他们花了几个星期赶工 ,而且还不是在 Altair 8800 上写的,最后在飞机上完成了代码。他们在墨西哥 阿尔伯克基(城市) 的 MITS 总部做演示时,才知道代码可以成功运行。幸运的是进展顺利 MITS 同意在计算机上搭载他们的软件,Altair BASIC 成了微软的第一个产品。

虽然 1975 年之前就有计算机爱好者,但 Altair 8800 大量催生了更多计算机爱好者,爱好者们组成各种小组 分享知识,软件,以及对计算机的热爱,最具传奇色彩的小组是"家酿计算机俱乐部”。第一次小组聚会在 1975 年 3 月,看一台第一批运来加州的 Altair 8800 。第一次聚会上,24 岁的 Steve Wozniak 被 Altair 8800 大大激励,开始想设计自己的计算机。1976 年 5 月,他向小组展示了原型机,并且把电路图分享给感兴趣的其他会员,他的设计不同寻常 要连到电视显示,并提供文本界面,在低成本计算机上还是第一次见。同是俱乐部成员和大学朋友的 史蒂夫·乔布斯 建议说与其免费分享设计,不如直接出售装好的主板,但用户依然需要自己加键盘,电源和机箱。1976 年 7 月开始发售,价格 $666.66 美元,它叫 Apple-I ,苹果计算机公司的第一个产品。

谢了 思想泡泡

就像 Altair 8800 一样,Apple-I 也是作为套件出售,Apple-I 吸引了业余爱好者 不介意机器买回来自己组装,但个人消费者和公司对 Apple-I 不感兴趣。

这在 1977 年发生变化 市场上有了三款开箱即用的计算机。

第一款是 Apple-II ,苹果公司第一个提供全套设备的产品,设计和制造工艺都是专业的,它还提供了简单彩色图形和声音输出,这些功能对低成本机器非常了不起。Apple-II 卖了上百万套,把苹果公司推到了个人计算机行业的前沿。第二款是"TRS-80 1 型”,由 Tandy 公司生产,由 Radioshack 销售,所以叫 TRS。虽然不如 Apple-II 先进 但因为价格只有一半,所以卖得很火爆。最后一款是 Commodore PET 2001 ,有一体化设计,集成了计算机,显示器,键盘和磁带驱动器,目标是吸引普通消费者。

计算机和家用电器之间的界限开始变得模糊,这 3 台计算机被称为 1977 年的"三位一体” 。它们都自带了 BASIC 解释器,让不那么精通计算机的人也能用 BASIC 写程序,针对消费者的软件行业 开始腾飞。市场上出现了各种 针对个人计算机的游戏和生产力工具,比如计算器和文字处理器,最火的是 1979 年的 VisiCalc - 第一个电子表格程序,比纸好无数倍,是微软 Excel 和 Google Sheets 的老祖先。

但这些计算机带来的最大影响 也许是他们的营销策略,它们针对普通消费者, 而不是企业和爱好者。这是第一次大规模地,计算机出现在家庭,小公司,以及学校中,这引起了全球最大计算机公司 IBM 的注意,其市场份额从 1970 年的 60% 在 1980 年降到了 30%左右,因为 IBM 忽略了增长的"微型计算机"市场,这个市场每年增长约 40% 。随着微型计算机演变成个人计算机 IBM 知道他们需要采取行动,但要做到这一点 公司要从根本上重新思考战略和设计 。1980 年 IBM 最便宜的计算机 “5120"的价格大概是一万美元,永远也没法和 Apple-II 这样的计算机竞争,意味着要从头开始。一个由十二名工程师组成的精干团队(后来叫"肮脏十二人”),被派往佛罗里达州的 博卡拉顿(Boca Raton)办公室,让他们独立工作。不受 IBM 内部的政治斗争干扰 他们想怎么设计怎么设计,没用 IBM 的 CPU,选了 Intel 的芯片,也没用 IBM 的首选操作系统 CP/M ,而是用了微软的 DOS 。依此类推,从屏幕到打印机都这样自由选择 。IBM 第一次不得不与外部公司竞争,来给新计算机做硬件和软件,这和 IBM 的传统做法不同:自己做硬件来节省成本,然后和其它公司合作,经过短短一年,IBM 个人计算机发布了,简称 IBM PC,产品立马取得了成功。长期信任 IBM 品牌的企业买了很多,但最有影响力的是 它使用 “开放式架构”,有良好的文档和扩展槽,使得第三方可以做硬件/外设 - 包括显卡,声卡,外置硬盘,游戏控制杆 以及无数其它组件,这刺激了创新,激发了竞争,产生了巨大的生态系统,这个开放架构叫 IBM Compatible"( IBM 兼容 ),意味着如果买了"IBM 兼容"的计算机,你可以用庞大生态系统中的其它软硬件。开放架构也意味着 竞争对手公司可以遵循这个标准,做出自己的"IBM 兼容"计算机。很快,康柏和戴尔也开始卖 PC ,微软很乐意把 MS-DOS 授权给他们,使 DOS 迅速成为最受欢迎的 PC 操作系统。仅在前三年 IBM 就卖出了 200 万台 PC ,超过了苹果。有了庞大用户群,软件和硬件开发人员 把精力放在"IBM 兼容"平台,因为潜在用户更多,同时,想买计算机的人 也会看哪种计算机的软硬件选择更多,就像雪球效应一样,而那些生产非"IBM 兼容"计算机的公司 (一般性能更好),都失败了。只有苹果公司在没有"IBM 兼容"的情况下 保持了足够市场份额,苹果公司最终选了相反的方式:“封闭架构”,即自己设计一切,用户一般无法加新硬件到计算机中,意味着苹果公司要做自己的计算机,自己的操作系统,还有自己的外围设备,如显示器,键盘和打印机。通过控制整个范围,从硬件到软件,苹果能控制用户体验并提高可靠性。不同的商业策略是 “Mac vs PC 谁更好” 这种争论的起源,这些争论如今还存在 不过"Mac vs PC"用词不对,因为它们都是个人计算机!但是随便啦!

为了在低成本个人计算机的竞争冲击下生存下来,苹果需要提高自身水平 提供比 PC 和 DOS 更好的用户体验,他们的答案是 Macintosh,于 1984 年发布 - 一台突破性 价格适中的一体式计算机 ,用的不是命令行界面,而是图形界面!

我们下周讨论图形界面。到时见。