编程
本课程学习编程中最基础的概念,包括变量、赋值、表达式、语句、循环、条件、函数等。这些是无关具体语言的编程技术,请不要纠结于语法细节和各种标准库函数如何使用——这些直接查询文档即可。
《CS50x》是 Harvard 大学的计算机导论课,其语言组合覆盖了常见的编程需求,很适合作为编程基础课。
- 课程从 C 语言开始学习,这是相对低级的语言,适合理解计算机底层设计。计算机系统、操作系统、系统编程、网络编程等课程都要求掌握 C 语言。
- 课程随后过渡到 Python,这是相对高级的语言,适合理解计算思维和算法逻辑。人工智能、数值分析等课程都要求掌握 Python。
- 课程最后接触了一点 SQL 和 Web,这常见于现代软件开发,适合理解实际的编程场景。
如果不喜欢跟着课程学习,也可以自己阅读教材。
- 如果你有一定的程序设计基础,或者天赋异禀,可以直接看《C 程序设计语言》。这是 C 语言的设计者写的书,绝对的权威教材。
- 如果你毫无编程经验,那么可以试试《C Primer Plus》。这相比另一本书厚很多,对初学者更加友好。
至于 Python、SQL、Web,从参考手册中了解一下基本语法和主要标准库就足够了。
程序构造与解释
Section titled “程序构造与解释”《计算机程序的构造和解释》一书的定位存在很大争议。这是 MIT 计算机科学的入门教材,正如书名所说,其介绍了程序如何构造以及如何解释。但我更愿意称该书为一本编程哲学书,一本有助于培养抽象思维和理解计算本质的书。
全书采用 Scheme 进行教学。这是 Lisp 的一种方言,如今不算主流,但其特性很适合本课程。
- Scheme 支持函数式编程。函数是一等公民,程序通过函数的定义、调用和组合来构造;名称用于绑定值,而非通过赋值不断修改状态。
- Scheme 也支持赋值。引入赋值后,名称绑定的值可以随程序执行而发生变化,程序因此拥有显式状态,可以构造有状态对象。
- Scheme 有很强的元语言抽象能力。元语言是用来定义其它语言的语言。而元语言抽象是指语言把自身作为元语言去创造新语言。
全书共 5 章,大概可分为 3 个部分。
- 第 1 章和第 2 章围绕着函数式编程展开,通过简单的函数来实现过程和数据,随后使用过程和数据来构建更复杂的程序。
- 第 3 章则突破了函数式编程的框架,通过引进赋值,程序拥有了状态,从而可以利用状态来编写程序。
- 第 4 章和第 5 章开始讨论语言自身,通过元语言抽象来用语言去创造语言,通过寄存器机器模型来理解实际机器如何执行程序。
该书的习题很有价值,可以挑选部分尝试完成。
本课程学习如何使用常见的开发工具,包含命令行、编辑器、数据整理、版本控制、程序调试、性能分析、编译构建、密钥生成等。
《计算机教育中缺失的一课》以 Linux 作为主要教学平台,macOS 可以无痛兼容。如果你使用的是 Windows 系统,那么讲义第 1 节的练习会教你怎么安装 WSL——这是 Windows 上的 Linux 子系统,足够满足本课程的需要。
讲义里附有简单的练习,可以尝试去完成。不过,完成这些练习并不代表真正掌握了所有开发工具。
我在学完本课程后,还花费了至少上百小时来学习如何使用开发工具——这是一个无底洞,每个工具都可以深究,工具与工具间的组合也可以探索。并且,工具自身也会不断演化改进,时不时还会有全新的工具冒出来。
因此本课程的目的不是让你完全掌握这些开发工具,而是让你知道有哪些开发工具,了解这些工具分别有什么用,以及学会大致的用法。本课程所学的知识大概率无法直接帮你解决实际开发中遇到的难题。但是,本课程会让你知道遇到这种难题时应该使用哪些工具。你可以因此更深入地去研究该工具从而解决实际问题。
数据结构与算法
Section titled “数据结构与算法”本课程推荐两套教材,可以自行选择。
- 《数据结构与算法分析》中的示例使用 C 语言。因此选用《数据结构与算法分析》作为教材,最好有 C 语言基础。
- 《算法导论》中的示例使用伪代码。因此选用《算法导论》作为教材,不要求有 C 语言基础,但最好还是有点编程基础,至少要能看懂伪代码。
另外,与《数据结构与算法分析》相比,《算法导论》多了许多内容,这些主要集中在该书的第七部分。这部分内容涉及到线性代数、信号与系统、凸优化等数学课程,建议初学者跳过这部分。如果确实对这些内容感兴趣,那么可以学习对应的数学课程,或者学习数值分析——这门课专门讨论复杂数学问题的算法。去掉这部分后,《算法导论》的篇幅就和《数据结构与算法分析》差不多了。
面向对象编程
Section titled “面向对象编程”- 强依赖
本课程有两本主要教材。
- 《C++ Primer》学习 C++ 中的独特语法和面向对象编程中的基本概念。
- 《设计模式》学习如何使用面向对象技术设计复杂的软件系统。
课程选择使用 C++ 学习面向对象编程,有以下几个主要原因。
- C++ 提供了封装、继承、抽象、多态等面向对象编程所需的语言特性。
- C++ 与前后课程都有很好的衔接。编程基础中已接触过 C 语言,而 C++ 沿用了 C 语言的部分语法,可以减轻学习负担;《设计模式》本身使用 C++ 教学,后续的软件工程、计算机图形学、游戏开发等课程也都要求掌握 C++。
关于《C++ Primer》,虽然网上口碑不错,但我个人觉得比较一般。本书大部分篇幅都在纠结 C++ 的语法和标准库的接口,面向对象编程相关的内容占比很少,因此阅读的时候需要取舍。
- 本书的第一部分讲语法,这部分不应该纠结过久,如果已有 C 语言基础,那么只关注 C++ 独特的语法即可。
- 本书的第二部分讲标准库,这部分也不用花太多时间,拿来参考就行。
- 本书的第三部分讲类设计工具,可以重点关注其中的面向对象编程和泛型编程部分。
关于《设计模式》,这是一本百科全书式的教材,阅读时也需要一些取舍。
- 本书第一部分讲解为什么要学习设计模式,并以一个具体的例子展示如何运用设计模式来解决复杂的软件设计问题。这部分建议完整看完。
- 本书第二部分将设计模式按功能分类,并依次详细地介绍每个设计模式。这部分不必详细地逐个阅读,建议先快速了解一下所有设计模式,然后再根据需要深入学习。
另外《设计模式》中还有部分内容可以酌情跳过。
- 本书使用 C++ 和 Smalltalk 这两种语言进行教学。其中 Smalltalk 虽然从语言设计到编程实践都完整地贯彻了面向对象编程的理念,但由于其并不主流,因此没必要专门为了本课程而学习,实在看不懂这部分代码的话直接跳过也没问题。
- 书中有非常多的设计示例,包括图形界面的设计、编译器的设计、操作系统的设计、文本编辑器的设计、迷宫游戏的设计等。部分示例可能需要一点专业知识才能完全理解。但本书的重点是学习设计模式,而不是理解每个示例。如果某个未能完全理解的示例并没有影响到对该设计模式的掌握,那么不妨将其跳过。
- 弱依赖
本课程学习函数式编程中的基本概念,以及如何使用函数式技术设计复杂的软件系统。
课程选择使用 JavaScript 学习函数式编程,有以下几个主要原因。
- JavaScript 支持函数作为一等公民、闭包、高阶函数等函数式编程所需的语言特性,且标准库中包含大量函数式接口。
- JavaScript 与前后的课程都有很好的衔接。编程基础中已经接触过 Web 技术,这降低了理解 JavaScript 语法和标准库的成本;后续的网站开发课程需要学习 React、Node.JS 和 TypeScript,这些都是 JavaScript 生态的一部分。
本课程选用《JavaScript 函数式编程指南》作为主要教材,其中部分内容与《计算机程序的构造和解释》有所重叠,但后者更关注计算模型,前者则把函数式编程作为一种独立的编程范式来学习。全书大致可以分为三个部分。
- 第一部分介绍函数式编程的基本思想,包括声明式编程、副作用、引用透明性、不可变数据、函数作为一等公民、高阶函数和闭包等概念。
- 第二部分介绍函数式编程中的主要技术,包括函数链、递归、柯里化、部分应用、函数组合、函子等。
- 第三部分讨论如何把函数式技术应用到实际的软件开发中,包括程序测试、性能优化和异步编程等问题。
本课程学习如何分析需求、设计架构、构建代码、测试应用,这覆盖了软件开发的主要活动。
本课程选用的教材是《代码大全》。从书名也能猜出来,本书重点关注代码构建这一部分。
- 对于代码构建,本书不仅讨论了代码好坏的评判标准,并且比较了多种编程实践的优劣。
- 对于构建之外的活动,本书进行了简要的介绍,并提供了丰富的资料让有兴趣的人可以深入研究。
书中的代码示例主要为 C++、Java 和 Visual Basic。本书重点是那些无关语言的技术,且这些示例都较为直观和易于理解,因此不必纠结于语法细节。
本课程学习编程语言背后的形式化理论,包括 lambda 演算、操作语义、类型系统及其元理论。
选择的教材为《类型和程序设计语言》,其中代码示例使用 OCaml,并以 Java 的面向对象类型系统作为研究对象。本书的重点是形式语义和类型理论,用于补充此前程序构造与解释、面向对象编程、函数式编程和编译原理等课程未能覆盖到的编程语言原理。
- 强依赖
本课程推荐两套教材,可以自行选择。
- 《软件基础》使用 Rocq 语言。课程相对更加成熟,有纸质印刷的英文版,但中文翻译只有电子文档。
- 《逻辑验证漫游指南》使用 Lean 语言。语言和课程本身都在高速迭代,因此没有纸质书籍,但社区里有可使用的中文翻译。
《软件基础》的内容远比《逻辑验证漫游指南》更多。如果选择读前者,那么只需重点读第一卷整卷和第二卷的霍尔逻辑、操作语义相关章节即可。
本课程学习如何设计一个游戏引擎,当然这对于使用现成的引擎去做游戏也有一定帮助。
《游戏引擎架构》全书近千页,把游戏引擎的整个技术栈都介绍了一遍。不过,由于游戏引擎过于复杂,因此部分内容实际上还是较为简略。
本书大体上为总分结构。
- 开头简要介绍了游戏引擎的整体架构。
- 然后补充了一些编程和数学的基础知识。
- 接着分别讲述游戏引擎的各个子系统。
本书使用 C++ 进行教学,几乎所有主流的游戏引擎都由这门语言编写。
本课程学习如何用 Web 技术开发全栈应用,主要技术栈为 MERN。
《全栈公开课》是 Helsinki 大学的公开课程,它覆盖了 Web 开发的所有主要内容。
前 7 部分使用以下技术构建了一个全栈应用。
- 使用 React 构建前端。
- 使用 Node.js 和 Express 构建后端。
- 使用 MongoDB 作为数据库。
- 使用 Vitest 和 Playwright 作为测试框架。
- 介绍 React Router、MUI、Styled 等库。
- 介绍 Zustand 状态管理方案。
- 介绍 Vite 和 esbuild 打包工具。
而第 7 部分之后,课程介绍了一些新兴技术。
- 讲解如何用 TypeScript 实现类型安全。
- 讲解如何用 GraphQL 设计服务端点。
- 讲解如何用 React Native 构建移动应用。
- 讲解如何用 Next.js 完成全栈开发。
- 以 PostgreSQL 为例介绍关系型数据库。
- 以 Docker 为例介绍容器技术。
- 以 GitHub Actions 为例介绍持续集成技术。
《UNIX 环境高级编程》介绍 UNIX 的 C 语言接口。本书内容非常详实且全面,比起教材更像参考书,因此建议只在需要的时候翻阅特定章节。
- 弱依赖
《UNIX 网络编程卷 1》介绍 UNIX 的 C 语言套接字 API,同样建议作为工具书使用。
《Java 并发编程实战》介绍了线程安全、对象共享、任务执行、活跃性、性能、锁、原子变量和内存模型。虽然其以 Java 的线程模型和并发库为载体,但竞争条件、同步、死锁、可见性等核心问题仍普遍存在于其它语言的并发编程中。