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

瑞_23种设计模式_状态模式

文章目录

    • 1 状态模式(State Pattern)
      • 1.1 介绍
      • 1.2 概述
      • 1.3 状态模式的结构
      • 1.4 状态模式的优缺点
      • 1.5 状态模式的使用场景
    • 2 案例一
      • 2.1 需求
      • 2.2 代码实现(未使用状态模式)
      • 2.3 代码实现(状态模式)
    • 3 案例二
      • 3.1 需求
      • 3.2 代码实现

🙊 前言:本文章为瑞_系列专栏之《23种设计模式》的状态模式篇。本文中的部分图和概念等资料,来源于博主学习设计模式的相关网站《菜鸟教程 | 设计模式》和《黑马程序员Java设计模式详解》,特此注明。本文中涉及到的软件设计模式的概念、背景、优点、分类、以及UML图的基本知识和设计模式的6大法则等知识,建议阅读 《瑞_23种设计模式_概述》

本系列 - 设计模式 - 链接:《瑞_23种设计模式_概述》

⬇️本系列 - 创建型模式 - 链接🔗

  单例模式:《瑞_23种设计模式_单例模式》
  工厂模式:《瑞_23种设计模式_工厂模式》
  原型模式:《瑞_23种设计模式_原型模式》
抽象工厂模式:《瑞_23种设计模式_抽象工厂模式》
 建造者模式:《瑞_23种设计模式_建造者模式》

⬇️本系列 - 结构型模式 - 链接🔗

  代理模式:《瑞_23种设计模式_代理模式》
 适配器模式:《瑞_23种设计模式_适配器模式》
 装饰者模式:《瑞_23种设计模式_装饰者模式》
  桥接模式:《瑞_23种设计模式_桥接模式》
  外观模式:《瑞_23种设计模式_外观模式》
  组合模式:《瑞_23种设计模式_组合模式》
  享元模式:《瑞_23种设计模式_享元模式》

⬇️本系列 - 行为型模式 - 链接🔗

模板方法模式:《瑞_23种设计模式_模板方法模式》
  策略模式:《瑞_23种设计模式_策略模式》
  命令模式:《瑞_23种设计模式_命令模式》
 职责链模式:《瑞_23种设计模式_职责链模式》
  状态模式:《后续更新》
 观察者模式:《后续更新》
 中介者模式:《后续更新》
 迭代器模式:《后续更新》
 访问者模式:《后续更新》
 备忘录模式:《后续更新》
 解释器模式:《后续更新》

在这里插入图片描述

1 状态模式(State Pattern)

瑞:状态模式堆程序员水平要求较高,使用有点困难,属于提升模式。可用于简化复杂的条件语句(如一个操作中含有庞大的分支结构,即长的 if-else 链或 switch case),并且这些分支决定于对象的状态。

  在状态模式(State Pattern)中,类的行为是基于它的状态改变的。这种类型的设计模式属于行为型模式。

  瑞:行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,它涉及算法与对象间职责的分配。
  瑞:行为型模式分为类行为模式对象行为模式,前者采用继承机制来在类间分派行为,后者采用组合或聚合在对象间分配行为。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象行为模式比类行为模式具有更大的灵活性

状态模式属于:对象行为模式

  在状态模式中,我们创建表示各种状态的对象和一个行为随着状态对象改变而改变的 context 对象。

1.1 介绍

  • 意图:允许对象在内部状态发生改变时改变它的行为,对象看起来好像修改了它的类。

  • 主要解决:对象的行为依赖于它的状态(属性),并且可以根据它的状态改变而改变它的相关行为。

  • 何时使用代码中包含大量与对象状态有关的条件语句

  • 如何解决:将各种具体的状态类抽象出来。

  • 关键代码:通常命令模式的接口中只有一个方法。而状态模式的接口中有一个或者多个方法。而且,状态模式的实现类的方法,一般返回值,或者是改变实例变量的值。也就是说,状态模式一般和对象的状态有关。实现类的方法有不同的功能,覆盖接口中的方法。状态模式和策略模式一样,也可以用于消除 if…else 等条件选择语句。

  • 应用实例
      1️⃣ 打篮球的时候运动员可以有正常状态、不正常状态和超常状态。
      2️⃣ 曾侯乙编钟中,“钟是抽象接口”,“钟A”等是具体状态,“曾侯乙编钟”是具体环境(Context)。

  • 优点
      1️⃣ 封装了转换规则。
      2️⃣枚举可能的状态,在枚举状态之前需要确定状态种类。
      3️⃣ 将所有与某个状态有关的行为放到一个类中,并且可以方便地增加新的状态,只需要改变对象状态即可改变对象的行为。
      4️⃣ 允许状态转换逻辑与状态对象合成一体,而不是某一个巨大的条件语句块。
      5️⃣ 可以让多个环境对象共享一个状态对象,从而减少系统中对象的个数。

  • 缺点
      1️⃣ 状态模式的使用必然会增加系统类和对象的个数。
      2️⃣ 状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱。
      3️⃣ 状态模式对"开闭原则"的支持并不太好,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源代码,否则无法切换到新增状态,而且修改某个状态类的行为也需修改对应类的源代码。

  • 使用场景
      1️⃣ 行为随状态改变而改变的场景。
      2️⃣ 条件、分支语句的代替者。

  • 注意事项:在行为受状态约束的时候使用状态模式,而且状态不超过 5 个。

1.2 概述

定义:对有状态的对象,把复杂的“判断逻辑”提取到不同的状态对象中,允许状态对象在其内部状态发生改变时改变其行为。

  状态模式通过将每个状态的行为封装在各自的类中,使得对象可以在运行时根据其内部状态的变化而改变行为,从而提供了一种优雅的方式来组织和管理复杂的状态转换逻辑。

  使用状态模式的好处是可以简化复杂的条件语句(如长的 if-else 链),使得代码更加清晰和易于维护。此外,当新的状态需要添加到系统中时,只需要增加一个新的具体状态类,而不需要修改环境类或其他状态类,这有助于保持系统的灵活性和可扩展性。

1.3 状态模式的结构

  • 状态模式主要包含以下角色:
      1️⃣ 环境(Context)角色:也称为上下文,它定义了客户程序需要的接口,维护一个当前状态,并将与状态相关的操作委托给当前状态对象来处理。
      2️⃣ 抽象状态(State)角色:定义一个接口,用以封装环境对象中的特定状态所对应的行为。
      3️⃣ 具体状态(Concrete State)角色:实现抽象状态所对应的行为。

1.4 状态模式的优缺点

优点

  • 将所有与某个状态有关的行为放到一个类中,并且可以方便地增加新的状态,只需要改变对象状态即可改变对象的行为。
  • 允许状态转换逻辑与状态对象合成一体,而不是某一个巨大的条件语句块。

缺点

  • 状态模式的使用必然会增加系统类和对象的个数。
  • 状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱。
  • 状态模式对"开闭原则"的支持并不太好。

1.5 状态模式的使用场景

  • 当一个对象的行为取决于它的状态,并且它必须在运行时根据状态改变它的行为时,就可以考虑使用状态模式。
  • 一个操作中含有庞大的分支结构,并且这些分支决定于对象的状态时。



2 案例一

【案例】电梯状态控制

2.1 需求

  通过按钮来控制一个电梯的状态,一个电梯有开门状态,关门状态,停止状态,运行状态。每一种状态改变,都有可能要根据其他状态来更新处理。例如,如果电梯门现在处于运行时状态,就不能进行开门操作,而如果电梯门是停止状态,就可以执行开门操作。

  该案例未使用状态模式设计的类图如下:

在这里插入图片描述

(图为未使用状态模式前)

2.2 代码实现(未使用状态模式)

电梯接口(接口)
/*** 电梯接口** @author LiaoYuXing-Ray**/
public interface ILift {// 定义四个电梯状态的常量int OPENING_STATE = 1;int CLOSING_STATE = 2;int RUNNING_STATE = 3;int STOPPING_STATE = 4;// 设置电梯状态的功能void setState(int state);// 电梯操作功能void open();void close();void run();void stop();
}
电梯类(类)

/*** 电梯类(ILift的子实现类)** @author LiaoYuXing-Ray**/
public class Lift implements ILift {// 声明一个记录当前电梯的状态private int state;public void setState(int state) {this.state = state;}public void open() {switch (state) { // 当前电梯状态case OPENING_STATE :// 什么事都不做break;case CLOSING_STATE :System.out.println("电梯打开了...");// 设置当前电梯状态为开启状态setState(OPENING_STATE);break;case STOPPING_STATE :System.out.println("电梯打开了...");// 设置当前电梯状态为开启状态setState(OPENING_STATE);break;case RUNNING_STATE :// 什么事都不做break;}}public void close() {switch (this.state) {case OPENING_STATE:System.out.println("电梯关门了。。。"); // 只有开门状态可以关闭电梯门,可以对应电梯状态表来看this.setState(CLOSING_STATE); // 关门之后电梯就是关闭状态了break;case CLOSING_STATE:// do nothing // 已经是关门状态,不能关门break;case RUNNING_STATE:// do nothing // 运行时电梯门是关着的,不能关门break;case STOPPING_STATE:// do nothing // 停止时电梯也是关着的,不能关门break;}}public void run() {switch (this.state) {case OPENING_STATE: // 电梯不能开着门就走// do nothingbreak;case CLOSING_STATE: // 门关了,可以运行了System.out.println("电梯开始运行了。。。");this.setState(RUNNING_STATE); // 现在是运行状态break;case RUNNING_STATE:// do nothing 已经是运行状态了break;case STOPPING_STATE:System.out.println("电梯开始运行了。。。");this.setState(RUNNING_STATE);break;}}public void stop() {switch (this.state) {case OPENING_STATE: // 开门的电梯已经是是停止的了(正常情况下)// do nothing break;case CLOSING_STATE: // 关门时才可以停止System.out.println("电梯停止了。。。");this.setState(STOPPING_STATE);break;case RUNNING_STATE: // 运行时当然可以停止了System.out.println("电梯停止了。。。");this.setState(STOPPING_STATE);break;case STOPPING_STATE:// do nothingbreak;}}
}
测试类
/*** 测试类** @author LiaoYuXing-Ray**/
public class Client {public static void main(String[] args) {// 创建电梯对象Lift lift = new Lift();/*设置当前电梯的状态*/lift.setState(ILift.OPENING_STATE);lift.open();lift.close();lift.run();lift.stop();System.out.println("\n=== 我是一条华丽的分割线 ===\n");lift.setState(ILift.CLOSING_STATE);lift.open();lift.close();lift.run();lift.stop();System.out.println("\n=== 我是一条华丽的分割线 ===\n");lift.setState(ILift.RUNNING_STATE);lift.open();lift.close();lift.run();lift.stop();System.out.println("\n=== 我是一条华丽的分割线 ===\n");lift.setState(ILift.STOPPING_STATE);lift.open();lift.close();lift.run();lift.stop();}
}

  代码运行结果如下:

	电梯关门了。。。电梯开始运行了。。。电梯停止了。。。=== 我是一条华丽的分割线 ===电梯打开了...电梯关门了。。。电梯开始运行了。。。电梯停止了。。。=== 我是一条华丽的分割线 ===电梯停止了。。。=== 我是一条华丽的分割线 ===电梯打开了...电梯关门了。。。电梯开始运行了。。。电梯停止了。。。

问题分析:

  • 使用了大量的switch…case这样的判断(if…else也是一样),使程序的可阅读性变差。
  • 扩展性很差。如果新加了断电的状态,我们需要修改上面判断逻辑

2.3 代码实现(状态模式)

  对上述电梯的案例使用状态模式进行改进。类图如下:

在这里插入图片描述

抽象状态类(抽象类)
/*** 抽象状态类** @author LiaoYuXing-Ray**/
public abstract class LiftState {// 声明环境角色类变量protected Context context;public void setContext(Context context) {this.context = context;}// 电梯开启操作public abstract void open();// 电梯关闭操作public abstract void close();// 电梯运行操作public abstract void run();// 电梯停止操作public abstract void stop();
}
电梯开启状态类(类)
/*** 电梯开启状态类** @author LiaoYuXing-Ray**/
public class OpeningState extends LiftState {// 当前状态要执行的方法public void open() {System.out.println("电梯开启。。。");}public void close() {// 修改状态super.context.setLiftState(Context.CLOSING_STATE);// 调用当前状态中的context中的close方法super.context.close();}public void run() {// 什么都不做}public void stop() {// 什么都不做}
}
电梯运行状态类(类)
/*** 电梯运行状态类** @author LiaoYuXing-Ray**/
public class RunningState extends LiftState {// 运行的时候开电梯门?你疯了!电梯不会给你开的@Overridepublic void open() {// do nothing}// 电梯门关闭?这是肯定了@Overridepublic void close() {// 虽然可以关门,但这个动作不归我执行// do nothing}// 这是在运行状态下要实现的方法@Overridepublic void run() {System.out.println("电梯正在运行...");}// 这个事绝对是合理的,光运行不停止还有谁敢做这个电梯?!估计只有上帝了@Overridepublic void stop() {super.context.setLiftState(Context.STOPPING_STATE);super.context.stop();}
}
电梯停止状态类(类)
/*** 电梯停止状态类** @author LiaoYuXing-Ray**/
public class StoppingState extends LiftState {// 停止状态,开门,那是要的!@Overridepublic void open() {// 状态修改super.context.setLiftState(Context.OPENING_STATE);// 动作委托为CloseState来执行,也就是委托给了ClosingState子类执行这个动作super.context.getLiftState().open();}// 虽然可以关门,但这个动作不归我执行@Overridepublic void close() {// 状态修改super.context.setLiftState(Context.CLOSING_STATE);// 动作委托为CloseState来执行,也就是委托给了ClosingState子类执行这个动作super.context.getLiftState().close();}// 停止状态再跑起来,正常的很@Overridepublic void run() {// 状态修改super.context.setLiftState(Context.RUNNING_STATE);// 动作委托为CloseState来执行,也就是委托给了ClosingState子类执行这个动作super.context.getLiftState().run();}// 停止状态是怎么发生的呢?当然是停止方法执行了@Overridepublic void stop() {System.out.println("电梯停止了...");}
}
电梯关闭状态类(类)
/*** 电梯关闭状态类** @author LiaoYuXing-Ray**/
public class ClosingState extends LiftState {// 电梯门关闭,这是关闭状态要实现的动作@Overridepublic void close() {System.out.println("电梯门关闭...");}// 电梯门关了再打开@Overridepublic void open() {super.context.setLiftState(Context.OPENING_STATE);super.context.open();}// 电梯门关了就跑,这是再正常不过了@Overridepublic void run() {super.context.setLiftState(Context.RUNNING_STATE);super.context.run();}// 电梯门关着,我就不按楼层@Overridepublic void stop() {super.context.setLiftState(Context.STOPPING_STATE);super.context.stop();}
}
环境角色类(类)
/*** 环境角色类** @author LiaoYuXing-Ray**/
public class Context {// 定义对应状态对象的常量public final static OpeningState OPENING_STATE = new OpeningState();public final static ClosingState CLOSING_STATE = new ClosingState();public final static RunningState RUNNING_STATE = new RunningState();public final static StoppingState STOPPING_STATE = new StoppingState();// 定义一个当前电梯状态变量private LiftState liftState;public LiftState getLiftState() {return liftState;}// 设置当前状态对象public void setLiftState(LiftState liftState) {this.liftState = liftState;// 设置当前状态对象中的Context对象this.liftState.setContext(this);}public void open() {this.liftState.open();}public void close() {this.liftState.close();}public void run() {this.liftState.run();}public void stop() {this.liftState.stop();}
}
测试类
/*** 测试类** @author LiaoYuXing-Ray**/
public class Client {public static void main(String[] args) {// 创建环境角色对象Context context = new Context();/*设置当前电梯装填*/context.setLiftState(new OpeningState());context.open();context.run();context.close();context.stop();System.out.println("\n=== 我是一条华丽的分割线 ===\n");context.setLiftState(new RunningState());context.open();context.run();context.close();context.stop();System.out.println("\n=== 我是一条华丽的分割线 ===\n");context.setLiftState(new StoppingState());context.open();context.run();context.close();context.stop();System.out.println("\n=== 我是一条华丽的分割线 ===\n");context.setLiftState(new ClosingState());context.open();context.run();context.close();context.stop();}
}

  代码运行结果如下:

	电梯开启。。。电梯门关闭...电梯停止了...=== 我是一条华丽的分割线 ===电梯正在运行...电梯停止了...=== 我是一条华丽的分割线 ===电梯开启。。。电梯门关闭...电梯停止了...=== 我是一条华丽的分割线 ===电梯开启。。。电梯门关闭...电梯停止了...

3 案例二

本案例为菜鸟教程中的案例

3.1 需求

  我们将创建一个 State 接口和实现了 State 接口的实体状态类。Context 是一个带有某个状态的类。StatePatternDemo,我们的演示类使用 Context 和状态对象来演示 Context 在状态改变时的行为变化。

在这里插入图片描述

3.2 代码实现

步骤 1

  创建一个接口。

State.java
public interface State {public void doAction(Context context);
}

步骤 2

  创建实现接口的实体类。

StartState.java
public class StartState implements State {public void doAction(Context context) {System.out.println("Player is in start state");context.setState(this); }public String toString(){return "Start State";}
}
StopState.java
public class StopState implements State {public void doAction(Context context) {System.out.println("Player is in stop state");context.setState(this); }public String toString(){return "Stop State";}
}

步骤 3

  创建 Context 类。

Context.java
public class Context {private State state;public Context(){state = null;}public void setState(State state){this.state = state;     }public State getState(){return state;}
}

步骤 4

  使用 Context 来查看当状态 State 改变时的行为变化。

StatePatternDemo.java
public class StatePatternDemo {public static void main(String[] args) {Context context = new Context();StartState startState = new StartState();startState.doAction(context);System.out.println(context.getState().toString());StopState stopState = new StopState();stopState.doAction(context);System.out.println(context.getState().toString());}
}

步骤 5

  执行程序,输出结果:

	Player is in start stateStart StatePlayer is in stop stateStop State



本文是博主的粗浅理解,可能存在一些错误或不完善之处,如有遗漏或错误欢迎各位补充,谢谢

  如果觉得这篇文章对您有所帮助的话,请动动小手点波关注💗,你的点赞👍收藏⭐️转发🔗评论📝都是对博主最好的支持~


相关文章:

瑞_23种设计模式_状态模式

文章目录 1 状态模式(State Pattern)1.1 介绍1.2 概述1.3 状态模式的结构1.4 状态模式的优缺点1.5 状态模式的使用场景 2 案例一2.1 需求2.2 代码实现(未使用状态模式)2.3 代码实现(状态模式) 3 案例二3.1 …...

system Verilog:clocking中定义信号为input和output的区别

在SystemVerilog中,clocking块用于定义时钟块,这通常用于描述时钟边缘和同步的输入/输出行为,特别是在测试平台和硬件接口描述中。 在下述两个代码示例中,主要区别在于a被定义为一个input还是output。 当a被定义为input时&#x…...

JAVA_Tomcat

Tomcat 使用教程 1.下载: http://tomcat.apache.org/ 2.安装: 解压压缩包(安装目录不要有中文) 3.卸载: 删除目录即可 4.启动: 运行./bin/startup.sh1.黑窗口一闪而过: 没有配置好JDK环境变量2.启动报错(查看日志文件): 端口占用 5.关闭: 1.强制关闭: 点击窗口关闭按钮2.正常…...

uniapp运行项目到微信小程序报错——未找到[“sitemapLocation“]

效果图 解决方式 重新运行项目即可;...

pytorch升级打怪(八)

保存模型和加载已有模型 保存并加载模型保存加载 保存并加载模型 在本节中,我们将研究如何通过保存、加载和运行模型预测来保持模型状态。 import torch import torchvision.models as models保存 PyTorch模型将学习的参数存储在内部状态字典中,称为s…...

全智能深度演进,一键成片让视频创作颠覆式提效

全智能一键成片,让内容创作的「边际成本」逼近于零。 大模型和AIGC技术的发展,可以用“日新月异”来形容,其迭代速度史无前例,涌现出的各类垂直应用模型,也使得音视频行业的应用场景更加广泛和多样化。 然而&#xff…...

uniapp(vue3) H5页面连接打印机并打印

一、找到对应厂商打印机的驱动并在windows上面安装。查看是否安装完成可以在:控制面板->查看设备和打印机,找到对应打印机驱动是否安装完成 二、打印机USB连接电脑 三、运行代码调用浏览器打印,主要使用的是window.print()功能。下面使用…...

Android视角看鸿蒙第八课(module.json5中的各字段含义之abilities)下

Android视角看鸿蒙第八课(module.json5中的各字段含义之abilities)下 导读 上篇文章开始学习abilities下的各字段含义,因为篇幅原因只学习了name、srcEntry、description、icon和label字段的含义和用法, 这篇文章继续学习和了解其他字段。 …...

设计模式 适配器模式

1.背景 适配器模式,这个模式也很简单,你笔记本上的那个拖在外面的黑盒子就是个适配器,一般你在中国能用,在日本也能用,虽然两个国家的的电源电压不同,中国是 220V,日本是 110V,但是这…...

前端面试题详解

前端面试 1.app如何实现登陆成功,卸载app重新安装再进入获取上一次已经登陆的信息? 要实现前端APP在登录成功后,即使卸载并重新安装也能获取上一次已经登录的信息,通常涉及以下几个关键步骤: 1. 使用持久化存储 在APP…...

抖音,剪映,TikTok,竖屏短视频转场pr模板视频素材

120个叠加效果视频转场过渡素材,抖音,剪映,TikTok,短视频转场pr模板项目工程文件。 效果:VHS、光效、胶片、霓虹灯闪光、X射线、信号、老电影等。 适用软件:Adobe Premiere Pro 2018 12.0或更高版本。 视频素材与大多数应用程序兼容&#xff…...

python网络相册设计与实现flask-django-nodejs-php

此系统设计主要采用的是python语言来进行开发,采用django框架技术,框架分为三层,分别是控制层Controller,业务处理层Service,持久层dao,能够采用多层次管理开发,对于各个模块设计制作有一定的安…...

设计模式: 外观模式

文章目录 一、什么是外观模式二、外观模式结构1、外观模式的主要角色包括:2、外观模式通常适用于以下情况: 三、优点 一、什么是外观模式 外观模式(Facade Pattern)是一种结构型设计模式,它提供了一个统一的接口&…...

Samba局域网共享文件

基于两个协议:smb协议(Server Message Block,服务消息块)和cifs协议(Common Internet File System,通用互联网文件系统) 两个主进程:smbd 和nmbd进程。 smbd:提供对服务…...

基于FPGA实现的UDP协议栈设计_汇总

基于FPGA实现的千兆以太网UDP协议栈设计(汇总篇) 1. MAC设计 2. IP层设计 3. ARP层设计 4. UDP层设计 5. ICMP层设计 6. 仲裁器设计 8. RGMII接口设计 9. 跨时钟域设计...

maven手动上传的第三方包 打包项目报错 Could not find xxx in central 解决办法

背景: 在Maven私服手动上传了第三方的jar包, 只有jar包, 没有pom文件, 项目在ide中可以正常编译启动,但打包报错无法找到jar包 解决办法: 上传jar包的时候, 点击生成pom. 则打包的时候不会报错...

利用Scala与Apache HttpClient实现网络音频流的抓取

概述 在当今数字化时代,网络数据的抓取和处理已成为许多应用程序和服务的重要组成部分。本文将介绍如何利用Scala编程语言结合Apache HttpClient工具库实现网络音频流的抓取。通过本文,读者将学习如何利用强大的Scala语言和Apache HttpClient库来抓取网…...

Linux(openEuler)部署SpringBoot前后端分离项目(Nginx负载均衡)

假如数据库在本地,没有放在Linux中 1.先把数据库中root的主机改成% 2.项目中的数据库链接配置换成本机ip 3.打包 4.把打包好的jar包放到Linux中 一般把jar包放到opt下 5.把前端部分拷贝到Linux的nginx中 5.1在package.json中修改build的值为图中这样 5.2同时由于在…...

InnoDB 缓存

本文主要聊InnoDB内存结构, 先来看下官网Mysql 8.0 InnoDB架构图 MySQL :: MySQL 8.0 Reference Manual :: 17.4 InnoDB Architecture 如上图所示,InnoDB内存主要包含Buffer Pool, Change Buffer, Log Buffer, Adaptive Hash Index Buffer Pool 其实 buffer pool 就是内存中的…...

目标检测——PP-YOLOE-R算法解读

PP-YOLO系列,均是基于百度自研PaddlePaddle深度学习框架发布的算法,2020年基于YOLOv3改进发布PP-YOLO,2021年发布PP-YOLOv2和移动端检测算法PP-PicoDet,2022年发布PP-YOLOE和PP-YOLOE-R。由于均是一个系列,所以放一起解…...

Vim 调用外部命令学习笔记

Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...

Xshell远程连接Kali(默认 | 私钥)Note版

前言:xshell远程连接,私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别

UnsatisfiedLinkError 在对接硬件设备中,我们会遇到使用 java 调用 dll文件 的情况,此时大概率出现UnsatisfiedLinkError链接错误,原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用,结果 dll 未实现 JNI 协…...

学校招生小程序源码介绍

基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码,专为学校招生场景量身打造,功能实用且操作便捷。 从技术架构来看,ThinkPHP提供稳定可靠的后台服务,FastAdmin加速开发流程,UniApp则保障小程序在多端有良好的兼…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1

每日一言 生活的美好,总是藏在那些你咬牙坚持的日子里。 硬件:OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写,"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...

解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错

出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上,所以报错,到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本,cu、torch、cp 的版本一定要对…...

分布式增量爬虫实现方案

之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面,避免重复抓取,以节省资源和时间。 在分布式环境下,增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路:将增量判…...

DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”

目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

iview框架主题色的应用

1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题,无需引入,直接可…...