前幾天參加了一場面試,GoLang 后端工程師,他們直接給了我 10 道題,我留了一個截圖。
在看答案之前,你可以先簡單做一下,下面我會對每個題目做一個說明。
文章目錄
- 1、golang map 是否并發安全?
- 2、協程泄漏的原因可能是什么?
- 3、關于channel操作正確的可能是?
- 4、Golang字符串轉成byte數組,會發生內存拷貝嗎?
- 5、請說一說Golang 的 GC可以怎么觸發的?
- 6、Channel是同步的還是異步的 ?
- 7、defer在return返回前還是返回后執行?
- 8、什么情況下可能會發生內存逃逸 ?
- 9、Golang中有哪些方式可以安全讀寫共享變量?
- 10、Golang協程為什么比線程輕量?
- 最后
1、golang map 是否并發安全?
Go 語言中的原生 map
并不是并發安全的。在多 goroutine 并發讀寫同一個 map
時,可能會導致數據競爭(race condition),從而引發程序崩潰。
可以用 sync.Map
Go標準庫中的 sync.Map
是一個并發安全的map實現。它內部通過讀寫分離的策略來減少鎖爭用,適用于讀多寫少的場景。例如:
var m sync.Map
m.Store("key", 42) // 存儲鍵值對
value, ok := m.Load("key") // 獲取值
m.Delete("key") // 刪除鍵值對
2、協程泄漏的原因可能是什么?
在 Go 語言中,協程泄漏(Goroutine Leak)是指啟動的協程無法正常退出,持續占用資源,最終可能導致程序崩潰或系統資源耗盡。
例如:
協程中存在無限循環,且沒有退出條件。多個協程之間存在死鎖,導致無法正常退出。總的來說就是協程沒有釋放、不受控制。
3、關于channel操作正確的可能是?
- 從已關閉的 channel 接收數據:是可以的。
- 向已關閉的 channel 發送數據:會導致運行時錯誤。
- 關閉已關閉的 channel:會導致運行時錯誤。
4、Golang字符串轉成byte數組,會發生內存拷貝嗎?
不會。GoLang 底層字符串就是用 byte 數組存儲的。
5、請說一說Golang 的 GC可以怎么觸發的?
自動觸發:堆內存達到閾值、時間周期觸發、系統監控觸發。
手動觸發:調用 runtime.GC()
。
6、Channel是同步的還是異步的 ?
無緩沖通道:同步。
ch := make(chan int) // 創建一個無緩沖通道
有緩沖通道:異步。
ch := make(chan int, 2) // 創建一個緩沖大小為2的通道
7、defer在return返回前還是返回后執行?
在函數真正返回給調用者之前執行。
8、什么情況下可能會發生內存逃逸 ?
在Go語言中,內存逃逸(Memory Escape)是指變量被分配到堆上,而不是棧上。這通常發生在Go編譯器無法確定變量是否會在函數外部被引用時。以下是一些可能導致內存逃逸的常見場景:
- 返回局部變量的指針
如果函數返回了局部變量的指針,該變量會被分配到堆上,因為其生命周期需要超出函數的作用域。
func createPointer() *int {x := 42return &x // x逃逸到堆上
}
- 閉包引用局部變量
如果閉包引用了局部變量,這些變量可能會被分配到堆上。
func main() {f := func() int {x := 10return x}fmt.Println(f()) // f會導致x逃逸到堆上
}
還有多種情況,這個有一定難度,我會再單開一篇繼續講解。
9、Golang中有哪些方式可以安全讀寫共享變量?
- 使用互斥鎖(sync.Mutex)
- 使用讀寫鎖(sync.RWMutex)
- 使用原子操作(sync/atomic)
- 使用通道(channel)
- 使用sync.Map進行并發訪問
10、Golang協程為什么比線程輕量?
- 調度開銷更小,協程的切換由Go運行時管理,上下文切換的開銷非常小,通常只需要幾十納秒。
- 協程的內存占用,Go協程:棧空間的初始大小非常小(通常為2KB),并且會根據需要動態擴展。這種動態棧分配機制使得協程的內存占用非常低。
- 協程的輕量級結構:Go協程的內部結構簡單,主要包含協程狀態、棧指針等信息,而操作系統線程需要維護更多的內核資源。
- Go運行時通過多路復用(Multiplexing)的方式將協程映射到少量的操作系統線程上,從而實現高效的并發執行。多路復用機制、高并發能力。
- 阻塞處理:協程阻塞時,運行時會自動切換到其他協程,充分利用CPU。
- Go協程:協程的創建和銷毀由Go運行時管理,開銷極小。創建和銷毀協程的成本非常低,因為它們不需要操作系統內核的介入。
最后
離線版PDF下載:
鏈接: https://pan.baidu.com/s/1zsffbsHj5CRC9whL7W-9aw?pwd=6666 提取碼: 6666