如何面试一名iOS开发

AlisonBaugh 6年前
   <h2>背景</h2>    <p>最近一段时间因为有小伙伴离职,需要补充新的同事,所以断断续续地面试了几位同学。从应聘者的角色转变成面试官,这种变换带给了我一些新的体验和思考。现在网络上有很多大牛都分享过如何面试iOS开发。实话实说,有些题目我自己也做不出来。当然了,大牛的面试题中很多都是平时开发应该掌握,问起来好像听说过,但是实际又没有深入研究的问题。比如OC语言中的Category,是否可以增加成员变量,是否可以增加属性,可以的话原因是什么,不可以的话原因又是什么。我觉得很多人都只是知道个结论,内部的实现就不清楚了。其实这种问题属于典型的送分题,因为只需要你有一个打破砂锅问到底的钻研劲儿,然后研究一下Category的C语言实现,一切就都明白了。可惜的是,我这段时间面试的几位同学,别说到这一步了,就是表面的结论都模棱两可,无法给出一个确定的答案。</p>    <p>书归正传,今天的文章就来介绍一下我们团队的面试标准,都着重于考查哪些方面的能力。</p>    <h2>基础知识</h2>    <p>我比较看中的基础知识包括两方面,一方面是语言相关的,包括常见的内存管理、修饰符的使用和区别、多线程、事件的传递和响应链、应用的生命周期、Notification、Block、Delegate。这一块基础如果回答的不错,就追问一些TableView的优化方案、Runtime相关、对Runloop的理解、OC与JS之间的互相调用和通信方案、静态库的打包和集成、Crash日志的收集和分析等等。我个人理解这些内容并没有涉及高深复杂的东西,更多的是平时开发中的研究和总结。</p>    <p>另一方面,我比较关注计算机基础,这其中包括计算机网络、操作系统、数据结构、编译原理。注意我这里列举的都是我们大学本科阶段学习的课程,本来就应该是掌握的。而且上面的顺序也是根据我个人的经验,按照工作中接触的频繁程序从高到低排序的。比如我并不会要求面试者精通编译原理(如果真是这样的大神,应该也不会来我们这边面试,哈哈),但是计算机网络中HTTP/HTTPS,TCP/IP,DNS解析这些内容应该是熟练掌握的。我也不会让面试者手写快排或者堆排,或者问一些类似于 进程和线程有什么区别 这种问题,并不是说这些问题不好,而是仅仅对面试这个事儿来说,这些东西完全可以在面试前上网查到,然后默写几十遍记在心里,这种行为是我一直以来都非常鄙视的,所以我对这类问题完全摒弃,我们的问题都希望是尽可能的贴近实战,贴近每天的开发场景,真真切切就是你加入团队后遇到的问题,这样更能看出面试者的能力。所以我更倾向于问一些有用的东西,比如OC中的方法调用涉及到Hash表的实现,在、图片下载场景中的内存缓存,内存中堆区和栈区的差别,多线程中串行和并发队列,同步和异步的方式差异等等。</p>    <p>这里特别要提一下,之前阅读过bestswifter大神的博客文章,有一个问题我觉得说的特别好,他提到很多计算机的基础知识,可能你平时不会也并不影响你的业务功能开发,但是它会影响你看问题的高度和深度。我们现在看到的很多大牛也并不是天生的,更多的是从无数次的问题排查中磨练和总结出来的,遇到了自己不懂不会的再回过头去学习和研究。这就是为什么有的同事一看问题现象,大致就能做出比较准确的定位判断,这里面固然有经验积累的因素,但是很重要的一方面是他们的基础足够扎实。而同样的问题你给其他没有基础的人,可能他们连线索在哪儿都不知道。</p>    <p>看到这里的同学,没事儿别看那些乱七八糟的快餐书了,赶紧把垫显示器的那本《TCP/IP详解》拿出来。</p>    <h2>开发调试能力</h2>    <p>对于一个做开发的同学来说,具备很好的开发调试能力是基本的素质,也是我个人最看重的一点。但是这个点在现有的面试流程中比较难考察,因为我们目前还没有达到让面试者现场写代码的程度,而且我本人对这种方式也持有一些个人看法,毕竟大家都是面试过的人,在面试的过程中写代码和平时写代码,心态上是不一样的,仅仅以这样的方式就得出面试结论可能也有失公允。</p>    <p>那么应该怎么办比较好呢,我调研了网上一些前辈的做法,比较赞同的是场景引导方案,也就是说在面试中我会提出一些开放性的场景,先抛出去问题,然后引导面试者提供解决方案。比如以最常见的登录场景为例:</p>    <p>用户输入了用户名和密码,点击登录按钮之后,客户端发出请求,服务器端接收请求返回响应,客户端收到响应进行后续处理。</p>    <p>在这个过程中,有这么几个问题:</p>    <p>用户输入的内容需要加密吗?如果需要,选择什么样的加密算法,密钥是固定秘钥还是随机秘钥,如何存储或者传输的。如果不需要加密,原因是什么。</p>    <p>发送和接收HTTP请求,是调用AFNetWorking或者其他第三方库,还是自己实现。如果是AFNetWorking,是否有了解过其内部的实现机制。如果是自己实现,具体是如何设计的。</p>    <p>这个HTTP请求的发送方式是POST还是GET,原因是什么,各自的优缺点是什么。除了Method,HTTP请求是否还包含其他的数据或者信息。</p>    <p>服务器端接口如果是HTTPS的话,是否需要设置证书校验,客户端需要做哪些配置修改,HTTPS与HTTP的差别在哪儿,跳过证书校验的话应该怎么做。</p>    <p>如果这个场景是用户点击H5活动页面,但是要求登录完成之后回到原来的H5页面,涉及到OC调用JS,这部分怎么做。如果是需要跳转其他的应用,又如何实现。</p>    <p>如果业务层面有新的需求,要求登录按钮的点击范围太小想要扩大一些,如何实现,是否有更好更优的解决方案......</p>    <p>这样的场景都是从我们团队的工作中抽象出来的,只不过隐去了业务上的一些信息,重点关注在技术层面的实现。如果面试者能够很好的回答上面这些问题,我会认为他是有一定的技术积累和经验的,不光是停留在这个功能我做完就结束了,而是对内部的实现有过自己的思考和学习。稍微差一点的,可能因为做过的项目都比较浅,但是能够提出他的想法和方案,我们共同去探讨交流,这说明对方具备学习的想法,即便说的不对也没关系,我更看重对方的思路和表达。最差的就是第三种同学,要不就是非常基础的东西说的都不对,其他东西是一问三不知,要不就是态度傲娇,口头禅一般是这个问题那不就是XXX嘛,各种不屑一顾,那我也只能在心里呵呵了。</p>    <h2>项目经历</h2>    <p>项目经历重要么,当然重要。从业务上说,iOS领域的开发有很多的细分领域,有的是做类似于快手抖音这种短视频的,所以对音视频这块的要求会比较高。有的是做淘宝京东这一类电商的,就更关注应用能否快速灵活的支持活动运营,应用的质量和体验能否得到有效的保障。有很多的公司在招聘时都比较看重项目经历的相关性。从公司成本的角度考虑,招聘一个做过类似项目的同学,会更加容易上手,更快速融入开发团队,甚至有的小公司本身就缺少这块业务,直接发布职位给猎头和HR,定向从大公司挖人。而且好的项目经历本身就是一张名片,确实是很重要的加分项。</p>    <p>从iOS开发的现状来说,由于前几年移动互联网兴起,大小公司全部开始转型或者All in无线。所以单说项目经历,那确实是各行各业无所不包,这几次面试也真的是让我见了世面。比如有一位同学的简历,光是项目经历就写满了4页A4纸,真的是“经验”丰富,仔细一看,好像又是把第一年的经验复用了4年。</p>    <p>所以面试的过程中,我们关注项目经历,本质上是关注项目中遇到的技术问题和解决方案。面试者既然写到了简历上,那么肯定是他比较熟悉的项目。一般会先介绍一下项目的背景,自己在项目中负责的模块。然后聊一下简历上写到的技术点,比如FMDB、网络优化等等,关注对方的技术方案实现。最后扩展一下相关的知识,这方面没有固定标准,可以问的深入一些,比如涉及页面卡顿优化,可以再聊一下RunLoop的相关内容。也可以问的广一些,比如网络优化中是否了解DNS劫持,HTTPDNS,证书链等等。</p>    <h2>沟通能力</h2>    <p>沟通能力是贯穿在面试过程中的,最后我们会根据整体的面试表现得出结论。基本上从自我介绍开始,到中间的回答问题,重点关注能否表达顺畅、思路清晰。</p>    <p>有的同学可能觉得这样不太公平,明明自己的技术很好,只是因为面试的时候比较紧张,或者自身并不太善于表达,导致面试没有通过。其实我个人建议,如果你是一个优秀的开发人员,觉得自己能力超群,不需要加入任何的团队进行协作开发,那么沟通能力差一些也不影响你的光辉。但是如果你过来参加面试,加入的是一个多人团队,以后的工作中要和领导、同事等等各种人员打交道,那么沟通能力就成为了很重要的一方面,甚至有些时候的重要程度是远超你自身的技术水平。另一方面,我们终归是技术面试,不是面试销售或者运营,并不会要求面试者说的天花乱坠,所以尽量调整好心态,有条理有思路的阐述即可。这方面的技巧可以参考STAR原则,网上相关的资料一大堆,这里就不多说了。</p>    <h2>学习能力</h2>    <p>学习能力是技术人员进步的原动力,尤其是现在的技术浪潮变化这么快,如果没有很好的学习能力,总是吃老本,很容易就会被更年轻的小同学拍死在沙滩上。</p>    <p>关于学习能力我会着重于两个方面,一个是在实际解决问题的过程中,是否展现出了面试者的学习能力,比如在面试者遇到的问题超过了其当时的技术水平线,但是通过学习和研究成功的解决了问题,能清楚的知道自己学到了新的知识和技能,这个会比较加分。因为在平时的开发工作中,每天都在跟各种问题打交道,这其中有些问题是你从未碰到过的,解决问题的过程就是自身的技术水平上升的最佳实践,如果最后能总结到自己的博客或者分享出来就更好了,这比起你fork10个开源项目,写10个小demo要强的多,因为是你亲身体验并解决的问题。</p>    <p>另一方面关注面试者的过往经历是否反映出他的态度,对待工作,对待技术的一种态度。我很喜欢一类同学,可能因为工作年限太短或者基础比较差,或者限于公司是个小作坊没有正规的开发流程,自身的技术水平确实一般,但是他有对技术的好奇心和钻研精神。遇到了问题,并不是去直接复制粘贴,而是自己去认真思考,这样做的原因是什么, 有没有其他更好的方案,会不会对现有的功能和以后的扩展造成影响。这些思考并不是无意义的,所有的努力都是在养成自己的技术思维,给自己的知识体系添砖加瓦。对于我们团队来说,技术不好不可怕,学习的态度不好才是真的大黑洞。</p>    <h2>面试礼貌</h2>    <p>最后谈一下面试礼貌,从我参加工作到现在为止,参与面试过的同学差不多也有20个左右了,大部分的同学都是非常有礼貌的,不论面试成功与否,都可以有一个比较良好的沟通氛围。因为我自己也参加了不少面试,也确实碰到过很多的奇葩,所以有一个好的面试礼貌,应该是双方都有的基本素质。</p>    <p>作为应聘者,我觉得比较好的态度是不卑不亢。并不会因为我是来参加面试的,希望能顺利通过这个面试而变得唯唯诺诺,过分的谦卑。这样会让面试官认为你对自己不够自信,对自己的技术水平也不够自信。另一方面,也不能表现出一副老子天下第一,你们都是渣渣的态度,这本身就对面试官不够尊重,面试更多的是一个相互选择,相互学习的过程,并不是邀请你来这里华山论剑,来争个技术的高低。</p>    <p>作为面试官,我觉得比较好的态度是友善和尊重,对技术比较弱的同学,即便你的问题对方没有回答出来,也应该先考虑下对方的背景和经历,只要不是基础的,公共的,应知应会的东西,都不要轻易的Pass掉这个人,也许只是他做的方向和你不同,你更熟悉罢了。对技术比较强的同学,就更要关注他的诉求和个人感觉,我们的团队能否满足他技术上提升的空间,他的整体感觉和性格特点能否融入我们的团队。</p>    <p>不管怎样,我们都应该在友好、轻松、愉快的氛围中进行面试,尊重自己,也尊重他人。</p>    <h2>招合适的人</h2>    <p>之所以要说这一点,是因为起初我过于看重了应聘者的技术能力,标准过于单一。后来与同事交流了之后,才明白面试的目的并不是非要招一个技术大牛,而是招一个与这个岗位相匹配的合适人选。这让我反思了一下自己之前的面试经历,确实没有从整个项目和团队的角度去考虑问题。个人的力量再强,他也没有三头六臂,也不可能将我们的项目全都接过来自己干。这就好比我们是团队作战,有的时候是士兵离开了,有的时候是排长离开了,所以为了保持战斗力我们需要补充人员进来,但是前提一定是搞清楚我们补充的是士兵还是军官。如果我想要招的是士兵,那就应该看重单兵作战素养,而不是要求丰富的战斗经验。如果我想要招的是排长,那就应该看重实战中的表现,能否带领团队完成任务。反之如果面试之前没有想清楚,那就是埋下了一个隐患,即使招进来了这个人,也可能因为不合适而再次离开,造成公司和团队的二次损失。</p>    <h2>小结</h2>    <p>一不小心就写了这么多,感谢能看到这里的小伙伴。总结一下就是我们团队在面试中,更看重基础知识、开发调试能力、项目经历、沟通能力、学习能力这些元素,我们坚持的原则是招聘合适的人。其实技术上有很多的细节没有再展开,比如一些开发调试的工具使用,脚本语言的使用等等。因为我自己也还是一个技术领域的小学生,深知行业内多的是藏龙卧虎的大牛,越是懂得多一些,就越是感觉自己懂得太少。所以这篇文章只是分享一些个人现阶段的思考,如果能给大家带来启发和思考就更好了。不管我们处在哪一个阶段,都要有一个好的态度,加上一份努力和一份坚持,相信付出总会有回报。</p>    <p> </p>    <p>来自:https://www.jianshu.com/p/3ea4dca4648f</p>    <p> </p>