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

事务AOP

事物管理

事务管理是指对一系列数据库操作进行管理,确保这些操作要么全部成功执行,要么在遇到错误时全部回滚,以维护数据的一致性和完整性。在多用户并发操作和大数据处理的现代软件开发领域中,事务管理已成为确保数据一致性和完整性的关键技术之一。

基本概念

  • 定义:事务是由N步数据库操作序列组成的逻辑执行单元,这系列操作要么全执行,要么全放弃执行。
  • 四大特性(ACID):事务需要满足原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)四个基本属性。

Spring事务管理

Spring事务管理是Spring框架提供的一个重要功能,用于确保在应用程序中多个数据库操作能够作为一个整体进行管理,要么所有操作全部成功,要么在出现错误时全部回滚

Spring事务管理通过提供一个统一的编程模型,可以整合各种事务API(如JTA、JDBC、Hibernate等),使得事务管理更加简便和统一。以下是Spring事务管理的详细解析:

Spring事务管理器

  • 事务管理器接口:Spring事务管理器的核心接口是PlatformTransactionManager,它定义了事务管理的基本操作,包括获取事务状态、提交事务和回滚事务等。
  • 具体实现类:针对不同的持久化技术,Spring提供了多个实现类,例如DataSourceTransactionManager用于JDBC事务管理,HibernateTransactionManager用于Hibernate事务管理,以及JpaTransactionManager用于Java Persistence API (JPA)事务管理。

Spring事务传播行为

  • 传播行为定义:事务传播行为定义了事务方法之间的调用关系。例如,当一个标记为@Transactional的方法A调用另一个标记为@Transactional的方法B时,方法B是运行在方法A的事务内部,还是独立运行在自己的事务中,这由传播行为决定。
  • 常见传播行为:Spring支持多种传播行为,包括REQUIRED(支持当前事务,如果没有则创建新事务)、REQUIRES_NEW(无论是否存在事务,都创建新事务并暂停当前事务)、NESTED(如果存在当前事务,则嵌套在其中;否则与REQUIRED类似)等。

Spring事务隔离级别

  • 隔离级别定义:事务隔离级别用于解决多个事务并发执行时可能产生的问题,如脏读、不可重复读和幻读等。
  • 常用隔离级别:Spring支持多种隔离级别,包括DEFAULT(使用底层数据库默认隔离级别)、READ_COMMITTED(提交读,防止脏读,但不能防止不可重复读和幻读)、SERIALIZABLE(串行化,最高隔离级别,防止所有并发问题,但性能开销大)等。

Spring事务注解用法

  • @Transactional注解:该注解用于声明事务管理,可以标注在类或方法上。通过该注解,开发人员可以轻松地开启事务管理,而不必像传统JDBC那样手动管理事务边界。
  • 注解属性@Transactional注解有多个属性,如propagation(指定传播行为)、isolation(指定隔离级别)、readOnly(指定事务是否只读)、timeout(指定事务超时时间)等。

Spring事务回滚规则

  • 遇到运行时异常回滚:Spring默认设置是在遇到运行时异常(RuntimeException)和错误(Error)时回滚事务。
  • 遇到检查异常不回滚:如果方法抛出检查异常(Checked Exception),事务将不会回滚。如果需要在这些情况下回滚,可以通过在@Transactional注解中设置rollbackFor属性来指定异常类型。

Spring事务模板

  • 编程式事务管理:除了声明式事务管理,Spring还支持编程式事务管理。这允许通过代码更灵活地控制事务的开始和结束。
  • 使用事务模板TransactionTemplate是Spring提供的一个工具类,用于编程式事务管理。通过这个模板,可以使用execute方法执行具有事务保护的操作。

 代码示例:

启动类加注释@EnableTransactionManagement

@SpringBootApplication
@EnableTransactionManagement //开启注解方式的事务管理
@Slf4j
@EnableCaching//开启spring cache 操作redis
public class Demo {public static void main(String[] args) {SpringApplication.run(SkyApplication.class, args);log.info("server started");}
}
import org.springframework.transaction.annotation.Transactional;
import org.springframework.stereotype.Service;@Service
public class UserService {private final UserRepository userRepository;public UserService(UserRepository userRepository) {this.userRepository = userRepository;}@Transactionalpublic void createUser(String name, String email) {// 创建用户对象User user = new User();user.setName(name);user.setEmail(email);// 保存用户到数据库userRepository.save(user);// 模拟异常,触发事务回滚if (email == null || email.isEmpty()) {throw new IllegalArgumentException("Email cannot be empty");}}
}

在这个示例中,我们定义了一个UserService类,其中包含一个createUser方法用于创建用户。该方法使用@Transactional注解标记为事务方法,表示该方法需要在一个事务中执行。在方法内部,我们首先创建一个User对象并设置其属性,然后调用userRepository.save()方法将用户保存到数据库中。最后,我们模拟了一个异常情况,当传入的电子邮件为空时抛出IllegalArgumentException异常,这将导致事务回滚。

需要注意的是,@Transactional注解可以应用于类或方法级别。在上述示例中,我们将其应用于方法级别,这意味着只有该方法内的代码会在一个事务中执行。如果将其应用于类级别,则该类中的所有方法都将在一个事务中执行。

AOP

AOP(Aspect Oriented Programming,面向切面编程)是一种编程范式,通过对程序的横切关注点进行模块化,强化程序的可重用性和开发效率。下面将细致解析AOP的概念、原理、应用场景以及在Spring框架中的具体实现:

AOP的概念

  • 定义:AOP是面向对象编程(OOP)的延续,旨在将散落在系统各个部分的交叉业务逻辑(如日志记录、事务管理等)封装起来,从而将应用中的业务逻辑与系统服务(如事务管理)分离。
  • 切面(Aspect):切面是AOP的核心,它将横切关注点如日志、事务等通用功能模块化。
  • 连接点(Joint point)和切点(Pointcut):连接点指程序中明确定义的点,如方法调用或异常处理;切点则是一组连接点,通过逻辑关系或正则表达式集中,定义增强(Advice)何时何地发生。
  • 增强(Advice):增强定义了切点处要执行的操作,可以在切点之前、之后或代替原操作执行。

AOP的原理

  • 代理模式:AOP基于代理模式,动态或静态地创建一个对象的代理,代理对象包含了原对象的核心业务逻辑以及横切关注点的增强逻辑。
  • 织入(Weaving):织入是将切面与目标对象结合的过程,可以在编译期、类加载期或运行期完成。例如,Spring AOP通常在运行期通过动态代理实现。
  • 通知(Advice)分类:AOP中的通知可以分为前置通知(Before advice)、后置通知(After returning advice)、环绕通知(Around advice)等,每种通知都有特定执行时机。

AOP的应用场景

  • 日志记录:通过AOP可以统一处理日志记录,无需在每个方法内部手动添加日志代码,提高代码的可维护性。
  • 事务管理:AOP能够自然地处理事务管理,增强方法的安全性和可靠性。在方法执行前后自动开启和提交事务,出现异常时回滚。
  • 权限验证:通过AOP切入权限检查逻辑,确保只有具备相应权限的方法调用才能执行。
  • 性能监测:AOP还可以用于性能监测,通过增强方法记录方法执行时间和异常情况,帮助开发者优化性能。

Spring框架中的AOP

  • Spring AOP的实现:Spring通过动态代理实现AOP,主要支持方法类型的连接点。如果需要对字段访问进行增强,则需要使用AspectJ等工具。
  • 注解和配置:在Spring中,可以通过@Aspect注解定义切面,并通过@Pointcut定义切点,最后使用@Before@After@Around等注解定义具体通知逻辑。
  • Spring AOP的局限:Spring AOP主要是动态代理机制,基于接口的动态代理(JDK动态代理),或者基于类的动态代理(CGLib代理)。对于没有实现接口的类,Spring AOP使用CGLib来实现代理。

AOP快速入门

pom.xml

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId>
</dependency>

切面类

@Component
@Aspect //当前类为切面类
@Slf4j
public class TimeAspect {@Around("execution(* com.aop.service.*.*(..))") public Object recordTime(ProceedingJoinPoint pjp) throws Throwable {//记录方法执行开始时间long begin = System.currentTimeMillis();//执行原始方法Object result = pjp.proceed();//记录方法执行结束时间long end = System.currentTimeMillis();//计算方法执行耗时log.info(pjp.getSignature()+"执行耗时: {}毫秒",end-begin);return result;}
}

通知类型

Spring AOP中共有五种类型的通知,这些通知定义了切面在何时以及如何与目标对象的方法进行交互。以下是这五种通知的详细介绍及其具体应用场景:

前置通知(Before advice)

  • 定义:前置通知在目标方法执行之前运行,可以对方法的输入参数进行检查或修改。
  • 使用场景:常用于权限验证、日志记录等。例如,可以在方法执行前检查用户是否具备相应操作权限。
  • 示例
    @Before("execution(* com.example.service.*.*(..))")
    public void beforeMethod(JoinPoint joinPoint) {System.out.println("前置通知: " + joinPoint.getSignature().getName() + " 方法开始执行");
    }
    

后置返回通知(After returning advice)

  • 定义:后置返回通知在目标方法成功完成并返回结果后执行。
  • 使用场景:适用于记录操作成功的日志、统计方法的执行时间等。
  • 示例
    @AfterReturning(pointcut = "execution(* com.example.service.*.*(..))", returning = "result")
    public void afterReturningAdvice(Object result) {System.out.println("方法执行结束,返回值:" + result);
    }
    

后置异常通知(After throwing advice)

  • 定义:当目标方法抛出异常时,后置异常通知会被执行。
  • 使用场景:用于处理异常情况,如记录错误日志、清理资源等。
  • 示例
    @AfterThrowing(pointcut = "execution(* com.example.service.*.*(..))", throwing = "ex")
    public void afterThrowingAdvice(Exception ex) {System.out.println("方法执行异常,异常信息:" + ex.getMessage());
    }
    

后置最终通知(After (finally) advice)

  • 定义:无论目标方法是正常结束还是抛出异常,后置最终通知都会在方法完成后执行。
  • 使用场景:常用于释放资源、记录方法的退出等。
  • 示例
    @After("execution(* com.example.service.*.*(..))")
    public void afterMethod(JoinPoint joinPoint) {System.out.println("最终通知: " + joinPoint.getSignature().getName() + " 方法结束执行");
    }
    

环绕通知(Around advice)

  • 定义:环绕通知在目标方法执行前后都可以执行自定义行为,并且可以选择是否继续执行目标方法。
  • 使用场景:最强大的通知类型,可以替代其他所有类型的通知,适用于事务管理、性能监控等复杂场景。
  • 示例
    @Around("execution(* com.example.service.*.*(..))")
    public Object aroundMethod(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {System.out.println("环绕通知 - 方法开始执行");Object result = proceedingJoinPoint.proceed();System.out.println("环绕通知 - 方法结束执行");return result;
    }
    

以上是Spring AOP提供的五种通知类型及其详细解释和示例代码。每种通知都有其特定的用途,可以根据具体需求选择合适的通知类型来实现AOP功能。

通知顺序

在Spring AOP中,如果有多个切面类同时作用于一个方法,它们的执行顺序是由切面类的优先级决定的。具体来说,有以下几种方式可以配置切面的执行顺序:

通过实现Ordered接口

  • 切面类可以实现org.springframework.core.Ordered接口,并重写getOrder()方法来指定切面的优先级。数值越小,优先级越高,越先执行。例如:
    @Component
    @Aspect
    public class FirstAspect implements Ordered {public int getOrder() {return 1; // 优先级最高}// 切面逻辑...
    }
    

使用@Order注解

  • 在切面类上添加@org.springframework.core.annotation.Order注解,并指定一个整数值来表示切面的执行顺序。同样,数值越小,优先级越高。例如:
    @Component
    @Aspect
    @Order(2)
    public class SecondAspect {// 切面逻辑...
    }
    

通过配置文件

  • 在Spring配置文件中,可以使用<aop:config>元素,并通过order属性为每个切面指定执行顺序。例如:
    <aop:config><aop:aspect ref="firstAspect" order="1"/><aop:aspect ref="secondAspect" order="2"/><!-- 其他切面配置 -->
    </aop:config>
    

当多个切面类联合作用于同一个方法时,它们的执行顺序遵循以下规则:

  1. 环绕通知(Around Advice)首先执行,因为它可以控制目标方法的执行时机。
  2. 紧接着是前置通知(Before Advice),然后是后置返回通知(After Returning Advice)或后置异常通知(After Throwing Advice)。
  3. 最后执行的是后置最终通知(After (Finally) Advice),它无论目标方法是正常结束还是异常结束都会被执行。

在切面内部,通知按照其类型依次执行,但在多个切面之间,其执行顺序则依据前述的优先级配置。如果未显式指定优先级,则默认按照切面类的名称字母顺序执行,字母越小越靠前。

切入点表达式

切入点表达式是Spring AOP中用于定义通知执行范围的表达式。下面将详细解析切入点表达式的各个组成部分以及如何有效应用它们:

概述

  • 切入点表达式(Pointcut Expression)是Spring AOP实现中非常关键的部分,它定义了哪些方法应该被切面(Aspect)影响。切点表达式可以精确地指定哪些包、类、方法以及它们的参数会被应用通知(Advice)。

类型

  • execution: 匹配方法执行点,是最常用和最复杂的切点表达式。例如,execution(* com.xyz.service.AccountService.*(..)) 表示所有com.xyz.service.AccountService接口或类中的方法都会被匹配。
  • within: 限定某个类型内部的方法。如within(com.xyz.service.*)将会匹配com.xyz.service包下所有类的方法。
  • this: 当代理对象可以被强制转型为给定的类型时,满足切点。例如this(com.xyz.service.AccountService)会拦截所有AccountService类型的Bean方法。
  • target: 当被代理的对象可以被强制转型为给定的类型时,满足切点。例如target(com.xyz.service.AccountDAO)会拦截所有AccountDAO类型的Bean方法。
  • args: 根据方法参数的类型来匹配切点。如args(java.lang.String)将会匹配所有第一个参数为String类型的方法。
  • @annotation: 当存在特定注解时匹配切点。例如@annotation(org.springframework.web.bind.annotation.RequestMapping)会匹配所有使用@RequestMapping注解的方法。

组合

  • 在定义切面时,可以使用逻辑运算符如&&||!来组合多个切点表达式,以满足复杂业务场景的需求。例如execution(* *(..)) && this(com.xyz.service.AccountService)仅匹配AccountService接口或类中的所有方法。

语法细节

  • modifier: 可选,用于匹配方法的访问修饰符(如public、protected等)。
  • ret-type: 必选,用于匹配方法的返回类型。使用*表示任意类型。
  • declaring-type: 可选,用于匹配类的全路径类型。使用*表示任意类型,使用..表示当前包及其子包中的类。
  • name-pattern: 必选,用于匹配方法名称。使用*作为通配符。
  • param-pattern: 必选,用于匹配方法参数。()表示无参数,(..)表示有任意数量参数,(*)表示有一个任意类型的参数。

公共配置

  • 可以在任意类中定义一个公共方法,并使用@Pointcut注解来指定表达式。例如,在一个专门配置切点的类中定义公共切点方法,并在切面类中引用这些切点方法。v

execution

在Spring AOP中,execution切入点表达式是用于定义哪些方法应该被切面(Aspect)影响的表达式。下面将详细解析execution表达式的各个组成部分,并给出具体的应用示例:

概述

  • execution表达式是Spring AOP中最常用且最复杂的切入点表达式,它允许开发者精确地匹配方法执行的连接点(Join point)。开发者可以通过该表达式指定包括修饰符、返回类型、类名、方法名和参数类型等多个元素来过滤需要拦截的方法。

语法格式

  • execution表达式的基础语法结构为:execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern)throws-pattern?)。其中,返回类型模式(ret-type-pattern)、方法名模式(name-pattern)和参数模式(param-pattern)是必须的部分,而其他部分如修饰符模式(modifiers-pattern)和异常模式(throws-pattern)是可选的。
  • 例如,execution(* com.xyz.service.AccountService.*(..)) 表示匹配com.xyz.service.AccountService接口或类中的所有方法。

关键元素详解

  • modifiers-pattern: 可选,匹配方法的访问修饰符,如public、private等。
  • ret-type-pattern: 必选,指定方法的返回类型,使用*表示任意类型。
  • declaring-type-pattern: 可选,指定类的全路径类型或包路径。使用*表示任意类型,使用..表示当前包及其子包中的类。
  • name-pattern: 必选,指定方法名称,使用*作为通配符。
  • param-pattern: 必选,指定方法参数的类型,()表示无参数,(..)表示有任意数量参数,(*)表示有一个任意类型的参数。

具体示例

  • execution(* *(..)): 匹配所有返回任意类型且接受任意数量参数的方法。
  • execution(public * *(..)): 仅匹配所有public方法。
  • execution(* com.taotao.Waiter.*(..)): 匹配com.taotao.Waiter接口中的所有方法。
  • execution(* com.taotao.Waiter+.*(..)): 匹配com.taotao.Waiter接口及其所有实现类中的方法。
  • execution(* com.taotao..*(..)): 匹配com.taotao包及其子孙包下所有类的所有方法。

高级组合

  • 使用逻辑运算符如&&||!可以组合多个切点表达式。例如,execution(* *(..)) && this(com.xyz.service.AccountService)仅匹配AccountService接口或类中的所有方法。
  • 可以在@Pointcut注解中使用这些组合表达式来定义公共切点方法,并在切面类中引用这些切点方法。

注意事项

  • 在使用execution表达式时,确保返回类型、方法名和参数模式正确无误,否则可能导致预期外的拦截行为。
  • 尽量避免使用过于宽泛的匹配模式,以免影响系统性能。合理规划切点表达式可以提高AOP的效率与准确性。

@annotation

@annotation 切入点表达式是Spring AOP中用于匹配带有特定注解的方法的表达式。下面将详细解析@annotation表达式的使用方法以及如何有效应用它们:

概述

  • @annotation表达式允许开发者在切面中匹配使用特定注解的方法。这种类型的切入点表达式非常适用于当开发者想要对标记了特定注解的方法应用特定的切面逻辑时。

语法格式

  • @annotation(annotationName):其中annotationName是需要匹配的注解名称。例如,@Before("@annotation(com.xyz.MyAnnotation)")表示在方法上使用com.xyz.MyAnnotation注解的所有方法都会被这个前置通知拦截。

关键元素详解

  • 该表达式会匹配使用了指定注解的方法。它不会匹配接口方法上的注解,因为Spring AOP只支持对Spring Bean的方法进行切入。
  • 开发者可以在通知方法的参数列表中直接引用这些注解类型,从而在通知方法内部方便地访问这些注解的属性和方法。

具体示例

  • 假设有一个自定义注解MethodLog,可以使用@Before("@annotation(methodLog)")来拦截所有使用MethodLog注解的方法,并在通知方法中处理这个注解及其属性。
  • 如要在环绕通知中使用@annotation,可以这样写:@Around("@annotation(methodLog)"),则methodLog参数可以直接在通知方法中使用。

高级组合

  • 开发者可以使用逻辑运算符如&&||!来组合多个切点表达式,以实现更复杂的匹配逻辑。例如,@Before("execution(* *(..)) && @annotation(com.xyz.MyAnnotation)")表示拦截所有方法,并附加特定注解的处理逻辑。

注意事项

  • 在使用@annotation表达式时,确保提供正确的注解全路径名,并且只在方法上使用该注解,而不是在类的其他地方使用。
  • 合理规划切点表达式可以提高AOP的效率与准确性,避免因过于宽泛的匹配模式而影响系统性能。

 案例:

案例背景

假设我们有一个需求,希望记录所有处理时间超过指定阈值的方法调用。为了实现这个功能,我们可以创建一个自定义注解TimeThreshold,并用它来标记那些需要被监控的方法。

步骤一:创建自定义注解

首先,我们需要定义一个自定义注解TimeThreshold,该注解可以包含一个表示时间阈值的属性:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target(ElementType.METHOD) // 注解应用于方法
@Retention(RetentionPolicy.RUNTIME) // 注解在运行时有效
public @interface TimeThreshold {long value() default 1000; // 默认阈值为1000毫秒
}

步骤二:创建切面类

接下来,我们创建一个切面类MethodMonitorAspect,在这个切面中,我们会使用@Before@Around通知来拦截带有TimeThreshold注解的方法:

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;@Aspect
@Component
public class MethodMonitorAspect {// 前置通知,用于记录方法开始时间@Before("@annotation(timeThreshold)")public void logStartTime(TimeThreshold timeThreshold) {System.out.println("Method " + timeThreshold + " started");}// 环绕通知,用于测量方法和记录超出阈值的方法@Around("@annotation(timeThreshold)")public Object monitorMethodExecutionTime(ProceedingJoinPoint joinPoint, TimeThreshold timeThreshold) throws Throwable {long start = System.currentTimeMillis();Object result = joinPoint.proceed(); // 执行目标方法long elapsed = System.currentTimeMillis() - start;if (elapsed > timeThreshold.value()) {System.out.println("Warning: Method " + joinPoint.getSignature() + " exceeded time threshold of " + timeThreshold.value() + " ms");} else {System.out.println("Method " + joinPoint.getSignature() + " executed within time threshold");}return result;}
}

步骤三:应用注解

现在,我们可以在任何需要被监控的方法上应用TimeThreshold注解:

import com.example.demo.aop.annotation.TimeThreshold;
import org.springframework.stereotype.Service;@Service
public class MyService {@TimeThreshold(2000) // 设置时间阈值为2000毫秒public void slowMethod() {// 模拟慢方法try {Thread.sleep(2500);} catch (InterruptedException e) {e.printStackTrace();}}public void fastMethod() {// 模拟快方法try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}}
}

相关文章:

事务AOP

事物管理 事务管理是指对一系列数据库操作进行管理&#xff0c;确保这些操作要么全部成功执行&#xff0c;要么在遇到错误时全部回滚&#xff0c;以维护数据的一致性和完整性。在多用户并发操作和大数据处理的现代软件开发领域中&#xff0c;事务管理已成为确保数据一致性和完…...

RAM和ROM

1&#xff0c;RAM和ROM区别 RAM和ROM都是由来存储的&#xff0c;比如CPU缓存&#xff0c;电脑和手机内存等属于RAM,而固态硬盘&#xff0c;U盘&#xff0c;手机的128G,256G存储空间等都属于ROM。他们的最主要区别是RAM在断电后存储数据就没有了&#xff0c;而ROM在断电后存储数…...

聊聊系统架构之负载均衡优化实践

一、写在前面 最近在进行线上监控检查时&#xff0c;我遇到了两个超出预期的案例。首先&#xff0c;网关层的监控数据与应用实际监控数据存在不一致性&#xff0c;尤其是max有较大的差异&#xff0c;详见如下图。其次在某个应用中&#xff0c;通过httpclient请求某域名时发现只…...

代码规范性思考

表命名和设计 业务模块前缀&#xff1b;下划线分隔&#xff0c;体现业务含义&#xff1b;数据库字符集、字段名、类型、长度、默认值&#xff1b;一对一、一对多、多对多建表&#xff1b;注释清晰&#xff1b;良好的索引&#xff1b; 接口文档 swagger增强工具swagger-boots…...

TestProject Python SDK入门

2024软件测试面试刷题&#xff0c;这个小程序&#xff08;永久刷题&#xff09;&#xff0c;靠它快速找到工作了&#xff01;&#xff08;刷题APP的天花板&#xff09;-CSDN博客跳槽涨薪的朋友们有福了&#xff0c;今天给大家推荐一个软件测试面试的刷题小程序。​编辑https://…...

服务器数据恢复—EMC Isilon存储中被误删的虚拟机数据恢复案例

服务器存储数据恢复环境&#xff1a; EMC Isilon S200集群存储&#xff0c;共三个节点&#xff0c;每节点配置12块SATA硬盘。 服务器存储故障&#xff1a; 工作人员误操作删除虚拟机&#xff0c;虚拟机中数据包括数据库、MP4、AS、TS类型的视频文件等。需要恢复数据的虚拟机通…...

华为安全Security认证,你了解多少?

华为安全Security 认证包含HCIA-Security, HCIP-Security,HCIE-Security。HCIA-Security 掌握中小型网络信息安全基础知识与相关技术&#xff08;华为防火墙技术、加解密技术、PKI 证书体系等&#xff09;&#xff0c;具备搭建小型企业信息安全网络的能力&#xff0c;实现中小企…...

自动驾驶规划-RTT* 算法 【免费获取Matlab代码】

目录 1.算法原理3.结果展示4.参考文献5.代码获取 1.算法原理 RRT(Rapidly-Exploring Random Trees) 快速随机扩展树&#xff0c;是一种单一查询路径规划算法。RRT 将根节点作为搜索的起点&#xff0c;然后通过随机撒点采样增加叶子节点的方式&#xff0c;生成一个随机扩展树&a…...

shell编程中的运算符的讲解

在Linux操作系统中也可以使用expr来进行一些数值的运算&#xff0c;expr接受表达式作为参数&#xff0c;并打印计算结果。 对于某些复杂的表达式或早期不支持内嵌算术表达式的Shell环境&#xff0c;expr 仍然是一个可行的选择。 如上图所示&#xff0c;是使用变量sum来承接加和…...

yudao-ui-admin-vue3 nginx配置

本文记录一个yudao-ui-admin-vue3 nginx配置信息 一、安装依赖 npm install 二、编译打包 npm run build:prod三、修改.env.prod文件 # 请求路径 VITE_BASE_URL=http://IP地址/admin-api四、 nginx配置 server {listen 80;server_name localhost...

vue3第四十节(pinia的用法注意事项解构store)

pinia 主要包括以下五部分&#xff0c;经常用到的是 store、state、getters、actions 以下使用说明&#xff0c;注意事项&#xff0c;仅限于 vue3 setup 语法糖中使用&#xff0c;若使用选项式 API 请直接查看官方文档&#xff1a; 一、前言&#xff1a; pinia 是为了探索 vu…...

PostgreSQL源码分析——索引扫描

这里&#xff0c;我们分析一下索引扫描的过程&#xff0c;以最简单的select * from t1 where a 100;语句为例&#xff0c;分析一下查询的过程。 postgrespostgres# \d t1;Table "public.t1"Column | Type | Collation | Nullable | Default ------------------…...

零基础入门学用Arduino 第四部分(一)

重要的内容写在前面&#xff1a; 该系列是以up主太极创客的零基础入门学用Arduino教程为基础制作的学习笔记。个人把这个教程学完之后&#xff0c;整体感觉是很好的&#xff0c;如果有条件的可以先学习一些相关课程&#xff0c;学起来会更加轻松&#xff0c;相关课程有数字电路…...

x-anylabelimg如何标识人脸

软件地址&#xff0c;下载CPU版本就好 https://github.com/CVHub520/X-AnyLabeling/releases/tag/v2.0.0 一、打开软件选择的一个按钮&#xff0c;选择文件夹 二、选择模型运行 未下载的模型需要安全上网下载 选用Yolov6Lite_l-Face MeiTuan生成的文件格式&#xff0c;略作调…...

Element-ui中Table表格无法显示

Element-ui中Table表格无法显示 在使用过程中发现样式正常显示但是table就是不显示&#xff0c;研究了一段时间后&#xff0c;发现问题是项目结构的问题 当你创建vue和安装el的时候&#xff0c;一定要注意进入到正确的项目文件夹&#xff0c;如果在外面也出现一个package.jso…...

电信网关配置管理系统 del_file.php 前台RCE漏洞复现

0x01 产品简介 中国电信集团有限公司(英文名称“China Telecom”、简称“中国电信”)成立于2000年9月,是中国特大型国有通信企业、上海世博会全球合作伙伴。电信网关配置管理系统是一个用于管理和配置电信网络中网关设备的软件系统。它可以帮助网络管理员实现对网关设备的远…...

游戏心理学Day18

游戏玩家心理 在游戏世界中&#xff0c;设计师的工作总是围绕尽可能留住玩家要展开。在游戏创作时&#xff0c;设计师会假设目标诉讼的特点并激励迎合他们的需求&#xff0c;如果这种假设是经过实际调研之后做出的&#xff0c;那么就会比较接近实际情况而。如果这种假设是设计…...

发文章不违规的5种解决方案,非常适用,记得收藏!

之前以为使用AI写出来的文章&#xff0c;只要检测通过就不会违规&#xff0c;结果却还是让我有些失望。最近测试几款AI工具&#xff0c;测试结果都还是会存在违规情况&#xff0c;无法全文发布。 AI是听从人的指令&#xff0c;只能说是如何下指令&#xff0c;这个非常重要。至…...

【ARMv8/ARMv9 硬件加速系列 2.2 -- ARM NEON 的加减乘除(左移右移)运算】

文章目录 NEON 加减乘除NEON 加减乘除 下面代码是使用ARMv8汇编语言对向量寄存器v0-v31执行加、减、乘以及左移和右移操作的示例。 ARMv8的SIMD指令集允许对向量寄存器中的多个数据进行并行操作。v0和v1加载数据,对它们进行加、减和乘,左移和右移操作。最后,我们会将结果存储…...

[2024-06]-[大模型]-[Ollama]- WebUI

主要涉及要部署的前端webui是来源于:https://github.com/open-webui/open-webui 正常就使用: docker run -d -p 3000:8080 --add-host=host.docker.internal:host-gateway -v open-webui:/app/backend/data --name open-webui --restart always ghcr.io/open-webui/open-web…...

AI智能盒子助力中钢天源设备工厂升级安全防护

中钢集团安徽天源科技股份有限公司成立于2002年3月27日,是中央企业中国中钢股份有限公司控股的上市公司&#xff0c;主导产品为永磁铁氧体器件、钕铁硼器件、四氧化三锰、锶铁氧体预烧料及各类磁选机等。 在中钢天源智能化升级过程中&#xff0c;采用并定制开发一系列厂区安全…...

RNN的变种们:GRULSTM双向RNN

上篇笔记记录到RNN的一个缺点&#xff1a;训练时会出现梯度消失&#xff0c;解决的办法是找到一个更优的计算单元。这里也有GRU和LSTM。 GRU&#xff08;Gated Recurrent Unit&#xff09;门控训练网络 什么是门控机制&#xff1f;就是对当前的输入进行一个筛选。门打开&…...

Linux网络-HttpServer的实现

文章目录 前言一、请求报文的解析URL的解析 二、响应报文的发送Content-LenthConten-TypeCookie和Set-CookieCookie的风险 三、尝试发送一个HTML网页404网页Location 重定向 四、浏览器的多次请求行为总结 前言 之前我们简单理解了一下Http协议&#xff0c;本章我们将在LInux下…...

GPT-4o的综合评估与前景展望

如何评价GPT-4o? GPT-4o作为OpenAI推出的最新一代大型语言模型&#xff0c;其性能、功能和应用前景都备受关注。以下是对GPT-4o的综合评估与前景展望&#xff1a; 一、技术性能评估 响应速度&#xff1a;GPT-4o在响应速度上有了显著提升&#xff0c;能够在极短的时间内对输入…...

私人云盘(自动云同步)

一、项目简介 模仿小米的云服务&#xff0c;实现一个通过TCP实现的私人云盘&#xff0c;因为能力有限&#xff0c;所以只实现自动云同步这一个功能&#xff0c;具体可以分为三个小功能&#xff0c;即保持云端和终端数据一致、实现文件的上传与下载以及手动同步 二、涉及到的知…...

【CMake】Linux 下权限丢失与软链接失效问题

【CMake】Linux 下权限丢失与软链接失效问题 文章目录 【CMake】Linux 下权限丢失与软链接失效问题问题概述解决方法1 - 安装目录2 - 安装文件3 - 手动指定 使用 Linux 下原生命令行注意事项参考链接 问题概述 一般使用 CMake 安装&#xff0c;在 Windows 平台不会出问题&…...

内部类介绍

内部类&#xff08;Inner Class&#xff09;是在另一个类的内部定义的类。它可以访问外部类的所有成员&#xff0c;包括私有成员。内部类有两种主要形式&#xff1a;局部内部类&#xff08;定义在方法内部&#xff09;和成员内部类&#xff08;定义在类的内部&#xff0c;但不在…...

【CVPR2021】LoFTR:基于Transformers的无探测器的局部特征匹配方法

LoFTR&#xff1a;基于Transformers的局部检测器 0. 摘要 我们提出了一种新的局部图像特征匹配方法。我们建议先在粗略级别建立像素级密集匹配&#xff0c;然后再在精细级别细化良好匹配&#xff0c;而不是按顺序进行图像特征检测、描述和匹配。与使用成本体积搜索对应关系的密…...

总结一下 C# 如何自定义特性 Attribute 并进行应用

前言 Attribute&#xff08;特性&#xff09;是一种用于为程序元素&#xff08;如类、方法、属性等&#xff09;提供元数据信息的方法。 特性是一种声明式的信息&#xff0c;附加到程序元素上&#xff0c;提供额外的数据用于描述和控制这些元素的行为。 在编译和运行时&…...

三种暴露方法和引入方式

1.分别暴露 export ...export...用于按需导出一个或多个模块&#xff0c;在导入时需要使用花括号指定导入的模块名称&#xff0c;例如import { a, b } from module module.js中 export let a 1 export function b(){console.log(hello,vue) } 2.统一暴露 export { ...}用于统…...

肥城 网站建设/关键词排名网站

经过一个多月的整合&#xff0c;作者的第一本电子书&#xff0c;程序人生上线了&#xff0c;读者可通过微信公众号&#xff1a;小小李童鞋回复关键字 程序人生 获取&#xff1b; 最后感谢各位朋友的支持&#xff1b;...

在那里做网站/企业网址搭建

题目连接 题目大意 给你一个01串&#xff0c;要你用最少的变化次数使得所有的1相邻的距离为k。变化的方式为1->0,0->1.要你求最少的变化次数 题目思路 emm完全没啥思路&#xff0c;看了题解&#xff0c;其实就是你要想这些数字1都是modk等于一个定值&#xff0c;那么…...

网站怎么会k/郑州网络营销公司哪个好

暗恋橘生淮南越播越热&#xff0c;小编觉得洛枳选角很好&#xff0c;骄傲又小心翼翼。但是盛淮南真的不帅&#xff0c;有时候还有点渣男气质&#xff0c;不够有魅力。配音也很尬。不过还是有很多名场面。大学生活挺写实的。不过小编最喜欢的还是张明瑞这个角色。那么张明瑞喜欢…...

企业邮箱哪家更好用/seo排名点击首页

场景&#xff1a;一个panel中动态加载多个自定义控件item&#xff0c;类似QQ聊天窗口 问题&#xff1a;加载panel时界面会卡顿&#xff0c;先显示阴影再显示界面&#xff1b;移动滚动条时item会闪烁 解决方法&#xff1a; panel 添加方法&#xff0c;减少界面闪烁&#xff1a; …...

中英文网站源码php/上海有什么seo公司

集成第三方融云的时候出现了这个错误&#xff0c;主要是之前的依赖过多&#xff0c;有的冲突了&#xff0c;总之就是很无奈&#xff1a; 下面来看看如何处理&#xff1a; 1、在app: build.gradle中添加以下配置 android {defaultConfig {...multiDexEnabled true}dexOptions…...

织梦做网站被告/谷歌seo是什么

首先一个android项目&#xff0c;然后编译和打包&#xff0c;将.java文件编译为.class&#xff0c;.class编译为.dex&#xff0c;将所有文件打包为一个apk&#xff0c;只编译代码&#xff0c;不编译资源。 .apk里面的.arsc是资源的索引&#xff0c;当资源比较多的时候&#xff…...