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

Java设计模式

Java设计模式

  • 一、观察者设计模式
    • 1.1 概述
    • 1.2 结构
    • 1.3 特点
      • 1. 优点
      • 2. 缺点
      • 3. 使用场景
    • 1.4 JDK中的实现
      • 1. Observable 类
      • 2. Observer 接口
      • 3. 例子
  • 二、模板设计模式
  • 三、单例设计模式
    • 一、懒汉式单例
    • 二、饿汉式单例
  • 四、Builder模式
    • 4.1 概述
    • 4.2 结构
    • 4.3 具体实现
    • 4.4 使用场景

一、观察者设计模式

1.1 概述

观察者模式(Observer Pattern),又称发布-订阅模式,是一种行为设计模式。它定义了一种一对多的依赖关系,允许多个观察者对象同时监听某个主题对象(Subject)。当主题对象的状态发生变化时,它会通知所有注册的观察者,以便这些观察者能够自动更新自身的状态。

1.2 结构

观察者模式通常包含以下角色:

  1. Subject(主题)
    • 抽象主题角色,负责维护观察者的列表。
    • 提供接口以添加和删除观察者。
    • 通常包括方法如 attach(observer)detach(observer)
  2. ConcreteSubject(具体主题)
    • 实现了 Subject 接口的具体类,维护有关状态。
    • 当状态变化时,调用通知方法以更新所有观察者。
  3. Observer(观察者)
    • 抽象观察者角色,定义更新接口,通常是 update() 方法。
    • 观察者在收到主题变化的通知时调用该方法更新自身状态。
  4. ConcreteObserver(具体观察者)
    • 实现 Observer 接口的具体类。
    • 在更新方法中实现如何响应主题变化。

例子:
在使用微信公众号时,大家都会有这样的体验,当你关注的公众号中有新内容更新的话,它就会推送给关注公众号的微信用户端。我们使用观察者模式来模拟这样的场景

  • 微信用户就是观察者
  • 微信公众号是被观察者
    有多个的微信用户关注了这个公众号。
    在这里插入图片描述
// 观察者接口
public interface Observer {void update(String message); // 接收更新消息
}// 主题接口
public interface Subject {void attach(Observer observer); // 添加观察者void detach(Observer observer); // 删除观察者void notifyObservers(String message); // 通知观察者更新消息
}// 具体主题类
import java.util.ArrayList;
import java.util.List;public class WeChatOfficialAccount implements Subject {private List<Observer> observers = new ArrayList<>(); // 观察者列表@Overridepublic void attach(Observer observer) {observers.add(observer);System.out.println(observer + " 关注了公众号。");}@Overridepublic void detach(Observer observer) {observers.remove(observer);System.out.println(observer + " 取消关注了公众号。");}@Overridepublic void notifyObservers(String message) {System.out.println("公众号发布新内容: " + message);for (Observer observer : observers) {observer.update(message);}}
}// 具体观察者类
public class WeChatUser implements Observer {private String name;public WeChatUser(String name) {this.name = name;}@Overridepublic void update(String message) {System.out.println(name + " 收到了新推送: " + message);}@Overridepublic String toString() {return name; // 方便打印}
}// 示例用法
public class WeChatObserverPattern {public static void main(String[] args) {// 创建公众号WeChatOfficialAccount wechatAccount = new WeChatOfficialAccount();// 创建微信用户WeChatUser user1 = new WeChatUser("用户A");WeChatUser user2 = new WeChatUser("用户B");WeChatUser user3 = new WeChatUser("用户C");// 用户关注公众号wechatAccount.attach(user1);wechatAccount.attach(user2);wechatAccount.attach(user3);// 发布新内容wechatAccount.notifyObservers("今天的天气真不错!");// 用户取消关注wechatAccount.detach(user2);// 再次发布新内容wechatAccount.notifyObservers("明天有一场特别活动!");}
}

1.3 特点

1. 优点

  • 降低了目标与观察者之间的耦合关系,两者之间是抽象耦合关系。
  • 被观察者发送通知,所有注册的观察者都会收到信息(可以实现广播机制)。

2. 缺点

  • 如果观察者非常多的话,那么所有的观察者收到被观察者发送的通知会耗时。
  • 如果被观察者有循环依赖的话,那么被观察者发送通知会使观察者循环调用,会导致系统崩溃。

3. 使用场景

  • 对象间存在一对多关系,一个对象的状态发生改变会影响其他对象。
  • 当一个抽象模型有两个方面,其中一个方面依赖于另一个方面时。

1.4 JDK中的实现

在Java中,通过iava.util. Observable类和java.util. observer接口定义了观察者模式,只要实现它们的子类就可以编写 观察者模式实例。

1. Observable 类

Observable 类是抽象目标类(被观察者),它有一个 Vector 集合成员变量,用于保存所有要通知的观察者对象。它的三个重要方法如下:

  • void addObserver(Observer o)
    用于将新的观察者对象添加到集合中。

  • void notifyObservers(Object arg)
    调用集合中的所有观察者对象的 update 方法,通知它们数据发生改变。通常,越晚加入集合的观察者越先得到通知。

  • void setChanged()
    用来设置一个 boolean 类型的内部标志,注明目标对象发生了变化。当它为 true 时,notifyObservers() 才会通知观察者。

2. Observer 接口

Observer 接口是抽象观察者,它监视目标对象的变化。当目标对象发生变化时,观察者会得到通知,并调用 update 方法进行相应的工作。

3. 例子

import java.util.Observable;
import java.util.Observer;// 具体的被观察者类
class WeatherData extends Observable {private float temperature;public void setTemperature(float temperature) {this.temperature = temperature;setChanged(); // 标记状态已更改notifyObservers(temperature); // 通知观察者}
}// 具体的观察者类
class CurrentConditionsDisplay implements Observer {private float temperature;@Overridepublic void update(Observable o, Object arg) {if (o instanceof WeatherData) {this.temperature = (float) arg; // 更新温度display(); // 显示当前条件}}public void display() {System.out.println("Current temperature: " + temperature + " degrees.");}
}// 主程序
public class WeatherStation {public static void main(String[] args) {WeatherData weatherData = new WeatherData();CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay();weatherData.addObserver(currentDisplay); // 注册观察者weatherData.setTemperature(25.5f); // 更新温度,触发通知weatherData.setTemperature(30.0f); // 再次更新温度}
}

二、模板设计模式

模板方法设计模式( Template Method Design Pattern ),在一个方法中定义一个算法骨架(即模板),并将某些步骤推迟到子类中实现
该模式在父类中定义一个方法的骨架(或算法的框架),并允许子类在不改变算法结构的情况下重新定义该算法的某些步骤。

举例:

  • 创建一个抽象类,定义算法骨架:
// 抽象类,定义制作饮料的模板方法
abstract class Beverage {// 模板方法,定义了制作饮料的通用步骤public final void prepareRecipe() {boilWater();brew();pourInCup();if (customerWantsCondiments()) { // 钩子方法,子类可以选择重写addCondiments();}}// 具体步骤:烧水private void boilWater() {System.out.println("Boiling water");}// 具体步骤:倒入杯中private void pourInCup() {System.out.println("Pouring into cup");}// 抽象步骤:冲泡饮料,具体实现由子类提供protected abstract void brew();// 抽象步骤:添加调料,具体实现由子类提供protected abstract void addCondiments();// 钩子方法:决定是否添加调料,子类可以选择重写protected boolean customerWantsCondiments() {return true; // 默认添加调料}
}
  • 创建具体的子类,实现抽象类中定义的抽象方法:
// 具体类:茶
class Tea extends Beverage {@Overrideprotected void brew() {System.out.println("Steeping the tea");}@Overrideprotected void addCondiments() {System.out.println("Adding lemon");}// 重写钩子方法,茶默认不添加调料@Overrideprotected boolean customerWantsCondiments() {return false;}
}
// 具体类:咖啡
class Coffee extends Beverage {@Overrideprotected void brew() {System.out.println("Dripping coffee through filter");}@Overrideprotected void addCondiments() {System.out.println("Adding sugar and milk");}
}
  • 客户端代码:
// 客户端代码
public class TemplateMethodPatternExample {public static void main(String[] args) {System.out.println("Preparing tea:");Beverage tea = new Tea();tea.prepareRecipe();System.out.println("\nPreparing coffee:");Beverage coffee = new Coffee();coffee.prepareRecipe();}
}
  • 输出:
Preparing tea:
Boiling water
Steeping the tea
Pouring into cupPreparing coffee:
Boiling water
Dripping coffee through filter
Pouring into cup
Adding sugar and milk
  • Beverage 抽象类定义了模板方法prepareRecipe,并封装了制作饮料的固定步骤
  • brew()addCondiments() 是由子类实现的抽象方法,各自实现了茶和咖啡的制作过程
  • 钩子方法 customerWantsCondiments()允许子类控制是否执行某个步骤

三、单例设计模式

单例模式有以下特点:

  1. 单例类只能有一个实例。
  2. 单例类必须自己创建自己的唯一实例。
  3. 单例类必须给所有其他对象提供这一实例。

一、懒汉式单例

在第一次访问时实例化自己

//懒汉式单例类.在第一次调用的时候实例化自己 
public class Singleton {private Singleton() {}private static Singleton single=null;//静态工厂方法 public static Singleton getInstance() {if (single == null) {  single = new Singleton();}  return single;}
}

Singleton通过将构造方法限定为private避免了类在外部被实例化,在同一个虚拟机范围内,Singleton的唯一实例只能通过getInstance()方法访问。

如果走到single == null时发生线程切换,会存在线程不安全的问题。

有三种方式确保懒汉式单例的线程安全问题:

  1. 在getInstance上加上同步:
public static synchronized Singleton getInstance() {if (single == null) {  single = new Singleton();}  return single;
}
  1. 双重检查锁定
public static Singleton getInstance() {if (singleton == null) {  synchronized (Singleton.class) {  if (singleton == null) {  singleton = new Singleton(); }  }  }  return singleton; 
}
  1. 静态内部类
public class Singleton {  private static class LazyHolder {  private static final Singleton INSTANCE = new Singleton();  }  private Singleton (){}  public static final Singleton getInstance() {  return LazyHolder.INSTANCE;  }  
}  
  • 静态内部类的特点
    • LazyHolder 是一个静态内部类,它只有在第一次被访问时才会被加载和初始化。
    • 类加载是线程安全的,JVM 在加载类时会确保类加载的线程安全性。
  • INSTANCE 的初始化
    • LazyHolder 内的 INSTANCE 是一个 static final 的变量,它在 LazyHolder 被加载时完成初始化。
    • static final 保证了 INSTANCE 的初始化只会发生一次,并且由 JVM 保证线程安全。
  • 特点:延迟加载,线程安全,利用类加载机制实现,推荐使用。

第三种比1、2好,即实现了线程安全,又避免了同步带来的性能影响

二、饿汉式单例

饿汉式在类创建的同时就已经创建好一个静态的对象供系统使用,以后不再改变,所以天生是线程安全的。

//饿汉式单例类.在类初始化时,已经自行实例化 
public class Singleton1 {private Singleton1() {}private static final Singleton1 single = new Singleton1();//静态工厂方法 public static Singleton1 getInstance() {return single;}
}
  • 特点:线程安全,类加载时初始化,简单实现,但可能会造成资源浪费。

四、Builder模式

4.1 概述

Builder 模式是一种创建型设计模式,通过逐步构建复杂对象,将对象的构建过程与表示分离,使得同样的构建过程可以创建不同的对象。

特点

  1. 将对象构建与其表示分离:
    • 构建复杂对象时,不直接实例化对象,而是使用 Builder 逐步设置属性,最后通过 build() 方法生成对象。
  2. 灵活性和可扩展性:
    • 新增属性或功能只需修改 Builder 类,而无需更改已有的构造代码。
  3. 链式调用:
    • Builder 模式允许链式设置属性,代码可读性更强。

4.2 结构

  1. 产品类(Product)
    • 要创建的复杂对象。
    • 包含多个属性,通常是不可变的。
  2. 构建器类(Builder)
    • 定义构建对象的步骤,每个步骤设置对象的一个属性。
    • 提供 build() 方法返回完整的产品对象。
  3. 具体构建器(ConcreteBuilder)
    • 实现构建器类,包含构建对象的具体逻辑。
  4. 指导者类(Director,可选)
    • 用于控制构建过程的顺序和逻辑。
    • 实际应用中常常省略,由客户端直接调用 Builder。

4.3 具体实现

比如我们现在要自定义一个http发送请求连接:

传统的方式(构造函数)

http对象代码为:

public class HttpRequest {private String url;private String method;private Map<String, String> headers;private String body;public HttpRequest(String url, String method, Map<String, String> headers, String body) {this.url = url;this.method = method;this.headers = headers != null ? headers : new HashMap<>();this.body = body;}@Overridepublic String toString() {return "HttpRequest { " +"url='" + url + '\'' +", method='" + method + '\'' +", headers=" + headers +", body='" + body + '\'' +" }";}
}

构建方式:

public class Main {public static void main(String[] args) {// 构建请求Map<String, String> headers = new HashMap<>();headers.put("Content-Type", "application/json");headers.put("Authorization", "Bearer token123");HttpRequest request = new HttpRequest("https://api.example.com/data", // URL"POST",                         // 方法headers,                        // Headers"{\"key\":\"value\"}"           // Body);System.out.println(request);}
}

问题分析

  • 构造器参数过多时,易混淆或出错,特别是可选参数场景。
  • 代码可读性差

传统方式(Set函数)
http对象代码:

public class HttpRequest {private String url;private String method;private Map<String, String> headers = new HashMap<>();private String body;public void setUrl(String url) {this.url = url;}public void setMethod(String method) {this.method = method;}public void setHeader(String key, String value) {this.headers.put(key, value);}public void setBody(String body) {this.body = body;}@Overridepublic String toString() {return "HttpRequest { " +"url='" + url + '\'' +", method='" + method + '\'' +", headers=" + headers +", body='" + body + '\'' +" }";}
}

构建方式:

public class Main {public static void main(String[] args) {// 构建请求HttpRequest request = new HttpRequest();request.setUrl("https://api.example.com/data");request.setMethod("POST");request.setHeader("Content-Type", "application/json");request.setHeader("Authorization", "Bearer token123");request.setBody("{\"key\":\"value\"}");System.out.println(request);}
}

问题分析

  • 缺点: 无法保证对象的完整性(可能遗漏某些关键参数),容易导致不一致的状态

为什么改用 Builder 模式

  • 参数过多且部分可选时,传统方式可读性差。
  • Builder 模式可以链式调用,代码更清晰。
  • Builder 可封装复杂的初始化逻辑,确保对象的一致性和不可变性。

改进后的builder:

  1. PRODUCT
public class HttpRequest {private String url;        // 必填private  String method;     // 必填private Map<String, String> headers; // 可选private String body;       // 可选// 私有构造器,确保只能通过 Builder 创建private HttpRequest(String url, String method, Map<String, String> headers, String body) {this.url = url;this.method = method;this.headers = headers;this.body = body;}// Getterspublic String getUrl() { return url; }public String getMethod() { return method; }public Map<String, String> getHeaders() { return headers; }public String getBody() { return body; }
}
  1. 构建器类(Builder)
public interface Builder {Builder setUrl(String url);Builder setMethod(String method);Builder addHeader(String key, String value);Builder setBody(String body);HttpRequest build();
}
  1. 具体构建器(ConcreteBuilder)
import java.util.HashMap;
import java.util.Map;public class HttpRequestBuilder implements Builder {private String url;private String method;private Map<String, String> headers = new HashMap<>();private String body;@Overridepublic Builder setUrl(String url) {this.url = url;return this;}@Overridepublic Builder setMethod(String method) {this.method = method;return this;}@Overridepublic Builder addHeader(String key, String value) {this.headers.put(key, value);return this;}@Overridepublic Builder setBody(String body) {this.body = body;return this;}@Overridepublic HttpRequest build() {// 校验必填参数if (url == null || method == null) {throw new IllegalStateException("URL and Method are required!");}return new HttpRequest(url, method, headers, body);}
}
  1. 指导者类(Director,可选)
public class HttpRequestDirector {private final Builder builder;public HttpRequestDirector(Builder builder) {this.builder = builder;}public HttpRequest constructGetRequest(String url) {return builder.setUrl(url).setMethod("GET").build();}public HttpRequest constructPostRequest(String url, String body) {return builder.setUrl(url).setMethod("POST").setBody(body).addHeader("Content-Type", "application/json").build();}
}
  1. 客户端代码
public class Main {public static void main(String[] args) {// 使用 Builder 直接构建HttpRequest request1 = new HttpRequestBuilder().setUrl("https://api.example.com/resource").setMethod("GET").addHeader("Authorization", "Bearer token123").build();System.out.println("Request1: " + request1.getUrl());// 使用 Director 构建HttpRequestDirector director = new HttpRequestDirector(new HttpRequestBuilder());HttpRequest request2 = director.constructPostRequest("https://api.example.com/resource", "{\"key\":\"value\"}");System.out.println("Request2: " + request2.getBody());}
}

Builder 的优势

  1. 强制性:
    • 必须设置关键参数(如 URL、method),否则无法创建对象。
  2. 校验性:
    • build() 方法集中校验,确保对象状态一致。
  3. 可读性:
    • 链式调用使代码更直观,避免参数顺序错误。

通过这种方式,Builder 模式能够显著提升代码的安全性和可靠性,避免遗漏关键参数的问题。

4.4 使用场景

  1. 参数多且部分可选的对象构建
    • 如配置类、网络请求对象(如 oKHttp)、数据库连接对象等。
  2. 不可变对象的构建
    • 需要在对象创建后禁止修改时,如 StringBuilderImmutable 对象。
  3. 复杂初始化逻辑的对象
    • 如需要组合多个子对象或处理复杂逻辑的初始化。
  4. 跨平台对象创建
    • 如需要动态生成 JSON、XML 等结构。
  5. 避免构造器参数过多
    • 如果构造器参数多且顺序容易搞混,Builder 模式可以显著改善代码可读性和安全性。

相关文章:

Java设计模式

Java设计模式 一、观察者设计模式1.1 概述1.2 结构1.3 特点1. 优点2. 缺点3. 使用场景 1.4 JDK中的实现1. Observable 类2. Observer 接口3. 例子 二、模板设计模式三、单例设计模式一、懒汉式单例二、饿汉式单例 四、Builder模式4.1 概述4.2 结构4.3 具体实现4.4 使用场景 一、…...

java 接口防抖

防抖&#xff1a;防止重复提交 在Web系统中&#xff0c;表单提交是一个非常常见的功能&#xff0c;如果不加控制&#xff0c;容易因为用户的误操作或网络延迟导致同一请求被发送多次&#xff0c;进而生成重复的数据记录。要针对用户的误操作&#xff0c;前端通常会实现按钮的l…...

[C++并发编程] 线程基础

线程发起 最简单的发起一个线程。 void thread_work(std::string str) {std::cout << "str: " << std << std::endl; } //初始化并启动一个线程 std::thread t1(thread, wangzn2016); 线程等待&#xff1a; 线程发起后&#xff0c;可能新的线…...

基于若依框架和Vue2 + Element-UI 实现图片上传组件的重写与优化

背景 在使用 若依分离版Element-UI 的图片上传组件时,需要根据业务需求进行定制化处理,比如: 需要传递额外的业务参数到后端需要对上传路径进行修改需要对上传组件进行样式定制 实现步骤 1. 创建本地组件 首先在业务模块下创建本地的图片上传组件: src/views/xxx/compone…...

自定义类型: 结构体、枚举 、联合

目录 结构体 结构体类型的声明 匿名结构体 结构的自引用 结构体变量的定义和初始化 结构体成员变量的访问 结构体内存对齐 结构体传参 位段 位段类型的声明 位段的内存分配 位段的跨平台问题 位段的应用 枚举 枚举类型的定义 枚举的优点 联合体(共用体) 联合…...

力扣98:验证二叉搜索树

给你一个二叉树的根节点 root &#xff0c;判断其是否是一个有效的二叉搜索树。 有效 二叉搜索树定义如下&#xff1a; 节点的左 子树 只包含 小于 当前节点的数。节点的右子树只包含 大于 当前节点的数。所有左子树和右子树自身必须也是二叉搜索树。 示例 1&#xff1a; 输入…...

Java Stream reduce 函数,聚合数据

Stream.reduce() 是 Stream 的一个聚合方法&#xff0c;它可以把一个 Stream 的所有元素按照自定义聚合逻辑&#xff0c;聚合成一个结果。 先看一个简单数字求和&#xff1a; public class Main {public static void main(String[] args&#xff09;{int sum Stream.of(1, 2…...

npm install -g@vue/cli报错解决:npm error code ENOENT npm error syscall open

这里写目录标题 报错信息1解决方案 报错信息2解决方案 报错信息1 使用npm install -gvue/cli时&#xff0c;发生报错&#xff0c;报错图片如下&#xff1a; 根据报错信息可以知道&#xff0c;缺少package.json文件。 解决方案 缺什么补什么&#xff0c;这里我们使用命令npm…...

阿里云服务器(centos7.6)部署前后端分离项目(MAC环境)

Jdk17安装部署 下载地址&#xff1a;https://www.oracle.com/java/technologies/downloads/ 选择自己需要的jdk版本进行下载。 通过mac终端scp命令上传下载好的jdk17到服务器的/usr/local目录下 scp -r Downloads/jdk-17.0.13_linux-x64_bin.tar.gz 用户名服务器ip地址:/us…...

【机器学习】机器学习基础

什么是机器学习&#xff1f; 机器学习&#xff08;Machine Learning, ML&#xff09;是一种人工智能&#xff08;AI&#xff09;的分支&#xff0c;指计算机通过数据学习规律并做出预测或决策&#xff0c;而无需明确编程。它的核心目标是让机器能够从经验中学习&#xff0c;逐…...

BUUCTF—Reverse—Java逆向解密(10)

程序员小张不小心弄丢了加密文件用的秘钥&#xff0c;已知还好小张曾经编写了一个秘钥验证算法&#xff0c;聪明的你能帮小张找到秘钥吗&#xff1f; 注意&#xff1a;得到的 flag 请包上 flag{} 提交 需要用专门的Java反编译软件:jd-gui 下载文件&#xff0c;发现是个class文…...

基于JSP+MySQL的网上招聘系统的设计与实现

摘要 在这样一个经济飞速发展的时代&#xff0c;人们的生存与生活问题已成为当代社会需要关注的一个焦点。对于一个刚刚 踏入社会的年轻人来说&#xff0c;他对就业市场和形势了解的不够详细&#xff0c;同时对自己的职业规划也很模糊&#xff0c;这就导致大量的 时间被花费在…...

js 中 file 文件 应用

文章目录 文件上传File 对象基本属性文件上传大文件上传文件格式校验通过 type 属性校验图片格式通过文件名扩展名校验 文件解析一、处理图片文件流&#xff08;以 Blob 格式接收文件流为例&#xff09;二、处理文本文件流三、处理 PDF 文件流&#xff08;借助 PDF.js 库来展示…...

Java 泛型详细解析

泛型的定义 泛型类的定义 下面定义了一个泛型类 Pair&#xff0c;它有一个泛型参数 T。 public class Pair<T> {private T start;private T end; }实际使用的时候就可以给这个 T 指定任何实际的类型&#xff0c;比如下面所示&#xff0c;就指定了实际类型为 LocalDate…...

「Mac畅玩鸿蒙与硬件33」UI互动应用篇10 - 数字猜谜游戏

本篇将带你实现一个简单的数字猜谜游戏。用户输入一个数字&#xff0c;应用会判断是否接近目标数字&#xff0c;并提供提示“高一点”或“低一点”&#xff0c;直到用户猜中目标数字。这个小游戏结合状态管理和用户交互&#xff0c;是一个入门级的互动应用示例。 关键词 UI互…...

自然语言处理期末试题汇总

建议自己做&#xff0c;写完再来对答案。答案可能存在极小部分错误&#xff0c;不保证一定正确。 一、选择题 1-10、C A D B D B C D A A 11-20、A A A C A B D B B A 21-30、B C C D D A C A C B 31-40、B B B C D A B B A A 41-50、B D B C A B B B B C 51-60、A D D …...

记录Threadlocal使用

编写ThreadLocal工具类 package com.jjking.jplan.context;public class BaseContext<T> {public static final ThreadLocal threadLocal new ThreadLocal();//存储用户public static void set(Object t) {threadLocal.set(t);}//获取用户public static <T> T ge…...

利用 SpringBoot 开发的新冠密接者跟踪系统:医疗机构疫情防控辅助方案

摘 要 信息数据从传统到当代&#xff0c;是一直在变革当中&#xff0c;突如其来的互联网让传统的信息管理看到了革命性的曙光&#xff0c;因为传统信息管理从时效性&#xff0c;还是安全性&#xff0c;还是可操作性等各个方面来讲&#xff0c;遇到了互联网时代才发现能补上自古…...

vue 2 父组件根据注册事件,控制相关按钮显隐

目标效果 我不注册事件&#xff0c;那么就不显示相关的按钮 注册了事件&#xff0c;才会显示相关内容 实现思路 组件在 mounted 的时候可以拿到父组件注册监听的方法 拿到这个就可以做事情了 mounted() {console.log(this.$listeners, this.$listeners);this.show.search !…...

【深度学习基础】一篇入门模型评估指标(分类篇)

&#x1f308; 个人主页&#xff1a;十二月的猫-CSDN博客 &#x1f525; 系列专栏&#xff1a; &#x1f3c0;深度学习_十二月的猫的博客-CSDN博客 &#x1f4aa;&#x1f3fb; 十二月的寒冬阻挡不了春天的脚步&#xff0c;十二点的黑夜遮蔽不住黎明的曙光 目录 1. 前言 2. 模…...

hls视频流学习

hls格式播放的依赖安装&#xff1a; <!-- 新增hls播放库 -->npm install hls.js 组件封装&#xff1a; <template><div class"hls-player-cls"><video ref" video" controls style"width: 100%; max-width: 800px;">…...

【electron-vite】搭建electron+vue3框架基础

一、拉取项目 electron-vite 中文文档地址&#xff1a; https://cn-evite.netlify.app/guide/ 官网网址&#xff1a;https://evite.netlify.app/ 版本 vue版本&#xff1a;vue3 构建工具&#xff1a;vite 框架类型&#xff1a;Electron JS语法&#xff1a;TypeScript &…...

第三方Express 路由和路由中间件

文章目录 1、Express 应用使用回调函数的参数&#xff1a; request 和 response 对象来处理请求和响应的数据。2、Express路由1.路由方法2.路由路径3.路由处理程序 3. 模块化路由4. Express中间件1.中间件简介2.中间件分类3.自定义中间件 1、Express 应用使用回调函数的参数&am…...

WPF 常用的5个布局容器控件介绍

1. Grid Grid 是最常用的布局容器之一&#xff0c;它允许开发者以表格的方式对控件进行组织和布局。Grid 使用行和列来划分区域&#xff0c;可以精确控制控件的位置和大小。 特点&#xff1a; 行列定义&#xff1a;Grid 使用 RowDefinitions 和 ColumnDefinitions 来定义行和…...

【JAVA] 杂谈: java中的拷贝(克隆方法)

这篇文章我们来介绍什么是拷贝&#xff0c;并且实现浅拷贝到深拷贝。 目录 一、浅拷贝 1.1 clone 方法 1.2 实现浅拷贝&#xff1a; 1.2.1 重写 clone方法 1.2.2 实现接口 Cloneable 1.2.3 调用克隆方法 1.2.4 原理图&#xff1a;​ 1.3 浅拷贝的不足 1.3.1 增加引用…...

同时多平台git配置:GitHub和Gitee生成不同的SSH Key

文章目录 GitHub和Gitee生成不同的SSH Key步骤1&#xff1a;生成SSH Key步骤2&#xff1a;配置SSH配置文件步骤3&#xff1a;查看SSH公钥步骤4&#xff1a;将SSH公钥添加到GitHub和Gitee步骤5&#xff1a;测试SSH连接步骤6&#xff1a;添加remote远程库 GitHub和Gitee生成不同的…...

flink1.6集成doris,并从mysql同步数据到doris

使用 Apache Flink 1.6 集成 Doris&#xff0c;并从 MySQL 同步数据到 Doris 是一个复杂的任务&#xff0c;但可以通过以下步骤实现。Doris 是一个现代化的 MPP&#xff08;大规模并行处理&#xff09;SQL 数据库&#xff0c;支持实时分析和交互式查询。Flink 可以作为实时数据…...

手搓一个不用中间件的分表策略

场景&#xff1a;针对一些特别的项目&#xff0c;不用中间件&#xff0c;以月为维度进行分表&#xff0c;代码详细设计方案 1. 定义分片策略 首先&#xff0c;定义一个分片策略类&#xff0c;用于决定数据存储在哪个分表中 import java.time.LocalDate; import java.time.fo…...

AI前景分析展望——GPTo1 SoraAI

引言 人工智能&#xff08;AI&#xff09;领域的飞速发展已不仅仅局限于学术研究&#xff0c;它已渗透到各个行业&#xff0c;影响着从生产制造到创意产业的方方面面。在这场技术革新的浪潮中&#xff0c;一些领先的AI模型&#xff0c;像Sora和OpenAI的O1&#xff0c;凭借其强大…...

损失函数Hinge Loss介绍

Hinge Loss 是一种损失函数,广泛用于 支持向量机(SVM, Support Vector Machine) 和一些分类问题中。它特别适合用于 二分类问题,主要目标是让模型的预测值(通常是经过线性变换的原始分数)与真实标签之间的间隔尽可能大,从而提高分类的鲁棒性。 Hinge Loss 的定义 Hinge…...

多维高斯分布(Multivariate Gaussian Distribution)以及协方差矩阵:解析与应用

多维高斯分布&#xff1a;全面解析及其应用 1. 什么是多维高斯分布&#xff1f; 多维高斯分布&#xff08;Multivariate Gaussian Distribution&#xff09;&#xff0c;也称多元正态分布&#xff0c;是高斯分布在高维空间中的推广。它描述了随机向量 ( x ( x 1 , x 2 , … ,…...

前端开发常用快捷键

浏览器 ctrl e 光标定位在搜索框ctrl r 刷新ctrl t 新打开tabctrl tab 向右切换tabctrl shift tab 向左切换tab vscode ctrl p 全局搜索文件ctrl f 当前文件搜索alt 光标左键向下拖动&#xff1a;竖向选中多行文本ctrl b 切换侧边栏显示隐藏ctrl shift p 显示命…...

用MATLAB符号工具建立机器人的动力学模型

目录 介绍代码功能演示拉格朗日方法回顾求解符号表达式数值求解 介绍 开发机器人过程中经常需要用牛顿-拉格朗日法建立机器人的动力学模型&#xff0c;表示为二阶微分方程组。本文以一个二杆系统为例&#xff0c;介绍如何用MATLAB符号工具得到微分方程表达式&#xff0c;只需要…...

全面解析 MySQL 常见问题的排查与解决方法

目录 前言1. 查看 MySQL 日志信息1.1 日志文件的种类与路径1.2 查看日志内容的方法1.3 日志分析的关键点 2. 查看 MySQL 服务状态2.1 查看服务状态2.2 检查进程运行情况2.3 常见启动失败问题与解决 3. 检查 MySQL 配置信息3.1 配置文件的路径与内容3.2 验证配置文件的正确性 4.…...

泷羽Sec-星河飞雪-BurpSuite之解码、日志、对比模块基础使用

免责声明 学习视频来自 B 站up主泷羽sec&#xff0c;如涉及侵权马上删除文章。 笔记的只是方便各位师傅学习知识&#xff0c;以下代码、网站只涉及学习内容&#xff0c;其他的都与本人无关&#xff0c;切莫逾越法律红线&#xff0c;否则后果自负。 泷羽sec官网&#xff1a;http…...

【小白学机器学习34】基础统计2种方法:用numpy的方法np().mean()等进行统计,pd.DataFrame.groupby() 分组统计

目录 1 用 numpy 快速求数组的各种统计量&#xff1a;mean, var, std 1.1 数据准备 1.2 直接用np的公式求解 1.3 注意问题 1.4 用print() 输出内容&#xff0c;显示效果 2 为了验证公式的背后的理解&#xff0c;下面是详细的展开公式的求法 2.1 均值mean的详细 2.2 方差…...

【C++】stack和queue

目录 1. stack的介绍和使用 1.1 stack的介绍 1.2 stack的使用 2. queue的介绍和使用 2.1 queue的介绍 2.2 queue的使用 3. 容器适配器 3.1 什么是适配器 3.2 STL标准库中stack和queue的底层结构 3.3 deque的简单介绍(了解) 3.3.1 deque的原理介绍 3.3.2 deque优势与…...

向量的内积和外积 为什么这样定义

向量的内积和外积 为什么这样定义 flyfish 定义、公理与证明的区别 定义&#xff1a; 定义是人为规定的&#xff0c;用于描述概念的含义。例如&#xff0c;内积和外积是根据实际需求定义的&#xff0c;目的是描述几何和代数性质。定义不需要证明。 公理&#xff1a; 公理是数…...

简述循环神经网络RNN

1.why RNN CNN&#xff1a;处理图像之间没有时间/先后关系 RNN&#xff1a;对于录像&#xff0c;图像之间也许有时间/先后顺序&#xff0c;此时使用CNN效果不会很好&#xff0c;同理和人类的语言相关的方面时间顺序就更为重要了 2.RNN和CNN之间的关联 RNN和CNN本质上其实一…...

【Electron学习笔记(四)】进程通信(IPC)

进程通信&#xff08;IPC&#xff09; 进程通信&#xff08;IPC&#xff09;前言正文1、渲染进程→主进程&#xff08;单向&#xff09;2、渲染进程⇌主进程&#xff08;双向&#xff09;3、主进程→渲染进程 进程通信&#xff08;IPC&#xff09; 前言 在Electron框架中&…...

APP自动化测试框架的开发

基于appium的APP自动化测试框架的开发流程概览 1. 环境搭建 安装Appium Server 下载与安装&#xff1a;可以从Appium官方网站&#xff08;Redirecting&#xff09;下载安装包。对于Windows系统&#xff0c;下载.exe文件后双击安装&#xff1b;对于Mac系统&#xff0c;下载.dmg…...

【深度学习】各种卷积—卷积、反卷积、空洞卷积、可分离卷积、分组卷积

在全连接神经网络中&#xff0c;每个神经元都和上一层的所有神经元彼此连接&#xff0c;这会导致网络的参数量非常大&#xff0c;难以实现复杂数据的处理。为了改善这种情况&#xff0c;卷积神经网络应运而生。 一、卷积 在信号处理中&#xff0c;卷积被定义为一个函数经过翻转…...

pytorch 融合 fuse 学习笔记

目录 fuse_lora 作用是什么 fuse_modules源码解读 fuse_lora 作用是什么 在深度学习模型微调场景下&#xff08;与 LoRA 相关&#xff09; 参数融合功能 在使用 LoRA&#xff08;Low - Rank Adaptation&#xff09;对预训练模型进行微调后&#xff0c;fuse_lora函数的主要作…...

41 基于单片机的小车行走加温湿度检测系统

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 基于51单片机&#xff0c;采样DHT11温湿度传感器检测温湿度&#xff0c;滑动变阻器连接数码转换器模拟电量采集传感器&#xff0c; 电机采样L298N驱动&#xff0c;各项参数通过LCD1602显示&#x…...

GitLab: You cannot create a branch with a SHA-1 or SHA-256 branch name

最近在迁移git库&#xff0c;把代码从gerrit迁移到gitlab&#xff0c;有几个库报错如下&#xff1a; GitLab: You cannot create a branch with a SHA-1 or SHA-256 branch name ! [remote rejected] refs/users/73/373/edit-95276/1 -> refs/users/73/373/edit-95276/1 (p…...

YOLOv9改进,YOLOv9引入TransNeXt中的ConvolutionalGLU模块,CVPR2024,二次创新RepNCSPELAN4结构

摘要 由于残差连接中的深度退化效应,许多依赖堆叠层进行信息交换的高效视觉Transformer模型往往无法形成足够的信息混合,导致视觉感知不自然。为了解决这个问题,作者提出了一种聚合注意力(Aggregated Attention),这是一种基于仿生设计的token混合器,模拟了生物的中央凹…...

TorchMoji使用教程/环境配置(2024)

TorchMoji使用教程/环境配置&#xff08;2024&#xff09; TorchMoji简介 这是一个基于pytorch库&#xff0c;用于将文本分类成不同的多种emoji表情的库&#xff0c;适用于文本的情感分析 配置流程 从Anaconda官网根据提示安装conda git拉取TorchMoji git clone https://gi…...

uniapp运行时,同步资源失败,未得到同步资源的授权,请停止运行后重新运行,并注意手机上的授权提示。

遇到自定义基座调试时安装无效或无反应&#xff1f;本文教你用 ADB 工具快速解决&#xff1a;打开 USB 调试&#xff0c;连接设备&#xff0c;找到应用包名&#xff0c;一键卸载问题包&#xff0c;清理干净后重新运行调试基座&#xff0c;轻松搞定&#xff01; 问题场景&#…...

uniapp中父组件调用子组件方法

实现过程&#xff08;setup语法糖形式下&#xff09; 在子组件完成方法逻辑&#xff0c;并封装。在子组件中使用defineExpose暴露子组件的该方法。在父组件完成子组件ref的绑定。通过ref调用子组件暴露的方法。 子组件示例 <template> </template><script se…...

腾讯云 AI 代码助手:单元测试应用实践

引言 在软件开发这一充满创造性的领域中&#xff0c;开发人员不仅要构建功能强大的软件&#xff0c;还要确保这些软件的稳定性和可靠性。然而&#xff0c;开发过程中并非所有任务都能激发创造力&#xff0c;有些甚至是重复且乏味的。其中&#xff0c;编写单元测试无疑是最令人…...