前两天有个朋友去面试,把他给问自闭了。。。 拿到他的面试题后,花了一些时间,整理了以下 golang 面试题,都是比较基础的问题,留给大家作为面试参考。
1、在进行项目开发时,遇到的关于 golang 的问题有哪些?
可简单描述工作中用到的东西,协程,通道,框架、加密等等,说一些关键的技术点
2、golang 中关于 grpc 和 rest 都使用过吗?grpc 相对于 rest 的优势是什么?为什么选择 groc?
两种 API 架构概述
- grpc:gRPC 是 RPC 框架中的一种,RPC(remote procedure call 远程过程调用)框架目标就是让远程服务调用更加简单、透明。RPC 框架负责屏蔽底层的传输方式(TCP 或者 UDP)、序列化方式(XML/Json/ 二进制)和通信细节。服务调用者可以像调用本地接口一样调用远程的服务提供者,而不需要关心底层通信细节和调用过程。RPC 是一种设计理念,而 gRPC 是基于此种设计理念设计的真实框架。
- rest:描述的是在网络中 client 和 server 的一种交互形式;一个架构样式的网络系统,指的是一组架构约束条件和原则。
grpc 相对于 rest 的优势
gRPC 对接口有严格的约束条件,安全性更高,对于高并发的场景更适用
为什么选择 grpc
- grpc 有明确的接口规范和对于流的支持;
- RPC 效率更高。RPC 使用自定义的 TCP 协议,可以让请求报文体积更小,或者使用 HTTP2 协议,也可以很好的减少报文的体积,提高传输效率。
3、golang 里面常用到的技术栈有哪些?
协程、通道、web 框架、密码学等
4、gin 框架的好处是什么?
- 快速:基于 Radix 树的路由,性能非常强大。
- 支持中间件:内置许多中间件,如 Logger,Gzip,Authorization 等。
- 崩溃恢复:可以捕捉 panic 引发的程序崩溃,使 Web 服务可以一直运行。
- JSON 验证:可以验证请求中 JSON 数据格式。
- 多种数据渲染方式:支持 HTML、JSON、YAML、XML 等数据格式的响应。
- 扩展性:非常简单扩展中间件。
5、无缓冲通道和缓冲通道的区别是什么?
- 无缓冲通道,在通道满了之后就会阻塞所在的 goroutine。(需要在其他 goroutine 中取出该通道中的元素,才能解除它所在通道的阻塞,不然就会一直阻塞下去。)
- 缓冲通道,存完了东西可以不取出来,不会阻塞;
- 缓冲通道相较于无缓冲区的通道在用法上是要灵活一些的,不会出现一次写入,一次读完就会堵塞。
6 、select 的用处是什么?
过 select 可以监听 channel 上的数据流动。 select 的用法与 switch 语言非常类似,由 select 开始一个新的选择块,每个选择条件由 case 语句来描述。
示例代码如下:
7、defer 的用途和使用场景是什么?
- defer 作用:可用于捕获程序异常,在某个方法中,出现异常时,defer 可捕获此异常并进行打印,使用关键字 defer 向函数声明退出调用,即主函数退出时,defer 后的函数才被调用。defer 语句的作用是不管程序是否出现异常,均在函数退出时自动执行相关代码。
8、defer 的执行顺序是什么?
- defer 语句并不会马上执行,而是会进入一个栈,函数 return 前,会按先进后出的顺序执行。也说是说最先被定义的 defer 语句最后执行。
注:先进后出的原因是后面定义的函数可能会依赖前面的资源,自然要先执行;否则,如果前面先执行,那后面函数的依赖就没有
9、defer 函数遇到 return 以后是怎么执行的?
先 defer 再 return,函数执行之后,return 返回之前,按照先进后出的顺序执行
10、对于进程,线程,协程的理解是什么?
- 线程可以理解为轻量级的进程 协程可以理解为轻量级的线程
- 协程最大的优势就是可以轻松的创建上百万个,而不会导致系统资源衰减
11、有时候会遇到一些空的结构体,这个目的是什么?
空结构体不占任何内存,使用空结构体,可以帮咱们节省内存空间,提升性能 golang
12、map 怎么顺序读取?
map 不能顺序读取,是因为他是无序的,想要有序读取,首先的解决的问题就是,把 key 变为有序,所以可以把 key 放入切片,对切片进行排序,遍历切片,通过 key 取值。
代码示例:
13、你在项目里面会用到什么数据结构,例如 map、slice
都会用到,包括基本数据类型:int、float、string、bool ,复合数据类型有:指针、数组、切片、字典(map)、通道、结构和接口
注:map 和 slice 也会用到,当有明确的 key 值时,使用 map,如果没有明显的 key,就使用切片
14、如果用 range 修改切片元素的值,会发生什么?
我们经常会使用到 range 来帮助我们遍历一些数据,通常情况下都是查看操作多一些,但是当我们需要对其原地址上的内容进行变更时,通常都是使用 ==for i:=0; i<len(); i++== 来修改值。在使用 range 的时候,通常会将该数据结构进行拷贝,来遍历这一份拷贝后的副本,使用的是一个值传递,如果我们进行修改,修改的就只是副本,对原地址上的值不会产生任何影响。
15、了解空指针吗?
- 当一个指针被定义后没有分配到任何变量时,它的值为 nil。
- nil 指针也称为空指针。
- nil 在概念上和其它语言的 null、None、nil、NULL 一样,都指代零值或空值。
16、怎么用 go 去实现一个 set
- Go 中是不提供 Set 类型的,Set 是一个集合,其本质就是一个 List,只是 List 里的元素不能重复。
- Go 提供了 map 类型,可是咱们知道,map 类型的 key 是不能重复的,所以,咱们能够利用这一点,来实现一个 set
- 构造一个 Set 的方法
构造一个 set,首先定义 set 的类型 svg
为一个结构体类型,内部一个成员为一个 map,这也是主要咱们存储值的容器函数产生 set 的工厂性能
17、一般怎么比较两个结构体,怎么判断他们是否相等?
一般没有效率太高的方法:
- if 判断比较:使用 if 一个个比较两个结构体中元素的值:if(p1->age==p2->age),如果有一个元素不等,即是两个实例不相等。
- 指针直接比较:如果保存的是同一个实例地址,则(p1==p2)为真。
18、make 和 new 的区别是什么?
- make 只用于 chan,map,slice 的初始化;
- new 用于给类型分配内存空间,并且置零;
- make 返回类型本身,new 返回指向类型的指针。
19、说一下你对并发编程的理解?
- 所谓并发编程是指在一台处理器上“同时”处理多个任务。
- 宏观的并发是指在一段时间内,有多个程序在同时运行。
- 并发在微观上,是指在同一时刻只能有一条指令执行,但多个程序指令被快速的轮换执行,使得在宏观上具有多个进程同时执行的效果,但在微观上并不是同时执行的,只是把时间分成若干段,使多个程序快速交替的执行。
20、碰到过分布式锁的问题吗?分布式锁的原理你清楚吗?
golang 中的分布式锁可使用 etcd 进行实现,实现原理如下:
- 在 ectd 系统里创建一个 key
- 如果创建失败,key 存在,则监听该 key 的变化事件,直到该 key 被删除,回到 1
- 如果创建成功,则认为我获得了锁
以上,就是今天分享的全部内容了,希望大家通过以上 golang 面试题解决自己的疑问,找到自己满意的工作。