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