软件虽“软”,背后却是有严密的逻辑体系作支撑,人类发出的指令,经过编程语言的抽象,到计算机的执行,离不开数学、算法、计算机体系结构等理论知识的发展。
用可计算性理论或图灵生平作为关键线索,结合了解一下计算机发展史,可以对计算机科学的历史有一个全局的认知,了解计算机是从哪里来的, 又如何发展到今天。你会发现计算机与数学逻辑的渊源,图灵机、信息论与冯诺依曼架构等大批关键词会进入你的脑海。
说不定你会对某块内容产生极大的兴趣和热情。
深刻理解事物,要追本溯源(第一性原理),以发展的眼光把握事物的发展史,站在巨人的肩膀,站得高,望得远。
基础不稳的缘由
很多计算机专业的学生在本科教育阶段遇到是上课只会读 PPT 的老师,加上同学之间有没有几个对计算机本身都感兴趣的伙伴合作学习或者做项目,就会因此丧失了对计算机的兴趣,最后变成突击复习应付考试,并没有把知识转化为能力。
还有很一大部分工程师并没有接受过完整的计算机学科训练,对基础知识的学习只是来自于短期培训、自学和工作中的碎片化积累,无法在职业生涯中走的更远。
不过好在软件行业注重实践,网络上亦有优质的学习资源和社区,你完全可以自学成才,基础不扎实并不是无法挽回的问题,亦不依赖什么天赋。
你可以伴随着好奇心,一点点去深入一件事情背后的原理与逻辑,在实践与应用中逐步搭起的知识框架,往往也是有着一件件事情前因后果逻辑的鲜活的知识体系,而这比在课堂上被动接收的一个个孤立的知识片段会坚实且具有生命力许多,从而在知识的实际应用与进一步拓展中显得更加游刃有余,并且在面对未知的事物时有更大的力量与精准度去直击事物的本质。
许多表面上的“天赋”,本质上是思维模式的不同,以及在此基础上随着时间,和滚雪球一样衍生出的“阅历”差异,而不是什么真正的天赋凛异。
— 知乎用户
初学入门,兴趣和热爱最重要
如果你对计算机知之甚少,也没有接触过编程,简单、轻松而全面的入门课程是最好的选择,一上来让你去啃 C 语言,可能会让你从此对编程丢掉信心。
Harvard CS50's Introduction to Computer Science
计算机科学和编程艺术的一场轻松之旅,我是 CS50 的爱好者,我愿称之为最棒的计算机科学入门课,每年都会刷最新学年的视频,而且你一定会被主讲教授 David J. Malan 的个人魅力感染,而且上完这个课程,你会非常自信的去尝试做软件或继续其他领域知识的学习。感受一下讲师的热情:

B 站上面有 CS50 年的课程视频,感谢字幕组做了双语言翻译,少了语言的门槛:
CS50 每年都会开新的网络课程,如果你英文不错,可以考虑直接参加 2022 年秋季学期,跟哈佛的小伙伴成为同学,一起做项目更有意义:
不用担心自己不懂编程,跟着做项目是最关键的。
还有一些非常不错的经典入门课程推荐:
- Udacity CS101:计算机科学导论
- CS 61A: The Structure and Interpretation of Computer Programs
- Berkeley 的经典 CS 入门课,也非常有深度,课程地址:https://cs61a.org/
- 教材 SICP(Structure and Interpretation of ComputerPrograms),原版:
- 课程使用 Python3 作为授课的编程语言,Python3 改写的 SICP 教材:
- 教授 John DeNero:https://denero.org/
额外的一些资源推荐,如果你还在大学校园,应该会感兴趣:
- csdiy.wiki 一个北京大学信科专业同学在大三(2021 年)整理的一份计算机自学指南,如果你还是学生,想寻找同龄人一起组团学习,这里是不错的选择:CS自学指南
- CrashCouse 计算机速成课系列视频,可以当成科普和学科概览视频:【计算机科学速成课】[40集全/精校]
- 0xFFFF 这是一个面向计算机爱好者的学习交流社区,发源于华南师大计算机学院,目前汇聚了一些来自各地高校、企业乃至于中小学的计算机爱好者们。
计算机是如何运转
想象一下,当你在浏览网页或者和朋友视频聊天的时,在漂亮的界面下面程序到底如何运行的一无所知。但是你决定成为一个软件工程师,你就要开始了解这些内部到底是如何运转的:
- 机器之间是如何通信的?数据传输和存储的方式?如何保证通信安全?
- 鼠标点击操作是如何变成一堆计算机执行指令的?
- 常听的那些计算机零件,芯片、CPU、GPU、内存等是如何协同工作的?...
虽然不用像硬件工程师熟悉集成电路设计,焊电路板,但是对于计算机的组成、运转机制、程序编译过程了然于胸、非常通透,绝对是有益无害的投资。
主要需要学习以下内容:
1)计算机组成(Computer Organization):计算机组成强调的是有关控制信号(怎样控制计算机)、信号传递方式以及存储器类型等问题,涵盖了有关计算机系统的物理构成的各个方面。
2)计算机体系架构(Computer Architecture):集中讨论计算机系统的结构和行为,主要涉及程序员熟悉的系统实现的逻辑方面内容。其包括许多基本要素,如指令集和指令格式、操作码、数据类型、寄存器的数目和类型、寻址方式、主存储器的访问方式和各种I/O机制等。对于某个特定的计算机,计算机体系结构就是其各硬件部分的组合,再加上其指令集体系结构(ISA,instruction set architecture)。
3)编译原理,编译原理是比较枯燥的一部分知识,包括词法分析、语法分析、语义分析、运行时环境、寄存器分配、代码优化与生成等内容。
4)操作系统(Operate System)我们下一节单独聊。
学习课程和资源推荐
关于编译原理,机客时间的付费课程(非广告),适合工作几年的工程师补课: 编译原理之美, 时间和精力充足,也可以考虑啃斯坦福的 CS143 Compilers:
对于初学者来说,Compiler Construction: Principles and Practice 比龙书可能更友好一些(需要读英文版),《Parsing Techniques》也有很多人推荐,没了解过:
如果想学习编译原理,不妨也了解一下: LLVM Tutorial: Table of Contents — LLVM 15.0.0git documentation
吃透操作系统
我们开发的软件并不能直接去控制硬件资源,需要找一个代理人/媒介去管理硬件资源和软件的交互,就像一个资源管理器(resource collector),这就是操作系统存在的意义。当我们按下开机键后,位于电脑主板上的固件 ROM 中的启动程序(Boot Loader)会运行,启动程序会加载操作系统的启动程序,进而把整个操作系统加载到内存中并开始执行操作系统。
操作系统也是一种软件,但是操作系统是一种非常复杂的软件。
操作系统提供了几种抽象模型:
文件:对 I/O 设备的抽象 | 虚拟内存:对程序存储器的抽象
进程:对一个正在运行程序的抽象 | 虚拟机:对整个操作系统的抽象
操作系统课程包含的主要内容:
- 操作系统运行时(程序中断、定时器)
- CPU 调度
- 进程(同步、互斥)、线程、管程(Monitor)
- 存储管理
- 文件系统
- I/O 输入
- 死锁
- 信号量编程
读书、看视频课程都可以加深对操作系统的了解,经典书籍:
不过我们也可以学习一些跟得上时代的内容:
推荐课程 #1:MIT 6.S081: Operating System Engineering
MIT PDOS 实验室开设的面向本科生的操作系统课程,注重动手能力培养,让你在基于 RISC-V 开发的操作系统 xv6 之上增加新特性,深刻理解操作系统的每一部分。
推荐课程 #2:rCoreOS 清华大学的操作系统课程
清华大学是国内首个使用 Rust 进行操作系统教学的高校。目前,陈渝教授和他的学生吴一凡正在编写新的操作系统教材。
这本教程旨在一步一步展示如何 从零开始 用 Rust 语言写一个基于 RISC-V 架构的 类 Unix 内核 。值得注意的是,本项目不仅支持模拟器环境(如 Qemu/terminus 等),还支持在真实硬件平台 Kendryte K210 上运行。
rust 社区也有一个重写操作系统的小项目,可以和这个项目做个对比参照:Writing an OS in Rust,基于 x86架构(the x86 architecture),使用 Rust 语言,编写一个最小化的 64 位内核。
推荐课程 #3: 南京大学计算机系统基础
课程的项目 (Programming Assignment)
理解"程序如何在计算机上运行"的根本途径是从"零"开始实现一个完整的计算机系统. PA 将提出 x86/mips32/riscv32 架构相应的教学版子集, 指导学生实现一个经过简化但功能完备的 x86/mips32/riscv32 模拟器NEMU(NJU EMUlator), 最终在NEMU上运行游戏"仙剑奇侠传", 来让学生探究"程序在计算机上运行"的基本原理.
学习自己动手构建一个操作系统,会让你对操作系统有全新的理解。
算法与数据结构
算法(algorithm):是刻画计算过程的机械能行的指令集,它可以在有限步执行指令对给定的一类问题中任一问题求解。
程序 = 数据结构 + 算法
— 尼古拉斯·沃斯, 创建与实现了 Pascal 语言,因这个公式获得 1984 年图灵奖
这部分的知识如何学习和总结比较合适呢?是一个难题。一上来就去啃经典巨著《算法导论》感觉不是很容易,听很多人建议,算法入门不要选算法导论,这个建议或许是中肯的。
普林斯顿大学在 Coursera 上开的公开课 Algorithm 是比较平缓的学习开始:算法,第一部分
找书籍的话 DVP(Sanjoy Dasgupta, Papadimitriou, Umesh Vazirani)的新书 Algorithms 是入门算法不错的选择,UC Berkeley 的 CS170 使用该教材,当然也不能放过手册:《算法设计手册》,这个可以作为参考书使用。
数据结构课程:UCB CS 61B Data Structures
Josh Hug 据说是位“可爱”、人气非常高的讲师,不去了解一下?而且如果你不懂得如何使用栈、队列、树、图等常见数据结构,遇到有难度的问题时,你将束手无策。

[双语字幕] [2019 SP/2020 FA] UCB CS 61B Data Structures
学习这部分的目的要有清晰的认知:
了解很多基础的算法和数据结构,学习理解算法设计的精髓,是要学习如何写出[好]的程序,亦涉及你对什么是好代码的判断标准。
题外话:如果你对如何解决本身缺乏思考,这本书说不定会让你茅塞顿开:《怎样解题》
如果是你为了面试准备或程序竞赛学习这部分内容,网络上应该有比较完备的资料,不作过多介绍。
🔐 密码学和信息安全(可选)
教程资源:
Udacity的公开课《Applied Cryptography》适合快速入门,→ 讲义
书籍资源:
PS:在这里忽略了两个很重要的部分:网络知识和数据库,不用担心,会在后面的部分出现。