• Welcome to the world's largest Chinese hacker forum

    Welcome to the world's largest Chinese hacker forum, our forum registration is open! You can now register for technical communication with us, this is a free and open to the world of the BBS, we founded the purpose for the study of network security, please don't release business of black/grey, or on the BBS posts, to seek help hacker if violations, we will permanently frozen your IP and account, thank you for your cooperation. Hacker attack and defense cracking or network Security

    business please click here: Creation Security  From CNHACKTEAM

Recommended Posts

本文谈的是计算机专业学生如何自学专业课。从长远来看,意味着如何借助网络上已经有的优质学习资源(主要是公开课),系统地点亮自己的CS技能树。本文是自学指南。你需要对编程充满热情,或者至少觉得编程是一种乐趣。兴趣是大前提,后面讲解的很多知识都比较“硬核”。只有保持热情,才能咀嚼。

写作背景

这里有一个很短的作文时间。如果不想看,可以利用博客的浮动目录功能跳转到“按主题讨论”这一章:

这篇文章最初是写给ACM培训团队的同学们的。刚开始觉得不太好,只在培训团队内部分享。后来发现虽然是篇烂文章,但多多少少帮了几个人,觉得还是有价值的,就干脆扔博客上了。- 2022.4.30

最近有几个ACM老队友感叹,大一大二的时候大部分精力都放在算法和数据结构的练习上,而且由于学校课程缺乏深度、实践性和趣味性,没有打开专业技能,对操作系统原理、计算机网络、数据库原理等专业科目了解不够。

但这些东西都是技术债,迟早要还的。实习前我以为有些知识是造火箭的屠龙术。实习结束后发现,如果只是为了谋生,确实是屠龙术。然而,稍微深入一点的工作将不可避免地涉及到处理这些知识。实习的时候,我被一致性哈希、单节点崩溃这种东西搞得晕头转向。实习结束后,我发现这些东西在分布式系统课程中都有详细的讨论。在另一次采访中,有人问我是否见过Linux源代码中TCP的RTT是如何计算的。我当时很震惊,但完全没想到会问到这个深度。后来才知道对方是做用户态网络协议栈的,问的都是自己真正需要的知识。

如果大学真的有四年,那两年打ACM,两年赶专业课,还是挺合理的。但是,实际时间和预想的不太一样。大三下学期开学,求职者要做好面试准备,考研者要集中精力复习。可自由支配的时间一下子就会少很多,很难抽出大段大段的时间来填补这个知识空洞。当你找到一份好工作或者考完试,你突然有了很多空闲时间。虽然这个时候回学校也可以,但是总有点亡羊补牢的感觉。

这种现象在很多大学都存在,是一个普遍性的问题。你可以说这背后的原因是教育资源分配不均,高校教师的评价体系重科研轻教学。但这些问题短期内无法根本改变,短期目标还是先实现自救,提升自己的专业水平。

但至于怎么做,还是没有太多前辈的经验可供参考。两年前,我和我的ACM队友讨论:“为什么我们学校刚成立一年的ACM队和其他学校成立多年的队差距这么大?“当时讨论的结果是‘沉淀’差,但沉淀是虚幻的,谁也说不清到底是什么。找工作的时候才知道,所谓的沉淀,是几代前辈用自己的血泪填的坑。有的坑是前人填的,可以踩着尸体走;有些坑是前人没有填好的,你只能跳进去当垫脚石,让后人不要重蹈覆辙。

世界上只有坑,掉进去的人多了,就变成了路。

3354,我说的

主要思路

这年头网上不缺各种学习资料,问题是选择太多,糟粕太多。本文是根据一套思路和我自己的学习经验来筛选出一些计算机基础课程的学习资料。

筛选数据时的主要考虑因素是:

1)保证真实性:除了少数特别注明的资料,所有的资料都是我自己学习经验整理出来的,也就是我实际学习过一次的所有资料,学习顺序基本一致。但由于个人基础不同,这些资料不一定适合每一个读者。

2)实践驱动:自学者能否遵循“理论 = 实践 = 总结”的循环,通过写玩具项目、做实验室来加深对知识的理解?

理论:字面上学习理论知识。主要考虑这门课的材料对自学者来说是否通俗易懂。

练习:重点是编码测试。这也是很多学校在教授操作系统等课程时忽略的一个环节。计算机科学是一个应用性很强的领域,我们应该挖掘更多的代码来加深对理论的理解。所以优先考虑那些带lab(编程实验)的学习资料。测试数据也很重要。自学没有老师批作业,你至少要找一些“参考答案”,直到你对知识的理解不正确。

总结:知识的沉淀,说白了就是记笔记。人脑是不可靠的。有些问题学了几个月就记住了,一两年就忘了。你可以在我的博客里看到ucore和chcore关于操作系统的笔记。这两个音符相隔一年。就是因为高二第一次学操作系统的时候觉得自己记性很好,所以也就轻描淡写的记住了。一年后,我发现很多重要的问题都没有详细记录,于是我又煞费苦心地学了一遍。你点开几篇文章也能看出两个笔记的质量差别很大。

3)实用性:考虑到有些读者这篇文章可能已经学了一大半,大三三四月份要准备春招实习季,所以优先考虑那些可以把Lab作为简历上一项的高难度课程。既满足了找工作的需要,又是自己学习成果的体现,一举两得。

其他前几门课基本都是中文,越往后越往后。

文比例会越高,主要是英文水平提升后敢去尝试些没有汉化的前沿玩意儿了。如果你已经有阅读大部头英文原著的能力的话那么 这篇文章 里的学习路线可能更适合你 。

碎碎念:这篇文章没有写完,在这贴个永久链接,不至于被爬虫爬了后找不到原文 https://www.cnblogs.com/kangyupl/p/cs-stack-self-study-guide.html

分科目讨论

构建知识库

还是说一说记笔记这个事儿。记笔记的主要目的有二:

1)第二次遇到同样的问题能快速运用已有经验解决掉。小的比如某个程序要怎么配置,大的比如“进程的 CPU 占用率突增该怎么分析?”。这些东西虽然网上慢慢搜也能搜到,但还是不如翻自己的笔记来的快。不一定要自己从头手写一遍,收藏下前人写的博客链接也是一种记笔记的方法,重点是能不能快速翻阅知识库找到解决同样的问题的方法。

2)用来审视自己的知识体系,知道自己哪块儿薄弱。知识体系的构建是一个滚雪球的过程,最开始记笔记时只是零零散散的几篇,后来记得多了就开始分类摆放,慢慢的就有了一个体系的样子。

具体用什么工具记录完全看个人,喜欢搭博客就用博客记,追求方便可以用各种商业云笔记软件。我自己的考量是纯 markdown 方便迁移、云端本地双备份(断网也能看)、手机上也能看,所以在本地创建了一堆 markdown 文件,写的话就用 Typora,云端备份坚果云。

如果你想要画几个技术文章里那种常见的流程图或者程序框图,我推荐使用 draw.io。既有网页版也有桌面版。

程序设计语言 & 数据结构

开头说了本文并不是完全面向小白的指南,所以这里只提一下想要按我这个学习路子走的话你目前应该有的水平:

会用一点 C 语言 + STL,然后浏览一下《C++ primer plus》学学 C++ 面向对象的语法(会继承,会用 RAII 管理内存),目前当成一本字典过一遍,后面用到知道去翻哪部分就行。

数据结构的能力也不好界定,我只是举个例子:能对着最小堆的百科一个小时复现一个出来就足够了。可以随机生成些数据和 C++ 的优先队列比较比较,结果相同就算是复现成功了。

这里我也给不了什么学习经验,我是在打 ACM 的过程中积累数据结构基础的,入门用的《算法竞赛入门经典》,对于不打算参加算法竞赛的人来说单纯为了学习数据结构看这本书是很划不来的。

基础工具

如果你已经有了一定的 Linux 和 git 使用经验,可以直接跳过这一部分内容。

不管是平常逛知乎还是逛 github,你基本上可以发现似乎是个程序员就会用 Linux 和 git。这属于那种早晚得学,但并没有专门的一门课讲的知识,运气好的可能在老师讲操作系统课时教一下,运气差的可能大四毕业也没碰过(我们专业就是后者)。所以在这里我要提一下,如果你没接触过的话那就先去把这两样工具给学了。

因为都是工具,没什么艰深的理论,跟着视频或者书籍敲一遍基本就能学会。B 站上这类“Linux 教程”或者“git 教程”一抓一大把,挑自己看得进去的跟着学就行,要有选择困难症的话可以用我下面推荐的(并不是最好的,只是我当时入门用过的)

Linux 基础操作

参考耗时:10h+

前置技能:无

个人推荐 蓝桥云课的 Linux 在线实验课。

学习的重点就是关注各种命令的用法,目前不需要研究 Linux 的运行原理,知道怎么打开目录、怎么复制移动重命名文件、怎么压缩解压、怎么用 vi 或者 Nano 编辑文件(查找复制剪切粘贴保存退出就够用了,不需要记太多命令)就差不多够用了。其他的命令用到了再去重学,一口气全学完了反而容易忘。

此外还需要学着在 VMware 或 VirtualBox 上手动安装一个 Linux 发行版,推荐装最新版的 Ubuntu,主要好处是用的人多,参考资料网上一抓一大把。(你应该会用 B 站搜索“VMware 安装 Ubuntu”之类的问题吧?)有台虚拟机这步是必须的,后面学习组成原理、计网的代码都只能在 Linux 上跑。当然如果你有能力在实体机上装 Linux 或者在 Windows 里装 WSL 都可以。

git 基础操作

参考耗时:< 10h

前置技能:无

个人推荐 廖雪峰老师的 git 教程。

学会怎么在 github 上创建仓库,怎么 push、pull、add、commit、创建切换合并分支基本就够了。

汇编语言

参考耗时: 10h+

前置技能:C 语言

我们编译好的程序都是以二进制机器码形式在操作系统上跑的,而与机器码最接近的就是汇编语言了。

所以要理解操作系统首先要理解汇编,我个人推荐直接 10 ~ 20 个小时啃完王爽写的《汇编语言》。每章节结尾有一道比较大的编程题,下载一个 emu8086 就可以愉快的编写和运行汇编代码了。

注意把每章的大编程写一遍这一步可不是建议,而是为了后面能理解操作系统内核源码和理解 CPU 里怎么运行机器码所必须的一步。

操作系统

参考耗时: 100h+

前置技能:汇编语言、C 语言、Linux 常用命令

注意:我个人是先学的操作系统再学的组成原理,但现在回想似乎当年学操作系统学的不是很顺利。如果读者按我这个顺序来学也觉得力不从心可以先去学学组成原理

学习操作系统解决的最大问题是“理解程序是怎么在计算机上运行的”。很多的计算机问题最终都会指向操作系统中,比如 “CPU 占用率 100% 为什么会卡?”, “malloc 是怎么分配内存的?”,“任务管理器里的进程是什么意思?”,“为什么 C 语言函数里面不能定义大数组的局部变量?”,“我的程序可以修改其他程序的内存吗?”,“多线程是怎么实现的?”。这些东西认真学完操作系统后基本都可以搞明白。

我个人推荐清华大学陈渝老师的开源的教学级操作系统 ucore。

理由一是陈渝老师录的公开课通俗易懂,我们这些普通学生也能轻松的看明白。

理由二 ucore 本身就是为了教学研发的,所以源代码写的对初学者比较友好,并且能够在 Linux 下编译并在 qemu 模拟器上运行,能切实看到自己写的操作系统跑起来所带来的反馈感是非常强烈的。

主要方法的学习方法就是:看公开课 => 跟着实验指导书完成对应 lab => 输出笔记。记笔记这点很重要,我亲身感受是看某个软件系统的源码这种事情,你不做笔记的话两三个月就忘光光了。总的来讲看内核源码的过程还是挺困难的,但同时也是有一种攻克难关的乐趣存在的。就种打《黑暗之魂》的感觉,读一小段代码就卡住了,回头翻一翻实验指导书、看一看课程视频,又突然觉得自己醍醐灌顶了。整个学习过程就是不断地“卡壳->回头思考下->豁然开朗”不断的循环。

公开课的视频,注册一下就能看了

官方的实验指导书,在线版的。在 Lab0 章节里提供了一个 VirtualBox 下的 Linux 实验镜像,可以省下安装各种依赖的力气了。

实验指导书的 github 仓库,需要离线版本的实验指导书的话就 clone 到本地,然后研究下搜索下怎么本地部署 gitbook 就能阅读了。

ucore 的源代码,master 分支下才是 C 语言的本体,clone 下来记得切一下

参考的教材,这个东西陈老师在公开课第一章里提到过,有需要可以去翻一翻。

更进阶的可以去阅读《深入理解 Linux 内核》,对哪块儿感兴趣就学习哪块儿。

组成原理

参考耗时: 100h+

前置技能:汇编语言、Linux 常用命令

我个人认为学习组成原理的主要目标是要搞明白 CPU 内部是怎么工作的,并能够针对现代 CPU 的 TLB、多级缓存、内存屏障等特性写出更优良的代码。

我个人推荐《深入理解计算机系统》(国内俗称 CSAPP)这本书。原教旨派认为的学习组成原理应该以实现简单的多级流水线 CPU 为目标,这跟我的着重点是不太相同的,我更关心说程序员可以根据哪些编程的原则来更好的利用 CPU 的特性,而 CSAPP 做到了,它真的是在认真教你怎么榨取 CPU 性能、怎么对自己的程序做优化,而且还出了好几个 LAB 专门考察你的理解够不够深刻。

读完它的前九章就差不多了,其他章节在操作系统课和计算机网络课里会更详细的学习,但如果想更轻松上手这两门课络也可以先读一下。也不需要死板的啃一遍,遇到不感兴趣的地方可以跳过,比如我觉得第二章手推浮点数的二进制表达那一堆计算题挺无聊的,所以只是写了点代码实现了字面上的小数和浮点数间的互转算法就掠过了。

书的作者开过 CMU 15213 这门课, B 站上有人给全汉化了,有需求可以去看看。

配套 lab 也是公开在网上的。注意每个实验的源码在压缩包里,参考文档在 writeup 里。

书里面的习题可以不做,但 lab 是必做的,因为它的设计确实巧妙。比如 Bomb Lab 直接扔给你一个可执行文件让你通过反汇编来 hack 掉它,比如 Performance Lab 里教你怎么运用 CPU 指令并行和 cache 来把程序的运行速度提高几十倍,这是别的课程里从未见过的奇妙体验。在攻略 CSAPP 的 lab 的过程中可以学到的知识包括 gdb 调试、分析程序反汇编码、CPU 级的性能优化方法,再加上一点点的 Linux 系统编程。

进阶:实现一个 CPU

参考耗时:10h+

前置技能:无(只是看下面这本书的话,你甚至可以不懂组成原理)

如果你想要想要更近一步实现一个 CPU 玩玩的话也有相关资料:

图一乐级别的参考书是《计算机系统要素-从零开始构建现代计算机》。它会教你用硬件编程语言 HCL 实现一个没有分支预测、没有流水线的极简化的 CPU。

配套源码

配套实验手册,分章节的

当然这个 CPU 只是图一乐的产物,甚至不及部分学校期末课设的难度。想要更进一步请自行上网搜索自制 CPU 相关资料。(我的待读列表里有本《自己动手写CPU》,不过我还没仔细看,这里只是提一嘴有兴趣的可以去看看)

网络

参考耗时:40h+

前置技能:无

学习计算机网络是为了......在座的应该没有不上网的人吧?那行了,这年头是个程序员都得懂点网络编程,所以学吧。

国内虽然有些计网的公开课讲的比较通俗,但动手的练习太少了。重点是要写点代码做做实验,只是几道填空计算题并不能算是有效的练习。我个人推荐阅读《计算机网络:自顶向下方法》这本书。

理由一网络栈分好几层,市面上很多教材都从硬件往应用的层次来讲的,一上来就搞得比较枯燥。从应用层开讲的话更容易理解。

理由二它的配套实验还是比较多的,有的会让你去模拟一下网络协议里的部分算法,有的需要抓包来切实的研究下数据在网络中传输的模样。

要更加深入理解计算机网络的话我个人去实现点小项目,比如写个 HTTP 服务器或者写个 TCP 协议原型。

进阶一:实现一个 HTTP 服务器

参考耗时:50h+

前置技能:C++、操作系统原理、计算机网络、简单的 Linux 系统编程(把 CSAPP 里的 shell lab 做完就行)

我个人推荐书籍是《Linux 高性能服务器编程》,游双老师写的。它会同时教你 Linux 编程、计算机网络、多线程编程多个方面的知识。书籍的章节分的也很不错,循序渐进的从连接的建立,到请求的解析,到线程池的维护,到使用多路复用技术维护多个连接,最后把这些模块组装起来得到一个 HTTP 服务器。

进阶二:实现一个 TCP 协议原型

参考耗时:50h+

前置技能:C++、理解 TCP 协议、简单的 Linux 系统编程

这方面主要是斯坦福的 CS 144 这门课,它以实验驱动的方式教你怎么实现一个 TCP 协议原型。

视频的话,我并没有看 CS 144 的官方录屏,也没感觉说做 Lab 有啥影响。做之前把《计算机网络:自定向下方法》里关于 TCP 的章节通读一遍,并在做 Lab4 前重点搞明白 《Linux 高性能服务器编程》里 TCP 的各个状态间是怎么转移,然后开撸就行。

数据库

SQL 基本操作

参考耗时:< 10h

前置技能:无

首先要对数据库的功能有个基本的认知,本着实践导向的原则,我推荐在 Linux 里装个 MySQL,然后跟着《MySQL 必知必会》把指令都敲一敲,增删改查交并补这些基本操作都学会了就行。

MySQL 原理

参考耗时:20h+

前置技能:SQL 基础操作

学会 SQL 的基本操作后可以去读一读 《MySQL 技术内幕 : InnoDB 存储引擎》,了解下 MySQL 里一些功能是怎么实现的。

看不下去也可以先去看后面的 CMU 15445,后者注重数据库原理学术界的一些做法,前者则是具体拿了数据库来分析,两者间互为补充。我先看的 CMU 15445,那时候虽然懂 SQL 怎么用,看是能看懂,但没什么太深感受。看完 InnoDB 后再看感觉就完全不同了,因为 CMU 15445 里讲的聚簇索引、缓冲池等等正式 InnoDB 实际用到的东西 ,再看 CMU 15445 就能理解 InnoDB 里有些地方为什么这么设计,有哪些权衡,其他的数据库权衡后又怎么设计,有了一种豁然开朗的快感。

数据库系统

参考耗时:100h+

前置技能:操作系统、MySQL 原理(推荐、非必须)

推荐学习资料为 CMU 15445 ,2021 版的没有汉化,不过经过前面几门课磨练后应该具备一定英文水平了,开着 AI 字幕看也不是特别困难。

这门课的老师 Andy 功力深厚,回答学生问题、课堂举例子都各种旁征博引。配套 project 也非常给力,会教你自底向上搭建一个简单的硬盘型数据库。

参考教材是 《数据库系统概念》,CMU 15445 的官网上有个 schedule 写了每节课对应的教材章节。

project 里会用到简单的 C++ 多线程编程知识,需要补充这部分短板可以去看网友翻译的《C++ 并发编程实战》,里面有一章会教你怎么设计并发安全的数据结构。

未完待续,有生之年有空再写

其他资源

最近网上冲浪也发现了几个其他网站也有专门的 CS 自学 Roadmap,感觉质量更上一层,直接贴在这里了。

TeachYourselfCS

CSDIY WIKI

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now