java思维导图
2021-08-21 13:09:44 19 举报
AI智能生成
为你推荐
查看更多
java思维导图
作者其他创作
大纲/内容
最常用的数据结构,想象成在尺子上放绿豆,在指定位置放很容易找到,但是数组长度不容易改变
数组
先进后出,想象往桶里放东西,是不是先放进去的最后才能拿出来
栈
先进先出,此处想象排队,先排的人先走
队列
想象成链条,一个个的小锁链组成一条链表,中间可以岁随意取下一块,但是想找到指定位置的一块只能从头开始数
链表
就是类似我们思维导图这种形式的父子节点之间的关系
一个父节点可能有一个或者不止一个子节点,也可能没有子节点
我们最长用到的就是二叉树
这里去了解一下红黑树,再关注一下hashmap的源码
树
无序数组中想要找到指定的值在哪很困难,只能自己一个个去比较
但是我们可以在放入的时候就进行一个哈希运算(通过给定的值,进行一次地址运算,得到一个下标),放在下标处
下次再取这个元素的时候,我们再进行哈希运算得到下标,直接访问
就是我们不同的元素进行哈希运算后得到的下标可能是一样的,就产生了哈希冲突
问题描述
我们的数组存储的是链表节点
产生冲突时,把后来的元素挂在这个链表后面就可以了,这是尾插法
也可以插在链表头部,这叫头插法
数组 + 链表
方法很多,这里着重关注拉链法
解决方法
哈希冲突
散列表
分为大顶堆、小顶堆
堆
迪杰斯特拉算法
图
八大数据结构
七大查找算法
十大排序算法
牛客-剑指offer
力扣-all
各个大厂模拟题
面经遇到的题
刷题
设计模式
内功需要持续修炼,并且很早就需要修炼,直到自身十分强大也不能丢弃
内功
html
css
js
祖传三大件
LayUI
ElementUI
UI框架
VUE简单入门
Vue
必看框架
前端
前期疯狂模仿别的网页熟练用法,中期利用框架快速开发,后期学习Vue
尚硅谷Java全集跟完,你就知道什么是Java了
2字节、16位
char
字节型
1字节、8位,但是只有1位有效,另外7位置0
boolean
布尔型
1字节、8位
byte
short
4字节、32位
int
8字节、64位
long
整型
float
double
浮点型
八大基本数据类型
基本数据类型就是比较值
引用数据类型就是比较地址
“==”
本质上就是“==”
有些类重写了equals方法,像String、Integer等,就是比较值了
equals
“==”和 equals 的区别
因为euqals判断的是对象是否相等,如果对象相等,那么他们的hashcode也应该相等
但是hashcode原本是通过地址计算的,所以我们要进行重写
为什么重写equals,必须重写hashcode
不一定
散列表中,hashcode相等发生哈希冲突,equals不相等
hashcode相等,euqals一定相等吗?
必须初始化,且值不能更改
修饰变量
被修饰的方法不能被重写
修饰方法
被修饰的类不能被继承
修饰类
final的作用
如果之前在常量池中已经存在abc,那么只创建一个对象
如果常量池中不存在abc,那么就是两个对象,因为jvm会先检查我们的常量池中是否存在abc,不存在会先创建
String str = new String(\"abc\"); 创建了几个对象
String
不可变字符串
线程安全,效率低
StringBuffer
线程不安全,效率高
StringBulider
可变字符串
字符串类型对象
StringBuffer、StringBulider的reverse()方法
字符串反转
同步阻塞IO
BIO
同步非阻塞IO
多个socket链接,一个线程处理
通过channel频道实现多路复用
阻塞的不再是socket进程,而是系统调用
select
poll
epoll
系统调用
IO多路复用
NIO
异步非阻塞IO
基于事件和回调机制实现
AIO
BIO、NIO、AIO
在遍历集合元素并进行操作时,可能会引发ConcurrentModificationException异常
这是由于底层进行操作的时候会记录一个modCount和当前的Count,而进行删除操作会引发当前Count不等于modCount,引发异常
所以需要使用迭代器进行操作
迭代器
继承Thread类,重写run方法
实现Runnable接口,实现run方法,用Thread包装
实现Callable接口,实现call方法,用FutureTask包装Callable对象实现执行结果返回,最后再用Thread包装
线程池创建线程
创建线程的方式
sleep来自Thread类,而wait来自Object类
sleep不释放锁,而wait释放锁
sleep到时间自动恢复,而wait可以通过notify、notifyAll提前唤醒
sleep和wait的区别
常见问题
Java EE
Server是顶层容器,代表整个服务器,包含多个Service
每个Service包含**多个Connector**和**一个Container**,对外提供服务
每个Connector负责连接相关的事情,提供socket与Request和Response相关转换
Container用于封装和管理Servlet,以及具体处理Request请求
简介
监听socket通道,将socket接收到的数据转发给Processor
Endpoint
接收并解析来自Endpoint的http请求,封装成Request转发给Adapter
Processor
接受来自Processor的Request对象,并把Request对象封装成ServletRequest,转发给Container,这里用到了**门面模式**
Adapter
Connector
共同组成ProtocolHandler
一个Service只有一个Engine
Engine
一个Engine可以有很多个虚拟主机(Host)
Host
每个Host又可以有很多个web程序(Context)
Context
每个Context又对应很多个Servlet(Wrapper),Wrapper作为最底层的容器,不再有子容器
Wrapper
Container
架构关系
整体架构
点击startup.bat启动tomcat,这个批处理命令会去找catalina.bat
在catalina.bat中做了一件事,就是去找Bootstrap的main方法
其实我抽取出来的重点是找到Bootstrap的main方法,但是中途有很多的系统验证,比如是否安装jdk等等,其中涉及的变量还是很多的
那为什么要一个文件一个文件找呢?为什么不直接打开Bootstrap的main方法呢?
进入到BootStrap的main方法后,首先加上一个同步锁,再执行init初始化方法
init方法中,通过反射创建Catalina实例,并设置成守护线程
然后执行load加载方法,这个load方法执行完后,从server、service一直到context都被初始化完成了,这里是个嵌套的关系
执行完load方法后,执行start方法,再从server、service到ProtocolHandler都执行start方法,和上面一样,是嵌套关系
这里面同时还涉及到一个线程池的创建和初始化,这个操作紧跟在Service后面,Engine前面
启动流程
Endpoint的NIOEndpointAcceptor监听socket端口,接受到请求,将请求转发给Processor
Processor将接受到的socket请求封装成Request对象
因为Container接受的是HttpRequest,而不是Request,所以adaptor的实现类coyoteAdapter会把Quest对象封装成HttpRequest,转交给Comtainer,这里设计到门面模式,其实就是进行了对象封装
这个接受请求转发给Container的整体实现有两种,一种是基于ajp实现的potocolHandler,一种是基于http1.1实现的protocolHander
Connector阶段
Engine、Host、Context、Warpper都有标准的实现类,名字叫做StandardXXX
这个其实就相当于一个拦截器,请求在每层容器传递过程中都要进行一些该层容器的处理,再交给下层的子级容器
管道通常由一个基础阀和若干普通阀组成,基础阀就是在该级容器和下层容器间建设桥梁,起到传递的作用,而普通阀就是用来做逻辑处理的
这里涉及到了责任链模式,在每层容器中都可以通过getPipeline得到管道对象,再由getFirst().invoke()执行第一个阀门逻辑,然后通过getNext().invoke()执行下个阀门逻辑
在请求传递过程中,会出现一个管道机制,它由pipeline和valve组成
最终会到达相对于的servlet执行具体的doGet、doPost方法,然后返回结果
Container阶段
请求流程
BootStrapClassLoader
ExtensionClassLoader
ApplicationClassLoader
用户自定义的ClassLoader
加载过程从下到上寻找,再从上到下加载
什么是双亲委派机制
这是为了防止java核心类被篡改
为什么需要双亲委派机制
tomcat打破双亲委派机制
如果没有线程池的话,每个请求到来的时候都会去开启一个线程对请求进行处理,若果一瞬间打来了上千个请求,会瞬间开启很多线程,直接就会导致服务器宕机,但是线程池在请求过多的时候会把暂时无法处理的请求存储在等待队列中,再者,线程池还有饱和策略应对请求过多的情况
另外就算请求量没有很高,每个请求来了还是得申请线程处理,线程线程完毕后立即销毁,不断的请求打过来,就会不断的重复这个过程,会给系统带来巨大的性能开销,我看过linux对于线程销毁的处理,线程的销毁并不是立刻销毁的,而是批量回收的,这个回收的过程会占用cpu资源,影响其他线程的运行,所以我们应该减少线程的销毁这一操作,线程池的线程的run方法是死循环的,它会不断的从队列中取任务执行,而不被销毁,这就减少了线程销毁这一操作带来的性能消耗,大幅提高了多线的的性能
为什么使用线程池
我们发起http请求,tomcat就接受到请求会封装两个对象,一个是request,一个是response
request就是我们的请求,会转发给相对应的servlet,然后处理的结果会保存在respoonse中,由tomcat把response转换成流,再通过tomcat返回给前端
void类型的doGet()和doPost()怎么返回数据
tomcat
spring
springmvc
mybatis
SSM框架
web开发
springboot
mybatis-plus
其他框架
后端
存储引擎
索引
事务
MVCC
explain分析
sql执行过程
慢查询优化
MySQL
基本数据类型
数据过期
持久化
主从复制
哨兵模式
缓存穿透
缓存击穿
缓存雪崩
布隆过滤器
分布式锁
Redis
数据库
cd XXX
进入当前目录的XXX目录
cd /
进入根目录
cd ../
进入上级目录
切换
ls
查看当前目录和文件
ls -a
查看当前目录和文件以及隐藏文件
查看
mkdir
创建
rm XXX
删除
rm -r
递归删除
rm -rf
递归不询问删除
mv aaa bbb
重命名aaa为bbb
mv aaa /home
剪贴aaa到home
cp -r aaa /home
拷贝aaa到home
修改
目录
vim xxx
进入xxx文件
i
开启编辑模式
ESC
退出编辑模式
:wq
保存并退出
:q!
撤销操作,退出
修改文件
chmod rwx
权限修改
tar -zcvf xxx.bar [xxx.txt........]
打包
tar -zxvf xxx.tar
解压
打包和解压缩
ps -ef
查看当前进程
ps -ef | grep xxx
带管道符的过滤查看
kill -9 pid
杀死进程
进程相关
su
sudo
切换用户
pwd
查看当前路径
常用命令
firewall-cmd --list-ports
查看当前端口开放情况
firewall-cmd --pernament --add-port=8888/tcp
打开某个端口
firewall-cmd --permanent --remove-port=8888/tcp
关闭某个端口
systemctl restart firewalld
无success提示
firewall-cmd --reload
有success提示
重启防火墙
linux端口开放
端口开放
Linux
jvm虚拟机
点击链接移步
JVM虚拟机
并发编程
应用层
视图层
会话层
传输层
网络层
数据链路层
物理层
OSI七层模型
网际层
网络接口层
TCP/IP四层模型
tcp面向有连接的服务
udp面向无连接的服务
面向连接
tcp以字节为单位进行传输
udp以报文为单位进行传输
传输单元
tcp是可靠的传输服务
udp是不可靠的传输服务
可靠与否
tcp传输速度慢
udp传输速度快
传输速度
TCP、UDP区别
校验和机制(CRC循环冗余码)
传输前后数据是否发生变化
序列号应答机制
传输过程是否丢失数据
超时/重传机制
丢失数据怎么办?
滑动窗口机制
序列号应答导致传输效率低
拥塞控制
网络拥塞怎么办
TCP如何实现可靠传输
三握四挥过程
TCP连接的三握四挥
访问一个网站的全过程
HTTP的各个版本及特性
session存储在服务器
cookie存储在浏览器
存储位置
session生成同时会有一个sessionID,会存储在cookie中,用户请求带着cookie,服务器就能拿到sessionID,就可以访问用户session
关系
可以的
只需要在url后面拼接sessionID就行了
如果浏览器禁用cookie,还可以使用session吗?
cookie、session
HTTP如何保存用户状态
HTTP、HTTPS区别
计算机网络
原理
Dubbo(相关框架)
RPC
springcloud
zookeeper
分布式开发
kafka(常用框架)
消息队列
java修炼手册
0 条评论
回复 删除
下一页