这篇不是那种"看了很多但记不住"的八股文,而是我按面试真实节奏整理的100题 :每题都包含「思路 + 一段话回答」,能让你在面试中说得出来、讲得清楚、还能接住追问。
适合人群:
-
正在准备 Java 后端实习 / 秋招
-
八股背了但说不出来
-
想快速补全知识体系的人
一、Java基础(1~10)
1. String、StringBuilder、StringBuffer区别?
思路:是否可变 + 线程安全 + 性能
回答:String是不可变对象,每次拼接都会创建新对象,性能较差;StringBuilder是可变的且线程不安全,但性能最好;StringBuffer通过synchronized保证线程安全,性能相对较低,因此单线程优先使用StringBuilder,多线程场景才考虑StringBuffer。
2. == 和 equals 区别?
思路:值 vs 地址
回答:基本类型中==比较的是值;引用类型中==比较的是对象地址,而equals默认也是比较地址,但像String重写了equals用于比较内容,因此实际开发中一般使用equals判断对象是否逻辑相等。
3. final、finally、finalize区别?
思路:关键字分类
回答:final用于修饰类、方法和变量,表示不可变或不可继承;finally是异常处理中的代码块,用于保证一定执行;finalize是对象被回收前调用的方法,但已经逐渐废弃,不推荐使用。
4. 重载和重写区别?
思路:编译期 vs 运行期
回答:重载发生在同一个类中,方法名相同参数不同,是编译期多态;重写是子类对父类方法的实现,是运行期多态,要求方法签名一致,返回值可以协变,访问权限不能缩小。
5. 深拷贝 vs 浅拷贝?
思路:引用复制
回答:浅拷贝只复制对象引用地址,多个对象共享同一数据;深拷贝会复制整个对象及其引用对象,生成完全独立的新对象,互不影响。
6. 接口和抽象类区别?
思路:设计用途
回答:接口用于定义行为规范,支持多实现;抽象类用于代码复用,只能单继承,通常接口用于扩展能力,抽象类用于模板设计。
7. 多态是什么?
思路:运行期行为
回答:多态是指同一方法在不同对象上表现不同,依赖继承和方法重写实现,编译期看引用类型,运行期看实际对象类型。
8. Java异常体系?
思路:Error vs Exception
回答:Java异常分为Error和Exception,Error通常是系统级错误;Exception分为受检异常和运行时异常,受检异常必须处理,而运行时异常可以不显式捕获。
9. 反射是什么?
思路:运行时操作类
回答:反射是在运行时动态获取类信息并操作对象的机制,广泛用于框架设计,但会带来一定性能开销。
10. 注解作用?
思路:元数据
回答:注解用于提供元数据,通过反射在运行时解析,实现自动配置、依赖注入等功能,是Spring等框架的核心机制。
二、集合(11~15)
11. ArrayList vs LinkedList?
思路:结构
回答:ArrayList基于数组,查询快但插入删除慢;LinkedList基于链表,插入删除快但查询慢,一般优先使用ArrayList。
12. HashMap原理?
思路:结构+冲突
回答:HashMap底层是数组+链表+红黑树,通过hash定位位置,冲突时使用链表,链表长度超过8转为红黑树,提高查询效率。
13. HashMap为什么线程不安全?
思路:并发问题
回答:HashMap在并发下可能出现数据覆盖、死循环等问题,因为其put和扩容操作没有加锁。
14. ConcurrentHashMap原理?
思路:CAS+锁
回答:JDK8中通过CAS和synchronized实现线程安全,降低锁粒度,提高并发性能。
15. HashSet原理?
思路:基于Map
回答:HashSet底层基于HashMap实现,通过key唯一性保证元素不重复。
三、并发(16~35)
(这里是面试重点,一定要会说)
16. 线程创建方式?
回答:主要有Thread、Runnable和Callable三种方式,其中Callable支持返回值,实际开发中更推荐使用线程池统一管理线程。
17. synchronized和Lock区别?
回答:synchronized是内置锁,使用简单;Lock更灵活,支持可中断、公平锁等高级功能。
18. volatile作用?
回答:保证变量可见性并禁止指令重排,但不保证原子性。
19. CAS是什么?
回答:CAS是一种无锁并发机制,通过比较并交换实现原子操作,性能高但存在ABA问题。
20. 线程池执行流程?
回答:任务提交后先创建核心线程执行,核心线程满后进入队列,队列满后创建非核心线程,超过最大线程数则执行拒绝策略。
21. 拒绝策略有哪些?
回答:包括抛异常、调用者执行、丢弃任务、丢弃最旧任务,常用CallerRuns削峰。
22. sleep vs wait?
回答:sleep不会释放锁,wait会释放锁并进入等待状态。
23. notify vs notifyAll?
回答:notify唤醒一个线程,notifyAll唤醒全部线程,推荐使用notifyAll避免线程饥饿。
24. 死锁条件?
回答:互斥、请求保持、不剥夺、循环等待。
25. 如何避免死锁?
回答:统一加锁顺序、减少锁粒度、使用超时机制等。
26. 什么是线程安全?
回答:多线程下程序结果正确,不受调度影响。
27. 并发三大特性?
回答:原子性、可见性、有序性。
28. ThreadLocal原理?
回答:为每个线程提供独立变量副本,实现线程隔离。
29. ThreadLocal内存泄漏?
回答:key是弱引用,value未清理会导致泄漏,因此需要手动remove。
30. CountDownLatch vs CyclicBarrier?
回答:前者一次性,后者可复用。
31. Semaphore?
回答:用于控制并发访问数量,实现限流。
32. 乐观锁 vs 悲观锁?
回答:悲观锁加锁保证安全,乐观锁通过CAS提高性能。
33. 自旋锁?
回答:循环尝试获取锁,不阻塞线程。
34. AQS?
回答:并发核心框架,通过队列实现锁机制。
35. ReentrantLock?
回答:支持可重入、公平锁、可中断等特性,比synchronized更灵活。
四、JVM(36~50)
(这里是"能拉开差距"的部分)
36. JVM内存结构?
回答:包括堆、栈、方法区、程序计数器等。
37. 堆 vs 栈?
回答:堆存对象,线程共享;栈存方法调用,线程私有。
38. 什么是GC?
回答:自动回收无用对象的机制。
39. 如何判断对象死亡?
回答:通过可达性分析。
40. GC算法?
回答:标记清除、复制、标记整理。
41. Minor GC vs Full GC?
回答:Minor GC快且频繁,Full GC慢且影响大。
42. 常见GC器?
回答:CMS、G1等,G1是主流。
43. G1特点?
回答:分Region管理,支持低停顿。
44. 类加载过程?
回答:加载→验证→准备→解析→初始化。
45. 双亲委派模型?
回答:优先父类加载器,防止篡改核心类。
46. JVM调优思路?
回答:分析GC日志,调整堆大小和回收策略。
47. OOM原因?
回答:内存不足或内存泄漏。
48. 泄漏 vs 溢出?
回答:泄漏是无法回收,溢出是内存不够。
49. 栈溢出?
回答:递归过深导致。
50. 对象创建过程?
回答:类加载→分配内存→初始化→构造方法。
五、Spring(51~59)
51. IOC原理?
回答:对象由容器管理,实现解耦。
52. 依赖注入方式?
回答:构造器、setter、字段注入,推荐构造器。
53. AOP原理?
回答:通过动态代理实现方法增强。
54. JDK代理 vs CGLIB?
回答:前者基于接口,后者基于继承。
55. 事务原理?
回答:基于AOP,在方法前后控制事务。
56. 事务失效?
回答:自调用、非public、异常被吞等。
57. Bean生命周期?
回答:实例化→初始化→销毁。
58. 循环依赖?
回答:通过三级缓存解决。
59. Spring线程安全吗?
回答:默认不保证,需要开发者控制。
六、MySQL + Redis(核心压轴)
60. 索引为什么用B+树?
回答:减少IO并支持范围查询。
61. 最左前缀原则?
回答:联合索引必须从左匹配。
62. 索引失效?
回答:like前缀%、函数、类型转换等。
63. 事务ACID?
回答:原子性、一致性、隔离性、持久性。
64. 隔离级别?
回答:读未提交→串行化。
65. Redis为什么快?
回答:内存+单线程+IO多路复用。
66. 缓存穿透?
回答:查不存在数据,用布隆过滤器解决。
67. 缓存击穿?
回答:热点key失效,加锁解决。
68. 缓存雪崩?
回答:大量key同时失效,加随机时间。
