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

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

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

    posts - 122,  comments - 25,  trackbacks - 0
    1、介紹
    通過證書驗證用戶身份(瀏覽器),其核心是利用cookie實現(xiàn)http和https的信息共享(同域名)。如http://test.abc.com/app/index.html 發(fā)現(xiàn)未驗證后,跳轉(zhuǎn)到https://test.abc.com:443/app/checkCrt.html身份驗證,要求出去證書,確認后將身份信息帶入http請求頭部,跳轉(zhuǎn)到原請求頁面(http://test.abc.com/app/index.html ),讀取身份信息后進入頁面(出于安全考慮Cookie需要加密)。

    流程圖

    流程說明:
    登錄流程詳細介紹:
    1). 未登錄用戶訪問頁面 如:http://test.abc.com/app/index.html
    2). 【CertAuthValve】判斷是否訪問受限制資源,如訪問受限制的資源則判斷用戶身份是否已驗證,未驗證則將用戶重定向到身份驗證頁面,原始請求的url做為
    query的一部分,登錄成功后可以跳轉(zhuǎn)回來, 如:https://test.abc.com:443/app/checkCrt.htm?done=/index.html。
    3). 【CertAuthValve】對于https請求,apache讀取請求提供的用戶證書,獲取證書中的郵件地址,并將該信息寫入請求頭中。
    4). 【GetUserInfoValve】讀取請求頭,獲取剛剛設(shè)置的用戶郵件地址信息,進一步獲取用戶的詳細信息,然后將這些信息加密后放入cookie中。
    5). 登錄完成,將用戶外部重定向回原始頁面。
    2、具體實現(xiàn)
    1)、安裝apache、ssh、java、jboss等環(huán)境,略。
    2)、生成服務(wù)證書和服務(wù)密碼
    openssl req -new -x509 -nodes -out /home/admin/app/conf/ssl.crt/server.crt -keyout /home/admin/app/conf/ssl.crt/server.key -days 3600
    因為要和內(nèi)網(wǎng)證書交互,所以需要一個內(nèi)網(wǎng)證書公鑰文件,可以通過以下方式獲取:
    獲取方法:IE->工具->Internet選項->內(nèi)容->證書->受信任的根證書頒發(fā)機構(gòu),找到intranet行,點擊導(dǎo)出,選擇下一步,選擇Base64編碼X.509,將證書文件保存為intranet-ca.crt,拷貝到目錄/home/admin/app/conf/ssl.crt/。
    3)、apache(httpd.conf)配置
    應(yīng)用和身份驗證頁面放在一起,所以需要同時配置兩個虛擬主機,同時監(jiān)聽80(處理http請求)、443(處理https請求)端口。
    #監(jiān)聽端口
    Listen 80
    Listen 443

    #app的虛擬主機配置
    NameVirtualHost *:80
    <VirtualHost *:80>
        ServerAdmin sa@abc.com
        ServerName test.abc.com
        DocumentRoot /home/admin/app/target/app/htdocs/
    </VirtualHost>

    #身份驗證的虛擬主機配置
    NameVirtualHost *:443
    <VirtualHost *:443>
        ServerAdmin sa@abc.com
        ServerName test.abc.com
        DocumentRoot /home/admin/app/target/app/htdocs/
        SSLEngine on
        SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+SSLv3:+EXP:+eNULL

        #該指令為虛擬主機指定證書文件名。
        SSLCertificateFile /home/admin/app/conf/ssl.crt/server.crt

        #該指令為證書指定一個對應(yīng)的私鑰文件
        SSLCertificateKeyFile /home/admin/app/conf/ssl.crt/server.key

        #該指令為指定一個包含Certificate Authority證書的文件
        #證書公鑰
        SSLCACertificateFile /home/admin/app/conf/ssl.crt/intranet-ca.cer
        SSLProxyEngine on
        RewriteEngine on
        #設(shè)置客戶端證書驗證為必須
        SSLVerifyClient require

        #因為一個CA證書能夠被另一個CA證書驗證,所以可以形成一個CA證書鏈.使用該指令可指定服務(wù)器驗證用戶證書時可以查找多少個CA證明。
        #設(shè)置認證深度:一般用默認10。
        SSLVerifyDepth  10

        #把mod_ssl里的變量變?yōu)槿汁h(huán)境的變量
        SSLOptions +StdEnvVars

        #將證書中的郵件地址添加到請求頭中
        RequestHeader unset SSL_CLIENT_S_DN_Email
        RequestHeader add SSL_CLIENT_S_DN_Email %{SSL_CLIENT_S_DN_Email}e
    </VirtualHost>

    4)、代碼片段
            //CertAuthValve.java
            
    //判斷session中是否有用戶郵箱地址
            SessionValue session = SessionHelper.getSessionValue(rundata);
            if (StringUtil.isNotEmpty(session.getCropEmail())) {
                return null;
            }
            
            // 從內(nèi)網(wǎng)證書中獲取用戶郵箱地址: SSL_CLIENT_S_DN_Email
            String cropEmail = rundata.getRequest().getHeader(SSL_CLIENT_HEADER_MAIL);
            if (StringUtil.isNotEmpty(cropEmail)) {
                //將郵箱地址保存到session
                session.setCropEmail(cropEmail);
                SessionHelper.saveSessionValue(rundata, session);
                if (log.isDebugEnabled()) {
                    log.debug("用戶" + session.getCropEmail() + "已經(jīng)通過證書驗證");
                }
                return null;
            }
            
            URIBrokerService uriBrokerService = (URIBrokerService) getWebxComponent().getService(
                    URIBrokerService.SERVICE_NAME);
            URIBroker noPermissionUriBroker = uriBrokerService.getURIBroker(CHECK_CRT_URL);
            //請求的原始URL & 驗證的URL
            String requestPath = rundata.getPathInfo().replace("_", "");
            String checkCrtUrl = (String) noPermissionUriBroker.getPath().get(
                    noPermissionUriBroker.getPath().size() - 1);

            try {
                //原始請求判斷
                if (requestPath.equalsIgnoreCase(checkCrtUrl)) {
                    //當前是https請求,但是依然不能得到證書信息,轉(zhuǎn)到禁止頁面
                    
    //(要將禁止頁面加入到允許訪問的配置文件中,不然會導(dǎo)致循環(huán)重定向)
                    URIBroker uriBroker = uriBrokerService.getURIBroker("forbidden");
                    rundata.setRedirectLocation(uriBroker.render());
                } else {
                    //轉(zhuǎn)到證書驗證頁面
                    rundata.setRedirectLocation(noPermissionUriBroker.render() + "?done=" + rundata.getPathInfo());
                }
            } catch (IOException e) {
                log.error("權(quán)限驗證重定向出錯", e);
            }
            return new BreakPipeline();

            //GetUserInfoValve.java
            Object user = rundata.getSession().getAttribute("userInfo");
            if (user == null) {
                SessionValue session = SessionHelper.getSessionValue(rundata);
                String email = session.getCropEmail();
                Employe employe = PersonInfoUtil.getPersonInfoByEmail(email);

                // 寫入cookie
                session.setEmployeeId(employe.getEmployeId());
                session.setName(employe.getName());
                session.setCropEmail(employe.getEmail());
                SessionHelper.saveSessionValue(rundata, session);
            }

    posted @ 2011-12-09 16:09 josson 閱讀(2441) | 評論 (0)編輯 收藏
    受限于證書的原因,以前經(jīng)常不得已用IE打開一些應(yīng)用。其實有一工具可以幫助我們導(dǎo)出IE證書,用于firefox,解決證書的困惑。

    Jailbreak [https://www.isecpartners.com/application-security-tools/jailbreak.html],win32的一個小軟件,可以幫助我們導(dǎo)出IE證書,使用很簡單。
    1、windows環(huán)境(xp\win7均可),以adminstrator登錄;
    2、下載jailbreak,解包后,運行jailbreak.exe(非jailbreak.msc);
    3、導(dǎo)出證書:Certificates - Current User > 個人 > 證書,選所有任務(wù)導(dǎo)出;


    選擇導(dǎo)出私鑰。
    4、在firefox中導(dǎo)入證書:選項 > 高級 > 查看證書(您的證書) > 導(dǎo)入(剛導(dǎo)出證書文件);

    5、搞定。
    posted @ 2011-12-09 13:54 josson 閱讀(3107) | 評論 (1)編輯 收藏

    互聯(lián)網(wǎng)的產(chǎn)品大都是面向海量用戶的服務(wù),且用戶分布區(qū)域廣泛,其教育水平、習慣也大多不同,具有高度不確定性,我們必須非常關(guān)注用戶的行為和反饋。因而,在互聯(lián)網(wǎng)產(chǎn)品服務(wù)的整個用戶研究,需求分析、產(chǎn)品研發(fā)及交付服務(wù)的過程中,都采用探索式、適應(yīng)性的研發(fā)理念進行產(chǎn)品的研發(fā)。通常,會把整個產(chǎn)品研發(fā)周期劃分為若干個迭代,采用迭代式的演進過程,不斷的去交付新的產(chǎn)品特性,并通過觀察用戶的行為和反饋獲取,進而隨時調(diào)整產(chǎn)品的思路和方向。一切以用戶價值為核心是互聯(lián)網(wǎng)產(chǎn)品最核心的特點,而以價值驅(qū)動的敏捷開發(fā)方法非常符合這一特點。

    一、敏捷項目管理實踐


    從阿里軟件開始,內(nèi)貿(mào)團隊就一直在實行著敏捷項目管理實踐,通過小步快跑,快速迭代、增量交付用戶價值,不斷獲取用戶反饋,持續(xù)、快速的調(diào)整產(chǎn)品,驗證并適合用戶價值。正是通過這些實踐活動,我們以迭代的、增量的交付用戶價值,最大限度的保證產(chǎn)品朝著符合用戶實際需求方向發(fā)展。目前,在內(nèi)貿(mào)團隊應(yīng)用較成熟的敏捷實踐活動有:

    1)、迭代計劃(Sprint Planning Meeting)

    2)、每日晨會(Daily Scrum Meeting) & 任務(wù)墻(Task Wall)

    3)、功能預(yù)演(Spring Review)

    4)、項目總結(jié)(Retrospect Meeting)

    5)、結(jié)對編程(Pair Programming)

    6)、其他技術(shù)實踐活動等

     二、敏捷團隊

    1)、自組織文化

    如google、facebook等互聯(lián)網(wǎng)企業(yè),他們很少甚至沒有特定的項目流程,通常怎么敏捷怎么做,具有濃厚的工程師驅(qū)動文化。我們則有較完整的開發(fā)流程指導(dǎo)和規(guī)范我們的項目研發(fā)工作,相比而言,喪失了一些靈活性和積極性,不利于我們工程師自我管理、自我驅(qū)動意識的培養(yǎng)。臃腫、缺乏靈活性的流程同互聯(lián)網(wǎng)產(chǎn)品快速更新、快速發(fā)展是不相適應(yīng)的,同時也弱化我們的責任心意識。除了遵守詳盡的流程,我們是否可以換個角度、換種方法,提倡和營造一種自我管理、自我驅(qū)動的開發(fā)文化,省卻一些并不能給我們帶來幫助卻影響效率的流程呢?

    敏捷團隊的自組織特性弱化了團隊技術(shù)領(lǐng)導(dǎo)這個角色,強調(diào)自我管理和自我驅(qū)動。雖然這對工程師的素質(zhì)要求更高,相對技術(shù)能力更難提高。但是,團隊導(dǎo)向很重要,我們努力營造這樣的氛圍,從小團隊做起,逐漸鍛煉和培養(yǎng)自組織團隊。相信在這樣的開發(fā)氛圍下,會讓我們做的更高效、更敏捷,可以走的更穩(wěn)、更遠。

    2)、追求一體化

    一體化團隊作為敏捷開發(fā)方法中最具精益思想基因的實踐,是指每個項目團隊包括分析,開發(fā),測試等角色,使團隊滿足一個需求從設(shè)計,開發(fā)到測試各個階段順利完成,達到符合質(zhì)量標準并滿足需求的軟件。這種以項目/產(chǎn)品為單位的虛擬團隊,坐在一起,全身心的為共同的目標而努力,可以更好的凝聚項目組中的各種角色,消除部門墻。 

     3)、追求全功能

    這里所指的全功能是希望項目團隊能打破工程師角色之間的邊界,如研發(fā)、測試和前端工程師的界線,消除開發(fā)、測試流程中一些潛在浪費,提高效率。在項目團隊內(nèi)部通過角色互換,不限角色的結(jié)對工作,加強不同角色,不同模塊間的知識傳遞,打破技術(shù)壁壘,幫助員工從不同視角理解項目,鍛煉技能,進而增加團隊均衡生產(chǎn)的能力。

    為什么要提倡打破邊界?項目整體效率依賴于項目過程中各環(huán)節(jié)的工作效率,而整體效率的優(yōu)化往往依賴于均衡生產(chǎn)(精益思想的按需生產(chǎn)),即消除生產(chǎn)的波峰(過度生產(chǎn))和波谷(生產(chǎn)不足),只有局部效率的增加無法直接轉(zhuǎn)換為整體效率的增加(就象桶能裝多少水,決定于最短的那塊板)。整體效率的優(yōu)化要求IT團隊消除技能壁壘,培養(yǎng)多面手,根據(jù)計劃的的變動,彈性地調(diào)整任務(wù),達到各角色和流程之間的平衡。

    三、質(zhì)量保證

    我們追求開發(fā)效率,同時也注重項目質(zhì)量。如何去保證質(zhì)量?就象美國的一位教授愛德化.戴明(W.Edwards Deming)所說:“我們應(yīng)該停止依靠大量檢驗來保證質(zhì)量,而是要改進工藝流程,從一開始就生產(chǎn)出優(yōu)質(zhì)的產(chǎn)品”。我們要在整個開發(fā)過程中多個環(huán)節(jié)去保證質(zhì)量。同時,質(zhì)量保證是整個團隊的責任,就如同前面所說的追求全功能團隊,打破邊界。

    至于在哪些環(huán)節(jié)采用哪些實踐,我們先做個分類,按是否能被系統(tǒng)用戶感知將質(zhì)量問題區(qū)分內(nèi)部質(zhì)量和外部質(zhì)量。外部質(zhì)量指能直接被系統(tǒng)用戶感知,如運行緩慢,不可操作或是操作復(fù)雜就屬于外部質(zhì)量低劣。而不能直接為系統(tǒng)用戶所直接感知的要素,對產(chǎn)品鍵壯性、可維護性有深遠影響的問題就屬于外部質(zhì)量,如系統(tǒng)設(shè)計的一致性、代碼可讀性、邏輯完整性等。內(nèi)部質(zhì)量對用戶的影響比較間接,但比外部質(zhì)量意義更深遠。一般來說,系統(tǒng)內(nèi)部質(zhì)量優(yōu)秀,外部質(zhì)量仍有可能很差。而內(nèi)部質(zhì)量差的系統(tǒng),外部質(zhì)量肯定也不怎么樣。

    1)、外部質(zhì)量保證

    在外部質(zhì)量保證上,大部分會在開發(fā)后期介入,可以通過性能測試、自動化測試及工程師的功能測試來保證,通過這些實踐活動發(fā)現(xiàn)并保證例如運行緩慢、不可操作等質(zhì)量問題不會存在。針對交互特別復(fù)雜的web應(yīng)用,可以更多的考慮采用webui自動化測試工具,如selenium、pwaitr(b2b)、automan(淘寶)等,可以很好的完成那些簡單、重復(fù)的TC用例,可以大大提高測試效率,解決測試工程師的資源瓶頸。

    2)、內(nèi)部質(zhì)量保證

    相對于外部質(zhì)量,內(nèi)部質(zhì)量問題影響更為深遠,在開發(fā)開始階段就應(yīng)該去保證。如通過單元測試、靜態(tài)代碼掃描(PMD\findbugs)、持續(xù)集成、重構(gòu)、結(jié)對編程、code review等多種實踐活動來保證項目代碼的健康。

    除了一些實踐活動去檢查代碼質(zhì)量外,更為重要的是研發(fā)工程師對內(nèi)部質(zhì)量的重視,如果工程師沒有形成良好的質(zhì)量意識,很可能這些實踐也只是停留于形式,并不能帶來較好的結(jié)果。如我們在開發(fā)過程中的編碼規(guī)范、單元測試的質(zhì)量及覆蓋率,code review的及時性及問題是否持續(xù)跟進等等。此外,有選擇的采用結(jié)對編程實踐,有助于質(zhì)量的提高。

    本文以敏捷、精益(消除浪費、按需生產(chǎn))思想的角度試圖去探討一種適合互聯(lián)網(wǎng)公司的產(chǎn)品開發(fā)體系,上述概要的介紹了項目管理、團隊、質(zhì)量方面的一些敏捷實踐活動,主要涉及了我們對敏捷方面的經(jīng)驗分享或者是些正在研究探討的課題。文中涉及的實踐活動,后續(xù)我將逐一展開詳細介紹,幫助大家更好的理解和認識。希望本文的分享能成為一個引子,引起大家對敏捷開發(fā)的思考和討論,或者更好的了解敏捷和精益思想。
    posted @ 2011-06-13 15:53 josson 閱讀(524) | 評論 (0)編輯 收藏

    以下為本人在公司內(nèi)部關(guān)于項目質(zhì)量和工作效率郵件回復(fù)的一此意見和想法。

    1、 談流程

    不可否認流程的重要性,但我們需要根據(jù)具合格情況分析,不斷的梳理和優(yōu)化我們的流程,讓流程更好的指導(dǎo)我們工作,而不是束縛。目前,我們的流程慢慢多了起來,感覺不如以前敏捷了。經(jīng)過rpm改造后,無論在測試環(huán)節(jié)還是發(fā)布階段,較之前失去了很大的靈活性。測試階段,開發(fā)bugfix后想在測試環(huán)境驗證,每次必須重走aone的流程及打包布署,相比之前的build效率真的差了好多。當然,也許是我們項目組對這個流程熟練度、方法還不夠,很多環(huán)節(jié)有待改進。

    發(fā)布階段,目前統(tǒng)一由SCM來發(fā)布,必然會導(dǎo)致開發(fā)對線上環(huán)境及發(fā)流程更加陌生,同我們提倡的打破邊界,敏捷響應(yīng)有些相背。再者,SCM資源有限的原因,要支持ITU眾多產(chǎn)品線,能否應(yīng)付的過來,始終是個問題。發(fā)布統(tǒng)一管理有好處,同樣也帶來了弊端,ITU不同于網(wǎng)站,大多數(shù)的技術(shù)團隊共同在維護在幾個應(yīng)用,而itu的應(yīng)用多、規(guī)模相對小、環(huán)境各異,這樣的產(chǎn)品線采用統(tǒng)一管理性價比不高。希望相應(yīng)的owner,能不定期的搜集各產(chǎn)品線的意見和反饋,不斷的優(yōu)化,讓我們的流程更合理。

    2、 談自測

    我們團隊一直在強調(diào)自測意識,也在這方面不斷的總結(jié)和改進。我覺的要提高自測,首先應(yīng)讓每位開發(fā)同學形成較好的自測意識,而不是自上而下的命令式管理,只有自己有這方面的意,才會去思考、去想辦法,去實踐。再者,需要PM或技術(shù)經(jīng)理去思考,目前階段實行自測會有什么困難,如沒有系統(tǒng)的自測方法、時間不充足(需要熟悉下階段的UC、下迭代的設(shè)計、單元測試補寫等),找到這些困難或問題,就容易對癥下藥了。最后,不斷總結(jié)和積累自測方式,優(yōu)化項目流程。自測不是一種形式,而要追求效果,開發(fā)自測同樣需要計劃和方法,所以我們需要向QA同學請教,總結(jié)過去 bug常犯的錯誤,整理自己的check項。相信通過這樣的一些自測方法,能真正提高我們的項目質(zhì)量,打破同QA的界線,我們的開發(fā)、測試資源比例可以得到更大的優(yōu)化,將以前開發(fā)階段緊,測試階段松的狀況加以改善,使整個項目過程中的緊張度趨于平緩。

    3、 談故障分

    “盡量不要讓故障分成為大家包袱,可以考慮被實施產(chǎn)品對事故級和A類才對個人計故障分,B和C類故障分記在主管頭上!”,個人也比較支持駱駝的觀點。目前大家對線上故障都小心翼翼,大家對質(zhì)量的意識很高,這當然是好事,但同時帶來的影響是效率低了。我的觀點是,作為增值服務(wù)的互聯(lián)網(wǎng)產(chǎn)品,我們更需要快速迭代增量提供用戶價值,盡快獲取用戶反饋并改善產(chǎn)品,產(chǎn)品推出的遲早,不僅影響獲得回報的時間,還影響到獲得價值的多少,錯過了一個時間窗口,產(chǎn)品可能就不再有任何價值。所以,我們需要找到一個平衡量點,可接受的質(zhì)量狀況達到最大的效率。

    從客戶第一角度談質(zhì)量,某些時候,客戶可以接受服務(wù)偶而不可用重啟下,卻不能接受產(chǎn)品沒價值、交互性太差,操作太復(fù)雜。所以,對于客戶來說什么對他們更重要,就需要我們每個人去分析和評估。所以,我們一味只注重質(zhì)量,而忽略客戶真實需求,那就太悲哀。我的觀點是,case by case,帶著這樣的觀點去思考和解決問題。

    4、談敏捷項目團隊

    從打破邊界,我想到了一體化的敏捷項目管理團隊,一個目標一致、自我管理的團隊,應(yīng)該具備良好的目標意識和執(zhí)行力,不僅能管好自己的一畝三分地,同時也能站在項目、團隊的角度看待問題。PD出現(xiàn)了問題,開發(fā)積極去彌補;開發(fā)出現(xiàn)了問題,QA積極去彌補,項目團隊的目標非常一致。每位項目組成員一定要把好每一關(guān),萬不可把問題向下拋,因為還有開發(fā)或QA會把關(guān),所以差不多就行了,這樣往往就是災(zāi)難的開始。

    posted @ 2011-05-20 16:39 josson 閱讀(480) | 評論 (0)編輯 收藏
    2010已成為歷史,記憶里2010年變化很多、做的很多、收獲也很多。2010是個轉(zhuǎn)型期、創(chuàng)業(yè)期,從年初開始,就在新的Marking中努力耕耘。前半年,以新產(chǎn)品研發(fā)為主;后半年,結(jié)合客戶使用產(chǎn)品后的反饋,不斷的優(yōu)化和改進產(chǎn)品功能,努力提升產(chǎn)品價值和用戶體驗。通過大家的努力,幾款新產(chǎn)品還是彼受用戶歡迎的,最欣喜的是我們提前完成了2010年的KPI目標。

    過去的一年,有著太多的痛苦和艱辛,為了新產(chǎn)品的上線,晚上、周未都沒了,唯一想的和做的就是確保產(chǎn)品如期上線。過程雖然很艱苦,但大家都努力堅持,齊心協(xié)力,確保任務(wù)如期完成,我們保持了一貫的說到做到、如期交付的作風。因為這樣的磨練,我和我們的團隊得到了更多成長。困難并不可怕,熬過去,明天的太陽會更加燦爛。

    1、談?wù)劤砷L和不足:

    1)、職業(yè)轉(zhuǎn)型,開發(fā)到管理
    雖然Team Leader已經(jīng)做了幾年了,但一直停留在項目上,多為管事不管人,對細節(jié)問題關(guān)注較多,所以之前談不上管理,只能算是積累些項目管理經(jīng)驗。經(jīng)過這一年的學習和發(fā)展,有了更多的管理意識,逐漸關(guān)注團隊建設(shè)、團隊成長,注意給小組成員更多的機會和空間,讓他們得到鍛煉和成長,承擔更多團隊或項目中的重要事項,而他們通過完成這些重要任務(wù),不僅得到了磨練,同時在團隊中建立了自己的影響力。
    放在以前,我會認為有風險,或者自己做更快,更省事,或最有把握的人去。現(xiàn)在想來,以前認識太膚淺了,我們需要的團隊戰(zhàn)斗力,而不是個別人的能力,若平常不注重團隊成員的培養(yǎng),團隊的戰(zhàn)斗力永遠不行,承擔不了關(guān)鍵任務(wù)。
    談到成長和培養(yǎng),團隊需要什么樣的人呢?作為互聯(lián)網(wǎng)企業(yè),同一般軟件企業(yè)不同,產(chǎn)品在推出之前,誰也無法肯定是否會受用戶歡迎,只能快速推出,讓市場來驗證,不斷的改進和適應(yīng)用戶的需要。因而,需要我們技術(shù)人員也具備技術(shù)判斷力,改變命令式管理體制下的工作習慣,充分發(fā)揮主觀能動性和創(chuàng)新意識,共同做好產(chǎn)品。

    2)、學會擁抱變化;
    2010年變化很多,有些也許對個人、團隊沒有影響或影響很小,有些直接關(guān)系自己或團隊,如團隊的核心成員不斷的被抽調(diào)、人員調(diào)整、KPI的271考評等,每次的變化都會帶來不同的問題。持續(xù)輸血,新人補允,使團隊戰(zhàn)斗力大打折扣,很長一段時間非常的糾結(jié)和無耐。事情總是具有兩面性,往好處看,這對我、對團隊也未必是件壞事,沒有經(jīng)驗過挫折和磨練,又怎能成佛呢?既然是組織需要或Boss的決定,那就多些理解和支持,支持和協(xié)助上級完成也是每個下屬的職責;況且,某些變化至少對于一些同學也是件好事,他們有更多的機會和更大的平臺去一展才華。

    大概人都是喜歡按習慣辦事的緣故,每每有變化都覺的很痛苦。我覺的如何擁抱變化關(guān)鍵在于心態(tài),我們需要理性看待變化,多往積極的方向思考,不僅更容易調(diào)整好心態(tài),而且可以在變化中吸取經(jīng)驗和教訓(xùn),鞭策我們成長。

    3)、提升項目管理能力
    雖然在項目管理知識上沒有太多的時間和精力去系統(tǒng)的學習,但通過不斷實踐和總結(jié),還是有了不少的積累和沉淀,對項目管理有了更多的理解和把握,對敏捷項目管理也有不同的認識,結(jié)合團隊自身尋找適合我們的實踐方式。在項目管理方面,還有很多需要去提升和學習,2011年希望安排更多的時間系統(tǒng)的學習項目管理知識及敏捷項目管理,并結(jié)合實際應(yīng)用到工作中。

    4)、提升向上溝通力
    在擁抱變化的同時,同樣需要理性的分析和積極的向上溝通。在過去,雖然會盡可能的去表達和反饋自己的想法和意見,但我重新審視下,總覺得表達還不夠明確或不是那么的到位,或許在表達時還有更好的方式,至少還有提升的必要。向上溝通也是門學問,需要好好研究下。

    5)、提升團隊建設(shè)和輔導(dǎo)能力
    相對來說,過去的一年所有的同學都會關(guān)注到,但領(lǐng)悟能力和基礎(chǔ)較好的同學成長更快,基礎(chǔ)稍弱的沒有太大變化。顯然,平常輔導(dǎo)工作沒有做好或做到位,關(guān)注程度不夠。越是基礎(chǔ)差些的同學需要關(guān)注和幫助的點越多,需要幫助他們找到不足和問題所在,一起找改進辦法,并給予必要的督促和檢查,養(yǎng)成好的學習習慣,促進成長。2011年,這方面需要做的還有更多。

    2、談?wù)?011年的期望
    1)、團隊
    解決目前團隊新人多,有效資源少的問題;積極關(guān)注和幫助新人溶入團隊,熟悉業(yè)務(wù),以減少對項目開展的影響;
    抓好梯隊建設(shè),關(guān)注和輔導(dǎo)基礎(chǔ)較差同學的,共同制定改進計劃和Action,做好必要的監(jiān)督和指導(dǎo),促進成長;
    2)、能力
    系統(tǒng)學習項目管理和敏捷軟件開發(fā)方面的知識,并應(yīng)用到項目管理實踐中;同時積極參與相關(guān)方面的分享和討論。
    3)、影響
    推動興趣小組活動的開展,借開發(fā)工具的發(fā)展和分享,建立團隊在部門或技術(shù)部的影響;
    鼓勵團隊成員積極參與技術(shù)部的公共事務(wù),提升影響力。

    給力2010,加油2011!!!


    posted @ 2011-02-02 21:46 josson 閱讀(312) | 評論 (0)編輯 收藏
    1、什么是iteration和release?
    iteration和release是兩個不同的概念,但在敏捷實踐活動中,我們往往認識的比較模糊,一個Iteration就是一次release,其實不然。那么,具體有什么區(qū)別和聯(lián)系呢?
    Iteration(迭代):在固定的周期內(nèi),經(jīng)過需求分析、設(shè)計、實現(xiàn)、測試等活動,完成計劃的的業(yè)務(wù)需求,迭代結(jié)束提供一個可工作的產(chǎn)品。計劃的業(yè)務(wù)需求,可能是一個完整的User Story,也可能是一個Story中的若干task。
    Release(發(fā)布):經(jīng)過一個或若干個iteration后,完成計劃中的所有User Story,經(jīng)過測試后才release,最終真正交付給客戶使用。
    在我們的實踐活動中,一個User Story所需的工作量超過我們的有效資源,無法安排在一個iteration內(nèi)。我們就會想當然的會去延長迭代周期,增加有效資源以適應(yīng)所需工作量。殊不知,這更象是形式上的迭代開發(fā),無異于瀑布式項目開發(fā)過程。

    2、建立固定的迭代周期,保持穩(wěn)定的開發(fā)節(jié)奏
    Scurm方法也非常強調(diào)穩(wěn)定的迭代節(jié)奏,一個穩(wěn)定的迭代節(jié)奏就如同項目的的心跳。Simon Baker描述說:"就像心臟有規(guī)律地跳動來保持身體運行,固定的迭代長度提供了一個恒量,有助于建立開發(fā)和交付的節(jié)奏。根據(jù)我的經(jīng)驗,節(jié)奏是幫助取得不變的步幅的重要因素"(2004)。對于敏捷開發(fā)的團隊而言,穩(wěn)定的迭代節(jié)奏可以讓產(chǎn)品保持更穩(wěn)定的交付。

    3、如何保持穩(wěn)定的開發(fā)節(jié)奏?
    當一個迭代期內(nèi)可提供的有效資源無法實現(xiàn)一個User Story時,我們?nèi)绾伟磁拍兀?在 談迭代周期控制的困惑 中已談到,這里不在細述。

    4、如何選擇適合自己團隊的迭代周期?
    一般需要考慮以下因素:
    1)、整個項目周期長度(完成計劃的商業(yè)需求所需時間)
    較短的迭代周期將會有以下一些好處:更頻繁的向客戶展示/交付可用的軟件;更頻繁的度量開發(fā)進度;更頻繁的取得反饋并改進;一般大的項目最好有多次(3次或以上)獲取反饋、修正的機會,根據(jù)項目周期調(diào)整迭代周期長度。
    2)、不確定性的多少
    不確定性有多種形式,客戶到底想要的是什么?小組的工作效率,時間?技術(shù)門檻等都不存在不確定性,不確定性越多,迭代就應(yīng)該越短。
    3)、獲得反饋的難易程度
    指小組獲取反饋數(shù)量、頻度和及時性,視所處的環(huán)境不同,選擇合適的迭代長度;
    4)、優(yōu)先級要以多久保持不變
    開發(fā)小組承諾在一次迭代中完成一組特定的功能,重要的是不要改變他們的目標方向,
    優(yōu)先級不會被改變的時間長度是選擇迭代長度時需要考慮的因素。
    5)、迭代的系統(tǒng)開銷
    每次迭代的成本(時間),如迭代中進行的完整回歸測試。最佳迭代周期的目標之一就是減少或近似消除每次迭代的系統(tǒng)開銷。如每次回歸時間成本很高,那決定周期長度時更傾向于長一些。
    6)、團隊成員的緊迫感
    Niels Malotaux指出:"只要項目的結(jié)束日期還在遙遠的將來,我們就不會感到任何壓力,并從容不迫的工作。當結(jié)束日期逼近時,我們才會開始更努力的工作"。意思指項目開始大家比較放松,而越臨近結(jié)束,工作越忙壓力越大。因此,選擇一個合適的迭代周期長度,讓團隊成員在整個迭代過程中感受到的壓力更平均,不是給團隊更多的壓力,而是壓力總量平均分布在迭代過程中。

    每個團隊根據(jù)所在環(huán)境和條件確定一個合適的迭代長度,一般建議2~4周。在我們的實踐中,以2周一次迭代的頻率,保持相對穩(wěn)定的開發(fā)和交付的節(jié)奏。

    5、參考資料:
    《敏捷估計與規(guī)劃》 Mike Cohn
    posted @ 2011-01-31 14:26 josson 閱讀(3418) | 評論 (0)編輯 收藏
    敏捷宣言中說到:"最好的架構(gòu)、需求和設(shè)計來自于自組織的團隊"。在自組織團隊中,我們每個人既是團隊/項目的管理者,又是執(zhí)行者,要取得優(yōu)異的結(jié)果,必須加強自我管理。

    如何做好自我管理呢?

    1、平和的心態(tài):我們會不斷的遇到各類或好事或壞事、或成功或挫折,什么樣的心態(tài)去對待決定了我們成長的方向及高度,"態(tài)度決定一切"。
    2、目標感:大到個人職業(yè)規(guī)劃,小到每件事的期望,對于目標(期望)的制定和管理,都需要我們認真的去對待;
    3、執(zhí)行力:目標是方向,不能執(zhí)行就不會有結(jié)果,好的執(zhí)行力是優(yōu)秀個人或團隊的必要條件。
    4、時間管理:工作需要區(qū)分輕重緩急,不能對事情沒有計劃和按排,對事需要分析重要性和緊急程度,分別對待;
    5、學習能力:"學歷代表過去,能力代表現(xiàn)在,學習能力代表將來。",一個人的學習能力決定他將來的成績;

    任何人都不希望自己被人管著,但要想不被人管只有一種辦法:時時嚴格要求自己,主動、出色的完成每項工作,努力學習,與團隊共成長。
    posted @ 2011-01-28 18:56 josson 閱讀(271) | 評論 (0)編輯 收藏
    昨日PM小組例會,談到了需求評估工作量遠大于有效資源情況下,如何保證迭代周期穩(wěn)定的問題。討論的內(nèi)容,對于PM如何控制、保持迭代周期穩(wěn)定有較大的參考價值。

      有效資源 評估工作量
    1
    2
    3 相同 相同
    注:
    有效資源:指迭代周期內(nèi),開發(fā)團隊所能提供的有效工作日,單位人/天。
    評估工作量:指迭代周期內(nèi),產(chǎn)品經(jīng)理提供需要實現(xiàn)的業(yè)務(wù)需求所評估的工作量之和。

    上表描述以固定周期為兩周的迭代中,可能會出現(xiàn)的有效資源和評估工作量對比情況。其中,1、3兩種情況因為評估工作量小于或等同能提供的有效資源,所以不會影響迭代周期。重點需討論的是有效資源小于評估工作量時,如何保持固定周期?

    例舉:一迭代周期,能提供有效資源20人/天,需求評估工作量30人/天。
    1、功能較獨立,需求不能拆分發(fā)布;
    安排一個release,兩個iterative。這種情況需要在迭代2中附加一些技術(shù)改造或低優(yōu)先級的小需求、bugfix,release日期相對會慢幾天。

    2、一個迭代中包括多個產(chǎn)品的需求(需要各位產(chǎn)品經(jīng)理協(xié)商,決定需求優(yōu)先級);
    a)、以保證質(zhì)量為重:
    忽略商業(yè)優(yōu)先級,先處理一個迭代中就能全部完成的需求。

    b)、保證價值
    分兩個迭代完成,一次release。

    通常情況下,我們盡力保證迭代周期的穩(wěn)定,但也允許例外,如:商業(yè)需求,產(chǎn)品上確定了發(fā)布時間點,或者節(jié)假期間團隊請假比較多,一個迭代所能提供的有效資源相對比較少的情況。

    保持迭代周期穩(wěn)定,其核心是:固定Timebox和可提供的資源,讓產(chǎn)品經(jīng)理來決定需求的優(yōu)先級,每迭代只接納(開發(fā)/QA資源)可承受的需求。
    posted @ 2011-01-13 15:31 josson 閱讀(1024) | 評論 (0)編輯 收藏
    對于互聯(lián)網(wǎng)行業(yè)來說,快速推出產(chǎn)品占領(lǐng)市場、快速檢驗產(chǎn)品的價值和方向性、快速調(diào)整及優(yōu)化是極期重要的。因此,采用小步快跑、持續(xù)迭代的敏捷實踐一種不錯的項目管理方法。我們團隊在敏捷項目管理方面持續(xù)開展了二年多時間,在scrum、xp等敏捷最佳實踐的基礎(chǔ)上,結(jié)合團隊自身的基礎(chǔ)和條件,不斷的償試和優(yōu)化,總結(jié)和積累了一些經(jīng)驗。目前,這些敏捷項目管理實踐在項目組開展情況良好,得到了大多數(shù)團隊成員的認同,特別是業(yè)務(wù)方、QA等合作方的認可。


    上圖描述了一個基本項目迭代流程,其中涉及三個角色,其職責同等于Scrum中的Product Owner、Scrum Master、Scrum Team。迭代流程中分別包含了以下敏捷實踐:
    1)、迭代計劃會議,按商業(yè)優(yōu)先級篩選需求列表,確定本項目需求范圍;
    2)、確認本次迭代需求、資源、時間的具體情況;
    3)、簡單設(shè)計,對關(guān)鍵技術(shù)點進行必要的設(shè)計;
    4)、晨會;
    5)、結(jié)對編程;
    6)、持續(xù)集成;
    7)、showcase;
    8)、項目總結(jié)會;
    9)、新迭代的開始... ...

    以上具體實踐活動內(nèi)容及組織形式,后續(xù)將逐一介紹,敬請關(guān)注。
    posted @ 2010-12-16 15:57 josson 閱讀(344) | 評論 (0)編輯 收藏

    1、什么是java序列化

    Java 序列化 API 提供一種處理對象序列化的標準機制。序列化Serialization是指將java對象用一連串字節(jié)描述的一個過程;反序列化deserialization是一種將這一串字節(jié)構(gòu)建成一個對象的過程。


    2、序列化的作用(必要性)

    Java中,一切都是對象,在分布式環(huán)境中經(jīng)常需要將對象從這一端網(wǎng)絡(luò)或設(shè)備傳遞到另一端。Java 序列化機制就是一種解決在網(wǎng)絡(luò)兩端傳輸數(shù)據(jù)的問題而產(chǎn)生的協(xié)議。下圖表示客戶端/服務(wù)器之間通信,一個對象是從客戶端傳送到服務(wù)器通過序列化的視圖。


    3、如何序列化一個對象

    為序列化一個對象,你需確保對象類實現(xiàn)Serializable接口。Serializable接口沒有方法,只要實現(xiàn)了序列化接口,Class 就能被序列化機制處理。

    示例代碼,需序列化的java對象:

    1 import java.io.Serializable;
    2 
    3 public class TestClassSerial implements Serializable  {
    4     public byte version = 100;
    5     public byte count = 0;  
    6 }

    示例代碼,TestClassSerial對照象輸出成 Byte 流,存儲到 temp.out 文件里:
     1     public static void main(String args[]) throws IOException {
     2         FileOutputStream fos = null;
     3         ObjectOutputStream oos = null;
     4         try {
     5             fos = new FileOutputStream("c:/temp.out");
     6             oos = new ObjectOutputStream(fos);
     7             TestClassSerial tcs = new TestClassSerial();
     8             oos.writeObject(tcs);
     9             oos.flush();
    10         }
    11         finally {
    12             if(oos != null) {
    13                 oos.close();
    14             }
    15             if(fos != null) {
    16                 fos.close();
    17             }
    18         }
    19     }

    示例代碼,從持久的文件中讀取 Bytes 重建對象
     1     public static void main1(String args[]) throws IOException {
     2         FileInputStream fis = null
     3         ObjectInputStream oin = null;
     4         try {
     5             fis = new FileInputStream("c:/temp.out");
     6             oin = new ObjectInputStream(fis);
     7             TestClassSerial tcs = (TestClassSerial) oin.readObject();
     8             System.out.println("version="+tcs.version);
     9         }
    10         finally {
    11             if(fis != null) {
    12                 fis.close();
    13             }
    14             if(oin != null) {
    15                 oin.close();
    16             }
    17         }
    18     }

    執(zhí)行結(jié)果為:100.


    4、對象的序列化格式

    TestClassSerial對象序列化輸出的 temp.out 文件,以 16 進制方式顯示,內(nèi)容如下:

    AC ED 00 05 73 72 00 0A 53 65 72 69 61 6C 54 65
    73 74 A0 0C 34 00 FE B1 DD F9 02 00 02 42 00 05
    63 6F 75 6E 74 42 00 07 76 65 72 73 69 6F 6E 78
    70 00 64

    這些二進制字節(jié)就是用來描述序列化以后的TestClassSerial對象的,我們注意到 TestSerial 類中只有兩個域:

    1 public  byte version = 100;
    2 public byte count = 0;

    都是 byte 型,理論上存儲這兩個域只需要 2 byte ,但是實際上 temp.out 占據(jù)空間為 51bytes ,也就是說除了數(shù)據(jù)以外,還包括了對序列化對象的其他描述。


    5、Java 的序列化算法

    序列化算法一般會按步驟做如下事情:

    1、將對象實例相關(guān)的類的元數(shù)據(jù)輸出;
    2、
    遞歸地輸出類的超類元數(shù)據(jù)描述直到不再有超類;
    3、
    類元數(shù)據(jù)完了以后,開始從最頂層的超類開始輸出對象實例的實際數(shù)據(jù)值;
    4、
    從上至下遞歸輸出實例的數(shù)據(jù);


    更多序例化事例及二進制字節(jié)含義參考文檔:http://my.oschina.net/god/blog/1291

    posted @ 2010-12-16 14:52 josson 閱讀(816) | 評論 (0)編輯 收藏
    1、員工激勵
    通過各種外部或內(nèi)部的刺激,以激發(fā)員工的需要、動機、欲望,調(diào)動人的工作積極性,充分挖掘潛力,全力達到預(yù)期目標的過程。

    2、激勵形式、方法:
    廣義的分物質(zhì)激勵和精神激勵(職務(wù)、榮譽、目標、信任、情感等)。

    3、原則:
    1)、精神激勵為主;
    2)、只激勵該激勵的人;
    3)、只激勵該激勵的事;
    4)、激勵方法、手段因人而異,把握按需激勵;
    5)、鼓勵公開競爭、和諧競爭;

    4、案例:
    1)、壓力非常大的時候,采用激勵手段 -- 目標激勵
    2)、當前員工不開心,采用的手段 -- 先溝通,明確原因
    3)、表現(xiàn)好的員工 -- 信任激勵,肯定
    4)、推行新方法 -- 目標激勵,競賽

    5、附:
    馬斯洛需求層次理論(Maslow's hierarchy of needs),亦稱“基本需求層次理論”,是行為科學的理論之一,由美國心理學家亞伯拉罕·馬斯洛于1943年在《人類激勵理論》論文中所提出。



    安全、生理需要屬于物質(zhì)性價值需求;社會需要、尊重需要、自我實現(xiàn)屬于精神價值需求;

    posted @ 2010-12-09 16:17 josson 閱讀(377) | 評論 (0)編輯 收藏
    解決沖突的法則
    1. 在不了解對方動機之前千萬不要表明自己的立場
    2. 準確把握自己的需求底線
    3. 解決沖突的最好辦法是談判
    決策的法則
    1. 首先,以事實而后數(shù)據(jù)為依據(jù),如果沒有,
    2. 以嚴密的邏輯推理為依據(jù),如果沒有,
    3. 以民主評議,如果沒有,
    4. 以最終負責人來決斷
    獎懲制度
    1. 在構(gòu)建獎勵制度的同時不要忘記處罰制度的建設(shè)
    2. 物質(zhì)與非物質(zhì)的獎勵(以非物質(zhì)的獎勵)
    3. 側(cè)重獎勵行為還是結(jié)果?

    表揚要及時(3天為限)、有理有據(jù)、真誠。
    表揚是最不花錢最辭舊的激勵手段,表揚是為下一個成功設(shè)立起點。
    不要過度的物質(zhì)獎勵,在這種方式的激勵下,員工永遠得不到激勵。
    要注重精神上的獎勵,只有精神是永存的。

    posted @ 2010-11-24 10:31 josson 閱讀(365) | 評論 (0)編輯 收藏
    垃圾收集的目的在于清除不再使用的對象,釋放那些不再使用的對象所占用的內(nèi)存。GC兩種常用的方法是引用計數(shù)和對象引用遍歷,早期的jvm使用引用計數(shù),現(xiàn)在大多數(shù)jvm采用對象引用遍歷。

    1、對象引用計數(shù):
    當應(yīng)用程序創(chuàng)建引用以及引用超出作用域(范圍)時,jvm必須適當增減引用數(shù)。當某對象的引用數(shù)為0時,對象便可以進行垃圾收集。

    2、對象引用遍歷:
    (1)、標記(marking)對象:從一組對象開始,沿著整個對象圖上的引用鏈,遞歸確定可到達的對象,GC將標記這些可到達的對象。如果某對象不能從這些根對象的一個(至少一個)到達,則表示它可被收集。

    (2)、清除(sweeping)對象:GC刪除不可到達的對象,刪除時,有些GC只是簡單的掃描堆棧,刪除未標記的對象,并釋放它們的內(nèi)存以生成新的對象。這種方法的問題在于內(nèi)存會分成好多小段,而它們不足以用于新的對象,但是組合起來卻很大。因此,許多gc可以重新組織內(nèi)存中的對象,并進行壓縮(compact),形成可利用的空間。
    posted @ 2010-09-25 12:13 josson| 編輯 收藏
    不一定要將所有的真話講出來,但你講的每一句真話必須是真話。(white lie)
    posted @ 2010-07-28 14:37 josson 閱讀(248) | 評論 (0)編輯 收藏

    最近一個項目主要涉及前端的交互優(yōu)化,由于UED資源不足,所以一起做了一些前端的工作,

    由于各瀏覽器的標準不一樣,如要兼容像ie6,7,8firefox,樣式調(diào)整比較費事,現(xiàn)在css相關(guān)

    的一些技巧分享一下,希望對大家有所幫助。

     

    1、什么是css hack.

    針對不同的瀏覽器去寫不同的CSS,讓它能夠同時兼容不同的瀏覽器,能在不同的瀏覽器中也

    能得到我們想要的頁面效果,這種針對不同的瀏覽器寫不同的CSS code的過程,稱之為CSS hack

     

    通過下表中的hack code就可以實現(xiàn)不同版本ie瀏覽器間的兼容:

    hack code

    ie6

    ie7

    firefox

    _

    ×

    ×

    *

    ×

    !import

    ×

    ‘_’ : 只有ie6能識別_ie7,8”width:100px; “的樣式是OK,但ie6不夠?qū)挄r,可以在”width:100px”后面增加一段”_width:105px;” 那么ie7,8不會解析_width:105px,但ie6會執(zhí)行。

    ‘*’ : ie6,7都能識別*,但firefox不能識別;

    ‘!import’ : ie 6不能識別,ie7ie8都能識別;

     

    2css調(diào)試工具

    (1). ie8的調(diào)試工具,ie8下按F12能呼出開發(fā)人員開發(fā)工具,如下圖:

    選中圖中的箭頭鼠標按鈕,在瀏覽器中選中需要優(yōu)化的HTML對象,HTML窗口就會

    定位到選中HTML對象的代碼上(如上圖左),則右窗口中則顯示當前對象的所有樣式,

    通過對右窗口中的樣式調(diào)整,達到預(yù)期效果后,找到css文件的class,并作相同修

    改。通過這個工具,修改樣式后所見即所得,確定樣式后再修改樣式文件。

     

    (2). Firebugfirefox下可以通過Firebug工具,來定位HTML對象并調(diào)試該對象的樣式,如下圖:

     

    posted @ 2010-06-29 11:03 josson 閱讀(2194) | 評論 (0)編輯 收藏
    事件 解說
    一般事件 onclick 鼠標點擊時觸發(fā)此事件
    ondblclick 鼠標雙擊時觸發(fā)此事件
    onmousedown 按下鼠標時觸發(fā)此事件
    onmouseup 鼠標按下后松開鼠標時觸發(fā)此事件
    onmouseover 當鼠標移動到某對象范圍的上方時觸發(fā)此事件
    onmousemove 鼠標移動時觸發(fā)此事件
    onmouseout 當鼠標離開某對象范圍時觸發(fā)此事件
    onkeypress 當鍵盤上的某個鍵被按下并且釋放時觸發(fā)此事件.
    onkeydown 當鍵盤上某個按鍵被按下時觸發(fā)此事件
    onkeyup 當鍵盤上某個按鍵被按放開時觸發(fā)此事件
    頁面相關(guān)事件 onabort 圖片在下載時被用戶中斷
    onbeforeunload 當前頁面的內(nèi)容將要被改變時觸發(fā)此事件
    onerror 出現(xiàn)錯誤時觸發(fā)此事件
    onload 頁面內(nèi)容完成時觸發(fā)此事件
    onmove 瀏覽器的窗口被移動時觸發(fā)此事件
    onresize 當瀏覽器的窗口大小被改變時觸發(fā)此事件
    onscroll 瀏覽器的滾動條位置發(fā)生變化時觸發(fā)此事件
    onstop 瀏覽器的停止按鈕被按下時觸發(fā)此事件或者正在下載的文件被中斷
    oncontextmenu 當彈出右鍵上下文菜單時發(fā)生
    onunload 當前頁面將被改變時觸發(fā)此事件
    表單相關(guān)事件 onblur 當前元素失去焦點時觸發(fā)此事件
    onchange 當前元素失去焦點并且元素的內(nèi)容發(fā)生改變而觸發(fā)此事件
    onfocus 當某個元素獲得焦點時觸發(fā)此事件
    onreset 當表單中RESET的屬性被激發(fā)時觸發(fā)此事件
    onsubmit 一個表單被遞交時觸發(fā)此事件
    posted @ 2010-04-11 13:05 josson 閱讀(154) | 評論 (0)編輯 收藏
    1、讓用戶隨時了解系統(tǒng)的狀態(tài);
    2、系統(tǒng)應(yīng)與真實世界相符合;
    3、給予用戶控制權(quán)和自主權(quán);
    4、提倡一致性和標準化;
    5、幫助用戶識別、診斷和修復(fù)錯誤;
    6、預(yù)防錯誤;
    7、依賴識別而不是記憶;
    8、強調(diào)使用的靈活性及有效性;
    9、最小化設(shè)計;
    10、提供幫助及文檔;
    posted @ 2010-04-11 13:05 josson 閱讀(204) | 評論 (0)編輯 收藏
    1、新建 archetype 項目(模板項目):
    mvn archetype:genera -DgroupId=org.simple -DartifactId=simple -DarchetypeArtifactId=maven-archetype-archetype
    2、修改主要模板文件:archetype-resources/pom.xml
    1)修改 META-INF/maven/archetype.xml 中相關(guān)的 sources
    2)安裝此項目:mvn install
    3、根據(jù)模板項目創(chuàng)建新項目:
    mvn archetype:generate
    -DarchetypeGroupId=org.simple\
    -DarchetypeArtifactId= simple \
    -DarchetypeVersion=1.0-SNAPSHOT

    【安裝私有庫】
    1、復(fù)制 mylib-1.2.3.jar 到本地代碼庫
    2、編寫 mylib-1.2.3.pom 文件:
    <project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.mylib</groupId>
    <artifactId>mylib</artifactId>
    <version>1.2.3</version>
    </project>
    如果有依賴關(guān)系,可以將依賴關(guān)系描述在 pom 中
    3、用Ant 來生成 jar 包和 pom 文件的 checksum 文件:
    build.xml:
    <project default="checksum">
    <target name="checksum">
    <checksum file="mylib-1.2.3.jar" algorithm="SHA" fileext=".sha1"/>
    <checksum file="mylib-1.2.3.pom" algorithm="SHA" fileext=".sha1"/>
    </target>
    </project>
    4、生成 mylib-1.2.3.jar.sha1 和 mylib-1.2.3.pom.sha1 文件
    ant build.xml
    【使用版本控制】
    提交:mvn scm:checkin -Dmessage="Message"
    檢出:mvn scm:checkout
    更新:mvn scm:update
    posted @ 2010-04-11 13:02 josson 閱讀(874) | 評論 (0)編輯 收藏
    作為一名開發(fā)者,通常會忽視系統(tǒng)可用性及用戶體驗。但系統(tǒng)的可用性和用戶體驗對于一個真正優(yōu)秀的Web-based系統(tǒng)卻至關(guān)重要,因此,我們有必要花一些時間來了解和學習一下。

    一、相關(guān)的概念:

    用戶體驗,user experience(或稱ux/ue),指用戶訪問或使用一個產(chǎn)品/服務(wù)時的全部感受。具有主觀性,不同的用戶本身的知識、愛好、價值觀等會有不同的結(jié)果,因人而異。

    可用性,指產(chǎn)品是否易學、使用是否有效果,以及通用性是否良好等。衡量一個產(chǎn)品的可用性,可以通過一些具體目標來評判,相對用戶體驗而言,比較客觀。考察產(chǎn)品可用性的目標可分為:
    1、可行性,指產(chǎn)品使用的效果;
    2、有效性,產(chǎn)品使用的工作效率;
    3、安全性,指產(chǎn)品能否安全的使用,或稱為容錯性;
    4、通用性,指產(chǎn)品是否具備良好的通用性;
    5、易學性,指產(chǎn)品的是否容易上手,易操作;
    6、易記性,指產(chǎn)品的操作方法簡單,易記性;

    二、開發(fā)人員的特點
    作為一名開發(fā)者,通常會對目標用戶的判斷有較大的偏差,往往高估實際用戶的操作能力和理解能力,忽視產(chǎn)品的易學性和易操作性。再者,作為技術(shù)人員,開發(fā)工作者通常重視功能實現(xiàn),忽視產(chǎn)品界面、視覺外觀,不重視用戶體驗。

    三、一些案例
    1、iPhone的成功
    iPhone的成功,產(chǎn)品的可用度及用戶體驗有者至關(guān)重要的作用。其產(chǎn)品的很多細節(jié),都凝聚著apple公司的創(chuàng)新。如3.5吋屏幕上觸摸輸入,比較費輕且易出錯,但iphone在輸入過程中,會放大選中的字符,便于用戶確認,同時,作一些輸入校驗,進行容錯處理,避免用戶輸入錯誤字符引起的麻煩。

    2、在線訂票、論壇注冊
    再如個在線訂票系統(tǒng),用戶興沖沖的跑上來想體驗一把,千辛萬苦輸入一大段信息,終于注冊成功,想下單的時候,即發(fā)現(xiàn)自己有的銀行卡不支持,試想此時用戶的心情會多么的糟糕。試想一下,如果在用戶注冊前,提示系統(tǒng)當前支持的銀行卡的話,用戶可以第一時間選擇其他的方式來實現(xiàn)自己的目的。

    再談?wù)搲臅T管理機制,網(wǎng)上這種案例也很多。用戶費了好大的勁完成注冊后,即告知新注冊用戶不能立即發(fā)言,很可能這個用戶就這樣失去了。

    所以要做好一個產(chǎn)品,需要每位項目成員的投入,從用戶角度出度,解決用戶的實際問題。

    posted @ 2009-11-18 11:32 josson 閱讀(333) | 評論 (0)編輯 收藏

    Codereivew是開發(fā)團隊中經(jīng)常采用的,為提高代碼質(zhì)量、提高編碼規(guī)范的一種手段。針對實際工作組織review過程中的一些想法、見解,作一下總結(jié)。

    關(guān)于CodeReview的幾點作用:

    1、提高團隊的編碼規(guī)范,培養(yǎng)良好的coding風格
    旨在提高整個團隊的編碼規(guī)范程度,統(tǒng)一編碼風格。通過每次的codereivew,發(fā)現(xiàn)團隊成員在實際開發(fā)中的一些細節(jié)問題,如不良的編碼習慣、錯誤的調(diào)用方式等。通過多次的發(fā)現(xiàn)、解決問題,使大家都養(yǎng)成良好的編碼習慣。review的內(nèi)容一般包括:
    1)、異常、日志的處理;
    2)、常量的定義及使用;
    3)、字符串處理、BigDecimal.ZERO等;
    4)、代碼的封裝,提高重用性;
    5)、代碼注釋情況;
    6)、javascript文件的抽取情況;

    2、檢查業(yè)務(wù)邏輯
    對項目實現(xiàn)的功能邏輯進行一次reivew,結(jié)合眾人發(fā)散思維,檢查業(yè)務(wù)邏輯是否有盲點或錯誤。通常需要參與review的成員能夠靜下心來深入地認真分析,比較耗費時間。

    3、分享和培訓(xùn)
    每個項目的工作安排相對來說都是比較緊湊的,所以每個團隊成員在完成自己的開發(fā)任務(wù)完,沒有太多的時間去了解或熟悉其他成員的功能實現(xiàn)。但對于敏捷開發(fā)來說,每個功能模塊的開發(fā)者并不是固定的,根據(jù)項目需要,很有可能由非原開發(fā)人員來完成增值功能或重構(gòu),所以codereivew是一次不錯的培訓(xùn)及分享機會,特別是對功能相對復(fù)雜的需求實現(xiàn)。可以讓團隊成員了解或熟悉基本的設(shè)計思想和相關(guān)的類定義,確保在今后接手這一塊工作時,可以更快的上手或找到最到最合適的人去了解更深層的邏輯。

    關(guān)于reivew的方式:

    1、集體review;
    項目成員一起參與codereive,成本比較大,一般一個項目組織一次。比較適合開發(fā)經(jīng)驗分享,以及新功能的實現(xiàn)介紹,利于其他成員了解、熟悉實現(xiàn)者的設(shè)計思路及代碼結(jié)構(gòu),在后續(xù)項目接手這些新功能時,更加從容。

    2、TM組織若干開發(fā)經(jīng)驗豐富的一起review;

    3、分組、交叉review;
    具有較好的靈活性,根據(jù)情況隨時找相關(guān)人員一起對已實現(xiàn)的代碼進行review,及時發(fā)現(xiàn)過程中問題并予以修正。比較適合分組\抱團開發(fā),以2-3人為單位,對具體的功能模塊負責,一起分析、設(shè)計、編碼,每位成員對于功能邏輯都比較邏輯,對業(yè)務(wù)邏輯reivew有比較好的效果。

    實際工作中,根據(jù)實際情況靈活選擇合適的review方式,不應(yīng)拘于某種形式。review過程,應(yīng)有明確的目的,具有針對性,而不是停留于表面,避免逐漸成為一種負擔,流于形式。另外,應(yīng)對每次review結(jié)果,整理出一份問題列表,進行分析和總結(jié),避免相同問題的重復(fù)出現(xiàn)。同時,也應(yīng)按排相關(guān)人員跟進并解決問題。總之,通過codereivew這一手段,盡可能的在提交測試之前去發(fā)現(xiàn)代碼中存在的一些實際問題,從項目經(jīng)歷中得到成長。

    posted @ 2009-09-20 16:50 josson 閱讀(421) | 評論 (0)編輯 收藏
    因項目需要,實現(xiàn)系統(tǒng)對IE8的支持,安裝了ie8版本。安裝完后,發(fā)現(xiàn)一個奇怪問題,打開一個窗口(window.open方式)后,再打開時,新窗口的頁面顯示空白,無法加載其內(nèi)容。關(guān)閉ie后,重新償亦是如此,第一次能打開,第二次就不行。無論是ie7模式,還是兼容模式。

    網(wǎng)上搜了很多內(nèi)容,都沒有找相應(yīng)的解決方案。后來償試了一下,ie設(shè)置重置(工具-Internet選項-高級-重置),刪除所有個性化設(shè)置,完成后,重試后該問題不再出現(xiàn),窗口能正常打開。回想,可能是裝完ie后,ie設(shè)置向?qū)е凶隽四承┎划數(shù)脑O(shè)置有關(guān),但具體是哪項尚不得而知。



    posted @ 2009-09-12 15:01 josson 閱讀(4054) | 評論 (2)編輯 收藏

    在原網(wǎng)頁窗口高度根據(jù)內(nèi)容自適應(yīng)的基礎(chǔ)上,做了一些調(diào)整:
    1、解決窗口底部靠近任務(wù)欄時,window.resizeBy 不能調(diào)整窗口高度問題;
    1、增加寬度自適功能(注:只針對寬度不足,進行擴展的情況;無法調(diào)整窗口寬度比實際內(nèi)容寬的情況)

    Ext.util.ResizeWin = function() {
        
    try {
            
    var sh = document.documentElement.scrollHeight
                
    || document.body.scrollHeight;
            
    var ch = document.documentElement.clientHeight
                
    || document.body.clientHeight;
            
    var sw = document.documentElement.scrollWidth
                
    || document.body.scrollWidth
            
    var cw = document.documentElement.clientWidth
                
    || document.body.scrollWidth;
            
            
    var xHeight = 55;//任務(wù)欄高度(double).
            var statHeigth = 30;//狀態(tài)欄高度
            var maxHeight = window.screen.height - xHeight; //最大可顯示網(wǎng)頁高度
            var wHeight = window.screenTop + sh + statHeigth;
            if(wHeight > maxHeight){
                
    //窗口位置過底時,向上移動若干象素,使窗口狀態(tài)欄在任務(wù)欄上面.
                var newTop = (window.screenTop - xHeight) + (maxHeight - wHeight);
                
    if(newTop < 0) newTop = 0;
                window.moveTo(window.screenLeft, newTop);
            }
            
    //寬度調(diào)整時,實際內(nèi)容不夠?qū)捒梢赃m用,過寬無法調(diào)整.
            window.resizeBy((sw-cw),(sh-ch));
        }
    catch (e){}
    };

    以下從網(wǎng)上收集的一些相關(guān)資料:

    1、關(guān)于網(wǎng)頁窗口高、寬示意圖:



    2、更多屬性:

    網(wǎng)頁可見區(qū)域?qū)挘篸ocument.body.clientWidth
    網(wǎng)頁可見區(qū)域高:document.body.clientHeight
    網(wǎng)頁可見區(qū)域?qū)挘篸ocument.body.offsetWidth (包括邊線的寬)
    網(wǎng)頁可見區(qū)域高:document.body.offsetHeight (包括邊線的寬)
    網(wǎng)頁正文全文寬:document.body.scrollWidth
    網(wǎng)頁正文全文高:document.body.scrollHeight
    網(wǎng)頁被卷去的高:document.body.scrollTop
    網(wǎng)頁被卷去的左:document.body.scrollLeft
    網(wǎng)頁正文部分上:window.screenTop
    網(wǎng)頁正文部分左:window.screenLeft
    屏幕分辨率的高:window.screen.height
    屏幕分辨率的寬:window.screen.width
    屏幕可用工作區(qū)高度:window.screen.availHeight
    屏幕可用工作區(qū)寬度:window.screen.availWidth

    HTML精確定位:scrollLeft,scrollWidth,clientWidth,offsetWidth
    scrollHeight: 獲取對象的滾動高度。
    scrollLeft:設(shè)置或獲取位于對象左邊界和窗口中目前可見內(nèi)容的最左端之間的距離
    scrollTop:設(shè)置或獲取位于對象最頂端和窗口中可見內(nèi)容的最頂端之間的距離
    scrollWidth:獲取對象的滾動寬度
    offsetHeight:獲取對象相對于版面或由父坐標 offsetParent 屬性指定的父坐標的高度
    offsetLeft:獲取對象相對于版面或由 offsetParent 屬性指定的父坐標的計算左側(cè)位置
    offsetTop:獲取對象相對于版面或由 offsetTop 屬性指定的父坐標的計算頂端位置
    event.clientX 相對文檔的水平座標
    event.clientY 相對文檔的垂直座標
    event.offsetX 相對容器的水平坐標
    event.offsetY 相對容器的垂直坐標
    document.documentElement.scrollTop 垂直方向滾動的值
    event.clientX+document.documentElement.scrollTop 相對文檔的水平座標+垂直方向滾動的量

    IE,F(xiàn)ireFox 差異如下:
    IE6.0、FF1.06+:
    clientWidth = width + padding
    clientHeight = height + padding
    offsetWidth = width + padding + border
    offsetHeight = height + padding + border

    IE5.0/5.5:
    clientWidth = width - border
    clientHeight = height - border
    offsetWidth = width
    offsetHeight = height

    (需要提一下:CSS中的margin屬性,與clientWidth、offsetWidth、clientHeight、offsetHeight均無關(guān))

    網(wǎng)頁可見區(qū)域?qū)挘?document.body.clientWidth
    網(wǎng)頁可見區(qū)域高: document.body.clientHeight
    網(wǎng)頁可見區(qū)域?qū)挘?document.body.offsetWidth (包括邊線的寬)
    網(wǎng)頁可見區(qū)域高: document.body.offsetHeight (包括邊線的高)
    網(wǎng)頁正文全文寬: document.body.scrollWidth
    網(wǎng)頁正文全文高: document.body.scrollHeight
    網(wǎng)頁被卷去的高: document.body.scrollTop
    網(wǎng)頁被卷去的左: document.body.scrollLeft
    網(wǎng)頁正文部分上: window.screenTop
    網(wǎng)頁正文部分左: window.screenLeft
    屏幕分辨率的高: window.screen.height
    屏幕分辨率的寬: window.screen.width
    屏幕可用工作區(qū)高度: window.screen.availHeight
    屏幕可用工作區(qū)寬度: window.screen.availWidt


    posted @ 2009-09-05 18:15 josson 閱讀(444) | 評論 (0)編輯 收藏
    1、ssh 登錄linux時,報: ssh_exchange_identification: Connection closed by remote host

    google了好一陣,才找到線索。主要由于我前晚寫shell腳本調(diào)試的時候,誤將一些系統(tǒng)文件的宿主為新用戶了。后來新的會話怎么都登錄不上去了,好在還有一個root登錄的會話,找到/var/empty/sshd,修改宿主及權(quán)限。
    chown -R root:root /var/empty/sshd
    chmod 
    700 /var/empty/sshd

    2、su 切換用戶,輸入密碼總是提示:密碼不正確。

    也是權(quán)限問題,root切到其他賬號時沒有問題;其他賬號之間切換就是不行,密碼輸入也正確。后來其到/bin/su 文件的權(quán)限不正確,調(diào)整如下解決問題:
    -rwsr-xr-x  1 root root 61144 Jul 30  2007 /bin/su

    posted @ 2009-08-13 18:34 josson 閱讀(197) | 評論 (0)編輯 收藏
    一般業(yè)務(wù)系統(tǒng)中總會存在一些基礎(chǔ)數(shù)據(jù),在其他的業(yè)務(wù)單據(jù)中會被套引用。因此,系統(tǒng)必須保證這些被業(yè)務(wù)單據(jù)引用的基礎(chǔ)數(shù)據(jù)不能任意的刪除。最常見的做法就是,在刪除基礎(chǔ)數(shù)據(jù)時,預(yù)先校驗該類數(shù)據(jù)是否在相關(guān)業(yè)務(wù)表中存在,若不存在才允許用戶刪除,否則給用戶以提示。

    但這樣的處理方法,有些缺點,就是需要編碼對每個業(yè)務(wù)類提供查詢方法,或在刪除邏輯中增加判斷邏輯。因此,每次引用關(guān)系變化,增加或減少時免不了要修改原來的邏輯,時間越長,系統(tǒng)的維護成本就越來越高了。因此,有必要對系統(tǒng)進行重構(gòu),將這類的處理邏輯進行抽象,單獨封裝成一個服務(wù),當引用關(guān)系有變更時,不用再修改原有邏輯,通過配置就可以完成變更。

    通用引用關(guān)系查詢服務(wù),主要就是通過db表或xml配置文件,對系統(tǒng)中每個基礎(chǔ)數(shù)據(jù)有引用的所有關(guān)系進行定義,定義屬性主要是引用的表及字段名稱。查詢時,從配置文件中讀取指定類別的引用關(guān)系,并逐一查詢這些表中的記錄,以確定數(shù)據(jù)是否被引用。這種處理方法的優(yōu)點為,易擴展、可維護性強,引用關(guān)系變更時,僅通過維護配置文件,不必進行編碼,就能實現(xiàn),這樣能大大的提高系統(tǒng)的穩(wěn)定性。

    xml配置文件如下:
    <rule bizName='product' desc="產(chǎn)品關(guān)聯(lián)項定義">
        
    <item>
            
    <refTable>sale_item</refTable>
            
    <refField>product_id</refField>
            <!-- 用于查詢條件的擴展,允許為空 -->
            <extCondition>CORP_ID = #corpId#</extCondition>
        
    </item>
        
    <item>
            
    <refTable>sale_order_item</refTable>
            
    <refField>product_id</refField>
            
    <extCondition>CORP_ID = #corpId#</extCondition>
        
    </item>
    </rule>
    <rule bizName='customer' desc="客戶關(guān)聯(lián)項定義">
        
    <item>
            
    <refTable>sale_order</refTable>
            
    <refField>cust_id</refField>
            
    <extCondition>CORP_ID = #corpId#</extCondition>
        
    </item>
        
    <item>
            
    <refTable>sale_bill</refTable>
            
    <refField>cust_id</refField>
            
    <extCondition></extCondition>
        
    </item>
        ... ...

    </rule>

    通用業(yè)務(wù)引用查詢類代碼片段如下:
    public class BizReferenceService implements IBizReferenceService {

        
    private static Map<String,List<BizReferenceRule>> ruleMaps;
        
        
    private static final String PATTERN = "#[\\w]+#";
        
    private static final String CFG_FILE = "bizReferenceRule.xml";
        ... ...

      
        
    /**
         * 查詢指定業(yè)務(wù)數(shù)據(jù)是否被其他業(yè)務(wù)表關(guān)聯(lián)依賴.
         * 
    @param bizName 關(guān)聯(lián)業(yè)務(wù)名稱
         * 
    @param bizId 關(guān)聯(lián)業(yè)務(wù)ID.
         * 
    @param extParam 擴展條件
         * 
    @return true 被關(guān)聯(lián)/false 未被關(guān)聯(lián).
         
    */
        
    public boolean isBizReference(String bizName,String bizId,Map<String,Object>extParam) throws ServiceException {
            Assert.notNull(bizName, 
    "業(yè)務(wù)名稱不能為空,bizName is NULL。");
            Assert.notNull(bizId, 
    "記錄ID不能為空,bizId is NULL。");

            
    try {
                
    //逐個檢查依賴項是否有數(shù)據(jù)關(guān)聯(lián).
                List<BizReferenceRule> rules = getBizRelationRule(bizName);
                
    for(BizReferenceRule rule : rules){
                    StringBuilder sqlBuilder 
    = new StringBuilder();
                    sqlBuilder.append(
    "select count(*) from ").append(rule.getRelTable()).append(" where ")
                        .append(rule.getRelField()).append(
    "='").append(bizId).append("");
                    String extConditon 
    = rule.getExtCondition();
                    
    if(StringUtil.isNotBlank(extConditon)){
                        initTenantParam(extParam);
                        sqlBuilder.append(
    " and ").append(getExtParamSql(extConditon,extParam));
                    }
                    logger.debug(sqlBuilder);
                    
    int nCount = bizReferenceDao.getBizRelationCount(sqlBuilder.toString());
                    
    if (nCount != 0return true;
                }
                
    return false;
            }
            
    catch(Exception ex){
                logger.error(
    "調(diào)用業(yè)務(wù)關(guān)聯(lián)服務(wù)錯誤。"+bizName+",bizId:"+bizId+",extParam"+LogUtil.parserBean(extParam),ex);
                
    throw new ServiceException("調(diào)用業(yè)務(wù)關(guān)聯(lián)服務(wù)錯誤。");
            }
        }
        
        
    /**
         * 組裝擴展查詢條件的sql
         * 
    @param condition
         * 
    @param extParam
         * 
    @return
         * 
    @throws Exception
         
    */
        
    private String getExtParamSql(String condition,Map<String,Object>extParam) throws Exception {
            List
    <String> paramList = parseDyncParam(condition);
            
    for(String param : paramList){
                String simpleParam 
    = simpleName(param);
                
    if(!extParam.containsKey(simpleParam)){
                    
    throw new ServiceException("動態(tài)參數(shù)值未設(shè)置! param:"+param+",extParam:"+LogUtil.parserBean(extParam));
                }
                condition 
    = condition.replaceAll(param, "'"+String.valueOf(extParam.get(simpleParam))+"'");
            }
            
    return condition;
        }
        
        
    /**
         * 解析擴展查詢條件中的動態(tài)參數(shù)名.
         * 
    @param condition
         * 
    @return
         * 
    @throws Exception
         
    */
        
    private List<String> parseDyncParam(String condition) throws Exception {
            PatternCompiler compiler 
    = new Perl5Compiler();
            PatternMatcher matcher 
    = new Perl5Matcher();
            MatchResult result 
    = null;
            PatternMatcherInput input 
    = null;
            List
    <String> paramList = new ArrayList<String>();
            input 
    = new PatternMatcherInput(condition);
            Pattern pattern 
    = compiler.compile(PATTERN,Perl5Compiler.CASE_INSENSITIVE_MASK);
            
    while (matcher.contains(input, pattern)){
                result 
    = matcher.getMatch();
                input.setBeginOffset(result.length());
                paramList.add(result.group(
    0));
            }
            
    return paramList;
        }
        
        
    /**
         * 獲取業(yè)務(wù)關(guān)聯(lián)查詢規(guī)則.
         
    */
        
    private List<BizReferenceRule> getBizRelationRule(String bizName){
            Assert.notNull(bizName, 
    "業(yè)務(wù)名稱不能為空,bizName is NULL。");
            
            
    //配置定義未加載到內(nèi)存時,讀取配置文件
            if(ruleMaps == null){
                parseRuleConfig();
                
    if(ruleMaps == nullreturn null;
            }
            
            
    return ruleMaps.get(bizName);
        }
        
        
    /**
         * 讀取業(yè)務(wù)關(guān)聯(lián)規(guī)則配置文件
         
    */
        @SuppressWarnings(
    "unchecked")
        
    private synchronized void parseRuleConfig(){
            
    if(ruleMaps != null){
                
    return;
            }
            
            
    //解析業(yè)務(wù)引用定義文件.
             
        }
        
        
    /**
         * 讀取Xml文檔
         * 
    @return
         
    */
        
    private Document getXmlDocument(){
            InputStream is 
    = null;
            
    try {
                ClassLoader loader 
    = Thread.currentThread().getContextClassLoader();
                is 
    = loader.getResourceAsStream(CFG_FILE);
                SAXBuilder sb 
    = new SAXBuilder();
                
    return sb.build(new BufferedInputStream(is));
            }
            
    catch(Exception ex) {
                logger.error(
    "讀取配置文件錯誤. file:"+CFG_FILE, ex);
                
    return null;
            }
            
    finally {
                
    try {
                    
    if(is != null){
                        is.close();
                        is 
    = null;
                    }
                }
                
    catch(Exception ex) {
                    logger.error(ex);
                }
            }
        }

         
    }

    其他的一些可選處理方法:
    b. 在客戶表增加引用計數(shù)字段;
    需額外維護引用計數(shù)字段,在引用的業(yè)務(wù)邏輯增加或刪除記錄時,需對該字段的數(shù)值進行更新。適用于需要直接查詢記錄被引用次數(shù)的場景,但在集群環(huán)境下,需注意并發(fā)問題。
    posted @ 2009-07-14 14:42 josson 閱讀(385) | 評論 (0)編輯 收藏
    關(guān)于瀏覽器的clientHeight、offsetHeight和scrollHeight

    在IE、FireFox、Netscape等不同的瀏覽器里,對于document.body 的 clientHeight、offsetHeight 和 scrollHeight 有著不同的含義,比較容易搞混,現(xiàn)整理一下相關(guān)的內(nèi)容:

    clientHeight:在上述瀏覽器中, clientHeight 的含義是一致的,定義為網(wǎng)頁內(nèi)容可視區(qū)域的高度,即在瀏覽器中可以看到網(wǎng)頁內(nèi)容的高度,通常是工具條以下到狀態(tài)欄以上的整個區(qū)域高度,與具體的網(wǎng)頁頁面內(nèi)容無關(guān)。可以理解為,在屏幕上通過瀏覽器窗口所能看到網(wǎng)頁內(nèi)容的高度。

    offsetHeight:關(guān)于offsetHeight,ie和firefox等不同瀏覽中意義有所不同,需要加以區(qū)別。在ie中,offsetHeight 的取值為 clientHeight加上滾動條及邊框的高度;而firefox、netscape中,其取值為是實際網(wǎng)頁內(nèi)容的高度,可能會小于clientHeight。

    scrollHeight:scrollHeight都表示瀏覽器中網(wǎng)頁內(nèi)容的高度,但稍有區(qū)別。在ie里為實際網(wǎng)頁內(nèi)容的高度,可以小于 clientHeight;在firefox 中為網(wǎng)頁內(nèi)容高度,最小值等于 clientHeight,即網(wǎng)頁實際內(nèi)容比clientHeight時,取clientHeight。

    clientWidth、offsetWidth 和 scrollWidth 的含義與上述內(nèi)容雷同,不過是高度變成寬度而已。

    若希望clientHeight、offsetHeight和scrollHeight三個屬性能取值一致的話,可以通過設(shè)置DOCTYPE,啟用不同的解析器,如:<!DOCTYPE HTML PUBLIC "DTD XHTML 1.0 Transitional">,設(shè)置DOCTYPE后,這三個屬性都表示實際網(wǎng)頁內(nèi)容的高度。

    通過以下HTML代碼,可以了解一下這三個屬性的含義:
    <!DOCTYPE HTML PUBLIC "DTD XHTML 1.0 Transitional"> //設(shè)置DOCTYPE
    <HTML>
     
    <HEAD>
      
    <TITLE> 測試。 </TITLE>
     
    </HEAD>
      
    <script type='text/javascript'>
      window.onload 
    = function(){
        
    var ch = document.body.clientHeight;
        
    var sh = document.body.offsetHeight;
        
    var ssh = document.body.scrollHeight;
        alert('clientHeight:'
    +ch+'; offsetHeight:'+sh+"; scrollHeight:"+ssh);
      }
      
    </script>
     
    <BODY style='margin:0px'>
      
    <div style='background-color:#ccc; height:400px; padding:0px'>
         text
      
    </div>
     
    </BODY>
    </HTML>

    根據(jù)頁面內(nèi)容調(diào)整窗口高度的方法:
    Ext.util.ResizeWin = function() {
        
    try {
            
    var sh = document.documentElement.scrollHeight
                
    || document.body.scrollHeight;
            
    var ch = document.documentElement.clientHeight
                
    || document.body.clientHeight;
            window.resizeBy(
    0,(sh-ch));
        }
    catch (e){}
    };

    posted @ 2009-06-14 16:48 josson 閱讀(1495) | 評論 (0)編輯 收藏
    我們通常依賴單元測試工具Luntbuild,來發(fā)現(xiàn)代碼中有許多隱藏的錯誤或不良的編碼,然后再去修正。這樣從發(fā)現(xiàn)問題,到解決問題花費很多功夫。其實我們可以利用一些java代碼分析工具,來及時發(fā)現(xiàn)相關(guān)的問題。如findbugs,luntbuild就是集成了findbugs插件來發(fā)現(xiàn)一些代碼上的問題。

    findbugs 當前版本為:1.3.9,其下載地址如下(包括eclipse插件):
    findbugs :http://findbugs.sourceforge.net/index.html
    findbugs for eclipse : http://findbugs.sourceforge.net/downloads.html
    documents: http://findbugs.sourceforge.net/manual/

    插件安裝比較簡單,將findbugs for eclipse 插件文件(zip)下載后,直接解壓至$eclipse.home$/plugins/目錄下,重啟eclipse即可使用。你可以通過查看:(eclipse 3.4) about ecliplse platform -> plug-ins details 中找到findbugs 插件安裝信息。

    Findbugs 的使用:
    在Package Explorer或Navigator視圖中,選中你的Java項目,右鍵,可以看到“Find Bugs”菜單項,子菜單項里有“Find Bugs”和“Clear Bug Markers”等項。點擊Find Bugs 后,開始分析項目中隱藏的代碼問題,發(fā)現(xiàn)的問題會在相應(yīng)的代碼行上進行標記,或者在Bug Explorer中顯示所有的問題(findbug視圖,window -> show view -> others 可以找到Bug Explorer.) 我們就可以根據(jù)findbugs發(fā)現(xiàn)的問題,進行逐一解決,提高代碼質(zhì)量。

    Findbugs 的一些配置說明:
    FindBugs是一個基于“Bug Patterns”進行分析并找出Java程序中隱藏的Bugs。打開 Window -> preferences ,對findbugs 的分析規(guī)則進行定義,如圖:



    posted @ 2009-06-13 23:55 josson 閱讀(1239) | 評論 (0)編輯 收藏
    http://java.decompiler.free.fr/

    一個不錯的java反編譯工具,有g(shù)ui及eclipse插件。
    posted @ 2009-05-21 08:34 josson 閱讀(241) | 評論 (0)編輯 收藏
    <2009年5月>
    262728293012
    3456789
    10111213141516
    17181920212223
    24252627282930
    31123456

    常用鏈接

    留言簿(3)

    隨筆分類

    隨筆檔案

    收藏夾

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 无码中文字幕av免费放| 免费看又爽又黄禁片视频1000| 午夜电影免费观看| 亚洲一区二区三区自拍公司| 亚洲伊人色一综合网| 成在线人直播免费视频| 永久在线免费观看| 免费看男女下面日出水视频| 亚洲精品视频在线| 免费国产黄网站在线看| 久久九九兔免费精品6| 亚洲国产aⅴ综合网| 91嫩草亚洲精品| 中国一级特黄高清免费的大片中国一级黄色片| www视频免费看| 伊人久久大香线蕉亚洲| 精品国产日韩久久亚洲| 国产一级片免费看| www.亚洲色图| 亚洲色大成网站www永久网站| a毛片免费观看完整| 成人免费无遮挡无码黄漫视频| 久久精品国产亚洲AV麻豆~| 日本亚洲中午字幕乱码| 亚欧免费视频一区二区三区| 国产亚洲精品高清在线| 亚洲爆乳大丰满无码专区| 18禁成人网站免费观看| 亚洲中文字幕无码爆乳AV| 亚洲AV无码专区在线电影成人 | 日日操夜夜操免费视频| 久久亚洲日韩看片无码| 国产精品免费久久久久久久久| 免费无码看av的网站| 亚洲精品视频在线观看视频| 97国免费在线视频| 亚洲精品国产综合久久一线| 亚洲日韩国产欧美一区二区三区 | 美女被吸屁股免费网站| 在线观看免费高清视频| 91亚洲一区二区在线观看不卡|