**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. 執行引擎

這個架構可以分成三層看:
* 最上層: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 方法里判斷的

**字符串**
// 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);
```
**輸出的結果是**

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 等等信息 )
* 類索引、父類索引、接口索引集合 (繼承那個類, 實現哪些接口)
* 字段表集合
* 方法表集合
* 屬性表集合

**字節碼指令分類**
* 加載與存儲指令
* 算術指令
* 類型轉換指令
* 對象的創建與訪問指令
* 方法調用與返回指令
* 操作數棧管理指令
* 控制轉移指令
* 異常處理指令
* 同步控制指令
**方法指令調用**

**基本類型為什么不存到堆中而是存到棧中**
棧空間相對小, 運算速度更快, 基本類型占用空間小更適合放到棧中
- 學習地址
- 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
- Double轉String出現E的問題
- springboot接收前端表單提交多字段和上傳文件
- 子線程的錯誤, 全局異常處理捕獲不到
- vue同一個項目訪問多個不同ip地址接口
- Autowired注解導入為null
- shiro
- UnavailableSecurityManagerException錯誤
- Windows服務器80端口被占用
- java圖片增加水印
- springcloud
- Feign方法配置錯誤導致jar包啟動失敗
- feign調用超時
- Springcloud從Nacos的yml文件讀取出錯
- 定時任務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黑/白名單
- vue項目get請求Nginx返回html頁面post返回405錯誤
- Nginx限制所有接口流量
- 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目錄樹不顯示
- 消息隊列
- 如何保證消費的順序
- 數據結構
- 漫畫算法:小灰的算法之旅
- oracle