-
Hack Rails的事务机制
- ActiveRecord不支持嵌套事务。
- 为了简单我们在ApplicationController里做了个filter,于是所有POST/PUT/DELETE的action都被包裹在一个事务里,事务边界是整个请求。
- 偏偏有时候你希望让某个操作中的某个部分不被包含在事务里。原因是当某些操作同时进行,你想看到的不是原子的结果,而是所有同时进行的操作汇总的最终结果
- 比如说,“审核改进措施”这个操作中包含了“重新算分”。
- 某企业有两项改进措施R1和R2,分别对应考核类别C1和C2。C1的原始分数是98,C2的原始分数是89。
- R1能给C1加回1分,R2能给C2加回11分。也就是说审核R1之后C1变成99分,审核R2后C2变成100分。
- 但,“重新算分”是在整个“审核”的事务之中的,于是如果R1和R2同时审核,你一定会看到下列两种原子结果之一:
- C1 99分,C2 89分;或者
- C1 98分,C2 100分。
- 其实这个时候我们不想让“重新算分”跟“审核”成为原子操作,我们希望把“算分”从“审核”的事务里拿出来,这样最后一次算分一定能体现最终的分数状态。
- 可以开一个线程或者进程(比如Kernel.system)把算分的逻辑分出来。
- 因为可以确定“算分”不会跟“审核”发生死锁,所以把这个线程join起来。
- 一定要小心,要是算分跟审核修改到同一条数据那么就会死锁…因为审核等待算分线程结束,而算分线程等待审核交出数据锁。
- 多个算分线程之间是不会死锁滴…为了确保时序可以一上来就锁自己最后要更新的分数记录。
-
首选键盘而非鼠标
开发人员实质上是特殊的数据录入职员。我们输入计算机的数据不是来自外界资源,而是来自于我们的大脑。但是数据录入操作员的教训仍能使我们产生共鸣。根据他们所能输入的信息量来收费的数据录入工人知道,使用鼠标会以数量级程度降低他们的速度。开发人员可以从中学到重要的一课。
VI和Emacs都支持一个非常重要的加速器:永远不要将你的双手从字符按键上移开。即使是下移到键盘上的箭头按键都会使你慢下来,因为你必须再次回到主排键来输入字符。真正有用的编辑器会使你的手保持在最佳位置,同时进行输入和导航。
-
开始豆瓣,读书,蹭饭
叶卡粉八卦…自己开了豆瓣以后就要窥探我读什么书…貌似要监督我的样子…昨天驾车经过几年前一起吃火锅的位于熊妍妍家隔壁的地方,突然的觉得不应该辜负她的期望…于是也把读书情况记下来…去年这个时候在西安是能坚持每天读5万字的,最近有点手忙脚乱都顾不上几日不读书口臭了,不应该。
(某位大人说,书读得越多越扼杀想象力。然则,真善美之中大概我最喜欢的还是真实…知道什么比创造什么更要紧…关于第三次世界大战之后情景的科幻小说恐怕我是写不出咯,该位大人应该体谅我这脑子里已然装满了各种关于此题材的小说,毕竟太阳下没有新雪…)
还有一位大人已然到了北京好几个月我还没去蹭顿饭…这个也很不应该…那么,就行动起来吧。
-
一万公里
4月中买的明锐,国庆假期里就开到一万公里了…竟然连一张锐锐的靓照也没有…
第二次换机油滤芯,全车检查。听着时速70时柔和得几乎听不见的引擎声在林荫的道路上行驶,风在耳边沙沙作响。
不在乎目的地,就是喜欢,这样的在路上。
-
白巧克力融化
他年轻的时候没有人能防住他,除了他自己没有人能看清楚他的运球,除了他自己没有人知道下一秒他会做什么;当球在他手上时,你要做的就是睁大双眼,然后尖叫。
现在已经不太有人知道了…大学时候我的床头一直贴他的海报,我一直穿国王的球衣,还会在半夜时戴着手套练胯下运球,而且至今还会偶尔做一个突破中的脑后传球。
最后一个把背后传球、不看人传球和长距离击地传球当常规武器用的NBA球员。最后一个像本能一样做脑后传球的NBA球员。最后一个以华丽、匪夷所思和玩弄对手为至高目标的NBA球员。
向曾经的白巧克力,以及那些曾经或者仍然固执着不被职业篮球改变的伟大球员们,致敬。
-
(LINK)敏捷与精益- 中国软件的发展之路
最近在计算机世界发表了一篇文章
中国应该追求并效仿印度的软件公司吗,比如把它们的组织结构和做事方式都照搬过来?这里的建议是”不”。印度的软件业建立在外包业务的基础上,而中国软件企业有一个更为广大的内需市场。相比用完全可预测的提前计划来保护自己的既得利益,中国更为重要的应该是为快速发展的中国经济提供适应变化的IT支持,从而创造更大的价值。
正在日益发展壮大的中国软件公司应该拥抱敏捷的开发方法和精益管理的行事方式以及一种不同于以往的软件开发者能力模型。笔者相信,通过采用敏捷与精益,这些公司将有能力更快速地交付低成本、高客户满意度的软件产品,并在市场上凸显出中国公司的与众不同。这也是一条可以同印度软件公司竞争的发展之路。
-
重构模式:用异步计算替代长计算
问题
当一个JavaScript计算进程耗时太长,浏览器会弹出警告框,不仅烦人而且一不小心就会点错导致后面的程序不被执行。
很多这类长计算是由于操作大数组造成的。虽然每个元素的处理耗时很少,当数组有几百上千个元素时整个计算时间就会长到超时。由于数组元素数不确定,对单一元素操作调优仍然不能根本解决问题。
办法
把长计算拆解成多个异步的短计算。
即使计算所需的总时间并不缩短,将阻塞的长计算拆解成异步的短计算至少带来响应性的提升:在计算进行的同时用户还可以做其他操作,而不是眼看着整个浏览器失去响应。
在拆解的基础上可以改进任务分发机制以提升整体计算时间。
步骤
- 重构原来的长计算
- 把整个长计算抽取到一个方法中
- 重构该方法使之呈现以下结构:
function longCalculation() {before();var items = getItems();items.each(handleSingleItem);after();}
- 把循环重构为递归
- 把“操作数组中所有元素”的逻辑抽取到一个递归调用的方法,使之呈现以下结构:
function handleItems(items, cur) {if(cur == items.length - 1) {after();return;}var item = items[cur];handleSingleItem(item);handleItems(items, cur + 1);}function longCalculation() {before();var items = getItems();handleItems(items, 0);}
- 把针对每个元素的操作变成一个异步的计算进程──这一步很简单,只要在调用handleItems方法时始终加上delay就行。
以上。应该很容易写出一个类似于library的玩意来封装这个模式。太容易了以至于我不想写。
- 重构原来的长计算
-
Starwood Footprint
受到Andy的鼓励,也来贴footprint
Revision: 4203+———————-+——-+——-+———+———+—–+——-+| Name | Lines | LOC | Classes | Methods | M/C | LOC/M |+———————-+——-+——-+———+———+—–+——-+| Controllers | 1922 | 1600 | 35 | 232 | 6 | 4 || Helpers | 1451 | 1210 | 8 | 206 | 25 | 3 || Models | 4337 | 3555 | 63 | 567 | 9 | 4 || Libraries | 2786 | 2317 | 37 | 233 | 6 | 7 || Model specs | 6689 | 5536 | 1 | 3 | 3 | 1843 || Controller specs | 5216 | 4355 | 0 | 7 | 0 | 620 || Helper specs | 939 | 765 | 0 | 1 | 0 | 763 || Library specs | 2744 | 2262 | 1 | 7 | 7 | 321 |+———————-+——-+——-+———+———+—–+——-+| Total | 26084 | 21600 | 145 | 1256 | 8 | 15 |+———————-+——-+——-+———+———+—–+——-+Code LOC: 8682 Test LOC: 12918 Code to Test Ratio: 1:1.5
正如Andy说的,4月到9月,trunk上共计约2400次commit。按照平均4个pair来算,每个pair每天提交6次。
除去统计失准的rspec部分,功能代码共计8682行,1238个方法,平均每个方法7行。测试代码是功能代码的1.5倍。
考虑到Ruby on Rails作为特别擅长开发web应用的框架所具备的强大表现力,以及对重复代码的低容忍,再加上stats所统计的只是Ruby代码(不包括HTML、JavaScript等代码),我毫不怀疑这个系统的复杂度能够等量于很多十万行代码级别的系统。
而重要的是,这个团队里的每个developer了解系统的每个角落──至少是能够在相当短的时间内通过阅读功能代码和测试来了解。每天6次的提交频率就是明证。
所以,作为总结,是一个值得骄傲的项目。
-
从持续集成开始,你怕啥呢?
人家说,你们搞这贸贸然的就持续集成,不行的。
1、认清真正的敏捷
通过学习和调研,认清什么是真正的敏捷。如果一些基本初始概念就错了,那么在后续的推行中必然会差之毫厘、谬之千里,真正的敏捷实施也就无从谈起。
2、预估推行敏捷的收益
在确认知道什么是真正敏捷的前提下,对自己团队、组织的现状、问题和薄弱环节进行评估,设定改进目标,并预估敏捷能否解决这些问题,带来潜在的改进。如果成功的把握小于 50%或者现状已经足够好,就不要推行敏捷,何必劳民伤财呢。
有意思啊。弄不清什么是“真正的敏捷”,“现状已经足够好”,就不需要改进了?就不要解决问题了?
怕啥呢?怕的就是这持续集成它是实打实的东西吧。怕的就是持续集成一上,所有的问题都以测试是红是绿这么截然的方式暴露出来,逼着不得不解决吧。怕的就是持续集成它没有放之四海而皆准的套话可以讲,build脚本得一点点写出来吧。怕的就是没人跟您玩“学习和调研”了吧。怕的就是“真正的敏捷实施”卖不掉了吧。
作为一个专门帮人解决问题的,我越来越频繁的说,我不在乎敏捷不敏捷。你告诉我,你有什么问题,咱们一起来看看怎么解决。可能一个项目做到最后你还是不搞敏捷,没关系,我解决你的问题提高你的效率就行。
ThoughtWorks是一个做实事的公司,所以我们认为每个项目应该做的第一件事就是让真正的软件开口说话,说出它有什么问题,然后我们来解决问题。难怪有人要怕呢。光顾着解决问题,那学习和调研基本初始概念的事可扔到哪儿去了呢?
怕是又动了谁的奶酪了吧。
-
南戴河,中秋
到昌黎的葡萄沟去买了新鲜的葡萄酒。
From昌黎葡萄沟 葡萄一串串的,很好看。
From昌黎葡萄沟 在平坦又少人的路上跑了一天,明明的平均油耗降到5.7…到晚上走了一段乡间路最终到了5.9。
From昌黎葡萄沟 乐极生悲…拖底了。跑完长途回京一定要去4S店检查,这个好习惯要保持下去。