百度笔试大集锦

转:http://www.itmian4.com/forum.php?mod=viewthread&tid=3358#lastpost

1 编程:

  用C语言实现一个revert函数,它的功能是将输入的字符串在原串上倒序后返回。

2 编程:

  用C语言实现函数void * memmove(void *dest,const void *src,size_t n)。memmove函数的功能是拷贝src所指的内存内容前n个字节到dest所指的地址上。

3 英文拼写纠错:

  在用户输入英文单词时,经常发生错误,我们需要对其进行纠错。假设已经有一个包含了正确英文单词的词典,请你设计一个拼写纠错的程序。

(1)请描述你解决这个问题的思路;
(2)请给出主要的处理流程,算法,以及算法的复杂度;
(3)请描述可能的改进(改进的方向如效果,性能等等,这是一个开放问题)。

4 寻找热门查询

  搜索引擎会通过日志文件把用户每次检索使用的所有检索串都记录下来,每个查询串的长度为1-255字节。假设目前有一千万个记录,这些查询串的重复度比较高,虽然总数是1千万,但如果除去重复后,不超过3百万个。一个查询串的重复度越高,说明查询它的用户越多,也就是越热门。请你统计最热门的10个查询串,要求使用的内存不能超过1G。

(1)请描述你解决这个问题的思路;
(2)请给出主要的处理流程,算法,以及算法的复杂度。

5 集合合并

  给定一个字符串的集合,格式如: {aaa bbb ccc}, {bbb ddd},{eee fff},{ggg},{ddd hhh} 要求将其中交集不为空的集合合并,要求合并完成后的集合之间无交集,例如上例应输出 {aaa bbb ccc ddd hhh},{eee fff}, {ggg}

(1)请描述你解决这个问题的思路;
(2)请给出主要的处理流程,算法,以及算法的复杂度
(3)请描述可能的改进(改进的方向如效果,性能等等,这是一个开放问题)。


1 题

char *revert(char * str)
{
int n=strlen(str);
int i=0;
char c;
for(i=0;i {
c=str;
str=str[n-i];
str[n-i]=c;
}
return str;
}

///

2 题

void * memmove(void *dest,const void *src,size_t n)
{
assert((dest!=0)&&(src!=0));
char * temp=(char * )dest;
char * ss=(char * )src;
int i=0;
for(;i {
*temp =*ss ;
}
return temp;
}

/

3 题

(1)思路: 字典以字母键树组织,在用户输入同时匹配

(2) 流程:
每输入一个字母: 
沿字典树向下一层,
a)若可以顺利下行,则继续至结束,给出结果;
b)若该处不能匹配,纠错处理,给出拼写建议,继续至a);
算法:

1.在字典中查找单词

字典采用27叉树组织,每个节点对应一个字母,查找就是一个字母
一个字母匹配.算法时间就是单词的长度k.

2.纠错算法

情况:当输入的最后一个字母不能匹配时就提示出错,简化出错处理,动态提示可能 处理方法:

(a)当前字母前缺少了一个字母:搜索树上两层到当前的匹配作为建议;
(b)当前字母拼写错误:当前字母的键盘相邻作为提示;(只是简单的描述,可 以有更多的)
根据分析字典特征和用户单词已输入部分选择(a),(b)处理

复杂性分析:影响算法的效率主要是字典的实现与纠错处理

(a)字典的实现已有成熟的算法,改进不大,也不会成为瓶颈;
(b)纠错策略要简单有效 ,如前述情况,是线性复杂度;

(3)改进

策略选择最是重要,可以采用统计学习的方法改进。

//

4 题

(1)思路:用哈希做

(2) 首先逐次读入查询串,算哈希值,保存在内存数组中,同时统计频度(注意值与日志项对应关系) my.chinahrlab.com 选出前十的频度,取出对应的日志串,简单不过了。哈希的设计是关键。

//

5 题

(1)思路:先将集合按照大小排列后,优先考虑小的集合是否与大的集合有交集。有就合并,如果小集合与所有其他集合都没有交集,则独立。独立的集合在下一轮的比较中不用考虑。这样就可以尽量减少字符串的比较次数。当所有集合都独立的时候,就终止。

(2)处理流程:

1.将集合按照大小排序,组成集合合并待处理列表
2.选择最小的集合,找出与之有交集的集合,如果有,合并之;如果无,则与其它集合是独立集合,从待处理列表 中删除。
3.重复直到待处理列表为空

算法: 1。将集合按照大小从小到大排序,组成待处理的集合列表。 2。取出待处理集合列表中最小的集合,对于集合的每个元素,依次在其他集合中搜索是否有此元素存在:

1>若存在,则将此小集合与大集合合并,并根据大小插入对应的位置 。转3。

2>若不存在,则在该集合中取下一个元素。如果无下一个元素,即所有元素都不存在于其他集合。则表明此集合独立,从待处理集合列表中删除。并加入结果集合列表。转3。

3。如果待处理集合列表不为空,转2。

如果待处理集合列表为空,成功退出,则结果集合列表就是最终的输出。

算法复杂度分析:

  假设集合的个数为n,最大的集合元素为m 排序的时间复杂度可以达到n*log(n) 然后对于元素在其他集合中查找,最坏情况下为(n-1)*m 查找一个集合是否与其他集合有交集的最坏情况是m*m*(n-1) 合并的时间复杂度不会超过查找集合有交集的最坏情况。所以最终最坏时间复杂度为O(m*m*n*n)

  需要说明的是:此算法的平均时间复杂度会很低,因为无论是查找还是合并,都是处于最坏情况的概率很小,而且排序后优先用最小集合作为判断是否独立的对象,优先与最大的集合进行比较,这些都最大的回避了最坏情况。

(3)可能的改进:

  首先可以实现将每个集合里面的字符串按照字典序进行排列,这样就可以将查找以及合并的效率增高。另外,可能采取恰当的数据结构也可以将查找以及合并等操作的效率得到提高。

、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、

1)此题10分

  对任意输入的正整数N,编写C程序求N!的尾部连续0的个数,并指出计算复杂度。如:18!=6402373705728000,尾部连续0的个数是3。   (不用考虑数值超出计算机整数界限的问题)

2)此题10分   编写一个C语言函数,要求输入一个url,输出该url是首页、目录页或者其他url 
  如下形式叫做首页: 
militia.info/ 
www.apcnc.com.cn/ 
http://www.cyjzs.comwww.greena888.com/ 
www.800cool.net/ 
http://hgh-products.my-age.net/ 
 如下形式叫做目录页: 
thursdaythree.net/greenhouses--gas-global-green-house-warming/ 
http://www.mw.net.tw/user/tgk5ar1r/profile/ 
http://www.szeasy.com/food/yszt/chunjie/ 
www.fuckingjapanese.com/Reality/

请注意:

a) url有可能带http头也有可能不带 
b)动态url(即含有"?"的url)的一律不算目录页,如: 
www.buddhismcity.net/utility/mailit.php?l=/activity/details/3135/ 
www.buddhismcity.net/utility/mailit.php?l=/activity/details/2449/

 另:如果你会linux,请用linux下的grep命令实现第2题的功能(附加5分)。

3)此题40分

 如果必须从网页中区分出一部分"重要网页"(例如在10亿中选8亿),比其他网页更值得展现给用户,请提出一种方案。

4)此题40分

  假设有10亿网页已经被我们存下来,并提供如下信息:网页全文(即网页的源码)、全文长度、网页正文(即网页中提取的主体文字)、正文长度,以及其他网页提取物等,现在希望去掉其中的重复网页,请提出可行的方案,计算出每个网页对应的重复度,你可以自己对网页重复下定义,也可以提出需要哪些更多的网页提取物来实现更好的去重复方案。

、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、

好久没来了。

  发生了一些事情,其间的心情已不是几行文字所能表述的了。

  终于明白有些事情,并不是自己努力就一定能圆满的;有些事情,是我控制不了的。

  唉,不提也罢!

  说说今天去百度笔试的经历吧

  部门:百度搜索应用技术部。

  地点:海淀南路银科大厦(海淀图书城西临)18层。

  时间:2005/6/15 10:00-11:20 am

  九点从实验室出发,725到知春路,转735,到海淀桥下车,9:50到达百度。在725的车上碰到一男士索要手机号,说自己认识信息产业部的部长杨泽民先生,以居高临下的姿态把手机号给了他-__-!

  在百度前台见到了一直帮我安排笔试的杨韫敏jj,不是想象中的HR形象,而是一副干练的女IT的样子跳跃的灵魂很快,给我找了一间小会议室,只有一张桌子,两把椅子,还帮我开了灯,关门,走人,我开始看题。冷汗也开始流。翻了一下三页纸的笔试题,只有很少的传说中的Linux题目,其他的全是C、数据结构、算法编程的题。第一反应:走人!但又觉得对不起陈jj,关键的是我已经在笔试题上写了姓名和学校了,sign,总的为自己的名字和学校负责吧,他们是无辜的。如此斗争良久,决定坚持下来。

  题目大致是这样的:

  第一部分选择题:有几道网络相关的题目,巨简单,比如第一题是TCP、RIP、IP、FTP中哪个协议是传输层的......。有一道linux的chown使用题目。其他的全是数据结构的题目!什么链,表,码的,不知所云跳跃的灵魂唉,我可以没有学过数据结构的人呐!真残忍!这一部分迅速猜完!

  第二部分简答题:

1、在linux中如何编译C程序,使之成为可执行文件?如何调试?

答案:

1)检查程序中.h文件所在的目录,将其加入系统PATH中;

2)执行C编译:#gcc [源文件名] -o [目标文件名]

      执行C++编译:#g++ [源文件名] -o [目标文件名]

3)改变目标文件为可执行文件:#chmod +x [目标文件名]

4)如需将多个可执行文件连续执行,可生成批处理文件:

#vi [批处理文件名]

        可执行文件1

        可执行文件2

.........

        最后将该批处理文件属性该位可执行。

  调试:在编译时使用-g参数,就可以使用gdb进行调试。

2、写出内存分配和释放的函数,并指出区别。

答案:

C语言的标准内存分配函数:malloc,calloc,realloc,free等。
malloc与calloc的区别为1块与n块的区别:
malloc调用形式为(类型*)malloc(size):在内存的动态存储区中分配一块长度为“size”字节的连续区域,返回该区域的首地址。
calloc调用形式为(类型*)calloc(n,size):在内存的动态存储区中分配n块长度为“size”字节的连续区域,返回首地址。
realloc调用形式为(类型*)realloc(*ptr,size):将ptr内存大小增大到size。
free的调用形式为free(void*ptr):释放ptr所指向的一块内存空间。
C++中为new/delete函数。

3、写出socket函数,并指出其功能。

socket():建立socket通信描述符;
bind():将套接字和机器上的一定的端口关联;
connect():连接到远程主机;
listen():使套接字做好连接的准备,规定等待服务请求队列的长度;
accept():接受连接,一旦有客户端发出连接,accept返回客户地址信息和一个新的sock;
  有了这个新的sock,双方就可以开始收发数据:
send()和recv():用于流式套接字或者数据套接字的通讯;
sendto()和recvfrom():用于无连接的数据报套接字;
close():关闭套接字;
shutdown():选择性的关闭套接字,可以只允许某一方向的通讯关闭;
getpeername():返回流式套接字时对端peer信息;
gethostname():返回程序所运行的机器的主机名字;
gethostbyname():返回本机IP;

  第三部分编程题:

1、从文件中读取字符串数据,反序显示并大小写转换。

2、给定26字母表以及对应的密码表,编程实现加密及解密功能。

第四部分思考题(正是传说中的字典纠错题):

  用户在输入英文单词时经常出错,现对其进行就错。给定一个正确的英文词典,考虑纠错实现。1)指出思路。2)流程、算法难易程度及可能的改进策略。

  不过陈jj没有给我答题纸,只好拿试题的背面做了答题纸兼草稿纸-___-!说实话有些题目是很基础的,就是没背过。不知怎么搞得,巨潦草。实验室参加过笔试的通同学都是憋着劲做了两个多小时才答完,而我只一个小时就完了,唉,正好说明肚子里只有别人一半的东西~~看着潦草而不着边际的答题,决定在最后给陈jj写段话,大意就是感谢她帮我挽回了一次笔试的机会,但我的表现很遗憾等等......然后交卷走人~~

  没想到交了试卷没让我走,等了大约30分钟的样子,有个很深沉的gg来看我的卷子跳跃的灵魂-___-!我颤颤的跟他说我很长时间没有接触C了,当时脖子都红了,真觉得丢人。gg看了一下,没有很鄙视的样子,问我有没有带简历。当然木有啦~~答应回来给他发个电子版的,然后赶紧跑人了!

、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、

题目大致是这样的:

  第一部分选择题:

  有几道网络相关的题目,巨简单,比如第一题是TCP、RIP、IP、FTP中哪个协议是传输层的......。有一道linux的chown使用题目。其他的全是数据结构的题目!什么链,表,码的,不知所云.唉,我可以没有学过数据结构的人呐!真残忍!这一部分迅速猜完!

  第二部分简答题:

1、在linux中如何编译C程序,使之成为可执行文件?如何调试?

答案: 1)检查程序中.h文件所在的目录,将其加入系统PATH中;

2)执行C编译:#gcc [源文件名] -o [目标文件名]

  执行C++编译:#g++ [源文件名] -o [目标文件名]

3)改变目标文件为可执行文件:#chmod +x [目标文件名]

4)如需将多个可执行文件连续执行,可生成批处理文件:

#vi [批处理文件名]

    可执行文件1

    可执行文件2

.........

        最后将该批处理文件属性该位可执行。

  调试:在编译时使用-g参数,就可以使用gdb进行调试。

2、写出内存分配和释放的函数,并指出区别。

答案:

C语言的标准内存分配函数:malloc,calloc,realloc,free等。
malloc与calloc的区别为1块与n块的区别:
malloc调用形式为(类型*)malloc(size):在内存的动态存储区中分配一块长度为“size”字节的连续区域,返回该区域的首地址。
calloc调用形式为(类型*)calloc(n,size):在内存的动态存储区中分配n块长度为“size”字节的连续区域,返回首地址。
realloc调用形式为(类型*)realloc(*ptr,size):将ptr内存大小增大到size。
free的调用形式为free(void*ptr):释放ptr所指向的一块内存空间。
C++中为new/delete函数。

3、写出socket函数,并指出其功能。

socket():建立socket通信描述符;
bind():将套接字和机器上的一定的端口关联;
connect():连接到远程主机;
listen():使套接字做好连接的准备,规定等待服务请求队列的长度;
accept():接受连接,一旦有客户端发出连接,accept返回客户地址信息和一个新的sock;
  有了这个新的sock,双方就可以开始收发数据:
send()和recv():用于流式套接字或者数据套接字的通讯;
sendto()和recvfrom():用于无连接的数据报套接字;
close():关闭套接字;
shutdown():选择性的关闭套接字,可以只允许某一方向的通讯关闭;
getpeername():返回流式套接字时对端peer信息;
gethostname():返回程序所运行的机器的主机名字;
gethostbyname():返回本机IP;

  第三部分编程题:

1、从文件中读取字符串数据,反序显示并大小写转换。

2、给定26字母表以及对应的密码表,编程实现加密及解密功能。

  第四部分思考题(正是传说中的字典纠错题):

  用户在输入英文单词时经常出错,现对其进行就错。给定一个正确的英文词典,考虑纠错实现。1)指出思路。2)流程、算法难易程度及可能的改进策略。

一道算法题目答案

int Replace(Stringtype &S,Stringtype T,Stringtype V);//将串S中所有子串T替换为V,并返回置换次数 

for(n=0,i=1;i〈=Strlen(S)-Strlen(T)+1;i++) //注意i的取值范围 
if(!StrCompare(SubString(S,i,Strlen(T)),T)) //找到了与T匹配的子串 
{ //分别把T的前面和后面部分保存为head和tail 
StrAssign(head,SubString(S,1,i-1)); 
StrAssign(tail,SubString(S,i+Strlen(T),Strlen(S)-i-Strlen(T)+1)); 
StrAssign(S,Concat(head,V)); 
StrAssign(S,Concat(S,tail)); //把head,V,tail连接为新串 
i+=Strlen(V); //当前指针跳到插入串以后 
n++; 
}//if 
return n; 
}//Replace 
分析:i+=Strlen(V);这一句是必需的,也是容易忽略的.如省掉这一句,则在某些情况下,会引起不希望的后果,虽然在大多数情况下没有影响.请思考:设S='place', T='ace', V='face',则省掉i+=Strlen(V);运行时会出现什么结果? (无限递归face)


百度2005年的笔试题


1.实现 void delete_char(char * str, char ch);
 把str中所有的ch删掉

2.把字符串S中所有A子串换成B,这个没给函数原型

3.搜索引擎的日志要记录所有查询串,有一千万条查询,不重复的不超过三百万
 要统计最热门的10条查询串. 内存<1G. 字符串长 0-255
(1) 主要解决思路 //具体用词和原题不大一样
(2) 算法及其复杂度分析

4.有字典,设计一个英文拼写纠正算法 (1) 思想 (2) 算法及复杂度 (3) 改进

5. { aaa, bb, ccc, dd }, { bbb, ff }, { gg } 等一些字符串的集合
 要求把交集不为空的集合并起来,如上例会得到 { aaa, bb, ccc, dd, ff }, {gg}
(1) 思想 (2) 算法及复杂度 (3) 改进

、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、

一、选择题:15分 共10题

1.一个含有n个顶点和e条边的简单无向图,在其邻接矩阵存储结构中共有____个零元素。 
A.e B.2e C.n2-e D.n2-2e

2.____是面向对象程序设计语言中的一种机制。这种机制实现了方法的定义与具体的对象无关,而对方法的调用则可以关联于具体的对象。 
A.继承(Inhertance) B.模板(Template) 
C.对象的自身引用(Self-Reference) D.动态绑定(Dynamic Binding)

3.应用层DNS协议主要用于实现 网络服务功能. 
A. IP地址到网络设备名字的映射 B. IP地址到网络硬件地址的映射 
C. 网络设备名字到IP地址的映射 D. 网络硬件地址到IP地址的映射

4.linux默认情况下,一个进程最多能打开多少文件? 
A.64 B. 128 C. 512 D. 1024

5.下面结构体 
struct s1 { 
char ch, *ptr; 
union { 
short a, b; 
unsigned int c:2, d:1; 

struct s1 *next; 
}; 
的大小是_____: 
A. 12字节 B.16字节 C.20字节 D. 24字节

6.任何一个基于"比较"的内部排序的算法,若对6个元素进行排序,则在最坏情况下所需的比较次数至少为____。 
A.10 B.11 C.21 D.36

7.以下不是进程间通讯的是___ 
A 共享内存 B 信号量 C线程局部存储 D 消息队列

8.下面程序,求count的值 
int func(x) 

int count= 0; 
x=9999; 
while(x) 

Count ++; 
x = x&(x-1); 

return count; 
}

A 8; B 10; C 5; D 11

9.使用malloc系统调用分配的内存是在____ 上分配的? 
A 栈; B bss; C 物理内存; D 堆

10.最坏情况下,合并两个大小为n的已排序数组所需要的比较次数_____ 
A.2n B.2n-1 C.2n+1 D.2n-2


二、简答题:20分,共3题

1.(5分)下面这段代码是把中英文混合字符串(汉字用两个字节表示,特点是第一个字节的最高位为1)中的大写字母转化为小写字母,请找出其中的bug,注意各种异常情况。 
for (char *piterator = szWord; *piterator != 0; piterator++) 

if (*piterator & 0x80 != 0) 

piterator++; 

else if (*piterator >= 'A' && *piterator <= 'Z')

       piterator += 32;

}

2.(5分)对给定的上亿条无序的url,请按照domain、site以及path分别排序,并请指出排序过程中可能会遇到的哪些问题?如何提高效率? 
例如:http://www.baidu.com/path/about.html,domain、site以及path的定义分别如下: 
Domain:baidu.com 
Site:www.baidu.com 
Path: www.baidu.com/path

3.(10分)某型CPU的一级数据缓存大小为16K字节,cache块大小为64字节;二级缓存大小为256K字节,cache块大小为4K字节,采用二路组相联。经测试,下面两段代码运行时效率差别很大,请分析哪段代码更好,以及可能的原因。 
为了进一步提高效率,你还可以采取什么办法? 
A段代码 
int matrix[1023][15]; 
const char *str = "this is a str"; 
int i, j, tmp, sum = 0;

tmp = strlen(str); 
for(i = 0; i < 1023; i++) { 
for(j = 0; j < 15; j++) { 
sum += matrix[j] + tmp; 

}

B段代码 
int matrix[1025][17]; 
const char *str = "this is a str"; 
int i, j, sum = 0;

for(i = 0; i < 17; i++) { 
for(j = 0; j < 1025; j++) { 
sum += matrix[j] + strlen(str); 

}


三、编程题:30分 共1题

注意:要求尽可能提供完整代码,如果可以编译运行酌情加分。

1.内存中有一个长数组,条目数为10万,数组单元为结构体struct array,sizeof(struct array)为512字节。结构有一int型成员变量weight。现需要取得按weight值从大到小排序的前500个数组单元,请实现算法,要求效率尽可能高。


四、设计题:35分 共1题

注意:请尽可能详细描述你的数据结构、系统架构、设计思路等,建议多写一些伪代码或者流程说明。

1.请设计一个字典。以字符串为索引,存储用户定义的定长结构。要求有增、删、查、改的功能。已经给定一个函数,可以由字符串映射到一个签名,每个签名由两个unsigned int类型组成。假设每一个字符串能够对应唯一的一个签名,完全没有重复(或者重复的概率可以忽略),并且签名分布足够均匀。

请描述你的数据结构?内存如何申请?增、删、查、改的功能如何实现?如果操作很频繁,该如何优化?

、、、、、、、、、、、、、、、、、、、、、、、、、、

经过在线笔试、两轮电话面试,今天上午收到了百度的拒信,我的百度求职算是告一段落了……

  从百度校园招聘开始,我就投了一份简历。在别人都有在线笔试机会的时候,我却没有任何消息。

  听说师兄可以给推荐,我就又通过内部推荐的方式投递了一次,这次很快就有消息了——拒信。

  那时基本上就放弃了百度。可是大概20多天以后,我投递的第一份简历有消息了——通知我在线笔试。经过精心准备,笔试题答得还凑合。过了几天给我来了封邮件告知我笔试通过,会找时间安排电话面试。又过了好几天,我正在剃头的时候接到百度电话,约了第二天下午三点电话面试。心情异常兴奋,回到寝室拼命复习数据结构并收集百度面试题型……临阵磨枪 呵呵。

  百度的面试氛围很是轻松,让你很快就觉得是在聊天而不是面试。第一轮主要是在针对我的在线笔试的题目进行提问和分析,主要讲的是做题的思路和改进的方法。面试时间大概有半个小时,觉得应该有下一轮。

  果然上个星期五晚上接到了百度技术经理的电话,自称姓刘。在前一天我同学也是这个时候接到百度第二面电话,看来是同一个人,后来的面试内容证实了是同一个人。面试过程大概如下:

1、介绍一下项目。

2、提了一个问题:上千万条记录,统计出重复记录最多的前N条。

3、一个概率题:54张扑克牌,除去两张大小王剩下52张扑克牌。问红桃A和黑桃A同时被一个人拿到的概率是多少?

4、多个线程访问共享内存时因该怎么办?

5、在写程序遇到问题的时候,通常采用什么调试方法?

6、一个client/server的协议问题

7、剩下就是随便聊聊,比如有缺点、期望工作的性质、职业规划等

总结一下教训:

1、介绍项目的时候不能一味的按照事前想好的模板说,应该根据所申请的工作的性质,多说一些和自己申请的工作内内容相近的东西说。我在介绍我的项目的时候,说了很多硬件的东西,而相关的Linux下的C编程却没有提到多少,一大失败之处。

2、对于他提的第二个问题,当时因为紧张没有想出来,挂了电话以后才有了思路。

3、这个概率题以前碰到过,而且和同学们讨论过,答案很早就知道了。但是遇到面试的时候,不能马上就说出答案,因为这样摆明了高诉人家你以前就见过这道题,这样就失去了作为考题的意义。所以,如果事前知道答案也不要马上说出来,装作考虑中,然后慢慢说出答案。我就是很快就说出了答案,失败!


4、在问项目的时候,他问我代码行大概有多少?我说大概有5.6K行左右。在回答第四个问题的时候,我几乎是将书上所讲过的东西背了一遍给他,虽然答案是正确的,但是我估计他一听就听出来是在背书了,所以这也会减分不少。,而且百度强调创新,其实就算你不知道答案也可以按照自己的思路说一下的,只要逻辑清晰、合理都会比我背书强……

5、我的回答是有时候用gdb,有时候用输出日志的形式。以我之前给他讲的项目经验是不大可能会涉及这么多的知识的,所以估计他又听出我是在背书了……继续减分

6、后来我发现这个问题其实他不是在考我问题的答案,是考我解决问题的能力和考虑问题的思路。这点是我比较差的地方,没办法……减分

百度电话面试题目:

1.谈谈你对数据库中索引的理解
2.现在普通关系数据库用得数据结构是什么类型的数据结构
3.索引的优点和缺点
4.session和cache的区别是什么
5.如果有几千个session,怎么提高效率
6.session是存储在什么地方,以什么形式存储的。




(2014)秋终端开发笔试题

1.问答题:

  1)TCP/UDP的区别,以及各自在应用层的协议举例。

  2)Android/IOS 中固化数据的方式。

  3)下面这个函数的缺陷:(这个有点想不起来了,好久不研究 了,印象不深刻了)
  char * initMem(char *p)
  {
    
      p=(char *)malloc(100);
      return p;
  }

  voidtest()
 {
   char *p=null;
   initMem(p);
   printf(p);

 }

 

2.编程题:

  1)用C/C++实现字符串的反转。

  2)(1,2,3(4,5,6),7,8)打印出1,2,3,4,5,6,7,8,即去括号,若出现括号不匹配,标识错误。

  3)分别实现二叉查找数root中两个节点的最近相连的双亲节点:递归,非递归函数。

4.系统设计题:

   是一个基于终端上的LBS+IM功能的架构设计,包括四个功能:

  1)用户打开LBS服务

  2)用户通过短信or 微信邀请好友加入LBS

  3)用户查询打开LBS的用户;

  4)用户选择LBS用户并发送IM 文本or 语音信息。

   划出架构设计图、功能图,分析这样设计是如何考虑的。

 

 (2013)笔试题

说明一下,编程题都是自己一点拙见,不免有很多 不到之处,错误的地方还请指出,一定认真修改。谢谢! 

一、简答题

1.简述数据库以及线程死锁产生的原理及必要条件,简述如何避免死锁。

2.请列举面向对象设计的三个基本要素和五个主要涉及原则。

  三个基本要素:封装、继承、多态。

    五个基本原则:

             (1)单一职责原则:就一个类而言,应该仅有一个引起它变化的原因。

             (2)开放封闭原则:软件实体对外扩展开放,对修改封闭。

             (3)里氏替换原则:子类的实例能够替换父类的实例。

             (4)接口分离原则:采用多个专门的接口比使用单一的总接口要好。一个类对另一个类的 

                        依赖性建立在最小的接口上。

             (5)依赖倒置原则:依赖抽象不要依赖具体实现。、

3.简述Windows内存管理的几种方式及其优缺点。

 

(1)块式管理。把主存分为一大块、一大块的,当所需的程序片段不在主存时就分配一块主存空间,把程序片段加载到主存,就算所需要的程序片段只有几个字节也只能把这块分配给它。优点:易于管理;缺点:浪费空间。

(2)页式管理。把主存分为一页一页的,每一页的空间要比一块一块的空间小很多,显然这种方式的空间利用率要比块式管理高出很多。

(3)段式管理。把主存分为一段一段的,每一段的空间又要比一页一页的空间小很多,这种方法在空间利用率上比页式管理高出很多,但也有另外一个缺点,一个程序片段可能会被分为几十个段,这样很多时间就会浪费在计算每一段的物理地址上。(I/O操作)

(4)段页式管理。结合了段式管理和页式管理的优点。把主存分为若干页,每一页又分为若干段。

二、算法和程序设计

1.公司组织一次羽毛球比赛,采用淘汰机制,假设公司有1001个人,如果要评出“公司羽毛球第一高手”的称号,至少需要进行多少场比赛?请简述设计过程,并写出代码模拟比赛过程。

 /*
  * 分析: 我们可以分轮来比赛,每一轮都有2个人去比赛,如果总数(person)是奇数,
  * 
  *       则有一个轮空,否则全部参与比赛,淘汰一半(person/2),剩余[person/2)+remain],
  * 
  *       这里,remain=person%2.,淘汰的人数亦即比赛的场数,加起来就构成了比赛场
  * 
  *       数。
  */

public static void main(String[] args) {

int person = 1001; //当然person一般是由用户来输入的。

int result = 0, remain;

while (person > 0 && person != 1) {

result += person / 2; // 进行了比赛==淘汰的人数

remain = person % 2; // 有没有人轮空

person /= 2; // 比赛后剩余的人数

person += remain; // 要加上轮空的人

}

System.out.println("共进行:" + result + "场比赛");

}

2.一百个灯泡排成一排,第一轮将所有灯泡打开;第二轮每隔一个灯泡关掉一个。即排在偶

数的灯泡被关掉,第三轮每隔两个灯泡,将开着的灯泡关掉,关掉的灯泡打开。依次类推,第100轮结束的时候,还有几盏灯泡亮着。

//哈哈,这道题是在宁波实习的时候有个网友问我的,不几天后就看到百度笔试有这道题,.

//真神奇啊!

//分析:

      

所有的台灯,只有摁下的次数是奇数,那么它一定是打开的,而对于台灯X,如果其前面有基数个X的约数,例如:

4=1*2*4

9=1*3*9

16=1*2*4*8*16

而6=1*2*3*6 //偶数

因此,1~100内,查找X的约数个数为奇数的数X即为开着的台灯。


public static void main(String[] args) {

//编码就很简单了.

for(int i=1;i<100;i++){

if(hasOddOddNumer(i)){

System.out.print("  "+i);

}

}

}

private static boolean hasOddOddNumer(int data) {

boolean result = false;

int approximateNumberCount = 0;

for (int i = 1; i <= data; i++) {

if (0 == data % i) {

approximateNumberCount++;

}

}

if (0 != approximateNumberCount % 2) {

result = true;

}

return result;

}

3.假定有20个有序数组,每个数组有500个数字,数字类型32位uint数值,现在需要取出

这10000个数字中最大的500个,怎么做?

额,这个我看了别人给的方案,发现自己想错了,仅贴出别人的算法:

从20个数组中各取一个数,并记录每个数的来源数组,建立一个含20个元素的大根堆。

此时堆顶就是最大的数,取出堆顶元素,并从堆顶元素的来源数组中取下一个数加入堆,再取最大值,一直这样进行500次即可。

时间复杂度:500*log2(20)

 

三、系统设计题

手机上通常采用九键键盘输入。即:1-9个数字分别对应一定的英文字母(如:2对应ABC, 

3对应DEF,...),因此,用户可以方便的输入中文内容。比如,用户输入“926”,可以对应

“WXYZ”,“ABC"和”MNO“的一系列组合”WAN”,“YAN"、”ZAO“等,这些对应“万”,“严”,“早”

等汉字的中文拼音。

要求我们把这样的输入方式应用在我们的手机联系人查找功能上。有一个联系人列表

UserList,记录了(姓名,手机号)这样的组合,通过输入的数字字符串NumStr,按照下面

的规则把对应的联系人查找出来,返回一个ReaultList。

规则:

1.手机号能连续部分匹配输入的数字字符串NumStr。如输入NumStr=926,则手机号为

13926811111会被查出来;

2.联系人姓名中的汉字转化成拼音后能够连续匹配输入数字字符串NumStr对应的英文字母

组合,如:输入NumStr=926,则联系人“王二”、“万事通”会被查找出来。因为“王二”的“王”的

拼音“WANG”中含有“WAN”,和“926”能匹配。 

输入:

联系人列表UserList;汉字拼音射射表Dict,数字拼音字符串

NumStr。

输出:

符合规则的联系人列表ResultList

/*

   对于这种题,我不知道考察的是什么,其实我们应该可以自由假设自己的条件吧,然后根据自己的步骤来做出判断,下面是我的一个思路,这个真不知道怎么样,还请高手们  不要笑话。
 */ 

设Phone  phoneList存储了所有联系人的信息;

首先,我们获取“926”对应的所有拼音可能组成一个列表:

      List inputNameList=new ArrayList ();

然后,把用户输入的字符串的所有可能add到inputNameList。例如,9,2,6就有3*3*3种可能都add到inputNameList里面。
    

根据需求,用户名和手机号关键字都可能存在满足条件的情况,所以我们在一次遍历phoneList的情况下分别判断: (假设ResultList已经初始化,这里不再做实例化)

    for(Phone aPhone:phoneList ){

         //电话号码中是否含有字串 “926”

        if(-1!=aPhone.getPhoneNo().indexOf(NumStr)){

              ResultList.add(aPhone);

     }

      //我们根据姓获取姓的拼音aDict,然后遍历   

   //这个表,同样用字串截取的办法来判别。

      String aDict=aPhone.getUserName().getDict(); 

      for(String indexName :inputNameList){

               If(-1!=aDict.indexOf(indexName )){

                    ResultList.add(aPhone);

               }

      }

}

这样,这个ResultList就找到了。

 


你可能感兴趣的:(笔试面试)