✍个人博客:Pandaconda-CSDN博客
📣专栏地址:http://t.csdnimg.cn/UWz06
📚专栏简介:在这个专栏中,我将会分享 Golang 面试中常见的面试题给大家~
❤️如果有收获的话,欢迎点赞👍收藏📁,您的支持就是我创作的最大动力💪
4. Go 支持什么形式的类型转换?
- 数值类型之间的转换
Go 语言支持整型和浮点型之间的转换,但需要注意转换的精度问题。通常,将高精度的数据类型转换为低精度的数据类型会丢失精度。例如,将 float64 类型的浮点数转换为 float32 类型的浮点数,可能会导致数据精度的损失。
- 字符串和数值类型之间的转换
Go 语言支持字符串和数值类型之间的相互转换。可以使用 strconv 包中的函数将字
符串转换为数值类型,或将数值类型转换为字符串。例如,将字符串转换为整型:
go">str := "123"
i, err := strconv.Atoi(str)
if err != nil {// 转换失败
} else {// 转换成功,i为123
}
- 指针类型之间的转换
Go 语言中的指针类型可以互相转换,但需要注意指针指向的数据类型必须一致。例如,将一个 *int 类型的指针转换为 *uintptr 类型的指针:
go">var i int = 123
p := &i
uintptrPtr := (*uintptr)(unsafe.Pointer(p))
需要注意的是,指针类型之间的转换需要使用 unsafe 包中的函数,因此不太安全,应该尽量避免使用。
- 自定义类型之间的转换
Go 语言中支持自定义类型之间的相互转换,但需要注意自定义类型的底层类型必须相同。例如,定义两个自定义类型:
go">type Celsius float64
type Fahrenheit float64
可以通过定义函数实现自定义类型之间的转换:
go">func CToF(c Celsius) Fahrenheit {return Fahrenheit(c*9/5 + 32)
}
总之,Go 语言支持数值类型、字符串、指针类型和自定义类型之间的转换,但需要注意转换的精度和安全性问题。
5. 什么是 Goroutine?你如何停止它?
Goroutine 是 Go 语言中的一种轻量级线程,由 Go 运行时环境调度。与传统的线程相比,Goroutine 的创建和销毁代价非常低,可以创建成千上万个 Goroutine,而不会导致系统负担过重。Goroutine 可以通过 go 关键字启动,它会在一个独立的栈空间中执行相应的函数,可以在函数中执行阻塞和非阻塞操作。
要停止 Goroutine,需要使用 Go 语言提供的通道(channel)机制。可以在 Goroutine 中使用一个通道来接收停止信号,当主线程需要停止 Goroutine 时,向该通道发送一个信号即可。Goroutine 在执行任务的同时需要不断检测该通道是否有信号,如果有,则立即退出任务。
下面是一个简单的示例代码,演示了如何使用通道停止 Goroutine:
go">package mainimport ("fmt""time"
)func worker(stopCh chan bool) {for {select {case <-stopCh:fmt.Println("worker stopped")returndefault:fmt.Println("working...")time.Sleep(1 * time.Second)}}
}func main() {stopCh := make(chan bool)go worker(stopCh)time.Sleep(5 * time.Second)stopCh <- truetime.Sleep(1 * time.Second)fmt.Println("main stopped")
}
在上面的示例代码中,我们创建了一个名为 worker 的 Goroutine,它会在循环中不断执行任务。主线程会在启动 worker 后等待 5 秒钟,然后向 stopCh 通道发送一个停止信号,worker 接收到该信号后会立即退出任务。最后,主线程等待 1 秒钟后结束执行。
6. 如何在运行时检查变量类型?
在 Go 语言中,可以使用反射(reflection)机制来在运行时检查变量的类型。反射是一种在程序运行时检查变量类型、值的机制,可以在不知道具体类型的情况下操作对象。
Go 语言中的反射主要依赖于 reflect 包提供的函数和类型。通过 reflect 包中的 TypeOf 和 ValueOf 函数,可以获取一个变量的类型和值,从而进行相关操作。以下是一个简单的示例代码:
go">package mainimport ("fmt""reflect"
)func main() {var x interface{}x = 42t := reflect.TypeOf(x)v := reflect.ValueOf(x)fmt.Printf("Type: %v\n", t)fmt.Printf("Value: %v\n", v)
}
在上面的示例代码中,我们定义了一个接口变量 x,并将其赋值为 42。接着,使用 reflect.TypeOf 和 reflect.ValueOf 函数获取了变量 x 的类型和值,并分别打印输出。
需要注意的是,反射机制的使用可能会带来一定的性能损失,因此应该尽量避免过度使用反射。在编写代码时,应该尽可能地使用静态类型检查,避免在运行时进行类型检查和转换。