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

Java二十三种设计模式-备忘录模式(19/23)

本文深入探讨了备忘录模式,从定义、组成、实现到使用场景、优缺点、与其他模式的比较,以及最佳实践和替代方案,全面解析了如何在软件开发中有效地保存和恢复对象状态,以支持复杂的撤销操作和历史状态管理。

备忘录模式:保存与恢复对象状态的策略

 基础知识,java设计模式总体来说设计模式分为三大类:

(1)创建型模式,共5种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。

(2)结构型模式,共7种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。

(3)行为型模式,共11种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

第一部分:备忘录模式概述

1.1 定义与用途

备忘录模式的基本定义:

备忘录模式是一种软件设计模式:在不破坏封闭的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。

备忘录模式是一种行为型设计模式,用于在不破坏对象封装性的前提下,捕获并保存对象的当前状态,以便未来可以恢复到该状态。

为何需要备忘录模式:

  • 状态恢复:在需要撤销操作或回滚到之前的状态时,备忘录模式允许对象恢复到特定的历史状态。
  • 封装性维护:通过将状态存储在外部的备忘录对象中,保持了原始对象的封装性,避免了外部直接访问对象的内部状态。

1.2 备忘录模式的组成

发起人(Originator)

  • 定义:负责创建备忘录对象,记录当前时刻的内部状态。
  • 职责:创建一个包含其当前状态的备忘录,并知道何时该状态需要被保存或恢复。

备忘录(Memento)

  • 定义:存储发起人的内部状态,但不允许外部直接访问。
  • 职责:安全地存储状态信息,并允许发起人在需要时恢复这些状态。

负责人(Caretaker)

  • 定义:负责保存和维护备忘录对象,但不干预其内容。
  • 职责:保存备忘录,确保在需要时可以提供给发起人恢复状态,但不修改备忘录中的状态信息。

角色之间的交互

  • 状态保存:发起人在关键时刻创建备忘录,并将其实例传递给负责人进行保存。
  • 状态恢复:当需要恢复状态时,发起人从负责人那里获取备忘录,并使用它来恢复之前的状态。

备忘录模式通过这三种角色的协作,提供了一种机制来捕获和恢复对象的状态,使得用户可以在不同时间点对对象进行快照和回滚。在下一部分中,我们将通过Java代码示例来展示备忘录模式的具体实现。

第二部分:备忘录模式的实现

2.1 Java实现示例

备忘录模式(Memento Pattern)是一种软件设计模式,用于在不破坏封装性的前提下捕获并保存一个对象的内部状态,以便之后可以恢复到该状态。这种模式通常用于实现撤销功能。

以下是Java语言中实现备忘录模式的一个简单示例:

// 发起人角色,负责创建备忘录并使用它来恢复之前的状态
class Originator {private String state;public void setState(String state) {this.state = state;}public String getState() {return state;}// 创建一个备忘录,存储当前状态public Memento saveStateToMemento() {return new Memento(state);}// 从备忘录中恢复状态public void getStateFromMemento(Memento memento) {state = memento.getState();}
}// 备忘录角色,负责存储发起人对象的内部状态
class Memento {private final String state;public Memento(String state) {this.state = state;}public String getState() {return state;}
}// 负责人角色,负责对备忘录的创建和存储进行管理
class Caretaker {private Memento memento;public void setMemento(Memento memento) {this.memento = memento;}public Memento getMemento() {return memento;}
}public class MementoDemo {public static void main(String[] args) {Originator originator = new Originator();Caretaker caretaker = new Caretaker();originator.setState("State #1");caretaker.setMemento(originator.saveStateToMemento());originator.setState("State #2");System.out.println("Current State: " + originator.getState());// 恢复到之前的状态originator.getStateFromMemento(caretaker.getMemento());System.out.println("Restored State: " + originator.getState());}
}

2.2 备忘录模式中的角色和职责

  1. 发起人(Originator)

    • 负责创建一个备忘录,用以记录当前时刻的内部状态。
    • 负责定义一个方法来获取当前状态,以便将其存储到备忘录中。
    • 负责定义一个方法来恢复之前存储的状态。
  2. 备忘录(Memento)

    • 负责存储发起人的内部状态。
    • 通常是一个不可变对象,只能通过发起人来访问。
  3. 负责人(Caretaker)

    • 负责保存好备忘录,不能对备忘录的内容进行操作或检查。
    • 可以决定保存多少个备忘录,以及保存多久。
  4. 客户端(Client)

    • 负责让发起人创建备忘录,并将备忘录传递给负责人。
    • 可以请求发起人恢复到备忘录中的状态,但不会直接与备忘录交互。

备忘录模式的关键在于发起人和备忘录之间的交互,以及负责人对备忘录的保存和管理。通过这种方式,可以安全地保存和恢复对象的状态,而不需要暴露对象的内部实现细节。

第三部分:备忘录模式的使用场景

3.1 需要保存与恢复状态的场景

在许多应用程序中,用户可能希望在进行一系列操作后能够回到之前的状态。以下是一些具体的场景:

  • 文本编辑器:用户在编辑文档时可能会进行多次修改。备忘录模式可以保存文档的每个状态,允许用户在需要时恢复到先前版本。
  • 图形设计软件:在设计过程中,设计师可能会尝试不同的元素布局或颜色方案。通过使用备忘录模式,设计师可以保存每个设计状态,并在不满意时回退到之前的版本。
  • 游戏开发:在游戏开发中,玩家的进度或游戏状态可能需要保存,以便在玩家退出游戏后能够继续之前的游戏进度。
  • 数据库事务:在数据库操作中,事务的回滚和提交可以看作是一种撤销和恢复操作,备忘录模式可以用于实现事务的持久性。

3.2 需要撤销操作的场景

撤销操作是用户界面设计中的一个常见需求,它允许用户撤销他们不希望保留的操作。以下是一些具体的应用场景:

  • 文本编辑:在文本编辑器中,用户可能希望撤销他们刚刚输入的文本或格式更改。备忘录模式可以保存文本的每个状态,以便用户可以逐个撤销操作。
  • 图形用户界面设计:在设计用户界面时,开发者可能希望尝试不同的控件布局或样式。备忘录模式可以保存每个设计步骤,允许开发者逐步撤销更改。
  • 图像编辑:在图像编辑软件中,用户可能希望撤销他们对图像所做的更改,如滤镜应用、颜色调整等。备忘录模式可以保存图像的原始状态和每次更改的状态。
  • 软件开发:在编码过程中,开发者可能会进行多次尝试和错误。使用备忘录模式,可以保存代码的每个版本,允许开发者在必要时撤销到之前的代码状态。

在这些场景中,备忘录模式通过提供一个简单而有效的方式来保存和恢复对象的状态,从而增强了应用程序的灵活性和用户体验。通过这种方式,用户可以更加自信地进行尝试,因为他们知道他们可以随时撤销不想要的操作。

 

第四部分:备忘录模式的优点与缺点

4.1 优点

备忘录模式提供了几个显著的优点,使其成为特定场景下的理想选择:

  1. 状态恢复:这是备忘录模式的主要优势之一。它允许对象在需要时恢复到之前的状态,这对于实现撤销功能至关重要。
  2. 封装性:备忘录模式通过将状态保存在备忘录对象中,而不是直接暴露对象的内部状态,从而保护了对象的封装性。
  3. 灵活性:对象可以在不同的时间点创建多个备忘录,这提供了在不同状态之间选择和切换的灵活性。
  4. 安全性:由于备忘录对象通常只对发起人对象可见,这减少了外部对对象状态的不当访问和修改的风险。
  5. 简化对象接口:对象不需要对外提供复杂的接口来处理状态的保存和恢复,这些操作可以封装在内部。

4.2 缺点

尽管备忘录模式有许多优点,但它也有一些潜在的缺点:

  1. 增加复杂性:实现备忘录模式需要引入额外的类和对象,这可能会使系统的设计和实现变得更加复杂。
  2. 资源消耗:如果系统需要保存大量的状态,每个状态都需要存储相应的备忘录对象,这可能会导致内存消耗显著增加。
  3. 管理负担:负责人(Caretaker)需要管理备忘录对象的生命周期,这可能会增加系统的管理负担,尤其是在需要长期保存大量状态的情况下。
  4. 性能问题:创建和恢复状态可能会涉及到复制对象的状态,这在某些情况下可能会影响性能。
  5. 有限的撤销能力:备忘录模式通常只支持单步撤销,实现多步撤销可能需要更复杂的逻辑和更多的资源消耗。

在使用备忘录模式时,开发者需要权衡这些优缺点,并根据具体的应用场景和需求做出合理的设计决策。例如,在资源受限的环境中,可能需要考虑替代方案或限制状态保存的数量。同时,也可以通过优化备忘录对象的存储和管理来减少资源消耗和提高性能。

 

第五部分:备忘录模式与其他模式的比较

5.1 与命令模式的比较

命令模式备忘录模式都提供了撤销操作的能力,但它们的实现方式和关注点有所不同:

  • 命令模式

    • 将请求封装为对象,从而允许用户对操作进行参数化、队列化和日志记录。
    • 通常包含执行操作的撤销和重做功能。
    • 命令对象知道接收者,即知道需要调用哪个对象的哪个方法。
    • 撤销是通过调用一个撤销方法来实现的,这通常涉及到命令对象内部状态的反转。
  • 备忘录模式

    • 专注于保存和恢复对象的状态,而不是命令或操作。
    • 通过创建一个包含对象状态快照的备忘录来实现撤销。
    • 发起人对象不知道负责人或备忘录的存在,这保持了低耦合性。
    • 撤销是通过恢复到之前保存的状态来实现的。

比较

  • 命令模式更适合需要记录一系列操作并提供撤销和重做功能的场景。
  • 备忘录模式更适合需要保存对象状态以便在将来恢复的场景,特别是当状态恢复不依赖于操作的顺序时。

5.2 与状态模式的对比

状态模式备忘录模式都与对象的状态管理有关,但它们的应用和目的不同:

  • 状态模式

    • 允许一个对象在其内部状态改变时改变其行为,看起来像是改变了其类。
    • 通过状态对象来封装不同的行为,这些状态对象通常是可互换的。
    • 状态模式关注于对象状态的转换,以及在状态改变时如何改变对象的行为。
  • 备忘录模式

    • 用于捕获并保存对象的内部状态,以便可以恢复到该状态。
    • 备忘录模式不关心状态转换的逻辑,只关心状态的保存和恢复。
    • 备忘录模式通常用于实现撤销功能,而不是状态转换。

比较

  • 状态模式更适合于对象的行为随状态变化而变化的场景,例如,一个对象在不同的状态下有不同的行为表现。
  • 备忘录模式更适合于需要保存和恢复对象状态的场景,例如,实现撤销操作或保存游戏进度。

总结来说,虽然命令模式、状态模式和备忘录模式都可以用于管理对象的状态或行为,但它们各自有不同的应用场景和设计目的。开发者在选择设计模式时,应该根据具体的需求和上下文来决定使用哪种模式。

第六部分:备忘录模式的最佳实践和建议

6.1 最佳实践

在使用备忘录模式时,遵循以下最佳实践可以帮助你更有效地实现和利用这一模式:

  1. 合理设计备忘录的存储

    • 只保存必要的状态信息,避免存储整个对象的副本,以减少内存消耗。
    • 考虑使用序列化或压缩技术来减少存储所需的空间。
  2. 确保备忘录的不可变性

    • 一旦备忘录被创建,它的状态就不应该被修改,以确保状态的一致性和可靠性。
    • 通过使用私有构造函数和不可变的数据结构来实现备忘录的不可变性。
  3. 限制备忘录的数量

    • 为避免资源过度消耗,限制可以创建的备忘录数量,例如,只保存最近的N个状态。
  4. 使用合适的数据结构

    • 使用栈或队列等数据结构来管理备忘录对象,以便实现撤销和重做操作。
  5. 清晰的接口设计

    • 为发起人、备忘录和负责人提供清晰和简洁的接口,以简化使用和维护。
  6. 考虑线程安全

    • 如果你的应用程序是多线程的,确保备忘录模式的实现是线程安全的。

6.2 避免滥用

  1. 评估需求

    • 在决定使用备忘录模式之前,评估是否真的需要撤销功能,以避免不必要的复杂性。
  2. 避免过度保存状态

    • 保存过多的状态可能会导致性能下降和资源浪费,因此应该根据实际需求来决定保存状态的频率和数量。
  3. 避免在简单场景中使用

    • 对于不需要复杂状态管理的简单操作,使用备忘录模式可能会过度设计。
  4. 监控性能影响

    • 定期检查备忘录模式对应用程序性能的影响,并在必要时进行优化。

6.3 替代方案

  1. 版本控制系统

    • 对于复杂的状态管理需求,考虑使用版本控制系统,它提供了更强大的状态跟踪和恢复能力。
  2. 栈或队列

    • 对于简单的撤销操作,可以使用栈来保存操作历史,实现后进先出(LIFO)的撤销机制。
  3. 命令模式

    • 如果撤销操作需要记录操作的详细信息,考虑使用命令模式来实现。
  4. 状态模式

    • 如果对象的行为随状态变化而变化,并且状态转换逻辑复杂,可以考虑使用状态模式。
  5. 数据库事务

    • 对于需要持久化状态的场景,可以使用数据库事务来管理状态的保存和恢复。
  6. 事件溯源

    • 对于需要详细历史记录的系统,事件溯源模式可以记录所有状态变化,允许重放和撤销操作。

通过考虑这些最佳实践和替代方案,你可以更明智地决定何时以及如何使用备忘录模式,以及如何优化你的设计以满足特定需求。

结语

备忘录模式提供了一种有效的方式来保存和恢复对象的状态,特别适用于需要撤销操作的场景。通过本文的深入分析,希望读者能够对备忘录模式有更全面的理解,并在实际开发中做出合理的设计选择。


博主还写了其他Java设计模式关联文章,请各位大佬批评指正:

(一)创建型模式(5种):

Java二十三种设计模式-单例模式(1/23)

Java二十三种设计模式-工厂方法模式(2/23)

Java二十三种设计模式-抽象工厂模式(3/23)

Java二十三种设计模式-建造者模式(4/23)

Java二十三种设计模式-原型模式(5/23)

(二)结构型模式(7种): 

Java二十三种设计模式-适配器模式(6/23)

Java二十三种设计模式-装饰器模式(7/23)

Java二十三种设计模式-代理模式(8/23)

Java二十三种设计模式-外观模式(9/23)

Java二十三种设计模式-桥接模式(10/23)

Java二十三种设计模式-组合模式(11/23)

Java二十三种设计模式-享元模式(12/23)

 (三)行为型模式(11种): 

Java二十三种设计模式-策略模式(13/23)

Java二十三种设计模式-模板方法模式(14/23)

Java二十三种设计模式-观察者模式(15/23)

Java二十三种设计模式-迭代子模式(16/23)

Java二十三种设计模式-责任链模式(17/23)

Java二十三种设计模式-命令模式(18/23)

​持续更新中......敬请关注 ​

相关文章:

Java二十三种设计模式-备忘录模式(19/23)

本文深入探讨了备忘录模式,从定义、组成、实现到使用场景、优缺点、与其他模式的比较,以及最佳实践和替代方案,全面解析了如何在软件开发中有效地保存和恢复对象状态,以支持复杂的撤销操作和历史状态管理。 备忘录模式&#xff1a…...

js一些杂乱理解

js 的值类型和引用类型 引用类型:object,array,function值类型:诸如number,stringboolean,null,Undefined,Symbol js使用变量访问对象属性示例 var myDog "Hunter"; var dogs { Fido: "Mutt", Hunter: "Doberman", Snoopie: "Beagle&q…...

机器学习 之 线性回归算法

目录 线性回归:理解与应用 什么是线性回归? 一元线性回归 正态分布的重要性 多元线性回归 实例讲解 数据准备 数据分析 构建模型 训练模型 验证模型 应用模型 代码实现 线性回归:理解与应用 线性回归是一种广泛使用的统计方法&…...

ThreadLoad如何防止内存溢出

优质博文:IT-BLOG-CN 从 ThreadLocalMap看 ThreadLocal使用不当的内存泄漏问题 【1】基础概念 : 首先我们先看看ThreadLocalMap的类图,我们知道 ThreadLocal只是一个工具类,他为用户提供get、set、remove接口操作实际存放本地变…...

2024.8.19 学习记录 —— 作业

一、TCP机械臂测试 #include <myhead.h>#define SER_PORT 8888 // 与服务器保持一致 #define SER_IP "192.168.0.114" // 服务器ip地址int main(int argc, const char *argv[]) {// 创建文件描述符打开键盘文件int fd open("/dev/input/event1…...

Java 阿里云视频直播开发流程

首先来看一下直播效果 推流工具有很多种&#xff08;例如OBS、阿里云直播Demo推流、等等&#xff0c;我用的是芯象导播&#xff09;阿里播放器地址 一、直播基础服务概述 官方文档说明 二、直播域名配置需要两个域名&#xff08;推流域名、播流域名&#xff09; 官方文档说…...

SQLite 轻量级的嵌入式关系型数据库的替代软件

SQLite 是一个轻量级的嵌入式关系型数据库&#xff0c;由于其简单易用和跨平台的特性&#xff0c;被广泛应用于各种应用程序中。以下是一些可作为SQLite替代品的数据库软件或可视化管理工具&#xff1a; 1. **SQLiteStudio**&#xff1a;这是一个免费、开源的跨平台SQLite数据…...

Flutter-自适用高度PageView

需求 在 Flutter 中&#xff0c;PageView 是一个非常常用的组件&#xff0c;能够实现多个页面的滑动切换。然而&#xff0c;默认的 PageView 高度是固定的&#xff0c;这在展示不同高度的页面时&#xff0c;可能会导致不必要的空白或内容裁剪问题。为了使 PageView 能够根据每…...

群晖NAS本地搭建可远程交互的大型语言模型LLM聊天机器人

文章目录 前言1. 拉取相关的Docker镜像2. 运行Ollama 镜像3. 运行Chatbot Ollama镜像4. 本地访问5. 群晖安装Cpolar6. 配置公网地址7. 公网访问8. 固定公网地址 前言 本文主要分享如何在群晖NAS本地部署并运行一个基于大语言模型Llama 2的个人本地聊天机器人并结合内网穿透工具…...

TypeScript 构建工具之 webpack

在实际开发中&#xff0c;直接使用TypeScript 编译器的情况不多。 在项目中&#xff0c;需要使用构建工具对代码进行打包&#xff0c;不可能脱离项目使用TypeScript 编译器单独打包TypeScript 。 那如何将 webpack 和 TypeScript 进行集成&#xff1f; 参考文档&#xff1a; w…...

conda环境下在pycharm中调试scrapy项目

前提条件 已经创建好了conda环境已经安装好了scrapy框架项目初始化完成 编写一个爬虫脚本 import scrapyclass StackOverflowSpider(scrapy.Spider):name stackoverflowstart_urls [http://stackoverflow.com/questions?sortvotes]def parse(self, response):print("…...

contenteditable=“true“的标签限制字数的时候修改光标位置

contenteditable"true"的标签限制字数的时候修改光标位置 有时候input和textarea并不能完全满足ui需求&#xff0c;这个时候我们就用contenteditable"true"来将别的标签修改为可编辑状态&#xff0c;但当我们通过js修改了内容之后光标的位置就是一个问题&…...

51单片机-LED灯蜂鸣器数码管按键DS18B20温度传感器

LDE灯的相关程序 LED灯闪烁 LED流水灯 方法1 方法二&#xff1a; 因为P1口可以直接控制P1^0~P1^7的8个led灯&#xff0c;利用一个8位的二进制数字来进行控制即可。如果要点亮P1^0 只需要给P1口传递 1111 1110即可。 蜂鸣器的使用 什么是蜂鸣器&#xff1f; 蜂鸣器是一种一…...

笔记本一线品牌有哪些

笔记本电脑的一线品牌通常指的是在市场上具有较高市场份额、良好口碑、较强的技术实力和服务能力的品牌。根据目前的信息&#xff0c;笔记本电脑市场的一线品牌主要包括以下几个&#xff1a; 联想 (Lenovo)&#xff1a;联想在全球笔记本市场上的占有率较高&#xff0c;其产品线…...

mysql聚合函数和分组

我最近开了几个专栏&#xff0c;诚信互三&#xff01; > |||《算法专栏》&#xff1a;&#xff1a;刷题教程来自网站《代码随想录》。||| > |||《C专栏》&#xff1a;&#xff1a;记录我学习C的经历&#xff0c;看完你一定会有收获。||| > |||《Linux专栏》&#xff1…...

ubuntu20.04+RealSenseD455

ubuntu20.04安装驱动双目相机RealSenseD455 安装环境安装RealSense SDK 2.0ROS包安装启动Realsense摄像头存在的 bugD455标定安装环境 系统:Ubuntu20.04 ROS:Noetic 视觉传感器:Intel RealSense D455 安装RealSense SDK 2.0 该安装有两种方式,一个是用命令安装,另一个是…...

WAF绕过技巧

WAF绕过技巧 WAF&#xff08;Web Application Firewall&#xff09;是一种安全系统&#xff0c;旨在监控和控制网络流量&#xff0c;以防止攻击&#xff0c;如SQL 注入、跨站脚本&#xff08;XSS&#xff09;和拒绝服务&#xff08;DoS&#xff09;。 WAF 可以通过多种方式绕过…...

HarmonyOS应用三之组件生命周期和参数传递

目录&#xff1a; 1、生命周期的执行顺序2、页面数据传递3、图片的读取4、数据的备份和恢复5、轮播图6、页面布局图 1、生命周期的执行顺序 /** Copyright (c) 2023 Huawei Device Co., Ltd.* Licensed under the Apache License, Version 2.0 (the "License");* yo…...

[Qt][Qt 网络][上]详细讲解

目录 0.概述1.UDP Socket1.核心API概览2.回显服务器3.回显客户端 0.概述 要使用Qt中有关网络编程的API&#xff0c;需要添加network模块 1.UDP Socket 1.核心API概览 主要的类有两个&#xff1a;QUdpSocket和QNetworkDatagramQUdpSocket表⽰⼀个UDP的socket⽂件 bind(const …...

读零信任网络:在不可信网络中构建安全系统21读后总结与感想兼导读

1. 基本信息 零信任网络&#xff1a;在不可信网络中构建安全系统 道格巴斯&#xff08;Doug Barth&#xff09; 著 人民邮电出版社,2019年8月出版 1.1. 读薄率 书籍总字数252千字&#xff0c;笔记总字数73194字。 读薄率73194252000≈29.5% 这个读薄率是最高的吧&#x…...

Java基础——注释

在开发中注释是必不可少的&#xff0c;帮助我们更好的标记阅读代码&#xff0c;下面介绍几种常用的注释方式。 一、注释种类 1. 单行注释 使用//一行代码来进行注释&#xff0c;只能注释一行内容 2. 多行注释 使用斜杠星号的方式 /*注释多行代码*/&#xff0c;注释多行代…...

Redis未授权访问漏洞利用合集

一、基本信息 靶机&#xff1a;IP:192.168.100.40 攻击机&#xff1a;IP:192.168.100.60 二、漏洞 & 过程 Redis 未授权访问漏洞利用无口令远程登录靶机 靶机 cd redis-4.0.8/src./redis-server ../redis.conf 攻击机 ./redis-cli -h 192.168.100.40 Redis 未授权访问…...

基于asp.net的在线考试系统、基于c#的在线考试管理系统

摘 要 伴随着社会以及科学技术的发展&#xff0c;互联网已经渗透在人们的身边&#xff0c;网络慢慢的变成了人们的生活必不可少的一部分&#xff0c;紧接着网络飞速的发展&#xff0c;管理系统这一名词已不陌生&#xff0c;越来越多的学校、公司等机构都会定制一款属于自己个…...

将 hugo 博客搬迁到服务器

1. 说明 在 Ubuntu 22.04 上使用 root 账号&#xff0c;创建普通账号&#xff0c;并赋予 root 权限。 演示站点&#xff1a;https://woniu336.github.io/ 魔改hugo主题: https://github.com/woniu336/hugo-magic 2. 服务器配置 建立 git 用户 adduser git安装 git sudo apt …...

【Datawhale AI夏令营第四期】 魔搭-大模型应用开发方向笔记 Task04 RAG模型 人话八股文Bakwaan_Buddy项目创空间部署

【Datawhale AI夏令营第四期】 魔搭-大模型应用开发方向笔记 Task04 RAG模型 人话八股文Bakwaan_Buddy项目创空间部署 什么是RAG&#xff1a; 我能把这个过程理解为Kimi.ai每次都能列出的一大堆网页参考资料吗&#xff1f;Kimi学了这些资料以后&#xff0c;根据这里面的信息综…...

CTF密码学小结

感觉没啥好总结的啊 基础的永远是RSA、流密码、哈希、对称密码、古典密码那一套&#xff08;密码学上过课都会&#xff09;&#xff0c;其他的就是数论的一些技巧 似乎格密码也很流行&#xff0c;以及一些奇奇怪怪的性质利用也很多 1、random设置种子后随机的性质&#xff1a…...

Vue快速入门(七)——Vue3 状态管理 - Pinia(二)

目录 六、核心概念——Getter 1、基本操作 定义getter 访问getter 2、访问其他 getter 3、向 getter 传递参数 4、访问其他 store 的 getter 使用 setup() 时的用法 使用选项式 API 的用法 使用 setup() 不使用 setup() 七、核心概念——Action 1、基本操作 定义a…...

ZooKeeper集群环境部署

1. ZooKeeper安装部署 1.1 系统要求 1.1.1 支持的平台 ZooKeeper 由多个组件组成。一些组件得到广泛支持&#xff0c;而另一些组件仅在较小的一组平台上得到支持。 客户端是 Java 客户端库&#xff0c;由应用程序用于连接到 ZooKeeper 集群。 服务器是在 ZooKeeper 集群节点…...

10 个 C# 关键字和功能

在 Stack Overflow 调查中&#xff0c;C# 语言是排名第 5 位的编程语言。它广泛用于创建各种应用程序&#xff0c;范围从桌面到移动设备再到云原生。由于有如此多的语言关键字和功能&#xff0c;对于开发人员来说&#xff0c;要跟上新功能发布的最新信息将是一项艰巨的任务。本…...

贪心算法之重叠区间问题

以下四个题都是重叠区间问题 452. 用最少数量的箭引爆气球 为了让气球尽可能重叠&#xff0c;先按照气球起始位置由大到小排序tips&#xff1a;sort默认就可以实现以上排序&#xff0c;不需要写cmp重点&#xff1a;当下一个气球的左边界不小于上一个气球的右边界时(即有重叠的…...