<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>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                ### 1、下面代碼能運行嗎?為什么。 ~~~go type Param map[string]interface{} type Show struct { Param } func main1() { s := new(Show) s.Param["RMB"] = 10000 } ~~~ **解析** 共發現兩個問題: 1. `main`函數不能加數字。 2. `new`關鍵字無法初始化`Show`結構體中的`Param`屬性,所以直接對`s.Param`操作會出錯。 ### 2、請說出下面代碼存在什么問題。 ~~~go type student struct { Name string } func zhoujielun(v interface{}) { switch msg := v.(type) { case *student, student: msg.Name } } ~~~ **解析:** golang 中有規定,`switch type`的`case T1`,類型列表只有一個,那么`v := m.(type)`中的`v`的類型就是 T1 類型。 如果是`case T1, T2`,類型列表中有多個,那`v`的類型還是多對應接口的類型,也就是`m`的類型。 所以這里`msg`的類型還是`interface{}`,所以他沒有`Name`這個字段,編譯階段就會報錯。具體解釋見:[https://golang.org/ref/spec#Type\_switches](https://golang.org/ref/spec#Type_switches) ### 3、寫出打印的結果。 ~~~go type People struct { name string `json:"name"` } func main() { js := `{ "name":"11" }` var p People err := json.Unmarshal([]byte(js), &p) if err != nil { fmt.Println("err: ", err) return } fmt.Println("people: ", p) } ~~~ **解析:** 按照 golang 的語法,小寫開頭的方法、屬性或`struct`是私有的,同樣,在`json`解碼或轉碼的時候也無法上線私有屬性的轉換。 題目中是無法正常得到`People`的`name`值的。而且,私有屬性`name`也不應該加`json`的標簽。 ### 4、下面的代碼是有問題的,請說明原因。 ~~~go type People struct { Name string } func (p *People) String() string { return fmt.Sprintf("print: %v", p) } func main() { p := &People{} p.String() } ~~~ **解析:** 在 golang 中`String() string`方法實際上是實現了`String`的接口的,該接口定義在`fmt/print.go`中: ~~~go type Stringer interface { String() string } ~~~ 在使用`fmt`包中的打印方法時,如果類型實現了這個接口,會直接調用。而題目中打印`p`的時候會直接調用`p`實現的`String()`方法,然后就產生了循環調用。 ### 5、請找出下面代碼的問題所在。 ~~~go func main() { ch := make(chan int, 1000) go func() { for i := 0; i < 10; i++ { ch <- i } }() go func() { for { a, ok := <-ch if !ok { fmt.Println("close") return } fmt.Println("a: ", a) } }() close(ch) fmt.Println("ok") time.Sleep(time.Second * 100) } ~~~ **解析:** 在 golang 中`goroutine`的調度時間是不確定的,在題目中,第一個寫`channel`的`goroutine`可能還未調用,或已調用但沒有寫完時直接`close`管道,可能導致寫失敗,既然出現`panic`錯誤。 ### 6、請說明下面代碼書寫是否正確。 ~~~go var value int32 func SetValue(delta int32) { for { v := value if atomic.CompareAndSwapInt32(&value, v, (v+delta)) { break } } } ~~~ **解析:** `atomic.CompareAndSwapInt32`函數不需要循環調用。 ### 7、下面的程序運行后為什么會爆異常。 ~~~go type Project struct{} func (p *Project) deferError() { if err := recover(); err != nil { fmt.Println("recover: ", err) } } func (p *Project) exec(msgchan chan interface{}) { for msg := range msgchan { m := msg.(int) fmt.Println("msg: ", m) } } func (p *Project) run(msgchan chan interface{}) { for { defer p.deferError() go p.exec(msgchan) time.Sleep(time.Second * 2) } } func (p *Project) Main() { a := make(chan interface{}, 100) go p.run(a) go func() { for { a <- "1" time.Sleep(time.Second) } }() time.Sleep(time.Second * 100000000000000) } func main() { p := new(Project) p.Main() } ~~~ **解析:** 有一下幾個問題: 1. `time.Sleep`的參數數值太大,超過了`1<<63 - 1`的限制。 2. `defer p.deferError()`需要在協程開始出調用,否則無法捕獲`panic`。 ### 8、請說出下面代碼哪里寫錯了 ~~~go func main() { abc := make(chan int, 1000) for i := 0; i < 10; i++ { abc <- i } go func() { for a := range abc { fmt.Println("a: ", a) } }() close(abc) fmt.Println("close") time.Sleep(time.Second * 100) } ~~~ **解析:** 協程可能還未啟動,管道就關閉了。 ### 9、請說出下面代碼,執行時為什么會報錯 ~~~go type Student struct { name string } func main() { m := map[string]Student{"people": {"zhoujielun"}} m["people"].name = "wuyanzu" } ~~~ **解析:** map 的 value 本身是不可尋址的,因為 map 中的值會在內存中移動,并且舊的指針地址在 map 改變時會變得無效。故如果需要修改 map 值,可以將`map`中的非指針類型`value`,修改為指針類型,比如使用`map[string]*Student`. ### 10、請說出下面的代碼存在什么問題? ~~~go type query func(string) string func exec(name string, vs ...query) string { ch := make(chan string) fn := func(i int) { ch <- vs[i](name) } for i, _ := range vs { go fn(i) } return <-ch } func main() { ret := exec("111", func(n string) string { return n + "func1" }, func(n string) string { return n + "func2" }, func(n string) string { return n + "func3" }, func(n string) string { return n + "func4" }) fmt.Println(ret) } ~~~ **解析:** 依據 4 個 goroutine 的啟動后執行效率,很可能打印 111func4,但其他的 111func\*也可能先執行,exec 只會返回一條信息。 ### 11、下面這段代碼為什么會卡死? ~~~go package main import ( "fmt" "runtime" ) func main() { var i byte go func() { for i = 0; i <= 255; i++ { } }() fmt.Println("Dropping mic") // Yield execution to force executing other goroutines runtime.Gosched() runtime.GC() fmt.Println("Done") } ~~~ **解析:** Golang 中,byte 其實被 alias 到 uint8 上了。所以上面的 for 循環會始終成立,因為 i++ 到 i=255 的時候會溢出,i <= 255 一定成立。 也即是, for 循環永遠無法退出,所以上面的代碼其實可以等價于這樣: ~~~go go func() { for {} } ~~~ 正在被執行的 goroutine 發生以下情況時讓出當前 goroutine 的執行權,并調度后面的 goroutine 執行: * IO 操作 * Channel 阻塞 * system call * 運行較長時間 如果一個 goroutine 執行時間太長,scheduler 會在其 G 對象上打上一個標志( preempt),當這個 goroutine 內部發生函數調用的時候,會先主動檢查這個標志,如果為 true 則會讓出執行權。 main 函數里啟動的 goroutine 其實是一個沒有 IO 阻塞、沒有 Channel 阻塞、沒有 system call、沒有函數調用的死循環。 也就是,它無法主動讓出自己的執行權,即使已經執行很長時間,scheduler 已經標志了 preempt。 而 golang 的 GC 動作是需要所有正在運行`goroutine`都停止后進行的。因此,程序會卡在`runtime.GC()`等待所有協程退出。
                  <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>

                              哎呀哎呀视频在线观看