golang常见的问题

1.切片与数组的区别

在 Go 中,与 C 数组变量隐式作为指针使用不同,Go 数组是值类型,赋值和函数传参操作都会复制整个数组数据。假想每次传参都用数组,那么每次数组都要被复制一遍。如果数组大小有 100万,在64位机器上就需要花费大约 800W 字节,即 8MB 内存。这样会消耗掉大量的内存。

于是乎有人想到,函数传参用数组的指针。这样更加高效的利用内存,性能也比之前的好。

不过传指针会有一个弊端,万一原数组的指针指向更改了,那么函数里面的指针指向都会跟着更改。

切片的优势也就表现出来了。用切片传数组参数,既可以达到节约内存的目的,也可以达到合理处理好共享内存的问题。打印结果第二行就是切片,切片的指针和原来数组的指针是不同的。

并非所有时候都适合用切片代替数组,因为切片底层数组可能会在堆上分配内存,而且小数组在栈上拷贝的消耗也未必比 make 消耗大。

2. 切片的底层实现

切片是基于数组实现的,它的底层是数组,它自己本身非常小,可以理解为对底层数组的抽象。因为基于数组实现,所以它的底层的内存是连续分配的,效率非常高,还可以通过索引获得数据,可以迭代以及垃圾回收优化

切片本身并不是动态数组或者数组指针。它内部实现的数据结构通过指针引用底层数组,设定相关属性将数据读写操作限定在指定的区域内。切片本身是一个只读对象,其工作机制类似数组指针的一种封装。

切片对象非常小,是因为它是只有3个字段的数据结构:

  • 指向底层数组的指针
  • 切片的长度
  • 切片的容量

这3个字段,就是Go语言操作底层数组的元数据。

3. defer、 return、返回值三者顺序

defer、 return、返回值 三者的执行顺序是 : return 最先给返回值赋值;接着 defer 开始执行一些收尾工作;最后 RET 指令携带返回值退出函数。

4.defer与panic

在panic语句后面的defer语句不被执行

5. 多个defer语句的执行顺序是逆序执行

当出现多条 defer 语句时以逆序执行(类似栈,即后进先出)。示例代码:

 

1
2
3
4
5
func deferSample() {
    for i := 0; i < 5; i++ {
        defer fmt.Printf("%d ", i)
    }
}

 

上述代码将会输出:4 3 2 1 0

6. new与make的区别

  func new(Type) *Type
  func make(t Type, size ...IntegerType) Type
make 的作用是为 slice,map 或 chan 初始化并返回引用(T)。

make返回的还是这三个引用类型本身;而new返回的是指向类型的指针。

7. 常用的go命令

go env: #用于查看go的环境变量

go run: #用于编译并运行go源码文件

go build: #用于编译源码文件、代码包、依赖包

go get: #用于动态获取远程代码包

go install: #用于编译go文件,并将编译结构安装到bin、pkg目录

go clean: #用于清理工作目录,删除编译和安装遗留的目标文件

go version: #用于查看go的版本信息

 8.go的协程

协程和线程都可以实现程序的并发执行;

通过channel来进行协程间的通信;

只需要在函数调用前添加go关键字即可实现go的协程,创建并发任务;

关键字go并非执行并发任务,而是创建一个并发任务单元;

9.说说go中switch

单个case中,可以出现多个结果选项

只有在case中明确添加fallthrough关键字,才会继续执行紧跟的下一个case

10.有哪些引用类型

数组切片、字典(map)、通道(channel)、接口(interface)

 11. 说说go中channel特性

A. 给一个 nil channel 发送数据,造成永远阻塞

B. 从一个 nil channel 接收数据,造成永远阻塞

C. 给一个已经关闭的 channel 发送数据,引起 panic

D. 从一个已经关闭的 channel 接收数据,如果缓冲区中为空,则返回一个零值

E. 无缓冲的channel是同步的,而有缓冲的channel是非同步的

 

12. go触发异常的场景

A. 空指针解析

B. 下标越界

C. 除数为0

D. 调用panic函数

13. go中select机制

A. select机制用来处理异步IO问题

B. select机制最大的一条限制就是每个case语句里必须是一个IO操作

C. golang在语言级别支持select关键字

 

14.GoStub的作用

A. GoStub可以对全局变量打桩

B. GoStub可以对函数打桩

C. GoStub不可以对类的成员方法打桩

D. GoStub可以打动态桩,比如对一个函数打桩后,多次调用该函数会有不同的行为

 

15.有关垃圾回收机制

常见的垃圾回收机制
引用计数法:当被引用的对象被创建或者赋值时自动加一,当引用对象的对象被销毁或者更新时自动减一
标记清除法:从根变量遍历所有被引用的对象,所有能够发现被引用的全部标记,剩下没标记的清除(每次启动垃圾回收机制会暂停所有代码的运行)

go语言1.3以前老式的标记清除一起会暂时暂停代码
1.3标记清除分离,先暂停代码标记,之后清除任务与其他任务一起并行
1.4标记遍历时只会遍历指针指向的对象
1.5三色标记法,每次mark不会遍历整个内存,而是渐进式

GC就是指垃圾回收机制

三色标记:白色:未访问的,灰色:本对象访问了,但它引用的对象未访问完,黑色本对象访问了,并且它引用的对象都访问完了

 
posted @ 2021-02-25 17:17  爱晒太阳的懒猫。。  阅读(168)  评论(0编辑  收藏  举报