<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                ### 1、寫出下面代碼輸出內容。 ~~~go package main import ( "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、 以下代碼有什么問題,說明原因 ~~~go type student struct { Name string Age 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、下面的代碼會輸出什么,并說明原因 ~~~go 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. ~~~go 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、下面代碼會輸出什么? ~~~go 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() } ~~~ **解析:** 輸出結果為`showA`、`showB`。golang 語言中沒有繼承概念,只有組合,也沒有虛方法,更沒有重載。因此,`*Teacher`的`ShowB`不會覆寫被組合的`People`的方法。 ### 5、下面代碼會觸發異常嗎?請詳細說明 ~~~go func main() { runtime.GOMAXPROCS(1) int_chan := make(chan int, 1) string_chan := make(chan string, 1) int_chan <- 1 string_chan <- "hello" select { case value := <-int_chan: fmt.Println(value) case value := <-string_chan: panic(value) } } ~~~ **解析:** 結果是隨機執行。golang 在多個`case`可讀的時候會公平的選中一個執行。 ### 6、下面代碼輸出什么? ~~~go func calc(index string, a, b int) int { ret := a + b fmt.Println(index, a, b, ret) return ret } func main() { a := 1 b := 2 defer calc("1", a, calc("10", a, b)) a = 0 defer 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`在定義的時候會計算好調用函數的參數,所以會優先輸出`10`、`20`兩個參數。然后根據定義的順序倒序執行。 ### 7、請寫出以下輸入內容 ~~~go 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、下面的代碼有什么問題? ~~~go type UserAges struct { ages map[string]int sync.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、下面的迭代會有什么問題? ~~~go 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、以下代碼能編譯過去嗎?為什么? ~~~go package main import ( "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、以下代碼打印出來什么內容,說出為什么。。。 ~~~go package main import ( "fmt" ) type People interface { Show() } type Student struct{} func (stu *Student) Show() { } func live() People { var stu *Student return stu } func main() { if live() == nil { fmt.Println("AAAAAAA") } else { fmt.Println("BBBBBBB") } } ~~~ **解析:** 跟上一題一樣,不同的是`*Student`的定義后本身沒有初始化值,所以`*Student`是`nil`的,但是`*Student`實現了`People`接口,接口不為`nil`。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看