-
排序算法的稳定和不稳定
稳定排序:冒泡、简单插入、归并、计数、基数
不稳定排序:快速、选择、堆、希尔 -
深拷贝和浅拷贝
深拷贝 | 浅拷贝 | |
---|---|---|
基本数据类型 | 复制基本类型的属性(值) | 复制基本类型的属性(值) |
引用类型 | 新建一个对象空间,复制栈中的变量和堆内存中的对象 | 复制栈中的变量和其所存的地址,不复制堆内存中的对象 |
Student student1 = new Student();
Student student2 = student1; //浅拷贝
Student student2 = (Student) sudent1.clone();//深拷贝
- volatile关键字
虚拟机为了提高程序的执行效率,把经常用到被访问的变量存储到缓存(cpu寄存器)中,而避免直接去内存中读
cup直接去内存读数据,需要通过总线发送指令给内存,速度远小于直接在缓存中直接读取数据。
遇到多线程的情况,变量的值可能已经被其他线程改变,而该缓存无法察觉内存中的变化,从而造成线程读取数据和内存中数据不一致。(脏数据)
使用volatile关键字,系统每次用到这个变量会直接去内存中取,不会利用缓存。 - 进程和线程
进程:进入到内存的程序
线程:进程中的一个执行单元,一个进行至少包含一个线程
- 多线程的创建
创建多线程的方式:(https://blog.csdn.net/wangzilong1995/article/details/104036403)
- 创建
Thread
子类,重写run
方法,设置线程任务,主程序创建子类对象,start
- 创建一个
Runable
接口的实现类,重写run
方法,创建实现类对象,创建Thread
对象,构造方法中加入刚创建的实现类对象,start
- 创建
Thread
对象,使用匿名内部类,重写run
方法三种方法优缺点:
- 一个儿子只有一个爸,第一种方法继承了
Thread
就不能继承别的类了,Runable
避免单继承的局限性,实现类实现了Runable
接口,还可以实现其他接口,继承其他类- Runable将设置线程任务与开启线程进行了分离
- 线程安全:多线程访问了共享的数据,会产生线程安全问题
- 解决方法
- 同步代码块
synchronized(同步锁对象){
可能发生线程安全的;
}
- 同步方法
public synchronized void 方法名(){
可能发生线程安全的;
}
- Lock锁
Lock l = new ReentrantLock();
l.lock();
可能发生线程安全的;
l.unlock();
- 死锁的解决方法:
1.加锁顺序(线程按照一定顺序加锁)
2.加锁时限(超时的时候放弃对该锁的请求,并释放自己占有的锁)
3.死锁检测 - 三次握手四次挥手
- 拥塞控制
若网络中有许多资源同时产生拥塞,网络的性能就要明显变差,整个网络的吞吐量将随输入负荷的增大而下降
- 慢开始:拥塞窗口值随着传输轮次呈指数增长
- 拥塞避免:拥塞窗口的值达到慢开始门限值(上一个超时点/2),慢开始停止,使用拥塞避免算法,每个传输轮次拥塞窗口值+1,直到发生部分报文段丢失,发送方对丢失报文段超时重传
- 第二次慢开始:拥塞避免中,发生部分报文段丢失,发送方对丢失报文段超时重传,此时进入快重传阶段,更新慢开始文献为发生超时点拥塞窗口的1/2,将拥塞窗口减小为1,重新慢开始
- 快重传快恢复:有时候个别报文段丢失,但是实际并未发生拥塞控制。因此可以采用快重传算法,让发送方尽早知道发生了个别报文段的丢失。如果在拥塞避免过程,收到3个ACK确认报文,就执行快重传和快算法:更新慢开始门限为超时/2,直接进行拥塞避免算法(省去慢开始)
- 流量控制
就是让发送方的发送速率不要太快,让接收方来得及接收
- 滑动窗口机制
发送端A和接收端B建立TCP连接时,B会传给A自己的接收窗口大小
A会根据B的接收窗口大小设置自己的发送窗口大小
A根据发送窗口的大小发送数据到B
B接收到数据后会向A发送:确认位ACK=1,累计确认,以及根据自己的资源情况动态调整的接收窗口
A根据B发送的接收窗口大小调整发送窗口,并根据累计确认(确认号字段)情况,右移滑动窗口
……
接收窗口置为0时,发送端不再发送数据,等待接收缓存有一些存储空间,再设置接收窗口,通知A发数据
其中可能发生情况:
1.发送端发送数据丢失:重传计时器超时,会被重传
2.当等待接收缓存有一些存储空间,再设置接收窗口,通知A发数据,这个通知的数据丢失:当A收到0窗口的时候,会启动一个持续计时器,持续计时器超时,A会发送携带1字节的零窗口探测报文
- TCP(传输控制协议)和UDP(用户数据报协议)的不同
TCP:
- 面向连接的服务,通信前要三次挥手建立连接,断开前要四次挥手断开连接
- 每条TCP连接只能是一对一的
- 将应用层的报文看成是字节流(面向字节流)
- 提供可靠的交付服务,无丢包;使用流量控制和拥塞控制(文件传输)
- 首部最小20字节,最大60字节(最大40字节扩展首部)(由于保证可靠服务,使用流量控制和拥塞控制,所以首部复杂)
UDP:
- 无连接
- 支持一对一,一对多,多对一,多对多交互通信
- 对应用层交付的报文直接打包(面向报文)
- 尽最大努力交互,也就是不可靠的;不使用流量控制和拥塞控制(IP电话,视频会议)
- 首部开销小,8字节
如何用UDP实现可靠传输:
由于在传输层UDP已经是不可靠的连接,那就要在应用层自己实现一些保障可靠传输的机制。等于说要在传输层的上一层(或者直接在应用层)实现TCP协议的可靠数据传输机制,比如使用UDP数据包+序列号,UDP数据包+时间戳等方法。
-
超时重传(定时器)
-
有序接受 (添加包序号)
-
应答确认 (Seq/Ack应答机制)
-
滑动窗口流量控制等机制 (滑动窗口协议)
UDT建于UDP之上,并引入新的拥塞控制和数据可靠性控制机制。试用于高带宽长距离网络 -
计算机网络模型
- ARP协议
IP地址到MAC的转化。
-
首先,每个主机都会在自己的ARP 缓冲区中建立一个ARP 列表,以表示 IP 地址和 MAC 地址之间的对应关系。
-
当源主机要发送数据时,首先检查ARP列表中是否有对应IP地址的目的主机的MAC地址,如果有,则直接发送数据
-
如果没有,就向本网段的所有主机发送ARP数据包,该数据包包括的内容有:源主机 IP 地址,源主机 MAC 地址,目的主机的 IP 地址。
-
当本网络的所有主机收到该ARP数据包时,首先检查数据包中的 IP 地址是否是自己的 IP 地址。如果不是,则忽略该数据包。如果是,则首先从数据包中取出源主机的 IP 和 MAC 地址写入到 ARP 列表中,如果已经存在,则覆盖,然后将自己的 MAC 地址写入 ARP 响应包中,告诉源主机自己是它想要找的 MAC 地址。
-
主机收到 ARP 响应包后。将目的主机的 IP 和 MAC 地址写入 ARP 列表,并利用此信息发送数据。
-
排序时间复杂度
-
冒泡排序
依次比较相邻元素的值,若发现逆序则交换 O ( n 2 ) O(n^2) O(n2)
import java.util.Arrays;
public class maopao {
public static void main(String[] args) {
int[] a = {21,1,3,2,4,-1,4};
int temp=0;
for (int i = 0; i <a.length -1; i++) {
for (int j = 0; j <a.length-1 ; j++) {
if (a[j]>a[j+1]){
temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
}
Arrays.stream(a).forEach(i -> System.out.print(i+" "));
}
}
- 快速排序
import java.util.Arrays;
public class quicksort {
public static void main(String[] args) {
int[] a={213,3,2,1,5,-1};
sort(a,0,a.length-1);
Arrays.stream(a).forEach(i -> System.out.print(i+" "));
}
public static void sort(int[] a,int left ,int right){
if (left>right){return;}
int i=left;
int j=right;
int key=a[i];
while (i<j){
while (i<j && a[j]>=key){
j--;
}
a[i]=a[j];
while (i<j && a[i]<=key){
i++;
}
a[j]=a[i];
}
a[i]=key;
sort(a,0,i-1);
sort(a,i+1,right);
}
}
- 关系型数据库非关系型数据库
非关系型 | 关系型 | |
---|---|---|
成本 | 部署简单,开源 | 大部分收费,尤其Oracle |
查询速度 | 快;将数据存储与缓存中,不需要SQL层解析 | 慢;将数据存储在硬盘中 |
数据存储格式 | 存储格式为key-value 形式,文档形式,图片形式。所以可以存储基础类型,对象,集合等 | 只支持基础类型 |
扩展性 | 基于键值对,数据之间没有耦合性,易于水平扩展 | 多表查询机制导致很难扩展 |
持久存储 | 不适用持久存储 | 适用于持久存储 |
数据一致性 | Nosql不提供对事务的处理 | 事务 |
- DNS解析过程
- 主机首先查询本地缓存是否有解析过域名对应对ip
- 主机没有解析过,递归查询本地域名服务器,若本地域名服务器高速缓存中有该域名对应对IP,则直接回传给用户
- 如果本地缓存和本地域名服务器的高速缓存中都不存在该域名对应都IP,那么:
- 递归查询:
主机向本地域名服务器递归查询,本地域名服务器向根域名服务器递归查询,根域名服务器前顶级域名服务器递归查询,顶级域名服务器向权限域名服务器递归查询,查询结果从之前路径传回给主机。
- 迭代查询
主机向本地域名服务器递归查询,本地域名服务器向根域名服务器迭代查询,根域名服务器回传给本地域名服务器顶级域名服务器的ip地址,本地域名服务器向顶级域名服务器迭代查询,顶级域名服务器回传给本地域名服务器权限域名服务器的ip地址,本地域名服务器向权限域名服务器迭代查询,权限域名服务器将查询结果告诉本地域名服务器,本地域名服务器把查询结果告诉主机
- Http请求方法
-
GET方法:对这个资源的查操作。
-
DELETE方法:对这个资源的删操作。但要注意:客户端无法保证删除操作一定会被执行,因为HTTP规范允许服务器在不通知客户端的情况下撤销请求。
-
HEAD方法:与GET方法的行为很类似,区别在于HEAD不含有呈现数据,而仅仅是HTTP头信息,使用HEAD,我们可以更高效的完成以下工作:
在不获取资源的情况下,了解资源的一些信息,比如资源类型;
通过查看响应中的状态码,可以确定资源是否存在;
通过查看首部,测试资源是否被修改; -
OPTIONS方法:用于获取当前URL所支持的方法。若请求成功,则它会在HTTP头中包含一个名为“Allow”的头,值是所支持的方法,如“GET, POST”。
put | post | |
---|---|---|
比较 | PUT通常指定了资源的存放位置。如果两个请求相同,后一个请求会把第一个请求覆盖掉。(所以PUT用来改资源) | POST的数据存放位置由服务器自己决定。后一个请求不会把第一个请求覆盖掉。(所以Post用来增资源) |
get | post | |
---|---|---|
用途 | 从服务器获取数据,?分割URL和传输数据,参数以&相连 | 向服务器发送数据,将提交的数据放在请求体 |
安全性 | 提交的内容可以显示在浏览器地址栏 | 请求数据放在请求体,相对安全 |
长度限制 | 一般不能超过2048字节,也与liu lan q | 无长度限制 |
幂等性(多次操作无副作用,或者副作用相同) | 幂等 | 无幂等性 |
参数数据类型 | ASCII字符 | 无限制 |
获取资源的速度 | faster | slower |
get比post快的原因:
- 最重要的一点:post在真正接收数据前会先将请求头发送给服务器进行确认,收到服务器回复100的确认码后,才开始发送正文;但是get会在第三次握手时就交付数据。
- 对于同一个资源请求多次时,get方法只有在第一次的时候和post时间相同,之后的话get方法会直接从缓存区中获取,而post方法必须再次发起完整请求。
- Java内存分配机制
-
https加密传输原理
-
集合
-
Hashtable与currentHashMap
Hashtable | currentHashMap | |
---|---|---|
线程安全 | 安全,修改数据的时候会锁住整个hash表,执行效率低,多线程中相当于串行 | 安全,将整个map划分成16个segment,对其中一个segment进行写操作时候会将本segment加锁,其他segment不受影响;读操作时候不加锁,会使用volatile关键字进行修饰,防止读到脏数据 |
- ArrayList与LinkedList
- 有序的ArrayList如何实现查找:数组下标查找
- 有序的LinkedList 如何实现查找:跳表,时间复杂的
O
(
l
o
g
(
n
)
)
O(log(n))
O(log(n))
- 垃圾回收
- 数据库
- 原子性(Atomicity)
原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚 - 一致性(Consistency)
一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态。 - 隔离性(Isolation)
多个并发事务之间要相互隔离。 - 持久性(Durability)
持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。
-
堆排序
-
树
-
网关
-
== 和 equal