Golang面試題 練習(xí)題

整理自golang中文網(wǎng)https://studygolang.com/ 以及公眾號(hào) golang來(lái)啦 (侵刪)

不管面試?yán)镉貌挥玫玫窖艟啵f(wàn)丈高樓平地起,先得從基礎(chǔ)做起

package main
 
import (
     "fmt"
)
 
 func main() {
    defer_call()
 }

func defer_call() {
   defer func() { fmt.Println("打印前") }()
   defer func() { fmt.Println("打印中") }()    
   defer func() { fmt.Println("打印后") }()
   panic("觸發(fā)異常")
}

答案:

打印后
打印中
打印前
觸發(fā)異常

參考解析:defer 的執(zhí)行順序是后進(jìn)先出千诬。當(dāng)出現(xiàn) panic 語(yǔ)句的時(shí)候滔吠,會(huì)先按照 defer 的后進(jìn)先出的順序執(zhí)行民褂,最后才會(huì)執(zhí)行panic设哗。

func main() {
     slice := []int{0,1,2,3}
     m := make(map[int]*int)
     for key,val := range slice {
         m[key] = &val
     }

    for k,v := range m {
        fmt.Println(k,"->",*v)
    }
}

答案:

0 -> 3
0 -> 3
0 -> 3
0 -> 3

參考解析:這是新手常會(huì)犯的錯(cuò)誤寫法柳弄,for range 循環(huán)的時(shí)候會(huì)創(chuàng)建每個(gè)元素的副本舶胀,而不是元素的引用,所以 m[key] = &val 取的都是變量 val 的地址碧注,所以最后 map 中的所有元素的值都是變量 val 的地址嚣伐,因?yàn)樽詈?val 被賦值為3,所有輸出都是3.

3.下面兩段代碼輸出什么

// 1.
func main() {
   s := make([]int, 5)
   s = append(s, 1, 2, 3)
   fmt.Println(s)
}

// 2.
func main() {
    s := make([]int,0)
    s = append(s,1,2,3,4)
    fmt.Println(s)
}

答案:

[0 0 0 0 0 1 2 3  ]
[1 2 3 4]

參考解析:這道題考的是使用 append 向 slice 添加元素萍丐,第一段代碼常見(jiàn)的錯(cuò)誤是 [1 2 3]轩端,需要注意
make 分配slice內(nèi)存元素默認(rèn)分配0值, slice內(nèi)存不足底層數(shù)組會(huì)重新分配

4.下面這段代碼有什么缺陷

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

答案: 返回第二個(gè)參數(shù)未命名
參考解析:
在函數(shù)有多個(gè)返回值時(shí)逝变,只要有一個(gè)返回值有命名基茵,其他的也必須命名。如果有多個(gè)返回值必須加上括號(hào)()壳影;如果只有一個(gè)返回值且命名也必須加上括號(hào)()拱层。這里的第一個(gè)返回值有命名 sum,第二個(gè)沒(méi)有命名态贤,所以錯(cuò)誤舱呻。

5.new() 與 make() 的區(qū)別
參考答案:
new(T) 和 make(T,args) 是 Go 語(yǔ)言內(nèi)建函數(shù),用來(lái)分配內(nèi)存,但適用的類型不同箱吕。

new(T) 會(huì)為 T 類型的新值分配已置零的內(nèi)存空間芥驳,并返回地址(指針),即類型為 *T 的值茬高。換句話說(shuō)就是兆旬,返回一個(gè)指針,該指針指向新分配的怎栽、類型為 T 的零值丽猬。適用于值類型,如數(shù)組熏瞄、結(jié)構(gòu)體等脚祟。

make(T,args) 返回初始化之后的 T 類型的值,這個(gè)值并不是 T 類型的零值强饮,也不是指針 *T由桌,是經(jīng)過(guò)初始化之后的 T 的引用。make() 只適用于 slice邮丰、map 和 channel.

6.下面這段代碼能否通過(guò)編譯行您,不能的話原因是什么;如果能剪廉,輸出什么

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

參考答案及解析:不能通過(guò)編譯娃循,new([]int) 之后的 list 是一個(gè) *[]int 類型的指針,不能對(duì)指針執(zhí)行 append 操作斗蒋“聘可以使用 make() 初始化之后再用。同樣的吹泡,map 和 channel 建議使用 make() 或字面量的方式初始化骤星,不要用 new() 。

7.下面這段代碼能否通過(guò)編譯爆哑,如果可以,輸出什么舆吮?

func main() {
    s1 := []int{1, 2, 3}
    s2 := []int{4, 5}
    s1 = append(s1, s2)
    fmt.Println(s1)
}
參考答案及解析:不能通過(guò)編譯揭朝。append() 的第二個(gè)參數(shù)不能直接使用 slice,需使用 … 操作符色冀,將一個(gè)切片追加到另一個(gè)切片上:append(s1,s2…)潭袱。或者直接跟上元素锋恬,形如:append(s1,1,2,3)屯换。

8.下面這段代碼能否通過(guò)編譯,如果可以,輸出什么彤悔?

var(
    size := 1024
    max_size = size*2
)

func main() {
    fmt.Println(size,max_size)
}
參考答案及解析:不能通過(guò)編譯嘉抓。這道題的主要知識(shí)點(diǎn)是變量聲明的簡(jiǎn)短模式,形如:x := 100晕窑。但這種聲明方式有限制:
必須使用顯示初始化抑片;
不能提供數(shù)據(jù)類型,編譯器會(huì)自動(dòng)推導(dǎo)杨赤;
只能在函數(shù)內(nèi)部使用簡(jiǎn)短模式敞斋;

9.下面這段代碼能否通過(guò)編譯?不能的話疾牲,原因是什么植捎?如果通過(guò),輸出什么阳柔?

  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")
    }
 }

參考答案及解析:編譯不通過(guò) invalid operation: sm1 == sm2

這道題目考的是結(jié)構(gòu)體的比較焰枢,有幾個(gè)需要注意的地方:

1>. 結(jié)構(gòu)體只能比較是否相等,但是不能比較大小盔沫。

2>. 相同類型的結(jié)構(gòu)體才能夠進(jìn)行比較医咨,結(jié)構(gòu)體是否相同不但與屬性類型有關(guān),還與屬性順序相關(guān)架诞,sn3 與 sn1 就是不同的結(jié)構(gòu)體拟淮;

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

3>. 如果 struct 的所有成員都可以比較,則該 struct 就可以通過(guò) == 或 != 進(jìn)行比較是否相等谴忧,比較時(shí)逐個(gè)項(xiàng)進(jìn)行比較很泊,如果每一項(xiàng)都相等,則兩個(gè)結(jié)構(gòu)體才相等沾谓,否則不相等委造;

那什么是可比較的呢,常見(jiàn)的有 bool均驶、數(shù)值型昏兆、字符、指針妇穴、數(shù)組等爬虱,像切片、map腾它、函數(shù)等是不能比較的跑筝。 具體可以參考 Go 說(shuō)明文檔。http://docs.studygolang.com/ref/spec#Comparison_operators

10.通過(guò)指針變量 p 訪問(wèn)其成員變量 name瞒滴,有哪幾種方式曲梗?
A.p.name
B.(&p).name
C.(*p).name
D.p->name
參考答案及解析:A C

11.下面這段代碼能否通過(guò)編譯?如果通過(guò),輸出什么虏两?

 package main
 
 import "fmt"
 
 type MyInt1 int
 type MyInt2 = int
 
func main() {
    var i int =0
    var i1 MyInt1 = i 
    var i2 MyInt2 = i
    fmt.Println(i1,i2)
}

參考答案及解析:編譯不通過(guò)愧旦,cannot use i (type int) as type MyInt1 in assignment。

這道題考的是類型別名與類型定義的區(qū)別碘举。

第 5 行代碼是基于類型 int 創(chuàng)建了新類型 MyInt1忘瓦,第 6 行代碼是創(chuàng)建了 int 的類型別名 MyInt2陶衅,注意類型別名的定義時(shí) = 么介。所以豌骏,第 10 行代碼相當(dāng)于是將 int 類型的變量賦值給 MyInt1 類型的變量方面,Go 是強(qiáng)類型語(yǔ)言服猪,編譯當(dāng)然不通過(guò)巷送;而 MyInt2 只是 int 的別名醉拓,本質(zhì)上還是 int圈盔,可以賦值售滤。

第 10 行代碼的賦值可以使用強(qiáng)制類型轉(zhuǎn)化 var i1 MyInt1 = MyInt1(i).

12.關(guān)于字符串連接罚拟,下面語(yǔ)法正確的是?

A. str := 'abc' + '123'
B. str := "abc" + "123"
C. str := '123' + "abc"
D. fmt.Sprintf("abc%d", 123)

參考答案:B D

知識(shí)點(diǎn):字符串連接完箩。除了以上兩種連接方式赐俗,還有 strings.Join()、buffer.WriteString()等

13.下面這段代碼能否編譯通過(guò)弊知?如果可以阻逮,輸出什么?

package main

import "fmt"

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

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

參考答案及解析:編譯通過(guò)秩彤,輸出:0 2 zz zz 5叔扼。知識(shí)點(diǎn):iota 的使用。給大家貼篇文章漫雷,講的很詳細(xì)
https://www.cnblogs.com/zsy/p/5370052.html

14.下面賦值正確的是()

A. var x = nil
B. var x interface{} = nil
C. var x string = nil
D. var x error = nil

B D

參考答案及解析:BD瓜富。知識(shí)點(diǎn):nil 值。nil 只能賦值給指針降盹、chan与柑、func、interface蓄坏、map 或 slice 類型的變量仅胞。強(qiáng)調(diào)下 D 選項(xiàng)的 error 類型,它是一種內(nèi)置接口類型剑辫,看下方貼出的源碼就知道,所以 D 是對(duì)的渠欺。

type error interface {
    Error() string
}

15.關(guān)于init函數(shù)妹蔽,下面說(shuō)法正確的是()

A. 一個(gè)包中,可以包含多個(gè) init 函數(shù);
B. 程序編譯時(shí)胳岂,先執(zhí)行依賴包的 init 函數(shù)编整,再執(zhí)行 main 包內(nèi)的 init 函數(shù);
C. main 包中乳丰,不能有 init 函數(shù)掌测;
D. init 函數(shù)可以被其他函數(shù)調(diào)用;
參考答案及解析:AB
關(guān)于 init() 函數(shù)有幾個(gè)需要注意的地方:

1> init() 函數(shù)是用于程序執(zhí)行前做包的初始化的函數(shù)产园,比如初始化包里的變量等;
2>一個(gè)包可以出線多個(gè) init() 函數(shù),一個(gè)源文件也可以包含多個(gè) init() 函數(shù)汞斧;
3> 同一個(gè)包中多個(gè) init() 函數(shù)的執(zhí)行順序沒(méi)有明確定義,但是不同包的init函數(shù)是根據(jù)包導(dǎo)入的依賴關(guān)系決定的(看下圖);


image.png

init() 函數(shù)在代碼中不能被顯示調(diào)用什燕、不能被引用(賦值給函數(shù)變量)粘勒,否則出現(xiàn)編譯錯(cuò)誤;
一個(gè)包被引用多次,如 A import B,C import B,A import C屎即,B 被引用多次庙睡,但 B 包只會(huì)初始化一次;
引入包技俐,不可出現(xiàn)死循壞乘陪。即 A import B,B import A,這種情況編譯失數窭蕖啡邑;

16.下面這段代碼輸出什么以及原因?

 func hello() []string {  
     return nil
 }
 
 func main() {  
     h := hello
     if h == nil {
         fmt.Println("nil")
     } else {
        fmt.Println("not nil")
     }
}

A. nil
B. not nil
C. compilation error

答案及解析:B捂刺。這道題目里面谣拣,是將 hello() 賦值給變量 h,而不是函數(shù)的返回值族展,所以輸出 not nil森缠。

17.下面這段代碼能否編譯通過(guò)?如果可以仪缸,輸出什么贵涵?

func GetValue() int {
     return 1
 }
 
 func main() {
     i := GetValue()
     switch i.(type) {
     case int:
       println("int")
     case string:
        println("string")
    case interface{}:
        println("interface")
    default:
        println("unknown")
    }
}

參考答案及解析:編譯失敗∏』考點(diǎn):類型選擇宾茂,類型選擇的語(yǔ)法形如:i.(type),其中 i 是接口拴还,type 是固定關(guān)鍵字跨晴,需要注意的是,只有接口類型才可以使用類型選擇片林《伺瑁看下關(guān)于接口的文章怀骤。

18.關(guān)于channel,下面語(yǔ)法正確的是()

A. var ch chan int
B. ch := make(chan int)
C. <- ch
D. ch <-

參考答案及解析:ABC焕妙。A蒋伦、B都是聲明 channel;C 讀取 channel焚鹊;寫 channel 是必須帶上值痕届,所以 D 錯(cuò)誤。

19.下面這段代碼輸出什么末患?
A.0
B.1
C.Compilation error

type person struct {  
    name string
}

func main() {  
    var m map[person]int
    p := person{"mike"}
    fmt.Println(m[p])
}

參考答案及解析:A研叫。打印一個(gè) map 中不存在的值時(shí),返回元素類型的零值阻塑。這個(gè)例子中蓝撇,m 的類型是 map[person]int,因?yàn)?m 中不存在 p陈莽,所以打印 int 類型的零值渤昌,即 0。

20.下面這段代碼輸出什么走搁?

A.18
B.5
C.Compilation error

func hello(num ...int) {  
    num[0] = 18
}

func main() {  
    i := []int{5, 6, 7}
    hello(i...)
    fmt.Println(i[0])
}

參考答案及解析:A 独柑。...語(yǔ)法糖把切片傳入只要不發(fā)生擴(kuò)容就會(huì)影響到原始切片

21.下面這段代碼輸出什么?

func main() {  
    a := 5
    b := 8.1
    fmt.Println(a + b)
}

A.13.1
B.13
C.compilation error

參考答案及解析:C私植。a 的類型是 int忌栅,b 的類型是 float,兩個(gè)不同類型的數(shù)值不能相加曲稼,編譯報(bào)錯(cuò)索绪。

22.下面這段代碼輸出什么?

package main

import (  
    "fmt"
)

func main() {  
    a := [5]int{1, 2, 3, 4, 5}
    t := a[3:4:4]
    fmt.Println(t[0])
}

A.3
B.4
C.compilation error
參考答案及解析:B贫悄。
知識(shí)點(diǎn):操作符 [i,j]瑞驱。基于數(shù)組(切片)可以使用操作符 [i,j] 創(chuàng)建新的切片窄坦,從索引 i唤反,到索引 j 結(jié)束,截取已有數(shù)組(切片)的任意部分鸭津,返回新的切片彤侍,新切片的值包含原數(shù)組(切片)的 i 索引的值,但是不包含 j 索引的值逆趋。i盏阶、j 都是可選的,i 如果省略闻书,默認(rèn)是 0般哼,j 如果省略吴汪,默認(rèn)是原數(shù)組(切片)的長(zhǎng)度。i蒸眠、j 都不能超過(guò)這個(gè)長(zhǎng)度值。

假如底層數(shù)組的大小為 k杆融,截取之后獲得的切片的長(zhǎng)度和容量的計(jì)算方法:長(zhǎng)度:j-i楞卡,容量:k-i

截取操作符還可以有第三個(gè)參數(shù)脾歇,形如 [i,j,k]蒋腮,第三個(gè)參數(shù) k 用來(lái)限制新切片的容量,但不能超過(guò)原數(shù)組(切片)的底層數(shù)組大小藕各。截取獲得的切片的長(zhǎng)度和容量分別是:j-i池摧、k-i。

所以例子中激况,切片 t 為 [4]作彤,長(zhǎng)度和容量都是 1。

詳細(xì)的知識(shí)點(diǎn)可以看下關(guān)于切片的文章乌逐。

23.下面這段代碼輸出什么竭讳?

func main() {
    a := [2]int{5, 6}
    b := [3]int{5, 6}
    if a == b {
        fmt.Println("equal")
    } else {
        fmt.Println("not equal")
    }
}

A. compilation error
B. equal
C. not equal
參考答案及解析:A。Go 中的數(shù)組是值類型浙踢,可比較绢慢,另外一方面,數(shù)組的長(zhǎng)度也是數(shù)組類型的組成部分洛波,所以 a 和 b 是不同的類型胰舆,是不能比較的,所以編譯錯(cuò)誤蹬挤。

24.關(guān)于 cap() 函數(shù)的適用類型缚窿,下面說(shuō)法正確的是()
A. array
B. slice
C. map
D. channel

A B D
知識(shí)點(diǎn):cap(),cap() 函數(shù)不適用 map闻伶。

25.下面這段代碼輸出什么滨攻?

func main() {  
    var i interface{}
    if i == nil {
        fmt.Println("nil")
        return
    }
    fmt.Println("not nil")
}

A. nil
B. not nil
C. compilation error

參考答案及解析:A。當(dāng)且僅當(dāng)接口的動(dòng)態(tài)值和動(dòng)態(tài)類型都為 nil 時(shí)蓝翰,接口類型值才為 nil光绕。

關(guān)于接口詳細(xì)的介紹可以看下之前的文章

26.下面這段代碼輸出什么畜份?

func main() {  
    s := make(map[string]int)
    delete(s, "h")
    fmt.Println(s["h"])
}

A. runtime panic
B. 0
C. compilation error
參考答案及解析:B诞帐。刪除 map 不存在的鍵值對(duì)時(shí),不會(huì)報(bào)錯(cuò)爆雹,相當(dāng)于沒(méi)有任何作用停蕉;獲取不存在的減值對(duì)時(shí)愕鼓,返回值類型對(duì)應(yīng)的零值,所以返回 0慧起。

27.下面屬于關(guān)鍵字的是()

A.func
B.struct
C.class
D.defer

參考答案及解析:ABD菇晃。知識(shí)點(diǎn):Go 語(yǔ)言的關(guān)鍵字。Go 語(yǔ)言有 25 個(gè)關(guān)鍵字蚓挤,看下圖:


image.png

28.下面這段代碼輸出什么磺送?

func main() {  
    i := -5
    j := +5
    fmt.Printf("%+d %+d", i, j)
}

A. -5 +5
B. +5 +5
C. 0 0

參考答案及解析:A。%d表示輸出十進(jìn)制數(shù)字灿意,+表示輸出數(shù)值的符號(hào)估灿。這里不表示取反。

29.下面這段代碼輸出什么缤剧?

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.ShowB()
}

參考答案及解析:teacher showB馅袁。知識(shí)點(diǎn):結(jié)構(gòu)體嵌套。在嵌套結(jié)構(gòu)體中荒辕,People 稱為內(nèi)部類型汗销,Teacher 稱為外部類型;通過(guò)嵌套兄纺,內(nèi)部類型的屬性大溜、方法,可以為外部類型所有估脆,就好像是外部類型自己的一樣钦奋。此外,外部類型還可以定義自己的屬性和方法疙赠,甚至可以定義與內(nèi)部相同的方法付材,這樣內(nèi)部類型的方法就會(huì)被“屏蔽”。這個(gè)例子中的 ShowB() 就是同名方法圃阳。

30.定義一個(gè)包內(nèi)全局字符串變量厌衔,下面語(yǔ)法正確的是()
A. var str string
B. str := ""
C. str = ""
D. var str = ""

參考答案及解析:AD。B 只支持局部變量聲明捍岳;C 是賦值富寿,str 必須在這之前已經(jīng)聲明;

31.下面這段代碼輸出什么?

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
知識(shí)點(diǎn):結(jié)構(gòu)體嵌套锣夹。這道題可以結(jié)合第 12 天的第三題一起看页徐,Teacher 沒(méi)有自己 ShowA(),所以調(diào)用內(nèi)部類型 People 的同名方法银萍,需要注意的是第 5 行代碼調(diào)用的是 People 自己的 ShowB 方法变勇。

32.下面這段代碼輸出什么?

func hello(i int) {  
    fmt.Println(i)
}
func main() {  
    i := 5
    defer hello(i)
    i = i + 10
}

參考答案及解析:5。這個(gè)例子中贴唇,hello() 函數(shù)的參數(shù)在執(zhí)行 defer 語(yǔ)句的時(shí)候會(huì)保存一份副本搀绣,在實(shí)際調(diào)用 hello() 函數(shù)時(shí)用飞袋,所以是 5.

func main() {
    str := "hello"
    str[0] = 'x'
    fmt.Println(str)
}

A. hello
B. xello
C. compilation error

C

34.下面代碼輸出什么?

func incr(p *int) int {
    *p++
    return *p
}

func main() {
    p :=1
    incr(&p)
    fmt.Println(p)
}

A. 1
B. 2
C. 3

B

35.對(duì) add() 函數(shù)調(diào)用正確的是()

func add(args ...int) int {

    sum := 0
    for _, arg := range args {
        sum += arg
    }
    return sum
}

A. add(1, 2)
B. add(1, 3, 7)
C. add([]int{1, 2})
D. add([]int{1, 3, 7}…)
A B D

36.下面代碼下劃線處可以填入哪個(gè)選項(xiàng)链患?

func main() {
    var s1 []int
    var s2 = []int{}
    if __ == nil {
        fmt.Println("yes nil")
    }else{
        fmt.Println("no nil")
    }
}

A. s1
B. s2
C. s1巧鸭、s2 都可以

C

37.下面這段代碼輸出什么?

func main() {  
    i := 65
    fmt.Println(string(i))
}

A. A
B. 65
C. compilation error

參考答案及解析:A锣险。UTF-8 編碼中蹄皱,十進(jìn)制數(shù)字 65 對(duì)應(yīng)的符號(hào)是 A。

38.下面這段代碼輸出什么芯肤?

type A interface {
    ShowA() int
}

type B interface {
    ShowB() int
}

type Work struct {
    i int
}

func (w Work) ShowA() int {
    return w.i + 10
}

func (w Work) ShowB() int {
    return w.i + 20
}

func main() {
    c := Work{3}
    var a A = c
    var b B = c
    fmt.Println(a.ShowA())
    fmt.Println(b.ShowB())
}

13 23
參考答案及解析:13 23。知識(shí)點(diǎn):接口压鉴。一種類型實(shí)現(xiàn)多個(gè)接口崖咨,結(jié)構(gòu)體 Work 分別實(shí)現(xiàn)了接口 A、B油吭,所以接口變量 a击蹲、b 調(diào)用各自的方法 ShowA() 和 ShowB(),輸出 13婉宰、23歌豺。

39.切片 a、b心包、c 的長(zhǎng)度和容量分別是多少类咧?

func main() {
    s := [3]int{1, 2, 3}
    a := s[:0]
    b := s[:2]
    c := s[1:2:cap(s)]
}

參考答案及解析:a、b蟹腾、c 的長(zhǎng)度和容量分別是 0 3痕惋、2 3、1 2娃殖。知識(shí)點(diǎn):數(shù)組或切片的截取操作值戳。截取操作有帶 2 個(gè)或者 3 個(gè)參數(shù),形如:[i:j] 和 [i:j:k]炉爆,假設(shè)截取對(duì)象的底層數(shù)組長(zhǎng)度為 l堕虹。在操作符 [i:j] 中,如果 i 省略芬首,默認(rèn) 0赴捞,如果 j 省略,默認(rèn)底層數(shù)組的長(zhǎng)度衩辟,截取得到的切片長(zhǎng)度和容量計(jì)算方法是 j-i螟炫、l-i。操作符 [i:j:k]艺晴,k 主要是用來(lái)限制切片的容量昼钻,但是不能大于數(shù)組的長(zhǎng)度 l掸屡,截取得到的切片長(zhǎng)度和容量計(jì)算方法是 j-i、k-i

40.下面代碼中 A B 兩處應(yīng)該怎么修改才能順利編譯然评?

func main() {
    var m map[string]int        //A
    m["a"] = 1
    if v := m["b"]; v != nil {  //B
        fmt.Println(v)
    }
}

m := make(map[stringint])
v, ok := m["b"]; ok
在 A 處只聲明了map m ,并沒(méi)有分配內(nèi)存空間仅财,不能直接賦值,需要使用 make()碗淌,都提倡使用 make() 或者字面量的方式直接初始化 map盏求。

B 處,v,k := m["b"] 當(dāng) key 為 b 的元素不存在的時(shí)候亿眠,v 會(huì)返回值類型對(duì)應(yīng)的零值碎罚,k 返回 false。

  1. 下面代碼輸出什么纳像?
type A interface {
    ShowA() int
}

type B interface {
    ShowB() int
}

type Work struct {
    i int
}

func (w Work) ShowA() int {
    return w.i + 10
}

func (w Work) ShowB() int {
    return w.i + 20
}

func main() {
    c := Work{3}
    var a A = c
    var b B = c
    fmt.Println(a.ShowB())
    fmt.Println(b.ShowA())
}

A. 23 13
B. compilation error

參考答案及解析:B荆烈。知識(shí)點(diǎn):接口的靜態(tài)類型。a竟趾、b 具有相同的動(dòng)態(tài)類型和動(dòng)態(tài)值憔购,分別是結(jié)構(gòu)體 work 和 {3};a 的靜態(tài)類型是 A岔帽,b 的靜態(tài)類型是 B玫鸟,接口 A 不包括方法 ShowB(),接口 B 也不包括方法 ShowA()犀勒,編譯報(bào)錯(cuò)屎飘。看下編譯錯(cuò)誤:

a.ShowB undefined (type A has no field or method ShowB)
b.ShowA undefined (type B has no field or method ShowA)

42.下面代碼中账蓉,x 已聲明枚碗,y 沒(méi)有聲明,判斷每條語(yǔ)句的對(duì)錯(cuò)铸本。

 1. x, _ := f()
 2. x, _ = f()
 3. x, y := f()
 4. x, y = f()

參考答案及解析:錯(cuò)肮雨、對(duì)、對(duì)箱玷、錯(cuò)怨规。知識(shí)點(diǎn):變量的聲明。1.錯(cuò)锡足,x 已經(jīng)聲明波丰,不能使用 :=;2.對(duì)舶得;3.對(duì)掰烟,當(dāng)多值賦值時(shí),:= 左邊的變量無(wú)論聲明與否都可以;4.錯(cuò)纫骑,y 沒(méi)有聲明蝎亚。

43.下面代碼輸出什么?

func increaseA() int {
    var i int
    defer func() {
        i++
    }()
    return i
}

func increaseB() (r int) {
    defer func() {
        r++
    }()
    return r
}

func main() {
    fmt.Println(increaseA())
    fmt.Println(increaseB())
}

A. 1 1
B. 0 1
C. 1 0
D. 0 0

B

44.下面代碼輸出什么先馆?

type A interface {
    ShowA() int
}

type B interface {
    ShowB() int
}

type Work struct {
    i int
}

func (w Work) ShowA() int {
    return w.i + 10
}

func (w Work) ShowB() int {
    return w.i + 20
}

func main() {
    var a A = Work{3}
    s := a.(Work)
    fmt.Println(s.ShowA())
    fmt.Println(s.ShowB())
}

A. 13 23
B. compilation error

A 類型斷言可以用來(lái)獲取接口的底層值发框, 通常的語(yǔ)法:i.(Type), 其中i是接口,其實(shí)i是接口煤墙,Type是類型或接口梅惯。編譯時(shí)會(huì)自動(dòng)檢測(cè)i的動(dòng)態(tài)類型與type是否一致

45.f1()、f2()仿野、f3() 函數(shù)分別返回什么铣减?

func f1() (r int) {
    defer func() {
        r++
    }()
    return 0
}

func f2() (r int) {
    t := 5
    defer func() {
        t = t + 5
    }()
    return t
}

func f3() (r int) {
    defer func(r int) {
        r = r + 5
    }(r)
    return 1
}

1 5 1

46.下面的題目輸出什么?

type Person struct {
    age int
}

func main() {
    person := &Person{28}

    // 1. 
    defer fmt.Println(person.age)

    // 2.
    defer func(p *Person) {
        fmt.Println(p.age)
    }(person)  

    // 3.
    defer func() {
        fmt.Println(person.age)
    }()

    person.age = 29
}

29 29 28

47.下面代碼輸出什么脚作?

func f() {
    defer fmt.Println("D")
    fmt.Println("F")
}

func main() {
    f()
    fmt.Println("M")
}

A. F M D
B. D F M
C. F D M

C

48.下面代碼輸出什么

type Person struct {
    age int
}

func main() {
    person := &Person{28}

    // 1.
    defer fmt.Println(person.age)

    // 2.
    defer func(p *Person) {
        fmt.Println(p.age)
    }(person)

    // 3.
    defer func() {
        fmt.Println(person.age)
    }()

    person = &Person{29}
}

29 28 28

49.下面的兩個(gè)切片聲明中有什么區(qū)別徙歼?哪個(gè)更可取鳖枕?

A. var a []int
B. a := []int{}

.參考答案及解析:A 聲明的是 nil 切片;B 聲明的是長(zhǎng)度和容量都為 0 的空切片桨螺。第一種切片聲明不會(huì)分配內(nèi)存宾符,優(yōu)先選擇

50.A、B灭翔、C魏烫、D 哪些選項(xiàng)有語(yǔ)法錯(cuò)誤?

type S struct {
}

func f(x interface{}) {
}

func g(x *interface{}) {
}

func main() {
    s := S{}
    p := &s
    f(s) //A
    g(s) //B
    f(p) //C
    g(p) //D
}

B D

51.下面 A肝箱、B 兩處應(yīng)該填入什么代碼哄褒,才能確保順利打印出結(jié)果?

type S struct {
    m string
}

func f() *S {
    return __  //A
}

func main() {
    p := __    //B
    fmt.Println(p.m) //print "foo"
}

A. &S{"foo"}
B. *f() 或者 f()

f() 函數(shù)返回參數(shù)是指針類型煌张,所以可以用 & 取結(jié)構(gòu)體的指針呐赡;B 處,如果填 *f()骏融,則 p 是 S 類型链嘀;如果填 f(),則 p 是 *S 類型档玻,不過(guò)都可以使用 p.m 取得結(jié)構(gòu)體的成員

52.下面的代碼各有幾處語(yǔ)法問(wèn)題怀泊,各是什么失都?

package main

import (
    "fmt"
)
func main() {
    var x string = nil

    if x == nil {
        x = "default"
    }
    fmt.Println(x)
}

string 不能是nil 不能和nil 比較

53.return 之后的 defer 語(yǔ)句會(huì)執(zhí)行嗎及汉,下面這段代碼輸出什么?

var a bool = true
func main() {
    defer func(){
        fmt.Println("1")
    }()
    if a == true {
        fmt.Println("2")
        return
    }
    defer func(){
        fmt.Println("3")
    }()
}

參考答案及解析:2 1丰嘉。defer 關(guān)鍵字后面的函數(shù)或者方法想要執(zhí)行必須先注冊(cè),return 之后的 defer 是不能注冊(cè)的枣申, 也就不能執(zhí)行后面的函數(shù)或方法售葡。

54.下面這段代碼輸出什么?為什么糯而?

func main() {

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

我們知道天通,golang 中切片底層的數(shù)據(jù)結(jié)構(gòu)是數(shù)組。當(dāng)使用 s1[1:] 獲得切片 s2熄驼,和 s1 共享同一個(gè)底層數(shù)組像寒,這會(huì)導(dǎo)致 s2[1] = 4 語(yǔ)句影響 s1。

而 append 操作會(huì)導(dǎo)致底層數(shù)組擴(kuò)容瓜贾,生成新的數(shù)組诺祸,因此追加數(shù)據(jù)后的 s2 不會(huì)影響 s1。

但是為什么對(duì) s2 賦值后影響的卻是 s1 的第三個(gè)元素呢祭芦?這是因?yàn)榍衅?s2 是從數(shù)組的第二個(gè)元素開始筷笨,s2 索引為 1 的元素對(duì)應(yīng)的是 s1 索引為 2 的元素。

image

55.下面選項(xiàng)正確的是龟劲?

func main() {
    if a := 1; false {
    } else if b := 2; false {
    } else {
        println(a, b)
    }
}

A. 1 2
B. compilation error

A

56.下面這段代碼輸出什么胃夏?

func main() {
    m := map[int]string{0:"zero",1:"one"}
    for k,v := range m {
        fmt.Println(k,v)
    }
}

0 zero
1 one
或者是
1 one
0 zero

57.下面這段代碼輸出什么?

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
}

func calc(index string, a, b int) int {
    ret := a + b
    fmt.Println(index, a, b, ret)
    return ret
}

參考答案及解析:

10 1 2 3
20 0 2 2
2 0 2 2
1 1 3 4
程序執(zhí)行到 main() 函數(shù)三行代碼的時(shí)候昌跌,會(huì)先執(zhí)行 calc() 函數(shù)的 b 參數(shù)仰禀,即:calc("10",a,b),輸出:10 1 2 3蚕愤,得到值 3答恶,因?yàn)?br> defer 定義的函數(shù)是延遲函數(shù),故 calc("1",1,3) 會(huì)被延遲執(zhí)行萍诱;

程序執(zhí)行到第五行的時(shí)候悬嗓,同樣先執(zhí)行 calc("20",a,b) 輸出:20 0 2 2 得到值 2,同樣將 calc("2",0,2) 延遲執(zhí)行裕坊;

程序執(zhí)行到末尾的時(shí)候包竹,按照棧先進(jìn)后出的方式依次執(zhí)行:calc("2",0,2),calc("1",1,3)碍庵,則就依次輸出:2 0 2 2映企,1 1 3 4。

58.下面這段代碼輸出什么?為什么静浴?

func (i int) PrintInt ()  {
    fmt.Println(i)
}

func main() {
    var i int = 1
    i.PrintInt()
}

A. 1
B. compilation error

參考答案及解析:B堰氓。基于類型創(chuàng)建的方法必須定義在同一個(gè)包內(nèi)苹享,上面的代碼基于 int 類型創(chuàng)建了 PrintInt() 方法双絮,由于 int 類型和方法 PrintInt() 定義在不同的包內(nèi)浴麻,所以編譯出錯(cuò)。

59.下面這段代碼輸出什么囤攀?為什么软免?

type People interface {
    Speak(string) string
}

type Student struct{}

func (stu *Student) Speak(think string) (talk string) {
    if think == "speak" {
        talk = "speak"
    } else {
        talk = "hi"
    }
    return
}

func main() {
    var peo People = Student{}
    think := "speak"
    fmt.Println(peo.Speak(think))
}

A. speak
B. compilation error

參考答案及解析:B。編譯錯(cuò)誤 Student does not implement People (Speak method has pointer receiver)焚挠,值類型 Student 沒(méi)有實(shí)現(xiàn)接口的 Speak() 方法膏萧,而是指針類型 *Student 實(shí)現(xiàn)該方法。

60.下面這段代碼輸出什么蝌衔?

const (
    a = iota
    b = iota
)
const (
    name = "name"
    c    = iota
    d    = iota
)
func main() {
    fmt.Println(a)
    fmt.Println(b)
    fmt.Println(c)
    fmt.Println(d)
}

0 0 0 0
知識(shí)點(diǎn):iota 的用法榛泛。

iota 是 golang 語(yǔ)言的常量計(jì)數(shù)器,只能在常量的表達(dá)式中使用噩斟。

iota 在 const 關(guān)鍵字出現(xiàn)時(shí)將被重置為0曹锨,const中每新增一行常量聲明將使 iota 計(jì)數(shù)一次。

推薦閱讀:
https://studygolang.com/articles/2192

61.下面這段代碼輸出什么剃允?為什么沛简?

type People interface {
    Show()
}

type Student struct{}

func (stu *Student) Show() {

}

func main() {

    var s *Student
    if s == nil {
        fmt.Println("s is nil")
    } else {
        fmt.Println("s is not nil")
    }
    var p People = s
    if p == nil {
        fmt.Println("p is nil")
    } else {
        fmt.Println("p is not nil")
    }
}

s is nil
s is not nil

參考答案及解析:s is nil 和 p is not nil。這道題會(huì)不會(huì)有點(diǎn)詫異斥废,我們分配給變量 p 的值明明是 nil椒楣,然而 p 卻不是 nil。記住一點(diǎn)牡肉,當(dāng)且僅當(dāng)動(dòng)態(tài)值和動(dòng)態(tài)類型都為 nil 時(shí)撒顿,接口類型值才為 nil。上面的代碼荚板,給變量 p 賦值之后,p 的動(dòng)態(tài)值是 nil吩屹,但是動(dòng)態(tài)類型卻是 *Student跪另,是一個(gè) nil 指針,所以相等條件不成立煤搜。

62.下面這段代碼輸出什么免绿?

type Direction int

const (
    North Direction = iota
    East
    South
    West
)

func (d Direction) String() string {
    return [...]string{"North", "East", "South", "West"}[d]
}

func main() {
    fmt.Println(South)
}

參考答案及解析:South。知識(shí)點(diǎn):iota 的用法擦盾、類型的 String() 方法嘲驾。

根據(jù) iota 的用法推斷出 South 的值是 3;另外迹卢,如果類型定義了 String() 方法辽故,當(dāng)使用 fmt.Printf()、fmt.Print() 和 fmt.Println() 會(huì)自動(dòng)使用 String() 方法腐碱,實(shí)現(xiàn)字符串的打印誊垢。

63.下面代碼輸出什么?

type Math struct {
    x, y int
}

var m = map[string]Math{
    "foo": Math{2, 3},
}

func main() {
    m["foo"].x = 4
    fmt.Println(m["foo"].x)
}

A. 4
B. compilation error

參考答案及解析:B,編譯報(bào)錯(cuò) cannot assign to struct field m["foo"].x in map喂走。錯(cuò)誤原因:對(duì)于類似 X = Y的賦值操作殃饿,必須知道 X 的地址,才能夠?qū)?Y 的值賦給 X芋肠,但 go 中的 map 的 value 本身是不可尋址的乎芳。

有兩個(gè)解決辦法:

使用臨時(shí)變量

type Math struct {
    x, y int
}

var m = map[string]Math{
    "foo": Math{2, 3},
}

func main() {
    tmp := m["foo"]
    tmp.x = 4
    m["foo"] = tmp
    fmt.Println(m["foo"].x)
}

修改數(shù)據(jù)結(jié)構(gòu)

type Math struct {
    x, y int
}

var m = map[string]*Math{
    "foo": &Math{2, 3},
}

func main() {
    m["foo"].x = 4
    fmt.Println(m["foo"].x)
    fmt.Printf("%#v", m["foo"])   // %#v 格式化輸出詳細(xì)信息
}

64.下面的代碼有什么問(wèn)題?

func main() {
    fmt.Println([...]int{1} == [2]int{1})
    fmt.Println([]int{1} == []int{1})
}

參考答案及解析:有兩處錯(cuò)誤

go 中不同類型是不能比較的,而數(shù)組長(zhǎng)度是數(shù)組類型的一部分帖池,所以 […]int{1} 和 [2]int{1} 是兩種不同的類型奈惑,不能比較;
切片是不能比較的碘裕;

65.下面這段代碼輸出什么携取?如果編譯錯(cuò)誤的話,為什么帮孔?

var p *int

func foo() (*int, error) {
    var i int = 5
    return &i, nil
}

func bar() {
    //use p
    fmt.Println(*p)
}

func main() {
    p, err := foo()
    if err != nil {
        fmt.Println(err)
        return
    }
    bar()
    fmt.Println(*p)
}

A. 5 5
B. runtime error

參考答案及解析:B雷滋。知識(shí)點(diǎn):變量作用域。問(wèn)題出在操作符:=文兢,對(duì)于使用:=定義的變量晤斩,如果新變量與同名已定義的變量不在同一個(gè)作用域中,那么 Go 會(huì)新定義這個(gè)變量姆坚。對(duì)于本例來(lái)說(shuō)澳泵,main() 函數(shù)里的 p 是新定義的變量,會(huì)遮住全局變量 p兼呵,導(dǎo)致執(zhí)行到bar()時(shí)程序兔辅,全局變量 p 依然還是 nil,程序隨即 Crash击喂。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末维苔,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子懂昂,更是在濱河造成了極大的恐慌介时,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件凌彬,死亡現(xiàn)場(chǎng)離奇詭異沸柔,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)铲敛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門褐澎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人伐蒋,你說(shuō)我怎么就攤上這事乱凿⊥缢兀” “怎么了?”我有些...
    開封第一講書人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵徒蟆,是天一觀的道長(zhǎng)胁出。 經(jīng)常有香客問(wèn)我,道長(zhǎng)段审,這世上最難降的妖魔是什么全蝶? 我笑而不...
    開封第一講書人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮寺枉,結(jié)果婚禮上抑淫,老公的妹妹穿的比我還像新娘。我一直安慰自己姥闪,他們只是感情好始苇,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著筐喳,像睡著了一般催式。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上避归,一...
    開封第一講書人閱讀 49,166評(píng)論 1 284
  • 那天荣月,我揣著相機(jī)與錄音,去河邊找鬼梳毙。 笑死哺窄,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的账锹。 我是一名探鬼主播萌业,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼奸柬!你這毒婦竟也來(lái)了咽白?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤鸟缕,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后排抬,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體懂从,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年蹲蒲,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了番甩。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡届搁,死狀恐怖缘薛,靈堂內(nèi)的尸體忽然破棺而出窍育,到底是詐尸還是另有隱情,我是刑警寧澤宴胧,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布漱抓,位于F島的核電站,受9級(jí)特大地震影響恕齐,放射性物質(zhì)發(fā)生泄漏乞娄。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一显歧、第九天 我趴在偏房一處隱蔽的房頂上張望仪或。 院中可真熱鬧,春花似錦士骤、人聲如沸范删。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)到旦。三九已至,卻和暖如春廓块,著一層夾襖步出監(jiān)牢的瞬間厢绝,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工带猴, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留昔汉,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓拴清,卻偏偏與公主長(zhǎng)得像靶病,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子口予,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容

  • 這是16年5月份編輯的一份比較雜亂適合自己觀看的學(xué)習(xí)記錄文檔娄周,今天18年5月份再次想寫文章,發(fā)現(xiàn)簡(jiǎn)書還為我保存起的...
    Jenaral閱讀 2,733評(píng)論 2 9
  • 選擇題部分 1.(),只有在發(fā)生短路事故時(shí)或者在負(fù)荷電流較大時(shí),變流器中才會(huì)有足夠的二次電流作為繼電保護(hù)跳閘之用沪停。...
    skystarwuwei閱讀 12,768評(píng)論 0 7
  • 1. 關(guān)于診斷X線機(jī)準(zhǔn)直器的作用煤辨,錯(cuò)誤的是()。 (6.0 分) A. 顯示照射野 B. 顯示中心線 C. 屏蔽多...
    我們村我最帥閱讀 10,272評(píng)論 0 5
  • 1. 下列敘述錯(cuò)誤的是()木张。 (2.0 分) A. 質(zhì)量管理包括QA和QC一切活動(dòng)的全部過(guò)程 B. 影像質(zhì)量是指對(duì)...
    我們村我最帥閱讀 3,773評(píng)論 0 8
  • 在C語(yǔ)言中,五種基本數(shù)據(jù)類型存儲(chǔ)空間長(zhǎng)度的排列順序是: A)char B)char=int<=float C)ch...
    夏天再來(lái)閱讀 3,325評(píng)論 0 2