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

《图解设计模式》笔记(五)一致性

十一、Composite模式:容器与内容的一致性

像文件夹与文件一样,文件夹中可以放子文件夹与文件,再比如容器中可以放更小的容器和具体内容。

Composite模式:使容器与内容具有一致性,创造出递归结构。

Composite:混合物、复合物

示例程序类图

请添加图片描述

Entry

public abstract class Entry {public abstract String getName();                               // 获取名字public abstract int getSize();                                  // 获取大小public Entry add(Entry entry) throws FileTreatmentException {   // 加入目录条目throw new FileTreatmentException();}public void printList() {                                       // 为一览加上前缀并显示目录条目一览printList("");}protected abstract void printList(String prefix);               // 为一览加上前缀// 定义实例的标准的文字显示方式public String toString() {                                      // 显示代表类的文字// 本例是将文件名和文件大小一起显示出来。以供 toString调用(即 三、Template Method模式:将具体处理交给子类)。return getName() + " (" + getSize() + ")";}
}

File

public class File extends Entry {private String name;private int size;// File类的构造函数,会根据传入的文件名和文件大小生成文件实例public File(String name, int size) {this.name = name;this.size = size;}public String getName() {return name;}public int getSize() {return size;}// 具体的显示方式是用"/”分隔prefix 和表示实例自身的文字。protected void printList(String prefix) {// 这里我们使用了表达式"/"+ this。像这样用字符串加上对象时,程序会自动地调用对象的toString方法。这是Java 语言的特点。System.out.println(prefix + "/" + this);// 上面一行与下面两种写法是等价的:
//        System.out.println(prefix + "/" + this.toString());
//        System.out.println(prefix + "/" + toString());}
}

Directory

import java.util.Iterator;
import java.util.ArrayList;public class Directory extends Entry {private String name;                    // 文件夹的名字private ArrayList directory = new ArrayList();      // 文件夹中目录条目的集合public Directory(String name) {         // 构造函数this.name = name;}public String getName() {               // 获取名字return name;}// 进行计算处理:遍历directory字段中的所有元素,计算出它们的大小的总和public int getSize() {                  // 获取大小int size = 0;Iterator it = directory.iterator();while (it.hasNext()) {Entry entry = (Entry)it.next();// 在变量size 中加上了entry的大小,entry的实例不一定是File类还是Directory类。// 但无论哪个,都可通过getSize方法得到它的大小。这就是Composite模式的特征“容器与内容的一致性”的表现。// getSize方法的递归调用与 Composite模式 的结构是相对应的。size += entry.getSize();}return size;}public Entry add(Entry entry) {         // 增加目录条目directory.add(entry);return this;}// 显示文件夹的目录条目一览。// printList方法也会递归调用,这一点和getSize方法一样。// 而且,printList方法也没有判断变量entry究竟是File类的实例还是Directory类的实例,这一点也与getSize方法一样。// 这是因为容器和内容具有一致性。protected void printList(String prefix) {       // 显示目录条目一览System.out.println(prefix + "/" + this);Iterator it = directory.iterator();while (it.hasNext()) {Entry entry = (Entry)it.next();entry.printList(prefix + "/" + name);}}
}

FileTreatmentException

// 自定义异常类:对文件调用add方法时抛出的异常
public class FileTreatmentException extends RuntimeException {public FileTreatmentException() {}public FileTreatmentException(String msg) {super(msg);}
}

Main

public class Main {public static void main(String[] args) {try {System.out.println("Making root entries...");Directory rootdir = new Directory("root");Directory bindir = new Directory("bin");Directory tmpdir = new Directory("tmp");Directory usrdir = new Directory("usr");rootdir.add(bindir);rootdir.add(tmpdir);rootdir.add(usrdir);bindir.add(new File("vi", 10000));bindir.add(new File("latex", 20000));rootdir.printList();System.out.println("");System.out.println("Making user entries...");Directory yuki = new Directory("yuki");Directory hanako = new Directory("hanako");Directory tomura = new Directory("tomura");usrdir.add(yuki);usrdir.add(hanako);usrdir.add(tomura);yuki.add(new File("diary.html", 100));yuki.add(new File("Composite.java", 200));hanako.add(new File("memo.tex", 300));tomura.add(new File("game.doc", 400));tomura.add(new File("junk.mail", 500));rootdir.printList();} catch (FileTreatmentException e) {e.printStackTrace();}}
}

角色

在这里插入图片描述

可以将 Composite角色 与它内部的 Component角色(即 Leaf角色或Composite角色)看成是父亲与孩子们的关系。

getChild方法的作用是从Component角色获取这些“孩子们”。

  • Leaf(树叶)

    表示“内容”。在该角色中不能放入其他对象。

    示例中是File类。

  • Composite(复合物)

    表示容器。可以在其中放入 Leaf角色和Composite角色。

    示例中是Directory类。

  • Component

    使 Leaf角色和Composite角色具有一致性的角色。Composite角色是Leaf角色和Composite角色的父类。

    示例中是Entry类。

  • Client

    使用 Composite模式的角色。

    示例中是Main类。

扩展思路的要点

Add方法应该放在哪里

示例中,Entry类中定义了 add方法,所做的处理是抛出异常,是因为能使用 add方法的只能是Directory类。

下面我们学习一下各种add方法的定义位置和实现方法。

  • 方法1:定义在Entry类中,报错

    这是示例程序中的做法。

    能使用 add方法的只有Directory类,它会重写 add方法,根据需求实现其处理。
    File类会继承Entry类的add方法,虽然也可以调用它的add方法,不过会抛出异常。

  • 方法2:定义在Entry类中,但什么都不做

    将add方法定义在Entry类中,但不做任何处理。

  • 方法3:声明在Entry类中,但不实现

    在Entry类中声明add 抽象方法。

    若子类需要add方法就根据需求实现该方法,否则可以简单地报错。

    优点是所有子类必须都实现 add方法,不需要add方法时的处理也可以交给子类自己去做决定。

    但会导致在File中也必须定义本来完全不需要的add(有时还包括remove 和 getChild)方法。

  • 方法4:只定义在Directory类中

    因为只有Directory类可以使用 add方法,所以可以不在Entry类中定义add方法,而只将其定义在Directory类中。

    但,如果要向Entry类型的变量(实际保存的是Directory类的实例)中add时,需先将它们一个个地类型转换(cast)为Directory类型。

到处都存在递归结构

示例中,是文件夹的结构为例,但实际上在程序世界中,到处都存在递归结构和Composite模式。

例如,在视窗系统中,一个窗口可以含有一个子窗口,这就是Composite模式的典型应用。

在文章的列表中,各列表之间可以相互嵌套,这也是一种递归结构。

将多条计算机命令合并为一条宏命令时,若使用递归结构实现宏命令,那么还可以编写出宏命令的宏命令。

通常来说,树结构的数据结构都适用Composite模式。

相关的设计模式

  • Command 模式(第22章)
    使用 Command 模式编写宏命令时使用了Composite模式。

  • Visitor模式(第13章)
    可以使用 Visitor模式访问 Composite模式中的递归结构。

  • Decorator模式(第12章)
    Composite模式通过Component角色使容器(Composite角色)和内容(Leaf角色)具有一致性。
    Decorator模式使装饰框和内容具有一致性。

十二、Decorator 模式:装饰边框与被装饰物的一致性

Decorator模式:不断地为对象添加装饰的设计模式。

Decorator指的是“装饰物”。

本章中的示例程序的功能是给文字添加装饰边框。这里所谓的装饰边框是指用“-”、“+”、“|”等字符组成的边框。

示例程序类图

在这里插入图片描述

补充说明:

Border类 装饰边框的抽象类
display字段 Display类型 表示被装饰物。
通过继承,装饰边框与被装饰物具有了相同的方法。
具体而言,Border类继承了父类的各方法。
从接口(API)角度而言,装饰边框(Border)与被装饰物(Display)具有相同的方法也就意味着它们具有一致性。

Decorator模式的结构:display字段所表示的被装饰物并仅不限于StringDisplay的实例。因为,Border也是Display类的子类,display字段所表示的也可能是其他的装饰边框(Border类的子类的实例),而且那个边框中也有一个display字段。

Display

public abstract class Display {public abstract int getColumns();               // 获取横向字符数public abstract int getRows();                  // 获取纵向行数public abstract String getRowText(int row);     // 获取第row行的字符串public void show() {                            // 全部显示// show方法使用了getRows 和getRowText等抽象方法,这属于Tempate Method模式(第3章)。for (int i = 0; i < getRows(); i++) {System.out.println(getRowText(i));}}
}

StringDisplay

public class StringDisplay extends Display {private String string;                          // 要显示的字符串public StringDisplay(String string) {           // 通过参数传入要显示的字符串this.string = string;}public int getColumns() {                       // 字符数return string.getBytes().length;}public int getRows() {                          // 行数是1return 1;}public String getRowText(int row) {             // 仅当row为0时返回值if (row == 0) {return string;} else {return null;}}
}

Border

public abstract class Border extends Display {protected Display display;          // 表示被装饰物protected Border(Display display) { // 在生成实例时通过参数指定被装饰物this.display = display;}
}

SideBorder

public class SideBorder extends Border {private char borderChar;                        // 表示装饰边框的字符public SideBorder(Display display, char ch) {   // 通过构造函数指定Display和装饰边框字符 super(display);this.borderChar = ch;}public int getColumns() {                       // 字符数为字符串字符数加上两侧边框字符数 return 1 + display.getColumns() + 1;}public int getRows() {                          // 行数即被装饰物的行数return display.getRows();}public String getRowText(int row) {             // 指定的那一行的字符串为被装饰物的字符串加上两侧的边框的字符 return borderChar + display.getRowText(row) + borderChar;}
}

FullBorder

public class FullBorder extends Border {public FullBorder(Display display) {super(display);}public int getColumns() {                   // 字符数为被装饰物的字符数加上两侧边框字符数return 1 + display.getColumns() + 1;}public int getRows() {                      // 行数为被装饰物的行数加上上下边框的行数return 1 + display.getRows() + 1;}public String getRowText(int row) {         // 指定的那一行的字符串if (row == 0) {                                                 // 上边框return "+" + makeLine('-', display.getColumns()) + "+";} else if (row == display.getRows() + 1) {                      // 下边框return "+" + makeLine('-', display.getColumns()) + "+";} else {                                                        // 其他边框return "|" + display.getRowText(row - 1) + "|";}}private String makeLine(char ch, int count) {         // 生成一个重复count次字符ch的字符串 StringBuffer buf = new StringBuffer();for (int i = 0; i < count; i++) {buf.append(ch);}return buf.toString();}
}

Main

public class Main {public static void main(String[] args) {Display b1 = new StringDisplay("Hello, world.");Display b2 = new SideBorder(b1, '#');Display b3 = new FullBorder(b2);b1.show();b2.show();b3.show();Display b4 = new SideBorder(new FullBorder(new FullBorder(new SideBorder(new FullBorder(new StringDisplay("你好,世界。")),'*'))),'/');b4.show();}
}

角色

在这里插入图片描述

  • Component
    增加功能时的核心角色。
    Component角色只是定义了接口(API)。示例中是Display类。

  • ConcreteComponent
    具体实现了Component角色所定义的接口(API)。示例中是StringDisplay类。

  • Decorator(装饰物)
    该角色具有与Component角色相同的接口(API)。在它内部保存了被装饰对象——Component角色。Decorator角色知道自己要装饰的对象。示例中是Border类。

  • ConcreteDecorator(具体的装饰物)
    该角色是具体的Decorator角色。示例中是SideBorder类和FullBorder类。

拓展思路的要点

  • 接口(API)的透明性

    在 Decorator模式中,装饰边框与被装饰物具有一致性。
    表示装饰边框的Border类是表示被装饰物的Display类的子类,这就体现了它们之间的一致性。
    即,Border类(以及它的子类)与表示被装饰物的Display类具有相同的接口(API)。
    这样,即使被装饰物被边框装饰起来了,接口(API)也不会被隐藏起来。其他类依然可以调用getColumns、getRows、,getRowText以及show方法。这就是接口(API)的“透明性”。

    在示例程序中,实例b4被装饰了多次,但是接口(API)却没有发生任何变化。
    得益于接口(API)的透明性,Decorator模式中也形成了类似于Composite模式中的递归结构。
    即,装饰边框里面的“被装饰物”实际上又是别的物体的“装饰边框”。
    就像是剥洋葱时以为洋葱心要出来了,结果却发现还是皮。
    不过,Decorator模式虽然与Composite模式一样,都具有递归结构,但是它们的使用目的不同。

  • Decorator模式的主要目的是通过添加装饰物来增加对象的功能。

    在不改变被装饰物的前提下增加功能
    在 Decorator模式中,装饰边框与被装饰物具有相同的接口(API)。
    虽然接口(API)是相同的,但越装饰,功能越多。
    例如,用SideBorder装饰Display后,就可以在字符串的左右两侧加上装饰字符。
    若再用 FullBorder装饰,则可以在字符串的四周加上边框。
    此时,我们完全不需要对被装饰的类做任何修改。这样,我们就实现了不修改被装饰的类即可增加功能。

    Decorator模式使用了委托。对“装饰边框”提出的要求(调用装饰边框的方法)会被转交(委托)给“被装饰物”去处理。
    以示例程序来说,就是SideBorder类的getColumns方法调用了display,getColumns ()。
    除此以外,getRows方法也调用了display.getRows()

  • 可以动态地增加功能

    Decorator 模式中用到了委托,它使类之间形成了弱关联关系。

    因此,不用改变框架代码,就可以生成一个与其他对象具有不同关系的新对象。

  • 只需要一些装饰物即可添加许多功能

    使用 Decorator模式可以为程序添加许多功能。只要准备一些装饰边框(ConcreteDecorator 角色),即使这些装饰边框都只有简单功能,也可将它们自由组合成为新的对象。
    这就像自由选择各种口味的冰激凌一样。冰激凌店不必准备所有的冰激凌成品,而是准备各种香料,顾客下单后在冰激凌上加各种香料就可以了。
    Decorator模式就是可以应对这种多功能对象的需求的一种模式。

  • java.io包与Decorator模式

    java.io包是用于输入输出(Input/Output,简称I/O)的包。这里,我们使用了 Decorator 模式。
    首先,可以用Reader reader = new FileReader("datafile.txt");生成一个读取文件的实例。
    然后,也可以用Reader reader = new BufferedReader(new Fi1eReader("datafile.txt"));在读取文件时将文件内容放入缓冲区。
    这样,在生成BufferedReader类的实例时,会指定将文件读取到FileReader类的实例中。
    再然后,也可以这样管理行号:Reader reader = new LineNumberReader(New BufferedReader(New FileReader("datafile.txt")))

    无论是LineNumberReader类的构造函数还是BufferedReader类的构造函数,都可以接收Reader类(的子类)的实例作为参数,因此我们可以像上面那样自由地进行各种组合。
    还可以只管理行号,但不进行缓存处理:Reader reader = new LineNumberReader (new FileReader ("datafile.txt"));
    接下来,我们还会管理行号,进行缓存,但是我们不从文件中读取数据,而是从网络中读取数据(下面的代码中省略了细节部分和异常处理)。

    java.net.Socket socket = new Socket (hostname, portnumber):
    Reader reader = new LineNumberReader (new BufferedReader (new InputstreamReader(socket.getInputstream())));
    

    这里使用的InputStreamReader类既接收getInputStream()方法返回的InputStream类的实例作为构造函数的参数,也提供了Reader类的接口(API)(这属于第2章学习过的Adapter模式)。
    除了java.io包以外,我们还在javax.swing.border包中使用了Decorator模式。
    javax.swing.border包为我们提供了可以为界面中的控件添加装饰边框的类。

  • 导致增加许多很小的类

    Decorator 模式的一个缺点是会导致程序中增加许多功能类似的很小的类。

相关的设计模式

  • Adapter模式(第2章)

    Decorator模式可以在不改变被装饰物的接口(API)的前提下,为被装饰物添加边框(透明性)。

    Adapter模式用于适配两个不同的接口(API)。

  • Stragety模式(第10章)

    Decorator模式可以像改变被装饰物的边框或是为被装饰物添加多重边框那样,来增加类的功能。

    Stragety 模式通过整体地替换算法来改变类的功能。

相关文章:

《图解设计模式》笔记(五)一致性

十一、Composite模式&#xff1a;容器与内容的一致性 像文件夹与文件一样&#xff0c;文件夹中可以放子文件夹与文件&#xff0c;再比如容器中可以放更小的容器和具体内容。 Composite模式&#xff1a;使容器与内容具有一致性&#xff0c;创造出递归结构。 Composite&#x…...

burpsuite抓取html登陆和上传数据包

一、burpsuite抓取html登陆数据包 1、先写一个html格式的登陆页面 <!doctype html> <html lang="en"> <head><meta charset="UTF-8"><title>这是标签</title></head> <body> <hr><!-- 登陆表单…...

前端导出pdf,所见即所得

一、推荐方案&#xff1a;html2canvas jsPDF&#xff08;图片式PDF&#xff09; javascript import html2canvas from html2canvas; import jsPDF from jspdf;const exportPDF async (elementId, fileName) > {const element document.getElementById(elementId);// 1.…...

使用orjson库提升Python JSON处理性能

使用orjson库提升Python JSON处理性能 引言 在现代软件开发中&#xff0c;JSON&#xff08;JavaScript Object Notation&#xff09;作为一种轻量级的数据交换格式&#xff0c;广泛应用于Web服务、配置文件、数据存储等场景。Python作为一门流行的编程语言&#xff0c;提供了…...

TcpClientTest

ClientTest&#xff1a; using System; using System.Net.Sockets; using System.Text;class TcpClientTest {static void Main(string[] args){try{// 创建一个TcpClient实例并连接到服务器 TcpClient client new TcpClient("1vg5062570.51mypc.cn", 43319);//1v…...

【系统架构设计师】操作系统 ② ( 存储管理 | 页式存储 | 逻辑地址 与 物理地址 | 页表结构 | 物理内存淘汰机制 )

文章目录 一、页式存储1、CPU 调用数据2、内存存储数据弊端3、分页存储4、逻辑地址 和 物理地址 的结构5、逻辑地址 和 物理地址 的结构 示例6、页式存储 优缺点 二、逻辑地址 与 物理地址1、逻辑地址2、物理地址3、逻辑地址 与 物理地址 区别4、逻辑地址 与 物理地址 的转换 三…...

STM32自学记录(八)

STM32自学记录 文章目录 STM32自学记录前言一、ADC杂记二、实验1.学习视频2.复现代码 总结 前言 ADC 一、ADC杂记 ADC其实就是一个电压表&#xff0c;把引脚的电压值测出来&#xff0c;放在一个变量里。 ADC&#xff1a;模拟——数字转换器。 ADC可以将引脚上连续变化的模拟电…...

Vim 多窗口编辑及文件对比

水平分割 :split 默认使用水平分割的方式。 :split :sp 垂直分割 :vsplit :vs 带文件的分割 :split 文件名 :sp 文件名 在光标所在的窗口&#xff0c;输入分割窗口命令就会对那个窗口进行分割。 切换窗口 Ctrlw 切换正在编辑的窗口 快速分割窗口 Ctrlwn 快速分割当前…...

基于深度学习的人工智能量化衰老模型构建与全流程应用研究

一、引言 1.1 研究背景与意义 1.1.1 人口老龄化现状与挑战 人口老龄化是当今全球面临的重要社会趋势之一,其发展态势迅猛且影响深远。根据联合国的相关数据,1980 年,全球 65 岁及以上人口数量仅为 2.6 亿,到 2021 年,这一数字已翻番,达到 7.61 亿,而预计到 2050 年,…...

第八届大数据与应用统计国际学术研讨会(ISBDAS 2025)

重要信息 官网&#xff1a;www.is-bdas.org 时间&#xff1a;2025年2月28-3月2日 地点&#xff1a;中国 广州 主办单位&#xff1a;广东省高等教育学会人工智能与高等教育研究分会 协办单位&#xff1a;北京师范大学人工智能与未来网络研究院、人工智能与大数据科研基地 …...

链表专题-03

链表专题(三) 两数相加 问题 [力扣2] 2. 两数相加 - 力扣&#xff08;LeetCode&#xff09; 问题描述 给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储 一位 数字。请你将两个数相加&#xff…...

Ollama下载安装教程

一、去官网下载Ollama 点击前往Ollama官网 进去后点击下载 根据不同的系统去选择 由于服务器在国外可能下载界面进不去或者下载非常慢&#xff0c;可以去网盘获取 点击下方蓝色字体直达 点击前往夸克网盘下载 点击前往百度网盘下载 下载好后双击应用程序安装即可 点击ins…...

SQL Server查询计划操作符(7.3)——查询计划相关操作符(6)

7.3. 查询计划相关操作符 48)Key Lookup:该操作符对一个有簇索引的表进行书签查找。参数列包含簇索引的名字和用于查找簇索引中数据行的簇键。该操作符总是伴随一个Nested Loops操作符。如果其参数列中出现WITH PREFETCH子句,则查询处理器已决定使用异步预取(预读,read-ah…...

IDEA查看项目依赖包及其版本

一.IDEA将现有项目转换为Maven项目 在IntelliJ IDEA中,将现有项目转换为Maven项目是一个常见的需求,可以通过几种不同的方法来实现。Maven是一个强大的构建工具,它可以帮助自动化项目的构建过程,管理依赖关系,以及其他许多方面。 添加Maven支持 如果你的项目还没有pom.xm…...

网络分析工具—WireShark的安装及使用

Wireshark 是一个广泛使用的网络协议分析工具&#xff0c;常被网络管理员、开发人员和安全专家用来捕获和分析网络数据包。它支持多种网络协议&#xff0c;能够帮助用户深入理解网络流量、诊断网络问题以及进行安全分析。 Wireshark 的主要功能 数据包捕获与分析&#xff1a; …...

【LeetCode 刷题】贪心算法(2)-进阶

此博客为《代码随想录》贪心算法章节的学习笔记&#xff0c;主要内容为贪心算法进阶的相关题目解析。 文章目录 135. 分发糖果406. 根据身高重建队列134. 加油站968. 监控二叉树 135. 分发糖果 题目链接 class Solution:def candy(self, ratings: List[int]) -> int:n l…...

网络工程师 (25)OSI模型—服务访问点

前言 OSI模型&#xff0c;即开放式通信系统互联参考模型&#xff08;Open System Interconnection Reference Model&#xff09;&#xff0c;是国际标准化组织&#xff08;ISO&#xff09;提出的一个旨在使各种计算机在世界范围内互连为网络的标准框架。 一、定义 服务访问点&a…...

如何在RTACAR中配置IP多播(IP Multicast)

一、什么是IP多播 IP多播&#xff08;IP Multicast&#xff09;是一种允许数据包从单一源地址发送到多个目标地址的技术&#xff0c;是一种高效的数据传输方式。 多播地址是专门用于多播通信的IP地址&#xff0c;范围从 224.0.0.0到239.255.255.255 与单播IP地址不同&#x…...

使用docker搭建FastDFS文件服务

1.拉取镜像 docker pull registry.cn-hangzhou.aliyuncs.com/qiluo-images/fastdfs:latest2.使用docker镜像构建tracker容器&#xff08;跟踪服务器&#xff0c;起到调度的作用&#xff09; docker run -dti --networkhost --name tracker -v /data/fdfs/tracker:/var/fdfs -…...

VC播放mp3的方法

1、使用msi库 #include <mmsystem.h> #pragma comment(lib,"winmm.lib") .......//打开文件MCI_OPEN_PARMS mciOpen; mciOpen.lpstrDeviceType _T("mpegvideo"); mciOpen.lpstrElementName _T("c://1.mp3"); MCIERROR mciError mci…...

【读书笔记·VLSI电路设计方法解密】问题46:什么是bug覆盖率

在IC设计项目的验证过程中&#xff0c;功能测试&#xff08;通过使用测试平台&#xff09;有助于定位设计错误或漏洞。这个验证过程有三个阶段&#xff1a;构建和启动测试平台、验证基本测试用例以及验证边界情况。 在前两个阶段&#xff0c;漏洞很容易被检测到&#xff0c;因…...

sqli-lab靶场学习(五)——Less15-17(post方法盲注、修改密码)

前言 第11-14关开始用post方法&#xff0c;15-17关会用到盲注&#xff0c;post方法盲注和get方法类似。 Less15 这关是单引号闭合&#xff0c;有报错但没有具体情况的回显&#xff0c;因此适合使用错误盲注。 在用户名密码框分别输入 账号&#xff1a;admin and 11 -- asd…...

1、http介绍

一、HTTP 和 HTTPS 简介 HTTP&#xff08;HyperText Transfer Protocol&#xff09; 用途&#xff1a;用于网页数据传输&#xff08;不加密&#xff09;。协议特性&#xff1a;以明文形式传输数据&#xff0c;默认端口 80&#xff0c;无身份验证和完整性保护。典型场景&#xf…...

Vim跳转文件及文件行结束符EOL

跳转文件 gf 从当前窗口打开那个文件的内容&#xff0c;操作方式&#xff1a;让光标停在文件名上&#xff0c;输入gf。 Ctrlo 从打开的文件返回之前的窗口 Ctrlwf 可以在分割的窗口打开跳转的文件&#xff0c;不过在我的实验不是次次都成功。 统一行尾格式 文本文件里存放的…...

LLM:DeepSeek 系列(二)

原文链接 3、DeepSeek-V2 DeepSeek-V2 发布于 2024 年 5 月&#xff0c;为多领域专家&#xff08;MoE&#xff09;语言模型&#xff0c;包含总共 2360 亿个参数&#xff0c;其中每个词元激活 210 亿个参数&#xff0c;并支持 12.8 万个词元的上下文长度。DeepSeek-V2 采用包括…...

订单超时设计(1)--- 如何使用redis实现订单超时实时关闭功能

如何使用redis实现订单超时实时关闭功能 准备工作实现步骤解释注意事项&#xff08;重点&#xff09; 使用Redis实现订单超时实时关闭功能&#xff0c;可以利用Redis的延时队列&#xff08;使用Sorted Set实现&#xff09;和过期键&#xff08;使用TTL和Keyspace Notifications…...

【0401】Postgres内核 CREATE DATABASE database-name 源码实现 ①

文章目录 1. CREATE DATABASE 语句1.1 CREATE DATABASE 语法1.2 CREATE DATABASE 调用栈2. CREATE DATABASE 内核实现2.1 从 CreatedbStmt 节点树 提取 options2.2 获取 datdba(proposed owner) OID2.3 当前用户具有 create DB 权限?2.4 获取 database template1. CREATE DA…...

Termux安装ssh实现电脑ssh

Termux下载 点击下载 在 Termux 中安装并使用 SSH&#xff0c;按照以下步骤操作&#xff1a; 1. 更新软件包列表 pkg update && pkg upgrade2. 安装 OpenSSH pkg install openssh3. 设置 SSH 密码&#xff08;必须&#xff0c;否则无法使用 SSH 服务器&#xff09…...

nexus部署及配置https访问

1. 使用docker-compose部署nexus docker-compose-nexus.yml version: "3" services:nexus:container_name: my-nexusimage: sonatype/nexus3:3.67.1hostname: my-nexusnetwork_mode: hostports:- 8081:8081deploy:resources:limits:cpus: 4memory: 8192Mreservations…...

【MySQL】表操作

表操作 一、创建表 1、语句2、语句介绍3、注意事项4、介绍5、示例 二、查看表结构 1、语句2、介绍3、返回的信息4、示例 三、添加字段 1、语句2、语句介绍3、示例 四、修改 1、语句2、语句介绍3、示例 五、删除 1、语句2、示例 六、修改表名 1、语句2、语句介绍3、示例 七、删…...

浅析Ruby类污染及其在Sinatra框架下的利用

和JavaScript中的原型链污染类似&#xff0c;Ruby中也存在类似的概念——类污染&#xff0c;两者都是对象进行不安全的递归合并导致的。 网上也没有相关的分析文章&#xff0c;只有下面这篇文章应该是第一次谈到这个问题 Class Pollution in Ruby: A Deep Dive into Exploiti…...

iPhone 在华销量大幅下挫

iPhone在乔布斯时代缔造的神话在中国正逐渐走向没落&#xff0c;挤牙膏式的升级方式类似于诺基亚的N70系列&#xff0c;毫无新意的创新能力&#xff0c;求稳着陆的经营理念&#xff0c;工艺和美学不再独领风骚&#xff0c;甚至拍照领域和AI增强计算&#xff0c;折叠屏等技术领域…...

Fedora 的 2025 年展望:AI 集成与 HDR 支持打造强大 Linux 桌面体验

Fedora 项目已经从节庆活动中恢复&#xff0c;准备在未来几个月推出一系列关键计划。Red Hat 软件工程总监 Christian Schaller 在他的博客文章中分享了 2025 年 Fedora 发行版的重点发展方向和优先事项&#xff0c;涵盖了人工智能集成、Wayland、HDR 协议、PipeWire 等多个领域…...

mysql 学习11 事务,事务简介,事务操作,事务四大特性,并发事务问题,事务隔离级别

一 事务简介&#xff0c; 数据库准备&#xff1a; create table account(id int auto_increment primary key comment 主键ID,name varchar(128) not null comment 姓名,backaccountnumber char(18) unique comment 银行账号,money float comment 余额 )comment 银行账号表;…...

C# Winform怎么设计串口,客户端和相机控件界面显示

首先我们必须把这个类创建好 INIAPI using System; using System.Text; using System.Runtime.InteropServices;namespace Ini {public class IniAPI{#region INI文件操作/** 针对INI文件的API操作方法&#xff0c;其中的节点&#xff08;Section)、键&#xff08;KEY&#x…...

【场景题】架构优化 - 解耦Redis缓存与业务逻辑

1. 需求分析 某公司需要将原有的Redis缓存抽离出来&#xff0c;并且还要要实现&#xff1a; 可配置热拔插高可用高通用 请问你会如何实现&#xff1f; 2. 思路 话不多说直接上思路&#xff1a; 自定义缓存注解&#xff0c;当容器扫描到该注解自动调用AOP想应的增强方法为…...

WGCLOUD监控系统部署教程

官网地址&#xff1a;下载WGCLOUD安装包 - WGCLOUD官网 第一步、环境配置 #安装jdk 1、安装 EPEL 仓库&#xff1a; sudo yum install -y epel-release 2、安装 OpenJDK 11&#xff1a; sudo yum install java-11-openjdk-devel 3、如果成功&#xff0c;你可以通过运行 java …...

linux——网络计算机{序列化及反序列化(JSON)(ifdef的用法)}

linux——网络&#xff08;服务器的永久不挂——守护进程&#xff09;-CSDN博客 目录 一、序列化与反序列化 1. 推荐 JSON 库 2. 使用 nlohmann/json 示例 安装方法 基础用法 输出结果 3. 常见操作 4. 其他库对比 5. 选择建议 二、ifdef宏的用法 基本语法 核心用途…...

Android 开发APP中参数配置与读取总结

以使用MQTT配置的参数 MQTT_BROKER_UR 、MQTT_USER_NAME、 MQTT_PASSWORD为例&#xff0c;说明配置设置和读取应用 项目中使用系统参数&#xff08;如环境变量和gradle.properties文件中的属性&#xff09;在Gradle构建脚本中&#xff0c;以下是一个详细的操作文档资料&…...

Web应用国际化(i18n)实现详解 python

Web应用国际化&#xff08;i18n&#xff09;实现详解 1. 设计理念 本项目的国际化&#xff08;Internationalization&#xff09;解决方案基于Python的gettext模块&#xff0c;提供了一个灵活、可扩展的多语言支持系统。 2. 语言支持 2.1 支持的语言列表 项目支持超过35种…...

mysql mvcc 锁 关系

多版本并发控制&#xff08;MVCC&#xff09;是一种用于数据库并发控制的机制&#xff0c;它可以在保证数据一致性的同时&#xff0c;提高数据库的并发性能。下面结合 MVCC 机制&#xff0c;详细阐述常见的四种事务隔离级别&#xff08;读未提交、读已提交、可重复读、串行化&a…...

【银河麒麟高级服务器操作系统】系统日志Call trace现象分析及处理全流程

了解更多银河麒麟操作系统全新产品&#xff0c;请点击访问 麒麟软件产品专区&#xff1a;https://product.kylinos.cn 开发者专区&#xff1a;https://developer.kylinos.cn 文档中心&#xff1a;https://document.kylinos.cn 服务器环境以及配置 系统环境 物理机/虚拟机/云…...

新能源产业的质量革命:六西格玛培训如何重塑制造竞争力

在新能源行业狂飙突进的今天&#xff0c;企业若想在全球供应链中占据高地&#xff0c;仅靠技术突破已远远不够。制造效率的毫厘之差&#xff0c;可能成为市场话语权的千里之距。某光伏巨头曾因电池片良率低于行业均值1.5%&#xff0c;导致年损失超2.3亿元——这恰恰印证了六西格…...

【ArcGIS】R语言空间分析、模拟预测与可视化技术

R语言在空间数据挖掘中具有广泛的应用&#xff0c;以下是一些关键内容和常用包的介绍&#xff1a; R语言空间数据挖掘的关键技术 空间数据类型 矢量数据&#xff1a;包括点&#xff08;Point&#xff09;、线&#xff08;Line&#xff09;、面&#xff08;Polygon&#xff09;等…...

单例模式几种实现

静态内部类holder实现&#xff08;推荐&#xff09; public class UniqueIdGenerator {public static final UniqueIdGenerator INSTANCE Holder.INSTANCE;// Private holder class for lazy initializationprivate static class Holder {static final UniqueIdGenerator INS…...

什么是Prompt工程?

什么是提示工程&#xff1f; Prompt一词&#xff0c;在英语中主要用作动词、形容词、名词和副词&#xff0c;主要意思包括“促使&#xff0c;导致&#xff1b;鼓励&#xff0c;提示&#xff1b;迅速的&#xff0c;立刻的&#xff1b;准时地”等。 在人工智能的语境下&#xf…...

C++,设计模式,【单例模式】

文章目录 一、模式定义与核心价值二、模式结构解析三、关键实现技术演进1. 基础版(非线程安全)2. 线程安全版(双重检查锁)3. 现代C++实现(C++11起)四、实战案例:全局日志管理器五、模式优缺点深度分析✅ 核心优势⚠️ 潜在缺陷六、典型应用场景七、高级实现技巧1. 模板化…...

详解SQLAlchemy的函数relationship

在 SQLAlchemy 中&#xff0c;relationship 是一个非常重要的函数&#xff0c;用于定义模型之间的关系。它用于在 ORM 层面上表示数据库表之间的关联关系&#xff08;如 1 对 1、1 对多和多对多&#xff09;。relationship 的主要作用是提供一个高级接口&#xff0c;用于在模型…...

vue 的 watch 和 computed 有什么区别?

在 Vue.js 中,watch 和 computed 都是用于响应式数据处理的功能,但它们有不同的用途和实现方式。以下是二者的主要区别: 1. 用途 computed 计算属性:用于基于已有数据计算出新的值。它们是基于依赖的数据变化而自动重新计算的,通常用于模板中显示的派生状态。缓存:计算…...

WPS如何接入DeepSeek(通过第三方工具)

WPS如何接入DeepSeek 一、下载并安装OfficeAI插件二、配置OfficeAI插件三、使用DeepSeek功能 本文介绍如何通过 WPS 的第三方工具调用 DeepSeek 大模型&#xff0c;实现自动化文本扩写、校对和翻译等功能。 一、下载并安装OfficeAI插件 1、访问OfficeAI插件下载地址&#xff…...