iOS 技术面试高频题及详细答案(真实职场版)_第1页
iOS 技术面试高频题及详细答案(真实职场版)_第2页
iOS 技术面试高频题及详细答案(真实职场版)_第3页
iOS 技术面试高频题及详细答案(真实职场版)_第4页
iOS 技术面试高频题及详细答案(真实职场版)_第5页
已阅读5页,还剩3页未读, 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

iOS技术面试高频题及详细答案(真实职场版)一、Swift基础语法核心面试题1.Swift中struct和class的核心区别?日常开发如何选型?详细答案:核心区别主要有五点:1.存储方式不同:struct是值类型,存储在栈区;class是引用类型,存储在堆区,栈区仅存储对象地址。2.赋值逻辑不同:值类型赋值、传参时会完整拷贝一份数据,新旧对象互不影响;引用类型赋值、传参仅拷贝内存地址,多个变量指向同一个对象,修改会互相影响。3.继承特性不同:struct不支持继承,无法创建子类;class支持单继承,可层层派生。4.构造器规则不同:struct默认自带成员逐一构造器,无需手动编写;class无默认构造器,自定义构造器后会覆盖默认构造器,需手动指定。5.析构方法不同:struct没有deinit析构方法;class拥有deinit,可在对象销毁前释放资源。开发选型原则:优先用struct:纯数据模型、枚举、配置类、轻量数据结构(如用户信息、列表数据),无复杂业务逻辑,追求低内存开销、线程安全。优先用class:需要继承、需要统一资源管理、存在生命周期、需要引用传参共享数据的场景(如页面控制器、网络请求管理器、单例工具类)。2.Swift中let和const、staticlet的区别?详细答案:1.let:定义常量,可以是实例属性、局部变量。内存在对象初始化时分配,仅能赋值一次,后续不可修改。如果是值类型,内容完全不可变;如果是引用类型,地址不可变,但对象内部属性可以修改。2.staticlet:定义静态常量,属于类型本身,不属于实例,全局唯一,所有实例共享。自带懒加载、线程安全特性,是Swift中单例的最优实现方式。3.const:仅用于OC语法,Swift中无此关键字,Swift统一用let实现常量定义。补充场景:页面内固定参数用let,全局配置、全局单例、固定常量(如接口地址、颜色值)用staticlet。3.解释Swift可选型?!和?的区别、隐式解包使用场景详细答案:可选型是Swift用来解决空值问题的特性,表示变量可以有值,也可以为nil。1.问号?:声明可选变量,使用时必须解包(可选绑定、空合运算符、强制解包),不允许直接使用,安全性高,日常开发首选。2.感叹号!:强制解包,强行取出可选值中的值,如果值为nil,会直接崩溃。非必要不使用。3.隐式解包可选(varname:String!):变量初始可能为空,但后续一定会在使用前赋值,使用时无需手动解包。隐式解包适用场景:控件属性(UIButton、UILabel)、storyboard/xib绑定属性,生命周期内初始化后必然有值,不会为空。4.guardlet和iflet的区别及使用场景详细答案:两者都是可选绑定,用来安全解包可选值,避免强制解包崩溃。1.iflet:条件成立(有值)则执行内部代码,不成立则跳过,作用域仅限大括号内部,适合分支判断逻辑。2.guardlet:条件不成立直接return/break/continue,提前拦截异常逻辑;解包后的变量作用域贯穿整个方法,可在后续代码直接使用。开发规范:方法开头参数校验、空值拦截、权限校验优先用guardlet,减少代码嵌套(金字塔地狱);局部分支判断用iflet。二、内存管理&闭包核心题1.Swift内存管理机制?ARC原理是什么?详细答案:Swift和OC一致,采用ARC(自动引用计数)管理堆内存,栈内存自动回收无需管理。核心原理:1.当创建一个堆对象时,引用计数+1;2.当有新变量指向该对象,引用计数+1;3.当变量销毁、置空、超出作用域,引用计数-1;4.当引用计数归0,系统立即销毁对象,释放堆内存。ARC是编译期特性,编译器会自动在合适位置插入retain、release、autorelease代码,无需手动管理,仅需处理循环引用问题。2.什么是循环引用?如何解决Swift循环引用?详细答案:两个及以上引用类型对象,互相强引用对方,导致引用计数永远无法归0,对象无法销毁,造成内存泄漏。常见场景:页面控制器与自定义View、闭包回调、代理回调。解决方案:1.weak弱引用:不持有对象,引用计数不改变,对象销毁后自动置空nil,适用于代理、控件引用、父引用子场景。2.unowned无主引用:类似weak,但不会自动置空,对象销毁后访问会崩溃,适用于生命周期完全一致的对象。3.闭包循环引用:使用[weakself]/[unownedself]解除强引用,页面回调、网络请求回调必加。开发规范:代理统一用weak修饰,闭包优先用weakself。3.闭包的特性?逃逸闭包和非逃逸闭包区别详细答案:闭包是自包含的代码块,可以捕获、存储、传递变量,默认会捕获上下文变量并强引用,极易产生循环引用。1.非逃逸闭包(默认):@noescaping,闭包执行完立即销毁,生命周期在函数内部结束,不会逃逸出函数,无需处理循环引用。2.逃逸闭包:@escaping,闭包会在函数执行完毕后继续执行(如网络回调、异步回调、延时任务),会逃逸出函数作用域,必须注意self引用,需要加weakself防止内存泄漏。三、UI框架&布局面试题1.Frame和AutoLayout核心区别?各自优缺点详细答案:1.Frame:基于绝对坐标布局,直接设置控件x/y/宽高。优点:代码简洁、渲染效率高、底层计算简单;缺点:适配多机型、屏幕旋转、动态高度极其麻烦,硬编码数值多,维护成本高。2.AutoLayout:基于相对约束布局,通过上下左右、宽高、居中约束确定控件位置。优点:适配性强,适配所有机型、屏幕旋转、动态内容,代码复用性高;缺点:约束计算耗时,复杂层级约束过多会造成卡顿,约束冲突易报错。开发选型:简单固定页面、自定义控件用Frame;复杂适配、列表、动态页面、多机型适配用AutoLayout。2.UIView和CALayer的区别与关系详细答案:1.层级关系:UIView是界面展示载体,所有UI控件都继承自UIView;CALayer是UIView的底层渲染图层,每个View底层都默认自带一个Layer。2.功能区别:UIView负责事件响应、手势交互、用户交互;CALayer负责界面渲染、绘制、动画、样式展示,不处理任何点击事件。3.特性区别:Layer可以多层叠加、可以做阴影、圆角、边框、3D动画;View无法直接做底层渲染样式,所有视觉效果最终都是Layer渲染。4.继承区别:UIView继承自UIResponder,具备事件响应能力;CALayer继承自NSObject,无交互能力。3.iOS页面渲染流程、卡顿原因详细答案:完整渲染流程:布局(Layout)→绘制(Display)→合成(Compose)1.布局阶段:系统计算控件约束、frame、层级位置;2.绘制阶段:Layer渲染文本、图片、颜色、阴影等样式;3.合成阶段:将所有图层合并,提交到屏幕展示。常见卡顿原因:1.主线程耗时操作:网络请求、文件读写、大量计算、数据解析;2.渲染耗时:大量圆角阴影、离屏渲染、图层层级过多、重复布局绘制;3.列表复用不当:cell内部创建大量控件、未复用、实时计算布局;4.约束冲突、自动布局嵌套过多。四、多线程&异步面试题1.iOS多线程方案对比(Thread、GCD、Operation)详细答案:1.Thread:最轻量,手动创建线程,需要手动管理生命周期、线程休眠、销毁,可控性差,极少日常使用,仅适合极简单异步任务。2.GCD:基于C语言,系统自动管理线程池,效率最高,语法简洁,适合大量异步任务、串行/并行队列、延时任务、栅栏任务,是日常开发主流方案。缺点是任务取消麻烦。3.Operation&OperationQueue:基于GCD封装的OC面向对象方案,支持任务取消、任务依赖、任务暂停、最大并发数控制,适合复杂有序的多任务场景(批量下载、批量上传)。2.GCD串行队列、并行队列、主队列区别?死锁场景讲解详细答案:1.串行队列(Serial):任务逐个执行,上一个任务结束才会执行下一个,线程唯一,保证任务顺序。2.并行队列(Concurrent):任务同时并发执行,系统自动开辟多线程,任务无序,效率高。3.主队列:特殊串行队列,绑定主线程,所有UI刷新必须在主队列执行。经典死锁场景:主线程同步执行主队列任务(sync+mainQueue)。主线程正在执行当前代码,又同步阻塞等待主队列任务执行完成,互相等待,造成死锁。开发原则:主线程禁止使用sync同步任务,子线程随意使用sync/async。3.GCD栅栏函数、延时函数使用场景详细答案:1.栅栏函数barrier:在并行队列中,拦截前后任务,栅栏前任务全部执行完毕,再执行栅栏任务,最后执行栅栏后任务。主要用于数据读写安全(多读单写),保证写操作排他性。2.延时函数dispatchAfter:延时执行任务,不会阻塞当前线程,适合弹窗延时展示、倒计时、延迟刷新页面场景。注意:延时任务不精准,受系统线程调度影响。五、列表优化&性能优化面试题1.UITableView/UICollectionView卡顿优化方案详细答案:1.复用机制优化:严格使用cell复用,禁止每次cellForRow新建控件,注册cell全局统一管理。2.布局优化:提前计算cell高度并缓存,避免实时动态计算;减少自动布局嵌套,复杂布局用Frame。3.渲染优化:减少圆角、阴影、渐变等离屏渲染效果;必要时开启masksToBounds优化,避免图层重复渲染。4.数据优化:分页加载,一次性不加载过多数据;数据预处理,提前解析、排序,避免在cell赋值时计算。5.线程优化:图片解码、数据解析、富文本计算全部放在子线程,主线程仅做赋值刷新。6.滑动优化:滑动时停止复杂渲染、停止网络请求,滑动停止后再刷新页面。2.什么是离屏渲染?如何避免?详细答案:屏幕渲染默认在当前屏幕缓冲区进行,当样式复杂(圆角、阴影、遮罩、渐变),系统需要额外开辟新缓冲区渲染,再合并到屏幕,这个过程就是离屏渲染,耗时极高,是列表卡顿核心原因。触发场景:masksToBounds、cornerRadius+阴影、layer遮罩、渐变图层。优化方案:1.图片圆角用裁剪绘图代替系统layer圆角;2.阴影设置shadowPath,提前固定阴影路径,避免实时计算;3.减少不必要的遮罩和渐变,简单样式尽量纯代码绘制。六、OC&Swift混编、底层原理1.Swift和Objective-C混编如何实现?混编注意事项详细答案:1.OC调用Swift:项目自动生成<工程名>-swift.h头文件,导入后可直接调用Swift类和方法;Swift类需加@objc、dynamic暴露给OC。2.Swift调用OC:新建Bridging-Header桥接文件,引入需要暴露的OC头文件,Swift可直接使用OC类、方法、宏。注意事项:1.Swift独有特性(可选型、结构体、枚举)无法被OC识别;2.混编项目编译耗时更长,需合理管理桥接文件;3.宏定义、静态常量建议统一管理,避免两边重复定义。2.iOS单例的几种实现方式及优缺点详细答案:1.常规懒加载单例(OC):线程不安全,多线程下可能创建多个对象,仅适合单线程场景。2.GCD单例(OC):dispatch_once实现,线程安全、高效、一次性创建,是OC最优方案。3.Swiftstaticlet单例:系统自带线程安全、懒加载、代码极简,无冗余代码,是Swift项目首选单例方案。4.手动锁单例:通过NSLock加锁保证线程安全,代码繁琐,性能略差,基本淘汰。七、项目工程化&实战问题1.项目中如何做组件化?组件化核心目的详细答案:组件化是将庞大项目按业务、功能拆分为独立子模块(组件),各组件独立开发、独立编译、互不耦合,通过中间路由通信。核心目的:1.解耦:消除页面直接依赖、代码耦合,避免牵一发动全身;2.提效:多人并行开发,互不冲突,编译速度提升;3.复用:公共组件(网络、登录、工具、弹窗)全局复用;4.维护:业务拆分清晰,bug定位、迭代维护更简单。常用方案:路由跳转+协议注册+中间件通信,杜绝直接导入头文件依赖。2.iOS打包卡顿、编译速度慢如何优化?详细答案:1.编译优化:关闭无用编译选项、开启增量编译、拆分组件减少单次编译代码量;2.资源优化:压缩图片、删除冗余资源、无用代码、重复文件;3.第三方库优化:替换臃肿第三方库、使用静态库/动态库替代源码编译;4.代码优化:减少嵌套、减少重复计算、拆分大文件、单个文件代码量不宜过大。八、实战场景面试题(面试官高频追问)1.页面跳转闪退、内存泄漏如何排查?详细答案:闪退排查:1.查看崩溃日志、断点调试,定位崩溃线程和代码行;2.大概率是数组越界、空值强制解包、野指针、主线程刷新UI、多线程资源竞争;3.检查页

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论