中軟國(guó)際Java程序員筆試題


作者:xcbeyond
瘋狂源自夢(mèng)想,技術(shù)成就輝煌!微信公眾號(hào):《程序猿技術(shù)大咖》號(hào)主,專注后端開發(fā)多年,擁有豐富的研發(fā)經(jīng)驗(yàn),樂于技術(shù)輸出、分享,現(xiàn)階段從事微服務(wù)架構(gòu)項(xiàng)目的研發(fā)工作,涉及架構(gòu)設(shè)計(jì)、技術(shù)選型、業(yè)務(wù)研發(fā)等工作。對(duì)于Java、微服務(wù)、數(shù)據(jù)庫、Docker有深入了解,并有大量的調(diào)優(yōu)經(jīng)驗(yàn)。 






   

  1、談?wù)刦inal, finally, finalize的區(qū)別。

     final:修飾符(關(guān)鍵字)如果一個(gè)類被聲明為final,意味著它不能再派生出新的子類,不能作為父類被繼承。因此一個(gè)類不能既被聲明為 abstract的,又被聲明為final的。將變量或方法聲明為final,可以保證它們?cè)谑褂弥胁槐桓淖?。被聲明為final的變量必須在聲明時(shí)給定初值,而在以后的引用中只能讀取,不可修改。被聲明為final的方法也同樣只能使用,不能重載。

      finally:在異常處理時(shí)提供 finally 塊來執(zhí)行任何清除操作。如果拋出一個(gè)異常,那么相匹配的 catch 子句就會(huì)執(zhí)行,然后控制就會(huì)進(jìn)入 finally 塊(如果有的話)。

      finalize:方法名。Java 技術(shù)允許使用 finalize() 方法在垃圾收集器將對(duì)象從內(nèi)存中清除出去之前做必要的清理工作。這個(gè)方法是由垃圾收集器在確定這個(gè)對(duì)象沒有被引用時(shí)對(duì)這個(gè)對(duì)象調(diào)用的。它是在 Object 類中定義的,因此所有的類都繼承了它。子類覆蓋 finalize() 方法以整理系統(tǒng)資源或者執(zhí)行其他清理工作。finalize() 方法是在垃圾收集器刪除對(duì)象之前對(duì)這個(gè)對(duì)象調(diào)用的。

2、Anonymous Inner Class (匿名內(nèi)部類) 是否可以extends(繼承)其它類,是否可以implements(實(shí)現(xiàn))interface(接口)?

       匿名的內(nèi)部類是沒有名字的內(nèi)部類。不能繼承其它類,但一個(gè)內(nèi)部類可以作為一個(gè)接口,由另一個(gè)內(nèi)部類實(shí)現(xiàn)。
3、Static Nested Class 和 Inner Class的不同,說得越多越好(面試題有的很籠統(tǒng))。

        Static nested class(嵌套類)是將內(nèi)部類聲明為static。普通內(nèi)部類對(duì)象隱式地保存了一個(gè)引用,指向創(chuàng)建它的外圍類對(duì)象,不能有static數(shù)據(jù)和static字段。嵌套類意味著:1> 要?jiǎng)?chuàng)建嵌套類的對(duì)象,并不需要其外圍類的對(duì)象;2>不能從嵌套類的對(duì)象中訪問非靜態(tài)的外圍類的對(duì)象。

4、&和&&的區(qū)別。
       & 是兩個(gè)數(shù)相與,是位運(yùn)算符
      &&是布爾邏輯運(yùn)算符,連接兩個(gè)條件表達(dá)式的,兩個(gè)條件表達(dá)式都為真時(shí),整個(gè)才為真
5、HashMap和Hashtable的區(qū)別。

   都屬于Map接口的類,實(shí)現(xiàn)了將惟一鍵映射到特定的值上。HashMap 類沒有分類或者排序。它允許一個(gè) null 鍵和多個(gè) null 值。Hashtable 類似于 HashMap,但是不允許 null 鍵和 null 值。它也比 HashMap 慢,因?yàn)樗峭降?,是線程安全的。

6、Collection 和 Collections的區(qū)別。

     Collections是個(gè)java.util下的類,它包含有各種有關(guān)集合操作的靜態(tài)方法。

     Collection是個(gè)java.util下的接口,它是各種集合結(jié)構(gòu)的父接口。

7、List, Set, Map是否繼承自Collection接口?

      List,Set是  Map不是

8、ArrayList和Vector的區(qū)別。

.    1>同步性:Vector是線程安全的,也就是說是同步的,而ArrayList是線程序不安全的,不是同步的 2>數(shù)據(jù)增長(zhǎng):當(dāng)需要增長(zhǎng)時(shí),Vector默認(rèn)增長(zhǎng)為原來一培,而ArrayList卻是原來的一半
9、什么時(shí)候用assert。
       assertion(斷言)在軟件開發(fā)中是一種常用的調(diào)試方式,很多開發(fā)語言中都支持這種機(jī)制。在實(shí)現(xiàn)中,assertion就是在程序中的一條語句,它對(duì)一個(gè)boolean表達(dá)式進(jìn)行檢查,一個(gè)正確程序必須保證這個(gè)boolean表達(dá)式的值為true;如果該值為false,說明程序已經(jīng)處于不正確的狀態(tài)下,系統(tǒng)將給出警告或退出。一般來說,assertion用于保證程序最基本、關(guān)鍵的正確性。assertion檢查通常在開發(fā)和測(cè)試時(shí)開啟。為了提高性能,在軟件發(fā)布后,assertion檢查通常是關(guān)閉的。
10、GC是什么? 為什么要有GC?
       GC是垃圾收集器。Java 程序員不用擔(dān)心內(nèi)存管理,因?yàn)槔占鲿?huì)自動(dòng)進(jìn)行管理。要請(qǐng)求垃圾收集,可以調(diào)用下面的方法之一:

                      System.gc()

                      Runtime.getRuntime().gc()
11、String s = new String("xyz");創(chuàng)建了幾個(gè)String Object?
     兩個(gè)對(duì)象,一個(gè)是“xyx”,一個(gè)是指向“xyx”的引用對(duì)象s
12、.Math.round(11.5)等於多少? Math.round(-11.5)等於多少?

         Math.round(11.5)返回(long)12,Math.round(-11.5)返回(long)-11;因?yàn)榉祷刈罱咏鼌?shù)的 long。通過加上 1/2 將該結(jié)果舍入為整數(shù),取結(jié)果的基數(shù)并將其強(qiáng)制轉(zhuǎn)換為 long 類型。換句話說,結(jié)果等于以下表達(dá)式的值: (long)Math.floor(a + 0.5d)
13、short s1 = 1; s1 = s1 + 1;有什么錯(cuò)? short s1 = 1; s1 += 1;有什么錯(cuò)?

        short s1 = 1; s1 = s1 + 1;錯(cuò), short s1 = 1; s1 += 1;對(duì)。對(duì)于short s1 = 1; s1 = s1 + 1;由于s1+1運(yùn)算時(shí)會(huì)自動(dòng)提升表達(dá)式的類型,所以結(jié)果是int型,再賦值給short類型s1時(shí),編譯器將報(bào)告需要強(qiáng)制轉(zhuǎn)換類型的錯(cuò)誤。對(duì)于short s1 = 1; s1 += 1;由于 += 是java語言規(guī)定的運(yùn)算符,java編譯器會(huì)對(duì)它進(jìn)行特殊處理,因此可以正確編譯。

14、sleep() 和 wait() 有什么區(qū)別?

        sleep是線程類(Thread)的方法,導(dǎo)致此線程暫停執(zhí)行指定時(shí)間,給執(zhí)行機(jī)會(huì)給其他線程,但是監(jiān)控狀態(tài)依然保持,到時(shí)后會(huì)自動(dòng)恢復(fù)。調(diào)用sleep不會(huì)釋放對(duì)象鎖。wait是Object類的方法,對(duì)此對(duì)象調(diào)用wait方法導(dǎo)致本線程放棄對(duì)象鎖,進(jìn)入等待此對(duì)象的等待鎖定池,只有針對(duì)此對(duì)象發(fā)出notify方法(或notifyAll)后本線程才進(jìn)入對(duì)象鎖定池準(zhǔn)備獲得對(duì)象鎖進(jìn)入運(yùn)行狀態(tài)。

15、數(shù)組有沒有l(wèi)ength()這個(gè)方法? String有沒有l(wèi)ength()這個(gè)方法?
         數(shù)組沒有l(wèi)ength()這個(gè)方法,有l(wèi)ength的屬性。String有有l(wèi)ength()這個(gè)方法。
16、是否可以繼承String類?
         String類是final類故不可以繼承。

17、Overload和Override的區(qū)別。Overloaded的方法是否可以改變返回值的類型?
       overload一般翻譯為重載,表示多個(gè)函數(shù)共用同一個(gè)函數(shù)名,為了保證調(diào)用這些同名函數(shù)時(shí)能正確區(qū)分究竟應(yīng)該調(diào)用的是其中的哪一個(gè),重載的各個(gè)函數(shù)的參數(shù)表(不考慮形參名)必須彼此不同,通常簡(jiǎn)略地說成“不同參數(shù)表”。它對(duì)返回值的類型沒有任何要求,所以你可以隨意為每一個(gè)重載的函數(shù)設(shè)置返回類型,相同也行,不同也行。

        override一般翻譯為覆蓋,表示子類對(duì)從父類繼承來的虛函數(shù)重新定義,它要求參數(shù)表必須跟父類中被覆蓋的那個(gè)函數(shù)的參數(shù)表完全相同,返回值類型原則上也要求相同,但如果返回類型是父類的指針或者父類的引用,覆蓋時(shí)返回類型允許是子類的指針或者子類的引用。
18、Set里的元素是不能重復(fù)的,那么用什么方法來區(qū)分重復(fù)與否呢? 是用==還是equals()? 它們有何區(qū)別?

       Set是Collection容器的一個(gè)子接口,它不允許出現(xiàn)重復(fù)元素,當(dāng)然也只允許有一個(gè)null對(duì)象。 equals()區(qū)分更合適。為什么用equals()而不用==來區(qū)分? 應(yīng)該從它倆的區(qū)別談起,==是用來判斷兩者是否是同一對(duì)象(同一事物),而equals是用來判斷是否引用同一個(gè)對(duì)象。再看一下Set里面存的是對(duì)象,還是對(duì)象的引用。根據(jù)java的存儲(chǔ)機(jī)制可知,set里面存放的是對(duì)象的引用,所以當(dāng)兩個(gè)元素只要滿足了equals()時(shí)就已經(jīng)指向同一個(gè)對(duì)象,也就出現(xiàn)了重復(fù)元素。所以應(yīng)該用equals()來判斷。
19、給我一個(gè)你最常見到的runtime exception。

       ArithmeticException, ArrayStoreException, BufferOverflowException, BufferUnderflowException, CannotRedoException, CannotUndoException, ClassCastException, CMMException, ConcurrentModificationException, DOMException, EmptyStackException, IllegalArgumentException, IllegalMonitorStateException, IllegalPathStateException, IllegalStateException,

ImagingOpException, IndexOutOfBoundsException, MissingResourceException, NegativeArraySizeException, NoSuchElementException, NullPointerException, ProfileDataException, ProviderException, RasterFORMatException, SecurityException, SystemException, UndeclaredThrowableException, UnmodifiableSetException, UnsupportedOperationException
20、error和exception有什么區(qū)別?

        Error(錯(cuò)誤)表示系統(tǒng)級(jí)的錯(cuò)誤和程序不必處理的異常,是java運(yùn)行環(huán)境中的內(nèi)部錯(cuò)誤或者硬件問題,比如,內(nèi)存資源不足等,對(duì)于這種錯(cuò)誤,程序基本無能為力,除了退出運(yùn)行外別無選擇。
        Exception(違例)表示需要捕捉或者需要程序進(jìn)行處理的異常,它處理的是因?yàn)槌绦蛟O(shè)計(jì)的瑕疵而引起的問題或者在外的輸入等引起的一般性問題,是程序必須處理的。
21、abstract class和interface有什么區(qū)別?
1>.相同點(diǎn)
  A. 兩者都是抽象類,都不能實(shí)例化。
  B. interface實(shí)現(xiàn)類及abstrct class的子類都必須要實(shí)現(xiàn)已經(jīng)聲明的抽象方法。

2.> 不同點(diǎn)
  A. interface需要實(shí)現(xiàn),要用implements,而abstract class需要繼承,要用extends。
  B. 一個(gè)類可以實(shí)現(xiàn)多個(gè)interface,但一個(gè)類只能繼承一個(gè)abstract class。
  C. interface強(qiáng)調(diào)特定功能的實(shí)現(xiàn),而abstract class強(qiáng)調(diào)所屬關(guān)系。
  D. 盡管interface實(shí)現(xiàn)類及abstrct class的子類都必須要實(shí)現(xiàn)相應(yīng)的抽象方法,但實(shí)現(xiàn)的形式不同。interface中的每一個(gè)方法都是抽象方法,都只是聲明的(declaration, 沒有方法體),實(shí)現(xiàn)類必須要實(shí)現(xiàn)。而abstract class的子類可以有選擇地實(shí)現(xiàn)。
  這個(gè)選擇有兩點(diǎn)含義:
    一是Abastract class中并非所有的方法都是抽象的,只有那些冠有abstract的方法才是抽象的,子類必須實(shí)現(xiàn)。那些沒有abstract的方法,在Abstrct class中必須定義方法體。
    二是abstract class的子類在繼承它時(shí),對(duì)非抽象方法既可以直接繼承,也可以覆蓋;而對(duì)抽象方法,可以選擇實(shí)現(xiàn),也可以通過再次聲明其方法為抽象的方式,無需實(shí)現(xiàn),留給其子類來實(shí)現(xiàn),但此類必須也聲明為抽象類。既是抽象類,當(dāng)然也不能實(shí)例化。
  E. abstract class是interface與Class的中介。
  interface是完全抽象的,只能聲明方法,而且只能聲明pulic的方法,不能聲明private及protected的方法,不能定義方法體,也不能聲明實(shí)例變量。然而,interface卻可以聲明常量變量,并且在JDK中不難找出這種例子。但將常量變量放在interface中違背了其作為接口的作用而存在的宗旨,也混淆了interface與類的不同價(jià)值。如果的確需要,可以將其放在相應(yīng)的abstract class或Class中。
  abstract class在interface及Class中起到了承上啟下的作用。一方面,abstract class是抽象的,可以聲明抽象方法,以規(guī)范子類必須實(shí)現(xiàn)的功能;另一方面,它又可以定義缺省的方法體,供子類直接使用或覆蓋。另外,它還可以定義自己的實(shí)例變量,以供子類通過繼承來使用。

3>. interface的應(yīng)用場(chǎng)合
  A. 類與類之前需要特定的接口進(jìn)行協(xié)調(diào),而不在乎其如何實(shí)現(xiàn)。
  B. 作為能夠?qū)崿F(xiàn)特定功能的標(biāo)識(shí)存在,也可以是什么接口方法都沒有的純粹標(biāo)識(shí)。
  C. 需要將一組類視為單一的類,而調(diào)用者只通過接口來與這組類發(fā)生聯(lián)系。
  D. 需要實(shí)現(xiàn)特定的多項(xiàng)功能,而這些功能之間可能完全沒有任何聯(lián)系。

4>、abstract class的應(yīng)用場(chǎng)合
  一句話,在既需要統(tǒng)一的接口,又需要實(shí)例變量或缺省的方法的情況下,就可以使用它。最常見的有:
  A. 定義了一組接口,但又不想強(qiáng)迫每個(gè)實(shí)現(xiàn)類都必須實(shí)現(xiàn)所有的接口。可以用abstract class定義一組方法體,甚至可以是空方法體,然后由子類選擇自己所感興趣的方法來覆蓋。
  B. 某些場(chǎng)合下,只靠純粹的接口不能滿足類與類之間的協(xié)調(diào),還必需類中表示狀態(tài)的變量來區(qū)別不同的關(guān)系。abstract的中介作用可以很好地滿足這一點(diǎn)。
  C. 規(guī)范了一組相互協(xié)調(diào)的方法,其中一些方法是共同的,與狀態(tài)無關(guān)的,可以共享的,無需子類分別實(shí)現(xiàn);而另一些方法卻需要各個(gè)子類根據(jù)自己特定的狀態(tài)來實(shí)現(xiàn)特定的功能


22、接口是否可繼承接口? 抽象類是否可實(shí)現(xiàn)(implements)接口? 抽象類是否可繼承實(shí)體類(concrete class)?
      接口可以繼承接口。抽象類可以實(shí)現(xiàn)(implements)接口。抽象類是否可繼承實(shí)體類,但前提是實(shí)體類必須有明確的構(gòu)造函數(shù)。

23、構(gòu)造器Constructor是否可被override?
       構(gòu)造器Constructor不能被繼承,因此不能重寫Overriding,但可以被重載Overloading。
24、.當(dāng)一個(gè)線程進(jìn)入一個(gè)對(duì)象的一個(gè)synchronized方法后,其它線程是否可進(jìn)入此對(duì)象的其它方法?

    不能,一個(gè)對(duì)象的一個(gè)synchronized方法只能由一個(gè)線程訪問。
25、編程題: 寫一個(gè)Singleton出來。

    public class Singleton {
     
      private Singleton(){}
     
      //在自己內(nèi)部定義自己一個(gè)實(shí)例,是不是很奇怪?
     
      //注意這是private 只供內(nèi)部調(diào)用
     
      private static Singleton instance = new Singleton();
     
      //這里提供了一個(gè)供外部訪問本class的靜態(tài)方法,可以直接訪問  
     
      public static Singleton getInstance() {
     
        return instance;   
     
       }
     
    }
     

 

  第二種形式:

    public class Singleton {
     
      private static Singleton instance = null;
     
      public static synchronized Singleton getInstance() {
     
      //這個(gè)方法比上面有所改進(jìn),不用每次都進(jìn)行生成對(duì)象,只是第一次     
     
      //使用時(shí)生成實(shí)例,提高了效率!
     
      if (instance==null)
     
        instance=new Singleton();
     
    return instance;   }
     
    }