面试题
- Go 语言中值传递和引用传递的区别是什么?
Go 中的所有变量都是值传递的。不支持引用传递。 - Go 语言中指针的用法?
指针用于存放变量的地址。使用&取地址,使用解引用。如ptr可以访问ptr指向的变量。 - Go 语言中 struct 的用法?
结构体用于组织数据。可以包含不同类型的字段,并带有方法。 - Go 语言中 interface 的用法?
interface 用于描述一个变量的行为,而不需要详细的类型信息。它可以让我们设计出更加松散耦合和更加易于扩展的程序。 - Go 语言中 goroutine 的用法?
goroutine 用来描述轻量级的线程。可以使用 go 关键字在一个 goroutine 中启动新的 goroutine。 - Go 语言中 channel 的用法?
channel 用于在 goroutine 之间传送和通信数据。需要 make 函数进行初始化。 - Go 语言中 defer 的用法?
defer 用于在函数结束前执行一些语句。这些语句会被推迟到函数结束执行。 - Go 语言中 panic 和 recover 的用法?
当panic被调用时,它会停止当前的goroutine,并展开栈轨迹,直到找到一个对应的recover函数。recover只能被延迟被调用的defer的函数调用。 - Go 语言中变量作用域的规则?
在Go中,变量的作用域依赖于定义变量的代码块。变量只在定义它的块中可见。 - Go 语言中的类型判断有哪些?
if-else 、type switch 、type assertion。
垃圾回收机制
Go语言的垃圾回收机制主要由GC(垃圾回收器)实现。它有以下几点特征:
- 引用计数:GC通过引用计数来判断是否回收一个对象。当一个对象的引用计数减到0时,它将被回收。但是引用计数有误差,无法处理循环引用的问题。
- 标记清除算法:GC首先通过标记reachable(可达)对象,然后回收所有未标记的对象。它通过 Breadth-First Search 算法来标记reachable对象。这个方法可以处理循环引用问题。
- Go的GC避免情况复杂的跟踪检查,只需简单的push/pop操作即可进行标记。这是Go GC高效的原因之一。
- Go有句柄机制,它用于管理内存和类型信息之间的对应关系,可以加快GC的标记速度。
- 在运行时,Go会定期触发GC垃圾回收,当内存用量超过了阀值就会进行回收。回收频率可以通过GOGC环境变量进行设置。
- Go的GC回收速度快,因此使用 Go 写的程序中很少出现明显的垃圾回收暂停现象。
- Go的GC不会设置内存归零,回收的内存会被新的对象覆盖。所以,无法通过分析内存内容追踪到之前的对象。
- Go的GC是确定性的,不需要手动干预。程序员无需考虑内存回收问题,只需要专注在业务逻辑的实现。
总体来说,Go的垃圾回收机制简单、高效,是Go语言获得高性能的重要原因之一。它确保了Go程序没有内存泄漏的问题,从而获得了良好的内存安全性。
新特性
Go语言每年都会发布新的版本,增加新的特性。这里总结一下Go 1.18及后续版本的新特性:
Go 1.18 (2021-05-11):
• 指针转换安全检查。防止将uintptr或unsafe.Pointer转换为不正确的指针类型。
• 调整堆栈跟踪以减少内存使用量。使 Goroutine 占用的栈空间减小一半。
• 提高回收器的并发度。将标记阶段从单线程改为多线程,加速垃圾回收。
• Go mod tidy 命令。用于整理和 cleanup module 依赖以及缓存。
• 工具包的改进,如 net/http 的 Keep-Alive 支持和 TLS 1.3 支持。
Go 1.19 (2021-11-23):
• 支持 Go 2。使用 Go 2 中的 64 位和 32 位指针。
• 编译器性能提升。减少编译时间,减小编译结果的大小。
• strings 包的新方法如 strings.Contains、strings.HasPrefix 等。
• http.Client 的超时设置。可以设置连接超时、读写超时。
• crypto/rsa 包的支持 OAEP padding 方法。提供更安全的 RSA 加密。
• go mod why 命令。用于追踪 module 依赖和它们来自哪里。
Go 1.20 (2022-05-10):
• 支持通用时间标准 (UTS)。可以使用时间标准 names (Local, UTC 等) 进行时间相关操作。
• TLS 1.3 支持提升。支持 TLS 1.3 暂时密钥和 Application-Layer Protocol Negotiation (ALPN) 选项。
• 无缝地支持64位和32位 wound。可在同一个 Go 程序中同时使用 64 位和 32 位类型。
• 定时任务的支持。可以使用 time.Tick()、time.Ticker() 和 time.Timer() 进行定时任务调度。
• 有 substring 方法的 strings 包的扩展。如 strings.HasSuffix()、strings.TrimPrefix() 等。
• os/fs 包的新原子操作方法。如 os.MkdirAllWithMode() 和 os.RenameWithOptions() 等。
• net/http 的体积更小的错误类型。支持对 http 请求|响应结果的更细粒度错误处理。
• go mod tidy 命令的 –modcache 选项。只清理 module 缓存,而保留 module 依赖信息。