说起程序猿,总绕不开的一个话题就是bug,估计每个程序猿听到某某测试跑过来一脸淫笑的告诉你这个功能有个bug的时候,总有种恨不得掐死他的想法。其实程序猿跟bug的关系,感觉有点像父亲和儿子的关系,自己制造的bug,哭着也要自己解决,就像自己生的儿子,哪天又犯了错,就算气得恨铁不成钢,也要教育他帮他改正一样。好了,扯远了,按照一般程序猿的心理,bug再正常不过了,解决就是了。可是你想过,解决bug的时间和人力成本吗?

1、bug从修复到解决的流程

通常情况下,一个bug从发现到解决的流程应该是这几步:

这其中,发现bug的环节不可控,因为我们不知道什么时候会有bug提出来,我们能做的就是发现bug后用最少的时间和人力成本来解决这个bug(都说技术人员的kpi不好衡量,如果做好了形成了团队的规范准则,应该也可以算一个绩效点,因为可以提高工作效率,至于权重多少,需要配合实际数据来分配)。复现bug环节,简单的问题很好复现,可能比较耗成本又最容易忽视的环节应该是复现bug了,至于定位bug,修复bug和测试环节,因为天生自带主角光环,更容易被重视。那么,有没有办法尽可能减少这个环节的时间和人力成本呢?

2、为什么不要去复现bug?

1、bug复现可能概率很小

虽然我们在开发过程中遇到的大部分的bug都是能复现的,但并不能保证所有的bug都能100%复现,而且经常出现这种情况:用户在IE浏览器上浏览某个网站时,发现某个页面是一片空白,多刷新几次,又正常显示了,这种蛋疼的问题,如果偶尔1,2次出现,可能是网络原因,但如果经常出现,而且不同的网络场景,不同的用户都出现了,你还敢说是网络的原因吗?

再举个后台的例子:某天某个集群(3台服务器)中某个重要的服务突然宕机了,接到告警后赶紧先把服务重启了,然后查看了core dump的日志,发现程序中并没有死锁和阻塞的线程,而且JVM的GC日志也是正常的,吊诡的是没过多久,另外2台服务器也相继崩了,于是硬着头皮,把所有可能的原因排查后重新部署,继续运行了几天后,正当你以为这bug已经解决时,突如其来的告警短信又提醒你服务又相继挂掉了,这时候你是不是要奔溃?

这时候我们要帮助用户解决他的疑问,就必然要先复现用户的bug来定位问题,而用户的问题出现的场景,往往依赖于用户的操作系统、浏览器版本,机器上装的第三方软件,网络环境,执行操作的顺序,甚至是用户打开了多个网站和网页导致cookie混淆等等多个因素,可能就因为其中某个被我们忽视的因素的差别,就导致bug不能复现,这时候你是不是很绝望?

2、复现bug有可能成本太高

复现bug的成本,主要分为时间成本和人力成本,你需要模拟环境,mock数据,一步步debug找到问题再修复,这整个流程走下来,可能半天时间就没了,在这过程中,你可能会找用户或者产品经理详细了解他们的操作流程,或者造数据时需要请求dba帮忙导入数据,这里都会产生时间成本和人力成本。

3、为什么做好日志记录?

1、良好的日志规范,能快速有效的定位问题。

做开发最怕的就是线上系统出问题了,轻则留下产品和系统不安全可靠的不好印象,重则影响到公司的收入和口碑。当然了,线上bug总会存在,这很正常,但是我们要做到即使出现了问题,也要能快速定位问题修复,也就是要做到常说的4个9:99.99%,否则年终奖可能要打水漂了。说到打日志,想起了关于程序员写注释的一个悖论:程序员最讨厌自己的代码写注释,也最讨厌别人的代码不写注释。打日志可能觉得很麻烦,但记录一些关键步骤,关键参数,对于快速定位问题进行修复时大有裨益的。

2、日志打印真的很耗性能吗 ?

打日志意味着有磁盘IO,为什么mysql采用B+树而不是红黑树或者AVL树也是这个原因:为了减少IO次数。除非是一些高并发接口,否则这就是伪命题。一般系统日均QPS上万都很不错了,对于大部分公司而言,打日志带来的性能损耗是可以完全忽略不计的。

3、如何做好日志记录?

请参考日志圣经:《阿里JAVA手册之异常日志(异常处理 日志规约》,不再赘述。

后记:说来惭愧,半年没写博客了,曾经自己许下的豪言壮志又食言了,这篇文章从构思到最终成型也是断断续续写了一个月,其中很多原因。自从换了家公司,加班时间至少是上家公司的double time,连周末也成了大小周,累的哟,不过习惯就好,让自己忙起来可以做更多的事情。19年又开始了,计划周末再复盘下过去的一年,并规划下新的一年,人嘛,梦想还是要有的,要不然跟咸鱼有什么区别呢?有想一起交流技术和交朋友的欢迎加我微信:1194426086,希望一起进步。

最新文章

  1. ENode简介与各种教学视频资源汇总(要进群这篇文章必看)
  2. 读IT小小鸟有感
  3. Effective Objective-C 2.0 — 第14条:理解“类对象“的用意
  4. Eclipse快捷键 10个最有用的快捷键【转】
  5. javascript冷知识
  6. Windows7下安装搭建redis教程和配置详解
  7. mount命令以及mount ntfs硬盘权限权限与显示的问题 分类: shell ubuntu 2014-11-08 18:29 148人阅读 评论(0) 收藏
  8. python setattr(),getattr()函数
  9. JAVA的extends使用方法
  10. gerrit的merge conflict
  11. 文件I/O的操作实例
  12. Android网络开发之Volley--Volley基本用法JsonObjectReques(二)
  13. SQL之left join、right join、inner join
  14. 字体图标 轻量级 Font Awesome
  15. classloader加载的双亲委托模式
  16. putty 与winscp 区别
  17. Web框架之Django基础篇
  18. VirtualBox下安装linux虚拟机
  19. HBase快速安装
  20. SpringBoot乱码

热门文章

  1. Unicode汉字编码表以及参考源码分享
  2. attr()与setAttribute()的区别
  3. Vue ajax跨域请求
  4. intellijidea课程 intellijidea神器使用技巧 5-1 svn相关
  5. The ninth day
  6. LINQ&EF任我行(二)--LinQ to Object
  7. 转:解决“arcsde服务启动又停止的问题” - shmiloy001的专栏 - 博客频道 - CSDN.NET
  8. iis 部署网站常见问题
  9. centos7按报错dracut
  10. Spring Boot:内置tomcat启动和外部tomcat部署总结