④集合部分
1、Map 和 ConcurrentHashMap 的区别?
考点:集合
参考回答:
hashmap 是线程不安全的,put 时在多线程情况下,会形成环从而导致死循环。 CoucurrentHashMap 是线程安全的,采用分段锁机制,减少锁的粒度。
2、hashMap 内部具体如何实现的?
考点:集合
参考回答:
Hashmap 基于数组实现的,通过对 key 的 hashcode & 数组的长度得到在数组中位置,如当 前数组有元素,则数组当前元素 next 指向要插入的元素,这样来解决 hash 冲突的,形成了拉链 式的结构。put 时在多线程情况下,会形成环从而导致死循环。数组长度一般是 2n,从 0 开始编 号,所以 hashcode & (2n-1),(2n-1)每一位都是 1,这样会让散列均匀。需要注意的是, HashMap 在 JDK1.8 的版本中引入了红黑树结构做优化,当链表元素个数大于等于 8 时,链表转 换成树结构;若桶中链表元素个数小于等于 6 时,树结构还原成链表。因为红黑树的平均查找长 度是 log(n),长度为 8 的时候,平均查找长度为 3,如果继续使用链表,平均查找长度为 8/2=4, 这才有转换为树的必要。链表长度如果是小于等于 6,6/2=3,虽然速度也很快的,但是转化为 树结构和生成树的时间并不会太短。还有选择 6 和 8,中间有个差值 7 可以有效防止链表和树频 繁转换。假设一下,如果设计成链表个数超过 8 则链表转换成树结构,链表个数小于 8 则树结构 转换成链表,如果一个 HashMap 不停的插入、删除元素,链表个数在 8 左右徘徊,就会频繁的发 生树转链表、链表转树,效率会很低。
3、如果 hashMap 的 key 是一个自定义的类,怎么办?
考点:集合
参考回答:
使用 HashMap,如果 key 是自定义的类,就必须重写 hashcode()和 equals()。
4、ArrayList 和 LinkedList 的区别,如果一直在 list 的尾部添加元素,用哪 个效率高?
考点:集合
参考回答:
ArrayList 采用数组数组实现的,查找效率比 LinkedList 高。LinkedList 采用双向链表实 现的,插入和删除的效率比 ArrayList 要高。一直在 list 的尾部添加元素,LinkedList 效率要 高。
5、HashMap 底层,负载因子,为啥是 2^n?
考点:集合
参考回答:
负载因子默认是 0.75, 2^n 是为了让散列更加均匀,例如出现极端情况都散列在数组中的 一个下标,那么 hashmap 会由 O(1)复杂退化为 O(n)的。
6、ConcurrentHashMap 锁加在了哪些地方?
考点:集合
参考回答:
加在每个 Segment 上面。
7、TreeMap 底层,红黑树原理?
考点:集合
参考回答:
TreeMap 的实现就是红黑树数据结构,也就说是一棵自平衡的排序二叉树,这样就可以保证 当需要快速检索指定节点。
红黑树的插入、删除、遍历时间复杂度都为 O(lgN),所以性能上低于哈希表。但是哈希表 无法提供键值对的有序输出,红黑树因为是排序插入的,可以按照键的值的大小有序输出。红黑 树性质:
性质 1:每个节点要么是红色,要么是黑色。
性质 2:根节点永远是黑色的。
性质 3:所有的叶节点都是空节点(即 null),并且是黑色的。
性质 4:每个红色节点的两个子节点都是黑色。(从每个叶子到根的路径上不会有两个连续 的红色节点)
性质 5:从任一节点到其子树中每个叶子节点的路径都包含相同数量的黑色节点。
8、concurrenthashmap 有啥优势,1.7,1.8 区别?
考点:集合
参考回答:
Concurrenthashmap 线程安全的, 1.7 是在 jdk1.7 中采用 Segment + HashEntry 的方式进 行实现的, lock 加在 Segment 上面。 1.7size 计算是先采用不加锁的方式,连续计算元素的个数, 最多计算 3 次:1、如果前后两次计算结果相同,则说明计算出来的元素个数是准确的;2、如果 前后两次计算结果都不同,则给每个 Segment 进行加锁,再计算一次元素的个数;
1.8 中放弃了 Segment 臃肿的设计,取而代之的是采用 Node + CAS + Synchronized 来 保证并发安全进行实现,1.8 中使用一个 volatile 类型的变量 baseCount 记录元素的个数,当 插入新数据或则删除数据时,会通过 addCount()方法更新 baseCount,通过累加 baseCount 和 CounterCell 数组中的数量,即可得到元素的总个数;
9、ArrayList 是否会越界?
考点:集合
参考回答:
ArrayList 是实现了基于动态数组的数据结构,而 LinkedList 是基于链表的数据结构 2. 对 于随机访问 get 和 set, ArrayList 要优于 LinkedList,因为 LinkedList 要移动指针; ArrayList 并发 add()可能出现数组下标越界异常
10、什么是 TreeMap?
考察点:key-value 集合
参考回答:
TreeMap 是一个有序的 key-value 集合,基于红黑树(Red-Black tree)的 NavigableMap 实现。该映射根据其键的自然顺序进行排序,或者根据创建映射时提供的 Comparator 进行排序, 具体取决于使用的构造方法。
TreeMap 的特性:
根节点是黑色
每个节点都只能是红色或者黑色
每个叶节点(NIL 节点,空节点)是黑色的。
如果一个节点是红色的,则它两个子节点都是黑色的,也就是说在一条路径上不能出现两个 红色的节点。
从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。