From 833621a7df5a1f5994878bb95dff3698fdc18564 Mon Sep 17 00:00:00 2001 From: x1a0xf Date: Mon, 22 Jul 2024 08:37:12 +0800 Subject: [PATCH] fix: fix go version --- .github/workflows/release_auto_update.yml | 2 +- .pre-commit-config.yaml | 4 +- gh.yml | 6258 --------------------- 3 files changed, 3 insertions(+), 6261 deletions(-) delete mode 100644 gh.yml diff --git a/.github/workflows/release_auto_update.yml b/.github/workflows/release_auto_update.yml index bb40e5b..b3e1da3 100755 --- a/.github/workflows/release_auto_update.yml +++ b/.github/workflows/release_auto_update.yml @@ -12,7 +12,7 @@ jobs: build: strategy: matrix: - go-version: [1.21.0] + go-version: [1.22.0] platform: [macOS-latest] runs-on: ${{ matrix.platform }} steps: diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 16e536b..c083deb 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -21,8 +21,8 @@ repos: - id: check-symlinks - id: mixed-line-ending - id: check-case-conflict - - id: check-executables-have-shebangs - - id: check-shebang-scripts-are-executable +# - id: check-executables-have-shebangs +# - id: check-shebang-scripts-are-executable - repo: https://github.com/pre-commit-ci/pre-commit-ci-config rev: v1.6.1 diff --git a/gh.yml b/gh.yml deleted file mode 100644 index 507e6d2..0000000 --- a/gh.yml +++ /dev/null @@ -1,6258 +0,0 @@ -# lang - -- type: lang - repo: - - url: https://github.com/langserver/langserver.github.io - des: LSP (Language Support Protocol) - - -- type: Compiler - md: false - repo: - - url: https://github.com/goccy/p5-Compiler-Lexer - - url: https://github.com/jamiebuilds/the-super-tiny-compiler - des: 基于js实现的compiler,合计不到1000行代码 - - url: https://github.com/skx/monkey - des: 用golang实现的interpreter,是用来学习compiler的好资料 - - url: https://github.com/chai2010/go-ast-book - - url: https://github.com/wa-lang/ugo-compiler-book - des: 同样是用golang实现的interpreter - - url: https://github.com/jacksplwxy/JavaScript-compiler - - url: https://github.com/robertkrimen/otto - des: golang call js. otto is much easier to use than goja. 可以理解为golang实现的js interpreter. - qs: - - q: Compare compiler and interpreter? - - q: java是编译型语言吗? - x: java可以看作是 semi-compiled 语言。具体来说,解释型语言在运行时使用 sapi 解释执行 PHP 时,通过 zend 转 opcode 码,再转为机器码。而java 则是运行前 JVM 先转为 bytecode(其实也是 opcode),运行的时候 JVM 再将 bytecode 转为机器码。 - - q: How compiler works? What are the roles of FE and BE? And how does each step works? - x: 这里的 FE 指的是编译器对程序代码的分析和理解过程。它通常只跟语言的语法有关,跟目标机器无关。而与之对应的 BE 则是生成目标代码的过程,跟目标机器有关。 - - q: CST(Parse Tree), AST - - q: Compare compilers such as (LLVM, goc, rustc, HHVM, v8(Ignition), tsc, cpython, pypy)? # arch, feats, philosophy - - q: 怎么学习“编译原理”? - x: 结论:对于新手,一开始就写编译器不一定是很好的选择,因为编译器的重点在于后端,而后端知识对于普通程序员而言用处不大。编译原理相关的知识,其实对普通程序员而言用处不大。因为compiler的重点是后端,而后端对普通开发没啥用。应该先学着写一个interpreter,然后再实现一个简单而完整的compiler,基本上就足够了。对我们来说主要要学习与lang相关的部分,也就是fe,至于be的IR和之类的东西,虽然通常这些才是真正的优化点,但是我们只需要了解即可。 - - - q: AOT, JIT - - q: 编译器优化有哪些方法? - x: 常量传播 cp, 常量折叠 cf, 死码消除, 公共子表达式消除 CSE, 循环不变代码移动, BCE(Bounds Check Elimination) - - q: inline - - q: IPA, LTO, PGO, FDO - - q: SSA, Alias Analysis, Dependence Analysis, Vectorization, Data-flow - - q: 循环不变式 - - q: 熟悉不同编译优化技术,如 IPA、LTO、PGO、FDO 等;理解部分编译优化概念,如 SSA、Alias Analysis、Dependence Analysis、Vectorization、Data-flow - - - - -- type: Malloc - md: true - repo: - - url: https://github.com/google/tcmalloc - qs: - - q: How TCMalloc works? - x: (CCMalloc, local memory-pool(multi-level, BestFit, free-lock), RSEQ) - - q: TCMalloc = CCMalloc(CPU Caching Malloc) - des: google. TCMalloc是专门对多线并发的内存管理而设计的,TCMalloc主要是在线程级实现了缓存,使得用户在申请内存时大多情况下是无锁内存分配。整个 TCMalloc 实现了三级缓存,分别是ThreadCache(线程级缓存),Central Cache(CentralFreeeList),PageHeap(页缓存),最后两级需要加锁访问。*TCMalloc 的核心思想是,切分内存多级管理降低锁粒度*(把内存切成几块,通过多级管理降低锁的粒度);将可用的堆内存采用二级分配的方式进行管理:每个线程都会维护一个独立的内存池,进行内存分配时优先从该内存池中分配,当内存池不足时,才会向全局内存池申请,以避免不同线程对全局内存池的频繁竞争。*使用多级缓存将对象大小分类,并按照类别使用不同的分配策略*。 - - url: https://github.com/microsoft/mimalloc - des: ms. better perf than others. 在微软的云服务, 虚幻引擎中使用. - qs: - - q: mimalloc 是lock-free的吗? 怎么实现的呢? - - url: https://github.com/jemalloc/jemalloc - des: facebook. 来自FreeBSD的内存分配器,在Firefox和Rust里被使用. - qs: - - q: jemalloc 是怎么通过使用多个 arena 来减少多线程间锁竞争? - - url: https://github.com/polarsignals/rust-jemalloc-pprof - des: convert jemalloc data to pprof format - des: Memory Allocator - qs: - - q: "***Compare memory allocators. (jemalloc, TCMalloc, PTMalloc(glibc默认Malloc), Mimalloc)***" - x: | - (mechanism, ) - 两个方面, - 系统向:看内存管理库是如何管理空闲内存的 - 用户向:看用户程序如何向内存管理库申请内存(释放大致相似,可以参考申请) - - 应该从 锁机制、内存利用率、内存分配粒度和效率、内存碎片 这5点来进行比较,其实都是“切分内存多级管理”来提高内存利用率和减少内存碎片的(当然具体切分粒度不同,比如Jemalloc的small, large, huge分别是56KB, 4MB,而TCMalloc则是256KB, 1MB),最大的区别在于锁机制(为了减少锁竞争,提高并发)的优化,比如PTMalloc直接mutex了,而其他三个则都有针对性优化,分别选择了“多个arena”、“小对象pool+大对象spinlock”、“lock-free”。 - - - - -- type: GC - md: true - repo: - - url: https://github.com/mkirchner/gc - des: zero-dependency garbage collection for C - qs: - - q: "***GC的核心需求(关注的指标)? 如何设计一个好的 GC 算法?***" - x: CPU(utilization and throughput, locality), STW(time, freq), memory fragmentation - - q: "***有哪些GC方案? MS存在哪些问题? 对 MS 有哪些优化方案? 请从“各种指标”比较这些方案***" - x: | - 分别针对mark阶段和sweep阶段 (Mark Compact, semispace(cheney, baker), Incremental GC, 分代回收) - MS 有以下问题: - - heap 容易出现碎片 - - 破坏引用本地性(由于对象不会被移动,存活的对象与空闲空间交错在一起) - - GC 时间与 heap 空间大小成正比 - - 在进行 GC 期间,整个系统会被挂起,即 stop-the-world - 需要说明一点,RC 类 GC 同样有前两个问题,但是对于 RC 来说,并没有好的优化措施来缓解。下面我们就来看追踪类 GC 是如何解决上述问题。 - - q: 请比较各种主流语言的GC机制? - x: java, erlang, ruby, v8 - - -- type: ASM - repo: - - url: https://github.com/capstone-engine/capstone - des: Capstone 反汇编框架 - - - ---- - - -- type: Config - repo: - - url: https://github.com/spf13/viper - key: true - des: 用viper的目的是是兼容本地配置和远程配置中心两种模式,因为可以无感从local切换到etcd. viper可以读取JSON, TOML, YAML, HCL, .env, and Java properties等格式的配置文件. - qs: - - q: viper合并多个viper文件 - d: https://mp.weixin.qq.com/s?__biz=MzAxMTA4Njc0OQ==&mid=2651453499&idx=1&sn=8f6234b80b49df964dfe5b1070c7fb35) - - q: viper读取单文件中的多个separate yaml - - url: https://github.com/jinzhu/configor - des: configor相比viper - - url: https://github.com/joho/godotenv - des: config, dotenv, 只支持从 .env 读取配置 - - url: https://github.com/mikefarah/yq - des: 相当于 jq 的 golang 实现, yq is a portable command-line YAML, JSON, XML, CSV, TOML and properties processor - -# [JSON库性能对比及实现探究 - MySpace](https://www.hitzhangjie.pro/blog/2023-08-23-json%E5%BA%93%E6%80%A7%E8%83%BD%E5%AF%B9%E6%AF%94%E5%8F%8A%E5%AE%9E%E7%8E%B0%E6%8E%A2%E7%A9%B6/) -- type: JSON - repo: - - url: https://github.com/bytedance/sonic - des: used to replace encoding/json, convert JSON to map or struct. faster than jsoniter, easyjson and go-json. easyjson need to generate file, jsoniter 比 gabs 好用. - - url: https://github.com/buger/jsonparser - des: jsonparser 比 simplejson 好用,因为 simplejson 要用逗号 ok 处理各种问题,还没有ArrayEach和ObjectEach两种遍历方法 - - url: https://github.com/json-iterator/go - des: jsoniter 21年就废弃了,但是仍然是比较常用的json解析库 - - url: https://github.com/jqlang/jq - des: used to parse JSON, very helpful. also support brew install, better than gojq. - - url: https://github.com/glideapps/quicktype - des: 类似jq,也是用来处理JSON的,但是这个是类似 JSON-To-Go 这样的工具,但是支持几乎所有语言。 - - url: https://github.com/brimdata/zed - des: zq is a lot like jq but is built from the ground up as a search and analytics engine based on the Zed data model. Since Zed data is a proper superset of JSON, zq also works natively with JSON. - - - - -- type: yaml - repo: - - url: https://github.com/go-yaml/yaml - des: config, yaml - - url: https://github.com/yaml/yaml-spec - doc: https://yaml.org/spec/1.2.2/ - qs: - - q: "*yaml的key的value怎么复用*" - x: 变量(${site.url.user}), anchors(&, <<), 只复用字符串(&, *) - - q: yaml数据类型强制转换 - - q: yaml多文件怎么parse - - q: yaml多行字符串的几种用法,有啥区别 - - q: yaml多值映射怎么搞(?和:分别用array标明key和val) - - - - ---- - -# golang - -- type: golang - md: true - repo: - - url: https://github.com/golang/go - qs: - - q: How to handle error in golang? - - q: "**code specs in golang?**" - - q: shallow copy and deep copy in golang? - x: (is shared memory address) (basic value, or ref value) value type and ref type (allocate to stack or heap) - - q: web framework? In another word, Why gin is popular than others? - x: middleware, router(LCP using TrieTree) - - q: golang project structure? (internal, pkg, cmd, api) - - q: How to troubleshot? golang services often report 502. What are the possible reasons? - - - q: How to use set/bitset in golang? - qq: - - topic: string - url: https://github.com/golang/go/blob/master/src/runtime/string.go - des: string 没有 cap,所以 string 是个只读类型,这点可以对比 slice(slice 就有 cap,所以可以修改) - qs: - - q: What happens when convert string to []byte in golang? How to optimize the conversion between string and []byte? - - topic: strings - url: https://github.com/golang/go/tree/master/src/strings - qs: - - q: EqualFold() - - q: Compare(), Contains()(Any()/Func()/Rune()), Count(), Cut(), CutPrefix(), CutSuffix(), Fields()(Func()), HasPrefix()/HasSuffix(), Index()/LastIndex()(Any()/Byte()/Func()/Rune()), Join(), Map(), Repeat(), Replace()/ReplaceAll(), Split()/SplitAfter()/SplitN()/SplitAfterN(), ToLower()/ToUpper()/..., Trim()/... - - q: golang strings Builder. - - q: golang strings Reader. - - q: golang 字符串匹配算法 - x: RK+FNV hash - - # https://github.com/golang/go/tree/master/src/slices - - topic: slice - url: https://github.com/golang/go/blob/master/src/runtime/slice.go - qs: - - q: 对 slice 赋值的具体实现? - x: 底层数组是可以同时被多个 slice 指向,所以对一个 slice 的元素进行操作是有可能会影响到其他 slice 的 - - q: How to implement slice? = (pointer, cap, len) Why cap? (相当于pool, 允许切片在一定范围内动态增长,避免频繁的内存分配操作) + How does slice create and expand? - x: (growslice, oldCap < 256(threshold)指数增长, >256 for..., 更平滑) - - q: Compare golang slice and redis list? 既然array完胜DLL,为啥redis还要用DLL实现list,而不是用array? - x: 核心区别就是slice基于Array,redis基于DLL。空间复杂度(slice内存开销更小)、读操作时间复杂度(slice更快)、扩容机制(预分配/按需分配)和使用场景的区别都是表现。很明显,DLL相比array更适合写多读少的场景,然而redis...DLL和Array就像绿皮火车和高铁 - - q: slice pseudo shrink - x: slice和map都是pseudo shrink,且回收都要靠GC来完成(事实上只要是带GC的语言都是pseudo shrink,都是靠GC完成回收)三种:c/cpp这种无GC的真缩容、带GC的都是伪缩容、rust - - q: golang slice是否原生支持并发? Why? - x: 如果定义了len,并发读是安全的,因为一旦定义len,就不能在不重新分配底层数组的情况下改变。但是并发写操作仍然是不安全的。 - use: - - url: https://go.dev/play/p/i7uq2OxZ82g - des: 删除slice中的元素 - - url: https://gist.github.com/hxhac/14753a2822ef1d060077a78c38fba355 - des: How to remove element from slice of struct? - - url: https://gist.github.com/hxhac/20fc39ea8fcc6eaee461e341d473f540 - des: append 无法修改传入参数 slice? - - url: https://gist.github.com/hxhac/14d35f334ae25151a4795e720daec2b8 - des: SliceToMapSlice() struct切片转为map切片 - - des: golang 怎么用双向链表实现双向队列? - - des: 怎么优化`[]Foo`转`[]Bar`这种问题? - - des: golang slices pkg. Clip(), Clone(), Grow(), Insert(), Replace(), Reverse(), Func(BinarySearch(), Compact(), Compare(), Contains(), Delete(), Equal(), IsSorted(), Max(), Min(), Index(), Sort()) - - des: Compare slice concat methods? append(), copy(), slices.Concat() - - des: Delete, DeleteFunc, Replace, Compact, CompactFunc等函数,缩容操作之后原slice的被缩掉的那部分数据被修改为0 - - - topic: map - url: https://github.com/golang/go/blob/master/src/runtime/map.go - qs: - - q: map 在遍历时,并不是从 0 号 bucket 开始遍历,而是从一个随机 bucket 的随机 cell 开始遍历 - - q: 为什么 map 增删改会触发标志位,导致 panic? - - q: 通过 hash 函数获取目标 key 的哈希,哈希和数组的长度通过位运算,获取数组位置的索引。遍历 bmap 里的 key,和目标 key 对比获取 key 的索引。根据 key 的索引通过计算偏移量,获取到对应 value。 - x: 用位运算转换求余操作,m % n,当 `n = 1 << B` 的时候,可以转换成 `m & (1 << B - 1)` - - q: tophash 数组的设计加速了 key 的查找过程,tophash 也被复用来标记扩容操作时的状态 - - q: mapassign - - q: 双桶, mapextra 用来优化 GC, - - q: hmap struct 中有哪些是主要字段?hmap 的 extra 有啥用? - - q: hmap 中的负载因子 B 是什么?为什么是 6.5?负载因子如何影响map的性能?溢出率 - x: LB是最大可容纳元素数,用来衡量当前哈希表中空间利用率的核心指标。是因为负载因子太大了,会有很多溢出的桶;太小了,就会浪费很多空间。 - - q: bmap 是什么?为什么golang的map还需要bmap? bucket - - q: map扩容机制 - x: 查看 hashGrow() 以及 渐进式扩容 growWork(). 当 map 的负载因子超过预设的阈值(通常是 6.5)或者溢出桶(overflow buckets)数量过多时,Go 会触发 map 的扩容机制。 - - q: map 有缩容机制吗? - x: | - 伪缩容,因为map 的扩缩容的主要区别在于 hmap.B 的容量大小改变,而缩容由于 hmap.B 压根没变,内存空间的占用也是没有变化的(具体来说就是,在删除元素时,并不会释放内存),所以一定不要往 golang 的 map 中塞入太多数据。 - - 若是扩容,则 bigger 为 1,也就是 B+1。代表 hash 表容量扩大 1 倍。不满足就是缩容,也就是 hash 表容量不变。可以得出结论:map 的扩缩容的主要区别在于 hmap.B 的容量大小改变。而缩容由于 hmap.B 压根没变,内存空间的占用也是没有变化的。 - - q: golang中map进行 读操作 的具体过程(查找数据的具体流程)? - x: key 经过 hash 后共 64 位,根据 hmap 中 B 的值,计算它到底要落在哪个桶时,桶的数量为 2^B,如 B=5,那么用 64 位最后 5 位表示第几号桶,在用 hash 值的高 8 位确定在 bucket 中的存储位置,当前 bmap 中的 bucket 未找到,则查询对应的 overflowbucket,对应位置有数据则对比完整的哈希值,确定是否是要查找的数据。如果当前 map 处于数据搬移状态,则优先人 oldbuck-ets 查找。 - - q: golang中map进行 写操作 的具体过程? - - q: golang map是怎么解决hash collision的? Why? - x: CA - - - q: 用hashtable实现hashmap,和用search-tree实现hashmap,有啥区别?为啥golang, java, redis使用hashtable实现map,而cpp使用RBT实现map? - x: 这类问题的本质实际上还是比较hashtable, RBT和trie-tree - - q: "***Compare golang map and redis HashMap?***" - x: 双 table、渐进式 rehash、扩容条件、缩容条件、bgsave、COW 机制 - use: - - des: "***golang 修改map中的元素?***" - - des: How to convert []map to []struct? - - des: map[string]interface{} to struct - - des: 怎么用map实现并发读写? # 比较 "mutex+map" 和 sync.Map - - des: How to check efficiently if a map contains a key in Go? # comma ok idiom (whether err/kv/chan exist, datatype detect) - - des: How to check whether the key of map exists? - - des: "***手写实现 golang 中 map 的有序查找,且支持 add、支持 delete、支持迭代?构造一个辅助 slice***" # How does map read data? And the specific process for finding key, assigning key, deleting key and traversing key? - url: https://gist.github.com/hxhac/ddab2b9d20186ff27ec0e159e835e779 - - - - topic: sync.Map - url: https://github.com/golang/go/blob/master/src/sync/map.go - qs: - - q: "***How does sync.Map implemented? 能否认为sync.Map是read-preferring呢?***" - x: 使用了读写分离来去保证线程安全的,sync.map 的数据结构分为读 map(read)、写 map(dirty)、还有mutex以及一个记录穿透次数的值(misses)。具体实现是每次读取都会先读取读部分的 kv,没有则去读写部分的 kv(操作写部分时都会上锁)。当穿透到写部分的次数大于写部分的长度时,就会将写部分同步到读部分,并且把写部分清空。所以多协程下一般都会先打到无锁的读部分,这能保证读取性能。 - - q: "***sync.Map feats? 逐一说明 double-checking, 读写分离和动态调整, 延迟删除(在 sync.Map 中删除一个键值对实际上只是将其标记为删除,真正的删除操作会在 read 升级时进行,这样可以减少锁的持有时间。), read-preferring ***" - x: | - read map(atomic.Value), dirty map(mutex) 之间互相转化,分别在什么样的时机下会进行?nil, normal - entry的p可能的状态,有哪些? - entry 的 p 可能的状态包括 nil(空值)、指向正常数据的指针、指向脏数据的指针、锁定状态的指针、等待状态的指针和过期状态的指针。 - - - - q: Store(), Load(), Delete() 各自的实现 - # - "***Why is map not thread-safe? How to make map achieve concurrent reading and writing?***" - - q: "***Why is sync.Map rarely used in golang? What's the pros and cons?***" - x: sync.Map适合读多写少的场景(...),这就是“使用sync.Map时需要考虑读写比”这个说法 - - q: pseudo shrink leads to mem-leak, How to resolve? - - - - topic: golang compiler - url: https://github.com/golang/go/tree/master/src/cmd/compile - qs: - - q: golang compiler directives? - x: (linkname, noescape, nosplit, noinline, norace, notinheap), go doc compile - - q: Why golang compiler using SSA (to optimize compiler backend)? # (BCE+CSE) - - q: "steps of golang compile?" - x: fe(lex, syntax, semantic analysis), be(IR, optimization, code-generation, asm(Plan9)) compiler的两个阶段中的be,其实就是AST转IR,再转Plan9 asm code,最后再转成机器码。那么实际上这里的Plan9实际上就是asm - - q: Compare cpp and golang memory management. - x: (arena, heap, chunk, memory) - - q: escape analysis - - - - - topic: golang malloc - url: https://github.com/golang/go/blob/master/src/runtime/malloc.go - des: 在我看来,golang内存管理由TCMalloc+compiler逃逸分析+GC组成。其中compiler解决掉了栈内存的问题,stack由compiler自动分配和回收(比如说栈上的函数参数、局部变量、调用函数栈),这些都是自动随着函数创建而分配,执行完成而销毁。而heap则有两部分,其中heap内存分配由golang实现的类似TCMalloc的malloc来管理,而heap回收则由GC实现。 - qs: - - q: What about golang memory management? (mutator, allocator, collector) - x: 当 mutator 申请内存时,会通过 allocator 申请新内存,而 allocator 会负责从堆中初始化相应的内存区域 - - q: (stack(compiler)+heap(TCMalloc+GC)) - - q: What's mspan, mcache, mcentral, mheap? - x: | - (8kb, DLL) - - mcache(tiny allocs, 线程缓存,为每个逻辑处理器 P 提供一个本地 span 缓存, < 16kb) - - mcentral(中心缓存,被所有的逻辑处理器 P 共享) - - mheap(large allocs, 页堆,可以认为是 golang 程序持有的整个堆空间,mheap 全局唯一, > 32kb) - - - - # gc.go - 这个文件包含了垃圾回收的主要逻辑和控制流程。 - # mheap.go - 管理堆内存的源码,包括内存的分配和回收。 - # mgc.go - 包含了与并发垃圾回收相关的后台标记和清扫工作。 - # gcbss.go - 包含了BSS段的垃圾回收逻辑。 - # gcmark.go - 包含了标记阶段的实现细节。 - # gcsweep.go - 包含了清扫阶段的实现细节。 - # https://github.com/golang/go/tree/master/src/cmd/compile/internal/gc - - topic: golang GC - url: https://github.com/golang/go/blob/master/src/runtime/mgc.go - qs: - - q: 内存屏障是啥?为啥有了MESI还需要内存屏障? - - q: golang GC的大概执行过程(四个阶段)?STW 发生在什么时候? - - q: golang如何实现的“并发三色标记扫描”? - - q: golang GC现在还存在哪些问题 - - q: golang GC有哪些优化?为何需要辅助标记和辅助清扫? - - q: golang为什么选择使用三色标记,而不是分代或者复制? - - q: 什么时候启动GC? - - q: 通过哪些指标来判断要启动GC? - - q: GC应该如何与scheduler进行交互? - - q: 如何暂停一个mutator线程足够长时间,以扫描器stack? - - q: 如何表示white、grey和black三种颜色来实现高效地查找、扫描grey对象? - - q: 如何知道roots对象在哪里? - - q: 如何知道一个指向对象的指针的位置? - - q: 如何最小化内存碎片? - - q: 如何解决cache性能问题? - - q: heap应该设置为多大? - - q: 怎么调优golang GC? - - - topic: context - url: https://github.com/golang/go/tree/master/src/context - qs: - - q: What's context? usage scenario? # cancel goroutine, store kv, - - q: How to implement context? - - q: How to use? # context.WithValue(), WithCancel(), WithTimeout(), WithDeadline() - - q: How to get current goroutine's ID? - - q: 有哪些常用的runtime库? - - q: context misuses? How to avoid? What are the usage spec for using context? - - topic: atomic - url: https://github.com/golang/go/tree/master/src/sync/atomic - qs: - - q: What's atomic? Why and When to use atomic, rather than sync package? - - q: How to use? (Add/(Store+Load)/CAS) - - q: atomic是怎么实现的? - - topic: GMP - url: https://github.com/golang/go/tree/master/src/runtime - qs: - - q: "***GMP分别是啥? 为啥协程(G)和线程(M)是M:N的映射关系? G和M直接绑定就可以了,为什么要有P (抢占式调度器相较于之前调度器的优势?)? golang异步抢占的整体流程???***" - x: | - 多对一的缺点是OS 无法感知到用户态的线程,所以可能造成一个线程被阻塞,导致整个进程被阻塞挂掉,M:N 模型就解决了这个问题。 - sched - Runtime 起始时会启动一些 G:垃圾回收的 G,执行调度的 G,运行用户代码的 G;并且会创建一个 M 用来开始 G 的运行。随着时间的推移,更多的 G 会被创建出来,更多的 M 也会被创建出来。 - - - q: work stealing, handoff 分别是啥? handoff为啥要释放掉线程绑定的processor,转移给其他空闲thread执行呢? 按理说,thread和processor不是一一绑定的嘛? - x: | - 都是为了“复用线程”,避免频繁创建和销毁thread - - 还是用公司项目做类比,如果你们项目组本身没有什么任务(M上没有G),那么就从其他项目组抢任务。这个就是work stealing嘛。如果你们项目组因为某个任务阻塞掉了(需要注意的是,这里实际上对应的thread的blocked或者waiting状态,而不是直接挂掉了),那就把这个项目所绑定的项目经理(也就是Processor,用来调度任务)释放掉,把这个项目经理让给其他项目组。 - - q: "***goroutine, type and state***" - x: 要搞清楚goroutine的type和state是不同的,type分为buffered chan和unbuffered chan,state则分为nil, active, closed三种 - - q: "***golang 内存泄漏的常见场景? goroutine leak? How to detect memory leak? How to find and fix?***" - x: | - goleak - - subslices, substring, not reset pointers, hanging goroutines, time.Ticker - - - q: GMP主动调度有哪些抢占时机? - x: GC(GC的STW是一个GMP主动调度的抢占时机), syscall(goroutine执行syscall时,Go调度器会主动选择一个合适的时机来调度其他可运行的goroutine), 时间片用尽(类似kernel里CFS tick的时候,也是最常见的抢占时机) - - q: goroutine OOM了,会发生什么?怎么处理? - use: - - des: Can you implement a lock-free queue using atomic in golang? - - des: "***How to limit the max number of goroutines in golang?***" - - des: "*How to control goroutine numbers?*" # chan+wg, ants - - des: "*How to close goroutine?*" # chan, context - - topic: struct - url: https://github.com/golang/go/blob/master/src/reflect/type.go - qs: - - q: golang 匿名结构体 # 在某些场景下,比struct或者map[string]interface都更实用 - - q: misuse # private fields, pass pointer(other than pass value) - - q: field alignment # CPU clock cycle, minimize the size of the struct(in memory), Data Types in golang(bool(1), int/map(8), string(16), slice(24)) - - q: tag (name, omitempty, -), What other tags are there? # (json, xml, protobuf, yaml, gorm, mapstructure) - - q: How tag works? # reflect - use: - - url: https://go.dev/play/p/kIDCniLJxek - des: struct的omitempty - - url: https://go.dev/play/p/KlmCr1-01Ng - des: struct的tag - - - topic: channel - url: https://github.com/golang/go/blob/master/src/runtime/chan.go - qs: - - q: "***How to implement chan? data structure?***" - x: | - (ring buffer, FIFO) (hchan, ) - chan 收发遵循先进先出 FIFO 的原则 - chan 中包括 buffer、sendx 和 recvx 收发的位置 (ringbuffer 记录实现)、sendq、recv。当 chan 因为缓区不足而阻塞了队列,则使用DLL存储 - - q: Compare channel types(buffered chan, unbuffered chan)? # capacity, is block - - q: "***What happens when close/read/write a nil/closed/normal chan?***" - - - q: channel patterns (pipeline, fan-in, fan-out, barrier, (future, workers-pool, pub/sub, or-chan))? pros and cons? Please implement. - x: | - - barrier模式: 用来阻塞直到聚合所有 goroutine 返回结果 - - pipeline模式: 与 barrier 的区别在于 pipeline 是有序的; 可以让一组线程按照顺序并发或者串行的执行; - - future模式: 在异步处理中称为 promise 模式,具体来说,就是主 goroutine 不等子 goroutine 执行完就直接返回了,然后等到执行完成之后再去取结果 - - workers-pool模式: 高并发任务 - - pub/sub模式: 一种消息通知模式,发布者发送消息,订阅者接收消息 - - or-chan: 当多个 chan 合并成一个,关闭任意一个,关闭全部 - - - q: 为啥不同状态的channel在执行读写操作时,会阻塞或者panic呢?怎么理解呢? - - - q: Compare barrier and fan-in? - - q: select...case # random select(avoid hungry), timeout, default - - q: select for loop - - q: select, deadlock - - q: How does "select" works? # OSELECT, OCASE - - q: "***How to loop chan? Iterate over Channel in Golang***" # (for, ) - - q: 如何检查channel是否已满? - - q: 如何使用select语句在多个channel上进行连续读取? - - q: select语句如何实现超时机制? - use: - - des: 事实上,chan的使用相当简单。比如说最简单的pipeline模式吧,先定义两个chan的变量,作为in和out(也可以理解为this和next),然后写两个go func,第一个pub,第二个sub。注意两个go func里都要close chan。最后再把outChan循环处理一下就可以了。几个需要注意的地方:go func里最好 `defer close()`,而不是直接在func最后写close。其次,最需要注意的就是最后的循环,也就是“遍历 chan”,无非是普通for循环和for...select两种。肯定推荐使用for...select,可以做更多类似超时、默认、ticker等自定义操作。 - - url: https://github.com/golang/go/blob/master/src/sync/mutex.go - topic: sync.Mutex{} - qs: - - q: "***How to implement mutex in golang? mutex running mechanism?***" # (sema), critical section 临界区. mutex 底层使用 atomic 包中的 CAS 操作来保证加锁时的原子性,CAS 底层就是通过 LOCK+CMPXCHGL 汇编指令实现的 - - q: mutex 的 sema 和 state 有什么用? # mutex 对 goroutine 的阻塞操作和唤醒操作就是通过 sema 实现的,具体来说,runtime 维护了一个全局的变量 semtable,里面有全部的信号量,每个信号量都由一个变量地址指定 - - q: mutex的normal, starvation两种模式 - - q: misuses # lock/unlock not in pairs(deadlock, panic), nocopy(vet), non-reentrant(goid) - - q: Implement spinlock? # CAS+runtime.Gosched() - - q: 为啥 golang 的 mutex 不可重入呢? # 为了避免deadlock - - q: What's noCopy in golang? and why are mutex, rwmutex, wg, pool and cond all noCopy? (cuz all of these is based on ) - use: - - url: https://go.dev/play/p/lw5jSOdpRqh - des: mutex的拓展实现,TryLock(), IsLocked(), IsWoken(), IsStarving(). How to check if a mutex is locked? - sol: 其实就是提取 state 字段的中数据,state是个int32类型的数据,从0~3分别代表 mutexLocked, mutexWoken, mutexStarving, mutexWaiterShift - - url: https://gist.github.com/hxhac/3e7996df3159d6862c2e833ccd0d2120, - des: How to implement ReentrantMutex? Why mutex not support ReentrantLock in golang? - sol: 关键是获取goid。mutex 不是可重入锁,因为 mutex 的实现本身就是没有记录哪个协程持有锁,所以当然是不可重入的。所以想实现可重入锁,核心就是记录持有锁的协程。方法无非是两种,获取 goid,或者直接使用 uuid 进行标识。 - - des: "*怎么用 mutex 实现自旋锁?*" - sol: spinlock 和 TryLock 的实现很类似,都是加个了 CAS 操作 - - des: 用 mutex 实现一个带 timeout 的锁?超时直接解锁 - - - url: https://github.com/golang/go/blob/master/src/sync/rwmutex.go - topic: sync.RWMutex{} - qs: - - q: What's RWMutex? How to implement? - x: | - (readers-writers problems) rwmutex=mutex+conditional variables+sema - struct (w, writerSem, readerSem, readerCount, readerWait, rwmutexMaxReaders) - starvation - 读锁获取锁流程? 释放读锁流程? 写锁获取锁流程? 释放写锁流程? - - - - q: (read-preferring, write-preferring) - - q: Compare the perf between mutex and rwmutex in golang? # read-write ratio - - q: misuses? # similar with mutex(no-copy, non-reentrant) - - - url: https://github.com/golang/go/blob/master/src/sync/waitgroup.go - topic: sync.WaitGroup{} - qs: - - q: What's wg? How to implement wg? # (state1(counter, waiter, sema), noCopy), align64. 64bit(8bytes) 的值分成两段,高 32bit 是计数值,低 32bit 是 waiter 的计数 - - q: How to implement (Add/Done/Wait)? # Done() similar with Add() - - q: Add、Done 和 Wait 三个方法的具体实现?(自己看源码) - - q: WaitGroup 内部怎么实现无锁操作?(自己看源码) - - topic: interface - qs: - - q: How to implement interface in golang? (eface, iface) - x: | - eface就是empty interface, iface则相反. type内置了各种数据结构, data指针。这两个结合之后,其实很类似string的数据结构。iface的数据结构也很类似,区别在于itab,itab是把eface的type又包了一层。 - - - type 接口自身的元信息 - - hash _type里也有一个同样的hash,此处多放一个是为了方便运行接口断言 - - fun 函数指针,指向具体类型所实现的方法 - - topic: defer - qs: - - q: When to use? # Delayed call, LIFO, recover panic, close(file, conn, mutex, chan, goroutine...) - - q: defer Close(), EIO. How to avoid? - - topic: golang http pkg - url: https://github.com/golang/go/blob/master/src/net/http/client.go - use: - - url: https://mp.weixin.qq.com/s?__biz=MzkyOTU5MTc3NQ==&mid=2247499280&idx=2&sn=5437a3549daef00178845766519a4261 - des: 使用golang的HTTP请求时,怎么正确地给每个长连接请求设置timeout?, 应该加在http.Client的Timeout中,而不是http.Transport中 - - url: https://github.com/golang/go/tree/master/src/html/template - topic: html/template - use: - - url: https://go.dev/play/p/d8kzvdR5kjy - des: html/template用法 - - url: https://github.com/x1ah/gena/blob/master/generators/webstack.go#L19 - des: golang中渲染html的方法,用template而不是自己手动渲染html - - url: https://github.com/golang/go/tree/master/src/reflect - topic: reflect - - - url: https://github.com/golang/go/blob/master/src/sync/once.go - topic: sync.Once{} - qs: - - q: usage scenarios # (delay init(lazy loading) in construct) - - q: implement # atomic(CAS, preliminary check) + Double-checked locking, singleton - - q: sync.Once 是如何保证只执行一次的语义的? # sync.Once 使用内部的 Mutex 来保证并发安全。它首先尝试通过原子操作检查 done 标志是否为 0,如果是,则进入慢路径(slow path),在慢路径中,它会加锁并再次检查 done 标志。如果仍然为 0,则执行函数并设置 done 标志为 1。这个过程中使用 defer 来确保即使函数执行过程中发生 panic,done 标志也能被正确设置。 - - q: 为什么 sync.Once 的 Do 方法中没有使用 CAS 原子判断? # 使用 CAS 原子判断虽然看似能提高性能,但它无法保证在 o.done 变为 1 时,传入的函数 f 已经完全执行。sync.Once 不仅要保证只执行一次,还要保证其他 goroutine 在 Once.Do 返回时,f 函数的执行已经完成。 - - q: sync.Once 的使用场景有哪些? # sync.Once 适用于需要延迟加载或单次初始化的场景,例如加载配置、初始化日志系统、创建单例对象等。它可以确保即使在高并发环境下,这些操作也只被执行一次,从而避免资源浪费和潜在的竞态条件。 - - url: https://github.com/golang/go/blob/master/src/sync/pool.go - topic: sync.Pool{} - qs: - - q: sync.Pool 实现原理? # (lock-free) (local+victim) *保存和复用临时对象,减少内存分配,降低 GC 压力*,但是这些对象会被 GC 定期清除,所以不要用来存数据库连接之类的长连接,*sync.Pool 最常用的场景就是 buffer 池*(缓冲池)(因为 byte slice 是经常被创建和销毁的一类对象,使用 buffer 池可以缓存已经创建的 byte slice)。Pool 使用两层回收策略 (local+victim) 避免性能波动。 - - q: sync.Pool 是怎么实现 thread-safe 的? # (temp data, GC, buffer pool) Pool 本身就是线程安全的 (可以并发地调用它的方法存取对象),并且是lock-free的,因为给每个 P 都分配 cache 数组,这样 cache 结构就不会有并发安全问题 - - q: How to use it? - - q: misuses? - - q: sync.Pool 内存池的内容会被清理吗?清理会造成数据丢失吗? - - q: 只 Get 不 Put 会造成内存泄漏吗? - - topic: sync.Cond - des: 从开发实践上,我们真正使用 Cond 的场景比较少。因为一旦遇到需要使用 Cond 的场景,我们更多地会使用 chan 的方式去实现 wait/notify 机制,因为那才是更地道的 golang 的写法。对于简单的 wait/notify 场景,比如等待一组 goroutine 完成之后继续执行余下代码,我们会使用 waitgroup 实现,使用简单还不容易出错。 - - - url: https://github.com/golang/go/tree/master/src/log/slog - topic: slog - des: log相比于slog没有日志分级、没有结构化日志、没有拓展性 - use: - - url: https://colobu.com/2024/03/10/slog-the-ultimate-guide/ - - url: https://gist.github.com/hxhac/d39d47d2f967884ff09856273ef45820 - - - url: https://github.com/golang/go/tree/master/src/net/http/httptrace - topic: golang httptrace pkg. - - - url: https://github.com/golang/go/tree/master/src/regexp - topic: golang regex - use: - - url: https://go.dev/play/p/LUH7Ib-QvqY, - des: regexp - - url: https://github.com/1jz/wisa/blob/master/wisa.go, - des: wisa对regexp的使用,MustCompile() - - url: https://pkg.go.dev/encoding/json - topic: encoding/json - use: - - url: https://go.dev/play/p/-J16F7AmMXO - des: json反序列化时 - - url: https://go.dev/play/p/DjDLYB8ES5n - des: JSON pointer - - url: https://gist.github.com/hxhac/0e7a917e8b07c9f6f5529d62fa4e80f7 - des: JSON handle - - des: Golang 中使用 JSON 时如何区分空字段和未设置字段?具体来说,struct tag 如果设置为omitempty执行update操作时会把该field设置为空字符串,导致出错,怎么避免该问题?如果给该field赋值恰好等于默认空值的话,Marshal后为nil,又怎么解决该问题? # 给该field加指针类型 - - # [[转]Golang 中使用 JSON 的小技巧](https://colobu.com/2017/06/21/json-tricks-in-Go/) - - des: 怎么临时忽略struct空字段,忽略指定field,或者临时添加额外的字段,一个json切分成两个struct,临时改名struct的字段,又或者临时粘合两个struct? - - des: 用字符串传递数字 - - des: 用jsoniter 模糊模式实现容忍字符串和数字互转,或者容忍空数组作为对象? - - des: json 数字精度丢失问题 - - des: json 包的时间格式问题 - - des: Precision is lost when deserializing json in golang, How to resolve? - - des: How to convert between struct, map and json in golang? - # - 使用 MarshalJSON支持time.Time - # - 使用 RegisterTypeEncoder支持time.Time - # - 使用 MarshalText支持非字符串作为key的map - # - 使用 json.RawMessage - # - 使用 json.Number - # - 使用 jsoniter 统一更改字段的命名风格 - # - 使用私有的field - - - - topic: golang net pkg. - url: https://github.com/golang/go/blob/master/src/runtime/netpoll.go - qs: - - q: golang的网络模型?存在什么问题?netpoll和gnet做了什么优化? - - url: https://github.com/golang/go/tree/master/src/testing - topic: golang test - des: 其中包括了对benchmark和fuzz的实现 - qs: - # test - - q: gotest # testdata, table-driven, Tags - - q: 四种测试函数?注意事项? - - q: Which unittest lib should we use? # gotest, testify, goconvey - - q: testdata, .input, .golden - - q: 如果需要测试辅助函数 (无状态函数), 就用`testify`进行`table driven`测试。如果需要测试业务逻辑,就用`goconvey`, 更有层次感。 - # benchmark - - q: benchmark, metrics - - q: benchmark 有哪些注意事项? # b.ResetTimer(), b.StopTimer(), b.StartTimer() - - q: 有哪些常用方法? # b.ReportAllocs(), b.SetBytes() - - q: benchmark 的返回参数都是啥意思? - # fuzz - use: - - des: 如何重复执行 gotest?怎么重复执行某个或者某组测试用例? # Don't use build tags for integration tests. use env replaced with build tags in golang test 不够显式 - - des: go test 如何禁用缓存? # 使用 -count=1 flag 禁用,不要GOCACHE=off,否则会影响 go.mod - - - topic: filepath - url: https://github.com/golang/go/tree/master/src/path/filepath - des: Use filepath.Walk() instead of for...range folders, `path` equals to `filename := dir + sep + fi.Name()` - - topic: golang errors pkg. - url: https://github.com/golang/go/tree/master/src/errors - qs: - - q: "***处理 golang Error?***" - x: 首先要分清楚Error, Exception和panic。go 源代码很多地方写 panic, 但是工程实践业务代码不要主动写 panic,理论上 panic 只存在于 server 启动阶段,比如 config 文件解析失败,端口监听失败等等,所有业务逻辑禁止主动 panic,所有异步的 goroutine 都要用 recover 去兜底处理。 - - q: 写一堆 `err != nil` 的问题 # 自定义错误记得要实现 error 接口 - - q: 怎么 wrapping 多个 errors? - - q: 操作数据库时,比如 dao 层中遇到一个 sql.ErrNoRows 时,是否应该 wrap 这个 error,抛给上层;为什么?应该怎么做?请写出代码 - x: 总结一下,错误处理的原则就是:错误只在逻辑的最外层处理一次,底层只返回错误。底层除了返回错误外,要对原始错误进行包装,增加错误信息、调用栈等这些有利于排查的上下文信息。 - - q: golang的哨兵错误、自定义错误以及隐式错误三种 - x: ??? - - use: - - des: errors.Join()使用场景 # 比如说对并发task的error的统一收集,类似ErrorGroup - - des: # 如果需要格式化错误,*应该用`fmt.Errorf(...)`代替`errors.New(fmt.Sprintf(...))`*;如果不需要格式化错误,直接`errors.New()`即可. - - des: golang中用errors.New(), errors.Is() 怎么判断err是否相同? # 需要注意 - - des: 不要直接return err,应该使用fmt.Errorf()自定义error,自己封装一个newError - url: https://akavel.com/go-errors - - - topic: slog - doc: https://colobu.com/2024/03/10/slog-the-ultimate-guide/ - - - topic: golang generics - qs: - - q: 类型参数 (类型形参param 和类型实参arg) - - q: 类型集 Type Set - - q: 类型union - - q: 泛型receiver - - q: What does the tilde ~ do? (~T) # 表示所有底层类型是 T 的类型,比如~string表示所有底层类型是 string 的类型集合。后面只能是基本类型。 - - q: 约束类型推断 - - q: generics是否有性能问题? - cmd: - - c: go get -u - x: 更新项目依赖到最新版本 - - c: go clean -modcache - x: 清除模块缓存 - - c: go build -gcflags '-m -l' main.go - x: 使用 go build -gcflags='-m=2' 查看编译器报告,来查看是否发生了内存逃逸。(-m 最大为 4,通常使用 2,否则返回信息太多) - - c: go test ./... - x: 运行当前文件夹下的所有 case - - c: go test foo/... - x: 指定目录下的所有 case - - c: go test foo... - x: 指定前缀的所有 case - - c: go test ... - x: 运行 GOPATH 下的所有 case ⚠️ - - c: go test -cover - x: 代码覆盖率 - - c: go test -covermode=set - x: 覆盖测试模式,有三种值 set,count,atomic, 其中 set 代表的是这个语句运行吗?count 代表的是这个语句执行多少次,atomic 代表的是多线程正确使用的,耗资源的。 - - c: go test -v -coverprofile=c.out && go tool cover -html=c.out -o=tag.html - x: 生成测试覆盖率报告,并转化为 html 文件进行预览 - - c: go test -bench=. - x: 基准测试 - - c: go test -benchtime=3s -bench=. - x: 在持续时间 3s 内运行每个基准测试 - - c: go test -benchmem -bench=. - x: 打印基准测试时的内存分配 - - c: go test -count=2 -bench=. - x: 执行指定次数的基准测试,在 - count=1 时相当于禁用缓存 - - c: go test -cpu=1 -bench=. - x: 设置指定的 cpu 数量来进行基准测试,可以指定多个不同的 cpu 个数列别,比如:-cpu=1,2,4 - - c: go test -timeout=3s - x: 默认情况下,测试执行超过 10 分钟就会超时而退出,我们可以通过这个时间指定超时时间 - - c: go test -parallel=2 - x: 当测试使用 t.Parallel () 方法将测试转为并发时,将受到最大并发数的限制,默认情况下最多有 GOMAXPROCS 个测试并发,其他的测试只能阻塞等待,这个可以用来并发安全的测试。 - - c: go test -v -cpuprofile=cpuprof.out - x: 生成 cpuprof 的文件 - - url: https://github.com/golang/sync - des: singleflight, ErrorGroup, Sema, Sync.Map - qs: - - q: What's ErrorGroup? When to use? How to use ErrorGroup? # timeout control, error return - - q: misuses? # defer, for(block), - - q: 什么是 ErrorGroup?怎么使用?实现原理? - - q: singleflight is used to prevent multi goroutines from doing the same thing simultaneously and repeatedly. - use: - - url: https://go.dev/play/p/A5vj4Pe-CQ8 - des: CyclicBarrier. CyclicBarrier是一种同步原语,它允许一组线程在某个临界点处等待,直到所有线程都达到该点,然后同时继续执行。与Barrier不同的是,CyclicBarrier在每个线程到达临界点后会自动重置,可以重复使用。 - - url: https://github.com/golang/mod - - url: https://github.com/golang/mobile - - url: https://github.com/golang/term - - url: https://github.com/golang/exp - - url: https://github.com/golang/sys - - url: https://github.com/golang/text - - url: https://github.com/golang/crypto - des: 主要使用场景就是用来存用户密码,md5(pwd+salt)这种传统方案已经被证明安全性非常差,不同于md5的方案,bcrypt.GenerateFromPassword每次生成的秘串都不同。既然每次生成的秘串都不同,怎么知道密码是否正确呢?使用bcrypt.CompareHashAndPassword - - url: https://github.com/golang/net - - url: https://github.com/golang/tools - - - -#- golang os pkg # https://blog.51cto.com/u_15289640/5840461 -#- golang time pkg. time.Since() -#- golang builtin functions, clear(), min(), max() -#- golang io.FS. How to embed FS? -## [超全总结:Go 语言如何操作文件](https://mp.weixin.qq.com/s?__biz=MzUxMDI4MDc1NA==&mid=2247496305&idx=2&sn=8f3d13db24875c13fef12862b885f570) -#- Higher-order function # 就是把func作为入参或者出参 -# -## comma-ok, options, builder, private-struct(avoid call), Callback as param -#- des: How to use "Builder Pattern"? -#- des: How to use "Functional Options Pattern"? -# -#- des: type func的写法 -# url: https://github.com/jorgelbg/pinentry-touchid/blob/main/main.go -#- des: 把func作为参数的写法 -# url: https://github.com/91go/docs-training/blob/main/cmd/all.go -# des: 我的 actions() 和 batch() 都需要复用 Xz(),只有 ExtractQuestion() 需要替代,所以就把 func() 作为参数使用 -#- des: LOOP, time -# url: https://go.dev/play/p/tl2-QGEbkv9 -# -#- des: chan -# url: https://gist.github.com/hxhac/350b22095801614111c3fe8485b87e5e -#- des: context -# url: https://go.dev/play/p/zCXAJiROScH -# -#- des: xxx -# url: https://go.dev/play/p/VO7T6abmODn -#- des: struct搭配generics的写法 -# url: https://github.com/Edouard127/reddit-placebot-2023/blob/master/web/websocket.go -#- des: xxxx -# url: https://github.com/solana-labs/token-list/blob/main/automerge/automerge.go#L79 -# des: 写得不错 -# -#- des: 数组 -# url: https://go.dev/play/p/pGBrqP9DGn- -#- des: time.Ticker time的打点器Ticker和定时器Timer -# url: https://go.dev/play/p/tKkj6mebb-f -#- 两个整数相除,为什么不返回 float?怎么得到 float? # 用 fmt.Sprintf("%.2f", a/b) 返回 float - -# [Go Playground - The Go Programming Language](https://go.dev/play/p/ZUnQAvquU67) - -# [html.NewTokenizer()](https://gist.github.com/hxhac/e2b7ecf5974f2fd591e9c40c9d4d1d3c) - -# [Go Playground - The Go Programming Language](https://go.dev/play/p/SCC82s2JyuU?v=) - -# [rsa](https://gist.github.com/hxhac/dc94137af2127d11fad5f08f44e1b22c) - - -# [一些常用的enum](https://gist.github.com/hxhac/17b67e09ca05c808a4bdeb8b34b2bfb9) - -# [创建高并发场景下订单号](https://gist.github.com/hxhac/4a9de86688fb2d596c4db27dfa7f4d8a) - -# [GetFilesOfFolder](https://gist.github.com/hxhac/8aff5f69d117d305c7df58b04ef33d8a) - -# [GetURL](https://gist.github.com/hxhac/a3e71019b0b8206a1953b7c1d1581295) - -# [GetFilesOfFolder](https://gist.github.com/hxhac/8aff5f69d117d305c7df58b04ef33d8a) - -# [dijkstra](https://gist.github.com/hxhac/8f31ab4703098d1768ac4818c2c72279) - -# [sync.Map + generics](https://go.dev/play/p/ij-ZL3bo17v) - -# [用Bitmap与AST做一个配置化时长系统](https://gist.github.com/hxhac/67e6066dc1e9dcd404ef3fba6f4c22cd) - - -# [mkmik/syncpool: generic sync.Pool](https://github.com/mkmik/syncpool) generics sync.Pool - - -# [generics](https://gist.github.com/hxhac/98ec5811f97969b7667da52c3357ed20) - -# [interface+struct](https://gist.github.com/hxhac/fddd94f0a85410ff01f0cf93b5cfa396) - -# [golang channel barrier usage](https://gist.github.com/hxhac/6e40ad06d80bbd8d74f0792688a9cf7b) -# -# [Go Playground - The Go Programming Language](https://go.dev/play/p/V2i7oeEE071) -# -# -# [Go Playground - The Go Programming Language](https://go.dev/play/p/b5PZoRzZPfS?v=) -# -# [channel fanout](https://gist.github.com/hxhac/96706d2e07ea6680695636a868db7950) -# -# [sync.code usage](https://gist.github.com/hxhac/8b9c7e42d9f3cfb67f6cbd50b4c10b86) -# -# [for...select and exit goroutine usage](https://gist.github.com/hxhac/d9d391a6ce36c4964c832835aec761eb) - - -# [Go Playground - The Go Programming Language](https://go.dev/play/p/DjDLYB8ES5n) - -# [io teeReader](https://gist.github.com/hxhac/c3a9e47c79a82b74e062af0d794e167b) - -# [sync map](https://gist.github.com/hxhac/0f8b39b10b790b6c00b788d869493d4c) - -# https://github.com/Wowo10/RetryWorkerPool - -# [CARP hash](https://gist.github.com/hxhac/29b87f876a3e9df4eaa3304445d8e4e7) - -# [lock-free using atomic](https://gist.github.com/hxhac/df52327e6badac2f8f4e74663b537c91) - -# [worker pool](https://gist.github.com/hxhac/ace505f5ce8d8be5338e2c70dc5bbc1a) - - -# [for循环时的变量问题](https://gist.github.com/hxhac/e9449acb4abc65cb620e0928c1d5fc7b) - - - -# [Go:用规则引擎让你一天上线十个需求](https://mp.weixin.qq.com/s?__biz=MzAxMTA4Njc0OQ==&mid=2651451957&idx=2&sn=1c8892b83cc5641e5e90856c9eb5bf5f) -- type: Rules-Engine - repo: - - url: https://github.com/Knetic/govaluate - des: 类似 Drools或者Activiti那样的规则引擎,但是17年之后就EOL了。有很多针对性优化的repo可供挑选。 - - url: https://github.com/casbin/govaluate - - url: https://github.com/nwkl-home/govaluate - - -- type: pprof - repo: - - url: https://github.com/google/pprof - cmd: - - c: pprof top10 -cum - - c: pprof web - - c: pprof web mapaccess1 - - c: pprof web mallocgc - - c: pprof list DFS - - c: pprof list FindLoops - qs: - - q: pprof 的各项参数 - - q: 怎么用pprof快速定位内存泄漏的代码? - - q: pprof 指标 metrics ((profile(CPU), heap), allocs, threadcreate, goroutine, block, mutex) # profile(CPU profile), heap, (allocs, block, goroutine, mutex, , threadcreate) - - q: "***pprof 的运行原理?***" - - q: pprof 应该监控 RSS、PSS 和 USS 中的哪个内存指标? - - q: 内存怎么采样?pprof是怎么实现内存分析的? - - url: https://github.com/grafana/pyroscope - des: Used to achieve continuous profiling - - url: https://github.com/grafana/pyroscope-go - des: pyroscope client in golang, Better than holmes - - url: https://github.com/mosn/holmes - des: 类似pyroscope,也是“自动采样工具” - - url: https://github.com/smallnest/zhuge - des: 搭配pyroscope使用,在程序CPU、内存等异常的情况下,自动生成Profile并提交到Profiler以便分析。 - - url: https://github.com/arl/statsviz - des: | - 功能与pprof类似,metrics也相同,也都需要添加route,都有侵入性,但是使用环境不同,为啥呢? - 本质上来说是因为pprof需要打开开关才开始采集metrics,而statsviz则默认采集。所以相应的,statsviz的性能开销更大,就不适合生产环境。 - - 想要持续收集golang的runtime,也可以通过Grafana,Graphite,Statsd等组件来采用UDP协议采集metrics上报到Grafana来进行一系列的展示,但是这种方案的成本比statsviz更高。 - - - - url: https://github.com/parca-dev/parca - des: 非常好用,Parca 是一个利用 eBPF 技术进行高效、低开销的性能分析工具,同时它与 pprof 格式兼容,使得它可以轻松集成到现有的性能分析工作流程中。并且相比于pprof等工具,parca 可以自动发现运行在 k8s 或 systemd 环境中的所有目标,也就是说parca是非侵入式的。并且内置了Web UI以及storage机制。metrics和pprof相差不大,也都是CPU, memory, IO之类的。 - - url: https://github.com/dominikh/gotraceui - use: - - url: https://colobu.com/2024/03/18/execution-traces-2024/ - des: flight recording - -#go install golang.org/x/tools/cmd/goimports@latest -#go install golang.org/x/tools/cmd/stringer@latest -- type: golang-Cli-Tools - repo: - - url: https://github.com/cortesi/modd - des: | - Pretty Useful. - go install github.com/cortesi/modd/cmd/modd@latest. - 支持通过监听文件系统的变化来自动重启服务,这在快速迭代和频繁更改代码时非常有用 - 不仅是pm2, supervisor或者forever这样的process manager,还支持类似 - - modd强制使用conf格式作为配置文件,非常蠢 - - - url: https://github.com/cosmtrek/air - - url: https://github.com/go-eagle/eagle - des: go install github.com/go-eagle/eagle/cmd/eagle@latest - - url: https://github.com/uber-go/nilaway - key: true - des: 用来在编译时捕获nil,来规避生产环境出现nil panic问题。确实非常实用,帮我避免了很多坑。 - - url: https://github.com/dkorunic/betteralign - key: true - des: | - Another filedalignment Tool. 相比于filedalignment,不会去修改各种 xxx_gen.go 以及 xxx_test.go 代码 - go install github.com/dkorunic/betteralign/cmd/betteralign@latest - - -- type: SDK - repo: - - url: https://github.com/go-pay/gopay - des: 微信、支付宝、通联支付、拉卡拉、PayPal、Apple 的Go版本SDK。【极简、易用的聚合支付SDK】 - - url: https://github.com/silenceper/wechat - - url: https://github.com/wechatpay-apiv3/wechatpay-go - des: 微信支付 - - url: https://github.com/royalrick/weapp - des: 微信小程序 - - -- type: feeds - repo: - - url: https://github.com/mmcdole/gofeed - des: parse rss - - url: https://github.com/gorilla/feeds - des: generate rss - - - - - -- type: golang-unittest - repo: - # [你该刷新gomonkey的惯用法了](https://mp.weixin.qq.com/s?__biz=MzI4NDM0MzIyMg==&mid=2247490825&idx=1&sn=ea12de64c3aee953820174dc1e8fb1d4) - - url: https://github.com/agiledragon/gomonkey - des: Similar tools include mockery, testify-mock, gostub. But gomonkey not suppport interface, just support func and struct. - - - url: https://github.com/brianvoe/gofakeit - des: 随机数据生成器。目前,它提供了160多个函数,涵盖少数不同的主题/类别,如Person、 Animals、 Address、 Games、 Cars、 Beers等等。这里的关键词是随机。 - - url: https://github.com/johannesboyne/gofakes3 - des: A simple fake AWS S3 object storage (used for local test-runs against AWS S3 APIs) - - - url: https://github.com/stretchr/testify - des: 某种gotest的替代品,但是没啥必要 - - url: https://github.com/go-testfixtures/testfixtures - des: 用来模拟数据库进行测试的工具,把样本数据保存在fixtures文件中。在执行每个测试之前,测试数据库都会被清理并将fixture数据加载到数据库中。 - - url: https://github.com/testcontainers/testcontainers-go - des: 用来在测试中启动Docker容器,主要用于自动化集成/冒烟测试中。Testcontainers支持各种数据库、消息代理和其他服务,以便在测试中模拟外部依赖项。 - - url: https://github.com/xhd2015/xgo - des: 非常好用的golang单测工具,xgo提供了一个全功能的Golang测试工具集,包括 Mock, Trace, Trap和增量覆盖率 - - url: https://github.com/maxatome/go-testdeep - des: ??? - - url: https://github.com/orlangure/gnomock - des: ??? - - url: https://github.com/mfridman/tparse - des: CLI tool for summarizing go test output. Pipe friendly. CI/CD friendly. - - url: https://github.com/onsi/ginkgo - des: ginkgo 是 BDD 开发模式工具,测试框架,没用 - - url: https://github.com/traefik/mocktail - - url: https://github.com/smartystreets/goconvey - - url: https://github.com/dvyukov/go-fuzz - - url: https://github.com/quasilyte/qbenchstat - des: Better benchstat. Support "Colored output" and "significance test". - - url: https://github.com/axw/gocov - des: 感觉没啥用,类似goconvey之类的工具都内置类似 "coverage reporting tool" 了 - - url: https://github.com/pingcap/failpoint - doc: https://www.luozhiyun.com/archives/595 - des: 相当于代码级别的chaos,支持在代码中精确地指定故障注入点,比chaos粒度更细 - - url: https://github.com/chaosblade-io/chaosblade - - url: https://github.com/chaos-mesh/chaos-mesh - - url: https://github.com/Netflix/chaosmonkey - - # [选择合适的测试框架 - MySpace](https://www.hitzhangjie.pro/blog/2020-08-19-go%E5%BC%80%E5%8F%91%E5%A6%82%E4%BD%95%E5%81%9A%E6%B5%8B%E8%AF%95%E9%80%89%E6%8B%A9%E5%90%88%E9%80%82%E7%9A%84%E6%B5%8B%E8%AF%95%E6%A1%86%E6%9E%B6/) - - url: https://github.com/go-redis/redismock - des: redis mock - - url: https://github.com/tokopedia/gripmock - des: gRPC mock - - url: https://github.com/DATA-DOG/go-sqlmock - des: go-mysql-driver mock # [[Go] 使用 go-sqlmock 模拟数据库驱动编写单元测试用例 - piaohua's blog](https://piaohua.github.io/post/golang/20220813-go-sqlmock/) - - url: https://github.com/h2non/gock - des: 用来模拟 HTTP 请求的工具,在我们写单元测试时,经常会遇到一些逻辑是需要请求别人的接口的场景,而我们无法完美模拟这些接口所需要的参数。这个时候就需要一个工具,当我们请求一些第三方接口时拦截请求,并返回我们的预设的返回值.比`httpexpect` 和 `httpmock`好用很多,推荐使用. - - url: https://github.com/gavv/httpexpect - des: Really? Let's try it out. - - url: https://github.com/jarcoal/httpmock - - url: https://github.com/uber-go/mock - des: gomock, mockgen, fork from golang/mock(EOL). ***使用 gomock 来做接口 mock,不要使用 testify-mock/mockery/gomonkey, 都不好用***. mock 不是用来处理简单的无状态函数,其应用场景主要在于处理不可控的第三方服务、数据库、磁盘读写等。如果这些服务的调用细节已经被封装到 interface 内部,调用方只看到了 interface 定义的一组方法,那么在测试中 mocks 就能控制第三方服务返回任意期望的结果,进而实现对调用方逻辑的全方位测试。 - - url: https://github.com/ory/dockertest - des: Dockertest helps you boot up ephermal docker images for your Go tests with minimal work. Ephemeral images and containers. 具体来说,通常用来模拟数据库,但是与sqlmock或者redismock不同的是,dockertest需要启动docker容器,所以相应的,开销更高,也不易集成到CI中,但是可以模拟更真实的场景,使用数据库的所有feats,也能发现更多bug - - - - -- type: network - repo: - - url: https://github.com/panjf2000/gnet - des: 高性能、轻量级、非阻塞的事件驱动 Go 网络框架 - - url: https://github.com/gnet-io/gnet-examples - - url: https://github.com/cloudwego/netpoll - des: 专注于RPC场景的network库,这是netpoll和gnet, evio的最大区别。字节自家的Kitex和Hertz都是用了netpoll - qs: - - q: netpoll为啥性能很好? - x: netpoll 底层基于 epoll, kqueue, iocp 这些 IO 多路复用技术来做封装,又借助runtime-scheduler对协程的高效调度,从而在通用性和性能上都足够满足绝大部分的应用场景 - - q: netpoll 有哪些问题?netpoll 为啥没有惊群问题吗? - x: 没有惊群问题,netpoll 用 sync.Once 保证只初始化一次 epoll 实例 (也就是一个 listener 支持有一个 epoll 实例来管理网络连接),既然只有一个 epoll 实例,也就不存在`惊群问题`了 - - q: netpoll 和 gnet 这种基于 Reactor 模型的网络库有什么区别?(为什么 gnet 会比 golang 原生的 net 包更快?) - - - - -- type: Markdown - repo: - - url: https://github.com/yuin/goldmark - des: Markdown Render. Most leading markdown-about service uses goldmark as markdown render service, rather than blackfriday. - - url: https://github.com/JohannesKaufmann/html-to-markdown - des: Used to convert HTML to markdown - - url: https://github.com/alecthomas/chroma - des: 可以理解为golang生态下的prism或者shiki。hugo, gitlab, sourcegraph all use chroma to achieve syntax highlighting. 除了上述应用,chroma还可以用在IDE语法高亮、各种blog的Code Block语法高亮、命令行工具的语法高亮中使用。 - - url: https://github.com/mattn/godown - des: Convert HTML into Markdown - - url: https://github.com/hibbitts-design/docsify-this - des: markdown viewer online platform github actions. 用来直接在线预览markdown文档,支持TOC,非常好用 - - url: https://github.com/hedgedoc/hedgedoc - des: 在线共享的markdown平台,相当于腾讯文档或者google docs - - url: https://github.com/pandao/editor.md - - - - -- type: ORM - repo: - - url: https://github.com/go-gorm/gorm - doc: https://gorm.io/ - des: orm, better than xorm or sqlx, support for mysql, pgsql and sqlite. - qs: - - q: gorm 多对多关系的多表联查怎么搞? - - q: golang 里 tinyint(1) 和 bool 的问题 # 建议用 tinyint(3),status 两种,1 和 2 - - q: gorm 的 update的坑? 如果参数类型为struct,则gorm默认不更新struct里的“零值字段” - - q: 结构体查询时int类型的0值问题 # 当进行整个结构体查询时 gorm会默认把没有设置的值为0 所以无法进行查询 gorm只能进行非零字段查询。(不推荐结构体查询)目前的解决方法是: 当要进行结构体查询时将结构体中的int改为指针int类型 - - q: gorm哪些查询语法无法避免sql注入? - - q: 自动生成uuid或者时间戳 # gorm:"type:uuid;primaryKey;default:gen_random_uuid()" 这种tag只有 DB.Create(&agent) 才能自动生成,直接insert不支持 - # [Using mysql in Go - creating pool of connection. Is it really needed? : golang](https://www.reddit.com/r/golang/comments/18g211c/using_mysql_in_go_creating_pool_of_connection_is/) no need to config connection-pool, but we need to - # db.SetMaxOpenConns(25) - - url: https://github.com/go-sql-driver/mysql - des: mysql driver for golang - qs: - - q: 怎么解决go-sql-driver读取timestamp时间戳时会出现错误的问题? - x: 需要在go-sql-driver的dsn中标明loc,否则默认使用UTC - d: https://mp.weixin.qq.com/s?__biz=MzAxMTA4Njc0OQ==&mid=2651453861&idx=1&sn=63b98cb5154a9b46f898e561b112bd8f - - url: https://github.com/gohouse/gorose - des: 支持 mysql、postgres、sqlite、mssql、oracle,类似laravel的Eloquent,但是性能不如gorm - - url: https://github.com/jmoiron/sqlx - des: sqlx - - url: https://github.com/go-mysql-org/go-mysql - des: MySQL协议解析库,专注于底层的协议解析和处理,可用于构建MySQL客户端程序、代理或实时读取binlog等应用。。而不是MySQL Client。应该说,可以使用这个pkg来实现MySQL Client。 - - url: https://github.com/jackc/pgx - - url: https://github.com/uptrace/bun - des: SQL-first Golang ORM - - url: https://github.com/tidwall/buntdb - des: kvdb, 支持 ACID、并发读、自定义索引和空间信息数据, 只用一个golang文件就实现了以上功能,是用来学习数据库开发的好 - - url: https://github.com/nutsdb/nutsdb - des: 类似buntdb,但是支持List、Set、Sorted Set这些数据结构。 - - url: https://github.com/Snapchat/KeyDB - des: KeyDB is a multi-threaded fork of Redis, meaning it is fully compatible with the Redis protocol, changes and modules while promising to stay aligned with the upstream changes Redis will be doing in the future. - - url: https://github.com/dolthub/go-mysql-server - - url: https://github.com/prisma/prisma - des: 我用不到. ORM for Node.js & TypeScript. Support pgsql, mysql, MariaDB, SQLite, MongoDB. - - url: https://github.com/steebchen/prisma-client-go - des: ??? 相当于prisma的golang client, 其实就是个ORM嘛,类似gorm之类的 - - - -- type: ms-framework - repo: - - url: https://github.com/go-micro/go-micro - des: 内置的身份验证和数据存储设计。一个轻量级的微服务框架,做为一个在 2015 年就开源的项目,在当时那个市面上开源的微服务框架稀少的年代,它是为数不多的选择。主要槽点就是作者重心做云服务去啦,相应的社区维护力度较弱。 - - url: https://github.com/go-kratos/kratos - des: 一个轻量级的微服务框架,B 站开源项目;web 和 rpc 服务的 DSL 协议直接采用 protobuf 和 grpc 进行定义,采用 wire 做依赖注入、自动生成代码。框架定位于解决微服务的核心诉求。社区建设:社区建设和维护上,算是做的中规中矩,官网更新一般,有公众号和微信群问题解答。 - - url: https://github.com/TarsCloud/TarsGo - des: tarsgo 做为 tars 这个大的 C++ 重量级微服务框架下的 go 语言服务框架,腾讯开源项目;对于有个好爹的这个事情,总是喜忧参半的;好处在于很多能力不用从头开始做起,直接依托母体;劣势就是独立性相对较差,要选用这个 tarsgo 的前提,就是要先选用 tars 这个大的框架。社区建设:Tars 已经是 linux 基础会项目,社群上做的还算可以,毕竟 tars 作为腾讯开源影响力最大的项目之一,有 QQ、微信群。 - - url: https://github.com/apache/dubbo-go - des: dubbogo 做为 dubbo 这个大的 Java 重量级微服务框架下的 go 语言服务框架,阿里开源项目;优劣基本跟 tarsgo 一样。 - - url: https://github.com/go-kit/kit - des: go-kit 从严格意义上来说,并不能做为一个微服务框架,而应该是一个微服务的工具集,其官方定义上也是这么说,提供各种选项让你自由选择。做为一个在 2015 年就开源的项目,也是当时很多 go 项目为数不多的选择之一。 - - url: https://github.com/douyu/jupiter - des: jupiter 做为一个重量级的微服务框架,斗鱼开源项目;整体思路上跟 tars 和 dubbo 力图提供一个大一统的框架,更确切的说是一个微服务平台,也带类似 tars 和 dubbo 那样的管理控制台,提供各种控制和 metric 的继承,这也无形中给选用此框架带来了不少代价,tars 和 dubbo 本身是有历史沉淀和大厂背景的,很多腾讯系、阿里系公司会采用。 - - url: https://github.com/tx7do/kratos-transport - des: kratos生态,把消息队列、任务队列,以及Websocket、HTTP3等网络协议实现为微服务框架 Kratos 的transport.Server。在使用的时候,可以调用kratos.Server()方法,将之注册成为一个Server。 - des: golang的各种微服务框架比如gozero, gomicro, kratos, gokit, gizmo, kite, go-chassis, ego, eagle - - - - - - - -- type: gozero - md: true - repo: - - url: https://github.com/zeromicro/go-zero - key: true - des: go-zero 整体上做为一个稍重的微服务框架,提供了微服务框架需要具备的通用能力,同时也只带一部分的强约束,例如针对 web 和 rpc 服务需要按照其定义的 DSL 的协议格式进行定义,日志配置、服务配置、apm 配置等都要按照框架定义的最佳实践来走。 - doc: https://go-zero.dev/docs/tasks - cmd: - - c: goctl api new - x: 用这个命令生成的项目结构 - - c: goctl api go -api *.api -dir . --style=goZero - - c: goctl rpc protoc *.proto --go_out=../ --go-rpc_out=../ -zrpc_out=../ --style=goZero - - c: goctl model mysql - - c: goctl model mysql datasource - - c: goctl model mysql ddl - x: goctl model mysql ddl -src blog.sql -dir ./model - - c: goctl model mysql ddl -src user.sql -dir ./users -c - x: 用来生成model层的CURD代码 - qs: - - q: gozero 的使用场景?以及各个场景下的优势 - - q: 介绍 core 中好用的组件,比如 timingwheel 等 - - q: 怎么快速增加一种 rpc 协议支持,将跨机发现改为本机节点,并关闭复杂 filter 和负载均衡功能? - - q: 日志和监控和链路追踪的设计和实现思路? - - q: gozero 在 api 的 middleware 与 rpc 的 interceptor的tracing是怎么实现的? jaeger - - q: go-zero 有哪些池化技术? - - q: go-zero 用到了哪些性能测试框架? - - q: gozero 怎么实现自动管理缓存? - - q: gozero 的自适应熔断算法? - - q: goctl 解决了哪些问题? - - q: gozero 中布隆过滤器的使用 - - q: gozero内置链路追踪是怎么实现的? - - - q: gozero怎么无缝接入dtm? - - q: 聊聊gozero的zrpc是啥?基于grpc实现了哪些附加功能? - x: | - zrpc 是基于 grpc 的一个 rpc 框架,内置了服务注册、负载均衡、拦截器等模块。这个我们后面会通过源码来说明。 - zrpc 实现了 gRPC 的 resolver.Builder 接口和 balancer 接口,自定义了 resolver 和 balancer。 - zrpc 提供了丰富的拦截器功能,包括自适应降载、自适应熔断、权限验证、prometheus 指标收集等。 - - - q: gozero的redis只支持0库,因为默认支持redis-cluster - - q: 多级 goroutine 的异常捕获,怎么设计? - x: | - 1. 微服务系统请求异常,应该隔离,不能让单个异常请求带崩整个进程。 - 2. go-zero 自带了 RunSafe/GoSafe,用来防止单个异常请求导致进程崩溃。 - 3. 需要监控,防止异常过量。 - 4. fail fast 和故障隔离的矛盾 - - q: 能否聊聊 gozero 的缓存的设计和案例 - x: | - 1. 分布式多 redis 集群,线上最大几十个集群为同一个服务提供缓存服务。 - 2. `无缝扩容`和`无缝缩容` - 3. 不存在没有过期时间的缓存,避免大量不常使用的数据占用资源,默认一周。 - 4. `缓存穿透`没有的数据会短暂缓存一分钟,`避免刷接口`或者`大量不存在的请求`拖跨系统。 - 5. 缓存击穿。一个进程只会刷新一次同一个数据,避免热点数据被大量同时加载。 - 6. 缓存雪崩。对缓存过期时间自动做了 jitter(抖动),5% 的标准变差,使得一周的过期时间分布在 16 小时内,有效防止了雪崩。 - 7. 自动缓存管理已经内置于 go-zero,我们可以通过 goctl 自动生成代码。 - - q: 如果打算换 go-zero 框架重构业务,如何做好线上业务稳定安全用户无感切换?另外咨询下如何进行服务划分? - x: | - 1. 逐步替换,从内到外。加个 proxy 来校对,校对一周后可以切换。 - 2. 如果数据库重构,就需要做好新老同步。 - 3. 服务划分按照业务来,遵循从粗到细的原则,避免一个 api 一个微服务。 - 4. 数据拆分对于微服务来讲,尤为重要。上层好拆,数据难拆,尽可能保证按照业务来拆分数据。 - - q: 微服务系统怎么拆分? - x: | - 1. 先粗后细,切忌过细,切忌一个请求一个服务 - 2. 横向拆分,而非纵向,一般不超过三层 - 3. 单向调用,严禁循环调用 - 4. 禁止接口类型透传 - 5. 没有依赖关系的串行调用,改为并行调用 - - q: gozero开发规范 - x: | - - 请求最好单独配置,最好以 Req 开头。相应的,响应也单独配置,以Resp开头。 - - 如果我们修改了 api 文件,可以追加生成吗? - - 同一个微服务的所有 api 文件,可以放在一起。比如说,用户系统,会涉及到登录相关操作、用户信息、关注和被关注等模块。这些模块可以加个 `group: friend`,就会自动生成到一个子文件夹。 - - - 用好api的import,分开写,然后import到主api,不要写在一起(需要各自的 service name 相同) - - api文件的@server,group, prefix, middleware - - - - q: ms架构下,gozero目录结构怎么组织最合理?goctl api/rpc生成的几个目录,分别有啥用? - x: | - internal/handler 目录:API 文件里定义的路由对应的 handler 实现 - internal/logic 目录:用来放每个路由对应的业务处理逻辑,之所以区分 handler 和 logic 是为了让业务处理部分尽可能减少依赖,把 HTTP requests 和逻辑处理代码隔离开,便于后续按需拆分成 RPC service - internal/svc 目录:用来定义业务逻辑处理的依赖,我们可以在 main 里面创建依赖的资源,然后通过 ServiceContext 传递给 handler 和 logic - internal/types 目录:定义了 API 请求和返回数据结构 - - - q: 添加配置 - x: | - 1. Add Config struct - 2. Add ServiceContext struct - - - q: gozero的logging怎么配置 - x: | - 用 go-stash 代替 logstash - filebeat 收集我们的业务日志,然后将日志输出到 kafka 中作为缓冲,go-stash 获取 kafka 中日志根据配置过滤字段,然后将过滤后的字段输出到 elasticsearch 中,最后由 kibana 负责呈现日志 - - - q: gozero怎么解决多环境下配置管理方案?给我具体代码 - x: | - 无非是两种方案 - - env + 各环境单独配置文件 - - 如果是ms的话,就需要etcd之类配置中心了,更安全(配置隔离,否则)并且实时生效,本身就适合低频修改但是需要保证分布式节点强一致性的需求。那就是viper+etcd嘛 - - - - url: https://github.com/wuyan94zl/IM - des: 一个单体、只有api的gozero项目,说是“聊天室”,实际上核心是用户模块和好友模块,我的gozero-feeds中借鉴了很多代码 - - url: https://github.com/zeromicro/goctl-swagger - des: gozero swagger - - url: https://github.com/zeromicro/awesome-zero - - url: https://github.com/zhoushuguang/lebron - des: gozero实现电商项目 - - url: https://github.com/gphper/cinema-shop - des: 基于go-zero的影票售卖系统。项目用到了 mysql, redis, etcd, rabbitMQ - - url: https://github.com/xiaopenggithub/zindle - des: gozero实现bookstore - - url: https://github.com/feihua/zero-admin - des: gozero实现的电商项目,表设计可以借鉴 - - url: https://github.com/zeromicro/zeromall - - url: https://github.com/kevwan/mapreduce - des: mapreduce, 并发编排任务。用 mapreduce 把正交逻辑并行化,就可以大幅度降低服务响应时长 (不需要优化 DB/缓存,重写业务逻辑)。 - - url: https://github.com/SpectatorNan/gorm-zero - des: gozero 中用 gorm 代替默认的 sqlx - - url: https://github.com/Mikaelemmmm/gozerodtm - des: gozero中使用dtm的教程 - - url: https://github.com/nivin-studio/go-zero-mall - doc: https://mp.weixin.qq.com/s?__biz=Mzg2ODU1MTI0OA==&mid=2247485055&idx=1&sn=474d13c6a31a9dbbce953bd6fada5daa - des: 一个gozero实现的电商项目 - - url: https://github.com/Mikaelemmmm/go-zero-looklook - des: | - doc 文件夹下就有该项目的全部教程,但是这个教程只有大概思路和关键代码讲解,不是那种跟着一步一步实现的。bz也有视频,但是不用看,直接看文档教程就行。 - - 技术栈: gozero(go-queue) + mysql + redis + EFK(+ go-stash) + PAG + jaeger + kafka + asynq - - - - -- type: Websocket - repo: - - url: https://github.com/centrifugal/centrifugo - des: Centrifugo can instantly deliver messages to application online users connected over supported transports (WebSocket, HTTP-streaming, SSE/EventSource, GRPC, SockJS, WebTransport) - - url: https://github.com/gorilla/websocket - des: Use websocket in golang - - - -- type: sync - repo: - - url: https://github.com/sourcegraph/conc - des: 相当于对sync的封装,可以用来写更简洁和标准的并发代码(增加代码可读性),并且可以有效避免很多“低级失误”(也就是他所说的 Make it harder to leak goroutines,比如各种 defer <-done来关闭goroutine,防止leak)。比如说对wg和mutex的封装,以及用Catcher来封装recover逻辑,来统一处理panic - qs: - - q: Catcher对recover逻辑的封装 - - q: 提供了哪几种worker pool (ContextPool, ResultContextPool, ResultPool, ErrorPool) - - q: stream (用来保证结果有序) - - q: ForEach、map操作(用来处理slice) - - url: https://github.com/uber-go/atomic - key: true - des: uber-go/atomic比atomic更简洁,并且还提供了一些atomic本身没有提供的操作,比如sub, MarshalJSON, UnMarshalJSON 这些高频,但是需要自己实现的atomic操作。 - - url: https://github.com/lotusirous/go-concurrency-patterns - - - - -- type: IM - repo: - - url: https://github.com/openimsdk/openim-sdk-core - - url: https://github.com/openimsdk/open-im-server - - - - -- type: cron - repo: - - url: https://github.com/go-co-op/gocron - des: cron, "robfig/cron" have been EOL, so we use gocron - - - -- type: qrcode - repo: - - url: https://github.com/skip2/go-qrcode - des: 性能是 barcode 的三倍左右,但是生成的图片白边很宽,不好看,自己取舍吧。二维码通常是各种营销场景,方便用户使用。url 过长导致二维码像素点过密,怎么解决?把长链转短链,也就是所谓的动态二维码。 - - url: https://github.com/yeqown/go-qrcode - - - - -- type: Crypto - des: En/Decrypt - repo: - - url: https://github.com/FiloSottile/age - des: used to encrypt and decrypt - - url: https://github.com/phpseclib/phpseclib - des: 一些对称加密(AES)和非对称加密(RSA/DSA)的PHP实现,可以用来实现数据加密 - - url: https://github.com/deatil/go-cryptobin - key: true - des: 非常好用,与js兼容的AES加密库,省得折腾了 - qs: - - q: DES/AES是基于XOR实现的? - - q: RSA - x: RSA 加密基于`Diffie–Hellman 密钥交换算法`的模幂运算,*简单来说就是,正向计算简单,逆向求解困难* - - -- type: Excel - repo: - - url: https://github.com/qax-os/excelize - - url: https://github.com/tealeg/xlsx - -- type: rate-limiter - repo: - - url: https://github.com/mennanov/limiters - - # [这个限流库两个大bug存在了半年之久,没人发现?](https://colobu.com/2023/12/05/two-bugs-of-uber-ratelimit/) - # [更精准的sleep](https://colobu.com/2023/12/07/more-precise-sleep/) - - url: https://github.com/uber-go/ratelimit - des: 比juju/ratelimit更易用。这个pkg之前因为time.Sleep()导致的bug在golang1.23已经fix了(之前time.Sleep()设定50us, 实际上会sleep 80us左右,还是在可用状态,但是在golang1.16之后会sleep 1ms以上,也就是20倍以上,如果设定5000qps,实际上则是5000/20=250qps,属于完全不可用状态。)。结论是,time.Sleep()的精度问题是普遍存在的,也无法解决,目前只能做到ms级精度,部分pkg能做到us级精度,至于ns级精度就不要想了。 - - -- type: OAuth - repo: - - url: https://github.com/casbin/casbin - doc: https://editor.casbin.org/ - des: access controls - qs: - - q: storage? Model Storage, Policy Storage, - - q: Multi-tenancy? RBAC with Domains - - url: https://github.com/Permify/permify - des: 也是类似casbin那样的Auth服务,但是permify更类似Google Zanzibar,更适用于复杂业务系统,提供更细粒度的权限。但是也与RBAC, ReBAC, ABAC兼容。与casbin的使用场景不同。 - - url: https://github.com/casdoor/casdoor - des: casdoor和casbin的maintainer差不多,也是casbin社区项目统一使用的鉴权平台。Casdoor 是一个基于 OAuth 2.0 / OIDC 的 UI 优先集中认证 / 单点登录 (SSO) 平台,简单点说,就是 Casdoor 可以帮你解决 用户管理 的难题,你无需开发用户登录注册等与用户鉴权相关的一系列功能,只需几个步骤,简单配置,与你的主应用配合,便可完全托管你的用户模块,简单省心,功能强大。。 - - url: https://github.com/markbates/goth - des: 第三方认证. gh, google, gitlab, apple, twitter, etc. - - url: https://github.com/zitadel/zitadel - - url: https://github.com/kanidm/kanidm - qs: - - q: OAuth 协议的工作原理? - - q: OAuth2 有哪几种授权模式? # 主流是密码模式,授权码模式和简化模式适用于大型网站,客户端模式很少被使用 - - -- type: TUI/cli - repo: - - url: https://github.com/spf13/cobra - key: true - des: Better than urfave/cli. As Trivy said "Trivy has a lot of capabilities and needs a configuration file now. spf13/cobra has a better integration of configuration files. ... We should move to spf13/cobra.". Support feats like sub-cmd, flags, hooks(PreRun, PostRun), integrate with viper - qs: - - q: 为啥用cobra而不是urfave/cli - - q: hook(PostRun, PreRun) - - q: "***How to integrate with viper? 也就是“把config.yml作为默认flag并解析后,就可以直接使用config.yml中的所有key”,这样就不需要bind太多flag了***" - - q: 怎么在所有命令的入口判断 env 是否存在,并且在所有子命令中都可以直接调用? - x: 给rootCmd加个checkEnv()的PersistPreRun - - q: 有哪几种flag - x: PersistentFlags()、local (Flags())、required 必填 - - q: PersistentFlags() - x: Must be matched, if flag use `PersistentFlags()`, should use `MarkPersistentFlagRequired()` as a matched required flag. - - q: flag的P(), Var(), VarP()的用法有啥区别? - - q: cmd的Args参数验证,有哪些内置验证规则? - x: | - ValidArgs(), 用`Args: func()`直接自定义参数的验证, 还有一些用来限制args数量的方法比如NoArgs, ExactArgs, RangeArgs等 - - q: how best to handle errors in Run? # SilenceErrors, SilenceUsage, RunE - - cmd: - - c: cobra-cli add config - x: need to notice command-name should be camel case, e.g. 'cobra-cli add addUser' - - c: cobra-cli add create -p 'configCmd' - x: used to assign a parent command to the newly added command - - url: https://github.com/spf13/cobra-cli - key: true - des: go install github.com/spf13/cobra-cli@latest - - url: https://github.com/charmbracelet/bubbletea - key: true - des: prompt cli/TUI (better than promptui) 用来实现 TUI 应用的框架 - use: - - url: https://github.com/charmbracelet/huh - - url: https://github.com/sheepla/srss - - url: https://github.com/robherley/snips.sh - - url: https://github.com/charmbracelet/lipgloss - des: Style definitions for nice terminal layouts. Built with TUIs in mind. - - url: https://github.com/charmbracelet/gum - des: gum并不能作为mod集成到golang应用,只是一个用来增强shell交互性和用户体验的cli工具。直接基于bubbletea+lipgloss实现。 - - url: https://github.com/alecthomas/kong - des: CLI parser for golang - - url: https://github.com/gdamore/tcell - - url: https://github.com/rivo/tview - - url: https://github.com/pterm/pterm - des: a ALL-in-One console output utils, it support progressbar, charts, tables, tree, text input, single-select/multi-select, etc. it will replace other single-function cli-tools like schollz/progressbar, gosuri/uiprogress, cheggaaa/pb, olekukonko/tablewriter, termtables. In fact, pterm is just a render tool, It can be used by itself with cobra to provide a better Terminal experience. - - url: https://github.com/olekukonko/tablewriter - des: pterm不能完全取代tablewriter。这个repo支持各种table自定义样式(Without Border / Footer / Bulk Append, Custom Separator, cells merging、无边框)、支持自定义table颜色、支持多种数据源(CSV)、支持输出多种格式(Markdown) - - - -- type: Local-Cache - repo: - - url: https://github.com/ben-manes/caffeine - - url: https://github.com/google/guava - - url: https://github.com/orca-zhang/ecache - des: Local Cache. Support LRU. - - url: https://github.com/golang/groupcache - des: Local Cache. - - url: https://github.com/eko/gocache - - url: https://github.com/allegro/bigcache - qs: - - q: Compare bigcache, cachego, freecache, gcache, gocache, groupcache, lrucache. - - - - -- type: Golang-Template - repo: - - url: https://github.com/evrone/go-clean-template - - url: https://github.com/golang-standards/project-layout - - url: https://github.com/amitshekhariitbhu/go-backend-clean-architecture - - -- type: Golang-Logging - repo: - # zap 和 zerolog 都支持 取样器 Sampler 来限制每秒写入的日志数量,以减少性能开销。也都支持zero allocs. - - url: https://github.com/uber-go/zap - des: | - log, zap 性能比 logrus 更好,logrus 更好用,跟标准库 log 包在 api 层面兼容. 不要使用 logrus,因为 logrus 使用了大量反射,导致大量内存分配。golang logging真正有必须要学的只有zap和内置的slog,一个重量一个轻量,并且都功能强大。 - - 使用 zap 或者 zerolog,这两种是没有使用反射,没有内存分配 - - 基础需求: - - - 自定义字段(json 格式(自定义格式化日志和输出))和日志级别 - - hooks - - 线程安全 - - 性能要好 - - 其他特性(旋转日志、自动分割日志、支持修改时间格式) - qs: - - q: zap怎么同时输出到文件、console和kafka? 并且以不同格式(比如Text和JSON) - - q: logging的前端和后端分别是啥? - - q: 怎么分割logging - - q: 怎么实现不同service把日志打到 - - q: sugared和logger除了perf(通过减少使用interface和reflect)还有啥区别吗? 原生支持格式化 - - q: slog相比zap - - q: 怎么把zap集成到gin中? - - q: SugaredLogger, format, with(kv) - - q: NewExample()/NewDevelopment()/NewProduction()这 3 个函数可以传入若干类型为zap.Option的选项,从而定制Logger的行为 - - q: zap.NewDevelopment() 默认console. zap.NewProduction() 默认json. - - - url: https://github.com/rs/zerolog - des: According benchmark zap provided, zerolog is better than zap in terms with time and allocs. - - url: https://github.com/go-simpler/sloglint - des: 搭配log/slog使用的Linter,直接配置到 golangci-lint 的配置文件 .golangci.yml 里 - - url: https://github.com/samber/slog-sampling - des: slog sampling工具 - qs: - - q: 日志降级是啥?怎么实现? - x: 将日志会拆分成info,err两种日志文件,可以对info日志很好的降级,但err日志不会受任何影响,能够更好的去监控我们服务的错误问题。 - - q: access log 包括哪些字段 - x: | - lv(info, err, warn, ...), ts, msg, aid, iid, host, cost - - req - - - req.aid - - req.method - - req.path - - req.len - - req.cip - - rep - - - rep.len - - rep.code - - rep.err - - - - - -- type: uuid - md: true - repo: - - url: https://github.com/rs/xid - des: better than gofrs/uuid - - url: https://github.com/oklog/ulid - des: sequential, database-friendly ID generation - use: - - url: https://github.com/superseriousbusiness/gotosocial/blob/main/internal/id/ulid.go - - url: https://github.com/google/uuid - - url: https://github.com/sony/sonyflake - des: snowflake - qs: - - q: 手写snowflake算法?(id 全局唯一且自增,怎么设计?) - - url: https://github.com/jetpack-io/typeid - key: true - des: 基于UUIDv7实现,易用性更好,按照UUIDv7 spec,支持K-Sortable,不同于UUIDv4,作为DB主键使用时可以获得更好的locality。另外,支持type用来分割不同业务。 - - url: https://github.com/josethz00/snowflake-vs-uuid - des: snowflake vs UUIDv4 benchmark. 实际上相差不大,与普遍认知中的“uuid比snowflake慢很多”的印象完全不同,uuid与snowflake除了在generate场景下性能相差一倍以外,其他CURD场景没啥区别。这点是必然的,毕竟snowflake直接位运算和位移操作即可生成,而UUID需要hash-func。也就是说,UUIDv7完全完全取代snowflake,毕竟UUIDv7支持自增和type,性能也相差不大。 - - url: https://github.com/sqids/sqids-go - doc: https://colobu.com/2024/05/05/Sqids-short-unique-identifiers-generators/ - des: sqids 出乎意料的不错,Sqids = Short Quick Unique Identifiers - qs: - - q: 不同UUID version (UUIDv1, UUIDv4, UUIDv7) 的feat(换句话说,各版本之间的优化)?分别是怎么实现的? - x: MAC address -> UUIDv4不依赖系统时钟和MAC -> SHA-1(需要输入ns和name) - - - - -- type: mail - repo: - - url: https://github.com/axllent/mailpit - des: send mail - - url: https://github.com/emersion/go-imap - des: send mail, IMAP4rev2 - qs: - - q: SMTP, POP, IMAP, MIME 有啥区别?为啥需要这么多种发邮件的协议? - - - - -- type: Golang-Web-Framework - repo: - - url: https://github.com/gin-gonic/gin - des: Better than echo, iris, fiber, chi, goravel, beego, go-spring - qs: - - q: Gin框架中如何处理HTTP请求 - - q: "***聊聊gin的路由算法 Trie-Tree、路由算法LCP、生命周期、中间件原理***" - x: | - - CTT, 在TrieTree的基础上,通过合并唯一子树预期父节点来节约空间 - - url: https://github.com/julienschmidt/httprouter - des: ??? - - url: https://github.com/gogf/gf - - url: https://github.com/avtion/goamis - des: gf搭配aims实现的后台,FRO - - url: https://github.com/CrazyRocks/goadmin - des: 同上,也是个gf实现的后台,他的这个 middleware/rtoken 写的不错,FRO - - url: https://github.com/goflyfox/gtoken - des: Better JWT. - - url: https://github.com/bufanyun/hotgo - des: 企业级应用的gf实现的后台项目 - - url: https://github.com/zhouyaozhouyao/goframe-admin - des: 这个项目搞了casbin,用 kustomize 部署 k8s。internal 文件夹下有 MVC 层,里面用了gf对Transaction的封装,不错 - - url: https://github.com/vbenjs/gf-vben - des: - - url: https://github.com/gobuffalo/buffalo - des: EOL, No longer maintained - - url: https://github.com/go-nunu/nunu - des: 类似buffalo, 也开始类似 - - url: https://github.com/ent/ent - des: ??? - - url: https://github.com/swaggo/swag - des: Swagger for golang - - url: https://github.com/rookie-ninja/rk-boot - des: ??? 其实是个Generator,用单个yaml管理一些web相关的一些常用服务(其实还是framework+db+cache+middleware这些),比较基础,其实没啥意思 - - url: https://github.com/flipped-aurora/gin-vue-admin - des: gva 仅供参考 - - url: https://github.com/suyuan32/simple-admin-core - des: Simple Admin 是一个强大的、易扩展的后台管理系统,基于 Go-Zero、Vben Admin、Ent、Casbin 等开源项目构建,提供了完整的用户管理、权限管理、角色管理、菜单管理、日志管理、配置管理等功能,支持多语言等特性,适用于小型或大型企业快速搭建分布式后台管理系统。 - - url: https://github.com/cloudwego/hertz - key: true - des: | - [Golang Middleware] - What middleware is built into hertz? Middleware, contains Auth middlewares like casbin, JWT, Paseto. And CSRF, CORS, Etag, cache middleware. Tracing middlewares like OpenTelemetry, OpenTracing, Limiter, etc. - - - - -- type: goframe - repo: - - url: https://github.com/xinjiayu/NoticeServices - - url: https://github.com/pibigstar/go-todo - - url: https://github.com/xuanyanwow/LogkitByGo - - url: https://github.com/xuanyanwow/GoFrameNotifyConsumer - - url: https://github.com/CrazyRocks/autocreate - - url: https://github.com/mlogclub/bbs-go - - url: https://github.com/PasteUs/PasteMeGoBackend - - -- type: Goroutine - repo: - - url: https://github.com/uber-go/automaxprocs - key: true - des: 自动设置 GOMAXPROCS 来最大化利用当前 CPU - - url: https://github.com/KimMachineGun/automemlimit - des: 类似 GOMAXPROCS 之于 CPU,但是 automemlimit 是用来限制内存的,通过自动设置 golang 的 GOMEMLIMIT 环境变量,以便与 Linux cgroups 的内存限制相匹配。它的主要目的是帮助限制 Go 程序的内存使用,确保程序不会超出在 cgroups 中设置的内存限制。 - # [Go 每日一库之 tunny - 大俊的博客](https://darjun.github.io/2021/06/10/godailylib/tunny/) - - url: https://github.com/panjf2000/ants - key: true - des: 协程池, 来控制协程的并发数量. Better than tunny. tunny只支持同步的方式执行任务,虽然任务在另一个 goroutine 执行,但是提交任务的 goroutine 必须等待结果返回或超时。不能做其他事情。正是由于这一点,导致tunny的设计稍微一点复杂,而且为了支持超时和取消,设计了多个通道用于和执行任务的 goroutine 通信。一次任务执行的过程涉及多次通信,性能是有损失的。从另一方面说,同步的编程方式更符合人类的直觉。ants完全是异步的任务执行流程,相比tunny性能是稍高一些的。但是也因为它的异步特性,导致没有任务超时、取消这些机制。而且如果需要收集结果,必须要自己编写额外的代码。 - - url: https://github.com/Jeffail/tunny - - url: https://github.com/oxtoacart/bpool - - url: https://github.com/valyala/bytebufferpool - des: 协程池 buffer pool - - - - - - -- type: Build-Tool - repo: - - url: https://github.com/go-task/task - des: = Makefile. 相比于 makefile,这个还需要多安装一个 go-task。好处是用了 yaml 文件,执行命令更清晰。Makefile 的优势在于 IDE,以及各种平台都原生支持,这点非常重要。缺点就在于格式确实不太清晰。 - use: - - url: https://github.com/SkYNewZ/github-notifications-rss - des: FRO Taskfile.yml - - url: https://github.com/casey/just - des: 某种Makefile或者Taskfile,没发现有什么比较特别的feats - - url: https://github.com/dnaeon/makefile-graph - des: 用来生成Makefile依赖图的 - - - -- type: Golang-Error-Handle - repo: - - url: https://github.com/hashicorp/go-multierror - des: 用来将多个error添加到MultiError中,并在需要时一起处理。可以避免传统handle error时的繁琐代码。 - - url: https://github.com/samber/oops - des: Error handling library with context, assertion, stack trace and source fragments - - - - - - -- type: Golang-HTTP-Request - repo: - - url: https://github.com/go-resty/resty - - url: https://github.com/valyala/fasthttp - des: 10 times faster than net/http, but only for scenario that needs to handle thousands of small to medium requests per second. For most cases net/http is much better as it's easier to use and can handle more cases. For most cases you won't even notice the performance difference. (fasthttp 使用goroutine-multi-conn,而非CPC(coroutine per conn),减轻了runtime调度goroutine的压力,所以性能更好) - qs: - - q: 为啥fasthttp选择slice而不是map来存储请求数据? - - - url: https://github.com/sethvargo/go-retry - des: 用于重试逻辑和回退。它是高度可扩展的,可以完全控制重试发生的方式和时间。还可以通过实现backoff接口编写自己的自定义后退函数。 - - url: https://github.com/hashicorp/go-retryablehttp - - url: https://github.com/guonaihong/gout - - url: https://github.com/aceld/zinx - des: TCP server - - -- type: Image - repo: - - url: https://github.com/h2non/bimg - des: too heavy, I just need compress image, so didn't use it. dependency on libvips. BIMG compression is used for PNG only. - - url: https://github.com/imgproxy/imgproxy - des: pls read docs, it's a webserver, not a cli-tool. - - url: https://github.com/h2non/imaginary - - url: https://github.com/davidbyttow/govips - des: need to process them separately according to the image format - - url: https://github.com/Kagami/go-avif - des: It supports encoding of JPEG and PNG files to AVIF. - - url: https://github.com/cshum/imagor - - url: https://github.com/Comdex/imgo - - url: https://github.com/n7olkachev/imgdiff - - url: https://github.com/issue9/watermark - des: 简单的图片水印功能,支持 GIF - - url: https://github.com/corona10/goimagehash - - url: https://github.com/disintegration/imaging - - url: https://github.com/kornelski/pngquant - des: pngquant only support PNG images, not support other image formats. - - url: https://github.com/dropbox/lepton - des: Lepton is a lossless image compression algo developed by Dropbox. Lepton compress images, and it saved as .lep file. jpeg-xl ARHC filetype - - url: https://github.com/imazen/imageflow - des: ALL-IN-ONE image-tools, build by rust - - # upload images - - url: https://github.com/eleven26/goss - - url: https://github.com/aliyun/aliyun-oss-go-sdk - des: 因为OSS和COS这些也是基于S3标准实现的(或者说是兼容S3的),所以 - - url: https://github.com/tencentyun/cos-go-sdk-v5 - - url: https://github.com/googleapis/google-cloud-go - - url: https://github.com/mingcheng/obsync - - url: https://github.com/burybell/osi - - url: https://github.com/tutengdihuang/cloud_storage - - -- type: Tokenizer - repo: - - url: https://github.com/huichen/sego - des: How to implement a chinese tokenizer? (DAT) golang 中文分词,类似ansj, jieba, hanlp, Thulac. - - url: https://github.com/hankcs/HanLP - des: Better than jieba. - - url: https://github.com/blueshen/ik-rs - des: Chinese Tokenizer. - - -- type: Golang-DI - repo: - - url: https://github.com/google/wire - des: | - DI. wire is much easier to use than uber-go/fx. dig 是通过运行时反射实现的依赖注入。 - - 而 wire 是根据自定义的代码,通过命令,生成相应的依赖注入代码,在编译期就完成依赖注入,无需反射机制。 - - 这样的好处是:首先,方便排查,如果存在依赖错误,编译时就能发现。而 dig 只能在运行时才能发现依赖错误。 - - 其次,避免依赖膨胀,wire 生成的代码只包含被依赖的,而 dig 可能会存在好多无用依赖。依赖关系静态存在源码,便于工具分析。 - - url: https://github.com/samber/do - - - - - -- type: regex - repo: - - url: https://github.com/mvdan/xurls - des: xurls provides a lot of commonly used regex. e.g. xurls.Strict.FindAllString() will extract all urls from text. - use: - - url: https://github.com/superseriousbusiness/gotosocial/blob/main/internal/regexes/regexes.go - - url: https://github.com/mingrammer/commonregex - des: = xurls - qs: - - q: 常用regex - x: | - \\D只保留数字 - - \s.* 以空格开始的所有字符 - - [u4e00-\u9fa5] 选择所有汉字 - - [^\u4e00-\u9fa5]^[-,.?:;'\"!'] 选择所有非汉字,但是不包括-,.?:;'"!'这些标点符号 - - ^((?!abc).)*admin((?!abc).)*$ 包含 admin 且不包含 abc。 - - - - url: https://github.com/rust-lang/regex - qs: - - q: "*regex syntax?*" - x: (characters, quantifiers, groups, white-space, character classes, anchors and boundaries, inline modifiers, back-references, lookarounds, flags) - - q: 多行修饰符 - - q: 量词(重复次数) - x: "*, +, ?, {}" - - q: 特殊单字符(简写字符集) - x: \d, \D, \w, \W, \s, \S - - q: 空白符(其他项) - x: \f, \n, \r, \t, \v - - q: 特殊运算符 - x: 锚点(^, $), 范围(转义运算符\, 或运算符|, 点运算符., 特征标群(...), be[^ou]r), , 不保存子组 - - q: 模式修正符 - x: 忽略大小写i (?i), 全局搜索g, 多行匹配m, 惰性匹配(在量词后加上 ? 将使得相关匹配项变成惰性模式, 正则默认贪婪匹配), 具名捕获 - - q: 断言(零宽度断言) - x: 正向断言 (?=), 正向否定断言 (?!), 反向断言 (?<=), 反向否定断言 (?`矫正 - - 添加索引,索引不一定是最优的,`force index`强制走索引,但是不建议使用 - - 查看是否存在回表的情况 - - 覆盖索引避免回表,不用* - - 合理安排联合索引的顺序 - - MySQL5.6 之后使用 ICP 减少回表次数 - - 给字符串加索引,用`前缀索引`、`倒序存储`、`hash` - - 数据库的 flush 时机 - - innoDB 刷盘速度,脏页比例、redolog 写盘速度 - - 索引字段不要做函数操作,会破坏索引值的有序性,优化器会放弃走树结构。如果触发隐式转换,也会走 cast 函数,会放弃走索引 - - - q: "*mysql middleware, core requirements?*" - - q: uuid、自增 id、snowflake 作为主键,分别有什么优缺点?为啥 mysql 不推荐使用 uuid 作为主键? - - q: "*What optimization methods does optimizer have?*" # ICP and index dive, (MRR, BKA, BNL) - - q: What's Index Dive? - - q: ICP 的原理?有什么好处?使用 ICP 的注意事项? - x: | - - ICP 只能用于二级索引,不能用于主索引。 - - 不是全部 where 都能用 ICP 筛选,如果 where 条件的字段不在索引中,当然还是要读取整条记录做筛选,在这种情况下,仍然要到 server 端做 where 筛选。 - - ICP 的加速效果取决于在存储引擎内通过 ICP 筛选掉的数据的比例。 - - - q: "*Execution order of mysql query statements?*" # FWG(H)SDO - - q: Volcano Model(iterator executor) - - qq: - - topic: Index - qs: - - q: "***Index 创建原则?***" - x: 左选小写修(最左前缀索引、选择性、小字段、写操作频率、修改索引)最主要的索引创建原则其实就是最左前缀和选择性。除此之外就是一些tips,比如什么查询频率、写操作频率(更新非常频繁的字段不适合创建索引)、小字段(对于大的文本字段甚至超长字段,不要建索引)、反向开闭(用修改代替新增)之类的 - - q: Index选择性是啥? - x: 就是字段不重复的比例`count(distinct col)/count(*)`(不重复的索引值(也称为基数 cardinality) 和数据表的记录总数的比值),区间为`(0,1]`,*识别度越高,扫描相同行数,需要的次数就越少,这是由 B+ 树的性质决定的* - - q: 最左前缀的本质是啥? - x: “最左前缀”实际上就是前缀索引在复合索引场景下的使用,也就是说,复合索引中field顺序也要按照“index创建原则”来排序。最左前缀的本质就是ICP,ICP只在满足"最左前缀"条件时起作用。如果查询条件中包含了索引的非最左前缀列,ICP将无法生效,MySQL会在存储引擎层面进行完整的行过滤,这可能会导致性能下降。总结来说,"最左前缀"原则和ICP的本质是基于索引列的前缀进行索引范围扫描,以减少需要访问的行数,提高查询性能。 - - q: What's clustered and non-clustered index? - - q: explain命令的结果集分析? - x: extra (index, temporary, filesort), type (const, range, index, ALL, ref, fulltext (system, eq_type, ref_or_null, index_merge, unique_subquery, index_subquery)) - - q: Why MySQL use B+Tree, other than btree or skiptable? - - q: How To Leverage MySQL Database Indexing? - - q: MySQL8 索引跳跃扫描 Index Skip Scan. - x: MySQL Optimizer提供的机制,不需要设置索引来开启 - - q: 聚簇索引和非聚簇索引,分别是什么? - x: 聚簇索引和非聚簇索引的区别就是,叶子节点是不是存有行数据。聚簇索引是一种物理存储方式,它决定了数据在磁盘上的物理排序顺序。聚簇索引的目的是将相关的行物理上存储在一起,以提高范围查询的性能。聚簇索引是以主键 ID 为节点生成的,非子节点都是 id,叶子节点(最下面一层)会相互连接变成双向链表,并且叶子节点会存储对应的行记录。而非聚簇索引的节点是基于索引列,找到了对应叶子节点的索引值后,会根据叶子节点存储的行记录们指针们,回到聚簇索引去查找行记录(这个过程也叫做回表)。 - - - q: mysql 索引 退化 - - q: 聊聊MySQL8新增的隐藏索引、降序索引、函数索引这三种索引? - x: | - - 隐藏索引: - 应用场景:软删除、灰度发布。 - - 在没有hiding index之前,只能通过显式的方式删除索引,如果删除后发现索引删错了,又只能通过创建索引的方式将删除的索引添加回来,如果数据库中的数据量非常大,或者表比较大,这种操作的成本非常高。 - - 在MySQL 8.0中,只需要将这个索引先设置为隐藏索引,使查询优化器不再使用这个索引,但是,此时这个索引还是需要MySQL后台进行维护,当确认将这个索引设置为隐藏索引系统不会受到影响时,再将索引彻底删除。这就是软删除功能。 - - 灰度发布,就是说创建索引时,首先将索引设置为隐藏索引,通过修改查询优化器的开关,使隐藏索引对查询优化器可见,通过explain对索引进行测试,确认这个索引有效,某些查询可以使用到这个索引,就可以将其设置为可见索引,完成灰度发布的效果。 - - - 降序索引: - - 函数索引: 在索引中使用函数(表达式)的值,函数索引基于虚拟列功能实现 - - - - topic: MSR - qs: - - q: MSR的工作原理? MSR过程中,主从服务器分别使用了哪些线程? - x: 写入、复制、重放 (write, replication, replay) (sql thread, io thread) (parallel MSR) - - - q: What's GTID? Compare with binlog position-based MSR? - x: (GTID=server_uuid:tag:transaction_id), Auto-Positioning - - q: GTID Auto-Positioning - - q: 怎么解决 Replication Lagging 问题? - x: (relaylog) (refer to the process of MSR) 主从复制的流程就三步,写入/复制/重放。写操作完成后会实时写入 binlog,没有优化点。所以优化点在于后面两步,复制和重放都可以通过多线程并行。所以核心 - - q: MMR, Master HA, shadow-master - - q: mysql-cluster, - - q: What's read-write separation? How to achieve? - - - - topic: MySQL Optimize - qs: - - q: "***How to optimize MySQL?***" - u: https://dev.mysql.com/doc/refman/8.0/en/performance-schema.html - - q: mysql内置了哪些用来优化sql的工具,和soar对比呢? - - q: 怎么用optimizer-trace来优化sql? 如何分析trace来改善查询的执行效率? - x: 通过trace,我们可能发现一些我们在explain中看不到的东西,当发现query并未产生并行查询计划时,可以将trace打开,可以协助我们 - - q: explain-analyzer - x: mysql8 提供的优化工具,他会做出查询计划,并且会实际执行,以测量出查询计划中各个关键点的实际指标,比如耗时、条数、循环次数 - - q: explain-analyzer 返回的 cost, actual, time, rows, loops 分别是啥? cost 多少说明优化 - x: cost是估算值,actual是实际执行 . cost < 100就都不错了 - - q: “Query Profiler 工具”已经废弃了 - - - - # geektime MySQL实战45讲 - # - 一条 SQL 查询语句是如何执行的? - # - 一条 SQL 更新语句是怎么执行的? - # - 事务隔离(为什么你改了我还看不见?) - # - 索引(上下) - # - 全局锁和表锁;(给表加个字段怎么有这么多阻碍?) - # - 行锁;(怎么减少行锁对性能的影响?) - # - 事务到底是隔离的,还是不隔离的? - # - 普通索引和唯一索引,应该怎么选择? - # - MySQL 为什么有时候会选错索引? - # - 怎么给字符串字段加索引? - # - 为什么我的 MySQL 会抖动一下? - # - 为什么表数据删掉一半,表文件大小不变? - # - count(*) 这么慢,我该怎么办? - # - order by 是怎么工作的? - # - 如何正确地显示随机消息? - # - 为什么这些 SQL 语句逻辑相同,性能却差异巨大? - # - 为什么我只查一行的语句,也执行这么慢? - # - 幻读是什么?幻读有什么问题? - # - 为什么我只改了一行的语句,锁这么多? - # - MySQL 有哪些“饮鸩止渴”提高性能的方法? - # - MySQL 是怎么保证数据不丢的? - # - MySQL 是怎么保证主备一致的? - # - MySQL 是怎么保证高可用的? - # - 备库为什么会延迟好几个小时? - # - 主库出问题了,从库怎么办? - # - 读写分离有哪些坑? - # - 如何判断一个数据库是不是出问题了? - # - 误删数据之后,除了跑路,还能怎么办? - # - 为什么还有 kill 不掉的语句? - # - 我查了这么多数据,会不会把数据库内存打爆? - # - 到底可不可以使用 join? - # - join 语句优化? - # - 为什么临时表可以重名? - # - 什么时候会使用内部临时表? - # - 都说 innoDB 好,那还要不要使用 memory 引擎? - # - 自增主键为什么不是连续的?为什么 MySQL 的自增主键不单调也不连续? # mysql8 之后通过 redolog 解决了自增主键不单调的问题,但是不连续的问题依然存在。*mysql8 对于自增计数器做了修改,每次计数器的变化都会写入到系统的 redolog,并在每个检查点存储在引擎私有的系统表中;当 mysql 服务器被重启后,可以从`持久化的检查点`和`redolog`中恢复出最新的自增计数器,避免出现不单调的主键* - # - insert 语句的锁为什么这么多? - # - 怎么最快地复制一张表? - # - grant 之后要跟着 flush privileges 吗? - # - 要不要使用分区表? - # - 自增 ID 用完了怎么办? - - topic: InnoDB - qs: - - q: "***InnoDB, feats? (checkpoint, buffer-pool, read-ahead, insert-buffer, double-write, adaptive-hash-index) 这些都是啥?***" - x: | - - 事务相关:支持 ACID 事务、MVCC、InnoDB 锁机制、redolog - - 性能相关:插入缓冲、二次写、缓冲池、自适应哈希索引 - 但是实际上事务相关特性,本质上也还是为了优化性能,比如说之所以用 MVCC 就是为了能够并发事务,而 InnoDB 锁机制和 redolog 本质上来说都是为了保证 MVCC 正常运行。另外,也有一些其他特性,比如外键、行级锁定、共享表空间和独立表空间等等,这些都比较简单,就不太重要了。 - - - `插入缓冲 (insert buffer)`,*加速插入操作*,插入缓冲用于非聚簇索引的插入和更新操作,先判断插入的非聚簇索引是否在缓存池中,如果在则直接插入,否则插入到`插入缓存对象`中。再以一定的频率进行插入缓冲和辅助索引叶子节点的 merge 操作,将多次插入合并到一个操作中,提高对非聚簇索引的插入性能 - - `二次写 (double write)`由两部分组成,一部分是内存中的`double write buffer`,大小为 2MB,另一部分是物理磁盘上共享表空间连续的 128 个页,大小也为 2MB。在对缓冲池的脏页刷新时,并不直接写磁盘,而是通过 memcpy 函数将脏页先复制到内存中的该区域,之后通过`double write buffer`再分两次,每次 1MB 顺序地写入共享空间的物理磁盘上,然后马上调用 fsync 函数,同步磁盘,避免 OS 缓冲写带来的问题 - - `自适应哈希索引 (adaptive hash index)`*自动在内存中创建 hash 索引来加速读操作*,innoDB 会根据访问的频率和模式,为热点页建立哈希索引,来提高查询效率。索引通过缓存池的 B+ 树页构造而来,因此建立速度很快,innoDB 存储引擎会监控对表上各个索引页的查询,如果观察到建立哈希索引可以带来速度上的提升,则建立哈希索引,所以叫做`自适应哈希索引` - - `缓存池`为了提高数据库的性能,引入缓存池的概念,通过参数可以设置缓存池的大小和实例个数,缓存池可以存储一下内容:索引页、数据页、undo 页、插入缓冲、自适应哈希索引、innoDB 存储的锁信息和数据字典信息 (data dict) - - - q: "*InnoDB, arch? How does it works?*" - - q: InnoDB, redolog - - q: InnoDB 为什么要使用 bptree? - - q: 为啥mysql的InnoDB使用bptree,而不是btree或者skiptable? - - q: checkpoint是啥? 只跟redolog 相关吗? 跟其他日志有关吗? - x: 其实就是刷盘操作(当然还有其他刷盘操作,具体的触发条件、执行方式和优化策略不同,比如同步写入、异步写、定时写等等),用来把内存中的脏页(尚未写入磁盘的修改数据页)写入磁盘,并更新相关的日志信息,以确保数据的持久性(防止系统崩溃时数据丢失)和一致性。 - - - - topic: Transaction - qs: - - q: 什么是 CC?有哪些单版本的 CC 方法?基于这些单版本 CC 方法,MVCC 有哪些不同的实现? - x: CC 由数据库的调度器负责,事务本身感知不到可能导致数据一致性的冲突事务,调度器会 delay 或者 abort,如果 delay 就延迟到合法时机,如果 abort 就直接回滚。本质上是一个取舍问题,乐观锁不维护锁,吞吐很高,但是相应回滚也会比较多,而回滚比延迟的成本要高很多,所以在冲突较少和 validation 开销小的情况下,使用 OCC。LBCC 的方案则相反。 - - q: 三种实现 MVCC 的方法? - x: 其实就是三种,乐观锁、悲观锁和ts。也就是 MV-2PL(悲观锁)和MV-OCC(乐观锁,读写时不做验证,延迟到提交时验证),以及MV-TO(ts-based) - - q: MySQL的2PL是啥? - x: 2PL就是通过组合使用innodb的S锁和X锁来在保证事务隔离的情况下,提高并发性能 - - - q: "***InnoDB是怎么保证事务ACID的?***" - x: | - 事务的原子性/A让你在提交前能随时中止事务并丢弃所有写入,相应地,事务的持久性/D则承诺一旦事务成功提交,即使发生硬件故障或数据库崩溃,写入的任何数据也不会丢失。事务的隔离性/I确保每个事务可以假装它是唯一在整个数据库上运行的事务 —— 数据库会确保当多个事务被提交时,结果与它们一个接一个地串行运行是一样的,尽管实际上它们可能是并发运行的。而原子性与隔离性则服务于 一致性/Consistency —— 也就是应用的正确性/Correctness —— ACID 中的C是应用的属性而非事务本身的属性,属于用来凑缩写的。然而在工程实践中,完整的隔离性/I是很少见的。 - - - `一致性`,*一致性是最基本属性,其他三种都是为了实现一致性而存在的* - - `隔离性`,用事务的`隔离级别`保证事务的隔离性,为了保证并发场景下的一致性,引入隔离性,不同事务之间互不影响 - - `原子性`,用 undolog 保证事务执行失败后,直接回滚 - - `持久性`,用 redolog 保证事务提交后,对数据的修改是永久性的,即使系统故障也不会丢失 - - q: ANSI SQL92 用三种并发异常(Anomaly),划分出四种不同的隔离级别,将这种利弊权衡进行了(糟糕的)标准化 - - q: MySQL对MVCC的实现? MVCC = 版本链+ReadView(undolog) - x: | - 通过版本链的 trx_id 和 ReadView 的高低水位比较后,决定使用哪个版本。ReadView 就是快照,用来做可见性判断。 - - ReadView 的结构 (m_ids, min_trx_id 低水位, max_trx_id 高水位, creator_trx_id) - - undolog 版本链的结构 (trx_id 事务 id, roll_pointer 回滚指针) - - - - q: "***事务的四种隔离级别是什么?RU、RC、RR、SR 分别是什么?RR 和 RC 的区别?RC 和 RR 的 MVCC 机制为什么不同?各自会解决和导致什么问题?***" - x: | - 隔离就是类似linux kernel的可见性,通过可见性来解决事务在并发请求(包括读写操作)时的数据一致性问题。比如什么RU、RC、RR、SR,随着隔离级别的加强,分别解决了脏写、脏读、不可重复读和幻读的问题。隔离级别越来越高,并发性就越差。 - - RU、RC、RR、SR 分别是什么? - - - `RU`读操作不加锁,可能会`脏读`(解决了`脏写`问题) - - `RC`只对记录加记录锁,而不会在记录之间加间隙锁,所以允许新的记录插入到被锁定记录的附近。所以在多次读操作时,会发生`不可重复读`(解决了`脏读`问题) - - `RR`多次读取同一范围的数据会返回第一次查询的快照,不会返回不同的数据行,但是可能会发生`幻读`(解决了`不可重复读`问题) - - `SR`InnoDB 隐式地将全部查询语句加上共享锁,解决了`幻读`问题,但是性能很差 - - - q: 为什么 MySQL 把 RR 作为默认的隔离级别呢? - - q: RR 和 RC 在锁、复制、一致性读方面的区别? - x: | - *RC 和 RR 的区别在于 ReadView 快照生成时机不同,导致可见性不同*,RC 在每次读取数据前都生成一个 ReadView,而RR 在第一次读取数据时生成一个 ReadView - - q: "*MySQL(中 InnoDB)的事务是怎么实现的?怎么实现 RR 的?*" - - q: "***不同隔离级别,可能导致哪些问题?***" - - q: 并发事务之间的相互影响? - - q: 脏读、不可重复读、幻读分别是什么? - x: | - - `脏读`,t1 在修改之前提交,t2 读取,t1 回滚,t2 读取了从未提交的数据,*读未提交时,读事务直接读取主记录,无论更新事务是否完成* - - `不可重复读`t1 读取,t2 修改该数据并提交,t1 重新读取,数据已被修改,数据不同 - - `幻读`数据不同*每次都能读到最新数据* - - q: MySQL 遇到脏读怎么办? - - - q: "*MVCC 机制的原理和实现:MVCC 是什么?ReadView 是什么?高水位、低水位?*" - x: (m_ids, min_trx_id, max_trx_id, creator_trx_id), undolog(trx_id, roll_pointer) - - q: "*RR 是怎么实现的?RR 怎么用间隙锁解决幻读?*(常见问题)" - - q: MySQL 的 RR 无法避免 PMP / G-Single 异常,Hermitage 将其实际等级定为 单调原子视图/MAV - d: https://zhuanlan.zhihu.com/p/675251957 - - - q: MySQL 事务中的加锁和解锁时机? - x: | - - 对记录进行更新操作,或者`select for update`(X 锁)、`lock in share mode`(S 锁) 时,会对记录进行加锁,锁的种类很多,不赘述 - - 在一个事务中,只有在`commit`或者`rollback`时,才会解锁 - - - - topic: InnoDB 缓冲池(buffer-pool) - qs: - - q: 避免每次读操作都进行磁盘 IO,具体来说,缓冲池缓存了大量数据页,让 CPU 读取和写入数据时,直接和缓冲区交互,不需要操作磁盘,从而避免磁盘拖慢数据库性能的问题(*注意缓冲池是 innoDB 引擎的特性,而不是 mysql 的*) - - q: 缓冲池存哪些数据? - x: 缓存表数据与索引数据,把磁盘上的数据加载到缓冲池,避免每次访问都进行磁盘 IO,起到加速访问的作用。 - - q: 缓冲池的工作机制? - - - topic: InnoDB 预读 - qs: - - q: 什么是预读? - x: 磁盘按页读取,如果要读取的数据就在页中,就能节省后面的磁盘 io,提高效率。数据访问遵循`集中读写`的原则,使用一些数据,大概率会使用附近的数据,这就是`局部性原理` - - q: 什么是预读失败? - - q: 如何对预读失败进行优化? - - q: 什么是缓冲池污染? - - q: 怎么解决缓冲池污染的问题? - - - topic: redolog - qs: - - q: redolog 是啥?为什么需要记录 redolog? - x: "*undolog是逻辑日志,redolog是物理日志。但是redolog是由undolog产生的*" - - q: 需要什么样的 redolog? - x: 为了获得更好的读写性能,innoDB 将数据缓存到内存 (innoDB Buffer Pool),对磁盘数据的修改也会落后于内存,如果进程崩溃就会导致内存数据丢失,所以 innoDB 就维护了 redolog,内存数据丢失后,innoDB 会在重启时,通过重放 REDO,恢复数据 - - q: redolog 中记录了什么内容? - - q: redolog 是怎么组织的? - - q: 如何高效地写 redolog? - - q: 如何安全地清除 redolog? - - - topic: InnoDB Lock - qs: - - q: 聊聊innodb锁机制? - - q: 多粒度锁机制 - x: 行锁分为共享锁和排他锁,但是 InnoDB 还有两种内部使用的意向锁,这两种意向锁都是表锁。表锁、页锁、行锁、字段锁,当然是锁粒度更小的,开销更小、加锁更快,这个是毫无疑问的。 - - q: 共享锁 (SL, shared lock), 排他锁 (XL, exclusive lock), 意向锁(I锁, intention lock), 记录锁(LOCK_REC_NOT_GAP), 间隙锁 (LOCK_GAP), 临键锁(LOCK_ORDINARY), 插入意向锁(LOCK_INSERT_INTENTION) - x: XL和SL就是mutex和rwmutex,所有语言里都有类似的锁机制,不多说。IL其实就是IsLocked,用来判断是否加锁,进而决定下一步操作是sleep还是spin什么的,也很常用。下面的gap lock, next-key lock 都是MVCC相关的锁,可以理解。自增锁auto-inc lock是用来保证自增字段唯一性的,防止并发插入时,某个自增字段的数据重复。Record Lock相当于行级X锁。 - - q: 怎么理解插入意向锁? 到底是I锁还是gap锁? # - - q: innoDB 间隙锁是什么? - x: InnoDB 的锁定是通过在指向数据记录的第一个索引键之前和最后一个索引键之后的空域空间标记锁定信息实现的。这种锁定方式被称为 "NEXT-KEY locking"(间隙锁) - - q: innoDB 间隙锁有哪些缺点? - x: 锁定一个范围之后,即使某些不存在的键值也会被无辜锁定,造成锁定的时候无法插入键值锁定内的任何数据 - - - q: MySql Lock wait timeout exceeded该如何处理? - x: | - Lock wait timeout exceeded; try restarting transaction - - 死锁导致事务超时 - - update语句锁全表导致的等待超时问题 - - - - topic: MySQL use - qs: - - q: 多表联查,有哪些连接查询? - x: 内连接, 左/右连接, 全连接(有就是有,没有就写 Null,但是 MySQL 不支持,可以同时使用left join和right join), 交叉连接(笛卡尔积,交叉连接返回左表中的所有行,左表中的每一行与右表中的每一行组合,cross join) - - q: 为啥最好用“子查询”而不是“联查”? - x: 数据量小的时候,join 查询好用,大的时候,子查询好用。另外, join 查询最好不要超过 3 个表的关联,大公司一般是禁止用 join 的。 - - q: "***已经有大量数据的表怎么改字段? 为什么大佬都喜欢建表的时候加个 ext 字段?***" - x: 因为大表加字段,执行alter操作会直接锁表,所以冗余几个JSON类型的ext字段。这样就可以直接把整个json发给前端,让他们自己处理。当然,mysql8的online ddl优化了加字段的操作,直接操作metadata了,可以秒加字段。但是建议还是建表时冗余几个ext字段。 - - q: 数据库不应该默认 null(因为负向查询`id!=1`不能命中索引,导致全表扫描) - - q: "*是否要使用 in?*" - - q: uuid、自增 id、snowflake 作为主键,分别有什么优缺点? - - q: 金额应该用什么字段类型?金额为什么不能用 float 存? (int, float, decimal) - - q: 时间类型用什么字段类型?timestamp 还是 datetime,有什么区别? 时区切换 - - q: 身份证图片存数据库,应该用什么字段类型? - - q: 如何描述性别数据? # 用 int,通常默认 0 未填写,1 男性,2 女性 - - q: 状态用什么字段类型? # 状态的字段类型用枚举类型 enum 或者 tinyint - - q: 为什么应该使用软删除,而不是硬删除? - - q: select/insert/update for update 引发死锁 - - q: MySQL 分页排序时的数据重复问题? (mysql8 order by priority queue, heapsort) 怎么解决? - - q: 用 show status 查看 sql 的执行效率,定位执行效率低的 SQL 语句,有哪些关键字段? - - q: 怎么监控 MySQL 索引的使用率? - - q: "*监控 MySQL 需要采集哪些指标?怎么监控 MySQL 的流量?*" # - use: - - des: 怎么避免“批量插入操作太多”,报错 Prepared statement contains too many placeholders? - sol: 分批插入嘛,insert操作最大限制65535 - # [MySQL CLI Cheatsheet](https://gist.github.com/hofmannsven/9164408) - cmd: - - c: CREATE INDEX <索引名> ON <表名> <要加索引的字段>; - x: 添加索引 - - c: DROP INDEX ON ; - x: 删除索引 - - c: SHOW INDEX FROM ; - x: 查看索引 - - c: optimize table - x: 硬删除数据库数据后,清除对应文件,从而优化索引效率的。但是实际开发中不会使用硬删除,所以该语句的使用场景很有限 - - c: show variables like '%partition%' - x: 查看 MySQL 是否支持分表 - - c: SHOW PROCESSLIST - - c: select left()/right()/substr()/substring_index(); - x: 字符串函数 - - c: select cast(date as datetime) as date from table1; - - c: select CONVERT('123', SIGNED); - x: string转int,也可以使用select CAST('123' AS SIGNED);进行转换 - - c: avg(), min(), max(), count(), sum() - x: 聚合函数 - - c: group_concat() - - c: select COUNT(IF(channel_type=1,IF(check_status=6,1,0),0)) FROM tougao_record WHERE accept_company_id=100; - x: 控制流函数if(), ifnull(), when case - - c: 'select date_format(date_entered, "%Y-%m-%d") as ud, count(id) as cs FROM ttrss_entries GROUP BY ud;' - x: 时间戳按天分组 - - c: select MONTH(date_entered) month, count(id) FROM ttrss_entries WHERE YEAR(date_entered) = 2020 GROUP BY month; - x: 每个月的数据统计 - - c: select count(id) FROM ttrss_feeds WHERE DATE_SUB(CURDATE(), INTERVAL 7 DAY) <= DATE(last_successful_update); - x: xxx时间内的数据统计 - - c: time_to_sec(timediff(t2, t1)), timestampdiff(second, t1, t2), unix_timestamp(t2) -unix_timestamp(t1) - x: 怎么获取格式化时间的差值 (不要用datetime类型的时间直接相减,因为datetime相减做了一个隐式转换,将时间的Y-m-d H:i:s直接拼接起来转换为整数,而没有使用unix_timestamp()进行转换,由于时间不是十进制的,所以时间会出错) - - c: select * from tablename WHERE 1=1 order by CONVERT( name USING gbk ) COLLATE gbk_chinese_ci ASC; - x: 按中文字母排序:先使用 convert 把 column 进行 gbk 编码,再把编码后的内容根据 gbk_chinese_ci 进行 collate 排序 - - c: select elt(interval(score, 0, 60, 80, 100), '0-60', '60-80', '80-100') as 'score_interval', count(id) FROM student_score GROUP BY socer_interval; - x: 目前有分数散布在1-100的n组数据,怎么根据统计区间呢?用interval()和elt()对结果进行分组 - - c: insert into test_tbl (id,dr) values (1,2),(2,3),(x,y) on duplicate key update dr=values(dr); - x: insert into ... on duplicate key update - - c: insert ignore into - x: 批量插入时,如何不插入重复数据?没有 ignore 的话,插入数据如果有重复数据,直接报错,后面不执行。加上 ignore,不返回错误,只返回 warning - - c: replace into test_tbl (id,dr) values (1,2),(2,3),(x,y); - x: 不存在则插入,存在则修改 replace into 操作本质是对重复的记录先 delete 后 insert,如果更新的字段不全会将缺失的字段置为缺省值 - - - url: https://github.com/jeremycole/innodb_ruby - des: InnoDB Viewer. 具体来说就是用来学习InnoDB的可视化工具 - - url: https://github.com/zput/innodb_view - des: 同上 - - url: https://github.com/cashapp/spirit - des: MySQL Migrate工具,只支持MySQL8. 据说性能比 github/gh-ost 更好。 - - url: https://github.com/pressly/goose - des: Database Migrate Tool that support postgres, mysql, sqlite, mssql, redshift, tidb, clickhouse, vertica, ydb, duckdb. - - url: https://github.com/XiaoMi/soar - des: | - soar之类基于SQL指纹实现的sql优化工具,可以对sql进行预优化(也就是搭配slow-log在服务还没上线之前就对sql进行优化)。目前soar只支持mysql。 - feats包括索引优化、EXPLAIN解读、sql打分、自动SQL重写以及启发式规则建议(就是类似各种Linter或者logger一样,解释sql的具体问题)。试用了几个,在同类工具里算是比较好用的。 - qs: - - q: 要求实现一个sql optimizer来给sql打分和美化,怎么实现? # 具体来说就是用go-sql-driver之类的ORM对EXPLAIN进行解析,并把结果集的字段修改为中文后,输出为自定义格式 - - q: soar.yaml - - q: "@sql指纹 sql fingerprint" # pt-fingerprint(percona fingerprint, using regex), TiDB SQL parser(AST) - - -- type: MySQL-HA - repo: - - url: https://github.com/vitessio/vitess - doc: https://vitess.io/docs/ - des: vitess能解决所有mysql高可用方面的常见问题,比如什么主从复制、读写分离、分库分表、写库单点问题等等。 - qs: - - q: Vitess 如何处理读写分离? - - q: How does VTGate, VTTablet works? - - q: sharding, Vitess 是如何实现数据库的水平扩展的?支持哪些类型的分片策略? - - q: Vitess 中的 Resharding 过程 - - q: Vitess 如何处理大规模的事务? - - q: Vitess 提供哪些机制来确保数据库的高可用性? - - q: Vitess 如何支持多租户架构? - - q: Vitess 的客户端如何处理连接池和事务? - - q: 为什么Vitess推荐每个MySQL服务器250GB? - - url: https://github.com/XiaoMi/Gaea - des: MySQL HA. Just for ref. - - url: https://github.com/MyCATApache/Mycat2 - des: 之前用过MyCAT1.6,但是已经EOL了,MyCAT2目前也EOL了。MyCAT2的feat有支持prom监控、XA事务、内置HAProxy - - url: https://github.com/mariadb-corporation/MaxScale - des: MaxScale是用来替代MHA(之前用 MHA+Consul)实现HA。由于 GTID 实现方式不同,Maxscale 最新版不支持 mysql 的故障自动转移,只支持读写分离功能。这部分内容是废的,MHA或者Maxscale这些组件实际上主要提供故障转移,但是vitess本身就支持,所以不需要搭配使用。 - des: Atlas, DBProxy, mysql-proxy, mysql-fabric, sharding-JDBC - qs: - - q: "***MySQL 中间件有哪些核心需求?***" - x: | - - 数据库虚拟化 - - 数据库对业务透明,业务不需要知道数据库的真实 IP、主从、读写、高可用等 - - 支持分库,且数据库的分库对业务透明 - - --- - - - 非跨库需求 - - partition key 的简单查询 - - partition key 上的 in 查询 - - 非 partition key 上的简单查询 - - 排序 + 分页 - - 跨库 join - - 跨库事务 - - 跨库子查询 - - q: MySQL分库分表 - x: 直接让`分库分表中间件`解决分表问题,业务和路由算法完全解耦,更灵活。其实这三点的目的都是类似的,都是为了降低大表问题,降低负载,是吗?只不过实现的方法不同,分库和分区是逻辑上拆分数据,分表则是物理上拆分数据。实际操作时通常是分表+分库。 - - - q: "***什么是分区?分区有哪些缺点,为什么大部分互联网公司都不使用分区,而更多的选择分库分表来进行水平拆分呢?请简述一下分区和分表的各自优势和缺点?使用分库分表的先后顺序?***" - x: | - *应该先分表,再分库*,因为分表后可以解决单表的压力,但是数据库本身的压力没有下降,我们需要分库,真正隔离来优化服务。 - - 分区就是,所有数据,逻辑上还在一个表中,但物理上,可以根据一定的规则放在不同的文件中。业务代码无需改动。 - - *不使用分区,主要是因为在高并发业务下,有很多问题*,主要是三点:如果 sql 不走分区键,很容易出现全表锁;分区表中使用关联查询,性能极差;使用分库分表,我们可以自己选择业务场景和访问模式,而分区则完全交给 MySQL,无法控制。 - - - q: MySQL 有哪几种分表方法?MySQL 有哪几种路由规则? - - q: 怎么实现 MySQL 分表?时间(按时间分区,大部分只查询最近的订单数据,那么大部分访问都集中在一个分区,比一个表小多了,数据库也可以更好地加缓存,从而提高性能) - - q: MySQL 有哪些分表方法? - - q: 分库分表带来的问题? - - - -# [PostgreSQL Ecosystem - OSSRank](https://ossrank.com/cat/368-postgresql-extension) -- type: pgsql - md: true - repo: - - url: https://github.com/postgres/postgres - key: true - doc: https://www.postgresql.org/docs/16/index.html - qs: - - q: 我有丰富的mysql的使用经验,可以直接平移到pgsql吗?使用时有哪些需要注意的? - - q: How to optimize? - x: analyze, explain, auto_explain之类的,类似mysql. AUTOVACUUM - - q: "***Compare mysql and pgsql. 从CC, replication, index(bptree), transaction, perf, extensibility, ecosystem, operability, usability方面***" - x: - - q: HEAP存储引擎,OrioleDB引擎 - - q: heap表的物理结构是怎样的? - x: pgsql每个数据库的表数据存储在$PGDATA/base目录下的子目录中,不同数据库之间是完全物理隔离的。表数据实际存在的物理文件可以通过查看文件系统目录看到。每个表有一个唯一的物理文件,这个文件以relfilenode命名,存储在对应的数据库目录下。如果对表执行了TRUNCATE操作,会生成一个新的relfilenode,即一个新的文件,但表的oid保持不变。 - - q: heap表文件的page是如何组织的? - x: heap表文件的单个页面(page)被分为多个heaptuple数据元组。每个page有一个header部分,其中包含了管理元组的字段,如pd_lsn、pd_checksum、pd_flags等。每个heaptuple由HeapTupleData和HeapTupleHeaderData组成,其中HeapTupleHeaderData包含了事务相关的字段,如t_xmin、t_xmax等,用于实现PostgreSQL的事务语义和MVCC(多版本并发控制)。实际的数据存储在data area部分。 - - q: pgsql的WAL是如何与heap表存储引擎协同工作的? - x: WAL是PostgreSQL中的一种日志机制,用于确保数据的一致性和可靠性。在heap表存储引擎中,当执行插入、更新或删除操作时,相关操作会被记录到WAL日志中。这些日志记录会在事务提交时写入到磁盘上的WAL文件中。在发生故障时,WAL日志可以用来恢复数据,确保数据不会因为系统崩溃而丢失。WAL机制与heap表存储引擎的写入操作紧密相关,确保了数据的持久性和一致性。 - - q: heap表文件的扩展文件有哪些? - - q: heap表的写入逻辑是怎样的? - x: heap表的写入操作首先会构造一个HeapTuple对象,然后通过一系列的函数调用,将该元组插入到一个可用的page中。这个过程包括初始化元组头、获取可用的page block-number、冲突检测、将元组信息添加到page中、标记page为dirty、写入WAL以及标记relation-cache中的旧tuple所在的buffer失效。值得注意的是,实际的数据落盘是通过checkpointer进程异步完成的,而不是在写入操作的主链路上直接落盘。 - - q: heap表的读取逻辑是怎样的? - - q: PostgreSQL是如何处理内核fsync的bug的? - - q: advisory lock 咨询锁 - - q: Replication - - q: 不停机备份? # dump, 文件级备份(PITR(Point-In-Time Recovery)) - - q: 怎么操作pgsql故障恢复? # 备份后,清除WAL,转储并重建数据库 - - q: pgsql的FTS有哪些缺点? # 性能、缺少feat支持(facet分面) - - q: FTS, textsearch, tsquery, tsvector, @@匹配运算符 - - q: 字组索引 pg_term, pg_bigm, - - q: sharding # pgsql没有内置分片,可以使用citus实现sharding - - q: pgsql 的WAL机制是如何保证数据一致性的? - - url: https://github.com/orioledb/orioledb - des: Next generation storage engine for pgsql. - - url: https://github.com/dimitri/pgcopydb - - url: https://github.com/zalando/patroni - des: 用来实现pgsql高可用集群的中间件 - - url: https://github.com/EnterpriseDB/repmgr - des: 同上,也是用来实现pgsql高可用集群的中间件 - - url: https://github.com/Vonng/pigsty - des: Pretty Useful. 用来构建生产级可用的pgsql服务(类似RDS)。 - - url: https://github.com/CrunchyData/pgmonitor - des: Used to collect metrics and alerting-resources from crunchy data. - - url: https://github.com/amutu/zhparser - des: zhparser = zh parser. pgsql extension for FTS of Chinese. 基于SCWS实现 - - url: https://github.com/Casecommons/pg_search - - url: https://github.com/dimitri/pgloader - des: 用来把数据import到supabase时发现的,支持各种sql(比如sqlite、mysql、mssql等) - - url: https://github.com/kataras/pg - des: postgres client for golang. - - url: https://github.com/pg-sharding/spqr - des: ??? Stateless Postgres Query Router - - url: https://github.com/citusdata/citus - des: Distributed PostgreSQL as an extension - - url: https://github.com/paradedb/paradedb - des: Postgres for Search and Analytics - - url: https://github.com/CrunchyData/postgres-operator - des: pgsql operator, 这种把pgsql放到k8s的operator确实挺鸡肋的 - - url: https://github.com/cloudnative-pg/cloudnative-pg - - url: https://github.com/jackc/pgx - des: pgx是一个为Go语言编写的PostgreSQL数据库驱动和工具包。它提供了一个低层次、高性能的接口,并且公开了PostgreSQL特有的功能,如LISTEN/NOTIFY和COPY。此外,它还包括了一个适配器用于标准的database/sql接口。 - - - - - - -- type: redis - md: true - repo: - - url: https://github.com/redis/redis - key: true - qs: - - q: redis arch # (event, ) - - q: redis thread model? # 其实redis的线程模型没啥好说的,就是主线程+fork子线程 - - q: redis 内存模型? Malloc(jemalloc), Eviction Strategy, Expiration Strategy - - q: redis virtual memory, THP and swap - - q: 我们输入redis命令时,redis怎么handle这些请求(client requests)? # redis use reactor as event-driven - - q: redis多线程之后,之前的那些阻塞操作(比如keys, bigkeys, HGETALL之类的各种遍历操作以及DEL之类的),还会阻塞吗?为啥? - - q: redis lazy-free机制 - - q: 有哪些可能导致 Redis OOM的操作? # monitor, setbit - - q: RESP(redis serialization protocol) - x: RESP 就是我们在主从复制和 pipeline 中使用的那个 redis 协议。实际上,所有 redis 命令的执行都是由 RESP 协议执行的(客户端发送命令给 redis 服务器时,redis 就会使用 RESP 协议来处理这些命令)。具体流程就是,序列化命令、解析并处理命令、处理完成后再序列化成 RESP 格式的响应、最后再通过 RESP 协议返回给客户端。 - - q: 2*3+2 (volatile/allkeys * LRU/LFU/random) + no-eviction, volatile-ttl - - q: Why redis use 'Approximated LRU', other than LRU? 近似LRU和LRU有啥区别? - x: 采样. 当 Redis 接收到新的写入命令,而内存又不够时,就会触发近似 LRU 算法来强制清理一些 key。具体清理的步骤是,Redis 会对 key 进行采样,通常是取 5 个,然后会把过期的 key 放到我们上面说的“过期池”中,过期池中的 key 是按照空闲时间来排序的,Redis 会优先清理掉空闲时间最长的 key,直到内存小于 maxmemory。redis 通过配置maxmemory-samples,默认为 3,数字越大,cpu 开销越大,越接近“理论 LRU 算法” - - q: What are the "caching patterns"? How to ensure the consistency of cache and database? - - q: redis服务调优? How to reduce the memory usage of redis? - - q: 为什么 redis 建议关闭THP? # THP会导致COW期间复制内存页从 4KB 变成 2MB,导致fork子进程速度变慢、高并发下容易造成内存溢出,所以建议关闭 - - # distributed lock - - q: 怎么用redis实现distributed locks? Compare (etcd, redis, zk, chubby)? - x: (avoid deadlock, reentrant, exclusive, ) (perf, consistency, retry-mechanism, lose-lock in MSR, expire) - - q: "Deadlock: What It Is, How to Detect, Handle and Prevent?" - x: (no mutual exclusion, no hold and wait, removal of no preemption, removal of circular wait) - - q: "***双写一致性:怎么保证缓存和数据库的数据一致性? (, read/write through, , write-behind)***" - x: 延迟双删(write-around + cache-aside)、异步重试(write-around + read through)、CDC旁路模式(canal) 先更 db 后删 cache 能在大部分情况保证缓存和数据库的一致性 - - q: CDC 怎么做到高可用呢? - x: CDC 服务也要做到高可用的,可以定期将消费的 binlog pos 同步到 zk/etcd 等外部存储,多个 CDC 服务竞争任务。如果是 MySQL 切表的话,需要 CDC 服务也参与,还要区分是否开启 GTID, 各种集群实现。一般为了避免这种情况,CDC 服务都是连接 slave 从库 - - q: "***有哪些监控 redis 的指标?***" - qq: - - topic: RedisObject - qs: - - q: redis中各种datatype分别使用什么ds实现? # (..., bitmap, hyperloglog, pub/sub) - - q: RedisObject, data structure? # type(datatype), encoding(ds), ptr, (lru, refcount) - - q: How does type and encoding mapping in RedisObject? (type, notused, encoding, lru, refcount) - # - Redis的Hashtable是如何扩容的? hash扩容渐进式rehash过程? - - q: redis 字符串的 []buf 有啥用?为啥还需要 free字段呢? - - q: redis的scan命令的实现? # hashmap, rehash, expand/shrink - - q: stream - - q: redis, transaction # BASE(not ACID), OCC, (multi, exec, discard, watch/unwatch) - - q: 那我如果想实现redis的原子操作,是用redis事务,还是用lua脚本呢? - - - q: redis lua中eval 和 evalsha 有什么区别?为什么推荐使用 evalsha? - - q: redis 的 lua 脚本?用哪些命令管理 lua 脚本?redis 里使用 lua 脚本的流程?怎么在 redis 里调试 lua 脚本?lua 脚本超时时间?超时后怎么处理? - - q: redis操作lua脚本 # script load/exists/flush/kill. script load加载,拿到返回的 sha1,再script exists判断脚本是否存在,最后evalsha sha1执行脚本 - - q: redis pipeline # (RESP buffer, ) (batch processing, not atomic (not support transaction)) - - q: 我有一个不太明白的问题哈,众所周知redis的transaction是BASE的,也就是弱一致性的。那为啥还要通过引入类似seata或者DTM这种Distributed Transation服务来使用AT和TCC这些弱一致性方案,而不是直接使用redis的transaction呢?既然都是弱一致性的。我们会在一个项目中使用各种数据库,比如postgres, mongo, elasticsearch, influxdb等等各种类型的数据库,分布式事务是怎么保证在这些数据库的数据一致性的呢?按照我的想法,分布式事务难道不应该是数据库服务本身应该提供的吗?比如说我们使用vitess实现mysql高可用,那vitess本身就应该给我们保证分布式事务的数据一致性。不是吗? - - - - topic: redis persistence - qs: - - q: Compare AOF, RDB and hybrid? # (work, config/usage, pros and cons, related issues) - - q: RDB (fork process+COW) (save time ops) (bgsave) - - q: redis RDB的bgsave的 "save N M" 是怎么实现的? - x: 轮询实现的,有个 serverCron 每100ms执行一次 - - q: 为啥RDB的需要配置这么多条规则呢? - x: 因为 Redis 每个时段的读写请求肯定不是均衡的,为了平衡性能与数据安全,我们可以自由定制什么情况下触发备份。所以这里就是根据自身 Redis 写入情况来进行合理配置。 - - q: "***AOF 工作原理***" # 命令追加append, - - q: AOF (append, write, fsync, rewrite compress) (fsync strategy) (bgrewriteaof) - - q: Hybrid # (header(RDB)+incremental(AOF)) - - q: How does AOF compress logs? - - q: Why does redis use fork to create child process, other than create a thread to rewrite AOF or RDB? - - - topic: redis MSR - qs: - - q: redis MSR具体流程? - x: SYNC(RDB+RESP buffer), PSYNC = full(SYNC)+partial+RESP buffer. redis2.8之后使用FSYNC+PSYNC结合来实现MSR, - - q: PSYNC(partial-sync) 具体流程? - x: (offset, copybuffer, runid). offset 是偏移量。copybuffer 是复制积压缓冲区,每次主节点同步数据推自己的 offset 和 buffer 过来后比对双方数据的 offset,之后决定是否需要同步 buffer 里面的数据。而 runid 是每个 slave 节点启动时发给 master 节点,用于标识之前是否同步过,决定进行全量还是部分复制。 - - q: position-based - - q: redis psync full-sync - - q: 命令传播 - x: 命令传播阶段主要有两个点,一个是*同步增量数据*,一个是*主从之间发送心跳*确认双方在线,slave 节点还会去发送自己的 offset 去获取更新命令 - - - - topic: redis-sentinel - qs: - - q: What's redis-sentinel? - x: HA, collateral tasks(monitor, failover). sentinel 解决高可用问题,master 宕机时故障转移 - - q: How does it works? - x: gossip(to notification leader is dead)+raft(to elect leader(smaller priority > larger offset > smaller runid)) - - topic: redis-cluster - qs: - - q: What's redis-cluster? How does it works? # 集群嘛,解决拓展性问题. meet/ping/pong/fail - - q: Why does redis-cluster use hash-slots to implement consistent hash? # slot=CRC16(key)/16384 - - q: Hash Slot Resharding and Rebalancing for Redis Cluster. - - topic: redis-sharding - qs: - - q: What's redis-sharding? - - q: range, hash(id=hash(key)%N) - - topic: RedLock - qs: - - q: "***分布式锁有哪些常见问题?***" - x: | - - `时钟漂移问题` 因为 redlock 算法没有对各 redis 实例的时钟校准,所以对上述`第三步`中`各实例返回加锁成功时间`都减去一小段时间,来抵消时钟漂移 - - `失败重试机制` 如果获取锁失败,会随机时间后再获取锁,以免竞争导致每个客户端都无法获取锁 - - `羊群效应 (Hard Effect)` 分布式锁的一种常见问题,所有客户端都尝试对某个临时节点去加锁,当一个锁被占有时,其他对客户端都会监听这个临时节点 - - q: 为啥RedLock比SETNX和Redisson更靠谱? - x: 因为能够同时解决 忘记释放锁、锁超时释放(业务还没执行完)和redis主从复制时锁丢失(客户端 A 对 master 节点加锁,master 节点主从复制给 slave 节点,此时 master 节点宕机,主从切换,slave 节点成为 master 节点; 此时客户端 B 来尝试加锁时,新 master 节点仍然可以加锁,而客户端 A 认为自己加锁成功,进行解锁操作,但是解锁失败; 多个客户端都可以完成加锁,真正需要解锁却解不了锁;)。说白了就是“未释放或者错误释放”的几种情况。 - - q: RedLock的原理? RedLock是怎么解决“redis主从复制时锁丢失”问题的? - x: 核心思想是,对redis集群中所有node获取锁,如果超过一半的node在锁的一半有效期内成功加锁,客户端认为获取了锁。如果完成该操作,则全部解锁。(其实就是通过redis集群的方法来避免主从复制时的锁丢失) - use: - - url: https://github.com/HDT3213/delayqueue - des: How to use redis to implement delay-queue? # (zset+lua) 使用 zset,拿时间戳作为 score,消息内容作为 key 调用 zadd 来生产消息,消费者用 zrangebyscore 指令获取 N 秒之前的数据轮询进行处理。 - - des: 限流,redis 实现限流有哪些方案? - - des: redis 实现分页 - - des: redis 实现多条件查询 - - des: 怎么使用 redis 实现流量整形 - - des: 怎么把 redis 数据刷回 MySQL - - des: 如何删除 redis 里的 key? - - des: MySQL 里有 200W 数据,redis 只存 20W 数据,如何保证 redis 中都是热点数据? - - des: 如何分析 Redis 里存了什么? # 使用 RDB 备份,解析生成的 RDB 文件 - - des: 使用redis时,能否列举一些既能用其他数据类型,也能用stream,但是stream更好的使用场景吗? # 现在看起来Streams像是一个追加模式的,以时间为分数,元素是小型Hash的zset。更省内存,在很多场景下可以代替zset(最常见的就是有ts但是只需要类似“比分”这样简单数据的场景(股票价格、气象数据、MQ的任务分发等、IM场景)) 用stream代替list - cmd: - - c: object encoding key - x: 查看某个 key 具体使用了哪种数据结构 - - c: object refcount key - x: 查看某个 key 的共享对象的引用次数 - - c: redis-cli --bigkeys - x: 用来查看所有bigkey - - c: redis-benchmark - x: redis 性能测试工具 - u: https://redis.io/docs/management/optimization/benchmarks/ - - c: redis-check-aof - x: 检查 aof 日志的工具 - - c: redis-check-dump - x: 检查 rdb 日志的工具 - - c: CONFIG RESETSTAT - u: https://redis.io/commands/config-resetstat/ - - c: INFO - u: https://redis.io/commands/info/ - - - c: migrate - x: 实际上是 dump+restore+del 三个命令的组合,但是是原子性命令,支持源 redis 和目标 redis 之间直接迁移,比 dump+restore 好用,可以直接替代 - - c: rename - x: key重命名会执行 del 删除旧键,如果数据太大,会阻塞 redis - - c: SETBIT key offset value - x: SETBIT;“置位” - - c: GETBIT key offset - x: GETBIT;“取值” - - c: BITCOUNT key [start end] - x: 返回位图中第一个值为 bit 的二进制位的位置;在默认情况下,命令将检测整个位图,但是用户可以通过可选的 start 参数和 end 参数指定要检测的范围 - - c: BITOP operation destKey key [key...] - x: BITOP 支持 and,or,not,xor 这四种操作;很常用的一条命令 - - c: SLOWLOG GET - x: 查看最新的N条慢日志,包括命令本身、执行时间和执行时所在的时间戳 - - - - url: https://github.com/redis/go-redis - doc: https://redis.uptrace.dev/guide/ - des: redis client. Better than redigo. - - url: https://github.com/go-redis/cache - des: 使用 Redis 作为后端存储,并使用 MessagePack 来序列化缓存的值。可以选择使用 TinyLFU 或其他算法作为本地进程内缓存。 - - url: https://github.com/redis/rueidis - des: 更轻量的redis,可以把rueidis理解为另一种leveldb或者boltdb之类的,但是更重要的是我们可以把redis无缝替换为rueidis。 - - url: https://github.com/valkey-io/valkey - des: FOSS redis - - url: https://github.com/go-redsync/redsync - des: redis distributed mutex lock - - - url: https://github.com/bsm/redislock - des: distributed lock implemented using redis - - url: https://github.com/tair-opensource/RedisShake - des: redis数据迁移工具,用来在不同的redis实例之间迁移、同步、备份数据。 - - - url: https://github.com/RediSearch/RediSearch - des: Redis Modules, Used to support FTS. 如果没有用ES,又把redis作为数据源的话,可以用RediSearch代替ES。RediSearch还支持secondary index, 比如说如果redis中存了大量文章,就可以把文章的标题和内容作为索引的字段,执行搜索操作时,就可以快速定位到包含关键字的文章,而不需要遍历整个数据集。 - # - url: https://github.com/redisson/redisson - - url: https://github.com/CodisLabs/codis - des: redis HA, 已经EOL了 - - url: https://github.com/twitter/twemproxy - des: redis proxy, HA, 也EOL了 - - url: https://github.com/spotahome/redis-operator - des: 用来在k8s上部署redis的CRD,可以用来自动化部署redis集群,并支持redis HA - - ## redis GUI - - url: https://github.com/ErikDubbelboer/phpRedisAdmin - - url: https://github.com/RedisInsight/RedisDesktopManager - - url: https://github.com/gphper/grm - - - - - -- type: RDB - repo: - - url: https://github.com/duckdb/duckdb - des: | - 有点离谱,更轻量的嵌入式RDB,其官方称之为In-Process RDB - 专注于OLAP,也就是适用于读多写少的场景,而不是像其他RDB一样,同时支持OLAP和OLTP - - - url: https://github.com/enpeizhao/duck_db - - url: https://github.com/pingcap/tidb - des: AP数据库,因为tidb使用Raft实现 consistency。当然,TiDB 默认采用悲观事务模式,当然也支持不同级别的事务(RC、RR、SI)。 - qs: - - q: TiDB 的架构和特性有哪些? - x: 其架构包括 TiDB Server、PD Server 和存储节点(TiKV 和 TiFlash) - - q: 为什么要range范围计算?怎么优化?DNF和CNF是怎么转化成范围区间的? - x: TiDB 在进行表扫描前会对查询条件进行优化,将 Selection 算子的过滤条件化简为区间扫描。这个过程包括将逻辑表达式转化为析取范式(DNF)和合取范式(CNF),然后生成扫描区间。 - - q: TiDB 的乐观事务是如何实现的? - x: TiDB 的乐观事务基于 Percolator 分布式事务模型,通过两阶段提交(2PC)来实现。在 Prewrite 阶段,事务会获取一个 start_ts 作为开始时间戳,并对要写入的数据进行加锁。在 Commit 阶段,会获取一个 commit_ts 作为提交时间戳,并清理在 Prewrite 阶段留下的锁。乐观事务追求极致性能,在高冲突率的场景中可能会失败。 - - q: TiDB 插入(Insert)语句的处理流程是怎样的? - x: TiDB 插入数据的流程包括构建执行计划、执行 Insert 计划、处理数据填充、维护索引等步骤。在执行 Insert 计划时,会根据字段类型获取数据并进行填充,然后批量设置自增 ID,并将数据写入存储引擎。如果遇到唯一键冲突,TiDB 会根据配置进行错误处理或事务回滚。 - - q: TiDB 的执行计划执行过程是怎样的? - x: TiDB 的执行计划执行过程包括生成执行器、执行 SQL 语句、获取 TiKV 数据等步骤。执行器会根据执行计划中的算子类型构建不同的 Executor,然后执行 Open 方法进行数据处理。数据获取过程中,会向 TiKV 发送请求并获取返回的结果。 - - q: TiDB 的执行优化包括哪些内容? - x: TiDB 的执行优化包括构建执行计划、逻辑计划优化和物理计划优化。逻辑优化基于规则进行,而物理优化则基于代价进行。优化过程中会考虑谓词下推、列裁剪、聚合消除等因素,以提高查询效率。 - - q: TiDB 的 Percolator 分布式事务? - x: Client、TSO、BigTable - - url: https://github.com/drawdb-io/drawdb - doc: https://drawdb.vercel.app/editor - des: 官方介绍 "database design tool and SQL generator.",实际上就是个用来画ER Diagram的工具。支持导出到5种RDB(mysql, pgsql, sqlite, mariadb, sqlserver),所以归类到RDB下面。感觉没啥用。 - des: 可以看到RDB实际上还是MySQL及其衍生物,比如MariaDB和Percona, 然后就是Oracle和SqlServer - - -- type: tsdb - repo: - - url: https://github.com/influxdata/influxdb - des: TICK(Telegraf + Influxdb + Chronograf + Kapacitor) 技术栈的核心 - qs: - - q: influxdb feats? - x: ts, metrics, event - - q: influxdb, storage engine? - x: TSM(LSM), Tree(cache, wal, TSM file, compactor) - - q: 聊聊TICK技术栈? - x: | - - influxdata提供的stack - - Chronograf 不如grafana或者kibana好用 - - kapacitor可以通过对influxdb中的数据进行分析处理,它提供了丰富的函数可以自定义不同的条件,根据符合的阀值,输出日志、输出警告到slack、POST数据至HTTP endpoint、执行脚本等等各类触发条件。 - - Influxdb是TICK最核心的服务,因为它是专门设计用于存储和查询时间序列数据的数据库。InfluxDB 的设计允许它高效地处理大量数据,并且能够快速地查询和分析这些数据,这对于监控系统来说是至关重要的。其他组件如Telegraf、Chronograf和Kapacitor都是围绕着InfluxDB构建的,以提供数据收集、可视化和事件处理的功能 - - - url: https://github.com/taosdata/TDengine - des: 相比于influxdb,TDengine支持强一致性、且性能更好(性能优势很大,官网提供了benchmark),更适合写多读少的场景。想要取代目前influxdb在物联网(嵌入式设备)中的地位。 - - url: https://github.com/VictoriaMetrics/VictoriaMetrics - - url: https://github.com/cnosdb/cnosdb - doc: https://docs.cnosdb.com/docs/ - - url: https://github.com/influxdata/kapacitor - des: 数据处理平台,用于处理时间序列数据,可以执行复杂的事件检测和警报 - - url: https://github.com/influxdata/chronograf - des: 类似grafana或者kibana,用于提供InfluxDB数据的可视化和查询 - - url: https://github.com/GreptimeTeam/greptimedb - - url: https://github.com/influxdata/telegraf - des: 工业互联网 influxDB+telegraf+OneNet+Hightopo 完美适配了工业数据采集的高并发、低数据、简单关系、强时序的使用场景。插件驱动的代理,用于收集、处理、聚合和发送指标到各种输出,如InfluxDB。 - - - -- type: kvdb/cache - md: true - repo: - - url: https://github.com/rosedblabs/rosedb - - url: https://github.com/etcd-io/bbolt - des: boltdb - - url: https://github.com/br0xen/boltbrowser - des: A CLI Browser for BoltDB Files - - url: https://github.com/lotusdblabs/lotusdb - - url: https://github.com/memcached/memcached - - url: https://github.com/dragonflydb/dragonfly - - url: https://github.com/OpenAtomFoundation/pika - - url: https://github.com/ideawu/ssdb - - url: https://github.com/dgraph-io/badger - des: BadgerDB 是一个快速的嵌入式键值存储引擎,专为 Go 语言设计。它具有高性能、低内存占用和持久性的特点,适用于各种应用场景。 - - url: https://github.com/facebook/rocksdb - des: RocksDB 是一个高性能的嵌入式键值存储引擎,由 Facebook 开发。它基于 Google 的 LevelDB,但进行了许多优化和改进,提供了更高的性能和可靠性。市面上开源 kv 轮子一大堆,架构上都是 rocksdb 做单机引擎,上层封装 proxy, 对外支持 redis 协议,或者根据具体业务逻辑定制数据类型,有面向表格 table 的,有做成列式存储的。 - qs: - - q: RocksDB 对 LevelDB 进行了哪些优化? - x: 无非是批量写入(Pipeline Write)和并发处理(并发写memtable) - - q: RocksDB 的 Pipeline Write 机制 - - q: RosksDB 中 LSM-Tree 写入流程? - x: 两步。首先将键值对(KV)追加写入到WAL(Write-Ahead Logging)日志,并强制刷盘以保证数据的持久化。然后将该KV写入到memtable。 - - url: https://github.com/google/leveldb - des: 相比于其他kvdb,其特性是在存储时,key 值根据用户指定的 comparator 函数进行排序。除此之外,通过WriteBatch可以实现atomic操作(不是transaction也不是lua脚本,更类似pipeline(但是支持atomic)),还默认使用snappy算法对数据进行压缩(compact机制)。leveldb默认异步写(而不是同步写,为了更好的性能) - qs: - - q: 怎么用Comparator自定义排序? - - url: https://github.com/cockroachdb/cockroach - - url: https://github.com/tikv/tikv - - url: https://github.com/pingcap/tiflash - des: 提供行存储引擎 TiKV、列存储引擎 TiFlash 两款存储引擎,TiFlash 通过 Multi-Raft Learner 协议实时从 TiKV 复制数据,确保行存储引擎 TiKV 和列存储引擎 TiFlash 之间的数据强一致。 - - url: https://github.com/EchoVault/EchoVault - - url: https://github.com/patrickmn/go-cache - des: FRO. 最简易的kvdb. - - url: https://github.com/dgraph-io/ristretto - des: FRO. - qs: - - q: "***cache指标***" - x: QPS和hit-ratio - - q: cache hit ratio? How to calculate? How to monitor? - - q: What about cache strategy? - x: (LRU/LFU/ARC/TTL) - # - How to ensure the consistency of database and cache? - - q: What causes? How to resolve? - - q: "***缓存雪崩(cache avalanche), 缓存穿透(cache penetration), 缓存击穿(cache breakdown). 怎么处理以上问题?***" - x: | - - (large number cache invalidation) (random expire, LFU, ) - - (bloomfilter) 总结一下,击穿和穿透都是某个 key 被高并发请求,表现都是缓存层被穿透,数据库被高并发请求,**区别在于这个 key 在数据库中是否存在,如果 key 存在就是击穿,key 不存在就是穿透**。 - - gozero 本身提供的对 cache 的处理就很好 - - - 缓存穿透:即使查不到,也自动缓存,1min 过期 - - 缓存击穿:通过 mutex 保证只有一个请求去访问数据库. 或者 singleflight - - 缓存雪崩:给缓存 key 自动设置随机过期时间,确保不会集中过期 - - - q: What's cache warming? What are the specific implementation methods for cache warming? (pipeline) - - # local cache - - q: What local caching options are there? What are the usage scenarios of local cache? Which one is better to use? - - - - - - -- type: GraphDB - repo: - - url: https://github.com/vesoft-inc/nebula - - url: https://github.com/neo4j/neo4j - - url: https://github.com/JanusGraph/janusgraph - - url: https://github.com/authzed/spicedb - - url: https://github.com/surrealdb/surrealdb - des: document-graph database??? 怎么理解 - - - - - - -- type: ColumnDB - des: DBMS - repo: - - url: https://github.com/ClickHouse/ClickHouse - des: 通常用在大数据的ETL中作为OLAP使用。具体来说就是日志分析、广告和推荐引擎、金融数据分析、物联网数据分析。相比于RDB,Vertical的优势在于存储效率、查询性能、数据压缩。 - - url: https://github.com/ClickHouse/clickhouse-go - - url: https://github.com/apache/cassandra - - url: https://github.com/apache/hbase - - - - - - -- type: DocumentDB - md: true - repo: - - url: https://github.com/mongodb/mongo - doc: https://docs.mongoing.com/ - cmd: - - c: show collections - x: 显示当前数据库中的所有集合 - qs: - - q: Compare mongo and mysql. - x: (SE, transaction, scalability, memory usage higher than mysql, aggregate的表达力弱于SQL) - - q: How does mongo query works? - x: (BSON+cursor) 执行查询操作(find, aggregate, count, ...)时,MongoDB 会把查询条件转化成 BSON,进行查找。返回数据时用 cursor 分批返回数据。 这个cursor类似redis scan或者mysql分页。 - - q: mongo存在mysql的连解查执吗?能否从存储引擎(包括存储引擎本身的区别,以及选择)、读操作机制(查询机制)、写操作机制、事务支持(ACID)、数据模型、数据持久化等方面,比较一下mysql和mongo - qq: - - topic: mongo transaction - qs: - - q: How to use transaction in mongo? - - q: Why to use WiredTiger as default engine in MongoDB? Compare with InnoDB? # (CC, perf, durability) - - q: Why does mongodb use WiredTiger instead of mmap? - - q: mongo replication lag, How to resolve? # write-concern - - q: mongo的WiredTiger为啥用btree,而不是b+tree呢? 哪些场景下WiredTiger使用LSM? - - - - url: https://github.com/mongodb/mongo-go-driver - des: mongo-go-driver - - url: https://github.com/apache/couchdb - des: Reduce简化器, Map - - - -- type: 嵌入式RDB - repo: - - url: https://github.com/sqlite/sqlite - des: - qs: - - q: sqlite (datatype, transaction, index, FTS) - cmd: - - c: sqlite3 data.db '.backup backup.db' - x: .backup 命令创建一个内容一致的数据库备份副本。如果备份期间有很多写入活动,则副本创建的速度可能会很慢。 - - c: sqlite3 data.db '.dump' > dump - x: .dump 命令创建一个数据库内容的转储。 - - url: https://github.com/benbjohnson/litestream - des: 一个将SQLite数据库流式复制到S3兼容的存储系统的解决方案, 也可以用于备份。相当于某种sqlite的MS复制方案,适用于大型应用(但是很好奇为啥大型应用还要用sqlite,哈哈)。底下来列出了一些备选方案,比如直接用sqlite内置备份命令,再加上s3的sync命令来实现。以及LiteFS 或者 VFS 来实现。感觉意思不大。 - - url: https://github.com/LMDB/lmdb - des: | - 与sqlite类似的嵌入式RDB,但是不如sqlite。 - - - 相同数据的情况下, 比sqlite3的数据库大13% - - key大小限制。lmdb的key被限制在1978个字节以内, 这在一些情况下会非常容易超出限制。 - - url: https://github.com/kriszyp/lmdb-js - des: | - Node.js和Deno的LMDB绑定 - - Simple, efficient, ultra-fast, scalable data store wrapper for LMDB - - url: https://github.com/mattn/go-sqlite3 - - url: https://github.com/nalgeon/redka - des: 基于sqlite实现的redis - - - - -- type: VectorDB - repo: - - url: https://github.com/facebookresearch/faiss - des: vector plugin - - url: https://github.com/milvus-io/milvus - - url: https://github.com/weaviate/weaviate - - url: https://github.com/qdrant/qdrant - - url: https://github.com/farouqzaib/fast-search - - - - - ---- - - -- type: js - repo: - - url: https://github.com/npm/cli - cmd: - - c: npm list -g - x: 查看所有全局包列表 - - c: npm root -g - x: 查看全局包位置 - - c: npm config set prefix <目标目录> - x: 修改全局包位置 - - c: npm install -g - x: 全局安装 - - c: npm rm -g - x: 全局卸载,相当于npm uninstall,rm是uninstall的alias,需要注意的是只写pkg名就可以了,不要加version. 比如 npm rm -g create-react-app. - - url: https://github.com/yarnpkg/berry - des: yarn - - url: https://github.com/pnpm/pnpm - des: pnpm - - url: https://github.com/dylang/npm-check - des: | - 可以认为 npm-check = depcheck + npm-check-updates. 可以用来检查并自动更新dependency,也支持检查unused依赖项. Check for outdated, incorrect, and unused dependencies in package.json. - - url: https://github.com/depcheck/depcheck - des: = npm-check - - url: https://github.com/raineorshine/npm-check-updates - des: 顾名思义,相当于 `npm-check -u`,用来检查pkg版本 - - - url: https://github.com/nvm-sh/nvm - des: Node Version Manager 用来管理node版本 - - url: https://github.com/cheeriojs/cheerio - des: parse HTML - - url: https://github.com/tailwindlabs/tailwindcss - des: CSS in HTML,其实就是类似bootstrap那种CSS框架嘛。对我们这种不会写css的人来说很有用(但是定制性更强,不如bootstrap简单。当然事情都有两面,在前端也日渐复杂的今天,对职业前端开发来说,简单并不是好事。),至于其优缺点,在我看来都很小,所以也就都无所谓了。使用tailwind时一定要用IDE插件,否则就要一直查官方文档,非常头疼。 - - url: https://github.com/shuding/nextra - des: used to dev website using MDX+Next.js - - url: https://github.com/PaulieScanlon/mdx-embed - des: used to embed in MDX, such as media like youtube, tiktok, etc. And code-snippets like CodePen, Gist, Replit, CodeSandbox etc. - - url: https://github.com/sveltejs/svelte - des: 基于编译器的前端框架 - - url: https://github.com/sveltejs/kit - des: svelte的meta-framework - - url: https://github.com/axios/axios - - url: https://github.com/trpc/trpc - des: 可以用来代替axios,但是更typesafe - - url: https://github.com/vuejs/core - - url: https://github.com/nuxt/nuxt - des: 让vue支持SSR - - url: https://github.com/vercel/next.js - des: react生态下的几个meta-framework, next.js适合做SSR, umi适合做CSR, 拓展性也更好, 还内置了很多贴地气的功能,比如配置式路由、补丁方案、antd 的接入、微前端、国际化、权限等. next.js和Gatsby都是MPA和SPA的结合使用,比如SSR/SSG 同构方案就是一个典型的体现,首先框架侧会在服务端生成完整的 HTML 内容,并且同时注入客户端所需要的 SPA 脚本。这样浏览器会拿到完整的 HTML 内容,然后执行客户端的脚本事件的绑定(这个过程也叫 hydrate),后续路由的跳转由 JS 来掌管。 - - url: https://github.com/umijs/umi - cmd: - - c: umi dva list model - x: 列出所有 model - - c: umi plugin list - x: 列出所有插件 - - c: umi generate page xxx --typescript --less - x: 目前只支持生成 page,生成基本页面 (其他文件如 model 都只能手动创建) - - c: umi generate dvx:model xxx - des: react meta-framework - - url: https://github.com/remix-run/remix - des: 也是react的meta-framework - - url: https://github.com/jestjs/jest - des: /js-unittest/. Better than mocha - - url: https://github.com/webpack/webpack - - url: https://github.com/vitejs/vite - des: 打包工具,better than gulp, grunt and webpack. vite 就是个更好用的 webpack,但是解决了 webpack 那些众所周知的问题,比如说打包速度慢、配置复杂之类的。 - qs: - - q: Compare webpack, vite, babel, gulp, grunt? - - url: https://github.com/expressjs/express - des: Express - qs: - - q: MERN(MEAN/MEVN) 技术栈有啥优缺点 - - url: https://github.com/element-plus/element-plus - des: for Vue - - url: https://github.com/ant-design/ant-design - des: for react - - url: https://github.com/chakra-ui/chakra-ui - des: sucks - - url: https://github.com/shadcn-ui/ui - des: 非常漂亮的 UI. ALL of these Table-Implements is based on "@tanstack/react-table", exactly as the "PesterDataTable" components. but shadcn/ui is a scaffold nor a lib, so we can't integrates it with docusaurus. - - url: https://github.com/facebook/docusaurus - des: docusaurus is pretty stable and robust. 但是docusaurus的TOC是inline的而不是全局的(这就导致在移动端很难在heading之间),这点就很烦,并且maintainer已经明确说了不太可能换成全局TOC,因为成本很高。 - qs: - - q: 比较几种SSG (MPA/SPA, perf(RT, compilation(build tool)), UI) # docsify, gitbook, astro - - q: 切换SSG之前,需要考虑哪些checklist (migration cost) # support "docs mode", plantUML, image zoom, code block?, admonitions syntax, Tabs(items) syntax - - q: markdown 图片缩放?(markdown 语法中并不支持控制图片显示大小,只能通过 css 来控制) - - q: 怎么添加 docusaurus 不支持的语言? - - q: How to custom sidebar? How to sort sidebar manually, also auto-generate docs inside? - - q: How to set "Docs" as the main page? - - q: How to hide(or remove) navbar? - - q: 怎么给docusaurus添加评论插件? 比较几种评论插件,哪个更好用? docusaurus 怎么集成 giscus插件? - x: Discussions(giscus), Issues(utterances, gitalk), third-party(Disqus), self-hosted(artalk) - - q: docusaurus本身不支持渲染PlantUML,那么怎么实现呢? - u: https://github.com/show-docs/remark-kroki - x: oki 的 docusaurus 插件,支持 PlantUML,需要自己部署 kroki 服务,或者使用官方提供的免费服务 - - q: docusaurus本身不支持“点击展示大图”,怎么实现? - u: https://github.com/gabrielcsapo/docusaurus-plugin-image-zoom - x: 用来“点击展示大图”,但是“scroll 之后zoom图片就直接关闭了”,就很蠢。 - - q: docusaurus支持哪些站内搜索? 除了algolia,有哪些本地搜索方法? - u: https://github.com/easyops-cn/docusaurus-search-local - x: algolia 需要开源 repo,且 blog 能够直接访问,所以我们直接使用本地搜索。比 cmfcmf/docusaurus-search-local 好用,样式好看,还支持中文搜索,支持快捷键搜索操作。 - cmd: - - c: docusaurus build --bundle-analyzer - - -- type: Typescript - repo: - - url: https://github.com/microsoft/TypeScript - qs: - - q: es - - q: vue, Lifecycle Hooks - - q: nuxt.js - - q: react-hooks - - q: How to set default parameter in ts? - - q: Compare SPA and MPA. - x: (SSR or CSR) (perf(首屏加载), SEO, route, state management) - - q: How to evaluate Astro? # islands arch, MPA - - url: https://github.com/TypeStrong/ts-node - des: 用来在node环境执行ts代码 - - url: https://github.com/sudheerj/ECMAScript-features - des: ES syntax. ECMA实际上是对所有js Engine(比如v8,而不只是interpreter)的spec,因为所谓的syntax本身就是Engine提供的。 - qs: - - q: 变量声明和赋值 # var, let, const - - q: class, extends, super - - q: arrow functions - - q: template string - - q: default, rest arguments - - q: 数组操作 - - q: 模块化 - - q: 异步编程 (Promise对象和异步操作, async/await异步函数) - - q: 迭代器和生成器 - - - -- type: Data-Visualization - repo: - - url: https://github.com/apache/echarts - - url: https://github.com/d3/d3 - - - ---- - - -- type: ghac - repo: - - url: https://github.com/actions/runner-images - des: 所有gh-actions内置的images,之前玩 nektos/act 的时候,想本地执行gh-actions要预装一个50GB的docker image,就是这堆东西,里面主要是各种lang和compilers,还有各种pkg manager,各种utils和cli tools, linters等等。 - - url: https://github.com/mxschmitt/action-tmate - des: Used to debug gh-actions via SSH, but I haven't used it yet. - - url: https://github.com/actions/toolkit - des: Used to develop gh-actions. - - url: https://github.com/actions-go/toolkit - des: Developing with TS is a better choice, but we can also develop ghac with docker. This toolkit is divided into inputs, outputs, results, logging, secrets and variables. There is no documentation, so we can directly view the source code, which is very simple to implement and use. we can load these inputs, directly use `os.Getenv()`, so it sucks. - - url: https://github.com/actions/gh-actions-cache - des: Used to manage the GitHub Actions caches being used in a GitHub repository. (Just a cli tool, Not a gh-actions) - # [如何为 Rust 项目配置 GitHub Action cache](https://liujiacai.net/blog/2022/10/29/github-action-cache-for-rust/) - # [Mark Phelps: Speed Up Your Go Builds With Actions Cache](https://markphelps.me/posts/speed-up-your-go-builds-with-actions-cache/) - - url: https://github.com/actions/cache - des: Pretty Useful. restore-key - - url: https://github.com/oprypin/find-latest-tag - des: Find the latest tag in a GitHub repository - - url: https://github.com/diggerhq/digger - des: Digger允许你在现有的CI(持续集成)流水线中运行IaC。它提供了一种在CI环境中本地运行Terraform的方式,以实现安全性和成本效益。你可以使用Digger在GitHub上的项目中运行Terraform,并通过PR(拉取请求)评论执行Terraform的计划和应用操作。它还支持Open Policy Agent(OPA)用于基于角色的访问控制、PR级别的锁定、漂移检测等功能。你可以通过GitHub Actions与AWS或GCP集成来使用Digger。 - - url: https://github.com/securego/gosec - des: Go security checker - - url: https://github.com/containrrr/watchtower - key: true - des: Used to automatically fetch container's newest image. - - url: https://github.com/bonaysoft/uptoc - des: 用来把文件传到S3, Google Storage, Qiniu, cos, Aliyun OSS的工具。比较常见的使用场景是把前端打包好的dist传到CDN上。 - - url: https://github.com/appleboy/ssh-action - des: 操作 ssh - - url: https://github.com/appleboy/scp-action - des: shell - - - url: https://github.com/stefanzweifel/git-auto-commit-action - des: 根据预设规则对文件变更进行自动化提交,并附上自定义的提交信息。这在自动化测试(当你更新Markdown文件时,自动提交并推送更新,确保文档与代码保持同步)、CICD(在测试成功后自动将构建产物更新到特定分支)或者文档更新(每次内容变化时,自动构建并更新站点)等场景下非常有用。 - - - url: https://github.com/goreleaser/goreleaser - key: true - cmd: - - c: goreleaser check - - c: goreleaser build - - url: https://github.com/goreleaser/goreleaser-action - des: goreleaser-action - - url: https://github.com/docker/login-action - des: Used to login DockerHub - - url: https://github.com/docker/build-push-action - des: Used to push image to DockerHub. Usually used with login-action. - - url: https://github.com/aliyun/acr-login - des: Used to login ACR(Aliyun Container Registries) - - url: https://github.com/hhyasdf/image-sync-action - des: 基于 image-syncer 实现,用来同步一些基于Docker Registry的服务(比如ACR, DockerHub, Quay, Harbor) What should be noted that it is not a two-way synchronization, but supports synchronizing an image to multiple docker-registries. The main usage scenario of this tool is to directly synchronize the packaged image to multiple platforms during release. There is no need to write a separate job for each docker-registry as before. Using this, we can directly synchronize to multiple platforms. goreleaser has done similar, but accroding this post , goreleaser only supports dockerhub, gcr and ghcr. - - - url: https://github.com/ad-m/github-push-action - des: push, push to repo itself, we can also push to another repo - - - url: https://github.com/gaurav-nelson/github-action-markdown-link-check - des: mlc, 活链检测, 之前花了一个下午的时间试用了各种lc服务,还是这个最好用。 - - url: https://github.com/UmbrellaDocs/linkspector - des: mlc作者的新作,据说比mlc更好用,基于Puppeteer进行check,有效减少FPR。试用了一下,体验一般,应该像mlc一样,在log中展示check过的文件名以及其中的link数,目前linkspector这种,完全不知道扫描过哪些文件,心里没底。config换成yaml好评。 - - url: https://github.com/raviqqe/muffet - des: = site sucker. 这个是用来检测自己的网站(尤其是CMS之类的内容站)是否有broken-link,不是lc。试用过几次,很不好用。 - - url: https://github.com/codecov/codecov-action - des: codecov - - url: https://github.com/github/codeql-action - des: codeql - - url: https://github.com/github/gh-actions-importer - des: gh-actions-importer 怎么把其他 ci 服务的 wf 转到 ghac? - - - - url: https://github.com/dawidd6/action-send-mail - des: used to send mail - - - url: https://github.com/cloudflare/wrangler-action - des: contains all wrangler operations like pages, functions, etc. 之前直接使用pages-action部署pages,但是因为pages的 - - - url: https://github.com/peter-evans/repository-dispatch - des: 在 workflow 中触发其他 workflow - - url: https://github.com/jigglycrumb/action-deploy-workspace-to-repo - des: 把本地文件夹推送到github repo的指定文件夹,并直接覆盖。我用来把docs的blog目录来覆盖掉blog项目。 - qs: - - q: ghac 的 workflow 有哪些基础语法?? # on, job, matrix, needs - - q: trigger # webhook(push, PR, fork, ...), schedule, manually(workflow_dispatch) - - q: "***有哪些常用的 context?What are the common context?***" # github, jobs, steps, (env, secrets, vars) - - q: How to use cache in gh-actions? - - q: 怎么本地执行 ghac? - - q: 如果使用gh作为团队的vcs,怎么优化 ghac 成本? - - q: 怎么在 workflow 中触发其他 workflow - - q: "***怎么开发 ghac 的 wf?***" # action.yml(with or env) - - - ---- - -# devops - - -- type: git - repo: - - url: https://github.com/git/git - key: true - cmd: - - c: 'git commit -m "():