Java技能树
2022-11-02 15:15:22 46 举报
AI智能生成
技能树
作者其他创作
大纲/内容
spring
循环依赖
aop
beanfactory factorybean
spring事务
事务传播行为
事务隔离级别
事务超时时间
Spring mvc流程
过滤器 和拦截器
常见设计模式
@Resource 和 @Autowired
spring 作用域以及bean的生命周期
缓存
缓存与数据库双写一致性
先更新数据库,后删除缓存(Cache Aside Pattern)
删除缓存失败后,需要引入MQ等进行补偿,达到最终一致性
缓存穿透
概念:恶意攻击查询一个肯定不存在的key,相当于从缓存中穿过了,
解决方案:0、非法请求校验 1、把查询为null的key也在缓存中缓存起来,并且设置过期时间2、布隆过滤器先进性过滤
缓存击穿
概念:某个热点key失效后,大量请求打到数据库
解决方案
互斥锁
软过期+互斥锁
静态数据
缓存雪崩
概念:1、缓存中大量的key同时失效,导致大量请求打到数据库2、缓存服务宕机
解决方案1:分散过期时间、缓存key的过期时间增加随机数,防止同一时间过期
解决方案2:提前做好系统的演练压测,发现性能瓶颈,预估合适的系统存储和计算容量。
解决方案3:缓存高可用(双缓存redis和tair) + 数据库限流
redis基本数据类型使用场景
string
简单的 KV 缓存
常用命令
get
set
底层实现:类似ArrayList,动态字符串采用预分配的方式减少内存频繁分配
hash
缓存结构化数据(比如对象),通过redis可以直接操作里面的属性
常用命令
hset
hget
底层实现: hash表
list
有序列表,存储列表型数据如:粉丝列表,评论列表
常用命令
lrange:可以用来分页,高性能
lpush,rpop:可以作为简单的消息队列使用
底层实现:类似于linkedList,底层实现就是一个双向链表或者ziplist
set
无序集合,自动去重。可以用来做分布式部署的应用全局去重
可以基于set做交集,并集,差集运算。比如粉丝列表做交集得到共同的粉丝
常用命令
sadd
smembers
sismember(是否包含元素)
srem(删除元素)
sinter(求交集)
sunion(求并集)
sdiff(求差集)
底层实现:有序整数集合intset 或者 字典dict
sorted set
排序的set,去重但可以排序,进去的时候给一个分数,自动根据分数排序
常用命令
zadd
zrevrange
zrank
底层实现:压缩列表ziplist 或者 跳表
redis过期策略
定期删除
惰性删除
内存淘汰机制
allkeys-lru
手写一个 LRU 算法
java中的LinkedHashMap是如何实现LRU的
allkeys-random
noeviction
volatile-lru
volatile-random
volatile-ttl
redis热点key问题
热点key的发现
二级缓存
需要解决多级缓存间数据一致性问题,可以引入ZooKeeper等中间件协调通知
热点key拆分(增加随机数),让热点数据分布在多个节点存储
redis的高并发与高可用
主从架构(master-slave)
基于主从架构部署的redis,可以通过哨兵集群实现高可用
一主多从,主负责写,并且将数据复制到其它的 slave 节点,从节点负责读。主从架构可以支撑高并发
redis原生支持的集群模式(redis cluster)
在多台机器上,部署多个 redis 实例,每个实例存储一部分的数据,同时每个 redis 主实例可以挂 redis 从实例。如果 redis 主实例挂了,会自动切换到 redis 从实例上来
针对海量数据+高并发+高可用场景
节点间内部通信机制
gossip协议
集中式zookeeper
分布式寻址算法
哈希
一致性哈希+虚拟节点
哈希槽
持久化
RDB
对 redis 中的数据执行周期性的持久化
AOF
每条写入命令作为日志,以 append-only 的模式写入一个日志文件中,在 redis 重启的时候,可以通过回放 AOF 日志中的写入指令来重新构建整个数据集
混合策略
用 AOF 来保证数据不丢失,作为数据恢复的第一选择; 用 RDB 来做不同程度的冷备,在 AOF 文件都丢失或损坏不可用的时候,还可以使用 RDB 来进行快速的数据恢复。
为啥 redis 单线程模型也能效率这么高
纯内存操作
核心是基于非阻塞的 IO 多路复用机制
一次redis通讯过程
C 语言实现
单线程反而避免了多线程的频繁上下文切换问题,
预防了多线程可能产生的竞争问题
redis的并发竞争问题
分布式锁
时间戳
mysql
索引
索引模型
哈希
有序数组
二叉搜索树(BST)
平衡二叉树(AVL)
N叉树
B+树
B+树与B树区别
树的层高
主键索引(聚簇索引)
在InnoDB中,表数据根据主键顺序以索引形式存储(索引组织表)
主键索引的叶子节点存的是整行数据
非主键索引(二级索引)
非主键索引的叶子节点存的是主键的值
基于非主键索引的查询:先通过非主键索引找到主键的值,再根据主键值去主键索引查整行表数据,这个过程叫做回表
索引失效的场景
索引优化
建议使用自增主键
覆盖索引
索引设计原则
执行计划
SQL优化
锁
锁范围
全局锁
表级锁
表锁
元数据锁(MDL)
行锁
由存储引擎实现
MyISAM不支持行锁,只能使用表锁
InnoDB支持
记录锁(Record Locks)
间隙锁(Gap Locks)
next-key锁(Next-Key Locks)
插入意向锁
两阶段锁协议
结论:行锁是在需要的时候才加上,但是要在事务结束后才释放
事务优化:如果事务中需要锁多个行,要把最可能造成锁冲突、最可能影响并发度的锁往后放
死锁问题
锁等待超时(默认50s)
死锁检测(默认开启),耗费大量CPU资源
如何解决热点行更新的性能问题
死锁问题排查
并发死锁insert
delete、insert
mvcc
每个事务有一个唯一的事务 ID,叫作 transaction id。它是在事务开始的时候向 InnoDB 的事务系统申请的,是按申请顺序严格递增的。
每次事务更新数据的时候,都会生成一个新的数据版本,并且把 transaction id 赋值给这个数据版本的事务 ID,记为 row trx_id
一致性读视图
当前读
update语句
select * for update
select * lock in share mode
为什么表结构不支持“可重复读”
关键字:隐式字段、undo 日志、版本链、快照读&当前读、Read View
事务隔离级别与读现象
读未提交
读现象:脏读、幻读、不可重复读
InnoDB实现:直接读取记录最新值
读已提交
读现象:幻读、不可重复读
InnoDB实现:每个SQL语句执行前会更新视图
可重复读
SQL标准读现象:幻读
InnoDB读现象:不产生幻读,因为加了间隙锁,防止在查询范围内新增数据
InnoDB实现:事务启动阶段创建视图,整个事务期间都使用该视图
每条记录在更新的时候都会同时记录一条回滚操作(undolog)。
记录的最新值通过回滚操作可以得到前一个状态的值。
同一条记录在系统中可以存在多个版本(MVCC)。
记录的最新值通过回滚操作可以得到前一个状态的值。
同一条记录在系统中可以存在多个版本(MVCC)。
尽量避免长事务
串行化
采用加锁方式实现
日志系统
redolog(重做日志)
InnoDB引擎实现
更新一条记录的时候,InnoDB引擎会先把记录写到redolog里面,并更新内存,更新操作就完成了。后续引擎会异步写磁盘
redolog文件固定大小,写到末尾又回到开头循环写
使数据库具备crash-safe能力
redolog是物理日志,记录的是“在某个数据页上做了什么修改”
binlog(归档日志)
Server层实现
binlog是逻辑日志,记录的是这个语句的原始逻辑,比如“给ID=2这行数据的c字段加1”
三种格式
statement格式
记录的是SQL语句
row格式
记录的是更新前和更新后的行内容,是两条
Mixed格式
statement格式+row格式
binlog是追加写入。指的是binlog文件写到一定大小后会切换到下一个,不会覆盖以前的日志
更新操作的两阶段提交
写入redolog,事务处于prepare状态-->写入binlog-->事务commit
redolog和binlog都可以用来表示事务的提交状态,两阶段提交为了保证这两个状态保持逻辑上的一致
乐观锁
事务特性
原子性
undo log实现
一致性
数据库的一致性理解
分布式一致性、一致性hash
隔离性
写隔离:锁机制
读隔离:MVCC
持久性
redo log实现
主从延迟问题
主从复制流程
分库分表问题
分表计算
大表问题
高可用部署方案
MHA
ORC
分表之后如何聚合查询?
select *
效率问题
不需要的列会增加数据传输时间和网络开销
失去了覆盖索引
容易写错 resultMap
项目
项目背景
组织架构问题
库有耦合
系统架构问题
服务职责定义不清晰
服务之间调用混乱
服务设计问题
设计混乱
数据模型设计问题
数据模型多套,底层能力不统一
接口耗时优化
资源问题
链路过长
外部依赖耗时长
项目挑战
项目非常复杂
难以理解
多
系统个数
代码量
接口多
模型多
无序
服务调用
代码分层
下游依赖
难以预测
不知道出什么问题
不知道业务诉求在哪怎么配合
业务网关
安全防护:鉴权、日志脱敏、数据加解密等
协议适配:泛化调用
流量管控:限流、降级、熔断、路由
资源管理:线程池隔离、上下文管理
业务认知
先用后付支付
先用后付垫付
先用后付垫付还款
承担角色
制定架构演进路线
系统整体的架构设计
全局协同工作
通用能力建设
计费系统
重复支付问题
掉单导致重复支付
多渠道支付导致重复支付
方案
生成支付单加锁+支付回调加锁
收银台业务特点
业务重要性高:业务交易最后一环,一旦出问题,就会影响公司各业务线的交易转化,造成新闻级事件;
体验要求高:工具的便捷性要求高,其实就是体验要求高,体验不好,产生客诉,比如支付到账延迟等问题,对于支付来说客诉产生的影响要远大于单损产生的影响;
业务精细化发展效率要求高:支付是工具,既要服务好公司各业务线的工具诉求,又要支撑好支付业务的增长诉求,还要协同金融信贷用户增长、流量变现等,对效率有较高的要求,然而我们的效率还比较低,双周交付率、发版周期等相对比较低;
策略
系统要稳
体验要好
性能方面:核心接口响应耗时保持稳定(500ms以下),同时给更多的时间到算法进行最有决策
客诉方面:客诉越少,说明认可度越高,体验也就相对越好
成功率方面:支付成功率尽可能的高,阻塞支付的问题越少越好
迭代要快
分布式
分布式锁
需要解决的问题
(分布式锁要具备的特性)
保证分布式互斥性:多个机器的多个线程同时加锁,只有一个成功
高可用
防止死锁
支持阻塞加锁与非阻塞加锁
实现方案
基于数据库唯一索引
表设计:方法名(唯一索引),创建时间,失效时间,
加锁的线程信息(机器标识+线程标识)
如何实现上述的分布式锁特性
高可用:主备切换
防止死锁或解锁失败问题:表字段增加失效时间,开启定时任务扫描失效后的数据并删除
非阻塞加锁:创建记录失败则立即返回加锁失败
阻塞加锁(可以带超时时间):循环重试,直到创建记录成功或超过最大等待时间
基于Redis的setNX命令实现
可以直接使用Redisson框架
缺点
实现复杂,需要考虑超时,误删,原子性等问题
可靠性不如Zookeeper
master节点宕机后,锁信息不能立刻同步到slave节点,出现并发问题
优点
性能高
问题1:如果第一个线程获得锁执行业务直到redis的key失效也没有执行完毕,那么有可能新的线程会获得锁出现并发问题
成功加锁的线程需要开启守护线程来为key延长失效时间,
问题2:redis的key过期后业务代码还没有执行完毕,新的线程加锁后,第一个线程解锁的时候需要判断是否自己加的锁,防止误删
方案一
加锁的时候,value存储的是线程标识(比如uuid+线程ID)
解锁的时候通过LUA脚本执行先判断value是否本线程,如果是再删除的逻辑,保证原子性
方案二
加锁的时候,在程序中使用ThreadLocal包装一个map,map的key是锁的key,value存储加锁的时间和锁的失效时间
解锁的时候,通过ThreadLocal获取到锁的失效时间,判断如果是超过了失效时间,不执行删除命令
基于Zookeeper临时顺序节点实现
可以直接使用开源框架Curator
缺点
性能上没有缓存服务那么高
优点
可靠性高
有锁等待队列功能,提高了抢锁效率
实现原理概要
分布式事务
两阶段
TCC
本地地消息表
分布式ID
leaf发号器
号段模式
snowflake模式
时间戳+工作机器id+序列号
时钟回拨问题:5ms内阻塞等待2倍时间,否则就抛异常
如何保证接口幂等
数据库层面
悲观锁 for upfate
乐观锁 cas
唯一索引幂等表
缓存层面
分布式锁
RPC框架
dubbo
框架图,流程
spi
概念
Service Provider Interface,是一种服务发现机制
SPI 的本质是将接口实现类的全限定名配置在文件中,并由服务加载器读取配置文件,加载实现类。这样可以在运行时,动态为接口替换实现类。
正因此特性,我们可以很容易的通过 SPI 机制为我们的程序提供拓展功能。
java原生的SPI实现
在META-INF/services文件夹下创建以接口全限定名为名称的文件
文件内写接口的实现类的全限定名,可以指定多个,一行写一个
用ServiceLoader.load方法,传入接口的类型即可创建对应的实现类对象
dubbo的SPI实现
配置文件需放置在 META-INF/dubbo 路径下
通过键值对的方式进行配置,可以指定多个,一行写一个
接口上标注 @SPI 注解
用ExtensionLoader.getExtensionLoader方法,传入接口的类型即可获得所配置的实现类;
extensionLoader.getExtension方法传入key即可获得对应的实现类对象
extensionLoader.getExtension方法传入key即可获得对应的实现类对象
负载均衡
Random LoadBalance 权重随机
RoundRobin LoadBalance 轮询策略
LeastActive LoadBalance 最少活跃调用数
ConsistentHash LoadBalance:一致性Hash策略
集群容错
failover 失败重试
failfast 快速失败,非幂等的写操作
failsafe 安全失败,啥也不干通常用于审计日志
forking 并行调用
Broadcast Cluster 广播调用
超时重试
并发数控制与限流
信号量控制并发数
每个service维护一个计数器,在指定时间间隔内控制最大请求数。TpsLimitFilter内实现,方式简单,不能应对突发大流量。限流算法包括令牌桶等
如何自己实现一个RPC框架
thrift
限流
计数器法
固定窗口
滑动窗口
漏桶算法
令牌桶算法
系统设计
秒杀系统设计
高性能
动静分离
数据拆分
静态缓存
热点优化
热点发现
热点隔离
热点隔离
系统优化
一致性
库存问题
预扣库存
下单减库存
付款减库存
性能问题
高并发读
高并发写
高可用
流量削峰
答题
排队
过滤
planB
DDD领域驱动设计
支付业务理解
看支付流程,简单理解支付收单业务
Java
集合
list
ArrayList
如何实现的增删改查?
add(e)
扩容校验->将插入的值放到尾部->将 size + 1
add(index,e)
下标检查->扩容校验->数组拷贝->添加元素到指定位置->size+1
remove(index)
下标检查->通过数据拷贝实现指定下标后的元素前移->末尾元素设置为null,便于GC->返回被删除的元素
优缺点
优点
底层数组实现,支持随机访问,也就是根据下标访问元素效率高
添加与遍历元素效率高
缺点
线程不安全
可以用CopyOnWriteArrayList或Collections.synchronizedList()进行包装达到线程安全
插入与删除元素效率低,需要数组拷贝
根据元素的值查找元素效率低,需要遍历整个数组
数组的拷贝
Arrays.copyOf()
底层也是调用System.arraycopy()
System.arraycopy()
将原数组指定下标后指定长度的元素复制到新的数组的指定下标后
浅复制
ArrayList 中 elementData 为什么使用 transient 修饰?
LinkedList
基于双向链表实现
不支持随机访问,按下标访问需要遍历链表。但是因为是双向链表,所以实现中判断index在前半部分还是后半部分决定是从头遍历还是从尾遍历
插入与删除效率高,查找效率低
线程不安全
CopyOnWriteArrayList
读写分离思想
写时复制,有性能和空间上的损耗。只适合读多写少场景
不能保证实时一致性,只能保证最终一致性
map
HashMap
底层基于数组+链表+红黑树实现
put
通过key的hashCode在经过扰动函数得到hash值
扰动函数就是HashMap的hash方法,目的是为了防止一些实现较差的hashCode方法出现太多哈希冲突
JDK1.8的hash函数实现:
(h = key.hashCode()) ^ (h >>> 16)
JDK1.7的hash函数实现:
h ^= (h >>> 20) ^ (h >>> 12);
return h ^ (h >>> 7) ^ (h >>> 4);
通过(n-1)&hash得到在数组中的下标,n 数组长度
HashMap规定数组长度是2的幂次方
①计算机中位运算的性能高于取模运算,
②当n是2的幂次方的时候,二进制形式是最高位1,后边全是0
那么n-1二进制形式是最高位0,后边全是1,
③此时hash值对n取模等价于hash值和n-1做与运算
②当n是2的幂次方的时候,二进制形式是最高位1,后边全是0
那么n-1二进制形式是最高位0,后边全是1,
③此时hash值对n取模等价于hash值和n-1做与运算
如果定位到的下标没有元素则直接插入
如果定位到有元素则equals方法比较
JDK1.7
遍历以这个元素为头结点的链表,依次和插入的key比较,如果key相同就直接覆盖,不同就采用头插法插入元素
并发场景下会出现死循环问题
JDK1.8
有元素就和要插入的key比较,如果key相同就直接覆盖,如果key不相同,就判断p是否是一个树节点如果是用putTreeVal方法插入,否则遍历链表用尾插法插入
转红黑树
数组长度大于64且链表长度超过8
自平衡二叉查找树
查询时间复杂度O(logn)
扩容
加载因子,默认0.75
加载因子越小,表示数组中元素越密集,
哈希碰撞概率越高,导致查询数据效率降低
加载因子越大,表示数组中元素越稀疏,
哈希碰撞概率小,数组空间利用率较低
rehash
JDK1.8优化后,要么索引还是原位置,要么索引位置等于原索引+原数组长度
怎么判断是否需要改变下标
e.hash&oldCap
哈希冲突的解决办法
拉链法
冲突后,在数组的同一个坐标处形成链表
开放地址法
冲突时,按照某种方法继续探测哈希表中的其他存储单元,直到找到空位置为止
红黑树转链表
扩容时候元素个数小于6
删除的时候
LinkedHashMap
继承HashMap,由双链表实现
两种排序方式
按插入顺序排序
按访问顺序排序
可以实现LRU算法
ConcurrentHashMap
JDK1.7
分段锁+数组+链表
JDK1.8
node+CAS + synchronized
数据安全和并发性能之间处理
多线程扩容
红黑树
锁力度
size方法
竞争不激烈:cas 原子递增
数组维护元素个数
并发
并发编程三大特性
原子性
有序性
可见性
synchronized
使用
修饰静态方法:当前类的Class对象当锁
修饰普通方法:类的当前对象this对象当锁
修饰代码块:自定义锁,放synchronized括号内
原理
对于同步代码块,通过monitorenter与monitorexit指令实现
当线程执行到monitorenter的时候需要获取锁
当线程执行到monitorexit或异常退出前需要释放锁
对于同步方法,通过ACC_SYNCHRONIZED标识实现,是一种隐式声明,底层也是monitor锁
Monitor对象
每个对象都拥有自己的监视锁Monitor
监视器(JVM中由C++实现的ObjectMonitor对象)
_owner:指向持有ObjectMonitor对象的线程
_WaitSet:存放处于wait状态的线程队列
_EntryList:存放处于等待锁block状态的线程队列
_count:用来记录该线程获取锁的次数
当多个线程同时访问一段同步代码时,首先会进入 _EntryList 队列中,当某个线程获取到对象的 monitor 后进入 _Owner 区域并把 monitor 中的_owner 变量设置为当前线程,同时monitor中的计数器 _count 加1,即获得对象锁
若持有monitor的线程调用 wait() 方法,将释放当前持有的monitor, _owner 变量恢复为 null, _count减1,同时该线程进入 _WaitSet 集合中等待被唤醒
若当前线程执行完毕也将释放monitor(锁)并复位变量的值,以便其他线程进入获取monitor(锁)
JDK1.6锁优化
偏向锁
单线程重复加锁-解锁涉及cas操作会导致本地方法延迟,为了提高性能只需要对比是否偏向锁、偏向锁状态、偏向锁ID
轻量级锁
自旋锁
适应性自旋
锁消除
锁粗化
锁膨胀
volatile
使用场景
懒汉单单例doublecheck
停止线程
可以保证内存可见性和禁止指令重排序
ReentrantLock原理
CyclicBarrier
CountDownLatch
线程
interrupted,yield,join阻塞主线程
Java线程的六种状态
New:线程被创建后尚未启动
RUNNABLE(运行):包括了操作系统线程状态中的Running和Ready,也就是处于此状态的线程可能正在运行,也可能正在等待系统资源,如等待CPU为它分配时间片
BLOCKED(阻塞):线程阻塞于锁
WAITING(等待):线程需要等待其他线程做出一些特定动作(通知或中断)
TIME_WAITING(超时等待):该状态不同于WAITING,它可以在指定的时间内自行返回
TERMINATED(终止):该线程已经执行完毕
阻塞状态与等待状态的区别
阻塞状态是等待着获取到一个排他锁,进入阻塞状态都是被动的,离开阻塞状态是因为其它线程释放了锁,不阻塞了
进入synchronized block/method
等待状态是在等待一段时间或者某个动作的发生,
进入等待状态是主动的,调用这些方法会进入等待状态
进入等待状态是主动的,调用这些方法会进入等待状态
Object.wait
Thread.join
LockSupport.park
线程池
参数介绍以及工作流程饱和策略
阻塞队列
ArrayBlockingQueue
LinkedBlockingQueue
PriorityBlockingQueue
手写一个阻塞队列
基本常识
异常类型
关键字final,static
装箱拆箱
object通用方法
泛型
java异常
threadlocal
关键词
空间换时间
用法
set
thread threadLocal threadLocalMap entry 关系
开放寻址法、斐波那契算法
get
remove
常见问题
开异步线程获取不到ThreadLocal信息
InheritableThreadLocal
浅拷贝共享父线程ThreaMap方法
重写copy方法-深拷贝
难点问题
线程泄露
解决hash冲突
1、通过黄金分割数让hash值能够均匀分布在2的n次方的数组里
2、线性探测法进行处理,也会有垃圾清理的动作
cas问题
ABA
无限循环带来的开销
只能操作一个共享变量
JDK 1.7 和 JDK1.8 区别
函数式接口
Lambda语法
接口默认方法
Optional
swith 支持String
AQS
jvm
内存结构
方法区
虚拟机加载类信息
常量
堆
年轻代
eden:8/10
from survivor:1/10
to survivor:1/10
老年代
虚拟机栈
局部变量
对象的引用地址
执行指令应用地址
方法出口
操作栈
本地方法栈
程序计数器
new 对象过程
对象分配过程
调优
常见配置
内存相关
GC相关
分配对象
空闲链表
指针碰撞
垃圾回收机制
识别垃圾
引用计数算法
可达性分析算法
垃圾收集算法
标记清除法
复制算法
标记-整理算法
分代收集算法
垃圾收集器
CMS
初使标记
独占CPU,stop-the-world, 仅标记GCroots能直接关联的对象,速度比较快;
并发标记
可以和用户线程并发执行,通过GCRoots Tracing 标记所有可达对象;
重新标记
独占CPU,stop-the-world, 对并发标记阶段用户线程运行产生的垃圾对象进行标记修正,以及更新逃逸对象;
并发清理
可以和用户线程并发执行,清理在重复标记中被标记为可回收的对象。
G1
对象分配调优
对象引用调优
差异对比
GC模式
young gc
mixed gc
full gc
内存结构
GC调优分析
日志排查
GC原因
常见问题
动态扩容引起的空间震荡
显式 GC 的去与留
MetaSpace 区 OOM
重复注册类加载到元空间
过早晋升
Young/Eden 区过小
分配速率过大
对象晋升年龄较小。
GC 日志中出现“Desired survivor size 107347968 bytes, new threshold 1(max 6)”等信息,说明此时经历过一次 GC 就会放到 Old 区。
GC 日志中出现“Desired survivor size 107347968 bytes, new threshold 1(max 6)”等信息,说明此时经历过一次 GC 就会放到 Old 区。
调整晋升年龄
CMS Old GC 频繁*
单次 CMS Old GC 耗时长
重点关注重新标记阶段的耗时情况
内存碎片&收集器退化
判断是不是GC问题
时序分析
CPU负载高-慢查询增多-GC耗时增大-线程block增多 - RT上涨
实验分析
线程block增多-CPU负载高-慢查询增多-GC耗时增大 - RT上涨
反证分析
GC耗时增大-线程block增多-RT上涨
评价标准
简而言之即为一次停顿的时间不超过应用服务的 TP9999,GC 的吞吐量不小于 99.99%。举个例子,假设某个服务 A 的 TP9999 为 80 ms,平均 GC 停顿为 30 ms,那么该服务的最大停顿时间最好不要超过 80 ms,GC 频次控制在 5 min 以上一次。如果满足不了,那就需要调优或者通过更多资源来进行并联冗余。(大家可以先停下来,看看 Raptor 上面的 gc.meantime 分钟级别指标,如果超过了 6 ms 那单机 GC 吞吐量就达不到 4 个 9 了。)
常用设计模式
代理模式
装饰器模式
责任链模式
工厂方法模式
模板方法模式
观察者模式
策略模式
桥梁模式
六大设计原则(SOLID)
接口隔离原则(Interface Segregation Principle)
单一职责原则(Single Responsibility Principle)
开闭原则(Open Closed Principle)
里氏替换原则(Liskov Substitution Principle)
迪米特法则(Law of Demeter)
依赖倒置原则(Dependence Inversion Principle)
门面模式
数据结构与算法
数组
找出只出现一次的数字
奇数偶数重排序
打印成最小的数
寻找多数元素
有序数组中计算关键字的出现次数
链表
单链表反转
单链表是否有环
删除值为v的所有节点
链表是否相交
求相交的第一个节点
查找倒数第K个节点
有序链表合并
链表的中间节点
字符串
队列
两个队列实现栈
栈
最小栈
两个队列实现栈
树
二叉树
深度优先遍历
前序遍历
中序遍历
后序遍历
广度优先遍历
路径和问题
二叉查找树
平衡二叉树AVL
红黑树
哈夫曼树
排序
快速排序
查找
二分查找法
线上问题处理
cpu 100%
内存溢出
计算机网络
应用层
传输层
tcp
udp
三次握手
网络层
数据链路层
物理层
一次http请求
消息队列
怎么保证消息不丢
怎么保证消息有序
kafka
零拷贝
生产者
Memory Mapped Files
消费者
send file
mmap 和 sendfile总结
kafka快
消息积压
ISR
leader 和 Follower机制
ACK
日志末端偏移(LEO) 和 已同步消息标识(HW)
kafka消息幂等性
pid+自增序列 + 消息体
高性能
顺序IO
零拷贝
批量发送
高可用
消息备份
故障恢复
延迟队列
死信队列
消费者pull
自动提交
手动提交
同步提交
异步提交
自我介绍
介绍基本信息
核心点
升华和拔高
职业规划
自我认识
支付业务严谨&质量要求高
对行业和职位了解
支付价值
稳定性
未来五年能够继续深扎支付或相关领域
离职原因
0 条评论
下一页