文章目录
-
- 一、Golang基础:
-
- 1. Golang有哪些数据类型
- 2. Go程序中的`包`是什么
- 3. 什么是Goroutine?
- 4.如主动停止Goroutine?
- 5. 如何在运行时检查变量类型:
- 6. Go两个接口之间可以存在什么关系:
- 7. Go当中同步锁有什么特点? 作用是什么?
- 8. Go语言中`cap函数`可以作用于哪些内容:
- 9. golang中解析tag是怎么实现的? 反射的原理是什么?
- 10. Go Convey是什么? 一般用来说什么?
- 11. new和make的区别:
- 12. `Printf()`、`Sprintf()`、`Fprintf()`都是格式化输出, 有什么不同:
- 13. Go语言中数组和切片的区别是什么:
- 14. Go语言中slice扩容前后是否相同:
- 15. Go语言中值传递和地址传递如何运用? 有什么区别?
- 16. Golang Map底层实现 扩容、查找:
- 17. Map不是并发安全的:
- 18. sync.Map 如何实现并发安全的?
- 19. channel的特性:
- 20. channel的底层实现原理:
- 二、并发编程:
- 三、Go Runtime:
一、Golang基础:
1. Golang有哪些数据类型
- 布尔: bool
- 数字类型:
- int[8、16、32、64]
- uint[8、16、32、64]
- uintptr:无符号整型,用于存放一个指针
- byte: 字节, uint8的别名,通常用来存储ASCII字符以及二进制数据。
- rune: int32别名,用于表示Unicode字符。这是因为Unicode字符可能需要多个字节来表示,因此需要更多的存储空间;
- 字符串类型: string
- 派生类型:
- 指针: pointer
- 数组: array
- 切片: slice
- 哈希表: map
- 接口: interface / any
- 结构体: struct
- 函数: func
- 通道: channel
- 浮点类型:
- 浮点数: float[32、64]
- 复数: complex[64、128]
- 空类型: nil
2. Go程序中的包
是什么
包(pkg)是go工作区中包含go原文件或者其他包的目录;
原文件中的每个函数、变量、常量、类型等 都存储在连接包中;
每个go元文件都属于一个包, 这个包在文件顶部通过 package <packageName>
声明; 在需要的地方使用import "<packageName>"
导入;
3. 什么是Goroutine?
协程: corutine, 轻量级线程;
与传统的系统级线程和进程相比, 协程最大的优势在于"轻量式";
可以轻松创建上万个且不是导致系统资源衰竭; 而线程和进程的数量受到系统资源限制;
一个线程中可以有壬寅多个协程, 但某一时刻只能有一个协程在运行, 多个协程共享该线程分配的计算机资源;
在协程中, 调用一个任务就像调用一个函数一样, 消耗的系统资源最少, 但能达到的进程和线程相同的效果;
要创建Goroutine, 将函数调用之前添加go
关键字:
go funcName()
4.如主动停止Goroutine?
可以通过让Goroutine监听一个信号或者传入一个上下文的方式
package main
import (
"context"
"fmt"
"time"
)
func main() {
quite := make(chan struct{
})
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
go func(ctx context.Context, quite <-chan struct{
}) {
for {
select {
case <-quite:
// do something
return
case <-ctx.Done():
// do something
return
default:
fmt.Println(time.Now().Format("2006-01-02 15:04:05"))
time.Sleep(time.Second)
}
}
}(ctx, quite)
// 使用上下文
cancel()
// 信号通道
quite <- struct{
}{
}
}
5. 如何在运行时检查变量类型:
通常使用类型断言(type assertion)与switch语句结合使用来实现;
package main
import (
"fmt"
)
func do(i interface{
}) {
switch v := i.(type) {
case int:
fmt.Println("I'm an int", v)
case string:
fmt.Println("I'm a string", v)
case bool:
fmt.Println("I'm a bool", v)
default:
fmt.Println("Don't know about t