中科创达 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面试圣经,带你练透java圣经

全部评论
二面也是技术?
点赞 回复 分享
发布于 04-24 14:57 重庆
27届实习机会或看我住业 https://careers.pddglobalhr.com/campus/intern?t=4OmKPVeX9a
点赞 回复 分享
发布于 03-11 17:32 上海
太强了
点赞 回复 分享
发布于 02-10 15:16 辽宁
mark
点赞 回复 分享
发布于 02-10 15:16 北京

相关推荐

📍面试公司:易点云🕐面试时间:03/06💻面试岗位:Java❓面试问题1. 实习经历里头包括项目,你可以详细说一说,比如做过哪些内容?2. 你在新版 OpenAPI 升级中封装了核心接口,降低 40% 对接成本,具体做了哪些封装优化?3. 封装优化后,老接口是怎么修改的?遇到过哪些兼容性问题?怎么解决的?4. 关键字+向量语义的混合检索引擎,具体实践逻辑是什么?5. RAG 检索底座是如何为大模型智能排错提供上下文的?(实现方式)6. 浅拷贝和深拷贝的区别?7. 什么是反射?反射有哪些应用场景?8. 常见的 IO 模型有哪些?9. 你对线程池的了解?如何创建?工作流程是怎样的?10. 线程池的工作流程(追问)?11. 线程池的参数如何考虑和设置?12. 讲讲 JVM 的内存结构模型、垃圾回收算法、垃圾回收过程?13. 实习或工作中有没有遇到过 GC 频繁的问题?如何快速排查和解决?14. MySQL 的隔离级别有哪些?15. 这些隔离级别分别解决了哪些问题?16. 一条查询语句在 MySQL 中的完整执行流程是怎样的?17. 哪些情况会导致索引失效?18. 了解 Elasticsearch 吗?它适合什么场景?有哪些特点?19. 如果把 MySQL 数据同步到 ES(如订单模糊查询),如何保证数据一致性?20. Redis 有哪些使用场景?21. 了解哪些消息队列?它们的使用场景和优势分别是什么?---🙌面试感想面完无推进,纯八股。公司大小周,而且听说很高压。我也不是很想去,所以止于一面。
查看21道真题和解析
点赞 评论 收藏
分享
评论
2
32
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务