字节一面面经

1.自我介绍

2.询问你一些简历上的基本信息

3.开始拷打提问

(1) Android的四大基本组件:Activity,Service,Content Provider,Broadcast Receive

(2) Activity的生命周期:onCreate,onRestart,onStart,onResume,onPause,onStop,onDestroy

(3) view的测量和布局

(4) ANR是什么:

​ ANR的全称是application not responding,是指应用程序未响应,Android系统对于一些事件需要在一定的时间范围内完成,如果超过预定时间能未能得到有效响应或者响应时间过长,都会造成ANR。一般地,这时往往会弹出一个提示框,告知用户当前xxx未响应,用户可选择继续等待或者Force Close。

​ 首先ANR的发生是有条件限制的,分为以下三点:

  • 只有主线程才会产生ANR,主线程就是UI线程;
  • 必须发生某些输入事件或特定操作,比如按键或触屏等输入事件,在BroadcastReceiver或Service的各个生命周期调用函数;
  • 上述事件响应超时,不同的context规定的上限时间不同
  1. 主线程对输入事件5秒内没有处理完毕
  2. 主线程在执行BroadcastReceiver的onReceive()函数时10秒内没有处理完毕
  3. 主线程在前台Service的各个生命周期函数时20秒内没有处理完毕(后台Service 200s)

(5)Java关键字sychronied

​ sychronied是Java中并发编程的重要关键字之一。在并发编程中synchronized一直是解决线程安全问题,它可以保证原子性,可见性,以及有序性。

原子性:原子是构成物质的基本单位,所以原子的意思代表着—“不可分”。由不可分可知,具有原子性的操作也就是拒绝线程调度器中断。

可见性:一个线程对共享变量的修改,另一个线程能够立刻看到,称为可见性。

有序性:程序按照代码的先后顺序执行。编译器为了优化性能,有时会改变程序中语句的顺序,但是不会影响最终的结果。有序性经典的例子就是利用DCL双重检查创建单例对象。

synchronized可以修饰方法,也能够使用synchronized(obj){}定义同步代码块。

  • 修饰方法:

    1. 实例方法,作用于当前实例加锁,进入方法前需要获取当前实例的锁;
    2. 静态方法,作用于当前类对象加锁,进入方法前需要获取当前类对象的锁;
  • 修饰代码块,指定加锁对象,对给定对象加锁,进入代码块前要获得给定对象的锁。

使用sychronied修饰普通方法和静态方法,其实也等价于synchronized(this){}synchronized(class){}

(6) Java关键字volatile

​ volatile是java提供的可以声明在成员属性前的一个关键字。在声明中包含此关键字的作用有:

保证内存可见性

​ 可见性是指线程之间的可见性,一个线程修改的状态对另一个线程是可见的。也就是一个线程修改的结果,另一个线程马上就能看到。

​ 当对非volatile变量进行读写的时候,每个线程先从主内存拷贝变量到CPU缓存中,如果计算机有多个CPU,每个线程可能在不同的CPU上被处理,这意味着每个线程可以拷贝到不同的CPU cache中。

​ volatile变量不会被缓存在寄存器或者对其他处理器不可见的地方,保证了每次读写变量都从主内存中读,跳过CPU cache这一步。当 一个线程修改了这个变量的值,新值对于其他线程是立即得知的。

禁止指令重排

​ 指令重排序是JVM为了优化指令、提高程序运行效率,在不影响单线程程序执行结果的前提下,尽可能地提高并行度。指令重排序包括编译器重排序和运行时重排序。

​ latile变量禁止指令重排序。针对volatile修饰的变量,在读写操作指令前后会插入内存屏障,指令重排序时不能把后面的指令重排序到内存屏

(7)描述TCP三次握手与四次挥手的过程与意义

​ TCP/IP协议定义了计算机在网络中如何发送数据、数据格式如何定义、发出消息后在网络中如何寻址找到目标计算机,最后目标计算机又如何检验收到消息的正确性、对数据拆解最后得到消息内容的一套处理标准。

有了这些标准后生产提供TCP/IP服务的软件商家就有了一套统一的规范,只要遵循这个规范去实现自己的软件功能。

三次握手

在进行业务通信前,必须建立好连接,而TCP/IP连接的建立需要经过三次握手的过程。其过程如下图:

图片

  1. 第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SENT状态,等待服务器确认;SYN:同步序列编号(Synchronize Sequence Numbers)。
  2. 第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
  3. 第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。
为什么要三次握手?

三次握手的意义在于确定双方都能够完成读写操作。

第一次握手,客户端发了个连接请求消息到服务端,服务端收到信息后知道自己与客户端是可以连接成功的,但此时客户端并不知道服务端是否已经接收到了它的请求,所以服务端接收到消息后的应答。客户端得到服务端的反馈后,才确定自己与服务端是可以连接上的,这就是第二次握手。而服务端发送出去的消息,要等客户端响应后,才能确定此次连接为有效连接。

否则假设:

客户端发出去的第一个连接请求由于某些原因在网络节点中滞留了导致延迟,直到连接释放的某个时间点才到达服务端,这是一个早已失效的报文,但是此时服务端仍然认为这是客户端的建立连接请求第一次握手,于是服务端回应了客户端,第二次握手。如果没有第三次握手,那么到这里,连接就建立了,但是此时客户端并没有任何数据要发送,会让服务端空等,造成资源浪费。

四次挥手

在完成数据交互之后,如果选择关闭连接,以回收资源,则完成四次挥手来进行“和平分手”。过程如下图:

图片

  1. 第一次挥手:主动关闭方发送第一个包,其中FIN标志位为1,发送顺序号seq为X。
  2. 第二次挥手:被动关闭方收到FIN包后发送第二个包,其中发送顺序号seq为Z,接收顺序号ack为X+1。
  3. 第三次挥手:被动关闭方再发送第三个包,其中FIN标志位为1,发送顺序号seq为Y,接收顺序号ack为X。
  4. 第四次挥手:主动关闭方发送第四个包,其中发送顺序号为X,接收顺序号为Y。至此,完成四次挥手。
为什么断开连接需要四次挥手?

三次握手是因为建立连接时,ACK和SYN可以放在一个报文里来发送。而关闭连接时,被动关闭方可能还需要发送一些数据后,再发送FIN报文表示同意现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的。因此断开连接需要4次。

(8)TCP和UDP的区别

​ TCP是有连接,UDP是无连接的;TCP比UDP传说数据更安全;TCP能够确认数据包是否传给对方,UDP直接发送报文不需要确认是否发送,传输更快。

(9)HTTP和HTTPS是什么,为什么HTTPS比HTTP更安全

网络编程面试题:谈谈你对Http与Https的关系理解 (qq.com)

(10)View的绘制(好像问了,我不会,没记住)

(11)一个线程可以有几个Handler,为什么

4.算法题:

​ 二叉树,相当于判断b树是不是a树的子树

5.面试管询问有没有什么想问的。

有一些问题可能没记住,忘了录音

Android面试资料:【建议收藏】106道Android核心面试题及答案汇总(总结最全面的面试题) - 掘金 (juejin.cn)

MartinLiuMingZhi/Notes: Java和Android面试八股文 (github.com) (能帮忙star一下吗)

Hello World - 愿世界更美好 (martinliumingzhi.github.io)