← Назад к вопросам

Что такое сериализация?

1.0 Junior🔥 181 комментариев
#Язык C++

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI29 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое сериализация?

Сериализация — это процесс преобразования структур данных в памяти в последовательность байтов (поток данных) для хранения в файл, передачи по сети или в другой среде передачи данных. Обратный процесс — десериализация — восстанавливает исходную структуру из байтов.

Концепция сериализации

Serialization: In-Memory Object → Stream of Bytes Deserialization: Stream of Bytes → Restored Object

Зачем нужна сериализация?

  1. Сохранение состояния: запись данных в файл
  2. Передача по сети: отправка объектов клиент-серверу
  3. Кеширование: хранение результатов в памяти или Redis
  4. Дифференцирование протоколов: общий формат данных между сервисами
  5. Database storage: сохранение сложных структур в БД

Простой пример сериализации в C++

struct Person {
    std::string name;
    int age;
    double salary;
};

// Ручная сериализация в вектор байтов
std::vector<uint8_t> serialize(const Person& person) {
    std::vector<uint8_t> buffer;
    
    // Сериализуем name (длина + содержимое)
    uint32_t name_len = person.name.size();
    buffer.insert(buffer.end(), 
                  (uint8_t*)&name_len, 
                  (uint8_t*)&name_len + sizeof(name_len));
    buffer.insert(buffer.end(), 
                  person.name.begin(), 
                  person.name.end());
    
    // Сериализуем age
    buffer.insert(buffer.end(), 
                  (uint8_t*)&person.age, 
                  (uint8_t*)&person.age + sizeof(person.age));
    
    return buffer;
}

Person deserialize(const std::vector<uint8_t>& buffer) {
    Person person;
    size_t offset = 0;
    
    uint32_t name_len = *(uint32_t*)(buffer.data() + offset);
    offset += sizeof(name_len);
    
    person.name = std::string((char*)(buffer.data() + offset), name_len);
    offset += name_len;
    
    person.age = *(int*)(buffer.data() + offset);
    
    return person;
}

Форматы сериализации

Бинарные форматы (компактные, быстрые):

  • Protocol Buffers (Google): компактный, типизированный, с версионированием
  • Thrift (Apache): кроссплатформенный RPC фреймворк
  • MessagePack: компактный JSON-подобный формат
  • Flatbuffers: очень быстрый доступ без распаковки

Текстовые форматы (читаемые, менее компактные):

  • JSON: человеко-читаемый, универсальный
  • XML: структурированный, валидируемый
  • YAML: читаемый конфиг-формат
  • CSV: табличные данные
// JSON сериализация (с библиотекой nlohmann/json)
#include <nlohmann/json.hpp>
using json = nlohmann::json;

json j = {
    {"name", "Alice"},
    {"age", 28},
    {"salary", 4500.0}
};

std::cout << j.dump(2) << std::endl;

Проблемы при сериализации

1. Endianness (порядок байтов):

  • Big-endian vs Little-endian
  • Решение: использовать protocolы типа Protocol Buffers

2. Версионирование:

  • При изменении структуры нужна совместимость
  • Решение: версия в заголовке сообщения

3. Обработка указателей и ссылок:

  • Нельзя просто сохранить адрес памяти
  • Решение: сериализовать всю связанную структуру рекурсивно

Когда использовать какой формат

ФорматИспользованиеПлюсыМинусы
JSONREST API, конфигиЧитаемый, универсальныйМедленнее, больше размер
Protocol Buffersмикросервисы, gRPCБыстро, компактноНужна schema
BinaryФайлы, базы данныхОчень быстро, компактноСложно отладить
MessagePackКеш, сетьБыстро, компактноМенее стандартизовано