JVM - 1.类加载子系统

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.将常量池内的符号引用转换为直接引用的过程(对应JVM - 2.运行时数据区的虚方法表的创建时机)
  • 2.事实上解析操作往往会在JVM执行完初始化后再执行
  • 3.符号引用:一组符号来描述所引用的目标,符号引用的字面量形式明确定义在《java虚拟机规范》的class文件格式中
  • 4.直接引用:直接指向目标的指针,相对偏移量或一个间接定位到目标的句柄
  • 5.解析动作主要针对类或接口,字段,类方法,接口方法,方法类型;对应常量池中的CONSTANT_Class_infoCONSTANT_Fieldref_infoCONSTANT_Methodref_info
    在这里插入图片描述
  • 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.classLast modified 2022-11-9; size 608 bytesMD5 checksum 5964d34bba8f8bf4e817be8fe95a17feCompiled from "HelloApp.java"
public class com.java.HelloAppminor version: 0major version: 52flags: 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: ()Vflags: ACC_PUBLICCode:stack=1, locals=1, args_size=10: aload_01: invokespecial #1                  // Method java/lang/Object."<init>":()V4: returnLineNumberTable:line 7: 0LocalVariableTable:Start  Length  Slot  Name   Signature0       5     0  this   Lcom/atguigu/java/HelloApp;public static void main(java.lang.String[]);descriptor: ([Ljava/lang/String;)Vflags: ACC_PUBLIC, ACC_STATICCode:stack=2, locals=1, args_size=10: getstatic     #2                  // Field >java/lang/System.out:Ljava/io/PrintStream;3: getstatic     #3                  // Field a:I6: invokevirtual #4                  // Method >java/io/PrintStream.println:(I)V9: returnLineNumberTable:line 12: 0line 13: 9LocalVariableTable:Start  Length  Slot  Name   Signature0      10     0  args   [Ljava/lang/String;static {};descriptor: ()Vflags: ACC_STATICCode:stack=1, locals=0, args_size=00: iconst_11: putstatic     #3                  // Field a:I4: returnLineNumberTable: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 = 2static {num = 2;number = 20;}private static int number = 10; //prepare:number = 0 ---> initial : number = 20 ---> number = 10public static void main(String[] args) {System.out.println(num);  // num = 2System.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);//nullClassLoader 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@1540e19dSystem.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 {@Overrideprotected 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.rhkb.cn/news/409448.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

pdf文件渲染到canvas

1、jQuery 2、Fabric.js Fabric.js是一个对canvas进行封装的Javascript库&#xff0c;主要的功能包括在canvas上创建和填充图形&#xff0c;比如矩形、圆形、多边形&#xff1b;生成的图像自带缩放、旋转、拖拽等功能。 3、PDF.js PDF.js 是一个使用 HTML5 构建的便携式文档格式…

在Linux中如何安装JDK

一、卸载JDK &#xff08;可以不删除&#xff0c;直接安装新的JDK&#xff0c;然后修改环境变量&#xff09; 1.1卸载使用yum安装的jdk 1.1.1卸载系统预安装的JDK 使用命令&#xff1a;yum list installed |grep java 注意&#xff1a;该命令只能查看使用yum命令安装的jav…

【架构-24】XML和JSON

XML&#xff08;可扩展标记语言&#xff09;和JSON&#xff08;JavaScript对象表示法&#xff09;是两种常用的数据格式&#xff0c;用于在不同系统之间传输和交换数据。它们各有优点和缺点&#xff0c;适用于不同的场景。下面是对XML和JSON的简要介绍以及它们之间的对比。 XM…

有关于算法备案的五大误区

有关于算法备案的五大误区 在这个数据为王的时代&#xff0c;算法已然成为推动社会前进的隐形巨轮。从搜索框中的每一次点击&#xff0c;到购物车里的每一件商品推荐&#xff0c;再到朋友圈里刷屏的动态&#xff0c;算法的身影无处不在&#xff0c;悄无声息地编织着我们的数字生…

提升文旅热度带动商家增收,抖音生活服务“心动大连”活动启动

8月22日&#xff0c;抖音心动之城大连系列活动&#xff08;下称“心动大连”&#xff09;启动仪式召开&#xff0c;主题为“遇见大连&#xff0c;心动无限”。活动由大连市人民政府指导&#xff0c;大连市文化和旅游局、抖音生活服务共同主办&#xff0c;旨在发挥抖音平台内容和…

opencv-python图像增强十六:图像马赛克

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、算法流程&#xff1a;二、算法实现&#xff1a;2.1 生成背板图&#xff1a;2.2 图片添加马赛克效果 三&#xff0c;整体代码实现&#xff1a;四&#xff0c…

点亮星星的世界:当小孩得了自闭症该怎么办

在这个丰富多彩的世界里&#xff0c;每一个孩子都是独一无二的天使。然而&#xff0c;有一些孩子却仿佛被困在了自己的小小世界中&#xff0c;难以与外界正常交流和互动。他们是自闭症儿童&#xff0c;他们的世界充满了挑战和困惑&#xff0c;也让家长们陷入了深深的担忧和焦虑…

UE5学习笔记17-让人物的视线和鼠标移动时的方向一致,并且不让人物模型旋转,只改变视线方向

一、创建标准动画帧 1.我想让人物在装备武器后根据鼠标的移动方向改变人物的视线方向&#xff0c;并且人物模型不会改变朝向 2.我的动画中存在一个四个方向瞄准的动画&#xff0c;将左下&#xff0c;坐上&#xff0c;左转&#xff0c;右上&#xff0c;右下&#xff0c;右转&…

Android - 音频参数合入

音频参数宏观来看分为两部分&#xff0c;audio和music。不管是哪个平台都需要分别合入这两部分。 A10 music参数 相关工程师调试后会提供 audio_para 文件&#xff0c;将该文件替换至对应工程下的文件编译即可 例: device/sprd/sharkle/sl8541e_1h10_32b/rootdir/system/et…

程序员失业跑滴滴,意外自学AI绘画成主业,月入过万不是梦!

一、突如其来的裁员 那是一个阴沉的下午&#xff0c;我像往常一样&#xff0c;在公司忙碌着。突然&#xff0c;HR叫我去会议室&#xff0c;告诉我由于公司业务调整&#xff0c;我所在的部门被整体裁撤。作为一名程序员&#xff0c;我从未想过自己会面临失业的困境。拿着那份补偿…

大语言模型-PDF文档解析

PDF解析能够提升大语言模型系统的信息处理能力和应用范围&#xff0c;为用户提供更加便捷、高效、个性化的服务体验。本文介绍三种常用的pdf解析方式&#xff1a;Open Parse、pdfplumber、PyMuPD。 一、Open Parse Open Parse是一个能够直观地识别文档布局并有效地对其进行分…

mac安装java17(jdk17)

1. 下载jdk17 官网下载&#xff1a;https://www.oracle.com/java/technologies/downloads 2. 直接安装 安装完后目录会存放在下面目录下 /Library/Java/JavaVirtualMachines 111111deMBP JavaVirtualMachines % ls jdk-11.0.227 jdk-17.jdk 3. 如果你已经安装过java&#…

kafka的12个重要概念

kafka的12个重要概念 1、服务器broker1.1、Broker 的主要功能1.2、Kafka Broker 的架构1.3、配置和管理1.4、高可用性和负载均衡1.5、总结 2、主题topic2.1、主要特点 3、事件Event4、生产者producer4.1、主要功能4.2、Producer 的配置选项4.3、Producer 的工作流程4.4、总结 5…

网页,html,Web端实现RTSP/RTMP实时推流视频和播放

随着技术的不断发展&#xff0c;实时流传输已经成为许多应用的重要组成部分。RTSP&#xff08;Real-Time Streaming Protocol&#xff09;作为一种实时流媒体传输协议&#xff0c;广泛应用于视频监控、直播等领域。然而&#xff0c;在Web端实现RTSP实时推流视频播放却面临一些挑…

谈下日本IT业现状以及未来的发展

日本IT业现状 市场规模与增长率&#xff1a; 根据最新数据&#xff0c;日本IT行业的市场规模在不断扩大。例如&#xff0c;2022年日本IT行业的总市值达到了约4500亿美元&#xff0c;年复合增长率约为3.5%。这表明该行业在经济中占据重要地位&#xff0c;并持续保持增长态势。就…

我忘记给我的代码备份了。。。。。。

ok啊&#xff0c;历经1个月&#xff0c;这个项目总算是快写完啦&#xff01;很烧脑&#xff0c;写这个脑细胞都不知道噶了多少&#xff0c;哎~ 虽然目前还有很大一部分可以改进&#xff0c;我觉得以我目前的能力能写成这样已经很不错了&#xff0c;还是学艺不精啊~ 实际上的话…

分享一个基于python新闻订阅与分享平台flask新闻发布系统(源码、调试、LW、开题、PPT)

&#x1f495;&#x1f495;作者&#xff1a;计算机源码社 &#x1f495;&#x1f495;个人简介&#xff1a;本人 八年开发经验&#xff0c;擅长Java、Python、PHP、.NET、Node.js、Android、微信小程序、爬虫、大数据、机器学习等&#xff0c;大家有这一块的问题可以一起交流&…

SpringBoot集成kafka开发-消息消费的分区策略(消费者如何判断从哪个分区中消费消息的?)

这里写目录标题 1、kafak消息者消费消息的4种分区策略2、kafka默认的消费分区策略1-RangeAssignor&#xff08;均匀分配、默认分配策略&#xff09;2.1、代码验证RangeAssignor的消息分区策略2.1.1、消费者2.1.2、生产者2.1.3、kafak配置类2.1.4、对象实体类2.1.5、项目配置文件…

卸载通过pip安装的所有Python包的详细指南

卸载所有通过pip安装的Python包的方法总结&#xff08;Windows系统&#xff09; 方法 1: 使用 pip freeze 和 requirements.txt 步骤: 导出依赖到requirements.txt文件: pip freeze > requirements.txt这个命令会将当前环境中所有已安装的Python包及其版本号输出到requirem…

Django | 从中间件的角度来认识Django发送邮件功能

文章目录 概要中间件中间件 ---> 钩子实现中间件demo 邮件发送过程Django如何做邮件服务配置流程 中间件结合邮件服务实现告警 概要 摘要 业务告警 邮件验证 密码找回 邮件告警 中间件 中间件 —> ‘钩子’ 例如 访问路由 的次数【请求】 中间件类须实现下列五个方法…