Go面试看这里了~(三)

原文地址:Go面试看这里了~(三)

1、数组和切片的区别?

  1. 切片是指针类型,数组是值类型。

  2. 数组的长度是固定的,切片不是,切片是动态的。

  3. 切片比数组多一个容量【cap】属性。

  4. 切片的底层是数组。

  5. 数组可进行等值比较 ,切片只能进行nil值判断。

  6. 在传递时,数组是值传递,切片是引用传递。

  7. 切片包含指针、长度、容量三个属性。

2、值传递和地址传递(引用传递)如何运用?有何区别?

  1. 值传递将参数值复制一份放进对应函数,两变量地址不同,不可互相修改。

  2. 地址传递(引用传递)将变量本身传入对应函数,可对值内容进行修改。

3、切片扩容?

Go使用append内置函数实现切片扩容,策略如下:

  1. 当所需容量超过原切片容量两倍时,会使用需要的容量作为新容量。

  2. 当原切片长度<1024时,新切片容量会直接翻倍。

  3. 当原切片容量>=1024时,会反复增加25%,直到新容量超过所需容量。

4、defer的执行顺序、作用和特点?

执行顺序:defer的执行顺序与声明顺序相反,最先声明的最后执行。

作用:

  1. 处理成对的操作,如打开和关闭、连接和断开连接、加锁和释放锁等。

  2. 通过defer机制,无论函数逻辑复杂度有多高,都可保证在任何执行路径下的资源释放操作成功执行。

  3. 释放资源的defer应直接跟在请求资源的语句之后。

特点:在调用普通函数或方法前添加defer关键字就是defer的语法,当defer被执行时,其后函数会被延迟执行,直到包含defer的函数被执行完毕,其后的函数才会被正常执行,不论保护defer的函数是正常return结束,还是由于panic导致的异常结束,还可在同一函数中执行多条defer语句。
5、slice的底层实现?

切片是Go一种基本的数据结构,其设计想法是由动态数组而来,旨在为开发者可更方便的使用一种可自动增加和减少的数据结构,其本身并不是动态数据或数组指针,只是内部实现的数据结构是通过指针引用底层数组,并设定相关属性将数据读写限制在指定区域,本身只是个可读对象,工作机制类似于数组指针的一种封装,可认为是一种长度可变的数组,也因为其基于数组实现,所以它底层的内存是连续分配的,同时还具有可索引、可迭代、垃圾回收优化的特性,其数据结构定义如下:

type slice struct {
   
       array unsafe.Pointer    len   int    cap   int}

6、扩容前后的slice是否相同?

  1. 原slice还有容量可扩容(实际容量未填充完毕)时,扩容后的slice还是原来的,对切片的扩容可能影响多个指针指向相同地址的slice。

  2. 原slice容量已达到最大值时,Go默认会先开一片内存将原slice拷贝过来,之后进行append扩容,不影响原slice。

顺带提一下,复制slice有slicecopy和copy两种,最好的选择还是使用copy内置函数,别问,问就是不知道。

7、参数传递、引用类型?

Go所有传参都是值传递(传值),都是一个副本、一个拷贝,因为拷贝内容有时是非引用类型(int、string、struct等),这样函数就无法修改原内容,有的是引用类型(指针、map、slice、chan等),这样函数可修改原内容。

Go引用类型包括map、slice和channel,它们有复杂的数据结构,除申请内存外还需初始化相关属性,new计算类型大小,为其分配零值内存,返回指针,make则会被编译器翻译成具体的创建函数,之后由创建函数分配内存和初始化成员结构,之后就会返回对象,而非指针。

至此,本次分享就结束了,后期会慢慢补充。

以上仅为个人观点,不一定准确,能帮到各位那是最好的。

好啦,到这里本文就结束了,喜欢的话就来个三连击吧。

以上均为个人认知,如有侵权,请联系删除。

  

猜你喜欢

转载自blog.csdn.net/luyaran/article/details/121327837
今日推荐