#分享 (二更)【程式學習成果分享】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的編譯過程如下方的第二張圖所示。
(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)
(圖B)
(圖C)
(2)如果main方法沒有被宣告為static,那麼它只是一個類別內的實例方法(instance method)或非靜態方法(non-static method),並不能作為程式的進入點。 (3)如果程式當中沒有可作為進入點的main方法(如圖D、圖E、圖F、圖G、圖H和圖I所示),程式依然可以完成編譯,不過執行時會發生錯誤。 (圖D)
(圖E)
(圖F)
(圖G)
(圖H)
(圖I)
5. 是否可以將int強制轉型為byte? 解答: (1)如果要將int的變數指定給byte的變數,必須將前者強制轉型為byte(如下方的第一張圖所示),否則會發生編譯錯誤(如下方的第二張圖所示,注意第二行的i底下有紅線,代表編譯錯誤)。
(2)將int強制轉型為byte雖然可行,但很有可能會發生資料遺失的情況,如下圖所示,雖然第二行有將i強制轉型為byte,不會出現編譯錯誤,但因為i的值已超出byte的範圍,所以超過範圍的部分會被丟棄。
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)
(圖2)
(圖3)
(圖4)
(圖5)
(圖6)
(圖7)
(圖8)
(圖9)
(圖10)
(圖11)
(圖12)
(圖13)
(圖14)
(圖15)
(圖16)
(圖17)
(圖18)
(2)如果「a + b」的運算結果的資料型態跟a的資料型態一樣,則「a += b;」和「a = a + b;」是一樣的意思(如圖19、圖20、圖21、圖22、圖23、圖24和圖25所示)。 (圖19)
(圖20)
(圖21)
(圖22)
(圖23)
(圖24)
(圖25)
8. 下圖中的程式碼是否會發生編譯錯誤?如果會的話,應該如何修改?
解答: 在Java當中,整數的字面常數預設的資料型態是int,所以「s + 1」的運算結果的資料型態是int,「s = s + 1;」會發生編譯錯誤,應該將它改成「s += 1;」,因為「s += 1;」相當於「s = (short) (s + 1);」。 9. 下圖中的程式會輸出什麼內容?
解答: (1)在「System.out.println(10 + 10 + "Hello!");」當中,第一個+的作用是加法,第二個+的作用是字串連接,故這個敘述會印出"20Hello!"(如下圖所示)。
(2)在「System.out.println("Hello!" + 10 + 10);」當中,兩個+的作用都是字串連接,故這個敘述會印出"Hello!1010"(如下圖所示)。
10. 下圖中的程式輸出的整數是什麼?
解答: 在main方法當中,傳入m1方法的引數是11;在m1方法當中,傳入m2方法的引數是121;在m2方法當中,傳入m3方法的引數是11;在m3方法當中,傳入m4方法的引數是0。所以m4方法的回傳值是11,main方法會印出11。
114
留言 18
文章資訊
18 篇文章285 人追蹤
Logo
每天有 6 則貼文
共 18 則留言
國立屏東大學 資訊管理學系
好讚👍
中原大學
感謝原Po分享👍
國立中山大學
推推
國立臺灣海洋大學
明新科技大學
用心👍
匿名
此帳號疑似異常
官方正在進行身份確認
這題目國中生都會
國立臺中科技大學
B6 我幫你問了我弟弟 完全不會呦
逢甲大學
上次被人資做業績面了一個對岸八大的 第一題我就結束面試了 高級技術官 : 談談你對 java lock 的理解 我 : 我不理解 END
國立成功大學
認真!給推!
明新科技大學
B6 那你有沒有難一點的題目,可以分享詳解嗎?
面試比較少考基礎語法的問題,準備策略可能得換一換。
第 4 題的答案模仿第 3 題的型式會好一些。 截圖如下:
1. 當一個 main method 不是 static 的情況,那他就只是某個 class 內的 non-static method。必需在該 class 被實體化後才能使用。 (以上是發生什麼事的「事實」) 2. 若期望的結果是作為 execution 的進入點,依 JLS 的定義得符合 public static void main 的型式,且得宣告一個字串陣列作為參數。 像這樣的寫法,都符合是一個字串陣列的情況。 main(String[] abc) main(String def[]) main(String ... ghi)
國立高雄大學 資訊管理學系
用心推
B13 謝謝你的指教,我沒有想到這一點,是我的疏失。第4題的解答我已做了修改。
淡江大學
超讚👍!感謝分享
通報 📢 好像有人對這篇文章有新想法唷,快來去看看!
我已將本篇的內容都放在Notion了。