阿里P6需要掌握的Java技术栈
2020-04-07 11:34:58 4 举报
AI智能生成
Java技术栈
作者其他创作
大纲/内容
java基础
javaSe
8种数据类型
boolean 1字节
byte 1字节
char 2字节
short 2字节
int 4字节
float 4字节
long 8字节
double 8字节
实例化
new
clone
通过反射机制创建
反序列化
四种引用类型
目的
可以让程序员通过代码的方式来决定某个对象的生命周期;
有效利用垃圾回收
强引用
gc不会回收,内存不足时,宁可报OutOfMemeryException
软引用
发生gc不回收,当gc后,内存还是不够时,gc会回收
弱引用
只要发生gc就会回收
应用:ThreadLocal、WeakHashMap
虚引用
作用回收对象时通知
当发生GC,虚引用就会被回收,并且会把回收的通知放到ReferenceQueue中。
在NIO中,就运用了虚引用管理堆外内存。
面向对象
三大特性
继承
多态
封装
七大设计原则
单一职责
类所具有的功能尽量单一。
开闭
对扩展开放,对修改关闭。
依赖倒转
抽象不应该依赖于细节,细节应该依赖于抽象
针对抽象(抽象类或接口)编程,而不是针对实现编程
里氏替换
所有引用基类(父类)的地方必须能透明地使用其子类的对象。
接口隔离
使用多个专门的接口,而不使用单一的总接口,即客户端不应该依赖那些它不需要的接口。
接口隔离原则与单一职责原则区别: 其一,单一职责原则注重的是职责;而接口隔离原则注重对接口依赖的隔离。
其二,单一职责原则主要是约束类,其次才是接口和方法,它针对的是程序中的实现和细节;
而接口隔离原则主要约束接口接口,主要针对抽象,针对程序整体框架的构建。
其二,单一职责原则主要是约束类,其次才是接口和方法,它针对的是程序中的实现和细节;
而接口隔离原则主要约束接口接口,主要针对抽象,针对程序整体框架的构建。
合成复用
复用时要尽量使用组合/聚合关系(关联关系),少用继承。
迪米特
一个软件实体应当尽可能少地与其他实体发生相互作用,低耦合。
IO
区分阻塞、非阻塞、同步、异步
阻塞:等待结果返回,当前操作线程被挂起,后续操作被阻断
非阻塞:不等待返回结果,直接执行后续操作
同步:轮询模型
异步:监听模型
IO(同步阻塞IO)
NIO(同步非阻塞IO),利用多路复用技术
传统IO(BIO)与NIO的区别:IO是面向流的,NIO是面向缓冲区的
主要组成
Channel(通道,双向)
多路复用。传统IO的流是单向的,不能同时用来进行读写操作,而Channel则是双向的
通过open()静态方法打开一个通道
Selector(选择器)
Selector类是NIO的核心类,它能够检测多个注册的Channel上是否有事件发生,如果有事件发生,便获取事件然后进行相应的处理
通过Selector.open()静态方法选择一个事件进行处理
Buffer(缓冲区)
其作用相当于BIO编程中常用的基本类型数组(byte[]、char[]等), 比如ByteBuffer就是对byte数组进行的封装,使得操作起来更方便
使用的是堆外内存,不受GC管理(GC主要是堆内存)
非线程安全
Netty/Mina框架
基于NIO的高性能网络框架,通常用于分布式应用开发中进行网络数据传输
AIO(异步非阻塞IO)
输入流/输出流
字节流/字符流
集合
Collection接口
List
set
Map
hashMap
LinkedHashMap
HashTable
SortedMap接口
Map接口的有序子接口,按照键的自然顺序或指定排序规则Comparator进行排序
TreeMap
继承SortedMap
底层就是红黑树算法的实现
线程不安全
ConcuurrentHashMap
网络编程
Socket
基于TCP/UDP,它是为进行TCP/UDP编程提供的API
多线程
java新版本特性
javaEE
基础
Servlet
jsp
监听器
过滤器
cookie
为了弥补HTTP协议无状态的不足而引入的机制。由服务端创建,但由客户端(浏览器)保存。
session
服务器中间件
nginx
核心配置文件nginx.conf
常用命令
开发框架
spring
IOC
WebApplicationContext:即Spring IOC容器,由容器创建和管理Bean,使用时直接从容器中获取
AOP
动态代理
JDK动态代理(针对接口,代理类为其兄弟类)
CGLIB动态代理(针对类,代理类为其子类)
拦截器
事务管理
只会回滚RuntimeException异常
五大事务隔离级别
七大事务传播特性
Spring Boot
”约定优于配置“思想
ORM框架
Hibernate
Mybatis
SpringMVC
数据库
关系型数据库
SQL Server、MySQL、Oracle等
SQL语法
ddl
数据定义语言,用于数据库表结构的相关操作,如创建表CREATE、删除表DROP、添加表索引等。
dml
数据操作语言,通过GRANT或REVOKE获得许可,确定单个用户和用户组对数据库对象的访问
dql
数据查询语言,select、where、order by、group by、having等动词
dcl
数据操纵语言,实现对数据库表数据的查询、增加、删除和修改操作,包括insert、update、delete
sql执行顺序
语法顺序:SELECT -> DISTINCT -> FROM -> JOIN ON -> WHERE -> GROUP BY -> HAVING -> UNION -> ORDER BY
执行顺序:FROM -> WHERE -> GROUP BY -> HAVING -> SELECT -> DISTINCT -> UNION -> ORDER BY
数据库设计
三大范式
1NF,每个字段具有原子性
2NF,每个字段都与主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言)
3NF,每个字段都与主键直接相关,不能间接相关
事务
ACID
原子性Atomicity
一致性Consistency
隔离性Isolation
并发的事务之间是相互隔离的,事务内部的操作对于其他事务而言都是互不可见的。 如果不考虑隔离性,就可能发生脏读、不可重复读、幻读的问题
脏读
一个事务读取了另一个事务改写但还未提交的数据,如果这些数据被回滚,则读到的数据无效。
不可重复读
在同一事务中,多次读取同一数据返回的结果不同。
幻读
个事务读取了几行记录后,另一个事务插入一些记录。后来的查询中,前一个事务就会发现有些原来没有的记录。
持久性Durability
隔离级别
读未提交
读已提交(oracle默认)
可重复读(mysql默认)
串行化
索引
一种有序的数据结构
按照物理结构
聚集索引
主键索引
若没有主动定义主键,则第一个唯一索引会被作为主键。若没有唯一索引,会自动添加一个隐藏的主键作为聚集索引,这个隐藏的主键是一个6个字节的列
索引中的数据物理存放地址和索引的顺序是一致的
一个表只能包含一个聚集索引
非聚集索引
数据和索引分开单独存放在不同的文件中,索引文件不存储数据,而是存储数据的地址
数据库表中记录的物理顺序与索引顺序可以不相同。一个表中可以包含多个非聚集索引
普通索引
唯一索引
全文索引
仅可用于 MyISAM 表,针对较大的数据,生成全文索引很耗时好空间。
组合索引
为了更多的提高mysql效率可建立组合索引,遵循”最左前缀“原则。
数据结构
Btree索引
以B/B+树的数据结构存储,应用范围广
Hash索引
mysql只有MEMORY存储引擎显示支持哈希索引。
通过Hash算法计算索引位置,效率高,一次定位。
但需要解决Hash冲突。不支持范围检索
数据库优化
方法
mysql使用explain进行分析
oracle ,explain plan for
设计表
字段避免null,可以默认0
尽量使用int,非负可以使用UNsigned(数字扩大一倍)
尽量使用timestamp,而不是datetime
使用枚举或者整数代替字符串
单表字段建议在20以内
用整形来存储IP
索引
查询频繁的列,在where,group by,order by,on从句中出现的列
长度小的列,索引字段越小越好,因为数据库的存储单位是页,一页中能存下的数据越多越好
尽量不使用唯一索引
不用外键,由程序保证约束
组合索引的顺序,要与查询条件保持一致,同时删除不必要的单列索引
子主题
非关系型数据库
Redis
todo
MongoDB
分布式数据库
Apache HBase
ElasticSearch
Alibaba OceanBase
接口服务
RPC
一种调用过程的方案/范式/实现。
具体实现
基于第七层应用层HTTP协议的REstful
第四层网络层TCP/IP协议
框架
Alibaba dubbo
Google grpc
RESTful
对资源的操作有获取、创建、修改和删除,与HTTP协议提供的GET、POST、PUT、DELTE等方法相对应
RMI
可以看成是RPC的Java实现,同时它也是JNDI(即Java Naming and Directory Interface,Java命名和目录接口)规范的一种实现
Web Service
大数据
高并发
概念
大量用户同时访问请求网站或系统,造成请求不能及时响应的现象
解决思路
负载均衡Load Balance,简称LB
硬件
F5
软件
nginx
Linux服务器集群系统LVS(Linux Virtual Server)
HaProxy
服务器集群
服务器集群就是指将很多服务器集中起来一起进行同一种服务,在客户端看来就像是只有一个服务器。
Tomcat服务器集群
Nginx + Tomcat:一台Nginx服务器进行反向代理与请求分发,多台Tomcat服务器处理请求
数据库服务器集群
锁机制
分布式锁
基于数据库实现
锁表
创建一张锁表,当需要锁住某个方法或资源时,我们就在该表中增加一条相应的记录,想要释放锁的时候就删除该条记录
排他锁
在查询语句后面增加for update,数据库会在查询过程中给数据库表增加排他锁,直到事务提交后才会释放锁
基于redis实现
如redis、memcached等
基于zookeeper
java锁
用于保证线程同步
synchronized
lock
CAS
数据库锁
乐观锁
悲观锁
共享锁
排他锁
加缓存
问题
缓存一致性
先更新数据库,再删除缓存
缓存穿透
同一时间大量请求查询不存在的缓存,造成后端数据库压力增大
接口层增加校验,如用户鉴权校验,id做基础校验,id<=0的直接拦截;
从缓存取不到的数据,在数据库中也没有取到,这时也可以将key-value对写为key-null,缓存有效时间可以设置短点,如30秒(设置太长会导致正常情况也没法使用)。这样可以防止攻击用户反复用同一个id暴力攻击
缓存雪崩
缓存在同一时间大面积失效
缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生。
如果缓存数据库是分布式部署,将热点数据均匀分布在不同搞得缓存数据库中。
设置热点数据永远不过期。
缓存击穿
缓存击穿是指缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力
设置热点数据永远不过期。
加互斥锁。获取不存在的缓存时,加锁访问数据库
好处
减轻数据库如MySQL、Oracle等的压力
提高访问速度
常用缓存中间件
Redis
数据类型
string
hash
list
set
zset
存储
持久化
RDB快照
Append-only file(缩写为AOF)日志
memcached
只支持key-value数据结构存储
缓存数据全部在内存中,不支持数据持久化
EhCache
CDN(Content Delivery Network,内容分发网络)缓存
服务降级
限流
限流算法
集群限流
为了控制访问次数,肯定需要一个计数器,而且这个计数器只能保存在第三方服务
单机限流
计数器
限制1s内的能通过的请求,qps=100,则每秒只能通过100个请求,其余的将被拒绝
缺点是:会产生突刺现象,通过的请求不均匀
漏桶
通过漏桶算法进行限流,每10毫秒处理一次请求
算法实现方面,可以准备一个队列,用来保存请求,另外通过一个线程池定期从队列中获取请求并执行,可以一次性获取多个并发执行。
缺点是,无法应对短时间内大流量
令牌桶
在令牌桶算法中,存在一个桶,用来存放固定数量的令牌。算法中存在一种机制,以一定的速率往桶中放令牌。每次请求调用需要先获取令牌,只有拿到令牌,才有机会继续执行,否则选择选择等待可用的令牌、或者直接拒绝
令牌桶,可以应对突发流量,同时可以控制范访问的速度
可以解决突刺,在突发流量将桶中令牌全部获取后,会按照一定速率继续产生令牌,可以继续访问
滑动窗口
记录每个小周期中的访问数量)
相对实现。滑动窗口的格子划分的越多,那么滑动窗口的滚动就越平滑
网页HTML静态化
数据库读写分离、分表分库
图片服务器分离
限流
常用工具
性能优化
性能测试
Jmeter
JVM参数调优
内存泄漏
内存使用后未得到及时释放,而且不能被GC回收,导致虚拟机不能再次使用该内存,此时这段内存就泄露了
内存溢出OOM
即OutOfMemoryError,当没有足够的空闲内存可供程序使用时出现
Java Heap Space : Java堆内存溢出
此种情况最常见,一般由于内存泄露或者堆的大小设置不当引起。 对于内存泄露,需要通过内存监控软件(如heapdump)查找程序中的泄露代码;而堆大小可通过设置JVM的参数-Xms、-Xmx来解决
PermGen Space:永久代内存溢出
即方法区内存溢出,如果程序加载的类过多,或者使用反射、gclib等这种动态代理生成类的技术,就可能导致该区发生内存溢出。 此种情况可以通过更改方法区的大小来解决,设置-XX:PermSize=64m -XX:MaxPermSize=256m参数。
另外,过多的常量尤其是字符串也会导致方法区溢出,因为常量池也位于方法区中。
注:从Java8开始移除了Permgen Space,取而代之的是MetaSpace
注:从Java8开始移除了Permgen Space,取而代之的是MetaSpace
StackOverFlowError:栈溢出
即虚拟机栈或本地方法栈区域内存溢出
出现原因:程序中出现死循环或递归次数过多;也可能是栈大小设置过小导致,可通过设置-Xss参数来调整栈大小。
监控工具
jps:查看Java进程
jmap:查看JVM当前的堆内存快照(heapdump)
jstack:查看JVM当前的线程快照,又称threaddump文件,它是JVM当前每一条线程正在执行的堆栈信息的集合
jinfo:实时查看JVM的参数信息
jstat:用于监控JVM的各种运行状态信息,如类的装载、内存、垃圾回收、JIT编译器等
jconsole:用于监控内存,线程、堆栈等信息
jprofile:类似于jconsole,比jconsole监控的信息更全面
程序优化
软件架构
SOA
是一种粗粒度、松耦合服务架构,各服务间均需要基于ESB(Enterprise Service Bus,企业服务总线)进行消息通信
微服务
设计模式
创建型5种
单例模式
不安全
懒汉
线程安全
枚举
饿汉
匿名内部类
双重校验锁
工厂模式
抽象工厂模式
建造者
原型模式
对象克隆
深克隆
1、实现序列化接口Serializable 2、通过字节数组流和对象流进行克隆
浅克隆
Object的clone方法
结构型7种
适配器模式
代理模式
装饰
1、通过创建一个包装类来扩展一个类的功能(比如添加新的方法),是对继承的一种替代方案,但能达到与继承一样的效果; 2、装饰类和原有类需要实现相同的接口,这样一来在任何使用原始对象的地方都可以使用装饰对象来替代;
3、装饰类中维护一个原有类型接口的引用
3、装饰类中维护一个原有类型接口的引用
特点:被装饰的对象一般会作为构造方法的参数传入装饰器类
与代理模式的区别: 装饰模式可以在不改变原有类的情况下对原有类进行功能扩展(增加方法);
而代理模式不会扩展原有类的功能(方法),只能控制在调用原有类的访问操作前后增加额外的操作,比如记录操作日志。
而代理模式不会扩展原有类的功能(方法),只能控制在调用原有类的访问操作前后增加额外的操作,比如记录操作日志。
外观模式
桥接
组合模式
享元模式
行为型11种
模板方法模式
观察者模式
应用:MVC(Model-View-Controller,当模型M(目标)中的数据改变时,通知相应视图V(观察者)做出改变)、Event Listener事件监听机制
策略模式
应用:SpringMVC中的HandlerMethodArgumentResolver,根据不同的参数或注解类型选择不同的参数解析器进行解析(即参数绑定)
迭代模式
责任链模式
命令模式
备忘录模式
状态模式
访问者模式
中介者模式
解释器模式
JVM
类加载机制
加载过程
加载-连接-验证-准备-解析-初始化-
类加载器
BootstrapClassLoader
启动类加载器:负责加载java基础类,主要是 %JAVA_HOME/jre/lib/rt.jar中的类。它是用C++语言写的。 由JVM启动,然后初始化sun.misc.Launcher ,sun.misc.Launcher初始化Extension ClassLoader、App ClassLoader。
ExtensionClassLoader
扩展类加载器:主要负责加载%JAVA_HOME%/jre/lib/ext/*.jar中的类
AppClassLoader
应用程序类加载器:主要负责加载应用中classpath目录下的类。
自定义ClassLoader
自定义ClassLoader需要继承ClassLoader抽象类,重写findClass方法,这个方法定义了ClassLoader查找class的方式。
双亲委派模型
当加载一个类的时候会先委托给父类加载器去加载,当父类加载器无法加载的时候再尝试自己去加载,因此类的加载顺序是”自上而下“的。采用这种方式的好处: 1、主要是保证了安全性,避免用户自己编写的类动态替换Java的一些核心类,比如 java.lang.String;
2、避免了类的重复加载,因为在JVM中只有类名和加载类的ClassLoader都一样才认为是同一个类(即使是相同的class文件被不同的ClassLoader加载也被认为是不同的类)
2、避免了类的重复加载,因为在JVM中只有类名和加载类的ClassLoader都一样才认为是同一个类(即使是相同的class文件被不同的ClassLoader加载也被认为是不同的类)
子主题
GC垃圾回收策略
垃圾回收的目标区域
堆
方法区
主要包括对废弃的常量和无用的类进行回收
垃圾判断方法
引用计数法
无法解决循环引用
可达性分析
从GC Roots开始向下搜索,搜索所走过的路径称为引用链。当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的。即为不可达对象,所以会被判定为是 可以回收的对象。
在Java中,GC Roots包括: * 虚拟机栈(栈帧中的局部变量表)中引用的对象
* 方法区中类静态属性引用的对象
* 方法区中常量引用的对象
* 本地方法栈中JNI(即native方法)引用的对象
* 方法区中类静态属性引用的对象
* 方法区中常量引用的对象
* 本地方法栈中JNI(即native方法)引用的对象
垃圾回收算法
标记清除
效率和内存碎片问题
标记整理
标记-清除-整理
适用于对象存活率高的场景(老年代
适用于对象存活率高的场景(老年代
复制算法
分区复制回收
适用于对象存活率低的场景(新生代)
适用于对象存活率低的场景(新生代)
分代收集
指的是针对不同分代的内存区域,采用不同的垃圾回收算法
年轻代一般采用复制算法,老年代则一般采用标记-整理算法
垃圾收集器
Serial收集器
ParNew收集器
Parallel收集器
Parallel Old 收集器
CMS收集器
G1收集器
运行时数据区
数据
堆
这是被所有线程共享的一块内存区域,其中存放的是对象实例本身以及数组(数组的引用在栈中)。
划分
年轻代(Young Generation)
年轻代用来存放新创建的Java对象。对年轻代的垃圾回收称为“Minor GC”,采用的是复制清除算法、并行收集器。 为使JVM更好的管理堆内存中对象的分配及回收,年轻代又被分为三个区域:Eden、From Survivor、To Survivor。
注意:年轻代可用内存空间是Eden区+一个Survivor区,另一个Survivor区则保持空闲状态,其中Eden区与一个Survivor区大小比例可以通过 -XX:SurvivorRatio参数进行设置,默认为8,表示Eden区与一个Survivor区大小比值是8:1。
注意:年轻代可用内存空间是Eden区+一个Survivor区,另一个Survivor区则保持空闲状态,其中Eden区与一个Survivor区大小比例可以通过 -XX:SurvivorRatio参数进行设置,默认为8,表示Eden区与一个Survivor区大小比值是8:1。
老年代(Tenured Generation)
年轻代中经过多次垃圾回收没有回收掉的对象将被Copy到老年代,因此可以认为老年代中存放的都是生命周期较长的对象。对老年代中对象的垃圾回收称为“Full GC”,采用的是标记-清除算法。
永久代(Permanent Generation)
简称Perm Gen,位于方法区。用于存放Class、Interface的元数据,其大小跟项目的规模、类、方法的量有关。永久代的对象垃圾回收发生在Full GC过程中。
限流算法
注:Java 8 已经去掉了永久代,用 MetaSpace 予以替代
注: 1)其中年轻代和年老代位于堆内存,堆内存会从JVM启动参数(如-Xmx:3G表示最大堆内存为3G)指定的内存中分配;
2)Perm Gen不位于堆内存中,而是属于方法区,由虚拟机直接分配,但可以通过-XX:PermSize -XX:MaxPermSize 等参数调整其大小。
2)Perm Gen不位于堆内存中,而是属于方法区,由虚拟机直接分配,但可以通过-XX:PermSize -XX:MaxPermSize 等参数调整其大小。
方法区
用于存储已经被虚拟机加载的类、常量、静态变量、编译器编译后的字节码等数据信息。 在方法区中还包含有运行时常量池,它是每一个类或接口的常量池的运行时表示形式,在类和接口被加载到JVM后,对应的运行时常量池就被创建出来。当然并非Class文件常量池中的内容才能进入运行时常量池,在运行期间也可将新的常量放入运行时常量池中,比如String的intern方法。
需要注意的是,虽然方法区逻辑上属于堆内存,但是在JVM规范中并没有强制要求对该区域进行垃圾回收。
运行时常量池
属于方法区。用于存储数值型常量、
指令
程序计数器 Program Counter
也称作PC寄存器。它跟汇编语言中的程序计数器的功能在逻辑上是等同的,用来标识执行的是哪条指令。每个线程都有自己独立的程序计数器,并且相互之间是独立的。
在JVM规范中规定: 1、如果线程执行的是非native方法,则程序计数器中保存的是当前需要执行的指令的地址;
2、如果线程执行的是native方法,则程序计数器中的值是undefined。
2、如果线程执行的是native方法,则程序计数器中的值是undefined。
虚拟机栈
其中存放的是一个个的栈帧,每个栈帧对应一个被调用的方法,在栈帧中包括局部变量表(Local Variables)、操作数栈(Operand Stack)、指向当前方法所属的类的运行时常量池(运行时常量池的概念在方法区部分会谈到)的引用(Reference to runtime constant pool)以及方法返回地址(Return Address)。
本地方法栈
存放native方法信息,也就是由C/C++实现的方法
分布式
CAP
幂等性
分布式系统需要解决的问题
分布式事务
分布式事务是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上。
Session共享
ip hash负载均衡
使用缓存如redis保存Session
通过编写自己的HttpServletRequest实现替代Tomcat的Session管理,然后在Filter中使用
已有的解决方案:Spring Session + Redis
1、引入Spring Session相关jar包
2、在web.xml增加SpringSessionRepositoryFilter配置
3、引入Redis相关jar包,并增加相应的Spring Bean配置
1、引入Spring Session相关jar包
2、在web.xml增加SpringSessionRepositoryFilter配置
3、引入Redis相关jar包,并增加相应的Spring Bean配置
服务器Session复制
收藏
收藏
0 条评论
下一页