莊周夢蝶

          生活、程序、未來
             :: 首頁 ::  ::  :: 聚合  :: 管理


          來源:http://moonbase.rydia.net/mental/blog/programming/the-biggest-mistake-everyone-makes-with-closures.html

          看下面的Ruby代碼
          = []
          for x in 1..3
            k.push(
          lambda { x })
          end

          執行
          k[0].call

          你可能預期返回1,實際的結果卻是3。這是為何?這是因為在迭代過程中共用了同一個context,導致k中的三個閉包都引用了同一個變量x。不僅僅Ruby有這個問題,python也一樣
          = [lambda: x for x in xrange(14)]
          k[0]()

          Javascript同樣如此

          var k = [];
          for (var x = 1; x < 4; x++) {
            k.push(function () { 
          return x; });
          }
          alert(k[0]())


          解決這個問題很簡單,就是將閉包包裝到一個函數里,建立新的context,那么迭代過程中生成的閉包所處的context不同:
          def make_value_func(value)
            
          lambda { value }
          end
          = (1..3).map { |x| make_value_func(x) }

          這個時候,k[0].call正確地返回1。

          這個問題并非在所有支持閉包的語言里都存在,例如scheme中就沒有問題

          (define k '())
          (do ((x 1 (+ x 1)))
              ((
          = x 4'())
            (set! k (cons (lambda () x) k)))
          (set! k (reverse k))

          ((car k)) 
          =>1


          Erlang也沒有問題
          K=[ fun()->X end || X <- [1,2,3]].

          lists:map(fun(F)
          -> F() end,K).

          再試試Clojure:
          (def k (for [i (range 1 4)] (fn [] i)))
          (map #(
          %) k)

          同樣沒有問題。這里Erlang和Clojure都采用列表推斷。




          posted @ 2010-07-09 23:52 dennis 閱讀(1737) | 評論 (4)編輯 收藏

              一些常見的關于xmemcached的問題,收集整理,集中解答在此。事實上這里的大部分問題都可以在用戶指南里找到。

          一、XMemcached是什么?
          經常碰到的一個問題是很多朋友對memcached不了解,誤以為xmemcached本身是一個緩存系統。Memcached是一個開源的,C寫的分布式key-value緩存,XMemcached只是它的一個訪問客戶端。Memcached通過網絡協議跟客戶端交互,通過客戶端你才可以去使用memcached,xmemcached是它的java客戶端之一。

          二、為什么要選擇xmemcached?

          memcached的java客戶端有多個選擇,為什么要選擇xmemcached?理由如下:

          1、支持所有的文本協議和二進制協議,支持連接KestrelTokyoTyrant等memcached協議兼容的系統并作特殊處理。
          2、支持動態添加和刪除memcached節點。
          3、支持客戶端統計
          4、支持JMX監控和統計,可以通過JMX增刪節點。
          5、高性能
          6、支持節點的權重設置
          7、支持nio的連接池,在高負載環境下提高吞吐量。

          三、對jdk版本有什么要求?

          Xmemcached僅支持jdk1.5及以上版本。

          四、使用的時候需要創建多個MemcachedClient對象嗎?MemcachedClient是不是線程安全?

          MemcachedClient是線程安全的,由于xmemcached的網絡層實現是基于nio長連接的,因此你并不需要重復創建多個MemcachedClient對象,通常來說將MemcachedClient設置為全局的唯一單例的服務使用,如果是使用spring配置,那更是簡單,在spring配置文件里配置一個MemcachedClient,其他對象引用即可使用。

          五、為什么會拋出java.util.TimeoutException?

          這是由于xmemcached的通訊層是基于非阻塞IO的,那么在請求發送給memcached之后,需要等待應答的到來,這個等待時間默認是1秒,如果超過1秒就拋出java.util.TimeoutExpcetion給用戶。如果你頻繁拋出此異常,可以嘗試將全局的等待時間設置長一些,如我在壓測中設置為5秒:
          MemcachedClient  memcachedClient=……
          memcachedClient.setOpTimeout(
          5000L);

          請注意,setOpTimeout設置的是全局的等待時間,如果你僅僅是希望將get或者set等操作的超時延長一點,那么可以通過這些方法的重載方法來使用:
          <T> T get(java.lang.String key,long timeout)

          boolean set(java.lang.String key, int exp,java.lang.Object value,
                      
          long timeout)

          ……


          六、Kestrel和TokyoTyrant不支持flag字段,xmemcached是怎么解決的?

          Xmemcached在存儲的value前面自動加上和去除4個字節的flag,這一切對應用來說是透明的。具體請看用戶指南。


          七、連接memcacheq,取出來的消息比放進去的多?


          這是由于memcacheq和kestrel一樣,不支持multi get協議,因此只要關閉xmemcached的multi get優化就可以了。

          memcachedClient.setOptimizeGet(false);

          所謂multi get優化是指xmemcached會將連續的單個get請求合并成一個multi get請求作批量獲取,提高效率。

          八、連接kestrel,為什么過一段時間會自動斷開并重連?

          你可能使用的是kestrel 1.2以下版本,kestrel 1.2才支持version協議,xmemcached是基于version協議做心跳檢測,因此當使用kestrel 1.2以下版本的時候會發生心跳檢測失敗并斷開連接重連的情況,你可以升級kestrel,也可以關閉心跳檢測:

          memcachedClient.setEnableHeartBeat(false);

          九、我使用maven,怎么引用xmemcached?

          xmemcached 1.2.5已經加入了maven的中心倉庫,因此你可以直接引用
            <dependency>
                
          <groupId>com.googlecode.xmemcached</groupId>
                
          <artifactId>xmemcached</artifactId>
                
          <version>1.2.5</version>
           
          </dependency>

          如果是之前版本,我推薦你升級,或者自己手工加入私人的maven倉庫。

          十、連接池是怎么回事?設置多大為好?

          在高負載環境下,nio的單連接也會遇到瓶頸,此時你可以通過設置連接池來讓更多的連接分擔memcached的請求負載,從而提高系統的吞吐量。設置連接池通過
          MemcachedClientBuilder builder = new    XMemcachedClientBuilder(AddrUtil.getAddresses("localhost:12000"));

          builder.setConnectionPoolSize(
          5);
          MemcachedClient client
          =builder.build();

          或者通過spring配置也可以。

          連接池通常不建議設置太大,我推薦在0-30之間為好,太大則浪費系統資源,太小無法達到分擔負載的目的。

          十一、性能建議及優化手段

              性能的調整只能給出一般性的原則,實際情況千差萬別,每次調整都需要做實際的測量才能確定是否帶來期望的效果。

          1、如果你的數據較小,如在1K以下,默認的配置選項已經足夠。如果你的數據較大,我會推薦你調整網絡層的TCP選項,如設置socket的接收和發送緩沖區更大,啟用Nagle算法等等:   
                      MemcachedClientBuilder builder = new XMemcachedClientBuilder(
                              AddrUtil.getAddresses(servers));
                      builder.setSocketOption(StandardSocketOption.SO_RCVBUF, 
          32 * 1024); // 設置接收緩存區為32K,默認16K
                      builder.setSocketOption(StandardSocketOption.SO_SNDBUF, 16 * 1024); // 設置發送緩沖區為16K,默認為8K
                      builder.setSocketOption(StandardSocketOption.TCP_NODELAY, false); // 啟用nagle算法,提高吞吐量,默認關閉

          默認如果連接超過5秒沒有任何IO操作發生即認為空閑并發起心跳檢測,你可以調長這個時間: 
            builder.getConfiguration().setSessionIdleTimeout(10000);  // 設置為10秒;

          更多網絡層配置選項請參見Configuration類。

          2、Xmemcached默認會做兩個優化:將連續的單個get合并成一個multi get批量操作獲取,將連續的請求合并成socket發送緩沖區大小的buffer發送。
          如果你對響應時間比較在意,那么可以將合并的因子減小,或者關閉合并buffer的優化:
              memcachedClient.setMergeFactor(50);   //默認是150,縮小到50
              memcachedClient.setOptimizeMergeBuffer(false);  //關閉合并buffer的優化

          如果你對吞吐量更在意,那么也可將合并因子調大,默認是150。但是也不可太大,太大可能導致平均響應時間延長。

          3、如果你對心跳檢測不在意,也可以關閉心跳檢測,減小系統開銷
          memcachedClient.setEnableHeartBeat(false);
          這個關閉,僅僅是關閉了心跳的功能,客戶端仍然會去統計連接是否空閑,禁止統計可以通過:
          builder.getConfiguration().setStatisticsServer(false);





          posted @ 2010-07-08 18:37 dennis 閱讀(20465) | 評論 (35)編輯 收藏

             讓你不帶薩隊,讓你不帶坎比亞所,我太他媽高興了。
             布爾迪索、德米凱利斯這樣的著名漏勺,還有古鐵雷斯這樣的牛B后衛,想進決賽完全在做夢。
             什么藝術足球,什么功利足球,看看德國隊的配合,臉紅不?
             只會在弱隊身上刷數據到伊瓜因,給米利托擦鞋都不配。
             梅球王被吹捧得太多了,相對于真小人的C羅,小動作、下陰招的梅球王終于帶著0進球到記錄回家了。88,阿根廷,世界清凈了。當然,馬上有一幫惡心阿迷矯情地唱著“阿根廷別為我哭泣”為他們的“潘帕斯雄鷹”招魂呢。


            

          posted @ 2010-07-04 00:08 dennis 閱讀(794) | 評論 (0)編輯 收藏

               摘要:     《飛行大亨》是我很喜歡的一部電影,不過這里我想介紹的是一個叫Aviator的開源的Java表達式求值器。 一、輪子的必要性     表達式的求值上,java的選擇非常多,強大的如Groovy、JRuby,N年沒維護的beanshell,包括javaeye上朋友的IKExpression。為什么還需要Aviator?或者說Avi...  閱讀全文

          posted @ 2010-06-29 11:44 dennis 閱讀(22108) | 評論 (15)編輯 收藏

          Java memcached客戶端——XMemcached發布1.2.5版本,這是1.2的最后一個小版本,主要的改進如下:

          1、合并yanf4j到xmemcached,目前只是簡單的源碼合并,以及去除了不需要的udp支持。因此從1.2.5開始,xmemcached不再依賴yanf4j,僅依賴slf4j

          2、支持SASL驗證。memcached 1.4.3新增了SASL授權特性,啟用了SASL的memcached會要求客戶端進行授權驗證,否則將拒絕請求,對于需要驗證的用戶來說是個可選的特性,關于memcached的SASL支持更多請看這里Xmemcached 1.2.5開始支持客戶端的SASL驗證,一個典型的使用例子如下:

                  MemcachedClientBuilder builder = new XMemcachedClientBuilder(
                                                  AddrUtil.getAddresses(
          "localhost:11211"));
                  builder.addAuthInfo(AddrUtil.getOneAddress(
          "localhost:11211"), AuthInfo
                                                  .typical(
          "cacheuser""123456"));
                  
          // Must use binary protocol
                  builder.setCommandFactory(new BinaryCommandFactory());
                  MemcachedClient client
          =builder.build();

           

          3、加快MemcachedClient.shutdown()方法的速度,應用可以更快地關閉xmemcached。

          4、完善中文用戶指南,添加客戶端分布和SASL驗證兩節。

             如果你使用maven,1.2.5已經放入maven的中心倉庫,因此添加依賴即可使用:

           <dependency>
                 
          <groupId>com.googlecode.xmemcached</groupId>
                 
          <artifactId>xmemcached</artifactId>
                 
          <version>1.2.5</version>
            
          </dependency>


          更多信息請參見wiki和changelog

          XMemcached是一個基于java nio的memcached客戶端

          項目主頁:  http://code.google.com/p/xmemcached/

          下載地址: http://code.google.com/p/xmemcached/downloads/list

          wiki地址:http://code.google.com/p/xmemcached/w/list

          posted @ 2010-06-22 18:17 dennis 閱讀(3516) | 評論 (2)編輯 收藏



          一、傳統并發模型的缺點


          基于線程的并發


          特點:
          每任務一線程
          直線式的編程
          使用資源昂高,
          context切換代價高,競爭鎖昂貴
          太多線程可能導致吞吐量下降,響應時間暴漲。

          基于事件的并發模型



          特點:
          單線程處理事件
          每個并發流實現為一個有限狀態機
          應用直接控制并發
          負載增加的時候,吞吐量飽和
          響應時間線性增長


          二、SEDA架構




          特點:
          (1)服務通過queue分解成stage:
             每個stage代表FSM的一個狀態集合
             Queue引入了控制邊界
          (2)使用線程池驅動stage的運行:
             將事件處理同線程的創建和調度分離
             Stage可以順序或者并行執行
             Stage可能在內部阻塞,給阻塞的stage分配較少的線程

          1、Stage-可靠構建的基礎



          (1)應用邏輯封裝到Event Handler
             接收到許多事件,處理這些事件,然后派發事件加入其他Stage的queue
             對queue和threads沒有直接控制
             Event queue吸納過量的負載,有限的線程池維持并發
          (2)Stage控制器
            負責資源的分配和調度
            控制派發給Event Handler的事件的數量和順序
            Event Handler可能在內部丟棄、過濾、重排序事件。

          2、應用=Stage網絡

             (1)有限隊列
                  入隊可能失敗,如果隊列拒絕新項的話
                  阻塞在滿溢的隊列上來實現吸納壓力
                  通過丟棄事件來降低負載
             (2) 隊列將Stage的執行分解
                  引入了顯式的控制邊界
                  提供了隔離、模塊化、獨立的負載管理
             (3)方便調試和profile
                  事件的投遞可顯
                  時間流可跟蹤
                  通過監測queue的長度發現系統瓶頸

          3、動態資源控制器

          (1)、線程池管理器

          目標: 決定Stage合理的并發程度
          操作:
          觀察queue長度,如果超過閥值就添加線程
          移除空閑線程



          (2)、批量管理器
          目的:低響應時間和高吞吐量的調度
          操作:
          Batching因子:Stage一次處理的消息數量
          小的batching因子:低響應時間
          大的batching因子:高吞吐量

          嘗試找到具有穩定吞吐量的最小的batching因子
          觀察stage的事件流出率
          當吞吐量高的時候降低batching因子,低的時候增加


          三、小結
             SEDA主要還是為了解決傳統并發模型的缺點,通過將服務器的處理劃分各個Stage,利用queue連接起來形成一個pipeline的處理鏈,并且在Stage中利用控制器進行資源的調控。資源的調度依據運行時的狀態監視的數據來進行,從而形成一種反應控制的機制,而stage的劃分也簡化了編程,并且通過queue和每個stage的線程池來分擔高并發請求并保持吞吐量和響應時間的平衡。簡單來說,我看中的是服務器模型的清晰劃分以及反應控制。



            

          posted @ 2010-06-20 23:53 dennis 閱讀(7293) | 評論 (6)編輯 收藏

              Java的垃圾收集算法是分代的,因為根據2/8原則,80%的Java對象都是速生速滅的,因此將Java Heap劃分為new和old,對兩個區域采用不同的垃圾回收算法,在new代存活下來的對象轉移到old區,這樣一來大大提高了Java GC的效率。
              類似分代的思想在很多地方可以用到,分代的本質是根據對象生命周期的不同做區別處理,而不是采取一刀切的方式來提高系統的處理效率。推而廣之,比如緩存的使用,現在很多web應用都采用了類似memcached這樣的緩存擋在數據庫前面分擔負載,那么你可以將memcached理解成new代,而數據庫是old代。memcached中存儲的是查詢的熱點數據,新鮮火熱,但是易失,并且在數據更新的時候被移除;而數據庫保存了所有的數據,當緩存沒有命中的時候才去查詢數據庫并存儲到緩存。new和old這只是簡單的二代劃分,事實上現在越來越多的系統是多級緩存,頁面緩存、memcached緩存、JVM內部緩存、查詢緩存等等直到數據庫,從web頁面到后端是一個越來越old的過程,緩存對象持續的生命周期逐漸增長直到persist狀態。
              具體到JVM內部緩存,我們通常使用LRU算法來實現一個安全有限的緩存,如直接繼承LinkedHashMap將可以實現一個簡單的LRUMap。基于內存使用上的考慮,我們會給LRUMap設定一個最大的capacity,當數據量超過這個capacity的時候將最近最少訪問的元素移除來容納新的元素。這樣處理產生的問題是這個capactity不能設置得太大,因為怕內存不夠用,但是不夠大的結果可能是命中率沒有那么高(跟你的場景相關),那么如何在保存內存安全的前提下更進一步緩存更多的對象呢?答案也是分代。LRUMap默認存儲的都是對象的強引用,我們知道Java還有其他3種引用類:soft,weak和phantom。其中Soft引用是在jvm內存不夠的時候進行回收,weak引用是在垃圾回收碰到的時候會被回收,顯然weak->soft->strong三類引用的生命周期可以劃分為3個代,我們將可以實現一個可以容納更多對象的LRUMap:LRUMap設置兩個閥值,一個是強引用的最大閥值,這個不能太大,一個是軟引用的最大數目,當超過第一個閥值的時候,不是將LRU替換出來的對象移除,而是替代轉換為軟引用存儲;如果軟引用的數目也超過閥值,那么可以將軟引用這個Map里的對象LRU替換成Weak引用存儲或者簡單移除。處理元素查詢的時候,多了一個步驟,在查詢強引用未果的情況下,需要再去查詢軟引用集合,不過都是O(1)復雜度的查詢,不會成為明顯的瓶頸。通過將緩存對象分代,我們實現了容難更多緩存對象的目標,大部分對象以強引用的形式存儲,被LRU替換出去最近最少訪問的元素以軟引用存儲,它們在內存不夠的時候被垃圾回收,保證了內存使用上的安全性。我們在系統中采用了類似這樣的緩存,緩存的命中率有了明顯的提高。
              題目是《緩存的分代》,其實談的是分代這種常見的設計或者說技巧,在需要處理大量對象的場景中,不采用一刀切的方式,而是根據對象的特點進行適當的分代處理,帶來的效率提升可能是驚人的。

              PS.關于這個招聘羅嗦兩句,我是這個小組的成員,有人質疑我的目的是為了賺推薦費,這個不能說沒有,不過主要目的還是招人,我們很缺人。那么多要求可以歸結為一句話:我們找Java基礎良好、對并發通信有豐富實踐經驗、寫代碼相對靠譜、為人相對靠譜的人。那些要求并非硬性,如果你覺的合適,盡管投簡歷,謝謝。我們小組做的東西我認為還是有價值的,也很有挑戰,淘寶內部的很多應用都在使用,如果你希望你做的產品被成千上萬的人每天使用,歡迎加入。

               

             

          posted @ 2010-06-05 10:13 dennis 閱讀(4521) | 評論 (5)編輯 收藏

              作為一個coder,我不僅在寫程序,也在寫bug。遇到bug總是比較尷尬的事情,如果這個bug還是別人發現,那更是心里不好受。責備自己是沒有用的,能做的是建立一個BUG數據庫,時常回顧下自己犯過那些愚蠢的事情,怎么避免以后再犯同樣的事情。昨天讀《程序員》看到一笑話,說優秀的程序員哪怕在過單行道的時候也會向左右兩邊看,笑話其實不好笑,反而再次提醒我:小心、小心、再小心。
              毫不慚愧地說,我也是今年才開始有意識地去做回顧bug這件事情,今天回顧下最近寫出來的這幾個BUG:三個是麻痹大意導致的,一個是switch語句竟然沒寫break,一個是并發BUG,一個是考慮問題不全面導致的問題。這里主要還是想講那三個麻痹大意寫出來的BUG,都是在急匆匆修改問題的情況下寫出來的,本意是為了解決原有的BUG,在自以為很有信心地情況下匆忙地修改代碼,沒有認真做review,沒有添加單元測試,在解決問題的同時引入了新的問題。
              這些愚蠢的BUG修正起來非常簡單,但是為什么那個時候卻沒有發現呢?我自省下,還是盲目自信導致的,因為快速地修復BUG似乎很能給人一種虛假的快感:瞧,這個問題我修正起來很快,我是代碼快槍手,哦耶~,修復也還罷了,如果能再補充下測試,也許這些問題就能避免,但是我卻又一次自信過了頭。我在想,如果下次還遇到這種需要快速修改問題的時候我該怎么做,我該先深呼吸下,停一停,先想想怎么改再動手,想想風險點,改完之后至少review三遍,并且一定要添加這些情況的測試。盡管我相信以后我還會寫下一些愚蠢的BUG,但是希望能讓自己少后悔一點點。

          posted @ 2010-06-05 01:06 dennis 閱讀(1108) | 評論 (0)編輯 收藏

          聯系郵箱: boyan@taobao.com
          簡歷格式: 最好是純文本格式

          淘寶分布式產品組誠聘Java工程師,有興趣的請聯系,謝謝,此招聘長期有效。具體職位和要求如下:

          消息中間件資深Java工程師
          工作地點:杭州
          職位描述:
          負責消息中間件的設計、開發等工作

          職位要求:
          1、扎實的Java開發基礎知識
          2、Java多線程、并發以及網絡通信有深厚的經驗
          3、熟悉大規模分布式系統架構,熟悉分布式存儲系統
          4、熱愛技術,對技術有不懈的追求。
          5、熟悉消息中間件,并了解消息中間件原理的優先考慮

          分布式數據層資深Java工程師
          工作地點:杭州
          職位描述:
          負責分布式數據層的設計、開發等工作

          職位要求:
          1、扎實的Java開發基礎知識
          2、Java多線程、并發以及網絡通信有深厚的經驗
          3、對JDBC,JPA,JTA有深厚的理解
          4、熟悉常見的分布式存儲解決方案
          5、熱愛技術,對技術有不懈的追求
          6、熟悉數據層的原理和應用
          7、熟悉關系數據庫模型、有分布式事務相關經驗優先

          Java框架和工具開發工程師
          工作地點:杭州
          職位描述:
          1、 設計、開發、改進基于Java的工具和框架。
          2、 指導開發團隊使用工具和框架,解決疑難問題。

          職位要求:
          1、 熟悉并自如運用Java語言及JDK類庫,具備良好的編程習慣。
          2、 熟悉多種Java開源項目,精通目前主流的Java開源項目的使用方法和設計理念。有獨到見解者更佳。
          3、 熟悉OOP理念及常見設計模式。
          4、 熟悉Eclipse開發平臺,了解Eclipse Plugin的開發。
          5、 視野廣闊,了解業內發展動態。
          6、 喜愛專研,精益求精,有較強的學習能力。
          7、 善于交流,樂于分享。
          8、 具備英文閱讀能力和書寫能力。

          應用管理工具開發工程師
          工作地點:杭州
          職位描述:
          1、承擔應用、系統管理工具及其他相關的工具、應用的開發
          2、大規模應用管理相關技術的預研工作

          職位要求:
          1、兩年及以上開發Java或Php開發經驗
          2、對技術充滿興趣,有扎實的編程基礎
          3、對經歷過的產品、項目有深入的理解,而不僅停留在開發



          聯系郵箱: boyan@taobao.com
          簡歷格式: 最好是純文本格式

          附注: 如果管理員覺的放在首頁不合適,請拿下,不好意思,招人不容易啊。

          posted @ 2010-06-03 16:05 dennis 閱讀(6027) | 評論 (27)編輯 收藏

               每天下班后回家跟兒子的例行對話:

          爸爸:你今天乖不乖?
          兒子:啊
          爸爸:有沒有想爸爸?
          兒子:啊
          爸爸:吃飯了沒?
          兒子:哦
          爸爸:有沒有吃飽啊?
          兒子:呃
          ……
               今天是兒童節,昨天晚上帶小家伙去買玩具,兒子很替老爸省錢,自己只挑了氣球。最后還是老爸老媽狠狠心給他買了畫板和音樂小屋子,慶幸的是兒子很喜歡,一個晚上在那邊“打電話”。兒子,節日快樂,希望你健康成長,快樂每一天。




          posted @ 2010-06-01 11:18 dennis 閱讀(1418) | 評論 (0)編輯 收藏

          僅列出標題
          共56頁: First 上一頁 8 9 10 11 12 13 14 15 16 下一頁 Last 
          主站蜘蛛池模板: 武义县| 太仆寺旗| 江城| 黑水县| 怀远县| 哈巴河县| 龙山县| 尼勒克县| 运城市| 来安县| 淅川县| 武安市| 通化县| 平阴县| 潢川县| 吉安市| 舞钢市| 繁昌县| 土默特右旗| 长寿区| 台前县| 图们市| 柯坪县| 武陟县| 新巴尔虎左旗| 依兰县| 佛坪县| 云梦县| 通榆县| 武鸣县| 辉南县| 栖霞市| 水富县| 呼和浩特市| 美姑县| 栾城县| 黄浦区| 夏河县| 丽水市| 阳新县| 即墨市|