JVM - 1.类加载子系统

news2024/9/21 2:45:15

1.类加载子系统

1.作用

  • 1.负责从文件系统或网络中加载字节码(.class)文件,即将物理磁盘上的字节码文件加载到内存中,生成供程序使用的类对象
    在这里插入图片描述
  • 2.字节码文件要求在文件开头有特定的文件标识(CA FE BA BE)
  • 3.类加载器(ClassLoader)只负责字节码文件的加载,是否可运行,由执行引擎(Execution Engine)决定
  • 4.类加载器是指特定的加载器,而类加载子系统是一个系统流程的统称
  • 5.加载生成的的类信息存放在称为方法区的内存空间中
  • 6.除了类的信息外,方法区还会存放运行时常量池(字节码文件中的Constant pool在运行时加载到内存中称为运行时常量池)信息,可能还包括字符串字面量数字常量,参考附录1

2.角色

在这里插入图片描述

  • 1.Car类通过编译器(javac)编译后生成Car.calss字节码文件并存在于本地磁盘上
  • 2.程序执行时字节码文件通过类加载器加载到JVM中,生成一个类对象
  • 3.通过该类对象可获取到类的构造器,根据该构造器可实例化出多个实例,通过实例的getClass方法也可以获取类对象本身
    在这里插入图片描述
    在这里插入图片描述
  • 4.字节码文件加载到JVM中,被称为DNA元数据模板,放在方法区
  • 5..class文件 -> JVM -> 元数据模板,该过程通过类加载器(Class Loader)实现
  • 6.物理磁盘上的字节码文件通过二进制流的方式加载到内存

3.类的加载过程

在这里插入图片描述
在这里插入图片描述

1.加载

  • 1.通过一个类的全限定名获取定义此类的二进制字节流
    在这里插入图片描述
  • 2.将这个字节流所代表的静态存储结构转化为方法区运行时数据结构
  • 3.方法区:抽象概念;落地实现:1.7及以前叫永久代,之后叫元空间
  • 4.并在内存中生成一个代表这个类的java.lang.Class对象,作为方法区该对象各种数据的访问入口
    在这里插入图片描述
    在这里插入图片描述

2.链接

1.验证(Verify)
  • 1.确保class文件的字节流包含信息符合当前虚拟机要求,保证被加载类的正确性,不会危害虚拟机的自身安全
  • 2.主要包括四种验证:文件格式验证,元数据验证,字节码验证,符号引用验证
  • 3.例:文件标识验证(CA FE BA BE),使用Binary Viewer工具进行查看
    在这里插入图片描述
2.准备(Prepare)
  • 1.为类变量/静态变量分配内存空间并且设置该类变量默认初始值
    • 1.成员变量:定义在方法体和语句块之外,不属于任何一个方法,作用域是整个类
      • 1.静态变量/类变量:用 static 修饰的成员变量
      • 2.全局变量/实例变量:无 static 修饰的成员变量
    • 2.局部变量:定义在方法或代码块中的变量,作用域是其所在的代码块
  • 2.例如:
    • 1.private static int a = 1,准备阶段会赋默认初始值为0,即a=0,然后在初始化(initial)阶段会赋值a = 1
  • 3.注意
    • 1.不同类型的类变量默认初始值不同
    • 2.这里不包含final修饰的static类变量,因为final修饰的是常量而不是变量,常量后期不会再被修改,所以在编译阶段就已经分配值,准备阶段只是显示初始化
    • 3.这里不会为实例变量默认初始化,因为当前还没创建对象,只是加载过程,类变量会分配在方法区中,而实例变量是会随着对象一起分配到Java堆
3.解析(Resolve)
  • 1.将常量池内的符号引用转换为直接引用的过程
  • 2.事实上解析操作往往会在JVM执行完初始化后再执行
  • 3.符号引用:一组符号来描述所引用的目标,符号引用的字面量形式明确定义在《java虚拟机规范》的class文件格式中
  • 4.直接引用:直接指向目标的指针,相对偏移量或一个间接定位到目标的句柄
  • 5.解析动作主要针对类或接口,字段,类方法,接口方法,方法类型等
  • 6.通过反编译可以查看class文件中的符号引用和直接引用
package com.java;

public class HelloApp {
   private static int a = 1;

   public HelloApp() {
   }

   public static void main(String[] args) {
       System.out.println(a);
   }
}
如下如示:Constant pool是常量池,其中以#开头的是符号引用,其余的是直接引用

F:\文档\笔记\代码\JVMDemo\out\java>javap -v HelloApp.class
Classfile /F:/文档/笔记/代码/JVMDemo/out/java/HelloApp.class
 Last modified 2022-11-9; size 608 bytes
 MD5 checksum 5964d34bba8f8bf4e817be8fe95a17fe
 Compiled from "HelloApp.java"
public class com.java.HelloApp
 minor version: 0
 major version: 52
 flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
  #1 = Methodref          #6.#23         // java/lang/Object."<init>":()V
  #2 = Fieldref           #24.#25        // java/lang/System.out:Ljava/io/PrintStream;
  #3 = Fieldref           #5.#26         // com/atguigu/java/HelloApp.a:I
  #4 = Methodref          #27.#28        // java/io/PrintStream.println:(I)V
  #5 = Class              #29            // com/atguigu/java/HelloApp
  #6 = Class              #30            // java/lang/Object	<=符号引用 
  #7 = Utf8               a	<=直接引用
  #8 = Utf8               I
  #9 = Utf8               <init>
 #10 = Utf8               ()V
 #11 = Utf8               Code
 #12 = Utf8               LineNumberTable
 #13 = Utf8               LocalVariableTable
 #14 = Utf8               this
 #15 = Utf8               Lcom/atguigu/java/HelloApp;
 #16 = Utf8               main
 #17 = Utf8               ([Ljava/lang/String;)V
 #18 = Utf8               args
 #19 = Utf8               [Ljava/lang/String;
 #20 = Utf8               <clinit>
 #21 = Utf8               SourceFile
 #22 = Utf8               HelloApp.java
 #23 = NameAndType        #9:#10         // "<init>":()V
 #24 = Class              #31            // java/lang/System
 #25 = NameAndType        #32:#33        // out:Ljava/io/PrintStream;
 #26 = NameAndType        #7:#8          // a:I
 #27 = Class              #34            // java/io/PrintStream
 #28 = NameAndType        #35:#36        // println:(I)V
 #29 = Utf8               com/atguigu/java/HelloApp
 #30 = Utf8               java/lang/Object
 #31 = Utf8               java/lang/System
 #32 = Utf8               out
 #33 = Utf8               Ljava/io/PrintStream;
 #34 = Utf8               java/io/PrintStream
 #35 = Utf8               println
 #36 = Utf8               (I)V
{
 public com.java.HelloApp();
   descriptor: ()V
   flags: ACC_PUBLIC
   Code:
     stack=1, locals=1, args_size=1
        0: aload_0
        1: invokespecial #1                  // Method java/lang/Object."<init>":()V
        4: return
     LineNumberTable:
       line 7: 0
     LocalVariableTable:
       Start  Length  Slot  Name   Signature
           0       5     0  this   Lcom/atguigu/java/HelloApp;

 public static void main(java.lang.String[]);
   descriptor: ([Ljava/lang/String;)V
   flags: ACC_PUBLIC, ACC_STATIC
   Code:
     stack=2, locals=1, args_size=1
        0: getstatic     #2                  // Field >java/lang/System.out:Ljava/io/PrintStream;
        3: getstatic     #3                  // Field a:I
        6: invokevirtual #4                  // Method >java/io/PrintStream.println:(I)V
        9: return
     LineNumberTable:
       line 12: 0
       line 13: 9
     LocalVariableTable:
       Start  Length  Slot  Name   Signature
           0      10     0  args   [Ljava/lang/String;

 static {};
   descriptor: ()V
   flags: ACC_STATIC
   Code:
     stack=1, locals=0, args_size=0
        0: iconst_1
        1: putstatic     #3                  // Field a:I
        4: return
     LineNumberTable:
       line 8: 0
}
SourceFile: "HelloApp.java"

3.初始化

  • 1.初始化阶段就是执行类构造器方法(<clinit>())的过程,可使用jclasslib查看(下载地址)
  • 2.此方法不需要定义,是javac编译器自动收集类中的所有类变量的赋值动作(类变量的显式赋值)和静态代码块中的语句合并而来,注意不包含静态方法
  • 3.类构造器方法中指定按语句在源文件中出现的顺序执行
  • 4.<clinit>()不同于类的构造器,类的构造器方法对应的是init()方法
  • 5.若该类具有父类,JVM会保证子类的<clinit>()执行前,父类的<clinit>()已经执行完毕
  • 6.虚拟机必须保证一个类的<clinit>()方法在多线程下被同步加锁(多线程下如果有一个线程加载,则其他加载线程会被阻塞;即保证类只会被加载一次,加载后的类对象保存在方法区)
  • 7.<clinit>()只有在类中有对静态变量静态代码块操作时才会有,其他情况不会存在(已测试静态方法不会存在)
public class HelloApp2 {
   private static int num = 1; //prepare:num = 0 ---> initial : num = 1 ---> num = 2

   static {
       num = 2;
       number = 20;
   }

   private static int number = 10; //prepare:number = 0 ---> initial : number = 20 ---> number = 10


   public static void main(String[] args) {
       System.out.println(num);  // num = 2
       System.out.println(number); // number = 10
   }
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 8.非法的前项引用,可以提前赋值,但不是不能提前引用

在这里插入图片描述

4.类加载器

  • 1.JVM支持两种类型的类加载器:
    • 1.引导类加载器(Bootstrap ClassLoader)
    • 2.自定义类加载器(User-Defined ClassLoader)
  • 2.一般来说自定义类加载器指的是程序中由开发人员自定义的类加载;但是《Java虚拟机规范》中将所有派生于抽象类ClassLoader的类加载器都划分为自定义类加载器
  • 3.程序中最常见的三个类加载器
    • 1.Bootstrap Class Loader:引导类加载器
    • 2.Extension Class Loader:扩展类加载器
    • 3.System Class Loader:系统类加载器
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
  • 4.以上四者之间(引导,扩展,系统,自定义)是包含关系,不是上层下层,也不是子父类的继承关系
  • 5.引导类加载器通过C/C++语言编写无法直接获取;扩展类加载器包含系统类加载器
    public class ClassLoaderTest {
        public static void main(String[] args) {
    
            //获取系统类加载器
            ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
            System.out.println(systemClassLoader);//sun.misc.Launcher$AppClassLoader@18b4aac2
    
            //获取其上层:扩展类加载器
            ClassLoader extClassLoader = systemClassLoader.getParent();
            System.out.println(extClassLoader);//sun.misc.Launcher$ExtClassLoader@1540e19
    
            //获取其上层:获取不到引导类加载器
            ClassLoader bootstrapClassLoader = extClassLoader.getParent();
            System.out.println(bootstrapClassLoader);//null
    
            //对于用户自定义类来说:默认使用系统类加载器进行加载
            ClassLoader classLoader = ClassLoaderTest.class.getClassLoader();
            System.out.println(classLoader);//sun.misc.Launcher$AppClassLoader@18b4aac2
    
            //String类使用引导类加载器进行加载的。---> Java的核心类库都是使用引导类加载器进行加载
            ClassLoader classLoader1 = String.class.getClassLoader();
            System.out.println(classLoader1);//null
    
            ClassLoader classLoader2 = Integer.class.getClassLoader();
            System.out.println(classLoader2);//null
        }
    }
    
  • 7.通过下列代码可以动态获取到引导类,扩展类,系统类加载器负责加载的类,其中越底层能加载的类就越多
    public class ClassLoaderTest1 {
        public static void main(String[] args) {
            System.out.println("**********引导类加载器**************");
            //获取BootstrapClassLoader能够加载的api的路径
            URL[] urLs = sun.misc.Launcher.getBootstrapClassPath().getURLs();
            for (URL element : urLs) {
                System.out.println(element.toExternalForm());
            }
            //从上面的路径中随意选择一个类,来看看他的类加载器是什么:引导类加载器
            ClassLoader classLoader = Provider.class.getClassLoader();
            System.out.println(classLoader);
    
            System.out.println("***********扩展类加载器*************");
            String extDirs = System.getProperty("java.ext.dirs");
            for (String path : extDirs.split(";")) {
                System.out.println(path);
            }
    
            //从上面的路径中随意选择一个类,来看看他的类加载器是什么:扩展类加载器
            ClassLoader classLoader1 = CurveDB.class.getClassLoader();
            System.out.println(classLoader1);//sun.misc.Launcher$ExtClassLoader@1540e19d
    
    		System.out.println("***********系统类加载器*************");
    		String appDirs = System.getProperty("java.class.path");
    		for (String path : appDirs.split(";")) {
    			System.out.println(path);
    		}
    		
         	//从上面的路径中随意选择一个类,来看看他的类加载器是什么:系统类加载器
         	ClassLoader classLoaderTest = ClassLoaderTest1.class.getClassLoader();
            System.out.println(classLoaderTest);//sun.misc.Launcher$AppClassLoader@18b4aac2
        }
    }
    

1.引导类加载器(Bootstrap ClassLoader)

  • 1.该类加载器使用C/C++语言实现,是JVM的一部分,通过Java代码是无法获取的
  • 2.该类加载器用来加载Java的核心库,提供JVM自身需要的类
    • 1.JAVA_HOME/jre/lib目录下的rt.jarresources.jar
    • 2.sun.boot.class.path路径下的内容
  • 3.该类加载器并不继承自java.lang.ClassLoader,没有父加载器
  • 4.该类加载器也用来加载扩展类和系统类加载器,并指定为他们的父类加载器
  • 5.出于安全考虑,引导类加载器只加载包名为javajavaxsun等开头的类

2.扩展类加载器(Extension ClassLoader)

  • 1.Java语言编写,由sun.misc.Launcher$ExtClassLoader实现(内部类),该加载器是JVM自带的
  • 2.ExtClassLoader派生于ClassLoader抽象类
  • 3.该类加载器的父类加载器为引导类加载器
  • 4.从java.ext.dirs系统属性所指定的目录中加载类库或从JDK的安装目录的jre/lib/ext子目录(扩展目录)下加载类库
  • 5.如果用户创建的jar包放在此目录(jre/lib/ext)下,也会自动由扩展类加载类加载,主要用来加载核心包外的扩展目录下的jar包
    在这里插入图片描述

3.系统类加载器(System Class Loader)

  • 1.Java语言编写,由sun.misc.Launcher$AppClassLoader实现(内部类),该加载器是JVM自带的
  • 2.AppClassLoade派生于ClassLoader抽象类
  • 3.该类加载器的父类加载器为扩展类加载器
  • 4.该类加载器负责加载环境变量classpath或系统属性java.class.path指定路径下的类库
  • 5.该类加载器是程序中默认的类加载器,一般来说Java应用的类都是由它来完成加载
  • 6.通过ClassLoader.getSystemClassLoader()方法可以获取到该类加载器
    在这里插入图片描述

4.用户自定义类加载器

  • 1.Java开发可以自定义类加载器,定制类的加载方式
  • 2.自定义类加载器的优势
    • 1.隔离加载类(不同中间件的加载是隔离的,确保加载jar包时相同名称的路径不会冲突)
    • 2.修改类加载的方式(修改为需要的时候动态的加载)
    • 3.扩展加载源(本地磁盘,网络,扩展其他加载源)
    • 4.防止源码泄露(自定义类加载器实现加密解密)
  • 3.实现步骤
    • 1.通过继承抽象类java.class.ClassLoader的方式,实现自定义类加载器
    • 2.JDK1.2之前,自定义类加载器会去继承ClassLoader类并重写loadClass()方法,从而实现自定义的类加载类
    • 3.JDK1.2之后,不建议覆盖loadClass()方法,建议把自定义的类加载逻辑写在findClass()方法中
    • 4.编写自定义类加载器时,如果没有太过于复杂的需求,可以直接继承URLClassLoader类,这样可以避免去编写findClass()方法以及获取字节码流的方式,使自定义类加载器编写更加简洁
    package com.java;
    
    import java.io.FileNotFoundException;
    
    /**
     * 自定义用户类加载器
     */
    public class CustomClassLoader extends ClassLoader {
        @Override
        protected Class<?> findClass(String name) throws ClassNotFoundException {
    
            try {
                byte[] result = getClassFromCustomPath(name);
                if(result == null){
                    throw new FileNotFoundException();
                }else{
    				//如果不为null则继续调用该方法
                    return defineClass(name,result,0,result.length);
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
    
            throw new ClassNotFoundException(name);
        }
    
    	//根据指定路径已二进制流的方式读入到内存中形成字节数组
        private byte[] getClassFromCustomPath(String name){
            //从自定义路径中加载指定类:细节略
            //如果指定路径的字节码文件进行了加密,则需要在此方法中进行解密操作。
            return null;
        }
    
        public static void main(String[] args) {
            CustomClassLoader customClassLoader = new CustomClassLoader();
            try {
                Class<?> clazz = Class.forName("One",true,customClassLoader);
                Object obj = clazz.newInstance();
                System.out.println(obj.getClass().getClassLoader());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    

5.ClassLoader

  • 1.ClassLoader是一个抽象类,除引导类加载器其余的类加载器都继承自ClassLoaser
  • 2.sun.misc.LauncherJVM的入口应用,ExtClassLoaderAppClassLoader都是Launcher的内部类
  • 3.加载类生成Class的方式:
    • 1.通过loadClass方法传入一个想要加载的路径然后返回Class的类实例
    • 2.通过findClassdefineClass配合传入一个想要加载的路径然后返回Class的类实例

在这里插入图片描述在这里插入图片描述
在这里插入图片描述

1.获取ClassLoader的途径

在这里插入图片描述
在这里插入图片描述

6.双亲委派机制

  • 1.Java虚拟机class文件采用的是按需加载的方式,当需要使用该类时才会将它的class文件加载到内存生成Class对象
  • 2.Java虚拟机加载某个类的class文件时,采用的双亲委派机制,即把请求交由父类处理,它是一种任务委派模式

1.工作原理

  • 1.如果一个类加载器收到了类加载请求,它并不会自己先去加载,而是把这个请求委托给父类的加载器去执行
  • 2.如果父类加载器还存在其父类加载器,则进一步向上委托,依次递归,请求最终将到达顶层的引导类加载器
  • 3.如果父类加载器可以完成类加载任务,则成功返回,如果父类加载器无法完成此加载任务,子类才会尝试自己去加载,这就是双亲委派机制
    在这里插入图片描述

2.实例

  • 1.本地创建一个和Java.lang.String同样包级的String类,如果该类被加载,则会输出静态代码块中的内容
    package java.lang;
    
    public class String {
        static{
            System.out.println("我是自定义的String类的静态代码块");
        }
    }
    
  • 2.创建一个测试类,调用Java.lang.String
    public class StringTest {
    
        public static void main(String[] args) {
            java.lang.String str = new java.lang.String();
            System.out.println("hello");
    
            StringTest test = new StringTest();
            System.out.println(test.getClass().getClassLoader()); //自定义的类加载器一般是系统类加载器
    		System.out.println(str.getClass().getClassLoader()); //核心类库加载器是引导类加载器
        }
    }
    
  • 3.测试结果发现自动调用的是核心类库中String类而不是本地中的String类(只限测试使用),因此可防止恶意攻击导致项目崩溃
    在这里插入图片描述
  • 4.上述自定义String类添加main方法并执行,因为双亲委派机制,最后本地String类的加载交给引导类加载器去加载核心类库中的String类,而该类不存在main方法,所以会报错
    在这里插入图片描述
  • 5.系统类接口由引导类加载器加载,实现其功能的第三方的jar包加载一般是通过线程上下文类加载器加载,默认为系统类型加载器
    在这里插入图片描述

3.优势

  • 1.避免类的重复加载
  • 2.保护程序的安全,防止核心API被随意篡改,防止自定义的类使JVM崩溃
    • 例:自定义类java.lang.String
  • 3.禁止自定义包名与系统包名冲突,因为该包名下的类由引导类加载器加载,但是该类并不存在于引导类加载器要加载的路径中
    在这里插入图片描述

4.沙箱安全机制

  • 1.沙箱:是一个限制程序运行的环境
  • 2.沙箱机制:是将Java代码限定在虚拟机JVM特定的运行范围中,并且严格限制代码对本地系统资源访问,通过这样的措施来保证对代码的有效隔离,防止对本地系统造成破坏,可参考Java沙箱机制
  • 3.简单来说
    • 1.上述自定义String类,加载的时候会优先使用引导类加载器加载
    • 2.引导类加载器在加载的过程中会先加载jdk自带的文件(rt.jar包中java\lang\String.class)
    • 3.上述报错信息说没有main方法就是因为加载的是rt.jar包中的String类,这样可以保证对java核心源代码的保护,这就是沙箱安全机制

5.判断两个Class对象是否为同一个类

  • 1.JVM中表示两个Class对象是否为同一个类存在两个必要条件
    • 1.类的完整类名必须一致,包括包名
    • 2.加载这个类的classLoader(指:ClassLoader实例对象)必须相同(例:上述两个String类不同,因为类加载器不同)
  • 2.JVM中即使两个类对象(Class对象)来源同一个class文件,被同一个虚拟机所加载,但只要加载它们的ClassLoader实例对象不同,那么这两个对象也是不相等的
  • 3.JVM必须知道一个类型是由引导类加载器加载还是由自定义类加载器加载的
  • 4.如果一个类型是由自定义类加载器加载的,JVM会将这个类加载器的一个引用作为类型信在这里插入代码片息的一部分保存在方法区中,引导类除外因为该类标识为null
  • 5.当解析一个类型到另一个类型的引用的时候,JVM需要保证这两个类型的类加载器是相同的(动态链接)

6.类的主动使用和被动使用

  • 1.Java程序对类的使用方式分为:主动使用和被动使用
    • 1.主动使用:分为七种情况
      • 1.创建类的实例
      • 2.访问某个类或接口的静态变量,或者对该静态变量赋值
      • 3.调用类的静态方法
      • 4.反射(Class.forName等)
      • 5.初始化一个类的子类
      • 6.Java虚拟机启动被标明启动类的类
      • 7.JDK7开始提供的动态语言支持:
        • 1.java.lang.invoke.MethodHandle实例的解析结果
        • 2.REF_getStatic,REF_putStatic,REF_invokeStatic句柄对应的类没有初始化,则初始化
    • 2.被动使用
      • 1.除以上七种情况,其他使用Java类的方式都被看作是对类的被动使用,都不会导致类的初始化
  • 2.不管是主动使用还是被动使用都会被加载,只要使用都会被加载,但是只有主动使用会执行类加载的初始化步骤

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

VS项目写完执行exe隐藏调试用的黑窗口(控制台)

在vs创建完项目&#xff0c;我们只希望运行显示界面&#xff0c;不显示控制台&#xff0c;控制台就是这样的黑色窗口&#xff0c;他可以在我们调试的时候打印一些东西来判断辅助编程。 1、首先修改为窗口模式 2、在你的main文件里最上面加入一行代码&#xff1a; #pragma comme…

android打印编码转换-SAAS本地化及未来之窗行业应用跨平台架构

一、打印转码 1.图片转打印 2.文字转打印 二、代码 package CyberWinPHP.Cyber_Plus;import java.util.Hashtable;import com.google.zxing.BarcodeFormat; import com.google.zxing.EncodeHintType; import com.google.zxing.WriterException; import com.google.zxing.co…

【文档合集】软件类常用文档整理大全,软件工程,软件项目管理,技术标书方案,模

目的&#xff1a;规范系统开发流程&#xff0c;提高系统开发效率。 立项申请需求分析方案设计方案评审开发调整测试阶段系统培训试运行测试验收投入使用 所有文档过去进主页获取。 获取方式&#xff1a;本文末个人名片直接获取。 软件资料清单列表部分文档清单&#xff1a;工作…

一款免费轻量的CAD看图软件

这款免费CAD看图软件&#xff0c;旨在为用户提供快速查看和处理CAD图纸的能力。该软件以其轻量化、功能全面、操作简便等特点受到用户的欢迎。支持多种CAD文件的快速查看&#xff0c;包括但不限于DWG、DXF等格式&#xff0c;而且不需要安装大型CAD软件即可使用。 主要特点包括…

齐护语音识别V2.1模块可自定义免编程学习唤醒词指令词自带IO实现人机对话 Arduino C编程图形化Mixly Scratch编程

齐护离线语音识别模块可免编程自定义学习唤醒词及识别词 固件V2.1 齐护语音识别V2.1模块可自定义免编程学习唤醒词指令词自带IO实现人机对话 Arduino C编程图形化Mixly Scratch编程 此固件&#xff08;程序/功能&#xff09;为自学习V2.1版本&#xff0c;在基础版本的上去除【变…

HashMap-leetcode总结

为什么用Hashmap? 将两种属性&#xff08;key,value&#xff09;具有某种联系&#xff0c;需要保存下来 随时读取是否存在且通过一方获取它对应值 数据结构 一数值value经过hashcode()计算出key&#xff0c;key对应数组位置建立链表 HashMap常用方法 1、HashMap的初始化 Hash…

4820道西医综合真题西医真题ACCESS\EXCEL数据库

本题库内容源自某出版物《西医综合真题考点还原与答案解析》&#xff0c;包含4千多道真题。这个数据库包含3个表&#xff0c;一个是分类表&#xff08;SECTION_BEAN&#xff09;&#xff0c;一个是题库主表&#xff08;QUESTION_INFO_BEAN&#xff09;&#xff0c;一个是选项表…

新版本 | GreatSQL 8.0.32-26全新发布 增强“四高”诸多新特性

近日&#xff0c;GreatSQL开源数据库社区正式发布 GreatSQL 8.0.32-26新版本&#xff0c;在高可用、高性能、高兼容、高安全等诸多方面进行了特性增强&#xff0c;修复多个缺陷&#xff0c;并详细说明了多个典型应用场景下&#xff0c;升级/降级到GreatSQL 8.0.32-26的操作策略…

从心理学的角度,探究一下人类为什么爱玩游戏。(缓解压力、社交需求、 获得成就感)

文章目录 引言I 游戏中的美学和文化元素,是影响玩家心理状态的关键因素。音乐美工文化背景II 成年人对游戏的心理需求获得成就感社交需求缓解压力III 心流理论(Flow Theory)解释玩家虽受虐,但也其乐无穷的现象知识扩展: 心流知识扩展: 心流活动知识扩展:得性乐观(Learne…

Koa商城项目-公共组件封装

项目地址 koa_system: &#x1f525;&#x1f525;&#x1f525;Koa2 React商城项目前端-React Antd前端-Vue2 Element-plus后端-Koa2 Sequelizehttps://gitee.com/ah-ah-bao/koa_system 欢迎大家点击查看,方便的话点一个star~ Vue2Admin和Vue3Admin版本的后台还没有对接…

学习记录:js算法(十二):柱状图中最大的矩形

文章目录 柱状图中最大的矩形我的思路网上思路 总结 柱状图中最大的矩形 给定 n 个非负整数&#xff0c;用来表示柱状图中各个柱子的高度。每个柱子彼此相邻&#xff0c;且宽度为 1 。 求在该柱状图中&#xff0c;能够勾勒出来的矩形的最大面积。 示例 1:上图 输入&#xff1a;…

i.MX6裸机开发(6):GPIO输入——按键查询检测

按键检测使用到GPIO外设的基本输入功能&#xff0c;GPIO外设相关的概念请参考 第四章节汇编点亮LED灯。 本章主要内容&#xff1a; i.MX 6U 在硬件上实现按键消抖 Pro开发板按键原理图和功能分析 在led_rgb_c基础上修改为button 编译代码&#xff0c;实现按键查询控制LED …

OpenAI 通过强大的结构化输出功能增强了其 API

介绍 可以通过打开/关闭 JSON 模式或使用函数调用来创建先前结构化的输出。 大型语言模型 (LLM) 与一般的对话式 UI 非常相似&#xff0c;擅长处理以自然语言呈现的非结构化数据。首先对这些非结构化输入进行组织和处理&#xff0c;然后将其重新转换为自然语言作为结构化响应。…

WIFI驱动开发

Linux 4.9 内核驱动移植 Linux 4.9 BSP 内核驱动 下载驱动后获得驱动的 tar.gz 压缩包 解压后找到如下驱动与文件夹 进入内核&#xff0c;找到 linux-4.9/drivers/net/wireless 文件夹中&#xff0c;新建文件夹aic8800 并且把上面的驱动与文件夹放入刚刚创建好的 aic8800 中。…

动漫二次元漂亮的网站导航HTML5源码

二次元漂亮网站导航HTML源码&#xff0c;页面中还调用了很多外站的图片等链接需自行更换。 动漫二次元漂亮的网站导航HTML5源码

NASA:ARM 增强短波实验(ARESE)太阳辐射数据

目录 简介 摘要 代码 网址推荐 0代码在线构建地图应用 机器学习 ARM Enhanced Shortwave Experiment (ARESE) Solar Radiation Data 简介 ARESE 研究了晴朗和多云大气对太阳辐射的吸收。 测量使用了三个飞机平台&#xff1a;一架高空载人埃格雷特飞机、一架装有仪器的双…

百度地图SDK Android版开发 8 覆盖物示例2动画

百度地图SDK Android版开发 8 覆盖物示例2动画 前言动画相关的类和接口帧动画MarkerOptions 加载动画MarkerOptionsMarkerOptions.MarkerAnimateType 动画类型 Animation动画MarkerAnimation类及其子类AnimationTransformationRotateAnimationAlphaAnimationScaleAnimationSing…

二、Java变量

文章目录 一、变量介绍1.1 为什么需要变量1.2 变量的介绍1.4 变量使用注意事项 二、号的使用三、数据类型1.1 整数类型1.2 浮点类型1.3 字符类型(char)1.4 布尔类型&#xff1a;boolean 四、编码五、数据类型转换5.1 自动类型转换5.2 强制类型转换5.3 基本数据类型和String类型…

计算机毕业设计花卉交易管理系统

技术可行性 根据花卉交易管理的基本需求&#xff0c;该系统需要实现把商品的基本信息&#xff0c;销售信息等内容存放到数据库中&#xff0c;是典型的管理信息系统。管理信息系统是建立在现代信息技术基础之上&#xff0c;面向组织的全面管理和简单决策的信息系统[3]。其开发主…

K8S故障

故障显示 解决办法 kubectl -n kube-system edit deployments.apps coredns删除下列数据