✍个人博客:Pandaconda-优快云博客
📣专栏地址:http://t.csdnimg.cn/UWz06
📚专栏简介:在这个专栏中,我将会分享 Golang 面试中常见的面试题给大家~
❤️如果有收获的话,欢迎点赞👍收藏📁,您的支持就是我创作的最大动力💪
124. sync.Pool 怎么实现?
以下是一个简单的示例,演示了如何使用 sync.Pool:
package main
import (
"fmt"
"sync"
)
type Object struct {
// 定义对象属性
}
func main() {
var pool = sync.Pool{
New: func() interface{} {
// 创建新对象
return new(Object)
},
}
// 获取对象
object1 := pool.Get().(*Object)
fmt.Printf("object1: %p\n", object1)
// 放回对象池中
pool.Put(object1)
// 再次获取对象
object2 := pool.Get().(*Object)
fmt.Printf("object2: %p\n", object2)
}
在这个示例中,我们首先创建了一个对象池 pool,并指定了 New 函数,用于创建新对象。然后我们从对象池中获取一个对象 object1,并打印它的内存地址。接着,我们将对象 object1 放回对象池中,然后再次从对象池中获取对象 object2,并打印它的内存地址。由于对象 object1 已经放回对象池中,所以对象池会优先从空闲对象池中获取对象,因此对象 object2 的内存地址和对象 object1 的内存地址相同。
125. Goroutine 定义
Goroutine 是 Go 语言中的一种轻量级线程实现,它可以在单个进程中同时执行多个任务,实现了并发编程。与传统的线程相比,Goroutine 的创建和切换开销非常小,因此可以轻松创建数以千计的 Goroutine,而不会导致系统资源的耗尽。
Goroutine 的定义非常简单,只需要在函数调用前添加关键字 go 即可创建一个 Goroutine。例如:
func main() {
go sayHello()
}
func sayHello() {
fmt.Println("Hello, world!")
}
在这个例子中,我们创建了一个 Goroutine 来执行 sayHello() 函数,使用关键字 go 来启动 Goroutine。当程序执行到 go sayHello() 时,会创建一个新的 Goroutine 来执行 sayHello() 函数,而主 Goroutine 则会继续执行下去,不会等待 sayHello() 函数执行完毕。
需要注意的是,Goroutine 是由 Go 运行时环境调度的,它们并不是线程或进程。每个 Goroutine 都是由 Go 运行时环境自动分配的,它们共享相同的地址空间和堆栈。因此,在 Goroutine 中共享内存需要采用同步机制来保证线程安全。
Goroutine 是 Go 语言的核心特性之一,它使得并发编程变得简单而高效。通过合理使用 Goroutine,可以充分发挥多核 CPU 的性能,提高程序的并发处理能力。
126. Go goroutine 的底层实现原理?
概念
Goroutine 可以理解为一种 Go 语言的协程(轻量级线程),是 Go 支持高并发的基础,属于用户态的线程,由 Go runtime 管理而不是操作系统。
底层数据结构
type g struct {
goid int64 // 唯一的goroutine的ID
sched gobuf // goroutine切换时,用于保存g的上下文
stack stack // 栈
gopc // pc of go statement that created this goroutine
startpc uintptr // pc of goroutine function
...
}
type gobuf struct {
sp uintptr // 栈指针位置
pc uintptr // 运行到的程序位置
g guintptr // 指向 goroutine
ret uintptr // 保存系统调用的返回值
...
}
type stack struct {
lo uintptr // 栈的下界内存地址
hi uintptr // 栈的上界内存地址
}
最终有一个 runtime.g 对象放入调度队列。