编译原理语言认知实验设计与实践

2019-08-24 08:58计卫星王贵珍
计算机教育 2019年8期
关键词:程序设计代码算法

计卫星,王贵珍,李 侃

(北京理工大学 计算机学院,北京 100081)

0 引 言

计算机高级程序设计语言自20世纪50年代出现以来,至今已经演化出成百上千种语言,这些语言面向不同的应用领域被不同的群体使用。少数语言自诞生以来一直保持旺盛的生命力,在计算机发展历史上发挥了重要作用;部分语言只在某个社区内被广泛使用,具有明显的专业领域特点;还有一些新兴的语言,一直在研究人员和相关社区的努力下不断发展壮大,正在逐步完善并得到大家的认可。TIOBE[1]排名显示,目前最流行的前10种程序设计语言分别是Java、C、C++、Python、C#、Visual Basic .NET、PHP、JavaScript、SQL和R。在这些语言当中,C语言属于传统的面向过程语言,C++、Java和C#是目前主流的面向对象程序设计语言,Visual Basic在.NET平台上得以持续发展,PHP、Python和JavaScript是脚本语言,SQL是声明式语言,R则是面向数据分析的专用语言。

各个学校依据各自的定位和培养目标,在计算机类相关本科专业培养方案中,通常会设置1~2门程序设计相关的课程。目前各个院校采用C语言的较多,非信息类逐步采用Python作为其首选程序设计语言,信息类学生在学期间也有选修C++、Java和C#课程的机会。尽管如此,有限的学时仍然无法让学生学习、领略各种不同程序设计语言的特点,因而造成学生只会使用1~2种程序设计语言,教和学两方面更多关注编程语言使用,而对高级编程语言自身的设计、改进以及语言的实现认识和思考不足,最终导致相关研究人才的缺乏。因此,如何在有限的学时内弥补这个不足,让学生尽可能多地接触多种程序设计语言,是一个值得探讨的问题。

各个学校在不断加强实践教学体系建设的同时[2],也逐步探索与语言设计和实现相关的内容。文献[3]中针对编译原理课程理论完整性不足、课程定位模糊、与其他课程内容重叠等问题,提出建设形式语言与编译课程。文献[4]认为面向对象编程语言和技术日益流行,对编译原理课程建设和教学改革实践提出新的挑战,因此提出基于面向对象技术的编译原理课程建设。

1 语言认知实验设计

语言认知实验的目的是通过一个课程实验让学生了解程序设计语言的多样性,具体要求为使用多种指定的语言实现同一功能,如使用C语言、Java、Python、Haskell和汇编语言实现快速排序算法,并对用不同语言实现的程序进行比较和分析,主要包括语言学习难度、代码规模、运行效率等。

该实验的首要目的是让学生了解语言的多样性,语言实现方式的不同对程序编写以及程序运行效率带来的影响,因此,选择什么样的语言和实现什么样的功能是非常关键的。考虑到语言的发展历史和现状以及语言的类型,所选语言应能够覆盖经典的面向过程语言、面向对象程序设计语言、脚本语言(动态语言)、函数式编程语言、命令式编程语言等。从语言的实现角度考虑,则希望覆盖编译执行和解释执行两种方式。

为了方便对不同的语言进行对比,应选择难度和规模适中的算法让学生使用不同的语言实现。算法难度和规模过大时,一方面学生难以完成,另一方面学生关注的焦点容易发生偏移,无法达到实验预期目标。当难度和规模适中时,学生会有更多的时间和精力进行语言之间的比较,因此,一般应该选择已经学习过的常见算法来实现,如矩阵乘法、各种排序算法等。

在对比阶段,主要关注代码规模和程序运行效率的对比。代码规模以代码行为单位进行统计分析,包括输入输出和具体计算的代码;而运行效率则只关注计算部分的运行时间,忽略输入和输出部分。考虑到输入较小时,部分算法的运行时间变化较大,应考虑规模适中的输入数据,并多次运行程序和采集运行时间,取平均值作为最终的性能数据进行对比分析。学生根据对比结果,撰写实验报告,提交相关资料,其中包括对比分析的算法选择、对各个语言的认识、实现方法、运行结果、语言学习难度比较、程序规模比较、程序运行时间比较等。

实验评定阶段,在尊重学生分析成果的基础上进行适当引导,触发学生更深层次的思考,如为什么不同语言对同一算法的描述会造成程序规模的不同、脚本语言和C语言程序相比性能相差较大的原因是什么等。

2 语言认知实验教学实践

根据编译原理与设计课程的教学计划,语言认知实验安排在第一章引言之后进行。在引言部分主要介绍程序设计语言从机器语言到高级程序设计语言的发展历史,重点解释编译程序的定义及其分类,特别强调编译执行和解释执行两种不同的执行方式、编译程序的典型框架结构以及从输入高级语言程序开始到目标代码翻译的工作流程和中间表示,最后以代表性编译器为例进行剖析,说明编译器的构造方法,这一部分的教学安排也是国内众多高校所采用的方案。这一部分的教学内容存在多个与语言相关的知识点,主要包括:①语言的发展历史以及编译器产生的背景;②编译程序的基本定义及其输入和输出;③编译执行和解释执行。

将语言认知实验安排在引言部分非常有利于学生对相关概念的认识和深入理解。表1给出了从2014年到2018年,笔者在实践过程中所选用的语言和要求学生实现的功能。对比可以发现,在这个过程中主要的改进在于将小众的Ruby语言改为Python,并在2018年添加汇编语言,这主要是由于网络安全、大数据、人工智能等学科专业的飞速发展,Python语言热度不断上升,学习的需求日益增大。添加汇编语言的目的是为了让学生更好地了解编译器的输出,在第一章手动完成从高级程序设计语言到汇编语言的翻译,并与后续实验生成的汇编语言进行对比,另外,也可以帮助学生提前预习汇编程序设计的相关内容。

表1 2014—2018年教学实践设置

在实验完成后,要求学生提交相关源码以及实验报告。实验报告中从3个方面对多个不同的语言进行对比分析:①代码规模:以代码行对比实现同一功能的不同语言程序的规模大小;②运行效率:在输入相同时,对比分析不同程序实现同一功能的运行时间;③语言易用性:从学习曲线、编程效率等方面对不同的语言进行对比,给出自己的结论。

3 教学效果

为了更好地了解语言认知实验的教学效果,2018年教学考核完成之后,课程组设计了调查问卷并对收回的问卷进行统计分析。经统计,语言认知实验能够加深学生对语言和编译器的认识,并对后续的学习和实践产生深远的影响。

(1)认识到语言的多样性。如图1所示,在语言认知实验之前,大多数学生熟悉的是C/C++,接近20%的学生熟悉Python语言,而大约10%的学生会使用Java语言;在语言认知实验之后,这一状况发生了明显变化,熟悉并喜欢Python的学生接近35%,对Java比较认同的学生比例上升到了20%,同时Haskell从原来的0%变为接近4%。多个语言的学习和接触让学生有了更多的选择机会,通过语言之间的比较分析,学生找到了更适合自己的语言。

图1 语言多样性认识对比

(2)认识到语言的差异性。语言认知实验的主要目标之一是让学生认识到语言之间的差异性。从程序的执行方式、编程效率、程序规模、学习曲线等方面进行统计,结果如图2所示。从图2的统计结果可以看出,80%左右的学生认识到不同语言实现同一个算法的效率是不同的,对应的代码规模也不相同。此外,50%左右的学生认识到语言执行方式不同和执行效率不同,这有利于加强对编译引论阶段所给出的编译执行和解释执行的深入理解和直观感受。此外,通过本次实验,部分学生发现不同语言的程序结构不同,对于程序语言自身的描述和表达方式有了更加深入的认识。

(3)了解实施过程存在的问题。为了了解实施过程中存在的问题,调查问卷中包括实验中遇到的主要困难等问题,如图3所示,80%以上的学生认为新的语言学习需要时间,而超过50%的学生认为程序开发环境的搭建比较费时费力,由此也导致超过40%的学生认为实验时间比较紧张。

(4)独立完成分析。由于每次选择的算法规模和难度适中,因此不可避免能够在网络上找到已有的实现代码,如使用Haskell实现的快速排序算法。在具体实践的过程中,并没有要求所有代码自己从头编写,但是要自行理解和运行代码。代码来源统计结果如图4所示,大约21%的学生是完全自己编写的代码,而约74%的学生是从网上搜索部分代码后运行的,剩余5%的学生是从网络搜索获得全部的代码。

4 持续改进措施

新语言的学习是了解程序设计语言多样性的必需过程,其中学生一部分精力主性化教学资源推荐,包括教学视频(SPOC),或推送更多的参考练习题;(2)组成动态讨论小组,由助教组织进行再讲解和分享。

课程教学一学期结束后闭卷期末考试,传统班级和教改班级题目相同。传统班级采用纸质考试(编程题有过程分),教改班级在线考试(编程题没有过程分,但有多个测试得分点)。两个班级期末考试分数对比如图8所示。

图8 教改班级和传统班级期末考试成绩对比

可以看出,敏捷教学模式大大地提高了学生能力水平及知识点的掌握程度。教改班级期末考试90分以上的学生占45%以上。传统方式培养的学生分数段集中在60~80分左右。值得注意的是,由于教改班级判分严格,不及格人数占比4%,而传统教学班级纸质考试判分较灵活,无不及格。还有一种可能是强节奏的能力冲击是使个别学生跟不上,最终掉队。

图9显示了教改班级期末考试知识点掌握情况柱状图,大部分学生掌握情况良好。但发现学生对指针、变量作用域等知识点掌握得不尽如人意,分析是因为临近期末教学比较匆忙,指针内容灵活难以消化;而变量作用域则是因为没有专门进行测试和布置作业,造成知识消化不够完全。令人惊奇的是,第一能力层级的输入输出语句得分率偏低,查阅下一层知识点掌握情况发现,由于“格式化输入输出”记忆性和技巧性较强,并学过的时间较长,很多学生已经忘记或者忽略,提示下一轮教学中,考试前需要给学生强调记忆并加强练习。

5 结 语

我们提出对程序设计基础课程进行知识图谱及能力层次构建,利用在线考试平台的不同平台进行概念测试和能力评估。进而提出适合程序设计基础课程的一种混合敏捷教学模式,在教学实践中取得了较好的效果,有积极的推广意义,并为其他工科课程改革提供了有益的参考。

猜你喜欢
程序设计代码算法
基于SolidWorks和VBA的电机阶梯轴建模程序设计
哪种算法简便
医学专业“Python程序设计”课程教学改革总结与思考
基于Visual Studio Code的C语言程序设计实践教学探索
Travellng thg World Full—time for Rree
从细节入手,谈PLC程序设计技巧
进位加法的两种算法
根据问题 确定算法
神秘的代码
一周机构净增(减)仓股前20名