刚从北京归来,心态很好哈,然后想起看过一些人的面试经历,觉得自己也应该和大家分享一下哈,也顺便请大家帮我分析一下我遇到的特殊情况啦~
从笔试开始吧。大概是三四月份网投简历,然后是五一假期来的通知说5月6号去北大笔试吧,收到通知第一时间联系曾经去过百度的冬雪师姐求资料,结果一直没联系上,然后网上随便看了看一些杂碎的资料吧,笔试前两天下午师姐把整理好的资料发过来,然后第二天全部去打印出来,结果呢,傻了,厚厚一摞,一天时间怎么能看的完,好吧,这天下午就去了北京,寄宿在北邮的同学赛男那,晚上呢打了电玩,聊天聊到凌晨一两点,第二天7点多起来去了北大。
一拿到面试题,有点懵~~题目罗列在下面哈:
总体要求(请详细说明使用的数据结构和算法,不能给出程序的请写出伪代码)
第一题 简答题
1. 给你一个单词a,如果通过交换单词中的字母的顺序可以得到另外的单词b,那么定义b是a的兄弟单词。现在给你一个字典,用户输入一个单词,让你根据字典找给这个单词有多少兄弟单词。要求最小的时间复杂度和空间复杂度。
2. 进程和线程有什么区别,线程安全问题。
3.C和C++分别是怎么样分配和释放存储空间的,有什么区别?
第二题 算法与程序设计题
1. 网页爬虫在抓取网页时,从指定的URL站点入口开始爬取这个站点上的所有URL link,抓取到下一级link对应的页面后,同样对页面上的link进行抓取从而完成深度遍历。为简化问题,我们假设每个页面上至多只有一个link,当爬虫抓取到某个页面时,有可能再链回原来的网页,也有可能爬取到一个不带任何link的终极页面。当抓取到相同的URL或不包含任何link的终极页面时即完成爬取。爬虫在抓取到这些页面后建立一个单向链表,用来记录抓取到的页面,如:a.html->b.html->x.html...->NULL。问:对于爬虫分别从l两个入口开始获得两个单向链表,得到这两个单向链表后,如何判断他们是否抓取到了相同的URL?(假设页面URL上百亿,存储资源有限,无法用hash方法判断是否包含相同的URL)
请先描述相应的算法,再给出相应的代码实现。(只需给出判断方法代码,无需爬虫代码)
2.数组al[0,mid-1]和al[mid,num-1]是各自有序的,对数组al[0,num-1]的两个子有序段进行merge,得到al[0,num-1]整体有序。要求空间复杂度为O(1)。注:al[i]元素是支持'<'运算符的。
第三题 系统设计题
1、相信大家都使用过百度搜索框的suggestion功能,百度搜索框中的suggestion提示功能如何实现?请给出实现思路和主要的数据结构、算法。有什么优化思路可以使得时间和空间效率最高?
然后哈,第一题有思路,但是觉得要求太恶心,要最小的时间复杂度和最小的空间复杂度,这不矛盾么。想啊想啊想啊,各种方案,但是没有一个好的,一看时间半个小时过去了,赶紧下笔,把自己心里最初的程序哗哗哗的写上去了,还画了程序流程图.......还有十分钟结束的时候把程序和算法都写好了,答得还算可以吧。出来马上和小覃覃讨论,结果还不错,回天津以后也网上查了资料,算是基本答到点上了吧。和师兄说了一下情况,师兄建议先准备面试的,不然到时候来不及复习,可惜没有听他的话,帮一个小软件公司写程序赚外快去了,而且一天两天三天到四天过去一直没消息,以为自己早被刷了,结果第五天来短信通知说,5月13早上10点半来百度大厦参加面试。有点诧异呀,意外呀~~
然后星期六一天,临时抱佛脚,翻书,翻资料,大多是以前从没有接触过的海量数据处理算法和数据结构问题,还有一些关于百度公司的基本情况,详细了解了百度的竞价排名。然后,星期天早上6点起来坐火车去了百度。到的时候差不多快10点。B座大厅里各种人,都是等待面试的学生。师兄也凑热闹来霸面,临时教会了我昨天看的似懂非懂的海量数据处理问题,很nice!时间到了,开发测试的排队~~~哇塞,我又懵了,怎么这个职位这么多人啊,竞争好大啊,大多都是研二的。。。面试过程是一共三轮面试,一轮没有通过直接走人,通过进入下一轮。然后一面开始了,是在B座大厅左侧二楼,面试官是位年轻的GG,看着很和善。
一坐上,给面试官一个甜甜的微笑(开玩笑啦~哈哈哈),递上简历,然后GG很认真地看了一遍开始了:你对C和C++开发比较熟悉吧,来写个程序吧。好嘛~屁股都没坐热就写程序,来吧,不怕。题目是对两个有序的数组进行组合排序要求了空间复杂度和时间复杂度,然后不假思索的拿起笔哗哗哗的写下了,GG很满意。
然后问,对操作系统熟悉吗,linux还是Windows?我回,还行吧。然后他说,说说Linux内核吧,我回:文件管理、进程调度管理、进程间通信、网络管理和存储管理,blablabla~~~。GG点头,说对。然后,说说进程间通信的方法,我回信号啊,信号量啊,管道啊,共享内存啊,消息队列啊;然后他说那信号和信号量有什么区别,我回,信号是一个整型数,不同的信号代表不同的控制命令吧,信号量需要由PV操作...blablabla的,GG听了又满意的点点头。
接下来GG又问了我是什么专业的,做了什么项目,聊到了项目上,问我简历上哪个项目比较熟悉,我说都比较熟悉,然后介绍了一下自己的研究方向啊,什么黑客攻击啊,网络安全啊之类的,然后GG很详细的问了我项目的实现,在linux系统下的操作之类的,我就很详细的介绍了实现原理啊,什么lorcon库啊,pcap文件啊,packit库啊,还有Backtrack啊。然后GG问我有没有实现过多线程的程序开发,我说有,就是MFC的界面开发,CDC类绘图和Socket通信,GG针对我的回答深入问了几个问题,我都反应很快的答上了。
然后GG说了句基础不错,算法和数据结构还行吗?我说会点吧。然后他又给我纸和笔,让我把快排的算法写下来。嘿嘿~~很快写完给GG看,GG点点头。然后又聊到了我项目上的事,这次给GG介绍了一下WPA的四次握手过程,GG随即想到了TCP的握手过程,给我纸和笔让我画出TCP连接的三次握手和四次解手过程,又很轻松的画完给他,还给他讲解了一下,然后他看到我在四次解手上画了time_delay标记,就顺带问了time_delay的作用和所处的状态,我答保证了TCP连接断开的可靠性什么什么的啦,处于属于准备释放但有没有释放,别人不用占用的状态啦什么什么的,GG满意的笑笑。
接下来GG又问了数据库方面的东西,我说用过一些,会MySQL和ACCESS,懂JAVA WEB开发,struts, sping, hibenate等有都有了解。他又给我纸和笔,让我写了几句SQL言语,关于SUM和COUNT函数的,我的答案他还是很满意哈。然后GG很强调脚本编程,问了我两次会不会SHELL脚本,我说不怎么会,回问把很多shell命令放在一个XXX.sh脚本文件中然后调用这个脚本属于shell编程吗?他笑笑说应该算最最简单的形式吧。看到我的简历上有JSP,问我会不会javascript,我说这是WEB前端开发技术,我能看懂代码,并知道功能,但是让我写可能有点问题,因为没有系统的学javascript的语言规范,不过如果要实现的话,我会用Dreamwaver中的事件功能来自动生成相关的javascript代码,Dw用的很熟~~
然后他又问了我关于测试的背景,我说没有具体说过正规的测试,都是简单的DEBUG。他问了解多少,我回了一些黑盒白盒测试的东西,他点点头,给我出了一个开发性的设计题:比如说,让你去测试那个刷卡的门禁系统,你准备从哪些方面入手,把你的思路和方法告诉我。
想了十秒左右就开始答了,我的答案是从功能测试,性能测试和用户体验测试三个方面回答的。功能测试是用各种门禁支持的卡刷,看它能不能正常工作,再用各种不支持的东西去刷,看看它是不是Bug之类的.....性能测试吧,不停的刷,折磨它,看它能忍受到什么时候,用水浇,暴晒啊,看它有木有变得反应迟钝啊....然后用户体验方面,就是好不好看,耐不耐用之类的....(这里写的很随便哈,答的时候用词比较专业)GG对我的思路和方法都表示肯定。
然后就轮到我提问了,我问了百度实习培训的情况,还有如果通过面试的入职时间,GG很详细的解说了一下,然后第二个问题他说,入职时间要看你自己了,反正我这你是通过了。
一面,很顺利也很愉快~~~然后,二面在吃完午饭还没消化的时候就开始了,在B座大厅右侧的二楼。一位很严肃的姐姐(jj).姐姐一上来看我的简历,同样很仔细。看到我的专业就问我,你是通信专业的,为什么要选择百度这样的互联网公司?我说我们导师带的学生是通信和计算机双向的,所有学生都混在一起工作学习,接触的比较多,然后我好学啊什么之类的,自学了他们一部分的课程,兴趣比较浓。然后有很多师兄师姐都有百度经历吧,受他们影响来体验百度生活blablabla的得波了一会。
一看到linux就不肯放了,一直在问Linux系统的问题,整个面试其他的什么都没有了。其实linux不是我的强项,但是她问的问题我基本上都答上了,比如啊怎么用shell命令操作中的“怎么查找一个文件在那个文件夹里”,我答“fine 文件名”;“怎么查到一个文件中的关键字的所在位置”,我答“grep XXX”;“怎么删除文件,拷贝文件,挂载,查看开启中端口和进程,改变文件权限等等....”我全都答上了,唯一卡住的只有一个命令,就是她问怎么样让一个程序在后台运行,我当时想了一会,皱眉说记忆有点模糊,我再想想,然后她说没事准备下一个问题时,我突然说,我想起来了,用Ctrl+Z,可能是口音问题哈,她听成了Ctrl+C,她说那样程序就ShutDown了,然后我说,不是啦,我说的是Ctrl+Z,然后她反应过来说对,但这是程序运行后Ctrl+Z再转后台的,(你刚也没说运行前还运行后啊),然后我说哦,这样啊,我很好奇还有什么方法呀,没用过,她说在程序前加&就能一开启就转后台,这样就不用占用终端界面,你可以进行其他操作了。然后我很受教的样子说,明白了,我以前如果想要其他操作的话一般都是新打开一个终端的。她点点头,笑了。
然后设计一些测试的问题,她给拿百度搜索框的Suggestion功能做例,让我设计测试方案,然后我还是从功能,性能和界面三个方面作答,反应很快。她对我三个方面的划分方式表示赞同。
然后我详细介绍了每个方面的测试内容和方法:功能上主要是User输入关键词后,提示框能给出什么样的提示,提示内容和是否符合一般大多数用户的需求心理,用户输入错误时是否有智能纠错功能,纠错效果如何之类的,还有就是提示的速度能否达到要求。这里她打断我,深入问道,你怎么衡量输入有错啊,我答简单的说哈,比如你要搜天津XXXX,然后输入天津,他却弹出北京XXXX什么的,那肯定就不对了。然后她说了纠错方面的东西,比如当你要检索天津大学XXX的时候输成了天津大雪,那这时suggestion要怎么提示呢,是纠错还是照着天津大雪来提示呢?我说这个吧,可能user输的就是天津大雪,可以按照后者检索提示,但是如果一定要加纠错的话,方法有三:1.可以在suggestion功能中加入热点话题或新闻排名算法,一般用户如果真的要搜天津大雪的话大多是因为天津的确有一场很大很大的雪,或者是最近有下雪,所以一定有相关的新闻检索,可以进行排名,如果排名不理想可能是输错了,那么这时可以在搜索框中提示一半关于天津大雪的重大事件,然后其他提示天津大学的内容。2.等待用户输入的下一个关键词,然后可以根据后面的条件来判断是否纠错。3. 可以在用户自己输入完信息Enter后在输入框下提示“您是不是再找‘天津大学’”...jj对我的回答还算满意吧,说是个解决的办法然后补充和纠正了一下。然后她又问我为什么把速度定为功能范畴而不是性能范畴,我回答,用户一般都不愿意等待网络功能的延时吧,都希望反应越快越好,所以这个速度应该达到一个指标才能被用户接受,这个应该当做一个功能来实现的。而速度的稳定与否这个才属于性能范畴。她满意点头。
我继续介绍我的测试方案。性能方面,我说主要有速度稳定测试,搜索结果的稳定性测试还有......然后她又打断我说,那你怎么进行这个速度稳定测试呢,我反应很快,说:用户输入关键字后的suggestion反应速度在实际中受到三个方面的影响,客户端,网络信道和服务器。首先网络信道因素是不可测的,忙时网速明显受限,可能会有阻塞重传等无法排除的因素,所以要排除网络因素,测试时选择客户机和服务器直连。然后客户端影响速度的因素是因为客户端同时运行的应用程序过多,占用内存过大,所以只要保证客户端开启的必须的进程,关闭不相关的程序即可。这样测试环境搭建起来了。答到这里jj脸上有满意的笑容。然后我接着说,在suggestion反应速度达到功能标准的可以不用管,测试需要记录的是每次超出这个标准的时间长度和总次数,需要多次分时段的进行统计分析,而且是对关键词的遍历性检索(对搜索结果的稳定性当然是同一关键词了),比如可能分为早午晚三个时段,统计各自的时间长度和次数,当然次数越多,时间长度越长那就是越不稳定,性能越不好了。jj对我这种方法表示肯定,然后她问,为什么要分为早午晚呀,我说,打个比方说哈,早上刚起来,机器起运作刚开始,这个时候的情况肯定不一样;然后中午,运行了半天,我当做是热身吧;晚上呢,跑了一天了,肯定累了呀,然后我补充,当然服务器是一直都开着的,呵呵我只是打个比方。jj笑了,说你真有趣,把机器人性化了,其实机器一直是一个状态运行的,不用考虑那些。然后我接话,其实吧,我是这个意思,早上的机器因为午夜和凌晨访问量肯定少(假设服务器只被同一时区的用户访问哈,不考虑国外的用户),然后服务器大多数进程可能处于休眠状态,这样机器产热相对少;然后中午开始,访问量增加,机器开始活动,大多数进程唤醒且处于忙碌状态,一直不停的工作,这样服务器的产热必然上升,到晚上一直是忙碌状态,机器性能受到热量的影响还是很大的....jj听了说我分析的很有道理。
然后听我把这道题分析完,又回到了Linux操作系统上来,问除了基本的Linux命令还有什么其他的操作,我说gcc和make,会写简单的makefile文件。然后她问那个调试的用过吗,我问是gdb吗,她说对,我说用过一两次吧,但觉得出现bug的时候还是自己写printf输出来找bug的位置比较直观,然后她点头。
然后她问如果要你把远程主机上的一个文件弄到本地主机上来,你怎么做,要在linux系统下?我说,用U盘拷呗,也可以用ftp接收呀,也可以直接telnet登入啊,或是email回来行吧,她点点头问我还有没有其他方法,我说想不到了,给我点提示吧,她笑笑没理我~~
接下来又是一道很大的设计题:假如有海量的user使用程序模块接口A来检索需要的url,然后A要调用n个功能相同的B模块去访问海量数据的数据库,怎么实现这个系统来解决海量user问题和海量数据问题。
我低头想了一会,然后很快在纸上列出了提纲大致是海量用户和海量数据的针对性解决方案。海量用户吧,不同用户在大时间范围内应该是有并发和先后执行顺序的,在程序执行的小时间片上肯定是先后顺序的。我首先设计了一个消息队列来存放用户的query,(她听到信息队列,点头说对),然后肯定要多线程处理不同用户的请求(她点头),最好使用动态的线程优先级这样可以防止有些用户等的太久。她这时打断我,为什么要使用动态优先级?我说因为如果出现高优先级的线程卡死,而低优先级的线程必须等待高优先级的线程执行才能执行,这样会有死锁状态。她这时纠正我说线程不存在这样的问题,我顿了一下想了想,反应过来,说,哦,我把线程和进程同步的问题搞混了。
然后接着说,处理海量数据,可以将海量数据分布式处理,分别交由n个B模块来处理。这时她问怎么分布这些Url,平均或是聚集?我说数量上应该平均,最好是用hash映射一下。她说那你要A怎么调度B模块呢?一个一个还是n个同时运作。我说,一个网页一次能显示的url是有限的,n个B同时返回所有Url还要将没有被显示的存储在A的内存中,这样多个用户请求就要开辟多个存储多余Url的空间,对于海量User相当困难吧,所以我觉得应该一个一个调度,先用一个B的url来满足用户需求,就像去一个很多顾客的餐馆吃饭,总不能把一桌的餐全上齐了再给另一桌上菜吧,其他桌子可以先上一盘菜让等待的顾客填填肚子。当用户点击下一页的时候再调度下一个B的url。jj有说,那为了保持每次访问的稳定性,就是结果相同,如果遇到这种情况:第一个user查询一个关键词,从第一个B中获取了url,那这时如果第二个user也输入同一个关键字,为了保证结果相同,必须要调用相同的B模块吧,那么有多个用户呢?这样第一个B模块的负担会很重啊,这个问题怎么解决?我回答说,可以在A中构造一个cache,这样就可以由A模块自己解决同样的关键字搜索了,jj说是一种解决方案,还有没有其他的?我说能不能将B模块指向其他模块的的数据库啊,她说那样的结构会很复杂,不予采纳。然后我说难道要每个B都访问同样的海量url数据库?她没给肯定的回答,也没否定,说让我按这个思路往下走,如果B都访问相同的数据库,那就肯定能保证相同的结果了,那应该怎么由A调度B,我说对每个B设置一个状态指示参数就可以了,调用空闲状态的B。然后我自己补充道,如果然B去访问海量数据库的话,其实还可以让B自身做一个Cache这样就不用为每个query去海量搜索了,jj说这个方法也行,但是不觉得为每个B设置cache很浪费吗?我说那就开辟共享内存吧,每个B都可以读取这个cache中的信息,不过要考虑写入时的进程互斥性吧。jj说这个可以~~
jj肯定这个想法,但似乎总是对我的设计有些疑问似的,可能没有答到她的点上吧,然后对我的系统总结了一下说,功能和想法上是正确的,也有针对性,但是实际系统这样实现起来肯定有问题的,不过人都是这样的,要解决问题总是跟着第一思路走,然后第一思路遇到问题,想办法解决,然后系统都越来越复杂什么之类.....然后我说是啊,这只是初步想法,设计后肯定要优化的啊,然后她又补充了一下,问我如果实习的话能保证多长时间,我说6个月没问题(我觉得问我这个问题一般是意味着我已经过了吧)。然后她问我有什么要问的之类的,我问了上海百度和北京总部的职能区别之类的东西。
完了之后,她微笑着说让我等等,然后她拿了我的简历和面试表格走开了,我坐在那等了一段时间吧,挺长的时间了,过来一位工作人员,让我跟她走,我以为带我去见三面呢,没想到她带我到扶梯对我说你下去吧,然后我就乖乖的下来了。到一楼,大厅前台的人就走过来问我要走么,我说不知道啊,然后回头看到有两个姐姐也下来了,而且往外走,我也跟了过去,和她们一起出去以后我才知道她们是被刷的,“难道我被刷了?”一个姐姐问我,面试官给你表格了吗,我说木有,她不肯定的说不给的话就是被刷吧。我说我一面的面试官也没有给我表格啊,她说她就不知道了。然后我和她们边走边讨论起了面试的问题,那两位姐姐说各种不会,然后互问什么是socket编程,我接话blablabla,给她说了一堆,什么是堆排序,程序什么写,我又blabla一堆;然后又说了海量数据处理的典型问题,我教她们怎么用bit-map还有trie树之类的。完了她们盯着我说,“你确定你被刷了吗?”“我也很想知道啊。”“你回去问问吧,我觉得她是让你在下面等着。”“回去......都进地铁了.....我打电话问问师兄吧。”然后师兄说不知道,建议我回去问问,然后呢,我也懒得回去了,直接回津了~~~
话说心态很好哈,有人不知道自己怎么死的,我却连自己死没死都不知道,哈哈哈哈~~~~算了,才研一呢,好好呆着吧,回南方实习不就是为了他么,他现在都不在了,我回去也木有意义了。还是学校呆着吧,收获挺大的,起码知道了自己的知识基础和应答水平了吧,给自己定位才是最重要的,清楚自己的分量才能更好的提高自己呀~~是吧~~~