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

C++软件设计模式之状态模式

在C++设计模式中,状态模式(State Pattern)是一种行为设计模式,它允许对象在内部状态改变时改变其行为,使对象看起来似乎修改了其类。状态模式的主要动机、意图和适用场合如下:

动机

在面向对象的设计中,对象的行为往往依赖于其状态。传统的实现方式是在对象中使用大量的条件语句来检查状态并执行相应的操作。这种做法有以下几个问题:

  • 代码复杂性:随着状态的增多,条件语句会变得越来越复杂,难以维护。
  • 可扩展性差:添加新状态时,需要修改现有的条件语句,违反了开闭原则(对扩展开放,对修改关闭)。
  • 状态转移不清晰:状态之间的转移逻辑分散在各个地方,不便于管理和理解。

为了解决这些问题,状态模式应运而生。

意图

状态模式的意图是将对象的状态抽象成类层次结构,并将行为封装在这些状态类中。具体来说:

  • 定义一个状态接口,该接口声明了所有可能状态共有的操作。
  • 为每种状态实现一个具体的类,每个类都实现了状态接口中的操作,并在必要时处理状态转换。
  • 维护一个当前状态的引用,主体对象通过这个引用委托给当前状态对象执行相应的操作。

通过这种方式,状态模式将状态相关的逻辑从主体类中分离出来,使得代码更加清晰、模块化,并且易于扩展。

适用场景

状态模式适用于以下情况:

  1. 对象行为依赖于其状态,且需要根据状态改变行为。
  2. 状态之间有复杂的转移逻辑,需要明确地定义状态转换规则。
  3. 希望将状态相关的代码集中管理,提高代码的可维护性和可扩展性。
  4. 需要对不同的状态进行不同的操作,并且这些操作可能涉及复杂的业务逻辑。

例如,一个自动售货机可以根据其当前状态(如待支付、已支付、缺货等)执行不同的操作,如接收硬币、发放商品、退还余额等。使用状态模式可以清晰地定义每种状态下的行为以及状态之间的转换。

示例代码

以下是一个简单的C++示例,展示了状态模式的使用:

#include <iostream>
#include <memory>// 状态接口
class State {
public:virtual void handle(const std::string& input) = 0;virtual ~State() = default;
};// 具体状态A
class StateA : public State {
public:void handle(const std::string& input) override {std::cout << "StateA handles: " << input << std::endl;// 可能会转换到其他状态}
};// 具体状态B
class StateB : public State {
public:void handle(const std::string& input) override {std::cout << "StateB handles: " << input << std::endl;// 可能会转换到其他状态}
};// 主体类
class Context {
public:void setState(std::shared_ptr<State> state) {currentState = state;}void request(const std::string& input) {if (currentState) {currentState->handle(input);}}
private:std::shared_ptr<State> currentState;
};int main() {// 创建具体状态实例auto stateA = std::make_shared<StateA>();auto stateB = std::make_shared<StateB>();// 创建上下文并设置初始状态Context context;context.setState(stateA);// 处理请求context.request("Initial request");// 转换状态context.setState(stateB);context.request("Another request");return 0;
}

在这个示例中,Context 类维护了一个 State 接口的指针,并将处理请求委托给当前状态对象。不同的状态类 (StateA 和 StateB) 实现了不同的处理逻辑。通过设置不同的状态,Context 对象可以表现出不同的行为。

通过这种方式,状态模式使得状态相关的逻辑更加清晰和模块化,同时也便于添加新的状态而不需要修改现有的代码。

 

面是一个使用状态模式来模拟Windows PnP(Plug and Play)设备驱动中状态转移的C++示例。我们将定义一个设备驱动类和多个状态类,每个状态类将处理不同状态下的设备行为和状态转移。

状态模式在PnP设备驱动中的应用

  1. 定义状态接口:定义一个状态接口 State,声明所有可能状态共有的操作。
  2. 实现具体状态类:为每种状态(如 UnpluggedPlugInInitializeReady)实现一个具体的类。
  3. 维护当前状态:在 DeviceDriver 类中维护一个当前状态的引用,并根据需要切换状态。

示例代码

#include <iostream>
#include <memory>
#include <string>// 状态接口
class State {
public:virtual ~State() = default;virtual void onUnplug(DeviceDriver* driver) = 0;virtual void onPlugIn(DeviceDriver* driver) = 0;virtual void onInitialize(DeviceDriver* driver) = 0;virtual void onReady(DeviceDriver* driver) = 0;
};// 设备驱动类
class DeviceDriver {
public:DeviceDriver() : currentState(std::make_shared<Unplugged>()) {}void unplug() {currentState->onUnplug(this);}void plugIn() {currentState->onPlugIn(this);}void initialize() {currentState->onInitialize(this);}void ready() {currentState->onReady(this);}void setState(const std::shared_ptr<State>& state) {currentState = state;}private:std::shared_ptr<State> currentState;
};// 具体状态:未插入
class Unplugged : public State {
public:void onUnplug(DeviceDriver* driver) override {std::cout << "Already unplugged." << std::endl;}void onPlugIn(DeviceDriver* driver) override {std::cout << "Device plugged in." << std::endl;driver->setState(std::make_shared<PlugIn>());}void onInitialize(DeviceDriver* driver) override {std::cout << "Cannot initialize. Device not plugged in." << std::endl;}void onReady(DeviceDriver* driver) override {std::cout << "Cannot be ready. Device not plugged in." << std::endl;}
};// 具体状态:已插入
class PlugIn : public State {
public:void onUnplug(DeviceDriver* driver) override {std::cout << "Device unplugged." << std::endl;driver->setState(std::make_shared<Unplugged>());}void onPlugIn(DeviceDriver* driver) override {std::cout << "Already plugged in." << std::endl;}void onInitialize(DeviceDriver* driver) override {std::cout << "Device initialized." << std::endl;driver->setState(std::make_shared<Initialize>());}void onReady(DeviceDriver* driver) override {std::cout << "Cannot be ready. Device not initialized." << std::endl;}
};// 具体状态:已初始化
class Initialize : public State {
public:void onUnplug(DeviceDriver* driver) override {std::cout << "Device unplugged." << std::endl;driver->setState(std::make_shared<Unplugged>());}void onPlugIn(DeviceDriver* driver) override {std::cout << "Already plugged in and initialized." << std::endl;}void onInitialize(DeviceDriver* driver) override {std::cout << "Already initialized." << std::endl;}void onReady(DeviceDriver* driver) override {std::cout << "Device is ready to use." << std::endl;driver->setState(std::make_shared<Ready>());}
};// 具体状态:已准备好
class Ready : public State {
public:void onUnplug(DeviceDriver* driver) override {std::cout << "Device unplugged." << std::endl;driver->setState(std::make_shared<Unplugged>());}void onPlugIn(DeviceDriver* driver) override {std::cout << "Device is already ready." << std::endl;}void onInitialize(DeviceDriver* driver) override {std::cout << "Device is already initialized and ready." << std::endl;}void onReady(DeviceDriver* driver) override {std::cout << "Device is already ready." << std::endl;}
};int main() {DeviceDriver driver;// 模拟设备插拔和状态转移driver.plugIn();driver.initialize();driver.ready();driver.unplug();driver.plugIn();driver.ready();return 0;
}

代码说明

  1. 状态接口 State

    • 定义了四个虚函数:onUnplugonPlugInonInitializeonReady,分别对应设备在不同状态下的行为。
  2. 设备驱动类 DeviceDriver

    • 维护一个当前状态 currentState,并提供四个公共方法 unplugplugIninitializeready,这些方法委托给当前状态对象处理。
    • 提供 setState 方法用于切换状态。
  3. 具体状态类

    • Unplugged:设备未插入状态。
    • PlugIn:设备已插入状态。
    • Initialize:设备已初始化状态。
    • Ready:设备已准备好状态。
  4. 主函数 main

    • 创建一个 DeviceDriver 对象,并模拟设备的插拔和状态转移过程。

通过这种方式,状态模式使得设备驱动的代码更加模块化和可维护,状态之间的转换也更加清晰

 

状态模式通常与其他设计模式协同使用,以提高代码的模块化和可维护性。以下是状态模式常见的协同模式及其使用场景:

1. 策略模式 (Strategy Pattern)

  • 场景:当不同状态下的行为可以通过不同的算法实现时,可以使用策略模式来定义这些算法。
  • 协同方式:状态模式中的每个状态类可以包含一个策略对象,用于实现具体的行为。这样,状态的改变不仅涉及状态的切换,还可以动态改变算法。
  • 示例:在状态模式中,不同状态下的设备初始化可以使用不同的初始化策略。

2. 工厂模式 (Factory Pattern)

  • 场景:当状态类的创建需要复杂逻辑时,可以使用工厂模式来创建状态对象。
  • 协同方式:通过工厂模式,可以在状态切换时动态创建所需的状态对象,而不需要在每个地方重复创建逻辑。
  • 示例:使用工厂模式创建设备驱动的初始状态或特定状态。

3. 观察者模式 (Observer Pattern)

  • 场景:当状态变化需要通知其他对象时,可以使用观察者模式。
  • 协同方式:状态对象可以充当被观察者,其他对象(如日志记录器、UI 更新器等)可以注册为观察者,当状态变化时,观察者会收到通知并作出相应处理。
  • 示例:在设备驱动状态变化时,通知UI更新显示状态。

4. 单例模式 (Singleton Pattern)

  • 场景:当状态类需要全局唯一实例时,可以使用单例模式。
  • 协同方式:状态类可以通过单例模式确保每个状态在整个应用中只有一个实例,这有助于节省资源并确保状态的一致性。
  • 示例:确保设备的“未插入”状态在整个应用中只有一个实例。

5. 模板方法模式 (Template Method Pattern)

  • 场景:当状态类有共同的骨架方法,但具体实现不同步时,可以使用模板方法模式。
  • 协同方式:状态类可以定义一个模板方法,该方法包含一系列步骤,其中某些步骤的具体实现由具体的子类提供。
  • 示例:定义一个模板方法 handleEvent,该方法包含一系列步骤,如检查前置条件、执行操作、更新状态等,具体状态类可以覆盖这些步骤的实现。

6. 命令模式 (Command Pattern)

  • 场景:当状态变化需要记录或撤销时,可以使用命令模式。
  • 协同方式:每个状态变化可以封装成一个命令对象,命令对象可以记录状态变化的操作,便于撤回或重做。
  • 示例:记录设备状态变化的命令,以便在需要时恢复到之前的状态。

7. 责任链模式 (Chain of Responsibility Pattern)

  • 场景:当状态变化需要多个对象处理时,可以使用责任链模式。
  • 协同方式:状态变化可以传递给一个链中的多个对象,每个对象根据其职责处理或传递请求。
  • 示例:当设备状态变化时,多个处理器(如日志记录器、安全检查器等)可以顺序处理该状态变化。

示例

以下是一个结合状态模式和工厂模式、策略模式的示例:

#include <iostream>
#include <memory>
#include <string>// 策略接口
class InitializationStrategy {
public:virtual void initialize() = 0;virtual ~InitializationStrategy() = default;
};// 具体策略:快速初始化
class QuickInitialization : public InitializationStrategy {
public:void initialize() override {std::cout << "Quick initialization" << std::endl;}
};// 具体策略:完整初始化
class FullInitialization : public InitializationStrategy {
public:void initialize() override {std::cout << "Full initialization" << std::endl;}
};// 状态接口
class State {
public:virtual ~State() = default;virtual void onUnplug(DeviceDriver* driver) = 0;virtual void onPlugIn(DeviceDriver* driver) = 0;virtual void onInitialize(DeviceDriver* driver) = 0;virtual void onReady(DeviceDriver* driver) = 0;
};// 状态工厂类
class StateFactory {
public:static std::shared_ptr<State> createUnpluggedState() {return std::make_shared<Unplugged>();}static std::shared_ptr<State> createPlugInState() {return std::make_shared<PlugIn>();}static std::shared_ptr<State> createInitializeState() {return std::make_shared<Initialize>();}static std::shared_ptr<State> createReadyState() {return std::make_shared<Ready>();}
};// 设备驱动类
class DeviceDriver {
public:DeviceDriver() : currentState(StateFactory::createUnpluggedState()) {}void unplug() {currentState->onUnplug(this);}void plugIn() {currentState->onPlugIn(this);}void initialize() {currentState->onInitialize(this);}void ready() {currentState->onReady(this);}void setState(const std::shared_ptr<State>& state) {currentState = state;}private:std::shared_ptr<State> currentState;
};// 具体状态:未插入
class Unplugged : public State {
public:void onUnplug(DeviceDriver* driver) override {std::cout << "Already unplugged." << std::endl;}void onPlugIn(DeviceDriver* driver) override {std::cout << "Device plugged in." << std::endl;driver->setState(StateFactory::createPlugInState());}void onInitialize(DeviceDriver* driver) override {std::cout << "Cannot initialize. Device not plugged in." << std::endl;}void onReady(DeviceDriver* driver) override {std::cout << "Cannot be ready. Device not plugged in." << std::endl;}
};// 具体状态:已插入
class PlugIn : public State {
public:PlugIn() : strategy(std::make_unique<QuickInitialization>()) {}void onUnplug(DeviceDriver* driver) override {std::cout << "Device unplugged." << std::endl;driver->setState(StateFactory::createUnpluggedState());}void onPlugIn(DeviceDriver* driver) override {std::cout << "Already plugged in." << std::endl;}void onInitialize(DeviceDriver* driver) override {std::cout << "Device initialized." << std::endl;strategy->initialize();driver->setState(StateFactory::createInitializeState());}void onReady(DeviceDriver* driver) override {std::cout << "Cannot be ready. Device not initialized." << std::endl;}private:std::unique_ptr<InitializationStrategy> strategy;
};// 具体状态:已初始化
class Initialize : public State {
public:void onUnplug(DeviceDriver* driver) override {std::cout << "Device unplugged." << std::endl;driver->setState(StateFactory::createUnpluggedState());}void onPlugIn(DeviceDriver* driver) override {std::cout << "Already plugged in and initialized." << std::endl;}void onInitialize(DeviceDriver* driver) override {std::cout << "Already initialized." << std::endl;}void onReady(DeviceDriver* driver) override {std::cout << "Device is ready to use." << std::endl;driver->setState(StateFactory::createReadyState());}
};// 具体状态:已准备好
class Ready : public State {
public:void onUnplug(DeviceDriver* driver) override {std::cout << "Device unplugged." << std::endl;driver->setState(StateFactory::createUnpluggedState());}void onPlugIn(DeviceDriver* driver) override {std::cout << "Device is already ready." << std::endl;}void onInitialize(DeviceDriver* driver) override {std::cout << "Device is already initialized and ready." << std::endl;}void onReady(DeviceDriver* driver) override {std::cout << "Device is already ready." << std::endl;}
};int main() {DeviceDriver driver;// 模拟设备插拔和状态转移driver.plugIn();driver.initialize();driver.ready();driver.unplug();driver.plugIn();driver.ready();return 0;
}

代码说明

  1. 策略接口 InitializationStrategy

    • 定义了一个初始化策略接口,包含一个 initialize 方法。
    • 具体策略类 QuickInitialization 和 FullInitialization 实现了不同的初始化策略。
  2. 状态工厂类 StateFactory

    • 提供静态方法创建不同状态的实例。
  3. 具体状态类 PlugIn

    • 包含一个策略对象 strategy,在 onInitialize 方法中使用该策略进行初始化。
  4. 主函数 main

    • 创建一个 DeviceDriver 对象,并模拟设备的插拔和状态转移过程。

通过这种方式,状态模式与工厂模式和策略模式协同使用,使得代码更加灵活和可维护。

相关文章:

C++软件设计模式之状态模式

在C设计模式中&#xff0c;状态模式&#xff08;State Pattern&#xff09;是一种行为设计模式&#xff0c;它允许对象在内部状态改变时改变其行为&#xff0c;使对象看起来似乎修改了其类。状态模式的主要动机、意图和适用场合如下&#xff1a; 动机 在面向对象的设计中&…...

Microsoft Visual Studio中的/MT, /MTd,/MD,/MDd分别是什么意思?

1. /MT&#xff0c;/MTd&#xff0c;/MD&#xff0c;/MDd的含义 /MT&#xff0c;/MTd&#xff0c;/MD&#xff0c;/MDd是 Microsoft Visual C 编译器的运行时库链接选项。它们决定了程序如何链接 C 运行时库&#xff08;CRT&#xff09;。具体含义如下&#xff1a; /MT&#x…...

谷粒商城项目125-spring整合high-level-client

新年快乐! 致2025年还在努力学习的你! 你已经很努力了&#xff0c;今晚就让自己好好休息一晚吧! 在后端中选用哪种elasticsearch客户端&#xff1f; elasticsearch可以通过9200或者9300端口进行操作 1&#xff09;9300&#xff1a;TCP spring-data-elasticsearch:transport-…...

日期时间选择(设置禁用状态)

目录 1.element文档需要 2.禁用所有过去的时间 3.设置指定日期的禁用时间 <template><div class"block"><span class"demonstration">起始日期时刻为 12:00:00</span><el-date-pickerv-model"value1"type"dat…...

基于SpringBoot的题库管理系统的设计与实现(源码+SQL+LW+部署讲解)

文章目录 摘 要1. 第1章 选题背景及研究意义1.1 选题背景1.2 研究意义1.3 论文结构安排 2. 第2章 相关开发技术2.1 前端技术2.2 后端技术2.3 数据库技术 3. 第3章 可行性及需求分析3.1 可行性分析3.2 系统需求分析 4. 第4章 系统概要设计4.1 系统功能模块设计4.2 数据库设计 5.…...

钉钉h5微应用安卓报错error29 ios报错error3 加上报错52013,签名校验失败 (前端)

这两个都是应为 免登报错52013&#xff0c;签名校验失败 用户后端签名使用的url地址和前端访问地址需要严格一致&#xff0c;包括端口号。前端部分可以用alert显示出当前的location.href&#xff0c;后端部分请在签名的时候打印日志。 访问通过反向代理服务器、各种NAT等场景下…...

Vue.js组件开发-客户端如何限制刷新Token次数

在Vue.js组件开发中&#xff0c;限制刷新Token的次数是一个重要的安全措施&#xff0c;可以防止恶意用户或攻击者无限次尝试刷新Token。 客户端限制 在客户端&#xff0c;可以通过Vuex、localStorage或sessionStorage等存储机制来跟踪刷新Token的尝试次数。以下是一个基本的实…...

Linux上安装jdk

在线环境的话&#xff0c;通过命令下载&#xff0c;离线环境的话&#xff0c;组要自行去oracle官网下载后上传 wget --no-check-certificate --no-cookies --header "Cookie: oraclelicenseaccept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jd…...

Ardunio BLE keyboard 库的使用

为了开发一个 ardunio 的蓝牙选歌器&#xff0c;网络上普遍推荐使用&#xff1a; https://github.com/T-vK/ESP32-BLE-Keyboard 结果搞了好几天&#xff0c;就是不行。最后发现&#xff0c;下面两点非常重要&#xff1a; 使用 NimBle-ardunio 库这个库目前是2.1.2 &#xff…...

django --递归查询评论

表数据 树状结构 action(methods(GET, ), detailFalse) def get_info_pinglun(self, request, *args, **kwargs) -> Response:根据评论id查所有回复params wenxian_pinglun_id --> 评论id;wenxian_pinglun_id self.request.GET.get(wenxian_pinglun_id)results se…...

【开源免费】基于SpringBoot+Vue.JS音乐网站(JAVA毕业设计)

本文项目编号 T 109 &#xff0c;文末自助获取源码 \color{red}{T109&#xff0c;文末自助获取源码} T109&#xff0c;文末自助获取源码 目录 一、系统介绍二、数据库设计三、配套教程3.1 启动教程3.2 讲解视频3.3 二次开发教程 四、功能截图五、文案资料5.1 选题背景5.2 国内…...

SUBSTRING_INDEX()在MySQL中的用法

语法&#xff1a; SUBSTRING_INDEX() 是 MySQL 中的一个字符串函数&#xff0c;它返回一个字符串&#xff0c;该字符串包含从字符串的开始或结束到指定的子字符串出现指定次数为止的部分。这个函数的语法如下&#xff1a; SUBSTRING_INDEX(string, delimiter, count)string&a…...

对45家“AI+安全”产品/方案的分析

一. 关键洞察 “AI+安全”创新非常活跃,一片百家争鸣之势,赛道选择上,以事件分诊Incident Triage、 安全辅助Security Copilots、自动化Automation三者为主为主,这充分反映了当前安全运营的主要需求,在产品理念选择上以 AI 和 自动化为主,这确实又切合上了在关键…...

Oracle Dataguard(主库为 Oracle 11g 单节点)配置详解(1):Oracle Dataguard 概述

Oracle Dataguard&#xff08;主库为 Oracle 11g 单节点&#xff09;配置详解&#xff08;1&#xff09;&#xff1a;Oracle Dataguard 概述 目录 Oracle Dataguard&#xff08;主库为 Oracle 11g 单节点&#xff09;配置详解&#xff08;1&#xff09;&#xff1a;Oracle Data…...

Pycharm 中 virtualenv、pipenv、conda 虚拟环境的用法

文章目录 前言虚拟环境的通俗介绍虚拟环境和非虚拟环境该怎么选?通过 Virtualenv 方式创建虚拟环境通过 Pipenv 方式创建虚拟环境通过 Conda 方式创建虚拟环境前言 在网上找了好一些资料,发现介绍 Pycharm 虚拟环境的不多,查了一些资料,并做个总结。 本文主要是介绍 Pycha…...

UNI-APP弹窗

组件代码 <template><view><!-- 蒙版 --><view class"mask" click"close()" v-show"tanchuang"></view><!-- 弹窗 --><view class"pop" :style"{height:height*0.8 px,top:tanchuang?…...

【大模型实战篇】LLaMA Factory微调ChatGLM-4-9B模型

1. 背景介绍 虽然现在大模型微调的文章很多&#xff0c;但纸上得来终觉浅&#xff0c;大模型微调的体感还是需要自己亲自上手实操过&#xff0c;才能有一些自己的感悟和直觉。这次我们选择使用llama_factory来微调chatglm-4-9B大模型。 之前微调我们是用两块3090GPU显卡&…...

【Cesium】三、实现开场动画效果

文章目录 实现效果实现方法实现代码组件化 实现效果 实现方法 Cesium官方提供了Camera的flyTo方法实现了飞向目的地的动画效果。 官方API&#xff1a;传送门 这里只需要用到目的地&#xff08;destination&#xff09;和持续时间&#xff08;duration&#xff09;这两个参数…...

#渗透测试#红蓝攻防#红队打点web服务突破口总结01

免责声明 本教程仅为合法的教学目的而准备&#xff0c;严禁用于任何形式的违法犯罪活动及其他商业行为&#xff0c;在使用本教程前&#xff0c;您应确保该行为符合当地的法律法规&#xff0c;继续阅读即表示您需自行承担所有操作的后果&#xff0c;如有异议&#xff0c;请立即停…...

适用于项目经理的跨团队协作实践:Atlassian Jira与Confluence集成

适用于项目经理的跨团队协作实践&#xff1a;Atlassian Jira与Confluence集成 现代项目经理的核心职责是提供可视性、保持团队一致&#xff0c;并确保团队拥有交付出色工作所需的资源。在过去几年中&#xff0c;由于分布式团队的需求不断增加&#xff0c;项目经理这一角色已迅速…...

XCTF-web-easyupload

试了试php&#xff0c;php7&#xff0c;pht&#xff0c;phtml等&#xff0c;都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接&#xff0c;得到flag...

CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型

CVPR 2025 | MIMO&#xff1a;支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题&#xff1a;MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者&#xff1a;Yanyuan Chen, Dexuan Xu, Yu Hu…...

STM32标准库-DMA直接存储器存取

文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA&#xff08;Direct Memory Access&#xff09;直接存储器存取 DMA可以提供外设…...

linux arm系统烧录

1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 &#xff08;忘了有没有这步了 估计有&#xff09; 刷机程序 和 镜像 就不提供了。要刷的时…...

Python如何给视频添加音频和字幕

在Python中&#xff0c;给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加&#xff0c;包括必要的代码示例和详细解释。 环境准备 在开始之前&#xff0c;需要安装以下Python库&#xff1a;…...

Redis数据倾斜问题解决

Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中&#xff0c;部分节点存储的数据量或访问量远高于其他节点&#xff0c;导致这些节点负载过高&#xff0c;影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...

如何在最短时间内提升打ctf(web)的水平?

刚刚刷完2遍 bugku 的 web 题&#xff0c;前来答题。 每个人对刷题理解是不同&#xff0c;有的人是看了writeup就等于刷了&#xff0c;有的人是收藏了writeup就等于刷了&#xff0c;有的人是跟着writeup做了一遍就等于刷了&#xff0c;还有的人是独立思考做了一遍就等于刷了。…...

Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?

在大数据处理领域&#xff0c;Hive 作为 Hadoop 生态中重要的数据仓库工具&#xff0c;其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式&#xff0c;很多开发者常常陷入选择困境。本文将从底…...

【生成模型】视频生成论文调研

工作清单 上游应用方向&#xff1a;控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...

网站指纹识别

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