Java基礎部分6

技術小牛人發表於2017-11-23

介紹Collection框架的結構

答:隨意發揮題,天南海北誰便談,只要讓別覺得你知識淵博,理解透徹即可。

 

3Collection框架中實現比較要實現什麼介面

comparable/comparator

3ArrayListVector的區別

答:

這兩個類都實現了List介面(List介面繼承了Collection介面),他們都是有序集合,即儲存在這兩個集合中的元素的位置都是有順序的,相當於一種動態的陣列,我們以後可以按位置索引號取出某個元素,,並且其中的資料是允許重複的,這是HashSet之類的集合的最大不同處,HashSet之類的集合不可以按索引號去檢索其中的元素,也不允許有重複的元素(本來題目問的與hashset沒有任何關係,但為了說清楚ArrayListVector的功能,我們使用對比方式,更有利於說明問題)。

 

接著才說ArrayListVector的區別,這主要包括兩個方面:
1)同步性:

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

 

備註:對於Vector&ArrayListHashtable&HashMap,要記住執行緒安全的問題,記住VectorHashtable是舊的,是java一誕生就提供了的,它們是執行緒安全的,ArrayListHashMapjava2時才提供的,它們是執行緒不安全的。所以,我們講課時先講老的。
2)資料增長:

       ArrayListVector都有一個初始的容量大小,當儲存進它們裡面的元素的個數超過了容量時,就需要增加ArrayListVector的儲存空間,每次要增加儲存空間時,不是隻增加一個儲存單元,而是增加多個儲存單元,每次增加的儲存單元的個數在記憶體空間利用與程式效率之間要取得一定的平衡。Vector預設增長為原來兩倍,而ArrayList的增長策略在文件中沒有明確規定(從原始碼看到的是增長為原來的1.5倍)。ArrayListVector都可以設定初始的空間大小,Vector還可以設定增長的空間大小,而ArrayList沒有提供設定增長空間的方法。

    總結:即Vector增長原來的一倍,ArrayList增加原來的0.5倍。

4HashMapHashtable的區別

(條理上還需要整理,也是先說相同點,再說不同點)

HashMapHashtable的輕量級實現(非執行緒安全的實現),他們都完成了Map介面,主要區別在於HashMap允許空(null)鍵值(key,由於非執行緒安全,在只有一個執行緒訪問的情況下,效率要高於Hashtable

HashMap允許將null作為一個entrykey或者value,而Hashtable不允許。

HashMapHashtablecontains方法去掉了,改成containsvaluecontainsKey。因為contains方法容易讓人引起誤解。

Hashtable繼承自Dictionary類,而HashMapJava1.2引進的Map interface的一個實現。

最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是,在多個執行緒訪問Hashtable時,不需要自己為它的方法實現同步,而HashMap 就必須為之提供外同步。

HashtableHashMap採用的hash/rehash演算法都大概一樣,所以效能不會有很大的差異。

 

HashMapHashTable主要從三方面來說。 
.歷史原因:Hashtable是基於陳舊的Dictionary類的,HashMapJava 1.2引進的Map介面的一個實現 
.同步性:Hashtable是執行緒安全的,也就是說是同步的,而HashMap是執行緒序不安全的,不是同步的 
.值:只有HashMap可以讓你將空值作為一個表的條目的keyvalue

5List  Map 區別?

一個是儲存單列資料的集合,另一個是儲存鍵和值這樣的雙列資料的集合,List中儲存的資料是有順序,並且允許重複;Map中儲存的資料是沒有順序的,其鍵是不能重複的,它的值是可以有重複的。

35List, Set, Map是否繼承自Collection介面?

  ListSet是,Map不是

 

109ListMapSet三個介面,存取元素時,各有什麼特點?

這樣的題屬於隨意發揮題:這樣的題比較考水平,兩個方面的水平:一是要真正明白這些內容,二是要有較強的總結和表述能力。如果你明白,但表述不清楚,在別人那裡則等同於不明白。

 

首先,ListSet具有相似性,它們都是單列元素的集合,所以,它們有一個功共同的父介面,叫CollectionSet裡面不允許有重複的元素,所謂重複,即不能有兩個相等(注意,不是僅僅是相同)的物件,即假設Set集合中有了一個A物件,現在我要向Set集合再存入一個B物件,但B物件與A物件equals相等,則B物件儲存不進去,所以,Set集合的add方法有一個boolean的返回值,當集合中沒有某個元素,此時add方法可成功加入該元素時,則返回true,當集合含有與某個元素equals相等的元素時,此時add方法無法加入該元素,返回結果為falseSet取元素時,沒法說取第幾個,只能以Iterator介面取得所有的元素,再逐一遍歷各個元素。

       List表示有先後順序的集合, 注意,不是那種按年齡、按大小、按價格之類的排序。當我們多次呼叫add(Obj e)方法時,每次加入的物件就像火車站買票有排隊順序一樣,按先來後到的順序排序。有時候,也可以插隊,即呼叫add(int index,Obj e)方法,就可以指定當前物件在集合中的存放位置。一個物件可以被反覆儲存進List中,每呼叫一次add方法,這個物件就被插入進集合中一次,其實,並不是把這個物件本身儲存進了集合中,而是在集合中用一個索引變數指向這個物件,當這個物件被add多次時,即相當於集合中有多個索引指向了這個物件,如圖x所示。List除了可以以Iterator介面取得所有的元素,再逐一遍歷各個元素之外,還可以呼叫get(indexi)來明確說明取第幾個。

       MapListSet不同,它是雙列的集合,其中有put方法,定義如下:put(obj key,obj value),每次儲存時,要儲存一對key/value,不能儲存重複的key,這個重複的規則也是按equals比較相等。取則可以根據key獲得相應的value,即get(Object key)返回值為key 所對應的value。另外,也可以獲得所有的key的結合,還可以獲得所有的value的結合,還可以獲得keyvalue組合成的Map.Entry物件的集合。

 

List 以特定次序來持有元素,可有重複元素。Set 無法擁有重複元素,內部排序。Map 儲存key-value值,value可多值。

 

 

HashSet按照hashcode值的某種運算方式進行儲存,而不是直接按hashCode值的大小進行儲存。例如,“abc” —> 78“def” —> 62“xyz” —> 65hashSet中的儲存順序不是62,65,78,這些問題感謝以前一個叫崔健的學員提出,最後通過檢視原始碼給他解釋清楚,看本次培訓學員當中有多少能看懂原始碼。LinkedHashSet按插入的順序儲存,那被儲存物件的hashcode方法還有什麼作用呢?學員想想!hashset集合比較兩個物件是否相等,首先看hashcode方法是否相等,然後看equals方法是否相等。new 兩個Student插入到HashSet中,看HashSetsize,實現hashcodeequals方法後再看size

 

同一個物件可以在Vector中加入多次。往集合裡面加元素,相當於集合裡用一根繩子連線到了目標物件。往HashSet中卻加不了多次的。

 

7、說出ArrayList,Vector, LinkedList的儲存效能和特性

ArrayListVector都是使用陣列方式儲存資料,此陣列元素數大於實際儲存的資料以便增加和插入元素,它們都允許直接按序號索引元素,但是插入元素要涉及陣列元素移動等記憶體操作,所以索引資料快而插入資料慢,Vector由於使用了synchronized方法(執行緒安全),通常效能上較ArrayList差,而LinkedList使用雙向連結串列實現儲存,按序號索引資料需要進行前向或後向遍歷,但是插入資料時只需要記錄本項的前後項即可,所以插入速度較快。

 

LinkedList也是執行緒不安全的,LinkedList提供了一些方法,使得LinkedList可以被當作堆疊和佇列來使用。

4、去掉一個Vector集合中重複的元素

Vector newVector = new Vector();

For (int i=0;i<vector.size();i++)

{

Object obj = vector.get(i);

       if(!newVector.contains(obj);

              newVector.add(obj);

}

還有一種簡單的方式,HashSetset = new HashSet(vector);

9Collection  Collections的區別。

Collection是集合類的上級介面,繼承與他的介面主要有Set List.

Collections是針對集合類的一個幫助類,他提供一系列靜態方法實現對各種集合的搜尋、排序、執行緒安全化等操作。

39Set裡的元素是不能重複的,那麼用什麼方法來區分重複與否呢是用==還是equals()? 它們有何區別?

Set裡的元素是不能重複的,元素重複與否是使用equals()方法進行判斷的。

  equals()==方法決定引用值是否指向同一物件equals()在類中被覆蓋,為的是當兩個分離的物件的內容和型別相配的話,返回真值。

 

53、你所知道的集合類都有哪些?主要方法?

最常用的集合類是 List  Map List 的具體實現包括ArrayList  Vector,它們是可變大小的列表,比較適合構建、儲存和操作任何型別物件的元素列表。 List 適用於按數值索引訪問元素的情形。

Map 提供了一個更通用的元素儲存方法。 Map 集合類用於儲存元素對(稱作),其中每個鍵對映到一個值。

 

ArrayList/VectoràList

                    àCollection

HashSet/TreeSetàSet

 

PropetiesàHashTable

                                   àMap

       Treemap/HashMap

 

我記的不是方法名,而是思想,我知道它們都有增刪改查的方法,但這些方法的具體名稱,我記得不是很清楚,對於set,大概的方法是add,remove,contains;對於map,大概的方法就是put,removecontains等,因為,我只要在eclispe下按點操作符,很自然的這些方法就出來了。我記住的一些思想就是List類會有get(int index)這樣的方法,因為它可以按順序取元素,而set類中沒有get(int index)這樣的方法。Listset都可以迭代出所有元素,迭代時先要得到一個iterator物件,所以,setlist類都有一個iterator方法,用於返回那個iterator物件。map可以返回三個集合,一個是返回所有的key的集合,另外一個返回的是所有value的集合,再一個返回的keyvalue組合成的EntrySet物件的集合,map也有get方法,引數是key,返回值是key對應的value

 

45、兩個物件值相同(x.equals(y) == true),但卻可有不同的hash code,這句話對不對?

對。

如果物件要儲存在HashSetHashMap中,它們的equals相等,那麼,它們的hashcode值就必須相等。

如果不是要儲存在HashSetHashMap,則與hashcode沒有什麼關係了,這時候hashcode不等是可以的,例如arrayList儲存的物件就不用實現hashcode,當然,我們沒有理由不實現,通常都會去實現的。

TreeSet裡面放物件,如果同時放入了父類和子類的例項物件,那比較時使用的是父類的compareTo方法,還是使用的子類的compareTo方法,還是拋異常!

(應該是沒有針對問題的確切的答案,當前的add方法放入的是哪個物件,就呼叫哪個物件的compareTo方法,至於這個compareTo方法怎麼做,就看當前這個物件的類中是如何編寫這個方法的)

實驗程式碼:

publicclass Parent implements Comparable {

    privateintage = 0;

    public Parent(int age){

       this.age = age;

    }

    publicint compareTo(Object o) {

       // TODO Auto-generatedmethod stub

       System.out.println(“method ofparent”);

       Parent o1 = (Parent)o;

       returnage>o1.age?1:age<o1.age?-1:0;

    }

 

}

 

publicclass Child extends Parent {

 

    public Child(){

       super(3);

    }

    publicint compareTo(Object o) {

 

           // TODO Auto-generatedmethod stub

           System.out.println(“method ofchild”);

//         Child o1 = (Child)o;

           return 1;

 

    }

}

 

publicclass TreeSetTest {

 

    /**

     *@paramargs

     */

    publicstaticvoid main(String[] args) {

       // TODO Auto-generatedmethod stub

       TreeSet set = new TreeSet();

       set.add(new Parent(3));

       set.add(new Child());

       set.add(new Parent(4));

       System.out.println(set.size());

    }

 

}

 

 

112、說出一些常用的類,包,介面,請各舉5

要讓人家感覺你對java ee開發很熟,所以,不能僅僅只列core java中的那些東西,要多列你在做ssh專案中涉及的那些東西。就寫你最近寫的那些程式中涉及的那些類。

 

常用的類:BufferedReader  BufferedWriter  FileReader FileWirter  String  Integer

java.util.DateSystemClassList,HashMap

 

常用的包:java.lang   java.io java.util  java.sql,javax.servlet,org.apache.strtuts.action,org.hibernate

常用的介面:Remote  List Map  Document  NodeList,Servlet,HttpServletRequest,HttpServletResponse,Transaction(Hibernate)Session(Hibernate),HttpSession

100java中有幾種型別的流?JDK為每種型別的流提供了一些抽象類以供繼承,請說出他們分別是哪些類?

位元組流,字元流。位元組流繼承於InputStreamOutputStream,字元流繼承於InputStreamReaderOutputStreamWriter。在java.io包中還有許多其他的流,主要是為了提高效能和使用方便。

102、位元組流與字元流的區別

       要把一片二進位制資料資料逐一輸出到某個裝置中,或者從某個裝置中逐一讀取一片二進位制資料,不管輸入輸出裝置是什麼,我們要用統一的方式來完成這些操作,用一種抽象的方式進行描述,這個抽象描述方式起名為IO流,對應的抽象類為OutputStreamInputStream ,不同的實現類就代表不同的輸入和輸出裝置,它們都是針對位元組進行操作的。

       在應用中,經常要完全是字元的一段文字輸出去或讀進來,用位元組流可以嗎?計算機中的一切最終都是二進位制的位元組形式存在。對於“中國”這些字元,首先要得到其對應的位元組,然後將位元組寫入到輸出流。讀取時,首先讀到的是位元組,可是我們要把它顯示為字元,我們需要將位元組轉換成字元。由於這樣的需求很廣泛,人家專門提供了字元流的包裝類。

  底層裝置永遠只接受位元組資料,有時候要寫字串到底層裝置,需要將字串轉成位元組再進行寫入。字元流是位元組流的包裝,字元流則是直接接受字串,它內部將串轉成位元組,再寫入底層裝置,這為我們向IO設別寫入或讀取字串提供了一點點方便。

  字元向位元組轉換時,要注意編碼的問題,因為字串轉成位元組陣列,

  其實是轉成該字元的某種編碼的位元組形式,讀取也是反之的道理。

 

講解位元組流與字元流關係的程式碼案例:

import java.io.BufferedReader;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.FileReader;

import java.io.FileWriter;

import java.io.InputStreamReader;

import java.io.PrintWriter;

 

public class IOTest {

   publicstatic void main(String[] args) throws Exception {

        Stringstr = “中國人“;

        /*FileOutputStreamfos  = newFileOutputStream(“1.txt”);

       

        fos.write(str.getBytes(“UTF-8”));

        fos.close();*/

       

        /*FileWriterfw = new FileWriter(“1.txt”);

        fw.write(str);

        fw.close();*/

        PrintWriterpw = new PrintWriter(“1.txt”,”utf-8″);

        pw.write(str);

        pw.close();

       

        /*FileReaderfr = new FileReader(“1.txt”);

        char[]buf = new char[1024];

        intlen = fr.read(buf);

        StringmyStr = new String(buf,0,len);

        System.out.println(myStr);*/

        /*FileInputStreamfr = new FileInputStream(“1.txt”);

        byte[]buf = new byte[1024];

        intlen = fr.read(buf);

        StringmyStr = new String(buf,0,len,”UTF-8″);

        System.out.println(myStr);*/

        BufferedReaderbr = new BufferedReader(

                      newInputStreamReader(

                             newFileInputStream(“1.txt”),”UTF-8″

                             )

                      );

        StringmyStr = br.readLine();

        br.close();

        System.out.println(myStr);

   }

 

}

105、什麼是java序列化,如何實現java序列化?或者請解釋Serializable介面的作用。

 

我們有時候將一個java物件變成位元組流的形式傳出去或者從一個位元組流中恢復成一個java物件,例如,要將java物件儲存到硬碟或者傳送給網路上的其他計算機,這個過程我們可以自己寫程式碼去把一個java物件變成某個格式的位元組流再傳輸,但是,jre本身就提供了這種支援,我們可以呼叫OutputStreamwriteObject方法來做,如果要讓java 幫我們做,要被傳輸的物件必須實現serializable介面,這樣,javac編譯時就會進行特殊處理,編譯的類才可以被writeObject方法操作,這就是所謂的序列化。需要被序列化的類必須實現Serializable介面,該介面是一個mini介面,其中沒有需要實現的方法,implements Serializable只是為了標註該物件是可被序列化的。

 

 

例如,在web開發中,如果物件被儲存在了Session中,tomcat在重啟時要把Session物件序列化到硬碟,這個物件就必須實現Serializable介面。如果物件要經過分散式系統進行網路傳輸或通過rmi等遠端呼叫,這就需要在網路上傳輸物件,被傳輸的物件就必須實現Serializable介面。

 

54、描述一下JVM載入class檔案的原理機制?

JVM中類的裝載是由ClassLoader和它的子類來實現的,Java ClassLoader 是一個重要的Java執行時系統元件。它負責在執行時查詢和裝入類檔案的類。

 

18heapstack有什麼區別。

java的記憶體分為兩類,一類是棧記憶體,一類是堆記憶體。棧記憶體是指程式進入一個方法時,會為這個方法單獨分配一塊私屬儲存空間,用於儲存這個方法內部的區域性變數,當這個方法結束時,分配給這個方法的棧會釋放,這個棧中的變數也將隨之釋放。

堆是與棧作用不同的記憶體,一般用於存放不放在當前方法棧中的那些資料,例如,使用new建立的物件都放在堆裡,所以,它不會隨方法的結束而消失。方法中的區域性變數使用final修飾後,放在堆中,而不是棧中。

 

24GC是什麼為什麼要有GC?

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

 

本文轉自  素顏豬  51CTO部落格,原文連結:http://blog.51cto.com/suyanzhu/1561389


相關文章