「BAT常問」40道Java基礎面試題及詳細答案整理匯總「25—32」

更多技術分享,請點擊右上角紅色的"關注",感謝你的支持!

本文為Java面試題系列文章第五篇,之前文章可點擊訪問:

一、

二、

三、

四、

25.Java(OOP)面向對象的三個特徵與含義


封裝(高內聚低耦合 -->解耦)

封裝是指將某事物的屬性和行為包裝到對象中,這個對象只對外公佈需要公開的屬性和行為,而這個公佈也是可以有選擇性的公佈給其它對象。在java中能使用private、protected、public三種修飾符或不用(即默認defalut)對外部對象訪問該對象的屬性和行為進行限制。

java的繼承(重用父類的代碼)

繼承是子對象可以繼承父對象的屬性和行為,亦即父對象擁有的屬性和行為,其子對象也就擁有了這些屬性和行為。

java中的多態(父類引用指向子類對象)

多態是指父對象中的同一個行為能在其多個子對象中有不同的表現

有兩種多態的機制:編譯時多態、運行時多態

1、方法的重載:重載是指同一類中有多個同名的方法,但這些方法有著不同的參數。,因此在編譯時就可以確定到底調用哪個方法,它是一種編譯時多態。2、方法的重寫:子類可以覆蓋父類的方法,因此同樣的方法會在父類中與子類中有著不同的表現形式。

「BAT常問」40道Java基礎面試題及詳細答案整理彙總「25—32」

26.Override和Overload的含義及它們的區別是什麼?

重載 Overload方法名相同,參數列表不同(個數、順序、類型不同)與返回類型無關。重寫 Override 覆蓋。 將父類的方法覆蓋。重寫方法重寫:方法名相同,訪問修飾符只能大於被重寫的方法訪問修飾符,方法簽名個數,順序個數類型相同。

Override(重寫)

  • 方法名、參數、返回值相同。

  • 子類方法不能縮小父類方法的訪問權限。

  • 子類方法不能拋出比父類方法更多的異常(但子類方法可以不拋出異常)。

  • 存在於父類和子類之間。

  • 方法被定義為final不能被重寫。

Overload(重載)

  • 參數類型、個數、順序至少有一個不相同。

  • 不能重載只有返回值不同的方法名。

  • 存在於父類和子類、同類中。

而重載的規則

1、必須具有不同的參數列表。2、可以有不同的返回類型,只要參數列表不同就可以了。3、可以有不同的訪問修飾符。4、可以拋出不同的異常。

重寫方法的規則

1、參數列表必須完全與被重寫的方法相同,否則不能稱其為重寫而是重載。2、返回的類型必須一直與被重寫的方法的返回類型相同,否則不能稱其為重寫而是重載。3、訪問修飾符的限制一定要大於被重寫方法的訪問修飾符(public>protected>default>private)。4、重寫方法一定不能拋出新的檢查異常或者比被重寫方法申明更加寬泛的檢查型異常。

例如:父類的一個方法申明瞭一個檢查異常IOException,在重寫這個方法是就不能拋出Exception,只能拋出IOException的子類異常,可以拋出非檢查異常。

27.Interface與abstract類的區別


Interface 只能有成員常量,只能是方法的聲明。Abstract class可以有成員變量,可以聲明普通方法和抽象方法。

interface是接口,所有的方法都是抽象方法,成員變量是默認的public static final 類型。接口不能實例化自己

abstract class是抽象類,至少包含一個抽象方法的累叫抽象類,抽象類不能被自身實例化,並用abstract關鍵字來修飾

28.Static class 與non static class的區別


static class(內部靜態類)

1、用static修飾的是內部類,此時這個內部類變為靜態內部類;對測試有用。

2、內部靜態類不需要有指向外部類的引用。

3、靜態類只能訪問外部類的靜態成員,不能訪問外部類的非靜態成員。

non static class(非靜態內部類)

1、非靜態內部類需要持有對外部類的引用。

2、非靜態內部類能夠訪問外部類的靜態和非靜態成員。

3、一個非靜態內部類不能脫離外部類實體被創建。

4、一個非靜態內部類可以訪問外部類的數據和方法。

「BAT常問」40道Java基礎面試題及詳細答案整理彙總「25—32」

29.java多態的實現原理

多態的概念:同一操作作用於不同對象,可以有不同的解釋,有不同的執行結果,這就是多態,簡單來說就是父類的引用指向子類對象。

將一個方法調用同一個方法主體關聯起來被稱作綁定,JAVA中分為前期綁定和後期綁定(動態綁定或運行時綁定),在程序執行之前進行綁定(由編譯器和連接程序實現)叫做前期綁定,因為在編譯階段被調用方法的直接地址就已經存儲在方法所屬類的常量池中了,程序執行時直接調用。後期綁定含義就是在程序運行時根據對象的類型進行綁定,想實現後期綁定,就必須具有某種機制,以便在運行時能判斷對象的類型,從而找到對應的方法,簡言之就是必須在對象中安置某種“類型信”,JAVA中除了static方法、final方法(private方法屬於)之外,其他的方法都是後期綁定。後期綁定會涉及到JVM管理下的一個重要的數據結構——方法表,方法表以數組的形式記錄當前類及其所有父類的可見方法字節碼在內存中的直接地址。

動態綁定具體的調用過程為:

1.首先會找到被調用方法所屬類的全限定名

2.在此類的方法表中尋找被調用方法,如果找到,會將方法表中此方法的索引項記錄到常量池中(這個過程叫常量池解析),如果沒有,編譯失敗。

3.根據具體實例化的對象找到方法區中此對象的方法表,再找到方法表中的被調用方法,最後通過直接地址找到字節碼所在的內存空間。

最後說明,域和靜態方法都是不具有多態性的,任何的域訪問操作都將由編譯器解析,因此不是多態的。靜態方法是跟類,而並非單個對象相關聯的。

30.foreach與正常for循環效率對比


用for循環arrayList 10萬次花費時間:5毫秒。用foreach循環arrayList 10萬次花費時間:7毫秒。用for循環linkList 10萬次花費時間:4481毫秒。用foreach循環linkList 10萬次花費時間:5毫秒。

循環ArrayList時,普通for循環比foreach循環花費的時間要少一點。循環LinkList時,普通for循環比foreach循環花費的時間要多很多。

當我將循環次數提升到一百萬次的時候,循環ArrayList,普通for循環還是比foreach要快一點;但是普通for循環在循環LinkList時,程序直接卡死。

ArrayList:ArrayList是採用數組的形式保存對象的,這種方式將對象放在連續的內存塊中,所以插入和刪除時比較麻煩,查詢比較方便。

LinkList:LinkList是將對象放在獨立的空間中,而且每個空間中還保存下一個空間的索引,也就是數據結構中的鏈表結構,插入和刪除比較方便,但是查找很麻煩,要從第一個開始遍歷。

結論:

需要循環數組結構的數據時,建議使用普通for循環,因為for循環採用下標訪問,對於數組結構的數據來說,採用下標訪問比較好

需要循環鏈表結構的數據時,一定不要使用普通for循環,這種做法很糟糕,數據量大的時候有可能會導致系統崩潰

「BAT常問」40道Java基礎面試題及詳細答案整理彙總「25—32」

31.Java IO與NIO概念和區別是什麼?


NIO是為了彌補IO操作的不足而誕生的,NIO的一些新特性有:非阻塞I/O,選擇器,緩衝以及管道。管道(Channel),緩衝(Buffer) ,選擇器( Selector)是其主要特徵

概念解釋

Channel——管道實際上就像傳統IO中的流,到任何目的地(或來自任何地方)的所有數據都必須通過一個 Channel 對象。一個 Buffer 實質上是一個容器對象。

每一種基本 Java 類型都有一種緩衝區類型:

ByteBuffer——byte

CharBuffer——char

ShortBuffer——short

IntBuffer——int

LongBuffer——long

FloatBuffer——float

DoubleBuffer——double

Selector——選擇器用於監聽多個管道的事件,使用傳統的阻塞IO時我們可以方便的知道什麼時候可以進行讀寫,而使用非阻塞通道,我們需要一些方法來知道什麼時候通道準備好了,選擇器正是為這個需要而誕生的。

NIO和傳統的IO有什麼區別呢?

IO是面向流的,NIO是面向塊(緩衝區)的。

IO面向流的操作一次一個字節地處理數據。一個輸入流產生一個字節的數據,一個輸出流消費一個字節的數據。,導致了數據的讀取和寫入效率不佳。

NIO面向塊的操作在一步中產生或者消費一個數據塊。按塊處理數據比按(流式的)字節處理數據要快得多,同時數據讀取到一個它稍後處理的緩衝區,需要時可在緩衝區中前後移動。這就增加了處理過程中的靈活性。通俗來說,NIO採取了“預讀”的方式,當你讀取某一部分數據時,他就會猜測你下一步可能會讀取的數據而預先緩衝下來。

IO是阻塞的,NIO是非阻塞的

對於傳統的IO,當一個線程調用read() 或 write()時,該線程被阻塞,直到有一些數據被讀取,或數據完全寫入。該線程在此期間不能再幹任何事情了。

而對於NIO,使用一個線程發送讀取數據請求,沒有得到響應之前,線程是空閒的,此時線程可以去執行別的任務,而不是像IO中那樣只能等待響應完成。

NIO和IO適用場景

NIO是為彌補傳統IO的不足而誕生的,但是尺有所短寸有所長,NIO也有缺點,因為NIO是面向緩衝區的操作,每一次的數據處理都是對緩衝區進行的,那麼就會有一個問題,在數據處理之前必須要判斷緩衝區的數據是否完整或者已經讀取完畢,如果沒有,假設數據只讀取了一部分,那麼對不完整的數據處理沒有任何意義。所以每次數據處理之前都要檢測緩衝區數據。

那麼NIO和IO各適用的場景是什麼呢?

如果需要管理同時打開的成千上萬個連接,這些連接每次只是發送少量的數據,例如聊天服務器,這時候用NIO處理數據可能是個很好的選擇。

而如果只有少量的連接,而這些連接每次要發送大量的數據,這時候傳統的IO更合適。使用哪種處理數據,需要在數據的響應等待時間和檢查緩衝區數據的時間上作比較來權衡選擇。

通俗解釋,最後,對於NIO和傳統IO

有一個網友講的生動的例子:

以前的流總是堵塞的,一個線程只要對它進行操作,其它操作就會被堵塞,也就相當於水管沒有閥門,你伸手接水的時候,不管水到了沒有,你就都只能耗在接水(流)上。

nio的Channel的加入,相當於增加了水龍頭(有閥門),雖然一個時刻也只能接一個水管的水,但依賴輪換策略,在水量不大的時候,各個水管裡流出來的水,都可以得到妥

善接納,這個關鍵之處就是增加了一個接水工,也就是Selector,他負責協調,也就是看哪根水管有水了的話,在當前水管的水接到一定程度的時候,就切換一下:臨時關上當

前水龍頭,試著打開另一個水龍頭(看看有沒有水)。

當其他人需要用水的時候,不是直接去接水,而是事前提了一個水桶給接水工,這個水桶就是Buffer。也就是,其他人雖然也可能要等,但不會在現場等,而是回家等,可以做

其它事去,水接滿了,接水工會通知他們。

這其實也是非常接近當前社會分工細化的現實,也是統分利用現有資源達到併發效果的一種很經濟的手段,而不是動不動就來個並行處理,雖然那樣是最簡單的,但也是最浪費資源的方式。

「BAT常問」40道Java基礎面試題及詳細答案整理彙總「25—32」

32.java反射的作用與原理是什麼?


什麼是Java的反射呢?

Java 反射是可以讓我們在運行時,通過一個類的Class對象來獲取它獲取類的方法、屬性、父類、接口等類的內部信息的機制。

這種動態獲取信息以及動態調用對象的方法的功能稱為JAVA的反射。

反射的作用?

反射就是:在任意一個方法裡:

1.如果我知道一個類的名稱/或者它的一個實例對象, 我就能把這個類的所有方法和變量的信息找出來(方法名,變量名,方法,修飾符,類型,方法參數等等所有信息)

2.如果我還明確知道這個類裡某個變量的名稱,我還能得到這個變量當前的值。

3.當然,如果我明確知道這個類裡的某個方法名+參數個數類型,我還能通過傳遞參數來運行那個類裡的那個方法。

反射機制主要提供了以下功能:

  • 在運行時判斷任意一個對象所屬的類。

  • 在運行時構造任意一個類的對象。

  • 在運行時判斷任意一個類所具有的成員變量和方法。

  • 在運行時調用任意一個對象的方法。

  • 生成動態代理。

反射的原理?

JAVA語言編譯之後會生成一個.class文件,反射就是通過字節碼文件找到某一個類、類中的方法以及屬性等。

反射的實現API有哪些?

反射的實現主要藉助以下四個類:

Class:類的對象 Constructor:類的構造方法 Field:類中的屬性對象 Method:類中的方法對象


分享到:


相關文章: