一、语雀-Spring面试题
1、Spring事务失效可能是哪些原因?
1. @Transactional 应用在非 public 修饰的方法上
2. 同一个类中方法调用,导致@Transactional失效
3. final、static方法
2、什么是MVC
3、SpringMVC是如何将不同的Request路由到不同Controller中的?
✅SpringMVC是如何将不同的Request路由到不同Controller中的?
1. SpringMVC的执行流程是什么样的?
4、Springboot是如何实现自动配置的?
1. 核心入口:@EnableAutoConfiguration
Spring Boot 的自动配置功能通过 @EnableAutoConfiguration 注解启用,该注解通常位于主启动类上,并被 @SpringBootApplication 组合注解包含。其核心作用是触发 Spring Boot 的自动配置机制,引导框架根据应用的依赖和环境动态加载合适的组件。当应用启动时,@EnableAutoConfiguration 会借助 SpringFactoriesLoader 机制,从所有依赖的 JAR 包中加载 META-INF/spring.factories 文件中声明的自动配置类,从而为容器注册相应的 Bean。这一过程是自动化的,开发者无需手动编写大量配置代码即可完成基础功能的搭建。
2. 条件化配置:@Conditional 系列注解
自动配置类并非无条件生效,而是通过一系列条件注解(如 @ConditionalOnClass、@ConditionalOnMissingBean 等)动态决定是否生效。例如,@ConditionalOnClass(SomeService.class) 表示只有当类路径中存在 SomeService 类时,对应的配置类才会被激活;而 @ConditionalOnMissingBean 则确保当容器中已有同名 Bean 时,自动配置类不会覆盖用户自定义的 Bean。这些条件注解通过条件评估逻辑(Condition 接口的实现)在运行时进行判断,使得自动配置既智能又灵活,能够适应不同项目的需求。
3. 自动配置类的加载:spring.factories
自动配置类的加载依赖于 META-INF/spring.factories 文件。每个自动配置模块(如 Web、数据库、安全等)需在该文件中声明需要加载的配置类全限定名,例如:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.SomeAutoConfiguration
Spring Boot 启动时,通过 AutoConfigurationImportSelector 读取所有 JAR 包中的 spring.factories 文件,收集其中的配置类,并按照优先级排序后注册到 Spring 容器中。这种机制使得第三方库可以无缝集成到 Spring Boot 应用中,仅需添加依赖即可自动启用相关功能。
4. 条件判断与优先级
自动配置类的生效顺序和条件判断直接影响最终 Bean 的注册结果。条件注解的评估顺序基于类路径、环境变量、配置属性等多维度因素,例如 @ConditionalOnProperty(name = "feature.enabled") 会根据配置文件中的属性值决定是否生效。若多个配置类尝试注册同名 Bean,后加载的配置类可能因 @ConditionalOnMissingBean 失效,或由用户显式定义的 Bean 覆盖自动配置的 Bean。此外,@Order 注解或实现 Ordered 接口可显式指定加载顺序,解决复杂场景下的冲突问题。
5、SpringBoot的启动流程是怎么样的?
1. new SpringApplication()
private <T> Collection<? extends T> getSpringFactoriesInstances(Class<T> type,
Class<?>[] parameterTypes, Object... args) {
// 获取当前线程的上下文类加载器
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
// 从spring.factories加载指定类型的工厂名称,并使用LinkedHashSet确保名称的唯一性,以防重复
Set<String> names = new LinkedHashSet<String>(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
// 创建指定类型的实例。这里使用反射来实例化类,并传入任何必要的参数
List<T> instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);
// 对实例进行排序,这里使用的是Spring的注解感知比较器,可以处理@Order注解和Ordered接口
AnnotationAwareOrderComparator.sort(instances);
// 返回实例集合
return instances;
}
2. SpringApplication.run
看完了new SpringApplication接下来就在看看run方法做了哪些事情。这个方法是 SpringApplication 类的核心,用于启动 Spring Boot 应用。
6、Spring的AOP在什么场景下会失效?
首先,Spring的AOP其实是通过动态代理实现的,所以,想要让AOP生效,前提必须是动态代理生效,并且可以调用到代理对象的方法。
什么情况下会不走代理对象的调用呢?
7、SpringBoot和Spring的区别是什么?
8、在Spring中如何使用Spring Event做事件驱动
✅在Spring中如何使用Spring Event做事件驱动
在Spring中,通过事件驱动模型实现组件解耦主要分为三步:1. 创建继承ApplicationEvent的自定义事件(如OrderCreatedEvent);2. 使用@EventListener注解或实现ApplicationListener接口编写事件监听器(如处理邮件通知);3. 通过ApplicationEventPublisher的publishEvent()方法发布事件。Spring会在事务提交后默认同步处理事件,若需异步执行可在监听方法添加@Async注解并启用异步支持。例如电商场景中,订单服务完成创建后发布订单事件,支付服务和物流服务分别监听处理各自业务逻辑,实现松耦合架构。
9、Spring中的事务事件如何使用?
@Service
public class UserService {
@Autowired
private ApplicationEventPublisher eventPublisher;
@Transactional
public void registerUser(User user) {
// 用户注册逻辑
// 发布用户注册事件
UserRegistrationEvent registrationEvent = new UserRegistrationEvent(user);
eventPublisher.publishEvent(registrationEvent);
}
}
@Component
public class UserRegistrationEventListener {
@TransactionalEventListener
public void handleUserRegistrationEvent(UserRegistrationEvent event) {
// 事务成功提交后执行的逻辑
sendWelcomeEmail(event.getUser());
}
private void sendWelcomeEmail(User user) {
// 发送欢迎邮件
}
}
10、为什么不建议直接使用Spring的@Async
11、什么是Spring的三级缓存
public class DefaultSingletonBeanRegistry
extends SimpleAliasRegistry implements SingletonBeanRegistry {
//一级缓存,保存完成的Bean对象
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
//二级缓存,存储"半成品"的Bean对象
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);
//三级缓存,保存单例Bean的创建工厂
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
}
12、三级缓存是如何解决循环依赖的问题的?
13、SpringBoot如何做优雅停机?
二、语雀-MySQL面试题
1、唯一索引和主键索引的区别?
2. 区别
唯一索引和主键索引的核心区别在于:主键要求列值唯一且非空(NULL),且一个表只能有一个主键,通常自动创建聚簇索引(数据物理顺序与索引一致),并用于表间关联;唯一索引仅要求列值唯一(允许存在NULL),可创建多个,多为非聚簇索引,主要用于确保特定字段的唯一性(如邮箱、手机号)。 主键更强调实体完整性,而唯一索引侧重数据唯一性约束。
2、一个查询语句的执行顺序是怎么样的?
3、on和where有什么区别?
4、InnoDB中的表级锁、页级锁、行级锁?
在数据库中,有各种各样的锁,按锁的粒度划分,可分为全局锁、表级锁、行级锁和页级锁。
在InnoDB中,有全局锁、表级锁、行级锁,但是是不支持页级锁的。
1. 全局锁
2. 表级锁
2.1 意向锁
2.2 AUTO-INC锁
2.3 字典锁
2.4 表级排他&共享锁
5、高并发情况下自增主键会不会重复,为什么?
6、从 innodb 的索引结构分析,为什么索引的 key 长度不能太长?
✅从 innodb 的索引结构分析,为什么索引的 key 长度不能太长?
7、什么是索引合并,原理是什么?
8、MySQL为什么会有存储(内存)碎片?有什么危害?
1. insert 导致的碎片
2. 碎片危害
3. 如何避免碎片
4. 如何清理碎片
9、A,B,C的联合索引,按照 AB,AC,BC查询,能走索引吗?
✅A,B,C的联合索引,按照 AB,AC,BC查询,能走索引吗?