网络知识 娱乐 2022iOS面试题集锦(iOS interview)

2022iOS面试题集锦(iOS interview)

1、面试一

1.1、#include 和 #import的区别

主要知识点:递归循环引入的问题
导入的文推荐格式,均可以导入 C/C++头文件,#include还能导入更多格式类似txt
导入的方式:#include是将文件内容复制到指令处
导入文件的查找方式:#include当前文件所处文件夹,再找不到就从当前文件夹的父文件夹查找,再不行就是往上推,再找不到就IDE设置的查找路径,再找不到就从系统环境变量配置的地址。
再讲讲"" && 的异同。

1.2、初始化返回值 id 和 instancetype 的区别

  1. 相同点:
  • 都可以作为返回值
  1. 不同点
  • instancetype 可以返回和方法所在类相同类型的对象,id只能返回未知类型的对象
  • instancetype 只能作为返回值,id可以作为参数类型

1.3、成员变量会出发KVO手动触发KVO的方式

成员变量可以
手动触发的方式KVO

1.4、 RunLoop 的理解 Source0、1的区别

1是基于端口的。0是基于非端口的。可以将runloop启动的过程讲一遍。
主要包含两个observer, 监听runloop entry状态,第二个observer主要监听beforeWaiting状态和 exit状态。然后静候面试官的问题,看看想要更深入的了解哪部分的。

1.5、定时器造成的卡顿的解决方案

按照提问的顺序,面试官可能对RunLoop比较感兴趣,可以讲讲定时器,在runloop中是如何注册事件的。然后讲讲定时器tolerance的问题,关于注册的事件,被一事件处理耽误过后并不会响应的问题。然后讲讲方案,丢到子线程中(主线程刷新UI),添加到RunLoop中。以及CADisplayer方案原理需要储备。

1.6、分类中的同名函数调用顺序

这个问题可以先讨论,一般函数的调用顺序,一般函数调用的顺序其实主要考察了runtime的知识点,关于分类和主类合并的过程中使用的movecopy.就是说主类函数后移,分类放在前面。故此处的一般函调用顺序是分类被编译的先后顺序。这里还有更深入的问题就是load,initailize的顺序。

1.7、关于RunLoop的理解

先用一句话来概述RunLoop是啥,RunLoop与线程的对应关系。因为知识点比较庞大,我们可以等面试官来问一下他想知道的点。Jeverson这里的想知道souce0,1的事情。然后Jeverosn讲了区别。然后又继续问了关于定时器在滑动过程为什么不工作的原因。Jeverson讲了关于runloop``mode切换的原因导致的。然后讲讲解决方案。

补充RunLoop的知识点还有很多,比如AFN2.x的常驻线程,常驻线程的使用场景。事件响应过程渲染过程异步绘制子线程使用peformselector:delay:的问题NSTimer的问题

2、面试二

2.1 跨平台方案

2.1.1 您接触过的跨平台方案有哪些?

Flutter, ReactNative

2.1.2 这两种方案的比较

综述一下FlutterReactNative 实现跨平台的方式,前者提供渲染引擎SDK使用dart驱动,后者是通过JscoreJsbridgenative 通信的。后面在讲描述组件结构结构树,讲讲AST中避免整个DOM更新/销毁的 VirtualDOM。讲了者玩意就会给你来点diff的问题

2.1.3 关于ReactNativekey开发中使用啥来给他赋值,用数组的index会有啥问题

VirturalDOM当前新DOM需要使用diff算法来比较结构树是否有变化,默认的key值就是idex组件具有唯一约束的属性id, 取的就是key值,当我们数组中对象的属性时(不修改数据源顺序), diff的时候就有问题,id0 的节点,virtualDom也存在,直接保留组件。但是这里的组件是要更新的!

2.1.5 关于Flutter A push B, B pop A ,A widget 状态保持的问题

AutomaticKeepAliveClientMixin 协议

2.1.4 Hybrid 的方式

拦截URljs注入,这里呢主要还有个UIWebView, 和WKWebView 两者前面方式不一样。描述一下即可。如果想再深入的交流WK做了哪些优化。

2.2 Runtime 相关

2.2.1 简述一下runtime

ObjC 是一门动态语言 runtime 为其动态性提供支持,所有应用将会连接到runtime 这个库中

2.2.2 ObjC作为一门动态语言,对象调用方法的过程是什么?

Person *p = [[Person alloc] init]; [p goodJob]; 首先讲出来这是个消息机制 然后讲一下实际发消息在 runtime 中是objc_msgSend, 然后讲讲p对象是个receiver, 然后讲讲p 对象是怎么找方法的. 也就是根据对象 isa指针找到class对象,从他的methodlist 中寻找,如果找不到会找到meta Class 对象寻找,再找不到就去root meta class,然后再从NSObject 中找在找不到就进入消息转发阶段。若三次转发还有没有,就直接unrecognizeMethod.

2.2.3 刚刚讲述到了方法的寻找,能给我讲讲类的数据结构吗

这里考察的问题是: class_rw_t, 和class_ro_t, 方法列表,属性列表协议列表成员变量,和ro 的指针。 这里还会问到ro 存放的是啥。

2.2.3 刚刚讲述的方法中少了类方法,+方法,存在哪里。寻找过程是怎么样的?

这里考察的问题是meta class 讲述出来,类方法存在与meta class 中,方法找寻的过程是从meta classisa 指针的指向。

2.2.4 请讲述一下消息转发的过程

  • 快速转发resolveInstanceMethodresolveClassMethod
  • 慢速转发methodSignatureForSelectorforwardInvocation
    这里指的注意的是NSInvocation的数据结构也了解一下

2.2.5 消息转发的应用场景

  • json null 问题等。

2.2.6 NSProxy

了解一下原理,以及timer 循环引用中使用,NSProxy;以及其中必须实现的方法。

2.3 Block 相关

2.3.1 谈谈您对block的了解

block是包含函数执行上下文的OC对象

2.3.2 Block的类型

简述一下全局block栈block堆block;以及描述一下ARC中将栈block copy到堆block的情况。有条件可以讲讲block获取变量的方式:值截获地址截获

2.3.3 __block修改局部变量的方式

__block 修饰的局部变量,其实就是修改了Auto变量的__forwarding 指向,指向在堆中变量。这样block修改局部变量的时候,就能轻松的持有堆中的变量。

2.3.4 block中的循环引用问题

解决方式是断开一方的强引用。__weak修饰。当然也可以使用unsafe_unretained,后者有可能会出现野指针的问题。

2.3.5 __weak的原理

简述一下weak修饰符的使用场景。以及weak的数据结构,哈希表。以及当weak指针指向的对象被销毁的过程中,如何从HashTable中移除weak修饰的对象并滞空的。需要准备weak_store()的过程,已经SideTable的数据结构。

2.3.6 NSMuteableArray的坑

可变数组中,遍历删除的会有问题吗?,挖坑题,这种情况只会出现在数组增强for循环,非反转数组便利的删除过程,会报错在便利过程中,修改原数组的异常。

3.面试三

3.1 KVO的原理

简述一下,KVO其实就是让类接收属性变化通知的过程。即生成NSOObserveringNotify_XXX子类,isa_swizzling将原对象的isa指针指向那个子类,重写set方法,调用NSObject,willChangeValueForKey 调用父类的set方法didChangeValueForKey.

3.1.1 KVC的原理

3.2 RunTime相关

3.2.1 消息机制

与上述问题重复,此处不再赘述

3.2.1 消息转发

与上述问题重复,此处不再赘述

3.2.2 类的数据结构

rw, ro, 都描述一下,主要包含属性列表协议列表成员变量方法列表,描述一下rorw的区别,主要讲述一下ro主要包含编译器期间的信息。可能会问到category方法合并的问题,在什么时间合并,合并到哪里。讲述一下即可。

3.2.3 元类的数据结构

此处主要考察的是,元类中主要和类有啥区别,讲述一下类方法存储在元类中。其他的结构和类相似。

3.3RunLoop

3.3.1 简述一下RunLoop的理解

与上面回答重复,此处不再赘述

3.3.2 autoreleasepool的数据结构

双向链表

3.4 3rdKitSource

3.4.1 AFNetWorking

  • AFN2.x 和 AFN3.x的变化
    • NSURLConnection -> NSURLSeesion
    • 取消常驻线程
3.4.1.1 AFN2.x 常驻线程的实现方式

NSThread + RunLoop

3.4.1.2 NSURLSeesion 为什么不需要常驻线程

NSURLConnection 请求是异步的,请求返回需要在当前线程中等待。为了避免线程的开销,节省资源,故采用常驻线程的方式。
NSURLSession NSOperationQueue对网络回调的管理,并且设置maxConcurrentOperationCount为1,保证了最大的并发数为1,也就是说让网络请求串行执行。避免了多线程环境下的资源抢夺问题。

3.4.2 SDWebImage

SDWebImage是一套封装良好的第三方库,分析源码能得到很大的启发。建议去浏览一下源码。配合源码去总结一下,这里指提供一些思路。

  • 目录结构,SD的上层APIUIView+Category, SDWebImageManager, SDWebImageDownloader&&SDWebImageDownloaderOperation 以及SDImageCache,
  • SDWebImage缓存策略,三级缓存内存缓存磁盘缓存网络缓存
  • 当使用上层API的使用,SDWebImage做了啥。

last

  • 祝大家前程似景,收获自己满意的offer

log

  • add the part1 on Feb.27
  • add the part2 2.2.3 on Mar.4
  • add the part3 3.4.2 on Mar.15