【Java】集合+I/O流+多线程の练习题+面试题
一. Collection
Collection 和 Collections的區別
 答:Collection是集合類的上級接口,繼承與他的接口主要有Set 和List.
 Collections是針對集合類的一個幫助類,他提供一系列靜態方法實現對各種集合的搜索、排序、線程安全化等操作
Set里的元素是不能重復的,那么用什么方法來區分重復與否呢? 是用 == 還是equals()? 它們有何區別
 答:Set里的元素是不能重復的,那么用iterator()方法來區分重復與否。equals()是判讀兩個Set是否相等
 equals()和 == 方法決定引用值是否指向同一對象equals()在類中被覆蓋,為的是當兩個分離的對象的內容
 和類型相配的話,返回真值
List, Set, Map是否繼承自Collection接口
 答: List,Set是,Map不是
兩個對象值相同(x.equals(y) == true),但卻可有不同的hash code,這句話對不對
 答:不對,有相同的hash code
說出ArrayList,Vector, LinkedList的存儲性能和特性
 答:ArrayList和Vector都是使用數組方式存儲數據,此數組元素數大于實際存儲的數據以便增加和
 插入元素,它們都允許直接按序號索引元素,但是插入元素要涉及數組元素移動等內存操作,所以
 索引數據快而插入數據慢,Vector由于使用了synchronized方法(線程安全),通常性能上較ArrayList
 差,而LinkedList使用雙向鏈表實現存儲,按序號索引數據需要進行前向或后向遍歷,但是插入數據時
 只需要記錄本項的前后項即可,所以插入速度較快。
HashMap和Hashtable的區別
 答:HashMap是Hashtable的輕量級實現(非線程安全的實現),他們都完成了Map接口,主要區別在于HashMap
 允許空(null)鍵值(key),由于非線程安全,效率上可能高于Hashtable。
 HashMap允許將null作為一個entry的key或者value,而Hashtable不允許。
 HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。因為contains方法容易讓
 人引起誤解。
 Hashtable繼承自Dictionary類,而HashMap是Java1.2引進的Map interface的一個實現。
 最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是,在多個線程訪問Hashtable時,不需要
 自己為它的方法實現同步,而HashMap 就必須為之提供外同步。
 Hashtable和HashMap采用的hash/rehash算法都大概一樣,所以性能不會有很大的差異。
ArrayList和Vector的區別,HashMap和Hashtable的區別
 答:就ArrayList與Vector主要從二方面來說.
 一.同步性:Vector是線程安全的,也就是說是同步的,而ArrayList是線程序不安全的,不是同步的
 二.數據增長:當需要增長時,Vector默認增長為原來一培,而ArrayList卻是原來的一半
 就HashMap與HashTable主要從三方面來說。
 一.歷史原因:Hashtable是基于陳舊的Dictionary類的,HashMap是Java 1.2引進的Map接口的一個實現
 二.同步性:Hashtable是線程安全的,也就是說是同步的,而HashMap是線程序不安全的,不是同步的
 三.值:只有HashMap可以讓你將空值作為一個表的條目的key或value
二. IO Stream
java中有幾種類型的流?JDK為每種類型的流提供了一些抽象類以供繼承,請說出他們分別是哪些類?
 答:字節流,字符流。
 字節流繼承于InputStream OutputStream,
 字符流繼承于Reader Writer。在java.io包中還有許多其他的流,主要是為了提高性能和使用方便。
什么是java序列化,如何實現java序列化?
 答:序列化就是一種用來處理對象流的機制,所謂對象流也就是將對象的內容進行流化。
 可以對流化后的對象進行讀寫操作,也可將流化后的對象傳輸于網絡之間。
 序列化是為了解決在對對象流進行讀寫操作時所引發的問題。
 序列化的實現:將需要被序列化的類實現Serializable接口,該接口沒有需要實現的方法,
 implements Serializable只是為了標注該對象是可被序列化的,然后使用一個輸出流(如:FileOutputStream)來構造
 一個ObjectOutputStream(對象流)對象,接著,使用ObjectOutputStream對象的writeObject(Object obj)方法就可以
 將參數為obj的對象寫出(即保存其狀態),要恢復的話則用輸入流。
在Java中,輸入輸出的處理需要引入的包是java.io,
 面向字節的輸入輸出類的基類是Inputstream和Outputstream。
 面向字符的輸入輸出類的基類是Reader和Writer。
使用處理流的優勢有哪些?如何識別所使用的流是處理流還是節點流?
 【答案】
 【優勢】對開發人員來說,使用處理流進行輸入/輸出操作更簡單;使用處理流的執行效率更高。
 【判別】
 處理流的構造器的參數不是一個物理節點,而是已經存在的流。而節點流都是直接以物理IO及節點作為構造器參數的。
填空:下列程序將從file1.dat文件中讀取全部數據,然后寫到file2.dat文件中。
importjava.io.File; importjava.io.FileInputStream; importjava.io.FileNotFoundException; importjava.io.FileOutputStream; importjava.io.IOException;public class FileStreamInOut {public static void main(String[] args){try{File inFile = new File("_________");File outFile = new File("_________");FileInputStream fis = new FileInputStream(_________);FileOutputStream fos = new FileOutputStream(_________);int c;while((c = fis.read())!=-1){fos.write(c);}_____.close();_____.close();}catch(FileNotFoundException e){System.out.println("FileStreamsTest:"+e);}catch(IOException e){System.out.println("FileStreamTest"+e);}} }Java中有幾種類型的流?JDK為每種類型的流提供了一些抽象類以供繼承,請指出它們分別是哪些類?
 【答案】Java中按所操作的數據單元的不同,分為字節流和字符流。
 字節流繼承于InputStream和OutputStream類,字符流繼承于Reader和Writer。
 按流的流向的不同,分為輸入流和輸出流。
 按流的角色來分,可分為節點流和處理流。緩沖流、轉換流、對象流和打印流等都屬于處理流,使得輸入/輸出更簡單,執行效率更高。
什么是標準的I/O流?
 在java語言中,用stdin表示鍵盤,用stdout表示監視器。他們均被封裝在System類的類變量in 和out中,
選擇
 1.計算機處理的數據最終分解為▁▁的組合。
 A 0
 B 數據包
 C 字母
 D 1
 2.計算機處理的最小數據單元稱為▁▁。
 A 位
 B 字節
 C 兆
 D 文件
 3.字母、數字和特殊符號稱為▁▁。
 A 位
 B 字節
 C 字符
 D 文件
 4.▁▁文件流類的 close 方法可用于關閉文件。
 A FileOutputStream
 B FileInputStream
 C RandomAccessFile
 D FileWrite
 5.RandomAccessFile 類的▁▁方法可用于從指定流上讀取整數。
 A readInt
 B readLine
 C seek
 D close
 6.RandomAccessFile 類的▁▁方法可用于從指定流上讀取字符串。
 A readInt
 B readLine
 C seek
 D close
 7.RandomAccessFile 類的▁▁方法可用于設置文件定位指針在文件中的位置。
 A readInt
 B readLiIne
 C seek
 D close
 8.在FilterOutputStream類的構造方法中,下面哪個類是合法:
 A File
 B InputStream
 C OutputStream
 D FileOutputStream
【答案】
 1.難度:容易答案:AD 知識點:計算機最終能處理的數據只能為 0 和 1。
 2.難度:容易答案:B 知識點:計算機處理的最小數據單元是字節。
3.難度:容易答案:C 知識點:字符的概念。
 4.難度:適中答案: ABC 知識點:FileOutStream、FileInputStream、RandomAccessFile
 文件流類的 close 方法可用于關閉文件。
 5.難度:適中答案:A 知識點:readInt方法的使用。
 6.難度:適中答案:B 知識點:readLIne方法的使用。
 7.難度:適中答案:C 知識點:seek 方法的使用。
 8.難度:適中答案:C 知識點:在FilterOutputStream類中只有一種結構:public
 FilterOutputStream(OutputStream)。
三. Thread
java中有幾種方法可以實現一個線程?用什么關鍵字修飾同步方法? stop()和suspend()方法為何不推薦使用?
 答:有兩種實現方法,分別是繼承Thread類與實現Runnable接口
 用synchronized關鍵字修飾同步方法
 反對使用stop(),是因為它不安全。它會解除由線程獲取的所有鎖定,而且如果對象處于一種不連貫狀態,
 那么其他線程能在那種狀態下檢查和修改它們。結果很難檢查出真正的問題所在。suspend()方法容易發生死鎖。
 調用suspend()的時候,目標線程會停下來,但卻仍然持有在這之前獲得的鎖定。此時,其他任何線程都不能訪
 問鎖定的資源,除非被"掛起"的線程恢復運行。對任何線程來說,如果它們想恢復目標線程,同時又試圖
 使用任何一個鎖定的資源,就會造成死鎖。所以不應該使用suspend(),而應在自己的Thread類中置入一個標志,
 指出線程應該活動還是掛起。若標志指出線程應該掛起,便用wait()命其進入等待狀態。若標志指出線程應當恢復,則用一個notify()重新啟動線程。
sleep() 和 wait() 有什么區別?
 答:sleep是線程類(Thread)的方法,導致此線程暫停執行指定時間,給執行機會給其他線程,但是監控狀態
 依然保持,到時后會自動恢復。調用sleep不會釋放對象鎖。
 wait是Object類的方法,對此對象調用wait方法導致本線程放棄對象鎖,進入等待此對象的等待鎖定池,只有針對
 此對象發出notify方法(或notifyAll)后本線程才進入對象鎖定池準備獲得對象鎖進入運行狀態。
同步和異步有何異同,在什么情況下分別使用他們?舉例說明。
 答:如果數據將在線程間共享。例如正在寫的數據以后可能被另一個線程讀到,或者正在讀的數據可能已經被另一個
 線程寫過了,那么這些數據就是共享數據,必須進行同步存取。
 當應用程序在對象上調用了一個需要花費很長時間來執行的方法,并且不希望讓程序等待方法的返回時,就應該使用
 異步編程,在很多情況下采用異步途徑往往更有效率。
啟動一個線程是用run()還是start()?
 答:啟動一個線程是調用start()方法,使線程所代表的虛擬處理機處于可運行狀態,這意味著它可以由JVM調度
 并執行。這并不意味著線程就會立即運行。run()方法可以產生必須退出的標志來停止一個線程。
當一個線程進入一個對象的一個synchronized方法后,其它線程是否可進入此對象的其它方法?
 答:不能,一個對象的一個synchronized方法只能由一個線程訪問。
請說出你所知道的線程同步的方法。
 答:wait():使一個線程處于等待狀態,并且釋放所持有的對象的lock。
 sleep():使一個正在運行的線程處于睡眠狀態,是一個靜態方法,調用此方法要捕捉InterruptedException異常。
 notify():喚醒一個處于等待狀態的線程,注意的是在調用此方法的時候,并不能確切的喚醒某一個等待狀態的
 線程,而是由JVM確定喚醒哪個線程,而且不是按優先級。
 notifyAll():喚醒所有處入等待狀態的線程,注意并不是給所有喚醒線程一個對象的鎖,而是讓它們競爭。
多線程有幾種實現方法,都是什么?同步有幾種實現方法,都是什么?
 答:多線程有兩種實現方法,分別是繼承Thread類與實現Runnable接口
 同步的實現方面有兩種,分別是synchronized,wait與notify
線程的基本概念、線程的基本狀態以及狀態之間的關系
 答:線程指在程序執行過程中,能夠執行程序代碼的一個執行單位,每個程序至少都有一個線程,也就是程序本身。
 Java中的線程有四種狀態分別是:運行、就緒、掛起、結束
簡述synchronized和java.util.concurrent.locks.Lock的異同 ?
 答:主要相同點:Lock能完成synchronized所實現的所有功能
 主要不同點:Lock有比synchronized更精確的線程語義和更好的性能。synchronized會自動釋放鎖,而Lock一定要求
 程序員手工釋放,并且必須在finally從句中釋放。
一、判斷題
 1.C 和 Java 都是多線程語言。( )
 2.如果線程死亡,它便不能運行。( )
 3.在 Java 中,高優先級的可運行線程會搶占低優先級線程。( )
 4.程序開發者必須創建一個線程去管理內存的分配。( )
 5.一個線程在調用它的 start 方法,之前,該線程將一直處于出生期。( )
 6.當調用一個正在進行線程的 stop()方法時,該線程便會進入休眠狀態。( )
 7.如果線程的 run 方法執行結束或拋出一個不能捕獲的例外,線程便進入等待狀態。( )
 8.一個線程可以調用 yield 方法使其他線程有機會運行。( )
【答案】
 1.難度:容易
 答案:錯誤
 知識點:C 是單線程語言。
 2.難度:容易
 答案:正確
 知識點:線程死亡就意味著它不能運行。
 3.難度:適中
 答案:正確
 知識點:線程優先級的使用。
 4.難度:適中
 答案:錯誤
 知識點:Java 提供了一個系統線程來管理內存的分配。
 5.難度:容易
 答案:正確
 知識點:出生期的概念。
 6.難度:適中
 答案:錯誤
 知識點:應該是 sleep 方法。
 7.難度:適中
 答案:錯誤
 知識點:如果線程的 run 方法執行結束或拋出一個不能捕獲的例外,線程便進入死亡狀態。
 8.難度:適中
 答案:正確
 知識點:yield 方法總是讓高優先級的就緒線程先運行。
二、選擇題
 1.Java 語言中提供了一個▁▁線程,自動回收動態分配的內存。
 A 異步
 B 消費者
 C 守護
 D 垃圾收集
 2.當▁▁方法終止時,能使線程進入死亡狀態。
 A run
 B setPrority
 C yield
 D sleep
 3.用▁▁方法可以改變線程的優先級。
 A run
 B setPrority
 C yield
 D sleep
 4.線程通過▁▁方法可以使具有相同優先級線程獲得處理器。
 A run
 B setPrority
 C yield
 D sleep
 5.線程通過▁▁方法可以休眠一段時間,然后恢復運行。
 A run
 B setPrority
 C yield
 D sleep
 6.▁▁方法使對象等待隊列的第一個線程進入就緒狀態。
 A run
 B notify
 C yield
 D sleep
 7.方法 resume( )負責重新開始▁▁線程的執行。
 A 被 stop( )方法停止
 B 被 sleep( )方法停止
 C 被 wait( )方法停止
 D 被 suspend( )方法停止
 8.▁▁方法可以用來暫時停止當前線程的運行。
 A stop( )
 B sleep( )
 C wait( )
 D suspend()
【答案】
 1.難度:容易
 答案:D
 知識點:垃圾線程的使用。
 2.難度:容易
 答案:A
 知識點:run 方法的使用。
 3.難度:容易
 答案:B
 知識點:setPrority 方法的使用。
 4.難度:容易
 答案:C
 知識點:yield 方法的使用。
 5.難度:容易
 答案:D
 知識點:sleep 方法的使用。
 6.難度:容易
 答案:B
 知識點:notify 方法的使用。
 7.難度:適中
 答案:D
 知識點:一個線程被用 suspend( )方法,將該線程掛起。并通過調用 resume( )方法來重新開始線程的執行。
 但是該方法容易導致死鎖,應盡量避免使用。
 8.難度:適中
 答案:BCD
 知識點:當調用 stop( )方法后,當前的線程不能重新開始運行。
Java為什么要引入線程機制,線程、程序、進程之間的關系是怎樣的。
答:線程可以彼此獨立的執行,它是一種實現并發機制的有效手段,可以同時使用多個線程來完成不同的任務,
 并且一般用戶在使用多線程時并不考慮底層處理的細節。
 程序是一段靜態的代碼,是軟件執行的藍本。進程是程序的一次動態執行過程,即是處于運行過程中的程序。
 線程是比進程更小的程序執行單位,一個進程可以啟動多個線程同時運行,不同線程之間可以共享相同的內
 存區域和數據。多線程程序是運行時間后嗣可能出現在一個進程之內的、有一個以上線程同時運行的情況的程序。
Runnable接口包括哪些抽象方法?Thread類有哪些主要域和方法?
答:Runnable接口中僅有run()抽象方法。
 Thread類主要域有:MAX_PRIORITY,MIN_PRIORITY,NORM_PRIORITY。
 主要方法有start(),run(),sleep(),currentThread(),setPriority(),getPriority(),join()等。
創建線程有哪兩種方式?試寫出每種的具體的流程。比較兩種創建方式的不同,哪個更優。
1—繼承Thread類
2—實現Runnable接口
【區別】
 繼承Thread: 線程代碼存放Thread子類run方法中。
 實現Runnable:線程代碼存在接口的子類的run方法。
【實現方法的好處】
 1)避免了單繼承的局限性
 2)多個線程可以共享同一個接口子類的對象,非常適合多個相同線程來處理同一份資源。
編寫一個繼承Thread類的方式實現多線程的程序。該類MyThread有兩個屬性,一個字符串WhoAmI代表線程名,
 一個整數delay代表該線程隨機要休眠的時間。構造有參的構造器,線程執行時,顯示線程名和要休眠時間。
 另外,定義一個測試類TestThread,創建三個線程對象以展示執行情況。
利用多線程設計一個程序,同時輸出 50 以內的奇數和偶數,以及當前運行的線程名。
public class Threadprint extends Thread {int k = 1; public void run() { int i=k; while(i<50) { System.out.println(Thread.currentThread().getName()+"-----"+i); i+=2; } System.out.println(Thread.currentThread().getName()+" end!"); } public static void main (String[] args) { Threadprint t1=new Threadprint();Threadprint t2=new Threadprint(); t1.k = 1;t2.k = 2;t1.start(); t2.start(); } }總結
以上是生活随笔為你收集整理的【Java】集合+I/O流+多线程の练习题+面试题的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 生成指定序列的前一字典序序列(洛谷P25
- 下一篇: 【Python】Python里的复数运算
