项目整合提问
🔹一、围绕“智慧社区综合服务平台”项目的面试问题
🧩 多数据源配置
你是如何实现 MySQL、Redis 和 HDFS 的多数据源配置的?它们是动态切换的吗?
不是动态切换的,因为MySQL只有一个
- MySQL:作为关系型数据的主存储;
- Redis:用于缓存加速和临时数据管理,比如用户登录态、AI计算中间结果等;
- HDFS:用于社区信息的分布式文件存储,比如大文件、视频图像、数据快照等。
在项目中 Redis 主要用作缓存,如何保证缓存一致性?你是否考虑了缓存穿透/击穿问题?
在整合 HDFS 时,你是如何设计文件上传、下载或读取逻辑的?是否有封装统一的工具类?
HDFS 文件存储整合: 在智慧社区综合服务平台中,负责将 HDFS 集成到 Spring Boot 后端,设计并封装了 HDFSUtil
工具类,实现了文件的上传、下载和读取功能。通过统一接口简化了业务模块调用,提升了系统可扩展性。
- 使用 Hadoop 的
FileSystem
类进行 HDFS 连接管理,配置NameNode
地址和认证方式,通过 Spring@Bean
管理连接。 - 封装了多种文件操作接口,包括上传(
uploadFile
)、下载(downloadFile
)、删除(deleteFile
)和读取(readTextFile
)。 - 提供 RESTful API 支持前后端文件上传、下载,确保文件流的高效处理和异常管理。
🧩 权限系统与安全设计
-
你提到 JWT 双签发机制,能具体讲讲你是如何实现 RefreshToken 与 AccessToken 的分离逻辑的?如何防止 Token 被盗用?
见外卖JWT
-
SpringSecurity 和 RBAC 权限控制是如何整合的?你是如何进行 URL 级别的权限校验的?有没有用到注解方式?
- RBAC:我们通过角色(如管理员、普通用户)来控制不同的权限。
- URL 级别权限:用 Spring Security 配置哪些角色可以访问哪些页面,确保不同角色的用户只能访问自己有权限的资源。
- 注解权限控制:通过
@PreAuthorize
注解,我们可以在方法级别控制权限,甚至使用复杂的表达式来进行更细粒度的控制。
🧩 并发与 AI 模块调度
-
你在 AI 模块里用了线程池进行任务调度,能详细讲讲你的线程池参数是怎么设置的吗?有没有使用过自定义 ThreadFactory?
corePoolSize = 4
:线程池启动时会保持 4 个线程。核心线程数通常根据系统的 CPU 核数 来进行设置。maximumPoolSize = 8
:最多允许 8 个线程同时运行。核心数*2keepAliveTime = 60L
:空闲线程如果超过 60 秒没有执行任务,则会被销毁。workQueue = new LinkedBlockingQueue<>(100)
:任务队列的容量为 100。设置为 100 是基于对系统任务负载的估算:如果任务的处理速度较快且不会长时间阻塞,那么 100 个任务容量可以容忍一定的突发请求量,避免任务被丢弃或者过早拒绝。如果处理非常快速的任务,可以适当增加队列容量。ThreadFactory
:自定义线程工厂,指定线程名称格式为ai-task-pool-%d
,有助于调试和日志管理。
-
多线程异步执行 AI 任务时如何进行统一推送?你用的是什么方式来控制线程之间的通信与同步?
使用 Future
和 ExecutorService
进行同步
在多线程异步执行任务时,可以通过 ExecutorService
和 Future
来执行异步任务,并在任务执行完毕后进行统一推送。
实现步骤:
- 提交任务:将多个 AI 任务提交给线程池(
ExecutorService
)进行异步执行。 - 获取结果:使用
Future
获取每个任务的结果,Future
会提供一个get()
方法,该方法会阻塞当前线程,直到异步任务完成并返回结果。 - 统一推送:当所有任务执行完成后,统一推送结果,或者通过一个 回调机制 或 事件驱动机制 将结果推送到客户端或前端。
-
ExecutorService
和Future
:-
适用于小到中等规模的异步任务,且任务主要在一个应用内部执行,任务之间有较强依赖关系,或者需要保证任务的顺序执行。
-
-
消息队列:
-
适用于大规模的异步任务、高并发、大数据量的任务,尤其是跨服务、跨系统的任务。消息队列能有效解耦生产者和消费者,支持分布式架构,适合大规模分布式系统。
-
🧩 AOP 和通用字段填充
-
你基于 AOP 实现了公共字段填充,这部分是通过注解实现的吗?是否有考虑和 MyBatis-Plus 的
MetaObjectHandler
做结合? -
AOP 切面在哪些场景下被触发?它是基于方法名还是注解识别?你是如何减少业务层代码冗余的?
🔹二、围绕“外卖服务平台”项目的面试问题
🧩 JWT 与拦截器
-
你是如何使用 ThreadLocal 实现用户信息上下文传递的?你是否有设计用户信息清理机制,防止内存泄漏?
-
拦截器 + JWT 校验中,如何处理 token 过期和非法 token 情况?是否设计了全局异常处理?
🧩 RabbitMQ 消息队列
-
你是如何配置 RabbitMQ 的?使用了哪几种 Exchange 类型?具体在哪些场景用了消息队列?
我在项目中使用 RabbitMQ 主要用于系统解耦、异步处理任务、以及延迟队列功能。在配置上,使用 Spring Boot 的 spring-boot-starter-amqp
进行自动化配置,通过注解或 Java 配置类声明队列、交换机和绑定关系。使用了 Direct、Fanout、Topic 三种 Exchange 类型:
-
Direct 用于订单模块中的库存锁定;
-
Fanout 用于用户行为后的多渠道通知;
-
Topic 用于 AI 模块的任务分发和状态通知;
此外,还设计了延迟队列用于订单超时关闭,提升了系统的用户体验和处理效率。
-
你是如何确保消息的幂等性与可靠性?有没有使用消息确认机制、死信队列、重试机制?
🧩 WebSocket 实现推送
-
你用 WebSocket 实现了来单提醒功能,是基于 STOMP 协议还是原生 WebSocket?如何实现用户级别的精准推送?
我们用的是 Spring Boot 原生 WebSocket,客户端通过携带 Token 建立连接,服务端校验 Token 并建立用户 ID 到 Session 的映射,实现用户级别的精准推送。通过内存 Map 维护连接,接收到订单后精准推送到商家端,并在连接关闭时自动清理资源,保证系统稳定性和实时性。
-
你有没有处理 WebSocket 的断线重连和会话保持问题?如果连接异常,你的系统是怎么处理的?
WebSocket 是长连接,断线可能由于网络不稳定、服务器重启、前端刷新等原因发生。如果不做处理,用户可能错过重要推送,比如外卖订单提醒。
我们前端实现了自动断线重连机制,后端通过 token 重新建立用户连接映射。同时在连接断开时及时清理旧 session,避免内存泄漏。对极端情况下消息可能漏发的问题,也通过 Redis 缓存未送达消息,或者接入消息队列做异步补偿,保证消息最终一致性。
🔹三、项目扩展类问题(融合两个项目)
📌 项目协作和模块拆分
-
这两个项目你都是“后端开发”,请问你在团队中具体负责了哪些模块?是否主导过某一部分的设计或开发?
-
在项目开发过程中,后端和前端是如何对接口的?你们是否采用了统一的接口文档管理工具,比如 Swagger?
📌 性能优化 & 问题排查
-
项目上线后是否遇到过性能瓶颈?比如 Redis 的命中率不高,或者线程阻塞等?你是如何排查并优化的?
-
数据库设计上有没有做过分库分表、索引优化等?能不能举个优化后明显提升的例子?