91-120
91. 下面代码输出什么?
func main() {
x := []string{"a", "b", "c"}
for v := range x {
fmt.Print(v)
}
}答:012
解析:
注意区别下面代码段:
func main() {
x := []string{"a", "b", "c"}
for _, v := range x {
fmt.Print(v) //输出 abc
}
}92. 下面这段代码能否编译通过?如果通过,输出什么?
type User struct{}
type User1 User
type User2 = User
func (i User) m1() {
fmt.Println("m1")
}
func (i User) m2() {
fmt.Println("m2")
}
func main() {
var i1 User1
var i2 User2
i1.m1()
i2.m2()
}答:不能,报错i1.m1 undefined (type User1 has no field or method m1)
解析:
第 2 行代码基于类型 User 创建了新类型 User1,第 3 行代码是创建了 User 的类型别名 User2,注意使用 = 定义类型别名。因为 User2 是别名,完全等价于 User,所以 User2 具有 User 所有的方法。但是 i1.m1() 是不能执行的,因为 User1 没有定义该方法。
93. 关于无缓冲和有冲突的channel,下面说法正确的是?
A. 无缓冲的channel是默认的缓冲为1的channel;
B. 无缓冲的channel和有缓冲的channel都是同步的;
C. 无缓冲的channel和有缓冲的channel都是非同步的;
D. 无缓冲的channel是同步的,而有缓冲的channel是非同步的;
答:D
94. 下面代码是否能编译通过?如果通过,输出什么?
答:non-empty interface
解析:
考点:interface 的内部结构,我们知道接口除了有静态类型,还有动态类型和动态值,当且仅当动态值和动态类型都为 nil 时,接口类型值才为 nil。这里的 x 的动态类型是 *int,所以 x 不为 nil。
95. 下面代码输出什么?
答:程序抛异常
解析:
先定义下,第一个协程为 A 协程,第二个协程为 B 协程;当 A 协程还没起时,主协程已经将 channel 关闭了,当 A 协程往关闭的 channel 发送数据时会 panic,panic: send on closed channel。
96. 关于select机制,下面说法正确的是?
A. select机制用来处理异步IO问题;
B. select机制最大的一条限制就是每个case语句里必须是一个IO操作;
C. golang在语言级别支持select关键字;
D. select关键字的用法与switch语句非常类似,后面要带判断条件;
答:A B C
97. 下面的代码有什么问题?
答:有方向的 channel 不可以被关闭。
98. 下面这段代码存在什么问题?
答:存在两个问题
解析:
map 需要初始化才能使用;
指针不支持索引。修复代码如下:
99. 下面代码编译能通过吗?
答:编译错误
解析:
Go 语言中,大括号不能放在单独的一行。
正确的代码如下:
100. 下面这段代码输出什么?
答:[1 0 2 3]
解析:
字面量初始化切片时候,可以指定索引,没有指定索引的元素会在前一个索引基础之上加一,所以输出[1 0 2 3],而不是[1 3 2]。
101. 下面这段代码输出什么?
答:2
解析:
知识点:指针。
p 是指针变量,指向变量 v,*p++操作的意思是取出变量 v 的值并执行加一操作,所以 v 的最终值是 2。
102. 请指出下面代码的错误?
答:变量 one、two 和 three 声明未使用
解析:
知识点:未使用变量。
如果有未使用的变量代码将编译失败。但也有例外,函数中声明的变量必须要使用,但可以有未使用的全局变量。函数的参数未使用也是可以的。
如果你给未使用的变量分配了一个新值,代码也还是会编译失败。你需要在某个地方使用这个变量,才能让编译器愉快的编译。
修复代码:
另一个选择是注释掉或者移除未使用的变量 。
103. 下面代码输出什么?
答:运行时错误
解析:
如果类型实现 String() 方法,当格式化输出时会自动使用 String() 方法。上面这段代码是在该类型的 String() 方法内使用格式化输出,导致递归调用,最后抛错。
104. 下面代码输出什么?
答:[1 2 3 4 5]
解析:
a 在 for range 过程中增加了两个元素,len 由 5 增加到 7,但 for range 时会使用 a 的副本 a' 参与循环,副本的 len 依旧是 5,因此 for range 只会循环 5 次,也就只获取 a 对应的底层数组的前 5 个元素。
105. 下面的代码有什么问题?
答:导入的包没有被使用
解析:
如果引入一个包,但是未使用其中如何函数、接口、结构体或变量的话,代码将编译失败。
如果你真的需要引入包,可以使用下划线操作符,_,来作为这个包的名字,从而避免失败。下划线操作符用于引入,但不使用。
我们还可以注释或者移除未使用的包。
修复代码:
106. 下面代码输出什么?
A. true true true
B. false true true
C. true true true
D. false true false
答:D
解析:
知识点:类型断言。
类型断言语法:i.(Type),其中 i 是接口,Type 是类型或接口。编译时会自动检测 i 的动态类型与 Type 是否一致。但是,如果动态类型不存在,则断言总是失败。
107. 下面代码有几处错误的地方?请说明原因。
答:有 1 处错误
解析:
有 1 处错误,不能对 nil 的 map 直接赋值,需要使用 make() 初始化。但可以使用 append() 函数对为 nil 的 slice 增加元素。
修复代码:
108. 下面代码有什么问题?
答:使用 cap() 获取 map 的容量
解析:
使用 make 创建 map 变量时可以指定第二个参数,不过会被忽略。
cap() 函数适用于数组、数组指针、slice 和 channel,不适用于 map,可以使用 len() 返回 map 的元素个数。
109. 下面的代码有什么问题?
解析:
nil 用于表示 interface、函数、maps、slices 和 channels 的“零值”。如果不指定变量的类型,编译器猜不出变量的具体类型,导致编译错误。
修复代码:
110. 下面代码能编译通过吗?
答:编译失败
解析:
不能使用短变量声明设置结构体字段值,修复代码:
111. 下面代码有什么错误?
答:变量重复声明
解析:
不能在单独的声明中重复声明一个变量,但在多变量声明的时候是可以的,但必须保证至少有一个变量是新声明的。
修复代码:
112. 下面代码有什么问题?
答:编译错误
解析:
第四行代码没有逗号。用字面量初始化数组、slice 和 map 时,最好是在每个元素后面加上逗号,即使是声明在一行或者多行都不会出错。
修复代码:
113. 下面代码输出什么?
答:34
解析:
与 rune 是 int32 的别名一样,byte 是 uint8 的别名,别名类型无序转换,可直接转换。
114. 下面的代码有什么问题?
答:编译可以通过
解析:
知识点:常量。
常量是一个简单值的标识符,在程序运行时,不会被修改的量。不像变量,常量未使用是能编译通过的。
115. 下面代码输出什么?
答:
解析:
常量组中如不指定类型和初始化值,则与上一行非空常量右值相同
116. 下面代码有什么问题?
答:将 nil 分配给 string 类型的变量
解析:
修复代码:
117. 下面的代码有什么问题?
解析:
对于自增、自减,需要注意:
自增、自减不在是运算符,只能作为独立语句,而不是表达式;
不像其他语言,Go 语言中不支持 ++i 和 --i 操作;
表达式通常是求值代码,可作为右值或参数使用。而语句表示完成一个任务,比如 if、for 语句等。表达式可作为语句使用,但语句不能当做表达式。
修复代码:
118. 下面代码最后一行输出什么?请说明原因。
答:输出1
解析:
知识点:变量隐藏。
使用变量简短声明符号 := 时,如果符号左边有多个变量,只需要保证至少有一个变量是新声明的,并对已定义的变量尽进行赋值操作。但如果出现作用域之后,就会导致变量隐藏的问题,就像这个例子一样。
这个坑很容易挖,但又很难发现。即使对于经验丰富的 Go 开发者而言,这也是一个非常常见的陷阱。
119. 下面代码有什么问题?
答:编译错误
解析:
:= 操作符不能用于结构体字段赋值。
120. 下面的代码输出什么?
答:编译错误
解析:
很多语言都是采用 ~ 作为按位取反运算符,Go 里面采用的是^ 。按位取反之后返回一个每个 bit 位都取反的数,对于有符号的整数来说,是按照补码进行取反操作的(快速计算方法:对数 a 取反,结果为 -(a+1) ),对于无符号整数来说就是按位取反。例如:
另外需要注意的是,如果作为二元运算符,^ 表示按位异或,即:对应位相同为 0,相异为 1。例如:
给大家重点介绍下这个操作符 &^,按位置零,例如:z = x &^ y,表示如果 y 中的 bit 位为 1,则 z 对应 bit 位为 0,否则 z 对应 bit 位等于 x 中相应的 bit 位的值。
不知道大家发现没有,我们还可以这样理解或操作符 | ,表达式 z = x | y,如果 y 中的 bit 位为 1,则 z 对应 bit 位为 1,否则 z 对应 bit 位等于 x 中相应的 bit 位的值,与 &^ 完全相反。
输出:
最后更新于