几种常见的Bug预防方法

我在自己日常的开发工作中时常遇到很多Bug, 这些Bug非常多样, 表面看来似乎各有成因. 我曾经试着记录各种Bug, 试图在以后避免遇到相同Bug, 但是, 这种方法非常表面, 我昨天遇到这个Bug, 今天可能会避免这个Bug, 但后天就会忘了可能性, 于是, 又重犯了相同的错误. 至于记录, 那么多Bug记录, 不可能有时间每天先预习一遍所有发生的Bug. 坦白讲, 试图让所有Bug都不会发生是不现实的. 

但是, 在这个过程中, 我还是总结出来了一个经验, 那就是将Bug分类, 并针对这些不同分类的Bug, 进行预防工作, 而非Bug发生后的治理工作. 结果相当不错, 我的Bug发生数量明显在减少. 我把我总结出来的几点经验提炼出来, 可供大家参考. 我会列举各种我遇到的Bug类型, 然后将我自己的预防方法写入其中. 

一. 数据抽象错误

所谓开发, 是将现实的产品需求变化成抽象的数据表达, 那么, 表达的方式其实是多样的, 因为没有统一的表达模式, 于是, 经常会在开发过程中造成表达方式的错乱, 导致Bug产生. 数据结构的设计其实是非常重要的过程, 我个人认为, 实际的开发过程前, 必须将所有能涉及到的数据结构, 都加以整理, 一旦发现数据矛盾, 初期就能调整结构来实现逻辑统一, 在开发工作之前, 数据抽象的错误就会大大减少. 但这增加了一个额外的工作, 那就是开发工作执行之前多了一步数据整理的工作. 但好处也很明显, 那就是程序的数据抽象比较稳定, 减少Bug并且为后续开发做了一个指导性的数据定义. 

二. 算法逻辑错误

实际的开发过程中, 有时候会遇到一些相对比较复杂的算法逻辑, 面对这种逻辑, 常常遇到情况是一边开发, 一边调整算法, 结果代码完成之后, 代码本身已经非常不可控了. 遇到这种情况, 我试图去预防的做法是做一个算法设计的逻辑草稿, 然后将这个草稿记录下来, 通常是记录在Evernote里面, 并且定标题, 如: Ref-1234, 同时, 在代码中加上一个注释, 附上这个标题Ref-1234. 以后调整代码的时候, 我随时可以到Evernote里面(你也可以记录到别的地方)看到当初设计这个算法的思路, 而不是单凭代码去理解之前的算法, 这样, 后面思考算法的方法和以前思考的方法保持一致, 从而减少反复调整代码过程中导致算法错误的发生. 

三. 定义错误

我们的代码中, 会有很多变量或常量的定义, 这些定义, 有它本身的意义, 但是, 我们经常会用混这些变量, 比如我们设计一个代码是a = b + 1, 实际上, 我们会不小心写成a = a + 1, 代码没有任何报错, 但实际上却发生了某种不可理喻的错误. 面对这种问题, 规范代码命名方式是最好的办法. 表达式变成了 Current = Prev + 1, 那么, 如果我们错写成了Current = Current + 1, 肉眼发现这个错误的可能性要比发现a = a + 1要更大. 事实上, 统一规范的命名方式, 可以预防很多错误的发生. 

四. 参数值错误

在开发中, 预料不到的数据总是会经常发生的, 我们不能指望所有的意外都能被预料到, 于是, 经常性的, 参数本身就会有错误带入. 一旦带入了错误的参数, 后面所有代码步骤都会变得不可控了. 为了预防这种错误, 我们应该经常性的使用assert, 通过assert的使用, 将参数值的安全性提升一个层次. 在bug发生之前, 我们的程序就已经知道错误发生在什么地方了. 

五. 流程错误

为了处理一个复杂的业务, 我们时常要设计一个比较多层次的流程, 理想中, 流程是线性的, A过程完了, 去处理B过程, 然后C过程.... 一切都非常完整. 但实际上, 它们是交错的, 这里有空间和时间上的交错, 空间上的交错, 最典型的例子就是递归模式, 而时间上的交错, 比如多线程处理, 具体空间和时间的交错不多举例, 很多时候, 都是在开发的时候才发现交错的发生, 也就是一边开发, 一边扩展流程, 结果变得一团糟. 为了应付这种状况, 个人认为最好的做法就是层级化逻辑, 尽可能让逻辑线性化, 这个我们可以通过函数的内容来调整. 实在不能做到的完全线性化的逻辑, 就在代码中加一句注释, 说明此函数可能会与哪个函数发生交错, 从而减少调整代码过程中, 因为调整某个函数, 导致另外一个函数不可工作. 

六. 结构性错误

每一个不同的代码段, 可能都有它自己的结构逻辑, 尤其是引入一些第三方库的时候, 比如: 一些库将触发行为放到回调函数或者闭包中, 一些库则需要定义某种stub形式, 而一些库则可能会发出一个消息, 还有一些库需要特定的init操作. 这就导致了各种结构都有不同, 不熟悉此库的人, 可能会错误的使用了错误的形式, 也许, 表面上可能会正常运行, 但其实它会带来了某种不可控的错误. 这时候, 开发者得先熟悉这套库, 才能预防这种错误的发生, 但我们开发者常常是拿到库, 一边开发一边学习的, 导致这样的结构性错误发生概率很高. 为了预防这种错误的发生, 我们无论拿到什么样的库, 最好的做法是先去观摩这个库的demo, 然后尝试写一篇这个库的使用方法的文章, 不用很复杂, 就是很入门的那种, 在写的过程中, 就可以大致的让自己了解一些这个库的具体化使用方法. 如果是在一个小规模的团队里面, 可以尝试举行一个分享会, 让开发者做一次讲授, 说明这个库的具体使用方法, 通过教授他人, 也让自己熟悉这个库的具体用法. 一旦熟悉, 这种结构性错误发生概率就会大幅度减少. 

Bug类型太多了, 不可能一一穷举, 细化下去有很多可能性, 这里只是提供几种比较常见的, 并且提出自己的预防方法. 我个人有一个看法, 那就是Bug本身完全不存在那是不可能, 但是, 通过预防方法让Bug大幅度减少, 是可以做到的. 上述文章纯属个人经验, 希望对别人有所借鉴. 

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,992评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,212评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,535评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,197评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,310评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,383评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,409评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,191评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,621评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,910评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,084评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,763评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,403评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,083评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,318评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,946评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,967评论 2 351

推荐阅读更多精彩内容

  • 关于Mongodb的全面总结 MongoDB的内部构造《MongoDB The Definitive Guide》...
    中v中阅读 31,916评论 2 89
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,933评论 25 707
  • 听朋友讲起她们的故事后 才发现在这里的每个人都在向着别人张开怀抱 向自己却无情开炮 。结果他们还在笑。没错,在笑...
    NN123阅读 221评论 0 1
  • 儿子最近一直认为他的牙齿有点凸出,同学们有时叫他仓鼠的牙齿,其实儿子也就是两颗门牙有点凸,本来我和老公想等他中考结...
    微笑的石子妈妈阅读 115评论 1 1
  • 也许就像林佳吃芒果,孟云街呐喊,泰勒唱写歌一般:告别,需要仪式。以下便是我缅怀你的仪式,希望再也不见。 可内心还是...
    目涩沐色阅读 317评论 0 0