
1. 项目概述Java后端开发——基础面试题汇总这个项目源于我在技术面试官和求职辅导中的多年实战经验。每次面试结束后我都会记录下候选人普遍存在的知识盲区以及那些真正能区分初级和中级开发者的核心问题。这份汇总不是网上随处可见的题库堆砌而是经过五年时间沉淀、迭代了十几个版本的活文档。最近帮一位朋友做模拟面试时发现即使是有3年经验的开发者在基础概念的深度理解上仍然存在系统性缺陷。比如当被问到HashMap扩容为什么选择2的幂次方时能完整解释位运算优化原理的不到20%。这促使我决定将这份私人笔记整理成结构化文档。2. 核心知识点体系2.1 Java语言基础数据类型与内存模型是面试中最容易被低估的环节。面试官常通过这样的问题考察基础扎实程度为什么Java中要有包装类型IntegerCache的默认范围是多少String s new String(abc) 会创建几个对象画出JVM内存结构图浮点数运算为什么会出现0.10.2≠0.3的情况BigDecimal如何解决重要提示在解释自动装箱时一定要提到-128~127的缓存范围这是实际开发中常见的坑点。我曾见过一个线上故障就是因为用比较超出缓存范围的Integer对象。异常处理机制的考察往往结合真实场景try { Files.readAllLines(Paths.get(test.txt)); } catch (IOException e) { throw new RuntimeException(文件读取失败); } finally { System.out.println(清理资源); } // 问如果readAllLines和throw new RuntimeException都抛出异常最终会输出什么2.2 集合框架深度解析HashMap的考点可以形成完整的知识链条初始容量16负载因子0.75的数学依据链表转红黑树的阈值8的统计学依据泊松分布并发修改异常的实际案例遍历时删除元素的正确方式对比ArrayList和LinkedList时不能停留在查快增删慢的层面。应该能用时间复杂度公式解释ArrayList的get(int index)是O(1)而LinkedList是O(n)但在中间插入元素时ArrayList的System.arraycopy()成本可能比LinkedList的节点遍历更高2.3 并发编程实战要点synchronized的锁升级过程是高频考点无锁 → 偏向锁Mark Word记录线程ID偏向锁 → 轻量级锁CAS自旋轻量级锁 → 重量级锁OS层面互斥量用生产者-消费者问题演示wait/notify的正确用法class Buffer { private QueueInteger queue new LinkedList(); private int maxSize 10; public synchronized void produce(int value) throws InterruptedException { while (queue.size() maxSize) { wait(); // 必须用while而不是if } queue.add(value); notifyAll(); } }3. JVM原理与性能调优3.1 内存区域详解通过一个OOM案例展示各区域关系// 堆溢出 Listbyte[] list new ArrayList(); while(true) list.add(new byte[1024*1024]); // 方法区溢出JDK8后是元空间 ListString strings new ArrayList(); while(true) strings.add(UUID.randomUUID().toString().intern());3.2 GC算法实战分析用MAT工具分析GC日志的典型步骤添加JVM参数-XX:PrintGCDetails -Xloggc:gc.log发现Full GC频繁老年代占用居高不下使用jmap -dump:formatb,fileheap.hprof 导出堆转储在MAT中分析Dominator Tree找到内存泄漏点4. 数据库与缓存4.1 MySQL索引优化最左前缀原则的经典错误案例CREATE INDEX idx_name_age ON users(name, age); -- 能命中索引 SELECT * FROM users WHERE name 张三 AND age 25; -- 不能命中索引 SELECT * FROM users WHERE age 25;4.2 Redis应用场景用SortedSet实现延迟队列的示例// 添加任务 redisTemplate.opsForZSet().add(delay_queue, taskId, System.currentTimeMillis() 5000); // 消费任务 SetString readyTasks redisTemplate.opsForZSet().rangeByScore( delay_queue, 0, System.currentTimeMillis());5. 框架原理剖析5.1 Spring循环依赖解决三级缓存的工作流程singletonObjects存放完全初始化好的beanearlySingletonObjects存放原始对象未填充属性singletonFactories存放ObjectFactory5.2 MyBatis缓存机制一级缓存失效的四种情况执行session.clearCache()执行了INSERT/UPDATE/DELETE跨SqlSession查询手动配置flushCachetrue6. 设计模式实战用订单状态流转展示状态模式interface OrderState { void next(Order order); void prev(Order order); } class PaidState implements OrderState { public void next(Order order) { order.setState(new ShippedState()); } // 已支付状态不能回退 public void prev(Order order) { throw new IllegalStateException(); } }7. 系统设计基础设计短链服务时要考虑哈希算法选择MurmurHash比MD5更高效分布式ID生成Snowflake算法301/302重定向的选择302更利于统计点击量8. 面试实战技巧遇到谈谈你对JVM的理解这类开放性问题时建议采用结构化回答先总述内存区域划分重点讲解堆内存的分代设计结合GC算法说明各代回收策略最后提一两个调优参数示例在解释volatile关键字时可以画这样的内存可见性示意图线程A的工作内存 → 主内存 ← 线程B的工作内存 volatile变量的读写会强制同步主内存9. 避坑指南ConcurrentHashMap的size()方法返回值不是绝对精确的SimpleDateFormat不是线程安全的推荐用DateTimeFormatter避免在finally块中使用return语句会覆盖try块中的异常Lombok的Builder会导致无参构造函数失效MySQL的utf8编码实际是3字节应该用utf8mb410. 持续学习建议建立知识图谱的有效方法使用Anki制作概念卡片如CMS收集器工作流程定期用JMeter压测自己写的Demo代码参加CodeReview时主动分析他人代码的优缺点在本地环境复现各种OOM和死锁场景我个人的经验是每个月至少深入研究一个JDK类的源码。最近分析ThreadLocal的实现时发现其内存泄漏问题比文档描述的更复杂这个认知过程比直接背面试题有价值得多。