面試系列(二)

一、抽象類必須要有抽象方法嗎?

不必須

  1. 抽象類必須有關鍵字abstract來修飾。
  2. 抽象類可以不含有抽象方法
  3. 如果一個類包含抽象方法,則該類必須是抽象類

二、普通類和抽象類有哪些區別?

  1. 普通類中不可含有抽象方法,可以被實例化;
  2. 抽象類,則抽象類中所有的方法自動被認爲是抽象方法,沒有實現過程,不可被實例化;抽象類的子類,除非也是抽象類,否則必須實現該抽象類聲明的方法

三、抽象類能使用 final 修飾嗎?

不能,抽象類是被用於繼承的,final修飾代表不可修改、不可繼承的。

四、接口和抽象類有什麼區別?

他們都不能實例化對象,都可以包含抽象方法,而且抽象方法必須被繼承的類全部實現。

區別:

1、抽象類和接口都不能直接實例化,如果要實例化,抽象類變量必須指向實現所有抽象方法的子類對象,接口變量必須指向實現所有接口方法的類對象。

2、抽象類要被子類繼承,接口要被類實現。

3、接口只能做方法申明,抽象類中可以做方法申明,也可以做方法實現

4、接口裏定義的變量只能是公共的靜態的常量,抽象類中的變量是普通變量。

5、抽象類裏的抽象方法必須全部被子類所實現,如果子類不能全部實現父類抽象方法,那麼該子類只能是抽象類。同樣,一個實現接口的時候,如不能全部實現接口方法,那麼該類也只能爲抽象類。

6、抽象方法只能申明,不能實現,接口是設計的結果 ,抽象類是重構的結果

7、抽象類裏可以沒有抽象方法

8、如果一個類裏有抽象方法,那麼這個類只能是抽象類

9、抽象方法要被實現,所以不能是靜態的,也不能是私有的。

10、接口可繼承接口,並可多繼承接口,但類只能單根繼承。

五、java 中 IO 流分爲幾種?

按照流的流向分,可以分爲輸入流和輸出流;

按照操作單元劃分,可以劃分爲字節流和字符流;

按照流的角色劃分爲節點流和處理流。

Java I0流的40多個類都是從如下4個抽象類基類中派生出來的。

•InputStream/Reader: 所有的輸入流的基類,前者是字節輸入流,後者是字符輸入流。

•OutputStream/Writer: 所有輸出流的基類,前者是字節輸出流,後者是字符輸出流。

字符流和字節流的區別
字符流的由來: 因爲數據編碼的不同,而有了對字符進行高效操作的流對象。本質其實就是基於字節流讀取時,去查了指定的碼錶。 字節流和字符流的區別:
讀寫單位不同:字節流以字節(8bit)爲單位,字符流以字符爲單位,根據碼錶映射字符,一次可能讀多個字節。
處理對象不同:字節流能處理所有類型的數據(如圖片、avi等),而字符流只能處理字符類型的數據。
字節流:一次讀入或讀出是8位二進制。通過字節的形式一個字節一個字節或者字節數組來操作文件中內容,可以操作一切文件。
字符流:一次讀入或讀出是16位二進制。通過單個字符或者是字符數組的形式來操作文件的,存在一定的侷限性,是專門用於對文本文件操作的,默認的版本爲GBK
設備上的數據無論是圖片或者視頻,文字,它們都以二進制存儲的。二進制的最終都是以一個8位爲數據單元進行體現,所以計算機中的最小數據單元就是字節。意味着,字節流可以處理設備上的所有數據,所以字節流一樣可以處理字符數據。

處理流的功能主要體現在以下兩個方面
1.性能的提高

        主要以增加緩衝的方式來提高輸入輸出的效率。

2.操作的便捷

        處理流可能提供了一系列便捷方法來一次輸入和輸出大批量的內容,而不是輸入輸出一個或者多個水滴。

處理流可以嫁接在任何一個流之上,這就允許java採取相同的代碼,透明的方式來訪問不同的輸入/輸出設備的數據流。

通過使用處理流,java程序就不必理會輸入輸出節點是磁盤, 網絡還是其他的輸入輸出設備。程序只要將這些節點流包裝成處理流,就可以使用相同的代碼來讀寫不同輸入輸出設備的數據。

六、BIO、NIO、AIO 有什麼區別?

•BIO (Blocking I/O): 同步阻塞I/O模式,數據的讀取寫入必須阻塞在一個線程內等待其完成。在活動連接數不是特別高(小於單機1000)的情況下,這種模型是比較不錯的,可以讓每一個連接專注於自己的 I/O 並且編程模型簡單,也不用過多考慮系統的過載、限流等問題。線程池本身就是一個天然的漏斗,可以緩衝一些系統處理不了的連接或請求。但是,當面對十萬甚至百萬級連接的時候,傳統的 BIO 模型是無能爲力的。因此,我們需要一種更高效的 I/O 處理模型來應對更高的併發量。

•NIO (New I/O): NIO是一種同步非阻塞的I/O模型,在Java 1.4 中引入了NIO框架,對應 java.nio 包,提供了 Channel , Selector,Buffer等抽象。NIO中的N可以理解爲Non-blocking,不單純是New。它支持面向緩衝的,基於通道的I/O操作方法。NIO提供了與傳統BIO模型中的 Socket 和 ServerSocket 相對應的 SocketChannel 和 ServerSocketChannel 兩種不同的套接字通道實現,兩種通道都支持阻塞和非阻塞兩種模式。阻塞模式使用就像傳統中的支持一樣,比較簡單,但是性能和可靠性都不好;非阻塞模式正好與之相反。對於低負載、低併發的應用程序,可以使用同步阻塞I/O來提升開發速率和更好的維護性;對於高負載、高併發的(網絡)應用,應使用 NIO 的非阻塞模式來開發

•AIO (Asynchronous I/O): AIO 也就是 NIO 2。在 Java 7 中引入了 NIO 的改進版 NIO 2,它是異步非阻塞的IO模型。異步 IO 是基於事件和回調機制實現的,也就是應用操作之後會直接返回,不會堵塞在那裏,當後臺處理完成,操作系統會通知相應的線程進行後續的操作。AIO 是異步IO的縮寫,雖然 NIO 在網絡操作中,提供了非阻塞的方法,但是 NIO 的 IO 行爲還是同步的。對於 NIO 來說,我們的業務線程是在 IO 操作準備好時,得到通知,接着就由這個線程自行進行 IO 操作,IO操作本身是同步的。
 

七、Files的常用方法都有哪些?

創建:
createNewFile()在指定位置創建一個空文件,成功就返回true,如果已存在就不創建,然後返回false。
mkdir()  在指定位置創建一個單級文件夾。
mkdirs()  在指定位置創建一個多級文件夾。
renameTo(File dest)如果目標文件與源文件是在同一個路徑下,那麼renameTo的作用是重命名, 如果目標文件與源文件不是在同一個路徑下,那麼renameTo的作用就是剪切,而且還不能操作文件夾。 

刪除:
delete()  刪除文件或者一個空文件夾,不能刪除非空文件夾,馬上刪除文件,返回一個布爾值。
deleteOnExit()jvm退出時刪除文件或者文件夾,用於刪除臨時文件,無返回值。
 判斷:
exists()  文件或文件夾是否存在。
isFile()  是否是一個文件,如果不存在,則始終爲false。
isDirectory()  是否是一個目錄,如果不存在,則始終爲false。
isHidden()  是否是一個隱藏的文件或是否是隱藏的目錄。
isAbsolute()  測試此抽象路徑名是否爲絕對路徑名。
 獲取:
getName()  獲取文件或文件夾的名稱,不包含上級路徑。
getAbsolutePath()獲取文件的絕對路徑,與文件是否存在沒關係
length()  獲取文件的大小(字節數),如果文件不存在則返回0L,如果是文件夾也返回0L。
getParent()  返回此抽象路徑名父目錄的路徑名字符串;如果此路徑名沒有指定父目錄,則返回null。
lastModified()獲取最後一次被修改的時間。

文件夾相關:
static File[] listRoots()列出所有的根目錄(Window中就是所有系統的盤符)
list()  返回目錄下的文件或者目錄名,包含隱藏文件。對於文件這樣操作會返回null。
listFiles()  返回目錄下的文件或者目錄對象(File類實例),包含隱藏文件。對於文件這樣操作會返回null。
list(FilenameFilter filter)返回指定當前目錄中符合過濾條件的子文件或子目錄。對於文件這樣操作會返回null。
listFiles(FilenameFilter filter)返回指定當前目錄中符合過濾條件的子文件或子目錄。對於文件這樣操作會返回null。

八、java 容器都有哪些?

數組,String,java.util下的集合容器

九、Collection 和 Collections 有什麼區別?

Collections

java.util.Collections,是不屬於java的集合框架的,它是集合類的一個工具類/幫助類此類不能被實例化, 服務於java的Collection框架。

包含有關集合操作的靜態多態方法,實現對各種集合的搜索、排序、線程安全等操作.

Collection

Collection是最基本的集合接口,一個Collection代表一組Object,即Collection的元素。它的直接繼承接口有List,Set和Queue。

十、List、Set、Map 之間的區別是什麼?

 

HashSet基於哈希表實現,有以下特點:

          1.不允許重複

           2.允許值爲null,但是只能有一個

           3.無序的。

           4.沒有索引,所以不包含索引操作的方法

LinkedHashSet跟HashSet一樣都是基於哈希表實現。只不過linkedHashSet在hashSet的基礎上多了一個鏈表,這個鏈表就是用來維護容器中每個元素的順序的。有以下特點:

           1.不允許重複

           2.允許值爲null,但是只能有一個

           3.有序的。

           4.沒有索引,所以不包含索引操作的方法

TreeSet是SortedSet接口的唯一實現類,是基於二叉樹實現的。TreeSet可以確保集合元素處於排序狀態。TreeSet支持兩種排序方式,自然排序 和定製排序,其中自然排序爲默認的排序方式。向TreeSet中加入的應該是同一個類的對象。有以下特點:

           1.不允許重複

           2.不允許null值

           3.沒有索引,所以不包含索引操作的方法

List下各種實現類對比。(這幾個類都是有序的,允許重複的)

ArrayList是基於數組實現的,其特點是查詢快,增刪慢。

        查詢快是因爲數組的空間是連續的,查詢時只要通過首地址和下標很快就能找到元素。

        增刪慢是因爲數組是不能擴容的,一旦增加或者刪除元素,內部操作就是新開闢一個數組把元素copy到新的數組,老的數   組等待被垃圾回收。

 

LinkedList是基於鏈表實現的。相比於ArrayList其特點是查詢慢,增刪快。

查詢慢:因爲鏈表在內存中開闢的空間不一定是連續的(基本上不可能是連續的)所以鏈表實現的方式是每個元素節點都會存放自己的地址,數據以及下一個節點的地址,這樣把所有的元素連接起來。所以當要查詢元素時只能一個一個的往下找,相比於數組的首地址加下標會慢上不少。

Vector也是基於數組實現的,相比於arrayList它是線程安全的。如果不考慮線程安全它,ArrayList性能更優。

Map是雙列集合的超類。也就是鍵值對形式。

HashMap和Hashtable都實現了Map接口,但決定用哪一個之前先要弄清楚它們之間的分別。主要的區別有:線程安全性,同步(synchronization),以及速度。

HashMap幾乎可以等價於Hashtable,除了HashMap是非synchronized的,並可以接受null(HashMap可以接受爲null的鍵值(key)和值(value),而Hashtable則不行)。
HashMap是非synchronized,而Hashtable是synchronized,這意味着Hashtable是線程安全的,多個線程可以共享一個Hashtable;而如果沒有正確的同步的話,多個線程是不能共享HashMap的。Java 5提供了ConcurrentHashMap,它是HashTable的替代,比HashTable的擴展性更好。
另一個區別是HashMap的迭代器(Iterator)是fail-fast迭代器,而Hashtable的enumerator迭代器不是fail-fast的。所以當有其它線程改變了HashMap的結構(增加或者移除元素),將會拋出ConcurrentModificationException,但迭代器本身的remove()方法移除元素則不會拋出ConcurrentModificationException異常。但這並不是一個一定發生的行爲,要看JVM。這條同樣也是Enumeration和Iterator的區別。
由於Hashtable是線程安全的也是synchronized,所以在單線程環境下它比HashMap要慢。如果你不需要同步,只需要單一線程,那麼使用HashMap性能要好過Hashtable。
HashMap不能保證隨着時間的推移Map中的元素次序是不變的。
LinkedHashMap和hashMap的區別在於多維護了一個鏈表,用來存儲每一個元素的順序,就跟HashSet和LinkedHashSet差不多。

HashMap通常比TreeMap快一點(樹和哈希表的數據結構使然),建議多使用HashMap,在需要排序的Map時候才用TreeMap。
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章