1.虚拟线程和异步线程(平台线程)的特点以及区别
- 平台线程 Java 线程 1:1 绑定操作系统内核线程 ,创建、调度、内存、阻塞全由 OS 内核 管理,JVM 仅做封装。
- 虚拟线程 JVM 层面自研的轻量逻辑线程 ,OS 完全感知不到;多对一(M:N) 复用少量平台线程作为载体线程,全程由 JVM 在用户态调度。
资源占用:
- 平台线程 单线程默认占用约 1MB 固定栈内存 ,还有 OS 线程控制块;创建上千个就会明显消耗内存,有系统线程数硬上限。阻塞(IO / 等待)时,整个 OS 线程资源被占用,无法复用。
- 虚拟线程 栈内存JVM 按需分配 ,单线程仅几 KB,开销极小;可轻松创建上万 / 百万级别 ,无数量瓶颈。阻塞时 JVM 自动卸载,载体线程立刻复用去执行其他任务,不浪费 OS 资源。
使用方式:
- 平台线程 必须手动维护线程池 ,提前设置核心线程、最大线程、队列;线程复用,池满则排队 / 拒绝。日常
new Thread()、@Async、Tomcat 工作线程都属于这类。 - 虚拟线程 无需手动建线程池,任务随用随创建、执行完销毁;JVM 内置少量载体线程,开发者不用配置线程数。
调度与性能
- 平台线程 OS 内核调度,上下文切换开销大。✅ CPU 密集场景最优 :无 JVM 额外调度逻辑,纯计算性能最高。❌ IO 密集短板:阻塞即浪费线程,并发能力受线程池大小限制。
- 虚拟线程 JVM 用户态调度,切换开销极低。✅ IO 密集场景最强 :阻塞自动让出载体,并发吞吐量远高于线程池。❌ CPU 密集略弱:持续运算不触发卸载,额外增加 JVM 管理开销,速度稍慢。
兼容性 & 版本
- 平台线程 全 JDK 版本支持(JDK1.2+),所有旧框架、中间件、
ThreadLocal、事务、连接池完全兼容。 - 虚拟线程 JDK21 正式转正,低版本无法使用;不适配传统
ThreadLocal(推荐ScopedValue),老业务框架改造有成本;不适合长驻后台任务。
适用场景(直接照着选)
👉 优先使用 平台线程 / 线程池
- 纯 CPU 密集:循环计算、加解密、大数据内存处理、数据解析
- 常驻后台任务:MQ 消费、定时任务、长连接监听
- 老旧项目、低版本 JDK、强依赖
ThreadLocal/ 线程上下文的业务
👉 优先使用 虚拟线程
- 纯 IO 密集:数据库查询、Redis、HTTP / 接口调用、文件读写、普通 Web 接口
- 高并发短任务,不想维护线程池参数
- JDK21 及以上新项目,追求高并发、低资源占用
2.数据库连接池
为什么需要数据库连接池?
答题要点:
- 数据库创建 / 销毁连接开销极大(TCP 握手、权限校验、会话初始化),频繁创建严重拖慢性能。
- 复用连接,减少开销、提升接口响应速度。
- 统一管控连接数量,保护数据库,避免应用无限创建连接压垮 DB。
- 统一管理超时、心跳、连接回收,简化开发。
连接池核心思想
提前初始化一批连接放入池中,业务请求从池子里获取连接,使用完毕归还,而非每次新建。
主流连接池对比(高频对比题)
市面主流:HikariCP、Druid、Tomcat JDBC Pool、C3P0 面试常问:SpringBoot 默认为什么选 HikariCP?和 Druid 区别?
- HikariCP(SpringBoot 2.x+ 默认)
- 优点:轻量、速度最快、代码精简、低开销,并发性能顶尖。
- 特点:追求极致性能,监控、扩展功能偏少。
- Druid(阿里)
- 优点:监控强大、防 SQL 注入、SQL 拦截、慢查询统计、多扩展,运维友好。
- 缺点:比 Hikari 重一点,纯性能略逊。
- 面试标准回答:
- 纯性能、追求低延迟 → 选 HikariCP
- 需要全面监控、安全防护、运维审计 → 选 Druid
HikariCP 核心参数
- maximum-pool-size 最大连接数
- 含义:池子允许的最大活跃连接数,DB 侧并发上限。
- 考点:不是越大越好。MySQL 单库单实例,单应用建议 10~30,超过 50 极易出现锁竞争、上下文切换,性能下降。
- minimum-idle 最小空闲连接
- 含义:池内最少保留的空闲连接。
- 考点:生产建议 = maximum-pool-size(固定连接池)。理由:关闭动态扩容缩容,避免连接反复创建销毁带来性能抖动。
- idle-timeout 空闲连接超时
- 含义:空闲多久后回收连接。
- 考点:固定连接池设为 0,禁止回收,连接常驻。
- connection-timeout 获取连接超时
- 含义:从池里拿不到连接时,最大等待时间。
- 现象:超时抛出
Connection is not available,典型连接池耗尽。
- max-lifetime 连接最大生命周期
- 必考坑点:必须小于数据库 wait_timeout(MySQL 默认 8 小时)。
- 原因:连接被 DB 主动断开,但池还持有旧连接,导致间歇性断连接、SQL 报错。
经典面试题:
线上偶尔报数据库连接异常,一会好一会坏,可能是什么原因?答:大概率
max-lifetime大于 MySQLwait_timeout,连接被 DB 断开,连接池持有失效连接。
- 连接池如何实现高效取 / 还连接? Hikari 使用FastList + 无锁并发设计,减少锁竞争,这是它速度快的核心原因。
- 连接池耗尽的整个流程 请求 → 从池获取连接 → 连接已满 → 排队等待
connection-timeout→ 超时报错。 - 连接归还流程 业务 close () 并不是关闭物理连接,而是把连接放回池子。.
-
**Q:说说 HikariCP 核心参数和线上配置?**A:线上采用固定连接池,maximum-pool-size 设 10~25,minimum-idle 和最大值一致,idle-timeout=0 禁止回收空闲连接,max-lifetime 小于 MySQL 超时时间,避免断连。
-
**Q:连接池满了怎么办?**A:先排查慢 SQL、事务过长、循环查库,加缓存;必要时小幅上调连接数,严禁无限加大。
-
**Q:HikariCP 和 Druid 怎么选?**A:追求极致性能选 Hikari;需要 SQL 监控、安全防护、运维审计选 Druid。
-
**Q:为什么不能把 minimum-idle 设很小?**A:会触发连接频繁扩容、销毁,产生性能抖动,生产建议固定连接数。
-
**Q:连接间歇性失效报错原因?**A:连接池内连接生命周期大于数据库空闲超时,连接被 DB 断开,池内残留无效连接