**Java 为什么跨平台**
先将java文件编译成字节码(.class)文件, 在所有的平台上生成的字节码文件都是相同的。
再使用Java虚拟机运行字节码文件。因为不同操作系统有对应版本的jvm, 这使得同一个java代码文件可以在不同的平台上运行。
**.class 文件里是什么**
.源代码经过编译器编译之后会生成一个字节码文件, 字节码是一种二进制的类文件, 它的内容是JVM的指令.
**JVM 的生命周期**
**虚拟机的启动**
Java 虚拟机的启动是通过引导类加载器(bootstrap class loader) 场景一个初始类(initial class) 来完成的 , 这个类是由虚拟机的具体实现指定的.
**虚拟机的退出有如下几种情况**
* 某线程调用Runtime类或System类的exit方法, 或Runtime类的halt方法,并且Java安全管理器也允许这次exit或halt操作。
* 程序正常执行结束
* 程序在执行过程中遇到了异常或错误而异常终止
* 由于操作系统出现错误而导致Java虚拟机进程终止
**简述 HotSpot 虚拟机**
* SUN的JDK版本从1.3.1开始运用HotSpot虚拟机, 2006年底开源,主要使用C++实现, JNI接口部·分用C实现, 用来**替换旧的解释型虚拟机 classic。**
* HotSpot是较新的Java虚拟机, 使用JIT(Just in Time)编译器,可以大大提高Java运行的性能。
* Java原先是把源代码编译为字节码在虚拟机执行,这样执行速度较慢。而HotSpot将常用的部分代码**编译为本地(原生, native)代码**,这样显着**提高了性能**。
* HotSpot JVM参数可以分为规则参数(standard options)和非规则参数(non-standard options),规则参数相对稳定,在JDK未来的版本里不会有太大的改动。非规则参数则有因升级JDK而改动的可能。
**JVM 的组成? 虚拟机的体系结构?**
1. 类加载器
2. 运行时数据区
3. 执行引擎
![](https://img.kancloud.cn/88/2e/882eb2e4b529aa785962f9e2888253f9_992x849.png)
这个架构可以分成三层看:
* 最上层:javac编译器将编译好的字节码class文件,通过java 类装载器执行机制,把对象或class文件存放在 jvm划分内存区域。
* 中间层:称为Runtime Data Area,主要是在Java代码运行时用于存放数据的,从左至右为方法区(永久代、元数据区)、堆(共享,GC回收对象区域)、栈、程序计数器、寄存器、本地方法栈(私有)。
* 最下层:解释器、JIT(just in time)编译器和 GC(Garbage Collection,垃圾回收器)
**什么是字节码的指令**
Java虚拟机的指令由一个字节长度的、代表着某种特定操作含义的操作码(opcode)以及跟随其后的零至多个代表此操作所需参数的操作数(operand)所构成。虚拟机中许多指令并不包含操作数,只有一个操作码。
**int i = 1; i = i++; i = ?**
**字节码在赋值过程会在 操作数栈 存一份 i=1, 而自增只是在局部变量表自增, 不会影响操作数栈的数据, 后面从操作数栈读取 i 覆盖了局部变量表的数据**
变形 int i = 2; i \*= i++; // 4 和上面原因一样
int i =10;
i = i + (i++) + (++i); // 32
// 第一个括号先读取出 10 , 然后自增了1, 就是 10 +10 但是这时候 i = 11了, 第二个括号在计算的时候是 11 进行自增成 12
10 + 10 + 12
**包装类的缓存**
Integer -128 到 127 之内(包含这俩) 都是用的同一个对象, 不在这个区间就是 new 了个新对象 125 == 125, 255 != 255 valueOf 方法里判断的
Boolean 有俩常量 true 和 false valueOf 方法里判断的
![](https://img.kancloud.cn/19/c7/19c798ceeb166f39e01a9577c3916ceb_688x343.png)
**字符串**
// string声明的字面量数据都放在字符串常量池中
// jdk 6中宇符串常量池存放在方法区(即永久代中)
// jdk 7及以后字符串常量池存放在堆空间
```
String str = new String("hello") + new String("world");
String str1 = "helloworld";
System.out.println(str == str1);
// false, str 实际在字节码中 是使用 StringBuilder 拼接的, 最后通过 StringBuilder
的 toString() 方法返回了一个 new String()
```
```
String str = new String("hello") + new String("world");
str.intern(); // 返回
String str1 = "helloworld";
System.out.println(str == str1);
// 1.6 是false, 1.7 是ture, intern 方法之后会返回常量池中这个值(没有会创建)
// 1.6 时 常量池在方法区和 intern 返回的不在一起(堆空间), 所以是俩变量
// 1.7 时 常量池也在堆空间, 这时候如果先 intern 就会把堆空间的引用地址
// 赋值给常量池, 这时候就用到同一个了. 如果后 intern 就直接从常量池中取值返回
System.out.println(str.intern() == str1); // true
```
// new StringBuilder("hellonihao").toString() 俩字符串,
// 一个 "hellonihao" 常量, 一个 new String 的 "hellonihao"
```
// 先 有常量, 后 intern() 则这个 toString() 后的值和 intern 的不相等
// new StringBuilder("hellonihao").toString() 俩字符串,
// 一个 "hellonihao" 常量, 一个 new String 的 "hellonihao"
String str2 = new StringBuilder("hellonihao").toString();
// false
System.out.println(str2 == str2.intern());
// jdk 中 本身已经有了 "Java(TM) SE Runtime Environment" 常量
// 组成 新字符串时, 原来的词组组合在一起的字符串出现过常量, 不是首次,
// StringBuilder.toString() 会重新生成一个, 不是把常量的引用拿过来用
String str2 =
new StringBuilder("Java(TM) SE ")
.append("Runtime Environment").toString();
// false
System.out.println(str2.intern() == str2);
String ss = "Java(TM) SE Runtime Environment";
// true
System.out.println(str2.intern() == ss);
```
**输出的结果是**
![](https://img.kancloud.cn/a2/58/a258d42a3037760e17cb7293def4793b_949x549.png)
Father f = new Son();
System.out.println(f.x);
执行过程是
1\. 子类构造器会**先调用父类构造器**, 在这里, 父类构造器里的this 指向的是 子类, **调用的也就是子类 print 方法**, 因为子类已经**重写了print**, 直接就执行子类的print方法, 但是这时候子类的 **x 还没有赋值 = 30,**所以输出 Son.x = 0。
2\. 执行完父类构造器再执行子类构造器,这时候**再调用子类的print x 已经是30了**, 所以输出 Son.x = 30。
3\. **f.x 是调用的 父类 x 变量**, 所以输出 20,父类的 x 在父类构造器中修改为 20了,父类 = new 子类 多态时, 父类是调用不了子类的变量的, 如果子类还定义了个 a 变量, 这时候是没法 f.a 的
**字节码**
**字节码(.class) 文件结构**
* 魔数 (用来标识文件类型的)
* class文件版本 (jdk的版本信息)
* 常量池计数器 和 常量池表数据
* 访问标识(或标志) (public final 等等信息 )
* 类索引、父类索引、接口索引集合 (继承那个类, 实现哪些接口)
* 字段表集合
* 方法表集合
* 属性表集合
![](https://img.kancloud.cn/d9/bb/d9bbcf1adcc38fff62c60a81ef45997e_1500x641.png)
**字节码指令分类**
* 加载与存储指令
* 算术指令
* 类型转换指令
* 对象的创建与访问指令
* 方法调用与返回指令
* 操作数栈管理指令
* 控制转移指令
* 异常处理指令
* 同步控制指令
**方法指令调用**
![](https://img.kancloud.cn/22/c5/22c581dcca3ff3f75b5ee9d2ba5ba5ee_673x498.png)
**基本类型为什么不存到堆中而是存到栈中**
栈空间相对小, 运算速度更快, 基本类型占用空间小更适合放到栈中
- 学习地址
- MySQL
- 查询优化
- SQL优化
- 关于or、in、not in、!=等走不走索引的说明
- 千万级数据查询优化
- MySQL 深度分页问题
- 嵌套循环 Block Nested Loop 导致索引查询慢
- MySQL增加日志统计表优化各种日志表的统计功能
- MySQL单机读写QPS(性能)优化
- sqlMode 置 select 的值可以比 group 里的多
- drop、delete、truncate的区别
- 尚硅谷MySQL数据库高级学习笔记
- MySQL架构
- 事务部分
- MySQL知识点
- mysql索引
- Linux docker安装 mysql 8.0.25
- docker 安装mysql 5.7
- mysql Field ‘xxx’ doesn’t have a default value
- mysql多实例
- docker中的sql文件导入
- mysql进阶知识
- mysql字符集
- 连接的原理
- redo日志
- InnoDB存储引擎
- InnoDB的数据存储结构
- B+树索引
- 文件系统-表空间
- Buffer Pool
- 亿级数据导入到es
- MySQL数据复制
- MySQL缺少主键的表数据
- mysql update 其中更新的字段根据另一个更新字段作为条件去更新
- MySQL指定字段值排序(将指定值排在前面)
- 设置MySQL连接数、时区
- Navicat15右键删除数据刷新就又恢复了
- MySQL替换字段部分内容
- Java和MySQL统计本周本月本季和年
- 分页时order by 排序数据重复,丢失
- mysql同一张表根据某个字段删除重复数据
- mysqldump定时全量热备
- 专题总结
- 事务
- MySQL事务
- spring事务
- spring事务本类调用
- spring事务传播行为
- spring事务失效问题
- 锁和Transactional注解一块使用的问题
- 数据安全
- 敏感数据
- SQL注入
- 数据源
- XSS
- 接口设计
- 缓存设计
- 限流
- 自定义注解实现根据用户做QPS限流
- 架构
- 高可用
- Java
- Unsatisfied dependency expressed through field ‘baseMapper‘
- mybatisplus多数据源
- 单个字母前缀的java变量
- spring
- spring循环依赖解决
- 事务@Transactional
- yml 文件配置信息绑定到java工具类的静态变量上
- @Configuration @Component 区别
- springboot启动yml文件报错
- spring方法重试注解Retryable
- spring读取yml集合数据
- spring自定义注解
- 获取resource下的图片资源
- 手机号和电话号的正则验证
- 获取字符串中的数字
- mybatis
- mybatis多参数添加数据并返回主键
- 统一异常处理
- 分组校验
- Java读取Python json.dumps 函数保存的redis数据
- springboot整合springCache
- 若依mybatis值为null的字段没有返回
- 若依
- 接口白名单
- @JsonFormat时区问题
- RequestParam.value() was empty on parameter 0
- jdk8和hutool请求第三方的https报错
- springMVC
- springMVC与vue使用post传数组
- elementUI 时间组件报错问题
- vue具名插槽slot
- springboot配置maven的profiles(配置微服务多环境切换打包)
- resources 配置文件读取顺序
- Windows的cmd部署jar注意事项
- Java基础
- JUC(锁-并发-线程池)
- CAS
- Java 锁简介
- synchronized和Logk有什么区别?用新的ock有什么好处
- synchronized锁介绍
- CompletableFuture
- 多线程
- 线程池
- 集合类
- map见过的小问题
- 退出双层循环
- StringBuilder和StringBuffer核心区别
- 日志打印
- 打印log日志
- log日志文件生成配置
- 日期时间
- 时间戳转为时间
- 并发工具
- 连接池
- http调用
- 内网访问天地图
- 判等问题
- 数值计算
- null问题
- 异常处理
- 文件IO
- 序列化
- 内存溢出OOM
- 子线程的错误, 全局异常处理捕获不到
- vue同一个项目访问多个不同ip地址接口
- Autowired注解导入为null
- shiro
- UnavailableSecurityManagerException错误
- Windows服务器80端口被占用
- java图片增加水印
- springcloud
- Feign方法配置错误导致jar包启动失败
- feign调用超时
- 定时任务quartz
- JavaPOI导出Excel
- 合并行和列
- 设置样式
- 设置背景色
- docker
- Linux 安装
- docker命令
- docker网络
- docker数据卷
- dockerfile
- docker安装ping命令
- docker-compose
- docker-compose文件内容介绍
- Linux关闭docker开机启动
- jar打包为镜像
- 迁移docker容器存储位置
- Nginx
- Linux在线安装Nginx
- nginx.conf 核心配置文件
- vue 和 nginx 刷新页面会报404
- nginx 转发给三个集群的tomcat
- ServerName匹配规则
- Nginx负载均衡策略
- location 匹配规则
- Nginx 搭建前端调用后台接口的集群
- alias与root
- nginx 拦截 post 请求, 带参数转发到前端页面
- 防盗链配置
- Nginx的缓存
- 通用Nginx配置
- nginx配置文件服务器
- 后台jar包得不到正确ip,nginx代理时要处理
- 升级使用websocket协议
- 设置IP黑/白名单
- Redis
- 缓存数据一致性
- 内存淘汰策略
- Redis数据类型
- gmt6
- Linux安装GMT6
- GMT6配置中文
- GMT文件修改Windows版本到Linux版本
- 注意GMT不同字体导致符号不同的问题
- GMT绘制南海诸岛小图
- GMT生成中文图例
- elasticsearch
- 安装配置
- Linux安装配置elasticsearch7.6.2
- Linux 安装 kibana 7.6.2
- 安装7.6.2中文分词器
- docker 安装elasticsearch7.6.2
- 安装Logback7.6.2
- springboot使用
- 0. elasticsearch账号密码模式访问
- 1. 配置连接
- 2. 索引
- 3. 批量保存更新
- Result window is too large 10000
- elasticsearch 分词的字段做排序 fielddata, 设置fielddata=true 无效果
- elasticsearch 完全匹配查询(精确查询)
- 模糊搜索
- 日期区间查询
- 6.x基础知识
- 自定义词库
- elasticsearch集群
- 搜索推荐Suggester
- 查询es保存的数组
- 亿级mysql数据导入到es
- es 报错 ORBIDDEN/12/index read-only
- es核心概念
- es的分布式架构原理
- 优化大数据量时的ES查询性能
- canal
- 1. mysql的Binlog
- 2. Canal 的工作原理
- 3. canal同步es
- JVM
- 1 类的字节码
- 2. 类的加载
- JVM知识点
- Maven
- 依赖冲突
- xxl-job
- docker 安装配置 xxl-job
- idea
- springboot启动报错命令过长
- services统一启动微服务各模块
- 云服务器安装宝塔面板
- 突然出现启动或者运行特别慢
- 有导入依赖但是显示红色同时点击进去也有依赖
- Linux
- sh文件执行报错: command not found
- 使用vagrant安装虚拟机
- Linux 开启端口
- 开放端口
- 复制文件夹及其文件到另一个文件夹
- 两个服务器之间映射端口
- TCP协议
- 分层模型
- TCP概述
- 支撑 TCP 协议的基石 —— 首部字段
- 数据包大小对网络的影响 —— MTU 与 MSS 的奥秘
- 端口号
- 三次握手
- TCP 自连接
- 四次挥手
- TCP 头部时间戳
- 分布式
- 分布式脑裂问题
- 分布式事务
- 基础知识
- 实现分布式事务的方案
- 阿里分布式事务中间件seata
- 幂等性问题
- 其他工具
- webstorm git提交代码后project目录树不显示
- 消息队列
- 如何保证消费的顺序
- 数据结构
- 漫画算法:小灰的算法之旅