考完我再来补充(考完了,也完了芜湖)
开卷的,不用担心
灵文灵文百事通,保佑我的Linux!!
试卷划分:
- 编程题(50)
- 文件
- 进程
- 选择题(30)
- 从面试题里面出,关于linux的系统管理,语法
- 问答题(20)
下面这部分是19届提供的,我整理了一下部分答案:
19软件试卷
(开卷,没必要带资料,没用,看课本就行,以下提到课本均为黄皮课本(王巍老师编的那个)
- 简答:
-
课本P82 例3-5 ,写出第一行后的输出 (第一行的pid会改)
-
课本P82 例3-6 ,写出第一行后的输出 (第一行的pid会改)
(1,2考察的就是fork和vfork,fork是复制父进程的数据段,vfork是共享父进程的数据段) -
课本p79 例3-2 输出是什么?为什么?(考察的是execlp,这个函数会取代原调用进程,exec组的函数都是这样)
-
给一段程序问是否会发生内存泄露,为什么?(知道内存泄露是什么就能回答):
- 内存溢出就是你要求分配的内存超出了系统能给你的,系统不能满足需求,于是产生溢出。
- 内存泄漏是指你向系统申请分配内存进行使用(new),可是使用完了以后却不归还(delete),结果你申请到的那块内存你自己也不能再访问(也许你把它的地址给弄丢了),而系统也不能再次将它分配给需要的程序。
-
考系统中变量的长度,涉及到了sizeof(数组),sizeof(指针),strlen。
- sizeof实际上是获取了数据在内存中所占用的存储空间,以字节为单位来计数。
- Size of char : 1
- Size of int : 4
- Size of short int : 2
- Size of long int : 4
- Size of float : 4
- Size of double : 8
- Size of wchar_t : 4
- sizeof(数组) = 类型 × 数组大小(数组在进行函数调用作为参数被传递时,在被调用函数内部其退化为指针,使用sizeof等价于对一个指针变量进行sizeof,大小为一个指针变量所占的内存空间。)
- sizeof(指针) = 4,不管指针指向什么类型的变量,它的大小总是固定的:只要能放得下一个地址就行。32位系统中所有指针的长度都是4,如果是64位就是8了。4个字节,一个字节八位,4 × 8 = 32。
- strlen:计算字符串sting的长度。不包含’\0’,strlen函数遇到\0就会停止下来。
- sizeof实际上是获取了数据在内存中所占用的存储空间,以字节为单位来计数。
-
- 编程:
- 课本p150 例4-10(建立线程共享资源的,20届没学线程,不考,下一个)
- 课本p124 思考题2()
#include<stdio.h> #include<unistd.h> int main(){ for(int i=0;i<4;i++){ int pid = vfork(); if(pid < 0){ //创建失败 } else if(pid == 0){ //子进程 printf("hello\n"); exit(0); } } printf("end\n"); }
4. 课本p58 例2-13:向终端pts1写入100个Unix
5. 父进程用管道写入“1234567890“,子进程从管道中读出并输出 P103
6. 生成一守护进程,来保证进程2存活,若进程2死亡则重启系统(题目会给提示:进程2每个10秒会向某一文件写数据,若10秒后该文件无变化则认为进程2已死亡。重启命令:system(“reboot“))
P99 while(1)里面的代码改成判断文件是否更新过struct stat fi; if(stat(file.c_str(), &fi) == 0 && fi.st_mtime != last_update_){***} //其中last_update_记录的是上次的更新时间
考完了,我来更新
和19级的差不多
- 选择(奇奇怪怪的啥都有,简单写几个我还记得的)
- 首先学习资料群发的习题,遇到了几道原题,推荐过一遍,有个印象就行,反正开卷。(我直接打印下来带进去了)
- Linux通过VSF支持多种不同的文件系统,Linux缺省的文件类型:Exit系列
- Linux文件系统的根目录的i节点号:2
- gcc -g包含调试信息
- big endian/littel endian(我们考的little endian)
- fsync的功能
- linux系统安装最少两个挂载点:/(根目录)和swap(交换分区)
- shell编程的注解符#
- 其他没啥印象了…
- 简答
- 和19说的差不多
- sizeof和strlen(指针,数组)
- IA-32中double a = 100,输出a为0,在80x64(好像这么写的)输出值不确定,问为什么
- unsigned类型的变量len,当len = 0,len-1是unsigned类型能表达的最大值,给的数组a大小只有1,遍历数组a,下标从0到len发生数组越界
- fork,就是书上那个多个fork,书上是三个fork,考试是4个fork
- 其他没啥印象
- 编程题
- 和19届的差不多
赠送一份我整理的,本来是为了我考试的时候方便翻书,不过实际考试的时候没用上
函数总结
自定义库
- 打开动态库:
void * dlopen(const char *pathname,int mode)
P16 - 获取动态库对象地址:
void *dlsym(void *handle,const char*name)
P16 - 关闭动态库:
int dlclose(void *handle)
P17 - 错误检查:
char * dlerror(void )
文件
- fprintf()
- sprintf()
- 打开文件:
int open(const char * pathname,int flags,int perms)
P27 - 创建文件:
int creat(const char *pathname,umask)
P28 - 关闭文件:
close(int fildes)
P28 - 删除文件:
unlink(char *path)
P28 - 读文件:
ssize_t read(int filedes,void *buff,size_t nbytes)
P29 - 写文件:
ssize_t write(int filedes,const void *buff,size_t nbytes)
P29 - 文件的定位:
ssize_t lseek(int filedes,off_t offset,int whence)
P30 - 文件控制:
fcntl
- 将缓存信息写入文件:fsync P30
- 复制文件:dip,dup2 P32
- 创建硬链接:
link("源文件名","新文件名")
P43 - 删除:
unlink("文件名“)
P43 - 查看文件属性(i节点):
stat
,fsrat
,lstat
P44 - 读取文件系统属性(超级块信息):
statfs
,fstatfs
P51 - 读取更改当前工作目录
getcwd
,getwd
,chdir
,fchdir
P52 - 目录的创建和删除:
mkdir
,rmdir
P54 - 目录的读取的定位:
opendir
,readdir
,rewinddir
,closedir
P54
进程
- 获取当前进程ID:
getpid()
P78 - 获取当前进程组ID:
getpgrp()
P78 - 返回父进程ID:
getpgid()
P78 - 返回进程实际用户ID:
getuid()
P78 - 返回进程有效用户ID:
geteuid()
P78 - 返回进程实际组ID:
getgid()
P78 - 返回进程有效组ID:
getegid()
P78 - exec函数组 P79
- 以复制的方式创建新进程:
fork()
P83 - 以共享的方式创建新进程:
vfork()
P83 - 进程休眠:
sleep(unsigned int seconds)
P83 - 进程撤销:
exit(int status)
P84 - 堵塞式等待子进程的结束,回收进程:
wait(int *status)
P85 - 不堵塞式等待:
waitpid(pid_t pid,int * status,int options)
P85-86 - 人为杀死进程:kill P87
- 信号量的创建或者访问:
semget(key_t key,int nsems,int semflg)
P89 - 信号量的控制:
int semctl(int semid,int semnum,int cmd,...)
P89 - PVZ操作:
semop(int semid,struct sembuf *sops,unsigned nsops)
P93 - 管道:
int pipe(int fildes[2])
P102 - 管道操作:
FILE *popen(const char *command,char *type)
P106 - 创建有名管道:
int mkfilo(char *path,mode_t mode)
P106 - 删除fifo文件:
unlink(char* path)
P106 - 创建或打开消息队列:
int msgget(key_t key,int msgflg)
P110 - 为消息队列发送消息:
int msgsnd(int msqid,const void *msgp,size_t msgsz,int msgflg)
P110 - 从消息队列中接受消息:
int msgsnd(int msqssvid,void *msgp,size_t msgsz,long int msgtype,int msgflgwd)
P110 - 消息队列控制:
int msgctl(int msqid,int cmd,struct msqid_ds *buf)
P114 * 创建或获取共享内存标识符:int shmget(key_t key,size_t size,int shmflg)
- 共享内存映射到进程地址空间:
void *shmat(int shmid,const void *shmaddr,int shmflgy)
书上编程例题总结
文件
- 实现文件复制命令”cp”:P21和P23
- 打开文件,新建文件,关闭文件:P28
- 从源文件读取最后10KB的数据复制到目标文件(lseek):P30
- 文件记录锁源代码:P34
- 文件写入锁:P35
- 文件读取锁:P36
- 判断文件类型:P46
- 判断文件访问权限:P47
- 从标准输入流读取100000个字节,非堵塞输出:P48
- 将文件其他属性信息转化成字符串写入参数:P49
- 模拟UNIX的“ls -l”:P49
- 读取文件系统属性,显示目录“/root”所挂在的文件系统信息:P51
- 模仿pwd命令:P53
- 创建目录删除目录:P54
- 模拟“ls -ai”:P55
- 向终端pst1写入100个“Unix”:P58
- 利用ioctl函数调节音卡音量大小:P61
- 判读串口是否可以读出数据,并将串口中数据连续读出重新写回串口:P67
进程
- 显示一堆和进程相关的ID:P78
- 在程序中运行“ps-ef”,使用execlp:P79
- 创建进程:P80-83
- 父进程通过fork创建子进程,调用wait使父进程进入堵塞状态,等待子进程结束:P86
- 模拟ipcs:P90(信号量),P115(消息队列)
- 拉货销货(信号量):P94
- 产生僵死进程:P96
- 守护进程的创建并写日志:P99
- 父创建两个子进程,子进程向管道写数据,父进程读取:P103
- 模拟“ps -ef|grep daemon”:P104
- 两个程序,一个读管道一个写管道:P106
- 消息队列发送接收程序:P113
20届没考到,19届有从课后题出一题
课后思考题
第一章P20
- 什么是系统编程P1,什么是系统调用 P2
- 微内核和宏内核在系统调用上的区别 P4
- 内核提供的服务包括哪些 P4-5
- 什么是系统空间和用户空间 P2
- 引用库的目的 P11
- 如何创建和调用静态链接库 P13
- 如何创建和调用动态链接库 P14
- 对系统编程的标准评价有哪些 P18
第二章P69
- 文件指针FILE*与文件描述符是什么关系:C语言中使用文件指针做为I/O的句柄。文件指针指向进程用户区中的一个被称为FILE结构的数据结构。FILE结构包括缓冲区和文件描述符。而文件描述符是文件描述符表的一个索引,也就是说c语言的文件指针是Linux系统中对文件描述符的一种封装。
- 简述进程操作一个文件的全过程:(也许?不然再加个定位,lseek?)
- 打开文件
- 读、写文件:
- 读 将文件内容读入内容
- 写 将内存内容写入文件
- 关闭文件
- 打开文件
- 简述目录的实现过程:P52(感觉也没啥关于实现的内容)。目录实现的基本方法有线性列表和哈希表两种。
- 编写cp相同功能的程序:P21,23
- 什么是设备文件(类Unix操作系统都是基于文件概念的,文件是由字节序列而构成的信息载体。根据这一点,可以把I/O设备当作设备文件这种所谓的特殊文件来处理),和普通意义上的文件有哪些区别?P59最下面
第三章P124
- 什么是进程,进程在UNIX中如何表示?P72
进程是一个具有独立功能的程序关于某个数据集合的一次运行活动,是系统调度和资源分配的基本单位。 - 编写一个程序,四个子进程打印hello,最后打印end。19届考到了,写上面了。
- 什么是僵死进程P95,什么是守护进程P97。
- 进程间通信有哪些,各有哪些特点?P124
- 文件,管道,消息队列,内存
- 文件P101
- 管道:无名P102 ,105有名P109
- 消息队列P109,116
- 内存P117
- 如何通过信号量实现进程间的同步P88,写程序吧,简述能简述啥。
- 进程获取临界资源之前,要先获取信号量资源;
- 若无信号量资源,则该进程阻塞等待,进入等待队列。
- 若有信号量资源,则对信号量进行P(-1)操作,再获取临界资源。
- 当临界资源+1时,对应的信号量资源则执行V(+1)操作,然后唤醒在等待队列中等待获取临界资源的进程