如何解决程序语言教学中的“知易行难”问题
2018-12-30杨波,张军
杨 波,张 军
(贵阳学院 数学与信息科学学院,贵州 贵阳 550005)
0 引 言
掌握一门程序设计语言的基本知识和编程技能并熟练运用于解决实际问题,是高等院校对理工类学生的一项基本要求。各类程序设计语言课程的教学,一方面需要一定课时的理论教学讲授语言基础知识、语法规则和基本技能,另一方面更需要相当数量的实践课时使学生训练和掌握这些规则与技能,进而培养和提升他们运用理论知识分析和解决问题的能力。
在实际的教学反馈中,常常发现很多学生都存在“课堂上能听懂语法知识,做实验时无从着手”的情况,也就是说,不少学生虽然掌握了一门程序语言的基本规则,却不具备分析一个一般问题并运用所学语言编程知识解决该问题的能力。在课程考核时,很多学生虽然能正确回答试卷中的理论知识,但是对于一个实际问题的算法或程序设计往往无能为力。近年来,“知易行难”问题已成为从事程序语言教学的教师面临的一大困扰,越来越多的讨论集中于对学生实践和创新能力的培养和提高[1-5]。针对这一问题,应从教与学双方进行深入剖析,找出可能的原因并进行相应的处理或改进,以期有效提高程序语言类课程学习的效率,进而培养学生主动进行探索性、创造性学习的能力。
1 “知易行难”问题的表现及原因分析
当前,对于本科阶段理工科学生而言,要求掌握的主流程序设计语言通常包括C、C++、Java、Python等。这些语言虽然有各自不同的应用背景、语法特征、编程技巧和思想,采用不同数据结构表示实际问题中的数据对象,但是核心任务仍然是利用顺序、选择、循环3种基本结构的组合对实际问题的操作步骤进行抽象表达。因此,不论是哪一种语言,其学习过程都是类似的:在初步认识和掌握语法规则的基础上,逐步运用语言中的各类工具求解实际问题并得出正确答案。
1.1 课堂教学中的“知易”
一门语言的基本构件及相应规则总是有限的。即使像C这样包含复杂、易错的指针运算的语言,能运用指针操作的对象也不外乎普通变量、数组、字符串、函数及结构体几类。如果教材组织合理、教学方法得当,学生通常能在给定的理论学时内识记和理解各类语言构件的运用规则。在实际教学过程中,学生通常的反馈是在课堂上听懂基本语法和简单例程分析没问题。事实上,不论哪一种程序语言,其在基本知识和技能的教学中并不涉及晦涩难懂的理论知识和抽象概念,教学内容具体而实践性强。对于大多数学生而言,只要认真听讲,就很容易掌握语法知识和简单例程分析。
1.2 实践教学中的“行难”
相对于基本语法知识的“知易”,学生在完成课下的编程作业或实验任务时,常常感到“无从下手,不知怎么开始”。面对这样不够具体的问题反馈,任课教师也很难找到原因所在,特别是一些有多年程序语言教学经验的教师,会疑惑为什么同样的教学过程,以前的学生基本没有这样的问题,近年来却越来越多学生反馈“听得懂、不会做”。
大致上,“行难”问题通常表现为:①面对一个编程任务,不能确定程序所要处理的计算对象是什么;②即使能正确分析出计算对象,也不知道采用哪些程序结构及其组合正确表达数据的操作步骤;③能正确给出一个问题的求解算法,但在实现时往往由于语法错误较多或经验不足导致调试通过耗时较多,甚至越改越错;④对较为复杂的实际问题,不能采用正确、合适的数据结构表示其中涉及的对象,也较难对问题进行合理的分解和组合。
以上表现中,①—③出现在初学者的入门阶段,④则常出现在学生基本能完成一些简单编程任务后的提高阶段。
1.3 “知易行难”的原因
学生在掌握基本语法规则后,面对实际问题仍然无从着手、不能写出正确可行的算法或代码,从教与学两方面来看,原因有以下几种。
1)教学内容相对固化,教学方式较为传统。
通常,程序设计语言类教材的内容组织架构都是以从易到难、从简单到复杂的顺序逐一介绍语言中各种构件的使用规则和基本运用。为适应不同的学习者,教材中的例程和习题也大多为常见简单数学或日常问题的求解。教师在安排课堂讲授和实验时,一般以教材内容为主,依教材顺序按部就班推进教学过程,很少针对学生的程度、专业方向等进行适当的增删或取舍;在完成一个语言构件的语法知识讲授后,安排一定数量的编程习题作为实验内容,由学生上机完成程序的调试运行。这样相对固化的教学内容与方式不太可能在最大范围内提升学生对于程序语言学习的兴趣度。
2)相关课程间衔接存在一定误差。
程序语言类课程的开设不会早于第二学期,在此之前,学生通常都已学习过计算机文化基础或计算科学导论课程。这类课程一般着眼于计算机基本操作和常用工具软件的使用,对于引领学生认识编程逻辑几乎没有作用。IT类专业的课程体系中,算法与数据结构类的课程必不可少,开课时间通常晚于第一门程序语言课程。在学生作为初学者第一次接触程序设计语言时,并不具备算法设计与数据结构方面的知识,这样在学习语言的过程中,就难免出现1.2节中的第4种表现。
3)学生独立思考能力和自主学习能力较弱。
很多在高校(特别是地方普通院校)任教多年的教师都有一个共同的感受:当下的学生似乎普遍没有10多年前的学生“聪明”,以前的学生在认知能力、推理能力、自主钻研等方面的表现普遍好于后来的学生。这种现象的出现,大概源于两个原因:一是近20年来高等院校不断扩招,大大提高了学生进入大学的几率,然而事实上不少学生在学习能力和自身素质上是达不到10多年前的高校录取标准的;二是中学阶段以升学率为第一指标的应试教育体制,很多升学率高的中学多年来已形成一套完善且相当有效的应试训练体系,即使是资质一般的学生,通过“刷题”之类的机械式训练,也能取得不错的高考分数,但这种机械训练方式在较大程度上扼杀了学生进行独立思考和自主学习的能力。
4)环境影响学习习惯和学习风气。
外界环境中的一些因素对学生的学习习惯和学风有较坏的影响。一些中学教师常以“现在辛苦学,进入大学就轻松”之类的说法激励学生,这就使得不少学生在完成中学阶段繁重的学习任务后,一进入大学就由于目标达成而丧失学习动力;再者,大学的教学方式不再是由老师“看”着学,学生无所适从,找不到正确的学习方法,特别在一些地方普通院校中,由于没有了教师的督促,学生在课下很少主动自习或深入钻研;此外,社会上偶有的“知识无用论”以及电子游戏的泛滥,也对一些思想不够成熟、自制力弱的学生产生了很大影响,导致学生怠惰,无心学习。
程序语言的学习需要学生有较强的逻辑分析和动手实践能力,对学生的学习主动性和积极性有较高要求。学生仅仅在课堂上听懂一门语言的语法规则和例程分析是远远不够的,需要在课下主动思考、积极动手、勇于探索才能真正熟练掌握这门语言,然而,由于前述3和4两个原因,能满足以上要求的学生并不多,这就使得学生在初学一门语言时常常是“听得懂,不会编”。
2 对策分析
2.1 改革课程教学内容与教学方式
首先,要根据上课对象、学时分配等条件,对教材中的章节进行合理取舍。如果是入门语言,可将一些对初学者而言难于理解和掌握,且属于进阶提升的内容(如C中的外部函数、动态内存分配、指针数组、链表、位操作等)暂时搁置,待学生能熟练运用语言主要构件后,必要时再根据专业需要将其作为补充内容加入。如果学生之前已学习过其他语言课程,则可将与之前课程重复或相似的内容作略化处理(如一些面向对象语言的教材中仍然会介绍变量、常量、数据类型、程序3种基本结构等基础知识),而将重心放在当前语言的核心特征上。
其次,拓宽例程分析或实验任务的范围,引入与学生专业背景相关的实例或问题进行分析与求解。例如,对于电子类专业学生,可在讲授C语言的选择或循环结构时演示C代码中条件判断对一些受控实体(如智能小车、无人机等)的控制作用,让学生能真正体会编程在本专业领域内的应用。
第三,前述两点对于教师提出了较高的要求,仅靠任课教师一人并不容易做到。教学院部可考虑将相关课程组成课程群,具体到程序语言类课程,可以将各类语言课程和算法与数据结构课划入同一课程群中。针对课程群成立课程教学组,组内成员既有分工,又有合作,各成员分别担任课程群中一门课程的主讲教师,同时也为群内其他课程提供支持。成员间的合作可以是相关课程间知识点的衔接教学,也可以是共性知识的平台化教学,如常量、变量、数据类型、程序3种基本结构等基本知识可由讲授入门语言的教师负责讲好讲透,各类语言涉及算法和数据结构的部分则由数据结构课程主讲教师负责讲解。
最后,一直以来惯常的“课堂讲理论,课下编程序”教学模式使得学生在课下缺乏指导,面对实验任务无从着手。教师可以在课堂上给出与实验任务相近但较为简单的题目,现场引导学生完成任务分析、算法描述、代码编写及调试运行的全过程。学生若能在课堂上完成简化版任务,则课下再进一步钻研完成实验的主动性和兴趣度都会得到提高。此外,教师可提供一定数量与当次实验内容相关的例程,要求学生在课下进行阅读分析,然后撰写阅读分析报告,与实验报告一起进行评定。
2.2 适当调整相关课程教学内容
学习程序语言的核心不在于掌握各构件的语法规则和使用技巧,而在于能将实际问题的操作步骤利用程序结构进行正确、高效的表达,这需要学生具有严密、清晰的逻辑思维。Scratch虽然是面向青少年的简易编程工具[6],但是建模、控制、逻辑、运算等编程要素都在其图形化界面操作中得到体现。在地方院校中,很多学生进入大学前没有条件和时间较为系统地接触程序设计,如果能在他们进校后普遍开设的计算机文化基础或计算科学导论课程中增加一个章节讲授Scratch,可让学生对程序设计的各要素有一个初步的感性认识,也为后续的程序语言学习建立起兴趣基础。
对IT类专业学生而言,算法和数据结构课程是学生深入程序设计领域的必修基础课程,需在学生掌握一门基本语言(通常为C、C++或Java)后才能开设。对于第一次接触程序语言的初学者而言,并没有算法和数据结构方面的知识基础,在遇到较为复杂的问题时,自然就无法对其中的计算对象和操作步骤进行有效、正确的抽象表达。为弥补这一不足,需在入门的语言课程中适当加入算法和数据结构方面的知识;在学习程序3种基本结构的控制语句时,首先强调其算法描述,然后再讲授相关语句的具体使用;在分析典型例程和布置作业、实验任务时也要将算法分析作为重点,以期逐渐培养学生分析和解决实际问题的能力。例如,对于2.1节中的第3点建议,可考虑由算法和数据结构类课程负责人将控制结构和数据结构的内容做成较为简化、占用学时数较少的通识型教学资源,语言类课程在学习到相关知识点时,由算法和数据结构类算法的主讲教师提供支持。
2.3 将明辨性思维方式引入课堂教学
很多学生在多年应试教育体制训练下形成了“老师怎么教就怎么学”的学习习惯,较难在课下主动学习并进行独立思考。在教学过程中引入明辨性思维方式,有助于引导学生摆脱盲从,养成带着问题学知识的习惯。
明辨性思维也称为批判性思维(critical thinking),原意是指逻辑清晰严密的思考,是一种非盲从的、分析的、推理的、反思性的思维方式。明辨性思维“是对思维展开的思维”,进行明辨性思维的目的是考量自己或他人的思维是否符合逻辑,是否符合好的标准,从而做出明智决定或得出正确结论。明辨性思维具有避免接受或做出不好的论证、排除无关因素干扰、不受情感/偏见/谬误的支配、不盲从权威或臆断等基本特征,具体包括判断信息的恰当性、区分理性断言和情感断言、区别事实和观点、识别不足证据等21项技能[7]。在程序语言教学中引入明辨性思维,可尝试以下方法。
(1)避免灌输型教学,给学生留主动学习的机会。在程序语言的教学中,给出所讲授语言构件的主要框架和重点、难点,该构件使用中的各种细节则交由学生补充完善,让学生在掌握主要使用方法的前提下通过实践逐渐深入体会。
(2)通过提出问题增加课堂讨论。每堂课可针对所讲授知识点设置一些(开放性的)问题,以提问或学生分组的形式进行充分讨论,引导学生从不同角度认识和分析问题,并给出合理的最佳解决办法。
(3)课程任务注重培养和提升学生进行独立思考和探索的能力。教师在布置习题或实验任务时应摒弃所谓标准答案,强调方法的多样性或结论的非唯一性,鼓励学生提出不同的思路,及时高度肯定学生给出的有效而与众不同的解决方案,营造敢于探索和创新的学习氛围。
2.4 充分利用第二课堂推动学生主动学习
强大的程序设计能力一定是来源于大量的实践,课堂教学范围内的习题或实验任务并不能提供足够宽广且深入的编程实践。第二课堂活动的开展,可在很大程度上弥补这一不足。程序语言类课程组的教师应组织学生建立编程或其他与专业相关的兴趣社团,通过社团活动(如讲座、竞赛、项目开发等)为学生提供交流、实践、提升编程技能的机会和平台,充分发挥第二课堂对课堂教学的补充和深化作用。
3 结 语
程序语言类课程具有非常强的实践性,仅仅掌握基本语法知识而缺乏足够的实践,学生就不可避免地面临“知易行难”问题。设计得当的教学内容和教学方法,着力于推动学生独立思考、主动探索、积极实践,可以让他们掌握并熟练运用一门程序语言。这不仅可为学生利用计算机技术解决专业问题进行技术储备,更为重要的是,还可训练和培养学生进行严密逻辑思维、正确分析和求解实际问题的能力,而后者才是一名合格大学毕业生的核心竞争力。