【C++后台开发面试】Linux系统相关

版权声明:本文为博主原创文章,转载请注明出处http://blog.csdn.net/jiange_zh https://blog.csdn.net/jiange_zh/article/details/71713284

以下复习资料仅供参考,并非面试真题。

  1. 用过的 linux 指令
    netstat : 显示网络状态 (-a 所有选项,-t 仅显示 tcp,-u 仅显示 udp,-r 路由表)
    tcpdump : 截获当前所有通过本机网卡的数据包。
    -i 指定网卡 tcpdump tcp port 23 and host XXX 获取从主机 XXX 接收或发出的 telnet 包
    top:任务管理器、ping、ps:查看进程状态、kill 发信号、man 帮助文档、chmod 修改权 限、scp:远程文件复制、cat:查看文件内容
    ipcs :检查系统上共享内存的分配,报告进程间通信设施状态。
    ipcrm :手动解除系统上共享内存的分配,删除消息队列、信号集、或者共享内存标识。

  2. 文件操作函数
    a. Linux API: create:创建,umask:去掉一些权限,open:打开;write,read:读写;lseek: 定位;close:关闭
    b. C 库(FILE ): fopen:创建打开;fclose:关闭;fileno:FILE转 fd;fgets;fprintf,fread

  3. 共享内存可以通过 mmap()映射普通文件(特殊情况下还可以采用匿名映射)机制实现, 也可以通过 System V 共享内存机制实现。
    mmap 的机制:在磁盘上建立一个文件,每个进程存储器里面,单独开辟一个空间来进 行映射。mmap 保存到实际硬盘。优点:储存量可以很大(多于主存);缺点:进程间读 取和写入速度要比主存的要慢。。
    shm 的机制:每个进程的共享内存都直接映射到实际物理存储器里面。shm 保存到物理存储器(主存),实际的储存量直接反映到主存上。优点,进程间访问速度(读写)比磁 盘要快;缺点,储存量不能非常大(多于主存) 。
    使用上看:如果分配的存储量不大,那么使用 shm;如果存储量大,那么使用 mmap。

  4. 进程 VS 线程
    进程资源管理和分配的基本单位,每个进程都有自己的地址空间。进程由程序代码、代码 相关的数据集和进程控制块(PCB)3 部分组成。
    线程CPU 调度和分派的基本单位,线程是属于进程的,它运行在进程空间内,同一进程所产生的线程共享同一内存空间。每个线程有独立的栈和线程控制块(TCB,包含寄存器的值、 程序计数器、优先级等)。
    并发度:两者都可提高并发度
    开销:线程执行开销小,但不利于资源管理和保护,进程创建和销毁系统都要分配和回 收资源,开销大。
    速度:线程的产生、通信、切换都比较快;
    资源利用率:线程的资源利用率好,因为共享数据;
    同步:线程使用公共变量和内存时需使用同步机制。
    资源:线程不拥有系统资源,但可以使用进程的资源。
    适用情况:线程适合在 SMP(多处理器)的机器上运行,进程可跨机器迁移。

  5. 为什么需要用户态和内核态?
    保护操作系统和重要的操作系统表(如进程控制块)不受用户程序的干涉。

  6. 操作系统的内容分为哪几块?
    进程管理、存储管理、设备管理、文件管理。

  7. 进程间通信方式有哪些?
    无名管道( pipe ):半双工,数据只能单向流动,只能在具有亲缘关系的进程间使用。(进程 先调用 pipe,再 fork)
    高级管道(popen):将另一个程序当做一个新的进程在当前程序进程中启动,则它算是当前 程序的子进程,这种方式为高级管道方式。(调用 popen,它封装的内容:先调用 pipe 创建 管道,之后 fork,子进程调用 exec 执行其他程序)
    有名管道 (named pipe): 有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。又称作 FIFO,调用 mkfifo 函数创建。
    消息队列( message queue ): 消息队列是消息的链表,存放在内核中并由消息队列标识符 标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等 缺点。
    信号量( semophore ): 信号量是一个计数器,可以用来控制多个进程对共享资源的访问。
    信号 ( sinal ): 信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。
    共享内存( shared memory ):共享内存就是映射一段能被其他进程所访问的内存,这段共 享内存由一个进程创建,但多个进程都可以访问,是最快的 IPC 方式
    套接字( socket ):可用于不同机器间的进程通信。(含 UNIX 域套接字: 类似套接字和管道 的混合,用于同一机器上的进程通信 socketpair 创建一对无命名的、相互连接的 UNIX 域套 接字)

  8. 列出常见的信号,以及信号怎么处理?
    a. 指定函数来处理。 b. 忽略。 c. 缺省
    进程通过系统调用 signal 来指定进程对某个信号的处理行为。在进程表的表项中有一个软中断信号域,该域中每一位对应一个信号,当有信号发送给进程时,对应位置位。对于同一个信号,进程并不知道在处理之前来过多少个
    SIGHUP 终端挂起或者控制进程终止
    SIGINT 键盘中断(如 break 键被按下)
    SIGQUIT 键盘的退出键被按下
    SIGKILL 信号
    SIGPIPE 管道破裂: 写一个没有读端口的管道
    SIGALRM 由 alarm(2)发出的信号
    SIGTERM 终止信号
    SIGCHLD 子进程结束信号
    **信号 SIGKILL 和 SIGSTOP 既不能被捕捉,也不能被忽略。

  9. 什么是死锁?如何避免死锁?
    死锁的条件
    互斥条件(Mutualexclusion):资源不能被共享,只能由一个进程使用。
    请求与保持条件(Hold andwait):已经得到资源的进程可以再次申请新的资源。
    非剥夺条件(Nopre-emption):已经分配的资源不能从相应的进程中被强制地剥夺。
    循环等待条件( Circularwait ):系统中若干进程组成环路,该环路中每个进程都在等待相 邻进程正占用的资源。
    处理死锁的策略
    a. 忽略该问题。例如鸵鸟算法,该算法可以应用在极少发生死锁的的情况下。
    b. 检测死锁并且恢复。
    c. 仔细地对资源进行动态分配,以避免死锁。
    d. 通过破除死锁四个必要条件之一,来防止死锁产生。

  10. 进程调度策略
    FCFS(先来先服务),优先级,时间片轮转,多级反馈。

  11. 内存分配算法:首次适应(最好),循环首次适应,最佳适应(内存碎片),最差适应

  12. linux 系统的同步机制
    互斥量、读写锁(读锁是共存的,锁是互斥的)、 条件变量、自旋锁、屏障、信号灯。

  13. 线程难题:死锁、数据竞争、优先权倒置、无限延迟

  14. 文件描述符
    fd 只是一个整数,起索引的作用,进程通过 PCB 中的文件描述符表找到该 fd 所指向的文件 指针,指针指向 file 结构体。流返回的是一个 FILE 结构指针, FILE 结构是包含有文件描述符 的,FILE 结构函数可以看作是对 fd 直接操作的系统调用的封装, 它的优点是带有 I/O 缓存

  15. 函数库中的函数可以没有调用系统调用,也可以调用多个系统调用。

  16. 动态链接和静态链接的区别
    动态链接:只建立一个引用的接口,真正的代码和数据存放在另外的可执行模块中,在运行 时再装入;
    静态链接:把所有的代码和数据都复制到本模块中,运行时就不再需要库了。

  17. exit() 与 _exit() 的区别
    _exit:不关闭文件,不清除输出缓存,也不调用出口函数。
    Exit:关闭所有文件,缓冲输出内容将刷新定义,并调用所有已刷新的“出口函数”。

  18. makefile 编写

    hello.o:hello.c hello.h        
        gcc –c hello.o -Lm 
  19. 进程守护化
    a. 屏蔽有关控制终端操作的信号,防止守护进程没有正常运作之前控制终端受到干扰退出或挂起。
    b. 后台运行(fork 后父进程 exit,此时进程不是会话首进程)。
    c. 脱离控制终端,登陆会话和进程组:setsid()。 此时进程是新的会话首进程。
    d. 再次 fork,exit 父进程,不再是会话首进程。
    e. 关闭打开的文件描述符,工作目录切换到根目录

  20. 虚拟内存
    物理内存:真实插在板子上的内存条。
    虚拟内存: 只是内存管理的一种抽象。当正在运行的进程所需的内存大于内存条容量之和 的,势必有一部分数据要放到其他介质中(比如硬盘),待进程需要访问那部分数据时,再 通过调度进入物理内存。所以,虚拟内存是进程运行时所有内存空间的总和,并且可能有一 部分不在物理内存中。
    计算机会对虚拟内存地址空间(32 位为 4G)分页,对物理内存地址空间(假设 256M)分 页产生页帧,这个页和页帧的大小是一样大的(于是虚页数多于页帧数)。 计算机上有一个页表,是页号到页帧号的映射,而且是一对一的映射。操作系统有个页面失 效功能,即找到一个最少使用的页帧,让他失效,并把它写入磁盘,随后把需要访问的页放 到页帧中,并修改页表中的映射,这样就保证所有的页都有被调度的可能了。
    虚拟内存地址由页号和偏移量组成。
    转换:页号->页帧号, 页帧号(前 m 位)+偏移量(后 n 位)=物理地址
    虚拟内存地址的大小与地址总线位数相关,物理内存地址的大小跟物理内存条的容量相关。

  21. GDB 调试
    r(run)运行
    br(break)设置断点
    l(list)列出源码
    info br(查看断点信息)
    n单句执行(不进入函数)
    c 继续运行
    p 打印
    bt 查看堆栈

  22. linux 的任务调度机制
    每个进程的 task_struct 结构中有以下四项: policy、 priority、 counter、 rt_priority。
    policy 是进程的调度策略,实时进程优先于普通进程运行;
    priority 是进程 ( 包括实时和普通 ) 的静态优先级;
    counter 是进程剩余的时间片,起始值就是 priority 的值; ( 计算 goodness 时起重要作用)
    rt_priority 是实时进程特有的,用于实时进程间的选择。
    用函数 goodness() 来衡量一个处于可运行状态的进程值得运行的程度。该函数综合了以上 提到的四项,还结合了一些其他的因素,给每个处于可运行状态的进程赋予一个权值 (weight) ,调度程序以这个权值作为选择进程的唯一依据。

  23. 写一个 c 程序辨别系统是 16 位 or 32 位

    int k=~0; 
    if ( (unsigned int)k > 65535 ) 
        cout<<"at least 32bits"<<endl; 
    else 
        cout << "16 bits" << endl; 
  24. 写一个 c 程序辨别系统是大端 or 小端字节序

    
    #include <stdio.h> 
    
    typedef union{  
        unsigned short value;  
        unsigned char bytes[2]; 
    }Test; 
    
    int main(void) {     
        Test test_value;     
        test_value.value = 0x1234;
        if(test_value.bytes[0] == 0x12 && test_value.bytes[1] == 0x34)      
            printf("big ending");     
        else if(test_value.bytes[0] == 0x34 && test_value.bytes[1] == 0x12)      
            printf("little ending");     
        else      
            printf("use test_value error");     return 0; 
    }

猜你喜欢

转载自blog.csdn.net/jiange_zh/article/details/71713284