标签题目
Java相关面试题
Java 的 GC 机制是怎样实现的?
这题考察对象存活判定、分代回收、GC 算法和收集器取舍,还会延伸到分配晋升、停顿和 GC 日志排查。
10G IP 文件、1G 内存,如何找出现最多的 Top10 IP?
这题考察海量数据精确 TopK 的分治思路、内存估算、全局正确性和数据倾斜处理。
线程安全的单例模式怎么写?
这题考察 Java 单例在并发下的安全发布、延迟初始化、重排序风险,以及枚举、静态内部类、DCL 各自的边界。
同题还出现在 1 个公司岗位
多线程如何防止并发问题?
这题考并发安全的系统化处理,回答要先减少共享,再对必须共享的状态保证原子性、可见性和有序性。
JVM 堆和栈的原理与区别是什么?
考察 JVM 运行时内存模型,核心是区分堆对象生命周期、线程私有栈帧、引用关系、异常类型和 JIT 优化边界。
HashMap 和 ConcurrentHashMap 的原理与区别是什么?
考察 Java 哈希表结构和并发容器实现,重点是桶结构、扩容、线程安全策略、弱一致迭代和 null 限制。
同题还出现在 1 个公司岗位
volatile 的原理是什么,能否替代锁?
考察 Java 内存模型,核心是 volatile 保证可见性和有序性,但不保证复合操作原子性,不能替代锁保护临界区。
Full GC 的触发原因和主动触发方式有哪些?
考察 JVM 内存压力和 GC 诊断能力,重点是触发原因、显式 GC 风险、不同收集器差异以及如何从日志定位根因。
C++ 和 Java 的主要区别是什么?
考察语言对比是否能上升到运行时、内存资源、类型模型、性能控制、工程生态和适用场景,而不是停留在语法差异。
Java 双亲委派机制是什么,目的是什么?
双亲委派机制是 Java 类加载器的一种委派模型:一个类加载请求先交给父加载器尝试加载,父加载器加载不了时,子加载器才自己加载。它的目的主要是保证核心类库安全、避免类重复加载,并维持类身份的一致性。
Java 常见集合有哪些,各自适合什么场景?
Java 常见集合可以按接口体系理解:List 适合有序可重复数据,Set 适合去重,Map 适合键值映射,Queue 和 Deque 适合队列、栈和任务调度。回答时要结合底层结构、复杂度、是否有序、是否线程安全和典型场景。
自定义对象的 hashCode 应该如何计算?
自定义对象的 hashCode 应该基于 equals 使用的关键字段来计算,核心目标是满足“相等对象必须有相同哈希值”,同时尽量让不同对象分布均匀、计算稳定,并避免使用会频繁变化的字段。
为什么 equals 和 hashCode 要保持一致?
equals 和 hashCode 必须保持一致,是因为哈希容器依赖 hashCode 定位桶,再依赖 equals 判断对象是否相等。如果两个相等对象的 hashCode 不同,它们会被放到不同查找路径上,导致重复存储、查找失败和删除失败。
Java Object 类有哪些常见方法?
Java Object 类是所有类的根类,常见方法可以分为对象身份相关、运行时类型相关、字符串表示、克隆、线程协作和对象生命周期几类。面试回答要说明方法用途,也要点出 equals/hashCode、wait/notify、clone、finalize 的关键边界。
HashMap 为什么会引入红黑树?
HashMap 引入红黑树,是为了解决哈希冲突严重时链表过长导致查询退化的问题。当同一个桶中的节点数量过多,链表查找会从平均常数级退化为线性级,红黑树可以把桶内查找复杂度降低到对数级,提升极端场景下的稳定性。
ReentrantLock 如何基于 AQS 实现可重入锁?
ReentrantLock 的核心不是自己从零管理阻塞队列,而是把获取锁、释放锁、排队、唤醒、可中断等待、条件队列等通用同步能力交给 AQS。它用 AQS 的 state 表示重入次数,用独占线程记录锁持有者,通过公平或非公平策略决定是否允许新线程插队。
AQS 是什么?
AQS 是 Java 并发包中的基础同步框架,用一个 volatile state 表示同步状态,用一个 FIFO 等待队列管理竞争失败的线程,并通过模板方法把通用排队唤醒流程和具体同步语义分离。
Java 线程池有哪些核心参数?
Java 线程池的核心参数来自 ThreadPoolExecutor:corePoolSize、maximumPoolSize、keepAliveTime、unit、workQueue、threadFactory、RejectedExecutionHandler。真正要掌握的是它们如何共同决定线程创建、任务排队、扩容、回收和拒绝策略。
synchronized 和 ReentrantLock 有什么区别?
synchronized 是 JVM 层面的内置锁,语法简单,自动加锁释放;ReentrantLock 是 JUC 提供的显式锁,基于 AQS,功能更丰富。两者都可重入,都能保证互斥和可见性,但在使用方式、等待能力、公平性、条件队列和可中断性上差异明显。
Java 有哪些常见加锁机制?
Java 常见加锁机制包括 synchronized、ReentrantLock、ReadWriteLock、StampedLock、原子类和基于 AQS 的同步器。面试重点不是罗列名称,而是说明它们的互斥语义、可重入性、公平性、可中断、条件等待、读写并发和适用场景。
Java 内部类为什么可以访问外部类成员?
Java 内部类能访问外部类成员,本质上不是虚拟机给了它特殊权限,而是编译器在字节码层建立了外部实例引用和访问通道。非静态内部类会携带指向外部对象的隐藏引用,因此能通过这个引用读取外部对象的字段和方法;对私有成员的访问则由同一 nest 的访问规则或编译期生成的桥接访问方法支持。
ConcurrentHashMap 的实现原理是什么?
ConcurrentHashMap 的核心是把哈希表操作拆成可并发执行的小粒度步骤:读操作大多依赖 volatile 可见性和链表或树查找,无需整体加锁;写操作在空桶上用 CAS 放入节点,在冲突桶上锁住桶头节点;扩容时通过 ForwardingNode 和协助迁移让多个线程共同搬迁数据。
Java 程序从编译到运行经历了哪些过程?
Java 程序从编译到运行通常经历源码编译、字节码生成、类加载、链接、初始化和执行几个阶段。执行阶段由 JVM 解释执行和 JIT 编译共同完成,并由运行时系统负责内存管理、线程调度和异常处理。
Java 为什么可以跨平台?
Java 能跨平台的核心原因是源码先编译成平台无关的字节码,再由不同操作系统和 CPU 上的 JVM 负责解释、编译和调用本地能力。跨平台成立的前提是运行环境、依赖和本地资源使用也保持兼容。
netty有哪些组件?
Netty 的组件可以按启动配置、连接抽象、线程模型、事件流转、数据缓冲、编解码、业务处理、异步通知来理解。回答时不应只罗列类名,而要把 ServerBootstrap 启动服务端、EventLoopGroup 分配线程、Channel 承载连接、Pipeline 串联 Handler、ByteBuf 承载数据、Future 返回异步结果这条链路讲清楚。
常见 JVM 垃圾收集器分别适合什么场景?
垃圾回收器适用场景不能只背名称,而要围绕吞吐量、停顿时间、堆大小、对象生命周期、CPU 余量和运行时版本来选择。Serial 适合小堆和低资源环境,Parallel 适合吞吐优先任务,CMS 是旧版本低停顿方案但有碎片和并发失败风险,G1 是较新主流服务端的平衡型选择,ZGC 与 Shenandoah 面向更严苛的低停顿和大堆场景,Epsilon 只适合测试、压测和短生命周期实验。
说一下TreeMap的实现原理?
TreeMap 是 Java 中基于红黑树实现的有序 Map。它按照 key 的比较规则维护全局排序,核心操作通常是 O(log n),适合按 key 有序遍历、范围查询、前驱后继、最大最小 key 等场景。
JVM 线程栈大小参数 -Xss 如何设置?
这道题考察的是 JVM 运行时栈内存模型和线程栈参数。核心结论:每个 Java 线程都有独立的 Java 虚拟机栈,方法调用会不断压入栈帧;递归过深或调用链过深通常会触发 StackOverflowError;线程创建过多、每个线程栈过大或系统/容器可用内存不足时,可能触发 OutOfMemoryError: unable to create new native thread。JVM 中常用 -Xss 设置单个线程的栈大小。
常见的cpu load过高,us过高,一般是什么问题?
CPU load 高和 CPU 使用率高不是同一个概念。load average 统计可运行队列和不可中断 I/O 任务,us 高表示用户态代码消耗大量 CPU。排查要先看 us、sy、wa、si、st 的结构,再定位到进程、线程和调用栈。
ArrayList 是怎么扩容的?
ArrayList 的扩容本质是底层 Object[] 容量不足时创建更大的数组并复制旧元素。常见 OpenJDK 实现中,空参构造会延迟分配默认容量,首次添加时通常扩到 10;后续容量不够时按约 1.5 倍增长。面试回答要同时讲清 add 触发路径、复制成本、均摊复杂度、极限容量和与数组、LinkedList 的差异。
HashMap过程讲一下?
HashMap 的核心是“数组定位桶,桶内解决冲突”。JDK 8 及以后主流实现是 Node 数组加链表加红黑树:先用 hash 扰动把 key 的 hashCode 高位混入低位,再用数组长度减一与 hash 做位与定位桶;put 在桶为空时直接插入,桶非空时按 hash 和 equals 查找同 key,存在则覆盖值,不存在则挂到链表或树中;get 走同样的定位和匹配过程。扩容由容量、负载因子和阈值控制,默认负载因子 0.75,超过阈值后容量通常翻倍。单桶冲突达到树化阈值且数组容量足够时会转红黑树,节点减少到退化阈值附近会退回链表。HashMap 不保证顺序,也不是线程安全容器。
AQS 的核心原理是什么?
AQS 是 Java 并发包中很多同步器的基础框架,它用一个 volatile 的 state 表示同步状态,用 CAS 保证状态修改的原子性,并通过一个变体 CLH 双向等待队列管理竞争失败的线程。面试回答时要把它讲成“状态管理 + 队列排队 + 阻塞唤醒 + 模板方法扩展”的组合,而不是只背 ReentrantLock 底层用了 AQS。
保证Map线程安全?
Map 本身只是键值存储抽象,是否线程安全取决于具体实现和访问方式。普通 HashMap 在并发读写下不安全,可能出现数据丢失、结构破坏、读到不一致状态等问题。保证线程安全通常有几类方案:用外部锁保护所有访问、使用 Collections.synchronizedMap 包装、使用 ConcurrentHashMap、在读多写少场景使用不可变快照或 CopyOnWrite 思路。实际回答时要结合读写比例、是否需要复合操作原子性、是否需要强一致迭代、性能和内存成本来选型。
JVM 堆内存通常如何分区?
JVM 堆可以从两条线理解:按对象生命周期分为年轻代和老年代,年轻代内部又分 Eden 和两个 Survivor;按具体垃圾收集器实现,传统分代收集器更强调连续代空间,G1、ZGC、Shenandoah 等更强调 region 或分区化管理。回答时要特别说明:元空间和线程栈不属于堆,TLAB 是 Eden 中给线程预分配的私有分配缓冲区,大对象可能直接进入老年代或被特殊 region 管理。
过去经历中怎么应对高并发或高性能场景的?
高并发或高性能场景不是考单点技术名词,而是考候选人能否把真实工程问题讲成闭环:先明确业务目标和容量指标,再通过压测和可观测性找到瓶颈,随后从流量、应用、缓存、队列、数据库、线程池、连接池、锁竞争、水平扩展和稳定性预案等层面治理,最后用结果指标证明方案有效。
Spring 事务失效有哪些常见场景?
Spring 事务失效不要只背 @Transactional 场景清单,核心要答出声明式事务的运行条件:方法调用必须进入 Spring AOP 代理,由 TransactionInterceptor 配合 TransactionManager 在调用前后开启、提交或回滚事务;常见失效本质上分为三类:没有经过代理、异常没有触发回滚、真实数据库资源没有加入同一个事务。
ConcurrentHashMap为什么性能比较好?
ConcurrentHashMap 性能好,本质上不是因为完全没有锁,而是把锁的范围、锁的频率和锁竞争都压到了更低水平。它通过读操作无锁、写操作尽量 CAS、冲突时只锁单个桶、扩容时多线程协作迁移、计数时分散热点等方式,避免了 Hashtable 或直接给 HashMap 加 synchronized 那种全表串行化的瓶颈。回答时要区分 JDK7 的 Segment 分段锁模型和 JDK8 的 Node 数组加 CAS、synchronized 桶级锁模型。
Java 动态代理的实现原理是什么?
Java 动态代理本质上是在运行期生成一个实现目标接口的代理类,把接口方法调用统一转发给 InvocationHandler。面试回答不能只说“反射”或“运行期生成对象”,还要讲清 JDK 动态代理的接口约束、Proxy 生成代理类、方法调用链、Spring AOP 的代理选择,以及 final、private、自调用等失效边界。
Java三大特性 多态是怎么实现的?
Java 三大特性是封装、继承和多态。高质量回答不能只背三个词,而要说明它们分别解决对象状态保护、类型复用扩展、抽象行为分派的问题。多态的实现重点在方法重写、向上转型和动态绑定:编译期确认引用类型上是否存在可调用方法,运行期根据对象真实类型分派到具体实现。
HashMap 的底层实现原理是什么?
HashMap 的核心是用哈希表存储键值对,通过 key 的 hash 值定位数组桶,再在桶内处理哈希冲突。JDK 1.7 主要是数组加链表,链表采用头插法,扩容迁移时在并发场景下可能形成链表环;JDK 1.8 改为数组、链表、红黑树组合,链表采用尾插法,并在冲突严重时树化,把极端情况下的查找从线性复杂度优化到对数复杂度。
了解哪些不同 JDK 版本的新特性?
这道题考察的不是背版本号,而是能否把 JDK 演进和工程实践联系起来。回答时应先按主线概括:JDK 8 是现代 Java 的分水岭,引入 Lambda、Stream、Optional、默认方法和新的日期时间 API;JDK 9 到 10 开始模块化、集合工厂方法、JShell、接口私有方法和局部变量类型推断;JDK 11 作为常用长期支持版本,补齐 HTTP Client、字符串和文件 API、ZGC 初步可用等能力;JDK 17 是当前大量生产系统升级的关键长期支持版本,带来 sealed class、record、switch 表达式、文本块、模式匹配等语言能力,并强化 JVM、GC 和封装边界;JDK 21 进一步把虚拟线程、结构化并发、模式匹配 switch、record pattern、分代 ZGC 等特性推向成熟,重点提升高并发服务的线程模型和表达能力。
JAVA中的hashmap怎么实现的?
HashMap 的核心是用数组承载桶位,用链表或红黑树解决哈希冲突。回答这题时要把结构、hash 扰动、桶定位、put/get 流程、扩容机制、树化条件、equals 与 hashCode 契约,以及非线程安全风险串起来,重点说明为什么容量是 2 的幂、为什么扩容会重新分布元素,以及 JDK8 后为什么在冲突严重时引入红黑树。
JDK25 有些什么新特性?
JDK 25 的面试回答应先定位版本:它在 2025-09-16 GA,并且是多数发行版选择的 LTS 基线。然后要区分 final、preview、incubator、experimental 四类能力。生产升级重点看正式特性、运行时变化、诊断能力、安全 API 和兼容性变化,预览、孵化、实验能力更适合评估与提前适配。
HashMap 的扩容机制是什么?
HashMap 的扩容本质是当键值对数量超过 threshold 后创建更大的 table,并把旧桶中的节点迁移到新桶。JDK 8 利用容量始终为 2 的幂这一特性,通过 hash & oldCap 把同一桶内节点拆成低位组和高位组,避免重新完整寻址,也保持链表相对顺序。
Java 的多态是怎么实现的?
Java 多态的核心是:编译期看引用的静态类型决定能调用哪些成员、选择哪个方法签名;运行期看对象的实际类型决定执行哪个被重写的方法实现。它主要依赖方法重写、动态分派以及虚方法调用指令完成,字段、静态方法、私有方法和构造方法不按同样规则参与多态。
Java 类加载流程和双亲委派机制是什么?
这道题要回答清楚两层:第一是类从字节码进入 JVM 到可执行状态的生命周期,通常按加载、验证、准备、解析、初始化来讲,其中验证、准备、解析属于链接阶段;第二是类加载器如何查找类,也就是双亲委派模型。面试中不能只背阶段名称,还要说明每阶段做什么、初始化触发时机、类身份由类名和加载器共同决定,以及为什么工程框架有时会打破或绕开双亲委派。
java中重载和重写有什么区别,分别用什么关键字?
Java 中重载是同一个类或继承关系中方法名相同、参数列表不同,属于编译期静态分派;重写是子类重新实现父类或接口中可被覆盖的实例方法,属于运行期动态分派。二者都没有专门关键字,@Override 是注解不是关键字。
熟悉Java的哪些框架?
这类问题不是让候选人背框架名称,而是考察你是否真正理解 Java 后端技术栈如何支撑业务系统。高质量回答应该从“核心开发框架、Web 请求链路、数据访问、微服务治理、RPC 通信、异步消息、缓存与性能、项目落地经验”几个层次展开,体现你不仅会用 Spring Boot 写接口,也理解框架背后的设计思想、运行机制、适用边界和工程实践。