好书一起读(82):电脑的原理
总览
电脑看似复杂,其实硬件无非四种:CPU,内存,磁盘,输入输出设备,重要性依次递减。硬件之上,操作系统是一层,应用程序又一层。
一通电,CPU就会开始运行,从磁盘中将操作系统读取到内存中,CPU按时间顺序从内存中的操作系统里,读取指令执行之。
操作系统使CPU迅速地在许多进程中切换,以造成进程们在并发运行的假象。
进程的诞生是,将程序从磁盘载入内存,并分配内存空间用于储存数据,这装载程序的内存和储存数据的内存构成了进程的载体,等分配了CPU,进程即开始运行。
CPU的分配以优先级和时间片为准,让重要程度不同的各个进程并发运行。
用户的操作通过输入设备(或定时器)产生中断,操作系统的主循环会发现中断,并分配给适当的响应中断的程序。
程序的执行结果,体现在硬件的变化上,如输出设备给出画面或声音,让用户看到或听到。
操作系统
操作系统位于「底层硬件」和「应用程序」之间,向下管理硬件资源,向上提供高级接口。
在CPU的计算能力之上,操作系统提供了调度的能力,来运行进程、显示图画、响应事件。
进程
在物理实现上,每个进程都是内存中的一个局部,这个局部既放了程序代码,又提供了储存状态的场所。
这些局部被CPU轮流访问,形成并发的假象。这「轮流」并非让各进程盲目地平摊CPU时间,而是有主次之分。在CPU的轮流访问期间,进程也因而在创建、就绪、运行、阻塞、终止这五种状态间切换。
CPU的轮流访问根据「优先级」和「时间片」,优先级是每个程序有的一个数字,数字大小关系决定了优先级高低关系,优先级低的进程要把CPU让给优先级高的,时间片指一小段时间,当一个进程用完一个时间片,CPU就重新选择下个时间片该运行谁。
因为CPU的程序计数器和各种寄存器都只有一份,当CPU切换到另一个进程时,上一个进程就需要把「我执行到哪了」保存下来,存到自己的「进程上下文」中,下次CPU切换回来时,把状态装回给CPU,继续运行,就好像什么都没发生过。
在任务管理器里查看进程列表,我们最关心的是内存占用和CPU占用,正说明了进程是「内存的片段」与「CPU的分配」的结合体。
进程可能是无限循环,也可能不是。如果不是,则处理完事务即停止,如果是,则不断监听事件以响应。
内存管理
如果内存有限,程序需要的内存超过实际内存,则需要虚拟内存:将磁盘的一部分用作「虚拟内存」,把内存中暂时不执行的程序外放到「虚拟内存」中,腾出来地方来运行需要执行的程序,当外放的程序需要执行时再换回到内存中。
分给某个程序的内存局部,在物理上未必是连续的,而是将真实内存分为固定大小的页,程序使用其中的若干页。这样能更灵活地使用。
文件
只有磁盘能断电存储,CPU和内存都不行,而且磁盘存储空间远大于CPU和内存,因此全部程序和数据都保存在磁盘上。保存的方式就是文件。
文件的本质是磁盘上的局部。磁盘分配方式与内存类似,也是划分为若干大小相等的小单元,文件按需使用其中一些小单元。
把磁盘看做输入输出设备也无妨,毕竟它相对于CPU和内存,是「外人」,内存从磁盘读,属于「输入」,内存向磁盘写,属于「输出」。
反过来,把输入输出设备,看做文件,也无妨,反正内存都是要向它们读和写的,只是看待它们的视角的差别。
输入输出设备
电脑想有用,就要跟用户有交互,跟用户的交互,全靠输入输出设备。用户给电脑信息,就是输入,电脑给用户信息,就是输出。
你对显示器、键盘、鼠标,肯定比对CPU、内存、磁盘更熟悉,对吧?因为显示器它们是「在一线面向用户」的。
引申,像计算机一样高效地使用大脑
人在同一时间只能做一件事,一心多用都是伪并发,切换上下文有成本。
应该把多而不重要的知识存到「磁盘」里,即笔记本、收藏夹等处,待用时方载入「内存」即大脑里即可,以减轻记忆负担。
最常用的知识才有必要记住在「内存」里,这取用方便,减少每次都从「磁盘」载入的成本,这是缓存的价值所在。
写在后面
这一个月每天都在读《30天自制操作系统》,同时使用大学时教材《计算机组成原理》《计算机三级教程PC技术》《现代操作系统》做参考,来进行对计算机底层硬件、操作系统的学习和巩固。
作为应用程序员,编写的代码都处于太高层,以至于觉得技术含量太差,久了对自己就不满意。一直都想好好复习下基础,但总因辛苦而坚持不下来。
后来终于想明白,基础的巩固和复习,应该是一个非常长期的工作,一蹴而就的想法非常不现实。于是决定用四个月时间,分别巩固计算机组成原理、操作系统、网络、算法的知识。这第一个月,做的是学习计算机组成原理的工作,还顺带看了操作系统。
机箱一拆开,电路板和连线怪复杂神秘的,吓人,其实那都不重要。最重要的三样东西,CPU,内存,磁盘,体积都有限,形状也规整,第四重要的就是机箱外面的显示器、键盘、鼠标这些总称为输入输出设备的东西了。
CPU是「原动力」,就像四驱车上的电机,呜呜转着,很蠢很机械。但能动起来就是万岁。人们开动脑筋,通过齿轮、皮带等零件,让电机旋转的单调动作转为更有意义的动作。对CPU也是一样,既然它能读取指令,并忠实地执行之,那就好办了,只要我们把指令写出花来,电脑的功能就会丰富锦簇。就像刘邦和张良,既然张良说什么刘邦都言听计从,那虽然刘邦能力有限,但只要张良智计百出,一切就都有可能了。
当然,在地位上,张良是刘邦的下级。在计算机体系中,操作系统是硬件的上层,其实计算机体系里,越上层权限越小,上层能做的,下层全能做,下层能做的,上层能不能做?那要看下层高不高兴暴露出调用的接口。所以,最上层的应用程序员,其实是被勒定在一个非常逼仄局促的空间里跳舞,在某个「平台」之上,利用平台好心提供的API,来使出浑身解数实现功能。API越简洁好用,应用程序员越显得无脑,其实未必是程序员蠢,而是饭已经熟了,再巧的媳妇也只能做做把它盛到碗里这种没有技术含量的工作,这跟「巧妇难为无米之炊」恰好是反的,好比「一键刷机」,程序给力到这个程度,只负责按一下按钮的人,即使有很高水平,也显不出来了。
不过,越上层固然离硬件越远,但抽象层次越高,离具体业务是越近的。搭积木搭得好,未必就不如造积木造得好那个人光荣。毕竟,用户要的,还是一个完成品,比如用户要一个城堡,那光造出来积木还是不行,需要有人搭起来。这搭积木,就需要很多造积木的人用不到的知识,例如空间想象力、图纸绘制能力、让城堡稳固不倒的力学知识、色彩搭配知识等等。每个层次,都有每个层次需要的专业技能,但人的认知总是有局限的,倾向重视自己的技能,轻视别人的技能,来达到满意自己、鄙视他人的心理诉求,其实这还是「成绩单的思维」,是没必要的。
但有些知识是无论造积木,还是搭积木的人都需要的,这就是所谓「通用知识」,例如数学知识、英语知识等等,当然计算机基础知识也是,这样看来计算机考研的课程都很有意义,比想象中的合理多了。不过现在学习资源这么丰富,书籍、视频、官网等等,即使不考研也可以自学,差别还是在肯不肯用功上。
话题回到刘邦张良,力量当然都在刘邦手上,但因为刘邦对张良言听计从,张良指哪里,刘邦的力量就打向哪里,这跟力量都在张良手上也没什么区别了。硬件和操作系统的关系也正像如此,虽然操作系统是「被动的」,只负责定义指令,执行权在CPU手里,但CPU这么听话,看成操作系统实际掌了权也就可以了:明明只有内存、磁盘的「容器」,却能无中生有地给抽象出「进程」「地址空间」「文件」这些可用性极强的概念来,操作系统真是把CPU内存和硬盘玩出了花来。
不过,同一份操作系统要卖给全世界,全世界各种用户需要的功能,这操作系统不可能全都包含了,所以操作系统索性也放权,操作系统提供出来API,世界各地程序员可以利用这API开发自己的程序,操作系统就负责把这些程序载入内存里作为进程来跑,当用户有操作时,操作系统负责把这操作事件交给适当的进程来响应。应用程序员能立足的基本点,其实就是操作系统提供的API们,当然,操作系统提供的API还是很丰富的,只要用好了各种程序都能开发出来,否则这操作系统也卖不出去呀。
对计算机的理解,最终就是到这里,CPU提供主循环,操作系统在这主循环中运行,提供次级主循环,应用程序的进程又在次级主循环中运行,提供三级主循环,当用户有操作了,CPU把操作交给操作系统,操作系统再交给应用程序进程,应用程序进程的三级主循环得知了事件的到来,再把它分发给响应事件的函数来处理,这个函数来做具体该做的事,比如把数据写向某个地方,或者在界面上显示某些东西,这显示某些东西,在本质上,其实也是向显卡内存中写些东西。
计算机组成原理和操作系统的学习,就先到这里(以后会慢慢修正和补充),下个月来复习数据结构和算法的知识,感觉还是这好玩,我都等不及了,至于计算机网络,下下个月再学,对这知识实在不很感兴趣。那对算法感兴趣的朋友,下个月咱们再见。