/golang

learn go

Primary LanguageGoMIT LicenseMIT

go

go study notes


go_learning

第一章(ch1)

  • 开发环境 GOPATH
    1. go 1.8 以后Unix默认$HOME/go
    2. Windows默认%USERPROFILE%/go
    3. Mac上修改~/.bash_profile设置
  • go command
    1. go version (查看go版本)
    2. go run hello_world.go (运行go)
    3. go build hello_world.go (编译go)
  • 应用程序入口
    1. 必须是main包: package main
    2. 必须是main方法: func main()
    3. 文件名不一定是main.go
  • 退出返回值(与其他语言区别)
    1. Go中main函数不支持任何返回值
    2. 通过os.Exit返回状态
  • 获取命令行参数(与其他语言区别)
    1. main函数不支持传入参数func main(arg []string)
    2. 在程序中直接通过os.Args获取命令行参数
  • 编写测试程序
    1. 源码文件以_test结尾:xxx_test.go
    2. 测试方法名以Test开头:func TestXXX(t *testing.T){}

第二章(ch2)

  • 变量赋值(与其他主要语言差异)
    1. 赋值可以进行自动类型推断
    2. 在一个赋值语句中可以对多个变量进行同时赋值
  • 常量定义(与其他主要语言差异)
    1. 快速设置连续值(iota)
  • 基本数据类型
    1. bool
    2. string
    3. int int8 int16 int32 int64
    4. uint uint8 uint16 uint32 uint64 uintptr
    5. byte // alias for uint8
    6. rune // alias for int32, represents a Unicode code point
    7. float32 float64
    8. complex64 complex128

第三章(ch3)

  • 类型转换(与其他主要语言差异)
    1. Go语言不允许隐式类型转换
    2. 别名和原有类型也不能进行隐式类型转换
  • 类型预定义值
    1. math.MaxInt64
    2. math.MaxFloat64
    3. math.MaxUint32
  • 指针类型(与其他主要语言差异)
    1. 不支持指针运算
    2. string是值类型,其默认初始值为空字符串,而不是nil

第四章(ch4)

  • 算数运算符
    1. + - * / % ++ --
    2. Go语言没有前置++, --
  • 比较运算符
    1. == != > < >= <=
  • 用==比较数组
    1. 相同维数且含有相同个数元素的数组才可以比较
    2. 每个元素都相同的才相等
  • 逻辑运算符
    1. && || !
  • 位运算符(与其他主要语言差异)
    1. & | ^ << >>
    2. &^ 按位置0

第五章(ch5)

  • 循环(与其他主要语言差异)

    1. Go语言仅支持循环关键字
    2. for j := 7; j <= 9; j++
  • if条件(与其他主要语言差异)

    1. condition表达式结果必须为布尔值
    2. 支持变量赋值:
    3. if var declaration; condition {

    }

  • switch(与其他主要语言差异)

    1. 条件表达式不限制为常量或者整数
    2. 单个case中,可以出现多个结果选项,使用逗号分隔;
    3. 与C语言规则相反,Go不需要break来明确退出一个case;
    4. 可以不设定switch之后的条件表达式,在此种情况下,整个switch结构与多个if...else...的逻辑等同

第六章(ch6)

  • 数组声明
    1. var a [3]int //声明并初始化为0
    2. b := [3]int{1, 2, 3} // 声明同时初始化
    3. c := [2][2]int{{1, 2}, {3, 4}} // 多维数组初始化
    4. 相同维数相同长度可以比较
  • 数组截取(与其他主要语言差异)
    1. a[开始索引(包含), 结束索引(不包含)]
    2. 不支持负数索引
  • 切片(可变长数组)
    1. 指针,len,cap
    2. 切片不可比较,只能和nil比较

第七章(ch7)

  • map(与其他主要语言差异)
    1. s := map[string]int{"a": 1, "b": 2}
    2. 在访问key不存在时,仍会返回零值,不能通过返回nil来判断元素是否存在

第八章(ch8)

  • map(extend)
    1. map的value可以是一个方法
    2. 与Go的Dock type接口方式一起,可以方便实现单一方法对象的工厂模式
  • 实现Set(与其他主要语言差异)
    1. Go的内置集合中没有Set实现,可以map[type]bool
      • 元素唯一性
      • 基本操作
        1. 添加元素
        2. 判断元素是否存在
        3. 删除元素
        4. 元素个数

第9章(ch9)

  • 字符串(与其他主要语言差异)
    1. string是数据类型,不是引用和指针类型
    2. string是只读的byte slice, len函数是它所包含的byte数
    3. string的byte数组可以存放任何数据
    4. string是不可变的byte slice
  • Unicode UTF8
    1. Unicode是一种字符集(code point)
    2. UTF8是unicode的存储实现(转换为字节序列的规则)
  • 常用的字符串函数
    1. strings http://golang.org/pkg/strings/
    2. strconv http://golang.org/pkg/strconv/

第十章(ch10)

  • 函数是一等公民(与其他主要语言差异)
    1. 可以有多个返回值
    2. 所有参数都是值传递:slice,map,channel会有传引用的错觉
    3. 函数可以作为变量的值
    4. 函数可以作为参数和返回值
    5. 函数可变参数相当于数组
    6. defer函数

第十一章(ch11)

  • 行为的定义和实现
    1. 定义
    2. 行为
  • 接口(与其他主要语言差异)
    1. 接口为非入侵性的,实现不依赖于接口定义
    2. 接口的定义可以包含在接口使用者包内
    3. 自定义类型

第十二章(ch12)

  • 扩展和复用

第十三章(ch13)

  • 多态
  • 空接口和断言
    1. 空接口可以表示任何类型
    2. 通过断言将空接口转换为制定类型
    3. v, ok := p.(int) // ok=true 转换成功
  • Go接口最佳实践
    1. 倾向于使用小的接口定义,很多接口只包含一个方法
    2. 较大的接口定义,可以有多个小接口组合而成
    3. 只依赖于必要功能的最小接口

第十四章(ch14)

  • Go的错误机制(与其他主要语言差异)
    1. 没有异常处理
    2. error类型实现了error接口
    3. 可以通过errors.New来快速创建错误实例
  • Go错误最佳实践
    1. 定义不同错误变量,以便于判断错误类型
    2. 及早失败,避免嵌套
  • panic
    1. panic用于不可恢复的错误
    2. panic退出前会执行defer指定的内容
  • panic vs os.Exit
    1. os.Exit退出时不会调用defer指定的函数
    2. os.Exit退出时不输出当前调用栈信息
  • recover
    1. 形成僵尸服务进程,导致health check失效
    2. "Let's it Crash!"往往是我们恢复不确定性错误的最好办法

第十五章(ch15)

  • 构建可复用模块
    1. 基本复用模块单元(以首字母大写来表明可被包外代码访问)
    2. 代码的package可以和所在的目录不一致
    3. 同一目录里的Go代码的package要保持一致
  • init方法
    1. 在main被执行前,所有依赖的package的init方法都会被执行
    2. 不同包的init函数按照包导入的依赖关系决定执行顺序
    3. 每个包可以有多个init函数
    4. 包的每个源文件也可以有多个init函数,这点比较特殊
  • package
    1. 通过go get来获取远程依赖
    2. go get -u 强制从远程更新依赖(go get -u github.com/easierway/concurrent_map)
    3. 注意代码在github上的组织形式,以适应go get
    4. 直接以代码路径开始,不要有src
  • Go未解决问题
    1. 同一环境,不同项目使用同一包的不同版本
    2. 无法管理对包的特定版本的依赖
    3. vendor(查找包路径解决方案)
      1. 当前包下的vendor目录
      2. 向上级目录查找,直到找到src下的vendor目录
      3. 在GOPATH下面查找依赖包
      4. 在GOROOT目录下查找
    4. 常用的依赖管理工具
      1. godep http://github.com/tools/godep
      2. glide http://github.com/Masterminds/glide
      3. dep http://github.com/golang/dep

第十六章(ch16)

  • Thead vs Groutine
    1. 创建时默认的stack的大小
      1. JDK5以后Java Thread stack 默认为1M
      2. Groutine 的Stack初始化大小2k
    2. 和KSE(Kernel Space Entity)的对应关系
      1. Java Thread 1:1
      2. Groutine M : N

第十七章(ch17)

  • 共享内存并发机制

第十八章(ch18)

  • CSP vs Actor
    1. 和Actor的直接通讯不同,CSP模式则是通过Channel进行通讯的,更松耦合一些.
    2. Go中是有容量限制并且独立与处理Groutine,而如Erlang,Actor模式中的mailbox容量是无限的,接受进程也是被动的处理消息.

第十九章(ch19)

  • 多路选择和超时(select)

第二十章(ch20)

  • 向关闭的channel发送数据, 会导致panic
  • v, ok <- ch; ok 为bool值,true表示正常接受,false表示通道关闭
  • 所有的channel接收者都会在channel关闭时,立刻从阻塞等待中返回且上述ok值为false,这个广播机制常常被利用,进行向多个订阅者同时发送信号.
  • 任务取消(close channel是广播机制,取消所有协程)
  • Context与任务取消
    1. 根Context: 通过context.Background()创建
    2. 子Context: context.WithCancel(parentContext)创建
      1. ctx, cancel := context.WithCancel(context.Background)
    3. 当前Context被取消时, 基于他的子context都会被取消
    4. 接受取消通知<-ctx.Done()

第二十一章(ch21)

  • 仅执行一次(单例模式)

第二十二章(ch22)

  • 仅需任意任务完成(buffer channel 防止协程泄漏,内存泄漏)

第二十三章(ch23)

  • 所有任务完成

第三十二章(ch32)

  • 对象池

第三十三章(ch33)

  • sync.Pool对象获取
    1. 尝试从私有对象获取
    2. 私有对象不存在,尝试从当前Processor的共享池获取
    3. 如果当前Processor共享池是空的,那么就尝试去其他Processor的共享池获取
    4. 如果所有子池都是空的,最后就用用户指定的New函数产生一个新的对象返回
  • sync.Pool对象的放回
    1. 如果私有对象不存在则保存为私有对象
    2. 如果私有对象存在,放入当前Processor子池的共享池中
  • sync.Pool对象的生命周期
    1. GC会清楚sync.pool缓存的对象
    2. 对象的缓存有效期为下一次GC之前
  • sync.Pool总结
    1. 适用于通过复用,降低复杂对象的创建和GC代价
    2. 协程安全,会有锁的开销
    3. 生命周期受GC影响,不适合于做连接池等,需自己管理生命周期的资源的池化

第三十四章(ch34)

  • 内置单元测试框架
    1. Fail,Error: 该测试失败,该测试继续,其他测试继续执行
    2. FailNow,Fatal: 该测试失败,该测试中止,其他测试继续执行
  • 代码覆盖率
    1. go test -v -cover
  • 断言
    1. https://github.com/stretchr/testify

第三十五章(ch35)

  • 内置单元测试框架
  • go test -bench=.(性能测试)
  • go test -bench=. benchmem(内存测试)

第三十六章(ch36)

  • BDD
  • 安装 go get -u github.com/smartystreets/goconvey/convey
  • WEB UI $GOPATH/bin/goconvey

第三十七章(ch37)

  • reflect.TypeOf vs reflect.ValueOf
    1. reflect.TypeOf 返回类型(reflect.Type)
    2. reflect.ValueOf 返回类型(reflect.Value)
    3. 可以从reflect.Value获得类型
    4. 通过kind的来判断类型

第三十八章(ch38)

  • DeepEqual(比较切片和map)
  • 关于反射你应该知道的
    1. 提高了程序的灵活性
    2. 降低了程序的可读性
    3. 降低了程序的性能

第三十九章(ch39)

  • 不安全编程(unsafe 和C联合使用)

第四十章(ch40)

  • Pipe-Filter模式
    1. 非常适合于数据处理和数据分析系统
    2. Filter封装数据处理功能
    3. 松耦合:Filter只跟数据(格式)耦合
    4. Pipe用于连接Filter传递数据或者异步处理过程中缓冲数据流 进程内同步调用时,pipe演变为数据在方法调用间传递

第四十一章(ch41)

  • Micro Kernel
    1. 特点
      1. 易于扩展
      2. 错误隔离
      3. 保持架构一致性
    2. 要点
      1. 内核包含公共流程或通用逻辑
      2. 将可变和可扩展部分规划为扩展点
      3. 抽象扩展点行为,定义接口
      4. 利用插件进行扩展

第四十二章(ch42)

  • 内置的JSON解析(利用反射实现,通过FieldTag来标识对应的json值)

Go程序设计语言

第一章 入门

  1. hello,world
  2. 命令行参数
  3. 找出重复行
  4. GIF动画
  5. 获取一个URL
  6. 一个Web服务器
  7. 其他内容

第二章 程序结构

  1. 名称
  2. 声明
  3. 变量
  4. 赋值
  5. 类型声明
  6. 包和文件
  7. 作用域

第三章 基本数据

  1. 整数
  2. 浮点数
  3. 复数
  4. 布尔值
  5. 字符串
  6. 常量

第四章 复合数据类型

  1. 数组
  2. slice
  3. map
  4. 结构体
  5. JSON
  6. 文本和HTML模块

第五章 函数

  1. 函数声明
  2. 递归
  3. 多返回值
  4. 错误
  5. 函数变量
  6. 匿名函数
  7. 变长函数
  8. 延迟函数调用
  9. 宕机
  10. 恢复

第六章 方法

  1. 方法声明
  2. 指针接受者的方法
  3. 通过结构体内嵌组成类型
  4. 方法变量和表达式
  5. 示例:位向量
  6. 封装

第七章 接口

  1. 接口即约定
  2. 接口类型
  3. 实现接口
  4. 使用flag.Value来解析参数
  5. 接口值
  6. 使用sort.Interface来排序
  7. http.Handler接口
  8. error接口
  9. 示例:表达式求值器
  10. 类型断言
  11. 使用类型断言来识别错误
  12. 通过接口类型断言来查询特性
  13. 类型分支
  14. 示例:基于标记的XML解析
  15. 一些建议

第八章 goroutine和通道

  1. goroutine
  2. 示例:并发时钟服务器
  3. 示例:并发回声服务器
  4. 通道
  5. 并行循环
  6. 示例:并发的Web爬虫
  7. 使用select多路复用
  8. 示例:并发目录遍历
  9. 取消
  10. 示例:聊天服务器

第九章 使用共享变量实现并发

  1. 竞态
  2. 互斥锁:sync.Mutex
  3. 读写互斥锁:sync.RWMutex
  4. 内存同步
  5. 延迟初始化:sync.Once
  6. 竞态检测器
  7. 示例:并发非阻塞缓存
  8. goroutine与线程

第十章 包和go工具

  1. 引言
  2. 导入路径
  3. 包的声明
  4. 导入声明
  5. 空导入
  6. 包及其命名
  7. go工具

第十一章 测试

  1. go test工具
  2. Test函数
  3. 覆盖率
  4. Benchmark函数
  5. 性能剖析
  6. Example函数

第十二章 反射

  1. 为什么使用反射
  2. reflect.Type和reflect.Value
  3. Display: 一个递归的值显示器
  4. 示例:编码S表达式
  5. 使用reflect.Value来设置值
  6. 访问结构体字段标签
  7. 显示类型的方法
  8. 注意事项

第十三章 低级编程

  1. unsafe.Sizeof,Alignof和Offsetof
  2. unsafe.Pointer
  3. 示例: 深度相等
  4. 使用cgo调用C代码
  5. 关于安全注意事项286

Go语言轻松搞定高性能Crontab

第一章 导学

第二章 如何执行shell命令

  1. 原理介绍
  2. 执行任务
  3. 捕获任务输出
  4. 强制结束任务

第三章 如何解析cron表达式

  1. cron表达式原理
  2. 开源cron解析库
  3. 调度多个cron

Go学习笔记

第一章 类型

  1. 变量
  2. 常量
  3. 基本类型
  4. 引用类型
  5. 类型转换
  6. 字符串
  7. 指针
  8. 自定义类型

第二章 表达式

  1. 保留字
  2. 运算符
  3. 初始化
  4. 控制流

第三章 函数

  1. 函数定义
  2. 变参
  3. 返回值
  4. 匿名函数
  5. 延迟调用
  6. 错误处理

第四章 数据

  1. Array
  2. Slice
  3. Map
  4. Struct

第五章 方法

  1. 方法定义
  2. 匿名字段
  3. 方法集
  4. 表达式

第六章 接口

  1. 接口定义
  2. 执行机制
  3. 接口转换
  4. 接口技巧

第七章 并发

  1. Goroutine
  2. Channel

第八章 包

  1. 工作空间
  2. 源文件
  3. 包结构
  4. 文档

第九章 进阶

  1. 内存布局
  2. 指针陷阱
  3. cgo
  4. Reflect

第十章 Memory Allocator

  1. 初始化
  2. 分配流程
  3. 释放流程
  4. 其他

第十一章 Garbage Collector

  1. 初始化
  2. 垃圾回收
  3. 内存释放
  4. 状态输出

第十二章 Goroutine Scheduler

  1. 初始化
  2. 创建任务
  3. 任务线程
  4. 任务执行
  5. 连续栈
  6. 系统调用
  7. 系统监控
  8. 状态输出

第十三章 Channel

  1. 初始化
  2. 收发数据
  3. 选择模式

第十四章 Defer

第十五章 Finalizer

Go语言核心36讲

第一章 Go语言基础知识

  1. 工作区和GOPATH
    1. 你知道设置 GOPATH 有什么意义吗?
      • 你可以把 GOPATH 简单理解成 Go 语言的工作目录,它的值是一个目录的路径,也可以是多个目录路径,每个目录都代表 Go 语言的一个工作区(workspace)
    2. GOROOT:Go 语言安装根目录的路径,也就是 GO 语言的安装路径。
    3. GOPATH:若干工作区目录的路径。是我们自己定义的工作空间。
    4. GOBIN:GO 程序生成的可执行文件(executable file)的路径
  2. 命令源码文件
    1. 命令源码文件的用途是什么,怎样编写它?
      • 命令源码文件是程序的运行入口,是每个可独立运行的程序必须拥有的。我们可以通过构建或安装,生成与其对应的可执行文件,后者一般会与该命令源码文件的直接父目录同名。
  3. 库源码文件
    1. 怎样把命令源码文件中的代码拆分到其他库源码文件?
      • 填入代码包声明语句package main(相同包名),main包一般不加载其它包并且一起运行
    2. 包函数权限
      • 相同包:函数可以小写(私有函数)
      • 不同包:函数必须大写才能调用(公用函数)
      • internal:包级权限
  4. 程序实体的那些事儿(上)
    1. 声明变量有几种方式?
      • 短变量声明
        • 直接声明 (var name string)
        • 赋值声明 (var name = hello())
      • 类型推断声明:=
    2. Go 语言的类型推断可以带来哪些好处?
      • 通过这种类型推断,你可以体验到动态类型编程语言所带来的一部分优势,即程序灵活性的明显提升。
      • 但在那些编程语言中(Python),这种提升可以说是用程序的可维护性和运行效率换来的。
      • Go 语言是静态类型的,所以一旦在初始化变量时确定了它的类型,之后就不可能再改变。这就避免了在后面维护程序时的一些问题。
      • 另外,请记住,这种类型的确定是在编译期完成的,因此不会对程序的运行效率产生任何影响。
  5. 程序实体的那些事儿(中)
    1. 如果一个变量与其外层代码块中的变量重名会出现什么状况?
      • 变量屏蔽
  6. 程序实体的那些事儿(下)
    1. 怎样判断一个变量的类型?
      • 使用“类型断言”表达式

第二章 Go语言进阶技术

  1. 数组和切片
    1. 数组类型的值(以下简称数组)的长度是固定的,而切片类型的值(以下简称切片)是可变长的
    2. 怎样正确估算切片的长度和容量?
      • var i; i++, cap = 2 * len
      • i := 1024; i++, cap = 1.25 * len
      • var i; 2 * i, cap > 2 * len
  2. container包中的那些容器
    1. 可以把自己生成的Element类型值传给链表吗?
      • 不会接受,这些方法将不会对链表做出任何改动。
      • 因为我们自己生成的Element值并不在链表中,所以也就谈不上“在链表中移动元素”。
      • 更何况链表不允许我们把自己生成的Element值插入其中。
  3. 字典的操作和约束
    1. 字典的键类型不能是哪些类型?
      • Go语言字典的键类型不可以是函数类型、字典类型和切片类型
    2. 用var声明的值为nil的map,读,删除都不报错,新增报错,需要初始化
  4. 通道的基本操作
    1. 对通道的发送和接收操作都有哪些基本的特性?
      • 对于同一个通道,发送操作之间是互斥的,接收操作之间也是互斥的。
      • 发送操作和接收操作中对元素值的处理都是不可分割的。
      • 发送操作在完全完成之前会被阻塞。接收操作也是如此。
  5. 通道的高级玩法
    1. 单向通道有什么应用价值?
      • 单向通道最主要的用途就是约束其他代码的行为
  6. 使用函数的正确姿势
    1. 怎样编写高阶函数?
      • 接受其他的函数作为参数传入
      • 把其他的函数作为结果返回
    2. 对于引用类型,比如:切片、字典、通道,像上面那样复制它们的值,只会拷贝它们本身而已,并不会拷贝它们引用的底层数据。
    3. 也就是说,这时只是浅表复制,而不是深层复制go中参数都是值复制
  7. 结构体及其方法的使用法门
    1. Animal类型中的字段声明AnimalCategory代表了什么?
      • 字段声明AnimalCategory代表了Animal类型的一个嵌入字段。
      • Go 语言规范规定,如果一个字段的声明中只有字段的类型名而没有字段的名称,那么它就是一个嵌入字段,也可以被称为匿名字段。
      • 我们可以通过此类型变量的名称后跟“.”,再后跟嵌入字段类型的方式引用到该字段。
      • 也就是说,嵌入字段的类型既是类型也是名称。
  8. 接口类型的合理运用
    1. 当我们为一个接口变量赋值时会发生什么?
      • pet变量的字段name的值依然是"little pig
    2. 除非我们只声明而不初始化,或者显式地赋给它nil,否则接口变量的值就不会为nil
  9. 关于指针的有限操作
    1. 你能列举出 Go 语言中的哪些值是不可寻址的吗?
      • 不可变的
      • 临时结果(例外: 切片字面量的索引结果值是可寻址的)
      • 不安全的
  10. go语句及其执行规则(上)
    1. 什么是主 goroutine,它与我们启用的其他 goroutine 有什么不同?
      • 不会有任何内容被打印出来
  11. go语句及其执行规则(下)
  12. if语句、for语句和switch语句
    1. 使用携带range子句的for语句时需要注意哪些细节?
      • 非引用类型复制,引用原地修改
  13. 错误处理(上)
    1. 对于具体错误的判断,Go 语言中都有哪些惯用法?
      • 对于类型在已知范围内的一系列错误值,一般使用类型断言表达式或类型switch语句来判断
      • 对于已有相应变量且类型相同的一系列错误值,一般直接使用判等操作来判断
      • 对于没有相应变量且类型未知的一系列错误值,只能使用其错误信息的字符串表示形式来做判断
  14. 错误处理(上)
  15. panic函数、recover函数以及defer语句(上)
    1. 从 panic 被引发到程序终止运行的大致过程是什么?
      • panic函数报错调用,栈结构,先进后出
  16. panic函数、recover函数以及defer语句(下)
    1. defer函数调用,栈结构,先进后出

第三章 Go语言实战与应用

  1. 测试的基本规则和流程(上)
    1. Go 语言对测试函数的名称和签名都有哪些规定?
      • 对于功能测试函数来说,其名称必须以Test为前缀,并且参数列表中只应有一个*testing.T类型的参数声明
      • 对于性能测试函数来说,其名称必须以Benchmark为前缀,并且唯一参数的类型必须是*testing.B类型的
      • 对于示例测试函数来说,其名称必须以Example为前缀,但对函数的参数列表没有强制规定
  2. 测试的基本规则和流程(下)
    1. cd golang/puzzlers/article20/q2 & go test .
    2. cd golang/puzzlers/article20/q2 & go test -bench=. -run=^$ .
  3. 更多的测试手法
  4. sync.Mutex与sync.RWMutex
    1. 我们使用互斥锁时有哪些注意事项?
      • 不要重复锁定互斥锁
      • 不要忘记解锁互斥锁,必要时使用defer语句
      • 不要对尚未锁定或者已解锁的互斥锁解锁
      • 不要在多个函数之间直接传递互斥锁
  5. 条件变量sync.Cond (上)
    1. 条件变量怎样与互斥锁配合使用?
      • 条件变量的初始化离不开互斥锁,并且它的方法有的也是基于互斥锁的
  6. 条件变量sync.Cond (下)
  7. 原子操作(上)
    1. sync/atomic包中提供了几种原子操作?可操作的数据类型又有哪些?
      • 加法(add)、比较并交换(compareand swap,简称 CAS)、加载(load)、存储(store)和交换(swap)
      • int32、int64、uint32、uint64、uintptr,以及unsafe包中的Pointer。
      • 不过,针对unsafe.Pointer类型,该包并未提供进行原子加法操作的函数。
  8. 原子操作(下)
  9. sync.WaitGroup和sync.Once
    1. sync.WaitGroup类型值中计数器的值可以小于0吗?
      • 不可以,这样会引发一个 panic
      • 先统一Add,再并发Done,最后Wait
  10. context.Context类型
    1. 怎样使用context包中的程序实体,实现一对多的 goroutine 协作流程?
      • 在这个函数体中,我先后调用了context.Background函数和context.WithCancel函数。
      • 并得到了一个可撤销的context.Context类型的值(由变量cxt代表)。
      • 以及一个context.CancelFunc类型的撤销函数(由变量cancelFunc代表)。
  11. 临时对象池sync.Pool
    1. 为什么说临时对象池中的值会被及时地清理掉?
      • Go 语言运行时系统中的垃圾回收器,所以在每次开始执行之前,都会对所有已创建的临时对象池中的值进行全面地清除
  12. 并发安全字典sync.Map (上)
    1. 并发安全字典对键的类型有要求吗?
      • 键的实际类型不能是函数类型、字典类型和切片类型
  13. 并发安全字典sync.Map (下)
  14. unicode与字符编码
  15. strings包与字符串操作
    1. 与string值相比,strings.Builder类型的值有哪些优势?
      • 已存在的内容不可变,但可以拼接更多的内容
      • 减少了内存分配和内容拷贝的次数
      • 可将内容重置,可重用值
  16. bytes包与字节串操作(上)
    1. bytes.Buffer类型的值记录的已读计数,在其中起到了怎样的作用?
      • 读取内容时,相应方法会依据已读计数找到未读部分,并在读取后更新计数
      • 写入内容时,如需扩容,相应方法会根据已读计数实现扩容策略
      • 截断内容时,相应方法截掉的是已读计数代表索引之后的未读部分
      • 读回退时,相应方法需要用已读计数记录回退点
      • 重置内容时,相应方法会把已读计数置为0
      • 导出内容时,相应方法只会导出已读计数代表的索引之后的未读部分
      • 获取长度时,相应方法会依据已读计数和内容容器的长度,计算未读部分的长度并返回
  17. bytes包与字节串操作(下)
  18. io包中的接口和工具(上)
    1. 在io包中,io.Reader的扩展接口和实现类型都有哪些?它们分别都有什么功用?
      1. 扩展接口
        • io.ReadWriter
        • io.ReadCloser
        • io.ReadWriteCloser
        • io.ReadSeeker
        • io.ReadWriteSeeker
      2. 实现类型
        • *io.LimitedReader
        • *io.SectionReader
        • *io.teeReader
        • io.multiReader
        • io.pipe
        • io.PipeReader
  19. io包中的接口和工具(下)
  20. bufio包中的数据类型(上)
    1. bufio.Reader类型值中的缓冲区起着怎样的作用?
      • bufio.Reader类型的值(以下简称Reader值)内的缓冲区,其实就是一个数据存储中介,它介于底层读取器与读取方法及其调用方之间。
      • 所谓的底层读取器,就是在初始化此类值的时候传入的io.Reader类型的参数值
      • Reader值的读取方法一般都会先从其所属值的缓冲区中读取数据
      • 同时,在必要的时候,它们还会预先从底层读取器那里读出一部分数据,并暂存于缓冲区之中以备后用
  21. bufio包中的数据类型(下)
  22. 使用os包中的API (上)
    1. os.File类型都实现了哪些io包中的接口?
      • os.File类型拥有的都是指针方法,所以除了空接口之外,它本身没有实现任何接口。
      • 而它的指针类型则实现了很多io代码包中的接口
      • 对于io包中最核心的 3 个简单接口io.Reader、io.Writer和io.Closer,*os.File类型都实现了它们
      • 该类型还实现了另外的 3 个简单接口,即:io.ReaderAt、io.Seeker和io.WriterAt
  23. 使用os包中的API (下)
  24. 访问网络服务
    1. net.Dial函数的第一个参数network有哪些可选值?
      • net.Dial函数会接受两个参数,分别名为network和address,都是string类型的。
      • 参数network常用的可选值一共有 9 个。这些值分别代表了程序底层创建的 socket 实例可使用的不同通信协议
      • tcp, tcp4, tcp6, udp, udp4, udp6, unix, unixgram, unixpacket
  25. 基于HTTP协议的网络服务
    1. http.Client类型中的Transport字段代表着什么?
      • 向网络服务发送 HTTP 请求,并从网络服务接收 HTTP 响应的操作过程
      • 也就是说,该字段的方法RoundTrip应该实现单次HTTP 事务(或者说基于 HTTP 协议的单次交互)需要的所有步骤
  26. 程序性能分析基础(上)
    1. 怎样让程序对 CPU 概要信息进行采样?
      • 需要用到runtime/pprof包中的 API
      • 在我们想让程序开始对 CPU 概要信息进行采样的时候,需要调用这个代码包中的StartCPUProfile函数
      • 而在停止采样的时候则需要调用该包中的StopCPUProfile函数。
  27. 程序性能分析基础(下)

Gin

GORM

JWT_go