2013年6月份毕业后进入一个做电子政务的小型个体企业,从试用到转正这段时间,坦白说自己真正参与的项目只有两个,一个是个人修改cms代码交付给新客户,另一个是个人负责公司的内部小系统。公司要中标才能有项目做,况且我是一个新人,所以在这里仅代表个人看法,这仅仅是一种简答的debug思路,如果说得不对,欢迎大家提出讨论,有讨论才能有火花,有火花才能够成长。
程序代码只分为两种:一种是已执行,一种是没有执行。
首先要说的是第一种情况,程序已经执行了。程序段执行了但是没有预期效果,这种情况就较为复杂,如果代码报错,例如java抛出异常,那么就可以顺着上面的信息区改正,更多的是执行了没有报错也没偶效果。执行了代码但是没有效果,首先不应该是怀疑类库、框架的bug之类,首先要怀疑自己的代码,如果你一开始就怀疑几乎全世界都在使用的公共代码存在一个自己轻易写一个简单代码段都出现错误,那么就说明这个类库或框架根本就没有机会接触到,除非你的公司使用的是最新(不成熟)的技术框架。所以如果debug到代码段已执行,首先要看看自己的代码,检查自己的代码最常见的就是检查参数有没有使用正确,使用该api有没有漏了步骤,这是最常见的,(个人看法)因为大部分国人太浮躁了,不会就找度娘,度娘上可以找到很多有关各方面技术的范例,有详细的代码段附加一些注释,有些人可能连注释都不看就直接把代码复制下来运行看效果,忽略了范例运行前提条件(参数、版本、依赖类库等等·······),诸如此类的问题本人犯了多次。解决办法就是直接上官网查找第一手资料(英文是必须的),本人建议学习技术直接上官网,官网上面的大多数例子比度娘找到的好,并且自己也可以多了解一点。如果自己已经按照官网上面指示的去做效果还是没有出来,那么就应该考虑外在的因素了,例如这个代码段的效果会不会被后续其他程序代码段的效果给覆盖了?因此自己代码正确了,那么就查找往下的代码效果,对于前面的调试难度提高了不少,这里说不清有多少的因素了,依赖个人技术的积累才能解决问题,本人技术积累甚少,不敢乱说。但是debug到这里一般来说很多人都会觉得结束了,对于一些是,对于另一些却不是了,因为现在程序很多是分布式的,程序的运行贯穿整个技术平台,例如目前较热的b/s结构的项目,后台运行结果没有异常,可能问题出现在前台,也可能出现在tomcat等服务器软件(没有清理缓存),中间还加上网络连接,每一个步骤都有可能出现问题,越往后的bug出现概率调试难度就相应增高,debug最重要的是知道问题域(问题可能出现的范围)。本人就曾遇到过运行两个项目(部署在同一个机器的不同tomcat上面),在统一浏览器上面访问会置另外一个项目登陆状态失效,查找很久,终于发现原来两个tomcat的server.xml没有指定sessionid变量名称,两个tomcat返回的sessionid变量都是默认的,所以会相互覆盖。类似这样的问题还很多,最文章末尾我会列出我遇到过的还记得的所有bug。
现在到了说没有执行代码段的调试了,没有执行代码段肯定是没有效果的,如果说没有执行代码段,效果也出来,那就说明你使用的技术太牛逼了,自己没有实现的功能,使用的技术给补上去了,这样的技术出现就会令整个世界陷入混乱,谁也不知道哪些是正确的,哪些是不正确的,哪些是自己实现的效果,哪些是技术实现的效果,关键是实现的这个程序不能确定按照自己预想的效果去跑。程序的价值在于唯一性,要么是,要么非,(继续个人看法)这是最基本的基本功了。说回没有执行代码怎么处理,这里的可能性是太多了,一般来说是由于逻辑错误,也就是说你所想要的代码段需要符合特定的条件才能运行,而你目前的条件没有,遇到这种情况调试最好的方式是给这个程序段划一个逻辑图,根据自己的系统输入与逻辑图进行比较,这样比较容易找出错误。还有一种较为复杂的逻辑错误就是算法的错误,不经常使用eclipse高级调试技能,这里我有一个笨方法,一步一步去运行,直至出错,数量小可以使用,数量大不能这么干。需要设置变量到达某一个值才断点(暂时没有用过)。
说到这里,你们都知道我的水平了,是的,我的水平和比较差,期望得到一些高手的指导。我总结一下debug的思路:(1)首先要确定程序问题域范围,然后是程序代码有没有执行,这一步可以大幅度帮忙你提高效率(2)如果已经运行代码没有效果,那么检查自己代码的参数是否已经全部设置正确和所使用api的充分必要条件全部具备,如果是,那么请检查该问题域的其他方面;如果没有运行代码,那么看看代码外层是否存在逻辑错误(if-else),如果不是有可能是其他方面的错误,例如jquery 的ajax请求有时候会不能进入成功请求后的回调函数,同时也没有报错,原因是回调匿名函数里面有语法错误(我不排除其他的原因,这里仅仅说我遇到过的原因),整个匿名函数都废掉了。
最后总结一下我遇到过的bug和解决方法:
(1)相同主机上面运行两个tomcat,同一个浏览器访问两个项目会相互影响登陆系统状态,我的系统表现如下:一个项目登陆后,然后另一个项目进行访问服务器,然后再在登陆的系统上面访问服务器,这是登陆的系统会返回到登陆页面。不同浏览器倒不会出现这样的情况(因为一个浏览器会服务器会创建一条连接,数据不干扰)
原因:是两个tomcat都是用默认的sessionid变量,浏览器就把这两个系统返回来的值相互覆盖,然后你把这些会话数据发到一个tomcat服务器的时候,它检查sessionid发现不是自己创建的,所以会拦截掉。
小拓展(还没有真正考究过):http协议是应用协议,底层通讯协议是基于tcp/ip的,浏览器(猜测是为了节省内存,每次访问一台主机都建立会话内存空间,开销可不小,一般来说也很少人有两个用户身份)仅仅维护一个会话内存空间,每次都会把会话数据发送到后台,以辨别用户身份(主要是sessionid)。其他技术服务器都类似(因为所有的web应用基本都是基于http协议的)。在这里也可以拓展到统一浏览器不能同时登录不同用户,所以现在大部分网站(前程无忧、京东、淘宝等等)都对同一浏览器的登陆用户进行处理,你登录后,只要会话没有超时,你再次访问网站,它会跳转到主页面(登陆后的页面)。除了java ee,我觉得这里也是可以拓展到大部分基于http的web开发技术,例如php 、asp .net等等。
解决办法:是给每个tomcat指定不一样的sessionid名称。具体请看tomcat的server.xml配置sessionCookieName。
(2)jquery ajax请求post方法的success属性后面的匿名函数没有进入。
原因:这里的原因有两方面的,第一是由于进入success是当请求成功的时候才进入;第二就是所写的匿名函数里面有语法错误了,同时可能是由于javascirpt解析器容错性大的原因,有时请求成功了,但是还是没有进入success属性的匿名函数,这时就应该是遇到语法错误了,但是却并不会提示匿名函数有错误了。
(3)在使用easyui(其实很多ui框架都差不多,如ext)的时候请注意datagrid的每一个属性列不能有html标签,不然datagrid的展示效果就会给你一个很大的惊喜。
原因:这是因为datagrid的每一行装载数据的最终实体都是div,div是一个容器,进入里面的东西都当做是html元素除了非html标签字符当做是文本。
解决办法:不要让你的数据到了展示阶段就出现问题,你的数据应当是文本,所以你可以用文本容器装载(input[type=text]、textarea);也可以把html标签尖括号转移成大小于号,我的选择是把html转移成大小于号,不仔细是分辨不出来的。其实人家设计框架的时候可能考虑到这个原因,但是没有使用input和textarea作为装载数据的容易,可能是由于这两个文本容器,input是装载数据还是挺有限的,textarea是由于比较难控制展示效果。
(4)在使用easyui datagrid的时候无论怎么选中记录,看到checkbox已经选中,你getChecked选中的记录只能是一条。
原因:极大可能是由于你的idField设置的列的值不唯一。
解决办法:是把它设置成一个值唯一的列就可以了。这里我没有具体看过easyui的源码,我当时是基于这个的思考认为的,官网说设置它预示着这个域是一个识别域,那么在使用getChecked的时候就是用这个域来识别,通过这个域的值来查找选中的行,就像是id一样。
(5)最后记得的一个是一个不甚起眼但是最近也花我不少时间的,就是java的java.lang.UnsupportedClassVersionError: Bad version number in .class file。网上很多都有,但是我的问题稍微曲折少少,那就是我要修改的项目年代久远,每一次的修改都是直接往上面扔jar包再进行开发新功能,导致同一功能jar包不同版本存在泛滥的现象。类加载器在类路径加载类的时候没有找到这个类,研究不多,这里有一个问题是如果类路径是哪个重复的类的话,那么它肯定能查找到类路径指定(jar包都在哪里)的类,这里我推测是由于加载了这个类,但是其依赖类不支持导致这样的事情发生。
解决办法:当然是删除重复的jar包,其实也可以把类路径修改成它要加来的哪一个,我当时改成是高版本的哪一个,可以解决,因为向后兼容,但是有些却不可以。