golang面试题

基础题

Go 的优势是什么?

  • 天然支持并发,通过Goroutine和通道实现的
  • 支持静态链接,也就是把依赖也打到可执行文件
  • 编译语言,效率更高,相对于php、、python、js

Go 程序中的包是什么?

相当于php中的命名空间 + 类库

make和new有什么区别?

数组和切片的区别是什么?

1、数组长度固定,切片长度不固定

2、**数组是值类型,切片是引用类型。**当切片传递给函数时,即使它是按值传递的,实际还是引用传递

channel有什么作用?

负责协程间通信

什么是 Goroutine?你如何停止它?

协程。使用context包停止

如何在运行时检查变量类型?

反射

defer关键字有什么作用?

提前定义好当前函数返回之前需要执行的代码,比如关闭文件或释放资源等操作

什么是交叉编译?

在一个平台上生成可以在另外一个平台执行的文件。具体命令如下:

bash 复制代码
# 要去linux下执行
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build main.go
# 要去Mac下执行
CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build main.go
# 要去win下执行
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build main.go

进阶题

如何在Go语言中实现错误处理?

通过error 接口,处理非致命性错误,例如打开一个不存在的文件、例如网络请求失败需要重试

通过panic,处理致命错误,需要立即中断,例如数据库挂了

推荐方式:尽量使用error

并发同步是什么?在Go语言中,如何实现并发同步?

多个线程或协程并发执行。golang使用goroutine+channel来实现,需要考虑以下问题:

1、开启协程使用goroutine

2、协程间通信使用channel

3、数据竞争处理使用互斥锁(Mutex)、读写锁(RWMutex)、原子操作(Atomic)

例外:尽量避免使用全局变量

Go语言中的并发安全性是什么?如何确保并发安全性?

数据竞争问题。见上题3

Map是线程安全的吗?

线程不安全, 一个 goroutine 在对 map 进行写的时候,另外的 goroutine 不能进行读和写操作

Go语言的泛型是什么,它们有什么用途?

编写模板适应所有类型,简化代码,否则就需要用接口和类型断言。从1.18版本之后才支持

什么是反射,什么场景使用?

反射是指在程序运行时检查变量和值的类型,并且可以改变它们的值或者调用它们的方法。

使用场景:

1、结构体转json时换key的别名

2、判断变量类型执行不同的方法,如1.18版本之前实现泛型

如何进行垃圾回收的?

三色标记原理、写屏障

GMP调度流程

原子操作和锁的区别

在Go语言中,如何进行网络编程?

使用net包

互斥锁(Mutex)

使用场景:写操作频繁

什么是Mutex互斥锁?它在并发编程中的作用是什么?

Mutex互斥锁是一种并发控制机制,用于保护共享资源的访问,以防止多个goroutine同时对该资源进行修改。它提供了两个基本操作:Lock和Unlock。当一个goroutine获得了Mutex的锁时,其他goroutine将被阻塞,直到该goroutine释放了锁。

读写锁(RWMutex)

使用场景:读操作频频率远高于写操作

有了Mutex为什么还需要RWMutex,解决了什么问题?

虽然Go语言中的Mutex互斥锁可以保证对共享资源的独占访问,但在大量并发读操作和少量并发写操作的场景下,Mutex会造成不必要的锁等待,影响性能。因此,引入了RWMutex读写锁,它在读锁占用的情况下,会阻止写操作,但不阻止读操作;在写锁占用的情况下,会阻止其他goroutine(读和写)进来,整个锁相当于由该goroutine独占。这样可以提高读操作的并发性,从而提高性能。因此,当需要明确区分reader和writer的协程场景,且是大量的并发读、少量的并发写时,可以考虑使用RWMutex替换Mutex

什么是 sync.Once

只执行一次,类似单例模式

sync.Pool 有什么用

需要重复分配、回收内存的地方可以用,如数据库连接池,从而减少并复用内存

有哪些常用的包,分别用来做什么?

WaitGroup:用于等待一组goroutine执行完毕,可以确保主goroutine不会过早退出

Go 复制代码
package main

import (
	"fmt"
	"sync"
	"time"
)

func worker(id int, wg *sync.WaitGroup) {
	defer wg.Done()
	time.Sleep(time.Second)
}

func main() {
	var wg sync.WaitGroup

	for i := 1; i <= 3; i++ {
		wg.Add(1)
		go worker(i, &wg)
	}
	wg.Wait()
	fmt.Println("All workers finished")
}
相关推荐
阿芯爱编程11 分钟前
最长和谐子序列,滑动窗口
前端·javascript·面试
拉不动的猪2 小时前
JQ常规面试题
前端·javascript·面试
每次的天空4 小时前
Android第十七次面试总结(Java数据结构)
android·java·面试
jinmo_C++5 小时前
第十四届蓝桥杯_省赛B组(C).冶炼金属
c语言·职场和发展·蓝桥杯
前端小巷子5 小时前
浏览器的渲染流程:从 HTML 到屏幕显示
前端·javascript·面试
寒山李白5 小时前
Java中高并发线程池的相关面试题详解
java·开发语言·面试·高并发·线程池·多线程
·云扬·5 小时前
【PmHub面试篇】PmHub中基于Redis加Lua脚本的计数器算法限流实现面试专题解析
redis·面试·lua
?!7145 小时前
算法打卡17天(补)
c++·算法·职场和发展
会飞的架狗师6 小时前
【面试题】如何保证MQ的消息不丢失、不重复
java·面试·kafka·java-rocketmq
阳火锅7 小时前
为了实现AI对话的打字效果,我封装一个vue3自定义指令
前端·vue.js·面试