1.关于init函数,下面说法正确的是
A. 一个包中,可以包含多个init函数
B. 程序编译时,先执行导入包的init函数,再执行本包内的init函数
C. main包中,不能有init函数
D. init函数可以被其他函数调用
参考答案:AB
2.关于main函数(可执行程序的执行起点),下面说法正确的是()
A. main函数不能带参数
B. main函数不能定义返回值
C. main函数所在的包必须为main包
D. main函数中可以使用flag包来获取和解析命令行参数
参考答案:ABCD
3.关于cap函数的适用类型,下面说法正确的是()
A. array
B. slice
C. map
D. channel
参考答案:ABD
4.关于函数声明,下面语法错误的是()
A. func f(a, b int) (value int, err error)
B. func f(a int, b int) (value int, err error)
C. func f(a, b int) (value int, error)
D. func f(a int, b int) (int, int, error)
参考答案:C
5.对于函数定义:
func add(args ...int) int {
sum :=0
for _,arg := range args {
sum += arg
}
return sum
}
下面对add函数调用正确的是()
A. add(1, 2)
B. add(1, 3, 7)
C. add([]int{1, 2})
D. add([]int{1, 3, 7}...)
参考答案:ABD
二、简答题
1.new() 与 make() 的区别?
参考答案:
相同点
make和new都是用来分配内存的,
不同点:作用的类型不一样:
make 被用来分配引用类型的内存,make常用。
new 被用来分配除了引用类型的所有其他类型的内存,new不常用
返回类型:
make:Type
new:*Type
2.Printf()、Sprintf()、Fprintf()函数的区别用法是什么?
Printf:标准输出,一般是屏幕
Fprintf:输出到文件
Sprintf:将格式化后的字符串返回
3.说说main函数和init函数?
相同点:
main函数和init函数没有参数和返回值
不同点:
main函数是程序的主入口,而且package也得是main
init函数是初始化函数,进入包或者导入包后先执行init函数,所以init函数在main函数之前执行
4.下面代码能不能正常编译?
func main() {
slice := new([]int)
slice = append(slice, 1,2,3)
fmt.Println(list)
}
答案:不能,这里需要理解new和make的区别,new出来的是指针,不能对指针进行append操作
5.说说你对闭包的理解?
首先说说什么是闭包,然后再说说闭包的特点
闭包是什么?
闭包是匿名函数与匿名函数所引用环境的组合
定义在一个函数内部的函数,闭包是将函数内部和函数外部连接起来的桥梁
闭包的特点:
让外部访问函数内部变量成为可能;
局部变量会常驻在内存中;
可以避免使用全局变量,防止全局变量污染;
有一块内存空间被长期占用,而不被释放,会造成内存泄漏
6.context包的用途
Context通常被译作上下文,它是一个比较抽象的概念,其本质,是【上下上下】存在上下层的传递,
上会把内容传递给下。
7.说说下面代码能不能正常执行?
func Sum(x,y int)(sum int,error){
sum = x + y
return sum,nil
}
答案:不能,
在函数有多个返回值时,只要有一个返回值有指定命名,其他的也必须有命名
返回值有多个的时候返回值必须加上括号
如果只有一个返回值并且有命名也需要加上括号
8.给定两个int类型的切片,将第二个添加到第一个的后面
s1 := []int{1, 2, 3}
s2 := []int{4, 5}
s1 = append(s1, s2...)
这里需要注意加...
9.说说你对go中可变参数的理解?
可变参数:函数方法的参数,可以是任意多个,一个参数可以有不确定长度的值
参数:a ...interface{}
1.关于接口,下面说法正确的是()
A. 只要两个接口拥有相同的方法列表(次序不同不要紧),那么它们就是等价的,可以相互赋值
B. 如果接口A的方法列表是接口B的方法列表的子集,那么接口B可以赋值给接口A
C. 接口查询是否成功,要在运行期才能够确定
D. 接口赋值是否可行,要在运行期才能够确定
参考答案:ABC
A.实质上同一个接口
B.A是B的子集,意味着A的方法B中都有,那么A是B的基类,所以A=B是可行的
c.接口查询实则是类型断言判断, val, ok := interfaceName.(TypeName)
D.接口赋值是否可行在编译阶段就可以知道
2.关于类型转化,下面语法正确的是()
type MyInt int
var mi MyInt
var i int = 1
A.mi = i
B.mi = (MyInt)i
C.mi = MyInt(i)
D.mi = i.(MyInt)
参考答案:C 强制类型转化
3.关于接口和类的说法,下面说法正确的是
A. 一个类只需要实现了接口要求的所有函数,我们就说这个类实现了该接口
B. 实现类的时候,只需要关心自己应该提供哪些方法,不用再纠结接口拆的多细才合理
C. 类实现接口时,需要导入接口所在的包
D. 接口由使用方按自身需求来定义
答案:ABD
4.interface{}是可以指向任意对象的类型()
A.是
B.否
答案:A
二、简答题
1.go的接口是什么?
在go语言中,interface也就是接口,被用来指定一个对象。接口具有下面的要素:
一系列的方法。
具体应用中用来表示某个数据类型。
在go中使用interface来实现多态。
2.请说出下面代码存在什么问题?
type Person struct {
Name string
}
func f(v interface{}) {
man := v.(Type)
switch v{
case Person{}:
man.Name = "hallen"
}
}
有错误,man := v.(Type)这里应该转为Person类型
正确代码如下:
type Person struct {
Name string
}
func f(v interface{}) {
man := Person{}
switch v{
case Person{}:
man.Name = "hallen"
}
}
3.下面代码语法有误吗?
func Test(x *interface{}) {
}
有错,
函数参数为 interface{} 时可以接收任何类型的参数,接收指针类型也用 interface{},不用 *interface{}
4.对于下面的代码,写出执行结果
func main() {
a := interface{}(nil) // 类型是
b := (*int)(nil) // 类型是*int
_, c := a.(interface{}) // 断言,不成功则为false,成功则为true
}
A.fmt.Println(a == b) // false
B.fmt.Println(b == nil) // true
C.fmt.Println(c) // false
5.2 个 interface类型 可以比较吗 ?
package main
import "fmt"
func main() {
var i1 interface{}
var i2 interface{}
if i1 == i2 {
fmt.Println("相等")
}
}
6.指针类型怎么转换?
var a int = 10
var p *int =&a
var c *int64
c= (*int64)(p)
7.写一个多态的示例
package main
import "fmt"
type NanSang interface {
wan()
da()
}
func nanSang(t NanSang) {
fmt.Println("娱乐")
t.wan()
t.da()
}
type duck struct {
Name string
}
func (d duck) wan() {
fmt.Println("玩云桑")
}
func (d duck) da() {
fmt.Println("打阿伟")
}
func main() {
d := duck{"南桑"}
d.wan()
d.da()
nanSang(d)
}