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

【Spring】Spring IOCDI:架构旋律中的“依赖交响”与“控制华章”

前言

🌟🌟本期讲解关于Spring IOC&DI的详细介绍~~~

🌈感兴趣的小伙伴看一看小编主页:GGBondlctrl-CSDN博客

🔥 你的点赞就是小编不断更新的最大动力                                       

🎆那么废话不多说直接开整吧~~

 

目录

📚️1.IOC&DI入门 

1.1什么是Spring

1.2什么是IOC

1.3IOC的介绍

1.3.1传统的开发过程

1.3.2IOC程序开发 

1.3.3IOC的优势

1.4DI的介绍

📚️2.IOC&DI的使用

📚️3.IOC详解

3.1Bean的存储

3.2类注解实现

3.3获取Bean的其他方式

3.4多种注解含义

3.5方法注解Bean

3.5.1方法注解要配合注解类

3.5.2存在多个对象

📚️4.DI详解

4.1属性的注入

4.2构造方法注入

4.3setter方式注入

4.4几种方式的优缺

4.5@Autowired的缺点

4.5.1使用@Primary

4.5.2使用@Qualifier

4.5.3使用@Resource

📚️5.总结


 

📚️1.IOC&DI入门 

1.1什么是Spring

通过前⾯的学习, 我们知道了Spring是⼀个开源框架, 他让我们的开发更加简单. 他⽀持⼴泛的应⽤场景, 有着活跃⽽庞⼤的社区, 这也是Spring能够⻓久不衰的原因.但是这个概念相对来说, 还是⽐较抽象.

我们⽤⼀句更具体的话来概括Spring, 那就是: Spring 是包含了众多⼯具⽅法的 IoC 容器 

1.2什么是IOC

在前⾯讲到, 在类上⾯添加 @RestController 和@Controller 注解, 就是把这个对象交给Spring管理, Spring 框架启动时就会加载该类. 把对象交给Spring管理, 就是IoC思想

IOC:: Inversion of Control (控制反转), 也就是说 Spring 是⼀个"控制反转"的容器

控制反转:

当需要某个对象时, 传统开发模式中需要⾃⼰通过 new 创建对象, 现在不需要再进⾏创建, 把创建对象的任务交给容器, 程序中只需要依赖注⼊ (Dependency Injection,DI)就可以了

总结:

IOC就是一个创建任务对象的容器;

DI就是我们后面需要注入的依赖

1.3IOC的介绍

1.3.1传统的开发过程

假如我们在实现创建一个车子的时候,我们知道他是依赖于车身,轮胎,底盘...那么就有如下的依赖的情况:

那么我们在程序实现的时候就是如下所示的:

public class Car {//车依赖于车身private Framwork framwork;public Car(int size) {framwork = new Framwork(size);System.out.println("Car init....");}public void run(){System.out.println("car run....");}
}

 解释:

这就是车在制造的时候,依赖车身,所以就会创建一个车身的对象,那但是此时车身依赖由于底盘,就会在车身类进行对象的构造;

public class Framwork {private Bottem bottem;public Framwork(int size){bottem=new Bottem(size);System.out.println("framwork init....");}
}

解释:

此时我们就会发现,车身的制造依赖于底盘,那么就要创建底盘的对象,那么此时一直到最后一环指定就是轮胎;

public class Tire {private int size;public Tire(int size){this.size=size;System.out.println("tire init...");}
}

解释:

如果这里我们这里,最后一环的情况下,假如我们要规定颜色和轮胎的尺寸大小,此时就会发现一个问题;

以上程序的问题是:当最底层代码改动之后,整个调⽤链上的所有代码都需要修改.程序的耦合度⾮常⾼(修改⼀处代码, 影响其他处的代码修改)

1.3.2IOC程序开发 

此时我们就可以使用IOC程序开发的思想进行改进,将整个对象进行统一管理,然后就可以大大降低耦合性;

public static void main(String[] args) {Tire tire = new Tire(20);Bottom bottom = new Bottom(tire);Framework framework = new Framework(bottom);Car car = new Car(framework);car.run();}
static class Car {private Framework framework;public Car(Framework framework) {this.framework = framework;System.out.println("Car init....");}public void run() {System.out.println("Car run...");}
}

 解释:

这里小编只展示了一小部分,其余的写法基本是一致的;代码经过以上调整,⽆论底层类如何变化,整个调⽤链是不⽤做任何改变的,这样就完成了代码之间的解耦,从⽽实现了更加灵活、通⽤的程序设计了

1.3.3IOC的优势

在传统的代码中对象创建顺序是:Car -> Framework -> Bottom -> Tire
改进之后解耦的代码的对象创建顺序是:Tire -> Bottom -> Framework -> Car

改进之后的控制权发⽣的反转,不再是使⽤⽅对象创建并控制依赖对象了,⽽是把依赖对象注⼊将当前对象中,依赖对象的控制权不再由当前类控制了 

那么此时就可以看做是如下所示的情况:

 

此时优点就是如下:

1. 资源集中管理: IoC容器会帮我们管理⼀些资源(对象等), 我们需要使⽤时, 只需要从IoC容器中去取就可以了
2. 我们在创建实例的时候不需要了解其中的细节, 降低了使⽤资源双⽅的依赖程度, 也就是耦合度. 

1.4DI的介绍

DI: Dependency Injection(依赖注⼊) 

容器在运⾏期间, 动态的为应⽤程序提供运⾏时所依赖的资源,称之为依赖注⼊。程序运⾏时需要某个资源,此时容器就为其提供这个资源.

 

就是一个依赖的注入;

IoC 是⼀种思想,也是"⽬标", ⽽思想只是⼀种指导原则,最终还是要有可⾏的落地⽅案,⽽ DI 就属于具体的实现。所以也可以说, DI 是IoC的⼀种实现

📚️2.IOC&DI的使用

既然 Spring 是⼀个 IoC(控制反转)容器,作为容器, 那么它就具备两个最基础的功能:
• 存
• 取
Spring 容器 管理的主要是对象, 这些对象, 我们称之为"Bean". 我们把这些对象交由Spring管理, 由
Spring来负责对象的创建和销毁. 我们程序只需要告诉Spring, 哪些需要存, 以及如何从Spring中取出对象

此时我们就会使用@component来进行管理Bean,使用@Autowired来进行依赖的注入,那么代码如下:

@Component
public class BookDao {public List<BookInfo> mockData(){List<BookInfo> books=new ArrayList<>();for (int i = 0; i < 5; i++) {BookInfo book = new BookInfo();book.setId(i);book.setBookName("书籍" + i);book.setAuthor("作者" + i);book.setCount(i * 5 + 3);book.setPrice(new BigDecimal(new Random().nextInt(100)));book.setPublish("出版社" + i);book.setStatus(1);books.add(book);}return books;}
}

我们将这个数据对象交给spring管理,就是加上注解@Component;

@Component //交给spring进行管理
public class BookService {@Autowiredprivate BookDao bookDao;public List<BookInfo> getBookList(){List<BookInfo> books=bookDao.mockData();for (BookInfo book : books) {if (book.getStatus() == 1) {book.setStatusCN("可借阅");} else {book.setStatusCN("不可借阅");}}return books;}
}

 这里就是将逻辑处理的对象交给spring管理,由于这里要使用数据,所以要引入依赖,这个依赖就可以将数据的对象传过来;

@RequestMapping("/book")
@RestController
public class BookController {@Autowiredprivate BookService bookService;@RequestMapping("/getList")public List<BookInfo> getList() {//获取数据//交给spring注入依赖List<BookInfo> books = bookService.getBookList();//处理⻚⾯展⽰return books;}
}

最后在controller表现层操作时,将引入逻辑处理层的对象,此时就可以spring管理的对象拿出来,就是依赖的引入;

📚️3.IOC详解

通过上⾯的案例, 我们已经知道了Spring IoC 和DI的基本操作, 接下来我们来系统的学习Spring IoC和DI的操作.前⾯我们提到IoC控制反转,就是将对象的控制权交给Spring的IOC容器,由IOC容器创建及管理对象。也就是bean的存储

3.1Bean的存储

在之前的⼊⻔案例中,要把某个对象交给IOC容器管理,需要在类上添加⼀个注解:@Component⽽Spring框架为了更好的服务web应⽤程序, 提供了更丰富的注解

1. 类注解:@Controller、@Service、@Repository、@Component、@Configuration.
2. ⽅法注解:@Bean.

那么下面小编来示范一下;

3.2类注解实现

这里小编就只使用controller进行操作,通过controller注解来进行存储Bean;

代码如下所示:

@Controller
public class UserController {public void userController(){System.out.println("userController start...");}
}

此时我们就将这里的对象给spring进行管理了;

如何从Spring容器中获取对象:

@SpringBootApplication
public class SpringIocDemoApplication {public static void main(String[] args) {//获取Spring上下⽂对象ApplicationContext context = SpringApplication.run(SpringIocDemoApplication.class, args);//从Spring上下⽂中获取对象UserController userController = context.getBean(UserController.class);//使⽤对象userController.sayHi();}
}
解释:
ApplicationContext 翻译过来就是: Spring 上下⽂因为对象都交给 Spring 管理了,所以获取对象要从 Spring 中获取,那么就得先得到 Spring 的上下⽂
这个上下⽂, 就是指当前的运⾏环境, 也可以看作是⼀个容器, 容器⾥存了很多内容, 这些内容是当前运⾏的环境
可以看到此时的对象就是拿到了的,即输出了usercontroller start这句话~~~

然后我们将这个controller进行删除试试:

 此时就是出现异常了:就是这不到这个类型对象的存在,所以就抛出了异常;

3.3获取Bean的其他方式

上述就是通过类型来进行获取Bean的;

上述代码是根据类型来查找对象, 如果Spring容器中, 同⼀个类型存在多个bean的话, 怎么来获取呢?

ApplicationContext 也提供了其他获取bean的⽅式, ApplicationContext 获取bean对象的功能, 是⽗类BeanFactory提供的功能.

public interface BeanFactory {String FACTORY_BEAN_PREFIX = "&";Object getBean(String name) throws BeansException;<T> T getBean(String name, Class<T> requiredType) throws BeansException;Object getBean(String name, Object... args) throws BeansException;<T> T getBean(Class<T> requiredType) throws BeansException;<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;

可以看到这里可以根据类型和名字进行对象的获取,那么Bean的名字是啥?

Spring bean是Spring框架在运⾏时管理的对象, Spring会给管理的对象起⼀个名字,给每个对象起⼀个名字, 根据Bean的名称(BeanId)就可以获取到对应的对象.

Bean的命名

官方的文档就是如下所示:

具体的内容就是:

命名约定使⽤Java标准约定作为实例字段名. 也就是说,bean名称以⼩写字⺟开头,然后使⽤驼峰式⼤⼩写 ;

类名: UserController, Bean的名称为: userController
类名: AccountManager, Bean的名称为: accountManager

当然也有特殊的情况,前面两个单词都是大写:

类名: UController, Bean的名称为: UController
类名: AManager, Bean的名称为: AManager 

还有就是三个大写字母,的Bean的命名就是:

类名:UserControllerDI,Bean的名称;usercontrollerDI

此时我们使用三种获取Bean的方式进行获取Bean对象:

  public static void main(String[] args) {ApplicationContext context= SpringApplication.run(SpringIocApplication.class, args);UserController bean = context.getBean(UserController.class);bean.userController();UserController bean1 = (UserController) context.getBean("userController");bean1.userController();UserController bean2 = context.getBean("userController",UserController.class);bean2.userController();
}

解释:

此时我们这里第一种获取Bean的方式就是通过类型进行获取,然后第二种就是通过bean的名称进行获取,第三种就是前面两种的合并的方式;

此时我们进入运行状态:

ApplicationContext与BeanFactory

继承关系和功能⽅⾯来说:Spring 容器有两个顶级的接⼝:BeanFactory 和ApplicationContext。其中 BeanFactory 提供了基础的访问容器的能⼒,⽽ApplicationContext 属于 BeanFactory 的⼦类,它除了继承了 BeanFactory 的所有功能之外,它还拥有独特的特性,还添加了对国际化⽀持、资源访问⽀持、以及事件传播等⽅⾯的⽀持

 从性能⽅⾯来说:ApplicationContext 是⼀次性加载并初始化所有的 Bean 对象,⽽
BeanFactory 是需要那个才去加载那个,因此更加轻量. (空间换时间

这里小编就不再演示其他几个了,基本代码和思想都是一样的~~~

3.4多种注解含义

• @Controller:控制层, 接收请求, 对请求进⾏处理, 并进⾏响应.
• @Servie:业务逻辑层, 处理具体的业务逻辑.
• @Repository:数据访问层,也称为持久层. 负责数据访问操作
• @Configuration:配置层. 处理项⽬中的⼀些配置信息

类注解之间的关系查看 @Controller / @Service / @Repository / @Configuration 等注解的源码发
现:

这些注解⾥⾯都有⼀个注解 @Component ,说明它们本⾝就是属于 @Component 的"⼦类".
@Component 是⼀个元注解,这些其他的注解就是@Component的衍生类;

3.5方法注解Bean

1.使⽤外部包⾥的类, 没办法添加类注解
2. ⼀个类, 需要多个对象, ⽐如多个数据源

3.5.1方法注解要配合注解类

代码如下所示:

@Configuration
public class BeanConfig {@Beanpublic UserInfo userInfo(){return new UserInfo("zhangsan");}
}

那么此时就将这个对象进行了管理了;

那么我们就可以拿到这个对象:

UserInfo bean = context.getBean("UserInfo.class");System.out.println(bean);
3.5.2存在多个对象

代码如下:

@Configuration
public class BeanConfig {@Beanpublic UserInfo user1(){return new UserInfo("zhangsan");}//@Primary@Beanpublic UserInfo user2(){return new UserInfo("lisi");}
}

那么此时我们使用类型进行获取时候;

那么此时我们就要通过bean的名称来进行获取了;

User user1 = (User) context.getBean("user1");User user2 = (User) context.getBean("user2")

📚️4.DI详解

依赖注⼊是⼀个过程,是指IoC容器在创建Bean时, 去提供运⾏时所依赖的资源,⽽资源指的就是对象.在上⾯程序案例中,我们使⽤了 @Autowired 这个注解,完成了依赖注⼊的操作

1. 属性注⼊(Field Injection)
2. 构造⽅法注⼊(Constructor Injection)
3. Setter 注⼊(Setter Injection)

4.1属性的注入

代码如下:

@Controller
public class UsercontrollerDI {@Autowiredprivate  UserServiceDI userServicedi;//private final UserServiceDI userServiceDI=new UserServiceDI();public void start(){userServicedi.start();}}

这里就是通过属性的注入的方式进行依赖的注入;

此时我们进行对象的获取和打印:

   UsercontrollerDI bean3 = context.getBean(UsercontrollerDI.class);bean3.start();

去掉@Autowired , 再运⾏⼀下程序看看结果:

就是说明了这里由于没有注入依赖,那么就直接为空了(这个对象)

4.2构造方法注入

 代码如下所示:

@Controller
public class UserControllerDI2 {private UserServiceDI userServiceDI;public UserControllerDI2(){}@Autowiredpublic UserControllerDI2(UserServiceDI userServiceDI){this.userServiceDI=userServiceDI;}public void start(){userServiceDI.start();}
}

解释:

这就是通过构造方法来进行操作的,当然这里有点问题就是当存在两个构造方法的时候,默认就是无参的构造方法;

只有一个构造方法的时候,默认是使用这一个

若存在两个构造方法,此时就要指定使用那个构造方法

4.3setter方式注入

这里就和get与set方式基本一致了:

@Controller
public class UserSet {private UserServiceDI userServiceDI;@Autowiredpublic void setUserServiceDI(UserServiceDI userServiceDI) {this.userServiceDI = userServiceDI;}public void start(){userServiceDI.start();}
}

这里小编就不在过多的解释了;

4.4几种方式的优缺

属性注入

◦ 优点: 简洁,使⽤⽅便;
◦ 缺点:
▪ 只能⽤于 IoC 容器,如果是⾮ IoC 容器不可⽤,并且只有在使⽤的时候才会出现 NPE(空指
针异常)
▪ 不能注⼊⼀个Final修饰的属性

构造函数注入

优点:
▪ 可以注⼊final修饰的属性
▪ 注⼊的对象不会被修改
▪ 依赖对象在使⽤前⼀定会被完全初始化,因为依赖是在类的构造⽅法中执⾏的,⽽构造⽅法
是在类加载阶段就会执⾏的⽅法.
▪ 通⽤性好, 构造⽅法是JDK⽀持的, 所以更换任何框架,他都是适⽤的
◦ 缺点:
▪ 注⼊多个对象时, 代码会⽐较繁琐

setter方式注入

优点: ⽅便在类实例之后, 重新对该对象进⾏配置或者注⼊
◦ 缺点:
▪ 不能注⼊⼀个Final修饰的属性
▪ 注⼊对象可能会被改变, 因为setter⽅法可能会被多次调⽤, 就有被修改的⻛险

4.5@Autowired的缺点

当出现多个同种类型的对象的时候:

public class BeanConfig {@Beanpublic UserInfo userInfo(){return new UserInfo("zhangsan");}//@Primary@Beanpublic UserInfo userInfo1(){return new UserInfo("lisi");}
}

此时我们进行注入,就会出现如下的情况:

@Autowiredprivate UserInfo user;public void start(){System.out.println(user);}

直接出错;

很明显就是分不清楚,那个是要注入的Bean;

那么就有下面几种方法;

4.5.1使用@Primary

代码如下:

@Beanpublic UserInfo userInfo(){return new UserInfo("zhangsan");}@Primary@Beanpublic UserInfo userInfo1(){return new UserInfo("lisi");}

此时我们默认这个对象;

4.5.2使用@Qualifier

注意这里要和autowired进行搭配使用

    @Qualifier("userInfo1")@Autowiredprivate UserInfo user;

这里就要指定那个;

4.5.3使用@Resource

这里和上面一样,只不过不用搭配@Autowired了;

  @Sesource("userInfo1")private UserInfo user;

•@Autowird 与 @Resource的区别
• @Autowired 是spring框架提供的注解,⽽@Resource是JDK提供的注解
• @Autowired 默认是按照类型注⼊,⽽@Resource是按照名称注⼊. 相⽐于 @Autowired 来说,@Resource ⽀持更多的参数设置,例如 name 设置,根据名称获取 Bean.

📚️5.总结

本期小编主要讲解了关于Spring IOC和DI的详细介绍,从入门讲解概念到实际的应用,都有涉及,当然其中还涉及比较重要的面试题哦~~~

🌅🌅🌅~~~~最后希望与诸君共勉,共同进步!!!


💪💪💪以上就是本期内容了, 感兴趣的话,就关注小编吧。

                 😊😊  期待你的关注~~~

相关文章:

【Spring】Spring IOCDI:架构旋律中的“依赖交响”与“控制华章”

前言 &#x1f31f;&#x1f31f;本期讲解关于Spring IOC&DI的详细介绍~~~ &#x1f308;感兴趣的小伙伴看一看小编主页&#xff1a;GGBondlctrl-CSDN博客 &#x1f525; 你的点赞就是小编不断更新的最大动力 &#x1f386;那么…...

安全基线检查

一、安全基线检测基础知识 安全基线的定义 安全基线检查的内容 安全基线检查的操作 二、MySQL的安全基线检查 版本加固 弱口令 不存在匿名账户 合理设置权限 合理设置文件权限 日志审核 运行账号 可信ip地址控制 连接数限制 更严格的基线要求 1、禁止远程连接数据库 2、修改…...

python 生成tts语音

之前一直使用微软、或者国内大厂的接口&#xff0c;网页操作比较麻烦&#xff0c;最近发现一个python库可以完美解决&#xff0c;在这里分享给大家 在这里 GitHub - rany2/edge-tts: Use Microsoft Edges online text-to-speech service from Python WITHOUT needing Microsof…...

【链表】【删除节点】【刷题笔记】【灵神题单】

237.删除链表的节点 链表删除节点的本质是不用删除&#xff0c;只需要操作指针&#xff0c;跳过需要删除的节点&#xff0c;指向下下一个节点即可&#xff01; 删除某个节点&#xff0c;但是不知道这个节点的前一个节点&#xff0c;也不知道头节点&#xff01;摘自力扣评论区…...

Keil 5, Flash Timeout. Reset the Target and try it again.

stm32F303RBT6 Flash Timeout. Reset the Target and try it again. 需要pack DFP 1.4.0&#xff0c; FLASH 烧写算法需要包括1.4.0...

如何估算自然对流传热系数

介绍 一般来说&#xff0c;对流可以定义为通过加热流体&#xff08;例如空气或水&#xff09;的运动来传递热量的过程。 自然对流&#xff08;对流的一种特定类型&#xff09;可以定义为流体在重力作用下由于较热因此密度较小的物质上升&#xff0c;而较冷且密度较大的物质下…...

uniapp中scrollview配合swiper实现一个简单的tab标签页

<template><view class"tab-container"><!-- Tab 标签滚动容器 --><scroll-view scroll-x"true" class"tab-scroll" scroll-with-animation"true"><view class"tab-list"><viewv-for"…...

Redis3——线程模型与数据结构

Redis3——线程模型与数据结构 本文讲述了redis的单线程模型和IO多线程工作原理&#xff0c;以及几个主要数据结构的实现。 1. Redis的单线程模型 redis6.0之前&#xff0c;一个redis进程只有一个io线程&#xff0c;通过reactor模式可以连接大量客户端&#xff1b;redis6.0为了…...

JavaScript(JS)的对象

目录 1.array 数组对象 2.String 字符串对象 3.JSON 对象&#xff08;数据载体&#xff0c;进行数据传输&#xff09; 4.BOM 浏览器对象 5.DOM 文档对象&#xff08;了解&#xff09; 1.array 数组对象 定义方式1&#xff1a;var 变量名 new Array(元素列表); 定义方式…...

计算机毕业设计Python+LSTM天气预测系统 AI大模型问答 vue.js 可视化大屏 机器学习 深度学习 Hadoop Spark

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…...

二阶信息在机器学习中的优化;GPTQ算法利用近似二阶信息;为什么要求近似二阶(运算量大,ReLu0点不可微)

目录 二阶信息在机器学习中的优化 GPTQ算法利用近似二阶信息来找到合适的量化权重 详细解释 举例说明 近似二阶信息 定义与解释 举例说明 总结 为什么要求近似二阶(运算量大,ReLu0点不可微) 计算复杂性 精度需求 实际应用场景中的权衡 二阶信息在机器学习中的优…...

Spring事务管理学习记录

一、概念 事务&#xff08;Transaction&#xff09;是指一组操作的集合&#xff0c;这些操作要么全部成功&#xff0c;要么全部失败。事务的四大特性&#xff08;ACID&#xff09;确保了数据的完整性和一致性&#xff1a; 原子性&#xff08;Atomicity&#xff09;&#xff1a…...

Linux locate 命令详解

简介 locate 命令用于通过查询预构建的数据库来快速搜索文件和目录&#xff0c;该数据库包含来自文件系统的索引文件路径。它比 find 之类的命令要快得多&#xff0c;因为它不会实时搜索整个文件系统。 关键概念 locate 命令依赖于数据库&#xff0c;通常位于 /var/lib/mloca…...

uniapp手机端一些坑记录

关于 z-paging-x 组件&#xff0c;在ios上有时候通过弹窗去粗发它reload时会触发闪退&#xff0c;可能是弹框插入进去导致的DOM 元素已经被移除或者不可用&#xff0c;解决办法是加上他自带属性 :showRefresherWhenReload"true" 加上showRefresherWhe…...

快速排序算法

快速排序是一种非常高效的排序算法&#xff0c;采用分治策略来对一个数组进行排序。它由C. A. R. Hoare在1960年提出。快速排序的基本思想是通过一趟排序将待排记录分割成独立的两部分&#xff0c;其中一部分记录的关键字均比另一部分的关键字小&#xff0c;然后分别对这两部分…...

CSS定位

定位 其中&#xff0c;绝对定位和固定定位会脱离文档流 设置定位之后&#xff1a;可以使用四个方向值进行调整位置&#xff1a;left、top、right、bottom 相对定位 温馨提示 设置定位之后&#xff0c;相对定位和绝对定位他是相对于具有定位的父级元素进行位置调整&#xff0c…...

追加docker已运行容器添加或修改端口映射方法

docker run可以指定端口映射 【】docker run -d -p 80:80 --name name 但是容器一旦生成&#xff0c;就没有一个命令可以直接修改。通常间接的办法是&#xff0c;保存镜像&#xff0c;再创建一个新的容器&#xff0c;在创建时指定新的端口映射。 【】 docker stop A 【】 doc…...

53 基于单片机的8路抢答器加记分

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 首先有三个按键 分别为开始 暂停 复位&#xff0c;然后八个选手按键&#xff0c;开机显示四条杠&#xff0c;然后按一号选手按键&#xff0c;数码管显示&#xff13;&#xff10;&#xff0c;这…...

ubuntu多版本安装gcc

1.ubuntu安装gcc 9.3.1 $ sudo apt update $ sudo apt install gcc-9 g-9 二、配置GCC版本 安装完成后&#xff0c;需要使用update-alternatives命令来配置GCC版本。这个命令允许系统在多个安装的版本之间进行选择 1.添加GCC 9.3.1到update-alternatives管理 $ sudo update-a…...

异步处理优化:多线程线程池与消息队列的选择与应用

目录 一、异步处理方式引入 &#xff08;一&#xff09;异步业务识别 &#xff08;二&#xff09;明确异步处理方式 二、多线程线程池&#xff08;Thread Pool&#xff09; &#xff08;一&#xff09;工作原理 &#xff08;二&#xff09;直面优缺点和适用场景 1.需要快…...

音视频技术扫盲之预测编码的基本原理探究

预测编码是一种数据压缩技术&#xff0c;广泛应用于图像、视频和音频编码等领域。其基本原理是利用数据的相关性&#xff0c;通过对当前数据的预测和实际值与预测值之间的差值进行编码&#xff0c;从而实现数据压缩的目的。 一、预测编码的基本概念 预测编码主要包括预测器和…...

计算机毕业设计SpringCloud+大模型微服务高考志愿填报推荐系统 高考大数据 SparkML机器学习 深度学习 人工智能 Python爬虫 知识图谱

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…...

AIGC训练效率与模型优化的深入探讨

文章目录 1.AIGC概述2.AIGC模型训练效率的重要性3.模型优化的概念与目标4.模型优化策略4.1 学习率调节4.2 模型架构选择4.3 数据预处理与增强4.4 正则化技术4.5 量化与剪枝 5.代码示例6.结论 人工智能领域的发展&#xff0c;人工智能生成内容&#xff08; AIGC&#xff09;越来…...

《深入浅出HTTPS》读书笔记(13):块密码算法之迭代模式(续)

CTR模式 每次迭代运算的时候要生成一个密钥流&#xff08;keystream&#xff09;。 各个密钥流之间是有关系的&#xff0c;最简单的方式就是密钥流不断递增&#xff0c;所以才叫作计数器模式。 ◎在处理迭代之前&#xff0c;先生成每个密钥流&#xff0c;有n个数据块&#xff0…...

定时任务删除MongoDB历史数据

前言 MongoDB数据过多&#xff0c;导致存储成本飙升&#xff0c;为了降低成本&#xff0c;需要将历史数据删除。 删除逻辑 添加配置文件控制删除逻辑 syncconfig:deleteMongoConfig:#同步状态&#xff0c;true同步&#xff0c;false不同步syncStatus: true#删除数据的时间&…...

Simulink的SIL软件在环测试

以基于模型的设计&#xff08;MBD&#xff09;的软件开发时&#xff0c;需要进行SIL&#xff08;软件在环测试&#xff09;。SIL测试就是在PC上验证模型是否与代码功能一致。在项目开展中&#xff0c;用在需要将控制器生成移植到硬件前&#xff0c;把控制器的模块生成代码&…...

你能穿过迷雾看清一切吗

很多事情的真相有谁知道&#xff1f; 我和家里人被看不见的攻击攻击和操控&#xff0c;失控和无助状态被假鬼录制&#xff0c;然后安排某些不知道整个实际情况和真相的人去听&#xff0c;间接歪曲了整件事情。 各种高科技配合和各种脑功能操控伤害是一般人想都想不到的&#…...

8 设计模式之简单工厂模式

设计模式是软件开发中的一套通用解决方案&#xff0c;而简单工厂模式则是最基础、最常用的一种创建型模式。在这篇博客中&#xff0c;我将为大家详细介绍简单工厂模式的概念、优缺点&#xff0c;以及通过一个饮料制作的案例&#xff0c;帮助大家更好地理解和应用这种模式。 一、…...

一步一步写线程之十六线程的安全退出之一理论分析

一、多线程的开发 多线程的开发&#xff0c;在实际场景中几乎是无法避开的。即使是前端看似没有使用线程&#xff0c;其实在底层的框架中也使用了线程进行了支撑。至少到现在&#xff0c;不管是协程还是其它什么新的编程方式&#xff0c;仍然无法撼动线程的主流地位。 多线程的…...

《Learn Three.js》学习(4) 材质

前言&#xff1a; 材质为scene中物体的皮肤&#xff0c;有着不同的特性和视觉效果。 材质的共有属性&#xff1a; 基础属性&#xff1a; 融合属性&#xff1a; 融合决定了我们渲染的颜色如何与它们后面的颜色交互 高级属性&#xff1a; 与WebGL内部有关 简单材质&#xff1…...

【QNX+Android虚拟化方案】128 - QNX 侧触摸屏驱动解析

【QNX+Android虚拟化方案】128 - QNX 侧触摸屏驱动解析 一、QNX 侧触摸屏配置基于原生纯净代码,自学总结 纯技术分享,不会也不敢涉项目、不泄密、不传播代码文档!!! 本文禁止转载分享 !!! 汇总链接:《【QNX+Android虚拟化方案】00 - 系列文章链接汇总》 本文链接:《【…...

Oracle SCN与时间戳的映射关系

目录 一、基本概述 二、相关操作 三、参考文档 一、基本概述 Oracle 数据库中的 SYS.SMON_SCN_TIME 表是一个关键的内部表&#xff0c;主要用于记录过去时间段中SCN与具体的时间戳之间的映射关系。这种映射关系可以帮助用户将 SCN 值转换为可读性更强的时间戳&#xff0c;从而…...

量化交易系统开发-实时行情自动化交易-8.2.发明者FMZ平台

19年创业做过一年的量化交易但没有成功&#xff0c;作为交易系统的开发人员积累了一些经验&#xff0c;最近想重新研究交易系统&#xff0c;一边整理一边写出来一些思考供大家参考&#xff0c;也希望跟做量化的朋友有更多的交流和合作。 接下来会对于发明者FMZ平台介绍。 发明…...

HBU深度学习作业9

1. 实现SRN &#xff08;1&#xff09;使用Numpy实现SRN import numpy as npinputs np.array([[1., 1.],[1., 1.],[2., 2.]]) # 初始化输入序列 print(inputs is , inputs)state_t np.zeros(2, ) # 初始化存储器 print(state_t is , state_t)w1, w2, w3, w4, w5, w6, w7, …...

关于otter监控告警使用

一、背景 近期在使用otter完成单机房单向同步时&#xff0c;常常遇到channel假死的情况&#xff0c;导致Pipeline同步停止&#xff0c;系统表数据同步停止&#xff0c;影响生产环境用户数据查询相关的功能&#xff0c;虽然事后能够通过停channel后再启用channel重新启用…...

复合查询和内外连接

文章目录 1. 简单查询2. 多表查询2.1 显示雇员名、雇员工资以及所在部门的名字2.2 显示部门号为10的部门名&#xff0c;员工名和工资2.3 显示各个员工的姓名&#xff0c;工资&#xff0c;及工资级别 3. 自连接4. 子查询4.1 where后的子查询4.1.1 单行子查询4.1.2 多行子查询 (i…...

动态规划【C++优质版】

&#xff08;本文未经作者书面允许&#xff0c;禁止以任何形式传播&#xff08;包括但不限于转载&#xff0c;翻译……&#xff09;如需引用 请标注原作者&#xff09; Intro&#xff1a; 动态规划是一种用于解决优化问题的算法策略。在 C 中&#xff0c;它主要用于处理那些具…...

柔性芯片:实现万物互联的催化剂

物联网 (IoT) 市场已经非常成熟&#xff0c;麦肯锡预测&#xff0c;物联网将再创高峰&#xff0c;到 2030 年将达到 12.5 万亿美元的估值。然而&#xff0c;万物互联 (IoE) 的愿景尚未实现&#xff0c;即由数十亿台智能互联设备组成&#xff0c;提供大规模洞察和效率。 究竟是…...

【分布式】分布式事务

目录 1、事务的发展 2、本地事务 &#xff08;1&#xff09;如何保障原子性和持久性&#xff1f; &#xff08;2&#xff09;如何保障隔离性&#xff1f; 2、全局事务 &#xff08;1&#xff09;XA事务的两段式提交 &#xff08;2&#xff09;XA事务的三段式提交…...

nacos安装部署

nacos安装部署 1.安装nacos 1.安装nacos nacos的安装很简单下载后解压启动即可&#xff0c;但是在启动前请确保jdk环境正常&#xff1b; 1.首先我们要下载nacos安装包&#xff1a;可以到官网下载&#xff0c;注意我这里使用的是2.1.0版本&#xff1b; 2.下载完成后&#xff0…...

git 上传代码时报错

在上传代码时&#xff0c;显示无法上传 PS E:\JavaWeb\vue3-project> git push To https://gitee.com/evening-breeze-2003/vue3.git! [rejected] master -> master (non-fast-forward) error: failed to push some refs to https://gitee.com/evening-breeze-20…...

【C++】数字位数提取:从个位到十位的深入分析与理论拓展

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 &#x1f4af;前言&#x1f4af;第一题&#xff1a;提取个位数解法代码解法分析代码优化拓展思考&#xff1a;取模运算的普适性 &#x1f4af;第二题&#xff1a;提取十位数题目解读与思路分析方法一&…...

数据结构--二叉树的创建和遍历

目录 引入 定义 性质 二叉树的创建 迭代法 注意事项&#xff1a; 递归法 注意事项&#xff1a; 二叉树的遍历 深度优先 广度优先 先序遍历&#xff08;前序遍历&#xff09; 中序遍历 后序遍历 层序遍历 查找树结构中是否存在某数值 方法一&#xff1a; 方法…...

CEF127 编译指南 Linux篇 - 安装Git和Python(三)

1. 引言 在前面的文章中&#xff0c;我们已经完成了基础开发工具的安装和配置。接下来&#xff0c;我们需要安装两个同样重要的工具&#xff1a;Git 和 Python。这两个工具在 CEF 的编译过程中扮演着关键角色。Git 负责管理和获取源代码&#xff0c;而 Python 则用于运行各种编…...

计算机网络的类型

目录 按覆盖范围分类 个人区域网&#xff08;PAN&#xff09; 局域网&#xff08;LAN&#xff09; 城域网&#xff08;MAN&#xff09; 4. 广域网&#xff08;WAN&#xff09; 按使用场景和性质分类 公网&#xff08;全球网络&#xff09; 外网 内网&#xff08;私有网…...

Web入门(学习笔记)

Web入门 文章目录 Web入门SpringSpringBootWeb入门HTTP协议HTTP-概述HTTP特点 HTTP-请求协议HTTP-请求数据格式 HTTP-响应协议响应状态码 HTTP-协议解析 Web服务器-TomcatWeb服务器简介基本使用Tomcat文件夹目录解析常见问题Tomcat部署项目 入门程序解析**内嵌的Tomcat服务器**…...

mind+自定义库编写注意事项

在mind图形化命令编写中&#xff0c;main.ts 文件是通过图形化编程工具生成 C 代码&#xff0c;然后将生成的 C 代码上传到 Arduino Uno 上执行。 这些由main.ts定义的图形化代码通过生成的代码&#xff0c;需要包含调用arduinoc/libraries文件夹的*.h和*.cpp文件&#…...

jQuery零基础入门速通(上)

大家好&#xff0c;我是小黄。 在前端开发的世界里&#xff0c;jQuery以其简洁的语法和强大的功能&#xff0c;一直是许多开发者手中的利器。它不仅简化了HTML文档遍历和操作、事件处理、动画以及Ajax交互&#xff0c;还极大地提高了开发效率。本文将带你走进jQuery的世界&…...

计算机网络-Wireshark探索IPv4

使用工具 Wiresharkcurl(MacOS)traceroute: This lab uses “traceroute” to find the router level path from your computer to a remote Internet host. traceroute is a standard command-line utility for discovering the Internet paths that your computer uses. It i…...

【05】Selenium+Python 两种文件上传方式(AutoIt)

上传文件的两种方式 一、input标签上传文件 可以用send_keys方法直接上传文件 示例代码 input标签上传文件import time from selenium import webdriver from chromedriver_py import binary_path # this will get you the path variable from selenium.webdriver.common.by i…...