百度面试题

 

出处:http://topic.youkuaiyun.com/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实现CAS
int compare_and_swap(int *pv,const int cv,const int nv)
{
int rv=*pv;
__asm{
mov eax,cv
mov ecx,pv
mov ebx,nv
cmpxchg [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,最终结果应该是: 初值+400
int 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);
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值