计算机科学基础_5 - 集成电路,操作系统

软件工程

  • 对象, Object
  • 面向对象编程, Object Oriented Programming
  • API, Application Programming Interface
  • public, private
  • 集成开发环境, IDE
  • 调试, debugging
  • 文档和注释, readme, comment
  • 版本控制, Version control
  • 质量控制, Quality Assurance testing, QA
  • Bate, Alpha

排序算法很少会是独立程序,更可能是大项目的一小部分,例如:微软的Office大约有4000万行代码。为了写大型程序,程序员用各种工具和方法,所有这些形成“软件工程”学科

“软件工程”这个词由工程师Margaret Hamilton创造,她帮助NASA在阿波罗计划中避免了严重问题。

计算机科学基础_5 - 集成电路,操作系统

Margaret Hamilton曾说过:“有点像牙根管治疗:你总是拖到最后才做,但有些事可以预先做好,有点像预防性体验,只不过是预防性软件出错”。

对象,面向对象编程

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

例如:汽车软件中可能有几个和定速巡航有关的函数,比如,设定速度,逐渐加速减速,停止定速巡航,因为这些函数都相关,可以包装成一个“定速巡航对象”。但不止如此,还可以做更多,“定速巡航”只是引擎软件的一部分,可能还有“火花塞点火”,“燃油泵”和“散热器”。
所以可以做一个“引擎对象”来包括所有“子”对象。除了子对象,“引擎对象”可能有自己的函数,比如,开关引擎。它也会有自己变量,比如汽车行驶了多少千米,总的来说,对象可以包其它对象,函数和变量。
当然,“引擎对象”只是“汽车对象”的一部分,还有传动装置,车轮,门,窗等。作为程序员,如果想设“定速巡航”,要一层层向下,从最外面的对象往里找,最后找到想执行的函数:Car.Engine.CruiseControl.setCruiseSpeed(55)

把函数打包成对象的思想叫“面向对象编程”

通过封装组件,隐藏复杂度,之前把晶体管,打包成了逻辑门,现在软件也这样操作。

API和IDE

把大型软件,拆分一个个更小单元,适合团队合作,在不同岗位同时工作,各尽其能。

各个团队负责不同项目,但也有所依赖,所以团队需要文档,帮助理解代码都做什么,以及定义好“程序编程接口”简称“API”

API帮助不同程序员合作,不用知道具体细节,只要知道怎么使用就行了。

API控制哪些函数和数据让外部访问,哪些仅供内部。“面向对象”的编程语言,可以指定函数是publicprivate来设置权限。

“面向对象编程”的核心是隐藏复杂度,选择性的公布功能。因为做大型项目很有效,所以广受欢迎。

代码在编译前就只是文字而已,只要编写出来,就可以。但是一般来说,现代软件开发者,会用专门的工具来写代码。工具里集成了很多有用的功能,帮助写代码,整理,编译和测试代码。因为集成了所有东西,因此叫集成开发环境简称IDE。

IDE会定位到出错代码,还会提供信息,帮助解决问题,这叫“调试(debug)”,调试很重要,大多数程序员会花70%~80%时间调试,而不是在写代码。

给代码写文档,文档一般放在README的文件里,告知其它程序员,看代码前先看这个文件。文档也可以直接写成“注释”,放在源码里。
注释存在的唯一作用,就是帮助开发者理解代码。

源代码管理,也叫“版本控制”。会把代码放到一个中心服务器上,叫“代码仓库”。

不希望提交的代码里有问题,因为其他人可能用到了这些代码,导致他们代码崩溃,造成困惑而且浪费时间,代码的主版本(master)应该是编译正常,尽可能少bug。

写代码和测试代码密不可分,测试一般由个人或小团队完成,测试可以统称“质量保证测试”,简称“QA”。
让软件在各种情况下按照预期运行。

bate 版软件:意思是软件接近完成,但不是100%完全测试过。
alpha 版软件:很粗糙,错误很多经常只在公司内部测试。

集成电路与摩尔定律

重点:晶圆的制作流程:光刻

  • 分立元件, Discrete components
  • 数字暴政,是1960年代工程师碰到的问题,意思是如果想强加电脑性能,就要更多部件,这导致更多线路,更复杂,所以很难做。
  • 光刻, Photolithography
  • 晶圆, Wafer
  • 光刻胶,Photoresist
  • 光掩膜,Photomask
  • 摩尔定律,Moore's Law
  • 英特尔
  • 晶体管数量大幅度增长,1980年三万个,1990年一百万个,2000年三千万个,2010年十亿个。
  • 进一步小型化会碰到2个问题,1.光的波长不足以制作更精细的设计 2. 量子隧穿效应

在大概50年代里,软件从纸带打孔变成面向对象,在集成开发环境中写程序。但如果没有硬件的大幅度进步,软件是不可能做到这些的。

硬件性能的爆炸性增长。

分立元件, Discrete components

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

分立元件:只有一个电路元件的组件,可以是被动的(电容,电阻,电感)或主动的(晶体管或真空管)

1950年代中期,晶体管开始商业化(市场上买得到)开始用在计算机里,晶体管比电子管,更小更快更可靠,但晶体管依然是分立元件。
1959年,IBM把709计算机从原本的电子管全部换成晶体管,诞生了新机器 IBM 7090速度快6倍,价格只有一半。

晶体管标志着“计算机2.0时代”的到来。

虽然更快更小,但晶体管的出现,还是没有解决“数字暴政”的问题,有十几万个独立元件的计算机不但难设计而且难生产。

1960年代,这个问题的严重性达到顶点,电脑内部常常一大堆电线缠绕在一起。
解决办法就是引入一层新抽象,封装复杂性。

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

起初,一个IC只有几个晶体管。
例如:早期样品,由西屋公司制造。

计算机科学基础_5 - 集成电路,操作系统

即使只有几个晶体管,也可以把简单电路,逻辑门,能封装成单独组件。
IC就像电脑工程师的乐高积木,可以组合出无数种设计,但最终还是需要连接起来,创造更大更复杂的电路,比如整个计算机。

计算机科学基础_5 - 集成电路,操作系统

所以工程师再度创新,印刷电路板,简称PCB
PCB可以大规模生产,无需焊接或用一大堆线。它通过蚀刻金属线,把零件连接到一起。
PCBIC结合使用,可以大幅减少独立组件和电线,但做到相同的功能。而且更小,更便宜,更可靠。

计算机科学基础_5 - 集成电路,操作系统

许多早期IC都是把很小的分立元件,封装成一个独立单元,例如这块1964年的IBM样品。不过,即使组件很小,塞5个以上的晶体管还是很困难。

计算机科学基础_5 - 集成电路,操作系统

光刻

为了实现更复杂的设计,需要全新的制作工艺:“光刻”。

简单说就是:用光把复杂图案印到材料上,比如半导体,它只有几个基础操作,但可以制作出复杂电路。

例子:

  1. 从一片硅开始,叫“晶圆”,长得像薄饼干一样。硅很特别,它是半导体,它有时导电,有时不导电,可以控制导电时机。所以硅是做晶体管的绝佳材料,可以用“晶圆”做基础,把复杂金属电路放上面,集成所有东西。非常适合做,集成电路。
  2. 下一步是硅片顶部,加一层薄薄的氧化层,作为保护层。
  3. 然后加一层特殊化学品,叫“光刻胶”,光刻胶被光照射后,会变得可溶。可以用一种特殊化学药剂洗掉。单单光刻胶本身,并不是很大作用,但和“光掩膜”配合使用会很强大。
  4. “光掩膜”就像胶片一样,要转移到“晶圆”上的图案。把光掩膜盖到晶圆上,用强光照射挡住光的地方,光刻胶不会变化。光照到的地方,光刻胶会发生化学变化,洗掉它之后,暴露出氧化层。
  5. 用另一种化学物质,通常是一种酸,可以洗掉“氧化层”露出的部分,蚀刻到硅层。氧化层被光刻胶保护住了,为了清理光刻胶,要用到另外一种化学药品洗掉它,光刻法很多化学品,每种都有特定用途。
  6. 现在硅又露出来了,修改硅露出来的区域,让它导电性更好。所以用一种化学过程来改变它,叫“掺杂Doping”,“掺杂”通常用高温气体来做,比如磷,渗透进暴露出的硅,改变点学性质。
  7. 还需要几轮光刻法,来做晶体管。过程:先盖氧化层,再盖光刻胶,然后用新的光掩膜,这次图案不同,在掺杂区域上方开一个缺口;洗掉光刻胶,然后用另一种气体掺杂,把一部分硅转成另一种形式。为了控制深度,时机很重要,不想超过之前的区域。
  8. 最后一步,把氧化层上做通道,这样可以用细小金属导线,连接不同晶体管。再次用光刻胶和光掩膜,蚀刻出小通道,现在用新的处理方法,叫“金属化”,放一层薄薄的金属,比如铝或铜。但不想用金属盖住所有东西,想蚀刻出具体的电路。所以又是类似步骤,用光刻胶+光掩膜,然后溶掉暴露的光刻胶,暴露的金属。
  9. 晶体管完成,它有三根线,连接着硅的三个不同区域。每个区域的掺杂方式不同,这叫双极型晶体管。

计算机科学基础_5 - 集成电路,操作系统

计算机科学基础_5 - 集成电路,操作系统

计算机科学基础_5 - 集成电路,操作系统

计算机科学基础_5 - 集成电路,操作系统

计算机科学基础_5 - 集成电路,操作系统

计算机科学基础_5 - 集成电路,操作系统

计算机科学基础_5 - 集成电路,操作系统

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

例子中,只做了一个晶体管,但现实中,光刻法一次会做上百万个细节。

芯片放大之后,导线上下交错,连接各个元件。

计算机科学基础_5 - 集成电路,操作系统

计算机科学基础_5 - 集成电路,操作系统

计算机科学基础_5 - 集成电路,操作系统

尽管可以把光掩膜投影到一整篇晶圆上,但光可以投射成任意大小。就像投影仪可以投满荧幕一样。
可以把光掩膜聚焦到极小的区域,制作出非常精细的细节。

计算机科学基础_5 - 集成电路,操作系统

计算机科学基础_5 - 集成电路,操作系统

一片晶圆可以做很多IC,整块都做完后,可以切割然后包进微型芯片,微型芯片就是在电子设备中,那些小长方体。记住,芯片的核心都是一小篇IC

计算机科学基础_5 - 集成电路,操作系统

随着技术的发展,晶体管变小,密度变高。
1960年代初,IC很少超过5个晶体管,因为塞不下。
但1960年代中期,市场上开始出现超过100个晶体管的IC

摩尔定律,Moore's Law

1965年,戈登●摩尔看到了趋势:每两年左右,得益于材料和制造技术的发展,同样大小的空间,能塞进两倍数量的晶体管。这叫摩尔定律。(它不是定律,只是一种趋势,但它是对的。)

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

Inter 4004 CPU,是个重要里程碑,发布于1971年,是第一个用IC做的处理器,也叫微型处理器。因为真的非常小。它有2300个晶体管。

计算机科学基础_5 - 集成电路,操作系统

惊叹于它的整合水平,整个CPU在一个芯片里,而仅仅20年前,用分立元件会占满整个屋子。
集成电路的出现,尤其是用来做微处理器,开启了计算3.0

晶体管数量大幅度增长,1980年三万个,1990年一百万个,2000年三千万个,2010年十亿个,在一个芯片里。

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

当然,CPU不是唯一受益的元件。大多数电子器件都在指数式发展:内存,显卡,固态硬盘,摄像头感光元件,等等。

如今的处理器,比如iphone7的A10 CPU,有33亿个晶体管。面积仅有1cm * 1cm,比一张邮票小。
现代工程师设计电路时,当然不是手工一个个设计晶体管,这不是人力能做到的。
1970年代开始,超大规模集成(VLSI)软件用来自动生成芯片设计。用比如“逻辑综合”这种技术可以放一整个高级组件,比如内存缓存。软件会自动生成电路,做到尽可能高效。(EDA技术,HDL自动综合技术)

进一步做小,会面临2个大问题:

  1. 用光掩膜把图案弄到晶圆上,因为光的波长,精度已达极限。所以科学家在研制波长更短的光源,投射更小的形状。
  2. 当晶体管非常小,电极之间可能只距离几个原子,电子会跳过间隙,这叫:“量子隧道贯穿”。如果晶体管漏电,就不是好开关。科学家和工程师在努力找解决方法,实验室已造出小至1纳米的晶体管。

操作系统

  • 操作系统,Operating systems
  • 批处理,Batch processing
  • 计算机变便宜变多,有不同配置,写程序处理不同硬件细节很痛苦,因此操作系统负责抽象硬件。
  • 外部设备,Peripherals
  • 设备驱动程序,Device drivers
  • 多任务处理,Multitasking
  • 虚拟内存,Virtual Memory
  • 动态分配内存,Dynamic memory allocation
  • 内存保护,Memory Protection
  • 1970年代,计算机足够便宜,大学买了让学生用,多个学生用多个“终端”连接到主机
  • 多用户分时操作系统,Multics
  • Unix
  • MS-DOS

1940,1950年代的电脑,每次只能运行一个程序,程序员在打孔纸卡上写程序,然后拿到一个计算机房间,交给操作员。等计算机空下来,操作员会把程序放入。然后运行,输出结果,停机。
以前计算机慢,这种手动做法可以接受。运行一个程序通常要几个小时,几天,甚至几周。

计算机越来越快,指数级增长,很快,放程序的时间,比程序运行时间还长,需要一种方式,让计算机自动运作。于是“操作系统”诞生了。

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

操作系统开始与1950年代,那时计算机开始变得更强大更流行。第一个操作系统,加强了程序加载方式。
之前只能一次给一个程序,现在可以一次多个。当计算机运行完一个程序,会自动运行下一个程序,这样就不会浪费时间,找下一个程序的纸卡,这叫: “批处理”。

电脑变得更快更便宜,开始在出现在世界各地,特别是大学和政府办公室,很快,人们开始分享软件,但有一个问题,在哈佛1号和ENIAC那个时代,计算都是一次性的,程序员只需给那“一台”机器写代码,处理器,读卡器,打印机都是已知的,但随着电脑越来越普遍,计算机配置并不总是相同的。比如计算机可能有相同CPU,但不同的打印机。不仅要担心写程序,还要担心程序怎么和不同型号的打印机交互,以及计算机连着的其它设备,这些统称“外部设备”。

设备驱动程序,Device drivers

和早期的外部设备交互,是非常底层的,程序员要了解设备的硬件细节,加重问题的是,程序员很少能拿到所有型号的设备来测代码。所以一般是阅读手册来写代码,祈祷能正常运行。

现在是“即插即用”,以前是“祈祷能用”。这很糟糕,所以为了程序员写软件更容易,操作系统充当软件和硬件之间的媒介。更具体的说,操作系统提供API来抽象硬件,叫“设备驱动程序”。

程序员可以用标准化机制,和输入输出硬件(I/O)交互。比如,程序员只需要调用print(highscore),操作系统会处理 输到纸上的具体细节。

到1950年代尾声,电脑已经非常快了,处理器经常闲着,等待慢的机械设备(比如打印机和读卡器)。程序阻塞在I/O上,而昂贵的处理器则在度假。

50年代后期,英国曼切斯特大学开始研发世界上第一台超级计算机,Atlas,他们知道机器会超级快,所以需要一种方式来最大限度的利用它。他们的解决方案是一个程序叫Altas Supervisor于1962年完成。这个操作系统,不仅像更早期的批处理系统那样,能自动加载程序,还能在单个CPU上同时运行几个程序。它通过调度来做到这一点。

假设Atlas上有一个游戏在运行,并且调用一个函数print(highscore)。它让Atlas打印一个叫highscore的变量值。

  • print函数运行需要一点时间,大概上千个时钟周期,但因为打印机比CPU慢,与其等着它完成操作,Altas会把程序休眠,运行另一个程序,最终,打印机会告诉Altas打印已完成,Altas会把程序标记可继续运行。
  • 之后在某时刻会安排给CPU运行。并继续print语句之后的下一行代码。

这样,Altas可以在CPU上运行一个程序,同时另一个程序在打印数据,同时另一个程序读数据。

计算机科学基础_5 - 集成电路,操作系统

Altas的工程师做的还要多,配了4台纸带读取器,4台纸带打孔机,多达8个磁带驱动器。

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

例如:假设计算机一共有10000个内存位置,程序A分配到内存地址0到999。而程序B分配到内存地址1000到1999,以此类推。(开着软件占缓存)

计算机科学基础_5 - 集成电路,操作系统

如果一个程序请求更多内存,操作系统会决定是否同意,如果同意,分配哪些内存块,这种灵活性很好,但带来一个奇怪的后果。程序A可能会分配到非连续的内存块,比如内存地址0到999,以及2000到2999。(解决方法:虚拟内存)
真正的程序可能会分配到内存中数十个地方。这对程序员来说很难跟踪。

虚拟内存,Virtual Memory

也许内存里有一长串销售额,每天下班后要算销售总额,但列表存在一堆不连续的内存块里,为了隐藏这种复杂性,操作系统会把内存地址进行“虚拟化”。这叫“虚拟内存”,程序可以假定内存总是从地址0开始,简单又一致。而实际物理位置,被操作系统隐藏和抽象了。

用程序B来举例,它被分配了内存地址1000到1999。对程序B而言,它看到的地址是0到999。操作系统会自动处理,虚拟内存和物理内存之间的映射。如果程序B要地址42,实际上是物理地址1042。这种内存地址的虚拟化,对程序A更有用。
在例子中,A被分配了两块隔开的内存,程序A不知道这点。以A的视角,它有2000个连续的地址,当程序A读内存地址999时,会刚好映射到物理内存地址999,但如果程序A读下一个地址1000,会映射到物理地址2000。这种机制使程序的内存大小可以灵活增减叫“动态内存分配”。

计算机科学基础_5 - 集成电路,操作系统

对程序来说,内存看起来是连续的。它简化了一切,为了操作系统同时运行多个程序提供了极大的灵活性。给程序分配专用的内存范围
另一个好处是这样隔离起来会更好,如果一个程序出错,开始写乱七八糟的数据,它只能捣乱自己的内存,不会影响到其它程序。这叫“内存保护”。防止恶意软件(如病毒)也很有用。
例如:不希望其它程序有能力读或改邮件程序的内存。如果有这种权限恶意软件可以以你的名义发邮件,甚至窃取个人信息。

  • 专用的内存范围
  • 更灵活
  • 内存保护
Multics

Atlas既有“虚拟内存”也有“内存保护”,是第一台支持这些功能的计算机和操作系统。到1970年代,计算机足够快且便宜。大学会买电脑让学生用,计算机不仅能同时运行多个程序,还能让多用户能同时访问。
多个用户用“终端”来访问计算机。“终端”只是键盘+屏幕,连到主计算机终端本身没有处理能力,冰箱大小的计算机可能有50个终端,能让50个用户使用。

计算机科学基础_5 - 集成电路,操作系统

这时操作系统不但要处理多个程序,还要处理多个用户。为了确保其中一个人,不会占满计算机资源,开发了分时操作系统,意思是:每个用户只能用一小部分处理器和内存等。因为电脑很快,即使拿到1/50的资源也足以完成许多任务。

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

Multics的研究人员Dennis Ritchie曾说过:阻碍Multics获得商业成功的一个明显问题是从某种方面来说,它被过度设计了,功能太多了。
所以Dennis和另外一个Multics研究员Ken Thompson联手开发新的操作系统叫Unix

他们想把操作系统分成两部分:

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

紧凑的内核意味着功能没有那么全面。
Multics的另外以为开发者Tom Van Vleck回忆说:我对Dennis说,我在Multics写的一半代码都是错误恢复代码。他说:“Unix 不会有这些东西, 如果有错误发生,我们就让内核‘恐慌’(panic)当调用它时,机器会崩溃,你得在走廊里大喊,‘嘿,重启电脑’”。

内核如果崩溃,没有办法恢复,所以调用一个叫“恐慌”(panic)的函数,起初只是打印“恐慌”一词,然后无限循环。

这种简单性意味着,Unix可以在更便宜更多的硬件上运行,使Unix在Dennis和Ken工作的贝尔实验室大受欢迎,越来越多开发人员用Unix写程序和运行程序。工具数量日益增长,1971年发布后不久,就有人写了不同编译语言的编译,甚至文字处理器,使得Unix迅速成为1970~80年代最流行的操作系统之一,到1980年代早期,计算机的价格降到普通人买得起,这些叫“个人电脑”或“家庭电脑”。这些电脑比大型主机简单得多,主机一般在大学,公司和政府。因此操作系统也得简单。
例如:微软的磁盘操作系统(MS-DOS)只有160KB,一张磁盘就可以容纳操作系统。

于1981年发布的,成为早期家用电脑最受欢迎的操作系统。虽然缺少“多任务”和“保护内存”这样的功能。意味着程序经常使系统崩溃。虽然很讨厌但还可以接受,因为用户可以重启。哪怕是微软1985年发布的早期Windows虽然在90年代很流行,但却缺乏“内存保护”。当程序行为不当时,就会“蓝屏”。代表程序崩溃的非常严重,把系统也带崩溃了。

如今的计算机,有现代操作系统,比如Mac OS X, Windows 10, Linux, iOS和Android。虽然大部分设备只有一个人使用。操作系统依然有“多任务”,“虚拟内存”, “内存保护”。因此可以同时运行多个程序:一边使用浏览器,一边使用PS修图,播放音乐,同步笔记等。如果没有操作系统这几十年的发展,这些都不可能。

操作系统:

  • 计算机自动运行。
  • 设备驱动程序,提供API来抽象硬件。
  • 批处理,多个程序同时运行,多任务。
  • 虚拟内存,内存保护,动态内存分配。
  • 多用户分时操作系统。

相关推荐