腾讯后台开发面试题解答Word文件下载.docx
《腾讯后台开发面试题解答Word文件下载.docx》由会员分享,可在线阅读,更多相关《腾讯后台开发面试题解答Word文件下载.docx(14页珍藏版)》请在冰豆网上搜索。
共享存是由IPC为一个进程创立的一个特殊的地址围,它将出现在进程的地址空间中。
其他进程可以把同一段共享存段“连接到〞它们自己的地址空间里去。
所有进程都可以访问共享存中的地址。
如果一个进程向这段共享存写了数据,所做的改动会立刻被有访问同一段共享存的其他进程看到。
因此共享存对于数据的传输是非常高效的。
共享存的原理:
共享存是最有用的进程间通信方式之一,也是最快的IPC形式。
两个不同进程A、B共享存的意思是,同一块物理存被映射到进程A、B各自的进程地址空间。
进程A可以即时看到进程B对共享存中数据的更新,反之亦然。
c++进程存空间分布〔注意各局部的存地址谁高谁低,注意栈从高到低分配,堆从低到高分配〕
ELF是什么?
其大小与程序中全局变量的是否初始化有什么关系〔注意未初始化的数据放在bss段〕
可执行文件:
包含了代码和数据。
具有可执行的程序。
可重定位文件:
包含了代码和数据〔这些数据是和其他重定位文件和共享的
object文件一起连接时使用的〕
共享object文件〔又可叫做共享库〕:
包含了代码和数据〔这些数据是在连接时候被连接器ld和运行时动态连接器使用的〕。
使创立共享库容易,使动态装载和共享库的结合更加容易。
在ELF下,在C++中,全局的构造函数和析构函数在共享库和静态库中用同样方法处理。
使用过哪些进程间通讯机制,并详细说明〔重点〕
makefile编写,虽然比拟根底,但是会被问到
mkdirmf
cdmf
vimmakefile
hello.o:
hello.chello.h
gcc–chello.o-Lm
make
./hello
gdb调试相关的经历,会被问到
如何定位存泄露?
存泄漏是指堆存的泄漏。
堆存是指程序从堆中分配的、大小任意的〔存块的大小可以在程序运行期决定〕、使用完后必须显示释放的存。
应用程序一般使用malloc、realloc、new等函数从堆中分配到一块存,使用完后,程序必须负责相应的调用free或delete释放该存块。
否那么,这块存就不能被再次使用,我们就说这块存泄漏了。
C++程序缺乏相应的手段来检测存信息,只能使用top指令观察进程的动态存总额。
而且程序退出时,我们无法获知任何存泄漏信息
使用Linux命令回收存,可以使用ps、kill两个命令检测存使用情况和进展回收。
在使用超级用户权限时使用命令“ps〞,它会列出所有正在运行的程序名称和对应的进程号〔PID〕。
kill命令的工作原理是向Linux操作系统的核送出一个系统操作信号和程序的进程号〔PID〕
动态和静态的区别
动态是指在生成可执行文件时不将所有程序用到的函数到一个文件,因为有许多函数在操作系统带的dll文件中,当程序运行时直接从操作系统中找。
而静态就是把所有用到的函数全部到exe文件中。
动态是只建立一个引用的接口,而真正的代码和数据存放在另外的可执行模块中,在运行时再装入;
而静态是把所有的代码和数据都复制到本模块中,运行时就不再需要库了。
32位系统一个进程最多有多少堆存
多线程和多进程的区别〔重点面试官最最关心的一个问题,必须从cpu调度,上下文切换,数据共享,多核cup利用率,资源占用,等等各方面答复,然后有一个问题必须会被问到:
哪些东西是一个线程私有的?
答案中必须包含存放器,否那么悲催〕
写一个c程序区分系统是16位or32位
法一:
intk=~0;
if((unsignedint)k>
63356)cout<
<
"
atleast32bits"
endl;
elsecout<
16bits"
法二:
//32为系统
inti=65536;
cout<
i<
intj=65535;
j<
写一个c程序区分系统是大端or小端字节序
用联合体:
如char类型的,可以看他输出的是int的高字节还是低字节
信号:
列出常见的信号,信号怎么处理?
i++是否原子操作?
并解释为什么?
说出你所知道的linux系统的各类同步机制〔重点〕,什么是死锁?
如何防止死锁〔每个技术面试官必问〕
死锁的条件。
〔互斥条件〔Mutualexclusion〕:
1、资源不能被共享,只能由一个进程使用。
2、请求与保持条件〔Holdandwait〕:
已经得到资源的进程可以再次申请新的资源。
3、非剥夺条件〔Nopre-emption〕:
已经分配的资源不能从相应的进程中被强制地剥夺。
4、循环等待条件〔Circularwait〕:
系统中假设干进程组成环路,该环路中每个进程都在等待相邻进程正占用的资源。
处理死锁的策略:
1.忽略该问题。
例如鸵鸟算法,该算法可以应用在极少发生死锁的的情况下。
为什么叫鸵鸟算法呢,因为传说中鸵鸟看到危险就把头埋在地底下,可能鸵鸟觉得看不到危险也就没危险了吧。
跟掩耳盗铃有点像。
2.检测死锁并且恢复。
3.仔细地对资源进展动态分配,以防止死锁。
4.通过破除死锁四个必要条件之一,来防止死锁产生。
列举说明linux系统的各类异步机制
exit()与_exit()的区别?
_exit终止调用进程,但不关闭文件,不去除输出缓存,也不调用出口函数。
exit函数将终止调用进程。
在退出程序之前,所有文件关闭,缓冲输出容将刷新定义,并调用所有已刷新的“出口函数〞〔由atexit定义〕。
‘exit()’与‘_exit()’有不少区别在使用‘fork()’,特别是‘vfork()’时变得很突出。
‘exit()’与‘_exit()’的根本区别在于前一个调用实施与调用库里用户状态结构(user-modeconstructs)有关的去除工作(clean-up),而且调用用户自定义的去除程序
如何实现守护进程?
守护进程〔Daemon〕是运行在后台的一种特殊进程。
它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。
守护进程是一种很有用的进程。
Linux的大多数效劳器就是用守护进程实现的。
比方,Internet效劳器inetd,Web效劳器d等。
同时,守护进程完成许多系统任务。
比方,作业规划进程crond,打印进程lpd等。
守护进程的编程本身并不复杂,复杂的是各种版本的Unix的实现机制不尽一样,造成不同Unix环境下守护进程的编程规那么并不一致。
需要注意,照搬某些书上的规那么〔特别是BSD4.3和低版本的SystemV〕到Linux会出现错误的。
下面将给出Linux下守护进程的编程要点和详细实例。
一.守护进程及其特性
守护进程最重要的特性是后台运行。
在这一点上DOS下的常驻存程序TSR与之相似。
其次,守护进程必须与其运行前的环境隔离开来。
这些环境包括未关闭的文件描述符,控制终端,会话和进程组,工作目录以及文件创立掩模等。
这些环境通常是守护进程从执行它的父进程〔特别是shell〕中继承下来的。
最后,守护进程的启动方式有其特殊之处。
它可以在Linux系统启动时从启动脚本/etc/rc.d中启动,可以由作业规划进程crond启动,还可以由用户终端〔shell〕执行。
总之,除开这些特殊性以外,守护进程与普通进程根本上没有什么区别。
因此,编写守护进程实际上是把一个普通进程按照上述的守护进程的特性改造成为守护进程。
如果对进程有比拟深入的认识就更容易理解和编程了。
二.守护进程的编程要点
前面讲过,不同Unix环境下守护进程的编程规那么并不一致。
所幸的是守护进程的编程原那么其实都一样,区别在于具体的实现细节不同。
这个原那么就是要满足守护进程的特性。
同时,Linux是基于SyetemV的SVR4并遵循Posix标准,实现起来与BSD4相比更方便。
编程要点如下;
1.在后台运行。
为防止挂起控制终端将Daemon放入后台执行。
方法是在进程中调用fork使父进程终止,让Daemon在子进程中后台执行。
if(pid=fork())
exit(0);
//是父进程,完毕父进程,子进程继续
2.脱离控制终端,登录会话和进程组
有必要先介绍一下Linux中的进程与控制终端,登录会话和进程组之间的关系:
进程属于一个进程组,进程组号〔GID〕就是进程组长的进程号〔PID〕。
登录会话可以包含多个进程组。
这些进程组共享一个控制终端。
这个控制终端通常是创立进程的登录终端。
控制终端,登录会话和进程组通常是从父进程继承下来的。
我们的目的就是要摆脱它们,使之不受它们的影响。
方法是在第1点的根底上,调用setsid()使进程成为会话组长:
setsid();
说明:
当进程是会话组长时setsid()调用失败。
但第一点已经保证进程不是会话组长。
setsid()调用成功后,进程成为新的会话组长和新的进程组长,并与原来的登录会话和进程组脱离。
由于会话过程对控制终端的独占性,进程同时与控制终端脱离。
3.禁止进程重新翻开控制终端
现在,进程已经成为无终端的会话组长。
但它可以重新申请翻开一个控制终端。
可以通过使进程不再成为会话组长来禁止进程重新翻开控制终端:
if(pid=fork())exit(0);
//完毕第一子进程,第二子进程继续〔第二子进程不再是会话组长〕
4.关闭翻开的文件描述符
进程从创立它的父进程那里继承了翻开的文件描述符。
如不关闭,将会浪费系统资源,造成进程所在的文件系统无法卸下以及引起无法预料的错误。
按如下方法关闭它们:
for(i=0;
i关闭翻开的文件描述符close(i);
>
5.改变当前工作目录
进程活动时,其工作目录所在的文件系统不能卸下。
一般需要将工作目录改变到根目录。
对于需要转储核心,写运行日志的进程将工作目录改变到特定目录如/tmpchdir("
/"
)
6.重设文件创立掩模
进程从创立它的父进程那里继承了文件创立掩模。
它可能修改守护进程所创立的文件的存取位。
为防止这一点,将文件创立掩模去除:
umask(0);
7.处理SIGCHLD信号
处理SIGCHLD信号并不是必须的。
但对于某些进程,特别是效劳器进程往往在请求到来时生成子进程处理请求。
如果父进程不等待子进程完毕,子进程将成为僵尸进程〔zombie〕从而占用系统资源。
如果父进程等待子进程完毕,将增加父进程的负担,影响效劳器进程的并发性能。
在Linux下可以简单地将SIGCHLD信号的操作设为SIG_IGN。
signal(SIGCHLD,SIG_IGN);
这样,核在子进程完毕时不会产生僵尸进程。
这一点与BSD4不同,BSD4下必须显式等待子进程完毕才能释放僵尸进程。
三.守护进程实例
守护进程实例包括两局部:
主程序test.c和初始化程序init.c。
主程序每隔一分钟向/tmp目录中的日志test.log报告运行状态。
初始化程序中的init_daemon函数负责生成守护进程。
读者可以利用init_daemon函数生成自己的守护进程。
linux的存管理机制是什么?
Linux虚拟存的实现需要