面试总失败?最全IOS 面试剖析,让你成为面霸!

论坛 期权论坛 期权     
键盘猫   2019-7-20 09:38   1675   0
点击上方蓝字,记得关注我们!
总有面邀在手,一面试就没下文?
莫急莫急,资深大牛告诉你,问题原来在这里!
▼▼▼知己知彼,赶快对号入座,先看下自己的技术段位吧~



高级IOS
  • 解决研发过程中的关键问题和技术难题
  • 调优设备流量、性能、电量
  • 较强的软件设计能力
  • 对iOS内部原理有深刻理解
    1. [/code]
    2. [/list]资深IOS
    3. [list][*]精通高性能编程以及性能调优
    4. [*]灵活运用数据结构、算法解决复杂程序设计问题
    5. [*]提供性能优化、日志搜索、统计分析等方案
    6. [*]架构、模块设计
    7. [/list]
    8. [code]
    复制代码
    简历
    • 排版清晰
    • 重要和突出的表达
    • 线上bug数变化、量化指标 质量上的指标
    • 开发成本节约了多少 量化指标
    • 基本信息、工作经历、项目经验、擅长技能
    • 项目经验(主导、参与),背景、方案、效果(START 法则)



    技术问题要点
    面答问题目录

    • 1. UI视图
    • 2. UITableView
    • 3. 视图显示原理
    • 4. OC语言面试问题
    • 5. RunTime
    • 6. 类对象,对象(实例,isa指向类对象),
    • 7. 内存管理
    • 8. Block
    • 9. 多线程
    • 10. RunLoop
    • 11. 网络
    • 12. 设计模式
    • 13. 架构&框架
    • 14. 算法
    • 15. 第三方库



    1.UI 视图
    • UITableView
    • 事件传递&视图响应
    • 图像显示原理
    • 卡顿&掉帧
    • 绘制原理&异步绘制
    • 离屏渲染

    2.UITableview
    • 重用机制
    • 数据源同步
      • 并发方案数据copy 串行方案
    • UI事件传递&响应
      • UIView提供内容,事件响应,响应链
      • CALayar的contents负责绘制
      • 单一指责原则



    3.视图显示原理
    3-1、卡顿、掉帧的原因
    • CPU
      • 对象创建、调整、销毁
      • 预排版(布局计算、文本计算)
      • 预渲染(文本等异步绘制,图片解码等)
    • GPU
      • 纹理渲染
      • 视图混合

    3-2、UIView的绘制原理
    • [UIView setNeedsDisplay] -> [view.layer setNeedsDisplay] -> [CALayer display]
    • [CALayer display]是否响应 [layer.delegate displayLayer]方法
    • 是,进入异步绘制。否,进入系统绘制流程
      • CALayer creats backing store(CGContextRef)
      • 是否有layer has a delegate
      • 是,[layer.delegate drawLayer:inContext:]
      • 否,[CALayer drawInContext:]
      • 最后 CALayer uploads backing store to GPU


    3-3、异步绘制 [layer.delegate displayLayer]
    1. - 代理负责生成对应的bitmap- 设置该bitmap作为layer.contents属性的值- 流程如下
    复制代码
    1234567- [AsyncDrawingView setNeedsDisplay]- [CALayer display]- [AsyncDrawingView displayLayer:]    - CGBitmapContextCreat()    - CoreGraphic API    - CGBitmapContextCreatImage()- [CALayer setContents][h1][/h1][h1]3-4、离屏渲染(OFF-SCREEN RENDERING)[/h1]在当前缓冲区创建新的缓冲区渲染缓冲区渲染,圆角(和maskToBounds一起使用),孟层遮罩,阴影,光栅化
    • 为何要避免离屏渲染?
    • 离屏渲染会增加GPU的工作量, CPU+GPU提交一帧的时间超过了16.7ms,造成了不满60帧的卡顿
    • 创建新的渲染缓冲区
    • 上下文切换
    4.OC语言面试问题[h1]4-1、分类[/h1][h2]分类都做了什么事情?[/h2]
    • 声明私有方法
    • 分解体积庞大的类文件
    • framework的私有方法公开
      [h2]特点[/h2]
    • [h2]运行时决议(runtime时添加)[/h2]
    • [h2]可以为系统类添加分类[/h2][h2]分类中可以添加哪些内容[/h2]
    • 可以为系统类添加分类
    • 实例方法
      • 类方法
      • 协议
      • 属性(只是声明了set和get方法,而不是私有属性)
        [h2][/h2][h2]结构体(objc-runtime-680版本源代码)[/h2]
    • const char * name
      • cls
      • instanceMethods
      • classMethods
      • protocols
      • instanceProperties
        [h2]加载调用栈[/h2]
    • _objc_init -> map_2_imags -> map_images_nolock -> _read_images -> remethodizeClass
      [h2]源码分析[/h2]
    • 效果上,分类添加的方法可以「覆盖」原类方法
    • 同名分类方法谁能生效取决于编译顺序
    • 名字相同的分类会引起编译报错
    [h1]4-2、扩展相关面试问题[/h1]
    • 声明私有属性
    • 声明私有方法
    • 声明私有成员变量
      [h2]扩展特性[/h2]
    • 编译时决议
    • 不能为系统类添加扩展
    • 只有声明
    [h1]4-3、代理相关[/h1]
    • 软件设计模式
    • @protocol形式提现
    • 代理传递一对一
    • weak规避循环引用
      [h1]4-4、通知相关(NSNotification)[/h1]
    • 是使用观察者模式来实现的用于跨层传递消息的机制(网络层,ui层传递等等)
    • 一对多
    [h1]4-5、KVO[/h1]
    • KVO是Objective-C对观察者设计模式的有一种实现
    • Apple使用了isa混写(isa-swizzling)来实现kvo
    • NSKVONotifying_A (子类)重写setter方法
      123456- (void)setValue:(id)obj {    [self willChangeValueForKey:@"keyPath"];    //调用父类实现,也即原类的实现    [supe setValue:obj];    [self didChangeValueForKey:@"keyPath"];}
    • 1、通过kvc设置value能否生效?
    • 2、通过成员变量直接赋值value能否生效?
    [h1]4-6、KVC (Key-value coding)键值编码[/h1]
    • valueForKey流程图


    • Accessor Method


      • [code][/code]
    • setValueForKey流程图



    5.RunTime
    • 数据结构
    • 类对象与元类对象
    • 消息传递
    • 方法缓存
    • 消息转发
    • Methond-Swizzling
    • 动态添加方法
    • 动态方法解析
    [h1]数据结构[/h1]objc_object
    • isa_t
    • 关于isa操作相关
    • 弱引用相关
    • 关联对象相关
    • 内存管理objc_class
    • Class = objc_class继承自objc_object
      • Class puserClass
      • cache_t cache
      • class_data_bits_t bits;isa指针
    • 指针型isa,的内存地址代表Class的地址
    • 非指针型的呢值,代表Class的地址isa指向
    • 关于对象,指向类对象,-class
    • 类对象,元类对象, Class——isa-MetaClasscache_t
    • 用于快速查找方法执行函数,消息传递的速度
    • 是可增量扩展的哈希表结构
    • 是局部性原理的最佳应用(调用频率越高,越容易命中)
    • 数据结构
      • key
      • IMPclass_data_bits_t
      • bucket_t 这样的数组
    • 主要是对class_rw_t的封装
      • class_ro_t
      • protocols(二维数组)
      • properties(二维数组)
      • methods(二维数组)
    • clcass_rw_t 代表了类相关的读写信息、对class_ro_t的封装
    • class_ro_t
      • name(类名等…)
      • ivars(二维数组)
      • properties(二维数组)
      • protocols(二维数组)
      • methodlist(二维数组)
    • method_t


      • struct method_t= name。。。SEL name; 名称
      • chonst char* types; 函数体
        • 返回值 参数1.。。参数n

        • v@: void, id SEL
      • IMP imp; 实现







      6.类对象,对象(实例,isa指向类对象)
    实例对象可以通过isa指针找到类对象,类对象的isa指针可以找到元类对象,元类对象isa指向根原类对象,根元类对象isa指向根类对象
    [h1]6-1、消息传递[/h1]
    • void objc_mesSend(void /* id self, SEL op, …*/)
    • void objc_mesSendSuper(void /* struct objc_super * super, SEL op, …*/)
    [h2]a.缓存查找 哈希查找[/h2]通过SEL->hash->key找多对应的bucket_t的IMP
    • 对于已排序好的列表,采用二分法查找对应执行函数
    • 对于没有排序好的列表,采用一般遍历
    • 缓存查找是否命中, 方法列表是否命中, 逐级父类方法是否命中, 消息转发
      [h2]b.x消息转发[/h2][h3]实例方法的转发[/h3]
    • 类方法 resolveInstanceMethode: 返回值bool。yes已处理,消息转发结束
    • forwarding TargetForSelector: 返回值是id,因该有那个对象来处理,返回nil进入第三次转发
    • methodSignatureForSelector: 返回方法签名,返回nil,消息无法处理
    • forwardInvocation:
    [h2]c.Method-Swizzling[/h2][h2]d.动态添加方法[/h2]
    • 通过消息转发机制,动态添加方法。在resolveInstanceMethod
    [h2]e.动态方法解析[/h2]
    • @dynamic 动态运行时语言将函数决议推迟到运行时
    • 编译时语言在编译器进行函数决议
    [h2]f.[obj foo]和objc_msgSend()函数有什么关系?[/h2]
    • [obj foo]在编译之后,就变成了和objc_msgSend()
    [h2]g.runtime如何通过Selector找到对应的IMP地址?[/h2]
    • 先从缓存方法列表—-待补充
      [h2]h.能否向编译后的类中增加实例变量?[/h2]
    • 不能!编译后结构体class_ro_t是只读属性

    7.内存管理
    • TaggedPointer
    • NONPOINTER_ISA
    • 散列表(引用技术表和弱引用表)
    [h1]7-1、NONPOINTER_ISA[/h1][h1]7-2、散列表 Side Tables()结构[/h1]
    • 自旋锁
    • 引用计数表
    • 弱引用表
      分离锁,提升并发问题
    • Spinlock_t 自旋锁
      • Spinlock_t是『忙等』的锁
      • 轻量访问
    • RefcountMap Hash表
    • weak_table_t 弱引用表 Hash表
    [h1]7-3、MRC & ARC[/h1]
    • ARC是LLVM和Runtime协作的结果
    • ARC禁止调用 retain/等
    • ARC中新增weak,strong等属性关键字
    [h1]7-4、引用计数管理[/h1][h2]retain实现[/h2]123SideTable& table = SideTables()[This];(哈西查找)size_t& refcntStorage = table.refcnts[This];   size_t就是无符号long型refcnStorage += SIDE_TABLE_RC_ONE;[h2]dealloc实现[/h2]
    • _objc_rootDeallco()
    • rootDealloc()
    • 是否可以释放
      • nonpointer_isa
      • weakly_referenced
      • has_assoc
      • has_cxx_dtor
      • has_sidetable_rc
    • 3全部为no,调用object_dospose().否则可直接c函数free()释放
    [h2]弱引用管理[/h2][h1]7-5、自动释放池[/h1]
    • 是以栈为节点通过双向链表的形式结合而成
    • 是和线程一一对应的
      [h2]双向链表[/h2]{id * next;AutoReleasePoolPage * const parent;AutoReleasePoolPage * child;pthread_t const thread}多层嵌套就是多次插入哨兵对象
    [h1]7-6、循环引用[/h1]
    • 自循环引用
    • 相互循环引用
    • 多循环引用
    [h2]如何破除循环引用[/h2]
    • 避免产生循环引用
    • 在合适的时机手动断环
    • __block
      • MRC下,__block修饰不会增加引用计数,避免了循环引用
      • ARC下,__block修饰会被强引用,无法避免循环引用,需手动解环
    • NSTimer的循环引用问题
      • nstimer 会对target强引用,Runloop会强制引用NSTimer;
      • 添加中间对象,NSTimer和对象之间
      • invalidInvocation
    8.Block
    Block是将函数以及执行上下文封装起来的对象.使用【clang -rewite-objc file.m】查看编译之后的文件内容
    [h1]8-1、截获变量[/h1]
    • 对于基本数据类型的局部变量截获其值
    • 对于对象类型的局部变量连同所有权修饰符一起截获
    • 以指针形式截获局部静态变量
    • 不截获全局变量、静态全局变量使用【clang -rewite-objc -fobjc-arc file.m】查看编译之后的文件内容
      [h1]8-2、__block修饰符[/h1]
    • 一般情况下,对被截获的变量进行赋值操纵时,需要添加__block修饰符
      [h1]8-3、Block的内存管理[/h1]无论任何位置,都可以顺利的用__block修饰变量访问到
      [h1]8-4、循环引用问题[/h1]
    • __block在MRC下不会引用计数+1,在arc下会引用计数+1
    9.多线程
    • GCD
    • NSOperation
    • NSTread (常驻线程)
    • 多线程与锁
      [h1]9-1、GCD[/h1]
    • 同步、异步和串行/并发
    • dispath_barrier_async 针对多读单写问题,栅栏函数
    • dispath_group
      [h2]a.同步串行[/h2]
    • 死锁原因,是队列引起的 循环等待
      [h2]b.同步并发[/h2][h2]c.异步串行[/h2][h2]d.异步并发 performSelector: delay[/h2]
    [h1]9-2、dispath_barrier_async()[/h1][h1]9-3、dispath_group_async()[/h1]使用GCD实现:ABC执行完,再执行D
    dispatch_group_notify(group,….){}
    [h1]9-4、NSOperation[/h1]
    • 需要和NSOperationQueue
    • 添加任务依赖
    • 任务执行状态控制
    • 最大并发量
    [h2]任务执行状态控制[/h2]
    • isReady
    • isExecuting
    • isFinished
    • isCancelled只重写了main方法,底层控制变更任务执行完成状态,以及任务退出如果重写了star方法,自行控制任务状态
    • gnustep=base-1.24.9
      系统通过KVO的形势移出一个isFinished为YES的NSOperation
    [h1]9-5、NSThread[/h1]启动流程 star() -> 创建pthread -> main() -> [target performSelector:SEL] -> exit()
    [h1]9-6、多线程和锁[/h1]
    • @synchronized
      • 创建单利对象的使用
    • atomic
      • 属性关键字,赋值操作线程安全,其它不安全
    • OSSpinLock
      • 自旋锁,循环等待询问,不释放当前资源
      • 轻量级的数据访问,简单的+1、-1
    • NSRecursivelock 递归锁
      • 可以重录
    • NSLock
      • 互斥
      • A方法中[lock lock],再次调用[lock lock]会造成死锁,使用NSRecursivelock
    • dispath_semaphore_t

    10.RunLoop
    RunLoop是通过内部维护的事件循环来对事件/消息进行管理的一个对象
    • 没有消息需要处理时,休眠以避免资源占用
      • 用户态 -> 内核态
    • 有消息需要处理时,立刻被唤醒
      • 内核态 -> 用户态
    [h1]10-1、数据结构[/h1]NSRunLoop 是CFRunLoop的封装,提供了面向对象的API, 开源地址
    • CFRunLoop
    • CFRunLoopMode
    • Source/Timer/Observer
    [h2]a.CFRunLoop数据结构[/h2]
    • pthread 一一对应 (Runloop和线程的关系)
    • currentMode CFRunLoopMode
    • modes NSMutableSet
    • commonModes NSMutableSet
      • 不是一种实际存在的Mode,
      • 同步Source/Timer/Observer到多个Mode中的一种技术方案
    • commonModeItems observer Timer source,
    [h2]b.CFRunLoopMode[/h2]
    • name NSDefaultRunloopMode
    • source0
    • source1
    • observers
    • timers
    [h2]c.CFRunLoopSource[/h2]
    • source0 需要手动唤醒线程
    • source1 具备唤醒线程的能力
      [h2]d.CFRunLoopObserver[/h2]
    • kCFRunLoopEntry
    • kCFRunloopBeforeTimers
    • kCFRunLoopBeforeSources
    • kCFRunLoopBeforeWaiting

    1个RunLoop有多个Model,一个model有多个 source、Timer、Observer
    [h1][/h1][h1]10-2、RunLoop的Mode[/h1][h1]10-3、s事件循环的实现机制[/h1]void CFRunLoopRun(),用户态到核心态相互切换



    10-4、常驻线程
    由于自己创建的线程并没有开启runloop(一一对应关系),需要创建并开启一个Runloop
    • 为当前线程开启一个RunLoop.
    • 向该RunLoop中添加一个Port/Source等维持RunLoop的事件循环. 没有就会退出
    • 启动该RunLoop
    11.网络
    12.设计模式
    • 责任链
    • 桥接
    • 适配器
    • 单例
    • 命令
    [h1]12-1、设计原则[/h1]
    • 单一指责原则
      • 一个类负责一件事儿,CALayer和UIView
    • 依赖倒置原则
      • 抽象不应该依赖于具体实现,具体实现可以依赖于抽象. 声明的接口等
    • 开闭原则
      • 对修改关闭、对扩展开放
    • 里氏替换原则
      • KVO,使用紫雷无缝替换,且原功能不受任何影响
    • 接口隔离原则
      • 使用多个专门的协议、delegate,datasouce
    • 迪米特法则
      • 一个对象应当对其他对象有尽可能少的了解
      • 高内聚,低耦合
    [h1]12-2、责任链[/h1]
    • 某一对象的成员变量也是该类类型
    [h1]12-3、桥接[/h1]
    • 一个类拥有一个抽象类,抽象类有多种实现
    [h1]12-4、适配器[/h1]
    • 一个现有类需要适应变化的问题
      • 对象适配器
      • 类适配器
        [h2]对象适配器[/h2]成员变量的方式持有原类
        12345- (void)request {    //额外处理    [self.target operation];    //额外处理}
    [h1]12-5、单例[/h1]
    instance = [[super allocWithZone:NULL] init];避免循环调用
    • 重写
    123456+ (id)allocWithZone:(struct _NSZone *)zone {    return [self shareInstance];}- (id)copyWithZone:(struct _NSZone *)zone {    return self;}[h1]12-6、命令模式[/h1]
    • 行为参数化
    • 降低代码重合度
    13.架构&框架
    • 图片缓存
    • 阅读时长统计
    • 复杂页面架构
    • 客户端整体架构
    [h1]13-1、图片缓存框架[/h1]
    • 内存的设计上需要考虑哪些问题?
    • 储存的Size
    • 淘汰策略
      [h2]存储的Size[/h2]
    • 10k以下的图片
    • 100k以下20张图片
    • 100k以上5张左右
      [h3]淘汰策略(内存)[/h3]
    • 队列先进先出的方式淘汰
    • 模拟LRU算法 (最近最久,如30分钟之内是否使用过)
      • 每次进行读写时
      • 前后台切换时
        [h3]磁盘设计[/h3]
      • 定时检查
      • 提高检查出发的频率
    • 存储方式
    • 大小限制(如100M)
    • 淘汰策略(如某一图片储存时间超过7天)
      [h3]网络请求图片设计[/h3]
    • 图片请求最大量
    • 请求超时策略
    • 请求优先级
      [h3]图片解码[/h3]
    • 对于不同格式的图片,用什么方式?
    • 应用策略模式对不同图片进行解码
    • 在哪个阶段图片解码处理
    • 磁盘读取后
    • 网络请求返回后
      [h3]线程处理[/h3]
    [h1]13-2、阅读时长统计[/h1]
    • 记录器
      • 页面记录
      • 流式
      • 自定义
    • 记录管理者
      • 前后台切换
      • 从无网到有网的变化
      • 记录缓存
      • 磁盘储存
      • 上传器(延时上传)
    • 处理数据丢失
      • 定时储存
      • 100条储存
    [h1]13-3、负责页面架构[/h1]
    • 整体框架
    • 数据流
    • 反向更新
    [h2]MVVM[/h2]
    • view(ViewController)
    • ViewModel
    • Model(Engeer)
    [h1]13-4、整体框架[/h1]
    • 独立于App的通用层
    • 通用业务层
    • 中间层
    • 业务ABCD
      [h2]业务解耦[/h2]
    • OpenUrl
    • 依赖注入(中间层)
    14.算法

    • 字符串反转 ;
      • 俩头交换
    • 链表反转
      • 插入头部
    • 有序数组合并
      • 比较大小,添加到新的数组
    • Hash算法
      • 字符对应的aciic码表
    • 查找两个子视图的共同父视图
      • 所有父视图 倒序比较
    • 求无序数组当中的中位数
    15.第三方库
    15-1、AFNetworking
    架构图



    • AFURLSessionManager 核心类
      • NSUrLSession
      • AFSecurityPolicy
      • AFNetworkReachablilityManager
      • 创建和管理NSUrLSession、NSURLSessionTask
      • 实现NSURLSessionDelegate等协议的代理方法
      • 引入AFSecurityPolicy保证请求安全
      • 引入AFNetworkReachablilityManager监控网络状态
    • AFHTTPSessionManeger
      • AFURLRequestSerialzation
      • AFURLResponseSerial
    [h1]15-2、SDWebImage[/h1]架构图



    15-3、ReactiveCocoa
    函数响应式编程框架,信号,订阅信号ReactiveCocoa中核心类RACSignal -> RACStream
    • RACDynamicSignal
    • RACReturnSignal
    • RACEmptySignal
    • RACErrorSignal
    [h2]a.信号[/h2]代表一连串的状态
    • empty,return,bind,concat,zipWith
      [h2]b.订阅 RACSubscriber[/h2]start -> RACSignal -> -subscribeNext: -> RACSubscriber -> -sendNext: -> -sendCompleted
    [h1]15-4、AsyncDisplayKit[/h1]提升iOS界面渲染性能的一个框架主要处理问题
    • Layout 文本宽高计算、视图布局计算
    • Rendering 文本渲染、图片解码、图形绘制
    • UIKit Objects 对象创建、对象调整、对象销毁
    [h2]基本原理[/h2]
    • ASNode === UIView === CALayer
    • 针对ASNode的修改和提交,会对其进行封装提交到一个全局容器当中
    • ASDK也在RunLoop中注册了一个Observer
    • 当RunLoop进入休眠前,ASDK执行该Loop内提交的所有任务








分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:
帖子:
精华:
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP