20道Java精選面試必問題(附詳細解答),還有什麼拿不到的offer

1.什麼是Java虛擬機?爲何Java被稱做是「平臺無關的編程語言」?

Java虛擬機是一個能夠執行Java字節碼的虛擬機進程。Java源文件被編譯成能被Java虛擬機執行的字節碼文件。javascript

Java被設計成容許應用程序能夠運行在任意的平臺,而不須要程序員爲每個平臺單獨重寫或者是從新編譯。Java虛擬機讓這個變爲可能,由於它知道底層硬件平臺的指令長度和其餘特性。java

2.JDK和JRE的區別是什麼?

Java運行時環境(JRE)是將要執行Java程序的Java虛擬機。它同時也包含了執行applet須要的瀏覽器插件。程序員

Java開發工具包(JDK)是完整的Java軟件開發包,包含了JRE,編譯器和其餘的工具(好比:JavaDoc,Java調試器),可讓開發者開發、編譯、執行Java應用程序。算法

3.」static」關鍵字是什麼意思?Java中是否能夠覆蓋(override)一個private或者是static的方法?

「static」關鍵字代表一個成員變量或者是成員方法能夠在沒有所屬的類的實例變量的狀況下被訪問。編程

Java中static方法不能被覆蓋,由於方法覆蓋是基於運行時動態綁定的,而static方法是編譯時靜態綁定的。static方法跟類的任何實例都不相關,因此概念上不適用。瀏覽器

4.是否能夠在static環境中訪問非static變量?

static變量在Java中是屬於類的,它在全部的實例中的值是同樣的。當類被Java虛擬機載入的時候,會對static變量進行初始化。若是你的代碼嘗試不用實例來訪問非static的變量,編譯器會報錯,由於這些變量尚未被建立出來,尚未跟任何實例關聯上。安全

5.Java支持的數據類型有哪些?什麼是自動拆裝箱?

Java語言支持的8中基本數據類型是:併發

  • byte
  • short
  • int
  • long
  • float
  • double
  • boolean
  • char

自動裝箱是Java編譯器在基本數據類型和對應的對象包裝類型之間作的一個轉化。好比:把int轉化成Integer,double轉化成double,等等。反之就是自動拆箱。app

6.Java中的方法覆蓋(Overriding)和方法重載(Overloading)是什麼意思?

Java中的方法重載發生在同一個類裏面兩個或者是多個方法的方法名相同可是參數不一樣的狀況。與此相對,方法覆蓋是說子類從新定義了父類的方法。方法覆蓋必須有相同的方法名,參數列表和返回類型。覆蓋者可能不會限制它所覆蓋的方法的訪問。框架

7.Enumeration和Iterator接口的區別?

Enumeration的速度是Iterator的兩倍,也使用更少的內存。Enumeration是很是基礎的,也知足了基礎的須要。可是,與Enumeration相比,Iterator更加安全,由於當一個集合正在被遍歷的時候,它會阻止其它線程去修改集合。

迭代器取代了Java集合框架中的Enumeration。迭代器容許調用者從集合中移除元素,而Enumeration不能作到。爲了使它的功能更加清晰,迭代器方法名已經通過改善。

8.爲什麼沒有像Iterator.add()這樣的方法,向集合中添加元素?

語義不明,已知的是,Iterator的協議不能確保迭代的次序。然而要注意,ListIterator沒有提供一個add操做,它要確保迭代的順序。

9.爲什麼迭代器沒有一個方法能夠直接獲取下一個元素,而不須要移動遊標?

它能夠在當前Iterator的頂層實現,可是它用得不多,若是將它加到接口中,每一個繼承都要去實現它,這沒有意義。

10.Iterater和ListIterator之間有什麼區別?

(1)咱們可使用Iterator來遍歷Set和List集合,而ListIterator只能遍歷List。

(2)Iterator只能夠向前遍歷,而LIstIterator能夠雙向遍歷。

(3)ListIterator從Iterator接口繼承,而後添加了一些額外的功能,好比添加一個元素、替換一個元素、獲取前面或後面元素的索引位置。

11.遍歷一個List有哪些不一樣的方式?

List<String> strList = new ArrayList<>(); //使用for-each循環 for(String obj : strList){ System.out.println(obj); } //using iterator Iterator<String> it = strList.iterator(); while(it.hasNext()){ String obj = it.next(); System.out.println(obj); } 

使用迭代器更加線程安全,由於它能夠確保,在當前遍歷的集合元素被更改的時候,它會拋出ConcurrentModificationException。

12.經過迭代器fail-fast屬性,你明白了什麼?

每次咱們嘗試獲取下一個元素的時候,Iterator fail-fast屬性檢查當前集合結構裏的任何改動。若是發現任何改動,它拋出ConcurrentModificationException。Collection中全部Iterator的實現都是按fail-fast來設計的(ConcurrentHashMap和CopyOnWriteArrayList這類併發集合類除外)。

13.fail-fast與fail-safe有什麼區別?

Iterator的fail-fast屬性與當前的集合共同起做用,所以它不會受到集合中任何改動的影響。

Java.util包中的全部集合類都被設計爲fail-fast的,而java.util.concurrent中的集合類都爲fail-safe的。

Fail-fast迭代器拋出ConcurrentModificationException,而fail-safe迭代器從不拋出ConcurrentModificationException。

14.在迭代一個集合的時候,如何避免ConcurrentModificationException?

在遍歷一個集合的時候,咱們可使用併發集合類來避免ConcurrentModificationException,好比使用CopyOnWriteArrayList,而不是ArrayList。

1五、Math.round(11.5)等於多少? Math.round(-11.5)等於多少?

Math類中提供了三個與取整有關的方法:ceil、floor、round,這些方法的做用與它們的英文名稱的含義相對應,

例如:

ceil的英文意義是天花板,該方法就表示向上取整,Math.ceil(11.3)的結果爲12,Math.ceil(-11.3)的結果是-11;

floor的英文意義是地板,該方法就表示向下取整,Math.floor(11.6)的結果爲11,Math.floor(-11.6)的結果是-12;

最難掌握的是round方法,它表示「四捨五入」,算法爲Math.floor(x+0.5):

即將原來的數字加上0.5後再向下取整,因此,Math.round(11.5)的結果爲12,Math.round(-11.5)的結果爲-11。

1六、下面的代碼有什麼不妥之處?

  1. if(username.equals(「zxx」){}

  2. int x = 1;

return x==1?true:false;

1七、請說出做用域public,private,protected,以及不寫時的區別

這四個做用域的可見範圍以下表所示。

說明:若是在修飾的元素上面沒有寫任何訪問修飾符,則表示friendly。

做用域 當前類同一package子孫類其餘package

public √ √ √ √

protected √ √ √ ×

friendly √ √ × ×

private √ × × ×

備註:只要記住了有4種訪問權限,4個訪問範圍,而後將全選和範圍在水平和垂直方向上分別按排從小到大或從大到小的順序排列,就很容易畫出上面的圖了。

1八、Overload和Override的區別。Overloaded的方法是否能夠改變返回值的類型?

Overload是重載的意思,Override是覆蓋的意思,也就是重寫。

重載Overload表示同一個類中能夠有多個名稱相同的方法,但這些方法的參數列表各不相同(即參數個數或d類型不一樣)。

重寫Override表示子類中的方法能夠與父類中的某個方法的名稱和參數徹底相同,經過子類建立的實例對象調用這個方法時,將調用子類中的定義方法,這至關於把父類中定義的那個徹底相同的方法給覆蓋了,這也是面向對象編程的多態性的一種表現。子類覆蓋父類的方法時,只能比父類拋出相同或更少的異常(父類拋出的異常的子異常),由於子類能夠解決父類的一些問題,不能比父類有更多的問題。子類方法的訪問權限只能比父類的相等或更大,不能更小。若是父類的方法是private類型,那麼,子類則不存在覆蓋的限制,至關於子類中增長了一個全新的方法。

至於Overloaded的方法是否能夠改變返回值的類型這個問題,要看你倒底想問什麼呢?這個題目很模糊。若是幾個Overloaded的方法的參數列表不同,它們的返回者類型固然也能夠不同。但我估計你想問的問題是:若是兩個方法的參數列表徹底同樣,是否可讓它們的返回值不一樣來實現重載Overload。這是不行的,咱們能夠用反證法來講明這個問題,由於咱們有時候調用一個方法時也能夠不定義返回結果變量,即不要關心其返回結果,例如,咱們調用map.remove(key)方法時,雖然remove方法有返回值,可是咱們一般都不會定義接收返回結果的變量,這時候假設該類中有兩個名稱和參數列表徹底相同的方法,僅僅是返回類型不一樣,java就沒法肯定編程者倒底是想調用哪一個方法了,由於它沒法經過返回結果類型來判斷。

override能夠翻譯爲覆蓋,從字面就能夠知道,它是覆蓋了一個方法而且對其重寫,以求達到不一樣的做用。對咱們來講最熟悉的覆蓋就是對接口方法的實現,在接口中通常只是對方法進行了聲明,而咱們在實現時,就須要實現接口聲明的全部方法。除了這個典型的用法之外,咱們在繼承中也可能會在子類覆蓋父類中的方法。在覆蓋要注意如下的幾點:

  1. 覆蓋的方法的標誌必需要和被覆蓋的方法的標誌徹底匹配,才能達到覆蓋的效果;

  2. 覆蓋方法的返回值必須和被覆蓋的方法的返回值一致;

  3. 覆蓋的方法所拋出的異常必須和被覆蓋方法的所拋出的異常一致,或者是其子類;

  4. 被覆蓋的方法不能爲private,不然在其子類中只是新定義了一個方法,並無對其進行覆蓋。

overload對咱們來講可能比較熟悉,能夠翻譯爲重載,它是指咱們能夠定義一些名稱相同的方法,經過定義不一樣的輸入參數來區分這些方法,而後再調用時,VM就會根據不一樣的參數樣式,來選擇合適的方法執行。在使用重載要注意如下的幾點:

  1. 在使用重載時只能經過不一樣的參數樣式。例如,不一樣的參數類型,不一樣的參數個數,不一樣的參數順序(固然,同一方法內的幾個參數類型必須不同,例如能夠是fun(int,float),可是不能爲fun(int,int));

  2. 不能經過訪問權限、返回類型、拋出的異常進行重載;

  3. 方法的異常類型和數目不會對重載形成影響;

  4. 對於繼承來講,若是某一方法在父類中是訪問權限是priavte,那麼就不能在子類對其進行重載,若是定義的話,也只是定義了一個新方法,而不會達到重載的效果。

1九、構造器Constructor是否可被override?

構造器Constructor不能被繼承,所以不能重寫Override,但能夠被重載Overload。

20、接口是否可繼承接口?抽象類是否可實現(implements)接口?抽象類是否可繼承具體類(concrete class)?抽象類中是否能夠有靜態的main方法?

接口能夠繼承接口。抽象類能夠實現(implements)接口,抽象類是能夠繼承具體類。抽象類中能夠有靜態的main方法

備註:只要明白了接口和抽象類的本質和做用,這些問題都很好回答,你想一想,若是你是java語言的設計者,你是否會提供這樣的支持,若是不提供的話,有什麼理由嗎?若是你沒有道理不提供,那答案就是確定的了。

只有記住抽象類與普通類的惟一區別就是不能建立實例對象和容許有abstract方法。

讀者福利

合理利用本身每一分每一秒的時間來學習提高本身,不要再用"沒有時間「來掩飾本身思想上的懶惰!趁年輕,使勁拼,給將來的本身一個交代!

 

 

相關文章
相關標籤/搜索