10道虐心的Java面試題,被面試官虐哭了,同事一題都沒答對

2020-12-27 網易

  有一天,小王告訴我,他去一家公司面試 Java 崗,結果被面試官虐哭了。整整 10 道 Java 面試題,小王一道也沒答正確。

  他沮喪地給我說,「哥,說點我的情況,你願意聽嗎?我和一個女孩相處,女孩大我兩歲,我非科班。本來打算國慶換一家薪水高點的,好確認關係。我經驗不多,技術一般般,之前在一家外包公司,有一個甲方內推,我就魯莽地把外包的工作辭了,結果沒想到面試被虐了,我擔心女朋友會不會因為我沒有工作和我分手。」

  聽他這麼一說,確實挺虐心的。後來我就安慰他,要他端正心態,先把這些面試題整明白,然後繼續找工作,不要想太多。

  借這個機會,我就把小王遇到的這 10 道面試題分享出來,希望能對其他小夥伴一些幫助。

  第一題,下面這串代碼列印的結果是什麼

  public class Test { public static void main(String[] args) { System.out.println(Math.min(Double.MIN_VALUE, 0.0d)); }}

  小王之所以沒答對這道題,是因為他覺得 Double.MIN_VALUE 和 Integer.MIN_VALUE 一樣,是個負數,應該小於 0.0d。

  但事實上,Double. MIN_VALUE 和 Double. MAX_VALUE 一樣,都是正數,Double. MIN_VALUE 的值是 2^(-1074),直接列印 Double. MIN_VALUE 的話,輸出結果為 4.9E-324。

  因此這道題的正確答案是輸出 0.0。

  第二題,在 try 塊或者 catch 語句中執行 return 語句或者 System.exit() 會發生什麼,finally 語句還會執行嗎?

  小王之所以沒答對這道題,是因為在他的刻板印象中,finally 語句是無論如何都會執行的。

  但事實上,在 try 塊或者 catch 語句中執行 return 語句時,finally 語句會執行;在 try 塊或者 catch 語句中執行 System.exit() 時,finally 語句不會執行。

  public class Test1 { public static void main(String[] args) { returnTryExec(); returnCatchExec(); exitTryExec(); exitCatchExec(); } public static int returnTryExec() { try { return 0; } catch (Exception e) { } finally { System.out.println("finally returnTryExec"); return -1; } } public static int returnCatchExec() { try { } catch (Exception e) { return 0; } finally { System.out.println("finally returnCatchExec"); return -1; } } public static void exitTryExec() { try { System.exit(0); } catch (Exception e) { } finally { System.out.println("finally exitTryExec"); } } public static void exitCatchExec() { try { } catch (Exception e) { System.exit(0); } finally { System.out.println("finally exitCatchExec"); } }}

  程序執行結果如下所示:

  finally returnTryExecfinally returnCatchExec

  第三題,私有方法或者靜態方法能被重寫(override)嗎?

  小王之所以沒答對這道題,是因為他不確定私有方法或者靜態方法與重寫之間的關係。

  重寫的兩個方法名相同,方法參數的個數也相同;不過一個方法在父類中,另外一個在子類中。

  class LaoWang{ public void write() { System.out.println("老王寫了一本《基督山伯爵》"); }}class XiaoWang extends LaoWang { @Override public void write() { System.out.println("小王寫了一本《茶花女》"); }}public class OverridingTest { public static void main(String[] args) { LaoWang wang = new XiaoWang(); wang.write(); }}

  父類 LaoWang 有一個 write() 方法(無參),方法體是寫一本《基督山伯爵》;子類 XiaoWang 重寫了父類的 write() 方法(無參),但方法體是寫一本《茶花女》。

  在 main 方法中,我們聲明了一個類型為 LaoWang 的變量 wang。在編譯期間,編譯器會檢查 LaoWang 類是否包含了 write() 方法,發現 LaoWang 類有,於是編譯通過。在運行期間,new 了一個 XiaoWang 對象,並將其賦值給 wang,此時 Java 虛擬機知道 wang 引用的是 XiaoWang 對象,所以調用的是子類 XiaoWang 中的 write() 方法而不是父類 LaoWang 中的 write() 方法,因此輸出結果為「小王寫了一本《茶花女》」。

  而私有方法對子類是不可見的,它僅在當前聲明的類中可見,private 關鍵字滿足了封裝的最高級別要求。另外,Java 中的私有方法是通過編譯器的靜態綁定的方式綁定的,不依賴於特定引用變量所持有的對象類型。

  方法重寫適用於動態綁定,因此私有方法無法被重寫。

  class LaoWang{ public LaoWang() { write(); read(); } public void write() { System.out.println("老王寫了一本《基督山伯爵》"); } private void read() { System.out.println("老王在讀《哈姆雷特》"); }}class XiaoWang extends LaoWang { @Override public void write() { System.out.println("小王寫了一本《茶花女》"); } private void read() { System.out.println("小王在讀《威尼斯商人》"); }}public class PrivateOrrideTest { public static void main(String[] args) { LaoWang wang = new XiaoWang(); }}

  程序輸出結果如下所示:

  小王寫了一本《茶花女》老王在讀《哈姆雷特》

  在父類的構造方法中,分別調用了 write() 和 read() 方法,write() 方法是 public 的,可以被重寫,因此執行了子類的 write() 方法,read() 方法是私有的,無法被重寫,因此執行的仍然是父類的 read() 方法。

  和私有方法類似,靜態方法在編譯期也是通過靜態綁定的方式綁定的,不依賴於特定引用變量所持有的對象類型。方法重寫適用於動態綁定,因此靜態方法無法被重寫。

  public class StaticOrrideTest { public static void main(String[] args) { Laozi zi = new Xiaozi(); zi.write(); }}class Laozi{ public static void write() { System.out.println("老子寫了一本《基督山伯爵》"); }}class Xiaozi extends Laozi { public static void write() { System.out.println("小子寫了一本《茶花女》"); }}

  程序輸出結果如下所示:

  老子寫了一本《基督山伯爵》

  引用變量 zi 的類型為 Laozi,所以 zi.write() 執行的是父類中的 write() 方法。

  靜態方法也叫類方法,直接通過類名就可以調用,通過對象調用的時候,IDE 會發出警告。


  第四題,1.0/0.0 得到的結果是什麼?會拋出異常嗎,還是會出現編譯錯誤?

  小王之所以沒答對這道題,是因為他沒有深入研究過 double 類型和 int 類型的除法運算。

  數字在 Java 中可以分為兩種,一種是整形,一種是浮點型。不太清楚的小夥伴先去研究一下數據類型。

  當浮點數除以 0 的時候,結果為 Infinity 或者 NaN。

  System.out.println(1.0 / 0.0); // InfinitySystem.out.println(0.0 / 0.0); // NaN

  Infinity 的中文意思是無窮大,NaN 的中文意思是這不是一個數字(Not a Number)。

  當整數除以 0 的時候(10 / 0),會拋出異常:

  Exception in thread "main" java.lang.ArithmeticException: / by zero at com.itwanger.eleven.ArithmeticOperator.main(ArithmeticOperator.java:32)

  通常,我們在進行整數的除法運算時,需要先判斷除數是否為 0,以免程序拋出異常。

  第五題,Java 支持多重繼承嗎?

  小王之所以沒答對這道題,是因為他知道,通過接口可以達到多重繼承的目的。

  來定義兩個接口,Fly 會飛,Run 會跑。

  public interface Fly { void fly();}public interface Run { void run();}

  然後讓一個類同時實現這兩個接口。

  public class Pig implements Fly,Run{ @Override public void fly() { System.out.println("會飛的豬"); } @Override public void run() { System.out.println("會跑的豬"); }}

  但說到多重繼承,討論的關鍵字是 extends,而非 implements。

  Java 只支持單一繼承,是因為涉及到菱形問題。如果有兩個類共同繼承一個有特定方法的父類,那麼該方法可能會被兩個子類重寫。然後,如果你決定同時繼承這兩個子類,那麼在你調用該重寫方法時,編譯器不能識別你要調用哪個子類的方法。


  類 C 同時繼承了類 A 各類 B,類 C 的對象在調用類 A 各類 B 中重寫的方法時,就不知道該調用類 A 的方法,還是類 B 的方法。

  第六題,當在 HashMap 中放入一個已經存在的 key 時,會發生什麼?

  小王之所以沒答對這道題,是因為他沒有深入研究過 HashMap 的工作原理。

  Hash,一般譯作「散列」,也有直接音譯為「哈希」的,這玩意什麼意思呢?就是把任意長度的數據通過一種算法映射到固定長度的域上(散列值)。

  再直觀一點,就是對一串數據 wang 進行雜糅,輸出另外一段固定長度的數據 er——作為數據 wang 的特徵。我們通常用一串指紋來映射某一個人,別小瞧手指頭那麼大點的指紋,在你所處的範圍內很難找出第二個和你相同的(人的散列算法也好厲害,有沒有)。

  對於任意兩個不同的數據塊,其散列值相同的可能性極小,也就是說,對於一個給定的數據塊,找到和它散列值相同的數據塊極為困難。再者,對於一個數據塊,哪怕只改動它的一個比特位,其散列值的改動也會非常的大——這正是 Hash 存在的價值!

  大家應該知道,HashMap 的底層數據結構是一個數組,通過 hash() 方法來確定下標。

  static final int hash(Object key) { int h; return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);}

  當我們放入一個鍵值對的時候,會先調用 hash() 方法對 key 進行哈希算法,如果 key 是相同的,那麼哈希後的結果也是相同的,意味著數組中的下標是相同的,新放入的值就會覆蓋原來的值。

  第七題,下面這段代碼將會列印出什麼?

  public class Test { public static void main(String[] args) { char[] chars = new char[]{'\u0097'}; String str = new String(chars); byte[] bytes = str.getBytes(); System.out.println(Arrays.toString(bytes)); }}

  小王之所以沒答對這道題,是因為他沒有深入研究過字符編碼方面的一些知識。

  在這段程序中,我們通過一個字符數組創建了一個字符串對象,然後調用 String 類的 getByte() 方法得到字節數組並將其列印到控制臺。

  這道面試題考察的核心並不是最終的列印結果(結果是不確定的),而是字符編碼。通常情況下,我們在調用 getBytes() 方法時,要指定編碼,比如說 str.getBytes(StandardCharsets.UTF_8)。

  當我們沒有指定編碼的時候,JDK 會調用平臺默認的字符編碼,而不同的作業系統,編碼不盡相同的,bytes 的結果也就會不同。

  當使用 UTF_8 時,結果為 -62, -105,當使用 GB2312 時,結果為 63。

  第八題,當方法在父類中拋出 NullPointerException 時,是否可以使用拋出 RuntimeException 的方法來重寫它?

  小王之所以沒答對這道題,是因為他被重寫(overriding)和重載(overloading)的概念搞混了。

  方法重寫和方法重載時,方法名可以完全相同,但根本的不同在於方法重寫時發生在運行時,方法重載時發生在編譯時。

  另外,方法重寫和方法重載時的規則也不盡相同。在 Java 中,不能重寫 private、static 和 final 方法,但可以重載它們。

  我們來重點看一下方法重寫時的規則:

  1)方法籤名必須相同,包括返回類型、參數的數量、參數的類型和參數的順序。

  2)重寫後的方法不能拋出比父類中更高級別的異常。舉例來說,如果父類中的方法拋出的是 IOException,那么子類中重寫的方法不能拋出 Exception,可以是 IOException 的子類或者不拋出任何異常。這條規則只適用於可檢查的異常。

  可檢查(checked)異常必須在原始碼中顯式地進行捕獲處理,不檢查(unchecked)異常就是所謂的運行時異常,比如說 NullPointerException、ArrayIndexOutOfBoundsException 之類的,不會在編譯器強制要求。

  3)重寫後的方法訪問權限不能比父類中的方法低,比如說父類中的方法是 public,重寫後的方法就不能是 protected。

  public class ExceptionDemo { public static void main(String[] args) { Super s = new Child(); s.write(); }}class Super{ public void write() throws NullPointerException { }}class Child extends Super { @Override public void write() throws RuntimeException { }}

  RuntimeException 和 NullPointerException 屬於不檢查異常,所以本題的答案是可以的。如果是可檢查異常的話,IDE 就會發出警告。


  第九題,下面這段代碼使用了 compareTo() 方法,有問題嗎?

  class Employee implements Comparable { private int id; @Override public int compareTo(Object o) { Employee emp = (Employee) o; return this.id - emp.id; }}

  小王之所以沒答對這道題,是因為他想當然地認為 id 的都是正整數。

  當我們需要按照一定的規則進行排序的時候,通常要實現 Comparable 接口,並實現 compareTo 方法,規則如下:

  1)如果當前對象小於另外一個對象,則 compareTo 方法必須返回負數;如果當前對象大於另外一個對象,則必須返回正數;如果兩個對象相等,則返回零。

  2)通常來說,compareTo 方法必須和 equals 方法一致,如果兩個對象通過 equals 方法判斷的結果為 true,那麼 compareTo 必須返回零。

  不過,JDK 中有一個反例,就是 BigDecimal。

  BigDecimal bd1 = new BigDecimal("2.0");BigDecimal bd2 = new BigDecimal("2.00");System.out.println("equals: " + bd1.equals(bd2));System.out.println("compareTo: " + bd1.compareTo(bd2));

  輸出結果如下所示:

  equals: falsecompareTo: 0

  這是因為 JDK 認為 2.0 和 2.00 的精度不一樣,所以不能 equals,但值確實是相等的。

  3)不能使用減法來比較整數值,因為減法的結果可能溢出。應該使用 Integer.compareTo() 來進行比較。如果你想通過減法操作來提高性能,必須得確保兩個操作數是正整數,或者確保兩者相差的值小於 Integer.MAX_VALUE。

  public class CompareDemo { public static void main(String[] args) { List list = new ArrayList<>(); list.add(new Employee(1)); list.add(new Employee(Integer.MIN_VALUE)); list.add(new Employee(Integer.MAX_VALUE)); Collections.sort(list); System.out.println(list); }}class Employee implements Comparable { private int id; public Employee(int id) { this.id = id; } @Override public int compareTo(Object o) { Employee emp = (Employee) o; return this.id - emp.id; } @Override public String toString() { return "Employee{" + "id=" + id + '}'; }}

  程序的輸出結果如下所示:

  [Employee{id=1}, Employee{id=2147483647}, Employee{id=-2147483648}]

  排序就亂了。因為 Integer.MIN_VALUE - 1 變成了正數 2147483647。

  第十題,StringBuffer 和 StringBuilder 之間有什麼區別?

  小王之所以沒答對這道題,是因為他覺得這道題太簡單了,結果說反了,大意了啊。

  StringBuilder 是 JDK 1.5 之後引入的,它和 StringBuffer 最大的區別就在於它的一系列方法都是非同步的。


  好了,以上就是小王這次面試遇到的 10 道虐心的面試題,本來最後一道是送分題,結果大意說反了,讓小王更加懊惱。年後是跳槽的高峰期,有打算的小夥伴要提前準備了,希望大家都能夠順利面上心儀的崗位。

相關焦點

  • 被這10道Java面試題虐哭了
    Java 崗,結果被面試官虐哭了。整整 10 道 Java 面試題,小王一道也沒答正確。他沮喪地給我說,「哥,說點我的情況,你願意聽嗎?我和一個女孩相處,女孩大我兩歲,我非科班。本來打算國慶換一家薪水高點的,好確認關係。
  • 2019 最新 200 道 Java 面試題
    ,我做了大量的「功課」,首先我研究了幾乎所有大廠的面試題,還和負責招聘工作的幾個朋友,詳細的探討了 Java 面試所要涉及的知識點,於是就有了今天大家看到的這 200 多道面試題。為什麼要公開這些面試題?原因一:身邊從事 Java 開發的人員越來越多,我的表弟表妹們,朋友的表弟表妹們,朋友的朋友的表弟表妹們,每次問我要相同的面試複習材料,已經讓我疲於應付,索性整理出來,直接發連結給他們。
  • Java 最常見的 200+ 面試題:面試必備
    聊回面試題這件事,這份面試清單原本是我們公司內部使用的,可到後來有很多朋友在微信上聯繫到我,讓我幫他們找一些面試方面的資料,而且這些關係也不太好拒絕,一呢,是因為這些找我,要面試題的人,不是我的好朋友的弟弟妹妹,就是我的弟弟妹妹們;二呢,我也不能馬馬虎虎的對付,受人之事忠人之命,我也不能辜負這份信任。
  • 10道棘手的Java面試題,看看你能答對幾個?
    作者:DD編輯部來源:程序猿DD昨晚看了幾個老外分享的面試題
  • 500道Java 必備面試題答案(過後即刪)
    其實,很多面試者在搜集面試資料的時候都踩過一些「坑」,你是不是也遇到過:免費搜索的面試題,內容不全面,這就算了,有時候答案都不準確;很多培訓機構提供的面試寶典內容雖然不少,但深度不夠,且面試題過於老舊脫離了企業實際需要;還有很多付費的面試題存在濫竽充數,提供了很多沒有價值的面試題,錢花了,乾貨沒學到;
  • 學了1年java的程式設計師面試,掛在了這道基礎算法題!
    這都是java的算法題,應該來講都是些比較簡單的算法題,但是我敢說很多基礎的學習的,或者想去面試的人都會不能完整的寫出來,現在
  • Java 線程面試題 Top 50
    掌握了這些技巧,你就可以輕鬆應對多線程和並發麵試了。許多Java程式設計師在面試前才會去看面試題,這很正常。因為收集面試題和練習很花時間,所以我從許多面試者那裡收集了Java多線程和並發相關的50個熱門問題。我只收集了比較新的面試題且沒有提供全部答案。想必聰明的你對這些問題早就心中有數了, 如果遇到不懂的問題,你可以用Google找到答案。若你實在找不到答案,可以在文章的評論中向我求助。
  • 50道Java集合經典面試題(收藏版)
    前言來了來了,50道Java集合面試題也來啦~ 已經上傳github:https://github.com/whx123/JavaHome1.可以跟面試官聊聊悲觀鎖和CAS樂觀鎖的區別,優缺點哈~25. 阻塞隊列的實現,ArrayBlockingQueue的底層實現?
  • 「秒殺」面試官,你只差這10道Python面試題
    哎呀!不多說了!胡陽老師就要來了,趕緊先看看這 10 道面試題。今天狗哥請我來幫一位讀者解決面試的問題,其實我們都是從這個階段過來的。所以能幫上大家也是比較開心的。那今天我從面試的角度給大家歸納下 Django 工程師面試時面試官都會問些啥。其實解析這些問題之前,大家要明白一個基本原則:面試的目的是找到合適的候選人,提問的目的是為了考察當前候選人對當前崗位的匹配度。
  • 【每日一題】(33題)面試官:你對圖論了解多少?(三)
    •第 12 題[每日一題]面試官問:JS引擎的執行過程(二)•第 11 題[每日一題]面試官問:JS引擎的執行過程(一)•第 10 題[每日一題]面試官問:詳細說一下JS數據類型•第 8 題[每日一題]面試官問:談談你對ES6的proxy的理解?•第 7 題[每日一題]面試官問:for in和for of 的區別和原理?
  • 面試官:圖中有多少個三角形?3個面試者,唯獨95後美女答對!
    面試官:圖中有多少個三角形?唯獨95後美女答對!今天小編給大家分享一個有趣的面試題。某大型公司招聘秘書時,面試官出了這樣一道題,給了大家一張圖片,並讓大家數出裡面一共有多少個三角形。這道題其實一點也不難,面試官只為了考察一個點,就是面試者的是否耐心,想要正確答對這道題,就是需要一點點的數,我們一起來看一下三位面試的小姑娘是怎麼回答的吧!第一位小姑娘,看到題目後,有點頭大三角形實在太多了,該怎麼數呢?小姑娘用手指著三角形,一個,兩個,三個……數了很長時間,每次數一會就亂了,又要重新開始,不一會小姑娘就煩了,什麼破題,煩死了!
  • 10個經典的 Java main 方法面試題
    以下是筆者認為比較經典的關於Java main方法的面試題,與其說是Java面試題,其實也是Java的一些最基礎知識問題,分享給大家,如有錯誤,請指出。1.不用main方法如何定義一個類?package com.instanceofjava;public class MainMethod{public static void main(String args[]){}}3.我們能不能改變main()方法的返回類型?不能,main()方法的返回類型只能是空。任何其它類型都是不能接受的。
  • 聽說這10道Java面試題90%的人都不會!!!
    譯者:Yujiaao  來源:http://1t.click/Jab這是我收集的10個最棘手的Java面試問題列表。這些問題主要來自 Java 核心部分 ,不涉及 Java EE 相關問題。你可能知道這些棘手的 Java 問題的答案,或者覺得這些不足以挑戰你的 Java 知識,但這些問題都是容易在各種 Java 面試中被問到的,而且包括我的朋友和同事在內的許多程式設計師都覺得很難回答。
  • 每周 10 道 Java 面試題 : 面向對象, 類加載器, JDBC, Spring 基礎概念
    (點擊上方公眾號,可快速關注)來源:lmportNew - 唐尤華每周10道 Java 面試題由 ImportNew
  • 這道面試題,出錯率90%
    大多數公司針對初級、中級都會有筆試的這個環節,甚至很多高級面試也存在筆試環節。對於筆試大家千萬不要掉以輕心,筆試題做不好,很有可能面試就黃了或者隨便找個面試官應付一下就可以回去等通知了。今天我們分享的這個面試題,出現的頻率是相當高。
  • Java典型面試題 ——談談你對Java平臺的理解?
    很多面試者會在這種問題上吃虧,稍微緊張了一下,不知道從何說起,就給出個很簡略的回答。對於這類籠統的問題,你需要儘量表現出自己的思維深入並系統化,Java 知識理解得也比較全面,一定要避免讓面試官覺得你是個「知其然不知其所以然」的人。
  • 10年+技術總監面FB,面試官竟然讓我寫算法題?
    原因很簡單,主講老師是算法競賽出身,刷過的題,超過2000道,所總結的「套路」和「模板」不是刷幾百道的人可以得出的。比如這個快排(Quick Sort)模板,直接能讓面試官眼前一亮👇面對激烈的求職,想要在面試中甩開對手的最好辦法,就是提高代碼質量,拿一道FB經常考的「最長回文串」舉例:描述:給出一個字符串(假設長度最長為1000),求出它的最長回文子串,你可以假定只有一個滿足條件的最長回文串。
  • 外資企業招聘會計,工資5千起,面試官出了5道題,看你都能答對嗎
    外資企業招聘會計,工資5千起,面試官出了5道題,看你都能答對嗎會計阿海最近參加了一場外資企業招聘會計的活動,外資企業要求懂出口退稅,會計職稱初級以上,有外資企業工作經驗,在外資企業最少工作三年以上,外資企業給出的薪水是5千起。
  • [java大數據面試] 百度面試經過+三面算法題:給定一個數組,求和為定值的所有組合.
    給定一個數組,求和為定值的所有組合, 這道算法題在leetcode應該算是中等偏下難度, 對三到五年工作經驗主要做業務開發的同學來說, 一般較難的也就是這種程度了
  • 10道經典面試題!聊一聊「面試」的那些事
    編輯導語:每次面試都是一種成長,與不同的人溝通也是一種學習;特別是面試,針對不同的公司和崗位,對應的問題都是有針對性,更加考驗我們的思考能力和應變能力;本文作者分享了十道經典的面試題並進行解析,我們一起來看一下。