BUG的增殖指南

本文探讨了BUG如何在软件开发过程中逐渐滋生和爆发,从初生期到潜伏期,再到爆发期。关键点包括补丁代码、数据不一致、重复代码和表里不一的方法等,强调了控制复杂度和引入自动化测试以减少和发现BUG的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

BUG(学名:缺陷),喜阴,容易在人类关注不到的角落繁殖,喜欢自由任性的开发流程,在规范、流程严格的环境中较难生存。

fa687a7ef0de21d93a3b9db8a809be64.jpeg

BUG初生期

BUG随着系统诞生而诞生。

系统MVP版本(最小化可行产品)后,BUG也开始苏醒,此时整个开发团队的规范和流程相对薄弱,是BUG喜欢的环境。

但是这个时候整个系统的业务逻辑简单清晰,相对应的业务代码也整洁清晰,开发和业务人员都少,每个人都对整个系统的逻辑了如指掌,缺少阴暗角落,BUG的增殖不易。

同时,这个时候系统业务量较少,存量的BUG也不多,程序、业务、测试们相对来说有更多的时间关注开发的质量以及生产的运行结果,BUG也更容易被消灭。

BUG的潜伏期

BUG随着系统复杂度变大而增殖。

MVP版本的效果得到验证后,业务和开发们的信心得到树立,决定大干快干,要往系统里加入更多的业务功能。在这过程中代码可能会由于时间紧迫、惰性等原因 引入下面的问题,而开始腐化:

补丁代码

//补丁形式举例
if(ProductA ==  currentProduct
    || ProductB == currentProduct
    || ProductC == currentProduct //最后一个判断为补丁判断逻辑) {
    SendMsg();
    ......
}
//抽象封装形式举例
if(currentProduct.isMsgRequired()) {
    SendMsg();
    ......
}

补丁形式代码的一个最大缺点就是缺少了封装性,或者说缺少了设计,所有复杂度都平铺于一个层级。这样的代码在业务简单、人员数量不多这类代码依然处于可控状态。

但当业务逻辑变复杂,产品增多时,将会变成一个灾难——复杂度失控。程序员再也无法理清这里的业务逻辑,而码农思维不能触达之处,是BUG最喜欢的场所。

数据不一致

//新增列,没有做初始化
ALTER TABLE trade
ADD COLUMN `product_type` VARCHAR(45) NULL AFTER `create_time`;

没有做存量数据的初始化的话,会导致在代码中增加一些没有业务含义的数据处理逻辑 ,增加了系统复杂度,增加了程序员的思维负担。

但同样,人少业务简单,该类坑能被很好的COVER住,但BUG们正心怀期待地等待着这个逻辑被遗忘。

重复的代码

一般来说,开发们都是经过专业训练的人,极度厌恶重复的代码,除非条件不允许。

经常会有类似“这个需求很简单,怎么实现我不管,明天上线”的场景出现,迫使开发们以当前最简单最快速的方式——“复制并修改”来完成代码的编写。

复制修改形式能应付本次任务,但却将复杂度进行了翻倍。所有人后续要修改对应的方法时,都需要仔细观察被复制的代码之间的异同,并在每一个复制点加上新逻辑。

复制代码是增加系统复杂度卓有成效的手段,如果我是BUG的话,我看到这些重复的代码,我会笑出来。

表里不一的方法

List<Order> getOrder(int userId) {
    result = dao.findOrderByUserId(userId);
    result.fileter(u->u.productId == 1);
    return result;
}

名字上说着是获取用户的Order,实际上却是获取用户下产品ID为1的Orde。

这类方法完全失去了封装的意义,封装是为了屏蔽复杂度,而这类方法,除非你看实现,否则不能知道它是干什么的。而看了实现则暴露了更多的复杂度,失去了封装的意义。

其他各类增加复杂度的操作

  • 不再使用的业务代码没有清理,不能清理

  • 没有经过系统思考的业务的污染

  • ......

BUG的爆发期

业务进一步成长,原有的开发人员已经Carry不住开发量,开始大量招聘相关人员。

新招聘的人员对历史的坑不太熟悉,系统也过于复杂,原有开发人员、业务人员也难以获得系统全貌时,BUG们开始增殖爆发。

开发一个新功能时:

  • 在某个地方遗漏了需要加上的补丁代码,导致BUG

  • 不知道历史数据与当前数据不一致,导致上生产出BUG

  • 大量重复代码,差异很小,理解错误导致BUG

  • ......

同时上述BUG爆发时,大家会耗费大量的时间去排查处理问题,相对来说减少了很多的开发时间,开发时间的减少又导致了更多的BUG,由此而形成了一个恶性的循环。

b78dda3903af753d782df50e66cc452c.jpeg

BUG的增殖总结

控制复杂度以减少BUG的诞生

在业务系统中,除了大意问题造成的BUG,大多数的BUG是由复杂度失控导致。

如果系统的复杂度过高,那么:

  • 业务设计时考虑的细节过多

    • 会导致设计的遗漏

    • 导致大量特性在开发后段才发现,压缩了开发的时间

  • 开发产品时,需要掌握的细节过多时

    • 会导致无法看到全貌

    • 代码质量会降低,产生大量BUG,压缩了测试的时间

  • 进行测试时,业务过于复杂

    • 导致需要进行大量测试

    • 同时开发的质量不过关,反复测试又大量占用时间

    • 最后导致整体质量失控

所以

要提高代码质量的根本是控制复杂度

系统整体的复杂度可以很高,但是每个业设计者、开发人员所直接面对的复杂度必须是 个人范围内可控的。这样在开发过程中,开发人员就能关注到每一个细节,减少BUG的诞生。

(系统复杂度控制并不简单,其关乎设计与监督,本文不展开,可以参考 之前的一篇文章 《从分治的思想到架构的设计》

自动化测试以保证BUG的发现

在系统越变越复杂时,发布的频率也越来越快的今天,我们已经不可能每次上线都人肉全量回归一遍逻辑,只能增量测试修改部分。

然而,实际上每次修改都有可能引起一些存量逻辑的变更,如一些切面层级的修改甚至会影响系统的每一个方面。

因而在复杂度控制的基础上,我们需要

引入自动化测试的代码以发现BUG

虽然自动化测试的成本极高,代码量可能数倍于实际业务代码,当业务逻辑不稳定,经常会变化时,其代价则更高。

但当系统成长到一定程度,那么其必然会有沉淀出一些不变的主干逻辑,至少这些逻辑我们可以对其进行自动化测试。

44a94f50fe464d5426a9fe497a54478c.jpeg

写在最后

关于BUG的产生原因还有其他很多,本文不成系统地写了自己的一点看法,欢迎大家补充其他繁衍BUG的手段。

下一篇文章将跟大家分享我对一个套餐系统设计的思考,欢迎大家关注。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值