1,關於JDK,JRE,JVM
【為什么安裝包要分JDK和JRE?】
先來說說什么是JDK,JRE。
JDK:Java Development Kit Java開發工具包【開發Java程序用】
JRE:Java Runtiome Environment Java運行環境【運行Java程序用】
【注:下載的JDK包是包含了JDK和JRE的,JDK和JRE是邏輯上的區分,兩者在JDK下載的包中都有】
JDK與JRE的關系:以Java代碼運行為例,編寫好Java代碼之后,通過javac將java源文件編譯成class字節碼文件,然后通過java命令,運行字節碼文件。那么運行字節碼的環境就是JRE。(JRE的核心就是JVM)
了解完JDK和JRE是什么之后,再聊聊為什么開發者當時要把一個安裝包分成兩部分呢?
平常使用的軟件都是一鍵安裝的,但JDK需要安裝兩次。JDK的發明者不會這么無聊,故意給開發者增加麻煩。
【我想】:這應該跟生產環境的部署問題有關,關於生產環境部署JDK還是JRE一直飽受爭議,具體情況根據項目而定。
出於對性能的考慮,盡可能的使服務器輕,能少裝一個軟件就少裝一個,這樣生產環境部署JRE就OK了。【又省了資源】
除了這個方面之外,還有一種可能。JDK的開發也有可能是分團隊的,JDK和JRE可能是交由不同團隊開發,JDK和JRE的耦合也可能因此而減小,從而加快JDK的迭代版本。(畢竟現在JDK一年更新兩次)
【為什么Java語言是跨平台的?】
跨平台和Java 虛擬機有關。
JVM有兩個主要的功能:
- 適配不同的操作系統的指令集(兼容不同的操作系統)
- 翻譯字節碼文件為機器碼執行
(Oracle官網上下載JDK,不同操作系統的JDK是不一樣的,對應不同的虛擬機)
這個就跟JVM有關了,先來了解一下什么是JVM:
JVM:Java Virtual Machine Java虛擬機
JVM的主要作用就是將class字節碼文件翻譯成機器碼(01)供給計算機執行。
跨平台——Java程序可以在多種平台上運行。
平台指的是操作系統,目前主流的操作系統:Windows,Mac,Linux。
以日常軟件為例,同一個軟件的win版和mac版是分開的。但是功能卻是基本相同的。
JVM同樣如此,也有win版,mac版以及linux版。安裝在不同的平台上的JVM雖然有所差異,但都能完成同樣一件使命——將class文件翻譯成機器碼。
概括來說,JVM有兩個功能:其一是,其二是翻譯class字節碼文件。
【為什么要設置環境變量?】
在解決這個問題之前,先解決環境變量是干嘛的:
運行一個程序(命令),系統從當前目錄尋找,或者從環境變量中尋找。
換句話說,如果在java,javac的目錄下執行這個兩個命令,是沒有問題的。但是如果更換了目錄,系統在當前目錄找不到,就會去環境變量中尋找。所以設置環境變量的根本目的是在電腦的任何一個文件夾下都可以編譯運行Java程序。
2,關於包裝類和基本數據類型
包裝類型和基本數據類型的區別
- 聲明方式:包裝類型需要new聲明
- 存儲方式:基本數據類型存放在棧中,包裝類型存在堆中
- 初始值不同:基本類型的初始值如int為0,boolean為false,而包裝類型的初始值為null;
Integer 與 int 的區別
Integer 是引用類型,默認值是null。而int是是值類型默認值是0
3,關於String類
1,String,StringBuilder,StringBuffer的區別
-
可變性
String是不可變的,StringBuffer和StringBuilder是可變的
-
安全性
StringBuffer和String是線程安全的,,StringBuilder是線程不安全的
【解釋】
聚焦:可變性,安全性
-
String 底層使用final修飾的數組實現
-
線程安全問題
String 中的對象是不可變的,也就可以理解為常量,線程安全。
StringBuffer 對方法加了同步鎖或者對調用的方法加了同步鎖,所以是線程安全的。
StringBuilder 並沒有對方法進行加同步鎖,所以是非線程安全的。
對於三者使用的總結:
- 操作少量的數據: 適用String
- 單線程操作字符串緩沖區下操作大量數據: 適用StringBuilder
- 多線程操作字符串緩沖區下操作大量數據: 適用StringBuffer
2,String s = "Hello";s = s + "world!";這兩行代碼執行后,原始的String對象中的內容到底變了沒有?
沒有。
因為String被設計成不可變(immutable)類(final修飾),所以它的所有對象都是不可變對象。
在這段代碼中,s原先指向一個String對象,內容是 "Hello",然后對s進行了+操作
這時,s不指向原來那個對象了,而指向了另一個 String對象,內容為"Hello world!"
原來那個對象還存在於內存之中,只是s這個引用變量不再指向它了。
3,String str =“i”;和String str = new String("i");有區別嗎?
前者會被JVM分配到常量池中,常量池中沒有重復的元素。
String str1 =“i”;
String str2 =“i”;
str2不會重新創建一個常量,而是指向str1。
String str1 = new String("i");
String str2 = new String("i");
str1會在堆內存中創建對象
str2還是會再次創建一個新的對象
4,如何將字符串反轉?
使用StringBuilder或者StringBuffer的reverse()方法。
StringBuffer str1 = new StringBuffer("12345");
StringBuffer str2 = str1.reverse();
System.out.println(str2);
5,關於運算符
==和equals的區別
==:
- 基本數據類型:比較值是否相等
- 引用類型:比較內存地址是否相同
equals:
通常會被重寫,比較引用類型的內容是否相同
int x = 7;
int y = 7;
//比較基本數據類型的值
System.out.println(x==y);
String str1 = new String("123");
String str2 = new String("123");
//比較引用類型的內存地址
System.out.println(str1==str2);
//比較引用類型的內容是否相同
System.out.println(str1.equals(str2));
&和&&的區別(|和||同理)
&和&&表示邏輯與,兩邊同時為true時才為true。
&&具有短路功能,&&左邊為false時,右邊表達式不會執行。
6,關於Math類
Math.round(11.5)等於多少?Math.round(-11.5)等於多少?
Math類中提供了三個與取整有關的方法:
ceil(向上取整)、floor(向下取整)、round(+0.5后四舍五入)
Math.ceil(11.3)的結果為12
Math.ceil(-11.3)的結果是-11
Math.floor(11.6)的結果為11
Math.floor(-11.6)的結果是-12
Math.round(11.5)的結果為12
Math.round(-11.5)的結果為-11。