后端知识图谱ByTans
2023-12-17 12:38:44 0 举报
AI智能生成
Java面试指南 还在更新中
作者其他创作
大纲/内容
语言
Java
IO
API
字节流
Reader
Writer
字符流
InputStream
OutputStream
IO模型
BIO(Blocking IO)
NIO(Non-Blocking IO)
IO多路复用
select
可以监控多个fd文件描述符,但是需要轮询,如果可以才会进行传输
每次调用select,都需要把被监控的fds集合从用户态空间拷贝到内核态空间,高并发场景下这样的拷贝会使得消耗的资源是很大的。
epoll
会有回调函数,设备就绪好之后就会加入到队列中,然后通知用户进程,
poll
AIO(NIO2)
JUC
锁
乐观锁 (CMS)
总是认为其他线程不会修改共享数据
缺点
ABA问题
CPU资源消耗
悲观锁 (Synchronize)
认为其他线程会修改数据,每一次操作都会上锁
作用范围
方法
类
代码块
synchronized优化
锁升级
无锁:无锁没有对资源进行锁定,所有的线程都能访问并修改同一个资源,但同时只有一个线程能修改成功。
偏向锁: 当一段同步代码被同一线程访问,那么那么该线程会自动获取锁,降低获取锁的代价。
轻量级锁:偏向锁的时候,被另外的线程所访问,就会升级为轻量级锁,其他线程会通过自旋的形式尝试获取锁,不会阻塞,从而提高性能。
重量级锁: 当等待线程自旋过长或者多个线程获取锁,发生锁膨胀,等待线程进入阻塞态
AQS
常用同步器
ReteentrantLock
Semaphore
互斥操作,3个车位,6辆汽车
CountDownLatch
允许一个或多个线程等待直到在其他线程中执行的一组操作完成的同步辅助
CyclicBarrier
允许一组线程全部等待彼此达到共同屏障点的同步辅助
构成
state
CLH
volatile
实现变量对所有线程的可见性
防止指令的重写排布(双重锁校验的单例模式)
happens-before法则
定义了两个动作的偏序关系
那么这两个操作就没有顺序的保障,JVM 可以对这两个操作进行重排序。
A happens before B表明A的操作对B可见
线程池
参数
CorePoolSize:核心线程数
MaximumPoolSize:总核心线程数
keepAliveTime:时间
当总核心线程数大于核心线程数的时候,定义核心之外线程最大存活时间
TimeUnit:单位
workQueue:队列
LinkedBlockingQueue
RejectedExecutionHandler:饱和策略
直接丢弃
抛出异常(默认)
用自己的线程去run这个方法
抛弃阻塞队列中的等待最久的任务
ThreadFactory : 线程工厂
作用:提供了线程池化的技术,同时也提供了线程的复用技术,可以减少线程创建和销毁所带来的资源上的消耗。
常用线程池
自定义线程池
逻辑
newFixedThreadPool
核心线程和最大线程都为n,其他的任务都放入到阻塞队列LinkedBlockingQueue
newSingleThreadExecutor
核心线程和最大线程都为1,阻塞队列是LinkedBlockingQueue,顺序执行
newCachedThreadPool
无核心线程,非核心线程数为MAX.VALUE。SynchronousQueue 同步队列不存储元素。60s过期时间
关闭线程池
shutdown():关闭还未执行的线程
shutdownNow():关闭所有线程
推荐配置(N为CPU个数)
IO密集型
2N
CPU密集型
N+1
JVM
运行时内存
程序计数器
作用:用来指向下一条JVM指令的地址
特点:
-是线程私有的
-不会存在内存溢出
-是线程私有的
-不会存在内存溢出
虚拟机栈
(JVM Stacks)
(JVM Stacks)
机栈:线程运行需要的内存空间,由栈帧组成,
栈帧:就对应着一次方法的调用的内存,包括参数、局部变量、返回地址等。
活动栈帧:正在运行的栈帧
栈帧:就对应着一次方法的调用的内存,包括参数、局部变量、返回地址等。
活动栈帧:正在运行的栈帧
方法内的局部变量是否线程安全?
如果方法内的局部变量没有逃离方法的作用范围,那么其就是线程安全的.
如果及局部变量引用了对象并且有逃离方法的范围,那么其就是不安全地
如果方法内的局部变量没有逃离方法的作用范围,那么其就是线程安全的.
如果及局部变量引用了对象并且有逃离方法的范围,那么其就是不安全地
栈内存溢出?
栈帧过多
StackOverflowError
栈帧过大
OutofMemory
本地方法栈 (线程私有)
堆
通过new关键字,创建对象都会使用堆内存
特点:
1.线程共享的,堆中对象都需要考虑线程安全问题
2.有垃圾回收机制
1.线程共享的,堆中对象都需要考虑线程安全问题
2.有垃圾回收机制
堆内存溢出
OutOfMemory: heap
方法区(1.7永生代1.8Metaspace)
存放和类有关的信息 类名 类方法
运行时常量池
就是一张表,根据这张常量表来找到要执行的类名、方法名、参数类型、字面量等信息
直接内存
常见于NIO的缓冲区
不受垃圾回收影响,是使用unsafe来管理直接内存的
垃圾回收
检测垃圾算法
引用技术
弊端:循环引用无法解决
通过被引用计数来判断
可达性分析算法
GC ROOT
虚拟机栈中引用的对象,如方法中的参数,局部变量等
方法区中类静态属性引用的对象
方法区中常量引用的对象
被同步锁(synchronized关键字)持有的对象
java虚拟机内部的引用,如基本数据类型对应的Class对象,一些常驻的异常对象,还有系统类加载器
以根对象作为起始节点集合,从根节点开始,根据引用关系向下搜索,
搜索过程所走过的路径称为引用链,如果某个对象到GC Roots间没有任何引用链相连
,该对象为不可达,将会被判定为可回收对象
搜索过程所走过的路径称为引用链,如果某个对象到GC Roots间没有任何引用链相连
,该对象为不可达,将会被判定为可回收对象
另外,即使被判定为不可达对象,那么需要 判断 是否有必要执行 finalize()方法
回收算法(搭配垃圾算法)
标记清除
速度较快,但是会造成内存碎片
标记整理
不会产生碎片,比较耗性能
标记复制
将内存区域划分成大小相同两段区域,将不是垃圾的内存放入空闲内存
分代回收思想
老年代:标记清除/标记整理
新生代:标记复制
一个伊甸园区
两个幸存区
垃圾回收器
Serial 串行收集器
新生代:标记复制 老生代:标记整理
串行
通常用在客户端,简单高效
吞吐量优先 ParallelGC
新生代:标记复制 老生代:标记整理
默认优先,旨在增加发运行代码时间/(代码运行时间+垃圾收集时间)
-XX:+UseParallelGC -XX:+UseParallelOldGC
-XX:+UseAdaptiveSizePolicy : 动态调整伊利园的大小
-XX:+UseAdaptiveSizePolicy : 动态调整伊利园的大小
JDK8
Parallel Old
Parallel Scavenge
并发收集,低停顿 CMS
标记清除算法
浮动垃圾可能回产生FullGC, 并且会产生碎片
G1(9 之后默认启用)
标记整理+复制
回收步骤
整体上是标记+整理算法,两个区域之间是复制算法
超大堆,堆分为多个区域
超大堆,堆分为多个区域
缺点
每个region都需要使用卡表来标记老年代到新生代的引用
内存占用 以及 执行负载比较高
优点
分region来回收
可以指定最大停顿时间
按利益动态回收
不会产生内存碎片
既能大概率满足GC停顿时间,也具备高吞吐量性能特征
触发条件
老年代
老年代没有足够空间存放对象
老年代的所剩空间小于历次YoungGC平均对象晋升大小
System.gc()
新生代
当JVM不能为一个新对象分配空间时 Eden区满
类加载机制
加载步骤
加载
类加载器
启动类加载器
扩展类加载器
应用程序类加载器
自定义类加载器
双亲委派模型
如果一个类收到了类加载的请求,那么它首先不会尝试去加载这个类,
而是把这个请求委派给父类加载器去完成,只有上级加载器反馈无法完成这个加载请求的时候,
子加载器才会尝试自己去加载。
而是把这个请求委派给父类加载器去完成,只有上级加载器反馈无法完成这个加载请求的时候,
子加载器才会尝试自己去加载。
打破双亲委派模型
加载步骤
1.通过全类名获取定义此类的二进制字节流
2.将字节流所代表的静态存储结构转换为方法区的运行时数据结构
3.在内存中生成一个代表该类的 Class 对象,作为方法区这些数据的访问入口
2.将字节流所代表的静态存储结构转换为方法区的运行时数据结构
3.在内存中生成一个代表该类的 Class 对象,作为方法区这些数据的访问入口
连接(验证->准备->解析)
如果static变量是final的基本类型,以及字符串常量,那么编译阶段值就确定了,赋值在准备阶段完成
如果static变量是final的,但是属于引用类型,那么赋值也会在初始化阶段完成。
解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程。
准备阶段是正式为类变量分配内存并设置类变量初始值的阶段,这些内存都将在方法区中分配。
初始化
执行<clinit>方法
加载时机
当new,getstatic,putstatic,invokestaticMethod的时候
反射, forname, newInstance
主类
初始化子类,父类未初始化
何为对象
对象结构
对象头
Markword 包括类对象hash码,对象的GC年龄,锁信息
指向类元数据的指针
数组长度
实例数据
实例数据部分是对象真正存储的有效信息,也是在程序中所定义的各种类型的字段内容。
对齐填充
对象的创建流程
类加载
检查所对应的类是否已经完成类加载操作,也就是加载连接以及初始化
分配内存
在类加载检查通过后,接下来虚拟机将为新生对象分配内存。对象所需的内存大小在类加载完成后便可确定。
分配方法
碰撞指针 适用于内存规整的情况下
适用于内容比较规整的情况,维护一个分界指针,然后一遍是已经占有的,一遍是未占的,分配内存,只要移动指针即可
适用于内容比较规整的情况,维护一个分界指针,然后一遍是已经占有的,一遍是未占的,分配内存,只要移动指针即可
空闲链表 适用于内存不规整的情况下
维护一张空闲内存区域的表,可能造成内容不规整
维护一张空闲内存区域的表,可能造成内容不规整
分配并发问题
采用CAS+失败重试:乐观的去等待可用内存
TLAB方法,当线程创立之后,给线程在新生代分配一块内存,当待分配内存大于TLAB内存或者TLAB内用尽的时候,会采用CAS
赋零值
内存分配完成后,虚拟机需要将分配到的内存空间都初始化为零值(不包括对象头),这一步操作保证了对象的实例字段在 Java 代码中可以不赋初始值就直接使用,程序能访问到这些字段的数据类型所对应的零值
设置对象头
初始化零值完成之后,虚拟机要对对象进行必要的设置,例如这个对象是哪个类的实例、如何才能找到类的元数据信息、对象的哈希码、对象的 GC 分代年龄等信息。 这些信息存放在对象头中。 另外,根据虚拟机当前运行状态的不同,如是否启用偏向锁等,对象头会有不同的设置方式。
执行init操作
通过程序自定义的方式来对对象做进一步初始化
对象定位方法
句柄地址
句柄包含指向类元数据(方法区)的指和指向实例数据的指针(堆)
优点 :当实例数据移动时候,只需要修改句柄中中的地址即可
优点 :当实例数据移动时候,只需要修改句柄中中的地址即可
直接指针
直接指向实例数据,其中实例数据包括类元数据
优点:一次定位
缺点:修改需要修改引用
优点:一次定位
缺点:修改需要修改引用
虚拟机相关参数
-Xss 1m 栈空间内存空间设置参数
-Xmx 1024K 堆空间最大
-Xms 1m/k 堆空间最小
-Xms 1m/k 堆空间最小
-XX:NewSize=256m //指定新生代何最大新生代内存的大小
-XX:MaxNewSize=1024m
-XX:MetaspaceSize=N //设置 Metaspace 的初始(和最小大小)
-XX:MaxMetaspaceSize=N
-XX +UseCMS
-XX +UseG1GC
-XX:MaxNewSize=1024m
-XX:MetaspaceSize=N //设置 Metaspace 的初始(和最小大小)
-XX:MaxMetaspaceSize=N
-XX +UseCMS
-XX +UseG1GC
晋升阈值
XX:MaxTenuringThreshold
动态对象年龄判断
JVM调优工具
jps
jstack
jmap
jstat
JMM
主内存
本地内存
集合
Collections接口
Set
HashSet(数组+链表\红黑树)
LinkedHashSet
TreeSet(红黑树)
List
ArrayList
基于数组的,然后扩容是1.5倍左右,n=n+n>>1,
适合快速随机读取,不适合频繁修改,线程不安全,
内存占用主要体现在空余的数组长度
适合快速随机读取,不适合频繁修改,线程不安全,
内存占用主要体现在空余的数组长度
默认初始长度:10
构造器
无参构造器,默认是10
带大小的构造器,大小是参数
带有Collection集合的构造器
LinkedList
Queue
Map接口
HashTable
初始长度:11(可自定义)
扩容大小 : 2n + 1
线程安全的 synchronized修饰
扩容大小 : 2n + 1
线程安全的 synchronized修饰
HashMap(线程不安全的Map)
初始长度:1<<4
最大容量: 1<<30
负载因子:0.75
树形阈值:8
转换为树形最小数组长度:64
最大容量: 1<<30
负载因子:0.75
树形阈值:8
转换为树形最小数组长度:64
1.7采用数组+链表的 头插法, 容易出现环状数组
1.8采用数组+链表/红黑树 尾插法,容易数据覆盖
1.8采用数组+链表/红黑树 尾插法,容易数据覆盖
扩容
超过上限不会扩容,不超过上限扩两倍
每次扩容要不不移动要不移动2的幂次方
hash扰动
CocurrentHashMap(线程安全的Map)
JDK 1.7 segment数组 + 数组 +链表实现
JDK 1.8 Node数组 + 链表/红黑树实现
JDK 1.8 Node数组 + 链表/红黑树实现
JDK1.8 只锁头节点降低了锁粒度
TreeMap
实现sortedMap拥有排序功能
实现NavigableMap拥有集合元素搜索功能
基础
final
修饰类:此类不可被继承
修饰方法:此方法不可被重写
修饰变量:引用变量不能指向其他对象,普通常量不能修改值
访问修饰符
public
所有类可见 修饰 类 方法 变量 接口
default
同包下类可见,修饰方法 类 变量 接口
protected
本类及其子类可见,修饰方法 变量 不可修饰类和接口
private
本类可见,修饰方法 变量 不可修饰类和接口
深拷贝和浅拷贝
基本数据类型拷贝,引用类型不拷贝(和原对象中的引用变量指向同一堆地址)
待对象对象的引用成员变量也拷贝
字符串
String
不可变
intern方法
StringBuffer
StringBuilder
异常错误 Throwable类
Error
Exceptioin
UncheckException
RuntimeException
CheckException
反射
动态代理
cglib
通过生成子类方法实现代理
只能代理非final修饰方法
速度更快,编译时生成
基于jdk
只能代理实现接口的类
方法
class.forName
.class
getClass()
注解
元注解
@Target :用来指定注解作用域 方法、参数 或者类
@Retention: 用来指定注解的生命周期
RetentionPolicy.SOURCE:源代码级别保留。在编译后的字节码中不保留注解信息,仅在源代码中可见。
RetentionPolicy.CLASS:类级别保留。在编译后的字节码中保留注解信息,但在运行时不可访问。
RetentionPolicy.RUNTIME:运行时级别保留。在编译后的字节码中保留注解信息,并可以在运行时通过反射机制访问。
Golang
GMP模型
G:协程
M: OS线程
P:逻辑处理器
切片
扩容
框架
Spring
bean的作用域
bean生命周期
实例化
属性赋零值(依赖注入)
构造函数
使用最后销毁
循环依赖问题
两大特性
IOC:IoC 的思想就是将原本在程序中手动创建对象的控制权,交由 Spring 框架来管理。
AOP:AOP(Aspect-Oriented Programming:面向切面编程)能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)抽离出来,并进行模块化管理 便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可拓展性和可维护性。
Spring事务
@Transactional
失效
数据库不支持事务
没有加入spring管理
方法不是public
异常类型错误
抛出异常错误
相关注解
SpringBootApplication
Spring MVC
核心组件
DispatcherServlet
HandlerMapping
HandlerAdapter
Handler
ViewResolver
Go-zero
Netty
Nio基础
Buffer Channel
属性
limit
capacity
position
Selector
处理消息边界
固定消息长度,浪费带宽
分隔符拆分,效率低
TLV格式
IO模型
同步阻塞
同步非阻塞
异步非阻塞
同步多路复用
信号驱动
组件
EventLoop
分布式(待完善)
分布式锁
RedLock
数据库唯一索引
分布式ID
数据库主键自增
号段式 Leaf算法
雪花算法
1bit无用
41bit表示时间戳
10bit用来表示机房ID+服务器ID
12bit用来表示生成ID的序列号,从0递增
41bit表示时间戳
10bit用来表示机房ID+服务器ID
12bit用来表示生成ID的序列号,从0递增
分布式事务
柔性事务
TCC
Try:尝试执行,检查并预留资源
Comfirm:所有事务参与者try都完成,会执行预留的资源,否则执行cancel阶段
Cancel:释放预留的资源
Saga
将一个长事务拆分成多个短事务,且每个短事务都有对应的补偿事务来进行恢复处理
刚性事务
3PC
CanCommit
Precommit
DoCommit
理论
BASE
BA 基本可用性 当系统出现故障时,允许失去部分可用性 但绝不是整个系统不可能
S 软状态 允许系统中数据存在中间状态,也就是容忍数据同步带来的延时
E 最终一致性 要求系统在一个时间段后,经过同步,都达到数据一致的状态
CAP
C:一致性 所有节点的返回的是最新的数据
A:可用性 部分可用节点必须能在合理的时间返回合理的数据(而不是空数据或者错误)
P:分区容错性 网络出现分区的时候,仍然能够对外提供服务
分布式和微服务的区别
分布式是物理部署层面的,将一个服务部署到多台机器
微服务说的是设计架构层面的
PACELC
分布式组件
序列化
PB
注册中心
ETCD
安全
限流
漏桶算法
令牌桶算法(guava实现)
滑动窗口
计数器
鉴权
JWT
Header
token类型
加密算法名称
Payload
base64(自定义信息)
Signature
HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
分布式Session
oauth2.0
refresh_token
access_token
降级
通过牺牲部分功能,保证核心业务 双十一
熔断
特殊的降级,防止上游业务出错导致系统链路雪崩
分布式算法
paxos
raft
三个状态
领导者
候选者
跟随者
一致性hash
hash环, 顺时针
节点增添时,尽量减少数据迁移
节点增添时,各个节点数据尽量均衡
运维(待完善)
Docker
K8s
压测工具
Jmeter
Git
保存暂存区 git stash
项目
投票系统
接口保护
返回验证码
令牌桶
黑用户
短视频项目
音视频传输
安全问题
RPC项目
性能
社团招新考核系统
秒杀系统
风控系统
密码为什么加盐?
浏览器指纹信息
UserAgent
操作系统
时区
积分系统
计算机网络
运输层
TCP可靠传输
ARQ(自动重传机制)
停止等待ARQ协议
特点:简单 但是信道利用率比较低
几种情况
无差错情况
超时重传情况
确认丢失和确认迟到
每发完一个分组之后就停止发送,等待对方的确认。
连续ARQ协议
滑动窗口和流量控制
发送窗口 = min(rwnd, cwnd)
ssthresh (门限值)
cwnd > ssthresh 拥塞避免算法
cwnd <= ssthresh 慢开始算法
特殊情况
超时重传
ssthresh = cwnd / 2
cwnd = 1
执行慢开始
cwnd = 1
执行慢开始
重复报文
ssthresh = cwnd / 2
cwnd = cwnd / 2
执行拥塞避免算法
cwnd = cwnd / 2
执行拥塞避免算法
拥塞控制
慢开始
cwnd=cwnd*2
拥塞避免
cwnd=cwnd+1
快重传
当发送方连续收到3个连续的重复确认,无需等待超时定时器溢出,直接重传丢失的报文段
快恢复
快速重传执行的不是慢开始算法而是拥塞避免
UDP可靠传输
Quick UDP Internet Connection (QUIC)
自定义连接机制
解决队头阻塞
自定义流量控制
改进的拥塞控制
QUIC优点
解决了队头阻塞 一个QUIC连接承载多个TCP的stream流
更好的连接方式 只需要1RTT就可以实现TCP中的握手连接
连接迁移 切换网络不变,不会产生影响,不使用五元组而是64位连接id
QUIC在应用层之上基于UDP实现丢包恢复,拥塞控制,加解密,多路复用等功能,既能优化握手延迟,同时又完全解决内核协议更新滞后问题。
区别
1.是否面向连接
2.是否可靠
3.传输形式
4.传输效率
5.消耗资源
6.应用场景
7.首部字节
8.报文格式
三挥四握
挥手
为什么挥手四次
全双工模式
注意几个时期
TIME_WAIT 2MSL时期
CLOSE_WAIT
三次握手的Seq、ACK、SYN标识位
传输问题
SYN泛洪攻击
客户端给服务端发送SYN,但是被连接方所发送的SYN+ACK报文永远到达不了,那么这个时候连接方会进行重连
抵御攻击:缩短半连接的等待时间,丢弃此IP报文
中间人攻击
RIP攻击
拆包粘包
只发生在TCP协议中,因为UDP有消息保护边界,也就是只接收一个报文
包太大被分割,包太小被缓冲 TCP是字节流
解决
使用定界符
固定包大小,不够进行填充
把消息分为头部和消息体,保存消息长度,读取一定数量不再接收
HTTP
HTTP报文格式
起始行
请求方法 空格 URL 空格 版本号 回车
请求头部
空行
数据
HTTP1.0和HTTP1.1改进
1.0默认采用短链接,每进行一次操作,都会进行一次TCP连接,也就是握手报文和挥手报文占用了宽带
1.1默认采用了长连接,也就是打开一个网页完成TCP连接后,用于传输HTTP数据的连接不会中断,客户端再次访问这个服务器的时候,会继续使用这条连接。可以支持超时时间的修改。
相关参数:Connection: Keep-alive \ close
1.1默认采用了长连接,也就是打开一个网页完成TCP连接后,用于传输HTTP数据的连接不会中断,客户端再次访问这个服务器的时候,会继续使用这条连接。可以支持超时时间的修改。
相关参数:Connection: Keep-alive \ close
请求头的处理:
1.0的时候请求头的请求资源不会加入主机名,这样的报文到达服务端,服务器理解不了请求的真正网址
1.0的时候请求头的请求资源不会加入主机名,这样的报文到达服务端,服务器理解不了请求的真正网址
1.1增加了新的状态码,
100:代表该大资源请示请求是否会被相应
410:资源已经被永久转移
100:代表该大资源请示请求是否会被相应
410:资源已经被永久转移
压缩:
1.1将内容编码和传输编码做了区分,内容编码总是端到端的,传输编码是逐跳的
1.1将内容编码和传输编码做了区分,内容编码总是端到端的,传输编码是逐跳的
url到网页渲染圆面
DNS解析 (DNS协议)
发送HTTP协议请求,三次握手,传输数据(HTTP、TCP、IP、ARP、OSPF(开放式最短路径优先))
解析html数据,构建DOM数,渲染
常用状态码
1XX: 表示信息,服务器要求客户端进行后续操作
2XX:表示成功 200OK,201Created
3XX: 301永久重定向,302暂时重定向 304访问缓存资源(最后修改时间)
4XX:客户端错误,401未验证,404:请求资源找不到
5XX:服务端错误,500内部错误,502Bad GateWay
2XX:表示成功 200OK,201Created
3XX: 301永久重定向,302暂时重定向 304访问缓存资源(最后修改时间)
4XX:客户端错误,401未验证,404:请求资源找不到
5XX:服务端错误,500内部错误,502Bad GateWay
请求方法
Get
Post
HTTP/3.0 和 HTTP/2.0区别
不再基于TCP、而是基于UDP(QUIC)
HTTP/1.1和HTTP/2.0区别
多路复用
二进制帧
头部压缩
服务器推送
HTTPS
和HTTP区别
443 80
https:// http://
加密传输
需不需要向CA申请证书
OS
进程通信
管道模型
有名管道
匿名管道
消息队列
消息队列是存放在内核中的消息链表,每个消息队列由消息队列标识符表示。
经常用来处理消费者和生产者模型
共享内存(share memory) + 信号量
减少不必要的拷贝之类的,但是会出现进程不安全的情况。所以要搭配信号量。同一个共享资源在同一时间只能呗一个访问
信号
SIGINT:程序终止信号,程序运行过程中, Ctrl+C键将产生该型号
SIGNQUIR:程序退出信号,Ctrl+\\键产生该信号
Socket
进程和线程
进程是资源调配的最小单位,而线程是CPU执行的最小单位
一个进程可能包括多个线程,而一个线程只能属于一个进程
多个进程会有独立的内存空间,但是多个线程会共享同一进程的内存单元
进程切换的开销会比较大,而线程切换的开销会比较小。
协程
线程的切换由操作系统(内核态)来执行,而协程的切换是由程序完成,是在用户态完成的
线程阻塞的时候,可以调用其协程
进程是程序的一次动态运行过程,是一个动态的概念
IO密集:多线程 CPU密集:多进程
进程调度算法
FCFS
SJF
RR
多级反馈调度算法
linux调度算法CFS
通过红黑树和虚拟运行时间来进行进程调度
死锁
条件
互斥
请求和保持
不可剥夺
循环等待
解决
预防
避免
检测
内存管理分配方式
连续分配管理方式
块式
非连续分配管理方式
段式
页式
虚拟地址 = 虚拟页号 + 页内偏移
物理地址 = f(虚拟页号) + 页内偏移
页表保存这虚拟页号到物理页号的映射关系
物理地址 = f(虚拟页号) + 页内偏移
页表保存这虚拟页号到物理页号的映射关系
页面置换算法
LRU
LFU
RR
OPT
FIFO
段页式
IO
IO调度算法
CFQ 为一个进程分配一个请求队列和一个时间片
NOOP: 将IO请求放入一个FIFO请求队列中,然后逐个执行
DeadLine : 保证每个IO请求在一段时间内能被服务到,以此来避免某个请求饥饿
线程通信
共享内存
消息传递
数据库
Mysql
索引
概念:索引其实是一种数据结构,能够帮助我们快速的检索数据库中的数据。
优缺点
优点:
1.增加数据检索速度(主要原因)
2.保证唯一性
1.增加数据检索速度(主要原因)
2.保证唯一性
缺点:
1. 创建索引和维护索引需要耗费许多时间,随着数据的修改,
索引也需要进一步修改。降低SQL执行效率。
2.耗费内存空间
1. 创建索引和维护索引需要耗费许多时间,随着数据的修改,
索引也需要进一步修改。降低SQL执行效率。
2.耗费内存空间
底层数据结构
Hash表
冲突问题:不同key可能映射成不同的index
不支持顺序和范围查询(最大缺点):如果我们需要进行排序或者范围查询,那么Hash索引就不可取了。接近O(n)
B+树(多路平衡查找树)
B树和B+树的区别
B树的所有结点既存放key又存放data, 而B+树只有叶子节点存放key,data,而其他节点只存放key
B树的叶子节点是孤立的,但是B+树的叶子节点有一条引用链指向它相邻的叶子节点
B树的检索过程相当于范围内的每个节点的关键字做二分查找,
可能还没到达叶子节点,检索就结束了,而B+树的检索效率就比较稳定,任何查找都是从根节点到叶子节点的过程。
可能还没到达叶子节点,检索就结束了,而B+树的检索效率就比较稳定,任何查找都是从根节点到叶子节点的过程。
目前大部分文件系统都是使用B-Tree和B+Tree及其变种。这也是MyISAM引擎和InnoDB引擎所使用B+Tree作为索引结构。
MyISAM和Innodb的区别
MyISAM的叶子节点存放的是数据的物理地址,即索引结构和真正的数据结构是单独存放的
Innodb的聚集索引(主键索引)中,所有数据是保存在主键索引中的。
前者无事务,后者又事务
前者只支持行锁,后者支持表锁和行锁
B+树相对于B树的优点
1.范围查询时可以通过访问叶子节点的链表进行有序遍历,而不再需要中序回溯访问结点。
2.非叶子结点只存储关键字key,一方面这种结构相当于划分出了更多的范围,加快了查询速度,另一方面相当于单个索引值大小变小,同一个页可以存储更多的关键字,读取单个页就可以得到更多的关键字,可检索的范围变大了,相对IO读写次数就降低了。
索引类型
物理存储分类
主键索引(聚集索引)
Clustered Index
索引结构和数据一起存放的索引
叶子节点就是整行的数据
非叶子节点存放的是键值和指向数据页的偏移量
Clustered Index
索引结构和数据一起存放的索引
叶子节点就是整行的数据
非叶子节点存放的是键值和指向数据页的偏移量
数据表的主键列使用的是主键索引
优缺点
优点:对排序查找和范围查找的速度特别快
缺点:1. 依赖有序的数据,非有序的数据插入的时候需要重新排序 2.更新代价大。
二级索引(辅助索引、非聚集索引)
Secondary Index :
即索引结构和数据分开存放的索引
叶子节点:书签+key
Secondary Index :
即索引结构和数据分开存放的索引
叶子节点:书签+key
分类
唯一索引:属性列不能存在重复数据,允许NULL,通常是为了确保数据的唯一性。
普通索引:加速查询速度,允许重复数据和NULL
前缀索引:适用于字符串类型的数据,前缀索引是对文本的前几个字符建立索引。
全文索引:为了检索大文本数据中的关键字信息,是目前搜索引擎数据库使用的一种技术。
优缺点
优点:更新代价比聚集索引更新代价小
缺点:1. 以来有序的数据 2. 可能会二次查询
数据结构分类
B+树索引
Hash索引
Full-Text索引
在辅助表存储了单词和单词本身在一个文档中所在位置之间的映射。
字段个数
单列索引
聚合索引
索引特性
覆盖索引(covering index)
概念:从辅助索引能查询到的数据,那么就不需要去查询聚集索引中的记录
优点:不包含整行记录,所以减小大量IO
联合索引
概念:对表上的多个列进行索引
过程:假设有对a,b两个字段进行索引,那么key就是(a,b), 然后对二元组排序。注意当单独查询b列的时候不能使用联合查询
最左前缀匹配原则:where子句中使用最频繁的一列放在最左边,因为MySQL索引查询会遵循最左前缀匹配的原则,即最左优先,在检索数据时从联合索引的最左边开始匹配。
索引下推
操作语句
主键索引
ALTER TABLE `table_name` ADD PRIMARY KEY ( `column` )
唯一索引
ALTER TABLE `table_name` ADD UNIQUE ( `column` )
普通索引
ALTER TABLE `table_name` ADD INDEX index_name ( `column` )
全文索引
ALTER TABLE `table_name` ADD FULLTEXT ( `column`)
多列索引
ALTER TABLE `table_name` ADD INDEX index_name ( `column1`, `column2`, `column3` )
相关问题
什么情况下会发生明明创建了索引,但是执行的时候并没有通过索引呢?
通配符%在左边
字符串无单引号
违反最左原则
当通过二级索引来进行查询相关主键的时候,如果回表查询就变成了离散读,但是顺序读远远快于离散读(如果是固态硬盘还好,但是传统磁盘受限于这个条件) 顺序读 > 离散读
事务
ACID
Atomicity 原子性
事务是最小的执行单位,要么全部执行,要么全不执行
Consistency:一致性
执行事务前后,应该保持数据的一致
Isolation:隔离性
并发访问数据库的时候,一个用户的事务不会被另一个事务所影响,各并发事务是独立的
Durability:持久性
一个事务提交之后,数据的改变是持久的,即使停机了也不会对其产生影响
实现原理
通过 redo 日志来实现持久性
通过 undo 日志来实现原子性
通过 MVCC、锁 来实现隔离性
实现持久性、原子性、隔离性之后,一致性才得到保证
并发事务影响
修改丢失 : 原来A数为20, 第一事务运行A--, 第二事务运行A--, 结果为19, 第一事务修改丢失
脏读 : 一个事务读到了另一个事务未提交的脏数据
不可重复读 : 一个事务重复读取一个数据,事务结束之前,另一个事务修改了这个数据,导致第一个事务前后读取的数据不一致
幻读 : T1事务读取几行后,T2事务插入或者删除几行数据。T1就会读到之前不存在的行数据
隔离级别
RU级别(未提交读):不加锁,可以读未提交的数据
RC级别(提交读):可以读已经提交的数据
RR级别(可重复读):在同一个事务内的查询都是事务开始时刻一致的(默认级别)
Serializable(可串行读): 完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞
设置操作:tranction isolation
MVCC
依赖
隐藏部分
DB_TRX_ID:表示最后一次更新的事务ID
DB_ROLL_PTR:指向该行的undoLog的指针
DB_ROW_ID
ReadView
m_ids存放当前对于本行数据的活跃数据
如果被访问trx_id小于m_ids最小值,那么此版本对此事务时可见的
如果被访问trx_id大于m_ids最大值,那么此版本对此事务是不可见的
如果被访问trx_id大于最小值小于最大值,就会二分判断是否存在这个活跃集合里面
如果被访问trx_id大于m_ids最大值,那么此版本对此事务是不可见的
如果被访问trx_id大于最小值小于最大值,就会二分判断是否存在这个活跃集合里面
Undolog
作用
用于当前的事务的回滚操作
另一个作用是 MVCC ,当读取记录时,若该记录被其他事务占用或当前版本对该事务不可见,则可以通过 undo log 读取之前的版本数据,以此实现非锁定读
种类
insert undo : 由于只对本事务可见,所以事务提交后可以删除,
update:由于可以用作MVCC版本控制,所以事务提交后放入log链表。等待删除后台purge线程删除。
通过为数据行添加隐藏字段、ReadView和undolog来实现版本控制,具体来说,通过DB_TRX_ID和ReadView来判断记录可见性,如果不可见,那么就会去沿DB_ROLL_PTR去寻找,直到找到第一个满足条件的记录
锁
按照粒度
表锁
意向共享锁 IS
意向排他锁 IX
行锁
共享锁 S
排他锁 X
间隙锁(Gap)
按照读写来分
共享锁(读锁):一个事务给某行数据加了读锁,那么其他事务可以读,但是不能写
排他锁(写锁):一个事务给某行数据加了写锁,其他事务不能读,也不能写
按照锁思想
悲观锁
乐观锁
日志
RedoLog
重做日志,提供了崩溃恢复的机制,物理日志,Inndb引擎自带。
刷盘时机(innodb_flush_log_at_trx_commit)
0:不进行刷盘,由后台进程1s一次来进行刷盘, 会造成1s的数都丢失
1:每次事务提交都会进行刷盘(默认)
2:设置为 2 的时候,表示每次事务提交时都只把 redo log buffer 内容写入 page cache(会造成1s数据丢失)
两部分
redo log buffer
redo log file
checkpoint技术
写入时机
在事务执行过程中不断写入
Binlog
提供了不同数据库之间同步,逻辑日志,在server层工作
记录格式(binlog_format)
Mixed:对于一般的用Statement,对于不可预知的变量或者函数用Row
Statement: 记录的是原SQL语句
Row:记录的是数据,对于一些函数比如说date()比较适用
写入时机
一次写入,先把数据写入到binlog cache中,然后最后进行一次刷盘操作,一个事务的binlog不能被拆开。
参数sync_binlog
0:每次write,由系统决定什么时候去fsync
1:每次事务提交都进行一次刷盘操作
N: N>1,n个事务进行刷盘一次
UndoLog(在MVCC已经说明)
优化
优化方向
1. 查看是否走了索引
通配符在左边
不服从最左原则
使用 or 但是有一个没走索引
2. 是否数据太多
3.是否走的是最优索引
4.查看所查的字段是否是必须的,是否查出了多余的数据 避免使用 select * (必要时可以引用索引覆盖 和 索引下推优化)
5.慢查询会导致CPU,IOPS,内存消耗过高
尽量去扩展索引而不是去新建索引
单表最大行数:500万
优化流程
slow_query_log : 打开慢查询日志
用 explain 进行查询
底层
InnoDB中的页结构
File header
Page header
Record
行格式
Compact
变长字段长度列表
NULL值列表
记录头信息
隐藏列
Redundant
Dynamic
Compressed
行溢出现象
Free Space
Page Dir
File Trailer
单表访问方法
ref
根据二级索引与一个常数进行等值比较
ref or null
在ref的基础上,把该列值为NULL的记录也找出来
const
根据主键或唯一索引列直接与一个常数比较
all
全表扫描
index
只扫描索引而不扫描数据,称为index访问
range
根据索引列的范围进行查询,称为range访问
查询优化器
单表查询成本
IO成本(从磁盘加载到内存所损耗的时间)成本常数:1
CPU成本(读取以及检测记录是否满足对应的搜索条件,排序等一些操作所损耗的时间)成本常数:0.2
优化步骤
根据搜索条件,找出所有可能使用到的索引
计算全表扫描的代价
计算使用不同索引执行查询的代价
对比各种执行方案的代价,找出成本最低的那一个
MongoDB(待整理)
基本概念
三范式
每一张表都包含一个主键,每一个字段不可再分
非主键字段完全依赖主键,不产生部分依赖, 也就是说主属性的部分字段就可以确定非主属性
在2NF的基础上解决传递依赖问题,这是为了冗余性的考究,但是工程中为了性能上提升,也可以打破这一范式
中间件
Redis
数据类型(5+3)
string
使用场景:由于key可以是数字,所以也适合一些计数类的实现
底层编码
sds
int
embstr
set
使用场景:可以实现去重,比如说可以实现求两个人的共同喜好之类的
底层编码
intset
hashtable
list
使用场景:做简单的消息队列
底层编码
linkedlist(3.2之前)
ziplist
quicklist(3.2之后)
hash
底层编码
hashtable
ziplist
sorted set(Zset)
ZADD KEY_NAME SCORE1 VALUE1.. SCOREN VALUEN
使用场景:可以用作topN,也可以用作分页。
TOPN操作:https://duyanghao.github.io/redis-rank/
底层编码
ziplist
skiplist
bitmap
存储的是连续的0和1,可以节省存储空间。
使用场景:适合需要保存状态信息,比如用户签到、活跃用户统计,用户行为统计。
setbit getibit count bitop
Hyperloglogs
基数排序 统计uv
Geo
地理信息
底层数据结构
简单动态字符串(sds)
O(1)查询长度
动态分配
如果对SDS进行修改之后,SDS的长度将小于1MB,那么程序分配和len属性同样大小的未使用空间。
如果对SDS进行修改之后,SDS的长度将大于等于1MB,那么程序会分配1MB的未使用空间。
如果对SDS进行修改之后,SDS的长度将大于等于1MB,那么程序会分配1MB的未使用空间。
惰性回收
列表
字典
整数集合
跳跃表(skiplist)
https://segmentfault.com/a/1190000006580930
是从有序链表中选取部分节点,作为二级索引,以此类推形成多级索引。
压缩列表(ziplist)
快速列表
过期策略和内存淘汰机制
过期策略
定期删除策略
惰性删除策略
定期删除策略+惰性删除策略
定时删除策略
内存淘汰策略
默认:no-eviction:静止驱逐数据
allkeys(从所有的)
lru : 从全部数据中挑选最近最少使用的
random:任意选择数据进行淘汰
lfu :移除最近最不经常使用的
volatile(从设置了过期时间的)
lru
random
lfu: 移除最近最不经常使用的
ttl : 从已设置过期时间的数据集选择即将过期的
持久化
RDB(snapshotting)默认的
通过创建快照来获得存储在内存里面的数据在某个时间点上的副本, 二进制数据
触发条件
redis.conf中配置save m n,即在m秒内有n次修改时,自动触发bgsave生成rdb文件; 主从复制时,从节点要从主节点进行全量复制时也会触发bgsave操作,生成当时的快照发送到从节点; 执行debug reload命令重新加载redis时也会触发bgsave操作; 默认情况下执行shutdown命令时,如果没有开启aof持久化,那么也会触发bgsave操作;
命令:save bgsave
优点
备份文件较小,适合灾后重建
恢复速度快
缺点
可读性差
实时性不高
AOF(append-only file)
每执行一条语句,那么Redis 就会将该命令写入到内存缓存,随后写入aof文件
持久化方式配置 appendfsync
always:AOF缓冲区全部写入到AOF文件并且同步到磁盘
everysecond: AOF缓冲区写入AOF文件,检查是否距离上次同步是否超过1s,如果是...
no : 只写入,同步由系统决定
配置命令
主动重写
BGREWRITEAOF:fork子进程重写
REWRITEAOF:阻塞执行重写
被动重写
// 当前AOF文件比上次重写后的AOF文件大小的增长比例超过100
auto-aof-rewrite-percentage 100
// 当前AOF文件的文件大小大于64MB
auto-aof-rewrite-min-size 64mb
auto-aof-rewrite-percentage 100
// 当前AOF文件的文件大小大于64MB
auto-aof-rewrite-min-size 64mb
三个步骤
命令追加
文件写入
文件同步
缺点
持久化文件较大,需要搭配AOF重写
数据还原恢复较慢
优点
可读性好
实时性高
可以做误删除之后的紧急恢复
RDB+AOF混合持久化(Redis4.0)
只发生在重写阶段,直接将rdb数据写入aof头部
aof-use-rdb-preamble no
多机
主从复制
主服务器负责写,从服务器负责读
具体步骤
同步
命令传播
处理断线机制的两种命令
SYNC 旧版复制
完全重同步
PSYNC 新版复制
完全重同步
部分重同步
实现原理
复制偏移量(主从服务器都要)
复制积压缓冲区
服务器运行id
心跳检测
Sentinel(哨兵)
主观下线
每秒一次频率发送给主从节点发送ping节点,并通过实例的pong命令判断是否在线
客观下线
故障转移
筛选新master指标
优先级(管理员配置)
复制进度
runid(运行id)
谁来完成转移操作选择哨兵Leader(Raft算法)
Cluster(集群)
维护cluster Node来实现
客户端向节点发送命令,判断是否在槽中,如果在那么就直接插入,如果不在那么就直接moved,客户端通过moved去相应的slot进行插入
重新分片
ASK错误
故障转移
转移
选取新的主节点
哈希槽
数量:16384个
为什么不使用一致性hash
在集群里面执行命令
1. 计算应该在哪个槽 crc16(key) & 163832
2. 判断是否是当前节点维护的槽
3. 如果是那就处理,否则返回moved信息
2. 判断是否是当前节点维护的槽
3. 如果是那就处理,否则返回moved信息
为什么是单线程
主要是面向内存操作,非常快速,同时它的瓶颈不在cpu,而在网络IO和内存。
单线程可以减少开发中的出现问题
单线程可以避免死锁等状况,同时可以避免上下文切换问题
非阻塞IO 基于Ractor开发的文件事件处理器
套接字
IO多路复用程序
文件事件分派器
事件处理器
多线程
4.0以后引如多线程,异步的来删除key 比如ulink
6.0引入多线程来快速处理IO
6.0引入多线程来快速处理IO
缓存一致性问题(1)
考虑的三个因素
并发
数据库+缓存一致成功问题
缓存利用率
更新+更新
先更新DB,再更新Cache
先更新Cache,再更新DB
更新+删除
先更新DB,再删除Cache
先删除Cache,再更新DB
如何解决第二步失败
通过MQ进行异步删除
通过订阅binlog日志来进行删除
可以保证强一致性吗?
常见问题
缓存穿透
当用户访问一个缓存和数据库都不存在的键时,请求会对数据库造成巨大压力
解决方法
缓存无效Key
布隆过滤器
存在误判,删除不支持
缓存击穿
一个热点key的到期时间到,当过期瞬间,大量请求会直接打在服务器上
解决方法
设置分布式锁,也就是获取值为空的时候,先锁上,然后用setnx先设置一个key,设置成功后进行load db操作,操作完成后删除这个setnx
热点数据不失效或者让其生命周期变长
缓存雪崩
同一时间,大面积的key同时失效
解决方法
设置插入键的时候,设置一个比较小的随机数时间间隔。
bigkey
使用redis -cli --bigkeys
Nginx
负载均衡算法
轮询法(默认)
hash ip/url的哈希值来映射到不同的服务器
最小连接数
随机发
加权轮询
常用命令
nginx -s stop/reload/start
nginx -t 测试配置文件是否正确
Rabbit MQ
作用
服务解耦
异步处理
流量削峰
死信队列
TTL到了
消费者拒绝消息
消息队列满了
如何保证消息不丢失
发送者端到MQ 开启confirm机制
MQ : 发送消息的时候开启持久化 DeliveryMode = 2
MQ到消费者:关闭自动ACK,处理完消费之后再ACK
如何保证消息不被重复消费
看具体业务,如果update操作无需操作
Mysql唯一索引
信息发送加个uuid, 并且放到Redis, 处理的时候判重
如何保证消息的顺序传输
一个队列只有一个消费者
如果想要并发,那么开多个队列
设计
交换机
Exchange模式
direct exchange : 只发到与之相关的queue
fanout exchange : 发送到全部的queue
topic exchange : 发送到通过模式匹配的queue
持久化
高可用
单机、集群、镜像
和Kafka对比
单机吞吐量,Kafka比较高
RabbitMq基于Erlang开发,延迟最低,可以达到微秒级别
Kafka消息可靠性较高
Zookeeper
数据模型
采用层次化的多叉树形结构
节点类型
持久节点
临时节点
持久顺序节点
临时顺序节点
用途
分布式锁
三个角色
Leader 唯一的写请求处理者
Follower: 能够接受客户端的请求,如果时读请求则自己处理,如果是写请求则转发给Leader
Observer: 没有选举权的Follower
其他
设计模式
基本原则
S 单一职责原则 一个类尽可能负责一个领域的功能
L 里氏替换原则 如果能接收基类参数,那么一定可以接收其子类参数
O 开闭原则 对扩展开放 对修改关闭 支持热拔插
D 依赖倒转原则 针对接口编程 而不是针对具体实现编程
I 接口隔离原则 降低耦合度 接口单独设计 功能模块相互独立
合成复用原则 尽量使用聚合、组合而不是继承
创建型模式
工厂模式
单例模式
饿汉式
双重锁校验
结构型模式
装饰器模式
是继承的一个替代模式 可以动态扩展类的一些功能 而无需修改内层接口
多层装饰有些复杂
代理模式
增加中间层,来达到访问一个对象时做一些控制
静态代理
动态代理
JDK
实现简单
通过运行动态生成,有点慢
Cglib
编译时生成子类对象,速度更快
上手难度较大
优缺点
职责清晰 高扩展 智能化
速度比较慢 实现起来可能有些麻烦
适配器模式
现存的"老接口"需要适配新的接口
优缺点
类的复用性好 让两个不同的类联系在一起 灵活性好
增加代码维护难度 建议重构而不是采用适配器
外观模式
为子系统的一组接口提供一致性的访问界面
优缺点
行为型模式
模板模式
策略模式
将几种相同功能算法封装起来,并且可以在使用中进行替换
优缺点
算法按需替换 无需if else多余判断 提升代码可读性
需要生成多个策略类 并且需要对外暴露
监听者模式
Linux
线上查询日志(重要)
tail [参数] 日志文件
-f 【间隔】 : 间隔多少秒进行日志循环输出
-n 显示多少行
head :查看前几行
sed: 查询中间几行
文件操作
vim cat
cp [源文件] 【目标目录】
mv 【源文件】【目标目录】
端口相关
netstat
-t:指明显示的fTCP端口
-u: 指明显示的UDP端口
lsof
进程相关的命令
ps
显示其他用户启动的进程(a)
查看系统中属于自己的进程(x)
启动这个进程的用户和它启动的时间(u)
查看系统中属于自己的进程(x)
启动这个进程的用户和它启动的时间(u)
查看线程状况 -T
top
-s cpu 根据cpu进行排序
内存操作
cat /proc/meminfo
free
区块链(待更新)
密码学
古典密码
置换密码
周期置换密码
把明文分成多个分组,然后在各个分组内进行置换读出
列置换密码
把明文按照规则填入二维数组,并按照一定的规则按列读出
代换密码
多表代换密码
单表代换密码
基于密钥的单表代换密码
仿射密码 通过一个线性变换e(x) = (ax + b) mod 26
轮转密码机
分组密码
DES加密
初始IP置换
16轮迭代运算
IP-1逆置换
基础概念
S盒 Substitution-box
代换,将原来的数据替换成其他数据,数据长度也可以不同
增加了非线性度
P盒 Permutation-box
置换,数据元素之间的相对位置发生变化
让明文和密钥的影响迅速扩散到整个密文中
E盒
扩展,将32bi数据扩展成48bit数据
为了更好适配密钥
F轮函数
E盒扩展置换
密钥加 将密钥和扩展后的数据进行异或计算
S盒代换盒 将48位数据分为8块,进6出4,转换成32位
P盒 置换
抗差分攻击和线性分析
S盒属于非线性结构 可以防止线性分析
AES加密
密钥扩展 扩展成4组
字节代换 通过S盒将状态数进行替换 非线性
行位移 第n行左移n个字节
列混合 固定矩阵乘以原文矩阵
轮密钥加 扩展密钥与状态密钥进行异或
序列密码(流加密)
Hash函数
MD5
输出128bit的消息摘要
输入消息以512bit的分组为单处理
SHA256
输出256bit
公钥密码体系
RSA公钥加密机制
基于大整数分解问题的困难性
当私钥变得越来越来越大,存在速度慢的问题
ElGamal公钥加密体制
ECC
基于椭圆曲线上的离散对数问题
计算量小,处理速度块,存储占用小,带宽要求低,适合移动通信、无线设备上的应用
数字签名
消息进行 摘要算法处理后 使用私钥采用某种签名算法来进行签名
延时双删
0 条评论
下一页