2

golang笔记-面试题整理01

 2 years ago
source link: https://learnblockchain.cn/article/3323
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

golang笔记-面试题整理01

前两天有个朋友去面试,把他给问自闭了。。。 拿到他的面试题后,花了一些时间,整理了以下golang面试题,都是比较基础的问题,留给大家作为面试参考。

前两天有个朋友去面试,把他给问自闭了。。。
拿到他的面试题后,花了一些时间,整理了以下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语句来描述。

示例代码如下:

select {
    case <-chan1:
        // 如果chan1成功读到数据,则进行该case处理语句
    case chan2 <- 1:
        // 如果成功向chan2写入数据,则进行该case处理语句
    default:
        // 如果上面都没有成功,则进入default处理流程
}

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取值。

代码示例:

package main

import (
	"fmt"
	"sort"
)

func main()  {
	map1 := make(map[int]string)
	map1[1] = "红孩儿"
	map1[2] = "牛魔王"
	map1[3] = "白骨精"
	map1[4] = "小钻风"
	map1[5] = "黄袍怪"
	map1[6] = "孔雀大明王"
	map1[7] = "白毛鼠"
	
	//获取所有的key,取值后存储到切片
	keys := make([]int,0,len(map1))
	for k,_ := range map1{
		keys = append(keys,k)
	}
	fmt.Println(keys)


	//对key值进行排序
	//内置函数sort包下的排序方法
	sort.Ints(keys)
	fmt.Println(keys)
	for _,key := range keys{
		fmt.Println(key,"-->",map1[key])
	}

	//冒泡排序方法
	for i := 1;i<len(keys);i++ {
		for j := 0;j<len(keys)-1;j++ {
			if keys[j] > keys[j+1] {
				keys[j],keys[j+1] = keys[j+1],keys[j]
			}
		}
		}
	for i := 1;i<=len(keys);i++ {
		fmt.Println(i,"-->",map1[i])
	}
}

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

//set类型
type Set struct {
    m map[int]Empty
}

为一个结构体类型,内部一个成员为一个map,这也是主要咱们存储值的容器函数产生set的工厂性能

//返回一19et
func SetFactory() *Set{
    return &Set{
        m:map[int]Empty{},#### 。所谓并发编程是指在一台处理器上“同时”处理多个任务。
}
}

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面试题解决自己的疑问,找到自己满意的工作。

如果文章中如果有不太正确的地方,欢迎指正,可以添加我的个人微信,备注:地区-职业方向-昵称,欢迎来撩,加入golang技术交流群,与更多的golang开发者、技术大佬学习交流。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK