百度笔试题

来源:互联网 发布:cn域名ns记录到哪里查 编辑:程序博客网 时间:2024/05/18 03:42

第一题     简答题
1. 多线程和多进程模式有什么区别?在用两种模型开发服务程序时,分别有什么优缺点?采用长连接和短连接模式有什么区别?分别有什么优缺点?采用同步和异步模式有什么区别?分别有什么优缺点。
(1)启动进程的时候,操作系统会为进程分配资源,其中最主要的资源是内存空间,因为程序是在内存中运行的。在进程中,有些程序流程块是可以乱序执行的,并且这个代码块可以同时被多次执行。实际上,这样的代码块就是线程体。线程是进程中乱序执行的代码流程。当多个线程同时运行的时候,这样的执行模式成为并发执行。
对于一个进程中的多个线程来说,多个线程共享进程的内存块,当有新的线程产生的时候,操作系统不分配新的内存,而是让新线程共享原有的进程块的内存。因此,线程间的通信很容易,速度也很快。不同的进程因为处于不同的内存块,因此进程之间的通信相对困难。线程切换快,但实现稍复杂。进程易实现,较稳定,但性能与线程相比较差。
(2)所谓长连接,指在一个TCP连接上可以连续发送多个数据包,在TCP连接保持期间,如果没有数据包发送,需要双方发检测包以维持此连接,一般需要自己做在线维持。 
短连接是指通信双方有数据交互时,就建立一个TCP连接,数据发送完成后,则断开此TCP连接,一般银行都使用短连接。


长连接多用于操作频繁,点对点的通讯,而且连接数不能太多情况,。每个TCP连接都需要三步握手,这需要时间,如果每个操作都是先连接,再操作的话那么处理速度会降低很多,所以每个操作完后都不断开,次处理时直接发送数据包就OK了,不用建立TCP连接。而像WEB网站的http服务一般都用短链接,因为长连接对于服务端来说会耗费一定的资源,而像WEB网站这么频繁的成千上万甚至上亿客户端的连接用短连接会更省一些资源,如果用长连接,而且同时有成千上万的用户,如果每个用户都占用一个连接的话,那可想而知吧。所以并发量大,但每个用户无需频繁操作情况下需用短连好。 


(3)同步:调用方调用一个程序,等待返回,然后再继续下面的程序处理 
异步: 调用方调用一个程序,不等待返回,继续执行下面的程序。
1)异步通信简单,双方时钟可允许一定误差。同步通信较复杂,双方时钟的允许误差较小。
2)通信效率:异步通信低,同步通信高。


2.请写出以下程序的运行结果,并解释导致这样运行结果的关键性原因。
 #include <iostream>
using std::cout;
class P
{
public:
virtual void print() 
{
cout << "P"; 
}
};
class Q: public P 
{
public:
virtual void print() 
{
cout << "Q";
}
};
int main() 
{
P * p = new P;
Q * q = static_cast <Q *> (p);
 
q->print();
         delete p;
cout << endl;
 
         q = new Q;
         p = q;
         q->print();
         p->print();
         cout << endl;
 
         p = new (q) P;
         q->print();
         p->print();
         cout << endl;
 
         p->~P();
         delete q;
         return 0;
}
P
QQ
PP
 
第二题 算法与程序设计题
1.给定如下的n*n的数字矩阵,每行从左到右是严格递增, 每列的数据也是严格递增
1 2 3
3 5 6
4 8 9
现在要求设计一个算法, 给定一个数k 判断出k是否在这个矩阵中。 描述算法并且给出时间复杂度(不考虑载入矩阵的消耗)
算法思想:
      沿着对角线查找,获得i,使得k位于a[i][i]与a[i+1][i+1]之间。
       k只可能存在于a[i][i]对应的右上角矩阵 和a[i+1][i+1]对应的左下角矩阵。
       使用递归法继续查找即可。
时间复杂度 O(n)
int searchK(int int_arr[][],int n,int startlow,int startclm,int k)
{
int lefttemp=0;
int downtemp=0;
int i=0;
while(int_arr[startlow+i][startclm+i]<k||i<n)
i++;
if (i==n)
return 0;
else if(arr[i][i]==k)
reuturn 1;
else 
return searchK(int_arr,n,startlow,startclm+i,k)+searchK(int_arr,n,startlow+i,startclm,k);
}
2.设 一个64位整型n,各个bit位是1的个数为a个. 比如7, 2进制就是 111,  所以a为3。
现在给出m个数, 求各个a的值。要求代码实现。
 #include <iostream>
#include<vector>
using namespace std;


int count(long long v)
{
int num=0;
while(v)
{
v &=(v-1); //执行效率为V中1的个数,时间复杂度比通过除操作、位操作比较高出很多
num++;
}
return num;
}


void main()
{
vector<long long> arr;
long long i;
cout<<"输入需要计算的数,Ctrl+z 停止" <<endl;
while(cin>>i)
{ //输入随机个数的数,使用Ctrl+z 停止,之后回车键继续。
arr.push_back(i);
};
for(vector<long long>::size_type idx=0;idx!=arr.size();++idx)
{
int n=count(arr[idx]);
cout<<n<<"\n";
}


}
 
第三题 系统设计题
实现一个简化的搜索提示系统。给定一个包含了用户query的日志文件,对于输入的任意一个字符串s,输出以s为前缀的在日志中出现频率最高的前10条query。
由于是分布式系统,假设至少有26台机器,每个机器存储以26个字母开头的query日志文件(如机器1存的是a字母开头的,机器2存的是以b字母开头的……)
每个机器上维护着一张哈希表,对于每条query, 在哈希表表中存放其地址(哈希地址为链式的),并对其进行排序,按频率由高到低进行排序。
当用户进行搜索时,可以很快定位到某台机器,并根据哈希表,返回出现频率最高的前10条query。


提示:
1、可以预处理日志
2、假设query不超过10亿条,每个query不超过50字节。
3、考虑在大查询量的情况下如何实现分布式服务


百度2013校园招聘笔试题(含整理的答案)

一:简答题(30)
1:数据库以及线程发生死锁的原理及必要条件,如何避免死锁
答:
产生死锁的原因主要是:
(1)因为系统资源不足。
(2)进程运行推进的顺序不合适。
(3)资源分配不当等。
产生死锁的四个必要条件:
(1)互斥条件:一个资源每次只能被一个进程使用。
(2)请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
(3)不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。
(4)循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
避免死锁:
死锁的预防是通过破坏产生条件来阻止死锁的产生,但这种方法破坏了系统的并行性和并发性。
死锁产生的前三个条件是死锁产生的必要条件,也就是说要产生死锁必须具备的条件,而不是存在这3个条件就一定产生死锁,那么只要在逻辑上回避了第四个条件就可以避免死锁。
避免死锁采用的是允许前三个条件存在,但通过合理的资源分配算法来确保永远不会形成环形等待的封闭进程链,从而避免死锁。该方法支持多个进程的并行执行,为了避免死锁,系统动态的确定是否分配一个资源给请求的进程。
预防死锁:具体的做法是破坏产生死锁的四个必要条件之一
2:面向对象的三个基本元素,五个基本原则
答:
三个基本元素:
封装
继承
多态
五个基本原则:
单一职责原则(Single-Resposibility Principle):一个类,最好只做一件事,只有一个引起它的变化。单一职责原则可以看做是低耦合、高内聚在面向对象原则上的引申,将职责定义为引起变化的原因,以提高内聚性来减少引起变化的原因。
开放封闭原则(Open-Closed principle):软件实体应该是可扩展的,而不可修改的。也就是,对扩展开放,对修改封闭的。
Liskov替换原则(Liskov-Substituion Principle):子类必须能够替换其基类。这一思想体现为对继承机制的约束规范,只有子类能够替换基类时,才能保证系统在运行期内识别子类,这是保证继承复用的基础。
依赖倒置原则(Dependecy-Inversion Principle):依赖于抽象。具体而言就是高层模块不依赖于底层模块,二者都同依赖于抽象;抽象不依赖于具体,具体依赖于抽象。
接口隔离原则(Interface-Segregation Principle):使用多个小的专门的接口,而不要使用一个大的总接口。
3:windows内存管理的机制以及优缺点
答:
 分页存储管理基本思想:
用户程序的地址空间被划分成若干固定大小的区域,称为“页”,相应地,内存空间分成若干个物理块,页和块的大小相等。可将用户程序的任一页放在内存的任一块中,实现了离散分配。
分段存储管理基本思想:
将用户程序地址空间分成若干个大小不等的段,每段可以定义一组相对完整的逻辑信息。存储分配时,以段为单位,段与段在内存中可以不相邻接,也实现了离散分配。
段页式存储管理基本思想:
分页系统能有效地提高内存的利用率,而分段系统能反映程序的逻辑结构,便于段的共享与保护,将分页与分段两种存储方式结合起来,就形成了段页式存储管理方式。
在段页式存储管理系统中,作业的地址空间首先被分成若干个逻辑分段,每段都有自己的段号,然后再将每段分成若干个大小相等的页。对于主存空间也分成大小相等的页,主存的分配以页为单位。
段页式系统中,作业的地址结构包含三部分的内容:段号     页号      页内位移量
程序员按照分段系统的地址结构将地址分为段号与段内位移量,地址变换机构将段内位移量分解为页号和页内位移量。
为实现段页式存储管理,系统应为每个进程设置一个段表,包括每段的段号,该段的页表始址和页表长度。每个段有自己的页表,记录段中的每一页的页号和存放在主存中的物理块号。
二:程序设计题(40)
 
1:公司里面有1001个员工,现在要在公司里面找到最好的羽毛球选手,也就是第一名,每个人都必须参赛,问至少要比赛多少次才能够找到最好的羽毛球员工。
答:两两比赛,分成500组剩下一人,类似于归并排序的方式,比出冠军后,让冠军之间再比,主要是要想想多余的那一个选手如何处理,必然要在第一次决出冠军后加入比赛组。
 
2:现在有100个灯泡,每个灯泡都是关着的,第一趟把所有的灯泡灯泡打开,第二趟把偶数位的灯泡制反(也就是开了的关掉,关了的打开),第三趟让第3,6,9....的灯泡制反.......第100趟让第100个灯泡制反,问经过一百趟以后有多少灯泡亮着
答: 
1.对于每盏灯,拉动的次数是奇数时,灯就是亮着的,拉动的次数是偶数时,灯就是关着的。
2.每盏灯拉动的次数与它的编号所含约数的个数有关,它的编号有几个约数,这盏灯就被拉动几次。
3.1——100这100个数中有哪几个数,约数的个数是奇数。我们知道一个数的约数都是成对出现的,只有完全平方数约数的个数才是奇数个。
所以这100盏灯中有10盏灯是亮着的。
它们的编号分别是: 1、4、9、16、25、36、49、64、81、100。
 3:有20个数组,每个数组有500个元素,并且是有序排列好的,现在在这20*500个数中找出排名前500的数
答:TOP-K问题,用个数为K的最小堆来解决
4. 字符串左移,void *pszStringRotate(char *pszString, intnCharsRotate),比如ABCDEFG,移3位变DEFGABC,要求空间复杂度O(1),时间复杂度O(n)
 
 
 
013.9.28百度 ----移动软件开发--- 笔试题
一、简答题
1.动态链接库与静态链接库的概念,优缺点
2.轮询任务调度于抢占式任务调度概念,及区别
3.第三版程序员面试宝典P65,面试例题2.原题
二、算法与程序题(30分)
1.一栋大楼底层有1001跟电线,电线的另一端在大楼顶,现有一个电池,一个灯泡,许多短电线,设计找到楼底和楼顶的线头为一根电线,找出上下楼多少次能全部找到。
2.长度为N(N很大)的字符串,求字符串中的最大回文字串
 3.大概是void*memcopy(void *des, void *src, size_t n)
将src的n bytes 复制到des,内存有overlap
三,系统设计
缓存系统服务器的设计,(很长,没记住)

 


 
2009百度校园招聘笔试题-研发工程师
一:算法题 
有一段文本,由英文字母、阿拉伯数字、GB2 2编码的中文字符和一些常用标点符号(假设只包含全/半角的逗号和句子)组成。请写出程序,统计这段文本中每个字的出现次数,对“字”的定义如下:1,连续的英文字母或者阿拉伯数字,例如ab3或123,但最长不超过32个字符;2,包含不超过一个半角句点的两段连续数字,例如2.34,但最长不超过32个字符3,单个汉字  
二:开放性题目:ORMapping是进行快速web开发经常使用到的技术,请设计一个简单的ORMapping框架,请首先说明设计思路,然后给出设计和Mapping部分的编码,并指出实现ORMapping所用到的编程语言的关键语言特性,要求:1,实现简单对象到关系的映射2,完成一对多关系到对象的映射。  
三:数据库题 
设计一个游戏积分系统,能够实现以下功能:1,用户在客户端结束游戏后,能够通过相应接口将积分进行上传;2,服务端保存结果并能展示该游戏的积分排行情况,分数按照从高到低排列,相同分数下按照提交时间的先后排定顺序;3,排行榜只展现排名前200的用户;4,同一个用户多次提交的情况下,只取分数最高的一次记录;5,系统要有一定的扩展性,能够灵活的增加、删除一个游戏。 
要求:1,阐述客户端和服务端如何进行交互,交互流程是怎样的,设计合理的交互过程及接口。 
2,设计服务端存储系统,阐述采用的存储方案,如果是使用数据库,详细说明表的结构索引等。 
3,系统要求有很强的防作弊功能,能够屏蔽用户自己伪造数据提交成其他的 spam行为。 
4,在满足功能的前提下,能够尽量提高整套系统的效率,例如:降低负载、缩 短响应时间等。 
5,同时在线游戏的用户有百万级,因此单机很可能承受不了这么大的浏览压力,在设计系统的时候要考虑多台服务器如何部署,怎样保证负载均衡 说明: 
1, 用户的登录信息系统可以直接获取到,设计的时候不用考虑这个问题 2, 要求中第5条为附加功能,在满足功能的前提下再考虑多服务器的部署问题 3, 客户端与服务器的交互采用简单的HTTP协议即可,不用考虑其他交互方式。 四:设计题 

历史操作信息分页显示设计。现有一系统,需要保存用户6个月内的操作信息以提供给用户查询,由于历史操作的数据量特别大,采用每个月的操作信息保存在一张数据表的形式存显示总的符合查询条件的记录数以及总的页数2,以上系统采用WEB形式实现。


一、简答题
1. 请说说C++/Java/Objective-C/C#语言是如何体现面向对象的
2. 请用C++或者Java编写实现多态
3. 编写一个栈的压栈操作(push),栈的结构为:
Struck Stack{
Element * base;
Element *top;
Int capacity;
}
实现以下函数:bool push(Stack *s Element elem),注:s已被初始化,Element为基本数据类型,初始化大小为INIT_SIZE
二、算法与程序题
1. 查找一字串中子串的个数,比如”Hello world”中”o”的个数为2,写出这个函数
2. 使用非递归方法实现二叉树的后序遍历,要求时间复杂度和空间复杂度都为O(n)
3. 给定一链表,其中的节点有两指针,指针一指向之后第一个节点,指针二指向之后第二个节点,请设计一个函数,删除链表中所有值为M的节点
三、系统设计题
基于手机系统平台,设计一个Push(消息推送)系统,包括手机端和push server端,这套push服务系统是一个基础服务系统,不包括具体业务逻辑功能,是一个开放系统,开放给第三方应用开发者使用,请基于手机系统的一些特性来设计这套push系统
1. 描述手机端部分设计时需要考虑的关键性能指标
2. 画出手机端程序的系统结构图
3. 请画出第三方程序使用这套系统时所涉及到的相关部分的系统结构图
4. 你觉得基于这套系统能开发一个什么样的第三方程序,请给出一个例子。


移动开发工程师(记忆版) 


1,解释一下精简指令集RISC。
2,给出二叉树后序遍历和中序遍历,写出前序遍历 
3, 重写和重载的区别 
编程题: 
1,链表的逆序, 1->2->3->4->5 变为 5->4->3->2->1
2,两个排过序的数组,快速找出两者相同的元素。
3,1000瓶酒,有一瓶有毒,用多少只老鼠可以一次测出哪瓶酒是有毒的。


看到没有,都超级简单的,全是经典题,亲们是不是感觉百度也不多如此吗?但是大题:


设计一个Email终端,支持多账户,POP3,IMAP,smtp。给第三方使用。
1,写出至少5种用例
2,采用sqlite数据库,写出 账户,已发邮件,已收邮件,草稿 的表
3,假设完成POP3,IMAP,smtp协议,画出模块图。


 百度2014校园招聘-研发工程师笔试题(济南站)

一,简答题(30分)

1,当前计算机系统一般会采用层次结构存储数据,请介绍下典型计算机存储系统一般分为哪几个层次,为什么采用分层存储数据能有效提高程序的执行效率?(10分)

所谓存储系统的层次结构,就是把各种不同存储容量、存取速度和价格的存储器按层次结构组成多层存储器,并通过管理软件和辅助硬件有机组合成统一的整体,使所存放的程序和数据按层次分布在各种存储器中。目前,在计算机系统中通常采用三级层次结构来构成存储系统,主要由高速缓冲存储器Cache、主存储器和辅助存储器组成。
存储系统多级层次结构中,由上向下分三级,其容量逐渐增大,速度逐级降低,成本则逐次减少。整个结构又可以看成两个层次:它们分别是主存一辅存层次和cache一主存层次。这个层次系统中的每一种存储器都不再是孤立的存储器,而是一个有机的整体。它们在辅助硬件和计算机操作系统的管理下,可把主存一辅存层次作为一个存储整体,形成的可寻址存储空间比主存储器空间大得多。由于辅存容量大,价格低,使得存储系统的整体平均价格降低。由于Cache的存取速度可以和CPU的工作速度相媲美,故cache一主存层次可以缩小主存和cPu之间的速度差距,从整体上提高存储器系统的存取速度。尽管Cache成本高,但由于容量较小,故不会使存储系统的整体价格增加很多。
综上所述,一个较大的存储系统是由各种不同类型的存储设备构成,是一个具有多级层次结构的存储系统。该系统既有与CPU相近的速度,又有极大的容量,而成本又是较低的。其中高速缓存解决了存储系统的速度问题,辅助存储器则解决了存储系统的容量问题。采用多级层次结构的存储器系统可以有效的解决存储器的速度、容量和价格之间的矛盾。

2,Unix/Linux系统中僵尸进程是如何产生的?有什么危害?如何避免?(10分)

一个进程在调用exit命令结束自己的生命的时候,其实它并没有真正的被销毁,而是留下一个称为僵尸进程(Zombie)的数据结构(系统调用exit,它的作用是使进程退出,但也仅仅限于将一个正常的进程变成一个僵尸进程,并不能将其完全销毁)。
在Linux进程的状态中,僵尸进程是非常特殊的一种,它已经放弃了几乎所有内存空间,没有任何可执行代码,也不能被调度,仅仅在进程列表中保留一个位置,记载该进程的退出状态等信息供其他进程收集,除此之外,僵尸进程不再占有任何内存空间。它需要它的父进程来为它收尸,如果他的父进程没安装SIGCHLD信号处理函数调用wait或waitpid()等待子进程结束,又没有显式忽略该信号,那么它就一直保持僵尸状态,如果这时父进程结束了,那么init进程自动会接手这个子进程,为它收尸,它还是能被清除的。但是如果如果父进程是一个循环,不会结束,那么子进程就会一直保持僵尸状态,这就是为什么系统中有时会有很多的僵尸进程。

避免zombie的方法: 
1)在SVR4中,如果调用signal或sigset将SIGCHLD的配置设置为忽略,则不会产生僵死子进程。另外,使用SVR4版的sigaction,则可设置SA_NOCLDWAIT标志以避免子进程 僵死。 
Linux中也可使用这个,在一个程序的开始调用这个函数 signal(SIGCHLD,SIG_IGN); 
2)调用fork两次。
3)用waitpid等待子进程返回.

3,简述Unix/Linux系统中使用socket库编写服务器端程序的流程,请分别用对应的socket通信函数表示(10分)

TCP socket通信
服务器端流程如下:
1.创建serverSocket
2.初始化 serverAddr(服务器地址)
3.将socket和serverAddr 绑定 bind
4.开始监听 listen
5.进入while循环,不断的accept接入的客户端socket,进行读写操作write和read
6.关闭serverSocket
客户端流程:
1.创建clientSocket
2.初始化 serverAddr
3.链接到服务器 connect
4.利用write和read 进行读写操作
5.关闭clientSocket 


这个列表是一个Berkeley套接字API库提供的函数或者方法的概要:
socket() 创建一个新的确定类型的套接字,类型用一个整型数值标识,并为它分配系统资源。
bind() 一般用于服务器端,将一个套接字与一个套接字地址结构相关联,比如,一个指定的本地端口和IP地址。
listen() 用于服务器端,使一个绑定的TCP套接字进入监听状态。
connect() 用于客户端,为一个套接字分配一个自由的本地端口号。 如果是TCP套接字的话,它会试图获得一个新的TCP连接。
accept() 用于服务器端。 它接受一个从远端客户端发出的创建一个新的TCP连接的接入请求,创建一个新的套接字,与该连接相应的套接字地址相关联。
send()和recv(),或者write()和read(),或者recvfrom()和sendto(), 用于往/从远程套接字发送和接受数据。
close() 用于系统释放分配给一个套接字的资源。 如果是TCP,连接会被中断。
gethostbyname()和gethostbyaddr() 用于解析主机名和地址。
select() 用于修整有如下情况的套接字列表: 准备读,准备写或者是有错误。
poll() 用于检查套接字的状态。 套接字可以被测试,看是否可以写入、读取或是有错误。
getsockopt() 用于查询指定的套接字一个特定的套接字选项的当前值。
setsockopt() 用于为指定的套接字设定一个特定的套接字选项。

二,算法与程序设计题

1,使用C/C++编写函数,实现字符串反转,要求不使用任何系统函数,且时间复杂度最小,函数原型:char* reverse_str(char* str)。(15分)

获取首尾指针,然后将首尾指针指向的元素交换,将首指针指向下一个,将尾指针指向前一个,交换指针指向的元素,然后重复执行,直到首尾指针相遇。 

2,给定一个如下格式的字符串(1,(2,3),(4,(5,6),7))括号内的元素可以是数字,也可以是另一个括号,请实现一个算法消除嵌套的括号,比如把上面的表达式变成:(1,2,3,4,5,6,7),如果表达式有误请报错。(15分)

使用栈和队列实现