美文网首页
2022年iOS高级工程师面试题

2022年iOS高级工程师面试题

作者: 凯文Kevin21 | 来源:发表于2023-02-12 15:03 被阅读0次

    PS:面试题内容来自群友收集分享,非本人!!!

    真实面试题

    load方法调用顺序、调用superLoad会走到谁?

    总结:

    • 1.父类先于子类调用;
    • 2.类先于分类调用;
      1. load调用时机比较早,当load调用时,其他类可能还没加载完成,运行环境不安全;
    • 4.load方法是线程安全的,它使用了锁,我们应该避免线程阻塞在load方法;
    • 5.load是根据函数地址直接调用的,与类在Compile Sources中的顺序一致;
    • 6.load方法通常用来进行Method Swizzle;

    PS: 调用superLoad, 走消息转发流程

    KVO 没有setter

    • _NSSetValueAndNotify

    atomic

    • 非线程安全,仅能保证进入set、get方法是线程安全的

    Barried和group

    • 栅栏和组,
    • 栅栏只能阻拦同步任务
    • group可以处理异步任务

    target project workspace scheme configuration

    • (workspace -> project -> target -> scheme -> configuration) 包含关系

    autoreleasePool

    绘制完成后下次runloop还绘制么

    • 是否绘制取决于UIKit是否认为他是dirty

    二叉树深度

    • 递归,如果有,则深度+1 取左右子树最大深度

    • 自旋锁忙等待, 优先级反转 高优先级占用时间片,低优先级任务无法抢占时间片,任务完不成,不释放资源
    • 互斥锁
    • 递归锁 统一线程可以重复获取递归锁
    • synchronized 性能最差 是递归锁
      • 找到obj对应的syncData结构进行加解锁

    设置一个单写多读的数据库,要考虑什么(setter如何加锁,同时getter如何高效)

    • 并发队列
    • 写异步dispatch_barried_async
    • 读同步并发队列

    App卡顿检测

    • runloop监测beforeSource -》 beforeWaitting 的间隔
      • 每次runloop CallBack的时候信号量释放,while循环里wait,使用的是信号量的超时机制(如果等待的时间大于设置的时间则直接执行, 超时信号量则返回的是非0
    • afterWaitting之后

    如何设计一个图片异步加载框架

    • api简洁易用
    • 任务优先级
    • 下载器
    • 取消之前任务
    • 解码
    • 缓存策略
    • 缓存过期策略LRU(双向链表配合hash表,key为URL value为node节点)

    IM如何解决启动消息堆积问题

    • 缓冲池缓存 空闲时处理,或者间隔多久处理一次
    • 合并处理

    数据库事务的好处

    • 原子性 (要么全执行 要么全不执行)
    • 隔离性(各个事务是隔离的,互不影响)
    • 一致性(事务完成时,数据保持一致状态)
    • 持久性 (事务一旦提交,对数据的改变是永久性的)

    浏览器输入网址后的过程

    • dns解析,
    • 三次握手后 https交换密钥,
    • 然后正常请求

    中间人攻击

    swift可选类型如何实现?

    • wrapper

    http2.1 (多路复用)

    HTTP滑动窗口、流量控制

    • 报文中有窗口字段,窗口为0时发送方停止发送数据
    • 防止接收方缓存区快满了,发送方还在发送数据
    • 发送方的发送窗口大小不能超过接收方的给出的窗口大小

    Isa

    • 实例对象 isa指向类,
    • 类对象的isa指向 metaclass

    单链表翻转

    • 递归

      def reverseList(self, head: ListNode) -> ListNode:
          # 1. 递归终止条件
          if head is None or head.next is None:
              return head
          
          p = self.reverseList(head.next)
          head.next.next = head
          head.next = None
      
          return p
      

    性能检测

    • CPU
    • FPS
    • 卡顿检测(利用runloop 和 信号量超时机制)

    SDWeb 然后一个带图片的列表,用sd展示,譬如第二和第四是同一个链接,这种情况下它的策略是什么

    • 查找队列任务,并把回调放在同一张图片operation的回调中
    • download operation存储着对同一张图片的回调block

    tcp拥塞控制,

    • 慢开始
    • 拥塞避免
    • 快重传
    • 快恢复

    加密

    • MD5
    • SHA256
    • Hash
    • AES

    gcd里的group,enter,leave,notify作用,

    • enter 开始执行任务了
    • leave 我执行完成了
    • notify 是获取当前组里的任务都完成了,不过要注意notify的位置

    方法缓存cache怎么查找的

    • 快查
    • 慢查
    • 填充缓存

    MachO的方法列表排序

    • 类加载的时候,先是把类中的方法排序然后加到类的方法数组后面,然后到分类时也是先把分类方法排序,再加到类方法数组的前面。
    • 分类中的方法地址比原始类中的方法地址要小,这样便能能保证方法列表是有序的,所以能用二分查找

    weak的原理,

    • weak_table_t

    项目结构,组件化分层

    • 地基层(第三方依赖以及工程的基础库)
    • 基础通用组件(对第三方库的封装以及异常上报,推送服务、支付)
    • 基础UI组件
    • 基础功能组件(登录注册这种不依赖业务的组件)
    • 业务组件
      • 更小的业务模块
    • 壳工程

    查找冲突怎么实现的, 线上日志 崩溃

    埋点这些

    • 无痕埋点 aop

    swift struct 和 class 区别

    • 默认创建构造器,
    • 值类型和引用类型,
    • 继承,
    • class堆,
    • struct栈,
    • 线程安全
    • struct更轻量

    mutating 关键字

    • @inout 传递引用修改

    WebView优化

    • 包缓存,
    • 空白webview常驻缓存,
    • 使用wk

    swift 派发机制

    • 函数表派发,
    • 动态派发,
    • 直接派发

    optinoal怎么实现的

    • (struct wapper)

    protocol 怎么实现optional

    • (@objc)

    swift访问权限修饰符

    • private
    • public
    • fileprivate
    • protect

    上传1个G的大文件,怎么设计,上传的时候读取到内存,一定是一次性读完吗

    • 分段读取,NSFileHandler

    微信通话,让你设计,用TCP 还是 UDP,为什么

    • udp, 视频通话丢包可以接受,

    UDP发送1、2、3、4、5,5 个数据包,怎么保证它的顺序

    • 协议中添加包的编号,接受包的时候排序

    冷启动runtime的初始化调用哪些方法

    编译器运行原理

    • 词法分析,
    • 语法分析,
    • 语义分析,
    • 中间代码生成,
    • 中间代码优化,
    • 目标代码生成,
    • 符号表管理,
    • 出错管理

    runloop应用场景,

    • 监控卡顿,
    • 线程保活,
    • timer滑动停止

    AOP,函数式等等区别,

    runtime应用

    • 动态添加属性和方法,
    • 方法交换,
    • 获取和修改私有属性和方法
    • 字典转模型

    怎么hook+load

    • 制作动态库
    • 优先编译

    内存管理机制

    • ARC
    • MRC

    内存分区以及堆区栈区区别,对象存哪里

    • 指针在栈区 325
    • 对象在堆区
    • 堆、栈、全局、代码、数据

    block值捕获,

    从点击应用图标开始的app启动流程(系统为程序启动做好准备,

    Runloop作用以及如何监测卡顿

    • (beforeSource -> waitting 大于阈值, 子线程监听,dump出调用栈)

    KVO原理以及自己如何实现

    自动释放池相关,譬如何时释放、实现原理、@autoreleasepool加for循环情况下何时释放

    深copy与浅copy

    • (浅拷贝 拷贝指针)

    KVC原理 之后是Key与keypath区别,然后定义一个属性_name 然后kvc通过setValueforkey,这时赋值是用key赋值还是keypath

    • keyPath 可以通过路径查找
    • 都可以

    消息发送原理 然后消息转发为啥要分三个阶段,苹果这样设计的意义在哪儿(字节)

    • 第一阶段为动态添加方法
    • 第二阶段为替换接收方
    • 第三阶段为完全消息转发(有invocation对象,可以实现多次转发,转发给多个对象)

    输入法要加载大量表情这时引起内存激增,这种情况如何优化

    • 如图大 imageIO进行缩放
    • 按需加载
    • 如不需要常驻内存,去掉内存缓存
    • 如本地图片,使用autoreleasepool包裹加载

    事件响应链如何寻找fitview(有次回答了事件响应链的hittest、pointinside方法寻找以及后边touchebegan之类的方法判定后,又这样问我有些懵逼)(字节、小红书、携程都有问)

    tcp/udp区别

    • tcp 可靠、一对一、流量控制和拥塞控制、面向连接、首部开销大
    • udp 不可靠,可一对一、一对多、多对一、多对多、无流量控制和拥塞控制、首部开销小

    strong 、weak、copy 、assign 、retain 、unsafe_unretained 与autoreleasing

    • autoreleasing当前autoreleasepool作用域内有效,出去即销毁
    • 对不可变对象执行copy操作,是指针复制,执行mutableCopy操作是内容复制。
    • 对可变对象执行copy操作和mutableCopy操作都是内容复制。

    https原理

    • Client Hello: Random1、SSL version、 加密套件
    • Server Hello:Random2、server选择的加密套件
    • Certificate:server让客户端校验证书
    • Certificate Verify:client通过证书加密Random3
    • Client Key Exchange: server和client用同样的算法加密 random1、2、3即为通讯秘钥

    websocket原理

    • 利用http协议握手
    • 利用tcp来传输数据,请求头小

    runloop与autoreleasepool关系

    • 线程与runloop一一对应
    • autoreleasepool依赖runloop来工作

    weak实现原理

    • 调用 objc_release
    • 因为对象的引用计数为0,所以执行 dealloc
    • 在 dealloc 中,调用了 _objc_rootDealloc 函数
    • 在 _objc_rootDealloc 中,调用了 object_dispose 函数
    • 调用 objc_destructInstance
    • 最后调用 objc_clear_deallocating,详细过程如下:
      • a. 从 weak 表中获取废弃对象的地址为键值的记录
      • b. 将包含在记录中的所有附有 weak 修饰符变量的地址,赋值为 nil
      • c. 将 weak 表中该记录删除
      • d. 从引用计数表中删除废弃对象的地址为键值的记录

    Swift与OC区别 以及swift安全性体现

    • 文件个数和后缀不同
    • 不需要main函数
    • 会自动推导类型
    • bool类型明确
    • 可以不继承任何类
    • final修饰不能被其他类继承
    • guard
    • inout

    逃逸闭包与非逃逸闭包

    • 闭包调用时的时机划分为逃逸闭包和非逃逸闭包

    gcd如何取消线程

    • 线程是由系统管理的,不需要手动管理
    • 如果问的是取消任务的话,可以cancel掉未执行的任务

    app保活

    • backgroundTask
    • 持续定位
    • 播放无声音频
    • 后台下载资源
    • BGTaskScheduler

    深拷贝和浅拷贝

    • 对数组等集合类app进行深拷贝,其内容不变
    • 因为数组里存的只是内容的指针,并非本体

    启动优化

    内存管理,关键字 weak释放

    category加载 消息机制(方法查找)

    setNeedLayout和layoutIfNeed

    UIView性能问题(卡顿掉帧)

    • 离屏渲染
    • 主线程执行耗时操作
    • 大图优化
    • tableview优化
    • 图层过于复杂

    SD 解码

    • 已经解码过
    • 动图不解码
    • 矢量图不解码

    组件化分层

    看过哪些源码

    音视频遇到过哪些问题

    im丢消息怎么处理

    多线程的应用

    YYWebImage和SD 异同点

    • 相同点
      • category扩展
      • 缓存&解码
    • 不同
      • YY URLConnect
      • sd URLSession
      • 解码(yy可控制,sd不能控制)

    腾讯1面

    Block

    • StackBlock
    • GlobalBlock
      • 不会访问任何auto变量
    • MallocBlock

    kvc与kvo

    +load 和 +initialize(有什么注意)

    • load由runtime通过函数指针直接调用,无需调用super
    • initialize有msgsend调用,存在方法查找,子类不实现,父类可能会调用多次

    Catagory 和 extension

    commbine

    • 响应式
      • publisher,
      • subscripter,
      • subject,
      • operator

    method swizzling

    • 注意事项
      • 1.hook次数,
      • 2.hook父类导致调用顺序错乱
      • 3.很难追查问题

    application生命周期

    1. 启动程序
      • willFinishLaunchingWithOptions
      • didFinishLaunchingWithOptions
      • applicationDidBecomeActive
    2. 按下home键
      • applicationWillResignActive:
      • applicationDidEnterBackground:
    3. app在后台状态,点击app打开
      • applicationWillEnterForeground:
      • applicationDidBecomeActive:

    腾讯二面

    工作经历

    编译优化

    多继承

    • oc/swift不支持多继承
    • 使用协议模拟

    ARC MRC

    weak 线程安全?

    • 线程安全,每次获取weak指针都会通过objc_loadWeakRetained这个函数
    • 判断其是否为tagged
    • 加锁并取值

    浮点数相等

    • NSDecimalNumber,
    • 或在已定误差范围内认为其相等

    性能监测

    • CPU
    • 内存 使用量or泄漏
    • FPS
    • 卡顿检测
    • 网络
    • crash检测
    • 耗电量监控
    • 启动时间

    断点

    • 符号断点
    • 条件断点

    离屏渲染

    TCP UDP

    头条1面

    sona优化

    • 代码过于复杂
    • 函数代码行数过多
    • switch case条件过多
    • if else嵌套严重
    • C参数未 release

    Flutter与Lua

    • 异同点
    • Flutter
      • 三棵树
        • Widget 存储渲染信息
        • Element 元素树,渲染实体
        • RenderObject 管理布局和绘制

    路由方案及事件总线

    • protocol
    • URL

    包体积优化

    • 无用图片、类、资源等,压缩图片
    • 减少动态库数量
    • 减少无用依赖
    • 去除无用架构
    • xcode默认配置的编译参数

    App启动过程

    runloop及应用

    • 卡顿检测

    搜狐一面

    sd用了哪些锁

    • synchronized

    锁的性能排行

    • synchronized 最差
    • os_unfair_lock 最好

    synchronized原理

    • objc_sync_enter
    • objc_sync_exit
    • 锁对象只能是同一个
    • 可重入型互斥锁

    afn线程保活

    • afn各版本的区别
      • 2.0有线程保活,基于URLConnection,回调只能回调给原runloop
      • 3.0不需要 URLSession可以指定回调队列,NSOperationQueue设定max为1,让回调串行执行

    伪代码设计单写多读

    runloop source0和1分别都对应什么事件

    • source 1 系统级别的事件
    • source 0 是程序员处理的任务

    点击btn是如何事件传递唤醒runloop

    • 包装event -> source1 -> mach_port唤醒runloop -> source0

    runloop和线程的关系

    • 关系存储在全局字典里 线程key runloop是value
    • 一一对应

    runloop有多少个mode 多少个status、

    • kCFRunLoopBeforeTimers
    • kCFRunLoopBeforeSources
    • kCFRunLoopBeforeWaiting
    • kCFRunLoopAfterWaiting *
    • kCFRunLoopExit

    @synthesize 和 @dynamic

    • 如果没有手动实现将为属性自动生成getter和setter方法
    • dynamic 告诉编译器不要自动生成setter和getter

    NSString类型为什么要用copy修饰

    • 对NSString来说没影响
    • 对NSMutableString来说有,防止被修改

    多线程实现方式以及优缺点(gcd对比NSOperation)

    • GCD是C语言, 所以效率更高, operation获得更好的依赖、优先级、kvo等优点
    • operation 是对GCD的高层次抽象
    • 依赖关系,operation可以设置依赖,gcd不行,可以用其他方法
    • operation可以kvo

    NSTimer循环引用

    • 使用block的形式
    • 使用NSProxy
    • iOS13+新API

    block类型 以及循环引用

    • stackBlock
    • mallocBlock
    • globalBlock

    如何优化启动时长

    • 管理启动项
    • load方法清理
    • 减少动态库
    • 减少类的数量

    extension和category的区别

    • extension在编译期间, 可新增成员变量,是类的一部分,无法为系统类添加extension
    • category在运行期间,不能添加成员变量

    autoreleasepool分别在哪些情况下会释放

    • runloop即将进入休眠时
    • 出pool作用域
    • 线程被释放

    autoreleasepool底层原理,

    • 双向链表
    • runloop enter的时候会push, exit会pop
    • runloop 在即将休眠时先pop 然后再push

    weak实现原理

    解压zip遇到过哪些问题

    • 中文文件名乱码

    webview加载优化

    autorelease 和 runloop的关系

    • 注册了entry来push 优先级最高,优先执行
    • 监听beforeWaiting来pop和push 优先级最低,保证最后执行

    webview桥接怎么做的

    说说Swift为什么将String,Array,Dictionary设计成值类型

    • 值类型相比引用类型,最大的优势在于内存使用的高效
    • 线程安全考虑

    MachO结构

    • Header(包含文件类型、目标架构类型等)
    • Load Commands(文件在虚拟内存中的逻辑结构、布局)
    • segment(segment约定使用双下划线加大写字母,例如__TEXT)
      • section(section约定使用双下划线加小写字母,例如:__text)

    MachO Segment

    • __TEXT

      包含代码,它被以只读和可执行的方式映射,即进程可以执行代码,但不能修改代码。代码也不能修改自身,因此,page永远不会dirty。

      • __text
        section包含编译好的机器码。
      • __stubs__stub_helper
        section用于动态链接器(dyld),这样链接动态链接代码时,可以延迟链接
      • __const其是常量;
      • __cstring
        包含可执行文件中字面量字符串。
    • __DATA
      段是可读可写的,但不能执行,包含可被更新的值。

      • __nl_symbol_ptr是非懒加载符号指针,在可执行文件加载时就已经加载了
      • __la_symbol_ptr是懒加载符号指针,用于调用可执行文件中未定义的符号
      • __const:包含一些需要重定向的常量数据。如char * const p = "foo";p指针指向的数据不是常量。
      • __bss:包含未初始化的静态变量。如static int a
      • __common:包含未初始化的外部全局变量。如函数外的int a
      • __dyld:是占位section,用于动态链接器。

    相关文章

      网友评论

          本文标题:2022年iOS高级工程师面试题

          本文链接:https://www.haomeiwen.com/subject/wmsdkdtx.html