Implement an In-Memory File Storage Class with Unique IDs and Duplicate-Name Suffixes

Read the full interview experience this question came from →

Quick Overview

Implement an in-memory FileStorage class with upload, get, delete and list methods, where every upload receives a unique id and duplicate file names get a suffix. Tests class design, name-collision edge cases, error handling and writing your own tests with no starter code or harness.

Implement an In-Memory File Storage Class with Unique IDs and Duplicate-Name Suffixes

Company: Cresta

Role: Software Engineer

Category: Software Engineering Fundamentals

Difficulty: medium

Interview Round: Technical Screen

Implement an in-memory file storage service as a single class, `FileStorage`, in a language of your choice. The interviewer gives only the description below: there is no starter code and no test code, so how the class is organised and how it is tested are entirely up to you. The description was recalled after the interview, so details may differ slightly from the original. ```python class FileStorage: def upload_file(self, file_name: str, file_content: bytes) -> str: ... def get_file(self, file_id: str) -> bytes: ... def delete_file(self, file_id: str) -> bool: ... def get_all_files(self) -> list[dict]: ... ``` - `upload_file` stores the file and returns a unique `file_id`. If a file with the same name already exists, a suffix is added to the new file's name. - `get_file` returns the file's content and raises an error if the file does not exist. - `delete_file` deletes the file and returns `True`, or returns `False` if the file did not exist. - `get_all_files` returns metadata for every stored file as a list of dictionaries of the form `{"file_id": ..., "file_name": ..., "file_size": ..., "upload_timestamp": ...}`. The round lasts about 60 minutes in a shared online editor, introductions included, so the time for writing and testing the code is shorter than that. ### Clarifying Questions - What exact suffix should a duplicate name receive (for example `report (1).txt` or `report_1.txt`), and does it go before the file extension? - Once a file is deleted, may a later upload reuse its name? May its `file_id` ever be reused? - If `report.txt` and `report (1).txt` are both stored and `report (1).txt` is uploaded again, what name should the new file get? - In what order should `get_all_files` list the files, and what unit or format should `upload_timestamp` use (epoch seconds, milliseconds, an ISO 8601 string)? - Which error should `get_file` raise for an unknown id, and should invalid input, such as an empty name or content that is not bytes, be rejected? - Is single-threaded use enough, or can several callers upload and delete at the same time? ### Part 1 — Implement FileStorage Implement the four methods with the behaviour described above. Decide how file ids are generated, how a duplicate name is made unique, and which data structures hold the files and their metadata. ```hint Two kinds of lookup Three of the methods find a file by its id, but the duplicate check finds a file by its name. Decide which lookups must be fast and what structure serves each one. ``` ```hint A name that already looks suffixed Consider a user who uploads a file whose name already ends the way one of your generated names would. ``` #### What This Part Should Cover - Data structures for lookups by id and by name, kept consistent on every upload and delete - An explicit unique-name rule: suffix format, position relative to the extension, and names freed by deletion - Id generation that never repeats, and file size and timestamp captured at upload - Clear error behaviour for unknown ids and invalid arguments ### Part 2 — Test it without a harness No test code is provided. Write the tests you would run before the round ends, and make the class testable, including the timestamp. ```hint Control the clock Think about how a test can assert an exact `upload_timestamp` without sleeping or reading the real time. ``` #### What This Part Should Cover - A test for the normal path and the failure path of each method - Duplicate-name cases: second and third uploads of one name, names without an extension, and a name freed by deletion - An injected clock, and optionally an injected id generator, so that expected values are exact - Pacing: tests written and run as the methods appear, not left for the last minute ### What a Strong Answer Covers - Raises the unresolved rules (suffix format, name reuse, list order, timestamp format) and settles them before coding - A small, readable class whose id and name indexes can never disagree - Correct suffixing in the edge cases, including collisions with names that already carry a suffix - Tests that actually run within the time box, rather than finished code that was never executed - Complexity of each method, and what would change for very large files or concurrent callers ### Follow-up Questions - How would you make the class safe when several threads upload and delete files at once? - Files can be several gigabytes. How would you change the storage and the signatures of `upload_file` and `get_file`? - How would you avoid storing the same bytes twice when different file names hold identical content? - How would you persist the files so that they survive a restart of the process?

Overview: Implement an in-memory FileStorage class with upload, get, delete and list methods, where every upload receives a unique id and duplicate file names get a suffix. Tests class design, name-collision edge cases, error handling and writing your own tests with no starter code or harness.

Read the full Cresta Software Engineer interview experience this question came from

Cresta logo
Cresta
Oct 26, 2026
mediumSoftware EngineerTechnical ScreenSoftware Engineering Fundamentals
0
0

Implement an in-memory file storage service as a single class, FileStorage, in a language of your choice. The interviewer gives only the description below: there is no starter code and no test code, so how the class is organised and how it is tested are entirely up to you. The description was recalled after the interview, so details may differ slightly from the original.

class FileStorage:
    def upload_file(self, file_name: str, file_content: bytes) -> str: ...
    def get_file(self, file_id: str) -> bytes: ...
    def delete_file(self, file_id: str) -> bool: ...
    def get_all_files(self) -> list[dict]: ...
  • upload_file stores the file and returns a unique file_id . If a file with the same name already exists, a suffix is added to the new file's name.
  • get_file returns the file's content and raises an error if the file does not exist.
  • delete_file deletes the file and returns True , or returns False if the file did not exist.
  • get_all_files returns metadata for every stored file as a list of dictionaries of the form {"file_id": ..., "file_name": ..., "file_size": ..., "upload_timestamp": ...} .

The round lasts about 60 minutes in a shared online editor, introductions included, so the time for writing and testing the code is shorter than that.

Clarifying Questions Guidance

  • What exact suffix should a duplicate name receive (for example report (1).txt or report_1.txt ), and does it go before the file extension?
  • Once a file is deleted, may a later upload reuse its name? May its file_id ever be reused?
  • If report.txt and report (1).txt are both stored and report (1).txt is uploaded again, what name should the new file get?
  • In what order should get_all_files list the files, and what unit or format should upload_timestamp use (epoch seconds, milliseconds, an ISO 8601 string)?
  • Which error should get_file raise for an unknown id, and should invalid input, such as an empty name or content that is not bytes, be rejected?
  • Is single-threaded use enough, or can several callers upload and delete at the same time?

Part 1 — Implement FileStorage

Implement the four methods with the behaviour described above. Decide how file ids are generated, how a duplicate name is made unique, and which data structures hold the files and their metadata.

What This Part Should Cover Guidance

  • Data structures for lookups by id and by name, kept consistent on every upload and delete
  • An explicit unique-name rule: suffix format, position relative to the extension, and names freed by deletion
  • Id generation that never repeats, and file size and timestamp captured at upload
  • Clear error behaviour for unknown ids and invalid arguments

Part 2 — Test it without a harness

No test code is provided. Write the tests you would run before the round ends, and make the class testable, including the timestamp.

What This Part Should Cover Guidance

  • A test for the normal path and the failure path of each method
  • Duplicate-name cases: second and third uploads of one name, names without an extension, and a name freed by deletion
  • An injected clock, and optionally an injected id generator, so that expected values are exact
  • Pacing: tests written and run as the methods appear, not left for the last minute

What a Strong Answer Covers Guidance

  • Raises the unresolved rules (suffix format, name reuse, list order, timestamp format) and settles them before coding
  • A small, readable class whose id and name indexes can never disagree
  • Correct suffixing in the edge cases, including collisions with names that already carry a suffix
  • Tests that actually run within the time box, rather than finished code that was never executed
  • Complexity of each method, and what would change for very large files or concurrent callers

Follow-up Questions Guidance

  • How would you make the class safe when several threads upload and delete files at once?
  • Files can be several gigabytes. How would you change the storage and the signatures of upload_file and get_file ?
  • How would you avoid storing the same bytes twice when different file names hold identical content?
  • How would you persist the files so that they survive a restart of the process?