《Java 17、Spring Boot、Spring Cloud、Redis、Kafka、Spring AI 与 Kubernetes:互联网医疗+AIGC平台的大厂面试实录》
凌晨十点,某互联网大厂会议室。
玻璃门一关,气压立刻低了三度。
面试官周工,表情严肃,像是连 NullPointerException 都不敢在他面前随便抛。
求职者王小二,简历写着“精通 Java 全家桶,熟悉 AI Agent、RAG、微服务、云原生、大数据生态”。
他坐下时很自信,坐稳后又有点像刚被 GC 标记过。
这次面试的业务背景,是一套互联网医疗健康管理+AIGC智能客服平台。
平台包含在线问诊、健康档案、药品商城、医生排班、智能客服、企业知识库问答、订单支付、风控审计等模块,技术栈以 Java 为主,运行在 Kubernetes 上。
第一轮:从单体到微服务,先看你能不能把系统搭起来
问题1:
面试官:
假设我们要做一个互联网医疗平台,包含用户、医生、挂号、订单、支付、病历、智能客服几个核心模块。你会怎么用 Java 技术栈做第一版架构?选型也说一下。
王小二:
这个……我会用 Java 17,因为新一点,看起来比较高级。然后框架嘛,肯定 Spring Boot,启动快,面试也爱听。
服务拆分的话,就拆成用户服务、医生服务、订单服务、支付服务、病历服务、客服服务。
数据库用 MySQL,ORM 我一般 MyBatis 和 JPA 都能写,看团队风格。
服务之间可以用 OpenFeign 调,注册发现可以用 Eureka 或 Consul。
缓存上 Redis,消息队列上 Kafka 或 RabbitMQ。
部署的话 Docker 加 Kubernetes,监控就 Prometheus 和 Grafana。
面试官:
回答得还算完整,至少不是“一个 Controller 走天下”。
那你继续说,为什么第一版不是直接上 WebFlux 和 R2DBC 全异步?
王小二:
因为……因为先活下来比较重要。大部分医疗后台还是 CRUD 比较多,Spring MVC 配合 JPA、MyBatis 更稳。WebFlux 更适合高并发 I/O 场景,比如流式推送、AI 对话。
面试官:
不错,这句说到点子上了。
问题2:
面试官:
挂号服务里,医生排班和患者预约很容易出现并发冲突。比如同一个号源最后一个名额,被两个人同时抢到。你怎么处理?
王小二:
这个我会先想到数据库层。
比如库存字段 remaining_count,更新时带条件:where remaining_count > 0,更新成功才算抢到。
也可以用乐观锁版本号,比如 JPA 的 @Version。
如果并发更大,就加 Redis 做预扣减,再异步落库。
实在不放心,还可以把预约请求丢 Kafka,排队串行消费。
面试官:
行,知道“别让两个病人拿同一个号”这件事要靠数据一致性,不靠祈祷。
那 Redis 预扣减失败和数据库写入失败的补偿,你考虑了吗?
王小二:
这个……一般会有补偿任务。
或者用消息事务……或者本地消息表……
大概就是,不能让 Redis 和数据库各过各的。
面试官:
嗯,后半句开始有点飘了,不过方向没错。
问题3:
面试官:
你说说 MyBatis、JPA、Hibernate 在这个场景里怎么选。别背定义,说实际业务。
王小二:
如果是用户、医生、病历这种对象关系比较明确、关联也比较多的模块,我会偏 JPA/Hibernate,开发快,适合后台管理系统。
如果是订单、报表、复杂查询、分页筛选、多表统计,我更倾向 MyBatis,SQL 可控。
有些简单服务也可以用 Spring Data JDBC,模型更轻。
连接池用 HikariCP,性能和稳定性都更主流。
数据库版本管理可以上 Flyway 或 Liquibase。
面试官:
不错,这个回答挺像干过活。
那病历查询为什么不全上 Elasticsearch?
王小二:
因为 Elasticsearch 适合检索,不适合做强事务主存储。
病历原始数据还是落 MySQL,检索索引异步同步到 Elasticsearch 比较稳。
面试官:
很好。
问题4:
面试官:
如果挂号成功后,需要发送短信、站内信、医生工作台提醒、患者 App 消息,你会怎么设计消息链路?
王小二:
我会把“挂号成功”作为领域事件发出去。
订单服务提交成功后,发 Kafka 消息,多个消费者分别处理短信、App Push、医生提醒。
如果业务需要更强路由能力,也可以用 RabbitMQ。
消息体可以用 Jackson 序列化 JSON;如果追求高性能和跨语言,可以用 Protobuf 或 Avro。
为了避免重复消费,要做幂等,比如消息表、业务唯一键、去重 Redis Key。
面试官:
可以,至少你知道 MQ 不是“发了就一定成”。
第一轮到这里。
第二轮:系统能跑起来还不够,你得让它撑住、守住、看得见
问题5:
面试官:
现在平台用户量起来了,问诊高峰期每秒几千请求。你怎么做缓存设计?说说 Redis、Caffeine、Spring Cache 分别怎么用。
王小二:
Redis 适合分布式缓存,比如医生详情、科室列表、号源快照。
Caffeine 适合单机热点缓存,比如本机短期高频字典数据。
Spring Cache 可以统一缓存注解,底层接 Redis 或 Caffeine。
缓存要注意穿透、击穿、雪崩。
穿透可以布隆过滤器或缓存空值;击穿可以互斥锁或热点永不过期加异步刷新;雪崩要加过期时间随机化和多级缓存。
面试官:
不错,这段答得挺顺。
那患者健康档案能不能直接全部丢 Redis?
王小二:
不能。这个数据敏感、体量大、更新也复杂。Redis 更适合热点读,不适合作为长期主存。
核心还是数据库,缓存只是加速层。
面试官:
嗯,没把 Redis 当万能冰箱,这点很好。
问题6:
面试官:
支付和医疗数据都很敏感。你说说 Spring Security、JWT、OAuth2、Keycloak 在这个系统里怎么落地。
王小二:
用户登录可以用 Spring Security 做认证鉴权。
移动端和小程序登录后签发 JWT,网关校验令牌。
如果平台有医生端、患者端、运营后台、第三方药企后台,多租户和统一身份管理可以引入 OAuth2 或 Keycloak。
权限模型上可以做 RBAC,接口按角色、资源、数据范围控制。
敏感字段比如身份证号、手机号可以加密存储,必要时用 Bouncy Castle 做加解密能力支持。
此外,操作病历、处方这些高风险接口,要做审计日志。
面试官:
回答合格。
那 JWT 一旦签发,用户被封禁了怎么办?
王小二:
这个……可以缩短 JWT 有效期,再配合 Redis 黑名单。
或者做双 Token 机制,Access Token 短效,Refresh Token 控制续签。
面试官:
行,比“让用户重新登录试试”强。
问题7:
面试官:
微服务之间经常有超时、雪崩。你说说 OpenFeign、Resilience4j、网关限流、熔断降级怎么配合。
王小二:
服务调用可以用 OpenFeign。
如果医生服务慢了,订单服务直接同步等,就容易把线程池拖死。
所以要做超时控制、重试、舱壁隔离、熔断和限流,Resilience4j 很适合。
比如查询医生画像失败,就降级返回基础信息;推荐标签失败,不影响挂号主链路。
API 网关层可以做统一限流和鉴权,防止恶意刷接口。
下游不可用时,可以快速失败,不要层层等待。
面试官:
不错。
那重试是不是越多越好?
王小二:
不是。重试太多可能把本来就快挂的服务彻底按死。
重试只适合幂等读操作或少量可控场景,支付扣款这类要非常谨慎。
面试官:
很好,这句靠谱。
问题8:
面试官:
线上出了问题,你怎么排查?把日志、指标、链路追踪说完整。
王小二:
日志方面我会统一 SLF4J 门面,底层用 Logback 或 Log4j2。
把 traceId、userId、orderId 放到 MDC 里,便于串联日志。
指标方面用 Micrometer 暴露 JVM、线程池、HTTP、数据库连接池指标给 Prometheus,再用 Grafana 做看板。
链路追踪可以接 Jaeger 或 Zipkin,看一次请求经过了哪些服务。
日志聚合可以上 ELK Stack。
如果发现接口 RT 飙升,要看是 CPU 高、GC 频繁、数据库慢查询、MQ 堆积还是外部依赖超时。
面试官:
不错,排障思路比很多只会说“重启试试”的强。
第二轮结束。
第三轮:现在加 AI,别把系统做成“智能胡说平台”
问题9:
面试官:
公司现在要做 AI 智能客服,支持医保政策问答、医院流程问答、药品说明检索。你会怎么用 Spring AI 和 RAG 落地?
王小二:
这个我熟,我简历上写了三遍。
大概流程是:先把医院制度、药品说明书、医保文档、常见问答导入知识库;然后切片;然后向量化;再存到向量数据库,比如 Milvus、Chroma 或 Redis Vector。
用户提问后,先做语义检索,拿到相关片段,再拼进 Prompt,最后交给大模型回答。
Spring AI 可以帮我们统一模型调用、Embedding、向量检索这些流程。
这样比模型“裸答”更靠谱,能减少幻觉。
面试官:
嗯,这个回答不错。
那你继续说,文档切片怎么做?是按 1000 字一刀切?
王小二:
这个……也不一定。
有时候按标题层级切,有时候按段落切。
反正就是,切得太大检索不准,切得太小上下文不够。
要根据业务调。
面试官:
你这句虽然有点像废话,但确实是对的。
问题10:
面试官:
如果用户问:“我高血压还能不能吃这个药?”你觉得企业文档问答和医疗建议之间的边界怎么控制?怎么避免 AI 幻觉带来风险?
王小二:
这个不能让 AI 直接当医生。
可以把它定位成“信息辅助”,比如引用药品说明书、医院规范、挂号流程,而不是直接给诊断结论。
回答里要带来源片段、免责声明。
高风险问题可以触发转人工或转医生。
还可以做提示词约束,不在知识库里的问题不要乱答。
另外把审核规则加上,比如命中禁答词、处方建议、高风险病症,就不让模型自由发挥。
面试官:
可以,风险意识合格。
那如果用户追问十轮,系统怎么保留会话上下文?
王小二:
可以做聊天会话内存。
短期上下文存在 Redis,长期摘要落库。
也可以把历史对话摘要后再拼接到 Prompt 里,避免 Token 爆炸。
面试官:
嗯,还行。
问题11:
面试官:
如果我们要做 Agent,让 AI 帮用户完成“查报告、预约复诊、推送用药提醒”这种复杂工作流,你怎么设计工具执行框架?
王小二:
我会把 AI 当成决策层,不让它直接乱调内部系统。
先定义标准化工具接口,比如查询报告、查询排班、创建预约、发送提醒。
工具调用要有权限校验、参数校验、审计日志。
模型只负责决定“该调哪个工具”,真正执行还是后端服务做。
如果是多步骤流程,可以做状态机或者编排流。
如果再高级一点,还可以做 MCP 或类似协议,把工具能力标准化接入。
面试官:
前面说得不错。
那 Agentic RAG 和普通 RAG 的区别呢?
王小二:
这个……普通 RAG 就是检索再回答。
Agentic RAG 可能就是……更聪明一点?
会自己规划、多跳检索、可能还会调用工具。
大概是从“查一遍”升级成“边查边想边干”。
面试官:
你最后这句,土是土了点,但意思差不多。
问题12:
面试官:
最后一个问题。你怎么保证这套系统能持续交付?从测试、CI/CD 到上线发布说一下。
王小二:
单元测试用 JUnit 5、Mockito、AssertJ。
历史遗留不好 mock 的代码,可能会碰到 PowerMock,但新项目尽量少用。
接口测试可以用 Spring Boot Test,端到端页面流程可以用 Selenium,业务验收可以用 Cucumber。
构建用 Maven 或 Gradle。
CI/CD 用 Jenkins、GitLab CI 或 GitHub Actions。
打包 Docker 镜像,发到 Kubernetes。
数据库变更用 Flyway 或 Liquibase 管理。
发布可以做灰度、蓝绿或滚动更新。
上线后通过 Prometheus、Grafana、ELK 看指标和日志,不行就回滚。
面试官:
整体还行。
你会的东西不少,懂的深浅嘛……有些地方像温水泡枸杞,颜色有了,药劲差点。
今天先到这里,回去等通知吧。
王小二:
好的老师。我这边如果有结果,是您通知我,还是 Kafka 异步通知我?
面试官:
……门在你右手边。
面试题答案精讲
下面把上面 12 个问题的标准答案,用小白也能看懂的方式详细展开。
1. 互联网医疗平台第一版架构怎么设计?
业务场景
一个互联网医疗平台,至少会有这些核心能力:
用户注册登录、医生信息展示、排班挂号、订单支付、病历查看、消息通知、智能客服。
推荐技术方案
-
Java 版本:优先 Java 17,兼顾性能、语法增强、LTS 支持
-
基础框架:Spring Boot
-
Web 层:大多数后台接口用 Spring MVC
-
AI 对话或流式返回:可局部使用 Spring WebFlux
-
服务治理:Spring Cloud、OpenFeign、Consul/Eureka
-
数据库:MySQL/PostgreSQL
-
ORM:JPA/Hibernate 处理标准对象模型,MyBatis 处理复杂 SQL
-
缓存:Redis
-
消息队列:Kafka 或 RabbitMQ
-
部署:Docker + Kubernetes
-
监控:Micrometer + Prometheus + Grafana
-
日志:SLF4J + Logback/Log4j2
-
文档:Swagger/OpenAPI
初期为什么不建议一上来全异步?
因为大部分业务是标准事务型接口,例如注册、挂号、支付订单查询,这类场景:
-
逻辑清晰
-
阻塞式开发更直接
-
团队更容易维护
-
排错更简单
WebFlux/R2DBC 更适合:
-
流式 AI 对话
-
长连接消息推送
-
高并发 I/O 聚合场景
所以第一版系统通常是:
核心交易链路走 Spring MVC,局部高并发/流式模块再引入 WebFlux。
2. 医生号源并发抢占怎么处理?
业务场景
医生某时间段只剩 1 个号源,两个用户同时点击预约。
风险
如果处理不好,就会出现:
-
超卖
-
重复挂号
-
数据不一致
常见方案
方案一:数据库条件更新
update doctor_schedule
set remaining_count = remaining_count - 1
where schedule_id = ? and remaining_count > 0;
如果更新行数为 1,说明抢号成功;为 0,说明没抢到。
优点:简单可靠
缺点:高并发下数据库压力大
方案二:乐观锁
JPA/Hibernate 可用 @Version 字段控制版本号。
适合:
-
冲突不是特别极端
-
需要在应用层处理重试逻辑
方案三:Redis 预扣减 + 异步落库
流程:
-
Redis 先扣号源
-
扣减成功后发 MQ
-
消费者写数据库
-
失败时做补偿
适合高并发秒杀式场景。
补偿机制
如果 Redis 扣了,但数据库失败,需要:
-
本地消息表
-
死信队列
-
重试任务
-
对账任务
核心原则
强一致核心数据不能只信缓存,一定要以数据库或可靠事务机制兜底。
3. MyBatis、JPA、Hibernate、Spring Data JDBC 怎么选?
JPA/Hibernate 适合什么?
适合:
-
用户、医生、科室、权限等标准领域模型
-
对象关系清晰
-
开发效率优先
优点:
-
开发快
-
统一实体管理
-
支持懒加载、级联、乐观锁
缺点:
-
复杂 SQL 可控性不如 MyBatis
-
不熟悉容易踩 N+1 查询坑
MyBatis 适合什么?
适合:
-
复杂列表查询
-
多表 join
-
统计报表
-
动态 SQL
-
性能调优要求高的模块
优点:
-
SQL 完全可控
-
易做复杂查询优化
缺点:
-
模板代码较多
-
纯 CRUD 时开发效率不如 JPA
Spring Data JDBC 适合什么?
适合:
-
模型简单
-
不需要复杂对象关联
-
希望比 JPA 更轻量
实战建议
一个大型项目里,JPA 和 MyBatis 混用非常常见:
-
核心后台管理模型:JPA/Hibernate
-
复杂查询与报表:MyBatis
-
连接池:HikariCP
-
数据库变更:Flyway/Liquibase
4. 挂号成功后的通知链路怎么设计?
业务场景
挂号成功后,要同时触发:
-
短信通知
-
App 推送
-
医生工作台待办
-
站内信
-
后续统计埋点
为什么不用同步串行调用?
如果订单服务在一个请求里同步调完所有通知服务,会导致:
-
耦合严重
-
响应变慢
-
某个通知服务挂了影响主流程
正确做法:事件驱动
订单服务完成后发一个事件,比如:AppointmentCreatedEvent
由多个消费者分别处理:
-
短信服务
-
Push 服务
-
医生待办服务
-
BI 埋点服务
Kafka vs RabbitMQ
Kafka
适合:
-
吞吐高
-
日志型事件流
-
多消费者订阅
-
数据回放
RabbitMQ
适合:
-
路由灵活
-
延迟队列
-
业务消息编排
幂等设计
MQ 至少一次投递时,要避免重复处理:
-
消息唯一 ID
-
数据库唯一约束
-
Redis 去重键
-
消费记录表
5. Redis、Caffeine、Spring Cache 怎么组合用?
业务场景
热门医生详情页、科室列表、医院公告、药品基础信息访问量极高。
三级思路
1)Caffeine:本地缓存
适合单机热点数据:
-
科室字典
-
配置项
-
高频静态数据
优点:
-
速度极快
-
不走网络
缺点:
-
多实例之间不共享
2)Redis:分布式缓存
适合多个服务节点共享的数据:
-
医生详情
-
号源快照
-
会话信息
-
黑名单 Token
3)Spring Cache:统一抽象
通过注解:
-
@Cacheable -
@CachePut -
@CacheEvict
底层可接 Redis 或 Caffeine。
三大缓存问题
缓存穿透
查询不存在的数据,导致请求每次打数据库。
方案:
-
缓存空值
-
布隆过滤器
缓存击穿
热点 Key 过期瞬间,大量请求打数据库。
方案:
-
互斥锁
-
热点永不过期
-
后台刷新
缓存雪崩
大量 Key 同时过期。
方案:
-
过期时间加随机值
-
多级缓存
-
限流降级
6. Spring Security、JWT、OAuth2、Keycloak 怎么落地?
业务场景
平台有:
-
患者端 App
-
医生端工作台
-
运营后台
-
第三方合作机构接口
认证与鉴权分层
Spring Security
负责基础认证鉴权框架:
-
登录
-
权限拦截
-
过滤器链
-
方法级权限控制
JWT
适合无状态认证:
-
用户登录后签发 Token
-
网关或服务端校验
优点:
-
不用每次查 Session
-
适合分布式系统
缺点:
-
签发后难立刻失效
OAuth2
适合:
-
第三方授权
-
统一身份平台
-
多客户端接入
Keycloak
适合:
-
企业统一身份认证
-
单点登录
-
多租户
-
统一权限中心
安全增强
-
Access Token 短期有效
-
Refresh Token 控制续签
-
Redis 黑名单处理封禁/登出
-
敏感字段脱敏/加密
-
审计日志记录谁看了谁的病历
7. OpenFeign、Resilience4j、限流熔断怎么配合?
业务场景
订单服务要调用:
-
用户服务
-
医生服务
-
优惠券服务
-
支付服务
任何一个慢了,整条链路都可能被拖垮。
OpenFeign
用于服务间声明式调用,代码简洁。
Resilience4j 能做什么?
-
超时控制
-
重试
-
熔断
-
限流
-
舱壁隔离
典型策略
超时
给每个下游调用设最大等待时间,避免线程长时间阻塞。
熔断
如果某服务持续失败,暂时不要继续打它,先快速失败。
降级
比如推荐服务挂了,只返回基础信息,不影响挂号主链路。
限流
避免某接口被刷爆,保护系统。
舱壁隔离
不同依赖使用不同线程池/信号量,防止一个服务故障拖死全系统。
注意
重试不是越多越好。
高峰期盲目重试,只会把故障扩大。
8. 线上故障怎么排查?
三大可观测性
1)日志
-
门面:SLF4J
-
实现:Logback / Log4j2
-
关键字段:traceId、spanId、userId、orderId
为什么要 MDC?
MDC 能把同一请求的关键字段自动打到所有日志里,方便串联。
2)指标
Micrometer 暴露:
-
JVM 内存
-
GC 次数与耗时
-
线程池状态
-
HTTP RT/QPS
-
数据库连接池
-
MQ 消费积压
Prometheus 负责采集,Grafana 负责展示。
3)链路追踪
Jaeger / Zipkin 追踪一次请求流经了哪些服务。
常见排查路径
接口慢时按顺序看:
-
网关 RT 是否异常
-
某个服务 CPU 是否高
-
JVM 是否频繁 Full GC
-
数据库是否有慢 SQL
-
MQ 是否堆积
-
外部依赖是否超时
-
是否有缓存失效
9. Spring AI + RAG 怎么做企业文档问答?
业务场景
智能客服回答:
-
医保报销流程
-
住院须知
-
医院制度
-
药品说明书
-
术前术后注意事项
RAG 流程
第一步:文档加载
来源可能包括:
-
PDF
-
Word
-
Excel
-
网页
-
知识库文章
第二步:文档切片
把长文档拆成适合检索的小段。
切片原则:
-
太大:检索不准
-
太小:上下文不完整
常见方式:
-
按标题层级切
-
按自然段切
-
固定长度 + 重叠窗口
第三步:Embedding 向量化
把文本转成向量表示。
可使用:
-
OpenAI Embedding
-
Ollama 本地模型
-
其他兼容模型
第四步:写入向量数据库
常见选择:
-
Milvus
-
Chroma
-
Redis Vector
第五步:检索增强生成
用户提问后:
-
把问题向量化
-
查最相关知识片段
-
拼到 Prompt
-
再交给模型生成答案
Spring AI 的价值
Spring AI 可统一:
-
模型调用
-
Prompt 构造
-
Embedding
-
向量检索
-
工具调用接入
10. 如何避免 AI 幻觉和医疗风险?
业务场景
用户问的问题可能涉及:
-
药品服用
-
病情判断
-
治疗建议
这些属于高风险场景,不能让模型“自由发挥”。
风险控制策略
1)角色定位
AI 不是医生,而是信息辅助助手。
2)只基于知识库回答
知识库没有的信息:
-
明确说不知道
-
转人工
-
引导咨询医生
3)来源引用
回答附带:
-
文档来源
-
相关片段
-
更新时间
4)高风险问题拦截
例如:
-
剂量建议
-
处方推荐
-
诊断结论
-
生死攸关判断
这些问题必须:
-
转人工
-
转医生
-
或只返回标准免责声明
5)Prompt 约束
提示模型:
-
不允许编造
-
没依据就拒答
-
只能使用检索内容
6)审核规则
用规则引擎、关键词、分类模型做二次风控。
11. Agent、工具执行框架、MCP、Agentic RAG 怎么理解?
业务场景
用户说:“帮我查体检报告、预约下周复诊、顺便提醒我今晚吃药。”
这已经不是单一问答,而是多步骤任务执行。
工具执行框架怎么设计?
工具标准化
定义统一工具接口:
-
queryReport -
queryDoctorSchedule -
createAppointment -
sendMedicationReminder
AI 的职责
AI 负责:
-
理解用户意图
-
决定下一步调用什么工具
-
组织结果反馈
后端服务负责:
-
权限校验
-
参数校验
-
真正执行业务操作
-
审计留痕
为什么不能让模型直接连数据库?
因为风险太高:
-
权限不可控
-
参数可能错
-
难审计
-
难回滚
MCP 的意义
MCP 可以理解为模型与外部工具/上下文交互的一种标准化协议思路,让不同工具能力更容易被模型发现和调用。
Agentic RAG 和普通 RAG 区别
普通 RAG
一次检索,拿结果,生成回答。
Agentic RAG
模型会自己规划:
-
先查哪个知识库
-
不够再查哪个系统
-
是否需要多跳检索
-
是否调用额外工具
-
是否先总结再回答
它更像:
“检索 + 推理 + 工具协作”
12. 如何保证持续交付?
测试分层
单元测试
-
JUnit 5
-
Mockito
-
AssertJ
适合测试:
-
Service 逻辑
-
工具类
-
参数校验
-
规则判断
遗留代码测试
-
TestNG、PowerMock 可能在老项目里会遇到
-
新项目尽量少依赖 PowerMock
集成测试
-
Spring Boot Test
-
Testcontainers(如果项目里使用)
UI 自动化
-
Selenium
验收测试
-
Cucumber,适合业务语言描述流程
构建与发布
-
Maven / Gradle 构建
-
Jenkins / GitLab CI / GitHub Actions 执行流水线
-
Docker 打包镜像
-
Kubernetes 部署
数据库变更管理
-
Flyway
-
Liquibase
避免手工改库导致环境不一致。
发布策略
-
滚动发布
-
灰度发布
-
蓝绿发布
上线后保障
-
Prometheus 监控
-
Grafana 大盘
-
ELK 日志
-
Jaeger/Zipkin 链路追踪
发现异常立即:
-
降级
-
限流
-
回滚
这场面试真正想考什么?
表面上,面试官问的是:
-
Spring Boot
-
Redis
-
Kafka
-
Spring Security
-
Spring AI
-
Kubernetes
实际上,他在看四件事:
1. 你是否理解业务
不是会背八股,而是知道“挂号、支付、病历、客服”分别怕什么问题。
2. 你是否有系统设计能力
不是会写接口,而是能把缓存、消息、数据库、微服务、安全、监控串起来。
3. 你是否知道边界
比如 AI 不是万能的,医疗建议不能乱答,缓存不能替代数据库,重试不能无限开。
4. 你是否有工程意识
测试、发布、监控、回滚、审计、幂等、限流,这些才是大厂真正关心的稳定性能力。
结尾小结
王小二不是完全不会。
他的问题在于:简单问题答得流畅,复杂问题一深入就开始“这个要看场景”“这个一般都能做”。
而真正的大厂面试,希望听到的是:
-
为什么这样设计
-
不这样设计会出什么问题
-
高并发下怎么兜底
-
高风险场景怎么控边界
-
出故障后怎么排查
所以,小白如果想从这篇文章学东西,可以记住一条主线:
先学会把一个 Java 业务系统做出来,再学会把它做稳,最后再学会把 AI 安全地接进去。
文章标签
Java,SpringBoot,SpringCloud,Redis,Kafka,MyBatis,JPA,SpringSecurity,JWT,SpringAI,RAG,Agent,Kubernetes,Prometheus,Grafana,Micrometer,JUnit5,OpenFeign,Resilience4j,Elasticsearch
文章简述(100字)
本文以互联网医疗+AIGC平台面试为主线,通过严肃面试官与搞笑程序员王小二的三轮对话,串联 Java 17、Spring Boot、微服务、缓存、消息队列、安全、监控、Spring AI、RAG、Agent、CI/CD 等核心知识,并在文末给出详细答案解析,帮助初学者理解真实业务场景下的技术设计思路。
文章标题
《Java 17、Spring Boot、Spring Cloud、Redis、Kafka、Spring AI 与 Kubernetes:互联网医疗+AIGC平台的大厂面试实录》
文章内容
凌晨十点,某互联网大厂会议室。
玻璃门一关,气压立刻低了三度。
面试官周工,表情严肃,像是连 NullPointerException 都不敢在他面前随便抛。
求职者王小二,简历写着“精通 Java 全家桶,熟悉 AI Agent、RAG、微服务、云原生、大数据生态”。
他坐下时很自信,坐稳后又有点像刚被 GC 标记过。
这次面试的业务背景,是一套互联网医疗健康管理+AIGC智能客服平台。
平台包含在线问诊、健康档案、药品商城、医生排班、智能客服、企业知识库问答、订单支付、风控审计等模块,技术栈以 Java 为主,运行在 Kubernetes 上。
第一轮:从单体到微服务,先看你能不能把系统搭起来
问题1:
面试官:
假设我们要做一个互联网医疗平台,包含用户、医生、挂号、订单、支付、病历、智能客服几个核心模块。你会怎么用 Java 技术栈做第一版架构?选型也说一下。
王小二:
这个……我会用 Java 17,因为新一点,看起来比较高级。然后框架嘛,肯定 Spring Boot,启动快,面试也爱听。
服务拆分的话,就拆成用户服务、医生服务、订单服务、支付服务、病历服务、客服服务。
数据库用 MySQL,ORM 我一般 MyBatis 和 JPA 都能写,看团队风格。
服务之间可以用 OpenFeign 调,注册发现可以用 Eureka 或 Consul。
缓存上 Redis,消息队列上 Kafka 或 RabbitMQ。
部署的话 Docker 加 Kubernetes,监控就 Prometheus 和 Grafana。
面试官:
回答得还算完整,至少不是“一个 Controller 走天下”。
那你继续说,为什么第一版不是直接上 WebFlux 和 R2DBC 全异步?
王小二:
因为……因为先活下来比较重要。大部分医疗后台还是 CRUD 比较多,Spring MVC 配合 JPA、MyBatis 更稳。WebFlux 更适合高并发 I/O 场景,比如流式推送、AI 对话。
面试官:
不错,这句说到点子上了。
问题2:
面试官:
挂号服务里,医生排班和患者预约很容易出现并发冲突。比如同一个号源最后一个名额,被两个人同时抢到。你怎么处理?
王小二:
这个我会先想到数据库层。
比如库存字段 remaining_count,更新时带条件:where remaining_count > 0,更新成功才算抢到。
也可以用乐观锁版本号,比如 JPA 的 @Version。
如果并发更大,就加 Redis 做预扣减,再异步落库。
实在不放心,还可以把预约请求丢 Kafka,排队串行消费。
面试官:
行,知道“别让两个病人拿同一个号”这件事要靠数据一致性,不靠祈祷。
那 Redis 预扣减失败和数据库写入失败的补偿,你考虑了吗?
王小二:
这个……一般会有补偿任务。
或者用消息事务……或者本地消息表……
大概就是,不能让 Redis 和数据库各过各的。
面试官:
嗯,后半句开始有点飘了,不过方向没错。
问题3:
面试官:
你说说 MyBatis、JPA、Hibernate 在这个场景里怎么选。别背定义,说实际业务。
王小二:
如果是用户、医生、病历这种对象关系比较明确、关联也比较多的模块,我会偏 JPA/Hibernate,开发快,适合后台管理系统。
如果是订单、报表、复杂查询、分页筛选、多表统计,我更倾向 MyBatis,SQL 可控。
有些简单服务也可以用 Spring Data JDBC,模型更轻。
连接池用 HikariCP,性能和稳定性都更主流。
数据库版本管理可以上 Flyway 或 Liquibase。
面试官:
不错,这个回答挺像干过活。
那病历查询为什么不全上 Elasticsearch?
王小二:
因为 Elasticsearch 适合检索,不适合做强事务主存储。
病历原始数据还是落 MySQL,检索索引异步同步到 Elasticsearch 比较稳。
面试官:
很好。
问题4:
面试官:
如果挂号成功后,需要发送短信、站内信、医生工作台提醒、患者 App 消息,你会怎么设计消息链路?
王小二:
我会把“挂号成功”作为领域事件发出去。
订单服务提交成功后,发 Kafka 消息,多个消费者分别处理短信、App Push、医生提醒。
如果业务需要更强路由能力,也可以用 RabbitMQ。
消息体可以用 Jackson 序列化 JSON;如果追求高性能和跨语言,可以用 Protobuf 或 Avro。
为了避免重复消费,要做幂等,比如消息表、业务唯一键、去重 Redis Key。
面试官:
可以,至少你知道 MQ 不是“发了就一定成”。
第一轮到这里。
第二轮:系统能跑起来还不够,你得让它撑住、守住、看得见
问题5:
面试官:
现在平台用户量起来了,问诊高峰期每秒几千请求。你怎么做缓存设计?说说 Redis、Caffeine、Spring Cache 分别怎么用。
王小二:
Redis 适合分布式缓存,比如医生详情、科室列表、号源快照。
Caffeine 适合单机热点缓存,比如本机短期高频字典数据。
Spring Cache 可以统一缓存注解,底层接 Redis 或 Caffeine。
缓存要注意穿透、击穿、雪崩。
穿透可以布隆过滤器或缓存空值;击穿可以互斥锁或热点永不过期加异步刷新;雪崩要加过期时间随机化和多级缓存。
面试官:
不错,这段答得挺顺。
那患者健康档案能不能直接全部丢 Redis?
王小二:
不能。这个数据敏感、体量大、更新也复杂。Redis 更适合热点读,不适合作为长期主存。
核心还是数据库,缓存只是加速层。
面试官:
嗯,没把 Redis 当万能冰箱,这点很好。
问题6:
面试官:
支付和医疗数据都很敏感。你说说 Spring Security、JWT、OAuth2、Keycloak 在这个系统里怎么落地。
王小二:
用户登录可以用 Spring Security 做认证鉴权。
移动端和小程序登录后签发 JWT,网关校验令牌。
如果平台有医生端、患者端、运营后台、第三方药企后台,多租户和统一身份管理可以引入 OAuth2 或 Keycloak。
权限模型上可以做 RBAC,接口按角色、资源、数据范围控制。
敏感字段比如身份证号、手机号可以加密存储,必要时用 Bouncy Castle 做加解密能力支持。
此外,操作病历、处方这些高风险接口,要做审计日志。
面试官:
回答合格。
那 JWT 一旦签发,用户被封禁了怎么办?
王小二:
这个……可以缩短 JWT 有效期,再配合 Redis 黑名单。
或者做双 Token 机制,Access Token 短效,Refresh Token 控制续签。
面试官:
行,比“让用户重新登录试试”强。
问题7:
面试官:
微服务之间经常有超时、雪崩。你说说 OpenFeign、Resilience4j、网关限流、熔断降级怎么配合。
王小二:
服务调用可以用 OpenFeign。
如果医生服务慢了,订单服务直接同步等,就容易把线程池拖死。
所以要做超时控制、重试、舱壁隔离、熔断和限流,Resilience4j 很适合。
比如查询医生画像失败,就降级返回基础信息;推荐标签失败,不影响挂号主链路。
API 网关层可以做统一限流和鉴权,防止恶意刷接口。
下游不可用时,可以快速失败,不要层层等待。
面试官:
不错。
那重试是不是越多越好?
王小二:
不是。重试太多可能把本来就快挂的服务彻底按死。
重试只适合幂等读操作或少量可控场景,支付扣款这类要非常谨慎。
面试官:
很好,这句靠谱。
问题8:
面试官:
线上出了问题,你怎么排查?把日志、指标、链路追踪说完整。
王小二:
日志方面我会统一 SLF4J 门面,底层用 Logback 或 Log4j2。
把 traceId、userId、orderId 放到 MDC 里,便于串联日志。
指标方面用 Micrometer 暴露 JVM、线程池、HTTP、数据库连接池指标给 Prometheus,再用 Grafana 做看板。
链路追踪可以接 Jaeger 或 Zipkin,看一次请求经过了哪些服务。
日志聚合可以上 ELK Stack。
如果发现接口 RT 飙升,要看是 CPU 高、GC 频繁、数据库慢查询、MQ 堆积还是外部依赖超时。
面试官:
不错,排障思路比很多只会说“重启试试”的强。
第二轮结束。
第三轮:现在加 AI,别把系统做成“智能胡说平台”
问题9:
面试官:
公司现在要做 AI 智能客服,支持医保政策问答、医院流程问答、药品说明检索。你会怎么用 Spring AI 和 RAG 落地?
王小二:
这个我熟,我简历上写了三遍。
大概流程是:先把医院制度、药品说明书、医保文档、常见问答导入知识库;然后切片;然后向量化;再存到向量数据库,比如 Milvus、Chroma 或 Redis Vector。
用户提问后,先做语义检索,拿到相关片段,再拼进 Prompt,最后交给大模型回答。
Spring AI 可以帮我们统一模型调用、Embedding、向量检索这些流程。
这样比模型“裸答”更靠谱,能减少幻觉。
面试官:
嗯,这个回答不错。
那你继续说,文档切片怎么做?是按 1000 字一刀切?
王小二:
这个……也不一定。
有时候按标题层级切,有时候按段落切。
反正就是,切得太大检索不准,切得太小上下文不够。
要根据业务调。
面试官:
你这句虽然有点像废话,但确实是对的。
问题10:
面试官:
如果用户问:“我高血压还能不能吃这个药?”你觉得企业文档问答和医疗建议之间的边界怎么控制?怎么避免 AI 幻觉带来风险?
王小二:
这个不能让 AI 直接当医生。
可以把它定位成“信息辅助”,比如引用药品说明书、医院规范、挂号流程,而不是直接给诊断结论。
回答里要带来源片段、免责声明。
高风险问题可以触发转人工或转医生。
还可以做提示词约束,不在知识库里的问题不要乱答。
另外把审核规则加上,比如命中禁答词、处方建议、高风险病症,就不让模型自由发挥。
面试官:
可以,风险意识合格。
那如果用户追问十轮,系统怎么保留会话上下文?
王小二:
可以做聊天会话内存。
短期上下文存在 Redis,长期摘要落库。
也可以把历史对话摘要后再拼接到 Prompt 里,避免 Token 爆炸。
面试官:
嗯,还行。
问题11:
面试官:
如果我们要做 Agent,让 AI 帮用户完成“查报告、预约复诊、推送用药提醒”这种复杂工作流,你怎么设计工具执行框架?
王小二:
我会把 AI 当成决策层,不让它直接乱调内部系统。
先定义标准化工具接口,比如查询报告、查询排班、创建预约、发送提醒。
工具调用要有权限校验、参数校验、审计日志。
模型只负责决定“该调哪个工具”,真正执行还是后端服务做。
如果是多步骤流程,可以做状态机或者编排流。
如果再高级一点,还可以做 MCP 或类似协议,把工具能力标准化接入。
面试官:
前面说得不错。
那 Agentic RAG 和普通 RAG 的区别呢?
王小二:
这个……普通 RAG 就是检索再回答。
Agentic RAG 可能就是……更聪明一点?
会自己规划、多跳检索、可能还会调用工具。
大概是从“查一遍”升级成“边查边想边干”。
面试官:
你最后这句,土是土了点,但意思差不多。
问题12:
面试官:
最后一个问题。你怎么保证这套系统能持续交付?从测试、CI/CD 到上线发布说一下。
王小二:
单元测试用 JUnit 5、Mockito、AssertJ。
历史遗留不好 mock 的代码,可能会碰到 PowerMock,但新项目尽量少用。
接口测试可以用 Spring Boot Test,端到端页面流程可以用 Selenium,业务验收可以用 Cucumber。
构建用 Maven 或 Gradle。
CI/CD 用 Jenkins、GitLab CI 或 GitHub Actions。
打包 Docker 镜像,发到 Kubernetes。
数据库变更用 Flyway 或 Liquibase 管理。
发布可以做灰度、蓝绿或滚动更新。
上线后通过 Prometheus、Grafana、ELK 看指标和日志,不行就回滚。
面试官:
整体还行。
你会的东西不少,懂的深浅嘛……有些地方像温水泡枸杞,颜色有了,药劲差点。
今天先到这里,回去等通知吧。
王小二:
好的老师。我这边如果有结果,是您通知我,还是 Kafka 异步通知我?
面试官:
……门在你右手边。
面试题答案精讲
下面把上面 12 个问题的标准答案,用小白也能看懂的方式详细展开。
1. 互联网医疗平台第一版架构怎么设计?
业务场景
一个互联网医疗平台,至少会有这些核心能力:
用户注册登录、医生信息展示、排班挂号、订单支付、病历查看、消息通知、智能客服。
推荐技术方案
-
Java 版本:优先 Java 17,兼顾性能、语法增强、LTS 支持
-
基础框架:Spring Boot
-
Web 层:大多数后台接口用 Spring MVC
-
AI 对话或流式返回:可局部使用 Spring WebFlux
-
服务治理:Spring Cloud、OpenFeign、Consul/Eureka
-
数据库:MySQL/PostgreSQL
-
ORM:JPA/Hibernate 处理标准对象模型,MyBatis 处理复杂 SQL
-
缓存:Redis
-
消息队列:Kafka 或 RabbitMQ
-
部署:Docker + Kubernetes
-
监控:Micrometer + Prometheus + Grafana
-
日志:SLF4J + Logback/Log4j2
-
文档:Swagger/OpenAPI
初期为什么不建议一上来全异步?
因为大部分业务是标准事务型接口,例如注册、挂号、支付订单查询,这类场景:
-
逻辑清晰
-
阻塞式开发更直接
-
团队更容易维护
-
排错更简单
WebFlux/R2DBC 更适合:
-
流式 AI 对话
-
长连接消息推送
-
高并发 I/O 聚合场景
所以第一版系统通常是:
核心交易链路走 Spring MVC,局部高并发/流式模块再引入 WebFlux。
2. 医生号源并发抢占怎么处理?
业务场景
医生某时间段只剩 1 个号源,两个用户同时点击预约。
风险
如果处理不好,就会出现:
-
超卖
-
重复挂号
-
数据不一致
常见方案
方案一:数据库条件更新
update doctor_schedule
set remaining_count = remaining_count - 1
where schedule_id = ? and remaining_count > 0;
如果更新行数为 1,说明抢号成功;为 0,说明没抢到。
优点:简单可靠
缺点:高并发下数据库压力大
方案二:乐观锁
JPA/Hibernate 可用 @Version 字段控制版本号。
适合:
-
冲突不是特别极端
-
需要在应用层处理重试逻辑
方案三:Redis 预扣减 + 异步落库
流程:
-
Redis 先扣号源
-
扣减成功后发 MQ
-
消费者写数据库
-
失败时做补偿
适合高并发秒杀式场景。
补偿机制
如果 Redis 扣了,但数据库失败,需要:
-
本地消息表
-
死信队列
-
重试任务
-
对账任务
核心原则
强一致核心数据不能只信缓存,一定要以数据库或可靠事务机制兜底。
3. MyBatis、JPA、Hibernate、Spring Data JDBC 怎么选?
JPA/Hibernate 适合什么?
适合:
-
用户、医生、科室、权限等标准领域模型
-
对象关系清晰
-
开发效率优先
优点:
-
开发快
-
统一实体管理
-
支持懒加载、级联、乐观锁
缺点:
-
复杂 SQL 可控性不如 MyBatis
-
不熟悉容易踩 N+1 查询坑
MyBatis 适合什么?
适合:
-
复杂列表查询
-
多表 join
-
统计报表
-
动态 SQL
-
性能调优要求高的模块
优点:
-
SQL 完全可控
-
易做复杂查询优化
缺点:
-
模板代码较多
-
纯 CRUD 时开发效率不如 JPA
Spring Data JDBC 适合什么?
适合:
-
模型简单
-
不需要复杂对象关联
-
希望比 JPA 更轻量
实战建议
一个大型项目里,JPA 和 MyBatis 混用非常常见:
-
核心后台管理模型:JPA/Hibernate
-
复杂查询与报表:MyBatis
-
连接池:HikariCP
-
数据库变更:Flyway/Liquibase
4. 挂号成功后的通知链路怎么设计?
业务场景
挂号成功后,要同时触发:
-
短信通知
-
App 推送
-
医生工作台待办
-
站内信
-
后续统计埋点
为什么不用同步串行调用?
如果订单服务在一个请求里同步调完所有通知服务,会导致:
-
耦合严重
-
响应变慢
-
某个通知服务挂了影响主流程
正确做法:事件驱动
订单服务完成后发一个事件,比如:AppointmentCreatedEvent
由多个消费者分别处理:
-
短信服务
-
Push 服务
-
医生待办服务
-
BI 埋点服务
Kafka vs RabbitMQ
Kafka
适合:
-
吞吐高
-
日志型事件流
-
多消费者订阅
-
数据回放
RabbitMQ
适合:
-
路由灵活
-
延迟队列
-
业务消息编排
幂等设计
MQ 至少一次投递时,要避免重复处理:
-
消息唯一 ID
-
数据库唯一约束
-
Redis 去重键
-
消费记录表
5. Redis、Caffeine、Spring Cache 怎么组合用?
业务场景
热门医生详情页、科室列表、医院公告、药品基础信息访问量极高。
三级思路
1)Caffeine:本地缓存
适合单机热点数据:
-
科室字典
-
配置项
-
高频静态数据
优点:
-
速度极快
-
不走网络
缺点:
-
多实例之间不共享
2)Redis:分布式缓存
适合多个服务节点共享的数据:
-
医生详情
-
号源快照
-
会话信息
-
黑名单 Token
3)Spring Cache:统一抽象
通过注解:
-
@Cacheable -
@CachePut -
@CacheEvict
底层可接 Redis 或 Caffeine。
三大缓存问题
缓存穿透
查询不存在的数据,导致请求每次打数据库。
方案:
-
缓存空值
-
布隆过滤器
缓存击穿
热点 Key 过期瞬间,大量请求打数据库。
方案:
-
互斥锁
-
热点永不过期
-
后台刷新
缓存雪崩
大量 Key 同时过期。
方案:
-
过期时间加随机值
-
多级缓存
-
限流降级
6. Spring Security、JWT、OAuth2、Keycloak 怎么落地?
业务场景
平台有:
-
患者端 App
-
医生端工作台
-
运营后台
-
第三方合作机构接口
认证与鉴权分层
Spring Security
负责基础认证鉴权框架:
-
登录
-
权限拦截
-
过滤器链
-
方法级权限控制
JWT
适合无状态认证:
-
用户登录后签发 Token
-
网关或服务端校验
优点:
-
不用每次查 Session
-
适合分布式系统
缺点:
-
签发后难立刻失效
OAuth2
适合:
-
第三方授权
-
统一身份平台
-
多客户端接入
Keycloak
适合:
-
企业统一身份认证
-
单点登录
-
多租户
-
统一权限中心
安全增强
-
Access Token 短期有效
-
Refresh Token 控制续签
-
Redis 黑名单处理封禁/登出
-
敏感字段脱敏/加密
-
审计日志记录谁看了谁的病历
7. OpenFeign、Resilience4j、限流熔断怎么配合?
业务场景
订单服务要调用:
-
用户服务
-
医生服务
-
优惠券服务
-
支付服务
任何一个慢了,整条链路都可能被拖垮。
OpenFeign
用于服务间声明式调用,代码简洁。
Resilience4j 能做什么?
-
超时控制
-
重试
-
熔断
-
限流
-
舱壁隔离
典型策略
超时
给每个下游调用设最大等待时间,避免线程长时间阻塞。
熔断
如果某服务持续失败,暂时不要继续打它,先快速失败。
降级
比如推荐服务挂了,只返回基础信息,不影响挂号主链路。
限流
避免某接口被刷爆,保护系统。
舱壁隔离
不同依赖使用不同线程池/信号量,防止一个服务故障拖死全系统。
注意
重试不是越多越好。
高峰期盲目重试,只会把故障扩大。
8. 线上故障怎么排查?
三大可观测性
1)日志
-
门面:SLF4J
-
实现:Logback / Log4j2
-
关键字段:traceId、spanId、userId、orderId
为什么要 MDC?
MDC 能把同一请求的关键字段自动打到所有日志里,方便串联。
2)指标
Micrometer 暴露:
-
JVM 内存
-
GC 次数与耗时
-
线程池状态
-
HTTP RT/QPS
-
数据库连接池
-
MQ 消费积压
Prometheus 负责采集,Grafana 负责展示。
3)链路追踪
Jaeger / Zipkin 追踪一次请求流经了哪些服务。
常见排查路径
接口慢时按顺序看:
-
网关 RT 是否异常
-
某个服务 CPU 是否高
-
JVM 是否频繁 Full GC
-
数据库是否有慢 SQL
-
MQ 是否堆积
-
外部依赖是否超时
-
是否有缓存失效
9. Spring AI + RAG 怎么做企业文档问答?
业务场景
智能客服回答:
-
医保报销流程
-
住院须知
-
医院制度
-
药品说明书
-
术前术后注意事项
RAG 流程
第一步:文档加载
来源可能包括:
-
PDF
-
Word
-
Excel
-
网页
-
知识库文章
第二步:文档切片
把长文档拆成适合检索的小段。
切片原则:
-
太大:检索不准
-
太小:上下文不完整
常见方式:
-
按标题层级切
-
按自然段切
-
固定长度 + 重叠窗口
第三步:Embedding 向量化
把文本转成向量表示。
可使用:
-
OpenAI Embedding
-
Ollama 本地模型
-
其他兼容模型
第四步:写入向量数据库
常见选择:
-
Milvus
-
Chroma
-
Redis Vector
第五步:检索增强生成
用户提问后:
-
把问题向量化
-
查最相关知识片段
-
拼到 Prompt
-
再交给模型生成答案
Spring AI 的价值
Spring AI 可统一:
-
模型调用
-
Prompt 构造
-
Embedding
-
向量检索
-
工具调用接入
10. 如何避免 AI 幻觉和医疗风险?
业务场景
用户问的问题可能涉及:
-
药品服用
-
病情判断
-
治疗建议
这些属于高风险场景,不能让模型“自由发挥”。
风险控制策略
1)角色定位
AI 不是医生,而是信息辅助助手。
2)只基于知识库回答
知识库没有的信息:
-
明确说不知道
-
转人工
-
引导咨询医生
3)来源引用
回答附带:
-
文档来源
-
相关片段
-
更新时间
4)高风险问题拦截
例如:
-
剂量建议
-
处方推荐
-
诊断结论
-
生死攸关判断
这些问题必须:
-
转人工
-
转医生
-
或只返回标准免责声明
5)Prompt 约束
提示模型:
-
不允许编造
-
没依据就拒答
-
只能使用检索内容
6)审核规则
用规则引擎、关键词、分类模型做二次风控。
11. Agent、工具执行框架、MCP、Agentic RAG 怎么理解?
业务场景
用户说:“帮我查体检报告、预约下周复诊、顺便提醒我今晚吃药。”
这已经不是单一问答,而是多步骤任务执行。
工具执行框架怎么设计?
工具标准化
定义统一工具接口:
-
queryReport -
queryDoctorSchedule -
createAppointment -
sendMedicationReminder
AI 的职责
AI 负责:
-
理解用户意图
-
决定下一步调用什么工具
-
组织结果反馈
后端服务负责:
-
权限校验
-
参数校验
-
真正执行业务操作
-
审计留痕
为什么不能让模型直接连数据库?
因为风险太高:
-
权限不可控
-
参数可能错
-
难审计
-
难回滚
MCP 的意义
MCP 可以理解为模型与外部工具/上下文交互的一种标准化协议思路,让不同工具能力更容易被模型发现和调用。
Agentic RAG 和普通 RAG 区别
普通 RAG
一次检索,拿结果,生成回答。
Agentic RAG
模型会自己规划:
-
先查哪个知识库
-
不够再查哪个系统
-
是否需要多跳检索
-
是否调用额外工具
-
是否先总结再回答
它更像:
“检索 + 推理 + 工具协作”
12. 如何保证持续交付?
测试分层
单元测试
-
JUnit 5
-
Mockito
-
AssertJ
适合测试:
-
Service 逻辑
-
工具类
-
参数校验
-
规则判断
遗留代码测试
-
TestNG、PowerMock 可能在老项目里会遇到
-
新项目尽量少依赖 PowerMock
集成测试
-
Spring Boot Test
-
Testcontainers(如果项目里使用)
UI 自动化
-
Selenium
验收测试
-
Cucumber,适合业务语言描述流程
构建与发布
-
Maven / Gradle 构建
-
Jenkins / GitLab CI / GitHub Actions 执行流水线
-
Docker 打包镜像
-
Kubernetes 部署
数据库变更管理
-
Flyway
-
Liquibase
避免手工改库导致环境不一致。
发布策略
-
滚动发布
-
灰度发布
-
蓝绿发布
上线后保障
-
Prometheus 监控
-
Grafana 大盘
-
ELK 日志
-
Jaeger/Zipkin 链路追踪
发现异常立即:
-
降级
-
限流
-
回滚
这场面试真正想考什么?
表面上,面试官问的是:
-
Spring Boot
-
Redis
-
Kafka
-
Spring Security
-
Spring AI
-
Kubernetes
实际上,他在看四件事:
1. 你是否理解业务
不是会背八股,而是知道“挂号、支付、病历、客服”分别怕什么问题。
2. 你是否有系统设计能力
不是会写接口,而是能把缓存、消息、数据库、微服务、安全、监控串起来。
3. 你是否知道边界
比如 AI 不是万能的,医疗建议不能乱答,缓存不能替代数据库,重试不能无限开。
4. 你是否有工程意识
测试、发布、监控、回滚、审计、幂等、限流,这些才是大厂真正关心的稳定性能力。
结尾小结
王小二不是完全不会。
他的问题在于:简单问题答得流畅,复杂问题一深入就开始“这个要看场景”“这个一般都能做”。
而真正的大厂面试,希望听到的是:
-
为什么这样设计
-
不这样设计会出什么问题
-
高并发下怎么兜底
-
高风险场景怎么控边界
-
出故障后怎么排查
所以,小白如果想从这篇文章学东西,可以记住一条主线:
先学会把一个 Java 业务系统做出来,再学会把它做稳,最后再学会把 AI 安全地接进去。
文章标签
Java,SpringBoot,SpringCloud,Redis,Kafka,MyBatis,JPA,SpringSecurity,JWT,SpringAI,RAG,Agent,Kubernetes,Prometheus,Grafana,Micrometer,JUnit5,OpenFeign,Resilience4j,Elasticsearch
文章简述(100字)
本文以互联网医疗+AIGC平台面试为主线,通过严肃面试官与搞笑程序员王小二的三轮对话,串联 Java 17、Spring Boot、微服务、缓存、消息队列、安全、监控、Spring AI、RAG、Agent、CI/CD 等核心知识,并在文末给出详细答案解析,帮助初学者理解真实业务场景下的技术设计思路。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐
所有评论(0)