Java面試題03

Java面試題(03

一、一個「.java」源文件中是否能夠包含多個類(不是內部類)?有什麼限制?

能夠包含多個類。只容許有一個公共類,且公共類名與Java源文件名相同。java

二、switch可否做用在byte上,可否做用在long上,可否做用在String上?

基本類型的包裝類(如:Character、Byte、Short、Integer)linux

switch可做用於char byte short int
switch可做用於char byte short int對應的包裝類
switch不可做用於long double float boolean,包括他們的包裝類
switch中能夠是字符串類型,String(jdk1.7以後才能夠做用在string上)
switch中能夠是枚舉類型程序員

三、說說final、finally、finalize三者的區別?

答:面試

1.final:若是一個類被final修飾,意味着該類不能派生出新的子類,不能做爲父類被繼承。所以一個類不能被聲明爲abstract,又被聲明爲final。將變量或方法聲明爲final。能夠保證他們在使用的時候不被改變。其初始化能夠在兩個地方:一是其定義的地方,也就是在final變量在定義的時候就對其賦值;二是在構造函數中。這兩個地方只能選其中的一個,要麼在定義的時候給值,要麼在構造函數中給值。被聲明爲final的方法也只能使用,不能重寫。算法

2.finally:在異常處理的時候,提供finally塊來執行任何的清除操做。若是拋出一個異常,那麼相匹配的catch字句就會執行,而後控制就會進入finally塊,前提是有finally塊。sql

3.finalize:finalize是方法名,java技術容許使用finalize()方法在垃圾收集器將對象從內存中清除出去以前作必要的清理工做。這個方法是在垃圾收集器確認一個對象沒有被引用時對這個對象調用的。它是在Object類中定義的,所以,全部的類都繼承了它。子類覆蓋finalize()方法已整理系統資源或者執行其餘清理工做。finalize()方法是在垃圾收集器刪除對象以前對這個對象調用的。數組

 

四、Math.round(11.5)和Math.round(-11.5)分別等於多少?

答案:12    和    -11瀏覽器

0一、round()方法能夠這樣理解:緩存

將括號內的數+0.5以後,向下取值,安全

好比:round(3.4)就是3.4+0.5=3.9,向下取值是3,因此round(3.4)=3; 

round(-10.5)就是-10.5+0.5=-10,向下取值就是-10,因此round(-10.5)=-10

因此,Math.round(11.5)=12; Math.round(-11.5)=-11;

 

0二、擴展

00一、Math.ceil求最小的整數,但不小於自己.  

ceil的英文意義是天花板,該方法就表示向上取整,

例子:

因此,Math.ceil(11.3)的結果爲12,Math.ceil(-11.3)的結果是-11;

 

00二、Math.floor求最大的整數,但不大於自己.

floor的英文意義是地板,該方法就表示向下取整,

例子:

floor的英文意義是地板,該方法就表示向下取整,

因此,Math.floor(11.6)的結果爲11,Math.floor(-11.6)的結果是-12;

 

五、說說String、StringBuffer、StringBuilder的區別。

區別:String 類型和 StringBuffer 類型的主要性能區別其實在於 String 是不可變的對象,所以在每次對 String 類型進行改變的時候其實都等同於生成了一個新的 String 對象,而後將指針指向新的 String 對象,因此常常改變內容的字符串最好不要用 String ,由於每次生成對象都會對系統性能產生影響,特別當內存中無引用對象多了之後, JVM 的 GC 就會開始工做,那速度是必定會至關慢的,

 

執行速度:三者在執行速度方面的比較:

StringBuilder >  StringBuffer  >  String

 

使用場景:

01.若是要操做少許的數據用 = String  

02.單線程操做字符串緩衝區 下操做大量數據 = StringBuilder

03.多線程操做字符串緩衝區 下操做大量數據 = StringBuffe

 

六、爲何不建議記錄日誌時使用System.out.println()。

1.  Log4j就是幫助開發人員進行日誌輸出管理的API類庫。它最重要的特色就能夠配置文件靈活的設置日誌信息的優先級、日誌信息的輸出目的地以及日誌信息的輸出格式。

2.  Log4j除了能夠記錄程序運行日誌信息外還有一重要的功能就是用來顯示調試信息。

3.  程序員常常會遇到脫離java ide環境調試程序的狀況,這時大多數人會選擇使用System.out.println語句輸出某個變量值的方法進行調試。這樣會帶來一個很是麻煩的問題:一旦哪天程序員決定不要顯示這些System.out.println的東西了就只能一行行的把這些垃圾語句註釋掉。若哪天又需調試變量值,則只能再一行行去掉這些註釋恢復System.out.println語句。

使用log4j能夠很好的處理相似狀況。

 

七、運行時異常和普通異常有什麼區別?

Java提供了兩種錯誤的異常類,分別爲Error和Exception,他們擁有共同的父類—Throwable。   

    Error表示程序在運行期間出了很是嚴重的錯誤,而且錯誤不可恢復,如OutOfMemoryError、ThreadDeath等

    Exception表示能夠恢復的異常,是編譯器能夠捕捉到的。包含兩種類型:

    檢查異常和運行時異常。

    1)檢查異常。Java編譯器強制程序去捕獲此類異常,如IO異常和SQL異常。

    2)運行時異常。編譯器不會對其強制進行捕獲並處理。若是不進行處理,出現異常時,JVM會來處理。

          出現運行時異常,系統會把異常一直往上拋,知道遇處處理代碼爲止。若沒有處理代碼,則拋到最上層。

          多線程又Thread.run()方法拋出,單線程用main()方法拋出。若是不處理異常,一旦發生,要麼線程終止,要麼主程序終止。

          運行時異常包括:NullPointException(空指針異常)

            ClassCastException(類型轉換異常)

      ArrayIndexOutOfBoundsException(數組越界異常)

      ArrayStoreException(數組存儲異常)

      BufferOverflowException(緩衝區溢出異常)

      ArithmeticException(算輸異常)

 

八、Thread.Sleep和Object.wait()有什麼區別?

一、這兩個方法來自不一樣的類分別是,sleep來自Thread類,和wait來自Object類。

sleep是Thread的靜態類方法,誰調用的誰去睡覺,即便在a線程裏調用了b的sleep方法,實際上仍是a去睡覺,要讓b線程睡覺要在b的代碼中調用sleep。


二、最主要sleep方法沒有釋放鎖,而wait方法釋放了鎖,使得其餘線程可使用同步控制塊或者方法。

sleep不出讓系統資源;wait是進入線程等待池等待,出讓系統資源,其餘線程能夠佔用CPU。通常wait不會加時間限制,由於若是wait線程的運行資源不夠,再出來也沒用,要等待其餘線程調用notify/notifyAll喚醒等待池中的全部線程,纔會進入就緒隊列等待OS分配系統資源。sleep(milliseconds)能夠用時間指定使它自動喚醒過來,若是時間不到只能調用interrupt()強行打斷。

Thread.Sleep(0)的做用是「觸發操做系統馬上從新進行一次CPU競爭」。


三、使用範圍:wait,notify和notifyAll只能在同步控制方法或者同步控制塊裏面使用,而sleep能夠在任何地方使用 
   synchronized(x){ 
      x.notify() 
     //或者wait() 
   }


四、sleep必須捕獲異常,而wait,notify和notifyAll不須要捕獲異常

 

九、當一個線程進入一個對象的一個synchronized方法後,其它線程是否能夠進入此對象的其餘synchronized方法和普通方法?

1.其餘方法前是否加了synchronized關鍵字,若是沒加,則能。
2.若是這個方法內部調用了wait,則能夠進入其餘synchronized方法。
3.若是其餘個方法都加了synchronized關鍵字,而且內部沒有調用wait,則不能。
4.若是其餘方法是static,它用的同步鎖是當前類的字節碼,與非靜態的方法不能同步,由於非靜態的方法用的是this。

 

十、如何遍歷HashMap。

public static void main(String[] args) {

  Map<String,String> map=new HashMap<String,String>();
        map.put("1", "value1");
        map.put("2", "value2");
        map.put("3", "value3");
        map.put("4", "value4");
       
        //第一種:普通使用,二次取值
        System.out.println("\n經過Map.keySet遍歷keyvalue"); 
        for(String key:map.keySet())
        {
         System.out.println("Key: "+key+" Value: "+map.get(key));
        }
       
        //第二種
        System.out.println("\n經過Map.entrySet使用iterator遍歷keyvalue: "); 
        Iterator map1it=map.entrySet().iterator();
        while(map1it.hasNext())
        {
         Map.Entry<String, String> entry=(Entry<String, String>) map1it.next();
         System.out.println("Key: "+entry.getKey()+" Value: "+entry.getValue());
        }
       
        //第三種:推薦,尤爲是容量大時 
        System.out.println("\n經過Map.entrySet遍歷keyvalue"); 
        for(Map.Entry<String, String> entry: map.entrySet())
        {
         System.out.println("Key: "+ entry.getKey()+ " Value: "+entry.getValue());
        }
       
        //第四種 
        System.out.println("\n經過Map.values()遍歷全部的value,但不能遍歷key"); 
        for(String v:map.values())
        {
         System.out.println("The value is "+v);
        }
 }

 

輸出結果:

 

經過Map.keySet遍歷keyvalue

Key: 1 Value: value1

Key: 2 Value: value2

Key: 3 Value: value3

Key: 4 Value: value4

 

經過Map.entrySet使用iterator遍歷keyvalue:

Key: 1 Value: value1

Key: 2 Value: value2

Key: 3 Value: value3

Key: 4 Value: value4

 

經過Map.entrySet遍歷keyvalue

Key: 1 Value: value1

Key: 2 Value: value2

Key: 3 Value: value3

Key: 4 Value: value4

 

經過Map.values()遍歷全部的value,但不能遍歷key

The value is value1

The value is value2

The value is value3

The value is value4

 

十一、Set中和的元素不能重複,用什麼方法來區分是否重複呢?使用==仍是用equals?他們有什麼區別?

Set是Collection容器的一個子接口,它不容許出現重複元素,固然也只容許有一個null對象。

如何來區分重複與否呢?

     「 用 iterator() 方法來區分重複與否 」,這是在網上流傳的答案,我的認爲這是個錯誤的答案。API中寫的很明白:「set 不包含知足

e1.equals(e2) 的元素對 e1 和 e2 」,因而可知回答使用equals()區分更合適。

 

爲何用equals()而不用==來區分?

     應該從它倆的區別談起,==是用來判斷二者是不是同一對象(同一事物),而equals是用來判斷是否引用同一個對象。再看一下Set裏面存的是

對象,仍是對象的引用。根據java的存儲機制可知,set裏面存放的是對象的引用,因此當兩個元素只要知足了equals()時就已經指向同一個對象,

也就出現了重複元素。因此應該用equals()來判斷。

 

 

十二、寫一個方法,計算菲波那切數列(1,1,2,3,5,8,...)第100項的值,方法  參數爲第N項,返回值爲第N項的值(考慮程序運行效率、異常處理)。

 

第一百項的值:354224848179261915075

public static BigDecimal getNum(Integer n){

      boolean flag=true;//聲明一個標識符

      List<BigDecimal> lists = new ArrayList<BigDecimal>();//聲明一個集合存儲斐波那契數列的值

      try {

        for(int i=1;i<=n;i++){

           if (i<=2) {//斐波那契數列前兩項值

              lists.add(new BigDecimal(1));

           }else{//大於兩項後的值計算

              lists.add((lists.get(i-3).add(lists.get(i-2))));

           }

        }

        for (BigDecimal bigDecimal : lists) {//便利斐波那契數列

           System.out.println(bigDecimal);

        }

       

      } catch (Exception e) {

        flag=false;

        System.err.print("出錯了");

        e.printStackTrace();

      }

      if (flag) {

        return lists.get(n-1);//返回第n象的值

      }else{

        return new BigDecimal(0);

      }

 

1三、談談你對java.math.BigDecimal類的認識。

java.math.BigDecimal 類提供用於算術,刻度操做,舍入,比較,哈希算法和格式轉換操做。

對於不須要任何準確計算精度的數字能夠直接使用float或double,可是若是須要精確計算的結果,則必須使用BigDecimal類,並且使用BigDecimal類也能夠進行大數的操做。

BigDecimal是Java中用來表示任意精確浮點數運算的類,在BigDecimal中,使用unscaledValue × 10-scale來表示一個浮點數。其中,unscaledValue是一個BigInteger,scale是一個int。從這個表示方法來看,BigDecimal只能標識有限小數,不過能夠表示的數據範圍遠遠大於double,在實際應用中基本足夠了。

toString()方法提供BigDecimal的規範表示。它使用戶能夠徹底控制舍入行爲。

提供用於操做BigDecimal規模兩種類型的操做:

縮放/舍入操做

小數點移動操做。

此類及其迭代器實現Comparable接口的全部可選方法。

 

1四、Java進程間通訊的方式有哪些。

1)管道(Pipe):管道可用於具備親緣關係進程間的通訊,容許一個進程和另外一個與它有共同祖先的進程之間進行通訊。

2)命名管道(named pipe):命名管道克服了管道沒有名字的限制,所以,除具備管道所具備的功能外,它還容許無親緣關 系 進程間的通訊。命名管道在文件系統中有對應的文件名。命名管道經過命令mkfifo或系統調用mkfifo來建立。

3)信號(Signal):信號是比較複雜的通訊方式,用於通知接受進程有某種事件發生,除了用於進程間通訊外,進程還能夠發送 信號給進程自己;linux除了支持Unix早期信號語義函數sigal外,還支持語義符合Posix.1標準的信號函數sigaction(實際上,該函數是基於BSD的,BSD爲了實現可靠信號機制,又可以統一對外接口,用sigaction函數從新實現了signal函數)。

4)消息(Message)隊列:消息隊列是消息的連接表,包括Posix消息隊列system V消息隊列。有足夠權限的進程能夠向隊列中添加消息,被賦予讀權限的進程則能夠讀走隊列中的消息。消息隊列克服了信號承載信息量少,管道只能承載無格式字節流以及緩衝區大小受限等缺

5)共享內存:使得多個進程能夠訪問同一塊內存空間,是最快的可用IPC形式。是針對其餘通訊機制運行效率較低而設計的。每每與其它通訊機制,如信號量結合使用,來達到進程間的同步及互斥。

6)內存映射(mapped memory):內存映射容許任何多個進程間通訊,每個使用該機制的進程經過把一個共享的文件映射到本身的進程地址空間來實現它。

7)信號量(semaphore):主要做爲進程間以及同一進程不一樣線程之間的同步手段。

8)套接口(Socket):更爲通常的進程間通訊機制,可用於不一樣機器之間的進程間通訊。起初是由Unix系統的BSD分支開發出來的,但如今通常能夠移植到其它類Unix系統上:Linux和System V的變種都支持套接字。

 

 

1五、CSS規則style=」padding:0 0 3px 3px」設置的元素內邊距分別是多少。

上:0px 右:0px 下:3px 左3px

 

1六、說出HTTP請求的GET和POST方式的區別。

(一)、原理區別

通常咱們在瀏覽器輸入一個網址訪問網站都是GET請求;再FORM表單中,能夠經過設置Method指定提交方式爲GET或者POST提交方式,默認爲GET提交方式。

 

HTTP定義了與服務器交互的不一樣方法,其中最基本的四種:GET,POST,PUT,DELETE,HEAD,其中GET和HEAD被稱爲安全方法,由於使用GET和HEAD的HTTP請求不會產生什麼動做。不會產生動做意味着GET和HEAD的HTTP請求不會在服務器上產生任何結果。可是安全方法並非什麼動做都不產生,這裏的安全方法僅僅指不會修改信息。

 

根據HTTP規範,POST可能會修改服務器上的資源的請求。好比CSDN的博客,用戶提交一篇文章或者一個讀者提交評論是經過POST請求來實現的,由於再提交文章或者評論提交後資源(即某個頁面)不一樣了,或者說資源被修改了,這些即是「不安全方法」。

 

(二)、表現形式區別

HTTP請求中,奇異行必須是一個請求行,包括請求方法,請求URL,報文所用HTTP版本信息。緊接着是一個herders小節,能夠有零個或一個首部,用來講明服務器要使用的附加信息。在首部以後就是一個空行,最後就是報文實體的主體部分,包含一個由任意數據組成的數據塊。可是並非全部的報文都包含實體的主體部分。

 

請求方式的區別:

1)、GET請求,請求的數據會附加在URL以後,以?分割URL和傳輸數據,多個參數用&鏈接。URL的編碼格式採用的是ASCII編碼,而不是uniclde,便是說全部的非ASCII字符都要編碼以後再傳輸。

 

POST請求:POST請求會把請求的數據放置在HTTP請求包的包體中。上面的item=bandsaw就是實際的傳輸數據。

 

所以,GET請求的數據會暴露在地址欄中,而POST請求則不會。

 

2)、傳輸數據的大小

 

HTTP規範中,沒有對URL的長度和傳輸的數據大小進行限制。可是在實際開發過程當中,對於GET,特定的瀏覽器和服務器對URL的長度有限制。所以,在使用GET請求時,傳輸數據會受到URL長度的限制。

 

對於POST,因爲不是URL傳值,理論上是不會受限制的,可是實際上各個服務器會規定對POST提交數據大小進行限制,Apache、IIS都有各自的配置。

 

3)、安全性

 

POST的安全性比GET的高。這裏的安全是指真正的安全,而不一樣於上面GET提到的安全方法中的安全,上面提到的安全僅僅是不修改服務器的數據。好比,在進行登陸操做,經過GET請求,用戶名和密碼都會暴露再URL上,由於登陸頁面有可能被瀏覽器緩存以及其餘人查看瀏覽器的歷史記錄的緣由,此時的用戶名和密碼就很容易被他人拿到了。除此以外,GET請求提交的數據還可能會形成Cross-site request frogery攻擊

 

4)、HTTP中的GET,POST,SOAP協議都是在HTTP上運行的

 

1七、Servlet的forword和redirect的區別。

使用forward的時候瀏覽器不知道它所請求的具體資源來源,因此地址欄不會變;  

使用redirect,服務端根據邏輯,發送一個狀態碼,告訴瀏覽器從新去請求那個地址。因此地址欄顯示的是新的URL。  

forward,轉發頁面和轉發到的頁面能夠共享request裏面的數據.redirect,不能共享數據。

 

1八、寫一段JDBC查詢oracle數據的代碼。

package test;

 import java.sql.Connection;

 import java.sql.DriverManager;

 import java.sql.ResultSet;

 import java.sql.SQLException;

 import java.sql.Statement;

 public class JDBCDemo {

     public static void main(String[] args){

         Connection conn = null;

         ResultSet rs = null;

         try {

             //加載驅動

             Clas敏感詞orName("oracle.jdbc.OracleDriver");

             //得到鏈接

             conn = DriverManager.getConnection(

                 "jdbc:oracle:thin:@localhost:1521:orcl",

                 "scott",

                 "tiger");

             Statement stat = conn.createStatement();

             //sql語句

             String sql = "SELECT * FROM emp";

             //執行語句得到結果集

             rs = stat.executeQuery(sql);

             //遍歷結果集

             while(rs.next()){

                 String name = rs.getString("name");

                 System.out.println(name);

             }

         } catch (Exception e) {

             e.printStackTrace();

         } finally {

             //關閉鏈接

             try {

                 conn.close();

             } catch (SQLException e) {

                 // TODO Auto-generated catch block

                 e.printStackTrace();

             }

         }

     }

 }

 

1九、JDBC中PreparedStatement相比Statement的好處。

1)極大提升了安全性能,能夠防止sql注入

 

2)代碼的可讀性和可維護性相比Statement要好.

 

3)有預編譯功能,相同操做批量數據效率較高

 

由於預編譯語句有可能被重複調用.因此語句在被DB的編譯器編譯後的執行代碼被緩存下來,那麼下次調用時只要是相同的預編譯語句就不須要編譯,只要將參數直接傳入編譯過的語句執行代碼中就會獲得執行

相關文章
相關標籤/搜索