為什么golang在并發環境下更有優勢
Go語言(Golang)在并發環境下的優勢主要源自其設計哲學和內置的并發機制,這些機制在語言層面提供了高效、簡潔且安全的并發編程工具。以下是其核心優勢的詳細分析:
1. Goroutine:輕量級并發單元
- 輕量級:Golang的
goroutine
是用戶級線程(協程),啟動時僅需 2KB 的棧內存(動態擴展),而傳統線程通常需要 1MB+。這使得程序可以輕松創建成千上萬個并發任務,而不會因資源耗盡導致崩潰。 - 低啟動開銷:創建和銷毀
goroutine
的代價極低(納秒級),無需依賴操作系統的線程管理,適合高頻短任務的場景(如處理HTTP請求)。 - 自動調度:Go運行時(runtime)通過調度器自動管理
goroutine
的生命周期,開發者無需手動管理線程池。
2. GMP 調度模型:高效的并發調度
Go的調度器采用 M:N 模型(多對多調度),將大量goroutine
映射到少量操作系統線程(OS Thread)上,核心組件包括:
- G(Goroutine):并發任務單元。
- M(Machine):操作系統線程,由內核調度。
- P(Processor):邏輯處理器,管理本地
goroutine
隊列(每個P綁定一個M)。
優勢:
- 工作竊取(Work Stealing):空閑的P會從其他P的隊列中“竊取”
goroutine
,實現負載均衡。 - 非阻塞系統調用:當
goroutine
觸發系統調用(如I/O)時,調度器會將M與P解綁,避免線程阻塞,并立即分配新的M執行其他任務。 - 用戶態調度:減少內核態與用戶態的切換開銷,上下文切換成本低于線程。
3. Channel:基于通信的并發同步
Golang通過 CSP(Communicating Sequential Processes)模型,提倡“通過通信共享內存,而非通過共享內存通信”:
- Channel(通道):類型安全的管道,用于
goroutine
間的數據傳輸和同步。- 避免顯式鎖(如
Mutex
),減少競態條件和死鎖風險。 - 支持阻塞式同步(如無緩沖Channel)或異步緩沖(有緩沖Channel)。
- 避免顯式鎖(如
- Select 多路復用:通過
select
語句監聽多個Channel,簡化事件驅動編程。
示例:
ch := make(chan int)
go func() {result := compute()ch <- result // 發送結果到Channel
}()
value := <-ch // 等待并接收結果
對比傳統線程模型
特性 | Golang (Goroutine) | 傳統線程(如Java/Python) |
---|---|---|
內存占用 | 2KB起步,動態擴展 | 1MB+(固定棧) |
創建/銷毀開銷 | 納秒級 | 微秒級 |
調度方式 | 用戶態調度(高效) | 內核態調度(上下文切換慢) |
并發同步機制 | Channel(避免鎖競爭) | 依賴鎖(易死鎖/競態) |
開發復雜度 | 低(語法內建支持) | 高(需手動管理線程池/鎖) |
總結
Go語言的并發優勢源于輕量級Goroutine、高效調度器、Channel通信模型以及標準庫的全方位支持,使得開發者能夠以簡潔的代碼構建高并發、高性能的系統,同時降低傳統并發編程的復雜性。這些特性使Go成為云原生、微服務和實時系統的首選語言。
說一下什么是虛擬地址?如果沒有虛擬地址,只有物理地址可以嗎?
說一下線程間是如何進行通訊
go設計模式有了解過嗎
參考:https://blog.csdn.net/weixin_45565886/article/details/136098371
簡單工廠模式
go 語言沒有構造函數,所以我們一般是通過 NewXXX 函數來初始化相關類。 NewXXX 函數返回接口時就是簡單工廠模式,也就是說 Golang 的一般推薦做法就是簡單工廠。
工廠方法模式
Go 中不存在繼承 所以使用匿名組合來實現
示例步驟:
定義接口type operator interface
參數a
參數b
result:具體業務方法
定義type BaseFactory struct:提供方法,用于設置a、b參數
參數a
參數b
根據不同操作,定義不同工廠類(addFactory、minusFactory)
addFactory實現operator的result:a+b
minusFactory實現operator的result:a-b
addFactory、minusFactory分別提供Create方法
簡單工廠:唯一工廠類,一個產品抽象類,工廠類的創建方法依據入參判斷并創建具體產品對象。
工廠方法:多個工廠類,一個產品抽象類,利用多態創建不同的產品對象,避免了大量的if-else判斷。
抽象工廠:多個工廠類,多個產品抽象類,產品子類分組,同一個工廠實現類創建同組中的不同產品,減少了工廠子類的數量。
package mainimport "fmt"/*
> - 簡單工廠:唯一工廠類,一個產品抽象類,工廠類的創建方法依據入參判斷并創建具體產品對象。
> - 工廠方法:多個工廠類,一個產品抽象類,利用多態創建不同的產品對象,避免了大量的if-else判斷。
> - 抽象工廠:多個工廠類,多個產品抽象類,產品子類分組,同一個工廠實現類創建同組中的不同產品,減少了工廠子類的數量。
*/// Operator 被封裝的實際接口
type Operator interface {SetA(int)SetB(int)Result() int
}// OperatorFactory 是工廠接口
type OperatorFactory interface {Create() Operator
}// OperatorBase 是Operator 接口實現的基類,封裝公用方法
type OperatorBase struct {a, b int
}func (o *OperatorBase) SetA(a int) {o.a = a
}func (o *OperatorBase) SetB(b int) {o.b = b
}// PlusOperatorFactory 加法運算的工廠類
type PlusOperatorFactory struct{}type PlusOperator struct {*OperatorBase
}func (p *PlusOperator) Result() int {return p.a + p.b
}func (p PlusOperatorFactory) Create() Operator {return &PlusOperator{OperatorBase: &OperatorBase{},}
}// MinusOperatorFactory 減法運算的工廠類
type MinusOperatorFactory struct {*OperatorBase
}func (p *MinusOperatorFactory) Result() int {return p.a - p.b
}func (p *MinusOperatorFactory) Create() Operator {return &MinusOperatorFactory{OperatorBase: &OperatorBase{},}
}func main() {//加法plusFactory := PlusOperatorFactory{}plusOperator := plusFactory.Create()plusOperator.SetA(10)plusOperator.SetB(20)result := plusOperator.Result()fmt.Println("plusOperator=", result)//減法minusFactory := MinusOperatorFactory{}minusOperator := minusFactory.Create()minusOperator.SetA(10)minusOperator.SetB(5)result = minusOperator.Result()fmt.Println("minusOperator=", result)
}
創建者模式
將build一個物品拆分為幾個部分
package mainimport "fmt"// Goods 構建的對象
type Goods struct {Name stringPrice float64Count int
}// GoodsBuilder 構建器
type GoodsBuilder interface {SetName(name string) GoodsBuilderSetPrice(price float64) GoodsBuilderSetCount(count int) GoodsBuilderBuild() *Goods
}// ConcreteBuilder 具體構建器
type ConcreteBuilder struct {goods *Goods
}func (g ConcreteBuilder) Build() *Goods {return g.goods
}func (g ConcreteBuilder) SetName(name string) GoodsBuilder {g.goods.Name = namereturn g
}func (g ConcreteBuilder) SetPrice(price float64) GoodsBuilder {g.goods.Price = pricereturn g
}func (g ConcreteBuilder) SetCount(count int) GoodsBuilder {g.goods.Count = countreturn g
}func NewGoodsBuilder() GoodsBuilder {return &ConcreteBuilder{goods: &Goods{},}
}func main() {builder := NewGoodsBuilder()goods := builder.SetName("apple").SetCount(2).SetPrice(65.0).Build()fmt.Println(goods)
}
單例模式
懶漢式:用到時才實例化(GetInstance),通過once.Do保證只加載一次
餓漢式:一開始就實例化(init)
package mainimport ("fmt""sync"
)// 懶漢式:用到才加載【餓漢式:直接放在init方法里,程序一啟動就創建好】
var (instance *Singletononce = sync.Once{}
)type Singleton struct {
}func GetInstance() *Singleton {once.Do(func() {instance = &Singleton{}})return instance
}func main() {one := GetInstance()two := GetInstance()//one=0x100f54088//two=0x100f54088fmt.Printf("one=%p\n", one)fmt.Printf("two=%p\n", two)
}
…
https講一下,如何進行加密的
HTTPS 通過 SSL/TLS 協議對通信數據進行加密,確保數據在傳輸過程中不被竊取或篡改。其核心加密機制結合了對稱加密和非對稱加密,并通過數字證書驗證身份。以下是具體流程:
一、SSL/TLS 握手(建立安全連接)
-
客戶端發起請求
瀏覽器訪問 HTTPS 網站時,發送支持的加密算法列表(如 RSA、ECDHE)和 TLS 版本。 -
服務器響應
服務器選擇加密算法,并返回數字證書(包含公鑰、域名、簽發機構等信息)。 -
證書驗證
- 瀏覽器檢查證書是否由受信任的證書頒發機構(CA)簽發。
- 驗證證書是否過期、域名是否匹配,防止中間人攻擊。
二、密鑰交換(核心加密步驟)
-
非對稱加密傳遞對稱密鑰
- 瀏覽器生成一個隨機數(Pre-master Secret),用證書中的公鑰加密后發送給服務器。
- 服務器用私鑰解密獲取 Pre-master Secret。
-
生成會話密鑰
雙方根據 Pre-master Secret 和握手階段的隨機數,生成相同的對稱密鑰(如 AES 密鑰),后續通信使用此密鑰加密數據。
為什么混合使用兩種加密?
- 非對稱加密(如 RSA)安全性高,但計算慢,適合交換密鑰。
- 對稱加密(如 AES)速度快,適合加密大量數據。
三、加密數據傳輸
- 握手完成后,雙方使用對稱密鑰加密所有通信內容。
- 即使數據被截獲,攻擊者無法解密(沒有密鑰)。
四、關鍵技術支持
-
數字證書
- 由 CA 頒發,證明服務器身份,防止偽造。
- 包含公鑰、域名、有效期等信息,并由 CA 私鑰簽名。
-
加密算法
- 非對稱加密:RSA、ECDHE(密鑰交換)。
- 對稱加密:AES、ChaCha20(數據加密)。
- 散列算法:SHA-256(驗證數據完整性)。
-
完整性校驗
使用 HMAC 或 AEAD 模式,確保數據未被篡改。
五、總結流程
客戶端 → 服務器:發起請求,支持哪些加密算法?
服務器 → 客戶端:返回證書和選定的算法。
客戶端驗證證書 → 生成隨機密鑰用公鑰加密 → 發送給服務器。
服務器用私鑰解密 → 雙方生成對稱密鑰。
后續通信全部使用對稱密鑰加密。
通過以上步驟,HTTPS 實現了:
- 機密性(對稱加密數據)
- 身份認證(數字證書驗證)
- 完整性(散列算法防篡改)
這使得 HTTPS 成為保護隱私(如密碼、支付信息)的核心技術。