面试官:HashTable,HashMap,TreeMap介绍下。
你:它们都实现了map接口,都是以key-value形式存储的。
HashTable线程安全且不能存null key null value
HashMap非线程安全,并且可以存放null key null value
TreeMap是基于红黑树的可以排序的map。
面试官:介绍下HashMap实现原理。
你:HashMap就会一个数组和链表的复合结构,通过hashcode来决定放在数组里的位置,然后同样的hashcode就放到链表里,如果链表长度大于阈值8了,就将链表转成红黑树。
面试官:说到hashcode,你有重写过hashcode吗?
你:有,Map里规定,equals相等,hashcode也相等,hashcode重写了,equals也要重写,equals的重写要注意对称(x=y),传递(x=y=z),反射(自反性 x = x,一致性 x=x=x=x=x)等。
面试官:你刚说的红黑树,介绍下?
你:红黑树也是一种树形数据结构,它要求一个M阶的红黑树,每个节点的子节点至少有M/2个节点,根节点例外,必须至少有两个节点。左边的节点必须小于右边的节点的值。这样就可以在插入和删除时,照样进行二分查找,时间复杂度O(logn),即保证了插入和删除,又保证了查询的效率。非常适合HashMap。
面试官:在插入HashMap的时候会与hash碰撞的问题,你会怎么解决?
你:可以像HashMap这样使用链表和树来解决,也可以将HashCode再次Hash,直到有一个新的hashcode。
面试官:如果要做一个pool,pool满 的时候删掉最老的。
你:可以利用LinkedHashMap来创建一个池。重写removeEldestEntry。
面试官:有没有在项目中使用过ConcurrentHashMap?
你:没,ConcurrentHashMap是一个基于分离锁实现的线程安全的Map类。
面试官:为什么需要ConcurrentHashMap?
你:因为HashTable性能低下。
面试官:不能让HashMap线程安全吗?
你:可以,用synchronized wrapper,但是都是粗粒度的,没ConcurrentHashMap快。
面试官:你刚说的那个分离锁是个什么东西?
你:就是和HashMap一样,ConcurrentHashMap也是数组和链表以及树的复合结构,但是数组又分散在各个segement里,segement加了锁,ReentrantLock,就成了分离锁了,有点也叫分段锁。
面试官:你不知道1.8里segement只是个摆设吗?
你:知道,1.8里只是为了序列化时兼容以前的版本,保留了segement,真正的锁是在每个链表或者树的头上。
面试官:行
你:嘿嘿
面试官:那你说的那个ReentrantLock是怎么实现的。
你:基于CAS
面试官:那CAS是什么?
你:就是compareAndSet,是CPU的一个指令,因为CPU单独一个指令是绝对线程安全的,而compare和set是在一个指令里的,所以就安全了。
面试官:那CPU指令是什么?
你:WDNMD,走了