周会平,毛新军,徐建军
(国防科技大学 计算机学院,湖南 长沙 410003)
计算机程序设计是一门实践性很强的课程,通常依托一门高级程序设计语言培养计算思维和问题求解能力。程序设计课程是一门容易教但又难以教好的课程,因为讲授一门程序语言的语法和语义很容易,但培养学生的问题求解能力很难,特别是兼顾不同基础、不同接受能力的学生培养更难。工程教育认证对本科毕业要求有明确规定,其中与程序设计课程相关的有两条[1]:①工程知识:能够将数学、自然科学、工程基础和专业知识用于解决复杂工程问题;②使用现代工具:能够针对复杂的工程问题选择与使用恰当的技术、资源、现代工程工具和信息技术工具,包括对复杂工程问题的预测与模拟,并能够理解其局限性。这需要依托程序设计课程培养两个能力:①针对具体问题建立计算模型并求解的能力;②选择程序语言、开发环境、辅助工具等对复杂工程问题进行分析、设计和编程实现的能力。为了达成能力培养目标,有的老师将课程实践和竞赛引入课堂[2],引入机试进行课程考核改革[3],创建MOOC[4]、线上线下混合式教学[5]等,尝试通过更多的编程实践提高学生的编程能力。
国防科技大学程序设计课程依托C++语言,面向大学一年级新生,学生个体差异性很大:①基础差异。有的学生中学就参加过信息类竞赛,学习过某种高级语言,掌握了一定的编程技巧;有些学生上大学前从来没有接触过电脑,使用电脑时畏手畏脚。让所有学生在一起学习同样的东西,做同样的练习,按同样的步伐齐步走明显不合适。面对这个问题的共识是“好的学生不需教,差的学生尽量带,跟不上也没办法,只需要把大多数学生教好就算成功了”;②悟性差异。有的学生悟性强,一点就透;有的学生工科思维较弱,单条语句还好理解,几条语句放在一起理解起来就非常困难,如果没有更多的讲解、示例、讨论等环节,最后的结果往往是自我放弃;③性格差异。有的学生碰到问题爱问,喜欢讨论;有的则喜欢自己琢磨。这些差异会导致随着课程进行,学生的两极分化越来越严重。为解决这些问题,需要以学生为中心的个性化教学,需要完美的教学生态去促进学生自我激励与自我成长,而这些目标仅仅靠课堂上的讲授和课后练习、答疑很难实现。
程序设计学习分为3 个阶段:①读程序。初学者从读程序开始学习每一条语句的语义,尝试理解并记忆三五条语句的组合语义。这个阶段理解语句的语义是关键,如果只是浅层理解,题目稍有变化就只能靠蒙了,这也是初学者容易出现背程序的原因;②改程序。发现新问题和自己碰到的例题很像,拿例题的程序改一改来解决新问题,而这种改需要建立在对程序语句的深层理解上。改程序分为两个阶段,一是语句本身的简单修改,如常量、变量、运算符修改等,二是语句组合,即用几条自己熟悉的语句组合出实现新功能的语句序列;③写程序。对程序语言比较熟悉,在掌握一定的程序设计方法之后就可以写程序了。刚进入这个阶段的学生往往觉得看别人的程序很容易,但要自己写就很困难。原因是写程序需要掌握两个能力,一是对问题进行分析和计算建模的能力,也就是针对具体问题的简单算法设计能力,这时候一般还不涉及数据结构设计,二是算法的程序实现能力,学生往往因为欠缺第一个能力而无从着手。掌握计算建模能力光靠编程实践很难,需要在实践中慢慢体会、归纳总结,往往需要几个月甚至更久的时间。将这个能力的培养过程化、工程化显得十分重要。
如何根据教学目标设计科学、合理、可行的教学过程是课程教学的前提。程序设计教学过程不仅要满足计算思维和问题求解能力的培养,还要综合考虑学生水平、课程特点、学时安排和各种实际条件。本文设计了包含3 个阶段的程序设计教学过程,循序渐进、逐步提升,以达成学生能力和素养的培养目标,并对支撑教学过程的教学生态提出需求,如图1 所示。
Fig.1 Teaching process of programming course图1 程序设计课程教学过程
这是课程教学的第一阶段。教学内容为程序的控制结构和函数部分,从读程序入手逐步实现改程序能力的培养。这一阶段学生的学习积极性培养和维持至关重要,而学习积极性主要来自不断解决新问题的成就感。为了实现读程序到改程序能力的进阶,也为了提升兴趣、夯实基础,要求学生做到:①手输教材上的例子,对于不完整的程序补全初始化和输出语句,在IDE 上编译运行,帮助学生熟练掌握语言语法和程序结构;②对于没把握的程序,要求学生通过微小的修改来体会该语法在不同状况下的执行结果,以全面理解该语法的语义。如求余运算符%,让学生尝试正负整数、浮点数求余时的结果或报错信息;③要求学生掌握基本的跟踪调试技能,能用单步跟踪方法跟踪选择结构和循环结构的执行过程。
为达成上述教学目标,需要建设支持能力进阶培养的实战实训。程序控制结构部分的实训以代码修改为主,函数部分的实训则侧重于功能的分解和组合。例如要完成某个实训,学生可能只需要增加几条相同的语句、改变表达式的运算符或操作数、改变分支或循环的条件、改变循环执行的边界、组合几条熟悉的语句就可实现新的功能,将一个功能分解成2 个或3 个函数实现等等。需要从语言、编译器、计算机系统多个角度对程序进行讲解,录制视频或编写图文结合的资料供学生随时查看,以促进学生对程序的深层次理解。
程序设计课程第二阶段是简单数据结构部分,实现从改程序到写程序的能力培养,独立完成第一阶段的实训就可以进入这一阶段。第二阶段由于引入了新的内容,需要进一步夯实改程序在数据组织和结构化数据操作上的应用能力,同时逐步培养问题分析和计算建模的能力。不管是示例还是实训,问题的描述都从之前的描述计算过程方式逐步转变到问题本身,如之前描述问题要用完整的伪码表示,这里则逐步减少描述问题的伪码层数,直到完全不涉及任何计算方法,通过留给学生足够思考空间的方式培养学生的问题分析和算法设计能力。
为达成上述教学目标,在视频录制时需要逐步增加问题分析和计算过程设计的比重。结构化数据的深层次理解离不开数据表示的底层细节,需要在视频和测试中讲解和反复训练。实训设计要体现结构化数据的设计、操作、评价、优化,同时培养写程序能力,以综合性的实训案例检测写程序阶段成效。
程序设计第三阶段是综合提升阶段,要全面培养学生的问题求解能力,即问题分析、计算建模、算法设计、编程实现、测试调试能力。①组织课堂研讨。对给定的问题给出算法设计,博采他人之长,拓宽自己的思路;②调试能力培养。针对逻辑较复杂、运行结果易出错的程序,让学生用跟踪调试的方法找出其中的逻辑错误;③结合线性结构和文件,尽可能接近实际问题进行设计,提高单个程序代码量,全面提高学生程序设计能力。
为配合第三阶段教学,需要以案例教学的方式讲授模块化程序设计方法和数据结构设计方法,实战实训以较大规模的综合题为主,分多个关卡实施,让学生在闯关过程中学习程序设计方法和程序架构。
有效完成课程教学,达成课程教学目标,必须要有相应的教学资源和教学辅助工具支撑。①程序设计课程教学质量往往依赖于任课教师和教辅的水平、耐心、投入的时间和精力等,同样的教学资源和教学方法可能在某个班教学效果良好,在另一个班则效果一般,需要借助群智学习力量尽量减少对教师和教辅的依赖度;②学生初始水平、悟性和性格差异性大,按同一进度授课只能照顾到学生中的大多数,好的学生大多只能自学,而跟不上的学生慢慢就会放弃,需要支持不同进度、采用不同学习方法的学生进行自主学习;③分阶段的实战训练及能力进阶需要精心设计的实训项目支撑,结果的评测更是工作量巨大,需要自动化工具支撑;④为满足不同条件下不同学生对程序设计课程的需求,学习资源和学习支撑工具需要不断演化,持续改进。为满足课程教学需求,笔者所在课程组建设了程序设计教学生态。
教学生态应该是一个开放的、多样化的、充满生机、相互依赖并具有适应性的体系,会从物质和心理两个方面影响教师、学生等主体[6]。程序设计教学生态建设包括硬软两个方面,硬指课程资源、平台和工具建设,软指如何组织使用好这些资源,使之成为一个真正为程序设计教学服务的好生态。目前,课程建设大多关注硬的方面,软的方面相对关注较少,基本上是教师主导课堂,而良好的教学生态应该以学生学习为中心。
近年来,利用互联网上海量用户及其智慧来解决各类问题的群智方法得到了广泛应用,如基于大众开发的开源软件、基于众筹众智的大众创业等,该方法也被用在了教学领域,解决软件工程的开放式实践教学问题[7]。程序设计教学面临着诸如学生基础和学习能力差异性问题,使以学生为中心的个性化教学很难实施,教师只能通过分析跟踪学生的情况照顾大多数,超前和落后的学生只能偶尔顾及甚至完全放手。受群智方法启发,可以建设全面支持自主学习的程序设计教学生态,吸引本班、本校、其它高校甚至社会学习者一起,不管学生处于哪个学习阶段,都有指导自己如何进一步学习的资源、平台,有相互讨论交流的学习群体;教师则为学生规划学习路径,通过自动化工具跟踪每个学生的学习情况,并给予适当的督促和引导。程序设计教学生态建设包括伴随式的实战实训、MOOC 和学习空间等。
课程实战实训依托头歌平台建设,URL 是https://www.educoder.net/paths/3,它为程序设计课程提供了大量的实战实训题库,支持公开课、SPOC、作业发布、自动评测、学习情况实时跟踪和统计、问卷调查、测试和考试组织等,如图2所示。实训课程分为3 个阶段,分别测重于改程序、写程序和综合实践能力的培养。实训采用游戏攻关模式,较大的题目可以分解成多个关卡,每个关卡植入相关的编程知识和技巧。每个实训都分为理论知识和实训实战两个部分,知识部分讲述本关卡植入的程序语言知识和编程技巧,学生需要学习掌握相关知识,完成关卡的实训实战才能进入下一个关卡,如果实在做不出也可以选择看答案,教师可以设置看答案后的扣分标准。这种组织方式能很好地展开如何使用模块化的增量式程序设计方法解决较复杂的问题。
Fig.2 Home page of open course of practical training course图2 实训课程公开课首页
(1)课堂组织。支持开设开放课程和SPOC 课程。开放课程只要注册网站就可以加入学习,SPOC 课程针对教学班组织,教师可以通过邀请码邀请学生和教辅加入,可以通过修改人员身份来改变其权限。
(2)实训和作业发布。支持按时发布实训作业和普通作业,教师可以设置每一个实训的截止时间、每一个关卡的分数,可以设置查看答案、延期提交的扣分等。学生可以多次提交,系统进行实时评测并给出评测结果。
(3)学情实时跟踪。支持实时跟踪统计每个学生的作业完成情况、提交次数、课堂活跃度、每个实训的完成情况等。
(4)测试和考试组织。教师可以使用题库组卷组织线上测试或考试,可以自己创建新题,也可以把实训的某个关卡组织进试卷。
计算机程序设计MOOC 依托学堂在线建设,URL 是https://www.xuetangx.com/course/NUDT08091001138/58822 53,为学习者提供了课程全部内容的讲授视频,每个视频后面都有针对关键知识点的随堂测试,如图3 所示。
(1)程序语言知识的系统性。实训实战是培养程序设计能力的关键,但从实战入手,植入的知识和编程技巧在系统性上难免会有所欠缺。如数组与地址的关系等一些难以在实训中体现的知识,需要结合讲授、测验、编程体会等方法才能获得较深层次的理解。
(2)理论促进实践。编写优质程序需要对程序语言有深层次的理解,对于一些重要内容从语言、编译器、计算机系统多个角度进行讲解并反复测验。如指针操作时的内存管理和操作流程等,学生需要从编译器和计算机系统的角度去理解才能有效掌握。
Fig.3 Learning page of computer programming MOOC图3 计算机程序设计MOOC 学习页面
程序设计课程的学习空间依托知士荟建设,URL 是https://learnerhub.net/#/spaces/478,它可以让学习者围绕C++程序设计开展交流、讨论和分享,只要是注册知士荟的用户都可以加入学习空间一起交流学习,如图4 所示。
Fig.4 Home page of programming course learning space图4 程序设计课程学习空间首页
(1)群智学习。课程利用学习空间开展群智学习,加入学习空间的学习者可以围绕C++程序设计开展群体化学习,如提出问题、回答问题、贡献学习资源、下载学习资源、投票、点赞等,进而支持学习者进行自主学习。将实训和MOOC 开放课程的学习者引导到学习空间,与SPOC 课程、线上线下混合开课的学生一起就课程学习开展讨论交流。
(2)基于群组的学习者管理。学习空间管理员可以通过创建群组来组织和管理学习者,汇聚具有共同学习目标和学习兴趣的学习者。群组管理者拥有群组成员和学习空间的管理权限,可以发布群组公告,也可以跟踪每一个群组成员的活动轨迹,统计每个成员某个时间段的发帖数、回帖数、点赞数、资源贡献数、在线时长等信息。
资源和平台建设只是教学生态的硬件,如何有效组织、管理和使用则是教学生态的软件。2020 年春季,两个教学班共150 名学生基于头歌实训课程开设了SPOC,关闭了同期学堂在线和头歌面向社会开设的开放课程讨论区,将讨论交流引导到知士荟的学习空间。由于疫情原因,两个教学班基于雨课堂进行线上教学。为了更好地用好课程学习生态,设计了如图5 所示的教学模式。
Fig.5 Course teaching mode based on programming teaching ecology图5 基于程序设计教学生态的课程教学模式
(1)学生实名注册实训SPOC、MOOC 和学习空间。
(2)在学习空间为两个教学班分别创建群组,方便学情统计和查询学生关注的问题,让教辅加入两个群组,负责整个学习空间的交流答疑。
(3)安排每次课的教学内容,每次课前布置本次课内容相关的实训作业和MOOC 任务。要求实训作业必做,MOOC 视频按重要性分为必看和选看。如果学生通过实训实战认为自己已经掌握了某部分知识,则对应的选看视频可以不看,但视频后面的随堂测试必须做。
(4)课堂教学采用线上翻转课堂,教师在课前查看学生实训完成情况和学习空间主要关注的问题,找出课程的重难点并对上课内容进行微调。课堂教学分4 个部分:①课堂前测通过选择题或填空题检测学生基本知识掌握情况;②重难点讲解根据学生学习情况选择一到两个知识点进行详细讲授,就学生关注的问题进行讨论,为需要进一步学习的学生提供视频或其它学习资源;③随堂实践一般要求应用本次课的知识和编程技巧编写完整的程序,要给随堂实践留下足够的时间并随后进行简单讲解;④课后检测学生重难点知识掌握情况,同时指导学生课后复习,布置下次课的学习内容。
以前,课程答疑交流基本靠上机时间与教辅的面对面答疑以及微信群的线上答疑,由于线上授课不能安排线下答疑,微信群的答疑也让教辅尽量往学习空间引导。由于习惯原因,第一周学习空间发帖数只有5 个,大量的问题还是在微信群。从第二周开始,微信群慢慢安静下来,学习空间的发帖数逐渐增多。前两三周主要是教师和教辅回贴解答问题,慢慢地几个学生活跃起来,几乎承包了学习空间所有问题的回答,教师和教辅的参与越来越少。将网上资源如CSDN 和StackOverflow 推荐给优秀学生,他们碰到疑难问题也会到互联网上寻求帮助。课程结束后,对两个教学班150 名学生进行问卷调查,几乎所有学生都参与了学习空间并得到有效帮助,大多数学生习惯于从学习空间获取帮助而不是提供帮助,见图6(彩图扫OSID 码可见,下同)。
Fig.6 Questionnaire survey on students'use of learning space图6 学生使用学习空间的问卷调查
教学生态建设主要为学生创建一个自主学习的环境,培养学生主动学习的能力,从而实现真正的个性化教学。期望学习者能共同构建一个活跃的学习环境,能喜欢这种学习氛围,在学习过程中碰到问题能及时得到帮助,知道自己想学什么并能获取合适的学习资源。课程结束后,关于教学生态的问卷调查显示,大多数学生都能利用该生态进行自主学习,并能得到相关帮助,学生的学习积极性和教学效果都有了较大提高,如图7 所示。
Fig.7 Questionnaire survey on the whole teaching ecology图7 教学生态问卷调查
教学生态应该是一个开放、活跃、自治的自主学习环境。将头歌和学堂在线加入开放课程,把社会学习者引进学习空间,希望其它高校能依托实训课程开设的SPOC 加入到学习空间,但实际效果并不好。虽然有600 多人注册了学习空间,但根据课程结束后系统后台数据统计结果,社会学习者加入学习空间后的参与度很低,活跃人数只有10 余人,如图8 所示。
Fig.8 Comparative study on the participation of students and social learners图8 本校课堂学生与社会学习者参与情况对比
程序设计课程语言容易教,但计算思维和问题求解能力培养很难,面对不同基础、不同接受能力的学生培养更难。好的学生“吃不饱”、不用教,差的学生跟不上、教不了,导致这个问题的原因不是教师水平不够、投入不多,而是未找到以学生为中心的因材施教个性化教学方法。本文提出建设程序设计教学生态,充分利用各种教学资源和自动化辅助工具,依靠群智学习方法构建自主学习环境,教师从教学的主导者变成学生自主学习的引导者、组织者和管理者,从而实现真正的个性化教学,达到为每个人单独铺设一条能力培养路径的目标。
教学生态应该是一个能自我演变完善的系统,对于学习者关注度很高的问题要在实训和MOOC 中加强,各种资源库和问答库的内容会越来越丰富,笔者学校基于上述方法进行的教学改革和探索成效显著。通过实践,笔者认为生态的开放性还需要进一步加强。如何有效引导社会学习者加入进来,如何有效利用互联网上已有资源提高学习效率还需深入研究。