1. 程式人生 > 其它 >JAVA面試題--Java基礎

JAVA面試題--Java基礎

Java基礎

Java基礎

1.說下面向物件四大特性

封裝、繼承、多型、抽象。

2.Java語言有哪些特點

簡單易學(Java語言的語法與C語言和C++語言很接近)

面向物件(封裝,繼承,多型)

平臺無關性(Java虛擬機器實現平臺無關性)

支援網路程式設計並且很方便(Java語言誕生本身就是為簡化網路程式設計設計的)

支援多執行緒(多執行緒機制使應用程式在同一時間並行執行多項任)

健壯性(Java語言的強型別機制、異常處理、垃圾的自動收集等)

安全性

3.什麼是Java程式的主類?應用程式和小程式的主類有何不同?

一個程式中可以有多個類,但只能有一個類是主類。在Java應用程式中,這個主類是指包含main()方法的類。而在Java小程式中,這個主類是一個繼承自系統類JApplet或Applet的子類。應用程式的主類不一定要求是public類,但小程式的主類要求必須是public類。主類是Java程式執行的入口點。

4.訪問修飾符public,private,protected,以及不寫(預設)時的區別?

修飾符 當前類 同 包 子 類 其他包
public
protected ×
default × ×
private × × ×

類的成員不寫訪問修飾時預設為default。預設對於同一個包中的其他類相當於公開(public),對於不是同一個包中的其他類相當於私有(private)。受保護(protected)對子類相當於公開,對不是同一包中的沒有父子關係的類相當於私有。Java中,外部類的修飾符只能是public或預設,類的成員(包括內部類)的修飾符可以是以上四種。

5.float f=3.4;是否正確?

不正確。3.4是雙精度數,將雙精度型(double)賦值給浮點型(float)屬於下轉型(down-casting,也稱為窄化)會造成精度損失,因此需要強制型別轉換float f =(float)3.4; 或者寫成float f =3.4F;。

6.Java有沒有goto?

goto 是Java中的保留字,在目前版本的Java中沒有使用。(根據James Gosling(Java之父)編寫的《The Java Programming Language》一書的附錄中給出了一個Java關鍵字列表,其中有goto和const,但是這兩個是目前無法使用的關鍵字,因此有些地方將其稱之為保留字,其實保留字這個詞應該有更廣泛的意義,因為熟悉C語言的程式設計師都知道,在系統類庫中使用過的有特殊意義的單詞或單詞的組合都被視為保留字)

7.&和&&的區別?

&運算子有兩種用法:(1)按位與;(2)邏輯與。

&&運算子是短路與運算。

邏輯與跟短路與的差別是非常巨大的,雖然二者都要求運算子左右兩端的布林值都是true整個表示式的值才是true。&&之所以稱為短路運算是因為,如果&&左邊的表示式的值是false,右邊的表示式會被直接短路掉,不會進行運算。很多時候我們可能都需要用&&而不是&,例如在驗證使用者登入時判定使用者名稱不是null而且不是空字串,應當寫為:username != null &&!username.equals(""),二者的順序不能交換,更不能用&運算子,因為第一個條件如果不成立,根本不能進行字串的equals比較,否則會產生NullPointerException異常。注意:邏輯或運算子(|)和短路或運算子(||)的差別也是如此。

8.Math.round(11.5) 等於多少?Math.round(-11.5)等於多少?

Math.round(11.5)的返回值是12,Math.round(-11.5)的返回值是-11。四捨五入的原理是在引數上加0.5然後進行下取整。

9.用最有效率的方法計算2乘以8?

2 << 3

10.什麼是Java註釋

定義:用於解釋說明程式的文字

Java註釋的分類

  • 單行註釋
    格式: // 註釋文字
  • 多行註釋
    格式: /* 註釋文字 */
  • 文件註釋
    格式:/** 註釋文字 */

Java註釋的作用
在程式中,尤其是複雜的程式中,適當地加入註釋可以增加程式的可讀性,有利於程式的修改、除錯和交流。註釋的內容在程式編譯的時候會被忽視,不會產生目的碼,註釋的部分不會對程式的執行結果產生任何影響。

注意事項:多行和文件註釋都不能巢狀使用。

11.Java有哪些資料型別

定義:Java語言是強型別語言,對於每一種資料都定義了明確的具體的資料型別,在記憶體中分配了不同大小的記憶體空間。

  • 基本資料型別
    • 數值型
      • 整數型別(byte,short,int,long)
      • 浮點型別(float,double)
    • 字元型(char)
    • 布林型(boolean)
  • 引用資料型別
    • 類(class)
    • 介面(interface)
    • 陣列([])

12.final 有什麼用?

用於修飾類、屬性和方法;

  • 被final修飾的類不可以被繼承
  • 被final修飾的方法不可以被重寫
  • 被final修飾的變數不可以被改變,被final修飾不可變的是變數的引用,而不是引用指向的內容,引用指向的內容是可以改變的

13.final finally finalize的區別

  • final可以修飾類、變數、方法,修飾類表示該類不能被繼承、修飾方法表示該方法不能被重寫、修飾變量表
    示該變數是一個常量不能被重新賦值。
  • finally一般作用在try-catch程式碼塊中,在處理異常的時候,通常我們將一定要執行的程式碼方法finally程式碼塊
    中,表示不管是否出現異常,該程式碼塊都會執行,一般用來存放一些關閉資源的程式碼。
  • finalize是一個方法,屬於Object類的一個方法,而Object類是所有類的父類,該方法一般由垃圾回收器來調
    用,當我們呼叫System.gc() 方法的時候,由垃圾回收器呼叫finalize(),回收垃圾,一個物件是否可回收的
    最後判斷。

14.String str = "i" 和String str = new String("1")一樣嗎?

不一樣,因為記憶體的分配方式不一樣。String str = "i"的方式JVM會將其分配到常量池中,而String str = new String("i")JVM會將其分配到堆記憶體中。

15.Java 中操作字串都有哪些類?它們之間有什麼區別?

操作字串的類有:String、StringBuffer、StringBuilder。
String 和 StringBuffer、StringBuilder 的區別在於 String 宣告的是不可變的物件,每次操作都會生成新的 String 物件,再將指標指向新的 String 物件,而 StringBuffer 、 StringBuilder 可以在原有物件的基礎上進行操作,所以在經常改變字串內容的情況下最好不要使用 String。
StringBuffer 和 StringBuilder 最大的區別在於,StringBuffer 是執行緒安全的,而 StringBuilder 是非執行緒安全的,但 StringBuilder 的效能卻高於 StringBuffer,所以在單執行緒環境下推薦使用 StringBuilder,多執行緒環境下推薦使用 StringBuffer。

16.Java中為什麼要用 clone?

在實際程式設計過程中,我們常常要遇到這種情況:有一個物件 A,在某一時刻 A 中已經包含了一些有效值,此時可能會需要一個和 A 完全相同新物件 B,並且此後對 B 任何改動都不會影響到 A 中的值,也就是說,A 與 B 是兩個獨立的物件,但 B 的初始值是由 A 物件確定的。在 Java 語言中,用簡單的賦值語句是不能滿足這種需求的。要滿足這種需求雖然有很多途徑,但clone()方法是其中最簡單,也是最高效的手段。

17.深克隆和淺克隆?

淺克隆:建立一個新物件,新物件的屬性和原來物件完全相同,對於非基本型別屬性,仍指向原有屬性所指向的物件的記憶體地址。

深克隆:建立一個新物件,屬性中引用的其他物件也會被克隆,不再指向原有物件地址。

18.new一個物件的過程和clone一個物件的區別?

new 操作符的本意是分配記憶體。程式執行到 new 操作符時,首先去看 new 操作符後面的型別,因為知道了型別,才能知道要分配多大的記憶體空間。分配完記憶體之後,再呼叫建構函式,填充物件的各個域,這一步叫做物件的初始化,構造方法返回後,一個物件建立完畢,可以把他的引用(地址)釋出到外部,在外部就可以使用這個引用操縱這個物件。

clone 在第一步是和 new 相似的,都是分配記憶體,呼叫 clone 方法時,分配的記憶體和原物件(即呼叫 clone 方法的物件)相同,然後再使用原物件中對應的各個域,填充新物件的域,填充完成之後,clone方法返回,一個新的相同的物件被建立,同樣可以把這個新物件的引用釋出到外部。

19.Java中實現多型的機制是什麼?

Java中的多型靠的是父類或介面定義的引用變數可以指向子類或具體實現類的例項物件,而程式呼叫的方法在執行期才動態繫結,就是引用變數所指向的具體例項物件的方法,也就是記憶體里正在執行的那個物件的方法,而不是引用變數的型別中定義的方法。

20.談談你對多型的理解?

多型就是指程式中定義的引用變數所指向的具體型別和通過該引用變數發出的方法呼叫在程式設計時並不確定,而是在程式執行期間才確定,即一個引用變數到底會指向哪個類的例項物件,該引用變數發出的方法呼叫到底是哪個類中實現的方法,必須在程式執行期間才能決定。因為在程式執行時才確定具體的類,這樣,不用修改原始碼,就可以讓引用變數繫結到各種不同的物件上,從而導致該引用呼叫的具體方法隨之改變,即不修改程式程式碼就可以改變程式執行時所繫結的具體程式碼,讓程式可以選擇多個執行狀態,這就是多型性。

21.構造器(constructor)是否可被重寫(override)?

答:構造器不能被繼承,因此不能被重寫,但可以被過載。

22.兩個物件值相同(x.equals(y) == true),但卻可有不同的hash code,這句話對不對?

不對,如果兩個物件x和y滿足x.equals(y) == true,它們的雜湊碼(hash code)應當相同。

Java對於eqauls方法和hashCode方法是這樣規定的:

(1)如果兩個物件相同(equals方法返回true),那麼它們的hashCode值一定要相同;

(2)如果兩個物件的hashCode相同,它們並不一定相同。

當然,你未必要按照要求去做,但是如果你違背了上述原則就會發現在使用容器時,相同的物件可以出現在Set集合中,同時增加新元素的效率會大大下降(對於使用雜湊儲存的系統,如果雜湊碼頻繁的衝突將會造成存取效能急劇下降)。

23.是否可以繼承String類?

String 類是final類,不可以被繼承。

補充:繼承String本身就是一個錯誤的行為,對String型別最好的重用方式是關聯關係(Has-A)和依賴關係(Use-A)而不是繼承關係(Is-A)。

24.String類的常用方法有哪些?

•indexof();返回指定字元的的索引。

•charAt();返回指定索引處的字元。

•replace();字串替換。

•trim();去除字串兩端空格。

•splt();字串分割,返回分割後的字串陣列。

•getBytes();返回字串byte型別陣列。

•length();返回字串長度。

•toLowerCase();將字串轉換為小寫字母。

•toUpperCase();將字串轉換為大寫字母。

•substring();字串擷取。

•equals();比較字串是否相等。

25.char型變數中能否能不能儲存一箇中文漢字,為什麼?

char可以儲存一箇中文漢字,因為Java中使用的編碼是Unicode(不選擇任何特定的編碼,直接使用字元在字符集中的編號,這是統一的唯一方法),一個char 型別佔2個位元組(16 位元),所以放一箇中文是沒問題的。

26.this關鍵字的用法

this是自身的一個物件,代表物件本身,可以理解為:指向物件本身的一個指標。

this的用法在java中大體可以分為3種:

1.普通的直接引用,this相當於是指向當前物件本身。

2.形參與成員名字重名,用this來區分:

public Person(String name, int age) {
    this.name = name;
    this.age = age;
}

3.引用本類的建構函式

class Person{
    private String name;
    private int age;
    
    public Person() {
    }
 
    public Person(String name) {
        this.name = name;
    }
    public Person(String name, int age) {
        this(name);
        this.age = age;
    }
}

27.super關鍵字的用法

super可以理解為是指向自己超(父)類物件的一個指標,而這個超類指的是離自己最近的一個父類。

super也有三種用法:

1.普通的直接引用

與this類似,super相當於是指向當前物件的父類的引用,這樣就可以用super.xxx來引用父類的成員。

2.子類中的成員變數或方法與父類中的成員變數或方法同名時,用super進行區分

class Person{
    protected String name;
 
    public Person(String name) {
        this.name = name;
    }
 
}
 
class Student extends Person{
    private String name;
 
    public Student(String name, String name1) {
        super(name);
        this.name = name1;
    }
 
    public void getInfo(){
        System.out.println(this.name);      //Child
        System.out.println(super.name);     //Father
    }
 
}

public class Test {
    public static void main(String[] args) {
       Student s1 = new Student("Father","Child");
       s1.getInfo();
 
    }
}

3.引用父類建構函式

3、引用父類建構函式

  • super(引數):呼叫父類中的某一個建構函式(應該為建構函式中的第一條語句)。
  • this(引數):呼叫本類中另一種形式的建構函式(應該為建構函式中的第一條語句)。

28.this與super的區別

  • super:它引用當前物件的直接父類中的成員(用來訪問直接父類中被隱藏的父類中成員資料或函式,基類與派生類中有相同成員定義時如:super.變數名 super.成員函資料名(實參)
  • this:它代表當前物件名(在程式中易產生二義性之處,應使用this來指明當前物件;如果函式的形參與類中的成員資料同名,這時需用this來指明成員變數名)
  • super()和this()類似,區別是,super()在子類中呼叫父類的構造方法,this()在本類內呼叫本類的其它構造方法。
  • super()和this()均需放在構造方法內第一行。
  • 儘管可以用this呼叫一個構造器,但卻不能呼叫兩個。
  • this和super不能同時出現在一個建構函式裡面,因為this必然會呼叫其它的建構函式,其它的建構函式必然也會有super語句的存在,所以在同一個建構函式裡面有相同的語句,就失去了語句的意義,編譯器也不會通過。
  • this()和super()都指的是物件,所以,均不可以在static環境中使用。包括:static變數,static方法,static語句塊。
  • 從本質上講,this是一個指向本物件的指標, 然而super是一個Java關鍵字。

29.static存在的主要意義

static的主要意義是在於建立獨立於具體物件的域變數或者方法。 以致於即使沒有建立物件,也能使用屬性和呼叫方法 !

static關鍵字還有一個比較關鍵的作用就是 用來形成靜態程式碼塊以優化程式效能 。static塊可以置於類中的任何地方,類中可以有多個static塊。在類初次被載入的時候,會按照static塊的順序來執行每個static塊,並且只會執行一次。

為什麼說static塊可以用來優化程式效能,是因為它的特性:只會在類載入的時候執行一次。因此,很多時候會將一些只需要進行一次的初始化操作都放在static程式碼塊中進行。

30.static的獨特之處

1、被static修飾的變數或者方法是獨立於該類的任何物件,也就是說,這些變數和方法 不屬於任何一個例項物件,而是被類的例項物件所共享 。

怎麼理解 “被類的例項物件所共享” 這句話呢?就是說,一個類的靜態成員,它是屬於大夥的【大夥指的是這個類的多個物件例項,我們都知道一個類可以建立多個例項!】,所有的類物件共享的,不像成員變數是自個的【自個指的是這個類的單個例項物件】…我覺得我已經講的很通俗了,你明白了咩?

2、在該類被第一次載入的時候,就會去載入被static修飾的部分,而且只在類第一次使用時載入並進行初始化,注意這是第一次用就要初始化,後面根據需要是可以再次賦值的。

3、static變數值在類載入的時候分配空間,以後建立類物件的時候不會重新分配。賦值的話,是可以任意賦值的!

4、被static修飾的變數或者方法是優先於物件存在的,也就是說當一個類載入完畢之後,即便沒有建立物件,也可以去訪問。

31.static應用場景

因為static是被類的例項物件所共享,因此如果 某個成員變數是被所有物件所共享的,那麼這個成員變數就應該定義為靜態變數 。

因此比較常見的static應用場景有:

1、修飾成員變數 2、修飾成員方法 3、靜態程式碼塊 4、修飾類【只能修飾內部類也就是靜態內部類】 5、靜態導包

32.static注意事項

1、靜態只能訪問靜態。 2、非靜態既可以訪問非靜態的,也可以訪問靜態的。

33.break ,continue ,return 的區別及作用

break 跳出總上一層迴圈,不再執行迴圈(結束當前的迴圈體)

continue 跳出本次迴圈,繼續執行下次迴圈(結束正在執行的迴圈 進入下一個迴圈條件)

return 程式返回,不再執行下面的程式碼(結束當前的方法 直接返回)

34.在Java中定義一個不做事且沒有引數的構造方法的作用

Java程式在執行子類的構造方法之前,如果沒有用super()來呼叫父類特定的構造方法,則會呼叫父類中“沒有引數的構造方法”。因此,如果父類中只定義了有引數的構造方法,而在子類的構造方法中又沒有用super()來呼叫父類中特定的構造方法,則編譯時將發生錯誤,因為Java程式在父類中找不到沒有引數的構造方法可供執行。解決辦法是在父類里加上一個不做事且沒有引數的構造方法。

35.構造方法有哪些特性?

名字與類名相同;

沒有返回值,但不能用void宣告建構函式;

生成類的物件時自動執行,無需呼叫。

36.靜態變數和例項變數區別

靜態變數: 靜態變數由於不屬於任何例項物件,屬於類的,所以在記憶體中只會有一份,在類的載入過程中,JVM只為靜態變數分配一次記憶體空間。

例項變數: 每次建立物件,都會為每個物件分配成員變數記憶體空間,例項變數是屬於例項物件的,在記憶體中,建立幾次物件,就有幾份成員變數。

37.靜態方法和例項方法有何不同?

靜態方法和例項方法的區別主要體現在兩個方面:

  1. 在外部呼叫靜態方法時,可以使用"類名.方法名"的方式,也可以使用"物件名.方法名"的方式。而例項方法只有後面這種方式。也就是說,呼叫靜態方法可以無需建立物件。
  2. 靜態方法在訪問本類的成員時,只允許訪問靜態成員(即靜態成員變數和靜態方法),而不允許訪問例項成員變數和例項方法;例項方法則無此限制

38.什麼是方法的返回值?返回值的作用是什麼?

方法的返回值是指我們獲取到的某個方法體中的程式碼執行後產生的結果!(前提是該方法可能產生結果)。返回值的作用:接收出結果,使得它可以用於其他的操作!

39.什麼是內部類?

在Java中,可以將一個類的定義放在另外一個類的定義內部,這就是 內部類 。內部類本身就是類的一個屬性,與其他屬性定義方式一致。

40.內部類的分類有哪些

內部類可以分為四種: 成員內部類、區域性內部類、匿名內部類和靜態內部類 。

41.Java中異常分為哪些種類?

按照異常需要處理的時機分為編譯時異常(也叫受控異常)也叫 CheckedException 和執行時異常(也叫非受控異常)也叫 UnCheckedException。Java認為Checked異常都是可以被處理的異常,所以Java程式必須顯式處理Checked異常。如果程式沒有處理Checked 異常,該程式在編譯時就會發生錯誤無法編譯。這體現了Java 的設計哲學:沒有完善錯誤處理的程式碼根本沒有機會被執行。對Checked異常處理方法有兩種:

● 第一種:當前方法知道如何處理該異常,則用try...catch塊來處理該異常。

● 第二種:當前方法不知道如何處理,則在定義該方法時宣告丟擲該異常。

執行時異常只有當代碼在執行時才發行的異常,編譯的時候不需要try…catch。Runtime如除數是0和陣列下標越界等,其產生頻繁,處理麻煩,若顯示申明或者捕獲將會對程式的可讀性和執行效率影響很大。所以由系統自動檢測並將它們交給預設的異常處理程式。當然如果你有處理要求也可以顯示捕獲它們。

42.hashCode 與 equals (重要)

HashSet如何檢查重複

兩個物件的 hashCode() 相同,則 equals() 也一定為 true,對嗎?

hashCode和equals方法的關係

面試官可能會問你:“你重寫過 hashcode 和 equals 麼,為什麼重寫equals時必須重寫hashCode方法?”

43.hashCode()介紹

hashCode() 的作用是獲取雜湊碼,也稱為雜湊碼;它實際上是返回一個int整數。這個雜湊碼的作用是確定該物件在雜湊表中的索引位置。hashCode() 定義在JDK的Object.java中,這就意味著Java中的任何類都包含有hashCode()函式。

散列表儲存的是鍵值對(key-value),它的特點是:能根據“鍵”快速的檢索出對應的“值”。這其中就利用到了雜湊碼!(可以快速找到所需要的物件)

44.為什麼要有 hashCode

我們以“HashSet 如何檢查重複”為例子來說明為什麼要有 hashCode:

當你把物件加入 HashSet 時,HashSet 會先計算物件的 hashcode 值來判斷物件加入的位置,同時也會與其他已經加入的物件的 hashcode 值作比較,如果沒有相符的hashcode,HashSet會假設物件沒有重複出現。但是如果發現有相同 hashcode 值的物件,這時會呼叫 equals()方法來檢查 hashcode 相等的物件是否真的相同。如果兩者相同,HashSet 就不會讓其加入操作成功。如果不同的話,就會重新雜湊到其他位置。(摘自我的Java啟蒙書《Head first java》第二版)。這樣我們就大大減少了 equals 的次數,相應就大大提高了執行速度。

hashCode()與equals()的相關規定

如果兩個物件相等,則hashcode一定也是相同的

兩個物件相等,對兩個物件分別呼叫equals方法都返回true

兩個物件有相同的hashcode值,它們也不一定是相等的

因此,equals 方法被覆蓋過,則 hashCode 方法也必須被覆蓋

hashCode() 的預設行為是對堆上的物件產生獨特值。如果沒有重寫 hashCode(),則該 class 的兩個物件無論如何都不會相等(即使這兩個物件指向相同的資料)

物件的相等與指向他們的引用相等,兩者有什麼不同?

物件的相等 比的是記憶體中存放的內容是否相等而 引用相等 比較的是他們指向的記憶體地址是否相等。

45.抽象類和介面(Java7)的區別

  1. 抽象類可以提供成員方法的實現細節,而介面中只能存在public abstract 方法;
  2. 抽象類中的成員變數可以是各種型別的,而介面中的成員變數只能是public static final型別的;
  3. 介面中不能含有靜態程式碼塊以及靜態方法,而抽象類可以有靜態程式碼塊和靜態方法;
  4. 一個類只能繼承一個抽象類,而一個類卻可以實現多個介面。

46.Java 8的介面新增了哪些特性?

增加了default方法和static方法,這2種方法可以有方法體。

47.重寫和過載的區別

重寫是子類對父類的允許訪問的方法的實現過程進行重新編寫, 返回值和形參都不能改變。即外殼不變,核心重寫!
重寫的好處在於子類可以根據需要,定義特定於自己的行為。 也就是說子類能夠根據需要實現父類的方法。
重寫方法不能丟擲新的檢查異常或者比被重寫方法申明更加寬泛的異常。

過載(overloading) 是在一個類裡面,方法名字相同,而引數不同。返回型別可以相同也可以不同。
每個過載的方法(或者建構函式)都必須有一個獨一無二的引數型別列表。

48.ArrayList和LinkedList有什麼區別?

  1. ArrayList和LinkedList的差別主要來自於Array和LinkedList資料結構的不同。ArrayList是基於陣列實現的,LinkedList是基於雙鏈表實現的。另外LinkedList類不僅是List介面的實現類,可以根據索引來隨機訪問集合中的元素,除此之外,LinkedList還實現了Deque介面,Deque介面是Queue介面的子介面,它代表一個雙向佇列,因此LinkedList可以作為雙向佇列 ,棧(可以參見Deque提供的介面方法)和List集合使用,功能強大。

  2. 因為Array是基於索引(index)的資料結構,它使用索引在陣列中搜索和讀取資料是很快的,可以直接返回陣列中index位置的元素,因此在隨機訪問集合元素上有較好的效能。Array獲取資料的時間複雜度是O(1),但是要插入、刪除資料卻是開銷很大的,因為這需要移動陣列中插入位置之後的的所有元素。

  3. 相對於ArrayList,LinkedList的隨機訪問集合元素時效能較差,因為需要在雙向列表中找到要index的位置,再返回;但在插入,刪除操作是更快的。因為LinkedList不像ArrayList一樣,不需要改變陣列的大小,也不需要在陣列裝滿的時候要將所有的資料重新裝入一個新的陣列,這是ArrayList最壞的一種情況,時間複雜度是O(n),而LinkedList中插入或刪除的時間複雜度僅為O(1)。ArrayList在插入資料時還需要更新索引(除了插入陣列的尾部)。

  4. LinkedList需要更多的記憶體,因為ArrayList的每個索引的位置是實際的資料,而LinkedList中的每個節點中儲存的是實際的資料和前後節點的位置。

49.HashMap是怎麼實現的?

詳見:https://blog.csdn.net/woshimaxiao1/article/details/83661464

50.HashMap在Java7和Java8中的實現有什麼不同?

詳見:https://blog.csdn.net/qq_36520235/article/details/82417949

51.HashMap有時候會死迴圈,你知道是什麼原因嗎?

詳見:https://www.cnblogs.com/williamjie/p/11089522.html

52.ConcurrentHashMap是怎麼實現的?

詳見:https://www.infoq.cn/article/ConcurrentHashMap/

53.靜態代理和動態代理的區別

靜態代理中代理類在編譯期就已經確定,而動態代理則是JVM執行時動態生成,靜態代理的效率相對動態代理來說相對高一些,但是靜態代理程式碼冗餘大,一單需要修改介面,代理類和委託類都需要修改。

54.JDK動態代理和CGLIB動態代理的區別

JDK動態代理只能對實現了介面的類生成代理,而不能針對類。
CGLIB是針對類實現代理,主要是對指定的類生成一個子類,覆蓋其中的方法。因為是繼承,所以該類或方法最好不要宣告成final。

線上刷題小程式

參考連結

https://blog.csdn.net/jackfrued/article/details/44921941

https://www.cnblogs.com/Java-JJ/p/12625888.html

http://www.mamicode.com/info-detail-3005972.html