Design an Extensible In-Memory Logger and Keyword Search
Quick Overview
Design an extensible in-memory logger with composable text transformations and ordered keyword search. The interview examines object-oriented boundaries, search semantics, duplicate handling, indexing and caching trade-offs, and consistency under updates.
Design an Extensible In-Memory Logger and Keyword Search
Company: Rippling
Role: Software Engineer
Category: Software Engineering Fundamentals
Difficulty: medium
Interview Round: Technical Screen
## Design an Extensible In-Memory Logger and Keyword Search
Design an object-oriented in-memory logger that can store messages and independently support these transformations: remove a supplied string, truncate to `n` characters, and capitalize a message. Extend it to search logs for a list of keywords and return matching messages without duplicates while preserving order. Then compare read-optimized and write-optimized designs, including the case where duplicate results do not matter.
The prompt does not specify transformation composition order, substring versus token search, any-keyword versus all-keyword matching, or what “duplicate” means. Resolve those contracts before implementation.
### Part 1 — Model Logging and Transformations
Define logger, message, storage, and transformation interfaces. Explain whether transformed or raw messages are stored and how several independent transformations compose.
#### What This Part Should Cover
- Pure transformation behavior and deterministic configured order.
- Exact remove, truncate, and capitalization semantics.
- Validation for negative truncation and empty removal strings.
- Encapsulation of the internal message list.
```hint Separate policy from storage
Transformation objects can change how one message is prepared without making the storage class branch on every operation type.
```
### Part 2 — Search and Preserve Unique Order
Define keyword matching and return the first occurrence of each matching message in insertion order. Cover repeated messages, repeated keywords, empty keyword lists, and case handling.
#### What This Part Should Cover
- A written any-keyword or all-keyword rule.
- Exact message equality or stable message identity for deduplication.
- First-seen order independent of hash iteration order.
- Returned copies or read-only values rather than mutable internal state.
```hint Track membership separately from order
Use one structure to know whether a result was emitted and append results only while scanning in the required order.
```
### Part 3 — Optimize Reads or Writes
Compare scanning, an inverted index, and query-result caching. State which keyword semantics the index supports and how appends invalidate or incrementally update derived state.
#### What This Part Should Cover
- Write-cheap scanning for small or infrequent queries.
- Token-to-message postings only when search uses the same tokenizer.
- Query cache keys containing all search semantics and a log generation.
- Time and space costs in messages, text bytes, keywords, and matches.
```hint An index must match the predicate
A token index cannot answer arbitrary substring queries exactly without verification or a different text index.
```
### Part 4 — Change the Duplicate Contract
Explain what becomes simpler if duplicate messages may appear in results, and what remains necessary for keyword search and ordering.
#### What This Part Should Cover
- Removal of result-level seen-state when duplicates are allowed.
- Postings that retain message occurrences rather than only message text.
- Stable insertion order for each occurrence.
- No accidental deduplication caused by using a set as the result container.
```hint Preserve occurrence identity
Two equal strings at different log positions remain two results when duplicate output is allowed.
```
### What a Strong Answer Covers
- Small composable classes with explicit string semantics.
- Deterministic matching, deduplication, and output order.
- Honest index and cache trade-offs tied to the actual search predicate.
- A clear distinction between equal message values and distinct stored occurrences.
### Follow-up Questions
1. How would truncation work for Unicode code points or grapheme clusters?
2. How would you remove or edit an existing log entry without rebuilding every index?
3. Which design would you choose for many writes and rare searches?
4. How would concurrent readers observe a consistent message and index generation?
Quick Answer: Design an extensible in-memory logger with composable text transformations and ordered keyword search. The interview examines object-oriented boundaries, search semantics, duplicate handling, indexing and caching trade-offs, and consistency under updates.
Design an Extensible In-Memory Logger and Keyword Search
Design an object-oriented in-memory logger that can store messages and independently support these transformations: remove a supplied string, truncate to n characters, and capitalize a message. Extend it to search logs for a list of keywords and return matching messages without duplicates while preserving order. Then compare read-optimized and write-optimized designs, including the case where duplicate results do not matter.
The prompt does not specify transformation composition order, substring versus token search, any-keyword versus all-keyword matching, or what “duplicate” means. Resolve those contracts before implementation.
Part 1 — Model Logging and Transformations
Define logger, message, storage, and transformation interfaces. Explain whether transformed or raw messages are stored and how several independent transformations compose.
What This Part Should Cover Guidance
Pure transformation behavior and deterministic configured order.
Exact remove, truncate, and capitalization semantics.
Validation for negative truncation and empty removal strings.
Encapsulation of the internal message list.
Part 2 — Search and Preserve Unique Order
Define keyword matching and return the first occurrence of each matching message in insertion order. Cover repeated messages, repeated keywords, empty keyword lists, and case handling.
What This Part Should Cover Guidance
A written any-keyword or all-keyword rule.
Exact message equality or stable message identity for deduplication.
First-seen order independent of hash iteration order.
Returned copies or read-only values rather than mutable internal state.
Part 3 — Optimize Reads or Writes
Compare scanning, an inverted index, and query-result caching. State which keyword semantics the index supports and how appends invalidate or incrementally update derived state.
What This Part Should Cover Guidance
Write-cheap scanning for small or infrequent queries.
Token-to-message postings only when search uses the same tokenizer.
Query cache keys containing all search semantics and a log generation.
Time and space costs in messages, text bytes, keywords, and matches.
Part 4 — Change the Duplicate Contract
Explain what becomes simpler if duplicate messages may appear in results, and what remains necessary for keyword search and ordering.
What This Part Should Cover Guidance
Removal of result-level seen-state when duplicates are allowed.
Postings that retain message occurrences rather than only message text.
Stable insertion order for each occurrence.
No accidental deduplication caused by using a set as the result container.
What a Strong Answer Covers Guidance
Small composable classes with explicit string semantics.
Deterministic matching, deduplication, and output order.
Honest index and cache trade-offs tied to the actual search predicate.
A clear distinction between equal message values and distinct stored occurrences.
Follow-up Questions Guidance
How would truncation work for Unicode code points or grapheme clusters?
How would you remove or edit an existing log entry without rebuilding every index?
Which design would you choose for many writes and rare searches?
How would concurrent readers observe a consistent message and index generation?