三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

Java 17 + Spring Boot + Spring Security:企业协同 SaaS 场景大厂面试实战

Java 17 + Spring Boot + Spring Security:企业协同 SaaS 场景大厂面试实战

面试官:燕双非,聊聊企业协同 SaaS 场景下的 Java 技术栈

场景设定:某互联网大厂在招聘企业协同与 SaaS 方向的 Java 后端工程师,候选人燕双非自称“会一点点”,实际是个很会讲故事的水货程序员。面试官风格严肃,问题从基础到深入逐步递进,围绕Java 17、Spring Boot、MyBatis、Redis、Kafka、Spring Security、JWT、Kubernetes、Micrometer、OpenAPI、R2DBC、WebSocket、Spring AI等技术展开。


第一轮:基础架构与业务建模

面试官:企业协同 SaaS 通常会做多租户隔离,你先说说 Java 17 相比 Java 8,在这个场景里你会重点关注哪些特性?

燕双非:嗯……Java 17 我知道比 Java 8 新很多,语法更简洁,像recordsealed这些我听过。做 SaaS 的话,我会优先考虑代码可读性和对象建模效率,record适合做 DTO,少写很多样板代码。然后 JVM 层面也会关注垃圾回收和启动性能,毕竟多租户服务实例通常比较多。

面试官:这个方向对了。那如果是一个文档协作平台,Spring Boot 和 Spring MVC 你会怎么拆分接口层、服务层和权限层?

燕双非:接口层交给 Spring MVC 做 REST API,服务层负责业务编排,权限层我一般会配合 Spring Security。比如文档列表、成员管理、权限设置这些接口,Controller 只做参数校验和返回值包装,核心逻辑放 Service 里,这样方便后续扩展。

面试官:可以,思路比较标准。那多租户数据隔离你一般怎么设计?

燕双非:我会先看业务强度。如果是中小型 SaaS,通常可以通过租户 ID 作为全链路上下文,数据库层加 tenant_id 过滤;如果是强隔离客户,可能会按租户独立库或者独立 schema。配合 MyBatis 或 JPA 时,需要保证拦截器或数据源路由不会漏掉租户条件。

面试官:还行,至少知道关键点是租户上下文和数据隔离。那如果文档上传之后要做异步 OCR 和全文索引,你会怎么接?

燕双非:可以通过 Kafka 把“文件已上传”事件发出去,下游消费者做 OCR、抽取文本、再写入 Elasticsearch 或搜索服务。这样上传链路就不会被慢任务拖住,用户体验也更好。


第二轮:中间件、缓存与安全

面试官:好,进入第二轮。你刚才提到 Kafka。那在协同编辑场景里,WebSocket 和 Kafka 分别承担什么角色?

燕双非:WebSocket 更适合前端和后端的实时双向通信,比如光标位置、在线成员、即时评论。Kafka 更适合后台事件流转,比如编辑动作审计、异步落库、通知分发。两者不是替代关系,而是一个负责“实时交互”,一个负责“可靠事件”。

面试官:说得不错。那 Redis 在这里你会怎么用?只说缓存,不够。

燕双非:嗯……Redis 除了缓存热点文档元数据,还可以做在线状态、分布式锁、会话存储、消息去重。比如协作编辑里可以用 Redis 做用户是否在线的快速判断,还可以用 Spring Cache 包一层常见查询结果,减少数据库压力。

面试官:那权限体系呢?企业协同一定有组织、部门、角色、文档级权限,Spring Security 和 JWT 怎么配合?

燕双非:登录后签发 JWT,里面放用户 ID、租户 ID、角色信息和过期时间。Spring Security 负责拦截请求、解析 token、构建认证对象,再结合方法级权限注解控制接口访问。文档级权限的话,通常还要在业务层做一次资源校验,不能只依赖 token 里的角色。

面试官:嗯,这个回答比刚才更接近实际。那如果 token 过期、刷新、踢下线,你会怎么做?

燕双非:可以做短期 access token + 长期 refresh token 机制,refresh token 存数据库或 Redis。用户退出登录时把 refresh token 作废;如果需要踢下线,可以把 token 黑名单放 Redis 里。这样既能保证安全,又不会每次都查数据库。

面试官:最后一个问题,指标监控你会怎么做?

燕双非:我会用 Micrometer 统一埋点,把接口耗时、错误率、Kafka 消费延迟、Redis 命中率等指标暴露给 Prometheus,再用 Grafana 做看板。对于文档协作这种系统,重点盯住编辑请求延迟、在线连接数和索引积压量。


第三轮:高并发、云原生与 AI 能力

面试官:假设你们要上线一个“智能文档助手”,支持企业知识库问答。你会如何结合 Spring AI、RAG 和向量数据库设计?

燕双非:先把企业文档做文档加载和切分,再通过 Embedding 模型生成向量,存到 Milvus 或 Redis 向量能力里。用户提问时先做语义检索,召回相关片段,再拼接到提示词中交给大模型生成答案。Spring AI 可以把这些调用封装起来,统一管理客户端、提示填充和工具调用。

面试官:那你怎么避免 AI 幻觉?企业场景里这是个很现实的问题。

燕双非:嗯……我会尽量让模型“少自由发挥”。比如限制答案只能基于检索到的知识片段,给出引用来源;如果命中率低,就直接返回“未找到相关内容”。另外可以做 prompt 约束和结果后校验,避免瞎编。

面试官:说到这里,微服务部署你会怎么考虑?如果文档服务、搜索服务、通知服务拆开了,Kubernetes 里怎么做弹性?

燕双非:可以把各个服务容器化后部署到 Kubernetes,配合 HPA 根据 CPU、内存或自定义指标扩缩容。比如搜索服务在白天请求高峰时自动扩容,Kafka 消费者根据积压量做水平扩展。服务之间可以通过 OpenFeign 调用,必要时加 Resilience4j 做熔断和限流。

面试官:最后一个追问,如果文档实时协作要支持跨端同步,你会选什么通信方式?

燕双非:我会优先考虑 WebSocket 做实时同步,复杂结构可以用 Protobuf 提升传输效率。如果是跨服务内部通信,也可以用 gRPC,把编辑操作、游标状态、心跳消息统一定义成强类型接口。

面试官:整体听下来,你对业务链路有一些概念,但复杂问题还不够深入。今天先到这里,你回家等通知吧。


问题详解与知识点梳理

1. Java 17 在 SaaS 场景的价值
Java 17 带来了更现代的语法和更好的长期支持,适合企业协同系统这类生命周期较长的项目。record可用于 DTO、事件对象,减少样板代码;sealed class可用于限制权限模型、消息类型等领域建模。JVM 层面要关注 GC、启动时间、内存占用,尤其是微服务拆分后实例数量更多。

2. Spring Boot + Spring MVC 的职责划分
Spring Boot 负责快速装配、自动配置和工程化落地,Spring MVC 负责传统 REST 接口的请求映射、参数绑定和返回值处理。Controller 应尽量保持薄,业务逻辑放在 Service 中,便于测试和扩展。

3. 多租户隔离设计
常见方案有共享库共享表、共享库分表、独立库独立表。企业协同平台通常会结合租户 ID 做逻辑隔离,并在 MyBatis 拦截器或 JPA 查询层自动注入 tenant_id。对于高价值客户,可采用独立库模式增强隔离性。

4. Kafka + WebSocket 的组合
WebSocket 用于前台实时协作,Kafka 用于后台异步解耦。比如用户编辑文档时,前端通过 WebSocket 与服务端维持长连接,服务端把编辑事件写入 Kafka,后续由消费者完成审计、索引、通知等任务。

5. Redis 的多种用途
除了缓存,Redis 还可用于在线状态、分布式锁、消息去重、限流、会话存储和短期黑名单。协同系统中,Redis 很适合维护“谁在线、谁正在编辑、文档热点数据”等高频访问数据。

6. Spring Security + JWT 的实践
JWT 适合无状态认证,服务端解析 token 后构建认证上下文,Spring Security 负责拦截和权限判断。企业系统通常还需要文档级、组织级权限,这部分不能只依赖 JWT,需要在业务层进行资源校验。

7. Micrometer + Prometheus + Grafana
Micrometer 提供统一指标埋点,Prometheus 负责采集与存储,Grafana 负责可视化。协同平台应重点监控接口响应时间、错误率、WebSocket 在线连接数、Kafka 积压、搜索延迟和缓存命中率。

8. Spring AI + RAG + 向量数据库
RAG 的核心是“先检索,再生成”。企业知识库问答时,先把文档切块并向量化,召回最相关的片段,再把上下文喂给大模型生成答案。Spring AI 可以降低模型接入门槛,统一提示词、工具调用和客户端管理。

9. 如何降低 AI 幻觉
通过限定回答范围、要求引用来源、提高检索精度、增加结果校验和人工兜底机制,可以有效降低幻觉风险。企业场景尤其要避免模型“编造制度、流程和审批结果”。

10. Kubernetes 下的弹性伸缩
协同系统的不同服务压力分布不均,搜索、通知、文档协作常常在高峰期波动明显。Kubernetes 配合 HPA 可根据 CPU、内存、自定义指标进行自动扩缩容,提升资源利用率和可用性。

11. WebSocket、gRPC 与 Protobuf 的适用边界
WebSocket 更适合浏览器与服务端的双向实时互动;gRPC 更适合内部服务间高性能调用;Protobuf 则适合高效二进制传输。根据链路类型选择合适协议,才能兼顾性能和开发效率。


感谢阅读,希望这篇围绕企业协同 SaaS 场景的 Java 面试文章,能帮助你更好地理解大厂面试中的技术追问方式,也希望能对你的学习和求职有所帮助。

← 返回列表