go 面试问题,go 笔试题,GO必知必会的常见面试题汇总

go 面试问题,go 笔试题,GO必知必会的常见面试题汇总

本文主要介绍GO必知的常见面试问题总结。

目录

什么是引入值类型和引用类型值类型?参考文献的类型有哪些?值类型和引用类型有什么区别?垃圾收集优于千字堆和栈堆切片比较。深层复制和浅层复制操作对象比较的详细说明如下:new和makenew特性,例如:使用技巧。makemake函数的函数签名特征。使用技巧总结:new和make的区别。go的地图实现排序解决方案idea代码实现:运行结果转义分析。最后,听我说。

引言

今年互联网的就业环境真的不好。很多朋友都做了优化。

平时工作中,除了好好编码,贯穿项目,还要内外兼修。你得练好自己的内功和招式,才能应对突发的变故,顺利拿到新的offer。别问我怎么知道的。

这个月我会整理和分享一系列后端工程师面试相关的文章。知识脉络图如下:

JAVA/GO/PHP面试中常见的知识点DB:MySQL PGSQL Cache:Redis Memcache MongoDB数据结构算法微服务高并发流媒体WEB3.0源代码分析

通过这一系列的文章,我们不仅可以对后端开发相关的知识点进行回顾和梳理,还可以知道当前的市场环境对服务器端开发,尤其是对Go开发工程师来说,需要哪些核心技术。

值类型和引用类型

值类型有哪些?

基本数据类型都是值类型,包括:int系列、float系列、bool、string、array、struct。

引用类型有哪些?

指针、切片、接口接口、管道通道

值类型和引用类型的区别?

值类型将值本身存储在内存中,而引用类型将值的内存地址存储在内存中。值类型的内存通常分配在栈中,引用类型的内存通常分配在堆中。

垃圾回收

类型的引用内存在堆中分配。当堆中没有变量引用内存地址时,内存地址对应的数据存储空间就变成了垃圾,会被GO语言的GC回收。

一图胜千言

堆和栈

在Go中,堆栈的内存由编译器自动分配和释放。堆栈区域通常存储函数参数、局部变量和调用函数框架,它们是在函数创建时分配的,但在函数退出时被销毁。

一个goroutine对应一个stack,是call stack的缩写。一个堆栈通常包含许多堆栈框架,这些框架描述了函数之间的调用关系。每一帧对应一个未返回的函数调用,它也以堆栈的形式存储数据。

与堆栈不同,应用程序运行时只有一个堆。狭义地说,内存管理只针对堆内存。程序运行过程中,可以主动从堆中申请内存,由Go的内存分配器分配,垃圾收集器收集。

切片

比较

切片不能互相比较。我们不能使用==运算符来确定两个切片是否包含所有相等的元素。

切片唯一合法的比较操作是与nil进行比较。

比较的详解

若要检查切片是否为空,您应该使用

透镜==0

来判断,而不应该使用

s==零

来判断。

原因是nil值的切片没有底部数组,nil值的切片长度和容量都是0。但我们不能说一个长度和容量都为0的切片就一定为零。

通过下面的例子我们有了很好的理解:

var S1[]int//len(S1)=0;cap(S1)=0;s1==零

S2:=[]int { }//len(S2)=0;cap(S2)=0;s2!=零

s3 :=make([]int,0)//len(S3)=0;cap(S3)=0;s3!=零

所以判断一个切片是否为空,如果用len(s)==0来判断,就不应该用s==nil来判断。

根本原因是后两种初始化方法已经给切片分配了空间,所以即使切片是空的,也不等于零。但是len(s)==0成立,则切片必须为空。

注意:在go中,var是一个声明关键字,不会打开内存空间;只有当:=或make关键字用于初始化时,内存空间才会打开。

深拷贝和浅拷贝

操作对象

深度复制和浅复制操作的对象是Go语言中的引用类型。

区别如下:

引用类型的特点是在内存中存储其他值的内存地址;而值类型将实值存储在内存中。

在go语言中,我们用:=赋值来指代浅拷贝的类型,即内存地址被拷贝,两个变量对应同一个内存地址对应同一个值。

a :=[]string{1,2,3}

乙:=甲

如果我们通过copy()函数赋值,就是深度拷贝,赋值的是实值而不是内存地址,会在内存中打开一个新的内存空间。

例子如下:

a :=[]string{1,2,3}

b :=make([]string,len(a),cap(a))

副本(b,a)

new和make

new

是NewGo语言的内置函数,其函数签名如下:

func new(Type) *Type

特点

Type表示类型,新函数只接受一个参数,是type *Type表示类型指针,新函数返回指向该类型内存地址的指针。

新功能不常用。类型的指针是使用new函数获得的,指针对应的值是该类型的零值。

举个例子:

func main() {

a :=new(int)

b :=新(布尔值)

fmt。Printf(%Tn ,a) //*int

fmt。Printf(%Tn ,b) //*bool

fmt。Println(*a) //0

fmt。Println(*b) //false

}

使用技巧

Var * int只是声明了一个指针变量A,但是没有初始化。作为一个引用类型,指针在拥有内存空间之前需要初始化,然后才能赋值。

应该使用内置的新函数对进行初始化,如下所示,然后可以对其进行正常赋值:

func main() {

变量a *int

a=新的(整数)

*a=10

fmt。Println(*a)

}

make

Make也用于内存分配,和new不一样。只用于slice、map、channel的内存创建,返回的类型是这三个类型本身,而不是它们的指针类型。因为这三种类型都是引用类型(指针类型),所以不需要返回它们的指针。

make函数的函数签名

func make(t型,尺寸.IntegerType)类型

特点

make函数是不可替代的。我们在使用切片、贴图、通道的时候,都需要用make进行初始化,然后才能操作。

使用技巧

Var map [string] int这段代码只声明了变量b是一个map类型的变量,它需要像下面的示例代码一样用make函数进行初始化,然后才能被赋予一个键值对:

func main() {

var b map[string]int

b=make(map[string]int,10)

B[分数]=100

fmt。印刷线路(b)

}

小结:new与make的区别

两者都用于内存分配。Make只用于切片、贴图、通道的初始化,返回类型本身(类型本身是引用类型(指针类型));new用于内存分配时,对应类型的零值(如0,false)存储在内存中,返回该类型的指针类型。

go的map实现排序

我们知道go语言中map类型的底层是通过hash实现的,hash是乱序的,不支持排序。

如果我们的数据是以map类型存储的,那么如何对其进行排序呢?

解决思路

对地图的键进行排序,然后根据排序后的键遍历输出地图。

代码实现:

主包装

导入(

fmt

数学/兰特

排序

时间

)

func main() {

Rand.seed (time.now()。UnixNano())//初始化随机数种子

var score map=make(map[string]int,30)

对于I:=0;i lt30;我{

Key:=fmt.sprintf (stud ,I)//生成以stu开头的字符串

值:=兰特。Intn(30) //生成一个从0到50的随机整数

scoreMap[key]=值

}

//取出map中的所有键,并存储在切片键中

var keys=make([]string,0,30)

对于关键字:=范围评分图{

keys=append(keys,key)

}

//对切片进行排序

排序。字符串(键)

//根据排序的键遍历地图

for _,key :=范围键{

fmt。Println(key,scoreMap[key])

}

}

运行结果

逃逸分析

逃遁的分析比较辛苦,我单独写了一篇:#【疯狂刷面试题】详细去逃遁分析。

最后,听我说

不要奇怪我为什么要发表这一系列的文章。是的,我最近失业了,所以掘金也失业很久了。我正在努力争取一份新的工作,但是我花了两个星期才得到它。

我想真诚地劝告我所有的朋友:如果你对你的工作不满意,请三思而后行,尤其不要以裸辞为荣。

如果你的公司或者你的部门发展良好,请加倍珍惜这份工作,踏踏实实,为公司做贡献,把不断学习的口号变成落地输出的行动,真正做到用肉眼提升。

如果你和我一样不幸被离开,请不要沮丧,不要抱怨。快速调整自己的负面情绪,进一步提升自己才是王道。

祸从口出:祸从口出,福从口出。

暂时的挫折在人生的长河中不算什么。我们应该做的是尽快收拾行囊,走向下一个更好的前方。尽管道路会崎岖不平,但我们一定会继续前进。

以上是GO必知的常见面试问题汇总的详细内容。更多关于GO面试问题的信息,请关注我们的其他相关文章!

go 面试问题,go 笔试题,GO必知必会的常见面试题汇总