面試復(fù)習(xí)之Java知識(shí)解答

Java知識(shí)復(fù)習(xí)解答

1.synchronize 和 volitale的區(qū)別;什么是可見性和原子性

可見性:當(dāng)一個(gè)線程修改了線程共享變量的值,其他線程能夠立即得知這個(gè)修改

原子性:一系列的操作要么全部執(zhí)行完,要么都不執(zhí)行

有序性:如果在本線程內(nèi)觀察,所有操作都是有序的;如果在一個(gè)線程中觀察另一個(gè)線程,所有操作都是無序的。前半句是指“線程內(nèi)表現(xiàn)為串行語義”,后半句是指“指令重排序”現(xiàn)象和“工作內(nèi)存中主內(nèi)存同步延遲”現(xiàn)象。

synchronized具有原子性,可見性,有序性,同一時(shí)刻只能有一個(gè)線程進(jìn)行獲??;會(huì)造成線程阻塞;標(biāo)記的變量會(huì)被編譯器優(yōu)化;可以使用在變量,方法,類級(jí)別中

volatile具有可見性,有序性,不能保證原子性,(需要保證原子性,1:運(yùn)算結(jié)果不依賴變量的當(dāng)前值,或者只有一個(gè)線程修改變量的值;2:該變量沒有包含在具有其他變量的不變式中);不會(huì)造成線程阻塞;標(biāo)記的變量不會(huì)被編譯器優(yōu)化(防止指令重排);只能使用在變量級(jí)別

2.Java的集合類

Java的集合類是放在java.util包下;集合類存放的是對(duì)象的引用,而非對(duì)象的本身;集合類主要分為Set(集),List(列表),Map(映射)。

List和Set是Collection(接口)的子類。

Set:不能包含重復(fù)的元素,沒有順序

List:

  1. ArrayList:是List的子類,底層是動(dòng)態(tài)擴(kuò)容的數(shù)組結(jié)構(gòu)??梢源娣胖貜?fù)的元素(包括null);有序,按照元素的添加順序,多用于查詢多增刪操作少的情況,ArrayList是線程異步的,是不安全。

    擴(kuò)容機(jī)制:每次擴(kuò)容的大小是原來的1.5倍;擴(kuò)容的過程其實(shí)就是一個(gè)將原來元素拷貝到一個(gè)擴(kuò)容后數(shù)組大小的長(zhǎng)度新數(shù)組中,所以ArrayList的擴(kuò)容其實(shí)是相對(duì)來說是比較消耗性能的。經(jīng)常出現(xiàn)的一個(gè)異常:ConcurrentModificationException,在foreach循環(huán)的時(shí)候,進(jìn)行了刪除操作,集合的長(zhǎng)度產(chǎn)生的變化,

  2. LinkedList:LinkedList是一種可以在任何位置進(jìn)行高效地插入和刪除操作的有序序列,多用于增刪操作多的情況下。底層實(shí)現(xiàn)的數(shù)據(jù)結(jié)構(gòu)是雙向鏈表。也是不安全的

Map是util包下另一個(gè)集合類,是以key-value形式,鍵不能重復(fù),值可以重復(fù)。對(duì)Map集合遍歷時(shí)先得到鍵的set集合,再對(duì)set集合進(jìn)行遍歷,得到相應(yīng)的值。

HashMap:

  1. 存儲(chǔ)數(shù)據(jù)是根據(jù)鍵值對(duì)存儲(chǔ)數(shù)據(jù)的,并且存儲(chǔ)多個(gè)數(shù)據(jù)時(shí),數(shù)據(jù)的鍵不能相同,如果相同該鍵之前對(duì)應(yīng)的值將被覆蓋。
  2. HashMap最多只允許一條存儲(chǔ)數(shù)據(jù)的鍵為null,可允許多條數(shù)據(jù)的值為null。
  3. HashMap存儲(chǔ)數(shù)據(jù)的順序是不確定的,并且可能會(huì)因?yàn)閿U(kuò)容導(dǎo)致元素存儲(chǔ)位置改變。因此遍歷順序是不確定的。
  4. HashMap是線程不安全的,使用ConcurrentHashMap具有線程安全。

底層存儲(chǔ)結(jié)構(gòu):

JDK1.7之前的存儲(chǔ)結(jié)構(gòu):

拉鏈法,專業(yè)點(diǎn)就叫鏈地址法。就是數(shù)組加鏈表的結(jié)合。每一個(gè)數(shù)組元素上存儲(chǔ)的都是一個(gè)鏈表。新添加進(jìn)來的元素總是放在數(shù)組對(duì)應(yīng)的角標(biāo)位置,而原來處于該角標(biāo)的位置的節(jié)點(diǎn)作為next節(jié)點(diǎn)放到新節(jié)點(diǎn)的后邊。

JDK1.8中的數(shù)據(jù)結(jié)構(gòu):

如果單單是數(shù)組加鏈表的話,當(dāng)處理hash值沖突較多的情況下,鏈表的長(zhǎng)度會(huì)越來越長(zhǎng),查找的效率會(huì)越來越低了。所以在1.8中當(dāng)新增節(jié)點(diǎn)導(dǎo)致鏈表的長(zhǎng)度超過8的時(shí)候,就會(huì)在添加元素的同事將單鏈表轉(zhuǎn)化為紅黑樹。紅黑樹是一種易于增刪改查的二叉樹,這樣HashMap中的元素操作起來就會(huì)更高效。

3. Java中的引用

  • StrongReference(強(qiáng)引用):從不回收,對(duì)象一直存在,垃圾回收器絕對(duì)不會(huì)回收它;當(dāng)JVM停止的時(shí)候才被終止
  • SoftReference(軟引用):可以和引用隊(duì)列(ReferenceQueue)聯(lián)合使用;內(nèi)存足夠,不會(huì)回收,內(nèi)存不夠就會(huì)回收;
  • WeakReference(弱引用):可以和引用隊(duì)列(ReferenceQueue)聯(lián)合使用,當(dāng)內(nèi)存不足時(shí),觸發(fā)GC后被終止。多用于內(nèi)存泄漏的解決;可以通過手動(dòng)GC進(jìn)行清除。
  • PhantomReference(虛引用):必須和引用隊(duì)列(ReferenceQueue)聯(lián)合使用,隨時(shí)會(huì)被回收,觸發(fā)GC后被終止

4. Java GC回收機(jī)制

GC機(jī)制:是Java虛擬機(jī)垃圾回收器提供的一種用于在空閑時(shí)間不定時(shí)回收無任何對(duì)象引用的對(duì)象占據(jù)的內(nèi)存空間的一種機(jī)制。

JVM把內(nèi)存劃分成了下面幾個(gè)區(qū)域:

  • 程序計(jì)數(shù)器

    每一個(gè)線程都有它自己的程序計(jì)數(shù)器,并且任何時(shí)間一個(gè)線程都只有一個(gè)方法在執(zhí)行,也就是所謂的當(dāng)前方法。會(huì)存儲(chǔ)當(dāng)前線程正在執(zhí)行的Java方法的JVM指令地址;如果是本地方法,則是未指定值(undefined)。

  • 方法區(qū)

    用于存儲(chǔ)所謂的元數(shù)據(jù),例如類的信息(名稱,修飾符等)、運(yùn)行時(shí)常量池、類中的字段和方法等。方法區(qū)GC,條件比較苛刻

    運(yùn)行時(shí)常量池:常量池可以存放各種常量信息,不管是編譯器生成的各種字面量,還是需要在運(yùn)行時(shí)決定的符號(hào)引用。

  • 堆區(qū)

    是Java內(nèi)存管理的核心區(qū)域,用來放置Java對(duì)象實(shí)例,幾乎所有創(chuàng)建的Java對(duì)象實(shí)例都是被直接分配在堆上的。所以堆區(qū)是GC最頻繁的

  • Java虛擬機(jī)棧

    每個(gè)線程在創(chuàng)建時(shí)都會(huì)創(chuàng)建一個(gè)虛擬機(jī)棧,線程私有,生命周期和線程一樣,每一個(gè)方法被調(diào)用時(shí)產(chǎn)生一個(gè)棧幀。JVM直接對(duì)Java棧的操作只有兩個(gè),就是對(duì)棧幀的壓棧和出棧。

    棧幀中存儲(chǔ)著局部變量表、操作數(shù)、動(dòng)態(tài)鏈接、方法出口。

  • 本地方法棧

    和Java虛擬機(jī)棧非常相似,支持對(duì)本地方法的調(diào)用,也是每個(gè)線程都會(huì)創(chuàng)建一個(gè)。

方法區(qū)和堆歸所有線程共享

在上面介紹的五個(gè)內(nèi)存區(qū)域中,有3個(gè)是不需要進(jìn)行垃圾回收的:本地方法棧、程序計(jì)數(shù)器、虛擬機(jī)棧。因?yàn)樗麄兊纳芷谑呛途€程同步的,隨著線程的銷毀,他們占用的內(nèi)存會(huì)自動(dòng)釋放。所以,只有方法區(qū)和堆區(qū)需要進(jìn)行垃圾回收,回收的對(duì)象就是那些不存在任何引用的對(duì)象。

GC算法:

經(jīng)典的引用計(jì)數(shù)算法,很難處理循環(huán)引用關(guān)系,所以Java并沒有采用這種方法。而是采用追蹤性垃圾收集,就是根搜索算法。

常見的垃圾收集算法:

  • 復(fù)制算法:高效,但是需要提前預(yù)留空間,有一定浪費(fèi)。
  • 標(biāo)記-清除:先進(jìn)行標(biāo)記,標(biāo)記處所有要回收的對(duì)象,然后進(jìn)行清除。有碎片化的問題,不適合特別大的堆。
  • 標(biāo)記-整理:類似清除,但是為了避免內(nèi)存碎片化,在清理過程中將對(duì)象移動(dòng),以確保移動(dòng)后的對(duì)象占用連續(xù)的內(nèi)存空間。

5.Java的內(nèi)存模型

Java內(nèi)存模型(Java Memory Model ,JMM)就是一種符合內(nèi)存模型規(guī)范的,屏蔽了各種硬件和操作系統(tǒng)的訪問差異的,保證了Java程序在各種平臺(tái)下對(duì)內(nèi)存的訪問都能保證效果一致的機(jī)制及規(guī)范。

6.多進(jìn)程和多線程

進(jìn)程是資源分配的最小單位,線程是CPU調(diào)度的最小單位

7. 線程的休眠方式,sleep和wait哪個(gè)會(huì)釋放鎖?

sleep是Thread類的方法,不會(huì)釋放對(duì)象鎖。

wait是Objec類的方法,線程會(huì)釋放對(duì)象鎖,可以用notify()或者notifyAll()喚醒。

8. String、StringBuffer、StringBuilder的區(qū)別

都是被final修飾的,都不允許被繼承。

String長(zhǎng)度固定,StringBuffer和StringBuilder長(zhǎng)度是可以改變的;StringBuffer是線程安全的,StringBuilder不是線程安全的。StringBuffer多用于多線程,操作大量數(shù)據(jù),StringBuilder用于單線程操作大量數(shù)據(jù),效率優(yōu)于StringBuffer;拼接字符串不建議使用+,因?yàn)閮?nèi)部也是額外創(chuàng)建StringBuffer來完成的。

9. 抽象類和接口有什么區(qū)別?

共同點(diǎn):是上層的抽象層。 都不能被實(shí)例化。 都能包含抽象的方法,這些抽象的方法用于描述類具備的功能,但是不會(huì)提供具體的實(shí)現(xiàn)。

區(qū)別:抽象類里面可以寫非抽象方法,接口中只能有抽象方法;類只能繼承一個(gè)類,可以是抽象類。類可以實(shí)現(xiàn)多個(gè)接口。抽象類抽象方法可以用所有修飾符修飾,接口里面的方法都是public,在JDK1.8允許一個(gè)靜態(tài)方法和多個(gè)Default方法。抽象類可以有構(gòu)造方法,接口不能有構(gòu)造器。

10.單例模式,雙判空懶漢單例模式,為什么變量用volitale修飾,new不是原子操作

用volitale修飾,是禁止指令重排。new不是原子操作,有多個(gè)步驟。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 所有知識(shí)點(diǎn)已整理成app app下載地址 J2EE 部分: 1.Switch能否用string做參數(shù)? 在 Jav...
    侯蛋蛋_閱讀 2,701評(píng)論 1 4
  • 第二部分 自動(dòng)內(nèi)存管理機(jī)制 第二章 java內(nèi)存異常與內(nèi)存溢出異常 運(yùn)行數(shù)據(jù)區(qū)域 程序計(jì)數(shù)器:當(dāng)前線程所執(zhí)行的字節(jié)...
    小明oh閱讀 1,275評(píng)論 0 2
  • 一:java概述: 1,JDK:Java Development Kit,java的開發(fā)和運(yùn)行環(huán)境,java的開發(fā)...
    慕容小偉閱讀 1,939評(píng)論 0 10
  • 整理來自互聯(lián)網(wǎng) 1,JDK:Java Development Kit,java的開發(fā)和運(yùn)行環(huán)境,java的開發(fā)工具...
    Ncompass閱讀 1,617評(píng)論 0 6
  • 一、運(yùn)行時(shí)數(shù)據(jù)區(qū)域 Java虛擬機(jī)管理的內(nèi)存包括幾個(gè)運(yùn)行時(shí)數(shù)據(jù)內(nèi)存:方法區(qū)、虛擬機(jī)棧、本地方法棧、堆、程序計(jì)數(shù)器,...
    luhanlin閱讀 602評(píng)論 0 0

友情鏈接更多精彩內(nèi)容