字节跳动(视频面试2020-03)

1、UI渲染为什么要放在主线程中?
- UI操作涉及到渲染访问各种View对象的属性,如果是异步操作会有读写问题;
- 如果加锁,性能损耗大(视图层次深、属性多);
所以,主线程操作UI,是约定俗称的开发规则

2、TCP三次握手和四次挥手
- 第一次握手:客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;
- 第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包,即SYN+ACK包,此时服务器进入SYN+RECV状态;
- 第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次状态。
- 第一次挥手:客户端向服务器发送FIN包,表示自己没有数据要发送了;
- 第二次挥手:服务器收到FIN包,回复FIN ACK,表示收到了FIN包,不会在接收数据了;
- ⚠️服务器在发完FIN ACK后,可能还有数据要发给客户端,这个数据是不能停止发送的,有数据还是需要继续发送;
- 第三次挥手:服务器发完了数据,也发出FIN包,告诉客户端自己的数据发送完了,不再发送数据;
- 第四次挥手:客服户收到服务器发送的FIN包,知道服务器没有数据要发送了,回复FIN ACK,此时断开连接。
为什么要多次确认呢?

TCP 是传输层的协议,是建立在物理层、数据链路层、网络层之上的协议,
而底层的网络是不可靠的,可能路由、网关、网线出问题,客户端没法保证自己发出来的消息服务器一定能收到。
所以一定要反馈机制,即 ACK,这样才能在不可靠的网络层智商构建可靠的传输层。
建连只需要交互三次,断连却需要四次,这是为什么呢?

- 建连的时候,只要双方都告知对方自己准备好了就可以;
- 断连的时候,一方提出要断开连接,不再发数据,另一方不能立即断开,
因为这一方可能还有数据要发送,直到数据全部发送完成后才能确认断开。

3、GCD定时器和NSTimer有什么不同
- NSTimer需要一个运行的Runloop 来处理其定时任务, MainThread是一直启动并运行的,所以在自定的线程如果使用NSTIme必须手动开启并运行子线程的Runloop;
- NSTimer必须调用invalidate来停止其定时任务,并且NSTimer 对其Target是强引用,要注意Target 与 - NSTimer间造成的循环引用造成的内存泄漏(可以封装成一个类方法来解决此问题);
- NSTimer的创建和 invalidate必须放在相同的线程中进行

- GCDTimer 是基于GCD实现的,使用的时候只要我们把任务提交给相应队列就好;
- GCDTimer 在使用时要注意 dispatch_resume(obj) dispatch_suspend(obj) -dispatch_source_cancel(obj)API 的使用
- GCDTimer 在对文件资源定期进行读写操作时很方便,其他与NSTimer使用场景差不多

4、https原理

必看文章一
必看文章二

  • 4.1、为什么用了HTTPS 就是安全的?HTTPS 的底层原理如何实现?用了 HTTPS 就一定安全吗?

  大家可能都听说过 HTTPS 协议之所以是安全的,是因为HTTPS协议会对传输的数据进行加密,而加密过程是使用了非对称加密实现。
  但其实,HTTPS 在内容传输的加密上使用的是对称加密,非对称加密只作用在证书验证阶段。

  • 4.2、证书验证阶段:
1、浏览器发起 HTTPS 请求;
2、服务端返回 HTTPS 证书;
3、客户端验证证书是否合法,如果不合法则提示告警
  • 4.3、数据传输阶段:
1、当证书验证合法后,在本地生成随机数;
2、通过公钥加密随机数,并把加密后的随机数传输到服务端;
3、服务端通过私钥对随机数进行解密;
4、服务端通过客户端传入的随机数构造对称加密算法,对返回结果内容进行加密后传输
  • 4.4、数据传输阶段
为什么数据传输是用对称加密?
- HTTP 的应用场景中通常端与端之间存在大量的交互,非对称加密的加解密效率是非常低的;
- 另外,在 HTTPS 的场景中只有服务端保存了私钥,一对公私钥只能实现单向的加解密
所以 HTTPS 中 ***内容传输*** 加密采取的是对称加密,而不是非对称加密。
  • 4.5、本地随机数被窃取怎么办?

  证书验证是采用非对称加密实现,但是传输过程是采用对称加密,而其中对称加密算法中重要的随机数是由本地生成并且存储于本地的,HTTPS 如何保证随机数不会被窃取?
  其实 HTTPS 并不包含对随机数的安全保证,HTTPS 保证的只是传输过程安全,而随机数存储于本地,本地的安全属于另一安全范畴,应对的措施有安装杀毒软件、反木马、浏览器升级修复漏洞等.


5、Charles抓包原理

  HTTPS 的数据是加密的,常规下抓包工具代理请求后抓到的包内容是加密状态,无法直接查看。但是,浏览器只会提示安全风险,如果用户授权仍然可以继续访问网站,完成请求。
  因此,只要我们自己的客户端在授权的情况下,便可以组建中间人网络,而抓包工具便是作为中间人的代理。
  通常HTTPS抓包工具的使用方法是会生成一个证书,用户需要手动把证书安装到客户端中,然后终端发起的所有请求通过该证书完成与抓包工具的交互。
  然后抓包工具再转发请求到服务器,最后把服务器返回的结果在控制台输出后再返回给终端,从而完成整个请求的闭环。

  • 5.1、既然HTTPS不能防抓包,那 HTTPS 有什么意义?

  HTTPS可以防止用户在不知情的情况下通信链路被监听,对于主动授信的抓包操作是不提供防护的,因为这个场景用户是已经对风险知情。
  要防止被抓包,需要采用应用级的安全防护,例如采用私有的对称加密,同时做好移动端的防反编译加固,防止本地算法被破解。


6、说说你知道的线程锁
常用:@synchronized、NSLock、dispatch_semaphore
不常用:OSSpinLock、pthread_mutex、NSCondition、NSRecursiveLock等等

具体可以看看这篇文章:iOS 开发中的八种锁


7、UITableView卡顿是如何优化的
- 可通过Instruments测试FPS,确保刷新帧率在 60+/s 
- 要想滚动UITableView流畅,关键的在创建cell或者从缓存池取cell时,让系统花费最少的时间,

即尽可能的减少显示cell的计算量。
1、缓存行高
举个简单的栗子: 如果现在要显示100个Cell,当前屏幕显示5个。

- 全局刷新UITableView时:
会先调用100次tableView:heightForRowAtIndexPath,然后调用5次tableView:cellForRowAtIndexPath

- 滚动屏幕时:
当Cell滚入屏幕,都会调用一次tableView:heightForRowAtIndexPath和tableView:cellForRowAtIndexPath

所以,要提前计算并缓存好高度,因为heightForRowAtIndexPath:是调用最频繁的方法
2、不要动态创建子视图
Cell所有的子视图都预先在初始化方法中创建。如果根据实际情况不需要显示的可以设置hidden。
这样能尽可能的减少Cell创建或从缓存池取时因为布局子控件所消耗的时间。
3、所有的子视图都必须指定背景颜色(可能会为你造成这种现象的原因)
相信很多程序员在开发时经常会遇到这种情况,当从某个控制器A跳转到下一个控制器B时,若B控制器的view未设置背景颜色,跳转时会有卡顿现象。
cell也一样,若控件未指定背景颜色,会影响tableView滚动的流畅度。
4、所有的颜色都不要使用alpha
控件如有透明度,会显示底部控件的部分轮廓,系统在显示cell时,需要计算各控件间的叠加面积,颜色的透明度等;
但如果所有控件颜色不透明,则不需要耗费性能去计算,能节省大量时间.
5、异步绘制
如果Cell 比较复杂,可以设置cell图层的属性 self.layer.drawsAsynchronously = YES;
6、UITableview加载图片的时候使用懒加载模式和异步加载模式
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章