Practical CodingIn-Memory File SystemSDE实战Startup面试真题Python算法
实战题解:In-Memory File System 与 Mini Unix Shell 面试全攻略
深度拆解北美 Startup(Applied Intuition、Retell AI、Rippling 等)最高频考题:从零实现 In-Memory File System、Path Normalization、递归目录树与 Mini Shell 命令解析。
Sam · · 18 分钟阅读
在北美中小型 Tech 公司与 AI 初创(如 Applied Intuition、Retell AI、Rippling、Uber 等)的面试中,In-Memory File System(内存文件系统) 是出镜率极高的核心实战题。
与单纯的 LeetCode 588 不同,实际面试中往往会要求候选人像写真实 Linux 工具一样,支持路径规范化(Path Normalization)、当前工作目录(CWD)、多级目录递归创建(mkdir -p)、以及类 Shell 命令行解析(cd, ls, cat, touch, find)。
本文给出工业级的清晰解法与 Follow-up 拆解。
核心需求与面向对象建模
classDiagram
class FSNode {
+String name
+Boolean is_file
+String content
+Dict children
+FSNode parent
}
class FileSystem {
+FSNode root
+FSNode cwd
+normalize_path(path) List
+mkdir(path)
+touch(path, content)
+ls(path) List
+cd(path)
+cat(path) String
}
FileSystem --> FSNode
1. 节点设计(FSNode)
class FSNode:
def __init__(self, name: str, is_file: bool = False, parent=None):
self.name = name
self.is_file = is_file
self.content = ""
self.children = {} # name -> FSNode
self.parent = parent
工业级标准实现(Python)
from typing import List, Optional
class FileSystem:
def __init__(self):
self.root = FSNode("/", is_file=False)
self.root.parent = self.root
self.cwd = self.root
def _resolve_tokens(self, path: str) -> List[str]:
"""处理相对路径、绝对路径、. 与 .."""
tokens = [t for t in path.split("/") if t and t != "."]
resolved = []
for t in tokens:
if t == "..":
if resolved:
resolved.pop()
else:
resolved.append(t)
return resolved
def _get_node(self, path: str) -> Optional[FSNode]:
"""根据路径导航到目标节点"""
if not path or path == "/":
return self.root
curr = self.root if path.startswith("/") else self.cwd
tokens = self._resolve_tokens(path)
for t in tokens:
if t not in curr.children:
return None
curr = curr.children[t]
return curr
def mkdir(self, path: str) -> bool:
"""递归创建目录 (类似 mkdir -p)"""
curr = self.root if path.startswith("/") else self.cwd
tokens = self._resolve_tokens(path)
for t in tokens:
if t not in curr.children:
curr.children[t] = FSNode(t, is_file=False, parent=curr)
curr = curr.children[t]
if curr.is_file:
raise ValueError(f"{t} is a file, cannot create directory.")
return True
def touch(self, path: str, content: str = "") -> None:
"""创建或覆写文件"""
tokens = self._resolve_tokens(path)
if not tokens:
raise ValueError("Invalid file path")
dir_path = "/" + "/".join(tokens[:-1]) if path.startswith("/") else "/".join(tokens[:-1])
filename = tokens[-1]
dir_node = self._get_node(dir_path)
if not dir_node or dir_node.is_file:
raise ValueError("Directory does not exist")
if filename not in dir_node.children:
dir_node.children[filename] = FSNode(filename, is_file=True, parent=dir_node)
file_node = dir_node.children[filename]
file_node.content += content
def ls(self, path: str = ".") -> List[str]:
"""列出文件或目录内容(按字母排序)"""
node = self._get_node(path)
if not node:
raise FileNotFoundError(f"Path {path} not found")
if node.is_file:
return [node.name]
return sorted(node.children.keys())
def cd(self, path: str) -> None:
"""切换工作目录"""
node = self._get_node(path)
if not node or node.is_file:
raise NotADirectoryError(f"{path} is not a valid directory")
self.cwd = node
def cat(self, path: str) -> str:
"""读取文件内容"""
node = self._get_node(path)
if not node or not node.is_file:
raise FileNotFoundError(f"File {path} not found")
return node.content
高频 Follow-up 与面试踩分点
- 并发锁机制(Thread Safety):
- 如果多个线程同时读写不同目录,全局加锁会导致性能下降。
- 优化解法:为每个
FSNode引入读写锁(ReadWriteLock),在遍历路径时使用 Lock Coupling(锁耦合 / 链条加锁) 机制。
- 通配符查找(
find / -name "*.log"):- 使用 DFS / BFS 遍历整棵树,结合 Python
fnmatch匹配文件名。
- 使用 DFS / BFS 遍历整棵树,结合 Python
- 软链接与硬链接(Symlinks):
- 如果增加软链接,必须在
_get_node中维护visited_symlinks集合,防止出现无限循环。
- 如果增加软链接,必须在
相关实战资源
相关面试辅导
如果你正在准备类似面试,可以直接从下面的专项辅导开始。