TAG
Golang
69 篇笔记
- 1.1 make vs newhistorical
1. 是什么 golang的内置函数 2. 为什么需要 分配内存空间 值类型的声明之后即可使用 引用类型的则需要分配空间 3. 使用 3.1. new 开辟一段内存,并置为零值,返回指向该类型内存地址的指针 3.1.1. 相当于&结构体{} 3.2. make 用于创建slice、map和chann
- 1.2 reflectionhistorical
1. 反射是什么 修改代码- 编译- 运行 正常来说我们要修改代码只能在编译前,反射能让我们在运行时修改代码 2. Golang如何实现反射 interface 当向interface变量赋予一个实体类型的时候,interface会存储实体的类型信息,反射就是通过interface的类型信息实现的
- 1.3 errorhistorical
1. exception和error Golang把错误分成exception和error - exception是严程序内部的BUG或者不可预料的情况 - error则是可以预期的,通过一个返回值来判断 2. 使用 2.1. exception - 内部BUG通过recovery捕获转换成erro
- 1.4 interfacehistorical
1. 有哪些 1.1. 空接口interface{} 可以接收任意类型的数据 它只要记录这个数据在哪儿,是什么类型的就足够了 1.1.1. 举例 底层结构如下 - 赋值 - 1.2. 非空接口 非空接口就是有方法列表的接口类型 一个变量要想赋值给一个非空接口类型,其类型必须要实现该接口要求的所有方法
- 1.5 functionhistorical
1. 是什么 - 函数是一等公民 - 有具名函数、匿名函数 - 把函数绑定在struct上就成了方法 2. 使用 2.1. 可变参数 2.2. 多返回值 go语言的函数可以返回多个值 2.2.1. 原理 - C语言的实现 在调用函数中分配返回值的空间,并将返回值的指针传给被调函数 - Go语言的实现
- 1.6 stringhistorical
1. 字符集 计算机只能存储字节(二进制),因此字符肯定也是用字节存储的 但是存储后怎么显示呢?需要建立字节和字符的映射,这就是字符集 比如 - 1.1. Unicode字符集 - 由来 最开始只有ASCII字符集,只支持英文; 为了支持中文简体,推出GB2312; 为了支持中文繁体,推出BIG5.
- 1.7 maphistorical
1. 什么是map O(1)效率存取k-v对 2. map如何实现 数组。数组中每个元素叫做桶 2.1. 写入 2.2. 读取 3. 如何找到key所属的桶 - 第一种:取模运算:hash%m - 第二种:按位与运算:hash&(m-1) - 这里m必须是2的幂次 4. 冲突了怎么办 - 开放寻址法
- 1.8 unsafehistorical
1. 指针类型 1.1. 是什么 变量的地址 1.2. 为什么需要指针类型 使用指针类型可以让callee修改caller传递的值 1.3. Golang的指针类型 Golang的指针类型是安全的 - 不能进行数学运算 - 不同类型的指针不能相互转换 - 不同类型的指针不能使用 == 或 != 比较
- 1.9 panic和recoverhistorical
1. 是什么 - panic是内置函数,可以停止正常的流程。 - recover是内置函数,可以捕获到panic,recover只在defer函数中有用。 2. 为什么需要 - panic一般用于不可恢复的错误,让程序不能继续进行 - recover为了防止panic之后整个进程都down掉,这个时
- 1.10 类型系统historical
1. 有哪些类型 1.1. 内置类型 1.2. 自定义类型 2. 类型元数据是什么 不管是内置类型哈还是自定义类型都有类型元数据,这些类型元数据共同构成了Go语言的类型系统 不管是内置类型还是自定义类型,都有一个对象头 2.1. 内置类型 内置类型除了对象头之外,还会有额外信息 2.1.1. 举例
- 1.11 arrayhistorical
1. 是什么 定长的数组 2. 使用 2.1. 数组的长度也是类型 2.2. 数组是值传递 赋值和函数传参时候是复制一份新的数组 2.3. 可以用range迭代 3. 原理 3.1. 数据结构 3.2. 创建 3.2.1. 初始化 - 第一种方式 会调用到cmd/compile/internal/t
- 1.12 slicehistorical
1. slice 是什么 支持动态扩容的数组 2. 为什么需要 slice array 元素长度固定,无法动态扩容 3. 如何使用 slice 3.1. 基本使用 3.2. 函数传参是引用 - 虽然传的是引用,但是为了避免扩容后 slice 改变,函数返回 slice 3.3. nil slice
- 1.13 deferhistorical
1. 什么是defer 让函数可以在当前函数执行完毕后执行的一种机制。 这里的函数执行完毕包括通过return正常结束或者panic导致的异常结束 2. 为什么需要defer 减少资源泄露的发生 3. 如何使用 在创建资源语句的附件,使用defer释放资源 3.1. 关闭资源 3.2. defer和
- 2.1 contexthistorical
1. context goroutine的上下文,在 goroutine 之间传递上下文信息,包括:取消信号、超时时间、截止时间、k-v 等。 控制并发的其中一种方式,另外一种是sync.WaitGroup.md 2. 使用 2.1. deadlines:超时取消 2.2. cancellation
- 2.2 sync.WaitGrouphistorical
1. 是什么 一种控制并发的方式 让一个goroutine等待其他goroutine完成 类似于9.CountDownLatch.md 2. 使用 3. 原理 - 里面维护了一个counter计数器 - Add 增加计数器 - Done 计数器-1 - Wait 等待计数器到达0时往下执行 4. 参
- 2.3 synchistorical
1. 是什么 提供了基本的 synchronization primitives 除了 Once 和 WaitGroup 外,大部分都是给 low-level 的库使用的 high-level 一般使用 channels 2. 有什么 2.1. Locker - 是个接口 - 有Lock和Unloc
- 2.4 sync.maphistorical
1. sync.map是什么 - 线程安全的Map - 底层使用乐观锁实现,所以适用竞争不大的场景 - 一次写多次读,如缓存的场景 - 多个goroutine读写的是没有交集的key 1.1. 并发安全的思路 - 加一把大锁 - 把map分成若干map,只操作小map 2. 使用 3. 源码分析 3
- 2.5 sync.poolhistorical
1. 是什么 保存temp object的pool。 temp表示这个对象可能会被回收,所以这个pool其实就是个cache 2. 为什么需要 将暂时不用的对象缓存起来,待下次需要的时候直接使用 这样就不用经过内存分配,减轻GC的压力 3. 怎么使用 3.1. fmt - Printf - Fpri
- 2.6 selecthistorical
1. 是什么 - 类似于IO多路复用 - 监听多个阻塞的事件,如果事件发生了,那么执行该事件逻辑 - 如果没有发生并有默认的事件,那么执行默认的事件逻辑 - 如果没有发生且没有默认的事件,那么一直阻塞 2. 使用 2.1. 基本使用 代码执行到 select 时,case 语句会按照源代码的顺序被评
- 2.7 sync.Oncehistorical
1. 是什么 Once 是一个对象,它提供了保证某个动作只被执行一次功能 说白了就是使方法只执行一次 2. 使用 2.1. 单例模式 单例模式.md 3. 原理 通过sync.atomic+sync.Mutex实现 - Do 方法为什么不直接 o.done == 0 而要使用 atomic.Load
- 2.8 sync.Mutexhistorical
1. Mutex是什么 - 互斥锁 - 实现了Locker接口,zero-value是没加锁的状态 - 加锁解锁可以在不同的goroutine中 2. 使用 2.1. 不使用Mutex的情况 2.2. 使用Mutex的情况
- 2.9 sync.RWMutexhistorical
1. 是什么 - 实现了Locker接口,是个读写锁 - Lock , RLock 分别用于加写锁和读锁 - Unlock , RUnlock 分别用于解写锁和读锁 2. 使用
- 2.10 sync.Condhistorical
1. 是什么 - 条件变量。Locker和Cond的关系类似于Java中Lock和Condition的关系。 - 所有方法必须持有Lock才能调用 - func NewCond(l Locker) Cond 使用Lock创建一个Cond - func (c Cond) Wait() 自动释放Lock
- 2.11 atomichistorical
1. atomic是什么 原子性 - 一个或多个操作要么全部执行,要么全部不执行。 - 最小的不可并行化的操作,就是同一时刻最多只有一个并发体对资源进行操作 - 一般情况下,原子操作都是通过“互斥”访问来保证的,通常由特殊的CPU指令提供保护 2. atomic value是什么 atomic包把底
- 2.12 channelhistorical
1. CSP并发模型 - 从内存的角度看,并行计算只有两种: 共享内存 、 消息通信 - 基于共享内存的并发模型通常提供互斥锁作为同步原语 - CSP 全称是 “Communicating Sequential Processes”,是一种基于消息通信的并发模型,由Tony Hoare于1977年提
- 2.13 concurrenthistorical
1. 有什么 1.1. goroutine+channel - goroutine.md - channel.md 1.2. sync包 sync.md 2. 同步 2.1. 顺序一致性模型 同一个Goroutine线程内部,顺序一致性内存模型是得到保证的 2.2. happens-before 不
- 2.14 goroutinehistorical
1. goroutine是什么 - 程序、进程、线程.md - Go语言实现的用户线程 - 相比较于线程,goroutine - 创建、销毁和切换:都在用户态完成无需进入内核 - 内存占用:默认栈大小为2K,并且可以动态扩缩容 2. goroutine使用 2.1. 创建协程 - go f(x, y
- 2.15 协程池historical
1. 协程池是什么 复用goroutine的池子 2. 为什么需要协程池 跟如何设计池化技术.md不同,由于 goroutine创建、销毁对象开销小:创建销毁是在用户态, goroutine数量理论上可以无限,一个goroutine占用内存仅仅不到2K 所以99%的情况下不需要协程池 但是在极限情况
- 3.1 GMPhistorical
1. goroutine调度器 - Golang中协程的调度模型,即有M个线程,N个协程,该怎么分配协程给线程执行 - 这个本质上和操作系统的调度器类似,即有M个处理器,N个线程,怎么分配处理器给线程执行 1.1. GM模型 - 最开始采用的是GM模型 - G:goroutine,M:内核线程 -
- 3.2 逃逸分析historical
1. 逃逸分析 如果是Java或C++创建出来的对象一般都是分配在堆上的,而Golang new出来的对象会根据逃逸分析决定是分配在堆还是栈上 2. 为什么需要逃逸分析 堆 栈 --- ----------- ------------- 回收 需要垃圾回收 退出函数即销毁 空间 大 小 3. 如何逃
- 3.3 Go构建过程historical
1. 文本文件 保存之后这个文件以二进制形式存储在磁盘中 使用vim打开,敲入 :%!xxd 最左边的地址列,中间是文本字符对应的十六进制ASCII编码,最右边是文本字符。 ASCII表可以通过 man ascii 查询 像这种把二进制通过字符表转换成人类可读的文件叫做文本文件,不可读的就是二进制文
- 3.4 内存管理historical
1. Golang内存分区 1.1. 栈 Golang栈管理.md 1.2. 堆 Golang堆管理.md 1.3. 全局区-静态全局变量区 - 全局变量+常量 - 分配:进程启动时 - 回收:进程退出时,由操作系统回收 1.4. 代码区 2. Golang runtime.MemStat Top
- 3.5 plan9汇编historical
1. Plan9汇编是什么 - 伪汇编 - 跟汇编一样需要通过汇编器转换成机器指令才能被CPU执行 - 伪的原因在于:对机器指令反汇编无法生成Go汇编,只能生成平台相关的汇编 2. 寄存器 - 通用寄存器 与AMD64机器的寄存器对应关系如下: 一般前六个用来传递参数,BP和SP用于管理栈顶和栈底
- 3.6 内存对齐historical
1. 机器字长 1.1. 地址总线和数据总线 - CPU通过地址总线到内存中寻址,而内存通过数据总线把数据传输给CPU - 地址总线的位数决定了内存大小:比如8bit地址总线,那么可以寻址[0, 255]总共256B的内存,内存超过256B也利用不了 - 数据总线则决定了一次性能传输多少数据:比如要
- 3.7 GChistorical
1. 什么是GC GC.md 2. 为什么需要GC GC.md 2.1. GC的问题 2.1.1. 内存泄露 Golang内存泄露.md 2.1.2. STW 通过三色标记法减少GC STW的时间 3. 如何进行垃圾回收 3.1. GC触发 - 主动触发 - 通过调用 runtime.GC 来触发
- 3.8 Golang栈管理historical
1. 栈是什么 - 空间小,数据存放时间较短暂。栈在高地址,从高地址向低地址增长 - 分配:函数调用自动分配 - 回收:函数返回自动回收 2. Golang栈的特点 2.1. 动态扩容 - go runtime不是给每个goroutine分配固定的空间,而是需要的动态分配栈空间 - 创建gorout
- 3.9 Golang堆管理historical
1. 堆是什么 - 空间大,数据存放时间较长。堆在低地址,从低地址向高地址增长 - 分配:程序员手动分配 - 回收:GC Go的内存管理是runtime,也就是说并不是每次内存分配都需要进行系统调用。 采用的算法是 TCMalloc 算法,即 Thread-Caching Malloc 。 他把可用
- 4.1 unittesthistorical
1. 是什么 单元测试 2. 使用 - 文件名 xxx test.go - 导入 testing - 函数名必须 TestXXX - 运行 - go test . 3. 参考 - Go语言基础之单元测试 \ 李文周的博客 - testing \- The Go Programming Languag
- 4.2 pprofhistorical
1. pprof是什么 Golang的性能分析工具。 2. 如何使用pprof 有两个库: runtime/pprof :采集工具型应用运行数据进行分析 net/http/pprof :采集web应用运行时数据进行分析 benchmark :压测 2.1. runtime/pprof 2.1.1.
- 4.3 benchmarkhistorical
1. 使用 - bench.go - bench test.go - 测试: - go test -bench=. - 查看内存分配信息: go test -bench=. -benchmem - 生成CPU信息: go test -bench=. -benchmem -cpuprofile pro
- 4.4 Golang内存泄露historical
1. 内存泄露 内存泄露.md 2. Golang内存泄露 2.1. root对象引用 2.2. goroutine 泄漏 goroutine泄露:原理、场景、检测和防范 \- SegmentFault 思否 - 如果你启动了一个 goroutine,但并没有符合预期的退出,那么直到程序结束这个go
- 4.5 tracehistorical
1. 使用 步骤如下: 1. 导入包: import runtime/trace 2. 开启分析: trace.Start(file) 停止分析: trace.Stop() 3. 命令行分析 - go tool trace trace.out - 2. 参考 Go execution tracer
- consulhistorical
1. 是什么 服务注册与发现的组件 2. 单机集群搭建 2.1. 下载 Download Consul \ Consul by HashiCorp 2.2. 配置文件 2.2.1. 创建目录 2.2.2. 配置文件 server1 server2 server3 2.3. 启动 server1 server2 server3 2.4. 测试 增加服务配置文件 增加服务 web ui 3. 参考 Consul集群搭建 \ 简书 WEHou
- etcdhistorical
1. 安装 下载 Releases · etcd\ io/etcd 解压配置环境变量 2. web ui Releases · evildecay/etcdkeeper 3. 参考 etcd \ Home
- hystrixhistorical
1. circuit golang版本的hystrix实现,用于服务熔断(降级的一种措施,其他如开关熔断等) 2. 使用 hystrix.go main.go 3. 参考 cep21/circuit: An efficient and feature complete Hystrix like Go implementation of the circuit breaker pattern\. expvar \ The Go Progr
- microhistorical
1. 安装micro 1.1. 方案一 下载 Releases · micro/micro 解压配置环境变量 1.2. 方案二 前提是配置好GOBIN环境变量 下载源码 安装到GOBIN中 2. 参考 micro/micro: Micro is a distributed systems runtime for the Cloud Micro \ The fastest way to build services in the Clou
- protobufhistorical
1. 是什么 高效的序列化、反序列化方式 1.1. 普通序列化 Teacher Test 结果 可以看出字节数挺大的 1.2. protobuf序列化 TearchSerializer.proto 生成Java Test 结果 可以看出生成的字节数小 1.3. 对比 protobuf序列化的时候减少了一些额外的信息 比如int占用4个字节,而protobuf则是根据长度占用1 5个字节 1.3.1. 普通的序列化反序列化 1.3.2.
- retryhistorical
1. 是什么 调用远程服务失败,重新调用一次有可能就成功了 2. 什么时候需要重试 网络错误能重试,逻辑错误没必要 当网络错误长时间持续的时候不能使用重试,防止进一步压垮服务 不是幂等请求,不能重试 3. 重试策略 快速失败和重试的权衡 如果重试多次之后还是失败,那么不应该继续重试。参考断路器模式 4. Golang重试 4.1. retry 相当于golang版本的ribbon,定义重试策略 5. 参考 avast/retry\ go
- Go环境搭建historical
1. 安装Golang 1.1. 下载 Downloads \ The Go Programming Language 1.2. 配置环境变量 Windows直接右键计算机修改环境变量,重启生效 Linux一般修改/etc/profile,然后source /etc/profile生效 新版本的golang可以用 go env w 变量名="" 来设置环境变量,存储于 <USER HOME \AppData\Roaming\go\env
- Go语言基础historical
1. 关键字 1.1. for 1.1.1. for循环的不同形式 1.1.1.1. 经典for循环 1.1.1.2. while循环 1.1.1.3. 死循环 1.1.1.4. 增强for循环 注意:增强for循环遍历的是同一个地址,如果是并发中会有问题 解决:使用局部变量 1.2. switch 1.3. defer defer.md 1.4. make new make vs new.md 2. 数据结构 2.1. string
- Go语言学习historical
1. Golang的特点 编译型,因此不需要虚拟机 静态类型 有GC,内存管理全自动 1.1. Golang vs Java Go Java 虚拟机 无 有 跨平台 支持,依赖编译器在不同平台编译 支持,依赖JVM一次编译,到处执行 类型 编译型 解释型 内存管理 GC,自动 GC,自动 编程范式 面向过程、面向对象、函数式、面向消息 面向对象 生态 不完善。需要自己组合 完善。基于Spring业务开发 Go的内存管理类似于操作系统的虚
- WaitGrouphistorical
1. 是什么 一种控制并发的方式 让一个goroutine等待其他goroutine完成 类似于9.CountDownLatch.md 2. 使用 3. 原理 里面维护了一个counter计数器 Add 增加计数器 Done 计数器 1 Wait 等待计数器到达0时往下执行 4. 参考 Go语言实战笔记(二十)\ Go Context \ 飞雪无情的博客
- cgohistorical
1. Windows CGO 1. 安装msys2 msys2.md(关联笔记尚未公开) 2. 安装GCC toolchain 3. 测试 2. 参考 Go development environment on Windows with MSYS2 · GitHub
- go.modhistorical
1. 使用 1.1. 查询某个包是谁引入的 2. 参考 【Go 专家编程】go\.mod 文件中的indirect准确含义 \ 恋恋美食的个人空间 \ OSCHINA \ 中文开源技术交流社区 两个生僻小命令\ \ \ go mod why和go mod graph \ 清澄秋爽 PaulXu\ cn/go\ mod\ graph\ chart: Draw graphs through GO MOD GRAPH output xingl
- godochistorical
1. 安装 2. 使用 浏览器打开:http://127.0.0.1:6060/ 3. 参考 golang go doc 与 godoc 文档生成查看\ whatday的博客\ CSDN博客
- httphistorical
1. 是什么 可以简单的使用http.Get、http.Post、http.PostForm,底层调用的都是 client.Do client是线程安全的 constant预设了状态码和method 使用NewRequest构造Request,这个对象有各种方法可以设置header、param、request body等;使用Client发起请求;返回的是Response,Response有各种属性 2. 使用 2.1. http bu
- iohistorical
1. 是什么 I/O操作 2. 有什么 2.1. os 提供了跨平台的操作系统操作,错误了会返回PathError,可以从里面获取详细的错误信息 常量有只读、只写等模式,变量有STDIN、STDOUT、STDERR func Open(name string) ( File, error) 用于打开一个文件, func OpenFile(name string, flag int, perm FileMode) ( File, erro
- jsonhistorical
参考 bashtian/jsonutils: Converter for JSON data to a Go struct or a Java class for GSON
- packagehistorical
1. 是什么 go组织源码的方式 2. 包初始化流程 package2 test.go service.go dao.go 输出 3. 循环依赖 package1 test.go dao.go service.go 输出 可以看出 test/package1/dao 导入了 test/package1/service ,而 test/package1/service 导入了 test/package1/dao ,因此循环依赖了 4. 常
- sqlhistorical
1. 是什么 2. 有什么 2.1. 连接 DB 是线程安全的 func Open(driverName, dataSourceName string) ( DB, error) Open只是验证连接串格式,不是打开连接;需要用PING func (db DB) Ping() error 需要的时候创建连接,并验证连接是否活着 0 < MaxidleConnection < MaxOpenConnection func (db DB)
- structhistorical
1. struct比较 同类型的struct可以进行比较 比较逻辑:对每个字段进行相等性比较,如果全部相等返回 true,否则返回 false 不同类型的struct不可以比较,会报编译错误
- xormhistorical
1. reverse tool 1.1. 安装 1.2. 使用 配置文件tao.yml 命令 2. 参考 xorm/reverse: A flexsible and powerful command line tool to convert database to codes \ README\ CN\.md at master \ reverse \ Gitea: Git with a cup of tea Xorm