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

从零手写Spring IoC容器(二):bean的定义与注册

从零手写Spring IoC容器(二):bean的定义与注册

一. 回顾简单容器的不足之处

在第一章中,我们实现了一个最简单的 IoC 容器,但该版本存在诸多不足,例如:

  • Bean 的管理方式过于简单,无法描述 Bean 之间的依赖关系。
  • 缺少 Bean 作用域的管理,无法区分单例(singleton)和原型(prototype)。
  • 无法设置 Bean 的属性,不能进行依赖注入。
  • 没有生命周期管理,无法进行初始化与销毁操作。

为了克服上述缺陷,我们需要引入 Bean 的定义与注册机制

二. 问题分析

1. 如何描述 Bean?

为了更灵活地管理 Bean,我们需要对其进行更详细的描述:

  • 类信息(Bean 的具体实现类)
  • 配置信息(属性值、环境相关配置)
  • 依赖关系(需要注入哪些其他 Bean)
2. 如何管理 Bean 的定义?

IoC 容器不仅需要存储 Bean,还需要提供完善的管理机制:

  • 统一注册机制:能够注册、移除、获取 Bean 定义。
  • 运行时切换:支持不同的 Bean 作用域,例如单例(singleton)或原型(prototype)。
  • 依赖分析和注入:支持属性注入,确保 Bean 能够正确构造。

三. 设计 BeanDefinition

我们先设计 BeanDefinition 接口来描述 Bean:

  • 包含 Bean 的完整信息
  • 支持属性配置
  • 支持作用域管理
  • 支持生命周期方法

1.设计BeanDefinition 接口

package com.fth.beans.factory.config;/*** 用于描述 Bean 的定义*/
public interface BeanDefinition {// Bean 作用域常量String SCOPE_SINGLETON = "singleton";String SCOPE_PROTOTYPE = "prototype";// 基本信息void setBeanClass(Class<?> beanClass);Class<?> getBeanClass();// 作用域void setScope(String scope);String getScope();boolean isSingleton();boolean isPrototype();// 是否延迟初始化void setLazyInit(boolean lazyInit);boolean isLazyInit();// 生命周期方法void setInitMethodName(String initMethodName);String getInitMethodName();void setDestroyMethodName(String destroyMethodName);String getDestroyMethodName();// 属性void setPropertyValues(PropertyValues propertyValues);PropertyValues getPropertyValues();
}
2. PropertyValuePropertyValues

PropertyValue 用于存储单个 Bean 属性的信息,而 PropertyValues 作为容器,存储 Bean 的所有属性。

package com.fth.beans.factory.config;/*** Bean 属性值的封装类*/
public class PropertyValue {private final String name;private final Object value;private final Class<?> type;/*** 创建一个新的 PropertyValue 实例*/public PropertyValue(String name, Object value, Class<?> type) {if (name == null || name.isEmpty()) {throw new IllegalArgumentException("Property name must not be null or empty");}this.name = name;this.value = value;this.type = type;}/*** 不指定类型的 PropertyValue 构造方法*/public PropertyValue(String name, Object value) {this(name, value, value != null ? value.getClass() : Object.class);}public String getName() {return this.name;}public Object getValue() {return this.value;}public Class<?> getType() {return this.type;}@Overridepublic boolean equals(Object other) {if (this == other) {return true;}if (!(other instanceof PropertyValue)) {return false;}return this.name.equals(((PropertyValue) other).name);}@Overridepublic int hashCode() {return this.name.hashCode();}@Overridepublic String toString() {return "PropertyValue: name='" + this.name + "', value=[" + this.value + "]";}
}

3.实现BeanDefinition

GenericBeanDefinitionBeanDefinition 的一个具体实现,用于存储 Bean 的元数据。

package com.fth.beans.factory.support;import com.fth.beans.factory.config.BeanDefinition;
import com.fth.beans.factory.config.PropertyValues;/*** 通用 BeanDefinition 实现*/
public class GenericBeanDefinition implements BeanDefinition {private Class<?> beanClass;private String scope = SCOPE_SINGLETON;private boolean lazyInit = false;private String initMethodName;private String destroyMethodName;private PropertyValues propertyValues = new PropertyValues();@Overridepublic void setBeanClass(Class<?> beanClass) {this.beanClass = beanClass;}@Overridepublic Class<?> getBeanClass() {return this.beanClass;}@Overridepublic void setScope(String scope) {this.scope = scope;}@Overridepublic String getScope() {return this.scope;}@Overridepublic boolean isSingleton() {return SCOPE_SINGLETON.equals(this.scope);}@Overridepublic boolean isPrototype() {return SCOPE_PROTOTYPE.equals(this.scope);}@Overridepublic void setLazyInit(boolean lazyInit) {this.lazyInit = lazyInit;}@Overridepublic boolean isLazyInit() {return this.lazyInit;}@Overridepublic void setInitMethodName(String initMethodName) {this.initMethodName = initMethodName;}@Overridepublic String getInitMethodName() {return this.initMethodName;}@Overridepublic void setDestroyMethodName(String destroyMethodName) {this.destroyMethodName = destroyMethodName;}@Overridepublic String getDestroyMethodName() {return this.destroyMethodName;}@Overridepublic void setPropertyValues(PropertyValues propertyValues) {this.propertyValues = propertyValues;}@Overridepublic PropertyValues getPropertyValues() {return this.propertyValues;}
}

四. 设计 BeanDefinitionRegistry

为了注册和管理 Bean 定义,我们设计 BeanDefinitionRegistry 接口:

package com.fth.beans.factory.support;import com.fth.beans.factory.config.BeanDefinition;/*** BeanDefinition 注册表*/
public interface BeanDefinitionRegistry {void registerBeanDefinition(String beanName, BeanDefinition beanDefinition);void removeBeanDefinition(String beanName);BeanDefinition getBeanDefinition(String beanName);boolean containsBeanDefinition(String beanName);String[] getBeanDefinitionNames();int getBeanDefinitionCount();
}

五.实现第二版 IoC 容器

我们现在基于 BeanDefinitionBeanDefinitionRegistry 来实现一个基本的 IoC 容器,支持手动注册 BeanDefinition,并能够根据 BeanDefinition 创建 Bean 实例,同时支持 单例原型 两种作用域。

1. 设计 DefaultBeanFactory

DefaultBeanFactory 负责:

  • 维护 BeanDefinition 的注册表
  • 根据 BeanDefinition 创建 Bean
  • 处理单例和原型作用域
package com.fth.beans.factory.support;import com.fth.beans.BeansException;
import com.fth.beans.factory.BeanFactory;
import com.fth.beans.factory.config.BeanDefinition;
import com.fth.beans.factory.config.BeanDefinitionRegistry;import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;/*** 默认 Bean 工厂,负责管理 BeanDefinition 和 Bean 实例*/
public class DefaultBeanFactory implements BeanDefinitionRegistry, BeanFactory {// 存储 BeanDefinitionprivate final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>();// 存储单例 Beanprivate final Map<String, Object> singletonObjects = new ConcurrentHashMap<>();// === 实现 BeanDefinitionRegistry ===@Overridepublic void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) {beanDefinitionMap.put(beanName, beanDefinition);// 如果是单例且非懒加载,则立即创建实例if (beanDefinition.isSingleton() && !beanDefinition.isLazyInit()) {singletonObjects.put(beanName, createBean(beanDefinition));}}@Overridepublic void removeBeanDefinition(String beanName) {beanDefinitionMap.remove(beanName);singletonObjects.remove(beanName);}@Overridepublic BeanDefinition getBeanDefinition(String beanName) {return beanDefinitionMap.get(beanName);}@Overridepublic boolean containsBeanDefinition(String beanName) {return beanDefinitionMap.containsKey(beanName);}@Overridepublic String[] getBeanDefinitionNames() {return beanDefinitionMap.keySet().toArray(new String[0]);}@Overridepublic int getBeanDefinitionCount() {return beanDefinitionMap.size();}// === 实现 BeanFactory ===@Overridepublic Object getBean(String name) throws BeansException {BeanDefinition beanDefinition = getBeanDefinition(name);if (beanDefinition == null) {throw new BeansException("No bean named '" + name + "' is defined");}if (beanDefinition.isSingleton()) {return singletonObjects.computeIfAbsent(name, k -> createBean(beanDefinition));}return createBean(beanDefinition);}@Overridepublic <T> T getBean(String name, Class<T> requiredType) throws BeansException {Object bean = getBean(name);if (!requiredType.isInstance(bean)) {throw new BeansException("Bean named '" + name + "' is not of type " + requiredType.getName());}return requiredType.cast(bean);}@Overridepublic <T> T getBean(Class<T> requiredType) throws BeansException {for (String beanName : beanDefinitionMap.keySet()) {Object bean = getBean(beanName);if (requiredType.isInstance(bean)) {return requiredType.cast(bean);}}throw new BeansException("No bean of type " + requiredType.getName() + " is defined");}@Overridepublic boolean containsBean(String name) {return beanDefinitionMap.containsKey(name);}@Overridepublic boolean isSingleton(String name) throws BeansException {BeanDefinition beanDefinition = getBeanDefinition(name);return beanDefinition != null && beanDefinition.isSingleton();}@Overridepublic boolean isPrototype(String name) throws BeansException {BeanDefinition beanDefinition = getBeanDefinition(name);return beanDefinition != null && beanDefinition.isPrototype();}@Overridepublic Class<?> getType(String name) throws BeansException {BeanDefinition beanDefinition = getBeanDefinition(name);return (beanDefinition != null) ? beanDefinition.getBeanClass() : null;}/*** 根据 BeanDefinition 创建 Bean 实例*/private Object createBean(BeanDefinition beanDefinition) {try {// 获取无参构造函数Constructor<?> constructor = beanDefinition.getBeanClass().getDeclaredConstructor();constructor.setAccessible(true);  // 设置可访问return constructor.newInstance();  // 使用构造函数创建实例} catch (Exception e) {throw new RuntimeException("Failed to create bean: " + beanDefinition.getBeanClass(), e);}}
}

2.测试使用

package com.fth.test;import com.fth.beans.factory.BeanFactory;
import com.fth.beans.factory.support.DefaultBeanFactory;
import com.fth.beans.factory.support.GenericBeanDefinition;/*** 测试 IoC 容器*/
public class BeanFactoryTest {public static void main(String[] args) {// 创建 BeanFactoryDefaultBeanFactory beanFactory = new DefaultBeanFactory();// 注册一个单例 BeanGenericBeanDefinition singletonDefinition = new GenericBeanDefinition();singletonDefinition.setBeanClass(TestService.class);singletonDefinition.setScope(GenericBeanDefinition.SCOPE_SINGLETON);beanFactory.registerBeanDefinition("testService", singletonDefinition);// 获取单例 BeanTestService service1 = beanFactory.getBean("testService", TestService.class);TestService service2 = beanFactory.getBean("testService", TestService.class);System.out.println("service1 == service2: " + (service1 == service2)); // true// 注册一个原型 BeanGenericBeanDefinition prototypeDefinition = new GenericBeanDefinition();prototypeDefinition.setBeanClass(TestService.class);prototypeDefinition.setScope(GenericBeanDefinition.SCOPE_PROTOTYPE);beanFactory.registerBeanDefinition("prototypeService", prototypeDefinition);// 获取原型 BeanTestService proto1 = beanFactory.getBean("prototypeService", TestService.class);TestService proto2 = beanFactory.getBean("prototypeService", TestService.class);System.out.println("proto1 == proto2: " + (proto1 == proto2)); // false}
}/*** 测试用 Bean*/
class TestService {public void sayHello() {System.out.println("Hello from TestService!");}
}

六.与Spring的对比与下一步实现

与Spring的对比

1. Bean 的注册与获取
  • Spring:
    • Spring 使用 ApplicationContext 来管理 Bean。
    • Bean 的定义可以通过注解、XML 配置或者 Java 配置类来进行。
    • ApplicationContext 允许根据名称或类型来获取 Bean,并且支持 Bean 的自动装配。
  • 自定义 IoC 容器:
    • 在自定义容器中,我们通过手动注册 BeanDefinitionBeanFactory 来管理 Bean。
    • 目前的实现只能通过名称获取单个 Bean,且只支持单例和原型的基本功能。
2. Bean 的生命周期管理
  • Spring:
    • Spring 提供了丰富的生命周期管理功能,例如:
      • 初始化方法:支持 @PostConstruct 注解、init-method 属性等。
      • 销毁方法:支持 @PreDestroy 注解、destroy-method 属性等。
      • BeanPostProcessor:可以在 Bean 初始化前后执行特定操作。
      • ApplicationContextAware、BeanFactoryAware 等:使 Bean 可以访问容器的相关信息。
  • 自定义 IoC 容器:
    • 当前实现没有处理 Bean 的初始化、销毁等生命周期管理,功能相对简单,主要关注 Bean 的创建和作用域(单例、原型)。
3. 作用域管理
  • Spring:
    • Spring 支持多种作用域,包括:
      • singleton(默认):每个 Bean 在容器中只有一个实例。
      • prototype:每次请求都会返回一个新的 Bean 实例。
      • request, session, application 等:在 Web 环境下,Spring 支持更多基于 HTTP 请求的作用域。
  • 自定义 IoC 容器:
    • 当前实现仅支持 singletonprototype 两种作用域。
4. 自动装配与依赖注入
  • Spring:
    • Spring 支持基于注解(如 @Autowired)和 XML 配置的自动装配。
    • 可以自动解析 Bean 之间的依赖关系,通过构造函数、Setter 或字段注入方式注入依赖。
  • 自定义 IoC 容器:
    • 当前版本没有实现依赖注入和自动装配,需要手动处理 Bean 的依赖关系。

下一步安排:Bean 的生命周期管理

为了让自定义的 IoC 容器更加完善,下一步实现 Bean 的生命周期管理,这包括以下几个方面:

1. 初始化与销毁
  • 初始化方法:可以为每个 Bean 定义一个初始化方法,在 Bean 创建后、依赖注入完成后执行。
  • 销毁方法:可以为每个 Bean 定义销毁方法,在 Bean 被销毁前执行,释放资源。
2. 添加 BeanPostProcessor 机制

Spring 提供了 BeanPostProcessor 接口,允许开发者在 Bean 初始化前后执行特定操作。你可以在自定义容器中实现类似机制:

  • 初始化前:在 Bean 实例化后、依赖注入前执行。
  • 初始化后:在 Bean 初始化完成后执行。

相关文章:

从零手写Spring IoC容器(二):bean的定义与注册

从零手写Spring IoC容器&#xff08;二&#xff09;&#xff1a;bean的定义与注册 一. 回顾简单容器的不足之处 在第一章中&#xff0c;我们实现了一个最简单的 IoC 容器&#xff0c;但该版本存在诸多不足&#xff0c;例如&#xff1a; Bean 的管理方式过于简单&#xff0c;…...

《大模型面试宝典》(2025版) 发布了

基于去年我们写的《大模型面试宝典》(2024版)的基础上&#xff0c;我根据自己实践经验和星球小伙伴的面经分享总结推出《大模型面试宝典》(2025版)&#xff0c;共计52w字。 与去年相比&#xff0c;内容增加了星球成员面试真题分享、大模型最新考试要点总结、DeepSeek 项目实战…...

AWS门店人流量数据分析项目的设计与实现

这是一个AWS的数据分析项目&#xff0c;关于快消公司门店手机各个门店进店人流量和各个产品柜台前逗留时间&#xff08;利用IoT设备采集&#xff09;和销售数据之间的统计分析&#xff0c;必须用到但不限于Amazon Kensis Data Stream&#xff0c;Spark Streaming&#xff0c;Sp…...

出租车特殊计费表算法解析与实现

目录 引言算法核心概念 特殊计费规则解析数据类型与输入输出算法数学原理 数字位判断与处理逻辑数值转换与累加计算算法框架图Python 实现 代码展示代码解析Python 实现的优势与局限C 语言实现 代码展示代码解析C 语言实现的性能特点性能分析与优化 性能分析 时间复杂度空间复杂…...

文档解析技术:如何高效提取PDF扫描件中的文字与表格信息?

想要高效提取PDF扫描件中的文字与表格信息&#xff0c;通常需要借助专业的工具或在线服务&#xff0c;以下是一些可行的方法&#xff1a; 预处理扫描件&#xff1a;在提取文字之前&#xff0c;尽量确保扫描件的图像质量清晰。如果扫描件模糊或有污渍&#xff0c;可以使用图像处…...

【2】高并发导出场景下,服务器性能瓶颈优化方案-异步导出

Java 异步导出是一种在处理大量数据或复杂任务时优化性能和用户体验的重要技术。 1. 异步导出的优势 异步导出是指将导出操作从主线程中分离出来&#xff0c;通过后台线程或异步任务完成数据处理和文件生成。这种方式可以显著减少用户等待时间&#xff0c;避免系统阻塞&#x…...

【DeepSeek论文精读】6. DeepSeek R1:通过强化学习激发大语言模型的推理能力

欢迎关注[【youcans的AGI学习笔记】](https://blog.csdn.net/youcans/category_12244543.html&#xff09;原创作品 【DeepSeek论文精读】1. 从 DeepSeek LLM 到 DeepSeek R1 【DeepSeek论文精读】6. DeepSeek R1&#xff1a;通过强化学习激发大语言模型的推理能力 【DeepSeek论…...

frida 通过 loadLibrary0 跟踪 System.loadLibrary

static {System.loadLibrary("libxxx.so"); }在 ndk 开发中&#xff0c;常见的实践是在 static 代码块里调用 loadLibrary 加载动态库。由于 apk 从 java 层开始启动&#xff0c;过早地 hook 原生代码会找不到函数。所以一种常见做法是在 loadLibrary 的 hook 回调里…...

【2025最新计算机毕业设计】基于SSM的智能停车场管理系统【提供源码+答辩PPT+文档+项目部署】(高质量源码,可定制,提供文档,免费部署到本地)

作者简介&#xff1a;✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流。✌ 主要内容&#xff1a;&#x1f31f;Java项目、Python项目、前端项目、PHP、ASP.NET、人工智能…...

【含文档+PPT+源码】Python爬虫人口老龄化大数据分析平台的设计与实现

项目介绍 本课程演示的是一款Python爬虫人口老龄化大数据分析平台的设计与实现&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的 Python学习者。 1.包含&#xff1a;项目源码、项目文档、数据库脚本、软件工具等所有资料 2.带你从零开始部署运行本…...

文本生图的提示词prompt和参数如何设置(基于Animagine XL V3.1)

昨天搞了半天 Animagine XL V3.1&#xff0c;发现市面上很多教程只是授之以鱼&#xff0c;并没有授之以渔的。也是&#xff0c;拿来赚钱不好吗&#xff0c;闲鱼上部署一个 Deepseek 都能要两百块。这里我还是想写篇文章介绍一下&#xff0c;虽不全面&#xff0c;但是尽量告诉你…...

快速提取Excel工作簿中所有工作表的名称?

大家好&#xff0c;我是小鱼。 在Excel表格中如何快速提取工作簿中所有工作表的名称&#xff1f;这个问题在日常工作中也经常遇到&#xff0c;比如说经常使用的INDIRECT函数跨工作表汇总或者制作类似于导航的工作表快捷跳转列表&#xff0c;就需要每个工作表的名称。如果工作表…...

【紫光同创PG2L100H开发板】盘古676系列,盘古100Pro+开发板,MES2L676-100HP

本原创文章由深圳市小眼睛科技有限公司创作&#xff0c;版权归本公司所有&#xff0c;如需转载&#xff0c;需授权并注明出处&#xff08;www.meyesemi.com) 一&#xff1a;开发系统介绍 开发系统概述 MES2L676-100HP开发板采用紫光创 logos2系列 FPGA&#xff0c;型号&#x…...

Node.JS 版本管理工具 Fnm 安装及配置(Windows)

Fnm 安装及配置&#xff08;Windows&#xff09; Fnm&#xff08;Fast Node Manager&#xff09;?? 一个快速而简单的 Node.js 版本管理工具&#xff0c;使用 Rust 编写。 1 安装 官网&#xff1a;Fnm&#xff08;镜像网站 &#xff09;。 下载&#xff1a;Fnm&#xff08…...

labview通过时间计数器来设定采集频率

在刚接触labview的时候&#xff0c;笔者通常用定时里的等待函数来实现指令的收发&#xff0c;但是当用到的收发消息比较多时就出现了卡顿&#xff0c;卡死的情况&#xff0c;这是因为当用队列框架时&#xff0c;程序卡在了其中的一个分支里&#xff0c;等通过相应的延时后才可以…...

汇编JCC条件跳转指令记忆

汇编中的条件跳转指令&#xff08;JCC&#xff09;&#xff1a; 1. 理解标志寄存器 JCC 指令依赖于标志寄存器&#xff08;FLAGS&#xff09;的状态&#xff0c;常见的标志位有&#xff1a; ZF&#xff08;Zero Flag&#xff09;&#xff1a;结果为0时置1。 CF&#xff08;Ca…...

HTML排版标签、语义化标签、块级和行内元素详解

目录 前言 一、HTML中的排版标签 1. 文本相关标签 1.1 标题标签 ~ 1.2 段落标签 1.3 强调和加粗 1.4 换行标签 1.5 水平线标签 二、HTML中的语义化标签 2.1 语义化标签概述 2.2 常见的语义化标签 示例&#xff08;核心代码部分&#xff09;&#xff1a; 三、HTM…...

【回溯+剪枝】单词搜索,你能用递归解决吗?

文章目录 79. 单词搜索解题思路&#xff1a;回溯&#xff08;深搜&#xff09; 剪枝 79. 单词搜索 79. 单词搜索 ​ 给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 …...

《深度揭秘LDA:开启人工智能降维与分类优化的大门》

在当今人工智能蓬勃发展的时代&#xff0c;数据成为了驱动技术进步的核心要素。随着数据采集和存储技术的飞速发展&#xff0c;我们所面临的数据量不仅日益庞大&#xff0c;其维度也愈发复杂。高维数据虽然蕴含着丰富的信息&#xff0c;但却给机器学习算法带来了一系列严峻的挑…...

Linux(CentOS)安装 MySQL

CentOS版本&#xff1a;CentOS 7 三种安装方式&#xff1a; 一、通过 yum 安装&#xff0c;最简单&#xff0c;一键安装&#xff0c;全程无忧。 二、通过 rpm 包安装&#xff0c;需具备基础概念及常规操作。 三、通过 gz 包安装&#xff0c;需具备配置相关操作。 --------…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)

0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述&#xff0c;后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作&#xff0c;其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

关于nvm与node.js

1 安装nvm 安装过程中手动修改 nvm的安装路径&#xff0c; 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解&#xff0c;但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后&#xff0c;通常在该文件中会出现以下配置&…...

数据链路层的主要功能是什么

数据链路层&#xff08;OSI模型第2层&#xff09;的核心功能是在相邻网络节点&#xff08;如交换机、主机&#xff09;间提供可靠的数据帧传输服务&#xff0c;主要职责包括&#xff1a; &#x1f511; 核心功能详解&#xff1a; 帧封装与解封装 封装&#xff1a; 将网络层下发…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…...

关于 WASM:1. WASM 基础原理

一、WASM 简介 1.1 WebAssembly 是什么&#xff1f; WebAssembly&#xff08;WASM&#xff09; 是一种能在现代浏览器中高效运行的二进制指令格式&#xff0c;它不是传统的编程语言&#xff0c;而是一种 低级字节码格式&#xff0c;可由高级语言&#xff08;如 C、C、Rust&am…...

【JavaSE】绘图与事件入门学习笔记

-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角&#xff0c;以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向&#xff0c;距离坐标原点x个像素;第二个是y坐标&#xff0c;表示当前位置为垂直方向&#xff0c;距离坐标原点y个像素。 坐标体系-像素 …...

C++ 设计模式 《小明的奶茶加料风波》

&#x1f468;‍&#x1f393; 模式名称&#xff1a;装饰器模式&#xff08;Decorator Pattern&#xff09; &#x1f466; 小明最近上线了校园奶茶配送功能&#xff0c;业务火爆&#xff0c;大家都在加料&#xff1a; 有的同学要加波霸 &#x1f7e4;&#xff0c;有的要加椰果…...

论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing

Muffin 论文 现有方法 CRADLE 和 LEMON&#xff0c;依赖模型推理阶段输出进行差分测试&#xff0c;但在训练阶段是不可行的&#xff0c;因为训练阶段直到最后才有固定输出&#xff0c;中间过程是不断变化的。API 库覆盖低&#xff0c;因为各个 API 都是在各种具体场景下使用。…...

上位机开发过程中的设计模式体会(1):工厂方法模式、单例模式和生成器模式

简介 在我的 QT/C 开发工作中&#xff0c;合理运用设计模式极大地提高了代码的可维护性和可扩展性。本文将分享我在实际项目中应用的三种创造型模式&#xff1a;工厂方法模式、单例模式和生成器模式。 1. 工厂模式 (Factory Pattern) 应用场景 在我的 QT 项目中曾经有一个需…...

LLaMA-Factory 微调 Qwen2-VL 进行人脸情感识别(二)

在上一篇文章中,我们详细介绍了如何使用LLaMA-Factory框架对Qwen2-VL大模型进行微调,以实现人脸情感识别的功能。本篇文章将聚焦于微调完成后,如何调用这个模型进行人脸情感识别的具体代码实现,包括详细的步骤和注释。 模型调用步骤 环境准备:确保安装了必要的Python库。…...