2. Class 文件的组成

news2024/11/19 19:29:47

16 进制打开class文件

可以通过Notepad++下载一个HexEditor插件,下载好该插件后可以以16进制的方式打开class看,打开后我们可以看到如下所示的图片:

class 文件的组成

class 文件的组成部分为:魔数,版本号,常量池,字段表集合,方法表集合


在这里插入图片描述


Java字节码分析

通过javap -v Java文件名称.class 我们可以获取到Java的class字节码的内容,例如获取JvmTest.class文件的字节码信息:

javap -v JvmTest.class

Java源文件内容如下:

package com.test.jvm;

import com.test.entity.ExportDataPushLog;

/**
 *
 * @author JR
 * @version 1.0
 * @description:
 * @date 2024年06月26日 14:58
 */
public class JvmTest implements JvmTestInterface {

    private static int a = 1;
    private static int b;
    // 注意如果使用javap -v 命令这里如果是private则这里在class文件中不显示的
    // 所以这里用的public,目前还不明白为什么这么做的原因,需要回头查查资料
    public static final String str = "123";

    public static void main(String[]args) {

        int i = 0;
        int j = 0;

        i = 1;
    }
    public static ExportDataPushLog A(String t1, int t2) {
        System.out.println("A执行了..");
        B();
        return null;
    }

    public static void B() {
        System.out.println("B执行了..");
        C();
    }
    public static void C() {
        System.out.println("C执行了.·.");
    }
}


获取到的字节码信息如下:

// 第一行文件指定了这个class文件在当前系统中的绝对路径
Classfile /C:/Users/Administrator/Desktop/my-file/Test/target/classes/com/test/jvm/JvmTest.class
  // 最后的修改时间 文件大小
  Last modified 202471; size 1084 bytes
  // 这个不知道没看懂
  SHA-256 checksum acf3be9291a67e6c4671e6a8639b26b99209979da771e519bb8fc38fa90064ed
  Compiled from "JvmTest.java"
public class com.test.jvm.JvmTest implements com.test.jvm.JvmTestInterface
// 主版本号
  minor version: 0
// 副版本号
  major version: 55
// 当前class 文件的标识,下面图片有相关说明继续往后看
  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
// 说明了当前是哪个类
  this_class: #10                         // com/test/jvm/JvmTest
// 当前类的父类
  super_class: #11                        // java/lang/Object
// 实现了一个接口,类中有3个成员变量,六个方法
// 至于attributes暂时不理解,后面在找找资料,主要不理解这里的fields和attributes
// 按道理字段就应该是属性,但是这里却是fields是3,而attributes:1
  interfaces: 1, fields: 3, methods: 6, attributes: 1
Constant pool:
   #1 = Methodref          #11.#40        // java/lang/Object."<init>":()V
   #2 = Fieldref           #41.#42        // java/lang/System.out:Ljava/io/PrintStream;
   #3 = String             #43            // A执行了..
   #4 = Methodref          #44.#45        // java/io/PrintStream.println:(Ljava/lang/String;)V
   #5 = Methodref          #10.#46        // com/test/jvm/JvmTest.B:()V
   #6 = String             #47            // B执行了..
   #7 = Methodref          #10.#48        // com/test/jvm/JvmTest.C:()V
   #8 = String             #49            // C执行了.·.
   #9 = Fieldref           #10.#50        // com/test/jvm/JvmTest.a:I
  #10 = Class              #51            // com/test/jvm/JvmTest
  #11 = Class              #52            // java/lang/Object
  #12 = Class              #53            // com/test/jvm/JvmTestInterface
  #13 = Utf8               a
  #14 = Utf8               I
  #15 = Utf8               b
  #16 = Utf8               str
  #17 = Utf8               Ljava/lang/String;
  #18 = Utf8               <init>
  #19 = Utf8               ()V
  #20 = Utf8               Code
  #21 = Utf8               LineNumberTable
  #22 = Utf8               LocalVariableTable
  #23 = Utf8               this
  #24 = Utf8               Lcom/test/jvm/JvmTest;
  #25 = Utf8               main
  #26 = Utf8               ([Ljava/lang/String;)V
  #27 = Utf8               args
  #28 = Utf8               [Ljava/lang/String;
  #29 = Utf8               i
  #30 = Utf8               j
  #31 = Utf8               A
  #32 = Utf8               (Ljava/lang/String;I)Lcom/test/entity/ExportDataPushLog;
  #33 = Utf8               t1
  #34 = Utf8               t2
  #35 = Utf8               B
  #36 = Utf8               C
  #37 = Utf8               <clinit>
  #38 = Utf8               SourceFile
  #39 = Utf8               JvmTest.java
  #40 = NameAndType        #18:#19        // "<init>":()V
  #41 = Class              #54            // java/lang/System
  #42 = NameAndType        #55:#56        // out:Ljava/io/PrintStream;
  #43 = Utf8               A执行了..
  #44 = Class              #57            // java/io/PrintStream
  #45 = NameAndType        #58:#59        // println:(Ljava/lang/String;)V
  #46 = NameAndType        #35:#19        // B:()V
  #47 = Utf8               B执行了..
  #48 = NameAndType        #36:#19        // C:()V
  #49 = Utf8               C执行了.·.
  #50 = NameAndType        #13:#14        // a:I
  #51 = Utf8               com/test/jvm/JvmTest
  #52 = Utf8               java/lang/Object
  #53 = Utf8               com/test/jvm/JvmTestInterface
  #54 = Utf8               java/lang/System
  #55 = Utf8               out
  #56 = Utf8               Ljava/io/PrintStream;
  #57 = Utf8               java/io/PrintStream
  #58 = Utf8               println
  #59 = Utf8               (Ljava/lang/String;)V
{
  // 字段表集合,这里一定要注意,一定要是public 否则的话使用Javap在class文件中是不显示的
  // 问题:问什么使用private在class文件中是不显示的?
  public static final java.lang.String str;
    descriptor: Ljava/lang/String;
    // 首先是public的,其次是静态字段,其次是常量字段
    flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
    ConstantValue: String 123

  // 方法信息
  public com.test.jvm.JvmTest();
    // ()V代表入参和返回值,这里没有入参,返回值也没有所以入参是:()出餐是:V,
    descriptor: ()V
    // 方法是public
    flags: (0x0001) 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 12: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   Lcom/test/jvm/JvmTest;

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
    Code:
    // 问题1:编译器是如何计算出栈的最大深度,本地变量表的最大容量的
    // 问题2:这里的槽的概念是什么
    // 方法的Code属性的一部分,具体说明了该方法在执行时的栈帧布局
    // stack=1: 这表示在执行该方法时,Java虚拟机(JVM)为它分配的栈的最大深度是1。栈深是指方法调用过程中,
    // 操作数栈所能容纳的最大元素数量。这个值由编译器计算得出,确保了足够的空间来存放方法执行过程中的中间结果和操作数,而又不会过多地占用资源。
    // locals=1: 这里指的是局部变量表的最大容量是1。局部变量表用于存储方法参数和方法内部定义的局部变量。这个值同样由编译器计算确定,
    // 确保有足够的槽位来保存所有可能同时存活的局部变量和方法参数。在这个例子中,有一个局部变量槽被分配。
    // args_size=1: 这个参数说明了该方法接收的参数数量。在这里,方法有一个参数。需要注意的是,对于实例方法,
    // 局部变量表的第一个槽位默认用于存储this引用(指向当前对象实例),但这不在args_size中计算。
    // 因此,如果这是一个实例方法且args_size=1,实际上局部变量表会有两个槽位:一个用于this,另一个用于传递给方法的参数。
      stack=1, locals=3, args_size=1
        // 在iconst_0中这里的0是指什么?在istore_1中这里的1又是什么
         0: iconst_0
        // 对变量i进行赋值,并弹栈
         1: istore_1
         2: iconst_0
         3: istore_2
         4: iconst_1
         5: istore_1
         6: return
      // 行号对应的Nr
      LineNumberTable:
        line 20: 0
        line 21: 2
        line 23: 4
        line 24: 6
      // 本地变量表(局部变量表)
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       7     0  args   [Ljava/lang/String;
            2       5     1     i   I
            4       3     2     j   I

  public static com.test.entity.ExportDataPushLog A(java.lang.String, int);
    descriptor: (Ljava/lang/String;I)Lcom/test/entity/ExportDataPushLog;
    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=2, args_size=2
         0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
         3: ldc           #3                  // String A执行了..
         5: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
         8: invokestatic  #5                  // Method B:()V
        11: aconst_null
        12: areturn
      LineNumberTable:
        line 26: 0
        line 27: 8
        line 28: 11
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      13     0    t1   Ljava/lang/String;
            0      13     1    t2   I

  public static void B();
    descriptor: ()V
    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=0, args_size=0
         0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
         3: ldc           #6                  // String B执行了..
         5: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
         8: invokestatic  #7                  // Method C:()V
        11: return
      LineNumberTable:
        line 32: 0
        line 33: 8
        line 34: 11

  public static void C();
    descriptor: ()V
    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=0, args_size=0
         0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
         3: ldc           #8                  // String C执行了.·.
         5: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
         8: return
      LineNumberTable:
        line 36: 0
        line 37: 8

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

问题:为什么没有看到字段表集合

class 文件中flags: ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT相关说明

在这里插入图片描述

class文件中的基本信息

class文件魔数

class文件魔数就是指class文件开头的ca fe ba be 联合起来是咖啡馆的意思,魔数(Magic Number)用于辨别当前文件是否是JavaClass 文件,例如:将class 文件的后缀".class"更改为**“.jpg”**扩展名可以随意修改不影响文件的内容,例如:有一张图片a.png 当我们尝试将后缀名称png 改为avi 此时发现使用图片打开工具仍然能够打开该文件,这说明文件后缀名的改变并不能实际改变文件的类型,一般软件通过文件开头的几个字节来分别文件的类型,如果不支持该类型就会报错,而开头的这个字节被称为魔数,以下是一些常见的文件类型及其对应的魔数:

  • JPEG 图像文件:FF D8 FF
  • PNG 图像文件:89 50 4E 47 0D 0A 1A 0A
  • GIF 图像文件:47 49 46 38 39 61 或 47 49 46 38 37 61
  • BMP 图像文件:42 4D
  • WAV 音频文件:52 49 46 46(RIFF)和57 41 56 45(WAVE)
  • MP3 音频文件:FF FB(MPEG-1 layer III)或 49 44 33(ID3)
  • MP4 视频文件:00 00 00 18 66 74 79 70 6D 70 34 32 00 00 00 00
  • AVI 视频文件:52 49 46 46(RIFF)和41 56 49 20(AVI )
  • PDF 文件:25 50 44 46(%PDF)
  • DOC 文件:D0 CF 11 E0 A1 B1 1A E1

class文件主副版本号

就是class文件在编译时,jdk的版本号,在魔数之后紧跟着魔数之后从第4个字节开始就是Class文件的版本号。第5和第6个字节所代表的含义是编译的副版本号,第7和第8个字节代表的是编译的主版本号。Class文件的版本号有主版本号.副版本号组成。

在这里插入图片描述

一般只需要关注主版本号,如上图所示上面7和8显示的版本号是37,37是十六进制转为10进制是55 使用55 减去44 等于11 所以当前的jdk 版本就是jdk 11,而副版本号则是作为主版本号相同时进行区分的作用,主版本号的作用一般是用来判断当前字节码的版本和运行时的jdk是否兼容,如果不兼容则有可能出现类似以下错误:

在这里插入图片描述

高版本的虚拟机可以执行低版本的编译器生成的Class文件,但是低版本的虚拟机不能执行高版本的编译成生成的Class文件。(向下兼容)


class文件中的常量池

常量池分为:静态常量池(class文件常量池),字符串常量池,运行时常量池,class文件中的常量池通常是指静态常量池和字符串常量池:

静态常量池(class文件常量池):静态常量池是相对于运行时常量池来说的,属于描述class文件结构的一部分,由字面量符号引用组成,在类被加载后会将静态常量池加载到内存中也就是运行时常量池


**字符串常量池:**字符串作为最常用的数据类型,为减小内存的开销,专门为其开辟了一块内存区域(字符串常量池)用以存放。其中保存了某些字符的唯一值,例如:当创建一个变量a1 并赋值为:我爱北京天安门,首先会先判断字符串常量池中是否存在字符串内容为:我爱北京天安门的字符串(也就是字面量),常量池中每个字段都有一个编号是从1开始的,并且在常量池中每个常量池这里引用的是一个编号,这里称为常量值索引,每个字段引用的并不是实际的值,而是常量值索引,通过常量值索引就可以找到具体编号的字面量

常量池保存了字符串常量、类或接口名、字段名,主要在字节码指令中使用,如果按照类型划分Class文件常量池主要存放两大常量:字面量和符号引用,字节码文件中常量池的作用主要是为了避免相同的内容重复定义,节省空间。例如存在以下两个字符:

public class ConstantPoolTest{
  public static final String a1="我爱北京天安门;
  public static final String a2="我爱北京天安门"public static void main(String[]args){ConstantPoolTest constantPoolTest new ConstantPoolTest();
}

在字节码文件中可能会出现:

"我爱北京天安门”
"我爱北京天安门”


通过使用classlib来观察class文件

从而导致出现重复的数据占用大量的空间内容,我们可以通过jclasslib 来观察class 文件,常量池中每个字段都有一个编号是从1开始的,并且在常量池中每个常量池这里引用的是一个编号
在这里插入图片描述

当我们打开八号会发现这里引用的并不是实际的值而是27号的一个索引:
在这里插入图片描述

打开27号发现27号才真正记录了真正的字面量,这个字面量才记录了:我爱天安门的数据

在这里插入图片描述

前面说过这里设置了两个变量,a1 和a2,所以同样的a2的字面量同样也并不是直接保存的我爱北京天安门,同样也是和a1一样,保存的字面量索引,通过索引逐步找到27号来获取实际的值,这样做的好处是可以节省一定的空间,同时也为了更好的管理变量,另外常量池中的字面量可能被变量名引用,也可以作为变量值引用。


字段表集合

字段表(field_info)用来描述接口或类中声明的变量,字段包括类级别变量以及实例级别变量。但不包括方法内部声明的局部变量


方法表集合

当前类或接口声明的方法信息的字节码指令,可以通过以下方式在jclasslib中查看指定方法的字节码指令,并通过鼠标右键点击后显示的列表中选择显示JVM规范功能查看当前指定字节码指令的作用:

在这里插入图片描述


打开之后我们发现 iconst_0 的作用描述为:

在这里插入图片描述


要了解下面这段代码生成的字节码指令首先要了解以下两个部分:

public static void main(String[]args){
    int i = 0;
    i = i ++;
}
  1. **操作数栈:**这里的操作数栈主要用于保存计算过程的中间结果,同时作为计算过程中变量临时的存储空间。是一个先进后出的一个结构,所以入栈也叫压栈,出栈也叫弹栈
  2. **局部变量表(本地变量表):**局部变量表是一组变量值的存储空间,用于存放方法参数和方法内部定义的局部变量,局部变量表中的存放顺序是通过变量定义的顺序存放的,同时方法内的变量赋值也是通过局部变量进行的,例如上面的main 方法为例:

在这里插入图片描述


了解了局部变量表和操作数栈之后我们可以尝试理解一下上面main 方法的字节码指令,通过jclasslib 查询我们可以了解到:

  • iconst_<i>(注意这里的”<i>“是一个变量值,例如下面的:iconst_0):将int常量<i>压入操作数栈。从上面的图片我们说过,局部变量表是按照变量的创建顺序来指定序号和位置的,所以这里是取出索引为零的
  • istore_<n>(这里"n"也一样,是个变量):而这里的n则代表局部变量表的索引位置,也就是上面的序号的值,所以这里的操作就是将从操作数栈中将序号为n的数据取出(也就是弹栈),放入局部变量表中,并对指定的变量进行赋值
  • iload_1:将局部变量表中下标为n的变量的值放入操作数栈中
  • iinc 1 by 1: 该方法直接操作局部变量表,直接加一
 0 iconst_0 将零放入操作数栈中
 1 istore_1 此时操作数栈中的值为0,并找到局部变量表中下标为1的变量,将值赋值给该变量 也就相当于i = 0
 2 iload_1 此时局部变量表中下标为1的变量是"i",将该操作变量值推入操作数栈
 3 iinc 1 by 1 直接操作局部变量表,加一,此时i = 1
 6 istore_1 此时操作数栈中的值为0,将操作数栈中的值弹出,并赋值给局部变量i
14 return

字节码常用工具

**javap -v命令:**javap -v是JDK自带的反编译工具,可以通过控制台查看字节码文件的内容。适合在服务器上查看字节码文件内
容。

在这里插入图片描述


jclasslib 的idea插件
在这里插入图片描述

Arthas工具

这个工具和之前的工具的不同是之前的工具无法在代码的执行过程中查看字节码,除此之外还有以下详细内容,感兴趣的话我回头重写写一篇文章专门介绍该文件

官网:https:/arthas…aliyun…com/doc/
在这里插入图片描述


Arthas常用命令

dump 命令:该命令可以将指定Java文件的class 保存到指定的目录当中去,使用这种方式保存的文件和运行当中的字节码文件时一致的,例如:dump -d 存放目录 类的全限定名(例如下图中包名为arthas类名为Demo 所以这里的全限定名就是 arthas.Demo),例如:

在这里插入图片描述


**jad命令:**可以将已加载(正在执行中的)的类的字节码文件反编译为Java文件,通过这种方式可以看出当前执行的文件的内容到底是怎样的。使用该命令可以查看当前更新的版本是否是最新版本,例如:刚刚修复了一个bug 但是不确定此时线上是否已经更新成功,可以通过该命令对更改过的文件进行反编译,再查看以确定更新后的版本是否已经成功发布到线上环境

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

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

相关文章

Springboot与SpringSecurity使用(1):介绍、登录验证

一、介绍 Spring 是非常流行和成功的 Java 应用开发框架&#xff0c;Spring Security 正是 Spring 家族中的成员。Spring Security 基于 Spring 框架&#xff0c;提供了一套 Web 应用安全性的完整解决方案。Web 应用的安全性包括用户认证&#xff08;Authentication&#xff09…

Linux网络:传输层协议TCP(三)滑动窗口及流量控制

目录 一、关于滑动窗口在TCP中的应用 1.1什么是滑动窗口&#xff0c;为什么要有滑动窗口 1.2滑动窗口的实现 1.3滑动窗口针对丢包重传的处理机制 二、流量控制 一、关于滑动窗口在TCP中的应用 1.1什么是滑动窗口&#xff0c;为什么要有滑动窗口 在上一篇博文中博主阐述了…

植物神经紊乱拜拜啦! 6招让你心情美美哒,放松到飞起~

Hey宝贝们&#xff0c;是不是有时候觉得心里的小宇宙&#x1f30c;乱糟糟的&#xff0c;像是有一群小精灵&#x1f9da;‍♀️在跳舞&#xff0c;却偏偏踩不到点上&#xff1f;没错&#xff0c;这可能就是植物神经紊乱在作祟啦&#xff01;别怕&#xff0c;我这就给你支几招&am…

Nginx系列-12 Nginx使用Lua脚本进行JWT校验

背景 本文介绍Nginx中Lua模块使用方式&#xff0c;并结合案例进行介绍。案例介绍通过lua脚本提取HTTP请求头中的token字段&#xff0c;经过JWT校验并提取id和name信息&#xff0c;设置到http请求头中发向后段服务器。 默认情况下&#xff0c;Nginx自身不携带lua模块&#xff0…

Transformer中的Multi-head Attention机制解析——从单一到多元的关注效益最大化

Transformer中的Multi-head Attention机制解析——从单一到多元的关注效益最大化 Multi-head Attention的核心作用 组件/步骤描述多头注意力机制&#xff08;Multi-head Attention&#xff09;Transformer模型中的关键组件&#xff0c;用于处理序列数据功能允许模型同时关注到…

Vue2从基础到实战(指令篇)

Vue中的常用指令&#xff01; 概念&#xff1a;指令&#xff08;Directives&#xff09;是 Vue 提供的带有 v- 前缀 的 特殊 标签属性。 vue 中的指令按照不同的用途可以分为如下 6 大类&#xff1a; 内容渲染指令&#xff08;v-html、v-text&#xff09; 条件渲染指令&…

昇思25天学习打卡营第1天|快速入门-构建基于MNIST数据集的手写数字识别模型

非常感谢华为昇思大模型平台和CSDN邀请体验昇思大模型&#xff01;从今天起&#xff0c;我将以打卡的方式&#xff0c;结合原文搬运和个人思考&#xff0c;分享25天的学习内容与成果。为了提升文章质量和阅读体验&#xff0c;我会将思考部分放在最后&#xff0c;供大家探索讨论…

04 | 深入浅出索引(上)

此系列文章为极客时间课程《MySQL 实战 45 讲》的学习笔记&#xff01; 索引的常见模型 可以提供查询效率的数据结构有很多&#xff0c;常见的有三种&#xff1a;哈希表、有序数组、搜索数。 哈希表是一种以 key-value 形式存储的数据结构。输入一个 key&#xff0c;通过固定…

Markdown使用~~pandoc插件安装

目录 1.两大秘密武器 2.vscode创作 3.Typora的安装 4.pandoc安装 4.1百度网盘 4.2按照说明安装 4.3到达github里面下载 4.4选择对应版本 4.5进入偏好设置 4.6对于导出的路径进行配置 5.Typora和vscode的对比 6.如何正确的学习这个Typora软件 7.一点相关的说明 1.两…

做一个能和你互动玩耍的智能机器人之三

内容节选自英特尔的开源项目openbot的body目录下diy下的readme&#xff0c;这是一个组装和连线方式的说明文档&#xff0c;接线需要配合firmware固件使用&#xff0c;固件代码的接线柱是对应的。 body目录内部十分丰富&#xff0c;主要介绍了这个项目的背景和硬件以及如何让他…

datawhale逻辑推理赛题01

跟着datawhale参加了逻辑推理赛题&#xff0c;这个是一个大模型比赛入门非常好的比赛&#xff0c;可以帮助我们更快的上手大模型相关的业务 我参加的是天池的这个比赛&#xff0c;跟着datawhale官方的baseline01已经上分0.6498&#xff0c;是一个非常好的开始 后续我讲继续跟着…

java项目中添加SDK项目作为依赖使用(无需上传Maven)

需求&#xff1a; 当需要多次调用某个函数或算法时&#xff0c;不想每次调用接口都自己编写&#xff0c;可以将该项目打包&#xff0c;以添加依赖的方式实现调用 适用于&#xff1a; 无需上线的项目&#xff0c;仅公司或团队内部使用的项目 操作步骤&#xff1a; 以下面这…

Linux---进程(2)

目录 查看进程 查看进程pid 系统目录查看 理解当前工作目录用途 fork创建进程 存在问题 问题解决 问题一 问题二 本文介绍进程标识符的相关知识以及创建子进程。 查看进程 指令就是可执行程序&#xff0c;每次运行时&#xff0c;都需要被加载到内存&#xff0c;运行…

动物之森-小红书2024笔试(codefun2000)

题目链接 动物之森-小红书2024笔试(codefun2000) 题目内容 塔子哥最近在玩一款叫做“动物之森”的四字开放游戏世界。由于塔子哥氪金了&#xff0c;所以他在游戏中拥有很多个宝箱&#xff0c;每个宝箱里都装着一些他收集的宝石。每一种类型的宝石都有不同的作用。 有一天&…

java--jvm虚拟机(都是要点)

请带着以下问题&#xff0c;学习并理解jvm 问题一&#xff1a; 为什么fullGC会对系统性能有影响&#xff1f;youngGC却几乎没有&#xff1f; 问题二&#xff1a; outofmemory是什么异常&#xff1f;什么时候会出现&#xff1f;如何处理&#xff1f; 问题三&#xff1a; 线程…

鸿蒙 HarmonyOS NEXT端云一体化开发-云函数篇

前言 TODO&#xff1a;新建项目和应用&#xff0c;开通云函数服务&#xff08;AGC&#xff09;端侧开发&#xff1a;Arkts界面开发云测开发&#xff1a;云函数、认证服务、云存储、云数据库 一、登录 地址&#xff1a;https://id1.cloud.huawei.com/CAS/portal/loginAuth.htm…

Nginx周末部署

背景 Nginx是本人学习的一类中间件&#xff0c;上次完成了vue的搭建&#xff0c;所以顺便把项目加入Nginx吧 1. 镜像拉取与测试 查询dockerHub&#xff0c;选择最新最稳定的版本 docker pull nginx:stable-perl 执行下载 docker run -d --name mynginx -p 8080:80 -v D:\IM…

【Kubernetes】配置管理(一):ConfigMap

配置管理&#xff08;一&#xff09;&#xff1a;ConfigMap 1.配置管理2.使用 ConfigMap 管理 Pod 的配置信息2.1 创建 ConfigMap2.1.1 在命令行中通过指定 ConfigMap 的参数进行创建2.1.2 通过指定的配置文件创建 ConfigMap2.1.3 通过一个文件内的多个键值对创建 ConfigMap2.1…

C++数据结构重要知识点(3)(红黑树及其插入操作)

1.红黑树和AVL树的区别 红黑树和AVL树都是平衡树&#xff0c;都是为了解决二叉搜索树的劣势。其中&#xff0c;AVL树的左右子树的高度差不超过1&#xff0c;而红黑树的最长路径不超过最短路径的二倍&#xff0c;也就是说&#xff0c;红黑树是一种近似平衡&#xff0c;而AVL树是…

【设计模式】(万字总结)深入理解Java中的创建型设计模式

1. 前言 在软件开发的世界里&#xff0c;设计模式是一种被广泛接受并应用的解决方案。它们不仅仅是代码的设计&#xff0c;更是对问题的思考和解决的方法论。在Java开发中&#xff0c;特别是在面向对象的编程中&#xff0c;设计模式尤为重要。创建型设计模式&#xff0c;作为设…