posts - 11, comments - 9, trackbacks - 0, articles - 0
            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

          日歷

          <2012年5月>
          293012345
          6789101112
          13141516171819
          20212223242526
          272829303112
          3456789

          隨筆分類

          搜索

          •  

          最新評論

          2012年5月15日

          原來Markdown如此之方便,github又提供了page服務(wù),還能用上git,真是無法無天了!

          http://www.100hack.com

          或者
          http://cuixin.github.com

          posted @ 2013-06-29 01:30 steven.cui 閱讀(245) | 評論 (0)編輯 收藏

          第5章 調(diào)試你的大腦


          我從來都不想成為怪人,但別人都認為我想。

          ——弗蘭克.扎帕,美國作曲家、音樂家、電影導(dǎo)演


          直覺是偉大的, 除了當它不偉大的時候。

          我們必須直視自己,“調(diào)試”(debug)自己的大腦。

          關(guān)于debugging,可以自己擴展閱讀,軟件是有人創(chuàng)造的,錯誤難免。

          為什么這么說呢?人類大腦又不是開源軟件,沒法找到代碼去修正,只是展示出錯的地方,但你卻能知道自己的缺陷在哪里,只能盡量避免,卻幾乎難以修正。這就是人,而不是計算機:

               1.認知偏見:思維如何被誤導(dǎo)

               2.時代影響:同代人如何影響你

               3.個性傾向:個性如何影響思維

               4.硬件故障:大腦較老區(qū)域如何壓制較聰明的區(qū)域


          了解認知偏見

               Wikipedia列舉了大約90多種認知偏見,書中著重舉了幾個值得重視的偏見:

             思維定勢

               思維定勢(Thinking Set) 是由先前的活動而造成的一種對活動的特殊的心理準備狀態(tài),或活動的傾向性。在環(huán)境不變的條件下,定勢使人能夠應(yīng)用已掌握的方法迅速解決問題。而在情境發(fā)生變化時,它則會妨礙人采用新的方法。消極的思維定勢是束縛創(chuàng)造性思維的枷鎖。

             基本歸因錯誤

               歸因理論的一個現(xiàn)象,即人們常常把他人的行為歸因于人格或態(tài)度等內(nèi)在特質(zhì)上,而忽略他們所處情境的重要性。比如,盡管我們在評價他人的行為時有充分的證據(jù)支持,但我們總是傾向于低估外部因素的影響,而高估內(nèi)部或個人因素的影響。這種現(xiàn)象解釋了當銷售人員的業(yè)績不佳時,銷售經(jīng)理更傾向于將其歸因于下屬的懶惰而不是競爭對手的實力。

            基本歸因錯誤(fundamental attribution error,F(xiàn)AE)描繪人們在考察某些行為或后果的原因時高估傾向性因素(譴責(zé)或贊譽人)、低估情境性因素(譴責(zé)或贊譽環(huán)境)的雙重傾向。

             自私的偏見

               這種偏見使人們相信,項目的成功是我的功勞,失敗則與我無關(guān)。這種行為可能是一種個人防御機制導(dǎo)致的,但是請記住你也是系統(tǒng)的一部分——無論結(jié)果好與壞。

              需要定論

               我們對疑問和不確定性感到不舒服,我們會竭盡全力解決不確定性。其實不確定性有時候是件好事,選擇是開放的。如果強行把不確定的事情強行的定論,會迫使你選擇放棄,易于犯錯,例如你宣布了一項項目截止日期,并沒有能力移除內(nèi)在的不確定性,它只是一種自我掩飾。說到這里,我們常說靠譜還是不靠譜,我個人是比較煩不靠譜的人,而我愛人卻總結(jié)出,不靠譜的人有時候往往做朋友比靠譜的人好相處,而且有時候能幫到你。

               因為不靠譜的人在事情模棱兩可的時候就可以承諾,但你別太把承諾當回事,也許他看似不靠譜的事情,真的就能辦到。因為靠譜的人從來不做沒把握的事情,不敢于嘗試,不去爭取嘗試甚至,特別覺得一旦說出去的話就得全部做到,要不就只字未提,聽她說完,身邊的朋友的確,雖然有些看似不靠譜的,卻真心對待的朋友,他們不是不靠譜,而是敢于給你幫助。


              認可上的偏見

               每個人都根據(jù)自己的成見和喜好原則來選擇相應(yīng)的事實。

              曝光效應(yīng)

               會因為習(xí)慣和熟悉某種事物對其偏愛,這包括不在好用或者出錯的工具或者技術(shù)。

               霍桑效應(yīng)/宣泄效應(yīng)

               1)社會心理學(xué)家所說的“霍桑效應(yīng)”也就是所謂“宣泄效應(yīng)”。霍桑工廠是美國西部電器公司的一家分廠。為了提高工作效率,這個廠請來包括心理學(xué)家在內(nèi)的各種專家,在約兩年的時間內(nèi)找工人談話兩萬余人次,耐心聽取工人對管理的意見和抱怨,讓他們盡情地宣泄出來。結(jié)果,霍桑廠的工作效率大大提高。這種奇妙的現(xiàn)象就被稱作“霍桑效應(yīng)”。

               2)1924年11月,以哈佛大學(xué)心理專家梅奧為首的研究小組進駐西屋(威斯汀豪斯)電氣公司的霍桑工廠,他們的初衷是試圖通過改善工作條件與環(huán)境等外在因素,找到提高勞動生產(chǎn)率的途徑。他們選定了繼電器車間的六名女工作為觀察對象。在七個階段的試驗中,支持人不斷改變照明、工資、休息時間、午餐、環(huán)境等因素,希望能發(fā)現(xiàn)這些因素和生產(chǎn)率的關(guān)系——這是傳統(tǒng)管理理論所堅持的觀點。但是很遺憾,不管外在因素怎么改變,試驗組的生產(chǎn)來效率一直未上升。

               歷時九年的實驗和研究,學(xué)者們終于意識到了人不僅僅受到外在因素的刺激,更有自身主觀上的激勵,從而誕生了管理行為理論。就霍桑試驗本身來看,當這六個女工被抽出來成為一組的時候,她們就意識到了自己是特殊的群體,是試驗的對象,是這些專家一直關(guān)心的對象,這種受注意的感覺使得她們加倍努力工作,以證明自己是優(yōu)秀的,是值得關(guān)注的。

               有一所國外的學(xué)校,在入學(xué)的時候會對每個學(xué)生進行智力測試,以智力測驗的結(jié)果將學(xué)生分為優(yōu)秀班和普通班。結(jié)果有一次在例行檢查時發(fā)現(xiàn),一年之前入學(xué)的一批學(xué)生的測驗結(jié)果由于某種失誤被顛倒了,也就是說現(xiàn)在的優(yōu)秀班其實是普通的孩子,而真正聰明的孩子卻在普通班。但是這一年的課程成績卻如同往年一樣,優(yōu)秀班明顯高于普通班,并未出現(xiàn)異常。原本普通的孩子被當作優(yōu)等生關(guān)注,他們自己也就認為自己是優(yōu)秀的,額外的關(guān)注加上心理暗示使得丑小鴨真的成了白天鵝。

               實驗結(jié)論

          1. 改變工作條件和勞動效率之間沒有直接的因果關(guān)系;
          2. 提高生產(chǎn)效率的決定因素是員工情緒,而不是工作條件;
          3. 關(guān)心員工的情感和員工的不滿情緒,有助于提高勞動生產(chǎn)率。

          研究者認為,這種自然形成的非正式組織(群體),它的職能,對內(nèi)在于控制其成員的行為,對外則為了保護其成員,使之不受來自管理階層的干預(yù)。這種非正式的組織一般都存在著自然形成的領(lǐng)袖人物。至于它形成的原因,并不完全取決于經(jīng)濟的發(fā)展,主要是與更大的社會組織相聯(lián)系。

          霍桑實驗最初的研究是探討一系列控制條件(薪水、車間照明度、濕度、休息間隔,等)對員工工作表現(xiàn)的影響。研究中意外發(fā)現(xiàn),各種試驗處理對生產(chǎn)效率都有促進作用,甚至當控制條件回歸初始狀態(tài)時,促進作用仍然存在。這一現(xiàn)象發(fā)生在每一名受試驗者身上,對于受試驗者整體而言,促進作用的結(jié)論亦為真。

          很顯然,實驗假設(shè)的各項條件并非是唯一的或決定性的生產(chǎn)效率影響因素。對此,喬治·埃爾頓·梅奧George Elton Mayo)以及他的助手們所做的解釋是,受試者對于新的實驗處理會產(chǎn)生正向反應(yīng),即由于環(huán)境改變(試驗者的出現(xiàn))而改變行為。所以績效的提高,并非由實驗操控造成。這種效果就是我們所稱的“霍桑效應(yīng)”或“霍索恩效應(yīng)”(Hawthorne Effect)。

               霍桑效應(yīng)的優(yōu)點

          • 能夠清楚地發(fā)現(xiàn)員工關(guān)心的事項。
          • 如果模型建設(shè)適當、準確的話,它所給出的解決生產(chǎn)力的辦法具有長期的、可持續(xù)的特點。
          • 對員工工作條件進行持續(xù)性衡量評估,有助于管理者指定長期的戰(zhàn)略決策。

               霍桑效應(yīng)的缺點

          • 一些內(nèi)在的工作環(huán)境屬性難以辨識,如組織動力。
          • 生產(chǎn)力模型的參數(shù)選擇a、b、c比較主觀,取決于管理人員的個人認識。
          • 關(guān)鍵性的工作環(huán)境屬性是動態(tài)的,模型需要不斷調(diào)整反映現(xiàn)實情況。
          • 從總體上來看,生產(chǎn)力模型的準確度與管理人員的個人判斷力、敏銳性緊密相關(guān)。

               霍桑效應(yīng)的啟示

               “霍桑效應(yīng)”,也就是社會心理學(xué)所說的“宣泄效應(yīng)”,它給我們的啟示是:人在生產(chǎn)或者生活的過程中,對自己未能實現(xiàn)和不能滿足的情緒,要把它發(fā)泄出來,情緒的發(fā)泄對人的身心健康和工作效率都非常有利。

              虛假記憶(讓我想到一部片子《羅生門》)

               虛假記憶(pseudo memory)是大腦記憶的信息之間自動的組合導(dǎo)致不真實的回憶。每個人的大腦都可能產(chǎn)生虛假的記憶,或?qū)⑹挛锏恼鎸嵡闆r扭曲。人們會對自己的記憶堅信不疑,甚至?xí)Υ竽X編造的謊言信以為真。這并非一種發(fā)病過程。所有人都會產(chǎn)生虛假記憶”,特別是關(guān)于童年時期親身經(jīng)歷的場景的記憶。

               符號約簡謬論和名詞謬論

               移位給事物貼上個標簽就意味著理解或者能解釋它,例如:當你嘗試畫一只人手時,L型思維的人會把光線、陰影、紋理的負責(zé)性簡化為“五條線加一個棍”。就如同人們一直認為天鵝只能是白的。

          在這里本人強烈推薦《怪誕心理學(xué)》,《影響力》,《引爆點》,《烏合之眾》等等,關(guān)于心理方面的書籍,每個人都應(yīng)該讀點心理學(xué),不是在于說自己腦子有問題,每個人都是有心理偏差的,正因為心理偏差造成的個體不同,才有各種不同的性格,社會進步的重要標志是能包容各種形式的不同形態(tài)存在。

          心理偏差是你的個性也好性格也罷,敢于去了解別人和自己本身就是一種對自己思維的挑戰(zhàn),或許說你再向自己發(fā)出改變的挑戰(zhàn),也許習(xí)慣是最難改變的,我們看似對新鮮事物充滿好奇,但如果熟悉一種事物,卻很難接受和改變自己替換原有思維。

          如果說中國古代皇帝最有作為的——李世民,如果只是但從人心理角度出發(fā)分析,對與其“元認知”的能力讓其能把國建建設(shè)的如此強大——自我批判和自我重塑,而這份能力恰恰是管理者最需要的能力。

          預(yù)言的失敗

               做預(yù)言太困難了,特別是關(guān)于未來的預(yù)測。

                                                          ——瑜伽.貝拉,偉大的智者、哲學(xué)家兼棒球手

               符號約簡(請注意:不是符號簡約,這兩個字前后顛倒,卻意思相差萬里)是個非常有害的問題,看個例子,你在嘗試畫一只人手時,L型把光線、陰影、紋理的復(fù)雜性簡化為“五條線加一個棍”。這種簡化被認為把復(fù)雜的現(xiàn)實看做由基本原素的組成:柏拉圖立體。

               我們善于將復(fù)雜的東西進行簡化和抽象,并且計算機編程也是如此之思想,但會讓我們陷入誤區(qū)。

               以前從來沒有人認為有黑天鵝的存在,以至于科學(xué)界認為沒有黑天鵝,知道有一只黑天鵝真的出現(xiàn)了。沒發(fā)現(xiàn)不等于不存在,很少也不代表沒有。

               作為一個團隊,我們往往會錯過重要的發(fā)展,因為我們關(guān)注了錯誤的事情或者提了錯誤的問題。

               現(xiàn)在,還有人在討論學(xué)習(xí)java好還是.net好?N年前的各種爭吵:RMI還是CORBA能取得中間件的勝利?Windows還是Linux能贏得桌面的勝利?

               就像是WEB的發(fā)展讓這些問題毫無意義,Web是典型的黑天鵝,其出乎意料的改變了游戲規(guī)則。


          “很少“不意味著”沒有“

               2012,7.21北京據(jù)說60年一遇的暴雨,幾乎每年都喊。程序員在寫程序的時候,不可能出現(xiàn)這樣的bug啊,其實應(yīng)該說概率低,但不代表沒有這種情況發(fā)生,花時間查一下認為的不可能的事情吧。不要說:”絕不可能“!


          推遲下結(jié)論

               軟件的制作過程在我本人看來就是一個消除不確定性的過程,而且跟時間成正比,如下圖所示:

               到項目末尾時你會達到智力巔峰,而在項目開始時則是最無知的。

               頂住壓力。你會做出決策,事情會解決,只不過不是今天。

               適應(yīng)不確定性,適應(yīng)敏捷開發(fā),盡可能的用更靈活的技術(shù)適應(yīng)不確定性,適應(yīng)了不確定性也就等于提高了效率。


          難以回憶

               記憶是靠不住的,舊的記憶會隨著時間改變,這反而會是你以為某些誤解和偏見是對的,不要僅僅依賴你的記憶。中國有句諺語說得好:好記性不如爛筆頭。


          認清時代的影響

               在這章里作者給出了美國從1901到現(xiàn)在經(jīng)歷的幾個時代,從技術(shù)和人的思維的變化,相似年齡段的人對某種事物的開發(fā)更接近,也就是不同年齡層次的人有代溝。本人不再贅述作者講述的美國各年代的歷史,其實這是我們都難以去逾越的,要想避免你所處時代的特有偏見,最好的方法就是保持多樣性。承認一種事物的存在,但卻能淡定的確很難。


          了解個性傾向

               他人即地獄。

                    ——讓.保羅.薩特,法國思想家、作家、存在主義哲學(xué)

               尊重不同人的不同性格,當你跟別人爭辯時,請想一想這點。

               MBTI(Myers Briggs Type Indicator)性格評估測試,在國內(nèi)有些機構(gòu)可以做些專業(yè)評測,如果想找免費的,可以借助谷歌去找,但如果英文一般的同學(xué)想做這個測試,我建議你去百合網(wǎng),雖然是個婚戀網(wǎng)站,但這個MBTI還是比較專業(yè)哦,不過MBTI的測試結(jié)果就如同你自己的性格一樣,性格有些人會發(fā)生改變,但有些人可能一輩子難以改變,曾經(jīng)我做過測試,經(jīng)歷過幾年后的測試有個界限發(fā)生了改變,所以不要讓MBTI成為你潛意識的引導(dǎo),而是作為了解自己的途徑,但不要太過于相信,而是時常打破自己的”符號約簡“。


          找出硬件問題

               大腦常犯一些低級錯誤——硬件問題。

               我曾見看過各種報到,為了一個誤會能讓人失去理智。。。

               蜥蜴邏輯:

                    戰(zhàn)斗、逃跑或者恐懼

                    立刻行動,不加思考

                    領(lǐng)頭意識,隨意指使你的隊友

                    守衛(wèi)領(lǐng)土,不分享信息和秘訣

                    受到傷害,憤憤不平,讓所有人都知道這是不公平的

                    像我這樣==好,不像我這樣==不好

               你或許認識到以上幾點我們都有過呢?

               見樣學(xué)樣,近朱者赤,近墨者黑,情緒就像傳染病,常跟一些樂觀的人在一起你也就變得樂觀了。

               進化行為:當你開始重播這些喜歡的電影時,努力阻止自己,記住:這只是一部電影。

               心靈是自己的地方,在那里可以把地獄變成天堂,也可以把天堂變成地獄。

                                                                                                         ——約翰.米爾頓《失樂園》


          現(xiàn)在我不知道該思考什么

               在上幾章提過,直覺是一種強大的工具,是專家的標志。但直覺可能完全錯誤,我們認為“正常的”未必是正常的。除了各種偏見,你可能被你自己誤導(dǎo),認為一切都好。

               之前提到關(guān)于創(chuàng)造一個R型到L型的轉(zhuǎn)化,也就是說,思考時是全局性和經(jīng)驗性的,然后轉(zhuǎn)換成更常規(guī)的實踐和技能,從而實現(xiàn)學(xué)習(xí)過程。

               相信直覺,但是要驗證。


          最后,測試你自己

               當你堅信某種事情時,問問自己原因。

               嘗試問問自己以下問題:

                    你怎么知道的?

                    誰說的?

                    有什么特別的?

                    我的做法會如何影響你?

                    與什么或者誰比較?

                    這總是發(fā)生么?你能想到一個特例么?

                    如果你這樣做了(或者不這樣做)會怎么樣?

                    什么阻止了你?

               實踐:

               當發(fā)生沖突時,考慮基本性格類型、不同年代的價值觀、你的偏見、別人的偏見和情境。通過司考更多因素,是不是更容易解決沖突?

               仔細檢查你的立場。你是如何知道你所知道的?什么使你這樣認為?


               我們通過邏輯來證明,通過直覺去發(fā)現(xiàn)。

                                                       ——龐加萊

           

          posted @ 2012-08-13 01:38 steven.cui 閱讀(380) | 評論 (0)編輯 收藏

          原文請參考,如有問題和歧義請指正,謝謝:)

          http://clojure.org/vars

          變量和全局環(huán)境

          Clojure是個很實用的語言,偶爾需要將維護和改變數(shù)據(jù)的值。她提供了4種不同的方式來操作變量:Vars, Refs, Agents, 和Atoms。Vars機制是是指向一個可改變的數(shù)據(jù)的位置,你可以為每個線程動態(tài)的綁定(制定一個新的存儲位置)一個新值。Vars可以初始化根綁定(不是必須的),綁定的值對于所有線程都是共享的,但卻別的線程就不能重新綁定。因此,要么Var可以為每個線程綁定值,要么使用根綁定。

          下面的special form def 創(chuàng)建了一個Var,如果Var不存在和沒有給初始化,var就是不綁定的(不允許創(chuàng)建非動態(tài)的Var,必須顯式指定根綁定):

          user=> (def x)
          #'user/x
          user=> x
          java.lang.IllegalStateException: Var user/x is unbound.

          為根值初始化(如果存在,就被再次綁定)

          user=> (def x 1)
          #'user/x
          user=> x
          1
           

          默認情況下(定義的時候初始化了根綁定),Vars是靜態(tài)的(static),但是,建立動態(tài)Var的定義可以通過元數(shù)據(jù)標記的方式,然后在線程用時通過binding來指定。

          user=> (def ^:dynamic x 1)

          user=> (def ^:dynamic y 1)

          user=> (+ x y)

          2

          user=> (binding [x 2 y 3]

                   (+ x y))

          5

          user=> (+ x y)

          2

           

          binding被創(chuàng)建后其他線程是是不可見的。創(chuàng)建的binding可以被賦值,也就是在沒有離開調(diào)用堆棧之前可以被上下文訪問。可以在一塊代碼之前設(shè)置matadata標簽:dynamic來指定:

          user=> (def ^:dynamic x 1)

          #'user/x

          user=> (meta #'x)

          {:ns #<Namespace user>, :name x, :dynamic true, :line 30, :file "NO_SOURCE_PATH"}

          user=> (binding [x 2] (println x))

          2

          nil

          user=> x

          1

          user=>

           

          如果你想讓函數(shù)編譯為static的,并且指定返回值,可以看下面的例子(速度提升不少,關(guān)鍵的調(diào)用函數(shù)可以采用這種方式加速):

           (defn fib [n]   (if (<= n 1)

              1

              (+ (fib (dec n)) (fib (- n 2)))))

          #'user/fib

           (defn ^:static fib2 ^long [^long n]

            (if (<= n 1)

              1

              (+ (fib2 (dec n)) (fib2 (- n 2)))))

          #'user/fib2

          user=> (time (fib 38))

          "Elapsed time: 1831.113 msecs"

          63245986

          user=> (time (fib2 38))

          "Elapsed time: 328.715 msecs"

          63245986

          user=> (meta (var fib))

          {:arglists ([n]), :ns #<Namespace user>, :name fib, :line 1, :file "NO_SOURCE_PATH"}

          user=> (meta (var fib2))

          {:arglists ([n]), :ns #<Namespace user>, :name fib2, :static true, :line 4, :file "NO_SOURCE_PATH"}

          user=>

           

          在上下文中可能需要重定義靜態(tài)變量,從Clojure1.3開始提供with-redefswith-redefs-fn這兩個宏來修改。

          定義函數(shù)的defn也是Vars的存儲方式,也可以在運行時被重定義。這也為aop編程帶來很多方便,例如:你可以封裝一個類似logging函數(shù)給調(diào)用的上下文或者或者線程。

           

          (set! var-symbol expr)

          將Vars指定為special form

          當?shù)匾粋€操作符為symbol的時候,它必須是全局變量。當前線程綁定的值就是后面的expr,也就是說必須是Thread-local的才可以,否則將會拋出一個使用set!來設(shè)定根綁定變量的錯誤。變量的表達式expr必須有返回值。

          注意,你不能賦值給一個函數(shù)的參數(shù)或者本地綁定,只能是java的字段Vars Refs和Agents,因為這些數(shù)據(jù)在Clojure里可不變的。

          使用set為java字段設(shè)置值,可以查看 Java Interop.

           

          Interning

          命名空間維護了每個Var對象的全局符號映射。如果使用def定義變量沒有在當前的命名空間找到該符號,就創(chuàng)建一個,否則使用現(xiàn)有的。創(chuàng)建或者尋找的過程被稱作interning。這就意味著,除非Var對象取消映射,否則Var對象每次被查詢,所以請在循環(huán)中千萬不要引用Var的全局變量,否則將非常慢,通過let或者binding讓全局變量取消映射來提高速度。命名空間在Evaluation中構(gòu)建了全局環(huán)境,編譯器也把所有free symbols當做Vars來解析了。

          可以使用閱讀宏(Reader)#’來得到Var對象的內(nèi)部的值。

           

          Non-interned的類型的變量

          可以通過with-local-vars來創(chuàng)建non-interned類型的變量,在free symbol解析的時候?qū)⒉粫话l(fā)現(xiàn),這些值只能被手工的訪問,但是也可以用作當前線程的變量。

          user=> (defn factorial [x]

                   (with-local-vars [acc 1, cnt x]

                     (while (> @cnt 0)

                       (var-set acc (* @acc @cnt))

                       (var-set cnt (dec @cnt)))

                     @acc))

          #'user/factorial

          user=> (factorial 7)

          5040

          posted @ 2012-07-31 01:48 steven.cui 閱讀(1501) | 評論 (0)編輯 收藏

          原文章寫在Google Groups thread里,但是還是值得再說下。

          有朋友把Java和Clojure的一些代碼片段放在Clojure Google group里比較,并提到Java的性能要比Clojure快太多了,疑問到底Clojure能不能趕上Java?

          在我的一個開源項目clj-starcraft中,關(guān)于java的性能問題,實際上也是我始終面對的,在我寫這篇文章的時,我的Clojure代碼還是慢了Java代碼6倍(Clojure花了70秒解析了1050個文件,Java則只有12秒)

          然而,70秒對過去的速度而言不算太糟糕,在剛開始的時候,竟然花了10分鐘來分析1050個文件。甚至比我用Python實現(xiàn)的還要慢。

          感謝Java的profiler和熱情的Clojure朋友,下面列出了我在提升Clojure性能方面的一些tips:


          (set! *warn-on-reflection* true)

          這恐怕是最重要的一個提升:打開這個設(shè)置將會警告你在任何一處用到Java反射API的方法和屬性。如你所想,直接調(diào)用永遠比反射要快,不管哪里Clojure都會你不能解析這個方法,你需要自己用type hint方式來避免反射調(diào)用。關(guān)于使用type hint,Clojure官方站點給了一個如何使用和提速的例子。

          修復(fù)所有關(guān)于*warn-on-reflection* 的編譯警告后,我的clj-starcraft從10分鐘降到了3分半。


          強制設(shè)置數(shù)據(jù)類型

          Clojure可以使用Java的基礎(chǔ)數(shù)據(jù)類型,無論何時在循環(huán)的時候,堅決考慮將你的值強制轉(zhuǎn)換成基礎(chǔ)類型,這將大幅提高你的性能。基礎(chǔ)數(shù)據(jù)類型在Clojure官方網(wǎng)站有例子和如何進行強制轉(zhuǎn)換來提高性能。


          使用二元運算符

          Clojure可以在一行里面支持多個表達式,但對于運算操作符,只有在兩個的時候才被inlined,如果你發(fā)現(xiàn)自己的運算符已經(jīng)超過了兩個,或許該考慮重寫你的代碼讓操作符顯示的成為兩個。下面請看兩者之間的比較:

          user> (time (dotimes [_ 1e7] (+ 2 4 5)))

          "Elapsed time: 1200.703487 msecs"

          user> (time (dotimes [_ 1e7] (+ 2 (+ 4 5))))

          "Elapsed time: 241.716554 msecs"


          使用==代替=

          使用==比較數(shù)字來代替=,提升性能那是相當明顯:

          user> (time (dotimes [i 1e7] (= i i)))

          "Elapsed time: 230.797482 msecs"

          user> (time (dotimes [i 1e7] (== i i)))

          "Elapsed time: 5.143681 msecs"


          避免vectors的destructing binding

          在一段循環(huán)種,如果你想為了提升可讀性從vector中傳出值,考慮下標訪問來代替destructing binding。雖然代碼看起來更清晰,但卻非常慢。

          user> (let [v [1 2 3]]

                  (time

                   (dotimes [_ 1e7]

                     (let [[a b c] v]

                       a b c))))

          "Elapsed time: 537.239895 msecs"

          user> (let [v [1 2 3]]

                  (time

                   (dotimes [_ 1e7]

                     (let [a (v 0)

                           b (v 1)

                           c (v 2)]

                       a b c))))

          "Elapsed time: 12.072122 msecs"


          優(yōu)先使用本地變量

          如果你需要在循環(huán)中查詢一個值,你或許需要考慮使用本地變量(通過let定義)來代替全局變量。看下兩者的時間對比:

          user> (time

                 (do

                   (def x 1)

                   (dotimes [_ 1e8]

                     x)))

          "Elapsed time: 372.373304 msecs"

          user> (time

                 (let [x 1]

                   (dotimes [_ 1e8]

                     x)))

          "Elapsed time: 3.479041 msecs"

          如果你想使用本地變量來提升性能,可以考慮下面比較土的式的方式來避免全局變量:

          (let [local-x x]

            (defn my-fn [a b c]

              ...))

          使用profiler工具:

          JVM有兩個profiler工具, -Xprof和-Xrunhprof,找到程序瓶頸而不是瞎猜。


          最后說明:

          你已經(jīng)注意到,在這些性能提升中,通過調(diào)用百萬量的執(zhí)行來提升了幾百毫秒的性能。所以,不到萬不得已需要提升性能的時候,沒必要讓你的代碼看起來不夠清晰。

          原文地址: http://gnuvince.wordpress.com/2009/05/11/clojure-performance-tips/

          最后補充:可以通過指定編譯為static方法來提高性能:

          pasting

           

          (defn
            ^{:static true}
            fib
            [n]
            (loop [a (long 1) b (long 1) i (long 1) r (list 1 1)]
              (if (== n i)
              r
              (recur b (+ a b) (inc i) (conj r (+ a b))))))

           

           

          posted @ 2012-07-29 14:15 steven.cui 閱讀(1962) | 評論 (2)編輯 收藏

          第4章  利用右腦


          人應(yīng)該努力學(xué)習(xí)洞察和培養(yǎng)自己內(nèi)心深處的靈光一現(xiàn),這遠遠勝于外面流光溢彩的整個世界。然而,人總會下意識地拋棄自己特有的想法,僅僅因為那是他自己的想法。

          ——拉爾夫.瓦爾多.愛默生(1803-1882)


          啟動感官輸入:

               研究顯示,使用多感官技術(shù)可以讓學(xué)生的學(xué)習(xí)效果提高5倍,目前我本人見過的電子產(chǎn)品ibooks2 已經(jīng)算是圖文聲并茂的最棒的學(xué)習(xí)產(chǎn)品了,也許以后全息技術(shù)的普及將帶來所有電子感官輸入和交互的一場革命。

               當你困在一個乏味的電話會議或者思考一個棘手的問題時,把玩下回形針或者晚些觸覺游戲能緩解疲勞。

               增加感官體驗以促進大腦的使用。

               在這里作者推薦不是使用商業(yè)工具(UML或者類似的東西)直接創(chuàng)建或者記錄設(shè)計和架構(gòu)信息,而是通過積木,樂高積木等等來增加感官輸入。

               為什么這樣做呢?實際就是刺激你的大腦,大腦總是渴望接受這種額外的、新奇的刺激。另外作者提到,團隊成員可以進行角色扮演,試試吧,無意中你可能會想到xx的幾句話真是讓人捧腹,但你卻對這個過程記憶猶新,比你寫上去的或者總結(jié)下來的文字要強好多倍。


          用右腦畫畫:

               繪畫既是觀察。

               繪畫是一種R型活動,共享總線被占用,如果你進行的L型活動,同時R型就必須停止。很多休閑活動都能夠激活R型停止L型的占用:聽音樂、繪畫、靜思、慢跑、針線活、攀巖,等等。

               角色扮演:

               書中有個角色扮演的例子,有興趣的可以去看《項目管理修煉之道》,琳達.萊辛描述了扮演的另一個用途:培訓(xùn)團隊。在向團隊介紹一種新框架的次數(shù)屢遭經(jīng)歷之后,她和同事大衛(wèi).得拉諾決定在下一個團隊中用表演來模擬框架。這次,開發(fā)人員不再抱怨沒有聽明白,而是抱怨表演簡直浪費時間,因為演出的內(nèi)容簡直是“太簡單了!”

               這是因為角色扮演真的有效果

               認知轉(zhuǎn)變,感受R型

               《用右腦繪畫》,或者叫《像藝術(shù)家一樣思考》,來自作者的推薦


          促成R型到L型的轉(zhuǎn)變

               去攀巖吧

               羅扎諾夫教學(xué)法(谷歌搜索:羅扎諾夫的音樂暗示學(xué)習(xí)法)

               酒酣寫作,酒醒修改(R型先行,L型做整理)

               結(jié)對編程(一人L型,一人R型),結(jié)對編程每個程序員都應(yīng)該嘗試

               隱喻相同(抽象與具體事物互相融合,嘗試將復(fù)雜的計算機用形象化的比喻將給不懂的人,你可以玩玩魔方,實際能恢復(fù)不難,轉(zhuǎn)得快需要很長時間的聯(lián)系,本人沒有繼續(xù)研究下去的勇氣,但嘗試了恢復(fù)的樂趣,是個很有意思的過程)

               并列參照系(隨機并列,也許兩個想法相隔十萬八千里,你卻能將其并列起來。例如,香煙和交通燈可以引出這樣一個概念:在香煙上使用紅色標志區(qū)來作為幫助戒煙的提示。)

               系統(tǒng)隱喻(隱喻思維是編程的基礎(chǔ),因為它存在于所有的抽象思維中)

               講個笑話吧(幽默既不是浪費時間,也不是無害的消遣,而是反映了思維、學(xué)習(xí)和創(chuàng)造所必須的重要能力。它與聯(lián)系有關(guān)。培養(yǎng)幽默感以建立更強的隱喻)


          收獲R性線索

               你已經(jīng)知道

               你是否曾經(jīng)聽到電臺里播放的一首老歌,然后在若干天突然想起歌名或者歌手?你的R型思維一直在背后異步地思考這個問題,直到最終找到相應(yīng)的記憶。

               伊萊亞斯.豪的奇遇


           

               在1845年,一個名叫伊萊亞斯.豪的美國人嘗試發(fā)明一種實用縫紉機。進展不是非常順利。在經(jīng)歷了漫長、艱苦、一無所獲的一天之后,晚上他做了一個非常可怕的噩夢,在尖叫中驚醒,直冒冷汗。

               在噩夢中,他身處非洲,被饑餓的食人魚綁架。他馬上就要被扔進沸水里煮死。他努力掙扎,而獵手們就一直用一種看起來非常可笑的長矛戳向他。

               第二天他描述噩夢時說,他的注意力集中在“可笑的長矛”上。因為這些長矛的前端鉤子上有洞,這就像是手持縫紉針上的洞,只不過后者是在末梢上。

               伊萊亞斯接著獲得了自動縫紉機的第一份美國專利,這要歸功于他來之不易的靈感:縫紉機針的洞需要與平常的針持針方向相反。


               利用圖像流

                    1.觀察圖像,努力看清所有細節(jié)

                    2.大聲地描述出來(真正發(fā)出聲音,這很關(guān)鍵)。

                    3.利用全部五種感官想象它

                    4.使用現(xiàn)在時態(tài),即使該圖像都溜跑了。


               利用自由日記

                    寫信是一種偉大的習(xí)慣。blog這種模式很受歡迎,wordpress或者blogspot(墻外)推薦。

               晨寫技術(shù)

                    早上起來第一件事情。

                    至少寫三頁,最好不用電腦,如果使用電腦關(guān)掉所有跟寫作無關(guān)的東西(只開evernote)

                    不要審查刪減你寫的東西。不論是優(yōu)秀的還是陳腐的,只管寫下來。

                    堅持天天寫

               “自由寫”技術(shù)

                    開個blog,將你的想法隨時記錄,或者用evernote,保持隨時隨地可以自由寫

               利用散步

                    遇到問題的時候,試著找個安靜的地方散散步,不要坐在電腦旁,離開鍵盤去解決難題。當你不寄希望于它時,就會發(fā)現(xiàn)答案自己冒了出來。


          收獲模式

               代碼中的模式

                    如果你不是一個特別在意編碼排版的人,那我可以負責(zé)任的告訴你,你離真正程序員的路還很遠,反而用lisp的人,更注意代碼排版,看代碼的時間遠遠高于你寫代碼的時間,如果你連代碼都排列不好,問題自然避免不了。切記,你可以桌子混亂,實際是為了保持上下文不被切換,而代碼卻不能格式混亂,格式都混亂甭提邏輯了。


               換換腦子

                    改變解決問題的角度,前面一章提到過,了解一只青蛙不是解剖它,而是如何創(chuàng)造它!


               神諭沖擊的魔力

                    在古代,教堂的大主教經(jīng)常通過神諭求的建議。像大多數(shù)算命者或者占星師一樣,神諭給予的響應(yīng)或者信息通常非常模糊,就像謎一樣。你不得不自己來“解釋”它。這就是對大腦的一次沖擊。

                   作曲家布萊恩.伊諾和彼得.施密特提出了一套100種間接策略來換腦。去看:http://www.rtqe.net/ObliqueStrategies/



           

                    例子:

                         這項別的什么東西么?

                         不做任何改變,堅持始終如一

                         關(guān)上門,從外面聽

                         錯誤是一種潛在的提示(其實可能不是一種錯誤,一種形態(tài))


               莎士比亞的謎語

                    莎士比亞做過很多語言重造的工作:

                         Full circle(繞圈子

                         Method of the madness(貌似瘋狂實則有理的行為)

                         Neither rhyme nor reason(莫名其妙)

                         Eaten out of house and home(吃的傾家蕩產(chǎn))


               在此,也感謝譯者(崔康)對本書的給力翻譯,沒有對語言的融會貫通很難將兩者聯(lián)系起來,謝謝。


          試一試:


                    使用樂高積木做項目模塊討論。

                    使用雙人機制,讓同伴激勵你,討論你的進展。

                    使用隱喻描述你當前的項目。

                    觀察你認識的專家,看看他們有什么“奇怪”的習(xí)慣讓你覺得更能理解?

          posted @ 2012-07-10 01:21 steven.cui 閱讀(391) | 評論 (0)編輯 收藏

          第3章  認識你的大腦

          我們的大腦就是雙CPU,單主機設(shè)計總線。




          1號CPU即線性的,也稱為L型處理模式或者叫思考模式。程序員大多喜歡step by step這種方式,一步步的去線性處理。

          2號CPU是非線性的,也稱為R型處理模式,更多的是直接和創(chuàng)造性,但兩者之間訪問內(nèi)存(大腦)的時候,都是互相搶占系統(tǒng)總線的。


          你的記憶更像是全息影像方式在存儲,在我剛上午看過的書,下午可能就忘記了,但是我看到什么位置竟然是書中的插圖提醒的我。人們對圖像和聲音的記憶更強于文字,L型記錄的是一些循規(guī)蹈矩,有規(guī)律可循的記憶,而R型則是突發(fā)奇想,在你不經(jīng)意間(睡夢中,洗澡時等等)想到了一個解決方案,R型是異步的,并且有時候是你不經(jīng)意間,而不是刻意去想就能聯(lián)系到另外一件事情上。


          隨時隨地記錄你的想法


               作者的推薦: http://www.pocketmod.com

               語音備忘錄/信箱

               Fisher Space鋼筆

               Moleskine筆記本


          我本人推薦:

               你應(yīng)該有個tablet/pad(我個人推薦ipad)

               你需要一臺不錯的智能手機可以跟你的電腦或者pad進行同步,iphone? 還是android都可以,屏幕至少4.0寸以上

               軟件方面:EverNote, GoodNotes,Penultimate,OmniFocus,Mindjet, AwesomeNote等等。


          我們每個人都有好點子,可真正付諸實踐的卻少的可憐。



          L型和R型處理方式的特點

               L型:

               處理令人感到舒適、熟悉而放松,提供以下九種能力:

          •      語言能力
          •      分析能力
          •      符號能力
          •      抽象能力
          •      時間能力
          •      推理能力
          •      數(shù)字能力
          •      邏輯能力
          •      線性思維能力

               R型:

               非語言性的,喜歡綜合學(xué)習(xí),集成事物形成整體。

          • 非語言
          • 綜合
          • 具體
          • 分析
          • 非理性
          • 空間性
          • 直覺
          • 全面

          R型思維能力是很難衡量的,至少比起L型來說要難的多。R型思維更是一種綜合,大局觀的體現(xiàn),也是一種逆向思維和想象力,創(chuàng)新能力的體現(xiàn)。我個人推薦程序員應(yīng)該至少了解一門藝術(shù),例如繪畫、攝影、音樂啊等等,這些是R型非線性思維給與你的靈感和想象力,并且會給你猶如突發(fā)奇想這樣的奇跡,我們了解一種事物不是通過逆向倒推來了解他,而是通過它是如何出現(xiàn)和創(chuàng)造的而去想如何構(gòu)建它。我個人推薦,無論學(xué)什么至少應(yīng)該去了解這么技術(shù)或者藝術(shù)的誕生歷史,為什么如此產(chǎn)生的,為什么會有這樣的想法,想法和初衷是什么?


          作者給出一個很精辟的理論:真正想要了解一只青蛙,傳統(tǒng)的解剖不是辦法,更好的方式是構(gòu)造一只青蛙。


          綜合學(xué)習(xí)與分析學(xué)習(xí)并重。


          設(shè)計勝于功能

               無論什么產(chǎn)品,面向的終端用戶都需要理解你的產(chǎn)品。蘋果的ipod的廣告上從來不說能容納多少個G,一個G等于多少多少字節(jié),這樣用戶會瘋掉,誰會聽你扯淡這些他們不理解的東西,他們只需要知道能存放多少首歌曲罷了。


          吸引力更有效

               吸引力的界面比不具有吸引力的界面更易于使用。盡最大努力爭取好的設(shè)計,它真的很有效,好的設(shè)計也是需要不斷修改出來的。

               美來自于選擇——路易.康,對于一個程序員來說,好的設(shè)計很多都是構(gòu)建于各種選擇(開源穩(wěn)定的組件),基于某種設(shè)計理論SEDA,CELL等等。


          R型看森林,L型砍樹木

               如果你想發(fā)現(xiàn)全局、整體的模式,你需要R型,如果你需要分析部分和細節(jié),你需要L型。講述一個程序員看開源項目的例子,在拿到一個開源項目的時候,下面幾個步驟開始:

          1. 了解開源想的初衷和目標,解決了什么問題,把握這個開源項目的方向性。
          2. 開始了解開源項目的大致結(jié)構(gòu)(導(dǎo)出UML圖,或者大致瀏覽項目的接口文件),以及開源項目中依賴的組件。
          3. 有了整體全局觀以后,下來試驗下開源項目提供的tutorial。
          4. 開發(fā)調(diào)試并親手實踐一個例子,對整個流程有個具體把握。
          5. 嘗試在開源項目上進行你自己項目的試驗和業(yè)務(wù)邏輯:
            1. 構(gòu)建一個具體的業(yè)務(wù)邏輯。
            2. 。。。。
            3. 。。。。
            4. 。。。。
          6. 回頭再來看一些代碼,這樣實踐相結(jié)合,更容易理解。


          訓(xùn)練自己的大腦

               程序員大多數(shù)都顯得死板和缺少R型思維能力,學(xué)習(xí)一些新鮮的事物,可以看看科幻電影或者小說等等,增加自己的想象力,想象力來源于生活,而生活卻是無所不包,包羅萬象的百科全書,你甚至可以說任何的發(fā)明都是來源于生活,唯有熱愛生活的人才能做出好產(chǎn)品,產(chǎn)品也許不需要你創(chuàng)造,只是在選擇不同的組合。

          posted @ 2012-06-19 22:40 steven.cui 閱讀(756) | 評論 (0)編輯 收藏

           

           此讀書筆記并不完全作為闡述想法,所以在闡述一些問題的時候可能沒有前因后果,更是一種總結(jié)性的話語和書上言語的精華,這有點悖論,如果你想了解,請去看《程序員的思維修煉》,這本書可以跨學(xué)科,即便你不懂程序,都值得一看,是從思維和大腦層面來開展介紹的。

           

          2 從新手到專家的歷程

           

               新手到專家需要經(jīng)歷5個階段(德雷福斯技能獲取模型

               真正的專家不怕考驗,而輕松面對~

               真正的專家很難將自己的行為解釋清楚,而熟練到已經(jīng)無意識了。

               

               新手:在乎自己是否能成功,不知道自己是對是錯,不是特別想要學(xué)習(xí),只是實現(xiàn)一個立竿見影的目標,不知道如何應(yīng)付錯誤,錯誤出現(xiàn)不知所措。新手需要指令清單,有規(guī)則,有順序。但規(guī)則只能讓你啟程,不會讓你走的更遠。

               高級新手:高級新手不想要全局思維,當公司在展示全年銷售測量表和數(shù)據(jù)時,你可能不感興趣,可這預(yù)示著明年你在這家公司是否還能繼續(xù)干下去。但是,你看不到這種聯(lián)系,因為你層次還不夠,只處于較低的技能水平

               勝任者:可以獨立解決自己遇到的問題,并開始考慮如何解決新的問題。處于這樣水平的人通常具備主動性足智多謀,往往在團隊中發(fā)揮著領(lǐng)導(dǎo)作用,他們是團隊里的好人,但缺乏足夠的能力——自我反思和糾正。

               精通者:精通者需要全局思維,而且需要更大的概念框架,過于簡單化的信息,他們會非常沮喪。在精通者中,最明顯的特征:自我改進和反思。同時他們善于傾聽別人的意見,并從那些失敗或者成功的項目中認真觀察、學(xué)習(xí)和總結(jié)。

               專家(大師):專家憑直覺工作,并不需要理由。他們有豐富的經(jīng)驗,并能家當運用,他們著書、寫文章、做演講等等。專家往往通過觀察一些細節(jié)(可能常人根本無法覺察到的一些細節(jié))就能判定特征和問題所在,那些無關(guān)緊要的會自動過濾更是專家具備的能力。

           

          實踐:

          你不知道自己不知道

                       達爾文:無知往往來自于自信而不是知識

           

          上面兩句話,剛開始理解的時候沒有突然頓悟的感覺,但跟媳婦一番討論后,更加理解了:

          學(xué)生問老師自己所掌握的知識到底有多少?

          老師給出了下面的回答:

          你現(xiàn)在的知識就仿佛是一個點,而老師比你要多一些,是個圈,老師知道你不知道的,你有可能知道自己不知道的而老師知道的,你通過學(xué)習(xí)將來會知道老師知道的,然后超過老師去知道老師不知道的,老師也在不停地學(xué)習(xí),但隨著知道的越來越多,也就意識到自己不知道的越來越多,因為越大的圓外面就會有更大的圓。

                       

          達爾文的總結(jié),一語道破了無知的自信(無知者無畏這句古話更是說明了假自信),潛意識層面根本就是不知道自己不知道。有時候自信也很可怕,因為你要確認自己到底是否真的知道。

           

          大師都是憑直覺辦事,可公司更希望通過數(shù)據(jù)或者規(guī)則來確定事情是否是對的,這種方式試圖在毀滅"專家,公司往往輕視專家的直覺,認為這是不科學(xué)不可重復(fù)。新手使用規(guī)則,而專家使用直覺,具備元認知能力metacognitive),或者叫具備自我認知能力的人往往出現(xiàn)在較高層次中。

          知道你不知道什么

          專家!=老師,教學(xué)是一門技能,你在某個領(lǐng)域是專家,但這并不能保證你可以將它教給別人。

           

               有效地使用德雷福斯模型

               十年磨一劍,也許需要一輩子或者更長?學(xué)漫漫路漫漫,我們需要積極實踐自己:

                需要一個明確定義的任務(wù)

                任務(wù)需要有適當?shù)碾y度——有挑戰(zhàn)性但可行

                任務(wù)環(huán)境可以提供大量反饋,以便于你采取行動

                提供重復(fù)犯錯和糾正錯誤的機會

                一旦你成為某個領(lǐng)域的專家,在別的領(lǐng)域成為專家就會變得更容易。你已經(jīng)有了現(xiàn)成的獲取知識的技能和模型構(gòu)建的能力。

               軟件開發(fā)的職業(yè)特征:

                程序員往往認為自己是一種工具,從而漠視工作,只是執(zhí)行分析師的指令,而不期望自己對項目的設(shè)計和架構(gòu)有所創(chuàng)見。

                由于薪酬等級的不平等,專家級的程序員爭先恐后的離開一線編碼,通過管理、教學(xué)或者巡回演講賺更多的錢。

                軟件工程教育開始受到質(zhì)疑。很多人認為正規(guī)的實踐模式是最好的教育方法。這種對正規(guī)方法和工具的過度依賴削弱了實踐中真正經(jīng)驗的作用。

                     R&D精神(Rip off and duplicate, 偷學(xué)技藝/偷師學(xué)藝),我們可以從他們的工作中借鑒很多經(jīng)驗教訓(xùn)并應(yīng)用到軟件開發(fā)中。

           

               勇于承擔(dān)責(zé)任:

                新手往往只是執(zhí)行命令,新手過渡到勝任者最大的區(qū)別在于能獨立解決問題
          和承擔(dān)責(zé)任。

                通過觀察和模仿來學(xué)習(xí)(R&D)。如果你有孩子你會發(fā)現(xiàn),他們很少照你說的做,而是大多時候在模仿你。

                模仿的同時就是實踐的過程,沒有實踐就沒有技能。模仿->吸收->創(chuàng)新

                保持實踐以維持專家水平,全世界最優(yōu)秀的那些專家沒有因為做了20年以上開發(fā)而不去編碼了,實踐是保持技能的唯一手段。

               警惕工具陷阱:

               曾經(jīng),在我剛接觸軟件領(lǐng)域的時候,曾一度認為UMLMDA以及TDD是未來解決軟件的必要良方,甚至也將其濫用,然而合宜的工具需要放到合宜的

               環(huán)境去運用,模型只是工具,而非鏡子。如果你需要創(chuàng)造力、直覺或者獨創(chuàng)能力,避免使用形式方法。

           

               再次考慮情境:

               高端的顧問最喜歡回答說:具體情況具體分析,當然他們是對的,他們的分析依賴于很多事情——所有那些專業(yè)人士懂得去尋找至關(guān)重要的細節(jié),同

               時也忽略無關(guān)的細節(jié)。

               在系統(tǒng)思維中,如面向?qū)ο缶幊蹋鞘挛镏g的聯(lián)系最讓人感興趣,而不是事物本身。這也是面向?qū)ο蠡幊痰奶攸c,你大多數(shù)時候在想事物本身的聯(lián)系,而實際問題的解決卻放到了后面,本人的目前的理解是,面向?qū)ο缶幊陶娴挠心敲粗匾矗炕蛟S只是在某些方面比較重要罷了,擴展性和低耦合的確是面向?qū)ο蟮膶嵺`的目的,可除此之外純?yōu)榱嗣嫦驅(qū)ο蠖袆樱痛嬖跒E用傾向了。例如java這種語言的面向?qū)ο蠹儗贋榻y(tǒng)一思想而設(shè)置的程序員枷鎖。

           

               日常中的德雷福斯模型:

                   新手需要快速成功和與情節(jié)無關(guān)的規(guī)則,而專家需要獲得全貌。理想情況下,你希望團隊里混合各種層次技能水平的人,擁有一個全部是專家的
     團隊存在它的難處。當所有人在考慮森林的時候,你也需要一些人來關(guān)注一棵棵大樹。

                   學(xué)習(xí)如何學(xué)習(xí)的技能。

           

          總結(jié):

               了解自己出于德雷福斯模型中的哪個階段,并自我評價,了解你的團隊成員,他們的技能階段,以及對你有何幫助。回顧曾經(jīng)團隊經(jīng)歷的問題,并運用德雷福斯模型解釋這些問題,對于已知的問題是否能通過德雷福斯模型解決或者避免?

                                   

           

          posted @ 2012-06-17 03:08 steven.cui 閱讀(469) | 評論 (0)編輯 收藏

          java的多線程Thread類提供了setName方法或者通過構(gòu)造器傳入name,來指定線程的名稱。

          近些時間在開源方面看到Netty,觀察到Netty的重命名線程的策略類:

          ThreadNameDeterminer。這個接口有兩個策略,一個是使用PROPOSED(建議名稱),還有個是CURRENT(當前名稱)

          當前名稱的策略是未實現(xiàn)的,可能為以后擴展考慮吧。

          另外就是ThreadRenamingRunnable這個類,這個類里面構(gòu)建函數(shù)傳入Runnable接口,和proposed建議名稱。

          由于本身ThreadRenamingRunnable也是實現(xiàn)Runnable類的,所以你在自己業(yè)務(wù)邏輯種還是照樣實現(xiàn)Runnable接口來寫邏輯,完全對業(yè)務(wù)代碼沒有侵入。

          代碼中大概是這樣的情況:

          public run() {
               //根據(jù)規(guī)則把線程名字進行修改
               try {
                    runnable.run(); // 調(diào)用傳入接口的run方法
               } finally {
                    if (renamed)
                         // 恢復(fù)之前的名字
               }
          }


          只需要在構(gòu)建的你的Runnable的時候,重新包裝一下即可:

          new ThreadRenamingRunnable(new OioWorker(acceptedChannel),

                                         "Old I/O server worker (parentId: " + channel.getId() + ", " + channel + ')'));


          這樣的Decorator模式,重新將Runnable接口進行了“裝飾”,使其具備了線程名稱的功能。

          Runnable接口還是原來的接口,對run方法的再次封裝使其具備了另外一項功能,這就是Decorator模式的精華所在。

          posted @ 2012-06-16 22:32 steven.cui 閱讀(1161) | 評論 (0)編輯 收藏

          判斷一個數(shù)是否是2的n次冪

          類似這樣的數(shù)字

          1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024 …


          if ((n & -n) == n)

          1 public class Is2Power {
          2      public static void main(String[] args) {
          3           for (int i = 0;i <= 1024; i++) {
          4                if ((i & -i) == i)
          5                     System.out.println(Integer.toBinaryString(i) + ", " + Integer.toBinaryString(-i) + " " + i);
          6           }
          7      }
          8 }

          posted @ 2012-06-16 22:26 steven.cui 閱讀(649) | 評論 (0)編輯 收藏

          業(yè)務(wù)上線后,在有大量并發(fā)后,出現(xiàn)了一個線程完全被占用的問題,后來通過得到j(luò)vm堆棧信息(kill -3)看出來是死鎖問題。

          由于業(yè)務(wù)邏輯代碼實在比較復(fù)雜,此處濾掉業(yè)務(wù)代碼把線程競爭關(guān)系展示出來:

          1線程———>獲得A鎖———>獲得B鎖———>釋放B鎖————>釋放A鎖

          2線程———>獲得A鎖———>釋放A鎖

          3線程-——————>獲得B鎖———>獲得A鎖


          問題就出在1和3線程之間的AB鎖嵌套導(dǎo)致死鎖問題,1線程在沒有獲得B鎖的時候,3線程開始獲得B鎖然后又得到了A鎖,這時候就完全釋放不了A鎖了,死鎖產(chǎn)生了。

          由于時間關(guān)系,問題是理清楚了,只要刪掉1線程的A鎖就可以了,當時還是仔細了解過是否刪除1線程A鎖,發(fā)現(xiàn)對業(yè)務(wù)A鎖是沒必要的。但是線程2會不會也會像剛才一樣產(chǎn)生線程死鎖呢?不會,因為線程2里并不會得到B鎖。

          1線程———>獲得B鎖———>釋放B鎖

          2線程-——————————>獲得A鎖————>釋放A鎖

          3線程———>獲得B鎖———>獲得A鎖————>釋放A鎖————>釋放B鎖


          問題是死鎖,但暴露了兩部分問題:

          1.過早的認為自己能控制好競爭關(guān)系,對線程間的競爭過早的做出了判斷

          2.每多設(shè)計一個鎖就增加了一個競爭的因素,盡量小心,一個鎖就有可能是一個地雷,一不小心就可能導(dǎo)致嚴重的問題。


          《java并發(fā)編程實踐》這本書中介紹過LeftRightLock,詳細了解這個問題的朋友可以去查下這本書的第十章 避免活躍性危險

          此書極其詳細的介紹了LeftRightLock出現(xiàn)的可能,有可能是因為自己編寫程序的疏忽導(dǎo)致,或者由于對鎖的認識不足導(dǎo)致,諸多原因都能找到解釋。

          posted @ 2012-06-16 22:22 steven.cui 閱讀(508) | 評論 (0)編輯 收藏

          NIO的理解,請參照:http://www.goldendoc.org/category/java-nio/

          Netty的一些理解,請參照:

          http://www.kafka0102.com/2010/06/167.html

          http://rdc.taobao.com/team/jm/archives/423


          Netty的高可靠性,可伸縮性,以及效率的確讓人著迷,為什么Netty這么快呢?

          Netty高效的原因:

          1. 實現(xiàn)了多路Selector用于讀和注冊,線程數(shù)量是cpu*2,reactor都是這么做的,自己處理寫事件,這個我在自己框架中也是這么做的,nio的selector處理注冊和讀,并且也優(yōu)化了wakeup,Netty中的wakeup也是優(yōu)化過的,本身一次wakeup對Nio并不大,但是大批量并發(fā)的時候就需要進行優(yōu)化處理了,只有當selector堵塞的時候進行wakeup,或者說需要下次立刻返回的時候wakeup。
          2. Netty在開啟多路讀寫的時候,用的是DirectBuffer,并用了SoftReferrence來做緩存優(yōu)化,減少傳輸數(shù)據(jù)的內(nèi)存移動和GC。還有預(yù)測數(shù)據(jù)算法,這個具體能不能提高有待討論
          3. 并發(fā)的控制,基于SEDA的設(shè)計理論構(gòu)建的高效事件模型,真正的異步處理,吞吐量和伸縮性都可以得到保證。


          nio的實現(xiàn)并不復(fù)雜,但想讓你的底層通訊,效率,以及可伸縮性和高可靠性做好,還是極具挑戰(zhàn)性的。


          目前有個項目是自己寫的nio,但效率比起netty來,小了幾個數(shù)量級,當然以本人一己之力能做到目前這個情況,還算自己滿意,也用到生產(chǎn)環(huán)境中了,一個web game,及時性要求很高,一臺server,5000人沒問題。同時廣播消息在10000人以內(nèi),當然有些優(yōu)化是在業(yè)務(wù)邏輯層面的。當然比起netty的效率來講還是差了幾個數(shù)量級。


          除了高效,Netty在擴展性方面做的不錯:

          1. 豐富的decoder/encoder實現(xiàn),你可以輕松的繼承一個類實現(xiàn)自己的邏輯,例如游戲中,直接繼承FiledLengthBaseFrameDecoder即可。
          2. 自行添加decoder或者encoder,自由的控制事件流向順序,通過這個,可以實現(xiàn)一些協(xié)議加密解密,協(xié)議過濾器,統(tǒng)計工具等等
          3. 提供很多工具類:Timeout的一些實現(xiàn),還有ChannelBuffers的一些工具,通常情況下,我們?yōu)榱藴p少對Netty的依賴,會自己再封裝一層,以完全達到脫離Netty的目的,都會再次封裝一層ChannelBuffer,這樣目的是不要讓上層邏輯跟底層通訊有任何關(guān)聯(lián),降低耦合,當然也在為考慮更換底層通訊而不影響上層邏輯。
          4. 提供監(jiān)聽底層消息的ChannelFuture,例如發(fā)送完消息可以斷開連接等等
          5. 可調(diào)控的通訊架構(gòu),可以根據(jù)業(yè)務(wù)的吞吐量來調(diào)整,Netty的各項參數(shù)不只有socket的一些設(shè)置,還能控制事件流順序和吞吐量的大小等等。


          最后,基于Netty我簡單封裝了一個web game所具備的一些GameBuffer,目前比較簡陋,后續(xù)可能加入一些別的功能。


          項目在:https://github.com/cuixin/XGameEnginee/


          posted @ 2012-05-15 17:09 steven.cui 閱讀(13460) | 評論 (7)編輯 收藏

          主站蜘蛛池模板: 白河县| 随州市| 南丹县| 彭水| 泾阳县| 巩义市| 沁水县| 周口市| 文化| 资溪县| 贞丰县| 屯留县| 芮城县| 托克托县| 霍山县| 余干县| 营口市| 阿拉善左旗| 庆元县| 溧阳市| 安泽县| 隆林| 策勒县| 聂拉木县| 象州县| 阳城县| 华宁县| 黄山市| 镇原县| 张家界市| 交口县| 宣威市| 巴彦淖尔市| 石棉县| 荃湾区| 怀仁县| 阜宁县| 金山区| 周口市| 潮州市| 禹州市|