深信服golang面經

在這里插入圖片描述

for range 中賦值的變量,這個變量指向的是真實的地址嗎,還是臨時變量

不是真實地址,是臨時變量

package mainimport "fmt"func main() {slice := []int{4, 2, 3}for _, v := range slice {fmt.Println(v, &v) // 這里的 v 是臨時變量}for i := range slice{fmt.Println(i, &i)fmt.Println(slice[i], &slice[i])}fmt.Println("sjhdjaskhdjkashdkas")for _, v := range slice {fmt.Println(v, &v) // 這里的 v 是臨時變量}for i := range slice{fmt.Println(i, &i)fmt.Println(slice[i], &slice[i])}
}

如果在for range里面有一個函數,這個函數需要傳一個指針,這時候應該怎么寫,這時候會進行拷貝嗎

slice內容未改變, 換成另一個方法才會改變
for _,v := range x
是值拷貝

package mainimport "fmt"func main() {slice := []int{4, 2, 3}for _,v := range slice{fmt.Println(v, &v)doDubole(&v)fmt.Println(v, &v)}fmt.Println(slice)
}func doDubole(x *int){fmt.Println(*x, x)*x = *x*2
}

有用過go link?那么在什么情況下如果我不賦給一個新的變量,它也是沒問題的?

在 Go 語言中,link 通常指的是鏈接操作,主要用于將多個包和可執行文件組合成一個單一的可執行文件。

如果我要在defer里面修改return里面的值呢?這時怎么寫?

命名返回值
返回110

package mainimport "fmt"func main() {ans := get(10)fmt.Println(ans)
}
func get(x int)(ans int){defer func(){ans += 10}()ans = x*10return
}

map時協程安全嗎?有什么是協程安全的?

在 Go 中,map 不是協程安全的。如果多個協程同時讀寫同一個 map,可能會導致數據競爭和不確定的行為。因此,使用 map 時需要確保并發安全。

協程安全的解決方案:

  1. 使用 sync.Mutexsync.RWMutex

    • 通過互斥鎖確保對 map 的訪問是安全的。
    var mu sync.Mutex
    m := make(map[string]int)func safeWrite(key string, value int) {mu.Lock()m[key] = valuemu.Unlock()
    }func safeRead(key string) int {mu.Lock()value := m[key]mu.Unlock()return value
    }
    
  2. 使用 sync.Map

    • Go 提供了一個內置的并發安全的 map 類型 sync.Map,適合并發讀寫。
    var m sync.Map// 存儲值
    m.Store("key", 42)// 讀取值
    value, ok := m.Load("key")
    
  3. 使用通道 (Channels)

    • 通過通道來同步對數據的訪問,而不是直接操作 map
    type request struct {key   stringvalue intreply chan int
    }func mapHandler(requests <-chan request) {m := make(map[string]int)for req := range requests {m[req.key] = req.valuereq.reply <- m[req.key]}
    }
    

總結:

  • map 在并發環境下不安全。
  • 使用互斥鎖、sync.Map 或通道可以實現協程安全。

channel有緩沖區和無緩沖區的區別?

無緩沖:必須有人接收才能發送,需要保證順序性
在這里插入圖片描述
以下是有緩沖區和無緩沖區通道的實際應用場景示例。

1. 有緩沖區的通道:任務隊列

在一個工作池中,多個工作者從一個任務隊列中獲取任務。使用有緩沖區的通道可以存儲一定數量的任務,提高效率。

package mainimport ("fmt""time"
)func worker(id int, tasks <-chan int) {for task := range tasks {fmt.Printf("工作者 %d 處理任務 %d\n", id, task)time.Sleep(time.Second) // 模擬任務處理時間}
}func main() {tasks := make(chan int, 5) // 創建一個緩沖區為 5 的通道// 啟動多個工作者for i := 1; i <= 3; i++ {go worker(i, tasks)}// 發送任務for i := 1; i <= 10; i++ {fmt.Printf("發送任務 %d\n", i)tasks <- itime.Sleep(500 * time.Millisecond) // 模擬任務生成時間}close(tasks) // 關閉通道time.Sleep(5 * time.Second) // 等待所有任務完成
}

2. 無緩沖區的通道:同步信號

在兩個 goroutine 之間使用無緩沖區通道進行同步,確保一個 goroutine 在另一個完成后再繼續執行。

package mainimport ("fmt"
)func main() {done := make(chan struct{}) // 創建一個無緩沖區的信號通道go func() {fmt.Println("工作者正在處理任務...")// 模擬任務處理// ...done <- struct{}{} // 發送完成信號}()// 等待工作者完成<-donefmt.Println("任務完成,主程序繼續執行。")
}

總結

  • 有緩沖區的通道適用于任務隊列等場景,可以提高并發性能。
  • 無緩沖區的通道適用于需要同步的場景,確保操作的順序。

我能不能在寫入channel的時候,先判斷它阻不阻塞再寫?

在 Go 中,無法直接檢查一個通道是否會阻塞。通道的發送和接收都是阻塞操作,具體行為取決于通道的狀態和接收方是否準備好。

解決方案

如果你想在寫入通道之前判斷是否會阻塞,可以使用非阻塞發送配合 select 語句。例如:

package mainimport ("fmt"
)func main() {ch := make(chan int, 1) // 創建一個緩沖通道,容量為 1// 先嘗試發送select {case ch <- 42: // 非阻塞發送fmt.Println("寫入成功")default:fmt.Println("通道已滿,寫入阻塞")}// 再次嘗試發送select {case ch <- 99:fmt.Println("寫入成功")default:fmt.Println("通道已滿,寫入阻塞")}// 從通道讀取值value := <-chfmt.Println("讀取值:", value)
}

關鍵點:

  1. select 語句:允許你進行非阻塞操作。
  2. default 分支:在通道不能發送或接收時執行,避免阻塞。

通過這種方式,你可以在寫入通道之前判斷通道的狀態,從而避免阻塞。

mutex是個悲觀鎖還是樂觀鎖,樂觀鎖和悲觀鎖的區別?

Mutex 是悲觀鎖,適用于高沖突的場景。
樂觀鎖 適用于低沖突的場景,減少了加鎖帶來的性能開銷。

需要知道一個goroutine里面的一個函數是否執行成功還是失敗,應該怎么寫

要在一個 goroutine 中檢查一個函數是否執行成功,可以使用通道(channel)來傳遞結果或錯誤信息。以下是一個示例,演示如何實現這一點:

示例代碼

package mainimport ("errors""fmt""time"
)func doWork(resultChan chan<- string, errChan chan<- error) {// 模擬一些工作time.Sleep(2 * time.Second)// 假設工作成功,返回結果// resultChan <- "工作成功"// 假設工作失敗,返回錯誤errChan <- errors.New("工作失敗")
}func main() {resultChan := make(chan string)errChan := make(chan error)go doWork(resultChan, errChan)select {case result := <-resultChan:fmt.Println("結果:", result)case err := <-errChan:fmt.Println("錯誤:", err)case <-time.After(3 * time.Second): // 設置超時fmt.Println("操作超時")}
}

關鍵點

  1. 通道

    • 使用 resultChan 來傳遞成功結果。
    • 使用 errChan 來傳遞錯誤信息。
  2. select 語句

    • 通過 select 等待通道中的結果或錯誤。
    • 如果有結果返回,則打印結果;如果有錯誤返回,則打印錯誤。
  3. 超時處理

    • 可以使用 time.After 設置超時處理,避免等待太久。

通過這種方式,你可以有效地在 goroutine 中檢查函數的執行狀態。

了解過Go的內存逃逸嗎?

是的,Go 的內存逃逸(Escape Analysis)是一個重要的功能,用于優化內存分配和管理。

什么是內存逃逸?

內存逃逸指的是在 Go 中某個變量的生命周期超出了其原本的作用域。這意味著該變量不能在棧上分配,而必須在堆上分配,以確保在函數返回后仍然能夠訪問。

如何工作?

  1. 棧 vs 堆

    • :用于存儲局部變量,分配和釋放速度快,但生命周期受限于函數調用。
    • :用于動態分配內存,生命周期更長,但分配和釋放速度較慢。
  2. 逃逸分析

    • Go 編譯器會在編譯時分析變量的使用情況,判斷它是否會“逃逸”到堆上。
    • 如果變量的地址被返回,或在函數外部使用,它將被分配到堆上。

示例

以下是一個簡單的例子,展示了內存逃逸的情況:

package mainimport "fmt"type Person struct {Name string
}func NewPerson(name string) *Person {return &Person{Name: name} // 逃逸到堆
}func main() {p := NewPerson("Alice")fmt.Println(p.Name)
}

在上面的代碼中,NewPerson 函數返回一個指向 Person 結構體的指針,這導致 Person 實例被分配到堆上,因為它的生命周期超出了函數的作用域。

逃逸分析的好處

  • 性能優化:通過避免不必要的堆分配,提升性能。
  • 內存管理:減少內存泄漏的風險,幫助開發者更好地管理內存。

如何檢查逃逸分析

可以使用 go build -gcflags -m 命令來查看編譯器的逃逸分析信息:

go build -gcflags -m yourfile.go

這將顯示哪些變量逃逸到堆上,以及相關的分析信息。

總結

內存逃逸分析是 Go 的一項重要特性,幫助編譯器優化內存分配,提高程序性能。理解內存逃逸有助于編寫更高效的 Go 代碼。

場景:1GB文件,每個單詞不超過16字節,在1M的內存里,得到出現頻率最高的100個單詞

由于文件大小為1GB,而內存的大小只有1MB,因此不能一次把所有的詞讀入到內存中去處理,可以采用分治的方法進行處理:把一個文件分解為多個小的子文件,從而保證每個文件的大小都小于1MB,進而可以直接被讀取到內存中處理。

第一步:使用多路歸并排序對大文件進行排序,這樣相同的單詞肯定是挨著的

第二步:
① 初始化一個 100 個節點的小頂堆,用于保存 100 個出現頻率最多的單詞
② 遍歷整個文件,一個單詞一個單詞的從文件中取出來,并計數
③ 等到遍歷的單詞和上一個單詞不同的話,那么上一個單詞及其頻率如果大于堆頂的詞的頻率,那么放在堆中,否則不放

最終,小頂堆中就是出現頻率前 100 的單詞了

多路歸并排序對大文件進行排序的步驟如下:
① 將文件按照順序切分成大小不超過 512KB 的小文件,總共 2048 個小文件
② 使用 1MB 內存分別對 2048 個小文件中的單詞進行排序
③ 使用一個大小為 2048 大小的堆,對 2048 個小文件進行多路排序,結果寫到一個大文件中

json和protobuf的區別

JSON(JavaScript Object Notation)和 Protobuf(Protocol Buffers)是兩種常用的數據序列化格式。它們各自有不同的特點和適用場景。以下是它們之間的主要區別:

1. 數據格式

  • JSON

    • 人類可讀的文本格式,易于調試和查看。
    • 數據使用鍵值對的結構表示,支持基本數據類型(字符串、數字、布爾值、數組和對象)。
  • Protobuf

    • 二進制格式,不易于人類直接閱讀。
    • 需要預先定義數據結構(消息格式)并編譯生成代碼來處理數據。

2. 性能

  • JSON

    • 解析和序列化速度較慢,因為它是文本格式。
    • 數據體積相對較大,尤其是在傳輸大量數據時。
  • Protobuf

    • 解析和序列化速度快,效率高。
    • 數據體積較小,適合網絡傳輸和存儲。

3. 可擴展性

  • JSON

    • 結構靈活,不需要預定義模式,可以隨意添加字段,但對版本控制支持較差。
  • Protobuf

    • 需要預定義結構,但支持向后兼容和向前兼容,可以安全地添加或刪除字段。

4. 語言支持

  • JSON

    • 幾乎所有編程語言都支持 JSON 解析和生成。
  • Protobuf

    • 支持多種編程語言,但需要使用特定的工具生成代碼。

5. 使用場景

  • JSON

    • 適用于配置文件、Web API(如 RESTful API)、輕量級數據傳輸等場景。
  • Protobuf

    • 適用于高性能網絡通信、大規模數據存儲、微服務架構等場景。

總結

  • JSON:易讀、靈活,但性能較低,適合簡單的應用場景。
  • Protobuf:高效、可擴展,適合對性能和數據體積有較高要求的應用場景。

Go怎么調試的,會Goland遠程調試嗎?

  1. 安裝dlv
    在Linux服務器上執行:go install github.com/go-delve/delve/cmd/dlv@latest,安裝dlv調試工具,因為是go編譯的可執行程序,可以隨意復制,其他環境甚至都可以不安裝go語言環境。

  2. 按照goland提示添加遠程調試

  3. 添加編譯配置

  4. 在服務器運行
    將可執行程序上傳到服務器,并使用dlv運行:
    dlv --listen=:2345 --headless=true --api-version=2 --accept-multiclient exec ./test001_linux

帶命令行參數,在可執行程序后面帶上 --,再后面就是命令行參數:

dlv --listen=:2345 --headless=true --api-version=2 --accept-multiclient exec ./test001_linux – -s 123

  1. 然后再window的goland上運行調試

算法:查找字符串子串,有哪些算法?

暴力匹配:簡單,但效率低。
KMP:高效,適合單個子串匹配。O(m+n)
部分匹配表(LPS 數組):

在開始匹配之前,KMP 算法首先構建一個部分匹配表(Longest Prefix Suffix,LPS)。
LPS 數組的每個元素 lps[i] 表示子串 pattern[0…i] 中的最長相等前后綴的長度。
LPS 數組可以幫助我們在匹配失敗時,不必回溯主串的指針,而是根據已匹配的部分直接跳到下一個可能匹配的位置。
匹配過程:

使用兩個指針,i 指向主串,j 指向子串。
逐個比較主串和子串的字符:
如果字符匹配,兩個指針同時向后移動。
如果不匹配且 j > 0,則根據 LPS 數組調整子串指針 j,而不移動主串指針 i。
如果 j 達到子串的長度,說明找到匹配,記錄匹配位置。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/81644.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/81644.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/81644.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

PLC雙人舞:profinet轉ethernet ip網關奏響施耐德與AB的協奏曲

PLC雙人舞&#xff1a;ethernet ip轉profinet網關奏響施耐德與AB的協奏曲 案例分析&#xff1a;施耐德PLC與AB PLC的互聯互通 在現代工業自動化中&#xff0c;設備之間的互聯互通至關重要。本案例旨在展示如何通過北京倍訊科技的EtherNet/IP轉Modbus網關&#xff0c;將施耐德P…

鏈接家里電腦

要在外網訪問家里的電腦&#xff08;或NAS&#xff09;&#xff0c;主要有 5種主流方法&#xff0c;各有優缺點&#xff0c;適用于不同需求。以下是詳細方案和操作指南&#xff1a; 一、方案對比速查表 方法適用場景速度安全性難度是否需要公網IP遠程桌面&#xff08;RDP&…

VS Code開源AI編輯器:一場編程革命的新起點

在2025年5月19日&#xff0c;微軟發布了一則激動人心的消息——VS Code將開源其AI編輯器組件&#xff0c;特別是GitHub Copilot Chat擴展。正如微軟官方博客所宣告的&#xff1a;“我們相信代碼編輯器的未來應該是開放的&#xff0c;并由AI驅動。” 為什么現在開源&#xff1f…

51c嵌入式※~合集7~Linux

我自己的原文哦~ https://blog.51cto.com/whaosoft/13926843 一、u-boot和bootloader~區別 Bootloader 比Bootloader從字面上來看就是啟動加載的意思。用過電腦的都知道&#xff0c;windows開機時會首先加載bios&#xff0c;然后是系統內核&#xff0c;最后啟動完畢。那…

深度學習實戰 04:卷積神經網絡之 VGG16 復現三(訓練)

在后續的系列文章中&#xff0c;我們將逐步深入探討 VGG16 相關的核心內容&#xff0c;具體涵蓋以下幾個方面&#xff1a; 卷積原理篇&#xff1a;詳細剖析 VGG 的 “堆疊小卷積核” 設計理念&#xff0c;深入解讀為何 332 卷積操作等效于 55 卷積&#xff0c;以及 333 卷積操作…

Ubuntu 20.04之Docker安裝ES7.17.14和Kibana7.17.14

你需要已經安裝如下運行環境: Ubuntu 20.04 docker 28 docker-compose 1.25 一、手動拉取鏡像 docker pull docker.elastic.co/kibana/kibana:7.17.14docker pull docker.elastic.co/elasticsearch/elasticsearch:7.17.14 或者手動導入鏡像 docker load -i es7.17.14.ta…

實時技術方案對比:SSE vs WebSocket vs Long Polling

早期網站僅展示靜態內容,而如今我們更期望:實時更新、即時聊天、通知推送和動態儀表盤。 那么要如何實現實時的用戶體驗呢?三大經典技術各顯神通: SSE(Server-Sent Events):輕量級單向數據流WebSocket:雙向全雙工通信Long Polling(長輪詢):傳統過渡方案假設目前有三…

測試開發面試題:Python高級特性通俗講解與實戰解析

前言&#xff1a;為什么測試工程師必須掌握Python高級特性&#xff1f; 通俗比喻&#xff1a; 基礎語法就像“錘子”&#xff0c;能敲釘子&#xff1b;高級特性就像“瑞士軍刀”&#xff0c;能應對復雜場景&#xff08;如自動化框架、高并發測試&#xff09;。面試官考察點&a…

C語言-9.指針

9.1指針 9.1-1取地址運算:&運算符取得變量的地址 運算符& scanf(“%d”,&i);里的&獲取變量的地址,它們操作數必須是變量int i;printf(“%x”,&i);地址的大小是否與int相同取決于編譯器int i;printf(“%p”,&i); &不能取的地址不能對沒有地址的…

【C++】Vcpkg 介紹及其常見命令

Vcpkg 簡介 Vcpkg 是微軟開發的一個跨平臺的 C/C 依賴管理工具&#xff0c;用于簡化第三方庫的獲取、構建和管理過程。 主要特點 跨平臺支持&#xff1a;支持 Windows、Linux 和 macOS開源免費&#xff1a;MIT 許可證大型庫集合&#xff1a;包含超過 2000 個開源庫簡化集成&…

Unity3D 動畫文件優化總結

前言 在Unity3D中&#xff0c;動畫文件的壓縮和優化是提升性能的重要環節&#xff0c;尤其在移動端或復雜場景中。以下是針對Animation Clip和Animator Controller的優化方法總結&#xff1a; 對惹&#xff0c;這里有一個游戲開發交流小組&#xff0c;希望大家可以點擊進來一…

前端工程的相關管理 git、branch、build

環境配置 標準環境打包 測試版&#xff1a;npm run build-test 預生產&#xff1a;npm run build-preview 正式版&#xff1a;npm run build 建議本地建里一個 .env.development.local 方便和后端聯調時修改配置相關信息。 和 src 同級有一下區分環境的文件&#xff1a; .env.d…

VAPO:視覺-語言對齊預訓練(對象級語義)詳解

簡介 多模態預訓練模型(Vision-Language Pre-training, VLP)近年來取得了飛躍發展。在視覺-語言模型中,模型需要同時理解圖像和文本,這要求模型學習二者之間的語義對應關系。早期方法如 VisualBERT、LXMERT 等往往使用預先提取的圖像區域特征和文本詞嵌入拼接輸入,通過 T…

docker運行Redis

創建目錄 mkdir -p /home/jie/docker/redis/{conf,data,logs}添加權限 chmod -R 777 /home/jie/docker/redis創建配置文件 cat > /home/jie/docker/redis/conf/redis.conf << EOF # 基本配置 bind 0.0.0.0 protected-mode yes port 6379# 安全配置 密碼是root require…

初識 java

目錄 前言 一、jdk&#xff0c;JRE和JVM之間的關系 二、JVM的內存劃分 前言 初步了解 jdk&#xff0c;JRE&#xff0c;JVM 之間的關系&#xff0c;JVM 的內存劃分。 一、jdk&#xff0c;JRE和JVM之間的關系 jdk 是 java 開發工具集&#xff0c;包含JRE&#xff1b; JRE 是…

關于百度地圖JSAPI自定義標注的圖標顯示不完整的問題(其實只是因為圖片尺寸問題)

下載了幾個阿里矢量圖標庫里的圖標作為百度地圖的自定義圖標&#xff0c;結果百度地圖顯示的圖標一直不完整。下載的PNG圖標已經被正常引入到前端代碼&#xff0c;anchor也設置為了圖標底部中心&#xff0c;結果還是顯示不完整。 if (iconUrl) {const icon new mapClass.Icon(…

系統安全及應用深度筆記

系統安全及應用深度筆記 一、賬號安全控制體系構建 &#xff08;一&#xff09;賬戶全生命周期管理 1. 冗余賬戶精細化治理 非登錄賬戶基線核查 Linux 系統默認創建的非登錄賬戶&#xff08;如bin、daemon、mail&#xff09;承擔系統服務支撐功能&#xff0c;其登錄 Shell 必…

02-前端Web開發(JS+Vue+Ajax)

介紹 在前面的課程中&#xff0c;我們已經學習了HTML、CSS的基礎內容&#xff0c;我們知道HTML負責網頁的結構&#xff0c;而CSS負責的是網頁的表現。 而要想讓網頁具備一定的交互效果&#xff0c;具有一定的動作行為&#xff0c;還得通過JavaScript來實現。那今天,我們就來講…

AXXI4總線協議 ------ AXI_FULL協議

https://download.csdn.net/download/mvpkuku/90855619 一、AXI_FULL協議的前提知識 1. 各端口的功能 2. 4K邊界問題 3. outstanding 4.時序仿真體驗 可通過VIVADO自帶ADMA工程觀察仿真波形圖 二、FPGA實現 &#xff08;主要用于讀寫DDR&#xff09; 1.功能模塊及框架 將…

React系列——nvm、node、npm、yarn(MAC)

nvm&#xff0c;node&#xff0c;npm之間的區別 1、nvm&#xff1a;nodejs版本管理工具。nvm 可以管理很多 node 版本和 npm 版本。 2、nodejs&#xff1a;在項目開發時的所需要的代碼庫 3、npm&#xff1a;nodejs包管理工具。nvm、nodejs、npm的關系 nvm 管理 nodejs 和 npm…