Machine Coding Problem

File System (Unix-like)

maco30maco60macoAllinfrastructurecomposite-patternconcurrent-read/write-lockshierarchical-path-resolution
Commonly Asked By:MicrosoftAppleGoogleDropbox

Requirements & System Scope

Functional Scope (In-Scope)

  • Composite Directory Trees: Treat directories and files uniformly under a common FileSystemNode base.
  • Recursive Path Resolving: Support complex navigation with absolute path tokens (., ..).
  • Safe Concurrency Strategy: Fine-grained locks on nodes and directories to allow simultaneous read navigation with isolated write controls.
  • Dynamic Metric aggregation: Calculate composite directory sizes dynamically from all recursive children.

Explicit Boundaries (Out-of-Scope)

  • No Physical Hard Drive Block Mapping: Does not write partition maps, raw disk inodes, or swap file sectors to physical hardware.
  • No Advanced File Compression Algorithms: Overwriting ignores dynamic zip, gzip, or compression pipeline integrations.

Class Diagram & Entity Relationships

Structural layout showing relationships between composite elements in the hierarchical tree:

Loading...
  • Polymorphic Composite Entities: FileSystemNode exposes parent paths, creation timestamps, and abstract directory checking.
  • Directory Component: Aggregates multiple polymorphic nodes, computing the total dynamic space usage on demand.

Design Patterns & SOLID Principles

  • Composite Design Pattern (Directories / Files): By forcing directories and files to inherit from the same FileSystemNode class, callers treat folders and leaf files uniformly, satisfying both SRP and OCP.
  • Single Responsibility Principle (SRP):File manages raw content access and locks; Directory maintains children collections and structure; FileSystem coordinates parsing and traversal operations.

Core Execution Workflows

Path Navigation Sequence

  1. Caller requests path lookup: resolvePath("/var/log/syslog").
  2. Split path input string using / boundaries.
  3. Traverse hierarchical child lists starting from the root folder:
    1. If intermediate elements are files instead of directories, abort resolving and return null.
    2. Verify next element coordinates exist in child directory maps.
  4. Return target FileSystemNode once final segment is successfully resolved.

Concurrency & Thread Safety Strategy

When multiple threads navigate, edit, or delete files concurrently within the directory tree, structural conflicts can occur:

  • Fine-Grained ReadWriteLocks: Guard individual files and directories with read-write locks (ReentrantReadWriteLock) to allow parallel reads while ensuring exclusive writes.
  • Atomic Subtree Locks: Directory edits (adding or removing children) acquire target directory locks exclusively to prevent list corruption.

Complete Clean Code Blueprint

Practical reference designs showing Unix-like file hierarchies in Java and Python:

// โ”€โ”€โ”€ JAVA BLUEPRINT โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
import java.util.*;
import java.util.concurrent.locks.*;

abstract class FileSystemNode {
    protected final String name;
    protected Directory parent;
    protected final long creationTime;
    protected long lastModifiedTime;

    public FileSystemNode(String name) {
        this.name = name;
        this.creationTime = System.currentTimeMillis();
        this.lastModifiedTime = this.creationTime;
    }

    public String getName() { return name; }
    public Directory getParent() { return parent; }
    public void setParent(Directory parent) { this.parent = parent; }

    public abstract boolean isDirectory();
    public abstract int getSize();
}

class File extends FileSystemNode {
    private String content = "";
    private final ReadWriteLock rwLock = new ReentrantReadWriteLock();

    public File(String name) {
        super(name);
    }

    @Override
    public boolean isDirectory() { return false; }

    public String read() {
        rwLock.readLock().lock();
        try {
            return content;
        } finally {
            rwLock.readLock().unlock();
        }
    }

    public void write(String newContent) {
        rwLock.writeLock().lock();
        try {
            this.content = newContent;
            this.lastModifiedTime = System.currentTimeMillis();
        } finally {
            rwLock.writeLock().unlock();
        }
    }

    @Override
    public int getSize() {
        rwLock.readLock().lock();
        try {
            return content.length();
        } finally {
            rwLock.readLock().unlock();
        }
    }
}

class Directory extends FileSystemNode {
    private final Map<String, FileSystemNode> children = new HashMap<>();
    private final ReadWriteLock rwLock = new ReentrantReadWriteLock();

    public Directory(String name) {
        super(name);
    }

    @Override
    public boolean isDirectory() { return true; }

    public Map<String, FileSystemNode> getChildren() {
        rwLock.readLock().lock();
        try {
            return new HashMap<>(children);
        } finally {
            rwLock.readLock().unlock();
        }
    }

    public void addChild(FileSystemNode node) {
        rwLock.writeLock().lock();
        try {
            node.setParent(this);
            children.put(node.getName(), node);
            this.lastModifiedTime = System.currentTimeMillis();
        } finally {
            rwLock.writeLock().unlock();
        }
    }

    public void removeChild(String name) {
        rwLock.writeLock().lock();
        try {
            FileSystemNode removed = children.remove(name);
            if (removed != null) {
                removed.setParent(null);
                this.lastModifiedTime = System.currentTimeMillis();
            }
        } finally {
            rwLock.writeLock().unlock();
        }
    }

    @Override
    public int getSize() {
        rwLock.readLock().lock();
        try {
            int totalSize = 0;
            for (FileSystemNode child : children.values()) {
                totalSize += child.getSize();
            }
            return totalSize;
        } finally {
            rwLock.readLock().unlock();
        }
    }
}

class FileSystem {
    private final Directory root = new Directory("/");
    private final ReadWriteLock globalLock = new ReentrantReadWriteLock();

    public Directory getRoot() { return root; }

    public FileSystemNode resolvePath(String path) {
        globalLock.readLock().lock();
        try {
            if (path == null || path.isEmpty()) return null;
            if (path.equals("/")) return root;

            String[] tokens = path.split("/");
            FileSystemNode current = root;

            for (String token : tokens) {
                if (token.isEmpty() || token.equals(".")) continue;
                if (token.equals("..")) {
                    current = current.getParent() != null ? current.getParent() : root;
                    continue;
                }

                if (!current.isDirectory()) return null;
                
                Directory currentDir = (Directory) current;
                current = currentDir.getChildren().get(token);
                if (current == null) return null;
            }
            return current;
        } finally {
            globalLock.readLock().unlock();
        }
    }

    public void mkdir(String path, boolean recursive) {
        globalLock.writeLock().lock();
        try {
            String[] tokens = path.split("/");
            Directory current = root;

            for (int i = 0; i < tokens.length; i++) {
                String token = tokens[i];
                if (token.isEmpty() || token.equals(".") || token.equals("..")) continue;

                FileSystemNode next = current.getChildren().get(token);
                if (next == null) {
                    if (i == tokens.length - 1 || recursive) {
                        Directory newDir = new Directory(token);
                        current.addChild(newDir);
                        current = newDir;
                    } else {
                        throw new IllegalArgumentException("Path directory does not exist: " + token);
                    }
                } else if (next.isDirectory()) {
                    current = (Directory) next;
                } else {
                    throw new IllegalStateException("Name conflict: " + token + " is a file");
                }
            }
        } finally {
            globalLock.writeLock().unlock();
        }
    }

    public void createFile(String path, String content) {
        globalLock.writeLock().lock();
        try {
            int lastSlash = path.lastIndexOf('/');
            String parentPath = path.substring(0, Math.max(1, lastSlash));
            String fileName = path.substring(lastSlash + 1);

            mkdir(parentPath, true);
            FileSystemNode parent = resolvePath(parentPath);
            if (parent != null && parent.isDirectory()) {
                Directory parentDir = (Directory) parent;
                File newFile = new File(fileName);
                newFile.write(content);
                parentDir.addChild(newFile);
            }
        } finally {
            globalLock.writeLock().unlock();
        }
    }
}

public class Main {
    public static void main(String[] args) {
        System.out.println("=== In-Memory File System Driver ===");
        FileSystem fs = new FileSystem();

        fs.createFile("/etc/hosts", "127.0.0.1 localhost");
        fs.createFile("/var/log/syslog", "System started successfully.");

        Directory varDir = (Directory) fs.resolvePath("/var");
        System.out.println("Resolved /var/log/syslog content: " + ((File) fs.resolvePath("/var/log/syslog")).read());
        System.out.println("Total space used in /var directory: " + varDir.getSize() + " bytes");

        // Concurrent reads/writes
        new Thread(() -> {
            File syslog = (File) fs.resolvePath("/var/log/syslog");
            syslog.write("Append content securely in concurrent thread.");
        }).start();
    }
}

๐Ÿ’ฌReview

Help Us Improve

How helpful was this walkthrough?

Click a star to rate. We actively use this feedback to refine and update our system design content.

Placeholder
Optional but highly appreciated!

Discussion

Share your thoughts, ask questions, or help others.

Loading comments...