注:这篇博客主要记录一些我觉得作为一个 Java 开发所应该知道的基础知识。有的内容我觉得有些博客已经写的很清晰了,我就会直接复制过来并标明原文链接。
一、Java 核心
1. final、static、static final修饰的字段赋值的区别
static修饰的字段在类加载过程中的准备阶段被初始化为0或null等默认值,而后在初始化阶段(触发类构造器)才会被赋予代码中设定的值,如果没有设定值,那么它的值就为默认值。
final修饰的字段在运行时被初始化(可以直接赋值,也可以在实例构造器中赋值),一旦赋值便不可更改;
static final修饰的字段在Javac时生成ConstantValue属性,在类加载的准备阶段根据ConstantValue的值为该字段赋值,它没有默认值,必须显式地赋值,否则Javac时会报错。可以理解为在编译期即把结果放入了常量池中。
原文链接:https://blog.csdn.net/zhuoxiuwu/article/details/47293111
2. Java 注解的原理
Java 注解的本质是接口。实现技术是:JDK 动态代理。
精品博客:https://juejin.im/post/5b45bd715188251b3a1db54f
3. Java 枚举的原理
4. Java 反射类
AnnotatedElement 表示可以加注解的元素,也就是注解可以加到的地方,都会实现该接口。比如:Class、Method、Field、Constructor 这个四个类都实现了 AnnotatedElement 这个接口。
Member 接口表示成员。一个类的成员由构造方法、普通方法、属性(成员变量、静态变量)组成,所以 Method、Field、Constructor 这三个类都实现了 Member 接口。
5. Cglib 原理
https://juejin.im/post/5b3e05caf265da0f652364ce#heading-1
6. Java Stream 流的实现原理
7. Java 语法糖
8. 自旋锁是如何保证公平的
二、JVM
1. 如何查看 Java 字节码
https://blog.csdn.net/w605283073/article/details/103209221
2. JVM 是如何处理异常的
流程如下:
1、编译而成的字节码中,每个方法都附带一个异常表。
2、异常表中每一个条目代表一个异常处理器。
3、触发异常时,JVM会遍历异常表,比较触发异常的字节码的索引值是否在异常处理器的from指针到to指针的范围内。
4、范围匹配后,会去比较异常类型和异常处理器中的type是否相同。
5、类型匹配后,会跳转到target指针所指向的字节码(catch代码块的开始位置)。
6、如果没有匹配到异常处理器,会弹出当前方法对应的Java栈帧,并对调用者重复上述操作。
上述文字来源于其他网站,忘记是哪个网站了,若有侵权,请联系我标注出处。
上述流程结合以下 demo 看更好理解。
编译后的 main 方法字节码:
异常表:
三、Mysql
1. redo log 为什么能保证 crash safe 机制?
crash safe机制主要得益于二阶段提交的设计。事务开始时是 redolog prepare,然后执行事务,最后 redolog commit 最终提交。
当数据库发生 crash 的时候,可以检查 redolog 文件:
- 如果状态为 commit,则证明该事务实际应已提交直接当成脏页刷入硬盘即可。
- 如果状态不为 commit,则检查相应的 binlog 是否完整。如果完整则提交,如果不完整则回滚。
这样就保证发生 crash 时应该提交的就提交,没有做完的事务就回滚。
2. 如何保证 binlog 和 redolog 在事务提交时双写成功?
2.1 背景
MySQL 为了保证 master 和 slave 的数据一致性,就必须保证 binlog 和 InnoDB redo 日志的一致性(因为备库通过二进制日志重放主库提交的事务,而主库 binlog 写入在 commit 之前,如果写完 binlog 主库crash,再次启动时会回滚事务。但此时从库已经执行,则会造成主备数据不一致)。
2.2 解决方案
在开启Binlog后,如何保证binlog和InnoDB redo日志的一致性呢?为此,MySQL引入二阶段提交(two phase commit or 2pc),MySQL内部会自动将普通事务当做一个XA事务(内部分布式事物)来处理:
https://www.cnblogs.com/xibuhaohao/p/10899586.html