Appearance
题目
文件 F 由 200 条记录组成,记录从 1 开始编号。用户打开文件后,欲将内存中的一条记录插入文件 F 中,作为其第 30 条记录。请回答下列问题,并说明理由。
(1) 若文件系统采用连续分配方式,每个磁盘块存放一条记录,文件 F 存储区域前后均有足够的空闲磁盘空间,则完成上述插入操作最少需要访问多少次磁盘块?F 的文件控制块内容会发生哪些改变?
(2) 若文件系统采用链接分配方式,每个磁盘块存放一条记录和一个链接指针,则完成上述插入操作需要访问多少次磁盘块?若每个存储块大小为 1 KB、其中 4 B 存放链接指针,则该文件系统支持的文件最大长度是多少?
解析
(1)连续分配下插入第 30 条记录
思路:连续分配 = 数组,插入 = 整体平移
连续分配的物理结构相当于内存中的数组——所有记录按编号紧挨着摆。要在第 30 位插入新记录,必须给它腾出位置。题目说"前后均有足够的空闲磁盘空间",意味着两种平移方向都可行:
| 方案 | 平移哪几条 | 平移块数 | 总访盘次数 |
|---|---|---|---|
| 方案 A:把第 30~200 条后移 1 位 | 200 - 30 + 1 = 171 条 | 171 × 2 = 342 + 1 写新记录 = 343 | |
| 方案 B:把第 1~29 条前移 1 位 | 29 条 | 29 × 2 = 58 + 1 写新记录 = 59 |
每移动一条 = "读出 1 次 + 存回 1 次" = 2 次访盘。题目要"最少",显然选方案 B:
FCB 哪些字段会变?
平移后整个文件实际从原起点的前一块开始(因为往前挪了 1 块),所以:
- 起始块号:减 1(指向新的第 1 条记录所在块)
- 文件长度(块数):从 200 增至 201
编者注(易错点):
- 标答把"起始块号 + 文件大小"两个字段都算上 1 分。漏写文件长度或**只写"地址变了"**都不全。
- 别陷在"是不是要把第 30 条本身也读出来再放回"的纠结里——题目要求的是"插入新记录",第 30~199 那些老记录需要平移,但第 200 → 201 这步只是把第 200 条往后挪而已(共 171 块若选方案 A)。方案 B 只动前 29 条。
- 现实中"前后都有空"的假设往往不成立,所以工业系统极少用纯连续分配 → 衍生出索引 / 链接分配。
(2)链接分配下插入第 30 条记录
插入操作的访盘次数
链接分配下"插入"不需要平移——只要找到第 29 块、修改其后继指针即可:
| 步骤 | 访盘次数 | 累计 |
|---|---|---|
| ① 沿链表找到第 29 块(从首块开始追指针,每追一块读 1 次) | 29 | 29 |
| ② 把新块写到磁盘任意空闲位置,新块的后继指针 = 第 29 块原本指向的下一块(即第 30 块) | 1 | 30 |
| ③ 修改第 29 块的后继指针指向"新块",再把第 29 块写回磁盘 | 1 | 31 |
编者注(细节):
- 步骤 ① 的"找到第 29 块"必须逐块沿链追,因为链接分配没有索引表可以直接定位。这是链接分配最大的痛——随机访问慢。
- 步骤 ③ 修改第 29 块时不需要重新读它——刚才追链时已经读到内存里。所以只算"写回 1 次"。
文件最大长度
每个块 1 KB = 1024 B,其中 4 B 存指针、剩余 1020 B 存数据。最关键的约束:指针字段决定能管多少块。
每块可用数据 1020 B → 文件最大长度:
编者注(评分约定):标答给两种算法都给分:
- 严格答:每块数据部分只有 1020 B → 4 G × 1020 B = 4080 GB(满分)
- 粗略答:忽略指针,按 1024 B 算 → 4 G × 1024 B = 4096 GB = 4 TB(给 1 分)
考场上优先按严格 1020 算,多算几下是值得的。这道题真正考的就是"识别出指针占用了 4 B"。
编者注(连续 vs 链接 的取舍):
维度 连续分配 链接分配 顺序访问 极快(无寻道) 较慢(追链) 随机访问 极快(O(1)) 极慢(O(n)) 插入 / 删除 慢(要平移) 快(改指针) 文件扩展 难 易 元数据开销 低(起点 + 长度) 高(每块占指针位) 现代 Unix / NTFS 都不用单纯的连续 / 链接 / 索引,而是混合方案(直接 + 间接 + 多级间接),结合各自优点。