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

spring状态机

1、概述

        Spring State Machine 是一个用于处理状态机逻辑的框架,它提供了一种简洁的方法来定义状

态、转换以及在状态变更时触发的动作。

概念

  • 状态  State  :一个状态机至少要包含两个状态。例如自动门的例子,有 open 和 closed 两个状态。

  • 事件  Event   :事件就是执行某个操作的触发条件或者口令。对于自动门,“按下开门按钮”就是一个事件。

  • 动作  Action   :事件发生以后要执行动作。例如事件是“按开门按钮”,动作是“开门”。编程的时候,一个 Action一般就对应一个函数。

  • 转换  Transition  :也就是从一个状态变化为另一个状态。例如“开门过程”就是一个转换。

  • 守卫(Guard) :一种条件逻辑,用于决定是否可以进行某个状态转换。守卫可以基于应用程序的当前状态或其他条件来确定转换是否应该发生。

状态机

        有限状态机(Finite-state machine,FSM),又称有限状态自动机,简称状态机,是表示有限

个状态以及在这些状态之间的转移和动作等行为的数学模型。FSM是一种算法思想,简单而言,有

限状态机由一组状态、一个初始状态、输入和根据输入及现有状态转换为下一个状态的转换函数组

成。其作用主要是描述对象在它的生命周期内所经历的状态序列,以及如何响应来自外界的各种事

件。

地址

官方地址:

Spring Statemachine

文档地址

Spring Statemachine - Reference Documentation

github地址

https://github.com/spring-projects/spring-statemachine

2、状态机图

        做需求时,需要了解以下六种元素:起始、终止、现态、次态(目标状态)、动作、条件,

我们就可以完成一个状态机图了,以订单为例:通过支付事件,订单状态从待支付状态转换为待发货状态。

  1. 现态:是指当前所处的状态。待支付。
  2. 条件:又称为“事件”,当一个条件被满足,将会触发一个动作,或者执行一次状态的迁移。支付事件。
  3. 动作:条件满足后执行的动作。动作执行完毕后,可以迁移到新的状态,也可以仍旧保持原状态。动作不是必需的,当条件满足后,也可以不执行任何动作,直接迁移到新状态。状态转换为待发货。
  4. 次态:条件满足后要迁往的新状态。“次态”是相对于“现态”而言的,“次态”一旦被激活,就转变成新的“现态”了。待发货。

注意事项:

  1. 避免把某个“程序动作”当作是一种“状态”来处理。那么如何区分“动作”和“状态”?“动作”是不稳定的,即使没有条件的触发,“动作”一旦执行完毕就结束了;而“状态”是相对稳定的,如果没有外部条件的触发,一个状态会一直持续下去。
  2. 状态划分时漏掉一些状态,导致跳转逻辑不完整。所以在设计状态机时,我们需要反复的查看设计的状态图或者状态表,最终达到一种牢不可破的设计方案。

3、代码

3.1 依赖

 <!--spring 状态机start-->
<dependency><groupId>org.springframework.statemachine</groupId><artifactId>spring-statemachine-core</artifactId><version>${spring-statemachine.version}</version>
</dependency>
<!-- redis持久化状态机 -->
<dependency><groupId>org.springframework.statemachine</groupId><artifactId>spring-statemachine-data-redis</artifactId><version>${spring-statemachine.version}</version>
</dependency>
<!--spring 状态机end-->
<!--redis start-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--redis end-->

3.2 定义状态和事件

package com.ybw.constant;/*** 状态** @author weixiansheng* @version V1.0* @className RegStatusEnum* @date 2023/12/26**/
public enum RegStatusEnum {// 未连接UNCONNECTED,// 已连接CONNECTED,// 注册中REGISTERING,// 已注册REGISTERED;
}
package com.ybw.constant;/*** 事件** @author weixiansheng* @version V1.0* @className RegEventEnum* @date 2023/12/26**/
public enum RegEventEnum {// 连接CONNECT,// 注册REGISTER,// 注册成功REGISTER_SUCCESS,// 注册失败REGISTER_FAILED,// 注销UN_REGISTER;
}

3.3 配置状态机

创建一个配置类来配置状态机。在这个配置中,我们定义状态转换逻辑。

package com.ybw.config;import com.ybw.constant.RegEventEnum;
import com.ybw.constant.RegStatusEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.statemachine.config.EnableStateMachine;
import org.springframework.statemachine.config.EnumStateMachineConfigurerAdapter;
import org.springframework.statemachine.config.builders.StateMachineStateConfigurer;
import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer;import java.util.EnumSet;/*** @author weixiansheng* @version V1.0* @className StateMachineConfig* @date 2023/12/25**/
@Configuration
@EnableStateMachine
@Slf4j
public class StateMachineConfig extends EnumStateMachineConfigurerAdapter<RegStatusEnum, RegEventEnum> {/*** 配置状态** @param states* @methodName: configure* @return: void* @author: weixiansheng* @date: 2023/12/25**/@Overridepublic void configure(StateMachineStateConfigurer<RegStatusEnum, RegEventEnum> states) throws Exception {states.withStates()// 定义初始状态.initial(RegStatusEnum.UNCONNECTED)// 定义状态机状态.states(EnumSet.allOf(RegStatusEnum.class));}/*** 配置状态转换事件关系** @param transitions* @methodName: configure* @return: void* @author: weixiansheng* @date: 2023/12/25**/@Overridepublic void configure(StateMachineTransitionConfigurer<RegStatusEnum, RegEventEnum> transitions) throws Exception {transitions// 1.连接事件// 未连接 -> 已连接.withExternal().source(RegStatusEnum.UNCONNECTED).target(RegStatusEnum.CONNECTED).event(RegEventEnum.CONNECT).and()// 2.注册事件// 已连接 -> 注册中.withExternal().source(RegStatusEnum.CONNECTED).target(RegStatusEnum.REGISTERING).event(RegEventEnum.REGISTER).and()// 3.注册成功事件// 注册中 -> 已注册.withExternal().source(RegStatusEnum.REGISTERING).target(RegStatusEnum.REGISTERED).event(RegEventEnum.REGISTER_SUCCESS).and()// 5.注销事件// 已连接 -> 未连接.withExternal().source(RegStatusEnum.CONNECTED).target(RegStatusEnum.UNCONNECTED).event(RegEventEnum.UN_REGISTER).and()// 注册中 -> 未连接.withExternal().source(RegStatusEnum.REGISTERING).target(RegStatusEnum.UNCONNECTED).event(RegEventEnum.UN_REGISTER).and()// 已注册 -> 未连接.withExternal().source(RegStatusEnum.REGISTERED).target(RegStatusEnum.UNCONNECTED).event(RegEventEnum.UN_REGISTER);}
}

3.4 状态机的转换事件配置

package com.ybw.config;import com.alibaba.fastjson2.JSON;
import com.ybw.constant.RegEventEnum;
import com.ybw.entity.Order;
import lombok.extern.slf4j.Slf4j;
import org.springframework.messaging.Message;
import org.springframework.statemachine.annotation.OnTransition;
import org.springframework.statemachine.annotation.WithStateMachine;/*** 状态机的转换事件配置** @author weixiansheng* @version V1.0* @className StateMachineEventConfig* @date 2023/12/26**/
@WithStateMachine
@Slf4j
public class StateMachineEventConfig {/*** 连接事件** @param message* @methodName: connect* @return: void* @author: weixiansheng* @date: 2023/12/26**/@OnTransition(source = "UNCONNECTED", target = "CONNECTED")public void connect(Message<RegEventEnum> message) {Order order = (Order) message.getHeaders().get("order");log.info("///");log.info("连接事件, 未连接 -> 已连接,order:{}", JSON.toJSONString(order));log.info("///");}/*** 注册事件** @param message* @methodName: register* @return: void* @author: weixiansheng* @date: 2023/12/26**/@OnTransition(source = "CONNECTED", target = "REGISTERING")public void register(Message<RegEventEnum> message) {log.info("///");log.info("注册事件, 已连接 -> 注册中");log.info("///");}/*** 注册成功事件** @param message* @methodName: registerSuccess* @return: void* @author: weixiansheng* @date: 2023/12/26**/@OnTransition(source = "REGISTERING", target = "REGISTERED")public void registerSuccess(Message<RegEventEnum> message) {log.info("///");log.info("注册成功事件, 注册中 -> 已注册");log.info("///");}/*** 注销事件** @param message* @methodName: unRegister* @return: void* @author: weixiansheng* @date: 2023/12/26**/@OnTransition(source = "REGISTERED", target = "UNCONNECTED")public void unRegister(Message<RegEventEnum> message) {log.info("///");log.info("注销事件, 已注册 -> 未连接");log.info("///");}
}

3.6 Redis持久化

持久化到redis中,在分布式系统中使用。

package com.ybw.config;import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.statemachine.data.redis.RedisStateMachineContextRepository;
import org.springframework.statemachine.data.redis.RedisStateMachinePersister;
import org.springframework.statemachine.persist.RepositoryStateMachinePersist;/*** 持久化** @author weixiansheng* @version V1.0* @className Persist* @date 2023/12/26**/
@Configuration
@Slf4j
public class Persist<E, S> {@Resourceprivate RedisConnectionFactory redisConnectionFactory;/*** 持久化到redis中,在分布式系统中使用** @methodName: getRedisPersister* @return: org.springframework.statemachine.data.redis.RedisStateMachinePersister<E, S>* @author: weixiansheng* @date: 2023/12/26**/@Bean(name = "stateMachineRedisPersister")public RedisStateMachinePersister<E, S> getRedisPersister() {RedisStateMachineContextRepository<E, S> repository = new RedisStateMachineContextRepository<>(redisConnectionFactory);RepositoryStateMachinePersist<E, S> p = new RepositoryStateMachinePersist<>(repository);return new RedisStateMachinePersister<>(p);}
}

3.6 测试

package com.ybw.state;import com.ybw.constant.RegEventEnum;
import com.ybw.constant.RegStatusEnum;
import com.ybw.entity.Order;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.data.redis.RedisStateMachinePersister;
import org.springframework.statemachine.persist.StateMachinePersister;/*** @author weixiansheng* @version V1.0* @className StateTest* @date 2023/12/26**/
@SpringBootTest
@Slf4j
public class StateTest {@Resourceprivate StateMachine<RegStatusEnum, RegEventEnum> stateMachine;@Resource(name = "stateMachineRedisPersister")private RedisStateMachinePersister<RegStatusEnum, RegEventEnum> persister;/*** @MethodName: testState* @Description:* @Param: []* @Return: void* @Author: ybwei* @Date: 2020/3/26**/@Testpublic void testState() {try {Order order = Order.builder().id(1L).name("张三").status(RegStatusEnum.CONNECTED).build();stateMachine.start();//尝试恢复状态机状态(read)persister.restore(stateMachine, order.getId().toString());Message<RegEventEnum> message = MessageBuilder.withPayload(RegEventEnum.CONNECT).setHeader("order", order).build();stateMachine.sendEvent(message);//持久化状态机状态(write)persister.persist(stateMachine, order.getId().toString());} catch (Exception e) {log.error("testState error:", e);}
//        stateMachine.sendEvent(RegEventEnum.REGISTER);
//        stateMachine.sendEvent(RegEventEnum.REGISTER_SUCCESS);
//        stateMachine.sendEvent(RegEventEnum.UN_REGISTER);
//
//        stateMachine.sendEvent(RegEventEnum.CONNECT);}
}

 执行结果:

第一次执行

[INFO ] 2023-12-26 17:35:20.563 [main] o.s.s.support.AbstractStateMachine - Got null context, resetting to initial state, clearing extended state and machine id
[INFO ] 2023-12-26 17:35:20.593 [main] c.ybw.config.StateMachineEventConfig - ///
[INFO ] 2023-12-26 17:35:20.688 [main] c.ybw.config.StateMachineEventConfig - 连接事件, 未连接 -> 已连接,order:{"id":1,"name":"张三","status":"CONNECTED"}
[INFO ] 2023-12-26 17:35:20.690 [main] c.ybw.config.StateMachineEventConfig - ///

第二次执行,没有日志打印。

修改代码

将RegEventEnum.CONNECT改为RegEventEnum.REGISTER

@Test
public void testState() {try {Order order = Order.builder().id(1L).name("张三").status(RegStatusEnum.CONNECTED).build();stateMachine.start();//尝试恢复状态机状态(read)persister.restore(stateMachine, order.getId().toString());Message<RegEventEnum> message = MessageBuilder.withPayload(RegEventEnum.REGISTER).setHeader("order", order).build();stateMachine.sendEvent(message);//持久化状态机状态(write)persister.persist(stateMachine, order.getId().toString());} catch (Exception e) {log.error("testState error:", e);}
}

第三次执行,打印日志

[INFO ] 2023-12-26 17:38:31.307 [main] c.ybw.config.StateMachineEventConfig - ///
[INFO ] 2023-12-26 17:38:31.307 [main] c.ybw.config.StateMachineEventConfig - 注册事件, 已连接 -> 注册中
[INFO ] 2023-12-26 17:38:31.307 [main] c.ybw.config.StateMachineEventConfig - ///

 总结:

  • 事件发生后,会执行StateMachineEventConfig相关逻辑。
  • 持久化状态机状态。
  • 相同的事件再次发生,不会执行StateMachineEventConfig相关逻辑。

3.7 源码地址

share: 分享仓库 - Gitee.com

相关文章:

spring状态机

1、概述 Spring State Machine 是一个用于处理状态机逻辑的框架&#xff0c;它提供了一种简洁的方法来定义状 态、转换以及在状态变更时触发的动作。 概念 状态 &#xff08; State &#xff09; &#xff1a;一个状态机至少要包含两个状态。例如自动门的例子&#xff0c;有 …...

K8S异常处理

一、概述 1、k8s有时候会报错The connection to the server ip:6443 was refused - did you specify the right host or port &#xff0c;本文档提供几种可能产生该报错的原因和排障思路。 二、发现问题 使用任意Kubectl 命令会报错&#xff1a;The connection to the serv…...

【挑战全网最易懂】深度强化学习 --- 零基础指南

深度强化学习介绍、概念 强化学习介绍离散场景&#xff0c;使用行为价值方法连续场景&#xff0c;使用概率分布方法实时反馈连续场景&#xff1a;使用概率分布 行为价值方法 强化学习六要素设计奖励函数设计评论家策略学习与优化 算法路径深度 Q 网络 DQN演员-评论家算法&…...

WPF RelativeSource

RelativeSource 类在 WPF 中提供了以下几种模式&#xff1a; RelativeSource Self&#xff1a;指定当前元素作为相对源。可以在当前元素的属性中绑定到自身的属性。 示例&#xff1a; <TextBlock Text"{Binding Text, RelativeSource{RelativeSource Self}}" /&…...

centos 安装 配置 zsh

centos 编译安装 zsh 和 配置 oh-my-zsh 下载 wget https://jaist.dl.sourceforge.net/project/zsh/zsh/5.9/zsh-5.9.tar.xz依赖 yum install ncurses-devel安装zsh 执行&#xff1a; tar -xvf zsh-5.9.tar.xz cd zsh-5.9 ./configure --prefix/usr/local/zsh5.9 make &am…...

git 常用基本命令, reset 回退撤销commit,解决gitignore无效,忽略记录或未记录远程仓库的文件,删除远程仓库文件

git 基本命令 reset 撤销commit https://blog.csdn.net/a704397849/article/details/135220091 idea 中 rest 撤销commit过程如下&#xff1a; Git -> Rest Head… 在To Commit中的HEAD后面加上^&#xff0c;点击Reset即可撤回最近一次的尚未push的commit Reset Type 有三…...

Vue Echarts 多折线图只有一条X轴(合并X轴数据并去重排序) - 附完整示例

echarts&#xff1a;一个基于 JavaScript 的开源可视化图表库。 目录 效果 一、介绍 1、官方文档&#xff1a;Apache ECharts 2、官方示例 二、准备工作 1、安装依赖包 2、示例版本 三、使用步骤 1、在单页面引入 echarts 2、指定容器并设置容器宽高 3、数据处理&am…...

WPF+Halcon 培训项目实战(6):目标匹配助手

文章目录 前言相关链接项目专栏模板匹配助手简单使用金字塔级别参数自动选择应用插入代码 总结 前言 为了更好地去学习WPFHalcon&#xff0c;我决定去报个班学一下。原因无非是想换个工作。相关的教学视频来源于下方的Up主的提供的教程。这里只做笔记分享&#xff0c;想要源码…...

Linux管理LVM逻辑卷

目录 一、LVM逻辑卷介绍 1. 概述 2. LVM基本术语 2.1 PV&#xff08;Physical Volume&#xff0c;物理卷&#xff09; 2.2 VG (Volume Group&#xff0c;卷组&#xff09; 2.3 LV (Logical Volume&#xff0c;逻辑卷&#xff09; 3. 常用的磁盘命令 4. 查看系统信息的命…...

vue如何实现局部刷新?

应用场景&#xff1a; 比如你要切换tap栏实现刷新下面form表单等&#xff0c;相当于刷新页面。 如何使用如下&#xff1a; <div v-if"isReloadData"> 比如你想刷新那个位置就把 v-if"isReloadData"写到那个标签上 </div> 在data中定义刷新标…...

C语言,指针链表详解解说及代码示例

C语言&#xff0c;指针链表详解解说及代码示例 指针链表是一种常用的数据结构&#xff0c;用于存储和组织数据。它由一系列节点组成&#xff0c;每个节点包含数据和一个指向下一个节点的指针。通过这种方式&#xff0c;可以动态地添加、删除和访问节点&#xff0c;实现灵活的数…...

6、LLaVA

简介 LLaVA官网 LLaVA使用Vicuna(LLaMA-2)作为LLM f ϕ ( ⋅ ) f_\phi() fϕ​(⋅)&#xff0c;使用预训练的CLIP图像编码器 ViT-L/14 g ( X v ) g(X_v) g(Xv​)。 输入图像 X v X_v Xv​&#xff0c;首先获取feature Z v g ( X v ) Z_vg(X_v) Zv​g(Xv​)。考虑到最后一…...

SpringMVC核心处理流程梳理

1、处理流程图展示 当我拿出这张图&#xff0c;阁下又该如何应对呢&#xff1f;执行流程是不是一目了然了。【记住一句话&#xff1a;所有的注解都只是一个标签或者标记&#xff0c;最终都是反射找到具体方法上面的注解标记&#xff0c;然后找到类、属性、方法扩展自己想要的功…...

go 语言程序设计第2章--程序结构

2.1 名称 如果一个实体在函数中声明&#xff0c;它只在函数局部有效。如果声明在函数外&#xff0c;它将对包里面所有源文件可见。 实体第一个字母的大小写决定其可见性是否跨包。如果名称以大写字母开头&#xff0c;它是导出的&#xff0c;意味着它对包外是可见和可访问的。包…...

JavaScript基础知识点总结:从零开始学习JavaScript(五)

如果大家感感兴趣也可以去看&#xff1a; &#x1f389;博客主页&#xff1a;阿猫的故乡 &#x1f389;系列专栏&#xff1a;JavaScript专题栏 &#x1f389;ajax专栏&#xff1a;ajax知识点 &#x1f389;欢迎关注&#xff1a;&#x1f44d;点赞&#x1f64c;收藏✍️留言 学习…...

Intel FPGA 技术开放日

概要 时间&#xff1a;2023.11.14 全天 &#xff08; 9:00 - 16: 20&#xff09; 地点&#xff1a;北京望京. 凯悦酒店 主题内容&#xff1a;分享交流了Intel FPGA 产品技术优势和落地实践方案。 会议的议程 开场致词&#xff1a; FPGA业务&#xff0c;是几年前intel收购而…...

分享72个Python爬虫源码总有一个是你想要的

分享72个Python爬虫源码总有一个是你想要的 学习知识费力气&#xff0c;收集整理更不易。 知识付费甚欢喜&#xff0c;为咱码农谋福利。 链接&#xff1a;https://pan.baidu.com/s/1v2P4l5R6KT2Ul-oe2SF8cw?pwd6666 提取码&#xff1a;6666 项目名称 10 photo websites…...

Mybatis 动态 SQL - foreach

动态SQL的另一个常见需求是需要迭代一个集合&#xff0c;通常用于构建IN条件。例如&#xff1a; <select id"selectPostIn" resultType"domain.blog.Post">SELECT *FROM POST P<where><foreach item"item" index"index&quo…...

编程笔记 GOLANG基础 001 为什么要学习Go语言

编程笔记 GOLANG基础 001 为什么要学Go语言 一、推荐学习的计算机程序设计语言&#xff08;一&#xff09;、前端设计与编程&#xff1a;htmlcssjavascripttypescript&#xff08;二&#xff09;、C/C语言&#xff08;三&#xff09;、Go语言&#xff08;四&#xff09;、Pytho…...

OrientDB使用教程:全面了解图数据库

图数据库在当今数据处理领域中扮演着越来越重要的角色&#xff0c;而OrientDB作为一种多模型的数据库&#xff0c;具有图数据库、文档数据库和对象数据库的特性&#xff0c;为应对不同场景提供了灵活的解决方案。本教程将简要介绍OrientDB的使用&#xff0c;包括基本概念、安装…...

VMware安装笔记

1、首先准备安装文件 没有的小伙伴可以网上自行下载&#xff0c;或者给我留言&#xff0c;我发给你。 2、开始安装 2.1、双击运行exe安装文件&#xff0c;下一步 2.2、接受许可&#xff0c;下一步 2.3、选择安装路径 2.4、选择好安装路径后&#xff0c;继续下一步 2.5、取消勾…...

MIT线性代数笔记-第27讲-复数矩阵,快速傅里叶变换

目录 27.复数矩阵&#xff0c;快速傅里叶变换打赏 27.复数矩阵&#xff0c;快速傅里叶变换 对于实矩阵而言&#xff0c;特征值为复数时&#xff0c;特征向量一定为复向量&#xff0c;由此引入对复向量的学习 求模长及内积 假定一个复向量 z ⃗ [ z 1 z 2 ⋮ z n ] \vec{z} \…...

三维点通用排序

前言 NWAFU 2021阶段二 C 一、题目描述 题目描述 在三维笛卡尔坐标系中&#xff0c;可以用X,Y,Z三个坐标分量表示三维空间中的一个点。现有一系列用X,Y,Z表示的三维点&#xff0c;需要对其按指定的X、Y或Z分量进行升序或降序排序。请用C语言实现这一排序过程&#xff0c;程序…...

[架构之路-265]:目标系统 - 设计方法 - 软件工程 - 软件设计 - 如何做好详细设计

目录 一、详细设计概述 1.1 什么是详细设计 1.2 软件概要设计、软件架构、软件详细设计比较 二、软件详细设计说明书 2.1 概述 2.2 撰写步骤 2.3 主要内容 三、详细设计详解 3.1 引言 3.2 系统架构设计 3.3 模块设计 3.3.1 模块描述 3.3.2 模块间接口设计与UML图 …...

java设计模式学习之【模板方法模式】

文章目录 引言模板方法模式简介定义与用途实现方式 使用场景优势与劣势在Spring框架中的应用游戏设计示例代码地址 引言 设想你正在准备一顿晚餐&#xff0c;无论你想做意大利面、披萨还是沙拉&#xff0c;制作过程中都有一些共同的步骤&#xff1a;准备原料、加工食物、摆盘。…...

篇章二 | Python 入门指南:深入理解基础数据类型

Python 是一门强大而易学的编程语言&#xff0c;而深刻理解其基础数据类型是掌握 Python 编程的重要一步。本入门指南将详细介绍 Python 中的基础数据类型&#xff0c;包括整数、浮点数、字符串、布尔值、列表、元组、字典和集合等&#xff0c;同时提供注意事项和与 C 语言的区…...

循环冗余效验码的计算方法

循环冗余效验码的计算方法 G&#xff08;x&#xff09;&#xff1a; 在了解计算方法之前我们首先要明白G&#xff08;x&#xff09;表明的意思&#xff0c;这一步非常重要&#xff01; 例如&#xff0c;G&#xff08;x&#xff09; x^3 x^2 1 &#xff0c;该式子表明的编…...

第P8周:YOLOv5-C3模块实现

>- **&#x1f368; 本文为[&#x1f517;365天深度学习训练营](https://mp.weixin.qq.com/s/rbOOmire8OocQ90QM78DRA) 中的学习记录博客** >- **&#x1f356; 原作者&#xff1a;[K同学啊 | 接辅导、项目定制](https://mtyjkh.blog.csdn.net/)** 一、 前期准备 1. 设…...

Java中常见的日志包分析(Log4j、Logback、SLF4J等)

Java中常见的日志jar包包括Log4j、Logback、SLF4J、java.util.logging等。它们各自的作用和应用场景如下&#xff1a; 1. Log4j 作用&#xff1a;Log4j是Apache的一个开源项目&#xff0c;提供日志记录的功能&#xff0c;支持多种输出目的地&#xff0c;如控制台、文件、GUI组…...

C++系列-第1章顺序结构-3-输出类cout

C系列-第1章顺序结构-3-输出类cout 在线练习&#xff1a; http://noi.openjudge.cn/ https://www.luogu.com.cn/ 总结 本文是C系列博客&#xff0c;主要讲述输出类cout的用法 cout介绍与基本用法 在C中&#xff0c;cout 是用于输出&#xff08;打印&#xff09;数据的工具&…...

网站百度不收录/免费的推广软件下载

读写锁和文件读写对速度的影响 因项目需求&#xff0c;添加一个功能&#xff0c;要不每次都打开一个文件&#xff0c;并遍历它&#xff0c;要不是一次读取至全局变量&#xff0c;每次遍历全局变量加读写锁&#xff0c;这两钟方案的速度需要简单测试一下 代码如下 #include &l…...

手机网站搭建公司/现在做百度推广有用吗

今天玩了一把Apache common configuration&#xff0c;感觉挺哈皮。 为了没有接触过这个工具的朋友少走弯路&#xff0c;我分享一下自己的经验。 1&#xff09;从官网上下载一个common configuration的jar包&#xff0c; http://commons.apache.org/configuration/downloads.ht…...

wordpress怎么上传ppt/网站运营师

提出需求做图像处理时&#xff0c;有时会遇到换色问题&#xff0c;就例如下面图片(网上找的小姐姐图片&#xff0c;侵删)的背景图并不喜欢&#xff0c;我想换成蓝色的要怎么做呢这时候肯定会有小伙伴会想到PS&#xff0c;PS 工具当然是首选&#xff0c;但是如果有大量图片需要更…...

wordpress 如何登录地址/搜索引擎营销

文章来源&#xff1a; http://www.tuicool.com/articles/qyEbya 多谢在网上搜集的资料主要有以下两个方面&#xff1a;第一方面&#xff1a;MySQL5.6.13安装步骤(Windows7 64位)1. 下载MySQL Community Server 5.6.132. 解压MySQL压缩包将以下载的MySQL压缩…...

驻马店做网站的公司/seo的工具有哪些

viewpager.getChildCount() 非常easy误解成viewpager子页面的size。它和getCount还是有差别的 getChildCount() 是表示当前可见页size 比方&#xff1a;Viewpager总共3页 当到第一页时候可见页面为2&#xff08;在滑动过程&#xff0c;可见第一张和第二张&#xff09;&#xff…...

用微信微博网站来做睡眠经济/哪个公司的网站制作

https://blog.csdn.net/xiaoshan0711/article/details/54571823 在小程序的开发过程中&#xff0c;我们会遇到一种情况&#xff0c;就是在制作五星点评的时候&#xff0c;默认五颗星星都是要亮的。这里我们就要分享一下自己做默认五星的心得。 在这里我们先看一下效果图&#x…...