博客记录-day130-Spring,MySQL面试题

一、语雀-Spring面试题

1、Spring中@Service 、@Component、@Repository等注解区别是什么?

✅Spring中@Service 、@Component、@Repository等注解区别是什么?

2、如何在Spring启动过程中做缓存预热

✅如何在Spring启动过程中做缓存预热

在Spring启动过程中实现缓存预热,可以通过监听ContextRefreshedEvent事件(如使用ApplicationListener@EventListener注解),在应用上下文初始化完成后触发缓存填充逻辑;通常会在该事件回调中调用服务层方法,主动从数据库或其他数据源加载热点数据存入缓存(如Redis、Caffeine等),确保后续请求可直接命中缓存。示例代码如下:

java 复制代码
@Component
public class CacheWarmupListener {
    @Autowired
    private CacheService cacheService;

    @EventListener(ContextRefreshedEvent.class)
    public void warmUpCache() {
        if (!cacheService.isInitialized()) { // 避免重复预热
            cacheService.preloadHotData(); 
            cacheService.markInitialized();
        }
    }
}

需注意:若存在多上下文环境(如父子容器),应通过标志位或分布式锁防止多次执行,并根据业务选择异步执行(@Async)提升启动速度。

3、@Lazy注解能解决循环依赖吗?

✅@Lazy注解能解决循环依赖吗?

4、Spring 中的 Bean 是线程安全的吗?

✅Spring 中的 Bean 是线程安全的吗?

5、Spring 中的 Bean 作用域有哪些?

✅Spring 中的 Bean 作用域有哪些?

6、Spring的事务在多线程下生效吗?为什么?

✅Spring的事务在多线程下生效吗?为什么?

7、如何根据配置动态生成Spring的Bean?

✅如何根据配置动态生成Spring的Bean?

1. 基于条件的 Bean 注册

2. 使用@ConfigurationProperties

8、介绍下@Scheduled的实现原理以及用法

✅介绍下@Scheduled的实现原理以及用法

1、@Scheduled 的常见用法

@Scheduled 是 Spring 提供的定时任务注解,支持多种调度策略:

  1. 固定速率执行 :通过 fixedRate = 5000 表示每隔 5 秒执行一次,任务按固定时间间隔触发,无论任务执行耗时多久。
  2. 固定延迟执行 :通过 fixedDelay = 5000 表示在上一次任务完成后,延迟 5 秒再执行下一次。
  3. 初始延迟 :通过 initialDelay = 1000 表示首次执行前延迟 1 秒。
  4. Cron 表达式 :通过 cron = "0 0/1 * * * ?" 支持复杂时间规则(秒、分、时、日、月、周、年)。

示例代码

java 复制代码
@Scheduled(fixedRate = 5000) 
public void fixedRateTask() { /*...*/ }

@Scheduled(cron = "0 0 12 * * ?") 
public void cronTask() { /* 每天中午12点执行 */ }

2、@Scheduled 的实现原理

  1. 注解扫描与注册

    Spring 启动时,通过 ScheduledAnnotationBeanPostProcessor(内置的 BeanPostProcessor)扫描所有带有 @Scheduled 注解的方法,将其解析为 TaskTrigger 对象(如 CronTriggerPeriodicTrigger),并注册到 TaskScheduler 中。

  2. 任务调度器(TaskScheduler)

    默认使用 ThreadPoolTaskScheduler 作为调度器,基于线程池管理任务执行。它会根据触发器的规则(如 Cron 表达式或固定间隔)计算下一次执行时间,并提交任务到线程池。

  3. 任务执行流程

    • 若使用 cron 表达式,CronTrigger 会解析表达式生成下一次触发时间。

    • 若使用 fixedRatefixedDelayPeriodicTrigger 会根据配置计算触发间隔。

    • 线程池从队列中取出任务并执行,异常会终止当前任务,但不会影响其他任务。


3、关键配置与注意事项

  1. 线程池自定义

    可通过配置 ThreadPoolTaskScheduler 调整线程池参数:

    java 复制代码
    @Bean
    public ThreadPoolTaskScheduler taskScheduler() {
        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
        scheduler.setPoolSize(10); // 设置核心线程数
        scheduler.setThreadNamePrefix("scheduled-task-");
        return scheduler;
    }
  2. 方法约束

    • 被 @Scheduled 修饰的方法必须是 public,返回值应为 void

    • 方法参数需为空,否则会抛出异常(如 String[] args 会导致解析错误)。

  3. 时区与错误处理

    • 默认使用服务器本地时区,可通过 zone 属性指定时区(如 @Scheduled(cron = "...", zone = "GMT+8"))。

    • 任务执行异常需手动捕获,避免影响后续任务调度。


4、典型应用场景

  1. 定时数据同步:如每小时同步数据库到缓存。
  2. 周期性清理:每日凌晨清理临时文件或过期数据。
  3. 报表生成:固定时间生成业务报表并发送邮件。
  4. 心跳检测:通过固定间隔检查服务健康状态。

动态扩展 :若需动态调整任务时间,可结合 ScheduledFuture 取消旧任务并重新注册(需自定义实现)。

9、Spring中创建Bean有几种方式?

✅Spring中创建Bean有几种方式?

1. 通过@Component系列注解

2. 通过@Bean 注解

@Configuration 是 Spring 框架中用于定义配置类的核心注解,标记一个类为 Spring 容器加载的配置源,替代传统的 XML 配置文件。该注解类通过 @Bean 注解的方法直接声明 Bean 实例(方法名即 Bean 名称),并由 Spring 自动调用并注册到应用上下文。其本质是通过 CGLIB 动态代理实现,确保配置类内方法调用时会触发 Spring 的 Bean 管理逻辑(如依赖注入、单例控制等),从而提供更简洁、类型安全的编程式配置方式,是 Java Config 的核心机制之一。

10、Spring 中注入 Bean 有几种方式

✅Spring 中注入 Bean 有几种方式

1. 使用@Autowired 注解

1.1 字段注入
java 复制代码
@Component
public class HollisService {

    @Autowired
    private HollisRepository hollisRepository;

}
1.2 构造器注入
java 复制代码
@Component
public class HollisService {

    private HollisRepository hollisRepository;

    @Autowired
    public HollisService(HollisRepository hollisRepository){

        this.hollisRepository = hollisRepository;

    }
}
1.3 setter注入
java 复制代码
@Component
public class HollisService {

    private HollisRepository hollisRepository;

    @Autowired
    public void setHollisRepository(HollisRepository hollisRepository){

    this.hollisRepository = hollisRepository;

    }

}

2. 使用 @Resource 和 @Inject 注解

java 复制代码
@Component
public class HollisService {

    @Resource
    private HollisRepository hollisRepository;

}

 
@Component
public class HollisService {

    @Inject
    private HollisRepository hollisRepository;

}

3. FactoryBean

java 复制代码
@Configuration
public class HollisService {

  
    @DubboReference(version = "1.0.0")
    private HollisRemoteFacadeService hollisRemoteFacadeService;

}

这里用到了@DubboReference把HollisRemoteFacadeService这个 bean给注入进来了。@DubboReference其实是RPC 框架Dubbo 提供的一个注解,他的实现原理其实就是基于 FactoryBean来创建并配置Dubbo服务的代理对象的。

11、同时使用 @Transactional 与 @Async 时,事务会不会生效?

✅同时使用 @Transactional 与 @Async 时,事务会不会生效?

@Transactional
@Transactional 是 Spring 框架中用于声明式事务管理的核心注解。当将其标注在方法或类上时,Spring 会自动为该方法开启一个数据库事务,确保方法内的所有数据库操作(如增删改查)满足原子性------即要么全部成功提交,要么在发生异常时全部回滚。通过设置参数(如 propagation 传播行为、isolation 隔离级别),可以灵活控制事务的边界和并发行为。典型场景如银行转账操作,需保证扣款和入账两个步骤同时成功或失败。

@Async
@Async 是 Spring 提供的异步执行注解,用于将方法标记为非阻塞式调用。当线程调用被 @Async 修饰的方法时,该方法会立即返回,实际执行交由独立的线程池处理(需提前配置 @EnableAsync 和线程池)。此特性适用于耗时操作(如文件上传、远程 API 调用),可避免主线程等待,提升系统吞吐量。但需注意异步方法的返回值需通过 Future 类型处理,且方法内异常不会直接抛出至调用方,需通过回调或日志等方式捕获。

1. 两者在同一方法,事务生效

2. 两者在不同方法,事务只在@Transactional生效,因为线程隔离

12、SpringBoot和传统的双亲委派有什么不一样吗?

✅SpringBoot和传统的双亲委派有什么不一样吗?

Spring Boot与传统双亲委派模型的核心区别

传统双亲委派模型遵循严格的类加载层级(Bootstrap → Extension → Application),确保核心类库的唯一性;而Spring Boot在启动时通过自定义类加载器(如LaunchedURLClassLoader)打破部分委派规则,优先加载应用自身的类和依赖(如嵌入式容器、自动配置模块),以支持模块化开发和条件化加载(如@ConditionalOnClass)。这种调整允许应用类覆盖父类加载器的同名类,解决了传统模型在复杂依赖和嵌套JAR场景下的局限性,但需开发者注意潜在的类冲突风险。


传统的采用双亲委派的类加载机制大家都知道,要加载一个类的额时候,先委托父类加载器加载该类;如果父类加载器无法找到(类不存在),才由当前 ClassLoader 加载;这样保证了核心类库(rt.jar)不会被重复加载,避免了类冲突问题。

1. 在JDK 1.8之前,传统的双亲委派如下:

2. 在JDK 1.9中,传统的双亲委派如下:

二、语雀-MySQL面试题

1、什么是索引跳跃扫描

✅什么是索引跳跃扫描

1. 原理

2、MySQL是AP的还是CP的系统?

3、什么是ReadView,什么样的ReadView可见?

✅什么是ReadView,什么样的ReadView可见?

4、undolog会一直存在吗?什么时候删除?

✅undolog会一直存在吗?什么时候删除?

原因解释

在基于多版本并发控制(MVCC)的数据库(如MySQL InnoDB)中,Undo Log 用于保存事务修改前的数据版本,以支持其他事务读取历史快照。当一个事务(记为T)提交后,若所有当前活跃的读事务(即尚未提交的读事务)均在T提交之前启动,则这些读事务的快照已不依赖T的Undo Log------因为它们只能看到T提交前的数据版本,而T的修改对它们的视图已不可见。此时,T的Undo Log不再被任何活跃事务需要,可被安全清理,避免占用存储空间。反之,若有活跃读事务在T提交后启动,则这些事务仍需通过T的Undo Log构建其快照,此时清理会导致数据不一致。

5、二级索引在索引覆盖时如何使用MVCC?

✅二级索引在索引覆盖时如何使用MVCC?

6、什么是前缀索引,使用的时候要注意什么?

✅什么是前缀索引,使用的时候要注意什么?

7、limit的原理是什么?

✅limit的原理是什么?

8、MySQL的update语句什么时候锁行什么时候锁表

✅MySQL的update语句什么时候锁行什么时候锁表

9、MySQL表级意向锁作用

MySQL 的意向锁(Intention Locks)确实主要用于在不同粒度的锁(如行级锁和表级锁)之间传递信息,以协调并发操作并避免冲突。它的核心作用是让表级锁 知道当前表中是否存在行级锁,从而避免不同事务之间的锁竞争。


1. 意向锁的类型

  1. 意向共享锁(IS Lock)
    表示事务打算在表中的某些行上加共享锁(S Lock)。
  2. 意向排他锁(IX Lock)
    表示事务打算在表中的某些行上加排他锁(X Lock)。

2. 示例场景

假设有一个表 orders,包含以下数据:

id product quantity
1 A 10
2 B 5
2.1 事务 A:对单行加排他锁(X Lock)
sql 复制代码
START TRANSACTION;
-- 对 id=1 的行加排他锁(X Lock)
UPDATE orders SET quantity = 20 WHERE id = 1; 
-- 此时,MySQL 自动为该表添加一个 IX 锁(意向排他锁)
  • 结果 :事务 A 在 id=1 的行上加了 X 锁,同时在表级加了 IX 锁。
  • 含义:告诉其他事务,"我正在修改某些行,但具体是哪些行不确定,你们如果要加表级锁需要先检查"。
2.2 事务 B:尝试对整个表加共享锁(S Lock)
sql 复制代码
START TRANSACTION;
-- 尝试对整个表加共享锁(S Lock)
LOCK TABLES orders READ; 
-- 这里会立即被阻塞,直到事务 A 提交或回滚!

原因:表级 S 锁与事务 A 的 IX 锁是兼容的(见下文兼容性规则),因此事务 B 可以加 S 锁。

2.3 事务 C:尝试对整个表加排他锁(X Lock)
sql 复制代码
START TRANSACTION;
-- 尝试对整个表加排他锁(X Lock)
LOCK TABLES orders WRITE; 
-- 这里会被阻塞,直到事务 A 提交或回滚!

原因 :表级 X 锁与事务 A 的 IX 锁不兼容。因为 IX 表示"某些行已被锁定",表级 X 锁要求独占整个表,因此必须等待。


2.4 锁兼容性矩阵

锁兼容性 决定了多个事务能否同时持有同一资源的锁,其核心规则是:

共享锁 (S)允许其他事务加共享锁,但排斥排他锁(X)。

排他锁 (X)完全排斥其他任何锁(包括S和X)。

意向锁 (IS/IX)与共享锁兼容(表示行级操作意图),但与排他锁冲突(防止表级独占)。

兼容性矩阵通过定义不同锁的共存规则,平衡并发性能与数据一致性,确保高并发场景下事务不会因锁冲突而阻塞或死锁。


2.5 关键点总结

  1. 传递信息:意向锁通过表级锁的元数据,告知其他事务"当前表中有行级锁存在"。
  2. 提高并发性:允许行级锁与表级锁共存(例如 IS/IX 与 S 锁兼容),避免表级锁成为性能瓶颈。
  3. 层级关系:意向锁是表级锁,但不会直接阻止其他行级锁的操作,仅用于协调表级锁的请求。

通过这种方式,MySQL 在粗粒度(表级)和细粒度(行级)锁之间实现了高效的协作。

10、MySQL事务ACID是如何实现的?

✅MySQL事务ACID是如何实现的?

1. 原子性

2. 隔离性

3. 持久性

4. 一致性

11、一次insert操作,MySQL的几种log的写入顺序?

相关推荐
uhakadotcom9 小时前
云计算与开源工具:基础知识与实践
后端·面试·github
uhakadotcom10 小时前
BPF编程入门:使用Rust监控CPU占用
后端·面试·github
uhakadotcom10 小时前
GHSL-2024-252: Cloudflare Workers SDK 环境变量注入漏洞解析
后端·面试·github
uhakadotcom10 小时前
GHSL-2024-264_GHSL-2024-265: 了解 AWS CLI 中的正则表达式拒绝服务漏洞 (ReDoS)
后端·面试·github
uhakadotcom10 小时前
了解Chainlit:简化AI应用开发的Python库
后端·面试·github
小华同学ai11 小时前
1K star!这个开源项目让短信集成简单到离谱,开发效率直接翻倍!
后端·程序员·github
ON.LIN11 小时前
Git提交本地项目到Github
git·github
uhakadotcom12 小时前
使用 Model Context Protocol (MCP) 构建 GitHub PR 审查服务器
后端·面试·github
uhakadotcom12 小时前
Apache Airflow入门指南:数据管道的强大工具
算法·面试·github
uhakadotcom12 小时前
Ruff:Python 代码分析工具的新选择
后端·面试·github