JAVA開發面試題&基礎篇&第十部分(基礎篇結尾)

zsk1996888發表於2020-11-15

基礎篇,最後一部分

1.抽象的(abstract)方法是否可同時是靜態的(static),是否可同時是本地方法(native),是否可同時被synchronized修飾?

答:都不能。抽象方法需要子類重寫,而靜態的方法是無法被重寫的,因此二者是矛盾的。本地方法是由原生程式碼(如C程式碼)實現的方法,而抽象方法是沒有實現的,也是矛盾的。synchronized和方法的實現細節有關,抽象方法不涉及實現細節,因此也是相互矛盾的。

2.靜態變數和例項變數的區別?

答:靜態變數是被static修飾符修飾的變數,也稱為類變數,它屬於類,不屬於類的任何一個物件,一個類不管建立多少個物件,靜態變數在記憶體中有且僅有一個拷貝;例項變數必須依存於某一例項,需要先建立物件然後通過物件才能訪問到它,靜態變數可以實現讓多個物件共享記憶體。兩者的相同點:都有預設值而且在類的任何地方都可以呼叫。在Java開發中,上下文類和工具類中通常會有大量的靜態成員。

3.是否可以從一個靜態(static)方法內部發出對非靜態(non-static)方法的呼叫?

答:不可以,靜態方法只能訪問靜態成員,因為非靜態方法的呼叫要先建立物件,因此在呼叫靜態方法時可能物件並沒有被初始化。【第3次出現,讀者記住了麼?】

4.如何實現物件克隆?

答:有兩種方式:
1.實現Cloneable介面並重寫Object類中的clone()方法;
2.實現Serializable介面,通過物件的序列化和反序列化實現克隆,可以實現真正的深度克隆。

package com.bjsxt;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
 
public class MyUtil {
      private MyUtil() {
        throw new AssertionError();
    }
      public static <T> T clone(T obj) throws Exception {
        ByteArrayOutputStream bout = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bout);
        oos.writeObject(obj);
        ByteArrayInputStream bin = new ByteArrayInputStream(bout.
toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bin);
        return (T) ois.readObject();
        // 說明:呼叫ByteArrayInputStream或ByteArrayOutputStream物件的close方法沒有任何意義
        // 這兩個基於記憶體的流只要垃圾回收器清理物件就能夠釋放資源
}
}

注意:基於序列化和反序列化實現的克隆不僅僅是深度克隆,更重要的是通過泛型限定,可以檢查出要克隆的物件是否支援序列化,這項檢查是編譯器完成的,不是在執行時丟擲異常,這種是方案明顯優於使用Object類的clone方法克隆物件。

5.介面是否可繼承(extends)介面? 抽象類是否可實現(implements)介面? 抽象類是否可繼承具體類(concrete class)?

答:介面可以繼承介面。抽象類可以實現(implements)介面,抽象類可以繼承具體類。抽象類中可以有靜態的main方法。
備註:只要明白了介面和抽象類的本質和作用,這些問題都很好回答,你想想,如果你是java語言的設計者,你是否會提供這樣的支援,如果不提供的話,有什麼理由嗎?如果你沒有道理不提供,那答案就是肯定的了。
只有記住抽象類與普通類的唯一區別就是不能建立例項物件和允許有abstract方法。

6.一個“.java”原始檔中是否可以包含多個類(不是內部類)?有什麼限制?

答:可以,但一個原始檔中最多隻能有一個公開類(public class)而且檔名必須和公開類的類名完全保持一致。【在IDEA中可以實現自動修復此異常的命名】關注公眾號:勝科課堂 獲取IDEA安裝包。

7.Anonymous Inner Class(匿名內部類)是否可以繼承其它類?是否可以實現介面?

答:可以繼承其他類或實現其他介面,在Swing程式設計中常用此方式來實現事件監聽和回撥。 但是有一點需要注意,它只能繼承一個類或一個介面

8.內部類可以引用它的包含類(外部類)的成員嗎?有沒有什麼限制?

答:一個內部類物件可以訪問建立它的外部類物件的成員,包括私有成員。如果要訪問外部類的區域性變數,此時區域性變數必須使用final修飾,否則無法訪問。

9.Java 中的final關鍵字有哪些用法?

(1) 修飾類:表示該類不能被繼承;
(2) 修飾方法:表示方法不能被重寫但是允許過載;
(3) 修飾變數:表示變數只能一次賦值以後值不能被修改(常量);
(4) 修飾物件:物件的引用地址不能變,但是物件的初始化值可以變。

10.指出下面程式的執行結果:

package com.bjsxt;
class A{
  static{
        System.out.print("1");
    }
  public A(){
        System.out.print("2");
    }
}
class B extends A{
  static{
        System.out.print("a");
    }
    public B(){
        System.out.print("b");
    }
}
 
public class Hello{
  public static void main(String[] args){
        A ab = new B();
        ab = new B();
    }
}

答:執行結果:1a2b2b。建立物件時構造器的呼叫順序是:先初始化靜態成員,然後呼叫父類構造器,再初始化非靜態成員,最後呼叫自身構造器。
考點:靜態程式碼塊優先順序 > 構造方法的優先順序如果再加一個普通程式碼塊,優先順序如下:靜態程式碼塊>普通程式碼塊>構造方法

11.說說資料型別之間的轉換:1 ) 如何將字串轉換為基本資料型別?2 ) 如何將基本資料型別轉換為字串?

答:1 ) 呼叫基本資料型別對應的包裝類中的方法parseXXX(String)或valueOf(String)即可返回相應基本型別;
2 ) 一種方法是將基本資料型別與空字串(””)連線(+)即可獲得其所對應的字串;另一種方法是呼叫String 類中的valueOf(…)方法返回相應字串

12.如何實現字串的反轉及替換?

答:方法很多,可以自己寫實現也可以使用String或StringBuffer / StringBuilder中的方法。有一道很常見的面試題是用遞迴實現字串反轉,程式碼如下所示:

package com.bjsxt;
public class A{
    public static String reverse(String originStr) {
 if(originStr == null || originStr.length() <= 1)
     return originStr;
       return reverse(originStr.substring(1)) + originStr.charAt(0);
     }
}

13.怎樣將GB2312編碼的字串轉換為ISO-8859-1編碼的字串?

答:getBytes( ,)方法程式碼如下所示:

String s1 = "你好";
String s2 = newString(s1.getBytes("GB2312"), "ISO-8859-1"); 

在String類的構造方法當中,存在一個字符集設定的方法,具體如下:

14.Java中的日期和時間:

1 ) 如何取得年月日、小時分鐘秒?
2 ) 如何取得從1970年1月1日0時0分0秒到現在的毫秒數?
3 ) 如何取得某月的最後一天?
4 ) 如何格式化日期?

答:操作方法如下所示:
1 ) 建立java.util.Calendar 例項,呼叫其get()方法傳入不同的引數即可獲得引數所對應的值
2 ) 以下方法均可獲得該毫秒數:
Calendar.getInstance().getTimeInMillis();
3)time.getActualMaximum(Calendar.DAY_OF_MONTH);
4 ) 利用java.text.DataFormat 的子類(如SimpleDateFormat類)中的format(Date)方法可將日期格式化。

15.列印昨天的當前時刻。

package com.bjsxt;
import java.util.Calendar;
public class YesterdayCurrent {
 public static void main(String[] args){
 Calendar cal = Calendar.getInstance();
 cal.add(Calendar.DATE, -1);
 System.out.println(cal.getTime());
 }
}

16.Java反射技術主要實現類有哪些,作用分別是什麼?

在JDK中,主要由以下類來實現Java反射機制,這些類都位於java.lang.reflect包中
1)Class類:代表一個類
2)Field 類:代表類的成員變數(屬性)
3)Method類:代表類的成員方法
4)Constructor 類:代表類的構造方法
5)Array類:提供了動態建立陣列,以及訪問陣列的元素的靜態方法

17.Class類的作用?生成Class物件的方法有哪些?

Class類是Java 反射機制的起源和入口,用於獲取與類相關的各種資訊,提供了獲取類資訊的相關方法。Class類繼承自Object類
Class類是所有類的共同的圖紙。每個類有自己的物件,好比圖紙和實物的關係;每個類也可看做是一個物件,有共同的圖紙Class,存放類的 結構資訊,能夠通過相應方法取出相應資訊:類的名字、屬性、方法、構造方法、父類和介面

方 法示 例
物件名.getClass()String str=“bdqn”;Class clazz = str.getClass();
物件名.getSuperClass()Student stu = new Student();Class c1 = stu.getClass();Class c2 = stu.getSuperClass();
Class.forName()Class clazz = Class.forName(“java.lang.Object”);Class.forName(“oracle.jdbc.driver.OracleDriver”);
類名.classClass c2 = Student.class; Class c2 = int.class
包裝類.TYPEClass c2 = Boolean.TYPE;

18.反射的使用場合和作用、及其優缺點

1)使用場合
在編譯時根本無法知道該物件或類可能屬於哪些類,程式只依靠執行時資訊來發現該物件和類的真實資訊。
2)主要作用
通過反射可以使程式程式碼訪問裝載到JVM 中的類的內部資訊,獲取已裝載類的屬性資訊,獲取已裝載類的方法,獲取已裝載類的構造方法資訊
3)反射的優點
反射提高了Java程式的靈活性和擴充套件性,降低耦合性,提高自適應能力。它允許程式建立和控制任何類的物件,無需提前硬編碼目標類;反射是其它一些常用語言,如C、C++、Fortran 或者Pascal等都不具備的
4) Java反射技術應用領域很廣,如軟體測試等;許多流行的開源框架例如Struts、Hibernate、Spring在實現過程中都採用了該技術
5)反射的缺點
效能問題:使用反射基本上是一種解釋操作,用於欄位和方法接入時要遠慢於直接程式碼。因此Java反射機制主要應用在對靈活性和擴充套件性要求很高的系統框架上,普通程式不建議使用。
使用反射會模糊程式內部邏輯:程式人員希望在原始碼中看到程式的邏輯,反射等繞過了原始碼的技術,因而會帶來維護問題。反射程式碼比相應的直接程式碼更復雜。

19.物件導向設計原則有哪些

物件導向設計原則是物件導向設計的基石,物件導向設計質量的依據和保障,設計模式是物件導向設計原則的經典應用
1)單一職責原則SRP
2)開閉原則OCP
3)里氏替代原則LSP
4)依賴注入原則DIP
5)介面分離原則ISP
6)迪米特原則LOD
7)組合/聚合複用原則CARP
8)開閉原則具有理想主義的色彩,它是物件導向設計的終極目標。其他設計原則都可以看作是開閉原則的實現手段或方法

相關文章