spring重点面试题总结
bean的生命周期
在 Spring 中,BeanDefinition
、Bean 实例化、依赖注入、Aware
接口的处理、以及 BeanPostProcessor
的前置和后置处理等,都是 Spring 容器管理 Bean 生命周期的关键部分。下面我将详细解释这些过程。
1. 通过 BeanDefinition
获取 Bean 的定义信息
BeanDefinition
是 Spring 容器中用于描述 Bean 的元数据的接口,包含了 Bean 的配置和信息,如 Bean 的类名、构造参数、属性等。通过 BeanDefinition
,Spring 容器可以知道如何实例化 Bean。
-
获取 BeanDefinition 示例:
Spring 容器在启动时,会加载并解析所有的配置(如 XML 配置文件、注解配置、Java 配置类等),将每个 Bean 的配置存储在BeanDefinition
中。BeanFactory beanFactory = new AnnotationConfigApplicationContext(AppConfig.class); BeanDefinition beanDefinition = beanFactory.getBeanDefinition("myBean"); String beanClassName = beanDefinition.getBeanClassName();
-
BeanDefinition
的常见方法:getBeanClassName()
:获取 Bean 的类名。getPropertyValues()
:获取 Bean 的属性值。getConstructorArgumentValues()
:获取 Bean 的构造方法参数。
2. 调用构造函数实例化 Bean
Spring 通过反射调用构造函数来实例化 Bean。在实例化过程中,Spring 会选择合适的构造器,并根据配置提供的构造参数来实例化对象。
- 步骤:
- Spring 通过
BeanDefinition
中的类名和构造方法配置,选择一个构造方法。 - 如果有构造方法参数(例如在 XML 配置中或注解中配置了构造器注入),Spring 会从配置中获取并注入这些参数。
- 使用反射调用构造函数创建 Bean 实例。
- Spring 通过
例如:
@Bean
public MyBean myBean() {return new MyBean("arg1", 2);
}
3. Bean 的依赖注入
依赖注入是 Spring 中实现控制反转(IoC)的核心机制。Spring 会根据配置将 Bean 的依赖自动注入到 Bean 中。
-
依赖注入的方式:
- 构造器注入:通过 Bean 的构造方法传入依赖。
- Setter 方法注入:通过设置属性的 setter 方法传入依赖。
- 字段注入:通过反射直接注入字段。
-
Spring 如何注入依赖:
- 对于构造器注入,Spring 会根据
@Autowired
注解或 XML 配置来自动匹配依赖的类型。 - 对于字段注入和 setter 注入,Spring 会将依赖通过反射注入到 Bean 中。
- 对于构造器注入,Spring 会根据
4. 处理 Aware 接口(BeanNameAware
、BeanFactoryAware
、ApplicationContextAware
)
Spring 提供了一些接口,让 Bean 在初始化过程中能够访问到容器的相关信息。通过实现这些接口,Bean 可以获得更多的容器信息,如其自身的 Bean 名称、BeanFactory 或 ApplicationContext。
-
BeanNameAware
:通过setBeanName()
方法获取当前 Bean 在容器中的名称。public class MyBean implements BeanNameAware {@Overridepublic void setBeanName(String name) {System.out.println("Bean name is: " + name);} }
-
BeanFactoryAware
:通过setBeanFactory()
方法获得当前 BeanFactory 实例,可以访问容器中的其他 Bean。public class MyBean implements BeanFactoryAware {@Overridepublic void setBeanFactory(BeanFactory beanFactory) {System.out.println("BeanFactory is: " + beanFactory);} }
-
ApplicationContextAware
:通过setApplicationContext()
方法获得当前 ApplicationContext 实例,从而能够访问 Spring 环境和其他 Bean。public class MyBean implements ApplicationContextAware {@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {System.out.println("ApplicationContext is: " + applicationContext);} }
5. Bean 的后置处理器(BeanPostProcessor
)- 前置处理
BeanPostProcessor
是一个接口,允许在 Bean 初始化的前后对 Bean 进行修改。Spring 会自动检测容器中实现了 BeanPostProcessor
接口的类,并在每个 Bean 初始化之前和之后调用相应的方法。
-
postProcessBeforeInitialization
:在 Bean 初始化之前调用,允许你修改 Bean 的属性或执行一些额外的操作。public class MyBeanPostProcessor implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {System.out.println("Before initialization: " + beanName);return bean; // 返回修改后的 Bean 对象} }
这里,
postProcessBeforeInitialization
方法在 Bean 的初始化方法(如@PostConstruct
或afterPropertiesSet()
)之前被调用。
6. 初始化方法(InitializingBean
、init-method
)
-
InitializingBean
接口:afterPropertiesSet()
方法会在所有的属性都设置完毕后调用,通常用于进行 Bean 的初始化操作。public class MyBean implements InitializingBean {@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("Bean has been initialized");} }
-
@PostConstruct
注解:这个注解标记的方法会在所有的依赖注入完成之后、Bean 初始化之前调用。public class MyBean {@PostConstructpublic void init() {System.out.println("Bean initialized using @PostConstruct");} }
-
自定义初始化方法:在 XML 配置文件中,或者 Java 配置类中,可以通过
init-method
配置一个自定义的初始化方法。<bean id="myBean" class="com.example.MyBean" init-method="init">... </bean>
@Bean(initMethod = "init") public MyBean myBean() {return new MyBean(); }
7. Bean 的后置处理器(BeanPostProcessor
)- 后置处理
BeanPostProcessor
接口还提供了 postProcessAfterInitialization
方法,该方法在 Bean 初始化完成后调用。这个方法可以用于对已经初始化的 Bean 进行修改或增强(如 AOP)。
-
postProcessAfterInitialization
:在 Bean 初始化之后调用,通常用于处理 Bean 的代理或日志功能等。public class MyBeanPostProcessor implements BeanPostProcessor {@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {System.out.println("After initialization: " + beanName);return bean; // 返回修改后的 Bean 对象} }
8. 使用(Usage)
-
发生时机:初始化完成后,Spring Bean 就可以进入应用程序的使用阶段。
-
具体操作:
- 这时,Spring Bean 已经是完整的,可以被应用程序中的其他组件或类通过
@Autowired
自动注入、手动查找或通过其它方式使用。 - Bean 可以被正常使用,比如进行方法调用或响应 HTTP 请求等。
- 这时,Spring Bean 已经是完整的,可以被应用程序中的其他组件或类通过
-
关键点:
- 在这个阶段,Bean 已经完全初始化,所有的依赖都已注入,并且初始化方法也已执行。
9. 销毁前处理(Post-process Before Destruction)
-
发生时机:在容器销毁之前,Spring 会进行销毁前的处理。
-
具体操作:
- 如果 Bean 实现了
DisposableBean
接口,Spring 会调用destroy()
方法。 - 如果 Bean 使用了
@PreDestroy
注解,Spring 会在销毁之前调用该方法。 - 如果 Bean 配置了自定义销毁方法(在 XML 配置中通过
destroy-method
或者 Java 配置类中的@Bean(destroyMethod = "...")
),Spring 会调用该方法。
- 如果 Bean 实现了
-
关键点:
- 这个阶段主要是进行资源的释放工作,比如关闭文件流、数据库连接、清理缓存等操作。
10. 销毁(Destruction)
-
发生时机:Spring 容器关闭时,销毁所有的 Bean。
-
具体操作:
- Spring 会在容器销毁之前,销毁所有的 Bean。这个过程包括:
- 释放所有与 Bean 相关的资源。
- 如果 Bean 是
singleton
(单例模式),那么销毁时会调用销毁方法。 - 对于
prototype
(原型模式)Bean,Spring 不负责销毁,通常需要开发者手动销毁。
- Spring 会在容器销毁之前,销毁所有的 Bean。这个过程包括:
-
关键点:
- 容器关闭时,Spring 会销毁所有在容器中管理的 Bean,并释放相应的资源。特别是对于单例 Bean,销毁时会执行注册的销毁方法。
生命周期钩子接口和注解
InitializingBean
和DisposableBean
:这两个接口提供了回调方法(afterPropertiesSet()
和destroy()
)来进行初始化和销毁的自定义操作。@PostConstruct
和@PreDestroy
:Java 注解,分别用于定义初始化和销毁方法。BeanPostProcessor
:可以在 Bean 初始化前后进行处理,常用于 AOP 或修改 Bean 实例。
通过这些不同的阶段和钩子方法,Spring 提供了非常灵活的 Bean 生命周期管理机制,允许开发者定制 Bean 的行为。
总结
Spring 的 Bean 生命周期包括从 Bean 的定义、实例化、依赖注入,到初始化、销毁等多个阶段。在这个过程中,BeanDefinition
提供了 Bean 的配置信息,Spring 会通过反射实例化 Bean,并通过注入不同的依赖来完成 Bean 的构建。BeanPostProcessor
在 Bean 初始化前后提供了扩展点,允许开发者进行自定义的 Bean 修改和增强。同时,通过实现 Aware
接口,Bean 可以获取到容器的一些元数据,从而进一步增强 Bean 的功能。
什么是 Spring 的循环依赖问题?
定义
- 循环依赖指的是两个或多个 Bean 之间互相依赖,形成一个依赖环。例如:
- Bean A 依赖 Bean B,而 Bean B 又依赖 Bean A。
- 更复杂的情况是多个 Bean 相互嵌套依赖,比如 A → B → C → A。
问题出现的场景
- 在 Spring 容器中,Bean 的实例化、初始化是分步骤进行的。如果 Bean 需要其依赖的对象,但该对象还未完成创建,就会导致循环依赖问题。
2. Spring Bean 的创建流程
- 实例化 (Instantiation): 创建 Bean 的原始对象(通过构造器或工厂方法)。
- 属性注入 (Populate Properties): 将依赖的其他 Bean 注入到当前 Bean。
- 初始化 (Initialization): 执行
@PostConstruct
方法、InitializingBean
的回调等初始化逻辑。 - 完成 Bean 创建: Bean 准备好供其他对象使用。
问题出现点:
- 如果两个 Bean 在属性注入阶段互相依赖,Spring 会因依赖未完成而报错。
3. 循环依赖的分类
-
构造器循环依赖:
- 两个或多个 Bean 的构造函数中互相依赖。
- 例如:
@Component public class A {public A(B b) {} }@Component public class B {public B(A a) {} }
- 特点: Spring 无法解决,直接报错,因为在实例化阶段就需要依赖,Spring 没法提前暴露 Bean。
-
字段/Setter 循环依赖:
- 两个或多个 Bean 通过字段或 Setter 方法互相依赖。
- 例如:
@Component public class A {@Autowiredprivate B b; }@Component public class B {@Autowiredprivate A a; }
- 特点: Spring 可以通过 三级缓存 解决。
4. Spring 的解决办法
4.1. 三级缓存机制
Spring 通过三级缓存机制解决 字段/Setter 循环依赖:
-
单例池(一级缓存):
- 保存已经完成初始化的单例 Bean。
singletonObjects
映射:{beanName: beanInstance}
。
-
早期曝光的单例 Bean(二级缓存):
- 保存半成品(实例化但未初始化完成的 Bean)。
earlySingletonObjects
映射:{beanName: earlyBeanInstance}
。
-
单例工厂(三级缓存):
- 保存一个工厂方法,用于生成早期 Bean。
singletonFactories
映射:{beanName: ObjectFactory}
。
4.2. 三级缓存的工作流程
-
实例化阶段:
- 创建 Bean 的实例,但未注入依赖。
- 将工厂方法(
ObjectFactory
)放入三级缓存singletonFactories
中。
-
属性注入阶段:
- 如果 Bean 依赖另一个 Bean,而该 Bean 还未完全初始化:
- 从一级缓存中尝试获取。
- 如果一级缓存未命中,从二级缓存中获取。
- 如果二级缓存仍未命中,从三级缓存中获取,并通过工厂方法生成早期 Bean,随后将其移动到二级缓存。
- 如果 Bean 依赖另一个 Bean,而该 Bean 还未完全初始化:
-
初始化完成后:
- 将完全初始化的 Bean 从二级缓存移动到一级缓存,并从其他缓存中移除。
4.3. 为什么需要三级缓存?
-
问题一:只有一级缓存时
- 只能存放完全初始化完成的 Bean,对于循环依赖无法处理,因为依赖对象未初始化完成时无法注入。
-
问题二:只有二级缓存时
- 二级缓存直接存储早期 Bean 实例,但没有工厂方法来生成代理对象。如果 Bean 是 代理对象(比如使用 AOP),无法提前暴露真实的代理对象。
-
三级缓存的作用
- 在实例化阶段,允许通过工厂方法生成代理对象,从而解决 Bean 的代理问题(如
@Transactional
或@Async
)。 - 工厂方法可以控制生成的是原始对象还是代理对象,再将其放入二级缓存。
- 在实例化阶段,允许通过工厂方法生成代理对象,从而解决 Bean 的代理问题(如
5. 示例代码
循环依赖示例
@Component
public class A {@Autowiredprivate B b;public A() {System.out.println("A is created");}public void doSomething() {System.out.println("A is working with B");}
}@Component
public class B {@Autowiredprivate A a;public B() {System.out.println("B is created");}public void doSomething() {System.out.println("B is working with A");}
}
运行输出
A is created
B is created
A is working with B
B is working with A
解析
- Spring 首先实例化 Bean
A
,但在注入B
时发现B
未完成。 - Spring 实例化 Bean
B
,发现A
尚未完成,将早期的A
暴露到三级缓存中。 - Spring 从三级缓存获取早期的
A
,完成B
的依赖注入。 - 最终完成
A
和B
的初始化。
6. 总结
-
循环依赖类型:
- 构造器循环依赖:无法解决。
- 字段/Setter 循环依赖:通过三级缓存解决。
-
三级缓存的必要性:
- 一级缓存存放完整 Bean。
- 二级缓存存放早期 Bean,但无法处理代理对象问题。
- 三级缓存通过工厂方法解决代理 Bean 的暴露问题。
-
原理优势:
- 三级缓存确保 Spring 能在复杂场景下正确地解析和初始化循环依赖的 Bean,同时支持代理对象和增强功能。
@lazy可以解决构造器循环依赖
1. @Lazy
的作用
当一个 Bean 使用 @Lazy
注解时,Spring 容器并不会在应用启动时立即实例化它,而是等到该 Bean 第一次被使用时才进行实例化。这对于减少应用启动时的初始化时间或者避免不必要的资源消耗非常有帮助。
具体来说,@Lazy
可以用于:
- 懒加载单例 Bean:使某个单例 Bean 在第一次使用时才实例化。
- 懒加载依赖:使 Bean 的依赖对象在实际需要时才被创建,而不是在 Bean 本身被实例化时就创建。
2. @Lazy
的工作原理
@Lazy
的工作原理基于 Spring 的 延迟初始化(lazy initialization)机制。具体来说,它是通过 代理机制 来实现懒加载的。当一个 Bean 被标记为 @Lazy
时,Spring 会为该 Bean 创建一个代理对象,该代理对象会在第一次被访问时才创建实际的 Bean 实例。
3. @Lazy
的实现
- 懒加载的代理:当你将一个 Bean 设置为懒加载时,Spring 会使用代理来实现懒加载。在大多数情况下,Spring 会使用 CGLIB 或 JDK 动态代理 创建代理对象。这个代理对象会在你第一次访问 Bean 时才初始化实际的 Bean 实例,并将其代理对象替换为真正的 Bean 实例。
相关文章:
spring重点面试题总结
bean的生命周期 在 Spring 中,BeanDefinition、Bean 实例化、依赖注入、Aware 接口的处理、以及 BeanPostProcessor 的前置和后置处理等,都是 Spring 容器管理 Bean 生命周期的关键部分。下面我将详细解释这些过程。 1. 通过 BeanDefinition 获取 Bean…...

新的一章:codegeex
三层结构的优点:可扩展性,可复用性...

游戏引擎学习第50天
仓库: https://gitee.com/mrxiao_com/2d_game Minkowski 这个算法有点懵逼 回顾 基本上,现在我们所处的阶段是,回顾最初的代码,我们正在讨论我们希望在引擎中实现的所有功能。我们正在做的版本是初步的、粗略的版本,涵盖我们认…...

快速理解类的加载过程
当程序主动使用某个类时,如果该类还未加载到内存中,则系统会通过如下三个步骤来对该类进行初始化: 1.加载:将class文件字节码内容加载到内存中,并将这些静态数据转换成方法区的运行时数据结构,然后生成一个…...

医院跌倒检测识别 使用YOLO,COCO ,VOC格式对4806张原始图片进行标注,可识别病人跌倒,病人的危险行为,病床等场景,预测准确率可达96.7%
医院跌倒检测识别 使用YOLO,COCO ,VOC格式对4806张原始图片进行标注,可识别病人跌倒,病人的危险行为,病床等场景,预测准确率可达96.7% 数据集分割 4806总图像数 训练组70% 3364图片 有效集20&#…...
[Unity Shader] 【游戏开发】【图形渲染】Unity Shader的种类2-顶点/片元着色器与固定函数着色器的选择与应用
Unity 提供了不同种类的 Shader,每种 Shader 有其独特的优势和适用场景。在所有类型的 Shader 中,顶点/片元着色器(Vertex/Fragment Shader)与固定函数着色器(Fixed Function Shader)是两种重要的着色器类型。尽管它们具有不同的编写方式和用途,理解其差异与应用场景,对…...
浏览器端的 js 包括哪几个部分
一、核心语言部分 1. 变量与数据类型 变量用于存储数据,在 JavaScript 中有多种数据类型,如基本数据类型(字符串、数字、布尔值、undefined、null)和引用数据类型(对象、数组、函数)。 let name "…...

GoogLeNet网络:深度学习领域的创新之作
目录 编辑 引言 GoogLeNet的核心创新:Inception模块 Inception模块的工作原理 1x1卷积:降维与减少计算量 1x1卷积的优势 深度分离卷积:计算效率的提升 深度分离卷积的实现 全局平均池化:简化网络结构 全局平均池化的作…...

深入C语言文件操作:从库函数到系统调用
引言 文件操作是编程中不可或缺的一部分,尤其在C语言中,文件操作不仅是处理数据的基本手段,也是连接程序与外部世界的重要桥梁。C语言提供了丰富的库函数来处理文件,如 fopen、fclose、fread、fwrite 等。然而,这些库…...
Java序列化
Java序列化 简单来说: 序列化是将对象的状态信息转换为可以存储或传输的形式(如字节序列)的过程。在 Java 中,通过序列化可以把一个对象保存到文件、通过网络传输到其他地方或者存储到数据库等。最直接的原因就是某些场景下需要…...

基坑表面位移沉降倾斜自动化监测 非接触式一体化解决机器视觉
基于变焦视觉位移监测仪的基坑自动化监测新方案是一种集成了光学、机械、电子、边缘计算、AI识别以及云平台软件等技术的自动化系统。该方案利用变焦机器视觉原理,结合特殊波段成像识别技术和无源靶标,实现了非接触式大空间、多断面、多测点的高精度水平…...
提升效率:精通Windows命令行的艺术
文章目录 引言1. 基本目录操作命令dir:列出目录内容cd:更改目录mkdir 和 rmdir:创建和删除目录 2. 文件操作命令copy:复制文件或目录move:移动或重命名文件/目录del:删除文件 3. 文件查看命令typeÿ…...

ESP32-S3-devKitC-1 点亮板上的WS2812 RGB LED
ESP32-S3-devKitC-1 板上自带了一个RGB LED,型号为 WS2812。 RGB LED 在板上的位置如下图所示。 为了点亮这个WS2812,需要确定这颗RGB LED连接到哪个GPIO上了。 下面是确定GPIO管脚的过程: 1、根据原理图 2、根据PCB布局图: 程…...

python调用matlab函数(内置 + 自定义) —— 安装matlab.engine
文章目录 一、简介二、安装matlab.engine2.1、基于 CMD 安装2.2、基于 MATLAB 安装(不建议) 三、python调用matlab函数(内置 自定义) 一、简介 matlab.engine(MATLAB Engine API for Python):…...

CAD c# 生成略缩图预览
代码如下: using (Transaction tr currentdb.TransactionManager.StartTransaction()){//当前数据库开启事务using (Database tempdb new Database(false, true)) //创建临时数据库(两个参数:是否创建符号表,不与当前文档关联){try{Bitmap …...

端点鉴别、安全电子邮件、TLS
文章目录 端点鉴别鉴别协议ap 1.0——发送者直接发送一个报文表明身份鉴别协议ap 2.0——ap1.0 的基础上,接收者对报文的来源IP地址进行鉴别鉴别协议ap 3.0——使用秘密口令,口令为鉴别者和被鉴别者之间共享的秘密鉴别协议ap 3.1——对秘密口令进行加密&…...

汽车电子元件的可靠性保障:AEC-Q102认证
AEC-Q102标准的起源与价值 随着汽车电子系统的日益复杂,电子器件必须能够在极端的温度、湿度、振动和电磁干扰等恶劣条件下保持性能。AEC-Q102标准由汽车电子委员会(AEC)制定,专门针对LED、激光二极管和光电二极管等光电器件&…...

主成分分析法大全(包括stata+matlab)
数据简介:主成分分析(Principal Component Analysis,PCA), 是一种统计方法。通过正交变换将一组可能存在相关性的变量转换为一组线性不相关的变量,转换后的这组变量叫主成分。在实际课题中,为了…...

ubuntu+ros新手笔记(五):初探anaconda+cuda+pytorch
深度学习三件套:初探anacondacudapytorch 系统ubuntu22.04 1.初探anaconda 1.1 安装 安装过程参照【详细】Ubuntu 下安装 Anaconda 1.2 创建和删除环境 创建新环境 conda create -n your_env_name pythonx.x比如我创建了一个名为“py312“的环境 conda cre…...
C++ List(双向链表)
是一个线性链表结构,它的数据由若干个节点构成,每一个节点都包括一个 信息块(即实际存储的数据)、一个前驱指针和一个后驱指针。它无需分配指定 的内存大小且可以任意伸缩,这是因为它存储在非连续的内存空间中&#…...

网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

19c补丁后oracle属主变化,导致不能识别磁盘组
补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...

如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...

2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...

AI书签管理工具开发全记录(十九):嵌入资源处理
1.前言 📝 在上一篇文章中,我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源,方便后续将资源打包到一个可执行文件中。 2.embed介绍 🎯 Go 1.16 引入了革命性的 embed 包,彻底改变了静态资源管理的…...

2025季度云服务器排行榜
在全球云服务器市场,各厂商的排名和地位并非一成不变,而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势,对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析: 一、全球“三巨头”…...

网站指纹识别
网站指纹识别 网站的最基本组成:服务器(操作系统)、中间件(web容器)、脚本语言、数据厍 为什么要了解这些?举个例子:发现了一个文件读取漏洞,我们需要读/etc/passwd,如…...

[大语言模型]在个人电脑上部署ollama 并进行管理,最后配置AI程序开发助手.
ollama官网: 下载 https://ollama.com/ 安装 查看可以使用的模型 https://ollama.com/search 例如 https://ollama.com/library/deepseek-r1/tags # deepseek-r1:7bollama pull deepseek-r1:7b改token数量为409622 16384 ollama命令说明 ollama serve #:…...
Kubernetes 网络模型深度解析:Pod IP 与 Service 的负载均衡机制,Service到底是什么?
Pod IP 的本质与特性 Pod IP 的定位 纯端点地址:Pod IP 是分配给 Pod 网络命名空间的真实 IP 地址(如 10.244.1.2)无特殊名称:在 Kubernetes 中,它通常被称为 “Pod IP” 或 “容器 IP”生命周期:与 Pod …...

认识CMake并使用CMake构建自己的第一个项目
1.CMake的作用和优势 跨平台支持:CMake支持多种操作系统和编译器,使用同一份构建配置可以在不同的环境中使用 简化配置:通过CMakeLists.txt文件,用户可以定义项目结构、依赖项、编译选项等,无需手动编写复杂的构建脚本…...