一、go语言基础
(1)一个包怎么调用另一包的函数,go语言中公有性和私有性怎么表达?
函数大写表示公有,小写表示私有
(2)简单的介绍一下闭包使用场景,优缺点?
首先闭包的特点是当闭包函数引用外部变量的时候,会把这个变量放在堆中,所以在内部函数引用外部函数的变量时,值不会被释放
package main import "fmt" func externalFunc(count int) func() int{ return func() int { count++ return count } } func main() { // 这时候的external是个函数,externalFunc函数返回了个匿名函数 external := externalFunc(1) // 这时候的count == 1 fmt.Println(external()) //输出2 fmt.Println(external()) //输出3 fmt.Println(external()) //输出4 }
用法1.函数计数器
// 函数计数器 func counter(f func()) func() int { n := 0 return func() int { f() n += 1 return n } } // 测试的调用函数 func foo() { fmt.Println("call foo") } func main() { cnt := counter(foo) cnt() cnt() cnt() fmt.Println(cnt()) } /* 输出结果: call foo call foo call foo call foo 4 */2)装饰器和中间件,即函数作为参数传递
func wrapping(f func() string) { fmt.Println("do my work...") fmt.Println("wrapping function: ", f()) fmt.Println("my work finished !") } func sayHello() string { return "Hello !" } func sayByeBye() string { return "Bye Bye !" } func main() { wrapping(sayHello) wrapping(sayByeBye) } /* 输出: do my work... wrapping function: Hello ! my work finished ! do my work... wrapping function: Bye Bye ! my work finished ! */
(3)map和array make的使用区别?
go语言中new和make是内置函数,主要用来创建分配类型内存。
new(T)创建一个没有任何数据的类型为T的实例,并返回该实例的 指针;
make(T,args) 只能创建slice,map,channel,并返回一个有初始值args(非零)的T类型的实例,非指针。
二者都是内存的分配(堆上),但是make只用于slice、map、channel的初始化,而new用于类型的内存分配,并且内存内置为0.
make返回的还是这三个引用类型本身;而new返回的是指向类型的指针。
slice和array接近,不过更加的灵活,可以在新的元素加入的时候增加长度。slice总是指向底层的一个array。slice是一个指向array的指针,这是其与array不同的地方;slice是引用类型,这意味着当赋值某个slice到另外一个变量,两个引用会指向同一个array。 例如,如果一个函数需要一个slice参数,在其内对slice元素的修改也会体现在函数调用者中,这和传递底层的array指针类似。
append: 向slice追加零值或者其他的x值,并且返回追加后的新的slice。如果原来的slice没有足够的容量,那么append会分配一个足够大的,新的slice来存放原来的slice和后面追加的值。因此返回的slice可能和原来的不是指向同一个array
Slice 所允许申请的最大容量大小,与当前值类型和当前平台位数有直接关系
slice扩容机制
1.如果切片的容量小于1024个元素,那么扩容的时候slice的cap就翻番,乘以2;一旦元素个数超过1024个元素,增长因子就变成1.25,即每次增加原来容量的四分之一。
2.如果扩容之后,还没有触及原数组的容量,那么,切片中的指针指向的位置,就还是原数组,如果扩容之后,超过了原数组的容量,那么,Go就会开辟一块新的内存,把原来的值拷贝过来,这种情况丝毫不会影响到原数组。
make创建
length 表示slice中已经使用的数据长度
capacity 表示slice中指针执行的数组容量,如果缺省capacity 和length大小相等
make([]T, length, capacity)
slice1 := make([]T, length)
(4)defer的工作模式
(5)匿名函数的使用(难点)
常用的感觉就是闭包和go func协程了,再说吧。。。。。
二、面向对象和并发
(1)go语言如何表现继承
go中没有extends关键字,所以没有原生级别的继承。go本质上是使用interface实现的,是使用组合来实现继承,用组合来代替继承。
在go的结构体struct,通过匿名成员的方式实现继承,比如,Student继承了Men
type Men struct { name string age int } type Student struct { Men score int }
对于接口interface,通过直接引入另一接口的方式实现继承,比如,ReadWriter继承了Reader和Writer
type Reader interface { } type Writer interface { } type ReadWriter interface { Reader Writer }
(2)接口的优点,使用场景。
实现代码解耦
(3)并发通信采用什么消息机制。
goroutine + channel数据共享
版权声明:《 Golang】面试总结 》为admin原创文章,转载请注明出处!
最后编辑:2021-3-1 08:03:14