想找到一份程序员的工做,一点技术都没有显然是不行的,可是,只有技术 也是不够的。前端
面试笔试经验技巧篇主要针对程序员面试笔试中遇到的 13 个常见 问题进行深度解析,而且结合实际情景,给出了一个较为合理的参考答案以供读 者学习与应用,掌握这 13 个问题的解答精髓,对于求职者大有裨益。node
经验技巧 1 如何巧妙地回答面试官的问题?程序员
所谓“来者不善,善者不来”,程序员面试中,求职者不可避免地须要回答面试官各类 刁钻、犀利的问题,回答面试官的问题千万不能简单地回答“是”或者“不是”,而应该具 体分析“是”或者“不是”的理由。 回答面试官的问题是一门很深刻的学问。面试
那么,面对面试官提出的各种问题,如何才能 条理清晰地回答呢?如何才能让本身的回答不至于撞上枪口呢?如何才能让本身的回答结 果令面试官满意呢? 谈话是一种艺术,回答问题也是一种艺术,一样的话,不一样的回答方式,每每也会产生 出不一样的效果,甚至是大相径庭的效果。在此,编者提出如下几点建议,供读者参考。算法
首先 回答问题务必谦虚谨慎。既不能让面试官以为本身很自卑,惟惟诺诺,也不能让面试官以为 本身清高自负,而应该经过问题的回答表现出本身自信从容、不卑不亢的一面。数据库
例如,当面 试官提出“你在项目中起到了什么做用”的问题时,若是求职者回答:我完成了团队中最难 的工做,此时就会给面试官一种居功自傲的感受,而若是回答:我完成了文件系统的构建工 做,这个工做被认为是整个项目中最具备挑战性的一部份内容,由于它几乎没法重用之前的 框架,须要从新设计。这种回答不只不傲慢,反而有理有据,更能打动面试官。编程
其次,回答面试官的问题时,不要什么都说,要适当地留有悬念。人通常都有猎奇的心 理,面试官天然也不例外,并且,人们每每对好奇的事情更有兴趣、更加偏心,也更加记忆 深入。因此,在回答面试官问题时,切记说关键点而非细节,说重点而非和盘托出,经过关 键点,吸引面试官的注意力,等待他们继续“刨根问底”。例如,当面试官对你的简历中一 个算法问题有兴趣,但愿了解时,能够以下回答:我设计的这种查找算法,对于 80%以上的 状况,均可以将时间复杂度从 O(n)下降到 O(log n),若是您有兴趣,我能够详细给您分析具 体的细节。后端
最后,回答问题要条理清晰、简单明了,最好使用“三段式”方式。所谓“三段式”, 有点相似于中学做文中的写做风格,包括“场景/任务”“行动”和“结果”三部份内容。 以面试官提的问题“你在团队建设中,遇到的最大挑战是什么”为例,设计模式
第一步,分析场景 /任务:在我参与的一个 ERP 项目中,咱们团队一共四我的,除了我之外的其余三我的中, 两我的能力很给力,人也比较好相处,但有一我的却不太好相处,每次咱们小组讨论问题 的时候,他都不太爱说话,也不多发言,分配给他的任务也很难完成。数组
第二步,分析行动: 为了提升团队的综合实力,我决定找个时间和他好好单独谈一谈。因而我利用周末时间, 约他一块儿吃饭,吃饭的时候,顺便讨论了一下咱们的项目,我询问了一些项目中他遇到的 问题,经过他的回答,我发现他并不懒,也不糊涂,只是对项目不太了解,缺少经验,缺 乏自信而已,因此愈来愈孤立,愈来愈不肯意讨论问题。为了解决这个问题,我尝试着把 问题细化到他能够完成的程度,从而创建起他的自信心。
第三步,分析结果:他是小组中 水平最弱的人,可是,慢慢地,他的技术变得愈来愈厉害了,也可以按时完成安排给他的 工做了,人也愈来愈自信了,也愈来愈喜欢参与咱们的讨论,并发表本身的见解,咱们也 都愿意与他一块儿合做了。“三段式”回答的一个最明显的好处就是条理清晰,既有描述,也 有结果,有根有据,让面试官一目了然。 回答问题的技巧,是一门大的学问。求职者彻底能够在平时的生活中加以练习,提升自 己与人沟通的技能,等到面试时,天然就驾轻就熟了。
经验技巧 2 如何回答技术性的问题?
程序员面试中,面试官会常常询问一些技术性的问题,有的问题可能比较简单,都是历 年的笔试面试真题,求职者在平时的复习中会常常遇到,应对天然不在话下。但有的题目可 能比较难,来源于 Google、Microsoft 等大企业的题库或是企业本身为了招聘须要设计的题 库,求职者可能历来没见过或者历来都不能完整地、独立地想到解决方案,而这些题目每每 又是企业比较关注的。 如何可以回答好这些技术性的问题呢?编者建议:会作的必定要拿满分,不会作的必定 要拿部分分。即对于简单的题目,求职者要努力作到彻底正确,毕竟这些题目,只要复习得 当,彻底回答正确一点问题都没有(编者认识的一个朋友听说把《编程之美》、《编程珠玑》、 《程序员面试笔试宝典》上面的技术性题目与答案全都背得倒背如流了,后来找工做简直成 了“offer 杀器”,彻底就是一个 Bug,无解了);对于难度比较大的题目,不要惊慌,也不要 惧怕,即便没法彻底作出来,也要努力思考问题,哪怕是半成品也要写出来,至少要把本身 的思路表达给面试官,让面试官知道你的想法,而不是彻底回答不会或者放弃,由于面试官 不少时候除了关注你的独立思考问题的能力之外,还会关注你技术能力的可塑性,观察求职 者是否可以在别人的引导下去正确地解决问题,因此,对于你不会的问题,他们颇有可能会 按部就班地启发你去思考,经过这个过程,让他们更加了解你。 通常而言,在回答技术性问题时,求职者大可没必要胆战心惊,除非是没学过的新知识, 不然,通常均可以采用如下六个步骤来分析解决。
(1)敢于提问 面试官提出的问题,有时候可能过于抽象,让求职者不知所措,或者无从下手,因此, 对于面试中的疑惑,求职者要勇敢地提出来,多向面试官提问,把不明确或二义性的状况都 问清楚。不用担忧你的问题会让面试官烦恼,影响你的面试成绩,相反还对面试结果产生积 极影响:一方面,提问可让面试官知道你在思考,也能够给面试官一个心思缜密的好印象; 另外一方面,方便后续本身对问题的解答。 例如,面试官提出一个问题:设计一个高效的排序算法。求职者可能丈二和尚摸不到头 脑,排序对象是链表仍是数组?数据类型是整型、浮点型、字符型仍是结构体类型?数据基 本有序仍是杂乱无序?数据量有多大,1000 之内仍是百万以上个数?此时,求职者大能够 将本身的疑问提出来,问题清楚了,解决方案也天然就出来了。
(2)高效设计 对于技术性问题,如何才能打动面试官?完成基本功能是必须的,仅此而已吗?显然不 是,完成基本功能顶多只能算及格水平,要想达到优秀水平,至少还应该考虑更多的内容, 以排序算法为例:时间是否高效?空间是否高效?数据量不大时也许没有问题,若是是海量 数据呢?是否考虑了相关环节,例如数据的“增删改查”?是否考虑了代码的可扩展性、安 全性、完整性以及鲁棒性?若是是网站设计,是否考虑了大规模数据访问的状况?是否须要 考虑分布式系统架构?是否考虑了开源框架的使用?
(3)伪代码先行 有时候实际代码会比较复杂,上手就写颇有可能会漏洞百出、条理混乱,因此,求职者 能够首先征求面试官的赞成,在编写实际代码前,写一个伪代码或者画好流程图,这样作往 往会让思路更加清晰明了。 切记在写伪代码前要告诉面试官,他们颇有可能对你产生误解,认为你只会纸上谈兵, 实际编码能力却不行。只有征得了他们的容许,方可先写伪代码。
(4)控制节奏 若是是算法设计题,面试官都会给求职者一个时间限制用以完成设计,通常为 20min 左 右。完成得太慢,会给面试官留下能力不行的印象,但完成得太快,若是不能保证百分百正 确,也会给面试官留下毛手毛脚的印象,速度快固然是好事情,但只有速度,没有质量,速 度快根本不会给面试加分。因此,编者建议,回答问题的节奏最好不要太慢,也不要太快, 若是实在是完成得比较快,也不要急于提交给面试官,最好可以利用剩余的时间,认真仔细 地检查一些边界状况、异常状况及极性状况等,看是否也能知足要求。 (5)规范编码 回答技术性问题时,多数都是纸上写代码,离开了编译器的帮助,求职者要想让面试官 对本身的代码一看即懂,除了字迹要工整,不能眉飞色舞之外,最好是可以严格遵循编码规 范:函数变量命名、换行缩进、语句嵌套和代码布局等,同时,代码设计应该具备完整性, 保证代码可以完成基本功能、输入边界值可以获得正确地输出、对各类不合规范的非法输入 可以作出合理的错误处理,不然,写出的代码即便无比高效,面试官也不必定看得懂或者看 起来很是费劲,这些对面试成功都是很是不利的。
(6)精心测试 在软件界,有一句真理:任何软件都有 bug。但不能由于如此就纵容本身的代码, 容许错误百出。尤为是在面试过程当中,实现功能也许并不十分困难,困难的是在有限的 时间内设计出的算法,各类异常是否都获得了有效的处理,各类边界值是否都在算法设 计的范围内。 测试代码是让代码变得完备的高效方式之一,也是一名优秀程序员必备的素质之一。所 以,在编写代码前,求职者最好可以了解一些基本的测试知识,作 一些基本的单元测试、功 能测试、边界测试以及异常测试。 在回答技术性问题时,注意在思考问题的时候,千万别一句话都不说,面试官面试 的时间是有限的,他们但愿在有限的时间内尽量地去了解求职者,若是求职者坐在那 里一句话不说,不只会让面试官以为求职者技术水平不行,思考问题能力以及沟通能力 可能都存在问题。 其实,在面试时,求职者每每会存在一种思想误区,把技术性面试的结果看得过重要了。 面试过程当中的技术性问题,结果当然重要,但也并不是最重要的内容,由于面试官看重的不只 仅是最终的结果,还包括求职者在解决问题的过程当中体现出来的逻辑思惟能力以及分析问题 的能力。因此,求职者在与面试官的博弈中,要适当地提问,经过提问获取面试官的反馈信 息,并抓住这些有用的信息进行辅助思考,从而博得面试官的欢心,进而提升面试的成功率。
经验技巧 3 如何回答非技术性问题?
评价一我的的能力,除了专业能力,还有一些非专业能力,如智力、沟通能力和反应能 力等,因此在 IT 企业招聘过程的笔试面试环节中,并不是全部的笔试内容都是 C/C++、数据 结构与算法及操做系统等专业知识,也包括其余一些非技术类的知识,如智力题、推理题和 做文题等。技术水平测试能够考查一个求职者的专业素养,而非技术类测试则更增强调求职 者的综合素质,包括数学分析能力、反应能力、临场应变能力、思惟灵活性、文字表达能力 和性格特征等内容。考查的形式多种多样,但与公务员考查类似,主要包括行测(占大多数)、 性格测试(大部分都有)、应用文和开放问题等内容。 每一个人都有本身的答题技巧,答题方式也各不相同,如下是一些相对比较好的答题技巧 (以行测为例):
1)合理有效的时间管理。因为题目的难易不一样,因此不要对全部题目都“绝对的公 平”、都“一刀切”,要有轻重缓急,最好的作法是不按顺序回答。行测中有各类题型,
如数量关系、图形推理、应用题、资料分析和文字逻辑等,而不一样的人擅长的题型是不 同样的,所以应该首先回答本身最擅长的问题。例如,若是对数字比较敏感,那么就先 答数量关系。
2)注意时间的把握。因为题量通常都比较大,能够先按照总时间/题数来计算每道题的 平均答题时间,如 10s,若是看到某一道题 5s 后还没思路,则立刻放弃。在作行测题目的时 候,以在最短的时间内拿到最多分为目标。
3)平时多关注图表类题目,培养迅速抓住图表中各个数字要素间相互逻辑关系的能力。
4)作题要集中精力,只有集中精力、全神贯注,才能将本身的水平最大限度地发挥 出来。
5)学会关键字查找,经过关键字查找,可以提升作题效率。
6)提升估算能力,有不少时候,估算可以极大地提升作题速度,同时保证正确率。 除了行测之外,一些企业很是相信我的性格对入职匹配的影响,因此都会引入相关的性 格测试题用于测试求职者的性格特性,看其是否适合所投递的职位。大多数状况下,只要按 照本身的真实想法选择就好了,不要弄巧成拙,由于测试是为了得出正确的结果,因此大多 测试题先后都有相互验证的题目。若是求职者自做聪明,选择该职位可能要求的性格选项,则 极可能致使测试先后不符,这样很容易让企业发现你是个不诚实的人,从而首先予以筛除。
经验技巧 4 如何回答快速估算类问题?
有些大企业的面试官,总喜欢使一些“阴招”“损招”,出一些快速估算类问题,对他们 而言,这些问题只是手段,不是目的,可以获得一个满意的结果当然是他们所须要的,但更 重要的是经过这些题目他们能够考查求职者的快速反应能力以及逻辑思惟能力。因为求职者 平时准备的时候可能对此类问题有所遗漏,一时很难想起解决的方案。
并且,这些题目乍一 看确实是毫无头绪,无从下手,彻底就是坑求职者的,其实求职者只要从惶恐不安中冷静下 来,稍加分析,也就那么回事。由于此类题目比较灵活,属于开放性试题,通常没有标准答 案,只要弄清楚了回答要点,分析合理到位,具备说服力,可以自圆其说,就是正确答案, 一点都不困难。
例如,面试官可能会问这样一个问题:“请你估算一下一家商场在促销时一天的营业 额?”,求职者又不是统计局官员,如何可以得出一个准确的数据呢?求职者家又不是开商 场的,如何可以得出一个准确的数据呢?即便求职者是商场的大当家,也不可能弄得清清楚 楚明明白白吧? 难道此题就无解了吗?其实否则,本题只要可以分析出一个概数就好了,不必定要精确 数据,而分析概数的前提就是作出各类假设。
以该问题为例,能够尝试从如下思路入手:从 商场规模、商铺规模入手,经过每平方米的租金,估算出商场的日租金,再根据商铺的成本 构成,获得全商场日均交易额,再考虑促销时的销售额与平时销售额的倍数关系,乘以倍数, 便可获得促销时一天的营业额。具体而言,包括如下估计数值:
1)以一家较大规模商场为例,商场通常按 6 层计算,每层大约长 100m,宽 100m,合 计 60000m2的面积。
2)商铺规模占商场规模的一半左右,合计 30000m2。
3)商铺租金约为 40 元/ m2,估算出年租金为 40×30000×365=4.38 亿。
4)对商户而言,租金通常占销售额 20%左右,则年销售额为 4.38 亿×5=21.9 亿。计算 平均日销售额为 21.9 亿/365=600 万。
5)促销时的日销售额通常是平时的 10 倍,因此大约为 600 万*10=6000 万。
此类题目涉及面比较广,例如:估算一下北京小吃店的数量?估算一下中国在过去一年方便面的市场销售额是多少?估算一下长江的水的质量?估算一下一个行进在小雨中的人 5min 内身上淋到的雨的质量?估算一下东方明珠电视塔的质量?估算一下中国去年一年一 共用掉了多少块尿布?估算一下杭州的轮胎数量?但通常都是即兴发挥,不是哪道题记住答 案就能够应付得了的。遇到此类问题,一步步抽丝剥茧,才是解决之道。
经验技巧 5 如何回答算法设计问题?
程序员面试中的不少算法设计问题,都是历年来各家企业的“炒现饭”,无论求职者以 前对算法知识学习得是否扎实,理解得是否深刻,只要面试前买本《程序员面试笔试宝典》 (编者早前编写的一本书,由机械工业出版社出版),学习上一段时间,牢记于心,应付此类 题目彻底没有问题,但遗憾的是,不少世界级知名企业也深知这一点,若是纯粹是出一些毫 无技术含量的题目,对于考前“突击手”而言,可能会占尽便宜,但对于那些技术好的人而 言是很是不公平的。因此,为了把优秀的求职者与通常的求职者可以更好地区分开来,他们 会年年推陈出新,愈来愈倾向于出一些有技术含量的“新”题,这些题目以及答案,再也不是 之前的陈谷子烂芝麻了,而是通过精心设计的好题。
在程序员面试中,算法的地位就如同是 GRE 或托福考试在出国留学中的地位同样,必 须但不是最重要的,它只是众多考核方面中的一个而已,不必定就能决定求职者的生死。虽 然如此,但并不是说就不用去准备算法知识了,由于算法知识回答得好,必然会成为面试的加 分项,对于求职成功,百利而无一害。那么如何应对此类题目呢?很显然,编者不可能将此 类题目都在《程序员面试笔试宝典》中一一解答,一来因为内容众多,篇幅有限,二来也没 必要,今年考过了,之后通常就不会再考了,否则仍是没有区分度。编者觉得,靠死记硬背 确定是行不通的,解答此类算法设计问题,须要求职者具备扎实的基本功以及良好的运用能 力,编者没法左右求职者的我的基本功以及运用能力,由于这些能力须要求职者“十年磨一 剑”地苦学,但编者能够提供一些比较好的答题方法和解题思路,以供求职者在面试时应对 此类算法设计问题。“授之以鱼不如授之以渔”,岂不是更好?
(1)概括法 此方法经过写出问题的一些特定的例子,分析总结其中通常的规律。具体而言就是经过 列举少许的特殊状况,通过分析,最后找出通常的关系。例如,某人有一对兔子饲养在围墙 中,若是它们每月生一对兔子,且新生的兔子在第二个月后也是每月生一对兔子,问一 年后围墙中共有多少对兔子。 使用概括法解答此题,首先想到的就是第一个月有多少对兔子,第一个月的时候,最初 的一对兔子生下一对兔子,此时围墙内共有两对兔子。第二个月还是最初的一对兔子生下一 对兔子,共有 3 对兔子。到第三个月除最初的兔子新生一对兔子外,第一个月生的兔子也开 始生兔子,所以共有 5 对兔子。经过举例,能够看出,从第二个月开始,每个月兔子总数 都是前两个月兔子总数之和,Un+1=Un+Un1,一年后,围墙中的兔子总数为 377 对。 此种方法比较抽象,也不可能对全部的状况进行列举,因此,得出的结论只是一种猜想, 还须要进行证实。
(2)类似法 正如编者“年年岁岁花类似,岁岁年年仍单身”同样,此方法考虑解决问题的算法是相 似的。若是面试官提出的问题与求职者之前用某个算法解决过的问题类似,此时此刻就能够 举一反三,尝试改进原有算法来解决这个新问题。而一般状况下,此种方法都会比较奏效。
例如,实现字符串的逆序打印,也许求职者历来就没遇到过此问题,但将字符串逆序确定 在求职准备的过程当中是见过的。将字符串逆序的算法稍加处理,便可实现字符串的逆序打印。
(3)简化法
此方法首先将问题简单化,例如改变一下数据类型、空间大小等,而后尝试着将简化后 的问题解决,一旦有了一个算法或者思路能够解决这个被“阉割过”的问题,再将问题还原, 尝试着用此类方法解决原有问题。 例如,在海量日志数据中提取出某日访问 xxx 网站次数最多的那个 IP。很显然,因为 数据量巨大,直接进行排序不可行,但若是数据规模不大时,采用直接排序不失为一种好的 解决方法。那么如何将问题规模缩小呢?因而想到了Hash法,Hash每每能够缩小问题规模, 而后在“阉割过”的数据里面使用常规排序算法便可找出此问题的答案。
(4)递归法 为了下降问题的复杂度,不少时候都会将问题逐层分解,最后归结为一些最简单的问题, 这就是递归。此种方法,首先要可以解决最基本的状况,而后以此为基础,解决接下来的问题。 例如,在寻求全排列的时候,可能会感受无从下手,但仔细推敲,会发现后一种排列组 合每每是在前一种排列组合的基础上进行的从新排列,只要知道了前一种排列组合的各种组 合状况,只需将最后一个元素插入到前面各类组合的排列里面,就实现了目标:即先截去字 符串 s[1…n]中的最后一个字母,生成全部 s[1…n1]的全排列,而后再将最后一个字母插入 到每个可插入的位置。
(5)分治法 任何一个能够用计算机求解的问题所需的计算时间都与其规模有关。问题的规模越小, 越容易直接求解,解题所需的计算时间也越少。而分治法正是充分考虑到这一内容,将一个 难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。分治 法通常包含如下三个步骤:
1)将问题的实例划分为几个较小的实例,最好具备相等的规模。
2)对这些较小的实例求解,而最多见的方法通常是递归。
3)若是有必要,合并这些较小问题的解,以获得原始问题的解。 分治法是程序员面试常考的算法之一,通常适用于二分查找、大整数相乘、求最大子数 组和、找出伪币、金块问题、矩阵乘法、残缺棋盘、归并排序、快速排序、距离最近的点对、 导线与开关等。
(6)Hash 法 不少面试笔试题目,都要求求职者给出的算法尽量高效。什么样的算法是高效的?一 般而言,时间复杂度越低的算法越高效。而要想达到时间复杂度的高效,不少时候就必须在 空间上有所牺牲,用空间来换时间。而用空间换时间最有效的方式就是 Hash 法、大数组和 位图法。固然,此类方法并不是包治百病,有时,面试官也会对空间大小进行限制,那么此时, 求职者只能再去思考其余的方法了。 其实,凡是涉及大规模数据处理的算法设计中,Hash 法就是最好的方法之一。
(7)轮询法 在设计每道面试笔试题时,每每会有一个载体,这个载体即是数据结构,例如数组、链 表、二叉树或图等,当载体肯定后,可用的算法天然而然地就会暴露出来。可问题是不少时 候并不肯定这个载体是什么。当没法肯定这个载体时,通常也就很难想到合适的方法了。 编者建议,此时,求职者能够采用最原始的思考问题的方法——轮询法,在脑海中轮询 各类可能的数据结构与算法,常考的数据结构与算法一共就那么几种(见表 1),即便不完 全同样,也是由此衍生出来的或者类似的,总有一款适合考题的。
表 1 最常考的数据结构与算法知识点
数 据 结 构 算 法 概 念
链表 广度(深度)优先搜索 位操做
数组 递归 设计模式
二叉树 二分查找 内存管理(堆、栈等)
树 排序(归并排序、快速排序等)
堆(大顶堆、小顶堆) 树的插入/删除/查找/遍历等
栈 图论
队列 Hash 法
向量 分治法
Hash 表 动态规划
此种方法看似笨拙,其实实用,只要求职者对常见的数据结构与算法烂熟于心,一点都 没有问题。 为了更好地理解这些方法,求职者能够在平时的准备过程当中,应用此类方法去答题,作 得多了,天然对各类方法也就熟能生巧了,面试的时候,再遇到此类问题,也就可以收放自 如了。固然,千万不要相信有着张无忌般的运气,可以在一晚上之间练成乾坤大挪移这一绝世 神功,称霸武林,算法设计功力的练就是平时一点一滴的付出和思惟的磨练。方法与技巧也 许只是给面试打了一针“鸡血”、喂一口“大补丸”,不会让本身变得从容自信,真正的功力 仍是须要一个长期的积累过程的。
经验技巧 6 如何回答系统设计题?
应届生在面试的时候,偶尔也会遇到一些系统设计题,而这些题目每每只是测试一下求 职者的知识面,或者测试求职者对系统架构方面的了解,通常不会涉及具体的编码工做。虽 然如此,对于此类问题,不少人仍是感受难以应对,也不知道从何提及。
如何应对此类题目呢?在正式介绍基础知识以前,首先罗列几个常见的系统设计相关的 面试笔试题,以下所示:
1)设计一个 DNS 的 Cache 结构,要求可以知足每秒 5000 次以上的查询,知足 IP 数据 的快速插入,查询的速度要快(题目还给出了一系列的数据,好比站点数总共为 5000 万、 IP 地址有 1000 万等)。
2)有 N 台机器,M 个文件,文件能够以任意方式存放到任意机器上,文件可任意分割 成若干块。假设这 N 台机器的宕机率小于 1/3,想在宕机时能够从其余未宕机的机器中完整 导出这 M 个文件,求最好的存放与分割策略。
3)假设有三十台服务器,每台服务器上面都存有上百亿条数据(有可能重复),如何找出这 三十台机器中,根据某关键字,重复出现次数最多的前100条?要求使用Hadoop来实现。
4)设计一个系统,要求写速度尽量快,并说明设计原理。
5)设计一个高并发系统,说明架构和关键技术要点。
6)有 25T 的 log(query->queryinfo),log 在不断地增加,设计一个方案,给出一个 query 能快速返回 queryinfo。 以上全部问题中凡是不涉及高并发的,基本能够采用 Google 的三个技术解决,即 GFS、 MapReduce 和 Bigtable,这三个技术被称为“Google 三驾马车”,Google 只公开了论文而未 开源代码,开源界对此很是有兴趣,仿照这三篇论文实现了一系列软件,如 Hadoop、HBase、 HDFS 及 Cassandra 等。 在 Google 这些技术还未出现以前,企业界在设计大规模分布式系统时,采用的架构往 往是 database+sharding+cache,如今不少公司(好比 taobao、weibo.com)仍采用这种架构。 在这种架构中,仍有不少问题值得去探讨。如采用什么数据库,是 SQL 界的 MySQL 仍是 NoSQL 界的 Redis/TFS,二者有何优劣?采用什么方式 sharding(数据分片),是水平 分片仍是垂直分片?据网上资料显示,weibo.com 和 taobao 图片存储中曾采用的架构是 Redis/MySQL/TFS+sharding+cache,该架构解释以下:前端 cache 是为了提升响应速度,后 端数据库则用于数据永久存储,防止数据丢失,而 sharding 是为了在多台机器间分摊负载。 最前端由大块大块的 cache 组成,要保证至少 99%(该数据在 weibo.com 架构中的是本身猜 的,而 taobao 图片存储模块是真实的)的访问数据落在 cache 中,这样能够保证用户访问速 度,减小后端数据库的压力。此外,为了保证前端 cache 中的数据与后端数据库中的数据一 致,须要有一个中间件异步更新(为何使用异步?理由简单:同步代价过高。异步有缺点, 如何弥补?)数据,这个有些人可能比较清楚,新浪有个开源软件叫 Memcachedb(整合 了 Berkeley DB 和 Memcached),正是完成此功能。另外,为了分摊负载压力和海量数据, 会将用户微博信息通过分片后存放到不一样节点上(称为“Sharding”)。
这种架构优势很是明显:简单,在数据量和用户量较小的时候彻底能够胜任。但缺点是 扩展性和容错性太差,维护成本很是高,尤为是数据量和用户量暴增以后,系统不能经过简 单地增长机器解决该问题。 鉴于此,新的架构应运而生。新的架构仍然采用 Google 公司的架构模式与设计思想, 如下将分别就此内容进行分析。
GFS 是一个可扩展的分布式文件系统,用于大型的、分布式的、对大量数据进行访问的 应用。它运行于廉价的普通硬件上,提供容错功能。如今开源界有 HDFS(Hadoop Distributed File System),该文件系统虽然弥补了数据库+sharding 的不少缺点,但自身仍存在一些问题,
好比:因为采用 master/slave 架构,所以存在单点故障问题;元数据信息所有存放在 master 端的内存中,于是不适合存储小文件,或者说若是存储大量小文件,那么存储的总数据量不 会太大。 MapReduce 是针对分布式并行计算的一套编程模型。其最大的优势是:编程接口简单, 自动备份(数据默认状况下会自动备三份),自动容错和隐藏跨机器间的通讯。在Hadoop中, MapReduce 做为分布计算框架,而 HDFS 做为底层的分布式存储系统,但 MapReduce 不是 与HDFS耦合在一块儿的,彻底能够使用本身的分布式文件系统替换掉HDFS。当前MapReduce 有不少开源实现,如 Java 实现 Hadoop MapReduce,C++实现 Sector/sphere 等,甚至有些数 据库厂商将 MapReduce 集成到数据库中了。
BigTable 俗称“大表”,是用来存储结构化数据的,编者以为,BigTable 在开源界最火 爆,其开源实现最多,包括 HBase、Cassandra 和 levelDB 等,使用也很是普遍。 除了 Google 的这“三驾马车”之外,还有其余一些技术可供学习与使用: Dynamo:亚马逊的 key-value 模式的存储平台,可用性和扩展性都很好,采用 DHT (Distributed Hash Table)对数据分片,解决单点故障问题,在 Cassandra 中,也借鉴了该技 术,在 BT 和电驴这两种下载引擎中,也采用了相似算法。 虚拟节点技术:该技术经常使用于分布式数据分片中。具体应用场景是:有一大块数据(可 能 TB 级或者 PB 级),需按照某个字段(key)分片存储到几十(或者更多)台机器上,同时 想尽可能负载均衡且容易扩展。传统的作法是:Hash(key) mod N,这种方法最大的缺点是不容易 扩展,即增长或者减小机器均会致使数据所有重分布,代价太大。因而新技术诞生了,其中一 种是上面提到的 DHT,如今已经被不少大型系统采用,还有一种是对“Hash(key) mod N”的 改进:假设要将数据分布到 20 台机器上,传统作法是Hash(key) mod 20,而改进后,N 取值要 远大于 20,好比是20000000,而后采用额外一张表记录每一个节点存储的 key的模值,好比: node1:0~1000000 node2:1000001~2000000 …
这样,当添加一个新的节点时,只需将每一个节点上部分数据移动给新节点,同时修改一 下该表便可。 Thrift:Thrift 是一个跨语言的 RPC 框架,分别解释“RPC”和“跨语言”以下:RPC 是远程过程调用,其使用方式与调用一个普通函数同样,但执行体发生在远程机器上;跨语 言是指不一样语言之间进行通讯,好比 C/S 架构中,Server 端采用 C++编写,Client 端采用 PHP 编写,怎样让二者之间通讯,Thrift 是一种很好的方式。 本篇最前面的几道题都可以映射到以上几个系统的某个模块中,如:
1)关于高并发系统设计,主要有如下几个关键技术点:缓存、索引、数据分片及锁粒 度尽量小。
2)题目 2 涉及如今通用的分布式文件系统的副本存放策略。通常是将大文件切分红小 的 block(如 64MB)后,以 block 为单位存放三份到不一样的节点上,这三份数据的位置需根 据网络拓扑结构配置,通常而言,若是不考虑跨数据中心,能够这样存放:两个副本存放在 同一个机架的不一样节点上,而另一个副本存放在另外一个机架上,这样从效率和可靠性上, 都是最优的(这个 Google 公布的文档中有专门的证实,有兴趣的可参阅一下)。若是考虑跨 数据中心,可将两份存在一个数据中心的不一样机架上,另外一份放到另外一个数据中心。
3)题目 4 涉及 BigTable 的模型。主要思想是将随机写转化为顺序写,进而大大提升写 速度。具体是:因为磁盘物理结构的独特设计,其并发的随机写(主要是由于磁盘寻道时间 长)很是慢,考虑到这一点,在 BigTable 模型中,首先会将并发写的大批数据放到一个内存 表(称为“memtable”)中,当该表大到必定程度后,会顺序写到一个磁盘表(称为“SSTable”) 中,这种写是顺序写,效率极高。此时可能有读者问,随机读可不能够这样优化?答案是: 看状况。一般而言,若是读并发度不高,则不能够这么作,由于若是将多个读从新排列组合 后再执行,系统的响应时间太慢,用户可能接受不了,而若是读并发度极高,也许能够采用 相似机制。
经验技巧 7 如何解决求职中的时间冲突问题?
对于求职者而言,求职季就是一个赶场季,一天少则几家、十几家企业入校招聘,多则 几十家、上百家企业招兵买马,企业多,选择项天然也多,这当然是一件好事情,但因为招 聘企业实在是太多,天然而然会致使另一个问题的发生:同一天企业扎堆,且都是本身心 仪或欣赏的大牛企业的现象。若是不可以提早掌握企业的宣讲时间、地点,是很容易迟到或 错过的。但有时候即便掌握了宣讲时间、笔试和面试时间,仍是有可能错过,为何呢?时 间冲突,人不可能具备分身术,也不可能同一时间作两件不一样的事情,因此,不少时候就必 须有所取舍了。 到底该如何取舍呢?该如何应对这种时间冲突的问题呢?在此,编者将本身的一些想法 和经验分享出来,以供读者参考:
1)若是多家心仪企业的校园宣讲时间发生冲突(前提是只宣讲,不笔试,不然请看后面 的建议),此时最好的解决方法是和同窗或朋友商量好,各去一家,而后你们进行信息共享。
2)若是多家心仪企业的笔试时间发生冲突,此时只能选择其一,毕竟企业的笔试时间 都是考虑到了成百上千人的安排,须要提早安排考场、考务人员和阅卷人员等,不可能为了 某一我的而轻易改变。因此,最好选择本身更有兴趣的企业参加笔试。
3)若是多家心仪企业的面试时间发生冲突,不要轻易放弃。对于面试官而言,面试任 何人都是同样的,由于面试官谁都不认识,而面试时间也是灵活性比较大的,通常能够经过 电话协商。求职者能够与相关工做人员(通常是企业的 HR)进行沟通,以某种理由(例如学 校的事宜、导师的事宜或家庭的事宜等,前提是必须可以说服人,不要给出的理由连本身都说服不了)让其调整时间,通常都能协调下来。但为了保证协调的成功率,通常要接到面试通知 后第一时间联系相关工做人员变动时间,这样他们协调起来也更方便。
正如世界上没有可以包治百病的药物同样,以上这些建议在应用时,不少状况下也作不 到全盘兼顾,当必须进行多选一的时候,求职者就要对此进行评估了,评估的项目能够包括: 对企业的中意程度、得到 offer 的几率及去工做的可能性等。评估的结果每每具备很强的参 考性,求职者依据评估结果作出的选择通常也会比较合理。