本文总结一下学习和工作以来思考了一些排错的思路和避免错误的思路积累在这里,希望对大家有帮助,也欢迎大家补充。
代码排错和中医理论很相似
发现写代码排查错误可以学学传统中医的诊断方法:
传统中医诊断讲究:“望闻问切”
望
望:指对病人的神色形态等进行有目的的观察,以测知病变。中医大量实践认识到,病人的外在变现和内部病变有相关性。
其实排除也是一样,既然有Bug,那么表现多半是异常的,我们先观察这种表现。
闻、问
闻:包括听声音和闻气味。
问:了解过往的病史,了解病因,发病的经过和治疗过程。
这有点类似于复现Bug,了解触发Bug的时机和过程。了解哪个步骤,哪个接口出了问题。
切
切:指摸脉象来推测疾病。
类似于通过抓请求响应(浏览器f12或者抓包工具)根据请求参数和响应码判断问题出在前端还是后端。
通过错误日志等提供的信息综合分析。
中医是靠经验的
老中医厉害是因为见多识广,见到的病例多,趟过的坑多,这点和程序员很相似。
很多医生根据病状,就大概知道可能得原因。
优秀的经验丰富的程序员,遇到一些错误的表现,就大概知道问题出现在哪里。
因为他们遇到过类似的情况,思考过类似的情况,看过别人的案例等。
提供几个常用的排错方法
F12看请求和响应
请求参数是否正确,响应码是啥,用来锁定是前端还是后端错误。
比如404,基本断定前端请求地址写错了,比如500,多半是后端代码错误。
很多人只看表现,看前端报错了就认为是前端的问题,看控制台有报错就认为肯定是后端的错误。
注意要分析!不要猜测。看F12的NetWork选项,分析参数的内容和格式是否符合预期等。
看错误或者请求日志
很多Bug可能是后端的逻辑错误和一些其他细节错误。
如果报错,直接看报错的信息,一般会有非常明确的原因。比如空指针、参数错误等。
尽量自己先去分析,而不是直接复制到百度或者谷歌上找方案一个一个试,否则就算解决了问题,印象不深刻,不知其所以然。
如果没有报错,可以查看从控制层到数据访问层的调用日志的输出和输出等判断哪一次调用出了问题。
比如服务层调用数据访问层时参数少传了一个,比如查询的数据封装VO时少了或者赋值错了字段等等。还有的是不是逻辑有问题?
本地或者测试服远程Debug
直接通过测试服远程Debug,可以单步跟踪,很容易找到错误的原因。Debug的时候可以利用条件断点、Watch机制类辅助排错。
控制变量法
这个思想非常好用。如果是新开发的功能,通过删除部分怀疑引入错误的新增的代码来排错。比如引入了3个二方Jar有冲突,可以去除某一个试试,好了就是这个Jar的问题。
注意好是拉取新的Git分支来操作,避免污染原有分支的代码,搞出Bug。
换环境大法
换浏览器,代码写到自己的Demo项目中试试等。
官方文档大法:如果是用法问题,配置问题,尽量查官方文档,看看这一块怎么用,是不是自己用错了。
Code Review法
重新对代码进行Code Review,查看逻辑是否正确,是否有线程安全问题,数据结构是否合理,是否有忽略的情况等。
搜索引擎大法
不必多说,很多人都懂。
不过尽量用谷歌,Stack Overflow,而且尽可能用英文关键词来搜。
但是相对于学到的知识,解决的问题其实很值。现在人吃一顿饭都得十几块钱,买个工具不舍得。
交流请教
实在自己解决不了,毫无思路,可以在群里请教或者和一些乐于分享和交流的人探讨。因为有些问题虽然不难,但是自己很难发现。还有一些问题别人经历过,一句话可能省去你半小时。请教别人之前,一定要把问题描述清楚。好能说说自己的想法,自己做了哪些尝试和努力。而不是“借钱的是大爷”的态度,觉得被人就该帮你。或者描述不清,让“大神”们猜测你遇到了什么问题。
另外尽量寻求思路,而不是具体的方案。
大多数为问题都可以通过F12大法、日志调试大法、搜索引擎大法解决。另外排错要靠逻辑,而不是靠猜测,不是靠尝试。否则浪费时间,而且对知识掌握不深入,容易引发新的Bug等。
怀疑是某个原因,要去印证。比如有一个条件的数据查不到,或者怀疑代码查询出的条数不对,拿前端的条件直接用SQL查试试。注意细节,是不是标记删除?是不是漏了某个条件等等。
不要猜测是某个原因就动手改,而是通过已有的代码和数据推断可能性,可能性很大再去试。如果有其他好的方法欢迎补充。
如何避免Bug
以上的都是排错的方法,要保证质量应该在编码阶段。
1、 要考虑充分再编码,避免返工,避免逻辑错误。
要充分进行参数校验,考虑各种可能出现的情况;
2、 要进行充分的单元测试。
对于DAO层必须全部覆盖。对于上层代码可以采用Mock测试来验证逻辑,验证程序的健壮性,这里超级推荐Mockito。
3、要养成良好的编码风格
参考《阿里巴巴Java开发规范》《重构》《编写可维护代码的艺术》。
举个例子,一个函数好几百行,报了错误,如果很久之前的代码,而且逻辑不够清晰,还得看半天。如果一个函数代码行数比较短,每个清晰的子步骤都封装到了子函数或者工具类中,那么排错起来就非常容易了。
4、开发过程中或自测前自我Code Review
在IDEA里,合并新Master之后,和Master分支比对代码。
看看有没有逻辑错误,有没有手误,有没有可以改进的地方。
5、充分自测
除了上面的单元测试外,有时间要充分自测。功能的测试也要简单过一遍,尝试一些诡异的操作,看看是否有问题。
6、分享两个神器
编程过程中,对某个类的用法不熟悉,可以看看知名开源项目都怎么写。
Codota
插件地址:https://plugins.jetbrains.com/plugin/7638-codota-
官网:https://www.codota.com/
使用快捷键可以搜索知名开源项目中该类或者方法的使用案例,超赞。
https://www.programcreek.com/java-api-examples/index.php?action=search
可以根据类名和方法等搜索代码案例
7、开发过程中遇到不熟悉的类或方法,建议直接进源码、看注释
建议在IDEA里进入源码,如果有条件可以去GitHub拉源码,然后看想了解的类或者方法的配套单元测试。就很容易知道怎么用,甚至可以运行起来看看效果,甚至可以打断点单步跟。
8、平时要加强学习,主动学习
平时加强学习,遇到问题知识储备充足才容易快速解决问题。
主要看专业图书,比较经典的技术图书,看一些核心技术栈的源码。
另外一个有趣的现象,很多人用了Spring很久,连Spring的官方文档都没仔细看过一遍,MyBatis依然。
只是看过一些入门视频,能用罢了,自己并没有系统看过文档,了解过原理读过源码。
还有很多人总是以忙为借口不去主动学习。
有其他好的方法欢迎补充。