#如何解决程序问题
在实现阶段的程序员,也会经常遇到写的程序出错,然后就束手无策,不知道怎么去查找程序问题,我总结一些查找程序问题的方法,希望能帮到大家。
##不要向小白用户那样提问
很多人一遇到问题就问人,而且描述不清楚问题,只说简单的问题现象,比如问“网站访问不了怎么回事?”,“连接不上服务器怎么办?”, “程序启动不了,怎么办?”,“程序在本地运行没有问题,上传到服务器运行就有问题,怎么回事?” 。 这些问题让人无法回答,哪位技术大牛能回答这些问题呀?
大家要知道你是程序员不是小白用户,不懂程序的小白用户,看见网站访问不了,他只能反馈给你网站访问不了, 作为一个程序员,只拿这样的现象去问人,技术大牛也不知道怎么解答,因为网站访问不了可能的原因太多了。作为程序员,你是可以提供更多的信息的,比如程序的错误信息、错误码、是在运行哪行代码时出错的,有了这些信息别人解答问题就更容易了。
我们在学校时,老师引导我们有问题就问,然后在编程时,有问题马上问,只看见个现象就问,反而沟通效率低,自己成长也慢。有问题要先自己找问题。
##首先要重现问题
如果同事给你反馈产品有bug,不要光靠猜测代码可能哪儿有问题就去改代码了, 改好了还自己不测试就告诉同事说改好了, 结果同事测试后告诉你“还是有问题呀!”,你告诉同事说“哦,我知道哪儿问题了,我再改改”,然后还是靠猜测去改代码,改好后还是让同事测试。如果这样往复几次程序都改不好,你的同事就会极其烦你。而且这样靠猜测修改代码,很容易引起更多的bug。
大家在找问题上不要偷懒,先问一下同事是怎么操作出的问题,自己也按他的步骤把问题重新显现一次,这一步我们简称“重现”,这样能帮助自己更了解问题,知道是在什么情况下出现的,在运行什么程序时出的问题,从而找出程序的报错的错误信息、错误码以及 报警的文件地址和行数,然后解决bug就很容易了。解决完bug后还要自己测试一下,确认问题真的解决了再告诉同事。
##找程序报错信息
每种编程语言看错误信息的方法都不一样,我们要知道怎么看错误信息。比如PHP语言需要开启报错,才会显示错误,在配置文件php.ini 中的设置配置项 display_errors 设置为on时才会把错误信息显示在页面中,不然的话,有错误也是显示500错误的空白页面。
如果是正式环境,开启报错并不安全,黑客可以通过报错信息猜测程序哪儿可能有漏洞,从而攻击我们的程序。正式环境下我们不开启报错,也可以通过查看错误日志文件知道错误信息, php的错误日志文件,可以通过php.ini配置设置
```log_errors = On
error_log = /var/log/php-error.log
```
然后在查找程序问题时,可以先查看看`/var/log/php-error.log`日志文件中是否有错误信息。
每种程序语言查看报错的方式都有所不同,JavaScript会把报错输出到浏览器的控制台,需要打开浏览器控制台才能看见报错信息。Android的报错可以在eclipse中看到。 iOS的调试中的应用报错可以在Xcode中看到。程序出错总是有错误信息的,即使表面上看不见,也要想想是否有错误日志,去查日志文件,不知道错误日志文件在哪儿,就去问搜索引擎。
做iOS开发的朋友可能遇到过这样的情况往往在安装应用的时候,只是弹出一个安装失败的提示框,根本不知道什么原因,很多做iOS开发人员遇到这种情况束手无策,岂不知这种错误也是记录到iPhone上一个错误日志里的,,用Log Guru这个工具可以抓取iPhone手机上的错误信息。
你不管在学习哪种编程语言,都要掌握查看错误信息、错误日志的方法。
往往找到了错误信息,在用搜索引擎搜索就会找到解决问题的方法。
但注意,有时候找的的错误信息可能不是真正的问题原因,比如报错信息是内存不足,报错所指向的程序文件第几行代码,那行代码可能并没有使用多少内存,它只是压死骆驼的最后一根稻草而已,真正占用内存很大的代码在前面。
我们没有做好防卫性编程,也会导致报错的信息不是真正的问题原因,比如某个变量我们认为它肯定不为空,在赋值时没有做判断, 在使用时程序才报错。问题原因不是变量使用时的问题,而是赋值时的问题,我们在赋值时没有做好判断。就好比飞机遭到恐怖袭击爆炸了,不一定是飞机的问题,可能是安检的问题。
关于防卫性编程,我们会在以后的章节详细讲解。
##排除法找问题
有时候我们实在找不到错误信息,或者找到的错误信息对解决问题帮助不大,可以先列出问题可能的原因,用排除法按着一个一个排除,先查找认为最可能的原因。
比如一个有问题的程序,他涉及到查数据库、调用接口、读取缓存等操作, 可能导致问题的因素太多了, 我们要让一些因素固定不变,比如查询数据库,我们可以把数据库查询结果写死为一个固定的值,不让程序真的去查询数据库,如果这样程序还有问题,就排除了是查数据库导致的问题,再继续查其他问题。
这有点像做物理实验,我们在研究摩擦力是否有重力有关的时候,一定要固定其他元素,要在相同的桌面上做试验,只改变物体的重力大小。
用排除法让问题的范围慢慢缩小,慢慢我们肯定能找的导致问题的代码在哪个文件的第几行。
在修复问题的时候可以把有问题的代码从复杂的环境独立出来,做一个简单的demo,然后来测试和修复问题。复杂代码环境不利于我们测试,比如有一处代码需要在产品上面操作好几步才能触发,每次测试十分麻烦,不然就把问题代码独立出来做一个简单的demo单独测试。等问题修复好了,再把代码复制到原来的复杂环境中,再最终测试一遍。
##奇怪问题一般是因为粗心
有时候我们感觉遇到的问题很奇怪,比如:“我之前这么做都没有问题,为什么今天会有问题。”
奇怪问题往往是因为粗心导致, 有可能只是少了一个标点符号。在PHP的判断语言中应该有两个等号却只写了一个等号。
```
if($num == 100){
echo '100';
}
```
经常粗心会写成
```
if($num = 100){
echo '100';
}
```
判断语句少了一个等号,变成了赋值语句,而赋值语句的条件永远都会为true,粗心范的错很难被发现,你会很奇怪“明明num的值不为100,为什么一直输出100”
如果你觉得问题很奇怪,一定要想想是不是粗心的原因,去找找你认为不可能出错的地方。
为了预防上面举例中的粗心问题,所以很多开源PHP程序,都这样写条件判断语句
```
if(100 == $num){
echo '100';
}
```
将判断值现在双等号前面,这样如果粗心少写一个等号会报语法错误。
##用好搜索引擎
找到了程序的错误信息或具体出错代码,再用搜索引擎上搜索很容易就能找到解决方法。程序的问题建议大家用Google搜索,会比百度准很多的, 但由于国内特殊原因Google不能正常访问,可以使用aolsearch.com , 他的搜索结果是和Google一样的。还可以在stackoverflow.com搜索一下,国外的程序员遇到问题喜欢在这里提问。
有时候整段话复制到搜索引擎去搜索,搜出来的结果比较少,可能找不到想要的解决方案。这时候要把整句话拆成关键词去搜索,用关键词搜索出来的结果比整段话多很多,更容易找到问题的解决方法。还有看看搜索引擎提示你的相关的关键词,可以换换其他相关的关键词去搜索。
##求助别人
如果上面的方法都不能让你解决问题,这时候再找技术大牛问吧。
问人的时候不要只拿表面的问题现象问人,也不要问搜索引擎能搜到的问题。 你通过前面的方法已经找到了报错信息,是运行哪段代码出错的,拿这些详细信息问人,对方如果有经验,很快就能告诉你怎么解决。
##解决问题后
我们千辛万苦的把问题解决了,一定要做好笔记,不然下次遇到相同问题可能还是忘了怎么解决,可以总结一下写在自己的博客中。
另外当我们解决一个问题后,想想我们的代码中其他地方还有没有类似的问题,把类似的问题都修正了,不要只修复发现的这一处。