您好,歡迎來到賦能網(wǎng)!

Java SE相關(guān)面試題匯總

賦能網(wǎng) 2023-06-11 147

1 你是怎樣理解面向?qū)ο蟮?/strong>

面向?qū)ο笫抢镁幊陶Z言對現(xiàn)實事物進行抽象。面向?qū)ο缶哂幸韵滤拇筇卣鳎?/p>

(1)繼承:繼承是從已有類得到繼承信息創(chuàng)建新類的過程

(2)封裝:通常認為封裝是把數(shù)據(jù)和操作數(shù)據(jù)的方法綁定起來,對數(shù)據(jù)的訪問只能通過已定義的接口。

(3)多態(tài)性:多態(tài)性是指允許不同子類型的對象對同一消息作出不同的響應(yīng)。

(4)抽象:抽象是將一類對象的共同特征總結(jié)出來構(gòu)造類的過程,包括數(shù)據(jù)抽象和行為抽象兩方面。

2 int和Integer有什么區(qū)別,以及以下程序結(jié)果

(1)Integer是int的包裝類,int則是java的一種基本數(shù)據(jù)類型

(2)Integer變量必須實例化后才能使用,而int變量不需要

(3)Integer實際是對象的引用,當new一個Integer時,實際上是生成一個指針指向此對象;而int則是直接存儲數(shù)據(jù)值

(4)Integer的默認值是null,int的默認值是0

 package com.atguigu.interview.chapter03;

public class Test01 {

public static void main(String[] args) {

Integer a = 127;

Integer b = 127;

Integer c = 128;

Integer d = 128;

System.out.println(a == b); //true

System.out.println(c == d); //false

}

}

3 ==和Equals區(qū)別

(1) ==

如果比較的是基本數(shù)據(jù)類型,那么比較的是變量的值

如果比較的是引用數(shù)據(jù)類型,那么比較的是地址值(兩個對象是否指向同一塊內(nèi)存)

(2)equals

如果沒重寫equals方法比較的是兩個對象的地址值

如果重寫了equals方法后我們往往比較的是對象中的屬性的內(nèi)容

equals()方法最初在Object類中定義的,默認的實現(xiàn)就是使用==

4 談?wù)勀銓Ψ瓷涞睦斫?/strong>

(1)反射機制:

所謂的反射機制就是java語言在運行時擁有一項直觀的能力。通過這種能力可以徹底地了解自身的情況為下一步的動作做準備。

Java的反射機制的實現(xiàn)要借助于4個類:Class,Constructor,F(xiàn)ield,Method;

其中Class代表的是類對 象,Constructor-類的構(gòu)造器對象,F(xiàn)ield-類的屬性對象,Method-類的方法對象。通過這四個對象我們可以粗略地看到一個類的各個組 成部分。

(2)Java反射的作用:

在Java運行時環(huán)境中,對于任意一個類,可以知道這個類有哪些屬性和方法。對于任意一個對象,可以調(diào)用它的任意一個方法。這種動態(tài)獲取類的信息以及動態(tài)調(diào)用對象的方法的功能來自于Java 語言的反射(Reflection)機制。

(3)Java 反射機制提供功能

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

在運行時構(gòu)造任意一個類的對象。

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

在運行時調(diào)用任意一個對象的方法

5 ArrarList和linkedList區(qū)別

(1)ArrayList是實現(xiàn)了基于動態(tài)數(shù)組的數(shù)據(jù)結(jié)構(gòu),linkedList基于鏈表的數(shù)據(jù)結(jié)構(gòu)。

(2)對于隨機訪問get和set,ArrayList絕對優(yōu)于linkedList,因為linkedList要移動指針。

(3)對于插入和刪除操作add和remove,linkedList比較占優(yōu)勢,因為ArrayList每插入或刪除一條數(shù)據(jù),都要移動插入點或刪除點及之后的所有數(shù)據(jù)。

6 HashMap底層源碼,數(shù)據(jù)結(jié)構(gòu)

HashMap的底層結(jié)構(gòu)在jdk1.7中由數(shù)組+鏈表實現(xiàn),在jdk1.8中由數(shù)組+鏈表+紅黑樹實現(xiàn),以數(shù)組+鏈表的結(jié)構(gòu)為例。

JDK1.8之前put方法:

JDK1.8之后put方法:

Java SE相關(guān)面試題匯總

7 HashMap和Hashtable區(qū)別

(1)線程安全性不同

HashMap是線程不安全的,Hashtable是線程安全的,其中的方法是Synchronized的,在多線程并發(fā)的情況下,可以直接使用Hashtable,但是使用HashMap時必須自己增加同步處理。

(2)是否提供contains方法

HashMap只有containsValue和containsKey方法;Hashtable有contains、containsKey和containsValue三個方法,其中contains和containsValue方法功能相同。

(3)key和value是否允許null值

Hashtable中,key和value都不允許出現(xiàn)null值。HashMap中,null可以作為鍵,這樣的鍵只有一個;可以有一個或多個鍵所對應(yīng)的值為null。

(4)數(shù)組初始化和擴容機制

Hashtable在不指定容量的情況下的默認容量為11,而HashMap為16,Hashtable不要求底層數(shù)組的容量一定要為2的整數(shù)次冪,而HashMap則要求一定為2的整數(shù)次冪。

Hashtable擴容時,將容量變?yōu)樵瓉淼?倍加1,而HashMap擴容時,將容量變?yōu)樵瓉淼?倍。

3.8 TreeSet和HashSet區(qū)別

HashSet是采用hash表來實現(xiàn)的。其中的元素沒有按順序排列,add()、remove()以及contains()等方法都是復(fù)雜度為O(1)的方法。

TreeSet是采用樹結(jié)構(gòu)實現(xiàn)(紅黑樹算法)。元素是按順序進行排列,但是add()、remove()以及contains()等方法都是復(fù)雜度為O(log (n))的方法。它還提供了一些方法來處理排序的set,如first(), last(), headSet(), tailSet()等等。

9 StringBuffer和StringBuilder區(qū)別

(1)StringBuffer 與 StringBuilder 中的方法和功能完全是等價的,

(2)只是StringBuffer 中的方法大都采用了 synchronized 關(guān)鍵字進行修飾,因此是線程安全的,而 StringBuilder 沒有這個修飾,可以被認為是線程不安全的。

(3)在單線程程序下,StringBuilder效率更快,因為它不需要加鎖,不具備多線程安全而StringBuffer則每次都需要判斷鎖,效率相對更低

10 Final、Finally、Finalize

final:修飾符(關(guān)鍵字)有三種用法:修飾類、變量和方法。修飾類時,意味著它不能再派生出新的子類,即不能被繼承,因此它和abstract(abstract修飾的類通常都需要子類來繼承)在使用上可以理解為互斥的。修飾變量時,該變量使用中不被改變,必須在聲明時給定初值,在引用中只能讀取不可修改,即為常量。修飾方法時,也同樣只能使用,不能在子類中被重寫。

finally:通常放在try…catch的后面構(gòu)造最終執(zhí)行代碼塊,這就意味著程序無論正常執(zhí)行還是發(fā)生異常,這里的代碼只要JVM不關(guān)閉都能執(zhí)行,可以將釋放外部資源的代碼寫在finally塊中。

finalize:Object類中定義的方法,Java中允許使用finalize() 方法在垃圾收集器將對象從內(nèi)存中清除出去之前做必要的清理工作。這個方法是由垃圾收集器在銷毀對象時調(diào)用的,通過重寫finalize() 方法可以整理系統(tǒng)資源或者執(zhí)行其他清理工作。

11 什么是 java 序列化,如何實現(xiàn) java 序列化?

序列化就是一種用來處理對象流的機制,所謂對象流也就是將對象的內(nèi)容進行流化??梢詫α骰蟮膶ο筮M行讀寫操作,也可將流化后的對象傳輸于網(wǎng)絡(luò)之間。序列化是為了解決在對對象流進行讀寫操作時所引發(fā)的問題。

序 列 化 的 實 現(xiàn) : 將 需 要 被 序 列 化 的 類 實 現(xiàn) Serializable 接 口 , 該 接 口 沒 有 需 要 實 現(xiàn) 的 方 法 , implements Serializable 只是為了標注該對象是可被序列化的,然后使用一個輸出流(如:FileOutputStream)來構(gòu)造一個ObjectOutputStream(對象流)對象,接著,使用 ObjectOutputStream 對象的 writeObject(Object obj)方法就可以將參數(shù)為 obj 的對象寫出(即保存其狀態(tài)),要恢復(fù)的話則用輸入流。

12 Object中有哪些方法

(1)protected Object clone()—>創(chuàng)建并返回此對象的一個副本。
(2)boolean equals(Object obj)—>指示某個其他對象是否與此對象“相等”。
(3)protected void finalize()—>當垃圾回收器確定不存在對該對象的更多引用時,由對象的垃圾回收器調(diào)用此方法。
(4)Class<? extends Object> getClass()—>返回一個對象的運行時類。
(5)int hashCode()—>返回該對象的哈希碼值。
(6)void notify()—>喚醒在此對象監(jiān)視器上等待的單個線程。
(7)void notifyAll()—>喚醒在此對象監(jiān)視器上等待的所有線程。
(8)String toString()—>返回該對象的字符串表示。
(9)void wait()—>導(dǎo)致當前的線程等待,直到其他線程調(diào)用此對象的 notify() 方法或 notifyAll() 方法。
void wait(long timeout)—>導(dǎo)致當前的線程等待,直到其他線程調(diào)用此對象的 notify() 方法或 notifyAll()方法,或者超過指定的時間量。
void wait(long timeout, int nanos)—>導(dǎo)致當前的線程等待,直到其他線程調(diào)用此對象的 notify()

13 線程有幾種狀態(tài),產(chǎn)生的條件是什么

14 產(chǎn)生死鎖的基本條件

產(chǎn)生死鎖的原因:

(1) 因為系統(tǒng)資源不足。
(2) 進程運行推進的順序不合適。
(3) 資源分配不當?shù)取?br>如果系統(tǒng)資源充足,進程的資源請求都能夠得到滿足,死鎖出現(xiàn)的可能性就很低,否則
就會因爭奪有限的資源而陷入死鎖。其次,進程運行推進順序與速度不同,也可能產(chǎn)生死鎖。
產(chǎn)生死鎖的四個必要條件:
(1) 互斥條件:一個資源每次只能被一個進程使用。
(2) 請求與保持條件:一個進程因請求資源而阻塞時,對已獲得的資源保持不放。
(3) 不剝奪條件:進程已獲得的資源,在未使用完之前,不能強行剝奪。
(4) 循環(huán)等待條件:若干進程之間形成一種頭尾相接的循環(huán)等待資源關(guān)系。
這四個條件是死鎖的必要條件,只要系統(tǒng)發(fā)生死鎖,這些條件必然成立,而只要上述條件之一不滿足,就不會發(fā)生死鎖。
死鎖的解除與預(yù)防:

理解了死鎖的原因,尤其是產(chǎn)生死鎖的四個必要條件,就可以最大可能地避免、預(yù)防和
解除死鎖。所以,在系統(tǒng)設(shè)計、進程調(diào)度等方面注意如何不讓這四個必要條件成立,如何確
定資源的合理分配算法,避免進程永久占據(jù)系統(tǒng)資源。此外,也要防止進程在處于等待狀態(tài)
的情況下占用資源。因此,對資源的分配要給予合理的規(guī)劃。

15 什么是線程池,如何使用?

線程池就是事先將多個線程對象放到一個容器中,當使用的時候就不用 new 線程而是直接去池中拿線程即可,節(jié)省了開辟子線程的時間,提高的代碼執(zhí)行效率。

在 JDK 的

java.util.concurrent.Executors 中提供了生成多種線程池的靜態(tài)方法。

ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();

ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(4);

ScheduledExecutorService newScheduledThreadPool = Executors.newScheduledThreadPool(4);

ExecutorService newSingleThreadExecutor = Executors.newSingleThreadExecutor();

然后調(diào)用他們的 execute 方法即可。

優(yōu)點:

第一:降低資源消耗。通過重復(fù)利用已創(chuàng)建的線程降低線程創(chuàng)建和銷毀造成的消耗。

第二:提高響應(yīng)速度。當任務(wù)到達時,任務(wù)可以不需要等到線程創(chuàng)建就能立即執(zhí)行。

第三:提高線程的可管理性。線程是稀缺資源,如果無限制的創(chuàng)建,不僅會消耗系統(tǒng)資源,還會降低系統(tǒng)的穩(wěn)定性,使用線程池可以進行統(tǒng)一的分配,調(diào)優(yōu)和監(jiān)控。

16 Java自帶有哪幾種線程池?

一、ThreadPoolExecutor

ThreadPoolExecutor提供了四個構(gòu)造方法:

我們以最后一個構(gòu)造方法(參數(shù)最多的那個),對其參數(shù)進行解釋:

 public ThreadPoolExecutor(int corePoolSize, // 1

int maximumPoolSize, // 2

long keepAliveTime, // 3

TimeUnit unit, // 4

BlockingQueue < Runnable > workQueue, // 5

ThreadFactory threadFactory, // 6

RejectedExecutionHandler handler) { // 7

if (corePoolSize < 0 || maximumPoolSize <= 0 ||

maximumPoolSize < corePoolSize || keepAliveTime < 0)

throw new IllegalArgumentException();

if (workQueue == null || threadFactory == null || handler == null)

throw new NullPointerException();

this.corePoolSize = corePoolSize;

this.maximumPoolSize = maximumPoolSize;

this.workQueue = workQueue;

this.keepAliveTime = unit.tonanos(keepAliveTime);

this.threadFactory = threadFactory;

this.handler = handler;

}

Java SE相關(guān)面試題匯總

二、預(yù)定義線程池

JDK給我們預(yù)定義的幾種線程池

1、FixedThreadPool

 public static ExecutorService newFixedThreadPool(int nThreads) {

return new ThreadPoolExecutor(nThreads, nThreads,

0L, TimeUnit.MILLISECONDS,

new linkedBlockingQueue<Runnable>());

}

  • corePoolSize與maximumPoolSize相等,即其線程全為核心線程,是一個固定大小的線程池,是其優(yōu)勢;
  • keepAliveTime = 0 該參數(shù)默認對核心線程無效,而FixedThreadPool全部為核心線程;
  • workQueue 為linkedBlockingQueue(無界阻塞隊列),隊列最大值為Integer.MAX_VALUE。如果任務(wù)提交速度持續(xù)大于任務(wù)處理速度,會造成隊列大量阻塞。因為隊列很大,很有可能在拒絕策略前,內(nèi)存溢出。是其劣勢;
  • FixedThreadPool的任務(wù)執(zhí)行是無序的;

適用場景:可用于Web服務(wù)瞬時削峰,但需注意長時間持續(xù)高峰情況造成的隊列阻塞。

2、CachedThreadPool

 public static ExecutorService newCachedThreadPool() {

return new ThreadPoolExecutor(0, Integer.MAX_VALUE,

60L, TimeUnit.SECONDS,

new SynchronousQueue<Runnable>());

}

  • corePoolSize = 0,maximumPoolSize = Integer.MAX_VALUE,即線程數(shù)量幾乎無限制;
  • keepAliveTime = 60s,線程空閑60s后自動結(jié)束。
  • workQueue 為 SynchronousQueue 同步隊列,這個隊列類似于一個接力棒,入隊出隊必須同時傳遞,因為CachedThreadPool線程創(chuàng)建無限制,不會有隊列等待,所以使用SynchronousQueue;

適用場景:快速處理大量耗時較短的任務(wù),如Netty的NIO接受請求時,可使用CachedThreadPool。

3、SingleThreadExecutor

 public static ExecutorService newSingleThreadExecutor() {

return new FinalizableDelegatedExecutorService(

new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS,

new linkedBlockingQueue<Runnable>()));

}

這里多了一層

FinalizableDelegatedExecutorService包裝,以下代碼解釋一下其作用:

 public static void main(String[] args) {

ExecutorService fixedExecutorService = Executors.newFixedThreadPool(1);

ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) fixedExecutorService;

System.out.println(threadPoolExecutor.getMaximumPoolSize());

threadPoolExecutor.setCorePoolSize(8);

ExecutorService singleExecutorService = Executors.newSingleThreadExecutor();

// 運行時異常 java.lang.ClassCastException

//ThreadPoolExecutor threadPoolExecutor2 = (ThreadPoolExecutor) singleExecutorService;

}

對比可以看出,F(xiàn)ixedThreadPool可以向下轉(zhuǎn)型為ThreadPoolExecutor,并對其線程池進行配置,而SingleThreadExecutor被包裝后,無法成功向下轉(zhuǎn)型。因此,SingleThreadExecutor被定以后,無法修改,做到了真正的Single。

4、ScheduledThreadPool

 public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {

return new ScheduledThreadPoolExecutor(corePoolSize);

}

newScheduledThreadPool調(diào)用的是ScheduledThreadPoolExecutor的構(gòu)造方法,而ScheduledThreadPoolExecutor繼承了ThreadPoolExecutor,構(gòu)造是還是調(diào)用了其父類的構(gòu)造方法。

public ScheduledThreadPoolExecutor(int corePoolSize) {

super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,

new DelayedWorkQueue());

}

三、自定義線程池

以下是自定義線程池,使用了有界隊列,自定義ThreadFactory和拒絕策略的demo:

public class ThreadTest {

public static void main(String[] args) throws InterruptedException, IOException {

int corePoolSize = 2;

int maximumPoolSize = 4;

long keepAliveTime = 10;

TimeUnit unit = TimeUnit.SECONDS;

BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(2);

ThreadFactory threadFactory = new NameTreadFactory();

RejectedExecutionHandler handler = new MyIgnorePolicy();

ThreadPoolExecutor executor

= new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit,

workQueue, threadFactory, handler);

executor.prestartAllCoreThreads(); // 預(yù)啟動所有核心線程

for (int i = 1; i <= 10; i++) {

MyTask task = new MyTask(String.valueOf(i));

executor.execute(task);

}

System.in.read(); //阻塞主線程

}

static class NameTreadFactory implements ThreadFactory {

private final AtomicInteger mThreadNum = new AtomicInteger(1);

@Override

public Thread newThread(Runnable r) {

Thread t = new Thread(r, "my-thread-" + mThreadNum.getAndIncrement());

System.out.println(t.getName() + " has been created");

return t;

}

}

public static class MyIgnorePolicy implements RejectedExecutionHandler {

public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {

doLog(r, e);

}

private void doLog(Runnable r, ThreadPoolExecutor e) {

// 可做日志記錄等

System.err.println( r.toString() + " rejected");

// System.out.println("completedTaskCount: " + e.getCompletedTaskCount());

}

}

static class MyTask implements Runnable {

private String name;

public MyTask(String name) {

this.name = name;

}

@Override

public void run() {

try {

System.out.println(this.toString() + " is running!");

Thread.sleep(3000); //讓任務(wù)執(zhí)行慢點

} catch (InterruptedException e) {

e.printStackTrace();

}

}

public String getName() {

return name;

}

@Override

public String toString() {

return "MyTask [name=" + name + "]";

}

}

}

17 Java 中有幾種類型的流

18 字節(jié)流如何轉(zhuǎn)為字符流

字節(jié)輸入流轉(zhuǎn)字符輸入流通過 InputStreamReader 實現(xiàn),該類的構(gòu)造函數(shù)可以傳入 InputStream 對象。

字符輸出流轉(zhuǎn)字節(jié)輸出流通過OutputStreamWriter 實現(xiàn),該類的構(gòu)造函數(shù)可以傳入 OutputStream 對象。

3.19 請寫出你最常見的5個Exception

(1)

java.lang.NullPointerException 空指針異常;出現(xiàn)原因:調(diào)用了未經(jīng)初始化的對象或者是不存在的對象。

(2)

java.lang.ClassNotFoundException 指定的類找不到;出現(xiàn)原因:類的名稱和路徑加載錯誤;通常都是程序試圖通過字符串來加載某個類時可能引發(fā)異常。

(3)

java.lang.NumberFormatException 字符串轉(zhuǎn)換為數(shù)字異常;出現(xiàn)原因:字符型數(shù)據(jù)中包含非數(shù)字型字符。

(4)

java.lang.IndexOutOfBoundsException 數(shù)組角標越界異常,常見于操作數(shù)組對象時發(fā)生。

(5)

java.lang.IllegalArgumentException 方法傳遞參數(shù)錯誤。

(6)

java.lang.ClassCastException 數(shù)據(jù)類型轉(zhuǎn)換

Java SE相關(guān)面試題匯總

標簽:java面試題

本文鏈接:

本文章“Java SE相關(guān)面試題匯總”已幫助 147 人

免責聲明:本信息由用戶發(fā)布,本站不承擔本信息引起的任何交易及知識產(chǎn)權(quán)侵權(quán)的法律責任!

本文由賦能網(wǎng) 整理發(fā)布。了解更多培訓機構(gòu)》培訓課程》學習資訊》課程優(yōu)惠》課程開班》學校地址等機構(gòu)信息,可以留下您的聯(lián)系方式,讓課程老師跟你詳細解答:
咨詢熱線:4008-569-579

如果本頁不是您要找的課程,您也可以百度查找一下: