中科创达 Java开发 二面 面经
1. 介绍一下Spring Boot的自动配置原理
Spring Boot的自动配置主要基于以下几个核心机制:
① @SpringBootApplication注解:这是一个组合注解,包含了@SpringBootConfiguration、@EnableAutoConfiguration和@ComponentScan三个注解
② @EnableAutoConfiguration的工作原理:
- 通过@Import注解导入AutoConfigurationImportSelector类
- 该类会读取META-INF/spring.factories文件中的配置类
- 加载所有候选的自动配置类
③ 条件注解机制:
- 使用@ConditionalOnClass判断类路径下是否存在某个类
- 使用@ConditionalOnBean判断容器中是否存在某个Bean
- 使用@ConditionalOnProperty判断配置文件中是否有某个属性
- 只有满足条件的配置类才会生效
④ 配置优先级:用户自定义的配置优先级高于自动配置,可以通过application.properties覆盖默认配置
⑤ 实际应用:比如引入spring-boot-starter-web依赖后,会自动配置Tomcat、DispatcherServlet等组件,无需手动配置
2. 说说你对Redis的理解,以及常见的应用场景
Redis是一个基于内存的高性能键值数据库,我从以下几个方面理解:
① 数据结构丰富:
- String:最基本的类型,可以存储字符串、数字
- Hash:适合存储对象
- List:有序列表,可以实现队列和栈
- Set:无序集合,支持交并差运算
- ZSet:有序集合,可以实现排行榜
② 持久化机制:
- RDB:定期生成快照,恢复速度快但可能丢失数据
- AOF:记录每个写操作,数据更安全但文件较大
- 可以同时使用两种方式
③ 常见应用场景:
- 缓存:减轻数据库压力,提高响应速度
- 分布式锁:使用SETNX实现
- 消息队列:使用List或Stream实现
- 排行榜:使用ZSet的score排序
- 计数器:使用INCR原子操作
- Session共享:分布式系统中存储用户会话
④ 缓存问题及解决方案:
- 缓存穿透:查询不存在的数据,解决方法是布隆过滤器或缓存空值
- 缓存击穿:热点key过期,解决方法是互斥锁或永不过期
- 缓存雪崩:大量key同时过期,解决方法是过期时间加随机值
3. 讲一下MySQL的事务隔离级别,以及会产生什么问题
MySQL的事务隔离级别从低到高分为四种:
① 读未提交(Read Uncommitted):
- 最低的隔离级别
- 会产生脏读问题:事务A读到了事务B未提交的数据
- 基本不使用
② 读已提交(Read Committed):
- 只能读取已提交的数据
- 解决了脏读问题
- 会产生不可重复读:事务A两次读取同一数据结果不同,因为事务B在中间修改并提交了
- Oracle默认级别
③ 可重复读(Repeatable Read):
- 保证在同一事务中多次读取同一数据结果一致
- 解决了不可重复读问题
- 会产生幻读:事务A查询某个范围的数据,事务B插入了新数据,事务A再次查询发现多了数据
- MySQL默认级别,通过MVCC和间隙锁解决了幻读
④ 串行化(Serializable):
- 最高的隔离级别
- 强制事务串行执行
- 解决了所有并发问题
- 性能最差,很少使用
⑤ MySQL的实现机制:
- 使用MVCC(多版本并发控制)实现读已提交和可重复读
- 每行数据有隐藏的版本号字段
- 读取时根据版本号判断数据可见性
- 避免了加锁,提高了并发性能
4. 分布式系统中如何保证接口的幂等性?
接口幂等性是指多次调用产生的结果与单次调用一致,实现方式有:
① 数据库唯一索引:
- 在数据库表中建立唯一索引
- 重复插入会抛出异常
- 适用于插入操作
② Token机制:
- 客户端先请求获取Token
- 提交时携带Token
- 服务端验证Token并删除
- 重复提交因为Token已被删除而失败
- 适用于表单提交
③ 分布式锁:
- 使用Redis的SETNX或Redisson实现
- 获取锁成功才执行业务
- 执行完释放锁
- 适用于高并发场景
④ 状态机:
- 通过状态流转控制
- 比如订单状态:待支付→已支付→已发货
- 已支付状态不能再次支付
- 适用于有明确状态流转的业务
⑤ 乐观锁:
- 使用版本号version字段
- 更新时判断version是否一致
- 不一致说明数据已被修改
- 适用于更新操作
⑥ 去重表:
- 建立专门的去重表记录请求ID
- 每次请求先查询是否存在
- 存在则直接返回
- 适用于需要记录请求历史的场景
5. 说说你对微服务架构的理解,以及遇到过什么问题
微服务架构是将单体应用拆分成多个小服务的架构模式:
① 核心特点:
- 服务独立部署:每个服务可以独立发布
- 技术栈灵活:不同服务可以用不同技术
- 数据库独立:每个服务有自己的数据库
- 按业务拆分:根据业务领域划分服务
② 常用组件:
- 注册中心:Nacos、Eureka,实现服务注册与发现
- 配置中心:Nacos、Apollo,统一管理配置
- 网关:Gateway、Zuul,统一入口和路由
- 负载均衡:Ribbon、LoadBalancer
- 熔断降级:Sentinel、Hystrix
- 链路追踪:Skywalking、Zipkin
③ 遇到的问题及解决方案:
- 分布式事务:使用Seata实现AT模式或TCC模式,或者采用最终一致性方案
- 服务雪崩:通过Sentinel设置熔断降级规则,快速失败保护系统
- 数据一致性:使用消息队列实现最终一致性,或者使用分布式锁
- 接口调用复杂:使用OpenFeign简化HTTP调用,声明式调用
- 服务拆分粒度:遵循单一职责原则,不能拆得过细也不能过粗
④ 优缺点:
- 优点:独立部署、技
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
Java面试圣经,带你练透java圣经
