goland有基礎速通(需要其它編程語言基礎)

tip: 無論是變量、方法還是struct的訪問權限控制都是通過命名控制的,命名的首字母是大寫就相當于java中的public,小寫的話就是private,(private只有本包可以訪問)

1 go的變量聲明

普通變量

特點: 變量類型后置

方式1var num int = 1
方式2:
num := 1					// := 會幫我們自動匹配數據類型(最常用)
方式3var num = 1

常量

還是通過const關鍵字聲明(和c是一樣的)const (//聲明常數列表ZHANGSAN = 1LISI = 2....
)并且我們可以使用iota關鍵字進行簡寫
const (ZHANGSAN = iota + 1      //iota默認是0,每次被使用后都會+1LiSI					//等同于LISI = iota + 1, 但是公式沒有發生變化所以可以省略
)常量使用:
fmt.println("ZHANGSNA = ", ZHANGSAN)

2 go的函數/方法聲明

特點: func (綁定struct名 類型) 函數名(形參名 形參類型, …) 返回類型 {函數體}

func print(s string) string {....
}go當中的方法是可以有多個返回值的:
func play() (string, string) {return zhangsan, lisi
}//多返回值接收
name1, name2 := play()

3.對象

聲明

特點: go語言的對象是一種組合概念,由結構體+一系列方法構成

type關鍵字:定義自定義類型type person struct {name stringage int
}func (p *person) setName(name string) {p.name = name
}上述代碼就等同于java中的如下代碼:
private class person {private String name;private int age;private void setName(String name) {this.name = name;}
}"(p *person)"代表這個方法綁定person這個struct為什么要使用"*person"?
因為go中的對象(struct)是值類型(也就是java中的基本類型),因此不傳入指針的話修改也不生效(需要一點c的指針基礎)

類繼承

type human struct {name stringage int
}type man struct {human // 就代表man繼承了human對象sex int
}//man的創建
man1 := man{human{"zhangsan", 18}, 1}

4 init方法

特點: 導包時執行的初始化方法

package p1import "fmt"func init() {fmt.println("p1, init")
}如果我們引入這個包,那么就會執行p1的init方法

5 指針

go中的指針和c是一樣的

6 defer關鍵字

特點: 在defer所在的代碼塊執行完后執行,類似java的finally或c++的析構函數

使用場景: 文件關閉、連接關閉、資源釋放等

func print() {defer fmt.println("2..")fmt.println("1..")
}
輸出:先12//defer可以有多個,通過棧結構存儲
func print() {defer fmt.println("2..")		//2進棧defer fmt.println("3..")		//3進棧fmt.println("1..")
}
輸出:先132tip:deferreturn的執行順序,因為defer是在所在方法的生命周期結束后才會執行
func deferCall() {fmt.println("defer...")
}
func returnCall() {fmt.println("return...")
}
func deferAndReturn() {defer deferCall()return returnCall()
}
func main() {deferAndReturn()
}
輸出: return...defer...

7 數組與動態數組

聲明

固定數組(常用)
arr := [3]int{1,2,3} 動態數組(也叫切片slice)
arr := []int{1, 2, 3} 或   //雖然我們只添加了三個初始值,但是我們還可以往后繼續添加
arr1 := make([]int, 3)    //開辟大小為3的數組,但是沒有設置初始值
arr2 := make([]int, 3, 5) //開辟一個大小為3,容量為5的切片(arr[3]和arr[4]實際還不可以訪問)
容量的概念就是我們聲明了這個空間但是我沒創建(也就是我告訴你這有但是現在還沒有),大小就是現在實際有的切片擴容:當容量不夠時,會自動擴容為當前容量的2倍,沒指定容量的話就是切片大小對動態數組的操作與python中的切片操作類似。tip: 
go當中的固定數組是一種直接類型,不像是java中的引用類型,所以[3]int 和 [4]int不是同一類型的,所以在使用固定數組作為方法形參的時候如果想要改變內容應該傳入指針。
而動態數組是引用類型,type(arr)得到的是[]int.

遍歷

arr := []int{1,2,3,4}方式1for index, value := range arr {fmt.println("下標是:", index)fmt.println("內容是:", value)
}方式2for i := 1, i < len(arr), i++ {fmt.println(arr[i])
}

8 map

聲明

var myMap map[String]string				//[]內是key類型,外是value類型//開辟空間
myMap := make(map[string]string, 10)//有初始值創建
myMap := map[string]string{"one":	"zhangsan""two":	"lisi"
}

使用

myMap := make(map[string]string)
//增
myMap["one"] = "zhangsan"
myMap["two"] = "lisi"//刪
delete(myMap, "one")//改
myMap["two"] = "wangwu"//查
value := myMap["two"]// 遍歷
for key, value := range myMap {}

9 多態

特點: 實現接口

type animal interface {show()play()
}
// cat實現了animal接口, 是通過實現接口方法
type cat struct {name string
}
func (c *cat) show() {fmt.println("這是一只貓")
}
func (c *cat) play() {fmt.println("貓在玩耍")
}

10.interface{}

特點: 通用數據類型,幾乎所有類型都實現了interface{}

func call(this interface{}) {fmt.println("this is ", this)// 類型斷言value, res := this.(string) // 判斷this是不是是tring類型,會返回兩個數據一個是this本身一個是判斷結果(bool)
}type human struct {name string
}func main() {human1 := human{"zhangsan"}//call 方法可以接收任何類型call(human1)call(1)call("lisi")
}

11 pair

任何變量都會有一個piar對變量描述,這個piar結構如下:<type, value>,type代表變量的類型,value代表變量存儲的值。

type又分為static type(基本類型,如:int、char這些)和concrete type(引用類型,如:切片)

12 反射

go提供了reflect包實現反射功能,其中有兩個核心方法TypeOf()和ValueOf(), 分別用來獲取參數對象的類型與值。

反射基本使用

package mainimport ("fmt""reflect"
)type User struct {Name stringAge int
}func (this User) Call() {   //這里寫*User會識別不到方法,原因在后面fmt.Println("User is call...")fmt.Printf("%v\n", this)
}func main() {user :=  User{"zhangsan", 18}DoFiledAndMethod(user)
}func DoFiledAndMethod(input interface{}) {// 獲取input信息t := reflect.TypeOf(input)fmt.Println("type:", t.Name())v := reflect.ValueOf(input)fmt.Println("value:", v)// 遍歷結構體的所有字段for i := 0; i < t.NumField(); i++ {field := t.Field(i)value := v.Field(i).Interface()fmt.Printf("%s: %v = %v\n", field.Name, field.Type, value)}methodNum := t.NumMethod()fmt.Printf("the User has %d methods\n", methodNum)// 通過type調用方法for i := 0; i < t.NumMethod(); i++ {method := t.Method(i)fmt.Printf("%s: %v\n", method.Name, method.Type)}
}

Go 的方法集規則

Go 的方法集規則如下:

  1. 值類型(T 的方法集包含所有接收者為 T 的方法。
  2. 指針類型(*T 的方法集包含所有接收者為 T*T 的方法。

因此:

  • User 值類型的方法集:只有接收者為 User 的方法。
  • *User 指針類型的方法集:接收者為 User*User 的方法。

13 標簽

在 Go 語言中,標簽(Tags) 是結構體字段的元數據,通常用于編碼/解碼(如 JSON、XML)、ORM 映射(如 GORM)、驗證(如 validator)等場景。標簽以反引號 `` 包裹,格式為 key:“value”,多個標簽用空格分隔。

package mainimport ("fmt""encoding/json"
)type User struct {Name string		`json:"name"`Age int			`json:"age"`
}func main() {user := User{"zhangsan", 18}// 結構體 -> jsonjsonData, _ := json.Marshal(user)fmt.Println(string(jsonData))//json -> 結構體myUser := User{}err := json.Unmarshal(jsonData, &myUser)if(err != nil) {fmt.Println("err: ", err)return}fmt.Printf("%v\n", myUser)
}輸出:
{"name":"zhangsan","age":18}
{zhangsan 18}

14 協程

協程(Goroutine) 是一種輕量級的并發執行單元,由 Go 運行時(runtime)管理,用于實現高并發編程。

go語言對于協程的設計是將原先線程中用戶態部分分離出來了,這樣不需要頻繁的切換,而原線程中的內核態部分成為新的線程復雜管理協程。

協程結構:

在這里插入圖片描述

GMP模型控制:

關鍵組件

  1. G (Goroutine)
    • 包含執行棧、程序計數器(PC)、狀態(運行/阻塞)。
    • 通過 go 關鍵字創建,輕量且可動態擴縮。
  2. P (Processor)
    • 協程調度器,綁定到 M 上運行。
    • 維護一個本地 Goroutine 隊列(優先調度本地隊列)。
  3. M (Machine)
    • 操作系統線程,真正執行計算的單元。
    • 由 P 分配任務,空閑時會被回收或休眠。

調度流程:

1. G 創建 → 放入 P 的本地隊列(或全局隊列)。//只用本地隊列滿會放入全局隊列
2. M 獲取 G → 從綁定的 P 的隊列中取 G 執行。
3. G 阻塞(如 I/O)→ 該阻塞協程從本地隊列移除,M解綁P,由M負責該阻塞協程,解綁后的P綁定一個新的線程,P可以正常工作去調度其他G。
4. G 就緒 → 被放回隊列,等待 M 執行。

在這里插入圖片描述

Goroutine 解決了線程的哪些痛點?

(1) 高創建和切換成本
  • 線程問題:每個線程需要分配較大的棧(1MB+),創建和切換涉及內核態操作,開銷大。
  • Goroutine 方案:初始棧僅 2KB,由 Go 運行時在用戶態調度,切換成本極低。
(2) 并發數量受限
  • 線程問題:受限于內存和內核調度,通常只能創建幾千個線程。
  • Goroutine 方案:輕量級設計,單機可輕松支持百萬級并發,還有協程調度器的存在支持多對多的調度關系。
(3) 共享內存導致的競態問題
  • 線程問題:多線程需通過鎖(mutex)同步,易引發死鎖、數據競爭。
  • Goroutine 方案:通過 Channel 通信,避免顯式鎖,更安全。
(4) 阻塞導致線程浪費
  • 線程問題:一個線程阻塞(如 I/O 操作)時,線程池中的線程被占用,影響整體吞吐量。
  • Goroutine 方案:阻塞時,Go 運行時會自動掛起該 Goroutine,復用線程執行其他任務。

協程的使用

package mainimport ("fmt""time"
)
func print() {i := 0for {i++fmt.Printf("new Goroutine: i = %d\n", i)time.Sleep(1 * time.Second)}
}func main() {go print() // 創建協程執行print方法i := 0for {i++fmt.Printf("main Goroutine: i = %d\n", i)time.Sleep(1 * time.Second)}
}// 也可以通過匿名調用的方式
func main() {go func ()  {i := 0for {i++fmt.Printf("new Goroutine: i = %d\n", i)time.Sleep(1 * time.Second)}}() // 括號中填入方法的參數,我這是無參就沒填i := 0for {i++fmt.Printf("main Goroutine: i = %d\n", i)time.Sleep(1 * time.Second)}
}//執行結果
main Goroutine: i = 1
new Goroutine: i = 1
new Goroutine: i = 2
main Goroutine: i = 2
main Goroutine: i = 3
new Goroutine: i = 3
new Goroutine: i = 4
main Goroutine: i = 4

15 channel

用于協程間通信的一種方式,分為無緩沖channel有緩沖channel

無緩沖channel:channel中同一時間只能存在一個數據

package mainimport ("fmt""time"
)// 1
func main() { // 主協程c := make(chan int)fmt.Println("main Goroutine try to read from channel")num := <-cfmt.Println(num)go func (){  //子協程c <- 1fmt.Println("already write")}()
}// 2
func main() {c := make(chan int)go func (){c <- 1fmt.Println("already write")}()fmt.Println("main Goroutine not read from channel")i := 0for {i++fmt.Println(i)time.Sleep(1 * time.Second)}
}輸出:
// 1
fmt.Println("main Goroutine try to read from channel")
1// 2
main Goroutine not read from channel
1
2
3
4
5

子協程向channel中寫入數據后會在此阻塞直到數據被取走,同樣如果主協程想要從channel中讀取數據但目前channel中沒有數據主協程也會阻塞等待。

有緩沖channel:其與阻塞隊列的功能非常相似,允許存在多個數據在channel中,如果從空channel中獲取元素或向滿channel中發送元素則會觸發阻塞。

// 聲明有緩沖channel
ch := make(chan int 3) //創建緩沖大小為3的有緩沖channel

雖然channel和阻塞隊列功能類似但他倆在實現上還是有很大的不同,感興趣的可以去了解一下。

關閉channel:

channel一旦關閉就無法向channel中發送數據,但如果緩沖區內還有數據則還可以讀取。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/84205.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/84205.shtml
英文地址,請注明出處:http://en.pswp.cn/web/84205.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

量化面試綠皮書:19. 相關系數

文中內容僅限技術學習與代碼實踐參考&#xff0c;市場存在不確定性&#xff0c;技術分析需謹慎驗證&#xff0c;不構成任何投資建議。 19. 相關系數 假設有三個隨機變量x、y和z。 x與y之間的相關系數為0.8&#xff0c;x與z之間的相關系數也是0.8。 Q: 那么y與z之間的最大相關…

新生活的開啟:從 Trae AI 離開后的三個月

很久沒有寫文章了&#xff0c;想借著入職新公司一個月的機會&#xff0c;和大家嘮嘮嗑。 離職 今年2月份我從字節離職了&#xff0c;結束了四年的經歷&#xff0c;當時離開的核心原因是覺得加班時間太長了&#xff0c;平均每天都要工作15&#xff0c;16個小時&#xff0c;周末…

LLM部署之vllm vs deepspeed

部署大語言模型(如 Qwen/LLaMA 等)時,vLLM 與 DeepSpeed 是當前主流的兩種高性能推理引擎。它們各自專注于不同方向,部署流程也有明顯區別。 vLLM 提供極致吞吐、低延遲的推理服務,適用于在線部署;DeepSpeed 更側重訓練與推理混合優化,支持模型并行,適用于推理 + 微調/…

Git(二):基本操作

文章目錄 Git(二)&#xff1a;基本操作添加文件修改文件版本回退撤銷修改情況一&#xff1a;工作區的代碼還沒有 add情況?&#xff1a;已經 add 但沒有 commit情況三&#xff1a;已經 add 并且也 commit 刪除文件 Git(二)&#xff1a;基本操作 添加文件 首先我們先來學習一個…

nginx + ffmpeg 實現 rtsp視頻實時播放和歷史播放

nginx和ffmpeg 的安裝請參考我的另一篇文章 Nginxrtmpffmpeg搭建視頻轉碼服務_nginx-rtmp-module-master-CSDN博客 目錄 1、整體方案設計如圖 2、nginx下目錄創建和配置文件創建 3、創建視頻流生成腳本 4、修改nginx配置 5、管理界面 (video.html) 6、ffmpeg后臺啟動 …

全國產!瑞芯微 RK3576 ARM 八核 2.2GHz 工業核心板—硬件說明書

前 言 本文為創龍科技 SOM-TL3576 工業核心板硬件說明書,主要提供 SOM-TL3576 工業 核心板的產品功能特點、技術參數、引腳定義等內容,以及為用戶提供相關電路設計指導。 為便于閱讀,下表對文檔出現的部分術語進行解釋;對于廣泛認同釋義的術語,在此不做注釋。 硬件參考…

web3 瀏覽器注入 (如 MetaMask)

以下是關于 瀏覽器注入方式(如 MetaMask) 的完整詳解,包括原理、使用方法、安全注意事項及常見問題解決方案: 1. 核心原理 當用戶安裝 MetaMask 等以太坊錢包擴展時,錢包會向瀏覽器的 window 對象注入一個全局變量 window.ethereum,這個對象遵循 EIP-1193 標準,提供與區…

解密提示詞工程師:AI 時代的新興職業

大家好!在人工智能飛速發展的當下&#xff0c;有一個新興職業正悄然崛起——提示詞工程師。他們雖不如數據科學家般廣為人知&#xff0c;卻在 AI 應用領域發揮著獨特且關鍵的作用。 何為提示詞工程師&#xff1f; 提示詞工程師專注于設計和優化與 AI 模型進行交互的提示詞&…

linux 下 jenkins 構建 uniapp node-sass 報錯

背景: jenkins 中構建 uniapp 應用 配置: 1. 將windows HbuilderX 插件目錄下的 uniapp-cli 文件夾復制到 服務器 /var/jenkins_home/uniapp-cli 2. jenkins 構建步驟增加 執行 shell ,內容如下 echo ">> 構建中..."# 打包前端 export LANGen_US.UTF-8…

QT常見問題(1)

QT常見問題&#xff08;1&#xff09; 1.問題描述 Qt在編譯器中直接運行沒有任何問題&#xff0c;但是進入exe生成目錄直接雙擊運行就報錯&#xff1a;文件無法定位程序輸入點_zn10qarraydata10deallocateepsyy于動態鏈接庫。 2.問題原因 這個錯誤通常是由于程序運行時找不…

『大模型筆記』第2篇:并發請求中的 Prefill 與 Decode:優化大語言模型性能

『大模型筆記』并發請求中的 Prefill 與 Decode:優化大語言模型性能 文章目錄 一. Token 生成的兩個階段:Prefill 和 Decode1.1. 指標分析1.2. 資源利用率分析二. 并發處理機制2.1. 靜態批處理 vs 持續批處理(Static Batching vs. Continuous Batching)2.2. Prefill 優先策略…

JVM(7)——詳解標記-整理算法

核心思想 標記-整理算法同樣分為兩個主要階段&#xff0c;但第二個階段有所不同&#xff1a; 標記階段&#xff1a; 與標記-清除算法完全一致。遍歷所有可達對象&#xff08;從 GC Roots 開始&#xff09;&#xff0c;標記它們為“存活”。 整理階段&#xff1a; 不再簡單地清…

進程虛擬地址空間

1. 程序地址空間回顧 我們在學習語言層面時&#xff0c;會了解到這樣的空間布局圖&#xff0c;我們先對他進行分區了解&#xff1a; 如果以靜態static修飾的變量就會當成已初始化全局變量來看待&#xff0c;存放在已初始化數據區和未初始化數據區之前。 如果不用static修飾test…

C語言學習day17-----位運算

目錄 1.位運算 1.1基礎知識 1.1.1定義 1.1.2用途 1.1.3軟件控制硬件 1.2運算符 1.2.1與 & 1.2.2或 | 1.2.3非 ~ 1.2.4異或 ^ 1.2.5左移 << 1.2.6右移 >> 1.2.7代碼實現 1.2.8置0 1.2.9置1 1.2.10不借助第三方變量&#xff0c;實現兩個數的交換…

【linux】簡單的shell腳本練習

簡單易學 解釋性語言&#xff0c;不需要編譯即可執行 對于一個合格的系統管理員來說&#xff0c;學習和掌握Shell編程是非常重要的&#xff0c;通過shell程序&#xff0c;可以在很大程度上簡化日常的維護工作&#xff0c;使得管理員從簡單的重復勞動中解脫出來 用戶輸入任意兩…

機構運動分析系統開發(Python實現)

機構運動分析系統開發(Python實現) 一、引言 機構運動分析是機械工程的核心內容,涉及位置、速度和加速度分析。本系統基于Python開發,實現了平面連桿機構的完整運動學分析,包含數學建模、數值計算和可視化功能。 二、系統架構設計 #mermaid-svg-bT8TPKQ98UU9ERet {font…

工程師生活:清除電熱水壺(鍋)水垢方法

清除電熱水壺&#xff08;鍋&#xff09;水垢方法 水垢是水加熱時自然形成的鈣質沉淀物&#xff0c;常粘附在水壺內壁及發熱盤上。它不僅影響水的品質&#xff0c;還會縮短水壺的使用壽命&#xff0c;因此需要定期清除。建議根據各地水質不同&#xff0c;每年除垢 2 至 4 次。…

[分布式并行策略] 數據并行 DP/DDP/FSDP/ZeRO

上篇文章【[論文品鑒] DeepSeek V3 最新論文 之 DeepEP】 介紹了分布式并行策略中的EP&#xff0c;簡單的提到了其他幾種并行策略&#xff0c;但礙于精力和篇幅限制決定將內容分幾期&#xff0c;本期首先介紹DP&#xff0c;但并不是因為DP簡單&#xff0c;相反DP的水也很深&…

LeeCode144二叉樹的前序遍歷

項目場景&#xff1a; 給你二叉樹的根節點 root &#xff0c;返回它節點值的 前序 遍歷。 示例 1&#xff1a; 輸入&#xff1a;root [1,null,2,3] 輸出&#xff1a;[1,2,3] 解釋&#xff1a; 示例 2&#xff1a; 輸入&#xff1a;root [1,2,3,4,5,null,8,null,null,6,7…

日本生活:日語語言學校-日語作文-溝通無國界(3)-題目:わたしの友達

日本生活&#xff1a;日語語言學校-日語作文-溝通無國界&#xff08;&#xff13;&#xff09;-題目&#xff1a;わたしの友達 1-前言2-作文原稿3-作文日語和譯本&#xff08;1&#xff09;日文原文&#xff08;2&#xff09;對應中文&#xff08;3&#xff09;對應英文 4-老師…