逝者已逝,众恶徒已正法,然天下居庙堂者与处江湖者,当以此为鉴,牢记生命之重,人权之重,民主之重,法治之重,无使天下善良百姓,徒为鱼肉。 ——孙志刚墓志铭
  • 我们常常能够看到或是听到许多有关敏捷的问题,无论在邮件组里、在技术交流活动上,还是在客户现场的时候──当然,最后一点是废话,没问题人家请你去咨询干嘛?有的问题只是简简单单的疑问、困惑,这就容易解决;但有些问题则是误解,当误解产生以后,扭转人们的观念相比起答疑解惑就要困难的多。于是我最近一直在考虑,这些误解产生的根源是什么呢?有什么方式可以帮助我们更容易说服对方,化解误解?我们在宣传推广某些理念的时候,又该怎样避免让别人产生误解?假如话题不仅限于敏捷,那我们自己在平时会存在哪些类似的思维误区?我们自己又可以怎样避免?

    这些问题我并没有很好的答案,刚根据刘未鹏的博客豆列买了几本有关行为经济学和判断决策的书,例如“怪诞行为学”、“别做正常的傻瓜”、“摇摆”,接下来应该还会读一些心理学方面的书。这篇博客只是记录一下我今天所想到的一些思考角度,希望看到的朋友能够不吝拍砖。

    Bob大叔在本月8号的一篇博客中解答了TDD中的一些问题,例如:

    为什么不把测试都放到后面再写?
    TDD能不能代替架构?
    TDD能不能代替设计?
    是不是每行代码都要用TDD的方式来写?

     

    把其中某几个问题换个写法可能就会看起来很眼熟:“有了TDD是不是就可以不做设计了?”、“有了TDD是不是就可以不做架构了?”我们还有更多的例子可以写,像“写单元测试是不是浪费时间?”“敏捷是不是就不要文档了?”“我们在搞敏捷,所以就......” 我姑且把这些误解分成两类:第一类是单纯因为知识欠缺所导致的,例如“写单元测试是浪费时间”、“先写测试后写测试一个样”;第二类所表现出来的,则是知识面跟思维方式的共同问题。

    从前我跟陶公子一起做过一个有关敏捷基础知识的Session,会后交流的时候,有个朋友就很感慨的说,“听了你们的session才知道,原来不是说用了敏捷之后,我们从前那些积累下来的成功经验就抛弃不要了啊,我操,原先我就一直以为实施敏捷以后,CMMI里面有些适合我们的做法也得扔呢。”这就是典型的第二类现象,知识欠缺加上思维方式有问题。

    这里的知识面欠缺指的是:从接触到的宣传、读到的材料和书籍等信息中,没有接触过这方面的内容,导致潜意识中对这个问题没有足够的认识;思维方式的问题指的是:其一,把没有接触到的东西当作是不存在的, 敏捷管理的书上没怎么写过要保留哪些文档,就认为敏捷不要文档;敏捷的书上没讲过要不要跟从前的成功经验结合,就以为要全盘抛弃。其二是新旧事物水火不容、新事物强大乃至万能的观念作祟,这种观念由来已久,像政权交替,像王安石变法,像“旧的必须彻底粉碎,新的才能顺利成长”的革命斗争,再到“有了TDD就可以不做设计”、“敏捷是银弹”等等,都是它的体现。而等人们发现新事物并非自己当初所认为的万能之后,光环背后的缺陷就会被无意识的放大,在心理逆差的作用之下,有些人就会恨不得把新事物推到在地上,再踩上一千只脚──这种现象在日常生活中很常见,在此不必赘述。

    这些林林总总的问题,究其根源可以归纳为以下两点(我这里的分析肯定不全面,希望以后有机会补足或是推倒重来):

    1. 被动接受信息,欠缺批判性思考。

    “学会提问:批判性思维指南”的第一章中,作者说道,“作为一个有思想的人,你必须决定对所见所闻做出什么反应。你可以像前面提到的那个新法官一样,无论碰到什么都接受它,但这就会导致你将其他人的观点当作自己的观点。更积极的做法是努力提出一些问题,尽量形成自己关于这个问题的观点。”

    把别人的观点当作自己的观点会让人慢慢丧失主动思考的习惯,信息从耳朵眼睛进入,直接从嘴巴手指流出,大脑成了没有过滤功能的中转站。盲从、人云亦云说得就是这样的做法。此外,所有人做所有的事情都有目的,当我们看到一篇文字,或是听到一场session,首先应该想的就是,这个写文章或者做session的人,他想传达给我什么信息,表达什么观点?他的目的是什么?

    我有位朋友是独立咨询师,他说过一句很经典的话:“我骗人的时候从不说谎。”当我们能够看清目的与真相,我们才能够尽可能的不被眼前见到的、耳边听到的所左右。(有关批判性思考的内容,请参见前面所提到的“学会提问:批判性思维指南”

    2. 对知识的掌握只是浮光掠影,没有深入的分析研究。

    回头再看Bob大叔的这篇博客,比较一下“有了TDD是不是就可以不做设计了”和“TDD能不能代替设计”这两个问题,从“是不是”到“能不能”其实表示了认知程度的一个跨越。当被问到“是不是”的时候,我们也许可以认为,这个问问题的人,他的知识并不足以支持他自己对这个问题做出判断,他对这个问题所包含的知识范畴,只是道听途说的了解而已;而当被问到“能不能”的时候,我们就可以知道,问问题的人已经做过了尝试,他自己已经隐约或是明确的意识到“不能”,但他从书本上,或是别人嘴里听到的话却隐隐约约跟他所动手了解到的不是一个样子,所以他还是想了解一下,他所认为的“不能”,到底是真的“不能”,还是因为他的能力不足,或者知识面不宽等原因导致的暂时“不能”。

    如果我们在质疑、指责、攻击某个观点之前,先尝试着对它的应用场景、使用方式、涉众、影响范围、结果……做一些模拟乃至真实的尝试,也许就可以避免肤浅的判断。

    每个人都难免有成见。所以如果我们曾经抱怨别人对敏捷、对我们的工作方式存在种种偏见,那么当我们看到别人的观点与我们不同时,请尊重他们,请尝试花时间理解他们,去了解背后的故事。因为别人也会以同样的眼光审视我们,也因为同样的工艺可以得到同样的面包(这个故事请参见《咨询的奥秘》)。

  • 上个月,Jim Highsmith在博客中写到,“于我而言,做TDD的开发者就像参加铁人三项一样:他们得掌握三项不同的运动─跑步、骑车、游泳,而这些运动又是集成在一起的。很多开发者编程技术很强,但就像不会游泳的杰出自行车运动员一样,他们在TDD铁人三项中会遇到很大麻烦…”

    我觉得这段话的解读方式可以有两个:一个是要完善自己的技能集,二是敏捷开发实践的相互支撑。而第二点在帮助客户排查问题的过程中也起着尤为关键的作用。

    前些日子,客户问过这样一个问题,“我看敏捷开发的一些书里面,提倡说每个故事做完以后都直接转给QA做测试,但在我们团队里面行不通,这样做的话,QA就会忙得焦头烂额,跟不上开发的节奏,我们只能每个迭代到最后的时候安排一个专门的测试阶段。”我请他描述一下详细情况,心里同时猜测着会不会跟故事粒度、QA和开发的人员配比等情况有关系。聊了一会便愕然发现,原来先前的猜测统统挨不上边,真正的原因是他们的开发人员根本就不写单元测试,也没有一丝一毫的自动化测试。

    这个结果还是很有意思的,客户以为他们是在尝试故事完成以后转QA这个做法的过程中出了问题,最后发现是因为他们没有单元测试,没有自动化测试。当然,这个事情也可以从问题的现象和本质之间的关联来分析,不过这也不是本文要说的重点,我想说的是,当我们想采用某个敏捷实践的时候,我们是否考虑过,实施这个实践的基础已经具备?

    客户在很多时候,认为一个实践做不下去只是因为他们的做法有问题,或者干脆认为这个实践不适合他们的环境。这时候我们必须得想到,问题可能不在于他们怎样来应用这个实践,而是与之相关联的哪些地方,尤其是支撑这个实践的基础可能出了麻烦。

    当然,可能不仅仅是技术实践,还有其他种种因素。例如麦罗常说的一句话就是:不要用技术来解决政治问题。光磊在“敏捷质疑系列”中也列出过这样的问题:

    Q: 我干嘛要把辛辛苦苦很多年积累的经验白白告诉别人? 我喜欢不可替代的感觉.

    A: 是的, 本质上这是一个心理学和政治学的问题, 我也无法说服你.

  • rojam是dreamhead同学做的一个用ruby代码操作java字节码的开源项目,项目具体内容因为跟本文主题无关,所以就不多描述了。我最近一段日子因为onbeach,所以就参和了进来。在开始读到rojam的代码之前,我原本以为自己还是会写一点ruby程序的,然后就被深深的打击了。。这里记录下来一些rojam中的metaprogramming技巧,并不是什么系统化的知识,只是自己的一点总结把。

    先看这段代码:

    class << self
           {
            :no_arg       => 1,
            :var          => 2,
            ......
          }.each do |type, size|
            class_eval %Q{
              def #{type}_instructions(*opcode, &block)
                instructions(#{size}, *opcode, &block)
              end
            }
          end
    ......
    end

    eval方法会将字符串作为ruby代码执行,它的变体有如下几种:class_eval, instance_eval, module_eval,分别用于其名字所表示的上下文。上面那段代码的含义就是,把block跟hash的each方法关联起来,当block被调用的时候,%Q{}所包含的部分就会被作为ruby代码执行,于是就有了

    def no_arg_instructions(*opcode, &block)
        instructions(1, *opcode, &block)
    end

    def var_instructions(*opcode, &block)
        instructions(2, *opcode, &block)
    end
    .......

    自然,这些方法是动态生成的。

    接下来再看这两个方法:

    def instructions(consumed_byte_size, *opcode, &block)
       opcode.each do |single_bytecode|
          define_method instruction_method_name(single_bytecode), &block
          consumed_byte_size_table[single_bytecode] = consumed_byte_size
       end
    end

    def instruction_method_name(instruction_code)
        "__#{instruction_code}__"
    end

    这行代码:define_method instruction_method_name(single_bytecode), &block,会把instruction_method_name(single_bytecode)所返回的字符串定义为方法,后面的block作为这个方法体的一部分。最终的结果就是为每一个opcode都定义了与opcode同名的方法。

  • 1. svnadmin create /home/jacky/repository/test (Note that this directory should be accessable by accounts other than root)

    2. svnserve -d --listen-port 8099 -r /home/jacky/repository

    3. vim svnserve.conf

    anon-access=none

    auth-access=write

    password-db=passwd

    4. vim passwd

    test=test

    5. vim authz

    [/]

    test=test

    6. cd /$cchome/projects, mkdir test, cd test, svn co svn://localhost:8099/test .

    7. edit /$cchome/config.xml, add "test" project

    8. commit something to svn://localhost:8099/test, and force build on cc

  • 1. make sure that JDK installed and JAVA_HOME configured.

    2. sudo vim cruisecontrol.sh, modify webport

    3. replace config.xml

    4. remove useless project under /logs and /projects

    5. cd /projects, mkdir marsrover

    6. cd /marsrover, run svn checkout http://marsrover.googlecode.com/svn/trunk/ . (don't miss .)

    7. start cruise.

    See the config.xml below:

    <cruisecontrol>

        <project name="marsrover">     <!-- should be the same as the project directory name-->
        <!-- NOTE: if you want to force build even if no code modifications detected, you can add requiremodification="false" to the project attributes -->
        <!--
        there are some different scenerios -
        http://confluence.public.thoughtworks.org/display/CC/CruiseControl+Scheduling+Scenarios
        -->
            <listeners>
            <!-- listening for status change, such as waiting for build, queued, building, etc. Normally we won't change this configuration -->
                <currentbuildstatuslistener file="logs/${project.name}/status.txt"/>
            </listeners>
           
            <!-- NOTE: CC doesn't support check out the code on the first time, so you should check out code to the project directory first.-->
            <!-- NOTE: if you're using https to update code, then the code should checked out firstly with command line, and accept certification permanently-->
            <bootstrappers>
            <!-- this element is used to checkout code, we use svn here, localWorkingCopy is used to check out code to local file system-->
                <svnbootstrapper localWorkingCopy="projects/${project.name}"/>
            </bootstrappers>

            <modificationset quietperiod="30">
            <!--if the code changed, and there are no checkins within quietperiod seconds, the cc will check out code from the repository-->
                 <svn localWorkingCopy="projects/${project.name}"/>
                 <!-- here we do a forced nightly build, it will create a faked modification on 11pm,
                        then it needn't <project requiremodification="false"> -->
                 <timebuild time="2300"/>
            </modificationset>

            <schedule interval="300">
            <!-- do CI during the day, every 5 minutes-->
            <!-- cc will launch a build every interval seconds, here we uses ant with the specified build file-->
            <!-- NOTE: user can also specify time attribute to ant, such as <ant time="2300"> means build on 23:00-->
                <ant anthome="apache-ant-1.7.0" buildfile="projects/${project.name}/build.xml"/>
            </schedule>

            <log>
            <!-- save log file, the file will be saved under logs/${project.name} by default-->
                <merge dir="projects/${project.name}/target/junit-test-report"/> <!-- merge the build result -->
                <!-- if we want to see the just test result in cc, the junit result should be located under the same directory as described above -->
                <merge file="projects/${project.name}/target/checkstyle_report.xml"/>
                <!-- to show the checkstyle result on the cc page, we should edit /webapps/cruisecontrol/main.jsp, and uncomment the lines below:
                <cruisecontrol:tabrow/>
                <cruisecontrol:tab name="checkstyle" label="CheckStyle">
                  <%@ include file="checkstyle.jsp" %>
                </cruisecontrol:tab>
                -->
            </log>

            <publishers>
            <!-- publish the build result to the specified location, there are many plugins in cc to do all kinds of publishing, such as send out
                email, call the specified page using http, play music, etc. -->
                <onsuccess>
                <!-- specify what will be published when build succeeded-->
                    <artifactspublisher dest="artifacts/${project.name}" file="projects/${project.name}/${project.name}.jar"/>
                    <!-- in the element above, we must make sure that the built jar file should be exactly named as ${project.name}.jar-->
                </onsuccess>
    <!-- NOTE: if you want cruisecontrol to report a test failure as a build failure, you need to make Ant report the test failure as a failure. just like this:

    <junit fork="true" haltonfailure="false"  failureproperty="junit_test_failed" printsummary="on">
    </junit>
    <fail if="junit_test_failed" message="One or more JUnit  tests failed"/>

    see: http://confluence.public.thoughtworks.org/display/CC/FailOnTestFailure
    -->
                <htmlemail mailhost="smtp.gmail.com" mailport="465" usessl="true" username="xxx@gmail.com" password="xxx" reportsuccess="always" returnaddress="build@xxx.com" subjectprefix="xxx build logs">
                    <always address="xxx@gmail.com" />
                </htmlemail>           

            </publishers>
        </project>
    </cruisecontrol>

  • anchuan Scrum认证测试,主要是考察敏捷项目管理的知识。ScrumMaster真正需要的是敏捷项目实施的能力,而不是知识。敏捷项目管理的知识,找几篇文章,找几本书读一下就可以了。

    vincentxu @anchuan agreed, it's just like sex, even though you've lots of knowledge, you still mess it up without real experience.

    vincentxu @JackyLiJian @anchuan another thing is ppl always over estimate the difficult to gain knowledge, which is really cheap nowadays. And more saddly most of ppl think knowledge == capability

  •    很多人都——如郑渊洁、马云——都曾经总结过懒人对于世界进步所起到的作用,但无论如何,到底还是勤奋的人居多。

       比如,在Firefox3里面,懒人会利用网址记忆联想功能,在地址栏里面输入infoq,在弹出的下拉框中找到http://www.infoq.com/cn/。而勤奋的人会不厌其烦的一次又一次输入整条网址,然后回车。

       又比如,在Eclipse里面,要为一个类生成main方法,懒人会输入main,按一下alt + /,再直接回车。而勤奋的人会运指如飞,敲出public static void main(string args[]){…}

       有那么很长一段时间,在记熟了大多数Firefox和Eclipse快捷键,用过各种插件、写过一堆自动化脚本……之后,我就欣欣然以懒人自居了。但翻开书稿没几页,小小的自鸣得意便化作了羞惭,而当书一页页翻过,在酣畅与快乐中,羞惭也消失殆尽。那不仅仅是眼前一亮,而是仿佛于中关村见芳草绿地,重重楼宇间见月色苍茫。

       原来懒人也有境界高下,有的于无意间得一鳞半爪,但不知触类旁通,或曰具懒人之形;有的时刻于一切可能之处寻省时省力省心之法,或曰得懒人之神。

       懒人不会费心去猜类名的含义,对那种要啃上几百行语句才能明白方法作用,或是跟着一大串if/else/switch/case跑来跑去的代码深恶痛绝,更不愿意发现有朝一日自己也读不懂自己的代码,所以他们会把代码写的很简洁、清晰,让人一眼就能看懂用途。

       懒人不愿意花时间做无用功,所以他们的设计原则是够用就好;面对不可完全预知的未来,轻装上阵会让他们感觉很爽快。

       懒人不喜欢花上一两个小时乃至大半天的时间做debug,做bug修复,更是不愿意改了一个bug或者修改一处需求引出若干连锁反应,所以他们一定要写单元测试,覆盖到绝大多数乃至每一处功能点,而且代码的每一处改动一定会有对应的单元测试。

       懒人不喜欢做简单重复的工作,因为“手工执行简单重复的任务会让你变傻,会消耗你的注意力,而注意力是最重要的生产力之源。”(作者语)所以他们会找工具、写程序来帮助自己做这样的事情。他们崇尚的是,能够让机器自动化做的,就不要手工做。因为人的时间比机器时间值钱。

       如果你想做一个真正的懒人

       就请继续读完这本书

       因为这本书是天堂

       如果你不想做一个真正的懒人

       那也可以读完这本书

       因为它至少可以教会你掌握一些小窍门耍酷,而且要比从前那种一遍遍敲ls或者dir滚屏更加专业。

       那么,到底这本书像什么呢?唔,就比作营养饮品吧,无论你将来选择怎样的职业生涯,你都会获益匪浅,因着书中的养分,还有益菌因子。

       最后再友情提示一下,看书的时候请不要一口气读完,不然作者所介绍的一些非常实用的小工具你还得回头再来找一遍下载地址,有我一个犯傻的就够了。

  • 这是一篇姗姗来迟的文章。

    在08年夏末上海举办的那次Scrum Gathering活动上,我邀请到两位朋友接收了InfoQ中文站的采访。

    他们一位是国内首位CST(Certified Scrum Trainer),活动组织者吕毅,一位是优普丰(UPerform.cn)的创办人李国彪。

    这篇访谈是为了让大家了解一下讲师和培训方眼中的Scrum认证。毕竟,无论是想拿个本子冠个头衔提升自己在公司内的地位,还是想藉此作为深入敏捷开发领域的敲门砖,你都需要明确自己能够收获些什么东西,是不?好歹也是上万的费用呢。

    所以,就有了这篇文章。详情请见InfoQ中文站报道:http://www.infoq.com/cn/articles/interview-scrum-training
  • Jerry Madden在NASA工作了37年,他退休之后,就这些年的实践总结出了“百条项目经理箴言”。

    以下为其中节选:

    绝大多数经理的成功都是凭借手下职员的能力。

    永远不要找借口;只需要把执行计划拿出来。

    不是所有成功的经理都能胜任工作,也不是所有失败的经理都无能。运气还是占了一定成分,不过运气偏向于那些有能力、勤恳工作的经理。

    牢记,即便你认为老板是错的,他也有权利做出决定。告诉老板你的想法,但是如果他依然坚持己见,你就要尽全力保证事情能有个好的结果。

    管理原则始终未曾变过,变的只是工具而已。你仍然要找到适当的人做事,而且不要挡他们的路。

    保持正直,这可以获得属下的信任。

    如果有问题需要招人,你应该跟少放了盐的厨师学习——一点一点来。

    所有的问题都可以及时解决,所以你的应急方案一定要准备的很充分——如果你做不到,那就可以换人了。

    犯错无可避免,失败则不然;你可以弥补错误,但无法弥补失败。所以,为你那些高风险的计划或是任务准备应急预案和备选方案吧。

    确保每个人都知道需求,理解需求。知易行难……一定要确保有合适的人了解需求,即便有一大堆经理跟销售都对需求表示赞同,这也不应该让你感到放心。

    更多讨论参见InfoQ中文站新闻:来自NASA的“百条项目经理箴言”
  • Jurgen Appelo上个月发表了一篇博客“敏捷团队当如群鸟飞”,他写到,“在敏捷软件开发中不应该限定规则,只应当做基本的限制”。

    他开篇提出:

    在组织中,人们总是试图通过引入某些规则来解决问题,例如,“在X情况下,你必须要做Y”。
     
    我认为这绝不是最好的方式。规则应该是留给团队自己决定,你只需要设定一些限制就行了。

    紧接着,他举了一个在计算机上为鸟群行为建模的例子,模拟鸟群的行为非常简单,只需要三条基本限制:

    1. 不许离群
    2. 不许相撞
    3. 往一个方向飞

    Jurgen Appelo认为,鸟群的行为可以很容易映射到软件开发团队上来:

    1. 不要把自己孤立
    2. 不要跟其他人打架
    3. 与团队的方向保持一致

    他接着说到:

    在管理软件项目的时候,敏捷软件开发是一种很自然而然的方式。它设置了一些限制,如“跟客户协作”、“允许频繁的变化”、“只交付可以工作的成品”,剩下的规则就由团队自己选择。

    ……

    这也表明,敏捷软件开发并不是天生就代表了结对编程、TDD、迭代……(注意,敏捷宣言根本没提到这些!)当然,这些实践很不错,但你要是想把它们当做固定规则来实施,你就……

    当然,也就失去了敏捷的能力。

    你对团队建设、团队管理持有何种态度呢?你有没有想办法组建自组织的团队?当团队能力和工作态度没有满足你的预期时,你采用了什么方式来提高生产效率,转变大家的心态?欢迎留下评论,与大家分享经验。

    如果你有切实行之有效的实践经验,也欢迎为InfoQ中文站投稿,请mail至lijian[at]cn.infoq.com。

  • 《Manage It!Your Guide to Modern, Pragmatic Project Management》是2008年第18届Jolt大奖通用图书类生产力大奖的获奖图书,在Amazon上保持全五星的评价长达一年多的时间。这本书的中文版由人民邮电出版社图灵公司引进版权,近期在译者郑柯的博客上发出了部分试译章节。

    用译者的话说:

    这是一本可供项目经理即刻上手、名副其实的项目管理使用指南。对于任何类型的软件项目经理来说,《ManageIt!》都是一本值得反复研读的书(不管你是读英文版还是中文版)。无论你是使用瀑布式、迭代式、还是敏捷式生命周期模型管理项目,都能从本书中得到有益的提示和帮助。

    迄今为止,在译者的博客上已经放出了四篇试译章节,读者不妨移步一观。

    谨祝阅读愉快。

    在InfoQ中文站上有新闻全文:

    http://www.infoq.com/cn/news/2009/01/manage-it-chapters-preview

  • 原文请见:http://worldofming.firingsquad.com.cn/?p=901

    今天在NGA看到一篇好玩的帖子,好像已经被炒得火热,原谅我这几天在忙些私事,进度落后太多。好几个朋友问我为什么一直用手机上QQ,我的回答是,已经停水停电停网。于是大家纷纷对我表示同情。好了,言归正传,如果还有人不知道这个事,那么我来简单讲下。

    故 事是这样的:一个有名的公会,由于种种原因开了个U团——ABCDEFGHIJKLMNOPQRSTU的U,“团结就是力量,就是大米饭,就是大铁缸“的 “团”(这个有名的公会显然实力不可小觑,连团都开了这么多)U团里有一个盗贼,叫A君,A君以前让了一对蛋刀给别人,而在让刀当天,团长承诺他下次可以 出分来飙第二对蛋刀。时间飞转,第二对蛋刀出现,而团长没有履行承诺,把蛋刀直接给了一位B君。B君是一位AFK了一段时间的老人。

    这样的一个事件,竟然引发了几百页的讨论,上千条的回帖,让我不禁感叹舆论的力量是多么伟大。无数的线索在回帖中闪现,一张张截图被无情地发了出来,整件事情简直就仿佛公安局破案一样,几乎每个场景都得来几张照片作为证据。

    猛一看,所有人都觉得A君太无辜啊,被公会欺负啦。再一看,下边有相关的公会官员回复,忽然发现:哦!原来这个A君在公会中的形象并不好,大家都不喜欢他,看来没有让他拿刀是众望所归啊!最后一看,好像A君是被冤枉的啊,也并不是所有人都不喜欢他呀……

    回复中,过路的,支持的,乱喷的,迷茫的,观望的,主持的,牢骚的,无奈的,写诗的,发图的,牛逼的,傻逼的,形形色色什么样的都有。这至少充分的说明了一点:中国,从来不缺少人才——其实人才多着哩,只是坐在电脑前,没什么事可做而已。

    管 事的人后来发表意见说:公会对不起你,U团对不起你,你的DKP可以换成G发给你,不过请你退团。A的朋友站出来说:其实团队中是有人赞同A拿刀的,可惜 这个时候无法站出来,原谅我不能透露自己姓名。U团的官员站出来说:这个人平时做事RP不好,不顾团队集体利益,一开始就想着拿蛋刀,DKP恶意囤积……

    一个小问题,往往反应了大问题,甚至是更大(大到哪去拼想象力了)的问题。

    如 果一个公会还存在官员和会员之分,那么DKP也只是个数据而已。DKP不是ROLL,ROLL是强制执行的,而DKP却只是一个参照品。说白了,所有人都 按照DKP办事,那么DKP就是有意义的,而一旦一件重要的事发生了,出现了一个极大的冲突,冲突的分量超过了DKP的分量时,DKP就是屁了,这时只需 要一个“强制执行者”,而所谓的“强制执行者”不就是那个团长吗?

    任何一个团体,没有强制执行者,是不行的。

    为什么国家 必须有“暴力机关”?一个好的国家应该所有人都安居乐业啊,应该没有小偷强盗啊,应该没有乱民谋反啊?这就是,目标与现实的不同。人们总是觉得DKP是一 个规则,它就是“法律”,可在现实当中法律尚不健全,何况DKP这种东西?大锅肉煮着,每个人看着,分东西的,却是拿刀的人。

    举个最简单 的例子:你DKP比别人少,我把东西给别人,你是不是没话说?那你一直留着DKP,你显然是为了比别人多,我说你不为团队着想,自己囤积DKP,你是不是 也没话说?你花了DKP,但是你还是比别人多,我可以说,那个人比你更着想团队,因为他花了更多的DKP去拿别的装备。

    如果我是团长,我怎么说都行的,我总有一个办法让“大家”都站在我这一边,我总有一个办法让“所有”人都支持我。要怪,只能怪团长是我,而不是你。

    这是不是太不公平了?这游戏还玩什么劲儿?我打了好几个月副本,每天出勤,换来的是什么?

    团 长,不是从一开始就冠名的。最开始,只有一个团长,而这个团长带团的第一天,也不会抱着什么伟大的梦想和目标。当一个公会能组起两个团,另外一个团长,必 定是他的朋友,而不是那个所谓的“最考虑团队的人”。当然,团长交朋友,也不会随便交的。这个朋友,必须有一定能力,还不能有能力到“可以把我挤下台”的 地步。

    每个团长,都隐忍过,退让过。不把装备让给别人,怎么“多为团队考虑”,不在分歧的时候向着领导说话,怎么成为领导的“团长”?想着攒一堆DKP去拼一件装备的人,是永远当不了团长的,因为:团长不相信DKP,团长只相信队长分配。

    A君,你拿不到蛋刀,怪不了大家不支持你,只能怪你自己,方方面面没有安排妥当。

    团长在想要不按规矩办事时,可以说一句:“你的RP不好。大家都不希望你拿。”

    这一句话,看似正义,实际放屁——甚至连沉默都不如。首先,你不喜欢他,可以;你们都不喜欢他,也可以;甚至于你们全公会都不喜欢他,就不愿意看他拿蛋刀,都可以!但是,你们为什么要带着他活动?为什么偏偏要到蛋刀出来的时候才说这些?这不是耍人,是什么?

    可是并不是所有人都觉得这句话有什么不对,却好像是“不让他拿,众望所归。”无关的人,大多观望,回帖的人,不是无聊,即是有所关系。在众多的回帖中,我看到了一个经常出现的词:民主。

    在 任何一个国家,民主都没有绝对实现过。就算让你每个人都投票,还是要分地区,看比重;就算让你们每个人都演讲,还要看推广,有属别。何况DKP这东西,和 民主又有什么关系?难道大家都能看到的东西,就叫做民主了?有人说平均大家的DKP,来换算成打出来的装备价值。哈哈,中国人喜欢讲平均,可是平均了这么多年,为什么贫富差距还是这么大?如果一切都按平均来,还真不如ROLL点儿,大家吵的架或许会少一些。

    为什么我们无法平均分配,是因为从骨子里,我们就不希望自己和别人得到一样的东西。

    团长能成为团长,靠的也是老团长提拔和自己的努力表现,和水民们关系不大。没有哪个公会选团长是要投票的,都是自然而然的,人家就站在了那个位置。团长也不容易,要处理乱七八糟的纠纷,还不能副本时候划水,你说你天天跟活动了,难道团长不是?团长绝对付出的比你更多,团长想要整你一下,道理上讲不通,可是人情上,却是占优势的。

    A君是个有趣的人——我见过许多人,但被我称为有趣的,并不太多。其实让了两次蛋刀,第二次又是这样的情景,此时把握机会,表现得大度一点,必定会赢得欣赏,第三把蛋刀无疑拿了,毕竟团长和“大家”也与你无仇,知道自己哪不招人喜欢,以后改过,必定能成为“为团队着想”的三好学生。然而A君毅然选择了“爱谁谁”的做法,玉石俱焚,天崩地裂,反目成仇,胸怀是非恩怨,打狗棒一扔,天下英雄都来定夺。实在也是一人才。

    那些安慰A君“蛋刀而已,一个装备而已,一个数据而已”之类的同胞,我想大可不必了。因为文章一发,A君显然早已看破蛋刀,只为尊严而战。正如“你可以让我死,但不能让我无声无息地死。”的“中华武术精神”一样啊。

     ~~~~~~~~~~~水木清华的分割线~~~~~~~~~~~~

    http://www.newsmth.net/bbstcon.php?board=WoW&gid=1354763

    蛋刀之过,谁之过,莫忘团长手分错。

    尊严之战,何之战,且看论坛口水溅。

    不问双刀英雄此去远方何时归,

    但求有朝一日“公道”能载回。

    莫怪英雄多是非,英雄也会AFK。

    莫追天堂毛团错,转战台服谁之过?

  • 原文见:http://blog.objectmentor.com/articles/2008/11/16/dirty-rotten-scrumdrels

    下面是偶的翻译:

    现在我们总算找到答案了。我们知道是谁的问题了。是SCRUM!SCRUM是敏捷运动失败的原因。SCRUM是敏捷团队把事情搞糟的原因。SCRUM是一切问题和罪恶的根源。SCRUM带来了“敏捷衰落”。

    你被我玩了。

    Scrum不是问题,它过去从来不曾成为问题,将来也永远不会成为问题。亲爱的工匠们,这个问题是我们自己的懒惰啊。

    既然我们不写测试,不能保证代码的干净,那埋怨SCRUM做什么呢?我们不能将技术债归咎于Scrum。在Scrum出现之前,技术债就存在已久了,而且它还将继续存在下去。不,Scrum不应该被骂。罪魁祸首还是跟从前一样:我们自己。

    当然,两天的认证课程不足以构成一个优秀软件领导的充要条件。而且在参加完CSM课程以后得到的证书,除了能够说明你花钱参加了两天的CSM课以外,也没 有别的用途。而且在工程实践方面,Scrum也有很多欠缺。但无论是Scrum还是CSM,它们的目的都不是从我们中间培养出工程师,或是给我们灌输工匠守则。那是我们自己该干的活!

    有些人还说要是那些Scrum团队都用的是XP,而不是Scrum,那就不会有那些技术债了。扯淡

    让俺说的更明白一些:荒谬!扯屁!狗屁!蠢驴!傻逼!

    让俺告诉你们,在这,从现在到以后,不管到什么时候,你永远都有可能把XP搞烂。用TDD想留下技术债真他妈的容易。没脑子的家伙跟人结对也会把代码搞成荒地。而且,我告诉你,你会在做出简单设计以后,不再维护它

    你想知道写出优秀软件的秘诀么?你想知道怎样保证代码干净吗?你想要银弹吗?私家汤料?万事万物间那唯一的真相?

    好,我现在就给你。你准备好了吗?秘诀就是……

    秘诀就是……

    干好自己的活。

    够了,别再埋怨一切,你自己别那么懒就行了。

  • I received an email this morning from a developer in Sweden team, which says he reverted my code to an earlier revision so that he could test his component, and my code was also locked by him. He said,  "DO NOT make ANY changes to these files."

    I haven't been so angry for many days, what's the matter with him? Or what's the matter with our project? Why he can/dares to revert my code just to test his code? Even without telling me where the problem is?

    I'll never work on the code which is now LOCKED by him, until he would give me a reasonale excuse.

    We've suffered a lot from the fucking management. No one cares about the process. The architect defined the development rules, the build environment, but it's only valid for us Beijing team. The swedish developers doesn't obey the rules, which waste us a lot of time. But it seems the manager, the architect doesn't care about it.

    I cannot stand for it any longer. We're working for the same project, if someone did something he/she isn't authorized to, he must be responsible for the consequence, must.

  • Q5. Why didn't you adopt Scrum successfully? Would you please describe the process?

    David:

    Our problem is, some guys on the top level misunderstood Agile and Scrum, made Agile a formality. For example,  we have a Scrum Master on one big project, which went on very well. And a project manager found it good, and began to push Daily Scrum in several projects; but he doesn't know what's Agile, what's Scrum, so Daily Scrum became Daily Report because of him. And the core principle of Scrum isn't followed.

    Everyone must attend the Daily Scrum in the fixed time, and tell the manager about his/her tasks today, then the manager will decide whether he/she would take more tasks or not. It sucks. The "Daily Scrum" was canceled finally, for everyone felt that it's too boring. And later there was no one talking about Agile in the company.

    Fiona:

    I'm in a distributed team, and the Chinese team only know a little about Agile. One day, the PM abroad sent us several links, which talked about a strange word -  Scrum. We're only given one or two days for checking the introduction documents of Scrum, and then we began the Stand-up Meeting. Actually everyone knows the importance of communication, but as we have 6 to 7 hours' time difference, when they came to work on the morning, we would be going to clean up the table and go back home.  It didn't improve our communiction, and is given up after one or two weeks,. We tried to do stand-up inside Chinese team, but the biggest problem is the culture difference between teams and the project planning. The stand-up meeting couldn't bring us much value, and became a formality very soon and finally given up.

    We didn't have planning meeting. We had so called Product Owner, but he never explain the details of each story, nor define the Done status. We tried Retrospective by ourselves, but the feedback got no response from the team abroad, and we gave up later.

    When we first used ScrumWorks, Product Owner did prioritize all the stories, and we did estimations. But now, everyone can throw stories into ScrumWorks, and no one says which is more important than others, we developers can decide it. If we left hundreds of stories in this sprint, they would be just thrown into the next one.

    Too many things happened in this project, although it still goes on despite all the difficulties, but anyone talking about Agile in our company will make me feel queasiness.