• <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, 評(píng)論 - 137, 引用 - 0
            數(shù)據(jù)加載中……

            我的SICP習(xí)題答案(1.6)

            會(huì)遞歸直到堆棧溢出。
            原因是 在 new-if 還沒有展開為 cond special forms 時(shí),else-clause 子式已經(jīng)陷入了無限遞歸。 做了以下實(shí)驗(yàn),可以驗(yàn)證
            (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))))

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

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

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

            淺論要協(xié)同作戰(zhàn)

            兵者,國之大事,不可不察也?!獙O武

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

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

            當(dāng) 作戰(zhàn)室只要指定一份作戰(zhàn)計(jì)劃,作戰(zhàn)部隊(duì)只要沖鋒殺敵,后勤部隊(duì)只要做飯埋尸體;空軍只管按線路圖投彈,炮兵只要向指定坐標(biāo)開炮時(shí)。如果沒有一個(gè)正確的、偉 大的、英明的將軍,這場戰(zhàn)爭只能在一個(gè)貌似嚴(yán)格符合教科書的方式開始,以一個(gè)不可思議的方式失敗。因?yàn)槌诉@位將軍,所有人都沒有帶著腦袋去打仗,他想的 對(duì)不對(duì),直接影響到結(jié)局。

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

            在 需求階段,需求人員應(yīng)該統(tǒng)領(lǐng)全局,向開發(fā)和測試人員介紹產(chǎn)品構(gòu)想,解釋需求,輔助開發(fā)和測試人員完成后續(xù)階段的計(jì)劃和方案;在開發(fā)階段,開發(fā)人員要重新整 合所有資源,由開發(fā)人員沖鋒,需求人員提供支持,測試人員監(jiān)督開發(fā)過程,糾正開發(fā)失誤;而在測試階段,測試人員才是指揮中心,他們要檢查軟件,需求人員配 合診斷,開發(fā)人員按測試計(jì)劃解決故障并封閉。不同的階段只是中心成員不同,決策人員不同,而不是責(zé)任不同,目的不同。

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

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


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

            我的SICP習(xí)題答案(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

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

            (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

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

            (define (p) (p))

            是無論如何也沒法完全展開的,因?yàn)樗鼤?huì)不斷遞歸,所以“正則序”才會(huì)死循環(huán)。

            而對(duì)于“應(yīng)用序”的實(shí)現(xiàn),則會(huì)這樣展開


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

            ; 0

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

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

            讀SICP有感

            思想都藏在lisp程序的層層括號(hào)中嗎?

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


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

            切和剝

            ——關(guān)于重構(gòu)方式的設(shè)想

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

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

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

            再論Singleton

            記得以前大家討論過Singleton三種寫法的優(yōu)劣,今天我又發(fā)現(xiàn)了一個(gè)新問題,在這里和大家分享一下。下面是三種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 }

            我們已經(jīng)知道方法1沒有多線程問題,但編譯時(shí)分配內(nèi)存。方法2有多線程問題,在運(yùn)行時(shí)分配內(nèi)存。方法3也有多線程問題,而且在編譯時(shí)分配內(nèi)存,但在運(yùn)行時(shí)調(diào)用構(gòu)造函數(shù)。(多線程問題的解決方法在此不再贅述。)

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

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

             

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

             

            結(jié)果發(fā)現(xiàn)在調(diào)用RegisterMethod()時(shí),Singleton::inst 還沒有初始化(構(gòu)造函數(shù)沒有被調(diào)用)。究其原因是編譯器雖然在編譯時(shí)對(duì)其分配內(nèi)存,但是構(gòu)造函數(shù)是在運(yùn)行時(shí),在Main()函數(shù)前調(diào)用。而對(duì)于全局變量,編譯器是不保證初始化順序的!而這個(gè)例子就是tmp在構(gòu)造時(shí), Singleton::inst 還沒有構(gòu)造。

            而這個(gè)問題的解決方法只有使用方法2或者方法3,考慮到我們不能在Main函數(shù)前使用new操作符,我用了方法3。又因?yàn)槲矣腥肿兞勘WC,就可以不考慮多線程問題了。

            要么是這個(gè)問題,要么是那個(gè)問題,你總要解決一個(gè)問題。

             

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

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

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

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

            UNICODE的區(qū)域列表(部分)

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

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

            灌水


             
            有兩種方式構(gòu)建軟件設(shè)計(jì):
            一種是把軟件做得很簡單以至于明顯找不到缺陷;
            另一種是把它做得很復(fù)雜以至于找不到明顯的缺陷。
            ——C.A.R. Hoare

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

            WSH+JSP

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

             
            當(dāng)然關(guān)于腳本語言還有諸如python、ruby、lua等,但要在windows下獨(dú)立運(yùn)行,破費(fèi)周折,目標(biāo)機(jī)是否有需要的dll還不一定,而這個(gè)程序只需要IE3.0以上版本,office。想必遍地都是吧。
             

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

            僅列出標(biāo)題
            共8頁: 1 2 3 4 5 6 7 8 
            国产精品成人99久久久久 | 国产精品久久久久久久久免费| 欧美精品九九99久久在观看| 亚洲欧洲久久av| 久久久久亚洲AV成人片| 国产精品免费看久久久香蕉| 国产欧美久久久精品影院| 久久免费国产精品一区二区| 亚洲欧美久久久久9999| 久久精品国产久精国产思思 | 色诱久久久久综合网ywww| 高清免费久久午夜精品| 深夜久久AAAAA级毛片免费看| 久久久久人妻一区精品色| 亚洲国产成人久久精品99 | 奇米影视7777久久精品人人爽| …久久精品99久久香蕉国产| 要久久爱在线免费观看| 久久久久噜噜噜亚洲熟女综合| 久久久久久久亚洲Av无码| 日本精品一区二区久久久| 亚洲天堂久久精品| 国产午夜精品久久久久免费视| 亚洲精品tv久久久久久久久久| 91久久精品电影| 日本久久久久久中文字幕| 久久久久久久久久久久中文字幕| 国产精品成人久久久| 香蕉99久久国产综合精品宅男自 | 久久亚洲国产最新网站| 亚洲乱亚洲乱淫久久| 亚洲成色999久久网站| 东京热TOKYO综合久久精品| 久久久久亚洲AV成人片| 久久国产欧美日韩精品| 99久久免费国产精精品| 久久精品aⅴ无码中文字字幕不卡| 久久青青草原亚洲av无码app| 国色天香久久久久久久小说| 亚洲日韩中文无码久久| 久久99精品久久只有精品|