之前看到别人的CS61a学后感时,只觉得学个网课都要写篇文章是不是有点表演型人格了,但我学了几节之后就觉得CS61a简直是文明的福音转码的圣经,为什么没有早点知道有这门课存在?并且陷入了对伯克利的学生的羡慕中(他们大一就学CS61a)。现在我学完了CS61a的(几乎)所有内容,特此写一篇文章记录一下,顺便安利给有缘人。

为什么学CS61a

本来我是看了一亩三分地上的转码帖子,学了斯坦佛的Databases课之后打算学CS61b的,但发现CS61a是CS61b的prerequisite。为了满足心理洁癖(也因为我时间比较充裕),我决定从CS61a学起。
由于当时最新的fa21还没更新完,次新的su21的最后一些录屏看不了,次次新的sp21没一个录屏看得到,于是我就学了fa20。非常感谢UCB把CS61a fa20材料中能公开的都公开了。

CS61a教了什么

这门课是SICP的变种,使用Python 3来展示抽象方法、编程范式和管理大型程序的技术。由于2012年之后的新版CS61a使用Python教学,所以较旧版(使用Scheme教学)更容易入门,也更贴近实际。分章节来说,CS61a主要教了以下这些内容:

  1. 用函数构建抽象关系
    1. 函数与函数设计
    2. 控制
    3. 高级函数
    4. 递归函数
  2. 用数据构建抽象关系
    1. 数据抽象
    2. 可变数据
    3. 面向对象编程
  3. 解释(interpreting)计算机程序
    1. 函数式编程
    2. 异常
    3. 解释器的开发
  4. 数据处理
    1. 声明式编程

我学到了什么

其实在学CS61a之前我也学过算法与数据结构,做过C语言的算法题、用python和java刷过一点leetcode。但一直苦于没有系统性地入门CS,知识点较为零散,没有构建"Computational Thinking"。通过学习CS61a,我感觉多少缓解了这种焦虑。在课程的主要知识点内外,我印象最深刻的内容是这些:

  1. 代码如何被解释器执行
    调用一个函数时operator和operands的计算顺序、程序执行的frame和environment、可变与不可变数据、多重赋值、nonlocal赋值、异常处理等
  2. Recursive Leap of Faith (递归的信仰之跃)
    递归与数学归纳法很像。编写递归程序时,一个base case规定边界条件、一个recursive case规定递归操作。在recursive case中,我们信任这个函数会给出正确的n返回值,再利用返回值去构建n+1的返回值。这种信任被称为"Recursive Leap of Faith"。同样当我们理解、修改递归程序时,不应该试图推演递归调用,而是直接信任它,并在其基础上修改从n到n+1的操作,leave the hard work to the computer。 当然,一定要推演的话可以推演一个递归深度浅的例子。
  3. 什么是abstraction (抽象)
    赋值、函数、对象等等都是抽象,没有抽象的语言是低级语言。通过抽象,我们可以把问题变为计算、变为对象。这也是面对对象编程的一大优势:问题的场景会自动解决一部分问题,it is what it is.
  4. 为什么说LISP是神的编程语言
    CS61a教了LISP的一门方言:Scheme。这是一门函数式编程语言(所有函数都没有副作用,纯粹依靠返回值),只有call expression和special form两种语句。但它神奇在于几乎无限的可拓展性:定义函数就不说了;Scheme还可以通过定义宏来定义special form(原理是宏的参数不会在调用之前被evaluate,进而可以控制evaluation的步骤);而且,Scheme中的数据与程序都是链表,这让编写编写程序的程序变得非常简单,事实上,计算机推导公式与符号计算正是如今lisp的主要应用之一。
  5. 解决问题的一般思路 (来自How To Design Programs)
    1. 从分析问题到定义数据
      阅读问题,寻找必须要被抽象化(表示)的信息,并思考用何种数据结构表示。寻找实际例子。
    2. 函数签名、目的描述、以及docstring
      思考解决问题的函数的输入与输出,准确描述这个函数在计算什么并撰写docstring。
    3. 例子推演
      通过例子推演计算的步骤,编写核心的步骤,设计函数的骨架。
    4. 函数定义
      编写剩下的函数使其能够支撑核心步骤,通过例子意识变量与表达式的实际意义。
    5. 测试
      使用例子推演函数、并使用doctest测试、修改错误、把程序修改得更为易读。

CS61a好在哪里

能学到知识当然好,但它是否值得我花时间去学呢?我想不少人可能有这样的疑惑。我的回答是YES,这门课在很大程度上增加了我对编写程序的热情,如果没有lab、homework、discussion、project以及其他课程工具的精巧设计,这是不可能的:(几乎)所有题目都有完善的说明、例子、半自动的测试和批改,python tutor可以帮你把python程序的frame可视化,在线interpreter让你可以随时随地互动测试。

最重要的是,CS61a的四个项目里面有三个都是做游戏,这真的很让人兴奋。我还记得我才学完控制和高等函数的时候,就遇到了第一个项目。没想到光是用这么基础的知识就可以编写一个掷骰子游戏hog的核心逻辑、策略。其他几个游戏在这里就不剧透了,它们都很有意思。另外,CS61a中有好几处谐音梗和对pop culture的致敬,其实这些才是我记得最牢的哈哈哈。除此之外,还有一些节目效果拉满的lecture,比如John表演手搓某游戏音乐、讲解对象的多重继承时的抽象一家人伦理小剧场...总之真的很欢乐。

数据

CS61a总共4个project,10个homework,14个discussion,14个lab,38个lecture,261个视频。
我从10月31日到1月11日,总共用了72天学完(几乎)所有可以得到的材料(刚开始的一个月只学了65小时)。学了最长时间的那天是2021年12月31号...在CS61a上用了6小时四十五分钟。有记录的学习时间共计229.08小时,详细数据(Google Spreadsheet)供考虑学CS61a的同学参考。

最后

千言万语难以表达我对这门课的喜爱和对UCB, Dr. John Denero, Dr. Hany Faird的感谢。就以他们的人生建议结束吧。

When I was getting married, I was a PhD student at the time. My mom pulled me aside on my wedding day and said "John I want to give you some advice". I was like oh she's going to like tell me to listen to my wife or whatever. But she didn't. She said only two words that have stuck with me for a long time. She said "don't compare". That's all. And then she was like okay you can go back to do whatever you're doing. At the time this was very hard for me to process because I was in a university which is all about comparing people based on like what their exam score was. It turns out that out there in the world, there are no exams that everybody takes that are standardized anymore. All that matter is what you go and get done on your own particular path. So, comparing yourselves to other people becomes meaningless rapidly as what really matter is what you could do yourself, like what you're capable of and what you bother to do and how you choose to spend your time. It took years of this two-word phrase "don't compare" to marinate inside of me and for me to realize that my self-worth really has noting to do with what other people can do or whether I can do it better than them or worse than them. It has everything to do with what i've done and what i'm gonna do next and how I spend my time and better myself. I should just focus on improving myself and forget about what everybody else is doing. (John Denero)

It is something that took me a long time in life to understand not to compare. And there's a trap too that we do. We compare for example how big our house is to that one friend and how much money we make to another friend, and the kind of clothes we have to this friend and how smart we are to that friend. We pick and choose these things and that's first of all, even doing that individually is meaningless right? But it's also a trap and this is the problem with social media, you see these sore of curated worlds of other people and it's a trap. One of the great things of getting older is you will get there, I promise, you will realize it's a trap and comparing means absolutely noting. It really is a very internal thing of what are you doing, who do you want to be, how do you want to go through this world, how do you want to treat other people. At the end of the day, that, and almost noting else, is going to matter. And you got to just trust that it's going to be there. (Hany Faird)

如果这篇文章对你有帮助,考虑给我的CS61a fall 2020 repository点个star,谢谢。