学C++,别再让孩子“看懂就算会”:真正高效的学习,是把知识讲出来
对于学生来说真正决定学习成果的往往不是“每天学几个小时”而是“学进去以后能不能变成自己的东西”。很多孩子会出现一种情况“老师讲的时候我听懂了”“看别人代码我也懂”“自己写不会”“考试遇到变形题更不会”这其实不是孩子笨而是学习还停留在“看懂”阶段没有进入“自己会讲、自己会做、自己会改”的阶段。我们应该怎样才能提高孩子的学习效率呢一、学习效率到底是什么我们可以把学习效率想象成学习效率 单位时间内真正变成“自己的知识”有多少。比如两个同学都学习 1 小时。小明开始跟了一节课int a 10; int b 20; cout a b;觉得“老师讲得真简单我都会了。”但是让他自己写一个程序输入两个数字输出它们的和。他可能又开始发呆“老师这个怎么写来着”小华也跟课学习了 1 小时。他理解了课堂知识变量就是给数据起名字。然后继续写了int age 10; int score 95;接着会自己复盘“什么是 int 类型”“为什么数字 95放在 ‘ ’的右边”“使用cout 是可以直接输出表达式的值”最后又自己给“另一个小朋友”讲了一遍。虽然他只学了一个知识点但这个知识点已经长到自己的脑子里了。所以学习不是“我看了多少”而是“我真正掌握了多少”。二、学习中危险的错觉看懂 ≠ 学会这是我特别想提醒同学们的一件事情。学习 C 时有四个不同层次第一层看见 ↓ 第二层看懂 ↓ 第三层会做 ↓ 第四层会讲很多孩子停在了第一、二层。第一层看见老师写for(int i 1; i 10; i) { cout i endl; }孩子“我见过 for 循环。”这只是认识。第二层看懂老师的讲解i 1是开始i 10是结束条件i是每次加 1孩子“哦我懂了。”这是理解。但是还不够。第三层会做老师说“请你自己写一个程序输出 1~100 的偶数。”孩子能够自己写for(int i 1; i 100; i) { if(i % 2 0) cout i ; }这才开始真正掌握。第四层会讲孩子给另一个同学讲“for 循环就像跑步机。”“第一步从 1 开始。”“每跑一步i就代表往前走一格。”“只要i 100就继续跑。”如果他能够很清晰把这个循环程序讲清楚恭喜这个知识点已经彻底掌握了。三、这就是费曼学习法费曼学习法可以简单理解成一句话学会一个知识以后不要马上继续学新的而是尝试把它讲给一个完全不懂的人听。最经典的流程可以简化成① 学习 ↓ ② 合上书 ↓ ③ 自己讲 ↓ ④ 发现哪里讲不清 ↓ ⑤ 回去补漏洞 ↓ ⑥ 再讲一次这套方法对于 我们小学生学习C 特别有效。因为C不是“看懂”的学科而是“能够自己写出来”的学科。四、为什么费曼学习法特别适合学习 C比如老师讲int a 10; int b 20; cout a b;孩子说“我懂了。”那么马上进行费曼测试请讲讲“什么叫变量”如果孩子讲“就是……那个……存数字的东西。”说明还没有真正理解。继续问请再进一步讲解下“为什么叫变量”如果他说“因为里面的数据可以改变。”这就开始理解了。再问“那下面这个呢”int score 100; score 80;为什么可以如果孩子能够解释“score 是变量它一开始保存 100后来又让它保存 80。”这就真正掌握了。五、给孩子一个非常重要的学习原则不要问“我听懂了吗”要问“如果老师现在不在我能不能讲出来、写出来”这两个问题完全不同。六、学习 C 的“费曼四问”以后每学一个 C 知识点都可以问自己四个问题。第一问它是什么例如学习指针是什么不要只背“指针是存储地址的变量。”而是尝试用自己的话说“普通变量像一个房间里面放着一个数字指针像一张纸条纸条上写着这个房间在哪里。”这就比死记定义好得多。七、第二问它为什么存在这是非常重要的一问。比如为什么 C 要有指针不能只背定义。应该思考“如果我已经有变量了为什么还需要一个东西记录它的地址”然后慢慢理解变量 ↓ 有数据 指针 ↓ 知道这个数据在哪里于是就可以继续理解函数为什么需要引用为什么动态内存需要指针这样知识就开始连起来了。八、第三问什么时候使用这一步能够帮助孩子从“知识”走向“应用”。比如学习vector不要只记vector 是动态数组。而应该问“什么时候我应该使用 vector”例如vectorint a;如果题目告诉你“有很多数字但是不知道到底有多少个。”这时候就想到vector于是知识就变成了工具。九、第四问我能不能自己写一个例子这是最重要的一步。例如今天学习sort()。不要只看老师sort(a, a n);马上自己出一个题“我有 5 个数字让它们从小到大排列。”自己写int a[5] {5, 2, 4, 1, 3}; sort(a, a 5);然后再改变“能不能从大到小”继续研究sort(a, a 5, greaterint());这时候一个知识点就开始变成自己的能力了。十、“C费曼学习法”图示我建议把一次学习过程变成下面这样学一个知识点 ↓ ┌───────┴───────┐ ↓ ↓ 看懂 动手写 ↓ ↓ └───────┬───────┘ ↓ 合上资料 ↓ 用自己的话讲 ↓ 能不能讲清楚 ↙ ↘ 不能 能 ↓ ↓ 找漏洞 自己出题 ↓ ↓ 再学习 自己解决 ↓ ↓ └──────→ 真正掌握这比上课 → 做笔记 → 看答案效率高得多。十一、一个特别适合小学生的方法给“空气学生”讲课家里没有同学怎么办非常简单。假装桌子对面坐着一个完全不会 C 的小朋友。然后开始讲。例如今天学习什么是数组你可以拿 5 个玩具 告诉“空气学生”“如果我要存 5 个苹果一个一个给它们取名字太麻烦了。”于是int a[5];就是“我一次性准备了 5 个小盒子。”然后继续讲a[0] a[1] a[2] a[3] a[4]就是“第 1 个盒子、第 2 个盒子……第 5 个盒子。”如果孩子可以这样讲说明他已经开始真正理解数组。十二、也可以让孩子给父母讲这个方法非常好。例如孩子刚学完什么是递归晚上可以跟爸爸妈妈讲“递归就是一个问题不断变小最后变成一个非常简单的问题。”例如int f(int n) { if(n 1) return 1; return n * f(n - 1); }孩子如果能够解释f(5) ↓ 5 × f(4) ↓ 5 × 4 × f(3) ↓ 5 × 4 × 3 × f(2) ↓ 5 × 4 × 3 × 2 × f(1) ↓ 5 × 4 × 3 × 2 × 1那他对递归的理解一定比单纯刷十道递归题更深。十三、学习效率提高还有一个非常重要的秘密少学一点但学深一点很多小朋友学习 C 有一个误区“今天我要学数组、函数、指针、结构体、排序……”结果数组懂一点 函数懂一点 指针懂一点 结构体懂一点 排序懂一点最后什么都学过什么都不会用。我更建议一次真正吃透 1~2 个知识点。比如今天只学习vector目标不是“我看完 vector 这一章。”而是“今天我要彻底搞懂 vector 是什么、为什么需要它、怎么创建、怎么添加元素、怎么遍历、什么时候使用。”然后vectorint a; a.push_back(10); a.push_back(20); a.push_back(30); for(int x : a) { cout x ; }最后孩子能够自己讲“vector 就像一个可以自动变长的盒子……”这才叫学会。十四、第二个提高效率的秘诀一定要“主动回忆”这是很多孩子特别容易忽略的。例如昨天老师讲了for今天上课之前不要马上翻书。先问自己“for 循环怎么写”自己写for(int i 0; i n; i) { }如果想不起来“糟糕我忘了。”这不是坏事。恰恰相反。因为发现自己忘记了然后努力回忆的过程本身就是学习。所以我特别建议不要一上来就看答案。先让大脑自己想。十五、第三个秘诀错误不是敌人而是“老师”学习 C孩子一定会遇到编译错误 运行错误 答案错误 数组越界 死循环 RE WA TLE很多孩子看到Wrong Answer第一反应“我太笨了。”这是非常错误的。正确的思维应该是“太好了我终于知道自己的漏洞在哪里了。”例如for(int i 0; i n; i)结果数组越界。不要只是改成i n而应该问“为什么错了”如果孩子能够自己解释“因为数组下标是0 ~ n-1所以不能访问a[n]。”那么这个错误反而帮他把一个知识点真正学会了。十六、第四个秘诀一道题不要只做一次真正优秀的 C 学习不是做 10 道题每道题做一次。而是一道好题要研究 3~5 次。比如一道数组题。第一次把答案写出来。第二次不看答案重新写。第三次改变数据看看程序还能不能运行。第四次改变题目条件。第五次想一想还能不能用另外一种算法。这时候一道题 五次学习。这就是“举一反三”。十七、我推荐孩子给自己建立一个“费曼本”不用写得很漂亮。每学一个知识点只写五句话① 它是什么 ② 为什么需要它 ③ 怎么使用 ④ 一个最简单的例子。 ⑤ 我能不能给别人讲明白比如今天学习vector① 它是什么 可以自动变长的数组。 ② 为什么需要 数组长度固定有时候不方便。 ③ 怎么用 vectorint a; ④ 最简单例子 a.push_back(10); ⑤ 我能不能讲明白 可以我可以把它讲成“会自动变大的盒子”。这样一本本子长期积累会很有价值。十八、对于信奥赛孩子必须学会“费曼学习法”尤其是学习算法的时候。例如学习 BFS。不要只记queueint q; q.push(1); while(!q.empty()) { int u q.front(); q.pop(); }而应该问① BFS 是什么一层一层向外扩散。② 为什么需要 queue因为先进去的人要先出来。③ 为什么要记录 visited防止一个点被重复访问。④ BFS 能解决什么最典型的是无权图最短路、迷宫最短路、层序搜索等。⑤ 我能不能自己讲如果同学能够从“水波纹扩散”讲到“队列”再讲到“visited”最后讲到“无权图最短路”这才是真正把 BFS 学会了。十九、费曼学习法真正厉害的地方不只是“讲给别人听”这一点非常重要。很多人误解费曼学习法“费曼学习法就是给别人讲。”其实不是。它真正厉害的地方是逼着你发现自己到底哪里不会。比如孩子说“我会递归。”让他讲“递归为什么一定需要结束条件”他突然“呃……”这一个“呃”就是一个知识漏洞。再问“return f(n-1)以后程序怎么回来的”孩子“呃……”又发现一个漏洞。所以费曼学习法实际上像一个知识漏洞探测器。二十、学习效率真正高的孩子通常有一个共同特点不是学得特别快。而是发现不会以后知道自己哪里不会。这是非常大的区别。普通孩子“这题不会。”优秀孩子“我不会。”更优秀的孩子“我知道我不会在哪里。”比如“代码不会写。”这是第一层。而真正好的学生会说“输入输出我会。”“循环我会。”“但是我不知道应该用 BFS 还是 DFS。”再进一步“我知道应该用 BFS但是我不知道为什么 BFS 能保证最短。”这时候老师就非常容易帮助他。因为问题已经从“我不会”变成了“我不会什么”。二十一、给小学生一套每天都能执行的“高效率费曼学习法”如果每天只有 60 分钟我很推荐第 1 阶段10 分钟——回忆不看资料。想一想昨天学了什么自己写几个代码。第 2 阶段15 分钟——学习学习一个新的知识点。注意只学一个核心知识。第 3 阶段15 分钟——自己写完全不看答案。哪怕写错也没关系。第 4 阶段10 分钟——费曼讲解合上书。假装自己是老师。给空气学生讲“今天我学会了什么”第 5 阶段10 分钟——总结回答今天我真正学会了什么 今天我哪里不会 我犯了什么错误 如果题目换一种问法我还会不会这一个小时是非常高效的。二十二、最后送给孩子一句特别重要的话学习 千万不要追求“我今天学了多少。”而要追求“今天有多少知识真正变成了我的能力。”可以把学习分成四个层次看过 ↓ 听懂 ↓ 做对 ↓ 讲明白真正高水平的学习是听懂 ↓ 自己做 ↓ 遇到错误 ↓ 自己改 ↓ 自己解释 ↓ 举一反三 ↓ 教给别人这时候知识才真正从“老师的知识”变成“我的知识”。 我建议把下面这句话放在孩子的书桌前少看答案多想一想少背代码多问为什么学完一个知识合上书讲一遍做错一道题找到自己的漏洞今天学会的东西要能在明天自己写出来。最后可以把整个学习过程浓缩成一句话“学一点 → 做一点 → 讲一点 → 错一点 → 改一点 → 再讲一遍。”这其实就是非常适合小学生学习 C 的费曼学习闭环。