【Android】创建型设计模式—单例模式、工厂模式、建造者模式
单例模式
单例模式(Singleton Pattern)是一种创建型设计模式,它确保一个类只有一个实例,并提供全局访问点。
单例模式类图:
单例模式有多种实现方式,下面我们详细介绍几种常见的实现方式:
1. 懒汉式(Lazy Initialization)
懒汉式单例模式(Lazy Singleton)是一种延迟实例化的方式,即在首次使用该类时才会创建实例。
代码示例(线程不安全):
public class Singleton {private static Singleton instance;// 私有构造函数,避免外部实例化private Singleton() {}// 获取实例的方法public static Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}
}
优点:
- 延迟实例化,直到第一次使用时才创建实例。
- 节省内存,如果没有使用这个单例,实例不会被创建。
缺点:
- 在多线程环境下,可能会出现多个线程同时进入
if (instance == null)
语句块,导致创建多个实例。需要考虑线程安全问题。
2. 线程安全的懒汉式(双重检查锁定,Double-Checked Locking)
为了避免线程不安全问题,懒汉式可以通过双重检查锁定来保证线程安全。
代码示例:
public class Singleton {private static volatile Singleton instance;// 私有构造函数,避免外部实例化private Singleton() {}// 获取实例的方法public static Singleton getInstance() {if (instance == null) {synchronized (Singleton.class) {if (instance == null) {instance = new Singleton();}}}return instance;}
}
关键点:
- 双重检查:第一次检查
instance == null
用来减少不必要的同步开销;第二次检查是在同步块内,保证在实例创建时只有一个线程可以创建。 volatile
关键字:确保多线程环境下对instance
的访问是可见的,并且防止由于 JIT 编译器优化等原因造成的问题。
优点:
- 保证线程安全,并且提高了性能。只有第一次实例化时需要同步,后续调用不再需要加锁。
缺点:
- 代码比较复杂,理解起来需要更多的思考。
3. 饿汉式(Eager Initialization)
饿汉式单例模式在类加载时就创建实例,这种方式不需要考虑线程安全问题,因为实例在类加载时就已经被创建。
代码示例:
public class Singleton {// 静态初始化时就创建实例private static final Singleton instance = new Singleton();// 私有构造函数,避免外部实例化private Singleton() {}// 获取实例的方法public static Singleton getInstance() {return instance;}
}
优点:
- 简单,容易理解。
- 线程安全:类加载时已经完成初始化,且
instance
是静态常量,JVM 保证线程安全。
缺点:
- 浪费内存:即使实例可能永远不被使用,类加载时实例就会创建。
- 不支持延迟初始化:如果类加载时并不需要这个单例对象,就会造成不必要的内存开销。
4. 静态内部类式(Bill Pugh Singleton)
静态内部类式单例模式是一种懒加载的单例实现方式,它结合了懒汉式和饿汉式的优点。使用静态内部类时,实例化的过程是延迟的,但又能够避免线程安全问题。
代码示例:
public class Singleton {// 静态内部类,它在第一次使用时被加载private static class SingletonHelper {private static final Singleton INSTANCE = new Singleton();}// 私有构造函数,避免外部实例化private Singleton() {}// 获取实例的方法public static Singleton getInstance() {return SingletonHelper.INSTANCE;}
}
关键点:
- 静态内部类:
SingletonHelper
是一个静态内部类,它只有在getInstance()
被调用时才会被加载,因此实现了懒加载。 - 线程安全:
SingletonHelper.INSTANCE
只会在类加载时初始化一次,而且类加载是线程安全的,因此不需要显式的同步控制。
优点:
- 线程安全。
- 延迟加载:实例会在第一次使用时才会被创建。
- 相对于双重检查锁定,代码更加简洁。
- 不会造成内存浪费,因为静态内部类只有在需要时才会被加载。
缺点:
- 无明显缺点,适用于绝大多数场景。
5. 枚举式(Enum Singleton)
枚举式单例模式是最简单、最安全的实现方式。Java 的枚举类型天然就是单例的,JVM 保证枚举实例的创建是线程安全的,而且枚举不允许被反射破坏单例。
代码示例:
public enum Singleton {INSTANCE;public void doSomething() {System.out.println("Singleton with Enum");}
}
优点:
- 简洁:单例实例是由
INSTANCE
常量代表的,代码非常简洁。 - 线程安全:Java 枚举类型在类加载时保证了线程安全。
- 防止反射攻击:枚举类型无法通过反射进行实例化,因此避免了反射破解单例的风险。
- 防止序列化破坏:枚举本身能够防止序列化导致的实例重复创建。
缺点:
- 不常见的实现方式,对于不了解枚举的开发者可能会产生困惑。
对比
特性 | 懒汉式(Lazy Initialization) | 线程安全的懒汉式(双重检查锁定) | 饿汉式(Eager Initialization) | 静态内部类式(Bill Pugh Singleton) | 枚举式(Enum Singleton) |
---|---|---|---|---|---|
实例化时机 | 延迟实例化,首次调用时才创建 | 延迟实例化,首次调用时才创建,但保证线程安全 | 类加载时就创建实例 | 延迟实例化,静态内部类加载时创建 | 类加载时创建(JVM保证线程安全和单例性) |
线程安全 | 否,可能出现并发问题(需要手动同步) | 是,使用双重检查锁定(synchronized )保证线程安全 | 是,由于类加载时创建,因此天然线程安全 | 是,JVM保证静态内部类加载时线程安全 | 是,JVM保证枚举类型线程安全和单例性 |
性能 | 较低(每次访问都需要判断 null ) | 较高(只有第一次需要同步) | 较高(不需要同步) | 较高(避免了每次判断 null ) | 最高,JVM直接管理,几乎无性能损耗 |
实现复杂度 | 简单,易于理解 | 稍复杂,需要额外的同步机制 | 简单,直接实现 | 稍复杂,涉及到静态内部类 | 非常简单,直接使用枚举实现 |
内存消耗 | 可能浪费内存(在未使用时实例仍然存在) | 不浪费内存,只在需要时实例化 | 可能浪费内存(实例化时就创建,不管是否使用) | 不浪费内存,实例化仅在第一次使用时创建 | 不浪费内存,枚举实例只在类加载时创建 |
防止反射攻击 | 否,反射可以创建多个实例 | 否,反射可以创建多个实例 | 否,反射可以创建多个实例 | 是,反射无法破坏单例 | 是,枚举类的反射破坏会抛出异常 |
防止序列化破坏 | 否,需要手动处理 | 否,需要手动处理 | 否,需要手动处理 | 是,JVM管理序列化,确保不会破坏单例 | 是,JVM保证序列化时保持唯一性 |
推荐场景 | 简单场景,单线程应用 | 线程安全需求较高,但性能要求不极端的场景 | 单线程应用或对性能要求较高的场景 | 需要延迟加载并且希望避免同步开销的场景 | 高度推荐,适用于大多数单例场景 |
常见问题 | 可能出现并发问题,需要同步 | 代码较复杂,性能相对稍差 | 不支持延迟加载,类加载时会立即初始化 | 稍复杂,理解需要一定的知识 | 极为简洁,但不适用于需要多个实例化参数的情况 |
总结
- 懒汉式适用于需要延迟实例化的场景,但需要注意线程安全问题。
- 双重检查锁定懒汉式是懒汉式的改进,能够保证线程安全并提高性能。
- 饿汉式不需要担心线程安全问题,但存在内存浪费的风险。
- 静态内部类式是较为推荐的懒加载方式,线程安全且高效。
- 枚举式是最简洁、最安全的实现方式,JVM保证线程安全和防止反射攻击,是最推荐的实现方式。
工厂模式
简单工厂模式
简单工厂模式(也称为静态工厂方法模式)是创建型设计模式之一,它提供了一个类来负责创建实例化对象的工作,客户端只需要传入相关的参数,而不需要关心对象的创建过程。
- Factory:工厂类,这是简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。工厂类的创建产品类的方法可以被外界直接调用,创建所需的产品对象。
- IProduct:抽象产品类,这是简单工厂模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。
- Product:具体产品类,这是简单工厂模式的创建目标。
简单实现
这里我们用生产计算机来举例,假设有一个计算机的代工生产商,它目前已经可以代工生产联想计算机了。随着业务的拓展,这个代工生产商还要生产惠普和华硕的计算机。这样我们就需要用一个单独的类来专门生产计算机,这就用到了简单工厂模式。下面我们来实现简单工厂模式。
(1)抽象产品类
public abstract class Computer {public abstract void start();
}
(2)具体产品类
我们创建多个品牌的计算机,都继承自己父类Computer,并且实现父类的start()方法:
public class LenovoComputer extends Computer{@Overridepublic void start() {System.out.println("联想计算机");}
}
public class HpComputer extends Computer{@Overridepublic void start() {System.out.println("惠普计算机");}
}
public class AsusComputer extends Computer{@Overridepublic void start() {System.out.println("华硕计算机");}
}
(3)工厂类
下来创建一个工厂类,提供一个静态方法createComputer去生产计算机:
public class ComputerFactory {public static Computer createComputer(String type){Computer mComputer = null;switch (type) {case "lenovo":mComputer = new LenovoComputer();break;case "hp":mComputer = new HpComputer();break;case "asus":mComputer = new HpComputer();break;}return mComputer;}
}
(4)客户端调用工厂类
public class CreatComputer {public static void main(String[] args) {ComputerFactory.createComputer("hp").start();}
}
优缺点
优点:
- 客户端与产品解耦:客户端代码不需要知道具体的产品类,只需要知道如何调用工厂来获取产品。
- 易于扩展:如果要添加新的产品类型,只需要在工厂类中增加新的
if-else
分支或修改创建产品的逻辑即可,客户端无需修改。 - 集中管理产品创建:产品的创建逻辑都集中在工厂类中,便于管理和修改。
缺点:
- 违反开闭原则:每当需要增加新的产品类型时,都需要修改工厂类的
createProduct()
方法,违反了“对扩展开放,对修改封闭”的设计原则。 - 工厂类职责过重:如果产品种类很多,工厂类的逻辑可能变得非常庞大,影响维护性。
- 不利于产品的复杂多样化:如果产品种类非常多且产品之间有较复杂的差异,简单的
if-else
分支可能使得工厂类显得臃肿和不可维护。
使用场景
简单工厂模式适用于以下场景:
- 产品种类较少且变化不大的情况:如果需要创建的产品类型固定且不经常变动,使用简单工厂模式非常适合。
- 客户端需要创建多个类型的对象:当客户端需要通过不同的输入来创建不同类型的对象时,工厂模式可以有效地隐藏对象的创建逻辑。
- 控制产品创建逻辑:当需要集中管理和控制产品的创建过程时,简单工厂模式提供了很好的解决方案。
工厂方法模式
工厂方法模式(Factory Method Pattern) 是一种创建型设计模式,用于定义一个创建对象的接口,让子类决定实例化哪一个类。它通过将对象的创建委托给子类,从而实现了代码的解耦,使得代码更加灵活和易于扩展。
工厂方法模式有如下角色:
- 产品接口(Product):定义产品的公共接口。
- 具体产品(ConcreteProduct):实现产品接口的具体类。
- 工厂方法(Creator):声明创建产品对象的工厂方法。
- 具体工厂(ConcreteCreator):实现工厂方法,创建并返回具体的产品对象。
简单实现
(1)创建抽象工厂
public abstract class ComputerFactory {public abstract <T extends Computer> T createComputer(Class<T> clz);
}
(2)创建具体工厂
广达代工厂是一个具体的工厂,其继承自抽象工厂,通过反射来生产不同厂家的计算机:
public class GDComputerFactor extends ComputerFactory{@Overridepublic <T extends Computer> T createComputer(Class<T> clz) {Computer computer = null;String classname = clz.getName();try {computer = (Computer) Class.forName(classname).newInstance();} catch (Exception e) {e.printStackTrace();}return (T) computer;}
}
(3)客户端调用
客户端创建了GDComputerFactor,并分别生产了联想计算机、惠普计算机和华硕计算机:
public class Client {public static void main(String[] args) {ComputerFactory computerFactory = new GDComputerFactor();LenovoComputer mLenovoComputer = computerFactory.createComputer(LenovoComputer.class);mLenovoComputer.start();HpComputer mHpComputer = computerFactory.createComputer(HpComputer.class);mHpComputer.start();AsusComputer mAsusComputer = computerFactory.createComputer(AsusComputer.class);mAsusComputer.start();}
}
比较
特点 | 简单工厂模式 | 工厂方法模式 |
---|---|---|
创建方式 | 使用静态方法通过条件判断创建不同的产品对象。 | 通过定义一个抽象工厂接口,具体工厂类实现该接口来创建产品。 |
工厂类数量 | 只有一个工厂类,负责所有产品的创建。 | 有多个工厂类,每个具体工厂类负责创建一种产品。 |
可扩展性 | 不符合开闭原则,增加新产品需要修改工厂类代码。 | 符合开闭原则,新增产品时只需添加新的具体工厂类,而无需修改现有代码。 |
耦合性 | 客户端代码直接依赖于工厂方法,需要知道产品的种类。 | 客户端代码依赖于抽象工厂接口,具体的工厂类是透明的。 |
复杂度 | 简单,适用于产品种类较少的情况。 | 相对复杂,适用于产品种类较多或者希望扩展的情况。 |
优点 | 实现简单,适合产品种类较少的情况。 | 符合开闭原则,容易扩展,灵活性更强。 |
缺点 | 不符合开闭原则,增加产品时需要修改工厂类代码。 | 增加了系统的复杂性,需要创建多个工厂类。 |
建造者模式
建造者模式(Builder Pattern) 是一种 创建型设计模式,它允许通过一步一步地构建复杂对象,而无需指定对象的具体构造过程。建造者模式关注的是对象的构建过程,将对象的构建和表示分离开来,使得同样的构建过程可以创建不同类型的对象。
例如,我们要“DIY”一台台式计算机。我们找到“DIY”商家。这时我们可以要求这台计算机的CPU、主板或者其他部件都是什么牌子的、什么配置的,这些部件可以是我们根据自己的需求来定制的。但是这些部件组装成计算机的过程是一样的,我们无须知道这些部件是怎样组装成计算机的,我们只需要提供相关部件的牌子和配置就可以了。
建造者模式通常包含以下几个角色:
- 产品(Product):即最终要创建的复杂对象。
- 抽象建造者(Builder):提供构建对象的抽象接口,定义如何构建产品的各个部分。
- 具体建造者(ConcreteBuilder):实现
Builder
接口,负责具体产品的构建。 - 指挥者(Director):负责安排建造的顺序和调用建造者的方法,指导建造者如何构建产品。
简单实现
(1)创建产品类
我要组装一台计算机,计算机被抽象为Computer类,(本例假设)它有3个部件:CPU主板和内存,并在里面提供了3个方法分别用来设置CPU、主板和内存:
public class Computer {private String mCpu;private String mMainboard;private String mRam;public void setmCpu(String mCpu) {this.mCpu = mCpu;}public void setmMainboard(String mMainboard) {this.mMainboard = mMainboard;}public void setmRam(String mRam) {this.mRam = mRam;}
}
(2)创建Builder类,规范产品的组建
商家组装计算机有一套组装方法的模板,就是一个抽象的Builder 类,其里面提供了安装CPU、主板和内存的方法,以及组装成计算机的create方法,如下所示:
public abstract class Builder {public abstract void buildCpu(String cpu);public abstract void buildMainboard(String mainboard);public abstract void buildRam(String ram);public abstract Computer create();
}
商家实现了抽象的Builder类,MoonComputerBuilder类用于组装计算机:
public class MoonComputerBuilder extends Builder{private Computer mComputer = new Computer();@Overridepublic void buildCpu(String cpu) {mComputer.setmCpu(cpu);}@Overridepublic void buildMainboard(String mainboard) {mComputer.setmMainboard(mainboard);}@Overridepublic void buildRam(String ram) {mComputer.setmRam(ram);}@Overridepublic Computer create() {return mComputer;}
}
(3)用导演类来统一组装过程
商家的导演类用来规范组装计算机的流程:先安装主板,再安装CPU,最后安装内存并组装成计算机:
public class Diretor {Builder mBuild = null;public Diretor(Builder mBuild) {this.mBuild = mBuild;}public Computer createComputer(String cpu, String mainboard, String ram) {this.mBuild.buildMainboard(mainboard);this.mBuild.buildCpu(cpu);this.mBuild.buildRam(ram);return this.mBuild.create();}
}
(4)客户端调用导演类
最后商家用导演类组装计算机。我们只需要提供自己想要的CPU、主板和内存就可以了至于商家怎样组装计算机我们无须知道。具体代码如下所示:
public class CreateComputer {public static void main(String[] args) {Builder mBuilder = new MoonComputerBuilder();Diretor mDiretor = new Diretor(mBuilder);mDiretor.createComputer("i5","8G","1T");}
}
优缺点
优点
- 解耦复杂对象的构建过程和表示:客户端不需要知道构建的细节,可以专注于产品的组装。
- 代码可读性和可维护性高:将复杂对象的构建过程拆分成多个步骤,使得代码结构更加清晰。
- 支持不同产品的变体:同样的建造过程可以用于构建不同的产品对象。
缺点
- 产生多余的 Build 对象以及导演类
使用场景
- 创建一个复杂对象时,其构建过程应该独立于该对象的组成部分,并且可以允许被构建成不同的表示。
- 当一个对象的构建过程独立于其组成部分,并且可以组合成不同的方式时,可以使用建造者模式。
已经到底啦!!
相关文章:
【Android】创建型设计模式—单例模式、工厂模式、建造者模式
单例模式 单例模式(Singleton Pattern)是一种创建型设计模式,它确保一个类只有一个实例,并提供全局访问点。 单例模式类图: #mermaid-svg-kzf6IdXdYeNOHtP0 {font-family:"trebuchet ms",verdana,arial,sa…...
ida9pro压缩包
资源类型的博客大部分都是为了自己某天换新机了用 下载链接2:ida9.zip 下载链接1:https://mega.nz/folder/yiAiVDAa#T0kogEE7ufqy0x0EpCuOLQ 主目录下该文件为证书文件 ida9中选择它,就可以了...
前端入门之VUE--vue组件化编程
前言 VUE是前端用的最多的框架;这篇文章是本人大一上学习前端的笔记;欢迎点赞 收藏 关注,本人将会持续更新。 文章目录 2、Vue组件化编程2.1、组件2.2、基本使用2.2.1、VueComponent 2、Vue组件化编程 2.1、组件 组件:用来实现…...
C++是如何工作的?
首先来看一个最基本的C程序段。 #include <iostream>int main() {std::cout << "HelloWorld" << std::endl;std::cin.get(); } 第一行 #include 的含义是预处理的意思,这条语句的作用是将一个名为iostream的文件拷贝到源代码中这个…...
JavaScript中的this, 究竟指向什么?
在JavaScript代码的不同位置中,this所指向的数据是不一样的。比如大部分同学都知道,在对象的函数属性方法中,this指向对象本身;在构造函数中,this指向要生成的新对象。事实上,this指向的逻辑不止这几种&…...
JavaWeb学习(3)(Servlet详细、Servlet的三种实现方式(面试)、Servlet的生命周期、传统web.xml配置Servlet(了解))
目录 一、Servlet详细。 (1)基本介绍。 (2)基本作用。 1、接收客户端请求数据。 2、处理请求。 3、完成响应结果。 二、Servlet的三种实现方式。 (1)实现javax.servlet.Servlet接口。 1、基本介绍。 2、代码…...
【图像去雾数据集】URHI数据集介绍
URHI数据集对应论文:RESIDE: A Benchmark for Single Image Dehazing(2017) URHI数据集下载链接:https://sites.google.com/site/boyilics/website-builder/reside 为便于下载,将上述官方提供的链接中百度云链接粘贴如…...
Playwright中Page类的方法
导航和页面操作 goto(url: str, **kwargs: Any): 导航到一个URL。 reload(**kwargs: Any): 重新加载当前页面。 go_back(**kwargs: Any): 导航到会话历史记录中的前一个页面。 go_forward(**kwargs: Any): 导航到会话历史记录中的下一个页面。 set_default_navigation_tim…...
算力介绍与解析
算力(Computing Power)是指计算机系统在单位时间内处理数据和执行计算任务的能力。算力是衡量计算机性能的重要指标,直接影响计算任务的速度和效率。 算力的分类和单位 a. 基础算力:以CPU的计算能力为主。适用于各个领域的计算。…...
CentOS 上如何查看 SSH 服务使用的端口号?
我们知道,linux操作系统中的SSH默认情况下,端口是使用22,但是有些线上服务器并不是使用的默认端口,那么这个时候,我们应该如何快速知道SSH使用的哪个端口呢? 1、通过配置文件查看 cat /etc/ssh/sshd_confi…...
每日算法Day03
1.19.删除链表的倒数第N个节点 算法链接: 19. 删除链表的倒数第 N 个结点 - 力扣(LeetCode) 类型: 链表 难度: 中等 思路:采用双指针法,控制两个指针之间的距离为n个节点 易错点:返回节点的确定和头节点的处理&…...
【漏洞复现】Apache Solr 身份认证绕过导致任意文件读取漏洞复现(CVE-2024-45216)
🏘️个人主页: 点燃银河尽头的篝火(●’◡’●) 如果文章有帮到你的话记得点赞👍+收藏💗支持一下哦 【漏洞复现】Apache Solr 身份认证绕过导致任意文件读取漏洞复现(CVE-2024-45216) 一、漏洞概述1.1漏洞简介1.2组件描述1.3漏洞描述二、漏洞复现2.1 应用协议2.2 环境…...
若依将数据库更改为SQLite
文章目录 1. 添加依赖项2. 更新配置文件 application-druid.yml2.1. 配置数据源2.2. 配置连接验证 3. 更新 MybatisPlusConfig4. 解决 mapper 中使用 sysdate() 的问题4.1. 修改 BaseEntity4.2. 修改 Mapper 5. 更新 YML 配置 正文开始: 前提条件:在您的…...
ubuntu远程桌面开启opengl渲染权限
背景 最近用windows的【远程桌面连接】登录ubuntu后(xrdp协议),发现gl环境是集显的,但是本地登录ubuntu桌面后是独显(英伟达),想要在远程桌面上也用独显渲染环境。 一、查看是独显还是集显环境…...
Scala的泛型
需求:定义一个名为getMiddleEle 的方法用它来获取当前的列表的中间位置的值中间位置的下标 长度/2目标:getMiddleEle(List(1,2,3,4,5)) > 5/2 2 > 下标为2的元素是:3 getMiddleEle(List(1,2,3,4)) > 4/2 2 > 下标为2的元素是:3格式如下: 定义一个函数的格式:def…...
每隔一秒单片机向电脑发送一个16进制递增数据
SCON0x50 SM00 SM11(工作方式为方式一) REN1允许单片机从电脑接收数据 TB8 RB8 SM2是方式2和方式3直接配置为0 TI为发送中断请求标志位 由硬件配置为1 必须由 软件复位为0,RI为接收中断请求标志位,同理TI UART.c #include &l…...
轻量级日志管理平台:Grafana Loki搭建及应用(详细篇)
前言 Grafana Loki是Grafana Lab团队提供的一个水平可扩展、高可用性、多租户的日志聚合系统,与其他日志系统不同的是,Loki最初设计的理念是为了为日志建立标签索引,而非将原日志内容进行索引。 现在目前成熟的方案基本上都是:L…...
React和Vue.js的相似性和差异性是什么?
React和Vue.js都是现代前端开发中广泛使用的JavaScript框架,它们都旨在提高开发效率和组件化开发。以下是他们的一些相似性和差异性: 相似性 组件化:两者都支持组件化开发,允许开发者将UI拆分成独立的、可复用的组件。虚拟DOM&a…...
跨域 Cookie 共享
跨域请求经常遇到需要携带 cookie 的场景,为了确保跨域请求能够携带用户的认证信息或其他状态,浏览器提供了 withCredentials 这个属性。 如何在 Axios 中使用 withCredentials 为了在跨域请求中携带 cookie,需要在 Axios 配置中设置 withCr…...
全国青少年信息学奥林匹克竞赛(信奥赛)备考实战之计数器与累加器(一)
学习背景: 在现实生活中一些需要计数的场景下我们会用到计数器,如空姐手里记录乘客的计数器,跳绳手柄上的计数器等。累加器是累加器求和,以得到最后的结果。计数器和累加器它们虽然是基础知识,但是应用广泛࿰…...
红黑树(Red-Black Tree)
一、概念 红黑树(Red Black Tree)是一种自平衡的二叉搜索树,通过添加颜色信息来确保在进行插入和删除操作时,树的高度保持在对数级别,从而保证了查找、插入和删除操作的时间复杂度为 O(log n)。这种树可以很好地解决普…...
火电厂可视化助力提升运维效率
图扑智慧火电厂综合管理平台实现对火电厂关键设备和系统的实时监控和数据分析。图扑可视化不仅优化了运维流程,还增强了安全管理,有效提升了电厂整体运营效率。...
application.yml 和 bootstrap.yml
在 Spring Boot 中,application.yml 和 bootstrap.yml 都是用来配置应用程序的属性文件,通常用于环境配置、服务配置等。但是,它们有一些不同的用途和加载顺序。以下是它们之间的主要区别: 1. application.yml: 主要…...
电子应用设计方案-49:智能拖把系统方案设计
智能拖把系统方案设计 一、引言 随着人们生活水平的提高和对清洁效率的追求,智能拖把作为一种创新的清洁工具应运而生。本方案旨在设计一款功能强大、操作便捷、清洁效果出色的智能拖把系统。 二、系统概述 1. 系统目标 - 实现自动清洁地面,减轻用户劳…...
Model Context Protocol 精选资源列表
Model Context Protocol 精选资源列表 Model Context Protocol 精选资源列表什么是MCP?教程社区说明服务器实现📂 浏览器自动化☁️ 云平台💬 社交👤 数据平台🗄️ 数据库💻 开发者工具🧮 数据科…...
Windows 11 12 月补丁星期二修复了 72 个漏洞和一个零日漏洞
微软于 2024 年 12 月为 Windows 11 发布的补丁星期二修复了其产品生态系统中的 72 个漏洞,包括 Windows 通用日志文件系统驱动程序中一个被积极利用的零日漏洞。 这个严重漏洞可以通过基于堆的缓冲区溢出授予攻击者系统权限,使其成为此版本中优先级最高…...
Python毕业设计选题:基于Hadoop 的国产电影数据分析与可视化_django+spider
开发语言:Python框架:djangoPython版本:python3.7.7数据库:mysql 5.7数据库工具:Navicat11开发软件:PyCharm 系统展示 管理员登录 管理员功能界面 用户管理 免费电影管理 在线论坛 留言反馈 看板展示 系统…...
蓝桥杯我来了
最近蓝桥杯报名快要截止了,我们学校开始收费了,我们学校没有校赛,一旦报名缴费就是省赛,虽然一早就在官网上报名了,但是一直在纠结,和家人沟通,和朋友交流,其实只是想寻求外界的支持…...
大模型qiming面试内容整理-编码能力评估
编码能力评估是大模型相关岗位面试中非常关键的一环,面试官通常希望通过这个环节了解候选人对编程语言、算法与数据结构的掌握情况,以及其在实践中解决实际问题的能力。以下是编码能力评估的常见内容和类型,特别是针对机器学习、大模型和深度学习方向: 编程语言熟练度 ● P…...
Vivado ILA数据导出MATLAB分析
目录 ILA数据导出 分析方式一 分析方式二 有时候在系统调试时,数据在VIVADO窗口获取的信息有限,可结合MATLAB对已捕获的数据进行分析处理 ILA数据导出 选择信号,单击右键后,会有export ILA DATA选项,将其保存成CS…...
Linux内核 -- 字符设备之read write poll基本实现
Linux字符设备:read、write和poll函数实现及完整代码 1. read函数 原型 ssize_t read(struct file *file, char __user *buf, size_t count, loff_t *pos);实现步骤 检查用户缓冲区:使用copy_to_user将数据从内核空间复制到用户空间。返回已读取的字…...
linux部署ansible自动化运维
ansible自动化运维 1,编写ansible的仓库(比赛已经安装,无需关注) 1、虚拟机右击---设置---添加---CD/DVD驱动器---完成---确定 2、将ansible.iso的光盘连接上(右下角呈绿色状态) 3、查看光盘挂载信息 df -h…...
springboot421社区医疗服务可视化系统(论文+源码)_kaic
摘 要 传统办法管理信息首先需要花费的时间比较多,其次数据出错率比较高,而且对错误的数据进行更改也比较困难,最后,检索数据费事费力。因此,在计算机上安装社区医疗服务可视化系统软件来发挥其高效地信息处理的作用…...
vue渲染时闪光白屏问题怎么解决(笔记)
Vue渲染时出现闪光白屏问题,可能是因为页面内容需要较长时间才能加载完成,而在加载期间,页面会显示白屏或者空白内容,给用户体验带来负面影响。 解决方法: 为标签绑定 v-cloak 在样式中写 v-clock {displaÿ…...
duxapp 2024-12-09 更新 PullView可以弹出到中间,优化CLI使用体验
UI库 修复 Button 禁用状态失效的问题Modal 组件即将停用,请使用 PullView 基础库 PullView side 新增 center 指定弹出到屏幕中间PullView 新增 duration 属性,指定动画时长新增 useBackHandler hook 用来阻止安卓端点击返回键 RN端 修复 windows …...
vue调试插件vue Devtools下载安装
Vue.js Devtools_6.6.3_Chrome插件下载_极简插件 进图官网点击推荐下载下载该调试工具 解压缩找到扩展程序开启开发者模式 将解压缩的文件拖拽到该页面空白处,点击添加扩展程序 点击详情允许访问文件网址 页面右键检查可以发现已经成功添加该页面调试插件...
.net core使用AutoMapper
AutoMapper 是一个用于 .NET 平台的对象映射工具,它简化了不同对象类型之间的转换过程。在软件开发中,尤其是在分层架构的应用程序里,常常需要在不同的对象模型之间进行数据传递,例如从数据库实体到视图模型、DTO(数据…...
HTTP头注入
注入类漏洞经久不衰,多年保持在owasp Top 10的首位。今天就聊聊那些被人遗忘的http头注入。用简单的实际代码进行演示,让每个人更深刻的去认识该漏洞。 3|0HOST注入 在以往http1.0中并没有host字段,但是在http1.1中增加了host字段ÿ…...
110.【C语言】编写命令行程序(1)
目录 1.前置知识 "命令"的含义 运行C语言程序 2.介绍 main函数的参数 实验1 执行结果 实验2 执行结果 修改代码 实验3 分析 方法:遍历数组argv[]中的所有参数 执行结果 修改代码 执行结果 1.前置知识 "命令"的含义 WINR输入cmd,在cmd窗口下…...
k8s 之 StatefulSet
深入理解StatefulSet(一):拓扑状态 k8s有状态与无状态的区别 无状态服务:deployment Deployment被设计用来管理无状态服务的pod,每个pod完全一致.什么意思呢? 无状态服务内的多个Pod创建的顺序是没有顺序的. 无状态服务内的多…...
PTA 7-2 从身份证号码中提取出出生年月
分数 12 作者 崔孝凤 单位 山东理工大学 输入一个18位的身份证号码,提取出年份和月份并输出,请判断输入的号码是否是18位,如果不是请提示"Invalid data,input again!",并重新输入新的号码。 输入格式: 输入一个18位…...
Plugin - 插件开发04_Spring Boot中的SPI机制与Spring Factories实现
文章目录 Pre方案概览使用插件的好处Spring Boot中的SPI机制与Spring Factories实现1. Spring Boot中的SPI机制Spring Factories文件 2. Spring Factories实现原理3. Code3.1 定义一个服务接口3.2 定义 实现类3.3 配置 spring.factories 文件3.4 创建一个Controller来加载插件3…...
GUNS搭建
一、准备工作 源码下载: 链接: https://pan.baidu.com/s/1bJZzAzGJRt-NxtIQ82KlBw 提取码: criq 官方文档 二、导入代码 1、导入后端IDE 导入完成需要,需要修改yml文件中的数据库配置,改成自己的。 2、导入前端IDE 我是用npm安装的yarn npm…...
路径规划之启发式算法之十四:蜘蛛蜂优化算法(Spider Wasp Optimizer, SWO)
蜘蛛蜂优化算法(Spider Wasp Optimizer, SWO)是一种受自然界中蜘蛛蜂行为启发的元启发式智能优化算法。由Mohamed Abdel-Basset等人于2023年提出,算法模拟了雌性蜘蛛蜂的狩猎、筑巢和交配行为,具有独特的更新策略,适用于具有不同探索和开发需求的广泛优化问题。 一、算法背…...
OpenGL ES详解——多个纹理实现混叠显示
目录 一、获取图片纹理数据 二、着色器编写 1. 顶点着色器 2. 片元着色器 三、绑定和绘制纹理 1. 绑定纹理 2. 绘制纹理 四、源码下载 一、获取图片纹理数据 获取图片纹理数据代码如下: //获取图片1纹理数据 mTextureId loadTexture(mContext, R.mipmap.…...
Java多线程与线程池技术详解(八)
《星游记》 “如果只有傻瓜才相信梦想,那么就叫我大傻瓜吧!” 《一人之下》 “想走的路不好走,想做人不好做,都说是身不由己,不是废话么。己不由心,身又岂能由己!” 目录 上一篇博客习题讲解 编…...
2024年12月11日Github流行趋势
项目名称:maigret 项目维护者:soxoj, kustermariocoding, dependabot, fen0s, cyb3rk0tik项目介绍:通过用户名从数千个站点收集个人档案信息的工具。项目star数:12,055项目fork数:870 项目名称:uv 项目维护…...
ThinkPHP 6.0 PHP新手教程
1、系统配置文件 下面系统自带的配置文件列表及其作用: 配置文件名描述app.php应用配置cache.php缓存配置console.php控制台配置cookie.phpCookie配置database.php数据库配置filesystem.php磁盘配置lang.php多语言配置log.php日志配置middleware.php中间件配置rou…...
【Excel学习记录】02-单元格格式设置
1.单元格格式工具美化表格 单元格格式位置 选中单元格,右键→设置单元格格式 合并居中 跨越合并 字体类型、大小、颜色、填充底纹、边框 斜线 软回车:alt enter 格式刷 2.单元格数字格式 格式不影响数值,只是展示形式 日期本质也是数…...
Paimon Tag和Branch创建文件存储过程
结论: 如果data-file被引用则不会被压缩,压缩仅针对未被引用的文件,创建tag时候根据当前快照进行创建 1、实际表和Manifest的内容 查看tag的内容 select * from table$tags;或者直接查看tag ossutil cat oss://test-dataware/warehouse/te…...