Коллекции и работа с данными
Раздел покрывает данные, которые чаще всего пересекают API и границы владения в Go: backing arrays slices, map, UTF-8, сериализацию и время. Каждая тема самостоятельна и содержит код, вопросы и проверяемую практику.
Результат раздела
После изучения раздела можно обосновать выбор структуры, избежать aliasing и data race, корректно обработать текст и внешний формат, а также не смешать duration, timezone и момент времени.
Темы
- Slice: len, cap, append и реаллокация
- Slice: aliasing, copy и удержание памяти
- Map: устройство, ограничения и конкурентный доступ
- Strings: UTF-8, bytes и runes
- bytes.Buffer и strings.Builder
- JSON: encoding/json, теги и custom marshal
- XML, CSV и base64
- Time: time.Time, duration и timezone
Минимум для E4
- Объяснять ownership backing array и назначение
copy/full slice expression. - Выбирать безопасную синхронизацию map и запускать проверку
-race. - Отличать byte, rune и пользовательский grapheme cluster.
- Обрабатывать ошибки кодеков и хранить моменты времени в явной зоне.
Углубление для E5/Senior
Старший инженер рассматривает данные как контракт: фиксирует владение и mutability, вводит лимиты внешнего ввода, отделяет DTO от внутренней модели и подтверждает performance-решения профилем и benchmark. Он также документирует семантику отсутствующего/пустого значения и времени, а не оставляет её случайным свойством библиотеки.
Ключевые понятия
Backing array, aliasing, capacity, comparable key, data race, UTF-8, code point, streaming codec, DTO, UTC, monotonic clock.
Типовые вопросы
- Почему append иногда меняет другой slice?
- Пока оба slice разделяют backing array и у первого есть свободная capacity, запись может попасть в общий массив.
- Можно ли безопасно читать map и писать в него из разных goroutine?
- Нет; синхронизируйте все обращения или используйте подходящую специализированную структуру.
- Почему
len(string)не равно количеству символов?- Это длина в байтах UTF-8, а не в rune или grapheme clusters.
- Когда
omitemptyменяет контракт API?- Когда клиент должен отличать отсутствующее поле от нулевого/пустого значения.
- Почему timestamp лучше хранить в UTC?
- UTC однозначно представляет момент; display zone применяют отдельно.
Практика
- Соберите мини-импорт: CSV → validated DTO → JSON. Готово: вход ограничен, ошибки возвращаются с контекстом, тесты покрывают Unicode и неверную запись.
- Реализуйте cache с map и mutex. Готово:
go test -raceпроходит, наружу не возвращается mutable внутренний map.
Частые ошибки и ловушки
- Считать slice или struct автоматически независимой копией.
- Полагаться на порядок обхода map.
- Использовать base64 как механизм защиты и локальное серверное время как формат хранения.
Связанные темы
Go: язык, runtime и стандартная библиотека · Производительность и память · HTTP и Web