企业级信息系统开发学习笔记1.5 初探Spring AOP
文章目录
- 零、本讲学习目标
- 一、Spring AOP
- (一)AOP基本含义
- (二)AOP基本作用
- (三)AOP与OOP对比
- (四)AOP使用方式
- (五)AOP基本概念
- 二、提出游吟诗人唱赞歌任务
- (一)采用传统方式实现
- (二)采用传统方式实现的缺点
- 三、采用配置方式使用AOP
- (一)创建本讲所需子包
- (二)创建杀龙任务类
- (三)创建勇敢骑士类
- (四)创建游吟诗人类
- (五)创建Spring配置文件
- 1、切点
- 2、切点表达式
- 3、切点函数
- (六)在pom文件里添加AOP相关依赖
- (七)创建测试类 - TestKnight
- (八)运行测试方法testBraveKnight(),查看结果
- (九)课堂练习
- 1、增加救美任务类与救美骑士类
- 2、在测试类里增加测试方法 - testDamselRescuingKnight()
- 3、运行testDamselRescuingKnight()方法,查看结果
- 四、采用注解方式使用AOP
- (一)创建本讲所需子包
- (二)创建杀龙任务类
- (三)创建勇敢骑士类
- (四)创建游吟诗人切面
- (五)创建Spring配置类
- (六)创建骑士测试类
- (七)运行测试方法testBraveKnight(),查看效果
- (八)课堂练习
- 1、增加救美任务类与救美骑士类
- 2、在测试类里增救美骑士测试方法 - testDamselRescuingKnight()
- 3、运行testDamselRescuingKnight()方法,查看结果
- 四、实现注解式拦截
- (一)拦截的含义
- (二)创建注解接口
- 1、@Target({ElementType.TYPE}) 注解
- 2、 @Retention({RetentionPolicy.Runtime}) 注解
- 3、@Documented注解
- (三)修改勇敢骑士类
- (四)修改游吟诗人切面
- (五)运行测试方法testBraveKnight(),查看效果
- (五)修改救美骑士类,给embarkOnQuest()添加自定义注解Action
- (六)运行测试方法testDamselRescuingKnight(),查看效果
- (七)课堂练习
- 任务:输出骑士完成任务的耗时
零、本讲学习目标
- 理解AOP与OOP的关系
- 掌握采用配置方式使用AOP
- 掌握采用注解方式使用AOP
一、Spring AOP
(一)AOP基本含义
- AOP(Aspect-OrientedProgramming,面向切面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善。OOP引入封装、继承和多态性等概念来建立一种对象层次结构,用以模拟公共行为的一个集合。当我们需要为分散的对象引入公共行为的时候,OOP则显得无能为力。
- OOP允许你定义从上到下的关系,但并不适合定义从左到右的关系。例如日志功能。日志代码往往水平地散布在所有对象层次中,而与它所散布到的对象的核心功能毫无关系。对于其他类型的代码,如安全性、异常处理和透明的持续性也是如此。这种散布在各处的无关的代码被称为横切(cross-cutting)代码,在OOP设计中,它导致了大量代码的重复,而不利于各个模块的重用。
- AOP技术则恰恰相反,它利用一种称为“横切”的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其名为“Aspect”,即方面。所谓“方面”,简单地说,就是将那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。
- AOP代表的是一个横向的关系,如果说“对象”是一个空心的圆柱体,其中封装的是对象的属性和行为;那么面向方面编程的方法,就仿佛一把利刃,将这些空心圆柱体剖开,以获得其内部的消息。而剖开的切面,也就是所谓的“方面”了。然后它又以巧夺天功的妙手将这些剖开的切面复原,不留痕迹。
(二)AOP基本作用
- 软件开发原则:高内聚,低耦合
- Spring的AOP作用在于
解耦。AOP让一组类共享相同的行为(比如事务管理、日志管理、安全管理)。 - OOP(Object-Oriented Programming)只能通过继承类或实现接口来增加代码的耦合度,而且类继承是单根继承(不允许一子多父),阻碍了将更多的行为添加到一组类上,此时AOP可以弥补OOP的不足。
(三)AOP与OOP对比
- AOP(Aspect-Oriented Programming)—— 横向的关系
- OOP(Object-Oriented Programming)—— 纵向的关系

(四)AOP使用方式
- Spring采用配置方式使用AOP
- Spring采用注解方式使用AOP
(五)AOP基本概念
- Aspect(切面):通常是一个类,里面可以定义切入点和通知
- JointPoint(连接点):程序执行过程中明确的点,一般是方法的调用
- Advice(通知):AOP在特定的切入点上执行的增强处理,有before、after、after-returning、after-throwing、around
- Pointcut(切入点):就是带有通知的连接点,在程序中主要体现为书写切入点表达式
- AOP代理:AOP框架创建的对象,代理就是目标对象的加强。Spring中的AOP代理可以使JDK动态代理,也可以是CGLIB代理,前者基于接口,后者基于子类
二、提出游吟诗人唱赞歌任务
- 骑士执行任务前和执行任务后,游吟诗人唱赞歌
(一)采用传统方式实现
-
修改
day04子包的勇敢骑士类

-
修改
day04子包里的救美骑士类

-
执行测试类 - TestKnight

(二)采用传统方式实现的缺点
- 每个骑士类的embarkOnQuest()方法都要修改,耦合度太高,当骑士类数量很大时,这个任务完成起来就十分枯燥繁琐。
下面我们采用AOP方式来实现同样的功能,大家通过对比可以更好地体会采用AOP方式的优越性。
三、采用配置方式使用AOP
(一)创建本讲所需子包
- 在net.hw.spring包里创建lesson05.aop_xml子包

(二)创建杀龙任务类
- 在aop_xml子包里创建杀龙任务类 - SlayDragonQuest

package net.hw.spring.lesson05.aop_xml;import org.springframework.stereotype.Component;/*** 功能:杀龙任务类* 作者:华卫* 日期:2021年03月24日*/
@Component
public class SlayDragonQuest {public void embark() {System.out.println("执行杀龙任务。");}
}
(三)创建勇敢骑士类
- 在aop_xml子包里创建勇敢骑士类 - BraveKnight

package net.hw.spring.lesson05.aop_xml;/*** 功能:勇敢骑士类* 作者:华卫* 日期:2021年03月24日*/import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;@Component("Mike")
public class BraveKnight {@Autowiredprivate SlayDragonQuest slayDragonQuest;public void embarkOnQuest() {slayDragonQuest.embark();}
}
(四)创建游吟诗人类
- 在aop_xml子包里创建游吟诗人类 - Minstrel

package net.hw.spring.lesson05.aop_xml;import org.springframework.stereotype.Component;/*** 功能:游吟诗人类* 作者:华卫* 日期:2021年03月24日*/
@Component
public class Minstrel {public void singBeforeQuest() {System.out.println("啦啦啦,骑士出发了!");}public void singAfterQuest() {System.out.println("真棒啊!骑士完成了任务!");}
}
(五)创建Spring配置文件
- 在resources里创建aop_xml目录,在里面创建spring-config.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"><!--组件扫描--><context:component-scan base-package="net.hw.spring.lesson05.aop_xml"/><!--AOP配置--><aop:config><!--定义切面--><aop:aspect ref="minstrel"><!--定义切点--><aop:pointcut id="embark" expression="execution(* net.hw.spring.lesson05..*.embarkOnQuest(..))"/><!--声明前置通知--><aop:before method="singBeforeQuest" pointcut-ref="embark"/><!--声明后置通知--><aop:after method="singAfterQuest" pointcut-ref="embark"/></aop:aspect></aop:config>
</beans>

1、切点
在使用Spring框架配置AOP时,不管是通过XML配置文件还是注解方式,都需要定义pointcut(切点)。
2、切点表达式
- 拦截类里的指定方法:
"execution(* net.hw.spring.lesson05..*.embarkOnQuest(..))" - 拦截类里的所有方法:
"execution(* net.hw.spring.lesson05..*.*(..))"
3、切点函数
execution()是最常用的切点函数,整个表达式可以分为五个部分。
execution():表达式主体。- 第一个
*号:表示返回类型,*号表示所有的类型。 - 包名:表示需要拦截的包名,后面的两个句点表示当前包和当前包的所有子包,net.hw.spring.lesson05包、子孙包下所有类的方法。
- 第二个
*号:表示类名,*号表示所有的类。 *(..):最后这个星号表示方法名,*号表示所有的方法,后面括弧里面表示方法的参数,两个句点表示任何参数。
(六)在pom文件里添加AOP相关依赖

<!--Spring AOP-->
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>${spring.version}</version>
</dependency>
<!--AspectJ支持-->
<dependency> <groupId>aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.5.4</version>
</dependency>
<dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.6</version> <scope>runtime</scope>
</dependency>
- 注意:添加新的依赖之后,记得更新

(七)创建测试类 - TestKnight
- 在test/java里创建net.hw.spring.lesson05.aop_xml包,在包里创建TestKnight

package net.hw.spring.lesson05.aop_xml;import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;/*** 功能:测试骑士类* 作者:华卫* 日期:2021年03月24日*/
public class TestKnight {private ClassPathXmlApplicationContext context; // 基于类路径XML配置文件的应用容器@Beforepublic void init() {// 基于Spring配置文件创建应用容器context = new ClassPathXmlApplicationContext("aop_xml/spring-config.xml");}@Testpublic void testBraveKnight() {// 根据名称从应用容器中获取勇敢骑士对象BraveKnight braveKnight = (BraveKnight) context.getBean("Mike");// 勇敢骑士执行任务braveKnight.embarkOnQuest();}@Afterpublic void destroy() {// 关闭应用容器context.close();}
}
(八)运行测试方法testBraveKnight(),查看结果

(九)课堂练习
1、增加救美任务类与救美骑士类

2、在测试类里增加测试方法 - testDamselRescuingKnight()

3、运行testDamselRescuingKnight()方法,查看结果

四、采用注解方式使用AOP
(一)创建本讲所需子包
- 在net.hw.spring包里创建lesson05.aop_annotation子包

(二)创建杀龙任务类
- 在aop_annotation子包里创建杀龙任务类 - SlayDragonQuest

package net.hw.spring.lesson05.aop_annotation;import org.springframework.stereotype.Component;/*** 功能:杀龙任务类* 作者:华卫* 日期:2021年03月29日*/
@Component
public class SlayDragonQuest {public void embark() {System.out.println("执行杀龙任务。");}
}
(三)创建勇敢骑士类
- 在aop_annotation子包里创建勇敢骑士类 - BraveKnight

package net.hw.spring.lesson05.aop_annotation;/*** 功能:勇敢骑士类* 作者:华卫* 日期:2021年03月29日*/import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;@Component("Mike")
public class BraveKnight {@Autowiredprivate SlayDragonQuest slayDragonQuest;public void embarkOnQuest() {slayDragonQuest.embark();}
}
(四)创建游吟诗人切面
- 在aop_annotation子包里创建游吟诗人切面 - MinstrelAspect


package net.hw.spring.lesson05.aop_annotation;import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;/*** 功能:游吟诗人切面* 作者:华卫* 日期:2021年03月29日*/
@Aspect // 声明为切面
@Component // 交给Spring容器管理
public class MinstrelAspect {// 注解声明切点@Pointcut("execution(* net.hw.spring.lesson05..*.embarkOnQuest(..))")public void embark() {}// 注解声明前置通知@Before("embark()")public void singBeforeQuest(JoinPoint joinPoint) {System.out.println("啦啦啦,骑士出发了!");}// 注解声明后置通知@After("embark()")public void singAfterQuest(JoinPoint joinPoint) {System.out.println("真棒啊!骑士完成了任务!");}
}
(五)创建Spring配置类
- 在aop_annotation子包里创建Spring配置类 - AopConfig

package net.hw.spring.lesson05.aop_annotation;import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;/*** 功能:AOP配置类* 作者:华卫* 日期:2021年03月29日*/
@Configuration // 标明Spring配置类
@ComponentScan("net.hw.spring.lesson05.aop_annotation") // 组件扫描
@EnableAspectJAutoProxy // 开启Spring对AspectJ的支持
public class AopConfig {
}
(六)创建骑士测试类
- 在test/java/aop_annotation子包里创建测试类 - TestKnight

package net.hw.spring.lesson05.aop_annotation;import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;/*** 功能:测试骑士类* 作者:华卫* 日期:2021年03月29日*/
public class TestKnight {private AnnotationConfigApplicationContext context; // 基于注解配置类的应用容器@Beforepublic void init() {// 基于注解配置类创建应用容器context = new AnnotationConfigApplicationContext(AopConfig.class);}@Testpublic void testBraveKnight() {// 根据名称从应用容器里获取勇敢骑士对象BraveKnight knight = (BraveKnight) context.getBean("Mike");// 勇敢骑士执行任务knight.embarkOnQuest();}@Afterpublic void destroy() {// 关闭应用容器context.close();}
}
(七)运行测试方法testBraveKnight(),查看效果

(八)课堂练习
1、增加救美任务类与救美骑士类

2、在测试类里增救美骑士测试方法 - testDamselRescuingKnight()

3、运行testDamselRescuingKnight()方法,查看结果

四、实现注解式拦截
(一)拦截的含义
在某个方法被访问之前进行拦截,然后在方法执行之前或之后加入某些操作,其实就是AOP的一种实现策略。Spring提供拦截器(Interceptor),它通过动态拦截Action调用的对象,允许开发者定义在一个action执行的前后执行的代码,也可以在一个action执行前阻止其执行。同时也是提供了一种可以提取action中可重用的部分的方式。本案例,我们不用拦截器,学习注解式拦截。
(二)创建注解接口
- 在aop_annotation子包里创建注解接口 - Action


package net.hw.spring.lesson05.aop_annotation;import java.lang.annotation.*;/*** 功能:动作注解接口* 作者:华卫* 日期:2021年03月29日*/
@Target(ElementType.METHOD) // 拦截目标 - 方法
@Retention(RetentionPolicy.RUNTIME) // 保留策略 - 运行时
@Documented // 注解文档化
public @interface Action {String name();
}
1、@Target({ElementType.TYPE}) 注解
- ElementType 这个枚举类型的常量提供了一个简单的分类:注解可能出现在Java程序中的语法位置(这些常量与元注解类型(@Target)一起指定在何处写入注解的合法位置)
2、 @Retention({RetentionPolicy.Runtime}) 注解
- RetentionPolicy这个枚举类型的常量描述保留注解的各种策略,它们与元注解(@Retention)一起指定注释要保留多长时间
3、@Documented注解
- Documented注解表明这个注解是由 javadoc记录的,在默认情况下也有类似的记录工具。 如果一个类型声明被注解了文档化,它的注解成为公共API的一部分。
(三)修改勇敢骑士类
- 给embarkOnQuest()添加自定义注解Action,并设置其name属性

package net.hw.spring.lesson05.aop_annotation;/*** 功能:勇敢骑士类* 作者:华卫* 日期:2021年03月29日*/import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;@Component("Mike")
public class BraveKnight {@Autowiredprivate SlayDragonQuest slayDragonQuest;@Action(name = "动作拦截器")public void embarkOnQuest() {slayDragonQuest.embark();}
}
(四)修改游吟诗人切面

package net.hw.spring.lesson05.aop_annotation;import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;import java.lang.reflect.Method;/*** 功能:游吟诗人切面* 作者:华卫* 日期:2021年03月29日*/
@Aspect // 声明为切面
@Component // 交给Spring容器管理
public class MinstrelAspect {// 注解声明切点@Pointcut("@annotation(net.hw.spring.lesson05.aop_annotation.Action)")public void embark() {}// 注解声明前置通知@Before("embark()")public void singBeforeQuest(JoinPoint joinPoint) {// 获取方法签名MethodSignature signature = (MethodSignature) joinPoint.getSignature();// 获取被拦截的方法Method method = signature.getMethod();// 获取注解式拦截Action action = method.getAnnotation(Action.class);// 提示用户被拦截了System.out.println("[" + action.name() + "]拦截了[" + method.getName() + "]:拦截前!");System.out.println("啦啦啦,骑士出发了!");}// 注解声明后置通知@After("embark()")public void singAfterQuest(JoinPoint joinPoint) {// 获取方法签名MethodSignature signature = (MethodSignature) joinPoint.getSignature();// 获取被拦截的方法Method method = signature.getMethod();// 获取注解式拦截Action action = method.getAnnotation(Action.class);// 提示用户被拦截了System.out.println("[" + action.name() + "]拦截了[" + method.getName() + "]:拦截后!");System.out.println("真棒啊!骑士完成了任务!");}
}
(五)运行测试方法testBraveKnight(),查看效果

(五)修改救美骑士类,给embarkOnQuest()添加自定义注解Action

(六)运行测试方法testDamselRescuingKnight(),查看效果

(七)课堂练习
任务:输出骑士完成任务的耗时
-
创建耗时切面类 - ElapseAspect

-
运行测试方法testBraveKnight(),查看效果

-
运行测试方法testDamselRescuingKnight(),查看效果

-
只让耗时切面起作用,查看运行结果

相关文章:
企业级信息系统开发学习笔记1.5 初探Spring AOP
文章目录零、本讲学习目标一、Spring AOP(一)AOP基本含义(二)AOP基本作用(三)AOP与OOP对比(四)AOP使用方式(五)AOP基本概念二、提出游吟诗人唱赞歌任务&#…...
Mysql数据库主主从设置
注意:在同一台服务器上部署主从或主主之类的时候,数据库data下有一个auto.cnf里的uuid不能重复。 原则:做同步之前要保证两个数据库数据一致. 锁表操作: FLUSH TABLES WITH READ LOCK; 注:没有锁定主服务器…...
监管持续,医疗卫生机构如何守好“涉疫”数据安全?
肆虐三年的新冠疫情,影响着全球经济发展、社会正常运行,也成为网络攻击、勒索软件攻击快速增长的温床,“滋生”了一系列网络、数据安全问题,受到各界关注。最近,上线运行三年的 “粤康码”发布公告、官宣部分服务下线&…...
STM32开发(13)----获取唯一设备标识符UID
获取唯一设备标识符UID前言一、什么事UID二、实验过程1.CubeMx配置2.代码实现3.实验结果总结前言 这一章节介绍如何获取STM32芯片中的唯一的ID号的两种方法。 一、什么事UID 在许多项目中,识别设备是必要的。从简单的设备描述到更复杂的设备,如 USB 串…...
华为OD机试 - 最优调度策略(Python) | 机试题+算法思路+考点+代码解析 【2023】
最优调度策略 题目 在通信系统中有一个常见的问题是对用户进行不同策略的调度 会得到不同系统消耗的性能 假设由 N 个待串行用户,每个用户可以使用 A/B/C 三种不同的调度策略 不同的策略会消耗不同的系统资源 请你根据如下规则进行用户调度 并返回总的消耗资源数 规则是:相…...
前端零基础入门-002-集成开发环境
本篇目标 了解市面上常用的前端集成开发环境(ide)掌握 HBuiberX 的使用:下载安装,新建项目、网页、运行网页。 内容摘要 本篇介绍了市面上流行的几款前端集成开发环境(ide),并介绍了 Hbuilde…...
su和sudo的区别
linux中 su和sudo的区别 su和sudo是两个常用的切换到root超级用户命令。功能上类似,但使用上还是有不少差异。 su命令 su是切换到root用户的命令,主要用法如下: su:不带参数直接输入su将切换到root用户,需要输入root…...
【ChatGPT】使用ChatGPT进行51单片机程序编程体验
背景 最近ChatGPT大火,笔者尝试使用它进行了51单片机编程尝试。ChatGPT是一种由OpenAI训练的大型语言模型,具有强大的自然语言处理能力和生成代码的能力。 使用ChatGPT进行51单片机编程,笔者发现它可以帮助开发人员快速生成符合要求的代码&a…...
Docker之路(1.Docker概述、组成以及特点)
1.docker为什么会出现? 一款产品或者项目来说,一般有三个环境,日常/测试环境、预发环境、正式/线上环境 这么多环境,对其环境的配置是十分麻烦的,每一个机器都要部署环境,有的会有集群Redis、Hadoop等&…...
非对称加密算法在android的应用
前言android 系统安全内容总结 4、非对称加密算法应用 主要特性包括secure boot、AVB、OTA包签名、apk签名、apex、ko签名; 除此外上层应用keystore服务、涉及TEEOS非对称算法的功能安全会用到。属于功能安全本章节暂不描述。 4.1、secboot+avb secboot+avb属于安全启动参照…...
51单片机——定时器中断实验,小白讲解,相互学习
定时器介绍 1,CPU时序的有关知识 震荡周期:为单片机提供定时信号的震荡源的周期(晶振周期或外加震荡周期)。状态周期:2个震荡周期为1个状态周期,用S表示。震荡周期又称S周期或时钟周期。机器周期ÿ…...
什么是循环依赖,spring是如何去解决循环依赖问题的?什么是三级缓存?【spring】
文章目录什么是循环依赖?什么是三级缓存?执行流程什么是循环依赖? 在我们的开发中,会不可避免的遇到Bean之间循环依赖的,所谓循环依赖,就是两个或者两个以上的Bean互相持有对方,这样在程序运行…...
Cron表达式
网上搜一下就有在线生成网站,很方便。 比如:Cron表达式生成器 用途 定时调度任务,比如说服务器、云函数中定时执行脚本函数。 Cron 表达式构成 Cron 表达式是字符串,一般由 6 - 7 个字段构成,空格分隔。每个字段代…...
JavaScript 作用域
作用域是可访问变量的集合。在JavaScript中,能够定义全局作用域或者局部作用域。在 JavaScript 中, 对象和函数同样也是变量。在 JavaScript 中, 作用域为可访问变量,对象,函数的集合。JavaScript 函数作用域: 作用域在函数内修改。JavaScrip…...
Hive内部表与外部表的区别具体说明
目录 1.在/opt/atguigu/目录下,新建两个txt文件 2.在hadoop的web端递归创建一个目录,存储这两个文件 3.查看web端的文件 一、内部表: 1.创建一个内部表,并指定内部表的存储位置 2.查看内部表,内部表中没有数据 …...
Java流程控制
目录 前言 一、用户交互Scanner及其进阶使用 输入的数据为字符串类型 输入的数据为整型或者浮点型 练习 二、顺序结构 三、选择结构 if单选泽结构 if双选择结构 if多选择结构 嵌套的if结构 switch多选择结构 四、循环结构 while循环 Do...while循环 For循环 练习 利用for循环…...
I.MX6ULL_Linux_系统篇(17) uboot分析-启动linux
bootz 启动 Linux 内核 images 全局变量 不管是 bootz 还是 bootm 命令,在启动 Linux 内核的时候都会用到一个重要的全局变量:images, images 在文件 cmd/bootm.c 中有如下定义: images 是 bootm_headers_t 类型的全局变量&…...
C/C++每日一练(20230221)
目录 1. 格雷编码 2. 矩阵问题 3. 搜索旋转排序数组 II 1. 格雷编码 格雷编码是一个二进制数字系统,在该系统中,两个连续的数值仅有一个位数的差异。 给定一个代表编码总位数的非负整数 n,打印其格雷编码序列。即使有多个不同答案&#…...
用Python采集热门城市景点数据并简单制作数据可视化图
前言 嗨喽~大家好呀,这里是魔王呐 ❤ ~! 模块使用: 爬虫部分: requests parsel csv 数据分析部分: pandas pyecharts 如何安装模块: win R 输入 cmd 输入安装命令: pip install 模块名 回车 pycharm里面安装 terminal 输入安装命令…...
论文阅读:pixelNeRF: Neural Radiance Fields from One or Few Images
中文标题:从一或少量图像中构建神经辐射场 提出问题 NeRF效果虽然惊艳,但是其需要大量环绕图像以及长时间的训练。 创新点 与原始的NeRF网络不使用任何图像特征不同,pixelNeRF将与每个像素对齐的空间图像特征作为输入。也可以集合更多输入…...
PHP和Node.js哪个更爽?
先说结论,rust完胜。 php:laravel,swoole,webman,最开始在苏宁的时候写了几年php,当时觉得php真的是世界上最好的语言,因为当初活在舒适圈里,不愿意跳出来,就好比当初活在…...
基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容
基于 UniApp + WebSocket实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...
算法岗面试经验分享-大模型篇
文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer (1)资源 论文&a…...
浪潮交换机配置track检测实现高速公路收费网络主备切换NQA
浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求,本次涉及的主要是收费汇聚交换机的配置,浪潮网络设备在高速项目很少,通…...
RSS 2025|从说明书学习复杂机器人操作任务:NUS邵林团队提出全新机器人装配技能学习框架Manual2Skill
视觉语言模型(Vision-Language Models, VLMs),为真实环境中的机器人操作任务提供了极具潜力的解决方案。 尽管 VLMs 取得了显著进展,机器人仍难以胜任复杂的长时程任务(如家具装配),主要受限于人…...
day36-多路IO复用
一、基本概念 (服务器多客户端模型) 定义:单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力 作用:应用程序通常需要处理来自多条事件流中的事件,比如我现在用的电脑,需要同时处理键盘鼠标…...
恶补电源:1.电桥
一、元器件的选择 搜索并选择电桥,再multisim中选择FWB,就有各种型号的电桥: 电桥是用来干嘛的呢? 它是一个由四个二极管搭成的“桥梁”形状的电路,用来把交流电(AC)变成直流电(DC)。…...
Neko虚拟浏览器远程协作方案:Docker+内网穿透技术部署实践
前言:本文将向开发者介绍一款创新性协作工具——Neko虚拟浏览器。在数字化协作场景中,跨地域的团队常需面对实时共享屏幕、协同编辑文档等需求。通过本指南,你将掌握在Ubuntu系统中使用容器化技术部署该工具的具体方案,并结合内网…...
uni-app学习笔记三十五--扩展组件的安装和使用
由于内置组件不能满足日常开发需要,uniapp官方也提供了众多的扩展组件供我们使用。由于不是内置组件,需要安装才能使用。 一、安装扩展插件 安装方法: 1.访问uniapp官方文档组件部分:组件使用的入门教程 | uni-app官网 点击左侧…...
