
1. 面试场景还原谢飞机的意外开场那天早上9点15分谢飞机提前45分钟到达了字节跳动总部大楼。他反复检查着背包里的物品三份打印好的简历、一瓶矿泉水、一包纸巾以及——等等这是什么他从侧袋摸出一包已经开封的洽洽瓜子。完蛋肯定是昨晚模拟面试时随手塞进去的...这个意外发现让他瞬间回忆起三周前那次尴尬的腾讯视频面试当时家里突然传来母亲飞机啊排骨要焯水几分钟的灵魂拷问。走进明亮的面试等候区他发现今天的对手们清一色穿着深色西装而自己套头卫衣上的Hello World图案显得格外扎眼。前台小姐姐微笑着递来一杯温水您是参加Java高级开发岗的谢先生吧这是您的临时访客卡二面面试官王总监正在3号会议室等您。注意大厂面试往往从踏入公司大门那刻就已开始着装细节、等候区行为都可能被纳入考察范围。曾有候选人在阿里等候时用手机看小说被路过的技术VP直接在评估表备注了缺乏职业敏感度。推开会议室门的瞬间谢飞机看到白板上还残留着上轮面试的算法题痕迹。王总监头也不抬地说先写个单例吧要线程安全的。这个看似简单的开场让谢飞机暗自松了口气毕竟单例模式就像Java界的Hello World。但当他写下第3行代码时突然意识到自己正在使用面经里标注的危险答案——双重检查锁定(DCL)实现。public class Singleton { private static Singleton instance; public static Singleton getInstance() { if (instance null) { // 第一次检查 synchronized (Singleton.class) { // 加锁 if (instance null) { // 第二次检查 instance new Singleton(); // 问题出在这里 } } } return instance; } }能说说这个实现可能有什么问题吗王总监终于抬起头眼镜片反射着显示器冷光。谢飞机额头开始冒汗——他确实背过DCL可能存在的指令重排序问题但此刻大脑突然像被GC了一样空白。2. HashMap死亡连环问从数据结构到生产事故当面试进行到第28分钟王总监突然合上笔记本我们聊点轻松的你平时用HashMap多吗谢飞机条件反射般点头却不知道即将面对的是互联网面试史上最著名的死亡连环问。能说说HashMap的底层结构吗 JDK8相比JDK7在实现上做了什么优化 为什么链表长度超过8要转红黑树 扩容时rehash的过程是怎样的 多线程下使用HashMap会导致什么问题 你知道哪些HashMap在生产环境引发的事故案例谢飞机在回答链表转红黑树问题时突然福至心灵这个8其实是个统计学结果。根据HashMap作者Doug Lea的论文在随机哈希码下链表长度符合泊松分布当负载因子为0.75时长度达到8的概率不足千万分之六。用红黑树虽然查找时间从O(n)降到O(log n)但节点占用空间是普通节点的两倍所以需要权衡...王总监微微颔首突然抛出一个场景题如果现在有个10万条数据要存入HashMap怎样初始化能避免扩容谢飞机想起上周在GitHub看到的阿里开发手册迅速心算100000/0.75≈133333于是回答new HashMap(133333)。没想到王总监追问确定吗看看这个构造方法的源码。public HashMap(int initialCapacity) { this(initialCapacity, DEFAULT_LOAD_FACTOR); } static final int tableSizeFor(int cap) { int n -1 Integer.numberOfLeadingZeros(cap - 1); return (n 0) ? 1 : (n MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n 1; }谢飞机这才恍然大悟——HashMap的容量总是2的幂次方传入133333实际会被调整为2621442^18造成了近一倍的浪费。正确做法应该是用new HashMap(100000, 1.0f)直接指定负载因子为1。3. 线程池的七个参数从理论到血泪教训当话题转到线程池王总监让谢飞机在白板上画出线程池工作原理示意图。谢飞机画到一半时王总监突然说停这里为什么把任务队列画在RejectedExecutionHandler前面这个细节让谢飞机意识到自己可能一直误解了线程池的工作流程。通过现场分析ThreadPoolExecutor.execute()源码他们梳理出完整的任务处理逻辑当前线程数 corePoolSize → 创建新线程执行任务达到corePoolSize → 任务入队列队列满且线程数 maximumPoolSize → 创建非核心线程达到maximumPoolSize且队列满 → 触发拒绝策略你们线上用什么拒绝策略王总监的问题让谢飞机想起前东家那次P0事故。当时支付系统使用默认的AbortPolicy在促销期间大量订单被直接丢弃。后来他们改用自定义策略将拒绝任务暂存Redis并启动补偿线程但因此又引发了线程泄漏——补偿线程忘记关闭最终导致应用重启。参数设置误区案例对比表错误配置可能导致问题优化方案corePoolSizemaximumPoolSize队列积压时无法弹性扩容根据业务波动特性设置合理区间LinkedBlockingQueue无界队列OOM风险使用SynchronousQueue或指定队列容量不指定ThreadFactory线程命名混乱难排查自定义含业务前缀的命名规则keepAliveTime设置过长资源浪费结合监控数据动态调整王总监分享了一个诊断案例某核心服务CPU周期性飙高最终发现是CachedThreadPool的线程在等待IO时没有正确释放。他们通过arthas的thread命令捕获到大量WAITING状态的pool-1-thread-*线程最终改用配置了上限的ThreadPoolExecutor解决问题。4. SpringBoot的陷阱式问题从Autowired到循环依赖当话题转向SpringBoot王总监的问题开始变得刁钻Autowired和Resource有什么区别什么时候会用到Qualifier谢飞机正准备回答王总监突然打断等等你先看看这段代码会报什么错Service public class OrderService { Autowired private MapString, PaymentStrategy strategies; } interface PaymentStrategy {} Service(alipay) class AlipayStrategy implements PaymentStrategy {} Service(wechat) class WechatPayStrategy implements PaymentStrategy {}谢飞机愣住了——这和他平时见的注入方式完全不同。经过5分钟思考他回忆起Spring的ListableBeanFactory特性试探性回答这个map会自动变成beanName到实现类的映射王总监露出今天第一个微笑不错但你知道底层是怎么实现的吗他们一起分析了DefaultListableBeanFactory的resolveDependency方法发现Spring会通过DependencyDescriptor获取泛型类型信息最终调用findAutowireCandidates返回匹配的bean实例。这个机制在实现策略模式时非常有用。紧接着的循环依赖问题更是让人防不胜防。王总监给出一个经典场景Service class A { Autowired B b; } Service class B { Autowired C c; } Service class C { Autowired A a; }Spring怎么解决这个问题三级缓存具体指什么谢飞机开始回忆Spring容器启动流程突然想到早期版本用early exposure机制——在对象构造完成后就提前暴露ObjectFactory但这种方式对AOP代理对象会有问题。新版Spring通过SmartInstantiationAwareBeanPostProcessor提供了更精细的控制。5. 压力测试当OOM遇到高并发面试最后30分钟王总监打开了一个生产问题记录上周我们商品详情页出现OOM日志显示是Insufficient memory但堆内存监控却只有70%使用率你觉得可能是什么原因谢飞机想到几种可能性直接内存溢出如NIO的ByteBuffer线程栈溢出-Xss设置过小方法区元数据溢出大量动态类生成操作系统内存限制容器环境常见通过现场分析heap dump文件他们最终定位到是JNI调用的本地库存在内存泄漏。王总监趁机追问你平时怎么排查Native Memory泄漏谢飞机分享了用NMT(Native Memory Tracking)参数启动JVM的方案-XX:NativeMemoryTrackingdetail -XX:UnlockDiagnosticVMOptions -XX:PrintNMTStatistics就在面试即将结束时王总监突然说现在给你5分钟设计一个模拟高并发的测试方案要求能暴露线程安全问题。谢飞机快速在白板上画出方案使用CountDownLatch控制并发起点通过CyclicBarrier模拟持续压力结合JMeter进行梯度施压用arthas监控锁竞争情况在关键路径插入Thread.sleep随机延迟为什么不用简单的for循环起线程王总监追问。谢飞机解释那样无法保证真正的并发执行CPU时间片轮转会导致实际是串行化执行。这个回答终于让王总监满意地合上了笔记本。离场前谢飞机注意到白板角落写着待确认瓜子梗。他红着脸掏出那包洽洽瓜子王总这是准备用来解释volatile可见性原理的教具...会议室里突然爆发出今天第一次大笑。