当前位置: 首页 > news >正文

Day05

1. MySQL脏读和幻读的区别

脏读是指一个事务读取到了另一个事务未提交的数据,比如事务B更新了账户余额还没提交,事务A就读到了这个更新结果,但如果事务B回滚,事务A读到的数据就是“脏数据”。
幻读是指在同一个事务中,两次执行相同的查询语句,结果行数不一致,比如第一次查询5条订单,另一个插入了一条新订单,第二次再查就是6条,这种多出来的数据就叫幻读。
区别:脏读影响的是“值”,幻读影响的是“行”,避免脏读可以用 Read Committed,避免幻读一般用 Repeatable Read 或 Serializable。

2. 如何避免幻读?

  1. 对于快照读(普通SELECT):InnoDB 使用 MVCC(多版本并发控制)技术,通过技术版本链,在一个事务内部始终读取事务开始时的一致性试图,即使其他事务插入了新数据,当前事务也读不到,自然避免了幻读现象。
  2. 对于当前读(如SELECT…FOR UPDATE):InnoDB 会使用 Next-Key Lock(记录锁 + 间隙锁)来锁定读取的记录范围,防止其他事务在该范围内插入数据,从而避免了由于并发插入而导致的幻读。

3. Java双亲委派机制是什么?

Java 双亲委派机制是一种类加载的设计模式,用于保证 Java 类加载的安全性和稳定性。
核心思想:当一个类加载器收到类加载请求时,不会自己先去加载这个类,而是先把请求委派给它的父加载器去加载。父加载器再继续委派给自己的父加载器,直到顶层的启动类加载器(Bootstrap ClassLoader)。如果父加载器能够完成加载,就直接返回结果;如果无法加载,子加载器才会尝试自己去加载。
好处:

  1. 避免重复加载同一个类,保证类的唯一性。
  2. 防止恶意类覆盖核心 Java 类,提升安全性。
  3. 保证 Java 核心库的稳定性和兼容性。

4. 垃圾回收cms和g1的区别是什么?

CMS(Concurrent Mark-Sweep)垃圾回收器采用标记-清除算法,主要目标是减少老年代的停顿时间,通过并发标记和清除垃圾来实现低延迟,但清理阶段仍可能产生较长的暂停且容易产生内存碎片。
G1(Garbage-First)则将堆划分为多个独立的小区域,通过并发标记和分区优先回收垃圾较多的区域,能更好地控制停顿时间,适合大堆内存和多核环境,兼顾低延迟和高吞吐,是更现代、更智能的垃圾回收器。

特性CMS(Concurrent Mark-Sweep)G1(Garbage-First)
设计目标减少老年代 GC 停顿时间,实现低暂停低暂停、高吞吐,兼顾大堆内存和多核处理
回收机制标记-清除(Mark-Sweep),主要针对老年代垃圾回收分区回收(Region-based),对年轻代和老年代统一管理
内存划分年轻代和老年代分开管理堆划分成多个大小相同的区域(Region),灵活管理
垃圾回收过程并发标记后,清除垃圾(清理阶段不是并发的,可能停顿)并发标记后,优先回收回收收益高的区域,分多次回收避免长时间停顿
缺点清理阶段可能会产生较长停顿(Stop-the-World),且易产生碎片实现复杂,JDK7及以后版本才有,适合大堆内存
适用场景对延迟敏感但堆较小的系统大内存、多核服务器应用,对延迟和吞吐均有较好支持

5. Spring三级缓存解决循环依赖问题?

循环依赖指的是多个 Bean 在实例化过程中相互依赖,形成闭环。这种问题会在 Spring 容器场景 Bean 时触发:Spring 在创建 A Bean 时,发现它依赖 B,然后去创建 B,又发现 B 也依赖 A,如果没有处理机制,就会一直递归下去,最终导致栈溢出或创建失败。

三种情况是根据注入方式(构造 VS setter)和作用域(singleton VS prototype)不同产生的:

  1. 构造器注入 + 循环依赖:Spring 在创建 Bean 时,必须一次性完成构造方法,所以如果 A 和 B 都通过构造方法互相依赖,就无法中断流程,也无法提前暴露任何 Bean,因此无法解决。
  2. Setter 注入 + prototype 多例:prototype Bean 每次都会新建实例,而且 Spring 不会进行缓存或管理原型 Bean 的生命周期,因此也无法提前暴露或解决循环依赖。
  3. Setter 注入 + singleton 单例:单例 Bean 是由 Spring 容器创建并容易管理的,Spring 可以提前将创建中的 Bean 暴露出来,后续 Bean 再依赖它时就能获取“早期引用”,从而打破死循环。

Spring 通过三个层级缓存 Bean 的不同状态来解决循环依赖:

  1. singletonObjects(一级缓存):保存完全初始化好的 Bean。
  2. earlySingletonObjects(二级缓存):保存实例化但未初始化的“早期 Bean。
  3. singletonFactories(三级缓存):保存创建早期 Bean 的 ObjectFactory 工厂。

过程举例:

  1. 创建 A,发现依赖 B → 先把 A 的 ObjectFactory 存入三级缓存。
  2. 开始创建 B,B 依赖 A → 去三级缓存中拿出 A 的早期引用注入。
  3. 最终 A 和 B 都完成初始化,从缓存中升级为正式 Bean。

6. 如何使用Spring实现事务?

  1. 使用注解方式:只需在业务方法上加 @Transactional 注解,Spring 会通过 AOP 动态代理的方法在方法调用前后加上事务管理逻辑。
  2. 编程式事务:通过手动控制事务提交/回滚。
// 注解方式
@Service
public class OrderService {@Autowiredprivate OrderMapper orderMapper;@Transactional  // 开启事务public void createOrder(Order order) {orderMapper.insert(order);  // 插入订单// 其他可能会抛异常的操作,比如库存扣减、支付处理等}
}
// 编程式
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;@Service
public class UserService {@Autowiredprivate UserDao userDao;@Autowiredprivate TransactionTemplate transactionTemplate;public void addUser(User user) {transactionTemplate.execute(new TransactionCallbackWithoutResult() {@Overrideprotected void doInTransactionWithoutResult(TransactionStatus status) {userDao.insert(user);// 其他数据库操作}});}
}

7. 介绍事务传播模型有哪些?

事务传播行为是指一个事务方法被另一个事务方法调用时,事务如何传播和处理。Spring 事务传播机制就是解决调用链上多个事务之间的关系和边界问题。

传播行为含义说明
PROPAGATION_REQUIRED(默认)如果当前没有事务,则新建一个事务;如果已有事务,加入该事务。
PROPAGATION_SUPPORTS如果当前有事务,则加入事务;如果没有事务,则以非事务方式执行。
PROPAGATION_MANDATORY必须在一个已有事务中运行;如果当前没有事务,则抛出异常。
PROPAGATION_REQUIRES_NEW始终新建一个新事务,如果当前存在事务,则将当前事务挂起。
PROPAGATION_NOT_SUPPORTED以非事务方式运行,如果当前存在事务,则将当前事务挂起。
PROPAGATION_NEVER以非事务方式运行,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED如果当前存在事务,则在嵌套事务内执行(通过 savepoint 实现部分回滚);如果没有事务,则新建事务。

8. Springboot常用注解有哪些?

springboot 启动相关

注解作用
@SpringBootApplication组合注解,包含 @Configuration@EnableAutoConfiguration@ComponentScan,标志主类为 Spring Boot 启动入口。
@ComponentScan扫描指定包及其子包下的 Bean,默认扫描启动类所在包及其子包。

Bean 定义与注入相关

注解作用
@Component普通组件类,交给 Spring 管理。
@Service业务逻辑层组件。
@Repository持久层组件(DAO 层),可支持 Spring 异常转换。
@Controller表示控制器类,用于处理请求。
@RestController@Controller + @ResponseBody,用于构建 RESTful API。
@Autowired自动注入依赖对象,按类型注入。
@Qualifier@Autowired 搭配使用,按名称指定注入 Bean。
@Value注入配置文件中的值。
@Configuration标明类是配置类,相当于 XML 中的 <beans>
@Bean将方法的返回值注入为 Spring 容器中的一个 Bean。

请求处理相关

注解作用
@RequestMapping通用映射请求路径,可以用于类或方法上。
@GetMapping / @PostMapping / @PutMapping / @DeleteMapping专门处理 GET、POST 等请求方式的简化注解。
@RequestParam获取请求参数(如 ?id=1)。
@PathVariable获取 URL 路径中的变量(如 /user/{id})。
@RequestBody将请求体中的 JSON 自动封装成对象。
@ResponseBody方法返回值作为响应体(JSON/XML 等),不是视图名。

事务与数据库

注解作用
@Transactional表示方法或类需要事务管理,支持传播机制。

Springboot 配置与自动化

注解作用
@EnableAutoConfiguration开启 Spring Boot 的自动配置功能。
@ConfigurationProperties将配置文件中的一组属性自动注入为 Java Bean。
@EnableConfigurationProperties配合 @ConfigurationProperties 使用,启用配置绑定。

其他使用注解

注解作用
@Slf4j来自 Lombok,自动注入日志对象 log。
@DataLombok 注解,自动生成 Getter、Setter、toString、构造函数等。
@ConditionalOnProperty配置类是否生效,取决于配置文件中某个值是否匹配。
@Profile指定该类或方法在哪个 profile(如 dev/test/prod)下生效。

9. 介绍下BIO、NIO、AIO?

BIO(阻塞I/O):是一种同步、阻塞的通信方式,服务器为每个客户端连接分配一个线程,当线程进行读写操作会一直阻塞,直到有数据可读或写入完成。适用于连接数较少的传统应用,简单但不适合高并发。
NIO(非阻塞I/O):是一种同步、非阻塞的方式,引入了 Channel(通道)、Buffer(缓冲区)和 Selector(选择器),一个线程可以处理多个连接,通过事件轮询机制提升并发处理能力。适用于高性能、高并发场景,如 Netty。
AIO(异步I/O):是一种异步、非阻塞的通信方式,I/O 操作由操作系统完成后通知应用程序(回调机制),开发者无需关心轮询或阻塞问题。适合对性能要求极高的系统,如金融、高并发服务器等。

相关文章:

  • 深度解析 Dockerfile 配置:构建高效轻量的FastAPI 应用镜像
  • Docker Desktop无法在windows低版本进行安装
  • JS逆向 QQ音乐sign签名|webpack实战 (上)
  • RocksDB
  • 对比RFX2401C:AT2401C功率放大器的性价比与PIN兼容方案
  • 2025年5月AI科技领域周报(5.19-5.25):大模型多模态突破 具身智能开启机器人新纪元
  • qt ubuntu 20.04 交叉编译
  • jq checked选中触发事件
  • 代码输出题:异步事件循环
  • 梯形面积计算shell脚本
  • Java设计模式之设计原则
  • 深入解析 Spring @Transactional 的事务开启机制
  • 【计算机网络】第1章:概述—分组延时、丢失和吞吐量
  • BugKu Web渗透之矛盾
  • 电脑长期不关机会怎样?
  • HarmonyOS 5 应用开发导读:从入门到实践
  • CloudCompare|点测量功能源码分析
  • ABP VNext + CRDT 打造实时协同编辑
  • 怎么快速判断一款MCU能否跑RTOS系统
  • OpenCV CUDA模块直方图计算------在 GPU 上计算图像直方图的函数calcHist()
  • 网站建设模块方案书/seo的定义
  • 如何用百度搜自己做的网站/百度排行榜风云
  • 设计师常用素材网站/免费模板网站
  • 网站开发需要懂哪些/广告策划方案范文
  • 做调研的网站有哪些/百度seo查询系统
  • 素材设计做的好的网站有哪些/免费b站软件推广网站2023