- 今日推薦
- 特別關注
java面試題整理「面試題java」
作者 | cxuan
責編 | 王曉曼
來源 | java建設者
Java 基礎篇
1、Java 有哪些特點?
并發性的:你可以在其中執行許多語句,而不必一次執行它;
面向對象的:基于類和面向對象的編程語言;
獨立性的:支持一次編寫,到處運行的獨立編程語言,即編譯后的代碼可以在支持 Java 的所有平臺上運行。
2、Java 的特性
Java 的特性有如下這幾點:
簡單,Java 會讓你的工作變得更加輕松,使你把關注點放在主要業務邏輯上,而不必關心指針、運算符重載、內存回收等與主要業務無關的功能。
便攜性,Java 是平臺無關性的,這意味著在一個平臺上編寫的任何應用程序都可以輕松移植到另一個平臺上。
安全性, 編譯后會將所有的代碼轉換為字節碼,人類無法讀取。它使開發無病毒,無篡改的系統/應用成為可能。
動態性,它具有適應不斷變化的環境的能力,它能夠支持動態內存分配,從而減少了內存浪費,提高了應用程序的性能。
分布式,Java 提供的功能有助于創建分布式應用。使用遠程方法調用(RMI),程序可以通過網絡調用另一個程序的方法并獲取輸出。您可以通過從互聯網上的任何計算機上調用方法來訪問文件。這是革命性的一個特點,對于當今的互聯網來說太重要了。
健壯性,Java 有強大的內存管理功能,在編譯和運行時檢查代碼,它有助于消除錯誤。
高性能,Java 最黑的科技就是字節碼編程,Java 代碼編譯成的字節碼可以輕松轉換為本地機器代碼。通過 JIT 即時編譯器來實現高性能。
解釋性,Java 被編譯成字節碼,由 Java 運行時環境解釋。
多線程性,Java支持多個執行線程(也稱為輕量級進程),包括一組同步原語。這使得使用線程編程更加容易,Java 通過管程模型來實現線程安全性。
3、描述一下值傳遞和引用傳遞的區別?
簡單理解的話就是:
值傳遞是指在調用函數時將實際參數復制一份到函數中,這樣的話如果函數對其傳遞過來的形式參數進行修改,將不會影響到實際參數
引用傳遞是指在調用函數時將對象的地址直接傳遞到函數中,如果在對形式參數進行修改,將影響到實際參數的值。
4、== 和 equals 區別是什么
== 是 Java 中一種操作符,它有兩種比較方式。
對于基本數據類型來說, == 判斷的是兩邊的值是否相等;
public class DoubleCompareAndEquals {
Person person1 = new Person(24,"boy");
Person person2 = new Person(24,"girl");
int c = 10;
private void doubleCompare{
int a = 10;
int b = 10;
System.out.println(a == b);
System.out.println(a == c);
System.out.println(person1.getId == person2.getId);
}
}
對于引用類型來說, == 判斷的是兩邊的引用是否相等,也就是判斷兩個對象是否指向了同一塊內存區域。
private void equals{
System.out.println(person1.getName.equals(person2.getName));
}
equals 是 Java 中所有對象的父類,即 Object 類定義的一個方法。它只能比較對象,它表示的是引用雙方的值是否相等。所以記住,并不是說 == 比較的就是引用是否相等,equals 比較的就是值,這需要區分來說的。
equals 用作對象之間的比較具有如下特性:
自反性:對于任何非空引用 x 來說,x.equals(x) 應該返回 true。
對稱性:對于任何非空引用 x 和 y 來說,若x.equals(y)為 true,則y.equals(x)也為 true。
傳遞性:對于任何非空引用的值來說,有三個值,x、y 和 z,如果x.equals(y) 返回true,y.equals(z) 返回true,那么x.equals(z) 也應該返回true。
一致性:對于任何非空引用 x 和 y 來說,如果 x.equals(y) 相等的話,那么它們必須始終相等。
非空性:對于任何非空引用的值 x 來說,x.equals 必須返回 false。
5、String 中的 equals 是如何重寫的
String 代表的是 Java 中的字符串,String 類比較特殊,它整個類都是被 final 修飾的,也就是說,String 不能被任何類繼承,任何 修改 String 字符串的方法都是創建了一個新的字符串。
equals 方法是 Object 類定義的方法,Object 是所有類的父類,當然也包括 String,String 重寫了 equals 方法,下面我們來看看是怎么重寫的:
首先會判斷要比較的兩個字符串它們的引用是否相等。如果引用相等的話,直接返回 true ,不相等的話繼續下面的判斷;
然后再判斷被比較的對象是否是 String 的實例,如果不是的話直接返回 false,如果是的話,再比較兩個字符串的長度是否相等,如果長度不想等的話也就沒有比較的必要了;長度如果相同,會比較字符串中的每個 字符 是否相等,一旦有一個字符不相等,就會直接返回 false。
下面是它的流程圖:
這里再提示一下,你可能有疑惑什么時候是:
if (this == anObject) {
return true;
}
這個判斷語句如何才能返回 true?因為都是字符串啊,字符串比較的不都是堆空間嗎,猛然一看發現好像永遠也不會走,但是你忘記了 String.intern 方法,它表示的概念在不同的 JDK 版本有不同的區分。
在 JDK1.7 及以后調用 intern 方法是判斷運行時常量池中是否有指定的字符串,如果沒有的話,就把字符串添加到常量池中,并返回常量池中的對象。
驗證過程如下:
private void StringOverrideEquals{
String s1 = "aaa";
String s2 = "aa" new String("a");
String s3 = new String("aaa");
System.out.println(s1.intern.equals(s1));
System.out.println(s1.intern.equals(s2));
System.out.println(s3.intern.equals(s1));
}
首先 s1.intern.equals(s1) 這個無論如何都返回 true,因為 s1 字符串創建出來就已經在常量池中存在了。
然后第二條語句返回 false,因為 s1 返回的是常量池中的對象,而 s2 返回的是堆中的對象
第三條語句 s3.intern.equals(s1),返回 true ,因為 s3 對象雖然在堆中創建了一個對象,但是 s3 中的 "aaa" 返回的是常量池中的對象。
6、為什么重寫 equals 方法必須重寫 hashCode 方法
equals 方法和 hashCode 都是 Object 中定義的方法,它們經常被一起重寫。
equals 方法是用來比較對象大小是否相等的方法,hashcode 方法是用來判斷每個對象 hash 值的一種方法。如果只重寫 equals 方法而不重寫 hashcode 方法,很可能會造成兩個不同的對象,它們的 hashcode 也相等,造成沖突。比如:
String str1 = "通話";
String str2 = "重地";
它們兩個的 hashcode 相等,但是 equals 可不相等。
我們來看一下 hashCode 官方的定義:
總結起來就是:
如果在 Java 運行期間對同一個對象調用 hashCode 方法后,無論調用多少次,都應該返回相同的 hashCode,但是在不同的 Java 程序中,執行 hashCode 方法返回的值可能不一致;
如果兩個對象的 equals 相等,那么 hashCode 必須相同;
如果兩個對象 equals 不相等,那么 hashCode 也有可能相同,所以需要重寫 hashCode 方法,因為你不知道 hashCode 的底層構造(反正我是不知道,有大牛可以傳授傳授),所以你需要重寫 hashCode 方法,來為不同的對象生成不同的 hashCode 值,這樣能夠提高不同對象的訪問速度;
hashCode 通常是將地址轉換為整數來實現的。
7、String s1 = new String("abc") 在內存中創建了幾個對象?
一個或者兩個,String s1 是聲明了一個 String 類型的 s1 變量,它不是對象。使用 new 關鍵字會在堆中創建一個對象,另外一個對象是 abc ,它會在常量池中創建,所以一共創建了兩個對象;如果 abc 在常量池中已經存在的話,那么就會創建一個對象。
8、String 為什么是不可變的、jdk 源碼中的 String 如何定義的、為什么這么設計?
首先了解一下什么是不可變對象,不可變對象就是一經創建后,其對象的內部狀態不能被修改,啥意思呢?也就是說不可變對象需要遵守下面幾條原則:
不可變對象的內部屬性都是 final 的;
不可變對象的內部屬性都是 private 的;
不可變對象不能提供任何可以修改內部狀態的方法、setter 方法也不行;
不可變對象不能被繼承和擴展。
與其說問 String 為什么是不可變的,不如說如何把 String 設計成不可變的。
String 類是一種對象,它是獨立于 Java 基本數據類型而存在的,String 你可以把它理解為字符串的集合,String 被設計為 final 的,表示 String 對象一經創建后,它的值就不能再被修改,任何對 String 值進行修改的方法就是重新創建一個字符串。String 對象創建后會存在于運行時常量池中,運行時常量池是屬于方法區的一部分,JDK1.7 后把它移到了堆中。
不可變對象不是真的不可變,可以通過反射來對其內部的屬性和值進行修改,不過一般我們不這樣做。
9、static 關鍵字是干什么用的?談談你的理解。
static 是 Java 中非常重要的關鍵字,static 表示的概念是靜態的,在 Java 中,static 主要用來:
修飾變量,static 修飾的變量稱為靜態變量、也稱為類變量,類變量屬于類所有,對于不同的類來說,static 變量只有一份,static 修飾的變量位于方法區中;static 修飾的變量能夠直接通過 類名.變量名 來進行訪問,不用通過實例化類再進行使用;
修飾方法,static 修飾的方法被稱為靜態方法,靜態方法能夠直接通過 類名.方法名 來使用,在靜態方法內部不能使用非靜態屬性和方法;
static 可以修飾代碼塊,主要分為兩種,一種直接定義在類中,使用 static{},這種被稱為靜態代碼塊,一種是在類中定義靜態內部類,使用 static class xxx 來進行定義;
static 可以用于靜態導包,通過使用 import static xxx 來實現,這種方式一般不推薦使用;
static 可以和單例模式一起使用,通過雙重檢查鎖來實現線程安全的單例模式。
10、final 關鍵字是干什么用的?談談你的理解。
final 是 Java 中的關鍵字,它表示的意思是不可變的,在 Java 中,final 主要用來:
修飾類,final 修飾的類不能被繼承,不能被繼承的意思就是不能使用 extends 來繼承被 final 修飾的類;
修飾變量,final 修飾的變量不能被改寫,不能被改寫的意思有兩種,對于基本數據類型來說,final 修飾的變量,其值不能被改變,final 修飾的對象,對象的引用不能被改變,但是對象內部的屬性可以被修改。final 修飾的變量在某種程度上起到了不可變的效果,所以,可以用來保護只讀數據,尤其是在并發編程中,因為明確的不能再為 final 變量進行賦值,有利于減少額外的同步開銷;
修飾方法,final 修飾的方法不能被重寫;
final 修飾符和 Java 程序性能優化沒有必然聯系。
11、抽象類和接口的區別是什么
抽象類和接口都是 Java 中的關鍵字,抽象類和接口中都允許進行方法的定義,而不用具體的方法實現。抽象類和接口都允許被繼承,它們廣泛的應用于 JDK 和框架的源碼中,來實現多態和不同的設計模式。
不同點在于:
抽象級別不同:類、抽象類、接口其實是三種不同的抽象級別,抽象程度依次是 接口 > 抽象類 > 類。在接口中,只允許進行方法的定義,不允許有方法的實現,抽象類中可以進行方法的定義和實現;而類中只允許進行方法的實現,我說的方法的定義是不允許在方法后面出現 {}
使用的關鍵字不同:類使用 class 來表示;抽象類使用 abstract class 來表示;接口使用 interface 來表示
變量:接口中定義的變量只能是公共的靜態常量,抽象類中的變量是普通變量。
12、重寫和重載的區別
在 Java 中,重寫和重載都是對同一方法的不同表現形式,下面我們針對重寫和重載做一下簡單的區分:
子父級關系不同,重寫是針對子級和父級的不同表現形式,而重載是在同一類中的不同表現形式;
概念不同,子類重寫父類的方法一般使用 @override 來表示;重寫后的方法其方法的聲明和參數類型、順序必須要與父類完全一致;重載是針對同一類中概念,它要求重載的方法必須滿足下面任何一個要求:方法參數的順序,參數的個數,參數的類型任意一個保持不同即可。
13、byte 的取值范圍是多少,怎么計算出來的
byte 的取值范圍是 -128 -> 127 之間,一共是 256 。一個 byte 類型在計算機中占據一個字節,那么就是 8 bit,所以最大就是 2^7 = 1111 1111。
Java 中用補碼來表示二進制數,補碼的最高位是符號位,最高位用 0 表示正數,最高位 1 表示負數,正數的補碼就是其本身,由于最高位是符號位,所以正數表示的就是 0111 1111 ,也就是 127。最大負數就是 1111 1111,這其中會涉及到兩個 0 ,一個 0 ,一個 -0 , 0 歸為正數,也就是 0 ,-0 歸為負數,也就是 -128,所以 byte 的范圍就是 -128 - 127。
14、HashMap 和 HashTable 的區別
相同點:
HashMap 和 HashTable 都是基于哈希表實現的,其內部每個元素都是 key-value 鍵值對,HashMap 和 HashTable 都實現了 Map、Cloneable、Serializable 接口。
不同點:
父類不同:HashMap 繼承了 AbstractMap 類,而 HashTable 繼承了 Dictionary 類:
空值不同:HashMap 允許空的 key 和 value 值,HashTable 不允許空的 key 和 value 值。HashMap 會把 key 當做普通的 key 對待。不允許 key 重復。
線程安全性:HashMap 不是線程安全的,如果多個外部操作同時修改 HashMap 的數據結構比如 add 或者是 delete,必須進行同步操作,僅僅對 key 或者 value 的修改不是改變數據結構的操作。可以選擇構造線程安全的 Map 比如 Collections.synchronizedMap或者是 ConcurrentHashMap。而 HashTable 本身就是線程安全的容器。
性能方面:雖然 HashMap 和 HashTable 都是基于單鏈表的,但是 HashMap 進行 put 或者 get
相關文章
- 基金名稱后面的ABC是什么意思「基金abc分別代表」
- 東莞通拓跨境電商公司「東莞通拓跨境電商園」
- 關于杭州西湖的故事「杭州西湖人文故事」
- 伊朗貨款怎么收「公司有很多私賬要付怎么處理」
- 關于跨境電商出口箱子的封箱「跨境海外倉有哪些」
- 最有名的越野拉力賽事「亞洲最大的沙漠水庫」
- 華為花瓣app「華為花瓣商店真的能中手機嗎」
- 大雪養生菜「適合天氣熱吃的家常菜」
- 濮陽公主家水果加盟「濮陽金龍街」
- 自閉癥電視劇《良醫》「美劇醫生」
- 為什么這么多人在鼓吹亞馬遜跨境電商「跨境電商流程」
- 支付系統設計與架構「高并發支付系統架構設計」
- 宜昌跨境電商產業園上半年正式開園嗎「宜昌綜合保稅區」
- 美國商標轉讓法規「商標注冊的國際分類是什么意思」
- 在tiktok可以掛的跨境電商平臺有哪些「傲基跨境電商平臺」
- 中小學師資隊伍建設的問題及對策「學校師資隊伍建設」
- 兩個人合伙做跨境電商「和朋友合伙做電商」
- 日照開啟跨境電商出口監管新模式了嗎「日照省級跨境電商綜合實驗區」