题目重点:围绕 create file/dir、delete、list 和深路径搜索,设计内存树、路径安全、错误契约与索引取舍。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 训练版是单进程内存目录树,根 `/` 永存;文件和目录各有唯一绝对路径,名称按原始大小写区分。
- `create` 默认父目录须已存在,不自动创建中间层;删除目录连同所有子节点,非空目录是否允许删除应先确认。符号链接和持久化未在题目出现。
解题路线
- 用节点保存 name、kind、parent 和目录 children 哈希表;统一 `normalize`:把重复斜杠、`.`、`..` 化成规范绝对路径,拒绝越根和非法名称。所有操作调用同一解析器,避免 create 与 delete 对路径的理解不同。
- create 先定位父目录并查重,最后原子挂入新节点;list 只列直接子项并固定排序;delete 从父 children 摘除整棵子树,若另有路径索引须同步更新。
- 深路径迭代查找避免递归栈溢出;若按文件名搜索频繁,可维护 name→路径集合二级索引,创建、移动、删除都要更新。全树 DFS 搜索 O(N),索引能加速精确名字,但模糊内容搜索需另建倒排索引。
- 若进阶到多线程/持久化,先决定目录级锁、事务边界和故障恢复;面试原题只列功能,不能把生产文件系统 POSIX 语义全部套入。
手动走一遍
建 `/team` 目录和 `/team/a.txt` 文件,`list('/team//.')` 返回 `a.txt`。删除 `/team` 后 `/team/a.txt` 不能再查到;如果 name 索引仍含该路径,则违反数据结构不变量。
规模与取舍
路径深度 d、单目录哈希 children 时解析平均 O(d),按名字全树搜索 O(N),list 若排序 m 个直接子项为 O(m log m);空间 O(N+总路径字符数),索引会增加 O(N) 条目。
易错点与追问
容易失分的边界
- 先把 `..` 拼入字符串再做权限判断,可能越界。
- 删父节点后留下全局索引孤儿路径。
- 把按名称搜索和全文搜索混为同一接口。
- 深链递归删除导致栈溢出。
- 未约定重复创建/不存在路径的错误语义。
继续深挖
- 搜索文件名和文件内容分别需什么索引?
- 目录移动时哪些路径索引必须更新?
- 怎样避免 `..` 穿越租户根目录?
- 若要持久化和并发,事务边界如何设?
