【Spring】手动实现Spring底层机制-问题的引出
🎄欢迎来到@边境矢梦°的csdn博文🎄
🎄本文主要梳理手动实现Spring底层机制-问题的引出 🎄
🌈我是边境矢梦°,一个正在为秋招和算法竞赛做准备的学生🌈
🎆喜欢的朋友可以关注一下🫰🫰🫰,下次更新不迷路🎆
Ps: 月亮越亮说明知识点越重要 (重要性或者难度越大)🌑🌒🌓🌔🌕
目录
🌸底层难点问题的引出🚀
🌈问题的概念解释
🎈BeanDefinition
🥝类加载器和类路径classPath
🌸底层难点问题的引出🚀
1. 底层如何实现依赖
2. 底层如何实现singleton (单例池)
3. 底层如何实现prototype (多例)
4. 底层如何实现IOC容器创建和初始化(之前用反射实现过, 较浅, 继续深入)
5. 底层如何实现getBean()
6. 底层如何实现BeanPostProcessor
7. Spring底层如何实现Bean后置处理器机制
8. 原生Spring底层如何实现AOP
🌈问题的概念解释
- spring底层实现依赖注入(Dependency Injection,DI)的主要机制是通过反射和配置元数据来实现的。依赖注入是Spring框架的核心功能之一,它允许开发者将一个Bean所依赖的其他Bean(依赖项)动态地注入到该Bean中,而不需要硬编码这些依赖项。以下是Spring底层如何实现依赖注入的关键步骤:
-
Bean Definition 注册:在Spring容器初始化的过程中,所有的Bean定义(Bean的类名、属性、依赖等信息)都会被注册到容器的BeanFactory中。这些Bean定义可以通过XML配置文件、Java注解或Java配置类来定义。
-
依赖关系定义:在Bean定义中,可以使用不同的方式来定义Bean之间的依赖关系。最常见的方式是使用构造函数注入(Constructor Injection)或Setter方法注入(Setter Injection)。依赖关系可以通过依赖注入的标签或注解来表示。
-
依赖解析和注入:当容器需要创建一个Bean实例时,它会检查该Bean的定义,以确定它所依赖的其他Bean。容器会自动解析这些依赖关系,并尝试实例化或获取依赖的Bean。
-
依赖注入:容器会将依赖项注入到目标Bean中。这可以通过调用目标Bean的构造函数、Setter方法、字段注入等方式来实现,具体取决于依赖关系的定义方式。
-
依赖的生命周期管理:Spring容器负责管理依赖项的生命周期。通常,依赖项的生命周期与目标Bean的生命周期相匹配。如果依赖项是Singleton作用域的Bean,那么它只会被创建一次并在容器启动时初始化;如果是Prototype作用域的Bean,每次注入都会创建一个新的实例。
-
可选的AOP代理(可选):如果Bean被配置为使用AOP(面向切面编程),容器可能会为该Bean创建一个代理对象,并将代理对象注入到依赖中,以便在方法调用时应用切面逻辑。
-
-
Spring框架实现Singleton模式的核心机制是通过控制Bean的创建和管理来确保在容器中只有一个实例的存在。Spring框架使用了一个叫做BeanFactory的容器来管理对象,其中包括了Singleton对象。下面是Spring如何实现Singleton模式的简要说明:
-
容器的生命周期管理:Spring容器本身也是一个Singleton对象,它负责管理所有的Bean实例。容器的生命周期通常与应用程序的生命周期相匹配。
-
同步管理:Spring通过使用同步机制来确保在多线程环境下Singleton对象的安全创建和访问。这样可以避免并发问题。
-
懒加载:虽然Spring默认在容器启动时就创建Singleton对象,但你也可以将Bean的懒加载标志设置为true,以延迟对象的创建直到第一次请求。这样可以节省资源,只有在需要时才会创建Singleton对象。
-
Bean的缓存:Spring使用一个叫做BeanFactory的容器来管理Bean的实例。在BeanFactory内部,Singleton对象会被缓存起来,以确保每次请求同一个Bean时,都会返回相同的实例。
-
Bean的创建和初始化:Spring容器会根据Bean定义创建实例对象。对于Singleton作用域的Bean,容器只会创建一个实例并在容器启动时进行初始化。这个实例会被缓存起来以供后续使用
-
Bean Definition:在Spring配置文件(如XML文件)或者Java配置类中,你需要定义Bean。这个Bean定义包括了Bean的类名、属性、依赖等信息。当Spring容器初始化时,它会解析这些Bean定义。
-
-
Spring框架底层实现Prototype作用域的Bean时,采用了一种不同的机制,与Singleton不同。在Prototype作用域下,Spring容器不会维护一个单独的缓存,每次请求Prototype类型的Bean都会创建一个新的实例。下面是Spring如何实现Prototype模式的简要说明:
-
Bean Definition:与Singleton作用域一样,你需要在Spring配置文件或Java配置类中定义Bean。Bean定义包括了Bean的类名、属性、依赖等信息。
-
Bean的创建和初始化:当请求一个Prototype作用域的Bean时,Spring容器会根据Bean定义创建一个新的实例对象,并在需要的情况下进行初始化。每次请求都会触发新的对象创建。
-
不进行缓存:与Singleton不同,Spring容器不会维护Prototype对象的缓存。每次请求Prototype Bean时,都会创建一个全新的实例。
-
不进行生命周期管理:Spring容器不会管理Prototype对象的生命周期。因此,容器不会在Bean的销毁阶段执行任何清理操作。对象的销毁由客户端代码负责。
-
-
底层实现IOC容器的创建和初始化通常包括以下几个步骤
- 创建容器对象:实例化一个容器对象,可以是自定义的容器类或者使用现有的容器框
- 扫描组件:容器会扫描指定的包或者目录,查找符合条件的组件(类)。
- 注册组件:将扫描到的组件注册到容器中,可以使用反射机制创建实例。
- 解析依赖:对于需要注入的依赖,容器会解析其依赖关系并在需要时注入对应的实例。
- 初始化组件:对于注册到容器中的组件,容器会调用其相应的初始化方法,可以是在注解上指定的初始化方法或者实现了特定接口的回调方法。
- 提供访问接口:容器提供相应的接口,如getBean()方法来获取容器中的组件实例。
-
Spring框架中的
getBean()
方法是用来从Spring容器中获取Bean实例的主要方法之一。下面是Spring框架底层如何实现getBean()
方法的简要说明:-
Bean Definition的注册:在Spring容器启动过程中,所有的Bean定义(包括Bean的名称、类名、属性等信息)都会被注册到容器的BeanFactory中。这个注册是在容器初始化阶段进行的,通常是通过XML配置文件或Java配置类来完成的。
-
Bean实例化:当调用
getBean()
方法时,容器首先会根据传入的Bean名称或类型信息,查找相应的Bean定义。 -
Bean的创建和初始化:如果找到了相应的Bean定义,容器会根据定义中的信息创建Bean的实例。这通常涉及到Java反射机制,它会调用Bean的构造函数来创建一个新的对象。然后,容器会应用依赖注入和初始化方法等来配置和初始化这个Bean实例。
-
Bean的缓存:Spring容器通常会维护一个Bean实例的缓存,以确保同一个Bean不会被多次创建。这样,如果之前已经创建了一个Bean实例,下次调用
getBean()
方法时,容器会直接返回缓存中的实例,而不会再次创建。 -
返回Bean实例:最终,
getBean()
方法会返回创建或从缓存中获取的Bean实例,供调用者使用。 -
AOP代理(可选):如果该Bean被配置为使用AOP(面向切面编程),容器可能会为该Bean创建一个代理对象,以便在方法调用时应用切面逻辑。
-
-
BeanPostProcessor
是Spring框架提供的一个扩展点,它允许开发者在Bean初始化的不同阶段插入自定义的逻辑。Spring底层通过一系列的回调方法来实现BeanPostProcessor
接口,以便在Bean的初始化前后执行额外的处理。以下是Spring底层如何实现BeanPostProcessor
的简要说明:-
接口定义:
BeanPostProcessor
是一个接口,其中定义了两个回调方法:-
postProcessBeforeInitialization(Object bean, String beanName)
: 在Bean的初始化前执行。在这个方法中,可以对Bean进行修改或者执行一些额外的初始化逻辑。 -
postProcessAfterInitialization(Object bean, String beanName)
: 在Bean的初始化后执行。在这个方法中,同样可以对Bean进行修改或者执行其他的操作。
-
-
注册BeanPostProcessor:开发者可以自定义一个或多个实现了
BeanPostProcessor
接口的类,然后将它们注册到Spring容器中。这可以通过XML配置文件、Java配置类或者注解方式来完成。一旦注册,这些BeanPostProcessor
将会被Spring容器调用。 -
回调方法执行:当Spring容器创建和初始化Bean时,它会在适当的时机调用已注册的
BeanPostProcessor
的回调方法。具体的调用时机如下:-
在Bean的实例化后,但在初始化方法调用之前,会调用
postProcessBeforeInitialization
方法。 -
在Bean的初始化方法调用后,会调用
postProcessAfterInitialization
方法
-
-
自定义逻辑:开发者可以在这两个回调方法中编写自己的逻辑,例如,可以在
postProcessBeforeInitialization
方法中进行属性设置或校验,也可以在postProcessAfterInitialization
方法中执行一些清理工作。-
在Java中,回调方法(Callback Methods)是一种常见的编程模式,它允许一个对象(通常是一个类)将某个方法的引用传递给另一个对象,以便在特定事件发生时调用该方法。回调方法通常用于事件处理、异步编程和自定义扩展点等情况。
-
-
-
Spring底层实现Bean后置处理器(BeanPostProcessor)机制主要依赖于接口和容器生命周期回调方法。Bean后置处理器允许在容器实例化、配置和初始化Bean之前和之后执行自定义逻辑,例如修改Bean的属性,执行代理等操作。以下是Spring底层如何实现Bean后置处理器机制的简要说明:
-
接口定义:
BeanPostProcessor
是Spring框架提供的接口,其中包含了两个回调方法:-
postProcessBeforeInitialization(Object bean, String beanName)
: 在Bean的初始化之前调用。开发者可以在此方法中修改Bean实例的属性或执行自定义初始化逻辑。 -
postProcessAfterInitialization(Object bean, String beanName)
: 在Bean的初始化之后调用。开发者可以在此方法中进行清理工作或者对Bean进行后处理。
-
-
注册BeanPostProcessor:开发者可以创建自定义的实现了
BeanPostProcessor
接口的类,并将这些后置处理器注册到Spring容器中。这通常可以通过XML配置文件、Java配置类或注解方式来完成。 -
容器生命周期回调方法:Spring容器在不同的生命周期阶段会自动调用已注册的Bean后置处理器的回调方法。以下是典型的生命周期回调方法执行顺序:
-
创建Bean实例。
-
在调用Bean的构造函数之后,但在初始化方法(如果有的话)之前,调用
postProcessBeforeInitialization
方法。 -
在调用Bean的初始化方法之后,调用
postProcessAfterInitialization
方法。
-
-
自定义逻辑:开发者可以在
postProcessBeforeInitialization
和postProcessAfterInitialization
方法中编写自己的逻辑,以根据需要修改、增强或清理Bean。 -
AOP代理(可选):在
postProcessBeforeInitialization
方法中,开发者可以选择创建AOP代理以包装Bean。这可以用于实现AOP切面。
-
-
原生Spring底层实现AOP(面向切面编程)主要依赖于动态代理和反射机制。Spring使用AOP实现了横切关注点(cross-cutting concerns)的模块化,允许在不改变业务逻辑的情况下,将横切关注点(如日志、事务、安全性检查等)应用于应用程序的各个部分。以下是Spring底层如何实现AOP的简要说明:
-
AOP核心概念:
-
切面(Aspect):切面是包含横切关注点的模块。它定义了何时以及在何地应用横切关注点。
-
连接点(Join Point):连接点是在应用程序中可能被拦截的点,例如方法调用、异常抛出等。
-
通知(Advice):通知是在连接点上执行的动作,包括"前置通知"、"后置通知"、"环绕通知"、"抛出异常通知"和"最终通知"。
-
切点(Pointcut):切点是一组连接点的集合,它定义了哪些连接点应该被拦截。
-
-
AOP代理生成:Spring底层使用JDK动态代理和CGLIB两种方式生成AOP代理。具体的代理方式取决于目标Bean是否实现了接口。如果目标Bean实现了接口,Spring将使用JDK动态代理,否则将使用CGLIB代理。代理对象负责调用切面的通知方法。
-
通知执行:当目标方法被调用时,AOP代理会根据切面定义的通知类型,在连接点上执行相应的通知。例如,前置通知会在方法执行前执行,后置通知会在方法执行后执行。
-
切点匹配:Spring使用切点表达式(Pointcut Expressions)来确定哪些连接点应该被拦截。切点表达式可以根据方法名、包名、类名等条件来匹配连接点。
-
通知执行顺序:通知可以按照特定的顺序来执行,这个顺序可以在切面配置中定义。通常情况下,通知的执行顺序包括前置通知、环绕通知、后置通知、抛出异常通知和最终通知。
-
XML配置或注解:Spring提供了两种方式配置AOP,一种是通过XML配置文件定义切面、切点和通知,另一种是使用注解来标注切面、切点和通知。
-
🎈BeanDefinition
在Spring框架中,BeanDefinition是Spring容器中的一个抽象概念,当Spring容器初始化时,它会解析配置文件或者注解,并生成相应的BeanDefinition对象。BeanDefinition是用于描述和定义一个Bean的元数据(数据的数据, 类属性的属性)信息的对象。它包含了一个Bean的类名、作用域、属性值、构造函数参数、初始化方法、销毁方法等相关信息。它的主要作用是为容器提供创建和管理Bean实例的必要信息。
通过BeanDefinition,Spring容器了解了如何实例化、配置和管理一个Bean对象。它允许我们对Bean进行灵活的配置和定制化,可以设置不同的作用域(如单例、原型等),设置属性值,指定构造函数参数等。
BeanDefinition可以通过不同的方式进行定义,包括XML配置文件、注解和Java代码等。无论使用哪种方式,最终都会被解析为BeanDefinition对象,然后由容器根据该对象来创建和管理相应的Bean实例。
Spring的BeanDefinition提供了一个统一的模型来管理和控制Bean的生命周期和行为。它使得Spring容器能够根据配置信息动态地创建和管理Bean对象,同时也提供了强大的扩展和定制化能力。
🥝类加载器和类路径classPath
java的类加载器3种
- Bootstrap类加载器--—----—--—---对应路径jre/lib
- Ext类加载器---------—----------对应路径jre/lib/ext
- App类加载器--—-------------—--对应路径classpath
App类加载器常用, classpath 类路径,就是 java.exe 执行时,指定的路径,比如
"C:\Program Files\Java\jdk1.8.0_181\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2023.1.2\lib\idea_rt.jar=55328:C:\Program Files\JetBrains\IntelliJ IDEA 2023.1.2\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_181\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\rt.jar;D:\NewExecllction\exicesecode\lxb-spring\target\classes;C:\Users\Administrator\.m2\repository\org\springframework\spring-context\5.3.8\spring-context-5.3.8.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-aop\5.3.8\spring-aop-5.3.8.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-beans\5.3.8\spring-beans-5.3.8.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-core\5.3.8\spring-core-5.3.8.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-jcl\5.3.8\spring-jcl-5.3.8.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-expression\5.3.8\spring-expression-5.3.8.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-aspects\5.3.8\spring-aspects-5.3.8.jar;C:\Users\Administrator\.m2\repository\org\aspectj\aspectjweaver\1.9.6\aspectjweaver-1.9.6.jar" com.lxb.spring.AppMain
🌰ClassLoader的getResource方法
相关文章:

【Spring】手动实现Spring底层机制-问题的引出
🎄欢迎来到边境矢梦的csdn博文🎄 🎄本文主要梳理手动实现Spring底层机制-问题的引出 🎄 🌈我是边境矢梦,一个正在为秋招和算法竞赛做准备的学生🌈 🎆喜欢的朋友可以关注一下…...
Java - List 去重,获取唯一值,分组列出所属对应集合
问题:List 去重,获取唯一值,分组列出所属对应集合 方案一:这个不需要额外的内存占用 //遍历后判断赋给另一个list集合public static void main(String[] args){List<String> list new ArrayList<String>(); lis…...
离散高斯抽样(Discrete Gaussian Sampling)
离散高斯抽样 离散高斯抽样(Discrete Gaussian Sampling)是一种常见于密码学和数学领域的随机采样方法。它通常用于构建基于格(lattice)的密码学方案,如基于格的加密和数字签名。Discrete Gaussian Sampling 的主要目…...

Elasticsearch:什么是生成式人工智能?
生成式人工智能定义 给学生的解释(基本): 生成式人工智能是一种可以创造新的原创内容的技术,例如艺术、音乐、软件代码和写作。 当用户输入提示时,人工智能会根据从互联网上现有示例中学到的知识生成响应,…...

责任链模式让我的代码精简10倍?
目录 什么是责任链使用场景结语 前言最近,我让团队内一位成员写了一个导入功能。他使用了责任链模式,代码堆的非常多,bug 也多,没有达到我预期的效果。实际上,针对导入功能,我认为模版方法更合适ÿ…...

Draw软件安装下载
Draw软件安装下载 1.软件简介2.软件下载3.安装方法 1.软件简介 Draw软件,全名为LibreOffice Draw,是一款免费、开源的2D矢量绘图软件,属于LibreOffice办公套件的一部分。它可以用来创建各种类型的图形,包括流程图、组织结构图、平…...
uniapp代码混淆ios上架43问题
参考文章:uniapp打包ios apk,混淆代码_uniapp 混淆_酸奶自由竟然重名了的博客-CSDN博客 uniapp打包ios,上传到ios应用市场时,会因为 4.3(代码重复率过高) 无法通过审核,此时可通过混淆代码来通过审核 1. 项目终端 安…...

Linux目录遍历函数
1.打开一个目录 #include <sys/types.h> #include <dirent.h> DIR *opendir(const char *name); 参数: -name:需要打开的目录的名称 返回值: DIR * 类型,理解为目录流 错误返回NULL 2.读取目录中的数据 #include <dirent.h…...

数据库-理论基础
目录 1.什么是数据库? 2.数据库与文件系统的区别? 3.常见的数据库由那些? 4.关系型数据库(MySQL)的特征及组成结构介绍 1.什么是数据库? 数据:描述事物的符号记录,可以是数字,文…...

【已解决】src/spt_python.h:14:20: 致命错误:Python.h:没有那个文件或目录
src/spt_python.h:14:20: 致命错误:Python.h:没有那个文件或目录 问题 其中重点的报错信息 src/spt_python.h:14:20: fatal error: Python.h: No such file or directory 思路 sudo yum install python-devel然后重新安装需要的依赖。 解决 成功。…...

基于Face++网络爬虫+人脸融合算法智能发型推荐程序——深度学习算法应用(含Python及打包exe工程源码)+爬虫数据集
目录 前言总体设计系统整体结构图系统流程图 运行环境Python环境Pycharm 环境 模块实现1. Face.APl调用1)Face.APl介绍2)调用API 2. 数据爬取1)网络数据爬取步骤2)爬虫实现 3. 模型构建4. 用户界面设计1)需要调用的库文…...

Jetson nano嵌入式平台配置ip记录
背景 Jetson nano平台使用千兆网和PC连接时没有ip地址,在ubuntu的终端输入ifconfig显示eh0未设置ip,需要先在nano平台上配置ip地址,然后PC通过千兆网远程控制该平台。 配置ip 使用终端进入到network文件夹中, cd /etc/network…...

前端中的跨域请求及其解决方案
聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 跨域(Cross-Origin)⭐CORS(跨域资源共享)⭐JSONP(JSON with Padding)⭐代理服务器⭐ WebSocket⭐服务器设置响应头⭐ 写在最后 ⭐ 专栏简介 前端入门之旅:…...

SpringBoot2.0(mybatis-plus初始使用)
目录 一,介绍二,SpringBoot2.x整合MybatisPlus Lombok2.1,添加依赖 pom2.2,配置数据库信息 application.properties2.3,工程结构初始化 三,创建接口返回统一对象四,创建bean五,创建…...

游戏视频录制软件对比,哪款最适合你的需求?
随着电子竞技和游戏直播行业的迅速崛起,越来越多的玩家渴望记录并分享自己在游戏中的精彩瞬间。游戏视频录制软件正是满足这一需求的关键工具。本文将针对三款优秀的游戏视频录制软件进行对比分析,以便为读者提供选购建议。 游戏视频录制软件1࿱…...

耐蚀合金连续油管最新版 学习记录
声明 本文是学习GB-T 42858-2023 耐蚀合金连续油管. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 1 范围 本文件规定了耐蚀合金连续油管的订货、材料、制造、检验试验、标记等。 本文件适用于油气井用耐蚀合金连续油管(以下简称"油管")…...

LoGoNet:基于局部到全局跨模态融合的精确 3D 目标检测
论文地址:https://arxiv.org/abs/2303.03595 论文代码:https://github.com/sankin97/LoGoNet 论文背景 激光雷达传感器点云通常是稀疏的,无法提供足够的上下文来区分远处的区域,从而造成性能次优。 激光雷达-摄像机融合方法在三…...
Python 多线程、线程池、进程池
线程间的通讯机制 消息队列 event 事件对象 当线程创建完成之后,并不会马上执行线程,而是等待某一事件发生,线程才会启动 import threading# # 创建 event 对象 # event threading.Event() # # 重置代码中的 event 对象,使得所…...

深入浅出了解华为端到端交付流程的概念和5个关键点
如果您或您所在的组织在学习和研究华为,那么对“端到端”这个词语就一点都不陌生。 今天华研荟带着您了解华为端到端的交付流程的思想和一些做法,如果了解了这个,那么对于华为在其他领域提出的端到端要求或做法就一通百通了。 一、什么是端…...

[Linux]进程信号
[Linux]进程信号 文章目录 [Linux]进程信号进程信号的定义信号的特点信号的生命过程发送信号的原理进程处理信号的方式分类使用指令查看Linux系统定义的信号信号产生使用终端按键产生信号使用指令向进程发送信号调用系统调用向进程发送信号由软件条件产生信号硬件异常产生信号 …...

Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...

7.4.分块查找
一.分块查找的算法思想: 1.实例: 以上述图片的顺序表为例, 该顺序表的数据元素从整体来看是乱序的,但如果把这些数据元素分成一块一块的小区间, 第一个区间[0,1]索引上的数据元素都是小于等于10的, 第二…...

Linux 文件类型,目录与路径,文件与目录管理
文件类型 后面的字符表示文件类型标志 普通文件:-(纯文本文件,二进制文件,数据格式文件) 如文本文件、图片、程序文件等。 目录文件:d(directory) 用来存放其他文件或子目录。 设备…...

盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...

PL0语法,分析器实现!
简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...
C# SqlSugar:依赖注入与仓储模式实践
C# SqlSugar:依赖注入与仓储模式实践 在 C# 的应用开发中,数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护,许多开发者会选择成熟的 ORM(对象关系映射)框架,SqlSugar 就是其中备受…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
代码随想录刷题day30
1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币,另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额,返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...

Python Ovito统计金刚石结构数量
大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要: 近期,在使用较新版本的OpenSSH客户端连接老旧SSH服务器时,会遇到 "no matching key exchange method found", "n…...