C++/Linux(笔试/面试)_(2)
本文主要考察Linux系统编程中的核心概念,包括进程管理、系统调用、内存管理和环境变量等。重点内容有: 进程管理:fork()创建子进程的机制,wait/waitpid回收子进程资源,进程退出的方式(exit/_exit)及返回值获取 系统调用:区分库函数和系统调用,exec函数族的作用和参数特点 进程特性:孤儿进程和僵尸进程的区别,守护进程的特点 内存管理:分页存储中地址转换,虚拟地址到物理地址
1.下列关于make/Makefile描述正确的有( )[多选]
A.make会生成Makefile中定义的所有目标对象
B.make会自动根据依赖对象检测目标对象是否需要重新生成
C.Makefile中伪对象的功能是目标对象存在则不需要生成
D.Makefile中声明伪对象使用 .PHONY
1.BD
make的执行规则是,只生成所有目标对象中的第一个,当然make会根据语法规则,递归生成第一个目标对象的所有依赖对象后再回头生成第一个目标对象,生成后退出。因此A选项错误。
make在执行makefile规则中,根据语法规则,会分析目标对象与依赖对象的时间信息,判断是否在上一次生成后,源文件发生了修改,若发生了修改才需要重新生成。因此B选项正确
makefile中的伪对象表示对象名称并不代表真正的文件名,与实际存在的同名文件没有相互关系,因此伪对象不管同名目标文件是否存在都会执行对应的生成指令。伪对象的作用有两个,1. 使目标对象无论如何都要重新生成。2. 并不生成目标文件,而是为了执行一些指令。 根据对伪对象的理解,C选项错误
makefile中使用 .PHONY 来声明伪对象, .PHONY: clean。 D选项正确
2.以下哪项命令可以完成, 在gdb调试中,查看断点信息的功能( )
A.bt
B.show break
C.set scheduler-locking off
D.info break
2.D
- A bt 查看函数调用栈
- B show break info break 用于查看断点信息
- C set scheduler-locking off 用于后期多线程调试,关闭调度锁(所有线程同步执行)
- D info break 查看断点信息
3.. 冯诺依曼体系结构中数据输入设备有[多选]
A.键盘
B.显示器
C.内存
D.磁盘
3.AD
D 磁盘 既可以从硬盘读取数据也可以向硬盘写入数据
4.不属于冯诺依曼体系结构必要组成部分的是
A.CPU
B.Cache
C.RAM
D.ROM
4. B
A CPU 运算器与控制器
B Cache 缓存(一种技术)
C RAM 内存(存储器)
D ROM 磁盘(输入输出设备)
5.关于 linux 的进程,下面说法不正确的是
A.僵尸进程会被 init 进程接管,不会造成资源浪费;
B.孤儿进程的父进程在它之前退出,会被 init 进程接管,不会造成资源浪费;
C.进程是资源管理的最小单位,而线程是程序执行的最小单位。Linux 下的线程本质上用进程实现
D.子进程如果对资源只是进行读操作,那么完全和父进程共享物理地址空间。
5.A
A 僵尸进程指的是进程退出后不会完全释放资源,会造成系统资源泄漏;
B 孤儿进程在父进程退出后,父进程成为init进程,进程退出,孤儿进程的资源将被init进程释放
C 操作系统通过pcb实现对程序运行调度控制
D fork系统调用通过复制父进程创建一个子进程,父子进程数据独有,代码共享(在数据不发生改变的情况下父子进程资源指向同一块物理内存空间(调研写时拷贝技术))
6.孤儿进程会被以下哪一个系统进程接管
A.syslogd
B.init
C.sshd
D.vhand
6.B
孤儿进程:子进程先于父进程退出,运行在后台,父进程成为1号init进程(在centos7中1号进程改名为systemd进程),退出后由1号进程回收资源
syslogd:系统中的日志服务进程
init:init进程是内核启动的第一个用户级进程,用于完成处理孤儿进程以及其他的一些重要任务。
sshd:远程登录服务进程
vhand:内存置换服务进程
7.以下描述错误的有
A.守护进程:运行在后台的一种特殊进程,独立于控制终端并周期性地执行某些任务。
B.僵尸进程:一个进程 fork 子进程,子进程退出,而父进程没有 `wait`/`waitpid`子进程,那么子进程的进程描述符仍保存在系统中,这样的进程称为僵尸进程。
C.孤儿进程:一个父进程退出,而它的一个或多个子进程还在运行,这些子进程称为孤儿进程。(孤儿进程将由 init 进程收养并对它们完成状态收集工作)
D.精灵进程:精灵进程退出后会成为僵尸进程
7. D
僵尸进程:子进程先于父进程退出,父进程没有对子进程的退出进行处理,因此子进程会保存自己的退出信息而无法释放所有资源成为僵尸进程导致资源泄露。
孤儿进程:父进程先于子进程退出,子进程成为孤儿进程,运行在后台,父进程成为1号进程(而孤儿进程的退出,会被1号进程负责任的进行处理,因此不会成为僵尸进程)
守护进程&精灵进程:这两种是同一种进程的不同翻译,是特殊的孤儿进程,不但运行在后台,最主要的是脱离了与终端和登录会话的所有联系,也就是默默的运行在后台不想受到任何影响
根据以上理解分析:
D错误:精灵进程其实和守护进程是一样的,不同的翻译叫法而已,它的父进程是1号进程,退出后不会成为僵尸进程
8.冯诺依曼体系结构计算机的基本原理是
A.信息存储
B.存储智能
C.数字控制
D.存储程序和程序控制
8. D
计算机就是为了完成指定的数据处理,而通过指令按指定流程完成指定功能,指令的合集就是一段程序。说白了计算机就是按照指定的指令执行流程完成对指定数据的处理
9.操作系统的主要功能有
A.控制和管理计算机系统软硬件资源
B.对汇编语言,高级语言和甚高级语言程序进行翻译
C.管理用各种语言编写的源程序
D.管理数据库文件
9.A
操作系统的定位就是控制和管理计算机上软硬件资源让计算机更加好用,因此A选项是 正确的
对汇编语言,高级语言和甚高级语言程序进行翻译,这个功能是编译器的功能,将高级语言解释为机器指令能够被机器识别执行。因此B选项不正确,这不是操作系统的主要功能,而是一个外部应用的主要功能
源程序以及数据库文件都是存储在磁盘上的,这是操作系统中,文件系统管理部分的主要功能,因此C和D选项不正确。
10.下面关于系统调用的描述中,错误的是
A.系统调用把应用程序的请求传输给系统内核执行
B.系统调用函数的执行过程应该是在用户态
C.利用系统调用能够得到操作系统提供的多种服务
D.是操作系统提供给编程人员的接口
E.系统调用给用户屏蔽了设备访问的细节
F.系统调用保护了一些只能在内核模式执行的操作指令
10.B
系统调用是操作系统向上层提供的用于访问内核特定功能的接口。
A正确,应用程序通过系统调用将自己需要完成的功能传递给内核,进行执行完成
B错误,系统调用的运行过程是在内核态完成的,操作系统并不允许用户直接访问内核,也就是说用户运行态并不满足访问内核的权限。
C正确,因为系统调用就是想上层提供用于完成特定内核服务或功能的。
D正确,
E正确,用户只需要将自己的请求以及数据通过系统调用接口传递给内核,内核中完成对应的设备访问过程,最终返回结果正确
F正确,系统向上层提供系统调用接口用于访问内核服务或功能的很大原因也是因为这样可以最大限度的保护内核的稳定运行。
11.下面的函数哪个是系统调用而不是库函数
A.printf
B.scanf
C.fgetc
D.read
E.print_s
F.scan_s
11.D
库函数是用户对系统调用接口的进一步封装接口
printf函数是glibc中封装的用于实现格式化输出的接口
scanf函数是glibc中封装的用于实现格式化输入的接口
fgetc函数是glibc中封装的用于实现从输入流中获取字符的接口
read是系统提供的用于从输入设备获取数据的接口
print_s以及scan_s这两个函数不存在,至少在C语言的常见典型的跨平台移植代码库中不存在。
12.下列有关进程的说法中,错误的是 [多选]
A.进程与程序是一一对应的
B.进程与作业是一一对应的
C.进程是静态的
D.进程是动态的过程
12.ABC
程序是静态的指令集合,保存在程序文件中,
进程是程序的一次运行过程中的描述。
作业是用户需要计算机完成的某项任务,是要求计算机所做工作的集合。
根据以上概念理解:
A选项错误,因为一个程序可以同时运行多次,也就有了多个进程
B选项错误,因为一个作业任务的完成可由多个进程组成,且必须至少由一个进程组成
C选项错误,因为程序是静态的,而进程是动态的。
D选项正确
13.系统感知进程的唯一实体是
A.进程id
B.进程控制块
C.进程管理器
D.进程名
13.B
进程是操作系统对于程序运行过程的描述,而这个描述学名叫做进程控制块-PCB,它是操作系统操作系统管理以及调度控制程序运行的唯一实体。
根据进程的理解分析:
A选项错误,因为进程ID只是进程的标识符,是系统能够找到特定进程的标识而已
C选项错误,进程管理器只是对大量PCB进行管理的一个程序而已
D选项错误,进程本质上来说没有名字,它有所调度管理运行的程序的名称,它的标识是进程ID,可以理解进程ID是它的名字
因此只有B选项正确,在系统角度看来,进程就是对于程序运行的描述,就是PCB进程控制块。
14.在抢占式多任务处理中,进程被抢占时,哪些运行环境需要被保存下来[多选]
A.所有cpu寄存器的内容
B.全局变量
C.页表指针
D.程序计数器
14.ACD
A 所有cpu寄存器的内容 cpu上正在处理的数据
B 全局变量 程序内的数据(并不一定正在被处理)
C 页表指针 程序切换时会将页表起始地址加载到寄存器中
D 程序计数器 下一步程序要执行的指令地址
15.一个分页存储管理系统中,地址长度为 32 位,其中页号占 8 位,则页表长度是
A.2的8次方
B.2的16次方
C.2的24次方
D.2的32次方
15.A
页号即页表项的序号,总共占8个二进制位,意味着页表项的个数就是2^8
16,p和"hello,world"存储在内存哪个区域
int main()
{
char *p = "hello,world";
return 0;
}
A.栈,堆
B.栈,栈
C.堆,只读存储区
D.栈,只读存储区
16. D
p是一个局部指针变量,本身空间在栈中,而空间中存储的地址指向的是一块常量字符串的地址,常量字符串存储在只读存储区
17.在CPU和物理内存之间进行地址转换时,( )将地址从虚拟(逻辑)地址空间映射到物理地址空间
A.TCB
B.MMU
C.CACHE
D.DMA
17. B
A TCB 线程控制块
B 内存管理单元,一种负责处理中央处理器(CPU)的内存访问请求,功能包括虚拟地址到物理地址的转换(即虚拟内存管理)、内存保护、中央处理器高速缓存的控制
C CACHE 高速缓存
D DMA 直接内存存取
18.使用shell时,默认的环境变量放在哪里
A.~/.bash_profile
B.~/.bash
C./etc/profile.d
D.~/bash
18.A
~/.bash_profile:用户级的环境配置文件,每个用户目录下都会具有各自的,在用户每次登录系统时被读取,里面所有命令都会被shell执行。包括环境变量的配置命令,因此A正确
~/.bash 以及 ~/bash 在linux的用户目录中默认是没有这两个文件的,因此也就不清楚其作用了,因此B和D都是错误的
/etc/progile.d 这是个目录或者说文件夹,其中包含了系统级的环境配置文件,任意用户登录时都会执行这个目录下的环境配置文件完成环境配置,但是要注意这个是目录并不是保存环境变量配置的配置文件,因此D错误
19.以下哪些命令可以查看环境变量 [多选]
A.echo
B.env
C.set
D.export
19.ABC
- echo 用于输出打印一个变量的内容,包括环境变量
- env 用于打印所有环境变量信息
- set 用于输出打印所有环境配置以及变量信息,不限于环境变量
- export用于设置环境变量
20.以下描述正确的有 [多选]
A.子进程默认会复制拥有与父进程相同的环境变量
B.环境变量使shell运行环境配置变的更加复杂
C.环境变量可以使用export命令设置
D.删除一个环境变量可以使用unset和rm命令
20.AC
- B选项错误 环境变量设置之后,不需要重启shell,也不需要重新加载文件,只要设置换环境变量就能直接生效,因此可以使运行环境的配置更加灵活简单
- D选项错误 rm只是普通的文件操作指令,无法删除环境变量
21.不算 main 这个进程自身,创建了多少个进程
int main(int argc, char* argv[])
{
fork();
fork() && fork() || fork();
fork();
}
A.18
B.19
C.20
D.21
.21. B(画图画对了,只能说起飞,也可能是碰巧)
fork()创建子进程成功,父进程返回子进程的pid是大于0的 为真
子进程返回的是0 为假;
根据if语句的与和或逻辑进行判断即可
例如:
将fork进行编号 2号fork创建子进程后父进程为真,则父进程的3号fork会被执行,
然而其子进程返回0为假,则子进程的3号fork不会被执行。。。
主进程和1号子进程都会创建2号子进程和3号子进程,但是不会创建4号子进程,然后创建5号
主进程每次返回真,创建2号子进程,3号子进程,5号子进程
1号每次返回真,创建2号子进程,3号子进程,5号子进程
2号自己为假,会创建4号子进程和5号子进程
3号自己为假,会创建4号子进程和5号子进程
4号自己为假,只会创建5号
主-1 主进程创建1号后与1号雷同 因此进程数 10 * 2 = 20 减去主进程自身:19
|-2
|-4 2号自己为假,会创建4号子进程
|-5 4号自己为假,只会创建5号
|-5 2号自己为假,会创建5号子进程
|-3 主/1号进程,创建2号返回真后创建3号进程
|-4 3号自己为假,会创建4号子进程
|-5 4号自己为假,只会创建5号
|-5 3号自己为假,会创建5号子进程
|-5
22.关于pid_t waitpid(pid_t pid,int *status,int options);函数,以下描述错误的是
A.若pid大于0,则表示等待指定的子进程退出
B.若pid等于-1,则表示等待任意一个子进程退出
C.status参数可以用于获取退出子进程的退出码
D.若options选项参数被设置为WNOHANG则waitpid为一直阻塞
22.D
waitpid默认阻塞等待任意一个或指定子进程退出,当options被设置为WNOHANG则函数非阻塞,且当没有子进程退出时,waitpid返回0
23.通过fork和exec系统调用可以产生新进程,下列有关fork和exec系统调用说法正确的是多选]
A.fork生成的进程是当前进程的一个相同副本
B.fork系统调用与clone系统调用的工作原理基本相同
C.exec生成的进程是当前进程的一个相同副本
D.exec系统调用与clone系统调用的工作原理基本相同
23.AB
A fork调用通过复制父进程创建子进程,子进程与父进程运行的代码和数据完全一样
B fork创建子进程就是在内核中通过调用clone实现
C exec是程序替换函数,本身并不创建进程
D clone函数的功能是创建一个pcb,fork创建进程以及后边的创建线程本质内部调用的clone函数实现,而exec函数中本身并不创建进程,而是程序替换,因此工作机理并不相同
24.下面哪些属于,Fork后子进程保留了父进程的什么?[多选]
A.环境变量
B.父进程的文件锁,pending alarms和pending signals
C.当前工作目录
D.进程号
.24. AC
fork函数功能是通过复制父进程,创建一个新的子进程。
- A选项正确:环境变量默认会继承于父进程,与父进程相同
- B选项错误:信号相关信息各自独立,并不会复制
- C选项正确:工作路径也相同
- D选项错误:每个进程都有自己独立的标识符
25.以下不是进程等待功能的是
A.获取子进程的退出码
B.释放僵尸子进程资源
C.等待子进程退出
D.退出指定子进程
25.D
进程等待:等待子进程退出,获取子进程返回值,释放子进程资源,避免出现僵尸进程
26.关于waitpid函数WNOHANG参数的描述正确的是[多选]
A.子进程默认会复制拥有与父进程相同的环境变量
B.环境变量使shell运行环境配置变的更加复杂
C.环境变量可以使用export命令设置
D.删除一个环境变量可以使用unset和rm命令
26.BD
waitpid默认阻塞等待任意一个或指定子进程退出,当options被设置为WNOHANG则函数非阻塞,且当没有子进程退出时,waitpid返回0,并不会阻塞。
27.以下描述正确的有
A.execl函数可以直接指定可执行程序文件的名称而不需要路径
B.execle函数可以直接指定可执行程序文件的名称而不需要路径
C.execl函数和execle函数的区别是是否自定义设置环境变量
D.execl函数和execlp函数的区别是是否自定义设置环境变量
27.C
#include <unistd.h> int execl(const char *path, const char *arg, ...); int execlp(const char *file, const char *arg, ...); int execle(const char *path, const char *arg, ...,char *const envp[]); int execv(const char *path, char *const argv[]); int execvp(const char *file, char *const argv[]); int execvpe(const char* file, char* const argv[], char* const envp[]); int execve(const char *path, char *const argv[], char *const envp[]);其中 l 和 v 的区别在于程序运行参数的赋予方式不同,l是通过函数参数逐个给与,最终以NULL结尾,而v是通过字符指针数组一次性给与。
其中有没有 p 的区别在于程序是否需要带路径,也就是是否会默认到path环境变量指定的路径下寻找程序,没有p的需要指定路径,有p的会默认到path环境变量指定路径下寻找
其中有没有 e 的区别在于程序是否需要自定义环境变量,没有e则默认使用父进程环境变量,有e则自定义环境变量。
28.以下描述正确的有[多选]
A.程序替换成功后,运行完新程序,依然会运行原有的代码
B.程序替换成功后,运行完新程序,则程序直接退出
C.程序替换成功后,原进程退出,创建新的进程运行新程序
D.程序替换成功后,原进程没有退出,使用原进程运行新程序
28.BD
- 程序替换是在当前进程pcb并不退出的情况下,替换当前进程正在运行的程序为新的程序(加载另一个程序在内存中,更新页表信息,初始化虚拟地址空间)
- 并且当前进程在运行完替换后的程序后就会退出,并不会继续运行原先的程序,这是尤其需要注意的。
29.如何使一个进程退出,以下错误的是
A.在程序的任意位置调用return
B.在main函数中调用return
C.在程序的任意位置调用exit接口
D.在程序的任意位置调用_exit接口
29. A
在普通函数中return退出的只是对应函数,而不是进程
30.以下关于进程退出描述正确的有[多选]
A.exit函数退出一个进程时会刷新文件缓冲区
B.exit函数退出一个进程时不会刷新文件缓冲区
C._exit函数退出一个进程时会刷新文件缓冲区
D._exit函数退出一个进程时不会刷新文件缓冲区
30.AD
- 库函数 exit 可以在任意位置调用,用于退出进程, 并且退出前会刷新文件缓冲区中的数据到文件中
- 系统调用 _exit 可以在任意位置调用,用于退出进程,但是退出时直接释放所有资源,并不会刷新缓冲区
31.关于进程退出返回值的说法中,正确的有
A.进程退出的返回值可以随便设置
B.进程的退出返回值可以在父进程中通过wait/waitpid接口获取
C.程序异常退出时,进程返回值为-1
D.进程的退出返回值可以在任意进程中通过wait/waitpid接口获取
31. B
进程的退出返回值也不能随意设置,因为进程的退出返回值实际上只用了一个字节进行存储,因此随意设置可能会导致实际保存的数据与设置的数据不同的情况,因为过大会导致数据截断存储。
waitpid(int pid, int *status, int options); 函数中 status参数 用于父进程获取退出子进程的返回值。
程序异常退出时,意味着程序并没有运行到return/exit去设置返回值,则返回值不做评判标准,因为返回值的存储位置的数据是一个未知随机值。
D:并不能由任意进程获取子进程退出返回值
更多推荐

所有评论(0)