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

【JavaEE进阶】Spring AOP详解

目录

🍃什么是AOP

🌳什么是Spring AOP

🌴上手Spring AOP

🚩引入依赖

🚩编写AOP程序

🎍Spring AOP核心概念

🚩切点(Pointcut)

🚩连接点(Join Point)

🚩通知(Advice)

🚩切面(Aspect)

🍀通知类型

🚩注意事项

🌲@PointCut

🎄切面优先级@Order

🎋切点表达式

🚩execution表达式

🚩@annotation

🏀自定义注解 @CostTime

🏀定义切面类

🏀添加自定义注解


🍃什么是AOP

AOP是Aspect Oriented Programming的简称(又称为面向切⾯编程)

什么是面向切面编程呢?

  • 切面就是指某⼀类特定问题,所以AOP也可以理解为面向特定方法编程.

什么是面向特定方法编程呢?

  • 比如在前面文章实现的的"登录校验",就是⼀类特定问题.登录校验拦截器,就是对"登录校验"这类问题的统⼀处理.所以,拦截器也是AOP的⼀种应用.
  • AOP是⼀种思想,拦截器是AOP思想的⼀种实现.Spring框架实现了这种思想,提供了拦截器技术的相关接⼝.
  • 同样的,统⼀结果返回和统⼀异常处理,也是AOP思想的⼀种实现.

简单来说:AOP是⼀种思想,是对某⼀类事情的集中处理

🌳什么是Spring AOP

AOP是⼀种思想,它的实现⽅法有很多,有Spring AOP,也有AspectJ、CGLIB等.

Spring AOP是其中的⼀种实现⽅式.

学会了统⼀功能之后,是不是就学会了SpringAOP呢,当然不是

拦截器作用的维度是URL(⼀次请求和响应),@ControllerAdvice 应用场景主要是全局异常处理(配合自定义异常效果更佳),数据绑定,数据预处理.

AOP作用的维度更加细致(可以根据包、类、方法名、参数等进⾏拦截),能够实现更加复杂的业务逻辑.

举个例⼦:

我们现在有⼀个项⽬,项目中开发了很多的业务功能

现在有⼀些业务的执行效率⽐较低,耗时较⻓,我们需要对接⼝进⾏优化.

第⼀步就需要定位出执行耗时⽐较长的业务方法,再针对该业务方法来进⾏优化

如何定位呢?

  • 我们就需要统计当前项⽬中每⼀个业务⽅法的执⾏耗时.

如何统计呢?

  • 可以在业务⽅法运⾏前和运⾏后,记录下⽅法的开始时间和结束时间,两者之差就是这个⽅法的耗时.

就如下图所示:

这种⽅法是可以解决问题的,但⼀个项目中会包含很多业务模块,每个业务模块⼜有很多接⼝,⼀个接⼝⼜包含很多⽅法,如果我们要在每个业务⽅法中都记录⽅法的耗时,对于程序员而言,会增加很多的⼯作量.

AOP就可以做到在不改动这些原始⽅法的基础上,针对特定的方法进行功能的增强.

AOP的作用:在程序运⾏期间在不修改源代码的基础上对已有⽅法进⾏增强,达到⽆侵⼊性,实现解耦

我们先来看一下Spring AOP是如何实现的吧、

🌴上手Spring AOP

在前面的图书管理系统中,我们使用Spring AOP来实现一下统计时间

🚩引入依赖

在pom.xml⽂件中添加配置

🚩编写AOP程序

编写AOP相关程序如下:

运行:

可以发现我们的AOP代码对整体没有任何侵入,没有改之前的任何代码,现在耗时时间确实打印了;包括之前的统一结果返回,异常处理都不需要改前面的代码。

代码解释如下:

  1.  @Aspect:标识这是⼀个切⾯类
  2. @Around:环绕通知,在⽬标⽅法的前后都会被执⾏.括号中的为切点表达式,表达式后面的第一个*表⽰类名,第二个*表示方法名;这里也就表示对于controller下面的所以类和方法都生效。
  3. ProceedingJoinPoint joinPoint为连接点,表示作用的对象(例如controller中的某个类中的某个方法)
  4. 通知:指需要做的事情(记录开始时间,执行目标方法,记录结束时间,记录耗时)
  5. ProceedingJoinPoint.proceed()让原始方法执行,并返回一个值
  6. 切面:表达式+连接点+通知
  7. 该方法最后需要返回一个值,也就是执行原始方法所接受的值 

整个代码划分为三部分  

我们通过AOP⼊门程序完成了业务接执行耗时的统计.

通过上面的程序,我们也可以感受到AOP面向切⾯编程的⼀些优势:

  •  代码⽆侵⼊:不修改原始的业务方法,就可以对原始的业务方法进行了功能的增强或者是功能的改变
  • 减少了重复代码
  • 提高开发效率
  • 维护方便 

🎍Spring AOP核心概念

🚩切点(Pointcut)

切点(Pointcut),也称之为"切⼊点"

Pointcut的作⽤就是提供⼀组规则(使⽤AspectJ pointcut expression language 来描述),告诉程序对哪些⽅法来进行功能增强.

  

上⾯的表达式 execution(* com.bit.book.controller.*.*(..)) 就是切点表达式

🚩连接点(Join Point)

满⾜切点表达式规则的⽅法,就是连接点.也就是可以被AOP控制的⽅法

以⼊⻔程序举例,所有 com.bit.book.controller 路径下的⽅法,都是连接点

  

上述BookController类中的⽅法都是连接点

连接点是满⾜切点表达式的元素.切点可以看做是保存了众多连接点的⼀个集合.
比如:

  • 切点表达式:全体教师
  • 连接点就是:张三,李四等各个⽼师

🚩通知(Advice)

通知就是具体要做的⼯作,指哪些重复的逻辑,也就是共性功能(最终体现为⼀个⽅法)

⽐如上述程序中记录业务⽅法的耗时时间,就是通知

  

在AOP面向切面编程当中,我们把这部分重复的代码逻辑抽取出来单独定义,这部分代码就是通知的内容.

🚩切面(Aspect)

切⾯(Aspect) = 切点(Pointcut) + 通知(Advice)

通过切⾯就能够描述当前AOP程序需要针对于哪些⽅法,在什么时候执⾏什么样的操作

切⾯既包含了通知逻辑的定义,也包括了连接点的定义.  

切面所在的类,我们⼀般称为切面类(被@Aspect注解标识的类)

🍀通知类型

上⾯我们讲了什么是通知,接下来我们来看一看通知的类型,上面所使用的@Around 就是其中⼀种通知类型,表示环绕通知.

Spring中AOP的通知类型有以下⼏种:

  • @Around:环绕通知,此注解标注的通知⽅法在⽬标⽅法前,后都被执⾏(例如上述getListByPage方法前后)
  • @Before:前置通知,此注解标注的通知⽅法在⽬标⽅法前被执⾏
  • @After:后置通知,此注解标注的通知⽅法在⽬标⽅法后被执⾏,⽆论是否有异常都会执⾏
  • @AfterReturning:返回后通知,此注解标注的通知⽅法在⽬标⽅法后被执⾏,有异常不会执⾏
  • @AfterThrowing:异常后通知,此注解标注的通知⽅法发⽣异常后执⾏

接下来我们通过代码来来加深对这几个通知的理解

含各个通知类型代码如下:  

我们再来写一下测试代码,代码如下:

  

我们先来运行程序,访问无异常的测试一

  

程序正常运行的情况下, @AfterThrowing 标识的通知方法不会执⾏

从上图也可以看出来, @Around 标识的通知方法包含两部分,⼀个"前置逻辑",⼀个"后置逻辑".

其中"前置逻辑"会先于 @Before 标识的通知⽅法执行,"后置逻辑"会晚于 @After 标识的通知⽅法执

  

我们再来看一下有异常时的情况  

观察日志:  

程序发⽣异常的情况下:

  • @AfterReturning 标识的通知⽅法不会执行, @AfterThrowing 标识的通知方法执行了
  • @Around 环绕通知中原始方法调⽤时有异常,通知中的环绕后的代码逻辑也不会在执行了(因为原始方法调用出异常了)

  

🚩注意事项

  • @Around 环绕通知需要调用 ProceedingJoinPoint.proceed() 来让原始方法执行,其他通知需要JoinPoint作为连接点
  • @Around 环绕通知方法的返回值,必须指定为Object,来接收原始方法的返回值,否则原始方法执行完毕,是获取不到返回值的.
  • ⼀个切⾯类可以有多个切点.

🌲@PointCut

上面代码存在⼀个问题,就是存在⼤量重复的切点表达式 

execution(* com.bit.book.controller.*.*(..))

待此问题,Spring提供了 @PointCut 注解,把公共的切点表达式提取出来,需要⽤到时引⽤该切⼊点表达式即可.

代码修改如下:

当切点定义使用private修饰时,仅能在当前切⾯类中使用,当其他切⾯类也要使用当前切点定义时,就需要把private改为public.引用方式为:全限定类名.方法名()

代码:

🎄切面优先级@Order

当我们在⼀个项目中,定义了多个切⾯类时,并且这些切⾯类的多个切⼊点都匹配到了同⼀个目标⽅法.

当目标⽅法运⾏的时候,这些切⾯类中的通知方法都会执行,那么这⼏个通知⽅法的执行顺序是什么样的呢?

我们先准备如下案例

TimeRecordAspect:

TimeRecordAspect2:

TimeRecordAspect3:

TimeRecordAspect4:

测试代码:

运行程序访问t1,我们观察日志:

通过上述程序的运⾏结果,可以看出: 存在多个切⾯类时,默认按照切⾯类的类名字⺟排序:

  • @Before 通知:字⺟排名靠前的先执⾏
  • @After 通知:字⺟排名靠前的后执⾏

但这种⽅式不⽅便管理,我们的类名更多还是具备⼀定含义的

Spring 给我们提供了⼀个新的注解,来控制这些切⾯通知的执⾏顺序:@Order

使⽤⽅式如下:

执行程序,观察日志

通过上述程序的运⾏结果,得出结论:

@Order注解标识的切⾯类,执⾏顺序如下:

  • @Before 通知:数字越⼩先执⾏
  • @After 通知:数字越⼤先执⾏

@Order 控制切⾯的优先级,先执⾏优先级较⾼的切⾯,再执行优先级较低的切面,最终执行目标⽅法.

🎋切点表达式

上面的代码中,我们⼀直在使⽤切点表达式来描述切点.下⾯我们来介绍⼀下切点表达式的语法.

切点表达式常见有两种表达⽅式

  1. execution(RR):根据方法的签名来匹配
  2. @annotation(RR):根据注解匹配

🚩execution表达式

execution()是最常用的切点表达式,用来匹配⽅法,语法为

其中访问修饰符和异常可以省略

切点表达式⽀持通配符表达:

关于 * ,匹配任意字符,只匹配⼀个元素(返回类型,包,类名,⽅法或者⽅法参数)

  • 包名使⽤ * 表⽰任意包(⼀层包使⽤⼀个*)
  • 类名使⽤ * 表⽰任意类
  • 返回值使⽤ * 表⽰任意返回值类型
  • ⽅法名使⽤ * 表⽰任意⽅法
  • 参数使⽤ * 表⽰⼀个任意类型的参数

关于. . 匹配多个连续的任意符号,可以通配任意层级的包,或任意类型,任意个数的参数

  • 使⽤. .配置包名,标识此包以及此包下的所有⼦包
  • 可以使⽤ . .配置参数,任意个任意类型的参数

切点表达式⽰例:

🚩@annotation

代码:

比如有以下需求:需要在TestController中的t1生效和UserConrtller中的u2生效

此时我们就需要通过自定义切点来完成

execution表达式更适用有规则的,如果我们要匹配多个无规则的方法呢

这个时候我们使用execution这种切点表达式来描述就不是很⽅便了.

我们可以借助自定义注解的方式以及另⼀种切点表达式 @annotation 来描述这⼀类的切点

实现步骤:

  1. 编写自定义注解
  2. 使用 @annotation 表达式来描述切点
  3. 在连接点的⽅法上添加自定义注解

🏀自定义注解 @CostTime

创建⼀个注解类(和创建Class⽂件⼀样的流程,选择Annotation就可以了)

只需要把该注解加在所需要的方法上,也就是t1和u2上即可;通过这个注解来记录方法执行时间

1. @Target 标识了 Annotation 所修饰的对象范围,即该注解可以用在什么地⽅.常用取值:

  • ElementType.TYPE:⽤于描述类、接⼝(包括注解类型)或enum声明
  • ElementType.METHOD:描述⽅法
  • ElementType.PARAMETER:描述参数
  • ElementType.TYPE_USE:可以标注任意类型

2. @Retention 指Annotation被保留的时间⻓短,标明注解的⽣命周期

@Retention 的取值有三种:

  • RetentionPolicy.SOURCE:表⽰注解仅存在于源代码中,编译成字节码后会被丢弃.这意味着在运⾏时⽆法获取到该注解的信息,只能在编译时使⽤.⽐如 @SuppressWarnings ,以及lombok提供的注解 @Data ,@Slf4j
  • RetentionPolicy.CLASS:编译时注解.表⽰注解存在于源代码和字节码中,但在运⾏时会被丢弃.这意味着在编译时和字节码中可以通过反射获取到该注解的信息,但在实际运⾏时⽆法获取.通常⽤于⼀些框架和⼯具的注解.
  • RetentionPolicy.RUNTIME:运⾏时注解.表⽰注解存在于源代码,字节码和运行时中.这意味着在编译时,字节码中和实际运行时都可以通过反射获取到该注解的信息.通常用于⼀些需要在运⾏时处理的注解,如Spring的@Controller @ResponseBody

🏀定义切面类

使用 @annotation 切点表达式定义切点,只对@CostTime⽣效

🏀添加自定义注解

在TestController中的t1()和UserController中的u2()这两个方法上添加自定义注解 @CostTime,其他方法不添加

进行测试后,只有添加@CostTime注解的切面才会打印耗时时间,其他都没有被执行

Spring AOP的实现⽅式(常⻅⾯试题):

  • 1. 基于注解 @Aspect
  • 2. 基于⾃定义注解(参考⾃定义注解 @annotation 部分的内容)
  • 3. 基于SpringAPI(通过xml配置的⽅式,⾃从SpringBoot⼴泛使⽤之后,这种⽅法⼏乎看不到了)
  • 4. 基于代理来实现(更加久远的⼀种实现⽅式,写法笨重,不建议使⽤)

参考:面试官:谈谈你对IOC和AOP的理解及AOP四种实现方式[通俗易懂]-腾讯云开发者社区-腾讯云

相关文章:

【JavaEE进阶】Spring AOP详解

目录 🍃什么是AOP 🌳什么是Spring AOP 🌴上手Spring AOP 🚩引入依赖 🚩编写AOP程序 🎍Spring AOP核心概念 🚩切点(Pointcut) 🚩连接点(Join Point) 🚩通知(Advi…...

Docker 的基本概念和优势,以及在应用程序开发中的实际应用

Docker 是一种开源的容器化平台,让开发人员能够打包、发布和运行应用程序在轻量级、可移植的容器中。Docker 容器包含应用程序的代码、运行时环境、系统工具、系统库等,使得应用程序能在任何环境中快速部署和运行。 Docker 的基本概念包括以下几点&…...

python flask

安装 pip install flask 查看版本 pip show flask 启动服务器 设置环境变量,在控制台执行命令,app.py是创建的文件名 windows set FLASK_APPapp.py mac/linux export FLASK_APPapp.py 启动内置web服务器,注意要进入到app.py所在的文…...

关于tomcat使用中浏览器打开index.jsp后中文显示不正常是乱码,但英文正常的问题

如果是jsp文件就在首行加 “<% page language"java" contentType"text/html; charsetUTF-8" pageEncoding"UTF-8" %>” 如果是html文件 在head标签加入&#xff1a; <meta charset"UTF-8"> 以jsp为例子&#xff0c;我们…...

双向选择排序算法

一 概述 双向选择排序(又称鸡尾酒选择排序)是选择排序的优化版本,核心改进在于每轮遍历同时确定未排序部分的最小值和最大值,分别交换到序列两端,从而减少遍历轮数。 二 时间复杂度 时间复杂度为(O(n^2)),但实际比较次数约为标准选择排序的 (1/2)。 三 C++实现代…...

P8662 [蓝桥杯 2018 省 AB] 全球变暖--DFS

P8662 [蓝桥杯 2018 省 AB] 全球变暖--dfs 题目 解析讲下DFS代码 题目 解析 这道题的思路就是遍历所有岛屿&#xff0c;判断每一块陆地是否会沉没。对于这种图的遍历&#xff0c;我们首先应该想到DFS。 代码的注意思想就是&#xff0c;在主函数中遍历找出所有岛屿&#xff0c…...

2-kafka集群环境搭建

本文介绍kafka集群环境的搭建&#xff0c;我利用三个虚拟机搭建。文中我一步步演示了过程中可能会碰到的问题&#xff0c;在文章的最后&#xff0c;利用jmx&#xff0c;能看到详细的各个kafka broker的运行情况。 -1、环境 ubuntu &#xff1a;22.04-ltskafka: 2.8java: 17 …...

ROS2与Navigation2入门教程:构建与安装Nav2

Navigation2&#xff08;Nav2&#xff09;是ROS2中用于机器人导航的核心框架&#xff0c;支持路径规划、避障、SLAM等功能。本教程将详细介绍Nav2的安装与构建方法&#xff0c;涵盖二进制安装、源码编译及Docker部署等多种方式&#xff0c;适用于不同开发需求。 一、通过APT安…...

MySQL入门手册

MySQL入门手册&#xff1a;从零开始掌握数据库管理 &#x1f4d6; 一、MySQL是什么&#xff1f; MySQL 是一个开源的关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;由瑞典MySQL AB公司开发&#xff0c;现隶属于Oracle旗下。它使用**结构化查询语言&#xff…...

深度学习算法实战——风格迁移(主页有源码)

✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连✨ ​ ​​​ 1. 领域介绍 风格迁移&#xff08;Style Transfer&#xff09;是深度学习中的一个热门应用&#xff0c;旨在将一幅图像的风格迁移到…...

基于SpringBoot的智能问诊系统设计与隐私保护策略

通过SpringBoot框架&#xff0c;我们可以快速搭建一个智能问诊系统&#xff0c;为用户提供便捷的线上医疗服务。然而&#xff0c;在系统设计和实现过程中&#xff0c;如何保障用户的隐私和数据安全&#xff0c;始终是一个亟需关注的问题。本文将探讨基于SpringBoot的智能问诊系…...

开发ai模型最佳的系统是Ubuntu还是linux?

在 AI/ML 开发中&#xff0c;​Ubuntu 是更优选的 Linux 发行版&#xff0c;原因如下&#xff1a; ​1. 开箱即用的 AI 工具链支持 Ubuntu 预装了主流的 AI 框架&#xff08;如 TensorFlow、PyTorch&#xff09;和依赖库&#xff0c;且通过 apt 包管理器可快速部署开发环境。 提…...

Vue 3 ref(new Map()) 无法触发watch

现象 const map ref(new Map()); 通过 map.value.set(k, v); 不能触发watch 下面验证&#xff0c;map.value.set 并不能触发watch 的监听 代码 <script setup lang"ts"> import { ref, triggerRef, watch } from vue;const map ref(new Map<string, R…...

NoteGen是一款开源跨平台的 AI 笔记应用,专注于 recording 和 writing ,基于 Tauri 开发

一、软件介绍 文末提供程序和源码下载 NoteGen 是一款专注于记录和写作的跨平台 AI 笔记应用&#xff0c;基于 Tauri 开发。NoteGen 的核心理念是将记录、写作和 AI 结合使用&#xff0c;三者相辅相成。记录功能可以帮助用户快速捕捉和整理碎片化知识。整理功能是连接记录和写…...

repo访问gerrit.googlesource失败

编译openharmony的时候&#xff0c;repo阶段碰到一个问题&#xff0c;建议不要通过 apt install安装&#xff0c;里面的源来自google curl https://gitee.com/oschina/repo/raw/fork_flow/repo-py3 -o ~/repo chmod 755 ~/repo 执行类似这样的操作 repo init -u gitgitee.com:…...

IDEA中Git版本回退终极指南:Reset与Revert双方案详解

目录 前言一、版本回退前置知识二、Reset方案&#xff1a;整体改写历史1、IDEA图形化操作&#xff08;推荐&#xff09;1.1、查看提交历史1.2、选择目标版本1.3、选择回退模式1.3.1、Soft&#xff08;推荐&#xff09;1.3.2、Mixed1.3.3、Hard&#xff08;慎用&#xff09;1.3.…...

【系统架构设计师】体系结构复审

目录 1. 说明2. 例题2.1 例题1 1. 说明 1.体系结构设计、文档化和复审是一个迭代过程。2.从这个方面来说&#xff0c;在一个主版本的软件体系结构分析之后&#xff0c;要安排一次由外部人员&#xff08;用户代表和领域专家&#xff09;参加的复审。3.鉴于体系结构文档标准化以…...

Unity之如何实现哔哩哔哩直播弹幕游戏

前言 什么是直播间互动? 当我们使用哔哩哔哩进行直播或者观看视频时,我们可以通过接入哔哩哔哩提供的 直播&互动玩法SDK,让直播和视频可以与Unity3D游戏客户端或者游戏服务器进行互动。 环境要求 Unity 2020.x或更高版本 依赖库:Newtonsoft Json Unity Package 在P…...

视觉图像处理

在MATLAB中进行视觉图像处理仿真通常涉及图像增强、滤波、分割、特征提取等操作。以下是一个分步指南和示例代码,帮助您快速入门: 1. MATLAB图像处理基础步骤 1.1 读取和显示图像 % 读取图像(替换为实际文件路径) img = imread(lena.jpg); % 显示原图 figure; subplot(2…...

学习LED驱动知识(二)

ppt来自B站周老师 使用普通元器件或者电源芯片构建电路驱动LED 1.电阻降压限流设计 案例一&#xff1a; USB供电电压为5V&#xff0c;因为LED的Vf为3v&#xff0c;所以电路只能6个LED并联&#xff0c;直接跟电源并联电流太大&#xff0c;LED会过流导致断路。所以要先串联一个…...

011---UART协议的基本知识(一)

1. 摘要 文章为学习记录。主要介绍 UART 协议的概述、物理层、协议层、关键参数。 2. UART概述 通用异步收发传输器&#xff08;Universal Asynchronous Receiver/Transmitter&#xff09;&#xff0c;通常称作UART&#xff08;串口&#xff09;&#xff0c;是一种异步****串…...

如何选择开源向量数据库

文章目录 评估维度查询性能索引与存储扩展性数据管理能力生态支持 常见向量数据库对比 评估维度 选择开源向量数据库时&#xff0c;需要综合考虑查询性能、数据规模、索引构建速度、生态支持等多个因素&#xff0c;以下是关键的评估维度&#xff1a;选择开源向量数据库时&…...

SpringBoot项目配置文件

SpringBoot项目提供了多种属性配置方式&#xff08;properties、yaml、yml&#xff09; yml配置文件 使用Apifox可以方便开发接口、前端测试等 工程搭建&#xff1a; 1.创建SpringBoot工程&#xff0c;并引入web开发起步依赖、mybatis、mysql驱动、lombok 2.创建数据库表&am…...

L33.【LeetCode笔记】循环队列(数组解法)

目录 1.题目 2.分析 方法1:链表 尝试使用单向循环链表模拟 插入节点 解决方法1:开辟(k1)个节点 解决方法2:使用变量size记录队列元素个数 获取队尾元素 其他函数的实现说明 方法2:数组 重要点:指针越界的解决方法 方法1:单独判断 方法2:取模 3.数组代码的逐步实现…...

前端知识点---库和包的概念

1. 什么是库&#xff08;Library&#xff09;&#xff1f; 库&#xff08;Library&#xff09; 是一组可复用的代码集合&#xff0c;提供特定功能&#xff08;如网络请求、UI 组件、数据处理等&#xff09;。 特点&#xff1a; 只是代码的集合&#xff0c;没有完整的应用结构…...

【CSS3】筑基篇

目录 复合选择器后代选择器子选择器并集选择器交集选择器伪类选择器 CSS 三大特性继承性层叠性优先级 背景属性背景色背景图背景图平铺方式背景图位置背景图缩放背景图固定背景复合属性 显示模式显示模式块级元素行内元素行内块元素 转换显示模式 结构伪类选择器结构伪类选择器…...

CentOS7 安装docker并配置镜像加速

一、Yum 安装docker【不推荐】 /var/lib/docker 路径主要用于存储容器数据&#xff0c;在使用和操作过程中数据量会逐渐增加。因此&#xff0c;在生产环境中&#xff0c;建议为 /var/lib/docker 单独挂载一个硬盘。也可以使用软连接的方式 1.1 安装必要的一些系统工具 yum i…...

【Go每日一练】统计字符出现的次数

&#x1f47b;创作者&#xff1a;丶重明 &#x1f47b;创作时间&#xff1a;2025年3月9日 &#x1f47b;擅长领域&#xff1a;运维 目录 1.&#x1f636;‍&#x1f32b;️题目&#xff1a;2.&#x1f636;‍&#x1f32b;️资源&#xff1a;3.&#x1f636;‍&#x1f32b;️代…...

正向代理与反向代理

代理: 通常称为代理、代理服务器或 Web 代理&#xff0c;代理一般是指正向代理&#xff0c;是位于一组客户端计算机之前的服务器。当这些计算机向 Internet 上的站点和服务发出请求时&#xff0c;代理服务器将拦截这些请求&#xff0c;然后代表客户端与 Web服务器进行通信&…...

报表DSL优化,享元模式优化过程,优化效果怎么样?

报表DSL优化与享元模式应用详解 一、报表DSL优化 1. 问题背景 报表系统通常使用领域特定语言&#xff08;DSL&#xff09;定义模板结构、数据绑定规则及样式配置。随着复杂度提升&#xff0c;DSL可能面临以下问题&#xff1a; 冗余配置&#xff1a;重复定义样式、布局或数据源…...

双击PPT文件界面灰色不可用,需要再次打开该PPT文件才能正常打开

双击PPT文件界面灰色不可用&#xff0c;需要再次打开该PPT文件才能正常打开 1. 软件环境⚙️2. 问题描述&#x1f50d;3. 解决方法&#x1f421;解决步骤 4. 结果预览&#x1f914; 1. 软件环境⚙️ Windows10 或 Windows11 专业版64位&#xff0c;安装MotionGo软件&#xff08…...

学习前置知识第18和19天

今天要做什么&#xff1f; 1&#xff1a;显示数字要求格式 2&#xff1a;无符号除法指令:div 3&#xff1a;前面用vhd和img等格式进行系统界面启动&#xff0c;详细了解多种镜像格式文件的区别 一&#xff1a;显示数字要求格式 屏幕上显示的数字格式,三个颜色编码和数字属性 1&…...

C#运算符详解

一、运算符分类与功能‌ 1‌.算术运算符‌ 基本运算‌&#xff1a;&#xff08;加&#xff09;、-&#xff08;减&#xff09;、*&#xff08;乘&#xff09;、/&#xff08;除&#xff09;、%&#xff08;取模&#xff09; int a 10 / 3; // 结果为3&#xff08;整数除…...

生成任务,大模型

一个生成项目 输入&#xff1a;文字描述&#xff08;但是给的数据集是一串数字&#xff0c;id&#xff0c;ct描述&#xff0c;医生描述&#xff09; 输出&#xff1a;诊断报告 一、数据处理 import pandas as pd #处理表格数据pre_train_file "data/train.csv"tr…...

下载Hugging Face模型的几种方式

1.网页下载 直接访问Hugging Face模型页面&#xff0c;点击“File and versions”选项卡&#xff0c;选择所需的文件进行下载。 2.使用huggingface-cli 首先&#xff0c;安装huggingface_hub: pip install huggingface_hub 然后&#xff0c;使用以下命令下载模型&#xff1…...

【Elasticsearch入门到落地】9、hotel数据结构分析

接上篇《8、RestClient操作索引库-基础介绍及导入demo》 上一篇我们介绍了RestClient的基础&#xff0c;并导入了使用Java语言编写的RestClient程序Demo以及将要分析的数据库。本篇我们就要分析导入的宾馆数据库tb_hotel表结构的具体含义&#xff0c;并分析如何建立其索引库。 …...

【由技及道】量子构建交响曲:Jenkinsfile流水线的十一维编程艺术【人工智障AI2077的开发日志008】

摘要&#xff1a;当代码提交触发时空涟漪&#xff0c;当构建流水线穿越量子维度——欢迎来到自动化构建的终极形态。本文将揭示如何用Jenkinsfile编写量子构建乐章&#xff0c;让每次代码提交都成为跨维度交响乐的音符。 动机&#xff1a;构建系统的量子哲学 “主人啊&#xff…...

Unity开发——CanvasGroup组件介绍和应用

CanvasGroup是Unity中用于控制UI的透明度、交互性和渲染顺序的组件。 一、常用属性的解释 1、alpha&#xff1a;控制UI的透明度 类型&#xff1a;float&#xff0c;0.0 ~1.0&#xff0c; 其中 0.0 完全透明&#xff0c;1.0 完全不透明。 通过调整alpha值可以实现UI的淡入淡…...

jenkins配置连接k8s集群

jenkins配置连接k8s集群 前言 我这边jenkins是在一个服务器里面&#xff0c;k8s集群在其他服务器&#xff0c;实现连接 首先jenkins下载有k8s插件 进入配置页面 获取k8s-api-server地址 对应k8s服务器执行 kubectl config view --minify -o jsonpath{.clusters[0].cluste…...

Linux 入门:常用命令速查手册

目录 一.指令 1.pwd&#xff08;显示所在路径&#xff09; 2.ls&#xff08;列出所有子目录与文件&#xff09; 3.touch&#xff08;创建文件&#xff09; 4.mkdir&#xff08;创建目录&#xff09; 5.cd&#xff08;改变所处位置&#xff09; 6.rm&#xff08;删除&…...

【VUE】day01-vue基本使用、调试工具、指令与过滤器

【VUE】day01-vue基本使用、调试工具、指令与过滤器 1. 什么是Vue2. Vue的基本使用 1. 什么是Vue Vue&#xff08;Vue.js&#xff09;是一个用于构建用户界面的渐进式 JavaScript 框架&#xff0c;其核心设计理念是“自底向上逐层应用”&#xff0c;既能作为轻量级库增强现有项…...

deepseek为什么要开源

一、生态位的抢占与锁定&#xff1a;以 JDK 版本为例​ 在软件开发的世界里&#xff0c;生态位的抢占和先入为主的效应十分显著。就拿 Java 开发中的 JDK 版本来说&#xff0c;目前大多数开发者仍在广泛使用 JDK8。尽管 JDK17 和 JDK21 已经推出&#xff0c;且具备更多先进特性…...

软考 中级软件设计师 考点知识点笔记总结 day02

文章目录 3、计算机系统组成 &#xff08;五大部件&#xff09;3.1、主存储器3.2、运算器3.3、控制器3.4、Flynn分类法 4、指令系统4.1、七种寻址方式4.2、指令的流水处理4.3、流水线的计算 上一篇文章 软考知识点 day01 3、计算机系统组成 &#xff08;五大部件&#xff09; …...

Redis Cluster 客户端定位分片全解析:哈希槽与动态路由机制

Redis Cluster客户端定位分片全解析&#xff1a;哈希槽与动态路由机制 一、引言 Redis Cluster通过分片技术将数据分散存储在多个节点&#xff0c;实现水平扩展。客户端如何快速定位目标分片&#xff1f;本文将深入解析哈希槽算法、路由逻辑及实战技巧。 二、核心原理&#…...

基于Python+Vue的智能服装商城管理系统的设计与实现

&#x1f457; 基于PythonVue的智能服装商城管理系统的设计与实现 电商级解决方案&#xff1a;全栈技术融合 智能推荐系统 多维度数据分析 项目亮点&#xff1a;课程设计优选 | 企业级架构规范 | 完整电商功能闭环 | 毕业设计选择 &#x1f310; 在线资源速览 类别地址访问方…...

提升Web可访问性的10个关键实践

在当今互联网时代&#xff0c;确保网站的可访问性&#xff08;Accessibility&#xff09;已经成为开发者和设计师的重要任务之一。Web可访问性不仅有助于残障用户更好地访问和使用网站&#xff0c;还能提升整体用户体验。本文将介绍10个关键的Web可访问性实践&#xff0c;帮助你…...

基于DeepSeek的智慧医药系统(源码+部署教程)

运行环境 智慧医药系统运行环境如下&#xff1a; 前端&#xff1a; HTMLCSS后端&#xff1a;Java AIGCDeepseekIDE工具&#xff1a;IDEA技术栈&#xff1a;Springboot HTMLCSS MySQL 主要角色 智慧医药系统主要分为两个角色。 游客 尚未进行注册和登录。具备登录注册、…...

yolov5训练自己数据集的全流程+踩过的坑

一&#xff0c;拿到yolov5数据集的第一步是什么呢&#xff0c;安装必要的依赖文件。在requirements.txt文件下存放 pip install -r requirements.txt二&#xff0c;检查是否可以正常进行检测&#xff0c;在detect.py&#xff0c;文件下&#xff0c;里面有默认的设置文件是可以…...

【Recon】Git源代码泄露题目解题方法

CTF中Git源代码泄露题目解题方法 1. 确认存在.git目录泄露2. 下载完整的.git目录3. 恢复Git仓库历史4. 查找Flag的常见位置5. 处理不完整的.git目录6. 其他技巧示例流程 在CTF中遇到Git源代码泄露题目时&#xff0c;通常可以通过以下步骤解决&#xff1a; 1. 确认存在.git目录泄…...

Android APP 启动流程详解(含冷启动、热启动)

目录 一、流程对比图 二、冷启动&#xff08;Cold Launch&#xff09; 2.1 用户点击应用图标&#xff08;Launcher 触发&#xff09; 2.2 AMS 处理启动请求 2.3 请求 Zygote 创建新进程 2.4 初始化应用进程 2.5 创建 Application 对象 2.6 启动目标 Activity 2.7 执行 …...