151-180
151. 下面列举的是 recover() 的几种调用方式,哪些是正确的?
A
func main() { recover() panic(1) }B
func main() { defer recover() panic(1) }C
func main() { defer func() { recover() }() panic(1) }D
func main() { defer func() { defer func() { recover() }() }() panic(1) }
答:C
解析:
recover() 必须在 defer() 函数中直接调用才有效。上面其他几种情况调用都是无效的:直接调用 recover()、在 defer() 中直接调用 recover() 和 defer() 调用时多层嵌套。
152. 下面代码输出什么,请说明?
答:21
解析:
recover() 必须在 defer() 函数中调用才有效,所以第 9 行代码捕获是无效的。在调用 defer() 时,便会计算函数的参数并压入栈中,所以执行第 6 行代码时,此时便会捕获 panic(2);此后的 panic(1),会被上一层的 recover() 捕获。所以输出 21。
153. flag 是 bool 型变量,下面 if 表达式符合编码规范的是?
A. if flag == 1
B. if flag
C. if flag == false
D. if !flag
答:B C D
154. 下面的代码输出什么,请说明?
答:12
解析:
152题与之类似
155. 下面的代码输出什么?
答:0 [{0} {9}]
解析:
知识点:for-range 循环数组。
此时使用的是数组 ts 的副本,所以 t.n = 3 的赋值操作不会影响原数组。
156. 下面的代码输出什么?
答:9 [{0} {9}]
解析:
知识点:for-range 数组指针。
for-range 循环中的循环变量 t 是原数组元素的副本。如果数组元素是结构体值,则副本的字段和原数组字段是两个不同的值。
157. 下面的代码输出什么?
答:9 [{0} {9}]
解析:
知识点:for-range 切片。
for-range 切片时使用的是切片的副本,但不会复制底层数组,换句话说,此副本切片与原数组共享底层数组。
158. 下面的代码输出什么?
答:9 [{3} {9}]
解析:
知识点:for-range 切片。参考前几道题的解析,这道题的答案应该很明显。
159. 下面代码有什么问题吗?
解析:
goto 不能跳转到其他函数或者内层代码。编译报错:
160. 下面代码输出什么,请说明。
答:22222
解析:
知识点:defer()、for-range。
for-range 虽然使用的是 :=,但是 v 不会重新声明,可以打印 v 的地址验证下。
161. 关于 slice 或 map 操作,下面正确的是?
A
B
C
D
答:A C D
162. 下面代码输出什么?
答:100 110
解析:
知识点:闭包引用相同变量。
163. 关于字符串连接,下面语法正确的是?
A. str := 'abc' + '123'
B. str := "abc" + "123"
C. str := '123' + "abc"
D. fmt.Sprintf("abc%d", 123)
答:B D
解析:
知识点:单引号、双引号和字符串连接。
在 Go 语言中,双引号用来表示字符串 string,其实质是一个 byte 类型的数组,单引号表示 rune 类型。
164. 下面代码能编译通过吗?可以的话,输出什么?
答:43
165. 判断题:对变量x的取反操作是 ~x?
答:错
解析:
Go 语言的取反操作是 ^,它返回一个每个 bit 位都取反的数。作用类似在 C、C#、Java 语言中中符号 ~,对于有符号的整数来说,是按照补码进行取反操作的(快速计算方法:对数 a 取反,结果为 -(a+1) ),对于无符号整数来说就是按位取反。
166. 下面代码输出什么,请说明原因。
答:132
解析:
这一题有两点需要注意:
Add() 方法的返回值依然是指针类型 *Slice,所以可以循环调用方法 Add();
defer 函数的参数(包括接收者)是在 defer 语句出现的位置做计算的,而不是在函数执行的时候计算的,所以 s.Add(1) 会先于 s.Add(3) 执行。
167. 下面的代码输出什么,请说明。
答:312
解析:
对比昨天的第166题,本题的 s.Add(1).Add(2) 作为一个整体包在一个匿名函数中,会延迟执行。
168. 下面的代码输出什么,请说明?
答:{5}
解析:
这道题容易忽视的点是,String() 是指针方法,而不是值方法,所以使用 Println() 输出时不会调用到 String() 方法。
可以这样修复:
169. 下面代码输出什么?
答:
解析:
知识点:闭包延迟求值。for 循环局部变量 i,匿名函数每一次使用的都是同一个变量。(说明:i 的地址,输出可能与上面的不一样)。
170. 下面的代码能编译通过吗?可以的话输出什么,请说明?
答:10x
解析:
这道题一眼看上去会输出 109876543210,其实这是错误的答案,这里不是递归。假设 main() 函数里为 f2(),外面的为 f1(),当声明 f2() 时,调用的是已经完成声明的 f1()。
看下面这段代码你应该会更容易理解一点:
171. 下面代码有什么问题,请说明?
答: 讨论 #11
以上代码在go1.14版本之前(不含1.14版本): for {} 独占 CPU 资源导致其他 Goroutine 饿死,
在go1.14版本之后(包含go1.14): 会打印0123456789, 并且主程会进入死循环
解析:
可以通过阻塞的方式避免 CPU 占用,修复代码:
172. 假设 x 已声明,y 未声明,下面 4 行代码哪些是正确的。错误的请说明原因?
答:2、3正确
解析:
知识点:简短变量声明。使用简短变量声明有几个需要注意的地方:
只能用于函数内部;
短变量声明语句中至少要声明一个新的变量;
173. 下面的代码有什么问题,请说明?
答:defer 语句应该放在 if() 语句后面,先判断 err,再 defer 关闭文件句柄。
解析:
修复代码:
174. 下面代码输出什么,为什么?
答:recover:1
解析:
知识点:panic、recover()。
当程序 panic 时就不会往下执行,可以使用 recover() 捕获 panic 的内容。
175. 下面这段代码输出什么?
答:
解析:
知识点:类型断言,结构体嵌套。
结构体 S2 嵌套了结构体 S1,S2 自己没有实现 g() ,调用的是 S1 的 g()。
176. 下面的代码有什么问题?
解析:
协程里面,使用 wg.Add(1) 但是没有 wg.Done(),导致 panic()。
177. 关于 cap 函数适用下面哪些类型?
A. 数组;
B. channel;
C. map;
D. slice;
答:A B D
解析:
cap()函数的作用是:
array 返回数组的元素个数
slice 返回slice的最大容量
channel 返回 channel的容量
178. 下面代码输出什么?
A. 18
B. 5
C. Compilation error
答:A
解析:
可变函数是指针传递
179. 关于 switch 语句,下面说法正确的是?
A. 单个 case 中,可以出现多个结果选项;
B. 需要使用 break 来明确退出一个 case;
C. 只有在 case 中明确添加 fallthrought 关键字,才会继续执行紧跟的下一个 case;
D. 条件表达式必须为常量或者整数;
答:A C
180. 下面代码能编译通过吗?可以的话,输出什么?
答:可以编译通过,输出:true
解析:
Go 代码断行规则。
最后更新于