Skip to content

Commit 05b1025

Browse files
committed
优化集合知识
1 parent fcbce3e commit 05b1025

File tree

1 file changed

+6
-14
lines changed

1 file changed

+6
-14
lines changed

MD/Java基础-集合.md

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,10 @@
1515
3. Vector可以设置capacityIncrement,而ArrayList不可以,从字面理解就是capacity容量,Increment增加,容量增长的参数。
1616

1717
### HashMap
18-
[面试必问的几个点](http://www.importnew.com/7099.html)
19-
20-
(1)JDK 1.8 以前 HashMap 的实现是 数组+链表,即使哈希函数取得再好,也很难达到元素百分百均匀分布。
21-
22-
(2)当 HashMap 中有大量的元素都存放到同一个桶中时,这个桶下有一条长长的链表,这个时候 HashMap 就相当于一个单链表,假如单链表有 n 个元素,遍历的时间复杂度就是 O(n),完全失去了它的优势。
23-
24-
(3)针对这种情况,JDK 1.8 中引入了红黑树(查找时间复杂度为 O(logn))来优化这个问题
25-
26-
(4)为什么线程不安全?多线程PUT操作时可能会覆盖刚PUT进去的值;扩容操作会让链表形成环形数据结构,形成死循环
18+
1. JDK 1.8 以前 HashMap 的实现是 数组+链表,即使哈希函数取得再好,也很难达到元素百分百均匀分布。当 HashMap 中有大量的元素都存放到同一个桶中时,这个桶下有一条长长的链表,这个时候 HashMap 就相当于一个单链表,假如单链表有 n 个元素,遍历的时间复杂度就是 O(n),完全失去了它的优势。针对这种情况,JDK 1.8 中引入了红黑树(查找时间复杂度为 O(logn))来优化这个问题
19+
2. 为什么线程不安全?多线程PUT操作时可能会覆盖刚PUT进去的值;扩容操作会让链表形成环形数据结构,形成死循环
20+
3. 容量的默认大小是 16,负载因子是 0.75,当 HashMap 的 size > 16*0.75 时就会发生扩容(容量和负载因子都可以自由调整)。
21+
4. 为什么容量是2的倍数?在根据hashcode查找数组中元素时,取模性能远远低于与性能,且和2^n-1进行与操作能保证各种不同的hashcode对应的元素也能均匀分布在数组中
2722

2823
### ConcurrentHashMap原理
2924
[http://www.jasongj.com/java/concurrenthashmap/](http://www.jasongj.com/java/concurrenthashmap/)
@@ -38,8 +33,5 @@ ConcurrentHashMap 类中包含两个静态内部类 HashEntry 和 Segment。Hash
3833
#### Java8
3934
![](https://github.com/xbox1994/2018-Java-Interview/raw/master/images/j4.jpg)
4035

41-
Java 8为进一步提高并发性,摒弃了分段锁的方案,而是直接使用一个大的数组。同时为了提高哈希碰撞下的寻址性能,Java 8在链表长度超过一定阈值(8)时将链表(寻址时间复杂度为O(N))转换为红黑树(寻址时间复杂度为O(long(N))
42-
43-
Java 8的ConcurrentHashMap同样是通过Key的哈希值与数组长度取模确定该Key在数组中的索引。
44-
45-
对于put操作,如果Key对应的数组元素为null,则通过CAS操作将其设置为当前值。如果Key对应的数组元素(也即链表表头或者树的根元素)不为null,则对该元素使用synchronized关键字申请锁,然后进行操作。如果该put操作使得当前链表长度超过一定阈值,则将该链表转换为树,从而提高寻址效率。
36+
1. 为进一步提高并发性,放弃了分段锁,使用CAS + synchronized 来保证
37+
2. put操作:如果Key对应的数组元素为null,则通过CAS操作将其设置为当前值。如果Key对应的数组元素(也即链表表头或者树的根元素)不为null,则对该元素使用synchronized关键字申请锁,然后进行操作。如果该put操作使得当前链表长度超过一定阈值,则将链表(寻址时间复杂度为O(N))转换为红黑树(寻址时间复杂度为O(log(N))

0 commit comments

Comments
 (0)