以下内容是根据ChatGPT得到的一些面试题
Golang 高频面试题
1. 什么是 Goroutine?如何创建 Goroutine?
goroutine 是 Go 语言 中的轻量级线程实现,由 Go 运行时(runtime)管理。Go 程序会智能地将 goroutine 中的任务合理地分配给每个 CPU。
- 普通函数创建goroutine
1 | go f(params) |
- 匿名函数创建goroutine
1 | go func(params) { |
2. 什么是 Channel?如何使用 Channel 进行通信?
channel 就是 goroutine 之间通过通信来共享内存的手段。
Go语言中的通道(channel)是一种特殊的类型。在任何时候,同时只能有一个 goroutine 访问通道进行发送和获取数据。goroutine 间通过通道就可以通信。
通道像一个传送带或者队列,总是遵循先入先出(First In First Out)的规则,保证收发数据的顺序。
阻塞场景梳理
操作 | 为空 | 非空已关闭 | 非空未关闭 |
---|---|---|---|
close | panic |
panic |
成功close |
写入 | 永久阻塞 | panic |
成功写入或阻塞 |
读取 | 永久阻塞 | 永不阻塞 | 成功读取或阻塞 |
3. 什么是 defer 关键字?它有什么作用?
golang中的defer
关键字用来声明一个延迟函数,该函数会放在一个列表中,在defer
语句的外层函数返回之前系统会执行该延迟函数。
defer
特点有: 函数返回之前执行 可以放在函数中任意位置
4. 如何实现并发安全的 Map?
- 加读写锁:
sync.RWMutex
- 分片加锁
sync.map
5. 如何实现一个 HTTP Server?
1 | package main |
6. 如何进行内存管理和垃圾回收?
GC垃圾回收机制
Go1.3 使用的是标记清除法
Go1.5 三色标记法
Go1.8 三色标记 + 混合写屏障
这个 GC 什么时候会被触发呢?
一是堆内存的分配达到控制器计算的触发堆大小,初始大小环境变量
GOGC
,之后堆内存达到上一次垃圾收集的 2 倍时才会触发 GC
二是如果一定时间内没有触发,就会触发新的循环,该触发条件由runtime.forcegcperiod
变量控制,默认为 2 分钟。
7. 什么是接口?如何实现接口?
在Golang 中,接口是一组方法签名。 当类型为接口中的所有方法提供定义时,它被称为实现接口。
如果一个任意类型 T 的方法集为一个接口类型的方法集的超集,则我们说类型 T 实现了此接口类型。T 可以是一个非接口类型,也可以是一个接口类型。
8. 如何进行单元测试和性能测试?
- 单元测试
1 | func TestHello(t *testing.T) {} |
- 基准测试
1 | func BenchmarkHello(b *testing.B) {} |
- 模糊测试
1 | func FuzzkHello(f *testing.F) {} |
9. 如何进行并发编程调试和排错?
- 使用Go标准库中pprof来对代码运行过程进行分析:
1 | func main() { |
10. 如何优化 Golang 程序的性能和资源利用率?
- 问题分析: 在服务上运行一些性能分析,并检查是什么导致 CPU 的高消耗,看看是否可以做些优化工作。
- 升级版本: 将 GO 升级到最新的稳定版本(软件生命周期中的关键一步)
- 使用工具分析程序: pprof,trace等定位出问题区域
Golang Hertz 面试题
1. 什么是 Hertz 框架?它有哪些特点和优势?
Hertz 是一个超大规模的企业级微服务 HTTP 框架,具有高易用性、易扩展、低时延等特点。
2. 如何使用 Hertz 框架进行 Web 开发?
3. 如何进行路由配置和参数解析?
4. 如何进行中间件配置和使用?
5. 如何进行模板渲染和静态文件服务?
6. 如何进行数据库操作和 ORM 映射?
7. 如何进行 Session 和 Cookie 管理?
8. 如何进行日志记录和错误处理?
目前
hlog
支持zap
和logrus
的拓展使用; 推荐使用zap
9. 如何进行性能优化和安全防护?
监控, 链路追踪, 服务注册与发现
10. Hertz 框架与其他 Web 框架的比较,有哪些优缺点?
- 优点: 稳定性, 高易用性, 易扩展, 低延时
Golang Kitex 面试题
1. 什么是 Kitex 框架?它有哪些特点和优势?
Kitex 字节跳动内部的 Golang 微服务 RPC 框架,具有高性能、强可扩展的特点,针对字节内部做了定制扩展。
2. 如何使用 Kitex 框架进行微服务开发?
基于服务注册和发现
3. 如何进行服务注册和发现?
- 基于 Etcd 实现服务注册与发现
- 基于 Nacos 实现服务注册与发现
4. 如何进行负载均衡和容错处理?
kitex 的负载均衡扩展方式和 gRPC 基本一样, 是通过实现 Loadbalancer
接口. 它的职责也是在每个 rpc 调用之前选择一个连接返回. 首先查看接口定义:
1 | // Loadbalancer generates pickers for the given service discovery result. |
5. 如何进行协议编解码和数据传输?
6. 如何进行中间件配置和使用?
7. 如何进行服务治理和监控管理?
8. 如何进行性能优化和安全防护?
- 性能优化:
- 减少内存操作
- buffer 管理
- string / binary 零拷贝
- 预计算
- 使用 SIMD 优化 Thrift 编码
- 减少函数调用
9. Kitex 框架与其他微服务框架的比较,有哪些优缺点?
高性能
扩展性
多消息协议
多传输协议
多种消息类型
服务治理
代码生成
10. Kitex 框架在实际项目中的应用场景和案例有哪些?
- 支付,订单,通知,账号等可以单独抽离的微服务
Golang Kratos 面试题
1. 什么是Kratos框架?它的主要特点是什么?
Kratos是一款基于Go语言的微服务框架,由Bilibili开源。它的主要特点包括高性能、易扩展、易用性强、支持多种协议等。
2. Kratos框架中的中间件有哪些?请简述它们的作用。
Kratos框架中的中间件包括日志中间件、链路追踪中间件、限流中间件等。
- 日志中间件用于记录请求和响应信息,
- 链路追踪中间件用于跟踪请求在系统内部的传递情况,
- 限流中间件则可以控制请求流量,防止系统过载。
3. Kratos框架支持哪些协议?
Kratos框架支持HTTP/1.1、HTTP/2和gRPC协议。
4. Kratos框架如何实现服务注册与发现?
Kratos框架使用etcd作为服务注册与发现组件。当一个服务启动时,它会将自己注册到etcd上,并定期向etcd发送心跳以保持自己在etcd上的存活状态。其他服务可以通过查询etcd来获取可用服务列表,并根据需要进行调用。
5. Kratos框架如何实现负载均衡?
Kratos框架使用go-grpc-middleware库来实现负载均衡。该库提供了多种负载均衡策略,包括轮询、随机等。当一个客户端需要调用一个服务时,它会从可用服务列表中选择一个地址,并将请求发送到该地址上。如果该地址不可用,则会尝试选择另一个地址进行调用。
Golang Gin 面试题
1. 什么是Gin框架?它的主要特点是什么?
Gin是一个基于Go语言的Web框架,由Gin Gonic开源。它的主要特点包括高性能、易扩展、易用性强、支持中间件等。
2. Gin框架中的中间件有哪些?请简述它们的作用。
Gin框架中的中间件包括Logger、Recovery、CORS等。Logger用于记录请求和响应信息,Recovery用于恢复程序崩溃时的状态,CORS用于处理跨域请求。
3. Gin框架支持哪些HTTP方法?
Gin框架支持GET、POST、PUT、PATCH、DELETE等HTTP方法。
4. Gin框架如何实现路由?
Gin框架使用Router来实现路由。当一个请求到达时,Router会根据请求路径和HTTP方法选择对应的处理函数进行处理。
5. Gin框架如何实现参数绑定?
Gin框架使用Context来实现参数绑定。当一个请求到达时,Context会将请求参数解析并绑定到对应的结构体上,然后将结构体传递给处理函数进行处理。
Golang Beego 面试题
1. 什么是 Beego?它有哪些特点?
Beego 是一个基于 Go 语言的 Web 开发框架,它具有高性能、简单易用、灵活可扩展等特点。Beego 提供了路由、模板、会话管理、日志记录等常用功能,并且支持 ORM 框架(如 GORM)和缓存框架(如 Redis)等。
2. 如何创建一个 Beego 应用程序?
可以使用命令行工具 bee 来创建一个 Beego 应用程序。首先需要安装 bee 工具,然后在命令行中执行以下命令:
bee new myapp
其中 myapp 是应用程序的名称。执行完上述命令后,bee 工具会自动创建一个名为 myapp 的应用程序,并生成一些默认的文件和目录结构。
3. 如何定义路由?
可以使用 beego.Router 函数来定义路由。例如:
beego.Router(“/hello”, &controllers.MainController{})
其中 “/hello” 是路由路径,&controllers.MainController{} 是处理该路由的控制器。
4. 如何使用模板引擎?
Beego 默认使用的是 Go 的模板引擎(html/template),可以通过 beego.SetViewsPath 函数设置模板文件所在的目录,然后在控制器中使用 this.TplName 和 this.Data 函数来渲染模板。例如:
func (this *MainController) Get() {
this.Data[“name”] = “world”
this.TplName = “index.tpl”
}
其中 index.tpl 是模板文件名,name 是传递给模板的数据。
5. 如何进行会话管理?
Beego 提供了 Session 模块来进行会话管理。可以通过 beego.BConfig.WebConfig.Session.SessionOn 设置是否启用会话管理,在控制器中使用 this.SetSession 和 this.GetSession 函数来设置和获取会话数据。例如:
func (this *MainController) Get() {
this.SetSession(“username”, “admin”)
username := this.GetSession(“username”)
}
6. 如何进行 ORM 操作?
Beego 支持多种 ORM 框架,如 GORM、XORM 等。可以通过 beego.AppConfig.String 函数获取数据库连接字符串,在控制器中使用相应的 ORM 方法进行增删改查操作。例如:
func (this *MainController) Get() {
var users []models.User
orm.NewOrm().QueryTable(“user”).All(&users)
}
其中 models.User 是定义在 models 包中的用户数据结构。
7. 如何进行缓存操作?
Beego 支持多种缓存框架,如 Redis、Memcache 等。可以通过 beego.AppConfig.String 函数获取缓存连接字符串,在控制器中使用相应的缓存方法进行读写操作。例如:
1 | func (this *MainController) Get() { |