代碼塊執行順序:
1、靜態代碼—》父類構造函數—》子類構造函數
2、HashMap實現原理及特點
答:HashMap基於hashing原理,我們通過put()和get()方法儲存和獲取對象。當我們將鍵值對傳遞給put()方法時,它調用鍵對象的hashCode()方法來計算hashcode,讓後找到bucket位置來儲存值對象。當獲取對象時,通過鍵對象的equals()方法找到正確的鍵值對,然後返回值對象。HashMap使用鏈表來解決碰撞問題,當發生碰撞了,對象將會儲存在鏈表的下一個節點中。 HashMap在每個鏈表節點中儲存鍵值對對象。
當兩個不同的鍵對象的hashcode相同時會發生什麼? 它們會儲存在同一個bucket位置的鏈表中。鍵對象的equals()方法用來找到鍵值對。
因爲HashMap的好處非常多,我曾經在電子商務的應用中使用HashMap作爲緩存。因爲金融領域非常多的運用Java,也出於性能的考慮,我們會經常用到HashMap和ConcurrentHashMap。
特點:允許鍵和值爲null
線程不安全
實現Map接口
HashMap存儲着Entry(hash,key,value,next)對象
3、單例模式
線程安全,比較常用,但容易產生垃圾,因爲一開始就初始化
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton (){}
public static Singleton getInstance() {
return instance;
}
}
線程安全,延遲初始化。這種方式採用雙鎖機制,安全且在多線程情況下能保持高性能。
public class Singleton {
private volatile static Singleton singleton;
private Singleton (){}
public static Singleton getSingleton() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
Volatile能使變量變爲可見性(即一個線程A修改一個共享變量後,能保證線程B讀取到最新值。
選擇題注意點:
List的remove方法
List.remove(int i);移除指定位置的元素;
List.remove(object o);移除指定元素;
編程
1、線程A向有界隊列Q中不停寫入數據,線程B從有界隊列中不停讀取數據
package com.hieu.cxh.limitqueue;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
/**
* @author cxh
* @version JDK1.8.0_171
* @date on 2018/10/26 14:21
* @descrption
*/
public class BlockQueueDemo {
public static void main(String[] args) {
final BlockingQueue queue = new ArrayBlockingQueue(3);//線性阻塞有界隊列
//for(int i=0;i<2;i++){
new Thread(){
public void run(){
while(true){
try {
Thread.sleep((long) (Math.random()*1000));
System.out.println(Thread.currentThread().getName() + "準備放數據!");
queue.put(1);
System.out.println(Thread.currentThread().getName() + "已經放了數據," +
"隊列目前有" + queue.size() + "個數據");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
//}
new Thread(){
public void run(){
while(true){
try {
//將此處的睡眠時間分別改爲100和1000,觀察運行結果
Thread.sleep(100);
System.out.println(Thread.currentThread().getName() + "準備取數據!");
queue.take();
System.out.println(Thread.currentThread().getName() + "已經取走數據," +
"隊列目前有" + queue.size() + "個數據");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
}
2、請簡單寫出使用Java語言連接MySQL數據庫的代碼片段,並使用分頁查詢獲取第二頁的數據(每頁10條)將獲取到的結果集打印在控制檯。
public class JDBC {
private static final int pagesize = 10;
public static void main(String[] args) {
int page = 2;
try {
Class.forName("com.mysql.jdbc.Driver");
String databaseName = "phildatabase";// 已經在MySQL數據庫中創建好的數據庫。
String userName = "root";// MySQL默認的root賬戶名
String password = "";// 默認的root賬戶密碼爲空
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/" + databaseName, userName, password);
String sql = "select * from test limit ?,?";
PreparedStatement pre = conn.prepareStatement(sql);
//pre.setMaxRows(page*pagesize);設置最多查詢多少行
pre.setInt(1, (page-1)*pagesize);
pre.setInt(2, pagesize);
ResultSet rs = pre.executeQuery(sql);
//rs.relative((page-1)*pagesize);使遊標移到當前頁的第一條數據
while (rs.next()) {
System.out.println(rs.getString(1) + "\t" + rs.getString(2));
}
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}