1. 程式人生 > >【面經】京東金融一面涼經

【面經】京東金融一面涼經

專案

1.你講一下你的秒殺專案?

2.秒殺最重要的點在哪?你說一下

3.你怎麼保證你的redis每個執行緒取商品庫存的時候的併發性不會出錯? setnx   那setnx怎麼用的?後續?redis的setnx鎖到了超時時間失效,併發的問題

框架

1.看你用過springboot,瞭解springcloud嗎? 不瞭解 微服務? 

java基礎

1.鎖synchronized ReentrantLock

2.併發包下的ConcurrentHashMap實現原理,以及內部資料結構 segment是什麼結構?

3.併發包下 AtomicInteger利用什麼實現?說一下CAS+volatile

3.HashMap的擴容resize()方法,講一下

4.讓你設計一個如何讓一個物件轉化為json串? --提示,利用反射   fastjson的實現?

5.ThreadLocal你覺得是解決什麼樣場景下的問題的? 執行緒私有資料,資料隔離------那麼ThreadLocal的key是怎麼儲存的?怎麼保證是執行緒之間不衝突的????

計算機網路
1.http中get 和post的區別?--面試官認為get不安全不是get的問題,是http本身的原因?不是很懂什麼意思

作業系統

1.一句話說明程序和執行緒的區別???

2.程序之間的通訊方式

Linux 

1.查詢程序的命令。。。說了半天ps 後面加什麼,沒明白,用的也不多

2.檢視檔案的命令

資料庫

1.資料庫的隔離級別,InnoDB的預設的使用的隔離界別

2.jdbc 如何操作? jdbc的事務如何操作

3.索引,聯合索引的訪問?如果用A,B,C同時建立索引,查詢的時候是 select  A andB? A and C? B and C? 你認為哪個用到索引,哪個沒有用到,哪個用全部索引,哪個用部分索引?

面試問題解答:

1.你怎麼保證你的redis每個執行緒取商品庫存的時候的併發性不會出錯? setnx   那setnx怎麼用的?後續?redis的setnx鎖到了超時時間失效,併發的問題?

SETNX key value

將 key 的值設為 value ,當且僅當 key 不存在。

若給定的 key 已經存在,則 SETNX 不做任何動作。

SETNX 是『SET if Not eXists』(如果不存在,則 SET)的簡寫。

可用版本:

>= 1.0.0

時間複雜度:

O(1)

返回值:

設定成功,返回 1 。

設定失敗,返回 0 。

利用Setnx實現分散式鎖,當一個key使用Setnx會隱式的給key加上鎖,讓其他執行緒在獲取這個key的時候進行阻塞。

具體:

setnx lock.key < currentTime + lockexpiretime+1>  可以加鎖,也可以在加鎖的同時為鎖加上過期時間。

java程式碼:Jedis 

public class SimpleRedisLock {

    public static ThreadLocal<Jedis> holder = new ThreadLocal<>();

    public static JedisPool jedisPool = new JedisPool(new JedisPoolConfig(), "localhost");

    public static void acquire(String lock){
        Jedis jedis = jedisPool.getResource();
        while(jedis.setnx(lock, "") == 0){   //上鎖並設定過期時間
            System.out.println(Thread.currentThread().getName()+"我卡在了jedis.setnx(lock,");
        }     //set and if not exist 設定key並判斷是否存在
        holder.set(jedis);
    }

    public static void release(String lock){
        Jedis jedis = holder.get();
        jedis.del(lock);
        jedis.close();
    }

}

key的上鎖與釋放,在獲取該key並對其操作的時候,先用acquire()方法判斷是否能夠獲取鎖,若能夠獲取鎖(返回值1),那麼執行業務操作,若拿不到(返回值0),那麼等待。

當操作完了,通過redis中del方法,刪除鎖來釋放。

常見問題:setnx死鎖--出現情況:當一個執行緒獲取鎖後, 並在過期時間內崩潰,那麼這個執行緒會一直持有鎖,其他執行緒無法獲得鎖、

解決方法:不能夠簡單的獲取鎖的時間戳,這樣會導致多執行緒競態,導致多個執行緒同時獲取鎖

我們可以通過鎖的鍵對應的時間戳來判斷這種情況是否發生了,如果當前的時間已經大於lock.foo的值,說明該鎖已失效,可以被重新使用。 

發生這種情況時,可不能簡單的通過DEL來刪除鎖,然後再SETNX一次,當多個客戶端檢測到鎖超時後都會嘗試去釋放它,這裡就可能出現一個競態條件,讓我們模擬一下這個場景: 

C0操作超時了,但它還持有著鎖,C1和C2讀取lock.foo檢查時間戳,先後發現超時了。 
C1 傳送DEL lock.foo 
C1 傳送SETNX lock.foo 並且成功了。 
C2 傳送DEL lock.foo 
C2 傳送SETNX lock.foo 並且成功了。 
這樣一來,C1,C2都拿到了鎖!問題大了! 

需要利用到:GETSET():GETSET lock.foo <current Unix time + lock timeout + 1> 

GETSET()方法,在獲取鎖的同時,利用當前時間更新其鎖的過期時間。這樣若有一個執行緒檢測出c1執行緒死鎖,鎖時間過期,那麼c2這個執行緒執行getset()方法後, 獲取鎖,同時更新鎖的過期時間,當下一個執行緒進來後,發現鎖未到期,那麼就不會發生鎖的爭搶。