跳到主要内容

总结

基础

语言

数据类型

数据类型分为四类:基础类型、复合类型、引用类型和接口类型。

基础类型,包括:数字、字符串和布尔型

复合数据,类型——数组和结构体——是通过组合简单类型,来表达更加复杂的数据结构。

引用类型,包括指针、切片、字典、函数、通道

接口类型,是对其它类型行为的抽象和概括

Goroutine

进程:进程是系统进行资源分配的基本单位,有独立的内存空间。

线程:线程是 CPU 调度和分派的基本单位,线程依附于进程存在,每个线程会共享父进程的资源。

协程:协程是一种用户态的轻量级线程,协程的调度完全由用户控制,协程间切换只需要保存任务的上下文,没有内核的开销。

Golang 的 goroutine 是如何实现的? - 知乎 https://www.zhihu.com/question/20862617

GPM 模型

Go 学习总结之 GPM 模型 - 知乎 https://zhuanlan.zhihu.com/p/261807834

G:Goroutine,每个 Goroutine 对应一个 G 结构体,G 存储 Goroutine 的运行堆栈、状态以及任务函数,可重用。G 并非执行体,每个 G 需要绑定到 P 才能被调度执行。

P: Processor,表示逻辑处理器,对 G 来说,P 相当于 CPU 核,G 只有绑定到 P 才能被调度。对 M 来说,P 提供了相关的执行环境(Context),如内存分配状态(mcache),任务队列(G)等。P 的数量决定了系统内最大可并行的 G 的数量(前提:物理 CPU 核数 >= P 的数量)。P 的数量由用户设置的 GoMAXPROCS 决定,但是不论 GoMAXPROCS 设置为多大,P 的数量最大为 256。

M: Machine,OS 内核线程抽象,代表着真正执行计算的资源,在绑定有效的 P 后,进入 schedule 循环;而 schedule 循环的机制大致是从 Global 队列、P 的 Local 队列以及 wait 队列中获取。M 的数量是不定的,由 Go Runtime 调整,为了防止创建过多 OS 线程导致系统调度不过来,目前默认最大限制为 10000 个。M 并不保留 G 状态,这是 G 可以跨 M 调度的基础。

Sched:Go 调度器,它维护有存储 M 和 G 的队列以及调度器的一些状态信息等。

调度器循环的机制大致是从各种队列、P 的本地队列中获取 G,切换到 G 的执行栈上并执行 G 的函数,调用 Goexit 做清理工作并回到 M,如此反复。

GC 的迭代

go1.1,提高效率和垃圾回收精确度。
标记-清除(mark and sweep)算法

go1.3,提高了垃圾回收的精确度。
go1.4,之前版本的runtime大部分是使用C写的,这个版本大量使用Go进行了重写,让GC有了扫描stack的能力,进一步提高了垃圾回收的精确度。
go1.5,目标是降低GC延迟,采用了并发标记和并发清除,三色标记,write barrier,以及实现了更好的回收器调度,设计文档1,文档2,以及2015 版的Go talk。
三色标记——“强-弱” 三色不变式、插入屏障、删除屏障

go1.6,小优化,当程序使用大量内存时,GC暂停时间有所降低。
go1.7,小优化,当程序有大量空闲goroutine,stack大小波动比较大时,GC暂停时间有显著降低。
go1.8,write barrier切换到hybrid write barrier,以消除STW中的re-scan,把STW的最差情况降低到50us,设计文档。
三色标记——混合屏障

go1.9,提升指标比较多,(1)过去 runtime.GC, debug.SetGCPercent, 和 debug.FreeOSMemory都不能触发并发GC,他们触发的GC都是阻塞的,go1.9可以了,变成了在垃圾回收之前只阻塞调用GC的goroutine。(2)debug.SetGCPercent只在有必要的情况下才会触发GC。
go.1.10,小优化,加速了GC,程序应当运行更快一点点。
go1.12,显著提高了堆内存存在大碎片情况下的sweeping性能,能够降低GC后立即分配内存的延迟。
go1.13,着手解决向操作系统归还内存的,提出了新的 Scavenger
go1.14,替代了仅存活了一个版本的 Scavenger,全新的页分配器,优化分配内存过程的速率与现有的扩展性问题,并引入了异步抢占,解决了由于密集循环导致的 STW 时间过长的问题
go gc垃圾回收——三色标记、混合写屏障 - 简书 https://www.jianshu.com/p/ff3d6da5d71a

golang gc| go语言gc详解 - 知乎 https://zhuanlan.zhihu.com/p/115143370

Slice

数组和切片的区别

切片包含了一个数组和它的长度以及容量数据。

扩容规则,cap<1024 翻倍扩容,cap>=1024 原来容量的四分之一扩容

range 的时候,value 是一个局部变量

深入解析 Go 中 Slice 底层实现 - 简书 https://www.jianshu.com/p/030aba2bff41

Chan

chan 谁发送谁关闭

操作nil channelclosed channelnot-closed non-nil channel
closepanicpanic成功 close
ch <-一直阻塞panic阻塞或成功写入数据
<- ch一直阻塞读取对应类型零值阻塞或成功读取数据

Map

hash

Interface

TODO:

Mutex

高并发 mutex

Defer Panic Recover

defer - 先进后出

recover - 只能接当前 routine panic

网络

TCP/IP

TCP 三次握手 四次挥手

HTTP(S)

TODO:

Websocket

TODO:

数据库

Sql Or NoSql,看完这一篇你就懂了 - 五月的仓颉 - 博客园 https://www.cnblogs.com/xrq730/p/11039384.html

SQL

MySQL TODO:实际语句用得少,但是很多人问。

NoSQL - not only SQL

内存缓存-Redis 这篇 Redis 文章,图灵看了都说好 https://mp.weixin.qq.com/s/k8agEub4qmhm3kX_TpETrA

五种数据类型 String 数据类型、List 数据类型、Hash 数据类型(散列类型)、set 数据类型(无序集合)、Sorted Set 数据类型 (zset、有序集合)。

搜索型-ElasticSearch TODO:

列式-HBase TODO:

文档型-MongoDB TODO:

进阶

语言

内存模型

Golang 并发编程核心—内存可见性

算法

TODO:

Nginx

Nginx 最全操作总结 https://mp.weixin.qq.com/s/LmtHTOVOvdcnMBuxv7a9_A

Docker

TODO:

RPC

花了一个星期,我终于把 RPC 框架整明白了! - 51CTO.COM https://developer.51cto.com/art/201906/597963.htm#topx

gRPC 基础概念详解 https://mp.weixin.qq.com/s/I2QHEBO26nGqhGwIw281Pg

面试题

Go 语言笔试面试题汇总 | 极客面试 | 极客兔兔 https://geektutu.com/post/qa-golang.html

Golang 面试题(从基础到高级) https://blog.csdn.net/weixin_34128839/article/details/94488565

Golang 进阶面试题整理 https://blog.csdn.net/sinat_35406909/article/details/103818364

你遇到过哪些高质量的 Go 语言面试题? - 知乎 https://www.zhihu.com/question/60952598