1. 程式人生 > 其它 >最新精選Java面試題及答案,Java基礎面試題答案精選

最新精選Java面試題及答案,Java基礎面試題答案精選


上圖是我整理的Java面試題合集,包攬了基本所有技術棧:完整版Java面試題合集附答案,高清PDF下載

1. 字元流和位元組流有什麼區別?

位元組流用於操作包含ASCII字元的檔案。JAVA也支援其他的字元如Unicode,為了讀取包含Unicode字元的檔案,JAVA語言引入了字元流。ASCII作為Unicode的子集,對於英語字元的檔案,可以使用位元組流也可以使用字元流。

2. 普通類和抽象類有哪些區別?

  • 普通類不能包含抽象方法,抽象類可以包含抽象方法。
  • 抽象類不能直接例項化,普通類可以直接例項化。

3. 字元型常量和字串常量的區別

  1. 形式上: 字元常量是單引號引起的一個字元 字串常量是雙引號引起的若干個字元
  2. 含義上: 字元常量相當於一個整形值(ASCII值),可以參加表示式運算 字串常量代表一個地址值(該字串在記憶體中存放位置)
  3. 佔記憶體大小 字元常量只佔一個位元組 字串常量佔若干個位元組(至少一個字元結束標誌)

4. 有哪些Filter流的子類?

1、 LineNumberInputStream:給目標檔案增加行號。
2、 DataInputStream:有些特殊的方法如:readInt()、readDouble()和readLine()等可以一次性的讀取一個int, double和一個string型別的資料。
3、 BufferedInputStream:增加效能。
4、 PushbackInputStream

:推送要求的位元組到系統中。

5. Java中引用資料型別有哪些,它們與基本資料型別有什麼區別?

引用資料型別分3種:類,介面,陣列;

簡單來說,只要不是基本資料型別.都是引用資料型別。 那他們有什麼不同呢?

1、從概念方面來說

1,基本資料型別:變數名指向具體的數值

2,引用資料型別:變數名不是指向具體的數值,而是指向存資料的記憶體地址,.也及時hash值

2、從記憶體的構建方面來說(記憶體中,有堆記憶體和棧記憶體兩者)

1,基本資料型別:被建立時,在棧記憶體中會被劃分出一定的記憶體,並將數值儲存在該記憶體中.

2,引用資料型別:被建立時,首先會在棧記憶體中分配一塊空間,然後在堆記憶體中也會分配一塊具體的空間用來儲存資料的具體資訊,即hash值,然後由棧中引用指向堆中的物件地址.

舉個例子

//基本資料型別作為方法引數被呼叫
public class Main{
   public static void main(String[] args){
      //基本資料型別
      int i = 1;
      int j = 1;
      double d = 1.2;


      //引用資料型別
      String str = "Hello";
      String str1= "Hello";
   }
}

由上圖可知,基本資料型別中會存在兩個相同的1,而引用型型別就不會存在相同的資料。
假如"hello"的引用地址是xxxxx1,宣告str變數並其賦值"hello"實際上就是讓str變數引用了"hello"的記憶體地址,這個記憶體地址就儲存在堆記憶體中,是不會改變的,當再次宣告變數str1也是賦值為"hello"時,此時就會在堆記憶體中查詢是否有"hello"這個地址,如果堆記憶體中已經存在這個地址了,就不會再次建立了,而是讓str1變數也指向xxxxx1這個地址,如果沒有的話,就會重新建立一個地址給str1變數。

從使用方面來說

1,基本資料型別:判斷資料是否相等,用和!=判斷。
2,引用資料型別:判斷資料是否相等,用equals()方法,
和!=是比較數值的。而equals()方法是比較記憶體地址的。

補充:資料型別選擇的原則

  • 如果要表示整數就使用int,表示小數就使用double;
  • 如果要描述日期時間數字或者表示檔案(或記憶體)大小用long;
  • 如果要實現內容傳遞或者編碼轉換使用byte;
  • 如果要實現邏輯的控制,可以使用booleam;
  • 如果要使用中文,使用char避免中文亂碼;
  • 如果按照儲存範圍:byte < int < long < double;

6. BIO、NIO、AIO 有什麼區別?

關於Java中的IO,網路通訊模型主要分三種:IO、NIO和AIO。

適用場景:

BIO, 適用於連線較少,對伺服器資源消耗很大,但是程式設計簡單。是同步阻塞的。
舉例:你到餐館點餐,然後在那兒等著,什麼也做不了,只要飯還沒有好,就要必須等著
NIO, 使用於連線數量比較多且連線時間比較短的架構,比如聊天伺服器,程式設計比較複雜。是同步非阻塞的
舉例:你到餐館點完餐,然後就可以去玩兒了,玩一會兒就回飯館問一聲,飯好了沒。
AIO, 適用於連線數量多而且連線時間長的架構,比如相簿伺服器,充分呼叫OS參與併發操作,程式設計比較複雜。是非同步非阻塞的。
舉例:飯館打電話給你說,我們知道你的位置,待會兒給您送來,你安心的玩兒就可以了。類似於外賣。

1、IO(同步阻塞)

傳統的網路通訊模型,就是BIO,同步阻塞IO, 其實就是服務端建立一個ServerSocket, 然後就是客戶端用一個Socket去連線服務端的那個ServerSocket, ServerSocket接收到了一個的連線請求就建立一個Socket和一個執行緒去跟那個Socket進行通訊。接著客戶端和服務端就進行阻塞式的通訊,客戶端傳送一個請求,服務端Socket進行處理後返回響應,在響應返回前,客戶端那邊就阻塞等待,上門事情也做不了。 這種方式的缺點, 每次一個客戶端接入,都需要在服務端建立一個執行緒來服務這個客戶端,這樣大量客戶端來的時候,就會造成服務端的執行緒數量可能達到了幾千甚至幾萬,這樣就可能會造成服務端過載過高,最後崩潰死掉。

2、NIO(同步非阻塞,JDK1.4)

NIO是一種同步非阻塞IO, 基於Reactor模型來實現的。其實相當於就是一個執行緒處理大量的客戶端的請求,通過一個執行緒輪詢大量的channel,每次就獲取一批有事件的channel,然後對每個請求啟動一個執行緒處理即可。這裡的核心就是非阻塞,就那個selector一個執行緒就可以不停輪詢channel,所有客戶端請求都不會阻塞,直接就會進來,大不了就是等待一下排著隊而已。這裡面優化BIO的核心就是,一個客戶端並不是時時刻刻都有資料進行互動,沒有必要死耗著一個執行緒不放,所以客戶端選擇了讓執行緒歇一歇,只有客戶端有相應的操作的時候才發起通知,建立一個執行緒來處理請求。

3、AIO(NIO2,非同步非阻塞,JDK1.7)

對於NIO來說,我們的業務執行緒是在IO操作準備好時,得到通知,接著就由這個執行緒自行進行IO操作,IO操作本身是同步的。但是對AIO來說,則更加進了一步,它不是在IO準備好時再通知執行緒,而是在IO操作已經完成後,再給執行緒發出通知。因此AIO是不會阻塞的,此時我們的業務邏輯將變成一個回撥函式,等待IO操作完成後,由系統自動觸發。

與NIO不同,當進行讀寫操作時,只須直接呼叫API的read或write方法即可。這兩種方法均為非同步的,對於讀操作而言,當有流可讀取時,作業系統會將可讀的流傳入read方法的緩衝區,並通知應用程式;對於寫操作而言,當作業系統將write方法傳遞的流寫入完畢時,作業系統主動通知應用程式。 即可以理解為,read/write方法都是非同步的,完成後會主動呼叫回撥函式。 在JDK1.7中,這部分內容被稱作NIO.2,主要在Java.nio.channels包下增加了下面四個非同步通道:

  • AsynchronousSocketChannel

  • AsynchronousServerSocketChannel

  • AsynchronousFileChannel

  • AsynchronousDatagramChannel

    AIO是非同步非阻塞IO,基於Proactor模型實現。 每個連線傳送過來的請求,都會繫結一個Buffer,然後通知作業系統去完成非同步的讀,這個時間你就可以去做其他的事情,等到作業系統完成讀之後,就會呼叫你的介面,給你作業系統非同步讀完的資料。這個時候你就可以拿到資料進行處理,將資料往回寫,在往回寫的過程,同樣是給作業系統一個Buffer,讓作業系統去完成寫,寫完了來通知你。這倆個過程都有buffer存在,資料都是通過buffer來完成讀寫。,

7. try {}裡有一個return語句,那麼緊跟在這個try後的finally{}裡的code會不會被執行,什麼時候被執行,在return前還是後?

我們知道finally{}中的語句是一定會執行的,那麼這個可能正常脫口而出就是return之前,return之後可能就出了這個方法了,鬼知道跑哪裡去了,但更準確的應該是在return中間執行,請看下面程式程式碼的執行結果:

public classTest {
    public static void main(String[]args) {
       System.out.println(newTest().test());;
    }
    static int test()
    {
       intx = 1;
       try
       {
          return x;
       }
       finally
       {
          ++x;
       }
    }
}

執行結果如下:

1

執行結果是1,為什麼呢?主函式呼叫子函式並得到結果的過程,好比主函式準備一個空罐子,當子函式要返回結果時,先把結果放在罐子裡,然後再將程式邏輯返回到主函式。所謂返回,就是子函式說,我不運行了,你主函式繼續執行吧,這沒什麼結果可言,結果是在說這話之前放進罐子裡的。

8. Java IO 中的設計模式?(重點)

重點是用到兩個設計模式:裝飾模式和介面卡模式。

裝飾模式: 在由InputStream、OutputStream、Reader和Writer代表的等級結構內部,有一些流處理器可以對另一些流處理器起到裝飾作用,形成新的、具有改善了的功能的流處理器。
介面卡模式: 在由InputStream、OutputStream、Reader和Writer代表的等級結構內部,有一些流處理器是對其他型別的流處理器的適配,這就是介面卡的應用。

9. static注意事項

  • 1、靜態只能訪問靜態。
  • 2、非靜態既可以訪問非靜態的,也可以訪問靜態的。

10. System.out.println()是什麼?

println是PrintStream的一個方法。out是一個靜態PrintStream型別的成員變數,System是一個java.lang包中的類,用於和底層的作業系統進行互動。

11. final 有什麼用?

用於修飾類、屬性和方法

  • 被final修飾的類不可以被繼承
  • 被final修飾的方法不可以被重寫
  • 被final修飾的變數不可以被改變,被final修飾不可變的是變數的引用,而不是引用指向的內容,引用指向的內容是可以改變的

12. &和&&的區別

  • &運算子有兩種用法:(1)按位與;(2)邏輯與。

  • &&運算子是短路與運算。邏輯與跟短路與的差別是非常巨大的,雖然二者都要求運算子左右兩端的布林值都是true 整個表示式的值才是 true。&&之所以稱為短路運算,是因為如果&&左邊的表示式的值是 false,右邊的表示式會被直接短路掉,不會進行運算。

注意:邏輯或運算子(|)和短路或運算子(||)的差別也是如此。

13. 面向物件五大基本原則是什麼(可選)

  • 單一職責原則SRP(Single Responsibility Principle)
    類的功能要單一,不能包羅永珍,跟雜貨鋪似的。
  • 開放封閉原則OCP(Open-Close Principle)
    一個模組對於拓展是開放的,對於修改是封閉的,想要增加功能熱烈歡迎,想要修改,哼,一萬個不樂意。
  • 裡式替換原則LSP(the Liskov Substitution Principle LSP)
    子類可以替換父類出現在父類能夠出現的任何地方。比如你能代表你爸去你姥姥家幹活。哈哈~~
  • 依賴倒置原則DIP(the Dependency Inversion Principle DIP)
    高層次的模組不應該依賴於低層次的模組,他們都應該依賴於抽象。抽象不應該依賴於具體實現,具體實現應該依賴於抽象。就是你出國要說你是中國人,而不能說你是哪個村子的。比如說中國人是抽象的,下面有具體的xx省,xx市,xx縣。你要依賴的抽象是中國人,而不是你是xx村的。
  • 介面分離原則ISP(the Interface Segregation Principle ISP)
    設計時採用多個與特定客戶類有關的介面比採用一個通用的介面要好。就比如一個手機擁有打電話,看視訊,玩遊戲等功能,把這幾個功能拆分成不同的介面,比在一個接口裡要好的多。

14. 什麼是Java

Java是一門面向物件程式語言,不僅吸收了C++語言的各種優點,還摒棄了C++裡難以理解的多繼承、指標等概念,因此Java語言具有功能強大和簡單易用兩個特徵。Java語言作為靜態面向物件程式語言的代表,極好地實現了面向物件理論,允許程式設計師以優雅的思維方式進行復雜的程式設計

15. 抽象類和介面的對比

  • 抽象類是用來捕捉子類的通用特性的。介面是抽象方法的集合。

  • 從設計層面來說,抽象類是對類的抽象,是一種模板設計,介面是行為的抽象,是一種行為的規範。

相同點

  • 介面和抽象類都不能例項化
  • 都位於繼承的頂端,用於被其他實現或繼承
  • 都包含抽象方法,其子類都必須覆寫這些抽象方法

不同點

引數 抽象類 介面
宣告 抽象類使用abstract關鍵字宣告 介面使用interface關鍵字宣告
實現 子類使用extends關鍵字來繼承抽象類。如果子類不是抽象類的話,它需要提供抽象類中所有宣告的方法的實現 子類使用implements關鍵字來實現介面。它需要提供介面中所有宣告的方法的實現
構造器 抽象類可以有構造器 介面不能有構造器
訪問修飾符 抽象類中的方法可以是任意訪問修飾符 介面方法預設修飾符是public。並且不允許定義為 private 或者 protected
多繼承 一個類最多隻能繼承一個抽象類 一個類可以實現多個介面
欄位宣告 抽象類的欄位宣告可以是任意的 介面的欄位預設都是 static 和 final 的

備註:Java8中介面中引入預設方法和靜態方法,以此來減少抽象類和介面之間的差異。

現在,我們可以為介面提供預設實現的方法了,並且不用強制子類來實現它。

  • 介面和抽象類各有優缺點,在介面和抽象類的選擇上,必須遵守這樣一個原則:
  • 行為模型應該總是通過介面而不是抽象類定義,所以通常是優先選用介面,儘量少用抽象類。
  • 選擇抽象類的時候通常是如下情況:需要定義子類的行為,又要為子類提供通用的功能。