李洪强经典面试题14
iOS面试一般性问题,学会这些拿offer几率提升90%!
面试题中有一些一般性的问题,通常是会问到的。面试iOS应聘者时,切入点很重要,不同的切入点会导致不同的结果,没有找到合适的切入点也无法对应聘者有一个全面的了解。所以下面的面试问题更多的是提供方向,没有固定的答案,而且可以根据应聘者的回应引出更多有意思深层次的讨论。
注意:以下问题的参考答案均为笔者所答,不代表正确,问题答案因人而异,请根据自己的实际情况回答,若认为不合理,请在评论中指出。下面所有的参考答案,都是笔者站在面试官的角度来分析的,不同的面试官也会不一样。笔者面试过一些人,一问就可以知道对方的底子如何了,虽然如此,不代表参考答案是每个面试官想要的。
自我介绍
自我介绍时,一定要简洁明了,不要长篇大论。以我个人而言,最不喜欢自我介绍说了一大堆,最后连她/他叫什么名字都没记住。
参考答案:
自我介绍时,突出重点,说话慢一些,在关键点声音大一点。本人回答时,就简单地说: 我叫某某某,做iosX年了,曾在XX公司担任过XX职务,在YY公司担任过XX职务,主要负责ZZ工作。业余喜欢做NN(要说积极点的),擅长LL(把自己的特长说明白)等。
最近这两天你有学到什么知识/技能么?
对于这个问题,面试官肯定知道作为求职者,这两天肯定是在忙于找工作、面试。那么,面试官问出这样的问题的目的是什么?如果我是面试官,我最想了解的是这两天你为此次面试准备了什么而不仅仅是告诉面试官这两天学习了某一方面的知识。
参考答案:
这两天为了准备面试,整理了以前所做过的一些项目的笔记,回头看了看以前的工作日志。一来是整理一些在工作中经常遇到的坑,比如cell重用问题、ios6适配问题等;二来是回头告别过去的自己,在思想上、技术上迎来全新的自我;三来定位自己下一个目标:往架构师方向深入研究。
最近有做过比较酷或者比较有挑战的项目么?
这个问题的关键是酷和挑战。其实这里所说的酷对应于开发中的动画,而挑战则对应于开发中的冲刺。对于笔者而言,其实并没有做过特别酷的项目,但是做过有挑战性的项目。但是没有做过并不是就不用回答,面试官想看到的是你的学习能力、应用能力以及解决问题的能力,而不是一句没做过或者没什么挑战性这样的话语。
参考答案:
我之前所负责的项目大多是电商项目,因此并不会特别酷,但是业务比较多,很有技术挑战性。不过,平时我也深入研究过ios核心动画相关知识,对于常用的动画是很熟悉的。在我看来,用户体验并不是所谓的酷,而是简单、方便且明了。我很在意用户体验问题,在开发中会不断地站在用户的角度地问自己用户讨厌什么、喜欢什么和怎样才能让用户感觉容易上手且使用简单等问题。比如,我会很在意网络状态的变化给用户的提示、请求网络时右上角的转圈圈是否开启、滚动cell时是否有卡顿的问题等。
我待过几家公司,从一个人开发到带领团队,从小公司到大公司,因此对于不同的公司对项目的要求完全不一样。对于大公司,一般项目管理机制相对比较完善,而且会有比较多经验丰富的技术VP,因此对于工作的要求比较高,对于用户的体验及反馈会非常地关注;而对于一些小公司,可能就一个人在开发,而这个人往往是菜鸟的多,因此都是东拼西凑而形成的项目,技术不成熟、水平不够,而且还被压着不断加班,因此几乎不会过多关注用户体验问题,当然这样项目也不会有什么好的构架(初创技术合伙人除外)。
现在我所在的公司不算大,也就1000+号人,而做ios也才40号人左右。本公司是按业务方向划分成多个团队,不同团队开发不同的业务需求,因此这样就面临技术架构问题、安全问题、团队开发如何做到互不干扰等问题了。而我在团队中的主要职责是处理团队之间冲突的问题、如何代码模块化以减少团队之外的依赖问题、移动端安全通信问题、项目存储安全问题、公共框架等问题,这一系列都是非常有技术挑战的,需要花费很多非工作时间去调研、写demo、写文档等。
关于动画的学习,可以参考相关专题:iOS Core Animation
最近看过的书/文章有哪些?
询问最近看过的书或者文章,其实通过所回答的书的性质差不多就可以猜出当前状态下应聘者的技术水平大致处于什么样的水准了。下面的参考答案是笔者的常态。
参考答案:
最近在看《iOS应用逆向工程》、《The Swift Programming Language》。不过本人更喜欢的是阅读博客文章和官方文档,虽然官方文档是英文的,阅读起来相对要费劲一些,但是一方面可以提高英文阅读能力,另一方面英文原版表达的语义才是最准确的,其他翻译过来的文章会有一些变味之处。
为什么要学习编程,编程对你而言的乐趣在哪儿?
这样的话题在很多社区都出现过,其实问这样的问题只是想知道应聘者的态度而已。通过应聘者的回答,一方面可初步了解应聘者对编程的认知程度,另一方面可从应聘者口出得出编程对于应聘者而言是什么样的态度。下面是结合笔者的事迹写下的参考答案,仅供参考。
参考答案:
说到这个问题,我曾经也问过自己为什么要学习编程。回想当年高考结果出来的时候,需要选择学校和专业的时候是很迷茫的,不知上大学应该学点什么。后来,我选择了计算机科学与技术专业,并为了这个专业而选择学校。由于高考考得不好,虽然超过一本线,但是高不成低不就,很多高校的计算机专业要求总分达到560(当时一本线是502分)左右才能稳拿到这个专业,而我才考了526分,想想计算机专业很强的高校是很难进的。于是选择了从广西到沈阳这么遥远的地方上学,竟然是为了计算机专业,现在回想起来还自己偷笑。
在大学的时候,大一天天在图书馆提前学习编程,因为动手能力突出,到大二的时候有好多教计算机的老师提前知道了这样的我,感谢他们的认可,在大学这几年,是他们引导我如何编程实战。大学的时候做过很多PC端的软件(.net开发的)、给老师做过教程网站(ASP.net开发的)、参加学习的ACM训练等等,一切的一切,都要感谢那些教导我的恩师们。
后来通过学长了解到未来就业的一些动向,了解到毕业后如何找工作,学习了iOS开发,于是越来越爱她了。如果非要说编程的乐趣在哪里,我想说在讨论技术的时候就像和同学、朋友一起玩LOL的时候;在解决掉一个别人解决不了的bug的时候,那是一种想要向全世界大声说:YES,I Can;当我们与技术总监并肩作战,一起为了项目上线熬夜,总监为我们买夜宵一起吃的时候,那就是兄弟情谊,那会有种相见恨晚的感觉。
如果一个函数10次中有7次正确,3次错误,问题可能出现在哪里?
这样的问题通过应聘者的分析,可以知道应聘者的功底如何。很多人的回答会是很简单的,没有从多方面去分析。这样的问题也是很有意义的,在项目开发中所产生的bug,有的时候会出现这样的情况,而代码量比较大且业务比较复杂时,通过其他工具并不能分析出来是什么bug,但是我们却可以根据出现的频率推测。笔者把这个问题当作测试部反馈过来的bug描述问题来分析一下。
参考答案:
从问题描述可知,bug不会必现的,因此无法直接定位出错之处。从以下角度出现来分析可能出错之处:
-
因出错并不是崩溃,因此没有错误日志可看。第一步就是分析函数中的所有分支,是否在语法上存在可能缺少条件的问题。所以,检查所有的分支,确保每个分支执行的结果的正确的
-
检测函数的参数,保证必传参数不能为空,若为空应该抛出异常。因此,用断言检测参数的正确性是很重要的。
-
检测函数中每个分支所调用的函数返回结果是正确的,其实就是一个递归的过程(步骤1、2)
自身最大优点是什么,怎么证明?
人最大的敌人不是别人,而是自己。战胜自己,才是最大的胜利。很多人不清楚自己的优点是什么,甚至很多朋友喜欢说我最大的优点是没有缺点。如果是对面试官说这一句话,那么你可能被pass掉了。
参考答案:
我也不清楚我最大的优点是什么,但是我知道我有很多优点。
-
我学习能力特别强,接受新事物的能力也特别强。比如,我在工作之余还会去学习swift、PHP、js等。
-
我喜欢写博客、写总结、分享技术、帮助他人等。我觉得写博客的过程,既让自己对相关知识有更深刻的认识,更是帮助到他人。每做一期需求,我都会写一份总结,记录那些坑。在公司每个季度都会做几次技术分享,带动团队的技术氛围。我也喜欢帮助他人,我创建了自己的技术群,短短1个月群就满500人了,在群里通过回答大家问题,也让我了解到很多知识。
-
我支持开源、喜欢开源。我写了几个开源库,大家若是觉得有价值,请随手给个star:标哥的GITHUB
-
我开发过多款App,解决问题的能力很强。在团队中充当技术主心骨,任何队员解决不好的问题,我都会帮助一起解决掉。
-
我对技术构架、团队如何解藕方面都有所研究。在团队开发中,因为经常面临团队开发存在交差的问题,导致需求变动引起很多问题,因此研究过如何让团队之间减少依赖的问题。
-
我活跃于GITHUB、CocoaChina、CSDN等,对于iOS相关技术知识比较熟悉。
就说这么多吧!(因为面试高级人员通常会交谈3个小时左右,所以尽可能地说吧,不要害怕时间过长)
有没有在 GitHub 上发布过开源代码,参与过开源项目?
github上的开源项目可以体现应聘者的水平以及对编程的热爱程度。一个不足够热爱编程的人,业余时间是不会花在编程上的,因此更不会有什么开源项目了。
参考答案:
参考开源库标哥的GitHub,里面除了一些开源库之外,还有很多的demo,每个demo都有对应的博客文章讲解,那都是我感觉学习的成果。
我在GITHUB上发布过很多开源代码,也提供了支持cocoapods的开源项目,现在也有不少人在使用,当然我也会一直维护着,不过我并没有参与过其他人发起的开源项目。
你最近遇到过的一个技术挑战是什么?怎么解决的?
通过应聘者回答所遇到过的技术挑战,其实从侧面就可以看出这个人的水平如何了。如果回答的技术挑战是个简单的问题,而在应聘者这里却是技术挑战,那么就可以知道这水平是初级的。然后应聘者针对这个技术挑战所给出的解决方案也可以看出面对技术挑战,可以看出应聘者处理问题的能力。
参考答案:
最近公司项目中的用户账号出现被盗现象,原因是通信安全问题处理不好。因为公司的项目已经是好几年的老项目了,包括服务端的接口好多是老接口,原来是没有处理任何加密的,因此很容易被盗取账号。现在我们的技术VP要求针对这个问题,做一个版本。因为主动接受挑战,所以这个重任落在了我的身上,由我来牵头做好这个需求。
这真的是一个很有挑战性的技术项目。步骤如下:
-
需要调研市场上比较有名的App,他们是如何做好安全通信问题的;
-
写好技术文档,将调研结果反馈出来并写出自己的技术方案;
-
开初步技术方案评审会,会有VP及各组Leader参与,会上会提出各种问题,并给予一一解答,然后做会议记录,会后继续完善文档;
-
开跨部分评审会,只有所有都通过了,才能立项。
-
技术立项,然后写好各方向所需要做的工作文档。
为什么要这么麻烦?因为我们既要兼容以前的所有版本,又要保证技术安全,那就不会自己就能说了算的,而且也不仅仅是客户端的问题。
开发常用的工具有哪些?
通过回答这个问题,一方面可以看出这个应聘者在iOS开发领域的深入程度。如果只知道Xcode和Cocoapods,说明是初级或者根本不愿意在业余时间花费精力去扩展。
参考答案:
常用的iOS开发工具有:
-
Xcode开发工具及配套的Instruments工具
熟悉CocoaPods么?能大概讲一下工作原理么?
这个问题不会回答也没有关系,因为很多老项目是不使用CocoaPods的,因此不一定会了解。 回答说使用过Cocoapods写过demo,但是不太懂工作原理是没有关系的。因为在我看到这个问题之前,我也没有深入了解过其工作原理,只是熟悉如何使用而已。
参考答案:
关于其原理,大家百度一下或者谷歌一下吧!因为笔者对其工作原理也不会很清楚,只知道它会为我们创建一个工作区间,然后将所有在cocoapods中的引入的第三方库以libPods.a这样的方式引入到我们的工程中,这样就可以直接访问第三方库了。但是,更具体的细节就不了解了,大家想要深入了解的话, 还得找谷歌或者百度。
最常用的版本控制工具是什么,能大概讲讲原理么?
关于这个版本控制工具的工作原理,其实也就是对这此命令的操作而已。
参考答案:
最常用的版本控制工具有SourceTree(GIT)和CornerStone(SVN):
今年你最想掌握的一门技术是什么?为什么?目前已经做到了哪个程度?
既然是技术,那么就要说明是什么技术,至于为什么想要掌握,当然是想要在技术上更上一层楼。
参考答案:
我现在一直在研究runtime相关知识。掌握runtime相关技术,可以做很多正常状态下做不到的事、可以让做一些自动化处理工作、解决代码依赖问题等。目前已经对runtime中的成员变量、属性、消息转发、Swizzling等可以熟练使用。关于runtime专题,大家可以阅读我的博客专题:iOS Runtime相关知识点
你一般是怎么用Instruments的?
这个就是工作经验的问题了。Instruments工具里面有很多个选项,没有必要每个都答,其实笔者也只用过里面的几个而已。
参考答案:
-
使用Allocations来检测内存和堆栈信息
-
使用Leaks检测内存的使用情况,包括内存泄露问题
-
使用Zombies来检测过早释放的僵尸对象,通过它可以检测出在哪里崩溃的。
-
使用Time Profiler来检测CPU内存使用情况
你一般是如何调试Bug的?
这个问题看起来很笼统,但又一针见血。通过应聘者的回答,可很直观地看出这个应聘者的处理bug的能力,以及其解决问题的思维。
参考答案:
Bug分为测试中的Bug和线上的Bug:
-
线上Bug:项目使用了友盟统计,因此会有崩溃日志,通过解析dYSM可以直接定位到大部分bug崩溃之处。解决线上bug需要从主干拉一个新的分支,解决bug并测试通过后,再合并到主干,然后上线。若是多团队开发,可以将fix bug分支与其他团队最近要上线的分支集成,然后集成测试再上线。
-
测试Bug:根据测试所反馈的bug描述,若语义不清晰,则直接找到提bug人,操作给开发人员看,最好是可以bug复现。解决bug时,若能根据描述直接定位bug出错之处,则好处理;若无法直观定位,则根据bug类型分几种处理方式,比如崩溃的bug可以通过instruments来检测、数据显示错误的bug,则需要阅读代码一步步查看逻辑哪里写错。
对于开发中出现的崩溃或者数据显示不正常,那就需要根据经验或者相关工具来检测可能出错之处。当然,团队内沟通解决是最好的。
你在你的项目中用到了哪些设计模式?
项目中使用了很多的设计模式,我相信面试官最好听到的不仅仅是设计模式的名字,更想听到的是这些设计模式在项目中如何应用。因此,笔者认为这个问题隐式地说明了应该回答设计模式及其在项目中的应用。
参考答案:
-
单例设计模式:在项目中,单例是必不可少的。比如UIApplication、NSUserDefaults就是苹果提供的单例。在项目中经常会将用户数据管理封装成一个单例类,因此用户的信息需要全局使用。
-
MVC设计模式:现在绝大部分项目都是基于MVC设计模式的,现在有一部分开发者采用MVVM、MVP等模式。
-
通知(NSNotification)模式:通知在开发中是必不可少的,对于跨模块的类交互,需要使用通知;对于多对多的关系,使用通知更好实现。
-
工厂设计模式:在我的项目中使用了大量的工厂设计模式,特别是生成控件的API,都已经封装成一套,全部是扩展的类方法,可简化很多的代码。
-
KVC/KVO设计模式:有的时候需要监听某个类的属性值的变化而做出相应的改变,这时候会使用KVC/KVO设计模式。在项目中,我需要监听model中的某个属性值的变化,当变化时,需要更新UI显示,这时候使用KVC/KVO设计模式就很方便了。
就说这么多吧,还有很多的设计模式,不过其它并不是那么常用。
如何实现单例,单例会有什么弊端?
单例在项目中的是必不可少的,它可以使我们全局都可共享我们的数据。这只是简单的问题,大家根据自己的情况回答。
参考答案:
-
首先,单例写法有好几种,通常的写法是基于线程安全的写法,结合dispatch_once来使用,保证单例对象只会被创建一次。如果不小心销毁了单例,再调用单例生成方法是不会再创建的。
-
其次,由于单例是约定俗成的,因此在实际开发中通常不会去重写内存管理方法。
单例确实给我们带来的便利,但是它也会有代价的。单例一旦创建,整个App使用过程都不会释放,这会占用内存,因此不可滥用单例。
iOS是如何管理内存的?
我相信很多人的回答是内存管理的黄金法则,其实如果我是面试官,我想要的答案不是这样的。我希望的回答是工作中如何处理内存管理的。
参考答案:
-
Block内存管理:由于使用block很容易造成循环引用,因此一定要小心内存管理问题。最好在基类controller下重写dealloc,加一句打印日志,表示类可以得到释放。如果出现无打印信息,说明这个类一直得不到释放,表明很有可能是使用block的地方出现循环引用了。对于block中需要引用外部controller的属性或者成员变量时,一定要使用弱引用,特别是成员变量像_testId这样的,很多人都没有使用弱引用,导致内存得不到释放。
-
对于普通所创建的对象,因为现在都是ARC项目,所以记住内存管理的黄金法则就可以解决。
使用过哪些第三方库?
开发过App,如果回答说没有使用过第三方库,那么这个人一定是刚入门。如果回答者能够说出很多有名的第三方库,并且能说明使用场景,那么可以突出这个面试者的知识面还是很广的,这是可以加分的。
参考答案:
关于常用的第三方库,笔者整理了一下自己常用的库,但并不是全部:http://www.henishuo.com/ios-thirdparty/
对多线程了解吗?
对GCD熟悉吗?iOS中实现多线程有哪些方式?与这些问题一样,都是考查多线程的知识。
参考答案:
关于GCD,请阅读:GCD由浅入深学习
关于多线程NSOperation,请阅读:iOS多线程NSOperation/Queue
问题来源
部分问题来源于github上,笔者也是在看到之后,花时间回答了一下,大家可以参考问题,但是无参考答案:https://github.com/lzyy/iOS-Developer-Interview-Questions
还有一部分是笔者提的问题!!!
写在最后
所有参考答案都是笔者亲自一字一句敲出来的,都是根据笔者的情况而写的参考答案,不具有代表性,仅供参考。