linux面试

来源:互联网 发布:广告相册制作软件 编辑:程序博客网 时间:2024/06/01 07:38

1.malloc和new的区别

 malloc与free时C++/C语言的标准函数,new/delete是C++的运算符,

它们都可用于申请动态内存和释放内存.


对于非内部数据类型的对象而言,光用malloc/free无法满足动态对象的要求,

对象在创建的同时要自动执行构造函数,对象在销往之前要自动执行析构函数。

由于malloc/free是库函数,而不是运算符,不能在编译器控制权限之类,不能

把执行构造函数和析构函数的任务强加于malloc/free.

C++语言需要一个能完成动态内存分配和初始化工作的运算符new,以及一个能完成

清理与释放内存工作的运算符delete.


2.解释一下位域

 有些信息在存储时,并不需要占用一个完整的字节,而只需要占几个二进制位。

为此C语言为了节省存储空间,提供了一个数据结构,称为“位域"或位段”。

所谓“位域”是把一个字节的二进制位划分为几个不同的区域,并说明每个区域的位数,

每个域有一个域名,允许在程序中按域名进程操作。这样就把几个不同的对象用一个

二进制位域来表示。

1.一个位域必须存储在同一个字节中,不能跨两个字节。

如果一个字节所剩空间不能存放另一个位域,应从下一个单一起存放该位域。

struct 位域结构名

{位域列表}

#include <stdio.h>struct bs {int a:8;int b:2;int c:6;}data;int main(void){printf("%d\n", sizeof(data));return 0;}
a占8位,c占2位,c占6位
结果为:4

3.c语言的地址对齐是怎么回事

对齐跟数据在内存中的位置有关,

如果一个变量的内存地址正好位于它长度的整数倍

,那么它就是自然对齐的。

需要对齐的根本原因在于CPU访问数据的效率问题。


对于标准数据类型,它的地址只要它的长度的整数倍就行了,

而非标准数据类型按下面的原则对齐:

结构体:结构体中的每个数据都要对齐

联合体:按其包含的长度最大的数据类型对齐。

struct stu {char sex;int length;char name[10];};

gcc下,默认4对齐,大小为20

1+3+4+10+2 =2 0

#pragma pack(2)的时候 1+1+4+10 = 16

参考:http://blog.csdn.net/21aspnet/article/details/6729724

4.写一个类似于printf的函数,可以接受任意多个参数


5.使用memcpy函数的时候,有什么要注意的

memcpy是C语言中的内存复制函数,它的函数原型:void *memcpy(void *dest, const void* src, size_t n);它的目的是将src指向地址

为起始地址的连续n个字节的数据复制到以dest指向地址为起始的空间内,需要主要的时,src和dest所值内存区域不能重叠,同时,与strcpy相比

memcpy()遇到'\0'不结束,而是一定要复制完n个字节,而且如果目标数组dest本身已有数据,执行memcpy()后,将覆盖原有数据。

6.说一下你知道的排序算法 ...


7.有两个单链表,用什么方法可以快速的知道他们有没有相同的部分


8.执行make命令的时候怎么给makefile传递参数


make 工具软件的主要用途是通过识别

哪些文件已被修改过,从而自动地决定在一个含有

多个源程序文件的程序系统中哪些文件需要被重新编
译。因此, make 工具软件是程序项目的管理软件。


9.解释一下僵尸进程

 当进程已停止运行,但其父进程还没有询问其状态时,则称该进程处于僵死状态。

 我们知道在unix/linux中,正常情况下,子进程是通过父进程创建的,子进程在创建新的进程。子进程的结束和父进程的运行是一个异步过程,即父进程永远无法预测子进程 到底什么时候结束。 当一个 进程完成它的工作终止之后,它的父进程需要调用wait()或者waitpid()系统调用取得子进程的终止状态。

孤儿进程:一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。

  僵尸进程:一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait或waitpid获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中。这种进程称之为僵死进程。

在每个进程退出的时候,内核释放该进程所有的资源,包括打开的文件,占用的内存等。 但是仍然为其保留一定的信息(包括进程号the process ID,退出状态the termination status of the process,运行时间the amount of CPU time taken by the process等)。直到父进程通过wait / waitpid来取时才释放。 但这样就导致了问题,如果进程不调用wait / waitpid的话, 么保留的那段信息就不会释放,其进程号就会一直被占用,但是系统所能使用的进程号是有限的,如果大量的产生僵死进程,将因为没有可用的进程号而导致系统不能产生新的进程. 此即为僵尸进程的危害,应当避免。


 任何一个子进程(init除外)在exit()之后,并非马上就消失掉,而是留下一个称为僵尸进程(Zombie)的数据结构,等待父进程处理。

10.僵尸进程怎么回收

1、父进程通过wait和waitpid等函数等待子进程结束,这会导致父进程挂起 

2. 如果父进程很忙,那么可以用signal函数为SIGCHLD安装handler,因为子进程结束后,父进程会收到该信号,可以在handler中调用wait回收(没有试验过) 

3. 如果父进程不关心子进程什么时候结束,那么可以用signal(SIGCHLD, SIG_IGN)通知内核,自己对子进程的结束不感兴趣,那么子进程结束后,内核会回收,并不再给父进程发送信号 

4. 还有一些技巧,就是fork两次,父进程fork一个子进程,然后继续工作,子进程fork一个孙进程后退出,那么孙进程被init接管,孙进程结束后,init会回收。不过子进程的回收估计还要自己做。 

父进程通过wait / waitpid来取时才释放


11.在linux系统上怎么列出所有的僵尸进程

用ps命令就能看到子进程的状态是“Z”。如果父进程能及时 处理,可能用ps命令就来不及看到子进程的僵尸状态,但这并不等于子进程不经过僵尸状态。如果父进程在子进程结束之前退出,则子进程将由init接管。init将会以父进程的身份对僵尸状态的子进程进行处理。

ps -o pid,ppid,state,tty,command


参考:http://www.cnblogs.com/Anker/p/3271773.html

12.怎么列出linux上所有在运行的进程

输入下面的ps命令,显示所有运行中的进程:

# ps aux | less

其中,

-A:显示所有进程

a:显示终端中包括其它用户的所有进程

x:显示无控制终端的进程

http://blog.csdn.net/mengyafei43/article/details/26610409


13.用shell命令怎么将所有进程的名字写到一个文件里面

ps -eo command > tmp

14.使用shell命令查找当前目录中所有包含txt字符串的文件,并且删除他们

find . | xargs grep -ri "IBM" 

-r 表示递归

-i 忽略大小

grep -rn "IBM" ./

15.c语言中,main方法返回值的意义

main()函数的返回值是返回“给”系统的。

16.说说你知道的排序算法

17.如何比较两个浮点数是否相等

18.浮点数是怎么存储的

19.fork函数和wait函数的作用

wait 

#include <sys/types.h> #include <sys/wait.h>pid_t wait(int *status)

进程一旦调用了wait,就立即阻塞自己,由wait自动分析是否当前进程的某个子进程已经退出,如果让它找到了这样一个已经变成僵尸的子进程,wait就会收集这个子进程的信息,并把它彻底销毁后返回;如果没有找到这样一个子进程,wait就会一直阻塞在这里,直到有一个出现为止。

参数status用来保存被收集进程退出时的一些状态,它是一个指向int类型的指针。但如果我们对这个子进程是如何死掉的毫不在意,只想把这个僵尸进程消灭掉,(事实上绝大多数情况下,我们都会这样想),我们就可以设定这个参数为NULL,就象下面这样:

 pid = wait(NULL);  

如果成功,wait会返回被收集的子进程的进程ID,如果调用进程没有子进程,调用就会失败,此时wait返回-1,同时errno被置为ECHILD。


20.解释一下僵尸进程是怎么产生的,然后怎么回收的。用什么命令可以查看当前所有的僵尸进程

一、僵屍進程的産生 

当子进程比父进程先运行结束,而父进程没有回收子进程的时候,子进程将成为一个僵尸进程。如果父进程先退出,子进程被init接管,子进程退出后init会回收,就没事了。 

1、父进程通过wait和waitpid等函数等待子进程结束,这会导致父进程挂起 

2. 如果父进程很忙,那么可以用signal函数为SIGCHLD安装handler,因为子进程结束后,父进程会收到该信号,可以在handler中调用wait回收(没有试验过) 

3. 如果父进程不关心子进程什么时候结束,那么可以用signal(SIGCHLD, SIG_IGN)通知内核,自己对子进程的结束不感兴趣,那么子进程结束后,内核会回收,并不再给父进程发送信号 

4. 还有一些技巧,就是fork两次,父进程fork一个子进程,然后继续工作,子进程fork一个孙进程后退出,那么孙进程被init接管,孙进程结束后,init会回收。不过子进程的回收估计还要自己做。 





0 0
原创粉丝点击