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")
}
相关推荐
CXDNW4 分钟前
【网络面试篇】HTTP(2)(笔记)——http、https、http1.1、http2.0
网络·笔记·http·面试·https·http2.0
阑梦清川4 小时前
在鱼皮的模拟面试里面学习有感
学习·面试·职场和发展
劲夫学编程5 小时前
leetcode:杨辉三角
算法·leetcode·职场和发展
鱼跃鹰飞13 小时前
大厂面试真题-简单说说线程池接到新任务之后的操作流程
java·jvm·面试
钱钱钱端15 小时前
【压力测试】如何确定系统最大并发用户数?
自动化测试·软件测试·python·职场和发展·压力测试·postman
程序员清风15 小时前
浅析Web实时通信技术!
java·后端·面试
测试199816 小时前
外包干了2年,快要废了。。。
自动化测试·软件测试·python·面试·职场和发展·单元测试·压力测试
mingzhi6117 小时前
渗透测试-快速获取目标中存在的漏洞(小白版)
安全·web安全·面试·职场和发展
嚣张农民17 小时前
一文简单看懂Promise实现原理
前端·javascript·面试
Liknana19 小时前
Android 网易游戏面经
android·面试