マルコのハイエンドGo言語数百万の同時高額クラス/マイクロサービス/分散型高可用性/ Go高同時実行

  1. 次のコードを実行できますか?なぜ

動作結果:

パニック:nil mapgoroutine 1のエントリへの割り当て[実行中]:main.main()

上記のように、動作中に例外が発生します。その理由は、辞書Paramのデフォルト値がnilであるためです。キーと値のペアが辞書nilに追加されると、ランタイムエラーパニック:nilマップのエントリへの割り当てが発生します。

正しい変更計画は次のとおりです。

パッケージメイン

「fmt」をインポート

タイプParammap [string] interface {}

タイプShowstruct {

Param

}

func main(){

// 创建Show结构体对象    s := new(Show)

// 为字典Param赋初始值    s.Param = Param{}

// 修改键值对    s.Param["RMB"] = 10000    fmt.Println(s)

}

結果は次のとおりです。

&{map [RMB:10000]}

プロセスは終了コード0で終了しました

  1. 以下のコードの何が問題になっているのか教えてください

タイプstudentstruct {

Name string

}

func f(v interface {}){

switch msg := v.(type) {

    case student, student:

        msg.Name   

}

}

2つの問題があります:

質問1:interface {}は、メソッドを宣言しないインターフェースです。

質問2:名前は属性であり、メソッドではありません。タイプinterface {}の変数は属性を呼び出すことができません。

  1. 印刷結果を書き込みます。

タイプPeoplestruct {

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)

}

出力は次のとおりです。

人: {}

結果は次のとおりです。

人々:{11}プロセスは終了コード0で終了しました

  1. 次のコードには問題があります。理由を説明してください。

パッケージメイン

「fmt」をインポート

タイプPeoplestruct {

Name string

}

func(p People)String()文字列{

return fmt.Sprintf("print: %v", p)

}

func main(){

p := &People{}

p.String()

}

結果は次のとおりです。

ランタイム:ゴルーチンスタックが1000000000バイトの制限を超えています

致命的なエラー:スタックオーバーフロー

ランタイムスタック:

runtime.throw(0x10c122b、0xe)

以下に示すように、%v形式の文字列自体がString()メソッドを呼び出すため、上記のコードにはスタックオーバーフローがあり、上記のスタックオーバーフローは無限の再帰によって発生します。

  1. 以下のコードで問題を見つけてください。

パッケージメイン

インポート(「fmt」「time」)

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)

}

結果は次のとおりです。

パニック:閉じたchannelokで送信

goroutine 5 [実行中]:

main.main.func1(0xc420098000)

分析:上記のエラーの理由は、チャネルが事前に閉じられているためです。

正しいコードは次のとおりです。

パッケージメイン

インポート(「fmt」「time」)

func main(){

// 创建一个缓冲通道

ch := make(chan int, 1000)

go func() {

    for i := 0; i < 10; i++ {

        ch <- i

    }

}()

go func() {

    for i := 0; i < 10; i++ {

        a, ok := <-ch

        if !ok {

            fmt.Println("close")

            close(ch)

            return            }

        fmt.Println("a: ", a)

    }

}()

fmt.Println("ok")

time.Sleep(time.Second)

}

結果は次のとおりです。

OK

a:0a:1a:2a:3a:4a:5a:6a:7a:8a:9

  1. 以下のコードが正しく書かれているかどうか説明してください。

var value int32

func SetValue(delta int32){

for {

    v := value

    if atomic.CompareAndSwapInt32(&value, v(v+delta)) {

        break

    }

}

}

atomic.CompareAndSwapInt32には、合計3つのパラメーターがあります。上記の記述は間違っています。正しい記述は次のとおりです。atomic.CompareAndSwapInt32(&value、v、v + delta)

func CompareAndSwapInt32(addr int32、old、new int32)(swapped bool)

最初のパラメーターの値は、操作された値へのポインターである必要があります。この値のタイプはint32です。

後者の2つのパラメーターのタイプは、どちらもint32タイプです。それらの値は、操作された値の古い値と新しい値をそれぞれ表す必要があります

CompareAndSwapInt32・関数は、最初に、パラメーターaddrが指す操作値が、呼び出された後のパラメーターold`の値と等しいかどうかを判別します。

この判断が肯定的である場合にのみ、関数は元の古い値を新しいパラメーターで表される新しい値に置き換えます。それ以外の場合、後続の置換操作は無視されます。

完全なコードは次のとおりです。

パッケージメイン

インポート(「同期/アトミック」「fmt」)

var value int32

func SetValue(delta int32){

for {

    v := value

    // 比较并交换

    if atomic.CompareAndSwapInt32(&value, v,v+delta) {

        fmt.Println(value)

        break 

   }

}

}

func main(){

SetValue(100)

}

実行結果は100です。

  1. 実行後に次のプログラムが爆発するのはなぜですか。

パッケージメイン

インポート(「fmt」「time」)

タイプProjectstruct {}

func(p Project)deferError(){

if err := recover(); err != nil {

    fmt.Println("recover: ", err)

}

}

おすすめ

転載: blog.csdn.net/weixin_52772147/article/details/112007980