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")
}
相关推荐
互联网老辛7 分钟前
【读者求助】如何跨行业进入招聘岗位?
面试·个人思考
_一条咸鱼_1 小时前
大厂Android面试秘籍:Activity 权限管理模块(七)
android·面试·android jetpack
zzx_blog3 小时前
简单易懂的leetcode 100题-第一篇 字母异位词分组
面试
和和和3 小时前
防抖(Debounce)与节流(Throttle)
前端·javascript·面试
和和和3 小时前
Get与Post区别
前端·javascript·面试
FlowD3 小时前
Reflection(Reflect对象 和 Proxy对象)
前端·javascript·面试
和和和3 小时前
Token、Cookie、Session的区别
前端·javascript·面试
和和和3 小时前
JavaScript 事件委托详解与面试指南
前端·javascript·面试
逆袭的小黄鸭4 小时前
JavaScript异步编程: Promise状态机制、链式调用及静态方法解析
前端·javascript·面试
独行soc4 小时前
2025年常见渗透测试面试题- 应急响应(题目+回答)
java·前端·数据库·python·安全·面试·csrf