网上投资网站建设,开发公众号 微网站开发,asp.net mvc 5网站开发之美 pdf,新手如何做服装网站作为程序员#xff0c;基本功不好#xff0c;可能会在工作中经常碰到一些看起来很隐蔽的 bug#xff0c;乍看没毛病#xff0c;自己半天还找不到问题所在。
但是#xff0c;如果基本功扎实的同学可能一眼就能看出来。
一、HashMap 取不到值
MapInteger, Integer基本功不好可能会在工作中经常碰到一些看起来很隐蔽的 bug乍看没毛病自己半天还找不到问题所在。
但是如果基本功扎实的同学可能一眼就能看出来。
一、HashMap 取不到值
MapInteger, Integer map new HashMap();
resMap.put(1, 1);
System.out.println(map.get(1L));
System.out.println(map.get(1));大家可以看下上面的代码输出是什么我稍后公布答案。
1、源码分析
HashMap的get方法源码如下已增加自己的注释 public V get(Object key) {NodeK,V e;return (e getNode(hash(key), key)) null ? null : e.value;
}/*** Implements Map.get and related methods.** param hash hash for key* param key the key* return the node, or null if none*/
final NodeK,V getNode(int hash, Object key) {NodeK,V[] tab; NodeK,V first, e; int n; K k;// 如果map不为空if ((tab table) ! null (n tab.length) 0 (first tab[(n - 1) hash]) ! null) {// 如果直接通过传进来的key找到了值直接返回// 1比较传进来key的hash值和在map中对应位置找到的结点的hash值是否一致// 2比较传进来的key对象和在map中对应位置找到的结点的key对象object是否相等if (first.hash hash // always check first node((k first.key) key || (key ! null key.equals(k))))return first;// 如果通过hash找到的结点的下一个节点不为空说明是链表if ((e first.next) ! null) {// 如果是红黑树直接红黑树查找if (first instanceof TreeNode)return ((TreeNodeK,V)first).getTreeNode(hash, key);// 如果是普通链表链表遍历查找do {if (e.hash hash ((k e.key) key || (key ! null key.equals(k))))return e;} while ((e e.next) ! null);}}// 上述都不满足返回nullreturn null;
}如果传的 key 对应的 hash 值能够匹配到 map 中的结点只能说 hash 表map中这个位置有东西还需要进行下面两个判断。
1比较传进来 key 的 hash 值和在 map 中对应位置找到的结点的 hash 值是否一致
2比较传进来的 key 对象和在 map 中对应位置找到的结点的key对象object是否相等。
看了上述源码分析之后我们公布答案
null
1最终的差异就是
(k first.key) key || (key ! null key.equals(k))这段代码相当于 Objects.equals(key, k)。
这里比较的是map 中存储的对象的key命名为k以及get方法传给map的 key命名为 key。
相当于比较new Integer(1) 和 new Long(1L)我们知道它们是两个不同的对象所以结果肯定不相等。所以 key 是1L的时候结果是 null。
2、结论
Map 获取值的时候key类型不匹配获取不到value。
二、日期计算
大家可以看看下面这段代码分别输出的是什么
long nowTime new Date().getTime();
System.out.println(nowTime);
System.out.println(new Date(nowTime - 7 * 24 * 60 * 60 * 1000));
System.out.println(new Date(nowTime - 25 * 24 * 60 * 60 * 1000));
System.out.println(new Date(nowTime - 30 * 24 * 60 * 60 * 1000));
System.out.println(new Date(nowTime - 60 * 24 * 60 * 60 * 1000));我们可以把代码扔给 GPT看它是否能识别其中的 bug。 上面的代码中存在一个潜在的问题。Date 的构造函数中传入的时间戳参数是 long 类型而 days * 24 * 60 * 60 * 1000 的计算结果是 int 类型存在可能的整数溢出问题。 因为 days 和其他整数相乘后超过了 int 类型能表示的范围所以这会导致计算的结果出现错误。 修复的代码可以将 int 类型的计算结果强制转换为 long 类型确保计算的精度不会丢失。修复后的代码如下 int days Integer.valueOf(daysStr);
long millisecondsInDay (long) days * 24 * 60 * 60 * 1000;
Date startDate new Date(System.currentTimeMillis() - millisecondsInDay);这样就可以避免由于整数溢出而导致的计算错误。
所以这里的知识点是 int 数组进行计算结果是 int 类型而 int 类型的范围是 21 亿2^31 - 1左右。
如果用来计算时间戳很容易就会越界导致非预期结果。
三、总结一下
虽然非科班、培训出身、转行的程序员可能会存在基本功不好的情况但是在 AI 时代这些相关的 bug 能够更快的解决。
只要你会用 AI这些有固定答案的领域很容易被 AI 取代。
我们更需要的是深入思考、创造性等只有人能干的事情。