百度面试题

来源:互联网 发布:mac电脑怎么打出顿号 编辑:程序博客网 时间:2024/06/07 03:42
 

出处:http://topic.csdn.net/u/20081123/19/87347aa7-fa61-42e2-8076-e2a8f638d1ce.html

 


一、编程题(30分)


现代的处理器提供了compare-and-swap原子操作:
int compare_and_swap(int * pv, const int cv, const int nv);
即比较*pv与cv,如果相等,则把*pv值替换为nv并返回*pv原值,否则返回*pv的值。
请利用上述原子操作实现如下操作:
int inc_if_gt_zero(int * pv);
即如果*pv > 0,则把*pv加1并返回修改后的*pv,否则返回*pv。
结果要线程安全且不使用锁、信号灯、互斥量、临界区或类似机制。

 

int inc_if_gt_zero(int * pv)
{
  return compare_and_swap(pv, -(*pv), *pv) == 0 ? 0 : compare_and_swap(pv, abs(*pv), *pv + 1);
}



二、算法题(35分)

假设有一台机器A,有1G内存,另外若干台机器(B、C、D……)通过网络TCP向机器A传输数据,A机器把接收到的数据写入硬盘。B、C、D等机器的数据按记录传输,每条记录大小范围:1M~16M。

为了保证每条记录的原子性,B、C、D等机器每次先向A汇报数据量大小,然后再进行数据传输。

汇报数据大小时,A机器会给记录分配一个序号,写入文件时每个记录按序号顺序、原子写入。

B、C、D等机器处理速度和网络速度都不尽相同,因此汇报数据大小之后,记录数据传递到A的顺序可能不一定按分配好的序号顺序到达。

现在要求给A上程序设计一个数据结构,利用该数据结构能高效的接收数据并顺序高效的写入磁盘(也即是不能序号大的记录先写,然后再回写序号小的记录;也不能接收到几十个字节就写一次磁盘)。

 

三、系统设计题(35分)

现有计算机的内存大部分为易失性内存,一旦断电内存中的数据就会全部丢失,所以操作系统的设计充分的考虑了易失性内存的特点。
问:如果在以后内存全部为非易失性内存,那么应该如何设计新的操作系统,或者说需要对现有的操作系统做哪些修改和改进?

 

其中某个牛人给出的一个答案,没测试是否正确与否。

#include <Windows.h>int *pv;int share = 1;//用cmpxchg实现CASint compare_and_swap(int *pv,const int cv,const int nv){int rv=*pv;__asm{mov eax,cvmov ecx,pvmov ebx,nvcmpxchg [ecx],ebx}return rv;}int inc_if_gt_zero(int *pv){  int ret = 0;  int cv;  int nv;  while(1)  {  //执行一次,得到*pv的当前值,必须确保不修改pv的原始值  //ret = compare_and_swap(pv,-1,-1);      //直接取就可以  ret = *pv;  //如果该值小于等于0,可以安全的返回ret值  if(ret<=0) return ret;    //否则需要对pv作加一的操作  cv = ret;  nv = ret+1;  //ret = compare_and_swap(pv,cv,nv);  //*pv = nv; //改为普通赋值速度会更快,但运行结果随机化  *pv = *pv + 1;  if(ret==cv) return ret+1;  }}//工作线程,操作pv,要求:确保线程的运行是无序的DWORD WINAPI ThreadFun(LPVOID lpParam){  int id = (int)lpParam;  int i;     srand((unsigned)time(0));      //打乱线程的第一次运行顺序  for(i=0;i<5;i++) Sleep(200*(1+rand()*5/RAND_MAX));  for(i=0;i<20;i++)  {  Sleep(20*(1+rand()*2/RAND_MAX));  printf("Thread %d NO. %d\n",id,i);  Sleep(20*(1+rand()*2/RAND_MAX));  inc_if_gt_zero(pv);//***************************  }  printf("Thread %d returned\n",id);  return 0;}//主函数测试// 开20个线程,每个线程对share通过inc_if_gt_zero加1操作20次// share初值可以任意设置// 如果share<=0,值不变// 如果share>0,最终结果应该是: 初值+400int main(void){  int i;srand((unsigned)time(0));  pv = &share;   for(i=0;i<20;i++) CreateThread(NULL,0,ThreadFun,(LPVOID)i,0,NULL);//主线程用原始方法等待所有线程终止getchar();printf("运行结果: share = %d\n",share);}

原创粉丝点击