东拉西扯

公开课

最近看了两个比较有名的公开课:《公平》和《幸福课》 《公平》告诉了我:在很多时候,人们不得不做选择,这些选择没有对错,只是代表了每个人不同的价值观。 正是这门课程,颠覆了我从小就被教育的非对即错,非黑即白的观念,那些被我误解了的人们,在这里跟你们说声对不起,原谅我当年的无知与鲁莽。 《幸福课》的老师刚出场的时候,他身上的那种气场就感染了我,即使是通过电脑屏幕,你依然能够从他的动作,他的眼神、他的语气上感受到他身上的那份宁静,心如止水,宠辱不惊。记得有这么一个笑话:”幸福是什么?幸福就是,我能吃着,你看着,我坐着,你站着”。这是最简单的物质的幸福,试想:当你从那个"看着"、"站着"的人变成"吃着"、”坐着”的人的以后,你得到幸福了,然后⋯⋯ 你的幸福感会持续多久?现在我还记得自己得到第一个手机、第一个笔记本电脑、第一个MP3播放器、第一个智能手机、第一个iPod的那些时刻,那种幸福或许会持续一天、一周或者再久一些,但是终归会消逝于平淡,这种通过获取物质而得到的幸福感是短暂的,不可延续的。只有获得了精神上的宁静,幸福才是长久的、延续的。

团队

再来说说团队里的事情,前几天跟一个一起入职的同事聊天,都谈到了一种共同的感觉: 因为事情比较少而感到了一种不安全感,其实就是姜鹏的这篇博客 里提到的存在感,一个人在团队里有了存在感,这种不安全感就会随之消失。

自己

再来说说自己,综观自己这短短二十多年里遇到的各式各样的人,有一种人看起来总是眉头紧皱,脸色阴沉、有着说不完的抱怨, 你能明确地感受到他/她不快乐。然而也有另外一种人,你总是在某个时候听到他/她爽朗的笑声,你很少能够听到他们的抱怨, 他/她有很多兴趣爱好,总是有说不完的话题,也很乐于分享。 不幸的是,我更接近于第一种,而在ThoughtWorks,你会发现大多数人都更接近于第二种,同样,放下轻车熟路的java进入ruby on rails 的世界也是。都会让我感受到一些压力。 一开始,是有点不适应,在读了《哪来的天才》这本书之后,对于这种压力有了新的认识,对于我来说,是从”舒适区”进入了”学习区”。这才是进入了提高的通道。

同事

最近公司邮件组里发起了关于如何在国内开展Social Impact Project的大讨论,其中有个比较好的点子是: 帮助留守儿童与他们外出打工的父母保持联系,以弥补空间带来的情感上的隔离。 我才意识到原来这帮人不仅仅是在为自己讨生活,他们确确实实在考虑着如何通过自己的一点努力来帮助那些需要帮助的人们, 能与这样一群人一起工作,真是一件很幸福的事情。

ThoughtWorks入职一月

     在最近的两周里,和一个同事一起搭建一个持续交付的demo工程,到目前为止,已经基本接近尾声。不过, 这个demo之前是根据一个ruby应用搭建的,但是考虑到国内目前的软件行业的现状,ruby仍然是一门小众语言,因此考虑通过一个java应用搭建一个CD Demo,这就是后面一周的工作重点啦。

成果:

  • 设计了一个包含了Go master、Go agent、puppet master,target nodes, Dev Env演示环境的部署策略:
  • 使用shell编写了一个简陋的rails应用远程部署脚本。
  • 对于puppet有个基本的认识,使用puppet搭建了上述的环境的基础设施。

收获:

   1)  对bash 有个基础的了解,知道了interactive shell和non-interactive shell、登陆shell与非登陆shell之间的区别(他们启动的startup不一样)

   2)  更加体会到了tasking的好处,尤其在考虑上述5个部件之间的交互关系时,采用这种方式能够帮助我理清思路,找出合理的解决办法。

   3)  对于SSH有了基本的了解,知道了可以通过发布公钥在多个节点之间建立信任关系,用shell脚本实现了通过ssh远程登陆目标机器完成相应操作。

 

计划:   

  • 了解open stack,目前仅知道这是一个开源的云计算平台软件集合
  • 搭建一个open stack环境。
  • 搭建一个java项目的持续构建、自动部署平台。

遗留问题:

  1) 对于rvm加载的机制尚不太清楚,需继续研究

  2) 对于maven还是不够了解,需要继续学习,通过maven对该java demo项目进行构建

好的编程习惯

 

昨天郑大晔校的主题是 “如何养成好的编程习惯”,只有养成好的编程习惯,当你在时间紧任务重的情况下仍然能够写出风格、质量良好的代码。

分组讨论后,每个小组都给出了自己认为好的编程实践,我把大家的想法总结了一下,并且根据这些实践的侧重点,分成如下五个方面:

任务规划:  Tasking,TimeBox

     关于Tasking,有两个大家最关注的问题

          ——如何确定tasking的粒度 ?

          结论:task的粒度是由开发者的能力确定的,

                   基本的评判标准是:如果你能够用一个测试用例描述这个task即将实现的功能,那么这个task的粒度就是合适的。

         ——如何划分task?

          结论:不需要一次性把所有task划分清楚,可以从最简单的task入手,在实现简单task的过程中,你会逐渐识别出新的task,

          把这些新的task加入task list中,待第一个task 完成后,再从task list中获取下一个task,如此持续下去直到所有需求都完成。

          推荐阅读《Test Driven Development》这本书,书中很好地演示了“Tasking”的实践。

     关于TimeBox,有同事推荐了一个比较有名的实践 tomato time,以15~30分钟为一个tomato time,有计划,有节奏地工作。

软件设计:  简单设计,先实现再重构,小步前进

     简单设计: 在软件设计上,一个程序员最容易犯两个错误——没有设计过度设计,两个极端。

                    对于一个刚入行的程序员,他/她最容易犯的错误是没有设计,比如,在一个类、一个方法内完成所有的功能。

                    对于一个刚入行并且阅读过设计模式相关书籍的程序员,他/她很容易犯一个错误——过度设计。比起没有设计,程序员更加难以意识到自己已经过度设计了。关于过度设计我有个深刻的体会,这里拿出来跟大家分享一下:

          在某个产品中,为了实现一个从远程部件获取数据,我想当然地为了提高效率,对从远端获取的数据进行了缓存,并且,为了进一步提高效率,在程序内部多个地方做了数据缓存,这种设计导致的问题是,在程序发布之后,当发现获取的数据是错误的时候,花了大量时间来定位错误的数据出现在了哪个环节。痛定思痛之后,我移除了这些缓存,把处理这些业务数据的spring bean改成无状态的,这样业务逻辑大大     简化,而且也没有发现性能低下的问题。 由此看来,这些缓存就是过度设计的思想引入的。

 

     先实现在重构:这个行为就是建立在简单设计的理念上的,其目的就是为了避免过度设计,完成刚刚好的功能。

效率提升:  熟练使用类库,熟悉IDE快捷键

     关于这两点,只有通过自己的实践慢慢积累,熟能生巧啦。

 

工程实践:  频繁提交, push前完成本地构建 ,  和pair及时沟通  

     频繁提交:频繁提交的目的在于及时地把自己开发出来的代码提交到代码仓库上去进行持续集成,验证自己的代码是否破坏了原有的功能。其本质思想在于快速得到反馈。

 

     push代码到代码仓库前完成本地构建:这个工程实践的目的在于,提前发现可能引入持续集成失败的问题,降低修复持续集成失败的成本。

     和pair及时沟通:在ThoughtWorks工作,大家都是以pair的形式进行的,这个实践的目的在于,及时从pair处得到反馈并获得成长。

 

代码风格:  代码要是自注释的,格式规范, 不提倡(switch, if else, 深度嵌套, 大函数,重复)

     关于代码风格方面,大家的观点基本是一致的:代码是给机器写的,但是是给人看的,所以要写人类能够看得懂的代码。

 

ThoughtWorks入职两周

 

从8月11日入职,到今天8月24,刚好两周时间,感觉又到了做总结的时候了。

     本周的主要工作是和一个今年刚毕业的研究生(在ThoughtWorks很多时候都是pair干活的)一起协助北京的一个同事制作一个关于Continuous Delivery的 demo,这个demo的目标是用于演示如何在实际项目运作过程进行Continuous IntegrationDevOps实践,达成Delivery的目的。

     经过简单的商议,我们选用了一个由我所在的“酱油组”维护的rails应用做为这些实践的应用目标。再把上面的大目标进行逐步细分,得到下面几个子任务:

     1. 搭建CI环境(这里采用的公司开发的一个CI产品 Go

     2. 把次rails程序自动部署到CI上

     3. 增加静态检查CI任务

     4. 增加unit test CI任务

     5. 增加functional test CI任务

     6. 增加产品 release CI任务

     7. 一键式完成产品部署(DevOps)

     其中主要涉及了rails, rvm, shell, DevOps等知识点,所有的这一切对我而言都是全新的,我们都是在未知领域里探索,在实现这些任务的过程中,我明显感到了我存在的一个问题,一个非常严重的问题——解决问题的能力较弱而且缺乏进一步钻研的欲望

     当遇到一个问题时,我在进行了有限的几次尝试后就放弃了,就准备向周围的人 请教了。

    其实ruby、rails、rvm、DevOps的在线文档都很全面的,多翻翻文档一般都能找到解决思路,更重要是,对于大多数问题来说,google一下,一般情况下你都能找到答案。

     在之前很长的一段时间里,由于始终在自己的一亩三分地里耕耘,我已经很久没有去面对全新的知识领域了,所以我几乎丢掉了原有的在未知领域钻研的能力。

     突然来到这个崭新的环境,海量的信息暴风雨般地扑面而来,太多的未知的东西需要了解,我感到了压力。

     好在,这个环境是开放的,资源很丰富,是应该利用好这些资源,给自己再来一次提升了,我要努力。

 

      检讨完自己的不足,也该总结一些优秀实践了。

     1. 构建思维导图

         在这两周时间的学习过程中,我都会打开XMind,逐步构建自己的知识地图,当读完一篇文档,一个简单明了的知识结构图有诞生了,让我对刚刚学到的知识有个系统的总结。

     2. 做笔记:

在阅读各种各样的文档中,我都会用evernote把自己的心得记下来,可以用来做回顾,同时这些材料都是写博客的最生动的素材。

 

This blog is talking about how I install metric_fu in a rails project.

firstly, I typed a command "gem install metric_fu", unfortunatlly, I got a error message like this

"ERROR:  While executing gem ... (Gem::DependencyError)

 Unable to resolve dependencies: metric_fu requires chronic (~> 0.3.0)"

seems that metric_fu can not find the required verion of chronic gem, then I googled chronic, and know that chronic is time parsing tool writen in ruby, the latest version of chronic is 0.6.2. 

so how should I solve this problem?

as I know, a gem package is just like a jar file, which contains  class files and some manifests files. but a gem package can do one more thing - telling you the name and version of those gems it depends on.  so I got a soluation :  change the version declaration of chronic in the "dependency declaration file", telling metric_fu to use the latest verion of chronic.

        Then I  googled again, and a got a import information - people can install gem from source , 

here is the steps:

1. download the correct version of gem source code from  code base (github in general)

        2. build a gem package from the source. 

        3. install the gem package you built.

for more detail, you can see here .

Note : step 2 is the key point.

        before I build my metric_fu gem, I check a file named

        "metric_fu.gemspec", and found out that this is the "dependency description file"


         then I find the dependency description of chronic "s.add_dependency("chronic", [">= 0.3.0"])"

modify the version to "0.6.2", run command "gem build metric_fu.gemspec",  so I got a metric_fu gem depends on chronic 0.6.2.

         finaly, cd to my project directory,

         run command "gem install ../gem_repositry/metric_fu.gem", 

this time, the metric_fu is installed successfully.

         Hope this information is helpful for you.

 

Update: this is not a good pratice.

                 you can install a old version of chronic manually, and then install metric_fu 2.1.1.

                and I met another problem when running metric_fu in ruby 1.9.2 with syntax 1.0 - "invalid UTF8 charater sequence", you can find the issue here .

                my soluation is just like Jscruggs said . here is my configuration code:

MetricFu::Configuration.run do |config| config.syntax_highlighting = false end