Go常見語法題目解析

1、寫出下面代碼輸出內容。

package mainimport ("fmt"
)func main() {defer_call()
}func defer_call() {defer func() { fmt.Println("打印前") }()defer func() { fmt.Println("打印中") }()defer func() { fmt.Println("打印后") }()panic("觸發異常")
}

解析:

defer 關鍵字的實現跟go關鍵字很類似,不同的是它調用的是runtime.deferproc而不是runtime.newproc

defer出現的地方,插入了指令call runtime.deferproc,然后在函數返回之前的地方,插入指令call runtime.deferreturn

goroutine的控制結構中,有一張表記錄defer,調用runtime.deferproc時會將需要defer的表達式記錄在表中,而在調用runtime.deferreturn的時候,則會依次從defer表中出棧并執行。

因此,題目最后輸出順序應該是defer 定義順序的倒序。panic 錯誤并不能終止 defer 的執行。

2、 以下代碼有什么問題,說明原因

type student struct {Name stringAge  int
}func pase_student() {m := make(map[string]*student)stus := []student{{Name: "zhou", Age: 24},{Name: "li", Age: 23},{Name: "wang", Age: 22},}for _, stu := range stus {m[stu.Name] = &stu}
}

解析:

golang 的 for ... range 語法中,stu 變量會被復用,每次循環會將集合中的值復制給這個變量,因此,會導致最后m中的map中儲存的都是stus最后一個student的值。

3、下面的代碼會輸出什么,并說明原因

func main() {runtime.GOMAXPROCS(1)wg := sync.WaitGroup{}wg.Add(20)for i := 0; i < 10; i++ {go func() {fmt.Println("i: ", i)wg.Done()}()}for i := 0; i < 10; i++ {go func(i int) {fmt.Println("i: ", i)wg.Done()}(i)}wg.Wait()
}

解析:

這個輸出結果決定來自于調度器優先調度哪個G。從runtime的源碼可以看到,當創建一個G時,會優先放入到下一個調度的runnext字段上作為下一次優先調度的G。因此,最先輸出的是最后創建的G,也就是9.

func newproc(siz int32, fn *funcval) {argp := add(unsafe.Pointer(&fn), sys.PtrSize)gp := getg()pc := getcallerpc()systemstack(func() {newg := newproc1(fn, argp, siz, gp, pc)_p_ := getg().m.p.ptr()//新創建的G會調用這個方法來決定如何調度runqput(_p_, newg, true)if mainStarted {wakep()}})
}
...if next {retryNext:oldnext := _p_.runnext//當next是true時總會將新進來的G放入下一次調度字段中if !_p_.runnext.cas(oldnext, guintptr(unsafe.Pointer(gp))) {goto retryNext}if oldnext == 0 {return}// Kick the old runnext out to the regular run queue.gp = oldnext.ptr()}

4、下面代碼會輸出什么?

type People struct{}func (p *People) ShowA() {fmt.Println("showA")p.ShowB()
}
func (p *People) ShowB() {fmt.Println("showB")
}type Teacher struct {People
}func (t *Teacher) ShowB() {fmt.Println("teacher showB")
}func main() {t := Teacher{}t.ShowA()
}

解析:

輸出結果為showAshowB。golang 語言中沒有繼承概念,只有組合,也沒有虛方法,更沒有重載。因此,*TeacherShowB 不會覆寫被組合的 People 的方法。

5、下面代碼會觸發異常嗎?請詳細說明

func main() {runtime.GOMAXPROCS(1)int_chan := make(chan int, 1)string_chan := make(chan string, 1)int_chan <- 1string_chan <- "hello"select {case value := <-int_chan:fmt.Println(value)case value := <-string_chan:panic(value)}
}

解析:

結果是隨機執行。golang 在多個case 可讀的時候會公平的選中一個執行。

6、下面代碼輸出什么?

func calc(index string, a, b int) int {ret := a + bfmt.Println(index, a, b, ret)return ret
}func main() {a := 1b := 2defer calc("1", a, calc("10", a, b))a = 0defer calc("2", a, calc("20", a, b))b = 1
}

解析:

輸出結果為:

10 1 2 3
20 0 2 2
2 0 2 2
1 1 3 4

defer 在定義的時候會計算好調用函數的參數,所以會優先輸出1020 兩個參數。然后根據定義的順序倒序執行。

7、請寫出以下輸入內容

func main() {s := make([]int, 5)s = append(s, 1, 2, 3)fmt.Println(s)
}

解析:

輸出為 0 0 0 0 0 1 2 3

make 在初始化切片時指定了長度,所以追加數據時會從len(s) 位置開始填充數據。

8、下面的代碼有什么問題?

type UserAges struct {ages map[string]intsync.Mutex
}func (ua *UserAges) Add(name string, age int) {ua.Lock()defer ua.Unlock()ua.ages[name] = age
}func (ua *UserAges) Get(name string) int {if age, ok := ua.ages[name]; ok {return age}return -1
}

解析:

在執行 Get方法時可能被panic。

雖然有使用sync.Mutex做寫鎖,但是map是并發讀寫不安全的。map屬于引用類型,并發讀寫時多個協程見是通過指針訪問同一個地址,即訪問共享變量,此時同時讀寫資源存在競爭關系。會報錯誤信息:“fatal error: concurrent map read and map write”。

因此,在 Get 中也需要加鎖,因為這里只是讀,建議使用讀寫鎖 sync.RWMutex

9、下面的迭代會有什么問題?

func (set *threadSafeSet) Iter() <-chan interface{} {ch := make(chan interface{})go func() {set.RLock()for elem := range set.s {ch <- elem}close(ch)set.RUnlock()}()return ch
}

解析:

默認情況下 make 初始化的 channel 是無緩沖的,也就是在迭代寫時會阻塞。

10、以下代碼能編譯過去嗎?為什么?

package mainimport ("fmt"
)type People interface {Speak(string) string
}type Student struct{}func (stu *Student) Speak(think string) (talk string) {if think == "bitch" {talk = "You are a good boy"} else {talk = "hi"}return
}func main() {var peo People = Student{}think := "bitch"fmt.Println(peo.Speak(think))
}

解析:

編譯失敗,值類型 Student{} 未實現接口People的方法,不能定義為 People類型。

在 golang 語言中,Student*Student 是兩種類型,第一個是表示 Student 本身,第二個是指向 Student 的指針。

11、以下代碼打印出來什么內容,說出為什么。。。

package mainimport ("fmt"
)type People interface {Show()
}type Student struct{}func (stu *Student) Show() {}func live() People {var stu *Studentreturn stu
}func main() {if live() == nil {fmt.Println("AAAAAAA")} else {fmt.Println("BBBBBBB")}
}

解析:

跟上一題一樣,不同的是*Student 的定義后本身沒有初始化值,所以 *Studentnil的,但是*Student 實現了 People 接口,接口不為 nil

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

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

相關文章

快速冪

a^b % q 給定整數 a b q&#xff0c; 求 a 的 b 次方 mod q 根據題目數字取值范圍&#xff0c;不能暴力處理。 會有兩個問題&#xff1a; 1、計算 a 的次方會超出范圍 2、不能循環 b 次計算 a 的乘積&#xff0c;會超時 處理問題1&#xff1a; 每計算一次 a 的乘積&#xf…

視頻匯聚平臺EasyCVR對接GA/T 1400視圖庫結構化數據:人員/人臉、非/機動車、物品

在信息化浪潮席卷全球的背景下&#xff0c;公安信息化建設日益成為提升社會治理能力和維護社會穩定的關鍵手段。其中&#xff0c;GA/T 1400標準作為公安視頻圖像信息應用系統的核心規范&#xff0c;以其結構化數據處理與應用能力&#xff0c;為公安信息化建設注入了強大的動力。…

【圖解IO與Netty系列】Reactor模型

Reactor模型 Reactor模型簡介三類事件與三類角色Reactor模型整體流程 各種Reactor模型單Reactor單線程模型單Reactor多線程模型主從Reactor模型 Reactor模型簡介 Reactor模型是服務器端用于處理高并發網絡IO請求的編程模型&#xff0c;與傳統的一請求一線程的同步式編程模型不…

翼龍面板是什么,如何進行搭建

翼龍面板是一個開源的&#xff0c;用于游戲服務器管理的程序&#xff0c;可以方便地在網頁界面中創建Minecraft&#xff0c;起源引擎游戲和Teamspeak3 服務器。 它使用前后端程序&#xff0c;因此可以創建多后端節點&#xff0c;對游戲服務器和服務器節點進行統一管理。 對游戲…

Vue進階之Vue無代碼可視化項目(二)

Vue無代碼可視化項目 項目初始化路由子路由錯誤示范正確示范App.vuerouter/index.tsAboutView.vueAboutAboutview.vuerouter/index.ts項目路由router/index.tsApp.vueActionsView.vueDataSourceView.vueLayoutView.vue路由樣式App.vue進一步的App.vue項目初始化 路由 router i…

synchronized 鎖的到底是什么?

通過8種情況演示鎖運行案例&#xff0c;看看我們到底鎖的是什么 1鎖相關的8種案例演示code package com.bilibili.juc.lock;import java.util.concurrent.TimeUnit;/*** 題目&#xff1a;談談你對多線程鎖的理解&#xff0c;8鎖案例說明* 口訣&#xff1a;線程 操作 資源類* 8…

修改hostname導致RabbitMQ數據丟失

背景介紹 公司的很多關鍵服務都使用了RabbitMQ來作為消息隊列服務, 可以說是非常地關鍵的一個環節, 最近由于業務量的上升, 導致RabbitMQ的CPU持續走高, 所以抽空研究了一下RabbitMQ的擴容, 利用我們自己運維平臺使用的一個單節點的RabbitMQ來作為測試吧.看到這個單節點的Rabbi…

第十七節 huggingface的trainner的斷點續訓的Demo(resume)

文章目錄 前言一、參數決定權重保存1、model.safetensors保存2、scaler.pt保存3、optimizer.pt與scheduler.pt保存4、self.state狀態保存(trainer_state.json)5、rng_state.pth保存6、權重相關保存位置(huggingface)二、Resume的Demo1、Demo構建2、實現Resume方法三、Resume訓…

005 CentOS 7.9 RabbitMQ安裝及配置

https://github.com/rabbitmq/rabbitmq-server/releases https://www.rabbitmq.com/docs/download https://packagecloud.io/rabbitmq/rabbitmq-server https://www.erlang-solutions.com/downloads/ https://www.erlang.org/ 文章目錄 卸載erlerl版本安裝與下載版本不匹配正…

AI技術的深度探索:重塑未來的智能引擎

隨著科技的迅猛進步&#xff0c;人工智能&#xff08;AI&#xff09;技術已經逐漸滲透到我們生活的每一個角落&#xff0c;從簡單的智能助手到復雜的決策支持系統&#xff0c;AI技術以其獨特的方式和前所未有的速度改變著我們的世界。本文將對AI技術進行深入探討&#xff0c;從…

開源貢獻 | 基于長安鏈去中心化數字身份合約標準協議(CMDID-1)的DID

DID為每個實體&#xff08;人、組織、物品等&#xff09;提供了一個唯一的全球身份標識符&#xff0c;讓用戶可以控制和管理的自己的數字身份&#xff0c;并在使用時以最小化的方式出示&#xff0c;將數據所有權歸還用戶的同時以區塊鏈技術保證了身份的不可篡改性&#xff0c;以…

LeetCode875愛吃香蕉的阿珂

題目描述 珂珂喜歡吃香蕉。這里有 n 堆香蕉&#xff0c;第 i 堆中有 piles[i] 根香蕉。警衛已經離開了&#xff0c;將在 h 小時后回來。珂珂可以決定她吃香蕉的速度 k &#xff08;單位&#xff1a;根/小時&#xff09;。每個小時&#xff0c;她將會選擇一堆香蕉&#xff0c;從…

IntelliJ IDEA / Android Studio 方法顯示Git提交人

顯示方法&#xff1a; 設置 > 編輯器 > 嵌入提示 > Code Vision > 代碼作者&#xff08;勾選&#xff09; IntelliJ IDEA Android Studio

springboot編寫日志環境搭建過程

AOP記錄日志 AOP記錄日志的主要優點包括&#xff1a; 1、低侵入性&#xff1a;AOP記錄日志不需要修改原有的業務邏輯代碼&#xff0c;只需要新增一個切面即可。 2、統一管理&#xff1a;通過AOP記錄日志可以將各個模塊中需要記錄日志的部分進行統一管理&#xff0c;降低了代…

神經網絡的工程基礎(二)——隨機梯度下降法|文末送書

相關說明 這篇文章的大部分內容參考自我的新書《解構大語言模型&#xff1a;從線性回歸到通用人工智能》&#xff0c;歡迎有興趣的讀者多多支持。 本文涉及到的代碼鏈接如下&#xff1a;regression2chatgpt/ch06_optimizer/stochastic_gradient_descent.ipynb 本文將討論利用…

WinApp自動化測試之輔助工具介紹

前篇文章中&#xff0c;我們簡單介紹了部分WinApp自動化測試腳本常規操作&#xff0c;今天我們來講剩余的部分。 文件批量上傳 文件批量上傳和文件單個上傳原理是相同的&#xff0c;單個上傳直接傳入文件路徑即可&#xff0c;批量上傳需要進入批量上傳的文件所在目錄&#xf…

Redis到底是AP還是CP?

這個問題差評&#xff0c;沒問清楚。當然&#xff0c;網上一搜&#xff0c;各種各樣的狗屁答案都有&#xff0c;有時候是AP的&#xff0c;有時候是CP的&#xff0c;薛定諤的Redis。 好的&#xff0c;那應該怎么問呢&#xff1f;Q1.Redis Cluster集群是AP還是CP&#xff1f; A…

uniapp創建支付密碼實現(初始密碼,第二次密碼)

示例&#xff1a; 插件地址&#xff1a;自定義數字/身份證/密碼輸入框&#xff0c;鍵盤密碼框可分離使 - DCloud 插件市場 1.下載插件并導入HBuilderX&#xff0c;找到文件夾&#xff0c;copy number-keyboard.vue一份為number-keyboard2.vue&#xff08;number-keyboard.vue是…

C++ STL map容器erase操作避坑

map容器的erase方法有三種重載形式&#xff1a; //1.刪除迭代器所指向的元素 //返回值是指向下一個節點的迭代器 iterator erase(iterator it); //2.區間刪除 iterator erase(iterator first, iterator last); //3.根據鍵值刪除 //返回值為刪除的元素個數 size_type erase(con…

民國漫畫雜志《時代漫畫》第37期.PDF

時代漫畫37.PDF: https://url03.ctfile.com/f/1779803-1248636302-c017ee?p9586 (訪問密碼: 9586) 《時代漫畫》的雜志在1934年誕生了&#xff0c;截止1937年6月戰爭來臨被迫停刊共發行了39期。 ps: 資源來源網絡!