百度二面,有點小激動!附面試題

磊哥課程 2024-06-22 10:20:51

前幾天剛面完百度,這不,沒兩天就收到二面邀請了,還有點小激動呢!來看看這次都問了哪些面試題吧,附答案僅供參考。

ConsurrentHashMap如何計算下標?

ConsurrentHashMap 計算下標和 HashMap 類似,它的主要執行流程有以下兩步:

計算 key 哈希值:JDK 1.7:key.hashCode()。JDK 1.8+:((h=key.hashCode()) ^ (h>>>16)) -> 算法更均勻,哈希沖突越少。計算下標:hash & (table.length-1)。說說MVCC機制?

MVCC(Multi-Version Concurrency Control)是一種並發控制機制,用于解決數據庫並發訪問中,數據一致性問題。它通過在讀寫操作期間保存多個數據版本,以提供並發事務間的隔離性,從而避免了傳統的鎖機制所帶來的資源爭用和阻塞問題。

在 MVCC 機制中,每個事務的讀操作都能看到事務開始之前的一致性數據快照,而不受其他並發事務的修改的影響。核心思想是通過創建多個數據版本,保持事務的一致性和隔離性。

MVCC 主要是依靠以下兩部分實現的:

Undo Log 鏈Read View(讀視圖或者叫一致性視圖)a. Undo Log 鏈

我們知道 Undo Log 主要是用于數據庫中事務回滾的,但在 MVCC 機制中也發揮著重要的作用,那什麽是 Undo Log 鏈呢?

Undo Log 鏈是指在每個數據對象上維護的 Undo Log 記錄鏈表。每張表都會有與之相對應的 Undo Log 鏈,用于記錄修改前的數據信息(以方便數據進行回滾)。

b. Read View

Read View(讀視圖)用于管理事務之間數據可見性的一種機制。Read View 在特定時刻爲事務創建的一個快照,該快照包含了在該時刻所有未提交事務的事務標識符,以及其他一些輔助信息。

在 Read View 中包含了以下 4 個主要的字段:

m_ids:當前活躍的事務編號集合。min_trx_id:最小活躍事務編號。max_trx_id:預分配事務編號,當前最大事務編號+1。creator_trx_id:ReadView 創建者的事務編號。

RC 級別中,每次快照讀都會生成一個全新的 Read View,而 RR 級別中同一個事務會複用一個 Read View。

有了 Read View 和 Undo Log 鏈之後,並發事務在查詢時就知道要讀取那些數據了。

c. 判斷方法

判斷方法是根據 Read View 中的 4 個重要字段,先去 Undo Log 中最新的數據行進行比對,如果滿足下面 Read View 的判斷條件,則返回當前行的數據,如果不滿足則繼續查找 Undo Log 的下一行數據,直到找到滿足的條件的數據爲止,如果查詢完沒有滿足條件的數據,則返回 NULL。

d. 判斷規則trx_id==creator_trx_id:先將 Undo Log 最新數據行中的 trx_id 和 ReadView 中的 creator_trx_id 進行對比,如果他們兩個值相同,則說明是在同一個事務中執行,那麽直接返回當前 Undo Log 的數據行即可,如果不相等,則繼續下面流程。trx_id<min_trx_id:如果 trx_id 小于 min_trx_id,則說明在執行查詢時,其他事務已經提交此行數據了,那麽直接返回此行數據即可,如果大于等于,則繼續下面流程。trx_id>max_trx_id:如果 trx_id 如果大于等于 max_trx_id,則說明該行數據比當前操作執行的晚,當前行數據不可見,繼續執行後續流程。min_trx_id<=trx_id<max_trx_id:trx_id 在 min_trx_id 和 max_trx_id 之間還分爲以下兩種情況:trx_id 在 m_ids 中:說明事務尚未執行完,該行數據不可被訪問。trx_id 未在 m_ids 中:說明事務已經執行完,可以返回該行數據。

以上判斷規則從 Undo Log 最新的行數據,逐行對比,直到找到匹配的數據,否則查詢完未匹配上,則返回 NULL。

說說讀已提交和可重複讀各自創建ReadView的時機?

創建 ReadView 時機如下:

讀已提交(Read Committed):在讀已提交隔離級別下,MySQL 爲每一個讀取操作創建一個新的 ReadView。這意味著每次執行 SELECT 查詢時,都會根據當前活躍事務的狀態重新計算可見性視圖。這樣做的結果是,同一個事務內的連續兩次查詢可能會看到不同的數據,因爲第二次查詢可能會看到第一次查詢後其他事務提交的新數據。因此,在這個隔離級別下,事務能看到其他事務已經提交的修改。可重複讀(Repeatable Read):在可重複讀隔離級別下,MySQ爲整個事務而不是單個查詢創建一個 ReadView。也就是說,當一個事務開始時,MySQL 會爲該事務創建一個快照(Snapshot),這個快照包含了數據庫在事務開始時刻的所有數據的一個一致性視圖。在整個事務的生命周期內,不論執行多少次查詢操作,都是基于這個初始創建的 ReadView 來決定數據的可見性,確保事務內多次相同的查詢結果是一致的,即“可重複讀”。因此,在這個隔離級別下,事務開始後,不會看到其他事務後續提交的修改。你知道哪些常用的Linux命令?

Linux 常用的命令有以下這些:

ls:用于列出目錄中的文件和子目錄。pwd:顯示當前工作目錄的路徑。cd:切換到指定工作目錄。mkdir:創建一個新的目錄。rmdir:刪除一個空目錄。rm:刪除文件或目錄。cp:複制文件或目錄。mv:移動或重命名文件或目錄。touch:創建空文件或更新文件的時間戳。less:分頁顯示文件內容。tail:顯示文件的開頭或結尾部分的內容(可查看動態日志)。cat:查看文件內容或將多個文件內容合並輸出。grep:在文件中搜索指定的文本模式。ps:顯示系統中的進程信息。kill:終止指定進程。ifconfig/ip:查看和配置網絡接口信息。ping:測試網絡連接。wget/curl:從網絡下載文件。chmod:改變文件或目錄的權限。如何排查CPU占用比較高的問題?

以 Linux 系統爲例,排查 CPU 飙升問題的實現步驟如下:

使用 top 命令,查詢占用 CPU 最高的進程 ID。查詢該進程 ID 中,哪個線程占用的 CPU 資源最多。將占用 CPU 資源最多的線程 ID 轉換成 16 進制。使用 Java 自帶的工具 jstack 查詢該線程的詳細信息,定位到問題代碼,分析代碼和解決 CPU 飙升的問題。說說Top命令各個指標的具體含義?

使用 top 命令查詢 cpu 占用最高的進程 ID(PID),如下圖所示:

可以使用 shift+P 快捷鍵進行 CPU 占用率排序(從高到低)。

指標含義:包括進程ID (PID)、用戶 (USER)、優先級 (PR)、nice 值 (NI)、虛擬內存使用量 (VIRT)、物理內存使用量 (RES)、共享內存大小 (SHR)、進程狀態 (S)、CPU 使用率 (%CPU)、內存使用率 (%MEM)、進程累計 CPU 時間 (TIME+) 和命令名 (COMMAND)。

其中:

優先級 (PR):優先級是進程在內核中的實際調度優先級,也稱爲動態優先級。它反映了進程被調度占用 CPU 的實際順序。在 top 命令中,PR 列顯示的是進程的調度優先級,對于實時進程,使用“RT”標記;對于非實時進程(普通用戶進程),其取值範圍是 0 至 39,值越小優先級越高。nice值 (NI):nice 值是進程的用戶態優先級,也稱爲靜態優先級。它是一個從 -20 到 19 的數值,其中負數表示較高的優先級,正數表示較低的優先級。默認情況下,大多數進程的 nice 值爲0。通過 nice 和 renice 命令,用戶可以調整進程的 nice 值,從而影響其優先級。Redis爲什麽快?

Redis 運行比較快的原因主要有以下幾點:

純內存操作:Redis 將所有數據存儲在內存中,這意味著對數據的讀寫操作直接在內存中進行,而內存的訪問速度遠遠高于磁盤。這種設計使得 Redis 能夠以接近硬件極限的速度處理數據讀寫。單線程模型:Redis 使用單線程模型來處理客戶端請求。這可能聽起來似乎效率不高,但實際上,這種設計避免了多線程頻繁切換和過度競爭所帶來的性能開銷。Redis 每個請求的執行時間都很短,因此在單線程下,也能夠處理大量的並發請求。I/O多路複用:Redis 使用了 I/O 多路複用技術,可以在單個線程中同時監聽多個客戶端連接,只有當有網絡事件發生時才會進行實際的 I/O 操作。這樣有效地利用了 CPU 資源,減少了無謂的等待和上下文切換。高效數據結構:Redis 提供了多種高效的數據結構,如哈希表、有序集合等。這些數據結構的實現都經過了優化,使得 Redis 在處理這些數據結構的操作時非常高效。Redis有哪些持久化方式?

Redis 4.0 之後支持以下 3 種持久化方案:

RDB(Redis DataBase)持久化:快照方式持久化,將某一個時刻的內存數據,以二進制的方式寫入磁盤。占用空間小,恢複快,可能存在數據丟失。AOF(Append Only File)持久化:文件追加持久化,記錄所有非查詢操作命令,並以文本的形式追加到文件中。數據通常不易丟失,但占用空間大。混合持久化:RDB + AOF 混合方式的持久化,Redis 4.0 之後新增的方式,混合持久化是結合了 RDB 和 AOF 的優點,在寫入的時候,先把當前的數據以 RDB 的形式寫入文件的開頭,再將後續的操作命令以 AOF 的格式存入文件,這樣既能保證 Redis 重啓時的速度,又能減低數據丟失的風險。說說AOF中的寫時複制技術?① AOF 重寫背景

隨著 Redis 運行,AOF 文件會不斷增長,因爲每次寫操作都被追加到文件中。爲了減小文件體積、提高恢複速度,Redis 提供了 AOF 重寫功能,它可以創建一個新的、更緊湊的 AOF 文件,僅包含重建當前數據集所需的最小命令序列。

② 寫時複制在 AOF 中的應用子進程寫時複制:Redis 在執行 AOF 重寫(bgrewriteaof)時,會 fork 出一個子進程(bgsave 子進程)來負責 AOF 文件的重寫,主進程依然執行 Redis 的業務命令。AOP 重寫遇到寫操作:在 bgsave 子進程運行期間,如果主進程有寫操作(如修改 key-value),主進程會采用寫時複制機制。具體來說,主進程會把這個新寫或修改的數據寫入到一個新的物理地址中,並修改自己的頁表映射。這樣,虛擬頁和物理頁的關系在子進程中保持不變,而主進程中的數據已經被更新。AOF 重寫緩沖區:爲了解決主進程在 AOF 重寫過程中修改數據導致的數據不一致問題,Redis 設置了一個 AOF 重寫緩沖區。在重寫 AOF 期間,當 Redis 執行完一個寫命令之後,它會同時將這個寫命令寫入到 AOF 緩沖區和 AOF 重寫緩沖區。當 AOF 重寫完成後,Redis 會將 AOF 重寫緩沖區中的命令追加到新的 AOF 文件中,以確保數據的一致性。手撕算法:三數之和?題目:https://leetcode.cn/problems/3sum/description/解題思路:雙指針+數組變量。解題思路推薦:https://leetcode.cn/problems/3sum/solutions/12307/hua-jie-suan-fa-15-san-shu-zhi-he-by-guanpengchn/

本文已收錄到我的面試小站 [www.javacn.site](https://www.javacn.site),其中包含的內容有:Redis、JVM、並發、並發、MySQL、Spring、Spring MVC、Spring Boot、Spring Cloud、MyBatis、設計模式、消息隊列等模塊。

0 阅读:10

磊哥課程

簡介:感謝大家的關注