AIGC标识 Java架构师100道面试题

Java高级工程师面试题100道(含详细答案)


一、Spring基础框架(20题)

1. Spring框架的核心模块有哪些?它们的作用分别是什么?

答案:

Spring框架由多个核心模块组成,主要分为以下几大类:

  1. 核心容器(Core Container)

    • Spring Core:框架的基础模块,提供IOC容器和依赖注入功能
    • Spring Beans:提供BeanFactory,是工厂模式的实现
    • Spring Context:构建在Core和Beans模块之上,是配置文件的核心抽象
    • Spring Expression Language (SpEL):提供表达式语言,可以在运行时查询和操作对象图
  2. 数据访问/集成(Data Access/Integration)

    • JDBC:抽象了JDBC操作,简化数据库访问
    • ORM:支持ORM框架如Hibernate、MyBatis等
    • JMS:Java消息服务,支持消息传递
    • Transactions:支持编程式和声明式事务管理
  3. Web

    • Spring Web:提供基础的Web开发功能
    • Spring MVC:实现Web层的MVC框架
    • Spring WebFlux:响应式Web框架
  4. AOP

    • Spring AOP:面向切面编程,支持声明式事务、安全等功能
  5. 测试

    • Spring Test:支持JUnit和TestNG进行测试
  6. 其他

    • Spring Security:安全框架
    • Spring Boot:快速开发框架
    • Spring Cloud:微服务解决方案

2. 详细解释Spring IOC容器的原理

答案:

IOC(Inversion of Control,控制反转) 是Spring框架的核心概念之一。

原理:

  1. 什么是IOC

    • 传统开发:对象A需要对象B,由A自己创建B
    • IOC:对象A需要对象B,由Spring容器创建并注入给A
    • 控制反转:将对象的创建权交给容器,而不是在代码中new
  2. IOC容器

    • BeanFactory:最基础的IOC容器,延迟加载Bean
    • ApplicationContext:BeanFactory的子接口,功能更强大,启动时立即创建Bean
  3. Bean的生命周期

    实例化Bean → 属性填充 → 初始化 → 使用Bean → 销毁Bean
    

    详细过程:

    • 实例化:通过构造函数或工厂方法创建Bean实例
    • 属性填充:将Bean依赖的属性注入(@Autowired、setter注入等)
    • 初始化:
      • 如果Bean实现了BeanNameAware,调用setBeanName()
      • 如果Bean实现了BeanFactoryAware,调用setBeanFactory()
      • 调用BeanPostProcessor的postProcessBeforeInitialization()
      • 调用init-method方法或@PostConstruct注解方法
      • 调用BeanPostProcessor的postProcessAfterInitialization()
    • 使用Bean:Bean可以正常使用
    • 销毁Bean:
      • 调用destroy-method方法或@PreDestroy注解方法
      • 如果Bean实现了DisposableBean,调用destroy()
  4. 循环依赖解决

    • Spring通过三级缓存解决循环依赖
    • singletonObjects:存储完全初始化的Bean
    • earlySingletonObjects:存储原始Bean实例(未完成初始化)
    • singletonFactories:存储Bean工厂,用于获取早期引用
    • 当A依赖B、B依赖A时:
      1. 实例化A,将A的工厂放入singletonFactories
      2. 填充A的属性,发现需要B
      3. 实例化B,填充B的属性,发现需要A
      4. 从singletonFactories获取A的早期引用(未初始化)
      5. 完成B的初始化,放回singletonObjects
      6. 完成A的初始化

3. Spring Bean的作用域有哪些?

答案:

Spring Bean有以下几种作用域:

  1. singleton(单例):默认作用域,Spring容器中只有一个Bean实例,所有请求共享
  2. prototype(原型):每次请求都创建一个新的Bean实例
  3. request:每个HTTP请求创建一个Bean实例,仅适用于Web环境
  4. session:每个HTTP Session创建一个Bean实例,仅适用于Web环境
  5. application:每个ServletContext创建一个Bean实例,仅适用于Web环境
  6. websocket:每个WebSocket会话创建一个Bean实例,仅适用于Web环境

使用示例:

@Component
@Scope("prototype")
public class MyBean {
    // 每次请求创建新实例
}

4. Spring中依赖注入的几种方式

答案:

Spring支持多种依赖注入方式:

  1. 构造器注入

    @Component
    public class UserService {
        private final UserRepository repository;
        
        @Autowired
        public UserService(UserRepository repository) {
            this.repository = repository;
        }
    }
    
    • 优点:保证依赖不可变,适合必填依赖
    • 推荐:优先使用构造器注入
  2. Setter注入

    @Component
    public class UserService {
        @Autowired
        private UserRepository repository;
        
        @Autowired
        public void setRepository(UserRepository repository) {
            this.repository = repository;
        }
    }
    
    • 优点:可选依赖,支持Bean的重新注入
    • 适用:可选依赖或需要重新注入的场景
  3. 字段注入

    @Component
    public class UserService {
        @Autowired
        private UserRepository repository;
    }
    
    • 优点:简洁,代码量少
    • 缺点:不直观,难以测试,不利于不可变性
  4. 方法注入

    @Component
    public class UserService {
        @Autowired
        public void init(UserRepository repository) {
            // 初始化逻辑
        }
    }
    
  5. 通过XML配置注入

    <bean id="userService" class="com.example.UserService">
        <property name="repository" ref="userRepository"/>
    </bean>
    

最佳实践:

  • 优先使用构造器注入(确保依赖不可变)
  • 可选依赖使用Setter注入
  • 不推荐使用字段注入(不利于测试和维护)

5. Spring AOP的原理和应用场景

答案:

AOP(Aspect-Oriented Programming,面向切面编程) 是将横切关注点从业务逻辑中分离出来的技术。

原理:

  1. 动态代理

    • Spring AOP默认使用JDK动态代理(针对接口)
    • 如果没有接口,使用CGLIB(继承类)
    • 可以通过配置强制使用CGLIB
  2. 核心概念

    • Aspect(切面):横切关注点的模块化,如日志、事务
    • Join Point(连接点):程序执行的某个特定位置,如方法调用、异常处理
    • Pointcut(切入点):匹配连接点的表达式,决定切面在哪些地方执行
    • Advice(通知):切面在特定连接点执行的动作
    • Weaving(织入):将切面应用到目标对象的过程
  3. 通知类型

    • @Before:前置通知,在方法执行前执行
    • @After:后置通知,在方法执行后执行
    • @AfterReturning:返回通知,在方法成功返回后执行
    • @AfterThrowing:异常通知,在方法抛出异常后执行
    • @Around:环绕通知,包裹方法执行,可以决定是否执行方法
  4. 应用场景

    @Aspect
    @Component
    public class LogAspect {
        
        @Pointcut("execution(* com.example.service.*.*(..))")
        public void serviceMethod() {}
        
        @Before("serviceMethod()")
        public void logBefore(JoinPoint joinPoint) {
            System.out.println("方法执行前:" + joinPoint.getSignature().getName());
        }
        
        @Around("serviceMethod()")
        public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
            long startTime = System.currentTimeMillis();
            Object result = joinPoint.proceed();
            long endTime = System.currentTimeMillis();
            System.out.println("执行时间:" + (endTime - startTime) + "ms");
            return result;
        }
    }
    

典型应用:

  • 日志记录
  • 事务管理
  • 权限校验
  • 性能监控
  • 异常处理

6. Spring事务管理的原理

答案:

Spring事务管理 的核心是声明式事务,通过AOP实现。

原理:

  1. 事务传播行为(Propagation)

    • REQUIRED(默认):如果当前有事务,则加入;否则创建新事务
    • REQUIRES_NEW:创建新事务,挂起当前事务
    • SUPPORTS:如果当前有事务,则加入;否则非事务执行
    • NOT_SUPPORTED:非事务执行,挂起当前事务
    • MANDATORY:必须在事务中执行,否则抛异常
    • NEVER:必须非事务执行,否则抛异常
    • NESTED:如果当前有事务,则在嵌套事务中执行
  2. 事务隔离级别(Isolation)

    • DEFAULT:使用数据库默认隔离级别
    • READ_UNCOMMITTED:可以读取未提交的数据(脏读)
    • READ_COMMITTED:只能读取已提交的数据(避免脏读)
    • REPEATABLE_READ:可重复读(避免脏读和不可重复读)
    • SERIALIZABLE:串行化(最安全,性能最低)
  3. 事务注解

    @Service
    public class UserService {
        
        @Transactional(
            propagation = Propagation.REQUIRED,
            isolation = Isolation.READ_COMMITTED,
            rollbackFor = Exception.class,
            timeout = 30
        )
        public void transferMoney(Long fromId, Long toId, BigDecimal amount) {
            // 转账逻辑
        }
    }
    
  4. 原理实现

    • Spring通过动态代理实现事务管理
    • 使用TransactionInterceptor作为通知
    • PlatformTransactionManager是事务管理器接口
    • 事务在方法调用前开始,方法正常返回后提交,异常时回滚
  5. 注意事项

    • @Transactional只能作用于public方法
    • 同一类中方法调用不会触发事务(self-invocation问题)
    • 异常被捕获后不会触发回滚
    • 建议指定rollbackFor以避免受检异常不回滚的问题

7. Spring MVC的工作流程

答案:

Spring MVC是一个基于请求的Web框架,工作流程如下:

  1. 客户端发送请求到DispatcherServlet(前端控制器)
  2. DispatcherServlet查询HandlerMapping,找到处理该请求的Controller
  3. HandlerMapping返回处理器执行链(包括Controller和拦截器)
  4. DispatcherServlet调用HandlerAdapter执行Controller
  5. Controller执行业务逻辑,返回ModelAndView
  6. DispatcherServlet将ModelAndView传递给ViewResolver
  7. ViewResolver解析视图,返回具体的View对象
  8. DispatcherServlet使用Model填充View,渲染页面
  9. DispatcherServlet将响应返回给客户端

核心组件:

组件 作用
DispatcherServlet 前端控制器,协调各组件
HandlerMapping 映射请求到处理器
HandlerAdapter 适配不同类型的处理器
Controller 处理请求,返回ModelAndView
ViewResolver 解析视图名称到具体视图
View 渲染视图,生成响应
Interceptor 拦截器,处理预处理和后处理

示例:

@Controller
public class UserController {
    
    @Autowired
    private UserService userService;
    
    @GetMapping("/user/{id}")
    public String getUser(@PathVariable Long id, Model model) {
        User user = userService.getUserById(id);
        model.addAttribute("user", user);
        return "user/detail"; // ViewResolver会解析为/user/detail.jsp
    }
}

8. Spring Boot自动配置原理

答案:

Spring Boot自动配置 是Spring Boot的核心特性,根据classpath上的依赖自动配置Spring应用。

原理:

  1. @SpringBootApplication注解

    @SpringBootApplication
    public class Application {
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
        }
    }
    

    该注解是三个注解的组合:

    • @SpringBootConfiguration:标识为配置类
    • @EnableAutoConfiguration:启用自动配置
    • @ComponentScan:组件扫描
  2. @EnableAutoConfiguration

    • 通过@Import(AutoConfigurationImportSelector.class)导入自动配置类
    • AutoConfigurationImportSelector读取META-INF/spring.factories文件
    • 加载EnableAutoConfiguration对应的所有配置类
  3. 条件注解

    • @ConditionalOnClass:classpath上有该类时才生效
    • @ConditionalOnMissingBean:容器中不存在该Bean时才生效
    • @ConditionalOnProperty:配置属性满足条件时才生效
    • @ConditionalOnWebApplication:Web应用时才生效
  4. 自动配置示例

    @Configuration
    @ConditionalOnClass({DataSource.class, JdbcTemplate.class})
    @AutoConfigureAfter(DataSourceAutoConfiguration.class)
    public class JdbcTemplateAutoConfiguration {
        
        @Bean
        @ConditionalOnMissingBean
        public JdbcTemplate jdbcTemplate(DataSource dataSource) {
            return new JdbcTemplate(dataSource);
        }
    }
    
  5. 工作原理流程

    启动Spring Boot
    → 读取@SpringBootApplication
    → 执行@EnableAutoConfiguration
    → 加载spring.factories
    → 筛选条件满足的配置类
    → 注册Bean到容器
    → 完成自动配置
    

9. Spring Boot常见的Starter有哪些?

答案:

Spring Boot提供了大量Starter,简化依赖管理:

Web开发:

  • spring-boot-starter-web:Web开发,包含Spring MVC、Tomcat
  • spring-boot-starter-webflux:响应式Web开发

数据访问:

  • spring-boot-starter-data-jpa:JPA数据访问
  • spring-boot-starter-jdbc:JDBC数据访问
  • spring-boot-starter-data-redis:Redis数据访问
  • spring-boot-starter-data-mongodb:MongoDB数据访问

消息队列:

  • spring-boot-starter-amqp:RabbitMQ
  • spring-boot-starter-activemq:ActiveMQ

安全:

  • spring-boot-starter-security:Spring Security

测试:

  • spring-boot-starter-test:测试支持,包含JUnit、Mockito等

工具:

  • spring-boot-starter-aop:AOP支持
  • spring-boot-starter-cache:缓存支持
  • spring-boot-starter-validation:参数校验

10. Spring中如何自定义Starter?

答案:

  1. 创建Spring Boot Starter项目

    • 命名为:my-starter
  2. 创建自动配置类

    @Configuration
    @ConditionalOnClass(MyService.class)
    @EnableConfigurationProperties(MyProperties.class)
    public class MyAutoConfiguration {
        
        @Bean
        @ConditionalOnMissingBean
        public MyService myService(MyProperties properties) {
            return new MyService(properties);
        }
    }
    
  3. 创建属性配置类

    @ConfigurationProperties(prefix = "my")
    public class MyProperties {
        private String name = "default";
        private int timeout = 3000;
        // getter/setter
    }
    
  4. 配置spring.factories
    在META-INF/spring.factories文件中添加:

    org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
    com.example.MyAutoConfiguration
    
  5. 使用
    在其他项目中引入依赖:

    <dependency>
        <groupId>com.example</groupId>
        <artifactId>my-starter</artifactId>
        <version>1.0.0</version>
    </dependency>
    

11. Spring中的BeanFactory和ApplicationContext有什么区别?

答案:

特性 BeanFactory ApplicationContext
延迟加载 默认延迟加载 默认启动时加载所有Bean
功能 基础IOC容器 功能更丰富
AOP支持 需要手动配置 自动支持
事件发布 不支持 支持
国际化 不支持 支持
注解支持 需要额外配置 自动支持

使用建议:

  • 大多数场景使用ApplicationContext
  • 只有在资源受限的环境下考虑BeanFactory

12. Spring中如何解决循环依赖问题?

答案:

循环依赖是指Bean A依赖Bean B,Bean B又依赖Bean A的情况。

解决方式:

  1. 三级缓存机制
    Spring通过三级缓存解决循环依赖:

    • singletonObjects:存储完全初始化的Bean
    • earlySingletonObjects:存储早期Bean引用(未完成初始化)
    • singletonFactories:存储Bean工厂,用于创建早期引用
  2. 解决流程

    创建A → 发现需要B → 创建B → 发现需要A
    → 从singletonFactories获取A的早期引用 → 完成B
    → 完成A
    
  3. 局限性

    • 只解决单例、构造器注入的循环依赖
    • 原型Bean无法解决循环依赖
    • 构造器注入的多例Bean也无法解决
  4. 解决方案

    • 使用@Lazy注解延迟加载
    • 改用Setter注入
    • 重构代码,打破循环依赖

13. Spring中如何实现插件机制?

答案:

Spring的插件机制基于BeanPostProcessor和注解实现。

  1. BeanPostProcessor

    @Component
    public class MyBeanPostProcessor implements BeanPostProcessor {
        
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) {
            // 初始化前处理
            return bean;
        }
        
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) {
            // 初始化后处理
            return bean;
        }
    }
    
  2. BeanFactoryPostProcessor

    @Component
    public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
        
        @Override
        public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
            // 在Bean实例化前修改Bean定义
        }
    }
    
  3. 自定义注解

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface EnableMyPlugin {
    }
    
    @Import(MyPluginRegistrar.class)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface EnableMyPlugin {
    }
    

14. Spring中如何优化启动速度?

答案:

  1. 延迟加载

    @Lazy
    @Component
    public class MyService {}
    
  2. 排除不需要的自动配置

    @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
    public class Application {}
    
  3. 使用Spring Boot DevTools

    • 热部署,提高开发效率
  4. 减少组件扫描范围

    @ComponentScan(basePackages = "com.example")
    
  5. 禁用不需要的AutoConfiguration

    spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
    

15. Spring中如何自定义注解?

答案:

  1. 定义注解

    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface MyAnnotation {
        String value() default "";
        int timeout() default 30;
    }
    
  2. 使用注解

    @MyAnnotation(value = "test", timeout = 60)
    public void testMethod() {}
    
  3. 处理注解

    @Aspect
    @Component
    public class MyAspect {
        
        @Around("@annotation(myAnnotation)")
        public Object around(ProceedingJoinPoint joinPoint, MyAnnotation myAnnotation) throws Throwable {
            // 处理注解逻辑
            return joinPoint.proceed();
        }
    }
    

16. Spring中如何实现懒加载?

答案:

  1. 类级别懒加载

    @Lazy
    @Component
    public class MyService {}
    
  2. Bean级别懒加载

    @Bean
    @Lazy
    public MyService myService() {
        return new MyService();
    }
    
  3. 依赖懒加载

    @Autowired
    @Lazy
    private MyService myService;
    
  4. 全局懒加载

    spring.main.lazy-initialization=true
    

17. Spring中如何管理多数据源?

答案:

  1. 配置多数据源

    spring:
      datasource:
        primary:
          url: jdbc:mysql://localhost:3306/db1
          username: root
          password: 123456
        secondary:
          url: jdbc:mysql://localhost:3306/db2
          username: root
          password: 123456
    
  2. 配置多数据源Bean

    @Configuration
    public class DataSourceConfig {
        
        @Primary
        @Bean(name = "primaryDataSource")
        @ConfigurationProperties("spring.datasource.primary")
        public DataSource primaryDataSource() {
            return DataSourceBuilder.create().build();
        }
        
        @Bean(name = "secondaryDataSource")
        @ConfigurationProperties("spring.datasource.secondary")
        public DataSource secondaryDataSource() {
            return DataSourceBuilder.create().build();
        }
    }
    
  3. 配置多个SqlSessionFactory

    @Configuration
    public class MybatisConfig {
        
        @Primary
        @Bean
        public SqlSessionFactory primarySqlSessionFactory(
            @Qualifier("primaryDataSource") DataSource dataSource) throws Exception {
            SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
            factory.setDataSource(dataSource);
            return factory.getObject();
        }
        
        @Bean
        public SqlSessionFactory secondarySqlSessionFactory(
            @Qualifier("secondaryDataSource") DataSource dataSource) throws Exception {
            SqlSessionFactoryBean factory = new SqlSessionFactoryBean;
            factory.setDataSource(dataSource);
            return factory.getObject();
        }
    }
    

18. Spring中如何处理并发问题?

答案:

  1. 线程安全的Bean

    • 尽量使用无状态Bean
    • 避免使用实例变量
  2. 使用@Scope("prototype")

    @Component
    @Scope("prototype")
    public class MyService {}
    
  3. 使用ThreadLocal

    public class UserContext {
        private static final ThreadLocal<String> USER = new ThreadLocal<>();
        
        public static void set(String user) { USER.set(user); }
        public static String get() { return USER.get(); }
        public static void clear() { USER.remove(); }
    }
    
  4. 使用并发工具类

    • ConcurrentHashMap
    • Atomic类
    • CountDownLatch
    • CyclicBarrier

19. Spring中如何进行性能监控?

答案:

  1. Spring Boot Actuator

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    
    management:
      endpoints:
        web:
          exposure:
            include: health,info,metrics,threaddump,heapdump
    
  2. Micrometer

    @Component
    public class MetricsConfig {
        
        private final MeterRegistry registry;
        
        public MetricsConfig(MeterRegistry registry) {
            this.registry = registry;
        }
        
        public void measureExecutionTime(String name, Runnable action) {
            Timer timer = Timer.builder(name)
                .description("Execution time")
                .register(registry);
            timer.record(action);
        }
    }
    
  3. Spring Boot Admin

    • 可视化的监控面板
    • 日志管理
    • 性能监控

20. Spring中如何处理异常?

答案:

  1. @ExceptionHandler

    @RestControllerAdvice
    public class GlobalExceptionHandler {
        
        @ExceptionHandler(ResourceNotFoundException.class)
        public ResponseEntity<ErrorResponse> handleNotFound(ResourceNotFoundException ex) {
            return ResponseEntity.status(HttpStatus.NOT_FOUND)
                .body(new ErrorResponse(ex.getMessage()));
        }
        
        @ExceptionHandler(Exception.class)
        public ResponseEntity<ErrorResponse> handleException(Exception ex) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body(new ErrorResponse("系统异常"));
        }
    }
    
  2. 自定义异常

    public class BusinessException extends RuntimeException {
        private Integer code;
        private String message;
        
        public BusinessException(Integer code, String message) {
            super(message);
            this.code = code;
            this.message = message;
        }
    }
    
  3. 使用@ResponseStatus

    @ResponseStatus(HttpStatus.NOT_FOUND)
    public class ResourceNotFoundException extends RuntimeException {}
    

二、分布式系统(20题)

21. 什么是CAP定理?

答案:

CAP定理由Eric Brewer提出,指在分布式系统中,Consistency(一致性)、Availability(可用性)、Partition Tolerance(分区容错性)三者不可兼得。

  1. Consistency(一致性)

    • 所有节点在同一时刻看到的数据是一致的
    • 数据更新后,所有读都能读到最新值
  2. Availability(可用性)

    • 每个请求都能在合理时间内收到响应
    • 不保证响应是最新数据
  3. Partition Tolerance(分区容错性)

    • 系统在遇到网络分区时仍能继续工作
    • 网络分区是分布式系统的常态

选择:

  • CP:一致性和分区容错性(如HBase、Zookeeper)
  • AP:可用性和分区容错性(如Cassandra、Dynamo)
  • CA:一致性和可用性(单机系统,分布式中不存在)

22. 什么是BASE理论?

答案:

BASE理论是对CAP中可用性和一致性的权衡,是NoSQL数据库的设计原则。

  1. Basic Availability(基本可用)

    • 分布式系统在出现不可预测故障时,保证核心功能可用
    • 允许损失部分可用性(如响应时间变长、功能降级)
  2. Soft State(软状态)

    • 允许系统存在中间状态
    • 中间状态不影响系统整体可用性
  3. Eventual Consistency(最终一致性)

    • 系统在经过一段时间的同步后,数据最终会达到一致状态
    • 不要求实时一致性

与CAP的关系:

  • BASE是CAP的AP方案的延伸
  • 强调在分布式系统中,可用性和分区容错性比强一致性更重要

23. 分布式锁的实现方案有哪些?

答案:

  1. 基于数据库

    -- 唯一索引实现
    INSERT IGNORE INTO lock_table (lock_name, create_time) VALUES ('order_lock', NOW());
    
    -- 版本控制实现
    UPDATE lock_table SET version = version + 1 WHERE lock_name = 'order_lock' AND version = 1;
    
    • 优点:简单,易于理解
    • 缺点:性能差,存在单点问题
  2. 基于Zookeeper

    // 创建临时顺序节点
    String path = zooKeeper.create("/locks/order_lock", new byte[0],
        Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
    
    // 监听前一个节点
    Stat stat = zooKeeper.exists(path.substring(0, path.lastIndexOf("/")) + path.substring(path.lastIndexOf("/") + 1).prev(), true);
    
    • 优点:强一致性,支持可重入
    • 缺点:依赖Zookeeper集群,复杂度较高
  3. 基于Redis

    // SET命令设置锁,NX表示不存在才设置,EX表示过期时间
    String result = jedis.set("lock", "1", "NX", "EX", 10);
    if ("OK".equals(result)) {
        try {
            // 业务逻辑
        } finally {
            // 删除锁(使用Lua脚本保证原子性)
            jedis.eval("if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end", 
                Collections.singletonList("lock"), Collections.singletonList("1"));
        }
    }
    
    • 优点:性能好,实现简单
    • 缺点:需要处理锁过期问题
  4. 基于Redisson

    RLock lock = redisson.getLock("order_lock");
    lock.lock();
    try {
        // 业务逻辑
    } finally {
        lock.unlock();
    }
    
    • 支持看门狗机制,自动续期
    • 支持可重入锁、公平锁、读写锁

24. 分布式事务有哪些解决方案?

答案:

  1. 2PC(两阶段提交)

    • 准备阶段:事务参与者准备执行,但不提交
    • 提交阶段:协调者决定是否提交
    • 优点:强一致性
    • 缺点:性能差,阻塞式事务,单点问题
  2. TCC(尝试-确认-取消)

    • Try:尝试执行,预留资源
    • Confirm:确认执行,提交资源
    • Cancel:取消执行,释放资源
    • 优点:性能好,非阻塞
    • 缺点:代码侵入性强,需要实现三个接口
  3. 消息最终一致性

    发送方 → 本地事务 → 发送消息 → MQ → 接收方 → 本地事务
    
    • 优点:性能好,解耦
    • 缺点:最终一致性,需要处理重复消费
  4. Seata

    • 提供AT、TCC、Saga等多种模式
    • 支持多种事务场景
    • 易于集成

25. 什么是分布式ID生成方案?

答案:

  1. 数据库自增ID

    CREATE TABLE id_generator (
        id BIGINT NOT NULL,
        value BIGINT NOT NULL,
        PRIMARY KEY (id)
    );
    
    • 优点:简单
    • 缺点:单点,扩展性差
  2. UUID

    String id = UUID.randomUUID().toString().replace("-", "");
    
    • 优点:简单,全局唯一
    • 缺点:无序,存储成本高,不适合数据库索引
  3. Snowflake(雪花算法)

    public class SnowflakeIdGenerator {
        private long workerId;
        private long datacenterId;
        private long sequence = 0L;
        private long lastTimestamp = -1L;
        
        public synchronized long nextId() {
            long timestamp = System.currentTimeMillis();
            if (timestamp < lastTimestamp) {
                throw new RuntimeException("时钟回拨");
            }
            if (timestamp == lastTimestamp) {
                sequence = (sequence + 1) & 4095;
                if (sequence == 0) {
                    timestamp = waitNextMillis(timestamp);
                }
            } else {
                sequence = 0L;
            }
            lastTimestamp = timestamp;
            return ((timestamp - START_EPOCH) << 22) | 
                   (datacenterId << 17) | 
                   (workerId << 12) | 
                   sequence;
        }
    }
    
    • 结构:1位符号位 + 41位时间戳 + 5位数据中心 + 5位机器ID + 12位序列号
    • 优点:趋势递增,高性能,无中心节点
    • 缺点:依赖系统时钟,时钟回拨需要处理
  4. 号段模式

    • 从数据库批量获取ID段
    • 优点:性能好,可扩展
    • 缺点:ID不连续

26. 什么是分布式会话方案?

答案:

  1. Session共享

    • 将Session存储到Redis
    • 所有节点从Redis读取Session
  2. Token机制

    // 使用JWT生成Token
    String token = Jwts.builder()
        .setSubject(userId.toString())
        .setExpiration(new Date(System.currentTimeMillis() + 3600000))
        .signWith(SignatureAlgorithm.HS256, secret)
        .compact();
    
    • 优点:无状态,易于扩展
    • 缺点:Token无法主动失效
  3. Spring Session

    @Configuration
    @EnableRedisHttpSession(maxInactiveIntervalInSeconds = 1800)
    public class SessionConfig {
    }
    

27. 什么是分布式缓存?有哪些解决方案?

答案:

  1. Redis

    • 支持多种数据结构
    • 持久化机制
    • 集群模式
    • 常用命令:GET、SET、EXPIRE、HGET、HSET等
  2. Memcached

    • 简单的KV存储
    • 多线程处理
    • 不支持持久化
  3. 本地缓存

    // Caffeine
    Cache<String, Object> cache = Caffeine.newBuilder()
        .maximumSize(1000)
        .expireAfterWrite(10, TimeUnit.MINUTES)
        .build();
    
  4. 多级缓存

    • L1:本地缓存(Caffeine)
    • L2:分布式缓存(Redis)

28. 什么是分布式服务治理?

答案:

  1. 服务注册与发现

    • Nacos:阿里巴巴开源,支持动态配置和服务发现
    • Eureka:Netflix开源,AP模型
    • Consul:HashiCorp开源,CP模型
    • Zookeeper:CP模型
  2. 负载均衡

    • 轮询
    • 随机
    • 加权
    • 最小连接数
  3. 服务熔断与降级

    • 熔断:当错误率达到阈值时,自动熔断,快速失败
    • 降级:当服务不可用时,返回默认值或缓存数据
  4. 限流

    • 令牌桶算法
    • 漏桶算法
    • 滑动窗口

29. 什么是RPC?有哪些实现?

答案:

RPC(Remote Procedure Call,远程过程调用) 是分布式系统的基本通信方式。

  1. gRPC

    • 基于HTTP/2和Protocol Buffers
    • 高性能,支持多语言
    • 双向流式通信
  2. Dubbo

    • 阿里巴巴开源,Java语言
    • 支持多种协议:Dubbo、RMI、HTTP
    • 支持多种序列化:Hessian、JSON、Kryo
  3. Thrift

    • Facebook开源
    • 支持多种语言
    • 多种传输协议
  4. Spring Cloud OpenFeign

    • 声明式HTTP客户端
    • 与Spring Cloud无缝集成

30. 什么是服务网格(Service Mesh)?

答案:

Service Mesh 是一种解决微服务通信的基础设施层。

  1. 核心概念

    • Sidecar:代理容器,与业务容器部署在同一Pod中
    • 数据平面:负责实际的数据转发
    • 控制平面:负责配置下发和管理
  2. 主流实现

    • Istio:Google、IBM、 Lyft联合开源
    • Linkerd:Buoyant开源
    • Envoy:Lyft开源,底层代理
  3. 优势

    • 业务代码无侵入
    • 统一的服务治理能力
    • 可观测性

31. 什么是微服务架构?有哪些优缺点?

答案:

微服务架构是一种将单一应用划分为一组小服务的方法。

  1. 特点

    • 服务粒度小
    • 独立部署
    • 去中心化
    • 容错性好
  2. 优点

    • 技术栈灵活
    • 易于扩展
    • 独立部署
    • 故障隔离
  3. 缺点

    • 运维复杂
    • 分布式事务
    • 服务治理
    • 测试困难

32. 什么是Docker容器技术?

答案:

Docker 是一个开源的应用容器引擎。

  1. 核心概念

    • 镜像(Image):只读模板
    • 容器(Container):镜像的运行实例
    • 仓库(Registry):镜像存储仓库
  2. 常用命令

    # 拉取镜像
    docker pull nginx
    
    # 运行容器
    docker run -d -p 80:80 nginx
    
    # 查看容器
    docker ps -a
    
    # 进入容器
    docker exec -it container_id bash
    
  3. Dockerfile

    FROM openjdk:11-jre
    COPY target/app.jar app.jar
    EXPOSE 8080
    ENTRYPOINT ["java", "-jar", "/app.jar"]
    

33. 什么是Kubernetes(K8s)?

答案:

Kubernetes 是一个容器编排平台。

  1. 核心概念

    • Pod:最小部署单元
    • Service:服务暴露
    • Deployment:无状态应用部署
    • StatefulSet:有状态应用部署
    • ConfigMap:配置管理
    • Secret:密钥管理
  2. 常用命令

    # 查看Pod
    kubectl get pods
    
    # 查看Service
    kubectl get services
    
    # 部署应用
    kubectl apply -f deployment.yaml
    

34. 什么是CI/CD?

答案:

CI/CD 是持续集成和持续部署。

  1. CI(持续集成)

    • 频繁合并代码到主干
    • 自动化构建和测试
    • 快速发现问题
  2. CD(持续部署/交付)

    • 自动化部署到生产环境
    • 减少人工操作
    • 提高发布效率
  3. 常用工具

    • Jenkins
    • GitLab CI
    • GitHub Actions
    • CircleCI

35. 什么是链路追踪?

答案:

链路追踪用于追踪请求在分布式系统中的调用链。

  1. 核心概念

    • Trace ID:一次请求的唯一标识
    • Span ID:一次调用的唯一标识
    • Parent Span ID:父调用的ID
  2. 常用工具

    • Jaeger:Uber开源
    • Zipkin:Twitter开源
    • SkyWalking:Apache开源

36. 什么是分布式消息队列?有哪些方案?

答案:

  1. Kafka

    • 高吞吐,持久化
    • 适合日志收集、流处理
  2. RocketMQ

    • 阿里开源,支持事务消息
    • 适合交易订单、消息堆积
  3. RabbitMQ

    • 灵活的路由机制
    • 适合企业级应用
  4. ActiveMQ

    • 老牌MQ
    • 功能丰富,但性能一般

37. 什么是分布式日志系统?

答案:

  1. ELK Stack

    • Elasticsearch:搜索引擎
    • Logstash:日志收集和处理
    • Kibana:日志可视化
  2. EFK Stack

    • 将Logstash替换为Fluentd
  3. 架构

    应用 → Logback/Log4j → Filebeat/Fluentd → Kafka → Logstash → Elasticsearch → Kibana
    

38. 什么是分布式配置中心?

答案:

  1. Spring Cloud Config

    • 基于Git存储配置
    • 支持配置版本管理
    • 配置热更新
  2. Nacos

    • 阿里巴巴开源
    • 支持动态配置和服务发现
    • 简单易用
  3. Apollo

    • 携程开源
    • 配置热更新
    • 支持权限管理

39. 什么是分布式搜索?

答案:

  1. Elasticsearch

    • 基于Lucene
    • 分布式搜索引擎
    • 支持全文检索、聚合分析
  2. Solr

    • Apache开源
    • 基于Lucene
    • 企业级搜索引擎

40. 什么是分布式协调服务?

答案:

  1. Zookeeper

    • 分布式协调服务
    • 提供配置管理、命名服务、分布式锁
    • 基于ZAB协议
  2. Consul

    • HashiCorp开源
    • 支持多数据中心
    • 提供健康检查
  3. etcd

    • CoreOS开源
    • K8s默认使用
    • 基于Raft协议

三、高并发(20题)

41. JVM内存模型是怎样的?

答案:

JVM内存模型分为以下几个区域:

  1. 堆内存(Heap)

    • 所有线程共享
    • 存储对象实例
    • 分为新生代和老年代
    • 新生代:Eden + Two Survivor + Survivor
    • 老年代:长期存活的对象
  2. 方法区(Method Area)

    • 存储类信息、常量、静态变量
    • JDK 8后称为元空间(Metaspace)
    • 使用本地内存
  3. 虚拟机栈(Java Stack)

    • 线程私有
    • 存储方法调用的栈帧
    • 每个方法对应一个栈帧
  4. 本地方法栈(Native Method Stack)

    • 线程私有
    • 为Native方法服务
  5. 程序计数器(Program Counter Register)

    • 线程私有
    • 记录当前执行的字节码指令地址

42. JVM垃圾回收算法有哪些?

答案:

  1. 标记-清除(Mark-Sweep)

    • 标记所有需要回收的对象
    • 统一清除
    • 缺点:产生内存碎片
  2. 标记-复制(Mark-Copy)

    • 将内存分为两半
    • 每次只使用一半
    • 存活对象复制到另一半
    • 缺点:内存利用率低
  3. 标记-整理(Mark-Compact)

    • 标记存活对象
    • 整理到内存一端
    • 直接清理边界外的内存
    • 优点:无碎片
  4. 分代收集算法

    • 新生代:使用复制算法
    • 老年代:使用标记-清除或标记-整理

43. GC Roots有哪些?

答案:

GC Roots 是判断对象是否存活的起点:

  1. 虚拟机栈中引用的对象

    • 局部变量表中的对象引用
  2. 方法区中类静态属性引用的对象

    • static修饰的属性
  3. 方法区中常量引用的对象

    • final修饰的常量
  4. 本地方法栈中JNI引用的对象

    • Native方法引用的对象

44. 常见的垃圾收集器有哪些?

答案:

  1. Serial Collector

    • 单线程收集器
    • 适合客户端模式
  2. Parallel Scavenge

    • 多线程收集器
    • 关注吞吐量
  3. Serial Old

    • 单线程收集器
    • 老年代收集器
  4. Parallel Old

    • 多线程收集器
    • 老年代收集器
  5. CMS(Concurrent Mark Sweep)

    • 并发收集器
    • 关注响应时间
    • 缺点:产生碎片
  6. G1

    • 分区收集器
    • 平衡吞吐量和响应时间
    • JDK 9后成为默认收集器
  7. ZGC

    • 低延迟收集器
    • pauses < 10ms
    • JDK 11引入,JDK 15成为候选特性

45. 什么是多线程?如何创建线程?

答案:

  1. 继承Thread类

    public class MyThread extends Thread {
        @Override
        public void run() {
            // 业务逻辑
        }
    }
    
  2. 实现Runnable接口

    public class MyRunnable implements Runnable {
        @Override
        public void run() {
            // 业务逻辑
        }
    }
    // 使用
    new Thread(new MyRunnable()).start();
    
  3. 实现Callable接口

    public class MyCallable implements Callable<String> {
        @Override
        public String call() throws Exception {
            return "result";
        }
    }
    // 使用
    FutureTask<String> futureTask = new FutureTask<>(new MyCallable());
    new Thread(futureTask).start();
    String result = futureTask.get();
    
  4. 使用线程池

    ExecutorService executor = Executors.newFixedThreadPool(10);
    executor.submit(new MyRunnable());
    

46. 线程池的核心参数有哪些?

答案:

public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory,
                          RejectedExecutionHandler handler)
  1. corePoolSize:核心线程数
  2. maximumPoolSize:最大线程数
  3. keepAliveTime:空闲线程存活时间
  4. unit:时间单位
  5. workQueue:任务队列
    • ArrayBlockingQueue
    • LinkedBlockingQueue
    • SynchronousQueue
    • PriorityBlockingQueue
  6. threadFactory:线程工厂
  7. handler:拒绝策略
    • AbortPolicy:抛出异常
    • CallerRunsPolicy:由调用者执行
    • DiscardPolicy:丢弃任务
    • DiscardOldestPolicy:丢弃最老的任务

47. 线程池的执行流程是什么?

答案:

1. 提交任务
2. 检查核心线程数
   - 未达核心线程数:创建新线程执行
   - 达到核心线程数:进入步骤3
3. 检查任务队列
   - 队列未满:放入队列等待
   - 队列已满:进入步骤4
4. 检查最大线程数
   - 未达最大线程数:创建新线程执行
   - 达到最大线程数:执行拒绝策略

48. 什么是volatile关键字?

答案:

volatile 是Java提供的轻量级同步机制。

  1. 保证可见性

    • 一个线程修改了变量,其他线程立即可见
  2. 保证有序性

    • 禁止指令重排序
  3. 不保证原子性

    • i++ 不是原子操作
  4. 使用场景

    // 单例模式(双重检查锁)
    public class Singleton {
        private static volatile Singleton instance;
        
        public static Singleton getInstance() {
            if (instance == null) {
                synchronized (Singleton.class) {
                    if (instance == null) {
                        instance = new Singleton();
                    }
                }
            }
            return instance;
        }
    }
    
    // 状态标志
    private volatile boolean running = true;
    

49. 什么是synchronized关键字?

答案:

synchronized 是Java提供的同步机制。

  1. 修饰实例方法

    • 锁当前对象实例
    public synchronized void method() {}
    
  2. 修饰静态方法

    • 锁Class对象
    public static synchronized void method() {}
    
  3. 修饰代码块

    • 锁指定对象
    public void method() {
        synchronized (this) {
            // 业务逻辑
        }
    }
    
  4. 实现原理

    • 对象头中的Mark Word
    • 偏向锁 → 轻量级锁 → 重量级锁
  5. 锁升级过程

    • 无锁状态
    • 偏向锁:只有一个线程访问
    • 轻量级锁:多线程竞争
    • 重量级锁:竞争激烈,申请系统锁

50. ReentrantLock和synchronized有什么区别?

答案:

特性 synchronized ReentrantLock
层面 JVM层面 API层面
锁释放 自动释放 需要手动释放
锁获取 无法中断 可中断获取
公平锁 非公平 可配置
条件变量 不支持 支持
性能 JDK 6后优化,性能接近 略好

使用建议:

  • 简单场景使用synchronized
  • 需要高级功能使用ReentrantLock

51. 什么是CAS?有什么缺点?

答案:

CAS(Compare-And-Swap) 是一种无锁并发算法。

  1. 原理

    • 比较并交换
    • 有三个值:内存值V、旧预期值E、新值N
    • 只有当V==E时,才将V改为N
  2. Java实现

    AtomicInteger atomicInteger = new AtomicInteger(0);
    atomicInteger.incrementAndGet(); // CAS操作
    
  3. 缺点

    • ABA问题:值从A→B→A,CAS认为没有变化
    • 自旋开销:长时间自旋消耗CPU
    • 只能保证一个共享变量的原子性

52. ABA问题如何解决?

答案:

ABA问题是指值从A变为B再变回A,CAS无法感知。

解决方案:

  1. 使用AtomicStampedReference

    AtomicStampedReference<Integer> reference = 
        new AtomicStampedReference<>(1, 1);
    
    // 带版本号的CAS操作
    Integer[] stamp = {1};
    reference.compareAndSet(1, 2, stamp[0], stamp[0] + 1);
    
  2. 使用版本号

    • 每次修改增加版本号
    • CAS时检查版本号

53. 什么是并发容器?

答案:

Java提供了一些线程安全的容器:

  1. Vector

    • 线程安全的List
    • 方法使用synchronized修饰
  2. Hashtable

    • 线程安全的Map
    • 不允许null键值
  3. ConcurrentHashMap

    • JDK 7:分段锁
    • JDK 8:CAS + synchronized
  4. CopyOnWriteArrayList

    • 写时复制
    • 适合读多写少的场景
  5. BlockingQueue

    • 阻塞队列
    • ArrayBlockingQueue
    • LinkedBlockingQueue

54. 什么是阻塞队列?有哪些实现?

答案:

BlockingQueue 是支持两个附加操作的队列:

  • 阻塞获取:队列为空时,获取操作阻塞
  • 阻塞插入:队列满时,插入操作阻塞

实现:

  1. ArrayBlockingQueue

    • 数组实现
    • 有界队列
    • 公平锁
  2. LinkedBlockingQueue

    • 链表实现
    • 默认无界(Integer.MAX_VALUE)
    • 两把锁(读写分离)
  3. PriorityBlockingQueue

    • 优先级队列
    • 无界队列
  4. SynchronousQueue

    • 不存储元素
    • 每次插入必须等待取出

55. 什么是ThreadLocal?如何使用?

答案:

ThreadLocal 提供线程局部变量。

  1. 使用示例

    public class UserContext {
        private static final ThreadLocal<User> USER_THREAD_LOCAL = new ThreadLocal<>();
        
        public static void set(User user) {
            USER_THREAD_LOCAL.set(user);
        }
        
        public static User get() {
            return USER_THREAD_LOCAL.get();
        }
        
        public static void remove() {
            USER_THREAD_LOCAL.remove();
        }
    }
    
  2. 应用场景

    • 用户会话管理
    • 事务管理
    • 数据库连接管理
  3. 内存泄漏问题

    • ThreadLocalMap的key是弱引用
    • 应该在使用后调用remove()

56. 什么是信号量?如何使用?

答案:

Semaphore 控制同时访问的线程数量。

Semaphore semaphore = new Semaphore(5); // 5个许可

// 获取许可
semaphore.acquire();
try {
    // 业务逻辑
} finally {
    // 释放许可
    semaphore.release();
}

使用场景:

  • 限流
  • 资源池管理

57. 什么是CountDownLatch?如何使用?

答案:

CountDownLatch 允许一个或多个线程等待其他线程完成操作。

CountDownLatch latch = new CountDownLatch(3); // 需要等待3个线程

// 线程1、2、3执行
new Thread(() -> {
    // 业务逻辑
    latch.countDown(); // 计数减1
}).start();

// 主线程等待
latch.await(); // 阻塞直到计数为0

58. 什么是CyclicBarrier?如何使用?

答案:

CyclicBarrier 允许一组线程互相等待,到达屏障点后再继续执行。

CyclicBarrier barrier = new CyclicBarrier(3, () -> {
    System.out.println("所有线程到达屏障");
});

for (int i = 0; i < 3; i++) {
    new Thread(() -> {
        // 业务逻辑
        try {
            barrier.await(); // 等待其他线程
        } catch (Exception e) {
            e.printStackTrace();
        }
    }).start();
}

与CountDownLatch的区别:

  • CountDownLatch:计数只能减,不能重置
  • CyclicBarrier:可以重置,可重复使用

59. 什么是Future和CompletableFuture?

答案:

  1. Future

    ExecutorService executor = Executors.newFixedThreadPool(10);
    Future<String> future = executor.submit(() -> "result");
    String result = future.get(); // 阻塞获取结果
    
  2. CompletableFuture

    CompletableFuture<String> future = CompletableFuture
        .supplyAsync(() -> "result")
        .thenApply(result -> result.toUpperCase())
        .exceptionally(ex -> "default");
    
    String result = future.join(); // 非阻塞获取
    

优势:

  • 支持链式调用
  • 支持异常处理
  • 支持组合多个Future

60. 什么是线程安全?如何实现线程安全?

答案:

  1. 不可变对象

    • 使用final修饰
    • 不暴露内部状态
  2. 线程封闭

    • ThreadLocal
    • 局部变量
  3. 同步机制

    • synchronized
    • ReentrantLock
    • volatile
  4. 并发容器

    • ConcurrentHashMap
    • CopyOnWriteArrayList
  5. 原子类

    • AtomicInteger
    • LongAdder

四、微服务(20题)

61. Spring Cloud的核心组件有哪些?

答案:

  1. Spring Cloud Netflix

    • Eureka:服务注册与发现
    • Ribbon:负载均衡
    • Hystrix:熔断降级
    • Zuul:API网关
    • Feign:声明式HTTP客户端
  2. Spring Cloud Alibaba

    • Nacos:服务注册与配置中心
    • Sentinel:流量控制
    • Seata:分布式事务
    • RocketMQ:消息队列
  3. Spring Cloud Gateway

    • 网关服务
    • 路由转发
    • 过滤器
  4. Spring Cloud Config

    • 配置中心
  5. Spring Cloud OpenFeign

    • 声明式服务调用

62. 什么是服务注册与发现?如何实现?

答案:

服务注册与发现是微服务的基础设施。

  1. 注册中心

    • 服务提供者启动时向注册中心注册
    • 服务消费者从注册中心获取服务列表
  2. 实现方案

    • Eureka:AP模型,支持心跳检测
    • Nacos:支持CP和AP切换
    • Consul:CP模型,支持健康检查
    • Zookeeper:CP模型
  3. 注册流程

    服务提供者 → 注册中心 → 服务发现 → 服务消费者
    

63. 什么是负载均衡?有哪些策略?

答案:

负载均衡将请求分发到多个服务实例。

策略:

  1. 轮询(Round Robin)

    • 依次分发到每个实例
  2. 随机(Random)

    • 随机选择一个实例
  3. 加权轮询(Weighted Round Robin)

    • 根据权重分配请求
  4. 最少连接(Least Connections)

    • 选择连接数最少的实例
  5. 一致性哈希(Consistent Hashing)

    • 相同请求路由到相同实例

64. 什么是熔断降级?如何实现?

答案:

熔断降级保护系统不被雪崩。

  1. 熔断

    • 当错误率达到阈值时,自动熔断
    • 快速失败,不调用下游服务
  2. 降级

    • 当服务不可用时,返回默认值或缓存数据
  3. Sentinel实现

    @SentinelResource(value = "getUser", blockHandler = "getUserFallback")
    public User getUser(Long id) {
        // 业务逻辑
    }
    
    public User getUserFallback(Long id, BlockException ex) {
        // 降级逻辑
        return new User();
    }
    
  4. Hystrix实现

    @HystrixCommand(fallbackMethod = "getUserFallback")
    public User getUser(Long id) {
        // 业务逻辑
    }
    

65. 什么是限流?有哪些算法?

答案:

限流控制单位时间内的请求数量。

算法:

  1. 计数器算法

    • 统计单位时间内的请求数
    • 超过阈值则拒绝
  2. 令牌桶算法

    • 以固定速率产生令牌
    • 请求获取令牌,获取不到则拒绝
  3. 漏桶算法

    • 请求进入漏桶
    • 以固定速率处理
    • 超过容量则拒绝
  4. 滑动窗口

    • 将时间窗口划分为多个小窗口
    • 统计小窗口的请求数

66. 什么是API网关?有什么作用?

答案:

API网关是微服务的统一入口。

作用:

  1. 路由转发

    • 根据请求路径转发到不同服务
  2. 负载均衡

    • 分发请求到服务实例
  3. 鉴权

    • Token验证
    • 权限控制
  4. 限流

    • 保护后端服务
  5. 日志

    • 请求日志记录
  6. 监控

    • 性能指标收集

实现:

  • Spring Cloud Gateway
  • Zuul
  • Kong
  • Nginx

67. 什么是服务调用?有哪些方式?

答案:

服务调用是微服务之间的通信方式。

  1. HTTP调用

    • RestTemplate
    • WebClient
    • OkHttp
  2. RPC调用

    • Dubbo
    • gRPC
    • Thrift
  3. 声明式调用

    • Feign
    • OpenFeign

Feign示例:

@FeignClient(name = "user-service")
public interface UserClient {
    
    @GetMapping("/user/{id}")
    User getUser(@PathVariable("id") Long id);
}

68. 什么是配置中心?如何实现?

答案:

配置中心统一管理应用配置。

实现方案:

  1. Spring Cloud Config

    • 基于Git存储配置
    • 支持配置版本管理
    • 支持配置热更新
  2. Nacos

    • 支持动态配置
    • 支持服务发现
    • 简单易用
  3. Apollo

    • 携程开源
    • 配置热更新
    • 支持权限管理

配置热更新:

@RefreshScope
@Component
public class ConfigBean {
    @Value("${config.property}")
    private String property;
}

69. 什么是链路追踪?如何实现?

答案:

链路追踪追踪请求在微服务间的调用链。

实现方案:

  1. Spring Cloud Sleuth

    • 与Zipkin集成
    • 自动添加Trace ID
  2. SkyWalking

    • 高性能链路追踪
    • 支持多种语言
  3. Jaeger

    • Uber开源
    • 支持追踪、分析

实现:

spring:
  sleuth:
    sampler:
      probability: 1.0
  zipkin:
    base-url: http://localhost:9411

70. 什么是服务网关?如何实现?

答案:

服务网关是微服务的统一入口。

Spring Cloud Gateway:

@Configuration
public class GatewayConfig {
    
    @Bean
    public RouteLocator routeLocator(RouteLocatorBuilder builder) {
        return builder.routes()
            .route("user-service", r -> r
                .path("/api/user/**")
                .filters(f -> f
                    .stripPrefix(1)
                    .addRequestHeader("X-Request-From", "gateway"))
                .uri("lb://user-service"))
            .build();
    }
}

过滤器:

@Component
public class AuthFilter implements GlobalFilter {
    
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String token = exchange.getRequest().getHeaders().getFirst("Authorization");
        if (token == null || token.isEmpty()) {
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }
        return chain.filter(exchange);
    }
}

71. 什么是服务熔断器?如何选择?

答案:

服务熔断器保护系统不被雪崩。

选择:

  1. Hystrix(已停止维护)

    • Netflix开源
    • 功能丰富
    • 已停止维护
  2. Sentinel(推荐)

    • 阿里巴巴开源
    • 轻量级
    • 功能强大
    • 支持实时监控
  3. Resilience4j

    • 轻量级
    • 响应式支持

推荐:

  • 新项目使用Sentinel
  • 响应式项目使用Resilience4j

72. 什么是服务网格?

答案:

服务网格是基础设施层。

核心:

  • Sidecar代理
  • 数据平面
  • 控制平面

实现:

  • Istio
  • Linkerd
  • Envoy

73. 什么是微服务治理?

答案:

微服务治理管理微服务生命周期。

治理内容:

  1. 服务注册与发现
  2. 负载均衡
  3. 熔断降级
  4. 限流
  5. 链路追踪
  6. 配置管理
  7. 日志管理

74. 什么是服务降级?如何实现?

答案:

服务降级当服务不可用时,返回默认值。

实现:

@SentinelResource(value = "getUser", fallback = "getUserFallback")
public User getUser(Long id) {
    // 业务逻辑
}

public User getUserFallback(Long id, Exception ex) {
    return new User();
}

75. 什么是服务限流?如何实现?

答案:

服务限流控制请求速率。

实现:

@SentinelResource(value = "getUser", blockHandler = "handleBlock")
public User getUser(Long id) {
    // 业务逻辑
}

public User handleBlock(Long id, BlockException ex) {
    return new User();
}

配置:

spring:
  cloud:
    sentinel:
      eager: true
      datasource:
        ds1:
          nacos:
            server-addr: localhost:8848
            data-id: gateway-flow-rules
            group-id: DEFAULT_GROUP
            rule-type: flow

76. 什么是分布式事务?有哪些方案?

答案:

分布式事务保证分布式系统的数据一致性。

方案:

  1. 2PC(两阶段提交)

    • 强一致性
    • 性能差
  2. TCC(尝试-确认-取消)

    • 高性能
    • 代码侵入
  3. 消息最终一致性

    • 解耦
    • 最终一致
  4. Seata

    • 支持多种模式
    • 易于集成

77. 什么是CAP理论?

答案:

见分布式系统部分。


78. 什么是BASE理论?

答案:

见分布式系统部分。


79. 什么是服务雪崩?如何预防?

答案:

服务雪崩是微服务的级联故障。

预防:

  1. 熔断降级
  2. 限流
  3. 超时控制
  4. 舱壁隔离
  5. 缓存

80. 什么是服务发现?如何实现?

答案:

见服务注册与发现部分。


五、中间件(20题)

81. Redis的数据结构有哪些?

答案:

  1. String(字符串)

    redis.set("key", "value");
    redis.get("key");
    
  2. List(列表)

    redis.lpush("list", "value1");
    redis.rpop("list");
    
  3. Set(集合)

    redis.sadd("set", "value1");
    redis.smembers("set");
    
  4. Sorted Set(有序集合)

    redis.zadd("zset", 1, "value1");
    redis.zrange("zset", 0, -1);
    
  5. Hash(哈希)

    redis.hset("hash", "field", "value");
    redis.hget("hash", "field");
    

82. Redis持久化机制有哪些?

答案:

  1. RDB(快照)

    • 定期保存数据快照
    • 恢复速度快
    • 可能丢失数据
  2. AOF(追加日志)

    • 记录每个写操作
    • 数据安全性高
    • 文件体积大
  3. 混合持久化

    • RDB + AOF
    • 结合两者优点

83. Redis缓存穿透、缓存击穿、缓存雪崩是什么?

答案:

  1. 缓存穿透

    • 查询不存在的数据
    • 解决方案:缓存空值、布隆过滤器
  2. 缓存击穿

    • 热点Key过期
    • 解决方案:永不过期、互斥锁
  3. 缓存雪崩

    • 大量Key同时过期
    • 解决方案:随机过期时间、多级缓存

84. Redis集群模式有哪些?

答案:

  1. 主从复制

    • 一主多从
    • 读写分离
  2. 哨兵模式

    • 主从 + 监控
    • 自动故障转移
  3. Cluster集群

    • 分布式存储
    • 16384个哈希槽

85. Kafka的架构是什么?

答案:

  1. Producer(生产者)

    • 发送消息
  2. Broker(代理)

    • 消息存储
  3. Consumer(消费者)

    • 消费消息
  4. Consumer Group(消费组)

    • 负载均衡消费
  5. Zookeeper

    • 管理集群

86. Kafka如何保证消息不丢失?

答案:

  1. 生产者

    props.put("acks", "all"); // 所有副本确认
    props.put("retries", Integer.MAX_VALUE); // 无限重试
    props.put("enable.idempotence", true); // 幂等
    
  2. Broker

    • 多副本同步
    • 持久化
  3. 消费者

    • 手动提交Offset
    • 处理完再提交

87. RabbitMQ的交换机类型有哪些?

答案:

  1. Direct Exchange

    • 精确匹配Routing Key
  2. Fanout Exchange

    • 广播消息
    • 忽略Routing Key
  3. Topic Exchange

    • 模式匹配

      • 匹配一个词
    • 匹配多个词

  4. Headers Exchange

    • 匹配消息头

88. RocketMQ的事务消息是什么?

答案:

事务消息保证本地事务和消息发送的一致性。

流程:

  1. 发送半消息
  2. 执行本地事务
  3. 提交或回滚消息
  4. Broker回查未确定消息

使用:

RocketMQTemplate rocketMQTemplate = new RocketMQTemplate();
LocalTransactionExecuter localExecuter = new LocalTransactionExecuter() {
    @Override
    public LocalTransactionState executeLocalTransaction(Message msg, Object arg) {
        // 执行本地事务
        return LocalTransactionState.COMMIT_MESSAGE;
    }
};
rocketMQTemplate.sendMessageInTransaction("topic", message, null);

89. MySQL索引优化有哪些?

答案:

  1. B+树索引

    • 聚簇索引
    • 非聚簇索引
  2. 索引原则

    • 最左前缀原则
    • 避免在索引列上做计算
    • 使用覆盖索引
    • 区分度高的列建索引
  3. Explain分析

    • type:访问类型
    • key:使用的索引
    • rows:扫描行数
    • Extra:额外信息

90. MySQL事务隔离级别有哪些?

答案:

  1. READ_UNCOMMITTED

    • 可读取未提交数据
    • 有脏读
  2. READ_COMMITTED

    • 只能读取已提交数据
    • 避免脏读
  3. REPEATABLE_READ

    • 可重复读
    • 避免脏读和不可重复读
  4. SERIALIZABLE

    • 串行化
    • 最安全

91. MySQL分页优化有哪些?

答案:

  1. 子查询优化

    SELECT * FROM table 
    WHERE id >= (SELECT id FROM table LIMIT 10000, 1) 
    LIMIT 10;
    
  2. 延迟关联

    SELECT t.* FROM table t 
    INNER JOIN (SELECT id FROM table LIMIT 10000, 10) temp 
    ON t.id = temp.id;
    
  3. 覆盖索引

    • 使用索引覆盖查询
    • 避免回表

92. MySQL分库分表方案有哪些?

答案:

  1. 水平分表

    • 按ID取模
    • 按时间范围
  2. 垂直分表

    • 常用字段和扩展字段分离
    • 大字段分离
  3. 分库分表中间件

    • ShardingSphere
    • MyCAT

93. MongoDB的特点是什么?

答案:

  1. 文档存储

    • BSON格式
    • 灵活的模式
  2. 索引支持

    • 单字段索引
    • 复合索引
    • 文本索引
    • 地理空间索引
  3. 聚合框架

    • MapReduce
    • Aggregation Pipeline
  4. 高可用

    • 副本集
    • 分片集群

94. Elasticsearch的特点是什么?

答案:

  1. 全文检索

    • 倒排索引
    • 分词器
  2. 分布式

    • 分片
    • 副本
  3. 近实时

    • 数据秒级可见
  4. 聚合分析

    • 多维度分析

95. Zookeeper的特点是什么?

答案:

  1. ZAB协议

    • Zookeeper原子广播协议
    • 保证一致性
  2. 数据结构

    • 树形结构
    • 节点带数据
  3. 节点类型

    • 持久节点
    • 临时节点
    • 持久顺序节点
    • 临时顺序节点
  4. 应用场景

    • 配置管理
    • 命名服务
    • 分布式锁
    • 集群管理

96. Nacos的特点是什么?

答案:

  1. 服务注册与发现

    • 支持Nacos和Eureka
    • 支持健康检查
  2. 配置管理

    • 动态配置更新
    • 配置版本管理
  3. DNS服务

    • 支持DNS协议
  4. 多环境支持

    • 命名空间
    • 分组

97. Sentinel的特点是什么?

答案:

  1. 流量控制

    • 限流
    • 降级
  2. 熔断降级

    • 慢调用比例
    • 异常比例
    • 异常数
  3. 系统负载保护

    • 自适应限流
  4. 实时监控

    • metrics接口
    • Dashboard

98. Seata的特点是什么?

答案:

  1. 多种事务模式

    • AT模式
    • TCC模式
    • Saga模式
    • XA模式
  2. AT模式

    • 无侵入
    • 自动生成回滚日志
  3. TCC模式

    • 高性能
    • 代码侵入

99. Dubbo的特点是什么?

答案:

  1. 高性能RPC

    • 多种序列化
    • 多种协议
  2. 服务治理

    • 负载均衡
    • 熔断降级
    • 服务路由
  3. 服务发现

    • 支持多种注册中心
  4. 监控

    • Hessian服务
    • Dubbo Admin

100. Spring Cloud Alibaba组件有哪些?

答案:

  1. Nacos

    • 服务注册与发现
    • 配置中心
  2. Sentinel

    • 流量控制
    • 熔断降级
  3. Seata

    • 分布式事务
  4. RocketMQ

    • 消息队列
  5. Distributed Seata

    • 分布式事务解决方案

总结

本文档整理了100道Java高级工程师面试题,涵盖:

  1. Spring基础框架(20题):IOC、AOP、事务、MVC、Boot等
  2. 分布式系统(20题):CAP、BASE、分布式锁、事务等
  3. 高并发(20题):JVM、多线程、并发容器、锁机制等
  4. 微服务(20题):Spring Cloud、服务治理、网关等
  5. 中间件(20题):Redis、Kafka、MQ、数据库等

建议学习方法:

  • 先理解原理,再记忆细节
  • 结合实际项目经验
  • 动手实践,加深理解
  • 定期复习,巩固记忆
posted @ 2026-09-24 20:52  明明很忙吖  阅读(5)  评论(0)    收藏  举报