万字解析设计模式之单例模式
一、概述
1.1简介
单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
1.2结构
单例模式的主要有以下角色:
- 单例类。只能创建一个实例的类
- 访问类。使用单例类
1.3单例模式的实现
单例设计模式分类两种:
饿汉式:类加载就会导致该单实例对象被创建
懒汉式:类加载不会导致该单实例对象被创建,而是首次使用该对象时才会创建
饿汉式-方式1(静态变量方式)
package com.yanyu.Singleton;public class Singleton {//私有构造方法private Singleton() {}//在成员位置创建该类的对象private static Singleton instance = new Singleton();//对外提供静态方法获取该对象public static Singleton getInstance() {return instance;}
}
这是一个单例模式的实现,确保在程序运行中只有一个该类的实例对象存在。
具体实现:
1. 将类的构造方法私有化,防止外部直接通过构造方法创建对象。
2. 在类的成员位置创建一个私有静态的对象 instance,确保了Singleton类不能在外部被实例化,只能在类内部创建对象。
3. 对外提供一个静态的方法 getInstance(),返回该类的对象 instance,确保在程序中只有一个该类的实例对象存在。
4. 由于 instance 是私有的静态成员,在类加载时就已经创建了该对象,所以在 getInstance() 方法中直接返回 instance 即可。由于instance是static成员,类的所有对象共享同一份instance,从而保证了在应用中只有一个Singleton对象被创建。
需要注意的是,该实现方法并未考虑线程安全性,可能会存在线程安全问题
使用单例模式可以避免重复创建对象,节省内存空间,并且可以确保对象在程序中只有一个实例,保证数据一致性。
package com.yanyu.Singleton;public class client{public static void main(String[]args){//创建singletion类的对象Singleton instance = Singleton.getInstance();Singleton instance1 = Singleton.getInstance();//判断获取到的两个是否是同一个对象System.out.println(instance == instance1);}
}

说明:
该方式在成员位置声明Singleton类型的静态变量,并创建Singleton类的对象instance。instance对象是随着类的加载而创建的。如果该对象足够大的话,而一直没有使用就会造成内存的浪费。
饿汉式-方式2(静态代码块方式)
package com.yanyu.Singleton;public class Singleton {//私有构造方法private Singleton() {}//在成员位置创建该类的对象private static Singleton instance;static {instance = new Singleton();}//对外提供静态方法获取该对象public static Singleton getInstance() {return instance;}
}
这是一种饿汉式单例模式的实现方式,通过静态代码块来初始化单例对象,保证了线程安全性和唯一性。在类被加载时就已经创建了单例对象,因此也叫做饿汉式单例模式。
因为类加载是线程安全的,不需要考虑多线程的情况。
但是,由于对象是在类被加载时就创建的,因此可能会造成资源浪费。如果该单例对象在程序运行期间一直没有被使用,那么一直占据着一部分内存空间,会对系统的性能产生一定的影响。
另外,由于单例对象是静态的,所以对于某些需要动态实现的场景,该实现方式并不合适。
懒汉式-方式1(线程不安全)
package com.yanyu.Singleton;public class Singleton {//私有构造方法private Singleton() {}//在成员位置创建该类的对象private static Singleton instance;//对外提供静态方法获取该对象public static Singleton getInstance() {if(instance == null) {instance = new Singleton();}return instance;}
}
具体实现是通过私有构造方法来禁止类的外部创建对象,然后在类的成员位置创建该类的唯一对象instance,并通过静态方法getInstance()来返回该对象。在getInstance()方法中,先判断instance是否为null,如果是则创建该对象,否则直接返回该对象。
这种实现方式称为懒汉式单例模式,因为只有在第一次调用getInstance()方法时才会创建对象,而之后的调用都会直接返回已创建的对象。从而避免了多个实例导致的资源浪费和数据不一致等问题。
懒汉式-方式2(线程安全)
package com.yanyu.Singleton;public class Singleton {//私有构造方法private Singleton() {}//在成员位置创建该类的对象private static Singleton instance;//对外提供静态方法获取该对象public static synchronized Singleton getInstance() {if(instance == null) {instance = new Singleton();}return instance;}
}
懒汉式相对于饿汉式来说,它是延迟加载的,只有在真正需要使用该对象时才会进行初始化,这样可以节省资源和减少初始化时间。但是,懒汉式实现需要考虑线程安全问题,因为在多线程环境下,如果多个线程同时调用 getInstance() 方法,可能会创建多个实例,导致单例模式失效。因此,需要使用 synchronized 关键字在方法内部进行同步,保证线程安全。
但是在getInstance()方法上添加了synchronized关键字,导致该方法的执行效果特别低。
懒汉式-方式3(双重检查锁)
对于
getInstance()方法来说,绝大部分的操作都是读操作,读操作是线程安全的,所以我们没必让每个线程必须持有锁才能调用该方法,我们需要调整加锁的时机。由此也产生了一种新的实现模式:双重检查锁模式
package com.yanyu.Singleton;public class Singleton {//私有构造方法private Singleton() {}private static Singleton instance;//对外提供静态方法获取该对象public static Singleton getInstance() {//第一次判断,如果instance不为null,不进入抢锁阶段,直接返回实际if(instance == null) {synchronized (Singleton.class) {//抢到锁之后再次判断是否为空if(instance == null) {instance = new Singleton();}}}return instance;}
}
是怕多线程创建多个对象,如果不为空直接返回提高效率,为空就要加锁防止
首先进行一次非空判断,如果instance为null,才进行同步代码块的抢锁,再次判断instance是否为空,确保只有一个线程可以创建对象。
双重检查锁模式是一种非常好的单例实现模式,解决了单例、性能、线程安全问题,上面的双重检测锁模式看上去完美无缺,其实是存在问题,在多线程的情况下,可能会出现空指针问题,出现问题的原因是JVM在实例化对象的时候会进行优化和指令重排序操作。
要解决双重检查锁模式带来空指针异常的问题,只需要使用
volatile关键字,volatile关键字可以保证可见性和有序性。
指令重排序问题解释
在多线程情况下,指令重排序可能会导致该模式的失效。当一个线程抢到锁之后,由于指令重排序的影响,实例变量可能会先被赋值到内存中,但是还没有调用构造函数,而此时另一个线程进入该方法,会认为instance不为空直接返回实例,但是此时实例并没有完成初始化,会导致程序出错。
为了避免这种情况,需要在instance前添加volatile关键字,保证它能正确的被初始化。这样可以确保其他线程在获取instance的时候,总是从主内存中获取,而不是线程的本地内存中获取,从而避免了指令重排序带来的问题。
package com.yanyu.Singleton;public class Singleton {//私有构造方法private Singleton() {}private static volatile Singleton instance;//对外提供静态方法获取该对象public static Singleton getInstance() {//第一次判断,如果instance不为null,不进入抢锁阶段,直接返回实际if(instance == null) {synchronized (Singleton.class) {//抢到锁之后再次判断是否为空if(instance == null) {instance = new Singleton();}}}return instance;}
}
这是一种线程安全的懒汉式单例模式实现方式,主要特点有:
1. 构造函数私有化,确保该类不能在外部通过构造函数来创建对象。
2. 使用 volatile 关键字修饰 instance,保证在多线程环境下 instance 的可见性。
3. getInstance 方法加入双重检查锁,确保在多线程环境下只有一个线程能够创建 Singleton 实例,并且只有在 instance 为 null 的情况下才会创建实例。
4. 使用 synchronized 关键字对 instance 进行加锁,保证在多线程环境下只有一个线程能够进入创建实例的代码块。
5. 返回 Singleton 实例的方法为静态方法,能够在类的外部方便地获取该对象。
这种实现方式既保证了线程安全,又减少了同步的开销,是一种比较常用的单例模式实现方式。
懒汉式-方式4(静态内部类方式)
静态内部类单例模式中实例由内部类创建,由于 JVM 在加载外部类的过程中, 是不会加载静态内部类的, 只有内部类的属性/方法被调用时才会被加载, 并初始化其静态属性。静态属性由于被 static 修饰,保证只被实例化一次,并且严格保证实例化顺序。
package com.yanyu.Singleton;public class Singleton {//私有构造方法private Singleton() {}private static class SingletonHolder {private static final Singleton INSTANCE = new Singleton();}//对外提供静态方法获取该对象public static Singleton getInstance() {return SingletonHolder.INSTANCE;}
}
这是一种利用静态内部类实现的线程安全的单例模式。在类加载器加载类的时候,静态内部类 SingletonHolder 不会被初始化,只有在 getInstance() 方法第一次被调用时,才会被加载进内存并实例化,同时保证了线程安全。这种方式既保证了线程安全,也避免了同步带来的性能损失,同时也实现了延迟加载。由于这种方式不需要加锁,因此效率比较高。
这种方式的核心思想是使用静态内部类来持有单例实例,因为静态内部类只会被加载一次,所以它的成员变量也只会被初始化一次,从而保证了线程安全。同时,通过将单例对象的实例化延迟到内部类加载时进行,也实现了懒加载。
枚举方式
枚举类实现单例模式是极力推荐的单例实现模式,因为枚举类型是线程安全的,并且只会装载一次,设计者充分的利用了枚举的这个特性来实现单例模式,枚举的写法非常简单,而且枚举类型是所用单例实现中唯一一种不会被破坏的单例实现模式。
package com.yanyu.Singleton;public enum Singleton {INSTANCE;
}
INSTANCE是一个枚举对象,也就是该单例类的唯一实例。通过这种方式获取单例对象,可以保证在任何情况下都只有一个实例对象存在。即使在多线程的情况下也是安全的。可以避免多线程问题和反射攻击
package com.yanyu.Singleton;public class client{public static void main(String[]args){//创建singletion类的对象Singleton instance = Singleton.INSTANCE;Singleton instance1 = Singleton.INSTANCE;//判断获取到的两个是否是同一个对象System.out.println(instance == instance1);}
}
在使用枚举类型实现单例模式时,反射攻击是无效的,因为枚举类型的构造方法是私有的,并且只会在类加载时被调用一次,保证了单例的唯一性。在使用反射获取该单例时,会抛出异常,因为枚举类型不支持反射创建实例。因此,枚举类型实现单例模式是一种安全可靠的方式。
1.4破坏单例模式的方式
使上面定义的单例类(Singleton)可以创建多个对象,枚举方式除外。有两种方式,分别是序列化和反射。
序列化反序列化
Singleton类:
package com.yanyu.Singleton;import java.io.Serializable;public class Singleton implements Serializable {//私有构造方法private Singleton() {}private static class SingletonHolder {private static final Singleton INSTANCE = new Singleton();}//对外提供静态方法获取该对象public static Singleton getInstance() {return SingletonHolder.INSTANCE;}
}
Test类:
package com.yanyu.Singleton;import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;public class Test {public static void main(String[] args) throws Exception {//往文件中写对象//writeObject2File();//从文件中读取对象Singleton s1 = readObjectFromFile();Singleton s2 = readObjectFromFile();//判断两个反序列化后的对象是否是同一个对象System.out.println(s1 == s2);}private static Singleton readObjectFromFile() throws Exception {//创建对象输入流对象ObjectInputStream ois = new ObjectInputStream(new FileInputStream("C:\\Users\\Think\\Desktop\\a.txt"));//第一个读取Singleton对象Singleton instance = (Singleton) ois.readObject();return instance;}public static void writeObject2File() throws Exception {//获取Singleton类的对象Singleton instance = Singleton.getInstance();//创建对象输出流ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("C:\\Users\\Think\\Desktop\\a.txt"));//将instance对象写出到文件中oos.writeObject(instance);}
}
上面代码运行结果是false,表明序列化和反序列化已经破坏了单例设计模式。
当单例模式中的实例被序列化成字节流并保存到文件系统或数据库中时,如果后续读取对象并反序列化后,会生成一个新的实例,从而破坏了单例模式的原则。
这是因为,在序列化和反序列化过程中,Java内部使用了一个特殊的方法来创建对象,该方法不会调用任何构造函数,也不会检查是否已经存在该对象的实例。因此,如果单例模式本身没有实现序列化和反序列化的特殊处理,就会导致破坏单例模式。
序列化会将对象转换为一个字节序列,以便在网络上传输或保存到文件中。当反序列化时,会将字节序列转换回对象。当单例类被序列化为字节流时,字节流中不包含单例类的状态,当反序列化时,新的实例会被创建出来,这样就违反了单例模式的原则,一个单例类就被破坏了。
反射
Singleton类:
package com.yanyu.Singleton;public class Singleton {//私有构造方法private Singleton() {}private static volatile Singleton instance;//对外提供静态方法获取该对象public static Singleton getInstance() {if(instance != null) {return instance;}synchronized (Singleton.class) {if(instance != null) {return instance;}instance = new Singleton();return instance;}}
}
Test类:
package com.yanyu.Singleton;import java.lang.reflect.Constructor;public class Test {public static void main(String[] args) throws Exception {//获取Singleton类的字节码对象Class clazz = Singleton.class;//获取Singleton类的私有无参构造方法对象Constructor constructor = clazz.getDeclaredConstructor();//取消访问检查constructor.setAccessible(true);//创建Singleton类的对象s1Singleton s1 = (Singleton) constructor.newInstance();//创建Singleton类的对象s2Singleton s2 = (Singleton) constructor.newInstance();//判断通过反射创建的两个Singleton对象是否是同一个对象System.out.println(s1 == s2);}
}
上面代码运行结果是
false,表明反射已经破坏了单例设计模式
单例模式可以被反射机制破坏,因为反射机制可以通过修改类的私有构造方法来创建一个新的实例,这样就违背了单例模式的原则。此外,反射还可以通过修改单例类中的字段来改变单例实例的状态,从而破坏单例模式的行为。
1.5 问题的解决
序列化、反序列方式解决
在Singleton类中添加readResolve()方法,在反序列化时被反射调用,如果定义了这个方法,就返回这个方法的值,如果没有定义,则返回新new出来的对象。
Singleton类:
package com.yanyu.Singleton;import java.io.Serializable;public class Singleton implements Serializable {//私有构造方法private Singleton() {}private static class SingletonHolder {private static final Singleton INSTANCE = new Singleton();}//对外提供静态方法获取该对象public static Singleton getInstance() {return SingletonHolder.INSTANCE;}/*** //当,进行反序列化时,会白动调用该力法,将该方法的返回值直接返回*/private Object readResolve() {return SingletonHolder.INSTANCE;}
}
当反序列化时,会先调用 readObject() 方法,如果该类中存在 readResolve() 方法,会在 readObject() 方法执行之后,将 readResolve() 方法的返回值直接返回,从而确保只有一个实例。在该示例中,readResolve() 方法返回 SingletonHolder 的 INSTANCE,即单例对象的唯一实例。
反射方式解决
为了防止这种破解,可以在单例类的构造函数中添加判断,如果已存在实例,则抛出异常或返回已存在的实例。这样,在通过反射调用私有构造函数时,就会抛出异常或返回已存在的实例,从而阻止破解单例模式。
package com.yanyu.Singleton;public class Singleton {private static boolean flag = false;//私有构造方法private Singleton() {/*反射破解单例模式需要添加的代码*/synchronized (Singleton.class){if (flag){throw new RuntimeException("不能创建多个对象");}flag = true;}}private static volatile Singleton instance;//对外提供静态方法获取该对象public static Singleton getInstance() {if(instance != null) {return instance;}synchronized (Singleton.class) {if(instance != null) {return instance;}instance = new Singleton();return instance;}}
}
上述代码中的防止反射破解的代码可以阻止通过反射调用私有构造方法创建多个实例。但是,如果通过反射修改了flag标志位,就可以绕过这个限制,破坏单例模式。
为了进一步防止通过反射破解单例模式,可以在getInstance方法中添加判断,如果已存在实例,再次调用构造方法时,直接返回已存在的实例。这样,即使通过反射修改了flag标志位,也无法创建新的实例,从而保证单例模式的唯一性。
1.6JDK源码解析-Runtime类
从上面源代码中可以看出Runtime类使用的是恶汉式(静态属性)方式来实现单例模式的。
使用Runtime类中的方法
public class RuntimeDemo {public static void main(String[] args) throws IOException {//获取Runtime类对象Runtime runtime = Runtime.getRuntime();
//返回 Java 虚拟机中的内存总量。System.out.println(runtime.totalMemory());//返回 Java 虚拟机试图使用的最大内存量。System.out.println(runtime.maxMemory());
//创建一个新的进程执行指定的字符串命令,返回进程对象Process process = runtime.exec("ipconfig");//获取命令执行后的结果,通过输入流获取InputStream inputStream = process.getInputStream();byte[] arr = new byte[1024 * 1024* 100];int b = inputStream.read(arr);System.out.println(new String(arr,0,b,"gbk"));}
}
1.7应用案例
- Windows 的 Task Manager(任务管理器)。
- Windows 的 Recycle Bin(回收站)。在整个系统运行过程中,回收站一直维护着仅有的一个实例。
- 网站的计数器,一般也是采用单例模式实现,否则难以同步。
- 应用程序的日志应用,一般都何用单例模式实现,这一般是由于共享的日志文件一直处于打开状态,因为只能有一个实例去操作,否则内容不好追加。
- Web 应用的配置对象的读取,一般也应用单例模式,这个是由于配置文件是共享的资源。
二、实验
任务描述
在企业网站后台系统中,一般会将网站统计单元进行独立设计,比如登录人数的统计、IP 数量的计数等。在这类需要完成全局统计的过程中,就会用到单例模式,即整个系统只需要拥有一个计数的全局对象。
本关任务:模拟网站登录,高并发场景。模拟 10 个登录线程,程序输出登录总数。
实现要点
- 在类中添加一个私有静态成员变量用于保存单例实例。
- 声明一个公有静态构建方法用于获取单例实例。
- 在静态方法中实现"延迟初始化"。 该方法会在首次被调用时创建一个新对象, 并将其存储在静态成员变量中。 此后该方法每次被调用时都返回该实例。
- 将类的构造函数设为私有。 类的静态方法仍能调用构造函数, 但是其他对象不能调用。
- 检查客户端代码, 将对单例的构造函数的调用替换为对其静态构建方法的调用。
编程要求
本任务有三个文件“Login.java”、“Client.java”和“Singleton.java”,在右侧编辑器 Begin-End 内补充 Singleton 中代码,其它文件请阅读代码
Singleton.java
package step1;import java.util.concurrent.atomic.AtomicLong;public class Singleton {private static Singleton instance;//AtomicLong是以原子方式操作long值的类,作用是保证并发时线程安全的累加private AtomicLong count = new AtomicLong(0);/********** Begin *********///此处增加Singleton的构造函数private Singleton() {// 私有化构造函数,防止外部实例化}/********** End *********/public static Singleton GetInstance(){/********** Begin *********///考虑线程安全问题if (instance == null) {synchronized (Singleton.class) {if (instance == null) {instance = new Singleton();}}}return instance;/********** End *********/}public AtomicLong getCount() {return count;}public void setCount() {count.addAndGet(1);}
}
Login.java
package step1;
//Runnable 接口由其实现类来由线程执行对应的实例。对于实现类必须是实现方法 run
public class Login implements Runnable{private String loginname;public String getLoginname() {return loginname;}public void setLoginname(String loginname) {this.loginname = loginname;}@Overridepublic void run() {Singleton lazySingleton =Singleton.GetInstance();lazySingleton.setCount();/*调试时观察System.out.println(getLoginname()+"登录成功."+lazySingleton);*/}
}
Client.java
package step1;public class Client {public final static int num = 10;public static void main(String[] args) throws InterruptedException {///创建10个线程,模拟10个用户登录Thread[] threads = new Thread[num];for (int i = 0; i < num; i++) {Login login = new Login();login.setLoginname("" + String.format("%2s", (i + 1)) + "号用户");//创建了线程threads[i],并把login对象(已实现Runnable接口)放入线程中threads[i]=new Thread(login);//线程状态转换为RUNNABLEthreads[i].start();}for (Thread thread : threads) {//Client等待线程结束之后才能继续运行,防止最后一行的System.out.println提前运行thread.join();}System.out.println("网站共有"+Singleton.GetInstance().getCount()+"个用户登录");}
}
相关文章:
万字解析设计模式之单例模式
一、概述 1.1简介 单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保…...
vue2.x 二次封装element ui 中的el-dialog
在做后台管理系统的时候,dialog组件是我们使用频率比较高的组件,但是有一些需求现有的组件是不满足的。因此会需要我们做二次封装。 组件本身的属性我们保留,只需要根据需求添加,然后在使用的时候props去拿取使用就可以了。 本次遇…...
ssh连接Ubuntu虚拟机出现connection reset by ip地址 port 22怎么解决
使用前提:我是用Windows去连接安装在本机的Ubuntu虚拟机的时候出现的这个问题。 解决的方法:我使用了很多网络上方法,都没有用,发现我把IP地址搞错了 请继续看下去,因为有可能你会错过解决的方法。 在Windows网络连…...
树莓派4B安装ffmpeg
环境: piraspberrypi:~/x264 $ lsb_release -aNo LSB modules are available.Distributor ID: RaspbianDescription: Raspbian GNU/Linux 10 (buster)Release: 10Codename: buster 装H264 git clone --depth 1 https://code.videolan.org/video…...
LeetCode|动态规划|1035. 不相交的线 、53. 最大子数组和
目录 一、1035. 不相交的线 1.题目描述 2.解题思路 3.代码实现 二、53. 最大子数组和 1.题目描述 2.解题思路 3.代码实现(动态规划解法) 一、1035. 不相交的线 1.题目描述 在两条独立的水平线上按给定的顺序写下 nums1 和 nums2 中的整数。 现…...
一体式IO模块:汽车行业的数字化转型助推器
随着市场经济需求的不断增长,汽车行业的自动化和智能化已经成为行业发展的必然趋势。在这个背景下,汽车行业的工作流程变得越来越复杂,工业机器人的广泛应用为汽车生产提供了强有力的支持,它们扮演着装配工、操作工、焊接工等多种…...
OpenCV官方教程中文版 —— Hough 直线变换
OpenCV官方教程中文版 —— Hough 直线变换 前言一、原理二、OpenCV 中的霍夫变换三、Probabilistic Hough Transform 前言 目标 • 理解霍夫变换的概念 • 学习如何在一张图片中检测直线 • 学习函数:cv2.HoughLines(),cv2.HoughLinesP() 一、原理…...
【Axure高保真原型】百分比堆叠柱状图
今天和大家分享百分比堆叠柱状图的的原型模板,鼠标移入堆叠柱状图后,会显示数据弹窗,里面可以查看具体项目对应的数据和占比。那这个原型模板是用中继器制作的,所以使用也很方便,只需要在中继器表格里维护项目数据信息…...
Vue.js中的双向数据绑定(two-way data binding)
聚沙成塔每天进步一点点 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 欢迎来到前端入门之旅!感兴趣的可以订阅本专栏哦!这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发…...
TFN 2.5G SDH传输分析仪 FT100-D300S
今天给大家带来一款TFN 2.5G SDH传输分析仪--TFN FT100-D300S. D300S SDH测试模块,是FT100智能网络测试平台产品家族的一部分,是一个坚固耐用、锂电池超长供电的传统PDH/SDH测试解决方案,支持2.5Gbps到2.048Mbps速率的传输链路测试。支持在线…...
电脑录像功能在哪?一文帮你轻松破解
“电脑录像功能在哪里呀?最近因工作上的原因,需要使用电脑来录像,但是找了一上午都找不到在哪里,眼看已经快没时间了,现在真的很急,希望大家帮帮我。” 电脑已经成为了人们生活和工作中必不可少的工具&…...
基于长短期神经网络的可上调容量PUP预测,基于长短期神经网络的可下调容量PDO预测,LSTM可调容量预测
目录 背影 摘要 代码和数据下载:基于长短期神经网络的可上调容量PUP预测,基于长短期神经网络的可下调容量PDO预测,LSTM可调容量预测(代码完整,数据齐全)资源-CSDN文库 https://download.csdn.net/download/abc991835105/88230834 LSTM的基本定义 LSTM实现的步骤 基于长短…...
站群服务器有哪些优势?
站群服务器有哪些优势? 站群服务器是单独为一个网站或者多个网站配置独立IP的一种服务器。企业或是用户如果想组建多个网站的话就需要用站群服务器了。 站群服务器可以提高搜索引擎多个网站的关注度,提高网站文章的收录以及网站文章的访问量。站群服务器有哪些优势…...
故障诊断模型 | Maltab实现LSTM长短期记忆神经网络故障诊断
文章目录 效果一览文章概述模型描述源码设计参考资料效果一览 文章概述 故障诊断模型 | Maltab实现LSTM长短期记忆神经网络故障诊断 模型描述 长短记忆神经网络——通常称作LSTM,是一种特殊的RNN,能够学习长的依赖关系。 他们由Hochreiter&Schmidhuber引入,并被许多人进行了…...
【WSL 2】Windows10 安装 WSL 2,并配合 Windows Terminal 和 VSCode 使用
【WSL 2】Windows10 安装 WSL 2,并配合 Windows Terminal 和 VSCode 使用 1 安装 Windows Terminal2 安装 WSL 23 在 Windows 文件资源管理器中打开 WSL 项目4 在 VSCode 中使用 WSL 24.1 必要准备4.2 从 VSCode 中 Connect WSL4.3 从 Linux 中打开 VSCode 1 安装 W…...
DbVisualizer和DBeaver启动不来,启动报错
启动报错 大多数启动报错都是因为你没有用管理员身份运行程序,提示的错误都是八竿子打不着的什么jdk、jvm问题。 比如DbVisualizer提示什么jvm配置参数,实际dbvis.exe 用管理员身份打开即可(右键 dbvis.exe->属性->兼容性->勾上 “…...
sftp连接远程服务器命令
...
el-select 、el-option 常见用法
<template> <div> // 可以多选 // 添加小叉,点击清空选择器 <el-select v-model"selectedValue" multiple disabled clearable filterable > <el-option …...
奇富科技引领大数据调度革命:高效、稳定、实时诊断
日前,在世界最大的开源基金会 Apache旗下最为活跃的项目之一DolphinScheduler组织的分享活动上,奇富科技的数据平台专家刘坤元应邀为国内外技术工作者献上一场题为《Apache DolphinScheduler在奇富科技的优化实践》的精彩分享,为大数据任务调…...
9.Python3-注释
题记 python3注释 单行注释 # 这是一个注释 print("Hello, World!") 多行注释 单引号 #!/usr/bin/python3 这是多行注释,用三个单引号 这是多行注释,用三个单引号 这是多行注释,用三个单引号print("Hello, World!"…...
102. 在控制平面主机名更改后恢复 Rancher 配置的 RKE2 集群
Environment 环境 Rancher provisioned RKE2 downstream cluster control plane node hostname changed, without removing the node from the cluster. Rancher 配置了 RKE2 下游集群控制平面节点的主机名更改,但未将该节点从集群中移除。 Procedure 程序It is …...
L1-064 估值一亿的ai核心代码 (分数20)字符串处理
•无论用户说什么,首先把对方说的话在一行中原样打印出来;•消除原文中多余空格:把相邻单词间的多个空格换成 1 个空格,把行首尾的空格全部删掉,把标点符号前面的空格删掉; •把原文中所有大写英文字母变成…...
5分钟掌握:PowerToys Image Resizer让图片批量处理效率提升10倍
5分钟掌握:PowerToys Image Resizer让图片批量处理效率提升10倍 【免费下载链接】PowerToys Microsoft PowerToys is a collection of utilities that supercharge productivity and customization on Windows 项目地址: https://gitcode.com/GitHub_Trending/po/…...
从选型到焊接:一份给嵌入式新手的晶振避坑指南(含32.768KHz实例)
从选型到焊接:嵌入式开发者的晶振实战避坑手册 第一次点亮自己设计的电路板时,那颗小小的晶振就像电子世界的心跳起搏器。记得三年前我为一个智能家居项目调试STM32时,连续三天卡在"晶振不起振"的问题上——电路图反复检查无误&…...
别再只会用Arduino了!用ESP8266+MicroPython快速搭建你的第一个物联网小项目(附完整代码)
用MicroPython解锁ESP8266的物联网潜能:10分钟搭建温湿度监测系统 当提到物联网开发时,大多数人的第一反应可能是Arduino和C。但今天,我要带你体验一种更高效、更友好的方式——MicroPython。这种基于Python的嵌入式编程语言,让物…...
Python EXE逆向解密终极指南:从打包程序到源码还原完整教程
Python EXE逆向解密终极指南:从打包程序到源码还原完整教程 【免费下载链接】python-exe-unpacker A helper script for unpacking and decompiling EXEs compiled from python code. 项目地址: https://gitcode.com/gh_mirrors/py/python-exe-unpacker Pyt…...
cool-admin(midway版)前端表单验证:AsyncValidator与异步校验完整指南
cool-admin(midway版)前端表单验证:AsyncValidator与异步校验完整指南 【免费下载链接】cool-admin-midway 🔥 cool-admin(midway版)一个很酷的后台权限管理框架,模块化、插件化、CRUD极速开发,永久开源免费,基于midwa…...
Klipper温度曲线优化终极指南:三步解决95%打印质量问题
Klipper温度曲线优化终极指南:三步解决95%打印质量问题 【免费下载链接】klipper Klipper is a 3d-printer firmware 项目地址: https://gitcode.com/GitHub_Trending/kl/klipper 你是否曾为PLA打印翘边、ABS层间开裂或PETG拉丝问题而烦恼?这些问…...
深入解析Python中ort.InferenceSession的底层实现与性能优化
1. 揭开ort.InferenceSession的神秘面纱 第一次接触ort.InferenceSession时,我完全被它的性能震惊了。作为一个用Python加载ONNX模型的标准入口,它看起来就是个普通的类实例化操作,但背后却隐藏着C和Python的完美协作。这种设计让开发者既能享…...
Wireshark抓包实战:用一道CTF题彻底搞懂IP分片与UDP重组
Wireshark抓包实战:用一道CTF题彻底搞懂IP分片与UDP重组 在网络安全竞赛中,一个看似简单的UDP传输任务可能隐藏着协议层面的精妙设计。去年CyBRICS赛事中的lx100题目就完美诠释了这一点——参赛者需要从相机传输的UDP流量中提取图片,而真正的…...
