毛片a做片在線觀看網站有哪些鄭州seo優(yōu)化公司
面試總結:總體不難,算法題腦抽了只過了一半,面試官點出了問題說時間到了,反問一點點,感覺五五開,許愿一個二面
1.Java中的鎖機制,什么是可重入鎖
Java中的機制主要包括
-
synchronized
關鍵字 -
Lock接口及其實現(xiàn)類(
如ReentrantLock
) -
原子類(如
AtomicInteger
) -
volatile關鍵字,僅保證可見性和有序性
可重入鎖
可重入鎖是指同一個線程在外層方法獲取鎖的時候,再進入該線程的內層方法會自動獲取鎖,不會因為之前已經獲取過還沒釋放而阻塞。Java中ReentrantLock
和synchronized
都是可重入鎖。
可重入鎖的實現(xiàn)原理:
- 記錄鎖的持有線程
- 維護一個計數(shù)器
- 當計數(shù)器為0時,表示鎖沒有被任何線程持有
- 當持有鎖的線程再次請求鎖時,計數(shù)器+1
- 當線程退出同步代碼塊時,計數(shù)器-1
- 計數(shù)器為0時釋放鎖
可重入鎖的優(yōu)點:
- 避免死鎖
- 提高了鎖的靈活性
2.AQS (AbstractQueuedSynchronizer)
AQS是Java并發(fā)包中的核心基礎組件,用于構建鎖或者其他同步組件。
AQS使用一個int成員變量表示同步狀態(tài),通過內置的FIFO隊列來完成資源獲取線程的排隊工作。
AQS的核心思想:
- 如果被請求的共享資源空閑,則將當前請求資源的線程設置為有效的工作線程,并且將共享資源設置為鎖定狀態(tài)。
- 如果被請求的共享資源被占用,那么就需要一套線程阻塞等待以及被喚醒時鎖分配的機制。
AQS的主要方法:
acquire(int)
: 獨占式獲取同步狀態(tài)release(int)
: 獨占式釋放同步狀態(tài)acquireShared(int)
: 共享式獲取同步狀態(tài)releaseShared(int)
: 共享式釋放同步狀態(tài)
AQS的實現(xiàn):
- 使用一個
volatile
的int類型的成員變量來表示同步狀態(tài) - 使用一個FIFO隊列來完成資源獲取的排隊工作
- 使用
CAS
來原子性地修改同步狀態(tài)值
AQS的應用:
- ReentrantLock
- Semaphore
- CountDownLatch
- ReentrantReadWriteLock
- ThreadPoolExecutor
3.Redis相關數(shù)據結構,為什么每種數(shù)據類型一般都有兩種數(shù)據結構?
Redis的主要數(shù)據結構
- String: 簡單動態(tài)字符串(SDS)
- List: 雙向鏈表和壓縮列表(ziplist)
- Hash: 哈希表和壓縮列表
- Set: 哈希表和整數(shù)集合(intset)
- Sorted Set: 跳表(skiplist)和壓縮列表
每種數(shù)據類型一般都有兩種數(shù)據結構的原因
- 空間和時間的權衡
- 數(shù)據量小的時候使用更加緊湊的數(shù)據結構,節(jié)省內存
- 數(shù)據量大的時候轉換為普通數(shù)據結構,提高操作效率
以Hash為例:
- 當field-value長度較短且個數(shù)較少時,使用壓縮列表
- 當數(shù)據量增大時,轉換為哈希表
這種設計能夠在內存使用和性能之間取得很好的平衡。
4.JVM相關內存結構,GC
JVM內存結構
- 堆(Heap)
- 年輕代(Young Generation)
- Eden空間
- Survivor空間(From和To)
- 老年代(Old Generation)
- 年輕代(Young Generation)
- 方法區(qū)(Method Area)
- 永久代(JDK 8之前)/元空間(JDK 8及以后)
- 程序計數(shù)器(Program Counter Register)
- 虛擬機棧(VM Stack)
- 本地方法棧(Native Method Stack)
GC(垃圾回收)
垃圾回收算法:
- 標記-清除算法
- 復制算法
- 標記-整理算法
- 分代收集算法
垃圾收集器:
- Serial收集器
- ParNew收集器
- Parallel Scavenge收集器
- Serial Old收集器
- Parallel Old收集器
- CMS收集器
- G1收集器
GC觸發(fā)時機:
- Minor GC:清理新生代。
- Major GC:清理老年代。
- Full GC:清理整個堆,包括新生代和老年代。
5.HashMap底層原理
HashMap的底層數(shù)據結構是數(shù)組+鏈表+紅黑樹(JDK 1.8及以后)。
主要屬性:
- Node<K,V>[] table: 存儲數(shù)據的數(shù)組
- int size: 實際存儲的鍵值對數(shù)量
- int threshold: 擴容閾值
- float loadFactor: 負載因子
put操作流程:
- 對key的
hashCode()
進行hash操作 - 計算index =
(n - 1) & hash
- 如果沒碰撞,直接放到bucket里
- 如果碰撞,以鏈表的形式存在buckets后
- 如果鏈表長度超過8,轉換為紅黑樹
- 如果size超過threshold,進行擴容
get操作流程:
- 對key的
hashCode()
進行hash操作 - 計算index =
(n - 1) & hash
- 遍歷該位置上的鏈表或紅黑樹
擴容機制:
- 當size超過
threshold
時進行擴容 - 擴容時,容量變?yōu)?strong>原來的2倍
- 重新計算每個元素在數(shù)組中的位置(再散列)
6.MySQL索引類型,索引失效,覆蓋索引,hash索引
MySQL索引類型
- B+樹索引(默認)
- Hash索引
- Full-text全文索引
索引失效的情況
- 使用!=或<>操作符
- 使用函數(shù)或表達式
- 類型隱式轉換
- 使用OR連接條件
- like以%開頭
- 不滿足最左前綴原則
覆蓋索引
查詢的數(shù)據列恰好是索引的一部分,可以直接從索引中獲取數(shù)據,不需要回表查詢。
Hash索引
- 基于哈希表實現(xiàn),只有精確匹配才有效
- 不支持范圍查詢
- 不支持排序
- 不支持部分索引列匹配查找
Hash索引 vs B+樹索引:
- Hash索引只支持等值查詢,B+樹索引支持范圍查詢
- Hash索引不支持排序,B+樹索引天然支持排序
- Hash索引不支持最左前綴匹配,B+樹索引支持
7.Spring IOC AOP原理,循環(huán)依賴解決
IOC(控制反轉)
- 核心是BeanFactory和ApplicationContext
- 通過反射機制實例化bean并建立bean之間的依賴關系
- 管理bean的生命周期
AOP(面向切面編程)
- 核心是ProxyFactory
- 兩種代理方式:JDK動態(tài)代理和CGLIB
- 通過織入切面來實現(xiàn)功能的統(tǒng)一維護
循環(huán)依賴解決
Spring通過三級緩存解決循環(huán)依賴
- 一級緩存,singletonObjects: 完全初始化好的bean
- 二級緩存,earlySingletonObjects: 實例化但未初始化的bean
- 三級緩存,singletonFactories: 存放BeanFactory的實例
解決流程:
- 創(chuàng)建bean實例
- 將創(chuàng)建的bean實例放入三級緩存
- 填充屬性
- 如果發(fā)現(xiàn)循環(huán)依賴,嘗試從三級緩存中獲取
- 沒有循環(huán)依賴,將bean放入一級緩存
構造函數(shù)的循環(huán)依賴無法解決,因為實例化和初始化是一體的。
8.MyBatis相關,#和$區(qū)別
MyBatis是一個優(yōu)秀的持久層框架,它支持定制化SQL、存儲過程以及高級映射。
#{}和${}的區(qū)別:
- #{}是預編譯處理,會將參數(shù)替換為?
- ${}是字符串替換,直接將參數(shù)值拼接到SQL中
使用場景:
- #{}用于SQL語句中的值
- ${}用于動態(tài)表名、列名等
安全性:
- #{}可以防止SQL注入
- ${}不能防止SQL注入
9.線程池相關,流程,拒絕策略,如何設計線程池最大線程數(shù)和核心線程數(shù)
線程池執(zhí)行流程
- 如果運行的線程少于
corePoolSize
,則創(chuàng)建新線程來處理請求 - 如果運行的線程等于或多于corePoolSize,則將請求加入隊列
- 如果無法將請求加入隊列,則創(chuàng)建新的線程來處理請求
- 如果創(chuàng)建新線程使當前運行的線程超出
maximumPoolSize
,任務將被拒絕
拒絕策略
AbortPolicy
: 丟棄任務并拋出RejectedExecutionException異常(默認)DiscardPolicy
: 丟棄任務,但是不拋出異常DiscardOldestPolicy
: 丟棄隊列最前面的任務,然后重新嘗試執(zhí)行任務CallerRunsPolicy
: 由調用線程處理該任務
如何設計線程池最大線程數(shù)和核心線程數(shù)
- CPU密集型任務: 線程數(shù) = CPU核心數(shù) + 1
- IO密集型任務: 線程數(shù) = CPU核心數(shù) * (1 + 平均等待時間/平均工作時間)
一般而言:
- 核心線程數(shù) = CPU核心數(shù)
- 最大線程數(shù) = CPU核心數(shù) * 2
實際應用中,可以通過壓測來確定最優(yōu)的線程池參數(shù)。
10.HashMap和ConcurrentHashMap
HashMap:
- 非線程安全
- 允許null鍵和null值
- 初始容量16,負載因子0.75
- JDK 1.8后,鏈表長度超過8會轉換為紅黑樹
ConcurrentHashMap:
- 線程安全
- 不允許null鍵和null值
- JDK 1.7使用分段鎖(Segment)
- JDK 1.8使用CAS+Synchronized
ConcurrentHashMap的實現(xiàn)(JDK 1.8):
- 使用
volatile
數(shù)組保存Node - 使用
CAS
操作保證數(shù)組的原子性 - 使用
Synchronized
鎖定鏈表或紅黑樹的首節(jié)點
put操作:
- 如果bucket為空,使用CAS操作放入
- 如果bucket非空,使用Synchronized鎖定首節(jié)點
- 執(zhí)行鏈表或紅黑樹的插入操作
get操作:
- 不需要加鎖,利用volatile的可見性保證
11.紅黑樹,二叉查找樹,紅黑樹高度差
二叉查找樹:
- 左子樹所有節(jié)點的值均小于根節(jié)點的值
- 右子樹所有節(jié)點的值均大于根節(jié)點的值
- 左右子樹也分別為二叉查找樹
- 時間復雜度: 平均O(logn),最壞O(n)
紅黑樹:
- 每個節(jié)點要么是紅色,要么是黑色
- 根節(jié)點是黑色
- 每個葉子節(jié)點(NIL)是黑色
- 如果一個節(jié)點是紅色的,則它的子節(jié)點必須是黑色的
- 從一個節(jié)點到該節(jié)點的子孫節(jié)點的所有路徑上包含相同數(shù)目的黑節(jié)點
紅黑樹的高度:
- 最短路徑: 全黑節(jié)點
- 最長路徑: 紅黑相間
- 最長路徑的長度不會超過最短路徑的2倍
紅黑樹 vs 平衡二叉樹:
- 紅黑樹犧牲了部分平衡性以換取插入/刪除操作時少量的旋轉操作
- 紅黑樹的統(tǒng)計性能要好于平衡二叉樹
12.MySQL索引
MySQL索引類型
- 普通索引
- 唯一索引
- 主鍵索引
- 聯(lián)合/組合索引
- 全文索引
B+樹索引的特點:
- 所有數(shù)據都存儲在葉子節(jié)點
- 葉子節(jié)點形成一個單向鏈表
- 非葉子節(jié)點只存儲鍵值信息
索引的優(yōu)點:
- 加快數(shù)據檢索速度
- 唯一索引可以保證數(shù)據的唯一性
- 加快表與表之間的連接
索引的缺點:
- 占用額外的存儲空間
- 降低更新表的速度
13.如何判斷鏈表有環(huán),如何判斷樹是二叉查找樹
判斷鏈表是否有環(huán)
快慢指針法
- 定義兩個指針,快指針每次移動兩步,慢指針每次移動一步
- 如果存在環(huán),兩個指針最終會相遇
- 時間復雜度O(n),空間復雜度O(1)
哈希表法
- 遍歷鏈表,將每個節(jié)點存入哈希表
- 如果當前節(jié)點已在哈希表中,說明存在環(huán)
- 時間復雜度O(n),空間復雜度O(n)
判斷樹是否為二叉搜索樹:
中序遍歷法
- 對二叉樹進行中序遍歷,結果應該是升序的
遞歸法
- 遞歸判斷,利用二叉搜索樹的性質,對于每個節(jié)點,它的左子節(jié)點值必須小于當前節(jié)點值,右子節(jié)點的值必須大于當前節(jié)點值,并且所有節(jié)點需要滿足這個條件。
14.Redis分布式鎖
Redis分布式鎖的實現(xiàn)原理
- 加鎖: 使用SETNX命令設置一個鍵值對,如果鍵不存在則設置成功并獲得鎖
- 解鎖: 刪除該鍵值對
- 超時: 設置鍵的過期時間,防止死鎖
實現(xiàn)細節(jié)
- 使用Lua腳本保證加鎖操作的原子性
- 使用唯一標識符(如UUID)作為值,防止誤刪其他客戶端的鎖
- 考慮Redis主從復制的延遲問題,使用Redlock算法
15.限流算法
- 計數(shù)器算法:基于時間窗口的請求數(shù)統(tǒng)計。
- 滑動窗口:將計數(shù)器細分成多個更小的時間窗口。
- 令牌桶算法:維持一個令牌桶,系統(tǒng)請求需拿到令牌。
- 漏桶算法:確保請求處理的穩(wěn)定速率,通過漏水的速率控制請求速率。
更多驚喜
我還將定期分享:
-
最新互聯(lián)網資訊:讓你時刻掌握行業(yè)動態(tài)。
-
AI前沿新聞:緊跟技術潮流,不斷提升自我。
-
技術分享與職業(yè)發(fā)展:助你在職業(yè)生涯中走得更遠、更穩(wěn)。
-
程序員生活趣事:讓你在忙碌的工作之余找到共鳴與樂趣。
關注回復【1024】驚喜等你來拿!