# 征战bat,后台开发面试题(五)——操作系统篇

题目列表

  • 什么是孤儿进程僵尸进程
  • 怎样创守护进程(附加)
  • 指针对应的地址是不是物理地址
  • 物理地址和虚拟地址通常叫做什么?缩写是什么
  • 操作系统的寻址方式
  • linux 中如何计算可用内存
  • linux 中如何用 top 命令中查看虚地址和实地址的信息(去除)
  • 如何用搜索引擎去了解 top 中的虚地址?不用搜索引擎怎么知道(去除)
  • top 的输出中哪些是表明了内存
  • 根据 top 计算可用内存有多少(去除)
  • 用 top 看耗性能的线程
  • 还有哪些命令可以找出性能瓶颈(去除)
  • epoll 与 select 比较
  • epoll 的缺点,如何克服缺点
  • epoll 机制中文件描述符就绪时如何从内核态通知到用户态的进程(去除)
  • epoll 实现(去除)
  • 说说同步与异步的区别
  • 进程间通信的方式(去除)
  • 进程间的通信有哪些机制?在资源内存方面比较如何
  • 同一进程线程间的通信;不同进程线程间的通信(去除)
  • 如何判断系统在哪些地方耗费性能
  • cpu 调度的单位是什么
  • 如何让多核 cpu 更好的利用资源
  • 什么是缺页
  • 如何控制两个进程对一个数据的访问?怎么处理加锁问题
  • 说一说协程
  • 是否了解 netstat
  • 在 shell 中用 ./a.out | wc -l 结果是多少?管道的输入是哪个进程的
  • 谈谈 Linux 的文件权限。让只有拥有者才能读写?让拥有者只能读和执行? 删除文件需要什么权限
  • 假如一个进程在对文件进行读写,管理员把文件删除了怎么办
  • 协程与进程线程比较有什么优势
  • 计算机从电源加载开始的启动过程
  • 什么是中断调用?中断程序的分类
  • lsof strace ptrace gdb 使用(去除)
  • 内核态和用户态的区别
  • 为什么需要内核态
  • 什么时候进入内核态
  • 多线程需要加锁的变量
  • 什么是死锁,如何防止死锁(附加)
  • 程序在内存中的布局
  • lsof作用和使用(附加)
  • strace作用和使用(附加)
  • ptrace作用和使用(附加)

题解

什么是孤儿进程僵尸进程,如何避免僵尸进程

  • 孤儿进程 父进程退出后,子进程还在运行,这些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。
  • 僵尸进程 如果子进程已经退出,但是父进程又没有调用wait/waitpid获取子进程的状态信息,释放它占用的资源,该子进程将成为僵尸进程。
  • 处理僵尸进程 需要找到其父进程:ps -ef | grep defunct_process_pid并kill掉
  • 避免僵尸进程:在fork子进程之后都要wait它们;同时,当子进程退出的时候,内核都会给父进程一个SIGCHLD信号,我们可以建立一个捕获SIGCHLD信号的处理函数,在函数体中调用wait(或waitpid),就可以清理退出的子进程以达到防止僵尸进程的目的

怎样创守护进程(附加)

  • fork创建子进程,并让父进程退出
  • setsid在子进程中创建新会话
  • chdir("/")改变当前目录为根目录
  • umask重设文件权限掩码
  • 关闭文件描述符(至少012)

指针对应的地址是不是物理地址

不是,是虚拟地址

物理地址和虚拟地址通常叫做什么?缩写是什么

  • 物理地址
  • 虚拟地址

操作系统的寻址方式

linux使用分页寻址的方式
linux的虚拟地址和线性地址直接对应

linux 中如何计算可用内存

free命令查看
可用内存=free+cached+buffers=total-used

top 的输出中哪些是表明了内存

top中指标:

  • PID:进程的ID
  • USER:进程所有者
  • PR:进程的优先级别,越小越优先被执行
  • VIRT:进程占用的虚拟内存
  • RES:进程占用的物理内存
  • SHR:进程使用的共享内存
  • S:进程的状态。S表示休眠,R表示正在运行,Z表示僵死状态,N表示该进程优先值为负数
  • %CPU:进程占用CPU的使用率
  • %MEM:进程使用的物理内存和总内存的百分比
  • TIME+:该进程启动后占用的总的CPU时间,即占用CPU使用时间的累加值。
  • COMMAND:进程启动命令名称

用 top 看耗性能的线程

top -H

epoll 与 select 比较

  • select,epoll都是IO多路复用的机制
  • 最大并发数:epoll>>select,select默认1024
  • select返回所有检测fd状态需要轮询fd状态,epoll_wait则只返回活跃连接的fd
  • select第次需要内核/用户空间内存拷贝,epoll则让内核和用户空间mmap一块内存

epoll 的缺点,如何克服缺点

epoll适用于有大师空闲连接的情况,假如网络中只有少数连接,并且都很活跃

说说同步与异步的区别

同步和异步关注的是消息通信机制。
同步是A发出一个调用后等待B完成返回结果再继续向下执行;
异步是A不需等待返回结果,继续处理其他事情,等B完成后再取回结果。

进程间的通信有哪些机制?在资源内存方面比较如何

  • 管道 命名管道和非命名管道,流式传输,linux下4k缓存
  • 内核消息队列
  • 信号量
  • 共享内存,最快的进程间通信方式
  • 信号
  • 套接字( socket ),可以跨主机通信

如何判断系统在哪些地方耗费性能

内存:top,free,sar,pmap,vmstat,mpstat,iostat,
cpu:top,vmstat,mpstat,iostat,sar
I/O:vmstat,mpstat,iostat,sar
进程:ps,top,ipcs,ipcrm
系统运行负载:uptime,w

  • ps:列出系统中正在运行的进程.ps告诉我们每个进程使用的内存量以及所消耗的CPU时间。

  • top:动态显示进程信息,对进程实时监控

  • free:显示系统使用和空闲的内存情况

  • pmap:可以显示进程占用的内存量。可以通过pmap找到占用内存量最多的进程。

  • sar:多方面对系统活动进行报告,包括磁盘IO,cpu效率,内存使用情况,系统调用情况,文件读写情况。

  • ipcs:提供进程间通信方式的信息,包括消息队列、共享内存、信号等

  • ipcrm:删除一个消息对象(消息队列、信号集或者共享内存标识)

  • vmstat:是Virtual Meomory Statistics(虚拟内存统计)的缩写,可对操作系统的虚拟内存、进程、CPU活动进行监控。它是对系统的整体情况进行统计

  • iostat:既可以显示CPU使用情况,也可以看到每个磁盘的IO情况.

  • mpstat:mpstat用在多处理器的服务器上,用来显示每一个CPU的状态。另外,mpstat也会显示所有处理器的平均状况。也可在/proc/stat中查看

  • uptime:显示系统已经运行了多长时间,它依次显示下列信息:当前时间、系统已经运行了多长时间、目前有多少登陆用户、系统在过去的1分钟、5分钟和15分钟内的平均负载。

  • w:查询登录当前系统的用户信息,以及这些用户目前正在做什么操作,另外load average后面的三个数字则显示了系统最近1分钟、5分钟、15分钟的系统平均负载情况

cpu 调度的单位是什么

线程

如何让多核 cpu 更好的利用资源

  • 合理配置服务运行的多进程(多线程)数
  • 对一些多进程(多线程)服务,将其进程(线程)绑定到指定核上运行,降低调度消耗等

什么是缺页

缺页中断就是要访问的页不在主存,需要操作系统将其调入主存后再进行访问

linux的内存管理采取的是分页存取机制,即程序的地址空间被划分成固定大小的区域,称为页,内存空间分成若干个与页大小相同的物理块。通过映射的方式将页离散分布到块中。为了保证物理内存能得到充分的利用,内核会在适当的时候将物理内存中不经常使用的数据页自动交换到虚拟内存的交换空间中,而将经常使用的信息保留到物理内存。
当进程访问到不在物理内存中的页时,便会触发缺页中断

如何控制两个进程对一个数据的访问?怎么处理加锁问题

  • 如果是使用原子操作则不必要加锁
  • 若是非原子操作,则锁作用相当于让一系列操作达到原子操作的效果
  • 在这系列操作前加锁,操作结束后解锁

说一说协程

协程是由
• 调度算法对于程序来说都是“被动”式的。比如调度算法会把CPU的时间分配给还在IO等待中的程序,虽jk然可以立即检查并交出CPU,但是这里还是有一个切换的过程。
• 协程可以说是“主动式”的,由程序来告诉计算机,我要进行等待IO行为了,可以把CPU的控制权交给别人,这个实现的基础是用户态的。所以,协程就是在用户态线程中,两个程序协商好了,通过某种方式协作运营,共享CPU控制权的方法。一般来说,这个协商的方法通用的关键字就是yield。

是否了解 netstat

netstat 命令用于显示各种网络相关信息,如网络连接,路由表,接口状态,masquerade 连接,多播成员等等。
常用的netstat选项包括:
-a : 所有socket信息,-l : 监听的socket
-t -u -x : 分别为TCP端口,UDP端口,UNIX端口
-r : 显示路由信息
-i : 显示网卡借口统计
-s : 显示网络协议统计
-p : 输出中显示 PID 和进程名称

在 shell 中用 ./a.out | wc -l 结果是多少?管道的输入是哪个进程的

输出一个整数,结果为a.out执行后标准输出的行数,管道输入为a.out的标准输出。

谈谈 Linux 的文件权限。让只有拥有者才能读写?让拥有者只能读和执行? 删除文件需要什么权限

文件权限 所有者的rwx,所在组的rwx,其他的rwx(rwx分别对应421)

  • 600 只有拥有者才能读写
  • 500 拥有者只能读和执行
  • 删除文件需要该文件所在目录的wx权限
    特殊权限
  • suid 4 使可执行文件的所有者以root权限运行该文件
  • sgid 2 使可执行文件的所有者能获取到该文件的组权限
  • sbit 1 使用户对于自己有写权限的目录下创建的文件目录,只有自己和root才能删除

假如一个进程在对文件进行读写,管理员把文件删除了怎么办

被程序打开的文件会在/proc//fd/下,删除文件仅删除了文件在磁盘上的inode引用减少了1,/proc//fd/还有该文件的引用,并且可以通过lsof查看到该文件对应的fd后,可以从/proc//fd/找到这个fd恢复该文件内容。

协程与进程线程比较有什么优势

进线程由操作系统进行调度,协程则由用户程序调度

  • 协程调度开销通常比进线程调度要小
  • 理论上协程能更好的避免无意义的调度来提高性能
  • 但程序必须由开发者承担调度的责任,一般而言协程不具有标准线程使用多CPU的能力

计算机从电源加载开始的启动过程

启动引导程序BIOS-自检-启动引导程序-加载操作系统(从磁盘读到RAM中)-读取配置文件)

什么是中断调用?中断程序的分类

  • 中断:系统执行期间,系统内发生急需处理事件,使得CPU暂时中断当前正在执行的程序而转去执行相应的事件处理程序。待处理完毕后又返回原来被中断处继续执行或调度新的进程执行的过程
  • 硬中断:由硬件引起的中断。如键盘、定时器,以及一些硬件故障等。硬中断又分为可屏蔽中断(如键盘产生的);非屏蔽中断(如由微处理器产生的);
  • 软中断:中断指令引起的中断。

内核态和用户态的区别

•当进程执行系统调用而陷入内核代码中执行时,我们就称进程处于内核态。此时处理器的特权级为0级。当进程处于内核态时,执行的内核代码会使用当前进程的内核栈。每个进程都有自己的内核栈
•当进程在执行自己的代码时,则称其处于用户态。即此时处理器在特权级最低的3级。当正在执行用户程序而突然被中断程序中断时,此时用户程序也可以象征性地称为处于进程的内核态。因为中断处理程序将使用当前进程的内核栈。

为什么需要内核态

进程处于内核态时,特权级最高,才能使用某些指令。在CPU的有些指令非常危险。所以,设计出用户态进行隔离,而一些必要时候就需要进入内核态执行这些指令

什么时候进入内核态

  • 进程执行系统调用而陷入内核代码中执行时
  • 用户程序被中断程序中断时,此时用户程序也可以象征性地称为处于进程的内核态

多线程需要加锁的变量

加锁通常针对的是一系列操作,而这一系列并非原子操作,这一系列操作并非并发安全。则需要加锁。
常见的有一些共享的有写操作的变量,一些不可重入函数等

什么是死锁,如何防止死锁(附加)

死锁是指多个进程相互对方释放共享资源的僵持形态,无外力作用下会无限的等待。
死锁的四个条件禁止抢占,持有和等待,互斥,循环等待
破坏死锁四个必要条件中的一个即可避免死锁,如资源有序分配等

程序在内存中的布局

从高地址到低地址依次是:

  • 命令行参数,环境变量
  • 栈(stack)
  • 可供堆栈增长的空间
  • 堆(heap)
  • 未初始化数据段(bss)
  • 已初始化数据段(data)
  • 代码段(code)

lsof作用和使用(附加)

列出当前系统打开文件(普通文件、目录、管道、socket等)

strace作用和使用(附加)

跟踪一个进程产生的系统调用(包括参数,返回值,执行消耗的时间)

ptrace作用和使用(附加)

提供了一种机制使得父进程可以观察和控制子进程的执行过程,同时提供查询和修改子进程的镜像和寄存器的能力。主要用于执行断点调试和系统调用跟踪。使用示例:

// long ptrace(enum __ptrace_request request, pid_t pid, void *addr, void *data);
// request:请求执行的行为,
// pid:目标进程标识。
// addr:执行 peek 和 poke 操作的目标地址。
// data:对于 poke 操作,存放数据的地方。对于 peek 操作,获取数据的地方。

#include 
#include 
#include 

int main () {
    pid_t fpid = fork();

    if (fpid < 0) {  // fork出错
        printf("error in fork!");
    } else if (fpid == 0) { // 子进程
        ptrace(PTRACE_TRACEME, 0, NULL, NULL); // 当前进程需要被trace
        execve(...); // 启动需要被跟踪的进程
    } else { // 父进程
        wait(); // 先等子进程准备好
        ptrace(...); // ... 对子进程干想干的事吧
    }
    return 0;
}

作者原创,转载请注明出处

你可能感兴趣的:(# 征战bat,后台开发面试题(五)——操作系统篇)