双非计科自学指南

双非计科自学指南

全文导引

  • 双非计科自学指南
    • 写在前面
      • 为什么要写此文
      • 此文适合谁
      • 此文怎么读
    • 0 进入计算机世界之前
      • 0.2 使用计算机的基本能力
      • 0.3 英语能力
      • 0.4 你能争取的权益
    • 1 基本编程能力
      • 1.1 C 语言
        • 1.1.1 基础学习
        • 1.1.1 Plus 编程环境
        • 1.1.2 进阶
    • 2 进阶编程能力
      • 2.1 C++
        • 2.1.1 基础知识
        • 2.1.2 进阶
      • 2.2 SQL
      • 2.3 Java
      • 2.4 Python
    • 3 专业基础
      • 3.1 数据结构&算法
        • 3.1.1 数据结构基础
        • 3.1.2 算法知识进阶
      • 3.2 计算机系统基础
        • 3.2.1 基础部分
        • 3.2.2 进阶部分
      • 3.3 计算机 络
        • 计算机 络基础
        • 计算机 络进阶
      • 3.4 操作系统
        • 计算机基础
        • 进阶
    • 4 专业进阶
      • 4.1 人工智能
        • 4.1.1 初步
        • 4.1.2 进阶
      • 4.2 计算机系统
        • 4.1.2 初步
        • 4.2.2 进阶
    • 5 缺失的 N 课
      • 5.1 开发环境迁移到 Linux
      • 5.2 Git/Github
      • 5.3 Markdown
      • 5.4 程序语言理论(初步)
    • 后话

写在前面

为什么要写此文

络上的计算机学习指导已经非常多,不能抛砖引玉,为什么还要狗尾续貂/p>

必须承认的是, 络上的 CS 指南通常标准较高,且难度偏大,不适合很多双非本同学的现实状况。

我们不妨将双非计科学生的总体状态总结如下:

  1. 基础知识有限:进入大学前没有接触过计算机
  2. 学习、自控能力有限:对于大多数人而言,高考都在很大程度上说明了自身的学习和自律能力
  3. 英语能力有限:优先推荐中文原生课程,其次是有较高质量的中文翻译,尽量避免全英文课程
  4. 学校能提供的资源有限:很少能接触到前沿的课题、高质量的课程和配套实现。

因此此文的构想也遵循如下原则:

  1. 从最基础的开始
  2. 难度不宜过大,主要目标是不和真正受到良好计算机教育的同学拉开差距

此文适合谁

此文怎么读

0 进入计算机世界之前

在最开始我不会推荐你去阅读专业的书籍,事实上,最应当做的事情是对计算机科学有一个整体的概念:计算机科学到底在研究一些什么样的问题/p>

通过互联 上的各种论坛和自媒体平台,我们能够接受到海量的信息。

0.2 使用计算机的基本能力

所谓能力,包括但不仅限于

  • 使用体验的提升,如打字、快捷键
  • 软件的安装,配置
  • 简单软硬件故障的排查和排除,基本的保养和维护知识
  • 如何稳定的使用某些连接不稳定的 站(包括但不仅限于 GitHub,Stack OverFlow,Google,zlibrary 等)

虽然我们总调侃:“我们是学计算机的,不是学修计算机的”

但必须认识到的是,计算机是计算机从业者日夜相伴的工具,是“用来吃饭的家伙”。在未来的使用过程中,不可能让一点点微小的故障或问题影响工作的进程,因此使用计算机的基本能力是必须的。或者说,懂(消费级)计算机的不一定都是程序员,但真正的程序员一定对此有一定程度的了解。

0.3 英语能力

所谓“日拱一卒,功不唐捐”。英语的学习最在乎坚持。其实做到读懂文章和简单的听说并不困难,坚持即可建功:

  • 使用一个记忆英语词汇的 APP,如“墨墨记单词”,每日新增+复习定一个数量,时间控制在 30 min以内(我设置的数量是300),坚持半年左右在阅读能力上就能大有改观
  • 哪怕是看的半懂不懂,也请坚持看下去。另外选择文本的时候尽量选择原生的英文文本。

0.4 你能争取的权益

此处的合理权益包括但不只限于:

  • 教育邮箱:可以用于购买电子产品享受折扣(如 Apple 和 Microsoft 的教育优惠),获得教育版软件的使用权限等等

某年学校请来了一位培训机构的讲师讲授 Java 微服务相关内容,第一堂课几乎全花在了如何破解 IntelliJ IDEA,尚且不论破解是否合乎道德、IntelliJ IDEA 本身就有免费的 区版这两件事,学校其实提供有教育邮箱可以在 Jetbrains 官 申请 免费的教育版(完整版)licenses。然而很多人直到毕业都不知道教育邮箱如何登录、有何用处。

  • 开放课程:越来越多的老师选择公开自己的课程讲义、课题教学录像、配套练习等内容。虽然理论上所有人都可以参与相关课程,但你的学生身份或许能让你有如使用 OJ 等额外的权益
  • 规避糟糕的课程:学校里少不了已经安排的质量低下的课程,如何辨别那些糟糕的课程,并在止损的同时还拿到这些课程的学分甚至高绩点。

1 基本编程能力

1.1 C 语言

1.1.1 基础学习

尽管互联 上很多人希望将 Python 作为入门的编程语言,但考虑到教学的实际情况,我们还是认为 C 语言是大多数双非同学的入门编程语言。

事实上,即便是考虑到:

  1. 很多院校使用恶名昭彰的“谭浩强 C语言教材”,即 《C程序设计-第五版》
  2. “念 PPT”的教学方式

C 语言入门在大多数的双非院校仍然算不上困难,原因如下:

  1. 内容少。很多学校只会讲到指针为止,并不会涉及 ,库和预处理指令等内容。

因此个人并不会为 C 语言课程推荐太多的书籍和课程

以被广泛推荐的 C primer plus 为例,其第十章“指针和数组”结束仅仅是第 317 页,不到全书 726 页的一半。而刚入门的新人又是很难在一学期内接受整本书的内容的。

学好 C 语言只需要在对应章节做一定量的编程练习即可

1.1.1 Plus 编程环境

你的 C 语言老师大概率会要求使用 VC++6.0 这一上古时代的编程环境,其古老的字体和界面风格仿佛让你的 PC 回到恐龙时代。

其实也有“自带编译器”的解决方案:建议使用 DEV C++ 或者 CodeBlocks,他们都拥有相对现代化的智能提示和

1.1.2 进阶

虽然第一学期只会接触到 C 语言的下列知识

  • 控制语句,包括判断、循环、基本输入输出
  • 数组
  • 指针

但我仍建议在 C 语言课程结束、接触数据结构等进阶课程之前补充学习下面的内容:

  • 结构:可以将 视为面向对象思想的第一步,事实上它在 C语言中被广泛的使用
  • 断言:也许在简单的课堂环境和作业中用不到 ,但它可以帮助你写出真正规范且标准的 C 程序
  • 和 :也许暂时还不能理解他们的原理和用处,但在数据结构的 C语言实现中也将反复的遇到它们,所以务必通过练习了解他们的用法,

此部分内容可以参考 C primer plus 的第 14 和 15章

C 语言的使用技巧远远不止于此,但是往往需要结合具体的使用场景,此处不再赘述。

2 进阶编程能力

2.1.1 是必须具备的能力,其他小节则按需取舍。但除 2.1.2 有一定难度之外,其他小节内容依然建议都进行学习。

2.1 C++

2.1.1 基础知识

C++ Primer 无疑是经典之作,但如前文所述,初学者很容易陷入 C++ 过多的细节当中

《C++程序设计——基础、编程抽象与算法策略》是斯坦福大学 CS 106B对应的教材,因此可以考虑跟随本书学习 CS106B 的课程并完成习题。此外本书关于“算法策略”部分的补充(包括树、图、哈希、回溯、递归)等数据结构和算法策略的描述也是后续数据结构课程很好的补充(毕竟很多数据结构教材的示例代码都烂到无以复加)。初学 C++ 者可以跳过数据结构相关的 7,8,9,10,15,16,17,18 章。

2.1.2 进阶

《C++程序设计——基础、编程抽象与算法策略》一书最大的缺点在于,其本质上仍然只是教授了一个“带类简单模板和少量 STL 的 C 语言”,但事实上,如 和 带来的类型推导能力,或者 , 和 带来的智能指针,或者 STL 的广泛使用,或者元编程思想的引入,都是所谓现代 C++ 不可缺少的特性,并且事实上已经广泛的引入到实际的开发当中。
如果有进阶 C++ 的实际需求(例如选择了高性能计算、图形学作为继续前进的方向),那么个人认为 C++ Primer 仍然是绕不过去的坎。

C++ Primer 之后,个人并不建议立刻上手如 effective C++ 之类偏向于“C++设计哲学”的书籍,而是先试着追赶现代 C++ 跃进的步伐,可以参考开源书籍 《现代 C++ 教程:高速上手 C++11/14/17/20》,两百多页的篇幅尽可能简明的介绍了现代 C++ 的诸多特性。

effective C++effective modern C++ 等等都是优秀的参考书籍,但如前文所述其更倾向于“C++ 编程哲学“,在编码量有限的情况下阅读是很难有所收获的

2.2 SQL

数据库的结构化查询语句应当是每个计算机专业学子必备的技能之一。

书籍推荐 《SQL必知必会》,推荐使用 Jetbrains 家的 DataGrip 进行练习,可以直接在 Markdown 笔记中执行 SQL 过程,图形化界面也能帮助初学者在误操作或者难以理解的问题上快速回到正轨。

不同于其他课程,不推荐 SQL 初学者看太多理论性课程或理论性教材。理论性的教材会在关系代数等等内容上花费非常多的实践,但事实上如果不从事数据库相关的深入工作,学习相关知识的将是收益非常低的。

2.3 Java

从我的专业方向也能看出,我也仅仅是 Java 新手,只能给出一点入门级别的建议。

《Java 疯狂讲义》 足够详细,但是细节太多

基于 Java5 的 《Java 编程思想》 首版于 2007 年,对于标准和特性日新月异的 Java 而言,是时候把它丢进故纸堆了

《Java 核心技术》秉承了外国教材由浅入深的风格,但是对于已经有一门编程经验的学习者而言废话太多。此外,本书翻译质量堪忧。

2.4 Python

问题求解的 Python 实现往往是相对简洁的存在。Python 入门推荐 《笨办法学 Python 3》(如果觉得本书的面向对象编程部分不够清晰,可以补充 《Python 编程——从入门到实践》 的相关章节。

3 专业基础

此节仅列出个人认为必须学习或了解的相关内容。可选部分参考第 4 节

基础部分需要不折不扣的完成,进阶部分则可以量力而行

3.1 数据结构&算法

3.1.1 数据结构基础

非常奇怪的是,数据结构作为一门基础课程,其相关书籍却堪称贫乏。

幸运的是,其性质和 C 语言类似,基础数据结构知识的难度不高(我们不妨将红黑树等视作相对高级的数据结构),但是需要一定的编程实践才能真正掌握。

推荐的来自thu邓俊辉老师的 《数据结构(C++语言版·第3版)》,一本少见的高分国产教材,并且有配套的 MOOC 。

需要补充的一点是,学 基础数据结构的关键仍然在于编程训练,以链表为例,不仅仅是完成LeetCode 风格的算法实现链表的遍历、查找、反转等,最好是能将建表、删除表等基础算法都自行完成实现和封装。

3.1.2 算法知识进阶

在 B 站有中国科学院计算技术研究所的卜东波研究员在国科大讲授 计算机算法设计与分析 课程的全程视频,事实上也有一本自编成书但尚未公开出版的讲义,需要的可以自行搜索相关内容。

3.2 计算机系统基础

3.2.1 基础部分

传统上来说,计算机系统基础应该被称为计算机组成原理,此外还包括数字电路、体系结构的一部分内容。学习完相关内容,应该具备开发一个单发射多级 CPU 的能力。

但是相关的课程和配套软硬件实验需要大量的时间、充分的指导(助教课程,线上QA,office hour)、相互呼应的课程安排(比如像 nju 一样设置整体性的计算机系统基础课程,或者设定 数电(verilog) -> 汇编->计算机组成原理这样相互呼应的课程安排)、完备的基础设施(如实验指导书、编程模板、环境开发)

根据个人的学习经验,对于双非本的同学们而言,没有来自学校的支持和配合,单打独斗很难完成系统的学习。

所以我们不得不适当的降低要求:我们的目的不再是具有设计计算机系统的基本能力,而是构建一个计算机系统的完整理解。此处需要请出绝对的神级教材 《深入理解计算机系统》(英文名称 Computer Systems: A Programmer’s Perspective,以下简称为 CSAPP)。

CSAPP 对 CPU 运算、内存工作原理、与操作系统的结合都有设计。而且鉴于其“APP”属性(英文名的后半部分,即 A Programmer’s Perspective),其主要描述都是基于程序员视角的 C 语言进行,不会设计过多的系统细节,是概览计算机系统的一大利器。

除开 4,10,11,12 章之外,其他小节尽量读明白

B 站上有UP 上传了 CMU 的 CSAPP 课堂视频,部分难以理解的地方可以参考。此外 UP 九曲阑干 使用 manim 制作的 CSAPP 导学视频也大有裨益。

3.2.2 进阶部分

所谓 talk is cheap,show me the code,如果能够真的搭建出一个堪用的系统,那么就真的是完成了进阶,此处推荐 nju 计算机系统基础的配套 实验课程。

这时候就会需要接触到具体的计算机实现,例如 《计算机组成与设计——软件硬件接口》 层次的内容,也可以参考胡伟武老师龙芯团队 《计算机体系结构基础》 相关内容,B 站也有胡伟武老师在国科大讲授计算机体系结构课程的 视频。

3.3 计算机 络

计算机 络基础

计算机 络课程知识点多且杂,且规则、标准非常之多,非常容易被上成一门背诵记忆型的课程。编程实践则非常考验 C/C++ 编程能力。

USTC 的计算机 络课程算是一个较好的均衡:在自顶向下一书的基础之上,尽可能的将考试内容和实际应用联系起来,访问 课程 站 可以得到课程相关资料和课程链接。

计算机 络进阶

如果有兴趣有能力继续在,可以尝试挑战 Stanford CS144,使用 C++ 实现整个 TCP/IP 协议栈。该课程已经有非常多的先行者,在 Github 和各大论坛 区都有大量经验可供参考。

3.4 操作系统

计算机基础

虽然 CSAPP 一书已经从程序员的视角俯瞰了包括操作系统在内的计算机系统的全貌,我仍然建议专门学习一下操作系统的相关内容。操作系统的设计不仅仅是一个工程问题,层次化、模块化的设计思路也将贯穿于整个计算机系统的发展当中。

上海交通大学 IPADS 组的 《现代操作系统:原理与实现》 已经出版、后半部分已经开源,

相比教材本身而言,该书在 B 站上的配套课程质量要差很多

课程方面更推荐南京大学计算机拔尖班的操作系统课程 操作系统设计与实现。通过大量的现场程序演示很好的结合了操作系统理论与实际。

必须承认课程配套的编程作业有一定难度,记得量力而行

课程配套的教材 《操作系统导论》 更倾向于演示和启发性的教学逻辑,而不是一本传统的操作系统教材,教材依然推荐 《现代操作系统:原理与实现》

进阶

参考 操作系统设计与实现 蒋炎岩老师的 个人主页 完成 OS 的相关练习,就已经拥有了非常不错的 OS 基础。

MIT 6.S081/6.828 也可以作为备选方案,相比 nju 课程,其开课时间更久远经验贴更多。

4 专业进阶

专业进阶部分会涉及更加深入的计算机知识,秉承负责的原则,只会介绍几个我个人曾经有相对深入了解的方向。

4.1 人工智能

4.1.1 初步

个人不赞同起手就是炼丹大法,但是作为初学者,深度学习不仅是最有效果,也是最可挖掘和深入的知识领域,因此第一阶段仍然推荐从深度学习开始,对于机器学习基础知识则是“先上车,再补票”

内容全面新颖且,李沐大神的 《动手深度学习》 无疑是入门最佳,提供 mxnet/tensorflow/pytorch 三种框架的实现。此外在李沐大佬也在他的 B站 更新了 《动手深度学习》 的对应课程(btw,每周的读论文等内容也非常值得学习)。

需要注意的是,《动手深度学习》 在知识讲解上算不上非常详细。因此更推荐的学习方法是以此书作为目录,寻找相关的课程进行学习,此后再基于书中的代码运行实践。

以下是我个人使用的部分内容对应的视频课程,这些课程通常都多达几十甚至数百小时,务必取其精华而用之,课程视频均来自 Blibili

  • 反向传播:Stanford CS231n
  • 注意力机制,Transformer,BERT:李宏毅机器学习
  • CNN 和 RNN:吴恩达深度学习课程

此外,在以下情况下,推荐 《深度学习入门——基于 Python 的理论与实践》一书

  • 运行 《动手深度学习》 存在困难
  • 感觉看不明白 《动手深度学习》 中的代码,或者自己难以写出类似的代码

如果你代码基础较差,使用鱼书(即 《深度学习入门——基于 Python 的理论与实践》)未尝不可,因为该书的代码实践仅仅基于 numpy 等基本库展开,可读性更佳

4.1.2 进阶

该补票了。也许近来深度学习的滚滚热潮让你感觉拥有了全世界,但是只有基础扎实才能行稳致远,而且在实际的生产应用中传统机器学习方法仍然在广泛的应用。

李航老师的 《统计学习方法》 无疑是个中翘楚,在数学意义上囊括了常见的机器学习算法。

可用的补充资料还包括:

  • 如果阅读期间存在数学理解上困难,可以参考 “机器学习白板推导” 系列视频

  • 如果感觉概念或者意义上难以理解,可以使用西瓜书即周志华老师的 《机器学习》 作为补充内容。机器学习的数学内容更少,讲解更偏向直观感受。配合开源的 “南瓜书” 可能才是完全体。B站 王木头学科学 的相关视频也可以作为参考

到这一步之后再继续前进的话,就会进入到读 Paper,做具体方向与课题的阶段。不过个人仍然推荐去对人工智能的发展脉络做一个基本的了解,当时是随便找了一本 《人工智能及其应用》 作为科普读物。此外 《哥德尔、艾舍尔、巴赫 : 集异璧之大成》 一书也可作为科普和消遣的读物。

4.2 计算机系统

偏向于 MLsys 方向

4.1.2 初步

系统方面的初步和进阶,并不像 4.1 的 AI 那样有明显的知识能力上的差距,因此基础部分个人会更倾向于 Coding 能力的夯实、计算机系统的深入理解。毕竟很多的 Paper 中很多地方的性能提升都来自 SIMD(单指令多数据流)实现,而不是文章提出的算法本身。

《UNIX环境高级编程》 可以作为参考。

在这个问题上,很多回答会推荐大名鼎鼎的 《计算机体系结构:量化研究方法》,在我看来给本科生推荐此书毫无疑问是一种不负责任的行为。按照计算所现在在国重的一个朋友的说法,真正能把量化读懂,那么你就具备了国内准一流体系结构低年级博士的水平。换句话说,本科生读懂量化一书是不现实的,推荐此书的人也很大概率没有真正读过/真正读懂过量化一书。

编程能力上,可以参考 B站教学视频 现代C++高性能编程实践 以及中山大学 C++实现高性能并行计算 的系列分享

OS_wiki 也提供了很多补充学习资料

4.2.2 进阶

来自计算所陈云霁研究员在国科大的课程:智能计算系统,聚焦于深度学习算子的实现、编程框架构建等内容

如果没有体系结构方面的基础,可以放弃 智能计算系统 中硬件设计部分的实验,但仍然建议听完全部课程

相关领域的公开中文资料非常之少,如果还需要其他补充,建议直接上手 CMU 15-418

5 缺失的 N 课

此节标题的灵感来自 MIT 《计算机教育中缺失的一课》

请注意“缺失的一课” 中部分内容并不一定是缺失的,例如 Vim 使用技巧这样的内容并不是每个人都必须掌握(Vim 很棒,但是它不是你编程能力的决定性因素)

5.1 开发环境迁移到 Linux

此处不会着墨于为什么使用 Linux 作为开发环境,只从使用体验上落笔:

  • Linux 下软件的安装配置更简单,奇怪的 BUG 更少
  • 很多开源软件仅 Linux 支持
  • 生产环境中的很多代码都运行在 Linux 上

建议将开发环境尽早的迁移到 Linux 或类 Unix 内核的平台下

不建议在同一个硬盘中安装多系统,当一个系统出现问题,可能导致另一个系统也无法正常启动

所以 Linux 系统建议使用 WSL(Windows Subsystem for Linux),虚拟机进行安装,或者使用 “容器”

5.2 Git/Github

当你的代码量足够大的时候,代码管理将会成为问题,而 Git 可以帮助你

  • 自动的代码版本管理
  • 可查看的修改记录

GitHub 则能够实践互联 的代码管理功能,如果你暂时英语能力不足,《GitHub 入门与实践》
或许能帮你更好的入门 GitHub

5.3 Markdown

如果你的目标是继续深造,建议系统性的学习 LaTeX用法

Markdown 本身也在飞速成长当中,例如 Slidev 这样的插件还在进一步的拓展 Markdown 的功能

5.4 程序语言理论(初步)

之所以没有在第 3 节写上“编译原理”的大名,是因为其并不是编程基础能力的一部分,
编译原理对大多数本科生的意义恰恰在于更深入的了解编程语言的内在逻辑,从而写出安全、高效的代码,而现有的编译原理课程大多专注于编译时需要履行的各种规则,并不侧重于程序本身的设计哲学。

推荐《计算机程序构造与解释》一书的 scheme 版

现在流行的似乎是 Python 版,但是 Python 版过多的封装事实上人为的增加了程序的复杂性,加上学习函数式编程的可观收获,仍然推荐使用 Scheme 版

是否添加本节纠结了很长的时间,事实上,读完本书前后花了我一年多的时间(其中很大一段还是大四的清闲时光),这不是一本易读的教材,但的确能够在不涉及太多形式化手法的情况下对程序语言的设计哲学有一个一定深度的认识。

后话

如有高见,还望各位在评论区不吝赐教。

文章知识点与官方知识档案匹配,可进一步学习相关知识CS入门技能树Linux入门初识Linux24719 人正在系统学习中

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2022年7月16日
下一篇 2022年7月16日

相关推荐