2020iOS面试题精选

DISPATCH_QUEUE_CONCURRENT
DISPATCH_QUEUE_SERIAL
dispatch_barrier_async
dispatch_group_notify
queue.maxConcurrentOperationCount = 1;
[operation2 addDependency:operation1];

[NSBlockOperation blockOperationWithBlock:^{
NSOperationQueue *queue = [[NSOperationQueue alloc] init];

// 添加操作到队列
[queue addOperationWithBlock:

1、对象循环引用
@class ,Strong,weak

2、block循环引用
__weak typeof(self) weakself = self;

3、NSNotification的观察者忘记移除
[[NSNotificationCenter defaultCenter] removeObserver:self];

4、delegate循环引用问题
@property (nonatomic, weak) id delegate;

5、NSTimer循环引用
([NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timeRepeat:) userInfo:nil repeats:YES]);
使用GCD

6、非OC对象内存处理
CGImageRef类型变量非OC对象,其需要手动执行释放操作CGImageRelease(ref),否则会造成大量的内存泄漏导致程序崩溃。其他的对于CoreFoundation框架下的某些对象或变量需要手动释放、C语言代码中的malloc等需要对应free等都需要注意;

7、使用过多的UIWebView
改为WKWebView

8、大次数循环内存暴涨问题

一、手机百度(搜索业务)

1.技术亮点、难点。

2.web加载渲染过程

3.组件化,路由和taget-action两种方案的优劣

4.算法

a>判断链表是否有环,一亿个数

快慢指针,直到两个指针相遇或者到达尾部

b>如何用100M的内存筛选出最小的100个数。

https://www.jianshu.com/p/119c1ff5ea69

5.runloop线程保活(具体代码是什么样子的)

https://www.jianshu.com/p/4d5b6fc33519

6.runloop监听卡顿(具体代码是什么样子的)

https://www.jianshu.com/p/ef2599f7251f

7.网路层的优化

要点 :dns缓存 弱网环境优化 包体积大小

域名合并:淘宝、美团等公司公布的解决方案中都有提到,就是将公司原来的很多域名都合并到较少的几个域名。为什么?因为 HTTP 的通道复用就是基于域名划分的。如果域名只有几个,那么多数请求都可以在长连接通道进行,这样就可以降低延迟、增加成功率
预热,尽早建立长连接。这样其他的业务请求就可以复用长连接通道。加快访问速度。因为每次建立连接都需要经过 DNS 域名解析、TCP 三次握手等漫长步骤。建立长连接的时机可以考虑:冷启动、前后台切换、网络切换等
如果情况允许,可以将网络切换到 HTTP 2.0,解决了 HTTP1.1 的 head of blocking ,降低了网络延迟,提供了更强大的多路复用技术。还加入了流量控制、新的二进制格式、Server Push、请求优先级和依赖等待等特性。
建立多通道。比如携程、艺龙、美团等公司都有自己的 TCP、UDP 通道。具有多域名共用通道。
有些超级大厂还自研了协议。比如 QUIC
加入 CDN 加速,动态静态资源分离
对于类似埋点的业务数据请求,可以合并请求,减小流量。另外结合埋点数据压缩上传
App 网络情况诊断
根据网络情况,动态设置超时时间等
https://zhuanlan.zhihu.com/p/115134324

8.包大小优化

https://blog.csdn.net/xj1009420846/article/details/80313566

9.启动速度优化(runtime和dyld阶段之间还有其他的)减少不必要的framework,因为动态链接比较耗时

check framework应当设为optional和required,如果该framework在当前App支持的所有iOS系统版本都存在,那么就设为required,否则就设为optional,因为optional会有些额外的检查
合并或者删减一些OC类,关于清理项目中没用到的类,使用工具AppCode代码检查功能,查到当前项目中没有用到的类如下:

image

删减一些无用的静态变量
删减没有被调用到或者已经废弃的方法

方法见:http://stackoverflow.com/questions/35233564/how-to-find-unused-code-in-xcode-7
https://developer.Apple.com/library/ios/documentation/ToolsLanguages/Conceptual/Xcode_Overview/CheckingCodeCoverage.html

将不必须在+load方法中做的事情延迟到+initialize中
尽量不要用C++虚函数(创建虚函数表有开销)

main()调用之后的加载时间

在main()被调用之后,App的主要工作就是初始化必要的服务,显示首页内容等。而我们的优化也是围绕如何能够快速展现首页来开展。 App通常在AppDelegate类中的- (BOOL)Application:(UIApplication *)Application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions方法中创建首页需要展示的view,然后在当前runloop的末尾,主动调用CA::Transaction::commit完成视图的渲染。
而视图的渲染主要涉及三个阶段:

准备阶段 这里主要是图片的解码

布局阶段 首页所有UIView的- (void)layoutSubViews()运行

绘制阶段 首页所有UIView的- (void)drawRect:(CGRect)rect运行
再加上启动之后必要服务的启动、必要数据的创建和读取,这些就是我们可以尝试优化的地方

因此,对于main()函数调用之前我们可以优化的点有:

不使用xib,直接视用代码加载首页视图
NSUserDefaults实际上是在Library文件夹下会生产一个plist文件,如果文件太大的话一次能读取到内存中可能很耗时,这个影响需要评估,如果耗时很大的话需要拆分(需考虑老版本覆盖安装兼容问题)
每次用NSLog方式打印会隐式的创建一个Calendar,因此需要删减启动时各业务方打的log,或者仅仅针对内测版输出log
梳理应用启动时发送的所有网络请求,是否可以统一在异步线程请求

https://www.jianshu.com/p/7096478ccbe7

10.离屏渲染

阴影 cornerRedius+clipstoBounds mask 透明度

runloop有个60fps回调,绘制内容交给GPU渲染,包括view拼接,纹理的渲染。
CPU计算好显示内容提交到GPU,GPU渲染完成后将渲染结果放入帧缓冲区
1 当前屏幕渲染,指的是GPU的渲染操作是在当前用于显示的屏幕缓冲区中进行
2 离屏渲染,指的是GPU在当前屏幕缓冲区以外新开辟一个缓冲区进行渲染操
3 重写了drawRect方法,并且使用任何Core Graphics的技术进行了绘制操作,就涉及到了CPU渲染
4 CoreGraphic通常是线程安全的,所以可以进行异步绘制,显示的时候再放回主线程

11.响应者链

  1. Initial view 尝试着去处理事件或者消息。如果不能处理事件,它就递交事件给superview,因为这个initial view并不是视图控制器层级中得顶级view.
  2. 这个superview尝试去处理该事件,如果superview不能处理该事件,它就递交事件给它的父view,因为它也不是view层级的顶级view。
  3. 视图控制器的顶级view尝试着去处理该事件,如果连顶级view都不能处理该事件,它就递交事件给它的controller。
  4. 这个viewcontroller尝试着去处理该事件,并且如果它不能处理该事件,它就会递交事件给window。
  5. 如果window不能处理该事件,它就递交事件给singlegon app object(既UIApplication)
  6. 如果连application都不能处理该事件,那么毫无疑问该事件将会被丢弃。
    响应事件+响应者链条(单向 从子控件到父控件)
    UIAppliction --> UIWiondw -->递归找到最适合处理事件的控件-->控件调用touches方法-->判断是否实现touches方法-->没有实现默认会将事件传递给上一个响应者-->找到上一个响应者
    用户点击屏幕后产生的一个触摸事件,经过一些列的传递过程后,会找到最合适的视图控件来处理这个事件
    整个响应顺序是从上到下再从下到上; 响应者链的响应事件是从下到上
    如何找到合适控件处理事件 触摸事件是从父控件传递到子控件
    1 自己能否接收触摸事件
    2 触摸点是否在自己身上
    3 从后往前遍历子控件 重复前面2个步骤
    4 没有合适的子控件 就自己做处理

二、快手

1.算法

a> 两个数n、m 如果是n= 2 m=5,用递归实现2 3 4 5相加等于14;


    public static int sum(int n1, int n2) {
        if(n1 == n2) {
            return n1;
        }
         
        if(n1 >  n2) {
            int temp = n1;
            n1 = n2;
            n2 = temp;
        }
         
        return sum(n1, n2-1) + n2;
    }

2.weak和assign的区别

一、区别
1.修饰变量类型的区别
weak 只可以修饰对象。如果修饰基本数据类型,编译器会报错-“Property with ‘weak’ attribute must be of object type”。
assign 可修饰对象,和基本数据类型。当需要修饰对象类型时,MRC时代使用unsafe_unretained。当然,unsafe_unretained也可能产生野指针,所以它名字是"unsafe_”。

2.是否产生野指针的区别
weak 不会产生野指针问题。因为weak修饰的对象释放后(引用计数器值为0),指针会自动被置nil,之后再向该对象发消息也不会崩溃。 weak是安全的。
assign 如果修饰对象,会产生野指针问题;如果修饰基本数据类型则是安全的。修饰的对象释放后,指针不会自动被置空,此时向对象发消息会崩溃。

二、相似
都可以修饰对象类型,但是assign修饰对象会存在问题。

三、总结
assign 适用于基本数据类型如int,float,struct等值类型,不适用于引用类型。因为值类型会被放入栈中,遵循先进后出原则,由系统负责管理栈内存。而引用类型会被放入堆中,需要我们自己手动管理内存或通过ARC管理。
weak 适用于delegate和block等引用类型,不会导致野指针问题,也不会循环引用,非常安全。

3.weak原理(很细致,具体到如何查找的)

1、调用objc_release
2、因为对象的引用计数为0,所以执行dealloc
3、在dealloc中,调用了_objc_rootDealloc函数
4、在_objc_rootDealloc中,调用了object_dispose函数
5、调用objc_destructInstance
6、最后调用objc_clear_deallocating。
https://blog.csdn.net/future_one/article/details/81606895

4.autoreleasePool 的结构和自动释放池中的对象存储过程,autoreleasePool的结构。(比较细致的问了一遍过程)

关键字:结构体 parent和child 双向链表
https://www.jianshu.com/p/58dab9c28a12

5.objc_msgSend()经历的过程,具体到cache_t结构和具体hashmap的查找方法。动态解析和消息转发要说具体的方法名称。

objc_msgSend汇编部分仅仅完成很少的缓存查找功能,如果找不到就会调用C方法去对象的方法二维数组中找,找不到再查父类的缓存(这也是汇编实现的)和父类的方法数组,一直找到根类,如果此过程中找到对应的方法则调用并添加缓存,如果没有找到,则表明该继承体系都没有直接实现该方法,这时runtime会调用对象的方法决议去尝试解决。如果不行则由CoreFoundation框架提供的forwarding来转发到其他对象处理,若还不能处理则抛出异常。
https://www.jianshu.com/p/75a4737741fd

6.block的捕获机制,block类型的区分,__block做了什么,__block修饰对象类型和基本数据类型的区别。

全局 堆栈 带__block的自动变量 和 静态变量 就是直接地址访问。所以在Block里面可以直接改变变量的值。
剩下的静态全局变量,全局变量,函数参数,也是可以在直接在Block中改变变量值的,但是他们并没有变成Block结构体__main_block_impl_0的成员变量,因为他们的作用域大,所以可以直接更改他们的值。
https://blog.csdn.net/DreamcoffeeZS/article/details/102257488
https://blog.csdn.net/DreamcoffeeZS/article/details/102475351

7.load()和initialize()区别

调用方式

1、load是根据函数地址直接调用
2、initialize是通过objc_msgSend调用

调用时刻

1、load是runtime加载类、分类的时候调用(只会调用一次)
2、initialize是类第一次接收到消息的时候调用, 每一个类只会initialize一次(如果子类没有实现initialize方法, 会调用父类的initialize方法, 所以父类的initialize方法可能会调用多次)

load和initializee的调用顺序

1、load:父子分
先调用类的load, 在调用分类的load
先编译的类, 优先调用load, 调用子类的load之前, 会先调用父类的load
先编译的分类, 优先调用load

image

2、initialize 分子父
先初始化分类, 后初始化子类
通过消息机制调用, 当子类没有initialize方法时, 会调用父类的initialize方法, 所以父类的initialize方法会调用多次

8.图层方法两倍形变后,frame和bouns的变化,相对位置,绝对位置。

三、快手二面

1.算法

a>爬楼梯,动态规划,是否可以优化空间复杂度

b>一面时面试题的变种

2.__strong和__weak的区别

3.strong和copy的区别

4.看代码(题目较多)

5.项目中重要的技术点

6.实现线程同步方案的几种方式的优缺点

四、探探/网易有道

1、算法

a> LRU(最近最少使用次数、最近最晚使用)

https://blog.csdn.net/elricboa/article/details/78847305

b>哈希冲突

开放定址法 拉链法
https://blog.csdn.net/xtzmm1215/article/details/47177701

c>哈希表以对象为键,怎么处理

2.A,B,C三个线程 打印array中元素,【1,2,3,4……100】,A线程打印1,B打2,C打3,A打4,依次打印。

https://www.jianshu.com/p/40078ed436b4

3.kvo监听一个weak修饰的属性,当对象释放的时候,kvo回调方法会被释放吗

kvo作为一个中间对象,在当前控制器销毁时任然会存在,所以在销毁时应该移除当前观察释放kvo对象

4.100*100像素的图片在内存中的大小,

一个像素是RGB + alpha 一个是16位,所以是100 * 100 * 4 *16 位

5.看代码的题目比较多

五、美团

1.block对mutablearray 修改需要用__block吗?对block的捕获是深拷贝还是浅拷贝?

浅拷贝,可以在block中修改数组中的元素

2.GCD和operation的区别

image

image

3.GCD是如何实现线程调度的

https://blog.csdn.net/zhangshichi/article/details/51161245

3.1GCD怎么实现线程同步的

组队列(dispatch_group) 阻塞任务(dispatch_barrier)
https://www.jianshu.com/p/81576172ad1f

4.线程同步的方案,

5.锁有哪些,有什么区别

6.读写锁实现的原理

7.内存管理的理解

8.方法查找

9.MVC和MVVM的区别

10.项目架构

11.autoreleasePool

12.autoreleasePool和runloop的关系

13.实际开发中autoreleasePool的作用以及应用

14.kvo底层原理

检查对象的类有没有相应的 setter 方法。如果没有抛出异常;
检查对象 isa 指向的类是不是一个 KVO 类。如果不是,新建一个继承原来类的子类,并把 isa 指向这个新建的子类;
检查对象的 KVO 类重写过没有这个 setter 方法。如果没有,添加重写的 setter 方法;
添加这个观察者
http://www.cocoachina.com/articles/11321

15.哈希冲突的解决方案

16.循环引用的原因,举例说明

https://www.jianshu.com/p/3ffa8bc19cbe

17.线程导致死锁的原因,举例说明

互斥条件 请求和保持条件 不剥夺条件 环路等待条件

18.weak和strong的区别,和assign的区别

19.llvm的编译流程

https://www.jianshu.com/p/333cf1c02a0e

20.对swift和oc的区别

21.跨平台技术的了解

算法:https://leetcode-cn.com/problems/ba-zi-fu-chuan-zhuan-huan-cheng-zheng-shu-lcof/solution/mian-shi-ti-67-ba-zi-fu-chuan-zhuan-huan-cheng-z-4/

六、知乎
1.组件化拆分的过程问答的很细致,以及拆完组件化是否还有可以优化的
2.包体积优化
3.启动优化
4.dyld阶段的细节
5.autoreleasepool和线程有什么关系
6.数组中有1万个数字,如果删除某一个元素,得到一个新的数组,怎么判断出删除的是几???
7.手触摸到屏幕,整个事件的响应全过程。
8.用协议实现一个一对多的通知效果
9.判断链表是否有环,且环是多少个节点
10.用栈实现一个数组的增删改查
11.设计上报日志的库
12.抽象工厂和工厂有什么区别

七、腾讯(个人觉得面试官实力有点差)
1.引用计数的理解?系统为什么这么设计
2.runloop和autoreleasepool的关系,子线程创建的时候需要些一个autoreleasepool吗,为什么?
3.webView和WKWebView的区别
4.实现多线程的方式,各有什么优缺点
多线程有多种实现方式,常见的有以下三种:
1、继承Thread类,重写run()方法。
1) 定义Thread类的子类,并重写该类的run()方法,该run()方法的方法体就代表了线程要完成的任务。因此把run()方法称为执行体。
2)创建Thread子类的实例即创建了线程对象。
3)调用线程对象的start()方法启动线程。
2、实现Runnable接口,重写run()方法。
1)定义Runnable接口的实现类,并重写该方法的run()方法,该run()方法同样是该线程的执行体。
2)创建Runnable实现类的实例,并依此实例作为Thread的target来创建Thread对象,该Thread对象才是真正的线程对象。
3)调用线程对象的start()方法启动线程。
3、通过实现Callable接口和使用FutureTask包装器来实现线程。
1)创建Callable接口的实现类,并实现call()方法,该call()方法的方法体同样是该线程的执行体。
2)创建Callable实现类的实例,使用FutureTask类来包装Callable对象,该FutureTask对象封装了该Callable对象的call()方法的返回值。
3)使用FutureTask对象作为Thread对象的target创建并启动新线程。
4)调用FutureTask对象的get()方法来获得子线程执行结束后的返回值。
三种实现方式的优缺点对比:
1、实现Runnable和Callable接口方式:
优点:
1)线程类只是实现了Runnable接口(JDK1.0开始)或Callable接口(JDK1.5开始),还可以继承其他类。
2)多线程可以共享同一个target对象,非常适合多个相同线程来处理同一份资源的情况,从而可以将CPU、代码和数据分开,形成清晰的模型,较好地体现了面向对象的思想。
3)实现Callable接口创建多线程最大的好处是可以有返回值。
缺点:
编程稍显复杂,如果要访问当前线程,则必须使用Thread.currentThread()方法。
2、使用继承Thread类方式:
优点:
编写简单,如果要访问当前线程无需使用Thread.currentThread()方法,直接使用this即可获得当前线程。
缺点:
线程类已经继承了Thread类,不能再继承其他类(java的单继承性),因此该方式不够灵活。
补充说明:
1)Callable规定重写call()方法;Runnable重写run()方法。
2)Callable的任务执行结束后可有返回值;Runnable的任务是不能有返回值的。
3)call()方法可以抛出异常;run()方法不可以。
4)运行Callable任务可以拿到一个Future对象,表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并检查计算的结果。通过Future对象可以了解任务执行情况,可取消任务的执行,可以获取执行结果。

5.iOS如何实现多继承,代码书写一下。
代理 消息转发

动态方法解析:向当前类发送resolveInstanceMethod: 信号,检查是否动态向该类添加了方法
快速消息转发:检查该类是否实现了 forwardingTargetForSelector: 方法,若实现了则调用这个方法,若该方法返回nil或者非self,则向该返回对象重新发送消息
标准消息转发:runtime发送methodSignatureForSelector:消息获取Selector对应的方法签名。返回值非空则通过forwardInvocation:转发消息,返回值为空则向当前对象发送doesNotRecognizeSelector:消息,程序崩溃退出.

6.创建子线程需要创建一个autoreleasepool吗?
https://blog.csdn.net/qq_22389025/article/details/85162240?utm_medium=distribute.pc_relevant.none-task-blog-title-1&spm=1001.2101.3001.4242
不需要,但是他说如果不出创建autoreleasepool对象,如果有autorelease修饰的对象会有警告,简直是胡扯。
7.为什么不能在子线程刷新UI
https://www.jianshu.com/p/5849eb69ec82
8.一个imageView在屏幕中显示的整个过程,那些步骤可以放在子线程,那些要在主线程执行

Pasted Graphic.png

1. 百度

  • 一面
  • MVC、MVP、MVVM的区别,使用场景
  • NSLayout、Masonry、SpanKit的区别,使用场景
  • ARC内存管理机制
  • 对Runtime的了解
  • 对Runloop的了解
  • 项目中遇到的困难
  • 性能优化
  • App体积优化
  • 启动时间优化
  • 离职原因
  • 你开发的SDK的使用量
  • 用Python做过什么
  • 对开发的这个App有没有自己的看法
  • 最近看了什么书
  • 发展方向(职业规划)
  • 对百度地图了解吗
  • 对加班的看法
  • 你想问的问题
  • 有其他公司的offer吗
  • 想问的问题
  • 二面
  • 谈谈你做的自动化测试
  • GCD的几个题目做一下
  • 子线程中创建NSTimer会执行吗
  • 在dealloc中释放NSTimer会怎样
  • NSNoticationCenter不释放监听者着会怎样
  • 自动释放池什么时候释放
  • Runloop何时退出
  • 互斥锁、自旋锁
  • NSLock、递归所、读写锁的区别和使用场景
  • 看过哪些源码
  • NSNoticationCenter的实现原理,如何自定义
  • KVO原理
  • 手写:字符串中寻找是否出现了重复的字符
  • 两层循环
    • hash
  • 设计hash表
  • 想问的问题
  • 三面
  • 项目架构
  • 职业规划
  • 遇到的困难
  • 对项目的贡献
  • 离职原因
  • 如何看待加班
  • 和同事有矛盾如何解决
  • 你的优点
  • 你的缺点
  • 想问的问题

2. 腾讯

  • 一面
  • 谈谈你做的自动化测试
  • Block中捕获全局、静态、实例、局部变量是怎样实现的
    https://www.jianshu.com/p/ee9756f3d5f6
    自动变量是以值传递方式传递到Block的构造函数里面去的。Block只捕获Block中会用到的变量。由于只捕获了自动变量的值,并非内存地址,所以Block内部不能改变自动变量的值。Block捕获的外部变量可以改变值的是静态变量,静态全局变量,全局变量。
  • ARC内存管理机制
  • Runloop
  • Runtime
  • 性能优化
  • App体积优化
  • 启动时间优化
  • 动/静态库分别在哪里占用了时间?
  • 项目中遇到的困难
  • 字符串转数字
  • 你想问的问题

3. 富途

  • 一面
  • ARC内存管理机制
  • Runloop
  • Runtime
  • 性能优化
  • App体积优化
  • 启动时间优化
  • KVO原理
  • struct和class的区别
  • swift协议
  • 手写快排
  • 手写,数组[1,0,3,0,4,0,0,-2],将0放在数组最前面且不影响非0值的顺序
  • 手写翻转二叉树
  • 绳子粗细不均匀,但烧完一定需要60分钟,如何烧出45分钟。
  • 想问的问题
  • 二面
  • 启动时间优化
  • 结构体 { char int int } 占用多少字节,内存对齐是什么
  • int a = 0, 两个线程中各加十次,a=多少,为什么,a的范围是多少?
  • 员工表,18年3月-18年8月工资少发了,现在需要对其补发,手写SQL
  • 25个人有5个跑道,求出最快的三个人,至少需要比赛多少次
  • 有2个玻璃珠和100层楼,玻璃珠摔坏了则无法二次使用,求玻璃球能承受的最大高度,至多需要多少次测试。
  • 1000瓶水,1瓶有毒,老鼠喝水后3天死亡,给3天时间,求至少需要多少只老鼠。
  • 手写二叉搜索树插入函数
  • 求无序数组中最大的K个数
  • 想问的问题

4. 有赞

  • 一面
    • Runloop
  • Runtime
  • 消息转发机制
  • 事件传递机制
  • 性能优化
  • App体积优化
  • 启动时间优化
  • KVO原理
  • 组件化
  • 职业规划
  • 想问的问题
  • 二面
  • 你做了什么功能,画出并解释流程图和项目结构
  • 你的职业规划
  • 想问的问题
  • 三面
  • 项目架构
  • 你的职业规划
  • 想问的问题

5. 方直

  • 一面
  • Runtime
  • Runloop
  • 性能优化
  • App体积优化
  • 启动时间优化
  • 启动流程
  • KVO原理
  • 事件传递机制
  • 消息转发机制
  • 自动释放池内部实现
  • Storyboard、classify
  • 想问的问题
  • 二面
  • 性能优化
  • 项目架构
  • 你能为公司带来什么
  • 你的价值
  • 你的职业规划
  • 想问的问题

6. TCL

  • 一面
  • Runloop
  • Runtime
  • OC底层结构
  • 消息转发机制
  • 事件传递机制
  • 性能优化
  • App体积优化
  • 启动时间优化
  • 启动流程
  • KVO原理
  • 组件化
  • load和initlize的区别
  • 两个相同的油漆桶,一个红色一个蓝色,一个勺子,使用勺子从红桶挖一勺到蓝桶并搅拌均匀,此时从蓝桶挖一勺到红桶搅拌均匀,问红桶中的红蓝比和蓝桶中的蓝红比是怎样的
  • 手写归并排序
  • 想问的问题
  • 二面
  • 性能优化
  • App体积优化
  • 启动时间优化
  • 组件化
  • 项目的产品角度
  • 项目架构
  • 想问的问题

7. 编程猫

  • 一面
  • Runloop
  • 性能优化
  • App体积优化
  • 启动时间优化
  • 启动流程
  • KVO原理
  • 暗黑模式适配
  • 了解哪些设计模式
  • 一个按钮会触发网络加载然后更新列表,用MVVM说思路
  • RAC的冷信号和热信号区别
  • 说说自动化测试
  • Bugly解决不了的异常,怎么处理的
  • atomic, weak
  • 链表和数组的区别,队列和栈的区别
  • SwiftUI
  • 想问的问题

8. 抖音

  • 一面
  • 说一个你做的App有什么功能
  • 说一说用到了AVFoundation的哪些功能
  • AVFoundation相机代理的视频流返回的图片是什么格式,如何显示在屏幕上
  • KVO原理
  • struct和class的区别,如果for循环1000次struct会怎样
  • unowned和weak的区别
  • NSTimer准吗,不准的话会延时调用吗,如何解决
  • AutoRelease对象什么时候释放
  • Runloop什么时候释放
  • Runloop干了什么
  • 自动释放对象在Runloop的哪个阶段释放
  • 野指针如何产生的
  • 使用Block时,为什么会使用__strong或__weak
  • 离屏渲染是什么,如何产生的,如何解决
  • 屏幕上的内容是如何显示的,卡顿是如何产生的,如果解决
  • 以对角线顺序打印二维数组
  • 想问的问题

9. 随手

  • 一面
    • Runloop
  • Runtime
  • OC底层结构
  • 消息转发机制
  • 事件传递机制
  • 性能优化
  • App体积优化
  • 启动时间优化
  • 启动流程
  • KVO原理
  • 英文笔试题:给NSString添加一个分类,实现将其转换为NSNumber
  • 英文笔试题:如何产生循环引用
  • 英文笔试题:设计低耦合的<花开蜂猜谜,花闭蜂回家>
  • 英文笔试题:寻找数组中出现次数最多的数值的和
  • 想问的问题
  • 二面
    • 消息转发机制
  • 事件传递机制
  • 性能优化
  • App体积优化
  • 启动时间优化
  • 组件化
  • 向我解释什么是GCD,假设我不懂iOS。
  • 职业规划
  • 想问的问题
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268