模擬面試題

陳俊成發表於2016-10-18

這是我自己在求職路上積累下來的經典面試筆試題。

  1. 說明執行緒和程式的區別
    答:程式是一個在計算機上執行的程式例項,由程式程式碼和資料集組成,它是能分配給處理器並由處理器排程的實體,程式擁有對資源的控制權和擁有權;執行緒是輕量級程式,由執行緒ID、當前指令集和堆疊組成,它是被系統獨立分派和排程的最小單位,執行緒不擁有自己的系統資源,只擁有一點在執行中必不可少的資源,它與在同一個程式中的執行緒共享資源。

  2. 寫一個死鎖的例子

A類,實現Runnable介面

package cn.review.deadLock.two;

public class A implements Runnable{
    private B b;

    public A(){

    }

    public B getB() {
        return b;
    }

    public void setB(B b) {
        this.b = b;
    }

    public synchronized void foo(B b){
        System.out.println("進入A類的foo()方法");

        //睡眠
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("A類例項睡眠結束,企圖呼叫引數B類例項的last方法");
        b.last();

    }

    public synchronized void last(){
        System.out.println("A類例項的last()方法");
    }

    @Override
    public void run() {
        foo(b);
    }
}

B類,實現Runnable介面

package cn.review.deadLock.two;

public class B implements Runnable{
    private A a;
    public B(){

    }

    public A getA() {
        return a;
    }

    public void setA(A a) {
        this.a = a;
    }

    public synchronized void bar(A a){
        System.out.println("進入B類的bar()方法");
        //睡眠
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("睡眠結束,企圖呼叫引數A類例項的last()方法");
        a.last();
    }

    public synchronized void last(){
        System.out.println("B類例項的last()方法");
    }

    @Override
    public void run() {
        bar(a);
    }


}

測試類Test1,出現死鎖

package cn.review.deadLock.two;

import org.junit.Test;

public class Test1 {
    public static void main(String[] args) {
        A a = new A();
        B b = new B();

        a.setB(b);
        b.setA(a);

        Thread ta = new Thread(a);
        Thread tb = new Thread(b);
        ta.start();
        tb.start();
    }

}
  1. 說說synchronized和volatile的區別
    synchronized意為同步,是一個方法或塊的修飾符,synchronize分為方法同步和塊同步;volatile是一個變數修飾符,被volatile修飾的變數不允許從主存中將自己的變數拷貝到自己的儲存空間(暫存器)。它們的區別是:
    (1)volatile本質上是告訴jvm當前變數的暫存器的值是不準確的,需要到主存中去取值;而synchronized鎖定當前變數,只有當前執行緒才可以訪問這個變數,其他執行緒將被阻塞。
    (2)volatile只能修飾變數;synchronized不僅可以鎖定某個變數,也可以鎖定當前物件或者整個類的class物件
    (3)volatile僅能實現操作的可見性,不能實現操作的原子性;synchronized不僅可以實現操作的可見性,同時也能實現操作的原子性。
    (4)volatile不會造成執行緒阻塞,而synchronized會造成執行緒阻塞。
    (5)volatile標記的變數不會被編譯器優化,而synchronized標記的變數會被編譯器優化。

  2. HashMap、Hashtable的區別
    (1)歷史問題。Hashtable是jdk1出現的,繼承於Directory,那時候還沒出現集合框架;HashMap是jdk2出現的,繼承於AbstractMap,屬於集合框架。注意Hashtable沒有駝峰型。
    (2)null值問題。Hashtable的key和value都不能是null值,而HashMap的key可以是null,但是隻能有一個,value允許時null。
    (3)執行緒安全問題。Hashtable裡面的很多方法都用synchronized標記,故它是執行緒安全的;HashMap裡面的方法並沒有用synchronized標記,故它是執行緒不安全的。所以,Hashtable的效能沒有HashMap高。
    (4)擴容問題。Hashtable的初始容量是11,當需要擴容時,擴容公式是int newCapacity = oldCapacity * 2 + 1;;HashMap的初始容量是16,當需要擴容時,擴容公式是int newCapacity = oldCapacity * 2。注意,擴容時會印象效能的。

  3. 什麼是資料庫索引?它有什麼優點,有什麼缺點?
    索引是建立資料庫表物件上的,由表中的一個欄位或多個欄位生成的鍵組成,這些鍵儲存在資料結構中,索引分為B樹索引和雜湊索引。
    優點:
    (1)大大加快資料的檢索速度;
    (2)建立唯一性索引,保證資料庫表中每一行資料的唯一性;
    (3)加速表和表之間的連線;
    (4)在使用分組和排序子句進行資料檢索時,可以顯著減少查詢中分組和排序的時間
    缺點:
    (1)索引需要佔用物理空間
    (2)當對錶中的資料進行增加、刪除和修改的時候,索引也要動態的維護,降低了資料的維護速度

  4. 、什麼是資料庫注入?
    利用某些資料庫的外部介面將使用者資料插入到實際的資料庫操作語言中,從而達到入侵資料庫乃至作業系統的目的。比如那麼使用者賬號名密碼登入

  5. String、StringBuffer、StringBuilder的區別
    (1)String是不可變類,每次對String物件進行操作,實際上都是在建立一些新的物件;StringBuffer與StringBuilder,他們是字串變數,是可改變的物件,每當我們用它們對字串做操作時,實際上是在一個物件上操作的。
    (2)在執行速度方面。StringBuilder>StringBuffer>String
    (3)執行緒安全方面。StringBuffer是執行緒安全的,StringBuilder是執行緒不安全的。
    對於三者使用的總結:
    1.如果要操作少量的資料用 = String
      2.單執行緒操作字串緩衝區 下操作大量資料 = StringBuilder
      3.多執行緒操作字串緩衝區 下操作大量資料 = StringBuffer
  6. 、同步和非同步的區別

相關文章