Java知识点
2022-04-13 11:37:53 16 举报
登录查看完整内容
Java面试知识点
作者其他创作
大纲/内容
HTTP
应用层
TCP/UDP
传输层
网络层
数据链路层
物理层
五层
网络模型
面向链接
由 IP 地址和端口号组成
Socket
用来解决乱序问题等
序列号
用来做流量控制
窗口大小
如何保证可靠性
可靠
字节流
特性
确认应答号
ACK
RST
SYC
FIN
控制位
格式
避免历史连接
同步双方的初始序列号
避免资源浪费
为什么要三次握手
三次握手
TCP连接
为什么要有TIME_OUT
四次挥手
TCP断开
什么是 SYN 攻击?如何避免 SYN 攻击?
常见问题
TCP
主要是告诉 UDP 协议应该把报文发给哪个进程
该字段保存了 UDP 首部的长度跟数据的长度之和
包长度
校验和是为了提供可靠的 UDP 首部和数据而设计
校验和
目标和源端口
UDP
TCP 是面向连接的传输层协议,传输数据前先要建立连接
UDP 是不需要连接,即刻传输数据。
连接
TCP 是一对一的两点服务,即一条连接只有两个端点
UDP 支持一对一、一对多、多对多的交互通信
服务对象
TCP 是可靠交付数据的,数据可以无差错、不丢失、不重复、按需到达
UDP 是尽最大努力交付,不保证可靠交付数据
可靠性
TCP 有拥塞控制和流量控制机制,保证数据传输的安全性
UDP 则没有,即使网络非常拥堵了,也不会影响 UDP 的发送速率
拥塞控制、流量控制
TCP 首部长度较长,会有一定的开销,首部在没有使用「选项」字段时是 20 个字节,如果使用了「选项」字段则会变长的
UDP 首部只有 8 个字节,并且是固定不变的,开销较小
首部开销
TCP与UDP区别
分片
增加协议头
工作原理
4 个 8 位(Octet)排列而成
组成
与子网掩码做位与运算
找各层网络
IPv4 的网络分成这样 4 层
寻址步骤
通过地址找设备
寻址
路径的选择,已知道地址
路由(Routing)
IP
区别
网络
Cluster:集群
每个es实例称为一个节点
自动分配
可手动配置
Node:节点
仅限小写字母
不能包含\\、/、 *、?、\"、<、>、|、#以及空格符等特殊符号
不包括引号
不能以-、_或+开头
不能超过255个字节
创建规则
Posting List(倒排表)
Term Dictionary(词典)
Term Index(词典索引)
有穷状态转换器
FST
索引帧
Frame Of Reference
咆哮位图
缓存的filter放到内存里面
short数组保存
数量小于4096
bitmap保存
数量大于等于4096
Roaring Bitmaps
其他核心
倒排索引
Index:索引
es中的最小数据单元
相当于数据库一行记录
Document:文档
数据库中的列(Columns)
定义每个document应该有的字段
Field:字段
每个索引里都可以有一个或多个type,type是index中的一个逻辑数据分类,一个type下的document,都有相同的fifield
7.x没有了
Type:类型
shard:分片
将每个index的分片都备份存到另外的机器上
replica:副本
核心概念
定义
原因
解决方案
脑裂
问题
ES
服务发现
权重管理
打标管理
优雅上下线
在线编辑
历史版本
一键回滚
灰度发布
推送轨迹
配置管理
Leader节点产生
Leader消息分发
节点数据同步
Raft 选举算法
推举算法
理论
cluster.conf
安装环境
配置数据库
部署
集群
nacos
注册中心
@LoadBalanced
使RestTemplate自动负载均衡
链接写服务名
RestTemplate.getForObject()
RestTemplate+注释
实现
轮询(默认)
随机
重试
最小连接数
判断该 server 是否超时可用、当前连接数是否超限
可用过滤
区域权衡
实现IRule接口
自定义均衡
均衡策略
Ribbon
客户端负载均衡器
负载均衡
@EnableFeignClients
启用 OpenFeign 声明式通信
@FeignClient
创建OpenFeign的通信接口
必要
开启负载均衡
开启数据压缩功能
切换通信组件
可选
OpenFeign
服务通信
谓词决定了路径的匹配规则
谓词
对请求或响应作出实质的前置、后置处理
过滤器
ElapsedFilter.java
自定义过滤器
路由
关键
gateway
API网关
熔断器
配置中心
日志管理
链路追踪
超链接
Spring Cloud Alibaba 官方文档
文档
资源
springcloud
冒泡排序
快速排序
交换排序
简单插入排序
希尔排序
插入排序
简单选择排序
堆排序
选择排序
二路归并排序
多路归并排序
归并排序
比较类排序
计数排序
桶排序
基数排序
非比较排序
冒泡
小于等于7
归并
大于7
对象
小于7
首个元素为基准
size=7
首、中、末三个元素中间大小的元素作为划分元
7<size<=40
从待排数组中较均匀的选择9个元素,选出一个伪中数做为划分元
size>40
大于等于7
普通类型
Java sort()
时间复杂度
排序算法
KMP算法
字符串中寻找子串
马拉车算法
判断是否是回文
leetcode
算法
NIO的零拷贝
使用本地内存
元数据区(JDK1.8)
堆外内存
永久代
静态变量
类的版本
字段
方法
接口描述
类信息
即时编译机器码
常量
运行时常量池
存储
方法区
新创建的对象
XX PretenureSizeThreshold
设置大对象的大小
配置
Eden(8/10)
保留幸存者
ServivorTo(1/10)
保留幸存者,活下来的留到ServivorTo
ServivorFrom(1/10)
结构
年轻对象
小对象
存放
新生代(1/3)
大对象
长生命周期的对象
老年代(2/3)
Class
Meta 元数据
使用JVM内存
永久代(JDK1.7)
内存比例
堆
引用计数法
可达性分析法
回收算法
共享
存储行数
不会溢出
程序计数器
记录方法的执行过程
存放局部变量
局部变量表
临时开辟一篇区域 做引用
操作数栈
符号引用变成直接应用
动态链接
栈帧
虚拟机栈
为本地方法服务的本地方法栈
本地方法区
私有
内存
循环引用
引用法
虚拟机栈中引用的对象
方法区中类静态属性引用的对象
方法区中常量引用的对象
本地方法栈中Native方法引用的对象
启动类加载器加载的类和创建的对象
root
可达性分析
垃圾确定
进入老年代的回收次数
XX:MaxTenuringThreshold
一半内存可用
长期存活对象回一直被复制
缺点
复制算法
效率低
内存碎片多
标记清除
标记整理法
分代收集法
强引用
软引用
弱引用
虚引用
引用类型
单线程复制
Serial
调整工作线程数
-XX:ParallelGCThreads
多线程复制
ParNew
最大停顿时间
-XX:MaxGCPauseMillis
吞吐量大小
-XX:GCTimeRatio
自适应
UseAdaptiveSizePolicy
关注系统的吞吐量
关注
Parallel Scavenge
新生代
多线程标记清除
最短回收停顿时间
CMS
单线程标记整理
Serial Old
多线程标注整理
Parallel Old
老年代
多线程标记整理
可预测的停顿
G1
只能在64位的linux上使用
ZGC
整合
垃圾回收器
选择合适的垃圾收集器
垃圾回收
CPU占用率高
性能调优
查看线程情况,发现没有死锁或者IO阻塞的情况
jstack PID
jstack
获取到jvm.hprof文件,上传到指定的工具分析,比如heaphero.io
jmap -histo:live PID | more
查看堆的情况
jmap -heap PID
生成堆转储快照
内存溢出时,会自动dump出该文件
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=heap.hprof
jmap
与ps -ef | grep java 类似
查找java进程
jps
查看JVM的参数配置
jinfo -flag [+|-] PID
jinfo
查看某个java进程的类装载信息,每1000毫秒输出一次,共输出10次
jstat -class PID 1000 10
查看类装载信息
jstat -gc PID 1000 10
查看垃圾收集信息
jstat
jconsole
jvisualvm
可视化
阿里
arthas
第三方
MAT
手动
自动
获取dump
dump信息
内存分析
工具
C1和C2
而AOT是在程序运行之前,将字节码转换为机器码
Java9引入
AOT
Java10引入
Graal VM
编译器
加载Class文件
在方法区中创建Class对象
加载
验证Class文件
验证
类变量分配空间
准备节点
final类型
设置类中初始值
准备
符号引用变成直接引用
解析
执行类构造器进行初始化
初始化
加载阶段
lib目录中的类库
启动类加载器(Bootstrap Classloader)
lib/ext目录中的类库
扩展类加载器( Extention Classloader)
加载用户路径(classpath)上的类库
应用程序类加载器(Application Class loader)
通过继承 java. lang classLoader 实现向定义的类加载器
自定义加载器(User Class loader)
类加载器
双亲委派模型
OSGI
类加载机制
继承Thread
实现Runnable接口
无返回值
实现Callable接口
有返回值
原生方式
线程创建
并发
JVM
NullPointer Exception
ClassCastException
ArraylndexOutOfBundsException
RuntimeException 运行时异常)
ClassNotFoundException
SQLException
IO Exception
CheckException (检查异常)
Exception
启动失败
Error
类型
定义方法可能抛出的异常
throws
作用在方法内, 表示明确抛出一个异常
throw
抛出异常
try catch finally
处理异常
处理异常方式
异常
id
主查询
primary
子查询
subquery
简单查询
simple
衍生查询,使用到临时表
derived
select_type
table
只有一条数据
system
仅仅能查到一条数据的SQL,用于主键和唯一键
const
唯一性索引
eq_ref
非唯一性索引
ref
范围查询
range
查询索引列
index
查询所有数据
all
type
explain
执行计划
第一范式(1NF)
第二范式(2NF)
第三范式(3NF)
三大范式
普通索引
唯一索引
全文索引
主键索引
修改需要挪动大量数据
使用可以二分查找的链表(查找树)
优化
二分查找
数组
变成链表
最坏变成O(n)
查找耗时和数的深度有关
使用自平衡树
避免最坏情况
二叉搜索数
左右旋自平衡
特点
左右子树指针
数据
一个节点才几字节造成IO浪费
操作一页有16K
数据量多要多次IO
访问一个节点需要一次IO
B树
减少树深度
节点为红色或者黑色
根节点必要黑色
叶子节点必须黑色
红色节点的子节点必须为黑色
任意节点到每一个叶子节点包含的黑色节点数目相同
红黑树
平衡二叉树
有多个子节点
根据数据分裂与合并
造成大量磁盘浪费,频繁分裂与合并
索引无序
需要返回上层节点查找数据
范围查询要IO的次数多
一次IO能读到的节点少
B树(多路平衡查找树)
只有叶子节点存储数据
有序
叶子节点用的是双向链表
每个节点存储更多数据,路数更多
遍历叶子节点的链表
扫遍能力强
根枝节点不保存数据,一次IO可以读取更多节点信息
磁盘读写能力强
叶子节点为链表
排序能力强
永远从叶子节点拿数据
效率稳定
一页16K可以读取1000路
千万级数据只要3次IO
优点
B+树
可以二分查找的链表
innoDB自动为buffer pool仲的热点页创建索引
hash是自适应hash
innoDB不能显式创建hash索引
memory可以使用hash
哈希
存储模型推演
表结构定义文件
.frm
数据和索引文件在一起
.idb
innoDB
数据文件
.myd
索引文件
.myi
myisam
存储文件
避免了回表查询
查询数据快
叶子节点存储的是数据
用唯一索引
内置6字节ROWID的值所为索引
没有唯一索引
没有主键索引
一级索引(聚集索引)
地址会变化
为什么不存地址
叶子节点存储的是主键的值
单列索引
从左到右查找
最左匹配原则
联合索引
细分
查询的属性就是索引值
只需从二级索引拿数据
索引覆盖
二级索引
索引的区别(innoDB)
经常用于where,order,join的值
浪费空间,更新慢
索引个数不能太多
过长字段建立前缀索引
扫面行数多
区分度低(性别)不建立索引
页分裂
频繁更新的值不作为主键或索引
无序分裂
无序的不作为索引
组合索引把散列高的放前面
索引创建
索引列使用了函数
字符串不加引号
用全文索引
like前面带%
not like
索引有序的话就可以
!= not in
负向查询
索引失效
索引
要么全成功要么全失败
通过undo log实现
原子性(Atomicity)
多个事务之间的操作是透明的
隔离性(Isolation)
事务提交就是永久的
redo log和 double write buffer(双写缓冲)
持久性(Durabilit)
数据前后一致
一致性(Consistent)
事务的特性
手动开启事务
可出现脏读、幻读或不可重复读
允许读取尚未提交的更改
Read Uncommitted(未提交读)
可出现幻读和不可重复
允许从已经提交的并发事务读取
Read Committed(已提交读)
幻读
对相同字段的多次读取的结果是一致的
Repeatable Read (可重复读)默认
串行化
Serializable(串行化)
事务隔篱级别(SQL92标准)
事务A读到了事务B未提交的数据,事务B又回滚了
脏读
事务A读取数据后事务B修改了值,事务A再读发现不一样了
不可重复读
事务A读取值的时候事务B新插入了一条,事务A再次读取发现多了一条数据
事务i并发出些的问题
修改或者删除造成的读不一致叫做不可重复读,插入造成的读不一致叫做幻读。
LBCC
第一次查询之前已经提交的事务修改
本事务修改
能看到的数据版本
本事务第一次查询之后创建的事务
活跃的(未提交的)事务的修改
不能看到的版本
原则
DB_TRX ID(事务ID)
指向undo log链的指针
DB_ROLL_PTR(删除版本号)
每行字段有两个隐藏字段
InnoDB事务都有编号且不断递增
原理
undo log链
旧版本数据的存储
Read View 是事务第一次查询的时候建立的
Repeatable Read (可重复读)
Read View 是事务每次查询的时候建立的。
每个事务都有Read View(可见性试图)
每个事务有一个视图
可见性规则的流程
规则
事务
MVCC
实现事务的两大方案
select ……. lock in share mode;
手动加锁
Shared(共享锁)
修改会自动加排他锁
Exclusive Locks(排他锁)
行级锁
用来防止自增字段重复
自增锁
锁允许多个事务同时插入数据到同一个范围
我们给数据加锁系统会自动加上意向锁
插入意向锁
Intention Locks
表级锁
Predicate Locks for Spatia Indexe()
锁分类
InnoDB 的行锁,就是通讨锁住索引来实现的
行锁
等值查询查询到记录
Record Locks(记录锁)
查询记录不存在时用到
Gap Locks(间隙锁)
范围查询中包含存在的记录
Next-KeyLocks(临键锁)
锁算法
不加锁
Read Uncommited
Serializable 所有的select 语句都会被隐式的转化为 selec …in share mode,会和 update、delete 互斥
Serializable
普通的 select 都是快照读,使用MVCC实现。
不使用间隙锁,所以会幻读
加锁的 select 都使用记录锁,因为没有 Gap Lock。除了两种特殊情况——外键约束检查((foreign-key constraint checking)以及重复键检查(duplicate-key checking)时会使用间隙锁封锁区间。
Read Commited
使用快照读(snapshot read),底层使用 MVCC来实现
普通的 select
加锁的 select(selec …in share mode /selec …for update)以及更新操作update,delete 等语句使用当前读(current read),底层使用记录锁、或者间隙锁、临键锁
Repeatable Read
隔离级别
一次只能有一个事务持有锁
锁互斥
其他事务要等持锁事务释放锁才能获得
不可剥夺
多个事务形成等待环路
形成等待环路
死锁的条件
show status like 'innodb_row_lock_%'
当前运行的所有事务,还有具体的语句
select*from information_schema.INNODB_TRX;
当前出现的锁
select*from information_schema.INNODB_LOCKS;
锁等待的对应关系
select*from information schema.INNODBLOCK_WAITS;
查看锁信息
set GLOBAL innodb status output=ON:set GLOBAL innodb_status output locks=ON;
打开锁监控
死锁
锁
查看版本
select version();
查看环境
show variables like '%engine%;
默认最大连接大小8
Druid
Hikari的默认最大连接池大小是10
Hikari
springboot2.0默认
使用连接池
避免频繁的上下文切换
机器核数乘以2加1
建议连接数
优化连接
缓存
集群,主从复制
分库分表
show variables like 'slow query%'
set 动态修改参数(重启后失效)
修改配置文件my.cnf
参数的两种修改方式∶
MySQL的 bin目录下
最慢的十条
显示运行线程
命令
mysqldumpslow
分析工具
慢查询日志
sql优化用例
分表分区
使用最小类型
字段定义
固定长度用char
字符类型
尽量使用非空
不用外键,触发器
字段冗余
优化结构
mysql查询流程
sql优化
MYSQL
select
poll
epoll
kqueue
多路复用io模型
io
指定下一个将要被写入或者读取的元素索引,它的值由 get/put()方法自动更新
创建Buffer 对象时,position被初始化为0。
position∶
指定还有多少数据需要取出
从缓冲区写入通道时
多少空间可以放入数据(
在从通道读入缓冲区时
limit
它指定了底层数组的大小
存储在缓冲区中的最大数据容量
capacity
∶0<= position<=limit<=capacity
重要属性
Buffer(缓冲区)
Selector(选择器)
Channel()
NIO
扩容因子
为什么线程不安全
初始容量值
ArrayList
线程安全
Vector
可以作为队列,堆栈使用
LinkedList
实现原理
CopyOnWriteArrayList
List
HashSet
Comparable 接口
TreeSet
LinkedHashSet
Set
比较器
PriorityQueue
DelayQueue
Queue
Collection
1.7和1.8的区别
键一条为空
当前数组容量
为什么加载因子是0.75
负载因子,默认为0.75
loadFactor
扩容的阈值
threshold
基础参数
不移动
高一位为 0
新的下标位置等于原下标位置 + 原数组长度
高一位为 1
高位运算判断是否需要移动
resize()扩容
put
常用方法
HashMap
Segment组成
1.7
CAS
1.8
ConcurrentHashMap
HashTable
默认升序
TreeMap
LinkHashMap
Map
集合
可以接收一个 Object 类型的参数
返回值为 Boolean
equals()
只能接收一个 String 类型的参数
compareTo() 的返回值则为 int
compareTo()
查询字符串首次出现的下标位置
indexOf()
去掉字符串首尾空格
trim()
安全高效
final修饰
先创建一个字符串对象,查看常量值有没有,没有就在常量池创建
new()
常量池有就直接从常量池引用,没有就在常量值创建
直接赋值
JDK8把字符串常量池从方法区移到了 Java 堆上
创建方式
String
复制对象的时候只复制地址
浅拷贝
重新复制一个新对象
实现克隆方法
构造方法实现深克隆
JDK字节流实现
SerializationUtils.clone(p1)
Apache Commons Lang
Gson
FastJSON
JSON工具
实现方式
深拷贝
深拷贝与浅拷贝
基础的知识
获取类的属性,方法
Class类
设置获取类中的属性值
Field类
获取方法的描述信息或者执行某个方法
Method类
类的构造方法
Constructor类
API
获取Class对象
子主题
步骤
反射
解耦
异步
削峰
MQ的作用
配置开启
无法线性拓展
镜像集群模式
RabbitMQ
partition
broker
topic
HA 机制
Kafka
高可用性
业务处理完offset未提交成功
有哪里场景会重复消费
先查询在更新
Redis的set
传一个唯一id
数据库主键插入
保证幂等性
重复消费
丢失的情况
生产者配置开启
confirm 机制
吞吐量下降
同步
事务机制
生产者丢了数据
创建 queue 设置为持久化
deliveryMode 设置为 2
设置持久化
开启 RabbitMQ 的持久化
RabbitMQ 弄丢了数据
关闭RabbitMQ 的自动 ack
消费端丢数据
解决
关闭自动提交 offset
消费端丢了数据
每个 partition 必须有至少 2 个副本
给 topic 设置 replication.factor 参数
一个 leader 至少感知到有至少一个 follower 还跟自己保持联系
Kafka 服务端设置 min.insync.replicas
写入所有 replica才成功
在 producer 端设置 acks=all
要求一旦写入失败,就无限重试
在 producer 端设置 retries=MAX
Kafka丢失数据
消息丢失
消息顺序性
紧急扩容
加快消费速度
消息未满
增加 Consumer 实例数量来提高并行度
修改参数 consumeThreadMin、consumeThreadMax
提高并行度
consumeMessageBatchMaxSize
批量方式消费
如果消息不重要,跳过消息不消费
跳过非重要消息
优化消息执行时间
优化每条消息消费过程
RocketMQ
把数据查询回来
批量重导
消息不要设置过期时间
防止丢失
判断消息数量,设置预警
提前预防
满了丢了
消息挤压
设计一个MQ
MQ
双写方案
数据迁移
效率高
不用网络请求
不会重复
没法排序
存储占用空间大,建立索引不友好
没有规律
Comb 算法
改进
UUID直接生成
每个数据库申请一批id号
批量号段式数据库
基于内存,速度快
天然排序,自增,有利于排序搜索
需要关注持久化,可用性等,增加系统复杂度
incr原子自增
Redis自增
美团Leaf服务
1位:不使用,二进制中最高位是为1都是负数,但是要生成的唯一ID都是正整数,所以这个1位固定为0
41位:记录时间戳(毫秒)
10位:记录工作机器的ID,可以机器ID,也可以机房ID + 机器ID
12位:序列号,就是某个机房某台机器上这一毫秒内同时生成的 id 序号
8字节64位
判断是否小于上次时间戳
回拨之后在拓展位上加1
时间回拨可能会重复
强依赖于时间
snowflake(雪花算法)
基于雪花算法
百度 uid-generator
主键生成策略
数据库级别锁
redis原子操作锁
Zookeeper锁
Redisson
分布式锁
分布式系统
独占锁和共享锁
可重入锁
乐观锁
悲观锁
锁类型
独占式悲观锁
JVM实现
禁止指令重排
volatile
单例模式
应用
monitorenter
monitorexit
修饰代码块
ACC_SYNCHRONIZED
修饰方法
JVM隐式实现
1.6后升级原理
修饰实例方法
修饰静态方法
使用方式
synchronized
可实现公平非公平
只能修饰代码块
手动加解锁
基础AQS实现
获取锁
acquire()排队
lock()
解锁
unlock()
方式
ReentrantLock
锁应用
互斥条件
请求和保持条件
不剥夺条件
循环等待
死锁的必要条件
线程锁
新建
NEW
就绪
RUNNABLE
阻塞等待锁的线程状态
BLOCKED
等待状态
WAITING
计时等待状态
TIMED_WAITING
终止状态
TERMINATED
线程的状态
线程状态
Thread.setPriority()
线程优先级
other.join()
让子线程执行
yield()
愿意让出使用权
让出执行权
synchronized修饰保证安全
Thread 自身的方法
start()
Runnable 的抽象方法
run()
主线程调用,会让出执行权给子线程
join()
线程方法
10最大,1最小
默认为5
创建线程的方法会默认继承创建它的线程的优先级
不一定大的就能抢到
优先级越大,抢占 CPU 时间片的概率越高
优先级级别
核心线程数
corePoolSize
最大可以创建的线程数
maximumPoolSize
存活时间
keepAliveTime
存活时间单位
unit
线程池执行的任务队列
workQueue
线程创建工厂
threadFactory
线程池会抛出异常并终止执行
终止策略
AbortPolicy(默认)
把任务交给当前线程来执行
CallerRunsPolicy
忽略此任务(最新的任务)
DiscardPolicy
忽略最早的任务(最先加入队列的任务)
DiscardOldestPolicy
自定义策略
拒绝策略
RejectedExecutionHandler
参数
new Runnable(){}
execute
new Callable<String>()
submit
执行流程图
ThreadPoolExecutor
线程池
防止重排序
强制把写缓冲区/高速缓存中的脏数据等写回主内存,让缓存中相应的数据失效
作用
语义中的内存屏障
在指令前插入Load Barrier,可以让高速缓存中的数据失效,强制从新从主内存加载数据
读屏障
Load Barrier
在指令后插入Store Barrier,能让写入缓存中的最新数据更新写入主内存,让其他线程可见
写屏障
Store Barrier
内存屏障
需要倒数的数量
CountDownLatch
0没锁
2,3,4表示重入次数
大于0 被其他线程持有
锁的占有情况
CAS设置值
compareAndSetState
使用volatile 内存屏障
setState
状态(state)
排队管理器
线程队列
lock
acquire
Semaphore
await
线程获取方法
去释放一个许可证,会让 state 加 1
release
作用是倒数一个数,让 state 减 1
countDown
线程释放方法
三大部分
tryAcquire
tryRelease
tryAcquireShared
tryReleaseShared
继承要实现的方法
AQS
多线程
int
embstr
raw
有三种编码
Simple Dynamic String 简单动态字符串。
value值指向SDS动态字符串
通过redisObject存储
操作命令
ziplist
hashtable
内层
Hash
ziplist 和 linkedlist 的结合体
quicklist
元素个数超过512个,也会用 hashtable 存储
intset
整形
非整形
元素数量小于128
skiplist(跳表)+dict存储
元素数量大于128或任意menber长度大于64
SortedSet
数据结构
HyperLogLog
Geo
Pub/Sub
BloomFilter
Redis Search
Redis-ML
Redis Module
Bitmaps是在字符串类型上面定义的位操作。一个字节由8个二进制位组成。
BitMap
进阶
2.6版本以上
2.6之前
锁代码
访问该值才判断是否过期
惰性删除
默认10次每秒
hz
redis.conf
随机抽取20
比例过25%
定期删除算法
每隔一段时间检查是否有过期
定期删除
定时器定时删除
设置过期时间
定时删除
25ms
最大执行时间
过期策略
reids内部默认使用这2种
config get maxmemory-policy
查看
重启失效
config set maxmemory-policy noeviction
设置
重启生效
maxmemory-policy noeviction
noeviction(默认)
6种策略
最久未使用
LRU
LFU
淘汰算法
内存淘汰策略
Redis卡顿
小问题
给Redis时间设置随机过期值
普i他解决
加互斥锁或者使用队列,针对同一个key 只允许一个线程到数据库查询
缓存定时预先更新避免同时失效
缓存永不过期
其他解决
key同一时间同时过期
缓存雪崩
Guava 的实现
布谷鸟过滤器
redisson分布式
变种
布隆过滤器
缓存穿透
缓存空数据
缓存特殊字符串,比如&&
MD5
SHA-1
哈希函数
大数据是否存在
面试题
缓存击穿
生产问题
删除缓存失败,捕获这个异常,把需要删除的key发送到消息队列。让后自己创建一个消费者消费,尝试再次删除这个 key
重试的机制
监听binlog日志
异步更新缓存
先更新数据库后更新缓存
写入数据之后,再删除一次缓存
延时双删
先更新缓存再更新数据库
缓存一致性
RedisTemplate
Jedis
Java工具
RDB
不用检验命令
不会阻塞当前的写操作
写后日志
AOF日志
写回策略
系统无法保存过大文件
文件大追加命令效率慢
宕机后恢复慢
性能问题
多变一
一拷贝两日志
bgrewriteaof线程实现
避免阻塞线程
重写机制
AOF
config get aof-use-rdb-preamble
查询是否开启
RDB + AOF(redis默认)
数据持久化
主从模式
从从模式
主从同步
src/redis-sentinel
./src/redis-sentinel sentinel.conf
启用命令
哨兵模式
槽位
crc16算法
集群模式(3.0版本)
高可用
单值缓存
SET user:1 value(json字符串);<br>存:MSET user:1:name zhangsan user:1:age 10<br>取:MGET user:1:name user:1:age<br>比json格式好,方便单属性操作,性能更好一点,最优选择HASH
对象缓存
SETNX product:10001 true // 发返回1表示加锁成功,有弊端不要使用 SETNX product:10001 true // 发返回0表示加锁失败 DEL product:10001 // 释放锁 SET product:10001 true ex 10 nx // 防止程序意外终止导致死锁
阅读量统计在Redis中的使用:<br>INCR article:readcount:{文章Id} 文章的阅读量统计<br>GET article:readcount:{文章Id}
计数器
INCRBY orderId 1000 redis生成序列号,提升性能。
分布式系统唯一id生成
string
Stack(栈)=LPUSH+LPOP-&gt;FILO 先进后出 Queue(队列)= LPUSH+RPOP-&gt;FIFO 先进先出 Blocking MQ(堵塞队列)= LPUSH+BRPOP
list
无序去重
集合操作
随机事件
set
维护顺序
排序实现
sortset
HSET user:10001 name zhangsan age 10 // 设置对象属性<br>HGET user:10001 name age // 获取属性信息
对象存储
q'we'q'we
以用户ID为key 商品ID为field 商品数量为value
电商购物车
hash
setbit等命令只不过是在set上的扩展
设置或者清空key的value(字符串)在offset处的bit值(只能只0或者1)。
指令 SETBIT key offset value
大概的空间占用计算公式是:($offset/8/1024/1024)MB
在一台2010MacBook Pro上,offset为2^32-1(分配512MB)需要~300ms,offset为2^30-1(分配128MB)需要~80ms,offset为2^28-1(分配32MB)需要~30ms,offset为2^26-1(分配8MB)需要8ms。
空间占用、以及第一次分配空间需要的时间
根据日期 offset =hash % 365 ; key = 年份#用户id
用户签到
使用时间作为cacheKey,然后用户ID为offset,如果当日活跃过就设置为1<br>那么我该如果计算某几天/月/年的活跃用户呢(暂且约定,统计时间内只有有一天在线就称为活跃),有请下一个redis的命令<br>命令 BITOP operation destkey key [key ...]<br>说明:对一个或多个保存二进制位的字符串 key 进行位元操作,并将结果保存到 destkey 上。<br>说明:BITOP 命令支持 AND 、 OR 、 NOT 、 XOR 这四种操作中的任意一种参数<br><br>20190216 活跃用户 【1,2】<br>20190217 活跃用户 【1】<br>统计20190216~20190217 总活跃用户数: 1
统计活跃用户
使用bitmap是一个节约空间效率又高的一种方法,只需要一个key,然后用户ID为offset,如果在线就设置为1, 不在线就设置为0,和上面的场景一样,5000W用户只需要6MB的空间。
用户在线状态
使用场景
bitmap
布隆过滤器实际上是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率和删除困难。
简介:
当一个元素被加入集合时,通过K个散列函数将这个元素映射成一个位数组中的K个点,把它们置为1。检索时,我们只要看看这些点是不是都是1就(大约)知道集合中有没有它了:如果这些点有任何一个0,则被检元素一定不在;如果都是1,则被检元素很可能在。
相比于其它的数据结构,布隆过滤器在空间和时间方面都有巨大的优势。布隆过滤器存储空间和插入/查询时间都是常数(O(k))。而且它不存储元素本身,在某些对保密要求非常严格的场合有优势。
一定的误识别率和删除困难。 结合以上几点及去重需求(容忍误判,会误判在,在则丢,无妨),决定使用BlomFilter。
思想
布隆过滤器BloomFilter
redis提供地理位置相关的操作
geo
Redis
XML 配置
注解
bean的注册方式
后面的覆盖前面的
不同Spring配置文件
同一个Spring配置文件
同名bean问题
bean生命周期
三个Map
三级缓存
spring循环依赖
singleton(默认)
prototype
request
session
application
bean的作用域
控制反转
依赖注入(DI)
容器
名词
好莱坞法则
设计模式
构造方法注入
Setter 注入
接口注入
注解注入
注入方式
IoC
代码实例
注释
实现 InvocationHandler 接口
JDK 动态代理
ASM字节码操作框架
CGLIB
当 Bean 实现了接口时,Spring 就会使用 JDK Proxy,在没有实现接口时就会使用 CGLib
动态代理
切面(aspect)
横切关注点
连接点(joinpoint)
切入点(pointcut)
通知(advice)
目标对象
织入(weave)
引入(introduction)
核心知识
AOP
springboot启动原理
spring中的BeanFactory就是简单工厂模式的体现,根据传入唯一的标识来获得bean对象
工厂模式
提供了全局的访问点BeanFactory
AOP功能的原理就使用代理模式(1、JDK动态代理。2、CGLib字节码生成技术代理。
代理模式
依赖注入就需要使用BeanWrapper
装饰器模式
spring中Observer模式常用的地方是listener的实现。如ApplicationListener
观察者模式
Bean的实例化的时候决定采用何种方式初始化bean实例(反射或者CGLIB动态字节码生成)
策略模式
日志框架,JDCB中各种数据库的选择
门面模式
原子性
一致性
隔离性
持久性
事务特性
外层有就用外层没有就新建
PROPAGATION_REQUIRED
A不回滚
B处理异常
A回滚
B不处理异常
B异常
不会滚B
A异常
每次都开新事务
PROPAGATION_REQUES_NEW
外层有就用没有就非事务
PROPAGATION_SUPPORT
有没有事务都不回滚该层代码
PROPAGATION_NOT_SUPPORT
外层有事务就抛出异常
PROPAGATION_NEVER
外层没事务就抛出异常
PROPAGATION_MANDATORY
AB都回滚
PROPAGATION_NESTED
传播机制
发生自调用
方法不是public的
数据库不支持事务
没有被Spring容器管理
异常没有抛出
事务失效
使用数据库默认隔篱级别
ISOLATION_DEFAULT
ISOLATION_READ_UNCOMMITTED
ISOLATION_READ_COMMITTED(Oracle默认)
mysql系统有mvcc不会幻读
ISOLATION_REPEATABLE_READ(mysql默认)
ISOLATION_SERIALIZABLE
事务隔篱级别
@Transactional(readOnly=true)
只读事务
@Transactional(timeout=30)
事务的超时性
@Transactional(rollbackFor=RuntimeException.class)
指定单一异常类
指定多个异常类
回滚
事务传播机制
Spring
mybatis
Java
0 条评论
回复 删除
下一页