Java高级工程师面试题及答案.docx

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多

Java高级工程师面试题及答案

一、JVM相关

问题:线上服务频繁触发FullGC,该怎么排查和解决?

答案:先从“日志+工具”双维度定位问题。第一步,开启JVMGC日志(-XX:+PrintGCDetails-XX:+PrintGCTimeStamps),看FullGC触发时的内存占用——如果老年代占满,大概率是大对象没回收;如果永久代/元空间满,可能是类加载过多(比如频繁动态生成类)。第二步,用Arthas的heapdump导出内存快照,用MAT分析:比如之前项目里,发现HashMap缓存没设过期时间,存了百万级订单数据,老年代持续上涨,FullGC10分钟一次。解决方式:把缓存换成GuavaCache,设置最大容量和1小时过期,之后FullGC降到每天1次。另外要注意:避免在循环里创建大对象(比如StringBuilder不重用),减少老年代对象晋升。

问题:JVM的内存模型(JMM)是什么?它解决了什么实际问题?

答案:JMM核心是定义了主内存和工作内存的交互规则,还有volatile、synchronized、final的内存语义。实际项目里,它主要解决“可见性”和“有序性”问题。比如之前做秒杀系统,有个库存变量intstock=100,多线程扣减时,线程A改了stock=99,线程B可能还读的是老值,导致超卖——这就是可见性问题,用volatile修饰stock后,线程改完会立刻刷回主内存,其他线程读的时候会从主内存加载,就解决了。还有有序性,比如DCL单例里,instance=newSingleton()会拆成分配内存、初始化、赋值三步,JVM可能重排序,导致线程拿到未初始化的instance,加volatile就能禁止重排序,这都是JMM的实际应用。

二、并发编程

问题:synchronized和ReentrantLock有啥区别?实际项目里怎么选?

答案:从三个维度区分:一是底层,synchronized是JVM层面的锁(字节码指令monitorenter/monitorexit),ReentrantLock是API层面(基于AQS);二是功能,ReentrantLock支持可中断(lockInterruptibly)、可超时(tryLock)、公平锁、条件变量(Condition),synchronized不行;三是性能,JDK1.6后synchronized做了偏向锁、轻量级锁优化,低并发下和ReentrantLock差不多,但高并发竞争激烈时,ReentrantLock更灵活。

实际选的时候看场景:如果只是简单的同步(比如单例初始化、简单方法加锁),用synchronized,代码简洁还不用手动释放锁(避免忘unlock导致死锁);如果需要复杂功能,比如秒杀里控制并发量,用ReentrantLock的tryLock(100ms),拿不到锁就返回“请求过忙”,避免线程阻塞;再比如生产者消费者模型,用Condition的await/signal,比synchronized的wait/notify灵活,能精准唤醒。

问题:线程池参数怎么设置?比如做一个定时任务处理大量日志,核心参数该怎么调?

答案:线程池核心参数要结合“任务类型”和“硬件资源”来定。首先明确任务是CPU密集型(比如计算)还是IO密集型(比如读数据库、日志写入)——CPU密集型线程数=CPU核心数+1(避免线程切换浪费),IO密集型线程数=CPU核心数*2(因为线程大部分时间在等IO,多开线程提高利用率)。

比如处理日志的定时任务:日志是IO密集型(写文件/传Elasticsearch),假设服务器是8核CPU,核心线程数可以设16,最大线程数24(防止突发日志量),队列用LinkedBlockingQueue,容量设1000(超出后触发最大线程数),拒绝策略用CallerRunsPolicy(让提交任务的线程自己处理,避免日志丢失)。另外要注意:线程池要手动创建,别用Executors的默认实现——比如FixedThreadPool用无界队列,日志突发时会堆满内存,OOM过一次就记教训了。

三、Spring生态

问题:SpringBean的生命周期是什么?循环依赖怎么解决的?实际项目里遇到过循环依赖吗?

答案:Bean生命周期分四步:实例化(new对象)→属性注入(setter赋值)→初始化(@PostConstruct、Initializ

文档评论(0)

151****9429 + 关注
实名认证
内容提供者

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

1亿VIP精品文档

相关文档