31-60

31. 定义一个包内全局字符串变量,下面语法正确的是()

  • A. var str string

  • B. str := ""

  • C. str = ""

  • D. var str = ""

答:A、D

解析:

B 只支持局部变量声明;C 是赋值,str 必须在这之前已经声明

32. 下面这段代码输出什么?

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

答:5

解析:

这个例子中,hello() 函数的参数在执行 defer 语句的时候会保存一份副本,在实际调用 hello() 函数时用,所以是 5.

33. 下面这段代码输出什么?

答:

解析:

知识点:结构体嵌套。这道题可以结合第 12 天的第三题一起看,Teacher 没有自己 ShowA(),所以调用内部类型 People 的同名方法,需要注意的是第 5 行代码调用的是 People 自己的 ShowB 方法。

34. 下面代码输出什么?

  • A. hello

  • B. xello

  • C. compilation error

答:C

解析:

知识点:常量

Go 语言中的字符串是只读的。

35. 下面代码输出什么?

  • A. 1

  • B. 2

  • C. 3

答:B

解析:

知识点:指针

incr() 函数里的 p 是 *int 类型的指针,指向的是 main() 函数的变量 p 的地址。第 2 行代码是将该地址的值执行一个自增操作,incr() 返回自增后的结果。

36. 对 add() 函数调用正确的是()

  • A. add(1, 2)

  • B. add(1, 3, 7)

  • C. add([]int{1, 2})

  • D. add([]int{1, 3, 7}…)

答:ABD

解析:

知识点:可变函数

37. 下面代码下划线处可以填入哪个选项以输出yes nil?

  • A. s1

  • B. s2

  • C. s1、s2 都可以

答:A

解析:

讨论 #6

知识点:nil 切片和空切片。

nil 切片和 nil 相等,一般用来表示一个不存在的切片;空切片和 nil 不相等,表示一个空的集合。

38. 下面这段代码输出什么?

  • A. A

  • B. 65

  • C. compilation error

答:A

解析:

UTF-8 编码中,十进制数字 65 对应的符号是 A。但是在Goland中会有警告 Conversion from int to string interprets an integer value as a code point, 推荐使用 var i byte = 65var i uint8 = 65 替代

39. 下面这段代码输出什么?

答:13 23

解析:

知识点:接口。

一种类型实现多个接口,结构体 Work 分别实现了接口 A、B,所以接口变量 a、b 调用各自的方法 ShowA() 和 ShowB(),输出 13、23。

40. 切片 a、b、c 的长度和容量分别是多少?

答:0 3、2 3、1 2

解析:

知识点:数组或切片的截取操作。

截取操作有带 2 个或者 3 个参数,形如:[i:j] 和 [i:j:k],假设截取对象的底层数组长度为 l。在操作符 [i:j] 中,如果 i 省略,默认 0,如果 j 省略,默认底层数组的长度,截取得到的切片长度和容量计算方法是 j-i、l-i。操作符 [i:j:k],k 主要是用来限制切片的容量,但是不能大于数组的长度 l,截取得到的切片长度和容量计算方法是 j-i、k-i

41. 下面代码中 A B 两处应该怎么修改才能顺利编译?

解析:

在 A 处只声明了map m ,并没有分配内存空间,不能直接赋值,需要使用 make(),都提倡使用 make() 或者字面量的方式直接初始化 map。

B 处,v,k := m["b"] 当 key 为 b 的元素不存在的时候,v 会返回值类型对应的零值,k 返回 false。

42. 下面代码输出什么?

  • A. 23 13

  • B. compilation error

答:B

解析:

知识点:接口的静态类型。

a、b 具有相同的动态类型和动态值,分别是结构体 work 和 {3};a 的静态类型是 A,b 的静态类型是 B,接口 A 不包括方法 ShowB(),接口 B 也不包括方法 ShowA(),编译报错。看下编译错误:

43. 下面代码中,x 已声明,y 没有声明,判断每条语句的对错。

答:错、对、对、错

解析:

知识点:变量的声明。

1.错,x 已经声明,不能使用 :=;2.对;3.对,当多值赋值时,:= 左边的变量无论声明与否都可以;4.错,y 没有声明。

44. 下面代码输出什么?

  • A. 1 1

  • B. 0 1

  • C. 1 0

  • D. 0 0

答:B

解析:

知识点:defer、返回值。

注意一下,increaseA() 的返回参数是匿名,increaseB() 是具名。关于 defer 与返回值的知识点,后面我会写篇文章详细分析,到时候可以看下文章的讲解。

45. 下面代码输出什么?

  • A. 13 23

  • B. compilation error

答:A

解析:

知识点:类型断言。

46. f1()、f2()、f3() 函数分别返回什么?

答:1 5 1

解析:

知识点:defer函数的执行顺序。

47. 下面代码段输出什么?

答:29 29 28

解析:

知识点:defer函数的执行顺序。

变量 person 是一个指针变量 。

1.person.age 此时是将 28 当做 defer 函数的参数,会把 28 缓存在栈中,等到最后执行该 defer 语句的时候取出,即输出 28;

2.defer 缓存的是结构体 Person{28} 的地址,最终 Person{28} 的 age 被重新赋值为 29,所以 defer 语句最后执行的时候,依靠缓存的地址取出的 age 便是 29,即输出 29;

3.闭包引用,输出 29;

又由于 defer 的执行顺序为先进后出,即 3 2 1,所以输出 29 29 28。

48. 下面这段代码正确的输出是什么?

  • A. F M D

  • B. D F M

  • C. F D M

答:C

解析:

被调用函数里的 defer 语句在返回之前就会被执行,所以输出顺序是 F D M。

49. 下面代码输出什么?

答:29 28 28

解析:

知识点:defer函数的执行顺序。

这道题在第 47 题目的基础上做了一点点小改动,前一题最后一行代码 person.age = 29 是修改引用对象的成员 age,这题最后一行代码 person = &Person{29} 是修改引用对象本身,来看看有什么区别。

1处.person.age 这一行代码跟之前含义是一样的,此时是将 28 当做 defer 函数的参数,会把 28 缓存在栈中,等到最后执行该 defer 语句的时候取出,即输出 28;

2处.defer 缓存的是结构体 Person{28} 的地址,这个地址指向的结构体没有被改变,最后 defer 语句后面的函数执行的时候取出仍是 28;

3处.闭包引用,person 的值已经被改变,指向结构体 Person{29},所以输出 29.

由于 defer 的执行顺序为先进后出,即 3 2 1,所以输出 29 28 28。

50. 下面的两个切片声明中有什么区别?哪个更可取?

答:29 28 28

解析:

A 声明的是 nil 切片;B 声明的是长度和容量都为 0 的空切片。第一种切片声明不会分配内存,优先选择。

51. A、B、C、D 哪些选项有语法错误?

答:BD

解析:

函数参数为 interface{} 时可以接收任何类型的参数,包括用户自定义类型等,即使是接收指针类型也用 interface{},而不是使用 *interface{}。

52. 下面 A、B 两处应该填入什么代码,才能确保顺利打印出结果?

答:

解析:

f() 函数返回参数是指针类型,所以可以用 & 取结构体的指针;B 处,如果填*f(),则 p 是 S 类型;如果填 f(),则 p 是 *S 类型,不过都可以使用 p.m取得结构体的成员。

53. 下面的代码有几处语法问题,各是什么?

解析:

两个地方有语法问题。golang 的字符串类型是不能赋值 nil 的,也不能跟 nil 比较。

54. return 之后的 defer 语句会执行吗,下面这段代码输出什么?

答:2 1

解析:

defer 关键字后面的函数或者方法想要执行必须先注册,return 之后的 defer 是不能注册的, 也就不能执行后面的函数或方法。

55. 下面这段代码输出什么?为什么?

答:

解析:

我们知道,golang 中切片底层的数据结构是数组。当使用 s1[1:] 获得切片 s2,和 s1 共享同一个底层数组,这会导致 s2[1] = 4 语句影响 s1。

而 append 操作会导致底层数组扩容,生成新的数组,因此追加数据后的 s2 不会影响 s1。

但是为什么对 s2 赋值后影响的却是 s1 的第三个元素呢?这是因为切片 s2 是从数组的第二个元素开始,s2 索引为 1 的元素对应的是 s1 索引为 2 的元素。

golang

56. 下面选项正确的是?

  • A. 1 2

  • B. compilation error

答:A

解析:

知识点:代码块和变量作用域。

57. 下面这段代码输出什么?

答:

解析:

map 的输出是无序的。

58. 下面这段代码输出什么?

答:

解析:

程序执行到 main() 函数三行代码的时候,会先执行 calc() 函数的 b 参数,即:calc("10",a,b),输出:10 1 2 3,得到值 3,因为 defer 定义的函数是延迟函数,故 calc("1",1,3) 会被延迟执行;

程序执行到第五行的时候,同样先执行 calc("20",a,b) 输出:20 0 2 2 得到值 2,同样将 calc("2",0,2) 延迟执行;

程序执行到末尾的时候,按照栈先进后出的方式依次执行:calc("2",0,2),calc("1",1,3),则就依次输出:2 0 2 2,1 1 3 4。

59. 下面这段代码输出什么?为什么?

  • A. 1

  • B. compilation error

答:B

解析:

基于类型创建的方法必须定义在同一个包内,上面的代码基于 int 类型创建了 PrintInt() 方法,由于 int 类型和方法 PrintInt() 定义在不同的包内,所以编译出错。

解决的办法可以定义一种新的类型:

60. 下面这段代码输出什么?为什么?

  • A. speak

  • B. compilation error

答:B

解析:

编译错误 Student does not implement People (Speak method has pointer receiver),值类型 Student 没有实现接口的 Speak() 方法,而是指针类型 *Student 实现该方法。

最后更新于