iOS高级面试题

以下是通过极客时间《iOS高级课》中总结的面试题,仅供参考。

  1. 以下关于 objc_msgSend 和 fishhook 的说法中,哪些是正确的?
    A. objc_msgSend 是使用 C 语言编写的
    B. objc_msgSend 在运行时根据对象和方法的 selector 找到对应的函数指针,然后执行
    C. 可以使用 fishhook 来 hook objc_msgSend
    D. fishhook 通过重新绑定符号,实现对 c 方法的 hook

    答案:B, D
    A 选项,objc_msgSend 是使用汇编语言编写的。
    C 选项,hook objc_msgSend 还需要用到汇编。

  2. Auto Layout 的布局工作过程描述,哪些是正确的?
    A. Layout Engine 在碰到约束变化后不会重新计算布局
    B. Constraints Change 不会触发约束变化
    C. Layout Engine 会将视图、约束、优先级、固定大小通过计算转换成最终的大小和位置
    D. 在 Layout Engine 里,每当约束发生变化,就会触发 Deffered Layout Pass

    答案:C, D
    A 选项,Layout Engine 在碰到约束变化后会重新计算布局,获取到布局后调用 superview.setNeedLayout(),然后进入 Deferred Layout Pass。
    B 选项,Constraints Change 表示的就是约束变化,添加、删除视图时会触发约束变化。

  3. 链接器对代码做的事情,哪些是正确的?
    A. 去项目文件里查找目标代码文件里已经定义的变量
    B. 扫描项目中的不同文件,将所有符号定义和引用地址收集起来,并放到全局符号表中
    C. 计算合并后长度及位置,生成同类型的段进行合并,建立绑定
    D. 对项目中不同文件里的变量进行地址重定位

    答案:B, C, D
    A 选项,查找没有定义的变量。

  4. 下面哪些工具可以作为静态分析器?
    A. OCLint
    B. Infer
    C. Injection
    D. ImageOptim

    答案:A, B
    C 选项,Injection 的工具用来动态地将 Swift 或 Objective-C 的代码在已运行的程序中执行,以加快调试速度,同时保证程序不用重启。
    D 选项,ImageOptim 是图片压缩工具。

  5. 关于减少 App 包大小,哪些说法是正确的?
    A. 通过 AppCode 找出无用代码
    B. LinkMap 结合 Mach-O 找无用代码
    C. 使用 LSUnusedResources 进行图片压缩
    D. 使用 App Thining 可以减少包大小

    答案:A, B
    C 选项,LSUnusedResources 是找无用图片的工具,TinyPng 或 ImageOptim 才是图片压缩的工具。

  6. 下面哪些问题是信号可捕获的?
    A. 内存被打爆
    B. NSNotification 线程问题
    C. 后台任务超时
    D. 野指针

    答案:B, D
    A 选项和 C 选项是无法通过信号捕获的。

  7. 下面哪个异常编码,是表示 App 在一定时间内无响应而被 watchdog 杀掉的?
    A. 0xdeadfa11
    B. 0xc00010ff
    C. 0x8badf00d
    D. 0xdead10cc

    答案:C
    A 选项,表示 App 被用户强制退出。
    B 选项,表示 App 因为运行造成设备温度太高而被杀掉。
    D 选项,表示死锁,当 App 在后台运行时,持有了系统资源。

  8. 导致卡顿的原因,以下说法哪些是正确的?
    A. 复杂 UI 、图文混排的绘制量过大
    B. 在主线程上使用锁
    C. 在主线程做大量的 IO 操作
    D. 运算量过大,CPU 持续高占用

    答案:A, C, D
    B 选项,主线程上使用锁不一定会导致卡顿,死锁和主子线程抢锁才会。

  9. 以下哪些方法可以获取内存上限值?
    A. 通过 JetsamEvent 日志计算内存限制值
    B. 通过 XNU 获取内存限制值
    C. 通过内存警告获取内存限制值
    D. 通过 hook malloc_logger 函数来获取内存限制值

    答案:A, B, C
    D 选项,hook malloc_logger 用来定位谁分配的内存。

  10. 关于线程,以下哪些说法是正确的?
    A. UIKit 是线程安全的
    B. UIKit 没有使用多线程技术
    C. 常驻线程一直存在于内存中
    D. 线程开多了会有内存问题

    答案:B, C, D
    A 选项,UIKit 不是线程安全的。

  11. 以下哪些是可以在 iOS 中使用的 GUI 框架?
    A. WebKit
    B. Flutter
    C. Blink
    D. Texture

    答案:A, B, D
    C 选项,Blink 是谷歌从 WebKit 中 WebCore 拉出的分支,用于 Chrome 中,无法用在 iOS 中。

  12. 关于 iOS 开发中使用的开源库,下面哪些说法是正确的?
    A. ReactiveCocoa、RxSwift、React.js 都是 iOS 响应式框架
    B. Lottie 框架可以解决动画制作与开发隔离,以及多平台统一的问题
    C. SkyLab 可以用来作 A/B 测试
    D. Promise 可以提高 JSON 解析的性能

    答案:B, C
    A 选项,React.js 是前端响应式框架。
    D 选项,Promise 是一种专门针对异步数据操作编写的一套统一规则的模式,可以用于事件总线的数据订阅和数据发布事件。

  13. iOS 系统可以分为哪几层?
    A. 最一层是 Topaz 层
    B. 第二层是应用框架层
    C. 第三层是微内核层
    D. 第四层是 Darwin 层

    答案:B, D
    A 选项,第一层是户体验层,主要是提供用户界面。这一层包含了 SpringBoard、Spotlight、Accessibility。Topaz 层是 Fuchsia 的系统基础应用层。
    C 选项,第三层是核心框架层,是系统核心功能的框架层。

  14. 关于 iOS 的 Runtime,以下说法哪些是正确的?
    A. 可以帮助我们在运行时进行方法交换
    B. 在原方法执行之前插入自定义方法
    C. 直接使用 Runtime 方法交换开发很安全,无风险
    D. Runtime 不光能够进行方法交换,还能够在运行时处理 Objective-C 特性相关(比如类、成员函数、继承)的增删改操作

    答案:A, B, D
    C 选项,直接使用 Runtime 的方法进行方法交换会有很多风险,更安全的是使用 Aspects。

  15. 关于函数调用,以下哪些说法是正确的?
    A. dlsym() 无法通过函数名字符串获取函数地址
    B. 编译时需要按照调用惯例针对不同 CPU 架构编译,生成汇编代码,确定好栈和寄存器
    C. Objective-C 的函数调用采用的是发送消息的方式
    D. Objective-C 具备动态调用函数的能力

    答案:B, C, D
    选项 A,dlsym() 可以通过函数名字符串拿到函数地址。

  16. 以下关于 libffi 的说法,哪些是正确的?
    A. libffi 中 ffi 的全称是 Foundation Function Interface
    B. libffi 还提供了可移植的高级语言接口,可以不使用函数签名间接调用 C 函数
    C. libffi 通过发送消息的方式来进行函数调用
    D. libffi 的作用类似于一个动态的编译器,在运行时就能够完成编译时所做的调用惯例函数调用代码生成

    答案:B, D
    A 选项,全称是 Foreign Function Interface。
    C 选项,libffi 是通过调用 ffi_call(函数调用) 来进行函数调用。

  17. 关于 ffi_call_SYSV 处理过程,以下说法哪些是正确的?
    A. ffi_call_SYSV 会先分配 stack 和 frame,保存记录 fn、rvalue、closure、flags
    B. 将向量参数传到寄存器,按照参数放置规则,调整 sp 的位置
    C. 将参数放入寄存器,存放完毕,就开始释放上下文,留下栈里的参数
    D. 调用完函数指针,直接保存返回值

    答案:A, B, C
    选项 D,调用完函数指针,保存返回值之前需要重新读取 rvalue 和 flags,析构部分栈指针。

  18. 以下关于 JavaScriptCore 的说法,哪些是正确的?
    A. JavaScriptCore 框架主要由 JSVirtualMachine 、JSContext、JSValue 类组成
    B. JSVirtualMachine 里只包含一个 JSContext,一个 JSContext 中可以有多个 JSValue
    C. JavaScriptCore 内部是由 Parser、Interpreter、Compiler、GC 等部分组成
    D. 原生线程可以将类方法和属性提供给 JavaScriptCore 使用

    答案:A, C, D
    B 选项,JSVirtualMachine 里可以有多个 JSContext。

  19. 关于渲染原理,下面说法哪些是正确的?
    A. CPU 内部流水线结构拥有并行计算能力,一般用于显示内容的计算
    B. GPU 专门用来处理渲染内容的计算,比如视图创建、布局、图片解码等
    C. GPU 的主要工作是将 3D 坐标转化成 2D 坐标,然后再把 2D 坐标转成实际像素
    D. CPU 处理完渲染内容的计算,然后将图形结果显示在屏幕像素中

    答案:A, C
    B 选项,GPU 并行计算能力强,通过计算将图形结果显示在屏幕像素中,渲染内容的计算,通常使用 CPU 完成。
    D 选项,CPU 专门用来处理渲染内容的计算,比如视图创建、布局、图片解码等,内容计算完成后,再传输给 GPU 进行渲染。

  20. 以下动态化方案的说法,哪些是正确的?
    A. JIT 技术就是在 App 运行时创建机器代码,同时执行这些机器代码
    B. LLVM IR 是 SSA 形式的
    C. SSA 主要解决的是,多种数据流分析时种类多、难以维护的问题
    D. LLVM 里有针对 iOS 系统可用的解释器

    答案:A, B, C
    D 选项,LLVM 没有专门针对 iOS 做解释器,因为 iOS 动态化在 LLVM 所有工作中的优先级并不高。