Java 后端高频 20 题超详细解析 ②

1. Spring Cloud 组件都用过哪些?

详细回答:

实际项目中常用的 Spring Cloud & Spring Cloud Alibaba 组件如下:

  • Nacos:服务注册发现、配置中心
  • Gateway:API 网关,路由转发、限流、鉴权
  • OpenFeign:声明式服务调用
  • Ribbon:客户端负载均衡(现已内置进 OpenFeign / LoadBalancer)
  • Sentinel:限流、熔断、降级、热点参数限流
  • Seata:分布式事务(AT/TCC/SAGA/XA)
  • Sleuth + Zipkin:链路追踪
  • SkyWalking:分布式链路追踪与性能监控
  • MyBatis-Plus / MyBatis:ORM 持久层
  • RabbitMQ / RocketMQ / Kafka:消息队列,异步解耦、削峰
  • Spring Cloud Config:配置中心(传统方案,现多用 Nacos)

2. Gateway 主要是用来做什么?

详细回答:

Spring Cloud Gateway 是 API 网关,核心功能:

  1. 路由转发
    根据请求路径、域名、Header 等将请求路由到对应微服务。
  2. 统一入口
    所有外部请求先经过网关,屏蔽内部服务架构。
  3. 权限认证
    统一登录校验、Token 解析、身份鉴权。
  4. 限流熔断
    内置限流过滤器,配合 Sentinel 实现限流、降级。
  5. 日志与监控
    统一日志打印、请求耗时统计、异常捕获。
  6. 跨域处理
    全局配置 CORS,避免每个服务单独处理跨域。
  7. 请求转发与重写
    路径重写、Header 增删改、超时控制。

一句话总结:网关是微服务的统一入口、门卫、调度中心。


3. 跨域问题怎么解决?

详细回答:

跨域是浏览器同源策略限制:协议、域名、端口任一不同即跨域。

常见解决方案:

  1. Gateway 全局配置 CORS (推荐)
    网关统一配置跨域,下游服务无需处理。
  2. @CrossOrigin
    局部注解,适合单体或测试环境。
  3. WebMvcConfigurer 配置跨域
    全局配置类,对整个服务生效。
  4. Nginx 配置跨域
    在反向代理层添加 Header。
  5. JSONP
    仅支持 GET,已淘汰。

核心跨域 Header:

复制代码
Access-Control-Allow-Origin
Access-Control-Allow-Methods
Access-Control-Allow-Headers
Access-Control-Allow-Credentials

4. Nacos 是 AP 还是 CP 系统?

详细回答:

Nacos 支持切换 AP / CP 模式

  • 服务发现(默认 AP 模式)
    满足 CAP 中的 AP:高可用、分区容错,允许暂时数据不一致,保证服务可用性。
  • 配置中心(CP 模式)
    满足 CP:强一致性,配置必须同步一致才能响应。

结论:

  • 服务注册发现:AP
  • 配置中心:CP

5. 服务注册的底层原理

详细回答:

以 Nacos 为例:

  1. 服务启动
    服务通过 NacosDiscoveryClient 向 Nacos Server 发送注册请求(IP、端口、服务名)。
  2. 心跳机制
    客户端每 5s 发送心跳。
  3. 健康检查
    超过 15s 没心跳标记不健康,30s 剔除。
  4. 服务列表拉取
    消费者定时拉取服务列表并缓存本地。
  5. 故障剔除 & 动态扩缩容
    服务下线自动剔除,新增自动同步。

核心机制:注册 + 心跳 + 健康检查 + 本地缓存 + 动态更新


6. explain 关注哪些信息?

详细回答:

重点看这几列:

  1. id:执行顺序,id 越大越先执行
  2. select_type:查询类型(SIMPLE、SUBQUERY、DERIVED、UNION 等)
  3. table:涉及表
  4. type最重要
    最优到最差:
    system > const > eq_ref > ref > range > index > ALL
    至少要达到 range ,最好 ref 以上
  5. possible_keys:可能用到的索引
  6. key:实际用到的索引
  7. key_len:索引长度
  8. rows:扫描行数,越小越好
  9. Extra :额外信息
    出现 Using filesort、Using temporary 必须优化

7. ABA 问题是什么?怎么解决?(version 机制)

详细回答:

ABA 问题

CAS 机制中:

  • 线程1将 A → B
  • 线程2将 B → A
  • 线程3再 CAS:A 没变,更新成功

值虽然是 A,但中间被改过,业务可能出错。

解决方案

版本号机制(version)

每次修改版本号 +1,CAS 时不仅比较值,还要比较版本。

典型应用:

  • MySQL 乐观锁
  • AtomicStampedReference(Java 版本号原子引用)

8. JDK8 和 JDK17 各自特性

详细回答:

JDK 8 核心特性

  • Lambda 表达式 & 函数式接口
  • Stream 流式编程
  • Optional 空指针安全
  • 新日期 API(LocalDateTime)
  • 默认方法
  • Metaspace 替代永久代
  • Nashorn JS 引擎
  • 并行流

JDK 17 核心特性

  • Sealed Class(密封类,限制继承)
  • Pattern Matching(模式匹配)
  • Record 数据类(简化 POJO)
  • Text Block 文本块(""" 多行字符串 """)
  • ZGC 正式成熟(低延迟垃圾回收)
  • 移除 Security Manager、Applet
  • 封装内部 API,无法直接访问 sun.misc 等
  • 虚拟线程(JDK19 正式,17 预览)

9. Spring 事务失效场景(高频)

详细回答:

  1. @Transactional 加在非 public 方法上
  2. 同类内部方法调用(this.方法())
    没走代理,事务失效
  3. 异常被 catch 吃掉了
    不抛异常 → 不回滚
  4. 抛出非 RuntimeException
    默认只回滚运行时异常
  5. 传播行为配置错误
    如 NOT_SUPPORTED、NEVER
  6. 数据库引擎不支持事务(MyISAM)
  7. 没有被 Spring 管理(未加 @Service/@Component)
  8. 多线程调用
    新线程不在原有事务中

10. ThreadLocal 使用场景

详细回答:

ThreadLocal 是线程本地变量,每个线程独立副本。

典型场景:

  1. 存储用户登录信息
    拦截器存入,Controller/Service 直接获取,避免层层传递。
  2. 数据库连接/会话管理
    保证一个线程一个连接。
  3. 请求上下文
    日志 traceId、请求ID。
  4. 线程安全的简单工具
    如 SimpleDateFormat 替换为 ThreadLocal 副本。

注意:线程池必须 remove,否则内存泄漏、数据错乱。


11. 复制算法为什么快?

详细回答:

复制算法(Java 新生代 From/Eden 区):

  1. 内存连续
    只移动存活对象,无内存碎片。
  2. 避免标记-整理
    不用移动大量对象,不用内存压缩。
  3. 只需复制存活对象
    新生代对象朝生夕死,存活率极低,复制量小。
  4. 分配简单
    存活对象挪到 To 区,指针碰撞分配,极快。

所以复制算法适合存活对象少的场景,速度远超标记清除、标记整理。


12. Redis 主从集群扩容之后,数据怎么同步?

详细回答:

如果是主从(主从复制)扩容

  1. 新从节点启动,发送 PSYNC
  2. 主节点 bgsave 生成 RDB
  3. 发送 RDB + 增量命令
  4. 完成全量同步 → 进入增量同步

如果是 Redis Cluster 集群扩容

  1. 新节点加入集群
  2. 手动分配槽(reshard)
  3. 槽对应数据从旧节点迁移到新节点
  4. 迁移过程对客户端透明
  5. 迁移完成后更新集群拓扑

整个过程不宕机、可平滑扩容


下面是我补的 8 道题,凑齐 20 道完整篇

13. ZSet 底层结构是什么?适用场景?

详细回答:

底层:压缩列表(ziplist)+ 跳表(skiplist)+ 哈希表

跳表优点:

  • 有序
  • 查找近似二分,O(logN)
  • 实现比红黑树简单

场景:

排行榜、延时队列、范围查询、带权重排序。


14. 分布式事务 Seata AT 模式原理

详细回答:

AT 模式是无侵入分布式事务

  1. 拦截 SQL,生成前镜像
  2. 执行业务 SQL
  3. 生成后镜像
  4. 注册分支事务
  5. TC 协调 commit/rollback
  6. 回滚时用前后镜像恢复数据

核心:两阶段提交 + 镜像自动回滚


15. 消息队列重复消费怎么解决?

详细回答:

  1. 业务幂等
    唯一主键、状态机、版本号。
  2. 全局唯一 ID + 去重表
    消费前先查是否已处理。
  3. Redis 记录消费标识
    消费成功 set 标记。
  4. 消息队列提供Exactly Once语义(如 Kafka 事务)

核心思想:保证幂等性


16. 强一致、最终一致、顺序一致性区别

详细回答:

  • 强一致:任何时刻所有节点数据一致(CP 系统)
  • 最终一致:允许短暂不一致,最终一致(AP 系统)
  • 顺序一致:不保证绝对一致,但保证所有节点看到操作顺序相同

Redis 最终一致;ZooKeeper / etcd 强一致;Kafka 顺序一致。


17. 微服务接口限流算法

详细回答:

  1. 计数器
    简单粗暴,临界突刺问题
  2. 滑动窗口
    细分窗口,解决突刺
  3. 漏桶算法
    匀速出水,削峰
  4. 令牌桶算法
    允许突发流量(Guava/Sentinel 都用)

生产常用:令牌桶


18. MySQL 索引最左前缀原则

详细回答:

联合索引(a,b,c),能命中的情况:

  • a
  • a,b
  • a,b,c

跳过前面字段则失效:

  • b
  • b,c
  • a,c

本质:B+ 树按索引从左到右排序。


19. JVM 内存结构(JDK8+)

详细回答:

  1. :新生代 + 老年代
  2. 元空间 Metaspace(本地内存)
  3. 虚拟机栈:方法栈帧
  4. 本地方法栈
  5. 程序计数器
  6. 方法区(逻辑概念,落地为 Metaspace)

20. 怎么定位线上 OOM?

详细回答:

  1. 开启 OOM 自动 dump
  2. 用 MAT/JProfiler 分析堆 dump
  3. 看大对象、集合泄漏、线程泄漏
  4. 检查 FullGC 频率
  5. 定位代码:静态集合、ThreadLocal 未 remove、连接未关闭
  6. 优化:对象池、缩短生命周期、及时释放资源
相关推荐
sg_knight2 小时前
如何实现“秒传”与“断点续传”?MinIO + Java 实战进阶篇
java·开发语言·文件管理·minio·ftp·oss·文件传输
Flittly2 小时前
【SpringAIAlibaba新手村系列】(15)MCP Client 调用本地服务
java·笔记·spring·ai·springboot
少许极端2 小时前
算法奇妙屋(四十四)-贪心算法学习之路11
java·学习·算法·贪心算法
鱼鳞_2 小时前
Java学习笔记_Day24(HashMAap)
java·笔记·学习
Flittly2 小时前
【SpringAIAlibaba新手村系列】(14)MCP 本地服务与工具集成
java·spring boot·笔记·spring·ai
夜珀2 小时前
OpenTiny NEXT 从入门到精通·第 4 篇
开发语言
范什么特西2 小时前
web练习
java·前端·javascript
小樱花的樱花2 小时前
1 项目概述
开发语言·c++·qt·ui
阿捞22 小时前
JVM排查工具单
java·jvm·python