欧美色欧美亚洲高清在线观看,国产特黄特色a级在线视频,国产一区视频一区欧美,亚洲成a 人在线观看中文

  1. <ul id="fwlom"></ul>

    <object id="fwlom"></object>

    <span id="fwlom"></span><dfn id="fwlom"></dfn>

      <object id="fwlom"></object>

      Java系統(tǒng)程序員修煉之道

      時(shí)間:2019-05-14 16:12:29下載本文作者:會(huì)員上傳
      簡(jiǎn)介:寫(xiě)寫(xiě)幫文庫(kù)小編為你整理了多篇相關(guān)的《Java系統(tǒng)程序員修煉之道》,但愿對(duì)你工作學(xué)習(xí)有幫助,當(dāng)然你在寫(xiě)寫(xiě)幫文庫(kù)還可以找到更多《Java系統(tǒng)程序員修煉之道》。

      第一篇:Java系統(tǒng)程序員修煉之道

      Java系統(tǒng)程序員修煉之道

      ——?jiǎng)恿?jié)點(diǎn)java 一:Java語(yǔ)言學(xué)習(xí)

      對(duì)線程(thread),串行化,反射,網(wǎng)絡(luò)編程,JNI技術(shù),容器(Map,List, Iterator), 類加載器(ClassLoader),輸入輸出流,垃圾回收機(jī)制,有比較深入的了解,最起碼做過(guò)項(xiàng)目應(yīng)用。有過(guò)Java項(xiàng)目的性能優(yōu)化經(jīng)驗(yàn),最起碼掌握一種性能監(jiān)視工具的使用,熟悉JVM參數(shù),最起碼知道可以在JVM啟動(dòng)時(shí)指定不同垃圾回收機(jī)制,以及不同垃圾回收機(jī)制之間的差別,熟悉JVM參數(shù)優(yōu)化。二:J2EE方面

      最好知道JDBC規(guī)范是怎么回事情,面對(duì)Oracle數(shù)據(jù)庫(kù)如果告訴你JDBC驅(qū)動(dòng)不能用了,你還知道有OCI驅(qū)動(dòng)可以。掌握常見(jiàn)的SQL語(yǔ)句,熟悉JMS,JNDI等組件,掌握一套web開(kāi)發(fā)模式,從前臺(tái)到后臺(tái),有能力整合好這樣的框架。理解并掌握MVC思想,像SSH已經(jīng)實(shí)現(xiàn)了MVC的分層,幾乎不需要你自己再實(shí)現(xiàn),假設(shè)你開(kāi)發(fā)一個(gè)簡(jiǎn)單的Swing程序,你能MVC就說(shuō)明你真的掌握了MVC的精髓。有能力在J2EE前端開(kāi)發(fā)中構(gòu)建自己的MVC模式,知道什么是WEB2.0,知道什么是SOA,SaaS,SaaP等含義 三:理解并能合理運(yùn)用設(shè)計(jì)模式,UML建模

      知道并理解設(shè)計(jì)模式中蘊(yùn)含的幾種基本原則如:里氏替換原則,開(kāi)閉原則,合成復(fù)用原則,依賴倒置原則有很好的理解,并能舉例說(shuō)明。對(duì)常用的設(shè)計(jì)模式如工廠模式,單例模式,觀察者模式,責(zé)任鏈模式,橋接模式等知道靈活運(yùn)用,明白什么是回調(diào)(Callback)。最后用一位高人話來(lái)總結(jié)設(shè)計(jì)模式,它是為了讓軟件更容易被別人讀懂,更容易維護(hù)而產(chǎn)生,設(shè)計(jì)模式本質(zhì)是程序員之間的交流,如果A用工廠模式設(shè)計(jì)一個(gè)模塊B來(lái)接替,A只要說(shuō)該模塊是工廠模式實(shí)現(xiàn),B維護(hù)起來(lái)應(yīng)該容易得多,所以設(shè)計(jì)模式是關(guān)于交流,不關(guān)于代碼。切忌濫用設(shè)計(jì)模式。學(xué)會(huì)使用UML建模工具至少熟悉一種URL建模工具。四:注重用戶體驗(yàn),掌握KISS原則,知道歐卡姆剃刀原則

      顧客就是上帝這個(gè)口號(hào)我們已經(jīng)喊了N年了,程序員的勞動(dòng)成果最終也需要轉(zhuǎn)換為服務(wù)提供給客戶,用戶體驗(yàn)至關(guān)重要,常常看到的場(chǎng)景是功能實(shí)現(xiàn)了,軟件很難使用,程序員有個(gè)很充足的理由我不是美工,其實(shí)注重用戶體驗(yàn)跟美工八桿子也打不到一起,F(xiàn)oxMail的成功在很大程度是用戶體驗(yàn)的成功,友好,清晰的用戶提示,強(qiáng)的容錯(cuò)與糾錯(cuò)設(shè)計(jì)是獲得好的用戶體驗(yàn)的不二法門(mén)。傻瓜相機(jī)顧名思義傻子都會(huì)使用,這個(gè)就著名的KISS原則(Keep itsimple and stupid)意思是UI設(shè)計(jì)要簡(jiǎn)單明了,傻子一看就知道怎么用,想想我們做出來(lái)的東西,對(duì)照說(shuō)明書(shū)都不知道怎么用。另外一個(gè)就是最著名的例子IPhone手機(jī)外觀設(shè)計(jì),是典型的歐卡姆剃刀設(shè)計(jì)原則來(lái)完成人機(jī)交互。五:自動(dòng)測(cè)試與軟件配置管理(SCM)實(shí)現(xiàn)

      知道什么是軟件配置管理,知道Hudson運(yùn)用該工具SCM,知道怎么獲取測(cè)試代碼覆蓋率,Java有效代碼行數(shù)(NCSS),完成firebug,JDepend等工具集成ant/maven。熟悉并注重在開(kāi)發(fā)過(guò)程中使用JUnit單元測(cè)試,理解白盒測(cè)試規(guī)范。六:熟悉常見(jiàn)的網(wǎng)絡(luò)通信協(xié)議

      對(duì)HTTP協(xié)議,知道POST, GET的區(qū)別是什么,閱讀過(guò)HTTP相關(guān)的RFC文檔。學(xué)會(huì)使用sniffer工具查看數(shù)據(jù)包,幫助查找與調(diào)試程序,知道TCP與UDP的區(qū)別,知道并理解E-Mail發(fā)送與接受的協(xié)議如SMTP,POP3,IMAP等協(xié)議,了解MIME與Base64編碼。知道組播是怎么回事情。

      七:面向市場(chǎng),永遠(yuǎn)對(duì)新技術(shù)保持渴望

      計(jì)算機(jī)技術(shù)的發(fā)展日新月異,做為IT行業(yè)的軟件開(kāi)發(fā)人員要不斷的給自己充電,更新自己的技術(shù)與時(shí)代保持同步,同時(shí)還要面向市場(chǎng),華為總裁任正非說(shuō)過(guò)-“華為的技術(shù)革新必須面向市場(chǎng)”,作為程序員同樣要有市場(chǎng)意識(shí),很多人都后悔沒(méi)有在android剛出來(lái)的時(shí)候加以關(guān)注學(xué)習(xí)。那些很早關(guān)注android開(kāi)發(fā)技術(shù)的很多程序員因此獲得豐厚回報(bào)。如今HTML5得到越來(lái)越多的瀏覽器廠家支持,你是否已經(jīng)跟上腳步,開(kāi)始學(xué)習(xí)。八:保持謙虛,三人行必有我?guī)?/p>

      喬幫主說(shuō)他要保持初心,努力學(xué)習(xí),我等更應(yīng)該保持謙虛,IT技術(shù)發(fā)展日新月異,在你眼中不可能實(shí)現(xiàn)的技術(shù),也許別人早已經(jīng)有思路。保持謙虛就有機(jī)會(huì)吸取別人身上的長(zhǎng)處,古人有云:滿招損,謙受益。一個(gè)得道的高人更是說(shuō)出了”下下人,上上智”的禪語(yǔ)。永遠(yuǎn)不要拒絕幫助你周?chē)娜私鉀Q難題,解決難題是進(jìn)步最快途徑。不要放棄任何一次可以提升自己技術(shù)與能力的機(jī)會(huì)。

      九:養(yǎng)成總結(jié)的習(xí)慣,不斷反思

      上學(xué)的時(shí)候老師常讓寫(xiě)小結(jié),也沒(méi)總結(jié)出來(lái)所以然,以至于工作以后再也不提這檔子事情,建議每個(gè)項(xiàng)目做完以后對(duì)自己都有個(gè)小結(jié),總結(jié)自己在項(xiàng)目里面學(xué)到了什么,反問(wèn)自己能不能完成在不需要?jiǎng)e人幫助的情況下自己完成這樣的系統(tǒng)搭建,是否熟悉與掌握項(xiàng)目中所用到的技術(shù),即使有些東西不是你負(fù)責(zé)完成的但是什么也不能阻擋一顆求知的心,總結(jié)要盡量詳細(xì)記錄你遇到那些難題是怎么一個(gè)一個(gè)的解決的,下次再遇到你是否可以很快解決或者避免這樣的問(wèn)題。有總結(jié)才有提高,孔子曰:學(xué)而不思則罔,如果我們只是coding到吐血,不思考,不總結(jié)提高,永遠(yuǎn)不可能有能有本質(zhì)提高,秦相李斯有云:“泰山不讓土壤,故能成其大,河海不擇細(xì)流,故能就其深”,點(diǎn)滴積累不斷總結(jié)方能量變導(dǎo)致質(zhì)變。十:數(shù)學(xué)功底與算法知識(shí) 用任何編程語(yǔ)言開(kāi)發(fā)應(yīng)用,都離不開(kāi)核心算法支持,很多國(guó)外的軟件單單從UI上看,恐怕寫(xiě)幾年程序的人都可以模仿,但是UI之下的那些真實(shí)深淺不一,相信不是你想模仿就可以模仿的,為什么我們?cè)絹?lái)越山寨,因?yàn)槲覀儧](méi)有核心競(jìng)爭(zhēng)力,對(duì)于程序員來(lái)說(shuō)算法與數(shù)學(xué)顯然是他最重要的核心競(jìng)爭(zhēng)力之一?!端惴▽?dǎo)論》,《編程珠璣》等書(shū)絕對(duì)值得讀十遍。微軟亞洲研究院視覺(jué)計(jì)算組負(fù)責(zé)人在一次演講中說(shuō)到他們招人的標(biāo)準(zhǔn)是“三好學(xué)生– 數(shù)學(xué)好,編程好,態(tài)度好”。可是現(xiàn)實(shí)的普遍情況卻是-微機(jī)原理鬧危機(jī),匯編語(yǔ)言不會(huì)變,實(shí)變函數(shù)學(xué)十遍。計(jì)算機(jī)基礎(chǔ)知識(shí)被大家普遍忽視。從今天開(kāi)始好好學(xué)習(xí)吧…… 十一:Java代碼反編譯與代碼保護(hù)

      Java編譯產(chǎn)生字節(jié)碼,因而可以被輕松的逆向工程(反編譯),微軟的C#生產(chǎn)的DLL也一樣可以被輕松反編譯。正式由于這個(gè)原因產(chǎn)生了許多Java開(kāi)源的代碼保護(hù)工具,而Proguar是其中佼佼者,已經(jīng)被google集成在android之中用于Java代碼保護(hù) 十二:努力成為某個(gè)行業(yè)或者領(lǐng)域骨干

      面對(duì)漫長(zhǎng)的職業(yè)生涯,要想不被淘汰,必須具備一招鮮吃遍天下的能力,選擇自己感興趣的方向,努力而深入的研究,計(jì)算機(jī)技術(shù)發(fā)展到今天已經(jīng)細(xì)分很細(xì),努力研究一種Java開(kāi)源框架或者開(kāi)源HTTP服務(wù)器源碼或者研究過(guò)網(wǎng)絡(luò)爬蟲(chóng)源碼或者WEBKIT內(nèi)核,不愁沒(méi)有人要你。如果你是非常了解金融,企業(yè)ERP,證券,保險(xiǎn),移動(dòng)應(yīng)用行業(yè)的應(yīng)用開(kāi)發(fā)業(yè)務(wù)的人,一樣不用愁工作。這些知識(shí)不隨語(yǔ)言而改變,努力做一個(gè)有核心競(jìng)爭(zhēng)力的Java程序員。十三:提高語(yǔ)言與書(shū)面表達(dá)能力,掌握基礎(chǔ)的項(xiàng)目管理知識(shí)

      文檔與語(yǔ)言表達(dá)能力是最好的向外界展現(xiàn)自己能力的方式,很多程序員編程能力很高,表達(dá)能力一般,Linux能夠成功,除了歸功于網(wǎng)絡(luò)社區(qū)的力量之外,也得益于Linux作者本人給各大基金會(huì)寫(xiě)信,宣傳推廣,試想如果沒(méi)有良好的書(shū)面語(yǔ)言表達(dá)能力,即使Linux系統(tǒng)再優(yōu)秀,卻無(wú)法被準(zhǔn)確表達(dá),失去各大基金會(huì)的支持,Linux還會(huì)像今天這么好的局面嘛。所以重視文檔,重視提升溝通與表達(dá)能力,才有可能成為Java系統(tǒng)程序員。掌握基本的2/8原則,學(xué)會(huì)將模塊細(xì)化分配給不同的人,預(yù)見(jiàn)并控制項(xiàng)目風(fēng)險(xiǎn),把握項(xiàng)目進(jìn)度,優(yōu)化流程,合理的時(shí)間管理,了解TDD,熟悉敏捷開(kāi)發(fā)模式,常規(guī)軟件開(kāi)發(fā)模式。

      第二篇:Java程序員修煉之道

      從2002開(kāi)始接觸Java學(xué)會(huì)HelloWorld這么經(jīng)典的程序到如今不知不覺(jué)已經(jīng)十年啦,十年中

      親耳聽(tīng)到過(guò)不少大牛的演講,見(jiàn)到過(guò)項(xiàng)目中的神人在鍵盤(pán)上運(yùn)指如飛的編程速度,當(dāng)時(shí)就

      被震撼了。當(dāng)編程越來(lái)越成體力活,我們還能有自己的思想,還能修煉為Java系統(tǒng)級(jí)別的

      程序員嘛?學(xué)習(xí)與修煉以下知識(shí)與技能,幫你早日達(dá)成愿望。

      一:Java語(yǔ)言學(xué)習(xí)

      對(duì)線程(thread),串行化,反射,網(wǎng)絡(luò)編程,JNI技術(shù),容器(Map,List, Iterator), 類加載器

      (ClassLoader),輸入輸出流,垃圾回收機(jī)制,有比較深入的了解,最起碼做過(guò)項(xiàng)目應(yīng)用。有

      過(guò)Java項(xiàng)目的性能優(yōu)化經(jīng)驗(yàn),最起碼掌握一種性能監(jiān)視工具的使用,熟悉JVM參數(shù),最起

      碼知道可以在JVM啟動(dòng)時(shí)指定不同垃圾回收機(jī)制,以及不同垃圾回收機(jī)制之間的

      差別,熟悉JVM參數(shù)優(yōu)化。

      二:J2EE方面

      最好知道JDBC規(guī)范是怎么回事情,面對(duì)Oracle數(shù)據(jù)庫(kù)如果告訴你JDBC驅(qū)動(dòng)不能用了,你

      還知道有OCI驅(qū)動(dòng)可以。掌握常見(jiàn)的SQL語(yǔ)句,熟悉JMS,JNDI等組件,掌握一套web開(kāi)

      發(fā)模式,從前臺(tái)到后臺(tái),有能力整合好這樣的框架。理解并掌握MVC思想,像SSH已經(jīng)實(shí)

      現(xiàn)了MVC的分層,幾乎不需要你自己再實(shí)現(xiàn),假設(shè)你開(kāi)發(fā)一個(gè)簡(jiǎn)單的Swing程序,你能MVC

      就說(shuō)明你真的掌握了MVC的精髓。有能力在J2EE前端開(kāi)發(fā)中構(gòu)建自己的MVC模式,知道

      什么是WEB2.0,知道什么是SOA,SaaS,SaaP等含義

      三:理解并能合理運(yùn)用設(shè)計(jì)模式,UML建模

      知道并理解設(shè)計(jì)模式中蘊(yùn)含的幾種基本原則如:里氏替換原則,開(kāi)閉原則,合成復(fù)用原則,依賴倒置原則有很好的理解,并能舉例說(shuō)明。對(duì)常用的設(shè)計(jì)模式如工廠模式,單例模式,觀

      察者模式,責(zé)任鏈模式,橋接模式等知道靈活運(yùn)用,明白什么是回調(diào)(Callback)。最后用一位

      高人話來(lái)總結(jié)設(shè)計(jì)模式,它是為了讓軟件更容易被別人讀懂,更容易維護(hù)而產(chǎn)生,設(shè)計(jì)模

      式本質(zhì)是程序員之間的交流,如果A用工廠模式設(shè)計(jì)一個(gè)模塊B來(lái)接替,A只要說(shuō)該模塊是

      工廠模式實(shí)現(xiàn),B維護(hù)起來(lái)應(yīng)該容易得多,所以設(shè)計(jì)模式是關(guān)于交流,不關(guān)于代碼。切忌濫

      用設(shè)計(jì)模式。學(xué)會(huì)使用UML建模工具至少熟悉一種URL建模工具。

      四:注重用戶體驗(yàn),掌握KISS原則,知道歐卡姆剃刀原則

      顧客就是上帝這個(gè)口號(hào)我們已經(jīng)喊了N年了,程序員的勞動(dòng)成果最終也需要轉(zhuǎn)換為服務(wù)提

      供給客戶,用戶體驗(yàn)至關(guān)重要,常??吹降膱?chǎng)景是功能實(shí)現(xiàn)了,軟件很難使用,程序員有個(gè)

      很充足的理由我不是美工,其實(shí)注重用戶體驗(yàn)跟美工八桿子也打不到一起,F(xiàn)oxMail的成功

      在很大程度是用戶體驗(yàn)的成功,友好,清晰的用戶提示,強(qiáng)的容錯(cuò)與糾錯(cuò)設(shè)計(jì)是獲得好的

      用戶體驗(yàn)的不二法門(mén)。傻瓜相機(jī)顧名思義傻子都會(huì)使用,這個(gè)就著名的KISS原則(Keep it

      simple and stupid)意思是UI設(shè)計(jì)要簡(jiǎn)單明了,傻子一看就知道怎么用,想想我們做出來(lái)的

      東西,對(duì)照說(shuō)明書(shū)都不知道怎么用。另外一個(gè)就是最著名的例子IPhone手機(jī)外觀設(shè)計(jì),是 典型的歐卡姆剃刀設(shè)計(jì)原則來(lái)完成人機(jī)交互。

      五:自動(dòng)測(cè)試與軟件配置管理(SCM)實(shí)現(xiàn)

      知道什么是軟件配置管理,知道Hudson微機(jī)原理鬧危機(jī),匯編語(yǔ)言不會(huì)變,實(shí)變函數(shù)學(xué)

      十遍。計(jì)算機(jī)基礎(chǔ)知識(shí)被大家普遍忽視。從今天開(kāi)始好好學(xué)習(xí)吧……

      十一:Java代碼反編譯與代碼保護(hù)

      Java編譯產(chǎn)生字節(jié)碼,因而可以被輕松的逆向工程(反編譯),微軟的C#生產(chǎn)的DLL也一樣可

      以被輕松反編譯。正式由于這個(gè)原因產(chǎn)生了許多Java開(kāi)源的代碼保護(hù)工具,而Proguard是

      其中佼佼者,已經(jīng)被google集成在android之中用于Java代碼保護(hù),訪問(wèn)這里了解更多:

      http://proguard.sourceforge.net/

      十二:努力成為某個(gè)行業(yè)或者領(lǐng)域骨干

      面對(duì)漫長(zhǎng)的職業(yè)生涯,要想不被淘汰,必須具備一招鮮吃遍天下的能力,選擇自己感興趣的

      方向,努力而深入的研究,計(jì)算機(jī)技術(shù)發(fā)展到今天已經(jīng)細(xì)分很細(xì),努力研究一種Java開(kāi)源

      框架或者開(kāi)源HTTP服務(wù)器源碼或者研究過(guò)網(wǎng)絡(luò)爬蟲(chóng)源碼或者WEBKIT內(nèi)核,不愁沒(méi)有人要

      你。如果你是非常了解金融,企業(yè)ERP,證券,保險(xiǎn),移動(dòng)應(yīng)用行業(yè)的應(yīng)用開(kāi)發(fā)業(yè)務(wù)的人,一樣不用愁工作。這些知識(shí)不隨語(yǔ)言而改變,努力做一個(gè)有核心競(jìng)爭(zhēng)力的Java程序員。

      十三:提高語(yǔ)言與書(shū)面表達(dá)能力,掌握基礎(chǔ)的項(xiàng)目管理知識(shí)

      文檔與語(yǔ)言表達(dá)能力是最好的向外界展現(xiàn)自己能力的方式,很多程序員編程能力很高,表達(dá)

      能力一般,Linux能夠成功,除了歸功于網(wǎng)絡(luò)社區(qū)的力量之外,也得益于Linux作者本人給各

      大基金會(huì)寫(xiě)信,宣傳推廣,試想如果沒(méi)有良好的書(shū)面語(yǔ)言表達(dá)能力,即使Linux系統(tǒng)再優(yōu)秀,卻無(wú)法被準(zhǔn)確表達(dá),失去各大基金會(huì)的支持,Linux還會(huì)像今天這么好的局面嘛。所以重視

      文檔,重視提升溝通與表達(dá)能力,才有可能成為Java系統(tǒng)程序員。掌握基本的2/8原則,學(xué)

      會(huì)將模塊細(xì)化分配給不同的人,預(yù)見(jiàn)并控制項(xiàng)目風(fēng)險(xiǎn),把握項(xiàng)目進(jìn)度,優(yōu)化流程,合理的時(shí)

      間管理,了解TDD,熟悉敏捷開(kāi)發(fā)模式,常規(guī)軟件開(kāi)發(fā)模式。

      十四:掌握英語(yǔ),良好的讀寫(xiě)能力

      英語(yǔ)是計(jì)算機(jī)的母語(yǔ),掌握好英語(yǔ)對(duì)于閱讀英文資料學(xué)習(xí)新技術(shù)大有幫助,我的建議是盡量

      讀英文原版書(shū),如果是算法方面的可能會(huì)困難一點(diǎn),但是其它像設(shè)計(jì)模式,軟件工程,OO

      編程思想等盡量讀原版,提高自己的英文水平,多多訪問(wèn)開(kāi)發(fā)者,code project,程序員天堂,Pc-magazine等英文IT網(wǎng)站。英語(yǔ)絕對(duì)是你必須修煉與提高的技能。此外英語(yǔ)好在外資企業(yè)

      尤其重要,只有外語(yǔ)足夠好才可能在外資企業(yè)中突破職業(yè)瓶頸,向上發(fā)展。

      第三篇:Java程序員修煉十大過(guò)程

      Java程序員修煉十大過(guò)程

      學(xué)習(xí)java這么久,見(jiàn)到過(guò)項(xiàng)目中的神人在鍵盤(pán)上運(yùn)指如飛的編程速度,當(dāng)時(shí)就被震撼了。當(dāng)編程越來(lái)越成體力活,我們還能有自己的思想,還能修煉為Java系統(tǒng)級(jí)別的程序員嘛?學(xué)習(xí)與修煉以下知識(shí)與技能,幫你早日達(dá)成愿望。

      一、努力成為某個(gè)行業(yè)或者領(lǐng)域骨干

      面對(duì)漫長(zhǎng)的職業(yè)生涯,要想不被淘汰,必須具備一招鮮吃遍天下的能力,選擇自己感興趣的方向,努力而深入的研究,計(jì)算機(jī)技術(shù)發(fā)展到今天已經(jīng)細(xì)分很細(xì),努力研究一種Java開(kāi)源框架或者開(kāi)源HTTP服務(wù)器源碼或者研究過(guò)網(wǎng)絡(luò)爬蟲(chóng)源碼或者WEBKIT內(nèi)核,不愁沒(méi)有人要你。如果你是非常了解金融,企業(yè)ERP,證券,保險(xiǎn),移動(dòng)應(yīng)用行業(yè)的應(yīng)用開(kāi)發(fā)業(yè)務(wù)的人,一樣不用愁工作。這些知識(shí)不隨語(yǔ)言而改變,努力做一個(gè)有核心競(jìng)爭(zhēng)力的Java程序員。

      二、保持謙虛,三人行必有我?guī)?/p>

      喬幫主說(shuō)他要保持初心,努力學(xué)習(xí),我等更應(yīng)該保持謙虛,IT技術(shù)發(fā)展日新月異,在你眼中不可能實(shí)現(xiàn)的技術(shù),也許別人早已經(jīng)有思路。保持謙虛就有機(jī)會(huì)吸取別人身上的長(zhǎng)處,古人有云:滿招損,謙受益。一個(gè)得道的高人更是說(shuō)出了“下下人,上上智”的禪語(yǔ)。永遠(yuǎn)不要拒絕幫助你周?chē)娜私鉀Q難題,解決難題是進(jìn)步最快途徑。不要放棄任何一次可以提升自己技術(shù)與能力的機(jī)會(huì)。

      三、熟悉常見(jiàn)的網(wǎng)絡(luò)通信協(xié)議

      對(duì)HTTP協(xié)議,知道POST, GET的區(qū)別是什么,閱讀過(guò)HTTP相關(guān)的RFC文檔。學(xué)會(huì)使用sniffer工具查看數(shù)據(jù)包,幫助查找與調(diào)試程序,知道TCP與UDP的區(qū)別,知道并理解E-Mail發(fā)送與接受的協(xié)議如SMTP,POP3,IMAP等協(xié)議,了解MIME與Base64編碼。知道組播是怎么回事情。

      四、理解并能合理運(yùn)用設(shè)計(jì)模式,UML建模

      知道并理解設(shè)計(jì)模式中蘊(yùn)含的幾種基本原則如:里氏替換原則,開(kāi)閉原則,合成復(fù)用原則,依賴倒置原則有很好的理解,并能舉例說(shuō)明。對(duì)常用的設(shè)計(jì)模式如工廠模式,單例模式,觀察者模式,責(zé)任鏈模式,橋接模式等知道靈活運(yùn)用,明白什么是回調(diào)(Callback)。最后用一位高人話來(lái)總結(jié)設(shè)計(jì)模式,它是為了讓軟件更容易被別人讀懂,更容易維護(hù)而產(chǎn)生,設(shè)計(jì)模式本質(zhì)是程序員之間的交流,如果A用工廠模式設(shè)計(jì)一個(gè)模塊B來(lái)接替,A只要說(shuō)該模塊是工廠模式實(shí)現(xiàn),B維護(hù)起來(lái)應(yīng)該容易得多,所以設(shè)計(jì)模式是關(guān)于交流,不關(guān)于代碼。切忌濫用設(shè)計(jì)模式。學(xué)會(huì)使用UML建模工具至少熟悉一種URL建模工具。

      五、自動(dòng)測(cè)試與軟件配置管理(SCM)實(shí)現(xiàn)

      知道什么是軟件配置管理,知道Hudson-http://java.net/projects/hudson/運(yùn)用該工具SCM,知道怎么獲取測(cè)試代碼覆蓋率,Java有效代碼行數(shù)(NCSS),完成firebug,JDepend等工具集成ant/maven.熟悉并注重在開(kāi)發(fā)過(guò)程中使用JUnit單元測(cè)試,理解白盒測(cè)試規(guī)范。

      六、Java語(yǔ)言學(xué)習(xí)

      對(duì)線程(thread),串行化,反射,網(wǎng)絡(luò)編程,JNI技術(shù),容器(Map,List, Iterator),類加載器(ClassLoader),輸入輸出流,垃圾回收機(jī)制,有比較深入的了解,最起碼做過(guò)項(xiàng)目應(yīng)用。有過(guò)Java項(xiàng)目的性能優(yōu)化經(jīng)驗(yàn),最起碼掌握一種性能監(jiān)視工具的使用,熟悉JVM參數(shù),最起碼知道可以在JVM啟動(dòng)時(shí)指定不同垃圾回收機(jī)制,以及不同垃圾回收機(jī)制之間的差別,熟悉JVM參數(shù)優(yōu)化。

      七、掌握英語(yǔ),良好的讀寫(xiě)能力

      英語(yǔ)是計(jì)算機(jī)的母語(yǔ),掌握好英語(yǔ)對(duì)于閱讀英文資料學(xué)習(xí)新技術(shù)大有幫助,我的建議是盡量讀英

      文原版書(shū),如果是算法方面的可能會(huì)困難一點(diǎn),但是其它像設(shè)計(jì)模式,軟件工程,OO編程思想等盡量讀原版,提高自己的英文水平,多多訪問(wèn)開(kāi)發(fā)者,code project,程序員天堂,Pc-magazine等英文IT網(wǎng)站。英語(yǔ)絕對(duì)是你必須修煉與提高的技能。此外英語(yǔ)好在外資企業(yè)尤其重要,只有外語(yǔ)足夠好才可能在外資企業(yè)中突破職業(yè)瓶頸,向上發(fā)展。

      八、養(yǎng)成總結(jié)的習(xí)慣,不斷反思

      上學(xué)的時(shí)候老師常讓寫(xiě)小結(jié),也沒(méi)總結(jié)出來(lái)所以然,以至于工作以后再也不提這檔子事情,建議每個(gè)項(xiàng)目做完以后對(duì)自己都有個(gè)小結(jié),總結(jié)自己在項(xiàng)目里面學(xué)到了什么,反問(wèn)自己能不能完成在不需要?jiǎng)e人幫助的情況下自己完成這樣的系統(tǒng)搭建,是否熟悉與掌握項(xiàng)目中所用到的技術(shù),即使有些東西不是你負(fù)責(zé)完成的但是什么也不能阻擋一顆求知的心,總結(jié)要盡量詳細(xì)記錄你遇到那些難題是怎么一個(gè)一個(gè)的解決的,下次再遇到你是否可以很快解決或者避免這樣的問(wèn)題。有總結(jié)才有提高,孔子曰:學(xué)而不思則罔,如果我們只是coding到吐血,不思考,不總結(jié)提高,永遠(yuǎn)不可能有能有本質(zhì)提高,秦相李斯有云:“泰山不讓土壤,故能成其大,河海不擇細(xì)流,故能就其深”,點(diǎn)滴積累不斷總結(jié)方能量變導(dǎo)致質(zhì)變。

      九、Java代碼反編譯與代碼保護(hù)

      Java編譯產(chǎn)生字節(jié)碼,因而可以被輕松的逆向工程(反編譯),微軟的C#生產(chǎn)的DLL也一樣可以被輕松反編譯。正式由于這個(gè)原因產(chǎn)生了許多Java開(kāi)源的代碼保護(hù)工具,而Proguard是其中佼佼者,已經(jīng)被google集成在android之中用于Java代碼保護(hù)。

      十、面向市場(chǎng),永遠(yuǎn)對(duì)新技術(shù)保持渴望

      計(jì)算機(jī)技術(shù)的發(fā)展日新月異,做為IT行業(yè)的軟件開(kāi)發(fā)人員要不斷的給自己充電,更新自己的技術(shù)與時(shí)代保持同步,同時(shí)還要面向市場(chǎng),華為總裁任正非說(shuō)過(guò)-“華為的技術(shù)革新必須面向市場(chǎng)”,作為程序員同樣要有市場(chǎng)意識(shí),很多人都后悔沒(méi)有在android剛出來(lái)的時(shí)候加以關(guān)注學(xué)習(xí)。那些很早關(guān)注android開(kāi)發(fā)技術(shù)的很多程序員因此獲得豐厚回報(bào)。如今HTML5得到越來(lái)越多的瀏覽器廠家

      支持,你是否已經(jīng)跟上腳步,開(kāi)始學(xué)習(xí)。

      第四篇:程序員修煉 收藏

      程序員修煉 收藏

      程序就是一系列按步驟進(jìn)行的操作序列,它有好多種級(jí)別,比如最低級(jí)的微程序、次低級(jí)的匯編程序、高級(jí)的各種編程語(yǔ)言程序、最高級(jí)的腳本語(yǔ)言程序,也許我列的不對(duì),但沒(méi)關(guān)系,我要說(shuō)的是不管是那個(gè)級(jí)別的程序,其本質(zhì)都是操作的邏輯序列。大多數(shù)系統(tǒng)和應(yīng)用程序都是建立在高級(jí)編程語(yǔ)言上的,比如C、C++、C#、FORTRAN、BISIC、JAVA等等,就讓我們只關(guān)注這一級(jí)的編程能力吧。因此如果一個(gè)程序員的邏輯能力不高,他永遠(yuǎn)都不能成為一名具有合格職業(yè)水準(zhǔn)的程序員,我們?cè)谙旅娴挠懻撚嘘P(guān)編程能力的方方面面,最終都是為了最大程度地提高和實(shí)現(xiàn)一名程序員的邏輯能力。

      一、掌握基礎(chǔ)知識(shí):十六年寒窗的持續(xù)積累

      從7歲讀小學(xué)起,經(jīng)過(guò)16年的學(xué)習(xí),你從軟件專業(yè)本科畢業(yè)后,必須完成以下幾門(mén)專業(yè)課程的學(xué)習(xí):計(jì)算機(jī)組成、操作系統(tǒng)原理、匯編語(yǔ)言、數(shù)據(jù)結(jié)構(gòu)、編譯原理、數(shù)據(jù)庫(kù)原理、軟件工程、結(jié)構(gòu)性設(shè)計(jì)語(yǔ)言(PASCAL、C)、面向?qū)ο笤O(shè)計(jì)語(yǔ)言(C++、C#)、計(jì)算機(jī)網(wǎng)絡(luò)等,你最好還懂一些算法分析、分布式系統(tǒng)、計(jì)算機(jī)圖形學(xué)、形式邏輯、人工智能原理、軟件設(shè)計(jì)模式、軟件構(gòu)架/框架等研究生的課程,16年來(lái),你積累的除了知識(shí),更重要的是形成最適合自己的學(xué)習(xí)方法和工作方法。這些是你具備程序員職業(yè)水準(zhǔn)的基礎(chǔ)能力,不要受什么計(jì)算機(jī)軟件怪杰之類傳奇的影響,那不過(guò)是小概率事件,而且這些怪杰們就算沒(méi)有讀過(guò)軟件本科和研究生,也往往自學(xué)了大多數(shù)專業(yè)課程,很可能比在校學(xué)習(xí)的學(xué)生對(duì)這些課程的精髓部分理解的更好,還有他們的工作方法和思維方式是特別而高效的,但普遍性差,可以借鑒,不宜模仿。好,所以現(xiàn)在你只需要問(wèn)問(wèn)自己,那些課程和知識(shí)都學(xué)會(huì)并掌握了嗎?如果是,那就準(zhǔn)備好進(jìn)行實(shí)踐了。

      二、在實(shí)踐中提高:成為一名高水平的Coder

      好了,你畢業(yè)了,在校功課都不錯(cuò),也找了一個(gè)專業(yè)對(duì)口的工作,你想大展鴻圖了,可是別急,你的翅膀還不夠硬,不信我們說(shuō)來(lái)看看。

      通常,你在工作中都會(huì)用到某一種單位/公司固定的操作系統(tǒng)和編程語(yǔ)言開(kāi)發(fā)環(huán)境,比如Windows、UNIX、LINUX等操作系統(tǒng),又比如用VC、VB、PB、Delph、JAVA、Motif/XWindow、QT、OpenGL、OpenInventor等編程語(yǔ)言和開(kāi)發(fā)環(huán)境,我們?cè)诤竺姘阉鼈兒戏Q為開(kāi)發(fā)環(huán)境。就在校學(xué)習(xí)的有關(guān)開(kāi)發(fā)環(huán)境的知識(shí)而言,大概你距工作需要的差距是不小的,當(dāng)某個(gè)操作系統(tǒng)和編程語(yǔ)言環(huán)境成為你的飯碗時(shí),就不應(yīng)也不能用通過(guò)課程/認(rèn)證考試之類的眼光和要求來(lái)評(píng)價(jià)你的能力,即使你能考100分。你需要深入地學(xué)習(xí)該操作系統(tǒng)和編程語(yǔ)言環(huán)境的各類開(kāi)發(fā)手冊(cè)的所有內(nèi)容,你會(huì)說(shuō)大多數(shù)你都用不上,其實(shí)你既對(duì)又不對(duì),對(duì)的是單從使用的角度而言,你確實(shí)用不上開(kāi)發(fā)手冊(cè)的大多數(shù)內(nèi)容,比如龐大的VC開(kāi)發(fā)類庫(kù)和復(fù)雜的開(kāi)發(fā)環(huán)境,你在實(shí)際工作中能用到的不到總數(shù)的1/10或1/5,不對(duì)的地方在于,你用到的部分不是孤立存在的,它們是整個(gè)體系中的一部分,只有對(duì)整個(gè)體系有了一個(gè)較完整的了解,才能得心應(yīng)手、隨心所欲地用好你用到的部分,你才算初步具備在這種開(kāi)發(fā)環(huán)境下進(jìn)行Coding的職業(yè)水準(zhǔn)(還遠(yuǎn)不夠程序員的職業(yè)水準(zhǔn)呢),而這只是剛開(kāi)始。如何才能真正掌握一種開(kāi)發(fā)環(huán)境的全面的知識(shí)呢,最原始的辦法就是讀開(kāi)發(fā)指南/教程、參考手冊(cè),一般來(lái)講,學(xué)習(xí)開(kāi)發(fā)指南/教程時(shí),你如果是一個(gè)認(rèn)真的人,都會(huì)完成5/10~7/10左右內(nèi)容的學(xué)習(xí)和練習(xí),如果你想成為職業(yè)選手,就應(yīng)該完成9/10以上內(nèi)容的學(xué)習(xí)和練習(xí)。參考手冊(cè)不同,大多數(shù)所謂的“程序員”們只是用到了才翻翻,這差的太遠(yuǎn)了,你應(yīng)該象讀開(kāi)發(fā)指南/教程一樣,每個(gè)環(huán)節(jié)都要讀,比如VC,參考手冊(cè)中的每個(gè)類,類的每個(gè)函數(shù),都要讀上幾遍,它們往往是一小伙一小伙地糾纏在一起使用的,開(kāi)始時(shí)讀得你毫無(wú)頭緒、心煩意亂,不要緊,還有一手呢,如果你開(kāi)發(fā)環(huán)境安裝的全面,它們往往都有開(kāi)發(fā)商做的demo例子可看,你就進(jìn)入另一個(gè)境界了,開(kāi)始時(shí)你關(guān)注demo中的具體技術(shù),后來(lái)你發(fā)現(xiàn)這些demo的程序?qū)懙亩歼€算不錯(cuò),結(jié)構(gòu)簡(jiǎn)單但合理,如果你真的用心,就一定能發(fā)現(xiàn)一些個(gè)別的demo是極品,它所展現(xiàn)的程序邏輯結(jié)構(gòu)是你設(shè)計(jì)不出來(lái)的,你現(xiàn)在有點(diǎn)更關(guān)心它的程序設(shè)計(jì)構(gòu)架,甚于對(duì)你原始目的(某種相關(guān)的技術(shù)/技巧)的關(guān)注,這時(shí)的你,開(kāi)始了從一名Coder向一名Programmer的轉(zhuǎn)變,你會(huì)忍不住要看看開(kāi)發(fā)商提供的源程序,比如.h和.cpp,通常你會(huì)找到include路徑下所有的.h程序,你才知道,哇!好多好多東東在參考手冊(cè)中都沒(méi)提到,你要學(xué)的太多了,沒(méi)時(shí)間顧及其它的業(yè)余愛(ài)好了,現(xiàn)在知道為什么程序員是年輕人的職業(yè)了吧,你要有足夠多的時(shí)間才行,即使你的智商有160。如果你走到這一步,在你工作的團(tuán)隊(duì)中,已經(jīng)是經(jīng)常有人向你請(qǐng)教技術(shù)問(wèn)題,經(jīng)常有人請(qǐng)求你幫忙debug,你已是公認(rèn)的“高手”了,別得意,因?yàn)槟闳匀皇莻€(gè)Coder,為什么這么說(shuō)呢,你想想,你已深入了解了這個(gè)開(kāi)發(fā)環(huán)境中的各種技能,知道一名Coder如何用好這些東西,可是你能設(shè)計(jì)的出提供給Coder們用的東西嗎?唔??,你想了想,可能還不太行。對(duì)了,就是這樣,你還是一名小我境界的程序員呢,本質(zhì)是個(gè)Coder,當(dāng)然已是一名高水平的Coder了,然而你需要進(jìn)一步登堂入室才能成為一名真正的程序員。

      讓我們繼續(xù)吧,通常你都是從精通一種編程環(huán)境開(kāi)始的,假設(shè)你已經(jīng)較為精通在Windows下用VC開(kāi)發(fā)軟件了,這時(shí)在技術(shù)和技巧方面你將面臨一小一大兩個(gè)挑戰(zhàn),第一個(gè)小挑戰(zhàn)是如果公司/單位改換了開(kāi)發(fā)環(huán)境,比如用LINUX下的QT交互語(yǔ)言工具進(jìn)行開(kāi)發(fā),你不過(guò)是把前面掌握VC的過(guò)程再來(lái)一遍,由于在主觀上經(jīng)歷了VC工具的學(xué)習(xí)過(guò)程,在客觀上各種開(kāi)發(fā)環(huán)境都有太多相似的方面,這回你掌握的應(yīng)該較快。要小心,在這時(shí)第一次誘惑之門(mén)打開(kāi)了,因?yàn)槟愀杏X(jué)良好,看!這回這么快,我就這么好地掌握了新的開(kāi)發(fā)環(huán)境,你開(kāi)始關(guān)注其它暫時(shí)還用不到的同類環(huán)境,比如VB、Delph、JAVA,如饑似渴地掌握各種開(kāi)發(fā)工具,證明自己的學(xué)習(xí)能力和價(jià)值,但你忘了一點(diǎn),你仍然是個(gè)Coder,只不過(guò)是一個(gè)在好多開(kāi)發(fā)環(huán)境下都能編程的Coder,就像你生活在中國(guó),因而精通了漢語(yǔ),工作需要你又掌握了英語(yǔ),然后你就來(lái)了勁,把俄語(yǔ)、日語(yǔ)、阿拉伯語(yǔ)、拉丁語(yǔ),等等等等,都學(xué)習(xí)個(gè)遍,我只能說(shuō),有點(diǎn)BT。你忘了自己是個(gè)職業(yè)人,同一類的東西工作中用得到才需學(xué)習(xí),太多太多的Coder們喜歡在一起比較和炫耀自己會(huì)掌握了幾種開(kāi)發(fā)工具,不信你看看招聘時(shí)的求職書(shū)就知道了,sigh!他們中絕大多數(shù)人永遠(yuǎn)都只能停留在這個(gè)層次上,心浮氣躁,一生都再也當(dāng)不成真正的程序員了??偨Y(jié)一下,其實(shí)你在這時(shí)需要的是對(duì)自己掌握新開(kāi)發(fā)環(huán)境的能力的自信,而不是一遍遍地重復(fù)來(lái)證明自己。第二個(gè)大挑戰(zhàn)就是你明白了只掌握VC是不夠的,你發(fā)現(xiàn)自己有點(diǎn)淺薄,有很多東東你會(huì)用但你不太懂,很多方面支持VC編程的知識(shí)你都沒(méi)掌握,比如操作系統(tǒng)的源碼、網(wǎng)絡(luò)協(xié)議知識(shí)、Windows 的注冊(cè)表、進(jìn)程和線程的基礎(chǔ)知識(shí)、硬件驅(qū)動(dòng)方面的知識(shí)、ActiveX、Windows 龐大的 API,又是一個(gè)等等等等,這些基礎(chǔ)知識(shí)的學(xué)習(xí)和掌握可是要花費(fèi)大量時(shí)間的,你再一次深切地感到時(shí)間太不夠用了,因?yàn)檫@時(shí)的你大概有許多俗務(wù)纏身了,所以有點(diǎn)沮喪,還不用提IT業(yè)每天不知有多少新東西在發(fā)布,KAO,永遠(yuǎn)都跟不上,越拉越遠(yuǎn)了。哎!別氣餒,振作一點(diǎn),你還是忘記了自己是個(gè)職業(yè)人,既然好多東東在工作中你永遠(yuǎn)都沒(méi)機(jī)會(huì)用,那么干嘛要學(xué)呢?用什么才學(xué)什么,最多預(yù)測(cè)到馬上要用什么,先一步學(xué)什么好了,要知道沒(méi)有人是真正的、無(wú)所不精的全科大夫,除非你是神,但如果你還在耐著性子看這篇文章,你肯定是個(gè)人嘛。

      OK,一般工作后三五年,你經(jīng)歷了上述過(guò)程,經(jīng)受了誘惑和考驗(yàn),終于明白了一個(gè)道理:你要的是強(qiáng)勁的學(xué)習(xí)知識(shí)的能力,是對(duì)某種軟件知識(shí)/技能的有深度的精通,一種摸到它的根的深度,而不是已掌握的技能的種類和數(shù)量。這時(shí)無(wú)論誰(shuí)用他掌握了多少種你不會(huì)的技能來(lái)嚇唬你都沒(méi)用,你對(duì)他的層次只有蔑視。通過(guò)幾年的學(xué)習(xí)和工作,要記住最重要的一點(diǎn),永遠(yuǎn)最重要:對(duì)自己學(xué)習(xí)IT知識(shí)能力的自信,一個(gè)程序員一生都要不停地進(jìn)行高強(qiáng)度的學(xué)習(xí),用心問(wèn)問(wèn)自己,有沒(méi)有這個(gè)自信?別用虛榮心來(lái)騙自己哦,如果沒(méi)有的話,那就不必花費(fèi)你寶貴的時(shí)間向下看了,作者在此感謝你有耐心看到這里,現(xiàn)在建議你關(guān)閉這篇文章,趁著年輕,當(dāng)機(jī)立斷轉(zhuǎn)行吧!

      三、注重邏輯:成為一名職業(yè)程序員

      好,再前進(jìn)一點(diǎn)點(diǎn),你就要成為一名職業(yè)程序員了,讓我們繼續(xù)來(lái)完成這個(gè)任務(wù)吧!我們?cè)谇耙还?jié)提到過(guò),“你發(fā)現(xiàn)一些個(gè)別的demo是極品,它所展現(xiàn)的程序邏輯結(jié)構(gòu)是你設(shè)計(jì)不出來(lái)的,你現(xiàn)在有點(diǎn)更關(guān)心它的程序設(shè)計(jì)構(gòu)架,甚于對(duì)你原始目的(某種相關(guān)的技術(shù)/技巧)的關(guān)注”,其實(shí)你是在關(guān)注這個(gè)demo程序作者的思維邏輯,所有程序的本質(zhì)就是邏輯。技術(shù)你已經(jīng)較好地掌握了,但只有完成邏輯能力的提高,你才能成為一名職業(yè)程序員。打一個(gè)比方吧,你會(huì)十八般武藝,刀槍棍棒都很精通,但就是力氣不夠,所以永遠(yuǎn)都上不了戰(zhàn)場(chǎng),這個(gè)力氣對(duì)程序員而言就是邏輯能力(其本質(zhì)是一個(gè)人的數(shù)學(xué)修養(yǎng),注意,不是數(shù)學(xué)知識(shí))。邏輯能力也是逐步提高的,開(kāi)始時(shí)你一定是用直觀的邏輯能力來(lái)編程的,怎么想就怎么編,不對(duì)就再改,在改進(jìn)中提高自己的邏輯能力,從直觀邏輯能力提高到抽象邏輯能力,這是很正常的。提前說(shuō)一句吧,到達(dá)邏輯能力的至高境界,其表現(xiàn)是用數(shù)學(xué)語(yǔ)言來(lái)描述問(wèn)題和問(wèn)題的解決辦法,高度抽象!好,說(shuō)回來(lái)吧,你要提高邏輯能力,最快的辦法就是讀別人寫(xiě)的結(jié)構(gòu)優(yōu)秀的程序。優(yōu)秀的代碼是百讀不厭的(這句話是我抄來(lái)的),暫時(shí)放放對(duì)其中某種技術(shù)和技巧的關(guān)注吧,你要推導(dǎo)和學(xué)習(xí)的是這些好程序的邏輯結(jié)構(gòu),它們是被精心設(shè)計(jì)出來(lái)的。你可以先捂住這個(gè)demo程序,自己設(shè)計(jì)一個(gè)功能相同的程序結(jié)構(gòu),然后比較一下demo的程序結(jié)構(gòu),如果差距較大,那你就不應(yīng)簡(jiǎn)單地改進(jìn)一下,而是要把demo作者設(shè)計(jì)的過(guò)程在心里復(fù)原一遍,做到這一點(diǎn)也許有點(diǎn)困難,但這種事干的多了,你就會(huì)越干越快,越來(lái)越得心應(yīng)手,你的邏輯能力飛速提升,你能看得上的邏輯結(jié)構(gòu)優(yōu)秀的程序開(kāi)始不多了,下一步就是練習(xí)。從工作中開(kāi)始吧,如果你有空閑,你需要做至少兩類練習(xí),一類是算法練習(xí),所有的經(jīng)典算法都是經(jīng)典的邏輯,題目有的是,像個(gè)好學(xué)生一樣吧,每年的國(guó)內(nèi)國(guó)際編程競(jìng)賽都有邏輯要求非常高的題,你可以只選一兩道難題來(lái)做做。當(dāng)你可以把復(fù)雜的單遞歸程序(只有A調(diào)A)變成非遞歸程序時(shí),已經(jīng)不錯(cuò)了,如果你能看得懂雙遞歸程序(A調(diào)A、A調(diào)B、B調(diào)A、B調(diào)B都有),我為你鼓掌!你不必往下看了,我有點(diǎn)不好意思啦――班門(mén)弄斧,你快滾蛋吧!另一類是把以前和當(dāng)前你工作中你不滿意的程序推倒重新設(shè)計(jì)一遍,這非常重要,省時(shí)省力,因?yàn)槟闶煜ば枨螅夹g(shù)上也沒(méi)問(wèn)題,目的就是改進(jìn)程序的邏輯結(jié)構(gòu),很劃算哦,唯一要克服的就是:你對(duì)推翻以前工作中那點(diǎn)小小成就的心理障礙,如果你真想優(yōu)秀,說(shuō)句粗話:這點(diǎn)心理障礙算個(gè)屁,一遍遍反復(fù)地推倒已有的成果只能使自己快速進(jìn)步,放手干吧,沒(méi)什么好可惜的,馬恩早就在《共.產(chǎn).黨宣言》里說(shuō)過(guò)了:在這個(gè)過(guò)程中,你失去的只有鎖鏈(禁錮你思想的鎖鏈)。

      讓我們來(lái)總結(jié)一下,經(jīng)過(guò)自我否定后,再生的你盡管對(duì)過(guò)去的“業(yè)績(jī)”還有一些眷戀,但已是一個(gè)初步具備職業(yè)水準(zhǔn)的程序員了,掌握了相應(yīng)的技術(shù)和技巧,具備了較高的抽象邏輯思維能力,最主要的特征是:能自覺(jué)地自我否定,不斷地追求更高水平的邏輯能力。

      在這個(gè)過(guò)程中,如果你能注意以下一些小的方面,你前進(jìn)的步伐也許會(huì)快一些。

      l 從編譯原理的角度來(lái)理解你工作中使用的高級(jí)語(yǔ)言,如果你做到這一點(diǎn),至少有兩個(gè)好處,第一個(gè)好處是避免一大堆低水平重復(fù)出現(xiàn)的編譯錯(cuò)誤。一名優(yōu)秀的Coder平均在一個(gè)工作日中應(yīng)該完成200行以上的源碼,其編譯錯(cuò)誤應(yīng)該控制在5個(gè)以下,要知道這200行源碼不是一次完成的,所以大多數(shù)情況下你都要追求一次編譯通過(guò),而一名職業(yè)水準(zhǔn)的程序員,應(yīng)該進(jìn)一步做到即使用purify這類的工具來(lái)檢查源碼,也不會(huì)存在嚴(yán)重的內(nèi)存泄露。第二個(gè)好處是可以提高源碼的可讀性和效率。規(guī)范地編寫(xiě)你的代碼使你自己的邏輯清晰,因?yàn)槟忝靼锥嗉訋讉€(gè)括號(hào)和空行、多換行對(duì)齊、多注釋,編譯器是會(huì)自動(dòng)識(shí)別的,不影響程序執(zhí)行的效率,反過(guò)來(lái),控制好遞歸調(diào)用和循環(huán)內(nèi)的if語(yǔ)句才是提高程序效率的關(guān)鍵,要全力避免遞歸,但要深刻理解遞歸,能通過(guò)自己建立堆棧來(lái)把遞歸程序轉(zhuǎn)換成非遞歸程序,要求還是較高的哦!

      l 避免思維陷阱,只要你是人就一定有自己的思維慣性,這一定又會(huì)表現(xiàn)在你的程序邏輯中,有時(shí)你就是從這個(gè)慣性中跳不出來(lái)(誰(shuí)都有這個(gè)時(shí)候),但要心里有數(shù)才行,所以你需要幫助,如果你有幾個(gè)水平相若或更高的職業(yè)伙伴,太好了,當(dāng)遇到花30分鐘還打不下的bug時(shí),就別浪費(fèi)時(shí)間了,找他們吧,最要緊的是能思路清晰明確地表述你的問(wèn)題,通常你自己在這個(gè)過(guò)程中或者伙伴中就有人把問(wèn)題解決了,又快又好。另外,有幾個(gè)可以良性競(jìng)爭(zhēng)的職業(yè)伙伴是人生的一件幸事,1+1>2,大家各有所長(zhǎng),你最好做到及時(shí)公開(kāi)你的成果,技不壓身嘛,IT發(fā)展的這么快,你再優(yōu)秀,那點(diǎn)東東也沒(méi)有什么值得隱藏的,所以你可以技術(shù)或水平不夠高,但千萬(wàn)不可以讓真正具有職業(yè)水準(zhǔn)的選手鄙視你的職業(yè)品質(zhì)和行為。

      l 有自己debug的特點(diǎn),下面的說(shuō)法作者不敢太肯定,只是經(jīng)驗(yàn)之談。即使在VC這種高度完善的開(kāi)放環(huán)境下,你仍然應(yīng)該要求自己僅憑打印語(yǔ)句就能debug。這也有兩點(diǎn)好處,第一個(gè)好處是,遇到bug你會(huì)認(rèn)真想問(wèn)題所在,而不是用debug工具一步步簡(jiǎn)單地追蹤卡在哪兒了,你定位bug范圍的方式是從大到小、從粗到精,這是一種自頂向下的思維方式,而用工具追蹤,容易形成自底向上的思維方式,這不算好,你應(yīng)該先看到森林,再看到樹(shù)木。我反復(fù)提及:程序就是邏輯過(guò)程,大多數(shù)程序從main函數(shù)開(kāi)始,是由數(shù)據(jù)結(jié)構(gòu)和功能子程序組成的一個(gè)樹(shù)形結(jié)構(gòu)的邏輯過(guò)程(要認(rèn)清即使是面向?qū)ο蟮某绦蛘Z(yǔ)言也是一樣的),它的執(zhí)行過(guò)程是深度優(yōu)先的,但你定位bug應(yīng)該是廣度優(yōu)先的,好好想想這一點(diǎn),嗯?第二個(gè)好處是強(qiáng)迫你思考并記住而不是用工具看到調(diào)用過(guò)程,你大腦的抽象邏輯思維能力和胳膊上肌肉的力量一樣,都是練出來(lái)的,如果你的bug是程序結(jié)構(gòu)上的邏輯錯(cuò)誤引起的,這一點(diǎn)就非常重要了,順便說(shuō)一句,最難打的bug就是程序邏輯結(jié)構(gòu)錯(cuò)誤導(dǎo)致的bug。你要是真正明明白白地認(rèn)識(shí)到這兒了,那我就沒(méi)什么東西可以告訴你了。總之,程序員的職業(yè)水準(zhǔn):生產(chǎn)效率和程序質(zhì)量,主要是取決于源碼中bug的數(shù)量和debug的速度,而不是取決于編寫(xiě)源碼的速度。給你一個(gè)我自己定義的考查一個(gè)職業(yè)程序員的指標(biāo):一個(gè)合格水準(zhǔn)的職業(yè)程序員,編程的時(shí)間如果算一份的話,其累計(jì)debug的時(shí)間不能超過(guò)一份,真正職業(yè)高手累計(jì)debug的時(shí)間應(yīng)該控制在0.5份以下,如何?你關(guān)上門(mén)悄悄問(wèn)問(wèn)自己,你花費(fèi)在編程和debug上的時(shí)間比例是多少?如果你把程序員作為自己一生的職業(yè),那么就永遠(yuǎn)都要牢記一點(diǎn):追求做一個(gè)0 bug的優(yōu)秀程序員!這是任何一個(gè)想成為職業(yè)程序員的人的理想,請(qǐng)相信:堅(jiān)忍不拔地追求實(shí)現(xiàn)這個(gè)理想將讓你出類拔萃!

      l 做好程序的單元測(cè)試,這是另一項(xiàng)考查你是否是一名具有合格職業(yè)水準(zhǔn)的程序員的一個(gè)必要指標(biāo)。其實(shí)在你拿到需求的時(shí)候就要準(zhǔn)備單元測(cè)試用例了,并且這些用例將直接影響你的詳細(xì)設(shè)計(jì)(有關(guān)軟件設(shè)計(jì)本來(lái)是該放在第四節(jié)講的)。我們還是打比方吧,當(dāng)你拿到一個(gè)需求時(shí),除了分析它靜態(tài)的功能外,還應(yīng)明確它動(dòng)態(tài)的操作/執(zhí)行過(guò)程,把這個(gè)動(dòng)態(tài)過(guò)程明確地用流程圖畫(huà)出來(lái),比如分為A~Z的26步,其中A又可以進(jìn)一步分解為A1~A5的5步,直到不能再分解為止。又比如說(shuō)A3步不可分解了,那么你應(yīng)該把A3步的正常操作和所有五花八門(mén)的異常操作都列出來(lái),確保正常的操作肯定正確,異常的操作起碼程序不退出才行。這樣你就要寫(xiě)好多好多的測(cè)試用例,說(shuō)句老實(shí)話,我也從來(lái)不寫(xiě)!但我一般會(huì)列一個(gè)提綱,比如A3步有正常的操作a、b、c、d、e共5項(xiàng),異常的操作有f、g、h、i、j、k、l、m、n共9項(xiàng),你在進(jìn)行單元測(cè)試時(shí)都應(yīng)該跑一遍,這樣的程序都還不敢說(shuō)質(zhì)量如何好,但起碼可以說(shuō)較穩(wěn)定吧!如果要想在進(jìn)行單元測(cè)試時(shí)干得快、效率高,那么在進(jìn)行詳細(xì)設(shè)計(jì)時(shí),你就應(yīng)該把A3步中對(duì)所有正常操作和異常操作的判斷都設(shè)計(jì)好,在編程實(shí)現(xiàn)A3步時(shí),使得程序的結(jié)構(gòu)合理高效,對(duì)不對(duì)?所以,如果你在工作中是割裂地看待軟件工程中從需求、分析、設(shè)計(jì)、編程、測(cè)試等各個(gè)環(huán)節(jié),恐怕水平很有限喔!但如果你在分析需求時(shí)就能看到測(cè)試的問(wèn)題,并改進(jìn)設(shè)計(jì)和實(shí)現(xiàn),為此做好相應(yīng)的準(zhǔn)備工作,嘿嘿,整個(gè)軟件開(kāi)發(fā)過(guò)程你的效率會(huì)高很多,通常你在一個(gè)開(kāi)發(fā)團(tuán)隊(duì)中就會(huì)高度自信的,你已越過(guò)當(dāng)一名偏頗、露骨的高手的境界,成為一個(gè)平靜的高手,這可是The best in the best!,用周星星的話說(shuō):是高手之高高手,因?yàn)閯e人看不出你高在哪兒,沒(méi)見(jiàn)你有什么高招或特拚命干,但反正你就是干得又快又好、又省力。關(guān)于進(jìn)行單元測(cè)試還有很多復(fù)雜的方法,在此本文只提到了最基本的一點(diǎn),目的是讓你在工作上考慮周全、安排有序,其它的自己琢磨吧,沒(méi)有人能替你吃飽飯!

      l 如果你是用C++編程,我再簡(jiǎn)單談?wù)動(dòng)嘘P(guān)內(nèi)層釋放的一個(gè)小技巧,就是對(duì)所有你編寫(xiě)的類,在構(gòu)造和析構(gòu)函數(shù)中加打印語(yǔ)句,統(tǒng)計(jì)每個(gè)類在運(yùn)行程序時(shí)構(gòu)造和析構(gòu)的地方,如果是配對(duì)的,那么起碼沒(méi)有對(duì)象類一級(jí)的內(nèi)層在程序運(yùn)行結(jié)束時(shí)沒(méi)有釋放,然后你就可以把打印語(yǔ)句刪掉了,招數(shù)雖土,但管用!

      l 還有其它一些好習(xí)慣,在這里我隨筆寫(xiě)一些,你要是有不同看法也請(qǐng)一笑過(guò)之吧。編程時(shí)應(yīng)該對(duì)齊縮進(jìn),一個(gè)縮進(jìn)用一個(gè)tab鍵,一般是4個(gè)空格,嚴(yán)格遵守開(kāi)發(fā)團(tuán)隊(duì)的編程規(guī)范也是非常重要的。一個(gè)子程序不應(yīng)超過(guò)30行(不算空行),其內(nèi)多重循環(huán)不應(yīng)超過(guò)3層,否則都應(yīng)該分裂成兩個(gè)子程序,個(gè)別算法程序可以長(zhǎng)一些,但也不宜超過(guò)200行。通常一個(gè)類的所有成員函數(shù)總和不宜超過(guò)1500行,多了就應(yīng)該考慮分解成兩個(gè)類(這個(gè)工作最好在設(shè)計(jì)時(shí)就完成)。每完成一小段程序,比如15~30行,就立即編譯運(yùn)行,不要假裝高手,先敲它一大堆程序,再編譯運(yùn)行,妄想一次成功,體驗(yàn)一種假爽的、虛榮的快感,或炫耀給別人看,這么做只能證明自己是一個(gè)不折不扣的傻瓜,裝酷而已。因?yàn)橹灰幸淮尾怀晒?,你就?huì)花費(fèi)大量的時(shí)間來(lái)調(diào)程序,別人的進(jìn)度在這時(shí)就遠(yuǎn)遠(yuǎn)地超過(guò)你了,平常心是道,還是修煉真功夫吧!孫子兵法里關(guān)于這一點(diǎn)有明確的闡述,我就不引用了,但建議你真的不要這么干,除非你確實(shí)就是這樣總是一次就成功的天才,那你還看這篇文章干什么呢?我又不是寫(xiě)給你們這些天才們看的。再就是有學(xué)會(huì)買(mǎi)好書(shū)、讀好書(shū),關(guān)于計(jì)算機(jī)和軟件方面的書(shū)太多了,時(shí)間有限,比如有一個(gè)叫侯捷的家伙,幾乎寫(xiě)的每本書(shū)都不錯(cuò),張國(guó)峰的C++編程也不錯(cuò),這只是我的個(gè)人意見(jiàn)啊,好書(shū)多著呢,列出來(lái)比這篇文章長(zhǎng)好多倍,我就不多說(shuō)了。還有一招,要是你運(yùn)氣好,能搞到一些著名軟件系統(tǒng)的源碼,好好讀讀吧,在此我只能告訴你,Linux操作系統(tǒng)的一些源碼不錯(cuò),是開(kāi)放的,你可以合法地搞到,其它的不要說(shuō)是我建議你侵犯知識(shí)版權(quán)啊!

      四、天生神力:成為系統(tǒng)分析員

      本來(lái)就論述如何成為一名職業(yè)程序員而言,本文已基本完成任務(wù)了,但《菜根譚》有言:竭世機(jī)樞,似一滴投于巨壑,窮諸玄辯,若一毫置于太虛。既已乘興到此,何妨多置一毫于太虛呢,作者不才,干脆盡興寫(xiě)算了。

      你要是運(yùn)氣好,直接進(jìn)入了一個(gè)嚴(yán)格規(guī)范生產(chǎn)的軟件企業(yè)就業(yè),剛開(kāi)始就應(yīng)該是按別人做好的軟件設(shè)計(jì)來(lái)實(shí)現(xiàn)編程,你可以有機(jī)會(huì)直接學(xué)習(xí)軟件設(shè)計(jì),當(dāng)你積累的足夠多了,能夠?qū)ζ渲械囊恍┰O(shè)計(jì)提出好的改進(jìn)建議,而且干得又快又好,就會(huì)漸漸地展露頭角,我相信你終有一天成為一名軟件設(shè)計(jì)人員(注意,不是軟件產(chǎn)品設(shè)計(jì)人員),步入系統(tǒng)分析員的行列,但這還需其它的一些條件和自我修煉。如果你在一個(gè)不規(guī)范的軟件企業(yè)工作,那也不錯(cuò),你很可能直接就有機(jī)會(huì)進(jìn)行軟件設(shè)計(jì),然后開(kāi)發(fā)、測(cè)試,甚至還不得不自己定義需求,把軟件開(kāi)發(fā)過(guò)程的各個(gè)環(huán)節(jié)走一個(gè)遍,當(dāng)然這樣對(duì)你的要求更高,而且你也不容易得到及時(shí)有益的指點(diǎn),在正態(tài)分布的情況下,你應(yīng)該是成長(zhǎng)的很慢。但不管就業(yè)的單位如何,如果你決心要成為頂尖軟件職業(yè)選手,通常什么客觀困難都阻擋不了你,然而你個(gè)人的因素可能會(huì)阻止你的前進(jìn)。下面提出的觀點(diǎn)純屬一己之見(jiàn),傷人自尊之處作者在此提前道歉,并建議你除非對(duì)本文有強(qiáng)烈的興趣,否則就請(qǐng)直接看第五節(jié)或放下別看了。丑話已說(shuō)在前頭了,在各種軟件開(kāi)發(fā)組織的發(fā)展過(guò)程中的事實(shí)也證明,只有少數(shù)程序員能成為系統(tǒng)分析員,我想這一點(diǎn)不是我杜撰的吧,因此你要是在看接下來(lái)的部分時(shí)感到氣憤難當(dāng),那也實(shí)在沒(méi)著,純屬活該,因?yàn)樽髡咧皇窃谡f(shuō)明自己的觀點(diǎn)而已,你最多可以呲之以鼻,表示一下你的輕蔑好了,但沒(méi)有任何理由可以罵人!

      作者自己沒(méi)有到微軟面試過(guò),但身處軟件行業(yè),關(guān)于微軟的許多東東當(dāng)然還是有耳聞的,據(jù)說(shuō)微軟招聘一名程序員要過(guò)五個(gè)已經(jīng)成為微軟程序員的面試關(guān),而且是一票否決制,又據(jù)說(shuō)大多數(shù)面試題并非編程,而是一些有關(guān)邏輯和智力的題,作者私下也做過(guò)許多流傳的微軟面試題,并對(duì)此做法深以為然。程序的本質(zhì)就是邏輯,所以幾十年前就有人提出編程是一門(mén)藝術(shù),而藝術(shù)是要靠天份的,這一點(diǎn)少有人反對(duì)。一個(gè)人的邏輯能力可以不斷提高,但其能到達(dá)的終極邏輯能力的層次必定為其天生智力所限制,這一點(diǎn)就讓人不易接受了。好笑??!人們可以公開(kāi)承認(rèn)自己沒(méi)有某種或全部的藝術(shù)天份,但要說(shuō)自己邏輯天份不夠,換句話說(shuō)承認(rèn)自己笨、IQ不夠高,往往是要怒發(fā)沖冠的,其實(shí)這又有什么區(qū)別呢?話都說(shuō)到這兒了,再次建議你如果不夠自信,就跳過(guò)這一節(jié)吧,直接看第五節(jié),好嗎?

      好了,把話題說(shuō)回來(lái),你已經(jīng)成為一門(mén)合格的職業(yè)程序員了,如果要想成為從事軟件系統(tǒng)設(shè)計(jì)的職業(yè)系統(tǒng)分析員,第一件事就是悄悄找一個(gè)標(biāo)準(zhǔn)智商測(cè)試的網(wǎng)站或其它渠道,嚴(yán)格認(rèn)真的測(cè)一測(cè)自己的智商,如果IQ低于130(正常智商是110),就請(qǐng)別費(fèi)勁了,打消掉成為系統(tǒng)分析員的念頭吧!好!好!先請(qǐng)你冷靜一下,好好想想,其實(shí)微軟面試時(shí)就是在測(cè)你的智商和邏輯數(shù)學(xué)素質(zhì)呢,這就是本節(jié)的標(biāo)題為“天生神力”的原因,因?yàn)樵O(shè)計(jì)就是從無(wú)到有地進(jìn)行創(chuàng)造,無(wú)論是軟件還是其它行業(yè)都一樣,可以有借鑒的,沒(méi)有現(xiàn)成的,設(shè)計(jì)就是創(chuàng)造!如果你IQ在130以上,又決心要當(dāng)一名職業(yè)軟件系統(tǒng)分析員,其實(shí)你不過(guò)是要準(zhǔn)備好吃更大的苦而已,有什么好虛榮的呢?

      修煉還是從基本功開(kāi)始的,過(guò)程和成為一名職業(yè)程序員差不多。必須使用設(shè)計(jì)工具這一點(diǎn)是不用多說(shuō)的。在工作中,你基本上遇到的是兩類方式的設(shè)計(jì),一個(gè)是結(jié)構(gòu)化設(shè)計(jì),另一個(gè)是面向?qū)ο笤O(shè)計(jì),就個(gè)人經(jīng)驗(yàn)而言,面向?qū)ο蟮脑O(shè)計(jì)更好。如果你工作中不得不采用結(jié)構(gòu)化的設(shè)計(jì),你必須熟練地掌握數(shù)據(jù)流圖和控制流圖的分析和設(shè)計(jì),一般來(lái)講,如果你把一個(gè)軟件中用到的數(shù)據(jù)模型設(shè)計(jì)好了,針對(duì)功能化的流程,不難設(shè)計(jì)出數(shù)據(jù)流圖,但下一步設(shè)計(jì)控制流圖才是挑戰(zhàn),如果你按照需求走不通設(shè)計(jì)好的控制流圖,那么你或別人在按照這個(gè)設(shè)計(jì)編程實(shí)現(xiàn)時(shí),必定也走不通,沒(méi)有奇跡會(huì)發(fā)生,還是在設(shè)計(jì)階段嚴(yán)格要求吧,又有一點(diǎn)需要牢記:返工是最慢的。當(dāng)你在進(jìn)行控制流圖的設(shè)計(jì)時(shí),也不要妄想得到需求人員提供給你明確的指點(diǎn),通常他們要是能夠把需求的功能和操作次序?qū)懲暾脑?,你?yīng)該就感恩戴德了,從需求中整理出功能、操作的拓?fù)浯涡蚝蜅l件是你作為系統(tǒng)分析員的職責(zé)。看看,要是沒(méi)有一點(diǎn)圖論的基礎(chǔ)和拓?fù)鋵W(xué)的入門(mén)知識(shí),你是當(dāng)不好一個(gè)職業(yè)系統(tǒng)分析員的,即使你天賦不錯(cuò),必要的數(shù)學(xué)和邏輯素質(zhì)仍然不可或缺。也不用氣餒,永遠(yuǎn)沒(méi)有最好的設(shè)計(jì),只有更好的設(shè)計(jì),反復(fù)地進(jìn)行設(shè)計(jì)迭代,勇于推翻舊的設(shè)計(jì),你將快速進(jìn)步。如果你在工作中是采用面向?qū)ο筮M(jìn)行設(shè)計(jì)的,那就更有利了,有關(guān)面向?qū)ο笤O(shè)計(jì)的書(shū)太多了,不用作者在此多費(fèi)口舌,建議精讀一本經(jīng)典的書(shū),比如北大邵維忠等編譯的《面向?qū)ο蟮姆治觥?,有些方法和技巧可能過(guò)時(shí),但其邏輯的基本原理是非常正確的,其本質(zhì)是,你在邏輯上是如何認(rèn)識(shí)這個(gè)世界的,你就是如何設(shè)計(jì)軟件體系結(jié)構(gòu)的,然后讀讀其它書(shū),觸類旁通,自己創(chuàng)造機(jī)會(huì)多實(shí)踐,成功自然會(huì)到來(lái)的,總之,不管是結(jié)構(gòu)化設(shè)計(jì)還是面向?qū)ο笤O(shè)計(jì),評(píng)價(jià)一下自己的軟件系統(tǒng)設(shè)計(jì)方案吧,有好多指標(biāo)呢,比如是否均勻和平衡?局部獨(dú)立性強(qiáng)不強(qiáng)?有沒(méi)有歧異的結(jié)構(gòu)?有沒(méi)有層次太多或太少?有沒(méi)有某個(gè)層次太大、太廣?是不是邏輯結(jié)構(gòu)先復(fù)雜了再化簡(jiǎn)的?還是只會(huì)設(shè)計(jì)簡(jiǎn)單的,復(fù)雜不起來(lái)(這一點(diǎn)是笨哦,如果出現(xiàn)多次,請(qǐng)你不要意氣用事,轉(zhuǎn)行吧)?最重要的一點(diǎn),是否容易理解、實(shí)現(xiàn)和改進(jìn)?你自己會(huì)得出評(píng)價(jià)的。如果有機(jī)會(huì)看到別人的設(shè)計(jì),一定不要錯(cuò)過(guò)學(xué)習(xí)的機(jī)會(huì),自己推導(dǎo)一遍,認(rèn)真比較比較,獲益會(huì)較多。

      走到這一步,你就應(yīng)該關(guān)注設(shè)計(jì)模式了,首先還是學(xué)習(xí),這方面的好書(shū)有的是,但一般在工作中用到的設(shè)計(jì)模式較為單一,應(yīng)該多嘗試一下其它的設(shè)計(jì)模式。其次必須要明白設(shè)計(jì)模式不是設(shè)計(jì)思路,也不能代替設(shè)計(jì)思路,比方你要從A到B修一條路,設(shè)計(jì)模式只是讓你選擇,是修水泥的還是柏油的?是高架路還是普通的,但線路必須你自己定,而線路就是設(shè)計(jì)思路,模式對(duì)思路是有影響,但不能代替,所以如果你的智商高達(dá)250,我相信你直接用匯編語(yǔ)言也能寫(xiě)出面向?qū)ο蟮某绦騺?lái)。第三在此有一個(gè)陷阱,很多系統(tǒng)分析員生搬硬套設(shè)計(jì)模式,全然不懂如何融會(huì)貫通,在你的一項(xiàng)具體工作中,往往是以一種設(shè)計(jì)模式為主,其它模式為輔的,思維不拘泥于形式才是關(guān)鍵,而且也為你到達(dá)更高的軟件設(shè)計(jì)的境界做好準(zhǔn)備。

      唉!都不知該怎么向下寫(xiě)好了,因?yàn)橐堰_(dá)到作者水平的極限了,我胡亂說(shuō)一點(diǎn),你湊合看吧。軟件設(shè)計(jì)最終的層次是:以無(wú)法為有法、以無(wú)限為有限,這句話是李小龍說(shuō)的,不是我說(shuō)的。再拾人牙慧一把,類比一個(gè)故事吧,金大俠在《倚天屠龍記》里講到張無(wú)忌初學(xué)太極,學(xué)會(huì)的標(biāo)志是把剛學(xué)的招數(shù)全忘了,記住的是太極的道理和精神,和李小龍有些相似喔,軟件設(shè)計(jì)也一樣,忘記所有的設(shè)計(jì)模式,隨心所欲進(jìn)行設(shè)計(jì)才是至高境界,所以你能到達(dá)多高的軟件設(shè)計(jì)的境界最終將取決于你的哲學(xué)素質(zhì),這一點(diǎn)實(shí)在是不好寫(xiě)啊,你自己領(lǐng)悟吧!作者只有祝福了!

      五、職業(yè)人的終極目標(biāo):全面修煉,成為L(zhǎng)eader

      這一節(jié)更不好寫(xiě),涉及到太多其它非技術(shù)方面的因素,特別是個(gè)人人生觀和世界觀的修煉,如果本帖的點(diǎn)擊率超過(guò)作者私下期望的一個(gè)數(shù)值,那我就爭(zhēng)取盡力厚著臉皮再補(bǔ)上吧。我只說(shuō)一句,雖然大家都知道軟件開(kāi)發(fā)是一個(gè)團(tuán)隊(duì)性的工作,但追求參與一個(gè)大型軟件系統(tǒng)的成功開(kāi)發(fā),是一名軟件人員的本能,就像拿破侖說(shuō)的不想當(dāng)元帥的士兵不是好士兵,所以不追求實(shí)現(xiàn)大系統(tǒng)的軟件人員,也不是一個(gè)好的職業(yè)軟件人員,但你只有成為L(zhǎng)eader,領(lǐng)導(dǎo)一個(gè)優(yōu)秀的軟件開(kāi)發(fā)團(tuán)隊(duì),才有機(jī)會(huì)實(shí)現(xiàn)這個(gè)終極職業(yè)目標(biāo),對(duì)不對(duì)? 好吧,不管你現(xiàn)在的感受如何,我都謝謝你能讀到這里!我不習(xí)慣假謙虛,就不說(shuō)什么作者水平有限,本文拋磚引玉,歡迎大家批評(píng)斧正之類的客套話了,雖然作者水平確實(shí)有限。所以我認(rèn)為你盡管有權(quán)砸磚,但實(shí)在沒(méi)必要搞回帖、或回罵、或頂之類的玩意兒,我只是盡興寫(xiě)一點(diǎn)多年從事軟件開(kāi)發(fā)工作的體驗(yàn),因此接下來(lái)我就高掛免戰(zhàn)牌,不回復(fù)任何回帖了。再次謝謝你能有耐心讀到這里!希望本文對(duì)你有所裨益,祝你成功!再見(jiàn)!

      本文來(lái)自CSDN博客,轉(zhuǎn)載請(qǐng)標(biāo)明出處:http://blog.csdn.net/carefree31441/archive/2008/07/10/2635287.aspx

      第五篇:C語(yǔ)言嵌入式系統(tǒng)編程修煉之道

      C語(yǔ)言嵌入式系統(tǒng)編程修煉之道收藏

      C語(yǔ)言嵌入式系統(tǒng)編程修煉之道——背景篇...1 C語(yǔ)言嵌入式系統(tǒng)編程修煉之道——軟件架構(gòu)篇...4 1.模塊劃分...4 2.多任務(wù)還是單任務(wù)...5 3.單任務(wù)程序典型架構(gòu)...6 4.中斷服務(wù)程序...7 5.硬件驅(qū)動(dòng)模塊...9 6.C的面向?qū)ο蠡?..10 總結(jié)...10 C語(yǔ)言嵌入式系統(tǒng)編程修煉之道——內(nèi)存操作篇...12 1.數(shù)據(jù)指針...12 2.函數(shù)指針...13 3.數(shù)組vs.動(dòng)態(tài)申請(qǐng)...14 4.關(guān)鍵字const 15 5.關(guān)鍵字volatile.16 6.CPU字長(zhǎng)與存儲(chǔ)器位寬不一致處理...17 總結(jié)...18 C語(yǔ)言嵌入式系統(tǒng)編程修煉之道——屏幕操作篇...19 1.漢字處理...19 2.系統(tǒng)時(shí)間顯示...20 3.動(dòng)畫(huà)顯示...21 4.菜單操作...22 5.模擬MessageBox函數(shù)...24 總結(jié)...26 C語(yǔ)言嵌入式系統(tǒng)編程修煉之道——鍵盤(pán)操作篇...27 1.處理功能鍵...27 2.處理數(shù)字鍵...28 3.整理用戶輸入...29 總結(jié)...30 C語(yǔ)言嵌入式系統(tǒng)編程修煉之道——性能優(yōu)化篇...31 1.使用宏定義...31 2.使用寄存器變量...31 3.內(nèi)嵌匯編...32 4.利用硬件特性...32 5.活用位操作...33 總結(jié)

      C語(yǔ)言嵌入式系統(tǒng)編程修煉之道——背景篇 不同于一般形式的軟件編程,嵌入式系統(tǒng)編程建立在特定的硬件平臺(tái)上,勢(shì)必要求其編程語(yǔ)言具備較強(qiáng)的硬件直接操作能力。無(wú)疑,匯編語(yǔ)言具備這樣的特質(zhì)。但是,歸因于匯編語(yǔ)言開(kāi)發(fā)過(guò)程的復(fù)雜性,它并不是嵌入式系統(tǒng)開(kāi)發(fā)的一般選擇。而與之相比,C語(yǔ)言——一種“高級(jí)的低級(jí)”語(yǔ)言,則成為嵌入式系統(tǒng)開(kāi)發(fā)的最佳選擇。筆者在嵌入式系統(tǒng)項(xiàng)目的開(kāi)發(fā)過(guò)程中,一次又一次感受到C語(yǔ)言的精妙,沉醉于C語(yǔ)言給嵌入式開(kāi)發(fā)帶來(lái)的便利。本文的目的在于進(jìn)行“C語(yǔ)言嵌入式系統(tǒng)開(kāi)發(fā)的內(nèi)功心法”秀,一共包括25招。

      圖1給出了本文的討論所基于的硬件平臺(tái),實(shí)際上,這也是大多數(shù)嵌入式系統(tǒng)的硬件平臺(tái)。它包括兩部分:

      (1)

      以通用處理器為中心的協(xié)議處理模塊,用于網(wǎng)絡(luò)控制協(xié)議的處理;(2)

      以數(shù)字信號(hào)處理器(DSP)為中心的信號(hào)處理模塊,用于調(diào)制、解調(diào)和數(shù)/模信號(hào)轉(zhuǎn)換。

      本文的討論主要圍繞以通用處理器為中心的協(xié)議處理模塊進(jìn)行,因?yàn)樗嗟貭可娴骄唧w的C語(yǔ)言編程技巧。而DSP編程則重點(diǎn)關(guān)注具體的數(shù)字信號(hào)處理算法,主要涉及通信領(lǐng)域的知識(shí),不是本文的討論重點(diǎn)。

      著眼于討論普遍的嵌入式系統(tǒng)C編程技巧,系統(tǒng)的協(xié)議處理模塊沒(méi)有選擇特別的CPU,而是選擇了眾所周知的CPU芯片——80186,每一位學(xué)習(xí)過(guò)《微機(jī)原理》的讀者都應(yīng)該對(duì)此芯片有一個(gè)基本的認(rèn)識(shí),且對(duì)其指令集比較熟悉。80186的字長(zhǎng)是16位,可以尋址到的內(nèi)存空間為1MB,只有實(shí)地址模式。C語(yǔ)言編譯生成的指針為32位(雙字),高16位為段地址,低16位為段內(nèi)編譯,一段最多64KB。

      圖1 系統(tǒng)硬件架構(gòu)

      協(xié)議處理模塊中的FLASH和RAM幾乎是每個(gè)嵌入式系統(tǒng)的必備設(shè)備,前者用于存儲(chǔ)程序,后者則是程序運(yùn)行時(shí)指令及數(shù)據(jù)的存放位置。系統(tǒng)所選擇的FLASH和RAM的位寬都為16位,與CPU一致。

      實(shí)時(shí)鐘芯片可以為系統(tǒng)定時(shí),給出當(dāng)前的年、月、日及具體時(shí)間(小時(shí)、分、秒及毫秒),可以設(shè)定其經(jīng)過(guò)一段時(shí)間即向CPU提出中斷或設(shè)定報(bào)警時(shí)間到來(lái)時(shí)向CPU提出中斷(類似鬧鐘功能)。

      NVRAM(非易失去性RAM)具有掉電不丟失數(shù)據(jù)的特性,可以用于保存系統(tǒng)的設(shè)置信息,譬如網(wǎng)絡(luò)協(xié)議參數(shù)等。在系統(tǒng)掉電或重新啟動(dòng)后,仍然可以讀取先前的設(shè)置信息。其位寬為8位,比CPU字長(zhǎng)小。文章特意選擇一個(gè)與CPU字長(zhǎng)不一致的存儲(chǔ)芯片,為后文中一節(jié)的討論創(chuàng)造條件。

      UART則完成CPU并行數(shù)據(jù)傳輸與RS-232串行數(shù)據(jù)傳輸?shù)霓D(zhuǎn)換,它可以在接收到[1~MAX_BUFFER]字節(jié)后向CPU提出中斷,MAX_BUFFER為UART芯片存儲(chǔ)接收到字節(jié)的最大緩沖區(qū)。

      鍵盤(pán)控制器和顯示控制器則完成系統(tǒng)人機(jī)界面的控制。以上提供的是一個(gè)較完備的嵌入式系統(tǒng)硬件架構(gòu),實(shí)際的系統(tǒng)可能包含更少的外設(shè)。之所以選擇一個(gè)完備的系統(tǒng),是為了后文更全面的討論嵌入式系統(tǒng)C語(yǔ)言編程技巧的方方面面,所有設(shè)備都會(huì)成為后文的分析目標(biāo)。

      嵌入式系統(tǒng)需要良好的軟件開(kāi)發(fā)環(huán)境的支持,由于嵌入式系統(tǒng)的目標(biāo)機(jī)資源受限,不可能在其上建立龐大、復(fù)雜的開(kāi)發(fā)環(huán)境,因而其開(kāi)發(fā)環(huán)境和目標(biāo)運(yùn)行環(huán)境相互分離。因此,嵌入式應(yīng)用軟件的開(kāi)發(fā)方式一般是,在宿主機(jī)(Host)上建立開(kāi)發(fā)環(huán)境,進(jìn)行應(yīng)用程序編碼和交叉編譯,然后宿主機(jī)同目標(biāo)機(jī)(Target)建立連接,將應(yīng)用程序下載到目標(biāo)機(jī)上進(jìn)行交叉調(diào)試,經(jīng)過(guò)調(diào)試和優(yōu)化,最后將應(yīng)用程序固化到目標(biāo)機(jī)中實(shí)際運(yùn)行。

      CAD-UL是適用于x86處理器的嵌入式應(yīng)用軟件開(kāi)發(fā)環(huán)境,它運(yùn)行在Windows操作系統(tǒng)之上,可生成x86處理器的目標(biāo)代碼并通過(guò)PC機(jī)的COM口(RS-232串口)或以太網(wǎng)口下載到目標(biāo)機(jī)上運(yùn)行,如圖2。其駐留于目標(biāo)機(jī)FLASH存儲(chǔ)器中的monitor程序可以監(jiān)控宿主機(jī)Windows調(diào)試平臺(tái)上的用戶調(diào)試指令,獲取CPU寄存器的值及目標(biāo)機(jī)存儲(chǔ)空間、I/O空間的內(nèi)容。圖2 交叉開(kāi)發(fā)環(huán)境

      后續(xù)章節(jié)將從軟件架構(gòu)、內(nèi)存操作、屏幕操作、鍵盤(pán)操作、性能優(yōu)化等多方面闡述C語(yǔ)言嵌入式系統(tǒng)的編程技巧。軟件架構(gòu)是一個(gè)宏觀概念,與具體硬件的聯(lián)系不大;內(nèi)存操作主要涉及系統(tǒng)中的FLASH、RAM和NVRAM芯片;屏幕操作則涉及顯示控制器和實(shí)時(shí)鐘;鍵盤(pán)操作主要涉及鍵盤(pán)控制器;性能優(yōu)化則給出一些具體的減小程序時(shí)間、空間消耗的技巧。

      本文即將講述的25個(gè)主題可分為兩類,一類是編程技巧,有很強(qiáng)的適用性;一類則介紹嵌入式系統(tǒng)編程的一般常識(shí),具有一定的理論意義。So, let’s go.C語(yǔ)言嵌入式系統(tǒng)編程修煉之道——軟件架構(gòu)篇 1.模塊劃分

      模塊劃分的“劃”是規(guī)劃的意思,意指怎樣合理的將一個(gè)很大的軟件劃分為一系列功能獨(dú)立的部分合作完成系統(tǒng)的需求。C語(yǔ)言作為一種結(jié)構(gòu)化的程序設(shè)計(jì)語(yǔ)言,在模塊的劃分上主要依據(jù)功能(依功能進(jìn)行劃分在面向?qū)ο笤O(shè)計(jì)中成為一個(gè)錯(cuò)誤,牛頓定律遇到了相對(duì)論),C語(yǔ)言模塊化程序設(shè)計(jì)需理解如下概念:(1)

      模塊即是一個(gè).c文件和一個(gè).h文件的結(jié)合,頭文件(.h)中是對(duì)于該模塊接口的聲明;

      (2)

      某模塊提供給其它模塊調(diào)用的外部函數(shù)及數(shù)據(jù)需在.h中文件中冠以extern關(guān)鍵字聲明;

      (3)

      模塊內(nèi)的函數(shù)和全局變量需在.c文件開(kāi)頭冠以static關(guān)鍵字聲明;(4)

      永遠(yuǎn)不要在.h文件中定義變量!定義變量和聲明變量的區(qū)別在于定義會(huì)產(chǎn)生內(nèi)存分配的操作,是匯編階段的概念;而聲明則只是告訴包含該聲明的模塊在連接階段從其它模塊尋找外部函數(shù)和變量。如: /*module1.h*/ int a = 5;

      /* 在模塊1的.h文件中定義int a */

      /*module1.c*/ #include “module1.h”

      /* 在模塊1中包含模塊1的.h文件 */ /*module2.c*/ #include “module1.h”

      /* 在模塊2中包含模塊1的.h文件 */ /*module3.c*/ #include “module1.h”

      /* 在模塊3中包含模塊1的.h文件 */ 以上程序的結(jié)果是在模塊1、2、3中都定義了整型變量a,a在不同的模塊中對(duì)應(yīng)不同的地址單元,這個(gè)世界上從來(lái)不需要這樣的程序。正確的做法是: /*module1.h*/ extern int a;

      /* 在模塊1的.h文件中聲明int a */ /*module1.c*/ #include “module1.h”

      /* 在模塊1中包含模塊1的.h文件 */ int a = 5;

      /* 在模塊1的.c文件中定義int a */ /*module2.c*/ #include “module1.h”

      /* 在模塊2中包含模塊1的.h文件 */

      /*module3.c*/ #include “module1.h”

      /* 在模塊3中包含模塊1的.h文件 */ 這樣如果模塊1、2、3操作a的話,對(duì)應(yīng)的是同一片內(nèi)存單元。一個(gè)嵌入式系統(tǒng)通常包括兩類模塊:

      (1)硬件驅(qū)動(dòng)模塊,一種特定硬件對(duì)應(yīng)一個(gè)模塊;

      (2)軟件功能模塊,其模塊的劃分應(yīng)滿足低偶合、高內(nèi)聚的要求。2.多任務(wù)還是單任務(wù)

      所謂“單任務(wù)系統(tǒng)”是指該系統(tǒng)不能支持多任務(wù)并發(fā)操作,宏觀串行地執(zhí)行一個(gè)任務(wù)。而多任務(wù)系統(tǒng)則可以宏觀并行(微觀上可能串行)地“同時(shí)”執(zhí)行多個(gè)任務(wù)。

      多任務(wù)的并發(fā)執(zhí)行通常依賴于一個(gè)多任務(wù)操作系統(tǒng)(OS),多任務(wù)OS的核心是系統(tǒng)調(diào)度器,它使用任務(wù)控制塊(TCB)來(lái)管理任務(wù)調(diào)度功能。TCB包括任務(wù)的當(dāng)前狀態(tài)、優(yōu)先級(jí)、要等待的事件或資源、任務(wù)程序碼的起始地址、初始堆棧指針等信息。調(diào)度器在任務(wù)被激活時(shí),要用到這些信息。此外,TCB還被用來(lái)存放任務(wù)的“上下文”(context)。任務(wù)的上下文就是當(dāng)一個(gè)執(zhí)行中的任務(wù)被停止時(shí),所要保存的所有信息。通常,上下文就是計(jì)算機(jī)當(dāng)前的狀態(tài),也即各個(gè)寄存器的內(nèi)容。當(dāng)發(fā)生任務(wù)切換時(shí),當(dāng)前運(yùn)行的任務(wù)的上下文被存入TCB,并將要被執(zhí)行的任務(wù)的上下文從它的TCB中取出,放入各個(gè)寄存器中。嵌入式多任務(wù)OS的典型例子有Vxworks、ucLinux等。嵌入式OS并非遙不可及的神壇之物,我們可以用不到1000行代碼實(shí)現(xiàn)一個(gè)針對(duì)80186處理器的功能最簡(jiǎn)單的OS內(nèi)核,作者正準(zhǔn)備進(jìn)行此項(xiàng)工作,希望能將心得貢獻(xiàn)給大家。

      究竟選擇多任務(wù)還是單任務(wù)方式,依賴于軟件的體系是否龐大。例如,絕大多數(shù)手機(jī)程序都是多任務(wù)的,但也有一些小靈通的協(xié)議棧是單任務(wù)的,沒(méi)有操作系統(tǒng),它們的主程序輪流調(diào)用各個(gè)軟件模塊的處理程序,模擬多任務(wù)環(huán)境。3.單任務(wù)程序典型架構(gòu)

      (1)從CPU復(fù)位時(shí)的指定地址開(kāi)始執(zhí)行;(2)跳轉(zhuǎn)至匯編代碼startup處執(zhí)行;

      (3)跳轉(zhuǎn)至用戶主程序main執(zhí)行,在main中完成: a.初試化各硬件設(shè)備;

      b.初始化各軟件模塊; c.進(jìn)入死循環(huán)(無(wú)限循環(huán)),調(diào)用各模塊的處理函數(shù)

      用戶主程序和各模塊的處理函數(shù)都以C語(yǔ)言完成。用戶主程序最后都進(jìn)入了一個(gè)死循環(huán),其首選方案是: while(1){ } 有的程序員這樣寫(xiě): for(;;){ } 這個(gè)語(yǔ)法沒(méi)有確切表達(dá)代碼的含義,我們從for(;;)看不出什么,只有弄明白for(;;)在C語(yǔ)言中意味著無(wú)條件循環(huán)才明白其意。下面是幾個(gè)“著名”的死循環(huán):(1)操作系統(tǒng)是死循環(huán);(2)WIN32程序是死循環(huán);(3)嵌入式系統(tǒng)軟件是死循環(huán);

      (4)多線程程序的線程處理函數(shù)是死循環(huán)。你可能會(huì)辯駁,大聲說(shuō):“凡事都不是絕對(duì)的,2、3、4都可以不是死循環(huán)”。Yes,you are right,但是你得不到鮮花和掌聲。實(shí)際上,這是一個(gè)沒(méi)有太大意義的牛角尖,因?yàn)檫@個(gè)世界從來(lái)不需要一個(gè)處理完幾個(gè)消息就喊著要OS殺死它的WIN32程序,不需要一個(gè)剛開(kāi)始RUN就自行了斷的嵌入式系統(tǒng),不需要莫名其妙啟動(dòng)一個(gè)做一點(diǎn)事就干掉自己的線程。有時(shí)候,過(guò)于嚴(yán)謹(jǐn)制造的不是便利而是麻煩。君不見(jiàn),五層的TCP/IP協(xié)議棧超越嚴(yán)謹(jǐn)?shù)腎SO/OSI七層協(xié)議棧大行其道成為事實(shí)上的標(biāo)準(zhǔn)? 經(jīng)常有網(wǎng)友討論:

      printf(“%d,%d”,++i,i++);

      /* 輸出是什么?*/ c = a+++b;

      /* c=? */ 等類似問(wèn)題。面對(duì)這些問(wèn)題,我們只能發(fā)出由衷的感慨:世界上還有很多有意義的事情等著我們?nèi)ハ瘮z入的食物。實(shí)際上,嵌入式系統(tǒng)要運(yùn)行到世界末日。4.中斷服務(wù)程序

      中斷是嵌入式系統(tǒng)中重要的組成部分,但是在標(biāo)準(zhǔn)C中不包含中斷。許多編譯開(kāi)發(fā)商在標(biāo)準(zhǔn)C上增加了對(duì)中斷的支持,提供新的關(guān)鍵字用于標(biāo)示中斷服務(wù)程序(ISR),類似于__interrupt、#program interrupt等。當(dāng)一個(gè)函數(shù)被定義為ISR的時(shí)候,編譯器會(huì)自動(dòng)為該函數(shù)增加中斷服務(wù)程序所需要的中斷現(xiàn)場(chǎng)入棧和出棧代碼。

      中斷服務(wù)程序需要滿足如下要求:(1)不能返回值;

      (2)不能向ISR傳遞參數(shù);

      (3)ISR應(yīng)該盡可能的短小精悍;

      (4)printf(char * lpFormatString,?)函數(shù)會(huì)帶來(lái)重入和性能問(wèn)題,不能在ISR中采用。

      在某項(xiàng)目的開(kāi)發(fā)中,我們?cè)O(shè)計(jì)了一個(gè)隊(duì)列,在中斷服務(wù)程序中,只是將中斷類型添加入該隊(duì)列中,在主程序的死循環(huán)中不斷掃描中斷隊(duì)列是否有中斷,有則取出隊(duì)列中的第一個(gè)中斷類型,進(jìn)行相應(yīng)處理。/* 存放中斷的隊(duì)列 */ typedef struct tagIntQueue { int intType;

      /* 中斷類型 */ struct tagIntQueue *next;}IntQueue;

      IntQueue lpIntQueueHead;

      __interrupt ISRexample(){

      int intType;

      intType = GetSystemType();QueueAddTail(lpIntQueueHead, intType);/* 在隊(duì)列尾加入新的中斷 */ } 在主程序循環(huán)中判斷是否有中斷: While(1){ If(!IsIntQueueEmpty())

      {

      intType = GetFirstInt();

      switch(intType)

      /* 是不是很象WIN32程序的消息解析函數(shù)? */

      {

      /* 對(duì),我們的中斷類型解析很類似于消息驅(qū)動(dòng) */

      case xxx:

      /* 我們稱其為“中斷驅(qū)動(dòng)”吧? */

      break;

      case xxx:

      break;

      } }

      } 按上述方法設(shè)計(jì)的中斷服務(wù)程序很小,實(shí)際的工作都交由主程序執(zhí)行了。5.硬件驅(qū)動(dòng)模塊

      一個(gè)硬件驅(qū)動(dòng)模塊通常應(yīng)包括如下函數(shù):(1)中斷服務(wù)程序ISR(2)硬件初始化

      a.修改寄存器,設(shè)置硬件參數(shù)(如UART應(yīng)設(shè)置其波特率,AD/DA設(shè)備應(yīng)設(shè)置其采樣速率等);

      b.將中斷服務(wù)程序入口地址寫(xiě)入中斷向量表: /* 設(shè)置中斷向量表 */

      m_myPtr = make_far_pointer(0l);/* 返回void far型指針void far * */

      m_myPtr += ITYPE_UART;/* ITYPE_UART: uart中斷服務(wù)程序 */ /* 相對(duì)于中斷向量表首地址的偏移 */

      *m_myPtr = &UART _Isr;

      /* UART _Isr:UART的中斷服務(wù)程序 */(3)設(shè)置CPU針對(duì)該硬件的控制線

      a.如果控制線可作PIO(可編程I/O)和控制信號(hào)用,則設(shè)置CPU內(nèi)部對(duì)應(yīng)寄存器使其作為控制信號(hào);

      b.設(shè)置CPU內(nèi)部的針對(duì)該設(shè)備的中斷屏蔽位,設(shè)置中斷方式(電平觸發(fā)還是邊緣觸發(fā))。

      (4)提供一系列針對(duì)該設(shè)備的操作接口函數(shù)。例如,對(duì)于LCD,其驅(qū)動(dòng)模塊應(yīng)提供繪制像素、畫(huà)線、繪制矩陣、顯示字符點(diǎn)陣等函數(shù);而對(duì)于實(shí)時(shí)鐘,其驅(qū)動(dòng)模塊則需提供獲取時(shí)間、設(shè)置時(shí)間等函數(shù)。6.C的面向?qū)ο蠡?/p>

      在面向?qū)ο蟮恼Z(yǔ)言里面,出現(xiàn)了類的概念。類是對(duì)特定數(shù)據(jù)的特定操作的集合體。類包含了兩個(gè)范疇:數(shù)據(jù)和操作。而C語(yǔ)言中的struct僅僅是數(shù)據(jù)的集合,我們可以利用函數(shù)指針將struct模擬為一個(gè)包含數(shù)據(jù)和操作的“類”。下面的C程序模擬了一個(gè)最簡(jiǎn)單的“類”: #ifndef C_Class

      #define C_Class struct #endif C_Class A {

      C_Class A *A_this;

      /* this指針 */

      void(*Foo)(C_Class A *A_this);/* 行為:函數(shù)指針 */

      int a;

      /* 數(shù)據(jù) */

      int b;};我們可以利用C語(yǔ)言模擬出面向?qū)ο蟮娜齻€(gè)特性:封裝、繼承和多態(tài),但是更多的時(shí)候,我們只是需要將數(shù)據(jù)與行為封裝以解決軟件結(jié)構(gòu)混亂的問(wèn)題。C模擬面向?qū)ο笏枷氲哪康牟辉谟谀M行為本身,而在于解決某些情況下使用C語(yǔ)言編程時(shí)程序整體框架結(jié)構(gòu)分散、數(shù)據(jù)和函數(shù)脫節(jié)的問(wèn)題。我們?cè)诤罄m(xù)章節(jié)會(huì)看到這樣的例子??偨Y(jié)

      本篇介紹了嵌入式系統(tǒng)編程軟件架構(gòu)方面的知識(shí),主要包括模塊劃分、多任務(wù)還是單任務(wù)選取、單任務(wù)程序典型架構(gòu)、中斷服務(wù)程序、硬件驅(qū)動(dòng)模塊設(shè)計(jì)等,從宏觀上給出了一個(gè)嵌入式系統(tǒng)軟件所包含的主要元素。

      請(qǐng)記?。很浖Y(jié)構(gòu)是軟件的靈魂!結(jié)構(gòu)混亂的程序面目可憎,調(diào)試、測(cè)試、維護(hù)、升級(jí)都極度困難。

      一個(gè)高尚的程序員應(yīng)該是寫(xiě)出如藝術(shù)作品般程序的程序員。

      C語(yǔ)言嵌入式系統(tǒng)編程修煉之道——內(nèi)存操作篇 1.數(shù)據(jù)指針

      在嵌入式系統(tǒng)的編程中,常常要求在特定的內(nèi)存單元讀寫(xiě)內(nèi)容,匯編有對(duì)應(yīng)的MOV指令,而除C/C++以外的其它編程語(yǔ)言基本沒(méi)有直接訪問(wèn)絕對(duì)地址的能力。在嵌入式系統(tǒng)的實(shí)際調(diào)試中,多借助C語(yǔ)言指針?biāo)哂械膶?duì)絕對(duì)地址單元內(nèi)容的讀寫(xiě)能力。以指針直接操作內(nèi)存多發(fā)生在如下幾種情況:

      (1)

      某I/O芯片被定位在CPU的存儲(chǔ)空間而非I/O空間,而且寄存器對(duì)應(yīng)于某特定地址;

      (2)

      兩個(gè)CPU之間以雙端口RAM通信,CPU需要在雙端口RAM的特定單元(稱為mail box)書(shū)寫(xiě)內(nèi)容以在對(duì)方CPU產(chǎn)生中斷;

      (3)

      讀取在ROM或FLASH的特定單元所燒錄的漢字和英文字模。譬如:

      unsigned char *p =(unsigned char *)0xF000FF00;*p=11;以上程序的意義為在絕對(duì)地址0xF0000+0xFF00(80186使用16位段地址和16位偏移地址)寫(xiě)入11。在使用絕對(duì)地址指針時(shí),要注意指針自增自減操作的結(jié)果取決于指針指向的數(shù)據(jù)類別。上例中p++后的結(jié)果是p= 0xF000FF01,若p指向int,即: int *p =(int *)0xF000FF00;p++(或++p)的結(jié)果等同于:p = p+sizeof(int),而p—(或—p)的結(jié)果是p = p-sizeof(int)。同理,若執(zhí)行:

      long int *p =(long int *)0xF000FF00;則p++(或++p)的結(jié)果等同于:p = p+sizeof(long int),而p—(或—p)的結(jié)果是p = p-sizeof(long int)。

      記?。篊PU以字節(jié)為單位編址,而C語(yǔ)言指針以指向的數(shù)據(jù)類型長(zhǎng)度作自增和自減。理解這一點(diǎn)對(duì)于以指針直接操作內(nèi)存是相當(dāng)重要的。2.函數(shù)指針

      首先要理解以下三個(gè)問(wèn)題:

      (1)C語(yǔ)言中函數(shù)名直接對(duì)應(yīng)于函數(shù)生成的指令代碼在內(nèi)存中的地址,因此函數(shù)名可以直接賦給指向函數(shù)的指針;

      (2)調(diào)用函數(shù)實(shí)際上等同于“調(diào)轉(zhuǎn)指令+參數(shù)傳遞處理+回歸位置入棧”,本質(zhì)上最核心的操作是將函數(shù)生成的目標(biāo)代碼的首地址賦給CPU的PC寄存器;(3)因?yàn)楹瘮?shù)調(diào)用的本質(zhì)是跳轉(zhuǎn)到某一個(gè)地址單元的code去執(zhí)行,所以可以“調(diào)用”一個(gè)根本就不存在的函數(shù)實(shí)體,暈?請(qǐng)往下看: 請(qǐng)拿出你可以獲得的任何一本大學(xué)《微型計(jì)算機(jī)原理》教材,書(shū)中講到,186 CPU啟動(dòng)后跳轉(zhuǎn)至絕對(duì)地址0xFFFF0(對(duì)應(yīng)C語(yǔ)言指針是0xF000FFF0,0xF000為段地址,0xFFF0為段內(nèi)偏移)執(zhí)行,請(qǐng)看下面的代碼:

      typedef void(*lpFunction)();

      /* 定義一個(gè)無(wú)參數(shù)、無(wú)返回類型的 */ /* 函數(shù)指針類型 */ lpFunction lpReset =(lpFunction)0xF000FFF0;

      /* 定義一個(gè)函數(shù)指針,指向*/ /* CPU啟動(dòng)后所執(zhí)行第一條指令的位置 */ lpReset();

      /* 調(diào)用函數(shù) */ 在以上的程序中,我們根本沒(méi)有看到任何一個(gè)函數(shù)實(shí)體,但是我們卻執(zhí)行了這樣的函數(shù)調(diào)用:lpReset(),它實(shí)際上起到了“軟重啟”的作用,跳轉(zhuǎn)到CPU啟動(dòng)后第一條要執(zhí)行的指令的位置。

      記?。汉瘮?shù)無(wú)它,唯指令集合耳;你可以調(diào)用一個(gè)沒(méi)有函數(shù)體的函數(shù),本質(zhì)上只是換一個(gè)地址開(kāi)始執(zhí)行指令!3.數(shù)組vs.動(dòng)態(tài)申請(qǐng)

      在嵌入式系統(tǒng)中動(dòng)態(tài)內(nèi)存申請(qǐng)存在比一般系統(tǒng)編程時(shí)更嚴(yán)格的要求,這是因?yàn)榍度胧较到y(tǒng)的內(nèi)存空間往往是十分有限的,不經(jīng)意的內(nèi)存泄露會(huì)很快導(dǎo)致系統(tǒng)的崩潰。

      所以一定要保證你的malloc和free成對(duì)出現(xiàn),如果你寫(xiě)出這樣的一段程序: char * function(void){

      char *p;

      p =(char *)malloc(…);

      if(p==NULL)?;

      ?

      /* 一系列針對(duì)p的操作 */ return p;} 在某處調(diào)用function(),用完function中動(dòng)態(tài)申請(qǐng)的內(nèi)存后將其free,如下: char *q = function();? free(q);上述代碼明顯是不合理的,因?yàn)檫`反了malloc和free成對(duì)出現(xiàn)的原則,即“誰(shuí)申請(qǐng),就由誰(shuí)釋放”原則。不滿足這個(gè)原則,會(huì)導(dǎo)致代碼的耦合度增大,因?yàn)橛脩粼谡{(diào)用function函數(shù)時(shí)需要知道其內(nèi)部細(xì)節(jié)!

      正確的做法是在調(diào)用處申請(qǐng)內(nèi)存,并傳入function函數(shù),如下: char *p=malloc(…);if(p==NULL)?;function(p);? free(p);p=NULL;而函數(shù)function則接收參數(shù)p,如下: void function(char *p){ ?

      /* 一系列針對(duì)p的操作 */ } 基本上,動(dòng)態(tài)申請(qǐng)內(nèi)存方式可以用較大的數(shù)組替換。對(duì)于編程新手,筆者推薦你盡量采用數(shù)組!嵌入式系統(tǒng)可以以博大的胸襟接收瑕疵,而無(wú)法“海納”錯(cuò)誤。畢竟,以最笨的方式苦練神功的郭靖勝過(guò)機(jī)智聰明卻范政治錯(cuò)誤走反革命道路的楊康。

      給出原則:

      (1)盡可能的選用數(shù)組,數(shù)組不能越界訪問(wèn)(真理越過(guò)一步就是謬誤,數(shù)組越過(guò)界限就光榮地成全了一個(gè)混亂的嵌入式系統(tǒng));

      (2)如果使用動(dòng)態(tài)申請(qǐng),則申請(qǐng)后一定要判斷是否申請(qǐng)成功了,并且malloc和free應(yīng)成對(duì)出現(xiàn)!4.關(guān)鍵字const const意味著“只讀”。區(qū)別如下代碼的功能非常重要,也是老生長(zhǎng)嘆,如果你還不知道它們的區(qū)別,而且已經(jīng)在程序界摸爬滾打多年,那只能說(shuō)這是一個(gè)悲哀: const int a;int const a;const int *a;int * const a;int const * a const;(1)關(guān)鍵字const的作用是為給讀你代碼的人傳達(dá)非常有用的信息。例如,在函數(shù)的形參前添加const關(guān)鍵字意味著這個(gè)參數(shù)在函數(shù)體內(nèi)不會(huì)被修改,屬于“輸入?yún)?shù)”。在有多個(gè)形參的時(shí)候,函數(shù)的調(diào)用者可以憑借參數(shù)前是否有const關(guān)鍵字,清晰的辨別哪些是輸入?yún)?shù),哪些是可能的輸出參數(shù)。

      (2)合理地使用關(guān)鍵字const可以使編譯器很自然地保護(hù)那些不希望被改變的參數(shù),防止其被無(wú)意的代碼修改,這樣可以減少bug的出現(xiàn)。const在C++語(yǔ)言中則包含了更豐富的含義,而在C語(yǔ)言中僅意味著:“只能讀的普通變量”,可以稱其為“不能改變的變量”(這個(gè)說(shuō)法似乎很拗口,但卻最準(zhǔn)確的表達(dá)了C語(yǔ)言中const的本質(zhì)),在編譯階段需要的常數(shù)仍然只能以#define宏定義!故在C語(yǔ)言中如下程序是非法的: const int SIZE = 10;char a[SIZE];/* 非法:編譯階段不能用到變量 */ 5.關(guān)鍵字volatile C語(yǔ)言編譯器會(huì)對(duì)用戶書(shū)寫(xiě)的代碼進(jìn)行優(yōu)化,譬如如下代碼: int a,b,c;a = inWord(0x100);/*讀取I/O空間0x100端口的內(nèi)容存入a變量*/ b = a;a = inWord(0x100);/*再次讀取I/O空間0x100端口的內(nèi)容存入a變量*/ c = a;很可能被編譯器優(yōu)化為: int a,b,c;a = inWord(0x100);/*讀取I/O空間0x100端口的內(nèi)容存入a變量*/ b = a;c = a;但是這樣的優(yōu)化結(jié)果可能導(dǎo)致錯(cuò)誤,如果I/O空間0x100端口的內(nèi)容在執(zhí)行第一次讀操作后被其它程序?qū)懭胄轮?,則其實(shí)第2次讀操作讀出的內(nèi)容與第一次不同,b和c的值應(yīng)該不同。在變量a的定義前加上volatile關(guān)鍵字可以防止編譯器的類似優(yōu)化,正確的做法是: volatile int a;

      volatile變量可能用于如下幾種情況:

      (1)并行設(shè)備的硬件寄存器(如:狀態(tài)寄存器,例中的代碼屬于此類);(2)一個(gè)中斷服務(wù)子程序中會(huì)訪問(wèn)到的非自動(dòng)變量(也就是全局變量);(3)多線程應(yīng)用中被幾個(gè)任務(wù)共享的變量。6.CPU字長(zhǎng)與存儲(chǔ)器位寬不一致處理

      在背景篇中提到,本文特意選擇了一個(gè)與CPU字長(zhǎng)不一致的存儲(chǔ)芯片,就是為了進(jìn)行本節(jié)的討論,解決CPU字長(zhǎng)與存儲(chǔ)器位寬不一致的情況。80186的字長(zhǎng)為16,而NVRAM的位寬為8,在這種情況下,我們需要為NVRAM提供讀寫(xiě)字節(jié)、字的接口,如下: typedef unsigned char BYTE;typedef unsigned int WORD;

      /* 函數(shù)功能:讀NVRAM中字節(jié)

      * 參數(shù):wOffset,讀取位置相對(duì)NVRAM基地址的偏移

      * 返回:讀取到的字節(jié)值 */ extern BYTE ReadByteNVRAM(WORD wOffset){

      LPBYTE lpAddr =(BYTE*)(NVRAM + wOffset * 2);/* 為什么偏移要×2? */

      return *lpAddr;}

      /* 函數(shù)功能:讀NVRAM中字

      * 參數(shù):wOffset,讀取位置相對(duì)NVRAM基地址的偏移

      * 返回:讀取到的字 */ extern WORD ReadWordNVRAM(WORD wOffset){

      WORD wTmp = 0;

      LPBYTE lpAddr;

      /* 讀取高位字節(jié) */

      lpAddr =(BYTE*)(NVRAM + wOffset * 2);

      /* 為什么偏移要×2? */

      wTmp +=(*lpAddr)*256;

      /* 讀取低位字節(jié) */

      lpAddr =(BYTE*)(NVRAM +(wOffset +1)* 2);

      /* 為什么偏移要×2? */

      wTmp += *lpAddr;

      return wTmp;}

      /* 函數(shù)功能:向NVRAM中寫(xiě)一個(gè)字節(jié)

      *參數(shù):wOffset,寫(xiě)入位置相對(duì)NVRAM基地址的偏移 *

      byData,欲寫(xiě)入的字節(jié) */ extern void WriteByteNVRAM(WORD wOffset, BYTE byData){

      … }

      /* 函數(shù)功能:向NVRAM中寫(xiě)一個(gè)字 */ *參數(shù):wOffset,寫(xiě)入位置相對(duì)NVRAM基地址的偏移 *

      wData,欲寫(xiě)入的字 */ extern void WriteWordNVRAM(WORD wOffset, WORD wData){

      … } 子貢問(wèn)曰:Why偏移要乘以2? 子曰:請(qǐng)看圖1,16位80186與8位NVRAM之間互連只能以地址線A1對(duì)其A0,CPU本身的A0與NVRAM不連接。因此,NVRAM的地址只能是偶數(shù)地址,故每次以2為單位前進(jìn)!

      圖1 CPU與NVRAM地址線連接

      子貢再問(wèn):So why 80186的地址線A0不與NVRAM的A0連接? 子曰:請(qǐng)看《IT論語(yǔ)》之《微機(jī)原理篇》,那里面講述了關(guān)于計(jì)算機(jī)組成的圣人之道??偨Y(jié)

      本篇主要講述了嵌入式系統(tǒng)C編程中內(nèi)存操作的相關(guān)技巧。掌握并深入理解關(guān)于數(shù)據(jù)指針、函數(shù)指針、動(dòng)態(tài)申請(qǐng)內(nèi)存、const及volatile關(guān)鍵字等的相關(guān)知識(shí),是一個(gè)優(yōu)秀的C語(yǔ)言程序設(shè)計(jì)師的基本要求。當(dāng)我們已經(jīng)牢固掌握了上述技巧后,我們就已經(jīng)學(xué)會(huì)了C語(yǔ)言的99%,因?yàn)镃語(yǔ)言最精華的內(nèi)涵皆在內(nèi)存操作中體現(xiàn)。

      我們之所以在嵌入式系統(tǒng)中使用C語(yǔ)言進(jìn)行程序設(shè)計(jì),99%是因?yàn)槠鋸?qiáng)大的內(nèi)存操作能力!

      如果你愛(ài)編程,請(qǐng)你愛(ài)C語(yǔ)言; 如果你愛(ài)C語(yǔ)言,請(qǐng)你愛(ài)指針; 如果你愛(ài)指針,請(qǐng)你愛(ài)指針的指針!

      C語(yǔ)言嵌入式系統(tǒng)編程修煉之道——屏幕操作篇 1.漢字處理

      現(xiàn)在要解決的問(wèn)題是,嵌入式系統(tǒng)中經(jīng)常要使用的并非是完整的漢字庫(kù),往往只是需要提供數(shù)量有限的漢字供必要的顯示功能。例如,一個(gè)微波爐的LCD上沒(méi)有必要提供顯示“電子郵件”的功能;一個(gè)提供漢字顯示功能的空調(diào)的LCD上不需要顯示一條“短消息”,諸如此類。但是一部手機(jī)、小靈通則通常需要包括較完整的漢字庫(kù)。

      如果包括的漢字庫(kù)較完整,那么,由內(nèi)碼計(jì)算出漢字字模在庫(kù)中的偏移是十分簡(jiǎn)單的:漢字庫(kù)是按照區(qū)位的順序排列的,前一個(gè)字節(jié)為該漢字的區(qū)號(hào),后一個(gè)字節(jié)為該字的位號(hào)。每一個(gè)區(qū)記錄94個(gè)漢字,位號(hào)則為該字在該區(qū)中的位置。因此,漢字在漢字庫(kù)中的具體位置計(jì)算公式為:94*(區(qū)號(hào)-1)+位號(hào)-1。減1是因?yàn)閿?shù)組是以0為開(kāi)始而區(qū)號(hào)位號(hào)是以1為開(kāi)始的。只需乘上一個(gè)漢字字模占用的字節(jié)數(shù)即可,即:(94*(區(qū)號(hào)-1)+位號(hào)-1)*一個(gè)漢字字模占用字節(jié)數(shù),以16*16點(diǎn)陣字庫(kù)為例,計(jì)算公式則為:(94*(區(qū)號(hào)-1)+(位號(hào)-1))*32。漢字庫(kù)中從該位置起的32字節(jié)信息記錄了該字的字模信息。

      對(duì)于包含較完整漢字庫(kù)的系統(tǒng)而言,我們可以以上述規(guī)則計(jì)算字模的位置。但是如果僅僅是提供少量漢字呢?譬如幾十至幾百個(gè)?最好的做法是: 定義宏:

      # define EX_FONT_CHAR(value)

      # define EX_FONT_UNICODE_VAL(value)(value), # define EX_FONT_ANSI_VAL(value)(value), 定義結(jié)構(gòu)體:

      typedef struct _wide_unicode_font16x16 { WORD value;

      /* 內(nèi)碼 */ BYTE data[32];/* 字模點(diǎn)陣 */ }Unicode;#define CHINESE_CHAR_NUM ?

      /* 漢字?jǐn)?shù)量 */ 字模的存儲(chǔ)用數(shù)組:

      Unicode chinese[CHINESE_CHAR_NUM] = { {

      EX_FONT_CHAR(“業(yè)”)

      EX_FONT_UNICODE_VAL(0x4e1a)

      {0x04, 0x40, 0x04, 0x40, 0x04, 0x40, 0x04, 0x44, 0x44, 0x46, 0x24, 0x4c, 0x24, 0x48, 0x14, 0x50, 0x1c, 0x50,0x14, 0x60, 0x04, 0x40, 0x04, 0x40, 0x04, 0x44, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00}

      },{

      EX_FONT_CHAR(“中”)

      EX_FONT_UNICODE_VAL(0x4e2d)

      {0x01, 0x00, 0x01, 0x00, 0x21, 0x08, 0x3f, 0xfc, 0x21, 0x08, 0x21, 0x08, 0x21, 0x08, 0x21, 0x08, 0x21, 0x08,0x3f, 0xf8, 0x21, 0x08, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00}

      },{

      EX_FONT_CHAR(“云”)

      EX_FONT_UNICODE_VAL(0x4e91)

      {0x00, 0x00, 0x00, 0x30, 0x3f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xff, 0xfe, 0x03, 0x00, 0x07, 0x00,0x06, 0x40, 0x0c, 0x20, 0x18, 0x10, 0x31, 0xf8, 0x7f, 0x0c, 0x20, 0x08, 0x00, 0x00}

      },{

      EX_FONT_CHAR(“件”)

      EX_FONT_UNICODE_VAL(0x4ef6)

      {0x10, 0x40, 0x1a, 0x40, 0x13, 0x40, 0x32, 0x40, 0x23, 0xfc, 0x64, 0x40, 0xa4, 0x40, 0x28, 0x40, 0x2f, 0xfe,0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40}

      } } 要顯示特定漢字的時(shí)候,只需要從數(shù)組中查找內(nèi)碼與要求漢字內(nèi)碼相同的即可獲得字模。如果前面的漢字在數(shù)組中以內(nèi)碼大小順序排列,那么可以以二分查找法更高效的查找到漢字的字模。

      這是一種很有效的組織小漢字庫(kù)的方法,它可以保證程序有很好的結(jié)構(gòu)。2.系統(tǒng)時(shí)間顯示

      從NVRAM中可以讀取系統(tǒng)的時(shí)間,系統(tǒng)一般借助NVRAM產(chǎn)生的秒中斷每秒讀取一次當(dāng)前時(shí)間并在LCD上顯示。關(guān)于時(shí)間的顯示,有一個(gè)效率問(wèn)題。因?yàn)闀r(shí)間有其特殊性,那就是60秒才有一次分鐘的變化,60分鐘才有一次小時(shí)變化,如果我們每次都將讀取的時(shí)間在屏幕上完全重新刷新一次,則浪費(fèi)了大量的系統(tǒng)時(shí)間。

      一個(gè)較好的辦法是我們?cè)跁r(shí)間顯示函數(shù)中以靜態(tài)變量分別存儲(chǔ)小時(shí)、分鐘、秒,只有在其內(nèi)容發(fā)生變化的時(shí)候才更新其顯示。extern void DisplayTime(…){

      static BYTE byHour,byMinute,bySecond;

      BYTE byNewHour, byNewMinute, byNewSecond;

      byNewHour = GetSysHour();

      byNewMinute = GetSysMinute();

      byNewSecond = GetSysSecond();

      if(byNewHour!= byHour)

      { ?

      /* 顯示小時(shí) */ byHour = byNewHour;}

      if(byNewMinute!= byMinute)

      { ?

      /* 顯示分鐘 */ byMinute = byNewMinute;}

      if(byNewSecond!= bySecond)

      { ?

      /* 顯示秒鐘 */ bySecond = byNewSecond;} } 這個(gè)例子也可以順便作為C語(yǔ)言中static關(guān)鍵字強(qiáng)大威力的證明。當(dāng)然,在C++語(yǔ)言里,static具有了更加強(qiáng)大的威力,它使得某些數(shù)據(jù)和函數(shù)脫離“對(duì)象”而成為“類”的一部分,正是它的這一特點(diǎn),成就了軟件的無(wú)數(shù)優(yōu)秀設(shè)計(jì)。3.動(dòng)畫(huà)顯示

      動(dòng)畫(huà)是無(wú)所謂有,無(wú)所謂無(wú)的,靜止的畫(huà)面走的路多了,也就成了動(dòng)畫(huà)。隨著時(shí)間的變更,在屏幕上顯示不同的靜止畫(huà)面,即是動(dòng)畫(huà)之本質(zhì)。所以,在一個(gè)嵌入式系統(tǒng)的LCD上欲顯示動(dòng)畫(huà),必須借助定時(shí)器。沒(méi)有硬件或軟件定時(shí)器的世界是無(wú)法想像的:

      (1)

      沒(méi)有定時(shí)器,一個(gè)操作系統(tǒng)將無(wú)法進(jìn)行時(shí)間片的輪轉(zhuǎn),于是無(wú)法進(jìn)行多任務(wù)的調(diào)度,于是便不再成其為一個(gè)多任務(wù)操作系統(tǒng);

      (2)

      沒(méi)有定時(shí)器,一個(gè)多媒體播放軟件將無(wú)法運(yùn)作,因?yàn)樗恢篮螘r(shí)應(yīng)該切換到下一幀畫(huà)面;

      (3)

      沒(méi)有定時(shí)器,一個(gè)網(wǎng)絡(luò)協(xié)議將無(wú)法運(yùn)轉(zhuǎn),因?yàn)槠錈o(wú)法獲知何時(shí)包傳輸超時(shí)并重傳之,無(wú)法在特定的時(shí)間完成特定的任務(wù)。

      因此,沒(méi)有定時(shí)器將意味著沒(méi)有操作系統(tǒng)、沒(méi)有網(wǎng)絡(luò)、沒(méi)有多媒體,這將是怎樣的黑暗?所以,合理并靈活地使用各種定時(shí)器,是對(duì)一個(gè)軟件人的最基本需求!在80186為主芯片的嵌入式系統(tǒng)中,我們需要借助硬件定時(shí)器的中斷來(lái)作為軟件定時(shí)器,在中斷發(fā)生后變更畫(huà)面的顯示內(nèi)容。在時(shí)間顯示“xx:xx”中讓冒號(hào)交替有無(wú),每次秒中斷發(fā)生后,需調(diào)用ShowDot: void ShowDot(){ static BOOL bShowDot = TRUE;

      /* 再一次領(lǐng)略static關(guān)鍵字的威力 */ if(bShowDot)

      { showChar(‘:’,xPos,yPos);} else

      { showChar(‘ ’,xPos,yPos);

      } bShowDot =!bShowDot;} 4.菜單操作

      無(wú)數(shù)人為之絞盡腦汁的問(wèn)題終于出現(xiàn)了,在這一節(jié)里,我們將看到,在C語(yǔ)言中哪怕用到一丁點(diǎn)的面向?qū)ο笏枷?,軟件結(jié)構(gòu)將會(huì)有何等的改觀!筆者曾經(jīng)是個(gè)笨蛋,被菜單搞暈了,給出這樣的一個(gè)系統(tǒng): 圖1 菜單范例

      要求以鍵盤(pán)上的“←→”鍵切換菜單焦點(diǎn),當(dāng)用戶在焦點(diǎn)處于某菜單時(shí),若敲擊鍵盤(pán)上的OK、CANCEL鍵則調(diào)用該焦點(diǎn)菜單對(duì)應(yīng)之處理函數(shù)。我曾經(jīng)傻傻地這樣做著:

      /* 按下OK鍵 */ void onOkKey(){ /* 判斷在什么焦點(diǎn)菜單上按下Ok鍵,調(diào)用相應(yīng)處理函數(shù) */ Switch(currentFocus){ case MENU1:

      menu1OnOk();

      break;case MENU2:

      menu2OnOk();

      break;? } } /* 按下Cancel鍵 */ void onCancelKey(){ /* 判斷在什么焦點(diǎn)菜單上按下Cancel鍵,調(diào)用相應(yīng)處理函數(shù) */ Switch(currentFocus){ case MENU1:

      menu1OnCancel();

      break;case MENU2:

      menu2OnCancel();

      break;? } } 終于有一天,我這樣做了:

      /* 將菜單的屬性和操作“封裝”在一起 */ typedef struct tagSysMenu

      {

      char *text;

      /* 菜單的文本 */

      BYTE xPos;/* 菜單在LCD上的x坐標(biāo) */

      BYTE yPos;/* 菜單在LCD上的y坐標(biāo) */

      void(*onOkFun)();

      /* 在該菜單上按下ok鍵的處理函數(shù)指針 */

      void(*onCancelFun)();/* 在該菜單上按下cancel鍵的處理函數(shù)指針 */ }SysMenu, *LPSysMenu;當(dāng)我定義菜單時(shí),只需要這樣: static SysMenu menu[MENU_NUM] = {

      {

      “menu1”, 0, 48, menu1OnOk, menu1OnCancel

      } ,{

      “ menu2”, 7, 48, menu2OnOk, menu2OnCancel

      } ,{

      “ menu3”, 7, 48, menu3OnOk, menu3OnCancel

      } ,{

      “ menu4”, 7, 48, menu4OnOk, menu4OnCancel

      }

      … };OK鍵和CANCEL鍵的處理變成: /* 按下OK鍵 */ void onOkKey(){

      menu[currentFocusMenu].onOkFun();

      } /* 按下Cancel鍵 */ void onCancelKey(){ menu[currentFocusMenu].onCancelFun();

      } 程序被大大簡(jiǎn)化了,也開(kāi)始具有很好的可擴(kuò)展性!我們僅僅利用了面向?qū)ο笾械姆庋b思想,就讓程序結(jié)構(gòu)清晰,其結(jié)果是幾乎可以在無(wú)需修改程序的情況下在系統(tǒng)中添加更多的菜單,而系統(tǒng)的按鍵處理函數(shù)保持不變。面向?qū)ο?,真神了?.模擬MessageBox函數(shù)

      MessageBox函數(shù),這個(gè)Windows編程中的超級(jí)猛料,不知道是多少入門(mén)者第一次用到的函數(shù)。還記得我們第一次在Windows中利用MessageBox輸出“Hello,World!”對(duì)話框時(shí)新奇的感覺(jué)嗎?無(wú)法統(tǒng)計(jì),這個(gè)世界上究竟有多少程序員學(xué)習(xí)Windows編程是從MessageBox(“Hello,World!”,?)開(kāi)始的。在我本科的學(xué)校,廣泛流傳著一個(gè)詞匯,叫做“‘Hello,World’級(jí)程序員”,意指入門(mén)級(jí)程序員,但似乎“‘Hello,World’級(jí)”這個(gè)說(shuō)法更搞笑而形象。

      圖2 經(jīng)典的Hello,World!圖2給出了兩種永恒經(jīng)典的Hello,World對(duì)話框,一種只具有“確定”,一種則包含“確定”、“取消”。是的,MessageBox的確有,而且也應(yīng)該有兩類!這完全是由特定的應(yīng)用需求決定的。

      嵌入式系統(tǒng)中沒(méi)有給我們提供MessageBox,但是鑒于其功能強(qiáng)大,我們需要模擬之,一個(gè)模擬的MessageBox函數(shù)為:

      /****************************************** /*

      函數(shù)名稱:

      MessageBox /*

      功能說(shuō)明:

      彈出式對(duì)話框,顯示提醒用戶的信息 /*

      參數(shù)說(shuō)明:

      lpStr---提醒用戶的字符串輸出信息

      /*

      TYPE---輸出格式(ID_OK = 0, ID_OKCANCEL = 1)/*

      返回值:

      返回對(duì)話框接收的鍵值,只有兩種 KEY_OK, KEY_CANCEL /****************************************** typedef enum TYPE

      { ID_OK,ID_OKCANCEL

      }MSG_TYPE;extern

      BYTE MessageBox(LPBYTE lpStr, BYTE TYPE){

      BYTE keyValue =-1;

      ClearScreen();

      /* 清除屏幕 */

      DisplayString(xPos,yPos,lpStr,TRUE);/* 顯示字符串 */

      /* 根據(jù)對(duì)話框類型決定是否顯示確定、取消 */

      switch(TYPE)

      {

      case

      ID_OK:

      DisplayString(13,yPos+High+1, “ 確定 ”, 0);

      break;

      case

      ID_OKCANCEL:

      DisplayString(8, yPos+High+1, “ 確定 ”, 0);

      DisplayString(17,yPos+High+1, “ 取消 ”, 0);

      break;

      default:

      break;

      }

      DrawRect(0, 0, 239, yPos+High+16+4);/* 繪制外框 */

      /* MessageBox是模式對(duì)話框,阻塞運(yùn)行,等待按鍵 */

      while((keyValue!= KEY_OK)||(keyValue!= KEY_CANCEL))

      { keyValue = getSysKey();} /* 返回按鍵類型 */ if(keyValue== KEY_OK){ return ID_OK;} else { return ID_CANCEL;} } 上述函數(shù)與我們平素在VC++等中使用的MessageBox是何等的神似?。繉?shí)現(xiàn)這個(gè)函數(shù),你會(huì)看到它在嵌入式系統(tǒng)中的妙用是無(wú)窮的。總結(jié)

      本篇是本系列文章中技巧性最深的一篇,它提供了嵌入式系統(tǒng)屏幕顯示方面一些很巧妙的處理方法,靈活使用它們,我們將不再被LCD上凌亂不堪的顯示內(nèi)容所困擾。

      屏幕乃嵌入式系統(tǒng)生存之重要輔助,面目可憎之顯示將另用戶逃之夭夭。屏幕編程若處理不好,將是軟件中最不系統(tǒng)、最混亂的部分,筆者曾深受其害。

      C語(yǔ)言嵌入式系統(tǒng)編程修煉之道——鍵盤(pán)操作篇 1.處理功能鍵

      功能鍵的問(wèn)題在于,用戶界面并非固定的,用戶功能鍵的選擇將使屏幕畫(huà)面處于不同的顯示狀態(tài)下。例如,主畫(huà)面如圖1: 圖1 主畫(huà)面

      當(dāng)用戶在設(shè)置XX上按下Enter鍵之后,畫(huà)面就切換到了設(shè)置XX的界面,如圖2:

      圖2 切換到設(shè)置XX畫(huà)面

      程序如何判斷用戶處于哪一畫(huà)面,并在該畫(huà)面的程序狀態(tài)下調(diào)用對(duì)應(yīng)的功能鍵處理函數(shù),而且保證良好的結(jié)構(gòu),是一個(gè)值得思考的問(wèn)題。

      讓我們來(lái)看看WIN32編程中用到的“窗口”概念,當(dāng)消息(message)被發(fā)送給不同窗口的時(shí)候,該窗口的消息處理函數(shù)(是一個(gè)callback函數(shù))最終被調(diào)用,而在該窗口的消息處理函數(shù)中,又根據(jù)消息的類型調(diào)用了該窗口中的對(duì)應(yīng)處理函數(shù)。通過(guò)這種方式,WIN32有效的組織了不同的窗口,并處理不同窗口情況下的消息。

      我們從中學(xué)習(xí)到的就是:

      (1)將不同的畫(huà)面類比為WIN32中不同的窗口,將窗口中的各種元素(菜單、按鈕等)包含在窗口之中;

      (2)給各個(gè)畫(huà)面提供一個(gè)功能鍵“消息”處理函數(shù),該函數(shù)接收按鍵信息為參數(shù);

      (3)在各畫(huà)面的功能鍵“消息”處理函數(shù)中,判斷按鍵類型和當(dāng)前焦點(diǎn)元素,并調(diào)用對(duì)應(yīng)元素的按鍵處理函數(shù)。

      /* 將窗口元素、消息處理函數(shù)封裝在窗口中 */ struct windows {

      BYTE currentFocus;

      ELEMENT element[ELEMENT_NUM];

      void(*messageFun)(BYTE keyValue);

      … };/* 消息處理函數(shù) */ void messageFunction(BYTE keyValue){

      BYTE i = 0;

      /* 獲得焦點(diǎn)元素 */

      while((element [i].ID!= currentFocus)&&(i < ELEMENT_NUM))

      {

      i++;

      }

      /* “消息映射” */

      if(i < ELEMENT_NUM)

      {

      switch(keyValue)

      {

      case OK:

      element[i].OnOk();

      break;

      }

      } } 在窗口的消息處理函數(shù)中調(diào)用相應(yīng)元素按鍵函數(shù)的過(guò)程類似于“消息映射”,這是我們從WIN32編程中學(xué)習(xí)到的。編程到了一個(gè)境界,很多東西都是相通的了。其它地方的思想可以拿過(guò)來(lái)為我所用,是為編程中的“拿來(lái)主義”。

      在這個(gè)例子中,如果我們還想玩得更大一點(diǎn),我們可以借鑒MFC中處理MESSAGE_MAP的方法,我們也可以學(xué)習(xí)MFC定義幾個(gè)精妙的宏來(lái)實(shí)現(xiàn)“消息映射”。2.處理數(shù)字鍵

      用戶輸入數(shù)字時(shí)是一位一位輸入的,每一位的輸入都對(duì)應(yīng)著屏幕上的一個(gè)顯示位置(x坐標(biāo),y坐標(biāo))。此外,程序還需要記錄該位置輸入的值,所以有效組織用戶數(shù)字輸入的最佳方式是定義一個(gè)結(jié)構(gòu)體,將坐標(biāo)和數(shù)值捆綁在一起: /* 用戶數(shù)字輸入結(jié)構(gòu)體 */ typedef struct tagInputNum

      {

      BYTE byNum;/* 接收用戶輸入賦值 */

      BYTE xPos;

      /* 數(shù)字輸入在屏幕上的顯示位置x坐標(biāo) */

      BYTE yPos;

      /* 數(shù)字輸入在屏幕上的顯示位置y坐標(biāo) */

      }InputNum, *LPInputNum;那么接收用戶輸入就可以定義一個(gè)結(jié)構(gòu)體數(shù)組,用數(shù)組中的各位組成一個(gè)完整的數(shù)字:

      InputNum inputElement[NUM_LENGTH];/* 接收用戶數(shù)字輸入的數(shù)組 */ /* 數(shù)字按鍵處理函數(shù) */ extern void onNumKey(BYTE num){

      if(num==0|| num==1)/* 只接收二進(jìn)制輸入 */

      { /* 在屏幕上顯示用戶輸入 */ DrawText(inputElement[currentElementInputPlace].xPos, inputElement[currentElementInputPlace].yPos, “%1d”, num);

      /* 將輸入賦值給數(shù)組元素 */

      inputElement[currentElementInputPlace].byNum = num;

      /* 焦點(diǎn)及光標(biāo)右移 */

      moveToRight();

      } } 將數(shù)字每一位輸入的坐標(biāo)和輸入值捆綁后,在數(shù)字鍵處理函數(shù)中就可以較有結(jié)構(gòu)的組織程序,使程序顯得很緊湊。3.整理用戶輸入

      繼續(xù)第2節(jié)的例子,在第2節(jié)的onNumKey函數(shù)中,只是獲取了數(shù)字的每一位,因而我們需要將其轉(zhuǎn)化為有效數(shù)據(jù),譬如要轉(zhuǎn)化為有效的XXX數(shù)據(jù),其方法是:

      /* 從2進(jìn)制數(shù)據(jù)位轉(zhuǎn)化為有效數(shù)據(jù):XXX */ void convertToXXX(){

      BYTE i;

      XXX = 0;

      for(i = 0;i < NUM_LENGTH;i++)

      {

      XXX += inputElement[i].byNum*power(2, NUM_LENGTH1);

      }

      } 反之,我們也可能需要在屏幕上顯示那些有效的數(shù)據(jù)位,因?yàn)槲覀円残枰軌蚍聪蜣D(zhuǎn)化:

      /* 從有效數(shù)據(jù)轉(zhuǎn)化為2進(jìn)制數(shù)據(jù)位:XXX */ void convertFromXXX(){

      BYTE i;

      XXX = 0;

      for(i = 0;i < NUM_LENGTH;i++)

      {

      inputElement[i].byNum = XXX / power(2, NUM_LENGTH1)% 2;

      }

      } 當(dāng)然在上面的例子中,因?yàn)閿?shù)據(jù)是2進(jìn)制的,用power函數(shù)不是很好的選擇,直接用“<< >>”移位操作效率更高,我們僅是為了說(shuō)明問(wèn)題的方便。試想,如果用戶輸入是十進(jìn)制的,power函數(shù)或許是唯一的選擇了??偨Y(jié)

      本篇給出了鍵盤(pán)操作所涉及的各個(gè)方面:功能鍵處理、數(shù)字鍵處理及用戶輸入整理,基本上提供了一個(gè)全套的按鍵處理方案。對(duì)于功能鍵處理方法,將LCD屏幕與Windows窗口進(jìn)行類比,提出了較新穎地解決屏幕、鍵盤(pán)繁雜交互問(wèn)題的方案。

      計(jì)算機(jī)學(xué)的許多知識(shí)都具有相通性,因而,不斷追趕時(shí)髦技術(shù)而忽略基本功的做法是徒勞無(wú)意的。我們最多需要“精通”三種語(yǔ)言(精通,一個(gè)在如今的求職簡(jiǎn)歷里泛濫成災(zāi)的詞語(yǔ)),最佳拍檔是匯編、C、C++(或JAVA),很顯然,如果你“精通”了這三種語(yǔ)言,其它語(yǔ)言你應(yīng)該是可以很快“熟悉”的,否則你就沒(méi)有“精通”它們。

      C語(yǔ)言嵌入式系統(tǒng)編程修煉之道——性能優(yōu)化篇 1.使用宏定義

      在C語(yǔ)言中,宏是產(chǎn)生內(nèi)嵌代碼的唯一方法。對(duì)于嵌入式系統(tǒng)而言,為了能達(dá)到性能要求,宏是一種很好的代替函數(shù)的方法。

      寫(xiě)一個(gè)“標(biāo)準(zhǔn)”宏MIN,這個(gè)宏輸入兩個(gè)參數(shù)并返回較小的一個(gè):

      錯(cuò)誤做法:

      #define MIN(A,B)(A <= B ? A : B)正確做法:

      #define MIN(A,B)((A)<=(B)?(A):(B))對(duì)于宏,我們需要知道三點(diǎn):(1)宏定義“像”函數(shù);

      (2)宏定義不是函數(shù),因而需要括上所有“參數(shù)”;(3)宏定義可能產(chǎn)生副作用。下面的代碼:

      least = MIN(*p++, b);將被替換為:

      ((*p++)<=(b)?(*p++):(b))發(fā)生的事情無(wú)法預(yù)料。

      因而不要給宏定義傳入有副作用的“參數(shù)”。2.使用寄存器變量

      當(dāng)對(duì)一個(gè)變量頻繁被讀寫(xiě)時(shí),需要反復(fù)訪問(wèn)內(nèi)存,從而花費(fèi)大量的存取時(shí)間。為此,C語(yǔ)言提供了一種變量,即寄存器變量。這種變量存放在CPU的寄存器中,使用時(shí),不需要訪問(wèn)內(nèi)存,而直接從寄存器中讀寫(xiě),從而提高效率。寄存器變量的說(shuō)明符是register。對(duì)于循環(huán)次數(shù)較多的循環(huán)控制變量及循環(huán)體內(nèi)反復(fù)使用的變量均可定義為寄存器變量,而循環(huán)計(jì)數(shù)是應(yīng)用寄存器變量的最好候選者。(1)

      只有局部自動(dòng)變量和形參才可以定義為寄存器變量。因?yàn)榧拇嫫髯兞繉儆趧?dòng)態(tài)存儲(chǔ)方式,凡需要采用靜態(tài)存儲(chǔ)方式的量都不能定義為寄存器變量,包括:模塊間全局變量、模塊內(nèi)全局變量、局部static變量;

      (2)

      register是一個(gè)“建議”型關(guān)鍵字,意指程序建議該變量放在寄存器中,但最終該變量可能因?yàn)闂l件不滿足并未成為寄存器變量,而是被放在了存儲(chǔ)器中,但編譯器中并不報(bào)錯(cuò)(在C++語(yǔ)言中有另一個(gè)“建議”型關(guān)鍵字:inline)。

      下面是一個(gè)采用寄存器變量的例子: /* 求1+2+3+?.+n的值 */ WORD Addition(BYTE n){ register i,s=0;for(i=1;i<=n;i++){ s=s+i;} return s;} 本程序循環(huán)n次,i和s都被頻繁使用,因此可定義為寄存器變量。3.內(nèi)嵌匯編

      程序中對(duì)時(shí)間要求苛刻的部分可以用內(nèi)嵌匯編來(lái)重寫(xiě),以帶來(lái)速度上的顯著提高。但是,開(kāi)發(fā)和測(cè)試匯編代碼是一件辛苦的工作,它將花費(fèi)更長(zhǎng)的時(shí)間,因而要慎重選擇要用匯編的部分。

      在程序中,存在一個(gè)80-20原則,即20%的程序消耗了80%的運(yùn)行時(shí)間,因而我們要改進(jìn)效率,最主要是考慮改進(jìn)那20%的代碼。

      嵌入式C程序中主要使用在線匯編,即在C程序中直接插入_asm{ }內(nèi)嵌匯編語(yǔ)句:

      /* 把兩個(gè)輸入?yún)?shù)的值相加,結(jié)果存放到另外一個(gè)全局變量中 */ int result;

      void Add(long a, long *b)

      {

      _asm

      {

      MOV

      AX, a

      MOV

      BX, b

      ADD

      AX, [BX]

      MOV

      result, AX

      }

      }

      4.利用硬件特性

      首先要明白CPU對(duì)各種存儲(chǔ)器的訪問(wèn)速度,基本上是:

      CPU內(nèi)部RAM > 外部同步RAM > 外部異步RAM > FLASH/ROM 對(duì)于程序代碼,已經(jīng)被燒錄在FLASH或ROM中,我們可以讓CPU直接從其中讀取代碼執(zhí)行,但通常這不是一個(gè)好辦法,我們最好在系統(tǒng)啟動(dòng)后將FLASH或ROM中的目標(biāo)代碼拷貝入RAM中后再執(zhí)行以提高取指令速度; 對(duì)于UART等設(shè)備,其內(nèi)部有一定容量的接收BUFFER,我們應(yīng)盡量在BUFFER被占滿后再向CPU提出中斷。例如計(jì)算機(jī)終端在向目標(biāo)機(jī)通過(guò)RS-232傳遞數(shù)據(jù)時(shí),不宜設(shè)置UART只接收到一個(gè)BYTE就向CPU提中斷,從而無(wú)謂浪費(fèi)中斷處理時(shí)間;

      如果對(duì)某設(shè)備能采取DMA方式讀取,就采用DMA讀取,DMA讀取方式在讀取目標(biāo)中包含的存儲(chǔ)信息較大時(shí)效率較高,其數(shù)據(jù)傳輸?shù)幕締挝皇菈K,而所傳輸?shù)臄?shù)據(jù)是從設(shè)備直接送入內(nèi)存的(或者相反)。DMA方式較之中斷驅(qū)動(dòng)方式,減少了CPU 對(duì)外設(shè)的干預(yù),進(jìn)一步提高了CPU與外設(shè)的并行操作程度。5.活用位操作

      使用C語(yǔ)言的位操作可以減少除法和取模的運(yùn)算。在計(jì)算機(jī)程序中數(shù)據(jù)的位是可以操作的最小數(shù)據(jù)單位,理論上可以用“位運(yùn)算”來(lái)完成所有的運(yùn)算和操作,因而,靈活的位操作可以有效地提高程序運(yùn)行的效率。舉例如下: /* 方法1 */ int i,j;i = 879 / 16;j = 562 % 32;

      /* 方法2 */ int i,j;i = 879 >> 4;j = 562-(562 >> 5 << 5);對(duì)于以2的指數(shù)次方為“*”、“/”或“%”因子的數(shù)學(xué)運(yùn)算,轉(zhuǎn)化為移位運(yùn)算“<< >>”通??梢蕴岣咚惴ㄐ省R?yàn)槌顺\(yùn)算指令周期通常比移位運(yùn)算大。

      C語(yǔ)言位運(yùn)算除了可以提高運(yùn)算效率外,在嵌入式系統(tǒng)的編程中,它的另一個(gè)最典型的應(yīng)用,而且十分廣泛地正在被使用著的是位間的與(&)、或(|)、非(~)操作,這跟嵌入式系統(tǒng)的編程特點(diǎn)有很大關(guān)系。我們通常要對(duì)硬件寄存器進(jìn)行位設(shè)置,譬如,我們通過(guò)將AM186ER型80186處理器的中斷屏蔽控制寄存器的第低6位設(shè)置為0(開(kāi)中斷2),最通用的做法是: #define INT_I2_MASK

      0x0040

      wTemp = inword(INT_MASK);outword(INT_MASK, wTemp &~INT_I2_MASK);而將該位設(shè)置為1的做法是:

      #define INT_I2_MASK

      0x0040

      wTemp = inword(INT_MASK);outword(INT_MASK, wTemp | INT_I2_MASK);判斷該位是否為1的做法是:

      #define INT_I2_MASK

      0x0040

      wTemp = inword(INT_MASK);if(wTemp & INT_I2_MASK){

      ?

      /* 該位為1 */ } 上述方法在嵌入式系統(tǒng)的編程中是非常常見(jiàn)的,我們需要牢固掌握。總結(jié)

      在性能優(yōu)化方面永遠(yuǎn)注意80-20準(zhǔn)備,不要優(yōu)化程序中開(kāi)銷不大的那80%,這是勞而無(wú)功的。

      宏定義是C語(yǔ)言中實(shí)現(xiàn)類似函數(shù)功能而又不具函數(shù)調(diào)用和返回開(kāi)銷的較好方法,但宏在本質(zhì)上不是函數(shù),因而要防止宏展開(kāi)后出現(xiàn)不可預(yù)料的結(jié)果,對(duì)宏的定義和使用要慎而處之。很遺憾,標(biāo)準(zhǔn)C至今沒(méi)有包括C++中inline函數(shù)的功能,inline函數(shù)兼具無(wú)調(diào)用開(kāi)銷和安全的優(yōu)點(diǎn)。

      使用寄存器變量、內(nèi)嵌匯編和活用位操作也是提高程序效率的有效方法。除了編程上的技巧外,為提高系統(tǒng)的運(yùn)行效率,我們通常也需要最大可能地利用各種硬件設(shè)備自身的特點(diǎn)來(lái)減小其運(yùn)轉(zhuǎn)開(kāi)銷,例如減小中斷次數(shù)、利用DMA傳輸方式等。

      下載Java系統(tǒng)程序員修煉之道word格式文檔
      下載Java系統(tǒng)程序員修煉之道.doc
      將本文檔下載到自己電腦,方便修改和收藏,請(qǐng)勿使用迅雷等下載。
      點(diǎn)此處下載文檔

      文檔為doc格式


      聲明:本文內(nèi)容由互聯(lián)網(wǎng)用戶自發(fā)貢獻(xiàn)自行上傳,本網(wǎng)站不擁有所有權(quán),未作人工編輯處理,也不承擔(dān)相關(guān)法律責(zé)任。如果您發(fā)現(xiàn)有涉嫌版權(quán)的內(nèi)容,歡迎發(fā)送郵件至:645879355@qq.com 進(jìn)行舉報(bào),并提供相關(guān)證據(jù),工作人員會(huì)在5個(gè)工作日內(nèi)聯(lián)系你,一經(jīng)查實(shí),本站將立刻刪除涉嫌侵權(quán)內(nèi)容。

      相關(guān)范文推薦

        JAVA程序員面試題

        JAVA程序員面試題 第一,談?wù)刦inal, finally, finalize的區(qū)別。 final?修飾符(關(guān)鍵字)如果一個(gè)類被聲明為final,意味著它不能再派生出新的子類,不能作為父類被繼承。因此一個(gè)類不......

        java程序員(筆試)

        筆試 一. 選擇題 1. 從“員工”表的“姓名”字段中找出名字包含“瑪麗”的人,下面的哪條select語(yǔ)句正確 A. Select*from 員工 where姓名 =“__瑪麗__” B. Select*from 員工 w......

        java程序員面試題

        1、 你怎樣理解Struts,又那些配置文件,以及作用? 理解:http://ruixin.iteye.com/blog/899289 配置文件:struts.xml 作用:struts 框架mvc 實(shí)現(xiàn)低耦合,便于程序的維護(hù)~ 配置文件控制......

        java程序員招聘

        職位描述:1、參加基于 JAVA 技術(shù)的門(mén)戶網(wǎng)站的開(kāi)發(fā); 2、負(fù)責(zé)公司的網(wǎng)站開(kāi)發(fā)維護(hù)及新產(chǎn)品的研發(fā); 3、書(shū)寫(xiě)技術(shù)文檔和制定開(kāi)發(fā)規(guī)范; 4、從系統(tǒng)層面去合理析網(wǎng)站產(chǎn)品,并提供開(kāi)發(fā)工程......

        java程序員之路

        JAVA程序員之路- - 每個(gè)人的學(xué)習(xí)方法是不同的,一個(gè)人的方法不見(jiàn)得適合另一個(gè)人,我只能是談自己的學(xué)習(xí)方法。因?yàn)槲覍W(xué)習(xí)Java是完全自學(xué)的,從來(lái)沒(méi)有問(wèn)過(guò)別人,所以學(xué)習(xí)的過(guò)程基本......

        JAVA程序員求職信

        JAVA程序員求職信范文 尊敬的領(lǐng)導(dǎo): 您好!十分感謝您在百忙之中能翻閱我的自薦信。與公司是一種選擇,與我則是一種機(jī)會(huì)。在上千份大同小異的求職信中,我期望你手中的這份能給您......

        Java程序員簡(jiǎn)歷

        個(gè)人簡(jiǎn)歷 ********************************************************************* 基本信息 ********************************************************************* 姓......

        java程序員面試題

        姓名: 年齡: 工作年限: 1.int和Integer有什么區(qū)別?2.抽象類(abstract class)和接口(interface)有什么異同?3.List、Set、Map的區(qū)別?4.Spring支持的ORM有哪些,哪些是你用過(guò)的?5.使用Spri......