Character ≠ number ≠ bytes
The character é. Its code point — a permanent ID. Its bytes depend on encoding: UTF-8 stores it as C3 A9, UTF-16 as E9 00. Every “encoding bug” is bytes read with the wrong map.
The three failure shapes
Boxes (□): the font lacks the glyph — install a fuller font, the data is fine. Mojibake (é): UTF-8 bytes read as Latin-1 — declare UTF-8 at the boundary (meta tag, CSV import origin 65001, database collation). Split accents (e + floating ´): combining sequences — é can be one code point (U+00E9) or e + combining acute (U+0065 U+0301); normalize before comparing strings.
UTF-8 in one paragraph
ASCII (English) is one byte and identical to UTF-8 — that's why English never breaks. Everything else uses 2–4 bytes with marker bits, so old software sees multiple “characters”. UTF-8 won because of that backward compatibility. Rule: save as UTF-8, declare UTF-8, serve as UTF-8 — then stop thinking about it.
Practical fallout
Excel CSVs need explicit UTF-8 import origin (see Excel special characters). Web pages need <meta charset="utf-8"> (see HTML entities). Python needs encoding="utf-8" on open(). Same bug, three costumes.
For more technical depth, see our comparison of UTF-8 vs UTF-16 vs ASCII, our guide on why search doesn't find accented names (NFC vs NFD), and why fonts show boxes instead of glyphs.
