1. 程式人生 > >Golang面試題解析

Golang面試題解析

12.是否可以編譯通過?如果通過,輸出什麼?

func main() {
	i := GetValue()

	switch i.(type) {
	case int:
		println("int")
	case string:
		println("string")
	case interface{}:
		println("interface")
	default:
		println("unknown")
	}

}

func GetValue() int {
	return 1
}

解析

考點:type

編譯失敗,因為type只能使用在interface

13.下面函式有什麼問題?

func funcMui(x,y int)(sum int,error){
    return x+y,nil
}

解析

考點:函式返回值命名
在函式有多個返回值時,只要有一個返回值有指定命名,其他的也必須有命名。 如果返回值有有多個返回值必須加上括號; 如果只有一個返回值並且有命名也需要加上括號; 此處函式第一個返回值有sum名稱,第二個未命名,所以錯誤。

14.是否可以編譯通過?如果通過,輸出什麼?

package main

func main() {

	println(DeferFunc1(1))
	println(DeferFunc2(1))
	println(DeferFunc3(1))
}

func DeferFunc1(i int) (t int) {
	t = i
	defer func() {
		t += 3
	}()
	return t
}

func DeferFunc2(i int) int {
	t := i
	defer func() {
		t += 3
	}()
	return t
}

func DeferFunc3(i int) (t int) {
	defer func() {
		t += i
	}()
	return 2
}

解析

考點:defer和函式返回值
需要明確一點是defer需要在函式結束前執行。 函式返回值名字會在函式起始處被初始化為對應型別的零值並且作用域為整個函式 DeferFunc1有函式返回值t作用域為整個函式,在return之前defer會被執行,所以t會被修改,返回4; DeferFunc2函式中t的作用域為函式,返回1; DeferFunc3返回3

15.是否可以編譯通過?如果通過,輸出什麼?

func main() {
	list := new([]int)
	list = append(list, 1)
	fmt.Println(list)
}

解析

考點:new
list:=make([]int,0)

16.是否可以編譯通過?如果通過,輸出什麼?

package main

import "fmt"

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

解析

考點:append
append切片時候別漏了'...'

17.是否可以編譯通過?如果通過,輸出什麼?

func main() {

	sn1 := struct {
		age  int
		name string
	}{age: 11, name: "qq"}
	sn2 := struct {
		age  int
		name string
	}{age: 11, name: "qq"}

	if sn1 == sn2 {
		fmt.Println("sn1 == sn2")
	}

	sm1 := struct {
		age int
		m   map[string]string
	}{age: 11, m: map[string]string{"a": "1"}}
	sm2 := struct {
		age int
		m   map[string]string
	}{age: 11, m: map[string]string{"a": "1"}}

	if sm1 == sm2 {
		fmt.Println("sm1 == sm2")
	}
}

解析

考點:結構體比較
進行結構體比較時候,只有相同型別的結構體才可以比較,結構體是否相同不但與屬性型別個數有關,還與屬性順序相關。

sn3:= struct {
    name string
    age  int
}{age:11,name:"qq"}

sn3與sn1就不是相同的結構體了,不能比較。 還有一點需要注意的是結構體是相同的,但是結構體屬性中有不可以比較的型別,如map,slice。 如果該結構屬性都是可以比較的,那麼就可以使用“==”進行比較操作。

可以使用reflect.DeepEqual進行比較

if reflect.DeepEqual(sn1, sm) {
    fmt.Println("sn1 ==sm")
}else {
    fmt.Println("sn1 !=sm")
}

所以編譯不通過: invalid operation: sm1 == sm2

18.是否可以編譯通過?如果通過,輸出什麼?

func Foo(x interface{}) {
	if x == nil {
		fmt.Println("empty interface")
		return
	}
	fmt.Println("non-empty interface")
}
func main() {
	var x *int = nil
	Foo(x)
}

解析

考點:interface內部結構

non-empty interface

19.是否可以編譯通過?如果通過,輸出什麼?

func GetValue(m map[int]string, id int) (string, bool) {
	if _, exist := m[id]; exist {
		return "存在資料", true
	}
	return nil, false
}
func main()  {
	intmap:=map[int]string{
		1:"a",
		2:"bb",
		3:"ccc",
	}

	v,err:=GetValue(intmap,3)
	fmt.Println(v,err)
}

解析

考點:函式返回值型別
nil 可以用作 interface、function、pointer、map、slice 和 channel 的“空值”。但是如果不特別指定的話,Go 語言不能識別型別,所以會報錯。報:cannot use nil as type string in return argument.

20.是否可以編譯通過?如果通過,輸出什麼?

const (
	x = iota
	y
	z = "zz"
	k
	p = iota
)

func main()  {
	fmt.Println(x,y,z,k,p)
}

解析

考點:iota
結果:

0 1 zz zz 4