面灵AI→

武汉亚信科技后端面经:Spring Boot 启动、并发工具与中间件选型

时间
2026-10
来源
牛客网

《面试题目》

开场与意向确认

  1. 你是大三吗?实习周期大概能安排多久?
  2. 学校是否允许全职实习?能否解决异地租房问题?
  3. 你未来的技术方向偏向哪一块?

Java 后端基础

  1. 请描述一下 Spring Boot 的启动过程。
  2. Spring Boot 的启动入口函数是什么?
  3. 你了解 SingleFlight 框架吗?它和分布式锁有什么区别?
  4. CAS 乐观锁的原理是什么?存在哪些潜在问题?
  5. 在项目中,你更偏好使用哪种锁?为什么?
  6. 如果部署多实例,SingleFlight 框架会有什么问题?如何解决?
  7. 你写过哪些脚本?有没有遇到过 MySQL 索引失效的情况?哪些场景会导致索引失效?
  8. 为什么单表数据量过大会导致索引失效?
  9. 如果接口响应变慢,你会如何排查?
  10. 主线程如何判断子线程已经执行完毕?有哪些实现方式?
  11. 除了 CompletableFuture,还有其他方式吗?比如 join 函数你用过吗?

消息队列与中间件

  1. 你用过哪些消息队列?
  2. 请对比一下 RabbitMQ 和 Kafka 的区别及使用场景。
  3. Redis 支持哪些数据结构?底层有什么优化机制?

语言对比与项目经验

  1. 你同时掌握 Java 和 Python,它们之间有什么区别?
  2. 用 Java 对接 AI 大模型,相比传统 CRUD 项目有什么挑战?
  3. 你简历上写了 Spring AI,这个项目是你独立完成的吗?
  4. 你有服务器部署经验吗?具体怎么操作?
  5. 你用过 Docker 容器化部署吗?怎么用?
  6. 你了解 JVM 调优吗?具体有哪些参数或手段?

业务介绍与反问环节

  1. 你了解我们公司吗?有没有了解过我们的业务?
  2. 你入职后希望接触什么方向的业务?
  3. 你接触过基于 AI 的提效工具(如 Cursor)吗?
  4. 这次面试的结果什么时候能出来?后续还有哪些流程?

《参考解析》

Spring Boot 启动过程:入口是 main 方法里的 SpringApplication.run。流程大致是:创建 SpringApplication(推断应用类型、加载 ApplicationContextInitializer 与 ApplicationListener)→ 准备环境(读取配置文件、命令行参数、环境变量,发布 EnvironmentPrepared)→ 创建并准备 ApplicationContext → 刷新容器(refresh:解析配置类、BeanFactoryPostProcessor、注册 BeanPostProcessor、实例化单例、启动内嵌 Web 容器)→ 发布 ApplicationStarted/Ready 事件 → 执行 ApplicationRunner/CommandLineRunner。自动配置的关键是 @SpringBootApplication 里的 @EnableAutoConfiguration,它通过 AutoConfigurationImportSelector 读取 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports(Spring Boot 3)并按 @Conditional 条件过滤。

SingleFlight 与分布式锁:分布式锁解决「同一时刻只允许一个执行者」,强调互斥;SingleFlight 解决「同一个 key 的并发请求只执行一次,其余复用结果」,强调去重与共享。两者都涉及「谁执行」,但 SingleFlight 的等待者不是被阻塞在临界区外,而是等待同一个结果;锁的持有者执行完就释放,SingleFlight 的结果可能还要缓存一段时间。多实例部署时,单机版 SingleFlight 只能合并本机请求,跨实例仍会重复调用;要么把选举放到 Redis(SET NX PX + 结果 key + 订阅/轮询),要么接受重复并在下游做幂等。

CAS 的问题:ABA、长时间自旋、只能保护单个变量。ABA 用版本号或 AtomicStampedReference;自旋用限制次数、退避、或直接升级为锁;多变量用锁或不可变对象整体替换。选锁的原则是「临界区长短、竞争强度、是否跨进程」:进程内短临界区用 synchronized/ReentrantLock,跨进程用 Redis/ZooKeeper 分布式锁,读多写少且能容忍短暂不一致时用乐观锁。

索引失效与单表数据量:索引失效的语法原因见上一类问题(函数、隐式转换、前导通配、最左前缀、OR 等)。「单表数据量大导致索引失效」这个说法不准确——索引不会因为数据多而失效,真正发生的是:B+ 树层数增加导致磁盘 I/O 变多、buffer pool 命中率下降、优化器估算后认为全表扫描更便宜、以及维护索引的成本上升。表现上像「索引不灵了」,本质是数据量与访问模式变了。应对是归档冷数据、分区、覆盖索引、读写分离,最后才是分库分表。

慢接口排查:先看监控定位是哪个接口、哪个时间段、是否伴随流量突增或发布;再看链路追踪(SkyWalking/OpenTelemetry)找耗时最长的 span;然后分四层查:入口(连接数、线程池是否打满、GC 停顿)、应用(锁竞争、慢 SQL、序列化、外部调用)、数据库(慢查询日志、执行计划、锁等待)、下游(超时、重试风暴)。用 jstack 看线程栈、jmap/jstat 看堆与 GC;不要一上来就调参数。

主线程等待子线程:Thread.join()、Future.get()、CountDownLatch.await()、CyclicBarrier、CompletableFuture.allOf(...).join()、ExecutorService.invokeAll()。区别:join 只能等线程结束、拿不到返回值;Future.get 能拿结果但阻塞;CountDownLatch 适合「等 N 个任务完成」但不重复使用;CompletableFuture 能组合、异常处理和超时更灵活。生产上还要设置超时,避免无限等待。

RabbitMQ 与 Kafka:RabbitMQ 是传统消息代理,强调可靠投递、灵活路由(Exchange/Queue/Binding)、低延迟,适合业务解耦、任务分发、RPC 式调用;Kafka 是分布式日志,强调高吞吐、顺序写、分区并行、可回放,适合日志采集、流处理、事件溯源。选型看吞吐与消费模型:需要复杂路由和逐条确认选 RabbitMQ,需要海量吞吐和回溯选 Kafka。两者都要考虑重复消费(幂等)、顺序(分区键)、积压与死信。

Redis 数据结构与底层:String、List、Hash、Set、ZSet、Bitmap、HyperLogLog、GEO、Stream。底层是「对象 + 编码」:String 用 SDS(预分配、二进制安全),小字符串用 embstr;List 早期用 ziplist/linkedlist,现在用 quicklist(链表套压缩列表);Hash 小数据用 listpack/ziplist,大了转 hashtable;Set 用 intset 或 hashtable;ZSet 用 listpack 或 skiplist + dict;还有渐进式 rehash、过期删除(惰性 + 定期)、内存淘汰策略。回答时挑两三个讲透,比报菜名好。

Java 与 Python:Java 静态类型、编译成字节码跑 JVM、强类型、生态偏企业级、并发模型基于线程与锁;Python 动态类型、解释执行、开发效率高、生态偏数据与 AI、GIL 限制 CPU 并行。选型看团队与场景:高并发长生命周期的服务偏 Java,数据处理、模型实验、脚本偏 Python。

Java 对接大模型的挑战:流式输出(SSE/WebSocket)与背压、超时与重试、token 计费与配额、上下文管理与截断、结构化输出的校验、模型不稳定的降级、以及多模型渠道的抽象。传统 CRUD 是「请求-响应确定且快」,大模型是「长耗时、非确定、按量计费」,线程池、连接池、事务边界都要重新设计,不能让模型调用占满业务线程。

部署与 Docker:部署讲清「构建产物 → 镜像 → 推送仓库 → 目标机拉取 → 启动 → 健康检查 → 回滚」。Docker 的常用命令是 build、run、ps、logs、exec、compose up -d;镜像用多阶段构建减小体积,配置用环境变量注入,数据卷持久化,健康检查配合重启策略。

JVM 调优:先测量再调。常用参数:-Xms/-Xmx(堆初始/最大,建议相等避免动态扩缩)、-Xmn 或 -XX:NewRatio(新生代)、-XX:MetaspaceSize、-XX:+UseG1GC、-XX:MaxGCPauseMillis、-XX:ParallelGCThreads、-Xss(栈大小)、-XX:+HeapDumpOnOutOfMemoryError。工具用 jps、jstat -gc、jmap、jstack、jcmd、VisualVM/Arthas。调优目标是满足停顿与吞吐指标,不是把参数调「大」。

公司与反问:亚信科技主要做电信运营商支撑系统(BSS/OSS)、数字化运营与云网服务,客户以运营商和大型企业为主。反问可以问团队的技术栈、新人培养、实习转正机制、以及当前业务面临的挑战;结果时间按 HR 的说法回答,不要替公司承诺。