1. 程式人生 > >花果山第一屆猿類分級考試實錄--Talk is cheap,Show me the code

花果山第一屆猿類分級考試實錄--Talk is cheap,Show me the code

本故事純屬虛構,如有雷同,純屬巧合!

故事背景

 

悟空師徒4人取經回來後,因不耐收到管教,就回到了花果山,帶領一幫猴子猴孫逍遙自在的過日子,奈何因在閻王殿裡將生死薄中的猴子猴孫的名字都劃去了,猴子猴孫是越來越多。

 

悟空最是沒有耐心的,無法一一管教,隨向太白金星討教。

 

猿類分級考試

太白金星給了主意:考試分級。

並且給出了題目:

建立一個通用的計數器,能計量很多的東西,如金箍棒。

 

參考答案如下:

猿類分階:一~九等級 依次上升

一階猿類

public class Counter1 {
    private static int cnt=0;
    
    public int increase() {
        return ++cnt;
    }
    
    public int decrease() {
        return --cnt;
    }    
    
}

 

旁白:實現了功能。

二階猿類

public class Counter2 {
    private static long cnt=0;
    
    public long increase() {
        return ++cnt;
    }
    
    public long decrease() {
        return --cnt;
    }        
}

 

旁白:考慮了int的範圍限制,long的範圍更廣泛。

三階猿類

public class Counter3 {
    private static long cnt=0;
    
    public synchronized long increase() {
        return ++cnt;
    }
    
    public synchronized long decrease() {
        return --cnt;
    }        
}

 

旁白:考慮了併發環境下的執行

四階猿類

public class Counter4 {
    private static AtomicLong cnt=new AtomicLong(0);
    
    public long increase() {
        return cnt.getAndIncrement();
    }
    
    public long decrease() {
        return cnt.getAndDecrement();
    }        
}

 

旁白:考慮了併發環境下的cas效能更優

五階猿類

public class Counter5 {
    private static LongAdder cnt=new LongAdder();
    
    public long increase() {
        cnt.increment();
        return cnt.longValue();
    }
    
    public long decrease() {
         cnt.decrement();
         return cnt.longValue();
    }        
}

 

旁白:在單執行緒下,併發問題沒有暴露,兩者沒有體現出差距;隨著併發量加大,LongAdder 的 increment 操作更加優秀,而 AtomicLong 的 get 操作則更加優秀。鑑於在計數器場景下的特點—寫多讀少,所以寫效能更高的 LongAdder 更加適合。

六階猿類

public class Counter6 {
    private static JdbcTemplateUtils jdbc=new JdbcTemplateUtils();
    private static long cnt=0;
    
    public long increase() {
        cnt=jdbc.getCnt();    
        return jdbc.setCnt(++cnt);
    }
    
    public long decrease() {
         cnt=jdbc.getCnt();
         return jdbc.setCnt(--cnt);;
    }        
}

 

旁白:考慮了在叢集環境下保證資料的唯一性和一致性。

七階猿類

public class Counter7 {
    private static RedisclusterUtils redis=new RedisclusterUtils();
    private static long cnt=0;
    
    public long increase() {    
        return redis.incr(cnt);
    }
    
    public long decrease() {
         return redis.decr(cnt);;
    }        
}

 

旁白:考慮了計數器叢集下的併發效能問題,同樣的實現可以使用zk或者mongo等記憶體資料庫。

八階猿類

public class Counter8 {
    private static JdbcTempalteUtils jdbc=new JdbcTempalteUtils();
    private static RedisclusterUtils redis=new RedisclusterUtils();
    private static long cnt=0;
    
    public long increase() {    
        if(redis.exsits(cnt)) {
            return redis.incr(cnt);
        }
        cnt=jdbc.getCnt(key);
        ++cnt;
        redis.set(key,cnt);
        
        return cnt;
    }
    
    public long decrease() {
        if(redis.exsits(cnt)) {
            return redis.decr(cnt);
        }
        cnt=jdbc.getCnt(key);
        --cnt;
        redis.set(key,cnt);
        
        return cnt;
    }        
}

 

旁白:考慮到redis宕機或者不可用的情況下的處理,有備份方案。

九階猿類

這個要免考的。

 

參考資料:

【1】https://mp.weixin.qq.com/s/yAvJFZWxfKb38IDMjQ