美文网首页
Android 面试总结

Android 面试总结

作者: dedeTao | 来源:发表于2019-08-06 17:02 被阅读0次

    [toc]

    1. ==JVM内存模型==

    • 程序计数器:当前线程所执行的字节码的行号指示器,用于记录正在执行的虚拟机字节指令地址,线程私有。
    • Java虚拟栈:存放基本数据类型、对象的引用、方法出口等,线程私有。
    • Native方法栈:和虚拟栈相似,只不过它服务于Native方法,线程私有。
    • Java堆:java内存最大的一块,所有对象实例、数组都存放在java堆,GC回收的地方,线程共享。
    • 方法区:存放已被加载的类信息、常量、静态变量、即时编译器编译后的代码数据等。(即永久带),回收目标主要是常量池的回收和类型的卸载,各线程共享


      image

    2. ==Java类加载机制==

    image

    Java类加载分为5个过程,分别为:加载,连接(验证,准备,解析),初始化,使用,卸载。

    1. 加载

    加载主要是将.class文件(也可以是zip包)通过二进制字节流读入到JVM中。 在加载阶段,JVM需要完成3件事:

    • 1)通过classloader在classpath中获取XXX.class文件,将其以二进制流的形式读入内存。
    • 2)将字节流所代表的静态存储结构转化为方法区的运行时数据结构;
    • 3)在内存中生成一个该类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。

    2. 连接

    • 验证

    主要确保加载进来的字节流符合JVM规范。验证阶段会完成以下4个阶段的检验动作:

    1. 文件格式验证
    2. 元数据验证(是否符合Java语言规范)
    3. 字节码验证(确定程序语义合法,符合逻辑)
    4. 符号引用验证(确保下一步的解析能正常执行)
    • 准备

    准备是连接阶段的第二步,主要为静态变量在方法区分配内存,并设置默认初始值。

    • 解析

    解析是连接阶段的第三步,是虚拟机将常量池内的符号引用替换为直接引用的过程。

    3. 初始化

    初始化阶段是类加载过程的最后一步,主要是根据程序中的赋值语句主动为类变量赋值。

    当有继承关系时,先初始化父类再初始化子类,所以创建一个子类时其实内存中存在两个对象实例。
    注:如果类的继承关系过长,单从类初始化角度考虑,这种设计不太可取。原因我想你已经猜到了。
    通常建议的类继承关系最多不超过三层,即父-子-孙。某些特殊的应用场景中可能会加到4层,但就此打住,第4层已经有代码设计上的弊端了。

    4. 使用

    程序之间的相互调用。

    5. 卸载

    即销毁一个对象,一般情况下中有JVM垃圾回收器完成。代码层面的销毁只是将引用置为null。


    3. ==Android Dex==

    Dalvik 是 Google 设计的用于 Android平台的运行时环境,ART 即 Android Runtime,Android 4.4 推出替换Dalvik。 Dalvik 虚拟机并不支持直接执行 JAVA 字节码,Dex 文件格式是专为 Dalvik 设计的一种压缩格式。简单的理解为:Dex 文件是很多 .class 文件处理后的产物,最终可以在 Android 运行时环境执行。
    参考链接

    1. 数据结构


      数据结构
    2. 加固原理
      [图片上传失败...(image-f27717-1565081811602)]

    3. 热修复原理


      方法
    微信热修复原理

    4. ==排序算法==

    参考链接

    1. ==简单选择排序==

    基本思想为每一趟从待排序的数据元素中选择最小(或最大)的一个元素作为首元素,直到所有元素排完为止,时间复杂度为O(n2)

    选择排序
        public static void selectSort(int[] arr) {
            for (int i = 0; i < arr.length - 1; i++) {
                //每一趟循环比较时,min用于存放较小元素的数组下标,这样当前批次比较完毕最终存放的就是此趟内最小的元素的下标,避免每次遇到较小元素都要进行交换。
                int min = i;
                for (int j = i + 1; j < arr.length; j++) {
                    if (arr[j] < arr[min]) {
                        min = j;
                    }
                }
                //进行交换,如果min发生变化,则进行交换
                if (min != i) {
                    swap(arr,min,i);
                }
            }
        } 
        
        /**
         * 交换数组元素
         */
        public static void swap(int []arr,int a,int b){
            arr[a] = arr[a]+arr[b];
            arr[b] = arr[a]-arr[b];
            arr[a] = arr[a]-arr[b];
        }
    
    1. ==冒泡排序==

    基本思想:对相邻的元素进行两两比较,顺序相反则进行交换,每一趟会将最小或最大的元素“浮”到顶端,最终达到完全有序,时间复杂度为O(n2)

    冒泡排序
        public static void bubbleSort(int[] arr) {
            for (int i = 0; i < arr.length - 1; i++) {
                boolean flag = true;//设定一个标记,若为true,则表示此次循环没有进行交换,也就是待排序列已经有序,排序已然完成。
                for (int j = 0; j < arr.length - 1 - i; j++) {
                    if (arr[j] > arr[j + 1]) {
                        swap(arr,j,j+1);
                        flag = false;
                    }
                }
                if (flag) {
                    break;
                }
            }
        }
    
    1. ==插入排序==

    基本思想是每一步将一个待排序的记录,插入到前面已经排好序的有序序列中去,直到插完所有元素为止,时间复杂度为O(n2)

    插入排序
        public static void insertionSort(int[] arr) {
            for (int i = 1; i < arr.length; i++) {
                int j = i;
                while (j > 0 && arr[j] < arr[j - 1]) {
                    swap(arr,j,j-1);
                    j--;
                }
            }
        }
    

    5. ==App启动流程==

    • ==图1==
    APP启动流程
    • ==图2==
    APP启动流程

    6. ==链表基础知识==

    链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。

    ┌────┬────┐

    │ data │ next │

    └────┴────┘

    1. ==数据结构==
    • 单链表:节点(元素+指针)
      单链表数据结构
    • 双向链表:可以知道前一个节点的位置
      双向链表数据结构
    1. ==与数组对比==

    数组(内存中==顺序存储==):数组长度固定、查询快,增删慢,随机访问性强

    链表(内存中==非顺序存储==):链表长度随时增减、查询慢,增删快,内存利用率高,不会浪费内存、不能随机查找,只能从头遍历查询

    1. ==增删==


      链表操作

    7. ==集合==

    1. ==集合继承关系==
    集合继承关系
    1. ==HashMap数据结构==

    JDK 1.8 以前 HashMap 的实现是 数组+链表,JDK 1.8 中引入了红黑树

    HashMap数据结构
    1. list、set、map的对比
      参考链接

    8. ==二叉树==

    1. 定义

    二叉树是每个节点最多有两个子树的树结构。

    二叉树
    1. ==二叉树遍历==
      [图片上传失败...(image-6e4-1565081811602)]
      [图片上传失败...(image-af0548-1565081811602)]
      [图片上传失败...(image-ae0ba2-1565081811602)]
      [图片上传失败...(image-cb4cf5-1565081811602)]
      [图片上传失败...(image-27513c-1565081811602)]

    2. ==满二叉树及完全二叉树== 参考链接


    9. ==Http==

    Hyper Text Transfer Protocol 超文本传输协议,是一种建立在TCP上的无状态连接,是一种建立在TCP上的无状态连接

    1. 三次握手和四次挥手
    • ==ACK== 确认字段:在连接建立后所有传送的报文段 ACK 必须为 1 。

    • ==SYN== 同步字段:连接建立时使用同步序号。

    • ==FIN== 终止字段:FIN = 1 是表示释放一个连接。

    • 序号 ==seq== :发送了多少被成功接受数据。

    • 确认号 ==ack==:接受了多少数据。

    • ==三次握手==

    第一次握手: 建立连接,客户端A发送SYN=1、随机产生Seq=client_isn的数据包到服务器B,等待服务器确认。

    第二次握手: 服务器B收到请求后确认联机(可以接受数据),发起第二次握手请求,ACK=(A的Seq+1)、SYN=1,随机产生Seq=client_isn的数据包到A。

    第三次握手: A收到后检查ACK是否正确,若正确,A会在发送确认包ACK=服务器B的Seq+1、ACK=1,服务器B收到后确认Seq值与ACK值,若正确,则建立连接。

    三次握手
    • ==四次挥手==
      四次挥手

    10. ==事件分发机制==

    事件分发机制

    11. ==Handler机制==

    相关文章

      网友评论

          本文标题:Android 面试总结

          本文链接:https://www.haomeiwen.com/subject/jrywdctx.html