java面试突击-2022最新迭代redis\mq\springCloud-纯手打
本博客是本人純手打然后去網上百度的圖片,轉發請注明出處
按照自己的理解適合給初級程序員找工作用的
順便給自己回顧一下,都是按照自己的理解來寫的,有的地方不通順或者不理解可以問我,有寫不對的地方或者不同的見解可以寫在下方
java基礎
java
jdk,JRE,JVM 區別?關系?
jdk是java程序開發的工具包,開發環境 jre是java程序運行時所需的運行環境 jvm是虛擬機,包含類解釋器和類加載器等等 jdk包含jre,jre包含jvm== 和 equals 的區別是什么?
==是比較的引用地址,來判斷是否相等 equals是比較值中的數據來判斷是否相等談談面向對象
1·面向對象我的理解就是將所有的事務都看作一個對象,那么一個對象就有他的屬性和行為,在java編程中就是將一個事務抽取出他的屬性與方法成為我們所定義的一個類,通過new 實例來調用對象,避免重復造輪子2·面向對象的三大特性封裝:將屬性給私有化,公開對屬性的訪問方法,就是將實現的細節給隱藏了繼承在以及有的類上去在派生出一個新的類,這個新的類繼承了原有的類的所有公開的屬性和方法多態就是同一個引用對象指向了不一樣的實例,然后指向同樣的方法,但是最后的結果不一樣,這就是多態性final finally 和 finalize的區別
final定義在類或者屬性或者方法上定義類:該類不能被繼承定義屬性:該屬性為常量,常量注意(基本數據類型不能被改變,對象是可以改變對象里面的東西,但是不能 改變所指向的這個對象)定義方法:該方法不能被重寫 finally是和try catch 一起使用的不管try代碼塊中是否出現異常,finally代碼塊中的代碼都會去執行 finalize是ojbect的方法,是gc判斷是否能回收的最后判斷String 類常用的方法
equals() indexof(); length(); trim(); subsring(); 等...基本的數據類型以及占用字節
整型:byte 1 ,shor 2,int 4,lang 8 浮點型: float 4, double 8 字符:char 2 boolean:1 bit bit與字節 1/8 比如byte就是1個字節 8個bit基本數據類型的封裝類
String、StringBuffet、StringBuder 區別
*String*是用來定義字符串的,但是String不能改變字符串的值,只能去改 變在內存中的地址,這個時候如果業務需求需要對一個字符串經常性的 進行修改那么我們就可以選擇使用*StringBuder 或StringBuffet*,可以使用 ‘+’進行字符串的連接或者append方法進行字符串的追加,那么如果業務 中需要考慮到*線程安全我們可以選擇StringBuffet*,如果不考慮線程問題 我們就可以選擇StringBuder,效率會更高重載與重寫的區別?
方法的重載是在本類當中進行的,方法要同名,參數不一致,和訪問修飾符返回值無關
方發的重寫是在子類或實現類中進行的,方法同名,參數一致,訪問修飾符不能比父類的小,返回值要和父類一樣或是其子類
四種引用類型
強引用:java中默認的就是強引用,比如User user=new User();只要user指向這個new User();的實例就不會 被gc回收,如果想要jvm進行回收可以選擇將user=null軟引用:只會在內存不夠的時候進行回收,如果回收完還是內存不夠則會拋出異常,一般用來實現緩存技術弱引用:只要jvm進行垃圾回收的時候就會回收虛引用:隨時都可能被回收jvm內存模型
其實就是堆、棧、方法區
堆中存放new的實例或則數組,可以被線程共享
棧中存放的引用對象,就是new對象等于的前面那一塊
方法區用于存儲已經被虛擬機加載的類信息,常量,靜態變量等,可以被線程共享
類加載過程,雙親委托機制
jvm將類加載分為3步
1、裝載:查找并加載二進制數據
2、鏈接:
- 驗證:為了確保加載的類正確
- 準備:為類的靜態變量分配內存,并初始化默認值
- 解析:把類中的符號引用轉換為直接引用
3、初始化:為類的靜態變量賦予初始化值
其實就是優先從緩存中去看有沒有這個要加載的類,如果沒有則向上讓上級去找,找到了就向下去加載類,作用就是為了保護java的類不會被應用程序覆蓋,比如你自己寫了個java.lang.String的類如果沒有雙親委托豈不是就把java中的String給覆蓋了
集合
Collection和Map的關系
依賴關系 Collection常用子接口1、List實現類:ArrayList、Vector、LinkedList2、Set實現類:HashSet Map的常用實現類1、HashMap2、Hashtable(t是小寫)List Set Map的區別
List 值不唯一,有序,可以插入多個null值 Set 值唯一,無需,只能插入一個null值 Map 鍵值對的存儲方式,映射關系可以一對一或多對一List 有基于數組、鏈表實現兩種方式 Set與Map 基于哈希存儲和紅黑樹兩種方式實現ArrayList與LinkedList、HashMap區別
ArrayList:使用動態數組的存儲方式,所以檢索速度快初始容量是10,通過rosize()進行擴容,擴容1.5倍新增時容量不夠則進行擴容LinkedList:使用的是雙向鏈表的存儲方式,所以插入數據刪除數據更快雙向鏈表就一直在頭和尾插入、刪除,所以沒有初始化大小,也沒有擴容的機制 HashMap:數組+鏈表的去實現的,可以存儲null鍵與null值,鍵唯一初始容量是16,在0.75的時候擴容,擴容的是2倍,比如集合容量到了12的時候進行擴容,那么容量就是32HashMap與Hashtable的區別?
HashMap:鍵值可以為null,鍵唯一,線程不安全初始容量是16,在0.75的時候擴容,擴容的是2倍,比如集合容量到了12的時候進行擴容,那么容量就是32Hashtable:鍵值不能為null,鍵唯一,線程安全初始容量為11談談ConcurrentHashMap?
前面說到HashMap線程不安全,Hashtable線程安全,那么為什么我們還要 一個ConcurrentHashMap呢?因為ConcurrentHashMap融合了hashtable和hashmap二者的優勢ConcurrentHashMap與Hashtable同樣都是線程安全,應對并發場景 的,那么ConcurrentHashMap的好處在哪里呢?(別的博主那截圖的)Hashtable是直接將這整合集合加鎖,當有一個線程去訪問hashtable的集 合的時候其他線程要等到訪問的這個的線程出來后才能訪問ConcurrentHashMap是將數據一段一段的去加鎖,ConcurrentHashMap 存儲方式就是將數據一段一段往內存中存儲,然后每一段都加上鎖在jdk1.8之前使用沒有紅黑樹,所有的集合都是一樣的,在jdk1.8之后 ConcurrentHashMap上鎖的方式改變成了synchronized迭代器Iterator
就是一個對集合進行遍歷訪問的,可以通過集合對象.Iterator()方法獲 得到迭代器對象進行使用 hasNext判斷是否還有下一個元素,如果有則返回true,通過next()獲 得元素迭代器ListIterator
ListIterato繼承Iterator只能去遍歷List集合,可以進行向前或向后(正序或倒序),Iterator只能向前進行遍歷,ListIterator可以在遍歷的時候對集合元素進行增加刪除操作Collections 和 Arrays?
Collections:是工具類,可以對集合進行搜索、排序、Arrays:工具類 ,對數組進行排序,比較poll()方法和 remove()方法的區別?
都是從隊列中取出元素,如果集合沒用元素的化remove()方法拋出異常, poll方法則會返回null打印數組
通過Arrays.toString()String[] jayArray = {"jay", "boy"};System.out.println(Arrays.toString(jayArray));HashMap 的擴容過程
將數組擴容到原來的倆倍,然后將舊數組的元素重新計算hash再插入到新擴容的數組中ArrayList 和 Vector 的區別是什么?
Vector 線程安全的ArrayList 線程不安全Vector只要是關鍵性的操作,方法前面都加了synchronized關鍵字,來保證線程的安全性。如何決定使用 HashMap 還是TreeMap?
看集合是否需要排序,需要排序可以使用TreeMapHashMap是怎么解決哈希沖突的
Hashmap解決hash沖突,使用的是鏈地址法,即數組+鏈表的形式來解決。 put執行先判斷table[i]位置,如果為空就直接插入,不為空判斷和當前值是 否相等,相等就蓋,如果不相等的話,判斷是否是紅黑樹節點,如果不是, 就從table[i]位置開始遍歷鏈表,相等覆蓋,不相等插入。IO
java中有幾種類型的流?
字符流和字節流 字節流繼承inputStreamOutputStream 字符流繼承自InputSteamReaderOutputStreamWriter字符流和字節流有什么區別?
字面意思以字節或字符輸入輸出,但是字符也可以用字節輸出, 要轉,使用byBytes(),貌似是這個,忘記了網絡通信
TCP和UDP有什么區別?TCP為什么是三次握手不是倆次?
TCP 是面向連接的可靠的傳輸層的通信協議,好比是打電話,可靠,點對點的通信,效率低,占用資源多
UDP就是無連接不可靠的傳輸層通信協議,好比是廣播,不需要連接,發送方不管接收方有沒有準備就直接發送,不可靠,效率高,占用的資源少
BIO,NIO,AIO
BIO:同步阻塞 ,讀寫必須阻塞在一個線程內等待完成,可靠性查,吞吐量低,適用于連接少且固定的場景,jdk1.4版本前唯一的選擇
NIO:同步非阻塞,線程不斷輪詢看IO的狀態,根據狀態來進行下一步操作,可靠性和吞吐量高,適用于連接比較多的場景,比如聊天室,jdk1.4開始執行
AIO:異步非阻塞,就是為了解決異步IO,基于回調機制,可靠性和吞吐量高,適用于連接比較多,且連接比較長,比如相冊服務器,jdk1.7版本才支持
NIO的核心組件什么?分別的作用
Channel Buffer Selector
channel每一個channel對應一個buffer緩沖區,channel會注冊到selector。
selector會根據channel上發生的讀寫時間,將請求交給某個空閑的線程處理,selector對應一個或多給線程。
Buffer和Channel都是可讀寫的。
session和cookie的區別?
cookie因為是存儲在客戶端的所以可以被客戶端禁用,session是存儲在服務端的所以無法禁用,session可以存儲任意類型,cookie只能存String,一般我們用session的session去配合存儲cookie
HTTP和HTTPS的區別?
HTTP:是互聯網上應用最廣泛的通信協議,基于TCP,可以使用游覽器工作更高效,減少網絡傳輸
HTTPS:是HTTP的加強版,在HTTP的基礎山增加安全機制,保證數據傳輸的安全,另一方面對訪問者增加了驗證機制
主要區別:
1、HTTP的連接是無狀態的,HTTPS的數據傳輸時經過證書加密的,安全性更高
2、HTTP免費,HTTPS需要申請證書,而證書要收費的
3、端口不同,http80,https時443
線程
博主談線程
初學者可能只是會用線程,但是并不知道在實際項目中應該怎么去用 博主在這里給你們打倆個比方:1、此時博主項目用到poi來將查詢出來的數據以Excel表格導出, 那么如果是單線程,且下載一份需要5秒鐘的情況,那么我一個用 戶下載,另一個用戶需要等上一個用戶下載完,那如果5個人下載 就需要25秒,但是我創建線程,讓線程去下載呢?那就是一個人 一個下載一個線程,是不是大大縮短了時間2、再來比如是查詢數據,數據量比較大,要用到6張表,那么我 門也創建線程去執行,一個線程分3張是不是也好很多可以理解為孫悟空一個人打小妖精,一棍一個太慢了,多分幾個身 一起打是不是快很多什么是線程?
線程就是一個程序的最小執行單位,還要想更細一點看上面博主談線程線程和進程有什么區別?
線程是進程的子集,一個進程可以有很多線程,每條線程并行執行不同的 任務。如何在Java中實現線程?
其實就是問線程的創建方式1、繼承Thread 類2、實現Runnable用Runnable還是Thread?
眾所周知java當中只能繼承一次,可以實現多個接口,當然是實現 Runnable好一點Thread 類中的start() 和 run() 方法有什么區別?
start()方法才是真正的創建了一個線程,如果不是start()方法調用到的 run()方法那么run方法就是一個很普通的方法,是沒有新的線程的線程如果問了肯定會問生命周期
線程的啟動狀態,就是前面說的start()方法的時候啟動 就緒狀態,就是start()方法執行到run()方法的時候 阻塞狀態,阻塞狀態里面有休眠,等待,掛起,阻塞 死亡狀態,線程執行完就進入了死亡狀態剛剛說到阻塞狀態的四個狀態,那就肯定會問這幾個方法 sleep(),wait(),join(),yield()
首先肯定是sleep()方法和wait()方法的區別 sleep()方法是將線程休眠,Thread類中的靜態方法,不會釋放鎖 wait()方法是將線程等待,Object中的方法,會釋放鎖 因為這個釋放鎖的原因所有導致sleep()可以寫在任何代碼塊中,而wait()方法只能定義在同步代碼塊中 調用wait()方法的線程會進入到等待池中,等待池中的線程不會去搶奪同 步鎖,只有調用notify()或notifyAll()方法才會去搶奪線程,這倆個方法看 方法名應該不用多說了吧 join()方法調用的線程執行完了其他線程才執行,理解為誰調用誰老大 yield()方法調用的線程進入阻塞狀態,會釋放CPU的執行權,然后包括調 用的線程在內所有的線程重新搶奪CPU的資源線程安全的理解?
java當中線程安全的定義是對象級別的,所以個人的理解是多個線程同時 操作同一個對象,我們不進行同步控制協同等操作這個對象最后的結果還 是正確的結果我就認為這個線程是安全的,那么如果不是線程安全的我們 怎么去處理呢?我們可以加鎖,或者使用線程安全的對象,比如Hashtable等...Lock接口和synchronized內置鎖
synchronized主要確保線程互斥同步代碼,保證線程共性變量被修改,其 它線程可以及時可見,解決重排序的問題 原理:加入了指令監視器鎖,判斷是0還是1來看線程的占有情況lock是一個類,通過lock()方法開啟鎖,通過unlock()關閉鎖 還有tryLock()獲取鎖的時候如果有占用就返回false,沒有占用就返回true 作用范圍是代碼塊倆者的區別:synchronized不會主動釋放鎖Lock鎖可以主動釋放鎖,想在哪里釋放就在哪里釋放synchronized就像是悲觀鎖,感覺自己什么時候都會被別的線程給搶走資源,所以就一直鎖著自己Lock鎖是樂觀鎖的一種,通過volatile和CAS操作實現Threadlocal的原理和使用場景?
使用Threadlocal創建的變量一個線程訪問了,其他線程則無法訪問和 修改,每一個線程的Threadlocal的值都不一樣,這就是Threadlocal的作 用是一個泛型類,保證可以接受任何類型的對象,因為是弱引用的題 ,所以在下一次垃圾回收的時候會被清理使用場景:每個線程都要有自己的一個單獨的實例的時候,單又要被 被多個線程所訪問的時候使用串行,并行,并發的區別?
串行:一個大任務被拆分成了多給小任務,但是這些小任務只能一個一個 有順序的完成 并行:相當于多個小任務要同時完成 并發:某一個時間段多個小任務一起執行,但是不是要一起完成,比如a 任務阻塞了,那么在這阻塞的期間可以操作b任務并發的三大特性?
原子性:要么全部執行,要么都不執行 可見性:當一個線程修改共享變量的值后對其他線程可見 有序性:任務的執行按先后順序完成Volatile
博主所知道的就是防止指令重排,在單例模式中的餓漢式用過,防止類加載的指令重排 還有就是保證不同線程對該變量內存可見談對AQS的理解,如何實現重入鎖
1、AQC是java線程同步框架
2、AQS中其實就是一個線程隊列和一個state,線程隊列就是用來給線程排隊的,而state就像是一個紅綠燈,來控制線程隊列中的線程是否放行
3、可重入鎖就是用state來表示加鎖次數,0表示無鎖,沒加一次state就加1,釋放就-1
java線程鎖機制,偏向鎖,輕量鎖,重量級鎖有什么區別?
1、java的鎖就是在Markword中記錄的鎖狀態,偏向鎖,輕量鎖重量鎖對應不同的鎖狀態
2、java的鎖機制就是根據搶奪資源的線程的多少來升級的過程,比如:
一個偏向鎖就是相當于給資源設置了一個門,一個線程進入后其他線程就進不去,然后等進入的線程出來以后才呢進入
如果線程一多,有一個線程進入了資源后其他線程就會自旋,這個也叫輕量級鎖
如果線程再多了,jvm不可能把性能都用來給線程自旋,jvm就會把這個情況直接給操作系統,然后操作系統會讓線程排隊進入
總結:重量鎖效率低,輕量鎖性能低
為什么使用線程池?
所有的什么什么池都是一樣的原因,都是為了降低消耗,提高利用 率,這個線程池就是創建了線程池后用線程池中的線程去執行任務 對線程統一管理,統一分配資源java中線程池創建的幾種方式
1、創建使用單個線程的線程池ExecutorService es1 = Executors.newSingleThreadExecutor();2、創建使用固定線程數的線程池ExecutorService es2 = Executors.newFixedThreadPool(3);3、創建一個會根據需要創建新線程的線程池ExecutorService es3 = Executors.newCachedThreadPool();3、創建擁有固定線程數量的定時線程任務的線程池ScheduledExecutorService es4 =Executors.newScheduledThreadPool(2);4、 //創建只有一個線程的定時線程任務的線程池ScheduledExecutorService es5 = Executors.newSingleThreadScheduledExecutor();線程池處理流程
1、判斷核心線程數是否已經滿了,如果沒滿則創建核心線程去執行任務,滿了則進入第二步
2、判斷任務隊列是否滿了,如果沒滿則把任務加到隊列中等待執行,滿了進入第三步
3、判斷最大線程數,如果沒滿則創建臨時線程去執行,臨時線程完全閑下來了就會被回收
4、如果都滿了則需要使用拒絕策略
創建線程池參數
1、核心線程數
2、最大線程數
3、線程空閑的存貨時間
4、存放待執行的任務
5、拒絕策略
什么是死鎖?解決死鎖的方式
死鎖:多個線程同時訪問某一個資源都阻塞了,由于循環依賴導致彼此一 直處于等待之中,沒有任何線程可以繼續前進就死鎖了 死鎖的解決方法就是上鎖,無法獲得線程執行的時候就重復去獲取或者退出Web基礎面試
servlet的生命周期
就是初始狀態和服務狀態,服務狀態就是調用servlet()的時候,然后就是 關閉servlet()被回收的時候執行get和post請求的區別?
get請求會將傳遞的請求信息會在地址欄上顯示,然后傳遞的信息有限 只能傳遞4到5kb post請求就不會將請求信息顯示,傳遞的信息沒有限制,所以我們一般 上傳文件上傳圖片都是用post請求轉發和重定向的區別
轉發請求一次,地址欄不改變 重定向請求倆次,地址欄會改變,可以重定向到項目外的其他項目去jsp和servlet的區別
如果在用jsp報錯的時候自己細心解決找過問題出在哪一行的小伙伴應該 已經知道了,jsp本質就是servlet,出現bug的時候提示哪一行報錯如果 找的話找到的式jsp被編譯成.java文件,里面是使用一個那個什么waite去 輸出成一個頁面的,我大概打了一個英文,小伙伴們感興趣可以百度去看講解JSP中的四種作用域
page是代表一個頁面相關的對象和屬性 request是代表與web客戶機發出的一個請求相關的對象和屬性 session是代表與用于某個web客戶機的一個用戶體驗相關的對象和屬性 application是代表與整個web應用程序相關的對象和屬這個servlet就到這吧,我感覺也不會這么問這個,如果面試公司用這個就趕緊走吧,除非是保險或銀行工資開的高,根本學不到技術,只能學邏輯
MySQL數據
數據庫
數據庫將數據永久保存在內存中,使用SQL語句,查詢方便效率高。管理數據方便事務的ACID
原子性:一個事務是一個不可分割的操作單位;保證原子性是通過undo log來回滾日志保證的
一致性:就是事務更改完數據后的數據要一致,不能每個事務看到同一個東西事務不一樣
隔離性:就是多個事務之間的數據不會受到其他事務的干擾;由MVCC主從來保持數據一致
持久性:就是事務執行完后的數據要永久保存;通過redo log來記錄操作,如果宕機了還能從redo log中恢復數據
MVCC
MVCC是多版本并發控制,不沖突讀寫,不同的事務看到i自己的版本數據和版本鎖
MVCC只有在rr與rc隔離級別中工作
數據庫三大范式是什么
第一范式:每個列都不可以再拆分 第二范式:非主鍵的列只依賴這個表的一個主鍵 第三范式:表中的數據都不能再分,比如一個表有學生姓名,教員名稱, 所學科目,成績,那么我們可以將教員和科目拿出來成為一張表然后只 要對學生成績表提供一個idMySQL存儲引擎MyISAM與InnoDB區別
Innodb支持事務,并且提供鎖和外鍵約束 MyIASM不支持事務鎖和外鍵索引
什么是索引?
索引就好像字典里面的那個按偏旁和拼音查字查不到,便于我們快速的查 找數據庫表中的數據索引的數據結構?
使用B+樹的數據結構,一個節點去存儲多個key,然后進行折半查找去查找下一個節點,大大的提高了我們的效率,在葉節點中存儲data與key
索引使用場景
首先是經常需要出現在where后的列就可以加索引mysql聚簇索引與非聚簇索引的區別
1、聚簇索引其實就是數據和索引都放在一起,找到索引就找到了數據,在mysql下的data文件夾下可以看到用的是.ibd文件去存儲索引和數據。
其中通過trx_id用來存對聚簇索引記錄修改的時候的事務id
roll_pointer每次對對聚簇索引記錄修改的將老版本寫入到undo log中去,這個roll_pointer就是存了一個指針,指向這個索引記錄的上一個版本
2、非聚簇索引是葉節點存索引,然后是儲存數據的地址,找到索引后再根據地址去找我們的數據,在data文件夾下面用的是.MYD存數據,MYI去存的索引
使用索引查詢一定能提高查詢的性能嗎?為什么
索引并不是用的越多越好,得考慮到索引也要占用儲存控件,也需要定期 維護,對增刪改的負擔增加了,每次都還得去多付出性能去操作索引索引分類
唯一索引:保證數據唯一 全文索引:比like “name”這種就可以用全文索引 組合索引:一般索引都是建立在一個字段上的,組合索引可以覆蓋多個字段sql語句的優化
查詢的時候避免全盤掃描,這里博主打個比分假如只需要查詢一行數據比如登錄,那么是不是最后加給limit更好這樣只要查到了一行數據就不會在數據庫中繼續查了 避免使用*,當然count(*)除外 count(")本來就是用來定義查詢多少行 數據的,如果你定義的是count(name),如果有一列沒有name不就少 了一行嗎,本來就是這樣定義的,不會影響查詢速度的,但是如果要 查詢出來一個一個的列,最好是在select 后面寫上字段,不管是后期 維護,加字段都會方便很多事務
什么是數據庫事務?
事務時一個不可分割的工作單位,要么都執行成功,要么就都失敗,比如 轉賬是倆個行為,但是我們說這是一個事務事務的ACID
原子性:上面說到了要么執行都成功要么都失敗 一致性:執行事務前后,數據一致 隔離性:并發訪問數據庫的時候,任務之間不能互相干擾到數據,都是各干各的 持久性:事務提交后在數據庫的改變是持久的,永久保存在數據庫中臟讀?幻讀?不可重復讀?
臟讀:就是某一個事務還沒有提交的事務被另一個事務訪問到了,打個比 分就是事務1,a這個時候轉賬個了b,然后事務2這個時候查看b,確實多 了一個億,這個時候事務1再回滾了,那么事務2豈不是白高興一場幻讀:繼續打比方,比如事務1干了一個查詢a表工資大于8000的人,然 后中間還干了其他事情,然后要再查a表工資大于8000的人,然而在a查 了第一次后去干其他的事情的時候事務2把a表中的張三工資漲到了1w, 事務1這個時候才干完中間的事情,再查a表工資大于8000的人的時候 就多了一行,這就好像是出現了幻覺一樣,就是幻讀不可重復讀:就是一個事務重復去讀取一個數據,但是中間還么讀取的 時候其他事務對數據進行的更改到時讀取倆次的結果不一致事務的隔離級別
事務的四個隔離級別,我推薦看一下spring的那個事務的注解,有 的面試官會要你說spring的事務,其實就是數據庫的事務 我發我這的部分代碼-在下面這個代碼塊中 這個@Transactional注解后的這個isolation參數點進去就可以看見 隔離級別,是四個隔離級別,然后spring定義了一個defult,mysql默認 的隔離級別是rc ,我這里定義的是rr然后我教你們這么記就記r開頭的 和_后的比如ru就是讀未提交,就等于沒得事務,什么都處理不了rc讀以提交,當然就是處理臟讀的了rr重復讀,當然就是處理不能重復讀的問題啦ser這個什么的太長了,就是序列化,當然就是什么都可以處理但是注意:事務用的越多對多線程的處理就越垃圾 ```java//開啟重復讀事務@Override@Transactional(isolation = Isolation.REPEATABLE_READ)//isolation 中的五個隔離級別public enum Isolation {DEFAULT(-1),READ_UNCOMMITTED(1),READ_COMMITTED(2),REPEATABLE_READ(4),SERIALIZABLE(8);private final int value;private Isolation(int value) {this.value = value;}public int value() {return this.value;} }MySQL的鎖了解嗎? 博主這里就只知道樂觀,悲觀鎖
這里百度幫你們粘貼了幾個核心 行級鎖 表示只針對當前操作的行進行加鎖,開銷大,加鎖慢;會出現死鎖 表級鎖 表示對當前操作的整張表加鎖,開銷小,加鎖快;不會出現死鎖 頁級鎖 頁級鎖是MySQL中鎖定粒度介于行級鎖和表級鎖中間的一種鎖,開銷和加鎖時間界于表鎖和行鎖之間;會出現死鎖數據庫的樂觀鎖和悲觀鎖是什么?怎么實現的?
悲觀鎖是什么時候都給自己加鎖,查詢完后就吧事務鎖起來,使用的是數據庫中的鎖機制 樂觀鎖:通過version來進行鎖定,假如一個事務執行修改,這個時候sql語句定義version=0的 時候再修改,然后修改的時候吧這個version該為1,然后下一個事務也是要version=0的時候再 進行修改,這個時候就做到了樂觀鎖,詳細的可以看mybtisplus官網,mybtisplus可以自動幫 我們做這個樂觀鎖的操作Spring
談談你對spring的理解
spring我的理解就是輕量級的javaEE開發框架,幫助咱們開發人員實現復雜的網址后端服務 其中核心就是IOC,控制反轉和AOP面向切面,極大的降低咱們企業級開發的復雜度博主洽談IOC
其實IOC并不是什么新的技術,而是一種設計思想,原始的開發方式是new對象,還需要我們 自己去維護,那么有了IOC之后我們就可以將自己設計好的類統一的交給容器去管理就完事了那么如何去實現呢?通過DI,也就是依賴注入然后在標簽中的 autoWired 可以定義自動注入:通過byName,byType注入值的方式有:set方法注入構造方法注入注解注入那么注入到容器當中我們知道了,那么咱們去取容器當中的bean呢?通常我們使用@Resource 注解 優先通過名字再是類型去看容器里面有沒有bean,如果沒有設置name,那么就會根據我們的屬性的名字當作是name去進行查找 @AutoWired 注解 這個是spring的注解,默認按類型查看容器,如果需要以名字查找還需要在下面加應該@Qualifier("容器id")去進行查找,還可以設置那個是主bean,設置了之后如果bytype找到同樣屬性的bean后會使用主bean,還有bean的優先級和主bean同理,不設置的話如果找到多個spring不知道用哪個則會報錯然后spring創建出來的bean默認是單例的,那么可以變成多例嗎?當時是可以,就是作用域,我一次面試被問我都傻了,不過也還是通過了面試了呢singleton單例prototype每調用一次new一個request Http協議中,調用一次生成一個session Http協議中一個會話一個博主洽談AOP
AOP就是面向切面,在不改變原有代碼的情況下去追加新的功能,一般我們都用來做日志,權限等...博主這里也用來做數據在后端的校驗,切入我們每一個新增的方法,得到方法后的參數類型再得到校驗返回 的異常信息,然后將異常返回到前端就完事了AOP的底層就是用的動態代理的設計模式去實現的又分了jdk原生的動態代理通過invkehedler(單詞記不清懶得搜了都是手敲的)去實現同一個接口的這種方式去代理的CjLib的動態代理生成子類去進行功能動態的追加然后就是那幾個名詞了,我用代碼邏輯的方式去講解________________________________________就拿校驗來說,如果我們要做一個校驗那么我們肯定是要定義一個 **切面** 然后在切面當中去定義我們的**增強**類型(前置,后置,環繞,異常,最終),還有我們的**切點**用注解的方式其實這完成了**切點**是我們要對那個邏輯進行增加,就是連接點**增強**就是我們追加的功能**連接點**就是我們被增強的那個方法的位置**織入**就是將切點放到外面的增強當中去,讓增強知道去增強那個地方spring的生命周期
1、通過一個類的class通過反射去實例化得到對象,中間還需要推斷使用哪個構造方法
2、得到對象后就需要進行屬性填充,就是我們的DI依賴注入
3、afterPropertiesSet()這個方法看執行可以不執行,相當于bean的init()方法,在注入屬性后就會執行到這個方法,比如當前我們的Userservice類中有一個user的引用沒有賦值(注意這個user不是bean),需要每一個用戶調用bean的時候去進行賦值得到每一個用戶獨有的user對象,那么就可以使用這個方法,在這個方法里面進行賦值
4、這個時候就執行到AOP了,會通過得到的這個類的信息去看我們的切面當中有沒有和這個類匹配的切點什么的,如果沒有的話就直接生成我們需要的bean了,如果有和切點匹配的方法那么就會生成一個代理類,我們最終得到的其實是一個代理類的bean
5、得到這個bean了當然就是進行調用了
6、調用完后就不歸我們管理了,我理解的就是不用的時候spring會幫我們銷毀掉
spring的循環依賴
A依賴B
B依賴C
A依賴C
這種情況,博主在創建文件操作工具類的時候,依賴了一個工具類去開啟文件服務器鏈接,需要的參數,服務器地址,用戶名密碼等等又是通過另一個類從配置中心拿,然后在工具類中去使用,就會導致在加載的時候參數那個類還沒通過反射住入到容器中,我不知道這個算不算依賴住入,我當時的解決方案是將參數那個類刪了,直接在工具類通過@value去配置文件拿這樣就解決了,網上的方案說是開啟三級緩存解決循環依賴
spring的單例bean是線程安全的嗎?
Spring中的單例bean并沒有做多線程處理,如果說你某個bean當中有計數的變量則需要自己維護,最簡單的辦法就是將這個單例的bean改成多例的就完事了
spring中用到了那些設計模式
1、工廠模式,BeanFactory就是其中一個
2、單例模式,保證一個類只有一個實例,提供全局訪問
3、適配器模式,每個controller都有對應的適配器,涉及到SpringMVC的執行流程,當請求進到controller的時候會通過headlr映射處理器處理heandler后到適配器找到對應的controller后執行完邏輯再去視圖解析器處理返回,最后將視圖返回
4、AOP的動態代理
spring事務
就是利用aop去做的事務,去生成代理類去進行事務的處理,這個時候我們從一個事務中去調用另一個事務的時候就涉及到了事務的傳播(下面有事務的傳播),默認是requied這個默認的,但是我們設置其他的傳播機制的時候想要生效就必須要把這個類的bean去注入進來,用這個bean去調用我們的a方法才能去用其他的一個傳播機制
Transaction事務的傳播機制
spring中的事務的傳播它是指a事務調用b事務之間的印象,傳播類型一般作用在后面那個 事務 required默認的就是這個,如果a沒事務則b就新建事務,如果有則加入這個事務 supports如果a有事務b就加入,a沒有那b也不加入事務 mandatory如果a有事務b就加入,如果沒有就拋異常 requlres_new讓a和b各自處理自己的事務 not_supported不管a有沒有事務,b都是按沒事務來運行 never a有事務b拋出異常 nested 就和默認的差不多哪些注解各位小伙伴做一個項目就收悉了,也可以百度一下,我個人懶得記那么多,看臨時發揮,都是些簡單的
SpringMVC
什么是SpringMVC
是spring針對web開發的一個一站式的解決方案,是基于web的框架,提供一個總的servlet 去收發請求處理結果,解析視圖一般都是問的執行流程,SpringMVC的執行流程
各位小伙伴不要死記硬背,這個東西要理解流程就是用戶發送請求給外面的核心servlet,然后我這就用servlet去代替,懶得打字了 servlet收到請求后通過映射的處理器去請求handler得到具體要處理那個controller的處理器的 handler返回給servlet再去找到處理這個handler的處理適配器去處理后返回modelandview給 servlet再去訪問視圖解析器去解析完再返回到servlet去調用視圖解析器再返回視圖讓servlet去 渲染給用戶解決亂碼問題
1、通過在web.xml文件中去設置CharacterEncodingFiter攔截器去攔截,設置encoding為utf-8 2、修改tomcat中的配置config.xml的那個文件里面的標簽找到encoding設置為utf-8 3、得到的默認是8859-1,可以通過轉byBytes()將88t9-1轉換成utf-8SpringMVC是不是單例模式
是單例的,如果是多線程去訪問的時候我們可能會遇到訪問同一個對象導致數據問題,我們可 以使用ThreandLock去定義公共訪問的變量,ThreandLock專門就是為了應對這種場景的我百度了一下問題,大部分都是在基本操作的基礎上去進行題目的改變來問技術,這些只要熟練使用就不會有問題的
MyBatis
MyBatis基礎
談談什么是MyBatis?
MyBatis是數據持久層的一個半ORM框架,封裝的JDBC的一些基本操作,不需要我們去進行哪些繁瑣 我們只需要去關注sql語句就好了,將sql語句都定義的映射文件當中方便我們的管理,可以大大縮短我 們的開發時間,但是因為sql語句是定義在映射文件中,那么我們要從mysql轉換使用其他的數據庫的 時候會特別不方便稍微深一點
通常一個Xml映射文件,都會寫一個Dao接口與之對應,請問,這個Dao接口的工作原理是什么?Dao接口里的方法,參數不同時,方法能重載嗎?
MyBatis底層是通過我們映射文件當中定義的namespes的名字,以及寫sql標簽上的id去對應我 們動態代理去生成dao接口的全限定類名再準確找到方法進行執行,所以方法不能重載,不然不 知道要執行那個${}與#{}的區別
${}的在定義到sql里面去的時候會先進行運算操作 #{}在定于sql的時候相當于占位符,在sql中相當于‘?’有效防止sql注入問題動態標簽?
set if trim where schoose foreach 一共9個我就記得這些常用的,別的我也記不得懶得寫了一級、二級緩存
一級緩存默認開啟,SqlSession級別的緩存 二級緩存在配置文件中把cacheEnablod設置為ture,在映射文件中的sql上中定義二級緩存 的開啟MyBatis如何進行分頁
可以通過插件那個pageh什么p的,麻煩百度一下我不會寫哈哈哈 然后要自己定義的話要先求出總行數,得到每頁顯示數,就可以得到頁數,然后通過傳入當前頁去進行分頁查詢傳入傳出參數
resultmap和resulttype,type底層其實就是用的resultmap,resultmap一般用來對應一對多 或者多對一的場景,使用ass什么tion的進行一對一,使用colltion進行一對多的操作, 傳入參數可以傳對象,或者使用@prom(“#{}中的name”)或者傳入map 傳出參數一般是傳對象Springboot
什么是SpringBoot
SpringBoot就是用來簡化spring應用開發的復雜度,在ssm的項目中我們需要配置特別多的xml配bean的操作,特別 繁瑣,springboot就把之前ssm項目中我們需要初始化配置的哪些xml配bean給砍掉,自動的去幫我們配置springbootApplication的運行機制
springboot通過根據配置文件自動裝配所屬依賴的類,再用動態代理的方式注入到容器里面
Spring Boot 的核心注解是哪個?
@SpringBootConfiguration:組合了 @Configuration 注解,實現配置文件的功能,用來標注一個類為配置類
@EnableAutoConfiguration:里面包含倆個注解
@ AutoConfigurationPackage:將主配置類所在的包作為自動配置的包進行管理
@import:導入類到ioc容器中,根據MATA-INFO/spring.factories下的
@ComponentScan:spring組件掃描,將指定需要掃描的包下的組件注冊到容器里面去
上一題其實也是自動配置的原理
自動配置的原理其實也很簡單,博主打比方時間到 比如要和MyBatis整合,那么MyBatis的依賴會提供一個使用@Configuration+@bean 的一個配置類,然后放到META-INF/spring.factories下去,然后通過spring.spi去掃描,再用@import導入自動配置類Redis
學習入口:https://blog.csdn.net/weixin_43829443/article/details/112839985?spm=1001.2014.3001.5506
redis主從復制的核心原理
redis主從復制只需要區分全量復制和部分復制;就是從一個服務器復制另一個服務器的數據,主數據庫可以進行讀寫操作,從數據庫一般都是進行度數據,并且接受主數據庫同步過來的數據,一個主數據可以擁有多個從數據庫。
全量復制:(RDB相當于快照復制和AOF復制相當于存儲的每一條操作記錄)
1、主節點通過命令將進程進行RDB鏡像的持久化,該過程非常消耗CUP硬盤IO
2、主節點再通過網絡將鏡像(RDB)文件發送給從節點,對從節點的寬帶都會帶來很大的消耗
3、從節點清空老數據,載入新的RDB文件的過程是阻塞的,無法響應客戶端的命令;如果從節點執行AOP復制數據也會帶來額外的消耗
部分復制:
1、需要復制偏移量,執行復制的雙方(主從節點)都要記錄一個偏移量好知道同步的進度
2、復制積壓緩沖區:主節點維護的一個隊列,先進先出的,從偏移量之后的數據開始存到緩沖區,但是緩沖區長度太長了,就會無法執行部分復制,就只能執行全量復制
3、主節點的服務器運行ID,每個redis的節點都有運行id,主節點在同步的時候會將運行id發送給從節點,如果 節點宕機了掛了就只能進行全量復制了,因為無法確認偏移量
redis過期健刪除策略
惰性刪除,有訪問的時候才去刪除
定期刪除,隔一段時間去刪除一定量的key
redis線程模型,單線程快的原因
redis的處理器是文件事件處理器,這個文件事件處理器是單線程的,所有redis才叫做單線程模型
單線程快的原因:純內存操作,核心是基于非阻塞io的多路復用,單線程反而避免了上下文切換的性能問題
緩存雪崩,緩存穿透,緩存擊穿
1、緩存雪崩是指同一時間大面積緩存失效啊,比如重啟緩存這種,就會導致請求都到了數據庫上,造成數據庫短時間承受太多請求導致崩掉
解決方案:
1)緩存的過期時間錯開,防止同一時間大量緩存過期
2)緩存預熱
2、緩存穿透是指緩存和數據庫中都沒有數據,導致請求都落到數據庫上
解決方案:
1)接口層增加校驗
2)都取不到數據庫的情況就設置這個key值為null的到redis,緩存時間設置短一點,可以防止反復的請求到同一個key被攻擊的情況
3)采用布隆過濾器,將可能存在的數據哈希到bitmap中,一定不存在的數據就會被攔截掉,從而避免對數據庫的請求
3、緩存擊穿是指緩存中沒有數據,當時同事并發量特別大,緩存沒讀到數據都去讀數據庫,導致數據庫壓力瞬間增大,和雪崩不同的是擊穿指的是某一條熱點數據
解決方案:
1)設置熱點數據永不過期
2)增加互斥鎖(就是在一個請求進入到這個key的時候就將這個key鎖上不讓其他請求進入)
(redis緩存問題)圖片采用 地址
redis事務實現
redis開啟事務,multi(嗎體奧)命令,標識開啟事務
客戶端進入事務狀態之后,執行的所有常規 Redis 操作命令(非觸發事務執行或放棄和導致入列異常的命令)會依次入列,命令入列成功后會返回 QUEUED
exec命令服務器就會執行事務
mq消息隊列
選擇使用那個中間件
RocketMQ特有的延遲隊列怎么實現的
在發送消息后加個中間層去存要發的消息,存延遲的時間,再返回給要發送的mq隊列中,再進行消費
RocketMQ保證事務一致性
在發送消息的時候會變成半發送狀態,不會發送給消費者消費,直到檢查到本地事務提交或者回滾后才會操作mq發送或者不發送
微服務
談談對微服務的理解,微服務有哪些優缺點
微服務就是一種架構風格,將大型的單體應用劃分成較小的服務單元,降低系統的復雜度
優點:
缺點:
SpringCloud
我的理解就是前面說的了單體服務的問題所在,那么用微服務肯定是要搭建集群的,那么客戶端服務端的都是集群搭建的,中間怎么去進行調用呢?我們就需要用到Eureka去進行服務的注冊與發現;那么服務注冊與發現好了,我們可以調用到我們的服務提供者了,但是又會有問題,如果a服務端用戶訪問的太多,b服務用戶訪問的少就造成了資源浪費,這個時候就需要用到Ribbon去進行負載均衡,調用服務端的方式還可以使用Feign,一種就好比是接口的形式去調用,一種就直接訪問的url;訪問沒問題了,這個時候又可能會出現服務端炸了啊或者怎么樣服務端出現問題了,那么服務消費肯定調用會報錯的,這個時候我們不能讓錯誤信息展示給用戶,所以又需要Hytrix去做服務熔斷和降級;這些問題都處理好了后又有服務端不好管理的問題,因為服務器的地址又不一致,所以這個時候我們就用zuul網關來解決這個問題
SpringCloudAlibaba
1、注冊中心使用nacos去注冊發現服務,以及服務的健康檢測,默認5s發送一次心跳;
2、那么注冊中心有了服務直接就可以互相調用了,但是微服務架構中每個服務都是集群的,如果是倆個服務器中有個服務器一直被訪問,另一個服務器的訪問量又極少,就會造成資源浪費,這個時候就需要用到負載均衡了,而我們的nacos已經集成了Ribbon去做客戶端的負載均衡(ribbon做的事情就是發現域名下機器,并且負載均衡的調用),會通過輪詢隨機權重去調用不同服務器的同一個服務,但是需要加上@LoadBalanced注解將RestTemplate注入到spring中;
2.1)原理:ribbon中有一個攔截器,在調用中會拿到url將域名解析出來,將域名發到注冊中心,用服務名將所有注冊中心的機器列表都拉到本地緩存中
2.2)openFeign,讓我們調用變得更加方便,就像調用本地方法一樣,調用端需要在啟動類加@EnableFeignClients注解,只需要寫調用遠端服務的Feign接口即可
2.3.1)原理:在feign接口會被代理,代理方法會將注冊中心的服務名拿到再去做負載均衡調用
3、Sentinel做服務熔斷降級限流
3.1、降級:(調用端)降級功能需要在feign接口中加fallback屬性中加fallback實現類,做折中的降級處理,原理就是動態代理去實現feign接口時用try cath處理 ,感知到報錯就在cath中調用fallback實現類
3.2、限流:(被調用端)需要安裝Sentinel客戶端,并且在服務中配置Sentinel的地址,這樣被調用的的請求都會在Sentinel的客戶端中的鏈路追蹤中就可以進行流控
3.3、熔斷:Sentinel客戶端中配置熔斷,如果調用鏈路異常次數超過設置的則就將這個調用鏈路熔斷掉,不再被調用
限流熔斷原理:熔斷就是多次進行遠程調用的失敗的時候就會進行屏蔽掉遠程服務,就把這個鏈路直接斷掉
4、網關Gatway 做路由轉發,權限校驗,灰度發布
shiro
什么是shiro
Shiro是一個強大易用的Java安全框架,主要用來認證、授權、加密、會話管理、與Web集成、緩存,相比其他安全框架shiro小的多,安全的多
Shiro的核心概念Subject、=SecurityManager、Realm
1、Subject :當前用戶的操作
2、SecurityManager:用于管理所有的Subject
3、Realms:用于進行權限信息的驗證
常用的組件
Authentication:身份認證/登錄,驗證用戶是不是擁有相應的身份;
Authorization:授權,即權限驗證,驗證某個已認證的用戶是否擁有某個權限
Session Manager:會話管理,即用戶登錄后就是一次會話
Cryptography:加密,保護數據的安全性,如密碼加密存儲到數據庫,而不是明文存儲;
Web Support:Web支持,可以非常容易的集成到Web環境;
Caching:緩存,比如用戶登錄后,其用戶信息、擁有的角色/權限不必每次去查,這樣可以提高效率;
Concurrency:shiro支持多線程應用的并發驗證,即如在一個線程中開啟另一個線程,能把權限自動傳播過去;
Testing:提供測試支持;
Run As:允許一個用戶假裝為另一個用戶(如果他們允許)的身份進行訪問;
Remember Me:記住我,這個是非常常見的功能,即一次登錄后,下次再來的話不用登錄了。
Liunx
當前目錄
pwd
查看文件
ls
查看文本文件
cat 文件
修改文本文件vi編輯器
在查看文件的使用按下i進入輸入模式就可以更改了,更改后按esc然后用wq!進行保存退出
復制文件
cp source dest 復制文件
cp -r sourceFolder targetFolder 遞歸復制整個文件夾
scp sourecFile romoteUserName@remoteIp:remoteAddr 遠程拷貝
創建目錄
mkdir
刪除目錄
rmdir deleteEmptyFolder 刪除空目錄
rm -rf deleteFile 遞歸刪除目錄中所有內容
移動文件
mv /temp/movefile /targetFolder
重命名
mv oldNameFile newNameFile
切換用戶
su -username
壓縮文件
tar -czf test.tar.gz /test1 /test2
網絡檢測
ping 網址
telnet
總結
以上是生活随笔為你收集整理的java面试突击-2022最新迭代redis\mq\springCloud-纯手打的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 点击开台.
- 下一篇: 倒计时器c语言,在线倒计时器