百度2011年实习生笔试题

来源:互联网 发布:一句话证明你会java 编辑:程序博客网 时间:2024/05/21 19:22

1、extern “C”是什么含义?用来解决什么问题?

分析:

  extern “C”包含双重含义,从字面上即可得到:首先,被它修饰的目标是”extern”的;其次,被它修饰的目标是”C”的。让我们来详细解读这两重含义。

  extern “C”是指将该段代码以C语言形式进行编译、链接。由于C不支持函数重载,CC++对于同一个函数编译后在符号表中保存的函数名字存在差异,故当进行CC++混合编程时会出现一些问题。

  用来解决CC++程序连接问题,extern “C”实现CC++的混合编程。

 

2、写出至少两种设计模式,阐明其使用场景,有伪代码更好。

分析:

  单例模式、适配器模式、工场模式、装饰模式等23种设计模式

  具体请参考《设计模式》一书。

 

3、TCP连接的time-wait是什么状态,描述其发生的场景,说明它存在的好处/坏处。

分析:

  TIME_WAIT状态是执行主动关闭的那段经历了这个状态,该端点停留在这个状态的持续时间是最长分节时间生命期(MSL)的两倍,有时候称之为2MSL

  任何TCP实现都必须为MSL选择一个值,MSL是任何IP数据报能够在因特网中存活的最长时间,这个时间是有限的,因为每个数据报含有一个称为跳限的8位字段,它的最大值为255,

  TIME_WAIT状态有两个存在的理由:

  (1)可靠地实现TCP全双工连接的终止

  假设最终的那个ACK丢失了,服务器将重新发送它的最终那个FIN,因此客户必须维护状态信息,以允许它重新发送最终那个ACK。如果TCP打算执行所有必要的工作以彻底终止某个连接上两个方向的数据流(即全双工关闭),那么它必须正确处理连接终止序列4个分节中任何一个分节丢失的情况。同时也说明了为什么执行主动关闭的那一端是处于TIME_WAIT状态的那一端:因为可能不得不重传最终那个ACK的就是那一端。

  (2)允许老的重复分节在网络中消逝

  假设12.11.22.111500端口和203.33.322.3321端口之间有一个TCP连接。我们关闭这个连接,过一段时间后在相同IP地址和端口之间建立另一个连接。后一个连接称为前一个连接的化身,因为它们的IP地址和端口号都相同。TCP必须防止来自某个连接的老的重复分组在该连接已终止后再现,从而被误解成为属于同一个连接的某个新的化身。为了做到这一点,TCP将不给处于TIME_WAIT状态的连接发起新的化身。既然TIME_WAIT状态的持续时间是MSL2倍,这就足以让某个方向上的分组最多存活MSL秒即被丢弃,另一个方向上的应答最多存活MSL秒也被丢弃。通过这个规则,我们保证每成功建立一个TCP连接时,来自该连接先前化身的老的重复分组都已经在网络中消逝了。

 

算法设计与分析

1、有N个任务(N<1000),其中有些任务的执行依赖于其他任务的执行,如A任务执行之后B任务才能执行,但这些任务之间不存在循环依赖。请用一个算法来输出这些任务的执行顺序。

分析:

  拓扑排序。

  算法思路:

  (1)把各个任务之间的依赖关系用有向无环图来表示,例如A任务依赖B任务,则建立一条B指向A的弧。(题目要求可以保证这个图无环);

  (2)计算有向无环图中各个节点的入度;

  (3)输出入度为0的节点,并删除该节点和所有以它为尾的弧;

  (4)重复第3步,直到所有节点都已输出;

  (5)输出的节点序列即为拓扑排序序列,也为任务的执行顺序;

值得注意的是:拓扑排序序列也可以用来验证各个任务之间是否存在循环依赖,也就是有向图是否存在环。如果输出的拓扑排序序列中包含了所有的任务,则有向图肯定不存在环。

  伪代码

  在实际的实现中,对于入度为0的节点,不需要真正删除节点以及所有以它为尾的弧,可以转换为对弧头入度减1的操作。

  

复制代码
 1 //假设用邻接表存储有向图 2 status TopologicalSort(ALGraph G) 3 { 4         //对各个节点求入度,存储在indegree数组中 5         FindInDegree(G, indegree); 6  7         //初始化栈 8         InitStack(S); 9 10         //遍历所有节点,把入度为0的节点加入栈11         for(i=0; i<G.vexnum; i++)12         {13             if(!indegree(i))14             {15                 Push(S, i);16             }17         }18 19         count = 0;20         while(!StackEmpty(S))21         {22             //出栈并输入之23             Pop(S, i);24             printf(i, G.vertices[i].data);25             count++;26             //对所有它的邻接点进行入度减一操作,如果入度减为0,则进栈27             for(p=G.vertices[i].firstarc; p; p=p->nextarc)28             {29                 k = p->adjvex;30                 if(!--indegree[k])31                 {32                     Push(S, k);33                 }34             }35         }36 37         //判断所有的有向图节点是否在拓扑排序序列中,如果在,则有向图无环,否则有环38         if(count < G.vexnum)39         {40             return ERROR;41         }42         else43         {44             return OK;45         }46 }
复制代码

 

  时间复杂度分析:

  假设有n个节点,e条弧。求各个节点入度花费O(e),把入度为0的节点加入栈花费O(n)while循环中每次对入度减一的操作可以看作删除一条弧的操作,把所有弧删除完了,while循环也结束了,因此while循环花费O(e)。所以总的时间复杂度为O(n+e)

 

2、查找一个文本内的完整句子的数量,文本中包含大小写字母、空格、“,”和“.”,完整的句子是指以“.”结束,且“.”号前必须出现至少一个字母。写出程序。
分析:

  读入文本每一行,然后遍历。
  记录每一行最后一个字符,若行首为“.”,则需要上一行末尾的字符。

   

复制代码
 1 int count_prefect_sentence(string str)  2 {  3       int i = 0, cnt = 0, hasOneLetter = 0;  4       while(str[i])  5       {  6             if(str[i] == '.')  7             {  8                    if(hasOneLetter)  9                         cnt++; 10                    hasOneLetter = 0; 11            } 12            else if(isalpha(str[i])) 13                 hasOneLetter = 1; 14           i++; 15      } 16       return cnt; 17 }
复制代码

 

系统设计题目

1、有1000亿条记录,每个记录包含urlip、访问时间,请设计一个系统,满足下面两个查询:
  
1)针对特定的时间段(精确到分),计算访问特定urlip数;
  (2)针对特定的时间段(精确到分),计算访问特定ip访问的url数。

分析:  

  映射Map[url][time],url进行字符串hash,再进行枚举统计。
  这两题如果做成两维映射,内存吃不消,既然两题中的一维是已经指定的,变化的只是时间段,因此可以用一维表示,先预处理,再进行统计。
      用的MapReduce的思想。

  按时间分成小文件,各自对urlip进行hash
  再分级做桶,同时merge各时间区段的hash表。
  这样查询就能做到Log级别。

 

 


  转载请注明:http://www.cnblogs.com/iloveyouforever/

0 0