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

SSM aop切面编程的学习

面向切面的AOP编程的引入:

    1. 代码缺陷

        - 非核心代码对核心业务功能有干扰,导致程序员在开发核心业务功能时分散了精力

        - 附加功能代码重复,分散在各个业务功能方法中!冗余,且不方便统一维护

    2. 解决思路

          核心就是:解耦。我们需要把附加功能从业务功能代码中抽取出来。

          将重复的代码统一提取,并且[[动态插入]]到每个业务方法!

    3. 技术困难

        解决问题的困难:提取重复附加功能代码到一个类中,可以解决。

如何实现这种提取的技术?——需要使用代理模式

一、代理模式的概述(sketch)

1.代理模式

    二十三种设计模式中的一种,属于结构型模式。它的作用就是通过提供一个代理类,让我们在调用目标方法的时候,不再是直接对目标方法进行调用,而是通过代理类间接调用。让不属于目标方法核心逻辑的代码从目标方法中剥离出来——解耦调用目标方法时先调用代理对象的方法,减少对目标方法的调用和打扰,同时让附加功能能够集中在一起也有利于统一维护。

    相关术语:

     - 代理:将非核心逻辑剥离出来以后,封装这些非核心逻辑的类、对象、方法。(中介)

     - 动词:指做代理这个动作,或这项工作

     - 名词:扮演代理这个角色的类、对象、方法

     - 目标:被代理“套用”了核心逻辑代码的类、对象、方法。(房东)

    代理在开发中实现的方式具体有两种:静态代理,[动态代理技术]

2.静态代理

主动创建代理类

静态代理确实实现了解耦,但是由于代码都写死了,完全不具备任何的灵活性。就拿日志功能来说,将来其他地方也需要附加日志,那还得再声明更多个静态代理类,那就产生了大量重复的代码,日志功能还是分散的,没有统一管理

提出进一步的需求:将非核心代码集中到一个代理类中,将来有任何日志需求,都通过这一个代理类来实现。这就需要使用动态代理技术了。

代码举例:

目标接口

public interface Calculator {int add(int i, int j);  int sub(int i, int j);  int mul(int i, int j); int div(int i, int j);}

目标(实现类)

public class CalculatorPureImpl implements Calculator {@Overridepublic int add(int i, int j) {int result = i + j;return result;}@Overridepublic int sub(int i, int j) {int result = i - j;return result;}@Overridepublic int mul(int i, int j) {int result = i * j;return result;}@Overridepublic int div(int i, int j) {int result = i / j;return result;}}

静态代理类:(继承目标接口,实现接口方法,使用构造函数传入目标,这样就可以通过目标类的对象调用核心代码;在方法中写非核心代码,核心代码由目标对象调用;当我们测试时我们调用代理的方法,而代理又调用了目标的方法)

public class StaticProxyCalculator implements Calculator {//使用构造函数传入目标private Calculator calculator;public StaticProxyCalculator(Calculator target){this.calculator=target;}@Overridepublic int add(int i, int j) {//非核心代码System.out.println("i = " + i + ", j = " + j);//调用目标int result = calculator.add(i, j);System.out.println("result = " + result);return result;}@Overridepublic int sub(int i, int j) {return 0;}@Overridepublic int mul(int i, int j) {return 0;}@Overridepublic int div(int i, int j) {return 0;}}

 

 

3.动态代理

- JDK动态代理

JDK原生的实现方式,需要被代理的目标类必须实现接口!他会根据目标类的接口动态生成一个代理对象代理对象和目标对象有相同的接口!(拜把子)

- cglib动态代理

通过继承被代理的目标类实现代理,所以不需要目标类实现接口!(认干爹)

4.代理模式的优缺点

优点:

可以解决附加功能代码干扰核心代码和不方便统一维护的问题。

实现方式主要是:将附加功能代码提取到代理中执行,不干扰目标核心代码!

缺点:

无论使用静态代理和动态代理(jdk,cglib),程序员的工作都比较繁琐,需要自己编写代理工厂等。

但是,在实际开发中,不需要编写代理代码,我们可以使用[Spring AOP]框架,会简化动态代理的实现!

二、面向切面的编程思维AOP

AOP:Aspect Oriented Programming面向切面编程

AOP可以说是OOP(Object Oriented Programming,面向对象编程)的补充和完善。OOP引入封装、继承、多态等概念来建立一种对象层次结构,用于模拟公共行为的一个集合。不过OOP允许开发者定义纵向的关系,但并不适合定义横向的关系,例如日志功能。日志代码往往横向地散布在所有对象层次中,而与它对应的对象的核心功能毫无关系。对于其他类型的代码,如安全性、异常处理和透明的持续性也都是如此,这种散布在各处的无关的代码被称为横切(cross cutting,在OOP设计中,它导致了大量代码的重复,而不利于各个模块的重用。

AOP技术恰恰相反,它利用一种称为"横切"的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其命名为"Aspect",即切面。所谓"切面",简单说就是那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性和可维护性。

使用AOP,可以在不修改原来代码的基础上添加新功能。

 

1. AOP思想主要的应用场景

    AOP(面向切面编程)是一种编程范式,它通过将通用的横切关注点(如日志、事务、权限控制等)与业务逻辑分离,使得代码更加清晰、简洁、易于维护。AOP可以应用于各种场景,以下是一些常见的AOP应用场景:

    1. 日志记录

在系统中记录日志是非常重要的,使用AOP来实现日志记录的功能,可以在方法执行前、执行后或异常抛出时记录日志。

    2. 事务处理

在数据库操作中使用事务可以保证数据的一致性,可以使用AOP来实现事务处理的功能,可以在方法开始前开启事务,在方法执行完毕后提交或回滚事务。

    3. 安全控制

在系统中包含某些需要安全控制的操作,如登录、修改密码、授权等,可以使用AOP来实现安全控制的功能。可以在方法执行前进行权限判断,如果用户没有权限,则抛出异常或转向到错误页面,以防止未经授权的访问。

    4. 性能监控

在系统运行过程中,有时需要对某些方法的性能进行监控,以找到系统的瓶颈并进行优化。可以使用AOP来实现性能监控的功能,可以在方法执行前记录时间戳,在方法执行完毕后计算方法执行时间并输出到日志中。

    5. 异常处理

系统中可能出现各种异常情况,如空指针异常、数据库连接异常等,可以使用AOP来实现异常处理的功能,在方法执行过程中,如果出现异常,则进行异常处理(如记录日志、发送邮件等)。

    6. 缓存控制

在系统中有些数据可以缓存起来以提高访问速度,可以使用AOP来实现缓存控制的功能,可以在方法执行前查询缓存中是否有数据,如果有则返回,否则执行方法并将方法返回值存入缓存中。

    7. 动态代理

AOP的实现方式之一是通过动态代理,可以代理某个类的所有方法,用于实现各种功能。

    综上所述,AOP可以应用于各种场景,它的作用是将通用的横切关注点与业务逻辑分离,使得代码更加清晰、简洁、易于维护。

AOP代码,用于处理非核心代码的冗余业务。

2.AOP八个核心名词

1-横切关注点

在各个类中具有相似形式的非核心代码。

从每个方法中抽取出来的同一类非核心业务。在同一个项目中,我们可以使用多个横切关注点对相关方法进行多个不同方面的增强。

这个概念不是语法层面天然存在的,而是根据附加功能的逻辑上的需要:有十个附加功能,就有十个横切关注点。

AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。AOP的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开

2-通知(增强)

增强:提取冗余代码。并且可以在方法前和方法后执行逻辑代码。

每一个横切关注点上要做的事情都需要写一个方法来实现,这样的方法就叫通知方法。

- 前置通知:在被代理的目标方法前执行

- 返回通知:在被代理的目标方法成功结束后执行(**寿终正寝**)

- 异常通知:在被代理的目标方法异常结束后执行(**死于非命**)

- 后置通知:在被代理的目标方法最终结束后执行(**盖棺定论**)

- 环绕通知:使用try...catch...finally结构围绕整个被代理的目标方法,包括上面四种通知对应的所有位置

3-连接点 joinpoint

连接点:目标方法

这也是一个纯逻辑概念,不是语法定义的。

指那些被拦截到的点。在 Spring 中,可以被动态代理拦截目标类的方法

4-切入点 pointcut

定位连接点的方式,或者可以理解成被选中的连接点

是一个表达式,比如execution(* com.spring.service.impl.*.*(..))。符合条件的每个方法都是一个具体的连接点。

5-切面 aspect

切点+增强

是一个类。

6-目标 target

被代理的目标对象。

7-代理 proxy

向目标对象应用通知之后创建的代理对象。

8-织入 weave

指把通知应用到目标上,生成代理对象的过程。可以在编译期织入,也可以在运行期织入,Spring采用后者。

三、Spring-aop框架

1. AOP一种区别于OOP的编程思维,用来完善和解决OOP的非核心代码冗余和不方便统一维护问题!

2. 代理技术(动态代理|静态代理)是实现AOP思维编程的具体技术,但是自己使用动态代理实现代码比较繁琐。

3. Spring AOP框架,基于AOP编程思维,封装动态代理技术,简化动态代理技术实现的框架!SpringAOP内部帮助我们实现动态代理,我们只需写少量的配置,指定生效范围即可,即可完成面向切面思维编程的实现

基于注解方式实现spring-AOP

1.导入依赖

2.正常编写核心业务,加入ioc容器

3,编写ioc的配置类和文件

4.测试环境

5.增强类,定义三个增强方法

6.增强类的配置

7.开启aop的配置

四、实现aop切面编程

1、总体过程

(1)准备接口和接口的实现类

(2)准备一个切面类(@Aspect,@Component)

在切面类中使用增强方法。

注意:需要使用@Aspect表示这个类是一个切面类,使用@Component注解放入ioc容器中

 1.定义方法存储增强代码

 * 核心代码中,在不同位置的非核心代码出现一次,对应一个增强方法。

 * 使用注解配置,可以指定插入目标方法的位置

 *  2. 使用注解配置 指定插入目标方法的位置

 *  前置  @Before

 *  后置  @AfterReturning

 *  异常  @AfterThrowing

 *  最后  @After

 *  环绕  @Around

 *  3.配置注解的内容

 *  4.完善注解,@Component

 *

 * @Author Qum

 * @Create 2025/3/19  10:28

 */

@Aspect@Componentpublic class LogAdvice {//注解需要指定插入的方法@Before("execution(* com.atguigu.service.impl.*.*(..))")public void start(){System.out.println("function started");}@After("execution(* com.atguigu.service.impl.*.*(..))")public void after(){System.out.println("function ended");}@AfterThrowing("execution(* com.atguigu.service.impl.*.*(..))")public void error(){System.out.println("function has error");}}

 

(3)创建一个注解类文件(@EnableAspectJAutoProxy,@Configuration,@ComponentScan)

@Configuration@ComponentScan(basePackages = "com.atguigu")//作用等于 <aop:aspectj-autoproxy /> 配置类上开启 Aspectj注解支持!@EnableAspectJAutoProxypublic class MyConfig {}

2、获取增强方法的具体信息

* 1、定义方法

* 2、使用注解指定对应的位置

* 3、配置切点表达式选中方法

* 4、切面和ioc 的配置

* 5、开启aspect的注解

*

* 增强方法中,获取目标方法的信息

* 在方法中传入JoinPoint joinPoint,使用joinPoint获取各种信息

* 返回的结果-@AfterReturning

* 在注解中指定返回变量,Object result

* 异常的信息-@AtferThrowing

* 在注解中指定异常的参数

(1) JointPoint接口

    需要获取方法签名、传入的实参等信息时,可以在通知方法声明JoinPoint类型的形参。

    - 要点1:JoinPoint 接口通过 getSignature() 方法获取目标方法的签名(方法声明时的完整信息)

    - 要点2:通过目标方法签名对象获取方法名

    - 要点3:通过 JoinPoint 对象获取外界调用目标方法时传入的实参列表组成的数组

 

```Java

// @Before注解标记前置通知方法

// value属性:切入点表达式,告诉Spring当前通知方法要套用到哪个目标方法上

// 在前置通知方法形参位置声明一个JoinPoint类型的参数,Spring就会将这个对象传入

// 根据JoinPoint对象就可以获取目标方法名称、实际参数列表

@Before(value = "execution(public int com.atguigu.aop.api.Calculator.add(int,int))")public void printLogBeforeCore(JoinPoint joinPoint) {// 1.通过JoinPoint对象获取目标方法签名对象// 方法的签名:一个方法的全部声明信息Signature signature = joinPoint.getSignature();// 2.通过方法的签名对象获取目标方法的详细信息String methodName = signature.getName();System.out.println("methodName = " + methodName);int modifiers = signature.getModifiers();System.out.println("modifiers = " + modifiers);String declaringTypeName = signature.getDeclaringTypeName();System.out.println("declaringTypeName = " + declaringTypeName);// 3.通过JoinPoint对象获取外界调用目标方法时传入的实参列表Object[] args = joinPoint.getArgs();// 4.由于数组直接打印看不到具体数据,所以转换为List集合List<Object> argList = Arrays.asList(args);System.out.println("[AOP前置通知] " + methodName + "方法开始了,参数列表:" + argList);}

```

(2) 方法返回值

    在返回通知中,通过@AfterReturning注解的returning属性获取目标方法的返回值!

 

```Java

// @AfterReturning注解标记返回通知方法// 在返回通知中获取目标方法返回值分两步:// 第一步:在@AfterReturning注解中通过returning属性设置一个名称// 第二步:使用returning属性设置的名称在通知方法中声明一个对应的形参@AfterReturning(value = "execution(public int com.atguigu.aop.api.Calculator.add(int,int))",returning = "targetMethodReturnValue")public void printLogAfterCoreSuccess(JoinPoint joinPoint, Object targetMethodReturnValue) {String methodName = joinPoint.getSignature().getName();System.out.println("[AOP返回通知] "+methodName+"方法成功结束了,返回值是:" + targetMethodReturnValue);}

```

(3)异常对象捕捉

    在异常通知中,通过@AfterThrowing注解的throwing属性获取目标方法抛出的异常对象

 

```Java

// @AfterThrowing注解标记异常通知方法

// 在异常通知中获取目标方法抛出的异常分两步:

// 第一步:在@AfterThrowing注解中声明一个throwing属性设定形参名称

// 第二步:使用throwing属性指定的名称在通知方法声明形参,Spring会将目标方法抛出的异常对象从这里传给我们

@AfterThrowing(value = "execution(public int com.atguigu.aop.api.Calculator.add(int,int))",throwing = "targetMethodException")public void printLogAfterCoreException(JoinPoint joinPoint, Throwable targetMethodException) {String methodName = joinPoint.getSignature().getName();System.out.println("[AOP异常通知] "+methodName+"方法抛异常了,异常类型是:" + targetMethodException.getClass().getName());}

```

3、切点表达式的规则

*  切点表达式固定语法execution(1 2 3.4.5(6))

*  1.访问修饰符

*  2.方法的返回值类型

*  String int void

*  如果不考虑访问修饰符和返回值,则整合声明为*

*  如果不考虑,则两个都不考虑。

*  3.包的位置

*  具体包;com.atguigu.service

*  单层模糊:com.atguigu.service.*

*  多层模糊:com..impl  任意层的模糊

*  *..*.*(..)表示全部包下的全部类的全部方法。..不能开头但是*可以

*  细节:..不能开头

*  4.类的名称

*  具体:CalculatorPureImpl

*  模糊:*

*  部分模糊:*Impl

*  5.  方法名 语法和类名一直

*  6.形参列表

*  没有参数:()

*  有具体参数(String)  若有两个参数:(String,Int)

*  部分具体和模糊:

*          第一个参数是字符串的方法 (String..)

*          最后一个参数是字符串 (..String)

*          字符串开头,int结尾 (String..int)

*          包含int类型(..int..)

4、统一切点管理(@PointCut)

@Pointcut("execution(* com.atguigu.service.impl.*.*(..))")public void pc(){}

//切点的统一管理

//1.定义一个空方法

//2.加上注解@Pointcut(“写入切点表达式”)

//2.可以在增强注解的括号内写入定义的空方法

推荐:

/创建一个切点类,存储统一管理的切点表达式

@Componentpublic class MyPointCut {@Pointcut("execution(* com.atguigu.service.impl.*.*(..))")public void pc(){}@Pointcut("execution(* com..impl.*.*(..))")public void mypc(){}}

 

对于增强方法括号内切点表达式的引用:

@Component@Aspect@Order(5)public class TXAdvice {@Before("com.atguigu.pointcut.MyPointCut.pc()")public void start(){System.out.println("事务开启");}@AfterReturning("com.atguigu.pointcut.MyPointCut.pc()")public void commit(){System.out.println("事务提交");}}

 

5、环绕通知(@Around)

环绕通知对应整个 try...catch...finally 结构,包括前面四种通知的所有功能。

@Component@Aspectpublic class TXAroundAdvice {@Around("com.atguigu.pointcut.MyPointCut.pc()")//在方法上使用@Around的注解,同样需要传入切点方法public Object transaction(ProceedingJoinPoint proceedingJoinPoint){// 通过在通知方法形参位置声明ProceedingJoinPoint类型的形参,Spring会将这个类型的对象传给我们//环绕通知  需要再通知中定义目标方法的执行Object[] args = proceedingJoinPoint.getArgs();//通过ProceedingJoinPoint对象获取外界调用目标方法时传入的实参数组// 通过ProceedingJoinPoint对象获取目标方法的签名对象Signature signature = proceedingJoinPoint.getSignature();// 声明变量用来存储目标方法的返回值Object result=null;try {System.out.println("开启事务");//相当于@Beforeresult = proceedingJoinPoint.proceed(args);System.out.println("结束事务");//相当于@AfterReurning} catch (Throwable e) {throw new RuntimeException(e);} finally {}return result;}}

6、切面优先级设置(@Order)

使用 @Order 注解可以控制切面的优先级:

- @Order(较小的数):优先级高

- @Order(较大的数):优先级低

7、CGLib动态代理生效

在目标类没有实现任何接口的情况下,Spring会自动使用cglib技术实现代理。

使用总结:

  a.  如果目标类有接口,选择使用jdk动态代理

  b.  如果目标类没有接口,选择cglib动态代理

  c.  如果有接口,接口接值

  d.  如果没有接口,类进行接值

使用aop的总结:

xml配置aop

<!-- 配置目标类的bean --><bean id="calculatorPure" class="com.atguigu.aop.imp.CalculatorPureImpl"/><!-- 配置切面类的bean --><bean id="logAspect" class="com.atguigu.aop.aspect.LogAspect"/><!-- 配置AOP --><aop:config><!-- 配置切入点表达式 --><aop:pointcut id="logPointCut" expression="execution(* *..*.*(..))"/><!-- aop:aspect标签:配置切面 --><!-- ref属性:关联切面类的bean --><aop:aspect ref="logAspect"><!-- aop:before标签:配置前置通知 --><!-- method属性:指定前置通知的方法名 --><!-- pointcut-ref属性:引用切入点表达式 --><aop:before method="printLogBeforeCore" pointcut-ref="logPointCut"/><!-- aop:after-returning标签:配置返回通知 --><!-- returning属性:指定通知方法中用来接收目标方法返回值的参数名 --><aop:after-returningmethod="printLogAfterCoreSuccess"pointcut-ref="logPointCut"returning="targetMethodReturnValue"/><!-- aop:after-throwing标签:配置异常通知 --><!-- throwing属性:指定通知方法中用来接收目标方法抛出异常的异常对象的参数名 --><aop:after-throwingmethod="printLogAfterCoreException"pointcut-ref="logPointCut"throwing="targetMethodException"/><!-- aop:after标签:配置后置通知 --><aop:after method="printLogCoreFinallyEnd" pointcut-ref="logPointCut"/><!-- aop:around标签:配置环绕通知 --><!--<aop:around method="……" pointcut-ref="logPointCut"/>--></aop:aspect></aop:config>

 

五、aop对于获取bean的影响

1. 情景一

    - bean 对应的类没有实现任何接口

    - 根据 bean 本身的类型获取 bean

        - 测试:IOC容器中同类型的 bean 只有一个

 正常获取到 IOC 容器中的那个 bean 对象

        - 测试:IOC 容器中同类型的 bean 有多个

            会抛出 NoUniqueBeanDefinitionException 异常,表示 IOC 容器中这个类型的 bean 有多个

解决:根据唯一的id值获取

2. 情景二

    - bean 对应的类实现了接口,这个接口也只有这一个实现类

        - 测试:根据接口类型获取 bean

        - 测试:根据类获取 bean

        - 结论:上面两种情况其实都能够正常获取到 bean,而且是同一个对象

3. 情景三

    - 声明一个接口

    - 接口有多个实现类

    - 接口所有实现类都放入 IOC 容器

        - 测试:根据接口类型获取 bean

            会抛出 NoUniqueBeanDefinitionException 异常,表示 IOC 容器中这个类型的 bean 有多个

        - 测试:根据类名获取bean

            正常

4. 情景四

    - 声明一个接口

    - 接口有一个实现类

    - 创建一个切面类,对上面接口的实现类应用通知

        - 测试:根据接口类型获取bean

            正常

        - 测试:根据类获取bean

            无法获取

    原因分析:

    - 应用了切面后,真正放在IOC容器中的是代理类的对象

    - 目标类并没有被放到IOC容器中,所以根据目标类的类型从IOC容器中是找不到的

 情景五

    - 声明一个类

    - 创建一个切面类,对上面的类应用通知

        - 测试:根据类获取 bean,能获取到

使用总结

目标类有接口时,放入ioc容器的是jdk动态代理实现目标接口的代理对象,此时只能根据接口类型获取bean,实现类没有被放入ioc容器中,无法通过实现类得到对应的bean。

相关文章:

SSM aop切面编程的学习

面向切面的AOP编程的引入&#xff1a; 1. 代码缺陷 - 非核心代码对核心业务功能有干扰&#xff0c;导致程序员在开发核心业务功能时分散了精力 - 附加功能代码重复&#xff0c;分散在各个业务功能方法中&#xff01;冗余&#xff0c;且不方便统一维护&#xff01; 2. 解决思路 …...

Zen 5白色装机优选,华硕X870 AYW GAMING WIFI W主板来了!

华硕X870/X870E系列主板再次迎来新成员——华硕X870 AYW GAMING WIFI W主板正式发售&#xff01;专为追求高性价比游戏玩家而量身打造&#xff0c;延续AYW系列经典SPACE太空元素&#xff0c;配合大面积银白色散热装甲&#xff0c;打造出了极具金属质感和科技感的外观&#xff0…...

第Y1周:调用YOLOv5官方权重进行检测

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 文章目录 1、前言2、下载源码3、运行代码 1、前言 YOLOv5分为YOLOv5s、YOLOv5m、YOLOv5l、YOLOv5x四个版本&#xff0c;这里以YOLOv5s为例。 2、下载源码 安…...

科技项目验收测试怎么做?验收测试报告如何获取?

科技项目从研发到上市需要一个很长的周期&#xff0c;并且在上市之前还有一个至关重要的交付过程&#xff0c;那就是项目验收&#xff0c;验收需要通过验收测试来呈现。科技项目验收测试是确保项目成功交付的关键步骤&#xff0c;那么是如何进行的呢?企事业单位想要获取科技项…...

C++笔记

C知识笔记 一、C概述 C是一种通用编程语言&#xff0c;它在C语言的基础上扩展而来&#xff0c;支持面向对象编程、泛型编程和过程化编程等多种编程范式。C具有高效、灵活、接近硬件等特点&#xff0c;广泛应用于系统软件、应用软件、嵌入式系统、游戏开发等领域。其强大的性能…...

国产Linux统信安装mysql8教程步骤

系统环境 uname -a Linux FlencherHU-PC 6.12.9-amd64-desktop-rolling #23.01.01.18 SMP PREEMPT_DYNAMIC Fri Jan 10 18:29:31 CST 2025 x86_64 GNU/Linux下载离线安装包 浏览器下载https://downloads.mysql.com/archives/get/p/23/file/mysql-test-8.0.33-linux-glibc2.28…...

如何应对“最后时刻任务堆积”(鼓包现象)

应对“最后时刻任务堆积”&#xff08;鼓包现象&#xff09;的方法包括&#xff1a;合理规划项目时间表、强化进度跟踪管理、明确任务优先级、有效的资源配置、提升团队沟通效率。其中&#xff0c;强化进度跟踪管理尤为关键。根据项目管理协会&#xff08;PMI&#xff09;的调查…...

C语言,原码、补码、反码

计算机是以补码来存储的 原码&#xff1a;正数最高位为&#xff1a;0&#xff1b;负数最高位为&#xff1a;1 &#xff08;最高位是符号位&#xff09; 正数&#xff1a;三码合一 如&#xff1a;2&#xff1a; 原码&#xff1a;0000 0000 0000 0000 0000 0000 0000 0010&#…...

Unifying Short and Long-Term Tracking with Graph Hierarchies—CVPR2023

Unifying Short and Long-Term Tracking with Graph Hierarchies 博客目录 Unifying Short and Long-Term Tracking with Graph Hierarchies摘要概况引言和相关介绍提出的观点 SUSHI核心构建跟踪图的层次结构构建分层剪辑分区 做第二个创新模块的需要将研究的重点从处理遮挡的问…...

深入解析 C# 中的模板方法设计模式

模板方法设计模式&#xff08;Template Method Pattern&#xff09;是行为型设计模式中的一种&#xff0c;它定义了一个操作中的算法框架&#xff0c;并允许子类在不改变算法整体结构的情况下&#xff0c;重新定义该算法的某些步骤。该模式通常用于类中包含一系列固定步骤的算法…...

0411 | 软考高项笔记:项目立项

在软考的项目管理知识体系中&#xff0c;技术可行性和经济可行性是项目立项阶段非常重要的两个分析维度。以下是对这两个考点的详细解释和记忆方法&#xff1a; 技术可行性分析 定义&#xff1a; 技术可行性分析是评估项目在现有技术条件和资源下是否能够成功实施。它主要回答…...

ubnetu 服务器版本常用端口和开放的端口对应的应用

1. 使用 netstat 查看端口与进程 netstat 是查看网络连接和监听端口的常用工具。通过以下命令可以列出所有开放的TCP/UDP端口及其关联的进程&#xff1a; sudo netstat -tulnp参数解析&#xff1a; -t&#xff1a;显示TCP端口。 -u&#xff1a;显示UDP端口。 -l&#xff1…...

【服务器端表单字符验证】

文章目录 一、实验目的二、核心代码实现三、调试关键问题四、总结 一、实验目的 掌握JSP表单验证在服务器端的实现技术&#xff0c;实现对用户输入字符的非空及长度为5的验证&#xff0c;返回对应提示信息并优化用户交互。 二、核心代码实现 前端表单 <form action"…...

pip 与 conda 的全面比较:Python 包管理的深度解析

在 Python 的生态系统中&#xff0c;包管理工具是开发者日常工作的重要组成部分。​其中&#xff0c;pip 和 conda 是最常用的两种包管理工具。​虽然它们在功能上有一些重叠&#xff0c;但在设计理念、功能范围、依赖管理、环境隔离等方面存在显著差异。​本文将从多个维度深入…...

GTID不一致修复

背景描述 GTID模式下&#xff0c;mysql主从切换后&#xff0c;主从同步报错 Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: The slave is connecting using CHANGE MASTER TO MASTER_AUTO_POSITION 1, but the master has purged bi…...

conda-pack打包环境到超算上。解决无法打包可编辑包

conda-pack 打包 使用 conda-pack 打包 Conda 环境可以将整个环境打包成一个独立的可移植压缩包&#xff0c;方便在其他机器上解压使用。以下是具体步骤&#xff1a; 1.安装 conda-pack 首先需要安装 conda-pack。你可以通过 conda 或 pip 安装&#xff1a; conda install …...

O(n)复杂度实现寻找数组第k小的数(快速选择算法)

非堆排序实现&#xff0c;利用快速排序思想实现的快速选择 package algorithm;public class Test {public int quickSelect(int nums[], int left, int right, int k){if (left right) return nums[left];int i left - 1, j right 1, x nums[left];while (i < j){do i…...

利用 RNN 预测股票价格:从数据处理到可视化实战

在金融领域&#xff0c;预测股票价格走势一直是众多投资者和研究者关注的焦点。今天&#xff0c;我们将利用深度学习中的循环神经网络&#xff08;RNN&#xff09;来构建一个简单的股票价格预测模型&#xff0c;并详细介绍从数据加载、预处理、模型搭建、训练到最终结果可视化的…...

前端从全链路角度分析性能

在面试中回答“从全链路角度分析性能优化”时,需覆盖用户请求到页面渲染的完整链路。以下是结构化回答框架,结合业界实践和最新优化策略: 一、网络传输优化 1. CDN与协议升级 ◦ 使用CDN缩短资源物理距离,结合HTTP/2/3的多路复用和头部压缩特性,提升资源加载效率(如We…...

2025年第十八届“认证杯”数学中国数学建模网络挑战赛【BC题】完整版+代码+结果

# 问题一&#xff1a;随机森林回归from sklearn.ensemble import RandomForestRegressormodel_rf RandomForestRegressor()model_rf.fit(X_train, y_train)# 问题二&#xff1a;LSTM时间序列预测from tensorflow.keras.models import Sequentialmodel_lstm Sequential()model…...

权限管控与数据安全:衡石ChatBot在钉钉中的合规部署指南

数据安全是ChatBot落地的第一道门槛 在数字化转型浪潮下&#xff0c;企业数据查询正从“专业BI工具”向“自然语言交互”跃迁。衡石ChatBot通过钉钉等企业IM工具&#xff0c;让业务人员以对话方式实时获取数据&#xff0c;极大提升了决策效率。然而&#xff0c;数据开放的同时…...

什么是生产管理看板?

简单来说,生产管理看板就是一种把生产过程“摆在明面上”的工具——它可能是贴在墙上的白板,也可能是车间里一块大屏幕,主要作用就是让生产信息一目了然。 这种看板广泛用在工厂、制造车间、或者办公室里,它把生产计划、任务进度、库存情况、设备状态等重要数据通通“晒”…...

YOLO学习笔记 | 一文详解YOLOv11核心创新与实践方法

===================================================== github:https://github.com/MichaelBeechan CSDN:https://blog.csdn.net/u011344545 ===================================================== YOLOv11核心创新与实践 一、架构创新1. ‌模块升级与参数优化‌2. ‌多…...

198. 打家劫舍:动态规划

前言 本篇文章来自leedcode&#xff0c;是博主的学习算法的笔记心得。 如果觉得对你有帮助&#xff0c;可以点点关注&#xff0c;点点赞&#xff0c;谢谢你&#xff01; 题目来源 198. 打家劫舍 - 力扣&#xff08;LeetCode&#xff09; 题目描述 思路 1.对于只有一个房间…...

算法基础模板

高精度加法 #include <bits/stdc.h> using namespace std; const int N10005; int A[N],B[N],C[N],al,bl,cl; void add(int A[],int B[],int C[]) {for(int icl-1;~i;i--){C[cl]A[i]B[i];C[cl1]C[cl]/10;C[cl]%10;}if(C[cl])cl; } int main() {string a,b;cin>>a&…...

【大模型LLM第十六篇】Agent学习之浅谈Agent loop的几种常见范式

anthropics agent https://zhuanlan.zhihu.com/p/32454721762 code&#xff1a;https://github.com/anthropics/anthropic-quickstarts/blob/main/computer-use-demo/computer_use_demo/loop.py sampling_loop函数 每次进行循环&#xff0c;输出extract tool_use&#xff0…...

[特殊字符] Spring Boot 日志系统入门博客大纲(适合初学者)

一、前言 &#x1f4cc; 为什么日志在项目中如此重要&#xff1f; 在开发和维护一个后端系统时&#xff0c;日志就像程序运行时的“黑匣子”&#xff0c;帮我们记录系统的各种行为和异常。一份良好的日志&#xff0c;不仅能帮助我们快速定位问题&#xff0c;还能在以下场景中…...

【模拟电路】隧道二极管

与标准二极管相比&#xff0c;隧道二极管通过使用具有令人难以置信的大掺杂水平的半导体物质来工作&#xff0c;导致p-n结之间的耗尽层变得比最快的硅二极管窄约1000倍。 一旦隧道二极管正向偏置&#xff0c;整个p-n结开始发生称为电子流“隧穿”的过程。  在测试隧道二极管的…...

qwen-vl 实现OCR的测试

OCR 技术是数字化时代必不可少的实用工具。以前都依赖专业的公司的专业软件才能完成。成本很高。也正因为如此&#xff0c;我国纸质资料的数字化并不普及。基于大模型的ORC 也许会改变这样的现状。 文本识别&#xff0c;也称为光学字符识别 (OCR)&#xff0c;可以将印刷文本或…...

3.0/Q2,Charls最新文章解读

文章题目&#xff1a;Exploring the association between socioeconomic inequalities in chronic respiratory disease and all-cause mortality in China: findings from the China Health and Retirement Longitudinal Study DOI&#xff1a;10.3389/fpubh.2024.1472074 中文…...

【大模型系列篇】基于Ollama和GraphRAG v2.0.0快速构建知识图谱

GraphRAG是一种结合了知识图谱和大型语言模型的检索增强生成&#xff08;RAG&#xff09;技术。它通过引入图结构化的知识表示和处理方法&#xff0c;显著提升了传统RAG系统的能力&#xff0c;为处理复杂和多样化数据提供了强有力的支持。更多介绍可以跳转《最强检索增强技术Gr…...

Wincc管对象的使用

Wincc管对象的使用 管对象的调用多边形管T形管双T形管管弯头管道大小调整 管对象的调用 打开【图形编辑器】 多边形管 多边形管如下&#xff1a; 一根管子的顶点数是两个&#xff0c;如果修改顶点数&#xff0c;管子就有多少个端点。 修改顶点数为5 此时点击端点然后拖动&#…...

springboot--页面的国际化

今天来实现页面中的国际化 首先&#xff0c;需要创建一个新的spring boot项目&#xff0c;导入前端模板&#xff0c;在我的博客中可以找到&#xff0c;然后将HTML文件放在templates包下&#xff0c;将其他的静态资源放在statics包下&#xff0c;如下图结构 页面的国际化主要在首…...

记 etcd 无法在docker-compose.yml启动后无法映射数据库目录的问题

1、将etcd 单独提取 Dockerfile #镜像 FROM bitnami/etcd:3.5.11 #名称 ENV name"etcd" #重启 ENV restart"always" #运行无权限 ENV ALLOW_NONE_AUTHENTICATION"yes" #端口 EXPOSE 2379 2380 #管理员权限才能创建数据库 USER root # 设置入口点…...

c++关键字new

链接&#xff1a;【C】C中的new关键字用法详解...

数字内容体验的核心价值是什么?

个性化推荐提升满意度 在数字内容体验的构建中&#xff0c;个性化推荐已成为提升用户满意度的核心策略。通过分析用户行为数据、偏好标签及场景特征&#xff0c;系统能够精准匹配内容资源&#xff0c;减少信息过载带来的决策疲劳。例如&#xff0c;基于用户画像的动态推荐算法…...

通过实施最小权限原则(POLP)来保护敏感数据

在处理机密信息时&#xff0c;应始终将确保组织的敏感数据安全放在首位。无论是制定新政策还是参与项目协作&#xff0c;都应采取一切必要预防措施&#xff0c;确保对任何敏感信息进行恰当的访问控制和存储管理。 最小权限原则(POLP)是企业保护客户与员工数据、财务记录、知识…...

VBA即用型代码手册:文档Document

我给VBA下的定义&#xff1a;VBA是个人小型自动化处理的有效工具。可以大大提高自己的劳动效率&#xff0c;而且可以提高数据的准确性。我这里专注VBA,将我多年的经验汇集在VBA系列九套教程中。 作为我的学员要利用我的积木编程思想&#xff0c;积木编程最重要的是积木如何搭建…...

【力扣hot100题】(089)最长有效括号

这题目真是越做越难了。 但其实只是思路很难想到&#xff0c;一旦会了方法就很好做。 但问题就在方法太难想了…… 思路还是只要遍历一遍数组&#xff0c;维护动态规划数组记录截止至目前位置选取该元素的情况下有效括号的最大值。 光是知道这个还不够&#xff0c;看了答案…...

为什么需要「实体识别」以及 RAG如何和实体识别结合用

&#x1f916; 为什么要做「实体识别」&#xff1f; 实体识别&#xff08;Named Entity Recognition, NER&#xff09; 是自然语言处理&#xff08;NLP&#xff09;中的一种基础技术&#xff0c;它的目标是&#xff1a; 从文本中识别出“有意义”的实体信息&#xff0c;如人名…...

初级社会工作者考试精选题库

通过练习题库中的题目&#xff0c;考生能了解考试的题型、难度分布以及命题规律&#xff0c;明确备考的重点和难点&#xff0c;有针对性地复习知识点&#xff0c;避免盲目备考。 精选练习题 1、社会工作者小王在为社区孤寡老人提供服务时&#xff0c;总是把他们当成自己的父母来…...

Transformer 训练:AutoModelForCausalLM,AutoModelForSequenceClassification

Transformer 训练:AutoModelForCausalLM,AutoModelForSequenceClassification 目录 Transformer 训练:AutoModelForCausalLM,AutoModelForSequenceClassification`AutoTokenizer.from_pretrained(model_name, trust_remote_code=True)`功能概述参数解释`AutoModelForSequen…...

图书管理系统(Python)

运行结果&#xff1a; 源代码&#xff1a; # 定义一个图书类 class Book: def __init__(self, title, author, isbn): self.title title self.author author self.isbn isbn def show_info(self): print(f"{self.title},{self.author},{self.isbn}") # 图书列表…...

2022年全国职业院校技能大赛 高职组 “大数据技术与应用” 赛项赛卷(4卷)任务书

2022年全国职业院校技能大赛 高职组 “大数据技术与应用” 赛项赛卷&#xff08;4卷&#xff09;任务书 背景描述&#xff1a;模块A&#xff1a;大数据平台搭建&#xff08;容器环境&#xff09;&#xff08;15分&#xff09;任务一&#xff1a;Hadoop 完全分布式安装配置任务二…...

装系统的一天!镜像系统!

虚拟机可以装系统&#xff0c;我们都知道&#xff0c;但是虚拟机可以装几个系统呢&#xff1f; macOS: 如何在 Windows 电脑上装 macOS 系统&#xff1f;_windows装mac-CSDN博客 Win10: Win10镜像&#xff08;官方正版&#xff09;下载及虚拟机配置&#xff08;保姆级教程…...

Wincc脚本全部不运行

Wincc脚本全部不运行 前言解决办法操作步骤 前言 这里主要是指旧项目移植到Wincc的高版本&#xff0c;移植后界面的一些功能均会失效。&#xff08;例如脚本不执行&#xff0c;项目编辑器不可用等情况&#xff09; 解决办法 Wincc的项目文件中有Dcf文件&#xff0c;Dcf文件包…...

第三节:React 基础篇-React组件通信方案

React 组件通信方案详解及使用场景 以下是 React 组件通信的常用方法及其适用场景&#xff0c;以层级结构呈现&#xff1a; 一、父子组件通信 1. Props 传递 • 实现方式&#xff1a; • 父组件通过 props 向子组件传递数据。 • 子组件通过回调函数 (onEvent) 通知父组件更…...

✨ MOS开关的非线性因素详解 ✨

MOS 开关在模拟电路、开关电源等应用中广泛使用&#xff0c;但其导通特性存在非线性&#xff0c;可能导致信号失真或系统性能下降。以下是主要非线性因素及解决思路&#xff1a; &#x1f527; 1. 导通电阻&#xff08;Ron&#xff09;的非线性 机理&#xff1a; Ron 并非固定值…...

解决vcpkg使用VS2022报错问题

转自个人博客&#xff1a;解决vcpkg使用VS2022报错问题 最近&#xff0c;在把Visual Studio2019完全更新到最新Visual Studio2022后&#xff0c;原使用的vcpkg无法正常安装包&#xff0c;会报如下与Visual Studio 2022相关的错误&#xff1a; error: in triplet x64-windows-m…...

基于支持向量回归(SVR)的空气质量预测

基于支持向量回归&#xff08;SVR&#xff09;的空气质量预测 1.作者介绍2.支持向量回归&#xff08;SVR&#xff09;算法介绍2.1 算法原理2.2 关键概念2.3算法特点2.4与其他回归方法对比 3.基于支持向量回归&#xff08;SVR&#xff09;的空气质量预测实验3.1数据集介绍3.2代码…...