程序员面试一直是社区乐于讨论的热门话题。
这篇文章, 是站在面试官的角度, 针对程序员面试问题, 进行的一个阶段性反思, 以及经验总结。
【目标】
想必和好些朋友相同, 在拥有了几年工作经验成为Senior后便开展了面试他人的历程。作者于最初这个时期仅仅依照自身的想象, 将“寻觅基础良好的程序员”, “寻觅算法能力出色的程序员”, “寻觅具备Android开发经验的程序员”等当作面试的目标。然而, 实际的经历告知作者, 特别是按“基础好”, “算法好”这些目标招录的人最终成效并不理想。譬如, 存在这样的面试者, 其基础知识以及算法的掌握状况还好, 进程、线程、内存等相关概念明晰 , 基本的Hash 、二叉树、快速排序等数据结构与算法也较为熟悉 , 然而进入公司之后在实际工作里的表现却相当糟糕。之后 , 作者才发觉原来是作者自身的面试目标存在问题 , 作者先前的面试方法更仿若大学的算法抑或操作系统期末考试 , 依照这种方法致使诸多并不适宜的人通过了面试 , 同时也极有可能错失了诸多合适的人。
后来, 作者进行了反思, 从公司的角度论, 面试的根本目标是寻觅“能够将工作干得好”的人, 然而“具备高学历”, “算法表现良好”, “基础状况良好”, “拥有相关经验”这些均属于表象并非根本所在, 它们无法直接与“工作出色”画上等号。
【方法】
目标已然明确了, 然而后续的问题在于, 假定面试者是一个黑盒般的系统, “工作情形佳妙”并非能够直接进行观测的变量, 你所能够予以直接观测的变量涵盖基础、算法、经验、学历、性格、谈吐、年龄等等。因而, 实际上, 你仅仅能够凭借“基础状况良好”,“算法表现出色”等这种可以直接观测到的量, 去推断出“工作状况良好可靠”的概率,这便是一个处于“X方面良好”条件之下“工作方面良好”的条件概率相关问题: P(工作好 | X好)。
基于这个模型, 面试所应考察的方面就清晰可见了, 即挑选那种最具区分性的方面予以考察。比如说, 去考察面试者的体型特征没什么太大意义, 因为P(工作好|高)的概率、P(工作好|矮)的概率、P(工作好|胖)的概率、P(工作好|瘦)的概率都大致相同;故而, 体型特征不具备区分性, 这并非是面试所该关注的内容。
面试官需要依据职位的要求, 去明确哪些因素具备比较不错的区分性。比如说, 要是打算招聘一名技术门槛相对较高的3D游戏引擎开发工程师, 面试者A拥有3D游戏引擎开发的经验, 然而在基础知识以及算法面试方面的表现较为普通;面试者B则相反, 基础知识与算法面试表现出色, 可是却没有游戏开发经验, 而你仅仅能够选择其中一个。你会选谁呢? 实际上, 这就是两个条件概率问题, P(工作好|经验好, 基础一般, 算法一般)以及P(工作好|没经验, 基础好, 算法好)。这个问题交由面试官去判断, 从作者自身来讲, 针对技术门槛偏高且需技术积累的职位, 经验更能说明情况, 故而, 作者更偏向面试者A。
下面,作者再结合自己的经验谈谈对面试中常见方面的看法。
【算法】
算法是Google以及MS等高规格大公司面试时着重考察的要点, 作者个人对算法颇为喜爱, 曾参与ACM/ICPC并荣获北京赛区的第13名。然而, 依个人经验来讲, 就作者所接触到的绝大部分开发职位来说, 算法并不适宜作为评判面试者能力高低的关键要素。对于一般的非算法类开发职位, 考查面试者的算法就如同考查其乒乓球水平高低一般, 与“工作出色”这一目标的关联度极低。依照作者个人所拥有的经验而言, 大致上P(工作状况良好|算法表现出色)=50%, 这意味着算法方面的面试并不具备太大的区分特性。
甚至, 存在一种极为糟糕的情形, 大量地出现在算法表现出色的面试者身上, 作者将其称作“只磨刀, 不砍柴”。这是什么样的意思呢?有着这样一类人, 仅仅对诸如A*算法、异步编程、JVM类加载机制这类纯粹的技术问题怀有兴趣, 对于达成用户需求却全然没有兴趣。这类人看似具备一定的技术水平, 但对于公司而言, 其贡献非常有限, 甚至比不上技术普通却认真负责的人。所以, 一旦碰到算法出色的面试者, 作者就格外留意考察其是否属于这种“只磨刀, 不砍柴”的人。
另外, 作者个人对Google以及MS并不了解, 然而作者却对其格外着重考察算法能力的面试策略持有怀疑态度。即便处于这般世界级的大公司, 算法固然重要, 可是能够想象, 在项目施行进程里所碰到的形形色色的问题之中, 算法问题多数情况下不会成为主要瓶颈, 尚未达到那种非得让每个人都是算法高手的地步。实际上, 绝大多数项目真正难点并非一两个算法瓶颈, 甚至也不是单点的技术瓶颈, 而是系统性的组织问题, 是系统性的协调问题, 是系统性的设计问题, 是系统性的开发问题, 存在大量看似没什么技术含量的脏活累活, 还有许多问题是因信息不足, 并非技术能力强就能克服这些困难。一个团队最好优势互补, 有人算法能力强, 有人业务分析能力强, 有人擅长后端服务, 有人擅长前端界面, 有人聪明, 有人踏实, 这般是最理想的。如果依据“算法好”这一单独的标准来挑选人才, 那么必然会将好多卓越的人才阻挡在门外。
更多知悉Google和Facebook等这类一流公司详情后, 作者在此问题认知上有了一定转变, 然而实际这情况中, 这些公司并非完全聚焦技巧性强的算法, 而是更看重编码, 也就是Coding能力, 只是在编码测试时是依据一些简单算法题逐步推进展开考核实施工作的。这种面试方法, 作者对其越来越欣赏, 此面试方法还成为了作者们公司面试过程里的重点环节。因为编码能力的测试很有必要, 它有着知识性问题没法取代的作用。要是一个面试者, 连“判断一个字符串是否是另一个字符串的子串”这样的题目都不能正确又快速地实现, 那基本上就可以直接排除掉了。需注意, 作者在此强调的是不必考察高难度的算法问题, 可不是不重视编码能力测试, 读者切勿误解。
【基础】
基础面试, 是那种考察像指针使用、进程线程概念等基础知识的面试, 它和大学期末考试题极为相似。作者原来觉得基础面试相当重要, 可如今却不这么认为了。在工作里基础确实是关键的, 然而在面试进程中, 它得具备区分性才具备意义, 换句话讲, 就是P(工作好|基础好)的概率要高, 如此一来, 考察指针使用、进程线程区别这类基础题目才会有其存在的意义。作者所拥有的实际经验表明, 基础面试并不具备良好的区分性, 如同算法那般, 大致上P(工作好|基础好)= 50%。与此同时, 基础面试属于最易于准备的, 而中国人有着长期的应试教育经验以及要去准备几个针对指针的题目是太容易实现的。
有这样一位面试者 , 让作者曾遇到。他对C语言基础 , 以及编译 、链接等原理掌握得极为出色 , 从而给作者留下了深层的印象。对此作者给出的面试结论是: 他虽是知识面不宽泛 , 仅仅会C语言 , 然而基础扎实 , 故而建议录用。后来发生的事表明那个结论的前半部分没错 , 但后半部分 “建议录用 ”却是错误的。这位面试者在实际工作里表现得糟糕透顶 , 既不理解需求 , 也不明白整体架构 ;并且 , 其上班时间并非花在项目上 , 而是耗费在阅读像《程序员的自作者修养》这类书籍上。最后,这位同事由于长期“不出活”离开了公司。
基础并非不重要, 然而“基础好”根本无法表明面试者能够出色地完成工作, 这是由于基础属于局部性知识, 可实际工作所需的是综合性能力。二者存在着极大的差异。能在C语言、操作系统考试中考出高分, 可是不会编写程序的人, 在大学作者们见得难道还少嘛。软件开发犹如盖房子, 综合能力就好比设置规划以及搭建框架结构, 基础知识则如同堆砌砖块。张小龙最初的Foxmail是用Delphi开发的, 他不懂C#, 要是你打算招聘一个开发.NET Email客户端的人员, 你去考察他对CLR掌握得是否良好有意义吗, 让张小龙去开发一个C#版的Foxmail真的会存在困难吗, 你招来一个精通C#却没有Email客户端开发经验的人真的会比张小龙更靠谱吗?
作者表明基础知识不重要, 这跟古人讲的“不积洼步无以至千里”是否存在矛盾呢, 并不矛盾, “洼步”与“千里”是一种能够累加得上的关系, 不过再多的“基础知识”都没办法累加成“综合能力”, 学习软件开发得如同持续集成那般, 从一开始就是一个完整的系统, 尽管规模不大, 问题不少, 然而它麻雀虽小五脏俱全, 要从小系统朝着大系统, 从简单系统向着复杂系统逐步地演化。
所以, 单单基础好这一点, 本身没办法说明太多方面的问题, 还得进一步去考察综合能力才行。对于那些在基础面试当中表现欠佳的面试者, 要是时间方面允许的话, 同样也得进一步去考察, 为啥, 因为有些面试者实际上是具备能力的, 只不过没有做好充分的准备罢了。最理想的那种状态自然是基础和综合能力这两方面都非常出色, 如果没办法同时兼顾的话, 那应当是把综合能力放在优先考虑的地位。
【经验】
这儿所讲的经验并非依据工作年限多少来衡量, 主要是指面试者的经历, 像是否完整达成过一个软件, 或者作为主要开发者完成过一个项目。经验的关键之处在于它能够表明一个人的综合能力, 从项目的性质、规模以及难度, 面试官能够大致推断出面试者的综合能力。要是一个面试者始终在大公司负责一个小模块的开发维护, 那么基本上能够判定他不具备独立或者作为主要开发者承担一个项目的能力, 仅适合在另一家大公司做类似的事儿。对于那种门槛比较高, 务必需要长期进行技术积累的职位而言, 相关经验愈发显得特别重要。比如说, Linux内核开发, JVM开发, 游戏引擎开发, 数据库实现还有高级UX等。对于这类职位来讲, 没有经验的面试者就算综合素质挺好的情况之下也是得经过长时间的学习以及积累才能够胜任的。所以, 基本上要是确定了你的职位属于这一类了, 那么相关经验毫无疑问必定得成为首选因素的, 换句话讲, P(工作好 | 相关经验好)的概率是相当高的。
凭借项目经验去判别面试者的好坏优劣相较于借助基础以及算法测试更为可信可靠, 因而, 在面试的进程里面, 面试官理应耗用比较多的时间去聆听面试者讲述项目经验, 并且展开深入地探究交流, 以此知晓面试者的知识范畴、思维能力、表达能力等等。与此同时, 可以依据项目提出一些根基知识以及算法方面的问题, 举例来说, 要是面试者做过与C++相关的项目, 那就能够询问他怎样开展内存管理? 是否熟悉智能指针? 要是面试者的回应无法让人感到称心如意, 那么就大致上能够判定他的项目做得并非出色良好。
需留意的是, 经验属于多维度的事物, 像C++股票交易中间件系统, 就涵盖着(C++, 中间件,股票)三个维度。假设面试者A做过C++股票交易客户端, 面试者B做过C的股票交易中间件。从语言层面来讲, A最为匹配, 从项目性质而言, B最为匹配, 你会怎样抉择呢? 这便是在多个维度里, 哪个维度更为重要的问题, 就这个事例来讲, 作者个人更偏向于B, 因为作者觉得中间件开发经验是主要矛盾, 而从C转换到C++并非难题。故而, 面试官要判别哪一种经验属于主要范畴, 哪一种经验属于次要范畴。举例来说, 作者们针对Android应用开发进行招聘, 此职位的Android技术门槛并非很高, 其真正的难点之处在于打造出良好的用户体验(UX)。所以, 要是一个面试者欠缺Android方面的经验作者们是能够接受的, 然而作者期望他在UX方面具备经验, 起码做过其他平台的移动应用开发。
【性格】
此刻, 著者来讲讲著者觉得最为关键的要素: 性格。这兴许是众多初次成为面试官的友人所难以设想的, 怎会是性格最为重要? 说实话, 当著者察觉到这一点的时候, 著者自身也颇为诧异!说白了, 确实是P(工作好|性格好)的概率最为高。著者的实际阅历是, 倘若一个人的性格良好, 那他把工作做好的可能性是最为高的, 性格好远比基础好、算法好要可靠。
假设一个人, 在技术层面存在着欠缺之处, 于经验层面有着不足之处, 然而其性格良好, 那么在团队里, 便极易被其他人予以补位, 并且其自身也能够较轻易地进而补起来;与之相反, 要是一个人的性格欠佳, 那么所有的技术优势以及经验优势均无法得到发挥, 甚至还会产生负面作用, 而且性格缺点是难以进行改变的。作者始终提及实际工作所需的乃是综合性的能力, 在这种综合能力的发挥之中, 性格是极为关键重要的。项目当中, 并非只会碰到技术方面的问题, 还得涉及到沟通, 以及协调, 不同的人、不同的部门, 既存在合作的情况, 又会产生磨擦, 怎样去处理这些事情, 无不都需要具备一个良好的性格。能够这么讲, 在开发团队里面, 致使你变得与众不同的, 并非是你毕业于哪所学校, 也并非是你过往的经验, 而是你的性格。
的确, 性格属于一种繁杂的事物, 它含有诸多方面, 并非全部方面都是程序员面试时所需留意的。该作者所具有的经验是能够着重考查这些方面:
1) 面对面试者, 其态度究竟是积极的, 还是消极的存在。部分面试者, 于谈吐期间, 会自然而然地向你传递出一种积极向上、力求进取的感觉, 又或者, 你能够在他过往的经历里头, 寻觅到彰显他积极一面的因素, 而这些, 其实都并非是特别难以察觉发现的。与之形成反向对比的是, 有的面试者, 你能够十分明显地感受到他所流露出来的消极情绪。积极性这一特质, 在工作范畴当中, 是具备着不可或缺且十分重要之意义的, 积极的人, 可以给团队赋予带来蓬勃的朝气与活力, 并且, 也更加容易便于合作共事。基本上而言, 如果能够确定面试者属于那种态度积极的类别, 那么他通过此次面试这一关卡的可能性, 就会大幅度地显著增加;反之相反, 如果确定其属于态度消极的类型, 即便其技术能力相当不错, 面试者也会秉持着十分谨慎的态度。
2) 智商。作者有着这样的经验, 从总体方面来看, 具备聪明特质的人于工作里的表现会更加出色。在面试期间, 若要去考察一个人是不是聪明, 并非一定要如同谷歌和微软那般找些专门用于测试智商的智力题目, 实际上, 你仅仅需要观察他探讨问题时是否极具逻辑性, 思考以及说话时反应是否敏捷, 如此便能够做出大致的判断。除此之外, 眼睛乃是人心灵的窗口, 一个人聪明与否, 眼睛是能够传达信息的。然而, 聪慧不全然是益处, 举例而言, 当公司或者项目遭遇困境之际, 往往正是聪明人率先撤离 , 留下坚守的常常是智商平常之人。
3) 要考量程序员的语言表达能力, 这是极为关键的一项素质, 其关乎项目里沟通是否能顺利进行。面试官应当观察面试对象, 了解 Ta 能不能运用简洁的话语, 清晰阐述过往做过的项目, 能不能精准抓住重点, 能不能充分顾及听者的相关背景情况。通常而言, 具备较强语言表达能力的人, 综合能力往往不会差。 (面试网 www.mian4.net)。
4) 有没有用户意识。有人讲开发人员是搞研发的, 哪会有啥用户, 仅有销售、市场这类人员才和用户有交流。实际上, 这可是彻头彻尾的错误认知。你编一个模块, 甚至一个应用程序编程接口, 只要有其他人用, 那这人就是你的用户。有些程序员设计模块或者一款软件时老是以使用者的视角去考量, 尽可能地给使用者提供便利, 这便是一种不错的用户意识。具备良好用户意识的人更能够顾及别人的感受以及整体的需求, 而非仅仅从自身和局部去计较问题。当面试者说起过往的项目经历的时刻, 面试官能够时常站在用户的视角针对其予以发问, 在这个进程里观察其是不是具备良好的用户意识。
5) 怎么去应对那质疑以及压力。面试的考官应当针对面试者给出的回答还有过往的项目展开合理性的质疑, 瞧瞧那个人怎样去应对。曾经存在一位面试者提及做游戏登录服务器的经历, 笔者就询问道: “要是登录服务器出现故障了, 该如何处理呢”? 这人表示先前尽管未曾思考过这个问题,然而能够如此这般地进行改进。实际上, 大伙都明白项目当中有着各种各样的不完美之处, 这里面的缘由是多种多样的, 只要身处质疑以及压力的情境下能够从容不迫地应对并且努力朝着好的方向去思索解决办法便行了, 无需去刻意掩饰缺陷, 更不应当产生情绪。作者曾碰到过一些面试者, 一旦你针对其项目发出质疑, 他即刻生出反抗情绪, 要么不高兴, 要么不承认存在问题, 这很轻易就能一下子瞧出来他在工作当中容不下质疑与批评, 此类人若想合作会非常困难。
6) 很多面试者在简历上经常写“精通C++/Linux”, 这样的字眼看得人都快麻木了, 要是有人写“喜欢C++/Linux”, 那作者就会有一瞬间觉得眼前突然一亮, 是那种能让人注意到的感觉。其中, “精通”只是种没有感情倾向的陈述, “喜欢”却涵盖着面试者本身的个性, 相比之下作者更倾向于看到表现面试者个性的内容。作者深信, 对于某样事物真正的热爱之情, 远比当下对其具身具备熟练的掌握程度在本质上显得更为关键重要。实际来讲, 经过N年的种种经历向作者们表明, 处于同一个班级的同学, 同在一个项目组的同事, 尽管每日所学习的知识, 所接触到的工作皆是一样的, 然而实际上每个人的成绩以及表现差异是极为显著的。那么, 究竟本质上的差异究竟是什么呢? 实际上, 就是每个人各自的个性。正是个性致使有的人在业余时间去从事打球活动, 有的人在业余时间去进行看书行为, 有的人喜好Linux, 有的人钟情于Mac。一个人于团队里所扮演的角色同样和他自身的个性存在着很大的关联。面试者需由面试官引导, 从而展现出自身个性, 且面试官要判断其个性对团队是否有益处。
【总结】
最后总结起来,作者的经验是:
1) 面试官的目的是寻觅“工作出色”之人, 务必围绕此目的来开展面试, 要是将面试视作算法或操作系统期末考试, 这便步入了歧途。
2) 面试进程, 是凭借学历、性格、基础、经验、算法等能够进行测试的因素, 去全面考量并判定, 关于面试者“在工作方面表现出色”的可能性。
3) 当考量各种因素时, 性格大于经验, 经验大于基础, 基础大于算法。性格是最为关键的, 一旦性格欠佳, 那么所有的技术能力都会大幅降低, 并且技术方面的缺陷易于弥补, 然而性格方面的缺陷却极难改变;经验展现出一个人的综合能力, 能够依据面试者过往的经历去判定其擅长从事何种工作, 不擅长从事何种工作;基础与算法主要发挥辅助参考的功效, 基础良好的程序员通常适应能力较强, 学习新的技术更快, 不过要切忌仅仅依据基础去评判一个人的能力。

CopyrightC 2009-2025 All Rights Reserved 版权所有 芜湖人才网 本站内容仅供参考,不承担因使用信息、外部链接或服务中断导致的任何直接或间接责任,风险自担。如有侵权,请联系删除,联系邮箱:ysznh@foxmail.com 鄂ICP备2025097818号-15
地址: EMAIL:qlwl@foxmail.com
Powered by PHPYun.