🌑

Hi Folks.

教学,如何是好?————7月18日教学反思

17号碰巧昆哥在上课,我旁边旁听了一下,反思了自己讲课的几个问题。

  1. 举例是应该带上变量的,否则小朋友的重新提取是很消耗精力的
  2. 我的变量定义不足够统一,应该用明确的英文单词,一来帮助小朋友背单词,二来有明确的含义,不会让小朋友弄混淆。
  3. 应该带着小朋友讨论for/while循环的终止条件,以前我经常直接抛出一些特殊情况,然后告诉孩子循环什么时候结束。我直接问”什么时候程序应该停下来?”,让孩子先思考,再一起讨论终止条件,而不是直接告诉他答案。

问题暴露

无独有偶,周五周六这些问题全部暴露了出来。
俊丞同志已经极度认真了,但还是没有很好的掌握。我带着他把他出现的问题记录了,以此去总结问题:

  1. 在最大值最小值(极差问题)中,俊丞是分不清if语句中究竟是些max > d还是max < d的。
  2. 同一个问题,他又写了d = max,实际上整个逻辑根本没有经过推导,只是在机械地模仿以前见过的代码。
  3. 同一个问题,if(max<d) 后,他又下意识的写了 else if,实际上他是没有经过大脑思考去理清这个逻辑。
  4. 在带格式输出的题目里,他不能理解printf里面实际是字符串,需要借助转义字符”%d”、”%f”来帮助变量输出。
  5. 经常把答案定义在 for 循环里面、在for循环里写 cout 答案,说明并没有真正理解作用域(Scope)的概念。
  6. 对于公式性问题利润计算,没有尝试拆分式子$money*(1+rate)^{year}-money$,所以没办法用变量去代替一部分$so=(1+rate)^{year}$,所以他设计不出来for循环。
  7. 在讲过一遍后,因为没有去思考so的计算过程,double so没有给初值,
  8. 税率计算问题我认为主要责任在我,因为我没有给出正确的税率计算公式,经历了修改后思考不连贯了。小朋友能想到小数问题(判断double和int),按照题目定义变量,能理解题目的意思
  9. 正方形输出问题相对简单(主要是做过了),但是没有测试,测试后没有和题目样例比对(过度自信)
  10. 正方形交错输出是个大问题,完全没有思考(i+j)%2==0这个事情,就是在随意的更改变量,希望得到正确的结果,没有想着去处理交错,一昧的去改变变量数字,在没有理清逻辑的情况下开始试错,他没有思考:为什么要加?为什么要取模?为什么判断偶数?而只是不断修改数字,以此希望碰巧得到正确答案。
    整个过程完全是在试错,而不是推导。
  11. 直角三角形问题:意识不到i是一个变量(变化的数字),没有写出来j<=i。

这些错误看起来毫无关联。但是整理下来以后,我意识到:俊丞之前几个月的学习,很可能一直停留在模仿(Imitation)。老师写什么,他就写什么。老师改哪里,他就改哪里。真正属于自己的思考几乎没有发生,简单的问题靠着模仿,而稍微困难的问题就靠豆包,直到现在没有办法完成for循环的例题,于是知识便如同受到虫蛀的大树一样,出现窟窿了。

从脑科学的角度,这是源于 “机械模仿”与“逻辑重构(Retrieval)”的断层

俊丞的11个问题看似零散(赋值错误、作用域混乱、数学公式无法转译),但从计算机科学教育(CS Ed)的角度来看,根源只有一个:他脑海中没有建立准确的“程序状态(Program State)”动态心理模型。

新手在入门时,认知负荷(Cognitive Load)极高。他们同时在处理三件事:

  • C++的晦涩语法(如 printf 的格式化)
  • 数学逻辑(如交错、极差)
  • 程序执行的时序性。

当大脑过载时,学生就会退化到典型的试错式编程(Guess-and-Check)——随意调换 max < dd = max,胡乱加 else if,不经思考地修改 (i+j)%2 中的数字,仅仅是为了“碰”出一个能通过样例的答案,而不是理解程序为什么这样运行。。

因此这11个问题虽然表面各不相同,本质都来源于同一个问题:孩子的大脑里没有建立”程序运行过程(Program State)”的心理模型。

要解决这个问题,必须用客观的、强制性的手段剥离他的认知负荷:

1. 解决赋值与作用域问题(问题1、2、5)

学生写出 d = max,是因为他用解数学方程的思维在看代码(在数学里 $x=y$ 和 $y=x$ 等价)。

  • 引入“盒子模型”: 明确告诉学生,= 不是等于,是“装入”。右边是物品,左边是盒子。让他在纸上画两个盒子,上面写好英文变量名。每次赋值,强制他做一个“把旧数字划掉,写上新数字”的物理动作。
  • 可视化作用域(Scope): 针对问题5(在 for 里定义和输出答案),引入“房间与大门”的比喻。for 循环的大括号 {} 就是一扇门,里面定义的变量在循环结束时“房间就塌了,东西就没了”。答案盒必须放在房间外面。

2. 先做人工CPU(问题9、10、11)

不妨使用追踪表(Trace Table)

  • 停止盲目敲击键盘: 针对问题10(交错输出)和问题11(直角三角形),不要让他直接在电脑上改代码。给他一张网格纸,让他画出 $i$ 和 $j$ 的变化图。
  • 数据驱动逻辑: 让他自己填表:当 $i=1, j=1$ 时,输出什么?当 $i=1, j=2$ 时,满足 $j \le i$ 吗?当他自己写出 $(1+1), (1+2), (2+1)$ 的奇偶规律时,代码逻辑自然就浮现了。写代码应该只是“翻译”他在纸上已经跑通的逻辑。

3. 将数学公式转化为程序流(问题6、7)

编程计算不是列数学方程,而是“流水线加工”。学生无法将 $money \times (1+rate)^{year} - money$ 转化为代码,是因为他缺乏子目标拆解(Subgoal Labeling)的能力。

  • 强制写伪代码: 不要让他上来就写 for。要求他先写出加工步骤:
  1. 第一步,我需要算出一个乘法倍数 $so = (1+rate)^{year}$。
  2. 第二步,我要算总钱数。
  3. 第三步,减去本金。
  • 攻克卡点: 拆解后,重点攻克第一步的循环。问他:“如果要连续乘 $year$ 次,我们的累乘器 so 刚开始应该是多少?”(引导他发现不能是0,必须是1.0)。这就顺理成章地解决了初始化(问题7)的遗漏。

4. 强制输出(Retrieval Practice)

他不提问,说明他没有经历 Retrieval(信息提取)的过程。

  • 废除“听懂了吗?”: 这种提问得到的数据全是无效的。将提问改为微型预测(Micro-predictions)
  • 费曼讲述法: 在他写完 if (max < d) 并且乱加 else if 时(问题3),让他停下来,指着屏幕说:“俊丞,如果现在 $max$ 盒子里是5,$d$ 盒子里是8,你作为电脑,告诉我这三行代码走完,盒子里各是多少?” 如果他答不出来,说明他根本没想明白逻辑,只是在条件反射地敲击键盘。
  • 引入测试用例(Test Cases)思维: 针对过度自信(问题9)。在讲题前,先给出3组极端数据。要求他写完代码后,必须用这3组数据在纸上“心算”走一遍,和电脑输出比对,以此建立严谨的工程习惯。

实际上我作为老师,我的职责不完全是讲知识点,重要的是帮助孩子从”照着写”引导走向”自己思考”。只有当课堂中真正发生了 Retrieval(主动提取),知识才会从短期记忆进入长期记忆,编程能力也才会真正开始形成。

如此说来,从根本上讲,一切学习归根结底都是自学,指望他人灌输终究是靠不住的。进一步想,各类辅导班最主要的功能,其实是服务家长——满足他们的“鸡娃”需求,缓解他们的教育焦虑。至于成绩提升,充其量只能算作副产品(当然,个别质量过硬的辅导班确实也能带来成效)。

循此思路,初中阶段出现成绩两极分化便不足为奇了。对校内尖子生而言,考试优异换来老师表扬,表扬激发更多做题热情,更多练习又巩固了成绩,如此循环往复,形成正向的“正反馈环”。但问题在于,一个班级里总有高下之分,不可能人人都站上这个光环。差生长期缺乏足够的积极反馈,大脑便会逐渐判定“做题不值”,从而降低对学习的投入权重。系统设计本身,就注定了只有少数优等生能获得持续的自学动力,而大多数学生则被排斥在这一循环之外。

— 2026年7月17日


Search