统计千行代码Bug率,有没有意义?

简介: 统计千行代码Bug率,有没有意义?

我的结论是:统计Bug率有意义。但是统计千行代码Bug率没有意义。

为什么千行代码Bug率是没有意义的?

某公司最近出了一个方案,用来量化程序员的工作绩效。叫做千行代码Bug率。在一个统计周期内,程序员每增加或者修改的代码行数与QA发现的Bug数,根据如下规则计算Bug率:

  • 1000行代码,1个bug,那么Bug率是100%;
  • 2000行代码,4个bug,那么Bug率是200%;
  • 5000行代码,3个Bug,那么Bug率是60%
  • n行代码,m个Bug,那么Bug率是m / n * 1000

先不考虑这个规则本身是否有问题。我觉得,所有和代码行数挂钩的绩效统计,都是没什么意义的。因为代码行数是可以刷的。如果某个绩效需要代码行数越少越好,那么可以使用行数少的写法;某个绩效需要代码行数越多越好,那么可以使用行数多的写法。

例如,对于字符串赋值:a = '今天天气竟然有40度,我要被烤化了。',可以把它扩写成:

a = ('今天天气'
     '竟然有40'
     '度,我要'
     '被烤化了。'
    )

甚至再进一步,扩写成:

a = '今天天气'
b = '竟然有40'
c = '度,我要'
d = '被烤化了。'
e = (a 
     + b
     + c
     + d
     )
a = e

这三种写法的效果完全一样。

还有些功能,原本就一行原生代码搞定。但是为了增加行数,故意使用第三方库。这样第三方库的代码行数也就统计进去了。代码总行数增加,相当于分母增大,千行代码Bug率就降下来了。

要缩写也简单,在Python里面,如果使用lambda表达式,通过非常炫技反人类的写法,你可以把常规要40行的代码缩成1行。但是这样的一行代码根本没法维护。

为什么Bug率是有意义的?

对于一个有实际用处的项目代码来说,Bug数是一个系统误差,只能设法减少,但是没有办法变成0。

同样实现一个功能,好的程序员能提前预判到别人会怎么使用,提前处理好非法逻辑和不合理的数据流程,从而降低Bug数。而差的程序员,写出来的代码,别人一用就出问题。因此,用Bug率来评判程序员水平,我觉得是合理的。但是从Bug数到Bug率,这个计算方法应该要精心设计。

开发阶段

如果公司有QA的话,在软件开发阶段,一般产品经理会先提出需求,然后拉上开发和QA一起评测需求。QA会在需求评审会后,设计测试案例。这些测试案例是公开的,每个开发都会看到。

这些公开的测试案例,我觉得可以用来作为分母。程序员写好了代码,却无法通过其中的部分测试案例。那就是程序员的水平不行。失败的测试案例数/所有公开的测试案例数。可以作为衡量程序员水平的参考指标之一。好的程序员应该尽量让这个比值为0.

但有时候,在测试的过程中,QA可能会临时增加测试案例,这些案例是程序员提前不知道的。那么这些案例如果测试失败了,也可以作为一个评判指标,用来评判程序员是否有提前预防的能力。但公平起见,可以给他乘以一个小于1的系数,降低它的权重:

开发阶段Bug率 = (已经公开的测试案例数 + 系数 × 临时增加的测试案例数) / 总测试案例数

说个题外话,今天我们不考虑单元测试数、单元测试覆盖率这种问题。因为据我所知,国内互联网公司会主动写单元测试的程序员太少了。有时候,一个原本要写单元测试的优秀程序员,进了某些大厂以后,迫于业务和工期压力,也逐渐放弃了。所以我们今天只考虑QA的测试案例。

线上阶段

如果只看QA的测试案例,可能会出现面向QA编程的问题。因为人是很聪明的,上有政策,下有对策。QA的一个测试API接口的案例,输入5,输出10.程序员直接在代码里面判断,如果输入是5,直接返回10,跳过中间的所有逻辑。这样就能100%通过QA的所有测试案例。但是这样做对产品本身是没有价值的。

市场是检验代码质量的重要标准。程序质量好不好,上线以后,让用户来评测。

你永远不知道你的用户有多蠢,你永远猜不透用户会怎么使用你的产品。

用户反馈的Bug,也可以用来评价代码的好坏,进而反映出程序员的能力高低。但需要考虑下面两个情况:

同一个功能,两个程序员实现:

  • A程序员写出的功能一上线,用户一用就报Bug
  • B程序员写出的功能上线很久了。几十万个用户都正常使用,有个沙雕用户乱操作,偶然暴露出了一个Bug。

大家凭主观判断都知道,B程序员应该比A程序员好。

我们再来考虑第二种情况,A程序员实现X功能,B程序员实现Y功能:

  • X功能每天会被使用几百万次,一周就发现了二十多个Bug
  • Y功能一个月总共就被用了3次。没有发现Bug

这种情况下,我们没有办法根据Bug数来判断AB两个程序员谁更好。也许B程序员去写X功能,一天就会被发现上百个Bug也说不定。

因此,根据这两种情况,我拍脑袋总结了一个经验公式:

某功能线上Bug率 = Bug数 / (log(功能使用次数 + 1) + 1)

其中的log是以10为底的对数。因为一个功能很轻松就能使用上百上千次,而Bug数一般来说就是个位数或者两位数。因此对使用次数求个对数,避免Bug率太小。公式中的两次+1。一次是因为不能对0求对数,另一次是分母不能为0.

对程序员开发的多个线上功能的Bug率统计,我们可以这样计算:

程序员线上Bug率 = A功能线上Bug率 * 功能重要性系数 + B功能线上Bug率 * 功能重要性系数 + ……

其中,相同重要性的功能,他们的功能重要性系数应该是相同的。不同重要性的功能,功能越重要,这个系数就越大。

这里,这个系数应该用功能重要性系数还是功能复杂性系数,我们可以讨论一下。我个人是觉得用重要性比较好。一方面是代码复杂性不好量化。第二是因为程序员的代码质量和业务是不能分开看的。对于重要的功能,应该优先做,应该更用心。在更用心的情况下bug还那么多,不就说明能力差吗。对于不重要的功能,最后做,可能后面时间来不及了,赶工完成有一些Bug。但是因为这个功能没什么人用,对业务影响不大,有一些Bug也没什么。

拍脑袋综合公式

综合开发阶段与线上阶段,我们可以得出一个综合公式。由于一般来说,某某率的值范围应该是0-100%,这两个公式合在一起以后,结果很可能大于1.因此我们改个名字,叫做程序员Bug指数

程序员Bug指数 = 开发阶段Bug率 * 开发阶段系数 + 程序员线上Bug率 * 线上阶段系数

这个指数越高,说明程序员能力越差。

最后还是强调一下,以上公式是我拍脑袋想出来的,仅做参考。但我认为它的价值应该比千行代码Bug率高得多。

最后,欢迎大家留言讨论,你们公司是怎么评估程序员能力水平和代码质量的呢?

目录
相关文章
|
Web App开发 容灾 安全
非功能关键知识总结
【2月更文挑战第4天】非功能关键知识总结
618 2
Bug级别判定法则
Bug级别判定法则
899 0
|
SQL 缓存 NoSQL
接口的幂等性设计和防重保证,详细分析幂等性的几种实现方法
本篇文章详细说明了幂等性,解释了什么是幂等性,幂等性的使用场景,讨论了幂等和防重的概念。分析了幂等性的情况以及如何设计幂等性服务。阐述了幂等性实现防重的几种策略,包括乐关锁,防重表,分布式锁,token令牌以及支付缓冲区。
8322 0
接口的幂等性设计和防重保证,详细分析幂等性的几种实现方法
|
存储 SQL 大数据
一篇文章搞懂数据仓库:三种事实表(设计原则,设计方法、对比)
一篇文章搞懂数据仓库:三种事实表(设计原则,设计方法、对比)
一篇文章搞懂数据仓库:三种事实表(设计原则,设计方法、对比)
|
JavaScript API 开发工具
记一次后台管理脚手架选型过程
面对大屏支持不足的vue移动端项目,业务部门要求改进。原项目优化困难,决定重构。选型阶段,因业务类似后台管理,选择vue框架。在git和gitee上对比了两款脚手架,最终选定[ pure-admin-thin ](https://github.com/pure-admin/pure-admin-thin)因其频繁更新、先进框架和丰富文档。选型关键在于资料易得性、框架时效性和维护者信誉。欢迎评论区提供反馈和建议。
316 1
|
前端开发 API Python
如何在Python中接收前端POST上传的文件
如何在Python中接收前端POST上传的文件
1188 2
|
JavaScript
cnpm 的安装与使用
本文介绍了npm和cnpm的概念、安装nodejs的步骤,以及cnpm的安装和使用方法,提供了通过配置npm使用中国镜像源来加速包下载的替代方案,并说明了如何恢复npm默认仓库地址。
cnpm 的安装与使用
|
前端开发 容器
CSS【详解】对齐 (含文本垂直对齐,文本水平对齐、单行文本垂直居中、多行文本垂直居中、6 种方案块级元素水平垂直居中 、7 种方案图片水平垂直居中、文本自适应对齐、图标和文本对齐,图片和文本对齐等)
CSS【详解】对齐 (含文本垂直对齐,文本水平对齐、单行文本垂直居中、多行文本垂直居中、6 种方案块级元素水平垂直居中 、7 种方案图片水平垂直居中、文本自适应对齐、图标和文本对齐,图片和文本对齐等)
662 0
|
消息中间件 监控 数据安全/隐私保护
RabbitMQ 技术详解与应用指南
**RabbitMQ** 是一个开源消息代理,基于 AMQP 实现,用于应用程序间轻量、可靠的消息传递。本文档详细介绍了 RabbitMQ 的基础,包括**消息、队列、交换机、绑定、路由键和消费者**等概念,以及其**高可靠性、高性能、灵活性、可扩展性和易用性**等特性。RabbitMQ 使用生产者-消费者模型,消息通过交换机路由到队列,消费者接收并处理。文中还涵盖了安装配置的基本步骤和常见应用场景,如**异步处理、消息推送、系统解耦、流量削峰和日志收集**。
1410 2
|
人工智能 自然语言处理 语音技术
pull错代码,恢复到pull之前 ---本地代码回退
pull错代码,恢复到pull之前 ---本地代码回退
321 0