Go 语言学习笔记
Go 语言学习笔记
wymyimeng
这个作者很懒,什么都没留下…
展开
-
Go 中的并发调度
1、概述go 的并发调度示意图为:首先是 Processor(简称 P),其作用类似于 CPU 核,用来控制可同时并发执行的任务数量。每个工作线程都必须绑定一个有效 P 才被允许执行任务,否则只能休眠,直到有空闲 P 时被唤醒。P 还为线程提供执行资源,比如对象分配内存、本地任务队列等。线程独享所绑定的P资源,可在无锁状态下执行高效操作。基本上,进程内的一切都在以 goroutine(简称...原创 2019-10-18 08:45:17 · 399 阅读 · 0 评论 -
Go 中的垃圾回收
三色标记和写屏障其基本原理为:起初所有对象都是白色。扫描找出所有可达对象,标记位灰色,放入待处理队列。从队列提取灰色对象,将其引用对象标记为灰色放入队列,自身标记为黑色。写屏障监视对象内存修改,重新标记或放回队列。当完成全部扫描和标记工作后,剩余的不是白色就是黑色,分别代表待回收和活跃对象,清理操作只续将白色对象内存收回即可。...原创 2019-10-17 08:46:14 · 156 阅读 · 0 评论 -
Go 中的内存分配
1、概述内存分配的基本策略:每次从操作系统申请一大块内存(比如1MB),以减少系统调用。将申请到的大块内存按照特定大小预先切分成小块,构成链表。为对象分配内存时,只须从大小合适的链表提取一小块即可。回收对象内存时,将该小块内存重新归还原链表,以便复用。如闲置内存过多,则尝试归还部分内存给操作系统,降低整体开销。内存块分配器将其管理的内存块分为两种。span: 将多个地址连续...原创 2019-10-16 08:56:17 · 294 阅读 · 0 评论 -
Go 中的工具链
1、编译编译并不仅仅是执行“go build” 命令,还有一些须额外注意的内容。如习惯使用 GDB 这类调试器,建议编译时添加 -gcflags “-N -l” 参数阻止优化和内联,否则调试时会有各种“找不到”的情况。package mainfunc test(x *int) { println(*x)}func main() { x := 0x100 test(&...原创 2019-10-14 08:56:12 · 397 阅读 · 0 评论 -
Go 中的测试
1、单元测试testing工具链和标准库自带单元测试框架,这让测试工作变得相对容易。测试代码须放在当前包以“_test.go” 结尾的文件中。测试函数以 Test 为名称前缀。测试命令(go test) 忽略以“_” 或 “.” 开头的测试文件。正常编译操作(go build/install) 会忽略测试文件。使用 Parallel 可有效利用多核并行优势,缩短测试时间。pac...原创 2019-10-10 08:55:51 · 291 阅读 · 0 评论 -
GO 中的反射
1、类型在面对类型时,我们要区分Type 和 Kind 。前者表示真实类型(静态类型),后者表示其基础结构(底层类型)类别。package mainimport ( "fmt" "reflect")type X intfunc main() { var a X = 100 t := reflect.TypeOf(a) fmt.Println(t.Name(), t.K...原创 2019-09-29 08:55:34 · 143 阅读 · 0 评论 -
Go 的包结构
1、导入包除使用默认包名外,还可使用别名,已解决同名冲突问题。import osx "github.com/apple/osx/lib"import nix "github.com/linux/lib"归纳起来,有四种不同的导入方式。import "github.com/qyuhen/test" // 默认方式:test.Aimport X "github.com/qyuhe...原创 2019-09-27 08:56:11 · 689 阅读 · 0 评论 -
Go 中的通道
从底层实现上来看,通道只是一个队列。同步模式下,发送和接收双方配对,然后直接复制数据给对方。如配对失败,则置入等待队列,直到另一方出现后才会唤醒。异步模式抢夺的则是数据缓冲槽。发送方要求有空槽可供写入,而接收方则要求有缓冲数据可读。需求不符时,同样加入等待队列,直到有另一方写入数据或腾出空槽后被唤醒。内置函数 cap 和 len 返回缓冲区大小和当前已缓冲数量;而对于同步通道则都返回0,据此可判...原创 2019-09-26 08:43:21 · 154 阅读 · 0 评论 -
Go 中的并发
1、并发的含义并发和并行的区别如下:并发:逻辑上具备同时处理多个任务的能力。并行:物理上在同一时刻执行多个并发任务。我们通常会说程序是并发设计的,也就是说它允许多个任务同时执行,但实际上并不一定真在同一时刻发生。在单核处理器上,它们能以间隔方式切换执行。而并行则依赖多核处理器等物理设备,让多个任务真正在同一时刻执行,它代表了当前程序运行状态。简单点说,并行是并发设计的理想执行模式。多线...原创 2019-09-24 08:55:49 · 296 阅读 · 0 评论 -
Go 中的接口
1、定义接口代表一种调用契约,是多个方法声明的集合。Go 接口实现机制很简洁,只要目标类型方法集合内包含接口声明的全部方法,就被视为实现了该接口,无须做显示声明。当然,目标类型可实现多个接口。2、执行机制接口有一个重要特征:将对象赋值给接口变量时,会复制该对象。package maintype data struct { x int}func main() { d := ...原创 2019-09-24 08:27:30 · 116 阅读 · 0 评论 -
Go 中的方法
定义方法和函数定义语法区别在于前者有实例接收参数,编译器以此确定方法所属类别。在某些语言里,尽管没有显示定义,但会在调用时隐式传递 this 实例参数。方法集类型有一个与之相关的方法集,这决定了它是否实现某个接口。类型 T 方法集包含所有 receiver T 方法。类型 *T 方法集包含所有 receiver T + *T 方法。匿名嵌入 S,T 方法集包含了所有 receiver...原创 2019-09-23 08:45:40 · 122 阅读 · 0 评论 -
Go 中的数据
1、字符串字符串是不可变字节序列,其本身就是一个复合结构。type stringStruct struct { str unsafe.Pointer len int} 使用“ ` ”定义不做转义处理的原始字符串,支持跨行。package mainimport ( "fmt")func main() { s := `line1\r\n line2`...原创 2019-09-19 09:01:03 · 190 阅读 · 0 评论 -
Go 函数
1、参数在 Go 中,不管是指针、引用类型,还是其他类型参数,都是值拷贝传递。区别无非是拷贝目标对象,还是拷贝指针而已。在函数面前,会为形参和返回值分配内存空间,并将实参拷贝到形参内存。表面上看,指针参数的性能要更好一些,但实际上得具体分析。被复制的指针会延长目标对象的生命周期,还可能会导致它被分配到堆上,那么其性能消耗就得加上堆内存分配和垃圾回收的成本。其实在栈上分配小对象只需要很少的指令...原创 2019-09-11 08:49:34 · 152 阅读 · 0 评论 -
Go 的表达式
1、运算符位移右操作数必须是无符号整数,或可以转换的无显示类型常量。package mainfunc main() { b := 23 x := 1 << b // 无效操作: 1 << b (shift count type int, must be unsigned integer) println(x)}如果是非常量位移表达式,那么会优先将无...原创 2019-09-09 09:01:12 · 1071 阅读 · 0 评论 -
Go 的类型
1、枚举Go 并没有明确意义上的 enum 定义,不过可借助 iota 标识符实现一组自增常量值来实现枚举类型。const ( x = iota // 0 y // 1 z // 2)const ( _ = iota // 0 KB = 1 << (10 * iota) // 1 ...原创 2019-09-07 09:02:22 · 100 阅读 · 0 评论