面试

Android面试总结

2019-05-20  本文已影响17人  我还是一个程序猿

 Android 面试总结

第一部分 Java部分

1 hashmap和hashtable的区别 详情请参考源码

  父类不同

  查询方式不同

  Hashmap 不是线程安全的而hashtable是线程安全的

  Hashmap key value 允许使用null值 那是因为hashmap默认把null的hash值设置成了0  而hashtable不允许key value使用null值

  Hashmap默认长度是16 每次增长2倍  hashtable默认长度是11 每次增加2n+1

Hashmap源码解析:

数组和链表如何工作  -----  当执行put方法的时候 把key的hashcode值通过位运算转变成数组下标

2 array list和 linkedlist的区别 详情请参考源码

  Arraylist 是以数组的形式存储数据  在查询的情况下 array list 效率比较快一点

  Linkedlist以单链表的形式存储数据 在插入和删除的情况下 linkedlist效率会快一点 

3 Java四种引用方式  弱引用和软引用区别

  使用软引用 Java GC工作的时候 如果内存空间够的话 不会回收 只有内存空间不够的情况下 才会回收  而使用弱引用的话 只要GC一工作便会回收

第二部分 Android 

 1  Activity的生命周期

  oncreate 当activity创建的时候执行此方法

  onstart 当activity开始运行 但是用户看不见的时候执行此方法

  onresume 当activity处于前台 用户能看见了 执行此方法

  onpause 当activity处于后台执行方法

  onstart 当activity暂停 执行此方法

  onrestart  当actvitiy 从后台重新回到前台执行此方法。

  Ondestroy 当activity 销毁执行此方法

  Activity 的启动方式

  Standard 默认启动方式 每次都会创建一个新的activity

  SingeTop 栈顶复用模式  当activity处于栈顶的时候 不执行 oncreate onstart 方法 执行 onnewIntert 方法  如果不处于栈顶 则会重新创建一个activity实例

  SingeTask 当activity处于栈顶的时候不执行 oncreate onstart方法 执行 onnewIntent 当activity 不在栈顶 他会把位于他上头的activity都出栈 自己到栈顶

  Singeinstance 单例模式的 直接创建一个新的任务栈 并且把activity实例放在任务栈中

2 Fragment 的生命周期

3 Service 生命周期

4 Android设计模式

   单例模式 观察者模式 代理模式

5  JVM

6 HTTP协议网络请求

 http发送请求分为七个步骤

  第一步建立连接

第二部客户端向服务器发送http请求

第三步客户端发送请求头信息 最后发送一个空的请求体代表请求头信息发送完毕 如果是post提交 则会继续发送请求体

第四步 服务器端应答 应答的第一部分是版本号和http状态码

第五步 发送应答头信息 最后发送一个空白行代表发送结束

第六步 web服务器发送数据以Content-type 应答头信息 开始的 然后跟一个空行 再以下是响应的数据

第七步 web服务器关闭TCP连接,一旦web服务器向客户端发送完消息之后它就要关闭TCP请求。

 三次握手

  第一次握手  建立连接,将SYN设置为1 seq设置x 然后客户端进入等待状态

  第二次握手  服务器端收到客户端的SYN设置,需要对SYN值进行确认,设置ACK的值为 seq+1,同时自己还要发送SYN值 设置为1 ,seq设置成Y,此时服务器进入等待状态

  第三次握手  客户端收到服务器的SYN+ACK报文段,然后将ACK设置成seq+1 seq = z一并发给服务器

  为了防止已失效的连接请求报文段突然又传送到服务端,因而产生错误 所以才需要三次握手。

 四次挥手

 五层模型   

应用层(http)  传输层(tcp)  网络层(ip)  链路层 物理层

 http和https的区别

Socket是应用层与TCP/IP协议通信的一个抽象层,它是一组接口,

 7多线程 线程池

 8线程安全 volatile关键字

   Synchronized (新块儿奈斯特) 同步代码块 同步方法

   Lock 是一个接口 当发生异常的时候不会主动释放锁 必须通过lock.unlock释放

 Synchronized是Java的关键字 当发生异常的时候会主动释放锁

 Volatile

9 HandlerThread    IntentService

 IntentServic继承自service。其实内部是以handler和handlerThread实现的 在oncreate方法里创建一个HandlerTread  

 然后在里头创建了一个名为ServiceHandler的hanlder  然后把ServiceHandler和HandlerThread对应的子线程进行绑定

通过onstartcommand方法 内部调用onstart方法把消息传递给Intent,依次插入到工作队列中,并逐个发送给onhandlerIntent方法

HandlerThread是Google帮我们封装好的 可以执行多个耗时操作 里面采用的是Handler Looper方式实现的

使用HandlerThread必须先调用start方法 调用start方法之后线程会交给虚拟机调度 虚拟机自行调用run方法

10 Handler讲解。

 Handler   负责处理消息 

 MessageQueue  存放消息 先进先出原则

 Looper   轮询消息队列里有没有消息 如果有消息就取出来 

  主线程的Looper在activityThread已经创建好了 所以主线程创建handler的时候不需要手动创捷looper

  当在activity主线程创建handler的时候 首先会先查找有没有looper

子线程中使用handler要创建Looper对象 调用Looper.prepare方法创建Looper 调用Looper.loop方法来轮询消息队列

 当Handler发送消息的时候会调用 MessageQueue 的 enqueuemessage方法来向消息队列里头插入消息 当通过looper.loop 循环消息的时候 调用MessageQueue.next 方法来获取消息

 Looper存储在ThreadLocal里头 ThreadLocal是线程本地存储区,每个线程都有自己私有的线程存储区,不同线程之间不能访问彼此的线程存储区 简称TLS区域

当handler执行sendMessage方法时 经过层层调用一直到MessageQueue的enqueueMessage方法往消息队列里插入数据 然后Loope通过MessageQueue.next方法取出消息

 为什么主线程loop死线程不会导致ANR

   MessageQueue.next方法会获取到第一个消息 来进行对比 看看到没到执行时间如果没到执行时间就等待 会放到Linux层等待 释放当前线程

 10.1 ThreadLocal的作用是提供线程内的局部变量,这种变量在线程的生命周期内起作用,减少同一个线程内多个函数或者组件之间一些公共变量的传递的复杂度。换句话说ThreadLocal是线程隔离的工具类

   一个Thraed只对应一个Looper , 因为MessageQueue是在Looper里头创建的所以也只有一个

   因为Looper的prepare方法里头调用了ThreadLocal.get方法来保证唯一性 如果之前已经创建过 就抛出异常

 11 当Android中发生handler泄露怎么办

 发生泄漏的情况一般是handler在执行耗时任务的时候 activity已经处于关闭状态 这个时候 由于handler还没有运行完毕 还持有activity的引用 所以没法回收activity 

 解决办法  当activity 执行 ondestroy方法的时候 关闭handler 把handler设置成null

 第二种办法就是 把当前handler设置成静态的  在handler里对当前activity使用弱引用

 12  Android中使用cookie  

 13  mvc mvp mvvm

  MVP全称是 model view presenter

   优点 视图(View) 和 model 完全分离 逻辑代码全部放再presenter里头 可以更高效的使用model

   缺点 presenter与view交互过于频繁 view发生改变 presenter也要随之发生改变

   Mvc 有点 耦合度低 重用性高  

  在MVP框架里 model和view并不直接交互 而是使用presenter做为两者之间的桥梁

 14  okhttp

 15 EnevtBus 工作原理

16 rxjava

17 view的绘制过程

   onMeause onLayout onDraw

18 Android 事件分发

  Activity PhoneWindow DecorView ViewGroup View

 先判断父容器是否拦截事件,没有拦截再继续向下分发,分发的时候找触摸点在哪个View 找的过程就是分发的过程,找到dispatchTouchEvent为true的View

 冲突解决方法  

   1 内部拦截  在子view进行处理的就 叫内部拦截

   2 外部拦截  在父容器处理的就叫外部拦截

19 进程保活 以及进程拉活

 进程保活 1像素保活  

 前台进程保活

 进程拉货

 双进程守护

20 进程优先级

  前台进程 可见进程 服务进程 后台进程 空进程

21 进程之间的通信 Aidl builder

22 内存泄漏以及内存优化

   集合泄漏

   单例模式泄漏

   Handler泄漏   在执行一个耗时任务的时候 当Acitivty关闭,但是线程并没有关闭 这个时候就会发生内存泄漏

   非静态内部类泄漏  因为非静态内部类会持有外部类的引用

   Static 泄漏  尽量不要用静态变量 它的生命周期伴随整个App的生命周期

   内存优化  

     布局优化  尽可能的少使用嵌套布局

     Bitmap的优化

     数据缓冲优化

     Handler优化

23 liveData hook技术

24 屏幕适配

    比例缩放

25 数据持久化 

MKV 不使用IO方式 使用的是MMAP

    Linux可以将虚拟内存与磁盘上的对象关联起来 。以初始化这个虚拟内存的内容 这个过程就叫做 MMAP。

    MMAP  不经过内核空间。通过对磁盘文件的映射,操作内存就相当于操作文件。

上一篇下一篇

猜你喜欢

热点阅读