Golang刷题
- 今日题目
- 1. 下面代码中两个斜点之间的代码,比如json:"x",作用是X字段在从结构体实例编码到JSON数据格式的时候,使用x作为名字,这可以看作是一种重命名的方式(如下图),这一说法是否正确。
- 2. 下面的代码中两个斜点之间的代码,比如json:"x",作用是X字段在从结构体实例编码到JSON数据格式的时候,使用x作为名字,这可以看作是一种重命名的方式()
- 3. golang虽然没有显式的提供继承语法,但是通过匿名组合实现了继承,这个说法是否正确。
- 4. 如果调用方调用了一个具有多返回值的方法,但是却不想关心其中的某个返回值,可以简单地用一个下划线“_”来跳过这个返回值,该下划线对应的变量叫匿名变量,这一说法是否正确。
- 5. golang支持goto语句,这一说法是否正确
- 6. inrerface{}是可以指向任意对象的Any类型,这一说法是否正确
- 7. channel本身必须同时支持读写的,所以不存在单向channel。这一说法是否正确。
- 8. 使用for range迭代map时每次迭代的顺序可能不一样,因为map的迭代是随机的。这一说法是否正确。
- 9. 关于类型转换,下面语法正确的是()
- 10. 下面关于文件操作的代码可能触发异常,这个说法是否正确。
- 11. 内置函数 delete 可以删除数组切片内的元素,这一说法是否正确
- 12. switch后面可以不跟表达式。这一说法是否正确。
- 13. 可以给任意类型添加相应的方法,这一说法是否正确
- 14. import 后面的最后一个元素是包名,这个说法是否正确
- 15. 结构体在序列化时非导出比那辆(以小写字母开头的变量名)不会被encode, 因此在decode的时候这些非导出变量的值为其类型的零值,这一说法是否正确。
- 16. Golang可以服用C/C++的模块,这个功能叫Cgo, 这一说法是否正确。
- 17. 对于常量定义zero(const zero = 0.0), zero是浮点型常量,这一说法是否正确。
- 18. 关于变量的自增和自减操作,下面语句正确的是()
- 19. 对下面这段代码,调用正确的是()
- 20. 关于beego框架,下面说法正确的是()
- 21. 关于字符串连接,下面语法正确的是()
- 22. 关于布尔类型变量, 下面的错误用法是
- 24. 关于const常量定义,下面正确的使用方式是()
- 26. 下面赋值正确的是()
- 27. 关于 go vet, 下面说法正确的是()
- 28. 关于GoStub,下面的说法正确的是()
- 29. Golang中大多数数据类型都可以转换为有效的JSON文本,下面的集中类型除外()
- 30. 关于cap函数的适用类型,下面说法正确的是()
今日题目
1. 下面代码中两个斜点之间的代码,比如json:“x”,作用是X字段在从结构体实例编码到JSON数据格式的时候,使用x作为名字,这可以看作是一种重命名的方式(如下图),这一说法是否正确。
type Position struct {
X int 'json:"x"'
Y int 'json:"y"'
Z int 'json:"z"'
}
这个说法是正确的。
2. 下面的代码中两个斜点之间的代码,比如json:“x”,作用是X字段在从结构体实例编码到JSON数据格式的时候,使用x作为名字,这可以看作是一种重命名的方式()
type Position struct {
X int 'json:"x"'
Y int 'json:"y"'
Z int 'json:"z"'
}
这个题目跟第一题一样,也是正确的。
3. golang虽然没有显式的提供继承语法,但是通过匿名组合实现了继承,这个说法是否正确。
这个说法是正确的。我们可以通过匿名组合让一个结构体拥有另外一个结构体的所有属性。
type Person struct {
age int,
name string,
}
type Student struct {
Person,
ID string,
}
上面的代码就是学生继承了人的属性。
4. 如果调用方调用了一个具有多返回值的方法,但是却不想关心其中的某个返回值,可以简单地用一个下划线“_”来跳过这个返回值,该下划线对应的变量叫匿名变量,这一说法是否正确。
这个说法是正确的,这个被称之为匿名变量对应的返回值。
5. golang支持goto语句,这一说法是否正确
这个说法是正确的,go语言支持goto。
goto关键字,用来改变函数内代码的执行顺序,跳转到函数内指定的标签地方运行,goto不能跨函数代码块跳转。下面请看一段实例,用goto实现for循环的功能:
package main
import (
"fmt"
)
func main() {
fmt.Println("Begin")
var i = 0
// 定义一个标签,这个标签只能被goto使用
RET:
if i < 5 {
fmt.Println("循环第", i, "次")
i++
// 调转到锚点RET处开始运行
goto RET
}
fmt.Println("end")
}
begin
循环第 0 次
循环第 1 次
循环第 2 次
循环第 3 次
循环第 4 次
end
在C/C++编程中,大多数时候都不推荐使用goto语句在函数内跳转,在golang中,也尽量少用goto,能够减少代码量的时候,该用还是要用,不要一味地排斥goto语句。
6. inrerface{}是可以指向任意对象的Any类型,这一说法是否正确
这个说法是正确的,因为空接口可以接受任意类型。
7. channel本身必须同时支持读写的,所以不存在单向channel。这一说法是否正确。
这个说法是正确的。具体来讲可以是:
有单向通道。一般作为函数的参数或者返回值。 单向通道都是由双向通道转换而来,不能自己声明单向通道,没有意义。 单向通道作为函数或者方法的参数时,表示该函数或者方法作用域内,只能执行接收或者发送操作。 单向通道作为函数或者方法返回值时,表示调用者得到该通道后只能做单向操作。
双向:var value chan int
单向只读:var value <-chan int
单向只写:var value chan<-int
单向一般用于参数传递和返回值
8. 使用for range迭代map时每次迭代的顺序可能不一样,因为map的迭代是随机的。这一说法是否正确。
这个说法是正确的。因为在GO语言当中,map是无序的。
9. 关于类型转换,下面语法正确的是()
A:
type MyInt int
var i int = 1
var j MyInt = i
B:
type MyInt int
var i int = 1
var j MyInt = (MyInt)i
C:
type MyInt int
var i int = 1
var j MyInt = MyInt(i)
D:
type MyInt int
var i int = 1
var j MyInt = i.(MyInt)
正确答案选择C
类型转换用C那种方式。
Go语言类型转换语法:Type(expression)
D选项是类型断言,类型断言语法为:expression.(Type)
对于类型断言,首先 expression 必须是接口类型,但D选项中 i 是 int 类型,无法进行类型断言;其次 i 是 int 类型,无法通过类型断言转换成 MyInt,只有类型相符时,类型断言才会成功。
10. 下面关于文件操作的代码可能触发异常,这个说法是否正确。
file, err := os.Open("test.go")
defer file.Close()
if err != nil {
fmt.Println("open file failed:", err)
return
}
这个说法是正确的。把defer放在错误判断前面是肯定会报错的。
file, err := os.Open("/null")
defer func() {
err := file.Close()
if err != nil {
fmt.Println("close error: ", err)
} else {
fmt.Println("close no error")
}
}()
if err != nil {
fmt.Println("open error! ", err)
return
}
// Output
open error! open /null: The system cannot find the file specified.
close error: invalid argument
11. 内置函数 delete 可以删除数组切片内的元素,这一说法是否正确
这个说法是错误的,具体原因如下
delete 只能够删除map,只会对map起效果,不能够对切片中的元素进行任何操作。这是Go语言当中的规定。
而 slice 可以通过append 的方式来实现元素的删除。例如 slice1 = append(slice1[:idx], slice1[idx + 1:])
12. switch后面可以不跟表达式。这一说法是否正确。
这个说法正确,在go中,switch后面的声明语句和表达式语句都是可选的。
13. 可以给任意类型添加相应的方法,这一说法是否正确
这个说法是错误的,因为必须是自定义类型才可以添加相对应的方法,默认类型是不可以的。
14. import 后面的最后一个元素是包名,这个说法是否正确
这个说法是错误的。
import后面的最后一个元素应该是路径,就是目录,并非包名
import "libproj1/foo"
func main() {
foo.Foo()
}
go编译器在这些路径(libproj2/foo)下找bar包。这样看来,go语言的惯例只是一个特例,即恰好目录名与包名一致。也就是说上面例子中的两个foo含义不同:
import中的foo只是一个文件系统的路径。而下面foo.Foo()中的foo则是包名。而这个包是在libproj1/foo目录下的源码中找到的。
15. 结构体在序列化时非导出比那辆(以小写字母开头的变量名)不会被encode, 因此在decode的时候这些非导出变量的值为其类型的零值,这一说法是否正确。
这个说法是正确的。
序列化通常将类型结构传入标准库或第三方包,类型结构中没有大写的变量未导出,对第三方包不可见,无法进行任何操作,依旧是默认的零值。
16. Golang可以服用C/C++的模块,这个功能叫Cgo, 这一说法是否正确。
这个说法是错误的。
因为具体来讲,Cgo 是智能让go去调用C代码模块、静态库和动态库的。
CGO是C语言和Go语言之间的桥梁,原则上无法直接支持C++的类。CGO不支持C++语法的根本原因是C++至今为止还没有一个二进制接口规范(ABI)。CGO只支持C语言中值类型的数据类型,所以我们是无法直接使用C++的引用参数等特性的。
17. 对于常量定义zero(const zero = 0.0), zero是浮点型常量,这一说法是否正确。
这个说法是错误的。
Go语言的常量有个不同寻常之处。虽然一个常量可以有任意有一个确定的基础类型,例如int或float64,或者是类似time.Duration这样命名的基础类型,但是许多常量并没有一个明确的基础类型。编译器为这些没有明确的基础类型的数字常量提供比基础类型更高精度的算术运算;你可以认为至少有256bit的运算精度。这里有六种未明确类型的常量类型,分别是无类型的布尔型、无类型的整数、无类型的字符、无类型的浮点数、无类型的复数、无类型的字符串。
我们可以参考下,下面的代码的结果
package main
import ( "reflect" "fmt"
)
func main(){
a := 0.0
const zero = 0.0
fmt.Println(reflect.TypeOf(a),reflect.ValueOf(a).Kind())
fmt.Println(reflect.TypeOf(zero),reflect.ValueOf(zero).Kind())
}
//结果都为float64:
//float64 float64
//float64 float64
18. 关于变量的自增和自减操作,下面语句正确的是()
A:
i := 1
i++
B:
i := 1
j = i++
C:
i := 1
++i
D:
i := 1
i--
正确答案选择 AD
B:go语言中的++、–操作符都是后置操作符,必须跟在操作数后面,并且它们没有返回值,所以它们不能用于表达式。
19. 对下面这段代码,调用正确的是()
func add(args ...int) int {
sum := 0
for _, arg := range args {
sum += arg
}
return sum
}
A: add(1, 2)
B: add(1, 3, 7)
C: add([]int{1, 2})
D: add([]int{1, 3, 7}...)
正确答案选择ABD
C:数组不会自动转化为多个参数。
可能争议比较大的是D,D中会把int数组中元素转成int的多个参数,因此也是正确的。
20. 关于beego框架,下面说法正确的是()
A: beego是一个golang实现的轻量级的HTTP框架
B: beego可以通过注释路由、正则路由等多种方式完成url路由注入
C: 可以使用bee new工具生成空工程,然后使用bee run命令自动热编译
D: beego框架只提供了对url路由的处理,而对于MVC框架中的数据库部分未提供框架支持
正确答案选择ABC
21. 关于字符串连接,下面语法正确的是()
A: str := `abc` + `123`
B: str := "abc" + "123"
C: str := '123' + "abc"
D: fmt.Sprintf("abc%d", 123)
正确答案选择BD,字符串不能使用’’
但是新版本里面是可以使用的了
我不知道题目是基于go的什么版本,但是我的go1.12.5版本,全都能正常连接和打印。
22. 关于布尔类型变量, 下面的错误用法是
A: b = true
B: b = 1
C: b = bool(1)
D: b = (1 == 2)
正确答案选择BC, bool和int没有办法强制类型转换。
24. 关于const常量定义,下面正确的使用方式是()
A:
const Pi float64 = 3.14159265358979323846
const zero = 0.0
B:
const (
size int64 = 1024
eof = -1
)
C:
const (
ERR_ELEM_EXIST error = errors.New("element already exists")
ERR_ELEM_NT_EXIST error = errors.New("element not exists")
)
D:
const u, v float32 = 0, 3
const a, b, c = 3, 4, "foo"
正确答案选择ABD
C: error是对象数据类型,是一个指针,不是常量。
go语言常量要是编译时就能确定的数据,C选项中errors.New(“xxx”) 要等到运行时才能确定,所以它不满足
26. 下面赋值正确的是()
A:
var x = nil
B:
var x interface{} = nil
C:
var x string = nil
D:
var x error = nil
正确答案选择BD
Go语言当中的引用类型只有五个:
切片、映射、函数、方法、通道
nil智能赋值给上面五中通道类型的变量以及指针变量。
27. 关于 go vet, 下面说法正确的是()
A: go vet 是golang自带工具go tool vet的封装
B: 当执行 go vet database时,可以对database所在目录下的所有子文件夹进行递归检测
C: go vet可以使用绝对路径、相对路径或相对GOPATH的路径制定待检测的包
D: go vet可以检测出死代码
正确答案选择ACD
具体原因
go tool vet package1 package2 ; go tool vet 才可以递归。
28. 关于GoStub,下面的说法正确的是()
A: GoStub可以对全局变量打桩
B: GoStub可以对函数打桩
C: GoStub可以对类的成员方法打桩
D: GoStub可以动态打桩,比如对一个函数打桩后,多次调用该函数会有不同的行为
正确答案选择ABD
做这道题之前,我还不知道GoStub是什么,但是先看选项就可以排除C,因为Go中没有【类】这个概念。
GoStub框架的使用场景很多,依次为:
基本场景:为一个全局变量打桩
基本场景:为一个函数打桩
基本场景:为一个过程打桩
复合场景:由任意相同或不同的基本场景组合而成
29. Golang中大多数数据类型都可以转换为有效的JSON文本,下面的集中类型除外()
A: 指针
B: channel
C: complex
D: 函数
正确答案选择BCD
golang中大多数数据类型都可以转化为有效的JSON文本,除了channel、complex、函数等。
在golang指针中可进行隐式转换,对指针取值,对所指对象进行序列化。
30. 关于cap函数的适用类型,下面说法正确的是()
A: array
B: slice
C: map
D: channel
正确答案选择ABD
cap的作用—— arry:返回数组的元素个数 slice:返回slice的最大容量 channel:返回channel的buffer容量。
aa := []int{1,2,3}
fmt.Println(cap(aa))
fmt.Println(len(aa))
bb := [2]int{1,2}
fmt.Println(cap(bb))
fmt.Println(len(bb))
cc := make(chan int,4)
fmt.Println(cap(cc))
fmt.Println(len(cc))
dd := make(map[string]string,2) //map no cap ;have len fmt.Println(len(dd))