Java高级程序员面试题及答案(实战版).docxVIP

Java高级程序员面试题及答案(实战版).docx

  1. 1、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多

Java高级程序员面试题及答案(实战版)

一、JVM核心技术(考察底层原理与问题排查能力)

1.题目:Java内存模型(JMM)中,volatile关键字的作用是什么?它和synchronized的核心区别是什么?实际项目中你怎么选择使用?

答案:

volatile的核心作用有两个:一是保证变量的可见性(禁止CPU缓存和指令重排序,写操作后强制刷新到主内存,读操作直接从主内存读取);二是禁止指令重排序(通过内存屏障实现,比如DCL单例中必须给instance加volatile,避免指令重排导致拿到未初始化的对象)。

和synchronized的区别:

粒度:volatile仅修饰变量,synchronized可修饰方法、代码块(粒度更粗);

原子性:volatile不保证原子性(比如i++仍会出现线程安全问题),synchronized是排他锁,能保证原子性;

性能:volatile是轻量级同步机制,无锁竞争,开销远低于synchronized(尤其是JDK1.6后优化了偏向锁、轻量级锁)。

实际选择:

若仅需保证变量“读可见、写有序”(比如状态标记位、配置开关),用volatile;

若需保证原子性(比如计数、数据更新)或临界区互斥,用synchronized,或并发工具类(AtomicInteger、ReentrantLock)。

2.题目:JVM垃圾回收(GC)中,哪些对象会被判定为“垃圾”?常见的GC算法有哪些?G1收集器的核心优势是什么?

答案:

垃圾判定的核心是“对象不可达”:通过GCRoots(如栈帧局部变量、静态变量、JNI引用等)作为起点,遍历对象引用链,无法被遍历到的对象即为垃圾(主流用可达性分析算法,而非引用计数法,避免循环引用问题)。

常见GC算法:

标记-清除:先标记垃圾,再直接清除(优点:简单;缺点:产生内存碎片);

标记-复制:将内存分为两块,存活对象复制到另一块(优点:无碎片;缺点:内存利用率低,适合新生代);

标记-整理:标记后将存活对象向一端移动,再清除垃圾(优点:无碎片、内存利用率高;缺点:耗时,适合老年代)。

G1收集器的核心优势:

Region化内存布局:将堆内存划分为多个大小相等的Region(新生代、老年代混合分布),避免全堆扫描;

可预测的停顿时间:通过优先级机制选择回收价值最高的Region,保证在指定时间内完成GC;

兼顾新生代和老年代:无需单独配置新生代、老年代大小,自动动态调整。

二、并发编程(考察实战能力与问题规避)

1.题目:线程池的核心参数有哪些?核心线程数和最大线程数怎么设置?实际项目中你遇到过哪些线程池问题?

答案:

线程池核心参数(ThreadPoolExecutor):

corePoolSize:核心线程数(常驻线程,即使空闲也不销毁);

maximumPoolSize:最大线程数(核心线程+临时线程的上限);

keepAliveTime:临时线程空闲时间(超过则销毁);

workQueue:任务阻塞队列(核心线程满时,任务进入队列等待);

threadFactory:线程创建工厂(可自定义线程名称、优先级);

handler:拒绝策略(队列满+最大线程数满时,处理新任务的方式,如AbortPolicy直接抛异常、CallerRunsPolicy回退到调用线程执行)。

核心线程数和最大线程数设置:

CPU密集型任务(如计算):核心线程数=CPU核心数+1(避免线程切换开销,充分利用CPU);

IO密集型任务(如数据库查询、网络请求):核心线程数=CPU核心数*2(因线程大部分时间在等待IO,多线程可提高吞吐量);

实际需结合压测调整,比如通过监控线程池的队列长度、活跃线程数动态优化。

项目中遇到的问题:

队列过大+核心线程数过少:导致任务堆积,响应变慢(解决方案:调整队列大小,增大核心线程数);

最大线程数过大:导致线程切换频繁,CPU利用率飙升(解决方案:降低最大线程数,优化任务执行效率);

拒绝策略不合理:比如用AbortPolicy时,高并发下直接抛异常导致请求失败(解决方案:改用CallerRunsPolicy或自定义拒绝策略,如降级处理、缓存任务);

任务执行时间过长:占用线程池资源,导致其他任务阻塞(解决方案:拆分长任务,或单独用一个线程池处理长任务)。

2.题目:CountDownLatch、CyclicBarrier、Semaphore的区别是什么?分别用在什么场景?

答案:

三者都是并发工具类,核心区别在“协作逻辑”和“复用性”:

CountDownLatch:倒计时门闩

文档评论(0)

***** + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档