计算机科学⾃学指南
英⽂出处: 。
如果你是⼀名⾃学⼯程师或者是⼀名软件集训课程毕业的学⽣,有些计算机科学基础课程是你必须要补齐的。幸好,你通过互联⽹就能获得世界顶级的CS(计算机科学)课程。
其实⽹上有很多学习资源但它们良莠不齐,你需要不是什么“200+免费在线课程”列表⽽是如下问题的答案:
你应该学习哪门课程?为什么?
每门课程最好的书籍或者视频,讲座是什么?
我写这篇⽂章的⽬的就是尝试对于这些问题给出的明确答案:
使⽤建议的书籍或者视频讲座来学习以下的九门科⽬,最好是书籍和讲座都仔细的研究⼀下,可以不严格按照列出的顺序来。每⼀门科⽬都需要花上100-200⼩时来研读,然后在你的职业⽣涯中对于最热爱的⽅向进⾏反复重温。
主题为什么学习它推荐书籍推荐视频
nobody 歌词
编程别做那些连“递归”是什么都搞不懂的程序员《 》Programs Brian Harvey’s Berkeley CS 61A
计算机体系
结构如果你基础薄弱,不知道计算机是如何运⾏的,那些你学会的所
谓“⾼层”技能不过是空中楼阁
《》Berkeley CS 61C
算法和数据
结构如果你不能很好的使⽤随处可见的数据结构(例如栈、队列、树和
图),你是⽆法解决复杂问题的
《 》Steven Skiena’s lectures
计算机数学计算机科学实际上是应⽤数学的⼀个分⽀,学好数学让你更具竞争⼒
《Mathematics for
Computer Science》
Tom Leighton’s MIT 6.042J
操作系统你编写的⼤部分代码是通过操作系统运⾏的,所以你需要知道它们是
梁静如如何交互的
《》Berkeley CS 162
计算机⽹络互联⽹是个了不起的发明,只有理解它的原理,才能发挥它的威⼒《 》Stanford CS 144
数据库对于很多程序来说,数据是其核⼼,但是很少有⼈真正理解数据库系
统是如何运⾏的
《》
Joe Hellerstein’s Berkeley CS
186
编程语⾔和编译器如果你理解语⾔和编译器是如何运⾏的,你就能编写更好的代码并轻
松学会新的语⾔
《》
Alex Aiken’s course on
Lagunita
分布式系统近年来,⼤部分系统已经发展成为分布式系统Distributed Systems
为什么要学习计算机科学
有两种软件⼯程师:⼀种⼈对于电脑科学有很好的理解从⽽去从事挑战性的、富有创造⼒的⼯作。另外⼀种⼈仅仅熟悉⼀些⾼级⼯具,对其原理持得过且过的态度。
两者都叫做软件⼯程师,⽽且两者在早期的职业⽣涯中可能领着同样的薪⽔。但是第⼀种⼯程师,不管他从事的是商业⼯作,还是突破性的开源⼯程,都会由于他的技术领导⼒或者杰出的个⼈贡献⼀点⼀点成长成⼀名对于编程更加痴迷⽽且待遇更⾼的⼯程师。
耸组词
第⼀种⼯程师可以通过常规⼿段或者在职业⽣涯中不断学习来加深对于计算机科学的理解深度。第⼆种⼯程师通常停留在表⾯,学习具体的⼯具或者技巧⽽不是其中的基础,当前流⾏什么技术,他们就仅仅捡起新的技能学习⼀下。
近些年来,越来越多的⼈进⼊软件领域⼯作,但是本质上计算机科学的毕业⽣数量是没有改变的。第⼆种⼯程师的供应过量开始导致他们的就业机会变少⽽且导致他们离企业中令⼈感觉充实的⼯作更远。不管你是努⼒要成为第⼀种⼯程师或者仅仅是保险起见地想到更多的⼯作,学习计算机科学是唯⼀⼀种可靠的途径。
课程指南
编程
⼤多数⼤学的计算机编程课程通常以“⼊门类”计算机的课程开始。这些课程最好是不仅仅针对于初学者,⽽且对于第⼀次学习编程,基本概念和编程模型不是很熟悉的⼈也有所启发的。
对于这种介绍的内容的我们给出的标准建议是经典的计算机程序的结构与解释,在⽹络上能到很多这样的资料,它们可能是或者是MIT的⼀系列讲座。这些讲座都很不错,但是我们的视频推荐的实际上是伯克利的⼀门课程: 讲座 ,这个系列的课程⽐起MIT的讲座更精炼⽽且对于⼊门者更具有针对性。
我们推荐观看完⾄少前三章节的SICP(《 》)并且做完相应训练。额外地,可以在 进⾏⼀些编程训练。
如果你觉得SICP太难,我们推荐《 这本书。如果你觉得它太简单,我们推荐《》 这本书。
计算机体系结构
硬件是平台 – Mike Acton(Insomniac Games的⼯程总监) ()
计算机结构–有的时候被称为“计算机系统”或者“计算机组织”–是了解程序外表下计算机运⾏的第⼀步。根据我们的经验,这是⾃学软件⼯程师最容易忽略的地⽅。
(),也被称为“从与⾮门到俄罗斯⽅块”。这是⼀本让你对于计算机中的每⼀个零件是怎么⼯作的有⼀个整体的理解的雄⼼勃勃的书。每个章节涉及到建⽴整体系统中⼀个⼩的部分,从写基本的逻辑门到HDL,到CPU和汇编语⾔,⼀直到完成⼀个俄罗斯⽅块应⽤程序。
我们推荐阅读书的前六章节并且完成相关的⼯程。这会提⾼你对于计算机结构和运⾏的软件之间关系的理解。
这本书的前半部分(和它的全部⼯程)在 ⽹站上可以免费获得。在 课程⽹站上你也可以到它们。
为了保证课程简单并吸引⼈,Nand2Tetris 舍弃了深度。特别是现代计算机结构中两个很重要的概念:流⽔线(pipelining)和内存层级(memory hierarchy),在书中都没有提及。
当你觉得看Nand2Tetris已经很简单了,我们下⼀个建议是Patterson和Hennessy合著的()——⼀本杰出的现代经典书籍。不是书中所有的部分都很重要;我们建议跟随——(),作为特殊读物。讲座的笔记和实验环境都是在线的,⽽且可以在回看讲座。
算法和数据结构
只有⼀个⽅法是我⼀直以来⼴泛推荐的—编码前⾸先要思考 — Richard Hamming
我们根据⼏⼗年的通识来看,熟悉通⽤的算法和数据结构是计算机科学教育中最重要的⽅⾯之⼀。这是⼀个训练⼀个⼈解决问题的通⽤能⼒的⽅式,⽽且这种能⼒还可以迁移到其他领域的学习。
这个领域有很多优秀的书籍,但是我们最喜欢的是Steven Skiena的() 。他显然喜欢这东西⽽且也
迫不及待地想帮助你学习数据结构和算法。这是令⼈⽿⽬⼀新的变化,我们认为这本书相对于被更多⼈所推荐的Cormen, Leiserson, Rivest & Stein 或者 Sedgewick 的书来说更好。后两本书有些太过于引经据典,对于想通过阅读来解决问题的⼈来说并不是⼀个好的选择。
对于那些更喜欢讲座视频的⼈来说,我们推荐Skiena的. 我们也喜欢Tim Roughgarden的课程,在斯坦福的MOOC平台或者上⾯可以获得。你喜欢 Skiena 还是 Roughgarden 的讲课风格就是你的个⼈喜好问题了。
说到练习,我们倾向于让学⽣在Leetcode上⾯解决问题。LeetCode上⾯的问题都⽐较有趣⽽且有答案和讨论。这上⾯还可以通过解决各⼤软件公司⼴泛应⽤的技术问题来帮助你测试你的进步。我们建议解决你学习的时候解决⼤约随机100道LeetCode上⾯的问题。
最后,我们强烈推荐《怎样解题》这本书,它针对如何解题进⾏了精彩绝伦和独特的讲解,既适⽤于数学也适⽤于电脑科学。
计算机科学领域的数学
如果⼈们不认为数学是简单的,那么他们⼀定没有体会过⼈⽣的艰难 — John von Neumann
在某些⽅⾯,计算机科学是应⽤数学的⼀个扩展。虽然许多软件⼯程师忽略了这⼀点,我们建议你去学习它。好好学习数学会给你⽐那些不学习它们的⼈巨⼤的竞争优势。
和CS最相关的数学领域是“离散数学”,离散是连续对⽴⾯。是微积分之外的⼀系列的有趣的应⽤数学的主题。从⼤体上说,尝试学会全部范围的“离散数学”是没有意义的。更现实⼀点的做法是对于逻辑学,组合学和概率学,集合论,图论和⼀些数论告知密码学有⼀个了解。对于计算机图像学和机器学习来说,线性代数也是⼀门值得学习的课程。
我们建议从László Lovász的学起. 这⼀系列开始学习离散数学。Lovász 教授让学习的内容变得直观⽣动,⽐起拘谨的⽂字,这更利于你学习。
接下来,我们推荐《》, 它是MIT同名课程的讲义。的视频也是免费的,⽽且是我们推荐的离散数学的视频课程。
线性代数,我们建议从 系列开始学习,接着是Gilbert Strang的和。
操作系统
()(恐龙书)和( )是经典的操作系统的书籍。这两本书的写作⽅式都饱受争议,⽽且为了⿎励你去购买新版,这些长达1000页的书每⼏年就会添加⼀些内容。
《》这本书是⼀本⽐较好的可供选择的线上免费读物。我们特别喜欢书的结构和它经典的练习题。
读完这本书,我们推荐你去探索⼀种特定的操作系统的设计⽅式,⽐如那些书名中有系统名字的书籍,⽐如 《、《》,还有 .
巩固你对于操作系统的理解很好的⽅式是去读⼀个⼩的内核并且添加功能。xv6 是⼀个不错的选择,它是 Unix V6 和 ANSI C 和 X86 的接⼝,MIT专门有⼀门课程就是讲这个的。OSTEP(之前提到的)这本书有⼀个 XV6 的实验附录,⾥⾯都是充满潜⼒项⽬的好点⼦。
计算机⽹络
你不能够通过凝视⽔晶球来预见未来。因特⽹未来会变成什么样,取决于如今⼈类如何去塑造它 — Bob Kahn
考虑到很多软件项⽬都是基于web服务器和客户端的,计算机⽹络变成计算机科学中⼀门有实⽤价值
的学科。系统学习过该课程的⾃学学⽣发现他们终于理解了围绕了伴随它们很多年的术语,概念,协议等等。
关于这个主题我们最推荐的书是:()。书中的⼩⼯程和实验都很好,值得⼀做。我们⾮常喜欢它们提供的 。
对于那些喜欢视频课程的⼈,我们推荐斯坦福MOOC平台上的《》。
学习⽹络的好处不仅仅在于做⼩的实验⽽且对于⼯程来说也有很⼤的好处。可能涉及到的有:⼀个HTTP的服务器,⼀个UDP协议的聊天软件,⼀个,⼀个代理或者负载平衡器,还有分布式的哈希表等等。
数据库
对于⾃学者来说,学习数据库系统会⽐学习其他花费更多的时间。这是⼀个相对较新的(即1970年代后期)的研究领域。⽐起写书,许多潜在的杰出教科书作者更愿意去加⼊或者创办⼀家公司。
在这种情况下,我们建议⾃学者放弃教科书⽽去学习伯克利的Joe Hellerstein的,看完课程再去阅读论⽂。
对于初学者有⼀篇论⽂⽐较推荐的是:《,它⾼屋建瓴地讲解了关系数据库管理系统是如果⼯作的这⼀问题。它会为你未来的学习提供⼀个有⽤的纲要。现在银行存款利率是多少
《》这本书,⼜被称为数据库红⽪书、是⼀本Peter Bailis、Joe Hellerstein和Michael Stonebraker编辑地论⽂集。对于那些理解了CS 186内容的⼈来说,红⽪书是你的不⼆之选。
如果你坚持要使⽤⼀本引导性的教科书,我们推荐Ramakrishnan 和Gehrke的(),对于更优秀的学⽣,Jim Gray的传统课程《》值得⼀看,但是我们不建议把它当成⼊门书。
不编⼤量的代码是不能很好的巩固数据库的理论的,CS 186的学⽣往Spark中添加功能,这是⼀个很有意义的⼯程。但是我们建议仅仅是从头写⼀个简单的关系数据库管理系统。功能可能不是很丰富,但是即使每⼀个部分都涉及到⼀些基本功能也很有启发性。
最后,数据模型是⼀个数据库使⽤中被忽略和没有被重点学习的⽅⾯。我们对于这个课题建议的书籍是:《》
语⾔和编译器
马达丽娜
Don’t be a boilerplate programmer. Instead, build tools for users and other programmers. Take historical note of textile and steel industries: do you want to build machines and tools, or do you want
to operate those machines? — Ras Bodik at the start of his compilers course
⼤部分程序员学习如何使⽤⼀门编程语⾔,然⽽⼤部分的计算机科学家则学习这门语⾔本⾝。这给了计算机科学家⽐起程序员很明显的优势。他们的知识能够更好的泛化,他们能⽐简简单单地掌握⼀门语⾔的更加深⼊和快速的理解⼀门新语⾔的操作。
经典的教科书( )通常⼜被称为“龙书”。不幸的是,这本书并不适合⾃学者,它⽐较适合教师从中选出1-2个章节并在课堂上讲授。这本书是有必要看的,你可以挑选⾥⾯的主题,最好再有个师傅指导你。
如果你选择在⾃学中使⽤龙书,我们推荐你⼀系列门视频讲座,然后再沉浸在对于龙书的研究中。我们推荐的在线课程是:Alex Aiken 的,你可以在斯坦福⼤学的幕课平台上观看。
也有可以替代龙书的教材:Terence Parr写的(),它更适合那些⼯作中使⽤类似特定领域语⾔的⼩众语⾔的有经验的编程者,它显得更加实⽤。当然,为了达到这个⽬的它也删去了⼀些有价值的理论。
对于⼯程实践,我们推荐你写⼀个编译器,你可以选择像COOL这种简单的教学语⾔或者你感兴趣的⼀门语⾔。如果你觉得太难,你可以参考,你可以参考它作为开始。
分布式系统
计算机的数量增长了,它们的分布也更⼴了。企业之前会购买越来越⼤型的主机,但是现在⼤家更倾向于在很多机器上分布式的运⾏多个⼩型的应⽤程序。分布式系统研究的就是这样的技术,这⼀技术变得越来越重要了。
父亲节送礼物排行榜我们建议的⾃学教科书是 Maarten van Steen 和 Andrew Tanenbaum 的《》。 针对于之前的版本做了很⼤的改进,⽽且作者慷慨地把书放在了⽹上共享。由于分布式计算是⼀门变化很快的领域,所以没有教科书可以很好的涵盖所有的内容。但是Maarten van Steen的书是我们读过的所有书中最好的书。
研究⽣在线课程  也是⼀个不错的选择,但可惜视频中的⾳质不太好,⽽且不清楚这些视频是不是都被授权过。
尽管有参考书或者其它的资源,但学习分布式系统是绝对要读论⽂的。链接中有⼀个很好的,⽽且我们⼗分推荐你从 上⾯下载论⽂到本地学习。