io_uring 与零拷贝 I/O(架构/提交完成队列/高级用法)

共 39 题
#

1. io_uring 的链接操作(chain)与多依赖(link)

A 链式操作必须多次提交
B 链中操作总是并行执行
C 链中任一失败不影响后续操作
D IOSQE_IO_LINK 把操作链接成链,前一个完成后才执行下一个 ✓ 正确答案
#

2. 在连接数很少、IOPS 不高的场景下,io_uring 为何可能因额外的环管理与注册开销反而比 epoll 更慢?

A epoll 的开销总是更大
B io_uring 在任何场景都优于 epoll
C io_uring 的环分配与注册有固定开销,低负载下可能比 epoll 更慢 ✓ 正确答案
D io_uring 无需注册文件
#

3. sendfile 的内核态单次拷贝,如何把数据从磁盘文件直接送到 socket

A sendfile 从页缓存直接发送到 socket,避免用户态拷贝 ✓ 正确答案
B sendfile 需要两次用户态拷贝
C sendfile 只能用于内存文件
D sendfile 比 read/write 更慢
#

4. tee 的"复制管道数据"能力,用户态可见但零拷贝

A tee 复制管道数据的页引用而非内容,实现零拷贝 ✓ 正确答案
B tee 会进行实质内容拷贝
C tee 只能用于 socket
D tee 与 splice 无关
#

5. mmap 文件后 write 到 socket,相比 sendfile 仍多出一次从页缓存到 socket 缓冲区的拷贝,这次拷贝发生在哪里?

A mmap+write 比 sendfile 多一次页缓存到 socket 缓冲区的拷贝 ✓ 正确答案
B mmap+write 与 sendfile 拷贝次数相同
C sendfile 需要两次用户态拷贝
D mmap 不经过页缓存
#

6. io_uring 与 epoll 在高 IOPS 场景下的性能对比

A io_uring 用批量提交与完成减少系统调用,高 IOPS 下优于 epoll ✓ 正确答案
B epoll 也支持批量提交 I/O
C io_uring 与 epoll 性能完全相同
D io_uring 只适合低 IOPS
#

7. io_uring 的 IORING_FEAT_* 特性探测

A 所有 io_uring 特性在所有内核都可用
B 特性探测与内核版本无关
C IORING_FEAT_* 标志位用于探测内核支持的 io_uring 特性 ✓ 正确答案
D liburing 不处理特性探测
#

8. io_uring 的 IORING_OP_* 系统调用族,如 READ、WRITE、ACCEPT、CONNECT 等

A IORING_OP_* 把传统系统调用映射为异步操作提交 ✓ 正确答案
B IORING_OP_* 只能用于同步 I/O
C io_uring 只支持文件读写
D ACCEPT 无法异步化
#

9. io_uring 的双环形队列(submission queue、CQE ring)设计

A SQ/CQ 通过系统调用交互
B SQ 存放完成结果
C io_uring 只有单一队列
D SQ 存放提交操作,CQ 存放完成结果,二者经 mmap 共享 ✓ 正确答案
#

10. io_uring 的固定缓冲区(fixed buffer)与缓冲区注册

A 固定缓冲区每次操作都重新锁定
B 固定缓冲区注册后内核直接引用,避免每次页锁定开销 ✓ 正确答案
C 固定缓冲区与性能无关
D 固定缓冲区无法用于零拷贝
#

11. io_uring_setup 与 io_uring_register 的内核注册流程

A io_uring_register 创建环形队列
B io_uring_setup 创建环形队列,io_uring_register 注册文件与缓冲区 ✓ 正确答案
C io_uring_setup 注册缓冲区
D 二者都只返回 fd
#

12. liburing 的 io_uring_prep_* 系列封装

A liburing 只用于网络 I/O
B liburing 需要手动填充 SQE
C liburing 不提供提交 API
D io_uring_prep_* 封装 SQE 填充,简化 io_uring 使用 ✓ 正确答案
#

13. io_uring 与 msync/posix_fadvise 的协同

A posix_fadvise 只能同步调用
B msync 与 io_uring 无关
C io_uring 提供异步的 msync/fadvise 操作,与其协同优化 I/O ✓ 正确答案
D io_uring 无法处理缓存策略
#

14. io_uring 的 persona(task_work)异步任务

A task_work 会增加系统调用
B task_work 在中断上下文立即执行
C task_work 与完成处理无关
D io_uring 通过 task_work 把完成回调调度到进程上下文执行 ✓ 正确答案
#

15. io_uring 的注册文件描述符(registered fds)减少 fd 表查找

A 注册 fd 后内核按索引直接引用,避免每次 fd 表查找 ✓ 正确答案
B 注册 fd 仍需每次查找 fd 表
C 注册 fd 与性能无关
D 注册 fd 无法复用
#

16. io_uring 在 Rust(tokio-uring)与 Java 的高级封装

A tokio-uring 把 io_uring 集成到异步运行时,提供安全高效的异步接口 ✓ 正确答案
B Java 无法使用 io_uring
C tokio-uring 直接暴露裸接口
D 这些封装不使用 io_uring
#

17. io_uring 在数据库(TiDB、ScyllaDB)的应用案例

A 数据库用 io_uring 实现异步读写,减少阻塞并提升吞吐 ✓ 正确答案
B io_uring 不适合数据库
C 数据库必须用同步 I/O
D io_uring 增加数据库延迟
#

18. io_uring 的"受限模式"(restricted mode)与安全边界

A 受限模式与安全无关
B 受限模式允许所有操作
C io_uring 受限模式限制可执行的操作,形成安全白名单 ✓ 正确答案
D 受限模式无法限制注册功能
#

19. mmap 通过"用户态映射内核页"避免 read 拷贝的原理

A mmap 仍需 read 拷贝数据
B mmap 把页缓存映射到用户态,读文件时避免 read 拷贝 ✓ 正确答案
C mmap 无法访问页缓存
D mmap 只能用于写文件
#

20. 传统 I/O 的"用户态-内核态"两次拷贝,即 read → 用户 buffer → write 的路径

A 传统 read/write 发生两次用户态-内核态拷贝 ✓ 正确答案
B 传统 I/O 只有一次拷贝
C read/write 完全不拷贝数据
D 零拷贝是为了增加拷贝次数
#

21. MSG_ZEROCOPY 让 send() 直接引用用户页避免拷贝,内核如何通过 error queue 的扩展错误信息通知用户页可回收?

A error queue 与零拷贝无关
B 用户发送后即可立即释放页
C MSG_ZEROCOPY 不涉及页引用
D MSG_ZEROCOPY 通过 error queue 返回扩展错误信息通知用户页可回收 ✓ 正确答案
#

22. io_uring 的 provided buffers(buffer ring,IORING_REGISTER_PBUF_RING)如何让内核接收时直接写入用户预提供缓冲,实现接收零拷贝?

A provided buffers 只用于发送
B provided buffers 每次都要拷贝数据
C provided buffers 让内核直接写入预注册缓冲区,实现接收零拷贝 ✓ 正确答案
D buffer id 不用于标识使用的缓冲
#

23. copy_file_range 的内核态文件到文件拷贝

A copy_file_range 需要经过用户态
B copy_file_range 在内核态完成文件间拷贝,避免用户态中转 ✓ 正确答案
C copy_file_range 只能拷贝到 socket
D copy_file_range 比 read/write 更慢
#

24. io_uring IORING_OP_SPLICE 的零拷贝 splice 操作

A IORING_OP_SPLICE 只能同步执行
B IORING_OP_SPLICE 把 splice 零拷贝操作异步化提交 ✓ 正确答案
C splice 无法零拷贝
D IORING_OP_SPLICE 与 splice 无关
#

25. IORING_SETUP_COOP_TASKRUN、IORING_SETUP_SINGLE_ISSUER 等标志分别优化了什么路径,使用时有何约束?

A COOP_TASKRUN 与调度无关
B SINGLE_ISSUER 允许任意并发提交
C IORING_SETUP_SINGLE_ISSUER 优化单线程提交路径,要求提交确实来自单一线程 ✓ 正确答案
D 这些标志总是安全启用
#

26. IORING_SETUP_SQPOLL 模式下内核轮询线程持续检查 SQ,它在什么场景下能彻底消除 io_uring_enter 调用?

A SQPOLL 仍需每次调用 io_uring_enter
B SQPOLL 用内核轮询线程处理 SQ,忙碌场景下可消除 io_uring_enter 调用 ✓ 正确答案
C SQPOLL 不占用 CPU
D SQPOLL 只适合低负载
#

27. io_uring 的 SQ/CQ 环形缓冲区通过 mmap 在用户态与内核态共享,提交与完成如何避免传统系统调用的陷入开销?

A io_uring 每次 I/O 仍需系统调用
B SQ/CQ 经 mmap 共享,应用直接写队列提交,减少系统调用陷入 ✓ 正确答案
C SQ/CQ 无法共享内存
D 内存屏障与同步无关
#

28. io_uring 的 linked submission 用 IOSQE_IO_LINK 把多个操作串成链,前一个失败时后续操作如何被取消?

A 普通 link 失败后仍执行全部后续操作
B 普通 link 中前一个操作失败会取消后续操作 ✓ 正确答案
C IOSQE_IO_HARDLINK 会在失败时取消后续
D linked submission 与取消无关
#

29. io_uring 的 linked timeout 如何给一组链式操作设置整体超时?它与独立 timeout 操作有何区别?

A linked timeout 与 group 无关
B linked timeout 只针对单个操作
C linked timeout 为整组链式操作设置整体超时 ✓ 正确答案
D 独立 timeout 也能给整组设置超时
#

30. CQE 的 res 与 flags 字段分别返回什么?IOSQE_BUFFER_SELECT 选中的 buffer id 如何回传?

A flags 只返回错误码
B CQE.res 返回 buffer id
C CQE.res 返回操作结果,flags 携带附加标志并可回传 buffer id ✓ 正确答案
D buffer id 无法回传
#

31. 当 SQ 填满或内核处理不过来时,io_uring 的背压如何体现?应用应如何排水?

A SQ 填满时应用应等待 CQE 完成释放空间后再提交,即排水 ✓ 正确答案
B SQ 填满时应用继续无限提交
C io_uring 无背压机制
D 排水会增加错误
#

32. io_uring buffer ring(IORING_REGISTER_BUFFERS / BUFFER_SELECT)在 1k concurrent buffer 的工程价值?

A BUFFER_SELECT 让内核从预注册池自动选取缓冲,适合高并发缓冲管理 ✓ 正确答案
B 高并发下需为每个请求单独分配缓冲
C buffer ring 只支持少量缓冲
D BUFFER_SELECT 与并发无关
#

33. io_uring buffer ring 在 BUFFER_SELECT 与 BPID(buffer pool id)的工程价值?

A BPID 只支持单一缓冲池
B BPID 标识不同缓冲池,支持按场景分类管理缓冲 ✓ 正确答案
C BUFFER_SELECT 无法指定缓冲池
D BPID 与缓冲管理无关
#

34. buffer ring 在 zero-copy + io_uring send 的工程价值?

A buffer ring 只能用于接收
B buffer ring 也支持发送侧,配合零拷贝 send 复用发送缓冲 ✓ 正确答案
C send 无法零拷贝
D buffer ring 增加发送拷贝
#

35. splice 在两个文件描述符之间实现"管道化"零拷贝

A splice 经管道在两个 fd 间传递页引用,实现零拷贝 ✓ 正确答案
B splice 复制数据内容
C splice 两端都必须是文件
D splice 会经过用户态缓冲
#

36. vmsplice 的"用户页直接入管道"半零拷贝

A vmsplice 与 splice 完全相同
B vmsplice 需要把数据拷贝到内核
C vmsplice 把用户页直接映射到管道,无需拷贝到内核 ✓ 正确答案
D vmsplice 只能从内核取数据
#

37. MSG_ZEROCOPY 在小包场景为何可能因页引用与通知开销反而变慢?它适合什么样的负载?

A MSG_ZEROCOPY 适合小包负载
B MSG_ZEROCOPY 的页引用与通知开销在小包场景占比高,反而变慢 ✓ 正确答案
C MSG_ZEROCOPY 无固定开销
D 小包场景零拷贝收益最大
#

38. sendpage 与 sendfile 的 socket-specific 优化

A sendpage 需要拷贝页
B sendpage 直接发送页到 socket,sendfile 整体发送文件,都是零拷贝优化 ✓ 正确答案
C sendfile 经用户态缓冲
D 二者只用于文件读取
#

39. multishot 操作(如 multishot recv/accept)一次提交可产生多个 CQE,它解决了什么重复提交的开销?

A multishot 无法取消
B multishot 每次只产生一个 CQE
C multishot 一次提交可持续产生多个 CQE,避免重复提交开销 ✓ 正确答案
D multishot 增加重复提交