尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
【苍穹外卖项目 Grill 面试总结】
第一轮基础概念Q1一次请求经过哪些层正确链路请求 → [JwtInterceptor检查Token] → [LogAspect记日志] → Controller → Service ↓ ← JSON Mapper ↑ ↓ [Jackson 序列化] MySQL ↓ ← Service ← 数据 ← [Redis 缓存拦截]第二次请求同一接口时Cacheable 让 Service 直接走 Redis连 Mapper 和 MySQL 都不经过。Q2category_id → categoryId 谁做的✅ MyBatis不是 Spring MVC配置在 application.propertiesmybatis.configuration.map-underscore-to-camel-casetrueMyBatis 查完数据库后自动把下划线命名转驼峰。Spring MVC 不管这事。Q3没有异常处理 vs 有异常处理阶段查 id999前端看到没有异常处理Mapper 返回 null → Controller 包装 Result.success(null){code:1,data:null} 用户懵了有异常处理Service 发现 null → throw new BusinessException(菜品不存在) → GlobalExceptionHandler 接住{code:0,msg:菜品不存在} ✅Q4#categoryId 里的 # 是什么✅ SpEL 表达式Spring Expression Language#categoryId → 取方法参数 categoryId 的实际值。categoryId1 → key 是 1categoryId → 字面量字符串所有分类用同一个 key查什么都返回同一份缓存常见 SpEL 表达式表达式含义#参数名取方法参数的值#result取方法返回值#对象.属性取对象的属性值Q5拦截器抛异常会被全局异常处理器捕获吗❌ 不会请求 → [拦截器 preHandle] ← 在 DispatcherServlet 之前 ↓ 抛异常 → 直接返回错误给客户端 DispatcherServlet 还没介入 RestControllerAdvice 管不到这里RestControllerAdvice 只拦截 Controller 层抛出的异常。拦截器在 Controller 之前必须自己 try-catch 处理。对比JwtInterceptorGlobalExceptionHandler部署位置Controller 之前Controller 之后拦截对象HTTP 请求Controller 抛出的异常覆盖范围门禁检查Controller → Service → Mapper 全线Q6form-data vs raw JSON格式Content-Type适用场景form-datamultipart/form-data传文件、文件文字混合raw JSONapplication/json传结构化数据x-www-form-urlencodedapplication/x-www-form-urlencoded传简单表单JSON 只支持文本图片是二进制数据。multipart/form-data 是专门为文件上传设计的协议。Q7Component、Service、RestController 的区别功能上完全一样把 Service 换成 Component 项目照样跑区别在语义分层标签Component ← 通用Spring 管理的组件 ├── Service ← 业务逻辑层 ├── Repository ← 数据访问层MyBatis 用 Mapper 替代 └── Controller ← 控制层返回视图 └── RestController ← 返回 JSONQ8Autowired 和 Cacheable 谁先生效✅ Autowired 先生效启动时Cacheable 后生效运行时启动时Spring 创建 DishServiceImpl → Autowired 注入 DishMapper→ Cacheable 生成代理对象包装原对象运行时来请求了→ 代理检查 Redis 有没有缓存→ 有 → 直接返回不执行方法体不碰 Mapper/MySQL→ 没有 → 执行方法体 → dishMapper 查 MySQL → 结果存 Redis注入是启动时的事缓存检查是运行时的事不在一个时间维度。第二轮架构与设计Q9为什么 Service 要写接口 实现类关键原因Spring AOP 代理机制Spring 需要生成代理对象来注入 Cacheable、Transactional 等魔力DishServiceImpl原始对象 ↓ JDK 动态代理基于接口 Proxy 对象 原始对象 Cacheable 拦截 CacheEvict 拦截 ↓ Controller 拿到的就是 Proxy缓存注解才能生效有接口 → JDK 动态代理干净。没接口 → CGLIB 继承代理也能跑但有坑不能代理 final/private 方法。Q10allEntries true 有什么问题问题删一道菜全清缓存 → 过度清理更好的做法是精确清除CacheEvict(cacheNames dish, key #dish.categoryId) // 只清该分类 CacheEvict(cacheNames dish, key all) // 只清全部列表Q11Service 内部 this.xxx() 缓存会生效吗❌ 不会this.getByCategoryId(1L) // ↑ this 原始对象没走过 Spring 的 Proxy // Cacheable 注解 摆设外部调用走代理 → 生效。内部 this 走原始对象 → 不生效。解决方法注入自己Autowired private DishService self; // 注入的是代理对象 self.getByCategoryId(1L); // 走代理 ✅经典 Spring AOP 陷阱面试高频考点。第三轮故障与边界Q12Redis 挂了Cacheable 方法会怎样默认直接抛异常整个请求失败但缓存不应该成为单点故障——缓存挂了业务必须降级跑。核心思想缓存是锦上添花不能因它瘫痪。拦截器 配置可以做到 Redis 不可用时自动跳过缓存、直连数据库。Q13数据库插入成功但清缓存失败 → 不一致场景insert(dish) → 成功 ✅清缓存 → Redis 网络抖动失败 ❌结果数据库有新菜Redis 是旧列表解决思路方案做法先删缓存再更新删缓存 → 更新数据库查询时重建延迟双删删缓存 → 更新 DB → 等一会儿再删一次TTL 兜底至少过期后会强制刷新不会永远不一致本项目allEntries true TTL 10 分钟就是最朴素的兜底。Q14管理员禁用员工后旧 JWT 还能用吗✅ 能JWT 是无状态的不记名小票——一旦签发只要没过期就能用。拦截器不查数据库不检查 status。解决方案方案做法代价每次请求查库拦截器查 status每次打 DBRedis 黑名单禁用时 JWT 加入黑名单有状态了短 TTL15 分钟过期 Refresh Token频繁刷新苍穹外卖JWT Redis 黑名单。全部薄弱点汇总轮次薄弱点正确答案R1SpEL #取变量值不是路径参数R1驼峰转换MyBatis 做的R1拦截器异常不被 RestControllerAdvice 捕获R1Component vs Service功能一样语义不同R1注入 vs 缓存时序注入启动时缓存运行时R2接口 实现类为了 JDK 动态代理AOPR2allEntries true过度清理应精确清除R2this.xxx()绕过代理缓存不生效R3Redis 挂掉缓存异常应降级不能拖垮业务R3DB/缓存不一致用 TTL 兜底至少不会永远不一致R3禁用后 JWT 仍有效无状态小票的固有缺陷靠黑名单或短 TTL 解决
RELATED

相关推荐

全能加解密工具包:统一SM2、RSA、AES、MD5,解决金融项目安全痛点

全能加解密工具包:统一SM2、RSA、AES、MD5,解决金融项目安全痛点

1. 项目概述:为什么我们需要一个全能的加解密工具包?在当今的数字化项目中,无论是处理用户敏感信息、保障API通信安全,还是进行数据完整性校验,加解密和签名验签都是绕不开的核心环节。我最近在重构一个老旧的金融项目…

📅 2026/8/2 8:07:26
这是什么树,花草树木种类在线识别

这是什么树,花草树木种类在线识别

我们经常在一下情况的时候需要知道这个是什么树木 一、游玩、户外出行时 爬山、徒步、公园散步、露营、郊野踏青,看到陌生树木想知道名字、是否有毒、果实能不能碰; 景区打卡古树、特色景观树,想了解树种习性与文化寓意。 二、学习、完成作…

📅 2026/8/3 1:11:23
如何用flutter-checkio打造高效习惯养成系统:从安装到打卡的完整指南

如何用flutter-checkio打造高效习惯养成系统:从安装到打卡的完整指南

如何用flutter-checkio打造高效习惯养成系统:从安装到打卡的完整指南 【免费下载链接】flutter-checkio How time flies.一款开源习惯打卡APP,流畅的动画体验,Bloc实现状态管理,主题(颜色)切换,字体切换,数…

📅 2026/8/22 8:19:50
MORE NEWS

更多资讯

📰

Oracle 19c RAC环境OPatch版本过旧?完整升级流程实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

代码注释去 AI 味 Skill,TaoToken 只供 Key

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

Python解析docx补录试题:从文档到结构化题库

简介:这是一份2019年广西柳州市三支一扶考试补录试题及答案解析文档,集中面向报考广西地区“三支一扶”岗位、需要系统刷题与快速提分的考生。文档共收录46页笔试题目,内容覆盖政治理论、法律基础、公文写作、计算机应用、时政热点及事业单位…

📰

AXI总线实战:Lite控制、Stream传输与MM外设的FPGA落地指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

保理业务管理系统解决方案:领域建模、计息引擎与对接实践

简介:这份《保理业务管理系统解决方案》文档面向商业保理公司信息化建设负责人、产品经理与系统实施人员,围绕客户管理、产品管理、项目管理、合同管理、作业管理、财务管理、预警管理及查询统计等模块,给出从保前调查、保中审查到保后检查的…

📰

鸿蒙版Flutter配置全指南:从环境搭建到fvm多版本管理

1. 项目概述与核心需求拆解1.1 为什么“鸿蒙版Flutter”成了开发者社区的硬需求做跨平台开发的朋友应该都有同感:Flutter从诞生那天起,主打的就是“一套代码,多端运行”。Android、iOS、Web、Windows、macOS、Linux,一套Dart代码基…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬