博客记录-day174-面试

博客记录-day174-面试

一、面试

1、为什么要用线程池?

✅什么是线程池,如何实现的?

线程池通过复用已创建的线程,避免了频繁创建和销毁线程的开销(如内存分配、JVM调度),从而提升系统性能。它能有效控制并发线程数量,防止资源耗尽,同时提供任务队列和拒绝策略,增强系统的稳定性和响应速度。此外,线程池简化了线程管理,支持定时、周期性任务执行,适用于高并发场景。

2、Java 里还有哪些使用了池化思想的技术?

Java 中池化技术的典型应用包括:

​​数据库连接池​​(如 HikariCP、Druid):复用数据库连接,减少连接创建开销。

​​对象池​​(如 Apache Commons Pool):缓存对象实例,避免重复初始化。

​​HTTP 连接池​​(如 Apache HttpClient):复用 HTTP 连接,提升请求效率。

​​线程池​​(如 ExecutorService):复用线程资源。

​​内存池​​(如 Netty 的 PooledByteBufAllocator):减少内存碎片和分配耗时。

3、Java 提供了哪几种线程池?

Java 通过 Executors 工厂类提供了四种线程池:

​​FixedThreadPool​​:固定大小的线程池,使用无界队列,适用于负载稳定的场景。

​​CachedThreadPool​​:可缓存的线程池,适合短时异步任务,线程数按需增长。

​​ScheduledThreadPool​​:支持定时及周期性任务执行。

​​SingleThreadExecutor​​:单线程顺序执行,保证任务无并发问题。

此外,ForkJoinPool 用于分治任务(如递归分解任务),WorkStealingPool(JDK 8+)基于工作窃取算法提升并行效率。

4、它们的使用场景、区别及选择原则是什么?

​​FixedThreadPool​​:适合已知并发量且任务稳定的场景(如 Web 服务器请求处理)。

​​CachedThreadPool​​:适合执行大量短期异步任务(如批量数据处理),但需警惕无界队列导致 OOM。

​​ScheduledThreadPool​​:用于定时任务调度(如日志清理、心跳检测)。

​​SingleThreadExecutor​​:需保证顺序执行且无并发问题的场景(如事件回调)。

选择原则:根据任务类型(CPU/IO密集)、并发量、资源限制及任务特性(是否需顺序执行)综合评估。

5、线程池的核心参数有哪些?

​​corePoolSize​​:核心线程数,即使空闲也保留。

​​maximumPoolSize​​:最大线程数,任务队列满时扩容的极限。

​​keepAliveTime​​:非核心线程的空闲存活时间。

​​workQueue​​:任务队列(如 LinkedBlockingQueue、SynchronousQueue)。

​​threadFactory​​:线程创建工厂,可自定义线程名称、优先级等。

​​RejectedExecutionHandler​​:拒绝策略(如抛出异常、丢弃任务)。

6、如何根据 CPU 密集型和 IO 密集型任务设置参数?

​​CPU 密集型​​:核心线程数 = CPU 核心数 + 1(避免线程切换开销),队列长度适中。

​​IO 密集型​​:核心线程数 = CPU 核心数 × 2(因线程常阻塞等待 IO),队列可适当增大或使用有界队列。

实际需结合系统负载测试调整,例如通过 Runtime.getRuntime().availableProcessors() 动态获取 CPU 核心数。

7、队列长度设置的依据是什么?

队列长度需权衡内存资源和任务处理效率:

​​有界队列​​(如 ArrayBlockingQueue):防止内存溢出,但需配置合理的拒绝策略。

​​无界队列​​(如 LinkedBlockingQueue):适合突发流量,但可能导致任务堆积。

依据包括:系统可用内存、任务到达速率、任务处理时间、队列类型(如优先级队列需固定长度)。通常通过压力测试确定最佳值。

8、动态调整线程池组件时,超出部分的线程怎么办?

会调用锁,获得到锁后才会中断线程。

9、如何快速定位线程泄露问题?

​​线程转储分析​​:通过 jstack 或 VisualVM 生成线程快照,检查线程状态(如 BLOCKED 或 WAITING)及堆栈跟踪。

​​监控工具​​:使用 Prometheus + Grafana 监控线程数变化,或 Arthas 动态跟踪线程创建。

​​代码审查​​:检查线程池配置(如是否误用 Thread.sleep 或未释放资源)。

​​内存分析​​:MAT 工具分析 Thread 对象引用链,定位未回收的线程。

10、使用 Redis 实现动态调整的原因是什么?是否有替代方案?

Redis 支持原子操作和高性能读写,适合实时更新配置(如通过 SET 命令动态修改参数)。替代方案包括:

​​ZooKeeper/Etcd​​:通过监听机制实现配置同步。

​​数据库​​:存储配置表,定时轮询更新。

​​本地缓存​​:结合 Guava Cache 或 Caffeine,但需处理一致性。

Redis 的临时节点(如结合 Sentinel)可用于故障转移,但更常见的动态调整是通过外部配置中心实现。

11、AQS 锁的实现原理是什么?

✅如何理解AQS?

AQS(AbstractQueuedSynchronizer)基于 CLH 队列的变体,使用一个 volatile int state 表示同步状态,线程通过 CAS 竞争修改状态。

​​独占模式​​(如 ReentrantLock):线程尝试获取锁,失败则进入等待队列,释放时唤醒队首。

​​共享模式​​(如 Semaphore):允许多个线程同时获取锁。

AQS 内部维护双向链表(CLH 队列),通过 Node 对象管理等待线程,结合自旋和阻塞减少 CPU 消耗。

12、ThreadLocal 为什么用 ThreadLocalMap 而不是 HashMap?

​​线程隔离​​:每个线程持有独立的 ThreadLocalMap,避免多线程竞争,无需同步开销。

​​内存泄漏预防​​:ThreadLocalMap 的 Entry 继承 WeakReference,当 ThreadLocal 实例被回收时,Entry 的键自动清除,防止内存泄漏(但值仍需手动清理)。

​​性能优化​​:直接访问线程内部的 Map,减少哈希冲突和锁竞争。

13、Runnable 和 Callable接口的区别是什么?

​​返回值​​:Runnable 的 run() 无返回值,Callable 的 call() 返回泛型结果。

​​异常处理​​:Callable 允许抛出受检异常(checked exception),Runnable 的异常需在内部捕获。

​​用途​​:Runnable 用于简单异步任务,Callable 适用于需返回结果或抛出异常的场景(如 FutureTask)。

14、数据库分片有哪些方式?水平拆分的缺点是什么?

​​分片方式​​:

​​垂直分片​​:按业务拆分表(如订单库、用户库)。

​​水平分片​​:按规则(哈希、范围)拆分同一表的数据。

​​水平拆缺点​​:

跨分片查询复杂(需聚合或冗余字段)。

数据分布不均可能导致热点问题。

扩容时需数据迁移,影响可用性。

15、SQL如何调优?

✅SQL执行计划分析的时候,要关注哪些信息?

16、数据库如何解决主从延迟问题?

✅什么是数据库的主从延迟,如何解决?

✅MySQL的并行复制原理

​​并行复制​​:从库多线程应用 relay log。

​​半同步复制​​:主库等待至少一个从库确认写入。

​​应用层优化​​:读写分离时,强一致性场景直接读主库,最终一致性场景异步读从库。

​​延迟监控​​:通过 SHOW SLAVE STATUS 监控 Seconds_Behind_Master,及时报警。

17、Redis 缓存穿透、雪崩、击穿的防御手段是什么?

✅什么是缓存击穿、缓存穿透、缓存雪崩?

​​穿透​​:布隆过滤器拦截非法请求,或缓存空值(设置较短 TTL)。

​​雪崩​​:随机过期时间,集群部署,永不过期+异步更新。

​​击穿​​:互斥锁(如 Redis 的 SETNX)或永不过期,后台线程定时刷新。

18、Redis 集群如何避免脑裂问题?选举临时节点的机制是什么?

​​脑裂预防​​:多数派原则(Quorum),配置 cluster-require-full-coverage no 避免部分节点宕机导致整体不可用。

​​临时节点​​:通过 ZooKeeper/Etcd 等协调服务创建临时节点,节点消失时自动触发选举。

​​选举机制​​:基于 Raft 或类似算法,节点通过心跳检测故障,多数派确认新主节点。

19、平时常用的设计模式有哪些?

​​单例模式​​(Spring Bean 默认作用域)。

​​工厂模式​​(JDBC 驱动、Hibernate SessionFactory)。

​​代理模式​​(AOP、动态代理)。

​​观察者模式​​(Spring 事件监听)。

​​策略模式​​(多支付渠道切换)。

​​装饰器模式​​(Java I/O 流)。

​​模板方法模式​​(Spring JdbcTemplate)。

20、Spring 框架中用到了哪些设计模式?

​​模板方法​​:JdbcTemplate、RestTemplate 封装公共流程。

​​工厂模式​​:BeanFactory 创建 Bean 实例。

​​代理模式​​:JDK 动态代理或 CGLIB 实现 AOP。

​​单例模式​​:默认 Bean 作用域。

​​观察者模式​​:ApplicationEvent 和 ApplicationListener。

​​适配器模式​​:HandlerAdapter 适配不同处理器。

​​装饰器模式​​:BeanPostProcessor 增强 Bean 初始化过程。

相关文章

曝孙俪片酬1.7亿贵么?孙俪片酬一集多少钱?孙俪片酬为什么高?
联通怎么查话费打什么号,10010/1001011(三种方式快速查询)
365bet体育在线下载

联通怎么查话费打什么号,10010/1001011(三种方式快速查询)

📅 07-22 👁️ 5120
探秘中国最大古墓群(图)
365bet怎么提款

探秘中国最大古墓群(图)

📅 07-22 👁️ 5237
信東帝帕克持續藥效膜衣錠500毫克的功效、適應症及副作用
windows11怎么关闭蓝牙
365bet怎么提款

windows11怎么关闭蓝牙

📅 09-12 👁️ 9304
网页时光机Wayback Machine:寻找消失的网页
365bet怎么提款

网页时光机Wayback Machine:寻找消失的网页

📅 07-13 👁️ 4603