记一次诡异的bug调试——————关于JDK1.7和JDK1.8中HashSet的hash(key)算法的区别

  

现象:

测试提了一个bug,我完全复现不了,但是最吊诡的是在其他人的机器上都可以复现。起初以为是SVN合并后出现的冲突,后来经过对比法排查:

step 1:

  我本地开两个jetty,一个跑合并之前的版本,一个跑合并之后的版本,数据库、redis配置都一样的,结果一致,由此可以推测应该不是代码的问题。

step 2:

  我电脑和别人电脑同样的配置、连的一个数据库,同样的代码、同样的数据,得到了两个结果,我这里是正常的,而且除了我其它人都可以复现,我喵了狗....

  我还一度以为是灵异现象....o(╯□╰)o

step 3:

  搞了很久,注意到还是有不一样的地方,我本地的jdk版本是1.8的,他们包括测试服务器用的应该都是1.7版本的。

  后来经过验证发现,关键点在于,在前端展示的时候,之前的人写了一个列表,这个列表的显示顺序依赖了一个无序数据结构Set的顺序!!!

  因为jdk7和jdk8的hash算法是不同的,而在jdk8上面的hash之后的顺序刚好是正确的(真尼玛巧....),然后在jdk7之前的话就会出问题。  

反思问题出现的原因:  

  因为这个js文件的是在是太难驾驭(可维护性基本为负,我觉得没必要花时间去理解那么烂的代码,把代码见缝插针放进去不出问题就好....) 

  让我去改别人的代码的时候,总是抗拒去理解别人的代码(虽然它根本就不可理解...),但让我自己重写一个新功能的时候就感觉比较爽,行云流水的感觉,逻辑也比较清晰,但作为一个低级码农,给别人擦屁股大概是必备技能...

  在这里也发现一个很有趣的现象,开始的时候我小心翼翼的写代码,后来我发现之前的人都这么写,然后我不自觉的也开始往烂了写了,反正大家都这么干,大概这就是工程开发中的破窗效应吧。一旦开始烂了就一发不可收拾了....

解决方案:

  以后跟其它人进行版本统一是表面上的解决方案,其根本解决方案在于写代码的时候一定要过脑子...过!脑!子! 为防止呆逼,得要挑两个不同的时间段review两次。

  为了避免之后的人再掉坑,本来想在返回客户端的时候将set进行排序,但我已经不敢乱动代码了,动了一处其它地方就会冒出来各种bug...,干脆强制他使用LinkedHashSet算了...  

  这个问题就算是马马虎虎的解决了....

JDK1.7和JDK1.8中hash算法的区别:

 1.7中map的hash算法:

1.8中map的hash算法:

  

.

原文地址:https://www.cnblogs.com/cc11001100/p/6637052.html