软件设计模式

news2025/2/7 21:29:39

目录

一.创建型模式

抽象工厂 Abstract Factory

构建器 Builder

工厂方法 Factory Method

原型 Prototype

单例模式  Singleton

二.结构型模式

适配器模式  Adapter

桥接模式  Bridge

组合模式  Composite

装饰者模式  Decorator

外观模式  Facade

享元模式  Flyweight

代理模式  Proxy

三.行为型模式 Behavioral Patterns

责任链模式 Chain of Responsibility 

命令模式 Command 

解释器模式  Interpreter

迭代器模式 Iterator

中介者模式  Mediator

备忘录模式  Memento

观察者模式 Observer 

状态模式  State

策略模式  Strategy

访问者模式  Visitor


  • 定义: 设计模式是针对软件设计中常见问题的可重用解决方案。

  • 作用: 提高代码的可复用性、可维护性和可扩展性。

  • 分类:

    • 创建型模式: 关注对象的创建过程,例如:工厂方法模式、抽象工厂模式、单例模式等。

    • 结构型模式: 关注类和对象的组合方式,例如:适配器模式、装饰器模式、代理模式等。

    • 行为型模式: 关注对象之间的通信和职责分配,例如:观察者模式、策略模式、模板方法模式等。

一.创建型模式

记忆方式:“单身的工人抽烟,想着建筑的原因。”

(5种)单例,工厂,抽象工厂,构建器,原型


抽象工厂 Abstract Factory

提供一个接口,用于创建一系列相关或相互依赖的对象,而无需指定它们的具体类。

  • (Abstract Factory):抽象工厂 - 定义创建产品对象的接口。
  • (Concrete Factory):具体工厂 - 实现抽象工厂接口,负责创建具体的产品对象。
  • (Abstract Product):抽象产品 - 定义产品的接口。
  • (Product):具体产品 - 实现抽象产品接口的具体类。

使用场景:

- 当系统需要独立于其产品的创建、组合和表示时。

- 当系统需要使用多个系列的产品,而不需要依赖于具体的产品实现时。

- 当产品的具体类在运行时决定时。


构建器 Builder

旨在简化复杂对象的构建过程。将对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。

  • Builder(建造者):定义创建一个产品所需的各个部件的抽象接口。
  • ConcreteBuilder(具体建造者):实现Builder接口,构建和装配各个部件,提供一个方法来返回构建好的产品。
  • Director(指挥者):负责管理Builder的构建过程,调用具体建造者的方法来构建产品。
  • Product(产品):最终构建的复杂对象。

使用场景:

- 当一个对象的构建过程复杂,且需要多个步骤时。

- 构造过程必须允许已构建对象有不同表示。


工厂方法 Factory Method

定义一个创建对象的接口,让子类决定实例化哪一个类。

  • 产品接口(Product):定义了工厂方法所创建的对象的接口。
  • 具体产品(ConcreteProduct):实现了Product产品接口的具体类。
  • 工厂接口(Creator):声明了一个工厂方法,返回一个Product产品对象。
  • 具体工厂(ConcreteCreator):实现了工厂接口,返回具体产品的实例。

原型 Prototype

它允许通过复制现有的实例来创建新对象,而不是通过直接实例化类。

  • 原型接口(Prototype):定义一个用于复制自身的接口。
  • 具体原型(ConcretePrototype):实现原型接口,提供具体的克隆方法。
  • 客户端(Client):使用原型实例来创建新的对象。

使用场景

- 当一个类的实例化成本较高时,可以考虑使用原型模式。

需要创建大量相似对象的场景,能够提高性能并减少内存消耗。


单例模式  Singleton

确保一个类只有一个实例,并提供一个全局访问点。将类的构造函数私有化,并提供一个静态方法获取唯一实例。

它常用于需要控制资源访问的场景,比如数据库连接、线程池等。

使用场景

- 需要控制资源的访问,如数据库连接、线程池等。

- 需要全局访问的配置类。

- 需要在整个应用中共享的状态。


二.结构型模式

该类模式主要用于如何组合已有的类和对象以获得更大的结构,一般借鉴封装,代理,继承等概念讲一个或多个类或对象进行组合,封装,以提供同一的外部视图或新的功能。

记忆:“适享外代组装桥”(是享外包代组装桥的服务)

适配器模式  Adapter

  • 问题: 需要将一个类的接口转换成客户端期望的另一个接口。

  • 解决方案: 创建一个适配器类,将目标接口转换成适配者接口。

  • 记忆技巧: 适配器就像一个转接头,连接不兼容的接口。

  • 1. **目标接口(Target)**:客户端所期待的接口。
  • 2. **适配者(Adaptee)**:需要被适配的类,通常是已有的类。
  • 3. **适配器(Adapter)**:实现目标接口,并持有一个适配者的实例,将目标接口的方法调用转发给适配者。

使用场景

- 当你希望使用一些现有的类,但其接口不符合你的需求时。

- 当你想要创建一个可以与多个不兼容接口的类协同工作的系统时。


桥接模式  Bridge

通过将类的抽象部分与实现部分分离,使得二者可以独立变化。它是一种对象结构型模式,又称为柄体模式(Handle and Body )或接口模式(Interface)这个模式主要用于解决类的层次结构过于复杂的问题

  • 1. **抽象类(Abstraction)**:定义了抽象的接口,并维护一个指向Implementor实现的指针。
  • 2. **扩展抽象类(Refined Abstraction)**:由Abstraction轴向类定义,扩展了抽象类的功能。
  • 3. **实现类接口(Implementor)**:定义了实现部分的接口。这个接口不一定要和Abstraction的接口完全一致,可以完全不同,一把来说,Implementor接口仅提供基本操作,而Abstraction则定义了基于这些基本操作的较高层次的操作
  • 4. **具体实现类(Concrete Implementor)**:实现了实现类接口,提供具体的实现。

适用场景

- 当你需要在多个维度上扩展系统时。

- 当你希望避免在类的层次结构中产生过多的子类时。

- 当你希望在运行时动态切换实现时。


组合模式  Composite

它允许将对象组合成树形结构以表示“部分-整体”的层次关系。组合模式使得客户端对单个对象和组合对象的使用具有一致性。

  • 1. **组件(Component)**:定义了叶子和组合对象的共同接口。,所有的叶子节点和组合节点都需要实现这个接口。
  • 2. **叶子节点(Leaf)**:实现了组件Component接口,表示树的叶子节点。它有自己的行为。
  • 3. **组合节点(Composite)**:实现了组件接口,能够包含叶子和其他组合对象。它可以包含子节点(其他的叶子或组合节点),并实现了添加和删除子节点的方法。

适用场景

- 当需要表示对象的部分-整体层次结构时。

- 当希望客户端忽略组合对象和单个对象的差异时。


装饰者模式  Decorator

问题: 需要动态地给一个对象添加一些额外的职责。

解决方案: 创建一个装饰器类,包装原始对象,并在保持原始对象接口的前提下提供额外的功能。装饰器就像给蛋糕加奶油,可以不断添加新的装饰。

  • 组件接口(Component):定义一个对象接口,可以给这些对象动态地添加职责。
  • 具体组件(ConcreteComponent):实现了组件接口的具体对象,定义了被装饰的对象。
  • 装饰器(Decorator):持有一个组件对象的引用,并定义与组件接口一致的接口。
  • 具体装饰器(ConcreteDecorator):扩展了装饰器类,添加了额外的职责。

外观模式  Facade

它为复杂的子系统提供一个统一的接口,使得子系统更易于使用。通过外观模式,客户端可以通过一个简单的接口与复杂的系统进行交互,而不需要了解系统内部的复杂性。

外观类(Facade):提供一个简单的接口,封装了复杂的子系统。

子系统类(Subsystem):实现具体的功能,通常包含多个类,外观类通过这些类来完成具体的操作。

使用场景

- 当需要为复杂的子系统提供一个简单的接口时。

- 当需要解耦客户端与子系统之间的关系时。

- 当希望提高系统的可读性和可维护性时。


享元模式  Flyweight

通过共享对象来减少内存使用和提高性能。

享元模式的核心思想是将对象的状态分为两部分:内部状态和外部状态。

内部状态**:对象可以共享的状态,通常是不可变的。多个对象可以共享同一个内部状态。

外部状态**:对象特有的状态,通常是可变的。外部状态在使用对象时传递给对象。

  • Flyweight:享元接口,定义了需要实现的方法。
  • ConcreteFlyweight:具体享元类,实现了Flyweight接口,包含内部状态。
  • FlyweightFactory:享元工厂,负责创建和管理享元对象,确保共享相同的对象。

使用场景:

当应用程序需要大量相似对象时。

当对象的创建和管理成本较高时。

当需要减少内存使用时。


代理模式  Proxy

  • 问题: 需要控制对某个对象的访问,或者需要在访问对象时执行一些额外的操作。

  • 解决方案: 创建一个代理类,代表原始对象,并在访问原始对象之前或之后执行一些操作。代理就像一个中介,控制对真实对象的访问

  • 主题接口(Subject):定义了代理和真实对象的共同接口。
  • 真实主题(RealSubject)**:实现了主题接口,定义了代理所代表的真实对象。
  • 代理 Proxy:持有对真实主题的引用,并实现了主题接口,控制对真实主题的访问。

代理模式通常用于以下几种情况:

1. **远程代理**:为一个对象在不同地址空间提供局部代表。

2. **虚拟代理**:根据需要创建开销较大的对象,延迟对象的创建。

3. **保护代理**:控制对原始对象的访问,提供不同的访问权限。

使用场景

-对象创建开销很大

- **网络请求**:在网络请求中,代理可以用于缓存响应,减少网络延迟。

- **权限控制**:在访问敏感数据时,代理可以检查用户权限。

- **资源管理**:在处理大对象时,代理可以延迟加载,优化性能。


三.行为型模式 Behavioral Patterns

该类模式主要用于对象之间的职责及其提供的服务的分配,它不仅描述对象或类的模式,还描述了他们之间的通信模式,特别是描述一组对等的对象怎样相互协作以完成其中任一对象都无法单独完成的任务。

记忆:10种

责命解,迭中备,观状策,访搞定。

  • 责命解:责任链、命令、解释器。

  • 迭中备:迭代器、中介者、备忘录。

  • 观状策:观察者、状态、策略。

  • 访搞定:访问者搞定一切!

责任链模式 Chain of Responsibility 

它允许将请求的发送者和接收者解耦,使多个对象都有机会处理请求。创建一个对象链,每个对象依次尝试处理请求,直到某个对象处理成功为止。

  • 1. **Handler(处理者)**: 定义一个处理请求的接口,并实现链中的处理逻辑。
  • 2. **ConcreteHandler(具体处理者)**: 实现Handler接口,处理请求或将请求传递给下一个处理者。
  • 3. **Client(客户端)**: 创建具体处理者并设置链的顺序,发送请求。

工作原理

1. 客户端创建多个处理者,并将它们连接成一条链。

2. 客户端发送请求,链中的处理者依次检查是否能够处理该请求。

3. 如果某个处理者能够处理请求,则执行相应的处理逻辑;如果不能,则将请求传递给链中的下一个处理者。

应用场景:审批流程、异常处理、事件处理等。


命令模式 Command 

  • 目的:将请求封装为对象,使得可以用不同的请求对客户进行参数化。

  • 核心思想:将“操作”抽象为对象,支持撤销、重做、日志记录等功能。

  • 1. **命令接口(Command)**:定义一个执行操作的接口。
  • 2. **具体命令(ConcreteCommand)**:实现命令接口,定义与接收者之间的绑定关系,并调用接收者的相应操作。
  • 3. **接收者(Receiver)**:知道如何实施与执行一个请求相关的操作。
  • 4. **调用者(Invoker)**:负责调用命令对象来执行请求。
  • 5. **客户端(Client)**:创建具体命令对象并设置接收者。
  • 应用场景:GUI 按钮操作、任务队列、事务管理等。

解释器模式  Interpreter

  • 目的:定义语言的文法规则,并解释执行语言中的句子。

  • 核心思想:将语言中的每个符号映射为一个类,通过组合这些类来解析和执行语言。

  • 应用场景:正则表达式解析、数学公式计算、编译器设计等。

  • 1. 抽象表达式(AbstractExpression):定义一个解释操作的接口,所有具体表达式都需要实现这个接口。
  • 2. 终结符表达式(TerminalExpression):实现了抽象表达式接口,表示文法中的基本元素。通常是一些简单的语法规则。
  • 3. 非终结符表达式(NonTerminalExpression):同样实现了抽象表达式接口,表示文法中的复杂结构,由多个终结符和非终结符组合而成。
  • 4. 上下文(Context):包含了在解释过程中需要的一些信息,通常是输入的字符串或其他数据。

工作原理

解释器模式的核心思想是将一个复杂的表达式分解为多个简单的表达式,然后通过递归的方式来解释这些表达式。

假设我们需要解析一个简单的数学表达式,比如加法和减法。我们可以定义以下结构:

- **抽象表达式**:`Expression` 接口,定义 `interpret(Context context)` 方法。

- **终结符表达式**:`NumberExpression` 类,表示数字。

- **非终结符表达式**:`AddExpression` 和 `SubtractExpression` 类,分别表示加法和减法。

具体步骤如下:

1. **定义文法**:首先需要定义要解析的语言的文法规则。

2. **构建表达式树**:根据文法规则构建一个表达式树,树的每个节点都是一个表达式。

3. **解释表达式**:通过遍历表达式树,调用每个节点的解释方法,最终得到结果。

使用场景(适用于特定的解析和执行需求)

- 需要系统要能应对“”自定义“”内容的解析。

- 需要解析和执行简单的语言或表达式。

- 需要对复杂的文法进行处理。

- 需要在运行时动态地解释和执行代码。


迭代器模式 Iterator

  • 目的:提供一种方法顺序访问一个聚合对象中的各个元素,而不暴露其内部表示。

  • 核心思想:将遍历逻辑从聚合对象中分离出来,封装到一个独立的迭代器对象中。

  • 应用场景:集合类的遍历(如列表、树、图等)。

  • 1. **迭代器(Iterator)**:定义了访问和遍历元素的接口。
  • 2. **具体迭代器(Concrete Iterator)**:实现了迭代器接口,负责遍历具体集合的元素。
  • 3. **聚合(Aggregate)**:定义了创建迭代器的接口。
  • 4. **具体聚合(Concrete Aggregate)**:实现了聚合接口,返回一个具体的迭代器。

中介者模式  Mediator

  • 目的:用一个中介对象来封装一系列对象之间的交互,降低对象之间的耦合度。

  • 核心思想:将对象之间的直接通信改为通过中介者间接通信。

  • 应用场景:聊天室、事件调度系统、GUI 组件交互等。

  • 1. **中介者接口(Mediator)**:定义了与各个同事对象交互的方法。
  • 2. **具体中介者(ConcreteMediator)**:实现中介者接口,维护对各个同事对象的引用,并协调它们之间的交互。
  • 3. **同事类(Colleague)**:各个参与者,它们通过中介者进行交互,而不是直接相互交互。

备忘录模式  Memento

  • 目的:在不破坏封装性的前提下,捕获并外部化一个对象的内部状态,以便以后恢复。

  • 核心思想:将对象的状态保存到备忘录对象中,并在需要时恢复。

  • 应用场景:撤销操作、游戏存档、事务回滚等。

这使得它在需要状态管理的应用程序中非常有用。

  • 1. **Originator(发起人)**:需要保存其内部状态的对象。它可以创建一个备忘录来记录当前状态,并可以使用备忘录恢复状态。
  • 2. **Memento(备忘录)**:用于存储发起人的内部状态。备忘录通常是一个不可变的对象,外部对象无法直接访问其内部状态。
  • 3. **Caretaker(看护者)**:负责管理备忘录的对象。看护者可以保存和恢复备忘录,但不能修改备忘录的内容。

使用场景

- 文本编辑器的撤销/重做功能。

- 游戏中的状态保存与加载。

- 任何需要保存和恢复对象状态的场景。


观察者模式 Observer 

  • 它定义了对象之间的一对多依赖关系,当一个对象(被观察者)的状态发生改变时,所有依赖它的对象(观察者)都会收到通知并自动更新。

想象一下,你是一个新闻订阅者

  • 被观察者:新闻出版社。

  • 观察者:订阅了新闻的用户。

  • 行为:当新闻出版社发布新的新闻时,所有订阅了新闻的用户都会收到通知。

观察者模式的核心思想是:被观察者维护一个观察者列表,当状态发生变化时,通知所有观察者

  • 被观察者(Subject):维护一个观察者列表,提供添加、删除和通知观察者的方法。

  • 具体被观察者(Concrete Subject):实现被观察者接口,存储具体状态,并在状态改变时通知观察者。

  • 观察者(Observer):定义一个更新接口,用于接收被观察者的通知。

  • 具体观察者(Concrete Observer):实现观察者接口,定义具体的更新逻辑。

优点

  • 解耦:被观察者和观察者之间是松耦合的,被观察者不需要知道观察者的具体实现。

  • 动态关系:可以在运行时动态添加或删除观察者。

  • 广播通信:被观察者可以一次性通知所有观察者。


缺点

  • 性能问题:如果观察者很多,通知所有观察者可能会导致性能问题。

  • 循环依赖:如果观察者和被观察者之间相互依赖,可能会导致循环调用。


适用场景

  • 事件驱动系统:当一个对象的状态改变需要通知其他对象时。

  • 广播机制:当一个对象需要通知多个对象,而不需要知道它们的具体实现时。

  • GUI事件处理:在图形用户界面中,用户操作(比如点击按钮)会触发事件,通知所有监听器。


状态模式  State

  • 目的:允许对象在其内部状态改变时改变其行为,使得对象看起来像是修改了它的类。

  • 核心思想:将状态抽象为独立的类,对象的行为随状态的变化而变化。

想象一下,你是一个电灯

  • 状态:电灯有两种状态——开和关。

  • 行为:当你按下开关时,电灯的行为会根据当前状态改变:

    • 如果电灯是的,按下开关后会打开

    • 如果电灯是的,按下开关后会关闭

状态模式的核心思想是:把对象的状态抽象成独立的类,对象的行为随着状态的改变而改变

  • 应用场景:工作流系统、游戏角色状态、订单状态管理等。

  • 1. **Context(上下文)**:持有一个状态对象的引用,并且可以在运行时改变它的状态。
  • 2. **State(状态接口)**:定义一个接口,用于封装与特定状态相关的行为。
  • 3. **ConcreteState(具体状态)**:实现状态接口的具体状态类,每个具体状态类都实现了与该状态相关的行为。

优点

  • 开闭原则:可以轻松添加新的状态,而无需修改现有代码。

  • 消除条件语句:避免了大量的if-elseswitch-case语句。

  • 清晰的状态管理:将状态和行为封装在独立的类中,使得代码更清晰、更易维护。

缺点:
  • 状态类增多:如果状态很多,会导致类的数量增加。

  • 上下文类依赖状态类:上下文类需要知道所有状态类,可能会增加耦合度。


策略模式  Strategy

策略模式的核心思想是:把不同的算法或行为封装成独立的策略类,客户端可以根据需要选择不同的策略

在电商平台中,用户可以选择不同的支付方式:

  • 策略接口:支付方式(比如支付宝、微信、信用卡)。

  • 具体策略类:支付宝支付、微信支付、信用卡支付。

  • 上下文类:订单系统,根据用户的选择调用具体的支付方式。

  • 1. **策略接口(Strategy)**:定义一个公共接口,所有具体策略都需要实现这个接口。
  • 2. **具体策略(ConcreteStrategy)**:实现策略接口的具体算法。
  • 3. **上下文(Context)**:持有一个策略的引用,并可以在运行时选择具体的策略。

使用场景

- 当你有多个算法可以选择,并且希望在运行时选择其中一个。

- 当你希望将算法的实现与使用算法的代码分离。

- 当你需要避免使用大量的条件语句(如 `if-else` 或 `switch`)。

在导航应用中,用户可以选择不同的路线策略:

  • 策略接口:路线策略(比如最短路径、最快路径、最少收费路径)。

  • 具体策略类:最短路径策略、最快路径策略、最少收费路径策略。

  • 上下文类:导航系统,根据用户的选择计算路线。


访问者模式  Visitor

允许你在不改变对象结构的前提下,定义新的操作。这个模式的核心思想是把“操作”从“对象”中分离出来。适用于需要对一组对象执行多种操作的场景。

  1. Visitor(访问者):定义了对每个元素(Element)的访问操作,每个操作对应一个具体的元素类。

  2. ConcreteVisitor(具体访问者):实现Visitor接口,定义了对每个具体元素类的具体操作。

  3. Element(元素):定义了一个接受访问者的接口(accept方法),通常是对象结构中的元素。

  4. ConcreteElement(具体元素):实现Element接口,提供具体的accept方法实现。

  5. ObjectStructure(对象结构):包含一组元素,可以枚举这些元素,并允许访问者访问它们。

假设你是一个超市管理员,超市里有三种商品:

  • 水果:按重量计价。

  • 饮料:按瓶计价。

  • 零食:按包计价。

你需要实现以下功能:

  1. 计算商品的总价。

  2. 打印商品的价格标签。

传统做法的问题

如果直接在商品类中添加calculatePriceprintLabel方法,会导致商品类的职责过多,而且每次新增功能(比如打折、促销)都需要修改商品类。

使用访问者模式
  • 对象结构:水果、饮料、零食。

  • 操作:计算总价、打印标签。

  • 访问者:价格计算器、标签打印机。

  • 优点

    • 开闭原则:可以在不修改对象结构的情况下,添加新的操作。

    • 单一职责原则:将相关的操作集中在一个访问者中,使得职责更加清晰。

    • 灵活性:可以在运行时选择不同的访问者来执行不同的操作。

  • 缺点

    • 增加复杂性:每增加一个新的元素类,都需要修改访问者接口及其所有具体访问者。

    • 破坏封装:访问者模式要求元素类暴露一些内部状态,以便访问者可以访问。

  • 访问者模式适合以下场景:

  • 对象结构稳定,但需要频繁添加新的操作。

  • 不希望修改对象类,但又需要扩展功能。

  • 操作逻辑复杂,且需要与对象结构分离。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2294471.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vscode 如何通过Continue引入AI 助手deepseek

第一步: 在deepseek 官网上注册账号,得到APIKeys(deepseek官网地址) 创建属于自己的APIKey,然后复制这个key,(注意保存自己的key)! 第二步: 打开vscode,在插件市场安装Continue插件, 点击设置,添加deepseek模型,默认…

通过docker安装部署deepseek以及python实现

前提条件 Docker 安装:确保你的系统已经安装并正确配置了 Docker。可以通过运行 docker --version 来验证 Docker 是否安装成功。 网络环境:保证设备有稳定的网络连接,以便拉取 Docker 镜像和模型文件。 步骤一:拉取 Ollama Docker 镜像 Ollama 可以帮助我们更方便地管理…

iOS 音频录制、播放与格式转换

iOS 音频录制、播放与格式转换:基于 AVFoundation 和 FFmpegKit 的实现 在 iOS 开发中,音频处理是一个非常常见的需求,比如录音、播放音频、音频格式转换等。本文将详细解读一段基于 AVFoundation 和 FFmpegKit 的代码,展示如何实现音频录制、播放以及 PCM 和 AAC 格式之间…

RK3576——USB3.2 OTG无法识别到USB设备

问题:使用硬盘接入到OTG接口无热插拔信息,接入DP显示屏无法正常识别到显示设备,但是能通过RKDdevTool工具烧录系统。 问题分析:由于热插拔功能实现是靠HUSB311芯片完成的,因此需要先确保HUSB311芯片驱动正常工作。 1. …

【MySQL】语言连接

语言连接 一、下载二、mysql_get_client_info1、函数2、介绍3、示例 三、其他函数1、mysql_init2、mysql_real_connect3、mysql_query4、mysql_store_result5、mysql_free_result6、mysql_num_fields7、mysql_num_rows8、mysql_fetch_fields9、mysql_fetch_row10、mysql_close …

20240206 adb 连不上手机解决办法

Step 1: lsusb 确认电脑 usb 端口能识别设备 lsusb不知道设备有没有连上,就插拔一下,对比观察多了/少了哪个设备。 Step 2: 重启 adb server sudo adb kill-serversudo adb start-serveradb devices基本上就可以了~ Reference https://b…

基于ansible部署elk集群

ansible部署 ELK部署 ELK常见架构 (1)ElasticsearchLogstashKibana:这种架构是最常见的一种,也是最简单的一种架构,这种架构通过Logstash收集日志,运用Elasticsearch分析日志,最后通过Kibana中…

Mac上搭建k8s环境——Minikube

1、在mac上安装Minikube可执行程序 brew cask install minikub 安装后使用minikube version命令查看版本 2、安装docker环境 brew install --cask --appdir/Applications docker #安装docker open -a Docker #启动docker 3、安装kubectl curl -LO https://storage.g…

MTGNN论文解读

模型架构 MTGNN 由多个模块组合而成,目标是捕捉多变量时间序列中的空间(变量间)和时间(时序)依赖。 图学习层:用于自适应地学习图的邻接矩阵,发现变量之间的关系。图卷积模块:根据邻…

C语言:函数栈帧的创建和销毁

目录 1.什么是函数栈帧2.理解函数栈帧能解决什么问题3.函数栈帧的创建和销毁的过程解析3.1 什么是栈3.2 认识相关寄存器和汇编指令3.3 解析函数栈帧的创建和销毁过程3.3.1 准备环境3.3.2 函数的调用堆栈3.3.3 转到反汇编3.3.4 函数栈帧的创建和销毁 1.什么是函数栈帧 在写C语言…

VSCode便捷开发

一、常用插件 Vue 3 Snippets、Vetur、Vue - Official 二、常用开发者工具 三、Vue中使用Element-UI 安装步骤: 1、在VSCode的终端执行如下指令: npm i element-ui -S 2、在main.js中全局引入: import Vue from vue; import ElementUI from …

二、tsp学习笔记——LINUX SDK编译

开发环境:window11 wsl ubuntu24.04 lypwslDESKTOP-39T8VTC:~$ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 24.04.1 LTS Release: 24.04 Codename: noble linux_sdk同步 tspi_linux_sdk_repo_202…

分析用户请求K8S里ingress-nginx提供的ingress流量路径

前言 本文是个人的小小见解,欢迎大佬指出我文章的问题,一起讨论进步~ 我个人的疑问点 进入的流量是如何自动判断进入iptables的四表?k8s nodeport模式的原理? 一 本机环境介绍 节点名节点IPK8S版本CNI插件Master192.168.44.1…

初阶数据结构:树---堆

目录 一、树的概念 二、树的构成 (一)、树的基本组成成分 (二)、树的实现方法 三、树的特殊结构------二叉树 (一)、二叉树的概念 (二)、二叉树的性质 (三&#…

feign 远程调用详解

在平常的开发工作中,我们经常需要跟其他系统交互,比如调用用户系统的用户信息接口、调用支付系统的支付接口等。那么,我们应该通过什么方式进行系统之间的交互呢?今天,简单来总结下 feign 的用法。 1:引入依…

Sentinel的安装和做限流的使用

一、安装 Release v1.8.3 alibaba/Sentinel GitHubA powerful flow control component enabling reliability, resilience and monitoring for microservices. (面向云原生微服务的高可用流控防护组件) - Release v1.8.3 alibaba/Sentinelhttps://github.com/alibaba/Senti…

讯飞智作 AI 配音技术浅析(三):自然语言处理

自然语言处理(NLP)是讯飞智作 AI 配音技术的重要组成部分,负责将输入的文本转换为机器可理解的格式,并提取出文本的语义和情感信息,以便生成自然、富有表现力的语音。 一、基本原理 讯飞智作 AI 配音的 NLP 技术主要包…

wxWidgets生成HTML文件,带图片转base64数据

编译环境大家可以看我之前的文章,CodeBlocks + msys2 + wx3.2,win10 这里功能就是生成HTML文件,没用HTML库,因为是自己固定的格式,图片是一个vector,可以动态改变数量的。 效果如下: #include <wx/string.h> #include <wx/file.h> #include <wx/ima…

【matlab基本使用笔记】

ctrl a i 代码格式化 fzero求非线性函数的根 arrayfun将函数应用于每个数组元素 format long长格式输出 format long g取消科学计数法 linspace logspace 一、界面使用 1.创建matlab脚本 利用.m后缀的脚本文件&#xff08;又称为m文件&#xff09;编程&#xff1a; 点击…

机器学习--python基础库之Matplotlib (1) 超级详细!!!

机器学习--python基础库Matplotlib 机器学习--python基础库Matplotlib0 介绍1 实现基础绘图-某城市温度变化图1.1绘制基本图像1.2实现一些其他功能 2 再一个坐标系中绘制多个图像3 多个坐标系显示-plt.subplots(面向对象的画图方法)4 折线图的应用场景 机器学习–python基础库M…