PracHub
QuestionsPremiumCoachesLearningGuidesInterview Prep

Quick Overview

This question evaluates a candidate's ability to implement a TCP-based in-memory key-value store, exercising skills in network I/O, protocol parsing, byte-level data handling, and state management.

  • medium
  • Reddit
  • Coding & Algorithms
  • Machine Learning Engineer

Implement a simplified memcached server

Company: Reddit

Role: Machine Learning Engineer

Category: Coding & Algorithms

Difficulty: medium

Interview Round: Technical Screen

Implement a simplified in-memory key-value store that speaks a small text protocol inspired by memcached. The server stores keys and raw byte values in memory. Clients connect over TCP, typically on port `11211`, and send ASCII command lines separated by a line-feed character `\n`. Commands are case-sensitive. You may use only the standard library. Key rules: - A valid key contains one or more characters matching `[A-Za-z0-9_-]+`. - Values may be arbitrary bytes. Supported commands: 1. `get <key>` Look up the given key and return its stored value if it exists. If the key exists, respond exactly in this format: ```text VALUE <key> <byte_count>\n <raw value bytes>\n END\n ``` Here, `<byte_count>` is the number of bytes in the raw value. If the key does not exist, respond with: ```text END\n ``` Example: ```text Client: get does_not_exist\n Server: END\n ``` 2. `set <key> <byte_count>` Store a value under the given key. After the command line, the client sends exactly `<byte_count>` bytes of raw data followed by a newline. After storing the value, respond with: ```text STORED\n ``` Bonus: Support multi-key reads: ```text get <key1> <key2> ... <keyN> ``` The response should contain one `VALUE` block for each existing key, followed by one final `END\n`. Missing keys should simply be omitted from the response.

Quick Answer: This question evaluates a candidate's ability to implement a TCP-based in-memory key-value store, exercising skills in network I/O, protocol parsing, byte-level data handling, and state management.

Part 1: Single-Key Memcached Protocol Simulator

Implement the core of a simplified in-memory memcached-like server for one client connection. Instead of opening sockets, your function receives the entire byte stream sent by a client and must return the concatenated byte stream that the server would send back. The store starts empty. Supported commands are case-sensitive ASCII command lines ending with LF (`\n`). A valid key matches `[A-Za-z0-9_-]+`. For `get <key>`, return the stored value if present, otherwise return `END\n`. For `set <key> <byte_count>`, read exactly `<byte_count>` raw bytes after the command line, then consume the following newline, store those bytes under the key, and return `STORED\n`. Values may contain arbitrary bytes, including newline bytes, so parsing must use `byte_count` rather than searching for the next newline inside the value.

Constraints

  • 0 <= len(requests) <= 200000
  • All command lines are well-formed and end with `\n`.
  • Keys contain one or more characters matching `[A-Za-z0-9_-]+`.
  • For Part 1, each `get` command has exactly one key.
  • For each `set`, `0 <= byte_count`, and exactly `byte_count` raw value bytes are followed by one newline byte.
  • The key-value store starts empty for each call to `solution`.

Examples

Input: (b'',)

Expected Output: b''

Explanation: empty stream returns empty response

Input: (b'get does_not_exist\n',)

Expected Output: b'END\n'

Explanation: get on a missing key returns END

Input: (b'set greeting 5\nhello\nget greeting\n',)

Expected Output: b'STORED\nVALUE greeting 5\nhello\nEND\n'

Explanation: store then retrieve a 5-byte value

Input: (b'set empty 0\n\nget empty\n',)

Expected Output: b'STORED\nVALUE empty 0\n\nEND\n'

Explanation: store a zero-length value then retrieve it

Input: (b'set bin 3\na\nb\nget bin\n',)

Expected Output: b'STORED\nVALUE bin 3\na\nb\nEND\n'

Explanation: value containing a newline byte is parsed by byte_count, not by scanning for the next newline

Input: (b'set k 1\nA\nset k 1\nB\nget k\n',)

Expected Output: b'STORED\nSTORED\nVALUE k 1\nB\nEND\n'

Explanation: overwriting a key keeps only the latest value

Input: (b'set blob 5\nx\ny\nz\nget blob\nget missing\n',)

Expected Output: b'STORED\nVALUE blob 5\nx\ny\nz\nEND\nEND\n'

Explanation: multi-newline value, then a hit followed by a miss

Input: (b'set big 1000\nqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq\nget big\n',)

Expected Output: b'STORED\nVALUE big 1000\nqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq\nEND\n'

Explanation: large 1000-byte value round-trips through set/get

Input: (b'set a 1\n1\nset b 2\n22\nget a\nget b\nget c\n',)

Expected Output: b'STORED\nSTORED\nVALUE a 1\n1\nEND\nVALUE b 2\n22\nEND\nEND\n'

Explanation: multiple interleaved keys, two hits and one miss

Hints

  1. Maintain an index into the byte stream. Use newline search only for command lines, not for value bodies.
  2. After a `set` line, slice exactly `byte_count` bytes for the value, then advance one more byte for the required trailing newline.

Part 2: Multi-Key Memcached Protocol Simulator

Extend the simplified in-memory memcached-like protocol simulator to support multi-key reads. As in Part 1, your function receives the entire byte stream sent by one client and returns the concatenated server byte stream. The store starts empty. Supported commands are `set <key> <byte_count>` and `get <key1> <key2> ... <keyN>`. A valid key matches `[A-Za-z0-9_-]+`. For a multi-key `get`, output one `VALUE` block for each requested key token that exists, in request order, then output one final `END\n`. Missing keys are omitted. If the same existing key appears multiple times in one `get`, output its `VALUE` block each time it appears. Values may contain arbitrary bytes, including newline bytes, so `set` parsing must read exactly `byte_count` bytes.

Constraints

  • 0 <= len(requests) <= 200000
  • All command lines are well-formed and end with `\n`.
  • Keys contain one or more characters matching `[A-Za-z0-9_-]+`.
  • Each `get` command contains at least one key and may contain multiple keys.
  • For each `set`, `0 <= byte_count`, and exactly `byte_count` raw value bytes are followed by one newline byte.
  • The key-value store starts empty for each call to `solution`.

Examples

Input: (b'',)

Expected Output: b''

Explanation: Empty input: empty store, no commands -> empty output.

Input: (b'set a 1\nA\nset b 2\nBB\nget b missing a\n',)

Expected Output: b'STORED\nSTORED\nVALUE b 2\nBB\nVALUE a 1\nA\nEND\n'

Explanation: Multi-key get: existing keys emitted in request order, missing omitted, single END.

Input: (b'get x y z\n',)

Expected Output: b'END\n'

Explanation: Get on empty store: all keys missing, only END.

Input: (b'set x 1\nZ\nget x x\n',)

Expected Output: b'STORED\nVALUE x 1\nZ\nVALUE x 1\nZ\nEND\n'

Explanation: Repeated existing key in one get emits its VALUE block each time.

Input: (b'set empty 0\n\nset c 1\nC\nget empty c nope\n',)

Expected Output: b'STORED\nSTORED\nVALUE empty 0\n\nVALUE c 1\nC\nEND\n'

Explanation: Zero-length value read correctly; missing key omitted.

Input: (b'set k 5\nab\ncd\nget k\n',)

Expected Output: b'STORED\nVALUE k 5\nab\ncd\nEND\n'

Explanation: Value contains a newline byte; set must read exactly byte_count bytes across the embedded newline.

Input: (b'get only\n',)

Expected Output: b'END\n'

Explanation: Single get on empty store with one missing key -> just END.

Input: (b'set key0 3\nv00\nset key1 3\nv01\nset key2 3\nv02\nset key3 3\nv03\nset key4 3\nv04\nset key5 3\nv05\nset key6 3\nv06\nset key7 3\nv07\nset key8 3\nv08\nset key9 3\nv09\nset key10 3\nv10\nset key11 3\nv11\nset key12 3\nv12\nset key13 3\nv13\nset key14 3\nv14\nset key15 3\nv15\nset key16 3\nv16\nset key17 3\nv17\nset key18 3\nv18\nset key19 3\nv19\nset key20 3\nv20\nset key21 3\nv21\nset key22 3\nv22\nset key23 3\nv23\nset key24 3\nv24\nset key25 3\nv25\nset key26 3\nv26\nset key27 3\nv27\nset key28 3\nv28\nset key29 3\nv29\nset key30 3\nv30\nset key31 3\nv31\nset key32 3\nv32\nset key33 3\nv33\nset key34 3\nv34\nset key35 3\nv35\nset key36 3\nv36\nset key37 3\nv37\nset key38 3\nv38\nset key39 3\nv39\nset key40 3\nv40\nset key41 3\nv41\nset key42 3\nv42\nset key43 3\nv43\nset key44 3\nv44\nset key45 3\nv45\nset key46 3\nv46\nset key47 3\nv47\nset key48 3\nv48\nset key49 3\nv49\nget key0 key1 key2 key3 key4 key5 key6 key7 key8 key9 key10 key11 key12 key13 key14 key15 key16 key17 key18 key19 key20 key21 key22 key23 key24 key25 key26 key27 key28 key29 key30 key31 key32 key33 key34 key35 key36 key37 key38 key39 key40 key41 key42 key43 key44 key45 key46 key47 key48 key49 missing key0 key2 key4 key6 key8 key10 key12 key14 key16 key18 key20 key22 key24 key26 key28 key30 key32 key34 key36 key38 key40 key42 key44 key46 key48\n',)

Expected Output: b'STORED\nSTORED\nSTORED\nSTORED\nSTORED\nSTORED\nSTORED\nSTORED\nSTORED\nSTORED\nSTORED\nSTORED\nSTORED\nSTORED\nSTORED\nSTORED\nSTORED\nSTORED\nSTORED\nSTORED\nSTORED\nSTORED\nSTORED\nSTORED\nSTORED\nSTORED\nSTORED\nSTORED\nSTORED\nSTORED\nSTORED\nSTORED\nSTORED\nSTORED\nSTORED\nSTORED\nSTORED\nSTORED\nSTORED\nSTORED\nSTORED\nSTORED\nSTORED\nSTORED\nSTORED\nSTORED\nSTORED\nSTORED\nSTORED\nSTORED\nVALUE key0 3\nv00\nVALUE key1 3\nv01\nVALUE key2 3\nv02\nVALUE key3 3\nv03\nVALUE key4 3\nv04\nVALUE key5 3\nv05\nVALUE key6 3\nv06\nVALUE key7 3\nv07\nVALUE key8 3\nv08\nVALUE key9 3\nv09\nVALUE key10 3\nv10\nVALUE key11 3\nv11\nVALUE key12 3\nv12\nVALUE key13 3\nv13\nVALUE key14 3\nv14\nVALUE key15 3\nv15\nVALUE key16 3\nv16\nVALUE key17 3\nv17\nVALUE key18 3\nv18\nVALUE key19 3\nv19\nVALUE key20 3\nv20\nVALUE key21 3\nv21\nVALUE key22 3\nv22\nVALUE key23 3\nv23\nVALUE key24 3\nv24\nVALUE key25 3\nv25\nVALUE key26 3\nv26\nVALUE key27 3\nv27\nVALUE key28 3\nv28\nVALUE key29 3\nv29\nVALUE key30 3\nv30\nVALUE key31 3\nv31\nVALUE key32 3\nv32\nVALUE key33 3\nv33\nVALUE key34 3\nv34\nVALUE key35 3\nv35\nVALUE key36 3\nv36\nVALUE key37 3\nv37\nVALUE key38 3\nv38\nVALUE key39 3\nv39\nVALUE key40 3\nv40\nVALUE key41 3\nv41\nVALUE key42 3\nv42\nVALUE key43 3\nv43\nVALUE key44 3\nv44\nVALUE key45 3\nv45\nVALUE key46 3\nv46\nVALUE key47 3\nv47\nVALUE key48 3\nv48\nVALUE key49 3\nv49\nVALUE key0 3\nv00\nVALUE key2 3\nv02\nVALUE key4 3\nv04\nVALUE key6 3\nv06\nVALUE key8 3\nv08\nVALUE key10 3\nv10\nVALUE key12 3\nv12\nVALUE key14 3\nv14\nVALUE key16 3\nv16\nVALUE key18 3\nv18\nVALUE key20 3\nv20\nVALUE key22 3\nv22\nVALUE key24 3\nv24\nVALUE key26 3\nv26\nVALUE key28 3\nv28\nVALUE key30 3\nv30\nVALUE key32 3\nv32\nVALUE key34 3\nv34\nVALUE key36 3\nv36\nVALUE key38 3\nv38\nVALUE key40 3\nv40\nVALUE key42 3\nv42\nVALUE key44 3\nv44\nVALUE key46 3\nv46\nVALUE key48 3\nv48\nEND\n'

Explanation: Large input: 50 sets then a multi-key get of all keys plus a missing key plus repeats, preserving request order and duplicates.

Input: (b'set d 2\n\nX\nset d 1\nQ\nget d\n',)

Expected Output: b'STORED\nSTORED\nVALUE d 1\nQ\nEND\n'

Explanation: Overwrite: re-setting an existing key replaces the value (value also starts with a newline byte).

Hints

  1. The single-key `get` logic becomes a loop over all key tokens after the command name.
  2. Append `END\n` once per `get` command, after all existing keys have been emitted.
Last updated: Jun 13, 2026

Loading coding console...

PracHub

Master your tech interviews with 8,000+ real questions from top companies.

Product

  • Questions
  • Learning Tracks
  • Interview Guides
  • Resources
  • Premium
  • For Universities
  • Student Access

Browse

  • By Company
  • By Role
  • By Category
  • Topic Hubs
  • SQL Questions
  • Compare Platforms
  • Discord Community

Support

  • support@prachub.com
  • (916) 541-4762

Legal

  • Privacy Policy
  • Terms of Service
  • About Us

© 2026 PracHub. All rights reserved.

Related Coding Questions

  • Moderator System with Ranking, Communities, and Demotion - Reddit (medium)
  • Solve palindrome and list tasks - Reddit (hard)
  • Merge Message Context Windows - Reddit (medium)
  • Implement a sliding-window rate limiter - Reddit (medium)
  • Find word sequence with 1–2 char changes - Reddit (Medium)