1. 程式人生 > >牛客網java常考面試題筆記

牛客網java常考面試題筆記

1.   什麼是Java虛擬機器?為什麼Java被稱作是平臺無關的程式語言

Java虛擬機器是一個可以執行Java位元組碼的虛擬機器程序。
java的跨平臺不是java源程式的跨平臺,如果是這樣,那麼所以語言都是跨平臺的, java源程式先經過javac編譯器編譯成二進位制的.class位元組碼檔案(java的跨平臺指的就是.class位元組碼檔案的跨平臺,.class位元組碼檔案是與平臺無關的),.class檔案再執行在jvm上,java直譯器(jvm的一部分)會將其解釋成對應平臺的機器碼執行,所以java所謂的跨平臺就是在不同平臺上安裝了不同的jvm,而在不同平臺上生成的.class檔案都是一樣的,而.class檔案再由對應平臺的jvm解釋成對應平臺的機器碼執行。

2.    JDKJRE的區別是什麼?
JRE: Java Runtime Environment 
JDK:Java Development Kit
JRE顧名思義是java執行時環境,包含了java虛擬機器,java基礎類庫。是使用java語言編寫的程式執行所需要的軟體環境,是提供給想執行java程式的使用者使用的。
JDK顧名思義是java開發工具包,是程式設計師使用java語言編寫java程式所需的開發工具包,是提供給程式設計師使用的。JDK包含了JRE,同時還包含了編譯java原始碼的編譯器javac,還包含了很多java程式除錯和分析的工具:jconsole,jvisualvm等工具軟體,還包含了java程式編寫所需的文件和demo例子程式。
如果你需要執行java程式,只需安裝JRE就可以了。如果你需要編寫java程式,需要安裝JDK。

JRE根據不同作業系統(如:windows,linux等)和不同JRE提供商(IBM,ORACLE等)有很多版本 

3.      ”static”關鍵字是什麼意思?Java中是否可以覆蓋(override)一個private或者是static的方法?
Static表示靜態的意思,可用於修飾成員變數和成員函式,被靜態修飾的成員函式只能訪問靜態成員,不可以訪問非靜態成員。靜態是隨著類的載入而載入的,因此可以直接用類進行訪問。重寫是子類中的方法和子類繼承的父類中的方法一樣(函式名,引數,引數型別,反回值型別),但是子類中的訪問許可權要不低於父類中的訪問許可權。重寫的前提是必須要繼承,private修飾不支援繼承,因此被私有的方法不可以被重寫。靜態方法形式上可以被重寫,即子類中可以重寫父類中靜態的方法。但是實際上從記憶體的角度上靜態方法不可以被重寫。

4.      是否可以在static環境中訪問非static變數?

因為靜態的成員屬於類,隨著類的載入而載入到靜態方法區記憶體,當類載入時,此時不一定有例項建立,沒有例項,就不可以訪問非靜態的成員。

static變數在Java中是屬於類的,它在所有的例項中的值是一樣的。當類被Java虛擬機器載入的時候,會對static變數進行初始化。如果你的程式碼嘗試不用例項來訪問非static的變數,編譯器會報錯,因為這些變數還沒有被創建出來,還沒有跟任何例項關聯上。

5.       Java支援的資料型別有哪些?什麼是自動拆裝箱?

基本資料型別: 整數值型:byte,short,int,long, 字元型:char 浮點型別:float,double 布林型:boolean 整數預設int型,小數預設是double型。Float和long型別的必須加字尾。首先知道String是引用型別不是基本型別,引用型別宣告的變數是指該變數在記憶體中實際儲存的是一個引用地址,實體在堆中。引用型別包括類、介面、陣列等。String類還是final修飾的。 而包裝類就屬於引用型別,自動裝箱和拆箱就是基本型別和引用型別之間的轉換,至於為什麼要轉換,因為基本型別轉換為引用型別後,就可以new物件,從而呼叫包裝類中封裝好的方法進行基本型別之間的轉換或者toString(當然用類名直接呼叫也可以,便於一眼看出該方法是靜態的),還有就是如果集合中想存放基本型別,泛型的限定型別只能是對應的包裝型別

6.  Java中的方法覆蓋(Overriding)和方法過載(Overloading)是什麼意思?

方法重寫的原則:

1) 重寫方法的方法名稱、引數列表必須與原方法的相同,返回型別可以相同也可以是原型別的子型別(從Java SE5開始支援)。

2) 重寫方法不能比原方法訪問性差(即訪問許可權不允許縮小)。

3) 重寫方法不能比原方法丟擲更多的異常。

4) 被重寫的方法不能是final型別,因為final修飾的方法是無法重寫的。

5) 被重寫的方法不能為private,否則在其子類中只是新定義了一個方法,並沒有對其進行重寫。

6) 被重寫的方法不能為static。如果父類中的方法為靜態的,而子類中的方法不是靜態的,但是兩個方法除了這一點外其他都滿足重寫條件,那麼會發生編譯錯誤;反之亦然。即使父類和子類中的方法都是靜態的,並且滿足重寫條件,但是仍然不會發生重寫,因為靜態方法是在編譯的時候把靜態方法和類的引用型別進行匹配。

7) 重寫是發生在執行時的,因為編譯期編譯器不知道並且沒辦法確定該去呼叫哪個方法,JVM會在程式碼執行的時候作出決定。

方法過載的原則:

1)  方法名稱必須相同。

2) 引數列表必須不同(個數不同、或型別不同、引數型別排列順序不同等)。

3) 方法的返回型別可以相同也可以不相同。

4) 僅僅返回型別不同不足以成為方法的過載。

5) 過載是發生在編譯時的,因為編譯器可以根據引數的型別來選擇使用哪個方法。

重寫和過載的不同:

1) 方法重寫要求引數列表必須一致,而方法過載要求引數列表必須不一致

2) 方法重寫要求返回型別必須一致(或為其子型別),方法過載對此沒有要求。

3) 方法重寫只能用於子類重寫父類的方法,方法過載用於同一個類中的所有方法

4) 方法重寫對方法的訪問許可權和丟擲的異常有特殊的要求,而方法過載在這方面沒有任何限制。

5) 父類的一個方法只能被子類重寫一次,而一個方法可以在所有的類中可以被過載多次

6) 過載是編譯時多型,重寫是執行時多型

7.    Java中,什麼是構造方法?什麼是構造方法過載?什麼是複製構造方法?
Java中的建構函式是為了初始化物件的,建構函式的函式名和類名一致,預設的建構函式沒有引數,沒有返回值,建構函式的函式體內,沒有內容。建構函式的過載是函式名與類名相同,引數型別不同,引數不同。同樣的作用也是為了初始化物件的。 Java中沒有拷貝建構函式的概念!

關於複製建構函式:C++中的複製建構函式通常有三種作用

1.物件作為函式引數

2.物件作為函式返回值

3.使用一個物件對另一個物件初始化。

C++語法允許使用者定義自己的複製建構函式以實現自定義的複製,比如說進行深複製。Java並不支援這樣的複製建構函式。但是這並不代表Java中沒有這種機制,在Java中Object類的clone()方法就是這種機制的體現。而且通過以上三種方式對Java物件進行的操作都是對引用的操作,不像C++裡面是對原物件的操作,因此Java中也不需要考慮需要使用複製建構函式這種問題。

   當新物件被建立的時候,構造方法會被呼叫。每一個類都有構造方法。在程式設計師沒有給類提供構造方法的情況下,Java編譯器會為這個類建立一個預設的構造方法
Java
中構造方法過載和方法過載很相似。可以為一個類建立多個構造方法。每一個構造方法必須有它自己唯一的引數列表。
Java
不支援像C++中那樣的複製構造方法,這個不同點是因為如果你不自己寫構造方法的情況下,Java不會建立預設的複製構造方法。

8.   Java支援多繼承麼?
Java中類不支援多繼承,只支援單繼承(即一個類只有一個父類)。 但是java中的介面支援多繼承,,即一個子介面可以有多個父介面。(介面的作用是用來擴充套件物件的功能,一個子介面繼承多個父介面,說明子介面擴充套件了多個功能,當類實現介面時,類就擴充套件了相應的功能)。

9.   介面和抽象類的區別是什麼?

從設計層面來說,抽象是對類的抽象,是一種模板設計,介面是行為的抽象,是一種行為的規範

Java提供和支援建立抽象類和介面。它們的實現有共同點,不同點在於:介面中所有的方法隱含的都是抽象的。而抽象類則可以同時包含抽象和非抽象的方法。類可以實現很多個介面,但是隻能繼承一個抽象類類可以不實現抽象類和介面宣告的所有方法,當然,在這種情況下,類也必須得宣告成是抽象的。抽象類可以在不提供介面方法實現的情況下實現介面。
Java
介面中宣告的變數預設都是final的。抽象類可以包含非final的變數。Java介面中的成員函式預設是public的。抽象類的成員函式可以是privateprotected或者是public介面是絕對抽象的,不可以被例項化。抽象類也不可以被例項化,但是,如果它包含main方法的話是可以被呼叫的。也可以參考JDK8中抽象類和介面的區別

10. 什麼是值傳遞和引用傳遞?

值傳遞是對基本型變數而言的,傳遞的是該變數的一個副本,改變副本不影響原變數.

引用傳遞一般是對於物件型變數而言的,傳遞的是該物件地址的一個副本並不是原物件本身

一般認為,java內的傳遞都是值傳遞. java中例項物件的傳遞是引用傳遞
public void add(int a) { int b = a; } 這個可以看作是值傳遞,a是基本資料型別,他把他的值傳給了b public void add(Object obj) { Object objTest = obj; } 這個可以看作是址傳遞,obj是引用資料型別,是把他棧中指向堆中的物件的地址值賦值給了objTest. 這時候就同時有兩個引用指向了堆中的某個Object物件其實這樣看來,java應該只有值傳遞的。如果是基本資料型別,傳遞的就是實際的值. 如果是引用資料型別,傳遞的就是該引用的地址值.

11. 程序和執行緒的區別是什麼?

程序是執行著的應用程式,而執行緒是程序內部的一個執行序列。一個程序可以有多個執行緒。執行緒又叫做輕量級程序。

執行緒的劃分小於程序,執行緒隸屬於某個程序。程序是程式的一種動態形式,是CPU、記憶體等資源佔用的基本單位,而執行緒是不能佔有這些資源的。程序之間相互獨立,通訊比較困難,而執行緒之間共享一塊記憶體區域,通訊比較方便。程序在執行的過程中,包含比較固定的入口,執行順序,出口,而執行緒的這些過程會被應用程式所控制

執行緒與程序的區別歸納:

a.地址空間和其它資源:程序間相互獨立,同一程序的各執行緒間共享。某程序內的執行緒在其它程序不可見。

b.通訊:程序間通訊IPC,執行緒間可以直接讀寫程序資料段(如全域性變數)來進行通訊——需要程序同步和互斥手段的輔助,以保證資料的一致性。

c.排程和切換:執行緒上下文切換比程序上下文切換要快得多。

d.在多執行緒OS中,程序不是一個可執行的實體。

12.建立執行緒有幾種不同的方式?你喜歡哪一種?為什麼?

 4種方式可以用來建立執行緒:繼承Thread實現Runnable介面應用程式可以使用Executor框架來建立執行緒池

實現Runnable介面這種方式更受歡迎,因為這不需要繼承Thread類。在應用設計中已經繼承了別的物件的情況下,這需要多繼承(而Java不支援多繼承),只能實現介面。同時,執行緒池也是非常高效的,很容易實現和使用。

還有一種方式是實現Callable介面

繼承Thread類(真正意義上的執行緒類),是Runnable介面的實現。

實現Runnable介面,並重寫裡面的run方法。

使用Executor框架建立執行緒池。Executor框架是juc裡提供的執行緒池的實現。

呼叫執行緒的start():啟動此執行緒;呼叫相應的run()方法

繼承於Thread類的執行緒類,可以直接呼叫start方法啟動執行緒(使用static也可以實現資源共享).一個執行緒(物件)只能夠執行一次start(),而且不能通過Thread實現類物件的run()去啟動一個執行緒。

實現Runnable介面的類需要再次用Thread類包裝後才能呼叫start方法。(三個Thread物件包裝一個類物件,就實現了資源共享)。

執行緒的使用的話,注意鎖和同步的使用。(多執行緒訪問共享資源容易出現執行緒安全問題)

一般情況下,常見的是第二種。

* Runnable介面有如下好處:

*①避免點繼承的侷限,一個類可以繼承多個介面。

*②適合於資源的共享

/*

 * Thread的常用方法:

 * 1.start():啟動執行緒並執行相應的run()方法

 * 2.run():子執行緒要執行的程式碼放入run()方法中

 * 3.currentThread():靜態的,調取當前的執行緒

 * 4.getName():獲取此執行緒的名字

 * 5.setName():設定此執行緒的名字

 * 6.yield():呼叫此方法的執行緒釋放當前CPU的執行權(很可能自己再次搶到資源)

 * 7.join():在A執行緒中呼叫B執行緒的join()方法,表示:當執行到此方法,A執行緒停止執行,直至B執行緒執行完畢,

 * A執行緒再接著join()之後的程式碼執行

 * 8.isAlive():判斷當前執行緒是否還存活

 * 9.sleep(long l):顯式的讓當前執行緒睡眠l毫秒  (只能捕獲異常,因為父類run方法沒有拋異常)

 * 10.執行緒通訊(方法在Object類中):wait()  notify()  notifyAll()

 *

 *設定執行緒的優先順序(非絕對,只是相對機率大些)

 * getPriority():返回執行緒優先值

 * setPriority(int newPriority):改變執行緒的優先順序

 */

13. 概括的解釋下執行緒的幾種可用狀態。

1.新建(new):新建立了一個執行緒物件。

2.可執行(runnable):執行緒物件建立後,其他執行緒(比如main執行緒)呼叫了該物件 的start()方法。該狀態的執行緒位於可執行執行緒池中,等待被執行緒排程選中,獲 取cpu 的使用權

3.執行(running):可執行狀態(runnable)的執行緒獲得了cpu 時間片(timeslice,執行程式程式碼。

4.阻塞(block):阻塞狀態是指執行緒因為某種原因放棄了cpu 使用權,也即讓出了 cputimeslice,暫時停止執行。直到執行緒進入可執行(runnable)狀態,才有機會再次獲得cpu timeslice 轉到執行(running)狀態。

阻塞的情況分三種:

(一).等待阻塞:執行(running)的執行緒執行o.wait()方法,JVM會把該執行緒放入等待佇列(waitting queue)中。

(二).同步阻塞:執行(running)的執行緒在獲取物件的同步鎖時,若該同步鎖 被別的執行緒佔用,則JVM會把該執行緒放入鎖池(lock pool)中。

(三).其他阻塞: 執行(running)的執行緒執行Thread.sleep(longms)t.join ()方法,或者發出了I/O請求時,JVM會把該執行緒置為阻塞狀態。            sleep()狀態超時、join()等待執行緒終止或者超時、或者I/O處理完畢時,執行緒重新轉入可執行(runnable)狀態。

5.死亡(dead):執行緒run()main()方法執行結束,或者因異常退出了run()方法,則該執行緒結束生命週期。死亡的執行緒不可再次復生。

14. 同步方法和同步程式碼塊的區別是什麼?

 區別:

同步方法預設用this或者當前類class物件作為鎖;

同步程式碼塊可以選擇以什麼來加鎖,比同步方法要更細顆粒度,我們可以選擇只同步會發生同步問題的部分程式碼而不是整個方法;

同步方法使用關鍵字synchronized修飾方法,而同步程式碼塊主要是修飾需要進行同步的程式碼,用synchronizedobject{程式碼內容}進行修飾;

為何要使用同步? 

    java允許多執行緒併發控制,當多個執行緒同時操作一個可共享的資源變數時(如資料的增刪改查), 

將會導致資料不準確,相互之間產生衝突,因此加入同步鎖以避免在該執行緒沒有完成操作之前,被其他執行緒的呼叫, 

從而保證了該變數的唯一性和準確性。

  1.同步方法 

即有synchronized關鍵字修飾的方法。 

由於java的每個物件都有一個內建鎖,當用此關鍵字修飾方法時, 

內建鎖會保護整個方法。在呼叫該方法前,需要獲得內建鎖,否則就處於阻塞狀態。

程式碼如: 

    public synchronized voidsave(){}

注: synchronized關鍵字也可以修飾靜態方法,此時如果呼叫該靜態方法,將會鎖住整個類

    2.同步程式碼塊 

即有synchronized關鍵字修飾的語句塊。 

被該關鍵字修飾的語句塊會自動被加上內建鎖,從而實現同步

程式碼如: 

    synchronized(object){ 

    }

注:同步是一種高開銷的操作,因此應該儘量減少同步的內容。 

通常沒有必要同步整個方法,使用synchronized程式碼塊同步關鍵程式碼即可。 

程式碼例項: 

複製程式碼

package com.x敏感詞hread;

    /**

     * 執行緒同步的運用

     * 

     * @author XIEHEJUN

     * 

     */

    public class SynchronizedThread{

        class Bank {

           private int account = 100;

           public int getAccount() {

               return account;

            }

           /**

            * 用同步方法實現

            * 

            * @param money

            */

           public synchronized void save(int money) {

               account += money;

            }

           /**

            * 用同步程式碼塊實現

            * 

            * @param money

            */

           public void save1(int money) {

               synchronized (this) {

                   account += money;

               }

            }

        }

        class NewThreadimplements Runnable {

           private Bank bank;

           public NewThread(Bank bank) {

               this.bank = bank;

            }

           @Override

           public void run() {

               for (int i = 0; i < 10; i++) {

                   // bank.save1(10);

                   bank.save(10);

                   System.out.println(i + "賬戶餘額為:" + bank.getAccount());

               }

            }

        }

        /**

         * 建立執行緒,呼叫內部類

         */

        public voiduseThread() {

           Bank bank = new Bank();

            NewThreadnew_thread = new NewThread(bank);

           System.out.println("執行緒1");

           Thread thread1 = new Thread(new_thread);

           thread1.start();

           System.out.println("執行緒2");

           Thread thread2 = new Thread(new_thread);

           thread2.start();

        }

        public staticvoid main(String[] args) {

           SynchronizedThread st = new SynchronizedThread();

           st.useThread();

        }

    }

複製程式碼

3.使用特殊域變數(volatile)實現執行緒同步

    a.volatile關鍵字為域變數的訪問提供了一種免鎖機制, 

    b.使用volatile修飾域相當於告訴虛擬機器該域可能會被其他執行緒更新, 

    c.因此每次使用該域就要重新計算,而不是使用暫存器中的值 

    d.volatile不會提供任何原子操作,它也不能用來修飾final型別的變數 

例如: 

在上面的例子當中,只需在account前面加上volatile修飾,即可實現執行緒同步。 

程式碼例項: 

複製程式碼

      //只給出要修改的程式碼,其餘程式碼與上同

        class Bank {

           //需要同步的變數加上volatile

           private volatile int account = 100;

           public int getAccount() {

               return account;

            }

           //這裡不再需要synchronized 

           public void save(int money) {

               account += money;

            }

複製程式碼

注:多執行緒中的非同步問題主要出現在對域的讀寫上,如果讓域自身避免這個問題,則就不需要修改操作該域的方法。 

用final域,有鎖保護的域和volatile域可以避免非同步的問題。 

4.使用重入鎖實現執行緒同步

JavaSE5.0中新增了一個java.util.concurrent包來支援同步。 

    ReentrantLock類是可重入、互斥、實現了Lock介面的鎖, 

它與使用synchronized方法和快具有相同的基本行為和語義,並且擴充套件了其能力

    ReenreantLock類的常用方法有:

        ReentrantLock(): 建立一個ReentrantLock例項 

        lock() : 獲得鎖 

        unlock() : 釋放鎖 

注:ReentrantLock()還有一個可以建立公平鎖的構造方法,但由於能大幅度降低程式執行效率,不推薦使用 

例如: 

在上面例子的基礎上,改寫後的程式碼為: 

程式碼例項: 

複製程式碼

//只給出要修改的程式碼,其餘程式碼與上同

        class Bank {

           private int account = 100;

           //需要宣告這個鎖

           private Lock lock = new ReentrantLock();

           public int getAccount() {

               return account;

            }

           //這裡不再需要synchronized 

           public void save(int money) {

               lock.lock();

               try{

                   account += money;

               }finally{

                   lock.unlock();

               }

            }

複製程式碼

注:關於Lock物件和synchronized關鍵字的選擇: 

        a.最好兩個都不用,使用一種java.util.concurrent包提供的機制, 

能夠幫助使用者處理所有與鎖相關的程式碼。 

        b.如果synchronized關鍵字能滿足使用者的需求,就用synchronized,因為它能簡化程式碼 

        c.如果需要更高階的功能,就用ReentrantLock類,此時要注意及時釋放鎖,否則會出現死鎖,通常在finally程式碼釋放鎖 

5.使用區域性變數實現執行緒同步 

如果使用ThreadLocal管理變數,則每一個使用該變數的執行緒都獲得該變數的副本, 

副本之間相互獨立,這樣每一個執行緒都可以隨意修改自己的變數副本,而不會對其他執行緒產生影響。

    ThreadLocal 類的常用方法

    ThreadLocal() : 建立一個執行緒本地變數 

    get() : 返回此執行緒區域性變數的當前執行緒副本中的值 

    initialValue() : 返回此執行緒區域性變數的當前執行緒的"初始值" 

    set(T value) : 將此執行緒區域性變數的當前執行緒副本中的值設定為value

例如: 

在上面例子基礎上,修改後的程式碼為: 

程式碼例項: 

複製程式碼

//只改Bank類,其餘程式碼與上同

        public classBank{

           //使用ThreadLocal類管理共享變數account

           private static ThreadLocal<Integer> account = newThreadLocal<Integer>(){

               @Override

               protected Integer initialValue(){

                   return 100;

               }

           };

           public void save(int money){

               account.set(account.get()+money);

            }

           public int getAccount(){

               return account.get();

            }

        }

複製程式碼

注:ThreadLocal與同步機制 

        a.ThreadLocal與同步機制都是為了解決多執行緒中相同變數的訪問衝突問題。 

        b.前者採用以"空間換時間"的方法,後者採用以"時間換空間"的方式

15. 在監視器(Monitor)內部,是如何做執行緒同步的?程式應該做哪種級別的同步?

java虛擬機器中,每個物件(Objectclass)通過某種邏輯關聯監視器,每個監視器和一個物件引用相關聯,為了實現監視器的互斥功能,每個物件都關聯著一把鎖.

一旦方法或者程式碼塊被synchronized修飾,那麼這個部分就放入了監視器的監視區域,確保一次只能有一個執行緒執行該部分的程式碼, 執行緒在獲取鎖之前不允許執行該部分的程式碼

另外java還提供了顯式監視器(Lock)和隱式監視器(synchronized)兩種鎖方案

監視器和鎖在Java虛擬機器中是一塊使用的。監視器監視一塊同步程式碼塊,確保一次只有一個執行緒執行同步程式碼塊。每一個監視器都和一個物件引用相關聯。執行緒在獲取鎖之前不允許執行同步程式碼。

16. 什麼是死鎖(deadlock)

所謂死鎖是指多個進程因競爭資源而造成的一種僵局(互相等待),若無外力作用,這些程序都將無法向前推進。死鎖產生的4個必要條件:

·        互斥條件:程序要求對所分配的資源(如印表機)進行排他性控制,即在一段時間內某資源僅為一個程序所佔有。此時若有其他程序請求該資源,則請求程序只能等待。

·        不剝奪條件:程序所獲得的資源在未使用完畢之前,不能被其他程序強行奪走,即只能由獲得該資源的程序自己來釋放(只能是主動釋放)

·        請求和保持條件:程序已經保持了至少一個資源,但又提出了新的資源請求,而該資源已被其他程序佔有,此時請求程序被阻塞,但對自己已獲得的資源保持不放。

·        迴圈等待條件:存在一種程序資源的迴圈等待鏈,鏈中每一個程序已獲得的資源同時被鏈中下一個程序所請求。

17. 如何確保N個執行緒可以訪問N個資源同時又不導致死鎖?

使用多執行緒的時候,一種非常簡單的避免死鎖的方式就是:指定獲取鎖的順序並強制執行緒按照指定的順序獲取鎖。因此,如果所有的執行緒都是以同樣的順序加鎖和釋放鎖,就不會出現死鎖了。

18. Java集合類框架的基本介面有哪些?

總共有兩大介面:Collection和Map ,一個元素集合,一個是鍵值對集合;其中List和Set介面繼承了Collection介面,一個是有序元素集合,一個是無序元素集合;而ArrayList和 LinkedList 實現了List介面,HashSet實現了Set介面,這幾個都比較常用; HashMap 和HashTable實現了Map介面,並且HashTable是執行緒安全的,但是HashMap效能更好;

19. 為什麼集合類沒有實現CloneableSerializable介面?

克隆(cloning)或者是序列化(serialization)的語義和含義是跟具體的實現相關的。因此,應該由集合類的具體實現來決定如何被克隆或者是序列化。

20. 什麼是迭代器(Iterator)

迭代器是一種設計模式,它是一個物件,它可以遍歷並選擇序列中的物件,而開發人員不需要了解該序列的底層結構。迭代器通常被稱為“輕量級”物件,因為建立它的代價小。  Java中的Iterator功能比較簡單,並且只能單向移動:  (1) 使用方法iterator()要求容器返回一個Iterator。第一次呼叫Iterator的next()方法時,它返回序列的第一個元素。注意:iterator()方法是java.lang.Iterable介面,被Collection繼承。  (2) 使用next()獲得序列中的下一個元素。  (3) 使用hasNext()檢查序列中是否還有元素。  (4) 使用remove()將迭代器新返回的元素刪除。  Iterator是Java迭代器最簡單的實現,為List設計的ListIterator具有更多的功能,它可以從兩個方向遍歷List,也可以從List中插入和刪除元素。

代器模式(Iterator),提供一種方法順序訪問一個聚合物件中的各種元素,而又不暴露該物件的內部表示。 當你需要訪問一個聚合物件,而且不管這些物件是什麼都需要遍歷的時候,就應該考慮使用迭代器模式。另外,當需要對聚集有多種方式遍歷時,可以考慮去使用迭代器模式。迭代器模式為遍歷不同的聚集結構提供如開始、下一個、是否結束、當前哪一項等統一的介面。

21. IteratorListIterator的區別是什麼?

下面列出了他們的區別:
Iterator
可用來遍歷SetList集合,但是ListIterator只能用來遍歷List
Iterator
對集合只能是前向遍歷,ListIterator既可以前向也可以後向。
ListIterator
實現了Iterator介面,幷包含其他的功能,比如:增加元素,替換元素,獲取前一個和後一個元素的索引,等等。

22. 快速失敗(fail-fast)和安全失敗(fail-safe)

相關推薦

java試題筆記

1.   什麼是Java虛擬機器?為什麼Java被稱作是“平臺無關的程式語言”?Java虛擬機器是一個可以執行Java位元組碼的虛擬機器程序。java的跨平臺不是java源程式的跨平臺,如果是這樣,那麼所以語言都是跨平臺的, java源程式先經過javac編譯器編譯成二進位制

Java試題 (整理)

    本文是牛客網的Java面試常考題 本人整理了一下 去除了 Applet Swing RMI 等不常考的 還有比較一些easy的題目。     原文連結  https://www.nowcoder.com/ta/review-java 下面還有精彩的討論  1、什

[Java試題-] 第1-10題

轉載請註明出處第1題:什麼是Java虛擬機器?為什麼Java被稱作是“平臺無關的程式語言”?Java虛擬機器JVM(java virtual machine)是一個執行位元組碼的程式。Java寫的程式碼儲存為字尾為.java的檔案,它會被特定的程式(javac.exe)編譯,

Java試題(三)

請求 其中 默認 查找 重新 技術分享 block 知識 logs     序言        說說今天遇到的一件小事吧,在遇到問題,查找答案時,看到很多人的博客裏面都有提到關鍵字眼,可讓人覺得可恨的是,大多數人寫的博文中,基本上都是照著書上的語言發表的,看了跟沒看一樣,沒

Java試題(一)

div 並且 功能 不出 共享 情況 字符型 對象 java字節碼       序言         我是一只亂飛亂撞的菜鳥,寫的文章目前是以記錄自己學習,和方便以後查看,期待日後不久能通過自己的努力,獲得一點小小的成功,然後寫出我的學習經驗總結性文章來。         

Java試題

class 出了 維護 們的 封裝 cep jdb destroy 輸出 Java集合類框架的基本接口有哪些? 參考答案 集合類接口指定了一組叫做元素的對象。集合類接口的每一種具體的實現類都可以選擇以它自己的方式對元素進行保存和排序。有的集合類允許重復的鍵,有些不允許。

Java試題11 內部類可以引用它的包含類(外部類)的成員嗎?有沒有什麼限制?

問:內部類可以引用它的包含類(外部類)的成員嗎?有沒有什麼限制? 答: 完全可以。如果不是靜態內部類,那沒有什麼限制!如果你把靜態巢狀類當作內部類的一種特例,那在這種情況下不可以訪問外部類的普通成

Java 試題及答案(吐血總結)持續更新...

1、解釋Java面向物件的特徵: 抽象、封裝、繼承、多型。 2、面向物件的好處是什麼? 3、Java常用的關鍵字、修飾符的使用 4、Java中的引數傳遞(值傳遞、引用傳遞) 5、簡述內部類、靜態內部類、匿名內部類的區別 6、try catch finally的

Java試題6 equals相同的物件對於的hashCode是否相等?

問: 兩個物件值相同(x.equals(y) == true),但卻可有不同的hash code,這句話對不對? 答: 不對!! 如果兩個物件x和y滿足x.equals(y) == true,它

Java試題8 深刻認識JAVA過載和重寫 以及是否可以根據返回型別來區分過載

問:過載(Overload)和重寫(Override)的區別。 過載的方法能否根據返回型別進行區分?  答: 方法的過載和重寫都是實現多型的方式,區別在於前者實現的是編譯時的多型性,而後者實現的是執行時的多型性。 過載發生在一個類中,同名的方法如果有不同的引數列表(引數

Java試題3--Java的基本資料型別有哪些?

問:String 是最基本的資料型別嗎? 答:不是。 Java中的基本資料型別只有8個:byte、short、int、long、float、double、char、boolean; 除了基本型別(pr

Java試題4--Java強制型別轉換

問:    float f=3.4;是否正確? 答:    不正確。3.4是雙精度數,將雙精度型(double)賦值給浮點型(float)屬於下轉型(down-casting,也稱為窄化)會造成精度損

Java試題的一些碎片化知識彙總

vs2008 : http://www.pcsoft.com.cn/soft/121335.html 0:方法不能獨立存在 Java裡的方法不能獨立存在,它必須屬於一個類或一個物件,因此方法也不能像函式那樣被獨立執行,執行方法時必須使用類或物件來作為呼叫者,即所有方法都必須使用"類.方法

java刷題10.3

多少 print ray 返回 ++i string 保留 刪除元素 -s 1、定義有StringBuffer s1=new StringBuffer(10);s1.append(“1234”)則s1.length()和s1.capacity()分別是多少? length(

有趣的二進制 java大數的一些方法

ons debug LG c++ 行為 -h 負數 compare ner 鏈接:https://www.nowcoder.com/acm/contest/124/C來源:牛客網 題目描述 小新在學C語言的時候,鄺老師告訴他double類型的數據在表示小數的時候,小

計算機網絡試題總結

計算 art msl csdn 什麽 http協議 net 輸入 控制 這裏先將搜集到的題目列出來,日後一一精細得寫完。 https://blog.csdn.net/u013408431/article/details/62442670 https://blog.csdn.

java部分刷題

普通類是一個完善的功能類,可以直接產生例項化物件,並且在普通類中可以包含有構造方法、普通方法、static方法、常量和變數等內容。而抽象類是指在普通類的結構裡面增加抽象方法的組成部分。 那麼什麼叫抽象方法呢?在所有的普通方法上面都會有一個“{}”,這個表示方法體,有方法體的方法

從一道題看執行緒安全--Java基礎題

從一道題看執行緒安全 Java中的執行緒安全是什麼:   就是執行緒同步的意思,就是當一個程式對一個執行緒安全的方法或者語句進行訪問的時候,其他的不能再對他進行操作了,必須等到這次訪問結束以後才能對這個執行緒安全的方法進行訪問。 什麼叫執行緒安全:   如果你的程式碼所在的程序中有多個執行緒在同時

HTTP試題

HTTP與HTTPS的區別 HTTP 的URL 以http:// 開頭,而HTTPS 的URL 以https:// 開頭 HTTP 是不安全的,而 HTTPS 是安全的 HTTP 標準埠是80 ,而 HTTPS 的標準埠是443 在OSI 網路模型中,HTTP工

Java刷題知識點之equals和hashcode()

不多說,直接上乾貨!   說簡單點,就是,先對hashcode,然後對eauals。   以下是HashMap的jdk1.6   :    以下是HashMap的jdk1.7  :    以下是HashMap