Serialize and Deserialize an In-Memory Key-Value Store

Quick Overview

Implement serialize and deserialize functions for an in-memory key-value store so that every store, including keys and values with separator characters, empty strings or non-ASCII text, survives a round trip. It tests unambiguous format design, text encoding, error handling and test design.

Serialize and Deserialize an In-Memory Key-Value Store

Company: ByteDance

Role: Software Engineer

Category: Software Engineering Fundamentals

Difficulty: medium

Interview Round: Onsite

Implement serialization and deserialization for an in-memory key-value store. `serialize` turns the store's contents into a single string or byte sequence that can be written to a file or sent over the network, and `deserialize` turns that output back into a store equal to the original. Only the task itself was reported, so the format is yours to design and justify. Assume to start that keys and values are strings, that they may be empty, and that they may contain any character, including any separator you might choose. ```python def serialize(store: dict[str, str]) -> bytes: ... def deserialize(data: bytes) -> dict[str, str]: ... ``` ```text store = {"user:1": "alice", "note": "a=b;c\nd", "empty": ""} deserialize(serialize(store)) == store -> True ``` ```hint Separators appear in the data Decide how the reader can tell where one key or value ends when the data itself may contain any character you pick as a separator. ``` ```hint Break your own format List the inputs most likely to break a round trip, such as empty strings, separators inside values and non-ASCII text, and check your format against each of them before writing code. ``` ### Constraints and Clarifications - Not given: value types beyond strings, the size of the store, whether the output must be human-readable, and whether files written today must stay readable by future versions of the code. Ask, or state your assumptions. ### Clarifying Questions - Are keys and values only strings, or can values be numbers, lists or nested maps? - Must the output be human-readable, or is a compact binary format acceptable? - Is the whole store serialized at once, or must the format support streaming a large store or appending changes? - Must the format survive changes to the code, such as new fields per entry, and should it detect corrupted or truncated input? - Must equal stores always produce identical output, for example so that outputs can be compared or checksummed? ### What a Strong Answer Covers - A format that is unambiguous for arbitrary keys and values, with an argument for why the reader can never misparse it - Correct handling of empty strings, separator characters and multi-byte text - Clean `serialize` and `deserialize` code that rejects malformed or truncated input instead of returning a wrong store - Time and space complexity, and at least one alternative format with its trade-offs, including when an existing format is the better choice - Tests, including a round-trip property checked over many generated stores ### Follow-up Questions - Values can now be integers, lists or nested maps. How does the format change? - How does `deserialize` detect a file that was truncated or corrupted on disk? - A later version of the code adds an expiry time to each entry. How do older and newer readers cope with files written by the other version? - The store is too large to build the whole output in memory, and writes continue while it is being saved. How do you produce a consistent snapshot?

Overview: Implement serialize and deserialize functions for an in-memory key-value store so that every store, including keys and values with separator characters, empty strings or non-ASCII text, survives a round trip. It tests unambiguous format design, text encoding, error handling and test design.

ByteDance logo
ByteDance
May 15, 2026
mediumSoftware EngineerOnsiteSoftware Engineering Fundamentals
0
0

Implement serialization and deserialization for an in-memory key-value store. serialize turns the store's contents into a single string or byte sequence that can be written to a file or sent over the network, and deserialize turns that output back into a store equal to the original. Only the task itself was reported, so the format is yours to design and justify.

Assume to start that keys and values are strings, that they may be empty, and that they may contain any character, including any separator you might choose.

def serialize(store: dict[str, str]) -> bytes: ...
def deserialize(data: bytes) -> dict[str, str]: ...
store = {"user:1": "alice", "note": "a=b;c\nd", "empty": ""}
deserialize(serialize(store)) == store    ->  True

Constraints and Clarifications

  • Not given: value types beyond strings, the size of the store, whether the output must be human-readable, and whether files written today must stay readable by future versions of the code. Ask, or state your assumptions.

Clarifying Questions Guidance

  • Are keys and values only strings, or can values be numbers, lists or nested maps?
  • Must the output be human-readable, or is a compact binary format acceptable?
  • Is the whole store serialized at once, or must the format support streaming a large store or appending changes?
  • Must the format survive changes to the code, such as new fields per entry, and should it detect corrupted or truncated input?
  • Must equal stores always produce identical output, for example so that outputs can be compared or checksummed?

What a Strong Answer Covers Guidance

  • A format that is unambiguous for arbitrary keys and values, with an argument for why the reader can never misparse it
  • Correct handling of empty strings, separator characters and multi-byte text
  • Clean serialize and deserialize code that rejects malformed or truncated input instead of returning a wrong store
  • Time and space complexity, and at least one alternative format with its trade-offs, including when an existing format is the better choice
  • Tests, including a round-trip property checked over many generated stores

Follow-up Questions Guidance

  • Values can now be integers, lists or nested maps. How does the format change?
  • How does deserialize detect a file that was truncated or corrupted on disk?
  • A later version of the code adds an expiry time to each entry. How do older and newer readers cope with files written by the other version?
  • The store is too large to build the whole output in memory, and writes continue while it is being saved. How do you produce a consistent snapshot?