239 Star 2.1K Fork 87

鹏磊 / DevBooks

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
并发编程高级面试题及答案,企业真面试题.md 9.13 KB
一键复制 编辑 原始数据 按行查看 历史

并发编程高级面试题及答案,企业真面试题

全部答案,更新日期:2023年6月11日,直接下载吧!

下载链接:高清172份,累计 7701 页大厂面试题 PDF

1、JVM 运行时内存

Java 堆从 GC 的角度还可以细分为: 新生代(Eden 区、 From Survivor 区和 To Survivor 区)和老年代。

新生代

是用来存放新生的对象。一般占据堆的 1/3 空间。由于频繁创建对象,所以新生代会频繁触发MinorGC 进行垃圾回收。新生代又分为 Eden区、 ServivorFrom、 ServivorTo 三个区。

Eden 区

Java 新对象的出生地(如果新创建的对象占用内存很大,则直接分配到老年代)。当 Eden 区内存不够的时候就会触发 MinorGC,对新生代区进行一次垃圾回收。

ServivorFrom

上一次 GC 的幸存者,作为这一次 GC 的被扫描者。

ServivorTo

保留了一次 MinorGC 过程中的幸存者。

MinorGC 的过程(复制->清空->互换)

MinorGC 采用复制算法。

eden、 servicorFrom 复制到 ServicorTo,年龄+1

首先,把 Eden 和 ServivorFrom 区域中存活的对象复制到 ServicorTo 区域(如果有对象的年龄以及达到了老年的标准,则赋值到老年代区),同时把这些对象的年龄+1(如果 ServicorTo 不够位置了就放到老年区);

清空 eden、 servicorFrom

然后,清空 Eden 和 ServicorFrom 中的对象;

ServicorTo 和 ServicorFrom 互换

最后, ServicorTo 和 ServicorFrom 互换,原 ServicorTo 成为下一次 GC 时的 ServicorFrom区。

2、如果你提交任务时,线程池队列已满,这时会发生什么

这里区分一下:

1、 如果使用的是无界队列LinkedBlockingQueue,也就是无界队列的话,没关系,继续添加任务到阻塞队列中等待执行,因为LinkedBlockingQueue可以近乎认为是一个无穷大的队列,可以无限存放任务

2、 如果使用的是有界队列比如ArrayBlockingQueue,任务首先会被添加到ArrayBlockingQueue中,ArrayBlockingQueue满了,会根据maximumPoolSize的值增加线程数量,如果增加了线程数量还是处理不过来,ArrayBlockingQueue继续满,那么则会使用拒绝策略RejectedExecutionHandler处理满了的任务,默认是AbortPolicy

3、永久代

指内存的永久保存区域,主要存放 Class 和 Meta(元数据)的信息,Class 在被加载的时候被放入永久区域, 它和和存放实例的区域不同,GC不会在主程序运行期对永久区域进行清理。所以这也导致了永久代的区域会随着加载的 Class 的增多而胀满,最终抛出 OOM 异常。

4、什么是不可变对象,它对写并发应用有什么帮助?

1、 不可变对象(Immutable Objects)即对象一旦被创建它的状态(对象的数据,也即对象属性值)就不能改变,反之即为可变对象(Mutable Objects)。

2、 不可变对象的类即为不可变类(Immutable Class)。Java平台类库中包含许多不可变类,如String、基本类型的包装类、BigInteger和BigDecimal等。

3、 不可变对象天生是线程安全的。它们的常量(域)是在构造函数中创建的。既然它们的状态无法修改,这些常量永远不会变。

1、 不可变对象永远是线程安全的。

2、 只有满足如下状态,一个对象才是不可变的;

3、 它的状态不能在创建后再被修改;

4、 所有域都是final类型;并且,

5、 它被正确创建(创建期间没有发生this引用的逸出)。

5、什么是多线程的上下文切换

多线程的上下文切换是指CPU控制权由一个已经正在运行的线程切换到另外一个就绪并等待获取CPU执行权的线程的过程。

6、Java的内存模型是什么?(JMM是什么?)

JVM试图定义一种统一的内存模型,能将各种底层硬件及操作系统的内存访问差异进行封装,使Java程序在不同硬件及操作系统上都能达到相同的并发效果。它分为工作内存和主内存,线程无法对主存储器直接进行操作,一个线程要和另外一个线程通信,只能通过主存进行交换。

JMM可以说是Java并发的基础,它的定义将直接影响多线程实现的机制,如果你想要想深入了解多线程并发中的相关问题现象,对JMM的深入研究是必不可少的。

上面两个问题是经常容易搞混的,但它们的内容却完全不同的。

7、Collections.synchronized  是什么?

**注意:_ 号代表后面是还有内容的_

此方法是干什么的呢,他完完全全的可以把List、Map、Set接口底下的集合变成线程安全的集合

Collections.synchronized * :原理是什么,我猜的话是代理模式:

8、在 Java 程序中怎么保证多线程的运行安全?

出现线程安全问题的原因一般都是三个原因:

1、 线程切换带来的原子性问题 解决办法:使用多线程之间同步synchronized或使用锁(lock)。

2、 缓存导致的可见性问题 解决办法:synchronized、volatile、LOCK,可以解决可见性问题

3、 编译优化带来的有序性问题 解决办法:Happens-Before 规则可以解决有序性问题

9、怎么获取 Java 程序使用的内存?堆使用的百分比?

可以通过 java.lang.Runtime 类中与内存相关方法来获取剩余的内存,总内存及最大堆内存。通过这些方法你也可以获取到堆使用的百分比及堆内存的剩余空间。Runtime.freeMemory() 方法返回剩余空间的字节数,Runtime.totalMemory()方法总内存的字节数,Runtime.maxMemory() 返回最大内存的字节数。

10、你如何确保main()方法所在的线程是Java 程序最后结束的线程?

我们可以使用Thread类的join()方法来确保所有程序创建的线程在main()方法退出前结束。

11、多线程同步和互斥有几种实现方法,都是什么?

12、怎么查看服务器默认的垃圾回收器是哪一个?

13、如何在两个线程间共享数据?

14、谈谈 JVM 中的常量池

15、线程池有什么优点?

16、你都有哪些手段用来排查内存溢出?

17、你都用过G1垃圾回收器的哪几个重要参数?

18、说说类加载的过程

19、什么是 Callable 和 Future?

20、什么是内存屏障?

21、栈溢出的原因?

22、你知道哪些故障处理工具?

23、你平时工作中用过的JVM常用基本配置参数有哪些?

24、说说ZGC垃圾收集器的工作原理

25、newScheduledThreadPool

26、什么是线程调度器(Thread Scheduler)和时间分片(Time Slicing)?

27、对象是怎么从年轻代进入老年代的?

28、SynchronizedMap 和 ConcurrentHashMap 有什么区别?

29、你对线程优先级的理解是什么?

30、在 Java 中,对象什么时候可以被垃圾回收?

31、重排序实际执行的指令步骤

全部答案,更新日期:2023年6月11日,直接下载吧!

下载链接:全部答案,整理好了

新增:高清PDF:172份,7701页,最新整理

Java
1
https://gitee.com/souyunku/DevBooks.git
git@gitee.com:souyunku/DevBooks.git
souyunku
DevBooks
DevBooks
master

搜索帮助