中间件&Linux
一、Spring&SpringBoot
1.IoC、依赖注入、@Autowired&@Resource
①什么是IoC?
②说一说Spring IoC实现的原理
③依赖注入的三种方式
④@Autowired和@Resource的区别
2.AOP、动态代理
①什么是AOP?
②JDK 动态代理和 CGLIB 动态代理对比
③SpringAOP实践
参考文章:https://blog.csdn.net/qq_40454136/article/details/126098759
首先通过@Aspect+@Component标注切面类,
然后通过@Pointcut:定义一个切面位置,通常是某个方法;
之后就可以通过@Before:前置通知、@After:后置通知、@Around:环绕通知等来定义切面前后要执行的操作;
(也可以不用@Pointcut定义切面位置,直接使用@Around+@Annotation来对某个自定义注解进行环切)
④AOP思想的体现2——HandlerInterceptor(同时也是Spring MVC的应用)
参考文章:https://blog.csdn.net/qq_38586496/article/details/111590660
通过实现HandlerInterceptor接口自定义拦截器,并在实现了WebMvcConfigurer接口的控制类中配置拦截器应用的url和执行次序,即可对指定url的执行进行拦截,在其执行前后进行特定操作;
HandlerInterceptor中有三个方法:
preHandle:在执行Controller方法前执行,只有当返回true时才会继续往下执行,返回false就不会继续执行Controller方法了——可以在此方法中进行权限校验等操作;
postHandle:在执行Controller方法中的逻辑,return视图之前执行——可以在此方法中添加对视图的操作
afterCompletion:在Controller方法return视图之后执行——
原理:在DispatcherServlet的doDispatch方法中,会获取拦截器链,并在执行Controller方法前后,执行每个拦截器中的对应方法;
⑤AOP思想的体现3——Filter
参考文章:https://blog.csdn.net/ShuSheng0007/article/details/129330360
通过实现Filter接口及其中的doFilter方法自定义过滤器,并加上@Component注解,即可对所有url进行拦截,并执行doFilter方法中的操作;
(还可以通过@Order来规定多个过滤器的执行顺序,越小越先执行,还可以在配置类中创建FilterRegistrationBean<自定义过滤器>的Bean,并在其中对过滤器的拦截范围进行配置)
原理:在HttpRequest到达servlet之前进行拦截,在HttpResponse到达客户端之前进行拦截;
和HandlerInterceptor的区别:
Filter过滤器是在Spring MVC外层对请求进行拦截,可以拦截所有请求,而HandlerInterceptor是在Spring MVC内部对请求进行拦截(有图见参考文章),只能拦截通过DispatcherServlet进行处理的请求
正因如此,Filter更具通用性,粒度更粗,在Filter中只能拿到http请求相关的信息,拿不到应用层面的信息——常用于检查用户请求,过滤非法请求
而HandlerInterceptor则通用性差一些,但粒度更细,可以获取应用层面的信息,例如类目方法名等——常用于
最后在使用层面,Filter在doFilter一个方法中定义预处理和后处理逻辑,在方法中通过filterChain.doFilter进行分隔,而HandlerInterceptor将预处理和后处理逻辑拆分成两个方法,即preHandle、postHandle方法;
⑥Filter过滤器和Interceptor拦截器使用到了哪些设计模式
AOP体现了代理模式,
拦截器链、过滤器链体现了责任链模式;
3.Spring MVC
①什么是Spring MVC?
②Spring MVC的原理?
③Spring MVC有哪些核心组件?
4.自动装配、Bean、SpringBoot的常用注解
①什么是SpringBoot的自动装配?原理是什么?
②SpringBoot的常用注解
5.Bean
①Bean 是线程安全的吗?
②Bean的生命周期
参考文章;https://zhuanlan.zhihu.com/p/638361741
首先,在Spring应用启动时,IOC容器就会读取配置文件,并通过反射机制为每个非懒加载的Bean创建实例和属性赋值;
之后,用户可以通过各种方法进行依赖注入来获得Bean的实例对象,并进行使用;
最后当应用程序关闭时,IOC容器也会执行销毁方法来销毁Bean,销毁方法中还可以添加一些资源释放的操作,例如关闭连接、清理缓存等;
③Bean的属性有哪些
class:类的全限定名;
name:Bean的名称;
scope:Bean的作用域,常用的就是singleton单例、prototype每次都重新创建,默认为单例;
lazy-initialization mode:是否懒加载,指是否在创建容器时就加载Bean到容器中,还是等使用到的时候再加载;
④Bean的作用域
- singleton : IoC 容器中只有唯一的 bean 实例,也是Spring 中默认的作用域;
- prototype : 每次获取都会创建一个新的 bean 实例。也就是说,连续
getBean()
两次,得到的是不同的 Bean 实例;
6.循环依赖、全局异常处理
①什么是循环依赖?如何解决?
循环依赖就是两个或多个Bean之间互相持有对方,形成了一个环,比如A中包含B,B中包含C,C中又包含了A;
可以通过采用构造器注入的方式进行依赖注入,这样如果存在循环依赖在启动项目时就会报错,对发生循环依赖的类进行修改即可;
②全局异常处理怎么做?
首先创建一个用@ControllerService标注的全局异常处理类,可以在参数值指定拦截范围(比如某个包)
然后在其中创建各种用@ExceptionHandler标注的处理异常的方法,并在参数中指定要处理的异常类型;
这样Spring就会给所有Controller添加异常处理的逻辑,当发生异常时就会去异常处理类下去找可以处理异常的方法,并取其中匹配度最高的;
二、RabbitMQ
1.消息队列、优缺点、常用消息队列对比
① 什么是消息队列?
②消息队列的优点&缺点
③常见消息队列的对比,为什么选用RabbitMQ?
三、Linux
1.常用的shell命令有哪些?
①目录操作的命令:
ls查看当前目录文件列表,pwd显示当前目录,cd进入目录,mkdir创建目录等;
②文件编辑相关命令:
vi/vim编辑文件,rm删除文件,cp复制文件,touch创建文件;
③系统管理相关命令:
ifconfig查看ip地址,ping测试连通性,kill杀死进程,ps查看进程状态;
查看当前进程使用到的端口:
netstat -tunlp | grep <进程ID>
-
netstat
:netstat
是一个用于显示网络连接、路由表和网络接口等网络系统状态的命令。在这个命令中,-tunlp
参数用于显示当前系统的网络连接情况,具体含义如下:-t
:显示 TCP 协议的连接。-u
:显示 UDP 协议的连接。-n
:直接使用 IP 地址,而不进行域名解析。-l
:仅显示监听状态的连接。-p
:显示正在使用的进程/程序的 PID 和名称。
-
grep
:grep
是一个用于在文本中搜索指定模式的命令。在这个命令中,grep <进程ID>
用于过滤出包含特定进程ID的行。
ls命令:显示当前目录文件列表,-a显示所有文件包括隐藏文件;
cd命令:切换目录,cd dir切换到dir目录,cd /切换到根目录,cd ...切换到上一级目录;
cp命令:copy文件,cp source target将文件source复制为target,cp /root/source将/root目录下的文件source复制到当前目录;
rm命令:删除文件或目录,rm file删除某个文件, rm -rf dir删除当前目录下叫dir的整个目录;
pwd命令:获取当前地址;
mkdir:创建文件夹;
2. Linux有哪些IO机制?
阻塞IO和非阻塞IO?——阻塞和非阻塞IO强调准备数据阶段线程是否会被阻塞
四、设计模式
1.代理模式、静态代理&动态代理
①什么是代理模式?
②静态代理和动态代理的区别
③动态代理中JDK 动态代理和 CGLIB 动态代理对比
④手动演示一下静态代理、两种动态代理的代码
2.单例模式
①什么是单例模式?
②单例模式需要满足的条件
③推荐使用的两种单例模式实现方式
3.工厂模式、适配器模式、观察者模式、策略模式
①什么是工厂模式?
②什么是适配器模式?代理模式和适配器模式的区别?
通过添加适配器类,将一个类的接口转换成客户端所期望的另一个接口,来解决接口不匹配的问题;
Spring MVC 中的 HandlerAdapter 就是适配器模式的应用,用于将不同类型的处理器适配到框架中统一的处理器接口;
③什么是观察者模式?
又叫发布者-订阅者模式,定义对象间的的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新;
使用场景:订阅通知场景,如消息队列、Redis的发布订阅功能;
④什么是策略模式?
指将一系列功能类型、对外接口都相同的算法单独封装起来作为一个个策略,通过一个上下文类来切换不同的策略,使得相同的接口在不同策略下可以实现不同的功能" 设计模式 设计模式分类 设计模式分类
⑤设计模式分类
4. Spring框架中用到了哪些设计模式?
①工厂模式:Spring通过BeanFactory、ApplicationContext创建bean对象就用到了工厂模式;
②单例模式:Spring中的Bean默认的作用域就是单例;
③代理模式:Spring AOP功能的实现就是通过动态代理来实现的;
④适配器模式:SpringMVC中DispatcherServlet通过调用HandlerAdapter来进一步调用各种Handler,HandlerAdapter就应用到了适配器模式;
⑤观察者模式:Spring的事件驱动模型就用到了观察者模式;
5.什么是责任链模式? 什么是责任链模式?
参考文章:https://blog.csdn.net/lishuzhen5678/article/details/125657672
用于将请求的发送者和接收者解耦,并按照一定顺序依次处理请求。
spring中的Filter使用、从Filter机制看设计模式(责任链模式,装饰器模式)
Spring中的过滤器filter,通过实现Filter接口中的init()、doFilter()、destroy()方法,在请求进入控制器之前、响应返回客户端之前进行预处理或者后处理。
过滤器常用于实现一些通用的功能,比如日志记录、权限验证等;
还有拦截器intercepter也是用到了责任链模式;
二者功能类似,区别主要在于Filter更加通用,可以用于任何Servlet容器中,而Interceptor更加专注于Spring MVC框架中的请求处理流程;
五、场景题
1.订单秒杀怎么做的?
①超卖问题如何解决?
超卖问题本质上是因为在高并发场景下,多个线程同时判断还有剩余商品,于是都进行了减少商品库存操作,导致商品数量被减
了负数,也就是超卖;
解决问题的核心在于保证查询商品数量+减少商品库存操作的原子性,
对于单体应用,可以通过本地锁synchronized/ReentranLock等来实现;
对于分布式应用,可以通过Redis set NX实现的分布锁、Redission框架提供的分布式锁、或是zookeeper提供的分布锁来实现;
如果不直接对数据库进行操作,而是对缓存进行操作的话,也可以使用Lua脚本来保证查询商品数量+减少商品库存操作的原子性
之后再通过MQ异步地将数据更新到数据库中;
在一个分布式系统中,如何设置订单ID?保证订单ID单调递增?(瞎蒙了一个时间戳+一个自增数值)
+
那么如果在某天,系统中获取时间戳的部分出问题,无法获取正确的时间戳,怎么保证订单ID单调递增?" "在一个分布式系统中,如何设置订单ID?保证订单ID单调递增?(瞎蒙了一个时间戳+一个自增数值)
那么如果在某天,系统中获取时间戳的部分出问题,无法获取正确的时间戳,怎么保证订单ID单调递增?
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构