- hashSet底层实现?
hashSet底层实现用的hashMap,存入的值都在key里面,value存放的是一个固定值
// Dummy value to associate with an Object in the backing Map private static final Object PRESENT = new Object();
- 为什么内置HashMap
hashMap是基于数组和链表的数据结构,是考虑时间和空间的的因素后比较优秀的一种实现,能重用为啥要单独自己搞
- 说下HashMap的数据结构
数组加链表+红黑树
- 为什么loalFactor是0.75
太高了增加时间成本,比如1,说明会产生很多碰撞,链表已经很长了;太低,空间利用率不够;
另外这个值是坐着根据泊松分布计算后综合考虑的,泊松分布是离散随机分布的一种,通常被使用在估算在 一段特定时间/空间内发生成功事件的数量的概率。
设置成0.75有一个好处,那就是0.75正好是3/4,而capacity又是2的幂。所以,两个数的乘积都是整数。
- 为什么要高位参与运算
增加 hash 值的任意性;
- 高位运算的步骤:是无符号右移16位,低位挤走,高位补0,高位参与运算,这样算出来的结果实质是高区与低区的二进制特征混合到低区;
- 假设数组槽的大小是16,(n - 1) = 15那么他的二进制是 0000 0000 0000 0000 0000 0000 0000 1111;
- 那么计算该hashCode属于哪个槽位是用的代码 (n - 1) & hash;由于这个 (n - 1)的高位都是0,所以和hash的高位&的时候,hashCode的高位有细微变化是体现不出来的,因为和0 &运算的结果都是0;
- 所以这种情况很容易产生冲突,所以高位参与地位运算的精髓就是,让高位的细微变动能导致不同的结果,这样hash的结果更加均匀
- 为什么高位参加运算的时候使用的是异或^,而不是与&
(^ 为按位异或,即转成二进制后,相异为1,相同为0);异或运算能更好的保留各部分的特征,如果采用 & 运算计算出来的值会向 1 靠拢,采用 | 运算计算出来的值会向 0 靠拢;因为右移了16,高位是0,&之后还是0,那右移了个寂寞
- ConcurrentHashMap的get方法有锁么
只有在get方法,如果此时结构是红黑树,这个时候在进行树查找时会判断这个树是否在变色,会进行读写锁的判断
- ConcurrentHashMap的get是强一致性么?为什么是弱一致性
不是,虽然Node的数组table被volatile修饰,但是这样只是代表table的引用地址如果被修改,其他线程可以立马看到,并不代表table里的数据被修改立马可以看到。
- happens-before 是什么?
前一个操作的结果可以被后续的操作获取。讲白点就是前面一个操作把变量a赋值为1,那后面一个操作肯定能知道a已经变成了1。
网友评论