C++软件设计模式之状态模式
在C++设计模式中,状态模式(State Pattern)是一种行为设计模式,它允许对象在内部状态改变时改变其行为,使对象看起来似乎修改了其类。状态模式的主要动机、意图和适用场合如下:
动机
在面向对象的设计中,对象的行为往往依赖于其状态。传统的实现方式是在对象中使用大量的条件语句来检查状态并执行相应的操作。这种做法有以下几个问题:
- 代码复杂性:随着状态的增多,条件语句会变得越来越复杂,难以维护。
- 可扩展性差:添加新状态时,需要修改现有的条件语句,违反了开闭原则(对扩展开放,对修改关闭)。
- 状态转移不清晰:状态之间的转移逻辑分散在各个地方,不便于管理和理解。
为了解决这些问题,状态模式应运而生。
意图
状态模式的意图是将对象的状态抽象成类层次结构,并将行为封装在这些状态类中。具体来说:
- 定义一个状态接口,该接口声明了所有可能状态共有的操作。
- 为每种状态实现一个具体的类,每个类都实现了状态接口中的操作,并在必要时处理状态转换。
- 维护一个当前状态的引用,主体对象通过这个引用委托给当前状态对象执行相应的操作。
通过这种方式,状态模式将状态相关的逻辑从主体类中分离出来,使得代码更加清晰、模块化,并且易于扩展。
适用场景
状态模式适用于以下情况:
- 对象行为依赖于其状态,且需要根据状态改变行为。
- 状态之间有复杂的转移逻辑,需要明确地定义状态转换规则。
- 希望将状态相关的代码集中管理,提高代码的可维护性和可扩展性。
- 需要对不同的状态进行不同的操作,并且这些操作可能涉及复杂的业务逻辑。
例如,一个自动售货机可以根据其当前状态(如待支付、已支付、缺货等)执行不同的操作,如接收硬币、发放商品、退还余额等。使用状态模式可以清晰地定义每种状态下的行为以及状态之间的转换。
示例代码
以下是一个简单的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设备驱动中的应用
- 定义状态接口:定义一个状态接口
State,声明所有可能状态共有的操作。 - 实现具体状态类:为每种状态(如
Unplugged、PlugIn、Initialize、Ready)实现一个具体的类。 - 维护当前状态:在
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;
}
代码说明
-
状态接口
State:- 定义了四个虚函数:
onUnplug、onPlugIn、onInitialize、onReady,分别对应设备在不同状态下的行为。
- 定义了四个虚函数:
-
设备驱动类
DeviceDriver:- 维护一个当前状态
currentState,并提供四个公共方法unplug、plugIn、initialize、ready,这些方法委托给当前状态对象处理。 - 提供
setState方法用于切换状态。
- 维护一个当前状态
-
具体状态类:
Unplugged:设备未插入状态。PlugIn:设备已插入状态。Initialize:设备已初始化状态。Ready:设备已准备好状态。
-
主函数
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;
}
代码说明
-
策略接口
InitializationStrategy:- 定义了一个初始化策略接口,包含一个
initialize方法。 - 具体策略类
QuickInitialization和FullInitialization实现了不同的初始化策略。
- 定义了一个初始化策略接口,包含一个
-
状态工厂类
StateFactory:- 提供静态方法创建不同状态的实例。
-
具体状态类
PlugIn:- 包含一个策略对象
strategy,在onInitialize方法中使用该策略进行初始化。
- 包含一个策略对象
-
主函数
main:- 创建一个
DeviceDriver对象,并模拟设备的插拔和状态转移过程。
- 创建一个
通过这种方式,状态模式与工厂模式和策略模式协同使用,使得代码更加灵活和可维护。
相关文章:
C++软件设计模式之状态模式
在C设计模式中,状态模式(State Pattern)是一种行为设计模式,它允许对象在内部状态改变时改变其行为,使对象看起来似乎修改了其类。状态模式的主要动机、意图和适用场合如下: 动机 在面向对象的设计中&…...
Microsoft Visual Studio中的/MT, /MTd,/MD,/MDd分别是什么意思?
1. /MT,/MTd,/MD,/MDd的含义 /MT,/MTd,/MD,/MDd是 Microsoft Visual C 编译器的运行时库链接选项。它们决定了程序如何链接 C 运行时库(CRT)。具体含义如下: /MT&#x…...
谷粒商城项目125-spring整合high-level-client
新年快乐! 致2025年还在努力学习的你! 你已经很努力了,今晚就让自己好好休息一晚吧! 在后端中选用哪种elasticsearch客户端? elasticsearch可以通过9200或者9300端口进行操作 1)9300: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,签名校验失败 用户后端签名使用的url地址和前端访问地址需要严格一致,包括端口号。前端部分可以用alert显示出当前的location.href,后端部分请在签名的时候打印日志。 访问通过反向代理服务器、各种NAT等场景下…...
Vue.js组件开发-客户端如何限制刷新Token次数
在Vue.js组件开发中,限制刷新Token的次数是一个重要的安全措施,可以防止恶意用户或攻击者无限次尝试刷新Token。 客户端限制 在客户端,可以通过Vuex、localStorage或sessionStorage等存储机制来跟踪刷新Token的尝试次数。以下是一个基本的实…...
Linux上安装jdk
在线环境的话,通过命令下载,离线环境的话,组要自行去oracle官网下载后上传 wget --no-check-certificate --no-cookies --header "Cookie: oraclelicenseaccept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jd…...
Ardunio BLE keyboard 库的使用
为了开发一个 ardunio 的蓝牙选歌器,网络上普遍推荐使用: https://github.com/T-vK/ESP32-BLE-Keyboard 结果搞了好几天,就是不行。最后发现,下面两点非常重要: 使用 NimBle-ardunio 库这个库目前是2.1.2 ÿ…...
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 ,文末自助获取源码 \color{red}{T109,文末自助获取源码} T109,文末自助获取源码 目录 一、系统介绍二、数据库设计三、配套教程3.1 启动教程3.2 讲解视频3.3 二次开发教程 四、功能截图五、文案资料5.1 选题背景5.2 国内…...
SUBSTRING_INDEX()在MySQL中的用法
语法: SUBSTRING_INDEX() 是 MySQL 中的一个字符串函数,它返回一个字符串,该字符串包含从字符串的开始或结束到指定的子字符串出现指定次数为止的部分。这个函数的语法如下: 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(主库为 Oracle 11g 单节点)配置详解(1):Oracle Dataguard 概述 目录 Oracle Dataguard(主库为 Oracle 11g 单节点)配置详解(1):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. 背景介绍 虽然现在大模型微调的文章很多,但纸上得来终觉浅,大模型微调的体感还是需要自己亲自上手实操过,才能有一些自己的感悟和直觉。这次我们选择使用llama_factory来微调chatglm-4-9B大模型。 之前微调我们是用两块3090GPU显卡&…...
【Cesium】三、实现开场动画效果
文章目录 实现效果实现方法实现代码组件化 实现效果 实现方法 Cesium官方提供了Camera的flyTo方法实现了飞向目的地的动画效果。 官方API:传送门 这里只需要用到目的地(destination)和持续时间(duration)这两个参数…...
#渗透测试#红蓝攻防#红队打点web服务突破口总结01
免责声明 本教程仅为合法的教学目的而准备,严禁用于任何形式的违法犯罪活动及其他商业行为,在使用本教程前,您应确保该行为符合当地的法律法规,继续阅读即表示您需自行承担所有操作的后果,如有异议,请立即停…...
适用于项目经理的跨团队协作实践:Atlassian Jira与Confluence集成
适用于项目经理的跨团队协作实践:Atlassian Jira与Confluence集成 现代项目经理的核心职责是提供可视性、保持团队一致,并确保团队拥有交付出色工作所需的资源。在过去几年中,由于分布式团队的需求不断增加,项目经理这一角色已迅速…...
SkyWalking 10.2.0 SWCK 配置过程
SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...
超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...
css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...
【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...
系统设计 --- MongoDB亿级数据查询优化策略
系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log,共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题,不能使用ELK只能使用…...
大模型多显卡多服务器并行计算方法与实践指南
一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...
Linux --进程控制
本文从以下五个方面来初步认识进程控制: 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程,创建出来的进程就是子进程,原来的进程为父进程。…...
使用 SymPy 进行向量和矩阵的高级操作
在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...
MySQL账号权限管理指南:安全创建账户与精细授权技巧
在MySQL数据库管理中,合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号? 最小权限原则…...
用机器学习破解新能源领域的“弃风”难题
音乐发烧友深有体会,玩音乐的本质就是玩电网。火电声音偏暖,水电偏冷,风电偏空旷。至于太阳能发的电,则略显朦胧和单薄。 不知你是否有感觉,近两年家里的音响声音越来越冷,听起来越来越单薄? —…...
