Java基础知识储备
2024-07-12 18:03:21 4 举报
AI智能生成
Java基础知识储备
作者其他创作
大纲/内容
除启动类加载器外都派生于ClassLoader
类加载器分类
类加载过程
类什么时候初始化
类初始化顺序
原理
优点
如何打破双亲委派机制
双亲委派机制
在jvm生命周期中每个类如果存在,则不会重复加载
改类后为什么需要重启`
类加载器
线程私有的,生命周期与线程生命周期保持一致
存储当前线程正在执行的 Java 方法的 JVM 指令地址
分支,循环,跳转,异常处理,线程恢复等基础功能都需要依赖这个计数器来完成
程序计数器
栈的特点及运行原理
局部变量表
操作数栈
动态链接(指向运行时常量池的方法引用)
方法返回地址
栈帧
Java虚拟机栈
简介
组成
作用
JNI
本地方法栈
堆内存区域划分
对象创建内存分配过程
新生区与老年区配置比例
分代收集思想 Minor GC、Major GC、Full GC
堆空间的参数设置
字符串常量池为什么要调整位置?
堆
方法区的内部结构
方法区的大小决定了系统可以保存多少个类,如果系统定义了太多的类,导致方法区溢出, 虚拟机同样会抛出内存溢出的错误。
方法区大小设置
方法区的垃圾回收
方法区
运行时数据区
字节码解释器
模版解释器
运行模式
热点代码
基于采样的热点探测
基于计数器的热点探测
热点探测
热点代码缓存
解析器
触发条件
即时编译器实现
即时编译器
C1编译器
C2编译器
javac编译器和即时编译器
JIT编译器
机器码
指令
指令集
汇编语言
高级语言
字节码
Java 代码编译和执行过程
执行引擎
性能的三个指标
JVM调优时机
调优的基本原则
调优目标
调优工具
调优步骤
JVM参数
示例
JVM调优
线程私有
线程公有
内存结构
引入计数法
GC ROOT对象包含哪些?
不可达对象不一定会被回收?
可达性分析算法
内存中“垃圾”的定义
标记清除(内存碎片)
标记整理
复制
分代回收
垃圾回收算法
Serial(复制)
Serial Old(标记整理)
ParNew(复制)
Parallel Scavenge(复制)
Parallel Old(标记整理)
初始标记(STW)-并发标记-并发预清理-重新标记(STW)-并发清理-并发重置
CMS(标记清除)
Region
hash表
Card Table
Region中存活对象的指针
Remembered Set(RS)
初始标记(STW)-并发标记-最终标记-筛选回收
G1
垃圾回收器
强引用
软引用(内存不足时回收)
弱引用(不考虑内存回收)
虚引用(任何时候)
终结器引用
引用分类
内存溢出
数据库连接(datasource)、io连接、网络连接(socket)未关闭
内存泄漏
内存问题
初始标记为什么会产生STW?
GC
概念、特点、对比
原子性
可见性
指令重排
有序性
JMM
缓存(字符串、序列化对象或者图片)、分布式锁、计数器、分布式Session、限流
字符串(String)
对象类型数据
哈希表(Hash)
简单队列,列表显示、分页、热点新闻
列表(List)
赞、踩、标签,统计独立IP,交并差集
集合(Set)
排行榜、商品排序
有序列表(ZSet)
地理信息(地理空间索引、附近商家)
地理空间(Geo)
记录状态(登录状态、签到)
位图(Bitmaps)
元素数量或者体积大时,计算基数所需空间固定很小
统计不重复的元素个数、搜索关键词数量、数据分析
基数统计(HyperLogLog)
消息队列
流信息(Streams)
九种数据类型及应用场景
noviction
volatile-lru
allkeys-lru
volatile-lfu
allkeys-lfu
volatile-random
allkeys-random
volatile-ttl
内存淘汰策略
定时删除
定期删除
惰性删除
过期删除策略
内存淘汰策略和过期删除策略
定义
优缺点
RDB
日志重写
工作原理
AOF
数据恢复
持久化方案建议
持久化机制
主要作用
同步
命令传播
主从复制
主要功能
哨兵监控
哨兵通知及故障转移
哨兵模式
数据分片
数据分区
高可用
复制原理
一致性保存
集合部署
Cluster 集群模式
三种集群模式
分布式存储
主从复制,读写分离
缓存前置
兜底逻辑
热点数据过期
高并发请求
场景
互斥锁
分布式锁
布隆过滤器
读写锁
空对象
解决方案
缓存击穿
恶意攻击
缓存与数据库不一致
缓存空对象
数据预热
数据库查询过滤
缓存穿透
设置了相同的过期时间
服务器宕机
设置相同的过期时间
数据持久化
使用Redis集群
使用缓存淘汰策略
限流和熔断
备份和灾难恢复
监控和告警
缓存雪崩
缓存常见问题及优化方案
内存存储
Reactor模型
单线程模型和多线程模型
网络协议
网络模型
redis
https://mp.weixin.qq.com/s/BJcPCzEzE-eAdzsuxTsVMQ
采用池化思想(类似连接池、常量池、对象池等)管理线程的工具
池中一直存活的线程数,即使处于空闲状态;c核心线程也会被回收
概念
CPU核心数+1
CPU密集型任务
CPU核心数 * 2
IO密集型任务
具体情况具体分析
混合任务
参数设置
核心线程数
资源受限的系统
200
高并发系统
核心线程全部繁忙且任务队列打满之后,线程池会追加线程,直到总线程数达到maximumPoolSize这个上限
最大线程数
1000
定义:BlockingQueue是一个基于阻塞机制(ReentrantLock)实现的线程安全的队列
ArrayBlockingQueue:由数组实现的有界阻塞队列,需指定队列大小,生产者消费者共用一个锁对象,无法真正并行运行,性能较低
LinkedBlockingQueue:有链表组成的无界阻塞队列,默认使用Integer.MAX_VALUE作为队列大小,生产者消费者分别维护独立的锁来控制数据同步
不存储元素的阻塞队列,无容量
SynchronousQueue
优先级队列,支持优先级排序的无界阻塞队列,通过Comparable接口的compareTo()方法实现
PriorityBlockingQueue
延迟队列,支持延时获取元素的无界阻塞队列
DelayQueue
一个由链表结构组成的无界阻塞队列,与LinkedBlockingQueue相比多了transfer和tryTranfer方法,该方法在有消费者等待接收元素时会立即将元素传递给消费者
LinkedTransferQueue
双端队列,一个由链表结构组成的双端阻塞队列
LinkedBlockingDeque
阻塞队列
任务队列
非核心线程空闲到达这个时间后,会被回收,将allowCoreThreadTimeOut参数设置为true后,核心线程也会这样
keepAliveTime
TimeUnit
指定线程池创建线程的方式
ThreadFactory
AbortPolicy
CallerRunsPolicy
DiscardPolicy
DiscardOldestPolicy
自定义拒绝策略
任务拒绝策略
核心组件
降低创建、销毁线程带来的开销,直接复用已创建的线程
降低资源消耗,提升响应速度
将提交与执行解耦,只需要向里面提交任务
降低使用复杂度
避免无限制创建线程
提高线程的可管理性
好处
运行状态
running
关闭状态,不再接受新任务提交,但是会将已保存在任务队列中的任务处理完
shutdown
停止状态,不再接受新任务提交,并且会中断当前正在执行的任务、放弃任务队列中已有的任务
stop
整理状态,所有的任务都执行完毕后(也包括任务队列中的任务执行完),当前线程池中的活动线程数降为 0 时的状态。到此状态之后,会调用线程池的 terminated() 方法。
tidying
销毁状态,当执行完线程池的 terminated() 方法之后就会变为此状态。
terminated
线程池状态
ThreadPoolExecutor.execute-ThreadPoolExecutor.addWorker-Thread.start-Worker.run-Worker.runWorker
步骤1失败,说明已经无法再创建新线程,那么考虑将任务放入阻塞队列,等待执行完任务的线程来处理。基于此,判断线程池是否处于Running状态(只有Running状态的线程池可以接受新任务),如果任务添加到任务队列成功则进入步骤3,失败则进入步骤4;
execute(Runnable command)
addWorker
runworker
https://mp.weixin.qq.com/s/I0IzEPffkwpwWkTmJ-J8Vw
线程池源码
https://mp.weixin.qq.com/s/nj9tnz1JI3ZsLeuk8S5DTg
线程池
时间片轮转
时间循环
协程
异步编程
单线程实现多并发
共享变量
线程不安全的工具对象(如:SimpleDateFormat)
Spring中的事务管理器
使用场景
ThreadLocal
new
ready
runnable
一个正在阻塞等待一个监视器锁的线程处于这一状态
blocked
waiting
timed-waiting
线程状态
当前线程调用,当前线程进入TIMED_WAITING状态,但不释放对象锁
Thread.sleep(long millis)
当前线程调用,当前线程放弃CPU时间片,但不释放锁资源,状态改为就绪状态,让OS再次选择线程
Thread.yield()
当前线程调用其他线程t的join方法,当前线程进入WAITING/TIMED_WAITING状态,当前线程不释放锁,join()基于wait实现
thread.jion()/join(long milis)
当前线程释放对象锁,进入等待队列,通过notify()/notifyAll()唤醒
obj.wait()/wait(long timeout)
唤醒对象监视器上等待的任意单个线程
obj.notify()/obj.notifyAll()
当前线程不需要获得锁,就进入WAITING/TIMED_WAITING状态,需要通过LockSupport.unpark(Thread thread)唤醒
https://blog.csdn.net/pange1991/article/details/53860651
中断线程,不会影响线程执行,只是作为一种标志位,被捕获InterruptedException后,中断状态为false
interrupt()
返回中断状态
isInterrupted
返回中断状态,且清除控制位
interrupted
中断
切换线程状态
判断线程池的状态,如果不是running状态,直接执行拒绝策略
如果当前线程数<核心线程数,则新建一个线程来处理提交的任务
如果当前线程数>核心线程数且任务队列没满,则将任务队列放入阻塞队列中执行
如果核心线程数<当前线程数<最大线程数,且任务队列已满,则创建新的线程执行提交的任务
如果当前线程数 > 最大线程数,且队列已满,则执行拒绝策略拒绝该任务
执行过程
execute()
多线程
https://mp.weixin.qq.com/s/HNmLYvmDaqnyH5IM34lvjw
重入锁
private ReentrantLock lock = new ReentrantLock(true)
公平锁
信号量
偏向锁
锁种类
数据库访问
文件读写
共享内存
队列操作
网络通信
锁场景
死锁问题
重入问题
性能问题
公平性问题
锁问题
拆分大事务
将长时间的计算、网络操作或其他操作移除出事务
使用乐观锁
提高系统性能
如何减少死锁
ReentrantLock.lock-ReentrantLock.Sync.lock-ReentrantLock.NonfairSync/FairSync.lock-AQS.acquire-AQS.tryAquire-NonfairSync/fairSync.tryAquire-若加锁失败,将线程存入等待队列AQS.addWaiter-等待队列中的线程尝试获取锁操作,如果获取成功或者被中断就退出AQS.acquireQueued
lock流程
1)判断等待队列是否有线程处于等待状态,如果没有,尝试获取锁;如果有,就进入等待队列(NonfairSync没有)2)采用CAS方式修改线程同步状态,如果成功返回true 3)支持当前线程,重复获得锁,将state值加1
tryAquire()内容
AQS中有变量exclusiveOwnerThread存储当前拥有独占访问权限的线程,tryAquire()通过getExclusiveOwnerThread获取对应线程
ReentrantLock如何实现可重入的
ReentrantLock.unlock-AQS.release-AQS.tryRelease-尝试释放锁Sync.tryRelease-若释放成功,从等待队列中获取一个等待线程并尝试唤醒AQS.unparkSuccessor
unlock流程
AQS是基于 CLH 队列,使用volatile修饰共享变量state,线程通过CAS方式去改变state状态值,如果成功则获取锁成功,失败则进入等待队列,等待被唤醒的线程同步器框架
AQS是JUC包下线程同步器实现的基石,ReentrantLock、ReadWriteLock、CountDownLatch、CyclicBarrier、Semaphore、ThreadPoolExecutor等
使用
AQS
https://mp.weixin.qq.com/s/KrTn6WQZOdcVfhCCEwGgPg
ReentrantLock
信号量用于控制同时访问资源的线程数量
private final Semaphore semaphoreA = new Semaphore(2);currentSemaphore.acquire();nextSemaphore.release();
控制多个线程依次执行
信号量(Semaphore)
互斥量用于保证同一时间只有一个线程访问资源
互斥量(Mutex)
Lock可尝试获取和定时获取,synchronized不支持
灵活性
lock获取所得操作可中断Lock.lockInterruptibly(),synchronized不支持
等待可中断
锁分离
lock可能会好些
性能
基于对象头的Mark Word来实现的,包括偏向锁、轻量级锁和重量级锁,通过monitor enter和monitor exit实现
synchronized
通过内部的AbstractQueuedSynchronizer(AQS)框架来实现锁的获取、释放以及线程等待和唤醒等功能
语法简洁性
https://mp.weixin.qq.com/s/XtSJomdqP1XjuTuv-0DqVQ
synchronized与lock的区别
Java锁
https://mp.weixin.qq.com/s/BfaHajANKUT65MaJUexXMg
可扩展
可靠性
可读性
重用性
单一职责原则
接口隔离原则
依赖倒转原则
里氏替换原则
开闭原则
迪米特法则
合成复用原则
7大原则
线程不安全、线程安全
懒汉式
SpringBoot 2.5.5默认实现方式
饿汉式
静态内部类
枚举
单例模式
进销项第三方配置
根据传入的参数决定创建哪种类型的对象
简单工厂模式
定义了一个创建对象的接口,但由子类决定实例化哪个类
工厂方法模式·
提供一个创建一系列相关或互相依赖对象的接口,而无需指定它们具体的类
抽象工厂模式
工厂模式
避免初始化的拷贝,不想被拷贝
原型模式
建造者模式
创建型
百望、航信大象、航信诺诺,查验需要参数不相同,但对其进行封装,对外统一用一个方法调用
适配器模式
多个复杂的子系统提供一个一致的接口
外观模式
为其他对象提供一种代理以控制对这个对象的访问
aop、Spring事务
代理模式
依据树形结构来组合对象,用来表示部分以及整体层次,比如:学校、院、系的关系
一个对象参数有多个子对象参数组成
组合模式
通过共享对象来减少创建大量相似对象时的内存消耗
池化技术、数据库连接池、线程池
享元模式
用于将抽象部分与实现部分分离,使得它们可以独立地变化
jdbc连接数据库,利用驱动来桥接
桥接模式
装饰器模式
结构型
票据过敏词
策略模式
百望对接token、参数、调用
模板方法模式
获取所有对象都执行逻辑,代码
观察者模式
命令模式
访问者模式
迭代器模式
行为型
种类
https://mp.weixin.qq.com/s/AIJBdwTVuN_U-tZoiKznOg
设计模式
反射
Volatile的原理
不同长度的输入,通过散列算法,变成固定长度的输出,结果为散列值
hash算法
被计算的数据是无限的,但是范围是有限的
按次序在哈希表(散列表)中找一个空闲的位置插入,threadlocal通过该方法解决
开放定址法(线性探测法)
存入单向链表,hashMap通过链式寻址法和红黑树来解决
链式寻址法
继续hash算法,直到没有hash冲突
再哈希法
单独的地址存放
建立公共溢出区
哈希冲突
用数组实现的 有界阻塞队列。此队列按照先进先出(FIFO)的原则对元素进行排序
ArrayBlockingQueue
用链表实现的 有界阻塞队列,此队列的默认和最大长度为Integer.MAX_VALUE
LinkedBlockingQueue
带优先级的队列,而不是先进先出队列,元素按优先级顺序被移除,而且它是无界的,也就是没有容量上限
无界阻塞队列,只有在延迟期满时才能从中提取元素
由链表结构组成的双向阻塞队列
ConcurrentLinkedQueue
ConcurrentLinkedDeque
内部基于数组实现,线程不安全的队列
PriorityQueue
非阻塞队列
双端队列是在两端都可以进行插入和删除的队列
Deque
双端队列
队列(Queue)
实现Filter 接口或通过@WebFilter注解实现对特定URL拦截
init():容器启动初始化过滤器时被调用,返回true,过滤器才能生效,只会掉一次
容器中的每一次请求都会调用该方法,方法内有个参数FilterChain,FilterChain的实现类ApplicationFilterChain,ApplicationFilterChain的回调函数doFiler() 实现的过滤器
doFilter()
容器销毁 过滤器实例时调用,只会掉一次
destroy()
方法
过滤器
实现HandlerInterceptor接口
如果返回false,这个和其他拦截器都会失效
preHandle()
在Controller 中的方法调用之后,DispatcherServlet 返回渲染视图之前被调用,,先进后出
postHandle()
在整个请求结束之后, DispatcherServlet 渲染了对应的视图之后执行
afterCompletion(()
拦截器
过滤器 是基于函数回调的,拦截器 则是基于Java的反射机制(动态代理)
实现原理
过滤器的接口Filter在servlet中,因此只能在web容器中使用,拦截器是spring的一个组件,使用没有限制
使用范围
Tomcat - Filter - servlet - Interceptor - controller
触发时机
过滤器几乎可以对所有进入容器的请求起作用,,而拦截器只会对Controller中请求或访问static目录下资源的请求起作用
拦截的请求范围
Filter支持注入Bean、Interceptor不支持,拦截器在SpringContext之前加载,,还没有DI
注入Bean情况
区别
拦截器与过滤器
TCP连接数优化、time_wait的优化
操作系统优化(内核参数)
redirectPort
maxThreads、minSpareThreads、maxSpareThreads、processorcache、acceptCount,maxKeepAliveRequests
URIEncoding
connectionTimeout、disableUploadTimeout、connectionUploadTimeout
enablelookups
compression、compressionMinSize、compressableMimeType
Tomcat配置文件参数的优化
-Xms、-Xmx、-Xmn、
子主题
Tomcat优化
手段:通过接口规约对象的属性和方法,是面向对象一部分
目的:统一标准问题(公用部分行为)
面向接口编程
手段:分离业务的主逻辑和次逻辑的一种思想
目的:解决的是逻辑分离问题(主逻辑和次逻辑分开,其实主要是分离业务逻辑和非业务逻辑分开)
场景:系统日志的记录、请求的拦截
面向切面编程
针对业务处理过程的实体及其属性和行为进行抽象封装,以获得更加清晰高效的逻辑单元划分
面向对象编程
编程思想对比
Vector、Stack、HashTable、ConcurrentHashMap、ConcurrentLinkedQueue、ArrayBlockingQueue
安全类
底层是HashMap
通过key值相同去重,对象必须重写equals和hashcode方法
key的hash相等,如果equals也相等,说明已存在,如果有一个不相等,则正常put
去重原理
HashSet
Set
Node数组+链表+红黑树
CAS:存在内存值a,预期值b,想要更新成c,若a == b,则a更新成c
CAS+synchronized
①若数组不存在,则初始化内存容量为16的Node数组;
②若无hash冲突,则通过CAS的方式将元素添加到Node数组,val和next都用volatile标识
③若数组正在扩容,则协助扩容
④若hash冲突则对Node数组上的索引加锁,再向链表或红黑树中添加数据
⑤增加map数量t
ConcurrentHashMap
集合
Java基础
遍历,存入map,key为值,value为索引
1. 两数之和
从最小开始,过滤重复数据,查找加一数据是否存在,当前最大,全局最大,max
128. 最长连续序列(不论顺序)
变量最长长度,当前字符长度,遍历,max方法
1446.连续字符(考虑顺序)
49. 字母异位词分组
哈希
冒泡算法
迭代算法
两个二分算法,mid的获取,high= mid -1
搜索二维矩阵
二分算法
最大堆调整(Max_Heapify):将堆的末端子节点作调整,使得子节点永远小于父节点堆排序(HeapSort):移除位在第一个数据的根节点,并做最大堆调整的递归运算
父节点i的左子节点在位置:(2*i+1);父节点i的右子节点在位置:(2*i+2);子节点i的父节点在位置:floor((i-1)/2)
https://mp.weixin.qq.com/s/NelX8acil-1vdtm8aRZg_A
堆算法
排序算法
迭代,当前节点的值val放在外面,node.next.val += 1
2. 两数相加
19. 删除链表的倒数第 N 个结点
迭代
21. 合并两个有序链表
迭代,传head、detail节点,不断取中间节点,直到取到detail,最后调用合并两个有序链表
148. 排序链表
链表
94. 二叉树的中序遍历
迭代:左最大高度,右最大高度,Math.max() + 1
104. 二叉树的最大深度
迭代,node.val +左最大和+右最大和,Math.max(原最大,现最大),返回node.val + 最大一边
给你一个二叉树的根节点 root ,返回其 最大路径和
迭代、左分支、右分支、返回node
108. 将有序数组转换为二叉搜索树
102. 二叉树的层序遍历
树
需要移动两头时,则可以用双指针
11. 盛最多水的容器
排序、遍历一个数,另外两个书用双指针获取,子方法
15. 三数之和
双指针
数组和为map的key,索引或者次数为值,赋初值0,1,map.containKey(curNum-key)为true,则是存在连续数组
和为 K 的连续子数组
前缀和加哈希表
连个二维数组一个三维数组,最后一个索引为单元格的值,值为数量
36. 有效的数独
77. 组合
1.拿到所有数的乘积,做除法
2.定义三个length长度的数组,一个表示指定位置的左侧乘积,一个表示指定位置的右侧乘积
238. 除自身以外数组的乘积
3>子查询员工表薪资>主查询员工表薪资
185. 部门工资前三高的所有员工
184. 部门工资最高的员工
1934-确认率
180. 连续出现的数字
mysql:176,oracle:rownum
177. 第N高的薪水
o.order_date like '2020-02-%'
1327. 列出指定时间段内所有的下单产品
select case count(distinct e1.salary)when 2 then min(e1.salary) else null end as SecondHighestSalary from employee e1where 2 > ( select count(distinct e2.salary) from employee e2 where e1.salary < e2.salary
176. 第二高的薪水
dense_rank()连续排序
178. 分数排名
相当于两个表
570. 至少有5名直接下属的经理
550. 游戏玩法分析 IV
select requester_id as ids from RequestAccepted union all select accepter_id from RequestAccepted两列合并
602. 好友申请 II :谁有最多的好友
1193. 每月交易 I
sql
刷题
JVM
https://mp.weixin.qq.com/s/WfYtW-VHdwopZLQ8VOaI6A
收藏
0 条评论
下一页