1、请解释HashMap
和ConcurrentHashMap
的主要区别,并说明为什么在多线程环境下推荐使用ConcurrentHashMap
?
1、线程安全性:HashMap线程不安全,ConcurrentHashMap线程安全HashMap没有锁机制,ConcurrentHashMap有锁机制有锁机制(CAS操作+synchronized桶级锁)
2.null支持:HashMap支持,ConcurrentHashMap不支持,禁止了null避免并发场景下的二义性问题
3.性能:ConcurrentHashMap有内置的安全机制,在高并发的场景下并发性能更高##为什么推荐 ConcurrentHashMap?因为它线程安全,能有效提高并发性能,避免锁竞争,适合在多线程场景下使用
2、请解释synchronized
和ReentrantLock
的区别,以及各自适用的场景。
1、锁机制synchronized是JVM层实现的,支持自动释放锁(即使异常也会释放)ReentrantLock是JDK层实现的,需要手动lock() 和 unlock(),必须在finally块确保释放锁,否则可能导致死锁
2、可中断性和超时synchronized不可中断,等待锁时除非获得锁或者自身中断,否则会一直阻塞ReentrantLock提供lockInterruptibly() 方法,允许等待锁时响应中断,避免一直阻塞ReentrantLock支持tryLock(timeout,unit),获取锁时可配置等待时间,超时响应中断,避免死锁风险。
3、公平性synchronized不支持ReentrantLock支持,构造函数new ReentrantLock(true),但公平性会降低吞吐量##适用场景synchronized简单的同步场景ReentrantLock复杂的同步场景,需要细粒度控制的场景,要用到tryLock,可中断,公平锁,
3、请解释 JVM 内存模型中 堆(Heap) 和 栈(Stack) 的区别,以及它们各自存储哪些数据?
##堆
存储内容:存储对象实例和数组,字符串常量池
生命周期:整个程序运行期间都可能存在,直到被GC回收(当没有任何引用指向该对象时会被GC回收)
大小:大小可通过JVM启动参数(如 -Xms 和 -Xmx)进行配置。
线程共享:所有线程共享堆内存,需通过同步机制保证线程安全(如 synchronized)。
## 栈
存储内容:栈帧(方法引用、操作数栈、局部变量、返回地址)
生命周期:栈帧随着方法调用创建,方法结束(正常返回或异常)时销毁。
大小:栈的大小通常较小,并且每个线程有独立的栈空间。可以通过 JVM 启动参数(如 -Xss)配置。
线程隔离:每个线程有独立的栈空间,无需同步。堆:用于存储对象和数组,由多个线程共享,生命周期较长,管理复杂。
栈:用于存储局部变量和方法调用信息,每个线程有独立的栈空间,生命周期较短。
4、请解释数据库事务的 ACID 特性,并说明在MySQL中如何保证这些特性?
##原子性
事务为一个整体,要么全部成功,要不全部失败。如果失败事务将回滚到初始状态。
如何保证:MySQL 使用 Undo Log(回滚日志)来实现原子性。##一致性
提交事务前后,数据库必须保持一致性状态。
如何保证:由数据库的约束和程序共同保证##隔离性
多个事务并发执行时,每个事务之间互相隔离,防止互相干扰。
如何保证:MySQL通过锁机制和MVCC来实现隔离性。
(锁机制:行级锁,表级锁等;MVCC:InnoDB存储引擎使用MVCC来实现非阻塞的读操作。)##持久性
持久性一旦事务提交,其对数据库的修改就是永久性的,即使系统崩溃也不会丢失。
如何保证:MySQL 使用 Redo Log(重做日志)来实现。当事务提交时,所有的修改操作会先写入 Redo Log,然后再写入磁盘。即使系统崩溃,MySQL 也可以通过 Redo Log 恢复未写入磁盘的数据。## 总结
原子性:通过 Undo Log 实现回滚操作。
一致性:通过数据库约束和应用程序逻辑保证。
隔离性:通过锁机制和 MVCC 实现并发控制。
持久性:通过 Redo Log 确保数据在崩溃后可以恢复。
5、请解释 Spring 中 Bean 的生命周期,并说明如何通过 BeanPostProcessor 干预 Bean 的初始化过程?如果多个 BeanPostProcessor
同时存在,它们的执行顺序是如何确定的?如何自定义顺序?
#生命周期
实例化,属性赋值,初始化,使用,销毁
#BeanPostProcessor干预 Bean 的初始化过程
使用BeanPostProcessor接口,实现前置方法和后缀方法,切断入点在Bean初始化前后
#执行顺序是如何确定的
默认由spring容器加载顺序决定,但可以通过@Order() 自定义指定优先级,值越小优先级越高。
6、请解释单例模式的实现方式,并说明在 Spring 中如何保证单例 Bean 的线程安全?
##单例模式
确保一个类只有一个实例,并提供一个全局访问点。
##Spring 单例 Bean
默认情况下,Spring 容器中的单例 Bean 是线程安全的,前提是 Bean 是无状态的。
对于有状态 Bean,可以通过同步机制、ThreadLocal 或并发集合来保证线程安全。
7、请解释 CAP 理论,并说明在分布式系统中如何权衡一致性(Consistency)、可用性(Availability)和分区容错性(Partition Tolerance)?
一致性,可用性,分区容错无法同时满足,最多满足其他的两个。在分布式系统中,需要确保分区容错,所以P是要有的。更新系统实际业务和需求在一致性和可用性中选择。
比如:读多写少的新闻系统选择AP。对数据一致性要求高的选择CP。
策略有:读写分离,最终一致性,分布式事务