2011-10-31

【原创】在VirtualBox环境下编译Cyanogenmod for HTC Tattoo的rom

手头上的htc tattoo(g4)充电慢、耗电量也特别大,通话20分钟就自动关机,但检测电池是满电。
初步检测怀疑是手机主板电源模块问题,跟换电源模块问题依旧,怀疑是CPU问题。
没有零配件,没办法维修,只能自己想办法解决。

初步想法如下:
  1. 手机检测电量存在问题,电池满电但显示不正确。
  2. 能否更改操作系统,让电量一直处于100%状态?即:屏蔽手机电量检测,避免自动关机。(以后只能靠经验估算电量了)。
  3. 先从Cyanogenmod下手,先能编译成正常可刷机的rom,然后再修改源代码编译成屏蔽手机电量检测的rom。
  4. 由于没有linux真机环境,只能采用VirtualBox安装的debian 6虚拟机环境编译Cyanogenmod 7。

过程记录:
  1. 使用git下载Cyanogenmod内核源代码
    1. sudo apt-get install git git-all git-core
    2. sudo apt-get install gnupg flex bison gperf libsdl1.2-dev libesd0-dev libwxgtk2.6-dev squashfs-tools build-essential zip curl libncurses5-dev zlib1g-dev sun-java6-jdk pngcrush schedtool
    3. 下载repo脚本(python编写,封装了git的用法),curl http://android.git.kernel.org/repo > repo
    4. repo可能下载不了,建议用迅雷找源。下载后执行,会提示repo版本需要升级,再升级之。邮件附件也有。
    5. 下载后放在/bin下方便调用,sudo mv repo /bin,chmod a+x /bin/repo
    6. 主目录建立cyanogenmod目录,用于放置cyanogenmod所有源代码。mkdir ~/cyanogenmod,cd ~/cyanogenmod
    7. 初始化git本地仓库。
      repo init -u https://android.googlesource.com/platform/manifest
      repo init -u git://github.com/CyanogenMod/android.git -b gingerbread
    8. 下载源代码。repo sync -j32,其中-j是并发job线程,加快下载速度。下载超级耗时,慢慢等……
    9. 完毕!
  2. 安装android sdk for linux
    1. http://developer.android.com /sdk/index.html下载linux版本的 android-sdk_r14-linux.tgz。用tar zxvf 解包。
    2. 配置添加/home/bbn/android-sdk-linux/platform-tools到PATH中,建议放在 /etc/profile,以后root也能访问到adb之类的命令。
    3. 多次执行:tools/android update sdk --no-ui,下载所有版本的android sdk。下载超 级耗时,慢慢等……
    4. 在windows中安装google-usb_driver,使得VirtualBox能访问到android手机
    5. 在debian配置usb驱动,如未配置,不管普通用户还是root用户都会出现以下问题:
      1. 执行adb devices,报:????????????    no permissions的错误
      2. 执行adb shell,报:error: insufficient permissions for device的错 误。
    6. 解决debian下usb驱动,使adb能正常工作的步骤如下:
      1. 在VirtualBox中USB设备中,勾选android手机。可能会需要重新安装windows的google- usb_driver驱动。

      2. 配置udev,在/etc/udev/rules.d目录下增加50-android.rules文件,并赋予/etc /udev/rules.d目录下所有文件a+rx权限,内容如下:
        SUBSYSTEM=="usb", SYSFS{idVendor}=="0bb4", MODE="0666"
        SUBSYSTEM=="usb_device", SYSFS{idVendor}=="0bb4", MODE="0666"
        其中,具体idVendor值可通过lsusb命令获取USB ID,进而可手动编辑50-android.rules文件。

        另:
        1. 不同厂家的USB ID都不一样。如某个USB设备的USB ID为XXXX,则在50-android.rules文件添加:SUBSYSTEM=="usb", SYSFS{idVendor}=="XXXX", MODE="0666"
        2. 如系统启动时出现:udevd : SYSFS{}= will be removed in a future udev version, please use ATTR instead.的警告,则将SYSFS{idVendor}=="XXXX"改为:ATTR{idVendor}=="XXXX"
        3. 如想一劳永逸的方法,只需要在50-android.rules文件保留一句 话:SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", MODE="0666"即可。
      3. 重启udev服务,使配置生效。sudo /etc/init.d/udev restart
      4. 以root用户启动adb server(必须是root,普通用户会报错):adb kill-server,adb start-server
    7. 以普通用户执行adb devices,或是adb shell,即可尽情进入手机android系统中。

    8. 完毕!
  3. 编译cyanogenmod源代码,生成rom。
    1. 连接手机,确保普通用户能正常执行adb命令
    2. 提取手机上的私有配置文件。为了能正常pull所有文件,建议先root手机。
      刷HTC官方1.6版本ROM,会缺少/system/etc/firmware/目录下的brf6300.bin和 brf6350.bin文件。这两个文件从cyanogenmod下载cm_click_full-xxx.zip的rom里面、 /system/etc/firmware目录里面提取,用adb push进去。
      cd ~/cyanogenmod/device/htc/click
      ./extract-files.sh

    3. http://download.clockworkmod.com /recoveries/RomManager.apk下 载RomManager.apk
      cd ~/cyanogenmod/vendor/cyanogen
      ./get-rommanager
    4. 提取手机上的google应用相关文件
      cd ~/cyanogenmod/vendor/cyanogen
      ./extract-google-files
    5. 提取gapps上的相关文件
      cd ~/cyanogenmod/vendor/cyanogen
      访问http://goo- inside.me/gapps/latest,获取最新的gapps。wget -O gapps-gb-20110828-signed.zip http://goo-inside.me/gapps/latest/7
      ./extract-gapps-files gapps-gb-20110828-signed.zip
    6. 生成编译配置脚本
      cd ~/cyanogenmod
      cp ./vendor/cyanogen/products/cyanogen_click.mk ./buildspec.mk,复制编译脚本文件到cyanogenmod目录下,后面编译整个系统用的就是这个文件
    7. 编译环境变量准备
      cd ~/cyanogenmod
      . build/envsetup.sh
      编译adb,如果安装了android sdk则无需使用,否则执行:make -j3 adb(-j是并发job线程),在out/host/linux-x86/obj/EXECUTABLES/adb_intermediates目录下 生成adb文件,将其添加到PATH变量中。
    8. 选择需要编译的产品的脚本
      cd ~/cyanogenmod
      sed -n -e "s/^add_lunch_combo//gp" vendor/*/vendorsetup.sh
      lunch cyanogen_click-eng
    9. 开始编译源代码方法有两种:
      1. 直接编译生成update.zip
        make -j`grep 'processor' /proc/cpuinfo | wc -l` CYANOGEN_WITH_GOOGLE=true otapackage
        如果想提高编译速度,则直接设置-j参数:make -j4 CYANOGEN_WITH_GOOGLE=true otapackage,默认经验值为CPU个数
        执行完毕之后会在~/cyanogenmod/out/target/product/click下生成一个 cyanogen_click-ota-eng.bbn.zip。编译很耗时,慢慢等……
      2. 编译生成Individual.img
        make -j`grep 'processor' /proc/cpuinfo | wc -l` CYANOGEN_WITH_GOOGLE=true
        刷.img文件可以在fastboot模式下进行
        cd ~/cyanogenmod/out/target/product/click
        fastboot flashall
    10. 完毕!
  4. 其他:
    1. debian可能通过apt-get安装了多个jdk,比如:openjdk和sunjdk。
      通过sudo update-alternatives --config java进行更改,方便android编译apk包。
  5. 修改cm源代码
    1. cd ~/cyanogenmod
      vi ./frameworks/base/services/jni/com_android_server_BatteryService.cpp
      修改:setPercentageField(env, obj, gPaths.batteryCapacityPath, gFieldIds.mBatteryLevel);
      为:env->SetIntField(obj, gFieldIds.mBatteryLevel, 100);
      原理:硬件问题导致返回的电量偏小,以上改动让android操作系统强制返回100%,欺骗上层应用。
    2. 重新编译
      cd ~/cyanogenmod
      . build/envsetup.sh
      lunch cyanogen_click-eng
      make -j`grep 'processor' /proc/cpuinfo | wc -l` CYANOGEN_WITH_GOOGLE=true otapackage
      第一次编译很耗时,之后修改后会采用增量编译,很快
    3. 刷机,重启。激动人心的时候到了。
      由于手机开机连着USB线,亮绿灯(不再是未充满的红灯),进入系统检查电量,完美的100%。






2011-10-28

CentOS下Yum安装Apache+PHP+MySQL环境

1.

CentOS 5.2 下用Yum安装Apache+PHP+MySQL环境

2009-04-03 23:47

Fedora 8下用Yum安装Apache+PHP+MySQL环境

fedora8 用yum来管理安装Apache+PHP+Mysql的基本安装。

1. 安装Apahce, PHP, Mysql, 以及php连接mysql库组件。

yum -y install httpd php mysql mysql-server php-mysql

centos安装php插件就是yum install php-*

yum install php-gd 安装图形支持

也可以通过光驱iso安装

mount /dev/cdrom /mnt挂载光驱到mnt

rpm -ivh /mnt/centos/httpd ****.rpm 安装ISO里的包

测试环境

rpm -qa |grep mysql

rpm -qa |grep httpd

rpm -qa |grep php

2. 配置开机启动服务

/sbin/chkconfig httpd on             [设置apache服务器httpd服务开机启动]

/sbin/chkconfig --add mysqld         [在服务清单中添加mysql服务]

/sbin/chkconfig mysqld on             [设置mysql服务开机启动]

/sbin/service httpd start             [启动httpd服务,与开机启动无关]

/sbin/service mysqld start           [启动mysql服务,与开机无关]

3.设置mysql数据库root帐号密码。

mysqladmin -u root password 'newpassword'           [引号内填密码]

4. 让mysql数据库更安全

mysql -u root -p

mysql> DROP DATABASE test;                             [删除test数据库]

mysql> DELETE FROM mysql.user WHERE user = '';         [删除匿名帐户]

mysql> FLUSH PRIVILEGES;                               [重载权限]

5. 按照以上的安装方式, 配置出来的默认站点目录为/var/www/html/

新建一个php脚本:

6. 新建一个数据库,添加一个数据库用户,设置用户权限。写个php脚本测试一下数据库连接吧。

mysql> CREATE DATABASE my_db;

mysql> GRANT ALL PRIVILEGES ON my_db.* TO 'user'@'localhost' IDENTIFIED BY 'password';

//安装apache扩展

yum -y install httpd-manual mod_ssl mod_perl mod_auth_mysql

//安装php的扩展

yum install php-gd

yum -y install php-gd php-xml php-mbstring php-ldap php-pear php-xmlrpc

//安装mysql扩展

yum -y install mysql-connector-odbc mysql-devel libdbi-dbd-mysql

[root@soft bin]# mysql

ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)  

""mysql dead but subsys locked

解决办法如下:

[root@soft mysql-4.1.19]# rm -fr /var/lib/mysql/*

[root@soft mysql-4.1.19]# rm /var/lock/subsys/mysql

rm: remove regular empty file `/var/lock/subsys/mysqld'? yes

shell> killall mysqld

shell> service mysqld start

[root@soft mysql-4.1.19]# /etc/rc.d/init.d/mysqld status

mysqld (pid 5457) is running...

###数据库运行正常;

一、两个重要目录:

  Apache有两个重要的目录:1、配置目录 /etc/httpd/conf;2、文档目录 /var/www:

  

  二、两种配置模式:

  Apache在Fedora下的两种配置方式:文本模式(终端命令行)和图形 化配置。两者各有优势:图形化下配置,更容易上手,在文本模式下直接编辑httpd.conf文件,自由性更强些、更直接。

  三、Apache服务的启动与关闭

  Apache服务的停止、启动、关闭可以通过两种模式下进行操作:文本(终 端)模式下和图形化界面。

  四、终端下的操作

  如果你想用Linux作为WWW服务器,我建议不要安装图形界面(即X window、KDE或GNOME桌面),很显然不安装这些程序,会显著提高系统的性能,易操作性和美丽的界面是要付出代价。我认为Linux的精髓在于 命令行的丰富。Linux的命令可以完成所有任务。

  1、Apache的启动、重启、停止服务:

     cd /etc/init.d命令切换到 /etc/init.d目录,运行如下命令:

     ./httpd start //启动Apache服务

     ./httpd restart //重新启动Apache服务

     ./httpd stop //停止Apache服务

  开机自动启动Apache服务

  cd /sbin命令切换到/sbin目录,运行chkconfig命令,参数:./chkconfig --level 5 httpd on

  ./chkconfig --list可以检查一下httpd开机是否自动启动,如果5:启动,表示开机自动启动。

  2、配置

  cd /etc/httpd/conf命令切换到目录/etc/httpd/conf,用vi编辑器打开、编辑httpd.conf配置,在配置之前,为了防止 配置出错,先备份

<?php

phpinfo();

?>

保存为info.php放到网站目录

然后输入http://ip/info.php看 看测试环境

2安装Apache+php+Mysql#

a.用yum安装前.先是替换为中国CentOS镜像服务器!中国官方镜像网站: http://centos.ustc.edu.cn/  

安装后请按照以下步骤修改CenOS-Base.repo,以后就可以方便的用 yum安装软件了

cd /etc/yum.repos.d

mv CentOS-Base.repo CentOS-Base.repo.save

wget http://centos.ustc.edu.cn/CentOS-Base.repo.5

mv CentOS-Base.repo.5 CentOS-Base.repo

b、更新系统内核到最新. yum -y update

c、安装Apahce, PHP, Mysql, 以及php连接mysql库组件

yum -y install httpd php mysql mysql-server php-mysql

d、安装mysql扩展

yum -y install mysql-connector-odbc mysql-devel libdbi-dbd-mysql

或一次性粘贴安装

yum -y install httpd php mysql mysql-server php-mysql httpd-manual mod_ssl mod_perl mod_auth_mysql php-mcrypt php-gd php-xml php-mbstring php-ldap php-pear php-xmlrpc mysql-connector-odbc mysql-devel libdbi-dbd-mysql

设置mysql数据库root帐号密码

mysqladmin -u root password 'newpassword'

[引号内填密码]

f、 让mysql数据库更安全

mysql -u root -p [此时会要求你输入刚刚设置的密码,输入后回车即可

mysql> DROP DATABASE test; [删除test数据库]

mysql> DELETE FROM mysql.user WHERE user = "; [删除匿名帐户]

mysql> FLUSH PRIVILEGES; [重载权限]

按照以上的安装方式, 配置出来的默认站点目录为/var/www/html/新建一个php脚本

<?php

phpinfo();

?>

配置防火墙4添加允许访问HTTP、FTP端口

iptables -I RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 21 -j ACCEPT

iptables -I RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT

重启iptables: service iptables restart

安装phpMyAdmin)

进入phpMyAdmin官方下载(不要最新版本,下phpMyAdmin 2.11.9.5就行了,3.1以上需php 5.2以上),上传到你的网站目录下,然后进行配置。只需几步即可搞定。

I.

config.sample.inc.php更名为 config.inc.php;

II.

打开config.inc.php文件,进行以下修改:

// $cfg['Servers'][$i]['controluser'] = 'pma';

// $cfg['Servers'][$i]['controlpass'] = 'pmapass';

// $cfg['Servers'][$i]['pmadb'] = 'phpmyadmin';

// $cfg['Servers'][$i]['bookmarktable'] = 'pma_bookmark';

// $cfg['Servers'][$i]['relation'] = 'pma_relation';

// $cfg['Servers'][$i]['table_info'] = 'pma_table_info';

// $cfg['Servers'][$i]['table_coords'] = 'pma_table_coords';

// $cfg['Servers'][$i]['pdf_pages'] = 'pma_pdf_pages';

// $cfg['Servers'][$i]['column_info'] = 'pma_column_info';

// $cfg['Servers'][$i]['history'] = 'pma_history';

// $cfg['Servers'][$i]['designer_coords'] = 'pma_designer_coords'

去掉每行前面的//;

II.

$cfg['blowfish_secret'] = "; |修改为| $cfg['blowfish_secret'] = 'http'

V.

$cfg['Servers'][$i]['controluser'] = 'pma'; |把'pma'修改为你的帐号|$cfg['Servers'][$i]['controlpass'] = 'pmapass'; |把'pmapass设置为你的mysql登录密码|

V.

V. $cfg['blowfish_secret'] = "; | 添加短语密码例如:$cfg['blowfish_secret'] = 'onohot'

6、//安装php的扩展

yum -y install php-gd php-xml php-mbstring php-ldap php-pear php-xmlrpc

7、//安装apache扩展

yum -y install httpd-manual mod_ssl mod_perl mod_auth_mysql

2011-10-11

java keytool使用方法

导入证书
keytool -import -keystore "%JAVA_HOME%"\jre\lib\security\cacerts -storepass changeit -keypass changeit -alias bocommCA -file root.cer
keytool -import -keystore "%JAVA_HOME%"\jre\lib\security\cacerts -storepass changeit -keypass changeit -alias bocommTestCA -file test_root.cer

删除证书
keytool -delete -alias bocommCA -keystore "%JAVA_HOME%/jre/lib/security/cacerts" -storepass changeit
keytool -delete -alias bocommTestCA -keystore "%JAVA_HOME%/jre/lib/security/cacerts" -storepass changeit

显示证书列表
keytool -list -v -keystore "%JAVA_HOME%"\jre\lib\security\cacerts -storepass changeit
keytool -list -v -alias bocommCA -keystore "%JAVA_HOME%"\jre\lib\security\cacerts -storepass changeit

创建证书
keytool -genkey -alias ligitalsso -dname "CN=portal,OU=huangwq,O=ligital,L=BJ,ST=BJ,C=CN" -keypass changeit -storepass changeit

导出证书
keytool -export -keystore "%JAVA_HOME%"\jre\lib\security\cacerts -alias bocommCA -file d:\temp\bocommCA.cer -storepass changeit
keytool -export -keystore "%JAVA_HOME%"\jre\lib\security\cacerts -alias bocommTestCA -file d:\temp\bocommTestCA.cer -storepass changeit

通过证书文件查看证书的信息
keytool -printcert -file root.cer
keytool -printcert -file test_root.cer

证书条目口令的修改
keytool -keypasswd -keystore "%JAVA_HOME%"\jre\lib\security\cacerts -alias bocommTestCA -keypass 123456 -new aaaaaaa -storepass changeit

修改存储证书的证书库密码(JDK默认存储证书的证书库密码为:changeit)
keytool -storepasswd -keystore "%JAVA_HOME%"\jre\lib\security\cacerts -storepass changeit -new 123456
keytool -storepasswd -keystore "%JAVA_HOME%"\jre\lib\security\cacerts -storepass 123456 -new changeit

小公司如何做项目管理(转)

我所在的公司和大多数国内IT公司一样,十几到几十人的规模,每次在做完项目过程中 我们都会感觉累,老板其实也很累,在小公司老板更像是一个项目经理的角色,很多东西都没有流程化 的东西可走,所以很多事情都要等老板拍板后才可以继续下去,员工在很多时候就会感到迷茫,随着公司规模的扩大,公司也意识到没有一套 规范的项目管理方案是万万不行的,自己在这方面也摸索的一段时间。

我 首先接触的是敏捷开发的方法,但很快我就感觉这个方法行不通,至少对于我们是这样,因为我们无法保证和客户以及业务人员及时沟通,一 个月见几次面就很不错 了,而且我们的开发人员也并不具有敏捷能力。后来接触了下CMMI,CMMI对于小公司就更不靠谱了,它庞大的身躯足以把一个小公司 压垮,如果仅为一个证 书的话,我建议完全可以向o6z订购,但不可否认的是CMMI也有很多优秀的地方可以借鉴。那么我对小公司项目管理的看法是一定要精 简,做到不是傻瓜都能 够理解并且能够执行,况且很多项目经理(老板)也并不是领域专家。在此我想简单谈谈我对适合小公司的项目管理方案的一些想法所谓基本适合就是80%适合,我要 是说100%适合那我是在扯淡,另外20%怎么办?那就像06z所说的那样,靠经验这个王道。

首先要谈的是需 求这个东西,那么什么是需求?需求就是掏钱买你产品的人一些需要,只要是客户的需要,不管是合理不合理那都是需求。其实很多开发人员 都意识需求的重要性, 那么真正去做需求的人有多少呢?需求应该是包括需求开发和需求管理这两个过程,这里有个特别的情况是对于自主研发的项目,我接触的项目也是这种情况居多,于 是我 们认为自己就是客户,所以需求开发做很简单甚至跳过去,结果后期的需求管理非常混乱,我觉得既然自己是客户,那就要当好客户这 个角色,在做客户时应完全忘却自己是个开发人员,同样要把需求做全面。很多教科书上都说应该做需求,但 关于怎么做的问题上却和实际情况差别比较大,以下是我关于需求该做什么以及怎么做到一些看法。

1 需求调研

我觉得需求调研非常的重要,1年前我还打算做一个在线教育服务平 台,理念就是淘宝在网上卖商品,我在网上卖教育资源,我提供网上交易场所,签约的老师、学校以及培训机构提供可交易的服务,这种服务可以通过视频、音 频、在线PPT、文本的形式展现。忙活了好一阵,发现这个市场早就有很多人做了,而且这个市场并不是很好做,首先在网上学习的人有几 个?并且先不说前期推广需要海量资金就是所需要的那么些高性能服务器丫也买不起!这件事就此搁浅,结果信了马云的邪,2年后你想 创业你在创业!我觉得这就是典型的需求调研没做好,没有对用户需求做调查,没有考虑同行竞争,没有考虑可行性!另外还要考虑括行业标 准和法律规定,比如前 些时候国家就出台了关于办视频网站的政策,我觉得你丫没有足够的背景就不要往火坑里跳楼。总之根据所做行业情况尽可能的把需求调研做 全面,这样才可以保证 项目首先是可以赚钱的。那么文档要写吗?我觉得可以不要正式的文档,小公司的人手本来就不够用,要把主要文档化工作集中在重要的环节上,对于需求调 研,本来就很杂乱,完全可以记在工作笔记上,放到需求分析的时候整理。

2 需求分析

为了得到用户的金钱,我们总是在说,用户是上帝,用户永远是对的,尽管背地里在说客 户端坏话:"你丫钱给的倒不多,要求还真少,这需求根本不合理,是正常人的逻辑吗?",如果你想活下去,最终我们还是要想方设法满足 用户的要求。用户是个外界因素,我们无法控制, 那么我们只有尽可能改进需求分析的方法来尽量减少不必要的麻烦。那么我觉得日本人做法倒是可以借鉴,在有条件的情况下派专人去现场, 随时记录关键性的需 求,即使不能去现场也尽可能的获取尽可能多大信息,不要指望开发后去获取什么有价值的东西。那么是否应该做个原型给客户看看?我是觉 得这不大合适,因为如 果项目周期短的话,等你做好原型,黄花菜都凉了。但我觉得等到需求做到差不多的时候可以做用户界面,所谓用户界面就是用户接口,是和 用户打交道的地方,所 谓一图解千言,有了界面用户会清楚自己所买的东西在未来会是个什么样的东西,再者开发几个有说明性都界面倒是不会暂用很多时间。等到 需求确定下来后要整理成文档了,这个是很重要的一步,是做设计时候的重要凭证和依据,这 个文档就是用户规格说明书,所谓规格就是有规范的格式和内容。

3 需求评审

我 们已经有了较正规的文档了,那么下一步就是召集所有开发人员开会,最好有客户代表参加,尽管我是很厌烦开会,但该开的会还是要开到, 因为之前我遇到这种情 况,开发人员根据设计文档写代码,可是他并不知道自己在开发什么,站在自己的角度想一下,如果自己都不确定自己做的东西,即使有再完 备的设计,也会对开发 毫无兴趣,只会让自己觉得自己是个代码机器。所以所有人员参加需求评审是让大家知道自己在做一件有意义的事情,自己正在满足社会的需 要,自己在为和谐社会 做贡献,即使你从没那么想过,那你敢保证的你的潜意识没那么想过吗?人是要有社会满足感的吧。另外开会前一定要准备关键有价值的议 题,据我观察需求评审会 最容易扯到不着边的话题,所以主持人要控制话题,会议控制在2-3个钟头,最好做成幸运52的形式,所有人员 一定要互动起来,否则变成了个人演讲。需求也做了,会也开了,那么要求 客户签字吧。

4 需求管理

需求管理是在开发开始之后进行的,这也是另所有人头疼的一件事,之前做完一个项目 后,客户经常打电话找我们,改过来改过去,后我听到电话,血压都要高50个百分点,后来索性就不接电 话,客户就在网上找我,搞的我连QQ都不敢登,但躲是躲不掉滴,客户直接打我手机,丫的真烦人,见过难缠的,没见过这么难缠的。后来 转念一想,难道这种情况真的不能避免吗?至少是可以大幅度的缓解吧。这就是我们需求管理中的变更管 理没做好,改了哪些地方自己都忘记了,最后是跟着感觉走,拆东墙补西墙。在 这里我建议要建立需求跟踪矩阵表,有了这个表我们至少可以对要修改的地方有了依据,迫使我们去调查到底是改什么地方,怎么改,最后改 成了什么样。可能你会 说客户需要大幅度修改原有计划,很难跟踪到具体某一项需求,那么我觉得这是由于前期的需求开发没有做好,在后期客户进行实质性的修改 的几率是很小的,比如 客户要求我们做个OA系统,最后总不会要我们改成个门户网站吧,在举个例子,在比如你开发一个ERP系统,客户自己的业务流程不会轻 易的改变吧,总不至于 把盘点这个业务改成一个报表系统吧。如果真是这样,我们完全有理由告诉客户,你丫乖乖掏银子,我们再给你们开发2期工程,要改,没 门!

在上篇文章里,我简要谈了项目管理中的需求开发和管 理,那么在这篇文章里就和各位以闲话家常的方式讨论下项目规划和项目监控。项目规划、项目监控其实也是项目管理中比较核心的工 作,也是很多开发人员最敏感的话题,因为这两个东西与公司的领导和员工关系都非常的密切。

    先从我以前的学校说起,以前我们学校有片荒地,当时的领导觉得学校应该搞绿化,于是组织在荒地上植树,不到一年换了一个校长,这位校长觉得学校应该抓体育 运动,决定再造一个足球场,于是把树移走,造了一个足球场,再后来北京奥运会来了,学习为了迎合绿色奥运的理念又开始植树,这就是没有规 划和监控的典型例 子,结果是劳民又伤财。当然对于学校来说,有国家财政的支持,有资本这么折腾,可是对于小公司做项目来说,这么折腾几下估计很快就要牺牲 了。

    事实求是的说大多数小公司在这两个方面做得很少有令人的满意的,小公司的老板其实也会意识到公司在项目规划和监控方面做得不咋地,但很少能做到有效的改 进,其实这个也是有很多方面的原因的,以我自作多情的猜测主要有以下两个原因,对于小公司,尽管盈利不是很多,但基本还是可以撑下去的, 老板会觉得管他乱 不乱,公司总之每个月还是有盈利的,少就少点吧,多干几年自己的下半辈子基本有别墅有车了,所以比较保守,要是改革吧,万一鸡飞蛋打怎么 办?还是本分点 好,小心使得万年船。其实是对项目规划和监控其实需要大量的成本,老板觉得钱应该花在刀刃上,搞这些东西就是在务虚。再者更恶劣的老板有 病就乱烧香,就有 想想借助CMMI这个洋玩意治病的,其实很多老板都蛮喜欢CMMI的,CMMI就是假定人就是一个机器的部件,可以替换可以不停的运转, 总之管机器总比管 人省心吧,结果是万分的矛盾,银子撒了一大把,收效却甚微,甚至比以前更乱,大家做的都不开心。与其听咨询师们拿什么高深的方法论来瞎 掰,不如我们谈点实 际的,想就以下议题来和各位消遣。

1 工作量估算

    对于工作量估算很多项目经理(老板)喜欢用数学公式来计算,可能数学公式更加的客观和科学,ok,,看看市面流行的计算方法吧,最常见的是基于代码行的数 学模型,那么这里存在不少问题,工作量估算主要是为了在项目进行中进行有效的项目监控,那么软件开发尚未结束,谁知道最后的代码行有多 大?代码经常会被修 改,那么修改的代码算不算?如果算,那么代码修改越多难道能说明工作量越大?代码效率的区别也是很大的,假如一个10行代码可以实现的东 西被写成50行, 难道能客观的反映工作量?还有2种比较高级点的方法是基于功能点和COCOMO的方法,那么我想问的是它们的公式中的系数该怎么定?那么 不少咨询师忽悠我 说,根据自己的实际情况来定呗,那么我想问的是,算命是迷信,电脑意味着科学,那么用电脑算命算不算迷信?所以我是主张这里还是要靠人的 经验来估算,大家 可以在项目周会上对工作量进行充分的估算,在估算时要同时考虑到项目执行的难度,根据经验给出合理的评估。

2 任务分配

    大多数的做法是将整个项目划分成一个个可以独立执行的原子任务,这些任务要划分优先级和难度,至少心理有个数,并且每项任务要制定负责人。那么问题就出在 这个任务分配上了,软件开发是一项智力创造的活动,如果按CMMI假设的那样,在分配任务时忽略人的因素是万万不可取的,我就有血的教 训,不久之前做一个 ruby的项目,然后开始在公司内部随便抓了几个有点ruby基础的人,也没太顾忌别人的想法。做着做着,觉得他们有点心在曹营心在汉, 平时还是抱着本 thinking in java看,做ruby也是在敷衍了事,结果是代码质量不行,需要大规模的修改。当然按理说员工应该服从公司的安排,做一样就要做好一样,但员工也有员工 的规划,你去叫他做他压根就不喜欢的事只能说明管理有问题。

    另外还有一个普遍性的问题是能者多劳,有个朋友刚进公司动手能力很强,也非常的积极,每次做项目都分给他最难最累的任务,做着做着也就厌倦了,这时老板会 忽悠你说,你能力强,要挑起公司的大梁,以后公司壮大了给你个什么职位,我觉得这就是在扯淡,这就是我经常见到的忽悠式的管理,很多管理 手段完全靠人情, 很多人都是在这种环境中被忽悠长大,到最后怎么样?被忽悠了几年还不是另谋高就了,所以指望人情化管理的公司很难长大。我觉得该讲原则的 地方就要讲原则, 在任务分配上给能力强的分配少而精的任务,而且要考虑到员工自己的想法,有些人想做java架构师,你叫他做oracle dba就不合适,有些对ui设计感兴趣,你叫他做系统分析员也不合适,有些人就喜欢搞技术,你硬要叫他做管理也是不合适。

3 进度管理

    在做进度之前,一项最重要的任务是识别关键任务,很多进度表进行任务安排时将各项任务平均分的特点为觉得极不合适,有些任务比较难处理,而且许多后续任务 依赖于该项任务,那么这项任务就应该配备更精良的人手和充裕的时间,依我的经验80%的时间都是在处理这些20%的关键任务上。这里还有 个比较重要的问题 是时间安排,我听很多项目经理说时间安排要尽可能的紧,也就是比预计要靠前,这样员工才有紧迫感。我觉得这是不可取的,首先即使你按原计 划进行,八成也是 要要延期的,那么这就会导致项目严重延期,长此以往,项目延期成了家常便饭,不延期反而不正常,于是大家都成了老油条,那么进度表不就是 废纸一张,毫无约 束力而言吗!我觉得根据实际情况指定个合理的进度表是比较重要的,或许你会说项目还是在延期,那我觉得是你项目估算没有做好,项目延期在 10%左右比较正 常,否则就可以调查是什么原因导致进度滞后,如果是客观原因,以后完全可以延长项目时间,总之一个合理的进度表比较重要。

4 项目奖金

    这里牵扯到一个钱的问题,据我了解国内大多小公司很少有项目奖金这么一说,年底给点路费就不错了!国内的大多数项目经理更像是一个技术负责人,根本没有用 钱的权利,我就曾像公司申请项目奖金,结果计划全盘泡汤,给的理由很荒唐,说项目奖金不好分配,给张三多一点吧,李四不爽,反之亦然。我 心理暗自想:"你 丫不想给就直说呗!",这里会导致一个问题,就是"项目经理"凭什么约束成员,大锅饭的道理我也不想再解释了,总之结果就是3个月的项目 就得做个5个月, 其实老板的小算盘看似很精明,其实未见得,虽然项目奖金能省就省了,那么工作效率的下降所带来的成本的提高,孰轻孰重?长远一点说,产品 质量的下滑导致的 项目维护的成本你计算过吗?依我的经验,3个月的有效工作时间其实也就是1个月,这已经不错了。不过项目奖金的分配确实是个难问题,但有 没有项目奖金和分 配合理与否是2码子事吧?由于我也没有能耐申请到项目奖金所以也就没有深入研究这个问题,只得望梅止渴,看看人家华为了,员工根据能力分 等级,加上年限、 加班、表现得出个权值来计算。总之现有鸡才能有蛋,这个问题需要更深入的讨论。