代码质量真的“一抓就死、一放就乱”吗?看专家如何破
访谈主题
随着软件系统及开发人员规模的增长,代码质量(包含其中所蕴含的设计质量)已经成为制约IT和互联网企业高效软件交付以及可持续发展的重要瓶颈。为此,许多企业都已经引入并建立了系统化的代码度量和代码质量管理实践,并将其与DevOps开发流程相结合,为保障软件质量、提高开发效率发挥了很大作用。
然而,代码度量及代码质量管理在实践中还面临着许多问题,例如如何定义合理的代码度量指标、如何看待代码度量所反映的质量问题、如何利用代码度量结果并采取相应的措施等。此外,代码度量及代码质量检查还存在“一抓就死、一放就乱”的现象,一线开发人员无法充分理解代码质量管理的意义,甚至还会采用各种方法“规避”相关检查,使得代码质量管理的目标无法实现。
围绕这些问题,我们邀请了多位来自业界领先的IT和互联网企业的技术专家与学术界相关领域的专家一起进行探讨,为大家了解业界相关实践状况、技术问题及未来发展方向提供参考。
访谈主持人
彭鑫
复旦大学教授
复旦大学计算机科学技术学院
教授、博士生导师
CodeWisdom研究团队负责人
Dr. Xin Peng Professor
School of Computer Science, Fudan University
个人主页:
https://cspengxin.github.io
Email:
pengxin@fudan.edu.cn
访谈嘉宾
王威
苏宁金融 项目管理中心质量管理部 部门经理
先后就职于亚信科技、华为、苏宁金融等公司,从事质量管理工作11年,有着丰富的研发质量管理、IT绩效管理经验。
叶赫华
京东零售集团
首席测试架构师
本名:张振兴
从2000年初进入IT行业以来,长期从事软件开发、测试服务、质量管理、过程改进、敏捷教练等,先后服务于51testing从事专职培训师、美国B2B电商公司从事测试架构师、英国金融IT公司从事研发运营经理、好买基金质量管理总监;目前为京东集团平台业务中心首席测试架构师,负责公司互联网测试体系建设、平台化设计与质量过程改进,以及DevOps的探索与实践。
Dr. Yuanfang Cai
Professor at Drexel University
Dr. Yuanfang Cai is a tenured Professor at Drexel University, USA. Dr. Cai received her Ph.D. degree in Computer Science from the University of Virginia. Her research focuses on software design, software architecture, software evolution, and software economics, aiming at using scientific theory to guide software practice, for the purpose of improving software quality and productivity. Her research received multiple awards from the National Science Foundation (NSF), and the technologies created by her lab have been adopted by multiple multinational corporations. Dr. Cai is currently an Associate Editor of TSE and serving on program committees and organizing committees for multiple top conferences in the area of software engineering.
黄泥
华为测试工程能力规划负责人
华为测试工程能力规划负责人,工程方法和工具专家。长期从事研发模式方法、测试自动化和工具平台的规划设计工作,支撑研发效率提升和高质量交付。
方一平
吉利测试与工程效率负责人
2002年进入测试领域;
2012年涉足工程效率领域;
对于新技术与实际工作的结合有着独到的见解,拥有17年的测试经验与7年的配置管理经验。
张刚
阿里云研发效能部资深技术专家
软件工程博士,软件工程方法学专家,多年来持续致力于领域工程、软件架构、敏捷精益方法等领域的探索与实践
乔梁
腾讯高级管理顾问,多个移动互联网公司的首席管理顾问
《持续交付》译者、《持续交付2.0》作者、持续交付领域专家,将持续交付理念、原则和最佳实践率先在国内推广。
中欧商业评论“颠覆式创新”私享会特邀嘉宾,分享 “大公司小团队”的轻敏捷方法在腾讯落地实施经验。
参与组织QCon等国内知名会议,一直是敏捷组织转型与持续交付领域的主题出品人,同时为会议提供了多个主题演讲与分享,并在InfoQ、Programmer等多种媒体上发表了数篇文章。作为InfoQ的特约编辑,主持《持续交付》专栏。
于旭东
网易敏捷教练/工程效能负责人/杭州敏捷社区组织者
专注于公司内部DevOps研发效能平台建设以及敏捷产品研发实践与培训;之前工作于阿里巴巴菜鸟网络,诺基亚网络等公司,拥有超过13年的敏捷产品研发经验,在敏捷产品研发,测试自动化,DevOps以及研发效能提升等方面具有丰富经验。杭州敏捷社区建设者之一,参与组织了2016中国RSG会议,RSG,Agile Tour,Agile China,TiD,DevOpsDays,DOIS等大会话题分享者
问题1
请问您的企业或您所了解的企业已经使用了哪些代码度量和代码质量检查工具?这些工具是以何种方式融入企业开发流程(如DevOps流程)并被使用的?
于旭东
目前网易静态代码扫描主要基于SonarQube,持续集成基于Pipeline,管理基于Jenkins,代码覆盖率基于JaCoCo,代码Review主要基于Phabricator,有部分团队使用Gerrit;
SonarQube,Jenkins,JaCoCo,Phabricator等都被集成到网易的研发效能平台(OVERMIND)里面,对于研发人员是透明的,代码提交的时候会自动触发代码持续集成;
另一方面通过IDE插件,支持研发同学在提交代码之前进行静态代码扫描,尽早的解决问题,而不是提交之后解决问题。
观点讨论
彭鑫:看来工具都和开发流程及平台有了很好的集成。一方面与DevOps流程相结合在后台默默地进行代码质量管控,另一方面通过IDE直接为开发人员提供代码质量反馈。
尹良泽:@于旭东 您好,请问你们使用sonarqube的效果如何,主要可以发现一些什么问题,对sonarqube在你们开发中所发挥的具体作用你们是怎么看的。是确实发挥了重大作用,觉得必须要用了心里才踏实还是形式上用用?
张超:个人代码每次持续集成多久能看到反馈结果?@于旭东
于旭东:@尹良泽 还是有很大作用的,后面会谈到
@张超 取决于pipeline的内容包含哪些步骤,单元测试数量以及执行时间,反馈时长在1分钟到20分钟之间。
叶赫华
京东这边的关于代码的工具很多,主要都是自研的。公司大,产品线多,工程效率这块也是遍地开花,比如代码扫描,主要是基于sonar做的,支持移动端IOS、安卓,服务端H5等多维度的静态扫描。另外,专门针对代码安全策略也有专门的扫描工具,也是自研的。
观点讨论
彭鑫:@叶赫华 基于SonarQube做了扩展改造?主要是哪些方面?接口层面还是基本检测能力方面?
叶赫华:主要是针对代码层的,包括服务端接口,也有客户端的。
王威
苏宁使用的主要是SonarQube工具,通过封装集成到自有开发平台(研发云)中。开发人员在研发云中拉分支、编译、打包、构建,并做静态扫描等,最后完成发布。过程中会进行质量控制。研发云是自研的平台,有专门的工具团队支撑。
观点讨论
彭鑫:SonarQube看来是标配,而且都跟DevOps流水线以及企业开发平台深度集成了。
黄泥
代码度量和质量检查用的工具不少,度量的工具有CCT,Source Monitor,CMetrics等,代码静态检查包括Pclint,Findbugs,Coverity,Fortify等以及根据内部需求定制开发的一些静态检工具。
度量和静态检查集成到开发流程和工具系统,在代码提交合入,review,流水线运行时执行。在个人开发环境也提供静态检查服务。同时也用看板评估代码质量指标变化趋势,看护整体代码质量。
随着度量内容,语言,开发过程在不断演进。
观点讨论
彭鑫:@黄泥(华为) 也是高度流水线化。同时还有宏观的代码质量指标分析。
方一平
我们这边也跟其他老师说的比较类似,度量和检查主要是SonarQube,然后依托jenkins的流水线将gitlab与sonarqube关联起来,通过我们自身的CI流程和生产发布评审流程,关联起来。但检查相对比较粗犷。目前正在自研平台将流水线和发布评审系统打通,提升易用性和上下游的可追溯性。
观点讨论
彭鑫:@方一平 追溯很重要。建立追溯和勾连关系,代码检查结果才能发挥最大的价值。
张刚
关于第一个问题,阿里在代码度量和代码质量检查方面做了不少工作。代码规约方面,影响力比较大的P3C工具https://github.com/alibaba/p3c,我刚刚看了一下github上有18221个star了,企业在用的也比较多。在代码平台上,已经集成了覆盖率检测、缺陷预测、复杂度检查、重复度扫描等工具。里面有不少工具都是自研的 ,一些开源的工具也有集成。
观点讨论
于旭东:网易在代码静态扫描里面也集成了P3C。
蔡元芳
这个问题我将根据和我们合作过,并共同发表了case study的公司的合作经验进行回答。
比较常用的是SonarQube,Structure101, klocwork, Coverity. SonarQube会被集成到CI framework,并提供统一的dashboard。其他工具不了解。和我们合作发表过的公司都用过我们的dv8或早期Titan工具。
乔梁
我服务过的大型软件企业都已经使用了常见的代码质量检查工具(包括自研、商业、开源工具都有用到),最常见的场景是软件生产及运行的整个流程中,在不同的环节被使用,作为质量关卡。
问题2
请问您的企业或您所了解的企业目前主要采用哪些代码度量指标以及进行了哪些代码质量检查?这些度量和检查结果如何反馈给开发人员并被进一步用于实施相应的代码改进?
于旭东
我理解代码质量数据主要包括两方面:
- 内在质量:
01
静态代码扫描缺陷指数
02
单测覆盖率,目前采用最简单的行覆盖率;
03
单测通过率 = 单测通过用例数/单测执行用例总数。
- 外在质量:
01
内部缺陷;
02
线上缺陷;
03
线上缺陷关闭时间等。
反馈和改进:举个简单例子,当开发人员提交代码的时候会触发代码持续集成过程,其中包括静态代码扫,单元测试,类冲突检测,Jar包版本检测等,持续集成的结果会通过邮件,POPO消息等方式通知到代码提交人以及相关其他人员;更进一步,在研发过程中,例如需求提测,应用发布等过程中会将最新的持续集成结果作为应用代码质量信息透明展示出来供相关人员决策参考;有的研发团队会通过OVERMIND效能平台制定质量约束规则,例如静态代码缺陷指数高于先前代码则不允许应用发布,或者静态代码扫描结果包含Blocker,Critical等缺陷时不允许应用发布;单元测试通过率低于某些值不允许发布;包含特定的版本的第三方包不允许发布等。
观点讨论
彭鑫:@于旭东 单元测试通过率没到100%不是应该持续修改代码解决问题吗?
叶赫华:@于旭东 单元测试覆盖率,这个我也蛮有兴趣了解下你们做法。
于旭东:不同团队成熟度不一样,有的团队会要求单元测试100%通过,有的要求会低一些,离我们的理想情况还有差距,需要继续努力。
张超:@于旭东 请问单元测试行覆盖率的指标百分之多少算通过?
于旭东:单元测试覆盖率目前采用最简单的行覆盖率,针对增量代码,不要求100%覆盖。
张超:不要求百分之百,那有固定的通过覆盖率吗?
于旭东:@张超 不是固定目标,这个在不同团队根据团队成熟度以及应用情况自行设置。
张超:@于旭东 明白了,看来大家都很成熟。
叶赫华:不管覆盖率目标定多大,我想知道你们的单元测试范围是看增量代码还是整个应用?
于旭东:覆盖率看增量代码,不是整个应用。
张刚:单元测试覆盖率,我的经验是不用TDD的团队,很难把这个覆盖率提上去的。
乔梁:@张刚 用不用TDD都可以将覆盖率提到100%,我见过这样的团队,而且是大公司~
张刚:我的观点是单元测试本质上是一个设计问题,不是测试问题。所以遗留代码的单元测试基本上不可能。
于旭东:遗留代码重构是潜在的一个增加单元测试的机会点。
叶赫华
京东这边的度量指标其实很多,有专门的研发效能度量平台。单纯针对代码扫描这块,主要看提交次数、提测失败率、代码重复度、代码评审覆盖率之类的,也和其他朋友说的差不多,都是集成在CICD流水线里,在开发人员日常工作中去辅助代码质量的把控。
王威
苏宁这边的代码指标主要有2类:质量类和效率类的。包括:阻断/严重问题个数、阻断/严重问题千行密度、代码注释率、代码重复率、代码复杂度、单元测试覆盖率、新增代码单元测试覆盖率、新增代码行数、千行代码缺陷密度等。单元测试覆盖率主要针对新增代码,对于不同等级的系统设定不同的要求,比如,一级系统80%。
度量和检查结果通过3种方式进行改进:
01
开发过程中,通过研发云设置质量阈值,如:阻断问题等于零。如果超过阈值则代码不允许打包;
02
项目发布时,展示各个版本分支的代码质量检查结果,对于不达标的需要走额外的审批流程;
03
项目上线后,SQA统计相关质量周/月报,对指标较差的系统等进行分析,推动团队进行改进。
黄泥
制定并实施公司级代码质量评估标准,目前已演进到第二代, 主要考虑了代码基础质量的多个方面:可读性、简洁性、可移植、安全性等。6类评估维度,10几个指标,包括:代码规模,目录数/文件数目,文件行数,文件重复率,函数行数,圈复杂度,冗余代码,编译告警,静态检查和安全检查告警数,编程规范符合度等,各个产品根据自己需求进行补充扩展。在个人级工作环境,编译构建,提交review时反馈给开发人员进行改进。
观点讨论
彭鑫:@黄泥 度量指标的总体态势分析主要面向什么角色?
黄泥:主要是管理层和质量管理人员用。
方一平
我们目前主要是代码产出率、代码重复率、合规率(代码扫描问题折算)、逻辑类缺陷占比;后续打算引入的指标:单元测试覆盖率、单元测试通过率、代码漏洞率、代码bug率(针对新版sonar)。利用内部的报表系统以及度量公式,将结果实时反馈给员工,然后会与开发组的绩效挂钩,原先是直接与个人绩效挂钩,但是发现一旦与人挂钩,又没有做好上下文关联的话,很容易就走样。
观点讨论
彭鑫:@方一平 嗯,大家开始规避检查了。
张刚:一些争议不大的指标和人挂钩还好,不过有些指标一旦挂钩还是很危险的。
方一平:有些是较真,有些是规避。其实这种更适合是自发的行为,更多的是一种文化而不是一种测试手段。
乔梁:会写良好单元测试的工程师并不多~写出来大部分也用处不大。
于旭东:@乔梁 同意乔老师说法,会写好的单元测试的工程师不多。
彭鑫:@乔梁 嗯,我觉得也许是因为单元测试一方面要求编写者对设计要求理解很深刻,同时又对测试技巧(例如各种边角情况)很熟悉。
张超:@彭鑫 主要是测试用例的设计模式,没做过测试的开发人员不能深刻理解。
于旭东:单元测试我简单分为4种人:1、完全不写或不会写;2、为了公司设定的目标写;3、为保证代码设计质量自己主动根据实际情况写;4、TDD测试先行。
张克强:@于旭东 以上4类各占大概多少比例,对代码质量有没有明显影响?
于旭东:@张克强 我看到的大部分是前两种,第三种有但比较少,第四种偶尔见过。
张超:@张克强 你这个问题可以变通下:多少程度员为了吃饭讨生活,多少为了公司的价值,多少为了实现自我价值。
张克强:@张超 谢谢,那也可以推断大概了。
张刚
目前我了解的在用的度量指标目前也都是比较常见的指标,很多前面的老师也都说过了,包括Java的规约、测试的覆盖度、测试覆盖率、圈复杂度等,面向对象的一些指标也有集成,但是我觉得这些OO的指标其实不好。
目前度量的反馈方面,一部分是作为IDE集成,作为即时的给开发人员的反馈,另外在Devops流水线上也有集成,团队可以根据度量工具在流水线上设置一些卡点,但是现状并没有强制。
蔡元芳
第一个问题,就是所使用的工具提供的指标。第二个问题企业专家更有发言权。我们的体会是各个公司差别非常大。根据我们的经验,度量指标一般需要反馈给架构师,或CTO,或专门的研究部门,将度量结果和开发团队进行沟通,然后共同决定是否改进,如何改进。
彭鑫
看来代码度量指标和代码质量检车结果一般都是通过几方面发挥作用:
01
通过IDE反馈给开发者;
02
通过代码提交与合并等卡点进行控制;
03
事后进行整体代码质量分析。
乔梁
主要的代码质量检查还集中于与直接质量相关的方面,如空指针、内存溢出、安全性等,有一些团队会要求代码规范类型的质量检查。大型企业产品线众多,产品不计其数,且处于不同的生命周期,所以检查项会根据具体情况进行定制。对于团队约定的规则,开发人员会根据这些规则进行代码改进。
讨论总结
QUERY 2
肖璐:
谢谢各位大佬分享!请问公司在使用质量检测的工具,平台,收到反馈后会要求开发人员采取什么行动改进代码吗?这样怎么保证代码开发的效率呢?
刘旭:
@肖璐 持续集成,有问题不让code进去,或者不release。
彭鑫:
@肖璐 不让代码提交、不让合并、不让发布。另外,可以秋后算账,计算开发绩效的时候引用代码质量检查结果。因为开发高度流水线化,因此有机会在很多地方设置卡点。
彭鑫:
我来问个问题,代码自动检查结果与代码评审如何结合?例如检查结果会在代码评审过程中提供给评审者参考吗?
王威:
@彭鑫 苏宁目前还没有结合起来。这其实是有一个很好的思路,在评审时对检查的问题,如阻断问题做一下review,看看是否已经修改,形成闭环。
彭鑫:
@王威 嗯,顺便为静态检查工具提供结果反馈。
方一平:
@彭鑫 我们是有检查节点的,sonar结果中不允许存在阻断和严重类问题,否则过不了评审节点。
彭鑫:
@方一平 不过这里的评审节点是人工卡点?
方一平:
是的。我们有套基于cmm4的管控流程。
彭鑫:
@方一平 估计还是流水线上的自动卡点效率高一点,六亲不认。
方一平:
嗯,自动化测试还不够智能,我们现在的流水线缺一环。而且还需要加入评审卡点。
张刚:
关于自动卡点,我的理解,其前提是:工具本身是可靠可信的。有些指标,争议不大的应该是没有问题,比如安全扫描、静态缺陷扫描等等。不过有些度量,可能就不太敢做自动卡点了。
乔梁:
现在很多code review 也是流于形式。
于旭东:
彭老师说的这个问题,正是我们效能平台OVERMIND目前在做的一个方向,能展示,但缺少学习的算法,这个也希望能和学术界的老师们多多交流。
彭鑫:
@于旭东 后面可以多多交流。
叶赫华:
我们比较常见的场景是:绝对不缺少发现问题的手段和工具,而是无时间去解决。
方一平:
@叶赫华 我们也有类似的问题,业务催的急,生产上不能犯错。
问题3
请问您的企业或您所了解的企业目前所采用的代码度量及代码质量检查取得了什么样的效果?还存在哪些问题?
于旭东
效果的话,我举一个例子,网易的某一个产品在OVERMIND效能平台上有将近900个微服务应用,其中将近400个应用的静态代码扫描缺陷指数归零,也就是说静态代码扫描结果缺陷指数是零分,配合上质量约束规则,例如缺陷指数不能高于前一次结果,否则不允许发布,这也就意味着不管任何人再修改代码都不会引入任何的静态代码扫描缺陷;当然另一方面扫描规则会持续演化。
现在还欠缺的是,目前安全代码扫描还没有集成到平台上,这个正在和安全部的同学沟通看如何接入。
叶赫华
关于整个工程效率层面的工作,京东一直持续在路上,实话说方向很多,但从代码扫描这个方面看,效果还不大,应该还属于一个次要地位。
这里核心的问题是:一个快速业务导向的公司,各研发团队主要精力在业务交付上,很难把这块内容作为主要的改进项,要么用绩效去导向,又太重,不落到绩效就会被忽视,包括针对工具扫描出的问题定级也会有分歧。
黄泥
较好的保障了基础代码质量,基本避免了低质量代码入库,如空指针,未初始化变量,高圈复杂度等防止了代码规模的持续扩张,减少了代码的技术债务。
但是检查项目越来越多,报警误报,处理起来也是很头疼。
观点讨论
王威:@黄泥 黄老师说的很对,有个问题请教下,基础代码质量的提升如何定性来衡量?这是我目前比较困惑的。谢谢!
黄泥:@王威 简单的说:1、代码度量指标;2、后续的测试结果和生产运行结果;3、维护和阅读代码的人的评价。
张刚:@黄泥 误报是非常麻烦的问题,直接影响了代码检查工具的实用性。
王威
我们这边遇到的一些问题有:
01
单元测试后补:开发进度紧张,版本转测时新增代码单元测试覆盖率不达标,发布前才补全。这样对当前版本没有起到质量提升的效果。
01
新增代码量统计的准确性:开发为了提高代码量,可以新增/删除、再新增/删除代码;大量框架性的代码引入等。
因为只要涉及到考核,数据就会失真,数据的有效性和正确性丧失,就失去其意义了。
观点讨论
彭鑫:@王威 自己删自己代码?这个需要放大镜去看了。建立代码演化追溯关系应该就能发现,我们正在做这个。
张刚:@王威 把代码量统计了的用途是啥啊?
王威:@张刚 比如千行代码缺陷率的度量指标,需要统计新增代码量。
乔梁:@王威 一次commit超过(500)行都不算数。
方一平:我们是commit超过1000行就不计算。
王威:@乔梁 好的习惯应该是频繁提交,持续集成我们的代码,但是目前很难做到。
张刚:@乔梁 超500行不算数这个思路可以的,可以鼓励更细粒度的提交。
方一平:从目前我们执行的情况来看,缺乏可追溯的度量都是成本很高的。
张超:@乔梁 赞同,架构解耦,小步快跑。
方一平
好处是代码生产率有所提高,自测质量提升,开发人员开始对缺陷较真。
问题:存在假代码现象,即反复提交,提交空行;重复率计算方式被质疑(比如由MyBatis之类框架生成的实体类,pagemodel对象),我们不同项目之间缺乏统一的规范,导致剔除此类情况时,维护工作量巨大,而且容易遗漏或误除,有些指标无法到个人;还有就是缺乏可信的系统模型,并不能真正反映团队或个人的代码实际情况。这块新版的sonar貌似可以支持。
张刚
我说一下我了解到的代码质量检查方面的一些收益。有些质量检查指标和质量检查工具,据我的体会,收效还是比较明显的,例如代码规约方面的检查,代码安全性方面的检查,缺陷检测方面以及测试覆盖率方面的检查等。除了对于代码质量,系统健壮性等方面的直接影响外,这也提高了软件开发人员对代码质量和度量方面的意识。
度量方面主要的挑战也还是有不少。有些度量指标本身不少那么靠谱,会随着上下文的不同存在争议,这类指标往往也就是作为一个参考。
蔡元芳
作为来自纯学术界的参与者,彭老师的问题我只能根据和企业合作的经验来回答。和前面几位嘉宾提到的静态检查工具不同,我们的研究侧重于从代码中检查设计和架构缺陷,定位和量化架构债务。对于工具的效果,也主要是围绕我们自己研发的工具在实践中的效果,主要根据和我们共同发表了case study的公司的合作经验进行回答。
第三个问题我从两方面回答,一个是成果,一个是问题。
关于成果:我们也首先会询问用户,既然你们已经购买了SonarQube等非常成熟的商用工具,为何还要用我们的研究工具?得到的回答有两类,第一类是像SonarQube这样的静态检查工具,会报出大量的警告和代码问题(误报),很难prioritize,或者给出天文数字一样的技术债务值,导致开发团队直接就忽略了这些结果。第二类是这些静态检查工具虽然已经非常成熟,但并不能指出设计和架构方面的缺陷。我们的研究表明,大量的代码缺陷都是由设计和架构缺陷导致的,越是高缺陷,高修改率的文件,它们之间的依赖(显性或隐性,动态或静态)就越强(ICSE 2016, TSE 2018)。
我们的DV8的工具直接解决上面两个问题。总结我们已发表的,在5个不同公司做过的经验研究 (需要这些论文的同学们请联系我),取得的效果有下面几类
01
定位产生高缺陷的文件组, 检测它们之间的架构缺陷,并且量化这些文件产生的技术债务。开发团队可以通过修改架构缺陷同时降低多个文件的缺陷率。当然,这个功能也可以用于影响分析:一个文件出了问题,可以了解其他哪些文件会受影响;
02
通过债务量化建立开发和管理的共同语言。开发人员通常对系统中哪里有问题有一定的了解 ,一般不需要我们帮助他们locate buggy file. 引用某程序员原话“我们天天改的就是这些文件,不用你们来“预测” 哪些文件 error prone. “ 但是,程序员往往无法准确表达问题的范围有多大,问题背后的架构和设计根源是什么,以及问题有多么严重,这样和管理者沟通,决策是否需要投资提升代码质量就比较困难,因为这种投资的回报率难以估算。“绝对不缺少发现问题的手段和工具,而是无时间去解决” 在我们2019发表的经验研究中,开发团队用DV8有效地解决了上述问题,在说服领导层投资重构方面起到了关键作用。同时在重构之后,根据开发系统产生的各种数据,量化证明了重构的收益。
03
和同类软件进行比较和排名。有些企业希望他们的软件和同类开源软件比较,有些希望比较本公司开发的不同项目。没有比较就没有伤害,受到伤害的结果就是开发团队有了提升设计质量的动力。
关于存在的问题:
01
和我们合作的公司,都是由于不能保证交付速度了,才来寻找设计和债务度量工具。
02
由于设计和架构问题是需要依赖关系作为输入的,文件依赖关系抽取的有效性直接影响了DV8的准确性。尤其是新语言,多语言,以及开发框架的大量使用,使得现有的依赖抽取工具(比如understand)的准确率大大下降,这样我们的度量指标在某些系统中很准确,在另外的系统中就不那么准确。比如JavaScript,我们也曾尝试解析JS的依赖,很有挑战。其实不止是文件间依赖,还有微服务之间的依赖,生态社区的依赖,等等,都是设计和架构分析的基础。依赖的可视化和有效管理是个恒久的话题。感谢@张刚老师以及@刘烃老师的博士生@武侠同学创建的Depends开源项目,https://github.com/multilang-depends/depends/releases/,为我们解决这个问题提供了优秀的平台,希望同学们,同事们,尤其是关注编程语言的研究和实践者,多多关注这个项目,共同解决这个问题。
03
企业开发数据的不规范。通过分析大量的开源软件,我们观察到:越是成功的开源系统,其管理越严格,数据越规范,分析结果也越有价值。而企业的开发数据却是多种多样,随机性比较强,导致分析的准确性下降。
观点讨论
张超:@蔡元芳 微服务之间运行态依赖如何解析啊?调用链那么复杂,随时可变。在这个情况下不如直接灰度测试了。
蔡元芳:@张超 这是研究课题呀。学术界很难找到微服务实例做研究。我们正在和企业合作试图解决这个问题。
张刚:@张超 我理解静态解析是不太可能的。这个需要的是通过微服务的治理体系来解决这个问题,不能从代码入手。
蔡元芳:@张刚 是的,静态分析远远不够,要多种数据源共同分析。比如构建依赖,运行日志,甚至performance report。
于旭东:这个可以通过链路跟踪数据进行解析得到,需要中间件支持~
张超:@蔡元芳 我认为投入运行态解析成本大过收益,只要能定性就可以了,不用定量分析。
蔡元芳:@张超 只要能证明“成本大过收益”就好,或者“收益大于成本”就好。
张超:嗯,这是SRE的范畴了。
乔梁
我曾在Nokia(不是诺西)任职。当时,Nokia功能手机业务线使用Coverity 进入Field test之前的质量扫描,P0级别问题必须修复,否则不得进入Field Test。据说是因为做过统计对比(并未查证)。一种型号手机内嵌操作系统的P0 issue数量与其在售后support 数量成正相关,而support数量可以换算为成本,因些才有了这一强约束,并被严格执行。但很多代码度量与直接收益并不直接关联,因为经济效果尚无法精确衡量。
讨论总结
QUERY 3
叶赫华:
我想问下,不管是单测还是扫描,通过平台扫出来的各类问题,你们的公司是什么人才关注这些结果?是有专职QA定期搜集汇总?还是技术领导会主动去看,去说你团队做的好、他团队不够好?还是绩效压着——你们每个组都在2019年搞到什么什么程度?它是如何指导后续工作决策的?
方一平:
@叶赫华 我们这边是我负责的,通过各类报表,表彰会进行的。QA也会关注。
张超:
其实在Devops模式下,激发大家一次写好代码不是工具、QA、测试,而是用户。
问题4
您觉得应当如何看待代码度量及代码质量检查“一抓就死、一放就乱”的现象?我们应当如何合理认识并利用代码度量及代码质量检查结果?例如,代码圈复杂度和代码重复率高的代码一定是不好的代码吗?
彭鑫
这个问题我自己也有一些直观感觉。前面在某个企业交流时提到代码重复率,企业想降低这个指标,马上有工程师略带激动地表示反对,并说明他那里因为何种情况需要大范围拷贝代码,因此无法降低代码重复率。如果强行要求降低,那么有开发人员会通过拆分函数、方法等手段绕开指标监测。
于旭东
这个是很重要的一个问题。我觉得有几个点需要注意:
01
质量透明可视化
Brooks讲软件研发的本质复杂性其中一个点就是不可见性。过去有些研发团队也都有静态代码扫描,单元测试,代码Review等工具,但是这些信息是分散无关联的,是不透明的,是存在某些人的头脑里的隐性信息,不可视化出来也会导致缺少前进的动力。
02
关注ROI
也就是内部代码质量的改进应该能体现到外在质量的提升,否则动力不足;举个例子,当初在网易的某一个产品引入静态代码扫描的时机是我和该产品的CTO一起出差的时候,半夜差不多11点,杭州的研发同学发过来一个线上故障修复发布申请的单子,故障的原因就是一个空指针没检查导致的,那么这种不涉及到业务逻辑设计的代码问题完全可以使用静态代码扫描可以发现,加上代码缺陷指数规则的约束,极大的降低了这种低级代码错误导致的线上缺陷。
03
效能平台支撑
将质量信息(能力)集成到研发过程中去。如果这些信息是分散的,而不是通过赋能的方式集成在研发过程中,例如提测,发布等环节,那么这些信息只是字面上的约束,很容易被打折或忽视,打折和忽视的次数多了,也就没人在意了;在网易的话我们会把这些信息能力集成到OVERMIND研发效能平台上赋能研发过程,并可以针对不同成熟度的产品可以自由配置不同的约束规则,适应团队现状。
04
注意冷启动成本
门槛太高的话很容易胎死腹中。
观点讨论
彭鑫:
@于旭东 很具体的体验。
王威
没有度量就没有管理,但是度量要为管理目标服务,不能为了管理而管理。我们可以在公司层面设立组织基线,但是也要考虑到系统的架构、复杂度的差异性。比如:前台和中/后台系统的差异、核心系统和非核心系统的差异。相当于一个漏斗,先把疑似有问题的系统筛选出来,然后针对具体问题具体分析。但是这些都依赖于人,分析成本比较高!不能不抓,但是有策略地抓!这也是前面几位老师提到的成本和收益的问题,要考虑投入产出比。
观点讨论
蔡元芳:@王威 我们需要至少大致估算投入产出比。我们的2015和2019经验研究里就是帮企业估算这个。
王威:@蔡元芳 期待蔡老师的指导。
张超:
收益也要看长期和短期,我们的项目经理如果只干两年就换,谁还在乎技术债务,重构这些呢,先交付了再说吧,反正下一任背锅。
乔梁:@张超 产品经理的变更周期更短~测试相对变更周期长一些。
彭鑫:@张超 微观上也是这样,反正是击鼓传花,在我手里不爆炸就行。
黄泥
度量和检查标准的开放性,权威性和文化建设是基础,让开发者知道为什么要度量检查,度量项的意义。检查内容要持续改进,听取反馈意见。
工具检查信息要反馈快和准确,误报少。告警要清晰告诉开发者定位和要做什么修改。
代码质量需要结合度量检查指标和人的review来综合判断。比如说,有各种医学检查,量体温,验血,CT后,还是需要医生观察看病和综合判断的,不能唯指标。
观点讨论
彭鑫:不同的度量指标也需要一一透视,例如代码重复度,各种不同原因不同形态的代码重复需要分类看待。
方一平
我认为这个是因为我们代码质量检查做成了一种制度而不是一种文化。让代码生产者认为是对其生产质量的不信任,并没有成为其工作的习惯,没有形成质量自信。
而且目前现有的代码度量和检查方式都缺乏上下文,相对比较割裂,度量可信度低。现有的一些度量方式大多偏向于概率论,比如说代码重复率高的代码大概率是不好的。
观点讨论
彭鑫:@方一平 “目前现有的代码度量和检查方式都缺乏上下文,相对比较割裂,度量可信度低” 这个跟我们理解一致。代码重复率高:这个我觉得要对重复代码分门别类做更细致的分析,不能光看表面重复。
方一平:@彭鑫 是的。这个涉及到一个可信度的问题。
叶赫华
我觉得“抓就死,不抓就乱”,这是绝大多数普通公司的情况吧,作为工程师,都是希望做好这些东西的,也从没怀疑过它的价值;作为企业要改进,还需要:
1)从企业文化上多熏陶工匠精神、自主创新的工作模式、全面质量意识等等;
2)组织架构设计:多数公司应该都有了工程效率团队,通过工具平手段帮着业务研发提供更高效的发现问题手段,但往往解决问题的人成为瓶颈;那么组织是否需要专门设立不做业务迭代团队、去专注技术质量的改进工作;
3)绩效导向:适当的绩效导向是必须的,不管喜欢与否,尤其早期,光激励没有板子是不行的;
4)工具实现:多数公司都是拿着开源框架自主搞,不管是代码扫描还是其他环节,其实自身的效率与能力也是有限的(例如前面嘉宾说的误报的),还是要业内同行多探索更智能化的技术手段,让发现问题变得简单外,还需要让解决问题变得简单。
张刚
我觉得代码度量“一抓就死,一放就乱”,一个很大的原因还是在于这些度量并没有直接和业务结果关联起来,部分检测工具的有效性严重依赖于上下文,而且存在不少误报,投入产出比不够高,所以呢,在业务压力下,很难对这些只是“或许会有问题”的度量结果采取足够的重视。
我觉得如果这些检查能做到比如安全扫描那样的准确性,情况就好多了,因为这些东西靠谱,查出来是问题就一定是问题,而且如果不修复。后果可能会很严重。设计好的质量度量体系和质量度量工具我觉得是根本解。
所以我觉得不是大家不重视,也不是主动要绕过去,工具的准确性和易用性是最根本的问题。
蔡元芳
哈哈,这个“一抓就死、一放就乱”现象我们学术界是观察不到滴,我就不做评论了。
关于第二个问题: “代码圈复杂度和代码重复率高的代码一定是不好的代码吗?“ 个人认为不是。 诸行无常,诸法无我。同理,代码设计, 只要完成功能,并没有绝对的好与坏。没有利息不用偿还的债务那就是礼物。对于代码质量的判断,应该放在具体质量属性的具体场景去评判,这个架构理论已经讲的很多了。 简而言之,代码质量的好坏,不能只看代码,还得看代码周边其他的数据。 赞同泥总检查身体的比喻,我们的工具组就叫软件健康管理系统。
个人认为,最有价值的,但往往被忽略的数据是活跃度。根据期权理论,最活跃的部分最有投资价值,但却没有和代码质量结合来分析。在学术界这个方面的研究也是很不够的。
乔梁
由于整个行业还处于“手工业生产”状态,因此更多还是依赖人的技能水平。由于过去20年里,国内市场旺盛,但是,“经过良好训练”的产业人才数量输出能力有限。另外,国内市场对软件质量的要求就不高,同时,与其它行业相比,代码的标准化程度低,生存时间短。多种因素造成当前状态。
所说的“一抓就死、一放就乱”,也许有一个方面的原因是:从业者基本软工技能水平不高,well trained的工程师数量较少。业内的软件工程管理水平偏低,而从业人员整体收入不低。这也说明,行业利润率还很高,成本优化的动力不足。
关于代码的好坏,有很多种说法。如外部质量和内部质量。无论如果,当我们说:“某种东西质量好”时,最终都是通过某种数据来反映。比如手机好与不好,会有一些相关的数据,例如电量、摄像头、存储、计算速度、价格。最后,消费者来选择也是根据自己的需求,选择他认为性价比的手机。而这个性价比在每个年代都不一样。
所以,代码圈复杂度、重复率等都是代码质量的一个方面。到底怎么评估,直接或间接地会由那些为写代码的工程师提供薪筹的雇主说的算。虽然在某个时间点,不同雇主有不同的选择,但从长周期来看,高品质和低价格是必然的选择。
讨论总结
QUERY 4
叶赫华:
我的问题还是各位的公司的研发团队是否有人不做业务需求、专门做些技术优化、代码重构的工作?
乔梁:
技术优化是有的,但很少专门,基本没有。
彭鑫:
@叶赫华 估计不太可能。重构,特别是架构重构,需要建立在对业务的深度理解基础上。
乔梁:
@彭鑫 是的,自己不会怎么抓。
叶赫华:
那么代码重构周期多久 判断依据是什么?
乔梁:
@叶赫华 那是重写,不是重构。有的模块半年就一次,有的就长一些。
张克强:
我对“一抓就死”有些不同看法,我觉得“不抓会死”,一抓不够,还得有二抓三抓N抓。
张刚:
@张克强 我觉得这个得看抓的对不对。比如,把代码行、重复度,甚至代码单元测试覆盖率当成抓手,确实是会出问题的。目前缺的是那种非常靠谱的抓手。
张克强:
@张刚 一抓未必抓准,所以要调整,不能指望一抓就灵,跟踪各团队情况进行持续调整。
问题5
您对于代码度量及代码质量检查未来的发展有什么展望?有哪些新技术、新方法还有待软件工程学术界与工业界一起进一步探索?
于旭东
软件研发的本质是复杂的;根本任务是打造构成抽象软件实体的复杂概念结构,次要任务是使用编程语言表达这些抽象实体,在空间和时间限制内将它们映射成机器语言,最困难的地方不在于代码实现和测试,而在于产品概念的描述和验证。以前在一个公司做过一个某一个产品缺陷的分析,发现大部分的缺陷是由于产品需求定义错误或者对需求理解错误导致的。
如果将来有一天我们能够实现对代码意图(产品逻辑)实现自动检查的话,那么也许会实现软件生产力10倍速的增长,当然到了那一天是不是已经不需要人写代码而是机器写代码?回到现在代码质量检查,一个关键的点在于如何将“缺陷”和某些代码关联起来,让机器能够持续的学习改进和演化,让机器不仅仅是提供信息供人决策而是由机器决策代码质量,做到真正的智能化。
观点讨论
彭鑫:@于旭东 关键是缺陷是相对于需求和上下文的,而这两者很难以一种机器可理解的方式来表达。
叶赫华
宏观的说就是智能化编程的场景。
微观点看,对技术手段面向业务的理解上、让技术人员快速熟悉企业现有代码和规范上、互联网系统耦合度高的问题、变更影响的智能化分析上,这些具体的场景都是可以探索出一些新的工具手段的。
不过个人喜欢还是排斥,这就是趋势,一个个微观的工作场景解决了,十年后智能化编程的场景就实现了。
王威
我设想的场景有些类似:是否可以通过大数据分析+AI实现代码的自动重构或为架构师提供代码重构的方案。
观点讨论
彭鑫:@王威 自动化重构缺乏指标引导是个问题。自动化重构算法很多,但都需要定义目标函数,而这个目标函数的定义又回到了度量问题上:如何量化“好的”设计。
王威:@彭鑫 我还有个设想,也是目前遇到的一个问题:是否能够实现自动化的业务代码评审。目前的质量检查都是一些规则,涉及到业务逻辑的代码评审还依赖于更有经验的开发人员以及他们的时间投入度。另外,随着业务复杂度的提高,有经验的人员也不能保证能检视出所有的代码逻辑问题。
彭鑫:@王威 关键是如何以一种机器可理解的方式表达业务需求和业务规则。
蔡元芳:@王威 “自动重构或为架构师提供代码重构建议” 一直是我们的研究方向。像彭老师提到的,现有的自动重构是以提高度量指标为目标的。如果架构师能够表达重构目标,自动化重构是有希望的。2016年和彭老师做的工作就是这个方向。但实践中很难。我们在想也许可以提出几个可供参考的设计模式让架构师选择。指望机器提出重构目标有点远。
黄泥
我的三个建议方向:
1、如何解决查出更多问题和降低误报率的冲突;
2、静态检查工具越来越多,检查项目也不断增加,如何能够评估和整合这些工具的信息,速度,去重;
3、检查规则的特定领域快速检查工具,根据编程语言,业务逻辑,外部约束等。
方一平
1、基于上下文的代码度量,而且更多的是检查一些指标的趋势,从而达到预测的目的。
2、借用大数据,对代码数据以及代码关联的需求,开发任务,缺陷所描述的内容进行标注,实现项目画像,开发人员画像。
而且,整个度量和检查模式对被检查者是很简单的,简单到只要相信自己的IDE,按时提交代码即可。基本上是目前的一个思路,目前自研的平台也是打算朝这个方向努力。
张刚
我前面说了代码度量的一些问题,建议也就是让代码度量真的和业务价值关联起来,同时降低这些工具误报率。
刚才很多老师也都提到了大数据和AI可能是个有机会的方向。
此外,补充一下,有些提升也未必需要太复杂的技术,一些关注点的切换,也可能会为代码度量带来本质的变化,比如刚才蔡老师说活跃度是个非常重要的指标,非常符合我的直观感受。
蔡元芳
其实我已经部分回答了这个问题:期待我们在依赖发掘和管理方面做出新的突破。 依赖还包括人与产品之间的依赖,产品与需求的依赖,产品与测试用例的依赖等等。有了这些依赖,再加上开发中产生的各种数据,以及科学理论的导向,对软件架构的各个质量属性进行经济学评估,科学地提升代码质量和生产效率是很有可能的。
根据各位企业专家的发言,可以看到最后殊途同归,都得考虑投入产出比,属于软件经济学范畴,可以用大数据方法探讨解决。
乔梁
所有的行业都是向工业化方向发展的。而人工智能是行业工业化的一种手段,给人无限想象空间。例如,只需要很少的人做写代码的工作。大部分人只要一说,软件就编写好了,还没有bug。当然,现在这只是一个假想。参与的人少,技能要求高。现在还处于手工业阶段。
观点讨论
张刚:老师这个思路好像是根本解啊,把制造问题的人彻底移出去。
彭鑫:未来可能是机器为主人为辅的编程。机器完成大部分程序合成工作,仅在一些难以决策的地方请教下专家。这样少量专家可以集中于解决一些机器难以决策的问题,而大部分基本编程活动机器自己完成,减少人犯错的机会。
自由讨论
尹良泽:
各位老师,我还问个问题。代码规约和代码缺陷是代码质量的重要部分,但即使都满足发布要求,资深工程师和新手在代码架构、可维护可理解性、系统健壮性、代码安全等方面也是有天壤之别的。所以:
1. 从人的角度来说,公司里面如何评判一个从业者基本软工技能水平高不高?通过他的从业年限、开发经验、是否能快速给出解决方案和实现产品,还是其他;
2. 从产品的角度来说,上面几位老师都提到了重构,重构也分设计上的整体重构和代码上的局部重构,一般公司在什么情况下认为需要进行重构了呢?
乔梁:
参见我第四个问题的答案……就是一抓就死那个题目。
张超:
当日就有代码缺陷反馈当日解决。日活量,bug数都和绩效挂钩,一下积极性高涨。我认为改善代码质量关键还是要看研发模式,减少反馈周期,通过用户驱动而不是自我驱动。
张刚:
真正的重构,其实就是设计的持续演进,是应该随时发生。
蔡元芳:
重构这个问题没有一定的答案。有很多新项目,都是在开发中架构师对客户领域的了解才慢慢深入的,等到对领域知识的了解深入到一定程度,知道如何进行有效的抽象了,就可以进行“架构级”重构了。
张刚:
是的,蔡老师,持续发现是软件开发的本质特征。所以这里的关键是要建立支持重构的基础设施,也就是防护网:完备的自动化测试,此外通过持续重构形成演进式的设计习惯以及建立代码的灵活性。
彭鑫:
一方面是代码重构,另一方面是代码资产整理。经过长时间积累后产生的巨大代码库,很多人都会产生“资产还是包袱”的疑问。此事就需要去梳理代码进行代码资产整理了,就像是挖矿。这个话题下次可以专门再搞一次微访谈。
张超:
@彭鑫赞同,针对重构和技术债务搞一次。