操作系统面试高频(三)
1.请你说说CPU工作原理⭐⭐
- 取指令(Instruction Fetch):CPU 从内存中获取当前要执行的指令。CPU 会根据指令寄存器中的指令地址,将指令从内存中读取到指令缓存(Instruction Cache)中。
- 解码指令(Instruction Decode):CPU 解析指令,确定指令的操作类型(如加载、存储、运算等),以及操作的操作数(如寄存器、内存地址等)。
- 执行指令(Execute):CPU 根据指令的操作类型和操作数执行相应的操作。这可能涉及数据的加载、存储、算术运算、逻辑运算、分支跳转等操作。
- 访问内存(Memory Access):如果指令需要访问内存(如加载、存储操作),CPU 将计算出需要读取或写入的内存地址,并将数据从内存中读取或写入。
- 写回结果(Write Back):如果执行的指令产生了结果,CPU 将结果写回到寄存器或内存中,以便后续的指令可以使用这些结果。
2.死锁的原因、条件?以及如何预防⭐⭐⭐
死锁: 是指多个进程在执行过程中,因争夺资源而造成了互相等待。此时系统产生了死锁。比如两只羊过独木桥,若两只羊互不相让,争着过桥,就产生死锁。
产生的条件:死锁发生有四个必要条件:
- 互斥条件:进程对已分配的资源独享,其他进程需要等待。
- 请求保持条件:进程需要持有已分配的资源,并继续请求其他资源,但他们无法满足请求,导致进程阻塞并保持对已有资源的持有。
- 不可剥夺条件:进程已经获得的资源不能被其他进程强制性剥夺。
- 环路等待条件:存在多个进程之间形成循环等待资源的关系。
对于预防死锁的方法,可以采取以下措施:
- 破坏互斥条件:尽可能地共享资源,而不是互斥地独占资源。
- 破坏请求保持条件:请求资源时先释放已占有的资源,再请求所需的资源,以避免持有资源的阻塞情况。
- 破坏不可剥夺条件:引入资源抢占机制,使得系统可以对进程已获取的资源进行剥夺。
- 破坏环路等待条件:通过合理的资源分配策略,避免形成循环等待的资源关系。
3.死锁与活锁⭐⭐
死锁(Deadlock)和活锁(Livelock)是多线程并发编程中的两种不同类型的问题。它们之间的区别如下:
死锁:
- 死锁指的是两个或多个线程彼此等待对方释放所持有的资源,从而导致所有线程都无法继续执行,程序无法继续运行的情况。
- 死锁是一种静止状态,线程被无限阻塞,直到外部干预,如强制终止某些线程。
- 死锁发生时,线程无法自行解锁,需要外部的干预来打破循环依赖,释放资源以解决死锁。
活锁:
- 活锁指的是多个线程不断重试,但最终无法取得进展的情况。线程们在不断改变自己的状态,但总是无法成功完成所需的操作。
- 活锁是一种动态状态,线程不断重试,但无法使程序向前推进。
- 活锁通常是由于竞争条件、过度的自旋等问题引起的。
解决活锁问题的一般策略包括:
- 引入随机性:通过引入随机因素,使线程的行为具有一定的不确定性,避免线程们不断重复相同的操作。
- 使用策略:在活锁发生时,采用某种策略,例如放弃一部分工作、转让任务或等待一段随机时间等。
- 调整线程优先级:适当调整线程的优先级,以改变线程的竞争行为。
- 重新设计算法和协调:如果活锁是由于设计问题引起的,需要重新设计算法或协调机制,以避免竞争条件。
4.说说sleep和wait的区别?⭐⭐⭐
sleep和wait的区别:
- 所属类别:sleep是Thread类的方法,而wait是Object类的方法。
- 锁的释放:在调用wait时,线程会释放它持有的锁,进入等待状态,并等待其他线程通过notify或notifyAll来唤醒它。而sleep方法不会释放锁,线程会保持对锁的持有。
- 唤醒方式:调用wait的线程必须依赖其他线程的notify或notifyAll来唤醒它,而sleep方法可以设定一个固定的时间,时间到后线程会自动唤醒。
- 使用场景:wait通常用于线程间的同步和协作,例如等待其他线程的信号或共享资源的通知。sleep适用于线程的暂时休眠,例如实现定时任务或控制线程执行间隔。
5. 简述epoll和select的区别,epoll为什么高效?⭐⭐⭐⭐
epoll:
- epoll是Linux提供的一种I/O事件通知机制,通过epoll系统调用实现。
- 它能够监视大量的文件描述符,并且在文件描述符就绪时触发相应的事件。
- epoll使用了边缘触发模式(EPOLLET),只有当文件描述符状态发生变化时才触发事件通知,避免了频繁的轮询操作,提高了I/O效率。
- epoll适用于大规模并发连接,具有较好的扩展性和性能优势。
Select:
- Select是一种传统的多路复用机制,通过select系统调用实现。
- 它能够监听一组文件描述符,并在其中任意一个文件描述符就绪时返回。
- 在使用select时,需要将文件描述符集合加入到fd_set中,并通过轮询操作检查是否有文件描述符就绪,然后进行相应的操作。
- Select适用于较小规模的连接,但在连接数较大时,效率会下降。
epoll为什么高效?
拷贝开销:
- 每次调用select,都需要将文件描述符集合从用户态拷贝到内核态,这个开销在文件描述符很多时会很大。
- epoll保证了每个文件描述符在整个过程中只会拷贝一次,因此不会有拷贝开销的增加。
遍历开销:
- 每次调用select,需要在内核遍历传递进来的所有文件描述符,即使只有很少的文件描述符就绪。
- epoll只需要轮询一次文件描述符集合,然后查看就绪链表中有没
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
c++/嵌入式面经专栏 文章被收录于专栏
BG双9,目前在某外企。打算把之前校招时做的笔记通过专栏发出来,本专栏适合于C/C++、嵌入式方向就业的同学,本篇面经总结数千篇面经的知识集合,实时更新全网最新的嵌入式/C++最新内容,囊括了C语言、C++、操作系统、计算机网络、嵌入式、算法与数据结构、数据库等一系列知识点,在我看来这些是求职者在面试中必须掌握的知识点。最后呢祝各位能找到自己合适的工作。。