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
解析:
知识点: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 = 65 或 var 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 的元素。
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 实现该方法。
最后更新于