JAVA知识点(持续更新)
2019-08-16 11:19:04 10 举报
AI智能生成
登录查看完整内容
JAVA面试知识点
作者其他创作
大纲/内容
网络协议
数字证书由信任的第三方,即认证中心使用自己的私钥对 A 的公钥加密,加密后的文件
数字证书
HTTPS
好处1:浏览器会自动采用 HTTPS 访问网站地址,从而保证用户始终访问到网站的加密链接,保护数据传输安全
https 访问响应头中添加
max-age 参数,时间设置不宜过长,建议设置时间为 6 个月
配置Header:Strict-Transport-Security: max-age=expireTime [; includeSubDomains] [; preload]
加入HSTS Preload List
HSTS(HTTP 严格安全传输)
1
阅读资料
HTTP/HTTPS/HTTP2
长连接
滑动窗口
参数
设计优雅
使用方便
高性能
安全
社区活跃
主要特点
Netty
基本原理:select 函数监视的文件描述符分3类,分别是writefds、readfds、和exceptfds。调用后select函数会阻塞,直到有描述符就绪(有数据 可读、可写、或者有except),或者超时(timeout指定等待时间,如果立即返回设为null即可),函数返回。当select函数返回后,可以通过遍历fdset,来找到就绪的描述符
缺点: 1、select最大的缺陷就是单个进程所打开的FD是有一定限制的,它由FD_SETSIZE设置,32位机默认是1024个,64位机默认是2048。cat /proc/sys/fs/file-max
缺点: 2、对socket进行扫描时是线性扫描,即采用轮询的方法,效率较低。
缺点: 3、需要维护一个用来存放大量fd的数据结构,这样会使得用户空间和内核空间在传递该结构时复制开销大
select
基本原理:poll本质上和select没有区别,它将用户传入的数组拷贝到内核空间,然后查询每个fd对应的设备状态,如果设备就绪则在设备等待队列中加入一项并继续遍历,如果遍历完所有fd后没有发现就绪设备,则挂起当前进程,直到设备就绪或者主动超时,被唤醒后它又要再次遍历fd。这个过程经历了多次无谓的遍历。它没有最大连接数的限制,原因是它是基于链表来存储的
缺点: 1、大量的fd的数组被整体复制于用户态和内核地址空间之间,而不管这样的复制是不是有意义
poll
epoll更加灵活,没有描述符限制。epoll使用一个文件描述符管理多个描述符,将用户关系的文件描述符的事件存放到内核的一个事件表中,这样在用户空间和内核空间的copy只需一次。
基本原理:epoll支持水平触发和边缘触发,最大的特点在于边缘触发,它只告诉进程哪些fd刚刚变为就绪态,并且只会通知一次。还有一个特点是,epoll使用“事件”的就绪通知方式,通过epoll_ctl注册fd,一旦该fd就绪,内核就会采用类似callback的回调机制来激活该fd,epoll_wait便可以收到通知
epoll的优点: 1、没有最大并发连接的限制,能打开的FD的上限远大于1024(1G的内存上能监听约10万个端口)
2、效率提升,不是轮询的方式,不会随着FD数目的增加效率下降。 只有活跃可用的FD才会调用callback函数;即Epoll最大的优点就在于它只管你“活跃”的连接,而跟连接总数无关
3、内存拷贝,利用mmap()文件映射内存加速与内核空间的消息传递;即epoll使用mmap减少复制开销
epoll
IO模型
网络
CPU
内存
IO
进程
shell
各种命令
节省了 CPU 周期,空出的 CPU 可以完成更多其他的任务
减少了内存区域之间数据拷贝,节省内存带宽
减少用户态和内核态之间数据拷贝,提升数据传输效率
应用零拷贝技术,减少用户态和内核态之间的上下文切换
好处
传统拷贝
sendfile(2 次的上下文切换,3 次的 I/O 拷贝)
支持 scatter-gather 特性的 sendfile(2 次的上下文切换,2 次的 I/O 拷贝)
mmap
原理
零拷贝
调优
操作系统
-XX:+UseSerialGC指定
一个单线程的收集器,只会使用一个CPU或一条收集线程去完成垃圾收集工作,进行垃圾收集时必须暂停其他所有的工作线程,直到它收集结束。Stop The World
Serial收集器
-XX:+UseParNewGC指定
Serial收集器的多线程版本,包括Serial收集器可用的所有控制参数、收集算法、Stop The World、对象分配规则、回收策略等都与Serial收集器完全一样
首选的新生代收集器,可以和cms老年代回收期配合使用。当old代采用CMS GC时new代默认采用ParNew
ParNew收集器
-XX:+UseParallelGC指定
新生代收集器,它也是使用复制算法的收集器,又是并行的多线程收集器
server模式下的默认GC方式
高吞吐量则可以高效率地利用CPU时间,尽快完成程序的运算任务,主要适合在后台运算而不需要太多交互的任务
Parallel Scavenge收集器
-XX:+UseConcMarkSweepGC指定
Concurrent Mark and Sweep 并发-标记-清除,是一款基于并发、使用标记清除算法的垃圾回收算法,只针对老年代进行垃圾回收。
CMS收集器工作时,尽可能让GC线程和用户线程并发执行,以达到降低STW时间的目的
阶段 1: 初始标记(Initial Mark)
阶段 2: 并发标记(Concurrent Mark)
阶段 3: 并发预清理(Concurrent Preclean)
阶段 4: 并发可取消的预清理(Concurrent Abortable Preclean)
阶段 5: 最终标记(Final Remark)
阶段 6: 并发清除(Concurrent Sweep)
阶段 7: 并发重置(Concurrent Reset)
七个阶段
最终标记阶段停顿时间过长问题
并发模式失败
晋升失败
并发模式失败(concurrent mode failure) & 晋升失败(promotion failed)问题
内存碎片问题
CMS常见问题
-XX:CMSInitiatingOccupancyFraction=70
-XX:+UseCMSInitiatingOccupancyOnly
-XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses
-XX:+CMSClassUnloadingEnabled
-XX:+CMSScavengeBeforeRemark
-XX:UseCMSCompactAtFullCollection
-XX:CMSFullGCsBeforeCompaction
常用参数
CMS收集器
G1(Garbage-First)是一款面向服务器的垃圾收集器,支持新生代和老年代空间的垃圾收集,主要针对配备多核处理器及大容量内存的机器
最主要的设计目标是: 实现可预期及可配置的STW停顿时间
Region
巨型对象
每次GC不必都去处理整个堆空间,而是每次只处理一部分Region,实现大容量内存的GC
通过计算每个Region的回收价值,包括回收所需时间、可回收空间,在有限时间内尽可能回收更多的垃圾对象,把垃圾回收造成的停顿时间控制在预期配置的时间范围内,这也是G1名称的由来: garbage-first
G1堆空间划分
Young GC
Mixed GC
G1工作模式
初始标记(Initial Mark)
根区域扫描(Root Region Scan)
并发标记(Concurrent Marking)
再次标记(Remark)
整理更新每个Region各自的RSet(remember set,HashMap结构,记录有哪些老年代对象指向本Region,key为指向本Region的对象的引用,value为指向本Region的具体Card区域,通过RSet可以确定Region中对象存活信息,避免全堆扫描)
回收不包含存活对象的Region
统计计算回收收益高(基于释放空间和暂停目标)的老年代分区集合
清理(Cleanup)
全局并发标记
程序主动执行System.gc()
全局并发标记期间老年代空间被填满(并发模式失败)
Mixed GC期间老年代空间被填满(晋升失败)
Young GC时Survivor空间和老年代没有足够空间容纳存活对象
原因
增大-XX:ConcGCThreads=n 选项增加并发标记线程的数量,或者STW期间并行线程的数量:-XX:ParallelGCThreads=n
减小-XX:InitiatingHeapOccupancyPercent 提前启动标记周期
增大预留内存 -XX:G1ReservePercent=n ,默认值是10,代表使用10%的堆内存为预留内存,当Survivor区域没有足够空间容纳新晋升对象时会尝试使用预留内存
解决
Full GC问题
巨型对象分配
不要设置Young区的大小
平均响应时间设置
G1调优
-XX:MaxGCPauseMillis=200
-XX:InitiatingHeapOccupancyPercent=45
-XX:G1ReservePercent=10
-XX:G1HeapRegionSize=2M
G1收集器
7种作用于不同分代的收集器
当年轻代Eden区域满的时候
触发条件
新生代GC(Minor GC)
显式调用System.gc方法
方法区空间不足(JDK8及之后不会有这种情况了
老年代空间不足
老年代GC(Major GC / Full GC)
吞吐量
引用计数法(已经不用了)
JVM栈中引用的对象
方法区中静态属性引用的对象
方法区中常量引用的对象
本地方法栈中引用的对象
GC Roots
可达性分析法
判断对象是需要回收
Young GC日志
Full GC日志
GC日志
GC过程中分析对象引用关系,为了保证分析结果的准确性,需要通过停顿所有Java执行线程,保证引用关系不再动态变化,该停顿事件称为Stop The World(STW)
Stop The World
代码执行过程中的一些特殊位置,当线程执行到这些位置的时候,说明虚拟机当前的状态是安全的,如果有需要GC,线程可以在这个位置暂停。HotSpot采用主动中断的方式,让执行线程在运行期轮询是否需要暂停的标志,若需要则中断挂起
Safepoint
垃圾收集
类加载机制
在单核单线程的机器上
Serial (DefNew)
Serial Mark-Sweep-Compact
-XX:+UseSerialGC
当你的目标是牺牲更多的CPU时间来GC以缩短GC停顿,并且有多个处理器
由于会发生内存碎片,CMS收集器会比其他收集器需要更多内存
“ParNew” + “CMS” + “Serial Old”
-XX:+UseConcMarkSweepGC
“ParNew” + “Serial Old”
-XX:+UseParNewGC
在多核处理器机器上,并且是CPU密集型应用
使用-server参数时默认启用
Parallel scavenge (PSYoungGen)
Serial Mark-Sweep-Compact (PSOldGen)
-XX:+UseParallelGC
Parallel Mark-Sweep-Compact(ParOldGen)
-XX:+UseParallelOldGC
Concurrent Mark Sweep
-XX:+UseConcMarkSweepGC -XX:-UseParNewGC
Parallel (ParNew)
-XX:+UseConcMarkSweepGC -XX:+UseParNewGC
G1
\t-XX:+UseG1GC
日志参数
参数调优
大多数情况下,对象先在新生代Eden区中分配。当Eden区没有足够空间进行分配时,虚拟机将发起一次Young GC
对象优先在Eden区分配
JVM提供了一个对象大小阈值参数(-XX:PretenureSizeThreshold,默认值为0,代表不管多大都是先在Eden中分配内存),大于参数设置的阈值值的对象直接在老年代分配,这样可以避免对象在Eden及两个Survivor直接发生大内存复制
大对象之间进入老年代
对象每经历一次垃圾回收,且没被回收掉,它的年龄就增加1,大于年龄阈值参数(-XX:MaxTenuringThreshold,默认15)的对象,将晋升到老年代中
长期存活的对象将进入老年代
当进行Young GC之前,JVM需要预估:老年代是否能够容纳Young GC后新生代晋升到老年代的存活对象,以确定是否需要提前触发GC回收老年代空间,基于空间分配担保策略来计算
空间分配担保策略
空间分配担保
新生代对象的年龄可能没达到阈值(MaxTenuringThreshold参数指定)就晋升老年代
动态年龄判定
内存分配策略
并发(concurrency)
并行(Parallel)
并发
JIT
CPU多级缓存和缓存一致性
处理器优化和指令重排
原子性
可见性
有序性
限制处理器优化
使用内存屏障
解决并发问题主要采用两种方式
java内存模型
各种工具
JVM
IOC
AOP
Springboot
Mybatis
Tomcat
日志组件
23种设计模式
UML
Restful
SSM
内核参数优化
查看java进程ID
jps
查看及调整虚拟机参数
jinfo
查看堆(heap)使用情况及生成堆快照
jmap
查看线程运行状态及生成线程快照
jstack
显示进程中的类装载、内存、垃圾收集等运行数据
jstat
自带命令行监测工具
均可监测本地及远程的java应用,包括堆使用情况,线程使用,cpu使用,类加载情况,gc情况
jconsole
还可以生成相应的堆和线程快照,同时还可以使用相应的插件
jvisualvm
自带可视化监测工具
eclipse的内存分析插件,通过MAT可以对dump出来的堆快照进行分析,并且辅助分析内存泄露原因,快速的计算出在内存中对象的占用大小,垃圾收集器的回收工作情况,并可以通过报表直观的查看到可能造成这种结果的对象
MAT
sun推出的一款Java 动态、安全追踪(监控)工具,可以在不停机的情况下监控系统运行情况,并且做到最少的侵入,占用最少的系统资源。
BTrace
阿里开源的在线Java诊断工具,同样可以在不停机情况监控系统,包括内存情况,线程情况,GC情况,运行时数据,也可以监测方法参数、返回值,异常返回等数据
Arthas
免费的GC日志图形分析工具,下载jar包直接运行
GCViewer
免费的GC日志图形分析工具,web工具,上传GC日志在线使用
gceasy
第三方诊断工具
JVM优化
网络参数优化
事务优化
数据库优化
连接池化
内存溢出排查
堆外内存排查
IO排查
高负载排查
性能优化&故障排查
SpringCloud
Dubbo
常用架构
HttpClient
thrift
grpc
hessian
feign
常用RPC框架
熔断&限流
负载均衡
灰度
监控报警
日志收集ELKB
调用链
治理
微服务
SSO
SQL注入
XSS
CSRF
DDos
加密解密
证书体系
网络隔离
OAuth
队列
栈
链表
数据
字典
图
平衡二叉树
红黑树
B+树
LSM树
数据结构
排序算法
常用算法
集合
文件操作
0 <= 标记 <= 位置 <= 限制 <= 容量
clear
flip
rewind
Buffer
NIO
反射
JDBC
JNDI
RMI
JMX
JMS
JDK
线程安全
线程池
AQS
自旋锁
偏向锁
轻量级锁
减少锁的时间
减少锁的粒度
锁粗化
使用读写锁
消除缓存行的伪共享
适应性自旋
锁消除
锁优化
锁
悲观锁/乐观锁
非/公平锁
JUC工具包
无锁队列
伪共享
加锁顺序
加锁时限
死锁检测
死锁
方法级
代码块
synchronized
GC分代年龄
无锁态
重量级锁
GC标记
锁状态标记
哈希码
epoch
对象头信息markword
初始状态(New)
就绪状态(Runnable)
运行状态(Running)
阻塞状态(Blocked)
死亡状态(Dead)
线程状态
Innodb
索引
事务隔离级别
MVCC
各种优化
Mysql
mongodb
Hbase
数据库
分布式锁
限流
缓存同步
string
hash
list
set
zset
其他
单线程
采用 IO 多路复用机制
事件模型
纯内存操作
基于非阻塞的 IO 多路复用机制
C 语言实现
单线程反而避免了多线程的频繁上下文切换问题,预防了多线程可能产生的竞争问题
高效原因
定期删除
惰性删除
过期策略
新写入操作会报错
noeviction
在键空间中,移除最近最少使用的 key
allkeys-lru
在键空间中,随机移除某个 key
allkeys-random
在设置了过期时间的键空间中,移除最近最少使用的 key
volatile-lru
在设置了过期时间的键空间中,随机移除某个 key
volatile-random
在设置了过期时间的键空间中,有更早过期时间的 key 优先移除
volatile-ttl
内存淘汰机制
RDB 会生成多个数据文件,每个数据文件都代表了某一个时刻中 redis 的数据,非常适合做冷备,可以将数据文件发送到一些远程的安全存储上去
RDB 对 redis 对外提供的读写服务,影响非常小,可以让 redis 保持高性能,因为 redis 主进程只需要 fork 一个子进程,让子进程执行磁盘 IO 操作来进行 RDB 持久化即可
相对于 AOF 持久化机制来说,直接基于 RDB 数据文件来重启和恢复 redis 进程,更加快速
一般来说,RDB 数据快照文件,都是每隔 5 分钟,或者更长时间生成一次,这个时候就得接受一旦 redis 进程宕机,那么会丢失最近 5 分钟的数据
RDB 每次在 fork 子进程来执行 RDB 快照数据文件生成的时候,如果数据文件特别大,可能会导致对客户端提供的服务暂停数毫秒,或者甚至数秒
RDB
AOF 可以更好的保护数据不丢失,一般 AOF 会每隔 1 秒,通过一个后台线程执行一次fsync操作,最多丢失 1 秒钟的数据
AOF 日志文件以 append-only 模式写入,所以没有任何磁盘寻址的开销,写入性能非常高,而且文件不容易破损,即使文件尾部破损,也很容易修复
AOF 日志文件即使过大的时候,出现后台重写操作,也不会影响客户端的读写。因为在 rewrite log 的时候,会对其中的指令进行压缩,创建出一份需要恢复数据的最小日志出来。在创建新日志文件的时候,老的日志文件还是照常写入。当新的 merge 后的日志文件 ready 的时候,再交换新老日志文件即可。
AOF 日志文件的命令通过非常可读的方式进行记录,这个特性非常适合做灾难性的误删除的紧急恢复
对于同一份数据来说,AOF 日志文件通常比 RDB 数据快照文件更大
AOF 开启后,支持的写 QPS 会比 RDB 支持的写 QPS 低,因为 AOF 一般会配置成每秒 fsync 一次日志文件
AOF
持久化
异步方式复制数据到 slave 节点
一个 master node 是可以配置多个 slave node 的
slave node 也可以连接其他的 slave node
slave node 做复制的时候,不会 block master node 的正常工作;
slave node 在做复制的时候,也不会 block 对自己的查询操作,它会用旧的数据集来提供服务;但是复制完成的时候,需要删除旧数据集,加载新数据集,这个时候就会暂停对外服务了;
slave node 主要用来进行横向扩容,做读写分离,扩容的 slave node 可以提高读的吞吐量。
如果采用了主从架构,那么建议必须开启 master node 的持久化
流程
断点续传
过期 key 处理
复制原理
主从架构
集群监控:负责监控 redis master 和 slave 进程是否正常工作
消息通知:如果某个 redis 实例有故障,那么哨兵负责发送消息作为报警通知给管理员
故障转移:如果 master node 挂掉了,会自动转移到 slave node 上
配置中心:如果故障转移发生了,通知 client 客户端新的 master 地址
功能
至少需要 3 个实例
需要majority 来允许执行故障转移
不保证数据零丢失的,只能保证 redis 集群的高可用性
重点
异步复制导致的数据丢失
min-slaves-to-write 1min-slaves-max-lag 10
脑裂导致的数据丢失
数据丢失
sdown 和 odown 转换机制
自动发现机制
slave 配置的自动纠正
slave->master 选举算法
quorum 和 majority
Sentinel哨兵模式
集群高可用
最佳实践
Redis
memcache
guava
常用缓存
查询一个数据库一定不存在的数据,每次查询都穿透缓存落到DB中
每次系统 A 从数据库中只要没查到,就写一个空值到缓存里去
解决方案
缓存穿透
指一个key非常热点,当这个key在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库
将热点数据设置为永远不过期
基于 redis or zookeeper 实现互斥锁,等待第一个请求构建完缓存之后,再释放锁,进而其它请求才能通过该 key 访问数据
缓存击穿
指在某一个时间段,缓存集中过期失效,或缓存服务节点的宕机,海量请求同时到达DB
redis 高可用,主从+哨兵,redis cluster,避免全盘崩溃。
本地 ehcache 缓存 + hystrix 限流&降级,避免 MySQL 被打死
redis 持久化,一旦重启,自动从磁盘上加载数据,快速恢复缓存数据。
缓存雪崩
缓存常见问题
缓存
Kafka
RabbitMQ
RocketMQ
ActiveMQ
常用MQ
解耦
异步
削峰
MQ用途
系统可用性降低
保存消费进度
消费者幂等性
如何解决
重复消费
事务机制,同步,不推荐
confirm机智,异步,推荐
生产者
开启持久化
备份replica
MQ
关闭自动ACK
消费者
丢失消息
消息顺序
系统复杂度上升
一致性问题
缺点
RabbitMQ和Kafka高可用
参考一:RabbitMQ和Kafka高可用
事务消息
ACK级别
如何解决消息队列的延时以及过期失效问题?消息队列满了以后该怎么处理?有几百万消息持续积压几小时,说说怎么解决?
如何设计一个消息队列
面试题
消息中间件
读写分离
分库分表
sharedingJDBC
mycat
mysql route
altas
zebra
常用中间件
binlog
基于 lucene
index -> type -> mapping -> document -> field
基本单位是索引
好处一:支持横向扩展
好处二:提高性能
好处三:shard多replica,高可用
索引可以拆分成多个 shard,每个 shard 存储部分数据
es 集群多个节点,会自动选举一个节点为 master 节点,master 节点是干一些管理的工作的,比如维护索引元数据、负责切换 primary shard 和 replica shard 身份等。要是 master 节点宕机了,那么会重新选举一个节点为 master 节点
非 master节点宕机了,master 节点会让宕机节点上的 primary shard 的身份转移到其他机器上的 replica shard。当宕机机器恢复后,master 节点会控制将缺失的 replica shard 分配过去,同步后续修改的数据之类的,让集群恢复正常
分布式架构原理
es 写数据过程
es 读数据过程
es 搜索数据过程
filesystem cache
数据预热
冷热分离
不允许深度分页
scroll api
search_after
分页性能优化
优化
ElasticSearch
搜索引擎
高性能高可用
写操作之后进行读操作无论在哪个节点都需要返回写操作的值
一致性(Consistence)
非故障的节点在合理的时间内返回合理的响应
可用性(Availability)
当网络出现分区后,系统依然能够继续履行职责
分区容忍性(Partition Tolerance)
CAP
分布式系统在出现故障的时候,允许损失部分可用性(例如响应时间、功能上的可用性),允许损失部分可用性
基本可用(Basically Available)
允许系统存在中间状态,而该中间状态不会影响系统整体可用性
柔性状态(Soft State)
系统中的所有数据副本经过一定时间后,最终能够达到一致的状态。弱一致性和强一致性相反,最终一致性是弱一致性的一种特殊情况
最终一致性(Eventual Consistency)
参考文章
BASE
Raft
Paxos
Gossip
分片
副本
Quorum/NWR
幂等
一致性哈希
ID生成器
理论
Zookeeper
ETCD
Consul
Eureka
性能问题:在事务进行过程中,节点都处于阻塞状态。各个操作数据库的节点都在占用着数据库资源,只有等所有节点都准备完毕,事务协调者才会通知全局提交,参与者进行本地事务提交才会释放数据库资源。整个过程比较漫长,对性能影响比较大
事务协调者宕机问题:事务协调者是整个XA模型的核心,一旦事务协调者节点挂掉,会导致参与者收不到事务提交或回滚的通知,从而导致事务参与者一直处于无法完成事务的中间状态
丢失消息导致的数据不一致问题:在第二阶段,当发生局部网络问题时,一部分节点收到事务提交通知,一部分节点没有收到提交通知,那么就会导致节点数据的不一致
适合单块应用里,跨多个库的分布式事务,而且因为严重依赖于数据库层面来搞定复杂的事务,效率很低
两阶段提交(2PC)
三阶段提交(3PC)
是对各个服务的资源做检测以及对资源进行锁定或者预留
Try 阶段
是在各个服务中执行实际的操作
Confirm 阶段
如果任何一个服务的业务方法执行出错,那么这里就需要进行补偿,就是执行已经执行成功的业务逻辑的回滚操作
Cancel 阶段
TCC
本地消息表
可靠消息最终一致性方案
最大努力通知方案
分布式事务
分布式
JAVA知识点
收藏
0 条评论
回复 删除
下一页