草色天涯
-
刘未鹏的博客上这样写:
好资料,坏资料。好资料的特点:从问题出发;重点介绍方法背后的理念( rationale ),注重直观解释,而不是方法的技术细节;按照方法被发明的时间流程来介绍(先是遇到了什么什么问题,然后怎样分析,推理,最后发现目前所使用的方法)。 坏资料的特点是好资料的反面:上来就讲方法细节,仿佛某方法是从天上掉下来的,他们往往这样写“我们定义… 我们称… 我们进行以下几个步骤… ”。根本不讲为什么要用这个方法,人们最初是因为面对什么问题才想到这个方法的,其间又是怎样才想出了这么个方法的,方法背后的直观思想又是什么。实际上 一个方法如果将其最终最简洁的形式直接表达出来往往丢失掉了绝大多数信息,这个丢掉的信息就是问题解决背后的思维过程。
知道了资料的好坏之分,我们也就可以知道如何更好的写文章,讲道理。
学习一个东西之前,首先在大脑中积累充分的“疑惑感”。即弄清面临的问题到底是什么,在浏览方法本身之前,最好先使劲问 问自己能想到什么方法。一个公认的事实是,你对问题的疑惑越大,在之前做的自己的思考越多,当看到解答之后印象就越深刻。记得大学里面的课本总是瀑布式地把整个知识结构一览无余地放在面前,读的过程倒是挺爽,连连点头,读完了很快又忘掉了,为什么?因为没有带着疑问去学习。
这跟我上一篇博客所讲的“主动思考”是一致的。
-
如何提高读书的投入产出比─主动思考 - [朝花夕拾]
2009-10-15
在上篇博客中我先是引用了笑来老师在《把时间当作朋友》中的一段文字:
“所有学习上的成功,都只靠两件事:策略和坚持,而坚持本身就应该是最重要的策略之一。”
接着便引申开来谈为什么有些事情难以坚持:
从我的个人体验来看,难以坚持下去的事情,基本都是因为没有迫切的欲望和激情。单说锻炼身体,无论是为了减肥,还是祛病,还是塑形美体……至少都有明确的目的,才能驱动着人们一直坚持下去,不会偷懒。没有动机,没有欲望,哪里来的毅力呢?
当时我只看到了书的前20页,今天又看到第30页上的另外一段话:
不劳而获是每个人心中所拥有的诸多梦想之一,甚至可能还是其中最大的梦想。如果不能做到不劳而获的话,那就最好尽量少劳但是一定要尽量多得,并且尽量多多益善。更进一步,大多数人看法惊人地类似甚至相同:如果有收获的话,那最好马上要有收获;如果没有收获的话,那最好要马上有结果……
要命的是,整个社会在用各种各样的方式刺激人们的这种天性并使其越来越强烈。电视广告告诉你所有的减肥药都有神奇的功效…各种培训班告诉你不管学什么都要速成… 其实,承认“希望自己的欲望马上获得满足”是自己的天性就好办了。因为,平静接受并且正确认识自己的天性是改变天性的第一步…
我在写那篇文章的时候也在想,有清晰明确的目的对于坚持并养成习惯而言,仅仅只是一个必要条件而已,但还有哪些必要条件和充分条件呢?也考虑过很多方面,但并没有想到“不劳而获”这个天性上来。于是这段话给我的印象就很深刻,然后我就按照刘未鹏同学在“如何更好的记忆与学习”中所说的那样,跟自己的经历相关联,思考自己应该在哪些方面战胜“不劳而获”的思想,耐心的投入时间和努力,因为“今天的所有轻松安逸,都可能是未来的成本”。
接着我便又问自己,为什么这段话给我的感触这么深?是因为它阐述的道理,还是因为文字表达的方式,还是因为听了刘未鹏的话?
这些肯定都是原因,但我感觉它们一定不是最重要的。于是我想了又想,后来还是刘未鹏的博客给了我启发。我今天看的是他讲阅读方法的一些博客,如“一直以来伴随我的一些学习习惯(三):阅读方法”,再如“阅读与思考”,我点开这些链接以后,下意识的没有先进去看内容,而是移开视线回想自己的读书方法,阅读习惯,然后再去看他的方法比我的好在哪里──在写完这篇博客之前我还没进去看:)。这时候就忽然灵光一闪,也许就是因为我在读书之前,先对“为什么习惯难以养成”进行了思考,得出了“缺少目标驱动”的结论,所以等看到“不劳而获的天性”这一论断时,与自己的想法进行对比,印象自然就深刻而鲜明了。
其实,这跟刘未鹏所说的“将别人的经历或者通过阅读和观察得来的经历和自身的经历进行比较,常常能够得到非常有价值的结论。”也有相近之处,只是在阅读和观察之前多了一步思考过程,而这对强化理解和记忆便居功甚伟。 所以我接下来的打算是,读完摇摆的序言和目录之后,就先回想一下从前在生活中或者自己做过、或是目睹耳闻过哪些不理性的行为,试着自己对这些行为给出解释,然后再来看这本书。也许单纯从阅读的速度来讲,这种方式会慢的多,但我相信从长远的角度,从投入产出比来看,它是值得的。就像单元测试一样。
-
本文节选自我为《高效程序员的45个习惯》写的推荐序,有删节。本书的译者是郑柯和钱安川,由图灵公司出版。
所谓“流水不腐,户枢不蠹”,厨房脏了就擦一下,总比满墙都是油烟以后再去清理的代价小得多。有价值的东西──比如回顾、比如测试、比如重构,一切有利于团队建设、有利于提高生产力的实践都该频繁做、持续做,然后──就养成了习惯。
有些习惯很容易养成,有些则很难。 我们大都常常许愿、做计划,比如要做一个成熟到至少100人在线的应用,比如参加义工活动,比如每周至少一篇博客……然后在计划落空的时候,用各种理由来安慰自己。
李笑来老师在《把时间当作朋友》一书中提到,“所有学习上的成功,都只靠两件事:策略和坚持,而坚持本身就应该是最重要的策略之一。”那么,为什么我们会在某些事情上坚持不下去呢?或者换个角度来看,哪些事情是容易坚持下去的呢?
以前我是标准的宅男,CS、网络小说、魔兽世界几乎是休闲的全部,等到后来得了腰肌劳损,又得了颈椎病,这才痛定思痛,开始游泳。每天游上两千米,一个月以后,游泳就成了习惯。再举个例子,我老婆生完孩子以后体型变化很大,刻骨铭心的想要减肥。为了坚持下去,她把怀孕前的照片放在电脑桌面上,时时督促自己。后来,减肥也就变成了一种生活方式。
从我的个人体验来看,难以坚持下去的事情,基本都是因为没有迫切的欲望和激情。单说锻炼身体,无论是为了减肥,还是祛病,还是塑形美体……至少都有明确的目的,才能驱动着人们一直坚持下去,不会偷懒。没有动机,没有欲望,哪里来的毅力呢?
那么,当我们决定做一件事情的时候,首先就该多问问自己,为什么要做这件事情?它所带来的好处是什么?如果不做它又会有哪些坏处?有了清晰的目的和思路再去做事,遇到变化时就知道孰轻孰重,该怎么调整计划,同时也不至于被重复和枯燥消磨了一时的意气。翻开这本书之后,你同样也该向自己提问,“为什么要有自动验收测试,有了足够的单元测试是不是就能保证质量了?”“写自动验收测试有哪些成本,会带来哪些收益?”只有明白了“为什么做”,才能够解决“如何做”的问题。 -
从误解看敏捷实施的阻力──思维方式 - [敏捷开发]
2009-10-13
我们常常能够看到或是听到许多有关敏捷的问题,无论在邮件组里、在技术交流活动上,还是在客户现场的时候──当然,最后一点是废话,没问题人家请你去咨询干嘛?有的问题只是简简单单的疑问、困惑,这就容易解决;但有些问题则是误解,当误解产生以后,扭转人们的观念相比起答疑解惑就要困难的多。于是我最近一直在考虑,这些误解产生的根源是什么呢?有什么方式可以帮助我们更容易说服对方,化解误解?我们在宣传推广某些理念的时候,又该怎样避免让别人产生误解?假如话题不仅限于敏捷,那我们自己在平时会存在哪些类似的思维误区?我们自己又可以怎样避免?
这些问题我并没有很好的答案,刚根据刘未鹏的博客和豆列买了几本有关行为经济学和判断决策的书,例如“怪诞行为学”、“别做正常的傻瓜”、“摇摆”,接下来应该还会读一些心理学方面的书。这篇博客只是记录一下我今天所想到的一些思考角度,希望看到的朋友能够不吝拍砖。
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: 是的, 本质上这是一个心理学和政治学的问题, 我也无法说服你.
-
多少年过去了,乡村的夜晚还是一如既往的黑。
也正因为如此,每次回到家里,总能看到星斗漫天,依稀可见银河的模样,或是明月高悬,旁边伴着一颗孤零零的小星。
我最爱这样的夜,站在空荡荡的庭院里,陶醉于清凉的星光月色,任寒气侵上身来,每每第二天便鼻子透不过气。
忽然想起十多年前的一个夜里,该是凌晨一点多钟的时候,我睡不着觉,便趁着月色骑车行了十多里地去看同学,到了村口,发现几天前的大雨留下的泥泞实在穿不过去,兴致也已尽,便作回转。那天,便只有这样一碧如洗的夜空,和不知照过多少深夜行人的明月,跟我一起走了两个来小时的路。
以后还会有很多很多这样的夜色,只是到哪里去寻有着同样精力同样兴致的莽撞少年呢? -
zz 给旅游者的忠告 - [朝花夕拾]
2009-09-29
一、 不要接近峨眉山的和尚。
二、 不要接近崂山的道士。
三、 不要买九寨沟的牦牛肉。
四、 不要买三峡船上的玉器珠宝。
五、 不要在西双版纳参加“抢亲”游戏。
六、 不要在西安的古玩一条街购买古物。
七、 不要在大理购买所谓“老乡”的便宜珠宝。
八、 不要在阳朔的酒吧里消费。
九、 不要招惹泰山景区的当地人。
十、 不要参观少林寺时走“捷径”。
十一、 不要逛十三陵“***”玉石店。
十二、 不要单独去海南旅游。
十三、 不要在坝上草原骑马。
十四、 不要在吐鲁番买葡萄。
十五、 不要在深圳中英街购买任何物品。
十六、 不要参加北京当地的长城一日游。
十七、 不要在张家界住便宜小旅馆。
十八、 不要在井冈山为“老区建设”捐款。
十九、 不要在杭州的娱乐场所消费。
二十、 不要在苏州的茶楼喝茶。
二十一、 不要在丰都鬼城照“免费”像。
二十二、 不要在北海乘坐摩托艇。
二十三、 不要在北戴河吃海鲜。
二十四、 不要在三亚海边接近小商贩。
二十五、 不要随导游在呼伦贝尔草原上吃烤全羊。
二十六、 不要在庐山乘个体出租车上山。
二十七、 不要在宏村的路上坐出租车。
二十八、 不要去黄山让人“免费带路”。
二十九、 不要在千岛湖码头的排档吃鱼。
三十、 不要参观乐山景区周边的付费景点。
三十一、 不要在郑州黄河游览区骑马。
三十二、 不要到恒山算命。
三十三、 不要随旅游团环游青海湖。
三十四、 不要买神农架的土特产。
三十五、 不要在敦煌的夜市吃地摊饭。
三十六、 不要在花果山的海鲜一条街吃饭。
三十七、 不要随导游逛清明上河园。
三十八、 不要在南京做“免费美容”。
三十九、 不要在上海外滩让人给你照数码像。
四十、 不要买“便宜票”看黄果树大瀑布。
四十一、 不要随导游在香港买名表和珠宝。
四十二、 不要投大钱在澳门赌博。
四十三、 不要在威海韩国城购买没经狠杀价的商品。
四十四、 不要在丽江洗桑拿浴。
四十五、 不要到五台山的五爷庙烧香。
四十六、 不要在平遥摸“鱼洗”。
四十七、 不要在武夷山景区买茶叶。
四十八、 不要在白洋淀景区买鸭蛋。
四十九、 不要在乌镇让道士“免费看相”。
五十、 不要去太阳岛坐“热心人”介绍的船。 -
你要换个戒指吗?不用了,戴习惯了。 - [朝花夕拾]
2009-09-19
记得04年的12月份,穷的很窘迫,鞋底裂了缝,靠厚鞋垫和一双厚袜子撑过了二十多天寒冷的凌晨和黄昏,直到圣诞节前落雪。寒假跟老婆回家结婚,路费也是借的。
婚后过了几个月,跟老婆逛商场,老婆说,我也给你买个戒指吧。于是我们一起挑了一只挺漂亮的银戒指,20块钱。
一开始戴戒指的时候,很不适应,感觉手上多了个东西,怪怪的;不过慢慢也就习惯了。戴了五年,只是有一次拜祭的时候从手上掉落过。
今天跟老婆逛超市,看到银饰柜台那里围了一堆人,走进一看,原来是把原价100多的首饰标价提升到1000多,然后打出1折销售的口号。临走的时候看到一些戒指,老婆便问,“你要换个戒指么?”我说,“不用了,戴习惯了。”然后就想起了五年前。
是为记。
-
在我的上一篇博客“敏捷中国2009,遇到一个没有大脑的淘宝SQA”中犯了几个错误:
1. 不应该提及公司名称。
2. 当时的事件说到底也只是限制在技术讨论内部,事后以攻击性的文字对当事人进行指名道姓的指责,也是我做得欠妥的地方。
在此对被伤害过的朋友──淘宝网的“雷卷”──表示诚挚的歉意。
ps: 立此为鉴,也希望自己以后做事情更冷静成熟一些。
-
一穷二白的给mongrel加上https - [朝花夕拾]
2009-07-08
开发环境一直都是mongrel,产品环境用的apache。客户突然提出,要在作某几个涉及到敏感数据操作的地方,用https。
先在一台开发机上尝试,用apt-get安装了apache,做了一些配置。然后gigix提出,最好编译一个apache放到svn上去,然后写脚本作自动化配置;尝试了一下,发现要编译apache的话,就得把openssl也得编了。。遂放弃。
下面是一些搞的步骤:
1. sudo apt-get install apache2
2. sudo a2ensite default-ssl
3. sudo /etc/init.d/apache2 reload
4. sudo a2enmod ssl
5. sudo a2enmod proxy
6. sudo a2enmod proxy_http
7. sudo a2enmod headers
8. sudo /etc/init.d/apache restart
9. sudo make-ssl-cert generate-default-snakeoil --force-overwrite
10. chmod 755 /etc/ssl/private/
11. cd /etc/apache2, run "sudo vi ports.conf", clear the contents in that file and copy/paste the contents below:
NameVirtualHost *:80
Listen 80
<VirtualHost *:80>
ServerName localhost
ProxyPass / http://localhost:3000/
ProxyPassReverse / http://localhost:3000
</VirtualHost>
<VirtualHost _default_:443>
SSLEngine on
ServerName localhost:443
SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
ProxyPass / http://localhost:3000/
ProxyPassReverse / http://localhost:3000
RequestHeader set X_FORWARDED_PROTO "https"
</VirtualHost>
<Proxy *>
Order Deny,Allow
Deny from all
Allow from localhost
</Proxy>
<IfModule mod_ssl.c>
# SSL name based virtual hosts are not yet supported, therefore no
# NameVirtualHost statement here
Listen 443
</IfModule>做完上面的步骤,apache、mongrel、ssl这些已经搞定了。接下来就是rails的配置,
先安装这个plugin:
ruby script/plugin install ssl_requirement
然后配置application controller:
class ApplicationController < ActionController::Base
include SslRequirement最后在controller里面需要用https的方法前面加上ssl_required,如:
ssl_required :new, :signin, :forgot_password
现在去页面执行操作,用firebug可以看到post请求已经被转发到https了。但到这里我们就遇到另外的问题了,因为我们并不想让所有的开发机器都去装apache,配https,只要这些配置在测试环境和产品环境中可以用就行了。所以就在config/{#projectname}.yml里面配了个:https_needed: false,而config/environments/production/{#projectname}.yml配的是:http_needed: true。这样QA在做测试的时候,只要改一下config/lpi.yml里面的参数就可以了。
于是在controller里面的方法就变成了这样子:
ssl_required :new, :signin, :forgot_password if PROJECT_ENV[:https_needed]
这样一切就都就绪了。可是还有个小问题没有收尾:可能有很多方法都需要加ssl_required,而且可能会分散在不同的controller里面,在每个用到ssl_required的地方都放一个if PROJECT_ENV[:https_needed]就会显得很难看。解决方案很fansy,下篇博客再写。
-
action_mailer的附件问题 - [朝花夕拾]
2009-07-06
最近的一个rails项目,用action_mailer发邮件,用的是这里的写法:
class ApplicationMailer < ActionMailer::Base
# attachments
def signup_notification(recipient)
recipients recipient.email_address_with_name
subject "New account information"
from "system@example.com"
attachment "application/pdf" do |a|
a.body = generate_your_pdf_here()
end
end
end
然后发现附件会把正文覆盖掉。
后来注意到这个页面在Multipart email的地方写了这样一句话:
Implicit template rendering is not performed if any attachments or parts have been added to the email. This means that you‘ll have to manually
add each part to the email and set the content type of the email to multipart/alternative.
于是想到应该用Multipart的方式发,改成这样的写法就好了:
content_type "multipart/alternative"
part :content_type => 'text/html', :body => render_message(#内容略去)
attachment :content_type => 'application/pdf', :body => '#pdf_location' -
从同事身上学到的一些东西 - [朝花夕拾]
2009-06-25
-
整理一下rojam中的metaprogramming - [敏捷开发]
2009-06-16
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
......
endeval方法会将字符串作为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同名的方法。
-
昨天听默默的讲座,清一色的头脑风暴,完事以后大家都感觉特累。
在一个头脑风暴里,当时是要每个组都给四天的课程安排agenda,我们组的人讲完以后,dreamhead说:我其实特别关注你的思路,因为你现在不是跟客户讲,而是跟公司内部的人讲课程安排,所以思路就很重要,你是出于什么目的来这样安排课程,这样安排会带来什么样的好处,这些一开始就是需要讲清楚的。
唔,其实何止是没讲清楚,我很怀疑大家有没有自己想清楚为什么要这样安排课程;当时team的人都是匆匆忙忙的往白板上贴纸条,后来我强调了一下,告诉大家别只顾着零零碎碎的贴,自己心里得有谱,有一条线索把你贴上去的这些东西能够串起来,自己能按照这些纸条把几天的课讲完。
不过dreamhead的话还是让我感触很深,在服从习惯做这样那样的事情的时候,一定要多问自己几个问题:为什么要做这样的事情?它给自己或是别人带来什么样的好处?有没有更好的方式来做这件事情?比如我现在用blogbus的编辑器写博客,旁边dreamhead就在用文本文件写,写完以后再往上贴。
以后要时时提醒自己,让自己做事更有效率一些。
-
今天听@eaglexiao讲去某大型电信厂商那里作咨询,做CI的一些经验心得,然后大家又探讨了很久。
下面是学到的一丁点东西:
1. 团队内部的沟通。我们是作为一个整体去为客户提供服务的,所以要有一致的声音,任何一点微不足道的分歧,在单独面对客户的时候都有可能给人产生不靠谱的印象。所以当我们在内部表达观点的时候,应当要努力坚持,直到被说服为止,而不是被简单的否定。不然就没有很主动的心态去说服客户也接收这个观点。
2. 知识的系统体系。上个月老大在office update的时候也讲到了小强的故事,说他每天晚上都要狂补CI、配置管理的知识,今天听@eaglexiao和dreamhead也是说同样的观点,很多知识也许在我们看来是common sense,但是客户不一定,甚至就是不这么以为。那么要说服客户,抛开沟通技巧、演讲技巧之类的软性因素不谈,自己和团队必须得建立完善的知识体系结构──至少在自己所擅长,所要为客户提供价值的领域内。这样自己心里有谱,客户也会觉得你比较专业。
3. 不要用自己的知识面去套客户所面对的问题。这还是锤子和钉子的典故了,一旦有了心理暗示,就容易忽略掉其他证据。要多听,多调查。
4. 多探究问题的本质。客户暴露给我们的问题、要我们去解决的问题可能只是表面现象,我们得追求它的成因,这才是能够更好提供价值的地方。
5. 不一定客户问什么,我们就得回答什么。那句话实际上是前面那条的引申,这是在@eaglexiao陈列客户问题的时候,dreamhead提出来的。当时列出来的问题有:单元测试应该有多大的覆盖率?测试代码跟产品代码的比例应该是多少?dreamhead就说,你不一定就非得给客户把这些问题回答出来,你可以问他,你问这些问题的目的是什么?这背后可能就隐藏着一堆问题是需要解决的。如果你告诉客户,测试代码跟产品代码的比例在0.8~1.5之间,这种答案对他有意义么?没有。也许你问他以后,他可能会回答你,他要用这个数据去做评估,那么你就继续问,为什么要用这种数据作评估,然后顺藤摸瓜找出流程的问题来。这样一来就可以找到让我们价值最大化的地方了。








