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

C++项目实战——基于多设计模式下的同步异步日志系统-③-前置知识补充-设计模式

文章目录

  • 专栏导读
  • 六大原则
  • 单例模式
    • 饿汉模式
    • 懒汉模式
  • 工厂模式
    • 简单工厂模式
    • 工厂方法模式
    • 抽象工厂模式
  • 建造者模式
  • 代理模式

专栏导读

🌸作者简介:花想云 ,在读本科生一枚,C/C++领域新星创作者,新星计划导师,阿里云专家博主,CSDN内容合伙人…致力于 C/C++、Linux 学习。

🌸专栏简介:本文收录于 C++项目——基于多设计模式下的同步与异步日志系统

🌸相关专栏推荐:C语言初阶系列C语言进阶系列C++系列数据结构与算法Linux

在这里插入图片描述
设计模式是一种在软件设计中常见的可重用解决方案的方法。它们是经过反复验证和证明的最佳实践,可以帮助软件开发人员解决特定问题或应对常见的设计挑战。设计模式提供了一种通用的框架,有助于构建高质量、易于维护和可扩展的软件系统

六大原则

  • 单一职责原则

    • 类的职责应该单一,一个方法只做一件事。职责划分清晰明了,每次改动到最小的方法或类;
    • 使用建议:两个完全不一样的功能不应该放在一个类中,一个类应该是一组相关性很高的函数、数据的封装;
    • 用例:网络聊天:网络通信&聊天,应该分割为网络通信类或聊天类;
  • 开闭原则

    • 对扩展开放,对修改封闭
    • 使用建议:对软件实体的改动,最好使用拓展而非修改的方式;
    • 用例:超市卖货:商品价格时长需要改动,但不是修改原来商品的价格而是新增促销价格;
  • 里氏替换原则

    • 通俗点讲,就是只要父类能出现的地方,子类就可以出现,而且替换为子类也不会出现任何错误或异常
    • 在继承类时,务必重写父类中所有的方法,尤其需要注意父类的protected方法,子类尽量不要暴露自己的public方法供外界调用;
    • 使用建议:子类必须完全实现父类的方法,孩子可以有自己的个性。覆盖或实现父类的方法时,输入参数可以被放大,输出可以缩小;
    • 用例:跑步运动员类会跑步,子类长跑运动员会跑步且擅长长跑,子类短跑运动员会跑步且擅长短跑;
  • 依赖倒置原则

    • 高层模块不应该依赖低层模块,两者都应该依赖其抽象。不可分割的原子逻辑就是低层模式,原子逻辑组装成的就是高层模块;
    • 模块间依赖通过抽象(接口)发生,具体类之间不之间依赖
    • 使用建议:每个类都尽量有抽象类,任何类都不应该从具体类派生。尽量不要重写基类的方法。结合里氏替换原则使用。
    • 用例:奔驰车司机类只能开奔驰,司机类给什么车就开什么车,开车的人:司机——依赖于抽象;
  • 迪米特法则

    • 尽量减少对象之间的交互,从而减少类之间的耦合。一个对象应该对其他对象有最少的了解。对类的低耦合提出了明确的要求:
      • 只和直接的朋友交流,朋友之间也是有距离的。自己的就是自己的(如果一个方法放在本类中,既不增加类间关系,也不产生负面影响,那就放置在本类中;
    • 用例:老师让班长点名,老师给班长一个名单,班长点完名勾选,返回结果,而不是班长点名,老师勾选;
  • 接口隔离原则

    • 客户端不应该依赖他不需要的接口,类间的依赖关系应该建立在最小的接口上
    • 使用建议:接口设计尽量精简单一,但是不要对外暴露没有实际意义的接口;
    • 用例:修改密码:不应该提供修改用户信息接口,而就是单一的最小修改密码的接口;

从整体上来了解六大原则,可以简要的概括为一句话:用抽象构建框架,用实现拓展细节。具体到每一条设计原则,则对应一条注意事项:

  • 单一职责原则告诉我们实现类要职责单一
  • 里氏替换原则告诉我们不要破坏继承体系
  • 依赖倒置原则告诉我们要面向接口编程
  • 接口隔离原则告诉我们在设计接口时要降低耦合
  • 开闭原则是总纲,告诉我们要对拓展开放,对修改关闭

单例模式

  • 一个类只能创建⼀个对象,即单例模式,该设计模式可以保证系统中该类只有一个实例,并提供⼀个访问它的全局访问点,该实例被所有程序模块共享。
  • 比如在某个服务器程序中,该服务器的配置信息存放在一个文件中,这些配置数据由⼀个单例对象统一读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息,这种方式简化了在复杂环境下的配置管理。

单例模式有两种实现模式:饿汉模式和懒汉模式。

饿汉模式

  • 程序启动时就会创建一个唯一的实例对象。因为单例对象已经确定,所以比较适用于多线程环境中,多线程获取单例对象不需要加锁可以有效的避免资源竞争,提高性能
#include <iostream>
#include <string>// 饿汉模式
class Singleton
{
public:Singleton(const Singleton &) = delete;Singleton& operator=(const Singleton&) = delete;static Singleton& getInstance(){return _eton;}std::string &getData(){return _data;}
private:Singleton() :_data("Singleton") {std::cout << "获取单例对象" <<std::endl;}~Singleton() {}
private:static Singleton _eton;std::string _data;
};Singleton Singleton::_eton;int main()
{std::cout << Singleton::getInstance().getData() << std::endl;return 0;
}

懒汉模式

  • 第一次要使用单例对象的时候创建实例对象。如果单例对象构造特别耗时或者耗费资源(加载插件、加载网络资源等),可以选择懒汉模式,在第一次使用的时候才创建对象。
    • C++11后,静态变量能够满足在线程安全的前提下唯一的被构造和析构
// 懒汉模式
class Singleton
{
public:Singleton(const Singleton &) = delete;Singleton &operator=(const Singleton &) = delete;static Singleton &getInstance(){static Singleton _eton; return _eton;}std::string &getData(){return _data;}
private:Singleton() : _data("Singleton"){std::cout << "单例对象构造" << std::endl;}~Singleton() {}
private:static Singleton _eton;std::string _data;
};

工厂模式

  • 工厂模式是一种创建型设计模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们创建对象时不会对上层暴露创建逻辑,而是通过使用一个共同结构来指向新创建的对象,以此实现创建与使用的分离

工厂模式可以分为:

  • 简单工厂模式;
  • 工厂方法模式;
  • 抽象工厂模式;

简单工厂模式

  • 简单工厂模式实现由一个工厂对象通过类型来决定创建出来指定产品类的实例
  • 假设有个工厂能生产出水果,当客户生产水果的时候明确告诉工厂生产哪类水果,工厂需要接收用户提供的类别信息,当新增产品的时候,工厂内部去添加新产品的生产方式。
/*简单工厂模式:通过参数控制可以生产任何商品优点:简单粗暴、直观易懂。使用一个工厂生产同一等级结构下的任意商品缺点:1.所有东西生产在一起,产品太多会导致代码量庞大;2.开闭原则遵守不是太好,要新增产品就必须修改工厂方法。
*/
#include <iostream>class Fruit
{
public:Fruit() {}virtual void name() = 0;
};class Apple : public Fruit
{
public:Apple() {}virtual void name(){std::cout << "苹果" << std::endl;}
};class Banana : public Fruit
{
public:Banana() {}virtual void name(){std::cout << "香蕉" << std::endl;}
};class FruitFactory
{
public:static std::shared_ptr<Fruit> create(const std::string &name){if (name == "苹果")return std::make_shared<Apple>();else if (name == "香蕉")return std::make_shared<Banana>();return std::shared_ptr<Fruit>();}
};int main()
{std::shared_ptr<Fruit> ff = FruitFactory::create("苹果");ff->name();ff = FruitFactory::create("香蕉");ff->name();return 0;
}

工厂方法模式

  • 在简单工厂模式下新增多个工厂,多个产品,每个产品对应一个工厂
  • 假设现在有A、B两种产品,则开两个工厂,工厂A负责生产产品A,工厂B负责生产产品B,用户只知道产品的工厂名,而不知道具体的产品信息,工厂不需要再接收客户的产品类别,而只负责生产产品。
/* 工厂方法模式:定义一个创建对象的接口,但是由子类来决定创建哪种对象,使用多个工厂分别生产指定的固定产品优点:1.减轻了工厂类的负担,将某产品的生产交给指定的工厂来进行;2.开闭原则遵循较好,添加新产品只需要新增产品的工厂即可,不需要修改原先的工厂类。缺点:对于某种可以形成一组产品族的情况处理较为复杂,需要创建大量的工厂类。*/
#include <iostream>
#include <string>
#include <memory>class Fruit
{
public:Fruit() {}virtual void name() = 0;
};class Apple : public Fruit
{
public:Apple() {}virtual void name(){std::cout << "苹果" << std::endl;}
private:std::string _color;
};class Banana : public Fruit
{
public:Banana() {}virtual void name(){std::cout << "香蕉" << std::endl;}
};class FruitFactory
{
public:virtual std::shared_ptr<Fruit> create() = 0;
};class AppleFactory : public FruitFactory
{
public:virtual std::shared_ptr<Fruit> create(){return std::make_shared<Apple>();}
};class BananaFactory : public FruitFactory
{
public:virtual std::shared_ptr<Fruit> create(){return std::make_shared<Banana>();}
};int main()
{std::shared_ptr<FruitFactory> factory(new AppleFactory());std::shared_ptr<Fruit> fruit = factory->create();fruit->name();factory.reset(new BananaFactory());fruit = factory->create();fruit->name();return 0;
}

抽象工厂模式

  • 工厂方法模式通过引入工厂等级结构,解决了简单工厂模式中工厂职责太重的问题,但由于工厂方法模式中的每个工厂只生产一类产品,可能会导致系统中存在大量的工厂类,势必会增加系统的开销。此时,我们可以考虑将一些相关的产品组成一个产品族(位于不同产品等级结构中功能相关联的产品组成的家族),由同一个工厂来统一生产,这就是抽象工厂模式的基本思想。
/*抽象工厂:围绕一个超级工厂去创建其他工厂。每个生成的工厂按照工厂模式提供对象。思想:将工厂抽象成两层,抽象工厂 & 具体工厂子类,在工厂子类中生产不同类型的子产品
*/
#include <iostream>
#include <string>
#include <memory>class Fruit
{
public:Fruit() {}virtual void name() = 0;
};class Apple : public Fruit
{
public:Apple() {}void name() override{std::cout << "苹果" << std::endl;}private:std::string _color;
};class Banana : public Fruit
{
public:Banana() {}void name() override{std::cout << "香蕉" << std::endl;}
};class Animal
{
public:virtual void voice() = 0;
};class Cat : public Animal
{
public:void voice() override{std::cout << "喵喵喵" << std::endl;}
};class Dog : public Animal
{
public:void voice() override{std::cout << "汪汪汪" << std::endl;}
};class Factory
{
public:virtual std::shared_ptr<Fruit> getFruit(const std::string &name) = 0;virtual std::shared_ptr<Animal> getAnimal(const std::string &name) = 0;
};class FruitFactory : public Factory
{
public:std::shared_ptr<Animal> getAnimal(const std::string &name) override{return std::shared_ptr<Animal>();}std::shared_ptr<Fruit> getFruit(const std::string &name) override{if (name == "苹果")return std::make_shared<Apple>();else if (name == "香蕉")return std::make_shared<Banana>();return std::shared_ptr<Fruit>();}
};class AnimalFactory : public Factory
{
public:std::shared_ptr<Fruit> getFruit(const std::string &name) override{return std::shared_ptr<Fruit>();}std::shared_ptr<Animal> getAnimal(const std::string &name) override{if (name == "小猫")return std::make_shared<Cat>();else if (name == "小狗")return std::make_shared<Dog>();return std::shared_ptr<Animal>();}
};class FactoryProducer
{
public:static std::shared_ptr<Factory> getFactory(const std::string &name){if (name == "水果")return std::make_shared<FruitFactory>();else if(name == "动物")return std::make_shared<AnimalFactory>();}
};int main()
{std::shared_ptr<Factory> fruit_factory = FactoryProducer::getFactory("水果");std::shared_ptr<Fruit> fruit = fruit_factory->getFruit("苹果");fruit->name();fruit = fruit_factory->getFruit("香蕉");fruit->name();std::shared_ptr<Factory> animal_factory = FactoryProducer::getFactory("动物");std::shared_ptr<Animal> animal = animal_factory->getAnimal("小猫");animal->voice();animal = animal_factory->getAnimal("小狗");animal->voice();return 0;
}

建造者模式

  • 建造者模式是一种创建型设计模式使用多个简单的对象一步一步构建出一个复杂的对象,能够将一个复杂的对象的构建与它的表示分离,提供一种创建对象的最佳方式。主要用于解决对象的构建过于复杂的问题。

建造者模式主要基于4个核心类实现:

  • 抽象产品类;
  • 具体产品类:一个具体的产品对象类;
  • 抽象pubic类:创建一个产品对象所需的各个部件的抽象接口;
  • 具体产品的Builder类:实现抽象接口,构建各个部件;
  • 指挥者Director类:统一组建过程,提供给调用者使用,通过指挥者来构建产品;
#include <iostream>
#include <memory>/* 抽象电脑类 */
#include <iostream>
#include <memory>class Computer
{
public:using ptr = std::shared_ptr<Computer>;Computer() {};void setBoard(const std::string &board) { _board = board ;}void setDisplay(const std::string &display) {_display = display;}virtual void setOs() = 0;std::string show(){std::string computer = "Computer:[\n";computer += "\tboard: " + _board + "\n";computer += "\tdisplay: " + _display + "\n";computer += "\tos: " + _os + "\n";computer += "]\n";return computer;}
protected:std::string _board;std::string _display;std::string _os;
};/* 具体产品类 */
class MacBook : public Computer
{
public:using ptr = std::shared_ptr<MacBook>;MacBook() {}virtual void setOs() {_os = "Mac Os X12";}
};/* 抽象建造者类:包含创建一个产品对象各个部件的抽象接口 */
class Builder
{
public:using ptr = std::shared_ptr<Builder>;virtual void buildBoard(const std::string &board) = 0;virtual void buildDisplay(const std::string &display) = 0;virtual void buildOS() = 0;virtual Computer::ptr build() = 0;
};/* 具体产品的具体建造者类:实现抽象接口,构建和组装各个部件 */
class MacBookBuilder : public Builder
{
public:using ptr = std::shared_ptr<MacBookBuilder>;MacBookBuilder() : _computer(new MacBook()) {}virtual void buildBoard(const std::string &board) {_computer->setBoard(board);}virtual void buildDisplay(const std::string &display){_computer->setDisplay(display);}virtual void buildOS(){_computer->setOs();}virtual Computer::ptr build(){return _computer;}
private:Computer::ptr _computer;
};/* 指挥者类:提供给调用者使用,通过指挥者来构造复杂的产品 */
class Director
{
public:Director(Builder* builder) : _builder(builder) {}void construct(const std::string &board, const std::string &display){_builder->buildBoard(board);_builder->buildDisplay(display);_builder->buildOS();}
private:Builder::ptr _builder;
};int main()
{Builder* builder = new MacBookBuilder();std::unique_ptr<Director> pd(new Director(builder));pd->construct("华为主板", "VOC显示器");Computer::ptr computer = builder->build();std::cout << computer->show() ;return 0;
}

代理模式

  • 代理模式指代理控制对其他对象的访问,也就是代理对象控制对原对象的引用。在某些情况下,一个对象不能或不适合直接被引用访问,而代理对象可以在客户端与目标对象之间起到中介作用

  • 代理模式的结构包括一个真正的你要访问的对象(目标类)、一个是代理对象。目标对象与代理对象实现同一个接口,先访问代理类,再通过代理类来访问目标对象。代理模式分为静态代理、动态代理:

    • 静态代理指的是:在编译时就已经确定好了代理类和被代理类的关系。也就是说,在编译时就已经确定了代理类要代理的是哪一个类。

    • 动态代理指的是:在运行时才动态生产代理类,并将其与被代理类绑定。这意味着在运行时才能确定代理类要代理的是哪一个类。

以租房为例,房东将房子租出去,但是房子要租出去,需要发布招租启示,带人看房,负责维修,这些操作中有些操作并非房东能完成,因此房东为了图省事,将房子委托给中介进行租赁。

#include <iostream>
#include <string>
/*房东要把⼀个房⼦通过中介租出去理解代理模式*//* 租房类 */
class RentHouse
{
public:virtual void rentHouse() = 0;
};/* 房东类 */
class Landlord : public RentHouse
{public:void rentHouse() {std::cout << "将房子租出去\n" << std::endl;}
};/* 中介类 */
class Intermedirary : public RentHouse
{public:void rentHouse(){std::cout << "发布告示" << std::endl;std::cout << "带人看房" << std::endl;_landlord.rentHouse();std::cout << "负责租后维修" << std::endl;}private:Landlord _landlord;
};int main()
{Intermedirary intermedirary;intermedirary.rentHouse();return 0;
}

在这里插入图片描述

相关文章:

C++项目实战——基于多设计模式下的同步异步日志系统-③-前置知识补充-设计模式

文章目录 专栏导读六大原则单例模式饿汉模式懒汉模式 工厂模式简单工厂模式工厂方法模式抽象工厂模式 建造者模式代理模式 专栏导读 &#x1f338;作者简介&#xff1a;花想云 &#xff0c;在读本科生一枚&#xff0c;C/C领域新星创作者&#xff0c;新星计划导师&#xff0c;阿…...

C++ 新旧版本两种读写锁

一、简介 读写锁&#xff08;Read-Write Lock&#xff09;是一种并发控制机制&#xff0c;用于多线程环境中实现对共享资源的高效读写操作。读写锁允许多个线程同时读取共享资源&#xff0c;但在有写操作时&#xff0c;需要互斥地独占对共享资源的访问&#xff0c;以确保数据的…...

ES6 字符串的repeat()方法

repeat() 方法返回一个新字符串&#xff0c;表示将原字符串重复n次 格式&#xff1a;str.repeat(n) 参数n&#xff1a;str需要重复多少次 参数n的取值&#xff1a; n是正整数&#xff1a; x.repeat(3) // 输出结果&#xff1a;"xxx" hello.repeat(2) // 输出结果…...

【车载以太网测试从入门到精通】系列文章目录汇总

【车载以太网测试从入门到精通】——物理层测试 【车载以太网测试从入门到精通】——数据链路层测试 【车载以太网测试从入门到精通】——网络层测试 【车载以太网测试从入门到精通】——传输层测试 【车载以太网测试从入门到精通】——以太网TCP/IP协议自动化测试&#xff08;…...

LLM推理优化技术综述:KVCache、PageAttention、FlashAttention、MQA、GQA

LLM推理优化技术综述&#xff1a;KVCache、PageAttention、FlashAttention、MQA、GQA 随着大模型被越来越多的应用到不同的领域&#xff0c;随之而来的问题是应用过程中的推理优化问题&#xff0c;针对LLM推理性能优化有一些新的方向&#xff0c;最近一直在学习和研究&#xf…...

go开发之个微机器人的二次开发

请求URL&#xff1a; http://域名/addRoomMemberFriend 请求方式&#xff1a; POST 请求头Headers&#xff1a; Content-Type&#xff1a;application/jsonAuthorization&#xff1a;login接口返回 参数&#xff1a; 参数名必选类型说明wId是String登录实例标识chatRoom…...

2023国赛数学建模B题思路代码 - 多波束测线问题

# 1 赛题 B 题 多波束测线问题 单波束测深是利用声波在水中的传播特性来测量水体深度的技术。声波在均匀介质中作匀 速直线传播&#xff0c; 在不同界面上产生反射&#xff0c; 利用这一原理&#xff0c;从测量船换能器垂直向海底发射声波信 号&#xff0c;并记录从声波发射到…...

SpringAOP面向切面编程

文章目录 一. AOP是什么&#xff1f;二. AOP相关概念三. SpringAOP的简单演示四. SpringAOP实现原理 一. AOP是什么&#xff1f; AOP&#xff08;Aspect Oriented Programming&#xff09;&#xff1a;面向切面编程&#xff0c;它是一种编程思想&#xff0c;是对某一类事情的集…...

A Guide to Java HashMap

原文链接: A Guide to Java HashMap → https://www.baeldung.com/java-hashmap 从Map里取值 # 原生方法 Map<String, Integer> map new HashMap<>();// map自身的方法 → 取不到返回null Integer age6 map.get("name"); // Integer时返回null可…...

LeetCode 449. Serialize and Deserialize BST【树,BFS,DFS,栈】困难

本文属于「征服LeetCode」系列文章之一&#xff0c;这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁&#xff0c;本系列将至少持续到刷完所有无锁题之日为止&#xff1b;由于LeetCode还在不断地创建新题&#xff0c;本系列的终止日期可能是永远。在这一系列刷题文章…...

嵌入式IDE(1):IAR中ICF链接文件详解和实例分析

最近在使用NXP的提供的MCUXPresso IDE&#xff0c;除了Eclipse固有的优点外&#xff0c;我觉得它最大的优点就是在链接脚本的生成上&#xff0c;提供了非常直观的GUI配置界面。但这个IDE仅仅支持NXP相关的产品&#xff0c;而且调试的性能在某些情况下并不理想。而我们用得比较多…...

分布式版本控制工具——git

✅<1>主页&#xff1a;&#xff1a;我的代码爱吃辣 &#x1f4c3;<2>知识讲解&#xff1a;Linux——git ☂️<3>开发环境&#xff1a;Centos7 &#x1f4ac;<4>前言&#xff1a;git是一个开源的分布式版本控制系统&#xff0c;可以有效、高速地处理从很…...

C基础-数组

1.一维数组的创建和初始化 int main() {// int arr1[10];int n 0;scanf("%d",&n);//int count 10;int arr2[n]; //局部的变量&#xff0c;这些局部的变量或者数组是存放在栈区的&#xff0c;存放在栈区上的数组&#xff0c;如果不初始化的话&#xff0c;默认…...

springboot项目配置flyway菜鸟级别教程

1、Flyway的工作原理 Flyway在第一次执行时&#xff0c;会创建一个默认名为flyway_schema_history的历史记录表&#xff0c;这张表会用来跟踪或记录数据库的状态&#xff0c;然后每次项目启动时都会自动扫描在resources/db/migration下的文件的版本号并且通过查询flyway_schem…...

成都精灵云初试

最近参加了成都精灵云的笔试与面试&#xff0c;岗位是c工程师。后面自己复盘了过程&#xff0c;初试部分总结如下&#xff0c;希望能对各位相进该公司以及面试C工程师的同学提供一些参考。这也是博主第一次参加面试&#xff0c;很多东西都还没准备&#xff0c;很多答得不好&…...

css relative 和absolute布局

1、relative和absolute内部的元素都是相对于父容器&#xff0c;若父容器没有指定为relative&#xff0c;则默认为整个文档视图空间&#xff0c;absolute可以重叠元素&#xff0c;relative则不行。relative意味着元素的任意属性如left和right都是相对于其他元素的。absolute则相…...

更健康舒适更科技的照明体验!书客SKY护眼台灯SUKER L1上手体验

低价又好用的护眼台灯是多数人的需求&#xff0c;很多人只追求功能性护眼台灯&#xff0c;显色高、无频闪、无蓝光等基础需求。但是在较低价格中很难面面俱到&#xff0c;然而刚发布的SUKER书客L1护眼台灯却是一款不可多得的性价比护眼台灯&#xff0c;拥有高品质光源&#xff…...

经管博士科研基础【19】齐次线性方程组

1. 线性方程组 2. 非线性方程组 非线性方程,就是因变量与自变量之间的关系不是线性的关系,这类方程很多,例如平方关系、对数关系、指数关系、三角函数关系等等。求解此类方程往往很难得到精确解,经常需要求近似解问题。相应的求近似解的方法也逐渐得到大家的重视。 3. 线…...

django报错解决 Forbidden (403) CSRF verification failed. Request aborted.

django报错解决 Forbidden (403) CSRF verification failed. Request aborted. 报错内容 Forbidden (403) CSRF verification failed. Request aborted.Help Reason given for failure:Origin checking failed - https://active-mantis-distinct.ngrok-free.app does not mat…...

k8s-实战——yapi平台部署

文章目录 k8s 部署yapi平台前言准备工作构建yapi镜像Dockerfileentrypoint.shbuild.sh源码下载构建镜像启动mongo数据库新建nfs服务mongo创建mongo服务初始化数据启动yapi服务创建yapi服务查看密码访问地址k8s 部署yapi平台 前言 部署yapi平台需要mo...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

ES6从入门到精通:前言

ES6简介 ES6&#xff08;ECMAScript 2015&#xff09;是JavaScript语言的重大更新&#xff0c;引入了许多新特性&#xff0c;包括语法糖、新数据类型、模块化支持等&#xff0c;显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var&#xf…...

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...

【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)

升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点&#xff0c;但无自动故障转移能力&#xff0c;Master宕机后需人工切换&#xff0c;期间消息可能无法读取。Slave仅存储数据&#xff0c;无法主动升级为Master响应请求&#xff…...

深度学习习题2

1.如果增加神经网络的宽度&#xff0c;精确度会增加到一个特定阈值后&#xff0c;便开始降低。造成这一现象的可能原因是什么&#xff1f; A、即使增加卷积核的数量&#xff0c;只有少部分的核会被用作预测 B、当卷积核数量增加时&#xff0c;神经网络的预测能力会降低 C、当卷…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

BLEU评分:机器翻译质量评估的黄金标准

BLEU评分&#xff1a;机器翻译质量评估的黄金标准 1. 引言 在自然语言处理(NLP)领域&#xff0c;衡量一个机器翻译模型的性能至关重要。BLEU (Bilingual Evaluation Understudy) 作为一种自动化评估指标&#xff0c;自2002年由IBM的Kishore Papineni等人提出以来&#xff0c;…...

c# 局部函数 定义、功能与示例

C# 局部函数&#xff1a;定义、功能与示例 1. 定义与功能 局部函数&#xff08;Local Function&#xff09;是嵌套在另一个方法内部的私有方法&#xff0c;仅在包含它的方法内可见。 • 作用&#xff1a;封装仅用于当前方法的逻辑&#xff0c;避免污染类作用域&#xff0c;提升…...

虚幻基础:角色旋转

能帮到你的话&#xff0c;就给个赞吧 &#x1f618; 文章目录 移动组件使用控制器所需旋转&#xff1a;组件 使用 控制器旋转将旋转朝向运动&#xff1a;组件 使用 移动方向旋转 控制器旋转和移动旋转 缺点移动旋转&#xff1a;必须移动才能旋转&#xff0c;不移动不旋转控制器…...

作为点的对象CenterNet论文阅读

摘要 检测器将图像中的物体表示为轴对齐的边界框。大多数成功的目标检测方法都会枚举几乎完整的潜在目标位置列表&#xff0c;并对每一个位置进行分类。这种做法既浪费又低效&#xff0c;并且需要额外的后处理。在本文中&#xff0c;我们采取了不同的方法。我们将物体建模为单…...