Golang 面試題解析 3

21.編譯執行下面代碼會出現什麼?

:= 定義變數時同時出數話,不能提供數據類型,只能在函數內部使用 https://go.dev/play/p/P5031XtJj7P

package main
var(
    size :=1024 // 這邊會出錯
    max_size = size*2
)
func main()  {
    println(size,max_size)
}

// prog.go:3:10: expected ';', found ':=' (and 1 more errors)

變量簡短模式限制: - 定義變量同時顯式初始化 - 不能提供數據類型 - 只能在函數內部使用


22.下面函數有什麼問題? const通常會被編譯器在預處理階段直接展開,作為指令數據使用

https://go.dev/play/p/5IbC47pIVaH

package main

const cl = 100

var bl = 123

func main() {
    println(&bl, bl)
    println(&cl, cl) // &cl 這邊會出錯
}
// ./prog.go:9:10: cannot take the address of cl

./prog.go:9:10: cannot take the address of cl, 常數不同於變量的在運行期分配內存,常數通常會被編譯器在預處理階段直接展開,作為指令數據使用,


23.編譯執行下面代碼會出現什麼? goto不能跳轉到其他函數或者內層代碼

https://go.dev/play/p/7vEcjr2mibC

package main

func main() {

    for i := 0; i < 10; i++ {
    loop:
        println(i)
    }
    goto loop
}

./prog.go:9:7: goto loop jumps into block starting at ./prog.go:5:26

goto不能跳轉到其他函數或者內層代碼


24.編譯執行下面代碼會出現什麼?

https://go.dev/play/p/w2feiGVuG_x

package main

import "fmt"

func main() {
    type MyInt1 int    // defintion(定義MyInt1 為一個Int型態)
    type MyInt2 = int // alias(別名, 將int 稱為 MyInt)
    var i int = 9
    var i1 MyInt1 = i // 這邊會出錯, 不能把一個int的值給 MyInt1這個型態
    var i2 MyInt2 = i
    fmt.Println(i1, i2)
}

./prog.go:9:6: cannot use i (type int) as type MyInt1 in assignment

Go 1.9 新特性 Type Alias 基於一個類型創建一個新類型,稱之為defintion;基於一個類型創建一個別名,稱之為alias。 MyInt1為稱之為defintion,雖然底層類型為int類型,但是不能直接賦值,需要強轉; MyInt2稱之為alias,可以直接賦值。i2 = 9


25.編譯執行下面代碼會出現什麼?

https://go.dev/play/p/uMm2CKBiehu

package main

import "fmt"

type User struct {
}
type MyUser1 User
type MyUser2 = User

func (i MyUser1) m1() {
    fmt.Println("MyUser1.m1")
}
func (i User) m2() {
    fmt.Println("User.m2")
}

func main() {
    var i1 MyUser1
    var i2 MyUser2
    i1.m1() // MyUser1.m1
    i2.m2() // User.m2
}

/*
MyUser1.m1
User.m2
*/

因為MyUser2完全等價於User,所以具有其所有的方法,並且其中一個新增了方法,另外一個也會有。但是i1.m2() 是不能執行的,因為MyUser1沒有定義該方法


26.編譯執行下面代碼會出現什麼?

https://go.dev/play/p/Ae_aNvhwRX6

package main

import "fmt"

type T1 struct {
}

func (t T1) m1() {
    fmt.Println("T1.m1")
}

type T2 = T1
type MyStruct struct {
    T1
    T2
}

func main() {
    my := MyStruct{}
    my.m1() // 這邊會出錯, 會不知道是誰的m1() function
}
// ./prog.go:20:4: ambiguous selector my.m1

結果不限於方法,字段也也一樣;也不限於type alias,type defintion也是一樣的,只要有重複的方法、字段,就會有這種提示,因為不知道該選擇哪個。

解法

https://go.dev/play/p/R_C0E136fN8

my.T1.m1()
my.T2.m1()

27.編譯執行下面代碼會出現什麼?

https://play.golang.org/p/LG-EcwE5yqL

package main

import (
    "errors"
    "fmt"
)

var ErrDidNotWork = errors.New("did not work")

func DoTheThing(reallyDoIt bool) (err error) {
    if reallyDoIt {
        result, err := tryTheThing()
        if err != nil || result != "it worked" {
            err = ErrDidNotWork
        }
    }

    return err
}

func tryTheThing() (string, error) {
    return "", ErrDidNotWork
}

func main() {
    fmt.Println(DoTheThing(true))
    fmt.Println(DoTheThing(false))
}

/*
<nil>
<nil>
*/

因為 if 語句塊內的 err 變量會遮罩函數作用域內的 err 變量

解法

https://play.golang.org/p/Ir-rIeK7r3V

func DoTheThing(reallyDoIt bool) (err error) {
    var result string
    if reallyDoIt {
        result, err = tryTheThing()
        if err != nil || result != "it worked" {
            err = ErrDidNotWork
        }
    }
    return err
}

28.編譯執行下面代碼會出現什麼?

https://go.dev/play/p/sJfSHHrjdw3

package main

func test() []func()  {
    var funs []func()
    for i:=0;i<2 ;i++  {
        funs = append(funs, func() {
            println(&i,i)
        })
    }
    return funs
}

func main(){
    funs:=test()
    for _,f:=range funs{
        f()
    }
}
/*
0xc00002c008 2
0xc00002c008 2
*/

考點:閉包延遲求值 for循環復用局部變量i,每一次放入匿名函數的應用都是想一個變量。

解法

https://go.dev/play/p/5R1KtBjKyZX

func test2() []func()  {
    var funs []func()
    for i:=0;i<2 ;i++  {
        x:=i
        funs = append(funs, func() {
            println(&x,x)
        })
    }
    return funs
}
/*
0xc000096000 0
0xc000096008 1
*/

29.編譯執行下面代碼會出現什麼? 閉包引用相同變數

閉包引用相同變數 https://go.dev/play/p/NtAXXtNWgXo

package main

func test(x int) (func(),func())  {
    return func() {
        println(x)
        x+=10
    }, func() {
        println(x)
    }
}

func main()  {
    a,b:=test(100)
    a() // 100
    b() // 110
}
/*
100
110
*/

閉包引用相同變數


30.編譯執行下面代碼會出現什麼?

panic 只有最後一個可以被 recover 捕獲, panic("panic") -> defer的panic("defer panic") 是最後一個 panic

package main

import (
    "fmt"
)

func main()  {
    defer func() {
       if err:=recover();err!=nil{   // 收到2的panic
           fmt.Println(err)
       }else {
           fmt.Println("fatal")
       }
    }()

    defer func() {
        panic("defer panic") // 2 觸發
    }()

    panic("panic") // 1 觸發
}

// defer panic

考點:panic僅有最後一個可以被revover捕獲 觸發panic("panic")後順序執行defer,但是defer中還有一個panic,所以覆蓋了之前的panic("panic")

© Kimi Tsai all right reserved.            Updated : 2023-07-12 09:04:53

results matching ""

    No results matching ""

    results matching ""

      No results matching ""