Java面試題-基礎篇三(乾貨)

發表於2019-07-27

這些JAVA基礎題確定都會了嗎?

31、String s = new String("xyz");建立了幾個StringObject?是否可以繼承String類?

        兩個或一個都有可能,”xyz”對應一個物件,這個物件放在字串常量緩衝區,常量”xyz”不管出現多少遍,都是緩衝區中的那一個。NewString每寫一遍,就建立一個新的物件,它使用常量”xyz”物件的內容來建立出一個新String物件。如果以前就用過’xyz’,那麼這裡就不會建立”xyz”了,直接從緩衝區拿,這時建立了一個StringObject;但如果以前沒有用過"xyz",那麼此時就會建立一個物件並放入緩衝區,這種情況它建立兩個物件。至於String類是否繼承,答案是否定的,因為String預設final修飾,是不可繼承的。

 

32、String和StringBuffer的區別

        JAVA平臺提供了兩個類:String和StringBuffer,它們可以儲存和操作字串,即包含多個字元的字元資料。這個String類提供了數值不可改變的字串。而這個StringBuffer類提供的字串可以進行修改。當你知道字元資料要改變的時候你就可以使用StringBuffer。典型地,你可以使用StringBuffers來動態構造字元資料。

      

33、下面這條語句一共建立了多少個物件:String s="a"+"b"+"c"+"d";

對於如下程式碼:

String s1 = "a";

String s2 = s1 + "b";

String s3 = "a" + "b";

System.out.println(s2 == "ab");

System.out.println(s3 == "ab");

第一條語句列印的結果為false,第二條語句列印的結果為true,這說明javac編譯可以對字串常量直接相加的表示式進行優化,不必要等到執行期再去進行加法運算處理,而是在編譯時去掉其中的加號,直接將其編譯成一個這些常量相連的結果。

題目中的第一行程式碼被編譯器在編譯時優化後,相當於直接定義了一個”abcd”的字串,所以,上面的程式碼應該只建立了一個String物件。寫如下兩行程式碼,

          String s ="a" + "b" +"c" + "d";

          System.out.println(s== "abcd");

最終列印的結果應該為true。

 

34、try {}裡有一個return語句,那麼緊跟在這個try後的finally{}裡的code會不會被執行,什麼時候被執行,在return前還是後?

        我們知道finally{}中的語句是一定會執行的,那麼這個可能正常脫口而出就是return之前,return之後可能就出了這個方法了,鬼知道跑哪裡去了,但更準確的應該是在return中間執行,請看下面程式程式碼的執行結果:

public classTest {

    public static void main(String[]args) {

       System.out.println(newTest().test());;

    }

    static int test()

    {

       intx = 1;

       try

       {

          returnx;

       }

       finally

       {

          ++x;

       }

    }

  

}

 

---------執行結果 ---------

1

執行結果是1,為什麼呢?主函式呼叫子函式並得到結果的過程,好比主函式準備一個空罐子,當子函式要返回結果時,先把結果放在罐子裡,然後再將程式邏輯返回到主函式。所謂返回,就是子函式說,我不執行了,你主函式繼續執行吧,這沒什麼結果可言,結果是在說這話之前放進罐子裡的。

 

35、final, finally, finalize的區別。 

        final 用於宣告屬性,方法和類,分別表示屬性不可變,方法不可覆蓋,類不可繼承。內部類要訪問區域性變數,區域性變數必須定義成final型別。

        finally是異常處理語句結構的一部分,表示總是執行。

        finalize是Object類的一個方法,在垃圾收集器執行的時候會呼叫被回收物件的此方法,可以覆蓋此方法提供垃圾收集時的其他資源回收,例如關閉檔案等。但是JVM不保證此方法總被呼叫

 

36、執行時異常與一般異常有何異同?

        異常表示程式執行過程中可能出現的非正常狀態,執行時異常表示虛擬機器的通常操作中可能遇到的異常,是一種常見執行錯誤。java編譯器要求方法必須宣告丟擲可能發生的非執行時異常,但是並不要求必須宣告丟擲未被捕獲的執行時異常。

 

37、error和exception有什麼區別?

        error 表示恢復不是不可能但很困難的情況下的一種嚴重問題。比如說記憶體溢位。不可能指望程式能處理這樣的情況。exception表示一種設計或實現問題。也就是說,它表示如果程式執行正常,從不會發生的情況。

 

38、簡單說說Java中的異常處理機制的簡單原理和應用。

        異常是指java程式執行時(非編譯)所發生的非正常情況或錯誤,與現實生活中的事件很相似,現實生活中的事件可以包含事件發生的時間、地點、人物、情節等資訊,可以用一個物件來表示,Java使用物件導向的方式來處理異常,它把程式中發生的每個異常也都分別封裝到一個物件來表示的,該物件中包含有異常的資訊。

        Java對異常進行了分類,不同型別的異常分別用不同的Java類表示,所有異常的根類為java.lang.Throwable,Throwable下面又派生了兩個子類:

        Error和Exception,Error表示應用程式本身無法克服和恢復的一種嚴重問題,程式只有奔潰了,例如,說記憶體溢位和執行緒死鎖等系統問題。

        Exception表示程式還能夠克服和恢復的問題,其中又分為系統異常和普通異常:

        系統異常是軟體本身缺陷所導致的問題,也就是軟體開發人員考慮不周所導致的問題,軟體使用者無法克服和恢復這種問題,但在這種問題下還可以讓軟體系統繼續執行或者讓軟體掛掉,例如,陣列指令碼越界(ArrayIndexOutOfBoundsException),空指標異常(NullPointerException)、類轉換異常(ClassCastException);

        普通異常是執行環境的變化或異常所導致的問題,是使用者能夠克服的問題,例如,網路斷線,硬碟空間不夠,發生這樣的異常後,程式不應該死掉。

java為系統異常和普通異常提供了不同的解決方案,編譯器強制普通異常必須try..catch處理或用throws宣告繼續拋給上層呼叫方法處理,所以普通異常也稱為checked異常,而系統異常可以處理也可以不處理,所以,編譯器不強制用try..catch處理或用throws宣告,所以系統異常也稱為unchecked異常。

 

39、Java 中堆和棧有什麼區別?
        JVM 中堆和棧屬於不同的記憶體區域,使用目的也不同。棧常用於儲存方法幀和區域性變數,而物件總是在堆上分配。棧通常都比堆小,也不會在多個執行緒之間共享,而堆被整個 JVM 的所有執行緒共享。

        棧:在函式中定義的一些基本型別的變數和物件的引用變數都是在函式的棧記憶體中分配,當在一段程式碼塊定義一個變數時,Java 就在棧中為這個變數分配記憶體空間,當超過變數的作用域後,Java 會自動釋放掉為該變數分配的記憶體空間,該記憶體空間可以立即被另作它用。

        堆:堆記憶體用來存放由 new 建立的物件和陣列,在堆中分配的記憶體,由 Java 虛擬機器的自動垃圾回收器來管理。在堆中產生了一個陣列或者物件之後,還可以在棧中定義一個特殊的變數,讓棧中的這個變數的取值等於陣列或物件在堆記憶體中的首地址,棧中的這個變數就成了陣列或物件的引用變數,以後就可以在程式中使用棧中的引用變數來訪問堆中的陣列或者物件,引用變數就相當於是為陣列或者物件起的一個名稱。

 

40、能將 int 強制轉換為 byte 型別的變數嗎?如果該值大於 byte 型別的範圍,將會出現什麼現象? 
        我們可以做強制轉換,但是 Java 中 int 是 32 位的,而 byte 是 8 位的,所以,如果強制轉化,int 型別的高 24 位將會被丟棄,因為byte 型別的範圍是從 -128 到 128。這裡筆誤:-128到127

相關文章