java基礎面試題

calvincalvin發表於2024-08-19

String 真正不可變有下面幾點原因:

  1. 儲存字串的陣列被 final 修飾且為私有的,並且String 類沒有提供/暴露修改這個字串的方法。
  2. String 類被 final 修飾導致其不能被繼承,進而避免了子類破壞 String 不可變。

字串拼接用“+” 還是 StringBuilder?

bad case

String[] arr = {"he", "llo", "world"};
String s = "";
for (int i = 0; i < arr.length; i++) {
    s += arr[i];
}
System.out.println(s);

image-20240818232752586

String#intern 方法有什麼作用?

String.intern() 是一個 native(本地)方法,其作用是將指定的字串物件的引用儲存在字串常量池中,可以簡單分為兩種情況:

  • 如果字串常量池中儲存了對應的字串物件的引用,就直接返回該引用。
  • 如果字串常量池中沒有儲存了對應的字串物件的引用,那就在常量池中建立一個指向該字串物件的引用並返回。

String 型別的變數和常量做“+”運算時發生了什麼?

String str1 = "str";
String str2 = "ing";
String str3 = "str" + "ing";
String str4 = str1 + str2;
String str5 = "string";
System.out.println(str3 == str4);//false
System.out.println(str3 == str5);//true
System.out.println(str4 == str5);//false

對於編譯期可以確定值的字串,也就是常量字串 ,jvm 會將其存入字串常量池。並且,字串常量拼接得到的字串常量在編譯階段就已經被存放字串常量池,這個得益於編譯器的最佳化。

引用的值在程式編譯期是無法確定的,編譯器無法對其進行最佳化。

不過,字串使用 final 關鍵字宣告之後,可以讓編譯器當做常量來處理。

image-20240818233459132

Java 異常類層次結構圖

注意:不要在 finally 語句塊中使用 return!

當 try 語句和 finally 語句中都有 return 語句時,try 語句塊中的 return 語句會被忽略。這是因為 try 語句中的 return 返回值會先被暫存在一個本地變數中,當執行到 finally 語句中的 return 之後,這個本地變數的值就變為了 finally 語句中的 return 返回值。

背一下動態代理?

public class DebugInvocationHandler implements InvocationHandler {
    /**
     * 代理類中的真實物件
     */
    private final Object target;

    public DebugInvocationHandler(Object target) {
        this.target = target;
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws InvocationTargetException, IllegalAccessException {
        System.out.println("before method " + method.getName());
        Object result = method.invoke(target, args);
        System.out.println("after method " + method.getName());
        return result;
    }
}


SPI 和 API 有什麼區別?

  • 當介面存在於呼叫方這邊時,這就是 **SPI ** 。由介面呼叫方確定介面規則,然後由不同的廠商根據這個規則對這個介面進行實現,從而提供服務。

相關文章