《计算机是怎样跑起来的》

“计算机科学概论”图解趣味版,太入门了一点。
原书是2003年写,内容过于成旧。
作者先写了《程序是怎样跑起来的》。有一位70多岁的老先生买了一本,但是觉得内容太难理解不了。所以作者又写了更加通俗易懂的这本书。

计算机的三大原则:
1.计算机是执行输入、运算、输出的机器
2.程序是指令和数据的集合
3.计算机的处理方式有时与人们的思维习惯不同

计算机进化的目的只有一个——与人类更加相近。要想贴近人类,就必须从计算机的处理方式中摒弃不符合人们思维习惯的部分。

在将一个2字节的数据存储到内存时,存储顺序是低8位在前、高8位在后(也就是逆序存储)。这样的存储顺序叫作“小端序”(Little Endian),与此相反,将数据由高位到低位顺序地存储到内存的存储顺序则叫作“大端序”(Big Endian)。

结构化程序设计是由学者戴克斯特拉提倡的一种编程风格。简单地说,所谓结构化程序设计就是“为了把程序编写得具备结构性,仅使用顺序执行、条件分支和循环表示程序的流程即可,而不再使用跳转指令”。

所谓算法(Algorithm),就是解决既定问题的步骤。
再去查查JIS(日本工业标准),上面写着算法的定义是“被明确定义的有限个规则的集合,用于根据有限的步骤解决问题。

那么到底哪种理解方法才是正确的呢?其实无论是哪种方法,只要能够通过实际的编程将其付诸实践,那么这种方法就是正确的。

也就是说用C++等面向对象编程语言编写程序的话,程序可以通过由一个对象去调用另一个对象所拥有的函数这种方式运行起来。这种调用方式被称为对象间的“消息传递”。在面向对象语言中所说的消息传递指的就是调用某个对象所拥有的函数。即便是在现实世界中,我们也是通过对象间的消息传递来开展业务或度过余暇的。在面向对象编程中还可以对对象间的消息传递建立模型。

“继承”(Inheritance)、“封装”(Encapsulation)和“多态”(Polymorphism,也称为多样性或多义性)被称为面向对象编程的三个基本特性。

1970年美国IBM公司的Codd先生设计发明了关系型数据库。现在关系型数据库被广泛应用,以至于一提到数据库就默认是关系型数据库。

所谓标记语言,就是可以用标签为数据赋予意义的语言。

XML并没有限定标签的使用方式,使用什么样的标签都可以。可以说XML仅仅限定了进行标记时标签的书写格式(书写风格)。也就是说通过定义要使用的标签种类,就可以创造出一门新的标记语言。通常把这种用于创造语言的语言称作“元语言”。

所谓计算机系统的设计,就是拆解。老一辈工程师们已经发明出了可作为规范的各种各样的设计方法,这些方法之间的差异只是拆解时的关注点不同。

所谓“对象”(Object),就是把指令和数据归拢到具有一定意义的组中而形成的整体。

《世界尽头的咖啡馆》

整本书讲的就是要问自己:“你为什么来这里?”。

译者万洁据说开始翻译这本书以后,卸载了“吃鸡”游戏。

你为什么来这里?
你害怕死亡吗?
你满足吗?

从不同的视角看待事物,有时候能帮助我们解决问题。

不同的人会在不同的时期面对那个问题。有的人在小时候就想清楚了,有的人长大一些才开始想,还有人终其一生都没想明白。

当一个人弄清了他为什么存在,就相当于定义了自己的‘存在意义(Purpose For Existing)'。我们简称其为‘PFE'。在一个人的一生中,他可以为了实现‘存在意义’做十件、二十件、甚至成百上千件事。他可以做任何事。我们有些客人清楚自己的PFE,并会尝试各种他们认为有利于实现PFE的活动,这些人通常对生活满意度很高。

当自己为实现存在意义而努力时,幸运的巧合就会自然出现,他们管这个叫顺其自然。

除了我自己,没人关心我在哪儿击球;同理,在生活中,只有你真正了解自己存在的意义。永远不要因为其他人或事失去对自己命运的掌控。要积极地选择自己的人生道路,不然就只能被动接受安排。要学会移走你人生中的高尔夫球。

你要记住一个关键点,自己的答案,全世界只有我们自己可以决定。所以很多人都在追寻答案的过程中选择独处。

生活本来就很精彩。只不过有人没发现自己是作者,没发现他们可以按自己的想法创作。

《编码:隐匿在计算机软硬件背后的语言》

非常好读的关于计算机如何实现的书,还有物理、布尔代数等学科的知识。

第17章自动操作是计算机从硬件到软件组成的关键一章

在这本书里,编码这个词的意思是指一种用来在机器和人之间传递信息的方式。换句话说,编码就是交流。

莫尔斯码也被称作二进制码(Binary Code),因为这种编码的组成元素只有两个——“点”和“划”。

尤其值得注意的是数字标识符和取消“数字标识状态”的字母标识符。它们改变了后面编码的意义——从表示字母到表示数字,又从表示数字回到表示字母。像这样的编码通常被称作“优先码”(precedence codes)或者“换档码”(shift codes)。它们改变着作用域内编码的含义,直到作用域结束。
大写字母标识符表示紧随它的字母(而且仅仅是紧随它的字母)应该被译为大写。类似这样的编码被称为“逃逸码”(escape codes)。

大约在1948年,美国数学家约翰·威尔德·特克(JohnWilder Turkey,生于1915年)就意识到随着计算机的普及,二进制数很可能会在未来发挥更重要的作用。他决定创造一个新的、更短的词语来代替使用起来很不方便的五音节词——binary digit。他曾经考虑使用bigit和binit,但是最终他还是选用了这个短小、简单、精巧而且非常可爱的词——bit。

回顾一下莫尔斯码的编码规则:划的长度等于点长度的三倍;单个字母内,点或划之间以长度与点相等的空格来分开;单词内的各个字母之间用长度等于划的空格分隔;各单词之间由长度等于两倍的划的空格分开。

每个与门、或门和与非门都需要两个继电器,因此一个异或门中就包含6个继电器。一个半加器是由一个异或门和一个与门组成的,因此一个半加器就需要8个继电器。每个全加器由两个半加器和一个或门组成,所以它要18个继电器。我们需要8个全加器来制作8位二进制加法器。因而总共需要144个继电器。

加法器的总体速度等于数字的位数乘以全加器器件的速度,这被称做行波进位(ripple carry,或脉冲进位)。更快的加法器运用了一个被称为“前置进位”的电路来提高运算的速度。

字节这个词最早起源于1956年前后,由IBM公司提出。最早的拼写方式是bite,但为了避免与bit混淆用y代替了i。曾几何时,字节仅表示某一数据路径上的位数,直到20世纪60年代中叶,在IBM的360系统的发展下(一种大规模复杂的商用计算机),字节这个词逐渐开始用来表示一组8比特数据。

字节的一半——即4比特——我们称之为半字节(nibble,也可拼写成nybble),在计算机这个领域,它并不像字节那样经常使用。

条件跳转指令将它与我们以往设计的加法器区别开来,能否控制重复操作或者循环(looping)是计算机(computer)和计算器(calculator)的区别。

约翰·冯·诺依曼协助设计的ENIAC的后续产品EDVAC(Electronic Discrete Variable AutomaticComputer)。特别是在1946年与亚瑟·W·伯克斯(ArthurW.Burks)和荷曼·哥斯廷(Herman H.Goldstine)共同执笔的题为“电子计算器件逻辑设计的初步分析及讨论(PreliminaryDiscussion of the Logical Design of an ElectronicComputing Instrument)”的论文中,他描述了几个EDVAC比ENIAC更加先进的特点。EDVAC的设计者们感觉到计算机内部中应当使用二进制数,而ENIAC使用的是十进制数。同时他们认为计算机中应当拥有尽可能大容量的存储器,这些存储器应该用来存储程序代码和程序执行中产生的数据(再说明一下,这些在ENIAC中都是不能实现的,对于ENIAC来说,编程不过是扳动开关和插拔电线的事情)。这些指令在存储器中是顺序存放的,而且可以由程序计数器进行寻址,但允许条件跳转。这就是著名的“存储程序概念”(stored-program concept)。

堆栈的功能是怎样实现的呢?首先,堆栈其实就是一段普通的RAM存储空间,只是这段空间相对独立不另作他用。8080微处理器设置了一个专门的16位寄存器对这段存储空间寻址,这个特殊的寄存器称为堆栈指针(SP, StackPointer)。

外围设备有时候需要获得处理器的注意。例如,当你按下键盘的某个键时,处理器应该马上注意到这个事件。这个过程由一个称为中断(interrupt)的机制实现,这是一个由外围设备产生的信号,连接至8080的INT输入端。

NOP代表(即声明)no op(no operation,无操作)。NOP指令使处理器什么操作也不执行。这样做有什么好处呢?填空,即保持处理器的运行状态而不做任何事情。8080可以执行一批NOP指令而不会引起任何错误事件的发生。

Intel和Motorola的微处理器在保存多字节数据问题上的根本区别从未得到解决。直到今天,英特尔的微处理器在保存多字节数据时,仍然把最低有效字节放在最前面(也就是说,在最低地址处),而Motorola的微处理器在保存多字节数据时,仍然把最高有效字节放在最前面。
这两种不同的方式分别称为little-endian(Intel方式)和big-endian(Motorola方式)。争论两者之间哪一种方式更好是件有趣的事,但在这么做之前,先要知道big-endian这个术语出自乔纳森·斯威夫特(Jonathan Swift)的Gulliver'sTravels,指的是刘普特(Lilliput)和布鲁夫思科(Belfuscu)之间关于在吃鸡蛋之前应该把鸡蛋的哪一头敲碎的争论。因此,这种争论可能是没有意义的(另一方面,坦白地说,在本书第17章设计的计算机所采用的方式我个人并不喜欢)。尽管不能确定那一种方式本质上是“对的”,这种差别确实造成了附加的兼容性问题,这种问题通常会在采用little-endian和big-endian系统的机器共享信息时出现。

通常对于每1位存储空间,SRAM需要用4个晶体管(在第16章中讲过将触发器作为存储器用,其用到的晶体管更多),而DRAM只需要1个晶体管,但DRAM需要较复杂的外围支持电路,这正是它的缺点。

字符生成器(character generator)也是视频适配器板上的一部分,包含了所有ASCII码字符的像素图,这点前面已经讲过。通常,它是只读存储器(read-only memory),即ROM。它是一种集成电路,在生产时里面已经填入了数据,固定的地址输出的数据是不变的。ROM中并没有数据输入信号,这点与RAM不同。

640×480的分辨率具有很重要的意义。也许你可能无法相信,它之所以那么重要,是因为它和托马斯·爱迪生(ThomasEdison, 1847—1931)有关。大概在1889年,爱迪生及他的工程师威廉·肯尼迪·劳里·迪克生(William Kennedy LaurieDickson)正在进行活动电影摄影机和活动电影放映机的研究,他们决定:让电影图像的宽比高多出1/3。图像的宽和高之比,称为屏幕长宽比(aspect ratio)。通常,我们把爱迪生和迪克生所确定的这个比表示成1.33:1,或者不想使用小数点的话,就表示成4:3。60多年了,大多数电影一直采用这个比例,电视机也是如此。但在20世纪50年代早期,好莱坞引入宽屏(widescreen)技术,与电视展开竞争,并最终打破了这个比例。

不出我们所料,掉电的时候,半导体存储器中的内容就会被全部清零;而首次给它上电的时候,它将处于随机且不可预测的状态。同样,我们用来构建微处理器的所有RAM都包含随机的字节。

人们习惯形象地称这种文件命名方式为8.3,就是说在点号隔开的前半部分最多有8个字母,后半部分最多有3个字母。

很多BASIC的后续版本都是解释型(interpreter)而不是编译型(compiler)。如前所述,编译器读取源文件并生成一个可执行文件;而解释器却采取边读边执行的方式,不会产生新的文件。解释器比编译器的原理简单一些,因此更容易编写,但其运行程序的速度要比后者要慢。

键盘和CRT一起对远程计算机传输来的ASCII码(可能还包括Escape字符序列)做出响应,这种设备我们称之为哑终端(dumb terminal)。

如果程序在图形操作系统下运行,那么它们在显示器或打印机上画图这一过程中,使用的是一套完全相同的API。正因为如此,字处理程序在屏幕上显示出的文档,与打印出来而得到的纸质文档,看上去非常相似。这种特点称为“所见即所得”(简写为WYSIWYG)。这是喜剧演员弗雷普·威尔森(Flip Wilson)在扮演杰拉尔丁(Geraldine)角色中的一句话,这句话也成了计算机领域的一个经典口号。