10/26/2011

Sharing session under sub-domains in ruby on rails

this could be done by just add the content below to your
RAILS_ROOT/config/initializers/session_store.rb file
ActionController::Base.session = {
:key => 'YOUR_KEY',
:secret => 'YOUR_SECRET',
:expire_after => 180.minutes,
:domain => '.DOMAIN_NAME.com'
}

10/25/2011

app to sd card for android focusing on the Huawei S7

Note: this how to expects some unix or gnu/linux know how.

Things that need to be done before starting.

Have the Android SDK installed (or droidexplorer if you're on windows for adb, as I've got the sdk this howto uses adb on the command line.)

Root the device. This goes without saying, Z4Root is recommend.

Install busybox, this could be done by simple download a busybox installer from the android market

Step 1: Prepairing the SD card.

Note: I have an 8gb sd card, so my examples use this in mind.

Using which ever partitioning program you wish to use, create two partitions on your sd card.

Partition 1 is 7GB and is fat 32 formatted.
Partition 2 is 1GB and is not formatted (we will do this later on the device.)*

*in my case I've mucked up and my ext2 partition is only 400Mb

Now place the sdcard back into the device and boot.

We need to make an ext2 file system on the second partition. This is done via the command line on
the device. So fire up the adb shell

./adb shell

Type the command su to get root privilages, then type the following command:
busybox mke2fs /dev/block/vold/179:2
This will output some data. Once done on the second partition we now have an ext2 file system.

Once this is all done the SD Card is ready.

Step2: Mounting the card, and moving data to the card.

For this step we need to mount the /system partition as read write as this partition is normally
mounted read only. To do this run the following command:
mount -o rw,remount -t yaffs2 /dev/block/mtdblock1 /system
mkdir /system/sd
Then we need to mount the ext2 partition and we can do this via this command:
mount -t ext2 /dev/block/vold/179:2 /system/sd
We need to now copy the data from the data directory to the ext2 partition, as we want to preserve
permissions we're going to use the command tar (cp can preserve partitions, but I've had more issues
with cp not working correctly in busybox I prefer tar:
cd /data/
tar -cvf /system/sd/app.tar app
tar -cvf /system/sd/data.tar data
tar -cvf /system/sd/dalvik-cache.tar dalvik-cache

cd /system/sd

tar -xvf app.tar
tar -xvf data.tar
tar -xvf dalvik-cache.tar

rm *.tar

Step 3: scripts and cleanup.

To mount the ext2 filesystem at boot, we need two scripts. These both go into /system/etc

The first one is called install-recovery.sh and contains the following:
#!/system/bin/sh
#
/system/etc/init-sd.sh&

The next is called init-sd.sh and contains the following:

#!/system/bin/sh
#
MYLOG=/data/install-recovery.log
echo "$(date) Starting install-recovery.sh" > $MYLOG
echo "$(date) Waiting SD to become ready..." >> $MYLOG
sleep 10
mount -t ext2 /dev/block/vold/179:2 /system/sd 1>>$MYLOG 2>>$MYLOG
mount -o bind /system/sd/app /data/app 1>>$MYLOG 2>>$MYLOG
mount -o bind /system/sd/data /data/data 1>>$MYLOG 2>>$MYLOG
mount -o bind /system/sd/dalvik-cache /data/dalvik-cache 1>>$MYLOG 2>>$MYLOG
mount >> $MYLOG
echo "$(date) Finishing install-recovery.sh" >> $MYLOG
now you need to use a decent text editor (I like vi) on windows I reccomend notepad++

copy both of these into /system/etc

for example:

cp /sdcard/install-recovery.sh /system/etc
cp /sdcard/init-sd.sh /system/etc

Now we need to make sure these files are executable with the following commands:
chmod 755 /system/etc/install-recovery.sh
chmod 755 /system/etc/init-sd.sh
Finally, we need to remove everything in the existing /data/app /data/data/ and /data/dalvik-cache
with the following commands:
cd /data/app
busybox rm -rf *
cd /data/data/
busybox rm -rf *
cd /data/dalvik-cache
busybox rm -rf *
now you will notice some odd things happening on the screen of your tablet but that will be fixed
with the command:
reboot
and if all went well you now have all your applications on the sdcard.

9/23/2011

IPSEC/L2TP VPN with OSX client: xl2tpd reports “maximum retries exceeded”

set up a vpn server for my own use, everything went just fine at the beginning,
but these days vpn dial-in don't work on my Mac OS X client, every
time I'm trying to connect my vpn the OS X client keep saying "can not
make connection to the server blah blah.."
here is my server side info:
Ubuntu 10.04 server
IPSEC supported by openswan: Linux Openswan U2.6.23/K2.6.32-317-ec2 (net key)
L2TP supported by xl2tpd v1.3.0
after the connection get failed, I found there's something like this
in my auth.log:
......

Sep 22 16:07:36 ip-xx pluto[14024]: "L2TP-PSK-NAT"[16] 114.xx.193.xx
#57: transition from state STATE_QUICK_R0 to state STATE_QUICK_R1
Sep 22 16:07:36 ip-xx pluto[14024]: "L2TP-PSK-NAT"[16] 114.xx.193.xx
#57: STATE_QUICK_R1: sent QR1, inbound IPsec SA installed, expecting
QI2
Sep 22 16:07:36 ip-xx pluto[14024]: "L2TP-PSK-NAT"[16] 114.xx.193.xx
#57: transition from state STATE_QUICK_R1 to state STATE_QUICK_R2
Sep 22 16:07:36 ip-xx pluto[14024]: "L2TP-PSK-NAT"[16] 114.xx.193.xx
#57: STATE_QUICK_R2: IPsec SA established transport mode
{ESP=>0x0687f589 <0x85b637f3 ......="......" dpd="none}" natd="114.xx.193.xx:4500" natoa="none" pre="pre" xfrm="AES_256-HMAC_SHA1">
it seems like the client made the ipsec connection successfully, so I
tried to restart the xl2tpd server with the "-D" parameter, then I got
the error like this:
.....
xl2tpd[17006]: Listening on IP address 0.0.0.0, port 1701
xl2tpd[17006]: control_finish: Peer requested tunnel 16 twice,
ignoring second one.
xl2tpd[17006]: control_finish: Peer requested tunnel 16 twice,
ignoring second one.
xl2tpd[17006]: Maximum retries exceeded for tunnel 28197. Closing.
xl2tpd[17006]: Connection 16 closed to 114.xx.193.xx, port 53911 (Timeout)
xl2tpd[17006]: control_finish: Peer requested tunnel 16 twice,
ignoring second one.
xl2tpd[17006]: Unable to deliver closing message for tunnel 28197.
Destroying anyway.
xl2tpd[17006]: control_finish: Peer requested tunnel 16 twice,
ignoring second one.
xl2tpd[17006]: Maximum retries exceeded for tunnel 4768. Closing.
xl2tpd[17006]: Connection 16 closed to 114.xx.193.xx, port 53911 (Timeout)
xl2tpd[17006]: Unable to deliver closing message for tunnel 4768.
Destroying anyway.
.....
I tried google the error message then got this article: http://serverfault.com/questions/178309/ipsec-l2tp-vpn-with-osx-client-xl2tpd-reports-maximum-retries-exceeded saying that just need to add the following lines to the conn L2TP-PSK-noNAT section of ipsec.conf:
leftnexthop=%defaultroute
rightnexthop=%defaultroute
now my vpn works great!


8/23/2011

MySQL with ruby on rails on Mac OS X Lion

1, download a 64bit version of mysql for mac at
http://dev.mysql.com/downloads/mysql/
2, install mysql
3, add the following into your .bash_profile:
export PATH="$PATH:/usr/local/mysql/bin"
export ARCHFLAGS="-arch x86_64"
export DYLD_LIBRARY_PATH="/usr/local/mysql/lib:$DYLD_LIBRARY_PATH"
4, install mysql gem by this command:
gem install -mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config

when I was doing all this, I forgot to export the DYLD_LIBRARY_PATH,
and either for the fourth step, I got the following error when running
'rake db:create':
Couldn't create database for {"reconnect"=>false, "encoding"=>"utf8",
"username"=>"root", "adapter"=>"mysql", "database"=>"xxx",
"host"=>"127.0.0.1", "pool"=>5, "password"=>"xxx",
"socket"=>"/tmp/mysql.sock"}, charset: utf8, collation:
utf8_unicode_ci (if you set the charset manually, make sure you have a
matching collation)

hope this may help you :)

8/19/2011

Way to switch your ruby gem version

Here is a common way to upgrade or downgrade your ruby gem
just two simple commands:

1, sudo gem install rubygems-update -v THE_VERSION_YOU_WANT
this will download and install a specified version of ruby gems
2, sudo update_rubygems
this will execute the ruby gems update script to actually update
your ruby-gems

7/15/2011

Command for network state and details

On Windows: netstat -an
On Linux: netstat -tnlp

7/07/2011

Little useful commands of linux

grep is for grep out some line from an input, for some specified keywords

lsof will give you a list of the running processes maps to their ports
which are using

kill is for killing a process, with paramater "-9 [PROCESS_NAME]"

ps will handle the process listing job, often be used with "aux" parameters

3/03/2011

在 Mac OS X Leopard 10.5.6 上安装配置 Oracle 10.2.0.4

第一个步骤自然是下载 Oracle Database 10g Release 2 (10.2.0.4.0) for MAC OS X on Intel x86-64 ,然后解压缩。URL: http://www.oracle.com/technetwork/database/10204macsoft-x86-64-092720.html

之后就是为安装Oracle建立用户组和用户。一般需要建立一个安装用户组oinstall,一个DBA用户组dba,用户oracle,它们都应当具有admin组的权限。在官方文档和一些帖子里都是推荐用dscl增加用户,这需要root权限。更简单的方法就是在系统偏好设置——账户里添加。记得确保该用户的shell是/bin/bash
# dscl . -append /users/oracle shell /bin/bash

安装过Linux平台Oracle的可能知道Oracle对组件和Java环境有一些要求。Leopard上就简单很多,只需要安装DVD里自带的Xcode(当然也可以下载最新版本),并将Java 1.4.2环境放到Java应用程序第一优先顺序就可以了。[MAC OS X 10.6以后没有了1.4.2,后续需要修改一些内容,将在方括号中提示]

下面就是准备系统内核参数了。这里建议大家还是开启root用户。在应用程序——实用工具——目录实用工具——编辑中启用。命令行su到root用户,然后建立/etc/sysctl.conf:
kern.sysv.shmmax=1073741824
kern.sysv.shmall=2097152
kern.maxfiles=65536
kern.maxfilesperproc=65536
kern.maxproc=2068
kern.maxprocperuid=2068
net.inet.ip.portrange.first=1024

重新启动系统就生效了。其他参数在Leopard(10.5.6)下不用更改。具体还可以参考安装文档(在下载的db.zip里就有)。特别提醒一点,如果真的完全按照安装文档上进行修改,有可能会出现这个错误:
TNS-01114: LSNRCTL could not perform local OS authentication with the listener
TNS-01115: OS error 22 creating shared memory segment of 127 bytes with key xxxxxxx
这个问题困扰了我很久,最后进行广泛搜索,受到一个Linux安装求助贴的启发,将kern.sysv.shmmin重新修改为1,就恢复了(文档上要求修改为4096)。

继续看文档,又会发现IPServices是找不到的,不管了,改/etc/rc.common咯,在最后增加:
ulimit -Hu 2068
ulimit -Su 2068
ulimit -Hn 65536
ulimit -Sn 65536

现在把db.zip解压的文件夹放到oracle用户下,并chown给oracle,su – oracle。给自己建立一个.bash_profile吧,可以参照下面内容设定环境参数:
ORACLE_BASE=/Users/oracle/oracle
ORACLE_SID=macora
ORACLE_HOME=/Users/oracle/oracle/product/10.2.0
PATH=/usr/local/bin:/Users/oracle/oracle/product/10.2.0/bin:$PATH
export ORACLE_BASE
export ORACLE_SID
export ORACLE_HOME
export PATH
DYLD_LIBRARY_PATH=$ORACLE_HOME/lib
export DYLD_LIBRARY_PATH
DISPLAY=127.0.0.1:0
export DISPLAY
ulimit -Hn 65536
ulimit -Sn 65536
export NLS_LANG="AMERICAN_AMERICA.UTF8"

如果最后不设置DISPLAY,就会在启动runInstaller的时候报错,提示无法创建窗口。如果不设置DYLD_LIBRARY_PATH就会在创建数据库中提示没有监听器等错误。这些参数需要重启shell环境生效,比如重新su – oracle。



到这里基本就完成了准备工作,命令行进入目录,运行./runInstaller[10.6以后,请手工修改runInstaller,将其中的/System/Library/Frameworks/JavaVM.framework/Versions/1.4.2改为/System/Library/Frameworks/JavaVM.framework/Versions/1.5.0。另一种解决思路是

sudo ln -s /System/Library/Frameworks/JavaVM.framework/Versions/1.5.0 /System/Library/Frameworks/JavaVM.framework/Versions/1.4.2
./runInstaller -J-d32

。后面就和其他平台安装一样了,安装到最后,需要开一个窗口以root权限运行$ORACLE_HOME/root.sh。

安装完成之后可以安装client.zip

安装后配置
(1)如果你的网络配置使用的是DHCP
修改\oracle\product\10.2.0\db_1\network\admin目录下的tnsnames.ora文件
ORCL =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = orcl)
)
)

EXTPROC_CONNECTION_DATA =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1))
)
(CONNECT_DATA =
(SID = PLSExtProc)
(PRESENTATION = RO)
)
)

对应的listener.ora也要做相应的更改
可以直接 netca 来配置, netmgr运行不起来不知道为什么

如何指定'listener.ora'存放的目录?不要默认目录($ORACLE_HOME/network/admin)
方法: 在 '.profile' 中加入(例)
TNS_ADMIN=/f01/oracle11/app/oracle/product/8.0.6/network/admin
export TNS_ADMIN


sqlplus连接: sqlplus "/ AS SYSDBA"


[最后补充10.6一些问题:
如果链接时遇到调用目标 ‘all_no_orcl ipc_g ihsodbc32' 错误,那么不要退出安装程序,直接打开终端,修改文件$ORACLE_HOME/rdbms/lib/ins_rdbms.mk,用#号注释掉$(HSODBC_LINKLINE)开头的行,然后返回安装程序,点击 “Retry”。

Java GUI工具(NETCA和DBCA)运行时也可能出错。那么修改 $ORACLE_HOME/jdk/bin/java脚本,将"java -Xbootclasspath…"改成"java -d32 -Xbootclasspath…"

安装时还可能提示ORA-3113错误,此问题Raimonds Simanovskis通过提供补丁文件解决了。

cd $ORACLE_HOME/bin
curl -O http://rayapps.com/downloads/oracle_ee.zip
unzip oracle_se.zip
chmod ug+s oracle
rm oracle_se.zip

]

2/24/2011

今天开了个巨长无比的会! 居然饿到晚上8点多才让走, 简直是绑架
屋里真热-.-
希望午饭不是面条, 阿弥驼佛!

8/22/2010

About scrum meetings

在Sprint中,ScrumMaster要确保没有任何影响Sprint目标的变更发生。团队构成和质量目标在Sprint中均保持不变。Sprint一个紧跟一个进行,之间没有任何时间间隔。发布计划确定发布目标、具有最高优先级的产品Backlog条目、重大风险和发布所包含的全部特性和功能。

在Scrum发布计划会议上确立一个整体目标和预期结果。发布计划会议通常不超过组织构建传统发布计划的15-20%时间。发布计划会议需要为该发布做产品Backlog条目的估算和优先级排列。

Sprint计划会议的产物是Sprint Backlog。计划会议一般安排整个Sprint周期的5%时间。Sprint计划会议包含两部分内容:“做什么”和“怎么做”。一些Scrum团队将这两部分结合起来。第一部分,Scrum团队处理“做什么”的问题。
产品负责人给团队介绍最高优先级的产品Backlog条目,并一起决定接下来的Sprint中开发什么功能。Sprint计划会议需要输入包括产品Backlog、最新的产品增量、团队的能力和以往的表现。团队自己决定选择多少产品Backlog的条目,因为只有团队可以评估在接下来的Sprint内可以完成什么工作。选定产品Backlog条目后,Sprint目标也就明确了。确定Sprint目标的原因是在功能方面为团队留出一定的回旋余地。例如,上一个Sprint的目标可能是:“通过一种安全、可重获的交易中间件实现客户账户修改功能的自动化”。所以当团队工作时,就会紧记这个目标。为了达到这个目标,团队就需要实现该功能和技术。如果团队感觉实现过程比预期的难度大,那么就可以和产品负责人协商,只实现部分功能。
在Sprint计划会议的第二部分,团队需要处理“怎么做”的问题。在Sprint计划会议的第二个4小时时间箱中,团队需要弄清楚如何将“做什么”会议阶段选定的产品Backlog条目转化成完成的增量。通常团队会先以设计展开工作,设计过程中,团队确定任务,这些任务就是将产品Backlog转化成可用软件的具体工作。任务需要被分解,以便在一天之内完成。这个任务列表就是SprintBacklog。团队通过自组织,并且是自己认领的方式分担任务,任务认领可以在Sprint计划会议上进行,或也可以Sprint中及时(Just-in-time)确定。产品负责人会参加Sprint计划会议的第二部分,为团队讲解产品Backlog条目,并协助团队权衡取舍。如果团队认为工作量过大或太小,就可以和产品负责人重新协商、确定产品Backlog。

新组建的团队常常在这次会议中第一次意识到:整个团队要么一起成功,要么一起失败,没有个体这个概念。团队同时认识到必须依靠自己。正因为意识到这一点,整个团队才逐渐自组织并形成自己的特色,真正成为一个团队。

Sprint结束时要举行Sprint评审会议,该会议的时长不要超过整个Sprint的5%。 评审会议至少要包含以下因素:产品负责人确定完成了哪些工作和剩余哪些工作。团队讨论在Sprint中哪些工作进展顺利、遇到了什么问题、问题是如何解决的。然后,团队演示完成的工作并答疑。产品负责人和与会人员讨论产品Backlog,并根据不同的速率计划出可能的完成日期。接着,整个团体就哪些工作已经完成,同时这对下一步工作有何意义进行探讨。Sprint评审会议为接下来的Sprint计划会议提供了宝贵的参考信息。

在Sprint评审会议结束之后和下个Sprint计划会议之前,Scrum团队需要举行Sprint回顾会议。对于长度为一个月的Sprint,回顾会议的长度一般为3小时。回顾会议旨在对前一个Sprint周期中的人、关系、过程和工具进行检验。检验应当确定并重点发展那些进展顺利的,和那些如果采用不同方法可以取得更好效果的条目。这些包括:Scrum团队、会议安排、工具、“完成”定义、沟通方法和将产品Backlog条目转化成“完成”工作的过程。在Sprint回顾会议的最后,Scrum团队应该确定将要在下个Sprint中实现的有效改进方法。这些变化更适应于经验检验。

About sprint backlog

由于在Sprint的刚开始的时候,增加的任务工作量可能大于完成的任务工作量,所以燃尽图有可能呈上升趋势。

任何人,包括ScrumMaster都没有权利规定团队如何将产品Backlog转化成可交付的功能增量,而是由团队自己确定。每个团队成员利用自己的专业技能,解决遇到的问题。这种协同配合提高了团队整体效率。

团队的构成在Sprint结束时可能会发生变化,每次团队成员的变化,都会降低通过自组织而获取的生产力。因此,改变团队构成时务必要谨慎。

Some basic scrum rules

Scrum的最基本原则是“Inspect and Adapt”(检视然后适应),如果什么事情做得很好,问问自己为什么,然后寻找提升的办法。

一个自组织的团队有一个非常明显的每天的节奏:Daily Scrum之前非常安静,每日站会之后会有一段活跃的讨论,到中餐前的时候就慢慢安静下来了。午饭之后会有另外一个阶段的活跃讨论,当下班前慢慢的安静下来。这就是一个自组织团队的脉冲。如果你能够感受到这个节奏,则说明团队是很健康的,每日站会起到了很好的效果。

1. 需要有全职的有威信,有能力的产品负责人(PO-Product Owner).
2. PO要和Scrum Team、其他的利益相关者(stakeholder)一起工作
3. 有PO来创建和管理产品backlog.
4. Scrum每日站会必须的3个问题(完成了什么,准备做什么,有什么障碍)。
5. Scrum每日站会要在固定的地方时间不要超过15分钟。
6. 有规律的Sprint长度(不超过30天)
7. 在Sprint计划会议上创建Sprint Backlog和经过详细估算的任务列表。
8. 一定要有Sprint的燃尽图。
9. Team必须的设备及相关的供应要齐全。
10. 使用回顾会议确保过程在不断提升。
11. 有明确的对于“任务完成”的定义。
12. 按照合理的速率给出承诺(根据Sprint的工作量估计)。
13. 团队大小在7 +/- 2,最多不能超过12人。
14. 跨职能的团队包括ScrumMaster和PO.
15. 自组织的团队 - 团队成员志愿挑选任务。
16. Scrum master要跟踪进度,并且为团队扫清障碍。
17. 确保Team不被外界干扰。
18. Sprint之间不能间断。
19. 合理的节奏 - 根据固定时间段来确定任务量, 不只是一个进度表。
20. 质量是第一,不需要在质量上讨价还价 - 代码缺陷永远位于Backlog的最上层。

About product backlog

一个完整的backlog是一个的蓝图,可以根据它来把产品改造成为我们期望的样子。
但是在Scrum中,Backlog是根据产品和产品使用环境的演化而不断演化的。所以Backlog是动态的,我们会持续的改变它去确保我们的产品是最合理的,最有竞争力的,最有价值的。

使用用户故事来描述产品Backlog条目是一个非常有效的实践,我们通常也把验收条件或验收测试作为产品Backlog条目的一个属性。

About Daily Scrum Meeting

每日站会和传统的项目会议有如下几点不同:
1. ScrumMaster或者其他任何人来指派任务。
2. 团队成员不是向ScrumMaster汇报情况,而是向其他的团队成员更新和同步信息。
3. 团队成员不会在会上讨论或者解决问题,大家会把问题记录下来,会后找相关的人讨论或召开具体的讨论会议。
4. 任何团队之外的人不得发言或干扰会议。

一个好的每日站会有如下几个特点:
1. ScrumMaster不会逐个的问每个人问题,如果是,那么这个会议已经沦为了报告会。
2. 团队成员互相交流,不是向ScrumMaster报告。
3. 每日站会都会在15分钟以内完成。如果你遵守了规则并按照正确的方式开会,你就不需要再担心超时了。
4. 站会结束后,ScrumMaster知道哪些问题需要帮助团队成员解决。

8/21/2010

零零散散的小东西

在需求定义上,我们需要采用业务导向的需求定义,保证每一个需求的完成都可以交付一定的商业价值。以往的需求往往是功能导向的,但是功能导向的需求对于用户来说不一定具备商业价值,但是业务导向的需求则可以保证这一点

Scrum团队是自组织的. 任何人,包括ScrumMaster都没有权利规定团队如何将产品backlog转化成可交付的功能增量,而是由团队自己决定.每个团队成员利用自己的专业技能,解决遇到的问题.这种协同配合提高了团队整体效率

最后,Sprint回顾会议是用来评审已经完成的Sprint,并且确定做出什么样的改善可以使接下来的Sprint更加高效,更加令人满意,并且工作更快乐

8/03/2010

沟通与管理(1)

好久没丢新垃圾了, 一些看到的见到的有用的东西

------
•在会议上,询问每个团队成员他们喜欢原来团队的什么方面,他们希望现在的团队有什么改变。
•使别人容易地得到你对问题和疑虑的回答。
•组织团队出游,团队出去吃午餐,确保新成员和旧成员坐在一起。
•作为ScrumMaster,确保你花一些时间和每个成员一对一交流,方便观察他们适应新团队动态的情况。

是使团队不受干扰直至Sprint的结尾

•如果在项目中已经太晚了,拒绝向团队中增加成员。
•同时引进所有新人,来减少逐步增加团队成员的成本。
•在团队中混合新人和旧人。
•要求新人使用重构、写单元测试、自动化验收测试来使他们提速。
•让新人和其他开发人员结对。

使用新人其实最关键是两个问题,第一是怎么快速培养新人,能让他们迅速适应岗位,第二是如何留住他们,只要解决这两个问题,新人就可以放心大胆地用

很多人怕新人犯错导致项目出问题,实际上这个问题出在监管上,新人在项目中肯定会犯错,这个时候你需要让一个负责任的老人去带他,起到这个事前提醒事后控制的作用

实际上许多人的离开,并非因为工资的原因,工资确实会导致一个人的离开,但很多时候不是主要原因,特别是对于一个踏入职场三年以内的人来说。他们最需要的是成长和受关注

关于该项目的目的首先要确定,究竟是以设计品质为标杆,还是以时间进度为标杆 — 如果是以品质为标杆,那么在可以接受的时间内,应该无条件的完成产品的设计上的品质要求;如果是以项目时间为标杆,那么可以优先解决产品中最紧急的问题,然后在下一次的升级版本中继续完善设计的部分

如果项目不是那么急,建议可给设计师多留一点点时间,并规划好评审会议与交付件的内容,目标时间应该以一个具体周期(比如一周)作为检查反馈的坐标,而不是整个设计阶段结束后才开始找设计师要东西。让设计师自己提出一个合理的时间,设计经理帮助协调资源(设计经理本人应该清楚具体设计内容需要的行业标准时间)是比较合理的。

作为管理层最不愿意参与的事情莫过于员工的自我管理,如果一个沟通过程(绝大多数情况是某些会议)显得缺乏准备,没有预期效果,那么我建议你最好不要先通知领导参加,否则他只能看到你处理事情上的不成熟

这个问题的最简单解决办法就是在项目开展初期,即明确各个部门的职权与关键点的评审责任,比如:页面实现一定要遵守页面设计效果图,代码效率一定不能低于某款产品的标准,软件开发一定要满足交互设计的预研效果

沟通的阀值是指沟通的心理底线,每个沟通的过程总是会有目的,达到这个目的会影响每个参与沟通的人的心理价位,一般来说,如果你要确定沟通中的有价值的部分,你需要回答四个问题:你的意见或者批评 — “有用的是什么”、“没用的是什么”、“如果这么做,得到什么”、“如果不这么做,失去什么” 如果沟通过程中,你说的话没有解决以上4个问题中的任何一个,那么你说的话基本是废话,没有沟通的必要。

一个关于开发周期确定的问题,可以降低到开发人员配置与项目周期的问题,而开发人员配置可以降低到人员数量和工作时间计算的问题,人员数量的问题可以降低到是不是有资源提供加班补助的问题。

如果你的成员说这个东西没时间做,潜台词就是“你没有给加班工资”,如果你的成员说这个东西有风险,潜台词就是“你给的钱和职位不足以让我承担这个风险”,如果你的成员说这个东西很简单,可以稍后考虑,潜台词就是“这玩意做得没意思,杀鸡不能用牛刀”,如果你的成员说我们慢慢来,心急吃不了热豆腐,GOOD,他可能准备跳槽了。

大部分沟通峰会,如果你注意观察的话,多数人都乐于提出现象,而不是问题本身,比如: 你们市场部不能老这样提出修改,产品都没做完,为什么要改呢? — 这个话根本没有说出问题的关键,问题出在为什么市场部可以提频繁的修改需求?谁给的权利?客户的要求由谁过滤的?修改的成本谁来承担?修改不好谁又来负责?是输入问题还是输出问题?

沟通要保证效率,就得在沟通之前准备好真正的问题,围绕问题,提供解决方法
-----

5/16/2009

The osx update guide for Core2Dual system with EFI

Backup your drivers
Open Terminal
sudo -s
*type password*
In terminal, type:
while sleep 1; do rm -rf /System/Library/Extensions/AppleIntelCPUPowerManagement.kext; done

Open Update Installer
Run update BUT DO NOT RESTART
Go back to your terminal and press Control C to end the script
In terminal type:
nano /System/InstallAtStartup/scripts/1
Replace the line Dont Steal Mac OS X.kext with dsmos.kext
Restore your drivers
Restart and boot with -v
It will start loading and then you will get the message MACH_REBOOT, there you can hard reboot your computer. When you reach the darwin boot screen again, boot with -v again just for safe measure and it will boot fine.

5/13/2009

LINQ expression of Select/Distinct and Count/Sum/Min/Max/Avg

Select/Distinct操作符



适用场景:o(∩_∩)o… 查询呗。


说明:和SQL命令中的select作用相似但位置不同,查询表达式中的select及所接子句是放在表达式最后并把子句中的变量也就是结果返回回来;延迟。


Select/Distinct操作包括9种形式,分别为简单形式、匿名类型形式、带条件形式、指定类型形式、过滤类型形式、shaped类型形式、嵌套类型形式、LocalMethodCall形式、Distinct形式。


1.简单形式:


var q =
  from c in db.Customers
  select c.ContactName;

注意:这个语句只是一个声明或者一个描述,并没有真正把数据取出来,只有当你需要该数据的时候,它才会执行这个语句,这就是延迟加载(deferred loading)。如果,在声明的时候就返回的结果集是对象的集合。你可以使用ToList() 或ToArray()方法把查询结果先进行保存,然后再对这个集合进行查询。当然延迟加载(deferred loading)可以像拼接SQL语句那样拼接查询语法,再执行它。


2.匿名类型形式:


说明:匿名类型是C# 3.0中新特性。其实质是编译器根据我们自定义自动产生一个匿名的类来帮助我们实现临时变量的储存。匿名类型还依赖于另外一个特性:支持根据property来创建对象。比如,var d = new { Name = "s" };编译器自动产生一个有property叫做Name的匿名类,然后按这个类型分配内存,并初始化对象。但是var d = new {"s"};是编译不通过的。因为,编译器不知道匿名类中的property的名字。例如string c = "d";var d = new { c}; 则是可以通过编译的。编译器会创建一个叫做匿名类带有叫c的property。

例如下例:new{c,ContactName,c.Phone};ContactName和Phone都是在映射文件中定义与表中字段相对应的property。编译器读取数据并创建对象时,会创建一个匿名类,这个类有两个属性,为ContactName和Phone,然后根据数据初始化对象。另外编译器还可以重命名property的名字。


var q =
   from c in db.Customers
   select new {c.ContactName, c.Phone};

语句描述:查询顾客的联系人和电话。


var q =
   from e in db.Employees
   select new {Name = e.FirstName + " " + e.LastName, Phone = e.HomePhone};

语句描述:查询职员的姓名和家庭电话


var q =
   from p in db.Products
   select new {p.ProductID, HalfPrice = p.UnitPrice / 2};

3.带条件形式:


说明:生成SQL语句为:case when condition then else。


var q =
   from p in db.Products
   select new {p.ProductName, Availability = p.UnitsInStock - p.UnitsOnOrder < 0 ? "Out Of Stock": "In Stock"};

4.指定类型形式:


说明:该形式返回你自定义类型的对象集。


var q =
   from e in db.Employees
   select new Name {FirstName = e.FirstName, LastName = e.LastName};

5.过滤类型形式:


说明:结合where使用,起到过滤作用。


var q =
   from c in db.Customers
   where c.City == "London"
   select c.ContactName;

6.shaped类型形式:


说明:其select操作使用了匿名对象,而这个匿名对象中,其属性也是个匿名对象。


var q =
   from c in db.Customers
   select new {
     c.CustomerID,
     CompanyInfo = new {c.CompanyName, c.City, c.Country},
     ContactInfo = new {c.ContactName, c.ContactTitle}
   };

语句描述:查询顾客的ID和公司信息(公司名称,城市,国家)以及联系信息(联系人和职位)。


7.嵌套类型形式:


说明:返回的对象集中的每个对象DiscountedProducts属性中,又包含一个集合。也就是每个对象也是一个集合类。


var q =
   from o in db.Orders
   select new {
     o.OrderID,
     DiscountedProducts =
       from od in o.OrderDetails
       where od.Discount > 0.0
       select od,
     FreeShippingDiscount = o.Freight
   };

8.LocalMethodCall形式:


var q = from c in db.Customers
   where c.Country == "UK" || c.Country == "USA"
   select new { c.CustomerID, c.CompanyName, Phone = c.Phone, InternationalPhone =

PhoneNumberConverter(c.Country, c.Phone) };

  


XDocument doc = new XDocument(
   new XElement("Customers", from c in db.Customers
             where c.Country == "UK" || c.Country == "USA"
             select (new XElement("Customer",
               new XAttribute("CustomerID", c.CustomerID),
               new XAttribute("CompanyName", c.CompanyName),
               new XAttribute("InterationalPhone", PhoneNumberConverter(c.Country, c.Phone))
               ))));

9.Distinct形式:


说明:筛选字段中不相同的值。用于查询不重复的结果集。生成SQL语句为:SELECT DISTINCT [City] FROM [Customers]


var q = (
   from c in db.Customers
   select c.City )
   .Distinct();

语句描述:查询顾客覆盖的国家。


Count/Sum/Min/Max/Avg操作符



适用场景:统计数据吧,比如统计一些数据的个数,求和,最小值,最大值,平均数。


Count


说明:返回集合中的元素个数,返回INT类型;不延迟。生成SQL语句为:SELECT COUNT(*) FROM


1.简单形式:


var q = db.Customers.Count();

2.带条件形式:


var q = db.Products.Count(p => !p.Discontinued);

LongCount


说明:返回集合中的元素个数,返回LONG类型;不延迟。对于元素个数较多的集合可视情况可以选用LongCount来统计元素个数,它返回long类型,比较精确。生成SQL语句为:SELECT COUNT_BIG(*) FROM


var q = db.Customers.LongCount();

Sum


说明:返回集合中数值类型元素之和,集合应为INT类型集合;不延迟。生成SQL语句为:SELECT SUM(…) FROM


1.简单形式:


var q = db.Orders.Select(o => o.Freight).Sum();

2.映射形式:


var q = db.Products.Sum(p => p.UnitsOnOrder);

Min


说明:返回集合中元素的最小值;不延迟。生成SQL语句为:SELECT MIN(…) FROM


1.简单形式:


var q = db.Products.Select(p => p.UnitPrice).Min();

2.映射形式:


var q = db.Orders.Min(o => o.Freight);

3.原理:


var categories =
   from p in db.Products
   group p by p.CategoryID into g
   select new {
   CategoryID = g.Key,
   CheapestProducts =
   from p2 in g
   where p2.UnitPrice == g.Min(p3 => p3.UnitPrice)
   select p2
   };

Max


说明:返回集合中元素的最大值;不延迟。生成SQL语句为:SELECT MAX(…) FROM


1.简单形式:


var q = db.Employees.Select(e => e.HireDate).Max();

2.映射形式:


var q = db.Products.Max(p => p.UnitsInStock);

3.原理:


var categories =
   from p in db.Products
   group p by p.CategoryID into g
   select new {
   g.Key,
   MostExpensiveProducts =
   from p2 in g
   where p2.UnitPrice == g.Max(p3 => p3.UnitPrice)
   select p2
   };

Average


说明:返回集合中的数值类型元素的平均值。集合应为数字类型集合,其返回值类型为double;不延迟。生成SQL语句为:SELECT AVG(…) FROM


1.简单形式:


var q = db.Orders.Select(o => o.Freight).Average();

2.映射形式:


var q = db.Products.Average(p => p.UnitPrice);

3.原理:


var categories =
   from p in db.Products
   group p by p.CategoryID into g
   select new {
   g.Key,
   ExpensiveProducts =
   from p2 in g
   where p2.UnitPrice > g.Average(p3 => p3.UnitPrice)
   select p2
   };

Aggregate


说明:根据输入的表达式获取聚合值;不延迟。即是说:用一个种子值与当前元素通过指定的函数来进行对比来遍历集合中的元素,符合条件的元素保留下来。如果没有指定种子值的话,种子值默认为集合的第一个元素。


下面用一个表格总结一下这篇说的LINQ语句













































Where 过滤;延迟
Select 选择;延迟
Distinct 查询不重复的结果集;延迟
Count 返回集合中的元素个数,返回INT类型;不延迟
LongCount 返回集合中的元素个数,返回LONG类型;不延迟
Sum 返回集合中数值类型元素之和,集合应为INT类型集合;不延迟
Min 返回集合中元素的最小值;不延迟
Max 返回集合中元素的最大值;不延迟
Average 返回集合中的数值类型元素的平均值。集合应为数字类型集合,其返回值类型为double;不延迟
Aggregate 根据输入的表达式获取聚合值;不延迟