[toc]
1. ==JVM内存模型==
- 程序计数器:当前线程所执行的字节码的行号指示器,用于记录正在执行的虚拟机字节指令地址,线程私有。
- Java虚拟栈:存放基本数据类型、对象的引用、方法出口等,线程私有。
- Native方法栈:和虚拟栈相似,只不过它服务于Native方法,线程私有。
- Java堆:java内存最大的一块,所有对象实例、数组都存放在java堆,GC回收的地方,线程共享。
-
方法区:存放已被加载的类信息、常量、静态变量、即时编译器编译后的代码数据等。(即永久带),回收目标主要是常量池的回收和类型的卸载,各线程共享
image
2. ==Java类加载机制==
imageJava类加载分为5个过程,分别为:加载,连接(验证,准备,解析),初始化,使用,卸载。
1. 加载
加载主要是将.class文件(也可以是zip包)通过二进制字节流读入到JVM中。 在加载阶段,JVM需要完成3件事:
- 1)通过classloader在classpath中获取XXX.class文件,将其以二进制流的形式读入内存。
- 2)将字节流所代表的静态存储结构转化为方法区的运行时数据结构;
- 3)在内存中生成一个该类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。
2. 连接
- 验证
主要确保加载进来的字节流符合JVM规范。验证阶段会完成以下4个阶段的检验动作:
- 文件格式验证
- 元数据验证(是否符合Java语言规范)
- 字节码验证(确定程序语义合法,符合逻辑)
- 符号引用验证(确保下一步的解析能正常执行)
- 准备
准备是连接阶段的第二步,主要为静态变量在方法区分配内存,并设置默认初始值。
- 解析
解析是连接阶段的第三步,是虚拟机将常量池内的符号引用替换为直接引用的过程。
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 运行时环境执行。
参考链接
-
数据结构
数据结构 -
加固原理
[图片上传失败...(image-f27717-1565081811602)] -
热修复原理
方法
4. ==排序算法==
- ==简单选择排序==
选择排序基本思想为每一趟从待排序的数据元素中选择最小(或最大)的一个元素作为首元素,直到所有元素排完为止,时间复杂度为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];
}
- ==冒泡排序==
冒泡排序基本思想:对相邻的元素进行两两比较,顺序相反则进行交换,每一趟会将最小或最大的元素“浮”到顶端,最终达到完全有序,时间复杂度为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;
}
}
}
- ==插入排序==
插入排序基本思想是每一步将一个待排序的记录,插入到前面已经排好序的有序序列中去,直到插完所有元素为止,时间复杂度为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==
- ==图2==
6. ==链表基础知识==
链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。
┌────┬────┐
│ data │ next │
└────┴────┘
- ==数据结构==
- 单链表:节点(元素+指针)
单链表数据结构 - 双向链表:可以知道前一个节点的位置
双向链表数据结构
- ==与数组对比==
数组(内存中==顺序存储==):数组长度固定、查询快,增删慢,随机访问性强
链表(内存中==非顺序存储==):链表长度随时增减、查询慢,增删快,内存利用率高,不会浪费内存、不能随机查找,只能从头遍历查询
-
==增删==
链表操作
7. ==集合==
- ==集合继承关系==
- ==HashMap数据结构==
HashMap数据结构JDK 1.8 以前 HashMap 的实现是 数组+链表,JDK 1.8 中引入了红黑树
- list、set、map的对比
参考链接
8. ==二叉树==
- 定义
二叉树二叉树是每个节点最多有两个子树的树结构。
-
==二叉树遍历==
[图片上传失败...(image-6e4-1565081811602)]
[图片上传失败...(image-af0548-1565081811602)]
[图片上传失败...(image-ae0ba2-1565081811602)]
[图片上传失败...(image-cb4cf5-1565081811602)]
[图片上传失败...(image-27513c-1565081811602)] -
==满二叉树及完全二叉树== 参考链接
9. ==Http==
Hyper Text Transfer Protocol 超文本传输协议,是一种建立在TCP上的无状态连接,是一种建立在TCP上的无状态连接
- 三次握手和四次挥手
-
==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机制==
- ==点击看大图==
handler机制
网友评论