J_Knight_ iOS 高级面试题 实战题解答以及一些扩展性链接

519 阅读11分钟

iOS 实战题

AppDelegate如何瘦身?

1.命令模式

2.分类

3.QTEventBus 实现一个优雅的iOS事件总线

4.组合模式

解释一下命令模式和组合模式的区别

命令模式:将一个请求封装为一个对象,从而使你可不用不同的请求对客户端进行参数化,对请求排队或记录请求的日志,以及支持可撤销的操作。

举例:烧烤摊:客户->烧烤者 烧烤店:客户->服务员->烧烤师傅

命令模式优点:

1:他比较设计一个命令队列

2:在需要的情况下,可以较容易的。

3:允许接受请求的一放决定是否否觉请求了

4:可以容易实现对请求的撤销和重做,

组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。

什么时候用组合模式:但你发现需求中是体现部分与整体层次的结构时,以及你希望用户可以忽略组合对象与单个对象的不同,统一的使用组合结构中的所有对象是,就该考虑用组合模式了。

组合模式的好处:组合模式这样就定义了包含人力资源部和财务部这些基本对象和分公司,办事处等组合对象类的层次结构,基本对象可以背组合成更加复杂的组合对象,而这个组合对象又可以被组合,这样不断的递归下去,客户代码中,任何代码中,任何用到基本的对象的地方都可以用组合的对象。

组合模式三个关键点:add remove dept 增加 移除 深度

反射是什么?可以举出几个应用场景么?(知道多少说多少)

反射机制有三个用途:

1.获得Class

2.检查继承关系

3.动态的调用方法

有哪些场景是NSOperation比GCD更容易实现的?(或是NSOperation优于GCD的几点,知道多少说多少)

<1>GCD GCD是iOS4.0推出的,主要针对多核cpu做了优化,是C语言的技术 GCD是将任务(block)添加到队列(串行/并行/全局/主队列),并且以同步/异步的方式执行任务的函数,任务的取出遵循队列的FIFO原则:先进先出,后进后出

GCD提供了一些NSOperation不具备的功能

一次性执行:可以保证某一段代码在程序运行的过程中只被执行一次;一次性执行是线程安全的,在多线程环境下也是只执行一次;应用场景:设计单例模式 延迟执行:既实现等待多长时间后在哪个队列中执行什么代码块 调度组:监听一组异步任务执行结束之后,我们能够得到统一的通知;注意:在其调度组内的任务执行完毕后执行后面的”刷新主界面”方法与”玩完”之间的执行没有先后顺序;例如:

<2>NSOperation

NSOperation是iOS2.0推出的,iOS4.0之后重写了NSOperation NSOperation将操作(异步的任务)添加到队列(并发队列),就会执行指定操作的方法

NSOperation里提供的方便的操作

最大并发数,

队列的暂定/继续

取消队列中所有的操作

指定操作之间的依赖关系(GCD可以用同步实现,但是比较麻烦)

•同步和异步决定了要不要开启新的线程(同步不开,异步开)

同步:在当前线程中执行任务,不具备开启新线程的能力

异步:在新的线程中执行任务,具备开启新线程的能力

•串行和并发决定了任务的执行方式

并发:多个任务并发(同时)执行

串行:一个任务执行完毕后,再执行下一个任务

•当任务是异步的时候,队列决定了开启多少条线程

串行队列:只开一条

并发队列:可以开启多条

•主队列特点:主队列中的任务,只有主线程空闲的时候才会调度任务执行 主队列又叫全局串行队列,程序启动的时候就创建了主队列,在使用的时候不需要创建,直接GET.主队列中的任务是要在主线程执行的.

•主队列,异步任务

不开线程,同步执行

•主队列,同步执行

同步执行:如果第一个任务没有执行,就继续等待第一个任务执行完成,再执行下一个任务此时互相等待,程序无法往下执行(死锁)

•全局队列本质就是并发队列

dispatch_get_global_queue(0,0);

•全局队列和并发队列的区别

并发队列有名称,可以跟踪错误,全局队列没有

全局队列在ARC中不需要考虑释放内存,dispatch_release(q);不允许调用。并发队列在MRC中需要手动释放内存,因为并发队列是create创建出来的在MRC中见到create就要release,全局队列不需要release(只有一个) 一般我们使用全局队列,因为使用起来更加简单

<3>综合比较其各自使用范围如下 性能:

①:GCD更接近底层,而NSOperationQueue则更高级抽象,所以GCD在追求性能的底层操作来说,是速度最快的。这取决于使用Instruments进行代码性能分析,如有必要的话

②:从异步操作之间的事务性,顺序行,依赖关系。GCD需要自己写更多的代码来实现,而NSOperationQueue已经内建了这些支持

③:如果异步操作的过程需要更多的被交互和UI呈现出来,NSOperationQueue会是一个更好的选择。底层代码中,任务之间不太互相依赖,而需要更高的并发能力,GCD则更有优势

App 启动优化策略?最好结合启动流程来说(main()函数的执行前后都分别说一下,知道多少说多少)

https://juejin.cn/post/6844903489013825550       iOS 启动优化
http://www.cocoachina.com/ios/20180927/25038.html    App启动速度优化
https://juejin.cn/post/6844903684040556551        你的 APP 为何启动那么慢?
https://juejin.cn/post/6844903525172903944         [iOS]一次立竿见影的启动时间优化
http://www.cocoachina.com/ios/20180802/24423.html    iOS启动时间优化
http://www.cocoachina.com/ios/20180521/23434.html 【高级iOS】启动时间优化
https://www.jianshu.com/p/c14987eee107       如何精确度量 iOS App 的启动时间


linkers and loaders
http://www.codeproject.com/Articles/187181/Dynamic-
Linking-of-Imported-Functions-in-Mach-O
http://blog.imjun.net/2016/10/08/
iOS (冰和火之歌)
WWDC 2016 Optimizing App Startup Time

https://blog.csdn.net/bjtufang/article/details/50628310
Mach-O文件格式和程序从加载到执行过程

https://blog.csdn.net/fishmai/article/details/51419824 dyld源码分析-动态加载main的流程和load函数执行的流程

https://blog.csdn.net/Hello_Hwc/article/details/78317863?locationNum=9&fps=1 深入理解iOS App的启动过程

https://zhuanlan.zhihu.com/p/24875905?refer=macos-sec dylib动态库加载过程分析

https://blog.csdn.net/sharemyfree/article/details/44036481 转 iOS 系列译文:Mach-O 可执行文件

http://blog.51cto.com/haidragon/2142524 MachOView源码(LoadCommands.mm)

https://www.jianshu.com/p/231b1cebf477 iOS App从点击到启动

https://njafei.github.io/2017/05/04/runtime/ iOS Runtime 详解

https://blog.csdn.net/vincentiss/article/details/54617915 深入剖析 iOS 编译 Clang / LLVM

http://www.cocoachina.com/ios/20180802/24423.html iOS启动时间优化

gcc为函数提供了几种类型的属性,其中包含:构造函数(constructors)和析构函数(destructors)。 程序员应当使用类似下面的方式来指定这些属性:

attribute((constructor)) // 在main函数被调用之前调用 attribute((destructor)) // 在main函数被调用之后调

http://www.cocoachina.com/ios/20170716/19876.html iOS程序启动->dyld加载->runtime初始化(初识) https://www.jianshu.com/p/231b1cebf477 iOS App从点击到启动

https://blog.csdn.net/fishmai/article/details/51419824 dyld源码分析-动态加载main的流程和load函数执行的流程

App 无痕埋点的思路了解么?你认为理想的无痕埋点系统应该具备哪些特点?(知道多少说多少)

无埋点数据收集SDK

你知道有哪些情况会导致app崩溃,分别可以用什么方法拦截并化解?(知道多少说多少)

Unrecognized Selector Sent to Instance

NSArray,NSMutableArray,NSDictonary,NSMutableDictionary NSString

KVO

Zombie Pointer

NSTimer

NSNotification

Unrecognized Selector Sent to Instance

[https://github.com/chenfanfang/AvoidCrash](AvoidCrash)

目前可以防止崩溃的方法有

unrecognized selector sent to instance
1. 对”unrecognized selector sent to instance”防止崩溃的处理
NSArray
1. NSArray的快速创建方式 NSArray *array = @[@"chenfanfang", @"AvoidCrash"]; //这种创建方式其实调用的是2中的方法

2. +(instancetype)arrayWithObjects:(const id  _Nonnull __unsafe_unretained *)objects count:(NSUInteger)cnt

3. 通过下标获取元素 array[100]、[array objectAtIndex:100]

- (id)objectAtIndex:(NSUInteger)index
4. - (NSArray *)objectsAtIndexes:(NSIndexSet *)indexes

5. - (void)getObjects:(__unsafe_unretained id _Nonnull *)objects range:(NSRange)range

NSMutableArray
1. 通过下标获取元素 array[100]、[array objectAtIndex:100]
- (id)objectAtIndex:(NSUInteger)index
2. - (void)setObject:(id)obj atIndexedSubscript:(NSUInteger)idx
3. - (void)removeObjectAtIndex:(NSUInteger)index
4. - (void)insertObject:(id)anObject atIndex:(NSUInteger)index
5. - (NSArray *)objectsAtIndexes:(NSIndexSet *)indexes
6. - (void)getObjects:(__unsafe_unretained id _Nonnull *)objects range:(NSRange)range
NSDictionary
1. NSDictionary的快速创建方式 NSDictionary *dict = @{@"frameWork" : @"AvoidCrash"}; //这种创建方式其实调用的是2中的方法
2. +(instancetype)dictionaryWithObjects:(const id _Nonnull __unsafe_unretained *)objects forKeys:(const id<NSCopying> _Nonnull __unsafe_unretained *)keys count:(NSUInteger)cnt
NSMutableDictionary
1. - (void)setObject:(id)anObject forKey:(id<NSCopying>)aKey
2. - (void)removeObjectForKey:(id)aKey
NSString
1. - (unichar)characterAtIndex:(NSUInteger)index
2. - (NSString *)substringFromIndex:(NSUInteger)from
3. - (NSString *)substringToIndex:(NSUInteger)to {
4. - (NSString *)substringWithRange:(NSRange)range {
5. - (NSString *)stringByReplacingOccurrencesOfString:(NSString *)target withString:(NSString *)replacement
6. - (NSString *)stringByReplacingOccurrencesOfString:(NSString *)target withString:(NSString *)replacement options:(NSStringCompareOptions)options range:(NSRange)searchRange
7. - (NSString *)stringByReplacingCharactersInRange:(NSRange)range withString:(NSString *)replacement
NSMutableString
1. 由于NSMutableString是继承于NSString,所以这里和NSString有些同样的方法就不重复写了
2. - (void)replaceCharactersInRange:(NSRange)range withString:(NSString *)aString
3. - (void)insertString:(NSString *)aString atIndex:(NSUInteger)loc
4. - (void)deleteCharactersInRange:(NSRange)range
KVC
1.- (void)setValue:(id)value forKey:(NSString *)key
2.- (void)setValue:(id)value forKeyPath:(NSString *)keyPath
3.- (void)setValue:(id)value forUndefinedKey:(NSString *)key //这个方法一般用来重写,不会主动调用
4.- (void)setValuesForKeysWithDictionary:(NSDictionary<NSString *,id> *)keyedValues
NSAttributedString
1.- (instancetype)initWithString:(NSString *)str
2.- (instancetype)initWithAttributedString:(NSAttributedString *)attrStr
3.- (instancetype)initWithString:(NSString *)str attributes:(NSDictionary<NSString *,id> *)attrs
NSMutableAttributedString
1.- (instancetype)initWithString:(NSString *)str
2.- (instancetype)initWithString:(NSString *)str attributes:(NSDictionary<NSString *,id> *)attrs

[https://github.com/jezzmemo/JJException](JJException)

保护App,一般常见的问题不会导致闪退,增强App的健壮性,同时会将错误抛出来,根据每个App自身的日志渠道记录,下次迭代或者热修复以下问题.

 Unrecognized Selector Sent to Instance(方法不存在异常)

 NSNull(方法不存在异常)

 NSArray,NSMutableArray,NSDictonary,NSMutableDictionary(数组越界,key-value参数异常)

 KVO(忘记移除keypath导致闪退)

 Zombie Pointer(野指针)

 NSTimer(忘记移除导致内存泄漏)

 NSNotification(忘记移除导致异常)

 NSString,NSMutableString,NSAttributedString,NSMutableAttributedString(下标越界以及参数nil异常)

如需想了解深入各位老铁,请搜索对应的源码解析

你知道有哪些情况会导致app卡顿,分别可以用什么方法来避免?(知道多少说多少)

分cpu卡和gpu卡顿。
主线程耗时操作
滑动页面渲染卡顿(离屏渲染)
图像渲染解码
“你知道有哪些情况会导致app卡顿”我觉的这个问题有点尬,有点不怎么会回答了,

1.避免主线程阻塞 afnetworking已经做了回到主线程操作,如果有数据耗时的数据处理,请用多线程
1.2 将cell高度和 cell里的控件的frame缓存在model里
1.3 减少cell内部控件的层级
1.4 通过覆盖圆角图片来实现头像的圆角效果
2. 按需加载cell
2.1 在cellForRow:方法里只加载可见cell
2.2 监听tableview的快速滚动,保存目标滚动范围的前后三行的索引
3. 异步处理cell
3.1 异步加载网络图片
3.2 异步绘制本地图片
3.3 异步绘制UIView
3.4 异步绘制NSString
3.5 异步绘制UILabel
4.  复用  等

https://mp.weixin.qq.com/s?__biz=MzA5NzMwODI0MA==&mid=2647761180&idx=1&sn=67e69d424f4fb6b5a77ed8cc5cbca7db&chksm=8887da23bff053354d17806e2d02a5bd5b1008be45a7f5eee6c784a0e1cf2b7d3df8dfd63372&mpshare=1&scene=1&srcid=10113fj7OH7WMuzM5lKM6c63&rd2werd=1#wechat_redirect .   iOS 界面渲染流程分析
 http://www.cocoachina.com/ios/20180417/23049.html .  深入理解 iOS Rendering Process . 
 http://www.cocoachina.com/ios/20180830/24599.html    iOS性能优化系列篇之“列表流畅度优化”
http://www.cocoachina.com/ios/20180806/24466.html Objective-C Message Throttle and Debounce(Objective-C消息节流和防抖
 http://www.cocoachina.com/ios/20180806/24469.html iOS 性能优化 Instruments 检测 App 耗电量实战
 http://www.cocoachina.com/ios/20180720/24246.html  iOS-性能优化深入探究 http://www.cocoachina.com/ios/20180712/24128.html  iOS 界面性能优化浅析 
http://www.cocoachina.com/ios/20180713/24147.html   深入剖析 iOS 性能优化
 http://www.cocoachina.com/ios/20180703/24024.html  iOS 保持页面流畅技巧
http://www.cocoachina.com/ios/20180412/22990.html  iOS 性能优化总结
 http://www.cocoachina.com/ios/20180625/23919.html  iOS高效图片IO框架是如何炼成的
http://www.cocoachina.com/ios/20180511/23354.html  iOS性能调优之--tableView优化
http://www.cocoachina.com/ios/20180323/22737.htmlUITableView 的优化技巧
http://www.cocoachina.com/ios/20180309/22514.html   iOS 性能优化探索
http://www.cocoachina.com/ios/20180207/22197.html iOS开发——实战UITableview深度优化
http://www.cocoachina.com/ios/20180213/22282.html  《高性能iOS 应用开发》之降低你 APP 的电量消耗
https://blog.csdn.net/zhaizu/article/details/51882768    理解 VSync
https://rannie.github.io/ios/2016/02/22/ios-display-opengles.html  OpenGL ES 基础以及 iOS 设备渲染探究优化
https://www.jianshu.com/p/997c05a77a7f   iOS绘制与渲染--GPU和OpenGL


这些都资料都是自己平常学习中收集下来的学习链接,写个博客分享给大家,希望大家能帮助大家,如文中有什么不对的地方请留言了,笔者进行改正了,因为这些资料都是以前写的一块一块的,这两天整理了一下,分享一下给大伙了,希望各位老铁都能找到一个好的工作。

各位老铁本人水平有限,如有不充分的欢迎各位老铁留言补充