尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

【Java面试】——Java 基础与并发编程

【Java面试】——Java 基础与并发编程
📅 发布时间:2026/7/26 6:51:30

以下是针对你整理的 Java 面试复习路线的详细补充,按原大纲结构逐一展开。由于内容量较大,本篇先完成第一部分Java 基础/JVM/JUC的完整补充。


一、Java 基础与并发编程(核心能力 20%)

1.1 JVM 内存模型

JVM 在执行 Java 程序时,将其管理的内存划分为5 个核心运行时数据区:

1.1.1 线程私有区域

(1)程序计数器(Program Counter Register)

  • 记录当前线程正在执行的字节码指令地址(行号)
  • 字节码解释器通过改变计数器值来选取下一条要执行的指令
  • 是实现线程上下文切换的关键——线程切换后能恢复到正确的执行位置
  • 唯一不会抛出 OOM 异常的内存区域

(2)Java 虚拟机栈(Java Virtual Machine Stack)

  • 为 Java 方法执行提供内存空间,每个方法执行时创建一个栈帧(Stack Frame)
  • 栈帧包含:局部变量表、操作数栈、动态链接、方法返回地址
  • 可通过-Xss参数设置栈大小(如-Xss1m)
  • OOM 场景:
    • StackOverflowError:线程请求栈深度超过允许最大深度(如无限递归)
    • OutOfMemoryError: unable to create native thread:无法为新线程分配栈内存

(3)本地方法栈(Native Method Stack)

  • 为 Native 方法执行提供服务,作用与虚拟机栈类似

1.1.2 线程共享区域

(4)堆内存(Heap)—— 垃圾回收的主要区域

采用分代模型,基于弱分代假说:

  • 绝大多数对象朝生夕灭(90%+ 对象存活时间极短)
  • 熬过越多次 GC 的对象越难被回收
区域占比核心职责
Eden 区80%新对象主要分配区域
Survivor 0 区10%存活对象"中转站"
Survivor 1 区10%存活对象"中转站"
老年代堆的 2/3存储生命周期长的对象

关键参数:

  • -XX:NewRatio:年轻代:老年代比例,默认 1:2
  • -XX:SurvivorRatio:Eden:Survivor 比例,默认 8:1:1

(5)元空间(Metaspace)—— JDK 8+ 替代永久代

  • 直接使用本地内存(Native Memory)而非 JVM 堆内存
  • 永久代被移除的原因:字符串常量池内存泄漏、方法区大小难以调优、HotSpot 与 JRockit 合并

1.1.3 堆内存工作机制

Young GC(Minor GC)执行流程:

  1. 新对象优先分配到 Eden 区
  2. Eden 区满时触发 Minor GC
  3. 标记 Eden 区和当前 From Survivor 区的存活对象
  4. 将存活对象复制到 To Survivor 区
  5. 清空 Eden 区和 From Survivor 区
  6. 交换 From 和 To Survivor 的角色(始终有一个 Survivor 区是空的)

对象晋升老年代的 4 种途径:

  1. 正常晋升:年龄达到MaxTenuringThreshold(默认 15)
  2. 动态年龄判定:Survivor 区中同龄对象总大小 > Survivor 一半时提前晋升
  3. 大对象直接进入:超过PretenureSizeThreshold设置值
  4. 空间分配担保失败:Minor GC 后 Survivor 区无法容纳所有存活对象

为什么 Young GC 很快?

  • 绝大多数对象在 Eden 区创建后快速死亡
  • 仅扫描 Eden 和单个 Survivor,不扫描老年代
  • 复制算法仅处理少量存活对象,效率高

1.1.4 常见 OOM 原因

OOM 类型原因排查方向
堆 OOM对象过多/内存泄漏jmap dump + MAT 分析
元空间 OOM类加载过多(动态代理、热部署)检查类加载器泄漏
栈 OOM线程过多检查线程池使用
直接内存 OOMNIO 使用不当检查 ByteBuffer 分配

1.1.5 Full GC 触发条件

  1. 老年代空间不足
  2. 元空间空间不足
  3. 调用System.gc()(建议但非强制)
  4. 晋升失败(Minor GC 后存活对象无法放入老年代)
  5. 大对象直接进入老年代导致空间不足

1.1.6 CMS Concurrent Mode Failure

  • 原因:老年代在 CMS 并发清理阶段被填满,无法等到下一次 GC
  • 本质:并发收集速度跟不上对象晋升速度
  • 解决方案:
    • 调大老年代大小或调小年轻代
    • 提高 CMS 触发阈值(-XX:CMSInitiatingOccupancyFraction)
    • 使用 G1 替代 CMS

1.1.7 G1 为什么能减少 STW

  • Region 化内存布局:将堆划分为多个大小相等的 Region,不再有固定的年轻代/老年代物理边界
  • 并发标记 + 增量回收:通过并发标记阶段和增量回收,避免全堆扫描
  • 可预测的停顿时间模型:用户可设定目标停顿时间,G1 根据历史数据智能选择回收 Region
  • 混合 GC:同时回收年轻代和部分老年代 Region,均衡回收效率

1.1.8 ZGC 为什么可以做到几毫秒

  • 染色指针(Colored Pointers):在指针中编码 GC 元数据,无需额外的标记位
  • 读屏障(Load Barrier):在对象访问时进行 GC 操作,实现并发移动
  • 并发整理:所有阶段(标记、整理、重定位)几乎都并发执行
  • Region 化:动态 Region 大小,支持 2MB 到 32TB 堆
  • NUMA 感知:优化多 CPU 架构下的内存访问

1.1.9 线上分析工具

工具用途
jmap生成堆转储(dump)、查看堆信息
jstack查看线程堆栈、定位死锁
jstat实时查看 GC 状态、类加载信息
jcmd综合诊断命令(JDK 7+)
jconsole可视化监控
jvisualvm性能分析、堆 dump 分析
Arthas阿里开源在线诊断工具,可在线查看方法调用、热更新
MATEclipse 堆转储分析工具,内存泄漏分析
GC 日志-Xloggc:开启,分析 GC 频率和停顿

1.2 Java 并发编程

1.2.1 AQS(AbstractQueuedSynchronizer)

核心思想:CLH 双向队列 + CAS 改 state

  • state:同步状态(int),通过 CAS 修改
  • CLH 队列:FIFO 双向链表,管理等待线程
  • 独占模式:只有一个线程能获取(如 ReentrantLock)
  • 共享模式:多个线程可同时获取(如 Semaphore、CountDownLatch)

基于 AQS 实现的同步器:

  • ReentrantLock
  • Semaphore
  • CountDownLatch
  • CyclicBarrier
  • ReentrantReadWriteLock
  • FutureTask

1.2.2 ReentrantLock

核心特性:

  • 可重入锁:state表示重入次数(0 表示未被占用)
  • 支持公平锁(new ReentrantLock(true))和非公平锁(默认)
  • 公平锁:按队列顺序获取;非公平锁:允许插队(性能更好)

与 synchronized 对比:

特性synchronizedReentrantLock
实现层面JVM 内置(C++)JDK 层面(Java + AQS)
释放方式自动释放手动unlock()
中断支持不可中断lockInterruptibly()可中断
超时获取不支持tryLock(timeout)支持
条件变量wait/notifyCondition多条件
性能相近相近

1.2.3 CAS(Compare And Swap)

核心原理:

  • 硬件级别原子操作,通过 CPU 指令CMPXCHG实现
  • 三个参数:内存地址 V、期望值 A、新值 B
  • 当 V 值 == A 时,将 V 更新为 B;否则失败

ABA 问题:

  • 现象:V 值从 A → B → A,CAS 误认为未变化
  • 解决方案:
    • AtomicStampedReference:带版本号(stamp)的原子引用
    • AtomicMarkableReference:带标记位(mark)的原子引用

Unsafe 类:

  • 提供底层 CAS 操作(compareAndSwapInt、compareAndSwapObject等)
  • 可直接操作内存(allocateMemory、putInt等)
  • 禁止直接使用(JDK 9+ 限制访问)

1.2.4 Volatile

两个语义:

  1. 可见性:写操作立即刷新到主内存,读操作从主内存读取
  2. 禁止指令重排序:内存屏障(LoadLoad、StoreStore、LoadStore、StoreLoad)

适用场景:

  • 状态标志位(volatile boolean running)
  • 单次读/写操作(非复合操作,如count++不适用)

1.2.5 Atomic 包

类说明
AtomicInteger原子 int
AtomicLong原子 long
AtomicBoolean原子 boolean
AtomicReference原子引用
AtomicIntegerArray原子 int 数组
AtomicStampedReference带版本号引用(解决 ABA)
AtomicMarkableReference带标记引用

1.2.6 LongAdder vs AtomicLong

  • AtomicLong:CAS 自旋,高并发下冲突严重,性能下降
  • LongAdder:分段累加(Cell 数组),各线程操作不同 Cell,最后 sum 汇总
  • 适用场景:LongAdder 适合写多读少,AtomicLong 适合读多写少

1.2.7 ThreadPoolExecutor

核心参数:

  1. corePoolSize:核心线程数
  2. maximumPoolSize:最大线程数
  3. keepAliveTime:空闲线程存活时间
  4. unit:时间单位
  5. workQueue:任务队列(ArrayBlockingQueue、LinkedBlockingQueue、SynchronousQueue)
  6. threadFactory:线程工厂
  7. handler:拒绝策略

拒绝策略:

  • AbortPolicy(默认):抛出 RejectedExecutionException
  • CallerRunsPolicy:调用者线程执行
  • DiscardPolicy:丢弃不抛异常
  • DiscardOldestPolicy:丢弃队列头部任务

线程池满的原因与排查:

  • 核心线程数过小
  • 任务队列过小或过大
  • 任务执行时间过长
  • 线程阻塞(IO、锁等待)

1.2.8 ForkJoinPool

  • 分治思想:大任务拆分为小任务,并行执行后合并结果
  • 工作窃取(Work-Stealing):空闲线程从其他队列尾部窃取任务
  • 适用场景:递归任务、大数组并行计算

1.2.9 CompletableFuture

核心方法:

  • supplyAsync/runAsync:异步执行
  • thenApply/thenAccept/thenRun:串行依赖
  • thenCombine/thenCompose:组合依赖
  • allOf/anyOf:多任务聚合
  • complete/completeExceptionally:手动完成

异步编排最佳实践:

  • 使用自定义线程池,避免共用ForkJoinPool.commonPool()
  • 合理设置超时(completeOnTimeout/orTimeout)

1.2.10 StampedLock

  • 优化 ReentrantReadWriteLock:乐观读锁不阻塞写操作
  • 三种锁模式:
    • writeLock:写锁
    • readLock:读锁(悲观)
    • tryOptimisticRead:乐观读(不阻塞写,需验证 stamp)

1.2.11 CountDownLatch vs CyclicBarrier vs Semaphore vs Phaser

同步器核心机制可重用典型场景
CountDownLatch计数器递减至 0 释放❌等待多个任务完成
CyclicBarrier等待所有线程到达屏障点✅多线程分段执行
Semaphore许可证控制并发数✅限流、资源池
Phaser动态注册/注销参与者✅多阶段并行任务

1.3 JUC 源码

1.3.1 ConcurrentHashMap(JDK 1.8+)

为什么 1.8 不用 Segment?

  • Segment 继承 ReentrantLock,锁粒度粗(一个 Segment 锁一个 Hash 桶数组)
  • 1.8 改用synchronized + CAS:锁粒度细化到单个桶(Node 头节点)
  • 更细粒度 → 更高并发度

核心数据结构:

// 核心属性transientvolatileNode<K,V>[]table;privatetransientvolatileNode<K,V>[]nextTable;privatetransientvolatileintsizeCtl;privatetransientvolatileinttransferIndex;

为什么 TreeBin?

  • 当链表长度 > 8 时,链表转为红黑树(TreeBin包装 TreeNode)
  • 红黑树查询复杂度 O(log n),避免长链表导致查询慢
  • 树化阈值 8,退化阈值 6(防止频繁转换)

为什么 ForwardNode?

  • 扩容时,已迁移的桶位置放置ForwardingNode
  • 指向nextTable,用于扩容期间转发读写请求
  • 写操作遇到 ForwardNode:协助扩容(helpTransfer)

为什么 sizeCtl?

  • 多状态控制变量:
    • -1:正在初始化
    • -(1 + nThreads):正在扩容
    • 0:默认值
    • > 0:下次扩容阈值(容量 * 0.75)

为什么 helpTransfer?

  • 扩容期间,写线程检测到 ForwardNode 时主动参与扩容
  • 提升扩容速度,减少阻塞等待
  • 体现“所有线程都是 Worker”的设计思想

1.3.2 其他 JUC 源码要点

  • CopyOnWriteArrayList:写时复制,适合读多写少
  • BlockingQueue 实现:ArrayBlockingQueue(有界数组)、LinkedBlockingQueue(有界链表)、SynchronousQueue(无存储)、PriorityBlockingQueue(优先级)、DelayQueue(延迟)
  • ConcurrentLinkedQueue:无界非阻塞队列,CAS 实现

1.4 线上排查经验

1.4.1 CPU 100% 排查流程

  1. top -H -p <pid>查看进程内各线程 CPU 占用
  2. printf "%x\n" <tid>将线程 ID 转为十六进制
  3. jstack <pid> | grep -A 20 <tid_hex>查看线程堆栈
  4. 定位热点代码(死循环、频繁 GC、锁竞争、正则匹配)
  5. Arthasthread命令一键分析 CPU 高的线程

1.4.2 Full GC 频繁排查

  1. jstat -gcutil <pid> 1000查看 GC 频率
  2. jmap -heap <pid>查看各代内存使用
  3. jmap -dump:live,format=b,file=heap.hprof <pid>导出堆快照
  4. MAT分析大对象、内存泄漏
  5. 常见原因:内存泄漏、大对象频繁进入老年代、元空间膨胀

1.4.3 OOM 排查流程

  1. 分析事故现场(CPU、内存、日志)
  2. 通过top -p <pid>分析进程资源占用
  3. 判断内存增长类型(爆炸性增长 vs 缓慢增长)
  4. jmap -dump导出堆快照
  5. MAT 分析:Leak Suspects报告、Dominator Tree、GC Roots路径

1.4.4 死锁排查

  1. jstack <pid>自动检测死锁(会打印 “Found one Java-level deadlock”)
  2. 查看线程状态(BLOCKED、WAITING)
  3. 分析锁持有和等待关系

本篇内容覆盖了原大纲第一、二、三部分的 Java 基础、JVM 和 JUC 相关知识点。后续将继续补充 Spring 体系、数据库、Redis、MQ、微服务、分布式、高并发、架构能力、云原生、制造业、跨境电商、代码能力、线上排查等剩余部分。

相关新闻

  • 5分钟搞定GTNH汉化:让Minecraft硬核科技包秒变中文界面
  • 2024年C/C++客户端开发实战指南:从环境搭建到面试进阶
  • 卫星阀门焊漏一滴毁一颗星?精密激光封焊三道关

最新新闻

  • 生产级RAG Agent设计:混合检索与质量保障实践
  • 字节跳动中级Android面经:RecyclerView源码级分析、事件分发那些坑
  • AI+传统艺术:春晚《贺花神》视觉特效技术解析
  • A股实时行情API最小可运行示例:从curl到参数全解
  • 21-时间序列预测简介
  • C语言:文件操作

日新闻

  • 大连理工大学与东京大学联手打造的“主动型AI助手“
  • 170.2026年国家级科研瓶颈:超精密单点金刚石切削(SPDT)光学表面生成
  • SongBloom:革命性歌曲生成框架深度解析——如何通过交织自回归与扩散模型创作完整音乐

周新闻

  • 大连理工大学与东京大学联手打造的“主动型AI助手“
  • 170.2026年国家级科研瓶颈:超精密单点金刚石切削(SPDT)光学表面生成
  • SongBloom:革命性歌曲生成框架深度解析——如何通过交织自回归与扩散模型创作完整音乐

月新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号