您的位置:首页 > 运维架构 > Linux

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

2017-05-12 11:23 447 查看
以下复习资料仅供参考,并非面试真题。

用过的 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 :手动解除系统上共享内存的分配,删除消息队列、信号集、或者共享内存标识。

文件操作函数

a. Linux API: create:创建,umask:去掉一些权限,open:打开;write,read:读写;lseek: 定位;close:关闭

b. C 库(FILE ): fopen:创建打开;fclose:关闭;fileno:FILE转 fd;fgets;fprintf,fread

共享内存可以通过 mmap()映射普通文件(特殊情况下还可以采用匿名映射)机制实现, 也可以通过 System V 共享内存机制实现。

mmap 的机制:在磁盘上建立一个文件,每个进程存储器里面,单独开辟一个空间来进 行映射。mmap 保存到实际硬盘。优点:储存量可以很大(多于主存);缺点:进程间读 取和写入速度要比主存的要慢。。

shm 的机制:每个进程的共享内存都直接映射到实际物理存储器里面。shm 保存到物理存储器(主存),实际的储存量直接反映到主存上。优点,进程间访问速度(读写)比磁 盘要快;缺点,储存量不能非常大(多于主存) 。

使用上看:如果分配的存储量不大,那么使用 shm;如果存储量大,那么使用 mmap。

进程 VS 线程

进程资源管理和分配的基本单位,每个进程都有自己的地址空间。进程由程序代码、代码 相关的数据集和进程控制块(PCB)3 部分组成。

线程CPU 调度和分派的基本单位,线程是属于进程的,它运行在进程空间内,同一进程所产生的线程共享同一内存空间。每个线程有独立的栈和线程控制块(TCB,包含寄存器的值、 程序计数器、优先级等)。

并发度:两者都可提高并发度

开销:线程执行开销小,但不利于资源管理和保护,进程创建和销毁系统都要分配和回 收资源,开销大。

速度:线程的产生、通信、切换都比较快;

资源利用率:线程的资源利用率好,因为共享数据;

同步:线程使用公共变量和内存时需使用同步机制。

资源:线程不拥有系统资源,但可以使用进程的资源。

适用情况:线程适合在 SMP(多处理器)的机器上运行,进程可跨机器迁移。

为什么需要用户态和内核态?

保护操作系统和重要的操作系统表(如进程控制块)不受用户程序的干涉。

操作系统的内容分为哪几块?

进程管理、存储管理、设备管理、文件管理。

进程间通信方式有哪些?

无名管道( pipe ):半双工,数据只能单向流动,只能在具有亲缘关系的进程间使用。(进程 先调用 pipe,再 fork)

高级管道(popen):将另一个程序当做一个新的进程在当前程序进程中启动,则它算是当前 程序的子进程,这种方式为高级管道方式。(调用 popen,它封装的内容:先调用 pipe 创建 管道,之后 fork,子进程调用 exec 执行其他程序)

有名管道 (named pipe): 有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。又称作 FIFO,调用 mkfifo 函数创建。

消息队列( message queue ): 消息队列是消息的链表,存放在内核中并由消息队列标识符 标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等 缺点。

信号量( semophore ): 信号量是一个计数器,可以用来控制多个进程对共享资源的访问。

信号 ( sinal ): 信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。

共享内存( shared memory ):共享内存就是映射一段能被其他进程所访问的内存,这段共 享内存由一个进程创建,但多个进程都可以访问,是最快的 IPC 方式

套接字( socket ):可用于不同机器间的进程通信。(含 UNIX 域套接字: 类似套接字和管道 的混合,用于同一机器上的进程通信 socketpair 创建一对无命名的、相互连接的 UNIX 域套 接字)

列出常见的信号,以及信号怎么处理?

a. 指定函数来处理。 b. 忽略。 c. 缺省

进程通过系统调用 signal 来指定进程对某个信号的处理行为。在进程表的表项中有一个软中断信号域,该域中每一位对应一个信号,当有信号发送给进程时,对应位置位。对于同一个信号,进程并不知道在处理之前来过多少个

SIGHUP 终端挂起或者控制进程终止

SIGINT 键盘中断(如 break 键被按下)

SIGQUIT 键盘的退出键被按下

SIGKILL 信号

SIGPIPE 管道破裂: 写一个没有读端口的管道

SIGALRM 由 alarm(2)发出的信号

SIGTERM 终止信号

SIGCHLD 子进程结束信号

**信号 SIGKILL 和 SIGSTOP 既不能被捕捉,也不能被忽略。

什么是死锁?如何避免死锁?

死锁的条件

互斥条件(Mutualexclusion):资源不能被共享,只能由一个进程使用。

请求与保持条件(Hold andwait):已经得到资源的进程可以再次申请新的资源。

非剥夺条件(Nopre-emption):已经分配的资源不能从相应的进程中被强制地剥夺。

循环等待条件( Circularwait ):系统中若干进程组成环路,该环路中每个进程都在等待相 邻进程正占用的资源。

处理死锁的策略

a. 忽略该问题。例如鸵鸟算法,该算法可以应用在极少发生死锁的的情况下。

b. 检测死锁并且恢复。

c. 仔细地对资源进行动态分配,以避免死锁。

d. 通过破除死锁四个必要条件之一,来防止死锁产生。

进程调度策略

FCFS(先来先服务),优先级,时间片轮转,多级反馈。

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

linux 系统的同步机制

互斥量、读写锁(读锁是共存的,锁是互斥的)、 条件变量、自旋锁、屏障、信号灯。

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

文件描述符

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

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

动态链接和静态链接的区别

动态链接:只建立一个引用的接口,真正的代码和数据存放在另外的可执行模块中,在运行 时再装入;

静态链接:把所有的代码和数据都复制到本模块中,运行时就不再需要库了。

exit() 与 _exit() 的区别

_exit:不关闭文件,不清除输出缓存,也不调用出口函数。

Exit:关闭所有文件,缓冲输出内容将刷新定义,并调用所有已刷新的“出口函数”。

makefile 编写

hello.o:hello.c hello.h
gcc –c hello.o -Lm


进程守护化

a. 屏蔽有关控制终端操作的信号,防止守护进程没有正常运作之前控制终端受到干扰退出或挂起。

b. 后台运行(fork 后父进程 exit,此时进程不是会话首进程)。

c. 脱离控制终端,登陆会话和进程组:setsid()。 此时进程是新的会话首进程。

d. 再次 fork,exit 父进程,不再是会话首进程。

e. 关闭打开的文件描述符,工作目录切换到根目录

虚拟内存

物理内存:真实插在板子上的内存条。

虚拟内存: 只是内存管理的一种抽象。当正在运行的进程所需的内存大于内存条容量之和 的,势必有一部分数据要放到其他介质中(比如硬盘),待进程需要访问那部分数据时,再 通过调度进入物理内存。所以,虚拟内存是进程运行时所有内存空间的总和,并且可能有一 部分不在物理内存中。

计算机会对虚拟内存地址空间(32 位为 4G)分页,对物理内存地址空间(假设 256M)分 页产生页帧,这个页和页帧的大小是一样大的(于是虚页数多于页帧数)。 计算机上有一个页表,是页号到页帧号的映射,而且是一对一的映射。操作系统有个页面失 效功能,即找到一个最少使用的页帧,让他失效,并把它写入磁盘,随后把需要访问的页放 到页帧中,并修改页表中的映射,这样就保证所有的页都有被调度的可能了。

虚拟内存地址由页号和偏移量组成。

转换:页号->页帧号, 页帧号(前 m 位)+偏移量(后 n 位)=物理地址

虚拟内存地址的大小与地址总线位数相关,物理内存地址的大小跟物理内存条的容量相关。

GDB 调试

r(run)运行

br(break)设置断点

l(list)列出源码

info br(查看断点信息)

n单句执行(不进入函数)

c 继续运行

p 打印

bt 查看堆栈

linux 的任务调度机制

每个进程的 task_struct 结构中有以下四项: policy、 priority、 counter、 rt_priority。

policy 是进程的调度策略,实时进程优先于普通进程运行;

priority 是进程 ( 包括实时和普通 ) 的静态优先级;

counter 是进程剩余的时间片,起始值就是 priority 的值; ( 计算 goodness 时起重要作用)

rt_priority 是实时进程特有的,用于实时进程间的选择。

用函数 goodness() 来衡量一个处于可运行状态的进程值得运行的程度。该函数综合了以上 提到的四项,还结合了一些其他的因素,给每个处于可运行状态的进程赋予一个权值 (weight) ,调度程序以这个权值作为选择进程的唯一依据。

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

int k=~0;
if ( (unsigned int)k > 65535 )
cout<<"at least 32bits"<<endl;
else
cout << "16 bits" << endl;


写一个 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: