当前位置: 首页 > article >正文

AOP相关面试题

什么是AOP答AOP面向切面编程。核心思想将横切关注点从核心逻辑中分离出来形成一个一个切面横切关注点多个类或对象中的公共行为如日志记录、事务管理、接口限流、接口幂等性切面Aspect对横切关注点进行封装的类最核心的三个实际应用场景统一日志记录不需要在每个Controller里写log.info直接搞个切面拦截所有请求然后记录日志权限校验加个自定义注解切面识别到这个注解就自定查一下这个人有没有权限Spring事物Transactional: Transactional注解的底层就是一个AOP切面。AOP常见的通知类型有哪些通知切面在某个连接点要执行的操作。有五种类型Before目标方法执行前执行After目标方法执行后执行Around环绕通知可以拿到目标对象以及要执行的方法可以编写代码控制目标方法的执行过程在目标方法的前或后执行After Returning目标方法调用完之后在结果return之前触发After Throwing目标方法运行抛出异常后执行Spring AOP实现方法有哪些Spring AOP基于动态代理实现的。动态代理是在运行时动态生成代理对象从而实现在不修改源代码的情况下增强方法的功能。Spring AOP支持两种动态代理基于JDK的动态代理使用Proxy类和InvocationHandler接口实现。Spring框架背地里生成代理对象Proxy包含源代码逻辑和增强逻辑基于CGLIB的动态代理当代理类没有实现InvocationHandler接口时Spring框架会使用CGLIB库继承代理类生成一个子类在子类中重写添加增强逻辑Spring AOP属于运行时增强而AspectJ是编译时增强直接基于字节码进行操作。Spring AOP已经集成了AspectJ两者区别Spring AOP是在运行时动态生成代理类启动慢 AspectJ 在编译时就缝合好了运行是没有额外开销性能拉满代价是编译时间长AOP实现接口幂等性的逻辑什么是接口幂等性答不管前端提交几次后端只执行一次使用AOP 自定义注解 Redis实现接口幂等性前端的请求头中带一个用户唯一表示比如订单号、前端申请的唯一token请求传过来时通过redis的 SETNX命令设置对应的值如果为True说明第一次请求放行如果为False说明已经有一摸一样的请求了如果没有AOP在“创建订单”、“支付”、“扣减库存”等业务中都需要执行redis记录和判断的逻辑可以创建AOP切面来进行解耦和复用。还需要自定义注解来加到需要进行幂等性操作的业务方法上。比如自定义 Idempotent 注解AOP切面方法盯着这些注解使用Around 环绕通知执行Redis逻辑来判断是否要放行执行业务方法伪代码Around(annotation(你的自定义注解Idempotent)) public Object checkIdempotent(ProceedingJoinPoint joinPoint) { // 1. 提取当前请求的唯一凭证比如 Header 里的 Token 或 订单号 String token request.getHeader(Idempotent-Token); // 2. 去 Redis 里占坑利用 SETNX 特性并设置个过期时间比如 5秒 boolean success redisTemplate.opsForValue().setIfAbsent(token, 正在处理, 5, TimeUnit.SECONDS); // 3. 判断是否重复请求 if (!success) { // 占坑失败说明是重复点击直接把这颗子弹没收不让它进入 Controller throw new RuntimeException(手速太快啦请勿重复点击); } try { // 4. 占坑成功放行执行目标方法你真正的买皮肤、扣钱逻辑 return joinPoint.proceed(); } finally { // 5. 业务执行完后你可以选择把 Redis 里的坑挖掉或者等它自己过期 // redisTemplate.delete(token); } }Spring 的事务是如何实现的Spring事务的本质就是 数据库 对事物的支持。没有数据库事务的支持 spring是无法提供事务功能的 Spring提供事务管理的统一接口具体实现都是由各个数据库自己实现。Spring 支持 编程式事务管理 和 声明式事务管理1.编程式事务使用 TransactionTemplateAutowired private TransactionTemplate transactionTemplate; public void testTransaction() { transactionTemplate.execute(new TransactionCallbackWithoutResult() { Override protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) { try { // .... 业务代码 } catch (Exception e){ //回滚 transactionStatus.setRollbackOnly(); } } }); }2. 声明式事务使用Transactional声明式事务建立在AOP之上的。其本质是通过AOP功能 对方法前后进行拦截将事务处理的额外功能 和 方法的核心功能功能编制在一起 。无法像编程式事务那样做到代码块级别的事务控制事务的传播机制是指当一个事务的方法被另一个事务方法调用时该事务方法如何进行。正常来说有三种解决方案1. 融入事务直接去掉serviceB中关于开启事务和提交事务的begin和commit融入到serviceA的事务中。问题B事务的错误会引起A事务的回滚。2. 挂起事务如果不想B事务的错误引起A事务的回滚可以开启两个连接一个执行A一个执行B互不影响执行到B的时候把A挂起新起连接去执行BB执行完了再唤醒A执行。两个事务的执行互不干扰B事务的回滚不影响A事务3.嵌套事务MySQL中可以通过给B事务加savepoint和rollback去模拟嵌套事务把B设置成伪事务。嵌套事务会保存回滚点7种事务传播行为TransactionDefinition.PROPAGATION_NEVER: 以非事务方式运行如果当前存在事务则抛出异常。默认传播行为requierd-加入到当前事务支持当前事务的requierd 有就加入没有就创建新事务常用于子方法为修改事务supports没有当前事务就以非事务执行常用于子方法为只读事务mandatory: 使用当前事务 没有当前事务就抛异常nested如果有当前事务则以嵌套事务执行。如果没有当前事务则创建新事务不支持当前事务的required_new: 新建一个事务当前事务挂起not_supported: 以非事务方式执行操作当前事务挂起never 以非事务方式执行如存在当前事务则抛出异常补充在 Spring 中一个事务方法A通过 this 调用同类中的非事务方法B时非事务方法会加入事务原理通过ThreadLocal实现的 B方法顺用了 A 在 ThreadLocal 里的连接Service public class MyService { Autowired private MyService selfProxy; // 注入自身代理 Transactional public void transactionalMethod() { selfProxy.nonTransactionalMethod(); // 通过代理调用非事务方法加入事务 } public void nonTransactionalMethod() { // 此时会加入事务 } }事务失效的情况1.事务方法非public修饰由于Spring的事务是基于AOP的方式结合动态代理来实现的。因此事务方法一定要是public的这样才能便于被Spring做事务的代理和增强。2. 非事务方法调用事务方法相当于通过this.调用的普通方法而不是生成代理方法非事务方法调用事务方法没有走代理事务启动不了3. 事务方法的异常被捕获了spring感受不到事务就不会回滚了4.事务异常类型不对Spring的事务管理默认感知的异常类型是RuntimeException当事务方法内部抛出了一个IOException时不会被Spring捕获5.事务传播行为不对如果一个事务调用另一个事务如果被调用的事务的事务传播行为是REQUIRED_NEW进入子事务时会创建一个新的事务为子事务而不会与调用者事务合并当调用者事务发生异常时被调用事务不会回滚6.没有被Spring管理比较低级的错误比如没有加 Service注解

相关文章:

AOP相关面试题

什么是AOP?答:AOP面向切面编程。核心思想:将横切关注点从核心逻辑中分离出来,形成一个一个切面横切关注点:多个类或对象中的公共行为(如:日志记录、事务管理、接口限流、接口幂等性)…...

SQL SERVER 登陆错误:18456

前几天开发让我去解决一个sql server express****的连接问题,由于只是他们自己用用,所以就没有由我们安装商业版。 报错如下我先去check****了下,发现数据库正常开启。**但是打开Network Configuration,**发现网络都没有开启,于是…...

【码道初阶-Hot100】LeetCode 438 + 567 对照详解:一套滑动窗口模板,彻底讲透“固定长度窗口 + 计数数组 + count维护”

LeetCode 438 567 对照详解:一套滑动窗口模板,彻底讲透“固定长度窗口 计数数组 count维护” 摘要 很多人把 LeetCode 438 和 567 当成两道题分开记,其实完全没必要。它们本质上是同一个固定长度滑动窗口模型,真正难点只在一个…...

大数据隐私保护与数据价值平衡:企业如何做到合规又能用好数据?

大数据隐私保护与价值平衡:企业的“合规用数”实战指南 引言:企业的“数据两难”——锁起来可惜,用起来怕违规 你有没有遇到过这样的困境? 为了符合《个人信息保护法》,把用户数据严严实实地锁在数据库里,看…...

「龙虾」来了!OpenClaw如何掀起AI智能体革命

「龙虾」爆火:OpenClaw的崛起与狂欢 OpenClaw生态系统 #mermaid-svg-CLPHlB6DV7TSkxDt{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{t…...

大模型AI-入门-发展历程-机器学习

部分内容可能来自网络或者由AI生成。 如有雷同,纯属巧合,仅供学习参考之用。机器学习(ML) 机器学习是人工智能的核心分支,其本质是让计算机系统从数据中自动学习规律,并用于预测或决策。一、机器学习的三大…...

【AI Agent 学习笔记 task1】Day2:初识智能体

【AI Agent 学习笔记 task1】Day2:初识智能体 上一篇:【AI Agent 学习笔记】Hello-Agents 环境配置与首个 Agent 实战 一、Agent 的本质 Agent(智能体) 大模型(大脑) 工具(手脚) 控…...

一次生成、无限复用:易元 AI 双引擎重构生产逻辑,AI 混剪素材复用让内容越做越省

内容生产的真正效率,从来不取决于单条视频做得有多快,而在于单次投入能产生多少次价值、一次制作能支撑多少次产出,这就是素材复用的核心价值。在传统模式下普通的混剪工具只是机械拼接、单次产出,无法实现素材沉淀与循环使用&…...

5-11字典合并

输入用字符串表示两个字典,输出合并后的字典。字典的键用一个字母或数字表示。注意:1和‘1’是不同的关键字!输入格式:在第一行中输入第一个字典字符串;在第二行中输入第二个字典字符串。输出格式:在一行中输出合并的字典&#xf…...

86745238

86745238...

AI 模型推理系统的延迟优化方案

AI模型推理系统的延迟优化方案 随着AI技术的广泛应用,模型推理延迟成为影响用户体验和系统性能的关键因素。无论是实时语音识别、自动驾驶,还是在线推荐系统,高延迟都会降低响应速度,甚至导致业务损失。如何优化AI推理系统的延迟…...

LeetCode 3070. 元素和小于等于 k 的子矩阵数目

LeetCode 3070. 元素和小于等于 k 的子矩阵数目 题目描述 给你一个大小为 m x n 的整数矩阵 grid 和一个整数 k。你需要找出 grid 中所有以左上角 (0,0) 为起始点的子矩阵,并统计这些子矩阵中元素和不超过 k 的个数。 注意:子矩阵必须包含 (0,0) 这个格子…...

Java的虚拟线程调度与平台线程池在IO密集型应用中的扩展性

Java虚拟线程与平台线程池在IO密集型应用中的扩展性探索 随着微服务与云原生架构的普及,IO密集型应用对高并发的需求日益增长。传统Java线程模型因平台线程(OS线程)的创建成本高、上下文切换开销大等问题,难以实现高效扩展。Java…...

都跟掉电保护有关,但不是一个东西

以前会误以为 BKP 就等于 RTC因为它们有三个很容易让人混淆的共同点:它们都和“掉电保持”有关它们都在备份域里访问它们时常常都要先打开相关权限于是很容易脑子里变成:既然都和掉电保持有关,那它们是不是一回事其实不是。这就像&#xff1a…...

虚拟实验室:物理化学实验的计算机模拟

虚拟实验室:物理化学实验的计算机模拟 在传统物理化学实验中,学生常受限于设备、安全风险或时间成本,而虚拟实验室通过计算机模拟技术,为学习者提供了全新的实验体验。虚拟实验室不仅能高度还原真实实验场景,还能突破…...

Python的__init_subclass__类方法在框架开发中的钩子机制与扩展点设计

Python作为一门灵活的动态语言,其元编程能力为框架设计提供了强大的扩展性。在众多魔法方法中,__init_subclass__作为Python 3.6引入的类方法,正逐渐成为框架开发中实现钩子机制与扩展点设计的秘密武器。这个特殊方法允许父类在子类创建时进行…...

去中心化应用(DApp)开发全流程

去中心化应用(DApp)开发全流程:从构思到落地 随着区块链技术的普及,去中心化应用(DApp)成为开发者关注的热点。与传统应用不同,DApp运行在区块链网络上,具备透明、不可篡改和去中心…...

Rust Trait 对象动态分派原理

Rust Trait对象动态分派原理探析 Rust作为一门注重安全与性能的系统级语言,其多态实现机制一直是开发者关注的焦点。Trait对象通过动态分派(Dynamic Dispatch)实现了运行时的多态行为,这种机制在需要灵活处理不同类型但共享相同行…...

SSH隧道实战:内网穿透与端口转发

SSH隧道实战:内网穿透与端口转发 在当今数字化时代,远程访问内网资源成为许多企业和开发者的刚需。由于防火墙或NAT的限制,直接访问内网服务往往困难重重。SSH隧道作为一种安全高效的解决方案,能够轻松实现内网穿透和端口转发&am…...

如何设计一个安全的 RESTful API?

如何设计一个安全的 RESTful API?在当今数字化时代,RESTful API 已成为不同系统间数据交互的核心桥梁。随着网络攻击手段的日益复杂,API 的安全性已成为开发者不可忽视的挑战。一个设计不当的 API 可能导致数据泄露、服务瘫痪甚至法律风险。那…...

计算机视觉算法优化

计算机视觉算法优化:让机器更懂世界 计算机视觉作为人工智能的核心领域之一,正深刻改变着我们的生活。从人脸识别到自动驾驶,从医疗影像分析到工业质检,计算机视觉算法的性能直接决定了应用的准确性和效率。随着数据量的爆炸式增…...

STM32:UART串口通信

将一个设备的数据传送到另一个设备时,需要根据情况的不同,制定通信的规则,即通信协议。通信双方按照协议规则进行数据收发。常用的通信协议有名称引脚双工时钟电平设备USARTTX\RX全双工异步单端点对点I2CSCL\SDA半双工同步单端多设备SPISCLK\…...

# WebHID:用 JavaScript 实现浏览器与物理设备的“直连”交互在传统Web 开发中,浏览器对硬件设备的

WebHID:用 JavaScript 实现浏览器与物理设备的“直连”交互 在传统 Web 开发中,浏览器对硬件设备的支持始终受限于安全策略。但随着 WebHID API 的出现,开发者终于可以绕过复杂的驱动层和中间件,直接通过标准 JavaScript 与 USB H…...

Java synchronized 锁优化与偏向锁分析

Java synchronized锁优化与偏向锁分析 在多线程编程中,synchronized关键字是Java实现线程同步的核心机制。早期的synchronized实现因性能问题饱受诟病,直到JVM引入了锁优化技术,尤其是偏向锁的引入,显著提升了并发性能。本文将深…...

Python的__getattr__业务对象

Python魔法方法揭秘:灵活操控属性的__getattr__在Python的面向对象编程中,__getattr__是一个强大而神秘的魔法方法,它像一位隐藏在幕后的属性调度员。当常规属性访问失败时,这个方法就会被自动触发,为开发者提供了处理…...

软件工程软件开发生命周期瀑布模型与敏捷模型的比较

软件工程中的开发模型选择直接影响项目成败,瀑布模型与敏捷模型作为两种经典方法论,分别代表了结构化与灵活性的两极。随着数字化转型加速,开发团队常面临模型选择的困惑。本文将从核心维度对比二者的差异,帮助读者理解不同场景下…...

wythoff构造(正十二面体)

...

C++ 析构函数的隐藏风险

C析构函数的隐藏风险:那些容易被忽视的陷阱 在C编程中,析构函数作为对象生命周期的终结者,负责释放资源、清理内存等重要任务。其看似简单的设计背后却暗藏诸多风险,稍有不慎便可能导致内存泄漏、未定义行为甚至程序崩溃。本文将…...

JavaScript性能优化实战不赜

JavaScript性能优化实战技术文章大纲 性能优化的核心原则 减少代码执行时间 降低内存占用 优化网络请求 提升用户体验 代码层面的优化 避免全局变量污染,使用模块化或闭包 减少DOM操作,批量更新或使用文档片段 使用事件委托减少事件监听器数量 优化循环结…...

C++中的策略模式实战

1、非修改序列算法这些算法不会改变它们所操作的容器中的元素。1.1 find 和 find_iffind(begin, end, value):查找第一个等于 value 的元素,返回迭代器(未找到返回 end)。find_if(begin, end, predicate):查找第一个满…...