繼續分享最新的面經,前面發的兩篇大家也可以看看:
- 「坐標上海,20K的面試強度」
- 「北京七貓,薪資25~35K,瞧瞧面試強度」
今天分享的是golang開發崗面經,要求是3年以上golang開發經驗,薪資為15~30K,整體面下來的感受就是,面的比較廣,細節拷打不多,來看看難度如何:
面試題詳解
1. GMP調度
GMP調度模型是Go語言運行時的核心調度機制,用于實現高效的并發執行。G代表Goroutine(協程),M代表Machine(操作系統線程),P代表Processor(處理器)。
- Goroutine 是用戶態的輕量級線程,由Go運行時管理,創建和銷毀成本低。
- Machine 是操作系統線程,負責真正執行代碼,每個M可以綁定一個或多個G。
- Processor 是邏輯處理器,用于分配任務給M,并維護本地隊列中的G。
調度過程:
- 每個P維護一個本地隊列,存放待執行的G。如果本地隊列為空,會從全局隊列或其他P的隊列中偷取任務(Work Stealing)。
- 當一個G阻塞時(如I/O操作),M會釋放當前P并尋找其他可執行的G,從而避免浪費資源。
- 如果所有M都在忙,而有新的G需要執行,運行時會動態創建新的M來滿足需求。
這種調度方式的優點是高效利用多核CPU,減少了上下文切換的開銷,同時支持大量并發任務。
2. 協作式調度和搶占式調度有什么區別
協作式調度 和 搶占式調度 是兩種不同的任務調度方式,主要區別在于任務的執行控制權歸屬:
-
協作式調度:
- 任務主動讓出CPU,只有當前任務完成或顯式調用讓出函數時,調度器才能切換到其他任務。
- 缺點是如果某個任務長時間占用CPU而不讓出,會導致其他任務“餓死”。
- 優點是實現簡單,上下文切換開銷小,適合任務間信任度高的場景。
-
搶占式調度:
- 調度器通過定時器中斷等方式強制剝奪當前任務的CPU使用權,確保公平性。
- 優點是可以防止某個任務獨占CPU,保證系統的響應性和公平性。
- 缺點是上下文切換頻繁可能導致性能開銷增大。
在現代操作系統中,搶占式調度更為常見,因為它能更好地應對復雜任務環境。而協作式調度更多用于嵌入式系統或特定領域。
3. 垃圾回收講一下,三色標記和混合寫屏障
垃圾回收(GC)是一種自動內存管理機制,用于回收不再使用的對象,避免內存泄漏。常見的GC算法包括引用計數、標記清除、分代回收等。
三色標記 是一種經典的GC算法,其核心思想是將對象分為三種狀態:
- 白色:尚未被訪問的對象,表示可能需要回收。
- 灰色:已被訪問但其引用的對象尚未完全掃描,表示正在處理中。
- 黑色:已被訪問且其引用的對象也已掃描完畢,表示安全存活。
GC過程:
- 初始時,所有對象為白色。
- 從根對象(如全局變量、棧變量)開始,將可達對象標記為灰色。
- 不斷從灰色對象集合中取出對象,將其引用的對象標記為灰色,自身標記為黑色。
- 當灰色集合為空時,剩余的白色對象即為不可達對象,可被回收。
混合寫屏障 是一種優化技術,用于解決三色標記中的并發問題。當GC與程序并發運行時,可能會出現新引用導致對象狀態不一致的情況。混合寫屏障通過記錄修改過的引用,確保GC能夠正確識別對象狀態,從而提高效率和安全性。
4. 事務執行中,mysql如果宕機了,重新恢復會發生什么?
MySQL使用事務日志(Redo Log和Undo Log)來保證數據一致性。如果在事務執行過程中發生宕機,重啟后會通過以下步驟恢復:
- 檢查Redo Log:Redo Log記錄了事務對數據頁的物理修改,即使事務未提交,修改也會先寫入日志。重啟后,MySQL會重放Redo Log,將未持久化的修改應用到數據頁上。
- 檢查Undo Log:Undo Log記錄了事務的回滾信息。對于未提交的事務,MySQL會使用Undo Log撤銷已完成的部分操作,確保事務原子性。
- 崩潰恢復:MySQL的InnoDB引擎會在啟動時執行崩潰恢復流程,將未完成的事務標記為回滾狀態,并清理相關的日志文件。
通過這種方式,MySQL能夠在宕機后恢復到一致狀態,保證事務的ACID特性。
5. 講一下兩階段提交的過程,兩階段提交解決什么問題?
兩階段提交(2PC, Two-Phase Commit)是一種分布式事務協議,用于協調多個節點之間的事務提交,確保分布式系統中的一致性。
過程:
- 準備階段:
- 協調者向所有參與者發送Prepare請求,詢問是否可以提交事務。
- 參與者執行事務操作,并將結果寫入日志,然后回復Yes或No。
- 提交階段:
- 如果所有參與者都回復Yes,協調者發送Commit請求,參與者正式提交事務。
- 如果有任何參與者回復No,協調者發送Abort請求,參與者回滾事務。
解決的問題:
- 2PC解決了分布式系統中事務的原子性問題,即要么所有節點都提交事務,要么全部回滾。
- 它適用于強一致性要求的場景,但存在單點故障(協調者故障)和性能瓶頸等問題。
6. 講一下MVCC,它解決了幻讀問題嗎?
MVCC(多版本并發控制)是一種數據庫并發控制機制,通過保存數據的多個版本來實現高并發讀寫。
原理:
- 每次更新數據時,都會生成一個新的版本,舊版本保留供讀取。
- 讀操作只訪問符合當前事務隔離級別的版本,避免了讀寫沖突。
解決的問題:
- MVCC有效解決了讀寫沖突問題,提高了并發性能。
- 在可重復讀(Repeatable Read)隔離級別下,MVCC通過版本控制避免了不可重復讀問題。
- 對于幻讀問題,MVCC在某些情況下可以通過間隙鎖(Gap Lock)結合版本控制部分解決,但在串行化(Serializable)級別下,仍需依賴鎖機制來完全避免幻讀。
7. redis的跳表了解嗎?
跳表(Skip List)是一種基于鏈表的數據結構,通過多層索引加速查找操作,時間復雜度接近O(log n)。
Redis中的跳表主要用于實現有序集合(Sorted Set)。
- 跳表的每一層是一個有序鏈表,越高層的鏈表包含的節點越少。
- 查找時從最高層開始,快速縮小范圍,然后逐層向下定位目標節點。
- 插入和刪除操作也通過多層索引進行維護,保證整體效率。
跳表的優點是實現簡單,性能穩定,適合Redis這種高性能場景。
8. Redis大key會有什么問題?怎么解決?
問題:
- 大key指的是存儲大量數據的單個鍵,可能導致Redis性能下降。
- 內存占用過高,增加GC壓力,甚至引發OOM(內存溢出)。
- 操作大key可能導致阻塞,影響其他請求的響應時間。
解決方案:
- 拆分大key:將大key拆分為多個小key,分散存儲。
- 使用合適的數據結構:例如,將Hash、List等結構改為分片存儲。
- 漸進式刪除:通過腳本逐步刪除大key,避免一次性操作引發阻塞。
- 監控和優化:定期分析Redis內存使用情況,及時發現和處理大key。
9. kafka如何解決消息有序問題?
Kafka通過分區(Partition)機制保證消息的有序性。
- 每個分區內的消息是嚴格有序的,按照寫入順序存儲和消費。
- 生產者可以指定消息的分區鍵(Key),相同Key的消息會被路由到同一分區,從而保證局部有序。
消費者組內的消費者按分區消費,每個分區只能被一個消費者消費,進一步確保順序性。
需要注意的是,跨分區的消息無法保證全局有序,若需要全局有序,需將所有消息寫入同一個分區。
10. 如何保障kafka消息不丟失?
保障Kafka消息不丟失需要從生產者、Broker和消費者三個層面入手:
- 生產者:
- 設置acks=all,確保消息寫入所有副本后才返回成功。
- 啟用重試機制,處理網絡異常等情況。
- Broker:
- 配置副本數大于1,啟用ISR(同步副本集)機制,確保數據冗余。
- 定期備份數據,防止磁盤損壞導致丟失。
- 消費者:
- 手動提交偏移量,在業務邏輯處理完成后提交,避免重復消費或丟失。
- 設置合理的消費超時時間,防止消費者掛起導致消息堆積。
通過以上措施,可以在絕大多數情況下保障消息不丟失。
11. 鏈上操作了解嗎?
鏈上操作通常指區塊鏈上的交易或智能合約執行。
- 交易:用戶發起的操作,如轉賬、調用智能合約等,需要經過共識機制驗證后寫入區塊鏈。
- 智能合約:部署在鏈上的代碼,通過交易觸發執行,具有自動化和不可篡改的特性。
鏈上操作的特點:
- 透明性:所有操作記錄公開可查。
- 不可篡改:一旦寫入區塊鏈,無法修改。
- 去中心化:無需信任第三方,由共識機制保證安全。
鏈上操作的挑戰包括性能瓶頸、Gas費用高昂等問題,因此在實際應用中需權衡成本與效率。
歡迎關注 ?
我們搞了一個免費的面試真題共享群,互通有無,一起刷題進步。
沒準能讓你能刷到自己意向公司的最新面試題呢。
感興趣的朋友們可以私信我,備注:面試群。