JVM 面試基礎準備篇(一)

2021-02-21 架構探險之道
JVM 面試基礎準備篇(一)

1. 計算機原理

2. JVM 原理

2.1  Class文件

2.2 類文件到虛擬機

2.2.3 初始化(Initialize)

2.2.4 類加載器 classLoader

小結


今天主要分享 JVM 的基礎知識。

1. 計算機原理1.1  計算機體系結構

遵循馮諾依曼計算機結構


計算機處理數據過程

提取階段: 由輸入設備把原始數據或信息輸入給計算機存儲器存起來

解碼階段: 根據CPU的指令集架構(ISA)定義將數值解譯為指令

執行階段: 再由控制器把需要處理或計算的數據調入運算器

本質上就是CPU取數據指令然後返回

CPU=存儲器+運算器+控制器

1.2 JVM 作用.

機器語言

我們把CPU能夠直接認識的數據指令,稱為機器語言,也就是010101001這種形式

不同廠商的 CPU

不同 CPU 使用的 CPU 指令集是不一樣的,這就會有不兼容的問題;而且要是直接操作 01 這種形式的,非常麻煩並且容易出錯,硬體資源管理起來也不方便。

作業系統

2. JVM 原理

官方文檔

JDK Reference

JDK8 JVM Reference


2.1  Class文件2.1.1 生成字節碼文件
package com.example.jvm.clazz;

class Person {
    private String name = "Jack";
    private int age;
    private final double salary = 100;
    private static String address;
    private final static String hobby = "Programming";
    private static Object obj = new Object();

    public void say() {
        System.out.println("person say...");
    }

    public static int calc(int op1, int op2) {
        op1 = 3;
        int result = op1 + op2;
        Object obj = new Object();
        return result;
    }

    public static void main(String[] args) {
        calc(1, 2);
    }
}

編譯生成 class 文件:javac -g:vars Person.java


vim Person.class


前期編譯

源文件Person.java

2.1.2 查看字節碼文件

vim Person.class ,然後輸入:%!xxd 就是以16進位顯示class文件了,內容如下:


Tips

linux下查看二進位文件
以十六進位格式輸出:
od [選項] 文件
od -d 文件 十進位輸出
-o 文件 八進位輸出
-x 文件 十六進位輸出
xxd 文件 輸出十六進位

在vi命令狀態下:
:%!xxd :%!od 將當前文本轉化為16進位格式
:%!xxd -c 12 每行顯示12個字節
:%!xxd -r 將當前文本轉化回文本格式

2.1.3 類文件結構

官網說明:https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html

ClassFile {
    u4             magic;
    u2             minor_version;
    u2             major_version;
    u2             constant_pool_count;
    cp_info        constant_pool[constant_pool_count-1];
    u2             access_flags;
    u2             this_class;
    u2             super_class;
    u2             interfaces_count;
    u2             interfaces[interfaces_count];
    u2             fields_count;
    field_info     fields[fields_count];
    u2             methods_count;
    method_info    methods[methods_count];
    u2             attributes_count;
    attribute_info attributes[attributes_count];
}

分析

u4             magic;

The magic item supplies the magic number identifying the class file format; it has the value 0xCAFEBABE.

提供了一個魔法值來聲明類文件格式,對應值為cafe babe

u2             minor_version;

u2             major_version;

0000 0034 16進位的,對應10進位:16*3+4=52,標識 JDK8

u2             constant_pool_count;

The value of the constant_pool_count item is equal to the number of entries in the constant_pool table plus one. A constant_pool index is considered valid if it is greater than zero and less than constant_pool_count, with the exception for constants of type long and double noted in §4.4.5.

003f 表示有 3*16+15=62 個元素在常量池中(下標區間[1,constant_pool_count-1])。

cp_info        constant_pool[constant_pool_count-1];

The constant_pool is a table of structures (§4.4) representing various string constants, class and interface names, field names, and other constants that are referred to within the ClassFile structure and its substructures. The format of each constant_pool table entry is indicated by its first "tag" byte.

The constant_pool table is indexed from 1 to constant_pool_count - 1.

常量池主要存儲兩方面內容:字面量(Literal)和符號引用(Symbolic References)

字面量:文本字符串,final修飾等符號引用:類和接口的全限定名、欄位名稱和描述符、方法名稱和描述符

2.1.3.1  javap 驗證

javap -v -p Person.class > vp.txt 反編譯驗證字節碼和指令信息

// 打開 vp.txt
Classfile /Users/xiazhaoyang/Ashe/workspace/architectrue-adventure/code-examples/jdk-jvm-analysis/src/main/java/com/example/jvm/clazz/Person.class
Last modified 2020-3-31; size 982 bytes
MD5 checksum de6394397e12fac0f518b4de12f6cef9 // 魔法值
class com.example.jvm.clazz.Person
minor version: 0
major version: 52 // JDK 版本號
flags: ACC_SUPER
Constant pool: // 常量池
 #1 = Methodref          #10.#43        // java/lang/Object."<init>":()V
 #2 = String             #44            // Jack
 #3 = Fieldref           #13.#45        // com/example/jvm/clazz/Person.name:Ljava/lang/String;
 #4 = Double             100.0d
 #6 = Fieldref           #13.#46        // com/example/jvm/clazz/Person.salary:D
 #7 = Fieldref           #47.#48        // java/lang/System.out:Ljava/io/PrintStream;
 #8 = String             #49            // person say...
 #9 = Methodref          #50.#51        // java/io/PrintStream.println:(Ljava/lang/String;)V
#10 = Class              #52            // java/lang/Object
#11 = Methodref          #13.#53        // com/example/jvm/clazz/Person.calc:(II)I
#12 = Fieldref           #13.#54        // com/example/jvm/clazz/Person.obj:Ljava/lang/Object;
#13 = Class              #55            // com/example/jvm/clazz/Person
#14 = Utf8               name
#15 = Utf8               Ljava/lang/String;
#16 = Utf8               age
#17 = Utf8               I
#18 = Utf8               salary
#19 = Utf8               D
#20 = Utf8               ConstantValue
#21 = Utf8               address
#22 = Utf8               hobby
#23 = String             #56            // Programming
#24 = Utf8               obj
#25 = Utf8               Ljava/lang/Object;
#26 = Utf8               <init>
#27 = Utf8               ()V
#28 = Utf8               Code
#29 = Utf8               LocalVariableTable
#30 = Utf8               this
#31 = Utf8               Lcom/example/jvm/clazz/Person;
#32 = Utf8               say
#33 = Utf8               calc
#34 = Utf8               (II)I
#35 = Utf8               op1
#36 = Utf8               op2
#37 = Utf8               result
#38 = Utf8               main
#39 = Utf8               ([Ljava/lang/String;)V
#40 = Utf8               args
#41 = Utf8               [Ljava/lang/String;
#42 = Utf8               <clinit>
#43 = NameAndType        #26:#27        // "<init>":()V
#44 = Utf8               Jack
#45 = NameAndType        #14:#15        // name:Ljava/lang/String;
#46 = NameAndType        #18:#19        // salary:D
#47 = Class              #57            // java/lang/System
#48 = NameAndType        #58:#59        // out:Ljava/io/PrintStream;
#49 = Utf8               person say...
#50 = Class              #60            // java/io/PrintStream
#51 = NameAndType        #61:#62        // println:(Ljava/lang/String;)V
#52 = Utf8               java/lang/Object
#53 = NameAndType        #33:#34        // calc:(II)I
#54 = NameAndType        #24:#25        // obj:Ljava/lang/Object;
#55 = Utf8               com/example/jvm/clazz/Person
#56 = Utf8               Programming
#57 = Utf8               java/lang/System
#58 = Utf8               out
#59 = Utf8               Ljava/io/PrintStream;
#60 = Utf8               java/io/PrintStream
#61 = Utf8               println
#62 = Utf8               (Ljava/lang/String;)V
// 欄位表集合                        
{
private java.lang.String name;
  descriptor: Ljava/lang/String;
  flags: ACC_PRIVATE

private int age;
  descriptor: I
  flags: ACC_PRIVATE

private final double salary;
  descriptor: D
  flags: ACC_PRIVATE, ACC_FINAL
  ConstantValue: double 100.0d

private static java.lang.String address;
  descriptor: Ljava/lang/String;
  flags: ACC_PRIVATE, ACC_STATIC

private static final java.lang.String hobby;
  descriptor: Ljava/lang/String;
  flags: ACC_PRIVATE, ACC_STATIC, ACC_FINAL
  ConstantValue: String Programming

private static java.lang.Object obj;
  descriptor: Ljava/lang/Object;
  flags: ACC_PRIVATE, ACC_STATIC
  // 方法表集合
com.example.jvm.clazz.Person();
  descriptor: ()V
  flags:
  Code:
    stack=3, locals=1, args_size=1
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: aload_0
       5: ldc           #2                  // String Jack
       7: putfield      #3                  // Field name:Ljava/lang/String;
      10: aload_0
      11: ldc2_w        #4                  // double 100.0d
      14: putfield      #6                  // Field salary:D
      17: return
    LocalVariableTable:
      Start  Length  Slot  Name   Signature
          0      18     0  this   Lcom/example/jvm/clazz/Person;

public void say();
  descriptor: ()V
  flags: ACC_PUBLIC
  Code:
    stack=2, locals=1, args_size=1
       0: getstatic     #7                  // Field java/lang/System.out:Ljava/io/PrintStream;
       3: ldc           #8                  // String person say...
       5: invokevirtual #9                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
       8: return
    LocalVariableTable:
      Start  Length  Slot  Name   Signature
          0       9     0  this   Lcom/example/jvm/clazz/Person;

public static int calc(int, int);
  descriptor: (II)I
  flags: ACC_PUBLIC, ACC_STATIC
  Code:
    stack=2, locals=4, args_size=2
       0: iconst_3
       1: istore_0
       2: iload_0
       3: iload_1
       4: iadd
       5: istore_2
       6: new           #10                 // class java/lang/Object
       9: dup
      10: invokespecial #1                  // Method java/lang/Object."<init>":()V
      13: astore_3
      14: iload_2
      15: ireturn
    LocalVariableTable:
      Start  Length  Slot  Name   Signature
          0      16     0   op1   I
          0      16     1   op2   I
          6      10     2 result   I
         14       2     3   obj   Ljava/lang/Object;

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: iconst_1
       1: iconst_2
       2: invokestatic  #11                 // Method calc:(II)I
       5: pop
       6: return
    LocalVariableTable:
      Start  Length  Slot  Name   Signature
          0       7     0  args   [Ljava/lang/String;

static {};
  descriptor: ()V
  flags: ACC_STATIC
  Code:
    stack=2, locals=0, args_size=0
       0: new           #10                 // class java/lang/Object
       3: dup
       4: invokespecial #1                  // Method java/lang/Object."<init>":()V
       7: putstatic     #12                 // Field obj:Ljava/lang/Object;
      10: return
}

2.1.3.2 常量池分析

官網:https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4

上面分析到常量池中常量的數量是62,接下來我們來具體分析一下這62個常量:

cp_info constant_pool[constant_pool_count-1] 也就是這塊包括的信息 ,

cp_info 其實就是一個表格的形式 All constant_pool table entries have the following general format:

cp_info {
    u1 tag;
    u1 info[];
}

常量池標識符

Constant TypeValueCONSTANT_Class7CONSTANT_Fieldref9CONSTANT_Methodref10CONSTANT_InterfaceMethodref11CONSTANT_String8CONSTANT_Integer3CONSTANT_Float4CONSTANT_Long5CONSTANT_Double6CONSTANT_NameAndType12CONSTANT_Utf81CONSTANT_MethodHandle15CONSTANT_MethodType16CONSTANT_InvokeDynamic18

常量池中的每一個元素必須以 1 byte 的標識符號作為開始,以此來表示它的具體 cp_info 類型。上表中列出的為官方聲明合法的標識符。

00000000: cafe babe 0000 0034 003f -> 0a00 0a00 2b08  ..4.?....+.
00000010: 002c 0900 0d00 2d06 4059 0000 0000 0000  .,....-.@Y.

接著往後面數一個 u1: 0a,表示10,對應 CONSTANT_Methodref ,表示這是一個方法引用。
CONSTANT_Methodref_info {
    u1 tag;
    u2 class_index;
    u2 name_and_type_index;
}

往下數一個 u1: 00 標示起始位,對應其具體的 cp_info 類型

往下數兩個 u2

00 0a 對應 10, 代表的是class_index,表示該方法所屬的類在常量池中的索引

00 2b對應 32+11=43,代表的是name_and_type_index,表示該方法的名稱和類型的索引

#1 = Methodref          #10.#43        // java/lang/Object."<init>":()V

往下數一個 u1 是 08,表示 CONSTANT_String
CONSTANT_String_info {
    u1 tag;
    u2 string_index;
}

根據之前的規律,第一個 u1 表示類型,往後數一個 u2 表示對應存儲指向的索引位置

00000000: cafe babe 0000 0034 003f 0a00 0a00 2b08  ..4.?....+.
00000010: -> 002c 0900 0d00 2d06 4059 0000 0000 0000  .,....-.@Y.

002c = 32 + 12 = 44;

#2 = String             #44            // Jack

後續的依此類推,簡而言之,Java 通過這種方式來表述一個類文件的結構。

2.1.3.3 結構劃分2.2 類文件到虛擬機

所謂類加載機制就是

轉換解析和初始化形成可以虛擬機直接使用的Java 類型,即 java.lang.Class
2.2.1 裝載

查找和導入class文件

將這個字節流所代表的靜態存儲結構轉化為方法區的運行時數據結構在Java堆中生成一個代表這個類的 java.lang.Class 對象,作為對方法區中這些數據的訪問入口

Class 對象封裝了類在方法區內的數據結構,並且向 Java 程式設計師提供了訪問方法區內的數據結構的接口。在 Java 堆中生成一個代表這個類的 java.lang.Class 對象,作為對方法區中這些數據的訪問入口:


2.2.2 連結(Link)2.2.2.1 驗證(verify)

保證被加載類的正確性

2.2.2.2 準備(prepare)

為類的靜態變量分配內存,並將其初始化為默認值

graph TD
A[方法區]
A-->A1[靜態變量的初始化 int age=10]
A1 --> B[堆]


public class Demo1 {
    private static int i;
    public static void main(String[] args) {
     // 正常列印出0,因為靜態變量i在準備階段會有默認值0 
      System.out.println(i);
    } 
}
public class Demo2 {
    public static void main(String[] args) {
      // 編譯通不過,因為局部變量沒有賦值不能被使用 int i;
    System.out.println(i);
    } 
}

2.2.2.3 解析(resolve)

將前文分析的類文件結構中的符號引用轉換為直接引用

符號引用就是一組符號來描述目標,可以是任何字面量。
直接引用就是直接指向目標的指針、相對偏移量或一個間接定位到目標的句柄。

解析階段是虛擬機將常量池內的符號引用替換為直接引用的過程。解析動作主要針對類或接口、欄位、類方法、接口方法、方法類型、方法句柄和調用限定符7類符號引用進行。

2.2.3 初始化(Initialize)

對類的靜態變量,靜態代碼塊執行初始化操作

graph TD
A[方法區]
A-->A1[將類中的符號引用轉換為直接引用]
A1 --> B[堆]

2.2.4 類加載器 classLoader

在裝載 (Load) 階段,其中第(1)步:通過類的全限定名獲取其定義的二進位字節流,需要藉助類裝載器完成,顧名思義,就是用來裝載Class 文件的。

2.2.4.1 分類Bootstrap ClassLoader 負責加載$JAVA_HOME中 jre/lib/rt.jar 裡所有的class或 Xbootclassoath選項指定的jar包。由C++實現,不是ClassLoader子類。Extension ClassLoader 負責加載java平臺中擴展功能的一些jar包,包括$JAVA_HOME中 jre/lib/*.jar 或 -Djava.ext.dirs指定目錄下的jar包。App ClassLoader 負責加載classpath中指定的jar包及 Djava.class.path 所指定目錄下的類和 jar包。Custom ClassLoader 通過 java.lang.ClassLoader 的子類自定義加載 class,屬於應用程式根據 自身需要自定義的 ClassLoader,如 tomcat、jboss 都會根據 j2ee 規範自行實現 ClassLoader。2.2.4.2 圖解
public class ClassLoaderTest {

        public static void main(String[] args) {
            // App ClassLoader
            System.out.println(new ClassLoaderTest().getClass().getClassLoader());
            // Ext ClassLoader
            System.out.println(new ClassLoaderTest().getClass().getClassLoader().getParent());
            // Bootstrap ClassLoader
            System.out.println(new ClassLoaderTest().getClass().getClassLoader().getParent().getParent());
            System.out.println(new String().getClass().getClassLoader());
        }
}

輸出

sun.misc.Launcher$AppClassLoader@18b4aac2
sun.misc.Launcher$ExtClassLoader@59690aa4
null
null

2.2.4.3 類加載原則(雙親委派)

自底向上,從Custom ClassLoader到BootStrap ClassLoader逐層檢查,只要某個Classloader已加 載,就視為已加載此類,保證此類只所有ClassLoader加載一次。

加載的順序 自頂向下,也就是由上層來逐層嘗試加載此類。
protected Class<?> loadClass(String name, boolean resolve)
        throws ClassNotFoundException
    {
        synchronized (getClassLoadingLock(name)) {
            // First, check if the class has already been loaded
            Class<?> c = findLoadedClass(name);
            if (c == null) {
                long t0 = System.nanoTime();
                try {
                   // 如果父加載器存在,委託給父類加載器加載
                    if (parent != null) {
                        c = parent.loadClass(name, false);
                    } else {
                        c = findBootstrapClassOrNull(name);
                    }
                } catch (ClassNotFoundException e) {
                    // ClassNotFoundException thrown if class not found
                    // from the non-null parent class loader
                }

                if (c == null) {
                    // If still not found, then invoke findClass in order
                    // to find the class.
                    long t1 = System.nanoTime();
                    c = findClass(name);

                    // this is the defining class loader; record the stats
                    sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
                    sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
                    sun.misc.PerfCounter.getFindClasses().increment();
                }
            }
            if (resolve) {
                resolveClass(c);
            }
            return c;
        }
    }

2.2.4.4 自定義加載器(破壞雙親委派)
小結

JVM 文件結構是理解 JVM 運行時數據區和內存模型的必備知識,簡單總結下:

類文件要經過裝載、連結、初始化後才能在虛擬機中被使用Class 文件中定義了文件頭、常量池、欄位表和方法表

相關焦點

  • 面經手冊 · 第23篇《JDK、JRE、JVM,是什麼關係?》
    目錄一、前言二、面試題三、JDK、JRE、JVM1. Java 平臺標準(JDK 8)2. JDK 目錄結構和作用3. JDK 是什麼?4. JRE 是什麼?5. JVM 是什麼?四、總結五、系列推薦一、前言截至到這已經寫了22篇面經手冊,你看了多少?😄其實小傅哥就是借著面經的幌子在講 Java 核心技術,探索這些核心知識點面試的背後到底在問什麼。
  • jvm面試系列一:java內存模型你掌握了多少?
    今天我們就來聊一聊Java內存模型,面試中面試官會通過考察你對jvm的理解更深入得了解你的水平。
  • JDK、JRE、JVM,是什麼關係?
    一、前言截至到這已經寫了22篇面經手冊,你看了多少?其實小傅哥就是借著面經的幌子在講 Java 核心技術,探索這些核心知識點面試的背後到底在問什麼。想問一些面試官,是因為大家都在問所以你問,還是你想從這裡問出什麼? 其實可能很多面試官如果不了解這些技術,往往會被求職者的答案擊碎內心,哈哈哈哈哈哈。
  • JVM、GC 大串講,面試夠用了
    字節碼解釋器工作時就是通過改變這個計數器的值來選取下一條需要執行的字節碼指令,分支、循環、跳轉、異常處理、線程恢復等基礎功能都需要依賴這個計數器來完成。java虛擬機的多線程是通過線程輪流切換並分配處理器執行時間的方式來實現的,任何一個確定的時刻,一個處理器都只執行一條線程中的指令。
  • 求職面試篇:面試準備之簡歷的準備
    面試準備部分講分四篇文章寫完,請持續關注!第一篇:面試準備1——關於簡歷方面的準備第二篇:面試準備2——關於面試公司和崗位的了解第三篇:面試準備3——關於面試官可能的問題的準備第四篇:面試準備4——一些細節問題【正文】 面試如作戰,我們看戰爭影視劇的時候
  • JVM菜鳥進階高手之路十四:分析篇
    題目回顧JVM菜鳥進階高手之路十三,問題現象就是相同的代碼,jvm參數不一樣,表現的現象不一樣。說明上面的題目僅僅是一個切入點而已,希望通過一個切入點把jvm的一些基礎知識剛剛好說明下,順便解答下上面的現象。內存相關簡單說明
  • 《變態面試官》系列——JVM基礎你會麼
    我愛學習,學習使我媽快樂,我媽快樂全家快樂好看請點讚,不喜請輕噴一入編程深似海,編程世界Very深。這裡是九神說編程,今天給大家說的是一個頂級大佬閒的無聊,在編程世界已經999級,閒來無事去新手村練小號的故事。大佬本以為只要拿出0.001%的功力就可以輕鬆入職升級了,沒有想到卻遇上了變態面試官!
  • 聊到JVM(還怕面試官問JVM嗎?)
    不管是工作還是面試中,JVM都是必考題。如果不懂JVM的話,薪酬會非常吃虧(近70%的面試者掛在JVM上了)。經過一段時間的研究!!接下來,我將以大白話從頭到尾給大家講講Java虛擬機!!1、什麼是JVM?在哪? JVM是Java Virtual Machine(Java虛擬機)的縮寫,JVM是一種用於計算設備的規範,它是一個虛構出來的計算機,是通過在實際的計算機上仿真模擬各種計算機功能來實現的。
  • JVM之jvisualvm的簡單使用
    JVM之jvisualvm的簡單使用閱讀本篇教程之前,必須先閱讀JVM之jconsole的簡單使用這篇教程。jvisualvm比jconsole稍微好用了那麼一點點,其實就是圖形化界面做的比jconsole好看了一點。還有一點就是jvisualvm支持插件安裝。
  • 面試官問我:Object o = new Object() 佔用了多少個字節?
    小小面試一下前言蜜語最近馬師傅火的不要不要的,雖然沒有搶到耗子尾汁的商標註冊權,但是必須得蹭一波馬師傅的熱度,下面就是閃電五連鞭的教學環節,你準備好了嗎!在正式內容開始前先甩兩篇關於類加載機制和內存布局的文章,因為今天的內容多少與這兩篇文章有直接的聯繫,對這方面還比較薄弱的朋友可以先看看,地址我放在下面。jvm┃java內存區域,跳槽大廠必會知識點!moon不講武德!!!一個類加載機制給面試官說蒙了!!
  • 【乾貨篇】複試準備之面試
    大家也休息了一段時間了 所以該好好準備複試了 關於複試的準備 我們也推送了相關方面的文章
  • 13道 常見的JVM 面試題
    加載過程:加載 -> 驗證 -> 準備 -> 解析 -> 初始化 -> 使用 -> 卸載驗證 -> 準備 -> 解析 這三步合起來稱為 連接 1.準備準備階段為類變量分配內存 和設置類變量初始化。這個過程中,只對static類變量進行內存分配,這個時候只是分配內存,沒有進行複製,所有的類變量都是初始化值。如果是final的話,會直接對應到常量池中。會在準備階段直接賦值。4.解析解析階段是讀符號引用進行解析。
  • JAVA面試題及答案一百道(SE篇上)——老面試官的經驗之談
    上篇請看這裡-->JAVA面試題及答案一百道(SE篇上)——老面試官的經驗之談本文的面試題裡有部分關於設計模式的題目,但是阿偉要在這裡提醒各位一句話,找工作時面試官的水平可以清晰地反映出這個公司的水平,如果你的面試官抓住設計模式死摳死問,想讓你一成不變的把網上的面試答案背下來
  • 20道阿里面試必問JVM面試專題(文末附答案及JVM學習文檔)
    前言很多朋友對面試不夠了解,不知道如何準備,對面試環節的設置以及目的不夠了解,因此成功率不高。通常情況下校招生面試的成功率低於1%,而社招的面試成功率也低於5%,所以對於候選人一定要知道設立面試的初衷以及每個環節的意義,有的放矢……而JVM 是 Java 程序運行基礎,面試時一定會遇到 JVM 相關的題。所以我們準備了部分的面試真題,作為參考,看看你距離阿里還差多遠。1.
  • 想理解JVM看了這篇文章,就知道了!
    本次將對jvm有更深入的學習,我們不僅要讓程序能跑起來,而且是可以跑的更快!可以分析解決在生產環境中所遇到的各種「棘手」的問題,比如運行的應用卡住了,日誌不輸出,程序沒有反應,CPU負載突然升高,多線程應用下,如何分配線程數量等。
  • 面試官:為什麼java中靜態方法不能調用非靜態方法或變量?
    這個可能很多人之前學習jvm的時候都會遇到,屬於一個小問題,寫這篇文章的原因是我在看java相關的面試題目中遇到的,因此順手總結一下:一、例子我們先看效果:我們在靜態方法我們不直接講原因,先從jvm說起:這是一張類加載的生命周期圖。
  • JVM 面試題解答(40道全)
    /se8/html/jvms-2.html#jvms-2.56、運行時棧幀包含哪些結構?表示當整個堆內存使用達到一定比例(默認是 45%),並發標記階段就會被啟動-XX:ConcGCThreads,表示並發垃圾收集器使用的線程數量,默認值隨 JVM 運行的平臺不同而變動,不建議修改參數查詢官網地址:https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html建議面試時最好能記住
  • 2019 最新 200 道 Java 面試題
    為什麼要公開這些面試題?原因一:身邊從事 Java 開發的人員越來越多,我的表弟表妹們,朋友的表弟表妹們,朋友的朋友的表弟表妹們,每次問我要相同的面試複習材料,已經讓我疲於應付,索性整理出來,直接發連結給他們。
  • 面試達人親授:面試準備三部曲
    這是曹將會客廳第 6 篇文章關於應屆生求職主題,我們已經發布了三篇主題文章
  • 來自JVM的一封ClassFile介紹信
    我在jvm中佔有很重要的地位,你可去看看jvm規範中我佔了多少篇幅,告訴你,足足有大半本書!第四章,標題叫做 The class File Format。可以這麼說。你把編譯器、字節碼、jit那些看過以後,再把我搞清楚,基本上jvm你也就精通了。鑑於我這麼重要,今天我介紹下自己。