新建文字文件1
什麼是字串常量池?
建立一個字串時,JVM會首先去字串常量池查詢是否存在這個物件,如果存在,則不建立任何物件,,直接將這個物件的地址返回。如果不存在,就新建立一個物件,然後返回。
字串常量池是JVM為了提升效能和減少記憶體消耗針對字串專門開闢的一塊區域。
為了避免字串的重複建立
String為什麼是不可變的?
String在定義時候宣告final型別
String類全域性變數都定義為private final型別,表明物件一旦初始化,屬性值就無法改變
String物件真的不可變嗎?
那麼,用什麼方式可以訪問私有成員呢? 沒錯,用反射,可以反射出String物件中的value屬性, 進而改變通過獲得的value引用改變陣列的結構
String s = new String("xyz");究竟產生了幾個物件,從JVM角度談談?
1個或者兩個
如果字串池沒有xyz字串,會在字串池中建立,會在堆記憶體建立
如果字串有xyz字串,則只會在堆記憶體中建立
String拼接字串效率低,你知道原因嗎?
比如在迴圈裡面連線字串,+在for迴圈內部,每次執行就會建立一個StringBuilder,如果不斷產生會佔用大量資源,應該在程式中直接使用StringBuilder來連線字串,StringBuilder物件直接進行append的話,可以節省建立和銷燬建立物件的時間。
你真的瞭解String的常見API嗎?
獲取字串的長度 int length()
將自負串裡面的小寫字母變成大寫 toUpperCase()
將字串裡面的大寫字母變成小寫字母toLowerCase()
比較兩個字串 equals
擷取字串 substring()
連線兩個字串 contat()
替換 replace()
淺析Java中的final關鍵字?
final用於宣告類,屬性,方法 ,即屬性不可變,方法不可覆蓋,類不可繼承
淺析Java中的static關鍵字?
static關鍵字宣告一個成員變數或者成員方法可以在沒有所屬的類的例項變數的情況下被訪問。
Java中static方法不能被覆蓋,方法覆蓋是執行時動態繫結的,static方法是編譯時靜態繫結的
你對Java中的volatile關鍵字瞭解多少?
volatile是保證了可見性,有序性,沒有原子性
volatile只是保持執行緒的可見性,被volatile修飾,也就有兩層含義:1.執行緒內的修改操作可以立馬被其他執行緒看到 2.禁止重排序
我們通過看被volatile修飾過後的編譯原始碼可以看到有一個字首指令.lock,這就是相當於一個記憶體屏障。
記憶體屏障有3個功能:1.保證記憶體屏障前的指令不會排到記憶體屏障的後面記憶體屏障後面的指令不會排到記憶體屏障的前面
2強制對快取的修改操作立即寫入主存
3.如果是寫操作,會導致CPU中對應的快取行失效
i++是執行緒安全的嗎?如何解決執行緒安全性?
執行緒不安全,都沒有原子性
對i++操作的方法加同步鎖,同時只有一個執行緒執行i++操作
從位元組碼角度深度解析 i++ 和 ++i 執行緒安全性原理?
i++位元組碼: j = i++是一個先壓棧,先將本地變數i壓棧,然後本地變數自增1,再將棧頂元素彈出寫到本地變數j內。此時j還是為0.
++i位元組碼: j = ++i的操作順序是先將本地變數i自增一,然後再壓棧,最後寫入到j內。也就是此時j為i+1之後的內容。
請談談什麼是CAS?
Compare and swap 比較並交換
CAS(compare and swap, 比較並交換),是原子操作的一種,可用於在多執行緒程式設計中實現不被打斷的資料交換操作,從而避免多執行緒同時改寫某一資料時由於執行順序不確定性以及中斷的不可預知性產生的資料不一致問題。
簡單來說,CAS可以保證多執行緒對資料寫操作時資料的一致性。
CAS的思想:三個引數,一個當前記憶體值V、舊的預期值A、即將更新的值B,當且僅當預期值A和記憶體值V相同時,將記憶體值修改為B並返回true,否則什麼都不做,並返回false。
CAS的缺點:
CASABA問題,迴圈時間長開銷大和只能保證一個共享變數的原子操作。其中ABA問題作為第三部分重點說明下。
從原始碼角度看看ArrayList的實現原理?
Arraylist是基於陣列儲存的,陣列有下標,可以通過陣列的下標進行一次訪問,所以查詢速度快。增刪效率低,因為定義陣列的時候需要定義其長度,不靈活不方便資料的增,刪。geter()和seter()方法快
手寫LinkedList的實現,徹底搞清楚什麼是連結串列?
LinkedList的底層是連結串列結構,是雙向連結串列。可以通過連結串列中的一個節點,可以訪問到它的前驅節點和後繼節點。所以add()和remove()效率高
Java中方法引數的傳遞規則?
值傳遞,如果是基本型別傳遞基本型別的字面值的拷貝,會建立副本,引數如果是引用型別傳遞的是引數所引用的物件在堆中地址值的拷貝,也會產生副本
Java中throw和throws的區別是什麼?
throw用來明確的丟擲一個異常
throws用來表明可能丟擲的各種異常
throw語句用在方法體內,用來明確的丟擲一個異常
throws用於方法宣告以後,表明可能丟擲的各種異常,throws表示出現異常的一種可能性,不一定會發生這種異常。
過載和重寫的區別?
過載發生在子類和子類,方法名必須相同,引數列表不同,實現了一個方法,可以實現類似的功能
重寫發生在子類與父類,方法名,引數列表必須相同,子類的返回值要小於等於父類,丟擲的異常範圍要小於等於父類,子類的訪問修飾符要大於等於父類,public,protected,default,private,父類如果是private,就不可以重寫。父類和子類的方法必須一致
finally語句塊你踩過哪些坑?
finally快不管有沒有捕獲異常或者處理異常都是會執行的,finally塊裡面不能有return,如果有的話就返回的是finally裡面的return的值了
為什麼重寫equals方法需同時重寫hashCode方法?
重寫了equals方法必須重寫hashCode方法,針對Set和Map集合:1.集合首先判斷儲存物件是不是唯一的
2.集合類判斷兩個物件是否相等,先用equals()方法判斷是否相等,如果為true,還要判斷HashCode返回值是否為true,如果為true,才認為兩個物件相等
equals() 與 == 的區別?
相等於如果是基本型別的話比較的值,如果是引用型別,比較的是記憶體地址
equals()如果是Object.equals()和相等於類似,如果是String.equals()比較的值
StringBuffer和StringBuilder的區別,從原始碼角度分析?
都是可變字元序列,都繼承AbstractStringBuilder
StringBuffer效率低,執行緒安全
StringBuilder效率高,執行緒是不安全的
看過StringBuffer原始碼可以看到,幾乎所有的方法都加了synchronized,synchronized是用來加鎖的,所以線城是安全的
我們通過StringBuilder原始碼看到,基本上方法都沒有用synchronized關鍵字修飾,當多執行緒訪問時候,就會出現執行緒安全性問題。
你知道HashMap的資料結構嗎?
HashMap在jdk1.7底層是陣列,連結串列,在jdk1.8是陣列,連結串列,紅黑樹
為何HashMap的陣列長度一定是2的次冪?
HashMap何時擴容以及它的擴容機制?
HashMap是基於Hashing原理的,是通過Put()方法和get()方法來儲存和獲取元素的,
HashMap只要不進行Put方法儲存元素之前,HashMap就不會擴容。當用put方法傳遞鍵和值時候,我們先對物件呼叫Hashcode()方法計算並返回Hashcode,隨後計算並返回的hashcode適用於找到Map陣列的bucket位置來儲存物件,如果bucket滿了,就要進行擴容
呼叫resize方法進行擴容,預設的負載因子為0.75,當一個map填滿了75%的bucket時候,就會擴容,擴容後table大小變味了原來的兩倍
HashMap的key一般用字串,能用其他物件嗎?
一般用Integer,String這種不可變類當HashMap當key
HashMap的key和value都能為null麼?如果key能為null,那麼它是怎麼樣查詢值的?
HashMap的key和value都能為null
HashMap是執行緒安全的嗎?如何實現執行緒安全?
執行緒不安全,使用Collections的synchronizedMap方法包裝一下
使用ConcurrentHashmap,使用分段鎖來保證執行緒安全
從原始碼角度分析HashSet實現原理?
Hashset是基於HashMap實現的,有放入HashSet中的集合元素實際上由HashMap的key來儲存,而HashMap的value則儲存了一個PRESENT,它是一個靜態的Object物件。
如果向HashSet中新增一個已經存在的元素,新新增的集合元素不會覆蓋原來已經有的集合元素
HashTable與HashMap的實現原理有什麼不同?
HashMap基於Hashing原理,是通過put方法和get方法來進行儲存和獲取元素的,使用put來傳遞鍵和值的時候,會先用hashcode方法,計算並返回的hashcode用於找到Map中的bucket位置來儲存物件
HashMap執行緒不安全,底層在jdk1.7是陣列,連結串列,在jdk1.8是陣列,連結串列,紅黑樹
HashTable底層是陣列,連結串列,是執行緒安全的
String方法intern() 你真的會用嗎?
intern()方法設計的初衷,就是重用String物件,節省記憶體消耗,這個方法返回的是 返回字串物件的規範化表示形式,當呼叫 intern 方法時,如果池已經包含一個等於此 String 物件的字串(該物件由 equals(Object) 方法確定),則返回池中的字串。否則,將此 String 物件新增到池中,並且返回此 String 物件的引用
什麼是自動拆裝箱?
將基本型別用包裝器型別包裝起來
將包裝器型別轉換為基本型別
String.valueOf和Integer.toString的區別?
相同點:都可以用於把int轉換成String
不同點:String.valueOf可以應用到任何資料型別,且不會有異常報出
Integer.toString先將int轉換為Interger型,然後再將Integer轉換成String型
三、Java多執行緒
執行緒的生命週期包括哪幾個階段?
建立,就緒,執行,阻塞,死亡
首先是建立,這個時候執行緒還沒有呼叫start方法,呼叫了start方法,執行緒進入就緒狀態,還沒有獲取到CPU的執行指令,獲取到了CPU的執行指令也就開始運行了,如果因為一些原因,丟失了CPU執行指令,也就進入了阻塞狀態,這個時候必須回到就緒狀態,等到重新獲得CPU的執行指令,
最後狀態是死亡狀態,執行緒執行完了,執行緒結束生命週期
多執行緒有幾種實現方式?
繼承Thread類,重寫Thread的run方法,只可以單繼承
實現Runnable介面的run方法,並且將Runnable例項傳給Thread類,再讓Thread類去執行run方法。
請談談什麼是程序,什麼是執行緒?
程序也就是一個程式從建立,執行,消亡的過程
一個程序可以有多個執行緒,每個執行緒都有自己的程式計數器,本地方法棧,虛擬機器棧
啟動執行緒是用start()方法還是run()方法?
用start()方法,開啟Start()方法就會自動啟動run()方法,這才是多執行緒。呼叫run()方法啟動的是main底下的run方法,就不是多執行緒了。
說說執行緒安全問題,什麼實現執行緒安全,如何實現執行緒安全?
執行緒安全就是,我們在寫的某的某個程式碼塊,比如i++,i初始值為0,第一個執行緒結果是1,第二個執行緒為2,這個執行緒就是安全的,如果執行緒不安全,那麼第一個執行緒結果是1,第二個執行緒的結果是1。也就是多個執行緒執行能夠正常執行,不會混亂。
可以用synchronized和lock來解決執行緒安全問題,
sychronized和Lock的區別?
sychronized是原子性內建鎖,是一個關鍵字,lock是一個介面
自動釋放鎖,需要手動釋放鎖,否則就會造成死鎖
無法判斷獲取鎖的狀態,而lock鎖可以判斷是否獲取到了鎖
lock可以中斷等待鎖的執行緒的狀態,sychronized裡等待的執行緒會一直等待下去,不能夠相應中斷
sychronized適合鎖少量的同步程式碼,lock適合鎖大量的同步程式碼
sleep()和wait()的區別?
兩者都可以暫停執行緒的執行,sleep()方法屬於Thread類中的,wait()方法屬於Object()類
sleep通常用於暫停執行,wait通常用於執行緒間互動/通訊
呼叫sleep(),執行緒不會釋放鎖,呼叫wait(),執行緒會放棄鎖
深入分析ThreadLocal的實現原理?
談談對synchronized的偏向鎖、輕量級鎖、重量級鎖的理解?
這是鎖的優化,鎖的狀態是由低到高為無鎖,偏向鎖,輕量級鎖,重量級鎖。 無鎖就是沒有鎖,偏向鎖就是通過物件頭的偏向執行緒ID來對比,輕量級鎖就是通過CAS修改物件頭鎖和自旋來實現的,重量級鎖則是除了擁有鎖擁有的執行緒,其他全部都塞。
通過三種方式實現生產者消費者模式?
通過一個容器來解決生產者和消費者的強耦合關係,生產者生成資料無需等待消費者索取,消費者無需直接索要資料,通過容器來進行操作。
使用synchronize以及wait()、notify()
可以自定義一個阻塞佇列,當佇列免了的時候,通過wait(),使生產者執行緒阻塞,並釋放佇列物件的鎖,然後呼叫notify()方法可以喚醒消費者執行緒
使用lock和Condition的await()和signal()方法
JVM層面分析sychronized如何保證執行緒安全的?
sychronized是原子性內建鎖,也被稱為監視器鎖,我們通過觀察被sychronized修飾的編譯過後的同步程式碼塊發現,有monitor和monitertesxt位元組碼指令,執行monitor指令會獲取鎖,如果獲取到了鎖,其他競爭鎖的執行緒會進入等待序列,執行了monitortext在位元組碼指令,鎖會釋放,處於等待佇列中的執行緒在繼續競爭鎖
如何寫一個執行緒安全的單例?
餓漢式單例模式,在第一次載入時就例項化
懶漢式單例模式,在第一次被引用時開始例項化
餓漢式比較好
ThreadLocal什麼時候會出現OOM的情況?為什麼?
1.ThreadLocal是什麼?
每個執行緒在對記憶體中開闢的一塊工作記憶體,同時把執行緒的共享資料拷貝了一份放進去,相當於做的本地副本,不會像synchronized一樣每次修改都要同步到主記憶體中
2.ThreadLocal有什麼用?
工作執行緒的資料互動主要是本地資料和主記憶體資料的互動,當資料儲存在本地記憶體中,可以大大提高讀取效率,避免了執行緒阻塞造成的cpu的吞吐下降;
在多執行緒中每個執行緒中都要維護sesion,可以提高對獨有資源的工作效率;
3.發生記憶體洩露原因?
synchornized是保證了主記憶體資料的一致,是時間換空間:通過阻塞一個共享變數,共享一小塊記憶體空間;
threadLocal是通過建立執行緒的副本資料,空間換時間
ThreadLocalMap的Key為弱引用,當threadlocal物件被回收(value在ThreadLocalMap呼叫get、set、remove的時候就會被清除),這時將key設定為null的entry。但是threadlocal一直不會被回收,導致記憶體的洩露
4.如何避免呢?
其實在呼叫threalocalMap的get/set方法時,會對key=null的entry(threadlocal物件=null)進行回收,也可以在呼叫結束時呼叫remove方法進行釋放。
為什麼wait, notify 和 notifyAll這些方法不在thread類裡面?
Wait-notify機制是在獲取物件鎖的前提下不同執行緒間的通訊機制。在Java中,任意物件都可以當作鎖來使用,由於鎖物件的任意性,所以這些通訊方法需要被定義在Object類裡。
你真的理解CountDownLatch與CyclicBarrier使用場景嗎?
CountDownLatch是一個同步的輔助類,允許一個或多個執行緒,等待其他一組執行緒完成操作,再繼續執行。
CyclicBarrier是一個同步的輔助類,允許一組執行緒相互之間等待,達到一個共同點,再繼續執行。
出現死鎖,如何排查定位問題?
1.在cmd視窗,使用jps指令查詢該類的埠號(pid)
2.在使用jstack+pid檢視日誌(jstack pid)
notify和notifyAll的區別?
呼叫notify()方法只隨機喚醒一個wait執行緒,這個執行緒會從等待池進入鎖池,呼叫notifyAll方法會喚醒所有wait執行緒,而且會將該物件等待池內的所偶執行緒移動到鎖池種,等待鎖競爭。
執行緒池啟動執行緒submit和execute有什麼不同?
execute只能執行Runnable型別的任務,沒有返回值
submit可以執行Runnable和Callable型別的任務
submit能獲取返回值,並且處理異常,通過捕獲Future.get()丟擲的異常
SimpleDateFormat是執行緒安全的嗎?如何解決?
SinmpleDateFormat是java提供的一個格式化和解析日期的工具類,在java中,可以使用SimpleDateFormat的format方法,將一個Date型別轉化成String型別,並且可以指定輸出格式。
執行緒不安全,被當作了共享變數在多個執行緒中進行使用,這就出現了執行緒安全問題。
解決:使用區域性變數,就不會被多個執行緒同時訪問到了,避免了執行緒安全問題
加同步鎖,通過加鎖使多個執行緒排隊順序執行
如果是Java8,使用DateTimeFormatter代替SimpleDateFormat
請談談ConcurrentHashmap底層實現原理?
當一個執行緒進入一個物件的一個synchronized方法後,其它執行緒是否可進入此物件的其方法?
執行緒池的原理,為什麼要建立執行緒池?建立執行緒池的方式?
建立執行緒池有哪幾個核心引數? 如何合理配置執行緒池的大小?
synchronized修飾的靜態方法和非靜態方法有什麼區別?
修飾靜態方法,作用於當前類物件加鎖,進入同步程式碼前要獲得當前類物件的鎖
修飾非靜態方法,作用於當前例項加鎖,進入同步程式碼前要獲得當前例項的鎖
四、Java Web
什麼是Servlet,Servlet生命週期方法?
什麼Session和Cookie,它們之間有什麼聯絡?
JSP的八個隱含物件有哪些?
JSP的四個域物件的作用範圍?
Post和Get請求的區別?
轉發和重定向有什麼區別?
JSP自定義標籤,如何實現迴圈列印功能?
Http1.0和Http1.1的區別是什麼?
攔截器與過濾器的區別?
五、JVM面試題
JVM記憶體區域如何劃分?
JVM堆中物件是如何建立的?
JVM物件的結構?
JVM垃圾回收-如何判斷物件是否是垃圾物件?
JVM垃圾回收演算法有哪些?
JVM垃圾收集器有哪些?
JVM記憶體是如何分配的?
從一道面試題分析類的載入過程?
JVM雙親委派機制?
JVM可以作為GC Root的物件有哪些?
請寫出幾段可以導致記憶體溢位、記憶體洩漏、棧溢位的程式碼?
哪些情況會導致Full GC?
頻繁GC問題或記憶體溢位問題,如何定位?
六、SQL效能優化
資料庫三正規化是什麼?
資料庫的事務、ACID及隔離級別?
不考慮事務的隔離性,容易產生哪三種情況?
資料庫連線池原理?
什麼是B-Tree?
什麼是B+Tree?
MySQL資料庫索引結構?
什麼是索引?什麼條件適合建立索引?什麼條件不適合建立索引?
索引失效的原因有哪些?如何優化避免索引失效?
MySQL如何啟動慢查詢日誌?
MySQL如何使用show Profile進行SQL分析?
一條執行慢的SQL如何進行優化,如何通過Explain+SQL分析效能?
什麼是行鎖、表鎖、讀鎖、寫鎖,說說它們各自的特性?
什麼情況下行鎖變表鎖?
什麼情況下會出現間隙鎖?
談談你對MySQL的in和exists用法的理解?
MySQL的資料庫引擎有哪些,如何確定在專案中要是用的儲存引擎?
count(*)、count(列名)和count(1)的區別?
union和union all的區別?
七、Spring框架
Spring的IOC和AOP機制?
Spring中Autowired和Resource關鍵字的區別?
依賴注入的方式有幾種,各是什麼?
Spring容器對Bean元件是如何管理的?
Spring容器如何建立?
Spring事務分類?
Spring事務的傳播特性?
Spring事務的隔離級別?
Spring的通知型別有哪些?
八、SpringMVC框架
SpringMVC完整工作流程,熟讀原始碼流程?
SpringMVC如何處理JSON資料?
SpringMVC攔截器原理,如何自定義攔截器?
SpringMVC如何將請求對映定位到方法上面?結合原始碼闡述?
SpringMVC常見註解有哪些?
SpringMVC容器和Spring容器的區別?
SpringMVC的控制器是不是單例模式,如果是,有什麼問題,怎麼解決?
九、MyBatis框架
MyBatis中#和$的區別?
MyBatis一級快取原理以及失效情況?
MyBatis二級快取的使用?
MyBatis攔截器原理?
看過MyBatis原始碼嗎,請說說它的工作流程?
十、Java高階部分
Dubbo負載均衡策略?
Dubbo中Zookeeper做註冊中心,如果註冊中心叢集都掛掉,釋出者和訂閱者之間還能通訊麼?
Dubbo完整的一次呼叫鏈路介紹?
請說說SpringBoot自動裝配原理?
有用過SpringCloud嗎,請說說SpringCloud和Dubbo有什麼不一樣?
什麼是WebService,如何基於WebService開發介面?
談談專案中分散式事務應用場景?
使用Redis如何實現分散式鎖?
請談談單點登入原理?
Tomcat如何優化?
後臺系統怎麼防止請求重複提交?
Linux常見命令有哪些?
請說說什麼是Maven的依賴、繼承以及聚合?
Git暫存區和工作區的區別?
Git如何建立、回退以及撤銷版本?