透明思考


Transparent Thoughts


  1. 出新意于法度之中

    周末去看了邱志杰的展览。对他的舞蹈课很是喜欢。

    创新不得和以前重复,这是艺术界的游戏规则;创新会越来越难,这是艺术史的规律;在早期,更多的事不用多加思索的本能选择,游戏越往后,组合、颠覆等可以开发创意就越来越经常被依赖;而是否被认可为创新,这是由之前已经出现过的现象以及众人的裁定所决定的。

    在很大程度上,艺术家并不像传说中的那样自由,相反,自由和个性要通过艰难的开发才最终会获得。因此,你必须去研究整个系统,你必须形成一种能够开发创造力的工作机制。

    缺乏创意或是坐井观天,如果一定要选的话,究竟哪一个更糟?和Miya说,想一想,如果有一天我也变成这样,以为自己看见的一个小圈就是整个天空,挺可怕的。何况,井里的创意,又能有什么好玩的。


  2. Cygwin的包管理器

    apt-cyg: install tool for cygwin similar to debian apt-get

    需要先安装wget、bzip2、tar和gawk。

    现在就可以体面地找软件和装软件了。

    apt-cyg find gcc

    apt-cyg install gcc


  3. 对象训练营:简介

    对象训练营是ThoughtWorks历史悠久的入门培训课程,而其中谈到的对象原则和实践历史就更悠久。面向对象的思想明显地分为两个阵营:

    • Rational。强调建模,推崇UML和形式化方法。这些人最初使用ADA为军方开发软件,系统本身并不复杂。软件正确性非常重要,因此重视对设计的评审。
    • Tektronics,一家电子设备测试工具制造商。强调示波器的可插拔性。使用新的编程语言Smalltalk,因为它的灵活性。这支团队中涌现了Ward Cunningham、KentBeck、SamAdams等敏捷世界的大师。使用Smalltalk,他们在设计和编码之间快速切换,这也是现在Agile的基本工作方式。

    80年代中期Tektronics团队解散,Sam Adams加入KSC咨询公司,当时在IBM负责与KSC接口的Fred George从他那里学到了Tektronics的对象思想。后来FredGeorge加入ThoughtWorks,并开创了对象训练营。因此本课程是基于Tektronics的对象思想,而不是Rational的。

    本课程采用苏格拉底式教学法,简单说就是学员自己教自己。我们会用问题来引导你,但不会手把手地教你正确答案。你会受阻,但这是好事。正如FredBrooks所说:“好的判断来自经验,而经验来自糟糕的判断。”记住受阻的时刻,并从中学习,这些经验会成为未来良好判断的基础。

    本课程至少3/4的时间会用来给学员自己动手练习编程。如果你喜欢编程,这些练习会很有趣。我们会针对练习中写出的代码展开讨论,所以每次讨论都会把某个pair的代码用投影展示出来供大家讨论。一开始也许你不好意思展示自己的代码,但是请大胆展示。被批评是最好的学习机会。

    课程内容分为两大部分:(一)对象原则与敏捷实践,(二)设计模式。


  4. 持续集成铁的纪律是怎样炼成的

    持续集成问题说到底是人的问题

    有一种常见的观点认为:持续集成是一系列技术问题;只要安装配置了适当的持续集成工具,解决了某些构建、测试自动化的技术问题,持续集成建设就能顺利开展。但实际上,持续集成建设中很少出现高难度的、超出团队本身能力范围的技术问题,涉及的工具也大多通用。持续集成建设中遭遇的一些典型难题,归根结底都不是技术问题,而是人的问题:

    • 构建失败率高:背后的原因是开发人员质量意识不足,习惯把质量保证的责任全部丢给测试人员
    • 构建修复难:背后的原因是开发人员在本地开发机无法重复构建过程,难以定位问题
    • 在失败构建上继续提交代码:背后的原因是构建结果不够公开、受重视不足

    持续集成建设就是提升团队质量能力的过程

    建设一个运转良好的持续集成体系的过程,就是在培养每个团队成员重视质量的意识,就是在帮助团队发现交付“最后一英里”潜藏的问题、并督促团队解决这些问题。为了保持项目的健康,需要整个团队的努力:

    • 加强对质量的关注,代码经过必要的自检再提交
    • 制定简明严格的提交纪律,构建失败及时修复
    • 用构建监视器显示持续集成状态,使项目健康情况公开可视
    • 为开发人员提供本地构建能力,以方便自检和问题定位


  5. 《持续集成建设》引言

    软件开发的最后一英里

    在任何软件开发过程中都有一个重要的部分:通过某种构建(build)流程,将已经编写好的源代码变成可用、能为客户创造价值的软件。尽管知道构建的重要性,但是我们仍然会经常因为构建中的各种问题而惊讶不已。曾有多少次,在所有人都认为“开发已经完成”之后,我们还要经历漫长而痛苦的编译、打包、联调、测试、上线过程?在代码都已经写好之后,我们还曾付出了多少个通宵的代价让软件真正可用?

    编写源代码不是软件开发的全部。从源代码构建出可用的软件,这个过程也被称为“软件开发的最后一英里”:胜利似乎就在眼前,但各种潜藏的危机可能这段短短的路程变得艰难万分。

    持续集成就是构建过程

    构建之所以如此困难,是因为在绝大多数软件组织中,构建过程有以下几个特点:

    • 它是一个神秘的、不可见的、只(模糊地)存在于少数人大脑中的过程
    • 它是一个需要人工操作的、耗时费力的、容易出错的过程
    • 它是一个偶尔为之的、缺乏练习的、充满未知风险的过程

    为了减少“最后一英里”的浪费,让艰险的最后一英里成为坦途,我们需要将构建过程明晰化、自动化、频繁化。持续集成就是一个将构建过程明晰化、自动化、频繁化的实践。通过使用软件工具来实现自动化的构建过程、展示构建结果,原本虚无的构建过程就成为了一个实际存在的、可以重复进行的、可以被有效管理的实体。从这个意义上来说,持续集成就是构建过程本身:只有以持续集成的形式呈现的那部分构建过程,才是确定并可靠的;“最后一英里”中尚未被纳入持续集成的部分,仍然是不确定和有风险的。


  6. 团队空间

    Martin Fowler说,一个好的团队空间,要有大面的墙作为信息辐射器,团队要围着大桌坐以保持眼神接触,要有自然光线和看到外面景色的落地大窗。

    ThoughtWorks北京的办公室,Martin Fowler认为是一个好的团队空间。

    这个空间又如何?除了缺少自然光,也是个不错的团队空间。


  7. 谁需要分布式事务?

    有个项目,用Tuscany实现了SCA。然后呢,服务与服务之间会互相调用。然后呢,因为你不知道被调用的下一个服务被部署在什么地方,所以就需要分布式事务。一切多么的合理。

    Bullshit.

    Martin Fowler说,分布式对象设计第一原则:不要分布你的对象。如何利用多个进程?集群,而非分布。

    因为很显然,如果应用程序本身是无状态的,分布式对象基本上无法带来任何集群不能提供的好处:性能,吞吐量,都不可能在涉及跨进程调用的情况下超过进程内调用。唯一可能的好处是,能够把应用程序分成小块,分别部署在不同的机器上。

    是的,这就是这个项目需要分布式对象(以及,分布式事务)的真正原因。当然,不是因为一台服务器不能负载整个应用程序,而是因为一个邪恶的原因:把功能模块与服务器硬件绑定。你已经买了功能A,还想要功能B吗?请购买功能B──和它所在的整个服务器。不管你的访问量是否大到需要一台真正的服务器,我们粗制滥造的程序会把它的性能都用尽的。

    是的,再一次地,一个企业级超复杂技术的漂亮广告词被扯开之后,归根结底就是一个制造浪费从而制造需求的邪恶玩意。FxxxIBM


  8. 一只土贼

    我承认一开始我认为小熊就是一只土贼。有次内部讲session的活动,别人的主题都是有模有样的理论结合实践,小熊搬把凳子往中间一坐,胶片也没有,开口第一句就是很土的话:

    “其实搞客户就是将心比心。你想想他的利益是什么,帮他把事情搞定了,他就喜欢你了。”

    好吧,确实是很有sense的实话。不过这种没有理论高度的话游沁说也就罢了,作为我司的咨询师用湖南塑料普通话这么讲出来,咋就觉得那么土呢?

    广州呆了一段时间之后我就发现这个小海龟基本上是故意装土,装得很土那么别人就觉得自己很洋于是就愿意跟他嘻嘻哈哈。处女座在人际关系上的感觉就是特别敏感哈。而且他有两个特别的好处,第一很会画画,第二对浪费极其敏感。我最喜欢和这种完美主义强迫症患者一起工作。

    然后小熊就搞出了史上最华丽的故事墙。在他的感染下我也搞出了一个华丽的大屏幕CI监视器。并且开始用各种华丽的方式工作,虽然还不如他华丽哈。

    今天小熊感到很兴奋,表示我们的工作很有意义,并且立下了要出名的目标。我觉得他可以出名。唯一的缺陷就像(忘了是谁)说胡适的:“这个人路子是对的,就是没读过多少书。”我们大部分人都是理论结合实践,他要把实践结合一下理论,拔高一下再写出来,一定会出名。

    总之,我觉得这只土贼有可能成为国内最好的敏捷BA。所以我现在开始收集他的签名。

    (还有哈,顺便给这个帅锅BA蒸个女盆友~~小熊表示青春痘都冒出来了的日子还是有点造孽~~有意的女童鞋可以找我报名~~)


  9. 关于内部工具开发的若干建议

    (本文都是基于某些现状与设想的建议,没有得到实践验证。仅供参考,责任自负。)

    作为一个超级大软件企业的内部工具开发部门,需要考虑几个重要问题:
    1. 避免作恶
    2. 发布管理
    3. 技术支持

    在考虑开发一个工具提供什么价值之前,首先考虑可能造成什么伤害。世界上有很多的开源工具。这些工具不仅仅是源代码的堆积,其中融入了一些最优秀的软件开发者在某一领域的经验与智慧。贸然开发一个新的工具,哪怕只是对现有开源工具的包装,都可能导致很多人失去学习这些经验与智慧的机会。优先考虑知识的普及。教人读《J2EEDevelopment WithoutEJB》比开发又一套框架要好,虽然做起来会更难。春天的旁边是一个好的框架,因为它重视知识的传递而非包装现有代码。

    使用业界公认的依赖管理工具来发布。通过邮件发给用户一个“XxxxXxx-V001R002C004B035SP02.exe”是不负责任的。使用Maven2或者YUM或者APT或者RubyGems这样体面的依赖包管理工具来发布你的作品。这样能让用户知道自己得到的每个版本都是经过某种发布流程的而不是一个野版本,并且使你的工具能以最低成本与其他依赖包集成。如果公司的信息安全规定禁止普通开发人员上外网从而导致他们无法使用这些体面的依赖管理工具来搭建自己的工作环境,给他们搭一个内部私服,并把下载新依赖的请求委派到互联网。这不仅有利于你自己的工作,而且能让开发人员的生活变得更容易,他们会因此感谢你。

    (Windows到现在也没有一个体面的依赖管理工具,所以Windows is stupid。)

    用一个简单易用的Bug跟踪工具来管理所有的支持要求,例如Trac就很好。建立一个邮件列表,把所有曾经提出支持要求的人都加进去。给用户建立社群,他们就会自己解决绝大部分的愚蠢问题。不要为了漂亮的界面而把事情搞得复杂。用户提问,你解答,把这些事情都变得就像发一个邮件那么简单,你就能得到一个社群──你确实应该考虑充分利用邮件,因为用户不会在知道了支持人员的邮件地址之后还记住你的在线支持社区地址。向那些体面的开源社区学习,向Google学习,看看他们是如何响应用户需求的。

    最后,开放源代码。尽管概率很小,但确实有些用户会给你贡献源代码(至少在他们失去耐心继续等待你的fix时)。像Microshit那样暴露几个莫名其妙的编程接口然后宣称“我们的软件具有可扩展性”是不够的,因为扩展永远都会在你没有想到的地方发生。不要把工具的开发者和用户隔开,因为那些用户很可能是比你更好的软件开发者。开放你的SVN地址,把它和开发指南的链接放在工具介绍的第一页上,就像绝大多数体面的开源项目所做的那样。及时并真诚地感谢那些给你贡献代码的人,以及那些checkout了你的代码库并嘲笑它的人,因为他们会让你的软件变得更好。

    最后的最后,随时准备抛弃你自己的任何东西,从一段源代码,到一个功能,甚至整个软件。如果你的目标是让别人的工作更容易的话。


  10. 配置分布式的CruiseControl

    这个文档描述得不是很清楚,因此记录一遍。首先需要同时下载src发布包bin发布包

    解开src发布包,在其中build distributed插件,然后把contrib目录copy到bin发布包解压后的目录:
    cd $CC_SRC/contrib/distributedantcd $CC_BINcp -r $CC_SRC/contrib ./contrib
    修改$CC_BIN/cruisecontrol.sh,在其中包含distributed插件的classpath:
    … …CCDIST=$CCDIR/contrib/distributedCCDIST_BUILDER=$CCDIST/dist/builder/CCDIST_CORE=$CCDIST/dist/core/CCDIST_JINICORE=$CCDIST/jini-core/CCDIST_JINILIBDL=$CCDIST/jini-lib-dl/jsk-dl.jarCCDIST_CONF=$CCDIST/confEXEC=”$JAVA_HOME/bin/java $CC_OPTS -Djavax.management.builder.initial=mx4j.server.MX4JMBeanServerBuilder -Djava.security.policy=$CCDIST_CONF/insecure.policy -Dcc.library.dir=$LIBDIR -Djetty.logs=$JETTY_LOGS -jar \$LAUNCHER -lib $JAVA_HOME/lib/tools.jar -lib $CCDIST_BUILDER:$CCDIST_CORE:$CCDIST_JINICORE:$CCDIST_JINILIBDL:$CCDIST_CONF \$@ -jmxport 8000 -webport 8080 -rmiport 1099”echo $EXEC$EXEC &echo $!  cc.pid
    在$CC_BIN/config.xml中指定需要分布的工程:
    plugin name=”distributed”classname=”net.sourceforge.cruisecontrol.builders.DistributedMasterBuilder”/… …distributedant antscript=”/usr/bin/ant”antworkingdir=”/path/to/my/project” //distributed
    打开Lookup server:
    cd $CC_BIN/contrib/distributed/dist/lookupant

    然后,把cc_agent.zip拷到Agent机器上,修改conf/agent.properties配置,ant启动,就好了。

    (郁闷地搞了一下午的心得是:不要尝试在Windows上做任何严肃的开发工作。Stupid Windows.)