陈立前,董 威,尹良泽,毛新军
(国防科技大学计算机学院,湖南长沙 410073)
软件工程以提高软件生产率和软件质量为目标,随着人们对软件的正确性、可靠性、安全性等可信需求日益迫切,软件质量尤其是代码质量得到了越来越多的关注和重视。尤其是,对于大型软件项目而言,开发人员多、代码规模大,如果没有高质量的代码作为基石,很难产出高质量的软件产品。任正非在其签发的华为总裁办2019 年一号文件《全面提升软件工程能力与实践,打造可信的高质量产品》中明确指出:“我们要从最基础的编码质量做起,视高质量代码为尊严和个人声誉。代码就像是高楼大厦的一砖一瓦,没有高质量的代码,可信的产品就是空中楼阁。”由此可见,代码质量对于当前IT 企业界打造高质量产品的重要性日益凸显。
对于软件工程人才培养,代码质量教育是软件工程能力素质培养的一个重要方面,编写高质量的代码也成为软件工程师必备的职业素养。但是,在软件工程课程教学过程尤其是软件项目实践过程中,学生主要关注软件系统功能设计与实现,而往往忽视了代码质量。究其原因在于:学生对高质量代码的重要性认识不够,“代码之美”感受不多,缺乏体验;学生在课程规定的时限内,会尽量实现和完善更多的软件功能以体现工作量,但因开发经验不足而导致实现的代码存在不规范、可读性差等问题,代码质量没有保证;学生排查软件缺陷经验不足、能力弱。
为了在人才培养中有效应对这些问题,围绕学生读代码、写代码、评代码、改代码4 个环节,从高质量开源软件代码阅读、编程规范学习与规范编程、代码测试分析能力训练3 个方面,设计相应的教学活动,以形成面向代码质量提升的软件工程能力素质培养体系,构建面向代码质量评价与提升的支撑技术和工具集。
代码质量一直是软件工程学术界和工业界关注的重要主题,也是软件工程教育的重要方面。
在软件工程教育方面,软件质量是软件工程教育知识体系(Software Engineering Education Knowledge,SEEK)的重要知识领域之一。文献[5]指出由于软件工程缺失导致软件开发项目中软件质量和生产率方面的问题越来越多,由此设计一种面向软件过程和软件质量教育的软件工程相关技能、知识与训练框架;文献[2]指出当前代码质量教育方面的不足,提出将代码坏味检测工具引入程序设计课程实践教学以提高代码质量教育水平;文献[6]指出软件工程课程实践教学中学生缺乏大规模和高质量软件开发经验以及高质量软件设计开发能力不足的问题,提出基于高质量开源软件的阅读与维护以培养软件工程能力;文献[7]探讨程序设计教学中程序设计风格养成的重要性,以及如何在课程教学中引导学生重视并养成良好的程序设计风格,同时介绍一种将程序源代码转化为图形以实现代码质量可视化评判的方法,旨在支持教师根据标准图形模式对学生的代码质量进行评判。
在工业界代码质量管理方面,文献[1]分析企业代码管理方面的建设与管理现状,对代码质量管理的组织管理、工具技术、技术规范、人员培养和流程管理等方面进行探讨,并提出一些实践建议;文献[8]总结如何实现代码整洁和干净的经验规则;文献[9]从代码风格统一问题、编程语言安全问题、编译工具告警开关以及告警消除的监控问题等方面,根据能力成熟度集成模型的软件质量过程和国际标准化组织的软件质量模型对各类规则进行梳理,开展代码质量检测实践。
在代码质量相关学术研究方面,文献[10]分析开源软件代码质量问题和软件开发人员代码质量现状,并研究了面向开源软件的代码质量问题与软件缺陷之间的关系;文献[11]针对源代码分析注释的质量评价,提出一种综合考虑客观质量属性和主观质量属性的质量评价框架,以支持对源代码分析注释进行更全面的质量评价。
相比已有工作,本文主要从软件工程教育的角度,关注学生代码质量意识的养成以及代码质量评价与提升能力的系统性训练与能力素质培养,教学实施过程涵盖读、写、评、改代码等多个训练环节。
代码质量直接关系到软件项目的产品质量、效益、成本、生命周期等,同时对软件开发组织的生产效率与团队协作效率都有重要影响。目前,研究人员已提出了很多不同的度量指标,从不同的角度衡量代码质量。从定性角度,评价代码质量的指标一般包括可信性、可维护性、可读性、可移植性、可重用性等;从定量角度,可从缺陷数、缺陷密度、代码复杂度等方面进行度量。软件开发人员可以通过遵循编程规范、人工审查代码、测试与代码分析、重构代码等方式提高代码质量。
从软件工程人才培养角度看,代码质量提升的训练过程要与软件工程专业的教学目标、核心课程、知识领域和知识点等有机结合,将训练环节与正常的教学活动融为一体,确保学生在达到软件工程相关规范和培养方案要求的基础上,进一步显著提升代码质量能力和素养。为此,在具体教学实施过程中,围绕代码质量提升,以软件工程教育知识体系SEEK为指导,与软件工程专业培养方案中专业核心课程的各种教学活动相结合,结合课堂教学与课外实践,形成一体化实施过程,以达成代码质量能力素质训练不断线。上述过程总体如图1所示。
Fig.1 Training process and teaching practice for code quality competency图1 代码质量能力素质培养过程与教学实施
具体教学实施时,首先让学生认识到代码质量的重要性,可通过典型案例、思政教育、当前IT 企业发展现实需求等对学生进行引导。在此基础上,结合软件工程教育知识体系SEEK,让学生了解代码质量的属性、度量方法和质量提升方法,增强学生的代码质量意识。进一步地,通过阅读和剖析优质代码,快速建立学生对高质量代码的感性认识。并且,让学生在软件开发项目实践过程中,运用代码质量相关知识,进行高代码质量的编程实现。在这一过程中,组织对学生代码质量进行评分,给出评价意见。最后,让学生依据评价意见,修改代码。
从实践角度看,上述教学实施涉及学生读代码、写代码、评代码、改代码4 个阶段的综合能力。对每个环节的主要关注点考虑如下:
(1)在读代码环节,通过梳理优质代码案例,引导学生进行总结与抽象提炼,然后结合软件工程教育知识体系SEEK 中的相关知识点,加深学生对背后原理的理解,提升其代码质量鉴赏能力。最终,形成结合泛读、精读、标注的代码阅读与代码之美欣赏能力培养体系。
(2)在写代码环节,让学生学习编程规范相关的国军标、行业标准等,引导学生养成良好的编程风格。在软件项目实践开发过程中,让学生遵从软件架构与软件设计原则,遵循相关编程规范,编写出规范、安全鲁棒、可读性强的代码。
(3)在评代码环节,形成代码规范性自动检查与代码质量评分方法,构建相关辅助支撑工具集,给出量化评分。进一步地,训练学生应用软件测试、静态代码分析技术与工具自动检测代码缺陷的能力。
(4)在改代码环节,让学生根据评代码环节给出的评价意见,依托Git 等版本管理平台,修改甚至重构代码,并让学生亲自比较和感受修改前后版本的代码质量差异。
本文将重点围绕高质量开源代码阅读、规范编程、代码测试与分析3 个方面,介绍如何开展面向代码质量提升的教学实施。在此基础上,介绍面向代码质量评价与提升的辅助支撑工具集以及教学实施效果。
鉴于软件工程课程施教初期,学生尚缺乏大规模高质量软件开发经验,设置相应的教学环节,让学生阅读具有一定规模的高质量开源软件的源代码,通过尽早接触优秀的高质量软件以增强学生质量意识。在这一过程中,设计相应的教学活动,对学生如何高效阅读代码进行引导和阶段性检查。主要分为代码泛读、代码精读、代码标注、撰写并分享代码阅读报告4 个阶段。代码泛读的主要目标是让学生在较短时间内快速掌握该软件的功能和概要设计,包括软件体系架构、模块划分等。代码精读则是在学生已经基本掌握软件整体架构的基础上,进一步体会软件的详细设计、代码规范、实现方法和技巧等。代码标注是让学生对开源软件中的关键模块及其关键代码文件、关键数据结构、关键函数等进行标注,通过代码注释等方式描述代码的主要功能、实现原理等,旨在培养和提升学生对开源软件代码的理解、分析和描述能力。撰写并分享代码阅读报告,是让学生对整个代码阅读过程和积累的素材进行总结、分析和分享,包括软件体系架构图、模块划分图、代码规范、收获和体会等,旨在让学生加深对代码质量的系统性理解和共鸣。
在具体施教过程中,选择应用软件“小米便签”、开源数据库软件Redis、Facebook 重构的高效底层组件库Folly、设计模式示例代码库java-design-patterns 等规模适中的高质量开源软件作为学生阅读的目标软件。这些软件覆盖软件类型不同,采用编程语言不同,学生可以根据自己的基础和兴趣,通过分组形式,选择合适的软件进行代码阅读。在该过程中,让学生熟悉和运用优秀的代码阅读工具Source Insight、Understand 等,以及代码标注工具Codepedia等。
经过代码阅读阶段性训练,观察到学生对较大规模高质量软件有了一定的感性认识,对如何开展高质量软件设计和编码实现也有了一定的认识和尝试,软件设计与编码能力得到增强,为后期系统学习软件工程的方法和技术以及开展软件项目实践打下了良好基础。
在程序设计、软件工程等相关课程学习中,让学生遵守编程规范、养成良好的编程风格至关重要。养成一种良好的编程习惯,可以让学生受益终生。目前,已有许多优秀程序员总结出了很多经验性的且非常实用的编程规则,形成了行之有效的编程规范。这些编程规范,一方面能够减少编程出错概率,另一方面能够在保证程序正确性的前提下使程序结构清晰、逻辑简明、易读易懂。一些编程规范已成为国际、国内标准,有些已成为IT 企业内部必须遵守的编程规范。如MISRA(汽车工业软件可靠性联合会)发布的针对汽车工业软件安全性的C 语言编程规范MISRA-C,已成为C 语言安全规范的事实标准。Google 公司制定了公司内部使用的编程规范,包括《Google C++编程风格指南》《Google Java 编程风格指南》等。在国内,国军标《GJB5369 航天型号软件C 语言安全子集》,已成为国内航天领域的C 语言编程标准,同时也是目前国内军工行业代码规则审查的主要参照依据。此外,代码质量与其整洁度成正比,让学生学习代码整洁之道,尤其是一系列行之有效的整洁代码操作实践,写出优雅、整洁、易懂的代码,这也是软件工程实践过程中的重要一环。
具体施教过程中,结合学生未来职业发展和任职岗位需求,介绍编码规范要求和编程风格建议。具体而言,从如下几个方面对学生进行引导,帮助他们遵守编程规范、养成良好的编程习惯。
(1)结合软件工程教育知识体系中相关知识单元和知识点,介绍编程规范关注的方面和规范化原因。编程规范关注的方面通常包括标志符命名、代码布局(如缩紧、空格、空行等)、代码注释、控制结构、数据结构、模块设计等。从认识编程规则背后原理方面,以编程规则“避免对浮点数作‘相等’或‘不相等’判断”为例,该规则在MISRA C、国军标GJB5369-2005 等编程规范中都是强制类型编程规则,究其规范化原因,需要教师从机器表示的角度,讲解机器浮点数与数学实数的差异,以让学生明白制定该规则背后的原因,从而产生认同感。总而言之,良好的编程风格能极大提高程序代码质量,包括程序的可读性、可维护性、健壮性和可重用性等。
(2)引导学生运用代码规范化工具或编程风格检查工具。给学生推荐Uncrustify、GNU Indent 等代码规范化工具,以及Cpplint、CheckStyle 等编程风格检查工具,让学生检查自己编写代码的规范性。让学生掌握如何应用自动化的工具对程序代码进行规范化,可以快速增强学生对于代码规范性的体验和成就感。
(3)在软件工程相关课程形成性考核中,注重代码规范性的评分和评价。在验收学生开发的课程实践软件项目时,除考察软件功能方面的工作量外,还需考察代码质量尤其是代码规范性。通过对代码规范性进行评分,可有效激励学生更主动、更自觉地学习和遵循良好的编程规范和软件设计准则。在该过程中,教师可以借助代码质量检查工具SonarQube 等自动化工具,对学生代码规范性和代码质量进行量化评估。
代码缺陷是影响软件代码内在质量的重要因素。为了发现代码中存在的缺陷,软件测试与源代码静态分析是目前工业界常用方法。对于国防、航天等领域的安全关键软件,软件开发过程中尤其重视这方面的开发活动。因此,从课程学习开始,培养软件工程专业学员在这些方面的能力和素质,对于学生未来的职业发展具有重要意义。
目前,开源的软件测试工具已经较为成熟,并具有一定的技术先进性,因此在软件工程相关课程中,选取一系列有针对性的测试工具用于技术讲授和软件项目实践。对于单元测试,采用Junit 工具定义测试用例;对于组合测试,采用PICT 工具生成高效测试用例结合;对于白盒测试,采用CFG Generator 生成程序控制结构,以支持路径测试;针对性能测试,采用JMeter 进行高效测试;对于Web 软件,采用Selenium 进行测试;对于测试覆盖率分析,采用CodeCover 进行分析和对测试进行评价。
程序静态分析技术门槛相对较高,其理论具有一定复杂性,使用起来需要对漏报、误报等予以更多考虑。当前,IT 工业界正在积极引入程序静态分析技术和工具,但目前具备相关知识能力的人才相对缺乏。为此,在软件工程课程中适当将程序分析技术和工具引入教学中。让学生熟悉包括CppCheck、FindBugs、PMD 等在内的基于缺陷模式和简单控制流数据流的分析工具,以及Infer、Clang、FramaC 等基于程序语义的分析工具。此外,为了让学生结合实际软件缺陷熟悉静态分析技术和工具,让学生针对国际主流的Juliet Test Suite 等缺陷代码基准测试集以及CVE 漏洞库,应用在这些工具开展实验,以加深学生对软件缺陷和漏洞的认识。
通过上述训练,学生对代码缺陷及其检测技术有了更深入的理解。在此基础上,要求学生将这些方法与工具应用于学生自己编写的软件工程实践项目的源代码上,并对检测出来的代码缺陷进行调试和修复,以提升其软件项目的代码质量。
在教学实施过程中,积累了一系列以开源软件工具为主体的面向代码质量评价与提升的辅助支撑工具集,包括代码阅读工具、代码标注工具、代码规范化工具、编程风格检查工具、代码质量评估工具、软件测试工具、静态程序分析工具等,可满足面向代码质量评价与提升的软件工程能力素质培养需求。具体而言,面向代码质量评价与提升的辅助支撑工具集如图2 所示。软件工程相关课程的授课教师可以让学生选择并利用其中的工具以提升其代码阅读能力、规范编程能力、代码测试与分析能力、代码质量评估能力等,最终提升其软件工程代码质量综合能力素质。
Fig.2 Supporting tools for code quality assessment and improvement training图2 面向代码质量评价与提升的辅助支撑工具集
开展上述面向代码质量提升的教学实施以来,学生在经过相关训练和阶段性考核后,学生的代码质量意识以及在课程实践项目中编写的代码质量有了极大提升。具体而言,通过对高质量开源项目代码的阅读标注与特征分析,从学生撰写的代码阅读报告中,可以感觉到学生建立了对高质量代码的感性认识,并对其重要性产生了认同感;通过规范编程训练与检查、学生代码质量评分与评价等环节,学生掌握了如何运用代码质量评价与提升相关方法与工具解决实际代码质量问题,在课程实践项目中能够编写出规范、可读性强的代码;通过在课程项目实践中训练学生应用软件测试、代码分析方法与工具,使得学生能够更早接触实际工程中代码质量控制所使用的一些工具及流程,学生代码缺陷检测和定位能力得到了加强。同时,学生对软件缺陷的调试和修复也有了新的认识。此外,通过后期反馈了解到,代码质量评价与提升训练对学生后期综合实践、毕业设计等环节的软件开发也起到了积极促进作用。
随着软件技术的发展和IT 企业界对软件产品质量的要求越来越高,代码质量已成为衡量软件开发者能力水平的重要因素,也是软件开发组织能力水平的重要体现。因此,在培养高水平软件工程人才过程中,如何培养学生的代码质量意识、能力、素养需要得到重视,这对于我国未来软件产业发展至关重要。通过多年的软件工程教学实践,围绕读代码、写代码、评代码、改代码4 个环节,从高质量开源软件代码阅读、规范编程、代码测试分析等方面对学生进行训练,使学生建立对高质量代码的感性认识,具备规范编程,以及运用测试及代码分析相关技术和工具评价与提升代码质量的能力,取得了较好的教学效果。
在后续工作中,将对开源社区中高质量开源软件项目作进一步梳理,增加多样性;增加更为丰富的、更全面的代码质量评价方式,全方位对学生编写的代码进行代码质量度量,并增强数据可视化效果;丰富案例、教材等教学资源,并推广到更多的教学实践中,为培养具有高代码质量能力素质的软件工程人才发挥更大作用。