前言:Go語言(或稱Golang)是由Google開發(fā)的一種編程語言,具有高效、簡潔和可靠性等特點(diǎn)。它被設(shè)計用于快速構(gòu)建可靠的軟件,支持并發(fā)、垃圾回收和內(nèi)置的并行計算等特性。Go語言擁有豐富的標(biāo)準(zhǔn)庫,同時也有很多第三方庫可以供使用。它適用于開發(fā)各種類型的應(yīng)用程序,包括網(wǎng)絡(luò)服務(wù)器、分布式系統(tǒng)、云服務(wù)以及移動應(yīng)用程序等。
要安裝和配置Golang,您可以按照以下步驟進(jìn)行操作:
1.訪問官方網(wǎng)站:前往Golang的官方網(wǎng)站(https://golang.org/),在主頁上找到適合您操作系統(tǒng)的下載鏈接。
2.下載安裝包:點(diǎn)擊下載鏈接,選擇與您操作系統(tǒng)相對應(yīng)的安裝包,并將其下載到本地計算機(jī)上。
3.安裝Golang:找到您下載的安裝包文件并運(yùn)行。根據(jù)提示,按照默認(rèn)設(shè)置進(jìn)行安裝即可。
4.配置環(huán)境變量:一旦安裝完成,需要配置環(huán)境變量以便在命令行中使用Golang。打開終端或命令提示符窗口,在其中輸入以下內(nèi)容:
在Linux/macOS上:
export PATH=$PATH:/usr/local/go/bin
在Windows上:
setx PATH "%PATH%;C:\Go\bin"
注意:以上路徑是默認(rèn)路徑,請根據(jù)實際情況修改。
5.驗證安裝成功:打開終端或命令提示符窗口,輸入以下命令來驗證是否成功安裝和配置了Golang:
go version
6.如果顯示了Golang的版本信息,則說明安裝和配置成功。已經(jīng)成功安裝和配置了Golang,可以開始使用它來編寫和運(yùn)行Go語言程序了。
常用的配置項:
GO111MODULE
: 是否開啟模塊支持;on-開啟,off-關(guān)閉,auto-自動
GOPROXY
: go包代理地址配置;官方的國內(nèi)訪問有問題
GOGCCFLAGS
: 環(huán)境信息GOGCCFLAGS的值則是Go語言在使用操作系統(tǒng)的默認(rèn)C語言編譯器對C語言代碼進(jìn)行編譯時加入的參數(shù)。
GOPATH
: go的工作空間目錄;我們使用模塊化管理后,下載的包會放在這個文件夾的pkg下面;
GO語言基礎(chǔ)語法包括以下內(nèi)容:
包聲明:每個Go程序都由包組成,通過package
關(guān)鍵字進(jìn)行聲明。常用的包有fmt
、os
、io
等。
導(dǎo)入其他包:使用import
關(guān)鍵字導(dǎo)入需要使用的其他包。
函數(shù)聲明:使用func
關(guān)鍵字定義函數(shù),可以指定參數(shù)和返回值類型。
變量聲明:使用關(guān)鍵字 var
聲明變量,并指定變量類型。
控制流程語句:
條件判斷語句:使用 if-else
或 switch-case-default
循環(huán)語句:使用 for
, range
數(shù)據(jù)類型:
基本數(shù)據(jù)類型:int, float, bool, string
復(fù)合數(shù)據(jù)類型:數(shù)組(Array)、切片(Slice)、映射(Map)、結(jié)構(gòu)體(Struct)
指針和引用類型:可以通過 &
獲取變量的內(nèi)存地址,通過 *
解引用指針獲取對應(yīng)的值。
方法和接口:Go支持面向?qū)ο缶幊蹋梢詾樽远x類型定義方法,并實現(xiàn)接口。
錯誤處理:Go推薦使用錯誤返回值來處理異常情況,通常將最后一個返回值設(shè)為error類型。
并發(fā)與協(xié)程:Go內(nèi)置了并發(fā)編程模型goroutine和通道channel,方便編寫高效的并發(fā)代碼。
Go 程序可以由多個標(biāo)記組成,可以是關(guān)鍵字,標(biāo)識符,常量,字符串,符號。如以下 GO 語句由 6 個標(biāo)記組成:
fmt.Println("Hello, World!")
在 Go 程序中,一行代表一個語句結(jié)束。每個語句不需要像 C 家族中的其它語言一樣以分號 ; 結(jié)尾,因為這些工作都將由 Go 編譯器自動完成。
如果你打算將多個語句寫在同一行,它們則必須使用 ; 人為區(qū)分,但在實際開發(fā)中我們并不鼓勵這種做法。
以下為兩個語句:
fmt.Println("Hello, World!")
fmt.Println("某某教程:runoob.com")
注釋不會被編譯,每一個包應(yīng)該有相關(guān)注釋。
單行注釋是最常見的注釋形式,你可以在任何地方使用以 // 開頭的單行注釋。多行注釋也叫塊注釋,均已以 /* 開頭,并以 */ 結(jié)尾。如:
// 單行注釋
/*
Author by 菜鳥教程
我是多行注釋
*/
標(biāo)識符用來命名變量、類型等程序?qū)嶓w。一個標(biāo)識符實際上就是一個或是多個字母(A~Z和a~z)數(shù)字(0~9)、下劃線_組成的序列,但是第一個字符必須是字母或下劃線而不能是數(shù)字。
以下是有效的標(biāo)識符:
mahesh kumar abc move_name a_123
myname50 _temp j a23b9 retVal
下面列舉了 Go 代碼中會使用到的 25 個關(guān)鍵字或保留字:
除了以上介紹的這些關(guān)鍵字,Go 語言還有 36 個預(yù)定義標(biāo)識符:
程序一般由關(guān)鍵字、常量、變量、運(yùn)算符、類型和函數(shù)組成。
程序中可能會使用到這些分隔符:括號 (),中括號 [] 和大括號 {}。
程序中可能會使用到這些標(biāo)點(diǎn)符號:.、,、;、: 和 …。
Go 語言中變量的聲明必須使用空格隔開,如:
var age int
在變量與運(yùn)算符間加入空格,程序看起來更加美觀,如:
fruit = apples + oranges
簡潔易讀:Go語言的設(shè)計目標(biāo)是簡潔易讀,注重代碼的可讀性和可維護(hù)性。
并發(fā)支持:Go語言內(nèi)置了協(xié)程(goroutine)和通道(channel),方便實現(xiàn)并發(fā)編程,可以高效地利用多核處理器。
垃圾回收:Go語言擁有自動垃圾回收機(jī)制,開發(fā)者無需手動管理內(nèi)存分配和釋放,減輕了程序員的負(fù)擔(dān)。
快速編譯:Go語言的編譯速度非???,可以在很短的時間內(nèi)將代碼編譯成機(jī)器碼,并且生成的可執(zhí)行文件體積小巧。
靜態(tài)類型和強(qiáng)類型:Go語言是靜態(tài)類型和強(qiáng)類型語言,變量需要聲明類型,并且不允許隱式類型轉(zhuǎn)換,這樣可以提高代碼的安全性和可讀性。
內(nèi)置工具豐富:Go語言提供了豐富的標(biāo)準(zhǔn)庫和工具集,包括網(wǎng)絡(luò)、文件操作、測試、調(diào)試等方面,為開發(fā)者提供了便利。
跨平臺支持:Go語言可以在各種主流操作系統(tǒng)上進(jìn)行開發(fā),并且能夠方便地交叉編譯生成不同平臺下的可執(zhí)行文件。
a、內(nèi)存自動回收,再也不需要開發(fā)人員管理內(nèi)存 //開發(fā)代碼中不能存在無引用的變量,不然代碼出錯
b、開發(fā)人員專注業(yè)務(wù)實現(xiàn),降低了心智負(fù)擔(dān)
c、只需要new分配內(nèi)存,不需要釋放
a、從語言層面支持并發(fā),非常簡單
b、goroute,輕量級線程,創(chuàng)建成千上萬個goroute成為可能
c、基于CSP(Communicating Sequential Process)模型實現(xiàn)(基于goroute、channel)
并發(fā)實例:
package main
import(
"time"
"fmt"
)
func test_goroute(a int) {
fmt.Println(a)
}
func main() {
for i := 0; i < 100; i++ {
go test_goroute(i)
}
time.Sleep(time.Second)
}
a、管道,類似unix/linux中的pipe
b、多個goroute之間通過channel進(jìn)行通信
c、支持任何類型
func main() {
pipe := make(chan int,3) //make 分配內(nèi)存空間
pipe <- 1 //向管道里面扔數(shù)值
pipe <- 2
// len(pipe) 管道的長度 t1 =<- pipe //取管道里面的數(shù)據(jù) }
管道的傳值:main/main.go
package main
import(
"go_dev/day1/goroute_example/goroute"
"fmt"
)
func main() {
var pipe chan int
pipe = make(chan int, 1)
go goroute.Add(100, 300, pipe)
sum := <- pipe
fmt.Println("sum=", sum)
}
goroute/add.go
package goroute
func Add(a int, b int, c chan int) {
sum := a +b
c <- sum
}
多返回值:一個函數(shù)返回多個值main/main.go
package main
import(
"go_dev/day1/package_example/calc" //調(diào)用其他包,路徑根據(jù)GOPANTH不用寫src,直接從src目錄下開始 "fmt"
)
func main() {
sum,_ := calc.Add(100, 300) //接收返回值得一個,_沒有值,打印報錯
fmt.Println("sum=",sum)
}
calc/Add.go
package calc
func Add(a int, b int) (int,int) {
return a + b,a - b
}
Go語言是一種支持并發(fā)編程的編程語言。它內(nèi)置了輕量級的協(xié)程(goroutine)和通信機(jī)制(channel),可以方便地進(jìn)行并發(fā)編程。
在Go語言中,使用關(guān)鍵字"go"可以創(chuàng)建一個新的協(xié)程。協(xié)程是一種輕量級的線程,可以同時執(zhí)行多個任務(wù),而不需要顯式地管理線程生命周期。通過協(xié)程,我們可以并發(fā)地執(zhí)行多個函數(shù)或方法。
另外,Go語言提供了通信機(jī)制來實現(xiàn)不同協(xié)程之間的數(shù)據(jù)傳遞和同步操作。通信機(jī)制主要是通過channel來實現(xiàn)的。通過channel,一個協(xié)程可以向另一個協(xié)程發(fā)送數(shù)據(jù),并且會阻塞等待對應(yīng)的接收操作;反之亦然。
這種基于協(xié)程和通信的并發(fā)模型使得在Go語言中編寫高效、簡潔、安全的并發(fā)程序變得相對容易。同時,Go語言還提供了豐富的標(biāo)準(zhǔn)庫以及第三方庫來支持各種并發(fā)相關(guān)的操作和模式,如鎖、條件變量、原子操作等。
傳統(tǒng)邏輯中,開發(fā)者需要維護(hù)線程池中線程與CPU核心數(shù)量的對應(yīng)關(guān)系。同樣的,Go地中也可以通過runtime.GOMAXPROCS()函數(shù)做到,格式為:
runtime.GOMAXPROC(邏輯cpu數(shù)量)
幾種數(shù)值:
<1:不修改任何數(shù)值。
=1:單核心執(zhí)行。
'>1':多核并發(fā)執(zhí)行
runtime.Num CPU()查詢CPU數(shù)量,并使用runtime.GOMAXPROCS()函數(shù)進(jìn)行設(shè)置,例如:
runtime.GOMAXPROC(runtime.NumCPU())
并發(fā)(concurrency):把任務(wù)在不同的時間點(diǎn)交給處理器進(jìn)行處理。在同一時間點(diǎn),任務(wù)并不會同時運(yùn)行。
并行(parallelism):把每一個任務(wù)分配給每一個處理器獨(dú)立完成。在同一時間點(diǎn),任務(wù)一定是同時運(yùn)行。
GO在GOMAXPROCS數(shù)量與任務(wù)數(shù)量相等時,可以做到并行執(zhí)行,但一般情況下都是并發(fā)執(zhí)行。
goroutine屬于搶占式任務(wù)處理,已經(jīng)和現(xiàn)有的多線程和多進(jìn)程任務(wù)處理非常類似。應(yīng)用程序?qū)PU的控制最終還需要由操作系統(tǒng)來管理,操作系統(tǒng)如果發(fā)現(xiàn)一個應(yīng)用程序長時間大量地占用CPU,那么用戶有權(quán)終止這個任務(wù)。
Go語言提倡使用通信的方法代替共享內(nèi)存,這里通信的方法就是使用通道(channel)
特性
任何時候,同時只能有一個goroutine訪問通道進(jìn)行發(fā)送和獲取數(shù)據(jù)。goroutine間通過通道就可以通信。
通道像一個傳送帶或者隊列,總是遵循先入先出(First In First Out)的規(guī)則,保證收發(fā)數(shù)據(jù)的順序。
使用通道接收數(shù)據(jù)
通道接收同樣使用“<-”操作符,通道接收有如下特性:
通道的收發(fā)操作在不同的兩個goroutine間進(jìn)行。由于通道的數(shù)據(jù)在沒有接收方處理時,數(shù)據(jù)發(fā)送方會持續(xù)阻塞,因此通道的接收必定在另外一個goroutine中進(jìn)行。
接收將持續(xù)阻塞直到發(fā)送方發(fā)送數(shù)據(jù)。如果接收方接收時,通道中沒有發(fā)送方發(fā)送數(shù)據(jù),接收方也會發(fā)生阻塞,直到發(fā)送方發(fā)送數(shù)據(jù)為止。
每次接收一個元素。
使用非阻塞方式從通道接收數(shù)據(jù)時,語句不會發(fā)生阻塞
非阻塞的通道接收方法可能造成高的CPU占用,因此使用非常少。如果需要實現(xiàn)接收超時檢測,可以配合select和計時器channel進(jìn)行
循環(huán)接收
通道的數(shù)據(jù)接收可以借用for range語句進(jìn)行多個元素的接收操作
for data := range ch {
}
單向通道
Go的通道可以在聲明時約束其操作方向,如只發(fā)送或是只接收。這種被約束方向的通道被稱做單向通道。
只能發(fā)送的通道類型為chan<-,只能接收的通道類型為<-chan,格式如下:
var 通道實例 chan<- 元素類型 // 只能發(fā)送通道
var 通道實例 <-chan元素類型 // 只能接收通道
但是,一個不能填充數(shù)據(jù)(發(fā)送)只能讀取的通道是毫無意義的。
time包中的單向通道
timer := time.NewTimer(time.Second)
timer的Timer類型定義如下:
type Timer struct {
C <-chan Time
r runtime Timer
}
C通道的類型就是一種只能接收的單向通道。如果此處不進(jìn)行通道方向約束,一旦外部向通道發(fā)送數(shù)據(jù),將會造成其他使用到計時器的地方邏輯產(chǎn)生混亂
帶緩沖的通道
在無緩沖通道的基礎(chǔ)上,為通道增加一個有限大小的存儲空間形成帶緩沖通道
無緩沖通道保證收發(fā)過程同步。無緩沖收發(fā)過程類似于快遞員給你電話讓你下樓取快遞,整個遞交快遞的過程是同步發(fā)生的,你和快遞員不見不散。但這樣做快遞員就必須等待所有人下樓完成操作后才能完成所有投遞工作。如果快遞員將快遞放入快遞柜中,并通知用戶來取,快遞員和用戶就成了異步收發(fā)過程,效率可以有明顯的提升。帶緩沖的通道就是這樣的一個“快遞柜”。
創(chuàng)建帶緩沖通道
通道實例 := make(chan通道類型,緩沖大小)
通道類型:和無緩沖通道用法一致,影響通道發(fā)送和接收的數(shù)據(jù)類型。
通道類型:和無緩沖通道用法一致,影響通道發(fā)送和接收的數(shù)據(jù)類型。
帶緩沖通道為空時,嘗試接收數(shù)據(jù)時發(fā)生阻塞。
通道的多路復(fù)用
多路復(fù)用通常表示在一個信道上傳輸多路信號或數(shù)據(jù)流的過程和技術(shù)
網(wǎng)線、光纖也都是基于多路復(fù)用模式來設(shè)計的,網(wǎng)線、光纖不僅可支持同時收發(fā)數(shù)據(jù),還支持多個人同時收發(fā)數(shù)據(jù)。
提供了select關(guān)鍵字,可以同時響應(yīng)多個通道的操作。select的每個case都會對應(yīng)一個通道的收發(fā)過程.當(dāng)收發(fā)完成時,就會觸發(fā)case中響應(yīng)的語句。多個操作在每次select中挑選一個進(jìn)行響應(yīng).
select{
case 操作1:
響應(yīng)操作1
case 操作2:
響應(yīng)操作2
...
default:
}
模擬遠(yuǎn)程過程調(diào)用(RPC)
服務(wù)器開發(fā)中會使用RPC(Remote Procedure Call,遠(yuǎn)程過程調(diào)用)簡化進(jìn)程間通信的過程。RPC能有效地封裝通信過程,讓遠(yuǎn)程的數(shù)據(jù)收發(fā)通信過程看起來就像本地的函數(shù)調(diào)用一樣。
控制并發(fā)數(shù)
令牌桶的思路:使用chan的緩沖數(shù)來控制每次處理任務(wù)的最大并發(fā)數(shù)
func main() {
ch := make(chan int,100)
for i := 0; i < 1000; i++ {
ch <- i
go func(){
// deal
time.Sleep(time.Second)
<- ch
}()
}
}
并發(fā)的安全退出
有時候需要通知Gorutine停止運(yùn)行,特別是當(dāng)它在錯誤的方向上。Go語言并沒有提供一個直接終止Goroutine的方法,因為這樣會導(dǎo)致Goroutine之間的共享變量處在未定義的狀態(tài)上
借助select及sync.WaitGroup控制
當(dāng)每個Goroutine收到退出指令退出時一般會進(jìn)行一定的清理工作,但是退出的清理工作并不能保證被完成,因為main線程并沒有等待各個工作Goroutine退出工作完成的機(jī)制。結(jié)合sync.WaitGroup來改進(jìn)。
func main() {
cancel := make(chan bool)
var wg sync.WaitGroup
for i :=0; i < 10; i++ {
wg.Add(1)
go worker(&wg, cancel)
}
time.Sleep(time.Second)
close(cancel)
wg.Wait()
}
func worker(wg *sync.WaitGroup, cancel chan bool) {
defer wg.Done()
for {
select {
deafult:
cancel <- cancel:
return
}
}
}
context包
標(biāo)準(zhǔn)庫增加了一個context包,用來簡化對于處理單個請求的多個Goroutine之間與請求域的數(shù)據(jù)、超時和退出等操作
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
var wg sync.WaitGroup
for i :=0; i < 10; i++ {
wg.Add(1)
go worker(ctx,&wg)
}
time.Sleep(time.Second)
cancel()
wg.Wait()
}
func worker(ctx context,Context, wg *sync.WaitGroup) error {
defer wg.Done()
for {
select {
deafult:
cancel <- ctx.Done():
return ctx.Err()
}
}
}
當(dāng)并發(fā)體超時或main主動停止工作者Goroutine時,每個工作者都可以安全退出。
當(dāng)main()函數(shù)完成工作前,通過調(diào)用cancel()來通知后臺Goroutine退出,這樣就避免了Goroutine的泄漏。
5.1項目一:短信發(fā)送
公有云服務(wù)接入基本套路
短信簽名與短信模板
短信應(yīng)用創(chuàng)建及設(shè)置
短信發(fā)送demo實現(xiàn)
短信發(fā)送邏輯封裝
短信模板注冊
短信發(fā)送接口實現(xiàn)
redis客戶端初始化
短信驗證碼接口實
郵件推送前置條件
ses郵件推動demo
ses郵件發(fā)送邏輯封裝
ses郵件模板注冊
ses郵件發(fā)送接口實現(xiàn)
smtp郵件發(fā)送demo
smtp發(fā)送郵件邏輯封裝
smtp郵件發(fā)送接口實現(xiàn)
smtp發(fā)送郵件接口調(diào)試
人機(jī)驗證簡介
驗證碼控制臺配置及接入流程
驗證碼demo實現(xiàn)
驗證碼服務(wù)邏輯封裝
驗證碼票據(jù)校驗接口實現(xiàn)
對象存儲相關(guān)概覽介紹
靜態(tài)網(wǎng)站托管
圖片壓縮與圖片樣式
數(shù)據(jù)直傳簽名邏輯封裝
web數(shù)據(jù)直傳實現(xiàn)
上傳圖片時壓縮圖片文件
PS:項目提供源碼
聯(lián)系客服