如果你是一名自学工程师或者是一名软件集训课程毕业的学生,你需要这份资料来帮助你更加高效的学习计算机科学。幸好,你不需要花上几年的时间和学费去获得编程方向的学位就能获得世界顶级的CS(计算机科学)课程。

网上有很多学习资源,良莠不齐。你不需要另外的“200+免费在线课程”列表。你需要的是如下问题的答案:

你应该学习哪门课程?为什么?

每门课程最好的书籍或者视频,讲座是什么?

我写这篇文章的目的就是尝试对于这些问题给出的明确答案:

TL;DR:

使用建议的书籍或者视频讲座来学习以下的九门科目,最好是书籍和讲座都仔细的研究一下,可以不严格按照列出的顺序来。每一门科目都需要花上100-200小时来研读,然后在你的职业生涯中对于最热爱的方向进行反复重温。

Subject Why study? Best book Best videos
Programming Don’t be the person who “never quite understood” something like recursion. Structure and Interpretation of Computer Programs Brian Harvey’s Berkeley CS 61A
Computer Architecture If you don’t have a solid mental model of how a computer actually works, all of your higher-level abstractions will be brittle. Computer Organization and Design Berkeley CS 61C
Algorithms and Data Structures If you don’t know how to use ubiquitous data structures like stacks, queues, trees, and graphs, you won’t be able to solve hard problems. The Algorithm Design Manual Steven Skiena’s lectures
Math for CS CS is basically a runaway branch of applied math, so learning math will give you a competitive advantage. Mathematics for Computer Science Tom Leighton’s MIT 6.042J
Operating Systems Most of the code you write is run by an operating system, so you should know how those interact. Operating Systems: Three Easy Pieces Berkeley CS 162
Computer Networking The Internet turned out to be a big deal: understand how it works to unlock its full potential. Computer Networking: A Top-Down Approach Stanford CS 144
Databases Data is at the heart of most significant programs, but few understand how database systems actually work. Readings in Database Systems Joe Hellerstein’s Berkeley CS 186
Languages and Compilers If you understand how languages and compilers actually work, you’ll write better code and learn new languages more easily. Compilers: Principles, Techniques and Tools Alex Aiken’s course on Lagunita
Distributed Systems These days, most systems are distributed systems. Distributed Systems, 3rd Edition by Maarten van Steen 🤷‍

Why learn computer science?

为什么要学习计算机科学

有两种软件工程师:一种人对于电脑科学有很好的理解从而去从事挑战性的、富有创造力的工作。另外一种人仅仅熟悉一些高级工具,对其原理持得过且过的态度。

两者都叫做软件工程师,而且两者在早期的职业生涯中可能领着同样的薪水。但是第一种工程师,不管他从事的是商业工作,还是突破性的开源工程,都会由于他的技术领导力或者杰出的个人贡献一点一点成长成一名对于编程更加痴迷而且待遇更高的工程师。

第一种工程师可以通过常规手段或者在职业生涯中不断学习来加深对于计算机科学的理解深度。第二种工程师通常停留在表面,学习具体的工具或者技巧而不是其中的基础,当前流行什么技术,他们就仅仅捡起新的技能学习一下。

近些年来,越来越多的人进入软件领域工作,但是本质上计算机科学的毕业生数量是没有改变的。第二种工程师的供应过量开始导致他们的就业机会变少而且导致他们离企业中令人感觉充实的工作更远。不管你是努力要成为第一种工程师或者仅仅是保险起见地想找到更多的工作,学习计算机科学是唯一一种可靠的途径。

Subject guides

课程指南

Programming

编程

大多数大学的计算机编程课程通常以“入门类”计算机的课程开始。这些课程最好是不仅仅针对于初学者,而且对于第一次学习编程,基本概念和编程模型不是很熟悉的人也有所启发的。

对于这种介绍的内容的我们给出的标准建议是经典的计算机程序的结构与解释,在网络上能找到很多这样的资料,它们可能是电子书或者是MIT的一系列讲座视频。这些讲座都很不错,但是我们的视频推荐的实际上是伯克利的一门课程:Brian Harvey’s SICP lectures ,这个系列的课程比起MIT的讲座更精炼而且对于入门者更具有针对性。

我们推荐观看完至少前三章节的SICP(计算机程序的结构与解释)并且做完相应训练。额外地,可以在 exercism 进行一些编程问题训练。

image

如果你觉得SICP太难,我们推荐How to Design Programs.这本书。如果你觉得它太简单,我们推荐Concepts, Techniques, and Models of Computer Programming 这本书。

Computer Architecture

计算机体系结构

Hardware is the platform

– Mike Acton, Engine Director at Insomniac Games (收看他在Cpp大会上的演讲)

计算机结构—有的时候被称为“计算机系统”或者“计算机组织”—是了解程序外表下计算机运行的第一步。根据我们的经验,这是自学软件工程师最容易忽略的地方。

The Elements of Computing Systems,也被称为“从与非门到俄罗斯方块”。这是一本让你对于计算机中的每一个零件是怎么工作的有一个整体的理解的雄心勃勃的书。每个章节涉及到建立整体系统中一个小的部分,从写基本的逻辑门到HDL,到CPU和汇编语言,一直到完成一个俄罗斯方块应用程序。

elements-computing-systems

我们推荐阅读书的前六章节并且完成相关的工程。这会提高你对于计算机结构和运行的软件之间关系的理解。

这本书的前半部分(和它的全部工程)在the Nand2Tetris website上可以免费获得。在Coursera course with accompanying videos上你也可以找到它们。

为了保证课程简单并吸引人,Nand2Tetris 舍弃了深度。特别是现代计算机结构中两个很重要的概念:流水线(pipelining)和内存层级(memory hierarchy),在书中都没有提及。

当你觉得看Nand2Tetris已经很简单了,我们下一个建议是Patterson和Hennessy合著的Computer Organization and Design——一本杰出的现代经典书籍。不是书中所有的部分都很重要;我们建议跟随Berkeley’s CS61C 课程——Great Ideas in Computer Architecture,作为特殊读物。讲座的笔记和实验环境都是在线的,而且可以在在这个归档链接回看讲座。

Algorithms and Data Structures

算法和数据结构

我们根据几十年的通识来看,熟悉通用的算法和数据结构是计算机科学教育中最重要的方面之一。这是一个训练一个人解决问题的通用能力的方式,而且这种能力还可以迁移到其他领域的学习。

这个领域有很多优秀的书籍,但是我们最喜欢的是Steven Skiena的The Algorithm Design Manual 。他显然喜欢这东西而且也迫不及待地想帮助你学习数据结构和算法。这是令人耳目一新的变化,我们认为这本书相对于被更多人所推荐的Cormen, Leiserson, Rivest & Stein 或者 Sedgewick 的书来说更好。后两本书有些太过于引经据典,对于想通过阅读来解决问题的人来说并不是一个好的选择。

skiena

对于那些更喜欢讲座视频的人来说,我们推荐Skiena的讲座. 我们也喜欢Tim Roughgarden的课程,在斯坦福的MOOC平台或者Coursera上面可以获得。你喜欢 Skiena 还是 Roughgarden 的讲课风格就是你的个人喜好问题了。

说到练习,我们倾向于让学生在Leetcode上面解决问题。LeetCode上面的问题都比较有趣而且有答案和讨论。这上面还可以通过解决各大软件公司广泛应用的技术问题来帮助你测试你的进步。我们建议解决你学习的时候解决大约随机100道LeetCode上面的问题。

最后,我们强烈推荐《怎样解题》这本书,它针对如何解题进行了精彩绝伦和独特的讲解,既适用于数学也适用于电脑科学。

polya

Mathematics for Computer Science

计算机科学领域的数学

— John von Neumann

在某些方面,计算机科学是应用数学的一个扩展。虽然许多软件工程师忽略了这一点,我们建议你去学习它。好好学习数学会给你比那些不学习它们的人巨大的竞争优势。

和CS最相关的数学领域是“离散数学”,离散是连续对立面。是微积分之外的一系列的有趣的应用数学的主题。从大体上说,尝试学会全部范围的“离散数学”是没有意义的。更现实一点的做法是对于逻辑学,组合学和概率学,集合论,图论和一些数论告知密码学有一个了解。对于计算机图像学和机器学习来说,线性代数也是一门值得学习的课程。

我们建议从László Lovász的讲座学起. 这一系列开始学习离散数学。Lovász 教授让学习的内容变得直观生动,比起拘谨的文字,这更利于你学习。

For a more advanced treatment, we suggest Mathematics for Computer Science, the book-length lecture notes for the MIT course of the same name. That course’s video lectures are also freely available, and are our recommended video lectures for discrete math.

接下来,我们推荐Mathematics for Computer Science, 它是MIT同名课程的讲义。讲座课程的视频也是免费的,而且是我们推荐的离散数学的视频课程。

For linear algebra, we suggest starting with the Essence of linear algebra video series, followed by Gilbert Strang’s book and video lectures.

线性代数,我们建议从 Essence of linear algebra 系列开始学习,接着是Gilbert Strang的书籍视频

Operating Systems

操作系统

Operating System Concepts (the “Dinosaur book”) and Modern Operating Systems are the “classic” books on operating systems. Both have attracted criticism for their writing styles, and for being the 1000-page-long type of textbook that gets bits bolted onto it every few years to encourage purchasing of the “latest edition”.

《操作系统的概念》(恐龙书)和《现代操作系统》是经典的操作系统的书籍。这两本书的写作方式都饱受争议,而且为了鼓励你去购买新版,这些长达1000页的书每几年就会添加一些内容。

Operating Systems: Three Easy Pieces is a good alternative that’s freely available online. We particularly like the structure of the book and feel that the exercises are well worth doing.

《Operating Systems: Three Easy Pieces》这本书是一本比较好的可供选择的线上免费读物。我们特别喜欢书的结构和它经典的练习题。

ostep

After OSTEP, we encourage you to explore the design decisions of specific operating systems, through “{OS name} Internals” style books such as Lion’s commentary on Unix, The Design and Implementation of the FreeBSD Operating System, and Mac OS X Internals.

读完这本书,我们推荐你去探索一种特定的操作系统的设计方式,比如那些书名中有系统名字的书籍,比如Lion‘s commentary on Unix, The Design and Implementation of the FreeBSD Operating System, 还有 Mac OS X Internals.

A great way to consolidate your understanding of operating systems is to read the code of a small kernel and add features. A great choice is xv6, a port of Unix V6 to ANSI C and x86 maintained for a course at MIT. OSTEP has an appendix of potential xv6 labs full of great ideas for potential projects.

巩固你对于操作系统的理解很好的方式是去读一个小的内核并且添加功能。xv6是一个不错的选择,它是 Unix V6 和 ANSI C 和 X86 的接口,MIT专门有一门课程就是讲这个的。OSTEP(之前提到的)这本书有一个 XV6 的实验附录,里面都是充满潜力项目的好点子。

Computer Networking

计算机网络

You can’t gaze in the crystal ball and see the future. What the Internet is going to be in the future is what society makes it.

— Bob Kahn

Given that so much of software engineering is on web servers and clients, one of the most immediately valuable areas of computer science is computer networking. Our self-taught students who methodically study networking find that they finally understand terms, concepts and protocols they’d been surrounded by for years.

考虑到很多软件项目都是基于web服务器和客户端的,计算机网络变成计算机科学中一门有实用价值的学科。系统学习过该课程的自学学生发现他们终于理解了围绕了伴随它们很多年的术语,概念,协议等等。

Our favorite book on the topic is Computer Networking: A Top-Down Approach. The small projects and exercises in the book are well worth doing, and we particularly like the “Wireshark labs”, which they have generously provided online.

关于这个主题我们最推荐的书是:《计算机网络——自顶向下方法》。书中的小工程和实验都很好,值得一做。我们非常喜欢它们提供的Wireshark labs

自学计算机科学 - 图6

For those who prefer video lectures, we suggest Stanford’s Introduction to Computer Networking course available on their MOOC platform Lagunita.

对于那些喜欢视频课程的人,我们推荐斯坦福MOOC平台上的Introduction to Computer Networking course

The study of networking benefits more from projects than it does from small exercises. Some possible projects are: an HTTP server, a UDP-based chat app, a mini TCP stack, a proxy or load balancer, and a distributed hash table.

学习网络的好处不仅仅在于做小的实验而且对于工程来说也有很大的好处。可能涉及到的有:一个HTTP的服务器,一个UDP协议的聊天软件,一个迷你的TCP协议栈,一个代理或者负载平衡器,还有分布式的哈希表等等。

Databases

数据库

It takes more work to self-learn about database systems than it does with most other topics. It’s a relatively new (i.e. post 1970s) field of study with strong commercial incentives for ideas to stay behind closed doors. Additionally, many potentially excellent textbook authors have preferred to join or start companies instead.

对于自学者来说,学习数据库系统会比学习其他花费更多的时间。这是一个相对较新的(即1970年代后期)的研究领域。比起写书,许多潜在的杰出教科书作者更愿意去加入或者创办一家公司。

Given the circumstances, we encourage self-learners to generally avoid textbooks and start with the Spring 2015 recording of CS 186, Joe Hellerstein’s databases course at Berkeley, and to progress to reading papers after.

在这种情况下,我们建议自学者放弃教科书而去学习伯克利的Joe Hellerstein的数据库课程,看完课程再去阅读论文。

One paper particularly worth mentioning for new students is “Architecture of a Database System”, which uniquely provides a high-level view of how relational database management systems (RDBMS) work. This will serve as a useful skeleton for further study.

对于初学者有一篇论文比较推荐的是:“Architecture of a Database System”,它高屋建瓴地讲解了关系数据库管理系统是如果工作的这一问题。它会为你未来的学习提供一个有用的纲要。

Readings in Database Systems, better known as the databases “Red Book”, is a collection of papers compiled and edited by Peter Bailis, Joe Hellerstein and Michael Stonebraker. For those who have progressed beyond the level of the CS 186 content, the Red Book should be your next stop.

Readings in Database Systems这本书,又被称为数据库红皮书、是一本Peter Bailis、Joe Hellerstein和Michael Stonebraker编辑地论文集。对于那些理解了CS 186内容的人来说,红皮书是你的不二之选。

自学计算机科学 - 图7

If you insist on using an introductory textbook, we suggest Database Management Systemsby Ramakrishnan and Gehrke. For more advanced students, Jim Gray’s classic Transaction Processing: Concepts and Techniques is worthwhile, but we don’t encourage using this as a first resource.

如果你坚持要使用一本引导性的教科书,我们推荐Ramakrishnan 和Gehrke的Database Management Systems,对于更优秀的学生,Jim Gray的传统课程Transaction Processing: Concepts and Techniques值得一看,但是我们不建议把它当成入门书。

It’s hard to consolidate databases theory without writing a good amount of code. CS 186 students add features to Spark, which is a reasonable project, but we suggest just writing a simple relational database management system from scratch. It will not be feature rich, of course, but even writing the most rudimentary version of every aspect of a typical RDBMS will be illuminating.

不编大量的代码是不能很好的巩固数据库的理论的,CS 186的学生往Spark中添加功能,这是一个很有意义的工程。但是我们建议仅仅是从头写一个简单的关系数据库管理系统。功能可能不是很丰富,但是即使每一个部分都涉及到一些基本功能也很有启发性。

Finally, data modeling is a neglected and poorly taught aspect of working with databases. Our suggested book on the topic is Data and Reality: A Timeless Perspective on Perceiving and Managing Information in Our Imprecise World.

最后,数据模型是一个数据库使用中被忽略和没有被重点学习的方面。我们对于这个课题建议的书籍是:Data and Reality: A Timeless Perspective on Perceiving and Managing Information in Our Imprecise World

自学计算机科学 - 图8

Languages and Compilers

语言和编译器

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

Most programmers learn languages, whereas most computer scientists learn about languages. This gives the computer scientist a distinct advantage over the programmer, even in the domain of programming! Their knowledge generalizes; they are able to understand the operation of a new language more deeply and quickly than those who have merely learned specific languages.

大部分程序员学习如何使用一门编程语言,然而大部分的计算机科学家则学习这门语言本身。这给了计算机科学家比起程序员很明显的优势。他们的知识能够更好的泛化,他们能比简简单单地掌握一门语言的更加深入和快速的理解一门新语言的操作。

The canonical introductory text is Compilers: Principles, Techniques & Tools, commonly called “the Dragon Book”. Unfortunately, it’s not designed for self-study, but rather for instructors to pick out 1-2 semesters worth of topics for their courses. It’s almost essential then, that you cherry-pick the topics, ideally with the help of a mentor.

经典的教科书《编译器:原理、技术与工具》通常又被称为“龙书”。不幸的是,这本书并不适合自学者,它比较适合教师从中选出1-2个章节并在课堂上讲授。这本书是有必要看的,你可以挑选里面的主题,最好再有个师傅指导你。

自学计算机科学 - 图9

If you choose to use the Dragon Book for self-study, we recommend following a video lecture series for structure, then dipping into the Dragon Book as needed for more depth. Our recommended online course is Alex Aiken’s, available from Stanford’s MOOC platform Lagunita.

如果你选择在自学中使用龙书,我们推荐你一系列门视频讲座,然后再沉浸在对于龙书的研究中。我们推荐的在线课程是:Alex Aiken 的讲座,你可以在斯坦福大学的幕课平台上观看。

As a potential alternative to the Dragon Book we suggest Language Implementation Patterns by Terence Parr. It is written more directly for the practicing software engineer who intends to work on small language projects like DSLs, which may make it more practical for your purposes. Of course, it sacrifices some valuable theory to do so.

也有可以替代龙书的教材:Terence Parr写的Language Implementation Patterns,它更适合那些工作中使用类似特定领域语言的小众语言的有经验的编程者,它显得更加实用。当然,为了达到这个目的它也删去了一些有价值的理论。

自学计算机科学 - 图10

For project work, we suggest writing a compiler either for a simple teaching language like COOL, or for a subset of a language that interests you. Those who find such a project daunting could start with Make a Lisp, which steps you through the project.

对于工程实践,我们推荐你写一个编译器,你可以选择像COOL这种简单的教学语言或者你感兴趣的一门语言。如果你觉得太难,你可以参考Make a Lisp,你可以参考它作为开始。

Distributed Systems

分布式系统

As computers have increased in number, they have also spread. Whereas businesses would previously purchase larger and larger mainframes, it’s typical now for even very small applications to run across multiple machines. Distributed systems is the study of how to reason about the trade-offs involved in doing so, an increasingly important skill.

计算机的数量增长了,它们的分布也更广了。企业之前会购买越来越大型的主机,但是现在大家更倾向于在很多机器上分布式的运行多个小型的应用程序。分布式系统研究的就是这样的技术,这一技术变得越来越重要了。

Our suggested textbook for self-study is Maarten van Steen and Andrew Tanenbaum’s Distributed Systems, 3rd Edition. It’s a great improvement over the previous edition, and is available for free online thanks to the generosity of its authors. Given that the distributed systems is a rapidly changing field, no textbook will serve as a trail guide, but Maarten van Steen’s is the best overview we’ve seen of well-established foundations.

我们建议的自学教科书是Maarten van Steen和Andrew Tanenbaum的Distributed Systems, 3rd Edition 针对于之前的版本做了很大的改进,而且作者慷慨地把书放在了网上共享。由于分布式计算是一门变化很快的领域,所以没有教科书可以很好的涵盖所有的内容。但是Maarten van Steen的书是我们读过的所有书中最好的书。

自学计算机科学 - 图11

A good course for which some videos are online is MIT’s 6.824 (a graduate course), but unfortunately the audio quality in the recordings is poor, and it’s not clear if the recordings were authorized.

研究生在线课程MIT’s 6.824 也是一个不错的选择,但可惜视频中的音质不太好,而且不清楚这些视频是不是都被授权过。

No matter the choice of textbook or other secondary resources, study of distributed systems absolutely mandates reading papers. A good list is here, and we would highly encourage attending your local Papers We Love chapter.

尽管有参考书或者其它的资源,但学习分布式系统是绝对要读论文的。链接中有一个很好的清单,而且我们十分推荐你从Papers We Love 上面下载论文到本地学习。

Frequently asked questions

常见问题