Java技术栈以及面试知识点
2021-12-14 01:18:24 2 举报
登录查看完整内容
Java工程师技术点总结以及粗略知识脉络,本人经历逐步更新
作者其他创作
大纲/内容
节省资源、常用语单片机、嵌入式开发
面向过程
方便维护、复用、扩展
面向对象
面向对象和面向过程
抽象类不能被实例化,可以有构造方法
抽象类和普通类
private 私有成员属性和方法,只能类自身可以调用,内部类除外
默认 本类和同一包下的类
protected 自身+同包+不同包的子类
public 自身+同包+不同包
方法访问权限修饰符
成员内部类可以无条件访问外部类所有的成员属性和方法,包括private
外部类如果访问内部类成员,必须先创建一个内部类对象才能进行访问
成员内部类不允许用static修饰
成员内部类
关键字static中提到Static可以修饰成员变量、方法、代码块,其他它还可以修饰内部类,使用static修饰的内部类我们称之为静态内部类,不过我们更喜欢称之为嵌套内部类。静态内部类与非静态内部类之间存在一个最大的区别,我们知道非静态内部类在编译完成之后会隐含地保存着一个引用,该引用是指向创建它的外围内,但是静态内部类却没有。
创建不依赖外部、静态内部类不能引用外部非静态成员活方法
静态内部类
必须集成一个抽象类或者实现接口
没有类名、没有构造方法
匿名内部类
种类
深入理解
内部类
对象之间比较大小例如obj1.compareTo(obj2),如果该方法返回0,则表示两个对象相等,如果该方法返回一个正整数,则表明obj1大于obj2;如果该方法返回一个负整数,则表明obj1小于obj2。
默认对比方式、也可以重写BigDecimal类、BigInteger以及所有的数值型对应的包装类:按他们对应的数值大小进行比较Character:按照字符的UNICODE值进行比较Boolean:true对应的包装类实例大于false对应的包装类实例String:按照字符的UNICODE值进行比较Date\\Time:后面的时间、日期比前面的时间、日期大
CompareTo
字符串
内存泄漏
异常
JDK1.8+新特性
日志
注解
反射
Java 基础
磁盘、内存、IObuffer
数据库DataPage 4K
基础常识
Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 与范围查询, bitmaps, hyperloglogs 和 地理空间(geospatial) 索引半径查询。 Redis 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(transactions) 和不同级别的 磁盘持久化(persistence), 并通过 Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)。
中文官网
memcached 对比
安装
Reactor线程模型
1:BIO 线程之间是相互阻塞的运行模式 称为阻塞IO
2:同步非阻塞 NIO, 基于轮询的处理模式,在用户空间内对链接进行轮询处理,请求多了以后还是会有调度成本耗费高的问题
3:多路复用 NIO 基于select事件监听,只对有请求得到客户进行响应,但是多个线程之间的调用从用户态到内核态互相切换还是有消耗
4:mmap NIO epoll的文件描述符,有共享内存区域维护一个红黑树进行数据传输,极大的减轻了系统的调用
Redis基于NIO网络模型 epoll的系统调度 可以快速响应 、 kafka也是类似原理
线程模型
Redis-cli 连接 ./redis-cli -p 10001 -a
查看帮助 ./redis-cli -h
默认16个DB
set
get
append
setrange
getrange
strlen
字符
incr
incrby
数值
setbit
bitcount
bitpos
bitop
1:用户系统统计登录天数,且窗口随机
场景
bitMap
String
lpush
lpop
栈 同向命令
rpop
队列 反向命令
lindex
数组
blpop 阻塞取,没取到阻塞
阻塞队列 单播队列
lrange key left right
循环取出
list
hash map(k-v) 命令H开头
无序、随机存放、不重复
随机事件
sorted sets
数据类型
SUBSCRIBE first topic1
订阅一个topic
客户端向领一个topic发布消息
发布订阅
开始
multi
执行
exec
放弃
descard
监听 标记所有指定的key 被监视起来,在事务中有条件的执行(乐观锁)
watch
事务
概率解决问题,将缓存中的数据向BitMap中标记 ,可能请求的被错标 , 可以很大程度的去 减少缓存穿透,而且成本极低
如果穿透了,数据不存在,client 增加Redis中key为null , 不用走布隆过滤了 , 增加元素需要完成对布隆过滤器的添加(双写一致)
布隆过滤器
set key value ex
主动设置过期时间
设置过期时间 EXPIRE
倒计时监听
1:被动访问判定
2:周期轮询判定
过期判断原理
KEY 有效期
maxmemory
最大内存配置
返回错误当内存限制达到并且客户端尝试执行会让更多内存被使用的命令(大部分的写入指令,但DEL和几个例外)
noeviction
碰了多少次
LFU
多久没碰他
LRU
回收策略
冷热数据
Redis 作为 数据库/缓存的区别
时点性
Linux中 子进程的修改不会破坏父进程,父进程的修改也不会破坏子进程
redis 在时间点 fork 出一个进程 进行RDB备份存储 , 主进程依旧对外服务
save
fork创建子进程
save 900 1save 300 10save 60 3600
配置文件中可以去配置保存时间,默认是5分钟
bgsave
不支持Linux日期拉链,永远只有一个dump.rdb , 备份比较难
落盘时候宕机了会造成数据丢失
优点:AOF文件格式类似Java序列化,恢复速度快
弊端
快照 RDB
衔接、前一个命令的输出作为后一个命令的输入
echo $$ | more
echo $BASHPID | more
管道会出发创建子进程
父进程设置的变量、子进程对外修改,父进程并不会感知
父子进程
Linux 管道
redis的操作记录会写到文件中
RDB 和 AOF 会同时开启,恢复只会用AOF恢复,速度快,完整性好一点
体量无线变大、恢复慢
优化:RDB 落盘以后 AOF追加操作
AOF文件过大会进行重写、重新落盘
AOF配置
日志 AOF
存储层
单点故障
容量有线
存储压力 、 网络压力
单节点问题 AKF拆分可解决
同步阻塞、强一致性、破坏可用性
异步 弱一致性,暂时丢失数据、最终一致性
一致性问题
多节点
1:BGSave 2:同步
replica-save-stale-data yes
replica-read-only yes
repl-diskless-sync no
增量复制
repl-backlog-size 1mb
min-replicas-to-write 3
min-replicas-max-log 10
主从复制
Redis 的 Sentinel 系统用于管理多个 Redis 服务器(instance), 该系统执行以下三个任务:监控(Monitoring): Sentinel 会不断地检查你的主服务器和从服务器是否运作正常。提醒(Notification): 当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过 API 向管理员或者其他应用程序发送通知。自动故障迁移(Automatic failover): 当一个主服务器不能正常工作时, Sentinel 会开始一次自动故障迁移操作, 它会将失效主服务器的其中一个从服务器升级为新的主服务器, 并让失效主服务器的其他从服务器改为复制新的主服务器; 当客户端试图连接失效的主服务器时, 集群也会向客户端返回新主服务器的地址, 使得集群可以使用新主服务器代替失效服务器。
哨兵 sentinel
哨兵会修改自己的配置文件, 可以根据主节点变化修改自身配置文件
管连接点进行通信
可以订阅topic , 查看所有通信内容
redis 发布订阅
HA
业务逻辑拆分
hash取摸是固定的,产生数据倾斜,难以新增机器
hash
随机
消息队列
random
key和设备都需要参与hash计算
产生一个hash环
优点:加节点的确可以分担其他节点的压力、不会造成全局洗牌、节点进行LRU\\LFU 淘汰算法
缺点:新增节点会造成部门节点数据失效,无法命中; 击穿、请求到mysql 双写一致性 , 可以每次取离我最近的连个物理节点
优缺点
一致性hash算法
shard分片
集群
一个key过期后,瞬时太多的请求打进来,瞬间访问数据库
这里就要用分布式锁, setnx 只允许一个线程去取这个数据,其余进程进行等待
击穿
业务数据查询不到、穿过redis
client 包含数据
算法 bitmap -> redis
redis 集成布隆
解决:布隆过滤器
穿透
大量key同时失效、见解造成访问到达数据库
击穿方案
业务层面加时间判断,零点延迟
业务不允许
业务上 均匀分布过期时间
雪崩
一致性(双写)
分布式锁
缓存常见问题
子主题
API
Redis
性能监控
A 原子性
C 一致性
I 隔离性
D 持久性
ACID
范式
反范式
多加一些冗余,减少JOIN选择。以空间换时间的思想进行设计
其他注意点
范式和反范式
与业务无关、无意义的数字序列
代理主键(推荐)
事务属性中的自然唯一标识
自然主键
主键选择
数据库字符集
聚簇索引、支持事务、表锁、行锁、全文索引
InnoDB
非聚簇索引、不支持事务、不支持表锁、不支持行锁、使用大量select
MyISAM
数据存储在内存中
MEMORY
InnoDB 与 MyISAM 对比
存储引擎
适当拆分
schema与数据类型优化
explain select * from users
id号分为三种情况:1、如果id相同,那么执行顺序从上到下2、如果id不同,如果是子查询,id的序号会递增,id值越大优先级越高,越先被执行3、id相同和不同的,同时存在:相同的可以认为是一组,从上往下顺序执行,在所有组中,id值越大,优先级越高,越先执行
ID 越大 越先执行
主要用来分辨查询的类型,是普通查询还是联合查询还是子查询sample:简单的查询,不包含子查询和unionprimary:查询中若包含任何复杂的子查询,最外层查询则被标记为Primaryunion:若第二个select出现在union之后,则被标记为uniondependent union:跟union类似,此处的depentent表示union或union all联合而成的结果会受外部表影响union result:从union表获取结果的selectsubquery:在select或者where列表中包含子查询dependent subquery:subquery的子查询要受到外部表查询的影响DERIVED: from子句中出现的子查询,也叫做派生类,UNCACHEABLE SUBQUERY:表示使用子查询的结果不能被缓存uncacheable union:表示union的查询结果不能被缓存:sql语句未验证
select_type 查询类型
type显示的是访问类型,访问类型表示我是以何种方式去访问我们的数据,最容易想的是全表扫描,直接暴力的遍历一张表去寻找需要的数据,效率非常低下,访问的类型有很多,效率从最好到最坏依次是:system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
type 访问方式
possible_key 显示可能用到那些索引
key 实际用到索引
rows 预估行数
extra 额外信息 例如排序类型 、覆盖索引
执行计划
哈希表
B+树
了解常用数据结构 哈希表、二叉树、红黑树、B树、B+树
索引结构
随机IO变为顺序IO
优点
快速匹配where子句
MySQL会排除多余数据扫描,总会命中行数最少的索引
用途
主键
唯一
普通
全文
组合
分类
回表
覆盖索引
最左匹配
索引下推
技术名词
全值匹配
匹配最左前缀
匹配列前缀
匹配范围
精确匹配某一列并范围匹配另一列
只访问索引查询
索引匹配方式
索引基础知识
memory 存储引擎
基于哈希表实现,只有精确匹配才能被查找
只存储hash值,数据紧凑,索引非常快
只包含hash值,不进行字段存储,不是顺序存储,无法进行排序
不支持部分列存储
考虑哈希冲突情况,冲突比较多会造成数据列维护不方便,代价也很高
限制
当需要存储大量的URL,并且根据URL进行搜索查找,如果使用B+树,存储的内容就会很大select id from url where url=\"\"也可以利用将url使用CRC32做哈希,可以使用以下查询方式:select id fom url where url=\"\" and url_crc=CRC32(\"\")此查询性能较高原因是使用体积很小的索引来完成查找
使用案例
hash索引
包含多个列作为索引,需要注意的是正确的顺序依赖改索引的查询,同事满足最左匹配原则
a
a = 3
a 、 b
a=3 and b=5
a=3 and b=4 and c=5
没使用索引
b=3 or c=4
a = 3 and c=4
a = 3 and b>10 and c = 7
a = 3 and b like '%1%' and c = 7
组合索引
可以把相关数据保存在一起
数据访问更快,不需要另外查找
覆盖索引扫描可以直接到叶节点
聚簇数据极大的现在了数据IO的扩展性
插入速度验证依赖插入书序,按照主键插入顺序最快
更新聚簇索引列代价很高,会强制将每个更新的行移动到新的位置
新插入行如果超过索引页大小,会导致页分裂的问题
全表扫描变慢
缺点
聚簇索引
非聚簇索引
聚簇索引与非聚簇索引
如果一个索引包含所有需要查询的字段的值,称之为覆盖索引
不是所有类型的索引都成为覆盖索引,覆盖索引必须要存储索引列的值
不同存储引擎实现索引的方式不同,不是所有引擎都支持覆盖索引,memory不支持
介绍
索引条目通常小于数据行大小,如果只需要读取索引,会极大的减少数据访问
IO密集型
索引按照顺序存储的,对IO密集型范围查找会比随机查找快很多
InnoDB是聚簇索引,覆盖索引效率特别高
优势
案例
索引列进行扫描时,尽量不要用表达式,将计算放到业务层而不是数据层
尽量使用主键索引,避免发生回表
使用前缀索引
使用索引扫描进行排序
范围列可以用到索引 但是只能用一列索引
强制转换可能会导致全表扫描
更新十分频繁的操作不宜建立索引
索引列不能为空
表进行连接时候,最好不要超过三张表,因为join需要的字段数据类型必须一致
能使用limit时候尽量使用limit limit 限制输出
单表索引建议控制在5个以内
组合索引字段不应该超过5个
优化细节
索引监控
索引优化简单案例
索引优化
网络
CPU
IO
上下文切换
系统调用
生成统计信息
1:分析存储引擎
2:读锁、写锁
锁等待时间
查询慢的原因
大数据量
加载多余数据
优化数据访问
查询缓存
执行过程的优化
重新定义关联查询顺序
外连接转内连接
等价变换规则、简化SQL
带条件 , 索引分组
优化 count min max
索引覆盖扫描
子查询进行优化、进行缓存
两个列的值关联,MySQL可以进行参数传播
等值传播
MySQL 优化机制
第一次数据读取是将需要排序的字段读取出来,然后进行排序,第二次是将排好序的结果按照需要去读取数据行。这种方式效率比较低,原因是第二次读取数据的时候因为已经排好序,需要去读取所有记录而此时更多的是随机IO,读取数据成本会比较高两次传输的优势,在排序的时候存储尽可能少的数据,让排序缓冲区可以尽可能多的容纳行数来进行排序操作
两次传输排序
先读取查询所需要的所有列,然后再根据给定列进行排序,最后直接返回排序结果,此方式只需要一次顺序IO读取所有的数据,而无须任何的随机IO,问题在于查询的列特别多的时候,会占用大量的存储空间,无法存储大量的数据
一次传输排序
当需要排序的列的总大小超过max_length_for_sort_data定义的字节,mysql会选择双次排序,反之使用单次排序,当然,用户可以设置此参数的值来选择排序的方式
算法优化
排序优化
查询优化
分区表
服务器参数设置
MySQL集群
读未提交
读已提交
可重复读
串行化
隔离级别
面试
SQL调优
操作系统会以进程为单位,分配系统资源(CPU时间片、内存等资源),进程是资源分配的最小单位。
进程
线程,有时被称为轻量级进程(Lightweight Process,LWP),是操作系统调度(CPU调度)执行的最小单位。
线程
协程,是一种比线程更加轻量级的存在,协程不是被操作系统内核所管理,而完全是由程序所控制(也就是在用户态执行)。这样带来的好处就是性能得到了很大的提升,不会像线程切换那样消耗资源。
协程
Thread
Runnable 接口
Callable
线程池
Future 接口
开启一个线程
新建
NEW
准备
Ready
Runnable
Runnable 运行
wait
join
park
等待
synchronized
阻塞
Block
结束
Teminated
Thread Status 线程状态(JVM管理)
基本概念
睡眠
sleep
线程谦让一下,暂时离开一会 , 进入等待队列中
Yield
调度其他线程的join方法相当于其他线程,当前线程等待
等待、需要用nitify方法唤醒
基本方法
无锁
记录线程ID 高效率
偏向锁
多线程调用后,一直在等待资源释放
自旋锁
插入阻塞队列,释放资源 成为等待状态
重量级锁
锁升级
可重入锁,指的是以线程为单位,当一个线程获取对象锁之后,这个线程可以再次获取本对象上的锁,而其他的线程是不可以的。synchronized 和 ReentrantLock 都是可重入锁。
可重入
锁粒度越小约好
主线程和自身线程 副本进行同步、MESI CPU的缓存一致性协议
保证多线程可见
单例模式双重检测Double Check Lock
1:申请内存
2:设置初始值
3:进行赋值
new Object()
禁止指令重排序
Volatile
期望值 期望是0
更新值 更新为1
三个值
CPU原语支持
Compare And Set
单例 静态unsafe 直接对内存地址进行操作 native 修饰的方法
unsafe类可以读写一个类的属性,即便是私有的也可以读写
Volatile 读写
有序性读写
CAS
线程调度
内存屏障
底层都是unsafe 相当于C 、c++ malloc free new delete
Atomic***
1 2 1 操作后加版本号记录
ABA 问题
结果: longAdder > atomic > Syonchorized
longAdder 分段锁
Atomic CPU 原子操作
synchronized CPU申请锁
案例:1000线程分别对 atomicInt synchronized LongAdder 相加 10000次
CAS 无锁优化 资源 乐观锁
可重入锁
synchronized 功能类似 但是必须手动释放锁 在final 里面
尝试申请锁
tryLock
打断加锁
lock Interruptibly
new ReentrantLock(true);
true 为公平锁、 默认为非公平锁
ReentrantLock
计数器 线程阻塞
减一操作
countDown
等待、阻塞
await
等待所有线程结束才进行下一步
CountDownLatch
满人发车、装载完成后开始执行
复杂操作、访问数据库、网络、文件 顺序执行 效率很低 并发执行但是可以
限流 -- 令牌桶 Guava RateLimiter
CyclicBarrier
共享锁、排他锁
static ReadWriteLock readWriteLock = new ReentrantReadWriteLock(); static Lock readLock = readWriteLock.readLock(); static Lock writeLock = readWriteLock.writeLock();
ReadWriteLock
信号量、允许同时执行的线程数
取的信号、没取到会进行阻塞
s.acquire();
释放信号
s.release();
Semaphore
LockSupport.park();
LockSupport.unpark(t);
LockSupport
CAS+ volatile
AQS 读源码
互斥条件、同一时间只能一个线程去获取资源
不可剥夺条件、一个资源被占有,不可被其他线程剥夺
请求和保持条件、等待过程不会释放占有资源
循环条件等待、多个线程互相等待
产生原因
加锁
AQS
解决方案
死锁
实现Runnable 实现run方法 无返回值 无法抛出异常
集成Thread类 执行start方法开始
实现Callable call() 方法带返回值
线程池创建线程
多线程几种创建方式
同一个线程资源竞争
不会阻塞线程,线程会一直重复执行某个相同操作,但是一直失败
活锁
读写锁(读的时候一直等待,产生饥饿)
饥饿
状态
加锁,保证你的操作都是原子性操作
竞态条件
线程安全活跃状态
wait 和 sleep
进程和线程的区别
WAIT
线程生命周期
面试问题
多线程高并发
数据节点保持一致,多节点数据值是一致的
主从异步复制
主从半同步复制
多数派写
弱一致性、保证最终一致性
主从同步复制
强一致性、数据时刻保持一致
一致性
前提概要
向集群发出议案,设置自己为leader 提议内容格式编号n内容value)
Proposer
对议案进行投票,达到多数派提议认可时提议才会被接受
Acceptor
对提议记录,对一致性没有任何影响
Learner
角色
1:prepare(N)请求
2:promise(N-Value)返回
prepare阶段
1:accept(N-value)请求
2:accepted 返回
accept阶段
阶段
先进行选举,产生最新leader,后续选举互动返回Leader
多个节点进行选举,未产生leader时,选则最大的N,直到过半accepted返回成功,在进行Leader 同步
图解
一次选举被拒绝会产生更大的N,如果两个Proposer发现自己的N小会进行更高N的选举,这样就会导致死循环,产生活锁
设置最大请求次数,超过请求次数便不再请求,请求时间依次递减直至不请求
二进制指数退避算法
每次选举请求经过两轮请求返回
效率低
实现困难
优化缺点
视频详解
集群所有消息均可靠,内部通信没有叛徒
前提条件
Paxos算法
CAP原则又称CAP定理,指的是在一个分布式系统中,一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)。CAP 原则指的是,这三个要素最多只能同时实现两点,不可能三者兼顾。
CAP原则
统计请求的延迟+请求次数,按照延迟时间进行升序排序,第99%位为最低满足延迟
计算 TP90、TP95 和 TP99 等水位线的方法
银行家算法
分布式算法
本地事务
2pc
3pc
TC 事务协调者
TM 事务管理者、发起者
RM 资源管理者、每个参与事务的微服务
基础概念
1:请求
执行业务数据
日志记录操作前、操作后数据记录
回滚日志记录
提交本地事务
释放资源
2:RM1
RM1 操作相同 共同提交给TC
3:RM2
一阶段
正常:TC 进行确认操作、提交 删除日志记录
依赖日常记录进行回滚、不会滚日志不删除
异常: 回滚
二阶段
本地锁+全局锁 1:获取本地锁2:执行sql3:获取全局锁4:提交本地事务5:释放本地锁
锁
AT 模式
Try
confirm
cancel
TCC 模式
SEATA
TX
分布式事务
Kafka是一个分布式的基于发布、订阅的消息系统,有着强大的消息处理能力,相比与其他消息系统,具有以下特性:快速数据持久化,实现了O(1)时间复杂度的数据持久化能力。高吞吐,能在普通的服务器上达到10W每秒的吞吐速率。高可靠,消息持久化以及副本系统的机制保证了消息的可靠性,消息可以多次消费。高扩展,与其他分布式系统一样,所有组件均支持分布式、自动实现负载均衡,可以快速便捷的扩容系统。离线与实时处理能力并存,提供了在线与离线的消息处理能力
优点简介
kafka 分布式消息系统,将消息直接存入磁盘,默认保存一周
broker kafka节点、没有主从挂你,依赖ZK进行协调。broker负责消息读写存储,一个broker可以管理多个partition
topic 一类消息总称,一个消息队列,topic是有partition组成的,指定创建partition数量
partition 组成topic的单元,每个partition有副本,由broker来进行管理
Producer 消息的生产者,自己决定向哪一个partatition中取生产消息,两种机制:hash、轮询
consumer 消息消费者,consumer 通过Zookeeper去维护消费者偏移量,consumer有自己的消费组,不同的组之间消费同一个topic的数据互不干扰,同一个组内的topic消费只产生一次
组件
依赖 ZK 进行分布式协调 , 环境搭建完成后会通过zc 来进行broker管理
每个Topic分为多个partition,每个分区存储不同的消息,消息进入partation时候回从0开始维护一个offset,并保证分区上唯一,消息在分区上的顺序由offset保证,消息在一个分区内是有序的
Topic
分区在逻辑上对应一个日志(Log),物理上对应的是一个文件夹。到kafka log文件夹去看,效果如下
消息写入分区时会进行分片,默认没片大小为1G ,实际存储为三个文件 .index .timeindex .log
日志索引
log
主体与日志
副本所在节点需要与ZooKeeper维持心跳。从副本的最后一条消息的offset需要与主副本的最后一条消息offset差值不超过设定阈值(replica.lag.max.messages)或者副本的LEO落后于主副本的LEO时长不大于设定阈值(replica.lag.time.max.ms),官方推荐使用后者判断,并在新版本kafka0.10.0移除了replica.lag.max.messages参数
ISR集合 -- 连通性&活跃性 的节点
高水位 High Watermark
LEO(Log End Offset)
副本文件
1:默认为1,表示在ISR中的leader副本成功接收到数据并确认后再发送下一条消息,如果主节点宕机则可能出现数据丢失场景,详细分析可参考前面提到的副本章节。0:表示生产端不需要等待节点的确认就可以继续发送下一批数据,这种情况下数据传输效率最高,但是数据的可靠性最低。-1:表示生产端需要等待ISR中的所有副本节点都收到数据之后才算消息写入成功,可靠性最高,但是性能最低,如果服务端的min.insync.replicas值设置为1,那么在这种情况下允许ISR集合只有一个副本,因此也会存在数据丢失的情况。
ACK
唯一标识:判断某个请求是否重复,需要有一个唯一性标识,然后服务端就能根据这个唯一标识来判断是否为重复请求。
记录已经处理过的请求:服务端需要记录已经处理过的请求,然后根据唯一标识来判断是否是重复请求,如果已经处理过,则直接拒绝或者不做任何操作返回成功。
幂等
生产者
消费组订阅主题下的每个分区只会分配给消费组中的一个消费者。group.id标识消费组,相同则属于同一消费组。不同消费组之间相互隔离互不影响。
消费组
自动提交
基于一条记录
基于partition (推荐,因为kafka的offset是基于partition维护的)
基于一次拉取数据
手动提交
偏移量 offset
消费者
kafka
数据保存在内存中
Leader 挂掉、可快速选举、快速修复
集群 主从复制、分片处理增、删、改 只能在主节点、查询能在其他节点
并且是数据二进制安全的
节点存数据很少 1M
客户端链接维护了一个session 通过session可以判断持续时间
数据模型、目录树
顺序一致性、客户端链接是顺序的
原子性操作
最终一致性
后面数据只能1M 大小 并且是二进制安全的 不会乱码
-S
-E 临时节点
create /xxoo “”
cZxid 创建事务ID
ctime 创建时间
mzxid 修改事务ID
mtime 修改时间
pzxid 子节点最后修改的事务id
cversion 子节点版本号
dataVersion 数据版本号
aclVersion 权限版本号
ephemeralOwner 创建临时节点的回话sessionID
dataLength 节点数据长度
子节点数量
Children
ls -s
ls /
基本命令
主节点,不参与计算,发号命令
Leader
选举
Follow
增加查询能力
Observer
多节点配置
zoo.cfg
扩展性
快速恢复:攘外必先安内
对外: 一致性、可靠性
内部 Paxos 协议选举
可靠性
特征
Paxos 协议精简版-- 原子广播协议
1:客户端创建节点2:Follow 转 Leader3:Leader 创建zxid -- 内存中维护数据,并且维护发送队列4:Leader 写入Follow 日志中,磁盘写日志 5:Follow 回复写成功6:过半Follow 回复OK 触发自身写操作 -- Follow 也写内存
zab
事件:Create\\delete\\change\\children
监听后执行callback
事件监听\\观察
new zk 时候创建的时间,和session、path 没关系
两类:
callback
Zookeeper
加载JAVA_HOME/jre//lib/rt.jar 里面的子类
BootStrap类加载器
加载JAVA_HOME/jre/*.jar
Extension类加载器
加载classpath中指定jar包以及目录中class
Application类加载器
用户开发者自定义、如Tomcat、JBoss 会根据J2EE规范自行实现classloader
Custom自定义类加载器
加载
字节码校验器会检查生成的字节码是否正确
验证
对静态变量分配内存以及默认值分配
解析或识别是从运行时常量池的符号,引用中动态具体值的过程
识别
链接
类或接口的初始化,由执行类或接口初始化方法构成。这里所有的静态变量与原来的值将被指派,静态块被执行
初始化
类装载子系统
存储已被虚拟机加载的类、常量、静态变量、编译后的代码等数据
JVM8已经用MetaSpace完全代替方法区
方法区 Method Area 持久代
存放内存实例的区域、几乎所有的对象实例都分配在内存。存储的数据不是线程安全的,堆和常量池空间不足会引发outofMemory
Heap 堆
每一个线程创建一个单独的运行时堆栈,对于每一个方法调用创建一个称为栈内存栈帧,所有局部变量被创建在栈内存中
VM虚拟机栈
与虚拟机类似,但是相关联的是计算机本地方法,Native方法
本地方法区 Native Method Stack
程序具体执行的计算机指令,当前指令执行完毕后,会更新下一个指令
程序计数器
线程区
运行时内存
解释器
中间代码生成器
代码优化器
目标代码生成器
探测分析器
即时编译器 JIT
收集和删除未引用的对象。可以通过System.gc 触发垃圾回收,但不能保证执行。JVN垃圾回收对象是已创建的对象
GC
Java执行引擎
与本机方法库进行交互,并提供引擎所需要的机器类库
本地方法接口 JNI
计算机提供的方法库
本地方法接库
内存模型 简述概况
1:通过classloader 在classpath中读取 class文件,然后存入内存2:将字节流锁代表的静态存储结构转到方法区的运行时数据结构3:内存生成该类的 java.lang.class 对象,作为方法区这个类的各种数据的访问入口
.class 通过二进制字节流读入JVM中
确保文件格式、元数据格式、字节码格式、符号引用格式正确
静态文件在方法区分配内存,设置默认值
虚拟机将常量池内的符号引用替换为直接引用
解析
类加载过程最后一步,主要根据程序中的赋值语句主动为类变量赋值,如果有集成关系,先初始化父类,再子类
类加载过程和初始化过程
堆内存划分
一个栈帧包括局部变量表、操作数栈、动态链接、返回地址
栈帧
一组变量值存储空间、用于存放方法参数和方法内部定义的局部变量
变量槽 -- 基本数据类型
对象实例引用
动态链接
8中数据类型、对象引用类型、引用地址
局部变量表
当一个方法刚刚开始执行的时候,这个方法的操作数栈是空的,在方法的执行过程中,会有各种字节码指令往操作数栈中写入和提取内容,也就是出栈/入栈操作。例如,在做算术运算的时候是通过操作数栈来进行的,又或者在调用其他方法的时候是通过操作数栈来进行参数传递的。举个例子,整数加法的字节码指令iadd在运行的时候操作数栈中最接近栈顶的两个元素已经存入了两个int型的数值,当执行这个指令时,会将这两个int值出栈并相加,然后将相加的结果入栈。
操作数栈
返回地址
虚拟机栈(线程私有)
与虚拟机栈发挥作用相似,不过是为虚拟机创建资源的,内部调用C++方法活用native修饰的方法
本地方法栈(线程私有)
一个较小的区域进行程序指令登记,程序执行字节码的行号指示器
程序计数器(线程私有)
存储虚拟机加载的类信息、常量、静态变量、编译后的代码。1.8以后已经用Metaspace完全替代了永久区,并且不在JVM中存储而存储到本地内存
永久代(公共区域)
虚拟机启动时创建,用来存放对象实例,所有对象实例都在此分配内存,存储数据不是线程安全的,堆和常量池空间不足容易引起oom
Heap堆 (公共区域)
运行时数据区
即时编译器
执行引擎
内存模型
YGC 新生代堆
FGC 全堆
GC 垃圾回收(Java堆)
垃圾回收算法
面对生产频繁GC处理方式
jmap
jstat
定位工具
JVM
可以参考ZK\\Redis
分布式锁
物理层
数据链路层
网络层
传输层
会话层
表示层
应用层
OSI 七层网络模型
用户空间
传输控制层
链路层
内核空间
网络请求基础
backLog 设置可以快速拒绝服务快速响应
accept 队列 -- 等待程序队列的链接配置backLog 大小限制,不会被程序取走 (代码可以设置)
得到客户端建立的链接
监听队列 -- Listion
消息传输在计算机内核中程序员无感知
accept 得到的 client 得到的
连通队列 -- eatablishd
socket : 请求队列 queueIO 就是程序对socket-queue的包装
Server.accept() 进行阻塞 等待返回
BIO
Server.accept() 立刻返回 0 , 1
NIO
循环IO驱动方式
select
循环
poll
时间驱动
epoll
和内核调用后才可以知道是否有时间,然后再进行队列
多路复用
IO 模型
内核增强了 select pollepoll
机制: 多路复用 、 阻塞、 非阻塞都是计算机内核提供的机制
nc
端口监听
HTTP + SSL = https
CA 证书就是 公钥和私钥、机构颁发一个证书,公钥(用户的信息)和私钥用户请求 证书的公钥, 私钥在服务器,进行非对称加密
CA 证书 非对称加密
对称加密 是双方秘钥生成的
HTTP HTTPS
客户请求---> 返回证书公钥
客户端浏览器 校验证书是否有效
客户端将加密后的秘钥发送给服务端
用私钥加密的信息发给客户端 进行双向认证
https 握手方式
公钥 == 私钥 双方用一个秘钥进行加解密
对称加密
加密和解密用不同秘钥公钥加密的信息,只有私钥才能解开私钥加密的信息,只要公钥才能解开
非对称加密
加密方式
1:服务没启动
2:Socket 队列满了
Connection Refused
状态: syn Send
1:client 发送 sync
状态: syn - receiver
2:Server 发送 synv -ack
状态为连接状态
3: client ACK
如果队列满了 就会Connection Refuse
三次握手是内核层次的过程握手成功进入 连通队列
三次握手
client 状态就是 fin-wait1
1:客户端 断开
服务器状态是 close - wait
2:服务端 断开 - ack
服务器状态
3:服务器 断开
4:客户端 断开 ack
四次分手
半链接过多
DDOS 攻击
协议
Proto
接受
REcv
发送
send
本地端口
LocalAddress
链接端口
Foreign Address
status
netstatus
tcp 只是帮你建立链接 具体的是应用层协议
开启了是同步复用链接 多次请求响应
http 1.0 1.1 没有开启keepalive一个连接只负责一次请求相应
TCP 是长链接吗?
BIO \\ NIO 都是同步的
同步阻塞、同步非阻塞
程序+内核 协调工作内核:三次握手TCP 传输时候 分包的
在包头部添加数据包的长度
固定长度 发送,会自动拆分
数据包设置边界
处理
粘包、拆包
面试突击
计算机网络
JAVA技术栈
0 条评论
回复 删除
下一页