2020年春招过半,iOS开发面试题清单,带你高效刷题!

2020年春招过半,iOS开发面试题清单,带你高效刷题!
最新回答
不与情长

2020-12-16 10:39:05

2020年春招iOS开发面试题清单

以下整理了2020年春招中常见的iOS开发面试题,涵盖runtime、内存管理、多线程、架构设计等核心知识点,帮助高效刷题备战面试。

一、runtime相关问题

  • 内存模型

    isa:指向类或元类的指针,普通对象指向类,类对象指向元类。

    对象结构:包含isa、成员变量等。

    类结构:包含superclass、方法缓存、方法列表等。

    metaclass:存储类的类方法,所有元类的isa指向根元类(NSObject的元类),形成闭环。

    结构体存储:class_rw_t(可读写,含方法列表、属性、协议)、class_ro_t(只读,编译期确定)。

  • metaclass设计原因统一管理类方法,使类对象能调用类方法(如+ (void)method),避免与实例方法混淆。

  • class_copyIvarList vs class_copyPropertyList

    IvarList:返回所有成员变量(包括@private和@protected)。

    PropertyList:仅返回@property声明的属性(自动合成实例变量)。

  • class_rw_t与class_ro_t区别

    ro_t:编译期确定,存储方法、属性、协议的初始列表。

    rw_t:运行时动态添加方法或属性时使用,包含ro_t和可修改的列表。

  • Category加载机制

    加载顺序:按编译顺序加载,后编译的Category方法覆盖先编译的。

    同名方法:后加载的Category方法会覆盖先加载的。

    load方法:在main函数执行前调用,按编译顺序执行。

  • Category vs Extension

    Extension:需在.m文件中声明,可添加实例变量和私有方法。

    Category:无法添加实例变量,只能扩展方法。

    NSObject Extension:可添加,但需在.m文件中实现。

  • 消息转发机制

    步骤:动态方法解析 → 备用接收者 → 完整消息转发。

    优势:灵活(如实现多继承),但性能较低(需多次查找)。

    与其他语言对比:Java/C#通过接口或虚函数表实现,更高效但灵活性差。

  • 方法调用流程

    缓存查找:优先在方法缓存中查找IMP。

    动态解析:若未找到,调用+resolveInstanceMethod:动态添加方法。

    消息转发:若仍未解决,进入转发流程。

  • IMP、SEL、Method区别

    SEL:方法选择器,类型为char*的唯一标识。

    IMP:函数指针,指向方法实现(id (*)(id, SEL, ...))。

    Method:结构体,包含SEL和IMP。

  • load vs initialize方法

    load:在main函数前调用,每个类/Category仅一次,按编译顺序执行。

    initialize:在首次发送消息前调用,子类未实现时会调用父类方法,仅一次。

二、内存管理

  • weak实现原理

    SideTable:全局哈希表,键为对象地址,值为SideTableEntry(包含引用计数和弱引用表)。

    弱引用表:存储指向对象的weak指针,对象释放时将所有weak指针置为nil。

  • 关联对象实现

    存储:通过ObjectAssociationsMap全局哈希表管理,键为对象地址,值为关联对象列表。

    内存管理:关联对象遵循普通对象的引用计数规则,需手动管理或使用OBJC_ASSOCIATION_RETAIN等策略。

  • Autoreleasepool原理

    数据结构:栈结构的AutoreleasePoolPage(每个页4096字节),包含next指针和thread字段。

    操作:push时压入POOL_BOUNDARY,pop时释放next之前的对象。

  • ARC实现原理

    编译期优化:插入retain/release代码,消除冗余操作(如局部变量无需release)。

    优化技术:合并相邻的retain/release,使用objc_storeStrong替代直接操作。

  • ARC内存泄漏场景

    循环引用:如Delegate属性用strong修饰。

    未释放资源:如NSTimer未调用invalidate。

    C语言资源:如malloc分配的内存未free。

三、多线程

  • GCD队列类型

    串行队列:任务按顺序执行。

    并发队列:任务并发执行(系统提供全局并发队列)。

    主队列:串行队列,与主线程关联。

    自定义队列:通过dispatch_queue_create创建。

  • GCD方法API

    同步任务:dispatch_sync(阻塞当前线程)。

    异步任务:dispatch_async(非阻塞)。

    单次执行:dispatch_once(保证代码仅执行一次)。

  • 死锁场景

    主队列同步任务:如dispatch_sync(dispatch_get_main_queue(), ^{})会导致死锁。

    串行队列嵌套:在串行队列中同步派发任务到同一队列。

  • 线程锁类型

    @synchronized:递归锁,性能较低。

    NSLock:普通互斥锁。

    NSRecursiveLock:递归锁,允许同一线程多次加锁。

    pthread_mutex:C语言级锁,性能更高。

四、视图与图像

  • AutoLayout原理

    约束引擎:通过线性方程计算帧,使用Cassowary算法解决冲突。

    性能优化:减少约束数量,避免复杂视图层级。

  • UIView vs CALayer

    UIView:负责事件处理、视图层级管理。

    CALayer:负责渲染、动画,包含contents(显示内容)和sublayers。

  • 离屏渲染

    触发条件:圆角、阴影、遮罩等需额外绘制的操作。

    优化:提前合成图片(如用UIBezierPath绘制圆角)。

  • imageName vs imageWithContentsOfFile

    imageName:缓存到系统,适合重复使用的图片。

    imageWithContentsOfFile:不缓存,适合大图或一次性图片。

五、性能优化

  • 启动优化

    监控工具:Instruments的Time Profiler。

    优化方法:延迟初始化非关键资源、减少dylib加载数量。

  • 卡顿优化

    监控:CADisplayLink检测帧率,Instruments的Core Animation工具。

    优化:减少主线程耗时操作(如JSON解析)、优化drawRect。

  • 耗电优化

    监控:Energy Log。

    优化:减少定位、网络请求频率,使用WKWebView替代UIWebView。

六、架构设计

  • 设计模式

    MVC:Model-View-Controller,适合简单项目。

    MVVM:Model-View-ViewModel,通过RAC或KVO绑定数据。

    VIPER:View-Interactor-Presenter-Entity-Router,适合大型项目。

  • 路由方案

    `