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

【设计模式】1、设计模式七大原则

目录

  • 一、单一职责
  • 二、接口隔离
  • 三、依赖倒置(倒转)
  • 四、里氏替换
  • 五、迪米特法则(Law of Demeter)
  • 六、开闭
  • 七、合成复用

一、单一职责

  • 类(或方法)功能的专一性。一个类(或方法)不应该承担太多功能,一个类(或方法)最好只承担 一种类型 的功能。
public class SingleResponsibility {public static void main(String[] args) {Vehicle vehicle = new Vehicle();vehicle.run("汽车");vehicle.run("火车");vehicle.run("自行车");vehicle.run("飞机"); // 有问题vehicle.run("轮船"); // 有问题}
}class Vehicle {public void run(String vehicleName) {System.out.println(vehicleName + "在公路上行驶");}
}

Vehicle 类既处理陆地上的交通工具,又处理天空中的交通工具;它的作用太广泛了,不单一。


public class SingleResponsibility {public static void main(String[] args) {RoadVehicle roadVehicle = new RoadVehicle();roadVehicle.run("汽车");roadVehicle.run("火车");roadVehicle.run("自行车");SkyVehicle skyVehicle = new SkyVehicle();skyVehicle.run("飞机");WaterVehicle waterVehicle = new WaterVehicle();waterVehicle.run("轮船");}
}class RoadVehicle {public void run(String vehicleName) {System.out.println(vehicleName + "在公路上行驶");}
}class WaterVehicle {public void run(String vehicleName) {System.out.println(vehicleName + "在水中行驶");}
}class SkyVehicle {public void run(String vehicleName) {System.out.println(vehicleName + "在天空中行驶");}
}

在类级别遵循了单一职责原则

当业务功能比较简单的时候也没有必要将其拆分为多个类(如下所示)


public class SingleResponsibility {public static void main(String[] args) {Vehicle vehicle = new Vehicle();vehicle.run("汽车", VehicleType.ROAD);vehicle.run("火车", VehicleType.ROAD);vehicle.run("自行车", VehicleType.ROAD);vehicle.run("飞机", VehicleType.SKY);vehicle.run("轮船", VehicleType.WATER);}
}enum VehicleType {ROAD, WATER, SKY;
}class Vehicle {public void run(String name, VehicleType type) {String sentence = "";if (type == VehicleType.ROAD) {sentence = "在公路上行驶";} else if (type == VehicleType.WATER) {sentence = "在水中行驶";} else if (type == VehicleType.SKY) {sentence = "在天空中行驶";}System.out.println(name + sentence);}// public void roadRun(String name) {}// public void skyRun(String name) {}// public void waterRun(String name) {}
}

Vehicle 类不符合单一职责原则,但其功能简单 。
当功能非常非常简单的时候,不一定必须遵循单一职责原则。(杀鸡别用宰牛刀)

  • 降低了类的功能的复杂度
  • 提高了代码的维护性
  • 代码修改导致连带错误几率降低

二、接口隔离

Clients should not be forced to depend on methods they do not use. 客户端不应该被迫依赖它不使用的方法。
The dependency of one class to another one should depend on the smallest possible interface. 一个类对另一个类的依赖应该建立在最小的接口上。

在这里插入图片描述

public class InterfaceSegregation {public static void main(String[] args) {InOutAbleImpl1 impl1 = new InOutAbleImpl1();InOutAbleImpl2 impl2 = new InOutAbleImpl2();Cat cat = new Cat();cat.use1(impl1);cat.use2(impl1);cat.use3(impl1);Dog dog = new Dog();dog.use1(impl2);dog.use2(impl2);dog.use3(impl2);}
}class Cat {public void use1(InOutAble inOutAble) {inOutAble.openDoor();}public void use2(InOutAble inOutAble) {inOutAble.pushGoods();}public void use3(InOutAble inOutAble) {inOutAble.writeGoodsName();}
}class Dog {public void use1(InOutAble inOutAble) {inOutAble.openDoor();}public void use2(InOutAble inOutAble) {inOutAble.popGoods();}public void use3(InOutAble inOutAble) {inOutAble.writePeopleName();}
}/*** 存取东西的接口*/
interface InOutAble {// 类型1void openDoor(); // 打开门// 类型2void pushGoods(); // 放入货物void writeGoodsName(); // 登记货物名字// 类型3void popGoods(); // 取出货物void writePeopleName(); // 登记取货人的名字
}class InOutAbleImpl1 implements InOutAble {@Overridepublic void openDoor() {System.out.println("InOutAbleImpl1 - openDoor");}@Overridepublic void pushGoods() {System.out.println("InOutAbleImpl1 - pushGoods");}@Overridepublic void writeGoodsName() {System.out.println("InOutAbleImpl1 - writeGoodsName");}@Overridepublic void popGoods() {System.out.println("InOutAbleImpl1 - popGoods");}@Overridepublic void writePeopleName() {System.out.println("InOutAbleImpl1 - writePeopleName");}
}class InOutAbleImpl2 implements InOutAble {@Overridepublic void openDoor() {System.out.println("InOutAbleImpl2 - openDoor");}@Overridepublic void pushGoods() {System.out.println("InOutAbleImpl2 - pushGoods");}@Overridepublic void writeGoodsName() {System.out.println("InOutAbleImpl2 - writeGoodsName");}@Overridepublic void popGoods() {System.out.println("InOutAbleImpl2 - popGoods");}@Overridepublic void writePeopleName() {System.out.println("InOutAbleImpl2 - writePeopleName");}
}

在这里插入图片描述


在这里插入图片描述

public class InterfaceSegregation {public static void main(String[] args) {OpenPushImpl impl1 = new OpenPushImpl();OpenPopImpl impl2 = new OpenPopImpl();Cat cat = new Cat();cat.use1(impl1);cat.use2(impl1);cat.use3(impl1);Dog dog = new Dog();dog.use1(impl2);dog.use2(impl2);dog.use3(impl2);}
}class Cat {public void use1(OpenPushImpl openPushImpl) {openPushImpl.openDoor();}public void use2(OpenPushImpl openPushImpl) {openPushImpl.pushGoods();}public void use3(OpenPushImpl openPushImpl) {openPushImpl.writeGoodsName();}
}class Dog {public void use1(OpenPopImpl openPopImpl) {openPopImpl.openDoor();}public void use2(OpenPopImpl openPopImpl) {openPopImpl.popGoods();}public void use3(OpenPopImpl openPopImpl) {openPopImpl.writePeopleName();}
}interface OpenDoorAble {void openDoor(); // 打开门
}interface PushAble {void pushGoods(); // 放入货物void writeGoodsName(); // 登记货物名字
}interface PopAble {void popGoods(); // 取出货物void writePeopleName(); // 登记取货人的名字
}class OpenPushImpl implements OpenDoorAble, PushAble {@Overridepublic void openDoor() {System.out.println("OpenPushImpl - openDoor");}@Overridepublic void pushGoods() {System.out.println("OpenPushImpl - pushGoods");}@Overridepublic void writeGoodsName() {System.out.println("OpenPushImpl - writeGoodsName");}
}class OpenPopImpl implements OpenDoorAble, PopAble {@Overridepublic void openDoor() {System.out.println("OpenPopImpl - openDoor");}@Overridepublic void popGoods() {System.out.println("OpenPopImpl - popGoods");}@Overridepublic void writePeopleName() {System.out.println("OpenPopImpl - writePeopleName");}
}

三、依赖倒置(倒转)

🍬 ① 高层模块不应该依赖低层模块(类),二者都应该依赖于抽象(接口)
🍬 ② 抽象(接口)不应该依赖细节(实现类),而是细节依赖于抽象
🍬 ③ 依赖倒置的中心思想是:面向接口(抽象)编程
🍬 ④ 依赖倒置设计理念:相对于细节的多变性,抽象的东西要稳定得多。以抽象为基础搭建的架构比以细节为基础搭建的架构要稳定
🍬 ⑤ 使用接口或抽象类的作用是:制定规范(协议);把展现细节的任务交给接口的实现类

接口 ➡️ 抽象
实现类 ➡️ 细节

public class DependencyInversion {public static void main(String[] args) {Person person = new Person();person.sendMessage(new QQMessage("用QQ问候一下小明"));person.sendMessage(new WechatMessage("用微信问候一下小明"));}
}class Person {public void sendMessage(QQMessage qqMessage) {System.out.println(qqMessage.buildMessage());}public void sendMessage(WechatMessage wechatMessage) {System.out.println(wechatMessage.buildMessage());} 
}class QQMessage {private String message;public QQMessage(String message) {this.message = message;}public String buildMessage() {return "QQ Message: " + message;}
}class WechatMessage {private String message;public WechatMessage(String message) {this.message = message;}public String buildMessage() {return "Wechat Message: " + message;}
} 

在这里插入图片描述
在这里插入图片描述

😰 假如版本升级,还想发送 抖音消息 的话:① 需要创建一个 TiktokMessage 类;② 需要在 Person 类中再重载一个 sendMessage(TiktokMessage tiktokMessage) 方法
😰 每次版本升级,增加新的发送消息的方式的时候对代码的改动非常大。假如不止一个用户(不仅仅只有 Person 类),哪改动就更加巨大了


面向接口编程:

在这里插入图片描述

public class DependencyInversion {public static void main(String[] args) {Person person = new Person();person.sendMessage(new QQMessage("用QQ问候一下小明"));person.sendMessage(new WechatMessage("用微信问候一下小明"));}
}class Person {public void sendMessage(IMessage iMessage) {System.out.println(iMessage.buildMessage());}
}interface IMessage {String buildMessage();
}/*** 发送 QQ 消息*/
class QQMessage implements IMessage {private String message;public QQMessage(String message) {this.message = message;}@Overridepublic String buildMessage() {return "QQ Message: " + message;}
}/*** 发送微信消息*/
class WechatMessage implements IMessage {private String message;public WechatMessage(String message) {this.message = message;}public String buildMessage() {return "Wechat Message: " + message;}
}

四、里氏替换

继承优点: 🍬 提高代码的复用性(子类继承父类后可使用父类的非 private 关键字修饰的的成员)

public class Animal {public void eat() {System.out.println("Animal - public void eat()");}protected void drink() {System.out.println("Animal - protected void drink()");}void play() {System.out.println("Animal - void play()");}
}class Dragon extends Animal {public void use() {eat(); // Animal - public void eat()drink(); // Animal - protected void drink()play(); // Animal - void play()}public static void main(String[] args) {Dragon dragon = new Dragon();dragon.use();}
}

继承缺点: 🍬 ① 继承关系过去庞大的话,整个代码结构会很乱
🍬 ② 代码耦合性变高
🍬 ③ 代码稳定性变差(子类可以重写父类的方法。重写之后,运行时究竟调用的是父类的方法还是子类重写的方法很难判断)
🍬 ④ 如果有多处直接使用父类方法的实现,但凡父类方法修改了,所有依赖该父类方法的地方都得考虑兼容性(考虑代码是否会产生 bug)


(1) 子类可以实现父类的抽象方法,【不要覆盖父类的非抽象方法】 (2) 子类可以可以增加自己特有的实现,不要影响父类的非抽象方法【你用父类的可以,但不要改】 (3) 子类方法重载父类方法的时候,方法的形参要比父类方法的形参更宽松(父类方法的形参得是子类方法的形参的父类型)
public class Main {public static void main(String[] args) {Parent parent = new Parent();parent.m2(new ArrayList<>());Son son = new Son();son.m2(new ArrayList<>());/*Parent - m2(ArrayList<String>)Parent - m2(ArrayList<String>)*/}
}class Parent {public void m1() {System.out.println("Parent - m1()");}public void m2(ArrayList<String> list) {System.out.println("Parent - m2(ArrayList<String>)");}
}class Son extends Parent {// 不符合里氏替换原则(子类不应该重写父类的非抽象方法)@Overridepublic void m1() {System.out.println("Son - m1()");}// 子类重载父类的方法(子类重载的方法的参数类型要比父类被重载的方法的参数类型大)// 这样才符合里氏替换原则, 子类增加代码(如新增一个方法)不会影响父类方法的使用public void m2(List<String> list) {System.out.println("Son - m2(List<String>)");}
}
(4) 子类实现父类的抽象方法的时候,方法的返回值应比父类的更加严格

五、迪米特法则(Law of Demeter)

🍬 只与你的直接朋友交谈,不与陌生人交谈【降低类与类之间的耦合】

A ➡️ B ➡️ C
① A 和 B 是直接朋友
② B 和 C 是直接朋友
③ A 和 C 是陌生人
④ 若 A 想使用 C 中的方法,需要通过 B

🍬 直接朋友:
① 当前对象本身
② 当前对象的成员变量
③ 当前对象的成员方法的返回类型
④ 当前对象的成员方法的参数

class Parent {public void m() {// 在方法内部 new 出来的是非直接朋友User user = new User();}
} class User {}

六、开闭

🎄 Open Close Principe:软件对象(类、模块、方法等)应该对扩展开放,对修改关闭
🎄 用抽象构建框架,用实现扩展细节
🎄 开放 服务方 的拓展,关闭 消费方 的修改


public class OpenClosePrincipe {public static void main(String[] args) {// 对消费方的修改关闭// 尽量少修改原先的代码MilkTeaFactory factory = new MilkTeaFactory();factory.makeMilkTea(MilkTeaType.APPLE);factory.makeMilkTea(MilkTeaType.BANANA);}
}interface MilkTeaAble {}class AppleMilkTea implements MilkTeaAble {public AppleMilkTea() {System.out.println("苹果奶茶");}
}class BananaMilkTea implements MilkTeaAble {public BananaMilkTea() {System.out.println("香蕉奶茶");}
}enum MilkTeaType {APPLE, BANANA
}class MilkTeaFactory {public MilkTeaAble makeMilkTea(MilkTeaType type) {switch (type) {case APPLE:return new AppleMilkTea();case BANANA:return new BananaMilkTea();}return null;}
}

public class OpenClosePrincipe {// 修改依赖的类型(消费方代码没有修改)private static MilkTeaAble factory = new WatermelonMilkTeaFactory();public static void main(String[] args) {factory.milkTea();}
}interface MilkTeaAble {void milkTea();
}class AppleMilkTeaFactory implements MilkTeaAble {@Overridepublic void milkTea() {System.out.println("苹果奶茶");}
}class BananaMilkTeaFactory implements MilkTeaAble {@Overridepublic void milkTea() {System.out.println("香蕉奶茶");}
}class WatermelonMilkTeaFactory implements MilkTeaAble {@Overridepublic void milkTea() {System.out.println("西瓜奶茶");}
}

七、合成复用

📖 通过对象 组合、聚合、依赖 达成代码复用,而不是继承

class Animal {public void eat() {System.out.println("Animal - eat()");}public void drink() {System.out.println("Animal - drink()");}public void play() {System.out.println("Animal - play()");}
}/*** 继承(不推荐, 不符合合成复用原则)*/
class People1 extends Animal {public void use() {eat();drink();play();}
}/*** 依赖(推荐)*/
class People2 {public void use(Animal animal) {animal.eat();animal.drink();animal.play();}
}/*** 聚合(推荐)*/
class People3 {private Animal animal;public void setAnimal(Animal animal) {this.animal = animal;}public void use() {animal.eat();animal.drink();animal.play();}
}/*** 组合(推荐)*/
class People4 {private Animal animal = new Animal();public void use() {animal.eat();animal.drink();animal.play();}
}

相关文章:

【设计模式】1、设计模式七大原则

目录一、单一职责二、接口隔离三、依赖倒置&#xff08;倒转&#xff09;四、里氏替换五、迪米特法则&#xff08;Law of Demeter&#xff09;六、开闭七、合成复用一、单一职责 类&#xff08;或方法&#xff09;功能的专一性。一个类&#xff08;或方法&#xff09;不应该承担…...

【前端老赵的CSS简明教程】10-1 CSS预处理器和使用方法

大家好,欢迎来到本期前端课程。我是前端老赵,今天的课程将讲解CSS预处理器的概念和使用方法,希望能够帮助大家更好地进行前端开发。 CSS预处理器是什么? CSS预处理器是一种将类似CSS的语言转换为CSS的工具。它们提供了许多额外的功能,如变量、嵌套、混入、函数等等。这些…...

BFC详解

1. 引言 在前端的布局手段中&#xff0c;一直有这么一个知识点&#xff0c;很多前端开发者都知道有它的存在&#xff0c;但是很多人也仅仅是知道它的存在而已&#xff0c;对它的作用也只是将将说得出来&#xff0c;可是却没办法说得非常的清晰。这个知识点&#xff0c;就是BFC…...

C++:哈希结构(内含unordered_set和unordered_map实现)

unordered系列关联式容器 在C98中&#xff0c;STL提供了底层为红黑树结构的一系列关联式容器&#xff0c;在查询时效率可达到$log_2 N$&#xff0c;即最差情况下需要比较红黑树的高度次&#xff0c;当树中的节点非常多时&#xff0c;查询效率也不理想。最好 的查询是&#xff…...

Java实现调用第三方相关接口(附详细思路)

目录1.0.简单版2.0.升级版2-1.call.timeout()怎么传入新的超时值2-2.timeout(10, TimeUnit.SECONDS)两个参数的意思&#xff0c;具体含义3.0.进阶版3-1.java.net.SocketTimeoutException: 超时如何解决4.0.终极版1.0.简单版 以下是一个使用 Java 实际请求“第三方”的简单示例代…...

基础数据结构:单链表

今天懒洋洋学习了关于基础数据结构有关单链表的相关操作&#xff0c;懒洋洋来这温习一下。一:单链表的定义链表定义&#xff1a;用链式存储的线性表统称为链表&#xff0c;即逻辑结构上连续&#xff0c;物理结构上不连续。链表分类&#xff1a;单链表、双链表、循环链表、静态链…...

基于51单片机的智能计算器Protues仿真设计

目录 一、设计背景 二、实现功能 三、硬件设计 3.1 总体硬件设计 ​3.2 键盘电路的设计 3.3 显示电路的设计 四、仿真演示 五、源程序 一、设计背景 随着社会的发展&#xff0c;科学的进步&#xff0c;人们的生活水平在逐步的提高&#xff0c;尤其是微电子技术的发展&am…...

Pandas数据分析实战练习

Pandas数据分析实战练习 文章目录 Pandas数据分析实战练习一、读取Excel文件中的数据1、读取工号、姓名、时段、交易额这四列数据,使用默认索引,输出前10行数据2、读取第一个worksheet中所有列,跳过第1、3、5行,指定下标为1的列中数据为DataFrame的行索引标签二、筛选符合特…...

C++ 继承下(二篇文章学习继承所有知识点)

5.继承与友元友元关系不能继承&#xff0c;也就是说基类友元不能访问子类私有和保护成员 //验证友元不能继承 class B {friend void Print(); public:B(int b): _b(b){cout << "B()" << endl;}protected:int _b; };class D : public B { public:D(int b,…...

【C++】C++11新特性——类的改进|lambda表达式

文章目录一、类的改进1.1 默认生成1.2 移动构造函数1.3 移动赋值重载函数1.4 成员变量缺省值1.5 强制生成默认函数的关键字default1.6 禁止生成默认函数的关键字delete1.6.1 C98防拷贝1.6.1 C11防拷贝二、lambda表达式2.1 对比2.2 lambda表达式语法2.3 捕捉列表2.4 函数对象与l…...

C语言进阶(37) | 程序环境和预处理

目录 1.程序的翻译环境和执行环境 2.详解编译链接 2.1 翻译环境 2.2 编译本身也分为几个阶段: 2.3 运行环境 3.预处理详解 3.1预定符号 3.2 #define 3.3 #undef 3.4 命令行定义 3.5 条件编译 3.6 文件包含 了解重点&#xff1a; 程序的翻译环境程序的执行环境详解: C语言程…...

Golang每日一练(leetDay0005)

目录 13. 罗马数字转整数 Roman to Integer ★ 14. 最长公共前缀 Longest Common Prefix ★ 15. 三数之和 3Sum ★★★ &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日一练 专栏 13. 罗马数字转…...

occt_modeling_data(一)——拓扑

下面是我基于opencascade英文文档中关于occt_modeling_data中Topology部分进行的翻译&#xff0c;英文好的还是建议直接看文档&#xff0c;部分我不肯定的地方我会附上英文原句。如发现有错误欢迎评论区留言。 OCCT Topolog允许用户访问和操纵物体的数据&#xff0c;且不需要处…...

【AcWing】蓝桥杯备赛-深度优先搜索-dfs(3)

目录 写在前面&#xff1a; 题目&#xff1a;93. 递归实现组合型枚举 - AcWing题库 读题&#xff1a; 输入格式&#xff1a; 输出格式&#xff1a; 数据范围&#xff1a; 输入样例&#xff1a; 输出样例&#xff1a; 解题思路&#xff1a; 代码&#xff1a; AC &…...

宇宙最强-GPT-4 横空出世:最先进、更安全、更有用

文章目录前言一、准确性提升1.创造力2.视觉输入3.更长的上下文二、相比于ChatGPT有哪些提升1.GPT-4 的高级推理能力超越了 ChatGPT2.GPT-4 在多种测试考试中均优于 ChatGPT。三、研究团队在GPT-4模型都做了哪些改善1.遵循 GPT、GPT-2 和 GPT-3 的研究路径2.我们花了 6 个月的时…...

HashMap的实际开发使用

目 录 前言 一、HashMap是什么&#xff1f; 二、使用步骤 1.解析一下它实现的原理 ​编辑 2.实际开发使用 总结 前言 本章&#xff0c;只是大概记录一下hashMap的简单使用方法&#xff0c;以及理清一下hashMap的put方法的原理&#xff0c;以及get方法的原理。 一、Has…...

OpenCV入门(十三)快速学会OpenCV 12 图像梯度

OpenCV入门&#xff08;十三&#xff09;快速学会OpenCV 12 图像梯度1.Sobel算子1.1 计算x1.2 计算y1.3 计算xy2.Scharr算子2.1 计算x2.2 计算y2.3 计算xy3.Laplacian算子4.总结图像梯度计算的是图像变化的速度。对于图像的边缘部分&#xff0c;其灰度值变化较大&#xff0c;梯…...

软考:常见小题目计算题

01采购合同的类型采购合同主要包括总价类合同、成本补偿类合同、工料合同三大类合同。1、总价类合同此类合同为既定产品、服务或成果的采购设定一个总价。这种合同应在已明确定义需求&#xff0c;且不会出现重大范围变更的情况下使用。包括&#xff1a;&#xff08;1&#xff0…...

【Linux】进程的程序替换

文章目录1. 程序替换1.创建子进程的目的是什么&#xff1f;2.了解程序是如何进行替换的3. 程序替换的基本原理当创建进程的时候&#xff0c;先有进程数据结构&#xff0c;还是先加载代码和数据&#xff1f;程序替换是整体替换&#xff0c;不是局部替换execl 返回值4. 替换函数1…...

【C++】模板(上)

文章目录1、泛型编程2、函数模板函数模板的实例化模板参数的匹配原则3、 类模板类模板的实例化1、泛型编程 void Swap(int& left, int& right) {int temp left;left right;right temp; } void Swap(double& left, double& right) {double temp left;left …...

深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录

ASP.NET Core 是一个跨平台的开源框架&#xff0c;用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录&#xff0c;以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》

引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解

【关注我&#xff0c;后续持续新增专题博文&#xff0c;谢谢&#xff01;&#xff01;&#xff01;】 上一篇我们讲了&#xff1a; 这一篇我们开始讲&#xff1a; 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下&#xff1a; 一、场景操作步骤 操作步…...

Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)

目录 1.TCP的连接管理机制&#xff08;1&#xff09;三次握手①握手过程②对握手过程的理解 &#xff08;2&#xff09;四次挥手&#xff08;3&#xff09;握手和挥手的触发&#xff08;4&#xff09;状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...

(二)原型模式

原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...

大模型多显卡多服务器并行计算方法与实践指南

一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...

服务器--宝塔命令

一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行&#xff01; sudo su - 1. CentOS 系统&#xff1a; yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...

HDFS分布式存储 zookeeper

hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架&#xff0c;允许使用简单的变成模型跨计算机对大型集群进行分布式处理&#xff08;1.海量的数据存储 2.海量数据的计算&#xff09;Hadoop核心组件 hdfs&#xff08;分布式文件存储系统&#xff09;&a…...

[大语言模型]在个人电脑上部署ollama 并进行管理,最后配置AI程序开发助手.

ollama官网: 下载 https://ollama.com/ 安装 查看可以使用的模型 https://ollama.com/search 例如 https://ollama.com/library/deepseek-r1/tags # deepseek-r1:7bollama pull deepseek-r1:7b改token数量为409622 16384 ollama命令说明 ollama serve #&#xff1a…...

华为OD机试-最短木板长度-二分法(A卷,100分)

此题是一个最大化最小值的典型例题&#xff0c; 因为搜索范围是有界的&#xff0c;上界最大木板长度补充的全部木料长度&#xff0c;下界最小木板长度&#xff1b; 即left0,right10^6; 我们可以设置一个候选值x(mid)&#xff0c;将木板的长度全部都补充到x&#xff0c;如果成功…...