初级Java开发工程师!绝密文档,面试手册全面突击!!!秋招已经到来
這里我要明說一下,不是Java初級和學習Java的千萬不要亂看,否則~~~~
你會懷疑人生,因為會浪費你時間啊!!!
本次考點是Java初級開發工程師面試必備的一些東西!!!
1、數據類型
基本類型
byte/8、short/16、int/32、long/64、boolean/ 、char/16、float/32、double/64boolean只有兩個值,true、false,可以使用1bit來存儲,但是具體大小沒有明確規定,JVM會在編譯時期將boolean類型轉為int,使用1來表示true,0表示false。JVM支持boolean數組,但是是通過讀寫byte數組來實現的。
包裝類型
基本類型都有對應的包裝類型,基本類型與其對應的包裝類型之間的賦值使用自動裝箱與拆箱完成。
Integer x=2 //裝箱,調用了Integer.valueOf(2) int y=x //拆箱 調用了 X.intValue()緩存池
new Integer(123)與Integer.valueOf(123)的區別在于:new Integer(123)每次都會新建一個對象 Integer.valueOf(123)會使用緩存池中的對象,多次調用會取得同一對象的引用。 Integer x = new Integer(123); Integer y = new Integer(123); System.out.println(x == y); // false Integer z = Integer.valueOf(123); Integer k = Integer.valueOf(123); System.out.println(z == k); // truevalueOf()方法的實現比較簡單,就是先判斷值是否在緩存池中,如果在的話就直接返回緩存池的內容。
2、String
概覽
String被聲明為final,因此它不可被繼承。(Integer等包裝類也不能被繼承)
在java8中,String 內部使用char數組存儲數據。
public final class Stringimplements java.io.Serializable, Comparable<String>, CharSequence {/** The value is used for character storage. */private final char value[]; }在java9之后,String類的實現改用byte數組存儲字符串,同時使用coder來標識使用了那種編碼。
public final class Stringimplements java.io.Serializable, Comparable<String>, CharSequence {/** The value is used for character storage. */private final byte[] value;/** The identifier of the encoding used to encode the bytes in {@code value}. */private final byte coder; }value 數組被聲明為final,這意味著value數組初始化之后就不能再引用其它數組。并且 String 內部沒有改變 value 數組的方法,因此可以保證 String不可變。
不可變的好處
1、可以緩存hash值
因為String的hash值經常被使用,例如String用作HashMap的key。不可變的特性可以使得hash值也不可變,因此只需要進行一次計算。
2、String Pool的需要
字符串常量池,如果一個String對象已經被創建過了,那么會從String Pool中取得引用。只有String是不可變的,才可能使用String Pool。
3、安全性
String經常作為參數,String不可變性可以保證參數不可變。
4、線程安全
String不可變性天生具備線程安全,可以在多個線程中安全地使用。
String Pool
字符串常量池(String Pool)保存這所有字符串字面量,這些字面量在編譯時期就確定。不僅如此,還可以使用String的intern()方法在運行過程中將字符串添加到String Pool中。
- 當一個字符串調用intern()方法時,如果String Pool中已經存在一個字符串和該字符串值相等(使用equals方法進行確定),那么就會返回String Pool中字符串的引用;否則,就會在String Pool中添加一個新的字符串,并返回這個新字符串的引用。
下面實例:s1和s2采用new String()的方式新建了兩個不同字符串,而s3和s4是通過s1.intern()和s2.intern()方法取得同一個字符串引用。intern()首先把“aaa”放到String Pool中,然后返回這個字符串的引用,因此s3和s4引用的是同一字符串。
String s1 = new String("aaa"); String s2 = new String("aaa"); System.out.println(s1 == s2); // false String s3 = s1.intern(); String s4 = s2.intern();//加入Java開發交流君樣:756584822一起吹水聊天 System.out.println(s3 == s4); // true如果采用"bbb"這種字面量的形式創建字符串,會自動地將字符串放入String Pool中。
String s5 = "bbb"; String s6 = "bbb"; System.out.println(s5 == s6); // true new String("abc")問題,使用這種方式一共會常見兩個字符串對象(前提是String Pool中還沒有"abc"字符串對象)
abc屬于字符串字面量,因此編譯時期會在String Pool中創建一個字符串對象,指向這個"abc"字符串字面量
而使用new的方式會在堆中創建一個字符串對象。
3、運算
參數傳遞
java的參數是以值傳遞的形式傳入方法中,而不是引用傳遞。
在給方法傳入參數時候,如果傳入對象,對象名其實代表地址,即將對象的地址傳給該方法。在運行時候可以對對象進行改變。
在方法中改變對象的字段值會改變原對象該字段值,因為引用的是同一個對象。
float與double
java不能隱式執行向下轉型,因為這會使得精度降低
字面量屬于double類型,不能直接將1.1直接賦值給float變量,因為這是向下轉型。
float f=1.1 //這會編譯錯誤 1.1f字面量才是float類型 //加入Java開發交流君樣:756584822一起吹水聊天 float f=1.1f 隱士類型轉換因為字面量1是int類型,它比short類型精度要高,因此不能隱式地將int類型向下轉型為short類型
4、關鍵字
final
1、數據
聲明數據為常量,可以是編譯時常量,也可以是在運行時被初始化后不能被改變的常量。
對于基本類型,final使數據不變
對于引用類型,final使引用不變,也就不能引用其他對象,但是被引用的對象本身是可以修改的。
final int x = 1; // x = 2; //不能賦值給被final修飾的變量 final A y = new A(); y.a = 1;2、方法
聲明方法不能被子類重寫。
private方法隱式地被指定為final,如果在子類中定義的方法和基類中的一個private方法簽名相同,此時子類的方法不是重寫基類方法,而是在子類中定義了一個新的方法。
3、類
聲明類不允許被繼承。
static
1、靜態變量
靜態變量:又被稱為類變量,也就是說這個變量屬于類的,類所有的實例都共享靜態變量,可以直接通過類名來訪問它。靜態變量在內存中只存在一份
實例變量:沒創建一個實例就會產生一個實例變量,它與實例同生共死。
public class A {private int x; // 實例變量private static int y; // 靜態變量public static void main(String[] args) {// int x = A.x; // Non-static field 'x' cannot be referenced from a static contextA a = new A();int x = a.x;int y = A.y;} }//加入Java開發交流君樣:756584822一起吹水聊天2、靜態方法
- 靜態方法在類加載的時候就存在了,它不依賴于任何實例。所有靜態方法必須有實現,也就是說它不能是抽象方法。
- 靜態方法只能訪問所屬類的靜態字段和靜態方法,方法中不能有this和super關鍵字,因此這兩個關鍵字與具體對象關聯。
3、靜態語句塊
靜態語句塊在類初始化時運行一次
public class A {static {System.out.println("123");}public static void main(String[] args) {A a1 = new A();A a2 = new A();} }123
4、靜態內部類
非靜態內部類依賴于外部類的實例,也就是說需要先創建外部實例,才能用這個實例去創建非靜態內部類。而靜態內部類不需要。
5、初始化順序
靜態變量和靜態語句塊優先于實例變量和普通語句塊,靜態變量和靜態語句塊的初始化順序取決于它們在代碼中的順序。
public static String staticField = "靜態變量";static {System.out.println("靜態語句塊"); }public String field = "實例變量";{//加入Java開發交流君樣:756584822一起吹水聊天System.out.println("普通語句塊"); }最后才是構造函數的初始化
public InitialOrderTest() {System.out.println("構造函數"); }存在繼承的情況下,初始化順序為:
父類(靜態變量、靜態語句塊) 子類(靜態變量、靜態語句塊) 父類(實例變量、普通語句塊) 父類(構造函數) 子類(實例變量、普通語句塊) 子類(構造函數)5、繼承
訪問權限
Java中有三個訪問權限修飾符:private、protected以及public,如果不加訪問修飾符,表示包級可見。
可以對類或類中的成員(字段和方法)加上訪問修飾符。
- 類可見表示其它類可以用這個類創建實例對象
- 成員可見表示其它類可以用這個類的實例對象訪問到改成員;
- protected用于修飾成員,表示在繼承體系中成員對于子類可見,但是這個訪問修飾符對于類沒有意義。
如果子類的方法重寫了父類的方法,那么子類中該方法的訪問級別不允許低于父類的訪問級別。這是為了確保可以使用父類實例的地方都可以使用子類實例去代替,也就是確保滿足里式替換原則。
字段決不能是共有的,因為這么做的話就市區了對這個字段修改行為的控制,客戶端可以對其隨意修改。我們可以使用公有的getter和setter方法來替換公有字段,這樣的話可以控制對字段的修改行為。
抽象類與接口
1、抽象類
抽象類和抽象方法都使用abstract關鍵字進行聲明。如果一個類中包含抽象方法,那么這個類必須聲明為抽象類。
抽象類和普通類最大的區別是,抽象類不能被實例化,只能被繼承。
public abstract class AbstractClassExample {protected int x;private int y;public abstract void func1();public void func2() {System.out.println("func2");} } public class AbstractExtendClassExample extends AbstractClassExample {@Overridepublic void func1() {System.out.println("func1");} }//加入Java開發交流君樣:756584822一起吹水聊天 // AbstractClassExample ac1 = new AbstractClassExample(); // 'AbstractClassExample' is abstract; cannot be instantiated AbstractClassExample ac2 = new AbstractExtendClassExample(); ac2.func1();2、接口
接口是抽象類的延伸,在java8之前,他可以看成是一個完全抽象的類,也就是說它不能有任何的方法實現。
從java8開始,接口也可以擁有默認的方法實現,這是因為不支持默認方法的接口維護成本太高了。 在 Java 8 之前,如果一個接口想要添加新的方法,那么要修改所有實現了該接口的類,讓它們都實現新增的方法。
接口的成員(字段 + 方法)默認都是public 的,并且不允許定義為 private 或者 protected。從 Java 9 開始,允許將方法定義為 private,這樣就能定義某些復用的代碼又不會把方法暴露出去。
接口的字段默認都是 static和final的。
重寫與重載
1、重寫
存在于繼承體系中,指子類實現了一個與父類在方法聲明上完全相同的一個方法。
為了滿足里式替換原則,重寫有一下三個限制:
-
子類方法的訪問權限必須大于等于父類方法
-
子類方法的返回類型必須是父類方法返回類型或為其子類型
-
子類方法拋出的異常類型必須是父類拋出異常類型或為其子類型
2、重載
存在于同一個類中,指一個方法與已經存在的方法名稱上相同,但是參數類型、個數、順序至少有一個不同。
應該注意的是,返回值不同,其它都相同不算是重載。
反射
每一個類都有一個Class對象,包含了與類有關的信息。當編譯一個新類時,會產生一個同名 的.class文件,該文件內容保存著Class對象。
類加載相當于Class對象的加載,類在第一次使用時才動態加載到JVM中。也可以使用Class.forName("com.mysql.jdbc.Driver")這種方式來控制類的加載,該方法會返回一個Class對象。
反射可以提供運行時的類信息,并且這個類可以在運行時才加載進來,甚至在編譯時期該類的.class不存在也可以加載進來。
Class和java.lang.reflect一起對反射提供了支持,java.lang.reflect類庫主要包含了以下三個類:
-
Field:可以使用get()和set()方法讀取和修改Field對象關聯的字段
-
Method:可以使用invoke()方法調用與Method對象關聯的方法
-
Constructor:可以用Constructor和newInstance()創建新的對象
反射的優點:
- 可擴展性:應用程序可以利用全限定類名創建可擴展對象的實例,來使用來自外部的用戶自定義類。
- 類瀏覽器和可視化開發環境:一個類瀏覽器需要可以枚舉類的成員。可視化開發環境(如IDE)可以從反射中可用的類型信息中收益,幫助程序員編寫正確的代碼。
- 調試器和測試工具:調試器需要能夠檢查一個類里的私有成員。測試工具可以利用反射來自動地調用類里定義的可被發現的API定義,以確保一組測試中有較高的代碼覆蓋率。
反射的缺點:
盡管反射很強大,但是不能濫用。如果一個功能可以不用反射完成,那么最好不用。
- 性能開銷:反射設計了動態類型的解析,所以JVM無法對這些代碼進行優化。因此,反射操作的效率要比那些非反射操作低得多。我們應該避免在經常被執行的代碼或對性能要求很高的程序中使用反射。
- 安全限制:使用反射技術要求程序必須在一個沒有安全限制的環境中運行。如果一個程序必須在有安全限制的環境中運行,如Applet,那么這就是一個問題了。
- 內部暴露:由于反射允許代碼執行一些在正常情況下不被允許的操作(比如訪問私有的屬性和方法),所以使用反射可能會導致意料之外的副作用
最后,祝大家早日學有所成,拿到滿意offer
總結
以上是生活随笔為你收集整理的初级Java开发工程师!绝密文档,面试手册全面突击!!!秋招已经到来的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 求职华为,被问观察者模式,从没有这种体验
- 下一篇: 2020延迟退休年龄时间表一览