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

【设计模式-行为型】状态模式

一、什么是状态模式

        什么是状态模式呢,这里我举一个例子来说明,在自动挡汽车中,挡位的切换是根据驾驶条件(如车速、油门踏板位置、刹车状态等)自动完成的。这种自动切换挡位的过程可以很好地用状态模式来描述。状态模式(State Pattern) 是一种行为型设计模式,它允许一个对象在其内部状态发生变化时(加速或者减速)改变其行为(换挡)。状态模式的核心思想是将对象的行为封装在不同的状态类中,使得对象的行为随着状态的改变而改变。这种模式特别适用于对象的行为依赖于其内部状态的场景。

二、为什么使用状态模式

  1. 清晰的职责划分:代码结构清晰,每个状态类的职责单一,易于理解和维护。例如,在自动挡汽车中,每个挡位的行为都封装在独立的状态类中,职责划分明确。

  2. 动态改变行为:减少了复杂的条件分支(如 if-elseswitch-case),使代码更加简洁和可读。例如,在自动挡汽车中,换挡逻辑由状态机自动处理,无需在主逻辑中写复杂的条件判断。

  3. 扩展性:符合开闭原则(对扩展开放,对修改封闭)。例如,在自动挡汽车中,新增一个挡位(如6挡)时,只需添加一个新的状态类,无需修改现有的换挡逻辑。

  4. 低耦合:状态类和上下文类之间的依赖关系减少,提高了代码的灵活性和可维护性。例如,在自动挡汽车中,Car 类与各个挡位状态类通过 GearState 接口交互,降低了耦合度。

  5. 适应复杂状态逻辑:能够清晰地表达状态转换逻辑,避免代码混乱。例如,在自动挡汽车中,换挡逻辑可能涉及多种条件(如车速、油门位置等),状态机模式能够清晰地表达这些逻辑。

三、状态模式的示例

3.1 状态模式示例及角色

1. State:定义状态接口(行为)

定义了所有挡位状态的通用接口,包含所有挡位共有的方法,例如加速、减速等

public interface GearState {void accelerate(Car car); // 加速时的行为void decelerate(Car car); // 减速时的行为
}

2. ConcreteState:实现具体状态类(档位)

每个挡位(如1挡、2挡、3挡、4挡、5挡等)都实现状态接口,并定义在该挡位下的行为。

public class FirstGear implements GearState {@Overridepublic void accelerate(Car car) {System.out.println("当前1档:加速...");car.setState(new SecondGear()); // 切换到2挡}@Overridepublic void decelerate(Car car) {System.out.println("当前1档:减速...");car.setState(new NeutralGear()); // 切换到空挡}
}public class SecondGear implements GearState {@Overridepublic void accelerate(Car car) {System.out.println("当前2档:加速...");car.setState(new ThirdGear()); // 切换到3挡}@Overridepublic void decelerate(Car car) {System.out.println("当前2档:减速...");car.setState(new FirstGear()); // 切换到1挡}
}public class ThirdGear implements GearState {@Overridepublic void accelerate(Car car) {System.out.println("当前3档:加速...");car.setState(new FourthGear()); // 切换到4挡}@Overridepublic void decelerate(Car car) {System.out.println("当前3档:减速...");car.setState(new SecondGear()); // 切换到2挡}
}public class FourthGear implements GearState {@Overridepublic void accelerate(Car car) {System.out.println("当前4档:加速...");car.setState(new FifthGear()); // 切换到5挡}@Overridepublic void decelerate(Car car) {System.out.println("当前1档:减速...");car.setState(new ThirdGear()); // 切换到3挡}
}public class FifthGear implements GearState {@Overridepublic void accelerate(Car car) {System.out.println("当前5档:加速...");// 保持在5挡}@Overridepublic void decelerate(Car car) {System.out.println("当前5档:减速...");car.setState(new FourthGear()); // 切换到4挡}
}public class NeutralGear implements GearState {@Overridepublic void accelerate(Car car) {System.out.println("当前空档:加速...");car.setState(new FirstGear()); // 切换到1挡}@Overridepublic void decelerate(Car car) {System.out.println("当前空档:减速...");// 保持在空挡}
}

3、Context(上下文):(当前车辆,记录当前状态)

上下文可以被视为汽车的驾驶系统,它包含当前挡位的状态,并根据驾驶员的操作切换挡位

public class Car {private GearState currentState;public Car() {this.currentState = new NeutralGear(); // 初始状态为空挡}public void setState(GearState state) {this.currentState = state;}public void accelerate() {currentState.accelerate(this);}public void decelerate() {currentState.decelerate(this);}
}

4、场景(开车)

public class Main {public static void main(String[] args) {Car car = new Car();car.accelerate(); // 初始状态为空挡,加速后切换到1挡car.accelerate(); // 当前状态为1挡,加速后切换到2挡car.accelerate(); // 当前状态为2挡,加速后切换到3挡car.decelerate(); // 当前状态为3挡,减速后切换到2挡car.decelerate(); // 当前状态为2挡,减速后切换到1挡car.decelerate(); // 当前状态为1挡,减速后切换到空挡}
}//输出
当前0档:加速...
当前1档:加速...
当前2档:加速...
当前3档:加速...
当前3档:减速...
当前2档:减速...
当前1档:减速...
当前0档:减速...

3.2 在JAVA开发中常用的Spring状态机

        在Spring框架中,可以使用Spring State Machine来实现状态机模式。Spring State Machine是一个功能强大的状态机框架,支持定义状态、事件和状态转换,并且可以与Spring生态系统无缝集成。在实际开发中,可能使用Spring框架比较多,一般都是直接使用现成的Spring State Machine 来实现状态模式。

1、集成依赖包

<dependency><groupId>org.springframework.statemachine</groupId><artifactId>spring-statemachine-core</artifactId><version>2.1.3.RELEASE</version>
</dependency>

2、定义状态和事件

//车辆档位枚举类
public enum CarState {NEUTRAL,     //空挡FIRST_GEAR,  //一档SECOND_GEAR, //二挡THIRD_GEAR,  //三挡FOURTH_GEAR, //四挡FIFTH_GEAR;   //五档
}//车辆行为枚举类
public enum CarEvent {ACCELERATE,     //加速行为DECELERATE;     //减速行为
}

3、配置状态机

@Configuration
@EnableStateMachine(name="carStateMachine")
public class CarStateMachineConfig extends StateMachineConfigurerAdapter<CarState, CarEvent> {public void configure(StateMachineStateConfigurer<CarState, CarEvent> states) throws Exception {states.withStates().initial(CarState.NEUTRAL).states(EnumSet.allOf(CarState.class));}@Overridepublic void configure(StateMachineTransitionConfigurer<CarState, CarEvent> states) throws Exception {states.withExternal().source(CarState.NEUTRAL).target(CarState.FIRST_GEAR).event(CarEvent.ACCELERATE).and().withExternal().source(CarState.FIRST_GEAR).target(CarState.SECOND_GEAR).event(CarEvent.ACCELERATE).and().withExternal().source(CarState.SECOND_GEAR).target(CarState.THIRD_GEAR).event(CarEvent.ACCELERATE).and().withExternal().source(CarState.THIRD_GEAR).target(CarState.FOURTH_GEAR).event(CarEvent.ACCELERATE).and().withExternal().source(CarState.FOURTH_GEAR).target(CarState.FIFTH_GEAR).event(CarEvent.ACCELERATE).and().withExternal().source(CarState.FIFTH_GEAR).event(CarEvent.ACCELERATE) // No change.and().withExternal().source(CarState.FIFTH_GEAR).target(CarState.FOURTH_GEAR).event(CarEvent.DECELERATE).and().withExternal().source(CarState.FOURTH_GEAR).target(CarState.THIRD_GEAR).event(CarEvent.DECELERATE).and().withExternal().source(CarState.THIRD_GEAR).target(CarState.SECOND_GEAR).event(CarEvent.DECELERATE).and().withExternal().source(CarState.SECOND_GEAR).target(CarState.FIRST_GEAR).event(CarEvent.DECELERATE).and().withExternal().source(CarState.FIRST_GEAR).target(CarState.NEUTRAL).event(CarEvent.DECELERATE);}// 配置状态机持久化@Beanpublic DefaultStateMachinePersister machinePersister() {return new DefaultStateMachinePersister<>(new StateMachinePersist<Object, Object, Car>() {@Overridepublic void write(StateMachineContext<Object, Object> stateMachineContext, Car car) throws Exception {//持久化操作。可以通过任何形式进行持久化。redis 、 mongodb、mysql,ecache}@Overridepublic StateMachineContext<Object, Object> read(Car car) throws Exception {// 从持久化组件里进行读取return new DefaultStateMachineContext(car.getCarState(), null, null, null);}});}
}

4、定义状态监听器

        在Spring State Machine中,可以通过@WithStateMachine注解和@OnTransition注解来定义状态监听器。这些监听器会在状态转换时被触发。

// 监听器是监听到 action 后进行状态的一个变更。
@Slf4j
@Component("carStateListener")
@WithStateMachine(name="carStateMachine")
public class CarStateListener {@OnTransition(source = "NEUTRAL", target = "FIRST_GEAR")public boolean onAccelerateFromNeutral(Message<CarEvent> message) {log.info("Accelerating from NEUTRAL to FIRST_GEAR");Car car = (Car) message.getHeaders().get("car");car.setCarState(CarState.FIRST_GEAR);return true;}@OnTransition(source = "FIRST_GEAR", target = "SECOND_GEAR")public boolean onAccelerateFromFirstGear(Message<CarEvent> message) {log.info("Accelerating from FIRST_GEAR to SECOND_GEAR");Car car = (Car) message.getHeaders().get("car");car.setCarState(CarState.SECOND_GEAR);return true;}@OnTransition(source = "SECOND_GEAR", target = "THIRD_GEAR")public boolean onAccelerateFromSecondGear(Message<CarEvent> message) {log.info("Accelerating from SECOND_GEAR to THIRD_GEAR");Car car = (Car) message.getHeaders().get("car");car.setCarState(CarState.THIRD_GEAR);return true;}@OnTransition(source = "THIRD_GEAR", target = "FOURTH_GEAR")public boolean onAccelerateFromThirdGear(Message<CarEvent> message) {log.info("Accelerating from THIRD_GEAR to FOURTH_GEAR");Car car = (Car) message.getHeaders().get("car");car.setCarState(CarState.FOURTH_GEAR);return true;}@OnTransition(source = "FOURTH_GEAR", target = "FIFTH_GEAR")public boolean onAccelerateFromFourthGear(Message<CarEvent> message) {log.info("Accelerating from FOURTH_GEAR to FIFTH_GEAR");Car car = (Car) message.getHeaders().get("car");car.setCarState(CarState.FIFTH_GEAR);return true;}@OnTransition(source = "FIFTH_GEAR", target = "FOURTH_GEAR")public boolean onDecelerateFromFifthGear(Message<CarEvent> message) {log.info("Decelerating from FIFTH_GEAR to FOURTH_GEAR");Car car = (Car) message.getHeaders().get("car");car.setCarState(CarState.FOURTH_GEAR);return true;}@OnTransition(source = "FOURTH_GEAR", target = "THIRD_GEAR")public boolean onDecelerateFromFourthGear(Message<CarEvent> message) {log.info("Decelerating from FOURTH_GEAR to THIRD_GEAR");Car car = (Car) message.getHeaders().get("car");car.setCarState(CarState.THIRD_GEAR);return true;}@OnTransition(source = "THIRD_GEAR", target = "SECOND_GEAR")public boolean onDecelerateFromThirdGear(Message<CarEvent> message) {log.info("Decelerating from THIRD_GEAR to SECOND_GEAR");Car car = (Car) message.getHeaders().get("car");car.setCarState(CarState.SECOND_GEAR);return true;}@OnTransition(source = "SECOND_GEAR", target = "FIRST_GEAR")public boolean onDecelerateFromSecondGear(Message<CarEvent> message) {log.info("Decelerating from SECOND_GEAR to FIRST_GEAR");Car car = (Car) message.getHeaders().get("car");car.setCarState(CarState.FIRST_GEAR);return true;}@OnTransition(source = "FIRST_GEAR", target = "NEUTRAL")public boolean onDecelerateFromFirstGear(Message<CarEvent> message) {log.info("Decelerating from FIRST_GEAR to NEUTRAL");Car car = (Car) message.getHeaders().get("car");car.setCarState(CarState.NEUTRAL);return true;}}

4、使用状态机

@Service
public class CarService {@Resourceprivate StateMachine<CarState, CarEvent> carStateMachine;@Resourceprivate StateMachinePersister<CarState, CarEvent, Car> carMachinePersister;//模拟一个存储private Car car = new Car();//加速方法public Car acc() {if (car.getCarState() == null){car.setCarState(CarState.NEUTRAL);}// 书写逻辑Message message = MessageBuilder.withPayload(CarEvent.ACCELERATE).setHeader("car", car).build();if(changeStateAction(message,car)) {return car;}return car;}//减速方法public Car dece() {if (car.getCarState() == null){car.setCarState(CarState.NEUTRAL);}// 书写逻辑Message message = MessageBuilder.withPayload(CarEvent.DECELERATE).setHeader("car", car).build();if(changeStateAction(message,car)) {return car;}return car;}private boolean changeStateAction(Message<CarEvent> message, Car car) {try {carStateMachine.start();//尝试恢复状态机状态carMachinePersister.restore(carStateMachine, car); // 待议boolean res = carStateMachine.sendEvent(message);//持久化状态机状态carMachinePersister.persist(carStateMachine, car); // 持久return res;} catch (Exception e) {e.printStackTrace();} finally {carStateMachine.stop();}return false;}
}

4、场景(开车)

@SpringBootApplication
public class CarApplication {public static void main(String[] args) {ConfigurableApplicationContext context = SpringApplication.run(DesignApplication.class, args);CarService carService = context.getBean(CarService.class);Car car;car = carService.acc(); // 初始状态为空挡,加速后切换到1挡System.out.println("After accelerate: " + car.getCarState());car = carService.acc(); // 当前状态为1挡,加速后切换到2挡System.out.println("After accelerate: " + car.getCarState());car = carService.dece(); // 当前状态为2挡,减速后切换到1挡System.out.println("After decelerate: " + car.getCarState());car = carService.dece(); // 当前状态为1挡,减速后切换到空挡System.out.println("After decelerate: " + car.getCarState());}
}//输出
After accelerate: FIRST_GEAR
After accelerate: SECOND_GEAR
After decelerate: FIRST_GEAR
After decelerate: NEUTRAL

相关文章:

【设计模式-行为型】状态模式

一、什么是状态模式 什么是状态模式呢&#xff0c;这里我举一个例子来说明&#xff0c;在自动挡汽车中&#xff0c;挡位的切换是根据驾驶条件&#xff08;如车速、油门踏板位置、刹车状态等&#xff09;自动完成的。这种自动切换挡位的过程可以很好地用状态模式来描述。状态模式…...

2024.1.22 安全周报

政策/标准/指南最新动态 01 工信部印发《关于加强互联网数据中心客户数据安全保护的通知》 原文: https://www.secrss.com/articles/74673 互联网数据中心作为新一代信息基础设施&#xff0c;承载着千行百业的海量客户数据&#xff0c;是关系国民经济命脉的重要战略资源。…...

idea修改模块名导致程序编译出错

本文简单描述分别用Idea菜单、pom.xml文件管理项目模块module 踩过的坑&#xff1a; 通过idea菜单创建模块&#xff0c;并用idea菜单修改模块名&#xff0c;结构程序编译报错&#xff0c;出错的代码莫名奇妙。双击maven弹窗clean时&#xff0c;还是报错。因为模块是新建的&am…...

root用户Linux银河麒麟服务器安装vnc服务

安装必要桌面环境组件 yum install mate-session-manager -y mate-session #确定是否安装成功安装vnc服务器 yum install tigervnc-server -y切换到root为root得vnc设置密码 su root vncpasswd给root用户设置vnc服务器文件 vi /etc/systemd/system/vncserver:1.service [Un…...

CentOS 7使用RPM安装MySQL

MySQL是一个开源的关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;允许用户高效地存储、管理和检索数据。它被广泛用于各种应用&#xff0c;从小型的web应用到大型企业解决方案。 MySQL提供了丰富的功能&#xff0c;包括支持多个存储引擎、事务能力、数据完整…...

OpenCV imread函数读取图像__实例详解

OpenCV imread函数读取图像__实例详解 本文目录&#xff1a; 零、时光宝盒 一、imread函数定义 二、imread函数支持的文件格式 三、imread函数flags参数详解 &#xff08;3.1&#xff09;、Flags-1时&#xff0c;样返回加载的图像&#xff08;使用alpha通道&#xff0c;否…...

激光线扫相机无2D图像的标定方案

方案一&#xff1a;基于运动控制平台的标定 适用场景&#xff1a;若激光线扫相机安装在可控运动平台&#xff08;如机械臂、平移台、旋转台&#xff09;上&#xff0c;且平台的运动精度已知&#xff08;例如通过编码器或高精度步进电机控制&#xff09;。 步骤&#xff1a; 标…...

【安当产品应用案例100集】034-安当KSP支持密评中存储数据的机密性和完整性

安当KSP是一套获得国密证书的专业的密钥管理系统。KSP的系统功能扩展图示如下&#xff1a; 我们知道商用密码应用安全性评估中&#xff0c;需要确保存储的数据不被篡改、删除或者破坏&#xff0c;必须采用合适的安全方案来确保存储数据的机密性和完整性。KSP能否满足这个需求呢…...

08.七种排序算法实现(C语言)

目录 一.排序的基本概念 1.1 排序的概念 1.2 常见的排序算法 二.常见排序算法的实现 2.1 插入排序&#xff08;直接&#xff09; 1.基本思想 2.直接插入排序的特性 3.代码实现 2.2 希尔排序 1.基本思想 2.希尔插入排序的特性 3.代码实现 2.3 选择排序 1.基本思想 2…...

Alibaba Spring Cloud 一 核心组件、特性

Alibaba Spring Cloud 是 Alibaba 基于 Spring Cloud 的分布式微服务解决方案&#xff0c;提供了一套高性能、高可靠的微服务开发和运维工具。它扩展了 Spring Cloud 的功能&#xff0c;并优化了许多在生产环境中的实践场景&#xff0c;例如服务发现、配置管理、熔断限流等。 …...

kafka学习笔记7 性能测试 —— 筑梦之路

kafka 不同的参数配置对 kafka 性能都会造成影响&#xff0c;通常情况下集群性能受分区、磁盘和线程等影响因素&#xff0c;因此需要进行性能测试&#xff0c;找出集群性能瓶颈和最佳参数。 # 生产者和消费者的性能测试工具 kafka-producer-perf-test.sh kafka-consumer-perf-t…...

HQChart使用教程30-K线图如何对接第3方数据45- DRAWRADAR数据结构

HQChart使用教程30-K线图如何对接第3方数据45- DRAWRADAR数据结构 效果图DRAWRADARHQChart代码地址后台数据对接说明示例数据数据结构说明效果图 DRAWRADAR DRAWRADAR是hqchart插件独有的绘制雷达图函数,可以通过麦语法脚本来绘制一个简单的雷达图数据。 雷达图显示的位置固定…...

Java集合学习:HashMap的原理

一、HashMap里的Hash是什么&#xff1f; 首先&#xff0c;我们先要搞清楚HashMap里的的Hash是啥意思。 当我们在编程过程中&#xff0c;往往需要对线性表进行查找操作。 在顺序表中查找时&#xff0c;需要从表头开始&#xff0c;依次遍历比较a[i]与key的值是否相等&#xff…...

ETLCloud在iPaas中的是关键角色?

在当今的数字化时代&#xff0c;企业越来越依赖于其处理和分析数据的能力。为了实现这一目标&#xff0c;企业需要将各种异构的应用和数据源集成在一起&#xff0c;形成一个统一的数据视图。在这一过程中&#xff0c;ETL&#xff08;Extract, Transform, Load&#xff09;和iPa…...

Docker Hub 全面解析及应对策略

在现代 DevOps 和容器化应用开发中&#xff0c;Docker Hub 是一个不可或缺的工具。然而&#xff0c;一些地区或企业对 Docker Hub 的访问受到限制&#xff0c;甚至全面禁止。这种现象引发了开发者和运维人员的广泛关注。那么&#xff0c;为什么 Docker Hub 会被禁用&#xff1f…...

第五天 Labview数据记录(5.1 INI配置文件读写)

5.1 INI配置文件读写 INI配置文件是一种简单的文本文件&#xff0c;通常用于存储软件的配置信息。它具有以下作用&#xff1a; 存储软件配置参数方便软件的维护和更新提高软件的灵活性和可扩展性便于用户修改和共享配置 5.1.1 前面板 1&#xff09;新建项目SaveData_Exampl…...

【算法】经典博弈论问题——巴什博弈 python

目录 前言巴什博弈(Bash Game)小试牛刀PN分析实战检验总结 前言 博弈类问题大致分为&#xff1a; 公平组合游戏、非公平组合游戏&#xff08;绝大多数的棋类游戏&#xff09;和 反常游戏 巴什博弈(Bash Game) 一共有n颗石子&#xff0c;两个人轮流拿&#xff0c;每次可以拿1~m颗…...

ES6语法

一、Let、const、var变量定义 1.let 声明的变量有严格局部作用域 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"&g…...

窥探QCC518x-308x系列与手机之间的蓝牙HCI记录与分析 - 耳机篇

上一篇是介绍如何窥探手机端Bluetooth的HCI log, 本次介绍是如何窥探Bluetooth的HCI log-耳机篇. 这次跟QCC518x/QCC308x测试的手机是Samsung S23 Ultra. QCC518x/QCC308x透过HCI界面取得Log教学. 步骤1: 开启QMDE -> 选择ADK r1102 QCC3083 Headset workspace.步骤2: 点…...

ubuntu k8s 1.31

ubuntu 系统 设置 更新源 apt-get upgradeapt upgradeapt update apt-get update释放root sudo passwd root密码su - 密码设置root可以登录 cd /etc/ssh/sshd_config.d && vi ssh.confPermitRootLogin yes PasswordAuthentication yes:wq 保存退出 systemctl resta…...

java_网络服务相关_gateway_nacos_feign区别联系

1. spring-cloud-starter-gateway 作用&#xff1a;作为微服务架构的网关&#xff0c;统一入口&#xff0c;处理所有外部请求。 核心能力&#xff1a; 路由转发&#xff08;基于路径、服务名等&#xff09;过滤器&#xff08;鉴权、限流、日志、Header 处理&#xff09;支持负…...

【磁盘】每天掌握一个Linux命令 - iostat

目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat&#xff08;I/O Statistics&#xff09;是Linux系统下用于监视系统输入输出设备和CPU使…...

MVC 数据库

MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用

文章目录 问题现象问题原因解决办法 问题现象 macOS启动台&#xff08;Launchpad&#xff09;多出来了&#xff1a;Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显&#xff0c;都是Google家的办公全家桶。这些应用并不是通过独立安装的…...

P3 QT项目----记事本(3.8)

3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序

一、开发环境准备 ​​工具安装​​&#xff1a; 下载安装DevEco Studio 4.0&#xff08;支持HarmonyOS 5&#xff09;配置HarmonyOS SDK 5.0确保Node.js版本≥14 ​​项目初始化​​&#xff1a; ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署&#xff0c;直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型&#xff0c;但是目前国内可能使用不多&#xff0c;至少实践例子很少看见。开发训练模型就不介绍了&am…...

Qemu arm操作系统开发环境

使用qemu虚拟arm硬件比较合适。 步骤如下&#xff1a; 安装qemu apt install qemu-system安装aarch64-none-elf-gcc 需要手动下载&#xff0c;下载地址&#xff1a;https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x…...

对象回调初步研究

_OBJECT_TYPE结构分析 在介绍什么是对象回调前&#xff0c;首先要熟悉下结构 以我们上篇线程回调介绍过的导出的PsProcessType 结构为例&#xff0c;用_OBJECT_TYPE这个结构来解析它&#xff0c;0x80处就是今天要介绍的回调链表&#xff0c;但是先不着急&#xff0c;先把目光…...

高抗扰度汽车光耦合器的特性

晶台光电推出的125℃光耦合器系列产品&#xff08;包括KL357NU、KL3H7U和KL817U&#xff09;&#xff0c;专为高温环境下的汽车应用设计&#xff0c;具备以下核心优势和技术特点&#xff1a; 一、技术特性分析 高温稳定性 采用先进的LED技术和优化的IC设计&#xff0c;确保在…...