Shell's Home

Oct 21, 2008 - 1 minute read - Comments

程序生产流程管理的一些想法

程序的生产管理本质上说应当可以纳入生产管理中,然而程序毕竟是一种特殊的产品,因此程序的生产管理也有其特殊性。下面贝壳从小到大阐述一下个人对生产管理的一些想法。当然,30人以上的团队规模贝壳根本没有碰到过,因此就不予置评。 首先我们从软件的生产流程开始论述,当然你可以没有流程,然而你不能没有过程。没有流程叫做不正规,低成本和高效率,没有过程……没有过程我也不知道你怎么做的,直觉? 管理的头一步是计划,软件生产的头一步是调研和需求分析,然后是紧密关联的系统构架,包括构架选择和结构设计。调研的典型情况是回答以下问题,软件为了谁而做(Who),设计周期和维护周期是多长(When),软件的适用范围(When),软件的意义和核心价值(Why),软件要达成什么目的 (What),如何设计达成这些目的(How)。这些问题中,要达成的目的和如何达成是核心。而后通过详细的讨论,得出到底要做什么东西,具备什么功能,以及一些细节问题。这时期形成的是软件需求分析报告和软件需求说明书。需求说明书的尺度是一个很难把握的问题,一般来说,需要灵活对应市场反馈的软件,需求说明书不用过早细化,反之则可以早细化一些。开发人员多,结构复杂的系统,设计说明书必须详尽,反之则可以简单一点。不过如果忽视甚至无视需求说明书,或者将需求说明书仅仅作为一个官样手续的团队,必定会在后面吃大苦头。如果要规避需求说明书,也并非不可以。贝壳会在最后描述一个原型系统方法,来规避灵活和不确定的需求对需求说明书的挑战。然而注意,这只是需求说明书的形成手段,本质上是以程序员和最终用户的互动来清晰需求,同时潜在的让程序员熟悉需求。并非真的不用讨论和细化需求,更不是提倡做项目不出需求说明。 项目的构架选择是在基本明确需求后做的事情,这个阶段主要明确以下问题。是单机软件还是群体软件,C/S还是B/S,.net还是java还是 C,Windows还是Linux。中间是否使用ORM,使用的话怎么设计细粒度表,不使用的话怎么使用冗余设计。结构设计和构架选择互相分离又紧密结合,结构理论上是脱离构架的,然而某些结构就必须适用某些构架(例如如果用了事务明显就不能用mysql,性能会差死),某些构架则要求你特殊设计结构。结构设计是系统一个非常广阔专业而复杂的问题,有兴趣的可以看系统结构和构架的一些书,还有设计模式和UML的,这里就不细说了。 在系统完成结构设计后,就开始系统的编码过程了。而项目时间确定,到这个时候才有依据。粗说是编码过程,其实又细分为构架实现,技术研发,编码,自测试,系统整合几个部分。结构设计完成后,抽象的结构必须经过严格定义才能进行使用,其中进行严格定义并且文档化的过程绝对不要轻率处理。如果是大型团队,应当指定一个人负责结构定义的维护,并指定几个技术骨干来讨论定义,讨论修改。这个人需要处理每一个对结构修改的请求,分辨是否应当修改结构,并且交给骨干团队讨论。讨论确定后,对定义进行修改,修改定义文档,并且通知所有部门进行修改。 当结构定义后,系统的框架模型已经清晰可见了,剩下的就是编码了。可是否能进行顺利编码呢?未必可行。因为实际上会在过程中碰到很多技术问题。例如需要使用以前没有接触过的框架和组件,需要对抽象数学模型提出可行算法等等。这些问题如果不先行解决,后面的编码无法顺利进行,技术骨干的最主要作用就在这里。在他们解决技术问题后(或者,更经常的,在中间提出的问题被他们解决后),系统就进入了编码阶段。编码阶段的代码一般来说会有不同级别的自测试,从最简单的写个小程序到最复杂的单元测试+冒烟测试,按照项目的级别具体分析。不过即使是再小的项目再小的模块,一般写一点代码就写个小片断测试下是否可行是最基本的常识,除非你能保证所有程序不论大小一次写对。在完成自测试后,还需要整合入系统,并可能伴随冒烟测试。如果结构设计良好,这个阶段会非常顺利,甚至不出现什么大的问题。反之,如果结构散乱,不用到客户那里,在这步就会碰到非常大的阻力。 在完成主程序的编码和整合后,项目进入收尾阶段。一般是漫长的测试和后续工作,主要包括叠代测试,性能分析,编写使用手册和编码手册,编写项目的技术分析,系统分析报告和各种材料。在这个阶段最主要是要通过测试,先于客户找出错误,并且逐步修改掉。良好的测试结果应当是逐步收敛的,当你看到一个逐步发散或者不稳定,根本没有规律的测试修改结果时,你的麻烦就大了。这通常是因为没有构架,构架错误,中间有不适应构架的修改,构架变化,核心算法错误,需求浮动太大等根本问题所导致的。当然,在测试的同时还要进行全面的文档化过程。 在测试和交付后项目是否结束呢?恐怕还没有。下面是漫长的客户服务期,需要收集和分析客户反馈,进行持续改进。不过那就是后面的问题了。下面我们按照团队的大小来逐步讨论团队的分配和任务。 首先是从一人团队开始,当然,如果也能叫团队的话。作为一人团队,也就没有什么分工问题。文档化要以轻量为主,方便自己日后理解,除非是客户特别需求。 而后是典型的一个团队,一个PM带几个技术,可能还有外面的美工支援什么的。人数不超过五人,不分组。这里前期的需求/后期文档都要由PM完成,程序员主要注重编码和测试(尤其是单元测试)。如果时间充裕,建议一些专门编码一些专门测试,这样可以有效保证代码质量。互相的沟通以开会为主,信息的沟通要诀是让每个人都知道别人的事情,尽量多的向别人传递信息。 再下面是一个典型的“大”团队,两个PM带四个程序员四个测试,其中有两个以上技术骨干,再加上一个专职美工和专职的UI Design(或者两个美工,基本差不多),8-16人的“大型”团队。说大型是因为这个团队开始内部就要分工协作了,加引号是因为……即使10个人,基本也就刚够分工的底线而已。 贝壳个人建议,除开美工等支持岗位,将这种团队分成三个部分。一个是PM组,负责和用户沟通协调,产生需求文档,盯项目进度,调度程序员,产生用户文档,产生其他材料。这组PM不要求高技术,对于技术建议会用,但不用精通(最好也别精通,业务骨干做PM是非常浪费的)。但是对于沟通技巧,协调能力和领导能力要求非常高,也要求有相当的文字功底。毕竟他们是要和客户沟通的人,要是鸡同鸭讲就麻烦了。和客户产生矛盾,文档写不好,更是麻烦中的大麻烦。由于协调要求非常高,因此PM组强烈建议至少两人,手机24小时开机!建议设立正副职,采取正职负责,副职挂钩的方式。 第二个团队是研发组(Dev),至少一个技术骨干带队。这组需要负责编码,自测试,系统整合,出开发文档,出技术文档。对于他们要求是沟通能力过关,程序编码效率高。对于系统经验,思考方式的全面和独特没有特殊要求。一般经过培训的新程序员就可以在研发组中担任工作。他们年轻力壮精力旺盛,相对编码效率比较高。不过如果有条件,还是用比较有经验的程序员比较好。在系统的整合测试,返工引发的效率低下控制方面会有相当的好处。 第三个团队是测试组(Test),至少一个技术骨干带队。这组要求负责系统的叠代测试和性能测试,可能还要帮助编写用户文档,进行项目实施,培训和售后支持。这组人的要求是工作勤奋(叠代测试的工作量是非常高的),技术过关(否则无法发现一些问题),系统经验丰富,思考问题全面而独特。因此强列建议由最强的技术骨干和一帮能吃苦的年轻人组成。一般来说测试组和研发组的人员比例在1:2到1:1之间。如果小于1:2,那么会发生测试不充分的情况。如果大于 1:1,只要成本允许,到是强烈支持。 最后一个团队(有人算了算……怎么还有),是系统的管理组。负责项目的构架选择,结构设计,时间节点认定,人事事务,开发成本控制,技术研发。这个团队有非常高的技术能力,管理能力和执行权限,一般由主PM,研发组和测试组骨干,客户代表,公司代表(多数和主PM是一个人)组成。主要是要对项目过程的监控,项目中人员权限的分配,核心技术的研究和管理进行处理。这个团队等若公司和客户的联合代表,对项目负全部责任。 对于30人以下的团队,估计可以按照比例放大组规模来使用同样的组织结构。不过如果再大,同样结构就不合适了。这主要是因为同一个组中的信息是互相完全流通的,超过10人的组会造成非常高的沟通成本。这时候一般是分解系统结构,分解研发组和测试组。将一个大型系统分解为两个或者多个独立的部分,让每个组分别研发和测试。这样可以避免每组内的信息沟通成本过高,可对文档的严密性和规范性提出了更高要求。通常来说,拆分方法有按照功能和按照构架。即按照功能划分出一个一个的业务模块,每个组开发一个完整的业务模块。和按照构架层次分为数据库组,业务逻辑层组和客户层组。通常来说,我支持以业务为主的拆分方法。因为此时组已经够大,让一个组精通所有层次不难。但是让所有组全部完整了解需求可就很难了。 对于这种成规模的开发,注重的主要是两点,文档和测试。最高的要求(也是我认为最好的褒奖)是及时的文档和全面的测试。此时的难点在于,研发过程中程序员经常为了修补问题而修改代码,但是忘记修改程序文档。或者需求变更后PM改了需求说明,通知了Dev,但是忘记通知Test。又或者通知了Test,但是忘记修改用户手册。因为诸多文档其实是对同一内容的不同描述,所以相互具有关联性。其中之一变化经常导致其他文档落后陈旧,而且版本不统一。 测试应当贯穿正规研发过程。从程序员实现一个个功能起就应当开始叠代,直到项目完成后。并且bug的管理应当和需求管理合并,成为几个组沟通的核心。测试的时候一定要注意充分测试和叠代测试,不要象微软一样弄出新的补丁补出老Bug的状况。 下面贝壳讲以下系统原型法,其实这个就是业界常说的敏捷开发。系统原型方法是指以构建非常简单的系统,实现非常核心功能的原型系统为基础,逐步推导出正规系统的功能和需求的系统分析方法。主要适用于系统需求不清晰,分析困难,开发周期短,程序员数量适中的项目。如果上述条件不成立,那么建议不要使用原型方法。 原型法的头一步是分析需求,不用说不确定的,就说为了实现业务目的(至少这个应该知道吧?)需要哪些功能。然后实现一个可用的,不用很美观,不用性能优化的系统。有了这个系统后,客户可以逐步分析使用这个系统哪里不方便,而后交给程序员改进。逐步反复,直到客户满意为止。使用这个方法,客户和程序员间,程序员互相之间要保证充分沟通,文档可以容后再写(前期还不确定呢,怎么写?)。主要是注意逐个的需求管理和Bug管理,这正好和我上面说的合并管理对应。使用这个方法的好处是当不清楚需求的时候可以马上做,逐步清晰。过程比较直观,做出来东西比较实用,也节约时间。坏处就是会浪费一定的程序员人力,而且一个没控制好就一直改一直改不知道哪里是头了…… 当前国内软件业企业的几个问题就是,不注重需求,不注重测试,不尊重专业,不尊重规范,不培养人才,不积累技术,不重视信誉,不打算做事。下面贝壳逐个细说。 不尊重需求,一般来说,老板讲的时候都是需求为重的,可当客户需要变的时候,老板很容易同意需求变更(虽然我可以理解,做生意也不容易)。不尊重测试,做程序的非常理解测试的重要性,然而老板却认为那个岗位可以随便找个人来做。实际上,测试是一个非常专业非常流程化非常严密的东西,测试的主管最好是公司里面最有经验的人。同时,还有不尊重专业的问题。并不是说老板干预程序员的决策,而是很多时候老板根本不了解技术骨干和PM,测试的区别。让技术骨干来做策划,或是负责、或者主导和客户沟通,这都是超级缺乏效率的做法。至于不尊重规范,事先划定的流程,在遇到重大问题的时候,往往就变成了废纸一张。到不是说在重大问题前非要坚持僵硬的步伐,可一个项目一半时间都是重大问题,这就过分了把?先说了项目过程中要推进知识积累,推进技术交流,推进这个推进那个,等项目一忙就全飞了。 同时由于程序员的超高流动率,当前中国的程序界有一个非常不良好的风气,公司基本不培养自己的程序员。都不知道公司是否能开到明年呢,培养了做什么呢?这点在大型公司就比较好,无论什么情况,基础的内部交流总是保证的。只要签长约,多数可以弄到一些培训。中小公司不培养人才一方面是没有必要,另外一方面就是没有能力。于是程序员就被迫自我培训,自学或者脱产参加培训。付出了成本,自然要赶快跳到能实现价值(能把钱赚回来)的公司里面去。中小公司为人员流动付出巨额成本,而且很多都根本无知觉。 举贝壳公司的例子吧。因为发展需要,今年年初公司曾大型招人,C#程序员,结果可用者寥寥无几,很多都是浮夸碰运气的。以至于一天面试十多个人,竟然一个备选都没有的情况经常发生。一个人过来投简历,硕士,要价10K多。不说公司能否负担,看了看做的题目,算法题还不错,C#技术,解决实际问题都一塌糊涂。这种人招进来差不多就是研究算法写Paper的主,要做程序还得培训一下。还有一个人,我前周刚刚送走,转眼又回来,估计是批量投简历的时候忘记筛公司了。还有一个项目经理真的是不错,讲起问题来很深入,经验丰富,可老板认为用不到,贝壳一点办法都没有。由于人员仓促到位,我们在开发后期付出惨烈代价!有一个程序员从到岗到离开公司,最大的贡献就是拖了三个多月的进度,因为他连static函数干吗用的都不知道。还有一些人,很适应岗位,可做不到多久就走了(当然,这是有各种原因的,试用和刚满期的人走是比较正常的事情)。问题是,其他人就要重新接手他的事情,等来了人再换手。这样的直接结果是什么呢?如果说项目拖延有一半是因为我们需求没做到位,另外一半就是团队的人才损失。如果在普通项目上碰到类似问题,来的人不能做事情,人员替换率高。那么本来能按时完成的任务就一定会延后,而且分析的时候很难直接表现出来,多数会被认为是工作效率不够高,工作态度不认真之类的(某种意义上也没错,毕竟不能做事的人,不是因为效率不高就是因为做事不认真)。不能留住人才造成的后果,是通过项目拖延表现出来的,使得公司往往失去了隐性可能的良好口碑。这种软性杀伤是非常致命的但是又是难以直接表现的。 如果说不注重人才,还怎么能积累技术呢?人是技术最主要的载体。尽管我们可以通过互相培训,技术交流,技术文档化来积累技术。但是如果没有老员工的指点,那么新员工是很难吸收企业的原有技术体系的。无法积累技术的直接表现有两个,一个是中国企业没有核心技术,另外一个就是掌握技术的人就卡了公司的脖子。可能有人会举出中国有多少专利多少成果。贝壳告诉你,按照贝壳做项目的经验,那个多数都是项目做好了用来表功的牌坊。很多技术都是公司不敢给个人,个人不敢给公司,因为浮动率太高。许多真正有价值的核心技术往往是因为缺乏大公司(或者缺乏人)作为后台,而无法正式的走向商业化运作,更无法走向系统化理论化。因此中国不但缺乏真正的核心技术(我指能解决问题,有实现难度的技术),更缺乏(这点可以确认)系统化理论化的技术体系。而掌握公司核心技术的人往往就能卡公司的脖子,尤其是技术都掌握在一个人手中的时候。并非说程序员都有坏心或者什么的,而是程序员有很多和老板不一样的想法(例如要重视测试,要重视专业等等)。当程序员觉得他是对的时候,为了和老板争辩,往往会使出走人的杀手锏。固然,公司是对产品拥有产权的。可是掌握核心技术的人不在,没有人能继续改进,研发新的产品系列,这不是要公司的命么?这时候老板就处于弱势的一方。从某个事情来说程序员往往是对的,可是从企业发展来说却绝非好事。 最后两个问题则是中国软件业更深层次的问题,不重视信誉,不打算做事。整天就想着前辈一夜暴富的事情,或者谁谁风投成功吃喝不愁的事情。根本不打算花心思将事业做好,而是设法请客招待人拉风投,找人做假买点击量买排名,花钱黑掉对手的网站,盘剥底层员工,炒作一些无聊的事情增加知名度。某种意义上说,这个才是中国软件业最大的毒瘤。

Oct 13, 2008 - 1 minute read - Comments

一件最XXX的事

好像小时候老师经常出这样的题目,不过我每次都没得可写,总觉得那堆事情太假太做作。没想到,我这两天亲身经历了一件很囧的事情。 事情是这个样子的。贝壳前两天玩开心(好啦,我知道很无聊,不过发现一堆N久没有联系的同学,很好玩那),然后突然想到搜索高中同学。首先跳出来的是我们的于飞同学,据记载,不出我们所料,去日本了。然后是一位叫江宁的同学,哪位?贝壳怕自己忘记了某些曾经的同学,所以打算点进去看看她的好友里面是否有高中的朋友,然后发现——这是谁? 她的列表中有一位“阿达”,这位同志刚刚加我,并且和我一样,是赵一搏的朋友,换句话说,是初中和大学圈子里面的。是不是贝壳点错了?还是开心太强大了? 事实证明,都不是,是事情太巧合了。贝壳联系该同志本人后发现,所谓“阿达”,乃是丁之光同学,正宗的初中和大学同学。而江宁同学在牛栏山高中复读,是杨亮和大佟的同学。他们是同事,我发消息的时候正好在旁边,OMG。 够囧了吧?好戏还在后面呢—— 贝壳一时高兴,问,那个秦伯韬你认得么?认得。段旭辉呢?认得。张雷?认得。王巍?认得。朱金辉?认得。许智翔?谁? shit,怎么就是不认得贝壳,俺这么有名的说。 不过此同学认出了我一箩筐的高中同学,于是贝壳自己都混了。然后说——段是在上海念书么?不是。那上海念书的是谁?张雷。(到底谁在牛山混的久啊?)哦——我知道,大佟的男友吧—— 刚刚说完——对面发出了一阵吓死人的叫声—— (贝壳):说错了么?我记得是杨亮女朋友和我说的(不就是刘莹同学么)—— (江宁):张雷很帅的—— (贝壳):小声点,大佟也是你朋友—— (江宁):呃—— (贝壳):好像我记得一起看过他们,那次我去复旦玩,大佟和张雷都来的,朱金辉陪他四中的女友,没来—— 然后对面发出一阵杀气—— (江宁):说,朱在复旦有几个女友—— (贝壳):啊,我又说错什么了? (江宁):我一个姐们,是朱前女友—— (贝壳):(原来是上门讨债的,少说的好)哦,哦,可能我记错了—— (江宁):OOXX..**(省略一堆话,具体可以自行想象),不过你是可能记错了,当时王巍的女朋友是四中的—— (贝壳):。。。(乌鸦飞过)。。。—— 天啊,贝壳不想活了——

Oct 12, 2008 - 1 minute read - Comments

分词算法的具体实践

说到分词算法,可能很多人都很陌生,然而说起百度,google,很多人却是耳熟能详。google,百度在搜索的时候,输入关键词后瞬间就可以得到结果,如果用通用数据库是无法做到的。实行这个加速的关键就是分词算法。例如”项羽是萝莉控”这句句子,我们一般搜索都是搜索项羽,或者萝莉控,萝莉。你见过有去搜”是萝”这个关键字的么?因此系统通过分词,将句子分解为”项羽/是/萝莉控”,去处单字常见词”是”(如果要索引”是”,可以想像有多少文章没有”是”的),我们就得到了项羽和萝莉控两个词。再通过反向关联,建立项羽,萝莉控指向文章的连接,就可以完成瞬间的搜索了(具体原理不说了,只要有一定数据库基础的人都应当能想明白原理)。并且通过关联性,某种程度上也可以提供”是萝”的搜索(带”是”的词,带”萝”的词,相关度最高)。 那么,如何来计算分词呢?方法很多,大家可以在网络上搜索下,贝壳就不赘述了。贝壳现在要说的是这次贝壳主要试验的方向,基于词典的机械分词中的最大分词算法。 机械分词算法是当今的主流,关键原因在于速度问题。虽然正确的分词很有价值,然而如果速度太慢,一样没有什么用处。机械分词一般可以保证 98%-99.5%以上的正确率,同时提供极高的分词速度。而机械分词一般来说,都是基于词典的。主要有正向分词算法,逆向分词算法,最大匹配分词算法。其中最大匹配分词算法具备最高的灵活性,只要你能评价一个切分的优秀程度,算法能把所有可能算出来让你评价。然而大家可以想像,这个是非常耗费CPU的。贝壳在这个基础上,做了一个具体的实现和细化加速。并且有准备做为一个开源项目来长期运作(只要有人有意向接手合作)。 首先我们先说贝壳这个算法的评价原则。贝壳认为,评价原则应当有以下几点。同时也必须要说明,以下原则是无法正确评价所有情况的。不过以下原则在原则正确的基础上比较便于优化。一、无法分析的词最少(这是全局最大匹配的理论核心)。二、匹配出的原子最少(这是保证分词优秀性的指标)。三、匹配出原子的出现概率和最高(这是纯粹没有办法了从概率上提高匹配正确的可能)。 当我们分析一句话的时候,我们可以想像,这句话应当是正常的,可被理解的。换句话说,句子中应当都是有意义的词。那么,在匹配后无法理解的词是什么呢?一种是匹配错误,一种是新单词,一种是单字成词和无意义助词。单字成词的例子有上面的”是”,我们可以通过一个比较小的词典去除。那么,假定词典够大的情况下,无法理解和分析的词越少的组合越正确。而同样一句话,匹配出的原子越少,在搜索的时候效率越高。因此我们有规定了原子最少原则。至于最后一个,在无法分析词一致,原子个数一致的情况下,我们只能通过出现概率来猜测可能性。 然后,现在让我们分析一下分词的特点,并且做一定的优化。首先就从最著名的例子,”长春/市长/春节/致辞”开始。 长春市长春节致辞 首先,匹配算法一定要先搜索到一个出现的词,有词才有匹配优化问题。没有词的话,你试试看分词”嗡嘛呢呗咪吽”。根本无法可分。因此首先我们要计算出一个出现的单词。贝壳是从正向开始计算的(主要是因为词典的加速方法是头索引的)。 *长春*{市长春节致辞} *长春市*{长春节致辞} 好的,我们匹配到了两个,不过这就是全部可能么?不是,否则就变成了正向最大搜索。你可以看看”有意见分歧”。如果从头一个匹配到开始计算,无论如何都是”有意/见/分歧”,而事实是”有/意见/分歧”。因此我们还有一种可能,在头一个匹配到的位置,其实并不匹配。不匹配多长呢?最大长度不会超过最短的匹配词。为什么?我们来看下面一个例子。 *长春*{市长春节致辞} *长/春/(这两个字不是词,而是两个无法理解的字){市长春节致辞} 很明显,后一种分法违背了我们的第一原则,无法分析的词最少。无论后面怎么计算,其最优结果是相同的。在后续结果相同的情况下,头一次匹配到词后,所有可能的跳空(搜索可能的不匹配)最大长度严格小于最短匹配词的长度。 那么是否所有跳空都要搜索呢?也不,我们可以继续剪枝。对于情况”有意见分歧”来说,这个路径是必须搜索的。但是对于我们的例子来说,是无需搜索的。为什么呢?我们看以下计算。 *长/{春市长春节致辞}(下一个匹配是什么?总不会是春市吧,所以应当是"市长") *长/春/市长*{春节致辞} *长春*{市长春节致辞} 大家可以看到,其实这个路径是无需计算的。那什么情况下需要计算呢? 一旦跳空,其跳空后寻找到的下个词的位置必须严格小于最短词的词尾位置。否则就没有搜索价值。具体可以看以下示例。 XXXXXXXNNNNNNNNNNN(X是词,N是无关紧要的) SSSSSSSXXNNNNNNNNN(S是跳空或者跳空后形成的无法理解字,X是词,在这种情况下,无论后面怎么评价,都不影响该匹配被剔除) OK,我们回到例子,刚刚我们说了,有”长”的匹配。但是通过刚刚的剪枝,又被剪了出去。我们下面分别计算两个情况。 市长春节致辞 *市/{长春节致辞} *市长*{春节致辞} 长春节致辞 好,我们先不计算下去了。通过上面的计算,我们发现,在计算过程中经常需要计算同一内容的结果。我们可以想一下,同样的分词,同样的算法,出现的应当是同样的结果。就是说,分词函数是状态无关的算法。通过分解一个单词,得到一个最优结果。那么,我们对于同样的数据,何必需要计算两次呢?贝壳上文中提到过记忆函数,这次就用上了。根据贝壳的试验结果,如果记忆全部词的分解结果,会造成大量的记忆-释放,而内容基本没有用到,造成效率下降。如果只记忆长词的分解结果,往往又会因为太长,大多数句子无法达到长度而根本没用。这中间有个平衡值,具体多少贝壳就不说了。我们可以按照上文的方法计算以下两个过程,得到结果。大家可以自行验证。 春节致辞 *春节*致辞* 长春节致辞 *长/春节*致辞* *长春*节/致辞* 结合上面的过程,我们推算得到结果。 *长春*{市长春节致辞} *长春*市长*春节*致辞* *长春市*{长春节致辞} *长春市*长/春节*致辞* *长春市*长春*节/致辞* 按照上面的评价原则,我们得到了正确的结果。 大家可以看看其他例子,这里着重说一下”有意见分歧”。 有意见分歧 *有*意见*分歧* *有意*见/分歧* 注意,有是单字成词,见可不是。如果见单字成词,做看见讲,那这句话就彻底成歧义句了。可以理解为,有意的要看到(或者让其表现出)分歧。这一般是古文语法。由此也可以看出上述原则在理解古文的时候往往会出现问题。同时还要指出的是,在匹配”长春市长春药店”的时候,会出现以下结果。 长春市长春药店 *长春*市长*春药店* *长春市*长春*药店* 两者的无法理解词都没有,切分数一致,最后硬是因为春药店出现概率低而被筛掉。可见系统有的时候是依赖概率和人品在工作的。 经过上面的原则和算法,贝壳实现了一个python的分词程序,1000行代码,原型系统。90W条词情况下,在AMD MK36上(2G主频)分词效率66K/s上下,具体看分词的选项(例如顺序分词就比较节约资源,分词排除重复就比较慢,启用多线程后在单CPU 机器上更慢),内存使用114M。使用C++写的核心词典后,90W条词的情况下分词速度80K/s,比python的核心词典快了20%,内存70M,节约内存40%。不过可惜,这个核心词典是公司产权,贝壳无权公布。并且贝壳做了一些工作,准备使用分词程序来生成分词词表。这个么贝壳就不准备讲了。前面讲的内容贝壳准备放到试验型站点 http://shell909090.3322.org/split_word/split_show/ 上面去,08年内有效。有兴趣联系我的可以发 mail给我,shell909090+split@gmail.com,欢迎大家试验并提出意见。

Oct 6, 2008 - 1 minute read - Comments

苏博婚礼回来暨python2.6发布

这次10.1算是个大日子,因为我们可爱的苏博终于和他美丽的新娘结婚了。据说两个人相识10年拍拖7年,找的高中班主任做证婚人。实在有点为难人家,到底说高中就好上了呢?还是高中没好上?不过总而言之,他们总算结婚了。具体苏博是怎么被我们蹂躏的,以及婚礼的起因经过什么的就不写了,毕竟我不是新闻记者。这次就写一些有趣的事情和感想。 首先是去震泽的车子,因为10.1的关系,并不怎么好去。不过坐在车上晃晃悠悠两个小时,看旁边的河跟路一起走,感觉还是很不错的。江南不愧是水乡,有条河就在我们的路旁跟了10多分钟,还有条船跟我们并排跑。震泽古镇也很灵的,宝塔街古香古色,保证没有现代元素,除了大头发现的几个公共厕所外。建议大家有空可以去看看,苏博的家乡。 而后是新郎和新娘的一个让我比较震撼的问题。婚礼上,主持人问新娘的大学同学,是否在校园里面经常看到新郎。人家说,一直以为苏於良是南大学生。我吓一跳,南大啊,我一直以为王苏瑾在上海念大学。由此我得到一个结论,远距离恋爱是否会失败,和双方爱对方的程度无关,而和双方把爱付诸行动的程度有关。其实不光远距离恋爱,婚姻也是一样。认识我的人都知道我的两个总结。夫妻双方性格相近或相反,价值观一致。今天看来还要加一条,愿意将爱付诸行动。 然后是婚礼前一天,阿丁同学打过来跟我哭诉她和她男友的情况。实话说,虽然被哭诉半天,但是我还是搞不清楚她和她男友的状态,总之是非常复杂一团浆糊。因为隐私关系,我不打算说她和她男友的具体状况。不过大致就是她很喜欢他男友,喜欢到没有自我没有尊严。他男友呢,则是有点——不知道怎么说。说有问题吧,说不出来,说没有问题吧,情况确实——不怎么好。而且她本人处理事情上也不是没有问题,我觉得这个应当叫孽缘吧。不过无论如何,我的建议是——分手。 然后我就建议阿丁同学到震泽来玩一天,反正黄禹同学正好没来。然后她跑来玩了一天,回去和我说了一句雷晕人的话。我彻底无语了—— 无论如何,那是她的家事。 再后面就是苏州到上海的车,同样也不怎么好弄。我问今天又没有去上海的车,最好是动车。回答说有,动车。我说来两张票(帮人代买一张),售票员说,晚上11点半的哦~~ 我彻底无语。 后面一个朋友则更悲惨。他问,今天到南京的车票还有么?没了。明天的呢?也没了。后天的呢?我们只发售今明两天的~~ 最后我们坐大巴回来的。 最后的最后,说一下,python2.6发布了,虽然我不打算用。比以前在构架上有了不少进步,不过很多东西暂时没有这么快迁移过去。我打算等3.0出了后直接用3.0,反正程序是一样写的。

Sep 24, 2008 - 4 minute read - Comments

VeryCD版电驴(eMule)存在封锁

eMule是一个GPL程序,所以VeryCD的改版必须公开源码。今天听说VeryCD版有封锁的现象,所以贝壳抓源码来看看。如果大家认为老调重弹的话,不妨把文章拉到最后。 源码从此处下载:http://www.emule.org.cn/download/ 最下方链接:http://download.verycd.com/eMule-VeryCD-src.rar 贝壳下到的文件大小13,703,064字节,打包时间2008-09-11。经过贝壳查找,在eMule-VeryCD-srcsrc WordFilter发现两个文件,WordFilter.cpp 2008-03-12 09:57 13374和WordFilter.h 2007-11-20 17:56 1009。仔细阅读里面,发现有以下内容。 void CWordFilter::Init() { HANDLE hFile; DWORD dwRead; int nLen; BOOL bResult; CStringList list; //m_count = 0; CString saaa = thePrefs.GetMuleDirectory(EMULE_EXECUTEABLEDIR) + FLITER_FILE; CString sbbb = thePrefs.GetMuleDirectory(EMULE_CONFIGDIR) + FLITER_FILE; // 如果文件目录不对,程序移动一下,到config目录下 added by kernel1983 2006.07.31 if (PathFileExists(thePrefs.GetMuleDirectory(EMULE_EXECUTEABLEDIR) + FLITER_FILE)) MoveFile(thePrefs.GetMuleDirectory(EMULE_EXECUTEABLEDIR) + FLITER_FILE, thePrefs.GetMuleDirectory(EMULE_CONFIGDIR) + FLITER_FILE); if (!PathFileExists(thePrefs.GetMuleDirectory(EMULE_CONFIGDIR) + FLITER_FILE)) { // 不存在,所有的都过滤 added by kernel1983 2006.08.08 m_filterall = true; return; } // Open file for read hFile = CreateFile(thePrefs.

Sep 23, 2008 - 1 minute read - Comments

百度、官员辞职和特供局

这几个东西有什么联系?其实没什么大联系,只是同样是没用的东西而已。 先说百度吧,大家可能不知道,google的一个原则就是“不作恶”。简单来说,不因为人为的理由而改变搜索结果。包括调整排名,屏蔽关键词等。google卖的关键词和百度不大一样,百度的是改变搜索结果,google则是在旁边显示广告栏,其显示特征明显不同于正常搜索结果。从商业角度来说,卖排名当然不如卖广告收入多,但是google的收入却比百度高很多。我以前也完全无法理解google费力坚持不做恶的理由,更无法理解为什么google的收入会远远超过百度,然而这次却明白了。大家应当听说某奶粉品牌300万搞定某搜索引擎的事情吧?当然,某搜索引擎否认了,我们也没有什么证据来说明这次的却是被搞定了。但是,百度卖排名是事实,卖关键词屏蔽也不是什么很难理解的事情吧?也许这次没有被搞定,然而在卖屏蔽却没有什么异议。然而如果这么说的话,那么百度,无疑就成为了遮盖大众知情权的帮凶了。当然,同样的问题google并非没有。google在进入中国后,和政府达成了协议。部分涉及国家的敏感词汇被封锁,大家可以看google最下方的提示。“据当地法律法规和政策,部分搜索结果未予显示。” 如果出现这个,就代表你的关键词有问题,部分内容被屏蔽了。作为进入中国的代价,我们理解这种事情。然而即使是这种程度的改变,依然被很多google的 fans质疑,认为google背叛了“不作恶”的原则。大家可以想想,一个搜索引擎受到国家约束而被迫改变结果尚且要引来怀疑。这时候,一个可以用钱买卖,结果改来该去的引擎,有用么? 因此我强烈的建议大家,使用google的搜索引擎。或者说,当你需要知道什么事情,怀疑什么事情,而这个事情又和强权的利益相关的时候,请使用google搜索引擎,因为百度可能被“买通”了。你不知道你搜索出来的“最有名”的培训公司是否真的好(这是我一个朋友的真实例子,他所在的培训公司就是打的百度排名,但公司有严重问题),你不知道你“搜索不到”有问题的词是否真的只是因为你个人的问题(例如这次的三鹿)。当你搜索到的东西其实只是一堆利益的集合的时候,我觉得这个搜索引擎也就没用了。 我当然不是对百度有意见,也不是对国产有意见。我本人就是中国的程序员,也有朋友在百度任职。然而中国的公义(好吧,这个词大了点)是不能因为利益而含糊的。说的更准确点,当你为了利益而含糊公义的时候,说不定你的儿女正在喝三鹿奶粉。 下面讲讲官员辞职。这次溃坝辞职的孟学农,其实是第二次辞职了。头一次是因为在北京,非典处置不力而辞职。这次又在山西,因为溃坝辞职。中国官方的解释是,孟学农的两次辞职为做太平梦的太平官敲响了警钟。然而贝壳要问,为什么辞职了两次? 大家理解官员辞职,基本就是,辞去职务。辞去后干什么?我们并不清楚。当然,辞职后又重入公职,说起来也不是不可以。但是,这样真的可以么?有人可能说说法规并不反对,但是我想问,一个已经有了明显的处置不力前科的人,为什么那么容易的又进入了公务员队伍呢?难道中国对农村户口的人进入公职防范的那么严格,对有处理问题不力前科的人反倒不必防范?辞职,下台躲躲风头,学学陈冠希,事情走了再出来,损失的只是以前积累的名气,是不是太容易了?进一步说,这次因为三鹿辞职的某些官员,下次又准备在哪里任职呢?大家明天又想喝些什么呢? 当然,还有一个更坏的理由,就是这些人因为没有背景,被屡次作为代罪羔羊。为什么说比辞职重新担任公职更糟糕呢?因为这代表真正应当负责的人屁股都不必动。辞职重新担任官职,好歹还有躲风头的时间,还要损失自己的名气和政绩。作为官员,在做事情前还是要想想这个代价的。然而花钱弄一堆不做事的替罪羊养起来,出了问题就让他们辞职顶罪,然后再给他们重新安排一个替罪羊的职务。这连想代价的时间都省了,反正这帮人的工资是国家支付,人民出钱。拿人民的钱来糊弄人民,没有比这个更好做的决定了。如果真的碰到这种情况(当然,这只是贝壳的猜测),那官员问责机制就会从“没什么用 ”彻底变成“什么用都没”。 最后一个,讲讲特供局。特供局的意义相信大家都清楚,就是给皇帝弄贡品的单位。这种局弄出来,肯定要被大家骂的。当官的只管自己吃喝好,不管老百姓生死。有人还这么说,只要特供局存在一天,当官的就不会真正在意老百姓的生死。只要产品安全到家了,总理可以在大街上随便买个番茄吃了。在这里贝壳不打算讨论政府和食品安全问题,只是想问另外一个问题。让一帮人浮于事吃拿卡要的家伙负责另外一帮同样家伙的食品,有用么? 以前给皇帝拿贡品的时候,下面的经手太监经常吃拿卡要雁过拔毛。只要给一定的好处,就可以打上贡品的标签。多收了是朝廷付钱,好吃的自己先吃掉,反正皇帝也不会来查——要是他有这个空,肯定自己来管了。最后经常会出现朝廷的采买太监吃的比皇帝都好的现象。同样的事实难保不会再特供局出现,毕竟东西经过特供局后一般不会再交付其他部门检查。那特供局完全有可能检验一下,扣下一些特别好的,收钱定贡品。反正只要交上去的东西没问题,就没人问他们负责。

Sep 22, 2008 - 1 minute read - Comments

紧急修复

贝壳周四的时候收到消息,烟台的系统崩溃,于是在24小时之内走了一趟天堂和地狱间的旅行。 开始的时候,贝壳在查一些业务有关的资料。期间和一个同事开了几句玩笑,但是发现他一脸便秘的样子,和我说没空。贝壳很郁闷,怎么这么没面子?过了几分钟,事情就发展成贝壳也一脸便秘的没胆子了,原因是烟台的系统崩溃。由于远程无法连接,只能让客户去机房重起整个系统。可重起后也没有反应。于是贝壳怕了,马上通知了老板。老板马上做了决定,要我们当时飞去烟台,并且在几分钟内给我们搞定了机票。于是在贝壳头处理紧急问题的时候,就受到了”飞机-出租- 零反应”的待遇。 中间首先要感谢一下给我们做Oracle技术支持的纪锋老师,这次如果不是他的大力协助,恐怕问题不会这么快解决。我们在零时间往烟台赶的时候,纪老师也马上打车往机场走。我们是五点接到的问题通告,五点半就联络好了各种问题,乘公司的车子往机场走(主要怕下班高峰不好打车)。六点多点的时候,我们拿到了登机牌,去做安检,然后顺便讨论起问题原因。当时认为基本不可能是软件问题,因为软件问题重起后基本都可以解决,也不会弄的机器停机(这个最终被检验是正确的)。可能是维护问题或者硬件问题。按照机器安装时间来计算,硬件问题的可能居多(系统才刚刚交付几个月)。 飞机是8点50在烟台落的地,落地后我们心急火燎地坐出租往报社赶。车刚出机场,收到一个消息,问题消失了。我们顿时安心很多,要是问题继续出现导致更严重问题,怕我们全都吃不了兜着走。现在,虽然我们还要去找出根本原因,可总比被客户拷问着检查系统来的好的多。到了报业后,我们先检查了系统。第一个被发现的问题是备份机已经满了,怎么会这样?系统的设计容量是三年500G,按照现在的数据量估计,最高不会超过30G,可备份机上足足有100G的空间!我们倒推了数据,发现备份要用140G以上的空间。怎么会这样呢? 原因我们没有找到,不过按照纪老师给出的原因,是备份的时候大量的归档日志造成了数据量暴增。但是备份暴增怎么会造成系统不能访问呢?贝壳陷入了奇怪的感觉中。虽然直觉上觉得就是这个理由,但是实际上却无法确定。按照我和同事说的话,如果用这个理由来说服我,是无法说服的。但是如果在目前让我给出一个理由,恐怕只有这个了。当天比较晚了,因此没有进一步分析,只是让纪老师调整了备份策略就去睡觉了。 第二天,贝壳仔细检查了所有的系统日志,找到了真正引发错误的理由。Linux9号错误,原因是因为文件无法访问。可是,究竟为什么造成9号错误呢?又是为什么导致重起后错误不消失,过后错误又莫名消失呢?进一步分析日志找到了这后两个问题的理由,客户重起节点1未完成时,直接重起了节点2。RAC似乎在所有节点同时失效后无法自动重连,即使重起也不行,必须重起客户端。最后按照数据倒推,认定问题在本地磁盘耗尽上。只是开始为了检测数据库备份,执行了 crosscheck,释放了部分磁盘空间,因此查不出来。 从这次事故恢复来说,最大的问题在于客户那里没有人及时进行系统维护,最终导致了磁盘耗尽。因此说做一个系统简单,然而要长期维护系统,恐怕就没这么简单了。

Sep 15, 2008 - 1 minute read - Comments

中国又出事了

这次是毒奶粉,08年真是多事之秋。贝壳分析了下,估计会进入世界十大事故的行列。 有这么严重么?有。到底有多少奶粉有毒?有多少流入了市场?有多少没有追回?当局能统计出来么?统计出来你信么?如果统计不出来或者你不信,那么我说有可能被做成了月饼进了你的肚子,或者被北京的残奥运动员吃了,你信么? 三鹿的销售体系,是很难统计出最终消费者的,因此我们对比台湾统计的结果。台湾从三鹿进口了有问题的奶粉1000袋,有600袋上下剩余,400袋上下销售,其中没有一袋是进入婴儿市场的,全部被做成食品进了大众的肚子。按照这个比例计算,三鹿出问题的没出问题的奶粉,到底有多少被做成食品,进了你我的肚子呢?谁也说不清楚。月饼,面包,冷饮,这些我们每日要吃的东西里面到底有没有问题呢?谁也不好说。毕竟现在食品成本上升,使用廉价的奶粉来替代昂贵的原料,恐怕是很多企业的第一选择。 这次风波问题更大的在于,还有很多残奥运动员在北京,他们的食品呢?你我当然知道,他们是吃不到廉价的奶产品的。问题是,他们是否愿意相信呢?如果这个问题没有一个很好的解答,恐怕中国这次的运动员餐赔本卖吆喝要变成赔本卖骂名了。 还有这次问题的发生原因,按照三鹿本身的说法,是不法分子造假。那么不说出问题的总数是多少,三鹿说过,召回有问题奶粉700吨。就贝壳看到的资料,原奶和奶粉的质量比大约是8:1。按照这个比例,三鹿有问题的原奶大约是5600吨。这么大量的奶就完全没检查?如果说是部分有问题,到底多大比例?比例低了是不会造成影响的。高了,高了还是得问有没有检查。还有,一个企业,不同产品使用的奶源不一样么?如果一样,为什么只有特定产品出现问题?如果不一样,这会造成成本的升高,为什么不一样? 另外,三鹿集团在这次的危机公关上有严重问题,石家庄当地政府加重了这个问题,而国家又放大了这个问题。三鹿集团说八月已经发现问题,开始召回奶粉。那九月初问题刚发现的时候,发表三鹿奶粉产品质量没有问题的声明是怎么回事?奶粉召回,有没有通知消费者?(也许是中国没有这个惯例,我和一堆朋友说的时候,他们都一脸惊诧,召回产品要通知消费者么?)有没有统计影响面?国家的质管部门呢?免检产品是否真的不需要抽检?那质检是怎么选免检的?口碑?口碑怎么评价?质量历史?企业质量没有问题历史才是常规,有问题历史的要着重查。如果免检产品真的免检,那质检部门有什么用处?如果食品质量有问题造成生病归卫生部门管,那么飞机质量问题造成坠机是否归国安部门管,汽车质量问题造成车祸是否归交通部门管?质检证书造假是否应当归公安管? 实际上,这次事件引发的最严重的问题,在于政府,质量检验体系失去了共信力。根据调查,92%的人不会再选择三鹿的任何产品,6成以上的人对政府质量体系持不信任态度。那么,这次政府说没有对你们造成影响,你们信不信?下次,政府说你们的房子没问题,你们信不信?如果不信,大家准备吃什么?喝什么?

Sep 10, 2008 - 1 minute read - Comments

语言的对比

最近贝壳在学(或者准备学)三门语言,python,ruby,scheme。全部都是高级抽象语言,都是脚本语言。加上贝壳本身已经非常熟悉的几门语言,C/C++,Java,Asm,bash,贝壳这次是正宗的要”精通”七门语言了。当然,如果加上勉强会用如vb这些,十多种也不成问题。做为一个学了多种语言用了多种语言的程序员,我想写一下自己多这些语言的认识,作为后来者的参考。 首先是C,当然,是不包含C++特性的C。这门语言可以说是贝壳所见的语言中,最强大最广泛最具备生命力的语言。其他任何一种语言说到混编接口,基本就是C语言接口。C语言也可以模拟非常多的特性,COM,C++,都可以用C模拟。当然,模拟的复杂程度是另外回事情。并且可以编写其他语言的解析器/虚拟机,而这点来说其他语言很难做到。其实本质上说,C语言就是跨机器跨平台的万能汇编语言,所以才具备这些强大特性。C的核心思想是指针,其整个语言构架都是基于指针的。通过指针,我们直接操纵着内存地址的读写。当然有利必定有弊,C语言太难掌握,效率太低了。使用C写代码,就是和机器打交道。你得控制数据的读出写入,控制设备的初始化,控制内核交互。根本上说,一个强大的C程序员,并不强大在算法和创意上,而是强大在对系统的方方面面的了解上,强大在对基础原理的掌握上。 其次是C++,说实话,这语言有点高不成低不就。如果要掌握系统的方方面面,他不比C。如果要抽象要构架要快速要敏捷,他比不上所有的抽象语言。但是 C++的长处在于在系统的层级上引入了算法抽象,增强了编码效率。如果你确定需要在系统层级上编程,又不高兴从C的角度去写。C++可以极大的增加你写代码的速度。当然,他的弊端就是对底层的掌控力和抽象实现的复杂程度。C++(我指的当然是包括STL和Boost的)的长处在系统层级,所以你写代码的时候必须了解抽象的实现方式。然而抽象实现的越强大(例如boost的share_ptr),其底层的机制就越复杂,你掌握的时间也越长。而如果不了解底层,往往会发生很多很奇怪的问题。例如smart pointer的问题,在其他语言中,这是语言系统的bug。而在C++中,则是你自己的问题。因此,想要真正玩好C++的程序员,必定首先是一个C高手,而不是拿着C++的OO特性把C++当普通OO语言的人。 再次是Asm,这种语言可以说没有什么生命力,因为他变化的太快了。一旦硬件构架改革,汇编就要调整。而且抽象层级不够高。除非你正好做操作系统底层,编译器优化和系统破解,否则最好不要考虑这种语言。这种语言的核心构架是寄存器。 然后是java,当然,还有很类似的C#。这类语言开始,语言的抽象层次提高了,因此可以提供反射(python中叫做自省)。反射是高级语言中必要的特性,然而C/C++并没有提供,原因么则必须说一下编译型和解释型语言。一般语言分为编译型和解释型,编译型的代码成型后只需要相关的库支持(其主要目的是代码复用减少复杂度和内存消耗),而解释型的语言需要解释器。如果仅仅从方便使用角度说,解释型语言远远不如编译型(因为要单独安装解释器,当然,像 bash这类怪胎就表说了),而且解释型的语言运行效率仅有编译型的1/10左右。然后当今语言界,编译型语言远远比不上解释型使用广泛。其根本原因有三个,一个是编译过程,一个是反射,最后一个就是内存管理。 如果读者有编译代码的例子,应当知道,除非在同等的条件下,否则编译C++代码是很麻烦的事情。而配置同等的编译条件则彻底失去了C++跨平台的意义。因此C++在不同平台下反复编译的时候,需要考虑大量的问题来达到跨平台的目的。往往这种事情麻烦到需要作者亲自指导编译的地步。如果一个软件,发布的时候声明可以跨平台,然而使用前需要作者指导用户做一堆繁复的操作。估计这个软件只会受到专业用户的欢迎吧。 所谓的语言编译,其实需要经过两步,编译和链接。编译的主要目的是将每行代码翻译成对应的汇编语言,而链接则是将符号引用转换为地址引用。举例来说,我使用了一个变量str来存放一个字符串,这个变量str就是一个符号。我需要在上文中声明(declear)这个变量,以便编译器在编译的时候代换这个符号对应的内存地址,和理解如何使用这个符号(关于上文没有声明的情况下的错误,请看”向下引用”特性)。我使用str的第四个字符的时候,str[3]就会被翻译到固定的内存地址或者基于基址的偏移,机器完全不用理会str是什么。而这点,则是反射实现的最大障碍。反射可以提供一个对象是什么,有什么的信息,并且可以动态创建对象。有了反射以后,才可以实现序列化,分布式等等高级应用。而C类语言在编译后失去了符号是什么的信息,只剩下一个名字,链接后连名字都没了。这种情况下,你怎么知道一个对象是什么呢? Java/C#可以提供反射,因此属于解释型语言。但是他们又不属于完全的解释型,而是解释型的一个特殊分支,中间代码。中间代码型的语言,需要编译,执行的时候又需要解释器。看起来没什么好处,可是在支持反射的基础上,大概可以以C代码1/2的速度运行,比纯解释快多了。原因何在呢?我们可以看看 C++为什么不支持反射。反射是保存针对执行结构的数据并且提供交互,而C++则在编译时生成后丢弃了这些数据。因此,理论上说只要保存了这些数据就可以实现C++的反射。这就是中间代码语言所做的事情。当然,考虑到跨平台特性,编译的结果并不是汇编代码,而是类似汇编的代码(Java叫P代码,C#叫 IL)。后JVM直接执行P代码,C#则通过引擎编译IL到本地代码。因此JVM执行的时候效率基本恒定,而C#初次执行速度慢,后来则是比C++慢不了多少。 最后就是Java/C#的最强特性,动态内存管理。使用这个特性,可以使得程序员彻底的从内存分配和管理的泥潭中脱身出来。白痴的程序员写的程序可用,强大的程序员写程序的效率提高。可是成也萧何败也萧何,内存不到底不回收,又有额外的内存开销,结果导致系统的缓存命中率下降。我们平时觉得Java类语言执行慢最大原因在这里,半解释才不是根本原因。 因此这些语言的特点就是中间代码,其核心思想是对象。这类语言的最大特性就是抽象和构架,使用强大的设计模式,将大型问题拆分成多个小型问题解决。在解决问题的时候,其代码量并不比C++少多少。 再然后是python和ruby,当然,某种程度上还有bash,只不过他弱了点。这类语言的核心思想是抽象数据,例如字典,字符串等。bash是围绕着字符串处理设计的,python是围绕着集合设计的。这些语言解决问题的速度非常快,但是模块化特征和抽象特征相对弱。一般情况下,和C++相比,解决问题的速度大概是1:5,代码量则是1:3。

Sep 9, 2008 - 1 minute read - Comments

程序员的几个分类

程序员有高下之分,可高下怎么分?到底什么是高程?程序员要完成哪些任务,怎么评价是否完成的很好? 下面由贝壳同学来胡诌一下他的个人感想,以下的程序员都指商业程序员。当然,爱好者可以类推。 首先我们先讨论一个风马牛不相及的问题,程序值钱么?废话,人家账单大门兄都已经是世界首富了。可贝壳认为,程序不值钱,算法也不值钱,如果说值钱的话,就和软件光盘上面的光盘一样,是个成本性质的辛苦钱。软件里真正值钱的是软件的思想,我们大可以想象一下,写一个让人想穿脑子也想不出怎么用的程序——当然,会写的程序员想穿脑子——然后想想值钱不值钱。大家就会了解到,其实程序员,编程本身,是和装配线上的装配工一样的低附加值行业。不同之处在于,不同培训程度的人劳动生产率不同,而且生产率差异远远大于普通行业而已。好的Coding比差的生产率会高上数倍,而且很难多找几个差的来替换好的,水平不足。但是,做Coding,无论做多快,其价值只会线性增长。 那么为什么软件也被称为今年来发展最迅猛的产业呢?其实关键在于软件业让人可以实现以前无法实现的一些想法。例如,以前不会有人能做到让地球上所有的人 (好吧,是大多的人)坐下来一起讨论一个事情的方法。那么,今天我们的技术已经可以做到。有个人针对当前的技术,设计出一个很好的让所有人坐下来讨论事情的系统。包括一个BBS,带自动翻译系统。在线视频会议中心,可以附加购买在线翻译。一个邮件列表,带存档功能。一个文档编辑和管理系统,带同步编辑,版本管理和资料索引。当我说出上面这堆东西的时候,可能有的人已经晕了,当然,六牙四皂小姐估计已经不继续看了。不过做过一些时间和电脑有关商务的童鞋应当都理解这些东西的意义,并且可以想象这些东西带来的便利。在线翻译的支持系统,邮件列表存档系统,同步编辑,版本管理,资料索引,这些都是技术。尤其是资料索引和自动翻译,更是技术的巅峰之作。可是如果不是结合起来让客户用的舒服,这些东西有价值么? 软件业的价值在于将技术转换为客户的满意,并且最终转换成客户的钞票。越成功的规划,越能满足更多的客户,并且让他们付更多的钱。从这个角度讲,不论软件做的怎么样,微软的规划是全球一流的。同时,能促进这个过程的人,才是具有价值的。不过遗憾的说,到这步基本就不是程序员,而是CTO了—— 程序员的最高价值,在于根据技术和行业,判断应当发展什么技术,采用什么框架,从而低成本,高效的做出让客户满意度最高的系统——而且不是一个系统,而是一堆。这有两个非常苛刻的要求同时存在,对于技术非常熟悉,视野开阔感觉敏锐,否则怎么去感觉技术的价值,判断应当研发的技术?就这点而言,许多程序员在超过30岁后往往都可以在熟悉的领域内做到,有条件的话大概可以在多数领域做到。然而最麻烦的在于,做这个事情的时候,你必须熟悉客户,熟悉客户需要什么。这点往往是不可能的!客户是不可理喻的!技术不是万能的!要知道,使用最好的技术,设计你最喜欢的系统,往往是客户最讨厌的事情。行业客户如此,通用客户更如此。 如果上点你做不到,自然有高水准(也许吧)的人来做,那么你可以做次之的工作。什么呢?执行他们制定的方向。上层的人会告诉你应当发展什么技术,采用什么框架。现在要求你——不用会——能够整合实现这个目标。说明白点,你可以招,但是要求能留下人,低成本。你可以培训,但是要求能做事。你可以研发,但是要求好用。你可以买,但是要求低成本。如果你能实现这些目标,那么同样,你也是有价值的。 这个层次的程序员往往是Project Manager(当然,很多PM根本不是程序员)/Team Leader/Core Programmer。对于他们的要求往往是兼顾技术,行政和人事的。他们需要能够组织研发,积累技术,产生产品。很遗憾的,个人编程能力往往又是次之。不过程序员是很艺术化和个性化的一群人,在这个位置上的人,如果没有相当的技术水准,很难镇住下面的人,用普通管理人员来管理程序员的结果往往是给程序员联合起来耍。因此一般情况下也需要了解大致的程序,并且最好有一定技术水准。 最下面一个层次的人,基本就是能够实现程序,会用上面决定的框架和技术,编码效率高,工资要求低——别的没了——当然,以上是从职业分工来讲一个职业程序员的价值的,你可能说上面没道理,贝壳乱讲。不过事实是,职业的情况下就是上面的状态。当然,从业余爱好者,技术研发者来说,程序员又有另外一种不同的分法。 第一个层次,是刚刚学会技术。能够使用某种特定语言,按照一些例子编写一些程序。实话说,按照贝壳的程度,入手一般语言做到这点不超过7天。然而很多人会徘徊在这个水准无法进步,原因在于——他们能写程序了,而且写了能用。从这个引申开来,顺便说一下,程序员的进步是个很吊诡的事情。一方面来说,要勤于钻研技术才能进步。但另一方面来说,如果不够懒,是很难有足够动力学程序的。因此,好程序员都是勤于钻研的懒汉。 第二个层次,学会了使用框架,并且能够设计一些中度复杂的系统,开始接触第二语言。和初级程序员不同的是,他们能实现一套完整的系统,而不是一个个零散的功能了。这要求他们了解框架,什么时候触发什么函数,系统间怎么互相通讯。并且,有水准的还可以写一些小型的框架。 再上一个层次,了解软件工程对软件的意义,能够跨多种语言编程,灵活使用设计模式,能够设计复杂框架,习惯文档化。和上面的区别看起来不大,不过是能多用几种语言,朴素的设计被设计模式所规范,设计的框架复杂化,并且会写一堆无聊的文档。不过从这步开始,程序员开始了迈向大道的第一步,在这个层次以下的只能算爱好者。无论是研究技术,研究数学理论,还是什么,规范化都是必须而且是非常重要的。我们很难想象一堆工程师,各画各的图纸,最后房子还建的多快好省的。同样,作为高级程序员,头一步就是学会和别人合作。使用设计模式的规范进行设计,使用文档描述系统,可以跨越多种语言协作,了解多种语言思想,这是必须的。 再上一个层次,就已经不是程序员的境界了。作为程序员,上个水准已经到头了。更强的程序员意味更规范?效率更高?那是八级钳工!作为程序员,你可以不认识英文,你可以大字不识一个,然而你必须是个数学高手(其实现在数学高手大字不识一个几乎不可能)。作为程序员的巅峰,你可以很轻易和他人协作,使用合适的语言,然而无法规避的是对问题的抽象描述和求解。在贝壳作为程序员的这段时间里,无数次的碰到数学问题,有些往往是大学里面我们所不屑一顾的。例如蒙特卡洛法,拉格朗日乘子算法,这些在程序里面都有很重要的应用。有的时候更要自行抽象数学模型,并且设计满足时间限制和空间限制的解法。能够抽象问题,解决问题的,才是真正的技术系的高手。 OK,上面,贝壳从两个方面(工程和技术)论述了程序员的高下之分,作为他胡诌的结果,他目前的水准大致是——不知道。并且很遗憾的告诉大家,目前贝壳能看到的就这么多,再上面是什么样子——要么等到了再告诉您?