转码记录 Vol.02 | 25 Winter:校内三门 + 自学四门,这学期开始有了层次感
上 学期(24 Fall)用三门课完成热身。这学期开始不一样了:校内三门课 + 自学四门课同步推进,工作量直接翻倍。CS 61A、CS 61B、CS 61C、Nand2Tetris——技术知识开始有了层次感,从 NAND 门到高级语言的完整链路第一次在脑子里贯通。
上学期(24 Fall)用三门课完成了热身——离散数学建立了形式化推理的思维方式,微积分稳住数学基础,EECS 1012 给了第一次写出可运行程序的感受。
但那个学期结束时,有一种感觉:框架有了,还很空。知道命题逻辑是什么,能写简单的 JavaScript,但还停留在"知道是什么"而不是"理解为什么"的阶段。
这学期开始不一样了。校内三门课 + 自学四门课同步推进——其中 CS 61A 实际在 24 Fall 期间并行完成,放在这里一起说。工作量直接翻倍,但收获也是。
24 Fall 同期自学:CS 61A – Structure and Interpretation of Computer Programs(UC Berkeley)
这门课用 Python 和 Scheme 讲,但重点不是语言语法,而是计算的基本思想:抽象、递归、解释器、高阶函数。
对我影响最大的是"函数是一等公民"这个概念——函数可以作为参数传入另一个函数,可以作为返回值返回。这和命令式编程(先做 A 再做 B)是不同的范式。Lambda、闭包、尾递归优化,在这门课里都有 系统讲解,而不是在某个框架文档的角落里顺带提一句。
课程还要求用 Python 实现一个简化的 Scheme 解释器。解释器的工作是:源代码字符串 → 词法分析(Tokenizer)→ 语法分析(Parser)→ 求值(Eval)。每一步都自己实现。做完这个之后,对后来 Nand2Tetris 里实现编译器的过程有了直接的认知基础——两者的结构几乎一样,只是输出目标不同。
校内课程
EECS 1022 – Programming for Mobile Computing
正式课程名是移动计算编程,用 Java 和 Android 环境做实际的移动应用开发,成绩 A+。
难点不在语法,在于从脚本思维切换到面向对象思维。
JavaScript 里写逻辑,函数是主角,数据跟着函数走。Java + Android 的世界里,首先要问的是:这个功能属于哪个类?这个类有什么状态?状态由谁管理?Activity 的生命周期(onCreate → onStart → onResume → onPause → onStop → onDestroy)是 Android 的基本框架,每个阶段对应不同的资源分配和回收策略。在写代码之前,必须先想清楚对象的结构。
Android 开发引入了事件驱动编程的完整模型:用户点击按钮,触发 OnClickListener,回调函数执行。这个模式和上学期 EECS 1012 里 JavaScript 的事件处理是同一套思想,但现在用类和接口来描述,结构更明确,边界更清晰。
课程 Lab 最后要做一个完整的 Android App,从 UI 设计到数据逻辑到设备传感器接入。第一次真正体会到"一个可以装进手机的程序是怎么从代码变出来的"。
MATH 1090 – Introduction to Logic for Computer Science
这门课的前置是 EECS 1019(离散数学),把上学期学的命题逻辑推向了更系统的形式化方向,成绩 A。
EECS 1019 讲的是命题逻辑的基本概念——真值表、逻辑连接词、证明方法。MATH 1090 在此基础上引入谓词逻辑(Predicate Logic),以及程序规约和验证的应用。
谓词逻辑的关键升级是引入了量词(∀ 和 ∃)和变量。∀x ∈ ℤ, P(x) 这类语句允许对一类对象统一描述性质,而不只是处理具体的真/假值。这让"描述系统行为"变得可能:可以用形式化语言说清楚一个函数"对所有合法输入都返回正确结果"是什么意思,而不只是靠测试用例来近似。
这门课最有实用价值的部分是前置条件(Precondition)和后置条件(Postcondition):
- 前置条件:函数调用前,输入必须满足的约束
- 后置条件:函数执行后,输出和状态必须满足的约束
这套语言让"正确性"从模糊的直觉变成了可以被形式化描述的东西。后来在 EECS 2101(数据结构)里,每个 ADT 操作都要用这套语言来规约;在 EECS 3311(软件设计)里,这套方法会进一步系 统化。这学期学的是基础,那些课里用的是应用。
MATH 1014 – Applied Calculus II
接续上学期的 MATH 1013,这学期完成微积分下册,成绩 A。
内容:积分技巧(分部积分、换元、三角代换)、级数(比值法、根值法、积分判别法)、多元函数入门(偏导数、梯度)。
级数收敛判别值得单独记一句:判断级数收敛与否用的是渐近估算思维,和算法分析里判断复杂度是否可接受用的是同一套工具。现在看起来是数学课,后来在 EECS 3101 算法分析里会用到。
自学课程
CS 61B – Data Structures(UC Berkeley)
系统学习基础数据结构和算法:链表、树(BST、AVL、Red-Black Tree)、哈希表、图(BFS / DFS / Dijkstra / Prim)、排序(MergeSort / QuickSort / HeapSort),以及对应的时间空间复杂度分析。
Berkeley 的这门课有完整的 Project 体系,Gitlet 项目是其中难度最高的:用 Java 实现一个简化版 Git,支持 init、add、commit、branch、checkout、merge 命令。
