go面试题
1.go语言中的主要关键字,一共25个
1.程序声明:
1.import
2.package
2.实体声明和定义
1.chan
2.const
3.func
4.interface
5.map
6.struct
7.type
8.var
3.流程控制
1.go
2.select
3.break
4.case
5.continue
6.default
7.defer
8.else
9.fallthrough
10.for
11.goto
12.if
13.range
14.return
15.switch
2.go语言类型定义
比如字符串
func main() {
var a string = "a"
b := "b"
var c string
c = "c"
var d = "d"
fmt.Println(a)
fmt.Println(b)
fmt.Println(c)
fmt.Println(d)
}
3.go语言全局变量定义
var a string = "a"
var b string
var c = ""
func main() {
fmt.Println(a)
fmt.Println(b)
fmt.Println(c)
}
4.结构体
func main() {
p1 := Person{"Alice", 20}
var p2 Person
p2.name = "Alice"
p2.age = 20
fmt.Println(p1)
fmt.Println(p2)
}
type Person struct {
name string
age int
}
5.通过指针变量访问成员变量
func main() {
person := Person{"Alice", 20}
p1 := &person
fmt.Println(person)
fmt.Println(&person)
fmt.Println(&p1)
fmt.Println(*p1)
fmt.Println(person.name)
fmt.Println(&person.name)
fmt.Println(p1.name)
fmt.Println(&p1.name)
}
type Person struct {
name string
age int
}
6.格式化输出
%T 类型
%t 布尔
%d 10进制整数
%X 16进制整数
%f 浮点数
%s 字符串
person := Person{"Alice", 20}
fmt.Printf("%Tn", person)
flag := true
fmt.Printf("%tn", flag)
number10 := 99
fmt.Printf("%dn", number10)
//十进制100为16进制的64
number16:= 0x64
fmt.Printf("%Xn", number16)
fmt.Printf("%dn", number16)
number0:= 0.123
fmt.Printf("%fn", number0)
str:= "hello world"
fmt.Printf("%sn", str)
7.接口
1.一个类如果实现了一个接口的所有函数,
那么这个类就实现了这个接口
8.init函数
func init() {
fmt.Println("init 1")
}
func init() {
fmt.Println("init 2")
}
func main() {
fmt.Println("main")
}
结果为
init 1
init 2
main
9.多参数函数
func add(args ...int) int {}
这个函数的调用方式有
add(1,2,3)
add([]int{1,2,3}...)
10.类型转换
type MyInt int
var a int = 1
var b MyInt = MyInt(a)
11.引用类型
slice
map
channel
12.main函数
1.main函数不能带参数
2.main函数不能定义返回值
3.main函数所在包必须为main
4.main函数中可以使用flag包来获取和解析命令行参数
13.slice切片初始化
func main() {
s1 := make([]int, 0)
s2 := make([]int, 6,10)
s3 := []int{1, 2, 3, 4, 5}
fmt.Println(s1)
fmt.Println(s2)
fmt.Println(s3)
fmt.Println(len(s2))
fmt.Println(cap(s2))
}
14.函数定义
func main() {
r1, r2 := getResult(1, 2)
fmt.Println(r1)
fmt.Println(r2)
}
func getResult(a int, b int) (c int, d int) {
return a b, a - b;
}
func getResult(a int, b int) (int, int) {
return a b, a - b;
}
15.接口
1.如果两个接口有相同的方法列表,那么它们就是等价的,可以相互赋值
2.如果接口A的方法列表是接口B的方法列表的子集,那么接口B可以赋值给接口A
3.接口查询是否成功,要在运行期才能够确定
16.同步锁
1.当一个goroutine获得了Mutex后,其他goroutine就只能乖乖的等待,除非该goroutine释放这个Mutex
2.RWMutex在 读锁 占用的情况下,会阻止写,但不阻止读
3.RWMutex在 写锁 占用情况下,会阻止任何其他goroutine(无论读和写)进来,整个锁相当于由该goroutine独占
17.channel
1.给一个 nil channel 发送数据,造成永远阻塞
2.从一个 nil channel 接收数据,造成永远阻塞
3.给一个已经关闭的 channel 发送数据,引起 panic
4.从一个已经关闭的 channel 接收数据,如果缓冲区中为空,则返回一个零值
18.channel缓冲
无缓冲的channel是同步的,而有缓冲的channel是非同步的
19.cap函数
1.array
2.slice
3.channel
20.go convey
1.goconvey是一个支持golang的单元测试框架
2.goconvey能够自动监控文件修改并启动测试,并可以将测试结果实时输出到web界面
3.goconvey提供了丰富的断言简化测试用例的编写
21.类型断言
func main() {
m := make(map[int]interface{})
m[0] = Person{}
m[1] = "abc"
r1, r2 := m[0].(Person)
r3, r4 := m[1].(string)
fmt.Println(r1)
fmt.Println(r2)
fmt.Println(r3)
fmt.Println(r4)
}
输出结果为
{}
true
abc
true
22.切片删除元素
func main() {
s := make([]string, 0)
s = append(s, "abc0")
s = append(s, "abc1")
fmt.Println(s)
s = append(s[:0], s[0 1:]...)
fmt.Println(s)
s = append(s[:0], s[0 1:]...)
fmt.Println(s)
}
23.json重命名
func main() {
p1 := Person{"Alice", 20}
fmt.Println(p1)
bytes, _ := json.Marshal(p1)
fmt.Println(string(bytes))
}
type Person struct {
Name string `json:"name"`
Age int `json:"age"`
}
24.继承
func main() {
stu := Student{Person{"Alice", 20}}
fmt.Println(stu)
}
type Person struct {
Name string
Age int
}
type Student struct {
Person
}
输出结果
{{Alice 20}}
25.使用for range迭代map时每次迭代的顺序可能不一样,因为map的迭代是随机的
func main() {
m := make(map[string]int)
m["string"] = 0
m["int"] = 1
m["float"] = 2
m["bool"] = 3
m["byte"] = 4
for k, v := range m {
fmt.Println(k, ",", v)
}
}
打印的顺序会出现不一样的情况
26.golang基本数据类型
一共是18个
主要有
1.bool
2.string
3.byte
4.int
5.uint
6.float
27.switch语句
func main() {
i := rand.Intn(2)
switch i {
case 0:
fmt.Println("get 0")
case 1:
fmt.Println("get 1")
}
}
switch后面可以不跟表达式
func main() {
i := rand.Intn(2)
switch {
case i == 0:
fmt.Println("get 0")
case i == 1:
fmt.Println("get 1")
}
}
28.
结构体在序列化时非导出变量(以小写字母开头的变量名)不会被encode
所以在decode时这些非导出变量的值为其类型的零值
29.new和make的区别
new的作用是初始化一个指向类型的指针
new函数是内建函数,函数定义: func new(Type) *Type
使用new函数来分配空间
传递给new函数的是一个类型,而不是一个值
返回值是指向这个新分配的地址的指针
看下代码
func main() {
p := new(Person)
person := Person{"Alice"}
fmt.Printf("%Tn",p)
fmt.Printf("%Tn",person)
}
type Person struct {
name string
}
输出结果为
*main.Person
main.Person
所以new函数返回的是指针
person是实体
30.make
make的作用是为slice,map或chan初始化
然后返回引用
make函数是内建函数,函数定义: func make(Type,size IntegerType) Type
make(T,args)函数的目的和new(T)不同
仅仅用于创建slice,map,channel,
而且返回类型是实例
31.Printf(),Sprintf(),FprintF()
都是格式化输出,但是输出的目标不一样
Printf是标准输出,一般是屏幕,也可以重定向
Sprintf()是把格式化字符串输出到指定字符串中
func main() {
person := Person{"Alice"}
s := fmt.Sprintf("类型是%Tn", person)
fmt.Println(s)
}
Fprintf()是把格式化字符串输出到文件中
主要用于文件操作
file, e := os.OpenFile("f:/1.txt", os.O_RDWR, 0777)
defer file.Close()
if e != nil {
fmt.Println(e)
}
fmt.Fprintln(file,"hello world")
32.数组和切片的区别
1.数组固定长度
2.数组长度是数组类型的一部分,
所以[3]int和[4]int是两种不同的数组类型
3.数组需要指定大小,不指定也会根据初始化的自动推算出大小,不可改变
4.数组是值传递
切片
1.切片可变长度
2.切片是轻量级数据结构,三个属性,指针,长度,容量
3.不需要指定大小
4.切片是地址传递(引用传递)
5.可以通过数组来初始化,也可以通过内置函数make()初始化,
初始化的时候len=cap,然后会进行扩容
33.值传递和地址传递(引用传递)
func main() {
p1 := Person{"Alice"}
p2 := Person{"Bob"}
change(p1)
changeAddress(&p2)
fmt.Println(p1)
fmt.Println(p2)
}
func change(p Person) {
p.name = "Hello"
}
func changeAddress(p *Person) {
p.name = "Hello"
}
type Person struct {
name string
}
34.数组和切片传递的区别
先看下类型有啥区别
func main() {
arr1 := [3]int{1, 2, 3}
arr2 := []int{1, 2, 3}
fmt.Printf("%Tn", arr1)
fmt.Printf("%Tn", arr2)
}
结果为
[3]int
[]int
然后看下传递的时候的区别
func main() {
arr1 := [3]int{1, 2, 3}
arr2 := []int{1, 2, 3}
changeArr(arr1)
changeSlice(arr2)
fmt.Printf("%Tn", arr1)
fmt.Printf("%Tn", arr2)
fmt.Println(arr1)
fmt.Println(arr2)
}
func changeArr(arr [3]int) {
arr[0] = 9
}
func changeSlice(arr []int) {
arr[0] = 9
}
结果为
[1 2 3]
[9 2 3]
所以
数组是值传递
切片是引用传递
35.写入文件
file, err := os.OpenFile("f:/1.txt", os.O_RDWR, 0777)
defer file.Close()
if err != nil {
fmt.Println(err)
return
}
file.WriteString("hello world")
36.切片扩容
func main() {
arr := make([]int, 0)
for i := 0; i
参与评论
手机查看
返回顶部