Java面试题(带答案)

📅 2026/7/1 2:50:50
Java面试题(带答案)
一、Java 并发与集合1. ConcurrentHashMap 特性30 秒版JDK 1.7分段锁Segment锁粒度比 Hashtable 小JDK 1.8数组 链表/红黑树用 CAS synchronized 锁链表头节点支持高并发读写读基本无锁volatile CAS不允许 null key/valuesize()等统计用 LongAdder 思想近似或分段统计扩容时多线程协助迁移追问 1.7 和 1.8 区别为什么不用 Segment 了和 HashMap 线程安全对比2. HashMap 底层30 秒版JDK 1.8数组 链表 红黑树默认容量 16负载因子 0.75超过阈值扩容 2 倍链表长度 ≥ 8 且数组 ≥ 64 转红黑树≤ 6 退化为链表通过(n-1) hash定位桶非线程安全1.7 头插可能死循环1.8 尾插3. 线程创建方式方式说明继承Thread不推荐单继承限制实现Runnable推荐实现CallableFutureTask有返回值线程池ExecutorService生产推荐CompletableFuture异步编排ForkJoinPool分治并行4. Java 线程池创建方式// 推荐显式 ThreadPoolExecutor new ThreadPoolExecutor( corePoolSize, // 核心线程数 maximumPoolSize, // 最大线程数 keepAliveTime, // 非核心线程空闲存活时间 unit, workQueue, // 任务队列 threadFactory, rejectedHandler // 拒绝策略 );7 个参数含义corePoolSize常驻核心线程数maximumPoolSize最大线程数keepAliveTime非核心线程空闲多久销毁unit时间单位workQueue阻塞队列ArrayBlockingQueue、LinkedBlockingQueue、SynchronousQueue、DelayQueuethreadFactory线程命名、优先级rejectedHandler队列满且线程满时策略Abort、CallerRuns、Discard、DiscardOldest执行流程任务 → 核心线程未满→ 创建核心线程→ 队列未满→ 入队→ 线程数 max→ 创建非核心线程→ 执行拒绝策略生产建议 不用Executors.newFixedThreadPool无界队列 OOM 风险5. synchronized 底层原理字节码monitorenter/monitorexit锁对象关联 Monitor管程存在对象头 Mark Word锁升级无锁 → 偏向锁 → 轻量级锁 → 重量级锁重量级锁依赖 OS Mutex涉及用户态/内核态切换wait/notify依赖 Monitor6. ReentrantLock vs synchronized对比synchronizedReentrantLock层面JVM 关键字APIJUC释放锁自动必须unlock()可中断否lockInterruptibly()公平锁非公平可选公平/非公平条件变量单个 wait/notify多个Condition底层MonitorAQS相同 可重入、互斥二、JVM7. JMMJava 内存模型你说的“主副内存”就是主内存 工作内存线程1工作内存 ←→ 主内存 ←→ 线程2工作内存主内存共享变量实际存储堆工作内存线程私有缓存存变量副本线程对变量操作在工作内存写回主内存才可见三大特性特性含义原子性不可分割synchronized、CAS可见性修改对其他线程可见volatile、synchronized有序性禁止指令重排volatile、happens-beforehappens-before 规则 程序次序、锁、volatile、线程 start/join 等8. 垃圾回收算法算法说明标记-清除标记存活对象清除其余有碎片标记-复制分两块存活复制到另一块适合新生代标记-整理存活对象向一端移动适合老年代分代收集新生代复制老年代标记整理/清除如何判断死亡 引用计数Java 不用、可达性分析GC Roots9. 垃圾回收器CMS、G1回收器区域特点Serial新生代单线程ParNew新生代多线程版 SerialParallel Scavenge新生代吞吐量优先CMS老年代并发标记清除低停顿有碎片已逐步淘汰G1全堆分区Region可预测停顿JDK 9 默认ZGC / Shenandoah全堆超低延迟CMS 流程 初始标记(STW) → 并发标记 → 重新标记(STW) → 并发清除缺点 碎片、浮动垃圾、Concurrent Mode Failure 退化为 Full GCG1 亮点 按 Region 回收优先回收垃圾多的区Mixed GC10. JVM 类加载机制过程 加载 → 验证 → 准备 → 解析 → 初始化双亲委派自定义加载器 → 应用类加载器 → 扩展类加载器 → 启动类加载器(Bootstrap)先让父加载器加载保证核心类不被篡改打破双亲委派SPIJDBC、Tomcat、热部署11. 深拷贝 vs 浅拷贝浅拷贝深拷贝基本类型复制值复制值引用类型复制引用共享对象递归复制新对象实现clone()默认浅拷贝序列化、手动递归、工具类// 浅拷贝Object clone obj.clone();// 深拷贝常用序列化ByteArrayOutputStream bos new ByteArrayOutputStream();ObjectOutputStream oos new ObjectOutputStream(bos);oos.writeObject(obj);ObjectInputStream ois new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray()));Object deep ois.readObject();12. 创建实例的方式new关键字反射Class.newInstance()/Constructor.newInstance()clone()反序列化工厂方法 / 建造者模式Objenesis 等绕过构造器前端 JSON 反序列化Jackson/Fastjson本质也是反射构造三、Java IO13. Java IO 模型模型说明BIO阻塞 IO一连接一线程NIO非阻塞 Channel Buffer Selector多路复用AIO异步 IO回调Linux 下 aio 支持有限NIO 核心Selector.select()监听多 Channel 事件单线程处理多连接Netty 基于 NIO 的高性能网络框架面试常一起说四、Spring14. IOC 理解控制反转对象创建和依赖交给容器不由new依赖注入 DIAutowired、Resource注入依赖流程扫描 Bean → 解析 BeanDefinition → 实例化 → 属性注入 → 初始化 → 放入容器单例 Bean 默认缓存在一级缓存15. AOP 理解横切关注点日志、事务、权限基于 动态代理有接口用 JDK 代理无接口用 CGLIB核心切点 Pointcut、通知 Advice、切面 Aspect16. Spring 设计模式至少 8 个模式应用单例Bean 默认单例工厂BeanFactory、FactoryBean代理AOP JDK/CGLIB模板方法JdbcTemplate、RestTemplate观察者ApplicationEvent适配器HandlerAdapter装饰器BeanWrapper策略Resource 加载策略责任链Filter、Interceptor 链手写单例双重检查锁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; } }简单工厂public class PayFactory { public static PayService create(String type) { return switch (type) { case wx - new WxPayService(); case ali - new AliPayService(); default - throw new IllegalArgumentException(); }; } }17. Spring Boot 自动装配流程SpringBootApplicationConfigurationEnableAutoConfigurationComponentScanEnableAutoConfiguration导入AutoConfigurationImportSelector读取META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports2.7或spring.factories老版本按ConditionalOnXxx条件决定是否生效如OnClass、OnProperty自动配置类注册 Bean 到容器例子 引入spring-boot-starter-data-redis自动配RedisTemplate18. Spring Scope 作用域Scope说明singleton默认容器内唯一prototype每次获取新建request每个 HTTP 请求一个session每个 Session 一个applicationServletContext 级别19. Spring 循环依赖仅单例 属性注入可解决三级缓存一级 singletonObjects 成品 Bean二级 earlySingletonObjects 早期暴露 Bean三级 singletonFactories ObjectFactory用于 AOP 代理流程A 创建 → 放三级 → 注入 B → B 创建 → 从三级拿 A 早期引用 → B 完成 → A 完成不能解决 构造器循环依赖、prototype 循环依赖20. Spring 事务八股基于 AOP 代理Transactional在方法前后开启/提交/回滚传播行为 REQUIRED、REQUIRES_NEW、NESTED 等隔离级别 默认 DB 默认可指定回滚 默认 RuntimeExceptionrollbackForException.class失效场景非 public 方法同类自调用不走代理异常被 catch 吞掉抛出 Checked Exception 默认不回滚Bean 未被 Spring 管理数据库引擎不支持MyISAM五、网络21. TCP 三次握手客户端 → SYN → 服务端客户端 ← SYNACK ← 服务端客户端 → ACK → 服务端为什么三次 确认双方收发能力防止历史连接请求22. TCP 四次挥手客户端 → FIN → 服务端客户端 ← ACK ← 服务端客户端 ← FIN ← 服务端客户端 → ACK → 服务端等待 2MSL为什么四次 FIN 和 ACK 分开发服务端可能还有数据要发六、MySQL23. InnoDB 数据结构 / B 树InnoDB 索引用 B 树非叶子节点只存索引键 指针不存数据叶子节点存完整数据聚簇索引或主键二级索引叶子节点双向链表适合 范围查询树高低通常 3~4 层存千万级IO 少对比 B 树 B 树叶子链表、非叶子不存数据更适合磁盘页读取24. MySQL 隔离级别级别脏读不可重复读幻读READ UNCOMMITTED✓✓✓READ COMMITTED✗✓✓REPEATABLE READInnoDB 默认✗✗基本解决*SERIALIZABLE✗✗✗*InnoDB RR 通过 MVCC 间隙锁/next-key lock 很大程度避免幻读MVCC 隐藏列trx_id、roll_pointerRead View 判断可见性25. MyBatis 分页方式说明LIMIT手动LIMIT offset, sizeRowBounds内存分页假分页PageHelper拦截器自动改 SQL 加 LIMIT最常用物理分页推荐数据库层 LIMITPageHelper.startPage(1, 10); ListUser list userMapper.selectAll(); PageInfoUser page new PageInfo(list);七、Redis26. Redis 基本数据结构类型底层实现场景StringSDS缓存、计数、分布式锁Hash哈希表/压缩列表对象属性List双向链表/压缩列表/quicklist队列、时间线Set哈希表/整数集合去重、标签ZSet跳表 哈希表排行榜BitmapString 扩展签到、布隆HyperLogLog基数统计UVStream日志型消息队列27. Redis String 实现 vs Java StringRedis SDSJava String结构lenallocbuf[]char[]/byte[]JDK 9长度O(1) 获取O(n) 或已缓存二进制可存任意字节文本为主扩容预分配减少重分配不可变修改产生新对象线程安全单线程模型无需锁不可变故线程安全28. Redis 为什么快纯内存操作高效数据结构SDS、跳表等单线程模型6.0 多线程处理 IO无锁竞争IO 多路复用epoll简单协议 RESP减少开销合理 持久化策略RDB/AOF 异步/子进程你答的虚拟内存机制Redis 4.0 后主要用内存老版本 VM 已废弃可提 内存淘汰策略 代替29. 分布式锁SETNX 看门狗基础SET lock_key unique_value NX EX 30NX不存在才设置EX 30过期防死锁unique_value防误删别人锁Lua 脚本校验后 DEL看门狗Redisson获取锁后启动定时任务每隔lockWatchdogTimeout/3续期业务未完成自动延长过期时间释放锁时取消续期注意 主从切换可能丢锁 → 红锁争议大或 Redisson 足够 TTL 业务幂等30. 缓存穿透 / 雪崩问题原因解决穿透查不存在的数据绕过缓存打 DB布隆过滤器、缓存空值短 TTL、参数校验击穿热点 key 过期瞬间大量请求打 DB互斥锁、逻辑过期、热点永不过期雪崩大量 key 同时过期或 Redis 宕机过期时间加随机、多级缓存、集群高可用、限流降级31. Redis 与数据库同步策略说明Cache Aside常用读先缓存后 DB写先更新 DB 再删缓存延迟双删删缓存 → 更新 DB → 延迟再删先更新 DB 再删缓存推荐配合消息重试Canal/CDC监听 binlog 异步更新缓存设置 TTL最终一致兜底原则 强一致难接受 最终一致写操作以 DB 为准八、消息队列32. Kafka 集群模式 / 主从同步Kafka 不用传统主从靠 Partition ReplicaTopic: orderPartition-0: Leader(Broker1) Follower(Broker2, Broker3)Partition-1: Leader(Broker2) Follower(Broker1, Broker3)Leader 处理读写Follower 同步ISRIn-Sync Replicas与 Leader 差距在阈值内的副本acks0/1/all生产者可靠性HW/LEO高水位保证消费可见性口述你做过主从同步Kafka 通过 Partition 副本 ISR 机制保证高可用acksall等 ISR 确认min.insync.replicas控制最少同步副本Leader 挂了 Controller 从 ISR 选举新 Leader。其他集群模式RabbitMQ镜像队列、普通集群RocketMQMaster-Slave、DLedger 多副本33. MQ 如何保证消息顺序消费前提 顺序只在 同一分区/队列 内保证Kafka同一业务 keyhash(key) % partition发到同一分区消费者单线程或 内存队列按 key 串行RocketMQMessageQueueSelector选同一队列消费端加 分布式锁 或单线程消费该队列注意 重试、失败会乱序 → 业务层幂等 版本号九、加密算法类型算法用途对称AES、DES、3DES大量数据加密非对称RSA、ECC密钥交换、数字签名摘要MD5、SHA-256、SHA-512完整性校验MD5 不安全国密SM2、SM3、SM4国内合规应用 HTTPSRSA/ECDHE AES、密码存储BCrypt/Argon2 加盐哈希不用 MD5十、速查总表题号关键词ConcurrentHashMapCAS synchronized1.8 无 SegmentIO 模型BIO/NIO/AIOSelector 多路复用JMM主内存/工作内存可见性/有序性/原子性CMS/G1CMS 并发标记清除G1 Region 分区类加载双亲委派加载→验证→准备→解析→初始化synchronizedMonitor锁升级ReentrantLockAQS可中断、公平、多 Condition线程池7 参数核心→队列→最大→拒绝Spring 事务AOP失效自调用、非 public、吞异常TCP三次握手/四次挥手B 树叶子链表范围查询InnoDB 默认隔离级别RC/RR/MVCC/间隙锁KafkaPartition ISR Leader 选举分布式锁SET NX EX Lua 看门狗穿透/雪崩布隆/空值/随机 TTL/集群设计模式单例、工厂、代理等 8循环依赖三级缓存仅单例属性注入深/浅拷贝clone 浅序列化深自动装配EnableAutoConfiguration 条件注解Redis 同步Cache Aside先更 DB 再删缓存