In-Memory File System with Non-Recursive mkdir and Missing-Path Handling

Quick Overview

Implement an in-memory file system class that lists directories, creates directories without creating missing parents, and appends to and reads files on absolute paths. It tests careful reading of a specification and robust path resolution, including missing directories or files, paths that name a file, and consistent error reporting.

In-Memory File System with Non-Recursive mkdir and Missing-Path Handling

Company: Perplexity

Role: Software Engineer

Category: Software Engineering Fundamentals

Difficulty: medium

Interview Round: Technical Screen

Implement an in-memory file system as a class. It keeps directories and files in memory and answers operations on absolute, Unix-style paths such as `/a/b/c`. The report names `mkdir` and `ls` and likens the task to a well-known problem whose interface also appends content to a file and reads a file back, so the interface below follows that standard form. | Method | Behavior | | --- | --- | | `ls(path) -> list[str]` | If `path` names a directory, return the names of the entries directly inside it, in lexicographic order. `path` may also name a file (see below). | | `mkdir(path) -> None` | Create a new, empty directory at `path`. | | `add_content_to_file(path, content) -> None` | If no file exists at `path`, create one containing `content`; otherwise append `content` to it. | | `read_content_from_file(path) -> str` | Return the full content of the file at `path`. | The version in this round is stricter than the standard form. The report lists the cases below as the ones that failed when the statement was read too quickly: - **Paths that do not exist.** Any operation can receive a path in which a directory along the way, or the target file or directory itself, does not exist. Detect it and respond as the specification requires; never crash. - **`mkdir` is not `mkdir -p`.** Only the last component of the path may be missing. Every parent directory must already exist, and `mkdir` never creates missing parents. - **`ls` on a file.** The path passed to `ls` may name a file rather than a directory. Settle the expected result of each case before writing the methods. An illustrative session, with failures shown as `error` because their exact form is one of the clarifying questions: ```text mkdir("/a") -> ok mkdir("/a/b/c") -> error: /a/b does not exist mkdir("/a/b") -> ok add_content_to_file("/a/b/f", "hi") -> ok, creates the file add_content_to_file("/a/b/f", "!") -> ok, appends read_content_from_file("/a/b/f") -> "hi!" ls("/a") -> ["b"] ls("/a/x") -> error: /a/x does not exist ``` ```hint One way to walk a path Every method starts by walking from the root along the path. Decide what that shared walk returns, and how it reports the two different ways it can fail: a component that is missing, and a component that exists but is a file. ``` ```hint List the failures per method For each method, write down every state the path can be in (missing parent, missing target, target is a file, target is a directory, the root itself) and the agreed result for each, before writing any method body. ``` ### Constraints and Clarifications - Paths are absolute and start with `/`. The path `/` alone is the root directory, which always exists. - Names are non-empty and do not contain `/`. A file and a directory can never have the same path. - Lexicographic order means ordinary string comparison of the names. - How a failed operation is reported was not given; settle it before coding. ### Clarifying Questions - How should a failed operation be reported: an exception, a return value such as `False` or an error string, or a specific message? Must each kind of failure be distinguishable? - What should `ls` return for a path that names a file: a list containing only the file's name, or an error? - What should `mkdir` do when the path already exists, as a directory or as a file? - Does `add_content_to_file` require the parent directory to exist, given that `mkdir` does not create parents? What if the path names an existing directory? - Can paths contain a trailing slash, repeated slashes, `.` or `..`? ### What a Strong Answer Covers - Settles the error contract and the result of every reported edge case before coding - A tree of directory nodes with a clear distinction between files and directories - One path-resolution routine shared by all methods that tells a missing component apart from a file used as a directory, and handles the root - Correct non-recursive `mkdir` and file-creation rules, with no partial changes left behind by a failed call - Sorted listing, the complexity of each operation, and tests for each reported edge case ### Follow-up Questions - Add a `-p` mode to `mkdir` that creates missing parents. If a component halfway along the path is a file, what state can a naive implementation leave behind, and how do you prevent it? - `ls` is called far more often than `mkdir` on directories with many entries. How would you avoid sorting on every call? - Add `rm` and `mv`. What checks does moving a directory need so that it cannot be moved into its own subtree? - How would you make the file system safe for concurrent callers?

Overview: Implement an in-memory file system class that lists directories, creates directories without creating missing parents, and appends to and reads files on absolute paths. It tests careful reading of a specification and robust path resolution, including missing directories or files, paths that name a file, and consistent error reporting.

Perplexity logo
Perplexity
Oct 29, 2026
mediumSoftware EngineerTechnical ScreenSoftware Engineering Fundamentals
0
0

Implement an in-memory file system as a class. It keeps directories and files in memory and answers operations on absolute, Unix-style paths such as /a/b/c. The report names mkdir and ls and likens the task to a well-known problem whose interface also appends content to a file and reads a file back, so the interface below follows that standard form.

MethodBehavior
ls(path) -> list[str]If path names a directory, return the names of the entries directly inside it, in lexicographic order. path may also name a file (see below).
mkdir(path) -> NoneCreate a new, empty directory at path.
add_content_to_file(path, content) -> NoneIf no file exists at path, create one containing content; otherwise append content to it.
read_content_from_file(path) -> strReturn the full content of the file at path.

The version in this round is stricter than the standard form. The report lists the cases below as the ones that failed when the statement was read too quickly:

  • Paths that do not exist. Any operation can receive a path in which a directory along the way, or the target file or directory itself, does not exist. Detect it and respond as the specification requires; never crash.
  • mkdir is not mkdir -p. Only the last component of the path may be missing. Every parent directory must already exist, and mkdir never creates missing parents.
  • ls on a file. The path passed to ls may name a file rather than a directory.

Settle the expected result of each case before writing the methods. An illustrative session, with failures shown as error because their exact form is one of the clarifying questions:

mkdir("/a")                           -> ok
mkdir("/a/b/c")                       -> error: /a/b does not exist
mkdir("/a/b")                         -> ok
add_content_to_file("/a/b/f", "hi")   -> ok, creates the file
add_content_to_file("/a/b/f", "!")    -> ok, appends
read_content_from_file("/a/b/f")      -> "hi!"
ls("/a")                              -> ["b"]
ls("/a/x")                            -> error: /a/x does not exist

Constraints and Clarifications

  • Paths are absolute and start with / . The path / alone is the root directory, which always exists.
  • Names are non-empty and do not contain / . A file and a directory can never have the same path.
  • Lexicographic order means ordinary string comparison of the names.
  • How a failed operation is reported was not given; settle it before coding.

Clarifying Questions Guidance

  • How should a failed operation be reported: an exception, a return value such as False or an error string, or a specific message? Must each kind of failure be distinguishable?
  • What should ls return for a path that names a file: a list containing only the file's name, or an error?
  • What should mkdir do when the path already exists, as a directory or as a file?
  • Does add_content_to_file require the parent directory to exist, given that mkdir does not create parents? What if the path names an existing directory?
  • Can paths contain a trailing slash, repeated slashes, . or .. ?

What a Strong Answer Covers Guidance

  • Settles the error contract and the result of every reported edge case before coding
  • A tree of directory nodes with a clear distinction between files and directories
  • One path-resolution routine shared by all methods that tells a missing component apart from a file used as a directory, and handles the root
  • Correct non-recursive mkdir and file-creation rules, with no partial changes left behind by a failed call
  • Sorted listing, the complexity of each operation, and tests for each reported edge case

Follow-up Questions Guidance

  • Add a -p mode to mkdir that creates missing parents. If a component halfway along the path is a file, what state can a naive implementation leave behind, and how do you prevent it?
  • ls is called far more often than mkdir on directories with many entries. How would you avoid sorting on every call?
  • Add rm and mv . What checks does moving a directory need so that it cannot be moved into its own subtree?
  • How would you make the file system safe for concurrent callers?