一、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