1. 程式人生 > >精心整理的 51個 JAVA SE 面試題

精心整理的 51個 JAVA SE 面試題

可以註冊賬戶,購買一些內容不錯的付費課程喲~

示例 1 : 面向物件的特徵有哪些方面?

封裝:最常見的是把屬性私有化封裝在一個類裡面,只能通過方法去訪問 繼承:子類繼承父類,從而繼承了父類的方法和屬性 抽象:比如一個英雄類,抽象出了name,hp這些屬性,使得開發過程中更加易於理解 多型:多型分操作符的多型和類的多型。 類的多型指父類引用指向子類物件,並且有繼承,有重寫。

示例 2 : String是最基本的資料型別嗎?

String是類型別,不是基本型別。 基本型別 有八種,這八種基本型別分別是: 整型 (4種) 字元型 (1種) 浮點型 (2種) 布林型(1種)

示例 3 : int 和 Integer 有什麼區別?

int 是基本型別32位長度的整數

Integer 是類型別,是int的封裝類

int和Integer之間可以通過自動裝箱 自動拆箱 互相轉換

示例 4 : String 和StringBuffer的區別?

String是immutable的,其內容一旦建立好之後,就不可以發生改變。

StringBuffer 是可以變長的,內容也可以發生改變;改變的原理是StringBuffer內部採用了字元陣列存放資料,在需要增加長度的時候,建立新的陣列,並且把原來的資料複製到新的陣列這樣的辦法來實現。

示例 5 : 執行時異常與一般異常有何異同?

執行時異常 又叫做非可查異常,在編譯過程中,不要求必須進行顯示捕捉

一般異常又叫做可查異常,在編譯過程中,必須進行處理,要麼捕捉,要麼通過throws 丟擲去.

示例 6 : 說出ArrayList,Vector, LinkedList的儲存效能和特性。

先說ArrayList和Vector 兩者都繼承了抽象類AbstractList,但是Vector是執行緒安全的,而ArrayList是非執行緒安全的

再說ArrayList和LinkedList的區別 ArrayList 是陣列結構,所以定位很快,但是插入和刪除很慢 LinkedList 是雙向連結串列結構,所以插入和刪除很快,但是定位很慢

示例 7 : Collection 和 Collections的區別

首先不要說成了一個是單數,一個是複數。。。 Collection是介面,是List和Set的父介面 Collections是工具類,提供了排序,混淆等等很多實用方法

示例 8 : &和&&的區別

& 有兩個作用,分別是 位與 和 邏輯與 && 就是邏輯與 作為邏輯與, &&& 分別表示 長路與 和 短路與 長路與的兩側,都會被運算 短路與 只要第一個是false,第二個就不進行運算了

示例 9 : HashMap和Hashtable的區別

HashMap和Hashtable都實現了Map介面,都是鍵值對儲存資料的方式

區別1: HashMap可以存放 null Hashtable不能存放null

區別2: HashMap不是執行緒安全的類 Hashtable是執行緒安全的類

示例 10 : final, finally, finalize的區別

final final修飾類,方法,基本型別變數,引用的時候分別有不同的意思 修飾類 表示該類不能被繼承 修飾方法 表示該方法不能被重寫 修飾基本型別變數 表示該變數只能被賦值一次 修飾引用 表示該引用只有一次指向物件的機會

finally finally 是用於異常處理的場面,無論是否有異常丟擲,都會執行

finalize finalize是Object的方法,所有類都繼承了該方法。 當一個物件滿足垃圾回收的條件,並且被回收的時候,其finalize()方法就會被呼叫

示例 11 : Overload和Override的區別,即過載和重寫的區別。 Overloaded的方法是否可以改變返回值的型別?

Overload是方法過載的意思,指的是在同一個類裡面,方法名一樣,但是引數不一樣

Override是方法重寫的意思,指的是子類繼承了父類的某個方法後,重新又寫了一遍

Overloaded的方法是否可以改變返回值的型別? 可以,過載其實本質上就是完全不同的方法,只是恰好取了相同的名字

示例 12 : Error和Exception有什麼區別?

Error和Exception都實現了Throwable介面

Error指的是JVM層面的錯誤,比如記憶體不足OutOfMemoryError

Exception 指的是程式碼邏輯的異常,比如下標越界OutOfIndexException

示例 13 : abstract class和interface有什麼區別?

abstract class 抽象類和interface介面的區別

使用方式: 抽象類只能夠通過繼承被使用 介面必須通過實現被使用

實現方法: 抽象類不僅可以提供抽象方法,也可以提供實現方法 介面只能提供抽象方法,不能提供實現方法。 但是在JAVA8版本開始,介面可以提供實現方法了,前提是要在方法前加一個default修飾符

示例 14 : heap和stack有什麼區別?

heap: 堆 stack: 棧 (在一些書籍裡,會被翻譯為堆疊,實際上指的就是單純的這個棧)

存放的內容不一樣: heap: 是存放物件的 stack: 是存放基本型別(int, float, boolean 等等)、引用(物件地址)、方法呼叫

存取方式不一樣: heap: 是自動增加大小的,所以不需要指定大小,但是存取相對較慢 stack: 是固定大小的,並且是FILO 先入後出的順序,並且存取速度比較快

示例 15 : GC是什麼? 為什麼要有GC?

GC是Garbage Collection的縮寫,即垃圾回收

這裡所謂的垃圾,指的是那些不再被使用的物件,JVM的垃圾回收機制使得開發人員從無聊、容易犯錯的手動釋放記憶體資源的過程中解放出來。

開發人員可以更加專注的進行業務功能的開發,而資源回收的工作交由更加專業的垃圾回收機制自動完成。

示例 16 : short s1 = 1; s1 = s1 + 1;有什麼錯?

short s1 = 1; 這一句沒有錯誤,編譯器會自動把1這個整數處理為short.

s1 = s1 + 1; 右側的表示式會返回一個Int型別的整數,再把這個int型別的整數賦給short型別的s1的時候,就會出現強制轉換錯誤

示例 17 : Math.round(11.5)等於多少? Math.round(-11.5)等於多少?

Math.round 的意思是 +0.5 之後向下取整數 所以 Math.round(11.5) 即 11.5+0.5 = 12 Math.round(-11.5) 即 -11.5+0.5 = -11

示例 18 : String s = new String(“xyz”);建立了幾個String Object?

String s = new String(“xyz”); 首先構造方法 new String(“xyz”); 中的"xyz" 這本身就是一個字串物件 然後 new 關鍵字一定會建立一個物件 所以總共建立了兩個String物件

示例 19 : Java有沒有goto?

goto 是關鍵字,但是是保留字,並不具備功能性

示例 20 : 介面是否可繼承介面? 抽象類是否可實現(implements)介面? 抽象類是否可繼承實體類(concrete class)?

介面是否可繼承介面? 可以,比如List 就繼承了介面Collection

抽象類是否可實現(implements)介面? 可以,比如 MouseAdapter滑鼠監聽介面卡 是一個抽象類,並且實現了MouseListener介面

抽象類是否可繼承實體類(concrete class)? 可以,所有抽象類,都繼承了Object

示例 21 : List, Set, Map是否繼承自Collection介面?

List 和 Set 繼承了Collection介面

但是Map和Collection之間沒有繼承關係,因為一個是鍵值對容器,一個是單值容器,無法相容 在這裡插入圖片描述

示例 22 : abstract的method是否可同時是static,是否可同時是synchronized?

abstract的method是否可同時是static,是否可同時是synchronized?

都不可以

示例 23 : 陣列有沒有length()這個方法? String有沒有length()這個方法?

陣列獲取長度的手段是 .length 屬性 String獲取長度的手段是 length()方法 集合獲取長度的手段是 size()方法 檔案獲取長度的手段是 length()方法

示例 24 : Set裡的元素是不能重複的,那麼用什麼方法來區分重複與否呢?

以HashSet為例,判斷重複的邏輯是:

  1. 首先看hashcode是否相同,如果不同,就是不重複的
  2. 如果hashcode一樣,再比較equals,如果不同,就是不重複的,否則就是重複的。

示例 25 : 構造器Constructor是否可被override?是否可以繼承String類?

子類不能繼承父類的構造方法,所以就不存在重寫父類的構造方法。 注: super() 表示子類呼叫父類的構造方法,這不能被叫做繼承父類的構造方法

String是final修飾的,所以不能夠被繼承

示例 26 : swtich是否能作用在byte上,是否能作用在long上,是否能作用在String上?

switch可以作用在 byte,short,int String,Enum(列舉) 上,但是不能作用在long上面

注:注:switch作用在String上從JDK1.7開始支援,實質是編譯時將字串替換為了其對應的hash值

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

try裡的return 和 finally裡的return 都會執行,但是當前方法只會採納finally中return的值

示例 28 : 兩個物件值相同(x.equals(y) == true),但卻可有不同的hash code,這句話對不對?

因為hashCode()方法和equals()方法都可以通過自定義類重寫,是可以做到equals相同,但是hashCode不同的

但是,在Object類的equals()方法中有這麼一段話

  • Note that it is generally necessary to override the {@code hashCode}
  • method whenever this method is overridden, so as to maintain the
  • general contract for the {@code hashCode} method, which states
  • that equal objects must have equal hash codes.

翻譯如下:

通常來講,在重寫這個方法的時候,也需要對hashCode方法進行重寫, 以此來保證這兩個方法的一致性——當equals返回true的時候,這兩個物件一定有相同的hashcode.

兩個物件值相同(x.equals(y) == true),但卻可有不同的hash code,這句話對不對? 所以這個題的答案應該是否定的,但是得搞清楚裡面的原委

在這裡插入圖片描述

示例 29 : 垃圾回收的優點和原理。並考慮2種回收機制。

與C語言開發人員需要手動進行記憶體資源的釋放不同,Java提供垃圾回收機制,自動進行GC,將開發人員從容易犯錯的記憶體資源管理中解放出來。

原理:當某個一個物件,沒有任何引用指向它的時候,那麼它就滿足垃圾回收的條件,在適當的時候,JVM虛擬機器進行GC將其回收,釋放空間,以供後續再利用。

兩種常見的回收機制:

  1. 定時回收 每隔30分鐘進行一次回收,這種機制的弊端是如果垃圾產生的比較快,有可能30分鐘之內垃圾已經把記憶體佔用光了,導致效能變慢

  2. 當垃圾佔到某個百分比的時候,進行回收 比如,當垃圾佔到70%的時候,進行回收。 這種機制的弊端是,如果垃圾產生的頻率很快,那麼JVM就必須高頻率的進行垃圾回收。 而在垃圾回收的過程中, JVM會停頓下來,只做垃圾回收,而影響業務功能的正常執行。

一般說來 JVM會採用兩種機制結合的方式進行垃圾回收。

示例 30 : 你所知道的集合類都有哪些?主要方法?

常見的集合 ArrayList,LinkedList,HashSet,HashMap,TreeSet 等等

常見方法: size() add() remove() 等等

示例 31 : char型變數中能不能存貯一箇中文漢字?為什麼?

char是16位的,佔兩個位元組 漢字通常使用GBK或者UNICODE編碼,也是使用兩個位元組 所以可以存放漢字

示例 32 : 解析XML文件有哪幾種方式?

主要是兩種,SAX和DOM SAX 就是逐行讀取,直到找到目標資料為止

DOM 是先全文件載入,然後讀取

示例 33 : 關鍵字:throws,throw,try,catch,finally分別代表什麼意義?在try塊中可以丟擲異常嗎?

throws 用在方法宣告上面,表示該方法有可能丟擲某個異常 throw 丟擲一個指定的異常 try catchtry 中有可能會丟擲某個異常,一旦某個異常丟擲後,就會在catch 中進行捕捉,他倆一般說來都是成對出現的。 finally: 表示無論是否捕捉住異常,都會執行

示例 34 : 一個".java"原始檔中是否可以包括多個類(不是內部類)?有什麼限制?

可以包括多個類,但是隻能出現一個public修飾的類,但是可以出現多個非public修飾的類。

示例 35 : java中有幾種型別的流?

Java中所有的流都是基於位元組流,所以最基本的流是 輸入輸出位元組流 InputStream OutputStream

在位元組流的基礎上,封裝了字元流 Reader Writer

進一步,又封裝了快取流 BufferedReader PrintWriter

以及資料流 DataInputStream DataOutputStream

物件流 ObjectInputStream ObjectOutputStream

以及一些其他的奇奇怪怪的流 ~~~

示例 36 : java中會存在記憶體洩漏嗎,請簡單描述。

因為Java是自動進行垃圾回收管理的,所以不存在 C語言中同等概念的記憶體洩漏,但是存在Java特色的記憶體洩漏

當某些物件不被使用,但是又有非直接引用指向的時候,那麼就不滿足垃圾回收的條件,而形成記憶體洩漏。

比如程式碼中的例子,每個Object建立的時候,有一個引用o指向,接著就被放進了集合al中。 下一個Object建立的時候,上一個Object就沒有引用指向了。

這些Object都沒有引用指向,但是卻放在ArrayList中,而這個Arraylist忘記了回收,那麼裡面的所有物件,都會一直存活下去,雖然不再被使用了。

package j2se;

import java.util.ArrayList;
 
public class MemoryLeak {
    static ArrayList<Object> al = new ArrayList<Object>();
 
    public static void main(String[] args) {
 
        for (int i = 0; i < 100; i++) {
            Object o = new Object();
            al.add(o);
        }
    }
}

示例 37 : java中實現多型的機制是什麼?

類的多型的條件:

  1. 父類(介面)引用指向子類物件
  2. 方法有重寫

示例 38 : 靜態變數和例項變數的區別?

靜態變數 直接通過類就可以訪問,無需例項

例項變數 比如同構類的某個具體例項,才可以訪問

示例 39 : 什麼是java序列化,如何實現java序列化?

序列化指的是把一個Java物件,通過某種介質進行傳輸,比如Socket輸入輸出流,或者儲存在一個檔案裡

實現java序列化的手段是讓該類實現介面 Serializable,這個介面是一個標識性介面,沒有任何方法,僅僅用於表示該類可以序列化。

示例 40 : 是否可以從一個static方法內部發出對非static方法的呼叫?

不行,因為非static方法需要一個具體的例項才可以呼叫,而呼叫 static方法的時候,不一定存在一個例項

示例 41 : 在JAVA中,如何跳出當前的多重巢狀迴圈?

在外部迴圈的前一行,加上標籤 在break的時候使用該標籤 即能達到結束多重巢狀迴圈的效果

public class HelloWorld {
    public static void main(String[] args) {
           
        //列印單數    
        outloop: //outloop這個標示是可以自定義的比如outloop1,ol2,out5
        for (int i = 0; i < 10; i++) {
              
            for (int j = 0; j < 10; j++) {
                System.out.println(i+":"+j);
                if(0==j%2) 
                    break outloop; //如果是雙數,結束外部迴圈
            }
        }
    }
}

示例 42 : List、Map、Set三個介面,存取元素時,各有什麼特點?

List 是有順序的,並且可以重複 Set 是無序的,不可以重複 (參考如何判斷Set中的物件是否重複) Map 儲存資料的方式是鍵值對

示例 43 : Anonymous Inner Class (匿名內部類) 是否可以extends(繼承)其它類,是否可以 implements(實現)interface(介面)?

匿名內部類本質上就是在繼承其他類,實現其他介面

如例: 匿名類1,就是繼承了Thread 匿名類2 ,就是實現了Runnable介面

package j2se;
 
public class HelloWorld {
    public static void main(String[] args) {
 
        // 匿名類1
        new Thread() {
            public void run() {
 					// do something
            }
        };
 
        // 匿名類2
        new Runnable() {
            public void run() {
 					// do something
            }
        };
    }
}

示例 44 : 內部類可以引用外部類的成員嗎?有沒有什麼限制?

可以使用 如果是非靜態內部類,可是使用外部類的所有成員 如果是靜態內部類,只能使用外部類的靜態成員

示例 45 : 多執行緒有幾種實現方法,都是什麼?

通常來講,Java 建立一個執行緒有三種方式

  1. 繼承一個Thread類
  2. 實現Runnable介面

示例 46 : sleep() 和 wait() 有什麼區別?

首先sleep和wait之間沒有任何關係

sleep 是Thread類的方法,指的是當前執行緒暫停。

wait 是Object類的方法, 指的佔用當前物件的執行緒臨時釋放對當前物件的佔用,以使得其他執行緒有機會佔用當前物件。 所以呼叫wait方法一定是在synchronized 中進行

示例 47 : 說出資料連線池的工作機制是什麼?

資料庫連線池原理: 因為建立連線和關閉連線的行為是非常耗時的,會顯著降低軟體的效能表現。解決辦法就是先建立n條資料庫連線Connection,迴圈使用,但是不進行關閉,這樣再執行SQL語句,就不需要額外建立連線了,直接使用現成的連線就可以了,從而節約了建立連線和關閉連線的時間開銷。

示例 48 : 簡述synchronized和java.util.concurrent.locks.Lock的異同 ?

  1. Lock是一個介面,而synchronized是Java中的關鍵字,synchronized是內建的語言實現,Lock是程式碼層面的實現。

  2. Lock可以選擇性的獲取鎖,如果一段時間獲取不到,可以放棄。synchronized不行,會一根筋一直獲取下去。 藉助Lock的這個特性,就能夠規避死鎖,synchronized必須通過謹慎和良好的設計,才能減少死鎖的發生。

  3. synchronized在發生異常和同步塊結束的時候,會自動釋放鎖。而Lock必須手動釋放, 所以如果忘記了釋放鎖,一樣會造成死鎖。

完整的Lock教程請檢視:Lock物件

示例 49 : Class.forName的作用?為什麼要用?

Class.forName常見的場景是在資料庫驅動初始化的時候呼叫。

Class.forName本身的意義是載入類到JVM中。 一旦一個類被載入到JVM中,它的靜態屬性就會被初始化,在初始化的過程中就會執行相關程式碼,從而達到"載入驅動的效果"

示例 50 : 當一個執行緒進入一個物件的一個synchronized方法後,其它執行緒是否可進入此物件的其它方法

這要看情況而定,如果該物件的其他方法也是有synchronized修飾的,那麼其他執行緒就會被擋在外面。否則其他執行緒就可以進入其他方法。

示例 51 : 給我五個你最常見到的runtime exception。

NullPointerException 空指標異常

ArithmeticException 算術異常,比如除數為零

ClassCastException 型別轉換異常

ConcurrentModificationException 同步修改異常,遍歷一個集合的時候,刪除集合的元素,就會丟擲該異常

IndexOutOfBoundsException 陣列下標越界異常

NegativeArraySizeException 為陣列分配的空間是負數異常