Machine Coding Problem

File System (Unix-like)

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

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.

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();
    }
}