1. 程式人生 > >【ForOffer】面試題基礎總結(3)

【ForOffer】面試題基礎總結(3)

  1. 介面是不能例項化的,但是可以例項化介面的類的物件。比如 Map m = new hashMap()。

  2. 什麼是執行緒?與程序有什麼區別?為什麼要使用多執行緒?

    1. 執行緒是一個程度執行過程中,能夠執行程式程式碼的一個執行單元。有四種狀態:執行,掛起,就緒,結束。

    2. 程序是指的一段正在執行的程式。

    3. 執行緒有時候被稱為輕量級的程序,他是程式執行的最小單元。

      1. 一個程序可以擁有多個執行緒,各個執行緒之間共享程式的記憶體空間,及一些程序級別的資源,

      2. 各個執行緒擁有自己的棧空間。

    4. 使用多執行緒的好處:

      1. 可以減少程式響應時間。

      2. 與程序相比,執行緒的建立和切換開銷更小。

      3. 多cpu和多核計算機本身就具有執行多執行緒的能力。

      4. 簡化程式結構,使得程式便於理解和維護。

  3. 同步非同步的區別

    1. 同步機制保證資源安全。

      1. 實現同步方式:

        1. 利用同步程式碼塊實現同步,

        2. 實現同步方法實現同步

    2. 非同步可以在不希望讓程式等待方法返回時,應該使用非同步程式設計,非同步能提高程式的效率

  4. 如何實現java多執行緒?(重要!!!面試寶典P144 )

    1. 繼承Thread類,重寫run()方法

    2. 實現Runnable介面,並且實現該介面的run()方法

    3. 實現Callable介面,重寫Call()方法。

      1. Collable介面實際是屬於Executor框架中的功能類,與Runnable介面的功能類似,但是提供了閉Runnable更強大的功能:

        • Callable可以在人物結束後提供一個返回值,Runnable無法提供這個功能

        • Callable中的call()方法可以丟擲異常,而Runnable的run()方法不能丟擲異常。

        • 執行Callable可以拿到一個Future物件,Future物件表示非同步計算的結果,他提供檢查計算時候完成的方法

  5. run()方法和start()方法的區別?

    1. 通常,系統通過呼叫執行緒類的start()方法來啟動一個執行緒,此時執行緒處於就緒狀態,而非執行狀態,也就是意味著了這個執行緒可以被JVM來排程使用。在排程過程中,JVM通過呼叫執行緒類的run()方法,來完成實際的操作,當run()方法結束後,此執行緒就會終止。

    2. start()方法能夠非同步呼叫run()方法,但是直接呼叫run()方法卻是同步的,因此無法達到多執行緒的目的。

  6. 多執行緒同步的實現方法有哪些?

    1. synchronized關鍵字

      1. synchronized方法

      2. synchronized塊

synchronized(syncObject){

    //訪問syncObject的程式碼

}

   2.wait()方法與notify()方法

    在synchronized程式碼被執行期間,執行緒可以呼叫物件的wait()方法,釋放物件鎖,進入等待狀態,並且可以呼叫notify()方法或nitifyAll()方法通知正在等待的其他執行緒。

    notify()喚醒一個執行緒(等待對了中的第一個執行緒)並允許它去獲得鎖,

   notifyAll()方法喚醒所有等待這個物件的執行緒並允許它們去獲得鎖(並不是所有喚醒的執行緒都能獲得鎖,而是讓他們去競爭)。

    3.Lock

     1、lock()。阻塞方式獲得鎖,獲得就返回,如果別的執行緒持有鎖,那就繼續等待。

     2、tryLock()。非阻塞方式獲得鎖,嘗試去獲得,如果獲得就返回true,否則立即返回false

     3、tryLock(long timeout,TimeUnit unit)如果獲得鎖立即返回true,否則等待引數給定的世家單元,在等待過程中,如果獲得鎖,也返回true,如果等待超時,返回false。

     4、lockInterruptibly(),如果獲得鎖,立即返回,沒有獲得鎖當期執行緒處於休眠狀態。直到獲得鎖,或者當前執行緒被別的執行緒中斷。該方法與Lock()不同的是,Lock沒有獲得鎖會一直處於阻塞狀態,且會忽略interrupt()方法。

  1. sleep()與wait()方法的區別?

    1. 原理不同。

      1. sleep(是Thread類的靜態方法,是執行緒用來控制自身流程的)會是此執行緒暫停一段時間,把執行機會交給別的執行緒,等計時時間一到,此執行緒自動“甦醒”

      2. wait()方法時是Object類的方法,用於執行緒間的通訊,這個方法會使得當前的擁有該物件鎖的程序等待,知道其他執行緒呼叫notify()或notifyAll()方法醒過來。

    2. 對鎖的處理機制不同。

      1. 呼叫sleep()不釋放物件鎖

      2. wait()會釋放鎖。

    3. 使用區域不同。

      1. wait()方法必須放在同步控制方法或同步語句塊中使用。

      2. sleep()方法任何地方都能用。

  2. sleep()與yield()方法的區別?

    1. sleep()方法給其他執行緒執行機會時不考慮執行緒的優先順序,所以低優先順序的執行緒也有獲得執行的機會。

      yield()方法只會給相同的優先順序或更高優先順序的執行緒以執行的機會。

    2. 執行緒執行sleep()方法後轉入阻塞狀態,所以在指定的時間內,執行緒執行了sleep()方法字元肯定不會被執行的。

      yield()方法只是使當前執行緒重新回到可執行狀態,所以執行yield()方法,有可能在進入到可執行狀態後馬上又被執行。

    3. sleep()方法宣告丟擲InterruptException

      yield()方法沒有宣告任何異常

    4. sleep()方法比yield()方法(跟作業系統相關)具有更好的可移植性。

  3. 終止執行緒的方法有哪些?

    1. stop()。Thread.stop()來終止執行緒時,會釋放已經鎖定的所有監視的資源,可能會導致程式執行的不確定性。

    2. suspend()。呼叫suspend()方法,容易發生死鎖。

  4. synchronized與Lock有什麼異同?

    1. 用法不一樣:synchronized是託管誒JVM執行的,而Lock的鎖定是通過程式碼實現的。

    2. 效能不一樣:JDK5.0中引入的ReetrantLock,如果資源競爭激烈,synchronized效能下降的非常快,而ReetrantLock的效能基本保持不變。

    3. 鎖機制不一樣。synchronized獲得多個鎖之後,按照相反的順序釋放,並且是自動釋放,不會因為異常導致鎖沒有釋放導致死鎖。Lock則需要開發人員手動去釋放,並且必須在finally塊中是否,否則引起死鎖。

  5. 什麼是守護執行緒?

    1. 任何一個守護執行緒都是整個JVM中所有非守護執行緒的“保姆”。

    2. 將一個使用者執行緒設定為守護執行緒的方法:在呼叫start()方法之前,呼叫物件的setDaemon(true)。

    3. 當一個守護執行緒中產生了其他執行緒,那麼這些新產生的執行緒預設還是守護執行緒。使用者執行緒也是如此。

  6. join()方法的作用是什麼?

    1. 將兩個執行緒合併,用於實現同步功能。

  7. 通過jdbc訪問資料庫步驟?

    1. 載入jdbc驅動器。

    2. 載入jdbc驅動,並將其註冊到DriverManager中,一般試用反射Class.forName(String driverName)

    3. 鍵入資料庫連線,取得Connection物件,一般通過DriverManager.getConnection(url,username,passwd)方法實現。

    4. 建立Statement物件或是preparedStatement物件

    5. 執行sql語句

    6. 訪問結果集ResultSet物件

    7. 依次將ResultSet,Statement,PreparedStatement,Connection物件關閉,釋放掉所佔的資源。

  8. sql中,on和where的區別

    • 在使用left jion時,on和where條件的區別如下:

    • on條件是在生成臨時表時使用的條件,它不管on中的條件是否為真,都會返回左邊表中的記錄。

    • where條件是在臨時表生成好後,再對臨時表進行過濾的條件。這時已經沒有left join的含義(必須返回左邊表的記錄)了,條件不為真的就全部過濾掉。

  9. 什麼是執行緒區域性變數(thread-local variable)?

    1. 執行緒區域性變數高效地為每個使用它的執行緒提供單獨的執行緒區域性變數值的副本。每個執行緒只能看到與自己相聯絡的值,而不知道別的執行緒可能正在使用或修改它們自己的副本。一些編譯器(例如 Microsoft Visual C++ 編譯器或 IBM XL FORTRAN 編譯器)用儲存類別修飾符(像 static 或 volatile )把對執行緒區域性變數的支援整合到了其語言中。Java 編譯器對執行緒區域性變數不提供特別的語言支援;相反地,它用 ThreadLocal 類實現這些支援, 核心 Thread 類中有這個類的特別支援。