2010年4月26日星期一

关于人力资源的一些话

    上周被猎头了,虽然没兴趣去,但是还是很高兴。算是对自己能力的一种认可吧。顺便联系了老董,得知原来公司的近况,又看了老赵的一篇文章。觉得有些话犹如骨鲠在喉不吐不快。
    1.程序员是什么人,他们能干嘛
    程序员当然是写程序的人,但是不是所有写程序的人都叫程序员。(耳熟?不是所有特仑苏都叫牛奶)一个程序员,必须能够完整的了解需求,设计系统,构架系统,完成代码,并且测试通过。当然按照现代软件工程,程序员不必亲自做这些事情。甚至更严格来说,要求这些事情不能都由程序员来完成,然而一个程序员是可以做到这些的。在这以下,基本都叫代码工人。
    如果按照以上的标准来衡量,老赵的这篇文章(http://blog.zhaojie.me/2010/04/why-i-say-no-to-aptech.html)里面说到的问题是不言自明的。很多培训机构培训学员使用快速工具,例如eclipse或者vs,基于可视化系统编写项目。这些学员有能力很快的完成一个项目,然而,却无法反转数组。这些“准程序员”所能做的项目,不会超出在培训中所教授的范围。例如如何完成一个论坛,或者如何编写一个博客。问题是,这些教授的内容,都是延续多年的,被反复验证的问题。这些问题,有着最优秀程序员们做出的成熟解答,根本不用这些菜鸟多此一举。
    2.精英和普通程序员
    昨天和猎头说到程序员和精英的区别。现在所有的老板都希望自己的队伍中能有几个精英程序员,然而joel on software里面谈到过,你很难找到一个精英(http://www.ruanyifeng.com/blog/2008/11/finding_great_developers.html)。我的问题是,什么是精英,什么是普通人。
    一个人,要成为精英,需要具备什么条件呢?不是快速产生代码,也不是良好的算法能力。要成为精英,编程能力和算法能力是必要的。然而更必要的是时间-事务管理,沟通和领导能力,名气和知名度,对行业的深刻认识和远见,以及人品。精英最大的价值并不在于写程序,而是能够激活公司内其他人员的能力。例如你可以方便的招聘到其他的程序员,让风投觉得你的团队靠谱,因为他在行业内的知名度很高,有相当的号召力。他可以培育新人,和其他程序员合作,稳定可靠的完成项目,因为他拥有良好的沟通和领导能力。最顶尖的精英可以产生新颖的创意和想法,让你规避可能的风险,让顶尖粉丝围着你转,因为他们在行业内领导性的认识和远见。当然,最重要的是,他是可靠的。
    3.精英一旦聚集,精英就密集
    昨天和猎头谈的另一个问题就是,他们需要精英还是普通程序员。可以想象,他们的标准答案是两个都要。然而我要说的是,精英和普通人在大多数情况下互相排斥。一旦公司或部门中多数都是精英,很神奇的,很快里面全都是精英了。而一旦一个公务或部门中多数都是普通人,那么很难留住精英——很多情况下都变质了。所以最好选择一者,或者为精英们专门成立个部门。
    为什么精英和普通程序员互相排斥?这个问题要分开说。精英程序员信仰简洁的人生,他们一般不屑与笨蛋说话。很多时候你向他们寻求解答,他们往往用一两句话点明这个问题的原因和机理。多数情况下这一两句话相当受用,值得你用几个小时来消化。然而多数普通程序员的问题是根本听不懂他们在说什么。曾仕强说过,一个能干的领导只有一个作用,就是证明你的手下都是白痴。在这种环境下,没有成为顶尖高手资质的,对技术没有狂热热爱的程序员会迅速离开,而有这些资质的程序员会快速的进化成另一个精英。而反过来,让一个技术高手来领导一群普通程序员是一件很痛苦的事情。要么他受尽折磨后离开了这里,要么他就变成了一个领导者。这种情况下他不再和其他程序员沟通技术细节。反之,他利用自己的技术能力建立解决问题的框架,分解问题为一些普通程序员能解决的问题,并丢给他们——而不管他们完成的细节。
    4.为什么要来你们公司
    如果你的公司需要招聘一个精英,那么你需要问这么一个问题。他们为什么要来你们公司,你们公司能给他带来什么?
    程序员工作的最低理由是收入。从收入层次上说,基本有工资,分红,股份三种激励方式,分别对应了短,中,长期合作关系的激励。高工资的激励效果最显著,然而由于你对高级程序员缺乏有效的监控手段(谁来实施?总不能他们监控自己或者互相监控),所以员工很快会怠惰。分红将程序员的收入和一年内或一个项目挂钩,所以能够保证他们采取一切措施,保护自己的收入——同时也保护了你这一年或一个项目的收入。而股份则是将程序员的收入和公司的成长挂钩。然而这些并不是精英们愿意去你们公司的全部理由。
    程序员做到一定程度后,对于非物质条件的要求是很挑剔的。往往我们能听说一个高手谢绝了大公司的工作,或者一些优厚的报酬,其原因往往如此。这些条件包括,部门中的人水准相近可以沟通(我们所说的3),工作自由安排,有自己的时间进行研究(隐含的就是加班很少),良好的工作环境,宽松的制度,等等。通常而言,这些人都喜欢去小公司或者自己创业了,其原因就是因为大公司很难给他们需要的东西。如果你打算招揽一个真正的高手,搞清楚他真的在意什么比一味的开高薪水更加有效。
    5.愿不愿意要培训生或应届生
    昨天谈到的另外一个问题就是,愿不愿意招收培训生或者应届生。这个问题的“标准”答案通常是,我们愿意接受新鲜血液,这些人的薪水具体要视能力而定,如果能力真的出众后期还可以调整。实际上,除非特殊情况,否则听到这这句话,你就应当了解到几个隐含的事实,这些东西往往和你的期望背道而驰。1.公司的压力很高,严重缺人,所以进去后可能会严重加班。2.新人工资很低,而且也没有什么晋升的空间。3.基本学不到什么东西。
    为什么会这样?通常而言,公司不喜欢培训生或者应届生。更准确的说,是不喜欢培训生或者应届生应聘。真正靠谱的应届生或培训生,是靠HR去校园里面抢的。记得上面那个joel on software的文章?他们在校园期间就会脱颖而出,成为佼佼者,很少有校园里默默无名的人出校园后表现出惊人实力的(虽然并非没有)。通常HR会虎视眈眈紧盯这些真正有才能的人,要抢到一个都困难,怎么可能沦落到人力市场上应聘呢?因此如果你真的有才能,请在校园期间就表现出来。否则就需要等费尽周折进入一家公司后才能表现出来,而且很晚才能反应到你的收入上。
    那么,一家公司愿意接受培训生或是应届生的真正原因是什么?多半只有人手不足,而且其中大多数是短期内的人手不足。因此不但可能要加班,而且一旦当人力问题缓解(更加不幸的是在你的试用期内缓解),能力不足的人还可能遭到遣退。是的,无赔偿的,虽然不是你的责任。即使留下来,也是作为一个基础的消耗品。主要的目的是承担大量的杂务工作,并且拉低工程师的薪水。为什么?当有大量廉价工程师存在的时候,工程师的薪水比他们应得的更低。一方面因为劳动力充足,导致自己是否会失业的竞争威胁。另一方面也因为比较性的从众心理,别人的薪水比自己更低,于是就心安理得了。此谓杀价妙方。在这种指导思想下,你的晋升和学习都无法顺利展开的。
    6.做项目,做产品,做团队
    这是整篇文章最大的一个问题。低端做项目,中端做产品,高端做团队。怎么解释?
    最低端的软件产业,依靠的是软件项目实现来获取利润。实际上他们做的事情,某种程度上也可以叫人力资源外包,他们主要通过外包价格和人力资源之间的差获得利润。因此,这类公司的主要特征是拥有发达的渠道和关系网络,拼命寻找高价的,大规模的外包项目。同时借助大量低端程序员,压低人力成本。这类公司永远处于人力缺乏状态,除非公司快倒闭了。
    中端的,大量的软件公司,是依靠对客户的了解,设计创新方案或者增强通用方案,改变原始流程,从而为客户带来好处。他们最大的利润来源是创造性的改变客户的原始流程,如果是互联网公司就是新的互动模式。这类公司的主要特征,是拥有一个强力的营销团队,和良好的售后体系。三流的公司往往试图改变团队来跻身其中,然而由于糟糕的流程设计或互动模式设计,或者用更流行的说法“商业模式”,因此无论其商业团队多么努力,都无法成功进入这类市场。这类公司对技术人员的成本并不很关心,只要小于产品的总收入就好。事实上通常来说,越是代价高昂的精英,往往能越好的完成改善流程,创新,设计,快速完成的过程,从而带来更高的收益。因此这类公司往往都有些牛人,少则一两个,多则一大群。
    这样的公司,从业务来说是完整的,稳健的。然而从公司角度来说却是缺失的,也不是投资者喜欢的。问题在于,公司的成败依赖于少数几个人的激情和努力。包括公司的决策层,主设计师,等等。例如苹果公司的股价就强烈的受到jobs的影响。通常而言,投资者更喜欢稳健的,风险可控的公司。通过一个固定的制度,和可迁移的管理团队,来发现和聚集人才。这类公司才是我们所说的“大公司”,并非规模大,而是构架方式大气,做事方法正规,拥有着成为行业顶尖的可能性(虽然并不一定保证)。一家从外包和产品做起的公司,如果一开始就采用了粗放型管理模式,而没有妥善解决团队打造和管理上的问题。到后期往往是版权纠纷,禁业纠纷层出不穷。或者高级程序员来一个走一个,来的薪水一个比一个高,走的速度一个比一个快。或者干脆树倒猢狲散,公司一拍两散的也有。
    因此,如果一家公司有意做大,请记得在一开始的时候就设计一个良好的团队打造计划和团队保持制度。否则当碰到问题的时候再做转换,往往已经太迟了。

2010年4月10日星期六

用android的usb网络共享上网很爽

什么设定都不需要,直接打开usb调试和usb网络共享,然后插上线路。Linux下自
动出现了usb网络设备,usb0。然后――没有然后了,随便上网吧。各种分享上网工
具可以全扔掉了。

2010年4月6日星期二

关于王江民先生几点

    前几天惊闻王江民先生离世,我说不上是高兴还是难过。按理说,逝者已矣,种种是非也应当随风而去。然而一个人存在过,就必然有存在过的痕迹。我仅从我个人的观点,追述一下江民杀毒的印象。
    我是谁?平凡的电脑用户,95年接触电脑,97-98年刚好赶上KV300L++。然后换用了金山毒霸,04-05年换用Avast。08年换用Linux,因此裸奔到现在。
    在DOS时代和前Windows时代,江民杀毒是杀毒软件中的佼佼者。最初的时候,最流行的杀毒产品是防毒卡。好像当时做电脑的人有硬卡情节,什么产品都搭配卡。汉字系统有汉卡,杀毒系统有防毒卡,就是放个VCD,也有解压卡。Whatever,防毒卡一路很牛,直到DIRII病毒出现。这个病毒直接将自己挂入了DOS的设备驱动链,从而直接修改了系统,这个方法很像现在的Rootkit技术。这个思路直接导致了防毒卡的失效,而KV系列,就是这个时候涌现出来的佼佼者。KV系列的成功,一在于他强大的杀毒能力,二则在于强大的抗盗版能力。当时我也有玩汇编/反汇编,底层编程一类东西。因此很是惊艳王江民先生强大的代码能力。KV系列当时可以查杀几乎所有的病毒,电脑报纸上几乎每期都有专栏,说最近出了什么病毒,大家要扩充防毒码。现在的用户可以想象这种情况么?
    在97-98年的时候,我碰到了KV300L++事件。简单来说,江民公司在KV300L++版本中加入了主动逻辑锁,当满足某些条件的时候自动触发,锁定用户的电脑。无法重装,也无法解除。具体的手法是通过修改硬盘的分区表链,做出一个循环的分区表,导致DOS系统识别失常。必须使用特殊的方法进行解锁,或者联系江民公司,进行书面的原因说明(其实就是盗版举证)。这篇文章(http://hi.baidu.com/inetpm/blog/item/9e7bea0f02e0e9266059f33a.html )中,将此事描述成正版软件商对盗版的战争。对此我表示强烈的抗议,这根本不是事实,而且我强烈怀疑此人是个枪手。我是一个KV300的受害用户,自然很清楚当时是什么情况。上文中有一段文字,我引述如下:

L++事件出来以后,王江民受到围攻。网上各种言论都有,但就是找不到L++事件的真实受害者用户。这一方面是因为L++网络升级版只在网上放了六天,二 是因为正版用户和使用没授权的解密版KV300的用户绝不会受伤害,被锁住机器的是那些在大量生产假冒KV300的盗版商。王江民自信“这个逻辑锁就是这 样准确!“

    KV300L++在判断用户当前插入的盘片不是江民的原始加密盘之后,会释放主动逻辑锁。这就是上文说不会波及正常用户的理由。然而,当时有大量正版用户受到伤害。至少我当时去抗议的时候,看到某个大叔拿着一堆正版包装在那里骂人,全公司都买了正版,为什么锁他电脑。为什么出现异常波及呢?因为KV300L++释放逻辑锁的条件并不是“插入的盘片有某个盗版加密盘特征”,而是“插入的盘片不具有正版加密盘特征”。这两点看似一样,但是实际上天差地别。前者逻辑炸弹很难释放,也很难奏效,而后者就很容易伤及无辜。我中标的原因就是因为搞不清哪张盘是正版的KV300加密盘,把一张游戏盘片插了进去。我相信大多数中标的人也是基于类似原因。
    从更深的层次来说,软件公司有权对盗版用户做出惩罚么?可以,但只能走司法途径。如果允许软件公司私下对盗版用户进行惩处,这就等于赋予软件公司权力来伤害任意个人。因此当年,公安部对江民公司罚款3000元,不再追究。与其说是惩罚,不如说是保护。如果没有这个处罚,我相信江民公司会面临遍地开花的侵权诉讼官司——按照法理,即使盗版用户都可以起诉。因为逻辑锁是未经认定的,因此从法理上说,被逻辑锁锁定的人并不能认定就是盗版用户,更何况这个认定机制根本不准确。只要不去解锁并承认错误,江民公司就无法举证受害者一定使用了盗版。江民公司锁定用户电脑是事实,很容易举证确认,而反过来举证用户使用盗版却很困难。前者是侵权官司,证据全面,法律完善。后者则是版权官司,没有什么确凿的证据,更何况当年连版权法都没有——如果有版权法江民公司更倒霉,版权法规定基于学习目地可以合法使用24小时,这下更难举证。
    何况其中大量的无辜正版用户,其中有很多人被无辜波及。至于后来Windows时代的没落,也不能说和这个无关。上文我看到的大叔,直接赌咒发誓,他这辈子不会用任何江民公司的产品。而江民的KV系列软件为了保持加密优势,在Windows时代还继续使用底层的软驱设备直接编程。先不说稳定不稳定的问题,我01年配的电脑连软驱都没有,用个P啊。直到很后来,江民公司才改掉了这个做法。更严重的问题是,由于后Windows时代,尤其是2000以后,对用户权限进行了严密保护,加上系统API的更新换代。导致杀毒软件技术推翻从头再来,杀毒软件商大洗牌,江民公司从此一蹶不振。现在的新用户也许听说过卡巴斯基,也许听说过瑞星,也许听说过金山,但是有多少听说过江民杀毒的?给别人推荐软件的人自己想想,你推荐过么?
    当然,就我个人感觉而言,王江民是强力的程序员。做事踏实,技术高超。然而任何人都只是人而不是神。他是个好程序员,但不是好的商人。当技术上的领先没有被放到正确的方向,而是向着错误的方向发展的时候,一个伟大公司的没落就无法避免了。

2010年4月1日星期四

Re: [shlug] 以nginx作为subversion前端的一些细节



2010/4/2 Shell Xu <shell909090@gmail.com>
    本文系电脑资料,同步到blog上。小黄姐姐不必看了,可以帮我留个言。
    nginx性能不错,可惜不支持WebDAV,因此没法拿来作为subversion的http服务。于是考虑开一个nginx作为前端,后端就跑一个apache来作为容器。配置这么写的(节选):


这样多累啊,换git/hg吧
 
--
simple is good
http://brucewang.net
http://twitter.com/number5

以nginx作为subversion前端的一些细节

    本文系电脑资料,同步到blog上。小黄姐姐不必看了,可以帮我留个言。
    nginx性能不错,可惜不支持WebDAV,因此没法拿来作为subversion的http服务。于是考虑开一个nginx作为前端,后端就跑一个apache来作为容器。配置这么写的(节选):
=========/etc/nginx/sites-enabled/default=========
server {
    listen   443;
    server_name  OOXX

    ssl  on;
    ssl_certificate  keys/server.crt;
    ssl_certificate_key  keys/server.key;

    ssl_session_timeout  5m;

    ssl_protocols  SSLv2 SSLv3 TLSv1;
    ssl_ciphers  ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
    ssl_prefer_server_ciphers   on;

    access_log  /var/log/nginx/localhost.access.log;
    include             /etc/nginx/mapping-ssl;
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
            root   /var/www/nginx-default;
    }
}
========================================
    打开了一个https的服务,这是当然的,svn传输的数据使用http很危险。
===========/etc/nginx/mapping-ssl=============
location ^~ /svn {
    proxy_set_header    Destination $http_destination;
    proxy_pass          http://apache_svr;

    proxy_set_header    Host            $host;
    proxy_set_header    X-Real-IP       $remote_addr;
    proxy_set_header    X-Forwarded-Host $host;
    proxy_set_header    X-Forwarded-Proto https;
    proxy_set_header    X-Forwarded-Server $host;
    proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
}
========================================
    将/svn下面的所有请求交给apache2。
=====/etc/apache2/mods-enabled/dav_svn.conf=====
<Location /svn/main>
  DAV svn

  SVNPath /var/web/svn/main
  AuthType Basic
  AuthName "Subversion Repository"
  Require valid-user
  AuthUserFile /var/web/svn/main/conf/passwd

  AuthzSVNAccessFile /var/web/svn/main/conf/authz
</Location>
========================================
    看起来很美,但是在使用中会发生502错误,原因是来自文件移动后,svn会使用COPY作为Verb去请求服务器端,这时候发生了这样一条日志:
==========/var/log/apache2/access.log==========
127.0.0.1 - {user} [02/Apr/2010:11:07:31 +0800] "COPY {path} HTTP/1.0" 502 546 "-" "SVN/1.5.4 (r33841)/TortoiseSVN-1.5.5.14361 neon/0.28.3"
========================================
    搜索了一下,这是因为使用https作为http服务的前端造成的,这里(https://secure.bonkabonka.com/blog/2008/01/04/nginx_fronting_for_subversion.html)提到了解决方案,而它又引用了另一个网页(http://silmor.de/49)解释细节。不幸的是,这个细节是错误的。关键在于这句上
LoadModule headers_module /usr/lib/apache2/modules/mod_headers_too.so
    仔细看一下就会发现,mod_headers_too应当是mod_headers。在debian下,应当执行这几条指令。
cd /etc/apache2/mods-enabled
ln -s ../mods-available/headers.load headers.load
    然后,在/etc/apache2/httpd.conf中写入以下内容:
RequestHeader edit Destination ^https http early
    问题解决,Q.E.D。