Что такое сериализация и десериализация
Что проверяют
Понимаете ли вы, что в C++ нет рефлексии, и поэтому сериализация всегда пишется руками либо генерируется по схеме. За вопросом стоит умение выбрать формат и не сломаться на указателях, выравнивании и совместимости версий.
Как отвечать
Сериализация это перевод объекта в последовательность байтов, пригодную для файла, сокета или строки в базе. Десериализация это обратный разбор в живой объект. Формулировка про плоский поток байтов важнее перечисления библиотек.
Дальше про специфику языка: компилятор не оставляет в рантайме описания полей, поэтому путей три. Писать пару функций на каждый тип руками. Описать поля один раз и получить обе стороны шаблоном, обходящим список полей. Взять схему и кодогенерацию, например Protobuf, FlatBuffers или Cap'n Proto.
void save(std::ostream& os, const User& u) {
uint32_t n = static_cast<uint32_t>(u.name.size());
os.write(reinterpret_cast<const char*>(&n), sizeof n);
os.write(u.name.data(), n);
}Текстовые форматы (JSON, XML) читаемы и терпимы к изменениям схемы, бинарные компактнее и быстрее. Обязательно скажите про версионирование: в поток кладётся номер схемы, иначе первое же добавленное поле делает старые файлы нечитаемыми.
Где спотыкаются
Копируют структуру в файл через memcpy. Это работает, пока внутри только POD, и ломается на std::string, векторах и указателях: в поток уедет адрес чужой кучи, а после чтения получится висячий указатель.
Забывают про выравнивание и порядок байтов. Дыры между полями и разный endianness делают дамп непереносимым между платформами и даже между сборками, поэтому в бинарном формате поля пишут по одному и фиксированными по ширине типами.
Не проверяют данные при разборе. Длина строки, прочитанная из потока, это недоверенное число: без верхней границы одна испорченная запись превращается в гигантский resize или в чтение за границей буфера, и это уже не баг, а уязвимость.