Skip to content

CS61B Lecture 1: Java 初探与课程概览

Lecturers: Kay Ousterhout, Josh Hug
Date: 2026 春季学期 (Spring 2026)
Website: sp26.datastructur.es

欢迎来到 CS61B! 🎉

如果说 CS61A 是教你如何使用列表(List),那么 CS61B 就是教你如何从零开始制造一个列表。我们要像造车一样,深入引擎盖底下,去理解数据结构是如何运作的。

准备好从 Python 的舒适区跳进 Java 的严谨世界了吗?Let's go! 🚀


1. 课程概览:我们在学什么?(Welcome to 61B)

抽象的层级 (Layers of Abstraction)

在 CS61A 中,你习惯了这种"魔法":

python
python
x = [3, 4, 5]
x.append(6)

你不需要知道 append 是怎么工作的,你只需要知道它能把 6 加进去。这就叫抽象

但在 CS61B,我们要打破砂锅问到底:这玩意儿在底层到底是怎么实现的? 🤯

我们将花费前 5 周的时间,探索实现列表(List)的两种截然不同的选择。这不仅仅是关于代码,更是关于:

  • 效率 (Efficiency): 如何写出跑得快的代码?
  • 数据结构 (Data Structures): 好的数据结构是程序的基石。
  • 算法 (Algorithms): 解决问题的聪明办法。

为什么是 Java? ☕️

我们要从 Python 迁移到 Java。我知道你可能在想:"Python 写得好好的,人生苦短,我用 Python,为什么要换?"

  1. 速度: Java 的运行速度通常比 Python 快得多(它是编译型语言,后面会讲)。
  2. 特性: Java 拥有 Python 缺失的一些特性,比如静态类型 (Static Typing)——这可是大公司的最爱。
  3. 工业标准: 它是世界上最流行的编程语言之一(面试必备!)。

CS 课程体系:

  • 61A (Python) -> 61B (Java) -> 61C (C/Assembly/Go)

这是一个从高层抽象逐渐走向底层的过程。

💡 课程亮点

这门课不仅教你写代码,还会教你工程能力。你将接触到工业级的工具链:Git, IntelliJ IDEA, JUnit, 甚至是如何正确(或尽量少)地使用 LLMs。


2. 课程后勤与生存指南 (Logistics)

课程三个阶段 (The Three Phases) 📅

Phase时间内容特点
Phase 1Week 1-5Java 入门与数据结构基础⚠️ 节奏非常快 (VERY FAST)!只有两周适应期
📝 都是个人作业 (Solo),通过手写 List 来练手
Phase 2Week 6-10数据结构深入 & 软件工程⏱️ 节奏适中
🎯 会有一个设计型项目 (Design Project),你要自己设计架构
Phase 3Week 11-15算法🐌 节奏变慢
👯‍♂️ 主要时间花在最终的结对项目 (Pair Project) 上

分数与评估 (The Points Game) 💯

CS61B 总分 3000 分。并没有强制的分布曲线(Curve),大家不需要互相卷,只需要拿分:

  • 送分题: 周问卷 (Surveys) - 只要做就是满分
  • 基本功: 作业 (HWs), 小项目 (Mini-Projects) - 中位数通常是 100%
  • 重头戏: 设计项目 (Design Projects) - 这才是拉开差距的地方
  • 考试: 目标均分是 65%(别慌,这是正常的)

📅 关键时间点

  • Midterm 1: Week 6 (机考,CBTF) - 主要是写代码
  • Final: 2026/5/12 - 传统的纸笔考试

Clobber Policy: 如果你期中考砸了,期末考得好可以覆盖期中成绩。

关于 AI 与抄袭 (LLMs Policy) 🤖

这是一个 2026 年避不开的话题。

🚫 血的教训

现状: 2025 年秋季的数据显示,许多过度依赖 LLM 的学生在 Midterm 1 惨败(10% 的学生得分低于 10% 😱)。

猜测: 基础不牢,地动山摇。如果你用 AI 跳过了早期的思维训练,后面会还债的。

红线: 严禁直接让 LLM 写你要提交的代码。

建议:

  • 不要使用 IDE 的 AI 插件 (Cursor, Copilot 等)
  • 除非你真的卡住了,否则不要把代码丢给 AI 问 "Where is the bug?"

3. Java 基础特性 (Basic Java Features)

这一部分超级重要!我们将结合官方教材的内容,手把手教你写 Java。

3.1 变量与循环 (Variables and Loops) 🔄

我们先来看一个简单的程序,它会打印 0 到 9 的数字。

java
java
void main() {
    int x; // 1. 变量声明

    x = 0; // 2. 变量赋值
    while (x < 10) { // 3. 循环条件
        IO.print(x + " "); // 4. 打印
        x = x + 1;
    }
}

当你运行这个程序时,你会看到:

bash
bash
$ javac HelloNumbers.java
$ java HelloNumbers
0 1 2 3 4 5 6 7 8 9

小白必须要懂的 4 个细节:

  1. 先声明,后使用: 我们的变量 x 必须在使用前声明,并且必须给它一个类型! (int 表示整数)。
  2. 花括号 {}: 所有的循环体、函数体都必须包在花括号里。
  3. 圆括号 (): while 后面的判断条件必须包在圆括号里。
  4. IO.print: 注意不是 IO.printlnprint 不会换行,所以数字会横着排。

这里的 x + " " 是个小技巧,它把数字和空格拼成了一个字符串,防止数字挤在一起(变成 0123...)。

在这些特性中,最重要的一个是:变量必须有声明的类型

3.2 静态类型的铁律 (Static Typing) 🛡️

Java 是一种 静态类型语言 (statically typed language)。这句话的意思是:

  • 所有变量、参数和方法都必须有一个"户口"(声明类型)。
  • 一旦上了户口,类型永远不能改变

优缺点分析 (Trade-offs)

优点 (The Good) 😍缺点 (The Bad) 😫
更早发现错误: 编译器就像一个严格的质检员,在程序运行前就能抓出类型错误代码啰嗦 (Verbose): 你得不停地写 int, String,手有点累
用户体验好: 既然质检员拦住了错误,你的用户就永远不会遇到"类型不匹配"导致的崩溃不够通用: 想处理小数?对不起,刚才那个 int 的代码不能用,你得重写
易读性: 看到 int x,你就知道 x 肯定是整数,不用猜
效率高: 机器不需要在运行时反复确认"x 到底是个啥",直接算,速度飞快

深度思考:为什么 5 + "horse" 会报错?🐴

让我们来看一个经典的例子。

Java 程序

java
java
public class HelloNumbers {
    public static void main(String[] args) {
        int x = 0;
        while (x < 10) {
            System.out.print(x + " ");
            x = x + 1;
        }
        x = "horse"; // 💥 试图把 "马" 塞进 "整数" 的笼子
    }
}

如果你尝试编译,编译器会直接拒绝你:

HelloNumbers.java:9: error: incompatible types: String cannot be converted to int
        x = "horse";
                ^
1 error

这可是个大好事!这意味着在这个程序真正运行之前,错误就被拦截了。这和 Python 这种动态类型语言完全不同,Python 可能会跑到这一行才崩溃。

🧠 脑力体操 (Extra Thought Exercise)

在 Java 里:

  • String h = 5 + "horse"; ✅ 成功。Java 很聪明,它看到你想把数字和字符串加起来,就猜到你是想拼接字符串。结果是 "5horse"
  • int h = 5 + "horse"; ❌ 失败。你要求结果必须是整数 (int),但"5匹马"显然不是一个数字。编译器为了保护你,报错了。

而在 Python 里,x = 5 + "horse" 会直接报错。因为 Python 不知道你是想把 5 变成字符,还是想把 "horse" 变成数字。

3.3 定义函数 (Defining Functions) 🛠️

在 Python 里,函数定义很随意,想在哪写就在哪写:

python
python
def larger(x, y):
    if x > y:
        return x
    return y

print(larger(8, 10))

但在 Java 里,我们必须守规矩:

java
java
// 函数定义
int larger(int x, int y) {
    if (x > y) {
        return x;
    }
    return y;
}

// 主程序
void main() {
    IO.println(larger(5, 10));
}

观察一下 Java 函数的特点:

  1. 参数有类型: 必须规定 xy 都是 int
  2. 返回有类型: 函数名前面的 int 表示"我承诺这个函数会吐出一个整数"。
  3. 单返回值: Java 函数一次只能吐出一个值。
  4. void main: 这里的 void 意味着 main 函数不返回任何东西。

🧗‍♂️ 精彩比喻:编程就像攀岩

  • Python 就像是 徒手攀岩 (Free-soloing)。速度快,自由自在。但如果你一脚踩空(犯了类型错误),你会直接摔死(程序崩溃)。
  • Java 就像是 全副武装的攀岩。你有绳索、头盔、安全带(这些就是静态类型检查)。虽然穿装备很麻烦(代码写起来啰嗦),但如果你失误了,绳子会拉住你(编译器报错),救你一命。

当你构建大型软件(爬高山)时,你会感谢这些绳索的。

3.4 代码风格、注释与 Javadoc 🎨

新手往往只在乎"代码能不能跑",但高手更在乎"代码长得好不好看"。

黄金法则:

写代码时要让陌生人也能轻松理解。 (Write your code so that it is easy for a stranger to understand.)

我们甚至愿意牺牲一点点运行速度,来换取代码的可读性。

Javadoc 注释规范

在 Java 里,我们有一种特殊的注释格式叫 Javadoc,以 /** 开头(注意有两个星号)。

java
java
public class LargerDemo {
    /** Returns the larger of x and y. */  // <--- 这就是 Javadoc
    public static int larger(int x, int y) {
        if (x > y) {
            return x;
        }
        return y;
    }

    public static void main(String[] args) {
        System.out.println(larger(8, 10));
    }
}

这种注释不仅仅是给人看的,还可以被工具读取,自动生成漂亮的 HTML 文档网页。


4. Java 工作流 (Java Workflow) ⚙️

在 Python 里,你写完代码直接运行。但在 Java 里,从代码到运行需要两步走

mermaid

1. 编译 (Compilation)

  • 命令: javac HelloNumbers.java
  • 作用: 检查语法错误,把代码翻译成机器更容易读懂的 .class 文件
  • 产物: HelloNumbers.class

2. 解释/运行 (Interpretation)

  • 命令: java HelloNumbers
  • 作用: 启动 Java 虚拟机 (JVM),运行 .class 文件

为什么要有个 .class 文件?

  • 安全: 经过了类型检查,更难出错
  • 速度: 机器读 .class 比读源代码快得多
  • 保护: 别人拿到了软件,但不一定能直接看到你的源代码

IntelliJ IDEA 🛠️

虽然我们在上面演示了用命令行 (javac, java) 来操作,但在实际课程中,我们会使用 IntelliJ IDEA

它是一个强大的集成开发环境(IDE),它会在后台自动帮你完成编译和运行的步骤,你甚至感觉不到 .class 文件的存在。

它还会像个贴身教练一样,在你打字的时候就提醒你哪里写错了。


5. 作业提醒 (Homework) 📝

⏰ 本周作业

  • HW 1: 配置环境。安装 Java, IntelliJ。
  • HW 2: Java 语法练习。把 Python 翻译成 Java。

Deadline: 都在 本周五

建议: 尽早开始,配置环境可能会遇到各种奇葩问题。


祝大家在 CS61B 的第一周过得愉快!Happy Coding! 💻🎉

版权所有 © 2025-至今 赵熠楷(Yikai Zhao)