天天看點

最常見的208道Java最新面試題及答案(一) 

  

今天動力節點java教育訓練機構小編為大家分享“最常見的208道Java最新面試題及答案”,本文主要包含十九個子產品的java面試題,分别是:Java 基礎、容器、多線程、反射、對象拷貝、Java Web 、異常、網絡、設計模式、Spring/Spring MVC、Spring Boot/Spring Cloud、Hibernate、MyBatis、RabbitMQ、Kafka、Zookeeper、MySQL、Redis、JVM,希望通過此能夠幫助到正在找工作或是準備找工作的“你”,下面就随小編一起看看。

最常見的208道Java最新面試題及答案(一) 

java面試題子產品

  一、 java最新面試題及答案:Java基礎子產品

  1、JDK 和 JRE 有什麼差別?

  JDK:Java Development Kit 的簡稱,Java 開發工具包,提供了 Java 的開發環境和運作環境。

  JRE:Java Runtime Environment 的簡稱,Java 運作環境,為 Java 的運作提供了所需環境。

  具體來說 JDK 其實包含了 JRE,同時還包含了編譯 Java 源碼的編譯器 Javac,還包含了很多 Java 程式調試和分析的工具。簡單來說:如果你需要運作 Java 程式,隻需安裝 JRE 就可以了,如果你需要編寫 Java 程式,需要安裝 JDK。

  2、== 和 equals 的差別是什麼?

  == 解讀:

  對于基本類型和引用類型 == 的作用效果是不同的,如下所示:

  基本類型:比較的是值是否相同;

  引用類型:比較的是引用是否相同;

  代碼示例:

String x = "string";

String y = "string";

String z = new String("string");

System.out.println(x==y); // true

System.out.println(x==z); // false

System.out.println(x.equals(y)); // true

System.out.println(x.equals(z)); // true

  代碼解讀:因為 x 和 y 指向的是同一個引用,是以 == 也是 true,而 new String()方法則重寫開辟了記憶體空間,是以 == 結果為 false,而 equals 比較的一直是值,是以結果都為 true。

  equals 解讀:

  equals 本質上就是 ==,隻不過 String 和 Integer 等重寫了 equals 方法,把它變成了值比較。看下面的代碼就明白了。

  首先來看預設情況下 equals 比較一個有相同值的對象,代碼如下:

class Cat {

public Cat(String name) {

this.name = name;

}

private String name; 

public String getName() {

return name;

public void setName(String name) {

this.name = name;

}

}

Cat c1 = new Cat;

Cat c2 = new Cat;

System.out.println(c1.equals(c2)); // false

  輸出結果出乎我們的意料,竟然是 false?這是怎麼回事,看了 equals 源碼就知道了,源碼如下:

public boolean equals(Object obj) {

return (this == obj);

}

  原來 equals 本質上就是 ==。

  同樣的,當我們進入 String 的 equals 方法,找到了答案,代碼如下:

String s1 = new String;

String s2 = new String;

System.out.println(s1.equals(s2)); // true

同樣的,當我們進入 String 的 equals 方法,找到了答案,代碼如下:

public boolean equals(Object anObject) {

if (this == anObject) {

return true;

}

if (anObject instanceof String) {

String anotherString = (String)anObject;

int n = value.length;

if (n == anotherString.value.length) {

char v1[] = value;

char v2[] = anotherString.value;

int i = 0;

while (n-- != 0) {

if (v1[i] != v2[i])

return false;

i++;

}

return true;

}

}

return false;

}

  原來是 String 重寫了 Object 的 equals 方法,把引用比較改成了值比較。

  總結 :== 對于基本類型來說是值比較,對于引用類型來說是比較的是引用;而 equals 預設情況下是引用比較,隻是很多類重新了 equals 方法,比如 String、Integer 等把它變成了值比較,是以一般情況下 equals 比較的是值是否相等。

  3、兩個對象的 hashCode() 相同,則 equals() 也一定為 true,對嗎?

  不對,兩個對象的 hashCode() 相同,equals() 不一定 true。

  代碼示例:

String str1 = "精彩";

String str2 = "筆記";

System. out. println(String. format("str1:%d | str2:%d", str1. hashCode(),str2. hashCode()));

System. out. println(str1. equals(str2));

  代碼解讀:很顯然“精彩”和“筆記”的 hashCode() 相同,然而 equals() 則為 false,因為在散清單中,hashCode() 相等即兩個鍵值對的哈希值相等,然而哈希值相等,并不一定能得出鍵值對相等。

  4、final 在 Java 中有什麼作用?

  final 修飾的類叫最終類,該類不能被繼承。

  final 修飾的方法不能被重寫。

  final 修飾的變量叫常量,常量必須初始化,初始化之後值就不能被修改。

  5、Java 中的 Math. round(-1. 5) 等于多少?

  等于 -1。round()是四舍五入,注意負數5是舍的,例如:Math.round(1.5)值是2,Math.round(-1.5)值是-1。

  6、String 屬于基礎的資料類型嗎?

  String 不屬于基礎類型,基礎類型有 8 種:byte、boolean、char、short、int、float、long、double,而 String 屬于對象。

  7、Java 中操作字元串都有哪些類?它們之間有什麼差別?

  操作字元串的類有:String、StringBuffer、StringBuilder。

  三者差別:

  StringBuffer和StringBuilder都繼承自抽象類AbstractStringBuilder。

  String 聲明的是不可變的對象,每次操作都會生成新的 String 對象,然後将指針指向新的 String 對象,而 StringBuffer、StringBuilder 存儲資料的字元數組沒有被final修飾,說明值可以改變,抽象類AbstractStringBuilder内部都提供了一個自動擴容機制,當發現長度不夠的時候(初始預設長度是16),會自動進行擴容工作,擴充為原數組長度的2倍加2,建立一個新的數組,并将數組的資料複制到新數組,是以對于拼接字元串效率要比String要高。

  線程安全性:StringBuffer由于很多方法都被 synchronized 修飾了是以線程安全,但是當多線程通路時,加鎖和釋放鎖的過程很平凡,是以效率相比StringBuilder要低。StringBuilder相反執行效率高,但是線程不安全。是以單線程環境下推薦使用 StringBuilder,多線程環境下推薦使用 StringBuffer。

  執行速度:StringBuilder > StringBuffer > String。

  8、String str="i"與 String str=new String(“i”)一樣嗎?

  不一樣,因為記憶體的配置設定方式不一樣。String str=“i"的方式,Java 虛拟機會将其配置設定到常量池中,如果常量池中有"i”,就傳回"i"的位址,如果沒有就建立"i",然後傳回"i"的位址;而 String str=new String(“i”) 則會被分到堆記憶體中新開辟一塊空間。

  9、如何将字元串反轉?

  使用 StringBuilder 或者 stringBuffer 的 reverse() 方法。

  示例代碼:

// StringBuffer reverse

StringBuffer stringBuffer = new StringBuffer();

stringBuffer. append("abcdefg");

System. out. println(stringBuffer. reverse()); // gfedcba

// StringBuilder reverse

StringBuilder stringBuilder = new StringBuilder();

stringBuilder. append("abcdefg");

System. out. println(stringBuilder. reverse()); // gfedcba

  10、String 類的常用方法都有那些?

  indexOf():傳回指定字元的索引。

  charAt():傳回指定索引處的字元。

  replace():字元串替換。

  trim():去除字元串兩端空白。

  split():分割字元串,傳回一個分割後的字元串數組。

  getBytes():傳回字元串的 byte 類型數組。

  length():傳回字元串長度。

  toLowerCase():将字元串轉成小寫字母。

  toUpperCase():将字元串轉成大寫字元。

  substring():截取字元串。

  equals():字元串比較。

  11、抽象類必須要有抽象方法嗎?

  不需要,抽象類不一定非要有抽象方法;但是包含一個抽象方法的類一定是抽象類。

  示例代碼:

abstract class Cat {

public static void sayHi() {

System. out. println("hi~");

}

}

  上面代碼,抽象類并沒有抽象方法但完全可以正常運作。

  12、普通類和抽象類有哪些差別?

  普通類不能包含抽象方法,抽象類可以包含抽象方法。

  抽象類是不能被執行個體化的,就是不能用new調出構造方法建立對象,普通類可以直接執行個體化。

  如果一個類繼承于抽象類,則該子類必須實作父類的抽象方法。如果子類沒有實作父類的抽象方法,則必須将子類也定義為abstract類。

  13、抽象類能使用 final 修飾嗎?

  不能,定義抽象類就是讓其他類繼承的,如果定義為 final 該類就不能被繼承,這樣彼此就會産生沖突,是以 final 不能修飾抽象類,如下圖所示,編輯器也會提示錯誤資訊:

最常見的208道Java最新面試題及答案(一) 

  14、接口和抽象類有什麼差別?

  實作:抽象類的子類使用 extends 來繼承;接口必須使用 implements 來實作接口。

  構造函數:抽象類可以有構造函數;接口不能有。

  實作數量:類可以實作很多個接口;但隻能繼承一個抽象類【java隻支援單繼承】。

  通路修飾符:接口中的方法預設使用 public 修飾;抽象類中的抽象方法可以使用Public和Protected修飾,如果抽象方法修飾符為Private,則報錯:The abstract method 方法名 in type Test can only set a visibility modifier, one of public or protected。

  15、Java 中 IO 流分為幾種?

  按功能來分:輸入流(input)、輸出流(output)。

  按類型來分:位元組流和字元流。

  位元組流和字元流的差別是:位元組流按 8 位傳輸以位元組為機關輸入輸出資料,字元流按 16 位傳輸以字元為機關輸入輸出資料。

  16、BIO、NIO、AIO 有什麼差別?

  BIO:Block IO 同步阻塞式 IO,就是我們平常使用的傳統 IO,它的特點是模式簡單使用友善,并發處理能力低。

  NIO:New IO 同步非阻塞 IO,是傳統 IO 的更新,用戶端和伺服器端通過 Channel(通道)通訊,實作了多路複用。

  AIO:Asynchronous IO 是 NIO 的更新,也叫 NIO2,實作了異步非堵塞 IO ,異步 IO 的操作基于事件和回調機制。

  17、Files的常用方法都有哪些?

  Files. exists():檢測檔案路徑是否存在。

  Files. createFile():建立檔案。

  Files. createDirectory():建立檔案夾。

  Files. delete():删除一個檔案或目錄。

  Files. copy():複制檔案。

  Files. move():移動檔案。

  Files. size():檢視檔案個數。

  Files. read():讀取檔案。

  Files. write():寫入檔案。

 二、java最新面試題及答案:Java 容器子產品

  18、Java 容器都有哪些?

  Java 容器分為 Collection 和 Map 兩大類,其下又有很多子類,如下所示:

  Collection

  List

  ArrayList

  LinkedList

  Vector

  Stack

  Set

  HashSet

  LinkedHashSet

  TreeSet

  Map

  HashMap

  LinkedHashMap

  TreeMap

  ConcurrentHashMap

  Hashtable

  19、Collection 和 Collections 有什麼差別?

  Collection 是一個集合接口,它提供了對集合對象進行基本操作的通用接口方法,所有集合都是它的子類,比如 List、Set 等。

  Collections 是一個包裝類,包含了很多靜态方法,不能被執行個體化,就像一個工具類,比如提供的排序方法:Collections. sort(list)。

  20、List、Set、Map 之間的差別是什麼?

  List、Set、Map 的差別主要展現在兩個方面:元素是否有序、是否允許元素重複。

  三者之間的差別,如下表:

最常見的208道Java最新面試題及答案(一) 

  21、HashMap 和 Hashtable 有什麼差別?

  HashMap是繼承自AbstractMap類,而HashTable是繼承自Dictionary類。不過它們都實作了同時實作了map、Cloneable(可複制)、Serializable(可序列化)這三個接口。

  Hashtable比HashMap多提供了elments() 和contains() 兩個方法。

  HashMap的key-value支援key-value,null-null,key-null,null-value四種。而Hashtable隻支援key-value一種(即key和value都不為null這種形式)。既然HashMap支援帶有null的形式,那麼在HashMap中不能由get()方法來判斷HashMap中是否存在某個鍵, 而應該用containsKey()方法來判斷,因為使用get的時候,當傳回null時,你無法判斷到底是不存在這個key,還是這個key就是null,還是key存在但value是null。

  線程安全性不同:HashMap的方法都沒有使用synchronized關鍵字修飾,都是非線程安全的,而Hashtable的方法幾乎都是被synchronized關鍵字修飾的。但是,當我們需要HashMap是線程安全的時,怎麼辦呢?我們可以通過Collections.synchronizedMap(hashMap)來進行處理,亦或者我們使用線程安全的ConcurrentHashMap。ConcurrentHashMap雖然也是線程安全的,但是它的效率比Hashtable要高好多倍。因為ConcurrentHashMap使用了分段鎖,并不對整個資料進行鎖定。

  初始容量大小和每次擴充容量大小的不同:Hashtable預設的初始大小為11,之後每次擴充,容量變為原來的2n+1。HashMap預設的初始化大小為16。之後每次擴充,容量變為原來的2倍。

  計算hash值的方法不同:為了得到元素的位置,首先需要根據元素的 KEY計算出一個hash值,然後再用這個hash值來計算得到最終的位置。Hashtable直接使用對象的hashCode。hashCode是JDK根據對象的位址或者字元串或者數字算出來的int類型的數值。然後再使用除留餘數發來獲得最終的位置。

  22、如何決定使用 HashMap 還是 TreeMap?

  對于在 Map 中插入、删除、定位一個元素這類操作,HashMap 是最好的選擇,因為相對而言 HashMap 的插入會更快,但如果你要對一個 key 集合進行有序的周遊,那 TreeMap 是更好的選擇。

  23、說一下 HashMap 的實作原理?

  HashMap 基于 Hash 算法實作的,我們通過 put(key,value)存儲,get(key)來擷取。當傳入 key 時,HashMap 會根據 key. hashCode() 計算出 hash 值,根據 hash 值将 value 儲存在 bucket 裡。當計算出的 hash 值相同時,我們稱之為 hash 沖突,HashMap 的做法是用連結清單和紅黑樹存儲相同 hash 值的 value。當 hash 沖突的個數比較少時,使用連結清單否則使用紅黑樹。

  24、說一下 HashSet 的實作原理?

  HashSet 是基于 HashMap 實作的,HashSet 底層使用 HashMap 來儲存所有元素,是以 HashSet 的實作比較簡單,相關 HashSet 的操作,基本上都是直接調用底層 HashMap 的相關方法來完成,HashSet 不允許重複的值。

  25、ArrayList 和 LinkedList 的差別是什麼?

  資料結構實作:ArrayList 是動态數組的資料結構實作,而 LinkedList 是雙向連結清單的資料結構實作。

  随機通路效率:ArrayList 比 LinkedList 在随機通路的時候效率要高,因為 LinkedList 是線性的資料存儲方式,是以需要移動指針從前往後依次查找。

  增加和删除效率:在非首尾的增加和删除操作,LinkedList 要比 ArrayList 效率要高,因為 ArrayList 增删操作要影響數組内的其他資料的下标。

  綜合來說,在需要頻繁讀取集合中的元素時,更推薦使用 ArrayList,而在插入和删除操作較多時,更推薦使用 LinkedList。

  26、如何實作數組和 List 之間的轉換?

  數組轉 List:使用 Arrays. asList(array) 進行轉換。

  List 轉數組:使用 List 自帶的 toArray() 方法。

  代碼示例:

// list to array

Listlist = new ArrayList();

list. add;

list. add;

list. toArray();

// array to list

String[] array = new String[];

Arrays. asList(array);

  27、ArrayList 和 Vector 的差別是什麼?

  線程安全:Vector 使用了 Synchronized 來實作線程同步,是線程安全的,而 ArrayList 是非線程安全的。

  性能:ArrayList 在性能方面要優于 Vector。

  擴容:ArrayList 和 Vector 都會根據實際的需要動态的調整容量,隻不過在 Vector 擴容每次會增加 1 倍,而 ArrayList 隻會增加 50%。

  28、Array 和 ArrayList 有何差別?

  Array 可以存儲基本資料類型和對象,ArrayList 隻能存儲對象。

  Array 是指定固定大小的,而 ArrayList 大小是自動擴充的。

  Array 内置方法沒有 ArrayList 多,比如 addAll、removeAll、iteration 等方法隻有 ArrayList 有。

  29、在 Queue 中 poll()和 remove()有什麼差別?

  相同點:都是傳回第一個元素,并在隊列中删除傳回的對象。

  不同點:如果沒有元素 remove()會直接抛出NoSuchElementException 異常,而 poll()會傳回 null。

  代碼示例:

Queuequeue = new LinkedList();

queue. offer("string"); // add

System. out. println(queue. poll());

System. out. println(queue. remove());

System. out. println(queue. size());

  30、哪些集合類是線程安全的?

  Vector、Hashtable、Stack 都是線程安全的,而像 HashMap 則是非線程安全的,不過在 JDK 1.5 之後随着 Java. util. concurrent 并發包的出現,它們也有了自己對應的線程安全類,比如 HashMap 對應的線程安全類就是 ConcurrentHashMap。

繼續閱讀