文章提供了JVM面试常见题目及详尽答案,系统阐述了JVM内存结构(程序计数器、虚拟机栈、本地栈、堆、方法区、直接内存)、GC Roots 类型、四种引用(强、软、弱、虚)以及分代收集假设。进一步介绍了垃圾回收算法(标记清除、复制、标记整理)、STW 与安全点、OopMap 的作用,并概括了主流收集器(Serial、ParNew、Parallel Scavenge、Serial Old、Parallel Old、CMS)的特点和适用场景。

文章围绕面试常见技术点展开,先示例如何从项目经验、设计优化和代码亮点切入;随后系统阐述零拷贝的概念、实现方式及其对上下文切换和拷贝次数的削减;归纳五种IO模型,比较NIO与多路复用(select、poll、epoll)的区别与优势;解析FutureTask阻塞获取结果的内部状态机与等待机制;对比ReentrantLock与synchronized的实现原理及适用场景;并简要涉及乐观/悲观锁、AQS、Paxos、B+树、TCP拥塞、JVM调优、分库分表、分布式事务、RocketMQ可靠性等面试热点。整体提供了技术要点的概念解释与实现细节,帮助读者在面试中快速组织答案。

在多线程环境中,多个线程可能同时访问共享可变资源,必须通过同步机制实现对临界资源的互斥访问。Java 提供的 synchronized 基于对象的 Monitor 锁实现,采用 monitorenter/monitorexit 指令并在对象头的 Mark Word 中记录锁状态。JVM 对内置锁进行多层优化:偏向锁、轻量级锁、自旋锁、锁膨胀(向重量级锁升级)以及锁消除(通过逃逸分析)。对象头结构、压缩指针(Compressed Oops)以及 JOL 等工具帮助分析锁状态和内存布局。整体上,synchronized 通过加锁实现序列化访问,其底层实现与性能优化相互配合,以在保证线程安全的前提下尽量降低开销。

零拷贝是一种 I/O 优化技术,避免 CPU 在用户态与内核态之间复制数据,从而减少上下文切换和拷贝次数。传统 read‑write 流程需四次态切换、四次拷贝;而通过 mmap+write、sendfile 以及带 DMA scatter/gather 的 sendfile,可将拷贝次数降至 1‑2 次,后者实现全程 DMA 传输,真正的零拷贝。Java NIO 提供 MappedByteBuffer(基于 mmap)和 FileChannel 的 transferTo/transferFrom(封装 sendfile),是 Kafka、RocketMQ 等高性能系统的关键加速手段。

本文围绕幂等概念展开,先解释幂等在数学和计算机中的含义及其必要性,尤其在远程调用超时、重复消费、表单重复提交等场景中的风险。阐述处理超时的两种思路:查询下游状态或依赖幂等接口。随后指出实现幂等的关键是全局唯一标识(UUID、Snowflake 等),并提供八种常见实现方案:①先查后插+唯一键冲突;②直接插入捕获冲突;③基于状态机的更新判断;④使用独立防重表;⑤Token 令牌;⑥悲观锁;⑦乐观锁(版本号);⑧分布式锁(Redis/ZooKeeper)。最后列举 HTTP 方法的幂等性,说明 GET、HEAD、OPTIONS、DELETE、PUT 为幂等,而 POST 不具幂等性。整体强调幂等设计的流程、实现技巧及其在分布式系统中的重要性。

消息队列(MQ)是一种基于队列的消息中间件,常见实现有 RabbitMQ、RocketMQ、Kafka。它用于应用解耦、流量削峰、异步处理、消息通信和远程调用等场景。为防止消息丢失,需在生产者采用同步或事务发送、存储端实现同步刷盘和主从复制、消费者在业务成功后确认 ACK。顺序性通过同分区或同消费者串行消费实现,局部有序可兼顾吞吐。重复消费可通过唯一业务标识或 Redis 幂等校验避免。积压时应先排查业务 BUG,再优化消费逻辑、批量处理或水平扩容;必要时临时扩容分区并并行消费。技术选型对比:Kafka 吞吐最高、支持顺序和大规模持久化;RocketMQ 稳定、阿里出品;RabbitMQ 稳定性好但吞吐一般。高可用依赖集群复制、Leader‑Follower 选举。事务消息通过半事务、本地事务提交或回滚实现最终一致性。设计自研 MQ 时需考虑生产‑存储‑消费流程、RPC、持久化、消费模型、幂等、高可用、事务和水平扩展等核心要素。