面試官:Redis中大Key怎麼刪除?

王中阳Go發表於2024-11-06

首先來看一下該崗位的職責和要求:

崗位職責

  1. 負責公司旗下產品的全新需求開發
  2. 負責公司中臺系統管理系統開發
  3. 開發臨時性工具和資料處理工作
  4. 設計開發可複用模組,提高開發效率節省維護成本
  5. 保質保量的完成上級領導安排的技術相關工作

任職要求

  1. 本科以上學歷,計算機相關專業優先,3年左右 Golang 開發經驗,有 PHP 轉 Go 專案經驗者優先
  2. 熟練掌握 Golang/PHP 語言,熟悉至少一種 Golang 框架
  3. 熟練掌握關係型資料庫 Mysql 及部分 Nosql
  4. 熟練掌握 Redis 快取技術及 Rabbitmq 等常用訊息佇列
  5. 熟悉 Svn/Git,熟悉 Shell,Python 等至少一種指令碼語言
  6. 基礎紮實,對資料結構有較為深刻的理解
  7. 具備良好的分析解決問題能力,能獨立承擔任務和有系統進度把控能力,注重結果導向
  8. 良好的程式碼書寫、註釋習慣,能寫出高質量的程式碼,對自己開發的程式碼負責

    面試問題

  9. 自我介紹
  10. 專案介紹
  11. 八股

1. Redis 大key 刪除

問題背景
在Redis中,刪除大key(如大型雜湊表、列表、集合或有序集合)時,直接使用DEL命令會導致Redis阻塞,影響效能。

解決方案

  • 使用UNLINK命令

    • UNLINK命令從Redis 4.0開始引入,它的工作原理是非同步刪除key。UNLINK命令會立即將key從資料庫中刪除,但實際的記憶體釋放工作會在後臺執行緒中進行,不會阻塞主執行緒。
    • 示例:

      UNLINK my_large_key
  • 分批刪除

    • 使用SCANHSCANSSCANZSCAN等命令分批刪除大key中的元素,減少每次操作的負載。
    • 示例:

      SCAN 0 MATCH my_large_hash:* COUNT 100

      這個命令會返回100個匹配的key,然後你可以逐個刪除這些key。

  • 選擇在業務低峰期執行刪除操作

    • 在業務低峰期執行刪除操作,可以減少對正常業務的影響。
    • 例如,可以選擇在夜間或週末進行大key的刪除操作。
  • 使用RENAME命令

    • 先將大key重新命名,使其不再被業務訪問,然後再逐步刪除。
    • 示例:

      RENAME my_large_key my_large_key_to_delete
      DEL my_large_key_to_delete

2. MySQL 什麼時候會回表

問題背景
在MySQL中,回表是指在查詢過程中,如果索引不能完全覆蓋查詢所需的所有列,MySQL需要透過主鍵索引回表獲取完整的行資料。

具體場景

  • 非覆蓋索引:當查詢條件命中了索引,但查詢結果需要的列不在索引中時,MySQL需要回表獲取這些列的資料。

    • 示例:

      SELECT name, age FROM users WHERE id = 1;

      如果id上有索引,但nameage不在索引中,MySQL需要回表獲取nameage

  • 非唯一索引:即使查詢條件能夠唯一確定一行,但如果使用的是非唯一索引,MySQL也需要回表確認這一行是否滿足查詢條件。

    • 示例:

      SELECT * FROM users WHERE email = 'example@example.com';

      如果email上有非唯一索引,MySQL需要回表確認是否有多個使用者具有相同的email

  • 多表聯接:在多表聯接查詢中,如果使用了非覆蓋索引,MySQL可能需要回表獲取額外的資料。

    • 示例:

      SELECT u.name, o.order_id FROM users u JOIN orders o ON u.id = o.user_id WHERE u.id = 1;

      如果users表的id上有索引,但name不在索引中,MySQL需要回表獲取name

3. MySQL explain type型別 ref 和 index的區別

問題背景
EXPLAIN命令用於顯示MySQL如何執行查詢計劃,其中type列顯示了訪問型別。

具體區別

  • ref

    • 表示使用了非唯一索引或唯一索引的一部分。
    • 對於每個索引值,MySQL需要進行一次查詢,以找到符合條件的行。
    • 適用於等值查詢(如=IN<=>)。
    • 示例:

      EXPLAIN SELECT * FROM users WHERE email = 'example@example.com';

      如果email上有索引,type列會顯示為ref

  • index

    • 表示全索引掃描,即MySQL會遍歷整個索引來查詢匹配的行。
    • 這通常用於索引覆蓋查詢,即查詢的所有列都包含在索引中,無需回表。
    • 適用於範圍查詢(如><BETWEENLIKE)。
    • 示例:

      EXPLAIN SELECT email FROM users ORDER BY email;

      如果email上有索引,type列會顯示為index

4. 對已經關閉的chan進行讀寫會怎麼樣?

問題背景
在Go語言中,channel是一種同步機制,用於在goroutine之間傳遞資料。

具體行為

  • 讀取已關閉的channel

    • 從已關閉的channel讀取資料時,會立即返回零值,並且關閉標誌位會被設定,表明channel已經關閉。
  • 向已關閉的channel寫入資料

    • 向已關閉的channel寫入資料會觸發panic,因為不允許向已關閉的channel寫入資料。

5. 如何保證多個goroutine的全部執行

問題背景
在Go語言中,goroutine是輕量級的執行緒,用於併發執行任務。確保多個goroutine全部執行完畢是常見的需求。

具體方法

  • 使用sync.WaitGroup

    • 在啟動goroutine前增加WaitGroup的計數,goroutine完成後呼叫Done()方法減少計數,最後在主goroutine中呼叫Wait()等待所有goroutine完成。
  • 使用通道

    • 可以建立一個通道,每個goroutine完成任務後向通道傳送一個訊號,主goroutine接收這些訊號直到所有goroutine完成。
  • 使用上下文

    • 透過context管理goroutine的生命週期,可以取消或超時等待。

6. string 轉bytes 是否會重新分配記憶體

問題背景
在Go語言中,字串是不可變的,而位元組切片是可變的。

具體行為

  • 轉換過程

    • []byte(s)將字串轉換為位元組切片時,通常不會重新分配記憶體,而是共享字串的底層記憶體。
    • 例如:

      s := "hello"
      b := []byte(s)

      在這個例子中,bs共享同一塊記憶體。

  • 修改位元組切片

    • 如果對位元組切片進行了修改,會觸發記憶體複製,因為字串是不可變的。
    • 例如:

      s := "hello"
      b := []byte(s)
      b[0] = 'H' // 這會觸發記憶體複製

7. goframe和gozero的區別

問題背景
goframe和gozero都是Go語言的開發框架,但它們有不同的設計理念和應用場景。

具體區別

  • goframe

    • 特點:企業級開發框架,提供了一整套的Web開發、資料庫操作、快取、日誌等元件。
    • 適用場景:適合快速構建企業級應用,特別是需要複雜功能和高效能的應用。
    • 優勢

      • 完善的文件和社群支援。
      • 提供豐富的中介軟體和外掛。
      • 支援多種資料庫和快取系統。
  • gozero

    • 特點:輕量級的微服務框架,專注於微服務架構,提供了API生成器、服務註冊與發現、配置中心等功能。
    • 適用場景:適合構建微服務應用,特別是需要高可擴充套件性和高可用性的應用。
    • 優勢

      • 輕量級,啟動速度快。
      • 內建了服務發現和配置管理功能。
      • 支援自動程式碼生成,提高開發效率。

8. 逃逸分析有哪些場景

問題背景
逃逸分析是編譯器的一種最佳化技術,用於確定變數的作用域和生命週期,以決定變數是否可以在棧上分配,從而減少堆上的記憶體分配,提高程式效能。

具體場景

  • 全域性變數

    • 作用域超出函式範圍的變數。
  • 函式返回值

    • 如果函式返回了區域性變數的引用或指標,該變數需要逃逸到堆上。
  • 閉包

    • 如果一個函式返回了一個閉包,而閉包引用了外部函式的區域性變數,那麼這些變數需要逃逸到堆上。
    • 例如:

      func createClosure() func() int {
          x := 10
          return func() int {
              return x // x 逃逸到堆上
          }
      }
  • 迴圈中的變數

    • 在迴圈中建立的變數,如果在迴圈外被引用,也會逃逸到堆上。

9. Kafka如何實現有序

問題背景
Kafka是一個分散式流處理平臺,用於構建實時資料管道和流應用。

具體實現

  • 分割槽

    • 每個主題可以被劃分為多個分割槽,每個分割槽內的訊息是有序的。
    • 生產者可以指定訊息的分割槽鍵,確保相同鍵的訊息被髮送到同一個分割槽。
  • 單一消費者

    • 對於每個分割槽,如果有多個消費者訂閱了同一個消費者組,那麼每個分割槽的訊息只會被一個消費者消費,確保了訊息的順序。
  • 事務

    • Kafka支援事務,可以確保訊息的生產者傳送的訊息按照傳送順序被提交。

10. 專案中常用的設計模式

問題背景
設計模式是解決常見問題的模板,可以幫助開發者編寫更高效、更可維護的程式碼。

  • 單例模式

    • 描述:確保一個類只有一個例項,並提供一個全域性訪問點。
    • 優點:節省資源,避免重複建立物件。
    • 缺點:單例物件通常是全域性可訪問的,容易引起耦合。
  • 工廠模式

    • 描述:提供一個建立物件的介面,但由子類決定例項化哪一個類。
    • 優點:將物件的建立和使用分離,提高程式碼的靈活性。
    • 缺點:增加了程式碼的複雜性。
  • 觀察者模式

    • 描述:定義了物件之間的一對多依賴關係,當一個物件的狀態改變時,所有依賴於它的物件都會得到通知。
    • 優點:實現了物件之間的松耦合。
    • 缺點:如果觀察者數量過多,通知過程可能會變得複雜。
  • 策略模式

    • 描述:定義一系列演算法,把它們一個個封裝起來,並且使它們可以互相替換。
    • 優點:演算法的變化獨立於使用演算法的客戶。
    • 缺點:增加了程式碼的複雜性。
  • 裝飾者模式

    • 描述:動態地給一個物件新增一些額外的職責,而不必修改物件結構。
    • 優點:增加了程式碼的靈活性和可擴充套件性。
    • 缺點:增加了程式碼的複雜性。
  • 代理模式

    • 描述:為其他物件提供一種代理以控制對這個物件的訪問。
    • 優點:增加了安全性和靈活性。
    • 缺點:增加了程式碼的複雜性。

歡迎關注 ❤

我們搞了一個免費的面試真題共享群,互通有無,一起刷題進步。

沒準能讓你能刷到自己意向公司的最新面試題呢。

感興趣的朋友們可以加我微信:wangzhongyang1993,備註:sf面試群。

相關文章