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

Spring AOP(AOP概念、组成、Spring AOP实现及实现原理)

文章目录

  • 1. Spring AOP 是什么
  • 2. 为什么要用 AOP
  • 3. 怎么学 Spring AOP
  • 4. AOP 组成
  • 5. Spring AOP 实现
    • 5.1 添加 Spring AOP 框架支持
    • 5.2 定义切面和切点
    • 5.3 实现通知方法
    • 5.4 使⽤ AOP 统计 UserController 每个⽅法的执⾏时间 StopWatch
    • 5.4 切点表达式说明 AspectJ
  • 6. Spring AOP 实现原理
    • 6.1 生成代理的时机 :织入(Weaving)
    • 6.2 JDK 动态代理实现
    • 6.3 CGLIB 动态代理实现
    • 6.4 JDK 和 CGLIB 实现的区别

1. Spring AOP 是什么

学习 Spring AOP 之前,先要了解 AOP 是什么

AOP(Aspect Oriented Programming):面向切面编程,它和 OOP(面向对象编程)类似。

它是一种思想,是对某一类事情的集中处理。

比如用户登录权限的效验,在学习 AOP 之前,在需要判断用户登录的页面,都要各自实现或调用用户验证的方法,学习 AOP 之后,我们只需要在某一处配置一下,那么所有需要判断用户登录的页面就全部可以实现用户登录验证了,不用在每个方法中都写用户登录验证了

AOP 是一种思想,而 Spring AOP 是实现(框架),这种关系和 IOC(思想)与 DI(实现)类似


2. 为什么要用 AOP

  1. 高频:对于这种功能统一,且使用地方较多的功能,可以考虑用 AOP 来处理(比如 用户登录验证)
  2. 使⽤ AOP 可以扩充多个对象的某个能⼒,AOP 可以说是 OOP 的补充和完善(比如 现在要实现的业务和这个通用的功能没什么关系,但处于安全考虑,又必须进行登录的验证)

除了统一的用户登录判断外,AOP 还可以实现

  • 统一日志处理
  • 统一方法执行时间统计
  • 统一的返回格式设置
  • 统一的异常处理
  • 事务的开启和提交等

3. 怎么学 Spring AOP

Spring AOP 学习主要分为3个部分

  1. 学习 AOP 是如何组成的
  2. 学习 Spring AOP 使用
  3. 学习 Spring AOP 实现原理

4. AOP 组成

(1)切面(Aspect)

定义 AOP 是针对某个统一的功能的,这个功能就叫做一个切面,比如用户登录功能或方法的统计日志,他们就各是一个切面。切面是由切点和通知组成的

(2)连接点(Join Point)

所有可能触发 AOP(拦截方法的点)就称为连接点

(3)切点(Pointcut)

切点的作用就是提供一组规则来匹配连接点,给满足规则的连接点添加通知,总的来说就是,定义 AOP 拦截的规则的

切点相当于保存了众多连接点的一个集合(如果把切点看成一个表,而连接点就是表中一条一条的数据)

(4)通知(Advice)

切面的工作就是通知

通知:规定了 AOP 执行的时机和执行的方法

Spring 切面类中,可以在方法上使用以下注解,会设置方法为通知方法,在满足条件后悔通知本方法进行调用

  1. 前置通知 @Before:通知方法会在目标方法调用之前执行
  2. 后置通知 @After:通知方法会在目标方法返回或者抛出异常后调用
  3. 返回之后通知 @AfterReturning:通知方法会在目标方法返回后调用
  4. 抛异常后通知:@AfterThrowing:通知方法会在目标方法爬出异常之后调用
  5. 环绕通知:@Around:通知包裹了被通知的方法,在被通知的方法通知之前和调用之后执行自定义的行为

举个例子,在一个生产型公司中

通知相当于底层的执行者,切点是小领导制定规则,切面是大领导制定公司的发展方向,连接点是属于一个普通的消费者用户

以多个⻚⾯都要访问⽤户登录权限为例子,AOP 整个组成部分如图所示

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zkAm0DT8-1676207159825)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1676183469495.png)]


5. Spring AOP 实现

Spring AOP 实现步骤

  1. 添加 Spring AOP 框架支持
  2. 定义切面和切点
  3. 实现通知

接下来我们使⽤ Spring AOP 来实现⼀下 AOP 的功能,完成的⽬标是拦截所有 UserController ⾥⾯的

⽅法,每次调⽤ UserController 中任意⼀个⽅法时,都执⾏相应的通知事件。

5.1 添加 Spring AOP 框架支持

在中央仓库中搜锁 Spring AOP Maven Repository: Search/Browse/Explore (mvnrepository.com)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uIsDmKWi-1676207159826)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1676185167353.png)]

在 pom.xml 中添加如下配置:

<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-aop -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId>
</dependency>

5.2 定义切面和切点

@Aspect // 当前类是一个切面
@Component
public class UserAspect {// 定义一个切点(设置拦截规则)@Pointcut("execution(* com.example.springaop.controller.UserController.*(..))")public void pointcut() {}
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p4mQspnI-1676207159827)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1676186116916.png)]

5.3 实现通知方法

  1. 前置通知 @Before:通知方法会在目标方法调用之前执行
  2. 后置通知 @After:通知方法会在目标方法返回或者抛出异常后调用
  3. 返回之后通知 @AfterReturning:通知方法会在目标方法返回后调用
  4. 抛异常后通知:@AfterThrowing:通知方法会在目标方法爬出异常之后调用
  5. 环绕通知:@Around:通知包裹了被通知的方法,在被通知的方法通知之前和调用之后执行自定义的行为

实现通知方法也就是在什么时机执行什么方法

@Aspect // 当前类是一个切面
@Component
public class UserAspect {// 定义一个切点(设置拦截规则)@Pointcut("execution(* com.example.springaop.controller.UserController.*(..))")public void pointcut() {}// 定义 pointcut 切点的前置通知@Before("pointcut()")public void doBefore() {System.out.println("执行前置通知");}// 后置通知@After("pointcut()")public void doAfter() {System.out.println("执行后置通知");}// 返回之后通知@AfterReturning("pointcut()")public void doAfterReturning() {System.out.println("执行返回之后通知");}// 抛出异常之后通知@AfterThrowing("pointcut()")public void doAfterThrowing() {System.out.println("执行抛出异常之后通知");}
}
@RestController
@RequestMapping("/user")
public class UserController {@RequestMapping("/sayhi")public String sayHi() {System.out.println("sayhi 方法被执行");int num = 10/0;return "你好,java";}@RequestMapping("/sayhi2")public String sayHi2() {System.out.println("sayhi2 方法被执行");return "你好,java2";}
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qVSOeHQj-1676207159828)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1676189891534.png)]

环绕通知:@Around:通知包裹了被通知的方法,在被通知的方法通知之前和调用之后执行自定义的行为

// 添加环绕通知
@Around("pointcut()")
public Object doAround(ProceedingJoinPoint joinPoint) {Object result = null;System.out.println("环绕通知:前置方法");try {// 执行拦截方法result = joinPoint.proceed();} catch (Throwable e) {e.printStackTrace();}System.out.println("环绕通知:后置方法");return result;
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5xizlv7M-1676207159828)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1676190278115.png)]

5.4 使⽤ AOP 统计 UserController 每个⽅法的执⾏时间 StopWatch

Spring AOP 中统计时间用 StopWatch 对象

    // 添加环绕通知@Around("pointcut()")public Object doAround(ProceedingJoinPoint joinPoint) {// spring 中的时间统计对象StopWatch stopWatch = new StopWatch();Object result = null;try {stopWatch.start(); // 统计方法的执行时间,开始计时// 执行目标方法,以及目标方法所对应的相应通知result = joinPoint.proceed();stopWatch.stop(); // 统计方法的执行时间,停止计时} catch (Throwable e) {e.printStackTrace();}System.out.println(joinPoint.getSignature().getDeclaringTypeName() + "." +joinPoint.getSignature().getName() +"执行花费的时间:" + stopWatch.getTotalTimeMillis() + "ms");return result;}

5.4 切点表达式说明 AspectJ

AspectJ 表达式语法:SpringAOP & AspectJ

    @Pointcut("execution(* com.example.springaop.controller.UserController.*(..))")

AspectJ 语法(Spring AOP 切点的匹配语法):

切点表达式由切点函数组成,其中 execution() 是最常⽤的切点函数,⽤来匹配⽅法,语法为:

execution(<修饰符><返回类型><包.类.⽅法(参数)><异常>)

AspectJ ⽀持三种通配符

* :匹配任意字符,只匹配⼀个元素(包,类,或⽅法,⽅法参数)

… :匹配任意字符,可以匹配多个元素 ,在表示类时,必须和 * 联合使⽤。

+ :表示按照类型匹配指定类的所有类,必须跟在类名后⾯,如 com.cad.Car+ ,表示继承该类的所有⼦类包括本身

修饰符,一般省略

  • public 公共方法
  • *任意

返回值,不能省略

  • void 返回没有值
  • String 返回值字符串
  • *任意

包,通常不省略,但可以省略

  • com.gyf.crm 固定包
  • com.gyf.crm.*.service crm 包下面子包任意(例如:com.gyf.crm.staff.service)
  • com.gyf.crm… crm 包下面的所有子包(含自己)
  • com.gyf.crm.*service… crm 包下面任意子包,固定目录 service,service 目录任意包

类,通常不省略,但可以省略

UserServiceImpl 指定类

*Impl 以 Impl 结尾

User* 以 User 开头

*任意

方法名,不能省略

addUser 固定方法

add* 以 add 开头

*DO 以 DO 结尾

*任意

参数

() 无参

(int) 一个整形

(int,int)两个整型

(…) 参数任意

throws可省略,一般不写

表达式示例

  • execution(* com.cad.demo.User.*(…)) :匹配 User 类⾥的所有⽅法
  • execution(* com.cad.demo.User+.*(…)) :匹配该类的⼦类包括该类的所有⽅法
  • execution(* com.cad..(…)) :匹配 com.cad 包下的所有类的所有⽅法
  • execution(* com.cad….(…)) :匹配 com.cad 包下、⼦孙包下所有类的所有⽅法
  • execution(* addUser(String, int)) :匹配 addUser ⽅法,且第⼀个参数类型是 String,第⼆个参数类型是 int

6. Spring AOP 实现原理

Spring AOP 是构建在动态代理基础上,因此 Spring 对 AOP 的支持局限于方法级别的拦截

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pDirrfMk-1676207159829)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1676192122209.png)]

Spring AOP 动态代理实现:

默认情况下,实现了接⼝的类,使⽤ AOP 会基于 JDK ⽣成代理类,没有实现接⼝的类,会基于 CGLIB ⽣成代理类

  1. JDK Proxy(JDK 动态代理)

  2. CGLIB Proxy:默认情况下 Spring AOP 都会采用 CGLIB 来实现动态代理,因为效率高

    CGLIB 实现原理:通过继承代理对象来实现动态代理的(子类拥有父类的所有功能)

    CGLIB 缺点:不能代理最终类(也就是被 final 修饰的类)

6.1 生成代理的时机 :织入(Weaving)

织入是把切面应用到目标对象并创建新的代理对象的过程,切面在指定的连接点被织入到目标对象中

在目标对象的生命周期中有多个点可以进行织入

  1. 编译期:切面在目标类编译时被织入,这种方法需要特殊的编译器,AspectJ 的织入编译器就是以这种方式织入切面的
  2. 类加载期:切面在目标类加载到 JVM 时被织入,这种方式需要特殊的类加载器,它可以在目标类被引入应用之前增强该目标类的字节码,AspectJ5 的加载时织入 (load-time weaving. LTW)就支持以这种方式织入切面
  3. 运行期:切面在应用运行的某一时刻被织入,一般情况下,在织入切面时,AOP容器会为目标对象动态创建一个代理对象,Spring AOP 就是以这种方式织入切面的

6.2 JDK 动态代理实现

JDK 动态代理就是依靠反射来实现的

//动态代理:使⽤JDK提供的api(InvocationHandler、Proxy实现),此种⽅式实现,要求被
代理类必须实现接⼝
public class PayServiceJDKInvocationHandler implements InvocationHandler {//⽬标对象即就是被代理对象private Object target;public PayServiceJDKInvocationHandler( Object target) {this.target = target;}//proxy代理对象@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {//1.安全检查System.out.println("安全检查");//2.记录⽇志System.out.println("记录⽇志");//3.时间统计开始System.out.println("记录开始时间");//通过反射调⽤被代理类的⽅法Object retVal = method.invoke(target, args);//4.时间统计结束System.out.println("记录结束时间");return retVal;}public static void main(String[] args) {PayService target= new AliPayService();//⽅法调⽤处理器InvocationHandler handler = new PayServiceJDKInvocationHandler(target);//创建⼀个代理类:通过被代理类、被代理实现的接⼝、⽅法调⽤处理器来创建PayService proxy = (PayService) Proxy.newProxyInstance(target.getClass().getClassLoader(),new Class[]{PayService.class},handler);proxy.pay();}
}

6.3 CGLIB 动态代理实现

public class PayServiceCGLIBInterceptor implements MethodInterceptor {//被代理对象private Object target;public PayServiceCGLIBInterceptor(Object target){this.target = target;}@Overridepublic Object intercept(Object o, Method method, Object[] args, MethodProxymethodProxy)throws Throwable {//1.安全检查System.out.println("安全检查");//2.记录⽇志System.out.println("记录⽇志");//3.时间统计开始System.out.println("记录开始时间");//通过cglib的代理⽅法调⽤Object retVal = methodProxy.invoke(target, args);//4.时间统计结束System.out.println("记录结束时间");return retVal;}public static void main(String[] args) {PayService target= new AliPayService();PayService proxy= (PayService) Enhancer.create(target.getClass(),new PayServiceCGLIBInterceptor(target));proxy.pay();}
}

6.4 JDK 和 CGLIB 实现的区别

  1. JDK 实现,要求被代理类必须实现接口,之后是通过 InvocationHander 及 Proxy,在运行时动态的在内存中生成了代理对象,该代理对象是通过实现同样的接口实现(类似静态代理接口实现的方式),只是该代理类是在运行期时,动态的织入统一的业务逻辑字节码来完成的
  2. CGLIB 实现,被代理类可以不实现接口,是通过继承被代理类,在运行时动态的生成代理类对象,这种方式实现方式效率高

相关文章:

Spring AOP(AOP概念、组成、Spring AOP实现及实现原理)

文章目录1. Spring AOP 是什么2. 为什么要用 AOP3. 怎么学 Spring AOP4. AOP 组成5. Spring AOP 实现5.1 添加 Spring AOP 框架支持5.2 定义切面和切点5.3 实现通知方法5.4 使⽤ AOP 统计 UserController 每个⽅法的执⾏时间 StopWatch5.4 切点表达式说明 AspectJ6. Spring AOP…...

8.条件渲染指令

目录 1 v-if v-show 2 v-if v-else-if v-else 1 v-if v-show v-if与v-show都可以控制DOM的显示与隐藏 由于flag是布尔值&#xff0c;所以这里可以直接写 v-if"flag" 当flag为true的时候&#xff0c;v-if与v-show控制的div都会被显示出来 当flag为false的时候&a…...

2023年全网最全最细最流行的自动化测试工具有哪些?你都知道吗!

下面就是我个人整理的一些比较常用的自动化测试工具&#xff0c;并且还有视频版本的详细介绍&#xff0c;同时在线学习人数超过1000人&#xff01; B站讲的最详细的Python接口自动化测试实战教程全集&#xff08;实战最新版&#xff09;一&#xff1a;前言 随着测试工程师技能和…...

网络安全——数据链路层安全协议

作者简介&#xff1a;一名云计算网络运维人员、每天分享网络与运维的技术与干货。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 前言 一.数据链路层安全协议简介 1.数据链路安全性 二.局域网数据链路层协议 1.…...

编译原理基础概念

一、什么是编译程序编译程序是一种程序&#xff0c;能够将某一种高级语言编写的源程序改造成另一种低级语言编写的目标程序&#xff0c;他们在逻辑上等价、完成相同的工作二、编译阶段1、当目标程序是机器语言时&#xff0c;编译阶段&#xff1a;&#xff08;1&#xff09;编译…...

蔬菜视觉分拣机器人的设计与实现(RoboWork参赛方案)

蔬菜视觉分拣机器人的设计与实现 文章目录蔬菜视觉分拣机器人的设计与实现1. 技术栈背景2. 整体设计3. 机械结构3.1 整体结构3.2 底座结构3.3 小臂结构3.4 大臂结构3.5 负载组件结构3.6 末端执行器结构4. 硬件部分4.1 视觉系统4.1.1 光源4.1.2 海康工业相机4.2 传送带系统4.2.1…...

【LVGL移植】STM32F1基于STM32CubeMX配置硬件SPI驱动1.8寸TFT ST7735S跑LVGL图形demo

【LVGL移植】STM32F1基于STM32CubeMX配置硬件SPI驱动1.8寸TFT ST7735S屏幕跑LVGL图形demo&#x1f3ac;运行LVGL 按键组件demo ✨基于STM32CubeMX配置工程是因为方便移植&#xff0c;只要是STM32芯片&#xff0c;拿到我的这个工程源码就可以根据自己的stm32芯片&#xff0c;自…...

写给20、21级学生的话

写给20、21级学生的话前言一、关于招聘变招生&#xff0c;你怎么看&#xff1f;二、对于即将实习/已经实习的学生&#xff0c;你有什么建议&#xff1f;1.学习方面2.提升方面三、思想成年真的很重要前言 最近&#xff0c;有一些同学遇到的实习问题&#xff0c;我统一回复下&…...

功能测试用例多次录制后,我丢掉了selenium,选择龙测AI-TestOps云平台

目录一、如何使用龙测AI-TestOps云平台1、进入龙测AI-TestOps云平台2、新建项目3、新建流程图4、创建任务5、查看任务状态6、查看报告、图片7、下载流程图、测试报告、excel用例二、龙测AI-TestOps云平台AI功能介绍1、NLP2、视频AI转流程图三、总结功能测试用例多次录制后&…...

【C++知识点】C++20 常用新特性总结

✍个人博客&#xff1a;https://blog.csdn.net/Newin2020?spm1011.2415.3001.5343 &#x1f4da;专栏地址&#xff1a;C/C知识点 &#x1f4e3;专栏定位&#xff1a;整理一下 C 相关的知识点&#xff0c;供大家学习参考~ ❤️如果有收获的话&#xff0c;欢迎点赞&#x1f44d;…...

数据库体系结构概念--集中式数据库、分布式数据库

数据库模式 前言&#xff1a; 平时我们接触的‘数据库’一般指的是DBMS&#xff0c;数据库管理系统&#xff0c;DBMS是软件如&#xff1a;mysql、oracle、dm等等都是集中式数据库&#xff0c;但它们不能代表整个数据库&#xff0c;只是通过这些软件来管理相应的数据内容&#…...

PyQt5数据库开发2 5.2 QSqlRelationalTableModel

目录 一、Qt窗体设计 1. 新建Qt项目 2. 添加组件 3. 添加资源 4. 添加Action 5. 添加工具栏 6. 添加菜单项 7. 添加退出功能 二、SQL Server下建表插数据 1. 建立表 2. 插入数据 3. 单表数据 4. 联合查询 三、代码实现 1. 新建项目目录 2. 编译窗体文件和资…...

树莓派——智能家居第一步

辛辛苦苦配了成功让树莓派开始工作了&#xff0c;开始搞智能家居&#xff01;大体思路&#xff1a;基于工厂模式&#xff0c;分模块来实现上图分为三部分&#xff1a;主控、外设、控制主控我采用的是树莓派的4b4G版本&#xff0c;外设包括四个区域的灯&#xff08;我的和上图有…...

【Golang】Golang基础入门级教程 -- 0基础安装搭建Go语言开发环境

目录 安装和下载GO语言 下载 下载地址 版本的选择 安装 Windows安装 Linux下安装 Mac下安装 检查 GOROOT和GOPATH GOPROXY Go开发编辑器 VS Code介绍 下载与安装 配置 Go扩展 第一个Go程序 Hello World go mod init 编写 编译 VSCode切换默认终端 本篇文章…...

MATLAB | 如何解决实验数据散点图重叠问题(overlap)

本期部分实验效果&#xff1a; 这期讲一下如果数据重合严重该咋办(overlap)&#xff0c;事先说明&#xff0c;本文中的绘图均使用一个几行的简单小代码进行了修饰&#xff1a; function defualtAxes axgca;hold on;box on ax.XGridon; ax.YGridon; ax.XMinorTickon; ax.YMinor…...

Kubernetes 一键部署利器:kubeadm

文章目录集群部署痛点kubeadm 的工作原理kubeadm init 的工作流程kubeadm join 的工作流程kubeadm 的部署配置参数集群部署痛点 Kubernetes 的部署一直以来都是挡在初学者前面的一只“拦路虎”。尤其是在 Kubernetes 项目发布初期&#xff0c;它的部署完全要依靠一堆由社区维护…...

[jS 事件循环理解] 主线程 宏任务 微任务 - 执行顺序优先级理解

最近看了一个帖子 事件循环机制-宏任务-微任务 把js单线程中 , 主线程 | 宏任务 | 微任务 的调用顺序讲解的很直白精巧 , 记录一下以供查阅 1.主线程, 可以理解为从上到下顺序执行的一个js线程 2. 宏任务 script / setTimeOut /setInterval等 3. 微任务主要有promise等 4. 热…...

顺序表和链表的比较

这两个结构各有优势&#xff0c;相辅相成。 顺序表&#xff1a; 优点&#xff1a; 1.支持随机访问。 2.CPU高速缓存命中率更高。(物理空间连续) 缺点&#xff1a; 1.头部和中部插入和删除时间效率低(O(n))。 2.连续的物理空间&#xff0c;空间不够后需要增容&#xff1a…...

Java为什么只能单继承???

目录 先屡清楚继承和实现的区别&#xff1a; 分析原因&#xff1a; 多继承虽然能使子类同时拥有多个父类的特征&#xff0c;但是其缺点也是很显著的&#xff0c;主要有两方面&#xff1a; (1)如果在一个子类继承的多个父类中拥有相同名字的实例变量&#xff0c;子类在引用该…...

数据安全-分类分级 调研分析报告

目录 前言一、数据分类分级概述1.数据分类2.数据分级二、数据分类分级原则三、数据分类分级的框架和方法1.数据分类分级的框架2.分类标准分类常见的方法2.1 MECE2.2 线分法和面分法及混合分法2.3 数据主题域2.4 技术选型维度2.5 以业务应用维度2.6 信息安全隐私方面的分类法3.分…...

浏览器对象详解

文章目录浏览器对象详解一、参考资料二、认识浏览器运行态下的 js1.问&#xff1a;是否了解浏览器的执行态&#xff08;分层设计&#xff09;&#xff1f;2.BOM1.[location](https://developer.mozilla.org/zh-CN/docs/Web/API/Location)拓展方向&#xff1a;2.[History](https…...

异步电路后端实现流程(cdc signOff 后端做什么)

一种后端异步电路的signOff流程同步电路和异步电路分别signOff对于同步电路&#xff0c;后端会分析sta setup/hold&#xff0c;这里不在赘述。在该scenario下 异步电路是不会分析&#xff0c;也不会关注异步电路之间的走线在cdc scenario(mode)下sdc有一下设置&#xff1a;将所…...

Linux网络编程实战介绍

文章目录 前言一、Linux网络编程介绍二、文章目录总结前言 本专栏将为大家讲解Linux网络编程的知识,本专栏只需要有C语言基础即可学习,学习本专栏将大大提高你的C语言水平,当然了我也还会在ARM板子上进行实验将Linux驱动也和网络编程联系起来,方便大家去实现自己的项目。我…...

C++概述 课堂笔记

函数的重载在C语言中函数名是唯一的&#xff0c;不可以重复定义&#xff0c;当我们利用函数执行&#xff0c;功能相似的函数&#xff0c;我们也不能使用同一个函数&#xff0c;比如说&#xff0c;求整型的函数&#xff0c;不能用来求浮点型、字符型。在C中引入函数重载的概念&a…...

一文读懂SpringBoot整合Elasticsearch(一)

&#xff08;本篇文章主要介绍Spring Boot如何整合Elasticsearch&#xff0c;包括基本配置、数据操作、搜索功能等方面。&#xff09; 一、前言 Elasticsearch是一款全文搜索引擎&#xff0c;可用于快速、准确地存储、搜索和分析大量数据。而Spring Boot是一款快速开发框架&a…...

(数论)(枚举)(前缀和)1230. K倍区间

目录 题目链接 一些话 切入点 流程 套路 ac代码 题目链接 1230. K倍区间 - AcWing题库 &#xff5e;数&#xff5e;啦&#xff01;我草&#xff0c;又~在&#xff5e;水&#xff5e;字&#xff5e;数&#xff5e;啦&#xff01;我草&#xff0c;又~在&#xff5e;水&…...

万字带你深入理解 Linux 虚拟内存管理(下)

接上文&#xff1a;万字带你深入理解 Linux 虚拟内存管理&#xff08;上&#xff09; 6. 程序编译后的二进制文件如何映射到虚拟内存空间中 经过前边这么多小节的内容介绍&#xff0c;现在我们已经熟悉了进程虚拟内存空间的布局&#xff0c;以及内核如何管理这些虚拟内存区域&…...

【iOS】—— JSONModel源码学习

JSONModel 文章目录JSONModel关于JSONModel的用法initWithDictionary等方法load方法实现load方法调用时机init方法__setup__方法__inspectProperties:方法__doesDictionary方法__importDictionary方法关于JSONModel的用法 可以参考之前写的博客&#xff1a;【iOS】—— JSONMo…...

单片机怎么实现真正的多线程?

所谓多线程都是模拟的&#xff0c;本质都是单线程&#xff0c;因为cpu同一时刻只能执行一段代码。模拟的多线程就是任务之间快速切换&#xff0c;看起来像同时执行的样子。据说最近有多核的单片机&#xff0c;不过成本应该会高很多。对于模拟的多线程&#xff0c;我知道的有两种…...

【LeetCode】剑指 Offer(23)

目录 题目&#xff1a;剑指 Offer 46. 把数字翻译成字符串 - 力扣&#xff08;Leetcode&#xff09; 题目的接口&#xff1a; 解题思路&#xff1a; 代码&#xff1a; 过啦&#xff01;&#xff01;&#xff01; 写在最后&#xff1a; 题目&#xff1a;剑指 Offer 46. 把…...

做网站具备的条件/交换链接是什么意思

lsof 是 Linux 下的一个非常实用的系统级的监控、诊断工具。它可以用来列出被各种进程打开的文件信息&#xff0c;记住&#xff1a;Linux 下 “一切皆文件”&#xff0c;因此&#xff0c;使用 lsof&#xff0c;你可以获取任何被打开文件的各种信息lsof 是 Linux 下的一个非常实…...

制作网站图片不显示/网络营销软文范文

目录 一、事件监听 API 二、同步 API 三、异步 API 四、API大全 五、api的私人订制 一、事件监听 API 以 on 开头的 API 用来监听某个事件是否触发。 二、同步 API 以 Sync 结尾的 API 都是同步 API。 三、异步 API 大多数 API 都是异步 API。 四、API大全 请戳这里&a…...

外贸网站如何seo推广/做关键词优化

一些官方提供的Frank-Cucumber代码&#xff0c;可以参考去写我们自己的自动化测试代码 WAIT_TIMEOUT 240require rspec/expectations# -- See -- # Then /^I wait to see "([^\"]*)"$/ do |expected_mark|Timeout::timeout(WAIT_TIMEOUT) dountil view_with_ma…...

郑州优化网站/seo发展前景怎么样啊

教育 -大学生身体活动与健康-章节资料考试资料-江西师范大学【】 第一章单元作业 第一章单元测试 1、【单选题】磷酸原系统和乳酸能系统供能时的共同特点是( ) A、生成乳酸 B、产生大量的ATP C、生成CO2和水 D、不需要氧 参考资料【 】 2、【单选题】糖、脂肪和蛋白质的热价约为…...

上海企业网站推广方法/三只松鼠网络营销案例分析

1. 安装webstorm 2.安装nodejs http://nodejs.cn/download/ 查看安装的版本 3. cnpm https://npm.taobao.org/ cmd 里执行 npm install -g cnpm --registryhttps://registry.npm.taobao.org 下载老师的源码&#xff0c;解压 在D盘新建 D:\VueShop\ 把online-store 拷贝过来…...

做网站几天能学会/百度推广区域代理

互联网服务上线之后需要密切关注用户的使用情况&#xff0c;这就需要一个能够整合多个系统日志并提供报表分析可视化的工具。ELK是(elastic-search, logstash, kibana)的缩写。它提供了可扩展的&#xff0c;风格酷炫的日志平台服务一. logstash 服务logstash作为节点日志采集的…...