diff --git a/404.html b/404.html index 7e427a16..16b54030 100644 --- a/404.html +++ b/404.html @@ -1 +1 @@ -
计算机领域方向庞杂,知识浩如烟海,每个细分领域如果深究下去都可以说学无止境。因此,一个清晰明确的学习规划是非常重要的。这一节的内容是对后续整本书的内容的一个概览,你可以将其看作是这本书的目录,按需选择自己感兴趣的内容进行学习。
不过,在开始学习之前,先向小白们强烈推荐一个科普向系列视频 Crash Course: Computer Science,在短短 8 个小时里非常生动且全面地科普了关于计算机科学的方方面面:计算机的历史、计算机是如何运作的、组成计算机的各个重要模块、计算机科学中的重要思想等等等等。正如它的口号所说的 Computers are not magic!,希望看完这个视频之后,大家能对计算机科学有个全貌性地感知,从而怀着兴趣去面对下面浩如烟海的更为细致且深入的学习内容。
俗话说:磨刀不误砍柴工。如果你是一个刚刚接触计算机的24k纯小白,学会一些工具将会让你事半功倍。
学会提问:也许你会惊讶,提问也算计算机必备技能吗,还放在第一条?我觉得在开源社区中,学会提问是一项非常重要的能力,它包含两方面的事情。其一是会变相地培养你自主解决问题的能力,因为从形成问题、描述问题并发布、他人回答、最后再到理解回答这个周期是非常长的,如果遇到什么鸡毛蒜皮的事情都希望别人最好远程桌面手把手帮你完成,那计算机的世界基本与你无缘了。其二,如果真的经过尝试还无法解决,可以借助开源社区的帮助,但这时候如何通过简洁的文字让别人瞬间理解你的处境以及目的,就显得尤为重要。推荐阅读提问的智慧这篇文章,这不仅能提高你解决问题的概率和效率,也能让开源社区里无偿提供解答的人们拥有一个好心情。
MIT-Missing-Semester 这门课覆盖了这些工具中绝大部分,而且有相当详细的使用指导,强烈建议小白学习。
翻墙:由于一些众所周知的原因,谷歌、GitHub 等网站在大陆无法访问。然而很多时候,谷歌和 StackOverflow 可以解决你在开发过程中遇到的 95% 的问题。因此,学会翻墙几乎是一个内地 CSer 的必备技能。(考虑到法律问题,这个文档提供的翻墙方式仅对拥有北大邮箱的用户适用)。
命令行:熟练使用命令行是一种常常被忽视,或被认为难以掌握的技能,但实际上,它会提高极大地提高你作为工程师的灵活性以及生产力。命令行的艺术是一份非常经典的教程,它源于 Quora 的一个提问,但在各路大神的贡献努力下已经成为了一个 GitHub 十万 stars 的顶流项目,被翻译成了十几种语言。教程不长,非常建议大家反复通读,在实践中内化吸收。同时,掌握 shell 脚本编程也是一项不容忽视的技术,可以参考这个教程。
IDE (Integrated Development Environment):集成开发环境,说白了就是你写代码的地方。作为一个码农,IDE 的重要性不言而喻,但由于很多 IDE 是为大型工程项目设计的,体量较大,功能也过于丰富。其实如今一些轻便的文本编辑器配合丰富的插件生态基本可以满足日常的轻量编程需求。个人常用的编辑器是 VS Code 和 Sublime(前者的插件配置非常简单,后者略显复杂但颜值很高)。当然对于大型项目我还是会采用略重型的 IDE,例如 Pycharm (Python),IDEA (Java) 等等(免责申明:所有的 IDE 都是世界上最好的 IDE)。
Vim:一款命令行编辑工具。这是一个学习曲线有些陡峭的编辑器,不过学会它我觉得是非常有必要的,因为它将极大地提高你的开发效率。现在绝大多数 IDE 也都支持 Vim 插件,让你在享受现代开发环境的同时保留极客的炫酷(yue)。
Git:一款代码版本控制工具。Git的学习曲线可能更为陡峭,但出自 Linux 之父 Linus 之手的 Git 绝对是每个学 CS 的童鞋必须掌握的神器之一。
GitHub:基于 Git 的代码托管平台。全世界最大的代码开源社区,大佬集聚地。
GNU Make:一款工程构建工具。善用 GNU Make 会让你养成代码模块化的习惯,同时也能让你熟悉一些大型工程的编译链接流程。
CMake:一款功能比 GNU Make 更为强大的构建工具,建议掌握 GNU Make 之后再加以学习。
LaTex:逼格提升 论文排版工具。
Docker:一款相较于虚拟机更轻量级的软件打包与环境部署工具。
实用工具箱:除了上面提到的这些在开发中使用频率极高的工具之外,我还收集了很多实用有趣的免费工具,例如一些下载工具、设计工具、学习网站等等。
Thesis:毕业论文 Word 写作教程。
私以为一本好的教材应当是以人为本的,而不是炫技式的理论堆砌。告诉读者“是什么”固然重要,但更好的应当是教材作者将其在这个领域深耕几十年的经验融汇进书中,向读者娓娓道来“为什么”以及未来应该“怎么做”。
你以为的开发 —— 在 IDE 里疯狂码代码数小时。
实际上的开发 —— 配环境配几天还没开始写代码。
推荐一个非常不错的 GitHub 项目 DevOps-Guide,其中涵盖了非常多的运维方面的基础知识和教程,例如 Docker, Kubernetes, Linux, CI-CD, GitHub Actions 等等。
另外大家可以参考一份灵感来自 6.NULL MIT-Missing-Semester 的 环境配置指南,重点在于终端的美化配置。此外还包括常用软件源(如 GitHub, Anaconda, PyPI 等)的加速与替换以及一些 IDE 的配置与激活教程。
More contents under construction.
正如这章开头提到的,这份课程地图仅仅是一个仅供参考的课程规划,我作为一个临近毕业的本科生。深感自己没有权利也没有能力向别人宣扬“应该怎么学”。因此如果你觉得以下的课程分类与选择有不合理之处,我全盘接受,并深感抱歉。你可以在下一节定制属于你的课程地图
以下课程类别中除了含有 基础 和 入门 字眼的以外,并无明确的先后次序,大家只要满足某个课程的先修要求,完全可以根据自己的需要和喜好选择想要学习的课程。
另外由于贡献者的不断增加,这份课程地图已经从最初我的学习经历,发展成为很多 CS 自学者的资源合集,其中难免有内容交叉甚至重复的。但之所以都列出来,还是希望集百家之长,给大家尽可能多的选择与参考。
作为大一新生,学好微积分线代是和写代码至少同等重要的事情,相信已经有无数的前人经验提到过这一点,但我还是要不厌其烦地再强调一遍:学好微积分线代真的很重要!你也许会吐槽这些东西岂不是考完就忘,那我觉得你是并没有把握住它们本质,对它们的理解还没有达到刻骨铭心的程度。如果觉得老师课上讲的内容晦涩难懂,不妨参考 MIT 的 Calculus Course 和 18.06: Linear Algebra 的课程 notes,至少于我而言,它帮助我深刻理解了微积分和线性代数的许多本质。顺道再安利一个油管数学网红 3Blue1Brown,他的频道有很多用生动形象的动画阐释数学本质内核的视频,兼具深度和广度,质量非常高。
作为计算机系的学生,及早了解一些信息论的基础知识,我觉得是大有裨益的。但大多信息论课程都面向高年级本科生甚至研究生,对新手极不友好。而 MIT 的 6.050J: Information theory and Entropy 这门课正是为大一新生量身定制的,几乎没有先修要求,涵盖了编码、压缩、通信、信息熵等等内容,非常有趣。
集合论、图论、概率论等等是算法推导与证明的重要工具,也是后续高阶数学课程的基础。但我觉得这类课程的讲授很容易落入理论化与形式化的窠臼,让课堂成为定理结论的堆砌,而无法使学生深刻把握理论的本质,进而造成学了就背,考了就忘的怪圈。如果能在理论教学中穿插算法运用实例,学生在拓展算法知识的同时也能窥见理论的力量和魅力。
UCB CS70 : discrete Math and probability theory 和 UCB CS126 : Probability theory 是 UC Berkeley 的概率论课程,前者覆盖了离散数学和概率论基础,后者则涉及随机过程以及深入的理论内容。两者都非常注重理论和实践的结合,有丰富的算法实际运用实例,后者还有大量的Python编程作业来让学生运用概率论的知识解决实际问题。
作为计算机系的学生,培养计算思维是很重要的,实际问题的建模、离散化,计算机的模拟、分析,是一项很重要的能力。而这两年开始风靡的,由 MIT 打造的 Julia 编程语言以其 C 一样的速度和 Python 一样友好的语法在数值计算领域有一统天下之势,MIT 的许多数学课程也开始用 Julia 作为教学工具,把艰深的数学理论用直观清晰的代码展示出来。
ComputationalThinking 是 MIT 开设的一门计算思维入门课,所有课程内容全部开源,可以在课程网站直接访问。这门课利用 Julia 编程语言,在图像处理、社会科学与数据科学、气候学建模三个 topic 下带领学生理解算法、数学建模、数据分析、交互设计、图例展示,让学生体验计算与科学的美妙结合。内容虽然不难,但给我最深刻的感受就是,科学的魅力并不是故弄玄虚的艰深理论,不是诘屈聱牙的术语行话,而是用直观生动的案例,用简练深刻的语言,让每个普通人都能理解。
上完上面的体验课之后,如果意犹未尽的话,不妨试试 MIT 的 18.330 : Introduction to numerical analysis,这门课的编程作业同样会用 Julia 编程语言,不过难度和深度上都上了一个台阶。内容涉及了浮点编码、Root finding、线性系统、微分方程等等方面,整门课的主旨就是让你利用离散化的计算机表示去估计和逼近一个数学上连续的概念。这门课的教授还专门撰写了一本配套的开源教材 Fundamentals of Numerical Computation,里面附有丰富的 Julia 代码实例和严谨的公式推导。
如果你还意犹未尽的话,还有 MIT 的研究生课程 18.335: Introduction to numerical method 供你参考。
如果世间万物的运动发展都能用方程来刻画和描述,这是一件多么酷的事情呀!虽然几乎任何一所学校的 CS 培养方案中都没有微分方程相关的必修课程,但我还是觉得掌握它会赋予你一个新的视角来审视这个世界。
由于微分方程中往往会用到很多复变函数的知识,所以大家可以参考 MIT18.04: Complex variables functions 的课程 notes 来补齐先修知识。
MIT18.03: differential equations) 主要覆盖了常微分方程的求解,在此基础之上 MIT18.152: Partial differential equations) 则会深入偏微分方程的建模与求解。掌握了微分方程这一有利工具,相信对于你的实际问题的建模能力以及从众多噪声变量中把握本质的直觉都会有很大帮助。
作为计算机系的学生,我经常听到数学无用论的论断,对此我不敢苟同但也无权反对,但若凡事都硬要争出个有用和无用的区别来,倒也着实无趣,因此下面这些面向高年级甚至研究生的数学课程,大家按兴趣自取所需。
Standford EE364A: Convex Optimization
MIT18.650: Statistics for Applications
Languages are tools, you choose the right tool to do the right thing. Since there's no universally perfect tool, there's no universally perfect language.
作为计算机系的学生,了解一些基础的电路知识,感受从传感器收集数据到数据分析再到算法预测整条流水线,对于后续知识的学习以及计算思维的培养还是很有帮助的。EE16A&B: Designing Information Devices and Systems I&II 是伯克利 EE 学生的大一入门课,其中 EE16A 注重通过电路从实际环境中收集和分析数据,而 EE16B 则侧重从这些收集到的数据进行分析并做出预测行为。
信号与系统是一门我觉得非常值得一上的课,最初学它只是为了满足我对傅里叶变换的好奇,但学完之后我才不禁感叹,傅立叶变换给我提供了一个全新的视角去看待这个世界,就如同微分方程一样,让你沉浸在用数学去精确描绘和刻画这个世界的优雅与神奇之中。
MIT 6.003: signal and systems 提供了全部的课程录影、书面作业以及答案。也可以去看这门课的远古版本
而 UCB EE120: Signal and Systems 关于傅立叶变换的 notes 写得非常好,并且提供了6 个非常有趣的 Python 编程作业,让你实践中运用信号与系统的理论与算法。
一份“能跑”的代码,和一份高质量的工业级代码是有本质区别的。因此我非常推荐低年级的同学学习一下 MIT 6.031: Software Construction 这门课,它会以 Java 语言为基础,以丰富细致的阅读材料和精心设计的编程练习传授如何编写不易出 bug、简明易懂、易于维护修改的高质量代码。大到宏观数据结构设计,小到如何写注释,遵循这些前人总结的细节和经验,对于你此后的编程生涯大有裨益。
当然,如果你想系统性地上一门软件工程的课程,那我推荐的是伯克利的 UCB CS169: software engineering。但需要提醒的是,和大多学校(包括贵校)的软件工程课程不同,这门课不会涉及传统的 design and document 模式,即强调各种类图、流程图及文档设计,而是采用近些年流行起来的小团队快速迭代 Agile Develepment 开发模式以及利用云平台的 Software as a service 服务模式。
从小我就一直听说,计算机的世界是由 01 构成的,我不理解但大受震撼。如果你的内心也怀有这份好奇,不妨花一到两个月的时间学习 Coursera: Nand2Tetris 这门无门槛的计算机课程。这门麻雀虽小五脏俱全的课程会从 01 开始让你亲手造出一台计算机,并在上面运行俄罗斯方块小游戏。一门课里涵盖了编译、虚拟机、汇编、体系结构、数字电路、逻辑门等等从上至下、从软至硬的各类知识,非常全面。难度上也是通过精心的设计,略去了众多现代计算机复杂的细节,提取出了最核心本质的东西,力图让每个人都能理解。在低年级,如果就能从宏观上建立对整个计算机体系的鸟瞰图,是大有裨益的。
当然,如果想深入现代计算机体系结构的复杂细节,还得上一门大学本科难度的课程 UCB CS61C: Great Ideas in Computer Architecture。UC Berkeley 作为 RISC-V 架构的发源地,在体系结构领域算得上首屈一指。其课程非常注重实践,你会在 Project 中手写汇编构造神经网络,从零开始搭建一个 CPU,这些实践都会让你对计算机体系结构有更为深入的理解,而不是仅停留于“取指译码执行访存写回”的单调背诵里。
计算机系统是一个庞杂而深刻的主题,在深入学习某个细分领域之前,对各个领域有一个宏观概念性的理解,对一些通用性的设计原则有所知晓,会让你在之后的深入学习中不断强化一些最为核心乃至哲学的概念,而不会桎梏于复杂的内部细节和各种 trick。因为在我看来,学习系统最关键的还是想让你领悟到这些最核心的东西,从而能够设计和实现出属于自己的系统。
MIT6.033: System Engineering 是 MIT 的系统入门课,主题涉及了操作系统、网络、分布式和系统安全,除了知识点的传授外,这门课还会讲授一些写作和表达上的技巧,让你学会如何设计并向别人介绍和分析自己的系统。这本书配套的教材 Principles of Computer System Design: An Introduction 也写得非常好,推荐大家阅读。
CMU 15-213: Introduction to Computer System 是 CMU 的系统入门课,内容覆盖了体系结构、操作系统、链接、并行、网络等等,兼具广度和深度,配套的教材 Computer Systems: A Programmer's Perspective 也是质量极高,强烈建议阅读。
操作系统作为各类纷繁复杂的底层硬件虚拟化出一套规范优雅的抽象,给所有应用软件提供丰富的功能支持。了解操作系统的设计原则和内部原理对于一个不满足于当调包侠的程序员来说是大有裨益的。出于对操作系统的热爱,我上过国内外很多操作系统课程,它们各有侧重和优劣,大家可以根据兴趣各取所需。
MIT 6.S081: Operating System Engineering,MIT 著名 PDOS 实验室出品,11 个 Project 让你在一个实现非常优雅的类Unix操作系统xv6上增加各类功能模块。这门课也让我深刻认识到,做系统不是靠 PPT 念出来的,是得几万行代码一点点累起来的。
UCB CS162: Operating System,伯克利的操作系统课,采用和 Stanford 同样的 Project —— 一个教学用操作系统 Pintos。我作为北京大学2022年春季学期操作系统实验班的助教,引入并改善了这个 Project,课程资源也会全部开源,具体参见课程网站。
NJU: Operating System Design and Implementation,南京大学的蒋炎岩老师开设的操作系统课程。蒋老师以其独到的视角
想必这两年各类 CS 讲座里最常听到的话就是“摩尔定律正在走向终结”,此话不假,当单核能力达到上限时,多核乃至众核架构如日中天。硬件的变化带来的是上层编程逻辑的适应与改变,要想充分利用硬件性能,编写并行程序几乎成了程序员的必备技能。与此同时,深度学习的兴起对计算机算力与存储的要求都达到了前所未有的高度,大规模集群的部署和优化也成为热门技术话题。
CMU 15-418/Stanford CS149: Parallel Computing
不知道你当年选择计算机是不是因为怀着一个中二的黑客梦想,但现实却是成为黑客道阻且长。
UCB CS161: Computer Security 是伯克利的系统安全课程,会涵盖栈攻击、密码学、网站安全、网络安全等等内容。
掌握这些理论知识之后,还需要在实践中培养和锻炼这些“黑客素养”。CTF 夺旗赛是一项比较热门的系统安全比赛,赛题中会融会贯通地考察你对计算机各个领域知识的理解和运用。北大今年也成功举办了第 0 届和第 1 届,鼓励大家后期踊跃参与,在实践中提高自己。下面列举一些我平时学习(摸鱼)用到的资源:
计网著名教材《自顶向下方法》的配套学习资源 Computer Networking: A Top-Down Approach。
没有什么能比自己写个 TCP/IP 协议栈更能加深对计算机网络的理解了,所以不妨试试 Stanford CS144: Computer Network,8 个 Project 带你实现整个协议栈。
没有什么能比自己写个关系型数据库更能加深对数据库系统的理解了。
CMU 15-445: Introduction to Database System
UCB CS186: Introduction to Database System
没有什么能比自己写个编译器更能加深对编译器的理解了。
Stanford CS148 Games101 Games103 Games202
网站的开发很少在计算机的培养方案里被重视,但其实掌握这项技能还是好处多多的,例如搭建自己的个人主页,抑或是给自己的课程项目做一个精彩的展示网页。
Stanford CS142: Web Applications
UCB Data100: Principles and Techniques of Data Science
Harvard CS50’s Introduction to AI with Python
UCB CS188: Introduction to Artificial Intelligence
Stanford CS231n: CNN for Visual Recognition
Stanford CS224n: Natural Language Processing
Stanford CS224w: Machine Learning with Graphs
UCB CS285: Deep Reinforcement Learning
授人以鱼不如授人以渔。
以上的课程规划难免带有强烈的个人偏好,不一定适合所有人,更多是起到抛砖引玉的作用。如果你想挑选自己感兴趣的方向和内容加以学习,可以参考我在下面列出来的资源。
计算机领域方向庞杂,知识浩如烟海,每个细分领域如果深究下去都可以说学无止境。因此,一个清晰明确的学习规划是非常重要的。这一节的内容是对后续整本书的内容的一个概览,你可以将其看作是这本书的目录,按需选择自己感兴趣的内容进行学习。
不过,在开始学习之前,先向小白们强烈推荐一个科普向系列视频 Crash Course: Computer Science,在短短 8 个小时里非常生动且全面地科普了关于计算机科学的方方面面:计算机的历史、计算机是如何运作的、组成计算机的各个重要模块、计算机科学中的重要思想等等等等。正如它的口号所说的 Computers are not magic!,希望看完这个视频之后,大家能对计算机科学有个全貌性地感知,从而怀着兴趣去面对下面浩如烟海的更为细致且深入的学习内容。
俗话说:磨刀不误砍柴工。如果你是一个刚刚接触计算机的24k纯小白,学会一些工具将会让你事半功倍。
学会提问:也许你会惊讶,提问也算计算机必备技能吗,还放在第一条?我觉得在开源社区中,学会提问是一项非常重要的能力,它包含两方面的事情。其一是会变相地培养你自主解决问题的能力,因为从形成问题、描述问题并发布、他人回答、最后再到理解回答这个周期是非常长的,如果遇到什么鸡毛蒜皮的事情都希望别人最好远程桌面手把手帮你完成,那计算机的世界基本与你无缘了。其二,如果真的经过尝试还无法解决,可以借助开源社区的帮助,但这时候如何通过简洁的文字让别人瞬间理解你的处境以及目的,就显得尤为重要。推荐阅读提问的智慧这篇文章,这不仅能提高你解决问题的概率和效率,也能让开源社区里无偿提供解答的人们拥有一个好心情。
MIT-Missing-Semester 这门课覆盖了这些工具中绝大部分,而且有相当详细的使用指导,强烈建议小白学习。
翻墙:由于一些众所周知的原因,谷歌、GitHub 等网站在大陆无法访问。然而很多时候,谷歌和 StackOverflow 可以解决你在开发过程中遇到的 95% 的问题。因此,学会翻墙几乎是一个内地 CSer 的必备技能。(考虑到法律问题,这个文档提供的翻墙方式仅对拥有北大邮箱的用户适用)。
命令行:熟练使用命令行是一种常常被忽视,或被认为难以掌握的技能,但实际上,它会提高极大地提高你作为工程师的灵活性以及生产力。命令行的艺术是一份非常经典的教程,它源于 Quora 的一个提问,但在各路大神的贡献努力下已经成为了一个 GitHub 十万 stars 的顶流项目,被翻译成了十几种语言。教程不长,非常建议大家反复通读,在实践中内化吸收。同时,掌握 shell 脚本编程也是一项不容忽视的技术,可以参考这个教程。
IDE (Integrated Development Environment):集成开发环境,说白了就是你写代码的地方。作为一个码农,IDE 的重要性不言而喻,但由于很多 IDE 是为大型工程项目设计的,体量较大,功能也过于丰富。其实如今一些轻便的文本编辑器配合丰富的插件生态基本可以满足日常的轻量编程需求。个人常用的编辑器是 VS Code 和 Sublime(前者的插件配置非常简单,后者略显复杂但颜值很高)。当然对于大型项目我还是会采用略重型的 IDE,例如 Pycharm (Python),IDEA (Java) 等等(免责申明:所有的 IDE 都是世界上最好的 IDE)。
Vim:一款命令行编辑工具。这是一个学习曲线有些陡峭的编辑器,不过学会它我觉得是非常有必要的,因为它将极大地提高你的开发效率。现在绝大多数 IDE 也都支持 Vim 插件,让你在享受现代开发环境的同时保留极客的炫酷(yue)。
Git:一款代码版本控制工具。Git的学习曲线可能更为陡峭,但出自 Linux 之父 Linus 之手的 Git 绝对是每个学 CS 的童鞋必须掌握的神器之一。
GitHub:基于 Git 的代码托管平台。全世界最大的代码开源社区,大佬集聚地。
GNU Make:一款工程构建工具。善用 GNU Make 会让你养成代码模块化的习惯,同时也能让你熟悉一些大型工程的编译链接流程。
CMake:一款功能比 GNU Make 更为强大的构建工具,建议掌握 GNU Make 之后再加以学习。
LaTex:逼格提升 论文排版工具。
Docker:一款相较于虚拟机更轻量级的软件打包与环境部署工具。
实用工具箱:除了上面提到的这些在开发中使用频率极高的工具之外,我还收集了很多实用有趣的免费工具,例如一些下载工具、设计工具、学习网站等等。
Thesis:毕业论文 Word 写作教程。
私以为一本好的教材应当是以人为本的,而不是炫技式的理论堆砌。告诉读者“是什么”固然重要,但更好的应当是教材作者将其在这个领域深耕几十年的经验融汇进书中,向读者娓娓道来“为什么”以及未来应该“怎么做”。
你以为的开发 —— 在 IDE 里疯狂码代码数小时。
实际上的开发 —— 配环境配几天还没开始写代码。
推荐一个非常不错的 GitHub 项目 DevOps-Guide,其中涵盖了非常多的运维方面的基础知识和教程,例如 Docker, Kubernetes, Linux, CI-CD, GitHub Actions 等等。
另外大家可以参考一份灵感来自 6.NULL MIT-Missing-Semester 的 环境配置指南,重点在于终端的美化配置。此外还包括常用软件源(如 GitHub, Anaconda, PyPI 等)的加速与替换以及一些 IDE 的配置与激活教程。
More contents under construction.
正如这章开头提到的,这份课程地图仅仅是一个仅供参考的课程规划,我作为一个临近毕业的本科生。深感自己没有权利也没有能力向别人宣扬“应该怎么学”。因此如果你觉得以下的课程分类与选择有不合理之处,我全盘接受,并深感抱歉。你可以在下一节定制属于你的课程地图
以下课程类别中除了含有 基础 和 入门 字眼的以外,并无明确的先后次序,大家只要满足某个课程的先修要求,完全可以根据自己的需要和喜好选择想要学习的课程。
另外由于贡献者的不断增加,这份课程地图已经从最初我的学习经历,发展成为很多 CS 自学者的资源合集,其中难免有内容交叉甚至重复的。但之所以都列出来,还是希望集百家之长,给大家尽可能多的选择与参考。
作为大一新生,学好微积分线代是和写代码至少同等重要的事情,相信已经有无数的前人经验提到过这一点,但我还是要不厌其烦地再强调一遍:学好微积分线代真的很重要!你也许会吐槽这些东西岂不是考完就忘,那我觉得你是并没有把握住它们本质,对它们的理解还没有达到刻骨铭心的程度。如果觉得老师课上讲的内容晦涩难懂,不妨参考 MIT 的 Calculus Course 和 18.06: Linear Algebra 的课程 notes,至少于我而言,它帮助我深刻理解了微积分和线性代数的许多本质。顺道再安利一个油管数学网红 3Blue1Brown,他的频道有很多用生动形象的动画阐释数学本质内核的视频,兼具深度和广度,质量非常高。
作为计算机系的学生,及早了解一些信息论的基础知识,我觉得是大有裨益的。但大多信息论课程都面向高年级本科生甚至研究生,对新手极不友好。而 MIT 的 6.050J: Information theory and Entropy 这门课正是为大一新生量身定制的,几乎没有先修要求,涵盖了编码、压缩、通信、信息熵等等内容,非常有趣。
集合论、图论、概率论等等是算法推导与证明的重要工具,也是后续高阶数学课程的基础。但我觉得这类课程的讲授很容易落入理论化与形式化的窠臼,让课堂成为定理结论的堆砌,而无法使学生深刻把握理论的本质,进而造成学了就背,考了就忘的怪圈。如果能在理论教学中穿插算法运用实例,学生在拓展算法知识的同时也能窥见理论的力量和魅力。
UCB CS70 : discrete Math and probability theory 和 UCB CS126 : Probability theory 是 UC Berkeley 的概率论课程,前者覆盖了离散数学和概率论基础,后者则涉及随机过程以及深入的理论内容。两者都非常注重理论和实践的结合,有丰富的算法实际运用实例,后者还有大量的Python编程作业来让学生运用概率论的知识解决实际问题。
作为计算机系的学生,培养计算思维是很重要的,实际问题的建模、离散化,计算机的模拟、分析,是一项很重要的能力。而这两年开始风靡的,由 MIT 打造的 Julia 编程语言以其 C 一样的速度和 Python 一样友好的语法在数值计算领域有一统天下之势,MIT 的许多数学课程也开始用 Julia 作为教学工具,把艰深的数学理论用直观清晰的代码展示出来。
ComputationalThinking 是 MIT 开设的一门计算思维入门课,所有课程内容全部开源,可以在课程网站直接访问。这门课利用 Julia 编程语言,在图像处理、社会科学与数据科学、气候学建模三个 topic 下带领学生理解算法、数学建模、数据分析、交互设计、图例展示,让学生体验计算与科学的美妙结合。内容虽然不难,但给我最深刻的感受就是,科学的魅力并不是故弄玄虚的艰深理论,不是诘屈聱牙的术语行话,而是用直观生动的案例,用简练深刻的语言,让每个普通人都能理解。
上完上面的体验课之后,如果意犹未尽的话,不妨试试 MIT 的 18.330 : Introduction to numerical analysis,这门课的编程作业同样会用 Julia 编程语言,不过难度和深度上都上了一个台阶。内容涉及了浮点编码、Root finding、线性系统、微分方程等等方面,整门课的主旨就是让你利用离散化的计算机表示去估计和逼近一个数学上连续的概念。这门课的教授还专门撰写了一本配套的开源教材 Fundamentals of Numerical Computation,里面附有丰富的 Julia 代码实例和严谨的公式推导。
如果你还意犹未尽的话,还有 MIT 的研究生课程 18.335: Introduction to numerical method 供你参考。
如果世间万物的运动发展都能用方程来刻画和描述,这是一件多么酷的事情呀!虽然几乎任何一所学校的 CS 培养方案中都没有微分方程相关的必修课程,但我还是觉得掌握它会赋予你一个新的视角来审视这个世界。
由于微分方程中往往会用到很多复变函数的知识,所以大家可以参考 MIT18.04: Complex variables functions 的课程 notes 来补齐先修知识。
MIT18.03: differential equations) 主要覆盖了常微分方程的求解,在此基础之上 MIT18.152: Partial differential equations) 则会深入偏微分方程的建模与求解。掌握了微分方程这一有利工具,相信对于你的实际问题的建模能力以及从众多噪声变量中把握本质的直觉都会有很大帮助。
作为计算机系的学生,我经常听到数学无用论的论断,对此我不敢苟同但也无权反对,但若凡事都硬要争出个有用和无用的区别来,倒也着实无趣,因此下面这些面向高年级甚至研究生的数学课程,大家按兴趣自取所需。
Standford EE364A: Convex Optimization
MIT18.650: Statistics for Applications
Languages are tools, you choose the right tool to do the right thing. Since there's no universally perfect tool, there's no universally perfect language.
作为计算机系的学生,了解一些基础的电路知识,感受从传感器收集数据到数据分析再到算法预测整条流水线,对于后续知识的学习以及计算思维的培养还是很有帮助的。EE16A&B: Designing Information Devices and Systems I&II 是伯克利 EE 学生的大一入门课,其中 EE16A 注重通过电路从实际环境中收集和分析数据,而 EE16B 则侧重从这些收集到的数据进行分析并做出预测行为。
信号与系统是一门我觉得非常值得一上的课,最初学它只是为了满足我对傅里叶变换的好奇,但学完之后我才不禁感叹,傅立叶变换给我提供了一个全新的视角去看待这个世界,就如同微分方程一样,让你沉浸在用数学去精确描绘和刻画这个世界的优雅与神奇之中。
MIT 6.003: signal and systems 提供了全部的课程录影、书面作业以及答案。也可以去看这门课的远古版本
而 UCB EE120: Signal and Systems 关于傅立叶变换的 notes 写得非常好,并且提供了6 个非常有趣的 Python 编程作业,让你实践中运用信号与系统的理论与算法。
一份“能跑”的代码,和一份高质量的工业级代码是有本质区别的。因此我非常推荐低年级的同学学习一下 MIT 6.031: Software Construction 这门课,它会以 Java 语言为基础,以丰富细致的阅读材料和精心设计的编程练习传授如何编写不易出 bug、简明易懂、易于维护修改的高质量代码。大到宏观数据结构设计,小到如何写注释,遵循这些前人总结的细节和经验,对于你此后的编程生涯大有裨益。
当然,如果你想系统性地上一门软件工程的课程,那我推荐的是伯克利的 UCB CS169: software engineering。但需要提醒的是,和大多学校(包括贵校)的软件工程课程不同,这门课不会涉及传统的 design and document 模式,即强调各种类图、流程图及文档设计,而是采用近些年流行起来的小团队快速迭代 Agile Develepment 开发模式以及利用云平台的 Software as a service 服务模式。
从小我就一直听说,计算机的世界是由 01 构成的,我不理解但大受震撼。如果你的内心也怀有这份好奇,不妨花一到两个月的时间学习 Coursera: Nand2Tetris 这门无门槛的计算机课程。这门麻雀虽小五脏俱全的课程会从 01 开始让你亲手造出一台计算机,并在上面运行俄罗斯方块小游戏。一门课里涵盖了编译、虚拟机、汇编、体系结构、数字电路、逻辑门等等从上至下、从软至硬的各类知识,非常全面。难度上也是通过精心的设计,略去了众多现代计算机复杂的细节,提取出了最核心本质的东西,力图让每个人都能理解。在低年级,如果就能从宏观上建立对整个计算机体系的鸟瞰图,是大有裨益的。
当然,如果想深入现代计算机体系结构的复杂细节,还得上一门大学本科难度的课程 UCB CS61C: Great Ideas in Computer Architecture。UC Berkeley 作为 RISC-V 架构的发源地,在体系结构领域算得上首屈一指。其课程非常注重实践,你会在 Project 中手写汇编构造神经网络,从零开始搭建一个 CPU,这些实践都会让你对计算机体系结构有更为深入的理解,而不是仅停留于“取指译码执行访存写回”的单调背诵里。
计算机系统是一个庞杂而深刻的主题,在深入学习某个细分领域之前,对各个领域有一个宏观概念性的理解,对一些通用性的设计原则有所知晓,会让你在之后的深入学习中不断强化一些最为核心乃至哲学的概念,而不会桎梏于复杂的内部细节和各种 trick。因为在我看来,学习系统最关键的还是想让你领悟到这些最核心的东西,从而能够设计和实现出属于自己的系统。
MIT6.033: System Engineering 是 MIT 的系统入门课,主题涉及了操作系统、网络、分布式和系统安全,除了知识点的传授外,这门课还会讲授一些写作和表达上的技巧,让你学会如何设计并向别人介绍和分析自己的系统。这本书配套的教材 Principles of Computer System Design: An Introduction 也写得非常好,推荐大家阅读。
CMU 15-213: Introduction to Computer System 是 CMU 的系统入门课,内容覆盖了体系结构、操作系统、链接、并行、网络等等,兼具广度和深度,配套的教材 Computer Systems: A Programmer's Perspective 也是质量极高,强烈建议阅读。
操作系统作为各类纷繁复杂的底层硬件虚拟化出一套规范优雅的抽象,给所有应用软件提供丰富的功能支持。了解操作系统的设计原则和内部原理对于一个不满足于当调包侠的程序员来说是大有裨益的。出于对操作系统的热爱,我上过国内外很多操作系统课程,它们各有侧重和优劣,大家可以根据兴趣各取所需。
MIT 6.S081: Operating System Engineering,MIT 著名 PDOS 实验室出品,11 个 Project 让你在一个实现非常优雅的类Unix操作系统xv6上增加各类功能模块。这门课也让我深刻认识到,做系统不是靠 PPT 念出来的,是得几万行代码一点点累起来的。
UCB CS162: Operating System,伯克利的操作系统课,采用和 Stanford 同样的 Project —— 一个教学用操作系统 Pintos。我作为北京大学2022年春季学期操作系统实验班的助教,引入并改善了这个 Project,课程资源也会全部开源,具体参见课程网站。
NJU: Operating System Design and Implementation,南京大学的蒋炎岩老师开设的操作系统课程。蒋老师以其独到的视角
想必这两年各类 CS 讲座里最常听到的话就是“摩尔定律正在走向终结”,此话不假,当单核能力达到上限时,多核乃至众核架构如日中天。硬件的变化带来的是上层编程逻辑的适应与改变,要想充分利用硬件性能,编写并行程序几乎成了程序员的必备技能。与此同时,深度学习的兴起对计算机算力与存储的要求都达到了前所未有的高度,大规模集群的部署和优化也成为热门技术话题。
CMU 15-418/Stanford CS149: Parallel Computing
不知道你当年选择计算机是不是因为怀着一个中二的黑客梦想,但现实却是成为黑客道阻且长。
UCB CS161: Computer Security 是伯克利的系统安全课程,会涵盖栈攻击、密码学、网站安全、网络安全等等内容。
掌握这些理论知识之后,还需要在实践中培养和锻炼这些“黑客素养”。CTF 夺旗赛是一项比较热门的系统安全比赛,赛题中会融会贯通地考察你对计算机各个领域知识的理解和运用。北大今年也成功举办了第 0 届和第 1 届,鼓励大家后期踊跃参与,在实践中提高自己。下面列举一些我平时学习(摸鱼)用到的资源:
计网著名教材《自顶向下方法》的配套学习资源 Computer Networking: A Top-Down Approach。
没有什么能比自己写个 TCP/IP 协议栈更能加深对计算机网络的理解了,所以不妨试试 Stanford CS144: Computer Network,8 个 Project 带你实现整个协议栈。
没有什么能比自己写个关系型数据库更能加深对数据库系统的理解了。
CMU 15-445: Introduction to Database System
UCB CS186: Introduction to Database System
没有什么能比自己写个编译器更能加深对编译器的理解了。
Stanford CS148 Games101 Games103 Games202
网站的开发很少在计算机的培养方案里被重视,但其实掌握这项技能还是好处多多的,例如搭建自己的个人主页,抑或是给自己的课程项目做一个精彩的展示网页。
Stanford CS142: Web Applications
UCB Data100: Principles and Techniques of Data Science
Harvard CS50’s Introduction to AI with Python
UCB CS188: Introduction to Artificial Intelligence
Stanford CS231n: CNN for Visual Recognition
Stanford CS224n: Natural Language Processing
Stanford CS224w: Machine Learning with Graphs
UCB CS285: Deep Reinforcement Learning
授人以鱼不如授人以渔。
以上的课程规划难免带有强烈的个人偏好,不一定适合所有人,更多是起到抛砖引玉的作用。如果你想挑选自己感兴趣的方向和内容加以学习,可以参考我在下面列出来的资源。
斯坦福的 Web 应用开发课程,内容覆盖了 HTML, CSS, JavaScript, ReactJs, NodeJS, ExpressJS, Web安全等等。8 个 Project 会让你在实战中锻炼自己的 Web 开发技巧。
斯坦福的 Web 应用开发课程,内容覆盖了 HTML, CSS, JavaScript, ReactJs, NodeJS, ExpressJS, Web安全等等。8 个 Project 会让你在实战中锻炼自己的 Web 开发技巧。
本课程是介绍如何使用 JavaScript 开发现代Web应用程序。 课程的重点是使用 ReactJS 构建单页面应用程序(SPA),并使用由 Node.js 构建 REST API。该课程还包含介绍 GraphQL 的部分,这是 REST API 的现代替代方案。
课程还包括测试、配置和环境管理,以及使用 MongoDB 来存储应用的数据。
本课程是介绍如何使用 JavaScript 开发现代Web应用程序。 课程的重点是使用 ReactJS 构建单页面应用程序(SPA),并使用由 Node.js 构建 REST API。该课程还包含介绍 GraphQL 的部分,这是 REST API 的现代替代方案。
课程还包括测试、配置和环境管理,以及使用 MongoDB 来存储应用的数据。
MIT 在每年 1 月份会有一个为期 4 周的 Independent Activities Period (IAP),在这个月里,MIT 的学生和老师可以自由地开设很多有趣的课程,而这门网站开发课程就是其中之一。
在一个月的时间里,你会从零开始掌握一个网站的设计、搭建、美化、交互等等核心内容,基本覆盖了 Web 开发的前后端大部分技术栈。如果你不需要系统地学习网络开发,而只是出于兴趣想把它加入自己的技能包里,那么这门课将非常适合你。
MIT 在每年 1 月份会有一个为期 4 周的 Independent Activities Period (IAP),在这个月里,MIT 的学生和老师可以自由地开设很多有趣的课程,而这门网站开发课程就是其中之一。
在一个月的时间里,你会从零开始掌握一个网站的设计、搭建、美化、交互等等核心内容,基本覆盖了 Web 开发的前后端大部分技术栈。如果你不需要系统地学习网络开发,而只是出于兴趣想把它加入自己的技能包里,那么这门课将非常适合你。
最近更新:增加陈天奇机器学习编译,增加 CMU 机器学习系统 ~
这是一本计算机的自学指南,也是对自己大学三年自学生涯的一个纪念。
这同时也是一份献给北大信科学弟学妹们的礼物。如果这本书能对你们的信科生涯有哪怕一丝一毫的帮助,都是对我极大的鼓励和慰藉。
本书目前规划了以下部分(如果你有其他好的建议,或者想加入贡献者的行列,欢迎邮件 zhongyinmin@pku.edu.cn 或者在 issue 里提问):
bash,环境变量,Anaconda ...大一入学时我是一个对计算机一无所知的小白,装了几十个 G 的 Visual Studio 天天和 OJ 你死我活。凭着高中的数学底子我数学课学得还不错,但在专业课上对竞赛大佬只有仰望。提到编程我只会打开那笨重的 IDE,新建一个我也不知道具体是干啥的命令行项目,然后就是 cin, cout, for 循环,然后 CE, RE, WA 循环。当时的我就处在一种拼命想学好但不知道怎么学,课上认真听讲但题还不会做,课后做作业完全是用时间和它硬耗的痛苦状态。我至今电脑里还存着自己大一上学期计算概论大作业的源代码 —— 一个 1200 行的 C++ 文件,没有头文件、没有类、没有封装、没有 unit test、没有 Makefile、没有 Git,唯一的优点是它确实能跑,缺点是“能跑”的补集。我一度怀疑我是不是不适合学计算机,因为童年对于极客的所有想象,已经被我第一个学期的体验彻底粉碎了。
这一切的转机发生在我大一的寒假,我心血来潮想学习 Python。无意间看到知乎有人推荐了 CS61A 这门课,说是 UC Berkeley 的大一入门课程,讲的就是 Python。我永远不会忘记那一天,打开 CS61A 课程网站的那个瞬间,就像哥伦布发现了新大陆一样,我开启了新世界的大门。
我一口气 3 个星期上完了这门课,它让我第一次感觉到原来 CS 可以学得如此充实而有趣,原来这世上竟有如此精华的课程。
为避免有崇洋媚外之嫌,我单纯从一个学生的视角来讲讲自学 CS61A 的体验:
独立搭建的课程网站: 一个网站将所有课程资源整合一体,条理分明的课程 schedule、所有 slides, hw, discussion 的文件链接、详细明确的课程给分说明、历年的考试题与答案。这样一个网站抛开美观程度不谈,既方便学生,也让资源公正透明。
课程教授亲自编写的教材:CS61A 这门课的开课老师将MIT的经典教材 Structure and Interpretation of Computer Programs (SICP) 用Python这门语言进行改编(原教材基于 Scheme 语言),保证了课堂内容与教材内容的一致性,同时补充了更多细节,可以说诚意满满。而且全书开源,可以直接线上阅读。
丰富到让人眼花缭乱的课程作业:14 个 lab 巩固随堂知识点,10 个 homework,还有 4 个代码量均上千行的 project。与大家熟悉的 OJ 和 Word 文档式的作业不同,所有作业均有完善的代码框架,保姆级的作业说明。每个 Project 都有详尽的 handout 文档、全自动的评分脚本。CS61A 甚至专门开发了一个自动化的作业提交评分系统(据说还发了论文)。当然,有人会说“一个 project 几千行代码大部分都是助教帮你写好的,你还能学到啥?”。此言差矣,作为一个刚刚接触计算机,连安装 Python 都磕磕绊绊的小白来说,这样完善的代码框架既可以让你专注于巩固课堂上学习到的核心知识点,又能有“我才学了一个月就能做一个小游戏了!”的成就感,还能有机会阅读学习别人高质量的代码,从而为自己所用。我觉得在低年级,这种代码框架可以说百利而无一害。唯一的害也许是苦了老师和助教,因为开发这样的作业可想而知需要相当的时间投入。
每周 Discussion 讨论课,助教会讲解知识难点和考试例题:类似于北京大学 ICS 的小班研讨,但习题全部用 LaTeX 撰写,相当规范且会明确给出 solution。
这样的课程,你完全不需要任何计算机的基础,你只需要努力、认真、花时间就够了。此前那种有劲没处使的感觉,那种付出再多时间却得不到回报的感觉,从此烟消云散。这太适合我了,我从此爱上了自学。
试想如果有人能把艰深的知识点嚼碎嚼烂,用生动直白的方式呈现给你,还有那么多听起来就很 fancy,种类繁多的 project 来巩固你的理论知识,你会觉得他们真的是在倾尽全力想方设法地让你完全掌握这门课,你会觉得不学好它简直是对这些课程建设者的侮辱。
如果你觉得我在夸大其词,那么不妨从 CS61A 开始,因为它是我的梦开始的地方。
在我2020年秋季学期担任《深入理解计算机系统》(CSAPP)这门课的助教时,我已经自学一年多了。这一年多来我无比享受这种自学模式,为了分享这种快乐,我为自己的小班同学做过一个 CS自学资料整理仓库。当时纯粹是心血来潮,因为我也不敢公然鼓励大家翘课自学。
但随着又一年时间的维护,这个仓库的内容已经相当丰富,基本覆盖了计科、智能系、软工系的绝大多数课程,我也为每个课程都建了各自的 GitHub 仓库,汇总我用到的自学资料以及作业实现。
直到大四开始凑学分毕业的时候,我打开自己的培养方案,我发现它已经是我这个自学仓库的子集了,而这距离我开始自学也才两年半而已。于是,一个大胆的想法在我脑海中浮现:也许,我可以打造一个自学式的培养方案,把我这三年自学经历中遇到的坑、走过的路记录下来,以期能为后来的学弟学妹们贡献自己的一份微薄之力。
如果大家可以在三年不到的时间里就能建立起整座CS的基础大厦,能有相对扎实的数学功底和代码能力,经历过数十个千行代码量的 Project 的洗礼,掌握至少 C/C++/Java/JS/Python/Go/Rust 等主流语言,对算法、电路、体系、网络、操统、编译、人工智能、机器学习、计算机视觉、自然语言处理、强化学习、密码学、信息论、博弈论、数值分析、统计学、分布式、数据库、图形学、Web开发、云服务、超算等等方面均有涉猎。我想,你将有足够的底气和自信选择自己感兴趣的方向,无论是就业还是科研,你都将有相当的竞争力。
因为我坚信,既然你能坚持听我 BB 到这里,你一定不缺学好 CS 的能力,你只是没有一个好的老师,给你讲一门好的课程。而我,将力图根据我三年的体验,为你挑选这样的课程。
对我来说,自学最大的好处就在于可以完全根据自己的进度来调整学习速度。对于一些疑难知识点,我可以反复回看视频,在网上谷歌相关的内容,上 StackOverflow 提问题,直到完全将它弄明白。而对于自己掌握得相对较快的内容,则可以两倍速甚至三倍速略过。
自学的另一大好处就是博采众长。计算机系的几大核心课程:体系、网络、操统、编译,每一门我基本都上过不同大学的课程,不同的教材、不同的知识点侧重、不同的 project 将会极大丰富你的视野,也会让你理解错误的一些内容得到及时纠正。
自学的第三个好处是时间自由,具体原因省略。
当然,作为 CS 自学主义的忠实拥趸,我不得不承认自学也有它的坏处。
第一就是交流沟通的不便。我其实是一个很热衷于提问的人,对于所有没有弄明白的点,我都喜欢穷追到底。但当你面对着屏幕听到老师讲了一个你没明白的知识点的时候,你无法顺着网线到另一端向老师问个明白。我努力通过独立思考和善用 Google 来缓解这一点,但是,如果能有几个志同道合的伙伴结伴自学,那将是极好的。关于交流群的建立,大家可以参考仓库 README 中的教程。
第二就是这些自学的课程基本都是英文的。从视频到slides到作业全是英文,所以有一定的门槛。不过我觉得这个挑战如果你克服了的话对你是极为有利的。因为在当下,虽然我很不情愿,但也不得不承认,在计算机领域,很多优质的文档、论坛、网站都是全英文的。养成英文阅读的习惯,在赤旗插遍世界之前,还是有一定好处的(狗头保命)。
第三,也是我觉得最困难的一点,就是自律。因为没有 DDL 有时候真的是一件可怕的事情,特别是随着学习的深入,国外的很多课程是相当虐的。你得有足够的驱动力强迫自己静下心来,阅读几十页的 Project Handout,理解上千行的代码框架,忍受数个小时的 debug 时光。而这一切,没有学分,没有绩点,没有老师,没有同学,只有一个信念 —— 你在变强。
正如我在前言里说的,任何有志于自学计算机的朋友都可以参考这本书。如果你已经有了一定的计算机基础,只是对某个特定的领域感兴趣,可以选择性地挑选你感兴趣的内容进行学习。当然,如果你是一个像我当年一样对计算机一无所知的小白,初入大学的校门,我希望这本书能成为你的攻略,让你花最少的时间掌握你所需要的知识和能力。某种程度上,这本书更像是一个根据我的体验来排序的课程搜索引擎,帮助大家足不出户,体验世界顶级名校的计算机优质课程。
当然,作为一个还未毕业的本科生,我深感自己没有能力也没有权利去宣扬一种学习方式,我只是希望这份资料能让那些同样有自学之心和毅力朋友可以少走些弯路,收获更丰富、更多样、更满足的学习体验。
在这里,我怀着崇敬之心真诚地感谢所有将课程资源无偿开源的各位教授们。这些课程倾注了他们数十年教学生涯的积淀和心血,他们却选择无私地让所有人享受到如此高质量的CS教育。没有他们,我的大学生活不会这样充实而快乐。很多教授在我给他们发了感谢邮件之后,甚至会回复上百字的长文,真的让我无比感动。他们也时刻激励着我,做一件事,就得用心做好,无论是科研,还是为人。
一个人的力量终究是有限的,这本书也是我在繁重的科研之余熬夜抽空写出来的,难免有不够完善之处。另外,由于个人做的是系统方向,很多课程侧重系统领域,对于数学、理论计算机、高级算法相关的内容则相对少些。如果有大佬想在其他领域分享自己的自学经历与资源,可以直接在项目中发起 Pull Request,也欢迎和我邮件联系(zhongyinmin@pku.edu.cn)。
方法参见仓库的 README.md。

最近更新:增加陈天奇机器学习编译,增加 CMU 机器学习系统 ~
这是一本计算机的自学指南,也是对自己大学三年自学生涯的一个纪念。
这同时也是一份献给北大信科学弟学妹们的礼物。如果这本书能对你们的信科生涯有哪怕一丝一毫的帮助,都是对我极大的鼓励和慰藉。
本书目前规划了以下部分(如果你有其他好的建议,或者想加入贡献者的行列,欢迎邮件 zhongyinmin@pku.edu.cn 或者在 issue 里提问):
bash,环境变量,Anaconda ...大一入学时我是一个对计算机一无所知的小白,装了几十个 G 的 Visual Studio 天天和 OJ 你死我活。凭着高中的数学底子我数学课学得还不错,但在专业课上对竞赛大佬只有仰望。提到编程我只会打开那笨重的 IDE,新建一个我也不知道具体是干啥的命令行项目,然后就是 cin, cout, for 循环,然后 CE, RE, WA 循环。当时的我就处在一种拼命想学好但不知道怎么学,课上认真听讲但题还不会做,课后做作业完全是用时间和它硬耗的痛苦状态。我至今电脑里还存着自己大一上学期计算概论大作业的源代码 —— 一个 1200 行的 C++ 文件,没有头文件、没有类、没有封装、没有 unit test、没有 Makefile、没有 Git,唯一的优点是它确实能跑,缺点是“能跑”的补集。我一度怀疑我是不是不适合学计算机,因为童年对于极客的所有想象,已经被我第一个学期的体验彻底粉碎了。
这一切的转机发生在我大一的寒假,我心血来潮想学习 Python。无意间看到知乎有人推荐了 CS61A 这门课,说是 UC Berkeley 的大一入门课程,讲的就是 Python。我永远不会忘记那一天,打开 CS61A 课程网站的那个瞬间,就像哥伦布发现了新大陆一样,我开启了新世界的大门。
我一口气 3 个星期上完了这门课,它让我第一次感觉到原来 CS 可以学得如此充实而有趣,原来这世上竟有如此精华的课程。
为避免有崇洋媚外之嫌,我单纯从一个学生的视角来讲讲自学 CS61A 的体验:
独立搭建的课程网站: 一个网站将所有课程资源整合一体,条理分明的课程 schedule、所有 slides, hw, discussion 的文件链接、详细明确的课程给分说明、历年的考试题与答案。这样一个网站抛开美观程度不谈,既方便学生,也让资源公正透明。
课程教授亲自编写的教材:CS61A 这门课的开课老师将MIT的经典教材 Structure and Interpretation of Computer Programs (SICP) 用Python这门语言进行改编(原教材基于 Scheme 语言),保证了课堂内容与教材内容的一致性,同时补充了更多细节,可以说诚意满满。而且全书开源,可以直接线上阅读。
丰富到让人眼花缭乱的课程作业:14 个 lab 巩固随堂知识点,10 个 homework,还有 4 个代码量均上千行的 project。与大家熟悉的 OJ 和 Word 文档式的作业不同,所有作业均有完善的代码框架,保姆级的作业说明。每个 Project 都有详尽的 handout 文档、全自动的评分脚本。CS61A 甚至专门开发了一个自动化的作业提交评分系统(据说还发了论文)。当然,有人会说“一个 project 几千行代码大部分都是助教帮你写好的,你还能学到啥?”。此言差矣,作为一个刚刚接触计算机,连安装 Python 都磕磕绊绊的小白来说,这样完善的代码框架既可以让你专注于巩固课堂上学习到的核心知识点,又能有“我才学了一个月就能做一个小游戏了!”的成就感,还能有机会阅读学习别人高质量的代码,从而为自己所用。我觉得在低年级,这种代码框架可以说百利而无一害。唯一的害也许是苦了老师和助教,因为开发这样的作业可想而知需要相当的时间投入。
每周 Discussion 讨论课,助教会讲解知识难点和考试例题:类似于北京大学 ICS 的小班研讨,但习题全部用 LaTeX 撰写,相当规范且会明确给出 solution。
这样的课程,你完全不需要任何计算机的基础,你只需要努力、认真、花时间就够了。此前那种有劲没处使的感觉,那种付出再多时间却得不到回报的感觉,从此烟消云散。这太适合我了,我从此爱上了自学。
试想如果有人能把艰深的知识点嚼碎嚼烂,用生动直白的方式呈现给你,还有那么多听起来就很 fancy,种类繁多的 project 来巩固你的理论知识,你会觉得他们真的是在倾尽全力想方设法地让你完全掌握这门课,你会觉得不学好它简直是对这些课程建设者的侮辱。
如果你觉得我在夸大其词,那么不妨从 CS61A 开始,因为它是我的梦开始的地方。
在我2020年秋季学期担任《深入理解计算机系统》(CSAPP)这门课的助教时,我已经自学一年多了。这一年多来我无比享受这种自学模式,为了分享这种快乐,我为自己的小班同学做过一个 CS自学资料整理仓库。当时纯粹是心血来潮,因为我也不敢公然鼓励大家翘课自学。
但随着又一年时间的维护,这个仓库的内容已经相当丰富,基本覆盖了计科、智能系、软工系的绝大多数课程,我也为每个课程都建了各自的 GitHub 仓库,汇总我用到的自学资料以及作业实现。
直到大四开始凑学分毕业的时候,我打开自己的培养方案,我发现它已经是我这个自学仓库的子集了,而这距离我开始自学也才两年半而已。于是,一个大胆的想法在我脑海中浮现:也许,我可以打造一个自学式的培养方案,把我这三年自学经历中遇到的坑、走过的路记录下来,以期能为后来的学弟学妹们贡献自己的一份微薄之力。
如果大家可以在三年不到的时间里就能建立起整座CS的基础大厦,能有相对扎实的数学功底和代码能力,经历过数十个千行代码量的 Project 的洗礼,掌握至少 C/C++/Java/JS/Python/Go/Rust 等主流语言,对算法、电路、体系、网络、操统、编译、人工智能、机器学习、计算机视觉、自然语言处理、强化学习、密码学、信息论、博弈论、数值分析、统计学、分布式、数据库、图形学、Web开发、云服务、超算等等方面均有涉猎。我想,你将有足够的底气和自信选择自己感兴趣的方向,无论是就业还是科研,你都将有相当的竞争力。
因为我坚信,既然你能坚持听我 BB 到这里,你一定不缺学好 CS 的能力,你只是没有一个好的老师,给你讲一门好的课程。而我,将力图根据我三年的体验,为你挑选这样的课程。
对我来说,自学最大的好处就在于可以完全根据自己的进度来调整学习速度。对于一些疑难知识点,我可以反复回看视频,在网上谷歌相关的内容,上 StackOverflow 提问题,直到完全将它弄明白。而对于自己掌握得相对较快的内容,则可以两倍速甚至三倍速略过。
自学的另一大好处就是博采众长。计算机系的几大核心课程:体系、网络、操统、编译,每一门我基本都上过不同大学的课程,不同的教材、不同的知识点侧重、不同的 project 将会极大丰富你的视野,也会让你理解错误的一些内容得到及时纠正。
自学的第三个好处是时间自由,具体原因省略。
当然,作为 CS 自学主义的忠实拥趸,我不得不承认自学也有它的坏处。
第一就是交流沟通的不便。我其实是一个很热衷于提问的人,对于所有没有弄明白的点,我都喜欢穷追到底。但当你面对着屏幕听到老师讲了一个你没明白的知识点的时候,你无法顺着网线到另一端向老师问个明白。我努力通过独立思考和善用 Google 来缓解这一点,但是,如果能有几个志同道合的伙伴结伴自学,那将是极好的。关于交流群的建立,大家可以参考仓库 README 中的教程。
第二就是这些自学的课程基本都是英文的。从视频到slides到作业全是英文,所以有一定的门槛。不过我觉得这个挑战如果你克服了的话对你是极为有利的。因为在当下,虽然我很不情愿,但也不得不承认,在计算机领域,很多优质的文档、论坛、网站都是全英文的。养成英文阅读的习惯,在赤旗插遍世界之前,还是有一定好处的(狗头保命)。
第三,也是我觉得最困难的一点,就是自律。因为没有 DDL 有时候真的是一件可怕的事情,特别是随着学习的深入,国外的很多课程是相当虐的。你得有足够的驱动力强迫自己静下心来,阅读几十页的 Project Handout,理解上千行的代码框架,忍受数个小时的 debug 时光。而这一切,没有学分,没有绩点,没有老师,没有同学,只有一个信念 —— 你在变强。
正如我在前言里说的,任何有志于自学计算机的朋友都可以参考这本书。如果你已经有了一定的计算机基础,只是对某个特定的领域感兴趣,可以选择性地挑选你感兴趣的内容进行学习。当然,如果你是一个像我当年一样对计算机一无所知的小白,初入大学的校门,我希望这本书能成为你的攻略,让你花最少的时间掌握你所需要的知识和能力。某种程度上,这本书更像是一个根据我的体验来排序的课程搜索引擎,帮助大家足不出户,体验世界顶级名校的计算机优质课程。
当然,作为一个还未毕业的本科生,我深感自己没有能力也没有权利去宣扬一种学习方式,我只是希望这份资料能让那些同样有自学之心和毅力朋友可以少走些弯路,收获更丰富、更多样、更满足的学习体验。
在这里,我怀着崇敬之心真诚地感谢所有将课程资源无偿开源的各位教授们。这些课程倾注了他们数十年教学生涯的积淀和心血,他们却选择无私地让所有人享受到如此高质量的CS教育。没有他们,我的大学生活不会这样充实而快乐。很多教授在我给他们发了感谢邮件之后,甚至会回复上百字的长文,真的让我无比感动。他们也时刻激励着我,做一件事,就得用心做好,无论是科研,还是为人。
一个人的力量终究是有限的,这本书也是我在繁重的科研之余熬夜抽空写出来的,难免有不够完善之处。另外,由于个人做的是系统方向,很多课程侧重系统领域,对于数学、理论计算机、高级算法相关的内容则相对少些。如果有大佬想在其他领域分享自己的自学经历与资源,可以直接在项目中发起 Pull Request,也欢迎和我邮件联系(zhongyinmin@pku.edu.cn)。
方法参见仓库的 README.md。
伯克利的人工智能入门课,课程 notes 写得非常深入浅出,基本不需要观看课程视频。课程内容的安排基本按照人工智能的经典教材 Artificial intelligence: A Modern Approach 的章节顺序,覆盖了搜索剪枝、约束满足问题、马尔可夫决策过程、强化学习、贝叶斯网络、隐马尔可夫模型以及基础的机器学习和神经网络的相关内容。
2018年秋季学期的版本免费开放了 gradescope,大家可以在线完成书面作业并实时得到测评结果。同时课程的 6 个 Project 也是质量爆炸,复现了经典的 Packman(吃豆人)小游戏,会让你利用学到的 AI 知识,去实现相关算法,让你的吃豆人在迷宫里自由穿梭,躲避鬼怪,收集豆子。
伯克利的人工智能入门课,课程 notes 写得非常深入浅出,基本不需要观看课程视频。课程内容的安排基本按照人工智能的经典教材 Artificial intelligence: A Modern Approach 的章节顺序,覆盖了搜索剪枝、约束满足问题、马尔可夫决策过程、强化学习、贝叶斯网络、隐马尔可夫模型以及基础的机器学习和神经网络的相关内容。
2018年秋季学期的版本免费开放了 gradescope,大家可以在线完成书面作业并实时得到测评结果。同时课程的 6 个 Project 也是质量爆炸,复现了经典的 Packman(吃豆人)小游戏,会让你利用学到的 AI 知识,去实现相关算法,让你的吃豆人在迷宫里自由穿梭,躲避鬼怪,收集豆子。
一门非常基础的AI入门课,让人眼前一亮的是12个设计精巧的编程作业,都会用学到的AI知识去实现一个简易的游戏AI,比如用强化学习训练一个Nim游戏的AI,用alpha-beta剪枝去扫雷等等,非常适合新手入门或者大佬休闲。
@PKUFlyingPig 在学习这门课中用到的所有资源和作业实现都汇总在 PKUFlyingPig/cs50_ai - GitHub 中。
一门非常基础的AI入门课,让人眼前一亮的是12个设计精巧的编程作业,都会用学到的AI知识去实现一个简易的游戏AI,比如用强化学习训练一个Nim游戏的AI,用alpha-beta剪枝去扫雷等等,非常适合新手入门或者大佬休闲。
@PKUFlyingPig 在学习这门课中用到的所有资源和作业实现都汇总在 PKUFlyingPig/cs50_ai - GitHub 中。
智能计算系统是智能的核心物质载体,每年全球要制造数以十亿计的智能计算系统(包括智能手机、智能服务器、智能可穿戴设备等),需要大量的智能计算系统的设计者和开发者。智能计算系统人才的培养直接关系到我国智能产业的核心竞争力。因此,对智能计算系统的认识和理解是智能时代计算机类专业学生培养方案中不可或缺的重要组成部分,是计算机类专业学生的核心竞争力。
国内的陈云霁老师开的课,在其他若干个大学也都有开对应的课程。这门课用一个个实验带大家以一个完整的视野理解人工智能的技术栈。从上层的深度学习框架,到用底层语言编写算子,再到硬件中 MLU 的设计,让大家形成系统思维,体会自上而下,融会贯通的乐趣。
我做了其中的 2,3,4,5 这几个实验,其中综合实验和硬件实验没有做,如果有做了的同学欢迎大家补上你的链接。
个人体会是第三章实现算子的实验让我对深度学习框架的了解加深了很多。第五章的实验BCL语言编写算子如果了解 CUDA 的话会感觉很熟悉。
推荐去买一本教材看一看,会让我们理解整体的技术栈。熟悉深度学习的同学可以直接从第五章开始看,看看深度学习框架底层到底是什么样的。
我因为这门课的启发,参考一本书(书名在仓库中)写了一个简易的深度学习框架。在这个框架里可以看到智能计算系统实验中的一些影子。同时受到 build-your-own-x 系列的启发,我也打算写一下教程,教大家写一个自己的深度学习框架。代码用 Python 写的,代码量较少,适合有一定基础的同学阅读。之后打算添加更多的算子,有望实现一个较为全面的框架,并希望移植到 C++ 中,以兼顾性能与开发效率。
@ysj1173886760 在学习这门课中用到的所有资源和作业实现都汇总在 ysj1173886760/Learning: ai-system - GitHub 中。
智能计算系统是智能的核心物质载体,每年全球要制造数以十亿计的智能计算系统(包括智能手机、智能服务器、智能可穿戴设备等),需要大量的智能计算系统的设计者和开发者。智能计算系统人才的培养直接关系到我国智能产业的核心竞争力。因此,对智能计算系统的认识和理解是智能时代计算机类专业学生培养方案中不可或缺的重要组成部分,是计算机类专业学生的核心竞争力。
国内的陈云霁老师开的课,在其他若干个大学也都有开对应的课程。这门课用一个个实验带大家以一个完整的视野理解人工智能的技术栈。从上层的深度学习框架,到用底层语言编写算子,再到硬件中 MLU 的设计,让大家形成系统思维,体会自上而下,融会贯通的乐趣。
我做了其中的 2,3,4,5 这几个实验,其中综合实验和硬件实验没有做,如果有做了的同学欢迎大家补上你的链接。
个人体会是第三章实现算子的实验让我对深度学习框架的了解加深了很多。第五章的实验BCL语言编写算子如果了解 CUDA 的话会感觉很熟悉。
推荐去买一本教材看一看,会让我们理解整体的技术栈。熟悉深度学习的同学可以直接从第五章开始看,看看深度学习框架底层到底是什么样的。
我因为这门课的启发,参考一本书(书名在仓库中)写了一个简易的深度学习框架。在这个框架里可以看到智能计算系统实验中的一些影子。同时受到 build-your-own-x 系列的启发,我也打算写一下教程,教大家写一个自己的深度学习框架。代码用 Python 写的,代码量较少,适合有一定基础的同学阅读。之后打算添加更多的算子,有望实现一个较为全面的框架,并希望移植到 C++ 中,以兼顾性能与开发效率。
@ysj1173886760 在学习这门课中用到的所有资源和作业实现都汇总在 ysj1173886760/Learning: ai-system - GitHub 中。
伯克利 CS61 系列的最后一门课程,深入计算机的硬件细节,带领学生逐步理解 C 语言是如何一步步转化为 RISC-V 汇编并在 CPU 上执行的。和 Nand2Tetris 不同,这门课 在难度和深度上都会提高很多,具体会涉及到流水线、Cache、虚存以及并发相关的内容。
这门课的 Project 也非常新颖有趣。Project1 会让你用 C 语言写一个小程序,20 年秋季学期是著名的游戏 Game of Life。Project2 会让你用 RISC-V 汇编编写一个神经网络,用来 识别 MNIST 手写数字,非常锻炼你对汇编代码的理解和运用。Project3 中你会用 Logisim 这个数字电路模拟软件搭建出一个二级流水线的 CPU,并在上面运行 RISC-V 汇编代码。Project4 会让你使用 OpenMP, SIMD 等方法并行优化矩阵运算,实现一个简易的 Numpy。
总而言之,这是个人上过的最好的计算机体系结构的课程。
@PKUFlyingPig 在学习这门课中用到的所有资源和作业实现都汇总在 PKUFlyingPig/CS61C-summer20 - GitHub 中。
伯克利 CS61 系列的最后一门课程,深入计算机的硬件细节,带领学生逐步理解 C 语言是如何一步步转化为 RISC-V 汇编并在 CPU 上执行的。和 Nand2Tetris 不同,这门课 在难度和深度上都会提高很多,具体会涉及到流水线、Cache、虚存以及并发相关的内容。
这门课的 Project 也非常新颖有趣。Project1 会让你用 C 语言写一个小程序,20 年秋季学期是著名的游戏 Game of Life。Project2 会让你用 RISC-V 汇编编写一个神经网络,用来 识别 MNIST 手写数字,非常锻炼你对汇编代码的理解和运用。Project3 中你会用 Logisim 这个数字电路模拟软件搭建出一个二级流水线的 CPU,并在上面运行 RISC-V 汇编代码。Project4 会让你使用 OpenMP, SIMD 等方法并行优化矩阵运算,实现一个简易的 Numpy。
总而言之,这是个人上过的最好的计算机体系结构的课程。
@PKUFlyingPig 在学习这门课中用到的所有资源和作业实现都汇总在 PKUFlyingPig/CS61C-summer20 - GitHub 中。
CMU 大名鼎鼎的镇系神课,以其内容庞杂,Project 巨难而闻名遐迩。课程内容覆盖了汇编语言、体系结构、操作系统、编译链接、并行、网络等,作为系统入门课,兼具深度和广度,如果自学确实需要相当的毅力和代码功底。
这门课配合的教材由 CMU 计算机系主任 Bryant 教授执笔,也即所谓的 CSAPP。这也是我第一本认认真真一页一页读过去的计算机教材,虽然很难啃,但着实收获良多。
北大购买了这门课的版权并开设了 Introduction to Computer System 这门课,但其实 CSAPP 所有的课程资源和实验代码都能在它的官方主页上访问到(具体参见下方链接)。
这门课由于过于出名,全世界的码农争相学习,导致其 Project 的答案在网上几乎唾手可得。但如果你真的想锻炼自己的代码能力,希望你不要借鉴任何第三方代码。
认真学完这一门课,你对计算机系统的理解绝对会上升一个台阶。
英语有困难的同学可以参考B站UP主九曲阑干对 CSAPP 的中文讲解(据说CMU的中国留学生也在CMU的课堂上看这个视频呢)。另外如果大家在看完 CSAPP 后对书中的第七章链接有一定的疑问,推荐阅读《程序员的自我修养》这本书,书的副标题是链接,装载与库。这本书能够帮助我们完善对程序链接的理解,相信你在看完这本书以后可以对程序的链接,ELF 文件,动态库都将有一个更加深入的理解。十分推荐在读完 CSAPP,对计算机系统有一定的了解以后作为补充资料来阅读。
CMU 大名鼎鼎的镇系神课,以其内容庞杂,Project 巨难而闻名遐迩。课程内容覆盖了汇编语言、体系结构、操作系统、编译链接、并行、网络等,作为系统入门课,兼具深度和广度,如果自学确实需要相当的毅力和代码功底。
这门课配合的教材由 CMU 计算机系主任 Bryant 教授执笔,也即所谓的 CSAPP。这也是我第一本认认真真一页一页读过去的计算机教材,虽然很难啃,但着实收获良多。
北大购买了这门课的版权并开设了 Introduction to Computer System 这门课,但其实 CSAPP 所有的课程资源和实验代码都能在它的官方主页上访问到(具体参见下方链接)。
这门课由于过于出名,全世界的码农争相学习,导致其 Project 的答案在网上几乎唾手可得。但如果你真的想锻炼自己的代码能力,希望你不要借鉴任何第三方代码。
认真学完这一门课,你对计算机系统的理解绝对会上升一个台阶。
英语有困难的同学可以参考B站UP主九曲阑干对 CSAPP 的中文讲解(据说CMU的中国留学生也在CMU的课堂上看这个视频呢)。另外如果大家在看完 CSAPP 后对书中的第七章链接有一定的疑问,推荐阅读《程序员的自我修养》这本书,书的副标题是链接,装载与库。这本书能够帮助我们完善对程序链接的理解,相信你在看完这本书以后可以对程序的链接,ELF 文件,动态库都将有一个更加深入的理解。十分推荐在读完 CSAPP,对计算机系统有一定的了解以后作为补充资料来阅读。
体系结构领域的大牛 Onur Mutlu 来教你数字电路和计算机体系结构。课程完全从计算机设计的角度出发,从晶体管、逻辑门开始,一直讲解到微架构、缓存和虚拟内存,还会介绍 很多体系结构领域最新的研究进展。课程共有 9 个 lab,使用 Basys 3 FPGA 开发板(可自行购买)和 Xilinx 公司的 Vivado 软件(可在官网免费下载使用)进行电路设计,从组合电路 和时序电路开始,一直到最后部署一个完整的 CPU。课程资料除了 lab 答案和当期考试答案之外全部开源,学完之后你可以掌握计算机相关的数字电路,Verilog 硬件描述语言,MIPS 与 C 之间的转换关系,MIPS 单周期多周期流水线 CPU 的设计和性能分析,缓存,虚拟内存等重要概念。
体系结构领域的大牛 Onur Mutlu 来教你数字电路和计算机体系结构。课程完全从计算机设计的角度出发,从晶体管、逻辑门开始,一直讲解到微架构、缓存和虚拟内存,还会介绍 很多体系结构领域最新的研究进展。课程共有 9 个 lab,使用 Basys 3 FPGA 开发板(可自行购买)和 Xilinx 公司的 Vivado 软件(可在官网免费下载使用)进行电路设计,从组合电路 和时序电路开始,一直到最后部署一个完整的 CPU。课程资料除了 lab 答案和当期考试答案之外全部开源,学完之后你可以掌握计算机相关的数字电路,Verilog 硬件描述语言,MIPS 与 C 之间的转换关系,MIPS 单周期多周期流水线 CPU 的设计和性能分析,缓存,虚拟内存等重要概念。
Coursera 上被数万人评为满分,在全球四百多所高校、高中被采用,让一个完全没有计算机基础的人从与非门开始造一台计算机,并在上面运行俄罗斯方块小游戏。
听起来就很酷对不对?实现起来更酷!这门课分为硬件和软件两个部分。在硬件部分,你将进入 01 的世界,用与非门构造出逻辑电路,并逐步搭建出一个 CPU 来运行一套课程作者定义的简易汇编代码。在软件部分,你将编写一个编译器,将作者开发的一个名为Jack的高级语言编译为可以运行在虚拟机上的字节码,然后进一步翻译为汇编代码。你还将开发一个简易的 OS,让你的计算机支持输入输出图形界面。至此,你可以用 Jack 开发一个俄罗斯方块的小游戏,将它编译为汇编代码,运行在你用与非门搭建出的 CPU 上,通过你开发的 OS 进行交互。学完这门课程,你将对整个计算机的体系结构有一个全局且深刻的理解,对于你后续课程的学习有着莫大的帮助。
你也许会担心课程会不会很难,但这门课面向的人群是完全没有计算机基础的人,课程作者的目标是让高中生都能理解。因此,只要你按部就班跟着课程规划走,一个月内学完应该绰绰有余。麻雀虽小但是五脏俱全,这门课很好地提取出了计算机的本质,而不过多地陷于现代计算机为了性能而设计出的众多复杂细节。让学习者能在轻松愉快的学习体验中感受计算机的优雅与神奇。
@PKUFlyingPig 在学习这门课中用到的所有资源和作业实现都汇总在 PKUFlyingPig/NandToTetris - GitHub 中。
Coursera 上被数万人评为满分,在全球四百多所高校、高中被采用,让一个完全没有计算机基础的人从与非门开始造一台计算机,并在上面运行俄罗斯方块小游戏。
听起来就很酷对不对?实现起来更酷!这门课分为硬件和软件两个部分。在硬件部分,你将进入 01 的世界,用与非门构造出逻辑电路,并逐步搭建出一个 CPU 来运行一套课程作者定义的简易汇编代码。在软件部分,你将编写一个编译器,将作者开发的一个名为Jack的高级语言编译为可以运行在虚拟机上的字节码,然后进一步翻译为汇编代码。你还将开发一个简易的 OS,让你的计算机支持输入输出图形界面。至此,你可以用 Jack 开发一个俄罗斯方块的小游戏,将它编译为汇编代码,运行在你用与非门搭建出的 CPU 上,通过你开发的 OS 进行交互。学完这门课程,你将对整个计算机的体系结构有一个全局且深刻的理解,对于你后续课程的学习有着莫大的帮助。
你也许会担心课程会不会很难,但这门课面向的人群是完全没有计算机基础的人,课程作者的目标是让高中生都能理解。因此,只要你按部就班跟着课程规划走,一个月内学完应该绰绰有余。麻雀虽小但是五脏俱全,这门课很好地提取出了计算机的本质,而不过多地陷于现代计算机为了性能而设计出的众多复杂细节。让学习者能在轻松愉快的学习体验中感受计算机的优雅与神奇。
@PKUFlyingPig 在学习这门课中用到的所有资源和作业实现都汇总在 PKUFlyingPig/NandToTetris - GitHub 中。
从最初的想法开始,到断断续续完成这本书,再到树洞的热烈反响,我很激动,但也五味杂陈。原来在北大这个园子里,也有那么多人,对自己的本科生涯并不满意。而这里,可是囊括了中国非常优秀的一帮年轻人。所以问题出在哪里?我不知道。
我只是个籍籍无名的本科生呀,只是一个单纯的求学者,我的目标只是想快乐地、自由地、高质量地掌握那些专业知识,我想,正在看这本书的大多数本科生也是如此,谁想付出时间但却收效甚微呢?又是谁迫使大家带着痛苦去应付呢?我不知道。
我写这本书绝不是为了鼓励大家翘课自学,试问谁不想在课堂上和那么多优秀的同学济济一堂,热烈讨论呢?谁不想遇到问题直接找老师答疑解惑呢?谁不想辛苦学习的成果可以直接化作学校承认的学分绩点呢?可如果一个兢兢业业、按时到堂的学生收获的却是痛苦,而那个一学期只有考试会出席的学生却学得自得其乐,这公平吗?我不知道。
我只是不甘,不甘心这些通过高考战胜无数人进入高校的学子本可以收获一个更快乐的本科生涯,但现实却留给了他们遗憾。我反问自己,本科教育究竟应该带给我们什么呢?是学完所有这些课程吗?倒也未必,它也许只适合我这种nerd。但我觉得,本科教育至少得展现它应有的诚意,一种分享知识的诚意,一种以人为本的诚意,一种注重学生体验的诚意。它至少不应该是一种恶意,一种拼比知识的恶意,一种胜者为王的恶意,一种让人学无所得的恶意。但这一切能改变吗?我不知道。
我只知道我做了应该做的事情,学生们会用脚投票,树洞的关注量和回帖数证明了这样一份资料是有价值的,也道出了国内CS本科教育和国外的差距。也许这样的改变是微乎其微的,但别忘了我只是一个籍籍无名的本科生,是北大信科一千多名本科生中的普通一员,是中国几百万在读本科生中的一分子,如果有更多的人站出来,每个人做一点点,也许是分享一个帖子,也许是当一门课的助教,也许是精心设计一门课的lab,更或许是将来获得教职之后开设一门高质量的课程,出版一本经典的教材。本科教育真的有什么技术壁垒吗?我看未必,教育靠的是诚意,靠的是育人之心。
今天是2021年12月12日,我期待在不久的将来这个帖子会被遗忘,大家可以满心欢喜地选着自己培养方案上的课程,做着学校自行设计的各类编程实验,课堂没有签到也能济济一堂,学生踊跃地发言互动,大家的收获可以和努力成正比,那些曾经的遗憾和痛苦可以永远成为历史。我真的很期待那一天,真的真的真的很期待。
PKUFlyingPig
2021年12月12日写于燕园
从最初的想法开始,到断断续续完成这本书,再到树洞的热烈反响,我很激动,但也五味杂陈。原来在北大这个园子里,也有那么多人,对自己的本科生涯并不满意。而这里,可是囊括了中国非常优秀的一帮年轻人。所以问题出在哪里?我不知道。
我只是个籍籍无名的本科生呀,只是一个单纯的求学者,我的目标只是想快乐地、自由地、高质量地掌握那些专业知识,我想,正在看这本书的大多数本科生也是如此,谁想付出时间但却收效甚微呢?又是谁迫使大家带着痛苦去应付呢?我不知道。
我写这本书绝不是为了鼓励大家翘课自学,试问谁不想在课堂上和那么多优秀的同学济济一堂,热烈讨论呢?谁不想遇到问题直接找老师答疑解惑呢?谁不想辛苦学习的成果可以直接化作学校承认的学分绩点呢?可如果一个兢兢业业、按时到堂的学生收获的却是痛苦,而那个一学期只有考试会出席的学生却学得自得其乐,这公平吗?我不知道。
我只是不甘,不甘心这些通过高考战胜无数人进入高校的学子本可以收获一个更快乐的本科生涯,但现实却留给了他们遗憾。我反问自己,本科教育究竟应该带给我们什么呢?是学完所有这些课程吗?倒也未必,它也许只适合我这种nerd。但我觉得,本科教育至少得展现它应有的诚意,一种分享知识的诚意,一种以人为本的诚意,一种注重学生体验的诚意。它至少不应该是一种恶意,一种拼比知识的恶意,一种胜者为王的恶意,一种让人学无所得的恶意。但这一切能改变吗?我不知道。
我只知道我做了应该做的事情,学生们会用脚投票,树洞的关注量和回帖数证明了这样一份资料是有价值的,也道出了国内CS本科教育和国外的差距。也许这样的改变是微乎其微的,但别忘了我只是一个籍籍无名的本科生,是北大信科一千多名本科生中的普通一员,是中国几百万在读本科生中的一分子,如果有更多的人站出来,每个人做一点点,也许是分享一个帖子,也许是当一门课的助教,也许是精心设计一门课的lab,更或许是将来获得教职之后开设一门高质量的课程,出版一本经典的教材。本科教育真的有什么技术壁垒吗?我看未必,教育靠的是诚意,靠的是育人之心。
今天是2021年12月12日,我期待在不久的将来这个帖子会被遗忘,大家可以满心欢喜地选着自己培养方案上的课程,做着学校自行设计的各类编程实验,课堂没有签到也能济济一堂,学生踊跃地发言互动,大家的收获可以和努力成正比,那些曾经的遗憾和痛苦可以永远成为历史。我真的很期待那一天,真的真的真的很期待。
PKUFlyingPig
2021年12月12日写于燕园
under construction.