最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

Java八股文大全

2023-02-19 15:55 作者:南京落葉--文軍  | 我要投稿


一、Java基礎(chǔ)篇

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

(1)抽象類可以有構(gòu)造方法,而接口沒有

(2)抽象類可以有抽象方法和具體方法,接口只能有抽象方法

(3)抽象類的成員4種權(quán)限修飾符都可以修飾,接口只能用private

2.重載和重寫的區(qū)別

重載發(fā)生在同一個類中,方法名相同、參數(shù)列表、返回類型、權(quán)限修飾符可以不同

重寫發(fā)生在子類中,方法名相、參數(shù)列表、返回類型都相同,權(quán)限修飾符要大于父類方法,聲明異常范圍要小于父類方法,但是final和private修飾的方法不可重寫

3.==和equals的區(qū)別

==比較基本類型,比較的是值,==比較引用類型,比較的是內(nèi)存地址

equlas是Object類的方法,本質(zhì)上與==一樣,但是有些類重寫了equals方法,比如String的equals被重寫后,比較的是內(nèi)存地址,另外重寫了equlas后,也必須重寫hashcode()方法

4.異常處理機制

(1)使用try、catch、finaly捕獲異常,finaly中的代碼一定會執(zhí)行,捕獲異常后程序會繼續(xù)執(zhí)行

(2)使用throws聲明該方法可能會拋出的異常類型,出現(xiàn)異常后,程序終止

5.HashMap原理

1.HashMap在Jdk1.8以后是基于數(shù)組+鏈表+紅黑樹來實現(xiàn)的,特點是,key不能重復(fù),可以為null,線程不安全

2.HashMap的擴容機制:

HashMap的默認容量為16,默認的負載因子為0.75,當(dāng)HashMap中元素個數(shù)超過容量乘以負載因子的個數(shù)時,就創(chuàng)建一個大小為前一次兩倍的新數(shù)組,再將原來數(shù)組中的數(shù)據(jù)復(fù)制到新數(shù)組中。當(dāng)數(shù)組長度到達64且鏈表長度大于8時,鏈表轉(zhuǎn)為紅黑樹

3.HashMap存取原理:

(1)計算key的hash值,然后進行二次hash,根據(jù)二次hash結(jié)果找到對應(yīng)的索引位置

(2)如果這個位置有值,先進性equals比較,若結(jié)果為true則取代該元素,若結(jié)果為false,就使用高低位平移法將節(jié)點插入鏈表(JDK8以前使用頭插法,但是頭插法在并發(fā)擴容時可能會造成環(huán)形鏈表或數(shù)據(jù)丟失,而高低位平移發(fā)會發(fā)生數(shù)據(jù)覆蓋的情況)

6.想要線程安全的HashMap怎么辦?

(1)使用ConcurrentHashMap

(2)使用HashTable

(3)Collections.synchronizedHashMap()方法

7.ConcurrentHashMap原如何保證的線程安全?

JDK1.7:使用分段鎖,將一個Map分為了16個段,每個段都是一個小的hashmap,每次操作只對其中一個段加鎖

JDK1.8:采用CAS+Synchronized保證線程安全,每次插入數(shù)據(jù)時判斷在當(dāng)前數(shù)組下標(biāo)是否是第一次插入,是就通過CAS方式插入,然后判斷f.hash是否=-1,是的話就說明其他線程正在進行擴容,當(dāng)前線程也會參與擴容;刪除方法用了synchronized修飾,保證并發(fā)下移除元素安全

8.HashTable與HashMap的區(qū)別

(1)HashTable的每個方法都用synchronized修飾,因此是線程安全的,但同時讀寫效率很低

(2)HashTable的Key不允許為null

(3)HashTable只對key進行一次hash,HashMap進行了兩次Hash

(4)HashTable底層使用的數(shù)組加鏈表

9.ArrayList和LinkedList的區(qū)別

ArratList的底層使用動態(tài)數(shù)組,默認容量為10,當(dāng)元素數(shù)量到達容量時,生成一個新的數(shù)組,大小為前一次的1.5倍,然后將原來的數(shù)組copy過來;

因為數(shù)組有索引,所以ArrayList查找數(shù)據(jù)更快,但是添加數(shù)據(jù)效率更低

LinkedList的底層使用鏈表,在內(nèi)存中是離散的,沒有擴容機制;LinkedList在查找數(shù)據(jù)時需要從頭遍歷,所以查找慢,但是添加數(shù)據(jù)效率更高

10.如何保證ArrayList的線程安全?

(1)使用collentions.synchronizedList()方法為ArrayList加鎖

(2)使用Vector,Vector底層與Arraylist相同,但是每個方法都由synchronized修飾,速度很慢

(3)使用juc下的CopyOnWriterArrayList,該類實現(xiàn)了讀操作不加鎖,寫操作時為list創(chuàng)建一個副本,期間其它線程讀取的都是原本list,寫操作都在副本中進行,寫入完成后,再將指針指向副本。

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

String 由 char[] 數(shù)組構(gòu)成,使用了 final 修飾,對 String 進行改變時每次都會新生成一個 String 對象,然后把指針指向新的引用對象。

StringBuffer可變并且線程安全;

StringBuiler不可變并且線程不安全。

操作少量字符數(shù)據(jù)用 String;單線程操作大量數(shù)據(jù)用 StringBuilder;多線程操作大量數(shù)據(jù)用 StringBuffer

二.Java多線程篇

1.進程和線程的區(qū)別

進程:系統(tǒng)運行的基本單位,包含多個線程

線程:獨立運行的最小單位,是進程的實體,多個線程共享同一進程內(nèi)的系統(tǒng)資源

2. 什么是線程上下文切換

當(dāng)一個線程被剝奪cpu使用權(quán)時,切換到另外一個線程執(zhí)行

3.什么是死鎖

死鎖指多個線程在執(zhí)行過程中,因爭奪資源造成的一種相互等待的僵局

4.死鎖的必要條件

互斥條件:同一資源同時只能由一個線程讀取

不可搶占條件:不能強行剝奪線程占有的資源

請求和保持條件:請求其他資源的同時對自己手中的資源保持不放

循環(huán)等待條件:在相互等待資源的過程中,形成一個閉環(huán)

想要預(yù)防死鎖,只需要破壞其中一個條件即可,銀行家算法可以預(yù)防死鎖

5.Synchrpnized和lock的區(qū)別

(1)synchronized是關(guān)鍵字,lock是一個類

(2) synchronized在發(fā)生異常時會自動釋放鎖,lock需要手動釋放鎖

(3)synchronized是可重入鎖、非公平鎖、不可中斷鎖,lock是可重入鎖,可中斷鎖,可以是公平鎖

6.sleep()和wait()的區(qū)別

(1)wait()是Object的方法,sleep()是Thread類的方法

(2)wait()會釋放鎖,sleep()不會釋放鎖

(3)wait()要在同步方法或者同步代碼塊中執(zhí)行,sleep()沒有限制

(4)wait()要調(diào)用notify()或notifyall()喚醒,sleep()自動喚醒

7.yield()和join()區(qū)別

yield()調(diào)用后線程進入就緒狀態(tài)

A線程中調(diào)用B線程的join() ,則B執(zhí)行完前A進入阻塞狀態(tài)

8.線程池七大參數(shù)

核心線程數(shù):線程池中的基本線程數(shù)量

最大線程數(shù):當(dāng)阻塞隊列滿了之后,逐一啟動

最大線程的存活時間:當(dāng)阻塞隊列的任務(wù)執(zhí)行完后,最大線長的回收時間

最大線程的存活時間單位

阻塞隊列:當(dāng)核心線程滿后,后面來的任務(wù)都進入阻塞隊列

線程工廠:用于生產(chǎn)線程

任務(wù)拒絕策略:阻塞隊列滿后,拒絕任務(wù),有四種策略(1)拋異常(2)丟棄任務(wù)不拋異常(3)打回任務(wù)(4)嘗試與最老的線程競爭

9.Java內(nèi)存模型

JMM(Java內(nèi)存模型 )屏蔽了各種硬件和操作系統(tǒng)的內(nèi)存訪問差異,實現(xiàn)讓Java程序在各平臺下都能達到一致的內(nèi)存訪問效果,它定義了JVM如何將程序中的變量在主存中讀取

具體定義為:所有變量都存在主存中,主存是線程共享區(qū)域;每個線程都有自己獨有的工作內(nèi)存,線程想要操作變量必須從主從中copy變量到自己的工作區(qū),每個線程的工作內(nèi)存是相互隔離的

由于主存與工作內(nèi)存之間有讀寫延遲,且讀寫不是原子性操作,所以會有線程安全問題

10.保證并發(fā)安全的三大特性?

原子性:一次或多次操作在執(zhí)行期間不被其他線程影響

可見性:當(dāng)一個線程在工作內(nèi)存修改了變量,其他線程能立刻知道

有序性:JVM對指令的優(yōu)化會讓指令執(zhí)行順序改變,有序性是禁止指令重排

11.volatile

保證變量的可見性和有序性,不保證原子性。使用了 volatile 修飾變量后,在變量修改后會立即同步到主存中,每次用這個變量前會從主存刷新。

單例模式雙重校驗鎖變量為什么使用 volatile 修飾? 禁止 JVM 指令重排序,new Object()分為三個步驟:申請內(nèi)存空間,將內(nèi)存空間引用賦值給變量,變量初始化。如果不禁止重排序,有可能得到一個未經(jīng)初始化的變量。

12.線程使用方式

(1)繼承 Tread 類

(2)實現(xiàn) Runnable 接口

(3)實現(xiàn) Callable 接口:帶有返回值

13.ThreadLocal原理

原理是為每個線程創(chuàng)建變量副本,不同線程之間不可見,保證線程安全。每個線程內(nèi)部都維護了一個Map,key為threadLocal實例,value為要保存的副本。

但是使用ThreadLocal會存在內(nèi)存泄露問題,因為key為弱引用,而value為強引用,每次gc時key都會回收,而value不會被回收。所以為了解決內(nèi)存泄漏問題,可以在每次使用完后刪除value或者使用static修飾ThreadLocal,可以隨時獲取value

14.什么是CAS鎖

CAS鎖可以保證原子性,思想是更新內(nèi)存時會判斷內(nèi)存值是否被別人修改過,如果沒有就直接更新。如果被修改,就重新獲取值,直到更新完成為止。這樣的缺點是

(1)只能支持一個變量的原子操作,不能保證整個代碼塊的原子操作

(2)CAS頻繁失敗導(dǎo)致CPU開銷大

(3)ABS問題:線程1和線程2同時去修改一個變量,將值從A改為B,但線程1突然阻塞,此時線程2將A改為B,然后線程3又將B改成A,此時線程1將A又改為B,這個過程線程2是不知道的,這就是ABA問題,可以通過版本號或時間戳解決

15.Synchronized鎖原理和優(yōu)化

Synchronize是通過對象頭的markwordk來表明監(jiān)視器的,監(jiān)視器本質(zhì)是依賴操作系統(tǒng)的互斥鎖實現(xiàn)的。操作系統(tǒng)實現(xiàn)線程切換要從用戶態(tài)切換為核心態(tài),成本很高,此時這種鎖叫重量級鎖,在JDK1.6以后引入了偏向鎖、輕量級鎖、重量級鎖

偏向鎖:當(dāng)一段代碼沒有別的線程訪問,此時線程去訪問會直接獲取偏向鎖

輕量級鎖:當(dāng)鎖是偏向鎖時,有另外一個線程來訪問,偏向鎖會升級為輕量級鎖,這個線程會通過自旋方式不斷獲取鎖,不會阻塞,提高性能

重量級鎖:輕量級鎖自旋一段時間后線程還沒有獲取到鎖,線程就會進入阻塞狀態(tài),該鎖會升級為重量級鎖,重量級鎖時,來競爭鎖的所有線程都會阻塞,性能降低

注意,鎖只能升級不能降級

16.JUC常用輔助類

CountDownLatch:設(shè)定一個數(shù),當(dāng)調(diào)用CountDown()時數(shù)量減一,當(dāng)調(diào)用await() 時判斷計數(shù)器是否為0,不為0就阻塞,直到計數(shù)器為0

CyclicBarrier:設(shè)定一個數(shù),當(dāng)調(diào)用await() 時判斷計數(shù)器是否達到目標(biāo)值,未達到就阻塞,直到計數(shù)器達到目標(biāo)值

Semaphore:設(shè)定一個信號量,當(dāng)調(diào)用acquire()時判斷是否還有信號,有就信號量減一線程繼續(xù)執(zhí)行,沒有就阻塞等待其他線程釋放信號量,當(dāng)調(diào)用release()時釋放信號量,喚醒阻塞線程

17.如何根據(jù) CPU 核心數(shù)設(shè)計線程池線程數(shù)量

IO 密集型:核心數(shù)*2

計算密集型: 核心數(shù)+1

為什么加 1?即使當(dāng)計算密集型的線程偶爾由于缺失故障或者其他原因而暫停時,這個額外的線程也能確保 CPU 的時鐘周期不會被浪費。

三.JVM篇

1.JVM運行時數(shù)據(jù)區(qū)(內(nèi)存結(jié)構(gòu))

線程私有區(qū):

(1)虛擬機棧:每次調(diào)用方法都會在虛擬機棧中產(chǎn)生一個棧幀,每個棧幀中都有方法的參數(shù)、局部變量、方法出口等信息,方法執(zhí)行完畢后釋放棧幀

(2)本地方法棧:為native修飾的本地方法提供的空間,在HotSpot中與虛擬機合二為一

(3)程序計數(shù)器:保存指令執(zhí)行的地址,方便線程切回后能繼續(xù)執(zhí)行代碼

線程共享區(qū):

(4)堆內(nèi)存:Jvm進行垃圾回收的主要區(qū)域,存放對象信息,分為新生代和老年代

(5)方法區(qū):存放類信息、靜態(tài)變量、常量、運行時常量池等信息。JDK1.8之前用持久代實現(xiàn),JDK1.8后用元空間實現(xiàn),元空間使用的是本地內(nèi)存,而非在JVM內(nèi)存結(jié)構(gòu)中

2.什么情況下會內(nèi)存溢出?

堆內(nèi)存溢出:(1)當(dāng)對象一直創(chuàng)建而不被回收時(2)加載的類越來越多時(3)虛擬機棧的線程越來越多時

棧溢出:方法調(diào)用次數(shù)過多,一般是遞歸不當(dāng)造成

3.JVM有哪些垃圾回收算法?

(1)標(biāo)記清除算法: 標(biāo)記不需要回收的對象,然后清除沒有標(biāo)記的對象,會造成許多內(nèi)存碎片。

(2)復(fù)制算法: 將內(nèi)存分為兩塊,只使用一塊,進行垃圾回收時,先將存活的對象復(fù)制到另一塊區(qū)域,然后清空之前的區(qū)域。用在新生代

(3)標(biāo)記整理算法: 與標(biāo)記清除算法類似,但是在標(biāo)記之后,將存活對象向一端移動,然后清除邊界外的垃圾對象。用在老年代

4.GC如何判斷對象可以被回收?

(1)引用計數(shù)法:已淘汰,為每個對象添加引用計數(shù)器,引用為0時判定可以回收,會有兩個對象相互引用無法回收的問題

(2)可達性分析法:從GCRoot開始往下搜索,搜索過的路徑稱為引用鏈,若一個對象GCRoot沒有任何的引用鏈,則判定可以回收

GCRoot有:虛擬機棧中引用的對象,方法區(qū)中靜態(tài)變量引用的對象,本地方法棧中引用的對象

5.典型垃圾回收器

G1 :JDK1.9以后的默認垃圾回收器,支持并發(fā),采用標(biāo)記整理+復(fù)制算法,注重響應(yīng)速度

6.類加載器和雙親委派機制

從父類加載器到子類加載器分別為:

BootStrapClassLoader ? ?加載路徑為:JAVA_HOME/jre/lib

ExtensionClassLoader ? ?加載路徑為:JAVA_HOME/jre/lib/ext

ApplicationClassLoader ?加載路徑為:classpath

還有一個自定義類加載器

當(dāng)一個類加載器收到類加載請求時,會先把這個請求交給父類加載器處理,若父類加載器找不到該類,再由自己去尋找。該機制可以避免類被重復(fù)加載,還可以避免系統(tǒng)級別的類被篡改

7.類加載過程

(1)加載 :加載字節(jié)碼文件,將字節(jié)碼中的靜態(tài)變量和常量轉(zhuǎn)換到方法區(qū)中,在堆中生成class對象作為方法區(qū)入口

(2)連接:

驗證:驗證字節(jié)碼文件的正確性。

準(zhǔn)備:正式為類變量在方法區(qū)中分配內(nèi)存,并設(shè)置初始值。

解析:將符號引用(如類的全限定名)解析為直接引用(類在實際內(nèi)存中的地址)。()

(3)初始化 :執(zhí)行類構(gòu)造器(不是常規(guī)的構(gòu)造方法),為靜態(tài)變量賦初值并初始化靜態(tài)代碼塊。

8.JVM中有哪些引用?

強引用:new的對象。哪怕內(nèi)存溢出也不會回收

軟引用:只有內(nèi)存不足時才會回收

弱引用:每次垃圾回收都會回收

虛引用:必須配合引用隊列使用,一般用于追蹤垃圾回收動作

9.對象頭中有哪些信息

對象頭中有兩部分,一部分是MarkWork,存儲對象運行時的數(shù)據(jù),如GC分代年齡、GC標(biāo)記、鎖的狀態(tài)、線程ID等;另外一部分是指向?qū)ο箢愋偷闹羔槪绻菙?shù)組,還有一個部分存放數(shù)組長度

10.JVM內(nèi)存參數(shù)

-Xmx[]:堆空間最大內(nèi)存

-Xms[]:堆空間最小內(nèi)存,一般設(shè)置成跟堆空間最大內(nèi)存一樣的

-Xmn[]:新生代的最大內(nèi)存

-xx[use 垃圾回收器名稱]:指定垃圾回收器

-xss:設(shè)置單個線程棧大小

一般設(shè)堆空間為最大可用物理地址的百分之80

11.JVM類初始化順序

父類靜態(tài)代碼塊和靜態(tài)成員變量->子類靜態(tài)代碼塊和靜態(tài)成員變量->父類代碼塊和普通成員變量->父類構(gòu)造方法->子類代碼塊和普成員變量->子類構(gòu)造方法

四.Mysql篇

1.MyIAm和InnoDB的區(qū)別

InnoDB支持事務(wù),MyIAm不支持

InnoDB支持外鍵,MyIAm不支持

InnoDB是聚簇索引,MyIAm是非聚簇索引

InnoDB支持行鎖和表鎖,MyIAm只支持表鎖

InnoDB不支持全文索引,MyIAm支持

InnoDB支持自增和MVCC模式的讀寫,MyIAm不支持

2.mysql事務(wù)特性

原子性:一個事務(wù)內(nèi)的操作統(tǒng)一成功或失敗

一致性:事務(wù)前后的數(shù)據(jù)總量不變

隔離性:事務(wù)與事務(wù)之間相互不影響

持久性:事務(wù)一旦提交發(fā)生的改變不可逆

3.事務(wù)靠什么保證

原子性:由undolog日志保證,他記錄了需要回滾的日志信息,回滾時撤銷已執(zhí)行的sql

一致性:由其他三大特性共同保證,是事務(wù)的目的

隔離性:由MVCC保證

持久性:由redolog日志和內(nèi)存保證,mysql修改數(shù)據(jù)時內(nèi)存和redolog會記錄操作,宕機時可恢復(fù)

4.事務(wù)的隔離級別

在高并發(fā)情況下,并發(fā)事務(wù)會產(chǎn)生臟讀、不可重復(fù)讀、幻讀問題,這時需要用隔離級別來控制

讀未提交: 允許一個事務(wù)讀取另一個事務(wù)已提交的數(shù)據(jù),可能出現(xiàn)不可重復(fù)讀,幻讀。

讀提交: ? ?只允許事務(wù)讀取另一個事務(wù)沒有提交的數(shù)據(jù)可能出現(xiàn)不可重復(fù)讀,幻讀。

可重復(fù)讀: 確保同一字段多次讀取結(jié)果一致,可能出現(xiàn)歡幻讀。

可串行化: 所有事務(wù)逐次執(zhí)行,沒有并發(fā)問日

Inno DB 默認隔離級別為可重復(fù)讀級別,分為快照度和當(dāng)前讀,并且通過間隙鎖解決了幻讀問題。

5.什么是快照讀和當(dāng)前讀

*快照讀讀取的是當(dāng)前數(shù)據(jù)的可見版本,可能是會過期數(shù)據(jù),不加鎖的select就是快照都

*當(dāng)前讀讀取的是數(shù)據(jù)的最新版本,并且當(dāng)前讀返回的記錄都會上鎖,保證其他事務(wù)不會并發(fā)修改這條記錄。如update、insert、delete、select for undate(排他鎖)、select lockin share mode(共享鎖) 都是當(dāng)前讀

6.MVCC是什么

MVCC是多版本并發(fā)控制,為每次事務(wù)生成一個新版本數(shù)據(jù),每個事務(wù)都由自己的版本,從而不加鎖就決絕讀寫沖突,這種讀叫做快照讀。只在讀已提交和可重復(fù)讀中生效。

實現(xiàn)原理由四個東西保證,他們是

undolog日志:記錄了數(shù)據(jù)歷史版本

readView:事務(wù)進行快照讀時產(chǎn)生的視圖,記錄了當(dāng)前系統(tǒng)中活躍的事務(wù)id,控制哪個歷史版本對當(dāng)前事務(wù)可見

隱藏字段DB_TRC_ID: 最近修改記錄的事務(wù)ID

隱藏字段DB_Roll_PTR: 回滾指針,配合undolog指向數(shù)據(jù)的上一個版本

7.MySQL有哪些索引

主鍵索引:一張表只能有一個主鍵索引,主鍵索引列不能有空值和重復(fù)值

唯一索引:唯一索引不能有相同值,但允許為空

普通索引:允許出現(xiàn)重復(fù)值

組合索引:對多個字段建立一個聯(lián)合索引,減少索引開銷,遵循最左匹配原則

全文索引:myisam引擎支持,通過建立倒排索引提升檢索效率,廣泛用于搜索引擎

8.聚簇索引和非聚簇索引的區(qū)別

聚簇索引:將索引和值放在了一起,根據(jù)索引可以直接獲取值,如果主鍵值很大的話,輔助索引也會變得很大

非聚簇索引:葉子節(jié)點存放的是數(shù)據(jù)行地址,先根據(jù)索引找到數(shù)據(jù)地址,再根據(jù)地址去找數(shù)據(jù)

他們都是b+數(shù)結(jié)構(gòu)

9.B和B+數(shù)的區(qū)別,為什么使用B+數(shù)

二叉樹:索引字段有序,極端情況會變成鏈表形式

AVL數(shù):樹的高度不可控

B數(shù):控制了樹的高度,但是索引值和data都分布在每個具體的節(jié)點當(dāng)中,若要進行范圍查詢,要進行多次回溯,IO開銷大

B+樹:非葉子節(jié)點只存儲索引值,葉子節(jié)點再存儲索引+具體數(shù)據(jù),從小到大用鏈表連接在一起,范圍查詢可直接遍歷不需要回溯7

10.MySQL有哪些鎖

基于粒度:

*表級鎖:對整張表加鎖,粒度大并發(fā)小

*行級鎖:對行加鎖,粒度小并發(fā)大

*間隙鎖:間隙鎖,鎖住表的一個區(qū)間,間隙鎖之間不會沖突只在可重復(fù)讀下才生效,解決了幻讀

基于屬性:

*共享鎖:又稱讀鎖,一個事務(wù)為表加了讀鎖,其它事務(wù)只能加讀鎖,不能加寫鎖

*排他鎖:又稱寫鎖,一個事務(wù)加寫鎖之后,其他事務(wù)不能再加任何鎖,避免臟讀問題

11.MySQL如果做慢查詢優(yōu)化

(1)分析sql語句,是否加載了不需要的數(shù)據(jù)列

(2)分析sql執(zhí)行計劃,字段有沒有索引,索引是否失效,是否用對索引

(3)表中數(shù)據(jù)是否太大,是不是要分庫分表

12.哪些情況索引會失效

(1)where條件中有or,除非所有查詢條件都有索引,否則失效

(2)like查詢用%開頭,索引失效

(3)索引列參與計算,索引失效

(4)違背最左匹配原則,索引失效

(5)索引字段發(fā)生類型轉(zhuǎn)換,索引失效

(6)mysql覺得全表掃描更快時(數(shù)據(jù)少),索引失效

13.Mysql內(nèi)連接、左連接、右連接的區(qū)別

內(nèi)連接取量表交集部分,左連接取左表全部右表匹部分,右連接取右表全部坐表匹部分

五.Spring系列(spring全家桶)

1.Bean 的作用域

(1)Singleton:一個IOC容器只有一個

(2)Prototype:每次調(diào)用getBean()都會生成一個新的對象

(3)request:每個http請求都會創(chuàng)建一個自己的bean

(4)session:同一個session共享一個實例

(5)application:整個serverContext只有一個bean

(6)webSocket:一個websocket只有一個bean

2.Bean 生命周期

實例化 Instantiation->屬性賦值 Populate->初始化 Initialization->銷毀 Destruction

在這四步的基礎(chǔ)上面,Spring 提供了一些拓展點:

*Bean 自身的方法: 包括了 Bean 本身調(diào)用的方法和通過配置文件中的 init-method 和 destroy-method 指定的方法

*Bean 級生命周期接口方法:包括了 BeanNameAware、BeanFactoryAware、InitializingBean 和 DiposableBean 這些接口的方法

*容器級生命周期接口方法:包括了 InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 這兩個接口實現(xiàn),一般稱它們的實現(xiàn)類為“后處理器”。

*工廠后處理器接口方法: 包括了 AspectJWeavingEnabler, ConfigurationClassPostProcessor, CustomAutowireConfigurer 等等非常有用的工廠后處理器接口的方法。工廠后處理器也是容器級的。在應(yīng)用上下文裝配配置文件之后立即調(diào)用。

3.Spring 事務(wù)原理?

spring事務(wù)有編程式和聲明式,我們一般使用聲明式,在某個方法上增加@Transactional注解,這個方法中的sql會統(tǒng)一成功或失敗。

原理是:

當(dāng)一個方法加上@Transactional注解,spring會基于這個類生成一個代理對象并將這個代理對象作為bean,當(dāng)使用這個bean中的方法時,如果存在@Transactional注解,就會將事務(wù)自動提交設(shè)為false,然后執(zhí)行方法,執(zhí)行過程沒有異常則提交,有異常則回滾、

4.spring事務(wù)失效場景

(1)事務(wù)方法所在的類沒有加載到容器中

(2)事務(wù)方法不是public類型

(3)同一類中,一個沒有添加事務(wù)的方法調(diào)用另外以一個添加事務(wù)的方法,事務(wù)不生效

(4)spring事務(wù)默認只回滾運行時異常,可以用rollbackfor屬性設(shè)置

(5)業(yè)務(wù)自己捕獲了異常,事務(wù)會認為程序正常秩序

5.spring事務(wù)的隔離級別

default:默認級別,使用數(shù)據(jù)庫自定義的隔離級別

其它四種隔離級別與mysql一樣

6.spring事務(wù)的傳播行為

(1)支持當(dāng)前事務(wù),如果不存在,則新啟一個事務(wù)

(2)支持當(dāng)前事務(wù),如果不存在,則拋出異常

(3)支持當(dāng)前事務(wù),如果不存在,則以非事務(wù)方式執(zhí)行

(4)不支持當(dāng)前事務(wù),創(chuàng)建一個新事物

(5)不支持當(dāng)前事務(wù),如果已存在事務(wù)就拋異常

(6)不支持當(dāng)前事務(wù),始終以非事務(wù)方式執(zhí)行

7.Spring IoC

8.spring用了哪些設(shè)計模式

BeanFactory用了工廠模式,AOP用了動態(tài)代理模式,RestTemplate用來模板方法模式,SpringMVC中handlerAdaper用來適配器模式,Spring里的監(jiān)聽器用了觀察者模式

9.SpringMV工作原理

SpringMVC工作過程圍繞著前端控制器DispatchServerlet,幾個重要組件有HandleMapping(處理器映射器)、HandleAdapter(處理器適配器)、ViewReslover(試圖解析器)

工作流程:

(1)DispatchServerlet接收用戶請求將請求發(fā)送給HandleMapping

(2)HandleMapping根據(jù)請求url找到具體的handle和攔截器,返回給DispatchServerlet

(3)DispatchServerlet調(diào)用HandleAdapter,HandleAdapter執(zhí)行具體的controller,并將controller返回的ModelAndView返回給DispatchServler

(4)DispatchServerlet將ModelAndView傳給ViewReslover,ViewReslover解析后返回具體view

(5)DispatchServerlet根據(jù)view進行視圖渲染,返回給用戶


10.springboot自動配置原理

啟動類@SpringbootApplication注解下,有三個關(guān)鍵注解

(1)@springbootConfiguration:表示啟動類是一個自動配置類

(2)@CompontScan:掃描啟動類所在包外的組件到容器中

(3)@EnableConfigutarion:最關(guān)鍵的一個注解,他擁有兩個子注解,其中@AutoConfigurationpackageu會將啟動類所在包下的所有組件到容器中,@Import會導(dǎo)入一個自動配置文件選擇器,他會去加載META_INF目錄下的spring.factories文件,這個文件中存放很大自動配置類的全類名,這些類會根據(jù)元注解的裝配條件生效,生效的類就會被實例化,加載到ioc容器中

11.springboot常用注解

@RestController ? ? ? ? ? ? ? ? ?:修飾類,該控制器會返回Json數(shù)據(jù)

@RequestMapping("/path") :修飾類,該控制器的請求路徑

@Autowired ? ? ? ? ? ? ? ? ? ? ? ? : ?修飾屬性,按照類型進行依賴注入

@PathVariable ? ? ? ? ? ? ? ? ? ? : ?修飾參數(shù),將路徑值映射到參數(shù)上

@ResponseBody ? ? ? ? ? ? ? ? :修飾方法,該方法會返回Json數(shù)據(jù)

@RequestBody(需要使用Post提交方式) :修飾參數(shù),將Json數(shù)據(jù)封裝到對應(yīng)參數(shù)中

@Controller@Service@Compont: ?將類注冊到ioc容器

六.Redis系列

1.redis為什么快?

(1)完全基于內(nèi)存操作,數(shù)據(jù)都存在內(nèi)存中

(2)采用單線程,避免了不必要的上下文切換帶來的性能問題,也不用考慮鎖的問題

(3)基于非阻塞的io多路復(fù)用機制

(4)數(shù)據(jù)結(jié)構(gòu)簡單,對數(shù)據(jù)操作簡單

2.redis持久化機制

(1)快照持久化RDB

redis的默認持久化機制,通過父進程fork一個子進程,子進程將redis的數(shù)據(jù)快照寫入一個臨時文件,等待持久化完畢后替換上一次的rdb文件。整個過程主進程不進行任何的io操作。持久化策略可以通過save配置單位時間內(nèi)執(zhí)行多少次操作觸發(fā)持久化。所以RDB的優(yōu)點是保證redis性能最大化,恢復(fù)速度數(shù)據(jù)較快,缺點是可能會丟失兩次持久化之間的數(shù)據(jù)

(2)追加持久化AOF

以日志形式記錄每一次的寫入和刪除操作,策略有每秒同步、每次操作同步、不同步,優(yōu)點是數(shù)據(jù)完整性高,缺點是運行效率低,恢復(fù)時間長

3.Redis如何實現(xiàn)key的過期刪除?

采用的定期過期+惰性過期

定期刪除 :Redis 每隔一段時間從設(shè)置過期時間的 key 集合中,隨機抽取一些 key ,檢查是否過期,如果已經(jīng)過期做刪除處理。

惰性刪除 :Redis 在 key 被訪問的時候檢查 key 是否過期,如果過期則刪除。

4.Redis數(shù)據(jù)類型

String ?常用命令: set,get,decr,incr,mget等

Hash ? 常用命令: hget,hset,hgetall 等

List ? ? 常用命令: lpush,rpush,lpop,rpop,lrange 等

Set ? ? 常用命令: sadd,spop,smembers,sunion 等

SortSet 常用命令: zadd,zrange,zrem,zcard 等

5.Redis緩存穿透如何解決?

緩存穿透是指頻繁請求客戶端和緩存中都不存在的數(shù)據(jù),緩存永遠不生效,請求都到達了數(shù)據(jù)庫。

解決方案:

(1)在接口上做基礎(chǔ)校驗,比如id<=0就攔截

(2)緩存空對象:找不到的數(shù)據(jù)也緩存起來,并設(shè)置過期時間,可能會造成短期不一致

(3)布隆過濾器:在客戶端和緩存之間添加一個過濾器,攔截掉一定不存在的數(shù)據(jù)請求

6.Redis如何解決緩存擊穿?

緩存擊穿是值一個key非常熱點,key在某一瞬間失效,導(dǎo)致大量請求到達數(shù)據(jù)庫

解決方案:

(1)設(shè)置熱點數(shù)據(jù)永不過期

(2)給緩存重建的業(yè)務(wù)加上互斥鎖,缺點是性能低

7.Redis如何解決緩存雪崩?

緩存雪崩是值某一時間Key同時失效或redis宕機,導(dǎo)致大量請求到達數(shù)據(jù)庫

解決方案:

(1)搭建集群保證高可用

(2)進行數(shù)據(jù)預(yù)熱,給不同的key設(shè)置隨機的過期時間

(3)給緩存業(yè)務(wù)添加限流降級,通過加鎖或隊列控制操作redis的線程數(shù)量

(4)給業(yè)務(wù)添加多級緩存

8.Redis分布式鎖的實現(xiàn)原理

原理是使用setnx+setex命令來實現(xiàn),但是會有一系列問題:

(1)任務(wù)時常超過緩存時間,鎖自動釋放。可以使用Redision看門狗解決

(2)加鎖和釋放鎖的不是同一線程??梢栽赩alue中存入uuid,刪除時進行驗證。但是要注意驗證鎖和刪除鎖也不是一個原子性操作,可以用lua腳本使之成為原子性操作

(3)不可重入??梢允褂肦edision解決(實現(xiàn)機制類似AQS,計數(shù))

(4)redis集群下主節(jié)點宕機導(dǎo)致鎖丟失。使用紅鎖解決

9.Redis集群方案

(1)主從模式:個master節(jié)點,多個slave節(jié)點,master節(jié)點宕機slave自動變成主節(jié)點

(2)哨兵模式:在主從集群基礎(chǔ)上添加哨兵節(jié)點或哨兵集群,用于監(jiān)控master節(jié)點健康狀態(tài),通過投票機制選擇slave成為主節(jié)點

(3)分片集群:主從模式和哨兵模式解決了并發(fā)讀的問題,但沒有解決并發(fā)寫的問題,因此有了分片集群。分片集群有多個master節(jié)點并且不同master保存不同的數(shù)據(jù),master之間通過ping相互監(jiān)測健康狀態(tài)??蛻舳苏埱笕我庖粋€節(jié)點都會轉(zhuǎn)發(fā)到正確節(jié)點,因為每個master都被映射到0-16384個插槽上,集群的key是根據(jù)key的hash值與插槽綁定

10.Redis集群主從同步原理

主從同步第一次是全量同步:slave第一次請求master節(jié)點會根據(jù)replid判斷是否是第一次同步,是的話master會生成RDB發(fā)送給slave。

后續(xù)為增量同步:在發(fā)送RDB期間,會產(chǎn)生一個緩存區(qū)間記錄發(fā)送RDB期間產(chǎn)生的新的命令,slave節(jié)點在加載完后,會持續(xù)讀取緩存區(qū)間中的數(shù)據(jù)

11.Redis緩存一致性解決方案

更新數(shù)據(jù)庫時把緩存給刪除是最優(yōu)方案,可以更大概率避免并發(fā)問題,但是依舊會有緩存刪除失敗的問題。可以使用分布式事務(wù),或者在刪除失敗后把key發(fā)送到rabbitMQ中進行異步刪除重試

七.計算機網(wǎng)絡(luò)系列

1.TCP/IP模型

2.瀏覽器輸入地址后做了什么?

3.TCP三次握手

4.為什么TCP不能兩次握手

假設(shè)是兩次握手,若客戶端發(fā)起的連接請求阻塞在網(wǎng)絡(luò)中,會造成該報文的重傳,這時服務(wù)收到連接請求后會立刻進入連接狀態(tài),當(dāng)雙方傳輸完數(shù)據(jù)結(jié)束連接后,第一次阻塞的請求突然又到達了服務(wù)端,此時服務(wù)端又進入連接狀態(tài),而客戶端不會響應(yīng)服務(wù)端的連接確認報文

5.TCP四次揮手

6.為什么要進入時間等待狀態(tài)?

若客戶端發(fā)送確認釋放包后直接關(guān)閉,而服務(wù)端因為某種原因沒有收到客戶端的確認釋放包,就會一直發(fā)送確認請求,而客戶端永遠不會再響應(yīng)該請求。

7.TCP 滑動窗口

TCP 流量控制,主要使用滑動窗口協(xié)議,滑動窗口是接受數(shù)據(jù)端使用的窗口大小,用來告訴發(fā)送端接收端的緩存大小,以此可以控制發(fā)送端發(fā)送數(shù)據(jù)的大小,從而達到流量控制的目的。如果TCP發(fā)送方收到接收方的零窗口通知后,會啟動持續(xù)計時器。計時器超時后向接收方發(fā)送零窗口探測報文,如果響應(yīng)仍為0,就重新計時,不為0就打破死鎖

8.TCP擁塞控制

發(fā)送方會維護一個擁塞窗口大小的狀態(tài)變量,大小取決于網(wǎng)絡(luò)的擁塞程度。發(fā)送方的發(fā)送窗口大小是取接收方接收窗口和擁塞窗口中較小的一個

擁塞控制有四種算法:

慢開始:從小到大主鍵發(fā)送窗口,每收到一個確認報文窗口大小指數(shù)增長

擁塞避免:當(dāng)窗口大小到達一定閾值時,轉(zhuǎn)為擁塞避免,每收到一個確認報文窗口大小+1。若此時網(wǎng)絡(luò)超時,就把閾值調(diào)小一半,重新慢開始

快重傳:要求接收方收到請求后要立即回復(fù)

快恢復(fù):發(fā)送方連續(xù)收到多個確認時,就把擁塞避免閾值減小,然后直接開始擁塞避免

9.TCP超時重傳

發(fā)送方在發(fā)送按數(shù)據(jù)后一定時間內(nèi)沒有收到接收方響應(yīng)報文,就會重新發(fā)送剛剛的報文,接收到收到報文后會對該報文的序列號進行檢驗,已存在就拋棄

10.TCP可靠傳輸?shù)膶崿F(xiàn)

TCP是靠滑動窗口協(xié)議和連續(xù)ARQ協(xié)議配合流量控制和擁塞控制來保證的可靠傳輸。

ARQ是停止等待協(xié)議和自動重傳請求,它規(guī)定TCP要為每一次傳輸?shù)陌幪枺堪l(fā)送一個包,要等待對方確認后才能發(fā)送下一個分組,若一段時間對方?jīng)]有確認,就重新發(fā)送剛剛的報文。接收方會對數(shù)據(jù)包排序,把有序數(shù)據(jù)傳給應(yīng)用層,返回缺失的第一個ACK確認序列號給發(fā)送方,接收到收到報文后會對該報文的序列號進行檢驗,重復(fù)就丟棄。

流量控制是.....擁塞窗口上......(上面已經(jīng)說了)

11.TCP報頭有哪些信息

12.狀態(tài)碼

1xx:請求正在處理

2xx:請求成功處理

3xx:請求重定向 ? 301:永久重定向 ? ? ?302:臨時重定向 ? ? ? 304:使用本地緩存

4xx:客戶端錯誤 ? 400:請求格式錯誤 ? 403:沒有訪問權(quán)限 ? 404:請求資源不存在

5xx:服務(wù)端錯誤

13.socket通信流程

(1)服務(wù)端創(chuàng)建socket并調(diào)用bind()方法綁定ip和端口號

(2)服務(wù)端調(diào)用listen()方法建立監(jiān)聽,此時服務(wù)的scoket還沒有打開

(3)客戶端創(chuàng)建socket并調(diào)用connect()方法像服務(wù)端請求連接

(4)服務(wù)端socket監(jiān)聽到客戶端請求后,被動打開,調(diào)用accept()方法接收客戶端連接請求,當(dāng)accept()方法接收到客戶端connect()方法返回的響應(yīng)成功的信息后,連接成功

(5)客戶端向socket寫入請求信息,服務(wù)端讀取信息

(6)客戶端調(diào)用close()結(jié)束鏈接,服務(wù)端監(jiān)聽到釋放連接請求后,也結(jié)束鏈接

八.linux系列

1.linux常用命令

ifconfig:查看網(wǎng)絡(luò)接口詳情

ping:查看與某主機是否能聯(lián)通

ps -ef|grep 進程名稱:查看進程號

lost -i 端口 :查看端口占用情況

top:查看系統(tǒng)負載情況,包括系統(tǒng)時間、系統(tǒng)所有進程狀態(tài)、cpu情況

free:查看內(nèi)存占用情況

kill:正常殺死進程,發(fā)出的信號可能會被阻塞

kill -9:強制殺死進程,發(fā)送的是exit命令,不會被阻塞

2.linux的io模型

IO是數(shù)據(jù)的讀取和寫入,用戶進程讀取一次IO請求分為兩個階段:等待數(shù)據(jù)到達內(nèi)核緩沖區(qū)和將內(nèi)核空間數(shù)據(jù)拷貝到進程空間,當(dāng)用戶去內(nèi)核中拷貝數(shù)據(jù)時,要從用戶態(tài)轉(zhuǎn)為核心態(tài)

5中io模型:

(1)同步阻塞IO模型

用戶進程發(fā)起io調(diào)用后會被阻塞,等待內(nèi)核數(shù)據(jù)準(zhǔn)備完畢時就被喚醒,將內(nèi)核數(shù)據(jù)復(fù)制到用戶進程。這兩個階段都是阻塞的

(2)同步非阻塞IO模型

用戶進程發(fā)起IO調(diào)用后,若內(nèi)核數(shù)據(jù)還未準(zhǔn)備好,進程不會被阻塞,而是給用戶進程返回一個error,進程會繼續(xù)干別的事,每隔一段時間就去看看內(nèi)核數(shù)據(jù)是否準(zhǔn)備好。不過將內(nèi)核數(shù)據(jù)復(fù)制到用戶進程這個階段依舊是阻塞的

(3)IO多路復(fù)用模型

同步非阻塞IO要不停的查看內(nèi)核中數(shù)據(jù)是否準(zhǔn)備好,十分消耗cpu。IO多路復(fù)用讓一個線程去監(jiān)控一個fd文件,每個用戶進程都有一個fd文件描述符,將自己的文件描述符寫入這個fd文件,當(dāng)某個用戶進程需要的數(shù)據(jù)準(zhǔn)備好后,這個線程就去通知用戶進程。

(4)信號IO模型

當(dāng)用戶進程發(fā)起IO調(diào)用后,會向內(nèi)核注冊一個信號處理函數(shù),進程不會被阻塞,當(dāng)內(nèi)核數(shù)據(jù)準(zhǔn)備就緒時就返回一個信號給用戶進程,進程就可以直接在這個信號處理函數(shù)中獲取內(nèi)核數(shù)據(jù)進行拷貝??截愡@個階段依舊是阻塞的

(5)異步非阻塞模型

前面四種全是同步的。進程在發(fā)起IO調(diào)用后,無論數(shù)據(jù)是否到達,都直接返回結(jié)果。內(nèi)核數(shù)據(jù)準(zhǔn)備好時,由內(nèi)核將數(shù)據(jù)復(fù)制給用戶進程。兩個階段都是非阻塞的

九.其他(RabitMQ、數(shù)據(jù)結(jié)構(gòu)與算法、nginx、git、jwtd登錄等...)


Java八股文大全的評論 (共 條)

分享到微博請遵守國家法律
平果县| 涪陵区| 成都市| 安远县| 尖扎县| 安庆市| 长武县| 上犹县| 吉安县| 遂宁市| 昌宁县| 苏尼特左旗| 屏东市| 改则县| 龙海市| 西乌珠穆沁旗| 山丹县| 吉安县| 灵璧县| 阿鲁科尔沁旗| 惠东县| 仙居县| 浏阳市| 平阴县| 南康市| 二手房| 海门市| 庐江县| 杭锦后旗| 和平县| 醴陵市| 始兴县| 县级市| 黎平县| 游戏| 屏东市| 禄劝| 浪卡子县| 澳门| 岳普湖县| 阿拉善左旗|