欧美1区2区3区激情无套,两个女人互添下身视频在线观看,久久av无码精品人妻系列,久久精品噜噜噜成人,末发育娇小性色xxxx

(高頻問題)161-180 計算機 Java后端 實習 and 秋招 面試高頻問題匯總

專欄簡介

161. Kafka分區(qū)機制與多實例環(huán)境下的消息順序性

Kafka通過分區(qū)(Partition)機制來提高吞吐量和實現(xiàn)負載均衡。在單個分區(qū)內部,Kafka能夠保證消息的嚴格順序性,即消息按照生產者發(fā)送的順序被存儲和消費。如果生產者將一系列消息指定發(fā)送到同一個分區(qū),并且這些消息都成功寫入,那么消費者在拉取該分區(qū)的消息時,將嚴格按照發(fā)送順序接收到它們。

然而,在多實例部署的生產者環(huán)境中,即使指定了分區(qū),也可能出現(xiàn)消費者感知到的消息順序與預期不符的情況。這主要源于以下幾個因素:

首先,多個生產者實例并發(fā)地向同一分區(qū)發(fā)送消息時,網(wǎng)絡延遲、客戶端處理速度差異以及Broker端的處理時序可能導致消息實際落盤的順序與任何單個生產者的發(fā)送順序不一致,形成局部的亂序。

其次,生產者的消息重試機制可能導致亂序。當一條消息發(fā)送失?。ㄈ缇W(wǎng)絡抖動或Broker短暫不可用)后,生產者會進行重試。如果在重試成功之前,后續(xù)的消息已經先一步發(fā)送成功,那么最終存儲在分區(qū)中的順序就會與原始發(fā)送順序不同。

再次,異步發(fā)送模式下,消息發(fā)送請求的完成順序并不一定與調用發(fā)送API的順序一致,這也可能影響消息抵達Broker并被存儲的順序。

最后,雖然不常見,但若在生產過程中分區(qū)策略發(fā)生改變(例如,通過某種動態(tài)邏輯決定分區(qū))或分區(qū)數(shù)量本身進行了調整,也可能間接影響依賴特定分區(qū)順序的消費邏輯。

為了在多實例環(huán)境下最大程度保證業(yè)務所需的順序性,可以考慮采用單一生產者實例負責關鍵順序消息的發(fā)送,或者在多個生產者之間實現(xiàn)嚴格的協(xié)調機制(如分布式鎖或序號生成器)來控制發(fā)送順序。同時,消費者端也可以設計具備排序能力的邏輯,例如根據(jù)消息體中包含的時間戳或業(yè)務序列號進行重排序,以應對潛在的順序問題。

162. Redis鍵刪除后的內存回收機制與碎片化處理

Redis在接收到客戶端執(zhí)行的 DEL 命令刪除一個鍵時,會觸發(fā)其內部的內存回收流程。Redis自身管理內存,通常使用如jemalloc這樣的高效內存分配器,而非直接依賴操作系統(tǒng)的標準內存管理。

內存回收主要依賴引用計數(shù)(Reference Counting)機制。Redis中的數(shù)據(jù)對象(如字符串、哈希、列表等)都關聯(lián)有引用計數(shù)。當執(zhí)行DEL命令時,Redis會找到該鍵所關聯(lián)的值對象,并減少其引用計數(shù)。一旦對象的引用計數(shù)降為0,表明不再有任何內部結構或鍵指向該對象,該對象占用的內存就可以被回收了。

內存的實際釋放由Redis集成的**內存分配器(如jemalloc)**負責。標記為可回收的內存會被內存分配器收回,這部分內存隨后可以被用于存儲新的數(shù)據(jù)。對于較大的內存塊,分配器可能會將其歸還給操作系統(tǒng);對于較小的內存塊,則通常保留在分配器的內部池中,以便快速復用,減少向操作系統(tǒng)申請內存的開銷。

需要注意的是,頻繁的鍵創(chuàng)建和刪除操作,尤其是在對象大小不一的情況下,可能導致內存碎片化。即物理內存中存在許多小的、不連續(xù)的空閑塊,雖然總空閑內存可能很多,但無法分配給需要較大連續(xù)內存的新對象。

為緩解此問題,較新版本的Redis提供了在線內存碎片整理(Active Defragmentation)功能。通過配置開啟后,Redis可以在運行時嘗試移動內存中的數(shù)據(jù),合并空閑塊,以降低碎片率,但這會消耗一定的CPU資源。在某些嚴重碎片化的情況下,通過主從切換進行實例重啟也是一種徹底清理內存碎片的方法。

163. HashMap數(shù)據(jù)傾斜問題分析與應對策略

HashMap的數(shù)據(jù)傾斜指的是大量的鍵(Key)經過哈希計算后,被映射到了少數(shù)幾個桶(Bucket)或槽位(Slot)上,而大部分桶卻很少被使用或完全空閑。理想情況下,HashMap的鍵應均勻分布在所有桶中,以確保增、刪、查操作的時間復雜度接近O(1)。數(shù)據(jù)傾斜會導致這些操作在傾斜的桶上退化為鏈表(或紅黑樹)的遍歷,最壞情況下時間復雜度可能接近O(n),嚴重影響性能。

應對HashMap數(shù)據(jù)傾斜可以采取以下策略:

優(yōu)化哈希函數(shù) (Hash Function Optimization):核心在于確保哈希函數(shù)能夠產生分布均勻的哈希碼。如果鍵的 hashCode() 方法實現(xiàn)不佳,導致大量不同鍵產生相同或相近的哈希碼,或者哈希碼集中在某個范圍內,就會引發(fā)傾斜??梢钥紤]重寫鍵對象的 hashCode() 方法,使其能更好地結合鍵自身的內容特征,生成更分散的哈希值。

采用一致性哈希 (Consistent Hashing):雖然主要應用于分布式系統(tǒng)(如分布式緩存),但其設計思想有助于理解和解決數(shù)據(jù)分布問題。一致性哈希通過將哈??臻g組織成一個哈希環(huán),并將節(jié)點(或在這里可類比為桶)和數(shù)據(jù)的哈希值映射到環(huán)上,數(shù)據(jù)歸屬于其在環(huán)上順時針遇到的第一個節(jié)點。虛擬節(jié)點技術的引入,通過為一個物理節(jié)點創(chuàng)建多個虛擬映射點,可以進一步增強節(jié)點在環(huán)上的均勻度,從而使得數(shù)據(jù)分布更為均衡。此外,其動態(tài)調整特性,即增刪節(jié)點時僅影響局部數(shù)據(jù),也體現(xiàn)了其對分布變化的適應性。

結構優(yōu)化 (Structural Optimization):Java 8及以后版本的HashMap實現(xiàn)引入了重要的優(yōu)化。當某個桶中的鏈表長度超過特定閾值(默認為8),并且HashMap的總容量大于等于64時,該鏈表會轉換為紅黑樹進行存儲。紅黑樹的查找、插入、刪除操作的時間復雜度為O(log n),這顯著改善了在嚴重哈希沖突(即數(shù)據(jù)傾斜)情況下的查詢性能,雖然不能完全消除傾斜的影響,但能有效緩解其帶來的性能退化。

164. JVM新生代對象晉升老年代的機制

Java虛擬機(JVM)的堆內存通常采用分代收集策略,劃分為新生代(Young Generation)和老年代(Old Generation)。新生代又細分為Eden區(qū)和兩個Survivor區(qū)(通常稱為S0和S1)。對象晉升老年代主要發(fā)生在新生代的垃圾收集(Minor GC)過程中。

新創(chuàng)建的對象通常首先被分配在Eden區(qū)。當Eden區(qū)空間不足時,會觸發(fā)一次Minor GC。Minor GC采用**復制算法(Copying Algorithm)**進行垃圾回收。其過程大致為:將Eden區(qū)和當前使用的那個Survivor區(qū)(稱為from區(qū),例如S0)中仍然存活的對象,復制到另一個空的Survivor區(qū)(稱為to區(qū),例如S1)。在復制過程中,每個存活對象的年齡(Age)會增加1。對象的初始年齡為0。

對象晉升到老年代(Old Generation)主要基于對象年齡閾值。JVM會設定一個晉升閾值(Promotion Age Threshold),可以通過參數(shù) -XX:MaxTenuringThreshold 指定(默認通常是15)。當一個對象在Survivor區(qū)中經歷多次Minor GC后,其年齡達到了這個閾值,它就會在下一次Minor GC時被移動到老年代,而不是復制到另一個Survivor區(qū)。

此外,還存在一些特殊情況可能導致對象提前晉升或直接在老年代分配:

  1. 動態(tài)年齡判斷:如果在一次Minor GC后,to Survivor區(qū)中相同年齡所有對象大小的總和大于Survivor空間的一半,那么年齡大于或等于該年齡的對象也會被直接晉升到老年代,無需等到MaxTenuringThreshold。
  2. 大對象直接進入老年代:如果創(chuàng)建了一個非常大的對象,新生代無法容納(特別是Eden區(qū)和from Survivor區(qū)都放不下),JVM可能會嘗試將其直接分配在老年代。這可以通過參數(shù) -XX:PretenureSizeThreshold 控制。

165. MySQL可重復讀隔離級別與MVCC機制的協(xié)同工作

MySQL InnoDB存儲引擎默認的事務隔離級別是可重復讀(Repeatable Read, RR)。該級別的核心目標是確保在同一個事務內部,多次讀取同一行數(shù)據(jù)的結果始終保持一致,不會看到其他并發(fā)事務在此期間對該行數(shù)據(jù)所做的修改(已提交的修改也不可見),從而避免了“不可重復讀”問題。在InnoDB中,RR級別還能在一定程度上防止“幻讀”。

多版本并發(fā)控制(Multi-Version Concurrency Control, MVCC)是InnoDB存儲引擎用來實現(xiàn)高并發(fā)事務處理的一種關鍵技術,它并非與可重復讀隔離級別相悖,反而是實現(xiàn)該隔離級別的底層機制。MVCC的核心思想是為數(shù)據(jù)庫中的每一行數(shù)據(jù)維護多個版本。

MVCC與可重復讀協(xié)同工作的原理如下:當一個事務開始時(在RR級別下,通常是執(zhí)行第一條查詢語句時),InnoDB會為該事務創(chuàng)建一個一致性視圖(Read View),也稱為快照(Snapshot)。該事務后續(xù)的所有一致性讀(Consistent Read)操作(即普通的SELECT語句)都會基于這個快照來進行。這意味著事務只能看到在創(chuàng)建快照那一刻之前已經提交的數(shù)據(jù)版本,而對于在快照創(chuàng)建之后其他事務所做的修改(即使已提交),該事務是“看不見”的。

寫操作(如INSERT, UPDATE, DELETE)并不會直接覆蓋舊數(shù)據(jù),而是會創(chuàng)建數(shù)據(jù)的新版本,并記錄下執(zhí)行該操作的事務ID。舊版本的數(shù)據(jù)會保留下來,直到不再被任何活躍事務的快照所需要時,才會被后臺的Purge線程清理。

因此,MVCC通過讓讀操作訪問數(shù)據(jù)的歷史版本(快照),實現(xiàn)了讀寫操作的非阻塞,極大地提高了數(shù)據(jù)庫的并發(fā)性能。同時,正是由于事務讀取的是其啟動時刻的數(shù)據(jù)快照,確保了在整個事務期間讀取到的數(shù)據(jù)是一致的,完美地支撐了可重復讀隔離級別的要求。所以,MVCC不僅不違背可重復讀,反而是InnoDB實現(xiàn)高并發(fā)下可重復讀隔離級別的基石。

166. 經典取石子博弈(每次取1-3個)的必勝策略分析

這是一個經典的博弈論問題,屬于取物游戲(如Nim游戲)的一種變體。規(guī)則為:兩名玩家輪流從一堆石子中取出石子,每次最少取1個,最多取3個,取走最后一個石子的玩家獲勝。此游戲存在明確的必勝策略,其核心在于控制剩余石子的數(shù)量

該策略基于一個關鍵數(shù):4(即可取數(shù)量的最大值3加1)。如果一個玩家在自己操作結束后,能確保留給對手的石子數(shù)量是4的倍數(shù),那么該玩家就掌握了主動權。因為無論對手接下來取走1、2或3個石子,剩余石子的數(shù)量將不再是4的倍數(shù)。此時,輪到的玩家總可以通過取走相應數(shù)量(3、2或1個)的石子,使得剩余石子數(shù)量再次變?yōu)?的倍數(shù)。

因此,必勝策略的實施取決于游戲開始時石子的總數(shù)N

  • 如果 N 是 4 的倍數(shù),那么先手玩家(第一個取石子的玩家)天然處于劣勢。只要后手玩家每次都采取與先手玩家互補的策略(即如果先手取k個,后手就取4-k個),就能確保每次留給先手玩家的都是4的倍數(shù),最終后手玩家將取走最后一顆石子獲勝。
  • 如果 N 不是 4 的倍數(shù),那么先手玩家可以通過第一次操作,取走 N % 4 個石子(即N除以4的余數(shù)個石子,這個數(shù)量必然在1-3之間),使得剩余石子數(shù)量變?yōu)?的倍數(shù)。此后,無論對手如何取,先手玩家始終可以采取上述互補策略,確保每次都留給對手4的倍數(shù)的石子,從而確保自己最終獲勝。

關鍵在于,有策略的一方需要始終致力于在自己的回合結束后,讓石子堆的數(shù)量成為4的倍數(shù)

167. HashSet 內部實現(xiàn):值(Value)的角色與 HashMap 的關聯(lián)

Java中的 HashSet 在其內部實現(xiàn)上,是基于 HashMap 來構建的。HashSet 的核心目標是存儲一組唯一的元素,它不關心元素對應的值,只關注元素(鍵)本身是否存在。

為了利用 HashMap 高效的鍵查找和唯一性保證機制,HashSet 將其存儲的元素作為 HashMap 的鍵(Key)。然而,HashMap 要求每個鍵都必須關聯(lián)一個值(Value)。由于 HashSet 的語義中值是無意義的,為了節(jié)省內存空間并簡化實現(xiàn),HashSet 采用了一個巧妙的方法:它為內部 HashMap 中的所有鍵都關聯(lián)同一個、預定義的靜態(tài)對象作為值。

這個充當“啞值”(Dummy Value)的對象通常是一個內部定義的、私有的靜態(tài)常量,例如:

// 在 HashSet 源碼內部類似定義
private static final Object PRESENT = new Object();

當你調用 HashSet 的 add(E element) 方法時,內部實際上執(zhí)行的是 map.put(element, PRESENT)。如果 put 操作返回 null(表示 element 是新添加的鍵),則 add 方法返回 true;否則返回 false。由于 PRESENT 是一個靜態(tài)常量對象,所有 HashSet 中的條目都共享對這同一個對象的引用,因此并不會因為存儲這個“值”而帶來顯著的額外的內存開銷。

168. Redis 緩存與數(shù)據(jù)庫一致性策略:延時雙刪詳解

延時雙刪(Delayed Double Delete)是解決緩存與數(shù)據(jù)庫數(shù)據(jù)一致性問題的一種常用策略,尤其適用于讀多寫少的業(yè)務場景。其目的是在更新數(shù)據(jù)庫數(shù)據(jù)時,盡可能地降低緩存中出現(xiàn)臟數(shù)據(jù)的風險。

該策略的操作步驟如下:

  1. 第一次刪除緩存:在執(zhí)行數(shù)據(jù)庫寫操作(更新或刪除)之前,首先嘗試刪除緩存中對應的條目。這一步旨在防止并發(fā)的讀請求在數(shù)據(jù)庫更新期間讀到舊的緩存數(shù)據(jù)。
  2. 更新數(shù)據(jù)庫:執(zhí)行實際的數(shù)據(jù)庫更新或刪除操作。這是數(shù)據(jù)變更的核心步驟。
  3. 延時等待:在數(shù)據(jù)庫操作成功后,不立即操作緩存,而是等待一段預設的時間(例如幾百毫秒或根據(jù)業(yè)務并發(fā)情況估算的時間)。設置延時的核心目的是,允許那些在步驟1(刪除緩存)之后、步驟2(更新數(shù)據(jù)庫)完成之前就已經發(fā)起的讀請求有機會完成。這些讀請求可能會因為緩存未命中而去查詢數(shù)據(jù)庫(此時可能讀到舊數(shù)據(jù)),并將舊數(shù)據(jù)重新寫入緩存。
  4. 第二次刪除緩存延時結束后,再次執(zhí)行刪除緩存的操作。這一步是為了清除在延時期間可能被并發(fā)讀請求重新寫入的臟數(shù)據(jù)(舊數(shù)據(jù)),確保最終緩存被清空,后續(xù)的讀請求將直接從數(shù)據(jù)庫加載最新數(shù)據(jù)。

通過這兩次刪除和中間的延時,延時雙刪策略提高了數(shù)據(jù)最終一致性的保障程度,但需要注意的是,它并不能完全保證強一致性,且延時時間的設定需要權衡。

169. Spring Boot 注解失效的常見場景分析(含 @Transactional 特例)

Spring Boot 及 Spring 框架大量使用注解來簡化配置和開發(fā)。然而,在某些情況下注解可能不會按預期生效。以下是一些常見的導致注解失效的場景:

首先,注解僅對由 Spring IoC 容器管理的 Bean 生效。如果你嘗試在通過 new 關鍵字手動創(chuàng)建的對象實例上使用 Spring 注解(如 @Autowired, @Component, @Service, @Transactional 等),這些注解將不會被處理。同時,確保相關的 Bean 被 Spring 正確掃描并加載到上下文中(例如,組件掃描路徑配置正確,配置類本身被 @Configuration 標記并被掃描)。

其次,涉及 AOP(面向切面編程) 的注解(如 @Transactional, @Async, @Cacheable 等)依賴于 Spring 的代理機制。這引入了幾個失效點:

  • 方法可見性:許多 AOP 注解默認只對 public 方法生效。將注解用在 protected, private 或包可見方法上可能導致其失效。
  • 靜態(tài)方法:Spring AOP 無法代理靜態(tài)方法,因此在靜態(tài)方法上使用這類注解無效。
  • 代理模式:Spring AOP 默認使用 JDK 動態(tài)代理(基于接口)。如果注解應用在沒有實現(xiàn)接口的類上,需要啟用 CGLIB 代理(通過配置 spring.aop.proxy-target-class=true),否則注解可能不生效。注解通常建議標注在實現(xiàn)類而非接口上,以避免代理模式帶來的問題。

此外,循環(huán)依賴問題可能干擾 Bean 的正常初始化過程,間接導致其上的注解無法正常工作。使用 @Conditional 系列注解時,如果其指定的條件未滿足,對應的 Bean 不會被創(chuàng)建,其上的注解自然也就無從談起。

@Transactional 注解失效的特例

除了上述通用原因,@Transactional 還有一些特定的失效場景:

  • 自調用問題:在一個 Bean 的內部方法調用另一個帶有 @Transactional 注解的本類方法時,事務不會生效。這是因為內部調用沒有經過 Spring 生成的代理對象,而是直接通過 this 引用調用,繞過了事務增強邏輯。
  • 異常類型與回滾策略:@Transactional 默認只在遇到 RuntimeException 或 Error 時才回滾事務。如果方法拋出的是受檢查異常(Checked Exception),并且沒有通過 @Transactional(rollbackFor = Exception.class) 等方式顯式指定需要回滾,事務將不會回滾。
  • 數(shù)據(jù)庫引擎不支持事務:如果底層數(shù)據(jù)庫使用的存儲引擎(如 MySQL 的 MyISAM 引擎)本身不支持事務,那么 @Transactional 注解自然無法產生效果。

170. HTTPS 通信流程詳解:從握手到加密傳輸

HTTPS(Hyper Text Transfer Protocol Secure)是在 HTTP 協(xié)議基礎上加入了 SSL/TLS 加密層的安全網(wǎng)絡傳輸協(xié)議,旨在保障數(shù)據(jù)在客戶端與服務器間傳輸?shù)?strong>機密性、完整性和身份認證。其詳細通信流程主要包括握手階段和加密傳輸階段:

SSL/TLS 握手階段

剩余60%內容,訂閱專欄后可繼續(xù)查看/也可單篇購買

曾獲多國內大廠的 ssp 秋招 offer,且是Java5年的沉淀老兵(不是)。專注后端高頻面試與八股知識點,內容系統(tǒng)詳實,覆蓋約 30 萬字面試真題解析、近 400 個熱點問題(包含大量場景題),60 萬字后端核心知識(含計網(wǎng)、操作系統(tǒng)、數(shù)據(jù)庫、性能調優(yōu)等)。同時提供簡歷優(yōu)化、HR 問題應對、自我介紹等通用能力??紤]到歷史格式混亂、質量較低、也在本地積累了大量資料,故準備從頭重構專欄全部內容

全部評論

相關推薦

評論
3
4
分享

創(chuàng)作者周榜

更多
??途W(wǎng)
??推髽I(yè)服務