1. Java后端框架面试核心要点解析作为Java后端开发的三大核心框架Spring、SpringMVC和MyBatis构成了现代企业级应用的基础架构。在技术面试中对这些框架的理解深度直接决定了候选人的竞争力等级。我整理了实际面试中最常被问及的20个核心问题并附上深度解析和实战经验。1.1 Spring框架核心机制Spring的核心价值在于其IoC控制反转和AOP面向切面编程的实现机制。面试官最常问的问题是Spring如何实现依赖注入 这里需要区分构造器注入和setter注入两种方式// 构造器注入示例 Service public class UserService { private final UserRepository userRepository; Autowired public UserService(UserRepository userRepository) { this.userRepository userRepository; } } // setter注入示例 Service public class OrderService { private PaymentService paymentService; Autowired public void setPaymentService(PaymentService paymentService) { this.paymentService paymentService; } }重要提示Spring 4.3版本中如果类只有一个构造器Autowired注解可以省略。但显式声明能让代码意图更清晰。循环依赖是另一个高频考点。Spring通过三级缓存解决这个问题singletonObjects存放完全初始化好的beanearlySingletonObjects存放早期引用已实例化但未初始化singletonFactories存放ObjectFactory面试时需要能说清楚解决过程当A依赖BB又依赖A时Spring会先创建A的原始对象放入三级缓存然后在注入B时发现需要A就从缓存中获取A的早期引用完成B的创建后再回头完善A的初始化。1.2 SpringMVC请求处理流程SpringMVC的工作流程可以用七个步骤概括DispatcherServlet接收HTTP请求调用HandlerMapping确定处理程序通过HandlerAdapter执行处理器处理器调用业务逻辑返回ModelAndView通过ViewResolver解析视图渲染视图返回响应面试时经常需要手绘这个流程图。有个容易忽略的细节是HandlerInterceptor的执行时机preHandle处理器执行前postHandle处理器执行后视图渲染前afterCompletion请求完成后Configuration public class WebConfig implements WebMvcConfigurer { Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LogInterceptor()) .addPathPatterns(/api/**) .excludePathPatterns(/static/**); } }1.3 MyBatis核心工作原理MyBatis的面试重点在于其SQL与Java对象的映射机制。需要掌握的核心概念包括SqlSessionFactoryBuilder读取配置构建工厂SqlSessionFactory生产SqlSessionSqlSession执行CRUD操作Executor执行器接口MappedStatement封装SQL信息一个典型的问题#{}和${}的区别是什么 答案要点#{}使用预编译PreparedStatement防止SQL注入${}直接拼接SQL适用于动态表名等场景优先使用#{}必须用${}时要做好过滤!-- 动态SQL示例 -- select idfindUsers resultTypeUser SELECT * FROM users where if testname ! null AND name LIKE #{name} /if if teststatus ! null AND status #{status} /if /where ORDER BY create_time DESC /select1.4 MyBatis-Plus增强特性MyBatis-Plus在MyBatis基础上提供了更多开箱即用的功能。高频问题包括条件构造器的使用// Lambda表达式写法 ListUser users userMapper.selectList( Wrappers.UserlambdaQuery() .eq(User::getStatus, 1) .like(User::getName, 张) .between(User::getCreateTime, startDate, endDate) );自动填充功能实现Slf4j Component public class MyMetaObjectHandler implements MetaObjectHandler { Override public void insertFill(MetaObject metaObject) { this.strictInsertFill(metaObject, createTime, LocalDateTime.class, LocalDateTime.now()); } Override public void updateFill(MetaObject metaObject) { this.strictUpdateFill(metaObject, updateTime, LocalDateTime.class, LocalDateTime.now()); } }分页插件配置Configuration public class MybatisPlusConfig { Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); return interceptor; } }2. 高级特性与性能优化2.1 Spring事务管理面试中关于事务的问题通常会深入到传播行为和隔离级别。需要掌握的要点七种传播行为REQUIRED默认当前有事务就加入没有就新建REQUIRES_NEW新建事务挂起当前事务NESTED嵌套事务外层回滚会影响内层隔离级别与问题READ_UNCOMMITTED可能脏读READ_COMMITTED避免脏读可能不可重复读REPEATABLE_READ避免不可重复读可能幻读SERIALIZABLE最高隔离级别Service public class OrderService { Transactional( propagation Propagation.REQUIRED, isolation Isolation.READ_COMMITTED, timeout 30, rollbackFor Exception.class ) public void createOrder(OrderDTO dto) { // 业务逻辑 } }常见陷阱同类中方法调用事务失效问题。这是因为Spring事务基于AOP实现自调用会绕过代理。解决方法将方法拆分到不同类通过AopContext获取当前代理需要开启exposeProxy2.2 MyBatis缓存机制MyBatis提供了一级缓存和二级缓存一级缓存SqlSession级别默认开启二级缓存Mapper级别需要手动配置面试常问如何保证缓存一致性 解决方案对写操作多的表关闭二级缓存使用 建立关联Mapper的缓存引用实现自定义缓存如Redis!-- 二级缓存配置示例 -- mapper namespacecom.example.mapper.UserMapper cache evictionLRU flushInterval60000 size512 readOnlytrue/ select idselectById resultTypeUser useCachetrue SELECT * FROM user WHERE id #{id} /select /mapper2.3 SpringBoot自动配置原理SpringBoot的魔法在于SpringBootApplication注解它实际上是三个注解的组合SpringBootConfiguration标识为配置类EnableAutoConfiguration启用自动配置ComponentScan组件扫描自动配置的关键在于spring.factories文件其中定义了各种AutoConfiguration类。面试时需要能解释条件注解的作用ConditionalOnClass类路径存在指定类时生效ConditionalOnMissingBean容器中没有指定Bean时生效ConditionalOnProperty配置属性满足条件时生效// 自定义starter示例 Configuration ConditionalOnClass(MyService.class) EnableConfigurationProperties(MyProperties.class) public class MyAutoConfiguration { Bean ConditionalOnMissingBean public MyService myService(MyProperties properties) { return new MyService(properties); } }3. 框架整合与实战问题3.1 SpringBoot整合MyBatis-Plus整合过程中的常见问题及解决方案多数据源配置Configuration MapperScan(basePackages com.example.mapper.db1, sqlSessionTemplateRef db1SqlSessionTemplate) public class Db1DataSourceConfig { Bean ConfigurationProperties(spring.datasource.db1) public DataSource db1DataSource() { return DataSourceBuilder.create().build(); } Bean public SqlSessionFactory db1SqlSessionFactory(Qualifier(db1DataSource) DataSource dataSource) throws Exception { MybatisSqlSessionFactoryBean factory new MybatisSqlSessionFactoryBean(); factory.setDataSource(dataSource); factory.setMapperLocations(new PathMatchingResourcePatternResolver() .getResources(classpath:mapper/db1/*.xml)); return factory.getObject(); } Bean public SqlSessionTemplate db1SqlSessionTemplate( Qualifier(db1SqlSessionFactory) SqlSessionFactory sqlSessionFactory) { return new SqlSessionTemplate(sqlSessionFactory); } }分页插件冲突 当同时使用MyBatis和MyBatis-Plus时需要确保只启用一个分页插件。推荐使用MyBatis-Plus的插件Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor new MybatisPlusInterceptor(); // 分页插件 interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); // 乐观锁插件 interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor()); return interceptor; }3.2 性能优化技巧SQL优化使用 标签重用SQL片段避免SELECT *只查询需要的字段合理使用 批量操作sql iduserColumnsid,name,email/sql select idselectUserList resultTypeUser SELECT include refiduserColumns/ FROM user WHERE status 1 /select连接池配置spring: datasource: hikari: maximum-pool-size: 20 minimum-idle: 5 connection-timeout: 30000 idle-timeout: 600000 max-lifetime: 1800000延迟加载策略mybatis: configuration: lazy-loading-enabled: true aggressive-lazy-loading: false4. 高频面试题深度解析4.1 Spring Bean生命周期完整的生命周期包括实例化Bean属性赋值依赖注入调用Aware接口方法BeanNameAware等BeanPostProcessor前置处理初始化方法PostConstruct、InitializingBeanBeanPostProcessor后置处理使用Bean销毁PreDestroy、DisposableBean面试时需要能画出这个流程图并解释关键扩展点。例如BeanPostProcessor的典型应用Component public class CustomBeanPostProcessor implements BeanPostProcessor { Override public Object postProcessBeforeInitialization(Object bean, String beanName) { if(bean instanceof MyService) { System.out.println(初始化MyService前处理); } return bean; } Override public Object postProcessAfterInitialization(Object bean, String beanName) { if(bean instanceof MyService) { System.out.println(初始化MyService后处理); } return bean; } }4.2 动态数据源路由实现多租户等场景下的动态数据源切换public class DynamicDataSource extends AbstractRoutingDataSource { Override protected Object determineCurrentLookupKey() { return DynamicDataSourceContextHolder.getDataSourceKey(); } } // 使用AOP切换数据源 Aspect Component Order(1) // 确保在事务注解前执行 public class DataSourceAspect { Before(annotation(ds)) public void beforeSwitchDS(DataSource ds) { DynamicDataSourceContextHolder.setDataSourceKey(ds.value()); } After(annotation(ds)) public void afterSwitchDS(DataSource ds) { DynamicDataSourceContextHolder.clearDataSourceKey(); } }4.3 分布式事务方案本地消息表业务与消息在同一个事务中提交定时任务补偿失败的消息Seata AT模式GlobalTransactional public void crossServiceOperation() { serviceA.update(); serviceB.update(); }最大努力通知先执行本地事务异步通知其他系统定时重试未成功的通知5. 框架对比与选型建议5.1 MyBatis vs MyBatis-Plus特性对比表特性MyBatisMyBatis-PlusCRUD接口需手动实现内置通用Mapper条件构造器无强大的Wrapper分页插件需额外配置内置代码生成器无内置乐观锁支持手动实现Version注解SQL注入器无支持扩展选型建议简单项目或需要高度定制SQL选择MyBatis快速开发或需要通用CRUD选择MyBatis-Plus复杂查询场景两者可以混合使用5.2 SpringMVC vs WebFlux响应式编程成为新趋势但传统SpringMVC仍是主流维度SpringMVCWebFlux编程模型命令式响应式线程模型每个请求占用一个线程少量线程处理所有请求适用场景传统CRUD应用高并发IO密集型应用学习曲线平缓较陡峭生态支持完善正在发展中迁移建议现有项目保持SpringMVC新项目根据团队技术储备选择网关、消息推送等场景优先考虑WebFlux6. 实战经验与避坑指南6.1 事务失效的常见场景方法非public修饰Spring AOP要求代理方法必须是public自调用问题类内部方法调用不会经过代理异常类型不匹配默认只回滚RuntimeException数据库引擎不支持如MyISAM不支持事务多线程调用事务上下文是线程绑定的解决方案示例// 通过AopContext解决自调用问题 Transactional public void methodA() { ((MyService) AopContext.currentProxy()).methodB(); } Transactional(propagation Propagation.REQUIRES_NEW) public void methodB() { // 业务逻辑 }6.2 MyBatis批量操作优化低效做法for (User user : userList) { userMapper.insert(user); }高效方案使用foreach标签insert idbatchInsert INSERT INTO user(name,age) VALUES foreach collectionlist itemitem separator, (#{item.name},#{item.age}) /foreach /insert使用ExecutorType.BATCHSqlSession sqlSession sqlSessionFactory.openSession(ExecutorType.BATCH); try { UserMapper mapper sqlSession.getMapper(UserMapper.class); for (User user : userList) { mapper.insert(user); } sqlSession.commit(); } finally { sqlSession.close(); }6.3 线上问题排查技巧SQL慢查询开启MyBatis日志logging.level.com.example.mapperDEBUG使用EXPLAIN分析执行计划添加合适的索引内存泄漏检查大对象持有如静态Map分析MyBatis一级缓存是否过大使用VisualVM或Arthas诊断连接池耗尽检查是否有连接未关闭调整连接池参数使用druid的监控功能# druid监控配置 spring: datasource: druid: stat-view-servlet: enabled: true url-pattern: /druid/* web-stat-filter: enabled: true url-pattern: /*7. 最新趋势与扩展学习7.1 Spring生态新特性Spring Native支持GraalVM原生镜像编译启动时间从秒级降到毫秒级内存占用减少50%以上适合Serverless场景Spring AI集成人工智能能力提供统一的AI接口支持多种大语言模型简化AI应用开发RestController public class AIController { private final ChatClient chatClient; public AIController(ChatClient chatClient) { this.chatClient chatClient; } GetMapping(/ai/chat) public String chat(RequestParam String message) { return chatClient.call(message); } }7.2 MyBatis-Plus新功能数据安全保护字段加解密数据脱敏防全表更新删除多租户支持public class MyTenantLineHandler implements TenantLineHandler { Override public String getTenantIdColumn() { return tenant_id; } Override public Expression getTenantId() { return new StringValue(当前租户ID); } Override public boolean ignoreTable(String tableName) { return !user.equalsIgnoreCase(tableName); } }动态表名支持public class MyTableNameHandler implements TableNameHandler { Override public String dynamicTableName(String sql, String tableName) { return tableName _ LocalDate.now().getYear(); } }8. 面试准备策略8.1 知识体系构建建议按以下顺序准备基础概念IoC、AOP、ORM等核心原理Bean生命周期、MVC流程、SQL映射高级特性事务、缓存、性能优化框架整合SpringBootMyBatis-Plus分布式扩展分库分表、分布式事务最新趋势响应式、云原生、AI集成8.2 项目经验提炼准备2-3个典型项目案例性能优化案例问题描述接口响应慢分析过程定位到N1查询问题解决方案使用 优化关联查询成果响应时间从2s降到200ms复杂业务实现需求多租户数据隔离实现动态数据源MyBatis-Plus多租户插件难点跨库事务处理线上问题排查现象数据库连接池耗尽排查发现未关闭的SqlSession修复统一使用try-with-resources8.3 模拟面试练习常见问题分类练习基础概念类Spring Bean的作用域有哪些MyBatis如何防止SQL注入原理机制类Spring如何解决循环依赖MyBatis一级缓存和二级缓存的区别实战经验类如何优化MyBatis批量插入性能遇到过哪些事务失效的场景如何解决的场景设计类设计一个多数据源动态切换的方案如何实现一个分布式ID生成器练习时注意先给出简明扼要的定义再深入原理和实现细节最后结合实际案例说明遇到不会的问题展示分析思路9. 推荐学习资源9.1 官方文档Spring Framework核心容器https://docs.spring.io/spring-framework/docs/current/reference/html/core.htmlAOP编程https://docs.spring.io/spring-framework/docs/current/reference/html/aop.htmlMyBatisXML配置https://mybatis.org/mybatis-3/configuration.html动态SQLhttps://mybatis.org/mybatis-3/dynamic-sql.htmlMyBatis-Plus快速开始https://baomidou.com/guide/核心功能https://baomidou.com/guide/wrapper.html9.2 源码学习路线Spring源码阅读顺序BeanDefinition解析Bean创建流程依赖注入实现AOP代理机制事务管理实现MyBatis源码重点SqlSession创建过程Executor执行流程插件拦截机制缓存实现原理调试技巧从单元测试入手使用条件断点关注核心接口和实现类绘制调用链路图9.3 实战项目推荐电商系统技术栈SpringBootMyBatis-PlusRedis亮点秒杀设计、分布式事务权限管理系统技术栈SpringSecurityJWT亮点RBAC模型、动态权限控制数据可视化平台技术栈SpringWebFluxWebSocket亮点实时数据推送、大屏展示10. 面试后的持续提升10.1 技术深度拓展Spring扩展点研究BeanFactoryPostProcessorBeanPostProcessorImportSelectorMyBatis插件开发Intercepts({ Signature(type Executor.class, methodupdate, args{MappedStatement.class,Object.class}) }) public class MyPlugin implements Interceptor { Override public Object intercept(Invocation invocation) throws Throwable { // 前置处理 Object result invocation.proceed(); // 后置处理 return result; } }自定义Starter开发定义自动配置类编写spring.factories打包发布10.2 技术广度扩展云原生技术栈Docker容器化Kubernetes编排Service Mesh响应式编程Reactor核心概念WebFlux实战R2DBC数据库访问领域驱动设计分层架构聚合根设计领域事件10.3 社区参与建议贡献方式文档翻译示例项目Issue排查PR提交优质社区Spring官方论坛MyBatis项目GitHub技术博客平台技术分享内部技术沙龙社区Meetup技术大会在实际面试中我发现很多候选人虽然能回答基础问题但缺乏对框架设计理念的深入理解。比如Spring的约定优于配置原则或是MyBatisSQL与代码分离的哲学。这些深层次的理解往往能让你在高级岗位面试中脱颖而出。建议在准备面试时不仅要掌握如何使用这些框架更要思考它们为什么这样设计以及如何在自己的项目中应用这些设计理念。