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

手撕四种常用设计模式(工厂,策略,代理,单例)

工厂模式

一、工厂模式的总体好处

  1. 解耦:客户端与具体实现类解耦,符合“开闭原则”。
  2. 统一创建:对象创建交由工厂处理,便于集中控制。
  3. 增强可维护性:新增对象种类时不需要大改动调用代码。
  4. 便于扩展:易于管理产品族或产品等级结构。、

手写静态工厂模式,通过一个汽车静态工厂负责创建汽车

特点:
  • 工厂类通过一个静态方法来返回不同的对象。
  • 客户端通过传入参数决定创建哪个类。
✅ 优点:
  • 实现简单,结构清晰。
  • 对客户端隐藏了对象的具体创建过程。
⚠️ 缺点:
  • 不符合开闭原则(新增产品需修改 createCar() 方法)。
  • 工厂职责过重,产品一多代码臃肿。
public class StaticFactoryModel {public static void main(String[] args){car car=new CarFactory.createCar("Tesla");
}
interface car{void drive();
}
class Tesla implements car{@Overridepublic void drive(){System.out.println("drive Tesla");}
}
class toyota implements car{@Overridepublic void drive(){System.out.println("drive toyota");}
}class CarFactory{public static car createCar(String type){switch(type){case"Tesla": return new Tesla();case"toyota":return new toyota();default:throw new IllegalArgumentException("UnKnow Car");}}
}

手写工厂方法模式

特点:
  • 将创建对象的工作延迟到子类,通过不同工厂子类创建不同对象。
✅ 优点:
  • 满足开闭原则,新增产品只需新增对应工厂。
  • 结构清晰,职责单一,每个工厂只负责一种产品的创建。
⚠️ 缺点:
  • 类的数量变多,增加系统复杂度。
  • 只能生产单一类型的产品。
package com;public class FactoryMethod {public static void main(String[] args) {phoneFactory factory=new iPhoneFactory();phone myphone=factory.createPhone();myphone.call();}
}interface phone{public void call();
}
class iPhone implements phone{@Overridepublic void call(){System.out.println("iPhone call");}
}
class Huawei implements phone{@Overridepublic void call(){System.out.println("Huawei call");}
}
interface phoneFactory{public phone createPhone();
}
class iPhoneFactory implements phoneFactory{@Overridepublic phone createPhone(){return new iPhone();}
}
class HuaweiFactory implements phoneFactory{@Overridepublic phone createPhone(){return new Huawei();}
}

手写抽象工厂模式

✅ 特点:
  • 一个工厂可以生产多个相关的产品(如电脑 + 操作系统)。
✅ 优点:
  • 更强的扩展能力,可以生产“产品族”(多个相关产品)。
  • 高度封装了产品的创建细节,对客户端透明。
⚠️ 缺点:
  • 不易新增“新产品”(比如新加一个 Printer 接口)需修改所有工厂。
  • 抽象程度更高,理解成本稍大。
package com;public class AbstractFactory {public static void main(String[] args){ShowFactory factory=new WinFactory();Computee myCom=factory.createCom();Os myOs=factory.createOs();}
}interface Computee{public void use();
}
interface Os{public void call();
}class hp implements  Computee{@Overridepublic void use() {System.out.println("useing window");}
}
class AppleCom implements  Computee{@Overridepublic void use() {System.out.println("using apple");}
}class window implements Os{@Overridepublic void call() {System.out.println("calling window");}
}
class AppleOS implements Os{@Overridepublic void call() {System.out.println("calling apple");}
}
interface ShowFactory{Computee createCom();Os createOs();
}
class WinFactory implements ShowFactory{@Overridepublic Computee createCom() {return new hp();}@Overridepublic Os createOs() {return new window();}
}
//..另外一个工厂对应行为

策略模式

策略模式

上下文负责生成具体的策略类并且负责与客户端交互

抽象策略类为抽象角色,通常由一个接口或者抽象类实现,给出所有的具体策略类需要的接口

具体策略类:是实现接口,提供具体算法或者行为

策略模式优点:

  • 算法解耦:将行为或算法封装在独立策略类中,便于切换和扩展。
  • 避免多重判断:通过多态替代 if-elseswitch,结构更清晰。
  • 符合开闭原则:新增策略时无需改动已有代码,只需增加新策略类。
  • 可复用性高:不同上下文可复用同一个策略类,提升代码复用率
package com;public class AbstractFactory {public static void main(String[] args){ShowFactory factory=new WinFactory();Computee myCom=factory.createCom();Os myOs=factory.createOs();}
}interface Computee{public void use();
}
interface Os{public void call();
}class hp implements  Computee{@Overridepublic void use() {System.out.println("useing window");}
}
class AppleCom implements  Computee{@Overridepublic void use() {System.out.println("using apple");}
}class window implements Os{@Overridepublic void call() {System.out.println("calling window");}
}
class AppleOS implements Os{@Overridepublic void call() {System.out.println("calling apple");}
}
interface ShowFactory{Computee createCom();Os createOs();
}
class WinFactory implements ShowFactory{@Overridepublic Computee createCom() {return new hp();}@Overridepublic Os createOs() {return new window();}
}
//..另外一个工厂对应行为

代理模式

代理模式(Proxy Pattern)是结构型设计模式的一种,
定义如下:

为其他对象提供一种代理以控制对这个对象的访问。

这里使用jdk代理实现代理模式

优点:

  • 增强功能:在不修改原始对象的情况下增加额外逻辑(如权限校验、日志、事务等)。
  • 解耦结构:将业务逻辑与通用功能分离,代码更清晰、职责更单一。
  • 灵活控制:可以在调用前后做一些处理,比如安全控制、延迟加载、访问控制等。
  • 支持动态扩展:通过 JDK 动态代理可根据接口生成代理对象,运行时更灵活。
package com;import java.awt.*;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;public class ProxyModel {
}interface UserDao{public void add();public void delete();
}
class UserDaoImpl implements UserDao{@Overridepublic void add() {System.out.println("adding");}@Overridepublic void delete() {System.out.println("deleteling");}
}
class UserProxy implements InvocationHandler{Object object;public UserProxy(Object obb){object=obb;}public Object getProxy(){return Proxy.newProxyInstance(object.getClass().getClassLoader(),object.getClass().getInterfaces(),this);}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("代理加强前");Object invoke = method.invoke(object, args);System.out.println("代理加强后");return invoke;}
}

单例模式

定义:

单例模式就是一个类只有一个实例,并且还提供这个实例的全局访问点(避免一个全局使用的类频繁创建和销毁,耗费系统资源)

设计要素

  • 一个私有的构造函数(确保只能由单例类自己创建实例)
  • 一个私有的静态变量(确保只有一个实例)
  • 一个公有的静态函数(给调用者提供调用方法)

单例类的构造方法不让其他人修改和使用;并且单例类自己只创建一个实例,这个实例,其他人也无法修改和直接使用;然后单例类提供一个调用方法,想用这个实例,只能调用。这样就确保了全局只创建了一次实例。

六种实现方式

懒汉式(线程不安全)

先不创建实例,当第一次被调用的时候再创建实例,延迟了实例化,不需要使用该类就不会实例化,节省了系统资源

线程不安全,如果多个线程同时进入了lazyd==null,此时如果还没有实例化,多个线程就会进行实例化,导致实例化了多个实例

package com;public class LazyD {private static LazyD lazyd;private LazyD(){}public static LazyD getUniqueInstance(){if(lazyd==null){lazyd=new LazyD();}return lazyd;}
}

饿汉式不管使用还是不使用这个实例,直接实例化好实例即可,然后如果需要使用的时候,直接调用方法即可

优点:提前实例化了,避免了线程不安全的问题

缺点:直接实例花了这个实例,不会再延迟实例化,如果系统没有使用这个实例,就会导致操作系统的资源浪费

package com;public class HungryD {private static HungryD uniqueInstance=new HungryD();private HungryD(){};public static HungryD getUniqueInstance(){return uniqueInstance;}
}

懒汉式(线程安全)

和基本的懒汉式的区别就是在get方法上 加了一把 锁。如此一来,多个线程访问,每次只有拿到锁的的线程能够进入该方法,避免了多线程不安全问题的出现。

package com;public class Singletion {private static Singletion uniqueInstance;private Singletion(){};public static synchronized Singletion getUniqueInstance(){if(uniqueInstance==null){uniqueInstance=new Singletion();}return uniqueInstance;}
}

双重校验锁实现(线程安全)

双重检查锁定(Double-Check Locking)是一种对线程安全的懒汉式单例模式的优化。传统的线程安全懒汉式存在性能问题——即使单例已经创建,每次调用仍然需要获取锁,导致性能下降。

而双重检查锁定通过在加锁前先判断实例是否已存在,避免了不必要的锁开销:

  • 如果实例已创建,直接返回实例,不进入加锁代码块,提升了效率。
  • 如果实例未创建,多个线程同时进入时,由于加锁机制,只有一个线程能够进入锁内创建实例,保证线程安全。

因此,只有在首次实例化时会发生线程阻塞,之后的调用都不会再产生锁竞争,从而实现了高效且安全的延迟初始化。

核心就是对比懒汉式的线程安全版本有性能提升

还有就是使用volatile关键字修饰uniqueInstance实例变量的原因如下

执行 uniqueInstance = new Singleton(); 时,实际上分为三步:

  1. 为 uniqueInstance 分配内存
  2. 初始化 uniqueInstance
  3. 将 uniqueInstance 指向分配的内存地址

虽然正常顺序是 1 → 2 → 3,但 JVM 可能因指令重排导致执行顺序变为 1 → 3 → 2。

在单线程环境中这不会有问题,但在多线程环境下可能导致安全隐患:例如线程 A 执行了步骤 1 和 3,还未完成初始化(步骤 2),线程 B 看到 uniqueInstance 非空后直接使用它,结果是使用了未初始化的实例。

为避免这种情况,使用 volatile 关键字修饰 uniqueInstance,可以禁止指令重排,确保多线程环境下实例的正确初始化和可见性,保证线程安全。

package com;public class Singletion {private volatile static Singletion uniqueInstance;private Singletion(){};public static Singletion getUniqueInstance(){if(uniqueInstance==null){synchronized (Singletion.class){if(uniqueInstance==null){uniqueInstance=new Singletion();}}}return uniqueInstance;}
}

静态内部类实现(线程安全)

  1. 延迟加载机制
    • 静态内部类 SingletonHolder 不会在类加载时初始化,只有在首次调用 getUniqueInstance() 方法并访问 SingletonHolder.INSTANCE 时才会被加载。
    • 此时 JVM 会保证 INSTANCE 的初始化过程是线程安全的,并且 仅执行一次。
  1. 线程安全保证
    • 由于类加载机制的特性,JVM 会通过 类初始化锁(Class Initialization Lock) 确保 INSTANCE 的唯一性,无需额外同步代码。
  1. 优势总结
    • 懒加载:实例仅在需要时创建,节省资源。
    • 线程安全:依赖 JVM 的类加载机制,无需双重检查锁(DCL)或 synchronized
    • 高性能:无锁竞争,访问效率高
package com;public class Singletion {private Singletion(){};private static class SingletionHolder{private static final Singletion INSTANCE=new Singletion()l}public static Singletion getUniqueInstance(){return SingletionHolder.INSTANCE;}
}

枚举类实现(线程安全)

枚举类的创建就是线程安全的,任何情况下都是单例的

枚举实现单例时,其实例的创建由 JVM 保证线程安全,且天然是单例。

优点

  • 写法简洁
  • 天然线程安全
  • 自动防止反射和反序列化攻击

关于反序列化问题

  • 序列化:将 Java 对象转换为字节序列
  • 反序列化:根据字节序列重建 Java 对象

常规单例模式在反序列化时可能会创建新的实例,破坏单例性。
为了避免这一问题,通常需要重写 readResolve() 方法来确保反序列化返回同一个实例:

package com;public enum Singletion {INSTANCE;// 添加业务逻辑方法public void using() {// 实际功能逻辑写在这里}
}

相关文章:

手撕四种常用设计模式(工厂,策略,代理,单例)

工厂模式 一、工厂模式的总体好处 解耦:客户端与具体实现类解耦,符合“开闭原则”。统一创建:对象创建交由工厂处理,便于集中控制。增强可维护性:新增对象种类时不需要大改动调用代码。便于扩展:易于管理…...

C# 深入理解类(静态函数成员)

静态函数成员 除了静态字段,还有静态函数成员。 如同静态字段,静态函数成员独立于任何类实例。即使没有类的实例,仍然可以调用静 态方法。静态函数成员不能访问实例成员,但能访问其他静态成员。 例如,下面的类包含一…...

数据类型转换

文章目录 基本数据类型(primitive type)整数类型:浮点类型字符类型boolean类型 类型转换类型转换注意点 基本数据类型(primitive type) 整数类型: ​ byte占1个字节范围:-128-127 ​ short占…...

深入理解 TypeScript 中的 unknown 类型:安全处理未知数据的最佳实践

在 TypeScript 的类型体系中,unknown 是一个极具特色的类型。它与 any 看似相似,却在安全性上有着本质差异。本文将从设计理念、核心特性、使用场景及最佳实践等方面深入剖析 unknown,帮助开发者在处理动态数据时既能保持灵活性,又…...

AI:人形机器人的应用场景以及商业化落地潜力分析

应用场景分析 人形机器人的设计使其能够适应人类环境,执行多样化任务。以下是未来主要的应用场景及其详细分析: 医疗与护理 具体应用: 老年护理:协助老年人穿衣、洗澡、喂食,或提供情感陪伴。康复辅助:帮助…...

JavaScript入门【3】面向对象

1.对象: 1.概述: 在js中除了5中基本类型之外,剩下得都是对象Object类型(引用类型),他们的顶级父类是Object;2.形式: 在js中,对象类型的格式为key-value形式,key表示属性,value表示属性的值3.创建对象的方式: 方式1:通过new关键字创建(不常用) let person new Object();// 添…...

亲测有效!OGG 创建抽取进程报错 OGG-08241,如何解决?

前言 今天在测试 OGG 一个功能的时候,需要重新初始化 oggca,所以重装了一下 OGG。重建完之后重新添加抽取进程报错,一直无法添加成功: 经过一翻分析,找到了解决方案,本文记录一下解决过程。 问题描述 OG…...

【第二篇】 初步解析Spring Boot

简介 SpringBoot是由Pivotal团队提供的全新框架,其设计目的是为了用来简化Spring应用的初始搭建以及开发过程的。本文章将详细介绍SpringBoot为什么能够简化项目的搭建以及普通的Spring程序的开发。文章内容若存在错误或需改进的地方,欢迎大家指正&#…...

JVM 机制

目录 一、什么是 JVM: 二、JVM 的运行流程: 三、JVM 内存区域划分: 1、( 1 ) 程序计数器: 1、( 2 ) 元数据区: 1、( 3 ) 栈: 1、( 4 ) 堆: 四、类加载: 1、什么时候会触…...

Java泛型详解

文章目录 1. 引言1.1 什么是泛型1.2 为什么需要泛型1.3 泛型的优势2. 泛型基础2.1 泛型类多个类型参数2.2 泛型方法2.3 泛型接口2.4 类型参数命名约定3. 类型擦除3.1 什么是类型擦除3.2 类型擦除的影响1. 无法获取泛型类型参数的实际类型2. 无法创建泛型类型的数组3. 无法使用`…...

机器学习,深度学习,神经网络,深度神经网络之间有何区别?

先说个人观点:机器学习>神经网络>深度学习≈深度神经网络。深度学习是基于深度神经网络的,深度神经网络和浅层神经网络都是神经网络,而机器学习是包括神经网络在内的算法。 一、机器学习 先说涵盖范围最广的机器学习。机器学习&#…...

AtomicInteger

AtomicInteger 是 Java 并发包 (java.util.concurrent.atomic) 中的一个原子类,用于在多线程环境下对整数进行原子操作。 核心特性 原子性 提供线程安全的原子操作(如自增、加法、比较并交换等),确保在多线程环境中操作不会被中…...

威布尔比例风险模型(Weibull Proportional Hazards Model, WPHM)详解:原理、应用与实施

威布尔比例风险模型(Weibull Proportional Hazards Model, WPHM)详解:原理、应用与实施 一、核心原理:从威布尔分布到比例风险模型 1. 威布尔分布的数学本质 威布尔分布通过两个关键参数(形状参数 (k) 和尺度参数 (\…...

Dubbo:Docker部署Zookeeper、Dubbo Admin的详细教程和SpringBoot整合Dubbo的实战与演练

🪁🍁 希望本文能给您带来帮助,如果有任何问题,欢迎批评指正!🐅🐾🍁🐥 文章目录 一、背景二、Dubbo概述三、Dubbo与SpringCloud的关系四、Dubbo技术架构五、Docker安装Zoo…...

Windows 上安装下载并配置 Apache Maven

1. 下载 Maven 访问官网: 打开 Apache Maven 下载页面。 选择版本: 下载最新的 Binary zip archive(例如 apache-maven-3.9.9-bin.zip)。 注意:不要下载 -src 版本(那是源码包)。 2. 解压 Mave…...

Unbuntu 命令

Ubuntu 命令速查表​ ​分类​​命令​​功能描述​​示例/常用选项​​​​文件与目录​ls列出目录内容ls -a(显示隐藏文件); ls -lh(详细列表易读大小) cd切换目录cd ~(主目录); cd ..(上级…...

机器学习-人与机器生数据的区分模型测试-数据处理1

附件为训练数据,总体的流程可以作为参考。 导入依赖 import pandas as pd import os import numpy as np from sklearn.model_selection import train_test_split,GridSearchCV from sklearn.ensemble import RandomForestClassifier,VotingClassifier from skle…...

【Linux】进程间通信(一):认识管道

📝前言: 这篇文章我们来讲讲进程间通信——认识管道 🎬个人简介:努力学习ing 📋个人专栏:Linux 🎀CSDN主页 愚润求学 🌄其他专栏:C学习笔记,C语言入门基础&a…...

AMD Vivado™ 设计套件生成加密比特流和加密密钥

概括 重要提示:有关使用AMD Vivado™ Design Suite 2016.4 及更早版本进行 eFUSE 编程的重要更新,请参阅AMD设计咨询 68832 。 本应用说明介绍了使用AMD Vivado™ 设计套件生成加密比特流和加密密钥(高级加密标准伽罗瓦/计数器模式 (AES-GCM)…...

第三十四节:特征检测与描述-SIFT/SURF 特征 (专利算法)

一、特征检测:计算机视觉的基石 在计算机视觉领域中,特征检测与描述是实现图像理解的核心技术。就像人类通过识别物体边缘、角点等特征来认知世界,算法通过检测图像中的关键特征点来实现: 图像匹配与拼接 物体识别与跟踪 三维重建 运动分析 其中,SIFT(Scale-Invariant F…...

【AI】SpringAI 第二弹:基于多模型实现流式输出

目录 一、基于多模型实现流式输出 1.1 什么是流式输出 1.2 多模型引入 1.3 代码实现 1.3.1 流式输出的API介绍 1.3.2 Flux 源码分析 二、了解 Reactor 模型 三、SSE 协议 一、基于多模型实现流式输出 1.1 什么是流式输出 流式输出(Streaming Output)是指数据在生成过程…...

SQL语句执行问题

执行顺序 select [all|distinct] <目标列的表达式1> AS [别名], <目标列的表达式2> AS [别名]... from <表名1或视图名1> [别名],<表名2或视图名2> [别名]... [where <条件表达式>] [group by <列名>] [having <条件表达式>] [ord…...

模型量化AWQ和GPTQ哪种效果好?

环境&#xff1a; AWQ GPTQ 问题描述&#xff1a; 模型量化AWQ和GPTQ哪种效果好? 解决方案&#xff1a; 关于AWQ&#xff08;Adaptive Weight Quantization&#xff09;和GPTQ&#xff08;Generative Pre-trained Transformer Quantization&#xff09;这两种量化方法的…...

Github 2025-05-17 Rust开源项目日报 Top10

根据Github Trendings的统计,今日(2025-05-17统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Rust项目10Dart项目1RustDesk: 用Rust编写的开源远程桌面软件 创建周期:1218 天开发语言:Rust, Dart协议类型:GNU Affero General Public Li…...

借助 CodeBuddy 打造我的图标预览平台 —— IconWiz 开发实录

我正在参加CodeBuddy「首席试玩官」内容创作大赛&#xff0c;本文所使用的 CodeBuddy 免费下载链接&#xff1a;腾讯云代码助手 CodeBuddy - AI 时代的智能编程伙伴 想做一款自己的图标预览平台 这段时间我在做前端 UI 设计时&#xff0c;常常需要到处找图标素材&#xff0c;复…...

KL散度 (Kullback-Leibler Divergence)

KL散度&#xff0c;也称为相对熵 (Relative Entropy)&#xff0c;是信息论中一个核心概念&#xff0c;用于衡量两个概率分布之间的差异。给定两个概率分布 P ( x ) P(x) P(x) 和 Q ( x ) Q(x) Q(x)&#xff08;对于离散随机变量&#xff09;或 p ( x ) p(x) p(x) 和 q ( x …...

【Linux网络】NAT和代理服务

NAT 之前我们讨论了&#xff0c;IPv4协议中&#xff0c;IP地址数量不充足的问题。 原始报文途径路由器WAN口时&#xff0c;对报文中的源IP进行替换的过程&#xff0c;叫做NAT。 NAT技术当前解决IP地址不够用的主要手段&#xff0c;是路由器的一个重要功能&#xff1a; NAT能…...

DeepSeek赋能电商,智能客服机器人破解大型活动人力困境

1. DeepSeek 与电商客服结合的背景 1.1 电商行业客服需求特点 电商行业具有独特的客服需求特点&#xff0c;这些特点决定了智能客服机器人在该行业的必要性和重要性。 高并发性&#xff1a;电商平台的用户数量庞大&#xff0c;尤其是在促销活动期间&#xff0c;用户咨询量会…...

Unity序列化字段、单例模式(Singleton Pattern)

一、序列化字段 在Unity中&#xff0c;序列化字段是一个非常重要的概念&#xff0c;主要用于在Unity编辑器中显示和编辑类的成员变量&#xff0c;或者在运行时将对象的状态保存到文件或网络中。 1.Unity序列化字段的作用 在编辑器中显示和编辑字段&#xff1a;默认情况下&…...

一个可拖拉实现列表排序的WPF开源控件

从零学习构建一个完整的系统 推荐一个可通过拖拉&#xff0c;来实现列表元素的排序的WPF控件。 项目简介 gong-wpf-dragdrop是一个开源的.NET项目&#xff0c;用于在WPF应用程序中实现拖放功能&#xff0c;可以让开发人员快速、简单的实现拖放的操作功能。 可以在同一控件内…...

hadoop.proxyuser.代理用户.授信域 用来干什么的

在Hadoop的core-site.xml文件中存在三个可选配置&#xff0c;如下 <property><name>hadoop.proxyuser.root.hosts</name><value>*</value> </property> <property><name>hadoop.proxyuser.root.groups</name><value…...

python 自动化教程

文章目录 前言整数变量​字符串变量​列表变量​算术操作​比较操作​逻辑操作​if语句​for循环遍历列表​while循环​定义函数​调用函数​导入模块​使用模块中的函数​启动Chrome浏览器​打开网页​定位元素并输入内容​提交表单​关闭浏览器​发送GET请求获取网页内容​使…...

C++学习:六个月从基础到就业——C++11/14:列表初始化

C学习&#xff1a;六个月从基础到就业——C11/14&#xff1a;列表初始化 本文是我C学习之旅系列的第四十三篇技术文章&#xff0c;也是第三阶段"现代C特性"的第五篇&#xff0c;主要介绍C11/14中的列表初始化特性。查看完整系列目录了解更多内容。 引言 在C11之前&a…...

城市静音革命:当垃圾桶遇上缓冲器

缓冲垃圾桶的核心原理是通过机械或液压装置实现垃圾桶盖的缓慢闭合&#xff0c;包含以下技术要点&#xff1a;‌能量吸收机制‌液压式&#xff1a;通过活塞挤压油液产生阻尼力&#xff0c;将动能转化为热能耗散弹簧式&#xff1a;利用弹性变形储存和释放能量&#xff0c;配合摩…...

数据库的规范化设计方法---3种范式

第一范式&#xff08;1NF&#xff09;&#xff1a;确保表中的每个字段都是不可分割的基本数据项。 第二范式&#xff08;2NF&#xff09;&#xff1a;在满足1NF的基础上&#xff0c;确保非主属性完全依赖于主键。 第三范式&#xff08;3NF&#xff09;&#xff1a;在满足2NF的基…...

p024基于Django的网上购物系统的设计与实现

开发语言&#xff1a;Python框架&#xff1a;djangoPython版本&#xff1a;python3.7.7数据库&#xff1a;mysql 5.7数据库工具&#xff1a;Navicat11开发软件&#xff1a;PyCharm 系统展示 管理员登录 管理员功能界面 用户管理 商品类型管理 商品信息管理 系统管理 订单管理…...

C++跨平台开发:挑战与应对策略

C跨平台开发&#xff1a;挑战与应对策略 在如今设备多样、操作系统碎片化的开发环境中&#xff0c;跨平台能力已成为衡量软件生命力与团队工程效率的重要指标。C 作为高性能系统级语言&#xff0c;在游戏引擎、嵌入式系统、实时渲染等领域依旧坚挺。然而&#xff0c;实现“一次…...

Kotlin 作用域函数(let、run、with、apply、also)对比

Kotlin 的 作用域函数&#xff08;Scope Functions&#xff09; 是简化代码逻辑的重要工具&#xff0c;它们通过临时作用域为对象提供更简洁的操作方式。以下是 let、run、with、apply、also 的对比分析&#xff1a; 一、核心区别对比表 函数上下文对象引用返回值是否扩展函数…...

JavaScript性能优化实战(11):前沿技术在性能优化中的应用

引言 随着Web应用复杂度和性能需求不断提高,传统的JavaScript优化技术已经无法满足某些高性能计算场景的需求。本文将深入探讨前沿Web技术如何突破JavaScript的性能瓶颈,为Web应用提供接近原生应用的性能体验。从底层计算到图形渲染,从并发处理到动画优化,我们将通过实际案…...

数据结构【AVL树】

AVL树 1.AVL树1.AVL的概念2.平衡因子 2.AVl树的实现2.1AVL树的结构2.2AVL树的插入2.3 旋转2.3.1 旋转的原则 1.AVL树 1.AVL的概念 AVL树可以是一个空树。 它的左右子树都是AVL树&#xff0c;且左右子树的高度差的绝对值不超过1。AVL树是一颗高度平衡搜索二叉树&#xff0c;通…...

电动调节V型球阀:行业应用与材质选择全解析

电动调节V型球阀&#xff1a;行业应用与材质选择全解析 作为工业自动化控制中的关键设备&#xff0c;电动调节V型球阀凭借其独特的结构设计与高性能调节能力&#xff0c;在石油、化工、造纸等高要求领域广泛应用。本文将从核心功能、行业应用场景、材质选择要点等方面深入解析…...

页面上如何显示特殊字符、Unicode字符?

在前端开发中&#xff0c;显示特殊字符通常涉及到HTML实体&#xff08;HTML Entities&#xff09;或 Unicode 字符的使用。以下是一些常见的方法来处理特殊字符的显示&#xff1a; 1、HTML实体&#xff1a; HTML为一些常见的特殊字符提供了预定义的实体。例如&#xff0c;要显…...

桌面端进程通信

以下是关于 Electron 桌面端进程通信的基本知识点总结: 一、Electron 进程模型基础 1. 进程类型与职责 进程类型职责权限主进程(Main)创建窗口、系统级操作、IPC中枢完全Node.js访问权限渲染进程(Renderer)展示Web内容、UI交互默认受限(可配置开启Node.js)预加载脚本(Prelo…...

vue2 切换主题色以及单页面好使方法

今天要新增一个页面要根据不同公司切换不同页面主题色&#xff0c;一点一点来&#xff0c;怎么快速更改 el-pagination 分页组件主题色。 <el-pagination :page-size"pageSize" :pager-count"pageCount"layout"sizes, prev, pager, next, jumper,…...

三层固定实体架构:高效实现图上的检索增强生成(RAG)

知识图谱正在成为跨各个领域组织和检索信息的强大工具。它们越来越多地与机器学习和自然语言处理技术相结合,以增强信息检索和推理能力。在本文中,我介绍了一种用于构建知识图谱的三层架构,结合了固定本体实体、文档片段和提取的命名实体。通过利用嵌入和余弦相似度,这种方…...

pnpm 与 npm 的核心区别

以下是 pnpm 与 npm 的核心区别总结&#xff0c;涵盖依赖管理、性能、安全性等关键维度&#xff1a; 1. 依赖存储机制 • npm&#xff1a; 每个项目的依赖独立存储于 node_modules&#xff0c;即使多个项目使用相同版本的包&#xff0c;也会重复下载和存储。例如&#xff0c;1…...

NVMe简介6之PCIe事务层

PCIe的事务层连接了PCIe设备核心与PCIe链路&#xff0c;这里主要基于PCIe事务层进行分析。事务层采用TLP传输事务&#xff0c;完整的TLP由TLPPrefix、TLP头、Payload和TLP Digest组成。TLP头是TLP中最关键的部分&#xff0c;一般由三个或四个双字的长度&#xff0c;其格式定义如…...

【C++详解】string各种接口如何使用保姆级攻略

文章目录 一、string介绍二、string使用构造函数析构函数赋值运算符重载string的遍历修改方法1、下标[]2、迭代器3、范围for 迭代器使用详解const迭代器反向迭代器&#xff08;reverse) Capacity(容量相关)size/lengthmax_sizecapacityclear/emptyshrink_to_fit(缩容)reserve(扩…...

深入理解 requestIdleCallback:浏览器空闲时段的性能优化利器

requestIdleCallback 核心作用 requestIdleCallback 是浏览器提供的 API&#xff0c;用于将非关键任务延迟到浏览器空闲时段执行&#xff0c;避免阻塞用户交互、动画等关键任务&#xff0c;从而提升页面性能体验。 基本语法 const handle window.requestIdleCallback(callb…...

QML鼠标事件和按键事件

1 鼠标事件 1.1 MouseArea组件 在QML中&#xff0c;鼠标事件主要通过MouseArea元素处理&#xff0c;它是用于检测和响应鼠标交互的核心组件。常用属性 cursorShape: 光标形状acceptedButtons: 设置响应鼠标的哪些按键事件&#xff0c;默认为鼠标左键 Qt.LeftButton&#xff1…...