天天看點

今天阿裡巴巴讓我線上程式設計

與阿裡巴巴的面試也有好幾次了,最早是在好幾年前,我初出茅廬,電話面試啥也不懂。都是心酸史。今天阿裡巴巴讓我線上寫一段程式,在一個網頁上,他們能線上看見我在寫什麼。

題目是:實作一個緩存容器,支援容量指定和超出容量按照熱度淘汰,同時盡可能保證多線程環境的讀寫性能,不能使用外部三方庫

給我的時間限制是一個小時:我大概寫了如下程式,不能運作,沒有調試,也沒有太多的深入思考,時間有限啊。現在把代碼貼出來了。

//緩存接口 
public interface Cache{
     Object get(String key);
     boolean delete(String key);
     boolean put(String key,Object value);
     boolean clear();
 }
 //帶熱度的值
 public class HotMatrix{
     private AutomicLong hot=new AutomicLong(0);
     private Object data;
     
     public void setData(Object data){
         this.data=data;
     }
     
     public Object getData(){
         return this.data;
     }
     
     public void incrementHot(){
         hot.incrementAndGet();
     }
     
     public long getHot(){
         return this.hot.longValue();
     }
 }
 //一個簡單緩存實作
 public class MyCache implements Cache {
    private long maxSize;
    private volatile AutomicLong currentSize=0L;
    private Map<String,HotMatrix> data=new ConcurrentHashMap<String,HotMatrix>(maxSize);
    
    public MyCache(int size){
        this.maxSize=size;
    }
    
    private synchronized void deleteLeastHottest(){
        Collection<HotMatrix> values=data.values();
        Collections.sort(values,new Comparator<HotMatrix>(){  
            @Override  
            public int compare(HotMatrix b1, HotMatrix b2) {  
                return b1.getHot()>b2.getHot();
            }  
              
        }); 
        
        Iterator it=values.Iterator;
        while(it.hasNext()){
            HotMatrix val=it.next();
            if(!it.hasNext()){
                values.remove(val);
            }
        }
    }
    public Object get(String key){
        HotMatrix hotValue=data.get(key);
        Object value=hotValue.getData();
        hotValue.incrementAndGet();
        return value;
    }
    public boolean delete(String key){
        data.remove(key);
        return true;
    }
    public boolean put(String key,Object value){
        HotMatrix hotValue=new HotMatrix();
        hotValue.setData(value);
        if(data.contains(key){
            data.put(key,hotValue);
            return true;
        }
        if(currentSize>=maxSize){
            deleteLeastHottest();
            
        }
        data.put(key,hotValue);
        currentSize.incrementAndGet();
        return true;
    }
    public boolean clear(){
        data.clear();
        return true;
    }
     
 }
 //緩存管理接口
 public interface CacheManager{
     void setCache(Cache cache);
     Object get(String key);
     boolean delete(String key);
     boolean put(String key,Object value);
     boolean clear();
 }
 //一個簡單的緩存管理實作
 public class MyCacheManager implements CacheManager{
     private static volatile MyCacheManager instance;
     private Cache cache;
     private Lock lock=new Reentrantlock();
     
     private MyCacheManager(){}
     
     private MyCacheManager(Cache cache){
         this.cache=cache;
     }
     
     public static CacheManager getInstance(){
         if(instance==null){
             lock.lock()
             try{
                 if(intance==null){
                     instance=new MyCacheManager()
                 }
             }finally{
                 lock.unlock();
             }
         }
         return instance;
     }
     
     public void setCache(Cache cache){
         this.cache=cache;
     }
     
     public Object get(String key){
         return this.cache.get(key);
     }
     public boolean delete(String key){
         return this.cache.delete(key)
     }
     public boolean put(String key,Object value){
         return this.cache.put(key,value);
         
     }
     public boolean clear(){
         return this.cache.clear();
     }
     
 }
     
     
//測試
public class Test{
    public static void main(String[]args){
        CacheManager manager= MyCacheManager.getInstance();
        manager.setCache(new MyCache(10L));
        manager.put("java","java程式設計思想");
        manager.put("java","java程式設計思想");
        manager.put("java","java程式設計思想");
        manager.put("java","java程式設計思想");
        
        Object value=manager.get("java");
        manager.delete("java");
        manager.put("java","java程式設計思想");
        manager.clear();
        
        Thread t1=new Thread(new Runnable(){
           public void run(){
               manager.put("java","java程式設計思想");
                manager.put("java","java程式設計思想");
                manager.put("java","java程式設計思想");
                manager.put("java","java程式設計思想");
                manager.put("scala","scala程式設計思想");
                Object value=manager.get("java");
                manager.delete("java");
                manager.put("java","java程式設計思想");
                manager.clear();
           } 
        });
        
        Thread t2=new Thread(new Runnable(){
           public void run(){
               manager.put("java","java程式設計思想");
                manager.put("java","java程式設計思想");
                manager.put("java","java程式設計思想");
                manager.put("java","java程式設計思想");
                manager.delete("java");
                Object value=manager.get("java");
                manager.put("scala","scala程式設計思想")
                value=manager.get("scala");
                manager.put("java","java程式設計思想");
                manager.clear();
           } 
        });
        
        t1.start();
        t2.start();
    }
}