yen@harvey:~$ cat ~/glossary.md

Glossary

文章里那些缩写和黑话,集中解释一下。

Aliasing · 混叠 / 锯齿
采样不足导致高频信息失真的现象,画面上就是斜边、曲线的锯齿。颜色边界频率无穷高,理论上永远采样不够,只能想办法让锯齿不那么显眼。
B+ 树 · B+ Tree
数据库索引的常用底层结构:多路平衡树,所有真实数据落在叶子节点上,且叶子按索引列顺序串成有序链表。一个索引本质上就是一份按指定列排好序的数据副本,所以范围查询和有序扫描都很快。
Copy
Rust 的一个标记 trait:表示这个类型“按位复制即可,且复制后原值仍然有效”。i32、bool、char 以及共享引用 &T 都是 Copy,赋值是拷贝不是 move,原变量照样能用;String、Vec 这种拥有堆内存的类型没有 Copy。
Debug / Release · 编译模式
Debug 不做优化、便于调试;Release 开满优化。Rust / C++ 等两者性能能差一个数量级,所以压测一定要用 Release 构建。
EAGAIN
非阻塞 I/O 的返回码:现在没数据可读(或缓冲区写满了),不是错误,稍后再试即可。边缘触发里就是靠它判断“读干净了”。
epoll · event poll
Linux 上高效监听大量 fd 就绪状态的系统调用。比 select / poll 快,因为注册一次后由回调把就绪的 fd 推进“就绪链表”,而不是每次遍历所有连接。单线程高并发的基础设施。
ET · edge-triggered / 边缘触发
epoll 的另一种触发方式:只在状态跳变(新数据到达)那一刻报一次。必须循环 read 到 EAGAIN、且用非阻塞 fd,否则剩下的数据再也不会被通知。
EXPLAIN
让数据库给出某条 SQL 的执行计划。PostgreSQL 用 EXPLAIN / EXPLAIN ANALYZE,输出一棵计划树:是 Seq Scan(全表扫,慢)还是 Index Scan / Index Only Scan(走了索引)、预估与实际行数、有没有多出一个 Sort 节点(说明在内存或磁盘上又排了一遍)。判断索引到底有没有被用上的第一工具。
fd · file descriptor / 文件描述符
进程打开的文件、socket、管道等的整数句柄。内核用它来标识一个 I/O 对象,read / write / epoll 都拿它说事。
FXAA · fast approximate AA / 快速近似抗锯齿
后处理抗锯齿:对渲染好的成品图找边缘再模糊。极省性能,但容易把细节一起糊掉。
GBK
简体中文的传统编码,一个汉字固定 2 字节(兼容更早的 GB2312),是中文 Windows 长期的默认 ANSI 代码页。和 UTF-8 互不兼容:按 UTF-8 存的中文用 GBK 读就是乱码,反之亦然。
Ghosting · 拖影 / 残影
TAA 在快速移动时复用了过时的历史像素,物体身后留下一道残影。靠“历史拒绝”或光流估计来修。
io_uring
较新的 Linux 异步 I/O 框架(5.1+),基于“完成模型”,用一对共享环形队列提交/收割请求,比 epoll 更省系统调用。现代异步运行时(如 tokio)已逐步支持。
kqueue · kernel event queue
BSD / macOS 上的 I/O 多路复用机制,角色等同 Linux 的 epoll。这些系统上事件循环的底座。
L4 · OSI 第四层 / 传输层
传输层,TCP / UDP 工作在这。四层代理只看得到源/目标 IP 和端口,看不懂 HTTP 内容,所以没法按域名或 URL 路由。
L7 · OSI 第七层 / 应用层
应用层,HTTP / DNS 等协议所在。七层代理能读懂 HTTP(路径、Host、Header、Cookie),据此做路由和规则判断。
LT · level-triggered / 水平触发
epoll 默认的触发方式:只要缓冲区还有没读完的数据,就一直提醒你。啰嗦但安全,漏读了会再报。
move · 移动语义
把一个拥有堆资源的值(如 String、Vec)赋给别的变量或传进函数时,所有权从旧变量转移给新变量,旧变量随即失效、不能再用。这样同一块内存永远只有一个 owner 负责释放,避免重复释放。想要真两份得显式 clone。
MSAA · multi-sample AA / 多重采样抗锯齿
只在几何边缘做多采样、内部单采样,是 SSAA 的省力折中。但管不了贴图内部的锯齿。
MVCC · multi-version concurrency control / 多版本并发控制
同一行可以有多个版本同时存在于表里:UPDATE 不原地覆盖,而是写一个新版本、保留旧版本,每个版本带 xmin / xmax 标明由哪个事务创建 / 废弃。每个事务按自己的快照决定看到哪个版本,于是读不阻塞写、写不阻塞读。旧版本由 VACUUM 回收。
N+1 · N+1 查询
常见的查询坑:查一次主列表,再在循环里对每条记录各查一次,总查询数随数据量线性膨胀。改法是把循环内的查询提到循环外、整批预取。
OSI 模型 · Open Systems Interconnection / 开放系统互联
网络的七层参考模型(物理→数据链路→网络→传输→会话→表示→应用)。搞清一个组件工作在哪一层,是排查网络问题的前提。
p99 · 第 99 百分位延迟
99% 的请求都比这个值快,剩下 1% 更慢的“尾延迟”。比平均值更能暴露真实瓶颈;同理还有 p50 / p95。
RPS · requests per second / 吞吐量
每秒处理的请求数,压测的核心指标。极简接口能上几万,业务聚合接口常在几百到一千,两者不能放一起比。
SELECT … FOR UPDATE
在读的时候就给选中的行加锁,别的事务要改这些行得排队等你提交。用在“必须先读、再据此写”的场景里防丢失更新(悲观锁)。计数这种纯加减,更简单的办法是直接 UPDATE … SET x = x + 1 一条搞定。
SMAA · subpixel morphological AA / 子像素形态学抗锯齿
FXAA 的升级:不只找边缘,还识别 L / Z 形等形状再精确混合。比 FXAA 锐利,仍比 MSAA / SSAA 便宜。
socket · 套接字
网络通信的端点抽象。在 Linux 上它本身也是一个 fd,所以能塞进 epoll 一起管。
SSAA · super-sampling AA / 超采样抗锯齿
最暴力的抗锯齿:按数倍分辨率渲染再缩小,等效每像素多次采样。效果最好但开销最大(帧数腰斩)。
syscall · system call / 系统调用
用户程序请内核办事的入口(如 read、epoll_wait)。每次调用都有跨用户态 / 内核态的开销,所以高并发下要尽量少调、调得值。
TAA · temporal AA / 时间抗锯齿
跨帧抗锯齿:每帧给摄像机加微小抖动,累积多帧样本来消锯齿。性能好、静止画面最干净,但动起来易拖影(ghosting),需要历史拒绝来缓解。
Unicode
给世界上几乎所有字符分配唯一编号(码点)的标准 / 字符集。它只管“字 ↔ 号码”的对照,不规定号码怎么存成字节——那是 UTF-8 等编码的事。常被和具体编码混为一谈,其实是上下两层。
UTF-8
Unicode 最通用的变长字节编码:ASCII 占 1 字节、拉丁扩展 2 字节、汉字 3 字节、生僻字 / emoji 4 字节。靠头字节高位连续几个 1 标明这个字符占几字节、续接字节一律以 10 开头,因此能自同步。名字里的 8 指编码单位是 8 位,不是“每字 8 位”。
WAL · write-ahead log / 预写日志
改动落到数据文件之前,先把它顺序写进 WAL,这样即使崩溃也能靠重放 WAL 恢复。它解决的是持久性 / 崩溃恢复,和 MVCC 的并发可见性是两回事——别把两者搅在一起。
丢失更新 · lost update
两个事务都“读出旧值 → 各自加工 → 写回”,后提交的那个用过时的旧值覆盖了先提交的结果,于是一次更新凭空消失。把读-改-写拆成两条语句、新值在应用层算好时最容易中招——光包进 BEGIN…COMMIT 并不能防它。
乱码 · mojibake
文本用一种编码存、却用另一种编码解读时出现的现象。字节本身没坏,只是“解码的尺子”拿错了,于是同样的字节被翻成别的字符(如“锟斤拷”“ä½ å¥½”)。
借用检查器 · borrow checker
Rust 编译期检查引用是否合法的组件:保证“同一时刻要么多个不可变借用 &、要么仅一个可变借用 &mut”,且任何引用都不会比它指向的数据活得更久。它把 C 里靠自觉遵守的别名 / 生命周期规则,变成编译期强制。
卷积 · convolution / 卷积核
图像处理的基本操作:用一个小权重矩阵(核)逐像素扫过图像、做加权求和。模糊、锐化、超采样的平均,本质都是卷积。
复合索引 · composite / 联合索引 + 最左前缀
在多个列上建的一个索引,按列从左到右依次排序。遵循“最左前缀”原则:索引 (a, b) 能服务 WHERE a、WHERE a AND b、以及 a 等值后按 b 排序;但单独 WHERE b 用不上,因为这份副本是先按 a 排的。
完成模型 · completion model
I/O 通知方式:内核把数据读完、放进你给的 buffer 后才通知你。io_uring、Windows IOCP 走这套,比就绪模型少一次系统调用。
就绪模型 · readiness model
I/O 通知方式:内核只告诉你“这个 fd 现在可读 / 可写了”,数据还在缓冲区,得你自己去 read。epoll 走的就是这套。
所有权 · ownership
Rust 的核心机制:每个值有且只有一个 owner(变量),owner 离开作用域时值被自动释放。靠它在编译期管内存——不需要 GC,也不会重复释放(double free)。
旁路缓存 · cache-aside
最常用的缓存读法:先查缓存,命中就返回;没命中(miss)就查数据库,再把结果写回缓存,下次就有了。穿透 / 击穿 / 雪崩本质上都是这套流程的某个假设被打破。
码点 · code point
Unicode 给一个字符分配的唯一编号,写作 U+ 加十六进制,如 你 = U+4F60。它是抽象编号,本身不是字节;要存进文件 / 内存还得经过 UTF-8 之类的编码这一步。
缓存击穿 · cache breakdown
某个热点 key 过期的那一瞬,大量并发请求同时 miss、同时去查同一条 DB 并回填,把 DB 瞬间打爆。数据是存在的,只是恰好过期了。解法:互斥锁 / single-flight 只让一个请求重建,或热点 key 逻辑过期 / 不过期。
缓存穿透 · cache penetration
查询的数据在数据库里根本不存在,缓存因此永远建不起来、次次 miss,每个这样的请求都直接打到 DB。常被人用不存在的 id 刷接口。解法:缓存空值(短 TTL)或用布隆过滤器先挡掉不存在的 key。
缓存雪崩 · cache avalanche
大批 key 在同一时间集中失效(常因一起写入又用了相同 TTL),或 Redis 整个宕机,导致请求洪水般同时压到 DB。相当于很多击穿一起发生。解法:给 TTL 加随机抖动打散过期、Redis 高可用、加限流 / 降级兜底。
覆盖索引 · covering index
查询要的列正好都在索引里(PostgreSQL 可用 INCLUDE 把额外列带进索引),于是只读索引就能凑齐结果,不必再回堆表(heap)捞一次数据。EXPLAIN 里出现 Index Only Scan 就是它。
谄媚 · sycophancy
大模型经人类反馈训练后,倾向于顺着用户、说用户想听的话:你流露出偏好它就附和,你给的现状它就据此推荐,而不一定给最优答案。表现为“揣摩上意”“迎合现状”,是 AI 辅助决策时最隐蔽的坑。
采样定理 · Nyquist–Shannon 采样定理
要无失真还原信号,采样率得至少是信号最高频率的 2 倍。因为图像边界频率无穷高,所以从原理上就不可能彻底消除锯齿。