#分享 (二更)【程式學習成果分享】Java工程師面試觀念考題整理(part 1)

2021年10月31日 22:37
更新的內容在 B18 - - - - - - - - - - - - - - - 謝謝 B13的指教,我沒有想到這一點,是我的疏失。第4題的解答我已做了修改。 - - - - - - - - - - - - - - - 以下的解答均是小弟經過深思熟慮後,依照自己的想法親手一字一句打出來的。雖然本篇列出的問題相當基本,而且我Java也學了蠻久了,但仍不能完全保證我的解答當中沒有疏漏或不專業之處,所以還請各位資深前輩多多指教😊! 1. 說明JDK、JRE和JVM之間的差別。 解答: (1)JVM是一種可以用來執行位元組碼(Byte Code)的虛擬機器。JVM是JRE的一部分。 (2)JRE是Java執行環境,它提供了所有JVM執行程式時所需要的類別(Java API或Java標準類別庫),因此所有的Java程式都要在JRE下才能執行。JRE是JDK的一部分。 (3)JDK是Java的SDK(軟體開發工具包),它包含了Java語言、JRE和一些工具程式,而所謂的工具程式有javac(Java編譯器)、java(執行工具,用來執行位元組碼)、Javadoc(只要在原始碼中按照一定的格式寫註解,就可利用Javadoc產生HTML格式的API文件)等等。 (4)總而言之,若要執行位元組碼,平台必須安裝JVM。不過要啟動JVM,前提是主機上必須有安裝JDK或JRE。簡單來說,開發Java程式才需要JDK,如果只是要執行Java程式,那麼只要安裝JRE即可,不用安裝JDK。 2. 為什麼Java有跨平台的特性? 解答: (1)Java不同於一般的編譯語言和直譯語言。一般的編譯語言若要分別在Windows和Linux上執行,由於每個平台認識的機器碼不一樣,所以必須透過其在Windows上的編譯器和在Linux上的編譯器分別編譯,才能達成。以C語言為例,C語言是編譯語言,其在Windows和Linux上的編譯過程如下方的第一張圖所示。然而,Java的編譯器在編譯時,並不會將原始碼直接編譯為相依於某個平台的機器碼,它首先會將原始碼編譯成位元組碼(副檔名為".class"),然後透過目標平台上安裝的JVM(不同的平台必須安裝專屬該平台的JVM)將位元組碼直譯為相依於該平台的機器碼,從而實現了「一次編寫,到處執行」的特性。Java的編譯過程如下方的第二張圖所示。
imgur
imgur
(2)比較C語言和Java在執行上的差別。C語言雖然必須在不同平台上編譯,但編譯後所產生的執行檔可以馬上在該平台上執行;Java編譯後所產生的位元組碼無法在作業系統上執行,只能在JVM上執行。因此,JVM實際上就相當於Java程式的作業系統,而位元組碼的檔案就是JVM的可執行檔。 3. 如果把"public static void main"改寫成"static public void main",程式還會執行嗎? 解答: public和static都是Java的修飾詞(modifier),Java沒有任何關於修飾詞擺放順序的規則,所以public和static的先後順序並不會影響main方法的意義。 4. 如果main方法沒有被宣告為static,會發生什麼事? 解答: (1)main方法作為Java程式的進入點(entry point),其宣告必須符合"public static void main"(或"static public void main")的形式,且其參數必須是字串陣列。舉例來說,圖A、圖B和圖C當中的宣告都可讓main方法作為程式的進入點。 (圖A)
imgur
(圖B)
imgur
(圖C)
imgur
(2)如果main方法沒有被宣告為static,那麼它只是一個類別內的實例方法(instance method)或非靜態方法(non-static method),並不能作為程式的進入點。 (3)如果程式當中沒有可作為進入點的main方法(如圖D、圖E、圖F、圖G、圖H和圖I所示),程式依然可以完成編譯,不過執行時會發生錯誤。 (圖D)
imgur
(圖E)
imgur
(圖F)
imgur
(圖G)
imgur
(圖H)
imgur
(圖I)
imgur
5. 是否可以將int強制轉型為byte? 解答: (1)如果要將int的變數指定給byte的變數,必須將前者強制轉型為byte(如下方的第一張圖所示),否則會發生編譯錯誤(如下方的第二張圖所示,注意第二行的i底下有紅線,代表編譯錯誤)。
imgur
imgur
(2)將int強制轉型為byte雖然可行,但很有可能會發生資料遺失的情況,如下圖所示,雖然第二行有將i強制轉型為byte,不會出現編譯錯誤,但因為i的值已超出byte的範圍,所以超過範圍的部分會被丟棄。
imgur
6. 「float f = 1.2;」是否為正確的敘述? 解答: 在Java當中,浮點數的字面常數預設的資料型態是double,double的值不能指定給float的變數,故「float f = 1.2;」必須改寫成「float f = (float) 1.2;」、「float f = 1.2F;」或「float f = 1.2f;」。 7. 假設a和b都是已經被宣告和初始化的變數,請問「a += b;」和「a = a + b;」有什麼差別? 解答: (1)如果「a + b」的運算結果的資料型態大於a的資料型態,那麼「a = a + b;」會發生編譯錯誤(如圖1、圖3、圖5、圖7、圖9、圖11、圖13、圖15和圖17所示,注意這9張圖當中的最後一行都有紅線,代表編譯錯誤),而「a += b;」可以正確執行(如圖2、圖4、圖6、圖8、圖10、圖12、圖14、圖16和圖18所示),因為「a += b;」相當於「a = (T) (a + b);」(假設T是a的資料型態)。 (圖1)
imgur
(圖2)
imgur
(圖3)
imgur
(圖4)
imgur
(圖5)
imgur
(圖6)
imgur
(圖7)
imgur
(圖8)
imgur
(圖9)
imgur
(圖10)
imgur
(圖11)
imgur
(圖12)
imgur
(圖13)
imgur
(圖14)
imgur
(圖15)
imgur
(圖16)
imgur
(圖17)
imgur
(圖18)
imgur
(2)如果「a + b」的運算結果的資料型態跟a的資料型態一樣,則「a += b;」和「a = a + b;」是一樣的意思(如圖19、圖20、圖21、圖22、圖23、圖24和圖25所示)。 (圖19)
imgur
(圖20)
imgur
(圖21)
imgur
(圖22)
imgur
(圖23)
imgur
(圖24)
imgur
(圖25)
imgur
8. 下圖中的程式碼是否會發生編譯錯誤?如果會的話,應該如何修改?
imgur
解答: 在Java當中,整數的字面常數預設的資料型態是int,所以「s + 1」的運算結果的資料型態是int,「s = s + 1;」會發生編譯錯誤,應該將它改成「s += 1;」,因為「s += 1;」相當於「s = (short) (s + 1);」。 9. 下圖中的程式會輸出什麼內容?
imgur
解答: (1)在「System.out.println(10 + 10 + "Hello!");」當中,第一個+的作用是加法,第二個+的作用是字串連接,故這個敘述會印出"20Hello!"(如下圖所示)。
imgur
(2)在「System.out.println("Hello!" + 10 + 10);」當中,兩個+的作用都是字串連接,故這個敘述會印出"Hello!1010"(如下圖所示)。
imgur
10. 下圖中的程式輸出的整數是什麼?
imgur
解答: 在main方法當中,傳入m1方法的引數是11;在m1方法當中,傳入m2方法的引數是121;在m2方法當中,傳入m3方法的引數是11;在m3方法當中,傳入m4方法的引數是0。所以m4方法的回傳值是11,main方法會印出11。
愛心跪
121
留言 18
文章資訊