Java基础
重载、重写、多态
多态条件
父类引用指向子类实现、重写父类方法、
字符串常量池题目
位运算符>>和>>>
填充0还是1
关键字
transient
修饰的成员变量不被序列化
使用到的地方:ArrayList的elementData数组
为什么最ArrayList不直接序列化元素数组呢?
出于效率的考虑,数组可能长度100,但实际只用了50,剩下的50不用其实不用序列化,这样可以提高序列化和反序列化的效率,还可以节省内存空间。
那ArrayList怎么序列化呢?
ArrayList通过两个方法readObject、writeObject自定义序列化和反序列化策略,实际直接使用两个流
ObjectOutputStream和ObjectInputStream来进行序列化和反序列化。
capacity
容量
wrapper
包装
aware
明白的
filter
过滤器
随web应用启动,init(一次)->dofilter->destroy(一次)
没法注入,因为web应用启动顺序:listener->filter->servlet
intercepter
拦截器,基于Java反射
用法:
- log打印机器id
- 依赖web框架
Java容器
ArrayList
HashMap
hash函数算法
转红黑树的阈值为8和6,因为泊松分布
扩容因子为0.75
JDK8对扩容的优化:不需要再重新计算每一个元素的Hash值
JDK8的五点优化
JDK8尾插法
jdk7的头插法在多线程下会出现环
数据结构
rehash
扩容的时候 1.7 需要对原数组中的元素进行重新 hash 定位在新数组的位置,1.8 采用更简单的判断逻辑,不需要重新通过哈希函数计算位置,新的位置不变或索引 + 新增容量大小。
扩容时机
在插入时,1.7 先判断是否需要扩容,再插入,1.8 先进行插入,插入完成再判断是否需要扩容;
散列函数
1.7 做了四次移位和四次异或,jdk1.8只做一次。
HashSet
网络
http组成
请求报文
响应报文
HTTPS对比http
https=http+ssl
https: 443端口 http: 80端口
https: 传输层 http: 应用层
非对称加密
http1.1
支持长连接,http1.0消耗太大
为此增加了请求头-Connection:Keep-Alive
管道网络运输
支持并发
100Status
HTTP/1.1加入了一个新的状态码100。
客户端事先发送一个只带头域的请求,如果服务器因为权限拒绝了请求,就回送响应码401(Unauthorized);
如果服务器接收此请求就回送响应码100,客户端就可以继续发送带实体的完整请求了。
100状态代码的使用,允许客户端在发request消息body之前先用request header试探一下server,看server要不要接收request body,再决定要不要发request body。
http2.0特点
容器(server、socket)
Lambdajuejin.cn/post/684490…
是不是一个匿名内部类
Lambda 表达式简化了匿名内部类的形式,可以达到同样的效果,但是 Lambda 要优雅的多。虽然最终达到的目的是一样的,但其实内部的实现原理却不相同。
匿名内部类在编译之后会创建一个新的匿名内部类出来,而 Lambda 是调用 JVM invokedynamic指令实现的,并不会产生新类。
作者:古时的风筝 链接:juejin.cn/post/684490… 来源:稀土掘金 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
类加载知识点
JVM加载特点
- 全盘负责,当一个类加载器负责加载某个
Class时,该Class所依赖的和引用的其他Class也将由该类加载器负责载入,除非显示使用另外一个类加载器来载入; - 父类委托,先让父类加载器试图加载该类,只有在父类加载器无法加载该类时才尝试从自己的类路径中加载该类;
- 缓存机制,缓存机制将会保证所有加载过的
Class都会被缓存,当程序中需要使用某个Class时,类加载器先从缓存区寻找该Class,只有缓存区不存在,系统才会读取该类对应的二进制数据,并将其转换成Class对象,存入缓存区。这就是为什么修改了Class后,必须重启JVM,程序的修改才会生效;
优点:
- 防止内存中出现多份同样的字节码
- 保证Java程序安全稳定运行
为什么破坏了双亲委派机制
为什么要破坏:tomcat不只一个server
如何打破:findClass还是loadClass
类、对象、静态方法、静态代码块执行顺序
类加载三种方式:
- 1、命令行启动应用时候由
JVM初始化加载 - 2、通过
Class.forName()方法动态加载 - 3、通过
ClassLoader.loadClass()方法动态加载
是否执行静态代码块
public class LoaderTest {
public static void main(String[] args) throws ClassNotFoundException {
ClassLoader loader= Test.class.getClassLoader();
//使用ClassLoader.loadClass()来加载类,不会执行初始化块
loader.loadClass("com.jvm.loader.Test");
//使用Class.forName()来加载类,默认执行初始化块
ClassLoader loader1 =
Class.forName("com.jvm.loader.Test")
.getClassLoader();
//Class.forName()來加载类,并指定ClassLoader,初始化时不执行静态块
ClassLoader loader2 =
Class.forName("com.jvm.loader.Test",false,loader)
.getClassLoader();
}
}
public class Test {
static {
System.out.println("静态初始化块执行了!");
}
}
扩展:代码加载后执行顺序,静态代码块、类方法、对象方法;继承后的表现
- 在加载一个类之前,虚拟机总是会试图加载该类的父类,因此父类的
<clinit>总是在子类<clinit>之前被调用,也就是说,父类的static块优先级高于子类
未整理
spring版本号
Spring Boot、Spring Cloud版本区别
boot
- snapshot: 快照
- alpha : 内测
- beta : 公测
- release : 稳定版本
- GA: 最稳定版本
- Final : 正式版
cloud
- CURRENT:当前推荐的版本。
- GA:稳定版,可用于生产
- PRE :里程碑版/预览版本
- SNAPSHOT : 快照
CAS重试和TLAB
BF和AC继承关系
反射机制概念
JDK6\7\8中方法区的变化
静态变量
字符串常量池
运行时常量池
字符串常量池、静态变量移动到堆中
符号引用和直接引用
- 符号引用:字符串,能根据这个字符串定位到指定的数据,比如java/lang/StringBuilder
- 直接引用:内存地址
首先:JVM 和 class 都有属于自己的数据结构
其次:class文件在被加载到jvm内存中时候,JVM根据class文件的数据结构规则, 拆分读取class文件,然后把对应的数据放入JVM中
class字节码的数据结构从前至后,包括 魔/版本/常量池/访问标志/类索引/父类索引/接口索引/字段表/方法表/属性表
虚拟机加载
虚拟机加载经历 加载--验证--准备--解析--初始化--使用--卸载,《深入理解Java虚拟机》-周志明,书中说,加载过程中也可以验证,我觉得没问题,比如,我读取了class的前四个字段,加载进来了,然后就直接验证,看看魔数对不对,不对我就不再加载。这个很OK。
比如魔数对了,那么我再加载四个字节,然后验证,看看版本号能不能被JVM解释,不能就报错,也很OK。
log日志
Redis
MySQL
基础:
执行顺序:
事务超时处理
事务隔离级别对并发影响
事务隔离级别对应锁
Tomcat
架构组成、处理请求流程
war包和jar包区别:
jar包和war包的区别:jar包是java打的包,war包可以理解为javaweb打的包,这样会比较好记。jar包中只是用java来写的项目打包来的,里面只有编译后的class和一些部署文件。而war包里面的东西就全了,包括写的代码编译成的class文件,依赖的包,配置文件,所有的网站页面,包括html,jsp等等。一个war包可以理解为是一个web项目,里面是项目的所有东西。
Socket底层、与Http、Tcp的关系
\