網站首頁 編程語言 正文
sync包
常用的有3個功能
鎖
鎖分為普通互斥鎖和讀寫鎖
互斥鎖 Mutex | 讀寫鎖 RWMutex |
---|---|
一個線程未釋放鎖時,其他線程加鎖阻塞 | 讀鎖:一個線程未釋放讀鎖時,其他線程可獲取讀鎖,獲取寫鎖阻塞 寫鎖:一個線程未釋放寫鎖時,其他線程可獲取讀鎖或寫鎖都會阻塞 |
線程監聽WaitGroup
使用場景:用于監聽一組子線程是否執行完畢
使用流程 | 代碼 |
---|---|
建立監聽對象 | wg := new(sync.WaitGroup) |
創建多個子線程并計入計數器 | go func1(wg) wg.Add(1) go func2(wg) wg.Add(1) |
線程子線程執行完畢后,減少計數器值 | func1(wg){wg.Done()} |
監聽計數器值,直到計數器值為0時,執行后面的代碼 | wg.Wait() |
池Pool
用于存放每次請求都需要實例化,且生命周期較長的對象,以減輕垃圾回收壓力。
使用流程 | 代碼 |
---|---|
建立一個池 | RequestPool = sync.Pool{New: func() interface{} {return &RequestHeader{}}} |
從池中取一個對象 | RequestPool .Get() |
把對象放回池中 | RequestPool .Put(RequestHeader) 把對象放入池之前,需要把對象中所有值都初始化 |
encoding/binary包
主要用來把數字轉換為字節類型
單數值轉換
//序列化 var dataA uint64=6010 var buffer bytes.Buffer err1 := binary.Write(&buffer, binary.BigEndian, &dataA) if err1!=nil{ log.Panic(err1) } byteA:=buffer.Bytes() fmt.Println("序列化后:",byteA) //反序列化 var dataB uint64 var byteB []byte=byteA err2:=binary.Read(bytes.NewReader(byteB),binary.BigEndian,&dataB) if err2!=nil{ log.Panic(err2) } fmt.Println("反序列化后:",dataB)
其中的BigEndian和LittleEndian 指定了轉換的方式是 大端字節序,還是小端字節序。
所謂大端和小端節序,是指不同cpu再把數據流轉換為字節時,排位位置的不同,如下
若不同計算機程序之間使用了不同節序處理同一組數據,就會造成無法解析的情況
多數值轉換
指把多個數字轉換到一個byte切片中
首先定義一個定長切片 s := make([]byte,10)
首先要確定轉換的節序,也可以跳過該步驟
binary.LittleEndian.PutUint16(s, uint16(0))
確定完之后,就可以向s中插入數字了
start := 0 start += binary.PutUvarint(b[2:], 1198)
插入數字到切片后,會返回該數字在切片中占用的長度
若切片空間不夠,則返報錯
所以我們最好確定往切片中插入數字的個數,并估算每個數字占用最大占用長度
解析切片中的某個數字,要知道該數字在切片中占用的起始位置,若位置不對則無法解析出正確的數字,返回0
i,err := binary.ReadUvarint(bytes.NewReader(b[2:])) if err==nil{ fmt.Println(i) }else{ fmt.Println(err.Error()) }
切片中可以插入字符串,轉換為數字時,只要能夠從正確的位置開始解析,就會解析出正確的數字
encoding/gob包
是一個golang專屬的數據序列化工具,用于序列化和反序列化數據,作用類似于json
不同的是,在反序列化時,需要有一個指定格式的變量接收值。該變量類型需要與序列化時數據類型兼容,否則反序列化失敗
type S struct{ Field1 string Field2 int } func main() { s1 := &S{ Field1: "Hello Gob", Field2: 999, } log.Println("Original value:", s1) buf := new(bytes.Buffer) err := gob.NewEncoder(buf).Encode(s1) if err != nil { log.Println("Encode:", err) return } s2 := &S{} err = gob.NewDecoder(buf).Decode(s2) if err != nil { log.Println("Decode:", err) return } log.Println("Decoded value:", s2) }
簡單的數據可以使用上面代碼直接加密和解密
但是當需要解密的數據是接口類型時,由于接口的特殊性,實現了接口中方法的變量可以作為值代替該方法,這導致gob不知道接口中數據的具體類型,會解密失敗,如下
type Getter interface { Get() string } type Foo struct { Bar string } func (f Foo)Get() string { return f.Bar } buf := bytes.NewBuffer(nil) // 創建一個接口變量 //接口中原值是一個get方法,因為Foo實現了get方法,所以可以最為值代替Get g := Getter(Foo{"wazzup"}) // gob解密g時,認為g中的值是Get() 類型,但其實是Foo類型,就會報錯 enc := gob.NewEncoder(buf) enc.Encode(&g)
解決這個問題的方法就是在代碼初始化時,使用 gob.Register()方法注冊Foo變量
當gob解碼是發現類型不對應,會從已注冊的類型中查找
hash/crc32包
常用方法:
func ChecksumIEEE(data []byte) uint32
返回數據data使用IEEE多項式計算出的CRC-32校驗和
可通過對比數據發送和接收時的校驗和,驗證數據是否被篡改
原文鏈接:https://blog.csdn.net/u012830303/article/details/126485652
相關推薦
- 2022-03-26 在ASP.Net?Core應用程序中使用Bootstrap4_實用技巧
- 2022-09-08 pytorch關于Tensor的數據類型說明_python
- 2022-05-18 python中leastsq函數的使用方法_python
- 2022-05-09 shell腳本編程Makefile的使用_linux shell
- 2022-11-21 Golang?Mutex互斥鎖源碼分析_Golang
- 2022-08-24 .net新興日志框架Serilog簡介_實用技巧
- 2022-08-04 GoFrame框架gcache的緩存控制淘汰策略實踐示例_Golang
- 2023-07-05 parcel運行終端報錯Uncaught ReferenceError: parcelRequire
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支