跳转至

2025年8月29日

面试题

请描述一下 @RequestParam、@RequestBody、@PathVariable 这几个注解的应用场景及作用?详细描述

@RequestParam

作用:用于获取请求中的查询参数或表单参数,把这些值绑定到方法参数上。

应用场景

  • URL 查询字符串:如 GET /users?page=1&size=10,接收分页参数。
  • 表单提交:处理简单的表单字段,如搜索关键字、状态筛选。
  • 多值参数:如 ids=1&ids=2,收集到 List

@RequestBody

作用:用于获取请求体中的数据,并自动反序列化成 Java 对象。

应用场景

  • JSON 提交:前端发送复杂对象,如用户注册信息、订单详情。
  • 批量操作:提交一个对象列表,比如批量新增用户。
  • 修改/新增接口:接收前端传来的完整数据对象。

@PathVariable

作用:用于从URL 路径占位符中提取参数,绑定到方法参数。

应用场景

  • RESTful 风格接口:如 GET /users/{id} 获取用户详情。
  • 资源定位:常用来标识资源的唯一 ID,比如商品编号、订单号。
  • 多层级资源:如 /shops/{shopId}/orders/{orderId}

午间演讲示例

@RequestParam用来接收查询参数或者表单字段,比如分页参数、搜索条件;

@RequestBody用来接收请求体里的数据,通常是前端传过来的JSON对象,用在新增或修改这类复杂对象提交;

@PathVariable则是从路径上取值,常见于RESTful接口,比如 /users/{id} 这种资源定位。

聊聊 Mybatis 中常见的动态 SQL 的标签有哪些,这些标签的作用和使用场景是什么

1、 <if>

作用:根据条件决定是否拼接一段 SQL。 应用场景:可选查询条件,比如用户搜索时,只有输入了关键字才拼接 AND name LIKE ...

2、 <where>

作用:自动去掉多余的 AND/OR,如果子条件都不满足,就不会加 WHERE应用场景:组合查询时非常常用,比如多条件筛选用户,避免写一堆 WHERE 1=1

3、 <set>

作用:主要用于动态 UPDATE 语句,会自动去掉最后多余的逗号。 应用场景:更新时,只修改用户传过来的字段,比如更新用户资料时,只有传了邮箱才更新邮箱。

4、 <foreach>

作用:用来遍历集合,生成 IN 条件或批量插入。 应用场景:批量操作,比如 SELECT * FROM user WHERE id IN (...) 或批量插入多条数据。

午间演讲示例

首先是 <if> ,它的作用是根据条件来决定是否拼接SQL,常见场景就是可选查询条件,比如用户搜索时,如果输入了关键字,就拼接AND name LIKE ...

接着是 <where> ,它能帮我们自动去掉多余的ANDOR,如果条件都没有,也不会生成WHERE,常用于多条件组合查询,避免写一堆WHERE 1=1

第三个是 <set> ,主要用在动态更新里,它会自动去掉最后多余的逗号,场景就是用户修改资料时,只更新传过来的字段,比如只传了邮箱就只更新邮箱。

最后是 <foreach> ,这个常用来遍历集合,生成IN条件或批量插入,典型场景就是批量查询用户id,或者一次性插入多条数据。

什么是 AOP

传智播客-面试知识点 - 飞书云文档

aop是面向切面编程,在spring中用于将那些与业务无关,但却对多个对象产生影响的公共行为和逻辑,抽取公共模块复用,降低耦合,一般像系统的公共日志记录,事务处理,权限的控制等都可以通过AOP来实现。

可能继续追问的问题:

1). 你们项目中有没有使用到AOP?

这个很多地方都用到了,比如我们当时在后台管理系统中,就是使用aop来记录了系统的操作日志、以及权限控制。那就来说一下,记录日志的操作思路吧。

主要思路是这样的,使用aop中的环绕通知 加上 基于注解@annotation 的切点表达式来实现的。

  • 首先,自定义了一个注解,比如叫 @Log,然后哪些操作需要记录日志,我们就在哪些方法上加上这个注解。
  • 然后再定义一个切面类,通过环绕通知,来获取原始方法在运行的各项信息,比如:类信息、方法信息、注解、请求方式、请求参数、当前操作人、操作时间、返回值等信息,全部记录下来,保存在数据库中。

当时,我们主要记录的是一些核心业务模块的增删改的操作日志,主要便于数据追踪。

2). AOP的底层是如何实现的?

SpringAOP的底层主要是通过动态代理技术实现的,主要是两种代理技术。一种是JDK的动态代理,而JDK的动态代理呢,有限制,只能针对于实现了接口的类做代理,所以,在spring中还有一种是Cglib动态代理,那Cglib动态代理呢,就没有这个限制。

3). JDK动态代理 与 Cglib动态代理有什么区别呢?

  • 限制不同。 JDK动态代理,要求被代理对象必须实现了接口才可以。 而Cglib动态代理,无论是否实现接口都可以(只要类不是final修饰即可)。
  • 代理对象不同。 JDK动态代理生成的代理对象,与被代理对象其实是实现了相同的接口,可以说是兄弟关系。 而Cglib动态代理生成的代理对象,其实是继承了被代理类,是基于继承体系的,所以是父子关系。 也正是因为此,所以Cglib不能为被final修饰的类做代理。

午间演讲示例

AOP是面向切面编程,在Spring里常用来处理日志、事务、权限这些和业务无关但很常见的逻辑,能降低耦合、提高复用。

在项目里我们就用AOP记录操作日志,做法是定义一个@Log注解,配合环绕通知,把方法信息、参数、操作人、时间等收集起来保存到数据库,方便追踪。

底层上,Spring AOP是通过动态代理实现的,分为JDK代理和Cglib代理。

JDK只能代理实现了接口的类,生成的代理和目标是兄弟关系;Cglib是通过继承目标类生成子类代理,不要求接口,但不能代理final类。

SpringMVC 的拦截器用过没有

追问:你说的这些个功能,过滤器好像也能干,那拦截器 Interceptor 与过滤器 Filter 有什么区别

拦截器在SpringMVC里主要做登录校验、权限控制、日志记录这些和请求相关的功能。它和过滤器的区别可以打个比方:过滤器就像机场安检,在大门口,所有人都要过一遍,不分场合;而拦截器就像公司前台的门禁,只有准备进某个会议室的人才会被拦下来验证身份。所以,Filter更偏底层通用,Interceptor更贴近业务逻辑。

午间演讲示例

我用过拦截器Interceptor,主要用来做登录校验、权限控制、日志记录这类跟请求相关的功能。

  1. 技术所属:Filter属于Java EE规范,Interceptor属于spring规范
  2. 拦截资源的范围:Filter拦截部署在Tomcat服务上web项目中所有资源(静态+动态) Interceptor只能拦截spring框架管控的资源(Controller)