名校公开课 / 斯坦福 / 经典

编程范式

Programming ParadigmsCS107斯坦福2008 (SEE)免费
C 语言内存模型汇编并发SchemePython

这门课学什么

课程讲程序在底层怎样运行:C 指针与内存布局、简化汇编模型、线程与信号量并发,再讲 Scheme 函数式编程和 Python。

内容摘要

这门课讲程序在机器层面怎样运行,然后横向比较几种编程范式。2008 年版共 27 讲,先修课是 CS106B。讲师 Jerry Cain 习惯在黑板上画内存图,把每个字节放在哪里讲得很具体。

第 1 阶段(第 1–8 讲)讲 C 语言和内存:整数的位表示、字节序、结构体和指针运算。然后用 void* 写通用的 swap、lsearch 和栈,最后讲堆分配器怎样管理内存。第 2 阶段(第 9–14 讲)用一个简化的汇编模型,讲 C 和 C++ 代码怎样翻译成机器指令。内容包括栈帧、函数调用、预处理、编译和链接。

第 3 阶段(第 15–18 讲)讲并发:线程、信号量、竞争条件和死锁。这部分用售票、哲学家就餐、冰淇淋店 3 个模拟例子展开。第 4 阶段(第 19–27 讲)讲函数式编程:Scheme 的递归、map、lambda 和内存模型。之后讲 Python 的多范式写法和 XML 处理,最后一讲是 Haskell 客座讲座。

课程有 8 个编程作业:RSG 随机句子生成器、Six Degrees 六度分隔、通用 Vector 和 HashSet、RSS 新闻搜索、Raw Memory、多线程版 RSS、Where am I? 和 Python 作业。作业规模明显大于 CS106 系列。学完后,你能看懂指针和内存错误的根源,能写多线程 C 程序,也能用函数式风格思考问题。

为什么值得学

Jerry Cain 把内存和调用栈讲得非常具体。在一门课里对比多种编程范式,在入门课程中少见。

课程信息

学校
斯坦福(Stanford)
课程号
CS107
讲师
Jerry Cain
学期
2008 (SEE)
平台
Stanford Engineering Everywhere
费用
免费
难度
中级
学时
27 讲
先修
需要 CS106B 程度的编程基础。
材料
视频、讲义、作业、考试
许可证
CC BY-NC-SA 4.0(SEE 站声明)
去课程主页 ↗看视频 ↗
课程是英文的。本页的介绍、摘要和大纲由极客教育原创撰写,讲次标题为中文意译。开课时间、收费和链接以官方页面为准。

课程大纲 · 共 27 节

大纲依据:SEE 2008 版讲次列表(27 讲,按每讲 Topics 概括)(查看原始页面 ↗)

  1. 1
    课程导论与编程范式概览Course Overview and Programming Paradigms

    介绍课程安排和评分。预告本课涉及的语言,并区分过程式范式和面向对象范式。

  2. 2
    数据表示:位、字节与补码Data Representation: Bits, Bytes and Two's Complement

    讲 char、short、int 在内存中的位模式。讲负数的表示和补码加法。

  3. 3
    类型转换、字节序、结构体与数组Type Conversion, Endianness, Structs and Arrays

    用指针强制转换观察不同类型的位模式。讲大端与小端、结构体布局和数组的指针运算。

  4. 4
    C 的泛型编程:void* 与 swapGeneric Programming in C: void* and swap

    用 void* 和 memcpy 写任意类型的 swap。比较 C 泛型和 C++ 模板,并列出误用 swap 的错误。

  5. 5
    通用线性查找Generic Linear Search

    写泛型 lsearch 和比较函数。用 C 字符串数组练习指向指针的指针。

  6. 6
    通用栈的实现Generic Stack Implementation

    先写 int 栈,并用 realloc 扩容。再把它改写成任意类型的泛型栈。

  7. 7
    内存所有权与释放函数Memory Ownership and Free Functions

    讨论栈中元素指向的堆内存由谁释放。给栈加入释放函数,并分析常见错误。

  8. 8
    堆内存管理Heap Management

    讲堆怎样记录每次分配的大小、怎样管理空闲块。讲错误 free 的后果和选择空闲块的策略。

  9. 9
    从 C 到汇编:读取、存储与跳转From C to Assembly: Loads, Stores and Branches

    用一个简化汇编模型翻译 C 代码。讲 load、store、ALU 运算,以及 for 循环怎样翻译成跳转指令。

  10. 10
    活动记录与函数调用Activation Records and Function Calls

    讲函数调用时栈帧的布局。讲参数入栈、返回地址和 call 指令。

  11. 11
    C++ 的代码生成:引用与方法Code Generation for C++: References and Methods

    比较指针版和引用版 swap 的汇编。说明引用就是自动解引用的指针。

  12. 12
    预处理器与宏The Preprocessor and Macros

    讲 #define 和带参数的宏。讲 assert 宏的实现,以及发布版怎样去掉断言。

  13. 13
    编译与链接Compilation and Linking

    讲源文件怎样变成 .o 文件。讲缺少函数原型时 gcc 的推断和链接器的行为。

  14. 14
    内存错误与栈Memory Bugs and the Stack

    用数组越界覆盖返回地址的例子讲栈的布局。演示两个函数意外共享数据的现象。

  15. 15
    并发入门:线程Introduction to Concurrency: Threads

    用售票例子从顺序程序转到多线程程序。介绍线程接口和时间片。

  16. 16
    信号量与竞争条件Semaphores and Race Conditions

    用信号量保护售票程序的临界区。讲竞争条件,以及线程切换时栈和寄存器怎样保存。

  17. 17
    哲学家就餐问题与死锁Dining Philosophers and Deadlock

    把每个哲学家建模成线程,展示死锁怎样产生。用信号量限制同时就餐人数来消除死锁。

  18. 18
    冰淇淋店模拟(客座讲座)Ice Cream Store Simulation (Guest Lecture)

    用顾客、收银员、店员、经理 4 类线程模拟冰淇淋店。讲多类线程之间的同步约束。

  19. 19
    函数式编程入门:SchemeIntroduction to Functional Programming: Scheme

    对比命令式、面向对象和函数式范式。介绍 Scheme 和 Kawa 环境,写第一个 Scheme 函数。

  20. 20
    Scheme 中的递归与类型检查Recursion and Type Checking in Scheme

    用 car/cdr 递归处理列表。比较运行时类型检查和编译时类型检查。

  21. 21
    在列表上映射函数Mapping Functions over Lists

    讲 Kawa 环境的使用和 map 操作。把函数映射到嵌套列表和多个列表上。

  22. 22
    幂集、lambda 与 letPower Set, Lambda and Let

    用 lambda 和 map 写递归的幂集函数。用 let 绑定减少重复递归。

  23. 23
    Scheme 的内存模型The Scheme Memory Model

    讲 Scheme 怎样在底层构造链表。比较有内存别名和无别名的两种布局,并讲可变参数函数。

  24. 24
    Python 入门Introduction to Python

    介绍 Python 作为多范式脚本语言的特点。讲动态类型、缩进和基本语句。

  25. 25
    Python 的多种范式与字典Python Paradigms and Dictionaries

    用 Python 同时以 3 种范式重写 RSG。讲 Python 对象和字典的实现。

  26. 26
    用 Python 处理 XMLXML Processing in Python

    比较两种 XML 处理模型。用 Python 解析网络上的 RSS 源。

  27. 27
    客座讲座:HaskellGuest Lecture: Haskell (Sasha Rush)

    介绍 Haskell 的历史、类型系统和惰性求值。用一行代码写出斐波那契数列。

斯坦福的其他经典课