每个程序员书柜必备的编程书籍
“
原文参考了Dan Luu的博客,经作者授权,由InfoQ编译、整理并分享。
http://danluu.com/programming-books/
一提到有关编程方面的书籍,你就会想起江湖中传说的“每个程序员必读的12本计算机科学书籍”,然而,这份清单并没有什么实用性。因为,计算机科学领域非常宽泛,几乎所有程序员都可以阅读任何主题,就算某个主题很重要,但由于读者的学习偏好天悬地隔,因此对所有读者而言,某个主题并不存在所谓“最好的”书籍。
本文是我已经阅读过的主题和书籍的清单。这些都是我很熟悉的主题,也许你可以在此文中,了解关于该主题更多的情况,并阅读其他相关书籍。换而言之,就是说你为什么需要阅读另一本书。
算法、数据结构、复杂性
为什么要关心算法、数据结构和复杂性? 好吧,有一个实用的结论:在工作中,即使你从来没有用到这些东西,但是,大多数一流的支付公司在面试中会测试这些内容。我决不瞎扯,算法真的很有用,就像我发现数学很有用一样。任何特定算法适用于任何特定问题的概率很低,但从总体上说明什么类型的问题如何解决,什么样的问题难以处理,通常当近似有效时就有用了。
《Cracking the Coding Interview》
作者:McDowell
出版社:CareerCup; 6th edition (July 1, 2015)
中文版:《程序员面试金典》
译者:李琳骁、漆犇
出版社:人民邮电出版社,第五版
《程序员面试金典》的作者McDowell,是原Google资深面试官的经验之作,层层紧扣了程序员面试的每一个环节,全面详尽介绍了程序员应当如何应对面试才能脱颖而出。
该书涉及到面试流程解析、面试官的幕后决策及可能提出的问题、面试前的准备工作、对面试结果的处理等内容,还涵盖了数据结构、概念与算法、知识类问题和附加面试题四个方面,为读者提供了来自Google、Facebook、Microsoft等多家知名公司的编程面试题,并为每一道面试题分别给出了详细的解决方案。
我会向那些并没有真正掌握算法、但又想通过面试的程序员推荐这本书。这本书读起来尚可,不过并不能真正教会你知识,如果想真正掌握算法和数据结构,那么继续往下看。
《Algorithms》
作者:Dasgupta、Papadimitriou、Vazirani
出版社:McGraw-Hill Education
中文版:《算法概论》
译者: 王沛、唐扬斌、刘齐军
出版社:清华大学出版社
《算法概论》是一本适合入门的读物,但却不失深度以及广度,读来让人兴趣盎然。我认为,认真读完这本书,并且思考每章后面的习题,会对算法有一个很好的大局观。当然要掌握算法,只靠这一本书是不够的,不过算作最佳入门是当之无愧的。
该书全面介绍了算法的基本知识,将算法分成类(例如分治法、,或贪婪算法),在表达每一种技术时,强调每个算法背后的数学思想,让你掌握如何判断应该使用什么样的算法来解决特定的问题。
该书合理挑选主题,厘清了一条算法这门学问的线索,对结构的精心安排,对问题的数学结构的剖析,从而推出一个算法的过程的讲解。长度适宜,仅有三百多页,可以利用几个周末进行阅读。
不过,我知道有些读者不会喜欢这本书,因为它包括了太多的数学思想。如果是你,我猜你可能喜欢Skiena著的那本书。
《The Algorithm Design Manual》
作者:Skiena
出版社:Springer; 2nd edition (July 26, 2008)
《The Algorithm Design Manual》要比Dasgupta所著的那本《Algorithms》更长,更全面,也更实用,而且涉及到的数学也更少。它差不多就是试图教你如何识别问题并使用正确的算法来解决问题、以及给出一个清晰的算法解释的那本书。
该书内容丰富,各个主题几乎无不涉及,从常见的各种数据结构到算法策略、可计算性。如果想当做教科书,该书每章结尾都有很多练习,值得推荐。这本书充满了激情的“战争故事”,显示了算法在现实世界编程的影响。
《Introduction to Algorithms》
作者:Cormen、Leiserson、Rivest、Stein(CLRS)
出版社:The MIT Press; 3rd edition (July 31, 2009)
中文版:《算法导论》
译者:殷建平、徐云、王刚、刘晓光、苏明、邹恒明、王宏志
出版社:机械工业出版社; 第1版 (2013年1月1日)
在江湖中流传的各种版本“所有程序员必读之书”的清单中,《算法导论》就占据了半壁江山。这本书将严谨性和全面性融为一体,深入讨论了各种算法。实际上,几乎没有读者会读完整本书。不过,全书各章自成体系,可以作为独立的学习单元。它是全球读者最多的算法圣经。
该书的特点是选材经典、内容翔实、结构合理、逻辑清晰。每章前半部分介绍了讲授和学习算法的有效方法,后半部分为更专业的读者和求知欲强的学生提供了更引人入胜的资料来讨论这个迷人领域的各种可能性和挑战,对本科生的数据结构课程和研究生的算法课程而言是非常棒的教科书。
比如说,有整整一章是关于Van Emde Boas树,写得很工整,这有点奇怪,像的平衡树结构的插入、删除、就像查找、继承一样好,也许以前的书籍可能如此,但它是第一个没有包含Van Emde Boas树的算法导论。
《Algorithm Design》
作者:Kleinberg、Tardos
出版社:PEARSON EDUCATION; 1 edition (2013)
《Algorithm Design》广受好评,堪比CLRS所著《Introduction to Algorithms》,被推荐为关于算法设计和分析的一本不可多得的优秀入门书。我发现,这本书与CLRS所著的书相比,该书将直观性与严谨性完美结合起来。覆盖面比较宽广,凡属串行算法的经典论题,都有所涉猎。
《Advanced Data Structures》
作者:Demaine
《Advanced Data Structures》是一套讲稿和笔记,而非一本书。如果你想要一套条理清楚但不难综合的数据结构的学习资料,在大多本科课程中,你不大可能看到,因此这套讲课和笔记,功德无量。
这些笔记没有出单行本的计划,所以如果您尚未看过这些资料,就必须观看教学视频。
《Purely Functional Data Structures》
作者:Okasaki
Cambridge University Press (June 13, 1999)
出版社: Cambridge University Press
《Purely Functional Data Structures》读起来很有趣,但不同于其他算法和数据结构的读物的是,我从这本书中,还没能得到真正解决实际问题的重要能力。
在我读完这本书后过了几年,有人告诉我,推理出纯函数冗余数据结构的性能并不难。我就向他们请教这本书中把我难倒的证明部分,我并不是在讨论那些晦涩难懂的超难习题,而是说这本书的主要内容,作者有太多过于明显的解释性的东西。但是并没有人解释。这种东西的推理比大家说的还要难。
《Higher Order Perl》
作者:Dominus
出版社: Morgan Kaufmann Publishers
中文版:《华章程序员书库:高阶Perl》
译者:滕家海
出版社:机械工业出版社
《高阶Perl》在Perl领域深入探讨了各种最新的主题,如递归、迭代器、过滤器、划分、数值方法、高阶函数、惰性求值等内容,并将这些转换成现实变成工作中强有力的实用工具:HTML处理、数据库访问、网页抓取、家庭理财等等。
该书恰当地介绍了使用Perl的函数式编程。通过这本书的学习,你可能像Python或Ruby那样很容易进行工作。
不过,如果你跟得上潮流,你会发现这本书可能有点过时,因为讲解的是2005年的Perl 5,而现在是2015年12月25日发行的Perl 6。不过,这本书提到的思想,目前已成主流。
《Algorithms》
作者:Levitin
出版社:Pearson; 3 edition (October 9, 2011)
“强化学习的其他特点,包括:章节摘要,习题提示。这是一本详细的解决方案手册。”、“学生通过习题提示和章节摘要进一步支持学习。”其中一个广告甚至印在书上。
当我看到这两个广告后,就在亚马逊下了订单购买《Algorithms》。但在我拿到这本书后,我唯一的自学资源却是在雅虎问答(Yahoo Answers)里的一些帖子,在那里你能找到提示或者解答。
最后,我拿起了Dasgupta的著作来取代了这本书,因为他的网站资源可以免费使用。
《Probability and Computing: Randomized Algorithms and Probabilistic Analysis》
作者:Mitzenmacher、Upfal
出版社: Cambridge University Press (January 31, 2005)
我获得的算法知识可能比其他任何算法书籍讲述的都多。许多随机算法移植到其他应用程序虽然很琐碎,但却可以简化很多事情。
《Probability and Computing: Randomized Algorithms and Probabilistic Analysis》有关概率学的介绍部分很翔实,就算读者不具备任何概率学的背景也能轻松入门。此外,的内容(例如,)对许多计算机科学理论的证明很有用,这些在我所阅读到的概率学介绍内容中都没有提到。
《Introduction to the Theory of Computation》
作者:Sipser
出版社:Cengage Learning; 3 edition (June 27, 2012)
中文版:《计算理论导引》
译者:段磊、唐常杰
出版社:机械工业出版社,第一版
《计算理论导引》以独特的视角,系统介绍了计算理论的三大板块:自动机与语言、可计算性理论、计算复杂性理论。讲述了宽泛的数学原理,没有拘泥于某些低层次的细节。
在证明之前,都有直观的“证明思路”,帮助读者理解数学形式下蕴涵的概念。很多重要的结果,如定理,都被作为练习题。所以你真的需要做这些关键练习题。但是,大多数关键练习题没有提供答案,因此你也无法知道你解答是否正确。
如果想选择更为现代的主题,也许可以阅读Aurora和Barak的著作。
《Computation》
作者:Bernhardt
《Computation》这部教学影片涵盖了一些计算机理论的重点部分。影片讲解令人愉悦,为了观看Bernhardt讲解的内容,这个影片我已经观看不止一次了。该影片的受众是那些没有计算机科学背景的一般程序员。
《An Introduction to Computational Learning Theory》
作者:Kearns & Vazirani
出版社:The MIT Press (August 15, 1994)
《An Introduction to Computational Learning Theory》是一本非常经典的读物。但是这本书已经过时(InfoQ注:该书1994年出版,距今已经22年了),而且漏洞百出,没有勘误。我最终从几门课程拼凑了一些笔记,一个是Klivans的著作,另一个是Blum的著作。
操作系统
为什么要关心操作系统?因为,掌握一些关于操作系统的知识,可以让你节省几天或一周的调试时间。 这是Julia Evans博客上经常提到的话题,我发现,就我个人经验来说,确实如此。
那些建立可行的系统并了解一些操作系统知识的人,却没有发觉如果有操作系统知识的话会很节省时间,这点我很难想象。
可是,读过操作系统书籍的人往往有偏见——正是做这方面的相关人士,如果你是骨灰级玩家,除非阅读这些,你可能得不到同样的结果。
《Operating System Concepts》
作者:Silberchatz、Galvin、Gagne
出版社:Wiley; 9 edition (December 17, 2012)
中文版:《操作系统概念》(第七版)(翻译版)
译者:郑扣根
出版社:高等教育出版社; 第1版 (2010年1月1日)
好吧,这是Comet Book成为标准之前,我们在Wisconsin就用过的一本书。
《操作系统概念》涵盖了高阶概念并击中要点,但是在技术层次的深度稍显不足,没有详细阐述事情是如何工作的,也没有清晰列出更高级的主题。
顺便说一下,我听说了关于Comet书籍的好消息,但是我不敢妄言,毕竟我还没有阅读过。
《xv6》
作者:Cox、Kasshoek、Morris
这本《xv6》真的太棒了!它解释了你如何能够在真实系统上有效运作,你可以设想自己实现一个可执行的操作系统。按照本书写作的设计,作者倾向于简单的实现而非优化的实现,因此,书中使用的算法、数据结构和平常的生产系统完全不同。
这本书与介绍现代操作系统如何工作的书籍配合阅读,比如Love著的《Linux Kernel Development》或者Russinovich著的《Windows Internals》,学习效果会更好。
《Linux Kernel Development》
作者:Love
出版社:Addison-Wesley Professional; 3 edition (July 2, 2010)
《Linux Kernel Development》的书名可能有误导之嫌,这不是关于Linux内核开发的读物,基本上是一本阐述Linux内核如何工作的书籍:事物是如何契合的,使用了什么算法和数据结构等等。我阅读的是第二版,现在已经完全过时了。
第三版内容有所更新,但是也引进了一些错误和矛盾之处。而且,这一版本仍然过时,这本书2010年出版,讲的是内核2.6.34。虽然如此,该书仍然不啻一本优秀的介绍现代操作系统原理的读物。
该书还有一个缺点,在作者拿Linux和Windows进行比较时,有失客观,基本上就是每次比较的时候,就宣扬Linux是明确无疑的正确选择,Windows总是干蠢事。总体来说,Linux和Windows我都喜欢,在有些领域,Windows做得更好。而且在有些地区,Windows已经领先很多年了。但在这本书中,你甭想看到类似这些评价。
《Windows Internals》
作者:Russinovich、Solomon、Ionescu
出版社:Microsoft Press; 6 edition (March 25, 2012)
中文版:《深入解析Windows操作系统:第6版(上册)》
译者:潘爱民、范德成
出版社:出版社: 电子工业出版社; 第1版 (2014年4月1日)
《深入解析Windows操作系统》是阐述现代操作系统如何工作最全面的一本书,只不过碰巧这本书是关于微软Windows。作为从*nix走过来的人,看到Windows和*nix不同的差异,这样的阅读非常有趣。
然而,该书并非简单的入门书,在阅读本书之前你必须掌握一些操作系统知识。
如果想买这本书,你要等到2017年初发行的第七版。
《The Little Book of Semaphores》
作者:Downey
《The Little Book of Semaphores》是一本这样的读物:列出一个主题,通常从操作系统的教科书中抽取一两个章节,然后拼凑成为自己长达300页的书。
这本书是一系列的习题,有点像小型提纲,但更多的是阐述。它首先解释了什么是信号量,然后给出构建高并发原语知识的一系列习题。
在我开始编写并发线程代码时,这本书提供了很大的帮助。我订阅了Butler Lampson学院关于并发的资料,我喜欢把并发相关代码塞到别人写的黑盒。但是有时候你坚持自己写黑盒的话,如果是这样,这本书有很好的导论,要求思考方式才可能写出不是完全错误的并发代码。
我希望有朝一日,能有这样的一本书问世:既照顾低水平的读者,又兼顾高水平读者,我很喜欢这样的写作设计。从几个指令集原语不同的内存模型的体系结构(如x86和Alpha),而不是从信号量开始讲起。如果今天我写低劣的低级线程代码,我会更喜欢用C++ 11的线程原语,所以我想用这些东西而非信号量。如果由我来写线程代码的话,我可能会用Win32 API来编写。但到目前为止,还不存在这样的一本书。以后如果有这样一本书问世,那将是最好不过的了。
我听说Doug Lee的Java并发编程非常不错,但我只泛泛而读没有深入研读。
计算机体系架构
为什么要关心计算机体系架构?当你进行底层性能优化的时候,你所学到的具体事实和细节,将会非常有用。但是,真正的价值就是学习如何在性能和其他因素进行权衡,无论是功耗、成本、体积、重量,亦或者其他因素。
从理论上讲,这种推理应该不分专业进行教授,但我的经验是,那些学习计算机体系结构的人更可能会“得出”那种推理和粗略的计算:才能让他们抛开一个没有理由在性能上2倍或10倍(或100倍)的因素。听上去很显然,但是我想到大公司的多个生产系统放弃10到100倍的性能,而以一个标准来运行,甚至2倍的性能差异,都足以支付VP的薪水。全是因为人们没有意识到他们的设计带来的性能影响。
《Computer Architecture: A Quantitative Approach》
作者:Hennessy、Patterson
《Computer Architecture: A Quantitative Approach》教你如何用多约束(如性能、TCO(总开销)、功率等)进行系统设计,以及如何推论权衡。它主要以微处理器和超级计算机为例。
该书的新版增加了实质性的补充,这个版本才是你真正想要的读物。比如,新版增加了一个关于数据中心设计的章节,回答了以下问题:用于电力、功率分布、制冷的运营开支OPEX/资本支出CAPEX,以及支持团队和机器的支付费用,使用低功耗机器对tail larency的结果质量及影响(以必应搜索的结果为例),在设计数据中心时应该考虑哪些其他因素。
假设读者具备一些背景,但背景已在附录中提供,并且可免费在线获取。
《Modern Processor Design》
作者:Shen、Lipasti
出版社:Waveland Press, Inc.; 1 edition (July 30, 2013)
《Modern Processor Design》展示了设计Pentium Pro(1995年)时代高性能微处理器所需要了解的大部分内容。因为这种处理器的复杂性,阐述清楚绝非易事。另外,还介绍了一些更为先进的想法和从各种工作负荷可以运行的平行计算的范围(以及你可能会如何进行如此计算)。该书有一个很长的章节,是关于值预测,因为作者发明了这个概念,当第一版发行的时候,还很热门。
对于纯CPU架构,这本可得到的读物大概是最好的。
《Readings in Computer Architecture》
作者:Hill、Jouppi、Sohi
出版社:Morgan Kaufmann; 1 edition (September 23, 1999)
因为历史原因而阅读,看看我们所理解的解释有多好。比如,比较Amdal关于定律的论文(没有公式,只有一幅并非显而易见的图表的两张纸),相对与现代教科书的表述(一个段落,一个公式,或者一幅图表来阐明,虽然通常来说足够清晰,不需要额外的图表)。
糟糕的是,《Readings in Computer Architecture]》看上去让你后退得更远。因为计算机架构真的是很年轻的领域,这里没有什么真正难以理解的东西。如果你想看到一个动人心魄的例子,例如我们怎样更好解释这一些,像比较Maxwell在方程组的最初论文与现代对同一事物的解释。如果你喜欢历史的话,这本书很有趣。但是如果你只是想学习的话,它勉为其难。
博弈算法理论、拍卖理论、机制设计
为什么要关注这些知识(博弈算法理论、拍卖理论、机制设计)?因为这些知识介绍了世界上最大的科技公司在广告收入的运作方式,而这些广告是通过拍卖来销售的。该领域介绍了它们运作的方法和理由。另外,当你尝试弄明白如何设计有效分配资源的系统,这些知识就派上用场了。此外,如果你玩桌游,拍卖理论解释了为什么通过拍卖机制来固化博弈失衡是重要的,往往使游戏更糟。
尤其对设计公司内部激励相容制度(粗略的说,就是如何创建能提供人们出于私心而追求最佳利益的全局最优结果的系统)的人员而言,这些书应为必读书籍。如果你曾在两家大公司供职过,其中一家建立了有效的内部激励相容制度,而另一家没有建立相应制度。你就会发现,没有建立内部激励相容制度的那家大公司烧了大把大把的钱,因为这些人建立了超级没用的激励系统。
这个领域展现了这么一幅画卷,让你了解什么样的机制会带来什么样的结果。通过阅读案例研究,你会得到一个耗资数百万甚至数十亿美元的错误列表,洋洋洒洒,也很有趣。
《Auction Theory》
作者:Krishna
出版社:Academic Press; 2 edition (August 26, 2009)
中文版:《拍卖理论》
译者:罗德明、奚锡灿
出版社:中国人民大学出版社
上一次我阅读《拍卖理论》的时候,它是当时唯一对拍卖理论进行全面且最近介绍的一本书。在第一章中,涵盖了经典的第二价格拍卖的结论,然后涵盖了风险规避、竞标操纵、多个拍卖、非对称信息和其他现实世界的问题。
该书涵盖了拍卖的大部分理论,对深入理解拍卖理论的主要脉络非常必要。但这本书相当枯燥无趣,不大可能激起阅读欲望。除非你对这个主题感兴趣。需要了解基本的概率学和微积分学的知识。该书对致力拍卖研究的研究生是不可或缺的读物。
《Snipers, Shills, and Sharks: eBay and Human Behavior》
作者:Steighlitz
出版社: Princeton University Press (April 1, 2007)
《Snipers, Shills, and Sharks: eBay and Human Behavior》看上去似乎是专门为外行介绍拍卖理论、带有娱乐性质的书籍。该书解释了eBuy的工作方式及理由,正如书名的副标题所言,作者还探讨了人类在eBuy和其他地方拍卖中的怪癖行为。这本书妙趣横生,无需读者具备数学背景,可能包含了Krishna所著《Auction Theory》的少量内容,能让读者对拍卖理论产生兴趣。
《Combinatorial Auctions》
作者:Crampton、Shoham、Steinberg
出版社: The MIT Press
《Combinatorial Auctions》所讨论的是,是像美国通信委员会(FCC)那次频段拍卖,由于拍卖机制设计中的“漏洞”引起数亿甚至数十亿美元的价差被摆上台面的案例(InfoQ注:有兴趣的读者可以通过google检索“美国拍卖600MHz频段”来了解这个事件)。该书虽然是由不同作者共同撰写的读物,但读起来仍然行云流水一气呵成,让我乐意阅读。
这本书在组合拍卖领域有着深度和广度,于细微处见功夫,它还罗列了详细的作者和主题索引,排版质量非常棒,以至于可以跳过开头提到的Krishna的著作进行阅读,但我不会推荐它。这本书对于想了解组合拍卖的研究人员和从业者,都是必不可少的读物。
《Multiagent Systems:Algorithmic,Game-Theoretic,and Logical Foundations》
作者:Shoham、Leyton-Brown
出版社:Cambridge University Press; 1 edition (December 15, 2008)
《Multiagent Systems:Algorithmic,Game-Theoretic,and Logical Foundations》最槽的就是书名了。然而,它是Multiagent System方面最值得阅读的读物之一。
该书涵盖了基本的博弈论、拍卖理论,以及在计算机科学中读者可能不知道的其他经典主题,囊括了很多新颖的前沿理论,还有计算机科学和这些主题的交集内容,比如博弈学习模型等,甚至还有逻辑学的内容(这也是Shoham最关注的方向,将博弈理论上升到哲学层次)。这本书非常有特色,前面几章有很多例子,计算机科学学术味很浓。该书假定读者对主题没有特定的背景。
《Algorithmic Game Theory》
作者:Nisan、Roughgarden、Tardos、Vazirani
出版社:Cambridge University Press; 1 edition (September 24, 2007)
《Algorithmic Game Theory》包含了博弈算法理论的各种调查结果。要求读者具有相当数量的背景(首先要阅读过Shoham和Leyton-Brown的著作),例如第五章基本上是Devanur、Papadimitriou、Saberi和Vazirani的JACM论文:
《Market Equilibrium via a Primal-Dual Algorithm for a Convex Program》(《通过用于Convex程序的原始对偶算法的市场均衡》),并引出一些相关问题,让读者有更上一层楼的动机。如果你深入了这本书的话,会发现该书阐述很棒,而且很有趣。但如果你想通过阅读一本书来窥探一个领域的话,它未必是你想要的那种书。
杂项
《Site Reliability Engineering》
作者:Beyer、Jones、Petoff、Murphy
出版社:O'Reilly Media; 1 edition (April 16, 2016)
中文版:《SRE:Google运维解密》
译者:孙宇聪
出版社:电子工业出版社; 第1版 (2016年10月1日)
《SRE:Google运维解密》可以让读者学习到Google工程师在提高系统部署规模、改进可靠性和资源利用效率方面的指导思想与具体实践——这些都是可以立即直接应用的宝贵经验。任何一个想要创建、扩展大规模集成系统的人都应该阅读,该书针对如何构建一个可长期维护的系统提供了非常宝贵的实践经验。
要看更丰富的简要说明,请阅读这本22页的该书的笔记。
《Refactoring》
作者:Fowler、Beck、Brant、Opdyke、Roberts
出版社:Addison-Wesley Professional; 1 edition (July 8, 1999)
中文版:《重构:改善既有代码的设计》
译者:熊节
出版社:人民邮电出版社; 第2版 (2015年8月1日)
那时候当我读这本《重构:改善既有代码的设计》时,由于它在关于代码异味的单独章节所花的篇幅,使得这本书非常值这个价。该书非常成功,因为它使重构和代码异味的观念成为主流。
Steve Yegge曾对这本书不吝赞誉之词:
2003年10月,我第一次阅读这本书,有一种不寒而栗的感觉。如果你意识到,当你想离职时,你已经工作5年。转天我就随意问周围:“嗯,你已经读过重构方面的书,对吧?我只是随便问问,因为我很久以前读过,当然不是现在。”在我所调查的20个人中,只有一个人读过。感谢上帝,所有的人都很尴尬,不只是我。
……
如果你是资深工程师,你会发现该书中至少80%,都是你所熟知的东西。但该书罗列了所有的名称,并客观地讨论这些技术的利弊,这一点很有用。它戳穿了我刚成为程序员时所珍藏的若干个“秘籍”的真相。不注释代码?局部变量是万恶之源?这疯子是狂人吗?要不要阅读这本书,取决于你自己!
《Peopleware》
作者:Demarco、Lister
出版社:Addison-Wesley Professional; 3 edition (June 28, 2013)
中文版:《人件(原书第3版)(珍藏版)》
译者:肖然、张逸、滕云
出版社:机械工业出版社; 第1版 (2014年9月1日)
在大学时我读到这本《人件》,该书似乎很令人信服,甚至所有的研究结果都支持该书的观点:不设置截止日期就比设置截止日期要好;办公室比隔间要好,等等。所有开发人员跟我讨论的时候,基本都赞同这些观点。
但实际上每家成功的公司都是以截然不同的方式运作的。甚至微软公司也从个人办公室转为开放式办公室进行了建筑改造。是不是这些观点都无所谓?如果真的很重要的话,那些公司怎么会成为真正信徒,像Fog Creek公司不去践踏竞争对手?
因为该书符合我的“偏见”,我就希望这本书是正确的。但是,荟萃分析(InfoQ注:Meta分析,指将多个研究结果整合在一起的统计方法)的理念让我用鉴定的眼光重读来查证主要来源。
《Renegades of the Empire》
作者:Drummond
出版社:Crown; 1 edition (November 16, 1999)
《Renegades of the Empire》讲述了DirectX历程的故事。它还揭示了今天的微软狼性文化是怎么形成的。阅读介绍:
微软未必会雇佣像盖茨的人(虽然企业园区有不少这样的人),但会招聘那些有着更为显著的盖茨特征的人——傲慢、进取心和高智商。
……
因为嘲笑某人的想法是“愚蠢的”,或者更为槽糕的是,“胡说八道”——盖茨因此臭名昭著——只是为了看他如何捍卫一个位置。这种敌对的管理技术贯穿一系列的命令,创造了一种冲突的文化。
……
微软建立了达尔文的秩序,资源经常被掠夺,囤积力量、财富和威望。一名外出休假的经理回来时可能会发现他的部门被竞争对手袭击,他的项目被勒令降级或者完全取缔。
在微软面试:
“你喜欢微软什么呢?”“比尔踢屁股。”St. John说,“我喜欢踢屁股。我喜欢那种扼杀竞争对手和支配市场的感觉。”
结果St. John被雇佣了。多年来他没有犯任何错误。这本书就讲述了他的故事,以及像他那样的员工的故事。如果你想在微软公司谋差,你就需要读这本书。我希望我加入之前就读过这本书而不是之后!
数学
为什么要关注数学?从纯ROI(InfoQ注:Return On Investment,投资回报率)观点来看,我怀疑,对于99%的工作,学习数学是值得的。据我所知,我用数学比大多数程序员要多,但我并没有那么经常使用数学。不过,有正确的数学背景可能会派上用场。我很享受学习数学的乐趣。
《Introduction to Probability》
作者:Bertsekas
出版社:Athena Scientific; 2nd edition (July 15, 2008)
中文版:《概率导论(第2版)》(修订版)
译者:郑忠国、童行伟
出版社:人民邮电出版社; 第1版 (2016年1月1日)
《概率导论》是入门的大学课程,对 阐述定义比较严谨、直观。对任何关心严密推导的读者而言,该书后面有一些更为详细的习题。有很多可用解决方案的练习题,使得本书更适宜作为自学用书。
《A First Course in Probability》
作者:Ross
出版社:Pearson Prentice Hall; 8th edition (January 7, 2009)
中文版:《华章教育·华章数学译丛:概率论基础教程(原书第9版) 》
译者:童行伟、梁宝生
出版社:机械工业出版社; 第1版 (2014年1月1日)
为了使学生购买《概率论基础教程》,该书经常推出新版本,亚马逊定价更是高达174美元,我曾跟作者请教过这个问题,他抱怨说,这几年,二手书市场破坏了教科书的收入,而作者的版税并不多,所以要有更多收入,就不得不保持每两年推出新版的节奏来保证版税收入。
新作者要编写前人著过的经典书籍,经常大发牢骚,因为最早的作者通常比后来的作者拿更多的版税,即使他的后续版本并没有什么更新。
我在Wisconsin学习概率学的时候,该书是一本标准的教科书。我真的想不起有谁发现这本书有所帮助。
《Introductory Combinatorics》
作者:Brualdi
出版社:Pearson; 5 edition (January 7, 2009)
中文版:《组合数学(原书第5版) 》
译者:冯速
出版社:机械工业出版社; 第1版 (2012年5月1日)
Brualdi是一名大教授,是我大学生涯最好的教授之一。但是他著的《组合数学》充满了错误,而且也不特别清晰。自从我使用该书后,有两个新版本,但从亚马逊评论来看,这本书仍然有很多错误。
至于另一本基础入门型的教科书,我听过关于Camina和Lewis合著的《An Introduction to Enumeration (Springer Undergraduate Mathematics Series)》好消息,但我自己没有读过。此外,Lovasz的《Combinatorial Problems and Exercises (AMS Chelsea Publishing)》是一本关于组合数学的名著,但它并未被广为人知。
《Calculus》
作者:Apostol
出版社:Wiley; 2nd edition (January 16, 1991)
《Calculus》第一卷涵盖了你所期望的微积分I和微积分II的内容。第二卷涵盖了线性代数和多元微积分。在多元微积分之前,讲述线性代数,这样使得多元微积分更易理解。
从编程角度来看,微积分学也是很有意义的。因为我在微积分得到的价值观就是近似应用等等。教授这一连串的概念,很清晰。
如果你没有教授或助教帮你的话,该书可能是一本粗略的入门书。Spring SUMS系列丛书在各门功课上更易自学,但我并没有读过它们的微积分书籍,因此,我不敢妄下结论来推荐。
《Calculus》
作者:Stewart
出版社:Cengage Learning; 7 edition (2012)
中文版:《微积分(第六版)》(双语教材)
译者:张乃岳
出版社:中国人民大学出版社; 第1版 (2014年10月1日)
《微积分》是那些作者通过无关紧要的变更推出新版来赚钱的众多书籍中的一本。这是Wisconsin大学Non-Honor学位的标准教科书。结果是,我教了很多人用Apostol的那本书所教授的方法来计算复杂的微积分,对许多人而言,更直观一些。
该书采用的方式是,对于某种类型的问题,你应该将该模式匹配很多可能的公式,然后套用该公式。而Apostle更多的是教授你一些技巧和直觉,让你足以应付各种各样的问题。我不知道你为什么会买这本书,除非你需要一些类。
硬件基础
为什么要关注硬件基础?人们经常宣称,要成为优秀程序员,你必须理解所用的每一个抽象概念。这是无稽之谈,因为现代计算过于复杂,以至于任何人都不可能真正完全理解到底发生了什么事情。事实上,现代计算之所以能高效完成它所做的工作,是因为它不需要程序员深入了解底层的相关内容,大部分也低于你的水平。
话虽如此,如果你对底层软件充满好奇,这里有一些适合你的入门书籍。
《nand2tetris》
作者:Nisan、Shocken
如果你只想读一本单一内容的书,那么非这本《nand2tetris》莫属。它是一本关于逻辑门和布尔逻辑的“101级”入门书。正如书名所示,它带你从与非门(NAND gate)到编一个可用的俄罗斯方块游戏。
《Fundamentals of Logic Design》
作者:Roth
出版社:CL Engineering; 5 edition (June 11, 2003)
《Fundamentals of Logic Design》在关于逻辑门和逻辑设计的细节上比《nand2tetris》还要多。该书有大量习题,似乎是为自学而著。注意,上面的链接是第五版,目前有更贵的新版本,但似乎没有什么改进,而且新版也有很多错误,而且更昂贵。
《CMOS VLSI Design》
作者:Weste、Harris、Bannerjee
出版社:Pearson; 4 edition (March 11, 2010)
中文版:《CMOS超大规模集成电路设计(第4版) 》
译者:周润德
出版社:电子工业出版社; 第1版 (2012年7月1日)
逻辑门下一级的就是VLSI(very large scale integration),即超大规模集成电路。然而,在今天真的没有任何意义。
《CMOS超大规模集成电路设计》比其他书籍更有广度和深度,并且阐述极为清晰。在探索设计空间,比如,加法器的章节,不仅仅提及了几种不同的类型,而且也提供了问题和解决方案,非常适合自学。
《CMOS Digital Integrated Circuits》
作者:Kang、Leblebici
《CMOS Digital Integrated Circuits》是Wisconsin当前的教科书。但这本书很难跟上,助教基本上重新解释了几乎所有的必要项目和考试。我觉得它是参考书而不是用来学习的读物。
与West等人相比,Weste 花费了更多的精力讨论设计中的折衷,如,创建并行前缀树加法器时,在设计空间的某个特定点,它意味着什么?
《Semiconductor Device Fundamentals》
作者:Pierret
出版社:Addison Wesley; 2nd edition (April 12, 1996)
超大规模集成电路(VLSI)下一级,也就是晶体管,你将了解晶体管实际上是如何工作的。
《Semiconductor Device Fundamentals》真正完美地解说了固态设备(SSD)。该书指出了你要真正理解诸如波段图解的这些东西,需要知道什么。然后用这些基础原理和清晰的解释,给你建立一个良好的思想模型,理解不同类型的交汇点和设备的工作原理。
《Pentium Pro and Pentium II System Architecture》
作者:Shanley
出版社:Addison-Wesley Professional; 2 edition (January 10, 1998)
与本文提到的其他书不同,《Pentium Pro and Pentium II System Architecture》是关于实践而非理论。它有点像Windows内部,因为它涉及一个真实的工作系统的细节。主题包括硬件总线协议、I/O实际上是如何工作的(如APIC,Advanced Programmable Interrupt Controller,即高级可编程终端控制器)等等。
实际介绍的问题,就是从8080的CPU以来,复杂性一直呈指数级的增长。当你学得越深,你就越容易理解系统重要的可移动部分,而知识越不相关。因为总线和I/O协议不得不操作多处理器,这本书似乎妥协了,这些系统包含了现代系统中的许多元素,只不过是以更简单的形式。
未尽事宜
在这些我喜欢的读物中,我会说,这些图书中,软件读物最多占据25%、硬件读物占据5%。一般说来,未在清单中罗列出来的读物更为专业。清单还缺少很多领域的主题,如PL,关于如何学习编程语言的实用书籍、网络等等。
未涉及某些领域的原因有多种,比如我没有列出任何PL相关书籍,因为我不阅读PL方面的书籍。我没有提到网络是因为我虽然读过一些书,但我这方面的了解程度不足以提供有用书籍的建议。
绝大部分硬件相关的书籍都没有包含在内,因为它们涉及到你不会关心的内容,除非你是专家(比如容错电路设计(《Skew-Tolerant Circuit Design (The Morgan Kaufmann Series in Computer Architecture and Design》,Harris著)或超快光学《Ultrafast Optics》,Weiner著))同样也适用于数学和计算机科学理论。
我遗落了相当数量的一些我认为是名著的读物,因为在我日常编程生活中基本没有机会用到,比如极值组合论(Extremal Combinatorics)。我也没有罗列那些我没有读完的书籍,除非我停下来,因为这些书籍极为晦涩难读。因为我没有读完像SICP和The Little Schemer的书籍,这意味着我无法列出经典的清单。那些书籍很好,只是我没有完成阅读的原因。
清单中还不包括历史和文化相关的书籍,像《Inside Intel》或《Masters of Doom》。我可能会在未来某个时候,在清单中添加一个类别,就是我一直尝试的实验,像Julia Evans(意识流,文字更少或者没有草稿)那样撰写。
我必须回去重读十多年前曾经阅读过的书,然后写出有意义的评论,但这不符合我这个实验。关于这一点,因为这份清单是根据我记忆写的,几年前我就几乎没再读过那些所有的书,而且可能有所遗忘很多书,我打算日后将补充。
今日荐号:细说云计算
探讨云计算的一切,关注云平台架构、网络、存储与分发。这里有干货,也有闲聊。
今日荐文
点击下方图片即可阅读
大规模Nginx平台化实践,
京东能提供哪些参考经验?
喜欢我们的会点赞,爱我们的会分享!
国庆期间,我造了台计算机
每个时代,都不会亏待会学习的人。
大家好,我是 yes。
对于我们程序员来说计算机的重要性不言而喻,相信大家对计算机内部也有一定的了解。
但是大家有没想过为什么一堆逻辑门组合起来就能运算了?它是如何运作来实现加减法的?
为什么 cpu 会不停地取指执行?是什么在驱动着它?
今天我就和大家一起来探索一下底层的奥秘,但是术业有专攻,我们大致的了解一下即可,很多细节不清晰也不影响。
不过相信通过这篇文章你会对底层有不一样的认识,包括运算单元、内存、时钟、地址、溢出、补码等等。
先打个预防针吧,这篇文章有很多电路图,你可能感觉这啥啊,和我们开发有关系吗?
看下去你会懂的,虽说平日里我们都是 CRUD Boy,但是我们也得时刻保持着好奇心,要有求知欲和探索精神。
正文
这个故事得从「电」开始说起。
生活中电无处不在,而它却时刻保持着神秘感,为何插上电我们的屏幕就会亮?我们的服务器就能跑?
电是如何来的?
电起源于电子的运动,我们知道一切物质都是由原子组成的,而原子又是由中子、质子和电子构成。
在某种情况下电子从原子中电离出来,这样电就产生了。
质子和电子都具有带电荷的特性,质子带正电荷、电子带负电荷。
而异电相吸,同电相斥,当质子数和电子数相等的时候是最稳定的,如果数量不平衡也会往趋于平衡的方向发展 。
像雷雨天气,云层下层积累电子而云层顶层失去电子,而闪电就是大量的电子迅速从一端转移到另一端产生的结果,为了趋于平衡。
题外话:细心的朋友可能看到这原子核质子不都合在一起了啊,不是说同电相斥嘛?这是因为有个叫强内力的玩意聚集了它们,释放核能的原子核裂变就是由强内力导致的。
相信大家都做过电池点亮灯泡的物理实验。
这其实就是电池发生化学反应,在负极产生多余的电子,然后通过回路中的原子类似接力的形式,一个原子得到电子之后会传递给相邻的另一个原子,如此循环传递电路就形成了,最终通过灯泡到达电池的正极。
改装下再套上个外壳,手电筒就这样被造出来了。
而手电筒不仅仅可以用来照明,还能用来通信。相信大家都看过类似的电影场景,我这手电筒的光闪三下咱们就上!
而说到这样简易的通信就不得不提摩尔斯电码 ,相信大家也从各渠道对摩尔斯电码有一定的了解,比如「星际穿越」这部贼好看的电影。
在 19 世纪初期,那时候的远距离通信还得利用马车等工具长时间运输传递,人们一直在摸索即时远距离通信的方法。那时的摩尔斯就开始埋头实验,最终发明了电报。
电报的思想和上述说的手电筒思想一样,手电筒通信的思想是通过开关来控制灯的亮暗,而电报利用的是电磁现象。
将导线缠绕在铁棒上,然后通电之后铁棒就变成了磁铁,断电了磁性又会消失,然后再搞个发声器,通过磁性来吸引可动棒敲击发声。
通电后可动棒被拉下,敲击下方就会发出 “滴” 的声音,断电则可动棒复位,敲击上方发出 “嗒” 的声音。将快速的滴答作为点,慢速的滴答作为划。
通过导线的长距离连接就能实现远距离通信,通过判别点和划的组合查阅摩尔斯电码表,转成最终的信息。
如果要双向通信,就再搞一个反过来部署就好了,这就是电报机了。
不过导线是有电阻的,导线越长电阻越大,所以是有距离限制的,不过这难不倒我们,最简单的方法就是转发一下。
在中间距离也建个电报站,然后雇一个人,得到发送方的电报信息之后,重新敲一遍发送给真正的接收方,但是这需要多余的人力,所以可以如下图所示,搞个棒子连起来带动下一个开关的输出 。
这其实就是继电器原理,我们来看看继电器是如何的设计的。
下方通电产生磁力,吸引上方的金属杆挂下,然后上方形成回路因此也通电了,这样远距离传输的微弱电流就被又一次放大输出了,所以最终的远距离电报应该是这样的。
可以看到继电器这个发明是真的巧妙。
理解了上面所述的电的生成、电报以及继电器之后我们再来看看二进制 。
基于二进制的数字系统是最简单的,只有 0 和 1,不能再进一步简化了,而简单就代表着清晰,就像开关要么开要么关。
而二进制的组合又可以代表多种可能,比如第一个 0 表示男,1 表示女 ,第二个 0 表示胖,1 表示瘦。
让我们再回到之前的电池电灯图中,这次搞两个开关。
可以得知两个开关都闭合电灯才会亮,如果转化成二进制表示,0 表示开关断开,1 表示开关闭合,0 表示灯泡不亮,1 表示灯泡亮,总结成一张表格的话就是:
左开关右开关灯泡 000010100111
这其实就是我们熟知的 AND 操作,如果把电路稍微改一下就是 OR 操作了。
如果把很多开关组合起来就能执行简单的逻辑任务,但是开关需要手动的去控制。
记得之前提到的继电器吗?它也能串联或者并联电路,而且可以被其他继电器联动控制,不需要一个一个拨动,因此用继电器来组合更加合适,而继电器的组合称之为逻辑门 。
简单点的就像下图所示,开关闭合灯泡就会亮。
有些人觉得这不是多次一举吗,这其实是个缓冲器,可以延迟信号,也可以放大信号,而且这个电路比较简单,实际上有很多组合,比如下图的这个反向操作,开关闭合的灯反而不会亮。
还有像这样的串联组合,只有两个开关都闭合灯泡才会亮。
当然这里的输入不一定得是开关,输出也不一定得是灯泡,只是为了更加直观的表现出来,不过这样画电路太麻烦了,于是电气工程师们就搞了个符号来表示这些电路,比如上面的串联其实就是 AND 操作,是与门。
简化一下上面的图就变成下面的样子。
如果电路图如下所示,就是并联,随便一个开关开了灯泡都会亮,这就是或门。
简化符号是这样的:
前面还提到个反向操作的,开关闭上灯泡反而不亮的叫反向器,符号如下图所示。
我们再来看看这样的电路。
只有当两个开关都断开的情况下灯泡才会亮,任何一个开关闭合灯泡都会熄灭,这个操作和 OR 操作相反,称之为 NOR 即或非门,简化后的符号比或门多了个小圆圈,代表反向。
或者这样,组合着画也一样。
然后我们再来看看这种电路,只有两个开关都断开才会熄灭,这和与门正好相反,称之为 NAND 与非门。
简化符号是这样的,也是多了个圆圈:
我再总结一下这几个简化图,加深一下印象。
二进制加法机
有了上面这几样东西,我们就可以造个二进制加法机,不要小看加法,因为可以用加法来实现减法、乘法、除法等操作。
加法我们知道会得到当前的和、进位这两个信息,例如二进制中 1 + 1,当前和是 0 ,进位 1。
进位01 000101
可以看到只有 1 +1 进位 1 ,再仔细看看是不是和 AND 操作很像?只有 1 AND 1 结果才为1 。
AND01 000101
我们再来看看当前和的计算
和01 001110
大家可以在脑子里面想象下,如果拿 OR 操作来套用的话右下角结果不对,如果是 NAND 操作的话左上角结果不对,所以得两个结合一下,电路图如下。
分别通过或门和与非门之后再做与门,出来的结果就是当前和的结果,这个其实就是 XOR 异或门,简化表示就是:
所以加法需要通过两个逻辑门,分别是异或门来操作当前和,与门来操作进位,结合起来如下图所示:
这其实就是个半加器,简化的图如下所示:
那为什么叫半加器?因为只能一位一位的加,而前一位的进位参与不到下一位的计算,如果要加入进位那下一位的运行就是 A 的当前位 + B 的当前位 + A 和 B 之前的进位。
因此需要改装一下,两个半加器合起来再加一个或门。
假设 A 输入 1 , B 输入 1, 进位输入 1,从最左边开始第一个半加器 S 输出 0 , CO 输出 1,第二个半加器 S输出 1,CO 输出 0,最终和输出 1,进位输出 1,结果没毛病可行,这叫全加器,简化一下图:
全加器有了,咱们得组合起来,并且需要有输入和输出,我们通过开关来输入数字,由灯泡的亮暗显示结果。
这就是一个 8 位的计算器,有 9 个灯是因为两个 8 位相加结果可能是 9 位。
然后从最右边开始如下图所示接上全加器,进位接地表示 0 输入
中间的都如下接法,前一个的进位输出是下一位的进位输入。
最后一个就是把进位输出直接接到第九个灯上就行了。
此时你摆动控制面板的开关,就可以通过机器得到相加的结果。简化的画法如下图所示:
现在我们已经造出了八位加法器了,如果要 16 位呢?简单合一下就好了。
当然真实的计算机原理差不多是这样的,不过会更复杂,比如不会像我们的加法器,一个一个的进位加,而是会先行进位,而且也不会用继电器,而是晶体管等等。
减法怎么弄?
加法器我们搞出来了,那减法怎么做?减法需要有借位操作。
我们先拿熟悉的十进制来说。假设你的账户上限是499,你的透支额度是500,也就是说你的账户金额范围是 -500~499 这 1000 个数字,要求不能用 负号 来表示。
可以看到这是个三位数,而最大值就到 499 过,说明 500~999 之间的数没用,那拿来表示负数不就刚刚好吗?
所以让 500 表示 - 500 ,501 表示 -499,以此类推。
500,501.......998,999,000,001......498,499,让5、6、7、8、9开头的数都代表负数 ,而且是不是看起来还形成了个环形, 499 + 1 就变成 500 了,然后 999 + 1 变成 1000 ,但是只能三位数表示,所以溢出了变成 000。
这种处理叫 10 的补数,如果要把三位负数转为 10 的补数,就是让 999 减去它再加一,也就是说 10 的补数等于 9 的补数加一。
补数的概念:拿 9 的补数来说,将一个数从一串 9 中减去得到的结果就叫这个数 9 的补数,比如 123 ,它是三位数 ,999-123 = 876 所以 123 的 9 的补数就是 876,如果把结果 + 1那就是 10 的补数了。
就拿 -499 来说,我们要转化成补数,就是 999 - 499 + 1 等于 501 ,看上面的排列确实用 501 来代表 - 499。
那减去一个数不就是加上一个数的负数吗?所以通过补数我们就不需要做减法,只需要转成补数再相加就行了!
现在我们再换成二进制,二进制相比于十进制就更简单了。
拿八位二进制数来说,范围是 00000000~11111111, 对应的十进制是 0~255,但现在我们想让它能表示负数,前面十进制的时候我们将 5、6、7、8、9开头的正数来表示负数,对应于二进制我们可以将第一位以1开头的作为负数。
那此时的范围就是:
如果你理解了上面的十进制转化,这个二进制肯定是没问题的,这其实就是算出 2 的补数,而 2 的补数又是 1 的补数 +1。
我们拿 125 来举个例子,125 二进制表示是 01111101,求 1 的补数就是 11111111 - 01111101,这个减法在二进制中不需要,因为这其实就是求反,还记得上文提到的反向器吗?
取反了之后再加一,就得到 2 的补码。
所以 -125 就是 10000011。
当然这一切的前提都是数字的位数需要固定,所以计算机中的位数就是固定的,超出了就会溢出,到这里你应该可以理解计算机中的补码是怎么来的,而且理解了为什么最大值 +1会变成最小值?
所以减法我们只需要改造一下上面的加法器,给个开关表示要这个数是负数,如果是负数则进行一波反向器操作然后再 +1,之后再进行加法操作即可得到最终的结果。
乘法和除法我就不分析了,一样也能通过加减法来实现。
振荡器(时钟)、锁存器(触发器)和计数器
当然这个和我们所认识的计算机还差很多,现在只能进行一些非常简陋的加减操作,别急我们先来看看这个电路。
这个电路很有意思,当你闭合开关的时候电路通了,此时由于电磁效应可动棒被吸了下来,电路就断了,断了之后磁性消失了可动棒又移了上去,这样电路又通了,如此往复 。
这种电路叫振荡器,这是一个很关键的东西,记住它。
它的来回振荡其实就是在输出 0 和 1 的交替序列,画成图如下所示:
随着时间的变化在 0 和 1之间交替变化,因此也称之为时钟。
一个变化循环所需要的时间称之为周期,频率是周期的倒数,如果周期是 0.05 秒,那么频率就是 20,每秒 20 个循环,用赫兹来作其单位,所以就是 20 Hz。
我们再来看下这个电路。
此时灯泡是不亮的。当上面的开关闭合后,左边的或非门输出 0 ,右边的或非门输出是 1,因此灯泡亮了。神奇的地方来了 ,此时你断开上面的开关,灯泡依然是亮的,因为左边的或非门输出还是 0,而或非门只要有一个输入是 1,输出就是 0 。
此时如果闭合下面的开关,灯泡就会熄灭,再断开下面的开关灯泡仍旧不亮。
可以看到这个电路是有记忆功能的,你看如果你发现此时的灯泡是亮的,你就能推断上一次闭合的是上面的开关,如果此时灯泡是暗的那么上次闭合的就是下面的开关!
这种电路叫触发器 ,其实上面的开关就等于置位(set),下面的开关等于复位(Reset),所以这也叫 R-S触发器。
不过更有用的电路应该能记住某个特定时间点的上上一个信号是 0 是 1 。
所以还需要搞个保持位,使得保持位关了之后,上下两个开关随意拨动都不影响之前保持结果(下面的图复位和置位位置和我们电路图是相反了,不过没影响一样的)。
其实就是当保持位 0 的时候,复位和置位通过与门的输出肯定是 0 根本影响不到之前的结果。
但是这样就有三位输入了,比较麻烦。从上面的观察来看有意义的输入其实是上面开下面关,或者上面关下面开,所以一定是相反的。所以搞个反向器这样就只有两个输入了。
这个叫电平触发的D型触发器 ,D表示 Data,数据的输入。电平触发就是当保持位为某一个特定电平时 (例子是 1),触发器就会保存数据端的输入值。
理解了保持位之后,我们需要引入时钟(标志为 clk),一个有规律的来回变化的时钟,当时钟从 1 切换到 0 的时候上一次操作的内容就被保存了,所以把保持位的输入替换成时钟输入。
这样的电路叫做电平触发的D型锁存器,它表示电路锁存住一位数据,并保持到将来使用,它也称之为 1 位存储器。
有了 1 位存储器,那多位存储器就很简单了,就是将多个锁存器合在一起,如下图是八位锁存器。
这里还需要提一下边沿触发器,不同于电平触发器的是边沿触发器是在 0 变成 1 的瞬间记录结果 ,像电平触发器是在 1 的时候每个结果都会被覆盖性的记住,在某些场景下边沿触发器的瞬时性更合适。
电路图如下,由两级 R-S 触发器链接而成,其实这种电路看不的很乱觉得很复杂没事,知道结果就行了。
简化的画法如下:
然后我们再来看下这个电路:
将振荡器的输出作为时钟的输入,然后反向 Q 端(上图中下面的Q代表反向Q,图少了一横)的输入又作为 D 的输入。
出来的波形图是这样的,可以看到 Q 的输出频率是时钟的一半,所以这种电路称为分频器。
而分频器的输出又可以是下一个分频器的输入,我们再来看下这个图:
出来的波形图是这样的:
再填上 0 和 1:
从 Q3 开始每一列从下往上看,是不是 0000、0001、0010.... 这就是计数器 ,把 8 个集成一下放在黑盒中,就构成了 8 位的计数器。
当然这个计数器是异步的,后面的得等前面的通知,比较不准确,所以更好的是同步计数器,不过比较复杂,这里就不介绍了。
简单组装一下
至此我们已经有了加法器、振荡器(时钟)、锁存器(触发器)和计数器,接下来我们就开始组装一下它们。
比如现在我们有一个灯泡,想测试一下八个锁存器,八个锁存器的话那么需要 3 个开关来表示具体选择哪个锁存器,2 的 3 次方等于8。
中间的黑盒肯定是拿来选择的,通过开关来控制通路,比较复杂我觉得稍微看看就行,反正就是电路选择。
输入的话也不用直接用八个,所以也搞个三个开关。
内部构造我就不贴了,也和选择器一样复杂,这叫译码器,最终完整电路图如下:
而是S0、S1、S2 其实就是地址 ,通过地址来选择写入哪个锁存器中,并且对应输出结果,这种配置叫读/写存储器,也称为随机访问存储器即 RAM 。
因为它能保存信息,所以叫存储器,因为能根据地址选择来写入读取所以是随机。
上图电路简化图如下,能存储 8 个独立的 1 位数据。
两个 8*1 RAM 结合一下就能表示存储 8 个独立的 2 位数据。
如果是通过下面这样的组合,则能表示 16*1 RAM,那个 DI 其实就是第四根地址线,所以是 2 的 4 次方。
可以看到 RAM 阵列的存储容量等于 2 的地址数次方,然后注意下我们图是简化了的,里面其实有很多继电器的,像逻辑门都是由继电器构成的,当断电之后电磁效应就没了,所有的触点都回归原样,这就是 RAM 为什么是易失性存储介质的原因。
咱们现在已经把内存给搞出来了 。
接下来我们的目标就是把要计算的数据输入内存中,然后让加法器计算了之后把结果写回内存,并且可以再通过内存查看结果,大致的组装样子如下:
然后我们可以将加法器和锁存器结合起来作为一个累加器,即每次加法的值存储到锁存器中并作为下一次累加的值。
有了累加器之后,我们可以将存储器的值传到累加器中,称为 Load 装载,把下一个值添加到累加器中,称为 Add,然后将结果保存在某个位置,称为 Store。
可以通过控制面板先往存储器里面写好要操作的值并且可以通过控制面板上的灯来查看内存写入结果,然后一开始访问存储器的地址为 0000,由计数器来驱动地址的前进,然后进行相加,最终将结果存储回 RAM 阵列中,当然也需要设置停止信号 。
把我们前面定义的 Load 等操作码,转化为特定的代码来控制整体的流程(你就认为这代码会指示电路做某种操作,没必要细想反正就是通过逻辑门组合产生的)。
这个操作码仅是个助记符,因为地址是固定的,并且操作码指令字节是固定长度(1个字节),所以我们可以在每条操作后面跟上地址,总的而言每条指令(除停止)需要 3 个字节。
简单的看下图,就是在存储器地址0000处存入以下“代码”。
并且可以搞个 Jump 指令用来跳转地址,可以通过设置计数器来达成跳转地址的功能,有了跳转我们就能做循环操作了。某些重复的指令只需要编写一次,通过条件跳转来完成循环,最终的组装示意图如下:
2-1 选择器是切换计数器的地址输入或者是计算得出的输入,通过三个 8 位锁存器来分别代表代码,地址高位和低位,上图来看可能有点绕,不理解细节也没有关系,大致的流程还是简单的。
至此我们其实已经组装了一台计算机了,之所以能叫计算机而不是计算器是因为它可以根据你写入存储器的指令自动取指执行,并且可以进行条件跳转和循环执行自动停止。
计算机的处理器就是我们上面的累加器,可以称之为算数逻辑单元,即 ALU。
那个计数器就是我们的程序计数器PC。
存储器就是内存了,输入就是控制面板,输出就是控制面板上的灯。
计算机几个核心模块就都有了。
至于前面我们定义的操作码其实就是机器语言,而人类为了好记就会搞一些助记符来标识,发展到后来就是汇编语言,而汇编语言又太麻烦了,因此又抽象搞了高级语言,比如 C、Java 等等。
最后
这篇文章最终所描述的计算机其实是相当简陋的,真正的计算机也肯定不会这样造的,比如不会用继电器,线路也会用各种总线啥的搭建起来各种集成电路等等,ALU 也不会如此简单,会有各种并行计算等等。
主要是想借此大致的说下计算机基本的运行原理和构成,因为本质上的道理是一样的。如果要我把很多细节都说出来我也不会,我也就懂一点点点点皮毛,我也不是搞硬件的,啥模电的课我也没上过,我就会装装机的水准。
本文大量借助了《编码的奥义》一书的例子,或者说是对此书一些章节的梳理和总结,如果对原文有兴趣的可以自己购买书籍,如果觉得囊中羞涩可以后台回「233」,我来帮你想想办法。
我是 yes,从一点点到 亿点点 ,我们下篇见 。
相关问答
与非是什么芯片?与非门(英语:NANDgate)是数字电路的一种基本逻辑电路。是与门和非门的叠加,有多个输入和一个输出。若当输入均为高电平(1),则输出为低电平(0);若输入...与...
NAND 8 与非门 介绍?与非门(英语:NANDgate)是数字电路的一种基本逻辑电路。若当输入均为高电平(1),则输出为低电平(0);若输入中至少有一个为低电平(0),则输出为高电平(...与非门...
与非门 是什么?与非门(英语:NANDgate)是数字电路的一种基本逻辑电路。是与门和非门的叠加,有多个输入和一个输出。若当输入均为高电平(1),则输出为低电平(0);若输入...与...
与非运算的含义?分别简述与、或、非三种逻辑关系的定义:设:A,B,C,D,E,.....为逻辑变量;F为逻辑函数。“逻辑与”运算:F=AB...(也称逻辑乘)A,B皆为1时,F=1,A,B...分别...
与非与非式是什么意思?与非-与非形式是连续两次先作一次“与”运算后,再做一次“非”运算。或非-或非是连续作两次或者多次“或”运算后再做两次“非”运算。与非是一种逻辑算法,常...
三菱plc 程序 ani是什么意思?三菱plc程序ani是与非指令意思。与非是一种逻辑算法,常在计算机中以“与非门”的形式存在。表示为:NAND。“与非”和合取得否定是等价的。三菱plc程序ani是与...
什么叫与或 非门 怎么运算与门--" AND "运算,逻辑乘。1*1=11*0=...[回答]与门--"AND"运算,逻辑乘。1*1=11*0=00*1=00*0=0或门--“OR"运算,逻辑加。1+1=11+0=10+1=10+0=0...
非门 表达式?在逻辑门电路中,与非门的表达式为:NOTAND、或非门的表达式为:NOTOR、与或非门的表达式为:NOTANDOR。基本逻辑电路称为门电路,一般有三种表达形式:一...
与门或门 非门 最简单的表示方法?1、与门的表达式为:Y=AB、或门的表达式为:Y=A+B、非门的表达式为:Y=非A。2、门电路的三种表达形式:与门(英语:ANDgate)又称“与电路”、逻辑“积”、逻...1...
关于联锁问题-盖德问答-化工人互助问答社区前面带圈是先取反再做and运算,后面带圈是先做and运算后结果取反带圆圈应该是状态取反小圈就是非门。状态取反是什么意思