当前位置: 首页 > news >正文

互联网大厂Java面试:Spring Boot/Redis/Kafka/K8s 可观测 + RAG(向量检索/Agent)三轮追问实录

互联网大厂 Java 面试实录:Spring Boot + Redis + Kafka + Kubernetes + RAG(向量检索/Agent)三轮追问

场景:某内容社区与UGC平台,近期上线“RAG 智能客服”(企业文档问答 + 工单流转),并要求支持高并发、可观测、可灰度。

人物:

  • 面试官(M):严肃、节奏快、喜欢追问“为什么”。
  • 小Y(Y):自称“全栈Java”,实际有点水但很会搞笑。

第一轮:Java 基础与 Web 入门(3-5问)

Q1:M:Java 8/11/17 你最常用哪些新特性?在我们“UGC内容审核/客服系统”里会怎么用?

Y:Java 8 就是……Lambda!Stream!写起来像在写 SQL,挺爽的。Java 11/17……我一般用 8,兼容性好。

M:Java 8 用得熟是好事,但别把“只会8”当优点。说说你在代码里怎么落地 Stream 的?

Y:比如把用户列表stream().filter()一下……然后就更优雅了。

M:还行,基础没丢。


Q2:M:Spring MVC 和 Spring WebFlux 有什么区别?我们智能客服“长连接/流式输出”该选哪个?

Y:MVC 是同步阻塞,WebFlux 是……反应式!就很快!

M:快不快不是口号。背后模型是什么?

Y:呃……就是 Reactor,Mono/Flux,那种“流”。

M:回答有点虚,但方向对。我们后面会追。


Q3:M:HikariCP 为什么普遍比 C3P0 受欢迎?你在 Spring Boot 怎么配置连接池参数?

Y:因为……Hikari 轻量、快!配置我一般用spring.datasource.hikari.*

M:行,能说出关键点。比如连接池满了会怎样?

Y:会……排队?

M:至少知道会阻塞/等待。继续。


Q4:M:如果线上出现“接口偶发超时”,你第一步看什么?日志怎么打?

Y:我先看 ELK!再看日志里有没有 error。日志用 SLF4J,log.info("xxx {}", id)

M:参数化日志不错,避免字符串拼接。还可以。


第二轮:微服务、缓存、消息队列(业务递进)(3-5问)

业务设定:UGC平台的“智能客服”接入站内私信与工单。用户提问后,系统要:

  1. 先查缓存命中“常见问题”;
  2. 未命中则走 RAG:向量检索 + LLM 生成;
  3. 生成结果与引用片段落库;
  4. 异步写入 Kafka 做埋点与质检。

Q1:M:你会怎么设计 Redis 缓存结构,避免热点 Key 和缓存穿透?

Y:热点 Key 我就加本地缓存 Caffeine!穿透就……加布隆过滤器?

M:不错,能说到点上。布隆过滤器怎么落地?

Y:就……Guava 有 BloomFilter,放 Redis 也行。

M:思路可以,但细节要补。


Q2:M:Kafka 和 RabbitMQ 怎么选?我们这里“埋点/质检/回放”更适合哪个?

Y:Kafka 吞吐高,RabbitMQ 延迟低?我感觉都行,看团队喜好。

M:(皱眉)“都行”是面试大忌。说出语义:顺序、消费模型、回放、消息堆积。

Y:Kafka 可以回放,按 partition 顺序;RabbitMQ 更像传统队列。

M:这句对了。


Q3:M:你会如何做微服务间调用?OpenFeign + Resilience4j 怎么配合?

Y:Feign 调用很方便,Resilience4j 就是限流熔断降级。我一般加个 fallback。

M:fallback 只是表面。重试、超时、隔离、舱壁这些怎么选?

Y:看感觉……哪个报错就加哪个。

M:嗯,开始“凭感觉写代码”了。


Q4:M:数据库层:MyBatis 和 JPA/Hibernate 你怎么选?RAG 结果落库的表会怎么设计?

Y:复杂 SQL 用 MyBatis,简单 CRUD 用 JPA。表设计就:question、answer、time。

M:字段太少。引用片段、模型版本、embedding版本、traceId、反馈标签呢?

Y:啊对对对,可以再加。

M:……


第三轮:云原生可观测 + AI 工程化(3-5问)

业务设定升级:RAG 客服上线后出现:

  • 高峰期 P95 延迟抖动
  • 偶发“答非所问”(幻觉)
  • 模型供应商切换(OpenAI ↔ Ollama/自建)
  • 需要对接企业知识库,支持文档加载与增量更新

Q1:M:Kubernetes 上部署 Spring Boot,你会重点关注哪些资源与探针?怎么做灰度?

Y:资源就 CPU、内存;探针有 liveness、readiness;灰度用……分批发布?

M:基本点都对。灰度更细一点:Service、Ingress、或者 Service Mesh。你再想想。

Y:可以用 Kubernetes 的 rollout……或者直接手动?

M:行吧。


Q2:M:Prometheus + Grafana + Micrometer 你会采哪些指标定位“P95抖动”?

Y:JVM 指标、GC 指标、线程池指标……还有接口耗时。

M:继续。你如何区分是“下游慢”还是“GC慢”还是“连接池耗尽”?

Y:我看图……哪个高就哪个。

M:过于朴素。


Q3:M:链路追踪 Jaeger/Zipkin 怎么把一次“RAG请求”串起来?要打哪些 tag?

Y:traceId 串起来,span 里面写“检索”和“生成”。

M:还不够。向量检索命中数、topK、prompt token、completion token、模型名、温度、知识库版本都要。

Y:这些也能打吗?那我都打上。

M:……打多了也会贵。


Q4:M:谈谈 RAG 的“文档加载→向量化→语义检索→提示填充→生成→引用校验”。你怎么降低幻觉?

Y:幻觉就……让模型别乱说?提示词写严格点。

M:(沉默两秒)继续。

Y:加个“如果不知道就说不知道”。

M:这是入门级。还可以:检索质量、chunk策略、引用强约束、回答后验证、以及 Agentic RAG 的工具执行。

Y:我回去研究一下。


Q5:M:Spring AI / MCP / 工具调用标准化:如果要让客服 Agent “查订单、查物流、建工单”,你会怎么设计工具接口?

Y:我就写三个接口给它调……

M:怎么做权限、审计、幂等、防重复下单?

Y:呃……加 Spring Security?JWT?

M:至少知道安全框架。细节先到这。


面试收尾

M:今天整体看下来,你 Java/Spring 基础还可以,场景理解也有,但在可观测细化、容灾治理、以及 RAG 工程化细节上比较虚。你回去把这些链路再系统补一下,我们会综合评估,回家等通知

Y:好的好的,我回去就把“凭感觉”升级成“凭数据”。


文末复盘:所有问题的详细答案(含业务落地)

下面按三轮问题逐一给出更“能上生产”的回答,小白可按此学习与扩展。


第一轮答案:Java / Web / 连接池 / 日志

A1:Java 8/11/17 常用特性与落地

  • Java 8
    • Lambda/Stream:用于集合处理、DTO转换、过滤排序。
    • Optional:减少空指针,但避免滥用(不要把 Optional 当字段类型)。
    • CompletableFuture:并行调用(如“FAQ缓存查询 + 热门知识库检索”可并发)。
  • Java 11
    • HttpClient:替代老旧 HttpURLConnection(微服务一般仍用 OkHttp/Apache HC)。
    • String/Collection API 增强。
  • Java 17
    • 记录类 record:适合不可变 DTO(如检索结果、Embedding请求响应)。
    • switch 表达式、文本块:拼 Prompt 更安全可读。

UGC/客服落地示例:

  • 并行:CompletableFuture同时拉取“用户画像/历史工单/常见FAQ”,最终合并为提示上下文。

A2:Spring MVC vs WebFlux,流式输出怎么选

  • Spring MVC:Servlet 模型,线程-per-request,适合传统 CRUD。
  • Spring WebFlux:基于 Reactor(Mono/Flux),非阻塞 I/O,适合:
    • SSE/WebSocket 流式输出(LLM token streaming)
    • 高并发下减少线程占用(但需要全链路非阻塞:Netty + R2DBC/Reactive Redis等)

选择建议:

  • 现有系统若大量阻塞组件(JPA/JDBC),强上 WebFlux 可能“表面Reactive、内部阻塞”。
  • 折中方案:核心仍 MVC,但对“生成回答”单独做 WebFlux/SSE 网关服务;或用异步 Servlet + chunked response。

A3:HikariCP 优势与关键参数

  • 优势:
    • 代码路径短、锁竞争少、性能稳定;Spring Boot 默认。
  • 关键配置:
    • maximumPoolSize:并发上限(结合 DB 连接限制与QPS评估)
    • minimumIdle:空闲连接
    • connectionTimeout:拿不到连接等待多久(避免线程无限挂)
    • leakDetectionThreshold:连接泄露检测(排查未关闭连接)

现象定位:

  • 接口超时可能来自:连接池耗尽(active=maximumPoolSize)、慢SQL、事务未提交、连接泄露。

A4:接口偶发超时的排查与日志规范

排查优先级:

  1. 指标:P95/P99、线程池/连接池、GC、下游依赖延迟
  2. 日志:是否有超时/重试/熔断
  3. 链路追踪:定位慢在网关、服务、DB、MQ、第三方

日志实践:

  • 统一用SLF4J + Logback/Log4j2,参数化:log.info("orderId={}", id)
  • 关键链路打印:traceId、用户id、请求耗时、下游耗时、错误码
  • 注意脱敏(手机号、身份证、token)。

第二轮答案:缓存 / MQ / 微服务治理 / ORM与表设计

A1:Redis 缓存结构 + 热点Key + 穿透

缓存目标:FAQ命中、检索结果短缓存、会话上下文。

设计:

  • Key 设计:
    • faq:answer:{normalizedQuery}
    • rag:retrieval:{queryHash}(短TTL)
  • 热点 Key:
    • 本地缓存 Caffeine+ Redis 二级缓存;热点FAQ可以预热。
    • 对极热点可用 Redis Cluster + Key hash tag、或拆分多Key。
  • 缓存穿透:
    • 布隆过滤器:对“FAQ问题集合/知识库文档id集合”做存在性判断。
    • 对确实不存在的请求写入空值缓存(短TTL)避免重复打DB。
  • 缓存击穿:
    • 互斥锁/单飞:SETNX或 Redisson Lock,确保同一key回源只发生一次。

A2:Kafka vs RabbitMQ 的选择(埋点/质检/回放)

  • Kafka更适合:
    • 高吞吐日志/埋点
    • 消费者组并行
    • 消息回放(按 offset 重放质检)
    • 长时间堆积(磁盘顺序写)
  • RabbitMQ更适合:
    • 复杂路由(topic/headers)
    • 每条消息确认与低延迟队列语义
    • 业务命令型消息(更强“队列感”)

本场景建议:

  • 埋点、质检、对话回放:Kafka
  • 工单创建这类强一致命令:可用 RabbitMQ 或事务外盒 + DB。

A3:OpenFeign + Resilience4j 的治理组合

常见组合:

  • Feign:声明式HTTP客户端
  • Resilience4j:
    • TimeLimiter:超时
    • Retry:谨慎使用(只对幂等GET或可重试错误)
    • CircuitBreaker:熔断,防止雪崩
    • Bulkhead:舱壁隔离(线程池/信号量隔离)
    • RateLimiter:限流

推荐策略(客服RAG):

  • 检索服务:超时短(如 200-400ms),失败可降级“少量topK”或“只走FAQ”。
  • LLM生成:超时较长(如 3-10s),失败返回“转人工/创建工单”。
  • 对下游依赖加 Bulkhead,避免生成占满线程池拖垮全站。

A4:MyBatis vs JPA/Hibernate,RAG落库表设计

选型:

  • MyBatis:复杂SQL、报表、多表join可控。
  • JPA/Hibernate:领域模型清晰、CRUD高效,但复杂SQL可能难维护。
  • 也可:Spring Data JDBC(更轻量)

RAG结果建议表:rag_conversation_turn

  • id
  • conversation_id(会话)
  • user_id
  • question_text
  • answer_text
  • citations(JSON:文档id、chunkId、score、offset)
  • retrieval_topkhit_count
  • kb_versionembedding_modelllm_modelprompt_version
  • token_prompttoken_completion
  • latency_ms(总耗时+分段耗时)
  • trace_id
  • feedback(like/dislike/标签)
  • created_at

配套:

  • Flyway/Liquibase管理表结构演进。

第三轮答案:K8s、可观测、链路追踪、RAG与Agent工程化

A1:Kubernetes 部署要点 + 探针 + 灰度

  • 资源:
    • requests/limits 合理设置,避免 OOMKilled 或 CPU throttling
    • JVM 参数与容器协同(如-XX:MaxRAMPercentage
  • 探针:
    • readiness:依赖就绪(DB/MQ连接、缓存预热)
    • liveness:死锁/假死检测(不要把外部依赖失败当liveness失败)
  • 灰度:
    • 多 Deployment(v1/v2)+ Service 按标签切流
    • Ingress/Nginx 按 header/cookie 做灰度
    • 或使用 Service Mesh(Istio)做更精细流量治理

A2:Micrometer/Prometheus 指标定位 P95 抖动

必采指标:

  • HTTP:QPS、P50/P95/P99、错误率
  • JVM:GC次数/停顿、堆使用、线程数
  • 线程池:active、queue size、reject count
  • 连接池:Hikari active/idle/pending
  • 下游依赖:HTTP client latency、DB query latency、Kafka produce latency

定位方法:

  • 若 GC pause 与延迟同周期上升:调堆、对象分配、缓存结构。
  • 若 Hikaripending上升:慢SQL/连接泄露/池太小。
  • 若下游依赖延迟上升:加超时、隔离、熔断、降级。

A3:Jaeger/Zipkin 链路追踪:RAG一次请求的 Span 设计

建议 span:

  1. http:entry
  2. cache:faq_get
  3. retrieval:vector_search
  4. prompt:render
  5. llm:completion
  6. postprocess:citation_check
  7. db:save_turn
  8. mq:kafka_produce

关键 tags(选取必要的,避免过量):

  • conversationIduserId
  • topKhitCountmaxScore
  • kbVersionembeddingModelllmModelpromptVersion
  • tokensPrompttokensCompletion
  • provider(OpenAI/Ollama)
  • fallback是否触发

A4:RAG 全流程与降低幻觉的工程手段

流程:

  1. 文档加载(PDF/HTML/Confluence等)
  2. 清洗切分(chunk:长度、重叠、按标题层级)
  3. 向量化(Embedding模型)
  4. 向量库(Milvus/Chroma/Redis Vector)存储与索引
  5. 语义检索(topK、相似度阈值、混合检索BM25+向量)
  6. 提示填充(把“引用片段”注入prompt)
  7. 生成(LLM)
  8. 引用校验与后处理(必须基于引用回答)

降幻觉:

  • 检索质量:合理 chunk、去噪、增量索引、阈值过滤
  • 强约束回答格式:要求输出引用id;无引用则拒答/转人工
  • 回答后验证:
    • 规则校验(是否引用)
    • 轻量模型/模板校验
  • Agentic RAG:当问题需要“查订单/查物流”时,先工具调用拿到确定性数据,再生成。

A5:Spring AI / MCP / 工具调用标准化:工具接口设计

目标:让 Agent 安全、可审计、可扩展地调用业务能力。

做法:

  • 工具清单(Tool Registry):
    • getOrderStatus(orderId)
    • trackShipment(trackingNo)
    • createTicket(category, content, attachments)
  • 关键工程点:
    • 鉴权:Spring Security + OAuth2/JWT,工具执行必须带用户上下文
    • 审计:记录 toolName、参数摘要、结果摘要、traceId、耗时
    • 幂等:如创建工单用幂等键(conversationId + turnId)
    • 权限与风控:敏感操作二次确认、限频(Resilience4j RateLimiter)
    • 客户端-服务器架构:Agent服务作为客户端,业务系统提供工具API(或通过 MCP 统一协议暴露)

学习路线(按面试暴露短板补齐)

  • JVM/性能:GC、线程池、连接池、火焰图
  • 微服务治理:超时/重试/熔断/隔离/限流的组合策略
  • 可观测:指标 + 日志 + 追踪三件套联动
  • RAG工程:chunk/索引/阈值/引用约束/工具调用与审计

http://www.jsqmd.com/news/658294/

相关文章:

  • RabbitMQ实战:流控机制(Flow Control)全解析——原理、触发、流程与实战
  • 告别AI幻觉:用ReAct模式手把手教你构建一个会‘查资料’的智能问答助手
  • 保姆级教程:在Orange Pi 5 Max上从零配置ROS+PX4无人机仿真环境(Ubuntu 20.04)
  • 多通道热红外辐射计温度系数校准研究
  • 如何快速批量保存小红书无水印内容:XHS-Downloader完整指南
  • 从设备入库到报废:设备档案管理能解决哪些场景痛点?一套设备档案管理系统的实战应用
  • Redis Cluster Slot 分布逻辑
  • MyBatis 使用步骤、实现原理与 MyBatis-Plus 扩展功能详解》
  • RabbitMQ实战:消息批量消费完全解析——原理+配置+SpringBoot代码+避坑指南
  • 从ET规则集看Suricata规则实战筛选与部署策略
  • 暗黑破坏神2存档编辑器:打造个性化游戏体验的完整指南
  • 洛洛王国-超时
  • 高效脚本编写:用Codex告别重复造轮子
  • 为什么先安慰,比先讲道理更有效(为什么这里会有这么一篇博客)
  • 算法训练营第四天|203. 移除链表元素
  • MATLAB量化工具箱实战:从quantizer配置到quantize应用
  • Linux搭建校园网络项目
  • 负采样:从Softmax瓶颈到高效词嵌入的工程实践
  • AUTOSAR MCAL实战:Dio_ChannelGroup配置详解与S32K144端口操作技巧
  • 以为生活缺的是标准答案,其实是丧失了“拆解”的能力
  • 如何用10个Illustrator脚本实现设计自动化:从手动操作到智能工作流的终极指南
  • golang如何实现图片水印批量添加_golang图片水印批量添加实现策略
  • Zotero Reference终极指南:如何3分钟内自动提取PDF文献参考文献
  • 快速上手Qwen2.5-7B微调:单卡10分钟体验AI训练
  • RDPWrap完整指南:免费解锁Windows远程桌面多用户并发连接
  • 别再只把JWT当令牌了:一个CTF实战案例,手把手教你用Burp Suite和jwt.io破解伪造
  • 从零构建垃圾分类识别系统:基于8万张图片与TensorFlow的实战指南
  • 揭秘Ribbon负载均衡:轻松实现请求分摊
  • iOS捷径(快捷指令)注入JavaScript:在移动端实现网页元素动态调试与修改
  • 监督学习、无监督学习、强化学习基础对比