> Что такое кодировки текста, например UTF-8 и UTF-16 (Go)

Уровень: junior · Роль: backend · Категория: Технические вопросы

Компании: Orion_soft

Стек: Go

> Пример ответа

Короткий ответ

Кодировка текста - это способ сопоставления символов (букв, цифр, знаков) их числовым представлениям в памяти компьютера. UTF-8 и UTF-16 - это кодировки стандарта Unicode, которые кодируют каждый символ одним или несколькими байтами. UTF-8 использует переменную длину от 1 до 4 байт и совместим с ASCII, а UTF-16 - от 2 до 4 байт. В Go строки - это последовательности байт, и понимание кодировок важно для корректной работы с текстом.

Подробное объяснение

Unicode - это стандарт, который присваивает каждому символу уникальный номер - code point (например, U+0041 для латинской буквы "A"). Кодировка определяет, как этот номер хранится в виде байтов.

UTF-8:

  • Переменная длина: 1 байт для ASCII-символов (U+0000-U+007F), 2 байта для латиницы с диакритикой и кириллицы, 3 байта для большинства остальных символов (включая китайские иероглифы), 4 байта для редких символов.
  • Совместим с ASCII: любой валидный ASCII-текст является валидным UTF-8.
  • Экономичен для текстов на английском и большинстве европейских языков.
  • Самый распространённый формат в вебе и в Go по умолчанию.

UTF-16:

  • Переменная длина: 2 байта для символов из базовой многоязычной плоскости (BMP, U+0000-U+FFFF), 4 байта для остальных (суррогатные пары).
  • Используется в Windows, Java, JavaScript (внутреннее представление).
  • Менее экономичен для ASCII-текста (каждый символ занимает минимум 2 байта), но эффективнее для языков с большим количеством символов в BMP (например, китайский).

Ключевое отличие: UTF-8 оптимизирован для совместимости с ASCII и экономии места на латинице, UTF-16 - для равномерного доступа к символам в BMP, но требует обработки суррогатных пар для редких символов.

В Go: строки - это неизменяемые последовательности байт, они не хранят информацию о кодировке. По умолчанию Go предполагает, что строки содержат UTF-8, и стандартная библиотека (например, range по строке) итерирует по рунам (code points), а не по байтам. Для работы с другими кодировками нужно использовать пакет golang.org/x/text/encoding.

На практике

  • При чтении данных из внешних источников (файлы, сеть, БД) всегда проверяйте кодировку. Если данные не в UTF-8, их нужно конвертировать.
  • В Go для конвертации используйте golang.org/x/text/encoding и golang.org/x/text/transform.
  • При работе с []byte и строками помните: len(string) возвращает количество байт, а не символов. Для подсчёта символов используйте utf8.RuneCountInString.
  • Итерация for i, r := range s корректно обрабатывает многобайтовые символы, но индекс i - это байтовое смещение, а не номер символа.
  • При сериализации в JSON или HTTP-ответах всегда используйте UTF-8 - это стандарт для веба.
  • Если вы пишете парсер или работаете с бинарными протоколами, где указана кодировка, обязательно учитывайте BOM (byte order mark) для UTF-16.

Пример кода

GO
package main
import (
"fmt"
"unicode/utf8"
)
func main() {
s := "Привет, мир! 👋"
// len() возвращает количество байт
fmt.Printf("Байт: %d\n", len(s))
// utf8.RuneCountInString возвращает количество символов
fmt.Printf("Символов: %d\n", utf8.RuneCountInString(s))
// Итерация по рунам
for i, r := range s {
fmt.Printf("Символ %q на байтовом смещении %d\n", r, i)
}
}

Вывод покажет, что строка содержит 20 байт, но 14 символов, а эмодзи 👋 занимает 4 байта.

Как отвечать на собеседовании

Начните с определения: кодировка - это правило преобразования символов в байты. Затем кратко опишите Unicode и code points. Сравните UTF-8 и UTF-16 по трём параметрам: длина, совместимость с ASCII, область применения. Упомяните, что в Go строки - это байты, и покажите понимание разницы между байтами и рунами. Если спросят про конвертацию, скажите, что используете golang.org/x/text/encoding. Не углубляйтесь в детали реализации, если не просят - для junior достаточно базового понимания.

Что проверяет интервьюер

  • Понимание разницы между символами, code points и байтами.
  • Знание, что UTF-8 - стандарт для веба и Go.
  • Умение объяснить, почему len() на строке возвращает байты, а не символы.
  • Осознание проблем с кодировками при работе с внешними данными.
  • Базовое знание инструментов Go для работы с UTF-8 (unicode/utf8, range).

Типичные ошибки

  • Утверждение, что UTF-8 всегда занимает 1 байт на символ - это неверно, длина переменная.
  • Путаница между UTF-8 и Unicode: Unicode - стандарт, UTF-8 - одна из кодировок.
  • Использование len() для подсчёта символов в строке.
  • Игнорирование BOM при чтении UTF-16 файлов.
  • Предположение, что Go автоматически конвертирует строки из других кодировок - это не так, нужна явная конвертация.
  • Забывание, что range по строке возвращает байтовые смещения, а не индексы символов.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью