Build an In-Memory Filesystem Class with Directories, Listing and File Contents
Company: Harvey
Role: Software Engineer
Category: Software Engineering Fundamentals
Difficulty: medium
Interview Round: Onsite
In an AI-assisted coding round, where you may use an AI coding assistant, implement an in-memory file system. The report names only the feature, so the interface below is a common starting scope to confirm with the interviewer before building it:
```python
class FileSystem:
def mkdir(self, path: str) -> None: ...
def add_content(self, path: str, content: str) -> None: ...
def read(self, path: str) -> str: ...
def ls(self, path: str) -> list[str]: ...
```
- `mkdir(path)` creates the directory at `path`, together with any missing parent directories.
- `add_content(path, content)` appends `content` to the file at `path`, creating the file if it does not exist.
- `read(path)` returns the file's full content.
- `ls(path)` returns, for a directory, the names of its direct children in lexicographic order, and for a file, a list containing only that file's name.
Paths are absolute and use `/` as the separator, for example `/docs/notes.txt`; `/` alone is the root directory. Partway through the round the interviewer also asked design questions about the system around the feature, so be ready to discuss how your design would change beyond a single process.
```hint One node type or two
Decide what each node in the tree must store so that the same path-walking code serves all four operations.
```
```hint Every way a path can be wrong
For each operation, list how a path can fail: a missing parent, a file where a directory is expected, a directory where a file is expected. Decide what the caller sees in each case.
```
### Clarifying Questions
- Should `add_content` create missing parent directories, or fail when the parent does not exist?
- What should happen when a path uses a file as a directory, for example `mkdir("/a.txt/b")` after `/a.txt` was created as a file?
- Must paths be normalized: repeated slashes, a trailing slash, `.` and `..`?
- Are delete, move or rename needed, and must the class be safe to call from several threads?
- What should `ls` and `read` do for a path that does not exist?
### What a Strong Answer Covers
- A tree model with clear file and directory semantics, and lookups whose cost grows with the path depth rather than the total number of files
- Explicit error behavior for missing paths and for file and directory mix-ups
- Correct sorted listing, root handling and path parsing
- Tests for the main operations and the edge cases, written or reviewed by the candidate rather than accepted from the assistant unread
- Effective use of the AI assistant: a precise specification, small steps and review of the generated code
- Reasoning about concurrency, persistence and scale when the discussion turns to design
### Follow-up Questions
- Two threads call `add_content` on the same file and `mkdir` on overlapping paths at the same time. What can go wrong, and how do you lock?
- The process must survive restarts without losing data. How would you persist the tree?
- A directory with millions of entries makes `ls` slow. What changes?
- How would you add `move(src, dst)` for directories, and what makes it tricky?
Overview: Implement an in-memory file system class in an AI-assisted coding round, supporting directory creation, listing, appending to files and reading them by absolute path. It tests tree modeling, path parsing, precise error semantics and verifying assistant-written code with tests, with follow-ups on concurrency, persistence and scale.