视频封面

视频元信息

  • 时长:约 1 小时(转录内容覆盖 Lecture 0 完整课堂)
  • 课程:CS50x Introduction to Computer Science(哈佛大学计算机科学导论)
  • 讲师:David Malan(大卫·马兰)
  • 主题:第 0 讲——Scratch(计算机科学基础、二进制、算法、编程入门)

内容摘要(TL;DR)

本讲从 AI 与编程的关系切入,介绍了计算机科学的核心——问题求解(输入→算法→输出)。通过灯泡演示讲解了二进制、ASCII/Unicode 编码、颜色与图像/视频/声音的表示方式,并用电话簿查找例子引出算法效率。最后通过 Scratch 图形化编程,展示了函数、条件、循环、变量、抽象等核心编程概念,并以学生作品(Oscar Time、Ivy's Hardest Game)收尾。

1. 开场:AI 与编程的关系 [130.8s~280s]

1.1 AI 正在改变编程,但基础依然重要

  • AI 对编程的影响:AI 已经并将在未来几年持续改变编程方式。现在可以用 AI 帮助解决代码中的 bug,甚至直接告诉 AI 你想添加什么功能。
  • 人类曾是瓶颈:过去几十年,人类是编程的瓶颈——一天只有那么多小时,团队只有那么多人,但想解决的 bug 和想实现的功能无穷无尽。
  • CS50 的真正目标:CS50 不是教你“如何编程”,编程只是副作用。真正的目标是教你如何思考——如何获取输入并产生正确的输出,掌握这些工具。
  • 理解:这类似于数学中学习多种求导方法,最终掌握思想后可以借助 AI(copilot)来执行具体计算。

1.2 现场演示:用 Python + OpenAI API 写一个聊天机器人 [285s~730s]

  • 在 VS Code(CS50 版本)中编写 chat.py,使用 from openai import OpenAI 创建客户端。
  • 调用 client.responses.create,传入 model="GPT-5" 和 input="In one sentence, what is CS50?"。
  • 运行 python chat.py,程序返回 CS50 的介绍。
  • 改进:使用 input() 让用户输入任意问题,存入变量 prompt,实现动态提问。
  • 进一步改进:引入 system prompt(系统提示),例如 limit your answer to one sentence,这样用户无需每次手动强调。
  • 趣味示例:将系统提示改为 pretend you're a cat,AI 的回答会带上猫的风格。
  • 关键结论:用大约 10 行代码就能构建自己的 AI 聊天机器人,这体现了编程的强大能力,也说明理解底层原理的重要性。

1.3 橡皮鸭调试法(Rubber Duck Debugging)与 CS50 的 AI 工具 [750s~850s]

  • 编程圈传统:在桌上放一只橡皮鸭(或任何可爱物品),当遇到 bug 时向它解释你的代码。通过把问题说出来、理清思路,常常能自己发现错误。
  • CS50 提供虚拟鸭子:cs50.ai(内置在 cs50.dev 中)。课程允许并且鼓励使用 CS50 自己的 AI 工具,但不允许使用 ChatGPT、Gemini 等其他 AI 软件(除非课程明确允许)。
  • 虚拟鸭子的设计目标:像一位好的人类导师,知道 CS50 内容,引导你找到解决方案,而不是直接剧透答案。

易错点/规定:CS50 课程只允许使用 cs50.ai 的 AI 工具,使用其他 AI(如 ChatGPT、Gemini、Claude)是不被允许的(除非作业另行说明)。

2. 计算机科学是什么?问题求解的核心模型 [856s~915s]

  • 计算机科学 = 信息的研究:如何表示信息、如何处理信息。
  • 计算思维(Computational Thinking):将计算机科学的理念应用于现实世界的一般问题。
  • 问题求解的抽象模型:
    • 输入(Input):要解决的问题
    • 输出(Output):期望的解决方案
    • 黑箱(Black Box):中间的“秘密酱料”,即算法
  • 理解:这个模型贯穿整个课程,所有编程都是围绕“输入→处理→输出”展开。

3. 二进制:计算机如何表示数字 [920s~1135s]

3.1 从十进制到二进制

  • 计算机底层只用 0 和 1(二进制),这是它们的“字母表”。
  • 十进制(Base-10):有 10 个数字(0~9),每一位代表 10 的幂(个位=10⁰,十位=10¹,百位=10²……)。例如 123 = 1×100 + 2×10 + 3×1。
  • 二进制(Base-2):只有 0 和 1,每一位代表 2 的幂(个位=2⁰=1,二位=2¹=2,四位=2²=4,八位=2³=8……)。
  • 用手指数数演示:只用一只手,二进制可以数到 31(因为 5 个手指,2⁵=32 种组合,包含 0)。模式比数量更重要——手指的“位置/模式”代表不同权重。

3.2 灯泡与晶体管

  • 灯泡关 = 0,灯泡开 = 1。计算机内部有数百万个微小开关——晶体管(transistors),通过控制电流通断来表示 0 和 1。
  • 为什么用二进制? 电要么流动要么不流动,区分“开/关”比区分 10 个电压等级简单可靠得多。
  • 用多个灯泡可以表示更大的数:3 个灯泡(3 bits)可以表示 0~7;4 bits 表示 0~15。

3.3 字节与常用单位

  • 位(bit):一个二进制数字(0 或 1)。
  • 字节(byte):8 个 bit 组成一个字节。8 bits 可以表示 0~255,共 256 种可能。
  • 常见单位:KB(千字节)、MB(兆字节)、GB(吉字节)、TB(太字节)等,都是基于字节的倍数。
  • 256 这个数字很常见:因为 2⁸=256,旧电脑只能显示 256 种颜色,某些图像格式也只支持 256 色。
  • 32 位与 64 位:32 bits 可以数到约 40 亿(2³²≈4 billion),若要表示负数则约 20 亿;现代电脑/手机普遍使用 64 bits(2⁶⁴)。
  • 溢出问题:如果没有足够的位来存储更高的数,计数可能会意外回到 0(如 7 之后变 0)。理解:这就是现实世界中很多程序 bug 的根源之一。

易错点:二进制中每一位的权重是 2 的幂(从右往左:1, 2, 4, 8, 16, 32, 64, 128……),不是 10 的幂。计算二进制数时,只需将对应位为 1 的权重相加。

4. 字符编码:从数字到字母 [930s~1400s]

4.1 ASCII 码

  • 计算机存储字母的方式:给每个字符分配一个整数编号。
  • ASCII(美国信息交换标准代码):早期标准,用 7 位或 8 位表示字符。
    • 大写 A = 65,B = 66,C = 67……
    • 小写 a = 97,b = 98,c = 99……
  • 规律:小写字母比对应大写字母大 32。例如 'a'(97) - 'A'(65) = 32。所以将大写转小写只需将二进制中 32 那一位从 0 改为 1。
  • 示例:二进制 01001000 01001001 00100001 = 十进制 72 73 33 = ASCII 字符 'H' 'I' '!',即 "HI!"。
  • 课堂互动:8 位学生上台分别代表 128、64、32、16、8、4、2、1 位,通过举手(1)或不举手(0)拼出单词。最终拼出 "BOW"(B=66, O=79, W=87)。

4.2 Unicode 与 Emoji

  • ASCII 的局限:只能表示 256 个字符,不够覆盖所有人类语言(如带重音的字符、亚洲文字等)。
  • Unicode:ASCII 的超集,使用更多位(16、24、32 位等),可表示超过 40 亿个字符。
  • Emoji 也是字符:它们本质上是 Unicode 编码的字符,只是显示为彩色图形字体。
  • 示例:😂(Face with Tears of Joy)的 Unicode 码点是十进制的 4,036,991,106(约 40 亿),不同的平台(Apple、Google、Telegram)对同一个码点有不同的图形渲染。
  • 理解:Emoji 的跨平台差异就像不同字体显示同一个字母,底层数据相同,只是“字体”不同。

5. 颜色、图像、视频与声音的表示 [1400s~1800s]

5.1 RGB 颜色模型

  • 颜色也可以用数字表示:使用 RGB(红绿蓝) 三色混合。
  • 每种颜色用 1 个字节(0~255)表示强度:红、绿、蓝各 8 bits,共 24 bits(3 字节)。
  • 示例:RGB(72, 73, 33) 在文本上下文中是 "HI!",但在图像上下文中是一种暗黄色。
  • 黑色 = RGB(0,0,0);白色 = RGB(255,255,255)。
  • 十六进制表示(如 #000000、#FFFFFF)是另一种基系统,之后课程会讲到。

5.2 图像与像素

  • 图像由 像素(pixels) 组成,每个像素有独立的颜色。
  • 每个像素颜色需要 3 字节(RGB),所以大图像文件自然以 MB 计。
  • 同一个二进制模式,在不同软件中解释不同:在文本编辑器里是字母,在 Photoshop 里是颜色,在播放器里是视频/声音。上下文决定解释方式。

5.3 视频

  • 视频 = 一系列快速播放的图像(如每秒 30 帧),利用视觉暂留产生运动错觉。
  • 这就是“电影”(motion pictures)的由来——快速翻动的图片。

5.4 声音

  • 声音可以用数字表示:频率(音高)、持续时间(时长)、振幅(响度) 等参数。
  • 例如每个音符用三个数字表示(频率、时长、音量),接收方按约定解释就能还原音乐。

5.5 课堂问答

  • 问:计算机如何区分字母 65 和数字 65? 答:取决于上下文(context)。程序员或软件决定如何解释这些 0 和 1——是显示为数字还是字母还是颜色。
  • 理解:这体现了“数据”与“元数据/解释”的分离,也是编程中类型系统存在的原因之一。

6. 算法与效率:电话簿查找问题 [1800s~2200s]

6.1 问题:在电话簿中找 John Harvard

  • 三种算法:
    1. 从第一页开始逐页查找:正确但慢(最多 1000 页)。
    2. 每两页一翻:快一倍,但可能跳过目标(需要回退一页检查)。
    3. 从中间开始,每次排除一半:每次将问题规模减半,效率最高。

6.2 算法效率的图形化

  • 横轴:问题规模(页数 n),纵轴:时间(秒/翻页次数)。
  • 算法 1:y = n(线性,直线)。
  • 算法 2:y = n/2 + 1(线性,但斜率更小)。
  • 算法 3:y = log₂(n)(对数曲线,增长非常缓慢)。
  • 关键结论:当问题规模翻倍(1000→2000 页),线性算法时间也翻倍,但对数算法只需多一步。
  • 计算机科学/良好设计 = 不仅要正确,还要高效,要考虑时间、CPU、内存、成本等资源约束。

考点:算法效率的比较——线性 O(n) vs 对数 O(log n)。二分查找(每次减半)是对数时间,远快于线性查找。

7. 伪代码与编程基础概念 [2200s~2600s]

7.1 电话簿算法的伪代码

1  拿起电话簿
2  翻开电话簿的中间
3  看这一页
4  如果 John Harvard 在这一页
5      打电话给他
6  否则如果 John Harvard 在书的前半部分
7      打开左半部分的中间
8      回到第 3 行
9  否则如果 John Harvard 在书的后半部分
10     打开右半部分的中间
11     回到第 3 行
12 否则
13     放弃(John Harvard 不在电话簿里)
  • 为什么可以循环回到第 3 行? 因为每次问题规模都在减半,最终会缩小到一页或空。
  • 遗漏的 corner case:如果 John Harvard 根本不在电话簿里,程序会无限循环或未定义行为。必须处理“找不到”的情况。
  • 理解:计算机死机/卡死往往是因为程序员没有预料到某些边界情况,导致软件进入未定义状态。

7.2 核心编程术语

  • 函数(Functions):动词/动作,完成一小块工作。
  • 条件(Conditionals):岔路口,决定走哪条路。
  • 布尔表达式(Boolean Expressions):只能回答“是/否”、“真/假”、“1/0”的问题,以数学家布尔命名。
  • 循环(Loops):重复执行某些操作。
  • 理解:这些概念构成了所有编程语言(Scratch、C、Python 等)的共同基础。

8. 从机器码到高级语言:抽象的力量 [2600s~2800s]

  • 计算机只懂 0 和 1(机器码)。早期人类直接用二进制编程(如打孔卡),非常繁琐。
  • 编译器(Compiler):把高级语言翻译成机器码的程序。
  • 层级示例:
    • 机器码:01101000 01100101 01101100 01101100 01101111(打印 "hello, world")
    • C 语言:printf("hello, world");
    • Python:print("hello, world")
  • 抽象(Abstraction):我们可以站在前人的肩膀上,使用别人封装好的高级功能,而不必关心底层实现。例如 OpenAI API 封装了复杂的模型推理,我们只需几行代码就能调用。
  • CS50 的教学路线:Scratch → C → Python → SQL → HTML/CSS/JavaScript,逐步从图形化到文本化,理解不同层次的抽象。

9. Scratch 入门:第一个程序 [2800s~3600s]

9.1 Scratch 环境介绍

  • Scratch 是 MIT 媒体实验室开发的图形化编程语言(约 20 年前),适合初学者。
  • 界面组成:
    • 积木区(Blocks Palette):各种彩色积木,按功能分类(事件、控制、外观、声音、侦测、运算等)。
    • 编程区(Programming Area):拖拽积木拼接代码。
    • 角色区(Sprites):默认是一只猫,可更换角色。
    • 舞台(Stage):角色活动的二维世界,有坐标系(x, y),中心为 (0,0),x 范围约 -240~240,y 范围约 -180~180。

9.2 第一个 Scratch 程序:说 Hello World

  • 使用 当绿旗被点击(事件)+ 说 Hello World(外观)积木。
  • 点击绿旗运行,点击红色停止按钮停止。
  • 函数与参数:说 积木是一个函数,白色椭圆框是它的输入(参数/argument)。
  • 副作用(Side Effect):屏幕上出现对话气泡就是副作用——程序运行产生的可见/可听效果。

9.3 让程序交互:询问名字

  • 使用 询问 What's your name? 并等待(侦测)积木,它会返回一个值。
  • 返回值(Return Value):函数返回给程序的值(存储在 回答 变量中),人看不到,但程序可以使用。
  • 用 连接 hello, 和 回答 积木拼接字符串。
  • Bug 演示:如果直接放两个 说 积木,会看到先显示 "hello" 再显示名字,因为程序执行太快,人眼来不及看到。解决办法:使用 等待 1 秒 积木,或者用 连接 积木一次性输出。
  • 理解:这个例子展示了“程序执行顺序”和“人眼感知速度”的差异,以及如何通过组合函数解决小问题。

9.4 声音与循环:让猫叫三次

  • 使用 播放声音 Meow 直到播放完毕 积木。
  • 最初复制粘贴三次,代码冗余;改用 重复 3 次 循环,并在每次之间加 等待 1 秒。
  • 代码质量:复制粘贴是坏味道,应该用循环/函数抽象公共逻辑。

9.5 自制积木(函数抽象)

  • 使用 制作新的积木 创建自定义的 喵 积木,内部封装“播放声音 + 等待”。
  • 更进一步:给 喵 积木添加输入参数 n(次数),内部用 重复 n 次 实现。
  • 抽象的好处:使用方只需调用 喵(3),不需要关心内部实现;修改内部实现不影响外部调用。
  • 理解:这就是“封装”和“模块化”——把复杂细节隐藏,提供简单接口,是软件工程的核心思想。

9.6 条件与事件:宠物猫

  • 使用 重复执行(forever)+ 如果 碰到鼠标指针? 条件积木,实现“鼠标碰到猫时猫叫”。
  • 演示 Bug:如果忘了 重复执行,程序只检查一次,之后移动鼠标无效——因为程序已经执行完了。
  • 理解:需要“持续监听”事件时,必须用循环包裹条件判断。

10. 综合案例:Oscar Time 游戏 [3600s~4500s]

10.1 游戏目标与实现

  • 学生作业:把掉落的垃圾拖到 Oscar 的垃圾桶里,音乐结束前得分。
  • 实现步骤:
    1. 舞台背景:画一个灯柱(静态背景)。
    2. 角色:把猫换成垃圾桶(用不同造型切换实现动画——盖子打开/关闭)。
    3. 垃圾角色:从顶部随机 x 位置出现,y 固定 180,不断向下移动(将 y 坐标增加 -1)。
    4. 拖拽:设置 将拖动模式设为可拖动,玩家可以拖动垃圾。
    5. 得分:如果垃圾碰到 Oscar,则“传送”回顶部(重新掉落),并 将 分数 增加 1。
    6. 音乐同步:用 等待 积木精确控制不同垃圾的出现时间,与歌曲节奏匹配。

10.2 代码演进(Oscar 0→4)

  • Oscar 0:只有背景和角色,无代码。
  • Oscar 1:Oscar 角色检测鼠标,切换盖子开/关造型。
  • Oscar 2:垃圾角色实现掉落和拖拽,碰到 Oscar 后回到顶部。
  • Oscar 3:发现重复代码(两处“回到顶部”),创建自定义积木 回到顶部 来消除重复。
  • Oscar 4:添加 分数 变量,碰到时加分。

10.3 设计教训

  • 先解决小问题:不要一开始就想着完整游戏,先做背景,再做角色,再添加交互,逐步迭代。
  • 避免复制粘贴:公共逻辑应提取为函数/积木,便于修改和复用。
  • 数学坐标很有用:理解舞台坐标系(x, y)才能实现“从天空掉落”“左右移动”等效果。

11. 综合案例:Ivy's Hardest Game [4500s~5200s]

  • 学生前辈实现的游戏,展示更多编程概念:
    • 角色移动:用键盘方向键控制哈佛校徽移动(如果 按下 上箭头 那么 将 y 坐标增加 1)。
    • 墙壁碰撞:检测碰到左墙/右墙,然后反向移动 1 像素(反弹效果)。
    • 敌方角色(Yale):自动来回移动——重复执行 + 碰到墙转向 180 度 + 移动 1 步。
    • 追踪角色(MIT):重复执行 + 面向 哈佛校徽 + 移动 1 步,实现自动追踪。
    • 速度调整:把 移动 1 步 改为 移动 10 步 会让游戏更难,但也可能产生视觉抖动(因为步子太大导致来回摇摆)。
  • 理解:这些游戏机制都可以用最基本的积木组合实现,体现了“组合”和“抽象”的力量。

12. 结尾与课程传统

  • 课程结束时请学生上台玩最终版游戏,获胜后发放蛋糕(CS50 第一节课的传统)。
  • 鼓励学生在课程网站(cs50.dev)上动手实践,使用 Scratch 完成自己的第一个编程作业。

关键标签/关键词

CS50 Lecture 0 Scratch 二进制 ASCII Unicode RGB 算法 二分查找 伪代码 函数 循环 条件 布尔表达式 抽象 编译器 变量 返回值 副作用 AI OpenAI API 橡皮鸭调试法 计算思维


生成时间:2026-09-02 15:37:56 生成平台:VideoNote