字节跳动面试题

字节跳动面试题

字节跳动面试题

1.retain strong 区别

在声明 block 时,retain 相当于 assign,strong 相当于 copy,block一般使用 copy

2.NSClassFromString 原理

反射方法

系统Foundation框架为我们提供了一些方法反射的 API,我们可以通过这些 API 执行将字符串转为SEL等操作。由于OC语言的动态性,这些操作都是发生在运行时的。

1
2
3
4
5
6
7
8
9
// SEL和字符串转换
FOUNDATION_EXPORT NSString *NSStringFromSelector(SEL aSelector);
FOUNDATION_EXPORT SEL NSSelectorFromString(NSString *aSelectorName);
// Class和字符串转换
FOUNDATION_EXPORT NSString *NSStringFromClass(Class aClass);
FOUNDATION_EXPORT Class __nullable NSClassFromString(NSString *aClassName);
// Protocol和字符串转换
FOUNDATION_EXPORT NSString *NSStringFromProtocol(Protocol *proto) NS_AVAILABLE(10_5, 2_0);
FOUNDATION_EXPORT Protocol * __nullable NSProtocolFromString(NSString *namestr) NS_AVAILABLE(10_5, 2_0);
常用判断方法

NSObject类中为我们提供了一些基础方法,用来做一些判断操作,这些方法都是发生在运行时动态判断的。

1
2
3
4
5
6
7
8
// 当前对象是否这个类或其子类的实例
- (BOOL)isKindOfClass:(Class)aClass;
// 当前对象是否是这个类的实例
- (BOOL)isMemberOfClass:(Class)aClass;
// 当前对象是否遵守这个协议
- (BOOL)conformsToProtocol:(Protocol *)aProtocol;
// 当前对象是否实现这个方法
- (BOOL)respondsToSelector:(SEL)aSelector;

参考链接:iOS反射机制

3.http协议版本

1、HTTP 0.9 :
(1)只接受GET一种请求方法,没有在通信中指定版本号,且不支持请求头;

(2)此外该版本也不支持POST方法,因此客户端无法向服务器传递太多信息;

2、HTTP 1.0:
(1)支持POST、GET、HEAD三种方法;

(2)规定浏览器与服务器之间只保持短暂的连接,浏览器的每次请求都需要与服务器建立一个TCP连接,服务器完成请求处理后立即断开TCP连接,服务器不跟踪每个客户也不记录过去的请求;

3、HTTP 1.1:
(1)新增了五种请求方法:PUT、DELETE、CONNECT、TRACE、OPTIONS;

(2)HTTP 1.1 在Request消息头里头多了一个Host域,便于一台WEB服务器上可以在同一个IP地址和端口号上使用不同的主机名来创建多个虚拟WEB站点;

(3)长连接

(4)缓存策略不同

(5)在HTTP/1.1中新增了24个状态响应码:
100-199 用于指定客户端应相应的某些动作。
200-299 用于表示请求成功。
300-399 用于已经移动的文件并且常被包含在定位头信息中指定新的地址信息。
400-499 用于指出客户端的错误。
500-599 用于支持服务器错误。

4、HTTP 2.0

二进制传输:http 1.x 的解析是基于文本,http2的解析是基于二进制;

多路复用

header压缩

服务端推送

4.http code 206 401

206 Partial Content

最后一条会话返回了HTTP/206 “Partial Content”响应.这种响应是在客户端表明自己只需要目标URL上的部分资源的时候返回的.这种情况经常发生在客户端继续请求一个未完成的下载的时候(通常是当客户端加载一个体积较大的嵌入文件,比如视频或PDF文件),或者是客户端尝试实现带宽遏流的时候。

你可以通过Range请求头辨认出一个部分内容请求.该请求头表明了客户端需要请求资源的哪一部分。

401错误原因:用户没有访问权限,需要进行身份认证。

http 常见的错误码

2XX 成功

· 200 OK,表示从客户端发来的请求在服务器端被正确处理

· 204 No content,表示请求成功,但响应报文不含实体的主体部分

· 206 Partial Content,进行范围请求

3XX 重定向

· 301 moved permanently,永久性重定向,表示资源已被分配了新的 URL

· 302 found,临时性重定向,表示资源临时被分配了新的 URL

· 303 see other,表示资源存在着另一个 URL,应使用 GET 方法丁香获取资源

· 304 not modified,表示服务器允许访问资源,但因发生请求未满足条件的情况

· 307 temporary redirect,临时重定向,和302含义相同

4XX 客户端错误

· 400 bad request,请求报文存在语法错误

· 401 unauthorized,表示发送的请求需要有通过 HTTP 认证的认证信息

· 403 forbidden,表示对请求资源的访问被服务器拒绝

· 404 not found,表示在服务器上没有找到请求的资源

5XX 服务器错误

· 500 internal sever error,表示服务器端在执行请求时发生了错误

· 503 service unavailable,表明服务器暂时处于超负载或正在停机维护,无法处理请求

5.为什么三次握手,四次挥手

6.dispatch_async(queue,block);会不会开线程

除了主队列,其他队列都开线程。

7.二叉树中和为某一值的路径

LeetCode题目链接:剑指 Offer 34. 二叉树中和为某一值的路径

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Solution {
LinkedList<List<Integer>> res = new LinkedList<>();
LinkedList<Integer> path = new LinkedList<>();
public List<List<Integer>> pathSum(TreeNode root, int sum) {
recur(root, sum);
return res;
}
void recur(TreeNode root, int tar) {
if(root == null) return;
path.add(root.val);
tar -= root.val;
if(tar == 0 && root.left == null && root.right == null)
res.add(new LinkedList(path));
recur(root.left, tar);
recur(root.right, tar);
path.removeLast();
}
}

8.Runtime

9.UIView 绘制过程

UIView的绘制原理

UIView的绘制原理

当我们调用 UIView 的 setNeedsDisplay 方法以后,实际上并没有立刻发生当前视图的绘制工作,而是在之后的某一时机才会进行当前视图的绘制 。为什么没有立刻发生当前视图的绘制工作?(因为到当前 runloop 将要结束的时候,才会开始介入到UI视图的绘制流程中)

  • 当调用 UIView 的 setNeedsDisplay 后
  • 系统会立刻调用 view 的 layer 的同名方法 [view.layer setNeedsDisplay] ,之后相当于在 layer 上面打上了一个脏标记
  • 然后再当前 runloop 将要结束的时候,才会调用 CALayer 的 display 函数方法,然后才进入到当前视图的真正绘制工作的流程当中
  • CALayer 的 display 方法,在内部会首先判断 layer 的 delegate 是否响应 displayLayer 这个方法
  • 若不响应,则系统开始绘制流程
  • 若响应,则开始异步绘制

系统绘制流程

系统绘制流程

  • 首先 CALayer 内部会创建一个 CGContextRef ,在 drawRect 方法中,可以通过上下文堆栈当中的取出这个 context,拿到的就是当前控件或者说视图的上下文或者说是 backing store
  • 然后 layer 会判断它是否有代理,若没有,则调用 CALayer 的 drawInContext。
  • 若有则调用代理方法,然后做当前视图的绘制工作(这一步发生在系统内部当中),再在合适的时机,基于 drawRect 回调方法,
  • drawRect 默认操作是什么都不做,而之所以有这个接口,就是为了让我们在系统绘制之上,可以做些自定义的绘制工作。
  • 最后再由 CALayer 上传对应的 backing store 给 GPU,这里的 backing store 我们可以理解为位图。

异步绘制流程

异步绘制时序图

  • 左侧是主队列,右侧是全局并发队列
  • 假如在某一时机调用了 setNeedsDiaplay 方法后
  • 在当前 runloop 将要结束的时候,会有系统调用视图所对应 layer 的 display 方法
  • 如果代理实现了 displayLayer 方法,会调用这个代理的 displayLayer 这个方法
  • 然后通过子线程的切换,我们会在子线程中去做位图的绘制,此时主线程可以去做些其他的工作
  • 然后再回到主队列中,提交这个位图,设置给 CALayer 的 contents 属性

子线程的绘制

  1. 通过 CGBitmapContextCreat 方法,来创建一个位图的上下文
  2. 通过 CoreGraphic 的相关 API,可以做当前 UI 控件的一些绘制工作
  3. 之后通过 CGBitmapContextCreatImage 方法,根据所绘制的上下文,生成一张 CGImage 图片
  4. 最后回到主队列中,将该 CGImage 图片设置为 CALayercontents

参考链接:UI绘制原理&系统/异步绘制流程

UIView的绘制原理及优化

10.autoreleasepool

  • 子线程使用了 autorelease 后,如果当前线程没有 AutorelesepoolPage 的话,代码执行顺序为 autorelease -> autoreleaseFast -> autoreleaseNoPage。在 autoreleaseNoPage 方法中,会创建一个 hotPage ,然后调用page->add(obj) 。也就是说即使这个线程没有 AutorelesepoolPage ,使用了 autorelease 对象时也会 new 一个 AutoreleasepoolPage 出来管理 autorelese 对象。
  • 子线程的 autoreleasepool 是在线程销毁的时候释放的。

11.VC生命周期,viewWillDisappear 和 viewDidDisappear 之间会不会调用view 的 layout

push 会调用,pop 不会调用

1
2
3
4
5
6
7
8
9
10
11
1 push 2
2-[2 loadView]
2-[2 viewDidLoad]
1-[1 viewWillDisappear:]
2-[2 viewWillAppear:]
2-[2 viewWillLayoutSubviews]
2-[2 viewDidLayoutSubviews]
1-[1 viewWillLayoutSubviews]
1-[1 viewDidLayoutSubviews]
1-[1 viewDidDisappear:]
2-[2 viewDidAppear:]

12.autorelease 调用 release 会立即销毁吗

13.GCD能不能取消任务

  • dispatch_block_cancel

  • 定义外部变量,用于标记block是否需要取消

参考链接:如何取消GCD任务

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×