java面试中经常被问到的问题有哪些?应届生必备这份Java常见面试题(四)_java自学_java相关资讯_成都java培训机构

java面试中经常被问到的问题有哪些?应届生必备这份Java常见面试题(四)

  • 作者:创始人
  • 发表时间:2022-01-14 10:10:12

java面试中经常被问到的问题有哪些?应届生必备这份Java常见面试题(四)

13.方法区存放什么东西

方法区又叫静态区,包含所有的class文件和static变量

方法区中包含的都是在整个程序中永远唯一的元素,如classstatic变量

运行时常量池都分配在Java虚拟机的方法区之中

14.并发集合和普通集合如何区别?

并发集合常见的有 ConcurrentHashMapConcurrentLinkedQueueConcurrentLinkedDeque 等。

并发集合位java.util.concurrent 包下,是 jdk1.5 之后才有的,主要作者是 Doug Lea完成的。

java 中有普通集合、同步(线程安全)的集合、并发集合。普通集合通常性能最高,但是不保证多线程的安全性和并发的可靠性。线程安全集合仅仅是给集合添加了synchronized 同步锁,严重牺牲了性能,而且对并发的效率就更低了,并发集合则通过复杂的策略不仅保证了多线程的安全又提高的并发时的效率。

java面试中经常被问到的问题有哪些

参考阅读:

ConcurrentHashMap 是线程安全的 HashMap 的实现,默认构造同样有 initialCapacity loadFactor属性,不过还多了一个 concurrencyLevel 属性,三属性默认值分别为 160.75 16。其内部使用锁分段技术,维持这锁Segment 的数组,在 Segment 数组中又存放着 Entity[]数组,内部 hash 算法将数据较均匀分布在不同锁中。

put 操作:并没有在此方法上加上 synchronized

首先对 key.hashcode 进行 hash 操作,得到 key hash 值。

hash操作的算法和 map也不同,根据此 hash 值计算并获取其对应的数组中的 Segment对象(继承自ReentrantLock),接着调用此 Segment 对象的 put 方法来完成当前操作。

ConcurrentHashMap 基于 concurrencyLevel 划分出了多个 Segment 来对 key-value 进行存储,从而避免每次 put 操作都得锁住整个数组。在默认的情况下,最佳情况下可允许 16 个线程并发无阻塞的操作集合对象,尽可能地减少并发时的阻塞现象。

get(key)操作:

首先对 key.hashCode 进行 hash 操作,基于其值找到对应的 Segment 对象,调用其 get 方法完成当前操作。而 Segment get 操作首先通过 hash 值和对象数组大小减 1 的值进行按位与操作来获取数组上对应位置的HashEntry。在这个步骤中,可能会因为对象数组大小的改变,以及数组上对应位置的HashEntry 产生不一致性,那么 ConcurrentHashMap 是如何保证的?

对象数组大小的改变只有在 put 操作时有可能发生,由于 HashEntry 对象数组对应的变量是 volatile 类型的,因此可以保证如 HashEntry 对象数组大小发生改变,读操作可看到最新的对象数组大小。

在获取到了 HashEntry 对象后,怎么能保证它及其 next 属性构成的链表上的对象不会改变呢?这点ConcurrentHashMap 采用了一个简单的方式,即 HashEntry 对象中的 hashkeynext 属性都是final 的,这也就意味着没办法插入一个 HashEntry 对象到基于 next 属性构成的链表中间或末尾。这样就可以保证当获取到 HashEntry对象后,其基于 next 属性构建的链表是不会发生变化的。

ConcurrentHashMap 默认情况下采用将数据分为 16 个段进行存储,并且 16 个段分别持有各自不同的锁Segment,锁仅用于 put remove 等改变集合对象的操作,基于 volatile HashEntry 链表的不变性实现了读取的不加锁。这些方式使得ConcurrentHashMap 能够保持极好的并发支持,尤其是对于读远比插入和删除频繁的 Map而言,而它采用的这些方法也可谓是对于 Java 内存模型、并发机制深刻掌握的体现

java面试中经常被问到的问题有哪些?应届生必备这份Java常见面试题(四)。关注成都Java培训机构,带你了解更多相关问题。