第3讲 谈谈final、finally、 finalize有什么不同?

谈谈 final、finally、 finalize 有什么不同?

典型回答
final 可以用来修饰类、方法、变量,分别有不同的意义,final 修饰的 class 代表不可以继承扩展,final 的变量是不可以修改的,而 final 的方法也是不可以重写的(override)。
finally 则是 Java 保证重点代码一定要被执行的一种机制。我们可以使用 try-finally 或者 try-catch-finally 来进行类似关闭 JDBC 连接、保证 unlock 锁等动作。
finalize 是基础类 java.lang.Object 的一个方法,它的设计目的是保证对象在被垃圾收集前完成特定资源的回收。finalize 机制现在已经不推荐使用,并且在 JDK 9 开始被标记为 deprecated。

继续阅读第3讲 谈谈final、finally、 finalize有什么不同?

第4讲 强引用、软引用、弱引用、幻象引用有什么区别?

强引用、软引用、弱引用、幻象引用有什么区别?具体使用场景是什么?

典型回答不同的引用类型,主要体现的是对象不同的可达性(reachable)状态和对垃圾收集的影响。见下1 引用类型。

继续阅读第4讲 强引用、软引用、弱引用、幻象引用有什么区别?

HashMap 的工作原理是什么?

HashMap 是基于 hashing 的原理
我们使用 put(key, value) 存储对象到 HashMap 中,使用 get(key) 从 HashMap 中获取对象。
当我们给 put() 方法传递键和值时,我们先对调用 hashCode() 方法,计算并返回的 hashCode 是用于找到 Map 数组 bucket 位置来储存 Node 对象。

这里关键点在于指出,HashMap 是在 bucket 中储存键对象和值对象,作为Map.Node

以下是 HashMap 初始化

Node[] table = new Node[16]; // 散列桶初始化,table
class Node {
    hash; //hash值
    key; //键
    value; //值
    Node next; //用于指向链表的下一层(产生冲突,用拉链法)
}


以下是具体的 put 过程(JDK1.8)
1. 对 Key 求 Hash 值,然后再计算下标
2. 如果没有碰撞,直接放入桶中(碰撞的意思是计算得到的 Hash 值相同,需要放到同一个 bucket 中)
3. 如果碰撞了,以链表的方式链接到后面
4. 如果链表长度超过阀值(TREEIFY THRESHOLD==8),就把链表转成红黑树,链表长度低于6,就把红黑树转回链表
5. 如果节点已经存在就替换旧值
6. 如果桶满了(容量16*负载因子0.75=12),就需要 resize(扩容2倍后重排),rehash的位置只可能在两处


关于具体的 get 过程
考虑特殊情况:如果两个键的 hashcode 相同,你如何获取值对象?

当我们调用 get() 方法,HashMap 会使用键对象的 hashcode 找到 bucket 位置,找到 bucket 位置之后,会调用 keys.equals() 方法逐一比较去找到链表中正确的节点,最终找到要找的值对象。