1.StringBuffer和StringBuilder有什麼區別?假設有一個方法,方法內部需要定義一個對象,可能是StringBuffer或StringBuilder,接下來會多次append操作,方法結束時,返回這個對象的toString()結果,並且這個線程會被多線程並發訪問,請選擇這個對象是被定義成StringBuffer或者StringBuilder?為什麼?
答:StringBuffer是線程安全的;StringBuilder是線程不安全的。
1.先來看String StringBuffer StringBuilder定義。final修飾的類不能被繼承,即不能擁有子類。 public final class StringBuffer public final class StringBuilder public final class String 2.關於appdend方法的源碼如下: public synchronized StringBuffer append(String str) { toStringCache = null; super.append(str); return this; } public StringBuilder append(String str) { super.append(str); return this; } 3.對於經常變動的字符串才會考慮使用StringBuilder和StringBuffer,使用StringBuilder效率比StringBuffer高,StringBuffer可以保證線程安全,而StringBuilder不能。
2.synchronized有什麼用?如何使用?(偽代碼,把所有使用方式都分別列出來)
答:synchronized是Java語言的關鍵字,同時也是一個可重入鎖。當它用來修飾一個方法或者一個代碼塊的時候,能夠保證在同一時刻最多只有一個線程執行該段代碼。synchronized用於修飾方法和代碼塊(對象鎖和成員鎖)。
package basic; public final class TestSynchronized { public static void main(String[] args) { new Thread("線程A") { @Override public void run() { try { print("線程A ..."); } catch (InterruptedException e) { e.printStackTrace(); } } }.start(); new Thread("線程B") { @Override public void run() { try { print("線程B ..."); } catch (InterruptedException e) { e.printStackTrace(); } } }.start(); } public static synchronized void print(String str) throws InterruptedException { System.out.println("當前線程:" + Thread.currentThread().getName() + "執行開始"); for (int i = 0; i < 10; i++) { System.out.println(str); Thread.sleep(2000); } System.out.println("當前線程:" + Thread.currentThread().getName() + "執行完畢"); } } //代碼執行結果: 當前線程:線程A執行開始 線程A ... 線程A ... 線程A ... 線程A ... 線程A ... 線程A ... 線程A ... 線程A ... 線程A ... 線程A ... 當前線程:線程A執行完畢 當前線程:線程B執行開始 線程B ... 線程B ... 線程B ... 線程B ... 線程B ... 線程B ... 線程B ... 線程B ... 線程B ... 線程B ... 當前線程:線程B執行完畢 synchronized修飾方法synchronized在修飾方法的同時,還可以修飾代碼塊。在修飾代碼塊的時候,分為對象鎖和成員鎖。接下來分別看代碼實現如下:
package basic; public class SynchronizedExample { public static void main(String[] args) { new Thread("線程A") { @Override public void run() { print("線程A"); } }.start(); new Thread("線程B") { @Override public void run() { print("線程B"); } }.start(); } public static void print(String str) { System.out.println("線程: " + Thread.currentThread().getName() + "開始執行"); synchronized (SynchronizedExample.class) { for (int i = 0; i < 10; i++) { System.out.println(Thread.currentThread().getName() + "打印了信息:" + i); try { Thread.sleep(1000); } catch (InterruptedException e) { } } } System.out.println("線程: " + Thread.currentThread().getName() + "執行結束"); } } // 代碼執行結果: 線程: 線程A開始執行 線程A打印了信息:0 線程: 線程B開始執行 線程A打印了信息:1 線程A打印了信息:2 線程A打印了信息:3 線程A打印了信息:4 線程A打印了信息:5 線程A打印了信息:6 線程A打印了信息:7 線程A打印了信息:8 線程A打印了信息:9 線程: 線程A執行結束 線程B打印了信息:0 線程B打印了信息:1 線程B打印了信息:2 線程B打印了信息:3 線程B打印了信息:4 線程B打印了信息:5 線程B打印了信息:6 線程B打印了信息:7 線程B打印了信息:8 線程B打印了信息:9 線程: 線程B執行結束 synchronized 對象鎖 示例代碼(只針對類的當前實例)
接下來再看,
package basic; public class SynchronizedExample { public static void main(String[] args) { final MySynchronized mySynchronized = new MySynchronized(); new Thread("線程A") { @Override public void run() { mySynchronized.print("線程A"); } }.start(); new Thread("線程B") { @Override public void run() { mySynchronized.print("線程B"); } }.start(); } } class MySynchronized { public synchronized void print(String str) { System.out.println("線程: " + Thread.currentThread().getName() + "開始執行"); for (int i = 0; i < 10; i++) { System.out.println(Thread.currentThread().getName() + "打印了信息:" + i); try { Thread.sleep(1000); } catch (InterruptedException e) { } } System.out.println("線程: " + Thread.currentThread().getName() + "執行結束"); } } //代碼運行結果: 線程: 線程A開始執行 線程A打印了信息:0 線程A打印了信息:1 線程A打印了信息:2 線程A打印了信息:3 線程A打印了信息:4 線程A打印了信息:5 線程A打印了信息:6 線程A打印了信息:7 線程A打印了信息:8 線程A打印了信息:9 線程: 線程A執行結束 線程: 線程B開始執行 線程B打印了信息:0 線程B打印了信息:1 線程B打印了信息:2 線程B打印了信息:3 線程B打印了信息:4 線程B打印了信息:5 線程B打印了信息:6 線程B打印了信息:7 線程B打印了信息:8 線程B打印了信息:9 線程: 線程B執行結束 package basic; public class SynchronizedExample { public static void main(String[] args) { final MySynchronized mySynchronized_first = new MySynchronized(); final MySynchronized mySynchronized_second = new MySynchronized(); new Thread("線程A") { @Override public void run() { mySynchronized_first.print("線程A"); } }.start(); new Thread("線程B") { @Override public void run() { mySynchronized_second.print("線程B"); } }.start(); } } class MySynchronized { public synchronized void print(String str) { System.out.println("線程: " + Thread.currentThread().getName() + "開始執行"); for (int i = 0; i < 10; i++) { System.out.println(Thread.currentThread().getName() + "打印了信息:" + i); try { Thread.sleep(1000); } catch (InterruptedException e) { } } System.out.println("線程: " + Thread.currentThread().getName() + "執行結束"); } } //代碼運行結果: 線程: 線程A開始執行 線程A打印了信息:0 線程: 線程B開始執行 線程B打印了信息:0 線程A打印了信息:1 線程B打印了信息:1 線程A打印了信息:2 線程B打印了信息:2 線程A打印了信息:3 線程B打印了信息:3 線程A打印了信息:4 線程B打印了信息:4 線程A打印了信息:5 線程B打印了信息:5 線程A打印了信息:6 線程B打印了信息:6 線程A打印了信息:7 線程B打印了信息:7 線程A打印了信息:8 線程B打印了信息:8 線程A打印了信息:9 線程B打印了信息:9 線程: 線程A執行結束 線程: 線程B執行結束 package basic; public class SynchronizedExample { public static void main(String[] args) { final MySynchronized mySynchronized_first = new MySynchronized(); final MySynchronized mySynchronized_second = new MySynchronized(); new Thread("線程A") { @Override public void run() { mySynchronized_first.print("線程A"); } }.start(); new Thread("線程B") { @Override public void run() { mySynchronized_second.print("線程B"); } }.start(); } } class MySynchronized { public static synchronized void print(String str) { System.out.println("線程: " + Thread.currentThread().getName() + "開始執行"); for (int i = 0; i < 10; i++) { System.out.println(Thread.currentThread().getName() + "打印了信息:" + i); try { Thread.sleep(1000); } catch (InterruptedException e) { } } System.out.println("線程: " + Thread.currentThread().getName() + "執行結束"); } } //代碼運行結果: 線程: 線程A開始執行 線程A打印了信息:0 線程A打印了信息:1 線程A打印了信息:2 線程A打印了信息:3 線程A打印了信息:4 線程A打印了信息:5 線程A打印了信息:6 線程A打印了信息:7 線程A打印了信息:8 線程A打印了信息:9 線程: 線程A執行結束 線程: 線程B開始執行 線程B打印了信息:0 線程B打印了信息:1 線程B打印了信息:2 線程B打印了信息:3 線程B打印了信息:4 線程B打印了信息:5 線程B打印了信息:6 線程B打印了信息:7 線程B打印了信息:8 線程B打印了信息:9 線程: 線程B執行結束 synchronized 對象鎖 示例代碼 (單純用synchronized修飾代碼塊,)
3.ReentranLock類有什麼作用?它常用的方法有哪幾個?分別有什麼特點?
4.集群環境下多機器間進行同步操作有什麼可選的解決方案?(最好用偽代碼寫出關鍵部分)
5.列出樂觀鎖的設計要點和使用方法?
6.何為冪等性控制?舉一個例子說明你之前如何實現冪等性控制?(或在項目IDCM中如何實現冪等性控制?)
7.spring實現aop用到的關鍵技術是什麼?
8.HashMap和ConcurrentHashMap有什麼區別和特點?
9.java.util.concurrent package下,你用過哪些類?分別有什麼用途和特點?
10.如果一張表數據量較大,影響了查詢性能,可以有哪些優化方案?建立索引有什麼原則?
11.說一說數據庫事務隔離級別的理解?(項目IDCM中是如何使用的?)
12.Spring中注解@Component @Repository @Service @Controller的區別?(項目IDCM中context:component-scan注解掃描是如何配置的?)