騰訊百度聚美Java面試題集總全集(九)_第1頁
騰訊百度聚美Java面試題集總全集(九)_第2頁
騰訊百度聚美Java面試題集總全集(九)_第3頁
騰訊百度聚美Java面試題集總全集(九)_第4頁
免費預覽已結束,剩余7頁可下載查看

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、56、TreeMap和 TreeSet在排序時如何比較元素?Collections工具類中的sort()方法如何比較元素?答: TreeSet 要求存放的對象所屬的類必須實現(xiàn) Comparable 接口,該接口提供了比較元素的 compareTo() 方法,當插入元素時會回調該方法比較元素的大小。TreeMap 要求存放的鍵值對映射的鍵必須實現(xiàn)Comparable接口從而根據(jù)鍵對元素進行排序。 Collections 工具類的 sort 方法有兩種重載的形式,第一種要求傳入的待排序容器中存放的對象比較實現(xiàn) Comparable 接口以實現(xiàn)元素的比較;第二種不強制性的要求容器中的元素必須可比較,

2、 但是要求傳入第二個參數(shù), 參數(shù)是 Comparator 接口的子類型(需要重寫 compare 方法實現(xiàn)元素的比較),相當于一個臨時定義的排序規(guī)則, 其實就是通過接口注入比較元素大小的算法, 也是對回調模式的應用( Java 中對函數(shù)式編程的支持)。例子 1:public class Student implements Comparable<Student> String name;/姓名private int age;/年齡privatename;public Student(String name, int age) this.age = age;Overridethis.

3、name =例子2:public String toString() name + ", age=" + age + ""Overridepublic int compareTo(Student o) o.age; /比較年齡 ( 年齡的升序 )return "Student name=" +return this.age -public static voidmain(String args) Set<Student> set = new TreeSet<>();/ Java 7的鉆石語法( 構造器后面的尖括

4、號中不需要寫類型)set.add(new Student("Hao LUO",33);set.add(new Student("XJ WANG",32);set.add(new Student("Bruce LEE",60);set.add(new Student("Bob YANG",22);for(Student stu : set) /輸出結果 : /YANG, age=22/Student name=XJ WANG,age=32/Student name=Hao LUO,age=33/Student nam

5、e=Bruce LEE, age=60Student name=Bobpublic class Student private int age;private String name;/年齡/姓名name;public Student(String name, int age) this.age = age; =/*獲取學生姓名*/public String getName() /*獲取學生年齡*/public int getAge() return name;return age;Overridepublic String toString() return"St

6、udent name=" + name + ", age=" + age + ""import java.util.ArrayList;import java.util.Collections;import java.util.Comparator;import java.util.List;class Test02 public static voidmain(String args) List<Student> list = new ArrayList<>();/ Java7 的鉆石語法 ( 構造器后面的尖括號中不需

7、要寫類型 )list.add(new Student("Hao LUO",33);list.add(new Student("XJ WANG",32);list.add(new Student("Bruce LEE",60);list.add(new Student("Bob YANG", 22);/通過 sort方法的第二個參數(shù)傳入一個Comparator 接口對象/ 相當于是傳入一個比較對象大小的算法到 sort 方法中/ 由于 Java 中沒有函數(shù)指針、仿函數(shù)、委托這樣的概念/ 因此要將一個算法傳入一個方法中

8、唯一的選擇就是通過接口回調Collections.sort(list, new Comparator<Student> () Overridepublic intcompare(Student o1, Student o2) returno1.getName().compareTo(o2.getName();/比較學生姓名);for(Student stu : list) /輸出結果 : /Student name=BobYANG, age=22/Student name=Bruce LEE,age=60/Student name=Hao LUO,age=33/Student na

9、me=XJ WANG, age=3257、Thread 類的 sleep() 方法和對象的 wait() 方法都可以讓線程暫停執(zhí)行,它們有什么區(qū)別 ?答: sleep() 方法(休眠)是線程類( Thread )的靜態(tài)方法,調用此方法會讓當前線程暫停執(zhí)行指定的時間,將執(zhí)行機會( CPU)讓給其他線程,但是對象的鎖依然保持,因此休眠時間結束后會自動恢復(線程回到就緒狀態(tài),請參考第66題中的線程狀態(tài)轉換圖)。 wait() 是 Object 類的方法,調用對象的 wait() 方法導致當前線程放棄對象的鎖 (線程暫停執(zhí)行) ,進入對象的等待池 (wait pool ),只有調用對象的 notify

10、() 方法(或 notifyAll() 方法)時才能喚醒等待池中的線程進入等鎖池( lock pool ),如果線程重新獲得對象的鎖就可以進入就緒狀態(tài)。補充:可能不少人對什么是進程, 什么是線程還比較模糊, 對于為什么需要多線程編程也不是特別理解。 簡單的說:進程是具有一定獨立功能的程序關于某個數(shù)據(jù)集合上的一次運行活動, 是操作系統(tǒng)進行資源分配和調度的一個獨立單位; 線程是進程的一個實體, 是CPU調度和分派的基本單位, 是比進程更小的能獨立運行的基本單位。線程的劃分尺度小于進程, 這使得多線程程序的并發(fā)性高; 進程在執(zhí)行時通常擁有獨立的內存單元,而線程之間可以共享內存。使用多線程的編程通常能

11、夠帶來更好的性能和用戶體驗, 但是多線程的程序對于其他程序是不友好的, 因為它可能占用了更多的 CPU 資源。當然,也不是線程越多,程序的性能就越好,因為線程之間的調度和切換也會浪費 CPU時間。時下很時髦的 Node.js 就采用了單線程異步 I/O 的工作模式。58、線程的 sleep() 方法和 yield()方法有什么區(qū)別?答: sleep() 方法給其他線程運行機會時不考慮線程的優(yōu)先級, 因此會給低優(yōu)先級的線程以運行的機會; yield() 方法只會給相同優(yōu)先級或更高優(yōu)先級的線程以運行的機會; 線程執(zhí)行 sleep() 方法后轉入阻塞( blocked )狀態(tài),而執(zhí)行 yield()

12、 方法后轉入就緒( ready )狀態(tài); sleep()方法聲明拋出InterruptedException,而yield()方法沒有聲明任何異常; sleep() 方法比 yield() 方法(跟操作系統(tǒng) CPU調度相關)具有更好的可移植性。59、當一個線程進入一個對象的 synchronized 方法 A 之后,其它線程是否可進入此對象的 synchronized 方法 B?答:不能。其它線程只能訪問該對象的非同步方法,同步方法則不能進入。因為非靜態(tài)方法上的 synchronized 修飾符要求執(zhí)行方法時要獲得對象的鎖,如果已經(jīng)進入 A 方法說明對象鎖已經(jīng)被取走, 那么試圖進入 B 方法的

13、線程就只能在等鎖池(注意不是等待池哦 )中等待對象的鎖。60、請說出與線程同步以及線程調度相關的方法。答:- wait():使一個線程處于等待(阻塞)狀態(tài),并且釋放所持有的對象的鎖;- sleep() :使一個正在運行的線程處于睡眠狀態(tài),是一個靜態(tài)方法,調用此方法要處理 InterruptedException異常;- notify():喚醒一個處于等待狀態(tài)的線程,當然在調用此方法的時候,并不能確切的喚醒某一個等待狀態(tài)的線程, 而是由 JVM確定喚醒哪個線程, 而且與優(yōu)先級無關;- notityAll() :喚醒所有處于等待狀態(tài)的線程,該方法并不是將對象的鎖給所有線程,而是讓它們競爭,只有獲得

14、鎖的線程才能進入就緒狀態(tài);補充:Java 5 通過 Lock 接口提供了顯式的鎖機制 (explicit lock ),增強了靈活 性以 及對線程的協(xié)調 。 Lock 接口 中定義了加鎖( lock() ) 和 解 鎖 ( unlock() ) 的 方 法 , 同 時 還 提 供 了 newCondition() 方法來產(chǎn)生用于線程之間通信的 Condition 對象;此外, Java 5 還提供了信號量機制( semaphore),信號量可以用來限制對某個共享資源進行訪問的線程的數(shù)量。 在對資源進行訪問之前,線程必須得到信號量的許可(調用Semaphore 對象的acquire() 方法);

15、在完成對資源的訪問后,線程必須向信號量歸還許可(調用 Semaphore對象的 release() 方法)。下面的例子演示了 100 個線程同時向一個銀行賬戶中存入 1 元錢,在沒有使用同步機制和使用同步機制情況下的執(zhí)行情況。銀行賬戶類:/* 銀行賬戶* author 駱昊*/publicclass Account privatedouble balance;/賬戶余額/* 存款* param money 存入金額*/public void deposit(double money) double newBalance= balance + money;try Thread.sleep(10)

16、;/模擬此業(yè)務需要一段處理時間catch(InterruptedException ex) ex.printStackTrace();balance = newBalance;/*獲得賬戶余額*/public double getBalance() return balance;存錢線程類:/* 存錢線程* author 駱昊*/public class AddMoneyThread implements Runnable privateAccount account;/存入賬戶private double money;/存入金額public AddMoneyThread(Account ac

17、count, double money)this.account = account;this.money = money;Overridepublic void run() account.deposit(money);測試類:importclassTest01 publicstatic void main(String args) Account account = new Account();ExecutorService service =Executors.newFixedThreadPool(100);for(int i = 1; i <= 100;i+) service.e

18、xecute(new AddMoneyThread(account, 1);service.shutdown();while(!service.isTerminated() 賬戶余額 : " + account.getBalance();在沒有同步的情況下,執(zhí)行結果通常是顯示賬戶余額在10 元以下,出現(xiàn)這種狀況的原因是,當一個線程 A 試圖存入 1 元的時候,另外一個線程 B 也能夠進入存款的方法中,線程 B讀取到的賬戶余額仍然是線程 A存入 1 元錢之前的賬戶余額,因此也是在原來的余額 0 上面做了加 1 元的操作,同理線程 C也會做類似的事情,所以最后 100 個線程執(zhí)行結束時,

19、 本來期望賬戶余額為100 元,但實際得到的通常在 10 元以下(很可能是 1 元哦)。解決這個問題的辦法就是同步,當一個線程對銀行賬戶存錢時, 需要將此賬戶鎖定, 待其操作完成后才允許其他的線程進行操作,代碼有如下幾種調整方案:在銀行賬戶的存款( deposit )方法上同步( synchronized )關鍵字/* 銀行賬戶* author 駱昊*/publicclass Account privatedouble balance;/賬戶余額/* 存款* param money 存入金額*/public synchronized void deposit(double money)doub

20、le newBalance = balance + money;try Thread.sleep(10);/模擬此業(yè)務需要一段處理時間catch(InterruptedException ex) ex.printStackTrace();balance = newBalance;/*獲得賬戶余額*/public double getBalance() return balance;在線程調用存款方法時對銀行賬戶進行同步/* 存錢線程* author 駱昊*/public class AddMoneyThread implements Runnable Account account;/存入賬戶private double money;/存入金額privatepublic AddMoneyThread(Account account, double mone

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論