通过Demo案例的形式弄懂Java中的设计模式

本文通过Java代码的形式手写设计模式案例,包含多个设计模式,例如常见的责任链模式,单例模式,工厂模式,模板模式,策略模式等,让你能轻松学懂设计模式以及能够手写出来


工厂模式

什么是工厂模式

我们通过工厂来创建我们的对象

我们工厂模式其实分起来也就两种

工厂方法就是一个工厂对应一个商品

抽象工厂就是一个工厂可以对应多种商品

我们把生产商品的具体细节,写到我们的工厂类中,我们使用的时候直接在方法里面new一个工厂使用对象就好了


流程介绍

我们要有产品,而我们的工厂是负责生产处我们的产品的,所以说生产产品的创建我们写到工厂类里面

我们使用工厂类,是为了得到工厂类里面创建的产品对象

工厂模式案例(抽象工厂)

定义产品接口
// 产品接口
interface Product {void use();
}

创建具体的产品类

我们有产品A和产品B

// 具体产品A
class ConcreteProductA implements Product {@Overridepublic void use() {System.out.println("Using Product A");}
}// 具体产品B
class ConcreteProductB implements Product {@Overridepublic void use() {System.out.println("Using Product B");}
}

创建工厂类

我们在工厂类里面,创建我们的产品对象

// 工厂类
class ProductFactory {public static Product createProduct(String type) {if (type.equals("A")) {return new ConcreteProductA();} else if (type.equals("B")) {return new ConcreteProductB();} else {throw new IllegalArgumentException("Unknown product type");}}
}

使用工厂类

使用工厂类,传一个参数我们来得到我们想要的产品对象

public class FactoryPatternExample {public static void main(String[] args) {// 使用工厂创建产品AProduct productA = ProductFactory.createProduct("A");productA.use();  // 输出: Using Product A// 使用工厂创建产品BProduct productB = ProductFactory.createProduct("B");productB.use();  // 输出: Using Product B}
}

适配器模式

什么是适配器模式

适配器模式通常用于将一个类的接口转换成客户端期望的另一个接口,使得原本不兼容的类可以一起工作

适配器模式的核心思想是:

  • 通过一个适配器类,将不兼容的接口转换为兼容的接口
  • 客户端代码只需要与目标接口交互,而不需要关心具体的实现细节
  • 这种模式非常适合在集成旧系统或第三方库时使用

ps:不要局限于接口or类,因为适配器模式是一个思想,可以适配接口or类


流程介绍

我们想要弄一个新的接口,但是这个新的接口要适配我们的旧的接口

可以理解成,通过适配器类让新的接口和旧的接口适配,从而实现我们调用新的接口可以使用旧接口里的东西,而不用直接调用旧接口


适配器模式案例

定义目标接口(也就是客户端需要的新接口)

Printer接口是我们要提供给我们客户端使用的接口

// 目标接口
interface Printer {void print(String document);
}

需要适配的类

LegactPrinter是我们的旧的类,我们要让他适配新的接口

// 旧的类
class LegacyPrinter {public void printDocument(String document) {System.out.println("Legacy Printer is printing: " + document);}
}

创建适配器类

我们的适配器类连接了我们要提供给客户端的接口Printer

同时也有一个对象,这个对象是我们的需要适配的类

然后我们在实现的接口方法里面,实现调用我们的旧的类的方法

这样子就实现了,我们可以在新的接口调用我们的旧的类的方法

// 适配器类
class PrinterAdapter implements Printer {private LegacyPrinter legacyPrinter;public PrinterAdapter(LegacyPrinter legacyPrinter) {this.legacyPrinter = legacyPrinter;}@Overridepublic void print(String document) {// 调用 LegacyPrinter 的方法legacyPrinter.printDocument(document);}
}

客户端代码(使用新接口)

我们把旧的类对象当道适配器接口实现类里面

这样子就能完成旧的类对象对新接口的适配了

public class AdapterPatternExample {public static void main(String[] args) {// 创建旧的 LegacyPrinter 对象LegacyPrinter legacyPrinter = new LegacyPrinter();// 创建适配器,将 LegacyPrinter 适配到 Printer 接口Printer printer = new PrinterAdapter(legacyPrinter);// 客户端通过 Printer 接口调用printer.print("Hello, Adapter Pattern!");}
}

观察者模式

什么是观察者模式

关注者可以收到状态变化通知

其实我感觉这个就类似于发布订阅

观察者模式的核心思想是:

  • 被观察者(Subject)维护一个观察者列表,并在状态变化时通知所有观察者。
  • 观察者(Observer)通过实现统一的接口,可以动态地注册或移除。
  • 这种模式非常适合实现事件处理系统、发布-订阅系统等场景

流程介绍

我们有被观察者类和观察者类,当我们的被观察者的XX发横变化时,我们要及时通知给我们的观察者让他们接收到反馈

假设我们有一个天气站,它可以监测温度变化。当温度变化时,需要通知多个显示设备(如手机显示、电视显示等)更新显示内容


观察者模式案例

定义观察者接口

定义观察者接口Observer

有一个update()更新温度方法

// 观察者接口
interface Observer {void update(int temperature);
}

定义被观察者接口

定义被观察者接口Subject

有三个方法

注册,移除和通知观察者

// 被观察者接口
interface Subject {void registerObserver(Observer observer);void removeObserver(Observer observer);void notifyObservers();
}

被观察者实现类

它连接了Subject接口,也就是被观察者接口,实现了里面的注册,移除和通知观察者方法

维护一个观察者列表List<Observer>

同时它有个自己的方法,设置温度并通知观察者setTemperature,里面调用了我们的通知

在温度变化时通知所有观察者,让观察者更新温度(也就是观察者的update()方法)

import java.util.ArrayList;
import java.util.List;// 具体的被观察者类
class WeatherStation implements Subject {private int temperature;private List<Observer> observers = new ArrayList<>();@Overridepublic void registerObserver(Observer observer) {observers.add(observer);}@Overridepublic void removeObserver(Observer observer) {observers.remove(observer);}@Overridepublic void notifyObservers() {for (Observer observer : observers) {observer.update(temperature);}}// 设置温度并通知观察者public void setTemperature(int temperature) {this.temperature = temperature;notifyObservers();}
}

观察者实现类

有通知手机更新温度的类PhoneDisplay

通知电视更新温度的类PhoneDisplay

他们都连接Observer观察者接口

// 具体的观察者类:手机显示
class PhoneDisplay implements Observer {@Overridepublic void update(int temperature) {System.out.println("Phone Display: Current temperature is " + temperature + "°C");}
}// 具体的观察者类:电视显示
class TVDisplay implements Observer {@Overridepublic void update(int temperature) {System.out.println("TV Display: Current temperature is " + temperature + "°C");}
}

客户端代码

我们注册我们的观察者,并更新温度

public class ObserverPatternExample {public static void main(String[] args) {// 创建被观察者对象WeatherStation weatherStation = new WeatherStation();// 创建观察者对象Observer phoneDisplay = new PhoneDisplay();Observer tvDisplay = new TVDisplay();// 注册观察者weatherStation.registerObserver(phoneDisplay);weatherStation.registerObserver(tvDisplay);// 模拟温度变化weatherStation.setTemperature(25);  // 通知所有观察者weatherStation.setTemperature(30);  // 通知所有观察者// 移除一个观察者weatherStation.removeObserver(tvDisplay);// 再次模拟温度变化weatherStation.setTemperature(35);  // 只通知 phoneDisplay}
}

代码运行结果

展示了我们的温度的变化,我们温度变化的时候,我们的观察者会及时接收然后做出行为

Phone Display: Current temperature is 25°C
TV Display: Current temperature is 25°C
Phone Display: Current temperature is 30°C
TV Display: Current temperature is 30°C
Phone Display: Current temperature is 35°C

装饰器模式

什么是装饰器模式

对现有的类进行包裹和封装

期望在不改变类对象以及类定义的情况下,为对象添加额外的功能

装饰器模式的核心思想是:

  • 动态扩展对象的功能,而无需修改原始类的代码。
  • 通过组合而非继承来实现功能的扩展。
  • 每个装饰器类都持有一个组件对象的引用,并可以在调用组件方法前后添加额外的行为

ps:其实就类似于动态地为对象添加功能,类似于代理模式实现代码增强


流程介绍

我们可以通过装饰器类,在代码运行中让原本的组件可以实现一些其他功能,动态进行修改

假设我们有一个简单的咖啡店系统,咖啡是基础组件,而调料(如牛奶、糖、巧克力等)是装饰器

我们可以通过装饰器模式动态地为咖啡添加调料,并计算总价格


装饰器模式Demo

定义组件接口
// 组件接口
interface Coffee {String getDescription();double getCost();
}
定义组件实现类
// 具体组件:基础咖啡
class SimpleCoffee implements Coffee {@Overridepublic String getDescription() {return "Simple Coffee";}@Overridepublic double getCost() {return 2.0;  // 基础咖啡的价格}
}
定义装饰器基类

我们连接Coffee组件接口

里面有我们的组件对象Coffee,我们针对他来进行修改

// 装饰器基类
abstract class CoffeeDecorator implements Coffee {protected Coffee decoratedCoffee;public CoffeeDecorator(Coffee coffee) {this.decoratedCoffee = coffee;}@Overridepublic String getDescription() {return decoratedCoffee.getDescription();}@Overridepublic double getCost() {return decoratedCoffee.getCost();}
}

定义装饰器基类实现类

有两个装饰器

一个是牛奶MilkDecorato

一个是糖SugarDecorator

// 具体装饰器:牛奶
class MilkDecorator extends CoffeeDecorator {public MilkDecorator(Coffee coffee) {super(coffee);}@Overridepublic String getDescription() {return decoratedCoffee.getDescription() + ", Milk";}@Overridepublic double getCost() {return decoratedCoffee.getCost() + 0.5;  // 牛奶的价格}
}// 具体装饰器:糖
class SugarDecorator extends CoffeeDecorator {public SugarDecorator(Coffee coffee) {super(coffee);}@Overridepublic String getDescription() {return decoratedCoffee.getDescription() + ", Sugar";}@Overridepublic double getCost() {return decoratedCoffee.getCost() + 0.2;  // 糖的价格}
}

客户端代码
public class DecoratorPatternExample {public static void main(String[] args) {// 创建基础咖啡Coffee coffee = new SimpleCoffee();System.out.println(coffee.getDescription() + " - Cost: $" + coffee.getCost());// 添加牛奶装饰器coffee = new MilkDecorator(coffee);System.out.println(coffee.getDescription() + " - Cost: $" + coffee.getCost());// 添加糖装饰器coffee = new SugarDecorator(coffee);System.out.println(coffee.getDescription() + " - Cost: $" + coffee.getCost());// 再添加一次牛奶装饰器coffee = new MilkDecorator(coffee);System.out.println(coffee.getDescription() + " - Cost: $" + coffee.getCost());}
}

运行结果
Simple Coffee - Cost: $2.0
Simple Coffee, Milk - Cost: $2.5
Simple Coffee, Milk, Sugar - Cost: $2.7
Simple Coffee, Milk, Sugar, Milk - Cost: $3.2

策略模式

什么是策略模式

不影响客户端的情况下发生变化

简单来说,就是我们在一个接口中封装我们针对某些操作的多个方法

例如:针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使他们可以相互替换

针对一个业务多个不同的方法进行封装,EasyExcel业务举例子

1.获取具体导出数据

2.获取当前业务类型 getEnum(),我们的enum类里面会有这个类具体的模板编码,模板文件名称,存储路径

3.获取导出类的实体类类型

策略模式的核心思想是:

  • 将算法封装在独立的类中,使得它们可以互相替换。
  • 上下文类持有一个策略对象,并通过策略接口调用具体的算法。
  • 客户端可以动态地选择不同的策略,而不需要修改上下文类的代码

流程介绍

我们把针对某个操作的行为封装到一个接口中,我们使用这个接口中的方法来处理业务中的某些特定逻辑

针对不同的业务有不同的策略

假设我们有一个电商系统,需要根据不同的支付策略(如信用卡支付、支付宝支付、微信支付)来处理订单支付


策略模式Demo

这里简单点,我们的策略接口中只有一个pay()方法,但是我们可以对三个不同的业务使用

ps:一般策略模式都是多个方法的

定义策略接口

我们有一个pay()支付方法

// 策略接口
interface PaymentStrategy {void pay(int amount);
}

定义策略实现类

我们有三个不同的实现类

分别针对信用卡支付,支付宝支付和微信支付

// 具体策略:信用卡支付
class CreditCardPayment implements PaymentStrategy {private String cardNumber;private String expiryDate;public CreditCardPayment(String cardNumber, String expiryDate) {this.cardNumber = cardNumber;this.expiryDate = expiryDate;}@Overridepublic void pay(int amount) {System.out.println("Paid " + amount + " via Credit Card (Card Number: " + cardNumber + ", Expiry Date: " + expiryDate + ")");}
}// 具体策略:支付宝支付
class AlipayPayment implements PaymentStrategy {private String account;public AlipayPayment(String account) {this.account = account;}@Overridepublic void pay(int amount) {System.out.println("Paid " + amount + " via Alipay (Account: " + account + ")");}
}// 具体策略:微信支付
class WechatPayment implements PaymentStrategy {private String account;public WechatPayment(String account) {this.account = account;}@Overridepublic void pay(int amount) {System.out.println("Paid " + amount + " via Wechat Pay (Account: " + account + ")");}
}

定义一个上下文类(适配策略实现类)

我们有一个PaymentStrategy接口对象

当我们传不同的对象,例如银行卡,支付宝,微信时

他能自动转变适配过去

这样子我们就能实现一个上下文类就可以在业务逻辑中适配多个业务对象

// 上下文类
class PaymentContext {private PaymentStrategy paymentStrategy;public PaymentContext(PaymentStrategy paymentStrategy) {this.paymentStrategy = paymentStrategy;}public void executePayment(int amount) {paymentStrategy.pay(amount);}
}

客户端代码

一个上下文类就可以在业务逻辑中适配多个业务对象

public class StrategyPatternExample {public static void main(String[] args) {// 创建支付上下文,使用信用卡支付PaymentContext context = new PaymentContext(new CreditCardPayment("1234-5678-9012-3456", "12/25"));context.executePayment(100);  // 支付 100 元// 切换支付策略,使用支付宝支付context = new PaymentContext(new AlipayPayment("alice@alipay.com"));context.executePayment(200);  // 支付 200 元// 切换支付策略,使用微信支付context = new PaymentContext(new WechatPayment("bob@wechat.com"));context.executePayment(300);  // 支付 300 元}
}

运行结果
Paid 100 via Credit Card (Card Number: 1234-5678-9012-3456, Expiry Date: 12/25)
Paid 200 via Alipay (Account: alice@alipay.com)
Paid 300 via Wechat Pay (Account: bob@wechat.com)

模板模式

什么是模板模式

模板模式是一种行为设计模式,它定义了一个算法的框架,并将一些步骤的实现延迟到子类

模板模式使得子类可以在不改变算法结构的情况下重新定义算法的某些步骤

ps:

其实和策略模式差不多,只不过策略模式是在接口中定义多个方法然后实现类实现

而模板模式是在一个抽象类中一开始定义好一些不变的方法(被final修饰)和一些要由子类改写的抽象方法

模板模式的核心思想是:

  • 定义一个算法的框架,并将一些步骤的实现延迟到子类中。
  • 模板方法通常是 final 的,以防止子类修改算法的结构。
  • 具体步骤可以是抽象的(由子类实现),也可以是具体的(通用步骤)

流程介绍

我们要一开始就定义好我们的方法的调用顺序,我们的调用顺序不能改变,我们的子类只负责改变在调用顺序里使用到的方法

假设我们有一个制作饮料的系统,饮料的制作过程可以分为几个固定的步骤(如烧水、冲泡、倒入杯中、添加调料等),但每种饮料的具体实现可能不同


模板模式Demo

定义抽象类模板

我们定义好了一个一开始的算法模板

也就是我们的方法的调用顺序

// 抽象模板类
abstract class BeverageTemplate {// 模板方法:定义算法的框架public final void prepareBeverage() {boilWater();brew();pourInCup();addCondiments();}// 具体步骤:烧水(通用步骤)private void boilWater() {System.out.println("Boiling water...");}// 抽象步骤:冲泡(由子类实现)protected abstract void brew();// 具体步骤:倒入杯中(通用步骤)private void pourInCup() {System.out.println("Pouring into cup...");}// 抽象步骤:添加调料(由子类实现)protected abstract void addCondiments();
}

子类实现类

有一个冲咖啡的实现类Coffee

和一个冲茶的实现类Tea

// 具体子类:咖啡
class Coffee extends BeverageTemplate {@Overrideprotected void brew() {System.out.println("Brewing coffee grounds...");}@Overrideprotected void addCondiments() {System.out.println("Adding sugar and milk...");}
}// 具体子类:茶
class Tea extends BeverageTemplate {@Overrideprotected void brew() {System.out.println("Steeping the tea...");}@Overrideprotected void addCondiments() {System.out.println("Adding lemon...");}
}

客户端代码
public class TemplateMethodPatternExample {public static void main(String[] args) {// 制作咖啡System.out.println("Making Coffee:");BeverageTemplate coffee = new Coffee();coffee.prepareBeverage();System.out.println();// 制作茶System.out.println("Making Tea:");BeverageTemplate tea = new Tea();tea.prepareBeverage();}
}

运行结果
Making Coffee:
Boiling water...
Brewing coffee grounds...
Pouring into cup...
Adding sugar and milk...Making Tea:
Boiling water...
Steeping the tea...
Pouring into cup...
Adding lemon...

责任链模式

什么是责任链模式

让我们的一个请求,沿着一个链条从前往后进行处理

责任链模式的核心思想是:

  • 将多个处理者连成一条链,并沿着这条链传递请求,直到有对象处理它为止。
  • 每个处理者只处理自己能处理的请求,否则将请求传递给下一个处理者。
  • 责任链模式可以动态地调整链中的处理者顺序或增减处理者

流程介绍

我们弄多个业务处理逻辑,然后装配到一个链式结构中

让我们的请求能够根据这个链从前往后进行处理

假设我们有一个审批系统,员工提交报销申请后,需要经过多个层级的审批(如经理、总监、CEO)。每个审批者只能处理一定金额范围内的请求,如果超出范围,则将请求传递给下一个审批


责任链模式Demo

链式节点接口

我们的责任链的节点是Approver接口

里面有一个processRequest()处理业务逻辑的方法

一个setNextApprover(Approver nextApprover)进入下一个链处理业务逻辑的方法,传递的对象就是我们的接口本身

interface Approver {void processRequest(PurchaseRequest request);void setNextApprover(Approver nextApprover);
}

链式节点实现类

我们有总监,CEO,经理审批

当我们业务逻辑处理完后,我们就要进入链中的下一个节点进行业务处理

金额小于1000由经理来处理

金额小于5000由总监处理

金额小于10000由CEO处理

// 具体处理者:经理
class Manager implements Approver {private Approver nextApprover;@Overridepublic void processRequest(PurchaseRequest request) {if (request.getAmount() <= 1000) {System.out.println("Manager approves the request for $" + request.getAmount());} else if (nextApprover != null) {nextApprover.processRequest(request);}}@Overridepublic void setNextApprover(Approver nextApprover) {this.nextApprover = nextApprover;}
}// 具体处理者:总监
class Director implements Approver {private Approver nextApprover;@Overridepublic void processRequest(PurchaseRequest request) {if (request.getAmount() <= 5000) {System.out.println("Director approves the request for $" + request.getAmount());} else if (nextApprover != null) {nextApprover.processRequest(request);}}@Overridepublic void setNextApprover(Approver nextApprover) {this.nextApprover = nextApprover;}
}// 具体处理者:CEO
class CEO implements Approver {@Overridepublic void processRequest(PurchaseRequest request) {if (request.getAmount() <= 10000) {System.out.println("CEO approves the request for $" + request.getAmount());} else {System.out.println("Request for $" + request.getAmount() + " requires a board meeting!");}}@Overridepublic void setNextApprover(Approver nextApprover) {// CEO 是责任链的末端,没有下一个处理者}
}

定义请求类
// 请求类
class PurchaseRequest {private double amount;public PurchaseRequest(double amount) {this.amount = amount;}public double getAmount() {return amount;}
}

客户端代码

建立节点实现类

然后装配我们的责任链

然后我们的一个请求就能在我们的链中进行处理了

public class ChainOfResponsibilityPatternExample {public static void main(String[] args) {// 创建处理者Approver manager = new Manager();Approver director = new Director();Approver ceo = new CEO();// 设置责任链manager.setNextApprover(director);director.setNextApprover(ceo);// 创建请求PurchaseRequest request1 = new PurchaseRequest(800);PurchaseRequest request2 = new PurchaseRequest(4500);PurchaseRequest request3 = new PurchaseRequest(12000);// 处理请求manager.processRequest(request1);  // Manager 处理manager.processRequest(request2);  // Director 处理manager.processRequest(request3);  // CEO 处理}
}

单例模式

参考我以前的文章

手写单例模式-CSDN博客


代理模式

参考我以前的文章

通过代理模式理解Java注解的实现原理-CSDN博客


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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Django开发入门 – 0.Django基本介绍

Django开发入门 – 0.Django基本介绍 A Brief Introduction to django By JacksonML 1. Django简介 1) 什么是Django? 依据其官网的一段解释&#xff1a; Django is a high-level Python web framework that encourages rapid development and clean, pragmatic design. …

苍穹外卖-新增菜品(阿里云OSS文件上传mybatis主键返回批量保存口味表数据)

新增菜品 2.1 需求分析与设计 2.1.1 产品原型 后台系统中可以管理菜品信息&#xff0c;通过 新增功能来添加一个新的菜品&#xff0c;在添加菜品时需要选择当前菜品所属的菜品分类&#xff0c;并且需要上传菜品图片。 新增菜品原型&#xff1a; 当填写完表单信息, 点击&quo…

只需两步,使用ollama即可在本地部署DeepSeek等常见的AI大模型

只需两步&#xff0c;使用ollama即可在本地部署DeepSeek等常见的AI大模型 1.下载ollama,进入ollama官网即可将ollama下载到本地&#xff0c;之后按照提示安装ollama。 https://ollama.com/download/windows 2.安装大模型 进入ollama官网模型页面&#xff0c;找到所需的模型及版…

java基础语法中阶

一、面向对象 补充快捷键&#xff1a;alt鼠标左键&#xff0c;实现同时多行选中相同位置的内容。 1.类与对象 2.封装 3.构造方法 altinsert添加构造方法 4.内存分布 对象 类型 this关键字的使用 成员变量与局部变量 %s是占位符 ,ctrlaltv-补全对象 for循环的快速生成方…

DeepSeek 评价开源框架存在幻觉么?

DeepSeek 横空出世 2025 年&#xff0c;DeepSeek 以「价格屠夫」姿态将 API 成本降至新低&#xff08;输入 0.1 元/百万 tokens&#xff0c;输出 2 元/百万 tokens9&#xff09;霸榜了 AI 热搜。 AI 生成内容中最让人关注的就是回答内容是否存在 “幻觉”&#xff0c;我们不希望…

【大模型】硅基流动对接DeepSeek使用详解

目录 一、前言 二、硅基流动介绍 2.1 硅基流动平台介绍 2.1.1 平台是做什么的 2.2 主要特点与功能 2.2.1 适用场景 三、硅基流动快速使用 3.1 账户注册 3.2 token获取 3.2.1 获取token技巧 四、Cherry-Studio对接DeepSeek 4.1 获取 Cherry-Studio 4.2 Cherry-Stud…

DeepSeek之Win10系统部署教程

一、下载并安装Ollama 1、为什么要安装Ollama的呢&#xff1f; Ollama 是一个用于本地部署和管理大型语言模型&#xff08;LLM&#xff09;的工具&#xff0c;支持多种模型格式和框架。 它可以帮助用户轻松下载、配置和运行模型&#xff0c;同时提供统一的接口和依赖管理。 …

DeepSeek-r1和O1、O3mini谁更强?

DeepSeek-r1和O1、O3mini谁更强&#xff1f; 题目&#xff1a;编写一个 js 程序&#xff0c;显示一个球在旋转的六边形内弹跳。球应该受到重力和摩擦力的影响&#xff0c;并且必须逼真地从旋转的墙壁上弹起 DeepSeek-r1 <!DOCTYPE html> <html> <body> &l…

我用AI做数据分析之数据清洗

我用AI做数据分析之数据清洗 AI与数据分析的融合效果怎样&#xff1f; 这里描述自己在使用AI进行数据分析&#xff08;数据清洗&#xff09;过程中的几个小故事&#xff1a; 1. 变量名的翻译 有一个项目是某医生自己收集的数据&#xff0c;变量名使用的是中文&#xff0c;分…

如何搭建DeepSeek R1的训推环境?

本篇文章主要介绍基于Linux系统的Tesla A30 GPU的硬件环境搭建深度学习环境&#xff0c;为训练和推理DeepSeek R1 提供必要的环境&#xff0c;篇幅最后也会介绍到MIG的一些常见报错解决方案。 Anaconda安装 进入 https://www.anaconda.com/download/success 选择Linux安装包。…

模型压缩 --学习记录2

模型压缩 --学习记录2 如何找到更好的权衡方式(模型量化)方法一:寻找更好的 range方法二:寻找更好的 X-fp32(浮点数)方法三:寻找更好的 scale 和 zp方法四:寻找更好的 roundPTQ 后训练量化(离线量化)QAT 量化感知训练(在线量化)量化为什么会带来加速?三、模型稀疏技…

Unity3D仿星露谷物语开发28之切换场景

1、目标 Player可以在Scene1_Farm和Scene2_Field之间自动切换。通过Trigger实现该功能。同时创建一个预设体绑定该功能&#xff0c;这样可以把预设体放到任何场景中&#xff0c;通过配置即可实现Player在Scene之间的自由切换。 2、创建场景切换的工具对象 在Hierarchy中&…

Maven插件—flatten-maven-plugin:工程模块统一版本依赖

文章目录 前言一、认识flatten-maven-plugin插件二、如何使用flatten-maven-plugin插件&#xff1f;未使用flatten-maven-plugin插件之前的情况描述配置flatten-maven-plugin插件步骤1&#xff1a;最外层父模块安装插件&配置版本变量步骤2&#xff1a;各个自模块使用版本使…

并查集题目

并查集题目 聚合一块&#xff08;蓝桥&#xff09;合根植物&#xff08;蓝桥&#xff09;等式方程的可满足性省份数量 并查集&#xff08;Union-Find&#xff09;算法是一个专门针对「动态连通性」的算法。双方向的连通。 模板&#xff1a; class UF {// 连通分量个数private …

【玩转 Postman 接口测试与开发2_019】第15章:利用 Postman 初探 API 性能测试(含实战截图)

《API Testing and Development with Postman》最新第二版封面 文章目录 第十五章 API 接口性能测试1 性能负载的类型2 Postman 负载配置3 Postman 性能测试实战3.1 Fixed 型负载下的性能测试3.2 基于数据驱动的 Postman 接口性能测试 4 性能测试的注意事项 写在前面 终于来到了…

Linux(20)——调度作业

目录 一、调度延迟的用户作业&#xff1a; 1、延迟的用户作业&#xff1a; 2、查看延迟的用户作业&#xff1a; 3、从计划中删除作业&#xff1a; 二、调度周期性用户作业&#xff1a; 1、周期性用户作业&#xff1a; 2、调度周期性用户作业&#xff1a; 3、用户作业格…

在 Visual Studio Code 与微信开发者工具中调试使用 emscripten 基于 C 生成的 WASM 代码

最近在尝试将一些 C/C、Lua 项目挪到 Web 上跑, 接触到了 emscripten. 这里会介绍下在 Visual Studio Code 与微信开发者工具中调试使用 emscripten 基于 C 生成的 WASM 代码 (WebAssembly) 的一些方法. Emscripten 与 WebAssebmly WebAssembly 是一种新的编码方式, 可以在现代…

deepseek API开发简介

1、申请deepseek api key&#xff1a; https://platform.deepseek.com/api_keys创建API Key&#xff0c;并复制Key 2、安装python、pip&#xff0c;然后安装requests pip install requests3、.示例代码 import requests import json# DeepSeek API 地址 API_URL "ht…

uniapp开发微信小程序请求超时设置【亲测有效】

在Hbuilderx中 使用uniapp开发微信小程序时 封装请求方法 请求代码如下 function requestFun(app) {// get请求app.config.globalProperties._get function(path, data, success, fail, complete) {data data || {};data.token uni.getStorageSync(token) || ;uni.request…

【03】 区块链分布式网络

3-1 P2P网络 传统中心化网络由中央服务器保存全量数据。客户端之间无法直接连接&#xff0c;必须通过中央服务器作为桥梁。客户端必须和中央服务器建立连接后访问资源。客户端之间并无连通。 在P2P网络中通过将数据资源分散在网络各个节点中存储以及节点间交互连接&#xff0…