▤书架 ← 返回索引
▶目录

阶段 03 讲义

数学 11h:高数 · 导数与微分(一)
编程 9h:循环(for / while)


第一部分 · 数学

1 导数的定义 ⭐

从实际问题来:一辆车走了 $s(t)$ 米,问它在时刻 $t_0$ 的瞬时速度是多少?

平均速度好算:$\frac{\Delta s}{\Delta t} = \frac{s(t_0+\Delta t) - s(t_0)}{\Delta t}$

但"瞬时"意味着 $\Delta t \to 0$。于是:

$$v(t_0) = \lim_{\Delta t \to 0}\frac{s(t_0+\Delta t) - s(t_0)}{\Delta t}$$

这就是导数。

1.1 定义

$$f'(x_0) = \lim_{\Delta x \to 0}\frac{f(x_0+\Delta x) - f(x_0)}{\Delta x}$$

也常写成:

$$f'(x_0) = \lim_{x \to x_0}\frac{f(x) - f(x_0)}{x - x_0}$$

其他记号:$y'$、$\frac{dy}{dx}$、$\frac{df}{dx}$

1.2 几何意义 ★

$$\frac{f(x_0+\Delta x) - f(x_0)}{\Delta x}$$

是割线的斜率。当 $\Delta x \to 0$,割线趋向切线。

所以:导数的几何意义 = 曲线在该点切线的斜率。

这带来两个直观:
- $f'(x_0) > 0$ → 曲线在上升
- $f'(x_0) < 0$ → 曲线在下降
- $f'(x_0) = 0$ → 切线水平(可能是极值点)

1.3 物理意义

导数是变化率:
- 位置 → 速度 → 加速度(速度的导数)
- 任何"某量的变化快慢"都是导数

1.4 用定义求导:完整例子

求 $f(x) = x^2$ 的导数

第一步:写出差商

$$\frac{f(x+\Delta x) - f(x)}{\Delta x} = \frac{(x+\Delta x)^2 - x^2}{\Delta x}$$

第二步:展开分子

$$= \frac{x^2 + 2x\Delta x + (\Delta x)^2 - x^2}{\Delta x} = \frac{2x\Delta x + (\Delta x)^2}{\Delta x}$$

第三步:约掉 $\Delta x$(注意 $\Delta x \ne 0$)

$$= 2x + \Delta x$$

第四步:取极限 $\Delta x \to 0$

$$f'(x) = 2x$$

∎

套路:展开 → 约去 $\Delta x$ → 取极限。
关键在第 2 步到第 3 步:必须先把 $\Delta x$ 约掉,否则取极限会出现 0/0。

1.5 再练一个:$\sqrt{x}$

$$\frac{\sqrt{x+\Delta x} - \sqrt{x}}{\Delta x}$$

分子有理化(乘共轭):

$$= \frac{(\sqrt{x+\Delta x} - \sqrt{x})(\sqrt{x+\Delta x} + \sqrt{x})}{\Delta x(\sqrt{x+\Delta x} + \sqrt{x})} = \frac{\Delta x}{\Delta x(\sqrt{x+\Delta x}+\sqrt{x})}$$

$$= \frac{1}{\sqrt{x+\Delta x}+\sqrt{x}} \xrightarrow{\Delta x\to0} \frac{1}{2\sqrt{x}}$$

技巧:遇到根号,有理化是标准操作。

2 基本求导公式表 ⭐(必须背)

$f(x)$ $f'(x)$
$C$(常数) $0$
$x^n$ $nx^{n-1}$
$\sin x$ $\cos x$
$\cos x$ $-\sin x$
$\tan x$ $\frac{1}{\cos^2 x} = \sec^2 x$
$e^x$ $e^x$
$a^x$ $a^x \ln a$
$\ln x$ $\frac{1}{x}$
$\log_a x$ $\frac{1}{x\ln a}$
$\arcsin x$ $\frac{1}{\sqrt{1-x^2}}$
$\arctan x$ $\frac{1}{1+x^2}$

💡 记忆要点:
- 幂函数:指数降 1,原指数提到前面
- $e^x$ 是唯一"导数等于自己"的函数(这条很重要,后续解微分方程会用到)

3 可导与连续的关系 ⭐

定理:可导 ⟹ 连续(可导更强)

反之不成立:连续不一定可导。

经典反例:$f(x) = |x|$ 在 $x=0$ 处

为什么:用定义算

$$\lim_{\Delta x\to0^+}\frac{|0+\Delta x|-|0|}{\Delta x} = \frac{\Delta x}{\Delta x} = 1$$

$$\lim_{\Delta x\to0^-}\frac{|\Delta x|}{\Delta x} = \frac{-\Delta x}{\Delta x} = -1$$

左右极限不等 → 导数不存在。

几何上:$|x|$ 在 $x=0$ 处有个尖角,切线有"两种方向",不唯一。

⚠️ 常见错误:以为"连续就能求导"。
记住:连续是"不断",可导是"光滑"。

4 微分

定义:$dy = f'(x)\,dx$

意义:当 $x$ 变化 $dx$ 时,$y$ 变化量的线性主部。

几何:微分是切线上的增量,$\Delta y$ 是曲线上的增量。$dx$ 越小时两者越接近。

可微 ⟺ 可导(一元函数中这两件事等价)。

近似计算的应用:

$$f(x_0 + \Delta x) \approx f(x_0) + f'(x_0)\Delta x$$

例:估算 $\sqrt{4.02}$

取 $f(x)=\sqrt{x}$,$x_0=4$,$\Delta x = 0.02$
$f(4)=2$,$f'(x)=\frac{1}{2\sqrt{x}}$,$f'(4)=\frac14$
$\sqrt{4.02} \approx 2 + \frac14 \times 0.02 = 2.005$

真实值 2.004995… ✓ 非常接近


5 数学作业 S3

第 8 题参考代码:

import numpy as np

x0 = 3.0
真实值 = 2 * x0          # f(x)=x² 在 x=3 处的导数 = 6

for h in [1e-2, 1e-4, 1e-6, 1e-8, 1e-10, 1e-12, 1e-15]:
    近似 = ((x0 + h)**2 - x0**2) / h
    print(f"h={h:<8} 近似={近似:<20.10f} 误差={abs(近似 - 真实值):.3e}")

你会看到一张"两头翘"的表,误差先变小、后变大:

$h$ 误差
$10^{-2}$ $10^{-2}$
$10^{-6}$ $10^{-6}$
$10^{-8}$ $\mathbf{4\times10^{-8}}$ ← 最好
$10^{-10}$ $5\times10^{-7}$
$10^{-12}$ $5\times10^{-4}$
$10^{-15}$ $0.67$ ← 彻底崩了

为什么会两头翘:
- h 太大 → 差商本身就是近似的,截断误差大(误差 $\approx h$)
- h 太小 → $(x+h)^2$ 和 $x^2$ 两个数非常接近,相减时前面的有效数字被吃掉了,
剩下的全是噪声,舍入误差大(误差 $\approx \frac{\text{机器精度}}{h}$)

这叫灾难性抵消。最佳 h 在两者相交处,大约 $10^{-8}$。

⚠️ 有一个前提:上面能出现"h 太小反而崩",要求 $f(x_0) \ne 0$。
像上面这样 $f(3)=9 \ne 0$,相减的两个数才真正接近,抵消才会发生。
如果换成在 $x_0=0$ 处测 $\sin x$($\sin 0 = 0$),分子就是 $\sin h - 0$,
没有抵消,h 小到 $10^{-16}$ 也依然准确——现象不会出现。
所以别用那个点做验证,会以为讲义写错了。

💡 意义:这是数值计算的第一课,"把公式直接翻译成代码"经常不work。
后面学数值方法(数值积分、解方程)时会反复遇到这个权衡。


第二部分 · 编程

6 for 循环

最常用的循环,对一堆东西,每个都做一遍。

for i in range(5):
    print(i)
# 输出:0 1 2 3 4(注意:不含 5!)

range() 的三种用法:

range(5)          # 0,1,2,3,4
range(2, 6)       # 2,3,4,5      (含起点,不含终点)
range(0, 10, 3)   # 0,3,6,9      (步长为 3)
range(10, 0, -1)  # 10,9,...,1   (倒着数)

⚠️ range(n) 不含 n。这是最常见的 off-by-one(差一)错误来源。

遍历列表:

fruits = ["苹果", "香蕉", "橙子"]
for fruit in fruits:
    print(f"我喜欢{fruit}")

同时要索引和值(用 enumerate):

for i, fruit in enumerate(fruits):
    print(f"{i}: {fruit}")
# 0: 苹果
# 1: 香蕉
# 2: 橙子

累加模式(非常常见):

total = 0
for i in range(1, 101):
    total += i
print(total)      # 5050

💡 total += i 是 total = total + i 的简写。-= *= /= 同理。

7 while 循环

用于"不知道要循环多少次"的情况。

count = 0
while count < 5:
    print(count)
    count += 1

⚠️ 一定要让条件有机会变假!否则就是死循环。

上面如果忘了 count += 1,程序会永远打印 0。

典型用法:直到满足条件为止

secret = 7
guess = 0

while guess != secret:
    guess = int(input("猜一个数字:"))
    if guess < secret:
        print("小了")
    elif guess > secret:
        print("大了")

print("猜对了!")

8 break 和 continue

关键字 作用
break 跳出整个循环
continue 跳过本次,进入下一次
# break:找到就停
for i in range(1, 100):
    if i * i > 50:
        print(f"第一个平方大于50的是 {i}")
        break
# 输出:第一个平方大于50的是 8

# continue:跳过偶数
for i in range(10):
    if i % 2 == 0:
        continue        # 跳过本次
    print(i)
# 输出:1 3 5 7 9

break 常用在"搜索"场景:

found = False
for x in data:
    if condition(x):
        found = True
        break

9 循环嵌套

for i in range(1, 4):
    for j in range(1, 4):
        print(f"{i}×{j}={i*j}", end="  ")
    print()      # 换行

输出:

1×1=1  1×2=2  1×3=3  
2×1=2  2×2=4  2×3=6  
3×1=3  3×2=6  3×3=9  

print() 不传参数就输出一个换行。
end=" " 表示"输出完不换行,而是加两个空格"。

💡 理解嵌套:外层跑一次,内层跑一整轮。
上面的例子:外层 i 变化 3 次,每次内层 j 都跑 3 次 → 共 9 次。

10 死循环与怎么逃出来 ⚠️

while True:
    print("按 Ctrl+C 才能停下我")

在 Jupyter / 终端里,按 Ctrl + C(Windows 是 Ctrl + C 或 Ctrl + F2)可以中断。

💡 你一定会不小心写出死循环,
知道怎么逃出来才不会被卡住。

合法的死循环(配合 break 使用):

while True:
    cmd = input("输入命令(q 退出):")
    if cmd == "q":
        break
    print(f"执行:{cmd}")

这是"命令行菜单"的标准写法。


11 🔧 技能卡 3:循环出错,怎么查

循环的 bug 有个特点:它跑完了、没报错、但结果不对。这时候没有 traceback 可读,得靠自己。

11.1 四步排查法

① 先确认它到底跑没跑

for i in range(5):
    print("进来了", i)      # ← 如果一行都没打印,说明循环根本没进去

② 把范围缩小再看

把 range(1, 100) 临时改成 range(1, 5),看前几轮到底发生了什么。

💡 这招叫缩小输入,是定位 bug 最有效的手段,也就是阶段 2 学的二分法思想:
每次排除一半,很快锁定问题在哪。小数据看逻辑,大数据看性能。

③ 每轮打印关键变量

total = 0
for i in range(1, 6):
    total += i
    print(f"i={i}  total={total}")     # ← 盯住每一轮的变化

④ 检查边界(off-by-one)

range(5) 只到 4,不含 5。这类"差一"错误是循环里最常见的 bug。

# 想算 1 到 5 的和,这样写漏了 5!
for i in range(5):        # 0,1,2,3,4  ← 少了 5,还多了 0
    total += i

11.2 循环专属的坑

现象 原因
循环体一次都没执行 条件一开始就是假;或 range 是空的
少算/多算一次 off-by-one,range 不含终点
死循环卡住 while 的条件永远为真;按 Ctrl+C 退出
累加结果不对 累加变量忘了初始化(total = 0 写在循环外)

⚠️ 最容易犯的:累加变量初始化写在了循环里面。

for i in range(1, 6):
    total = 0        # ❌ 每轮都被清零,最后只剩最后一个数
    total += i

初始化必须在循环外面。


12 🧠 这跟认知科学有什么关系

概念性内容,无法用代码验证,请对照文献。

导数 ↔ 学习曲线的"进步速度"。

把"练习次数"当自变量 $x$,"成绩"当因变量 $f(x)$,那么导数 $f'(x)$ 就是"进步速度"。

技能习得有个著名规律:进步速度随练习递减。也就是说:

$$f'(x) \text{ 本身在减小} \quad\Longleftrightarrow\quad f''(x) < 0$$

也就是说,学习曲线的形状是"先陡后平",开头涨得快,后来越来越平。

怎么在图上认出来:曲线像一个拱形(∩),越往右越平。
阶段 7 会给它一个正式名字(凹凸性),注意那个名字在不同教材里叫法相反,
到时我会专门提醒。现在你只要记住形状:先陡后平。

这解释了"边际收益递减":练习当然有用,只是同样的练习量,带来的提升越来越小。
这个现象在你自己身上就能观察到:第 1 小时学打字进步巨大,第 100 小时几乎看不出变化。

💡 对你有实际用处:既然学习曲线是先陡后平,那"每天 1 小时 × 7 天"和"7 小时 × 1 天"
在同一个阶段效果接近,但间隔重复能让曲线整体上移(记忆保持更久)。
这就是后面要讲的"分散练习优于集中练习"。

数值差分 ↔ 实验数据求变化率。

实验测出来的曲线是离散的点(每次试验一个数据点),没有解析表达式。
想求它的变化率,只能像第 8 题那样用差分近似导数——这就是科研里"算梯度"的实际做法。

⚠️ 诚实说明:上面"学习曲线先陡后平"是经验规律 + 常见模型(幂律、指数模型),
不是从公理推出的定理。不同任务、不同被试,曲线形状会变。
数学部分($f''<0$ 意味着导数递减)我能保证;认知部分请以文献为准。


13 编程作业 S3

第 8 题的代码(先别跑,先自己读出来错在哪):

for i in range(1, 11):
    total = 0
    total += i * i
print(total)

正确答案是 385。读完之后再跑一遍验证你的判断。

第 3 题提示(素数判断):

for n in range(2, 101):
    is_prime = True
    for d in range(2, n):
        if n % d == 0:
            is_prime = False
            break        # 找到一个因子就够了
    if is_prime:
        print(n, end=" ")

第 7 题提示:

a, b = 1, 1        # 一行同时给两个变量赋值
for _ in range(20):
    print(a, end=" ")
    a, b = b, a + b

a, b = b, a + b 是 Python 的优雅写法:
等号右边的两个值先全部算好,然后才赋给左边。
所以这里不需要临时变量,a + b 用的是旧的 a。

对比一下其他语言的写法(要先存个临时变量):

temp = a + b
a = b
b = temp

术语上这叫"同时赋值"(背后用到的是元组,阶段 9 会正式讲)。
现在你只要记住右边先算完、再赋值这一条规律就够用。

下划线 _ 表示"我不关心这个循环变量"(这里只是要循环 20 次)。


本阶段自评

  1. 数学:导数的几何意义是什么?为什么 $|x|$ 在 0 处不可导?
  2. 数学:$e^x$ 的导数是什么?(它有个独特性质,是什么?)
  3. 数学:为什么 h 太小反而让数值导数更不准?什么条件下才会出现这个现象?
  4. 编程:range(1, 5) 会生成哪些数?range(0, 10, 2) 呢?
  5. 编程:break 和 continue 的区别是什么?
  6. 技能:循环跑了但结果不对,第一步该做什么?
  7. 连接:为什么说"进步速度递减"等价于"学习曲线先陡后平"?
  8. 动手:第 6 题做了吗?你成功从死循环里逃出来了吗?

全部答得上 → 进阶段 4。

最后更新:2026-09-26