GO面试


1.defer执行顺序
先定义,后执行

defer在panic之前执行

defer虽然是在return的时候才执行,但是如果参数是函数,会先执行参数,并且把结果放到调用栈里面

2.for循环的时候千万不要用tmp的指针

3.array赋值是只拷贝

func main() {
    c := [3]int{1, 2, 3} 
    d := c 
    c[0] = 999 
    fmt.Println(d) // 输出[1, 2, 3] 
}

c[0]不会修改d

slice数据结构:

  • array
  • len
  • cap

slice底层是指向一个固定大小的数组,当容量够的时候不会扩容,会忘数组中添加数据;当容量不够的时候,先扩容。

4.静态语言和动态语言
静态语言:如果在编译的时候就知道变量的类型,则是静态语言,优点是编译器可以在编译阶段做一些类型检查。例如:c,c++,java,go

动态语言:在编译的时候不知道变量类型,因此检查变量类型需要再运行时做。一般是脚本语言,优点是开发快,但是维护难。比如:python,php,javascript

5.使用Go的好处

  • 语言层面支持并发。并且并发度特别高
  • 内置GC
  • 简单易学
  • 代码格式强一致
  • 跨平台

6.go什么时候会发生内存逃逸

golang程序变量会携带有一组校验数据,用来证明它的整个生命周期是否在运行时完全可知。如果变量通过了这些校验,它就可以在栈上分配。否则就说它 逃逸 了,必须在堆上分配

  • 在方法内把局部变量作为指针返回。
  • 发送指针到channel
  • 切片的元素是指针
  • 切片重新分配大小
  • 在interface类型的变量上调用方法

7.拷贝大切片比小切片的代价大吗?

不大,代价是一样的。因为切片底层结构是三个属性:1个指向data的指针和2个int类型的属性,切片的拷贝如果不扩容,只会是这三个属性的值拷贝。代价与切片容量和元素的多少无关

8.unsafe.Pointer与uintptr的区别

unsafe.Pointer只是单纯的通用指针类型,用于转换不同类型指针,它不可以参与指针运算;

而uintptr是用于指针运算的,GC 不把 uintptr 当指针,也就是说 uintptr 无法持有对象, uintptr 类型的目标会被回收

unsafe.Pointer 可以和 普通指针 进行相互转换

unsafe.Pointer 可以和 uintptr 进行相互转换

9.mysql为什么用B+树

与B树比较,有三点优势:

  • 所有数据都在叶子节点,非叶子节点相当于是一个稀疏索引。这样非叶子节点就比较小,一个数据页上可以存放更多的非叶子节点,减少磁盘io
  • B+树所有叶子节点都连起来了,比B树更容易遍历。B树遍历需要用到中序遍历
  • 适合范围查询。由于B树非叶子节点也保存了数据,因此不好做范围查询

文章作者: Alex
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Alex !
  目录