尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Java面试必备:线程安全、JVM调优与微服务实战

Java面试必备:线程安全、JVM调优与微服务实战 1. 面试开场当面试官让我手写一个线程安全的单例模式那天阳光明媚我穿着唯一一件没沾上咖啡渍的衬衫去面试。刚坐下面试官推了推眼镜先写个双重校验锁的单例吧。 我嘴角微微抽搐——这题我背过八百遍但每次写都像在拆炸弹。public class Singleton { private static volatile Singleton instance; private Singleton() {} public static Singleton getInstance() { if (instance null) { synchronized (Singleton.class) { if (instance null) { instance new Singleton(); } } } return instance; } }血泪教训去年有次面试我忘了写volatile结果被追问指令重排序会导致什么问题时直接卡壳。后来才知道JVM可能会对对象初始化进行指令重排导致其他线程拿到未初始化完成的对象。2. 多线程连环问从synchronized问到AQS说说synchronized和ReentrantLock的区别 面试官突然切换话题。我暗自庆幸上周刚在博客上整理过这个特性synchronizedReentrantLock实现机制JVM层面通过monitor实现JDK层面通过AQS实现锁获取方式自动获取和释放需要手动lock/unlock中断响应不支持支持lockInterruptibly()公平锁非公平可配置公平/非公平条件变量只能配合wait/notify可创建多个Condition正当我滔滔不绝时面试官突然打断AQS的CLH队列为什么用双向链表 我手一抖水杯差点打翻——这问题我研究源码时还真注意过。因为要支持取消操作。当线程取消获取锁时需要快速找到前驱节点修改next指针单向链表做不到O(1)时间复杂度的前驱查找...3. JVM调优实战从OOM到GC日志分析面试官突然掏出一道场景题线上服务Full GC频繁怎么排查 我仿佛听见了送分题的声音抓取现场证据jmap -heap pid # 看堆内存分布 jstat -gcutil pid 1000 # 每秒钟打印GC情况分析GC日志记得加JVM参数-XX:PrintGCDetails -XX:PrintGCDateStamps -Xloggc:/path/to/gc.log常见病根内存泄漏用MAT分析堆转储大对象直接进老年代检查-XX:PretenureSizeThresholdSurvivor区过小导致过早晋升调整-XX:SurvivorRatio真实案例去年我们有个服务Young GC耗时突然从20ms涨到200ms最后发现是有人往List里疯狂add没控制上限。教训就是永远要给集合设置初始容量4. 微服务连环炮从雪崩效应到分布式事务说说你们怎么处理服务雪崩 面试官的眼睛突然亮了起来。我清了清嗓子防御三板斧熔断Hystrix/Sentinel降级准备静态fallback限流Guava RateLimiter/RedisLua分布式事务的坑// 伪代码Seata的AT模式 GlobalTransactional public void purchase() { orderService.create(); // 分支事务1 storageService.deduct(); // 分支事务2 accountService.debit(); // 分支事务3 }注意Seata的全局锁会阻塞其他事务高并发场景要用SAGA模式... 我话没说完面试官突然问那SAGA怎么保证最终一致性靠重试逆向操作 我赶紧画图解释每个正向操作都要配补偿操作就像...5. 面试官的灵魂拷问你的JVM参数是怎么调的空气突然安静。我咽了咽口水开始掏实战经验电商项目配置范例-Xms4g -Xmx4g # 堆内存固定避免动态调整开销 -XX:NewRatio2 # 年轻代占1/3 -XX:SurvivorRatio8 # Eden和Survivor比例 -XX:UseG1GC # 大堆内存用G1 -XX:MaxGCPauseMillis200 # 目标暂停时间 -XX:InitiatingHeapOccupancyPercent45 # 触发并发GC的堆占用率等等 面试官突然打断为什么G1的IHOP默认值是45 我额头开始冒汗——这细节我确实研究过因为G1的计算模型里45%的占用率开始回收能在老年代填满前完成并发标记。如果设太高可能来不及回收就OOM了...6. 那些年我踩过的坑多线程调试实录面试接近尾声面试官突然笑了说说你遇到最棘手的并发bug 我顿时来了精神死锁现场重现// 线程A synchronized(lock1){ Thread.sleep(100); synchronized(lock2){...} } // 线程B synchronized(lock2){ Thread.sleep(100); synchronized(lock1){...} }后来我们用jstack抓到死锁但线上环境更可怕——那次是线程池任务卡住用Arthas的thread命令发现是Redis连接池被耗尽了...7. 微服务架构的黑暗面当Nacos集群崩了面试官最后抛出一个开放题微服务架构最让你头疼的是什么 我苦笑着说出血泪史配置中心高可用Nacos集群必须3节点以上且不能用默认的derby存储链路追踪成本SkyWalking的ES分片设置不好会把集群压垮接口兼容性加字段容易删字段难我们强制要求所有DTO都继承版本号基类最惨的一次是发布时忘了兼容老接口导致凌晨三点被叫起来回滚... 看到面试官会意的笑容我知道这波稳了。
返回列表