天天看點

java面試題筆試

今天給大家整理了一些筆試題,有時間的話我會盡可能的去整理更全面的問題,希望對大家有所幫助。

筆試

基礎題

1:談談final,finally,finallize的差別

final 用于聲明屬性,方法和類,分别表示屬性不可變,方法不可覆寫,類不可繼承。内部類要通路局部變量,局部變量必須定義成final類型。

finally是異常處理語句結構的一部分,表示總是執行。

finalize是Object類的一個方法,在垃圾收集器執行的時候會調用被回收對象的此方法,可以覆寫此方法提供垃圾收集時的其他資源回收,例如關閉檔案等。但是JVM不保證此方法總被調用

2:說說你知道的幾種設計模式,并寫出相關代碼或畫出類圖(至少兩種)。

這種問題肯定寫的越多越好,是以這就很考研我們平時掌握的知識了。

建議答案:單例模式,抽線工廠模式,代理模式,模闆方法模式,裝飾模式,擴充卡模式。以上幾種都是我們常用的。

單例模式(懶漢式):

該模式的特點是類加載時沒有生成單例,隻有當第一次調用 getlnstance 方法時才去建立這個單例

public class LazySingleton
{
    private static volatile LazySingleton instance=null;    //保證 instance 在所有線程中同步
    private LazySingleton(){}    //private 避免類在外部被執行個體化
    public static synchronized LazySingleton getInstance()
    {
        //getInstance 方法前加同步
        if(instance==null)
        {
            instance=new LazySingleton();
        }
        return instance;
    }
}
           

單例模式(餓漢式):

該模式的特點是類一旦加載就建立一個單例,保證在調用 getInstance 方法之前單例已經存在了。

public class HungrySingleton
{
    private static final HungrySingleton instance=new HungrySingleton();
    private HungrySingleton(){}
    public static HungrySingleton getInstance()
    {
        return instance;
    }
}
           

抽象工廠模式:

(1) 抽象工廠:提供了産品的生成方法。

interface AbstractFactory
{
    public Product1 newProduct1();
    public Product2 newProduct2();
}
           

(2) 具體工廠:實作了産品的生成方法。

class ConcreteFactory1 implements AbstractFactory
{
    public Product1 newProduct1()
    {
        System.out.println("具體工廠 1 生成-->具體産品 11...");
        return new ConcreteProduct11();
    }
    public Product2 newProduct2()
    {
        System.out.println("具體工廠 1 生成-->具體産品 21...");
        return new ConcreteProduct21();
    }
}
           

代理模式:

java面試題筆試
public class ProxyTest
{
    public static void main(String[] args)
    {
        Proxy proxy=new Proxy();
        proxy.Request();
    }
}
//抽象主題
interface Subject
{
    void Request();
}
//真實主題
class RealSubject implements Subject
{
    public void Request()
    {
        System.out.println("通路真實主題方法...");
    }
}
//代理
class Proxy implements Subject
{
    private RealSubject realSubject;
    public void Request()
    {
        if (realSubject==null)
        {
            realSubject=new RealSubject();
        }
        preRequest();
        realSubject.Request();
        postRequest();
    }
    public void preRequest()
    {
        System.out.println("通路真實主題之前的預處理。");
    }
    public void postRequest()
    {
        System.out.println("通路真實主題之後的後續處理。");
    }
}
           

3:談談接口與抽象類的差別。

1.抽象類可以有構造方法,接口中不能有構造方法。
2.抽象類中可以有普通成員變量,接口中沒有普通成員變量
3.抽象類中可以包含非抽象的普通方法,接口中的所有方法必須都是抽象的,不能有非抽象的普通方法。
4. 抽象類中的抽象方法的通路類型可以是public,protected和(預設類型,雖然
eclipse下不報錯,但應該也不行),但接口中的抽象方法隻能是public類型的,并且預設即為public abstract類型。
5. 抽象類中可以包含靜态方法,接口中不能包含靜态方法
6. 抽象類和接口中都可以包含靜态成員變量,抽象類中的靜态成員變量的通路類型可以任意,但接口中定義的變量隻能是publicstatic final類型,并且預設即為publicstatic final類型。
7. 一個類可以實作多個接口,但隻能繼承一個抽象類。
           

4:Overload和Override分别代表什麼?有什麼差別?

Overload是重載的意思,Override是覆寫的意思,也就是重寫。

重載Overload表示同一個類中可以有多個名稱相同的方法,但這些方法的參數清單各不相同(即參數個數或類型不同)。

重寫Override表示子類中的方法可以與父類中的某個方法的名稱和參
 數完全相同,通過子類建立的執行個體對象調用這個方法時,将調用子類中的定義方法,
 這相當于把父類中定義的那個完全相同的方法給覆寫了,這也是面向對象程式設計的多态性的一種表現。
 子類覆寫父類的方法時,隻能比父類抛出更少的異常,或者是抛出父類抛出的異常的子異常,
 因為子類可以解決父類的一些問題,不能比父類有更多的問題。
 子類方法的通路權限隻能比父類的更大,不能更小。如果父類的方法是private類型,
 那麼,子類則不存在覆寫的限制,相當于子類中增加了一個全新的方法。

至于Overloaded的方法是否可以改變傳回值的類型這個問題,要看你倒底想問什麼呢?
這個題目很模糊。如果幾個Overloaded的方法的參數清單不一樣,
它們的傳回者類型當然也可以不一樣。但我估計你想問的問題是:如果兩個方法的參數清單完全一樣,
是否可以讓它們的傳回值不同來實作重載Overload。
這是不行的,我們可以用反證法來說明這個問題,因為我們有時候調用
一個方法時也可以不定義傳回結果變量,即不要關心其傳回結果,
例如,我們調用map.remove(key)方法時,雖然remove方法有傳回值,
但是我們通常都不會定義接收傳回結果的變量,這時候假設該類中有兩個名稱和參數清單
完全相同的方法,僅僅是傳回類型不同,java就無法确定程式設計者
倒底是想調用哪個方法了,因為它無法通過傳回結果類型來判斷。 
           

override可以翻譯為覆寫,從字面就可以知道,它是覆寫了一個方法并且對其重寫,以求達到不同的作用。對我們來說最熟悉的覆寫就是對接口方法的實作,在接口中一般隻是對方法進行了聲明,而我們在實作時,就需要實作接口聲明的所有方法。除了這個典型的用法以外,我們在繼承中也可能會在子類覆寫父類中的方法。在覆寫要注意以下的幾點:

1、覆寫的方法的标志必須要和被覆寫的方法的标志完全比對,才能達到覆寫的效果;

2、覆寫的方法的傳回值必須和被覆寫的方法的傳回一緻;

3、覆寫的方法所抛出的異常必須和被覆寫方法的所抛出的異常一緻,或者是其子類;

4、被覆寫的方法不能為private,否則在其子類中隻是新定義了一個方法,并沒有對其進行覆寫。

Overload對我們來說可能比較熟悉,可以翻譯為重載,它是指我們可以定義一些名稱相同的方法,通過定義不同的輸入參數來區分這些方法,然後再調用時,VM就會根據不同的參數樣式,來選擇合适的方法執行。在使用重載要注意以下的幾點:

1、在使用重載時隻能通過不同的參數樣式。例如,不同的參數類型,不同的參數個數,不同的參數順序(當然,同一方法内的幾個參數類型必須不一樣,例如可以是fun(int,float),但是不能為fun(int,int));

2、不能通過通路權限、傳回類型、抛出的異常進行重載;

3、方法的異常類型和數目不會對重載造成影響;

4、對于繼承來說,如果某一方法在父類中是通路權限是priavte,那麼就不能在子類對其進行重載,如果定義的話,也隻是定義了一個新方法,而不會達到重載的效果。

5:Integer與int的差別?

int是java提供的8種原始資料類型之一。Java為每個原始類型提供了封裝類,Integer是java為int提供的封裝類。int的預設值為0,而Integer的預設值為null,即Integer可以區分出未指派和值為0的差別,int則無法表達出未指派的情況。

6:char型變量中能不能存貯一個中文漢字?為什麼?

char型變量是用來存儲Unicode編碼的字元的,unicode編碼字元集中包含了漢字,是以,char型變量中當然可以存儲漢字啦。不過,如果某個特殊的漢字沒有被包含在unicode編碼字元集中,那麼,這個char型變量中就不能存儲這個特殊漢字。補充說明:unicode編碼占用兩個位元組,是以,char類型的變量也是占用兩個位元組。

7:String s = new String(“xyz”);建立了幾個StringObject?是否可以繼承String類?

注:這道題是我自己遇到過次數最多的一道題,基本上好多筆試
都會有這道題
           
兩個或一個都有可能,”xyz”對應一個對象,這個對象放在字元串常量緩沖區,常量”xyz”不管出現多少遍,都是緩沖區中的那一個。NewString每寫一遍,就建立一個新的對象,它使用常量”xyz”對象的内容來建立出一個新String對象。如果以前就用過’xyz’,那麼這裡就不會建立”xyz”了,直接從緩沖區拿,這時建立了一個StringObject;但如果以前沒有用過"xyz",那麼此時就會建立一個對象并放入緩沖區,這種情況它建立兩個對象。至于String類是否繼承,答案是否定的,因為String預設final修飾,是不可繼承的。

8:GC是什麼?為什麼要有GC?

GC是垃圾收集的意思(Gabage Collection),記憶體處理是程式設計人員容易出現問題的地方,忘記或者錯誤的記憶體回收會導緻程式或系統的不穩定甚至崩潰,Java提供的GC功能可以自動監測對象是否超過作用域進而達到自動回收記憶體的目的,Java語言沒有提供釋放已配置設定記憶體的顯示操作方法。

9:List,Set, Map是否繼承自Collection接口?

List,Set是,Map不是

10:ArrayList和Vector的差別

(1)同步性:

Vector是線程安全的,也就是說是它的方法之間是線程同步的,而ArrayList是線程式不安全的,它的方法之間是線程不同步的。如果隻有一個線程會通路到集合,那最好是使用ArrayList,因為它不考慮線程安全,效率會高些;如果有多個線程會通路到集合,那最好是使用Vector,因為不需要我們自己再去考慮和編寫線程安全的代碼。

(2)資料增長:即Vector增長原來的一倍,ArrayList增加原來的0.5倍。

11:==和equals差別

“== ” 比較的是兩個引用在記憶體中指向的是不是同一對象(即同一記憶體空間),也就是說在記憶體空間中的存儲位置是否一緻。如果兩個對象的引用相同時(指向同一對象時),“==”操作符傳回true,否則傳回flase。

equals用來比較某些特征是否一樣。我們平時用的String類等的equals方法都是重寫後的,實作比較兩個對象的内容是否相等。

12:String、StringBuffer和StringBuilder差別

  1. 資料可變和不可變:

    String底層使用一個不可變的字元數組private final char value[];是以它内容不可變。

    StringBuffer和StringBuilder都繼承了AbstractStringBuilder底層使用的是可變字元數組:char[] value;

  2. 線程安全:

    StringBuilder是線程不安全的,效率較高;而StringBuffer是線程安全的,效率較低。

    通過他們的append()方法來看,StringBuffer是有同步鎖,而StringBuilder沒有:

13:ArrayList和LinkedList差別?

注:這個問題我在技面的時候也被問到了哦!
           

1、ArrayList是實作了基于動态數組的資料結構,LinkedList基于連結清單的資料結構。

2、對于随機通路get和set,ArrayList覺得優于LinkedList,因為LinkedList要移動指針。

3、對于新增和删除操作add和remove,LinedList比較占優勢,因為ArrayList要移動資料。

14: 線程建立方式

線程的重要性就不要我多說了,無論是想對于基礎的知識還是
進階的知識都是多頻考點與問點。
           

方法一:繼承Thread類,作為線程對象存在(繼承Thread對象)

方法二:實作runnable接口,作為線程任務存在

方法三:匿名内部類建立線程對象

方法四:建立帶傳回值的線程(實作Callable) :

這種方法帶有傳回值,其他方式可以不了解,但是基本的方法一、
方法二以及	這種方法一定要掌握。
傳回指定泛型的call方法。然後調用FutureTask對象的get方法得到
call方法的傳回值。
           

方法五:定時器Timer

方法六:線程池建立線程

方法七:利用java8新特性 stream 實作并發:這個就是用到lambda了

15:兩個對象的hashCode相同,則equals也一定為true,對嗎?

這塊肯定是有争議的。面試的時候這樣答:如果按照官方設計要求來打代碼的話,hashcode一定相等。但是如果不按官方照設計要求、不重寫hashcode方法,就會出現不相等的情況。

16:Math.round(-2.5)等于多少?

+0.5後向下取整。是以結果是-2。
注:千萬不要把他記成四舍五入
           

17:JDK1.8新特性

1、lambda表達式

2、函數是接口

3、流式(stream)處理

4、新時間日期API

5、接口中的預設方法和靜态方法

6、方法引用和構造器調用

18:TCP和UDP差別

1、TCP面向連接配接,UDP面向非連接配接

2、TCP提供可靠的服務(資料傳輸無差錯、不丢失、不重複、按序到達),UDP不可靠

3、TCP面向位元組流,UDP面向封包

4、TCP資料傳輸慢,UDP資料傳輸快

5、TCP首部開銷20位元組,UDP8位元組

19:為什麼要三次握手?

保持資訊對等。

防止請求逾時導緻髒連接配接。

20:兩次握手會怎樣?

如果兩次握手就建立連接配接,傳輸完資料并釋放連接配接後,第一個逾時的連接配接請求才到達伺服器,伺服器會認為是用戶端建立新連接配接的請求,然後建立連接配接。此時用戶端的狀态不是SYN_SENT,是以會直接丢棄伺服器傳來的确認資料,導緻最後隻是伺服器單方面建立了連接配接。

網絡基礎部分除去個别公司考的不多,但不能不看哦!還可以看一下常用的端口号等知識。字元串的相關方法以及數組這裡我沒有提及,但是一定一定一定要會,尤其字元串的方法,如:切割,截取字元等方法。