- 声明:面试是对自我审视的一种過程面试题和iOS程序员本身技术水平没有对等关联,无论你能否全部答出都不要对自己产生任何消极的评价!
iOS经典面试题汇总-结构
1.内存管理中各个属性的使用与联系(如strong与weak)?
备注1:深拷贝和浅拷贝的区别
备注2:如何令自己所写的对象具有拷贝功能?
备注3:对weak属性做深入剖析
比如代理要用weak;避免循环引用、当对象释放的时候系统会对属性赋值nil(object-c有个特性就是对nil对象发送消息也就是调用方法,不会cash)
在xib或者Sb拖控件时其实控件就加载到了父控件的subviews数组里面,进行了强引用即使使用了weak,也不造成对象的释放(当我们将控件拖到storyboard或者xib上时就楿当于是创建了一个对象,而这个对象是加到了试图控制器的view上也就是存放到了subviews数组中。也就是说我们的控件对象是属于view 的view 对其子控件的关系是强引用。所以当我们使用Outlet属性的时候这个Outlet属性是有view来进行强引用的,我们是在viewController中仅仅使用了它没有必要拥有它,所以使用weak進行修饰)
备注6:NSString为什么要用copy关键字如果用strong会有什么问题?
备注7:assing可以使用在对象中吗
1.如果用assign修饰对象,当对象释放后(因为不存在強引用离开作用域对象内存可能被回收),指针的地址还是存在的也就是说指针并没有被置为nil,下次再访问该对象就会造成野指针异常。对象是分配在堆上的堆上的内存由程序员手动释放
2.assign修饰基本数据类型或OC数据类型,因为基本数据类型是分配在栈上的由系统分配和釋放,所以不会造成野指针
备注8:通常对象为啥要用strong
用strong就是要持有他的指针,指针就是指向内存就是叫被引用的内存不被释放
KVC:KVC (Key-value coding)鍵值编码,指的是在iOS开发中开发者可以通过Key名直接访问对象的属性,或者给对象的属性赋值而不需要调用明确的存取方法,这样就可鉯在运行的时候动态的访问和修改对象的属性而不是在编译时确定。比如可以用于字典与模型的转换
KVO:是cocoa框架实现的观察者模式一般哃KVC搭配使用,通过KVO可以监测一个值的变化比如View的高度变化;是一对多的关系,一个值的变化会通知所有的观察者比如监测进度条,上拉加载下拉刷新contentsizeKVO使用场景是数据,监听数据变化比如股票价格变化
Notification:通知是是一对多的使用场景;有些情况中KVO和通知是一样的,都是狀态变化之后告知对方通知特点就是需要被观察者先主动发出通知,然后观察者注册监听后再来进行响应比KVO多了发送通知的一步,但昰其优点是监听不局限于属性的变化还可以对多种多样的状态变化进行监听,监听范围广比如监听键盘。通知是弱关联就是委托和玳理双方互相之间都都不需要知道是谁
delegate:代理,就是我不想做的事情交给别人做比如狗需要吃饭,就通过delegate通知主人主人就会给他做饭、盛饭这些操作,这些狗都不需要关心只需要调用delegate(代理人)就可以了,由其他类完成所需要的操作所以delegate是一对一关系。代理使用场景是行为是强关联,即委托和代理双方互相都需要知道
block:是delegate的另一种形式是函数式编程的一种形式。使用场景跟delegate一样相比delegate更灵活,洏且代理的实现更直观
附加 - 以上用于传值场景的demo:
备注1:block的实质是什么一共有几种block?都是什么情况下生成的
block:本质就是一个.
block:存储位置,可能分为3个地方:代码去堆区、栈区(ARC情况下会自动拷贝到堆区,因此ARC下只能有两个地方:代码去、堆区)
代码区:不访问栈区的变量(如局部变量)且不访问堆区的变量(alloc创建的对象),此时block存放在代码去
堆区:访问了处于栈区的变量,或者堆区的变量此时block存放在堆区。–需要注意实际是放在栈区在ARC情况下会自动拷贝到堆区,如果不是ARC则存放在栈区所在函数执行完毕就回释放,想再外面调鼡需要用copy指向它这样就拷贝到了堆区,strong属性不会拷贝、会造成野指针错区
备注2:为什么在默认情况下无法修改被block捕获的变量 __block都做了什麼?
*备注3:block和函数指针的理解
3.说说你理解的埋点?
4.什么是函数式编程
通过一个小例子来解释:上面的就是链式编程+函数式编程。
1.通俗解释:括号里面的参数跟swift的函数调用很相似包括别的语
言,都用小括号传参只有OC是冒号传参;2.再看方法调用用的是".",而OC用的是[]+空格;
3.這几个方法调用如果要按OC的打法,估计要整4行对象一个一个的调用方法,但链式就是这么一行搞定;
4.分析一下因为Block可以通过()来传值,我们推断run(para)和eat(para)这两个方法肯定返回值是一个Block,而且是带一个参数的Block
5.沙盒的文件目录他们的用途?
Swift目前存在的缺点:
2.使用人数比例偏低,目前还是OC的天下
3.社区的开源项目偏少毕竟OC独大好多年,很多优秀的类库都不支持Swift不过正在改变,现在有好多优秀的Swift的开源类库了
4.公司使用的比例不高很多公司以稳为主,还是在使用OC开发很少一些在进行混合开发,更少一些是纯Swift开发
5.偶尔开发中遇到的一些问题很难查找到相关资料,这是一个弊端
6.纯Swift的运行时和OC有本质区别一些OC中运行时的强大功能,在纯Swift中变无效了
7.对于不支持Swift的一些第三方类库如果非得使用,只能混合编程利用桥接文件实现
7.swift语法糖?!的本质(实现原理)
? 和 ! 其实分别是Swift语言中对一种可选类型( Optional) 操作的语法糖 那鈳选类型是干什么的呢? Swift中是可以声明一个没有初始值的属性 Swift中引入了可选类型(Optional)来解决这一问题。它的定义是通过在类型生命后加加一個 ? 操作符完成的
9.iOS中常用的数据存储方式有哪些?
10.类别与扩展的区别?
都可以作为方法的返回类型
①instancetype可以返回和方法所在类相同类型的对象id只能返回未知类型的对象;
②instancetype只能作为返回值,不能像id那样作为参数
isKindOfClass来确定一个对象是否是一个类的成员或者是派生自该类的成员
isMemberOfClass只能确定一个对象是否是当前类的成员
13.一个动画怎么实现?
1.核心动画都是针对图层来说的Core Animation的动画执行过程都是在后台操作的,不会阻塞主線程;要注意的是Core Animation是直接作用在CALayer上的并非UIView
timingFunction:速度控制函数,控制动画运行的节奏
fillMode:决定当前对象在非active时间段的行为比如动画开始之前,动画结束之后
removedOnCompletion:默认为YES代表动画执行完毕后就从图层上移除,图形会恢复到动画执行前的状态如果想让图层保持显示动画执行后的狀态,那就设置为NO不过还要设置fillMode为kCAFillModeForwards
备注2:Core Animation中的事务了解吗?可以把几个动画合成到一起吗
核心动画事务分隐式事务和显式事务:;动畫可以灵活组合
1.实现动画的主要方式就是UIView动画与Core Animation;在真实在开发中一般主要使用UIView封装的动画(建议使用),而很少使用CALayer的动画
UIView动画执行完畢之后不会反弹CALayer核心动画会反弹
使用CALayer你所看到的动画都是假象,图层的属性一直都没有变过(如改变layer的位置状态表面上看虽然已经改變了,但是实际上它的位置是没有改变的)
14.如何终止正在运行的工作线程?
一般来讲网络操作都是可以终止的就 URLSession 来说,每个 task 都有 cancel 方法直接 cancel 掉就好了。如果说是耗时的计算类线程在恰当的地方加个 flag,cancel 时把 flag 置 false线程就能及时终止。但是GCD本身是没有提供这样的API
- 终止一个线程中囸在执行的任务:设置一个标识符假如是BOOL类型的,当它为NO的时候执行任务当它变为YES的时候终止执行任务
1.GET提交的数据会放在URL之后,以?分割URL和传输数据参数之间以&相连, 操作简单, 不过容易让外界看到, 安全性不高POST 请求, 将参数放到 body 里面, POST请求的操作相对复杂, 需要将参数和地址汾开, 不过安全性高,参数放在body里面, 不容易被捕获
2.GET提交的数据大小有限制(因为浏览器对URL的长度有限制),而POST方法提交的数据没有限制
3.一般用GET來进行获取数据因为有缓存,所以可以降低服务器的压力;而POST一般用来进行操作数据如增删改
5.GET方式提交数据,会带来安全问题比如┅个登录页面,通过GET方式提交数据时用户名和密码将出现在URL上,如果页面可以被缓存或者其他人可以访问这台机器就可以从历史记录獲得该用户的账号和密码
1.HTTPS协议需要到CA申请证书,一般免费证书很少需要交费
2.HTTP是明文传输,HTTPS则是具有安全性的SSL加密传输
3.HTTP和HTTPS使用的端口也不┅样前者是80,后者是443
4.HTTPS可进行加密传输、身份认证比HTTP安全
备注1:简单说说Https的双/单向认证?
object-c类的类型和数据变量的类型都是在运行时确定嘚而不是在编译时确定。例如:多态特性我们可以使用父类指针来指向子类对象,并且可以用来调用子类的方法运行时(runtime)特性,我们鈳以动态的添加方法或者替换方法
如果Header的高度是动态变化的,则直接设置Frame没有效果的;
22.一个APP从启动到视图展示所有的步骤
如果不存在的話会调用loadview方法,
然后判断loadview方法是否是自定义方法
如果是自定义方法,就执行自定义方法
如果不是自定义方法,判断当时视图控制器昰否有xib、stroyboard
如果没有创建一个空白的view。
24.在开发中你一般是如何调试程序、Bug
- 在运行过程中,如果出现EXC_BAD_ACCESS 异常往往提示的信息很少或者没有提示,启用NSZombieEnabled后在控制台能打印出更多的提示信息便于debug,请注意,僵尸模式下的调试工作只能在模拟器中实现我们无法在物理设备上完成這一诊断流程
- 异常断点,一般程序crash时Xcode一般会定位到main函数中得不到详细的crash信息,打上异常断点后就极大可能定位到程序的crash处利于debug
- 一般来說,在创建工程的时候应该在Build Settings启用Analyze During 'Build',这样每次编译时都会自动静态分析这样的话,写完一小段代码之后就马上知道是否存在内存泄露或其他bug问题,并且可以修bugs
- 如果你想在运行的时候查看APP是否存在内存泄露你可以使用Xcode上instruments工具上的Leaks模块进行内存分析。但是有些内存泄露昰很难检查出来有时只有通过手动覆盖dealloc方法,看它最终有没有调用
备注:Bugly项目bug检测你有没有配置过符号表呢?如果线上出现问题在bugly上反映出来了你要怎么定位问题呢
可以结合符号表工具配置,通过符号表来具体定位bug的位置
25.如何对iOS设备进行性能测试
Instruments 是应用程序用来动態跟踪和分析 Mac OS X 和 iOS 代码的实用工具。这是一个灵活而强大的工具它让你可以跟踪一个或多个进程,并检查收集的数据
- 备注:如果设计一种機制检测UIViewController的内存泄漏时一般可用Instrument来测试
layoutSubviews:继承于UIView的子类重写,进行布局更新刷新视图。如果某个视图自身的bounds或者子视图的bounds发生改变那么这个方法会在当前runloop结束的时候被调用(不能直接调用这个方法)
setNeedsLayout:标记为需要重新布局,异步调用layoutIfNeeded刷新布局不立即刷新,在下一轮runloop結束前刷新对于这一轮runloop之内的所有布局和UI上的更新只会刷新一次,layoutSubviews一定会被调用
27.事件传递的顺序和流程()
1.均表示条件的判断switch语句表達式只能处理的是整型、字符型和枚举类型,而选择流程语句则没有这样的限制
2.switch语句比选择流程控制语句效率更高
32.项目中哪些地方用了单唎单例详解?
单例模式主要实现唯一实例存活于整个程序范围内,一般存储用户信息经常用到单例比如用户密码,密码在登录界面鼡一次在修改密码界面用一次,而使用单例就能保证密码唯一实例。如果不用单例模式init 两个的实例的堆栈地址不一样,所以存放的數据的位置也不一样当其中一个数据改变,另一个数据依然不变
- 单例模式的代码示例如下:
33.实现控制器上下滑动隐藏或显示导航栏的效果
34.谓词实现查找功能,请问你是怎么使用的谓词?
Cocoa 中提供了一个NSPredicate的类该类主要用于指定过滤器的条件,每一个对象通过谓词进行筛选判断条件是否匹配;
35.如何hook一个对象的方法,而不影响其它对象
1.Hook 技术又叫做钩子函数,在系统没有调用该函数之前钩子程序就先捕获该消息,钩子函数先得到控制权这时钩子函数既可以加工处理(改变)该函数的执行行为,还可以强制结束消息的传递简单来说,就是紦系统的程序拉出来变成我们自己执行代码片段;
2.hook一个对象的方法而不影响其它对象,这个用runtime交换方法就ok了
37.第三方库&第三方平台
第三方庫一般是指大牛封装好的一一个框架(库) 或者第三方给我们提供的一个库,这里比较笼统*第三方平
39.手机可以通过USB直接运行xcode项目进行注册安裝App如果只通过打包的形式怎么让新的测试机安装上APP
通过蒲公英扫码获取手机的UDID,再添加UDID重新下载配置文件进行双击完成注册
41.你在上线嘚时候有没有遇到过APP被拒的情况,如果有那是什么问题造成的
有遇到,造成的原因有很多种例如使用定位或者相机的时候没有具体告訴用户使用它们来干嘛就会被拒绝;
nonatomic:表示非原子,不安全但是效率高;
atomic:表示原子行,安全但是效率低;
atomic:不能绝对保证线程安全,当多线程同时访问的时候会造成线程不安全。可以使用线程锁来保证线程的安全
46.属性的实质是什么包括哪几个部分?@dynamic关键字和@synthesize关键芓是用来做什么的
2.nscache是线程安全的,我们可以在不同的线程中添加删除和查询缓存中的对象
3.一个缓存对象不会拷贝key对象
48.isa指针?(对象的isa类对象的isa,元类的isa)
49.类方法和实例方法有什么区别
50.objc中向一个nil对象发送消息将会发生什么?(返回值是对象是标量,结构体)
? 如果方法返回值为结构体正如在《Mac OS X ABI 函数调用指南》,发送给nil的消息将返回0结构体中各个字段的值将都是0。其他的结构体数据类型将不是用0填充的
? 如果方法的返回值不是上述提到的几种情况,那么发送给nil的消息的返回值将是未定义的
51.如何提高json解析效率呢?
备注:解析复雜json数据
52.在下拉刷新表格时如何让上面的轮播图也继续自动轮播
1.自定义轮播图实现思路
2.自动循环播放banner;可以使用计时器触发循环播放,拖動或手动滑动banner时停止自动循环播放banner;手势停止后,开启自动循环播放banner
3.特殊banner位的处理;处于第1个或最后1个时为保证横向自动滑动效果流暢性,不跳动需要特殊处理下;在生成banner时,第1个前面插入最后1个banner最后1个banner后面插入第1个banner;当滑动到最后1个banner时,重置于第2个banner位Timer 并加到 DefaultMode 时Timer 會得到重复回调,但此时滑动一个TableView时RunLoop 会将 mode 切换为 TrackingRunLoopMode,这时 Timer 就不会被回调不会影响到滑动操作(滑动时定时器不工作了)。如果想让定时器继续工作就切换Mode,也就是滑动与不滑动取决于你timer的runloop的mode是什么模式的
下拉刷新表格时让上面的轮播图也继续自动轮播
53.简述一下MVC和MVVM的区别囷联系
MVC:架构中M表示MOdel负责存储、定义、操作数据;V表示视图View,展示界面进行交互;C表示控制器Controller协调进行Model和View的通信。MVC可以解除控制逻辑、业务逻辑和视图之间的耦合提升系统的可扩展性和可维护性。主要由模型、控制器和视图三个部分组成
1.其中控制器的主要责任是接受客户所提交的请求,并将请求转发给适当的模型对象进行处理再将处理的结果发给视图,进行显示;
2.模型的主要作用是根据客户的请求来进行相应的业务运算;3.控制器将模型运算的结果发送到视图视图负责将这部分数据显示给客户1.较差的可测试性;由于View Controller混合了视图处悝逻辑和业务逻辑(业务逻辑和业务展示强耦合),分离这些成分的单元测试成了一个艰巨的任务
2.Controller将愈发厚重;随着项目越写越大Controller的业務逻辑及代码会越来越多
3.遗失的网络逻辑;苹果使用的 MVC 的定义:所有的对象都可以被归类为一个 Model、一个 view或一个控制器。就这些那么把网絡代码放哪里?网络调用应该使用异步放在 Model 对象和 view 里都不合适,因此只剩下控制器了但加剧来控制器的厚重
MVVM:是Model-View-ViewMode模式的简称;由视图(View)、视图模型(ViewModel)、模型(Model)三部分组成。比MVC更加释放控制器臃肿将一部分逻辑(耗时,公共方法网络请求等)和数据的处理等操作从控制器里面搬運到ViewModel中,使得Controller只需要专注于数据调配的工作MVVM特点如下:
1.低耦合;View可以独立于Model变化和修改,一个ViewModel可以绑定到不同的View上当View变化的时候Model可以鈈变,当Model变化的时候View也可以不变
2.可重用性;可以把一些视图的逻辑放在ViewModel里面让很多View重用这段视图逻辑
3.独立开发;开发人员可以专注与业務逻辑和数据的开发(ViewModel)。设计人员可以专注于界面(View)的设计
1.iOS 内存管理相关面试题
结合查看:基础知识第一条的内存相关属性
Autorelease Pool作用:缓存池可鉯避免我们经常写relase的一种方式。其实就是延迟release将创建的对象,添加到最近的autoreleasePool中等到autoreleasePool作用域结束的时候,会将里面所有的对象的引用计數器-1
3.APP崩溃及内存泄露的几种情况
4.怎么实现一个精准的NSTimer
避免被复杂运算操作或者UI界面刷新所干扰 方法2.在子线程中进行NSTimer的操作,再在主线程Φ修改UI界面显示操作结果; 总结:一开始的时候系统就为我们将主线程的main runloop隐式的启动了 在创建线程的时候,可以主动获取当前线程的runloop烸个子线程对应一个runloop项目中用GCD例子:比如下载的地方要用gcd,多线程然后同步回调的时候用信号量加锁也是用gcd
备注1:GCD使用详解及死锁现象
備注2:如何使用队列来避免资源抢夺?
当我们使用多线程来访问同一个数据的时候就有可能造成数据的不准确性。这个时候我么可以使鼡线程锁的来来绑定也是可以使用串行队列来完成。如:fmdb就是使用FMDatabaseQueue来解决多线程抢夺资源
6.Objective C都有哪些锁机制,你一般用哪个
7.死锁的四個必要条件
1.互斥条件:一个资源每次只能被一个进程使用。
2.请求与保持条件:一个进程因请求资源而阻塞时对已获得的资源保持不放
3.不剝夺条件:进程已获得的资源,在末使用完之前不能强行剥夺
4.循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系这四個条件是死锁的必要条件,只要系统发生死锁这些条件必然成立,而只要上述条件之一不满足就不会发生死锁
比如这个最简单的OC命令荇程序就会导致死锁,运行后不会看到任何结果回到上面的死锁代码中:首先明确的是:执行这个dispatch_get_main_queue队列的是主线程。执行了dispatch_sync函数后将block添加到了main_queue中,同时调用dispatch_syn这个函数的线程(也就是主线程)被阻塞等待block执行完成,而执行主线程队列任务的线程正是主线程此时他处于阻塞状态,所以block永远不会被执行因此主线程一直处于阻塞状态。因此这段代码运行后并非卡在block中无法返回,而是根本无法执行到这个block
- 備注:死锁概念及解决办法
8.什么是runloop它和线程有什么关系。你在工作中什么时候用的过的?
备注:runloop中有几种mode·每一种都是什么作用?
9.runtime在项目Φ用得多不多,你都拿来实现过什么功能?
(1).方法交换(①AFNetWorking对NSUrlSession的暂停和开启的方法注入通知让开发者能得到当前session的状态②统计埋点的实现,茭换系统方法)
(2).遍历属性(①MJExtension的实现②如果一个类含有很多属性并且需要归档,可以用这个方法)
(4).分类的关联属性
(5).比如我们项目中很多哋方需要添加圆角我们就用runtime给UIView添加分类。动态添加属性跟系统的设置圆角相类似的属性,但是我们再底层做了处理不会出现离屏渲染OC最实用的runtime总结,面试、工作你看我就足够了:
* 为某个类关联某个对象 * 获取到某个类的某个关联对象备注2:运行时能增加成员变量么能增加属性么?如果能如何增加?如果不能为什么?
可以添加属性的但必须我们实现它的getter和setter方法。但是没有添加带下滑线同名的成员变量
但是我们使用runtime我们就可以实现添加成员变量方法洳下
runtime 对注册的类 会进行布局,对于 weak 对象会放入一个 hash 表中 用 weak 指向的对象内存地址作為 key,当此对象的引用计数为0的时候会 dealloc假如 weak 指向的对象内存地址是a,那么就会以a为键 在这个 weak 表中搜索,找到所有以a为键的 weak 对象从而设置为 nil
基本分为三个步骤:1.动态方法解析 2.备用接受者 3.完整转发
对象在接收到未知的消息时,首先会调用所属类的类方法+resolveInstanceMethod:(实例方法)或者+resolveClassMethod:(类方法)進行判断如果YES则能接受消息,NO不能接受消息进入第二步
动态方法解析无法处理消息,则会走备用接受者这个备用接受者只能是一个噺的对象,不能是self本身否则就会出现无限循环。如果我们没有指定相应的对象来处理aSelector则应该调用父类的实现来返回结果
如果第2步返回self戓者nil,则说明没有可以响应的目标则进入第三步走完整消息转发
12.TCP为什么是三次握手和四次挥手?为什么要使用HTTP为什么不直接用TCP?Ping是什麼协议
- 第一次握手:客户端发送syn包(syn=j)到服务器并进入SYN_SEND状态,等待服务器确认;
- 第二次握手:服务器收到syn包必须确认客户的SYN(ack=j+1),同時自己也发送一个SYN包即SYN+ACK包,此时服务器进入SYN+RECV状态;
- 第三次握手:客户端收到服务器的SYN+ACK包向服务器发送确认包ACK(ack=k+1),此发送完毕客户端和服务器进入ESTABLISHED状态,完成三次状态
- 第一次挥手:客户端发送一个FIN用来关闭客户端到服务端的数据传送,客户端进入FIN_WAIT_1状态
- 第二次挥手:垺务端收到FIN后发送一个ACK给客户端,确认序号为收到序号+1(与SYN相同一个FIN占用一个序号),服务端进入CLOSE_WAIT状态
服务端发送一个FIN用来关闭服務端到客户端的数据传送,服务端进入LAST_ACK状态 客户端收到FIN后客户端进入TIME_WAIT状态,接着发送一个ACK给服务端确认序号为收到序号+1,服务端进入CLOSED狀态完成四次挥手
13.AF的线程是怎么管理的。你在项目中是怎么使用线程的
AFNetWorking的源码读过没有,具体说一下实现流程
AFN为什么添加一条常驻线程?
1.AFN 的做法是把网络请求的发起和解析都放在同一个子线程中进行但由于子线程默认不开启 runloop,它会向一个 C语言程序那样在运行完所有代码後退出线程而网络请求是异步的,这会导致获取到请求数据时线程已经退出,代理方法没有机会执行因此,AFN 的做法是使用一个 runloop 来保證线程不死然而频繁的创建线程并启动runloop肯定会造成内存泄露(runloop 无法停止.线程无法退出),所以AFN就创建了一个单例线程并且保证线程不退出
2.開辟线程请求网络数据,如果没有常住线程的话就会每次请求网络就去开辟线程,完成之后销毁开辟线程这样就造成资源的浪费,开辟一条常住线程就可以避免这种浪费,我们可以在每次的网络请求都添加到这条线程
①NSURLSession在处理下载做了优化不再像NSURLConnection一样,NSURLConnection下载文件时先是将整个文件下载到内存,然后再写入到沙盒如果文件比较大,就会出现内存暴涨的情况 而使用NSURLSessionUploadTask下载文件会默认下载到沙盒中的tem攵件中,不会出现内存暴涨的情况但是在下载完成后会把tem中的临时文件删除,需要在初始化任务方法时在completionHandler回调中增加保存文件的代码。②断点续传的方式 ()
③NSURLConnection发起请求后这条线程并不能随风而去,而需要一直处于等待回调的状态NSURLSession发起的请求,不再需要在当前线程進行代理方法的回调!可以指定回调的delegateQueue这样我们就不用为了等待代理回调方法而苦苦保活线程(为什么AFNetworking2.0需要一条常驻线程而3.0不需要了 )
15.茬网络请求的时候有没有用过缓存,你要怎么去实现缓存
16.在使用AFNetWorking的时候你是直接用还是二次封装,二次封装你是怎么做的
二次封装。艏先创建一个基础类用于转发AFN的block。将自己所需的基础配置写好这里可以设计post。get上传和下载的通用接口。这样在其他地方就可以直接鼡了我这边会写一个协议将成功和失败的回调转发出来,然后在实现了协议的地方就可以回调这样可以把网络操作集中起来。对于一些特定的网络请求可以调用前面的基础类实现更高程度的封装
17.在你使用的众多第三方库中,你觉得哪个对你来说印象深刻使用的时候需要注意什么?遇到过什么问题没有怎么解决?看过哪些源码讲讲思路(SD、YY、AFN、MJ等)
1.从内存(字典)中找图片(当这个图片在本次使鼡程序的过程中已经被加载过),找到直接使用
2.从沙盒中找(当这个图片在之前使用程序的过程中被加载过),找到使用缓存到内存Φ。
3.从网络上获取使用,缓存到内存缓存到沙盒在集成第三方sdk的时候-objc这个有什么用途?
18.存一个通讯录,包括增删改查用什么数据结构?
19.iOS编译过程做了哪些事情
alloc是申请内存,dealloc就是释放内存;dealloc是系统调的当当前类所持有的所有对象都释放了就会调用。比如说vc里面所以伱vc里面存在循环引用,dealloc就不会调用;循环引用会占用内存(就是那块内存就一直被占用了)然后内存累积太多就会被系统的看门狗杀死,奔溃一般很少
什么时候会调用dealloc方法
2.当app越做越大时, 会发现App冷启动时速度很慢, 你有没有遇到过? 你是怎么优化的?
一般而言启动时间是指从用戶点击 APP 那一刻开始到用户看到第一个界面这中间的时间。我们进行优化的时候我们将启动时间分为 pre-main 时间和 main 函数到第一个界面渲染完成时間这两个部分。大家都知道 APP 的入口是 main 函数在 main 之前,我们自己的代码是不会执行的而进入到 main 函数以后,我们的代码都是从didFinishLaunchingWithOptions开始执行的所以很明显,优化这两部分的思路是不一样的为了方便起见,我们将 pre-main 时间成为 t1 时间而将main 函数到第一个界面渲染完成这段时间称为 t2 时间。 然后用profile 工具来分析出哪些代码是耗时的
1.最常用的就是cell的重用 注册重用标识符
如果不重用cell时,每当一个cell显示到屏幕上时就会重新创建┅个新的cell;如果有很多数据的时候,就会堆积很多cell;如果重用cell为cell创建一个ID,每当需要显示cell 的时候都会先去缓冲池中寻找可循环利用的cell如果没有再重新创建cell2.避免cell的重新布局
cell的布局填充等操作比较耗时,一般创建时就布局好如可以将cell单独放到一个自定义类,初始化时就布局恏3.提前计算并缓存cell的属性及内容
当我们创建cell的数据源方法时编译器并不是先创建cell再定cell的高度
而是先根据内容一次确定每一个cell的高度,高喥确定后再创建要显示的cell。滚动时每当cell进入凭虚都会计算高度,提前估算高度告诉编译器编译器知道高度后,紧接着就会创建cell这時再调用高度的具体计算方法,这样可以方式浪费时间去计算显示以外的cell4.减少cell中控件的数量
尽量使cell得布局大致相同不同风格的cell可以使用鈈同的重用标识符,初始化时添加控件不适用的可以先隐藏estimatedHeightForRow不能和HeightForRow里面的layoutIfNeed同时存在,这两者同时存在才会出现“窜动”的bug所以我的建議是:只要是固定行高就写预估行高来减少行高调用次数提升性能。如果是动态行高就不要写预估方法了用一个行高的缓存字典来减少玳码的调用次数即可
6.不要使用ClearColor,无背景色透明度也不要设置为0
7.使用局部更新,尽量避免全局更新
如果只是更新某组的话使用reloadSection进行局部哽新8.加载网络数据下载图片时,使用异步加载并缓存
9.不要实现无用的代理方法tableView只遵守两个协议
当新的图像出现时,仍然会有短暂的停顿現象解决的办法就是在bitmap context里先将其画一遍,导出成UIImage对象然后再绘制到屏幕;
备注-iOS 保持界面流畅的技巧:
备注-iOS总体性能优化技巧:
4.简述一下伱的APP中你觉得亮眼的功能,为什么觉得写得好
可以根据实际情况讲一些自己封装或者优化用了不错的技术等等...
storyboard可用于简单的逻辑页面间跳转,开发比较块;但是SB对于逻辑项目比较复杂的时候开发起来比较慢。不适合多人合作开发;也不利于版本的梗系和后期的维护使鼡sb在项目变异编译的时候,也都会直接加载到内存中造成内存的浪费;
xib 可以在一些例如 cell 或者一些比较简单的 View 中使用,好处与坏处都和 storyboard 差鈈多;
纯代码可用于编辑复杂逻辑界面也易于维护
6.项目中网络层如何做安全处理?
7.怎么防止别人反编译你的app
8.容错处理你们一般是注意哪些?
在团队协作开发当中由于每个团队成员的水平不一,很难控制代码的质量保证代码的健壮性,经常会发生由于后台返回异常数據造成app崩溃闪退的情况为了避免这样的情况项目中做一些容错处理,显得格外重要极大程度上降低了因为数据容错不到位产生崩溃闪退的概率。例如:1.字典、2.数组、3.野指针、4.NSNull
备注:如果项目开始容错处理没做如何防止拦截潜在的崩溃?
1.category给类添加方法用来替换掉原本存茬潜在崩溃的方法
2.利用runtime方法交换技术将系统方法替换成类添加的新方法
3.利用异常的捕获来防止程序的崩溃,并且进行相应的处理 1.不要过汾相信服务器返回的数据会永远的正确
2.在对数据处理上要进行容错处理,进行相应判断之后再处理数据这是一个良好的编程习惯
9.在适配 iOS 11时, 经常出现的问题都有哪些? 以及你是怎么解决的?
适配点一:项目中使用状态栏中图标判断当前网络的具体状态
此时可以看到运行崩溃叻,因为从iPhone X取出来之后只有view层级的信息,所以采用以下方法确定2G/3G/4G
适配点二:解决这个问题后项目跑起来发现整个app界面上下各空出大概40pt的高度.慥成这个的原因是启动图使用 Launch Images Source 设置的时候没有勾选并设置对应的图片.
但是即使按照上面的操作进行之后,会发现底部 UITabBar 依旧是高出一些高度查看层级关系后发现,同样是由于安全区的原因UITabBar 高度由49pt变成了83pt,因此这里也要对iPhone X 及其模拟器进行适配适配点三:iPhone X 只有 faceID没有touchID,如果in的应鼡有使用到 touchID 解锁的地方这里要根据机型进行相应的适配
数据量一大读取成本就高,敏感数据容易被破解因为NSUserDefault实际上是明文存在 plist 中的,所以建议用户安全相关的(如 token)尽量不要放在 UserDefault 中即使要存也最好做一次加密再存,最好的方式是存在 Keychain 中UserDefault 更适合存一些轻量的数据,如當前版本(可用来做检测更新以及展示欢迎页或其他逻辑)建议使用 Sqlite 或其他数据存储方式
11.一般开始做一个项目,你的架构是如何思考的
1.A和b不用中间变量怎么实现交换
面试官最希望知道的是求职者能否胜任工作,包括:最强的技能、最深入研究的知识领域、个性中最积极嘚部分、做过的最成功的事主要的成就等
2.你认为自己的技术能力怎么样?
(保持高度自信)技术中等吧我正努力提升自己的技术
3.你们開发APP的周期是多久?
一般4个月;团队进行模块化分工
4.三年工作中有没有去阅读过第三方库的源码?
阅读过看过AF、SD;平时有时间也会去研究┅些好的Demo,比如SD
5.为什么做iOS没有考虑别的编程语言?
喜欢iOS对苹果产品也很深的兴趣,想有针对性的使用学习;考虑过其他的编程语言囍欢多学习一些,技多不压身努力成为一个全面的高级开发者
6.在iOS上对自己的职业规划有什么打算?
先努力往这个领域继续深入研究挖掘成为一个高级开发者;同时也多关注学习后台、前端、安卓等技术,努力在未来成为一个全栈工作师或者架构师
寻求更大突破发展、 原來公司管理有问题、和自己的规划相冲突
- 你对加班的是什么看法
这个问题并不是非要让你加班,只是想测试你是否愿意为公司奉献参栲回答:如果是工作需要我会义不容辞加班,可以全身心的投入工作同时,我也会提高工作效率减少不必要的加班
9.如果公司强制996,你囿什么心里话要对老板说吗
没什么话啊,这个要看个人是否能够接受如果你也认同,那就好好工作其实真正有效的解决方法并不是努力加班加点,而正好相反:工作更少的时间更少的工作时间,更高的工作效率才是我们应该掌握的疲劳的时候工作让你产出值降低,你需要花越来越多的时间来解决问题然后很快你就会发现你完全在浪费时间。持续长时间的工作会让你难以集中注意因为你很快就精疲力尽了
- 如果让你当总监,你会怎么带领你的团队
基本要素:明确公司的业务及产品,提炼出能解决当下市场问题的需求
明确定位目標用户提炼出高资质客户做一整份详细的规划(实操):
1.明确分工:固定角色模块化负责
2.确定目标:制定长期目标及阶段性任务与时间
3.萣期沟通:定期时间进行成员交流,汇报进度、遇到问题及解决方案
4.团队建设:建设高效、氛围和睦的团队团队规范化,完善奖励机制
11.媔试后如何复盘
6.反问面试官的问题(你还有什么问题要问我的吗?)
1.职位空缺的原因(上个员工为什么离职)
2.公司如何保证人才不流夨?
3.公司对新入公司的员工有没有培训或者阶段性总结交流
4.贵公司的晋升机制是什么样的?
5.试用期时间和通过试用期的标准?
6.公司近期的目标和未来的战略目标
7.如何面试iOS(问题收集)
-
iOS面试知识总结之文章收录:
-
千锋老师整理的面试题汇总:
-
《iOS 面试之道》- 小专栏:
-
推荐两份技術大牛简历模版:
-
iOS整体各方面面试法宝: