论一次iOS面试
最近觉得现在所在公司平台用户量太少,自身技术已经到了一个瓶颈,是时候需要换一个用户量多的平台,好好研究下iOS的性能优化、内存优化等问题了。
所面试的公司由于一些默认的规定,就不多说了,大致是面了一个下午,从2点到下午6点半,正式拿到offer,先从笔试题开始说起吧。
笔试题:15道题,稍微有些多了,做了将近一个半小时。从笔试题就可以稍微看出一个公司的iOS团队技术水平如何,以及他们是不是真的想要招人。我春节之前投过一波简历,当时挑了一家公司去,还没技术面,只是看了他们的面试题,就知道了这个公司大概不会录用我,因为那面试题太水了,一看就是百度过来还没有筛选的。做完之后,面我的面试官就和我说,这套面试题从他入职以来到现在就没换过,我就呵呵了,明显是没招人的打算,叫我过来纯属浪费时间。
第一道,是C\OC\C++里面的一些常识吧,就是nil、Null、Nil的区别
这道题我答的不好,只是从C\OC语法的角度上解释了下它们的区别,回来百度下,看了其他人的回答,该这么写:
nil和null从字面意思来理解比较简单,nil是一个对象,而NULL是一个值,我的理解为nil是将对象设置为空,而null是将基本类型设置为空的,个人感觉有点像属性当中,基本类型分配为assign NSString类型一般分配copy,而对象一般用retain。而且我们对于nil调用方法,不会产生crash或者抛出异常。
nil是一个对象指针为空,Nil是一个类指针为空,NULL是基本数据类型为空。这些可以理解为nil,Nil, NULL的区别吧。
第二道,UIEvent与UITouch的异同
我当时的回答是,UIEvent对象包含一个UITouch对象,这是错误的。实际开发中,我经常用到touches系列API,但是基本没关注UIEvent对象:
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
[[touches anyObject] locationInView:self.view];
}
经常这么用,主要关注的是UITouch对象,谷歌过来,关于UITouch:
当用户手指触摸屏幕,就会创建一个与这根手指相关联的对象,一根手指对应一个UITouch对象,它保存着与手指相关的信息,比如手指触摸的位置、时间、阶段。
UIEvent对象:
每产生一个事件,就会产生一个UIEvent对象,它称为事件对象,记录事件产生的时刻和类型。
第三道,响应者链条,这是妥妥的送分题,不详细解释了。
第四道,好像是关于assign\copy\retain\nonatomic\atomic的使用场合吧,也算是送分题,需要注意的是,即使是atomic也不能保证线程安全的,这个我测试过,相应的资料谷歌下,应该有的。
第五道,好像是为什么delegate用assign,而不用retain,送分题,不解释。
第六道,就是说,一个autoreleasepool在什么时候被销毁?
如果不知道RunLoop机制,这里建议回答,在线程被销毁之前会销毁autoreleasepool,对pool立面的所有对象做一次release操作。
正确的回答,应该是在RunLoop进入休眠之前,会销毁pool,在RunLoop被唤醒时,会创建pool,但是,你既然这么写了,就要做好面试官问你RunLoop相关知识的准备。
第七、八、九、十道,基本就是MRC的内存管理,判断是否正确以及纠错。
比如说:
NSString *name = [[NSString alloc] initWithString:@"lisi"];
[name retain];
[name release];
[name autorealse];
需要在后面写出reationCount的值,一开始我比较蒙的是,autorealse到底在啥时候会对name进行一次release操作,然后想了下,要进行release操作,肯定是要这个RunLoop进入休眠时,而在这样一个状态,RunLoop并未进入休眠......
实际上也证明我是正确的:Autorelease实际上只是把对release的调用延迟了,对于每一个Autorelease,系统只是把该Object放入了当 前的Autorelease pool中,当该pool被释放时,该pool中的所有Object会被调用Release。那么pool在啥时候被销毁?上面那个题目已经有解释了。
第十一、十二、十三道,貌似忘记了,不是送分题,但也没有很大难度的题,没啥印象了。
第十四、十五道,是算法题,第十四题,我没看懂出题人的意思?!看了好几遍,没看懂,唯一空白的一个题目。
第十五题,是将两个有序链表合并成一个有序链表,分分钟秒了它。
第一面,应该是iOS负责人。
大概聊了将近两个小时吧,挺认真负责的,技术非常好。他所提的比较有印象的面试问题:
1、RunLoop,于是我便把我理解的RunLoop详细说了说,大致就是下面这些东西:
RunLoop:运行循环,一个iOS程序的从main函数进入UIApplicationMain,UIApplicationMain就开启了一个RunLoop,这个RunLoop是主线程的RunLoop,也就是Main RunLoop,它的作用是让我们的OC程序一直运行。
实际上,我们可以把RunLoop认为是一个死循环,它在这个循环内,不断的休眠与重启,从而保持程序的运行,处理程序的各种事件。例如:
do
{
}while(1);
iOS中有两套API来使用和访问RunLoop,一个是Foundation下的NSRunLoop,一个是Core Foundation下的CFRunLoopRef,(NSRunLoop是基于CFRunLoopRef的一层OC包装)。
RunLoop与线程的关系:
每一个线程都有与之相对应的RunLoop,只有主线程的RunLoop是默认开启的,子线程的RunLoop需要我们手动开启。
RunLoop在第一次获取时创建,在线程结束时销毁。
[NSRunLoop CurrentRunLoop]
[NSRunLoop MainRunLoop]
CFRunLoopGetCurrent()
CFRunLoopGetMain()
Core Foundation中runLoop相关的五个类
CFRunLoopModeRef:
代表着RunLoop的运行模式,RunLoop在一个时间点只能运行一种模式,比如说要么是defaultMode,要么是TrackingMode
一个RunLoop包含若干个Mode,每个mode又包含若干个Source\Timer\observer
如果需要切换Mode,只能是先退出Loop,再重新指定一个Mode进入
这样做的目的主要是为了分割开不同组的Source/Timer/Observe,让他们互不影响。
CFRunLoopSourceRef :系统的一些点击、拖拽等事件,相当于一个事件源
CFRunLoopTimerRef : 定时器相关的处理
CFRunLoopObserverRef : 实际上,我们是可以监听RunLoop的活动的,比如说监听它是否开启、是否将要进入休眠等。
这两种RunLoop使我们在日常编程中经常用到的:
kCFRunLoopDefaultMode:App的默认Mode,通常主线程是在这个Mode下运行
UITrackingRunLoopMode:界面跟踪 Mode,用于 ScrollView 追踪触摸滑动,保证界面滑动时不受其他 Mode 影响
在OC中,几种常见的Mode
NSDefaultRunLoopMode
UITrackingRunloopMode : 需要注意,这种模式下的Mode,是只能处理UIScrollView、或者继承自UIScrollView的对象的拖拽等事件的,也就是说,当UIScrollView在滚动的时候,是进入UITrackingRunloopMode,在默认条件下,Timer是添加在NSDefaultRunLoopMode下的,所以就不能处理Timer的相关事件。
(利用这样的一个特性,我们可以优化UITableView和UICollectionView的滚动,我们可以将图片的加载设置在NSDefaultRunLoop下,这样在滚动UITableView的时候,RunLoop会是UITrackingRunloopMode,就不会去加载图片,从而减少卡顿的现象出现,使得UI交互更加流畅)
还有一个NSRunLoopCommonMode,需要注意的是,它并不是真正的Mode,只是一个占位符
如果想要监听RunLoop状态的改变,有如下代码可以设置监听:
- (void)observer
{
//创建observer
CFRunLoopObserverRef observer = CFRunLoopObserverCreateWithHandler(CFAllocatorGetDefault(), kCFRunLoopAllActivities, YES, 0, ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) {
NSLog(@"监听到RunLoop状态发生改变 %zd", activity);
});
//添加监听者
CFRunLoopAddObserver(CFRunLoopGetCurrent(), observer, kCFRunLoopDefaultMode);
CFRelease(observer);
}
这是runLoop可以被监听的状态:
/* Run Loop Observer Activities */
typedef CF_OPTIONS(CFOptionFlags, CFRunLoopActivity) {
kCFRunLoopEntry = (1UL << 0), //进入,也就是开启runloop了的时候
kCFRunLoopBeforeTimers = (1UL << 1), //在处理所有定时器操作之前
kCFRunLoopBeforeSources = (1UL << 2), //在处理所有source源(点击等事件)之前
kCFRunLoopBeforeWaiting = (1UL << 5), //将要进入休眠状态
kCFRunLoopAfterWaiting = (1UL << 6), //将要苏醒的状态
kCFRunLoopExit = (1UL << 7), //退出runLoop
kCFRunLoopAllActivities = 0x0FFFFFFFU //以上所有的状态
};
@autoReleasePool在什么时候被释放?
它是在它所在的runLoop进入休眠时被释放,在runLoop再一次启动时创建。
当然,这些都是理论上的知识,实际中我们可以把imageView设置成在RunLoop的DefaultMode下显示,那么当UIScrollView,以及继承自UIScrollView的控件在拖拽的时候就不会显示ImageView,因为在滚动的时候,RunLoop是TrackingMode。
还可以开启一条常驻线程,这样就没必要多次创建子线程,造成性能上的损耗。
2、如果我们在开发中使用SDWebImage框架,会发现在UITableView滚动的停止的时候,它是优先下载显示在屏幕上的cell里面的图片的,这个效果如果让你来实现,你如何实现?
开发中我是经常使用SDWebImage框架的,但是没看过它的源代码,不过以前我做过不依赖SDWebImage框架的图片下载操作,那个时候是用NSOperation来实现的,还考虑到了重复下载的问题。
NSOperation是可以设置停止(暂停)的,这样的话,监听scrollView的滚动,当cell离开屏幕时,我们就把它设置为暂停下载状态,当它出现在屏幕时,再设置为开启下载状态。
面试官问我,是否还有其他的解决方案,(一脸蒙--)没有了。然后他提出了一种很好的解决方案,就是我们在设置并行队列的时候,是有一个优先值的,我们设置后面的image下载操作的优先级递增,这样的话,轻轻松松就解决了问题。
(好吧,我一直都在使用着默认的优先级,的确没考虑过这个问题,不过苹果文档也说了,建议开发者使用default优先级,因为如果优先级比较乱的话,可能会造成未知原因而导致程序崩溃,但这并不是理由,不知道就是不知道)。
3、问了下iOS里面工厂模式的使用场景,其实这个问题我在《Objective-C编程之道》上看到过,也知道它,但是那一瞬就是脑海一片空白,好吧,然后面试官和我说了,比如UIButton的类方法创建,里面是黑箱的,我们只是知道它会返回一个啥样类型button回来,类似的,NSValues等。(不得不说是幸运啊,刚好这个问题,在移动端负责人面我时候,我就举了这样的例子)
4、有三个网络请求需要发送,等三个网络请求发送完之后,要更新UI,怎么操作可以节省时间?
我第一个回答,觉得是直接使用dispatch_group来搞就好,不过面试官提醒了下我,就是一个网络请求发送完毕之后,等待数据返回还要一段时间,所以,dispatch_group是不行的。
然后,我觉得貌似只能一条条发送了,认真的想了下,其实是可以设置一个int属性,来记录是否都返回数据成功了,如果成功,就++,然后用kvo来监听这个属性就好。(当时回答是这么回答的,实际上应该用不到kvo来监听,可以直接重写该属性的setter方法)
还有其他的问题吧,不过印象不是很深刻了。
移动端负责人面试:
1、至此,第一面算是过了,心中松了一口气。这位面试官进来,先是问了我,iOS程序启动这之间的一系列过程,我回答的比较简单,从main->UIApplicationMain来开启一个主运行循环->Main RunLoop 开始处理各种source\observe\timer,从一个Mode到另一个Mode,然后调用appDelegate里面的application didFinish....那方法,进入KeyWindow......
2、把你所知道的设计模式其中思想都说说,举例说下应用场景
差点跪了,以前在看设计模式的时候,那理论太多了,记不住啊。然后只说出九种模式的思想,勉强算是过关了。
3、把所知道的排序算法手写出来
我在想,还好不是面试官来定某些算法,我所知道的并且能写的,冒泡、选择、快速、归并,写了下,算是过关了。
技术总监\经历面试
就是一个算法题,一个人上台阶,一次可以走一阶,走两阶,走三阶,那么如果有n阶,走法有多少种?
递推题,根据前面的规律,可以很容易推出,f(n) = f(n-1) + f(n-2) +f(n-3),然后用c语言把它写出来了。
之后就是人事面,顺利拿到offer。
ps:我辞职报告已经提交了,公司让我帮他面试iOS人员,我想说,那些培训的,写两年iOS工作经验,竟然和我说没学过C?对C不熟?作为一个计算机专业毕业的人,做数据结构的题,20道只正确7道,我去。这一行现在是有多乱,开的工资,10~~15k,还有一个15~~25k!真的是无知者无畏么?
论一次iOS面试的更多相关文章
- ios面试技术要点
iOS面试 技术总结点(可参考):多线程 运行时 runloop app框架 几种动画编程 jsonmodel原理 sdwebimage原理 masonry怎么应用及原理 应用框架有哪些 说一下Fac ...
- iOS 面试基础题目
转载: iOS 面试基础题目 题目来自博客:面试百度的记录,有些问题我能回答一下,不能回答的或有更好的回答我放个相关链接供参考. 1面 Objective C runtime library:Obje ...
- iOS面试贴士
iOS面试小贴士 ———————————————回答好下面的足够了------------------------------------- 多线程.特别是NSOperation 和 GCD 的内部原 ...
- IOS面试攻略
IOS面试攻略(1.0) 2013-10-13 20:58:09| 分类: IOS面试 | 标签:ios知识点总汇 ios面试 |举报|字号 订阅 来自:伊甸网 @ 看到这个关键字,我 ...
- C C++ OC iOS面试重点问题(一)
C C++ OC iOS面试重点问题(一) 1.字符串常量需要加\0 2.逻辑运算 位操作(经典:实现两个数的交换) 3.关键字 4.引用和指针的区别和联系 5.如何引用一个已经定义过的全局变量? ...
- IOS面试问题总结
IOS面试问题总结 分类: IOS开发2013-11-20 17:26 10458人阅读 评论(1) 收藏 举报 目录(?)[+] 通过网络搜寻和自己总结经历找了一些IOS面试经常被问道的问题 ...
- 十个iOS面试问题
十个iOS面试问题 十个iOS面试问题.不管对于招聘和应聘来说,面试都是很重要的一个环节,特别对于开发者来说,面试中的技术问题环节不仅是企业对应聘者技能和积累的考察,也是一个开发者自我检验的好机会. ...
- [转] 上级向的十个iOS面试问题
上级向的十个iOS面试问题 转自 http://onevcat.com/2013/04/ios-interview/ 不管对于招聘和应聘来说,面试都是很重要的一个环节,特别对于开发者来说,面试中的技术 ...
- iOS面试的算法相关
转自:https://www.jianshu.com/p/c4820b159159 面试中遇到的这些算法,在平常工作中,基本不会用到. 不过现实的面试中经常喜欢问关于算法的问题 有些还要求写出代码.一 ...
- 一些iOS面试基础题总结
一些iOS面试基础题总结 目录 多线程 AutoLayout objc_msgSend Runtime 消息转发 Category NSObject 与 objc_class Runloop Auto ...
随机推荐
- css 中字体大小
css属性font-size可以用来设置字体的大小, 可是有时候看到大小的设置是font:bold 20px/24px Verdana, Geneva, sans-serif; 这里的20px/24p ...
- lnmp memcache出问题
打开另一台用0.9装好的memcache 的PHP配置文件,找到了“extension = "memcache.so" ,将这个加入到了1.0的php.ini重启后 执行/memc ...
- centos7 安装 notejs
1.安装集成工具 yum -y install gcc make gcc-c++ 2.安装notejs 自行选择版本:https://nodejs.org/dist/ wget https://nod ...
- Django表单验证
从前端提交的各种数据可能存缺少必要字段以及包含非法数据等问题, 并且通常需要进行类型转换后才可以交由业务逻辑处理. 我们当然可以在控制器(Django的views函数)中完成这些工作, 但是这样会使控 ...
- [BTS] System.Xml.Schema.XmlSchemaException: The complexType has already been declared when generate IDoc schema.
I use wcf-sap adapter for generate the schema of IDoc that named "YHREMPMASTER". but throw ...
- Qt 二级菜单栏 中文无法输入问题
问题描述:Qt5.3.1版本在建立主界面的二级菜单的时候,中文无法输入,而英文确是可以输入的.(首先我在网页上面搜索了一下,他们说是Qt的设计问题.) 解决方法: (1)粘贴复制,把中文写在其他的地方 ...
- [python爬虫] Selenium定向爬取海量精美图片及搜索引擎杂谈
我自认为这是自己写过博客中一篇比较优秀的文章,同时也是在深夜凌晨2点满怀着激情和愉悦之心完成的.首先通过这篇文章,你能学到以下几点: 1.可以了解Python简单爬取图片的一些思路和方法 ...
- 常用dom对象
DOM:文档对象模型 --树模型 文档:标签文档,对象:文档中每个元素对象,模型:抽象化的东西 一:window: window.shuxing; 属性(值或者子对象): opener:打开当前窗口的 ...
- MySQL分区表
当数据库数据量涨到一定数量时,性能就成为我们不能不关注的问题,如何优化呢? 常用的方式不外乎那么几种: 1.分表,即把一个很大的表达数据分到几个表中,这样每个表数据都不多. 优点:提高并发量,减小锁的 ...
- 大家一起写mvc(三)_结束
上一篇介绍到要写mvc的所用的核心技术,这一篇我们就开始真正的开始写mvc,其实就是把昨天写过的代码进行一些组装就可以了. 我们用eclipse新建一个web项目.然后web.xml如下 <?x ...