透過 Go Slog 達成結構化寬事件 logging 最佳實踐
最近有較多的時間思考開發上的最佳實踐,考慮到目前開發的一個後端項目基本就是拿 go 原生的 log 到處打印儲存片面狀態而已。在閱讀一些文件與最佳實踐後,我想著手改善現有的 logging 體驗透過導入 Go 1.21 引入的原生 slog 庫。
最近有較多的時間思考開發上的最佳實踐,考慮到目前開發的一個後端項目基本就是拿 go 原生的 log 到處打印儲存片面狀態而已。在閱讀一些文件與最佳實踐後,我想著手改善現有的 logging 體驗透過導入 Go 1.21 引入的原生 slog 庫。
大多程式都可以採取「並行 Concurrency」的方式來達成簡單安全且高效的運行,但隨著多核 CPU 出現以及特定場景對於效率的追求「平行 Parallelism」運行程式是另一個提高運行效率方向。本文練習透過 Go 複習平行程式開發下資料存取相關技巧:原子操作、鎖、信號量⋯⋯
相較於 C 讀取未定義數值的變數會造成安全漏洞或崩潰,或是動態語言如 JavaScript 沒有數值型別初始化的問題,Go 的設計上就自動賦予了確定意義的數值避免出錯與創建即可使用。具體來說在例如使用 json 反射的標籤中 `omitempty` 也正是運用了 Zero Value 的概念來判斷。
紀錄近期從 JavaScript 遷移到 Go 的過程中實踐 Set 資料結構的方式。先前代碼使用 JavaScript Set 來實現不重複資料定義,但在 Go 語言當中並沒有實踐 Set 資料結構,但我們可以透過改造 map 來實踐。
紀錄使用到其中一項 Go 1.16 的 embed 功能,可以把任何檔案在編譯時就包進去,進而不用煩惱路徑與環境問題。如果資料需要在 runtime 被修改,那就不適合使用 embed,但如果它是「版本的一部分」,那 embed 是更安全的選擇。
從 JavaScript 轉寫 Go 我其實還是不太熟悉 Go 如何模組化處理代碼,雖然它們有大致相似的地方,但使用體驗感覺非常簡單甚至到簡陋的程度,當然簡單並不意味著「容易」或「沒用」,Go 簡單且固執己見的哲學在各方面都感受得到。
處理傳遞資料時都快忘了有「序列化與反序列化資料」這個步驟,因為都被套件像是:Axios 抽象掉了,近期在寫後端也重新溫習相關知識,也延續先前文章:Go Struct Tag 是什麼?如何透過 reflect 動態處理欄位?探討 Go 如何處理序列化資料。
Context 是 Go 1.7 添加於標準函式庫的功能。常在存取資料庫或其他服務時會遇到,初步看起來是用於「傳遞取消信號」用途的語法,用於處理 goroutine:背負期限(deadline)、取消信號(cancellation signal)、傳遞請求相關的值(request-scoped values)。
當在 Go 字串中索引位置 `n` 時,為什麼沒有得到第 `n` 個字元?相較於其他程式語言一串文字在遍歷時會預期拿到單一個字符,在 Go 會拿到「Rune」;如果直接透過索引取得 string 內容會拿到 byte。透過實際解 Codewars 題目了解處理字串要留意的東西
最近在與 MongoDB 互動時發現 Struct 欄位結尾有一段語法不是很熟悉,這篇文章探討 Struct Tag 存在的原因以及解決什麼問題。與其命令式的操縱資料,透過宣告式的方式來描述資料格式是 Struct Tag 的主要用途。
Goroutine 是由 Go 語言本身管理的輕量級執行緒(User-space Thread),而不是由作業系統管理的執行緒(OS Thread)。背後使用 M:N 排程模型。這意味著,M 個 Goroutine 會被分配到 N 個作業系統執行緒(OS Threads)上執行。
在 Go 語言中,有兩種常見的資料結構可用於表示「序列資料」:Array 與 Slice。這兩者在語法上相似,但背後行為與使用情境差異非常關鍵。簡單來說,Array 是固定長度(Static Array),而 Slice 是動態長度(Dynamic Array)。
對於「多型 Polymorphism」的概念理解像是「要做一件事,但這件事對不同對象來說實踐的方式不同」。具體來說像是各種「形狀」都可以「算面積」,但背後實踐的方法卻不同,而在 Go 當中 interface 就是方法的集合。
第一次看到 Go 的 Receiver 函式會覺得這是啥怪語法,函式名前面還能接收參數?Go 語言提倡「Composition over inheritance」(組合優於繼承),並極力追求程式碼的簡潔性,以此迴避 class-based OOP 所帶來的複雜性。
Go 設計上一切數值都是直白的「Passing by value」,會有「Passing by value」的效果原因是因為 Reference Types 帶有指標,複製時是複製指標值。要讓 Value Types 有 Passing by Reference 的效果要顯式的使用 Pointer。