-
千里走单骑
早上6:30,从望京磨磨唧唧发车。天漆黑。日出很美。
7:34,出北京界。京石高速¥15。
过石家庄,在元氏服务区加油,¥140。
11:36,出河北界,高速收费¥160。
12:03在安阳服务区休息,吃自己带的肉松饼。犯困,喝红牛。右侧脖子酸疼。
13:10在新乡服务区加油,¥125,听说是乙醇汽油又买了加油员推荐的添加剂,¥30
郑州许昌一段脖子疼得难受,戴墨镜更觉头疼。在许昌服务区再次休息,喝红牛。转上许平南高速以后头疼减轻。
改成右腿(准确说是右膝附近)酸疼。平顶山和方城服务区都休息。许平南路况好,车少。
16:13,南阳下高速,收费¥210。
16:40酒店checkin。晚饭吃一大碗烩面,当地的辣椒呈小块状,很香。
总里程约950KM,总时间约10小时,路上总费用680。
结论:(1)日行千里是可行的;(2)也是很累的。(3)如果夏天两人换开的话一天可以干到武汉去。
明日目标:荆州-常德
-
快速冲锋步
快速冲锋也有节奏。把节奏记下来,下次可以改进。这就是泰勒在伯利恒钢铁公司做过的事。
- 愿景(1小时):我要做个东西,要快。也许应该试试用Rails做?因为它很快。似乎没有特别的原因阻碍用Rails?是的,没有。
- 空谈(1小时):它好像是个什么东西。它看起来有点像Mephisto吗?呃,Mephisto是什么?你看,我用Mephisto做了我的blog和AgileChina的网站。不错,看起来有点像。
- 部署(3小时):给我服务器,我把Mephisto架起来。没问题,连域名都给你。
- Rails 2.2在Windows上不好使,因为MySQL gem的原因,也许应该装Ruby version而非win32 version
- 在Windows平台使用Apache2.2和Mongrel运行Ruby onRails
- 原型+反馈(3小时):现在你可以添加内容了。管理后台和我想的不一样。我们可以定制Mephisto。定制是一堆破事,重做也是一堆破事。你让我想想。
- 抛弃(30分钟):现在我基本上知道你要什么了。我决定重做。
- 堆砌(2小时):插件,generator。我知道所有的convention。没有测试。我要看到第一个页面,让我可以部署它。
- 第一个model不是User,而是核心概念
- 第一组数据写进fixture,直接load到产品系统
- 第一个migration叫做release_1,不允许回滚
- 第一个build脚本就用上svn.rake
- 用TODO文件来管理storys/defects/unknowns
- 再次部署(30分钟):尝试过Mephisto,现在我知道该怎么部署了。
- 反馈+小步前进(6小时):好像可以发布内容了,酷。用户权限我是这样设想的。能不能这样简化?以后我们可以这样去改变。可以,我们可以先控制邀请。
- 给build脚本加上stats:我允许现在测试覆盖率低,但从现在开始它必须一直提高
- 每次代码修改开始加上测试,因为我开始记不清每个细节了
- 没有Selenium
- 每个story完成后立即部署
- 发布+反馈(1小时):告诉我一个帐号。quentin和admin都可以。我添加了一些东西,有些更多的想法。TMD…我本来没打算发布的。看在你费劲的份上,就算我发布了吧,现在开始不再清数据库。
- 新的migrations:每个migration只做一件事,每个migration都可以rollback。
- 继续小步前进(6小时):SMTP server帮我搞搞好。80端口给我。我收到邮件了。80端口腾出来以后我再改Apache配置,共计需要删掉4字符。
- 界面的手工验证开始变多
- 复杂的业务逻辑出现,借用了上一个项目的经验,还是出了一点tricky的错误,耗时30分钟
从周六开始,共计5天业余时间,或换算成3个工作日。
-
最后一公里总是比你想象的长
软件不被部署到产品环境,就不能被真正的用户使用;软件不被真正的用户使用,它创造的价值就是0。
不管做了多少,没有真正部署,就等于什么都没有。
所以,部署不是最后一天才需要做的事。部署是第一天就应该做的事。当第一个功能被开发出来,紧跟着优先级最高的就是部署它,而不是开发第二个功能。如果这时部署被block住,这就始终是优先级最高的blocker,不解决就食不甘味夜不能寐。
客户每次看到软件,都应该是在实际的产品环境下看到──即使不是最终那个实际的产品环境,你也必须清楚,只要一个按钮,你就可以让它成为实际的产品环境。这个按钮不存在于想象中,你必须亲手按过它,知道它一定工作。
如果产品服务器还没有到位,如果还要等系统管理员来装什么软件,如果网络还没有调整好…如果客户跟你说“不用着急”。这时候你就必须着急,你必须尽你一切努力让“部署”按钮成为现实,然后按下它,看到它真的工作。
否则,最后一公里一定比你想象的长。
-
美国·历史·跨界阅读
这是一种运气:在读这本《美国众神》的同时,恰好也在读《贸易打造的世界》。
好吧,一本重要的科幻小说和一本不太重要的经济散文集,两者之间的交集是什么?
答案是,关于美国,这个全世界最受关注的国家,那短短的历史,一些并不广为人知的内容。
有一个──很可能是我编造的──笑话:一个美国人问一个中国人对西藏问题有什么看法,后者反问:
How about California? It had been a part of Mexico, until gold was found there in 1848.
有时神秘的荒诞的愚昧的轶传的调侃的一厢情愿的经不住考证的传说故事比教科书上的历史似乎更值得相信。
这是对历史的讽刺么?
-
重构是关于行为保持的技术
重构首先是一个形式化的过程:如果必须把代码看懂了才能重构的话,那么你就会让自己陷入一个悖论,因为最需要重构的代码你是看不懂的
WilliamOpdyke用他的博士论文奠定了重构技术的理论基础,而这篇博士论文的核心则是对“行为保持”的研究。简言之,在这篇论文中,William用数学方法证明,在满足特定条件的情况下,以特定形式进行的程序修改将不影响程序的行为(也即“行为保持”),并且行为保持的修改之间的组合也将继续是行为保持的。
精华在第4章。
-
重复信息是邪恶的
就算不说所有的软件问题都是因为信息重复造成的,至少很多问题确实是因为重复造成的。
是什么带来了痛苦?是信息的分布吗?
String title = “Blog”;
和String title = “博客”;
有什么重要的区别?一个字符串字面量包含了两重信息:(1)字符串的内容;(2)字符串的编码方式。这两个字符串的区别在于,前者的编码方式是缺省的ASCII而后者带有额外的编码方式信息(例如UTF8或者GBK)。
所以真正的问题是信息重复,关于“如何编码字符串”的信息被重复了。
重复信息是邪恶的,信息应该在并且只在一处被表述。
-
Mongrel的内存占用确实成问题
2 sets of configurations:
- A. 20 mongrel instances 300MB memory limitation for each
- B. 10 mongrel instances 512MB memory limitation for each
- with config A, total memory usage is about 6000+MBytes
- with config B, total memory usage is about 4000+MBytes
- in normal cases, the momory usage of each mongrel instance is about 400MBytes
- for operations with light calculation, config A is generally faster than config B
- for operations with heavy calculation, config B is more efficient than config A when load(amount ofconcurrent users) grows
- more importantly, config B performs more consistenly than config A
- config A fails 2 test cases for 15 concurrent users, and the possibility of failuregrowssignificantly to 5.57% for 20 concurrent users
- config B doesn’t fail any test case
- the degrading curve of performance of config B is flatter than config A
- besides the memory usage,CPUusage is yet another bottle neck of performance
- 20 mongrel instances on 1 server overloads the CPUs, and thus degrades the performance
- reducing the amount of mongrel instances makes HAProxy works as a queue, therefore makes thesystem performslinearly
- prefer config B than A: 10 mongrel instances on each of 2 production servers can handle 20concurrent users,which (based on my experience) effectively means at least 1000 users onlineAT THE SAME TIME
- try config C (15 mongrel instances 400MB limitation for each) and D (5 or 7 mongrel instances 512MBlimitation for each),IF NECESSARY
-
僭序《实现模式》
(InfoQ:《实现模式》中文版面市)
这是一本关于如何写好代码的书。
如果你不认为写好代码是一件重要、困难并且有趣的事,请立即放下这本书。
什么是好的代码?可以工作的、性能良好的、不出bug的代码,就是好的代码吗?
所谓好的代码,除了其他所有要求以外,还应该清晰准确地传达写作者的想法。
Martin Fowler在《重构》里说:“任何一个傻瓜都能写出机器能懂的代码。好的程序员应该写出人能懂的代码。”
如果你不同意这句话,请立即放下这本书。因为这是一本关于如何用代码与他人(而非机器)沟通的书。
任何读到这一行的程序员都应该读完这本书。
SteveMcConnell在《代码大全》里说:“不要过早优化,但也不要过早劣化。”这本书将告诉你如何在几乎不引入任何额外成本的前提下避免一些常见的低级错误——它们是常见的,因为几乎每个人都犯过并且还在犯着这些错误。
如果你确实没有时间,至少应该读完第6章“状态”。因为在各种常见的低级错误中最常见者就是关于“什么信息在什么地方”的决策错误。
在这样一本书的序言里说任何废话都将是佛头着粪。
所以,现在就祝你阅读愉快、编程愉快。
是为序。
-
读·沈从文
因了某人的缘故,连着两天,读了沈从文的《边城》、《凤凰》和半本的《从文自传》。
最感触的,便是这句话:
知识同权力相比,我愿意得到智慧,放下权力。我明白人活到社会里应该有许多事情可作,应当为现在的别人去设想,应当如何去思索生活。且应当如何去为大多数人牺牲,为自己一点点理想受苦,不能随便马虎过日子,不能委屈过日子了。
太多的道理,太少的感觉。所谓左脑作主,便是如此的罢。
而后半本的自传里,竟然连他自己也说起道理来了。
-
Recommendations From The Build Master
It’s about multi-team configuration management (or continuous integration). It’s fromThe BuildMaster.
- Create the mainline (public) and virtual build labs (private) codelines.
- Make sure the mainline is pristine and always buildable and consumable. Create shippable bits ona dailybasis. Use consistent, reliable builds.
- Build private branches in parallel with the main build at a frequency set by theCBT.
- Use consistent reverse and forward integration criteria across teams.
- Be aware that dev check-ins are normally made only into a private branch or tree, not themainline.
- Know that check-ins into a private branch are only reverse integrated (RId) into main whenstringent,division-wide criteria are met.
- Use atomic check-ins (RI) from private into main. Atomic means all or nothing. You can back outchanges ifneeded.
- Make project teams accountable for their check-ins, and empower them to control their buildprocess withhelp from theCBT.
- Configure the public/private source so that multisite or parallel development works.
- Optimize the source tree or branch structure so that you haveONLY ONEbranch per component of your product.
