1. 程式人生 > 其它 >最新精選Java面試題及答案,Java基礎面試題答案精選(六)

最新精選Java面試題及答案,Java基礎面試題答案精選(六)


上圖是我整理的Java面試題合集,包攬了基本所有技術棧:完整版Java面試題合集附答案,高清PDF下載

1. Integer a= 127 與 Integer b = 127相等嗎

  • 對於物件引用型別:==比較的是物件的記憶體地址。
  • 對於基本資料型別:==比較的是值。

如果整型字面量的值在-128到127之間,那麼自動裝箱時不會new新的Integer物件,而是直接引用常量池中的Integer物件,超過範圍 a1==b1的結果是false

public static void main(String[] args) {
    Integer a = new Integer(3);
    Integer b = 3;  // 將3自動裝箱成Integer型別
  int c = 3;
    System.out.println(a == b); // false 兩個引用沒有引用同一物件
  System.out.println(a == c); // true a自動拆箱成int型別再和c比較
  System.out.println(b == c); // true


    Integer a1 = 128;
    Integer b1 = 128;
    System.out.println(a1 == b1); // false
    
    Integer a2 = 127;
    Integer b2 = 127;
    System.out.println(a2 == b2); // true
}


2. static的獨特之處

  • 1、被static修飾的變數或者方法是獨立於該類的任何物件,也就是說,這些變數和方法不屬於任何一個例項物件,而是被類的例項物件所共享

怎麼理解 “被類的例項物件所共享” 這句話呢?就是說,一個類的靜態成員,它是屬於大夥的【大夥指的是這個類的多個物件例項,我們都知道一個類可以建立多個例項!】,所有的類物件共享的,不像成員變數是自個的【自個指的是這個類的單個例項物件】…我覺得我已經講的很通俗了,你明白了咩?

  • 2、在該類被第一次載入的時候,就會去載入被static修飾的部分,而且只在類第一次使用時載入並進行初始化,注意這是第一次用就要初始化,後面根據需要是可以再次賦值的。

  • 3、static變數值在類載入的時候分配空間,以後建立類物件的時候不會重新分配。賦值的話,是可以任意賦值的!

  • 4、被static修飾的變數或者方法是優先於物件存在的,也就是說當一個類載入完畢之後,即便沒有建立物件,也可以去訪問。

3. Java 中 IO 流分為幾種?

  • 按照流的流向分,可以分為輸入流和輸出流;
  • 按照操作單元劃分,可以劃分為位元組流和字元流;
  • 按照流的角色劃分為節點流和處理流。

Java Io 流共涉及 40 多個類,這些類看上去很雜亂,但實際上很有規則,而且彼此之間存在非常緊密的聯絡, Java I0 流的 40 多個類都是從如下 4 個抽象類基類中派生出來的。

  • InputStream/Reader: 所有的輸入流的基類,前者是位元組輸入流,後者是字元輸入流。
  • OutputStream/Writer: 所有輸出流的基類,前者是位元組輸出流,後者是字元輸出流。

按操作方式分類結構圖:

4. final 在 Java 中有什麼作用?

final作為Java中的關鍵字可以用於三個地方。用於修飾類、類屬性和類方法。

特徵:凡是引用final關鍵字的地方皆不可修改!

(1)修飾類:表示該類不能被繼承;

(2)修飾方法:表示方法不能被重寫;

(3)修飾變數:表示變數只能一次賦值以後值不能被修改(常量)。

5. 什麼是內部類?

  • 在Java中,可以將一個類的定義放在另外一個類的定義內部,這就是內部類。內部類本身就是類的一個屬性,與其他屬性定義方式一致。

6. 在使用 HashMap 的時候,用 String 做 key 有什麼好處?

  • HashMap 內部實現是通過 key 的 hashcode 來確定 value 的儲存位置,因為字串是不可變的,所以當建立字串時,它的 hashcode 被快取下來,不需要再次計算,所以相比於其他物件更快。

7. 內部類相關,看程式說出執行結果

public class Outer {
    private int age = 12;


    class Inner {
        private int age = 13;
        public void print() {
            int age = 14;
            System.out.println("區域性變數:" + age);
            System.out.println("內部類變數:" + this.age);
            System.out.println("外部類變數:" + Outer.this.age);
        }
    }
    
    public static void main(String[] args) {
        Outer.Inner in = new Outer().new Inner();
        in.print();
    }


}


執行結果:

區域性變數:14
內部類變數:13
外部類變數:12


8. 泛型常用特點

泛型是Java SE 1.5之後的特性, 《Java 核心技術》中對泛型的定義是:

“泛型” 意味著編寫的程式碼可以被不同型別的物件所重用。

“泛型”,顧名思義,“泛指的型別”。我們提供了泛指的概念,但具體執行的時候卻可以有具體的規則來約束,比如我們用的非常多的ArrayList就是個泛型類,ArrayList作為集合可以存放各種元素,如Integer, String,自定義的各種型別等,但在我們使用的時候通過具體的規則來約束,如我們可以約束集合中只存放Integer型別的元素,如

List<Integer> iniData = new ArrayList<>()

9. super關鍵字的用法

super可以理解為是指向自己超(父)類物件的一個指標,而這個超類指的是離自己最近的一個父類。

super也有三種用法:

  • 1.普通的直接引用

與this類似,super相當於是指向當前物件的父類的引用,這樣就可以用super.xxx來引用父類的成員。

  • 2.子類中的成員變數或方法與父類中的成員變數或方法同名時,用super進行區分
      class Person{
          protected String name;


          public Person(String name) {
              this.name = name;
          }


      }


      class Student extends Person{
          private String name;


          public Student(String name, String name1) {
              super(name);
              this.name = name1;
          }


          public void getInfo(){
              System.out.println(this.name);      //Child
              System.out.println(super.name);     //Father
          }


      }


      public class Test {
          public static void main(String[] args) {
             Student s1 = new Student("Father","Child");
             s1.getInfo();


          }
      }


3.引用父類建構函式

  • super(引數):呼叫父類中的某一個建構函式(應該為建構函式中的第一條語句)。
  • this(引數):呼叫本類中另一種形式的建構函式(應該為建構函式中的第一條語句)。

10. instanceof 關鍵字的作用

instanceof 嚴格來說是Java中的一個雙目運算子,用來測試一個物件是否為一個類的例項,用法為:

boolean result = obj instanceof Class

其中 obj 為一個物件,Class 表示一個類或者一個介面,當 obj 為 Class 的物件,或者是其直接或間接子類,或者是其介面的實現類,結果result 都返回 true,否則返回false。

注意:編譯器會檢查 obj 是否能轉換成右邊的class型別,如果不能轉換則直接報錯,如果不能確定型別,則通過編譯,具體看執行時定。

int i = 0;
System.out.println(i instanceof Integer);//編譯不通過  i必須是引用型別,不能是基本型別
System.out.println(i instanceof Object);//編譯不通過
​```


```java
Integer integer = new Integer(1);
System.out.println(integer instanceof  Integer);//true
​```


```java
//false   ,在 JavaSE規範 中對 instanceof 運算子的規定就是:如果 obj 為 null,那麼將返回 false。
System.out.println(null instanceof Object);

11. short s1 = 1; s1 = s1 + 1;有錯嗎?short s1 = 1; s1 += 1;有錯嗎

  • 對於 short s1 = 1; s1 = s1 + 1;由於 1 是 int 型別,因此 s1+1 運算結果也是 int型,需要強制轉換型別才能賦值給 short 型。

  • 而 short s1 = 1; s1 += 1;可以正確編譯,因為 s1+= 1;相當於 s1 = (short(s1 + 1);其中有隱含的強制型別轉換。

12. 內部類的分類有哪些

內部類可以分為四種:**成員內部類、區域性內部類、匿名內部類和靜態內部類**。

13. this關鍵字的用法

  • this是自身的一個物件,代表物件本身,可以理解為:指向物件本身的一個指標。

  • this的用法在java中大體可以分為3種:

    • 1.普通的直接引用,this相當於是指向當前物件本身。

    • 2.形參與成員名字重名,用this來區分:

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    • 3.引用本類的建構函式
    class Person{
        private String name;
        private int age;
    
        public Person() {
        }
    
        public Person(String name) {
            this.name = name;
        }
        public Person(String name, int age) {
            this(name);
            this.age = age;
        }
    }
    

14. 什麼是多型機制?Java語言是如何實現多型的?

  • 所謂多型就是指程式中定義的引用變數所指向的具體型別和通過該引用變數發出的方法呼叫在程式設計時並不確定,而是在程式執行期間才確定,即一個引用變數倒底會指向哪個類的例項物件,該引用變數發出的方法呼叫到底是哪個類中實現的方法,必須在由程式執行期間才能決定。因為在程式執行時才確定具體的類,這樣,不用修改源程式程式碼,就可以讓引用變數繫結到各種不同的類實現上,從而導致該引用呼叫的具體方法隨之改變,即不修改程式程式碼就可以改變程式執行時所繫結的具體程式碼,讓程式可以選擇多個執行狀態,這就是多型性。

  • 多型分為編譯時多型和執行時多型。其中編輯時多型是靜態的,主要是指方法的過載,它是根據引數列表的不同來區分不同的函式,通過編輯之後會變成兩個不同的函式,在執行時談不上多型。而執行時多型是動態的,它是通過動態繫結來實現的,也就是我們所說的多型性。

多型的實現

  • Java實現多型有三個必要條件:繼承、重寫、向上轉型。

  • 繼承:在多型中必須存在有繼承關係的子類和父類。

  • 重寫:子類對父類中某些方法進行重新定義,在呼叫這些方法時就會呼叫子類的方法。

  • 向上轉型:在多型中需要將子類的引用賦給父類物件,只有這樣該引用才能夠具備技能呼叫父類的方法和子類的方法。

只有滿足了上述三個條件,我們才能夠在同一個繼承結構中使用統一的邏輯實現程式碼處理不同的物件,從而達到執行不同的行為。

對於Java而言,它多型的實現機制遵循一個原則:當超類物件引用變數引用子類物件時,被引用物件的型別而不是引用變數的型別決定了呼叫誰的成員方法,但是這個被呼叫的方法必須是在超類中定義過的,也就是說被子類覆蓋的方法。

15. 說出 5 條 IO 的最佳實踐(答案)

IO 對 Java 應用的效能非常重要。理想情況下,你不應該在你應用的關鍵路徑上

避免 IO 操作。下面是一些你應該遵循的 Java IO 最佳實踐:

1、 使用有緩衝區的 IO 類,而不要單獨讀取位元組或字元。

2、 使用 NIO 和 NIO2

3、 在 finally 塊中關閉流,或者使用 try-with-resource 語句。

4、 使用記憶體對映檔案獲取更快的 IO。