JAVA基础学习
2021-08-01 12:56:13 46 举报
AI智能生成
JAVA基础学习,包含java基础数据结构,线程池,JVM,Sping,MySQL,Redis等基础知识
作者其他创作
大纲/内容
限流算法
窗口算法
滑动窗口算法
漏桶算法
令牌桶算法
RateLimiter的实现原理
分布式
分布式锁的实现原理
redisson原理
设计模式
单例模式
代理模式
MySQL
mysql索引原理
B+树
树节点存储索引,单节点可存储更多索引
叶子结点存放数据
叶子结点用链表连接,有序
数据库引擎
MyIsam
查询效率高
不支持事务
支持表锁
非聚集索引
.frm
创建表的语句
.myi
表里面的索引文件(myisam index)
.myd
表里面的数据文件(myisam data)
叶子结点存储数据的物理地址
InnoDB
查询较Myisam低,增删改效率高
支持事务
表锁
行锁
聚集索引
.frm
创建表的语句
.idb
表里面的数据+索引文件
主键B+树叶子结点存储数据,其他索引B+树叶子结点存储主键Key
为什么不建议在sql中加order by
如果最终的结果集是以order by字段为条件筛选的,将order by字段加入索引,并放在索引中正确的位置,会有明显的性能提升
order by字段需要是非空的属性,否则会无效。
对于 a=1 or b=2 or c<3 类似的where 语句如何优化
使用union??
https://www.runoob.com/mysql/mysql-union-operation.html
事务
ACID
原子性(Atomicity,或称不可分割性)、一致性(Consistency)、隔离性(Isolation,又称独立性)、持久性(Durability)
事务控制语句
BEGIN 或 START TRANSACTION 显式地开启一个事务;
COMMIT 也可以使用 COMMIT WORK,不过二者是等价的。COMMIT 会提交事务,并使已对数据库进行的所有修改成为永久性的;
ROLLBACK 也可以使用 ROLLBACK WORK,不过二者是等价的。回滚会结束用户的事务,并撤销正在进行的所有未提交的修改;
SAVEPOINT identifier,SAVEPOINT 允许在事务中创建一个保存点,一个事务中可以有多个 SAVEPOINT;
RELEASE SAVEPOINT identifier 删除一个事务的保存点,当没有指定的保存点时,执行该语句会抛出一个异常;
ROLLBACK TO identifier 把事务回滚到标记点;
SET TRANSACTION 用来设置事务的隔离级别。InnoDB 存储引擎提供事务的隔离级别有READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ 和 SERIALIZABLE。
隔离级别
表锁
表共享读锁(Table Read Lock)
表独占写锁(Table Write Lock)
行锁(InnoDB)
共享锁(S):允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁。
SELECT * FROM table_name WHERE ... LOCK IN SHARE MODE
排他锁(X):允许获得排他锁的事务更新数据,阻止其他事务取得相同数据集的共享读锁和排他写锁。另外,为了允许行锁和表锁共存,实现多粒度锁机制,InnoDB还有两种内部使用的意向锁(Intention Locks),这两种意向锁都是表锁。
SELECT * FROM table_name WHERE ... FOR UPDATE
意向共享锁(IS):事务打算给数据行加行共享锁,事务在给一个数据行加共享锁前必须先取得该表的IS锁。
意向排他锁(IX):事务打算给数据行加行排他锁,事务在给一个数据行加排他锁前必须先取得该表的IX锁。
Redis
redis数据结构
集群高可用如何保证
宕机的服务器恢复后还能继续作为leader吗
哨兵机制
击穿雪崩
JAVA基础
集合
常见的集合类
实现关系
List
ArrayList
数组
有序
LinkedList
有序
链表
Vector
有序
数组
线程安全,synchronized 实现
Set
HashSet
无序
使用Hash表
LinkedHashSet
有序
hash表和链表结构
HashSet+LinkedHashMap
TreeSet
有序
通过TreeMap实现
底层结构为红黑树
Map
HashMap
无序
数组+链表+红黑树
Java8以前是 数组 + 链表
当链表长度大于8时,转为红黑树
ConcurrentHashMap
无序
线程安全
java7 分段锁(Segment)
继承ReentrantLock(可重入锁)
ReentrantLock+Segment+HashEntry
java8 cas
使用volatile修饰 value 和 next
synchronized+CAS+HashEntry+红黑树
HashTable
线程安全
synchronized实现
效率较ConcurrentHashMap低
key和value不能为null
TreeMap
有序,可重写排序
LinkedHashMap
继承HashMap
哪些是线程安全的
Vector
HashTable
ConcurrentHashMap
Stack
继承Vector
数组链表的差别
hashTable和ConcurrentHashMap
如何保证线程安全的
HashTable使用 synchronized锁
ConcurentHashMap CAS
实现和区别是什么
hashMap的实现原理
hashmap为什么o(1)查询
hashcode数组
插入操作
多线程
线程
继承Thread
实现Runable
实现Callable
有返回值Future
线程的生命周期
New 新建状态
Runable 就绪
调用start()方法后,JVM会创建方法调用栈和程序计数器,等待调度运行
Running 运行
获得CPU,开始执行run()方法
Blocked 阻塞
wait
释放锁
lock
sleep
不释放锁
join
Dead 死亡
终止线程的几种方式
程序正常结束
interrupt
stop
线程池
线程池的种类
newCachedThreadPool
创建一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们。对于执行
很多短期异步任务的程序而言,这些线程池通常可提高程序性能。调用 execute 将重用以前构造
的线程(如果线程可用)。如果现有线程没有可用的,则创建一个新线程并添加到池中。终止并
从缓存中移除那些已有 60 秒钟未被使用的线程。因此,长时间保持空闲的线程池不会使用任何资
源。
newFixedThreadPool
创建一个可重用固定线程数的线程池,以共享的无界队列方式来运行这些线程。在任意点,在大
多数 nThreads 线程会处于处理任务的活动状态。如果在所有线程处于活动状态时提交附加任务,
则在有可用线程之前,附加任务将在队列中等待。如果在关闭前的执行期间由于失败而导致任何
线程终止,那么一个新线程将代替它执行后续的任务(如果需要)。在某个线程被显式地关闭之
前,池中的线程将一直存在。
newScheduledThreadPool
创建一个线程池,它可安排在给定延迟后运行命令或者定期地执行。
newSingleThreadExecutor
Executors.newSingleThreadExecutor()返回一个线程池(这个线程池只有一个线程),这个线程
池可以在线程死后(或发生异常时)重新启动一个线程来替代原来的线程继续执行下去!
线程池的核心参数
CorePoolSize
核心线程数
核心线程会一直存活,及时没有任务需要执行
当线程数小于核心线程数时,即使有线程空闲,线程池也会优先创建新线程处理
设置allowCoreThreadTimeout=true(默认false)时,核心线程会超时关闭
queueCapacity
任务队列容量(阻塞队列)
当核心线程数达到最大时,新任务会放在队列中排队等待执行
maxPoolSize
最大线程数
当线程数>=corePoolSize,且任务队列已满时。线程池会创建新线程来处理任务
当线程数=maxPoolSize,且任务队列已满时,线程池会拒绝处理任务而抛出异常(默认)
keepAliveTime
线程存活时间
当线程空闲时间达到keepAliveTime时,线程会退出,直到线程数量=corePoolSize
如果allowCoreThreadTimeout=true,则会直到线程数量=0
allowCoreThreadTimeout
允许核心线程超时
rejectedExecutionHandler
两种情况会拒绝处理任务:
当线程数已经达到maxPoolSize,切队列已满,会拒绝新任务
当线程池被调用shutdown()后,会等待线程池里的任务执行完毕,再shutdown。如果在调用shutdown()和线程池真正shutdown之间提交任务,会拒绝新任务
线程池会调用rejectedExecutionHandler来处理这个任务。如果没有设置默认是AbortPolicy,会抛出异常
ThreadPoolExecutor类有几个内部实现类来处理这类情况:
AbortPolicy 丢弃任务,抛运行时异常
CallerRunsPolicy 执行任务
DiscardPolicy 忽视,什么都不会发生
DiscardOldestPolicy 从队列中踢出最先进入队列(最后一个执行)的任务
实现RejectedExecutionHandler接口,可自定义处理器
如何设置
需要根据几个值来决定
tasks :每秒的任务数,假设为500~1000
taskcost:每个任务花费时间,假设为0.1s
responsetime:系统允许容忍的最大响应时间,假设为1s
做几个计算
corePoolSize = 每秒需要多少个线程处理?
threadcount = tasks/(1/taskcost) =tasks*taskcout = (500~1000)*0.1 = 50~100 个线程。corePoolSize设置应该大于50
根据8020原则,如果80%的每秒任务数小于800,那么corePoolSize设置为80即可
queueCapacity = (coreSizePool/taskcost)*responsetime
计算可得 queueCapacity = 80/0.1*1 = 800。意思是队列里的线程可以等待1s,超过了的需要新开线程来执行
切记不能设置为Integer.MAX_VALUE,这样队列会很大,线程数只会保持在corePoolSize大小,当任务陡增时,不能新开线程来执行,响应时间会随之陡增。
maxPoolSize = (max(tasks)- queueCapacity)/(1/taskcost)
计算可得 maxPoolSize = (1000-800)/10 = 2000
(最大任务数-队列容量)/每个线程每秒处理能力 = 最大线程数
rejectedExecutionHandler
根据具体情况来决定,任务不重要可丢弃,任务重要则要利用一些缓冲机制来处理
keepAliveTime和allowCoreThreadTimeout采用默认通常能满足
线程池的工作流程
分支主题
常见的池化技术和优点
线程池
内存池
优点
减少内存碎片
提高内存使用频率
缺点
造成内存浪费
数据库连接池
HttpClient连接池
JVM
jvm分区
分支主题
分支主题
子主题 2
类加载机制,类只能从Class文件加载吗
启动类加载器
扩展类加载器
系统类加载器
自定义加载器,继承ClassLoader
JVM内存调优
-Xms 初始堆大小,默认物理内存的1/64 -Xms512M
-Xmx 最大堆大小,默认物理内存的1/4 -Xms2G
-Xmn 新生代内存大小,官方推荐为整个堆的3/8 -Xmn512M
-Xss 线程堆栈大小,jdk1.5及之后默认1M,之前默认256k -Xss512k
-XX:NewRatio=n 设置新生代和年老代的比值。如:为3,表示年轻代与年老代比值为1:3,年轻代占整个年轻代年老代和的1/4 -XX:NewRatio=3
-XX:SurvivorRatio=n 年轻代中Eden区与两个Survivor区的比值。注意Survivor区有两个。如:8,表示Eden:Survivor=6:1:1,一个Survivor区占整个年轻代的1/8 -XX:SurvivorRatio=8
-XX:PermSize=n 永久代初始值,默认为物理内存的1/64 -XX:PermSize=128M
-XX:MaxPermSize=n 永久代最大值,默认为物理内存的1/4 -XX:MaxPermSize=256M
-verbose:class 在控制台打印类加载信息
-verbose:gc 在控制台打印垃圾回收日志
-XX:+PrintGC 打印GC日志,内容简单
-XX:+PrintGCDetails 打印GC日志,内容详细
-XX:+PrintGCDateStamps 在GC日志中添加时间戳
-Xloggc:filename 指定gc日志路径 -Xloggc:/data/jvm/gc.log
-XX:+UseSerialGC 年轻代设置串行收集器Serial
-XX:+UseParallelGC 年轻代设置并行收集器Parallel Scavenge
-XX:ParallelGCThreads=n 设置Parallel Scavenge收集时使用的CPU数。并行收集线程数。 -XX:ParallelGCThreads=4
-XX:MaxGCPauseMillis=n 设置Parallel Scavenge回收的最大时间(毫秒) -XX:MaxGCPauseMillis=100
-XX:GCTimeRatio=n 设置Parallel Scavenge垃圾回收时间占程序运行时间的百分比。公式为1/(1+n) -XX:GCTimeRatio=19
-XX:+UseParallelOldGC 设置老年代为并行收集器ParallelOld收集器
-XX:+UseConcMarkSweepGC 设置老年代并发收集器CMS
-XX:+CMSIncrementalMode 设置CMS收集器为增量模式,适用于单CPU情况。
GC
怎么判断对象死亡
计数法
存在循环依赖的问题
根搜索算法
通过一系列的“GC roots”
对象作为起点搜索。如果在“GC roots”和一个对象之间没有可达路径,则称该对象是不可达的。
要注意的是,不可达对象不等价于可回收对象,不可达对象变为可回收对象至少要经过两次标记
过程。两次标记后仍然是可回收对象,则将面临回收。
垃圾收集算法
标记清除
复制
标记整理
JMM
Java Memory Model
java内存模型
java内存模型
JavaWeb
网络
Http和Https的区别
1、https协议需要到ca申请证书,一般免费证书较少,因而需要一定费用。
2、http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。
3、http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
4、http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。
Https是如何保证安全的
工作原理
(1)客户使用https的URL访问Web服务器,要求与Web服务器建立SSL连接。
(2)Web服务器收到客户端请求后,会将网站的证书信息(证书中包含公钥)传送一份给客户端。
(3)客户端的浏览器与Web服务器开始协商SSL连接的安全等级,也就是信息加密的等级。
(4)客户端的浏览器根据双方同意的安全等级,建立会话密钥,然后利用网站的公钥将会话密钥加密,并传送给网站。
(5)Web服务器利用自己的私钥解密出会话密钥。
(6)Web服务器利用会话密钥加密与客户端之间的通信。
优点
(1)使用HTTPS协议可认证用户和服务器,确保数据发送到正确的客户机和服务器;
(2)HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,要比http协议安全,可防止数据在传输过程中不被窃取、改变,确保数据的完整性。
(3)HTTPS是现行架构下最安全的解决方案,虽然不是绝对安全,但它大幅增加了中间人攻击的成本。
(4)谷歌曾在2014年8月份调整搜索引擎算法,并称“比起同等HTTP网站,采用HTTPS加密的网站在搜索结果中的排名将会更高”。
Mqtt协议相关
http访问网页的具体过程
输入地址
浏览器查找域名的IP
浏览器携带IP地址向Web服务器发起HTTP请求
服务器的永久重定向响应
发出新的请求(重定向)
服务器主机处理
Web应用服务器处理http请求
浏览器处理并显示html文件
dns解析的过程
递归解析
迭代解析
三次握手
非对称加密
请求头?如何设置过期时间
混合加密
是将对称密码和公钥密码的优势相结合的方法,解决了公钥密码速度慢的问题,并通过公钥密码解决了对称密码的密钥配送问题。网络上的密码通信所用的SSL/TLS都运用了混合密码系统。
会话密钥(session key)
加密步骤(发送消息)
首先,消息发送者要拥有消息接收者的公钥
生成会话密钥,作为对称密码的密钥,加密消息
用消息接收者的公钥,加密会话密钥
将前2步生成的加密结果,一并发给消息接收者
发送出去的内容包括
用会话密钥加密的消息(加密方法:对称密码)
用公钥加密的会话密钥(加密方法:公钥密码)
解密步骤(收到消息)
消息接收者用自己的私钥解密出会话密钥
再用第1步解密出来的会话密钥,解密消息
混合加密
对称加密AEC
缺点
无法很好的解决秘钥配送的优缺点
非对称加密RSA
缺点
加密与解密速度比较慢
Session和Cookie
JWT
jwt原理
jwt数据格式
Spirng
一个轻量级的控制反转(IOC)和面向切面(AOP)的企业级容器框架
大小和开销两方面都是轻量级的
通过IO技术达到松耦合
提供了面向切面编程的丰富支持,使得系统服务和业务逻辑进行分离,达到内聚性的开发
包含并管理应用对象(Bean)的配置和生命周期
将简单的组件配置、组合成复杂的应用
BeanFactory 和 ApplicationContext
ApplicationContext
BeanFactory的子接口
继承MessageSource,支持国际化
统一资源文件的访问方式
提供在监听器中注册Bean的事件
同时加载多个配置文件
载入多个(有继承关系)上下文,使得每一个上下文都专注于一个特定的层次,比如应用web层
容器启动时,一次性创建所有bean
可以以声明的方式创建,如使用ContextLoader
BeanFactory
采用延迟加载的方式注入bean,调用getBean()时注入bean
通常以编程的方式被创建
Bean的生命周期
解析类得到BeanDefinition
如果有多个构造方法,则要推断构造方法
确定好构造方法后,进行实例化得到一个对象
对对象中加了@Autowired注解的属性进行填充
回调Aware方法,比如BeanNameAware,BeanFactoryAware
调用BeanPostProccessor的初始化前的方法
调用初始化方法
调用BeanPostProccessor的初始化后方法,在这里进行AOP
如果当前创建的bean是单例的,则放入单例池
使用bean
Spring容器关闭时调用DisposableBean中的destory()方法
Bean的作用域
singletion
默认,每个容器中只有一个bean的实例
由BeanFactory自身来维护
生命周期与Spring IO容器一致
prototype
为每一个bean请求提供一个实例
在每次注入时都会创建一个新的对象
request
bean被定义为在每个http请求中创建一个单例对象
在单个请求中都会复用这一单例对象
请求结束后,实例回收
session
与request范围类似,确保每个session中有一个bean实例,在session过期后,bean会随之消失
application
bean被定义为在SevletContext的生命周期中复用一个单例对象
websocket
bean被定义为在websocket的生命周期中复用一个单例对象
global-session
全局作用域
基本不用
单例Bean是线程安全的吗
不是线程安全的
有状态需要处理线程安全问题
可以使用ThreadLocal
加锁
使用了哪些设计模式
简单工厂
BeanFactory
工厂方法
FactoryBean
单例模式
适配器模式
**HandlerAdapter
装饰器模式
wrapper
decorator
动态代理
观察者模式
listener
事件驱动模型
策略模式
资源访问Resource接口
@Autowired和@Resource
工作原理
Springboot
springboot 自动装配原理
0 条评论
下一页