Appearance
13 期末题型速查
选择题
IEEE 754:
- 非规格化数用于逐步下溢。
- 单精度 Bias = 127,双精度 Bias = 1023。
- 阶码全 0 是非规格化或 0,不是普通规格化指数。
- 阶码全 1 且 frac 全 0 是 Inf,frac 非 0 是 NaN。
- 浮点数不均匀分布,越远离 0 间距越大。
- 浮点加法不满足结合律。
流水线:
- 数据冒险 RAW 可用转发缓解,但 load-use 可能仍需 stall。
- 分支预测解决控制冒险,不解决数据冒险。
- 加深流水线不能消除冒险。
链接:
- 多个强符号同名错误。
- 强符号优先于弱符号。
- 函数和初始化全局变量通常强;未初始化全局变量通常弱。
- 静态库代码复制进可执行文件;动态库运行时加载/映射。
- 共享库需要 PIC 以便映射到不同地址并共享代码页。
Cache:
- 组数
。 - index 位
,offset 位 。 - 写回:脏块替换时才写回主存。
- MESI 解决多核私有 Cache 副本一致性问题。
- 按行访问 C 二维数组空间局部性好,按列访问差。
虚拟内存:
- TLB 缓存页表项。
- TLB miss 不一定 page fault。
- page fault 可恢复,也可能因权限错误导致进程终止。
- 页表大小与虚拟页数量和 PTE 大小有关。
- 逆向页表空间与物理页数相关。
信号:
- 同类型 pending 信号不排队。
- 当前正在处理某信号时,内核默认阻塞同类型信号。
sigprocmask可阻塞/解除阻塞信号,不是删除 pending 信号。- handler 中不要调用
printf。
网络:
- TCP 是可靠有序字节流,不保留应用层消息边界。
- 服务器
bind后调用listen。 accept返回已连接描述符。- HTTP/1.1 默认持久连接,需要明确消息边界。
填空题
| 问法 | 答案 |
|---|---|
| x86-64 返回值寄存器 | %rax |
| x86-64 栈指针 | %rsp |
| 前 6 个整数参数 | %rdi,%rsi,%rdx,%rcx,%r8,%r9 |
| 32 位虚拟地址空间大小 | |
| 4KB 页偏移位数 | 12 位 |
| 8KB 页偏移位数 | 13 位 |
rwxr-x--x 权限码 | 751 |
| 动态内存分配函数 | malloc/calloc/realloc |
| 释放堆内存 | free |
| HTTP 发送数据常用方法 | POST |
| 服务器进入被动监听 | listen |
| 文件描述符 0/1/2 | stdin/stdout/stderr |
浮点题
最大规格化正数:
给定位数:1 符号位,
十进制转浮点:
- 转二进制。
- 规格化为
。 - sign 看正负。
- exponent =
。 - fraction 取小数点后
位,必要时舍入。
Cache 题
先写参数表:
text
C = 总容量
E = 相联度
B = 块大小
m = 地址位数
S = C / (E * B)
s = log2(S)
b = log2(B)
t = m - s - b地址拆分:
text
tag = addr >> (s + b)
index = (addr >> b) & ((1 << s) - 1)
offset = addr & ((1 << b) - 1)模拟表格:
| Step | Addr | Tag | Index | Hit/Miss | Eviction | 组内状态 |
|---|
LRU 每次访问后更新时间,替换同组最老的行。
直接映射命中率例:
Cache 256B,块 16B,直接映射。访问 0,16,32,48,64,80,0,16。
前 6 次装入不同块,均 miss;第 7 次 0 命中,第 8 次 16 命中。命中率:
多级页表题
页大小
每页 PTE 数:
每级索引位:
单级页表大小:
汇编反推 C
步骤:
- 识别参数寄存器。
- 找 base case:
cmp/test后直接ret。 - 找递归调用前参数变化。
- 找递归返回后如何组合
%rax。 - 说明 callee-saved 寄存器为何 push/pop。
常见阶乘:
asm
testq %rdi, %rdi
jle .L3
pushq %rbx
movq %rdi, %rbx
subq $1, %rdi
call func
imulq %rbx, %rax
popq %rbx
ret
.L3:
movl $1, %eax
ret对应:
c
long func(long n) {
if (n <= 0) {
return 1;
}
return n * func(n - 1);
}fork 输出
规则:
- 每次无条件
fork()使当前进程数翻倍。 if (fork() == 0)中,子进程进 if,父进程不进 if。if (fork())中,父进程进 if,子进程不进 if。- 所有到达
printf的进程都会输出。
例:
c
fork();
fork();
printf("hello\n");输出 4 行。
信号竞争题
问题描述:
- 主程序和 signal handler 并发访问共享状态。
- 信号可能在关键区中间到达。
- 造成丢失更新、重复删除、僵尸或 job list 不一致。
sigprocmask 修复:
c
sigset_t mask, prev;
sigemptyset(&mask);
sigaddset(&mask, SIGCHLD);
sigprocmask(SIG_BLOCK, &mask, &prev);
pid_t pid = fork();
if (pid == 0) {
sigprocmask(SIG_SETMASK, &prev, NULL);
execve(path, argv, envp);
_exit(1);
}
addjob(pid);
sigprocmask(SIG_SETMASK, &prev, NULL);sigsuspend 修复等待竞态:
c
sigprocmask(SIG_BLOCK, &mask, &prev);
while (!flag) {
sigsuspend(&prev);
}
sigprocmask(SIG_SETMASK, &prev, NULL);答题关键词:原子地解除阻塞并睡眠,避免检查条件和进入睡眠之间丢信号。
链接题
静态库 vs 动态库:
- 静态库:链接时复制所需目标模块进可执行文件;运行不依赖库文件;更新库需重新链接。
- 动态库:运行时由加载器映射共享库;多个进程共享代码页;更新库可能无需重编译但有 ABI 风险。
PIC:
- 位置无关代码。
- 使用相对寻址和 GOT/PLT。
- 让共享库可映射到不同虚拟地址,减少代码段重定位,保持代码页可共享。
网络代码题
服务器基本顺序:
text
socket -> bind -> listen -> accept -> read/write -> close(connfd)客户端基本顺序:
text
socket -> connect -> read/write -> close解释关键函数:
socket创建通信端点。bind绑定本地地址和端口。listen进入被动监听。accept接受连接并返回已连接 fd。connect主动建立连接。read/write在 socket 上收发字节流。
扩展题
RAID:
- RAID 0:条带化,提高吞吐,无冗余,任一盘坏可能丢数据。
- RAID 1:镜像,利用率 50%,可靠性高。
- RAID 5:分布式奇偶校验,通常允许一块盘损坏。
- RAID 10:先镜像再条带化,结合可靠性和性能。
死锁四必要条件:
- 互斥。
- 请求并保持。
- 不剥夺。
- 循环等待。
生产者消费者信号量:
text
sem empty = N
sem full = 0
sem mutex = 1
producer:
P(empty)
P(mutex)
put item
V(mutex)
V(full)
consumer:
P(full)
P(mutex)
get item
V(mutex)
V(empty)协程:
- 通常用户态实现。
- 切换不需要内核参与。
- 单个协程本身不等于并行;并行需要多个线程/CPU 配合。
线程:
- 进程是资源分配基本单位。
- 线程是 CPU 调度基本单位。
- 同进程线程共享地址空间,修改共享变量要同步。