iOS面试技巧及问题最全梳理,让BAT的Offer再也不难拿!

序言

目前形势,参加到iOS队伍的人是愈来愈多,甚至已经到供过于求了。今年,找过工做人可能会更深入地体会到今年的就业形势不容乐观,随着各大公司秋招的开始,不少小伙伴都行动起来了,我也有幸得到了一份不错的offer并和你们分享本身的经验心得。因为我面试公司比较多,因此天然也是作了这方面的准备,所以这篇总结并不必定适合想去创业公司的同窗。另外,因为经验原本就是主观性极强的东西,加之笔者水平有限,因此若是有不承认的地方,万望诸君呵呵一笑,抛之脑后。程序员

接下来,我就斗胆分享一下本身在准备和参加面试的过程当中的收获、对面试的思考,以及一些可能对你们有用的建议。但愿能助你们一臂之力!!面试

首先我要问你们几个问题算法

什么是面试编程

有些人可能会把面试看的过重,以为面试过了就能进入大厂,技术和财富兼得……设计模式

我却是以为,面试没有这么夸张(抱歉作了一回标题党),它实际上是一次你和面试官互相了解的绝佳机会,借此机会你还能够对将来的工做有初步的了解。数组

面试自己并不能彻底评价一我的的实力。面试经过的人,也许只是刚好在面试时遇到了本身熟悉的问题,面试不经过,也有多是面试官自身的问题,并不是每一个面试官都具有客观评价别人的能力。缓存

换句话说,面试没经过也许是面试官没有发现你的才华,面试经过了也并不表明你就能胜任工做,由于进入企业以后可不是天天负责回答面试题!安全

因此从这一点来看,面试有点像相亲。你满意我,我满意你,王八对绿豆——看上眼了,那就一拍即合,不然就分道扬镳。我本人很是但愿可以多几轮面试(实际并不老是能作到),这样你们都有充足的时间互相了解,决定去留。网络

网上某些面经中,介绍了一些“装逼”的方法,还有所谓的“面试技巧”,我是不太承认的。技巧须要有,这是为了让你更好的展现本身,而非坑蒙拐骗,无理取闹,无中生有。我更想展示一个真实的本身,若是面试官不承认,说明咱们没有缘分,或者说本身的能力还不够。多线程

面试要准备什么

有一位小伙伴面试阿里被拒后,面试官给出了这样的评价:“……计算机基础,以及编程基础能力上都有所欠缺……”。但这种笼统的回答并不是是咱们但愿的答案,所谓的基础到底指的是什么?

做为一名 iOS 开发者,我所理解的基础是 操做系统、网络和算法这三大块,不一样的开发方向可能有不一样的侧重,但基础总的来讲就是这些。我不推荐经过去网上看教程来学习这些基础知识,由于能用短短几篇文章讲明白的事情不叫基础,至少我没见过写得这么深刻浅出的文章。

不知道有多少读者和我同样有过这样的困扰:“我知道某些东西很重要,因此去百度查了资料,可是查到的文章质量不好,正确率没有保证”。这实际上是正常的,优秀的文章通常都放在优秀的做者的我的博客上,这偏偏是搜索引擎的盲区,因此通常只能搜到 CSDN、博客园这种地方的文章。天然就没法保证文章质量。因此拥有一个本身的iOS交际圈子就很重要。

在这里欢迎你们加入个人iOS交流群659170228,无论是小白仍是大牛,欢迎你们入驻,一块儿交流成长!

除了准备通用的基础知识之外,简历也是一个很重要的环节。一直很仰慕唐巧老师的猿题库,无奈简历太差,都没有收到面试邀请。后来好好改了简历之后,就没有这种问题了。关于简历的书写,推荐两篇文章:如何写面向互联网公司的求职简历、程序猿简历模板。你也能够参考个人简历,没有亮点,就当是抛砖引玉。

最后,固然是准备好相关岗位的基础知识了。做为 iOS 开发者,虽然 Swift 已经发布了快两年,可是大公司转向 Swift 的动做还不明显,因此 Objective-C 几乎是必备项,Swift 都不必定能算是加分项。iOS 方面的知识也必不可少,虽然招聘信息上写着若是基础扎实,零 iOS 基础也能够,可是现实每每是比较残酷的。

在这里有一些试探性的面试问题不知道你们会答的怎么样呢?

  • 您在工程中遇到过什么很难的问题?不管是特殊的交互方式、复杂动画、性能、安全问题…… 最后怎么解决的?

  • 展现您作过最复杂的一个界面 / 本身封装得比较好的组件,介绍它的结构和为何这么作;

  • 您在工程中作过哪些重构?作出了哪些改变,最后的效果如何?

  • 日常工程中用到哪些第三方开源库?您读过它们的源码吗?讲讲本身最熟悉的一个开源库的源码结构;

  • 下面给您看的这几张图是我上一期刚开发完的需求,若是让您开发的话,您能给出一个估时吗?其中有什么难点和风险点吗?

这些问题的好处是显而易见的,每一个人都能多少说上几句。回答大部分是“没有”、“没什么”的基本能够 pass 了,而优秀的工程师每每有不少内容可聊。

一些面试技巧

在这里我给各位小伙伴一些建议,开场白很是重要!通常HR开场都会让你们介绍一下本身的基本状况,说一说本身作过的项目以及负责过的模块。在这个环节,我以为各位应该把以前全部的紧张不安的情绪所有稳定下来,由于我相信这个问题,你们应该已经作好了充分的准备,而且应该要有足够的勇气跟自信来回答这些问题。这个阶段就有人被淘汰了,有的人表达得结结巴巴,不懂如何描述,或者先后不连贯,想到哪算哪,甚至对他的项目表述的都是一头雾水。这样的人在HR眼里就会以为他产品需求人员沟通必定会出大问题,误会和返工少不了,由于他无法表达清楚他作的项目的业务。

此外我以为你们扩充一下本身的知识广度是很是有必要的!从iOS的基础,底层,到音视频编码,逆向还有新的AR,coreML,你们对这些技术了解多少?也许由于项目经历所限,你没机会用过这些技术,可是随便上一些技术网站,都能了解到如今流行什么,这些技术是为了解决什么问题存在的,你看这些技术也说明你注意到了一些问题的存在。视野开阔的人,说明他的求知欲强。也许应聘者不少关于各类技术的回答是错的,可是HR能看出来你是想过仍是没想过,是有本身的一套认知仍是胡说八道。你说错不要紧,咱们团队里有懂的人,他之后会给你把观点改正过来,可是想都没想过,差距就显而易见。若是你能了解一些AR,coreML的知识 那么你就会在HR那里加分很多!

扯了这么多,让咱们进入重头戏

先来梳理一下iOS面试中常常会遇到的一些问题吧!

OC的理解与特性

OC做为一门面向对象的语言,天然具备面向对象的语言特性:封装、继承、多态。它既具备静态语言的特性(如C++),又有动态语言的效率(动态绑定、动态加载等)。整体来说,OC确实是一门不错的编程语言。

Objective-C具备至关多的动态特性,表现为三方面:动态类型(Dynamic typing)、动态绑定(Dynamic binding)和动态加载(Dynamic loading)。动态——必须到运行时(run time)才会作的一些事情。

简述内存管理基本原则

以前:OC内存管理遵循“谁建立,谁释放,谁引用,谁管理”的机制,当建立或引用一个对象的时候,须要向她发送alloc、copy、retain消息,当释放该对象时须要发送release消息,当对象引用计数为0时,系统将释放该对象,这是OC的手动管理机制(MRC)。

目前:iOS 5.0以后引用自动管理机制——自动引用计数(ARC),管理机制与手动机制同样,只是再也不须要调用retain、release、autorelease;它编译时的特性,当你使用ARC时,在适当位置插入release和autorelease;它引用strong和weak关键字,strong修饰的指针变量指向对象时,当指针指向新值或者指针不复存在,相关联的对象就会自动释放,而weak修饰的指针变量指向对象,当对象的拥有者指向新值或者不存在时weak修饰的指针会自动置为nil。

如何理解MVC设计模式

MVC是一种架构模式,M表示MOdel,V表示视图View,C表示控制器Controller:

Model负责存储、定义、操做数据;

View用来展现书给用户,和用户进行操做交互;

Controller是Model和View的协调者,Controller把Model中的数据拿过来给View用。Controller能够直接与Model和View进行通讯,而View不能和Controller直接通讯。View与Controller通讯须要利用代理协议的方式,当有数据更新时,MOdel也要与Controller进行通讯,这个时候就要用Notification和KVO,这个方式就像一个广播同样,MOdel发信号,Controller设置监听接受信号,当有数据更新时就发信号给Controller,Model和View不能直接进行通讯,这样会违背MVC设计模式。

如何理解MVVM设计模式

ViewModel层,就是View和Model层的粘合剂,他是一个放置用户输入验证逻辑,视图显示逻辑,发起网络请求和其余各类各样的代码的极好的地方。说白了,就是把原来ViewController层的业务逻辑和页面逻辑等剥离出来放到ViewModel层。

View层,就是ViewController层,他的任务就是从ViewModel层获取数据,而后显示。

NSNotification、Block、Delegate和KVO的区别

代理是一种回调机制,且是一对一的关系,通知是一对多的关系,一个对向全部的观察者提供变动通知;

效率:Delegate比NSNOtification高;

Delegate和Block通常是一对一的通讯;

Delegate须要定义协议方法,代理对象实现协议方法,而且须要创建代理关系才能够实现通讯;

Block : Block更加简洁,不须要定义繁琐的协议方法,但通讯事件比较多的话,建议使用Delegate;

使用block有什么好处?使用NSTimer写出一个使用block显示(在UILabel上)秒表的代码

  • 代码紧凑,传值、回调都很方便,省去了写代理的不少代码。

  • NSTimer封装成的block,具体实现

  • 实现方法:


有2种方法解决:一个view已经初始化完毕,view上面添加了n个button,除用view的tag以外,还能够采用什么办法来找到本身想要的button来修改button的值

第一种:若是是点击某个按钮后,才会刷新它的值,其它不用修改,那么不用引用任何按钮,直接在回调时,就已经将接收响应的按钮给传过来了,直接经过它修改便可。

第二种:点击某个按钮后,全部与之同类型的按钮都要修改值,那么能够经过在建立按钮时将按钮存入到数组中,在须要的时候遍历查找。

线程与进程的区别和联系?

  • 一个程序至少要有进城,一个进程至少要有一个线程.

  • 进程:资源分配的最小独立单元,进程是具备必定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位.

  • 线程:进程下的一个分支,是进程的实体,是CPU调度和分派的基本单元,它是比进程更小的能独立运行的基本单位,线程本身基本不拥有系统资源,只拥有一点在运行中必不可少的资源(程序计数器、一组寄存器、栈),可是它可与同属一个进程的其余线程共享进程所拥有的所有资源。

  • 进程和线程都是由操做系统所体会的程序运行的基本单元,系统利用该基本单元实现系统对应用的并发性。

  • 进程和线程的主要差异在于它们是不一样的操做系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不一样执行路径。线程有本身的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,因此多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。

  • 但对于一些要求同时进行而且又要共享某些变量的并发操做,只能用线程,不能用进程。

多线程编程

  • NSThread:当须要进行一些耗时操做时会把耗时的操做放到线程中。线程同步:多个线程同时访问一个数据会出问题,NSlock、线程同步块、@synchronized(self){}。

  • NSOperationQueue操做队列(不需考虑线程同步问题)。编程的重点都放在main里面,NSInvocationOperation、BSBlockOperation、自定义Operation。建立一个操做绑定相应的方法,当把操做添加到操做队列中时,操做绑定的方法就会自动执行了,当把操做添加到操做队列中时,默认会调用main方法。

  • GCD(`Grand Central Dispatch)宏大的中央调度,串行队列、并发队列、主线程队列;

  • 同步和异步:同步指第一个任务不执行完,不会开始第二个,异步是无论第一个有没有执行完,都开始第二个。

  • 串行和并行:串行是多个任务按必定顺序执行,并行是多个任务同时执行;

  • 代码是在分线程执行,在主线程嘟列中刷新UI。

多线程编程是防止主线程堵塞、增长运行效率的最佳方法。

  • Apple提供了NSOperation这个类,提供了一个优秀的多线程编程方法;

  • 一个NSOperationQueue操做队列,至关于一个线程管理器,而非一个线程,由于你能够设置这个线程管理器内能够并行运行的线程数量等。

  • 多线程是一个比较轻量级的方法来实现单个应用程序内多个代码执行路径。

  • iPhoneOS下的主线程的堆栈大小是1M。第二个线程开始就是512KB,而且该值不能经过编译器开关或线程API函数来更改,只有主线程有直接修改UI的能力。

定时器与线程的区别;

  • 定时器;能够执行屡次,默认在主线程中。

线程:只能执行一次。

关于面试问题方面就先梳理到这,固然这确定不是所有只是一部分,接下来我给你们分享一下个人经历吧!

这里就列举个人两次面试经历吧

公司一

一面:约 1.5 小时

首先是四个算法题:

  1. 不用临时变量怎么实现 swap(a, b)——用加法或者异或均可以

  2. 二维有序数组查找数字——剑指 offer 第 3题

  3. 亿级日志中,查找登录次数最多的十个用户——(不肯定对不对,个人思路是)先用哈希表保存登录次数和ID,而后用红黑树保存最大的十个数。剑指 offer 第 30题

  4. 简述排序算法——快排partion函数的原理,堆排(不稳定),归并排序,基数排序。

最后是 iOS 相关,面试官问的很开放,都是谈谈本身的理解

  1. 说说你对 block 的理解。—— 三种 block,栈上的自动复制到堆上,block 的属性修饰符是 copy,循环引用的原理和解决方案。

  2. 说说你对 runtime 的理解。——主要是方法调用时如何查找缓存,如何找到方法,找不到方法时怎么转发,对象的内存布局。

  3. 说说你对 MVC 和 MVVM 的理解。—— MVC 的 C 太臃肿,能够和 V 合并,变成 MVVM 中的 V,而 VM 用来将 M 转化成 V 能用的数据。

  4. 说说 UITableView 的调优。——一方面是经过 instruments 检查影响性能的地方,另外一方面是估算高度并在 runloop 空闲时缓存。

  5. 谈谈你对 ARC 的理解。ARC 是编译器完成的,依靠引用计数,谈谈几个属性修饰符的内存管理策略,什么状况下会内存泄露。

一面的问题很是基础,主要是算法和 Objective-C,由于准备比较充分,基本上答出来 80% 吧。大约一周后忽然二面。

二面:约 0.5 小时

二面比较忽然,显示简单的自我介绍,而后问了三个问题:

  1. 野指针是什么,iOS 开发中什么状况下会有野指针?——野指针是不为 nil,可是指向已经被释放的内存的指针,不知道何时会有,若是有知道的读者还望提醒。

  2. 介绍 block。—— (接第一问) 我让面试官提示我一下何时会有野指针,他说用 block 时,我表示仍是不知道,只知道 block 会有循环引用。因而就扯回了一面的问题。

  3. 说说你是怎么优化 UITableView 的。——仍是一面的问题。。。。。。。。。。。

虽然经过了,可是几乎又问了一遍一面的问题让我感受对方不太认真。

公司二

笔试

主要是计算机方面的大杂烩,涉及操做系统,网络,移动开发,算法等。难度不大,目测是为了淘汰浑水摸鱼的人,就不列出题目了,算法有三题,直接在线写(木有 IDE 表示很忧伤):

  1. 很长一道题,读了好久才读懂,目测是 DFS,可是最后没时间了,写了个思路。

  2. 把 "www.zhidao.baidu.com" 这样的字符串改为 "com/baidu/zhidao/www"。——老题目了,剑指 offer 的,两次逆序排列便可。

  3. 求数组中和为某个值的全部子数组,好比数组是 [5,5,10,2,3] 一共有四个子数组的和是 15,好比 [5,10][5,10][10,2,3][5,5,2,3]。这个就是简单的递归了,分两种状况,当前位置的数字在子数组中,以及不在子数组中。

面试

所有是 iOS 题,多是以为算法已经面过了

  1. 介绍 block。——我提到栈上的 block 在 ARC 下会自动复制到堆上,面试官问我从 iOS 4 仍是 5 开始支持这一特性,表示不知道,我又不是学 OC 历史的,后来想一想多是公司内部老项目有这个坑

  2. 介绍一下 MVVM 和 RAC。——多是我简历的某个角落写了用过 RAC,被挖出来了,大概谈了一下,结果面试官问我数据的双向绑定怎么作,bind函数了解过么,果断说已经忘了

  3. 介绍本身用过哪些开源库。——Masonry 和 SnapKit,AFNetWorking,MKNetworkKit,Alamofire,Mantle,SDWebImage

  4. SDWebImage 下载了图片后为何要解码?——当时蒙住了,面试官很 nice 的解释了一下,说是要把 png 文件创建一个什么内存映射,目前还不太懂,有空研究一下。

面试收获,注意看!!很是重要!!

1.给本身写一份很是专业的简历

个人建议是,若是你想增长本身的入选机会,那最好仍是花点钱制做一份专业的简历。相较于你未来可能获得的巨大收获,这真的只是一个小小的投资。

2.研究面试官

当HR联系程序员来面试的时候,他老是会事先发电子邮件给他,并附上他的名字和博客地址。可是让我惊讶的是,当不少小伙伴去面试的时候,他居然对HR仍是一无所知。

举个正面的例子,当HR在面试时遇到一位开发人员,甚至能对他之前写的一篇博客或者作的教学视频上面的内容侃侃而谈。

你说HR会推荐哪一个?

面试官也是人,也会有人性的弱点和特色。Dale Carnegie曾说过,要让别人对你感兴趣,最简单的方法就是你先表达出对对方的兴趣。

无论这种方法是否有欠公正,可是若是你想面试成功,那么我建议你事先最好先好好研究一下你应聘的这家公司和面试官(若是知道的话)。

当今社会的信息是如此的发达,咱们彻底能够在贴吧、论坛、微博、博客上找到任何人的资料。即便你只是大体浏览一番,也会让你受益良多。

3.得到内部推荐

知道找工做最简单的方法是什么吗?那就是得到内部推荐。

这不但能够增长面试机会,还能提高40%的录用概率。

讲一下我之前的一次经历吧,我找到了一家心仪的公司。而后直接投简历?NONO,猜猜我是怎么作的吧?

首先我找到一名和我有共同想法和意见的开发人员,而后开始关注他的博客。

接着我在他的博客中留言、发表建议,而且表现出对他的工做和公司很是感兴趣的想法。最后我成功拿到了这个宝贵的内部推荐资格。

不少程序员会说,“但是,某某某公司里面的人我一个也不认识啊”。若是你想就此放弃,那当我什么也没说,若是你愿意试试,我敢打赌,你总能想出一种方法达到你的目的。

不过这有个秘诀,那就是首先你得在网上建立本身的“名片”——让别人有了解你的机会,因此do it now吧。

4. 学会解决算法问题

这是每个开发人员都应该具有的重要技能,并且真要掌握起来也并不是那么难。

在不少面试中,都会有这样的问题,要求你在白板或者电脑上解决编程问题,可是许多程序员,即便是那些很是优秀的程序员,都会一会儿大脑一片空白,彻底理不出思路来。

若是你能花时间学会如何解决这种类型的面试问题,那么下次再碰到这种场景,就不会这么紧张了。

咱们会紧张其实和怯场无关,主要是由于咱们不熟悉这些问题,也没有自信能解决这种问题。

在这方面创建起自信以后,你就不再会紧张了。

5.活力洋溢地回答问题

只用一个字或者一句话,照本宣科平平无奇地回答问题,或许在技术上是正确的,可是你忘了应该借此机会好好展现本身的激情——这才是一个开发人员能带给团队的最大正能量。

举个例子说,若是我问你什么是多态性,我不是要你按照课本中的定义重复给我听,我但愿你能就这个主题阐述一下,而后咱们能够更深刻地聊一聊。

6.当心陷阱问题

你为何换工做?

说说你最大的优势和缺点。

最近一次你是如何解决和同事之间发生的技术分歧的?

在回答问题以前,你最好明白面试官问这些问题的目的,掌握如何回答这类问题的技巧。

就先说说第一个问题吧“你为何换工做?”

在大多数状况下,面试官想知道的是你是不是一个爱说三道4、惯于诽谤抨击雇主的人。因此千万不要上当。

7. 遇到真的不会的问题怎么处理

遇到不会的问题果断认可啊。若是是基本问题,好比问你哈希表怎么实现,你说不会,那么此次面试可能就悬了。若是是有必定难度的问题,那么你认可不会,也是一种明智之举,毕竟人无完人,一个问题不会并不能全盘否认一我的的能力。

可是比较糟糕的一种状况是,面试者因为过度紧张,担忧答不上面试官的问题会有严重后果,因此尝试着去敷衍面试官。好比:“我猜是 xxx 吧”,“我以为多是 ……”,更有甚者直接装逼:“这个我试过,不就是 xxx 么”。要知道,此时的你,因为紧张,在心态上已经输给了面试官,更况且面试官问你的问题必定是他有把握的,你以为这时候你负隅顽抗会有几成胜算呢?

因此,面试官问我“堆排序”的细节时,因为我当时忘了堆排序是怎么实现的,因此我直接告诉他我记不清了。另外一个主动认输的例子是面试官问我 RAC 如何实现双向绑定,我告诉他这个是我当时学习的时候写过的 demo,由于不经常使用,已经只记得一些简单的概念了。

最后,还须要保持一个平稳的心态:“面试时尽力就好,遇到本身不会的问题也是正常状况”。若是面试者顺利答对了全部问题,不免会让面试官感到一丝尴尬,面试者也有可能会产生一些别的情绪。因此,咱们要作的只是把本身的能力展现给面试官,作到不骄不躁。

今天给你们的分享就到这吧!你们若是以为写的不错能够点一波关注收藏!还能够加入个人iOS交流群659170228,你们一块儿交流成长!!

相关文章
相关标签/搜索