1-30
1. 下面这段代码输出的内容:
package main
import "fmt"
func main() {
defer_call()
}
func defer_call() {
defer func() {fmt.Println("打印前")}()
defer func() {fmt.Println("打印中")}()
defer func() {fmt.Println("打印后")}()
panic("触发异常")
}答:输出内容为:
打印后
打印中
打印前
panic: 触发异常解析: defer 的执行顺序是先进后出。出现panic语句的时候,会先按照 defer 的后进先出顺序执行,最后才会执行panic。
2. 下面这段代码输出什么,说明原因。
答:输出内容为:
解析:
for range 循环的时候会创建每个元素的副本,而不是每个元素的引用,所以 m[key] = &val 取的都是变量val的地址,所以最后 map 中的所有元素的值都是变量 val 的地址,因为最后 val 被赋值为3,所有输出的都是3。
3. 下面两段代码输出什么?
答:输出内容为:
解析:
使用 append 向 slice 中添加元素,第一题中slice容量为5,所以补5个0,第二题为0,所以不需要。
4. 下面这段代码有什么缺陷?
答:第二个返回值没有命名
解析:
在函数有多个返回值时,只要有一个返回值有命名,其他的也必须命名。如果有多个返回值必须加上括号();如果只有一个返回值且命名也需要加上括号()。这里的第一个返回值有命名sum,第二个没有命名,所以错误。
5. new() 与 make() 的区别
解析:
new(T)和make(T, args)是Go语言内建函数,用来分配内存,但适用的类型不用。new(T)会为了T类型的新值分配已置零的内存空间,并返回地址(指针),即类型为*T的值。换句话说就是,返回一个指针,该指针指向新分配的、类型为T的零值。适用于值类型,如数组、结构体等。make(T, args)返回初始化之后的T类型的值,也不是指针*T,是经过初始化之后的T的引用。make()只适用于slice、map和channel。
6. 下面这段代码能否通过编译,不能的话原因是什么;如果能,输出什么?
答:不能通过
解析:
不能通过编译, new([]int) 之后的 list 是一个 *int[] 类型的指针,不能对指针执行 append 操作。可以使用 make() 初始化之后再用。同样的, map 和 channel 建议使用 make() 或字面量的方式初始化,不要用 new 。
7. 下面这段代码能否通过编译,不能的话原因是什么;如果可以,输出什么?
答:不能通过
解析:
append() 的第二个参数不能直接使用 slice ,需使用 ... 操作符,将一个切片追加到另一个切片上: append(s1, s2...) 。或者直接跟上元素,形如: append(s1, 1, 2, 3) 。
8. 下面这段代码能否通过编译,如果可以,输出什么?
答:不能通过
解析:
这道题的主要知识点是变量的简短模式,形如:x := 100 。但这种声明方式有限制:
必须使用显示初始化;
不能提供数据类型,编译器会自动推导;
只能在函数内部使用简短模式;
9. 下面这段代码能否通过编译?不能的话,原因是什么?如果通过,输出什么?
答:不能通过,invalid operation: sm1 == sm2
解析:
考点是结构体的比较,有几个需要注意的地方:
结构体只能比较是否相等,但是不能比较大小;
想同类型的结构体才能进行比较,结构体是否相同不但与属性类型有关,还与属性顺序相关;
如果struct的所有成员都可以比较,则该struct就可以通过==或!=进行比较是否相同,比较时逐个项进行比较,如果每一项都相等,则两个结构体才相等,否则不相等;
那有什么是可以比较的呢?
常见的有bool、数值型、字符、指针、数组等
不能比较的有
slice、map、函数
10. 通过指针变量p访问其成员变量name,有哪几种方式?
A. p.name
B. (&p).name
C. (*p).name
D. p->name
答:A C
解析:
& 取址运算符, * 指针解引用
11. 下面这段代码能否通过编译?如果通过,输出什么?
答:不能通过
解析:
这道题考的是 类型别名 与 类型定义 的区别 第5行代码是基于类型 int 创建了新类型 MyInt1 ,第6行代码是创建了int的类型别名 MyInt2 ,注意类型别名的定义是 = 。所以,第10行代码相当于是将int类型的变量赋值给MyInt1类型的变量,Go是强类型语言,编译当然不通过;而MyInt2只是int的别名,本质上还是int,可以赋值。 第10行代码的赋值可以使用强制类型转换 var i1 MyInt1 = MyInt1(i)
12. 以下代码输出什么?
答:输出内容为:
解析:
因为append导致底层数组重新分配内存了,append中的a这个alice的底层数组和外面不是一个,并没有改变外面的。
13. 关于字符串连接,下面语法正确的是?
A. str := 'abc' + '123'
B. str := "abc" + "123"
C. str := '123' + "abc"
D. fmt.Sprintf("abc%d", 123)
答:B、D
解析:
在Golang中字符串用双引号,字符用单引号 字符串连接除了以上两种连接方式,还有 strings.Join() 、 buffer.WriteString() 等
14. 下面这段代码能否编译通过?如果可以,输出什么?
答:编译通过,输出:**0 2 zz zz 5**
解析:
iota初始值为0,所以x为0,_表示不赋值,但是iota是从上往下加1的,所以y是2,z是“zz”,k和上面一个同值也是“zz”,p是iota,从上0开始数他是5
15. 下面赋值正确的是()
A. var x = nil
B. var x interface{} = nil
C. var x string = nil
D. var x error = nil
答:B、D
解析:
A错在没有写类型,C错在字符串的空值是 "" 而不是nil。 知识点:nil只能赋值给指针、chan、func、interface、map、或slice、类型的变量。
16. 关于init函数,下面说法正确的是()
A. 一个包中,可以包含多个init函数;
B. 程序编译时,先执行依赖包的init函数,再执行main包内的init函数;
C. main包中,不能有init函数;
D. init函数可以被其他函数调用;
答:A、B
解析:
init()函数是用于程序执行前做包的初始化的函数,比如初始化包里的变量等;
一个包可以出现多个init()函数,一个源文件也可以包含多个init()函数;
同一个包中多个init()函数的执行顺序没有明确的定义,但是不同包的init函数是根据包导入的依赖关系决定的;
init函数在代码中不能被显示调用、不能被引用(赋值给函数变量),否则出现编译失败;
一个包被引用多次,如A import B,C import B,A import C,B被引用多次,但B包只会初始化一次;
引入包,不可出现死循环。即A import B,B import A,这种情况下编译失败;

17. 下面这段代码输出什么以及原因?
A. nil
B. not nil
C. compilation error
答:B
解析:
这道题里面,是将 hello() 赋值给变量h,而不是函数的返回值,所以输出 not nil
18. 下面这段代码能否编译通过?如果可以,输出什么?
答:编译失败
解析:
只有接口类型才能使用类型选择 类型选择的语法形如:i.(type),其中i是接口,type是固定关键字,需要注意的是,只有接口类型才可以使用类型选择。
19. 关于channel,下面语法正确的是()
A. var ch chan int
B. ch := make(chan int)
C. <-ch
D. ch<-
答:A、B、C
解析:
A、B都是申明channel;C读取channel;写channel是必须带上值,所以D错误。
20. 下面这段代码输出什么?
A. 0
B. 1
C. Compilation error
答:A
解析:
打印一个map中不存在的值时,返回元素类型的零值。这个例子中,m的类型是map[person]int,因为m中 不存在p,所以打印int类型的零值,即0。
21. 下面这段代码输出什么?
A. 18
B. 5
C. Compilation error
答:18
解析:
可变参数传递过去,改变了第一个值。
22. 下面这段代码输出什么?
A. 13.1
B. 13
C. compilation error
答:C
解析:
a 的类型是int ,b 的类型是float ,两个不同类型的数值不能相加,编译报错。
23. 下面这段代码输出什么?
A. 3
B. 4
C. compilation error
答:B
解析:
知识点:操作符
[i, j]。基于数组(切片)可以使用操作符[i, j]创建新的切片,从索引i,到索引i,到索引j结束,截取已有数组(切片)的任意部分,返回新的切片,新切片的值包含原数组(切片)的i索引的值,但是不包含j索引的值。i、j都是可选的,i如果省略,默认是0,j如果省略,默认是原数组(切片)的长度。i、j都不能超过这个长度值。假如底层数组的大小为 k,截取之后获得的切片的长度和容量的计算方法:长度:j-i,容量:k-i。
截取操作符还可以有第三个参数,形如 [i,j,k],第三个参数 k 用来限制新切片的容量,但不能超过原数组(切片)的底层数组大小。截取获得的切片的长度和容量分别是:j-i、k-i。
所以例子中,切片 t 为 [4],长度和容量都是 1。
24. 下面这段代码输出什么?
A. compilation error
B. equal
C. not equal
答:A
解析:
Go中的数组是值类型,可比较,另外一方面,数组的长度也是数组类型的组成部分,所以 a 和 b 是不同的类型,是不能比较的,所以编译错误。
25. 关于 cap() 函数的适用类型,下面说法正确的是()
A. array
B. slice
C. map
D. channel
答:A、B、D
解析:
cap(),cap() 函数不适用 map
26. 下面这段代码输出什么?
A. nil
B. not nil
C. compilation error
答:A
解析:
当且仅当接口的动态值和动态类型都为 nil 时,接口类型值才为 nil
27. 下面这段代码输出什么?
A. runtime panic
B. 0
C. compilation error
答:B
解析:
删除 map 不存在的键值对时,不会报错,相当于没有任何作用;获取不存在的减值对时,返回值类型对应的零值,所以返回 0。
28. 下面属于关键字的是()
A. func
B. struct
C. class
D. defer
答:A、B、D
29. 下面这段代码输出什么?
A. -5 +5
B. +5 +5
C. 0 0
答:A
解析:
%d表示输出十进制数字,+表示输出数值的符号。这里不表示取反。
30. 下面这段代码输出什么?
答:teacher showB
解析:
知识点:结构体嵌套。
在嵌套结构体中,People 称为内部类型,Teacher 称为外部类型;通过嵌套,内部类型的属性、方法,可以为外部类型所有,就好像是外部类型自己的一样。此外,外部类型还可以定义自己的属性和方法,甚至可以定义与内部相同的方法,这样内部类型的方法就会被“屏蔽”。这个例子中的 ShowB() 就是同名方法。
最后更新于