OI授课思考 1

来到天津滨海也有些时日,算来算去已经上了4个月左右的线下课。第一批 OI 零基础的学生已经学到数组,优秀的学生能灵活使用桶数组,一般的学生能自如使用循环嵌套,当然也存在学了和没学一样的学生。都是同样的老师,都是同样上课,为什么会出现这般断层?为什么线下授课会出现无法想象的疲惫?

以前我的思路都在「标准化」课程中,对于知识点的讲法与运用会有些许研究,比如说数据存储与输入输出、循环过程、基础序列处理等等。但是这些内容还是在讲课层面,这些新知识往往在第一遍学生听的时候,吸收程度不会有多高,所以量少与重复是新课的重点。不能给太多的量,也得有大量的重复,比如说提问、简单选择题、模板题。这些内容在讲新课的时候都能很好的开展。无论是什么程度的学生,只要愿意听,在跟上课堂活动,就能有所收获,通过重复与提问能保证基本内容的掌握。但是随着后续做题与讲题的推进,学生的层次逐渐会变化。起点一样,但是速率产生了差距。在不考虑学生自身层次的情况下,我认为是讲题出现了问题。目前出现的问题如下:

  1. 学生对于代码运行逻辑不清晰,写出很多逻辑不自恰的内容。比如将最终答案输出写在循环里,将初始化写在判断/循环里。让学生自己讲代码是如何执行的出现无法梳理清楚的情况。
  2. 学生对于模块化思维不清晰。比如一个循环的作用不清楚,导致在完成循环嵌套相关题目的时候会出现循环中的内容写到循环外。
  3. 自主架构代码的能力低下,自己写不出来东西。

目前OI课程的内容由“少部分知识点 + 大部分做题技巧“构成,所以讲解题目与课上完成题目是课程的主要内容,反而知识点的讲解占很小一部分。这就和学切菜和切出花来有些区别一样,知识点就相当于怎么抓刀,知道刀的哪个部分锋利,而多做题更像是独立使用刀对不同菜品进行处理,不同题的处理手法是不一样的。目前出现的问题,我认为是在讲题层面出现了问题。事物的发展规律都是可以探寻的,错误的讲题形式导致了现在学生出现的不同层面的问题。

讲题分为:讲解题目与分析学生代码两部分。目前的课程存在助教这个角色,助教的核心作用就是帮助学生分析代码,维护课堂秩序(会有上课乱叫/唱歌/跳舞的学生)。我不喜欢该角色,但是不能否定在课程过程中,该角色起到了稳定课堂与缓解教师压力的作用。其中讲解题目是上课老师的任务,分析学生代码是老师与助教共同执行。当然这里存在一个问题就是,在讲解调试方法后学生应该是不需要老师帮助分析代码的,但是普遍学生用不起来调试,在老师亲自带着调试几次后,还是不愿意进行调试。反而是原本不需要分析的学生能独立自主解决一切问题(可能这个就是下沉教育会遇到的难题吧)。目前认为在讲解题目与分析代码中均出现了问题。

做题与讲题的为了什么?我将这个问题的答案分成了两种:目标导向与理解导向。目标导向就是完成题目;理解导向是理解全部,无论是问题还是答案全部都理解。两种导向会有两种讲解方式。目标导向就是直接输出给学生,让理解导向就是让学生自己思考,老师来辅助引导。一般人在这种问题上会普遍认为理解导向是应该选择的方向,但是这种想法脱离了实际生产生活,脱离了群众。如果是一对一的课程,那确实应该与必须是理解导向,做题就是为了让你明白某一种思维方式或模式的,只有理解了才能有收获。而在8人以上的课程中,在目的上就会存在偏差。很多学生最开始无法做到理解全部,如果全力耗费在让他们理解上,那其他人便会觉得课程内容少,只能自己往下推进,还有学生讲的能懂,但是自己推进就不懂了,反而还会觉得课程内容难。所以此时对于同一班级就需要为学生区分不同的导向,对于慢的学生,需要先完成,对于快的学生,需要全理解。慢也不是非常的慢,快也不是非常的快,慢与快只是相对而言。先完成,再让他想办法理解,只能说这是一个折中的方案。

原本如何讲解题目的?日常的讲题分为:读题、抽象模型、过程梳理、带着写代码。

  • 读题需要注意题目中隐藏的信息与需要在题目中注意的部分。
  • 抽象模型为将题目抽离故事,分解为:题目提供了什么数据、题目给出了什么操作和题目要求解什么数据,基本上三句话可以将题目解释清楚。
  • 过程梳理就是按照步骤的形式来梳理如何处理这些数据,往往梳理过程就是求解题目。基本上梳理过程就是讲解答案,因为题目的数据处理往往就是核心技巧。比如说如何循环,如何统计或者如何记录。在抽象模型和梳理过程中间就会将这些技巧贯穿到讲解里。
  • 最后就是写代码,往往这个适合会配合着。直接输出给学生和让学生自己去思考。

一般上课,我先带着读题与抽象模型,先让学生理解是什么意思,然后再来分析如何去处理数据。这个时候会抓住局部的问题来讲,最后会写一个类似于流程的文字描述,再交给学生来独立完成代码和细节。这样看起来很好,但是的问题在于,学生会忙于实现,没有去思考。这也是现有的模式最大的问题,学生没有去独立思考。有思考的学生都是写的快的学生,写的越快就越往后做,往后做就会独立思考。越多思考,上手越快,学的越好。每次都是带着读题,带着分析,然后让他们自己写,这反而缺失了真正思考的部分。那这些写的慢的学生写的好吗?也写的不好,往往代码细节乱写,前言不搭后语的代码都是由写的慢的学生写出来的。为什么会这样?因为这些代码不是他们自己写的,而是老师说什么写什么“抄“出来的。再加上这些学生本身的学习习惯就有问题,回家也不完成代码,不会就是不会了,也不愿意去动脑子想一想。恶化就开始了。

在带着写代码与讲解代码的过程中,我觉得直接带着写也是有问题的。第一:我的代码速度和学生的代码速度存在差异,我写的速度很快,就算我边写边讲边分析,写的慢的学生也会存在能不能跟上的问题。第二:我只是写出来了,讲出来了,学生也只是抄出来了,还是没有对问题进行思考。也不能单纯的以完全目标导向来完成教学任务,作为老师还是更期待学生能在理解导向有所突破,可惜现阶段的这种模式我看不到突破。

不过,在BiliBili看到一位竞赛教练视频中提及3个关键点:主动写注释、引导学生写注释、学生的算力。这三个方面我觉得非常适合现在这种僵局。写代码的过程中主动写注释,或者就以注释来作为框架(和伪代码的区别在于有代码格式了)。配齐注释对于现阶段讲课起到了很大的辅助作用,确实对写的慢的学生有接受的帮助。不过我才尝试这种方案没几天,是否能让跟上进度的学生增多,还有待考察。短时间内,我觉得学生能回答上来部分想法,说明是有进步的。其次就是让学生对自己的代码进行注释,这也是一种复习的方案,不过此方案对学校的培训会有所帮助,对培训机构的学生,不太可能推进开展下去,只能说方法告诉学生,学生自己有这个进步的意识就去落实这件事。最后是学生的算力,指学生能自主代入数据到程序中进行模拟,然后检查。我之前没有对这方面产生过意识,我在调学生程序的时候会下意识的进行这个操作,当这件事被说破了,我反应过来,确实学生的算力需要提升,需要让学生有能代入数据进行模拟的能力。这样学生对于程序逻辑理解的会更深刻。

当然,会有老师或者学时间比较长的学生认为,应该提前上马单步调试,让学生能自主调试程序并且帮助理解程序。这其实是一件比较困难的事情,调试适合具有一定算力的学生,他能知道自己的输入数据应该有什么样的变化,或者最起码知道自己写的代码在干什么事情。在学生不知道自己的代码在做什么事情之前,我不会强制性让他们使用调试功能,也仅仅是让学生知道怎么用。在学生能明显独立完成题目之后,我开始慢慢不帮助看代码,让学生独立使用调试功能自主查错。所以调试不太能往前提,因为不思考和不明白往往是学OI的最大阻碍,单步调试不太能帮助完成学生从0到1的跨越,拥有算力与独立思考才行。

总结一下:现阶段的授课方案没有引导学生独立思考,反而让学生对老师产生依赖。缓慢授课进度、分班、让学生自己写。当然道理都明白,实施下去也是存在难度。