Java SE面試中常見問題總結(jié)

1. Java面向?qū)ο?/h2>

(1). 封裝

? 核心思想就是“隱藏細(xì)節(jié)”、“數(shù)據(jù)安全”慰枕、”重用”搞挣、”不必關(guān)心具體的實(shí)現(xiàn)”:將對象不需要讓外界訪問的成員變量和方法私有化育谬,只提供符合開發(fā)者意愿的公有方法來訪問這些數(shù)據(jù)和邏輯演熟,保證了數(shù)據(jù)的安全和程序的穩(wěn)定。

? 使用 private 修飾符把成員變量設(shè)置為私有霸褒,防止外部程序直接隨意調(diào)用或修改成員變量伴找,然后對外提供 publicsetget 方法按照開發(fā)者的意愿(可以編寫一些業(yè)務(wù)邏輯代碼,雖然很少這樣做)設(shè)置和獲取成員變量的值废菱。

(2). 繼承

? 用來提高了程序的復(fù)用性技矮、擴(kuò)展性

? 在實(shí)際開發(fā)中,應(yīng)該是先有子類,然后從中抽象封裝出父類

? 使用extends關(guān)鍵字實(shí)現(xiàn)

? Java只允許單繼承

? 父類中public和protected修飾的成員變量和方法可以被子類集成,構(gòu)造方法不能被繼承,但可以在子類中使用super()調(diào)用.子類中可以降低提高級(jí)別而不能降低.

? state修飾的變量或者方法屬于類,不能被繼承,但是子類可以直接調(diào)用

1). 方法重寫

? 方法重寫針對于實(shí)例方法.

? 方法名和參數(shù)必須一致,訪問修飾可以提高.(如果有必要可以才上方添加@Override注解自動(dòng)檢查)

? 返回值可以不一樣,但是只能是子類.

? 拋出異常必須是父類該方法拋出異常的子集

? 對于類方法(static,靜態(tài)),在子類中重寫是進(jìn)行隱藏(與重載的區(qū)別是如果向上進(jìn)行轉(zhuǎn)型,那么執(zhí)行的還是父類的方法)

2). 類實(shí)例化的過程

  1. 類加載
    1. 讀取class文件,加載到內(nèi)存,如果有父類,也會(huì)加載父類(==加載和驗(yàn)證==)
    2. 分配空間(==準(zhǔn)備==,會(huì)賦初值為默認(rèn)值)
    3. 執(zhí)行父類,子類靜態(tài)代碼塊(==初始化==,在這一步之前進(jìn)行了==解析==過程,將符號(hào)引用轉(zhuǎn)化為直接引用)
  2. 分配堆內(nèi)存空間,所有值為默認(rèn)值
  3. 對對象屬性進(jìn)行默認(rèn)初始化(顯示賦值的)
  4. 調(diào)用構(gòu)造方法
    1. 先調(diào)用父類構(gòu)造方法初始化父類數(shù)據(jù)
    2. 顯示的執(zhí)行子類的構(gòu)造代碼塊(與靜態(tài)代碼塊的區(qū)別在于不加static)
    3. 執(zhí)行子類構(gòu)造方法中的代碼進(jìn)行初始化
  5. 將地址賦給引用(外層new關(guān)鍵字那里)

(3). 多態(tài)

? 同一個(gè)行為具有多個(gè)不同表現(xiàn)形式.

? ==同一個(gè)接口使用不同的實(shí)例對象而執(zhí)行不同的操作.==

? Java中有兩種引用類型:編譯時(shí)類型和運(yùn)行時(shí)類型.編譯時(shí)類型由引用決定,運(yùn)行時(shí)類型由實(shí)例對象的類型決定.

條件:

  • 繼承
  • 重寫
  • 父類引用指向子類對象

? 在編譯時(shí)會(huì)先判斷父類中有沒有此方法,如果沒有,則編譯錯(cuò)誤.如果有,再去調(diào)用子類中的同名方法(要么繼承下去,要么被重寫,只有被重寫才能體現(xiàn)出多態(tài)性)

? 在JVM底層實(shí)現(xiàn)中,實(shí)際上是由于方法的編譯期靜態(tài)多分派和運(yùn)行期動(dòng)態(tài)單分派來完成的.靜態(tài)多分派是指在編譯階段,會(huì)對方法的重載進(jìn)行選擇,這里是根據(jù)靜態(tài)類型中的方法進(jìn)行選擇,選擇的依據(jù)是方法名,方法返回值和方法的參數(shù)列表,所以才叫多分派.而在運(yùn)行期,在靜態(tài)分派已經(jīng)選擇出的方法的基礎(chǔ)上,JVM從實(shí)際類型出發(fā),尋找符合該方法的方法,如果找不到就上升到父類中進(jìn)行查找,這里查找的依據(jù)只有父類這一條路,所以叫單分派.這樣就造成了,對于不同的子類,可能會(huì)由于動(dòng)態(tài)分派選擇到不同的方法去運(yùn)行,也就實(shí)現(xiàn)了多態(tài).

2. 訪問權(quán)限修飾關(guān)鍵字

本類 本包 子類 外部包
public
protected ×
default × ×
private × × ×

? 訪問權(quán)限的控制是在編譯層的,通過反射還是可以訪問私有成員的

3. Java中的異常

(1). 異常體系

image-20200221133732048
  • Throwable:所有錯(cuò)誤或者異常的超類,這個(gè)類或者其子類才能被throw拋出,才能作為catch中的參數(shù)類型
    • Error:不應(yīng)該捕獲的嚴(yán)重類型,出現(xiàn)就應(yīng)該退出程序
      • VirtulMachineError:虛擬機(jī)錯(cuò)誤(硬件錯(cuò)誤,還是內(nèi)存不夠等等)
      • AWTError:AWT是Java用戶界面和繪制圖形圖像的包,這個(gè)錯(cuò)誤多是GUI中產(chǎn)生的
    • Exception:通常講的異常,==受檢查異常==,指程序可以處理的異常
      • RuntimeException:==運(yùn)行時(shí)異常==,可以不進(jìn)行處理也可以加上try-catch或者throws
        • 空指針,數(shù)組越界,類型轉(zhuǎn)換,算數(shù)錯(cuò)誤等等
      • IOException:輸入輸出異常,這里代表性的泛指非運(yùn)行時(shí)異常(又稱可檢查異常),必須要顯示的加上try-catch或者throws,否則編譯不通過
      • 等等,沒有列舉出全部

(2). throws和throw關(guān)鍵字

? throws關(guān)鍵字用于在方法后面聲明方法內(nèi)部可能會(huì)拋出的異常.

? throw用于手動(dòng)的拋出異常(通常在try-catch中會(huì)有一些處理后再向外層拋出,具體使用與業(yè)務(wù)邏輯有關(guān))

(3). finally關(guān)鍵字

? 無論是否發(fā)生異常,finally代碼塊中的代碼都會(huì)被執(zhí)行

關(guān)于return和finally的順序:

return語句其實(shí)是先將后面的變量從局部變量區(qū)放入操作數(shù)棧頂,然后執(zhí)行return,返回操作數(shù)棧頂?shù)闹?/p>

finally代碼塊中的代碼執(zhí)行在這兩個(gè)過程之間.也就是說,如果finally代碼塊中沒有出現(xiàn)return語句,是不會(huì)影響方法的返回值的.如果有,那么操作數(shù)棧頂?shù)闹禃?huì)被替換,會(huì)改變方法的返回值.

4. Synchronized詳解

深入理解Java并發(fā)之synchronized實(shí)現(xiàn)原理

(1). Synchronized使用

1). 對象鎖(同步代碼塊)

synchronized (object) {
    // 臨界區(qū)代碼
}

? 不同線程訪問同一個(gè)對象的對象鎖,只能有一個(gè)線程成功進(jìn)入,其他線程阻塞在代碼塊外面.當(dāng)該線程退出代碼塊時(shí),其他的線程進(jìn)行CPU的競爭(就緒態(tài)),成功競爭到CPU的線程獲取鎖.

2). 方法鎖(同步方法)

public synchronized method(){
    // 整個(gè)方法內(nèi)部都是臨界區(qū)
}

? 不同線程不能同時(shí)進(jìn)入此方法,鎖對象為this,所以多個(gè)線程調(diào)用==同一個(gè)對象的不同同步方法==也會(huì)進(jìn)行同步

? 方法級(jí)的同步是隱式殊轴,即無需通過字節(jié)碼指令來控制的穆役,它實(shí)現(xiàn)在方法調(diào)用和返回操作之中。JVM可以從方法常量池中的方法表結(jié)構(gòu)(method_info Structure) 中的 ACC_SYNCHRONIZED 訪問標(biāo)志區(qū)分一個(gè)方法是否同步方法梳凛。當(dāng)方法調(diào)用時(shí),調(diào)用指令將會(huì) 檢查方法的 ACC_SYNCHRONIZED 訪問標(biāo)志是否被設(shè)置梳杏,如果設(shè)置了韧拒,執(zhí)行線程將先持有monitor(虛擬機(jī)規(guī)范中用的是管程一詞), 然后再執(zhí)行方法十性,最后再方法完成(無論是正常完成還是非正常完成)時(shí)釋放monitor叛溢。在方法執(zhí)行期間,執(zhí)行線程持有了monitor劲适,其他任何線程都無法再獲得同一個(gè)monitor楷掉。

? ==synchronized修飾的方法并沒有monitorenter指令和monitorexit指令,取得代之的確實(shí)是ACC_SYNCHRONIZED標(biāo)識(shí)==霞势,該標(biāo)識(shí)指明了該方法是一個(gè)同步方法烹植,JVM通過該ACC_SYNCHRONIZED訪問標(biāo)志來辨別一個(gè)方法是否聲明為同步方法斑鸦,從而執(zhí)行相應(yīng)的同步調(diào)用。

與sync代碼塊的區(qū)別在于,sync代碼塊的實(shí)現(xiàn)方式實(shí)際上是在代碼塊的開始和結(jié)束處調(diào)用了monitorenter 和 monitorexit 兩個(gè)指令.分別獲取和釋放monitor對象的持有權(quán).

而同步方法中是進(jìn)行了標(biāo)記,沒有使用字節(jié)碼指令,但實(shí)際上還是獲取Monitor對象

3). 類鎖

public MyClass{
    public synchronized static void method(){}
}

? 不同的線程不能同時(shí)進(jìn)入這個(gè)類的這個(gè)靜態(tài)方法.使用當(dāng)前類的類對象==MyClass.class為鎖==,所以其他線程只要調(diào)用這個(gè)類其中的任意一個(gè)靜態(tài)同步方法,都會(huì)被阻塞.

(2). Synchronized原理(代碼塊)

1). Java對象模型

? 每一個(gè)Java類在被JVM加載的時(shí)候,JVM都會(huì)給這個(gè)類創(chuàng)建一個(gè)instanceKlass保存在方法區(qū),在JVM層用來表示該Java類.使用new創(chuàng)建一個(gè)對象的時(shí)候,JVM會(huì)創(chuàng)建一個(gè)instanceOopDesc對象,這個(gè)對象中包含了對象頭和實(shí)例數(shù)據(jù)(還會(huì)有填充數(shù)據(jù)來保證每個(gè)對象的內(nèi)存都是8字節(jié)的整數(shù)倍)

? 對象頭包含兩部分:Mark Word(運(yùn)行時(shí)數(shù)據(jù),哈希碼,GC分代年齡,鎖狀態(tài)標(biāo)志,等等)和Klass Point(只想的是對象所屬類的instanceKlass).

? 對象的實(shí)例(instantOopDesc)保存在堆上草雕,對象的元數(shù)據(jù)(instantKlass)保存在方法區(qū)巷屿,對象的引用保存在棧上。

2). 監(jiān)視鎖Monitor

? 每一個(gè)Object對象中都內(nèi)置了一個(gè)Monitor對象.(對象頭中Mark Word中的LockWord指向的是Monitor對象的起始地址)

? Monitor相當(dāng)于許可證,拿到Monitor可以進(jìn)行操作,沒拿到需要等待.

? 在Java虛擬機(jī)中,monitor是由ObjectMonitor實(shí)現(xiàn)的.

ObjectMonitor中有幾個(gè)關(guān)鍵屬性:

  • _owner:指向持有Monitor對象的線程
  • _WaitSet:存放在該Monitor上處于wait狀態(tài)的線程隊(duì)列(obj.wait())
  • _EntryList:存放處于等待鎖block狀態(tài)的線程隊(duì)列
  • _recursions:鎖的可重入次數(shù)
  • _count:用來記錄當(dāng)前占有鎖的線程的重入次數(shù)

一些操作:

  • 線程T等待獲取鎖(同步代碼塊外等待):_EntryList中加入T
  • 線程T獲取對象鎖(進(jìn)入代碼塊):_EntryList移除T,_Owner置為T,計(jì)數(shù)器_count+1
  • 線程T獲取對象鎖之后調(diào)用了wait()方法:在之前的基礎(chǔ)上給_WaitSet中加入T

3). Synchronized底層

1>. 同步代碼塊
  • monitorenter指令插入到同步代碼塊的開始位置
  • monitorexit指令插入到同步代碼塊的結(jié)束位置

? JVM保證這兩個(gè)指令是一一對應(yīng)的.

? 當(dāng)線程執(zhí)行到monitorenter時(shí),會(huì)嘗試獲取該對象所對應(yīng)的monitor的所有權(quán).

2>. 同步(靜態(tài))方法

? synchronized方法則會(huì)被翻譯成普通的方法調(diào)用和返回指令如:invokevirtual墩虹、areturn指令.

? 在VM字節(jié)碼層面并沒有任何特別的指令來實(shí)現(xiàn)被synchronized修飾的方法嘱巾,而是在==Class文件的方法表中將該方法的access_flags字段中的synchronized標(biāo)志置為1==,表示該方法是同步方法并==使用調(diào)用該方法的對象或該方法所屬的Class在JVM的內(nèi)部對象表示Klass做為鎖對象==诫钓。

(3). 鎖優(yōu)化

? ==JDK 6==之后對synchronized鎖進(jìn)行優(yōu)化,新增了輕量級(jí)鎖和偏向鎖.

1). 偏向鎖

? “偏向”的意思是旬昭,偏向鎖假定將來只有第一個(gè)申請鎖的線程會(huì)使用鎖(不會(huì)有任何線程再來申請鎖),因此菌湃,只需要在Mark Word中CAS記錄owner(本質(zhì)上也是更新问拘,但初始值為空),如果記錄成功慢味,則偏向鎖獲取成功场梆,記錄鎖狀態(tài)為偏向鎖,以后當(dāng)前線程等于owner就可以零成本的直接獲得鎖纯路;否則或油,說明有其他線程競爭,膨脹為輕量級(jí)鎖驰唬。

? ==記錄線程id,之后這個(gè)線程再次進(jìn)行訪問不需要進(jìn)行同步.當(dāng)其他線程嘗試去獲取這個(gè)鎖時(shí),偏向模式結(jié)束.==

2). 輕量級(jí)鎖

? 使用輕量級(jí)鎖時(shí)顶岸,不需要申請互斥量,僅僅將==Mark Word中的部分字節(jié)CAS更新指向線程棧中的Lock Record(鎖記錄)==,如果更新成功,則輕量級(jí)鎖獲取成功酿炸,記錄鎖狀態(tài)為輕量級(jí)鎖良姆;否則,說明已經(jīng)有線程獲得了輕量級(jí)鎖笤妙,目前發(fā)生了鎖競爭(允許短時(shí)間的鎖競爭,使用==自旋鎖優(yōu)化==),接下來膨脹為重量級(jí)鎖。

  1. 在代碼進(jìn)入同步塊的時(shí)候世蔗,如果同步對象鎖狀態(tài)為無鎖狀態(tài)(鎖標(biāo)志位為“01”狀態(tài),是否為偏向鎖為“0”)朗兵,虛擬機(jī)首先將==在當(dāng)前線程的棧幀中建立一個(gè)名為鎖記錄(Lock Record)的空間==污淋,用于存儲(chǔ)鎖對象目前的Mark Word的拷貝
  2. 拷貝對象頭中的==Mark Word復(fù)制到鎖記錄==(Lock Record)中
  3. 線程嘗試==使用CAS將對象頭中的Mark Word替換為指向鎖記錄的指針==,成功則代表獲得鎖余掖,失敗表示其他線程競爭鎖寸爆,當(dāng)前線程嘗試使用自旋操作來獲取鎖。
  4. 自旋多次后仍然沒有獲取到鎖,該鎖升級(jí)為重量級(jí)鎖,使用mutex阻塞當(dāng)前線程

3). 自旋鎖

  • 當(dāng)前線程競爭鎖失敗時(shí),打算阻塞自己
  • 不直接阻塞自己赁豆,而是自旋(空等待仅醇,比如一個(gè)空的有限for循環(huán))一會(huì)
  • 在自旋的同時(shí)重新競爭鎖
  • 如果自旋結(jié)束前獲得了鎖,那么鎖獲取成功歌憨;否則着憨,自旋結(jié)束后阻塞自己

4). 重量級(jí)鎖

? 在輕量級(jí)鎖自旋一定次數(shù)還沒有競爭到鎖資源時(shí),輕量級(jí)鎖膨脹為重量級(jí)鎖,并阻塞當(dāng)前線程.

? synchronized重量級(jí)鎖本質(zhì)依賴監(jiān)視器鎖monitor實(shí)現(xiàn),而monitor的本質(zhì)是依賴于底層操作系統(tǒng)的Mutex Lock實(shí)現(xiàn),監(jiān)視器鎖可以認(rèn)為直接對應(yīng)底層操作系統(tǒng)中的互斥量(mutex),要進(jìn)行線程之間的切換需要從用戶態(tài)轉(zhuǎn)換成內(nèi)核態(tài),成本非常高.

5. 深拷貝和淺拷貝

? Object對象有個(gè)clone()方法,實(shí)現(xiàn)了對象中各個(gè)屬性的復(fù)制务嫡,但它的可見范圍是protected的甲抖,所以實(shí)體類使用克隆的前提是:

  1. 實(shí)現(xiàn)Cloneable接口,這是一個(gè)標(biāo)記接口心铃,自身沒有方法准谚。
  2. 覆蓋clone()方法,可見性提升為public去扣。

? 調(diào)用Object的clone()方法可以返回一個(gè)與當(dāng)前對象完全一樣的拷貝對象.

? 淺拷貝:創(chuàng)建一個(gè)新對象柱衔,然后將當(dāng)前對象的非靜態(tài)字段復(fù)制到該新對象,如果字段是值類型的愉棱,那么對該字段執(zhí)行復(fù)制唆铐;如果該字段是引用類型的話,則復(fù)制引用但不復(fù)制引用的對象奔滑。

? 深拷貝:創(chuàng)建一個(gè)新對象艾岂,然后將當(dāng)前對象的非靜態(tài)字段復(fù)制到該新對象,無論該字段是值類型的還是引用類型朋其,都復(fù)制獨(dú)立的一份王浴。當(dāng)你修改其中一個(gè)對象的任何內(nèi)容時(shí),都不會(huì)影響另一個(gè)對象的內(nèi)容梅猿。

? ==深拷貝和淺拷貝的區(qū)別在于:對對象內(nèi)部的引用是直接復(fù)制還是遞歸的進(jìn)行拷貝.==

6. 線程池

(1). 為什么需要線程池

? 減少線程的創(chuàng)建和銷毀操作,增加復(fù)用

(2). 線程池參數(shù)

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler)
  • corePoolSize:核心線程數(shù),線程池中至少存活的線程,不會(huì)進(jìn)行銷毀.(關(guān)于超時(shí)時(shí)間可以進(jìn)行設(shè)置是否進(jìn)行銷毀)
  • maxumumPoolSize:所有線程總數(shù)上限(核心線程+臨時(shí)線程)
  • keepAliveTime:線程最大空閑時(shí)間,線程閑置的時(shí)間到達(dá)這個(gè)時(shí)間會(huì)被銷毀(默認(rèn)不使用于核心線程)
  • unit:超時(shí)時(shí)間的單位
  • workQueue:任務(wù)隊(duì)列,如果線程池的核心線程沒有空閑,此時(shí)出現(xiàn)了新的任務(wù),新任務(wù)會(huì)被放入這個(gè)隊(duì)列
    • 有界隊(duì)列:超出隊(duì)列的上限后會(huì)創(chuàng)建臨時(shí)線程
    • 無界隊(duì)列:永遠(yuǎn)不會(huì)創(chuàng)建臨時(shí)線程
  • threadFactory:一個(gè)接口對象,用于定義生成線程的方式,如線程名格式
  • handler:當(dāng)任務(wù)隊(duì)列滿了,出現(xiàn)新任務(wù)時(shí)的拒絕策略
    • ThreadPoolExecutor.AbortPolicy:直接拋出異常氓辣,這是==默認(rèn)策略==
    • ThreadPoolExecutor.DiscardPolicy:直接丟棄任務(wù),但是不拋出異常袱蚓。
    • ThreadPoolExecutor.DiscardOldestPolicy:丟棄隊(duì)列最前面的任務(wù)钞啸,然后將新來的任務(wù)加入等待隊(duì)列
    • ThreadPoolExecutor.CallerRunsPolicy:由線程池所在的線程處理該任務(wù),比如在 main 函數(shù)中創(chuàng)建線程池喇潘,如果執(zhí)行此策略体斩,將有 main 線程來執(zhí)行該任務(wù)

(3). 幾種封裝好的線程池實(shí)現(xiàn)(不推薦使用,但是很重要)

以下各種實(shí)現(xiàn)都有包含ThreadFactory的構(gòu)造,下面沒有列舉

1). newFixedThreadPool

public static ExecutorService newFixedThreadPool(int nThreads) {
    return new ThreadPoolExecutor(nThreads, nThreads,
                                  0L, TimeUnit.MILLISECONDS,
                                  new LinkedBlockingQueue<Runnable>());
}

? 一個(gè)==線程數(shù)量固定==的線程池,規(guī)定的最大線程數(shù)量响蓉,超過這個(gè)數(shù)量之后進(jìn)來的任務(wù),會(huì)放到等待隊(duì)列中哨毁,如果有空閑線程枫甲,則在等待隊(duì)列中獲取,遵循先進(jìn)先出原則。

? 核心線程數(shù)和最大線程數(shù)一致

? 默認(rèn)使用的是 LinkedBlockingQueue(無界隊(duì)列) 作為等待隊(duì)列

2). newSingleThreadExecutor

public static ExecutorService newSingleThreadExecutor() {
    return new FinalizableDelegatedExecutorService
        (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS,
                                new LinkedBlockingQueue<Runnable>()));
}

? ==只有一個(gè)線程==的線程池,其他任務(wù)進(jìn)來,會(huì)在等待隊(duì)列中排隊(duì).

? 使用LinkedBlockingQueue(無界隊(duì)列) 作為等待隊(duì)列,可能會(huì)無限長

3). newCachedThreadPool

public static ExecutorService newCachedThreadPool() {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                  60L, TimeUnit.SECONDS,
                                  new SynchronousQueue<Runnable>());
}

? 緩存型線程池,全部都是臨時(shí)線程.

? ==隊(duì)列中不保存等待任務(wù)==,當(dāng)前沒有空閑線程直接創(chuàng)建新的臨時(shí)線程.臨時(shí)線程的空閑時(shí)間很短.

? 關(guān)鍵在于使用SynchronousQueue作為等待隊(duì)列,它不會(huì)保留任務(wù).

4). newScheduledThreadPool

public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
    return new ScheduledThreadPoolExecutor(corePoolSize);
}
public ScheduledThreadPoolExecutor(int corePoolSize) {
    super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
          new DelayedWorkQueue());
}

? 計(jì)劃型線程池,可以設(shè)置固定時(shí)間的延時(shí)或者定期執(zhí)行任務(wù).

? 使用DelayedWorkQueue 作為等待隊(duì)列,保證隊(duì)列中的任務(wù)只有到了指定的延時(shí)時(shí)間想幻,才會(huì)執(zhí)行任務(wù)粱栖。

(4). 線程池工作原理

  1. 當(dāng)提交一個(gè)新任務(wù)到線程池時(shí),線程池判斷corePoolSize線程池是否都在執(zhí)行任務(wù)脏毯,如果有空閑線程闹究,則創(chuàng)建一個(gè)新的工作線程來執(zhí)行任務(wù),直到當(dāng)前線程數(shù)等于corePoolSize食店;
  2. 如果當(dāng)前線程數(shù)為corePoolSize渣淤,繼續(xù)提交的任務(wù)被保存到阻塞隊(duì)列中,等待被執(zhí)行吉嫩;
  3. 如果阻塞隊(duì)列滿了价认,那就創(chuàng)建新的線程執(zhí)行當(dāng)前任務(wù),直到線程池中的線程數(shù)達(dá)到maxPoolSize自娩,這時(shí)再有任務(wù)來用踩,由飽和策略來處理提交的任務(wù)

7. 反射

與反射機(jī)制相關(guān)的類:

  • Class類:類在內(nèi)存中的實(shí)體
  • Field類:類的成員變量
  • Method類:類的方法
  • Constructor類:類的構(gòu)造方法

(1). 獲取Class對象

  • Class.forName(className)

(2). 獲取構(gòu)造方法

  • Class.getDeclaredConstructors()獲取所有構(gòu)造方法的數(shù)組.(不加Declared不能獲取私有構(gòu)造)
  • Class.getDeclaredConstructors(參數(shù)類型數(shù)組也就是Class[])獲取指定參數(shù)的構(gòu)造.(要try-catch,可能找不到)

(3). 調(diào)用構(gòu)造方法

  • Constructor.newInstance(參數(shù)1, 參數(shù)2)調(diào)用相應(yīng)構(gòu)造方法
    • 如果是私有構(gòu)造,需要進(jìn)行設(shè)置setAccessible(true)

(4). 獲取方法

? 與獲取構(gòu)造方法類似

  • Class.getDeclaredMethod(String methodName, Class[] paraTypeArray)獲取指定名稱,參數(shù)的方法
  • Class.getDeclaredMethods()獲取全部的方法數(shù)組

(5). 調(diào)用方法

  • Method.invoke(參數(shù)1,參數(shù)2,參數(shù)3.......)返回Object
    • 私有方法setAccessible(true)

(5). 獲取屬性

  • Class.getDeclaredField(String fieldName)根據(jù)屬性名獲取屬性對象
  • Class.getDeclaredFields()獲取所有屬性數(shù)組
    • 通過set設(shè)置屬性,私有setAccessible(true)

8. 抽象類和接口的區(qū)別

(1). 組成

  • 抽象類可以有實(shí)現(xiàn)了的方法,接口不可以有
  • 抽象類可以有各種訪問級(jí)別的成員變量,接口只能有public static final的變量
  • 抽象類可以有構(gòu)造器(用于子類中調(diào)用以構(gòu)造父類部分的屬性),接口不能
  • 抽象類中不能有private的方法,接口中只能有public

(2). 用途

  • 抽象類用于表示不可實(shí)例化的類,本質(zhì)上還是類,而接口只是方法的集合,并不是類
  • 抽象類只能單繼承,而接口可以實(shí)現(xiàn)多個(gè)

8. 關(guān)于Object.hashcode()方法

? hashCode返回的并不一定是對象的(虛擬)內(nèi)存地址,具體取決于運(yùn)行時(shí)庫和JVM的具體實(shí)現(xiàn)忙迁。

? Object.hashCode是一個(gè)native方法脐彩,看不到源碼。

? Object.hashCode()在JRE中應(yīng)該遵循的一些契約:

  • 一致性姊扔,在程序的一次執(zhí)行過程中惠奸,對==同一個(gè)對象必須一致地返回同一個(gè)整數(shù)==。

  • 如果兩個(gè)對象通過==equals(Object)==比較旱眯,==結(jié)果相等==晨川,那么對這兩個(gè)對象分別調(diào)用==hashCode方法應(yīng)該產(chǎn)生相同的整數(shù)結(jié)果==。

  • 如果兩個(gè)對象通過java.lang.Object.equals(java.lang.Ojbect)比較删豺,==結(jié)果不相等共虑,不必保證對這兩個(gè)對象分別調(diào)用hashCode也返回兩個(gè)不相同的整數(shù)。==

9. JDK個(gè)版本的新特性

java5

  1. 泛型
  2. 增強(qiáng)for循環(huán)
  3. 自動(dòng)封箱拆箱
  4. 枚舉
  5. 注解
  6. 新的線程模型和并發(fā)庫(java.util.concurrent)呀页。

java6

  1. 集合框架增強(qiáng)妈拌。
  2. 新的數(shù)組拷貝方法。Arrays.copyOfArrays.copyOfRange
  3. Scripting. 可以讓其他語言在java平臺(tái)上運(yùn)行蓬蝶。 java6包含了一個(gè)基于Mozilla Rhino實(shí)現(xiàn)的javascript腳本引擎尘分。
  4. 支持JDBC4.0規(guī)范。

java7

  1. 二進(jìn)制前綴0b或者0B丸氛。整型(byte, short, int, long)可以直接用二進(jìn)制表示培愁。
  2. 字面常量數(shù)字的下劃線。用下劃線連接整數(shù)提升其可讀性缓窜,自身無含義定续,不可用在數(shù)字的起始和末尾谍咆。
  3. 泛型實(shí)例化類型自動(dòng)推斷(new后面跟的不需要注明泛型)。
  4. try-with-resources語句(帶資源的try)私股。
  5. 單個(gè)catch中捕獲多個(gè)異常類型(用| 分割)并通過改進(jìn)的類型檢查重新拋出異常摹察。

java8

  1. lambada表達(dá)式(Lambda Expressions)。Lambda允許把函數(shù)作為一個(gè)方法的參數(shù)(函數(shù)作為參數(shù)傳遞進(jìn)方法中)倡鲸。
  2. HashMap改進(jìn)供嚎,在鍵值哈希沖突時(shí)能有更好表現(xiàn)。
  3. Date Time API峭状。加強(qiáng)對日期和時(shí)間的處理克滴。
  4. java.util 包下的改進(jìn),提供了幾個(gè)實(shí)用的工具類宁炫。
    • 并行數(shù)組排序偿曙。
    • 標(biāo)準(zhǔn)的==Base64==編解碼。
    • 支持無符號(hào)運(yùn)算羔巢。
  5. HotSpot
    • 刪除了 永久代(PermGen).
    • 方法調(diào)用的字節(jié)碼指令支持默認(rèn)方法望忆。

代理類的特點(diǎn)java9

  1. java模塊系統(tǒng) (Java Platform Module System)。

10. Java中基本數(shù)據(jù)類型和其內(nèi)存大小

  1. 整型
    1. byte 1字節(jié)
    2. short 2字節(jié)
    3. int 4字節(jié)
    4. long 8字節(jié)
  2. 字符型
    1. char 2字節(jié)(ASCII碼和UFT-8,默認(rèn)為'\0')
  3. 浮點(diǎn)型
    1. float 4字節(jié)
    2. double 8字節(jié)
  4. 布爾型
    1. boolean (布爾類型比較復(fù)雜,單個(gè)的布爾類型,編譯時(shí)會(huì)被當(dāng)做int類型處理,原因是32位機(jī)一次處理的數(shù)據(jù)量就是4字節(jié).而對于bollean[],會(huì)被轉(zhuǎn)化成byte[],每個(gè)元素占1字節(jié))
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末竿秆,一起剝皮案震驚了整個(gè)濱河市启摄,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌幽钢,老刑警劉巖歉备,帶你破解...
    沈念sama閱讀 221,406評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異匪燕,居然都是意外死亡蕾羊,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,395評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門帽驯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來龟再,“玉大人,你說我怎么就攤上這事尼变±眨” “怎么了?”我有些...
    開封第一講書人閱讀 167,815評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵嫌术,是天一觀的道長哀澈。 經(jīng)常有香客問我,道長度气,這世上最難降的妖魔是什么割按? 我笑而不...
    開封第一講書人閱讀 59,537評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮磷籍,結(jié)果婚禮上适荣,老公的妹妹穿的比我還像新娘丙躏。我一直安慰自己,他們只是感情好束凑,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,536評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著栅盲,像睡著了一般汪诉。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上谈秫,一...
    開封第一講書人閱讀 52,184評(píng)論 1 308
  • 那天扒寄,我揣著相機(jī)與錄音,去河邊找鬼拟烫。 笑死该编,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的硕淑。 我是一名探鬼主播课竣,決...
    沈念sama閱讀 40,776評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼置媳!你這毒婦竟也來了于樟?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,668評(píng)論 0 276
  • 序言:老撾萬榮一對情侶失蹤拇囊,失蹤者是張志新(化名)和其女友劉穎迂曲,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體寥袭,經(jīng)...
    沈念sama閱讀 46,212評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡路捧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,299評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了传黄。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片杰扫。...
    茶點(diǎn)故事閱讀 40,438評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖尝江,靈堂內(nèi)的尸體忽然破棺而出涉波,到底是詐尸還是另有隱情,我是刑警寧澤炭序,帶...
    沈念sama閱讀 36,128評(píng)論 5 349
  • 正文 年R本政府宣布啤覆,位于F島的核電站,受9級(jí)特大地震影響惭聂,放射性物質(zhì)發(fā)生泄漏窗声。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,807評(píng)論 3 333
  • 文/蒙蒙 一辜纲、第九天 我趴在偏房一處隱蔽的房頂上張望笨觅。 院中可真熱鬧拦耐,春花似錦、人聲如沸见剩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,279評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽苍苞。三九已至固翰,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間羹呵,已是汗流浹背骂际。 一陣腳步聲響...
    開封第一講書人閱讀 33,395評(píng)論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留冈欢,地道東北人歉铝。 一個(gè)月前我還...
    沈念sama閱讀 48,827評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像凑耻,于是被迫代替她去往敵國和親太示。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,446評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容