Golang 面试题总结 I
Golang 中goroutine之间用什么来通信的
用的channel
buffered channel vs unbuffered channel
buffered channel 有容量, 发送者在channel容量未填满前不会阻塞直到容量满了,接受者在channel未空前不会阻塞直到channel变空。
unbuffered channel 发送者做发送操作之后,同时必须有一个接受者做接受操作。常用来做goroutine之间的同步。
make vs new
make: 只用来分配map, slice, channel, 返回一个类型的初始化零值。make初始化这些类型的内部数据结构,为使用做好准备。
new: 分配内存,但不初始化。返回类型T的零值指针。
slice 内部结构
slice 内部有一个指针指向底层的数组,还有长度和容量,分别表示当前slice的元素个数以及从指针开始处到数组末尾的长度。
1 2
| ss := []int{1,2,3,4,5,6,7} s1 := ss[1:5]
|
从一个slice中切分出来的slice添加元素对原来的slice是否有影响
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| package main
import ( "fmt" )
func main() { ss := []int{1,2,3,4,5,6,7} s1 := ss[1:5] fmt.Println(len(s1), cap(s1)) fmt.Println(ss, s1) s1 = append(s1, 10) fmt.Println(len(s1), cap(s1)) fmt.Println(ss, s1) s1 = append(s1, 11) fmt.Println(len(s1), cap(s1)) fmt.Println(ss, s1) s1 = append(s1, 12) fmt.Println(len(s1), cap(s1)) fmt.Println(ss, s1) fmt.Println("Hello, playground") }
有影响,会改动原始slice里面元素的值,*但是不会改变原来slice的长度和容量*
|
说说对goroutine的理解
goroutine 是并发运行的function或method
goroutine 是轻量级的线程,创建一个goroutine开销较小。
goroutine 被多路复用到多个os线程上。当一个goroutine出现阻塞的时候,一个新的os thread将被创建去运行其他的运行的goroutine。
goroutine 使用channel来通信。
function 和 method 定义上的区别
区别就是定义方式不一样
1 2 3 4 5
| func (v *Type) Method() {}
func Func() {}
|
defer 的执行顺序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| package main
import ( "fmt" )
func main() { defer fmt.Println("defer 1") defer fmt.Println("defer 2") defer fmt.Println("defer 3") fmt.Println("main") }
与定义的相反顺序执行
|
panic recorver
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| package main
import ( "fmt" )
func main() { defer func() { if e := recover(); e != nil { fmt.Printf("%T, %v\n", e, e) } }() panicFunc() }
func panicFunc() { panic("call panic ") }
|
golang init 函数的调用
golang 中init是在执行main开始前调用的
多个init是按照定义的顺序执行的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| package main
import ( "fmt" )
var v = setV()
func init() { fmt.Println("init 1") }
func init() { fmt.Println("init 2") }
func main() { fmt.Println(v) }
func setV() int { fmt.Println("setV") return 42 }
|
##