TIP欢迎来到我的 CS61B 课程笔记! 在这份说明中,我将分享与CS61B
CS61B: Data Structures相关的笔记和资源,该课程由 Justin Yokota 和 Peyrin Kao 讲授。我会发布我在课程期间完成的讲座笔记、作业和其他材料。我希望这些笔记能对正在修这门课的其他人有所帮助。如果你有任何问题或反馈,请随时联系我。感谢你的关注。 如果你想阅读英文版,请点击这里。
CS61B课程笔记
可以直接跳过对未来的展望,这一部分主要是对UCB的学生的考核,当然你也可以参考一下UCB对学生的要求~
课程介绍
CS61B课程主要关注以下内容:
- 编写高效的代码
- 良好的算法
 - 良好的数据结构
 
 - 高效地编写代码
- 设计、构建、测试和调试大型程序
 - 使用编程工具
- git、IntelliJ、JUnit和各种命令行工具
 
 - Java(不是课程的重点)
 
 
课程假设学生具备以下编程基础:
- 面向对象编程、递归、列表和树
 
CS61B的其他精彩之处:
- 软件工程面试中最受欢迎的主题
- 示例:哈希表、二叉搜索树、快速排序、图、Dijkstra算法
 
 - 一些非常酷的数学
- 示例:
- 渐近分析
 - 数组扩容
 - 自平衡2-3树与自平衡红黑树的等距性
 - 图论
 - P=NP
 
 
 - 示例:
 - 完成后: 有信心可以构建任何软件
 
问题
你希望/期望从这门课中学到什么?你为什么选这门课?
- 工作
 - 我终于可以让我的代码高效运行了
 - 我想要得A
 - 从零开始编码
 - 更好地掌握数据结构和算法
 
你是谁?
- 大一?大二?大三?大四?研究生?以上都不是?
 - 计算机科学专业?打算成为计算机科学专业?其他?
 - 修过CS61A?有Java经验吗?
 
NOTE当你离开这门课时,我希望每个人都能为了乐趣而编写程序,因为他们有一些需要解决的问题,或者他们只是想浪费一个周末做点什么。 —Peryin
课程组成部分
- 讲座为你提供介绍和基础。
 - 你将通过以下方式学习大部分课程内容:
- 编程(实验、作业、项目、讨论课)
 - 解决有趣的问题(学习指南、作业3、作业4、旧考试题、讨论课)
 
 
一般来说,你会通过实践学到很多。编程不是仅靠理论就能学会的。 你需要真正去实践。因此,你会通过作业、实验和项目获得大量用Java编程的经验。讨论课不会直接进行编程,但你会讨论很多关于如何有效编码的内容。 整个学期你将解决很多有趣的问题。
评估
- 这门课有四种类型的分数:
- 低努力,每个人都应该得到: 每周调查、课程评估
- 中位数分数为100%
 
 - 高努力,每个人都应该得到: 作业、项目、实验
- 中位数分数为100%
 
 - 高努力,不是每个人都得到: 考试
- 平均分数为65%
 - 如果你在期中考试中表现不佳(或两次),期末考试分数可以替代期中考试分数
 
 - 进度分数: 参加讨论课、实验课并跟上讲座进度
- 跟上课程进度可获得少量额外学分
 - 不会将你的分数提高到超过75%(B-)
- 示例:你有740分并获得20个进度分数,你将得到750分
 
 
 - B到B+的门槛: 考试65%,其他部分95%
 
 - 低努力,每个人都应该得到: 每周调查、课程评估
 
课程阶段
- 第一阶段(第1-4周):Java和数据结构入门
- 所有编码工作都是个人完成
 - 进度非常快
 - 作业0(Java入门)将在周五到期(还有两天!)
 
 - 第二阶段(第5-10周):数据结构
- 所有编码工作都是个人完成
 - 进度适中
 
 - 第三阶段(第12-14周):算法
- 编码工作完全用于最终项目,由两人一组完成
 - 进度较慢
 
 
Java入门
print("hello world");Java是一种非常注重面向对象编程的语言。
它非常注重你编写的代码都在一个类中。让我们来创建一个类。我将使用 魔术词 public class 来定义一个类。
public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("hello world"); // print不包含"\n"
    }
}Java与面向对象编程
关于Hello World的反思:
- 在Java中,所有代码都必须是类的一部分
 - 类使用 
public class CLASSNAME定义 - 我们使用 
{ }来划分事物的开始和结束 - 我们必须用分号结束一行
 - 我们想要运行的代码必须在 
public static void main(String[] args)中- 我们稍后会学习这意味着什么
 
 
Java是一种具有严格要求的面向对象语言:
- 每个Java文件必须包含一个类声明
 - 所有代码 都在一个类中,即使是辅助函数、全局常量等
 - 要运行Java程序,你通常需要使用 
public static void main(String[] args)定义一个main方法 
Java与Python:静态类型
Python:
x = 0
while x < 10:
    print(x)
    x = x + 1
x = "horse"
print(x)Java:
public class HelloNumbers {
    public static void main(String[] args) {
        int x = 0;
        while (x < 10) {
            System.out.println(x);
            x = x + 1;
        }
        x = "horse"; // 这将导致编译时错误
        System.out.println(x);
    }
}关于Hello Numbers的反思:
- 在Java中使用变量之前,必须先声明
 - Java变量必须有一个特定的类型
 - Java变量的类型不能改变
 - 类型在代码运行之前就会被验证!
 
Java与静态类型
- Java是静态类型的!
- 所有变量、参数和方法都必须有一个声明的类型
 - 该类型不能改变
 - 表达式也有类型,例如 
larger(5, 1) + 3的类型为int - 编译器会在程序运行之前检查程序中的所有类型是否兼容!
- 例如,
String x = larger(5, 10) + 3将无法编译 - 这与Python不同,Python在执行期间进行类型检查
 
 - 例如,
 
 
在Java中编写函数
Python:
def larger(x, y):
    if x > y:
        return x
    else:
        return y
print(larger(-5, 10))Java:
public class LargeDemo {
    public static int larger(int x, int y) {
        if (x > y) {
            return x;
        } else {
            return y;
        }
    }
    public static void main(String[] args) {
        System.out.println(larger(5, 4));
    }
}关于Larger的反思:
- 在Java中,函数必须作为类的一部分声明。作为类一部分的函数称为“方法”
 - 要在Java中定义一个函数,我们使用 
public static。我们稍后会看到定义函数的其他方法 - 函数的所有参数都必须有一个声明的类型,函数的返回值也必须有一个声明的类型。Java中的函数只返回一个值!
 
面向对象编程回顾
- 一种组织程序的模型
- 模块化: 定义每个部分而不必担心其他部分,它们都能一起工作
 - 数据抽象: 你可以与对象交互而不必知道它是如何实现的
 
 - 对象
- 对象将信息和相关行为捆绑在一起
 - 每个对象都有自己的本地状态
 - 几个对象可能都是某个共同类型的实例
 
 - 类
- 类作为其所有实例的模板
 - 每个对象都是某个类的实例
 
 
Python、Java和C++中的类
Python:
class Car:
    def __init__(self, m):
        self.model = m
        self.wheels = 4
    def drive(self):
        if self.wheels < 4:
            print(self.model + " no go vroom")
            return
        print(self.model + " goes vroom")
    def getNumWheels(self):
        return self.wheels
    def driveIntoDitch(self, wheelsLost):
        self.wheels = self.wheels - wheelsLost
c1 = Car("Civic Type R")
c2 = Car("Porsche 911")
c1.drive()
c1.driveIntoDitch(2)
c1.drive()
print(c2.getNumWheels())Java:
public class Car {
    public String model;
    public int wheels;
    public Car(String m) {
        this.model = m;
        this.wheels = 4;
    }
    public void drive() {
        if (this.wheels < 4) {
            System.out.println(this.model + " no go vroom");
            return;
        }
        System.out.println(this.model + " go vroom");
    }
    public int getNumWheels() {
        return this.wheels;
    }
    public void driveIntoDitch(int wheelsLost) {
        this.wheels = this.wheels - wheelsLost;
    }
    public static void main(String[] args) {
        Car c1 = new Car("Porsche 911");
        Car c2 = new Car("Toyota Camry");
        c1.drive();
        c1.driveIntoDitch(2);
        c1.drive();
        System.out.println(c2.getNumWheels());
    }
}C++:
#include <iostream>
using namespace std;
class Car {
public:
    string model;
    int wheels;
    Car(string m) {
        this->model = m;
        this->wheels = 4;
    }
    void drive() {
        if (this->wheels < 4) {
            cout << this->model << " no vroom." << endl;
            return;
        }
        cout << this->model << " vroom." << endl;
    }
    int getNumWheels() {
        return this->wheels;
    }
    void driveIntoDitch(int wheelsLost) {
        this->wheels = this->wheels - wheelsLost;
    }
};
int main() {
    Car* c1 = new Car("Toyota Camry");
    Car* c2 = new Car("Porsche 911");
    c1->drive();
    c1->driveIntoDitch(2);
    c1->drive();
    c2->drive();
    cout << c2->getNumWheels() << endl;
    delete c1;
    delete c2; // 避免内存泄漏
    return 0;
}面向对象编程回顾
- 一种组织程序的模型
- 模块化: 定义每个部分而不必担心其他部分,它们都能一起工作
 - 数据抽象: 你可以与对象交互而不必知道它是如何实现的
 
 - 对象
- 对象将信息和相关行为捆绑在一起
 - 每个对象都有自己的本地状态
 
 
写在最后
作为一名中国学生,当我接触到CS61B的课程内容时,不禁感慨万千。这样的课程,才是计算机专业学生真正应该学习的内容。相比之下,国内许多课程却过于专注于语法细节和机械化的应试训练,缺乏对计算机科学本质的深入探索。这让我时常思考:为什么大学教育总是被批评为与社会生产脱节?其实,问题的根源在于教学内容的停滞不前。
在国内,课程内容的陈旧并非偶然。一方面,改变课程大纲意味着教师需要重新设计教学方案,这无疑增加了备课的难度和工作量;
另一方面,学生也可能因为内容难度的提升而面临更高的挂科风险。因此,许多学校和教师选择维持现状,继续沿用那些陈旧的知识体系。这种“路径依赖”导致了多年来大学课程内容的固化,甚至与时代需求渐行渐远。
这也是我选择深入学习公开课的原因之一。通过接触像CS61B这样注重理论与实践结合的课程,我希望能够弥补国内教育的不足,真正理解计算机科学的核心思想和实际应用。这种学习不仅是对个人能力的提升,更是对教育现状的一种反思和回应。
