数优编码 All articles
安全与面试

十种乱码长相速查表:从问号方块到「锟」字全家桶,对号入座就能修

数优编码
十种乱码长相速查表:从问号方块到「锟」字全家桶,对号入座就能修

Photo: Grj23, CC0, via Wikimedia Commons

为什么值得背这张表

面试里聊编码原理,候选人能背出 UTF-8 是变长编码的不多,能说清「为什么页面上是一排问号」的更少。乱码其实是编码知识最直观的考试题——每种乱码长相都精确对应一种错误操作。把这张表背熟,排查和面试两头收益。

速查表

# 你看到的 成因 修复思路
1 ??? 或 ????? 写入时字符无法映射到目标字符集(如 GBK 库收了 Emoji),MySQL 用 ? 填充 换 UTF-8(utf8mb4)存储,无法救回原数据
2 方块 □□□ 或豆腐块 字体缺字形,数据本身没坏 换支持该字符的字体,数据层面无需处理
3 是 这类拉丁扩展字符 UTF-8 字节被按 Latin-1 解释(经典 mojibake) text.encode('latin-1').decode('utf-8') 逆变换
4 ä½ å¥½ 同上,UTF-8 被按 Windows-1252 读 同上,注意 Windows-1252 有不可逆的映射点
5 锟斤拷 UTF-8 双重错误:坏字节→U+FFFD→再按 GBK 解码 从源头修:找到产生 U+FFFD 的环节,原始数据多半已损
6 烫烫烫 Windows debug 堆未初始化内存填充 0xCC,按 GBK 显示 不是编码问题,是内存问题,查未初始化变量
7 一串 你好 JSON 序列化时非 ASCII 被转义 ensure_ascii=False(Python)或用支持 UTF-8 的序列化配置
8 & < 满天飞 HTML 实体被二次转义或未解码 一次解码即可,禁止对已解码文本重复 escape
9 长串 %E4%BD%A0%E5%A5%BD URL 百分号编码,不是乱码 urllib.parse.unquote() / decodeURIComponent()
10 中文正常但英文正常中文变宽/错位 终端或编辑器把 UTF-8 当成单字节解析 检查 locale:export LANG=en_US.UTF-8

排查三步法

  1. 确认数据在哪一环变坏:直接查数据库原始字节(MySQL 用 HEX(col)),如果字节是对的,问题在展示层;字节错了,问题在写入层。
  2. 识别字节模式:UTF-8 中文每字节高位都是 1(E4–E9 开头常见),GBK 中文以 D0–F7 开头居多。HEX 输出对照一下,就能猜出「原始编码 → 被误读成的编码」。
  3. 能逆则逆,不能逆就重录:单层 mojibake 可以逆变换救回;出现 U+FFFD 或 ? 说明信息已永久丢失,只能找原始数据源重新导入。

面试怎么答才加分

被问到「线上出现乱码怎么排查」,别只说「统一用 UTF-8」。好的回答结构是:先区分数据损坏与显示错误,再给出字节级验证手段(HEX),最后按乱码长相定位具体环节——这套流程答出来,面试官基本不会再追问了。

把这张表存到书签里,下次凌晨三点被乱码告警叫醒时,你会感谢现在的自己。

All Articles

Related Articles

中文内容选序列化格式,别只看压缩率:JSON、XML 与 Protobuf 实测对比

中文内容选序列化格式,别只看压缩率:JSON、XML 与 Protobuf 实测对比

面试官问「Base64 能保护数据吗」:90% 候选人都答错了

面试官问「Base64 能保护数据吗」:90% 候选人都答错了

搜索召回率上不去?先看看你是不是把中文词切成了两半

搜索召回率上不去?先看看你是不是把中文词切成了两半