一、描述一下进程和线程有啥区别?
1、进程是操作系统资源分配的基本单位,线程是任务调度和执行的基本单位
2、进程有自己的独立地址空间,每启动一个进程,系统就会为器分配地址空间,建立数据表来维护代码段、堆栈段和数据段;但是线程没有独立的地址空间,它使用相同的地址空间共享数据
3、cpu切换一个线程比切换进程花费小;创建一个线程比进程开销小;线程占用的资源要进程少很多
4、线程之间通信更加方便;线程共享全局变量、静态变量等数据,进程之间需要ipc来通信(管道、socked、 信号量、 信号、 共享内存)
5、多进程的程序更加安全,生命力更强,一个进程死掉不会对另一个进程造成影响(源于它有独立的地址空间);多线程程序更不容易维护,一个线程死掉了,整个进程就死掉了(因为共享地址空间)
二、解释一下虚拟内存里面的分段与分页机制?
1、分段机制:
(1)什么是分段机制?
分段机制就是把虚拟地址空间(也叫逻辑地址空间)中的虚拟内存组织成一些长度可变的称为段的内存块单元。
(2)什么是段?
每个段由三个参数定义:段基地址、段限长、段属性。段的基地址、段限长以及段的保护属性存储在一个称为段描述符的结构项中
(3)段的作用?
段可以用来存放程序的代码、数据、堆栈、或者用来存放系统数据结构
(4)段的存储地址?
系统中所有使用的段包括在处理器线性地址空间中。
(5)段选择符?
逻辑地址包含一个段选择符和一个偏移量,段选择符是一个段的唯一标识,它提供了段描述符表,段描述符表指明段的大小和类型、访问权限和段的特权级、以及段的第一个字节在线性地址空间中的位置(称为段的基地址);逻辑地址的偏移量部分到段的基地址上就可以定位段中某个字节的位置。因此基地址加上偏移量就形成了处理器线性地址空间中的地址
2、分页机制:
(1)什么是分页机制?
分页机制在分段机制之后进行的,它是进一步把线性地址转换成物理地址。
(2)分页机制的存储?
分页机制支持虚拟存储技术,在使用虚拟存储的环境中,大容量的线性地址空间需要使用小块的物理内存(RAM或者ROM)以及某些外部存储空间来模拟;当使用分页时,每个段被划分成页面(通常每页为4K大小),页面为被存储于物理内存中或者硬盘中。操作系统通过维护一个页目录和一些页表来留意这些页面;当程序试图访问线性地址空间中的一个地址位置时,处理器就会使用页目录和页表把线性地址转换成一个物理地址,然后在该内存位置上执行所要的操作。
(3)分段机制与分页机制的区别?
--分页机制会使用固定的内存块大小,而分段机制使用大小可变的块内存大小.
--分页使用固定大小的块更适合管理物理内存,而分段机制使用大小可变的块更适合处理复杂系统的逻辑分区
--段表存储存储在线性地址空间,而页表则保存在物理地址空间
注:具体过程实现可以看<深入理解计算机操作系统>和<linux内核完全注释>这两本书
三、手写memcpy、strcpy函数功能实现
1、手写strcpy:
(1):
void strcpy(char *strDest, char *strSrc)
{
while((*strDest++ = *strSrc++) != '');
}
(2):
void strcpy(char *strDest, const char *strSrc)
{
while((*strDest++ = *strSrc++)!='');
}
(3):
char *strcpy(char *strDest, const char *strSrc)
{
assert((strDest !=NULL)&& (strSrc !=NULL));
char *address = strDest;
while((*strDest = *strSrc++)!='')
return address
}
2、手写memcpy:
1)不考虑拷贝覆盖问题
void *sky_memecpy(void *dst, const void *str, int n)
{
if (NULL == dst || NULL == str || n <= 0) {
return NULL;
}
char *pdst = (char *)dst;
char *pstr = (char *)str;
while (n --) {
*pdst ++ = *pstr ++;
}
return dst;
}
2)考虑拷贝覆盖问题
void *sky_memecpy(void *dst, const void *str, int n)
{
if (NULL == dst || NULL == str || n <= 0) {
return NULL;
}
char *pdst = (char *)dst;
char *pstr = (char *)str;
if (pdst > pstr && pdst < pstr + n) {
pdst = pdst + n - 1;
pstr = pstr + n - 1;
while (n --) {
*pdst -- = *pstr --;
}
} else {
while (n --) {
*pdst ++ = *pstr ++;
}
}
return dst;
}
四、小结:
以上答案仅供参考,都是一些面试官高频喜欢问的题目!文中的提到的两本书,可以在后台领取!
好了,今天的分享就到这里,如果文章中有错误或者不理解的地方,可以交流互动,一起进步。我是txp,下期见!