linux常见面试题/笔试收录(一)
==========================================
真实面试环境中,被问到的相关问题,感兴趣的可以看下
==========================================
1. 说一说网络IO
- 阻塞 IO:简单客户端程序
- 非阻塞 IO
- IO 多路复用:高并发服务端(如 Nginx、Redis)
- 异步 IO:少见,适用于极高并发或延迟敏感场景
模型 | 特点简述 |
---|---|
阻塞 I/O | 调用 recv() 时线程被挂起,直到数据到达 |
非阻塞 I/O | 调用立即返回,如果没数据就继续轮询 |
I/O 多路复用 | 如 select / poll / epoll ,一个线程管理多个连接 |
信号驱动 I/O | 用信号通知数据到达,不常用 |
异步 I/O (AIO) | 系统负责全部读写,完成后通知应用 |
2. 说一说IO多路复用
IO 多路复用是指用一个线程监听多个 IO 描述符(如 socket),当某个 IO 就绪时才进行读写操作,常用方法有 select
、poll
和 epoll
,适合高并发网络编程。
3. 说说进程、线程、协程是什么,区别是什么?
进程是资源调度的基本单位,运行一个可执行程序会创建一个或多个进程,进程就是运行起来的可执行程序
线程是程序执行的基本单位,是轻量级的进程。每个进程中都有唯一的主线程,且只能有一个,主线程和进程是相互依存的关系,主线程结束进程也会结束
协程:用户态的轻量级线程,由程序主动切换,切换开销更小,适合大量并发场景
在linux中用过吗
在 Linux C 中使用线程,主要依赖 POSIX 提供的 pthread
(POSIX thread)库。下面简洁明了地讲解:
- pthread_create
- pthread_join
从内存空间来说:进程是独立的,线程和协程是共享线程内存
从调度方式来说:进程和线程都是系统调用,协程是用户程序主动调度
从切换开销来说:进程开销大,线程开销中,协程小
从适用场景来说:进程资源隔离,线程多核并行,协程高并发异步
4. 线程池 是什么? 为什么? 怎么用
一种预先创建好多个线程,用于复用执行任务的机制,避免频繁创建/销毁线程,提升性能。
为什么用线程池:
减少资源开销(线程复用)
提升响应速度(任务来了就用现成线程)
统一管理线程数量,防止系统压力过大
在QT中:
- 使用QThreadPool,搭配QRunnable,实现线程池
- 也有在我那个智能手表多媒体系统中音乐视频处理就是使用的线程池处理
4. 说一下线程池的工作原理
简单流程
初始化固定数量的线程,进入等待状态
然后任务提交到任务队列
空闲线程从队列中取任务执行
执行完任务后回到线程池继续等待
5. linux线程安全? 什么是线程安全,怎么保证线程安全
线程安全是指:多个线程同时访问共享资源时,不会导致数据错误或程序异常,即操作是原子的、互不干扰的。
如何保证线程安全
- 使用同步机制:互斥锁,信号量,条件变量,读写锁
- 使用原子操作std::atomic
- 使用TLS线程局部变量存储的方法,避免共享数据
互斥锁在linux中pthread_mutex_lock
6. 什么是死锁? 什么时候造成死锁,规避死锁
多个线程/进程互相等待对方释放资源,导致程序永远阻塞,这就是死锁。
产生的四个条件
互斥:资源不可共享
占有且等待:持有资源还想申请其他资源
不可抢占:资源只能主动释放
循环等待:形成资源等待环
如何避免死锁?
- 资源加锁顺序统一
- 避免长时间占有锁
- 设置锁超时,避免永久等待
- 加锁前先尝试
trylock()
,失败就释放已有锁重试
7. 生产者和消费者模型? 什么是? 怎么实现?
生产者-消费者模型是一种经典的线程/进程协作模型,用于解决数据缓冲区共享问题。
生产者生产数据放入缓冲区,消费者从缓冲区取数据,二者通过线程同步机制协调执行
pthread+ 条件变量+std::mutex
+ std::condition_variable
缓冲区满:生产者等待
缓冲区空:消费者等待
操作缓冲区时需要互斥
8. 用过哪些c库?
glib:提供数据结构、线程、事件循环等功能支持。
libcurl:用于执行 HTTP、FTP 等网络请求的跨平台网络传输库。
cJSON:轻量级的 JSON 格式解析与构建库。
SQLite:嵌入式轻量级关系型数据库,适合本地存储。
zlib:实现数据压缩和解压缩的通用压缩库。
9. 有没有做单元测试?glib
有了解一些,glib 自带的单元测试框架是 glib testing framework
,可以用 g_test_init
、g_test_add_func
等接口来组织和运行测试,适合测试基于 glib 的项目
10. 进程之间通信
管道:父子进程通信用匿名管道,无亲缘关系的进程通信用命名管道
消息队列:基于内核,可发送结构化消息,支持多进程读写
共享内存:多进程共享一块物理内存
信号量:用于进程间同步和互斥
信号:用于通知进程发生了某些事件(如中断、终止)
套接字(Socket):不仅支持本地进程通信,也支持网络通信
11. http与tcp联系和区别 ?
联系:
- HTTP 是基于 TCP 的应用层协议,通信时必须先建立 TCP 连接
- HTTP 报文通过 TCP 传输数据,TCP 保证数据可靠传送。
区别:
- HTTP是应用层协议,TCP是传输层协议
- HTTP是定义客户端与服务器之间的通信格式,而TCP是可靠的传输数据
- HTTP传输单位为报文,TCP传输单位是字节流
12. 说一下tcp的三次握手 四次挥手?
第一次握手:客户端向服务器发送的报文当中的SYN位被设置为1,表示请求与服务器建立连接。
第二次握手:服务器收到客户端发来的连接请求报文后,紧接着向客户端发起连接建立请求并对客户端发来的连接请求进行响应,此时服务器向客户端发送的报文当中的SYN位和ACK位均被设置为1
第三次握手:客户端收到服务器发来的报文后,得知服务器收到了自己发送的连接建立请求,最后客户端再向服务器发来的报文进行响应
为什么两次握手不行,非得三次:
- 两次握手不行,是因为无法确认客户端和服务器都具备“收发能力”
- 三次握手是验证双方通信信道的最小次数,让能建立的连接尽快建立起来。
四次挥手
第一次挥手:客户端向服务器发送的报文当中的FIN位被设置为1,表示请求与服务器断开连接。
第二次挥手:服务器收到客户端发来的断开连接请求后对其进行响应。
第三次挥手:服务器收到客户端断开连接的请求,且已经没有数据需要发送给客户端的时候,服务器就会向客户端发起断开连接请求。
第四次挥手:客户端收到服务器发来的断开连接请求后对其进行响应
三次握手是连接建立,四次挥手是连接关闭,两者结构不同是因为TCP是全双工通信,两边都需单独关闭。
13. 说一下网络四层模型?每层分别有哪些协议?
网络四层模型如下(自上而下):
应用层:提供用户接口 协议:HTTP、FTP、DNS、SMTP、SSH
传输层:端到端通信 协议:TCP(可靠)、UDP(快速)
网络层:实现路由转发 协议:IP、ICMP、ARP、IGMP
链路层:物理地址通信 协议:Ethernet(以太网)、PPP、MAC、Wi-Fi 等
==============================
4. linux查看某进程的命令
- ps -aux | grep PID
- netstat -ano | grep 80
5. 说说软链接和硬链接的区别
软链接(符号链接):是一个特殊文件,保存的是目标文件路径,类似快捷方式,可以跨文件系统,可以链接目录,原文件删除后软链接失效(变成悬挂链接
硬链接:多个文件名指向同一个inode,不能跨文件系统,不能链接目录。删除原文件不影响其他硬链接,
6. 简述Linux系统态与用户态,什么时候会进入系统态?
用户态:程序正常运行时所在的状态,权限受限。
系统态:操作系统内核执行任务的状态,权限高。
当发生:系统调用(如 read
、write
)中断处理(如外设中断)异常处理(如除零错误)
8. 说一下线程 posix,相关函数
pthread_create
:创建线程pthread_join
:等待线程结束pthread_exit
:线程退出pthread_cancel
:取消线程pthread_detach
:分离线程(结束后自动回收资源)pthread_mutex_init
/lock
/unlock
/destroy
:互斥锁操作pthread_cond_init
/wait
/signal
/broadcast
/destroy
:条件变量操作
需要加头文件:#include <pthread.h>
,链接时加 -lpthread
。
9. 怎么实现生产者和消费者模块
生产者负责生成数据,放入缓冲区
消费者从缓冲区取数据处理
通过互斥锁(mutex)和条件变量(condition variable)保证线程安全和同步,防止资源冲突和空/满队列问题
12. 你知道那些网络相关的协议
HTTP网页传输、FTP文件传输、DNS域名解析、SMTP邮件收发、SSH远程登录
17. Linux上socket套接字编程,写一个TCP服务器需要那些接口
- socket bind listen accept read write
18. 信号了解吗
- 本质是一种通知机制,由用户or操作系统通过发送一定的信号,通知进程,但不是需要立即处理,你可以在后续进行处理
- 而在linux中查看信号的命令是:kill -l
19. 信号处理的过程
21. Linux下最快的进程间通信方式是,为什么?
- 共享内存
- 无需拷贝:共享内存直接映射到多个进程地址空间,不需要数据在内核和用户空间之间来回拷贝;
22. Linux下gdb调试命令
i: 显示行号
b+行号:打断点 d+断点编号:删除断点 info b:查看断点
r: 运行 s:逐语句 n:逐过程
23. TCP和UDP的区别
- TCP面向连接字节流,有连接,可靠,且只能点对点通信
- UDP面向报文,无连接,不可靠,可以1对多,多对多通信
24. OSI七层网络协议都有哪些?
- 应用层、表示层、会话层、传输层、网络层、数据链路层、物理层
26. 说一下网络io模型
阻塞 I/O:调用后一直阻塞,直到数据准备好并读取完成,简单但效率低,适合小并发
非阻塞 I/O :立即返回,如果没数据就返回错误,需轮询,占 CPU,效率不高
I/O 多路复用(select
/ poll
/ epoll
):等待多个 socket,有就绪的才去读写,适合高并发连接
信号驱动 I/O: 数据就绪时内核发信号通知进程,用得少,复杂
27. 说说linux多路IO复用技术有哪些,区别是什么
select poll epoll
- select有fd数量限制,poll和epolll没有fd数量限制
- 从事件通知方式来说:select和poll是遍历查询,而epoll是事件驱动通知(只返回活跃的fd)
- select不支持大量连接,poll和epoll都支持大量连接,且在高并发的情况下效率更高
28. epoll为什么高效?
事件驱动机制:有事件的/活跃 fd 才会被通知,不用轮询全部 fd
fd 无需重复传入:注册一次,后续内核直接管理
支持边沿触发(ET):减少系统调用次数(有变化才通知)
支持大规模连接:适合成千上万的并发 socket