本文是根據近期對 Etcd-Raft 的學習把自己的理解做個簡單整理和分享。近期負責的項目中有一個場景需要依賴數據一致性算法,因此做了一些相關的調研。本文是根據近期對【Etcd-Raft】的學習把自己的理解做個簡單整理和分享。注:本文並沒有對 Etcd/Raft 源碼和流程事無鉅細的解剖,更多地關注其核心功能以及過程中個人覺得值得學習的點。前言Etcd 是什麼? 爲什麼選擇 etcd-ra ⌘ Read more
本文是根據近期對 Etcd-Raft 的學習把自己的理解做個簡單整理和分享。近期負責的項目中有一個場景需要依賴數據一致性算法,因此做了一些相關的調研。本文是根據近期對【Etcd-Raft】的學習把自己的理解做個簡單整理和分享。注:本文並沒有對 Etcd/Raft 源碼和流程事無鉅細的解剖,更多地關注其核心功能以及過程中個人覺得值得學習的點。前言Etcd 是什麼? 爲什麼選擇 etcd-ra ⌘ Read more
如果你不是做大數據分析的,提到 Arrow 這個詞,你可能會以爲我要聊聊那個箭牌衛浴或是箭牌口香糖 (注:其實箭牌口香糖使用的單詞並非 Arrow)。其實我要聊的是 Apache 的一個頂級項目:Arrow[1]。爲什麼要聊這個項目呢?說來話長,主要是因爲前段時間接觸到的幾個時序數據庫開源項目,包括國外大名鼎鼎的 InfluxDB(尤指其 iox 這個新存儲引擎)[2] 以及國內一個新初創公司的開 ⌘ Read more
1 裝飾器模式本期和大家交流的是設計模式中的裝飾器模式.下面聊聊關於裝飾器模式的基本定義:裝飾器模式能夠在不改變原對象結構的基礎上,動態地爲對象增加附屬能力. 在實現思路上,裝飾器模式和 “繼承” 一定的類似之處,但是兩者側重點有所不同,可以把裝飾器模式作爲 “繼承” 的一種補充手段.這麼幹講概念顯得過於抽象,下面我們通過一個實際案例,來和大傢俱體地剖析一下有關於裝飾器模式的實現思路:JwsYMP ⌘ Read more
一、介紹fastcache 是一個用 go 語言實現的,很快的,線程安全的,內存緩存的,用於大量對象緩存的組件。它的特點是:快速的多核 CPU 的性能可擴展。 線程安全。併發 goroutines 可以讀取和寫入單個緩存實例。 快速緩存是爲存儲大量條目而設計的,沒有 GC 開銷。 當達到創建時設置的最大緩存大小時,Fastcache 會自動收回舊條目。 簡單的 API ⌘ Read more
easyfsm 之前看過新亮老哥的 go-fsm-order,感覺還不錯。最近在遷移項目的時候,發現有多處業務存在一些狀態的流轉,所以就基於 go-fsm-order 做了重改,讓它可以在不同的業務場景下使用。 爲什麼不使用 looplab/fsm,star 挺多的啊。不是特別喜歡,每次實例化 fsm 都需要重新傳遞對應 events(雖然我們可以統一封裝),我更期望在項目啓動時把此項目涉及到 ⌘ Read more
問題--當 Go 系統遭遇突增流量,洪峯過境,流量恢復正常後,整個系統的資源消耗是否會變大?第一反應,應該是會恢復到之前的水平吧!資源消耗在流量恢復正常之後,爲什麼會變大呢... 復現-- 模擬一下該場景。我們知道 Go 原生的網絡模型 goroutine-per-connection,即一個連接分配一個 goroutine 去處理。當流量突增,瞬間高併發,很有可能使協程數量也同步增加。即如 ⌘ Read more
Go 內建的 map 類型對於插入的元素並沒有保持它們的插入順序,遍歷的時候也故意設置成隨機的 1]。因此,如果我們想讓 map 保持元素的插入順序,需要藉助第三方的庫纔行,今天就給大家介紹一個這樣的庫 OrderedMap。其實在其他編程語言中,也有類似的數據結構,比如 java 中的 LinkedHashMap[2], python 中的OrderedDict。本文介紹如何使用 Go 語言實現 ⌘ Read more
goreleaser 介紹GoReleaser 是一個開源的 Go 二進制文件打包和發佈工具,它能夠自動化和簡化發佈過程,從而使得發佈應用程序變得更加容易和可靠。GoReleaser 的主要特點包括:支持多種打包格式:GoReleaser 可以將您的 Go 應用程序打包成多種格式,包括二進制文件、Docker 鏡像、Snap 包、RPM 和 Deb 包等。 支持多種發佈渠道:GoReleas ⌘ Read more
概述--sync.Pool 是 Go 語言標準庫中的一個併發安全的對象池,可以用來緩存那些需要重複創建和銷燬的對象,從而避免頻繁地進行內存分配和回收,降低內存和 GC 壓力。需要注意的是: 任何存儲在對象池中的元素可能會被隨時刪除,如果元素是一個資源類的引用,並且該資源僅在對象池中被引用 (沒有其他地方引用了),那麼當該元素被對象池刪除時,其指向的資源同時也會被釋放。內部實現----sync.Po ⌘ Read more
大家好,我是漁夫子。channel 是 golang 中獨有的特性,也是面試中經常被問到的。相信大家都看到過下面這張圖,對於不同狀態下通道,在操作時會有什麼結果。這張圖總結的非常好。但我們不能死記硬背這些結果。要了解其底層的基本原理,就能理解這些結果是怎麼來的。我們分三部分來講。先是 channel 的基礎使用,基礎使用提現了 channel 有哪些特性。再引出 channel 的底層數據結構。底 ⌘ Read more
下面分析下 mysql 作爲後端存儲的時候,是如何存儲的,它的核心源碼位 graph/sql/mysql/mysql.go,首先定義了存儲類型是 mysql,然後註冊。const Type = "mysql"func init() { csql.Register(Type, csql.Registration{ Driver: "mysql", HashT ⌘ Read more=
下面我能看下 cadence 的 helloword 例子的源碼,它包含兩個文件,第一個文件是啓動程序,第二個定義了 workflow 和 activitypackage mainimport ( "flag" "time" "github.com/pborman/uuid" "go.uber.org/cadence/client" "go.uber.org/cadenc ⌘ Read more
什麼是原子操作?\\-\\-\\-\\-\\-\\-\\-\\- 原子操作是變量級別的互斥鎖。如果讓我用一句話來說明什麼是原子操作,那就是:原子操作是變量級別的互斥鎖。簡單來說,就是同一時刻,只能有一個 CPU 對變量進行讀或寫。 當我們想要對某個變量做併發安全的修改,除了使用官方提供的 Mutex,還可以使用 sync/atomic 包的原子操作, 它能夠保證對變量的讀取或修改期間不被其他的協程所影響。我們可以用下圖來表示: ⌘ Read more
介紹Golang 配置信息管理庫 Viper[1],它提供一套完整的管理配置信息的解決方案。Go 語言中很多知名開源項目也都選擇使用 Viper,它功能非常強大,本文介紹 Viper 讀取結構體嵌套配置信息的使用方式。02 讀取結構體嵌套配置信息在實際項目開發中,我們經常會遇到一些比較複雜的配置信息,比如多層嵌套的配置信息,在結構體中嵌套結構體和切片。userdata: uid: 10000 ⌘ Read more
接着我們分析下命令行工具,這裏除了導入導出工具還有 gizmo 語法支持、graphql 支持等相關命令行工具。 gogen.go 裏定義瞭如何生成 Gizmo 的文檔。//go:generate go run ./cmd/docgen/docgen.go -i ./docs/GizmoAPI.md.in -o ./docs/GizmoAPI.mdimports. ⌘ Read more
接着看下 query 目錄,首先是 session.go 文件,它定義了迭代器接口type Iterator interface { // Next advances the iterator to the next value, which will then be available through // the Result method. It returns false if no ⌘ Read more
https://github.com/mattn/goreman 是 golang 實現的一個進程管理器,方便我們快速啓動多個進程,比如 etcd 就是通過它來管理的,下面我們看下如何使用: 新建一個文件 Procfile command1: lscommand2: pwdcommand3: echo 'helloworld'然後,運行命令 % goreman start ⌘ Read more
作者: 金刀大菜牙 https://juejin.cn/post/7229193250903507004作爲一種常見的數據結構,緩衝區(Buffer)在計算機科學中有着廣泛的應用。Go 語言標準庫中提供了一個名爲 bytes.Buffer 的緩衝區類型,它可以方便地進行字符串操作、IO 操作、二進制數據處理等。本文將詳細介紹 Go 中 Buffer 的用法,從多個方面介紹其特性和應用場景 ⌘ Read more
接着我們看下 writer 的實現,writer 的核心源碼位於 writer/single.go,writer 的註冊方式和存儲的註冊類似,它註冊了一個 single 的 writerfunc init() { graph.RegisterWriter("single", NewSingleReplication)type Single struct { qs ⌘ Read more
接着分析 memstore 中索引的具體實現,它的 B + 樹不是自己實現的,而是引用了一個第三方包,首先我們看下 gen.go,它裏面其實是運行來 Makefile 命令package memstore//go:generate make specify Makefile 文件中下載了實現了 B + 樹的包 https://github.com/cznic/b, ⌘ Read more
下我們先體驗下如何使用然後分析下例子的源碼。首先我們使用默認的配置,採用 docker-compose 啓動 server 端% cd cadence/docker % docker-compose upCreating network "dockerdefault" with the default driverPulling cassandra (cassandra:3.11) ⌘ Read more
介紹-----Go語言以簡單、高效地編寫高併發程序而聞名,這離不開Go語言原語中協程(Goroutine)的設計,也正對應了多核處理器的時代需求。與傳統多線程開發不同,GO語言通過更輕量級的協程讓開發更便捷,同時避免了許多傳統多線程開發需要面對的困難。因此,Go語言在設計和使用方式上都與傳統的語言有所不同,必須理解其基本的設計哲學和使用方式才能正確地使用。系統進化史--------爲了瞭解Go語言 ⌘ Read more
大家好,這裏是 Go 學堂。今天給大家推薦一個高效的 HTTP 的請求包:carlmjohnson/requests。項目地址是:https://github.com/carlmjohnson/requests該包誕生的背景-------作者在自己的博客中描述了自己爲什麼寫這個 request 包。作者這樣描述 go 的 net/http 包:Go 的 net/http 包雖然功能強大、用途也廣泛 ⌘ Read more
你在什麼時候會產生 “想要放棄用 Go 語言” 的念頭?也許是在用 Go 開發過程中,接連不斷踩坑的時候。本文作者提煉和總結《100 Go Mistakes and How to Avoid Them》裏的精華內容,並結合自身的工作經驗,盤點了 Go 的常見典型錯誤,撰寫了這篇超全避坑指南。讓我們跟隨文章,一起重拾用 Go 的信心~👉目錄1 注意 shadow 變量2 慎用 init 函數3 em ⌘ Read more
大家好,我是站長 polarisxu。上次介紹了標準庫中的文件類型檢測方法,有不少人提到它很不準。的確如此。本期介紹一個更好、更準的第三方庫。filetype(https://github.com/h2non/filetype)是一個 Go 語言的第三方庫,可以根據文件的魔數(magic numbers)簽名來推斷文件的類型和 MIME 類型。它支持多種常見的文件類型,包括圖片、視頻、音頻、文檔、 ⌘ Read more
大家好,我是漁夫子。本文總結了 go 語言中對 JSON 數據結構和結構體之間相互轉換問題及解決方法。基礎使用----使用 Go 標準庫中的 json.Marshal()與json.Unmarshal進行基本的序列化和反序列化。type Person struct { Name string Age int64 Weight float64}func main() { p1 := Per ⌘ Read more=
下面我們分析下不同存儲後端是如何註冊的,最後具體分析下,內存存儲的具體實現方式。 獲取內部存儲註冊完成後的實例函數定義如下 graph/registry.go func NewQuadStore(name string, dbpath string, opts Options) (QuadStore, error) { r, registered ⌘ Read more
圖片拍攝於 2023 年 04 月 27 日 日本鎌倉各位大佬,還不會 iouring,輕噴。不鴿了不🐦了。 目前 Go 圈有很多款異步的網絡框架: evio,nbio,gnet,cloudwego/netpoll......,排名不分先後。這裏面最早的實現是 evio。evio 也存在一些問題,之前也寫過 evio 文章介紹過。其他比如 nbio 和 gnet 也寫過一些源碼分析。這些框架在應 ⌘ Read more
反射 [1] 是一種編程語言的高級特性,它允許程序在運行時檢視自身的結構和行爲。通過反射,程序可以動態地獲取類型 (type) 與值 (value) 等信息,並對它們進行操作,諸如修改字段、調用方法等,這使得程序具有更大的靈活性和可擴展性。不過,反射雖然具有強大的功能,但也存在一些缺點。由於反射是在運行時進行的,因此它比直接調用代碼的性能要差。此外,反射還可能導致代碼的可讀性和維護性降低,因爲它使 ⌘ Read more
https://github.com/go-redsync/redsync 是 golang 實現的一個 redis 分佈式鎖,支持 quorum 機制,內部通過委託模式支持 https://github.com/redis/go-redis 客戶端和 https://github.com/gomodule/redigo 客戶端。首先看下如何使用,然後分析下它的源碼具體實現。pac ⌘ Read more
簡介Go,也被稱爲 Golang,是一種開源的編程語言,由於其簡單、強類型化和內置的併發功能而受到歡迎。雖然 Go 被設計成易於學習和使用,但開發人員仍然會犯錯誤。這篇博文將討論開發人員在用 Go 編程時常犯的 25 個錯誤,爲提高你的 Go 編程技能提供一個全面的指南。不處理錯誤Go 中最常見的錯誤之一是不處理錯誤。在調用一個返回錯誤的函數時,一定要檢查錯誤,並進行相應的處理。忽略 deferd ⌘ Read more
在分析完如何使用 cayley 後,我們總結下使用的時候的步驟: 1,初始化後端存儲,比如 memory、kv、sql 等2,加入四元祖 3,指定起始節點 4,綁定查詢條件 5,使用迭代器獲取結果 如何初始化後端存儲呢?我們分析下它的源碼,比如 memstore 的初始化邏輯位於 imports.go,第一個參數是存儲類型,第二個參數存儲的磁盤路徑,第三個 ⌘ Read more
cayley 可以使用多種後端存儲,那麼如何使用 mysql 作爲後端存儲呢,首先我們看下如何配置: store: # backend to use backend: mysql # address or path for the database address: "root:@tcp(localhost:3306)/cayley?loc=Local&charset=u ⌘ Read more
close channel 設計理念------------------func closechan(c hchan) { // 關閉一個 nil channel, 拋出 panic if c == nil { panic(plainError("close of nil channel")) }}爲什麼關閉一個已經關閉的 channel 會 panic ?官方這樣設計的初衷, ⌘ Read more
文件類型識別是在很多應用場景中都需要用到的功能,比如在 Web 開發中,我們需要根據上傳文件的類型來進行不同的處理,或者在文件管理系統中,我們需要根據文件類型來顯示不同的圖標和操作。文件類型識別的常用方法有兩種:一種是根據文件的擴展名來判斷,比如 .jpg 表示 JPEG 圖像,.mp3 表示 MP3 音頻等;另一種是根據文件內容的特徵來判斷,比如 JPEG 圖像的前幾個字節是 FF D8 FF, ⌘ Read more
爲了方便在 Bucket 內部快速訪問,並按需換頁,boltdb 抽象出了 cursor 方便快速訪問,源碼位於 cursor.go,其定義如下:type Cursor struct { bucket Bucket stack []elemRef}其中 Bucket 指向當前的 Bucket,stack 代表了從 root 到葉子節點深度方向的訪問棧,它的每一個元素代表了 B ⌘ Read more
接收 TCP 連接流程-----------TCP 連接對象type TCPConn struct { conn}type conn struct { fd netFD}Conn 接口Conn 表示通用的面向流的網絡連接。type Conn interface { Read(b []byte) (n int, err error) Write(b []byte) (n int, err err ⌘ Read more
在 Go 1.21 中, 增加了和 sync.Once 有關的三個函數。sync.Once 本身實現就非常簡單了,新增加的這三個函數到底是幹啥的?讓我們一起來看看。sync.Once---------我們常常使用 sync.Once 實現單例模式,它也非常的高效。下面的代碼是官方的一個例子,運行它可以看到onceBody函數只會被執行一次:package mainimport ( "fmt" "s ⌘ Read more
最近有讀者留言說,平時在寫代碼的過程中,是會對字符串進行修改的,但網上都說 Go 語言字符串是不可變的,這是爲什麼呢?這個問題本身並不困難,但對於新手來說確實容易產生困惑,今天就來回答一下。首先來看看它的底層結構:type stringStruct struct { str unsafe.Pointer len int}和切片的結構很像,只不過少了一個表示容量的 cap 字段。str: ⌘ Read more
在分析瞭如何編譯啓動 cayley 圖數據庫,並使用它自帶的 Gizmo 工具來進行查詢後,我們來看看使用客戶端如何進行查詢。 首先使用官方的 github.com/cayleygraph/go-client,但是它聲明的 go.mod 文件有問題,修改調整後,使用如下: package mainimport ( "context" "fmt" //clien ⌘ Read more
概述--下面是一個基礎的服務器網絡程序,主要包含如下功能:監聽 TCP 連接,綁定 8888 端口 收到新的客戶端連接後,啓動一個新的 goroutine 進行處理 收到客戶端的數據後,不做任何處理,原樣返回 package mainimport ( "log" "net")func main() { // 初始化監聽 listener, err := net.ListenTCP ⌘ Read more=
在分析完核心數據結構後,我們結合使用 boltdb 的核心過程瞭解下上述數據結構建立的過程,總結下來核心過程如下: bolt.Opendb.Updatedb.Begintx.CreateBuckettx.Bucketb.Getb.Puttx.Commit在 db.go 中我們可以瞭解到 Update 函數其實也是調用了 Begin 來開啓一個事務的。事務執行成功就提交,失敗則回 ⌘ Read more
通過前面源碼分析,我們差不多瞭解了 boltdb 的核心數據結構了,邏輯視圖上是通過 Bucket 組建的嵌套結構來管理數據的,每一層都可以存儲一一系列 key 和 value,也是使用 boltdb 的用戶需要關注的。物理視圖上是通過 node 來定義 B + 樹來管理磁盤頁的。下面我們詳細分析下它們在內存以及磁盤上 存儲結構。 先從磁盤上的存儲結構開始,每一個 b ⌘ Read more
大家好,我是漁夫子。今天給大家推薦一個基於redis實現的簡單、可靠且高效的分佈式任務隊列:asynq。該隊列出自谷歌員工 Ken Hibino。項目的開源地址:https://github.com/hibiken/asynq ,星標 star 6.1k,目前有 29 位貢獻者。asynq 的架構設計-----------基於 redis 的集羣,支持哨兵模式。因此具備了存儲可橫向擴展及高可用性。 ⌘ Read more
可用的空閒頁號信息存儲在 freelist 中,具體位於 freelist.go 文件中,定義如下:// freelist represents a list of all pages that are available for allocation.// It also tracks pages that have been freed but are still in use ⌘ Read more
概述--Go 語言內置 GC,因此一般不會內存泄漏,但是 goroutine 可能會發生泄漏,泄漏的 goroutine 引用的內存同樣無法被 GC 正常回收。常見泄漏場景------下面總結一下開發中經常遇到的 goroutine 泄漏場景,本文示例代碼只是爲了演示,沒有任何現實意義。通道爲 nil在 nil 通道 上發送和接收操作將永久阻塞,會造成 goroutine 泄漏。 最佳實踐: ⌘ Read more
https://github.com/cayleygraph/cayley 是 go 實現的一個圖數據庫,它支持多種後端存儲,包括 mysql,boltdb 甚至是 elasticsearch。下面我們先學習下如何使用它。 首先下載源碼並下載依賴的靜態文件,然後編譯。 clone projectgit clone https://github.com/cayleyg ⌘ Read more
大家好,我是漁夫子。今天在知乎上看到這樣一個問題:Golang 的 IO 庫那麼多,我該怎麼選。今天就跟大家聊聊這個問題。首先,我們要知道,golang 中有哪些 IO 包。我整理了一下,大概有 io 包、bufio 包、ioutil、os、net 等。其次,要知道這些 io 包的各自的定位。我整理了一張圖供大家參考:我們大致講解下上圖:io:基礎的 IO 庫,提供了 Reader 和 Write ⌘ Read more
1.sync.Mutex 和 sync.RWMutex要知道,mutex(互斥)對於我們 gopher 來說就像一個老夥計。在處理 goroutine 時,確保它們不會同時訪問資源是非常重要的,而 mutex 可以幫助我們做到這一點。sync.Mutex----------看看這個簡單的例子,我沒有使用互斥鎖來保護我們的變量 a:var a = 0func Add() { a++}func ma ⌘ Read more=
介紹完 github.com/golang/groupcache 如何使用和基本原理後,我們來分析下它的源碼。初始化的代碼位於 groupcache.gofunc NewGroup(name string, cacheBytes int64, getter Getter) Group { return newGroup(name, cacheBytes, getter, nil)}func ne ⌘ Read more
github.com/golang/groupcache 存儲的是 kv 結構,同是 memcache 作者出品. 在放棄 update/delete 的特性後,換來的是:Cluster 的能力,處理熱點的能力。 因爲 groupcache 只能 get,不能 update 和 delete,也不能設置過期時間,只能通過 lru 淘汰最近最少訪問的數據;有些數據如果長 ⌘ Read more
今天給大家推薦一個隊列庫:adrianbrad/queue。該庫實現了多種類型的隊列,包括阻塞隊列、環形隊列、優先級隊列。同時還支持泛型。 該庫是 2022 年才提交的,由於比較新的原因,所以星標也只有 102 個 star。但星標不是衡量該庫唯一的標準。下面我們來看下該庫的具體功能。阻塞隊列首先,該庫實現了阻塞隊列。所謂阻塞隊列的特點就是阻塞。阻塞發生在以下兩個地方:消費者阻塞當消費者從隊列中 ⌘ Read more
概述--Go 語言中的計時器常用於定期執行某個操作或者在指定時間內執行某個操作,主要通過標準庫的 time 包中的相關方法來實現,如 time.After(), time.Tick() 等。 相信讀者已經可以熟練掌握應用層面,本文主要分析計時器功能的內部代碼實現。K 叉堆----在正式分析源代碼之前,我們首先簡單瞭解下 K 叉堆 這種數據結構。 K 叉堆(k-ary heap)是一種基於二叉樹 ⌘ Read more
閱讀本文大概需要 4 分鐘。雖然官方有 xml 處理的庫,但比較簡單。今天介紹一個基於官方 xml 庫的增強庫:etree https://github.com/beevik/etree,它是一個輕量級的純 Go 包,它可以用於以元素樹的形式表示 XML 文檔。它的設計受到了 Python ElementTree 模塊的啓發。etree 的特點---------支持導入、序列化、修改或從頭創建 X ⌘ Read more
大家好,這裏是每週都在陪你一起進步的網管~!今天繼續學習設計模式,也是我們要學習的最後一個設計模式—中介者模式,對這個模式有一點了解後會覺得它跟我們已經學過的觀察者模式挺像,但是兩者還是有些區別的,使用場景也不一樣,具體我們放在最後再講,先來一起學習中介者模式。中介者模式是一種行爲設計模式, 能讓程序減少對象之間混亂無序的依賴關係。 該模式會限制對象之間的直接交互, 迫使它們通過一箇中介者對象進行 ⌘ Read more
大家好,我是漁夫子。今天跟大家聊聊 redis 實現的分佈式鎖時需要注意的問題。之前給大家推薦過一個 golang 版本的 redis 的分佈式鎖是redsync,該包也是 redis 官網推薦使用的。有讀者給我留言說 爲什麼不能直接使用 redis 的setnx命令就行,非要用這麼一個包呢?今天我們就深入剖析一下redsync包的實現,看看除了setnx命令外,還做了哪些必要的工作。redsyn ⌘ Read more
給大家分享一個阻止 Go 程序退出的方法集合,其中還是有一些腦洞大開的方法。你有什麼別的方法可以阻止 Go 程序退出麼, 歡迎在留言區留言。像下面這樣的程序,程序一運行就是退出了,原因在於主 goroutine 執行完了,子 goroutine 雖然存在,但是沒能阻止主 goroutine 的執行:package mainimport "net/http"func main() { go http ⌘ Read more
在瞭解完 boltDB 如何使用後,我們開始詳細分析 boltdb 的源碼,我們從創建實例函數 bolt.Open 開始,它的源碼位於 db.go,它的第一個參數是文件名稱,第二個參數是權限信息,第三個參數是創建數據庫實例的可選參數,具體定義如下: // Options represents the options that can be set when opening a d ⌘ Read more
boltdb 是 golang 實現的一個基於 b + 樹的存儲系統,通過 mvcc 實現了單個寫事務和多個讀事務併發。結構也很清晰,由於比較穩定,已經歸檔,確實是學習數據庫的最佳選擇。而且不少出名的開源項目在使用它,比如 etcd,InfluxDB 等。下面我們先通過例子分析下它是如何使用的,後面再從源碼的角度來分析下它的具體實現原理。 boltdb 是通過內存映射 ⌘ Read more
背景提要分享一個 GC 相關的踩坑實踐。公司線上某組件內存資源泄漏,偶發 oom 。通過 Go 的 pprof 排查,很快速定位到泄漏的數據結構 A ,結構 A 的相關資源是通過 Go 的 Finalizer 機制來釋放的。但詭異的來了,對照着代碼審視了多次之後,大家一致斷定,這段代碼絕對沒有泄漏的問題。但是,事實勝於雄辯,現實就是泄漏就在此處。想不通。。。幾天之後,問題的轉機來自於另一個毫不相 ⌘ Read more
概述--下面表格中的內容是 Go 語言中 channel 數據類型的使用規則,相信讀者已經可以熟練掌握,本文主要分析 channel 的內部實現中的數據結構和算法,所以相關的基礎概念會直接跳過, 希望讀者閱讀完本文後,可以深入理解表格中的各類規則,從應用層代碼到底層實現,能夠知其然並知其所以然。操作規則\\| 操作 \\| nil \\| 已關閉的 channel \\| 未關閉有緩衝區的 channel \\| 未 ⌘ Read more
指針是 Go 編程語言的重要組成部分。它們提供了一種直接引用和操作內存中數據的方法,這在某些情況下非常有用。但是,指針也很難正確使用,錯誤使用導致錯誤和內存泄漏。在這篇文章中,我們將探討一些技巧和技巧,以掌握 GoLang 中的指針並編寫高效的代碼。Go 語言中的指針是什麼?-------------Go 語言中的指針是一個變量,它存儲另一個變量的內存地址。這允許您直接訪問和修改該內存位置的變量值 ⌘ Read more
Go 語言中的 map 是一種非常強大的數據結構,它允許我們快速地存儲和檢索鍵值對。然而,當我們遍歷 map 時,會有一個有趣的現象,那就是輸出的鍵值對順序是不確定的。現象--先看一段代碼示例:package mainimport "fmt"func main() { m := map[string]int{ "apple": 1, "banana": 2, ⌘ Read more=
@注: 以下內容來自【Go 語言底層原理剖析、Go 語言設計與實現】兩書中的摘要信息,一起讀書、一起學習。介紹-----Go語言中的map又被稱爲哈希表,是使用頻率極高的一種數據結構。哈希表的原理是將多個鍵/值(key/value)對, 分散存儲在buckets(桶)中。通常map的時間複雜度爲O(1), 通過一個鍵快速尋找其唯一對應的值value。在許多情況下,哈希表的查找速度明顯快於一些搜 ⌘ Read more*
介紹-----隨着哈希表中元素的逐漸增加,哈希的性能會逐漸惡化,所以我們需要更多的桶和更大的內存保證哈希的讀寫性能。怎麼觸發-------在每次對哈希表賦值時,都會調用runtime.mapassign 函數,該函數每次都會判斷是否需要擴容,主要有兩個函數:overLoadFactory和tooManyOverflowBuckets:// hash[k]=x表達式,會在編譯期間轉換成runtime ⌘ Read more*
@注: 以下內容來自《Go 語言底層原理剖析》、《Go 語言設計與實現》書中的摘要信息,本人使用版本 (Go1.18) 與書中不一致,源碼路徑可能會有出入。介紹-----defer是Go語言中的關鍵字,也是Go語言的重要特性之一。defer的語法形式爲defer 函數,其後必須緊跟一個函數調用或者方法調用。在很多時候,defer後的函數以匿名函數或閉包的形式呈現,例如:defer func(. ⌘ Read more
go test 加參數 -json 就能輸出 json 格式,下面我們用一個簡單的例子看下對他進行分析,然後分析下相關源碼。對於單測package testimport ( "fmt" "testing")func TestAdd(t testing.T) { type args struct { a int b int } tests := []struc ⌘ Read more=
今天給大家推薦的是基於 redis 的 Go 版本的分佈式鎖工具:redsync。該工具也是 redis 官網上推薦的。redsync 包具有高性能、高可用、防死鎖、防誤刪的特點。小檔案---\\| redsync 小檔案 \\|\\| --- \\|\\| star \\| 2k \\| used by \\| 276 \\|\\| contributors \\| 21 \\| 工具分類 \\| 分佈式鎖 \\|\\| 功能簡介 \\| 基於 redis ⌘ Read more
這是 Go 應用程序項目的基本佈局。它不是核心 Go 開發團隊定義的官方標準;然而,它是 Go 生態系統中一組常見的老項目和新項目的佈局模式。其中一些模式比其他模式更受歡迎。它還具有許多小的增強,以及對任何足夠大的實際應用程序通用的幾個支持目錄。如果你嘗試學習 Go,或者你正在爲自己建立一個 PoC 或一個玩具項目,這個項目佈局是沒啥必要的。從一些非常簡單的事情開始 (一個 main.go 文件綽 ⌘ Read more
在瞭解 Golang 的網絡 IO 模型的具體實現之前,可以先了解一下 Linux 的幾種經典網絡模型Linux 經典網絡模型阻塞式 IO(BIO)應用進程從發起 IO 系統調用一直到返回結果,整個期間都是處於阻塞狀態,當前線程被掛起非阻塞式 IO(NIO)Socket 可以設置爲非阻塞,這樣應用進程可發起 IO 系統調用後可以立刻返回。輪詢發起的 IO 系統調用直到返回結束標識,需要應用進程不停 ⌘ Read more
01 Go 中文件的普通寫入方式在 Go 中,普通的寫入方式是將內容通過 io.Writer 直接寫入到目標文件中。如下圖: 下面是普通的讀取文件內容的示例代碼:package mainimport ( "fmt" "os")func main() { filename := "./test.txt" //以讀寫模式打開文件 fd, := os.OpenFile( ⌘ Read more
概述--sync.Map 提供了併發安全的 map 操作,數據結構語義類似 map[any]any,多個 goroutine 併發操作時無需加鎖。官方的建議是大多數情況下,應該使用普通 map 類型,並完成對應的鎖和併發控制以保證安全性,這樣可以使類型擁有更好的安全性和可維護性。sync.Map 類型是針對兩種特殊的場景進行優化的:當指定的 key 只被寫入一次,但是被讀取多次,例如不斷增長的緩存 ⌘ Read more
大家好,我是漁夫子。本文我們介紹下 recover 在 gin 框架中的應用。首先,在 golang 中,如果在子協程中遇到了 panic,那麼主協程也會被終止。如下:package mainimport ( "github.com/gin-gonic/gin")func main() { r := gin.Default() // 在子協程中引起panic,主協程也會退出 go func( ⌘ Read more=
概述\\-\\- fasthttp 是一個使用 Go 語言開發的 HTTP 包,主打高性能,針對 HTTP 請求響應流程中的 hot path 代碼進行了優化,達到零內存分配,性能比標準庫的 net/http 快 10 倍。上面是來自官方 Github 主頁的項目介紹,拋開其介紹內容不談,光從名字本身來看,作者對項目代碼的自信程度可見一斑。本文不會講解 fasthttp 的應用方法,而是會重點分析 fa ⌘ Read more
大家好,我是漁夫子。今天給大家推薦一個 Go 的開源包:mimetype,一個快速的檢測媒體類型和文件類型的包,共支持 172 種 MIME 類型。例如,檢測是否是 Content-Type 是否 json 格式還是 text/plain 格式,亦或者是 text/html、xml 等。該包星標 1.1k,有 51 個貢獻者,4.1k 的開源包在使用。項目地址:https://github.com ⌘ Read more
概述--context.Context 類型表示上下文信息,作用是在 API 通信、進程通信、函數調用之間傳遞超時時間、取消信號和其他數據值。規則--使用 context.Context 時應遵循以下規則,以保證不同包之間的接口一致性,並啓用靜態分析工具來檢查上下文的鏈路傳播和可能產生的數據競態。不要將 context.Context 嵌入結構體類型,應該明確地將其作爲函數參數傳遞,並且應該是第一 ⌘ Read more
Go 語言中的 map 是一個非常常用的數據結構,它允許我們快速地存儲和檢索鍵值對。然而,在併發場景下使用 map 時,還是有一些問題需要注意的。本文將探討 Go 語言中的 map 是否是併發安全的,並提供三種方案來解決併發問題。先來回答一下題目的問題,答案就是併發不安全。看一段代碼示例,當兩個 goroutine 同時對同一個 map 進行寫操作時,會發生什麼?package mainimpor ⌘ Read more
大家好,我是漁夫子。今天,跟大家聊聊 gin 框架中是如何實現分片輸出的。主要分以下 4 點:分片輸出的效果圖 gin 實現分片傳輸代碼 http 分片傳輸的基礎:transfer-encoding gin 實現分片傳輸原理 效果圖---首先看下分片輸出的效果圖:gin 分片傳輸實現代碼------------上面的效果圖中,網頁中的內容不斷的輸出。在 gin 中是主要是利 ⌘ Read more
我們使用 Go 標準庫中的net包,很容易發送 UDP 和 TCP 的 packet,以及在它們基礎上開發應用層的程序,比如 HTTP、RPC 等框架和程序,甚至我們可以利用官方擴展包golang.oef/x/net/icmp, 專門進行 icmp packet 的發送和接收,不過,有時候我們想進行更低層次的網絡通訊,這個時候我們就需要藉助一些額外的庫,或者做一些額外的設置,當前相關的介紹 IP ⌘ Read more
大家好,這裏是每週都在陪你一起進步的網管~!今天繼續學習設計模式—解釋器模式解釋器模式是一種行爲設計模式,可以用來在程序裏創建針對一個特點領域語言的解釋器,用於處理解釋領域語言中的語句。換句話說,該模式定義了領域語言的抽象語法樹以及用示來解釋語法樹的解釋器。模式使用場景------解釋器模式,用於解決需要解釋語言中的句子或表達式的問題。以下是一些可以在 程序中使用解釋器模式的真實場景:處理配置文件 ⌘ Read more
Go 錯誤處理簡要回顧--------------Go 是一種非常強調錯誤處理的編程語言。在 Go 中,錯誤被表示爲實現了 error 接口的類型的值,error 接口只有一個方法:type error interface { Error() string}這個接口的引入使得 Go 程序可以以一致和符合慣用法的方式進行錯誤處理。在所有編程語言中,錯誤處理的挑戰之一都是能提供足夠的錯誤上下文信息,以 ⌘ Read more
今天帶大家來一段代碼的變換之旅,代碼篇幅較多,主要參考自one-way-to-do-it-six-variations,在這裏加了一些自己的理解。 文章: https://phlatphrog.medium.com/one-way-to-do-it-six-variations-cd58602ac06d代碼倉庫: https://github.com/pdk/oneway我們先來模擬一段開車去商 ⌘ Read more
前言--前兩天看了一篇文章 GOMAXPROCS 與容器的相處之道 [1],裏面提到了 Go 標準庫中 runtime.GOMAXPROCS 方法的問題: 因爲系統調用 schedgetaffinity 並不感知它對進程的限制,所以運行在 Kubernetes 中的 Go 程序的運行時始終會認爲自己可以使用宿主機上的所有 CPU,進而創建了相同數量的 P (處理器), 而當 GOMAXPROCS ⌘ Read more
Go 語言中的模板(Template)是一個強大的工具,它可以讓開發者在生成 HTML、XML、Markdown 等文本格式時,更加簡單高效。Go 的模板語言在設計上非常簡潔,但是在功能上非常強大,它支持基本的控制流、條件語句、變量、函數等,同時還可以通過自定義函數和自定義類型等方式擴展其功能。在本文中,我們將深入學習 Go 語言中的模板,探討其常用功能。Go 語言中的模板(Template)是一 ⌘ Read more
網絡上寫testing的文章浩如雲煙,有初學者Hello World級別的玩具,也有大佬乾貨滿滿的實踐。不跟那個風(其實是寫得太水了有失逼格,寫得太高深了力有不逮,團隊沒有測試的傳統)。換個角度來學習一下testing領域巧妙的設計,開闊眼界是爲了舉一反三,所謂技多不壓身。按照慣例,從一個問題開始:問題testing和unsafe不一樣:unsafe所有的語義和實現都由編譯器負責解釋,本身只是作爲 ⌘ Read more
作者: 金刀大菜牙 https://juejin.cn/post/7228071726206353465在 Go 語言中,Context 包是一種非常常用的工具,它被用來管理 goroutine 之間的通信和取消。本文將深入探討 Context 包的基本原理,包括使用場景、原理和一些最佳實踐。基本原理-------1.1 Context 包的介紹在 Go 語言中,Context 包是用於 ⌘ Read more
前言--在 Golang 中,接收器是一種特殊的參數類型,它可以讓我們在函數中訪問結構體的屬性和方法。接收器的使用非常靈活,可以用於定義方法、實現接口、擴展類型等多種場景。本文將介紹 Golang 中接收器的基礎知識和使用技巧。接收器的定義------接收器是一個函數參數,它出現在函數名之前,用於指定函數的調用者。接收器可以是值類型或指針類型,它決定了函數對結構體的訪問方式。下面是一個接收器的定義 ⌘ Read more
隨着軟件開發行業的發展,Golang 和 Java 成爲了兩個非常流行的編程語言。它們都是強類型語言,都支持面向對象編程,並且都具有良好的接口編程支持。在這篇技術博客中,我們將探討 Golang 和 Java 接口編程的異同,以幫助那些已經掌握其中一門語言,希望學習另外一門語言的人員。一、Golang 與 Java 接口編程的異同1. 定義方式在 Golang 中,接口由一組方法簽名定義,不需要顯 ⌘ Read more
信號量 是一個同步對象,用於保持在 0 至指定最大值之間的一個計數值。當線程完成一次對該 semaphore 對象的等待(wait)時,該計數值減一;當線程完成一次對 semaphore 對象的釋放(release)時,計數值加一。當計數值爲 0,則線程等待該 semaphore 對象不再能成功直至該 semaphore 對象變成 signaled 狀態。semaphore 對象的計數值大於 0, ⌘ Read more
概述--sync.Cond 實現了一種條件變量同步原語,可以讓一個 goroutine 集合在滿足特定條件時被喚醒。sync.Cond 典型的使用場景是 生產-消費者模式,多個 goroutine 等待某個事件發生, 單個 goroutine 通知某個事件已發生。比如電商中的用戶下單事件發生時,會通知到訂單、用戶、積分、優惠券、倉儲等服務,如果是單個生產者對單個消費者,直接使用 互斥鎖 或 cha ⌘ Read more
概述\\-\\- 在計算機學中,反射 (reflection) 是指計算機程序在運行時 (runtime) 可以訪問、檢測和修改它本身的狀態或行爲的一種能力。簡單來說,反射就是程序在運行的時候能夠觀察並且修改自己的行爲。常見場景----Go 中 反射 常見的使用場景有 元數據編程,確認接口實現機制。元數據編程通過 反射 獲取字段標籤,實現簡單的元數據編程,比如 ORM 框架中的 Model 屬性。pac ⌘ Read more
概述\\-\\- 鎖是一種常見的同步機制,用來解決多個線程同時訪問共享資源導致的數據競爭問題。在高併發場景下,鎖的使用可能會成爲性能瓶頸,因爲線程需要頻繁地加鎖和釋放鎖,這會增加上下文切換開銷並降低程序的吞吐量。 無鎖編程(lock-free programming)是一種併發編程技術,主要用於消除多線程編程中鎖操作帶來的性能損耗。如果對一個共享的數據結構的所有操作都不需要加鎖 (這裏的操作一般指讀寫 ⌘ Read more
break 語句通常用來終止一個循環,當循環語句帶有 switch 或 select 語句時,使用 break 語句要特別小心,否則會產生 bug。下面通過一個具體的例子說明,這段程序在循環內部通過 switch 判斷 i 的值,如果 i 的值爲 2,期望通過 break 終止循環。for i := 0; i < 5; i++ { fmt.Printf("%d ", i) switc ⌘ Read more=
在使用 Go 實現 ping 工具 [1] 那一篇文章中,我們自己實現了 ping 工具的基本功能,我們也瞭解了 ping 底層實現的原理。讀者 @ZerOne 提出一個問題:能不能實現單向跟蹤路由的功能,類似 ping -R一樣,從 A 端 tracert B 端,同時顯示 B 端到 A 端的路徑?Record Route 背景知識-----------------我先前沒有用過 ping 的- ⌘ Read more
快速排序是由東尼 · 霍爾所發明的一種排序算法,時間複雜度是 O(nlogn), 是不穩定排序算法。快速排序使用分治思想,通過一趟排序將要排序的數據分割成獨立的兩部分,其中一部分的所有數據都比另外一部分的所有數據都要小,然後再按此方法對這兩部分數據分別進行快速排序,整個排序過程可以遞歸進行,以此達到整個數據變成有序序列。算法演示----通過動圖來演示一下這個算法的執行過程: 從數列中挑出一個元素 ⌘ Read more
大家好,我是 frank。 歡迎大家點擊標題下方藍色文字「Golang 語言開發棧」關注公衆號。 設爲星標,第一時間接收推送文章。 文末掃碼,加羣一起學 Golang 語言。01 介紹Go 協程之間通過 channel 通信,但是 channel 讀寫取決於自身特性,即是否有可寫入緩衝區、緩衝區中是否有數據、是否已關閉...爲了檢測 channel 的特性,Go 提供了一個關 ⌘ Read more
0 前言未來兩週,想和大家探討的主題是 Golang 內存管理機制.本系列會分爲兩篇,第一篇談及 Golang 內存模型以及內存分配機制,第二篇會和大家討論 Golang 的垃圾回收機制. 本文是其中第一篇.我個人比較推崇” 基於源碼支撐原理 “的信念,所以本文在闡述原理的基礎上,會伴有大量源碼走讀的過程,作爲理論的支撐論證. 走讀的 Go 源碼版本爲 1.19.內存管理與垃圾回收都屬 Go 語言 ⌘ Read more
0 前言幾個月前和大家分享過一篇——Golang 單機鎖實現原理,恰逢最近在研究 etcd 的 watch 機制,這是一項可以應用於實現分佈式鎖的核心能力,於是擇日不日撞日,接下來就和大家一起來聊聊單機鎖的升級版本——Golang 分佈式鎖技術攻略介紹本文內容分爲兩部分:第一部分聊聊如何通過 redis 實現主動輪詢模型下的分佈式鎖;第二部分和大家一起探討如何使用 etcd 實現 watch 回調 ⌘ Read more
獨特的 “非侵入式” 接口設計是 Go 語言的一亮點。接口使得 Go 這種靜態型語言有了動態型語言的特性,提供了非常大的靈活性。Go 語言的成功,接口功不可沒。Golang 與 "鴨子類型" 的關係------------------- Ducking Typing , 鴨子類型,是動態編程語言的一種對象推斷策略,它主要關注於對象如何被使用,而不是對象類型的本身。Go 語言作爲一門靜態語言, ⌘ Read more
概述\\-\\- 在計算機科學中,關聯數組 (Associative Array),又稱映射 (Map)、字典 (Dictionary) 是一個抽象的數據結構,它包含着類似於(鍵,值)的有序對。從應用的角度來看,Go 語言的 map 數據結構主要有以下常見問題:未初始化寫入時報錯 遍歷時無序 非併發安全 本文通過分析標準庫中 map 的內部實現,嘗試解答上面的問題。內部實現----ma ⌘ Read more