[转]前人挖坑,后人填坑—如何把那些bug挖掘出来
当我们放下一个项目转投下一个时,手头的东西就要转交给他人处理,或者..不再有人处理,可代码还在那里,搞不好你就引用了别人的东西,保不准哪天别人的代码里就爆出了个大 bug,当然这里的“别人”也可能是 你!我们既不希望自己是受害者,更不希望自己是施害者。
写代码不免出点bug,没有人可以保证自己写的代码不出问题,而那些没有被挖掘出来的bug,便成了后来者哭笑不得的坑...
这段时间公司全面 https 改造,涉及到域名的迁移,域名的迁移不是 nginx 做个映射就完事儿了,还有各种代码的去 schema,各种组件的搬迁,算是一个大手术!我看最近百度主站也升级到了 https,期间应该出过一次问题吧,貌似回滚了一次,他们遇到的坑应该还不算多,只是 www 域升级,而不是全网。公司最近出了不少的问题,大小问题都有,表面看是前人挖的坑,实际是整体架构思考的有欠缺。
当我们放下一个项目转投下一个时,手头的东西就要转交给他人处理,或者..不再有人处理,可代码还在那里,搞不好你就引用了别人的东西,保不准哪天别人的代码里就爆出了个大 bug,当然这里的“别人”也可能是 你!我们既不希望自己是受害者,更不希望自己是施害者。
1. 如何挖坑
挖坑可不是一件简单的事情,你写出来的插件、组件、代码,很可能被很多人用到了,各种业务场景下狂奔你的代码,一堆测试人员检测你的bug,所以在项目中埋坑可不是一件容易的事情。
那么如何埋坑呢?可以参考以下方案:
- 在一个文件中放一坨很长很长的代码,不加注释,不解耦程序
- 把判断都放在一层嵌一层深深的逻辑里头
- 程序中临时加入几个全局的标记变量,在很多地方改变变量的值,在很多地方使用变量的值
- 不考虑多变的场景,不实时容错,让他按照你脑子的轨迹跑
- 到处散播不同版本的代码,不整理统一的文档
如果这些方案还不够你挖坑,我想你团队同学的技术水平也真真是太高了。
很多时候,我们都是不经意间留下了隐患。当自己写的东西被其他人使用后,程序需要兼顾的场景就会增多,出现的问题也会变多,这个时候我们不得不完善自己的代码逻辑。结果就是,逻辑耦合度高了不少,代码层次深了不少,出错的概率也就增加了不少。
所以在设计一个功能或者组件的时候,该考虑什么,不该考虑什么,一定要理清楚。并不是所有东西都适合往代码里加,我们不是在做 ExtJS 这个整体方案,也不是编织一个底层的操作库,只是用少量的逻辑整合离散化、个性化的业务,这些逻辑越少越好,与核心逻辑无关的内容就必须抽离出来!
2. 使劲踩坑
如果说挖坑是一件很有难度的活儿,那踩坑就更难了。其实可以说难的不是踩坑,而是发现自己踩坑了。
在一堆巨量的文件中找出「因把等于号写成恒等号」造成的 bug,这不是轻松的事情,可能你在 debugger 的时候进入了别人的代码领域,对着别人巨长而又没什么注释的代码,估计当场就晕了,更晕的是,自己却还在怀疑这到底是不是这堆代码里头的问题。团队合作中,我们心里默认相信队友,队友产出的代码是没有问题可以直接拿过来使用的,所以一旦出现问题,我们怀疑更多的是自己,质疑别人需要很大的勇气,尤其是质疑那些成熟的框架,用了很多年的代码。
那么如何踩坑呢?我们可不喜欢踩坑,有的坑踩进去就跳不出来了,最后只能选择其他方案处理。很少有前端同学写程序的测试用例,可能还有一部分同学根本就没听说过什么测试用例。而在后端中(比如nodejs)没有测试用例的代码就是一堆废代码,除了自己可以拿着用用,别人根本就不敢用的。那么测试用例会考虑做那些事情呢?简单点说:
- 写出有问题的代码,让程序按照期望的出错方式出错,如果没有,程序就有bug
- 写出没问题的代码,让程序按照正常的流程返回正确的结果,如果没有,程序就有bug
测试用例要覆盖到程序中所有的逻辑判断,比如 if elseif else 等判断的逻辑都要覆盖进去。当我们的测试代码覆盖了100%的逻辑,那坑位就展露无遗了。
埋坑人的致命弱点就是很少对程序作出异常情况判断,只要找出程序中的异常点,试图以另类的方式触发这个异常,你就顺利踩坑了!
3. 用力填坑
首先,填坑是一种责任。
发现问题是最难的,解决问题只是时间的问题。当我们确认了一个坑之后,第一件事情就是告诉别人这里有坑,你不要踩了。但是最好再多补一句话:你先别踩,等我填好了坑你再来。我这觉得这句话真的很暖人心,程序猿之间的关怀就应该这么赤裸裸的。尽管,有的时候,这个坑不是你挖的..
当我们挖好坑,踩完坑,再埋好坑之后,回头想想自己在团队中扮演什么样的角色,挖坑者还是埋坑者?这必然是有益于成长的。
[转]前人挖坑,后人填坑—如何把那些bug挖掘出来的更多相关文章
- Windows环境下写Linux sh脚本的一次挖坑和填坑
最近在研究Docker集群和安装的时候,需要准备若干台机器.所以我为节约时间,打算批量复制VM机器,然后用sh脚本命令执行机器名称和IP等基础配置信息的修改. 具体操作:我在windows环境下,用N ...
- windows下jenkins常见问题填坑
没有什么高深的东西,1 2天的时间大多数人都能自己摸索出来,这里将自己遇到过的问题分享出来避免其他同学再一次挖坑. 目录 1. 主从节点 2. Nuget自动包还原 3. powershell部署 4 ...
- 【过程改进】 windows下jenkins常见问题填坑
没有什么高深的东西,1 2天的时间大多数人都能自己摸索出来,这里将自己遇到过的问题分享出来避免其他同学再一次挖坑. 目录 1. 主从节点 2. Nuget自动包还原 3. powershell部署 4 ...
- WebApi传参总动员(填坑)
本以为系列文章已经Over,突然记起来前面留了个大坑还没填,真是自己给自己挖坑. 这个坑就是: (body 只能被读取一次)Only one thing can read the body MVC和W ...
- 持续集成 windows下jenkins常见问题填坑
[过程改进]持续集成 windows下jenkins常见问题填坑 没有什么高深的东西,1 2天的时间大多数人都能自己摸索出来,这里将自己遇到过的问题分享出来避免其他同学再一次挖坑. 目录 1. 主从节 ...
- [Python3 填坑] 004 关于八进制
目录 1. print( 坑的信息 ) 2. 开始填坑 2.1 问题的由来 2.2 问题的解决 2.2.1 先说结论 2.2.2 八进制的用途 2.2.3 少废话,上例子 1. print( 坑的信息 ...
- [Python3 填坑] 018 组装类的几个例子
目录 1. print( 坑的信息 ) 2. 开始填坑 2.1 MetaClass 举例 2.2 type 举例 2.3 MetaClass 举例 1. print( 坑的信息 ) 挖坑时间:2019 ...
- [Python3 填坑] 017 实例方法、静态方法、类方法的区别
目录 1. print( 坑的信息 ) 2. 开始填坑 2.1 先上例子 2.2 分析 1. print( 坑的信息 ) 挖坑时间:2019/04/07 明细 坑的编码 内容 Py024-1 实例方法 ...
- [Python3 填坑] 016 对 __getattr__ 和 __setattr__ 举例
目录 1. print( 坑的信息 ) 2. 开始填坑 2.1 __getattr__ 2.2 __setattr__ 1. print( 坑的信息 ) 挖坑时间:2019/04/07 明细 坑的编码 ...
随机推荐
- Jmeter 数据库测试
1.环境准备,下载驱动 mysql-connector-java-5.1.45-bin.jar 下载的 jar 包保存在 Jmeter 的文件的 lib 下的 ext 目录下,则不需要做其他的配置了, ...
- Spring Cloud Alibaba系列(一)nacos作为服务注册中心
Spring Cloud Alibaba各组件版本关系 Spring Cloud Alibaba Version Sentinel Version Nacos Version RocketMQ Ver ...
- grep 如何自动标注颜色
首先 最后一行加入 保存 然后source ~/.bashrc 然后来试一下效果
- 【不断更新】mysql经典50道题自我练习
mysql经典50道题自我练习 测试数据和练习题均转载自CSDN博主@启明星的指引的文章sql语句练习50题(Mysql版),用于mysql的每日自我练习 表名和字段 –1.学生表 Student(s ...
- NFS服务器搭建-共享PC与ARM主板文件
NFS服务器搭建-共享PC与ARM主板文件 在搭建好交叉编译环境之后需要实现目标板与宿主机的文件共享,在这里选择NFS,由于资料较多.需要注意的以下几点: 目标板与宿主机需要连接在同一个网段内. 宿主 ...
- [uva_la7146 Defeat the Enemy(2014 shanghai onsite)]贪心
题意:我方n个军队和敌方m个军队进行一对一的对战,每个军队都有一个攻击力和防御力,只要攻击力不小于对方就可以将对方摧毁.问在能完全摧毁敌方的基础上最多能有多少军队不被摧毁. 思路:按防御力从大到小考虑 ...
- csu1617]强连通分量
题意:定义域属于一个集合S={0,1,...,n-1},求S的子集个数,满足以子集的元素为定义域的函数P(x)的值域等于子集本身. 思路:以元素为点,x到P(x)连一条有向边,不难发现,如果有一个有向 ...
- flink源码阅读
Flink面试--源码篇 1.Flink Job的提交流程? 2.Flink所谓"三层图"结构是哪几个"图"? 3.JobManger在集群中扮演了什么角色? ...
- vue实例中created、mounted以及其他类型说明
生命周期图示(图片来自coderwhy老师): 每个 Vue 实例在被创建之前都要经过一系列的初始化过程.例如,实例需要配置数据观测(data observer).编译模版.挂载实例到 DOM ,然后 ...
- MyBatis缓存机制(一级缓存,二级缓存)
一,MyBatis一级缓存(本地缓存) My Batis 一级缓存存在于 SqlSession 的生命周期中,是SqlSession级别的缓存.在操作数据库时需要构造SqlSession对象,在对象中 ...