<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    莊周夢蝶

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

        自從知道singleton模式這把錘子是什么樣的之后,我就把很多小疙瘩也當成了釘子,時常想象偶頂著模式的光環(huán)揮舞著“萬能”錘子在代碼叢林中學習蘭博搏斗的光輝形象~~~~。昨天讀《重構與模式》的inline singleton一節(jié),一句話點醒夢中人,singleton模式是“保證一個類僅有一個實例,并提供一個訪問它的全局訪問點”,原來——singleton也是全局變量啊。馬教主深刻地教育過我們:全局變量在被證明無害之前都是有害。偶大汗淋漓。看看迷戀singleton的幾種現(xiàn)象:
    1、僅僅在一個地方調用到了某個singleton實例,并且對這個實例的處理代碼也集中在這么一兩個地方,這樣的情況下你為什么要singleton?這里需要一個個全局訪問點嗎?我看你是為了singleton而singleton。

    2、我為了性能優(yōu)化啊!singleton只有一個實例,減小了創(chuàng)建開銷。oh,我終于找到一個用singleton的充分理由了——性能。慢著,跟我讀高大師的名言:“不成熟的優(yōu)化是萬惡之源”。你怎么知道singleton對象的重復創(chuàng)建是明顯影響了性能?現(xiàn)代jvm對“短命”對象的創(chuàng)建代價已經非常低了。不成熟的優(yōu)化不僅可能是無效的,而且也給以后重構工作帶來了困難。除非有明顯數(shù)據(jù)證明(分析工具而來)某個對象的重復創(chuàng)建是對性能影響極大,否則所謂性能優(yōu)化不能成為采用singleton模式的理由。

    3、有時候我們需要在系統(tǒng)的不同層次間傳遞一些共享信息,如果不采用singleton對象來提供這些共享信息,就得在調用的方法中重復地傳遞這些參數(shù),這是個應用singleton模式的場景。但是,如果這些共享信息是可被修改的,或者說singleton對象不是無狀態(tài)的,如果還采用singleton模式,那么你就不得不在調用的方法中從single對象取出舊信息和存入新信息,這樣的重復代碼將遍布的到處都是,不僅僅引入了同步訪問的需要,而且出錯的風險大大提高。這種情況下你還將這些信息作為方法參數(shù)傳遞而不是采用singleton可能更為清晰和健壯。

        singleton不僅僅是“保證一個類僅有一個實例”(這僅僅是描述),更重要的是它是用來“提供全局訪問點”的(這才是它的功能),不要再迷戀這把錘子,好好利用這把錘子。

    題外話:腳本語言似乎更容易濫用全局變量,javascript里可以模擬命名空間,Ruby也可以模擬類似的機制。最近寫的一個比較大一點的Ruby腳本,用了幾個全局變量(都是數(shù)組)用于保存狀態(tài)數(shù)據(jù),一開始沒有意識到這一點,導致對全局變量的訪問散落在好幾個腳本文件里,RDT下看起來紅通通的一片極其不爽。那么就重構吧——封裝數(shù)組重構,將對這些全局數(shù)組的訪問和修改操作統(tǒng)一到一個模塊,調用全局變量的地方都引用這個模塊,通過模塊去操作全局變量,代碼看起來清爽多了。


    posted @ 2008-02-23 15:34 dennis 閱讀(2162) | 評論 (5)編輯 收藏

    Primitive Writes up to and including… ...are made visible to…
    Object the end of a synchronized block or method a thread entering a synchronized block or method for the same object.
    Volatile field a write to a volatile field any thread reading that volatile field.
    Thread a call to Thread.start the newly started thread.
    Thread the final write made by a dying thread any thread which successfully calls Thread.join on that thread.
    Final field the initialization of a final field (but only those writes affecting the field and any object it references) any thread, provided that the constructor of the object containing the field doesn’t write the value of this anywhere eventually visible to other threads


      這些在《java并發(fā)編程實踐》一書中已經有詳細解釋,特別是對于ReentrantLock、volatile域以及final域的討論。今天在MenTaLguY的blog上看到這張表,摘錄下。

    posted @ 2008-02-23 10:44 dennis 閱讀(833) | 評論 (1)編輯 收藏

        今天在pongba的郵件列表里看到了這個《免費電子書<使用開源軟件——自己動手寫操作系統(tǒng)>》
        只能說太酷了,china-pub上一直有本書《自己動手寫操作系統(tǒng)》,牛人看到這本書使用的是商業(yè)軟件做示范,于是動念想是不是能使用開源軟件來實現(xiàn)書中所有的demo,于是就有了這本寶貴的電子書。
        項目主頁:http://share.solrex.cn/WriteOS/


    posted @ 2008-02-22 17:53 dennis 閱讀(2927) | 評論 (3)編輯 收藏

        Buffer是一個包裝了基本數(shù)據(jù)元素數(shù)組的對象,它以及它的子類定義了一系列API用于處理數(shù)據(jù)緩存。

    一、屬性
    Buffer有四個基本屬性:
    1、capacity  容量,buffer能夠容納的最大元素數(shù)目,在Buffer創(chuàng)建時設定并不能更改
    2、limit buffer中有效位置數(shù)目
    3、position 下一個讀或者寫的位置
    4、mark  用于記憶的標志位,配合reset()使用,初始值未設定,調用mark后將當前position設為值

    四者關系:0 <= mark <= position <= limit <= capacity

    二、API

    package java.nio;
    public abstract class Buffer {
    public final int capacity( )
    public final int position( )
    public final Buffer position (int newPosition)
    public final int limit( )
    public final Buffer limit (int newLimit)
    public final Buffer mark( )
    public final Buffer reset( )
    public final Buffer clear( )
    public final Buffer flip( )
    public final Buffer rewind( )
    public final int remaining( )
    public final boolean hasRemaining( )
    public abstract boolean isReadOnly( );
    }

    支持鏈式調用,如:buffer.mark().position(5).reset( );
    注意isReadOnly()方法決定了buffer是否可寫。

    三、操作
      以ByteBuffer為例,
    1、訪問,通過get(),get(index),其中get()從當前position位置讀取,get(index)從index位置讀取,不改變當前position,下面要說到的put也一樣。
    2、填充,通過put(byte),put(index,byte),按照絕對位置填充也是不改變當前position屬性

    3、flipping,試想,我們將填充完畢的buffer傳遞給socket輸出,那么socket讀取是依據(jù)position屬性確定,就會從結尾后一位開始讀,這樣肯定是不正確的,如果要正確的讀取我們先要:
      buffer.limit(buffer.position( )).position(0);
    將limit設為position, 將position設為0,這個操作就叫flipping,API直接提供了這個操作:
      buffer.flip( );
    特別注意,flip()方法會改變limit屬性,將limit屬性從capacity設置為當前position。rewind()方法與flip()類似,但是僅將position設為0,而不改變limit,通常用于重新讀取已經被flip的buffer。flip()另一個注意點是,兩次調用buffer的flip方法,將使得position和limit屬性都為0。

    4、迭代取元素:
    for (int i = 0; buffer.hasRemaining( ), i++) {
    myByteArray [i] 
    = buffer.get( );
    }

    int count = buffer.remaining( );
    for (int i = 0; i < count, i++) {
    myByteArray [i] 
    = buffer.get( );
    }
    ByteBuffer不是線程安全的,前一種方式適合并發(fā)訪問,后一種方式效率更高。這兩種方式都是一個一個取,效率都比批量取低。

    5.clear()方法,將buffer重設為空狀態(tài),也就是設置limit=capacity,position=0,以便重復利用。

    6.compact()方法,用于壓縮buffer,這個方法在多次重復調用時是比較低效。

    7.mark(),初始是未定義的,這適合如果調用reset將拋出InvalidMarkException。調用makr()后,將當前position設為mark以便reset時返回。注意,rewind( ), clear( ), and flip( )方法都將丟棄已經創(chuàng)建的mark。調用limit(index),positioon(index),如果index的值小于當前mark,mark也將被丟棄。

    8.比較,可以通過equals()和compateTo()方法來比較兩個buffer,前一個返回boolean,后一個返回0,-1,1。兩個buffer equal的條件是:
    1)類型相同
    2)剩余元素的數(shù)目相等
    3)剩余元素也一一相等

    9、批量移動數(shù)據(jù),為了更有效地進行數(shù)據(jù)傳送,批量的數(shù)據(jù)存取肯定是不能少的,Buffer及其子類都有提供類似的方法,比如CharBuffer:
    public CharBuffer get (char [] dst)
    public CharBuffer get (char [] dst, int offset, int length)
    public final CharBuffer put (char[] src)
    public CharBuffer put (char [] src, int offset, int length)
    public CharBuffer put (CharBuffer src)
    public final CharBuffer put (String src)
    public CharBuffer put (String src, int start, int end)

    四、創(chuàng)建Buffer
        Buffer以及其子類都無法直接new,而必須把通過他們提供的工廠方法來創(chuàng)建。通常有兩種方式:
    1、allocate,例如
    CharBuffer charBuffer = CharBuffer.allocate (100);
    將在堆上分配一個可以存儲100個字符的數(shù)組作為backing store。

    2、wrap,包裝一個已有的數(shù)組:
    char [] myArray = new char [100];
    CharBuffer charbuffer = CharBuffer.wrap (myArray);
    注意,這樣的方式創(chuàng)建的Buffer,將不會在堆上創(chuàng)建新的數(shù)組,而是直接利用myArray做backing store,這意味著任何對myArray或者buffer的修改都將影響到buffer或者myArray。可以通過public final boolean hasArray( )方法來判斷是否擁有一個數(shù)組,通過array()方法取得這個數(shù)組。

    五、復制Buffer
       其實這個復制也是“淺拷貝”,通過duplicate()方法將返回一個新創(chuàng)建的buffer,這個新buffer與原來的Buffer共享數(shù)據(jù),一樣的capacity,但是有自己的position、limit和mark屬性。通過asReadOnlyBuffer()方法復制的buffer與duplicate()類似,但是是只讀的,不能調用put。比較特別的是slice()方法,故名思議,類似切割一個Buffer出來,與duplicate類似,但是它將從原來Buffer的當前position開始,并且capacity等于原來Buffer的剩余元素數(shù)目,也就是(limit-position)。

    posted @ 2008-02-22 14:31 dennis 閱讀(6632) | 評論 (1)編輯 收藏

        讀blog看到的一個小技巧,原文在這里
        我們常常處理這樣的代碼:
    name=person?person.name:nil

        取某個對象的一個屬性,先判斷對象是否為nil,不是nil就返回對象屬性,否則返回nil。這樣的代碼寫多了比較惡心,是否有比較有趣的方式來減少代碼?作者給出了一段代碼:
    module ObjectExtension
     
    def nil_or
      
    return self unless self.nil?
      o 
    = Object.new
      
    class << o
        
    def method_missing(sym, *args); nil; end
      end
      o
      end
    end
    class Object
      include ObjectExtension
    end

       上面的代碼為Object加入了擴展,為每個對象實例增加了一個nil_or方法,分析下這個方法:如果對象不為nil,馬上返回self(也就是對象本身),否則生成一個新的對象,這個對象通過method_missing機制將所有的方法調用都返回nil(原文是用Class.new,生成的類將不會被GC,這里采用回復給出的方案,生成對象,在對象的metaclass上做method_missing)。那么現(xiàn)在代碼可以寫成:
        name=person.nil_or.name
    是不是相當?shù)腄SL呢?

    posted @ 2008-02-19 13:39 dennis 閱讀(844) | 評論 (1)編輯 收藏

    修正了很多bug,我關注的 JRUBY-1686也得到了修正,距離1.1的發(fā)布不遠了。

    The JRuby community is pleased to announce the release of JRuby 1.1 RC 2

    Homepage: http://www.jruby.org/
    Download: http://dist.codehaus.org/jruby/

    JRuby 1.1RC2 is the second release candidate of JRuby 1.1.  JRuby 1.1
    represents a concerted focus on speed and refinement.  ruby code can
    completely compile in an Ahead Of Time (AOT) or Just In Time (JIT) mode;
    yielding a faster ruby!  It also uses less memory than our previous releases.

    We need people to download JRuby 1.1RC2 and give us feedback.  Test your
    applications and help us make JRuby 1.1 a great release.

    Highlights:
    - 260 issues resolved since JRuby 1.1RC1
    - Large IO refactoring
    - Memory improvements for JIT'd methods:
      - Control total number of methods JIT'd
      - Support a JIT cache between runtimes to return permgen
      - Reduce codesize of generated methods (50-70% reduction)

    posted @ 2008-02-18 09:43 dennis 閱讀(1047) | 評論 (0)編輯 收藏

        要在JRuby中實現(xiàn)java接口,接口include進來,實現(xiàn)接口方法即可,例如實現(xiàn)java.lang.Runnable接口做線程處理:
    require 'java'
    include_class 'java.lang.Runnable'
    class
     TestRunnable
        include Runnable
        
    def initialize(name)
          @name
    =name     
        end
        
    def run
          puts 
    "hello,"+@name
        end
    end

        要在JRuby中繼承抽象類,實現(xiàn)其中的抽象方法,方法稍微麻煩點,需要cglib,到這里下載cglib-nodep-2.1_3.jar,寫個通用庫abstract_class.rb方便處理:

    load 'cglib-nodep-2.1_3.jar'

    class Object
      include Java
      include_class 
    "net.sf.cglib.proxy.Enhancer"
      include_class 
    "net.sf.cglib.proxy.NoOp"
      
      
    class <<self
        
    def method_missing(mname, *args, &block)
          unless mname 
    == :abstract_impl and respond_to?(:java_class) and JavaLang::reflect::Modifier.isAbstract(JavaLang::Class.for_name(java_class.name).modifiers)
            super
          
    else
            generate_abstract_impl(args, 
    &block)
          end
        end
        
        private 
        
        
    def generate_abstract_impl(args, &block)
          factory 
    = Enhancer.new
          factory.setSuperclass(java_class)
          factory.setInterfaces(java_class.interfaces.to_java(
    "java.lang.Class"))
          factory.setCallback(NoOp::INSTANCE)
          
          object_args 
    = args.map { |arg| Java.ruby_to_java(arg) }
          class_arguments 
    = object_args.map {|arg| arg.java_class}.to_java("java.lang.Class")
          generated_class 
    = factory.create(class_arguments, object_args.to_java("java.lang.Object"))
          
          ruby_class 
    = Class.new(generated_class.class)
          ruby_class.class_eval(
    &block)
          
          
    return ruby_class.new(*args)
        end
      end
      
    end

        使用的話,require一下abstract_class,例如我們要繼承java.util.TimerTask,實現(xiàn)其中的run方法:
    $:.unshift File.join(File.dirname(__FILE__),'.')
    require 
    'java'
    require 
    'abstract_class'
    import java.util.TimerTask
    import java.util.Timer
    timer_task 
    = TimerTask.abstract_impl do
      
    def run
        puts 
    "timer task"
      end
    end

    Timer.new.schedule(timer_task, 
    10001000)



    posted @ 2008-02-15 14:34 dennis 閱讀(1519) | 評論 (1)編輯 收藏

        過去寫的那個利用google在線翻譯的小腳本工具一直在用,今天用的時候,突然想,我今年不是想加強下英語學習嗎?那么把每天查過的單詞保存下來,每天早上或者上班空閑期間花那么幾分鐘記憶復習下這些單詞不是很好,畢竟技術性文章翻來覆去運用的單詞就那么多,過去沒有注意積累,導致常常還得重新查,所謂提高也就放在口頭上了。說改就改,腳本語言改起來就是容易:

    #利用google在線翻譯,翻譯中文<->英文
    #
    author dennis
    #
    version 0.2
    require 'net/http'
    $contents
    =Hash.new
    $dir
    ="F:/English/"
    now
    =Time.now
    $today
    ="#{now.year}#{now.month.to_s.rjust(2,'0')}#{now.day.to_s.rjust(2,'0')}"
    def translate
      txt
    =STDIN.gets
      
    if txt.strip=='e' or txt.strip=='exit'
        
    #退出前保存
        if $contents.size>0 then
          File.open(
    "#{$dir}#{$today}.txt","a+") do |file|
            $contents.each {
    |key,value| file.write(key.ljust(20)+value.ljust(20)+"\n")}
          end
        end
        exit
      end
      temp
    =txt.split(' ')
      
    if temp[1]=='1' or temp.size==1
        langpair
    ='en|zh-CN'
      
    else
        langpair
    ='zh-CN|en'
      end
      begin 
        
    #使用代理  
        #$proxy_addr = '192.168.9.25'
        $proxy_port = 8081
        $proxy_user
    ='test'
        $proxy_passwd
    ='test'
        
    if $proxy_addr
         response 
    = Net::HTTP.Proxy($proxy_addr,$proxy_port,$proxy_user,$proxy_passwd).post_form(URI.parse("http://translate.google.com/translate_t"),{'text'=>temp[0],'langpair'=>langpair}) 
        
    else
          response 
    = Net::HTTP.post_form(URI.parse("http://translate.google.com/translate_t"),{'text'=>temp[0],'langpair'=>langpair}) 
        end
        response.body 
    =~ /<textarea.*?id=suggestion>(.*?)<\/textarea>/
      rescue  StandardError 
    =>e
        $stderr.
    print "錯誤:"+e
      
    else
        result 
    = $1 
        puts 
    '翻譯內容:'+temp[0]
        puts 
    'google返回:'+result if result
        $contents[temp[0]]
    =result
        puts 
    '-------------------退出請打e或者exit---------------'
        translate
      end
    end
    translate


    posted @ 2008-02-14 11:15 dennis 閱讀(532) | 評論 (0)編輯 收藏

        習慣了,如果沒有過完春節(jié),感覺這一年還不算過去。年過完了,今天就開始上班了,昨天一早3點多到的廣州,太冷了。怎么說呢?先來個總結吧,2007年都干了什么,2008年想干什么,工作上的。
        首先是折騰——換工作,11月份辭職到星網(wǎng),然后干了兩個月,被mryufeng老大召喚到了廣州,折騰來折騰去終于是穩(wěn)定下來,要安心干活了。然后今年學習了Erlang,讀了sicp前三章,開始學習網(wǎng)絡和并發(fā)編程,對Ruby也有所深入,不過對unix編程還是進展不多。本來是計劃能看完sicp和豆瓣上列著那幾本,后來折騰的人精神都散了,沒什么心思讀書。今年的計劃,首先是sicp第四章要繼續(xù)讀,習題繼續(xù)做,讀完這個還有《算法導論》等著我;然后是Erlang,按魚老大的意思是年后要搞一搞,怎么也得再下番功夫,主要是otp這方面我還不是很熟悉。然后是想去讀讀幾本經典的unix網(wǎng)絡編程方面的,動手做做。最后就是繼續(xù)關注感興趣的那么幾個主題:osgi、Ruby、高性能網(wǎng)絡服務器的開發(fā)。
       自從做了這行,貌似人變的越來越枯燥了,新一年要多關心身邊的人,多關心老爸老媽,多關心弟弟,多聽聽音樂,幸好我還是保持著看電影和看球的習慣,希望家人朋友都身體健康(這比啥都重要),希望inter五月份能去莫斯科,希望我能有更多的耐性和堅持。也祝福看blog的你身體健康,工作順利,恭喜發(fā)財咯,哈哈。
     

    posted @ 2008-02-13 11:30 dennis 閱讀(477) | 評論 (2)編輯 收藏

        1月28日,24歲的深圳打工仔杜登勇孤獨地走在京珠高速公路上,他已經步行了18個小時。25日,他得知女朋友在回家途中被困湖南株洲,而且生病了。 27日,他借了500元,坐火車從深圳來到廣州,當天乘汽車到了韶關。當晚,京珠高速已封。杜登勇最后決定,連夜步行,前往400多公里外的株洲。

        其實這世界從來不缺乏溫暖的瞬間。


    posted @ 2008-01-31 19:59 dennis 閱讀(427) | 評論 (1)編輯 收藏

    僅列出標題
    共56頁: First 上一頁 29 30 31 32 33 34 35 36 37 下一頁 Last 
    主站蜘蛛池模板: 噼里啪啦电影在线观看免费高清| 亚洲国产精品久久久久| 噼里啪啦免费观看高清动漫4| 亚洲精品视频免费观看| 亚洲日韩精品无码专区加勒比| 亚洲91av视频| 国产精品亚洲美女久久久 | 亚洲国产高清在线一区二区三区| 猫咪免费人成网站在线观看| 一区二区三区免费视频网站| 色噜噜噜噜亚洲第一| 国产成人精品亚洲2020| 久久精品国产亚洲av日韩| 中文字幕不卡免费高清视频| 日韩免费高清一级毛片在线| 亚洲国产精品乱码一区二区| 瑟瑟网站免费网站入口| 亚洲第一福利视频| 免费人成在线观看网站视频| 成人免费视频小说| 久久不见久久见中文字幕免费| 精品国产sm捆绑最大网免费站| 久久国产精品免费网站| 成全高清在线观看免费| 免费无码av片在线观看| 两个人看www免费视频| 成av免费大片黄在线观看| eeuss影院ss奇兵免费com| 一级特黄录像免费播放中文版| 国产亚洲午夜精品| 无码一区二区三区亚洲人妻| 激情婷婷成人亚洲综合| 美女的胸又黄又www网站免费| 在线精品自拍亚洲第一区| 美女被暴羞羞免费视频| 免费一区二区无码视频在线播放| 午夜亚洲乱码伦小说区69堂| 曰批全过程免费视频观看免费软件| 免费一级毛片在线播放放视频 | 未满十八18禁止免费无码网站| 日本视频免费高清一本18|