• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            CG@CPPBLOG

            /*=========================================*/
            隨筆 - 76, 文章 - 39, 評論 - 137, 引用 - 0
            數據加載中……

            我的SICP習題答案(1.6)

            會遞歸直到堆棧溢出。
            原因是 在 new-if 還沒有展開為 cond special forms 時,else-clause 子式已經陷入了無限遞歸。 做了以下實驗,可以驗證
            (define (new-if pred thenc elsec)
              (cond (pred thenc)
                    (else elsec)))

            (define (iter x y)
              (new-if (
            = x y)
                      
            0
                      (iter (+ x 
            1) y)))

            (define (iter-if x y)
              (if (
            = x y)
                  
            0
                  (iter-if (+ x 
            1) y)))

            (define (iter-cond x y)
              (cond ((
            = x y) 0)
                    (else (iter-cond (+ x 
            1) y))))

            對于 (iter 1 10), (iter-if 1 10), (iter-cond 1 10)
            其中 iter 會 導致堆棧溢出,而 iter-cond 和 iter-if 并不會。

            此題同1.5
            在1.5中,由于應用序的原因,在 test 表達式 還沒有展開為 if 特殊形式(special forms)時, (p)已經陷入了無限遞歸。

            posted @ 2008-03-09 23:12 cuigang 閱讀(1760) | 評論 (9)編輯 收藏

            淺論要協同作戰

            兵者,國之大事,不可不察也。——孫武

            戰 爭是一個復雜的系統工程,需要多兵種的協同,即便是在冷兵器時代,也不能依靠單一兵種完成某場戰役,現代戰爭更是需要不同專業士兵的配合。我們經常可以在 影視劇中看到這樣的情景:兩軍對壘,最前面是盾牌兵,接下來是弓箭兵、長槍兵、騎兵、樸刀兵。首先弓箭兵在盾牌兵的掩護下放箭,一通亂射之后,然后盾牌兵 和長槍兵沖鋒,弓箭兵掩護,快接近敵軍時,盾牌兵后撤,弓箭兵停止射箭,騎兵和樸刀兵沖鋒。這種配合看似教條,實際是有一定意義的,它是從實踐中總結出來 的,從某種程度上反應了冷兵器時代多兵種協同作戰的重要性。

            軟 件開發也是一個復雜的系統工程,需要各種專業的技術人員配合。通常我們簡單的把這些技術人員分成需求、開發和測試,相應的也把整個過程分為需求階段、開發 階段、測試階段。這種劃分積極的意義是區分了不同專業方向,將整個過程流水化,負面的意義是將各個階段和各個專業團隊割裂開,各自為政,失去了劃分專業的 本意,形式替代了目的。結果需求人員的目的變成了寫出一份需求,然后封閉意見;開發人員按照需求寫出代碼,改正bug;測試人員挖掘bug,監督開發人員改正,然后寫一份報告。整體的目的蕩然無存。當然無法否認這種流水作業的正確性以及必要性,我這里要說的只是它的負面問題。

            當 作戰室只要指定一份作戰計劃,作戰部隊只要沖鋒殺敵,后勤部隊只要做飯埋尸體;空軍只管按線路圖投彈,炮兵只要向指定坐標開炮時。如果沒有一個正確的、偉 大的、英明的將軍,這場戰爭只能在一個貌似嚴格符合教科書的方式開始,以一個不可思議的方式失敗。因為除了這位將軍,所有人都沒有帶著腦袋去打仗,他想的 對不對,直接影響到結局。

            可 惜的是,我們沒有這樣的將軍指揮軟件開發,也不存在這樣的將軍。我們都長著腦袋,都要去思考。從另外一個角度,我們并不嚴格類似軍隊,我們更像一個自治的 團體。那么自我協同就成了一個現實問題。需求、開發和測試人員如何協同完成一個產品呢?首先我們要把他們看做一個整體,他們所有人工作的目的只有一個:完 成一個產品。需求階段、開發階段和測試階段只是這個目的的一個階段,不是某個人工作的終極目的。我們已經認識到這點,但我們做的遠遠不夠。

            在 需求階段,需求人員應該統領全局,向開發和測試人員介紹產品構想,解釋需求,輔助開發和測試人員完成后續階段的計劃和方案;在開發階段,開發人員要重新整 合所有資源,由開發人員沖鋒,需求人員提供支持,測試人員監督開發過程,糾正開發失誤;而在測試階段,測試人員才是指揮中心,他們要檢查軟件,需求人員配 合診斷,開發人員按測試計劃解決故障并封閉。不同的階段只是中心成員不同,決策人員不同,而不是責任不同,目的不同。

            可 能說的太隱晦了,舉兩個例子來說明。一個還是打仗的例子,比如現在我們需要讓弓箭兵上馬,去追殺敵軍。弓箭兵老大可能反對并提出幾個原因,第一,并非職責 范圍,弓箭兵的職責是遠距離造成敵軍傷亡,沒有追逃的責任,這是騎兵的責任。第二,技術能力不足,弓箭兵都不善于騎馬,而且馬上射箭難度較大,沒法實現。 第三,如果敵人反撲,由于不善近戰,可能會造成大量傷亡。的確有道理,可是如果我們真的需要這樣做來表現我們的戰略意圖,怎么辦?

            再 舉一個身邊的例子來說明,前幾天有這樣的爭執,關于需求應不應該明確界面限制導致選項不生效,然后切換界面取消限制,選項應如何的問題。需求人員的意見是 這樣的,第一,選項最終是什么不重要。第二,強行限制,會使需求工作量變大,同時開發和測試的工作量也增大(因為不同的地方,自然結果必然不同,強行一致 會導致不自然的處理,同時測試需要關注測試)。第三,不利于平臺化建設,這種限制會導致需求過分依賴于產品,無法在不同產品間共用。都很有道理。但是我認 為,提出這個問題是無可厚非的,需求的意見也是中肯的,解決的辦法是,我們要看看我們的終極目標,以此來判斷是否需要這樣做。首先,如果不限制造成不一 致,對我們的產品有沒有影響,其次,如果不一致,會不會造成后續工作的阻滯。對于這個問題的本身,我覺的對于無關緊要的選項,需求可以不寫,開發可以順其 自然,測試不必關注。而對于比較重要的選項,需求必須明確,開發必須處理,測試要注意關注。不可一概而論,非左即右。


            posted @ 2008-01-10 23:02 cuigang 閱讀(339) | 評論 (0)編輯 收藏

            我的SICP習題答案(1.1~1.5)

            1.1

            10,12,8,3,10 6,a,b,19,#f,4,16,6,16

            1.2


            (/(+ 5 4 (- 2 (- 3 (+ 6(/ 4 5)))))(* 3 (- 6 2)(- 2 7)))

            or

            (/(+ 5 4 (- 2 (- 3 (+ 6 4/5))))(* 3 (- 6 2)(- 2 7)))

            1.3

            這個問題中文版的翻譯是錯的,參看原文是求平方和而不是“和”。

            (define (square(x)(* x x)))
            (define (max x y)(if (< x y) y x))
            (define (func x y z)
              (+ (square (max x y))
                 (square (max (min x y) z))))

            1.4

            a+|b| 

            <=>

            1 # in python
            2 def a_plus_abs_b(a,b):
            3     if b>0 :
            4         x = a + b
            5     else:
            6         x = a - b
            7     return x

            1.5

            在網上看了很多答案,都認為“應用序”的實現會導致死循環,我非常困惑。反復看了中文版和英文版,覺得大家這樣認為可能是書中說lisp的實現是“應用序”,而在scheme中跑這段代碼會死循環,就先入為主的認為“應用序”的實現會死循環。其實對照正文,我們可以看到“正則序”停止展開的條件是“只包含基本運算符的表達式”,而對于

            (define (p) (p))

            是無論如何也沒法完全展開的,因為它會不斷遞歸,所以“正則序”才會死循環。

            而對于“應用序”的實現,則會這樣展開


            (test 0 (p))
            (if (= 0 0) 0 (p))
            (if #t 0 (p))

            ; 0

            解決這個問題主要是“正則序”(Normal order)以及“應用序”(Applicative order)展開一個組合式的規則,仔細研究了MIT 6.001課程講義,網上的各種答案,以及中英文版。我認為,正則序以類似廣度優先的方式進行展開。而應用序優先計算子表達式,類似與深度優先。那么對于這個問題,
            正則序會展開為
            => (if (= 0 00 (p))
            => (if #t 0 (p))
            接著,由于這是一個if的special form(特殊形式),就會被展開為
            0
            而應用序,由于(p)一直可以遞歸代換,從一開始就會進入一個無限遞歸中去。
            簡言之,由于應用序的原因,在 test 表達式 還沒有展開為 if 特殊形式(special forms)時, (p)已經陷入了無限遞歸。

            posted @ 2007-12-26 00:19 cuigang 閱讀(2320) | 評論 (13)編輯 收藏

            讀SICP有感

            思想都藏在lisp程序的層層括號中嗎?

            1 (define (abs x)
            2     (if (< x 0)
            3         (- x)
            4         (x)))


            posted @ 2007-12-25 21:48 cuigang 閱讀(761) | 評論 (0)編輯 收藏

            切和剝

            ——關于重構方式的設想

            我們重構部分代碼時,往往想到的是穩定,最好是不變接口,只變實現,保持接口的穩定性。但現實往往沒有這么輕松,接口不變,意味著有著一個良好的結構設計,至少在功能職責劃分上沒有大的問題。而我們卻時常遭遇這種職責的混亂,這種Martin Fowler不愿詳談的事情,對我們來說很麻煩。我們不能橫切式的改變,這將導致大規模的變化,特別是對于層次靠下的部分,范圍的擴大,無論是從控制能力上,還是工作量上,包括對系統穩定性的影響方面都是巨大的,兼容舊組件也許并不亞于推倒重來。

            也許是個好辦法,另辟蹊徑繞開原來的設計,從底向上建立一條新的結構通路,將舊的部分一片一片的剝開,合并到新的部分中來,直到完成重構。就像做一個心臟搭橋手術。

            posted @ 2007-12-21 19:36 cuigang 閱讀(259) | 評論 (0)編輯 收藏

            再論Singleton

            記得以前大家討論過Singleton三種寫法的優劣,今天我又發現了一個新問題,在這里和大家分享一下。下面是三種Singleton的寫法:

             

             1 // 1st
             2 class Singleton{
             3     static Singleton inst;
             4 public:
             5     Singleton& GetInst(){
             6         return inst;
             7     }
             8 };
             9 Singleton Singleton::inst;
            10 // 2nd
            11 class Singleton{
            12     static Singleton* _inst;
            13 public:
            14     Singleton& GetInst(){
            15         if(_inst == NULL)
            16             _inst = new Singleton;
            17         return *_inst;
            18     }
            19 };
            20 // 3rd
            21 class Singleton{
            22 public:
            23     Singleton& GetInst(){
            24         static Singleton inst;
            25         return inst;
            26     }
            27 }

            我們已經知道方法1沒有多線程問題,但編譯時分配內存。方法2有多線程問題,在運行時分配內存。方法3也有多線程問題,而且在編譯時分配內存,但在運行時調用構造函數。(多線程問題的解決方法在此不再贅述。)

            那么,我們可能就認為方法
            1雖然在編譯時分配內存,但我們不在乎這點內存,反正寫出來是要用的,這點內存少不了,既避免了多線程,又避免了分配失敗。就用它了!

            不幸的是,方法1也有它自身的問題。今天我在構造一個對象工廠時,期望通過全局變量,向工廠注冊派生類的生成方法時,方法1暴露了它的問題。比如我們在Singleton中有一個方法RegisterMethod(CallBack*),那么我可能這樣實現。

             

            1 //以下代碼是全局的,文件級作用域
            2 
            3 namespace{
            4     CBase* CreateDeriveObj()
            5     {
            6         return new(CDerive);
            7     }
            8     BOOL tmp = Singleton::GetInst().RegisterMethod(CreateDeriveObj);
            9 }//end of namespace
             

             

            結果發現在調用RegisterMethod()時,Singleton::inst 還沒有初始化(構造函數沒有被調用)。究其原因是編譯器雖然在編譯時對其分配內存,但是構造函數是在運行時,在Main()函數前調用。而對于全局變量,編譯器是不保證初始化順序的!而這個例子就是tmp在構造時, Singleton::inst 還沒有構造。

            而這個問題的解決方法只有使用方法2或者方法3,考慮到我們不能在Main函數前使用new操作符,我用了方法3。又因為我有全局變量保證,就可以不考慮多線程問題了。

            要么是這個問題,要么是那個問題,你總要解決一個問題。

             

            posted @ 2007-12-20 21:55 cuigang 閱讀(399) | 評論 (0)編輯 收藏

            在LINUX下看WINDOWS的中文文件名不是亂碼的方法

            mount -o codepage=936   iocharset=cp936  /dev/hda?  /mnt/???

            posted @ 2007-12-17 23:41 cuigang 閱讀(1901) | 評論 (2)編輯 收藏

            UNICODE的區域列表(部分)

            0000-00FF        ASCII字符
            0370-03FF        希臘字母
            2000-206F        通用符號
            2070-209F        上標和下標
            2150-218F        特殊數字
            2190-21FF        箭頭
            2460-24FF        帶圈的數字
            2500-257F        制表符
            2580-259F        陰影
            2E80-2EFF        CJK基本補充(好象是偏旁)
            2F00-2FDF        偏旁
            3000-303F        CJK標點符號
            3040-309F        日文平假名
            30A0-30FF        日文片假名
            3100-312F        漢字注音符號
            31A0-31BF        漢字注音符號擴展
            31F0-31FF        片假名語音擴展(?)
            3200-32FF        帶圈的CJK字符和月份符號
            3300-33FF        CJK兼容
            3400-34FF        CJK統一漢字擴展A
            4E00-9FAF        CJK統一漢字
            AC00-D7AF        韓文音節
            E000-F8FF        私用保留區域
            F900-FAFF        CJK兼容漢字
            FE30-FE4F        CJK兼容符號

            posted @ 2007-12-17 23:39 cuigang 閱讀(424) | 評論 (0)編輯 收藏

            灌水


             
            有兩種方式構建軟件設計:
            一種是把軟件做得很簡單以至于明顯找不到缺陷;
            另一種是把它做得很復雜以至于找不到明顯的缺陷。
            ——C.A.R. Hoare

            posted @ 2007-12-17 22:17 cuigang 閱讀(353) | 評論 (2)編輯 收藏

            WSH+JSP

            向大家隆重推薦一個比批處理更強大的windows腳本。不知道你是不是經常寫一些小工具,用批處理實現不了。只好用C來做,結果打開IDE,寫段程序, 調試編譯。當然這些都沒問題,關鍵是因為是臨時寫的,沒有考慮需求變化(呵呵),之后有時想要改改,那么就是打開工程,修改調試,編譯運行。如果有人要享 用,往往你把可執行文件發給他還不夠,還要把源碼發給他,因為他要改。小小一個文件處理,寫個exe。殺雞焉用牛刀。今天我隆重推薦WSH+JSP, Java的語法,支持COM組件的windows腳本宿主,完全替代簡陋的批處理,并且做出的東西,全是開源的。
             
            這里響應靳波前日日志中的txt2bin工具,寫了一段簡單的例子,你把它保存為一個文本文件txt2bin.js,雙擊就可以運行:
             
             1 ////////////////////////////////////////////////////////
             2 //txt2bin
             3 ////////////////////////////////////////////////////////
             4 // 創建文件系統對象
             5 var FileSys = WScript.CreateObject("Scripting.FileSystemObject");
             6 // 打開文本文件
             7 var TxtFile = FileSys.OpenTextFile("test.txt");
             8 // 創建bin文件
             9 var BinFile = FileSys.CreateTextFile("test.bin"true);
            10 // 讀一行
            11 var buf = TxtFile.ReadLine();
            12 // 聲明一個字符串
            13 var str = new String();
            14 for(var i =0 ;i<buf.length/*字符串長度*/; i++){
            15     ch = buf.charAt(i); //得到一個字符,并把它轉成數值
            16     str+= String.fromCharCode(ch); // 追加到數組
            17 }
            18 // 寫入bin文件
            19 BinFile.Write(str);
            20 // 關閉文件
            21 TxtFile.Close();
            22 BinFile.Close();
            23 ////////////////////////////////////////////////////////

             
            當然關于腳本語言還有諸如python、ruby、lua等,但要在windows下獨立運行,破費周折,目標機是否有需要的dll還不一定,而這個程序只需要IE3.0以上版本,office。想必遍地都是吧。
             

            posted @ 2007-12-17 21:52 cuigang 閱讀(379) | 評論 (0)編輯 收藏

            僅列出標題
            共8頁: 1 2 3 4 5 6 7 8 
            青青国产成人久久91网| 青青久久精品国产免费看| 国产亚洲美女精品久久久| 国产一久久香蕉国产线看观看 | 国产91久久精品一区二区| 中文字幕久久亚洲一区| 香港aa三级久久三级老师2021国产三级精品三级在 | 久久强奷乱码老熟女网站| 亚洲国产精品热久久| a级成人毛片久久| 狠狠色婷婷综合天天久久丁香| 久久精品人人槡人妻人人玩AV| 熟妇人妻久久中文字幕| 久久天天躁狠狠躁夜夜躁2O2O| 久久超乳爆乳中文字幕| 久久青青草原国产精品免费 | 久久精品国产色蜜蜜麻豆| 久久精品18| 一本色综合久久| 久久精品国产99久久久古代| 色综合久久久久无码专区 | 色欲久久久天天天综合网| 人妻无码αv中文字幕久久| 久久美女人爽女人爽| 久久人人爽人人爽人人片AV东京热| 亚洲午夜久久久| 久久久av波多野一区二区| 亚洲国产天堂久久综合网站| 色综合久久中文字幕综合网| 久久人人爽人人爽人人片av麻烦| 久久国产精品无码一区二区三区 | 国产精品久久久久影院嫩草| 久久久WWW免费人成精品| 精品综合久久久久久98| 亚洲欧美精品伊人久久| 久久久久波多野结衣高潮| 伊人久久大香线焦综合四虎| 思思久久99热只有频精品66| 久久久精品免费国产四虎| 国产成人综合久久精品红| 9999国产精品欧美久久久久久|