qileilove

          blog已經轉移至github,大家請訪問 http://qaseven.github.io/

          TP配置apache下Rewrite模式

           httpd.conf配置文件中加載了mod_rewrite.so模塊
            AllowOverride None 將None改為 All
            把下面的內容保存為.htaccess文件放到應用入口文件的同級目錄下
          <IfModule mod_rewrite.c>
          RewriteEngine on
          RewriteCond %{REQUEST_FILENAME} !-d
          RewriteCond %{REQUEST_FILENAME} !-f
          RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]
          </IfModule>
            特別應該注意第二點,如果配置了虛擬目錄,則虛擬目錄也需要做同樣修改,否則無法使用

          posted @ 2014-11-04 10:17 順其自然EVO 閱讀(1305) | 評論 (0)編輯 收藏

          UNIX標準化及實現之功能測試宏

          在頭文件中定義了很多POSIX.1和XSI的符號。但是除了POSIX.1和XSI的定義之外,大多數實現在這些頭文件中也加上了它們自己的定義。如果在編譯一個程序時,希望它只使用POSIX定義而不使用任何實現自己定義的限制,那么就需要定義常量_POSIX_C_SOURCE。所有POSIX.1頭文件中都使用此常量。當定義該常量時,就能排除任何實現專有的定義。
            注:POSIX.1標準的以前版本都定義了_POSIX_SOURCE常量。在POSIX.1的2001版中,它被替換為_POSIX_C_SOURCE。
            常量_POSIX_C_SOURCE及_XOPEN_SOURCE被稱為功能測試宏(feature test macro)。所有功能測試宏都以下劃線開始。當要使用它們時,通常在cc命令行中以下列方式定義:
            cc -D_POSIX_C_SOURCE=200112 file.c
            這使得C程序包括任何頭文件之前,定義了功能測試宏。如果我們僅想使用POSIX.1定義,那么也可將源文件的第一行設置為:
            #define _POSIX_C_SOURCE 200112
            為使Single UNIX Specification v3的功能可由應用程序使用,需將常量_XOPEN_SOURCE定義為600。
            Single UNIX Specification將c99實用程序定義為C編譯環境的接口。隨之,就可以用如下方式編譯文件:
            c99 -D_XOPEN_SOURCE=600 file.c -o file
            為了在gcc C編譯器中啟用1999 ISO C擴展,可以使用-std = c99選項,如下所示:
            gcc -D_XOPEN_SOURCE=600 -std=c99 file.c -o file
            另一個功能測試宏是:__STDC__,它由符合ISO C標準的C編譯器自動定義。這樣就允許我們編寫ISO C編譯器和非ISO C編譯器都能編譯的程序。例如,為了利用ISO C原型功能(如果支持),一個頭文件可能包含:
          #ifdef __STDC__
          void *myfunc( const char *, int );
          #else
          void *myfunc();
          #endif
            雖然,當今的大多數C編譯器都支持ISO C標準,但在很多頭文件中仍舊使用__STDC__功能測試宏。

          posted @ 2014-11-04 10:16 順其自然EVO 閱讀(263) | 評論 (0)編輯 收藏

          Linux系統工程師學習方法

            學習順序:
            一、至少熟悉一種嵌入式芯片架構
            最適合初學者的就是arm芯片
            二、uboot的使用與移植
            首先要了解uboot的啟動流程,根據啟動順序,進行代碼的修改、編譯與移植
            三、linux驅動開發
            主要參考兩本書:《Linux設備驅動程序》 《Linux設備驅動開發詳解》
            第一本書講理論,第二本講實踐。
            在學驅動開發的時候,會涉及許多內核知識(例如內核定時器、內核鏈表、并發等),首先先學會使用,千萬不要去看它們的實現。并且在看驅動的時候,用到那部分知識,再去查看相關的運用。
            四、linux內核
            此部分在學習驅動半年后,對驅動十分熟悉的情況下,再去專門的研究內核。

          posted @ 2014-11-03 09:31 順其自然EVO 閱讀(342) | 評論 (0)編輯 收藏

          遠程linux服務器mysql數據庫定期備份和刪除

           網上已經有部分關于Linux下定期備份mysql的方法,但是很多步驟不夠詳細,不適合新手,自己琢磨了很久,終于搞定了。
            1.Linux服務器一般是ssh協議,如果本地也是Linux環境,可以直接通過shell連接,命令:
            ssh  -l  root  -p  8080  202.***.***.***
            其中root為用戶名,一般為root,8080為端口,202.***.***.***為服務器ip地址;
            接下來會提示你輸入密碼,輸入正確后即可進入服務器;
            2.然后需要創建一個數據庫備份數據存放的文件夾;
            mkdir /mysql/mysqldata_bakeup
            /mysql/mysqldata_bakeup為創建的路徑,可以自定義;
            3.創建并編輯文件在路徑 /usr/sbin/bakmysql,命令:
            vi /usr/sbin/bakmysql
            此時會在/usr/sbin/路徑下創建bakmysql文件,并進入bakmysql編輯狀態,接著輸入;
            fn = ` date +%Y%m%d `
            tar  zcvf  /mysql/mysqldata_bakeup/mysql$fn.tar.gz  /mysql/data
            或
            mysqldump -u root -ppassword /mysql/data/yourdatabase > /mysql/mysqldata_bakeup/mysql$fn.sql
            find /mysql/mysqldata_bakeup/ -type f -mtime +7 -exec rm -f {} \;
            /mysql/mysqldata_bakeup/為備份數據保存路徑,msql$fn.tar.gz為備份數據根據日期編號的名稱,/mysql/data為服務器數據庫的數據路徑,yourdatabase為你要備份的數據庫名;
            注意其中第一句命令不是單引號,而是tab鍵上面的符號,且date前后需要有空格;
            第二句命令有兩種方法,第一種直接備份并壓縮數據庫數據源文件,第二種是利用mysql自帶命令mysqldump導出數據庫yourdatabase的sql文件;
            第三句是刪除7天前的備份文件,mtime是文件修改時間,如果沒有修改過,則為創建時間;
            4.修改文件bakmysql屬性,使其可執行;
            chmod +x /usr/sbin/bakmysql
            5.修改/etc/crontab:
            vi /etc/crontab
            進入編輯狀態,在最下面添加:
            01 3 * * * root /usr/sbin/bakmysql
            01 3 是每天凌晨3:01執行 bakmysql文件;
            6.關于重啟有時候并不需要,如果服務器在/etc/rc.d/init.d/路徑下有crond服務,可以選擇重啟crond,命令:
            /etc/rc.d/init.d/crond restart
            7.最后退出服務器命令:exit

          posted @ 2014-11-03 09:31 順其自然EVO 閱讀(424) | 評論 (0)編輯 收藏

          鳥瞰數據庫系統原理

            數據庫系統是一種管理數據的系統,首先設計到數據,談到數據就要從數據管理的歷史來看數據庫系統的發展。其中,達到數據庫階段后,我們開始來討論我們這門課程。
            先來看應用部分:
            1、分析數據
            設計使用數據庫,首先要對問題進行分析。那么數據庫世界中的問題不就圍繞數據開展的嘛!所以先從數據開始分析。
            數據分析時,由于人們往往不能對問題的解決一步到位。所以人們對數據庫的分析也是一般從宏觀到微觀,采用抽象的辦法來對數據進行逐步細化的分析。人們在對數據抽象過程中對數據抽象不同階段得到四種模型。
            由于人們在得到四種模型過程中是通過不斷細化得到的,所以這些模型也自然形成了一種層次關系。這種層次關系各自解決不同層次的問題,層次之間通過映射來聯系。這種數據庫結構分析好之后就該動手設計了。
            2、設計數據庫
            要設計數據庫,先整體規劃好,然后弄清楚需求。有了一個比較清晰的需求,下面針對各個模型進行具體的設計。
            在概念模型設計中,一個比較重要的工具是E-R圖,通過E-R圖可以比較直觀地了解將要開發的系統。如果一個好的系統設計出來,那么自然要上手嘗試一下它的魅力。
            3、使用
            數據庫的使用最基本的是SQL語言,單獨來說SQL語言其實就是對表的增刪改查。而對SQL語言擴充之后的T-SQL也就是增加了一些流程控制。數據庫語言的使用學會之后,就要學會對數據庫的管理了。
            4、管理
            使用數據庫系統的前提是該系統能保證數據的正確性和安全性,要能保證這些離不開對數據庫系統的管理。數據正確性最直接的是使用約束,限制數據范圍。其次是通過事務機制來保證隨著系統運行,數據不會發生意外損失。系統中多個事務并行進行,就要對系統進行并行控制。最后最糟糕的情況,就一定能保證恢復原來的狀態。
            保證了數據的正確性仍然不能滿足人們的需要,因為對數據的操作是有權限的,正如我們在程序設計中使用訪問控制符來限定對數據操作一樣。我們要對數據的安全進行管理,防止非法的操作及意外故障對系統的破壞。
            再看理論部分:
            應用總是要有相應的理論來支持和指導的,這里我們按照順序從建表的理論開始學習,在表設計中總要有個好壞的標準吧,盲目地建表會產生許多麻煩的問題,這就提出了范式。建表有了統一的標準后,接下來就是用表了即操作表,對表有許多的操作,你講不出為什么能這么做總不行吧。所以下面就針對表的操作來研究這些操作的理論。

          posted @ 2014-11-03 09:30 順其自然EVO 閱讀(363) | 評論 (0)編輯 收藏

          從Oracle轉到Mysql前需了解的50件事

          1、 對子查詢的優化表現不佳。
            2、 對復雜查詢的處理較弱
            3、 查詢優化器不夠成熟
            4、 性能優化工具與度量信息不足
            5、 審計功能相對較弱
            6、 安全功能不成熟,甚至可以說很粗糙。沒有用戶組與角色的概念,沒有回收權限的功能(僅僅可以授予權限)。當一個用戶從不同的主機/網絡以同樣地用戶名/密碼登錄之后,可能被當作完全不同的用戶來處理。沒有類似于Oracle的內置的加密功能。
            7、身份驗證功能是完全內置的。不支持LDAP,Active Directory以及其它類似的外部身份驗證功能。
            8、Mysql Cluster可能與你的想象有較大差異。
            9、存儲過程與觸發器的功能有限。
            10、垂直擴展性較弱。
            11、不支持MPP(大規模并行處理)。
            12、支持SMP(對稱多處理器),但是如果每個處理器超過4或8個核(core)時,Mysql的擴展性表現較差。
            13、對于時間、日期、間隔等時間類型沒有秒以下級別的存儲類型。
            14、可用來編寫存儲過程、觸發器、計劃事件以及存儲函數的語言功能較弱。
            15、沒有基于回滾(roll-back)的恢復功能,只有前滾(roll-forward)的恢復功能。
            16、不支持快照功能。
            17、不支持數據庫鏈(database link)。有一種叫做Federated的存儲引擎可以作為一個中轉將查詢語句傳遞到遠程服務器的一個表上,不過,它功能很粗糙并且漏洞很多。
            18、數據完整性檢查非常薄弱,即使是基本的完整性約束,也往往不能執行。
            19、優化查詢語句執行計劃的優化器提示非常少。
            20、只有一種表連接類型:嵌套循環連接(nested-loop),不支持排序-合并連接(sort-merge join)與散列連接(hash join)。
            21、大部分查詢只能使用表上的單一索引;在某些情況下,會存在使用多個索引的查詢,但是查詢優化器通常會低估其成本,它們常常比表掃描還要慢。
            22、不支持位圖索引(bitmap index)。每種存儲引擎都支持不同類型的索引。大部分存儲引擎都支持B-Tree索引。
            23、管理工具較少,功能也不夠成熟。
            24、沒有成熟能夠令人滿意的IDE工具與調試程序。可能不得不在文本編輯器中編寫存儲過程,并且通過往表(調試日志表)中插入記錄的方式來做調試。
            25、每個表都可以使用一種不同的存儲引擎。
            26、每個存儲引擎在行為表現、特性以及功能上都可能有很大差異。
            27、大部分存儲引擎都不支持外鍵。
            28、默認的存儲引擎(MyISAM)不支持事務,并且很容易損壞。
            29、最先進最流行的存儲引擎InnoDB由Oracle擁有。
            30、有些執行計劃只支持特定的存儲引擎。特定類型的Count查詢,在這種存儲引擎中執行很快,在另外一種存儲引擎中可能會很慢。
            31、執行計劃并不是全局共享的,,僅僅在連接內部是共享的。
            32、全文搜索功能有限, 只適用于非事務性存儲引擎。 Ditto用于地理信息系統/空間類型和查詢。
            33、沒有資源控制。一個完全未經授權的用戶可以毫不費力地耗盡服務器的所有內存并使其崩潰,或者可以耗盡所有CPU資源。
            34、沒有集成商業智能(business intelligence), OLAP 多維數據集等軟件包。
            35、沒有與Grid Control類似的工具(http://solutions.mysql.com/go.php?id=1296&t=s)
            36、沒有類似于RAC的功能。如果你問”如何使用Mysql來構造RAC”,只能說你問錯了問題。
            37、不支持用戶自定義類型或域(domain)。
            38、 每個查詢支持的連接的數量最大為61。
            39、MySQL支持的SQL語法(ANSI SQL標準)的很小一部分。不支持遞歸查詢、通用表表達式(Oracle的with 語句)或者窗口函數(分析函數)。支持部分類似于Merge或者類似特性的SQL語法擴展,不過相對于Oracle來講功能非常簡單。
            40、 不支持功能列(基于計算或者表達式的列,Oracle11g 開始支持計算列,以及早期版本就支持虛列(rownum,rowid))。
            41、不支持函數索引,只能在創建基于具體列的索引。
            42、不支持物化視圖。
            43、不同的存儲引擎之間,統計信息差別很大,并且所有的存儲引擎支持的統計信息都只支持簡單的基數(cardinality)與一定范圍內的記錄數(rows-in-a-range)。 換句話說,數據分布統計信息是有限的。更新統計信息的機制也不多。
            44、沒有內置的負載均衡與故障切換機制。
            45、復制(Replication)功能是異步的,并且有很大的局限性。例如,它是單線程的(single-threaded),因此一個處理能力更強的Slave的恢復速度也很難跟上處理能力相對較慢的Master。
            46、 Cluster并不如想象的那么完美。或許我已經提過這一點,但是這一點值得再說一遍。
            47、數據字典(INFORMATION_SCHEMA)功能很有限,并且訪問速度很慢(在繁忙的系統上還很容易發生崩潰)。
            48、不支持在線的Alter Table操作。
            49、不支持Sequence。
            50、類似于ALTER TABLE或CREATE TABLE一類的操作都是非事務性的。它們會提交未提交的事務,并且不能回滾也不能做災難恢復。Schame被保存在文件系統上,這一點與它使用的存儲引擎無關。
          我本人比較關心的幾點:
            1、對子查詢的優化表現不佳
            2、對復雜查詢的處理較弱
            4、性能優化工具與度量信息不足
            12、支持SMP(對稱多處理器),但是如果每個處理器超過4或8個核(core)時,Mysql的擴展性表現較差。
            15、沒有基于回滾(roll-back)的恢復功能,只有前滾(roll-forward)的恢復功能。
            18、數據完整性檢查非常薄弱,即使是基本的完整性約束,也往往不能執行。
            20、只有一種表連接類型:嵌套循環連接(nested-loop),不支持排序-合并連接(sort-merge join)與散列連接(hash join)。
            21、大部分查詢只能使用表上的單一索引;在某些情況下,會存在使用多個索引的查詢,但是查詢優化器通常會低估其成本,它們常常比表掃描還要慢。
            26、每個存儲引擎在行為表現、特性以及功能上都可能有很大差異。
            28、默認的存儲引擎(MyISAM)不支持事務,并且很容易損壞。
            30、有些執行計劃只支持特定的存儲引擎。特定類型的Count查詢,在這種存儲引擎中執行很快,在另外一種存儲引擎中可能會很慢。
            31、執行計劃并不是全局共享的,僅僅在連接內部是共享的。
            33、沒有資源控制。一個完全未經授權的用戶可以毫不費力地耗盡服務器的所有內存并使其崩潰,或者可以耗盡所有CPU資源。
            45、復制(Replication)功能是異步的,并且有很大的局限性。例如,它是單線程的(single-threaded),因此一個處理能力更強的Slave的恢復速度也很難跟上處理能力相對較慢的Master。
            46、Cluster并不如想象的那么完美。或許我已經提過這一點,但是這一點值得再說一遍。
            47、數據字典(INFORMATION_SCHEMA)功能很有限,并且訪問速度很慢(在繁忙的系統上還很容易發生崩潰)。
            48、不支持在線的Alter Table操作。
            50、類似于ALTER TABLE或CREATE TABLE一類的操作都是非事務性的。它們會提交未提交的事務,并且不能回滾也不能做災難恢復。Schame被保存在文件系統上,這一點與它使用的存儲引擎無關。

          posted @ 2014-11-03 09:30 順其自然EVO 閱讀(131) | 評論 (0)編輯 收藏

          Java實現將漢字轉為拼音

          有時候為了方便操作程序的開發,需要將漢字轉為拼音等操作。下面這個是自己結合網上的資料,加上自己在公司項目中的親自實踐。完整的實現了將漢字轉為拼音的操作。這個Demo只是負責將其轉換,在main方法中測試,在實際需要中,只需要調用這個類中的方法即可。
            首先貼出測試結果:
            測試參數:
            漢字轉換為拼音
            漢字轉換為拼音
            main測試方法的代碼:
            1 public static void main(String[] args) {
            2         System.out.println(ToFirstChar("漢字轉換為拼音").toUpperCase()); //轉為首字母大寫
            3         System.out.println(ToPinyin("漢字轉換為拼音"));
            4     }
            本功能的實現時利用java開源庫,開發此程序需要一個jar包。本人用的是pinyin4j-2.5.0.jar。網上可以直接下載,也可以在其官網進行下載。在此不祥述。如果實在不樂意,可以點擊下載將進行這個jar包的下載。
          貼出實現該Demo的源碼:
          1 package com.red.test;
          2
          3 import net.sourceforge.pinyin4j.PinyinHelper;
          4 import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
          5 import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
          6 import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
          7 import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
          8
          9 /**
          10  * 漢字轉換為拼音
          11  * @author Red
          12  */
          13 public class PinyinDemo {
          14     /**
          15      * 測試main方法
          16      * @param args
          17      */
          18     public static void main(String[] args) {
          19         System.out.println(ToFirstChar("漢字轉換為拼音").toUpperCase()); //轉為首字母大寫
          20         System.out.println(ToPinyin("漢字轉換為拼音"));
          21     }
          22     /**
          23      * 獲取字符串拼音的第一個字母
          24      * @param chinese
          25      * @return
          26      */
          27     public static String ToFirstChar(String chinese){
          28         String pinyinStr = "";
          29         char[] newChar = chinese.toCharArray();  //轉為單個字符
          30         HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat();
          31         defaultFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);
          32         defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
          33         for (int i = 0; i < newChar.length; i++) {
          34             if (newChar[i] > 128) {
          35                 try {
          36                     pinyinStr += PinyinHelper.toHanyuPinyinStringArray(newChar[i], defaultFormat)[0].charAt(0);
          37                 } catch (BadHanyuPinyinOutputFormatCombination e) {
          38                     e.printStackTrace();
          39                 }
          40             }else{
          41                 pinyinStr += newChar[i];
          42             }
          43         }
          44         return pinyinStr;
          45     }
          46
          47     /**
          48      * 漢字轉為拼音
          49      * @param chinese
          50      * @return
          51      */
          52     public static String ToPinyin(String chinese){
          53         String pinyinStr = "";
          54         char[] newChar = chinese.toCharArray();
          55         HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat();
          56         defaultFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);
          57         defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
          58         for (int i = 0; i < newChar.length; i++) {
          59             if (newChar[i] > 128) {
          60                 try {
          61                     pinyinStr += PinyinHelper.toHanyuPinyinStringArray(newChar[i], defaultFormat)[0];
          62                 } catch (BadHanyuPinyinOutputFormatCombination e) {
          63                     e.printStackTrace();
          64                 }
          65             }else{
          66                 pinyinStr += newChar[i];
          67             }
          68         }
          69         return pinyinStr;
          70     }
          71 }

          posted @ 2014-11-03 09:22 順其自然EVO 閱讀(203) | 評論 (0)編輯 收藏

          Java LoggingAPI 使用方法

          因為不想導入Log4j的jar,項目只是測試一些東西,因此選用了JDK 自帶的Logging,這對于一些小的項目或者自己測試一些東西是比較好的選擇。
            Log4j中是通過log4j.properties這個配置文件控制日志的輸出,java logging中是通過logging.properties文件完成類似的功能。
            Logging.properties文件位于JDK安裝路徑的 jre/lib/目錄下,直接上配置文件:
          handlers= java.util.logging.ConsoleHandler
          .level= INFO
          java.util.logging.FileHandler.pattern = %h/java%u.log
          java.util.logging.FileHandler.limit = 50000
          java.util.logging.FileHandler.count = 1
          java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter
          java.util.logging.ConsoleHandler.level = INFO
          java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
            既想要輸入在控制臺,又想要收入在文件中,如下進行設置。
            handlers= java.util.logging.FileHandler, java.util.logging.ConsoleHandler
            log文件的格式要求設置如下行:
            java.util.logging.FileHandler.pattern = %h/java%u.log
            具體的表示如何定義,可以查看java logging format api 進行設置。
            通過上述設置就可以實現將日志輸入到指定文件的要求了。但是有時候只是希望某些類的文件輸出到制定,這樣調試起來更清晰些,為了實現個要求還要再進行些設置。
            com.jason.logger.LoggerDemo.level = ALL
            com.spt.logger.LoggerDemo.handlers = java.util.logging.FileHandler
            “com.spt.logger.LoggerDemo”是“Logger”的名字,它要和代碼中指定的Logger相匹配。
            c程序使用中,代碼如下:
            private static Logger log = Logger.getLogger(LoggerDemo.class.getName());
            對了,還忘記了logging 的幾個級別做一下介紹:
            SEVERE (最高級別)
            WARNING
            INFO
            CONFIG
            FINE
            FINER
            FINEST (最低級別)
            簡單的使用這些已經足夠了,再復雜的使用,個人感覺就要上log4j 了。

          posted @ 2014-11-03 09:20 順其自然EVO 閱讀(222) | 評論 (0)編輯 收藏

          幾個軟件研發團隊管理的小問題

          最近在與一位總經理交流的時候,他談到他們公司的軟件研發管理,說:“我們公司最大的問題是項目不能按時完成,總要一拖再拖。”他問我有什么辦法能改變這個境況。從這樣一個問題開始,在隨后的交談中,又引出他一連串在軟件研發管理中的遇到的問題,包括:
            . 現有代碼質量不高,新來的開發人員接手時寧愿重寫,也不愿意看別人留下的“爛”代碼,怎么辦?
            . 重構會造成回退,怎樣避免?
            . 有些開發人員水平相對不高,如何保證他們的代碼質量?
            . 軟件研發到底需不需要文檔?
            . 要求提交代碼前做Code Review,而開發人員不做,或敷衍了事,怎么辦?
            . 當有開發人員在開發過程中遇到難題,工作無法繼續,因而拖延進度,怎么解決?
            . 如何提高開發人員的主觀能動性?
            其實,每個軟件研發團隊的管理者都面臨著或曾經面臨過這些問題,也都有著自己的管理“套路”來應對這些問題。我把我的“套路”再此絮叨絮叨。
            1. 項目不能按時完成,總要一拖再拖,怎么改變?
            找解決辦法前,當然要先知道問題為什么會出現。這位總經理說:“總會不斷地有需求要改變和新需求提出來,使原來的開發計劃不得不延長。”原來如此。知道根源,當然解決辦法也就有了,那就是“敏捷”。敏捷開發因其迭代(Iterative)和增量(Incremental)的思想與實踐,正好適合“需求經常變化和增加”的項目和產品。在我講述了敏捷的一些概念,特別是Scrum的框架后,總經理也表示了對“敏捷”的認同。
            其實仔細想想,這里面還有一個非常普遍的問題。對于產品的交付時間或項目的完成時間,往往由高級管理層根據市場情況決策和確定。在很多軟件企業中,這些決策者在決策時往往忽略了一個重要的參數,那就是團隊的生產率(Velocity)。生產率需要量化,而不是“拍腦門子”感覺出來的。敏捷開發中有關于如何估算生產率的方法。所以使用敏捷,在估算產品交付時間或項目完成時間時,是相對較準確的。Scrum創始人之一的Jeff Sutherland說,他在一個風險投資團隊做敏捷教練時,團隊中的資深合伙人會向所有的待投資企業問同一個問題:“你們是否清楚團隊的生產率?”而這些企業都很難做出明確的答復。軟件企業要想給產品定一個較實際的交付日期,就首先要弄清楚自己的軟件生產率。
            2. 現有代碼質量不高,新來的開發人員接手時寧愿重寫,也不愿意看別人留下的“爛”代碼,怎么辦?
            這可能是很多軟件開發工程師都有過的體驗,在接手別人的代碼時,看不懂、無法加新功能,讀代碼讀的頭疼。這說明什么?排除接手人個人水平的因素,這說明舊代碼可讀性、可擴展性比較差。怎么辦?這時,也許重構是一種兩全其美的辦法。接手人重構代碼,既能改善舊代碼的可讀性和可擴展性,又不至于因重寫代碼帶來的時間上的風險。
            從接手人心理的角度看,重構還有一個好的副作用,就是代碼重構之后,接手人覺得那些原來的“爛”代碼被修改成為自己引以自豪的新成就。《Scrum敏捷軟件開發》的作者Mike Cohn寫到過:“我的女兒們畫了一幅特別令人贊嘆的杰作后,她們會將它從學校帶回家,并想把它展示在一個明顯的位置,也就是冰箱上面。有一天,在工作中,我用C++代碼實現了某個特別有用的策略模式的程序。因為我認定冰箱門適合展示我們引以為豪的任何東西,所以我就將它放上去了。如果我們一直對自己工作的質量特別自豪,可以驕傲地將它和孩子的藝術品一樣展示在冰箱上,那不是很好嗎?”所以這個積極的促進作用,將使得接手人感覺修改的代碼是自己的了,而且期望能夠找到更多的可以重構的東西。
            3. 重構會造成回退,怎樣避免?
            重構確實很容易造成回退(Regression)。這時,重構會起到與其初衷相反的作用。所以我們應該盡可能多地增加單元測試。有些老產品,舊代碼,可能沒有或者沒有那么多的單元測試。但我們至少要在重構前,增加對要重構部分代碼的單元測試。基于重構目的的單元測試,應該遵循以下的原則(見《重構》第4章:構筑測試體系):
            - 編寫未臻完善的測試并實際運行,好過對完美測試的無盡等待。測試應該是一種風險驅動行為,所以不要去測試那些僅僅讀寫一個值域的訪問函數,應為它們太簡單了,不大可能出錯。
            - 考慮可能出錯的邊界條件,把測試火力集中在哪兒。扮演“程序公敵”,縱容你心智中比較促狹的那一部分,積極思考如何破壞代碼。
            - 當事情被公認應該會出錯時,別忘了檢查是否有異常如期被拋出。
            - 不要因為“測試無法捕捉所有Bug”,就不撰寫測試代碼,因為測試的確可以捕捉到大多數Bug。
            - “花合理時間抓出大多數Bug”要好過“窮盡一生抓出所有Bug”。因為當測試數量達到一定程度之后,測試效益就會呈現遞減態勢,而非持續遞增。
            說到《重構》這本書,其實在每個重構方法中都有“作法(Mechanics)”一段,在重構的實踐中按照上面所述的步驟進行是比較穩妥的,同時也能避免很多不經意間制造的回退出現。 4. 要求提交代碼前做Code Review,而開發人員不做,或敷衍了事,怎么辦?
            如果每個開發人員都是積極主動的,Code Review的作用能落到實處。但如果不是呢?團隊管理者需要一些手段促使其有效地進行Code Review。首先,我們采用的Code Review有2種形式,一是Over-the-shoulder,也就是2個人座在一起,一個人講,另一個人審查。二是用工具Code Collaborator來進行。無論哪種形式,在提交代碼時,必須注明關于審查的信息,比如:審查者(Reviewer)的名字或審查號(Review ID,Code Collaborator自動生成),每天由一名專職人員來檢查Checklist中的每一條,看是否有人漏寫這些信息,如果發現會提醒提交的人補上。另外,某段提交的代碼出問題,提交者和審查者都要一起來解決出現的問題,以最大限度避免審查過程敷衍了事。
            博主Inovy在某個評論說的很形象:“木(沒)有賞罰的制度,就是帶到廁所的報紙,看完就可以用來擦屁股了。”沒有獎懲制度作保證,當然上面的要求沒有什么效力。所以,當有人經常不審查就提交,或審查時不負責任,它的績效評定就會因此低一點,而績效的評分是跟每年工資漲落掛鉤的。說白了,可能某個人會因為多次被查出沒有做Code Review就提交代碼,而到年底加薪時比別人少漲500塊錢。
            5. 軟件研發到底需不需要文檔?
            軟件研發需要文檔的起原可能有2種,一是比較原始的,需要文檔是為了當開發人員離職后,企業需要接手的人能根據文檔了解他所接手的代碼或模塊的設計。二是較高層次的,企業遵從ISO9001質量管理體系或CMMI。
            對于第一種,根源可能來自于兩個方面:
            - 原開發人員設計編碼水平不高,其代碼可讀性較差。
            - 設計思想和代碼只有一個人了解,此人一旦離職,無人知道其細節。
            在編碼前寫一些簡單的設計文檔,有助于理清思路,尤其是輔以一些UML圖,在交流時也是有好處的。但同時,我們也應該提高開發人員的編碼水平增加其代碼的可讀性,比如增強其變量命名的可讀性、用一些被大家所了解的設計模式來替代按自己某些獨特思路編寫的代碼、增加和改進注釋等等,以減少不必要的文檔。另外推行代碼的集體所有權(Collective Ownership),避免某些代碼只被一個人了解,這樣可以減少以此為目的而編寫的文檔。
            對于第二種,情況有些復雜。接觸過敏捷開發的人都知道《敏捷宣言》中的“可以工作的軟件勝于面面俱到的文檔”。接觸過CMMI開發或者ISO9001質量管理體系的人知道它們對文檔的要求是多么的高。它們看起來水火不相容。但是,它們的宗旨是一致的,即:構建高質量的產品。
            對于敏捷,使用手寫用戶故事來記錄需求和優先級的方法,以及在白板上寫畫的非正式設計,是不能通過ISO9001的審核的,但當把它們復印、拍照、增加序號、保存后,可以通過審核。每次都是成功的Daily Build和Auto Test報告無法證明它們是否真正被執行并真正成功,所以不能通過ISO9001的審核。但添加一個斷言失敗(類似assert(false)的斷言)的測試后,則可以通過審核。
            CMMI與敏捷也是互補的,前者告訴組織在總體條款上做什么,但是沒有說如何去做,后者是一套最佳實踐。SCRUM之類的敏捷方法也被引入過那些已通過CMMI5級評估的組織。很多企業忘記了最終目標是改進他們構建軟件及遞交產品的方式,相反,它們關注于填寫按照CMMI文檔描述的假想的缺陷,卻不關心這些變化是否能改進過程或產品。
            所以敏捷開發在過程中只編寫夠用的文檔,和以“信息的溝通、符合性的證據以及知識共享”作為主要目標的質量體系文檔要求并不矛盾。在實踐中,我們可以按以下方法做,在實現SCRUM的同時,符合審核和評估的要求:
            - 制作格式良好的、被細化的、被保存的和能跟蹤的Backlog。復印和照片同樣有效。
            - 將監管需要的文檔工作也放入Backlog。除了可以確保它們不被忘記,還能使監管要求的成本是可見的。
            - 使用檢查列表,以向審核員或評估員證明活動已執行。團隊對“完成”的定義(Definition of “Done”)可以很容易轉變為一份檢查列表。
            - 使用敏捷項目管理工具。它其實就是開發程序和記錄的電子呈現方式。
            總而言之,軟件研發需要文檔(但文檔的形式可以是多種多樣的,用Word寫的文字式的文件是文檔,用Visio畫的UML圖也是文檔,保存在Quality Center中的測試用例也是文檔),同時我們只需寫夠用的文檔。
            6. 當有開發人員在開發過程中遇到難題,工作無法繼續,因而拖延進度,怎么解決?
            這也是個常遇到的問題。如果管理者對于某個工程師的具體問題進行指導,就會陷入過度微觀管理的境地。我們需要找到宏觀解決辦法。一,我們基于Scrum的“團隊有共同的目標”這一規則,利用前面提到的集體所有權,當出現這些問題時,用團隊中所有可以使用的力量來幫助其擺脫困境,而不是任其他人袖手旁觀。當然這里會牽扯到績效評定的問題,比如:提供幫助的人會覺得,他的幫助無助于自己績效評定的提高,為什么要提供幫助。這需要人力資源部門在使用Scrum開發的團隊的績效評估中,盡量消除那些傾向個人的因素,還要包含團隊協作的因素,廣泛聽取個方面的意見,更頻繁地評估績效等等。
            二,即使動用所有可以使用的力量,如果某個難題真的無法逾越,為了減少不能按時交付的風險,產品負責人應當站出來,并有所作為。要么重新評估Backlog的優先級,使無法繼續的Backlog遲一點交付,先做一些相對較低優先級的Backlog,以保證整體交付時間不至于延長;要么減少部分功能,給出更多的時間去攻克難題。總之逾越技術上難關會使團隊的生產率下降,產品負責人必須作出取舍。
            7. 有些開發人員水平相對不高,如何保證他們的代碼質量?
            當然首先讓較有經驗的人Review其要提交的代碼,這幾乎是所有管理者會做的事。除此之外,管理者有責任幫助這些人(也包括水平較高的人)提高水平,他們可以看一些書,上網看資料,讀別人的代碼等等,途經還是很多的。但問題是你如何去衡量其是否真正有所收獲。我們的經驗是,在每年大約3月份為每個工程師制定整個年度的目標,每個人的目標包括產品上的,技術上的,個人能力上的等4到5項。半年后和一年后,要做兩次Performance Review,目標是否實現,也會跟績效評定掛鉤。我們在制定目標時,遵循SMART原則,即:
            Specific(明確的):目標應該按照明確的結果和成效表述。
            Measurable(可衡量的):目標的完成情況應該可以衡量和驗證。
            Aligned(結盟的):目標應該與公司的商業策略保持一致。
            Realistic(現實的):目標雖然應具挑戰性,但更應該能在給定的條件和環境下實現。
            Time-Bound(有時限的):目標應該包括一個實現的具體時間。
            比如:某個人制定了“初步掌握本地化技術”的目標,他要確定實現時間,要描述學習的途經和步驟,要通過將技術施加到公司現有的產品中,為公司產品的本地化/國際化/全球化作一些探索,并制作Presentation給團隊演示他的成果,并準備回答其他人提出的問題。團隊還為了配合其實現目標,組織Tech Talk的活動,供大家分享每個人的學習成果。通過這些手段,提高開發人員的自學興趣,并逐步提高開發人員的技術水平。
            8. 如何提高開發人員的主觀能動性?
            提高開發人員的主觀能動性,少不了激勵機制。不能讓開發人員感到,5年以后的他和現在比不會有什么進步。你要讓他感到他所從事的是一個職業(Career),而不只是一份工作(Job)。否則,他們是不會主動投入到工作中的。我們的經驗是提供一套職業發展的框架。框架制定了2類發展道路,管理類(Managerial Path)和技術類(Technical Path),6個職業級別(1-3級是Entry/Associate,Intermediate,Senior。4級管理類是Manager/Senior Manager,技術類是Principal/Senior Principal。5級管理類是Director/Senior Director,技術類是Fellow/Architect。6級是Executive Management)。每個級別都有13個方面的具體要求,包括:范圍(Scope)、跨職能(Cross Functional)、層次(Level)、知識(Knowledge)、指導(Guidance)、問題解決(Problem Solving)、遞交成果(Delivering Result)、責任感(Responsbility)、導師(Mentoring)、交流(Communication)、自學(Self-Learning),運作監督(Operational Oversight),客戶響應(Customer Responsiveness)。每年有2次提高級別的機會,開發人員一旦具備了升級的條件,他的Supervisor將會提出申請,一旦批準,他的頭銜隨之提高,薪水也會有相對較大提高。從而使每個開發人員覺得“有奔頭”,自然他們的主觀能動性也就提高了。
            上面的“套路”涉及了軟件研發團隊管理中的研發過程、技術實踐、文檔管理、激勵機制等一些方面。但只是九牛一毛,研發團隊管理涵蓋的內容還有很多很多,還需要管理者在不斷探索和實踐的道路上學習和掌握。

          posted @ 2014-11-03 09:19 順其自然EVO 閱讀(156) | 評論 (0)編輯 收藏

          《全面軟件質量管理》核心觀點摘錄

           軟件產品的質量定義始終都是滿足要求和適合使用,高質量和高等級是有區別的。軟件質量目標應該來源于商業目標驅動,商業目標決定了軟件的價值。提高軟件質量的目標仍然是為了盈利和創造更大的效益,而不是創造完美無缺的產品。
            軟件產品質量不是靠測試和評審出來的,而是靠設計出來的。關注軟件項目中的好質量成本和壞質量成本可以宏觀的看到項目軟件質量管理的水平。對于軟件項目COQ一般在35%-55%,而壞質量成本一般在8-15%,這也說明我們要盡量減少返工,爭取第一次就把事情做對。
            1.軟件的質量屬性和質量要素
            PMBOK中質量的定義是符合要求和適合使用。CMM對質量的定義是一個系統,組件或過程符合客戶或用戶的要求或期望的程度。因此可以講質量更多不是研發者說的,而是用戶的最終感受。
            通過類比,我們這樣理解軟件質量:軟件質量是許多質量屬性的綜合體現,各種質量屬性反映了軟件質量的方方面面。人們通過改善軟件的各種質量屬性,從而提高軟件的整體質量(否則無從下手)。
            軟件的質量屬性很多,如正確性、精確性,健壯性、可靠性、容錯性、性能、易用性、安全性、可擴展性、可復用性、兼容性、可移植性、可測試性、可維護性、靈活性等。這些質量屬性又可以分為功能性和非功能性兩大類。
            功能性質量要素:正確性,健壯性,可靠性
            非功能性質量因素:性能,易用性,安全性,可擴展性,兼容性,可移植性
            a.正確性:第一重要,機器不會欺騙人,軟件運行錯誤都是人為造成的。
            b.健壯性:包括容錯能力和恢復能力,開發過程中應該充分考慮各種異常和邊界。
            c.可靠性:可靠性是指在一定的環境下,在給定的時間內,系統不發生故障的概率。
            d.性能:性能通常是指軟件的“時間-空間”效率,而不僅是指軟件的運行速度。(性能問題解決根本還是算法和程序的優化,而不是期待硬件的更高配置)
            e.易用性:易用性是指用戶使用軟件的容易程度。(界面友好僅僅是一方面,還包括人機工程很多內容)
            f.安全性:安全性是指防止系統被非法入侵的能力
            g.擴展性:反映了軟件應對變化的能力
            h.兼容性:對硬件的兼容,對軟件的兼容
            非功能性需求是軟件質量重要組成,是架構設計和軟件產品化的重要考慮,但往往容易被忽視。特別是在開發通用性的產品的時候,非功能性質量要素必須要考慮全面。
            什么是質量要素,應該理解為能夠提高用戶滿意度和提高產品核心競爭力和價值的質量屬性。如果某些質量屬性并不能產生顯著的經濟效益,我們可以忽略它們,把精力用在對經濟效益貢獻最大的質量要素上。簡而言之,只有質量要素才值得開發人員下功夫去改善。
            2.商業目標決定質量目標
            重視軟件質量是應該的,但是“質量越高越好”并不是普適的真理。只有極少數軟件應該追求“零缺陷”,對絕大多數軟件而言,商業目標決定了質量目標,而不該把質量目標凌駕于商業目標之上。
            企業的根本目標是為了獲取盡可能多的利潤,而不是生產完美無缺的產品。如果企業銷售出去的軟件的質量比較差,輕則挨罵,重則被退貨甚至被索賠,因此為了提高用戶對產品的滿意度,企業必須提高產品的質量。但是企業不可能為了追求完美的質量而不惜一切代價,當企業為提高質量所付出的代價超過銷售收益時,這個產品已經沒有商業價值了,還不如不開發。
            企業必須權衡質量、效率和成本,產品質量太低了或者太高了,都不利于企業獲取利潤。企業理想的質量目標不是“零缺陷”,而是恰好讓廣大用戶滿意,并且將提高質量所付出的代價控制在預算之內。
            3.質量保證能夠保證質量嗎
            軟件質量保證(Quality Assurance)的目的是為管理者提供有關軟件過程和產品的適當的可視性。它包括評審和審核軟件產品及其活動,以驗證其是否遵守既定的規程和標準,并向有關負責人匯報評審和審核的結果。
            簡而言之,質量保證活動就是檢查軟件項目的“工作過程和工作成果”是否符合既定的規范。如此簡單的活動為什么被冠以“質量保證”這等份量的術語呢?沒有歷史典故,經我考究,猜想是源于一個天真的假設:
            過程質量與產品質量存在某種程度的因果關系,通常“好的過程”產生“好的產品”,而“差的過程”將產生“差的產品”。假設企業已經制定了軟件過程規范,如果質量保證人員發現某些項目的“工作過程以及工作成果”不符合既定的規范,那么馬上可以斷定產品存在缺陷。反之,如果質量保證人員沒有發現不符合既定規范的東西,那么也可以斷定產品是合格的。
            符合既定規范的東西并不意味著質量一定合格,僅靠規范無法識別出產品中可能存在的大量缺陷.
            4.全面軟件質量管理模型
            提高軟件質量最好的辦法是:在開發過程中有效地防止工作成果產生缺陷,將高質量內建于開發過程之中。主要措施是“不斷地提高技術水平,不斷地提高規范化水平”,其實就是練內功,通稱為“軟件過程改進”。
            其次方法是當工作成果剛剛產生時馬上進行質量檢查,及時找出并消除工作成果中的缺陷。這種方式效果比較好,人們一般都能學會。最常用的方法是技術評審、軟件測試和過程檢查,已經被企業廣泛采用并取得了成效。
            最差的是在軟件交付之前,沒有及時消除缺陷。當軟件交付給用戶后,用著用著就出錯了,趕緊請開發者來補救。可笑的是,當軟件系統在用戶那里出故障了,那些現場補救成功的人倒成了英雄,好心用戶甚至還寄來感謝信。
          誰對軟件質量負責?是全員負責。任何與軟件開發、管理工作相關的人員都對質量產生影響,都要對質量負責。所以人們不要把質量問題全部推出質量人員或測試人員。
            誰對軟件質量負最大的責任?誰的權利越大,他所負的質量責任就越大。質量人員是成天與質量打交道的人,但他個人并不對產品質量產生最大的影響,所以也不負最大的責任。
            質量人員的主要職責:
            1.負責制定質量計劃(很重要但是工作量比較少);
            2.負責過程檢查(類似于CMM中的質量保證),約占個人工作量的20%;
            3.參與技術評審,約占個人工作量的30%;
            4.參與軟件測試,約占個人工作量的30%;
            5.參與軟件過程改進(面向整個機構),約占個人工作量的20%;
            質量管理計劃的主要內容(模板見word文件):
            1. 質量要素分析
            2. 質量目標
            3. 人員與職責
            4. 過程檢查計劃
            5. 技術評審計劃
            6. 軟件測試計劃
            7. 缺陷跟蹤工具
            8. 審批意見
            5.技術評審
            技術評審(Technical Review, TR)的目的是盡早地發現工作成果中的缺陷,并幫助開發人員及時消除缺陷,從而有效地提高產品的質量。技術評審最初是由IBM公司為了提高軟件質量和提高程序員生產率而倡導的。技術評審方法已經被業界廣泛采用并收到了很好的效果,它被普遍認為是軟件開發的最佳實踐之一。
            技術評審的主要好處有:
            1.通過消除工作成果的缺陷而提高產品的質量;
            2.技術評審可以在任何開發階段執行,不必等到軟件可以運行之際,越早消除缺陷就越能降低開發成本;
            3.開發人員能夠及時地得到同行專家的幫助和指導,無疑會加深對工作成果的理解,更好地預防缺陷,一定程度上提高了開發生產率。
            技術評審有兩種基本類型:
            1.正式技術評審FTR。FTR比較嚴格,需要舉行評審會議多。
            2.非正式技術評審ITR。ITR的形式比較靈活,通常在同伴之間開展,不必舉行評審會
            技術評審和軟件測試的目的都是為了消除軟件的缺陷,兩者的主要區別是:
            1.前者無需運行軟件,評審人員和作者把工作成果擺放在桌面上討論;
            2.而后者一定要運行軟件來查找缺陷。技術評審在軟件測試之前執行,尤其是在需求開發和系統設計階段。
            相比而言,軟件測試的工作量通常比技術評審的大,發現的缺陷也更多。在制定質量計劃的時候,已經確定了本項目的主要測試活動、時間和負責人,之后再考慮軟件測試的詳細計劃和測試用例。
            如果機構沒有專職的軟件測試人員的話,那么開發人員可以兼職做測試工作。當項目開發到后期,過程檢查和技術評審都已經沒有多少意義了,開發小組急需有人幫助他們測試軟件,如果質量人員參與軟件測試,對開發小組而言簡直就是“雪中送炭”。
            強調:質量人員一定要參與軟件測試(大約占其工作量的30%左右),只有這樣他才能深入地了解軟件的質量問題,而且給予開發小組強有力地幫助。
            CMM和ISO9001所述的軟件質量保證,實質就是過程檢查,即檢查軟件項目的“工作過程和工作成果”是否符合既定的規范。
            “過程檢查”這個詞雖然沒有質量保證那么動聽,但是其含義直接明了,不會讓人誤解。為了避免人們誤以為“質量保證”能夠“保證質量”,我提議用“過程檢查”取代質量保證這個術語。
            雖然本章批判了“質量保證”的浮夸,但是并沒有全盤否定質量保證的好處。過程檢查對提高軟件質量是有幫助的,只是它的好處沒有象質量保證鼓吹的那么好而已。
            符合規范的工作成果不見得就是高質量的,但是明顯不符合規范的工作成果十有八九是質量不合格的。例如版本控制檢查,再例如,機構制定了重要工作成果的文檔模板(例如需求規格說明書、設計報告等),要求開發人員寫的文檔盡可能符合模板。如果質量人員發現開發人員寫的文檔與機構的模板差異非常大,那么就要搞清楚究竟是模板不合適?還是開發人員偷工減料?
            過程檢查的要點是:找出明顯不符合規范的工作過程和工作成果,及時指導開發人員糾正問題,切勿吹毛求疵或者在無關痛癢的地方查來查去。
            不少機構的質量人員并沒有真正理解過程檢查的意義,老是對照規范,查找錯別字、標點符號、排版格式等問題,迷失了方向,這樣只有疲勞沒有功勞,而且讓開發人員很厭煩。
            對于中小型項目而言,過程檢查工作由質量人員一個人負責就夠了,約占其20%的工作量,讓質量人員抽出更多的時間從事技術評審和軟件測試工作。

          posted @ 2014-11-03 09:17 順其自然EVO 閱讀(232) | 評論 (0)編輯 收藏

          僅列出標題
          共394頁: First 上一頁 23 24 25 26 27 28 29 30 31 下一頁 Last 
          <2025年7月>
          293012345
          6789101112
          13141516171819
          20212223242526
          272829303112
          3456789

          導航

          統計

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 高碑店市| 商城县| 武定县| 洱源县| 黄大仙区| 兖州市| 麻城市| 壤塘县| 乐昌市| 翼城县| 高州市| 泽州县| 沛县| 浑源县| 衢州市| 马山县| 宣恩县| 麻阳| 新晃| 泽普县| 礼泉县| 新津县| 拉孜县| 闽清县| 孝义市| 迭部县| 龙川县| 保德县| 山丹县| 桂阳县| 二连浩特市| 富阳市| 唐海县| 连州市| 尖扎县| 张北县| 邓州市| 余庆县| 双城市| 文登市| 莱西市|