iOS 面试题汇总

 

系统学习推荐一些经典书籍:
《Effective Objective-C 2.0》
《Objective-C 高级编程》

 

本文收录了一些 iOS 常见的面试题目,重点是要理解其背后原理实现,知道其具体应用场景。

iOS 面试题汇总_第1张图片

 

  • Runloop 的实现原理和数据结构,及其应用?

包括 Runloop 与线程的关系,NSRunloop 和 CFRunLoopRef,  pthread_t 和 NSThread, 线程和 RunLoop, Runloop 的 Mode 等

参考:深入理解 Runloop, iOS Runloop 详解, iOS 刨根问底--深入理解 Runloop

 

  • 谈谈对 runtime 的理解,及其应用, 为什么称 OC 为动态语言?

包括 isa 指针, SEL,  IMP,MetaClass,objec_msgSend,消息转发, Method Swizzling,Objective-C Associated Objects,performSelector(iOS performSelector(参考))等。

Objective-C Associated Objects可用于给Category 添加属性, 给 button 点击事件添加参数(iOS UIButton点击事件传递参数的解决办法) 。

动态语言:

  1. 消息传递机制, 动态查找方法实现 objc_msgSend(obj, foo)
  2. Method Swizzling类似1, 消息传递时动态替换方法实现
  3. Category 动态添加类方法, 实例方法, 属性等 4.Objective-C Associated Objects 动态添加关联值

参考:iOS Runtime 详解,Objective-C runtime

 

  • 内存管理

包括 ARC, MRC, 内存泄露,野指针,循环引用,内存泄露调试工具,堆,栈等

参考:iOS内存管理机制, iOS开发堆栈你理解多少?, iOS 面试题汇总

 

  • 多线程,哪些场景需要开辟线程?

包括 NSTread, NSOperationQueue,CGD,同步锁,主线程刷新 UI, 同步,异步,并行,串行

进程和线程:
1. 根本区别: 进程是一个正在执行的程序实例, 是操作系统资源分配的基本单位,而线程是任务调度和执行的基本单位.

2. 开销方面:每个进程都有独立的代码和数据空间(程序上下文),程序之间的切换会有较大的开销;

线程可以看做轻量级的进程,同一类线程共享代码和数据空间,每个线程都有自己独立的运行栈和程序计数器(PC),线程之间切换的开销小。

3. 所处环境:在操作系统中能同时运行多个进程(程序);而在同一个进程(程序)中有多个线程同时执行(通过CPU调度,在每个时间片中只有一个线程执行)

4. 内存分配方面:系统在运行的时候会为每个进程分配不同的内存空间;而对线程而言,除了CPU外,系统不会为线程分配内存(线程所使用的资源来自其所属进程的资源),线程组之间只能共享资源。

iOS多线程使用并不复杂,关键是如何控制好各个线程的执行顺序、处理好资源竞争问题。

参考:iOS 中的多线程技术,iOS 并行开发系列--并行开发其实很容易

 

  • Autoreleasepool 原理和使用场景

参考:黑幕背后的 Autoreleasepoo

 

  • App 的启动过程

参考:深入理解 iOS App 的启动过程

 

  • UIViewController 生命周期

参考:探究 UIViewController 生命周期

 

  • UIView 的绘制流程

包括 init, initwithcode, awake, layoutsubviews, drawrect 等方法的调用顺序,使用xib, storyboard 的调用顺序

setNeedsDisplay, layoutIfNeeded,hittest, pointinside

参考:谈谈 layoutSubviews 和 drawrect,UIView 的 hitTest 和pointInside 方法

 

  • UIView 的 layer

包括 anchorPoint,position,各种动画

参考:iOS 开发系列--让你的应用动起来

 

  • Block 本质

包括 __weak 和 __block,循环引用问题

参考:iOS Block 用法和实现原理

 

  • property(属性) 和 ivar(成员变量) 的区别

包括属性关键字 strong,weak,assign, retain, copy, atomic, nonatomic,readonly, readwrite

属性是对成员变量的一种封装。可以大概理解为: @property = ivar + getter + setter;

property的特质分为三类:

1.原子性--- nonatomic 特质 (iOS atomic 对象是线程不安全的原因以及与 nonatomic 的区别)

atomic是Objc使用的一种线程保护技术,基本上来讲,是防止在写未完成的时候被另外一个线程读取,造成数据错误。而这种机制是耗费系统资源的,所以一般地,如果没有使用多线程间的通讯编程,那么nonatomic是一个非常好的选择。

而且atomic所说的线程安全只是保证了getter和setter存取方法的线程安全,并不能保证整个对象是线程安全的。要保证线程安全还要使用 lock.

2.读/写权限---readwrite(读写)、readonly (只读)

3.内存管理语义---assign、 retain、copy、strong、 weak、unsafe_unretained

参考:iOS 开发 @property 和 ivar 的区别,OC MRC 成员变量, property, synthesize, dynamic

 

  • static, const, extern 关键字的作用

参考:OC 中的 static,const,extern 的理解, iOS开发中的关键字const/static/extern

 

  • KVO 和 KVC,Delegate,单例, Notification等设计模式

 

  • Category 和 Extension, Protocol

参考: iOS Category(类目)和 Extension(扩展) 的区别和创建

 

  • iOS中常用的数据存储方式有哪些?

包括 NSUserDefault,KeyChain, plist,Archive(归档), 读写,SQLite,CoreData

 

  • iOS的沙盒机制

如何访问其它应用:iOS 开发之沙盒机制, iOS项目中的URL Schemes与白名单, 跳转三方地图, 

 

  • OC 和 Swift 对比

(1)Swift 是一门类型安全(Type Safety)的语言,

编译时会检查进行类型检查(type checks), 类型不匹配会报错,然而这并不意味着要声明每一个常量或变量的类型,编码器会通过所赋值的类型进行类型推断(Type inference),但是必须声明是常量还是变量

(2)面向协议编程 POP

 Swift 的标准库中有超过 50 个协议,例子, 实现输入框抖动, 按钮抖动, 如果自定义两个子视图, 修改时需要修改两个,如果使用 extension 抖动方法就到处都是了.使用协议只需定义协议, 让需要调用的类服从协议即可调用, 或者使用Protocol extension.

协议还可以做变量类型, 参数类型

(3)可选类型

可选类型使用时要使用 if 或 guard 进行判断是否为 nil

(4) let var

(5) class struct enum

Swift 中所有的基本类型---整数(Integer)、浮点数(floating-point)、布尔值(Booleans)、字符串(string)、数组(array)和字典(dictionaries),都是值类型,并且都是以结构体的形式在后台所实现。

Class 和 Struct 相同点:

//1. 定义属性用于存储值

        //2. 定义方法用于提供功能

        //3. 定义下标用于访问值

        //4. 定义构造器用于生成初始化值

        //5. 通过扩展以增加默认实现的功能

        //6. 符合协议以对某类提供标准功能

//Class 不同于 Struct 的特点:

        //1. 允许一个类继承另一个类的特征

        //2. 类型转换(Type casting)允许在运行时检查和解释一个类实例的类型

        //3. 解构器允许一个类实例释放任何其所被分配的资源

        //4. 引用计数允许对一个类的多次引用

类和结构体的选择

        //结构体的适用场景:

        //结构体的主要目的是用来封装少量相关简单数据值。

        //有理由预计一个结构体实例在赋值或传递时,封装的数据将会被拷贝而不是被引用。

        //任何在结构体中储存的值类型属性,也将会被拷贝,而不是被引用。

        //结构体不需要去继承另一个已存在类型的属性或者行为。

        

        //合适的结构体候选者包括:

        //几何形状的大小,封装一个width属性和height属性,两者均为Double类型。

        //一定范围内的路径,封装一个start属性和length属性,两者均为Int类型。

        //三维坐标系内一点,封装x,y和z属性,三者均为Double类型。

        

        //在所有其它案例中,定义一个类,生成一个它的实例,并通过引用来管理和传递。实际中,这意味着绝大部分的自定义数据构造都应该是类,而非结构体。

(6) 泛型

sum 函数, OC 中两个 int, 两个 Float相加 需要分别写两个函数, Swift 中只需要写一个,调用时传入类型即可

 

  • iOS 消息传递链

hittest 等

参考:iOS 消息传递机制

 

  • UITableView 性能优化, cell 重用

 

  • 开源框架源码: AFNetworking, SDWebImage 等

 

  • 代码调试编译: lldb, llvm, clang(iOS——LLVM、Clang浅析), mach-o, 代码混淆, 国际化

 

  • 常见错误及调试: iOS 常见崩溃, 调试技巧

 

  • App 上架流程, 被拒原因

 

  • Flutter, Hybrid App, 小程序

 

 

面试题参考:

  1. iOS 面试题汇总
  2. 2018 iOS 面试题及答案

你可能感兴趣的:(iOS)