同步/异步 I/O 模型与事件驱动(select/poll/epoll/io_uring)

共 69 题
#

1. DEP/NX(No Execute)位阻止数据页执行代码?

A NX 位由操作系统软件在每次取指令时检查
B 开启 NX 后 JIT 编译器无需任何调整
C NX 位只对 32 位系统有效
D NX 位是页表项中的硬件标志,MMU 在取指时强制检查,阻止不可执行页被执行 ✓ 正确答案
#

2. Intel CET(Control-flow Enforcement Technology)中 IBT 与 Shadow Stack?

A Shadow Stack 在 RET 时比对普通栈与影子栈的返回地址,不匹配触发异常 ✓ 正确答案
B IBT 通过影子栈校验返回地址
C IBT 防御的是后向控制流
D CET 启用无需编译器参与
#

3. stack canary(gcc -fstack-protector)防止栈溢出?

A canary 由编译器在函数序言写入随机值,尾声校验失败则调用 __stack_chk_fail 终止进程 ✓ 正确答案
B canary 存放在保存的返回地址之后
C canary 可以完全阻止所有形式的栈溢出攻击
D canary 的值对所有进程是相同的固定值
#

4. 为何 ARM64 中 PSTATE.PAN 防止内核读到用户数据?

A PAN 与 x86 的 SMEP 完全等价,都只防止执行
B PAN 只禁止内核读用户数据,不禁止写
C PAN 置位后内核无法读写用户空间页,需通过 uaccess 辅助函数显式访问 ✓ 正确答案
D 内核任何指令在 PAN 置位时都不能访问内存
#

5. O_NONBLOCK 对 socket、pipe、regular file 的不同影响?

A O_NONBLOCK 对普通文件读写也会使其返回 EAGAIN
B socket 在 O_NONBLOCK 下无数据时 read 返回 EAGAIN,而普通文件读写基本不受该标志影响 ✓ 正确答案
C 非阻塞模式下 connect 会立即返回 EINTR
D O_NONBLOCK 只能用于 socket,不能用于 pipe
#

6. 为何 socket 默认阻塞而 pipe 与 FIFO 也默认阻塞?

A 阻塞模式下 read 无数据时立即返回 EAGAIN
B 默认阻塞让程序按线性方式编写,但每个阻塞调用占用一个线程,高并发下代价巨大 ✓ 正确答案
C 阻塞模式比非阻塞模式吞吐更高,是高性能服务器的首选
D pipe 默认是非阻塞的,只有 socket 默认阻塞
#

7. epoll 在多线程中需 epoll_create per thread 还是共享?

A 多个线程共享同一 epoll 实例时,一个事件必然唤醒所有等待线程
B 每线程独立 epoll 实例并分区管理 fd 可避免共享实例的竞争,但需处理 fd 生命周期与线程绑定 ✓ 正确答案
C 每个线程必须创建独立的 epoll 实例,共享会直接崩溃
D epoll fd 不能通过 EPOLL_CTL_ADD 加入另一个 epoll 实例
#

8. DMA(Direct Memory Access)的核心动机,如何解放 CPU 并实现高吞吐?

A DMA 由 DMA 控制器按描述符完成内存与外设间的搬运,CPU 只负责准备与接收完成中断 ✓ 正确答案
B DMA 模式下 CPU 仍需逐字节参与数据搬运
C DMA 只用于内存到内存的拷贝
D DMA 传输完成后不需要任何通知机制
#

9. Linux 中 IRQ 与 softirq、tasklet、workqueue 的关系?

A softirq 在进程上下文执行,可以睡眠
B workqueue 的执行优先级高于 hardirq
C hardirq 阶段关中断、不能睡眠,只做最小工作;softirq/tasklet 在中断返回前延迟处理,workqueue 可在进程上下文睡眠执行 ✓ 正确答案
D tasklet 可以在多个 CPU 上并发执行同一实例
#

10. 为何 Linux 引入 threaded IRQ(request_threaded_irq)?

A 线程化中断后 hardirq_fn 仍然必须完成全部数据处理
B request_threaded_irq 让中断处理在专用内核线程中执行,thread_fn 可以睡眠 ✓ 正确答案
C 线程化中断适合所有设备,包括超低延迟网卡路径
D 线程化中断会提高硬中断的执行优先级
#

11. CPU affinity(IRQ affinity)在多核 NUMA 下的优化?

A IRQ affinity 与 NUMA 无关,只影响负载均衡
B 把高频中断集中在一个 CPU 上能提升整体吞吐
C NUMA 下应把中断投递到设备所在 node 的 CPU,并让应用与 softirq 同 node 处理,避免跨节点访存 ✓ 正确答案
D irqbalance 会忽略 NUMA 拓扑
#

12. Linux tasklet 在网络收包与调度中的角色?

A tasklet 同一实例在同一时刻只在一个 CPU 上执行,串行语义可免额外加锁 ✓ 正确答案
B 网络收包主路径由 tasklet 批量完成
C tasklet 可以在执行中睡眠
D tasklet 是内核推荐新增驱动使用的主要机制
#

13. Linux 中 irqbalance daemon 的负载均衡策略?

A irqbalance 基于中断频率与 CPU 负载周期性迁移 IRQ,但高吞吐专用路径应禁用并手工固定亲和性 ✓ 正确答案
B irqbalance 会把所有中断固定到第一个 CPU
C irqbalance 只负责软件中断,不处理硬件中断
D irqbalance 的迁移不会改变 smp_affinity
#

14. NIC 多队列(RSS)与 IRQ affinity 的协同?

A RSS 把同一连接的数据包随机分散到不同队列
B RSS 按四元组哈希把同一流固定到一个 RX 队列,队列中断绑定不同 CPU,实现收包并行且保序 ✓ 正确答案
C RSS 只能用一个队列
D RSS 需要应用层手动分配队列
#

15. page cache 与 buffer cache 在 Linux 2.4 起如何统一,为何文件读写统一走页缓存而块设备路径仍保留缓冲区语义?

A Linux 2.4 后文件数据在 page cache 与 buffer cache 中各存一份
B 2.4 起文件数据统一缓存于 page cache,buffer_head 退化为块在页内的描述,块设备路径仍保留块粒度缓冲区语义 ✓ 正确答案
C 2.4 后 buffer cache 完全消失
D 块设备读写与普通文件读写使用完全相同的路径
#

16. page cache 在文件读与写(write-back)中的角色?

A 写路径先修改 page cache 并标记脏页,由 writeback 按阈值异步回写;write-back 比 write-through 吞吐高但断电可能丢数据 ✓ 正确答案
B write() 总是同步等待数据落盘后才返回
C readahead 只对随机读有效
D fsync 与 write() 的语义完全相同
#

17. splice() 与 tee() 系统调用在管道间的零拷贝?

A splice 通过把页引用挂到管道实现零拷贝,tee 复制页引用到另一管道而不消费数据 ✓ 正确答案
B splice 需要用户态缓冲区中转
C tee 会立即消费源管道的数据
D splice 两端都必须是管道
#

18. Linux read() 在 page cache 命中与未命中时的 CPU cycle 差异?

A read() 未命中时只是多拷一次内存
B 命中与未命中时 read() 的开销差异可达数个数量级,未命中要经过块层提交、睡眠等待与中断唤醒 ✓ 正确答案
C page cache 命中率只影响吞吐不影响延迟
D mmap 与 read 在缺页处理上完全等价
#

19. O_DIRECT 绕过 page cache 的工程取舍?

A O_DIRECT 完全不需要缓冲区对齐
B O_DIRECT 能提升所有类型文件的读写性能
C O_DIRECT 绕过页缓存,适合自管理缓存且批量对齐 I/O 的场景;小随机 I/O 会失去预读与合并优势 ✓ 正确答案
D O_DIRECT 与 O_SYNC 语义完全相同
#

20. mmap + write 的 mmap page 与 page cache 同步?

A mmap 创建独立副本,与 read/write 互不可见
B mmap 写映射直接修改 page cache 页,与 read/write 共享缓存,脏页统一由 writeback 回写,msync 可强制同步 ✓ 正确答案
C mmap 写的数据不需要回写即可持久
D msync(MS_ASYNC) 会阻塞等待落盘完成
#

21. 为何数据库(MySQL InnoDB)使用 O_DIRECT 绕过 page cache?

A InnoDB 用 O_DIRECT 是为了让内核管理缓存
B InnoDB 使用 O_DIRECT 后不再需要 fsync
C O_DIRECT 会禁用 InnoDB 的 buffer pool
D InnoDB 用 O_DIRECT 避免与 buffer pool 双重缓存,收回缓存与刷盘控制权;redo log 通常仍走 buffered I/O ✓ 正确答案
#

22. io_uring 的提交队列与完成队列通过 mmap 共享内存,如何避免每次 I/O 都陷入内核?

A io_uring 每次 I/O 仍需要一次 io_uring_enter
B SQ/CQ 环形缓冲通过 mmap 共享,用户态直接填 SQE、读 CQE,批量或零系统调用提交 ✓ 正确答案
C io_uring 的完成结果必须通过信号量获取
D SQPOLL 模式会增加每次 I/O 的系统调用次数
#

23. 为什么说 epoll 本质仍是同步 I/O 多路复用,而 io_uring 能提供真正的异步 I/O 语义?

A epoll 属于异步 I/O,读写不占用调用线程
B io_uring 请求与线程生命周期解耦,提交后由内核异步执行,CQ 环异步收割;epoll 只是就绪通知,读写仍同步执行 ✓ 正确答案
C io_uring 必须等待每个请求完成才能提交下一个
D epoll 与 io_uring 在语义上等价
#

24. io_uring 的 SQPOLL 模式让内核线程轮询提交队列,它在什么负载下能省去 io_uring_enter 系统调用?

A SQPOLL 与 IOPOLL 是同一机制
B SQPOLL 在任何负载下都免除系统调用
C SQPOLL 内核线程常驻轮询 SQ,高频请求场景可免去 io_uring_enter,但空闲时占用 CPU 与功耗 ✓ 正确答案
D SQPOLL 模式下应用每次提交仍需 enter
#

25. io_uring 并非万能,它在 fd 类型支持、内存占用与调试复杂度上有哪些适用边界?

A io_uring 对所有文件类型都能提供真正的异步 I/O
B io_uring 在所有内核版本上行为一致
C io_uring 不占用任何额外内存
D io_uring 对无异步路径的 fd 会退化为内联或 io-wq 线程执行,且固定缓冲区与请求上下文占用不可回收内存,调试复杂度高 ✓ 正确答案
#

26. Linux 传统 POSIX AIO(aio_read)为何多被 io_uring 取代?其实现常退化为线程池的原因是什么?

A 内核原生 aio 支持 buffered 文件与网络
B glibc 的 POSIX AIO 用线程池模拟异步,内核原生 aio 仅支持 O_DIRECT 文件且事件驱动能力弱,故多被 io_uring 取代 ✓ 正确答案
C io_uring 不支持 O_DIRECT
D glibc aio 的线程池实现没有性能问题
#

27. ASLR(地址空间布局随机化)的 stack/heap/binary 三层随机?

A ASLR 只随机 stack 基址
B ASLR 提供确定性的绝对防护
C 非 PIE 二进制也能被随机加载地址
D PIE 二进制与共享库的 mmap 加载基址、初始栈顶、brk 堆基址分别被内核注入随机偏移,randomize_va_space=2 启用全部三层 ✓ 正确答案
#

28. RELRO(Read-Only Relocations)在 dynamic linker 中的 GOT 保护?

A Partial RELRO 使整个 GOT 只读
B Full RELRO 在启动时完成全部绑定后把 GOT 置为只读,消除 GOT 覆写利用面,但增加启动开销 ✓ 正确答案
C RELRO 与 lazy binding 无关
D Full RELRO 下 GOT 仍可被运行时写入
#

29. 为何 PIE 在 ASLR 下有效但 ASLR 本身需 PIE?

A 只有 PIE 二进制能被加载器放置到随机基址,从而让 ASLR 覆盖代码段;非 PIE 固定地址无法随机 ✓ 正确答案
B ASLR 对非 PIE 二进制同样能随机代码基址
C PIE 与 ASLR 互斥
D PIE 会消除所有绝对寻址,无需 GOT
#

30. 为何现代 OS 启用 NX 而 32 位 Windows XP 默认关闭?

A 32 位 x86 经典页表没有 NX 位,启用需 PAE,且大量旧软件依赖可执行内存,故 XP 默认关闭 ✓ 正确答案
B XP 关闭 DEP 是因为技术上无法实现
C 现代 OS 默认关闭 NX
D NX 与页表格式无关
#

31. io_uring 的 registered buffers(IORING_REGISTER_BUFFERS)与 fixed files 如何减少每次 I/O 的映射与引用计数开销?

A registered buffers 注册时完成页固定与映射,后续请求免去逐次 get_user_pages;固定文件免去逐次 fd 查找与引用计数 ✓ 正确答案
B registered buffers 只是标记,仍要逐次映射
C fixed files 允许注册后关闭 fd 继续使用
D 注册缓冲区不影响内存回收
#

32. Linux read() 系统调用在 O_NONBLOCK flag 下的返回行为?

A EAGAIN 表示永久错误,应关闭 fd
B O_NONBLOCK 使普通文件 read 也返回 EAGAIN
C O_NONBLOCK 下 socket 无数据时 read 返回 -1/EAGAIN,EOF 时返回 0;普通文件不受该标志影响 ✓ 正确答案
D EOF 时返回 EAGAIN
#

33. POSIX 五种 I/O 模型,阻塞、非阻塞、多路复用、信号驱动、异步 I/O 如何区分?

A 五种模型都是同步 I/O
B 阻塞 I/O 不等待数据
C 非阻塞 I/O 是异步 I/O
D 多路复用与信号驱动仍属同步 I/O,只有异步 I/O 模型的数据拷贝由内核后台完成 ✓ 正确答案
#

34. select()、poll()、epoll() 在 fd 数量与效率上的差异?

A select 受 FD_SETSIZE 限制且每次全量拷贝扫描,poll 无上限但仍 O(N) 扫描,epoll 通过内核注册与就绪链表实现 O(就绪数) 获取 ✓ 正确答案
B select 无 fd 数量限制
C epoll 每次调用也要拷贝全部 fd
D poll 的就绪获取复杂度为 O(1)
#

35. 为何 SIGIO(信号驱动 I/O)在 Linux 中很少使用?

A epoll 也会合并就绪事件
B SIGIO 支持所有 fd 类型
C SIGIO 不会合并信号,每个就绪事件单独通知
D SIGIO 就绪通知可能被合并丢失,信号处理函数受限多,配置繁琐,故现代 Linux 服务普遍改用 epoll ✓ 正确答案
#

36. 为何 epoll 在 100k+ 文件描述符下比 select/poll 更高效?

A epoll 每次 wait 仍要扫描全部注册 fd
B epoll 通过红黑树注册与就绪链表回调,epoll_wait 复杂度与就绪数相关而非连接总数,适合 100k+ 连接 ✓ 正确答案
C select 在 100k fd 下与 epoll 效率相同
D epoll_ctl 每次 wait 都需要调用
#

37. 为何 epoll_wait 在 1k fd 下仍有 O(1) 开销?

A O(1) 表示每次调用耗时完全相同
B epoll_wait 在 1k fd 时比 select 慢
C epoll_wait 的 O(1) 指开销与注册 fd 总数无关,实际与就绪事件数相关 ✓ 正确答案
D epoll_wait 每次都要遍历红黑树
#

38. epoll 在 ET 模式下为何需要一次性读完 fd 数据?

A ET 模式每次 wait 都会重新通知有数据的 fd
B ET 模式只在就绪状态变化时通知一次,应用必须循环读取到 EAGAIN,否则剩余数据不会再次触发通知 ✓ 正确答案
C ET 模式可以阻塞读取
D ET 模式不要求非阻塞 fd
#

39. epoll 在 LT 模式下处理 accept 与 read 的工程取舍?

A LT 模式就绪 fd 会持续通知,工程上循环 accept 到 EAGAIN、合理控制 read 量,并用 EPOLLONESHOT 防止多线程重复处理 ✓ 正确答案
B LT 模式只会通知一次
C LT 模式下不处理 read 也不会再收到通知
D LT 模式必须使用阻塞 fd
#

40. epoll 在 LT(level-triggered)与 ET(edge-triggered)模式的应用选择?

A ET 模式下事件处理不完会自动重发
B LT 持续通知防漏、实现简单,适合通用服务;ET 只在边沿通知一次、事件少但要求非阻塞循环读写到 EAGAIN ✓ 正确答案
C LT 模式的性能永远优于 ET
D ET 模式可以使用阻塞 fd
#

41. epoll 在 one-shot 模式(EPOLLONESHOT)与 LT/ET 的协同?

A one-shot 模式下 fd 永远不会再被通知
B EPOLLONESHOT 与 ET 等价
C EPOLLONESHOT 使 fd 事件被返回一次后自动摘除,需 EPOLL_CTL_MOD 重新启用,可防止多线程重复处理同一 fd ✓ 正确答案
D EPOLLONESHOT 只能与 LT 组合
#

42. epoll_create()、epoll_ctl()、epoll_wait() 三步调用模型?

A epoll_create 的 size 参数在 Linux 2.6.8 后仍然严格限制可注册 fd 数
B epoll_create 创建实例,epoll_ctl 增删改注册,epoll_wait 返回就绪事件数;ADD 已注册 fd 报 EEXIST ✓ 正确答案
C epoll_wait 返回后 events 数组由用户自行填写
D EPOLL_CTL_MOD 可以注册新 fd
#

43. poll() 系统调用的 pollfd 数组与 revents 返回字段?

A poll 用 pollfd 数组表达监听与结果,revents 由内核回填;无 1024 上限,但每次调用仍全量拷贝与 O(N) 扫描 ✓ 正确答案
B poll 的 revents 由应用预先填写
C poll 受 FD_SETSIZE 限制
D poll 返回后必须重建监听位图
#

44. select() 系统调用的 fd_set(bitmask)参数与 fd_set 大小限制?

A FD_SETSIZE 由内核动态决定
B fd_set 是链表结构
C select 的位图只进不出,内核不修改
D select 用 fd_set 位图表达关注集,FD_SETSIZE(默认 1024)限制可管理 fd 数,超出行为未定义,需重编译或改用 poll/epoll ✓ 正确答案
#

45. 为何 select/poll 在高并发下表现差,O(N) 扫描的代价如何?

A epoll_wait 也要拷贝全部注册 fd
B select/poll 的内核扫描与连接数无关
C select/poll 每次调用需全量拷贝与 O(N) 扫描全部 fd,高并发低活跃负载下无效开销极大;epoll 只处理就绪链表,开销与就绪数相关 ✓ 正确答案
D 活跃比例越低,select 相对 epoll 的优势越大
#

46. Redis aeMain 在 epoll_wait 主循环的事件分发?

A epoll_wait 阻塞时间与定时器无关
B Redis 的文件事件与时间事件在独立线程并行执行
C ae 使用 ET 模式减少唤醒
D Redis ae 事件循环用 epoll_wait 的 timeout 关联最近时间事件,先文件事件后时间事件分发,单线程内顺序处理 ✓ 正确答案
#

47. libevent / libev / libuv 的 epoll 后端差异?

A libev 提供内置 HTTP 服务
B 三者都基于 select 后端
C libuv 不支持 epoll
D libevent 提供 bufferevent 等高层抽象,libev 只做极简事件原语,libuv 提供文件/DNS/进程等全栈异步能力 ✓ 正确答案
#

48. Linux top half 与 bottom half 的中断处理模型?

A softirq 运行在进程上下文
B bottom half 也关中断执行
C top half 可以执行耗时很长的操作
D top half 关中断执行、不可睡眠、只做最小工作;bottom half 延迟处理数据,workqueue 运行于进程上下文可睡眠 ✓ 正确答案
#

49. NAPI(New API)在 Linux 网络栈中的软中断与 poll 协同?

A NAPI 在首个包中断后关闭设备中断,改为软中断轮询批量收包,受包数与时间预算约束,避免高负载中断风暴 ✓ 正确答案
B NAPI 让每包都触发一次中断
C NAPI 只在硬件不支持中断时使用
D NAPI 的 poll 不受任何预算限制
#

50. 硬中断(hardirq)与软中断(softirq)的区别?

A softirq 由硬件直接触发
B hardirq 由硬件触发且关中断执行,softirq 在中断返回路径等软件时机执行、开中断但仍不可睡眠 ✓ 正确答案
C hardirq 可以睡眠
D softirq 在同一 CPU 上关中断执行
#

51. MSI/MSI-X 中断相对于传统 IRQ 线中断的优势?

A MSI-X 提供每设备大量独立中断向量并可逐向量设置亲和性,避免共享中断扫描,是多队列设备并行收包的硬件基础 ✓ 正确答案
B MSI 中断仍走共享物理线
C INTx 的向量数不受限制
D MSI-X 最多支持 4 个向量
#

52. sendfile() 系统调用如何避免用户态 buffer 拷贝?

A sendfile 必须由用户态提供缓冲
B sendfile 内部仍执行 read+write
C sendfile 支持任意 fd 组合
D sendfile 把 page cache 页直接以引用形式交给 socket 发送缓冲,数据不经过用户态,零拷贝收益依赖页缓存命中 ✓ 正确答案
#

53. select、poll、epoll 在数据结构与就绪发现机制上的根本区别是什么?

A select/poll 每次调用全量询问各 fd 状态,epoll 通过等待队列回调把就绪 fd 链入就绪链表,事件发现是通知式 ✓ 正确答案
B 三者的就绪发现机制相同
C epoll 每次也要扫描所有注册 fd
D select 的事件发现是通知式
#

54. epoll 的 ET 模式为何要求 fd 非阻塞并循环读到 EAGAIN?LT 模式为何没有这一强制要求?

A ET 模式下阻塞读不会漏事件
B ET 只通知一次,阻塞读无法可靠判断已读空且会漏事件,故必须非阻塞循环读到 EAGAIN;LT 持续通知,未读完仍会再次报告 ✓ 正确答案
C LT 模式必须使用非阻塞 fd
D ET 与 LT 对 fd 的阻塞性要求相同
#

55. io_uring 相对 epoll 在高并发下的优势体现在哪里?它主要解决了 epoll 的什么瓶颈?

A io_uring 与 epoll 性能完全一致
B io_uring 以共享内存批量提交与收割、请求异步在飞、注册优化,解决 epoll 就绪后仍需逐请求系统调用且线程被占用的瓶颈 ✓ 正确答案
C io_uring 每次提交仍需多次系统调用
D epoll 本身提供异步读写语义
#

56. epoll 配合 LT 编程简单但可能重复通知,配合 ET 性能好但易漏事件,工程上如何取舍?

A ET 模式编程复杂度与 LT 相同
B ET 一定优于 LT,应无条件使用
C LT 一定会丢事件
D 取舍应综合事件密度、编程约束、延迟目标与可观测性;无明确收益时默认 LT,用压测数据决定是否切 ET ✓ 正确答案
#

57. 从 select 到 epoll 再到 io_uring 的演进,反映了高并发服务器性能瓶颈怎样的转移?

A io_uring 适合所有负载类型
B select 的瓶颈在数据拷贝而非就绪发现
C epoll 已解决所有 I/O 瓶颈
D 演进反映瓶颈从就绪发现(select 全量扫描)转向逐请求系统调用与线程占用(epoll),再转向请求提交与完成机制(io_uring) ✓ 正确答案
#

58. fortify source 在 glibc 中的检查(__builtin_object_size)?

A _FORTIFY_SOURCE 与编译优化等级无关
B _FORTIFY_SOURCE 能拦截所有形式的溢出,包括运行时大小未知的
C _FORTIFY_SOURCE 只影响性能不影响安全
D _FORTIFY_SOURCE 通过 __builtin_object_size 编译期推导目标缓冲大小,为 memcpy/strcpy 等插入大小检查,超限调用 __chk_fail ✓ 正确答案
#

59. io_uring 的 linked SQEs 与 multishot accept/poll 如何减少应用与内核的交互次数,典型使用场景是什么?

A multishot 每次完成都需要应用重新提交请求
B linked SQEs 把依赖操作链成一次提交,multishot 一次注册持续产生完成,适合连接风暴与长连接网关等高频场景 ✓ 正确答案
C linked SQEs 用于并行提交无关请求
D multishot accept 只完成一次
#

60. 网卡中断合并(interrupt coalescing)与 busy polling 的取舍,低延迟与高吞吐如何平衡,adaptive coalescing 如何工作?

A 中断合并能同时降低延迟与提升吞吐
B 中断合并降低中断频率提升吞吐但引入延迟,busy polling 消除中断延迟但占满 CPU,adaptive coalescing 按负载自动调节二者 ✓ 正确答案
C busy polling 不消耗 CPU
D 自适应合并只在负载极低时工作
#

61. ARM64 BTI(Branch Target Identification)中的 landing pad?

A BTI 用于保护返回地址
B BTI 要求间接分支目标必须是 bti landing pad 指令,否则触发异常;未启用时 bti 等价于 nop ✓ 正确答案
C landing pad 指令与普通指令无区别
D BTI 只对直接调用生效
#

62. sysctl kernel.randomize_va_space 的 0/1/2 三档?

A 修改该参数对已运行进程立即生效
B 1 表示关闭所有随机化
C randomize_va_space=2 为完整随机(stack/heap/mmap/PIE 均随机),0 关闭,1 仅随机 mmap 基址 ✓ 正确答案
D 现代 Linux 默认值为 0
#

63. 为何 Linux 中 PT_GNU_STACK 影响 stack 可执行性?

A 现代 GCC 默认生成可执行栈
B PT_GNU_STACK 只影响堆的权限
C 内核根据 PT_GNU_STACK 段决定栈权限,缺省时按可执行栈处理;链接器依据各目标文件的 .note.GNU-stack 生成该段 ✓ 正确答案
D 栈权限与链接选项无关
#

64. Linux 中 accept() 在 O_NONBLOCK 下 EAGAIN 与 EWOULDBLOCK 等价?

A Linux 上 EAGAIN 与 EWOULDBLOCK 数值相同、完全等价,非阻塞 accept 在连接队列空时返回 EAGAIN 表示稍后再试 ✓ 正确答案
B Linux 上二者是不同的错误码
C accept 的非阻塞返回与监听队列无关
D EAGAIN 表示致命错误应关闭 fd
#

65. macOS kqueue 与 BSD kqueue 的实现差异?

A kqueue 只支持 socket 事件
B macOS 的 kqueue 与 Linux epoll 完全等价
C kqueue 有 fd 数量上限
D macOS 继承 BSD kqueue 的事件过滤器模型,一次 kevent 调用可同时注册与收割;与 epoll 的注册/等待分离结构不同,需在抽象层统一 ✓ 正确答案
#

66. Linux 中 copy_file_range 的零拷贝语义?

A copy_file_range 不适用于同文件系统
B copy_file_range 必须先读入用户缓冲区
C copy_file_range 只能用于 socket
D copy_file_range 在内核内完成文件间复制,支持 reflink 的 fs 退化为 COW 引用复制;与 sendfile 的文件到 socket 方向不同 ✓ 正确答案
#

67. dirty page writeback 在 pdflush 与 writeback daemon 的协同?

A pdflush 按设备独立管理
B pdflush 是全局线程池,慢设备会拖累其他设备;writeback daemon(2.6.32+)per-bdi 独立线程回写并按背压自适应 ✓ 正确答案
C writeback daemon 与 pdflush 完全相同
D 脏页回写只由前台进程触发
#

68. mmap() 在文件 I/O 中作为零拷贝的优缺点?

A mmap 的数据写入立即持久化
B mmap 把文件页映射进用户地址空间,读写免显式拷贝,但有大映射页表开销、缺页延迟与 SIGBUS 风险 ✓ 正确答案
C mmap 只适合小文件
D mmap 没有 TLB 开销
#

69. 为什么 io_uring 对 fd 类型有限制,对不支持异步路径的设备(如某些字符设备)会退化成什么行为?

A 无异步路径的 fd 会退化为提交时内联执行或 io-wq 工作线程执行,失去真正异步与流水线收益 ✓ 正确答案
B io_uring 对所有 fd 都能提供完全异步
C 退化只影响性能不影响语义
D io-wq 线程数无任何限制