JAVA校招面試題

具體是哪家公司的就不說了,反正我不記得,也沒我份。。。。另外,問題是別人的,答案是自己的,不保證是否正確。

1、線程的實現方式有幾種?分別是什麼?

倆種,一種是繼承Thread類,一種是實現Runnable接口,常用第二種,因爲收到了java單繼承的限制。

2、java的特點是什麼?有哪些特性?

我的回答是:面向對象,主要包含以下三個特性:封裝、多態、繼承

此外,還有五大基本原則:

(1)單一職責原則(Single-Responsibility Principle,SRP):指一個類的功能要單一,不能包羅萬象,如同一個人一樣,分配的工作不能太多,否則一天到晚雖然忙忙碌碌,但效率不高。

(2)開放封閉原則(Open-Closed Principle,OCP):一個模塊在擴展性方面應該是開放的,而在更改性方面應該是封閉的。比如,一個網絡模塊,原來只服務端功能,而現在要加入客戶端功能。那麼應該

不用修改服務端代碼的前提下,就能夠增加客戶端功能的實現代碼。這要求在設計之初就應當將服務端和客戶端分開,公共部分抽象出來。

(3)里氏替換原則(Liskov-Substituent Principe,LSP):子類應當可以替換父類並出現在父類能夠出現的任何地方。比如:公司搞年度晚會,所有員工都可以參加抽獎,那麼無論是老員工還是新員工,也

管是總部員工還是外派員工,都應當可以參加抽獎。

(4)依賴原則(Dependency-Inversion Principle,DIP):具體依賴抽象,上層依賴下層。假設B是較A低的模塊,但B需要用到A的功能,這個時候,B不應該直接使用A中的具體類,而應當由B定義一抽象

口,並由A來實現這個抽象接口,B只使用這個抽象接口,這樣就達到了依賴倒置的目的,B也解除了對A的依賴,反過來是A依賴於B定義的抽象接口,通過上層模塊難以避免

賴下層模塊,加入B也直接依賴A實現,那麼就可能造成循環依賴,一個常見的問題就是編譯A模塊時需要直接包含到B模塊的CPP文件,而編譯B時同樣需要直接包含到A

CPP文件。

(5)接口分離原則(the interface Segregation Principe,ISP):模塊間要通過抽象接口隔離開,而不是通過具體的類強耦合起來。

該題部分答案來自http://www.cnblogs.com/hnrainll/archive/2012/09/18/2690846.html

3、抽象類可以繼承抽象類嗎?
可以,抽象類也是類,所以具有類的特性,詳情如下:

abstract class A{  
    abstract void add();  
    public void delete(){}  
}  
abstract class B extends A{  
    //繼承了抽象A類,因爲也是抽象的,可以不寫抽象方法,當然也可以重寫抽象方法(切記抽象方法是沒有方法體的)  
    //abstract void add(); //也是沒有問題的  

    abstract void getXX();  
}  
public class extends B{  
    //必須實現抽象方法  
    //繼承了B,也就繼承了A,A B方法都有,所以必須重寫這兩個抽象類的抽象方法  
    public void add(){}  
    public void delete(){}  
    public void getXX(){}  
}  

4、接口可以實現接口嗎?

不可以,因爲接口的成員方法都具有抽象屬性,不具有方法體,無法實現繼承的接口,但是可以繼承接口,並且可以繼承多個接口,如下:

public interface Interface2 extends Interface1,Interface3{  


}  

5、接口可以繼承抽象類嗎?

不可以,接口裏的方法是不能有方法體的,但抽象類允許方法體,所以會有衝突。但是抽象類可以實現接口。

6、接口和抽象類的區別?

(1)抽象類可以有方法實現,接口完全抽象,不存在方法實現;

(2)抽象類可以有構造器,接口不能有;

(3)抽象類除了不能實例化,其他和普通的java類沒有什麼區別,接口是完全不同的類型;

(4)抽象類可以有public、protected和default這些修飾符,接口默認public,不允許其他的修飾符;

(5)抽象類可以繼承一個類,實現多個方法,接口可以繼承一個或多個其他接口;

(6)抽象類速度比接口快,因爲接口需要時間去尋找在類中實現的方法。

(7)抽象類可以添加新的方法,可以給該方法提供默認實現,因此可以不需要改變子類。接口一旦添加方法,實現該接口的類也必須改變。

來源:http://www.importnew.com/12399.html

7、靜態代碼塊、構造代碼塊、構造方法、main方法執行順序

public class StaticCode {  


    //執行順序:(優先級從高到低。)靜態代碼塊>main方法>構造代碼塊>構造方法。  
    int i = 1;  
    static int j = 2;  
    //這是靜態代碼塊:項目啓動時初始化,而靜態方法則是被調用時初始化  
    static{  
        j=3;  
        //i=1;編譯報錯  
        System.out.println("靜態代碼塊1");  
    }  
    static{  
        System.out.println("靜態代碼塊2");  
    }  
    //這是構造代碼塊:實例化對象時執行  
    {  
        j=2;  
        i=3;  
        System.out.println("構造代碼塊1");  
    }  
    {  
        System.out.println("構造代碼塊2");  
    }  

    public StaticCode(){  
        System.out.println("構造方法");  
    }  
    public static void main(String[] args) {  
        System.out.println("main方法");  
        new StaticCode();  
        new StaticCode();  
    }  
}  

運行結果:
靜態代碼塊1
靜態代碼塊2
main方法
構造代碼塊1
構造代碼塊2
構造方法
構造代碼塊1
構造代碼塊2
構造方法

8、同步的實現方法

(1)同步方法synchronized

由於java的每個對象都有一個內置鎖,當使用該關鍵字修飾方法時,內置鎖會保護整個方法。在調用該方法前,需要獲得內置鎖,否則處於阻塞狀態。

代碼示例:

public synchronized void synchronizedMethod1(){  

    }  

改關鍵字也可以修飾靜態方法,如果調用該靜態方法,將會鎖住整個類。

(2)同步代碼塊

被synchronized修飾的代碼塊,例如:

int account;  
    public void synchronizedMethod2(){  
        synchronized (this) {  
            account= 1000;  
        }  
    }  

同步是一種高開銷的操作,因此應該儘量減少同步的內容。通常沒必要同步整個方法,使用同步代碼塊即可。

(3)使用特殊域變量(volatile)

a、volatile爲域變量的訪問提供了一種免鎖機制;

b、使用volatile相當於告訴虛擬機該域可能會被其他線程更新;

c、因此每次使用該域需要重新計算,而不是使用寄存器中的值;

d、volatile不會提供任何原子操作,它也不能用來修飾final類型的變量。

使用方法:直接加載變量前;

注:多線程中非同步問題主要出現在對域的讀寫上,如果讓域自身避免這個問題,這就不需要修改操作該域的方法。

用final域,有鎖保護的域和volatile域可以避免非同步的問題。

(4)使用重入鎖

JavaSE5.0新增了一個java.util.concurrent包來實現同步

ReentrantLock類是可重入、互斥、實現了Lock接口的鎖,他與使用synchronized方法和塊具有相同的基本行爲和語義,並且擴展了其能力。

ReentrantLock常用方法:

a、ReentrantLock():創建實例;

b、lock():獲得鎖,
c、unlock():釋放鎖。

9、線程有哪幾種狀態?

五種:

(1)新建:使用new;

(2)就緒:調用start()方法後的狀態;

(3)運行:處於run()方法的狀態;

(4)阻塞/等待/睡眠;

(5)死亡:run()完成時,此時調用start()會報錯;

狀態的轉換:
這裏寫圖片描述

圖片來自:https://my.oschina.net/mingdongcheng/blog/139263

10、mysql中InnoDB和MyIsam(默認)的區別

(1)InnoDB支持外鍵和事務,MyIsam不支持;

(2)InnoDB支持數據行鎖定,MyISAM只支持鎖定整張表;

(3)InnoDB不支持全文索引FULLTEXT,MyISAM支持;

(4)InnoDB主鍵範圍更大;

(5)MyISAM支持gis數據,InnDB不支持。

(6)MyISAM會保存表的行數,所以select (*) from table;的速度更快,但如果帶有where子句,而倆者的操作是一樣的。

11、mysql回滾的實現原理

似乎是使用保存點savepoint實現的,後期補充

12、spring事務配置方式

<!-- 事務管理器 -->  
<bean id="transactionManager"  
    class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
    <property name="dataSource" ref="dataSource"></property>  
</bean>  

   <!-- 配置事務處理通知 -->  
<tx:advice id="txAdvice" transaction-manager="transactionManager">  
    <tx:attributes>  
        <tx:method name="save*" rollback-for="Exception" />  
        <tx:method name="get*" read-only="false" />  
        <tx:method name="add*" rollback-for="Exception" />  
        <tx:method name="addOrUpdate*" rollback-for="Exception" />  
        <tx:method name="del*" rollback-for="Exception" />  
        <tx:method name="remove*" rollback-for="Exception" />  
        <tx:method name="update*" propagation="REQUIRED"  
            rollback-for="Exception" />  
        <tx:method name="query*" rollback-for="Exception" />  
    </tx:attributes>  
</tx:advice>  


<aop:config proxy-target-class="true">  
    <aop:pointcut id="serviceMethod"  
        expression="execution(* com.gpl.**.*.biz.*Biz.*(..))" />  
    <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethod" />  
</aop:config>  

13、String的緩存機制

參見此處(http://blog.csdn.net/tiantiandjava/article/details/46309163

14、spring的核心是什麼?

IOC和AOP

IOC:傳統上使用一個對象需要使用new關鍵字實例化,而使用IOC則允許在配置文件中配置而後注入到對應的類中;

AOP: 面向切面變成,可以在方法前、方法後、實例化前、實例化後做一下操作,如傳統的日誌記錄需要在每個類中做處理,而使用AOP則只需要寫一個類,之後配置一下即可

15、mysql隔離機制?
這裏寫圖片描述

圖片來源:http://xm-king.iteye.com/blog/770721

髒讀:一個事務未提交,而另一個事務可以讀到這部分未提交的數據,而這部分數據由於未提交,可能會回滾;

不可重複讀:事務A先查詢一遍,之後事務B提交,事務A在查詢,發現數據被更改;

幻讀:幻讀,是指當事務不是獨立執行時發生的一種現象,例如第一個事務對一個表中的數據進行了修改,這種修改涉及到表中的全部數據行。同時,第二個事務也修改這個

表中的數據,這種修改是向表中插入一行新數據。那麼,以後就會發生操作第一個事務的用戶發現表中還有沒有修改的數據行,就好象發生了幻覺一樣.

16、事務的特性

(1)原子性:要麼都完成,要麼都不完成;

(2)一致性:事務完成前後數據的完整性保持不變(如外鍵不會被破壞);

(3)隔離性:當多個事務同時操作數據庫時,可能存在並發現象,此時應保持事務之間隔離,彼此不受影響;

(4)持久性:事務一旦提交,那麼改變的數據就是永久的,不能再回滾。

17、拼接字符串有哪些方式?
http://blog.csdn.net/kimsoft/article/details/3353849

18、如何在http頭中指定緩存?
http中緩存主要是以下內容:

(1)Expires和Cache-Control

Expires: Sun, 16 Oct 2016 05:43:02 GMT(絕對時間)
Cache-Control: max-age:600(相對時間,解決上述設置由於客戶端時間設置引起的問題)

(2)Last-Modifed和If-Modify-since

客戶端第一次訪問資源的時候,服務端返回資源內容的同時返回了Last-Modifed:Wed, 07 Aug 2013 15:32:18 GMT

服務端在告訴客戶端:你獲取的這個文件我最後的修改時間是Wed, 07 Aug 2013 15:32:18 GMT 。瀏覽器在獲取這個文件存到緩存中的時候,給緩存中的文件同時記錄上這個最後修改時間。
第二次訪問的時候(我們假設這裏沒有設置expires或者cache-control)。那麼客戶端訪問資源的時候會帶上If-Modify-since:Wed, 07 Aug 2013 15:32:18 GMT ;
客戶端詢問服務端:喂,我需要的這個資源其實我這邊已經有緩存了,我的緩存文件的最後修改時間是這個,如果你那邊的資源在這個時間以後沒有修改的話,你就告訴我一下就好了,不需要返回實際的資源內容。反之,要是你有修改的話,你就把文件內容返回給我吧。
服務端迴應說:哦。行爲是看下資源是否在這個時間後沒有修改過,如果沒有修改返回個304告訴客戶端,我沒有修改過。如果有變化了,我就返回200,並且帶上資源內容。

(3)ETag和If-None-Match

第一次客戶端訪問資源的時候,服務端返回資源內容的同時返回了ETag:1234,告訴客戶端:這個文件的標籤是1234,我如果修改了我這邊的資源的話,這個標籤就會不一樣了。
第二次客戶端訪問資源的時候,由於緩存中已經有了Etag爲1234的資源,客戶端要去服務端查詢的是這個資源有木有過期呢?所以帶上了If-None-Match: 1234。告訴服務端:如果你那邊的資源還是1234標籤的資源,你就返回304告訴我,不需要返回資源內容了。如果不是的話,你再返回資源內容給我就行了。服務端就比較下Etag來看是返回304還是200。

(4)各種刷新

理解了上面的緩存標籤之後就很好理解各種刷新了。
刷新有三種
a、瀏覽器中寫地址,回車
b、F5
c、Ctrl+F5
假設對一個資源:
瀏覽器第一次訪問,獲取資源內容和cache-control: max-age:600,Last_Modify: Wed, 10 Aug 2013 15:32:18 GMT
於是瀏覽器把資源文件放到緩存中,並且決定下次使用的時候直接去緩存中取了。
瀏覽器url回車

瀏覽器發現緩存中有這個文件了,好了,就不發送任何請求了,直接去緩存中獲取展現。(最快)
下面我按下了F5刷新

F5就是告訴瀏覽器,別偷懶,好歹去服務器看看這個文件是否有過期了。於是瀏覽器就膽膽襟襟的發送一個請求帶上If-Modify-since:Wed, 10 Aug 2013 15:32:18 GMT
然後服務器發現:誒,這個文件我在這個時間後還沒修改過,不需要給你任何信息了,返回304就行了。於是瀏覽器獲取到304後就去緩存中歡歡喜喜獲取資源了。
但是呢,下面我們按下了Ctrl+F5
這個可是要命了,告訴瀏覽器,你先把你緩存中的這個文件給我刪了,然後再去服務器請求個完整的資源文件下來。於是客戶端就完成了強行更新的操作…
注意:那個ETag實際上很少人使用,因爲它的計算是使用算法來得出的,而算法會佔用服務端計算的資源,所有服務端的資源都是寶貴的,所以就很少使用etag了。

本題來源:http://www.cnblogs.com/yjf512/p/3244882.html

設置緩存的方式如下:

response.setHeader("Pragma","No - cache");  
response.setHeader("Cache - Control","no - cache");  
response.setDateHeader("Expires",0)  

19、java是按值傳遞還是按地址傳遞?

原生類型按值傳遞,自定義類型按地址傳遞

此外:

a、“在Java裏面參數傳遞都是按值傳遞”這句話的意思是:按值傳遞是傳遞的值的拷貝,按引用傳遞其實傳遞的是引用的地址值,所以統稱按值傳遞。
b、在Java裏面只有基本類型(包括其包裝類)和按照下面這種定義方式的String是按值傳遞,其它的都是按引用傳遞。就是直接使用雙引號定義字符串方式:String str = “Java私塾”;

示例1(基礎數據封裝類):

public class Main {  
    public static void main(String[] args) {  
        Integer integer = 10;  
        test(integer);  
        System.out.println(integer);  
    }  

    private static void test(Integer integer) {  
        // TODO Auto-generated method stub  
        integer = 20;  
    }  

}  

輸出10
示例2(自定義類):

public class Main {  
    public static void main(String[] args) {  
        A a = new A();  
        a.a = 10;  
        test(a);  
        System.out.println(a.a);  
    }  

    private static void test(A a) {  
        // TODO Auto-generated method stub  
        a.a = 20;  
    }  

}  
class A{  
    int a;  
}  

輸出20

解決示例2因爲按地址傳遞導致結果被改變的方法:在test方法中重新new對象:

public class Main {  
    public static void main(String[] args) {  
        A a = new A();  
        a.a = 10;  
        test(a);  
        System.out.println(a.a);  
    }  

    private static void test(A a) {  
        // TODO Auto-generated method stub  
        a = new A();  
        a.a = 20;  
    }  

}  
class A{  
    int a;  
}  

輸出10

20、js定義一個對象

http://group.cnblogs.com/topic/37998.html

21、以下倆行代碼有何區別:

public class Main {  
    private static final int a = 10;  
    private static final int b = 11;  
    private static int c = 10;  
    private static int d = 11;  
    public static void main(String[] args) {  
        int e = a + b; //1  
        int f = c + d; //2  
    }  
}  

第一行在編譯器執行,第二行在運行期執行,原因:java編譯器使用了常量摺疊技術來優化

22、九種基本類型大小及封裝類
這裏寫圖片描述

雖然定義了boolean這種數據類型,但是隻對它提供了非常有限的支持。在Java虛擬機中沒有任何供boolean值專用的字節碼指令,Java語言表達式所操作的boolean值,在編譯之後都使用Java虛擬機中的int數據類型來代替,而boolean數組將會被編碼成Java虛擬機的byte數組,每個元素boolean元素佔8位”。這樣我們可以得出boolean類型佔了單獨使用是4個字節,在數組中又是1個字節。

文字來自:http://blog.csdn.net/syc434432458/article/details/49964089

23、switch能否用string做參數:

Cannot switch on a value of type boolean. Only convertible int values, strings or enum variables are permitted

從上面的話中可以看出,switch只支持byte、char、int、string(1.6及之前不支持string)、short、enum,而不支持long、double、float、boolean

24、equals和等號的區別?

前者比較內容,後者比較地址

25、object有哪些公用方法?

equals、hashcode、wait、notify、notifyAll、clone、getClass

26、 Java的四種引用,強弱軟虛,用到的場景。

強引用:不會被gc回收,平常使用的便是強引用,如Object object = new Object();就是;

軟引用:內存空間足夠,垃圾回收器就不會回收它,如果內存空間不足了,就會回收這些對象的內存

弱引用:一旦發現了只具有弱引用的對象,不管當前內存空間足夠與否,都會回收它的內存

虛引用(幽靈引用):發現它還有虛引用,就會在回收對象的內存之前,把這個虛引用加入到與之關聯的引用隊列

強弱次序:強>軟>弱>虛

注:可通過System.gc();提醒虛擬機執行垃圾回收,但虛擬機未必會執行。

來源:http://blog.csdn.net/u011860731/article/details/48714321

27、hashcode方法的作用

hashCode方法的主要作用是爲了配合基於散列的集合一起正常運行,這樣的散列集合包括HashSet、HashMap以及HashTable。(因爲equals方法代價比較大)

28、ArrayList、LinkedList、Vector的區別。

ArrayList 是一個可改變大小的數組.當更多的元素加入到ArrayList中時,其大小將會動態地增長.內部的元素可以直接通過get與set方法進行訪問,因爲ArrayList本質上就是一個數組.
LinkedList 是一個雙鏈表,在添加和刪除元素時具有比ArrayList更好的性能.但在get與set方面弱於ArrayList.
當然,這些對比都是指數據量很大或者操作很頻繁的情況下的對比,如果數據和運算量很小,那麼對比將失去意義.
Vector 和ArrayList類似,但屬於強同步類。如果你的程序本身是線程安全的(thread-safe,沒有在多個線程之間共享同一個集合/對象),那麼使用ArrayList是更好的選擇。
Vector和ArrayList在更多元素添加進來時會請求更大的空間。Vector每次請求其大小的雙倍空間,而ArrayList每次對size增長50%.
而 LinkedList 還實現了 Queue 接口,該接口比List提供了更多的方法,包括 offer(),peek(),poll()等.
注意: 默認情況下ArrayList的初始容量非常小,所以如果可以預估數據量的話,分配一個較大的初始值屬於最佳實踐,這樣可以減少調整大小的開銷。

來源:http://blog.csdn.net/renfufei/article/details/17077425

29、String、StringBuffer與StringBuilder的區別。

性能上來講:StringBuilder>StringBuffer>String

原因:

String內部定義如下:

/** The value is used for character storage. */    
private final char value[];    

/** The offset is the first index of the storage that is used. */    
private final int offset;    

/** The count is the number of characters in the String. */    
private final int count;    

可見,用於存放字符的char數組是final的,所以每次改變String的值時,實際上是重新創建了一個String對象,然後將原來的對象指向新創建的對象的地址,另外,在某些特別情況下, String 對象的字符串拼接其實是被 Java Compiler 編譯成了 StringBuffer 對象的拼接,所以這些時候 String 對象的速度並不會比 StringBuffer 對象慢。但要注意的是,如果拼接的字符串來自另外的String對象的話,Java Compiler就不會自動轉換了,速度也就沒那麼快了。
StringBuffer是線程安全的,StringBuilder是線程不安全的。

使用策略:

(1)基本原則:如果要操作少量的數據,用String ;單線程操作大量數據,用StringBuilder ;多線程操作大量數據,用StringBuffer。

(2)不要使用String類的”+”來進行頻繁的拼接,因爲那樣的性能極差的,應該使用StringBuffer或StringBuilder類,這在Java的優化上。

是一條比較重要的原則
(3)爲了獲得更好的性能,在構造 StringBuffer 或 StringBuilder 時應儘可能指定它們的容量。

來源:http://blog.csdn.net/kingzone_2008/article/details/9220691

30、 Map、Set、List、Queue、Stack的特點與用法。

java容器類類庫可以劃分爲倆個不同的概念:

a、Collection(包括List、Set和Queue):每個位置只能保存一個元素(對象);

b、Map:保存的是”鍵值對”,就像一個小型數據庫。我們可以通過”鍵”找到該鍵對應的”值”

以上轉載自:http://blog.csdn.net/wyccyw123456/article/details/52643726

發佈了36 篇原創文章 · 獲贊 51 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章