2011年六月月 发布的文章

小试番茄工作法

番茄工作法Pomodoro Technique),你可能没有听说过,呵呵,它年纪也不小了,官方说它是在1980s时发明的一种时间管理方法,只不过它最近又被一些人“挖掘”了出来,并被大力推广了一番。特别是在软件开发圈子里,被包装后的番茄工作法披上了光鲜的外衣,拥有了不少粉丝(我还算不上粉丝,充其量算是个试用者 ^_^)。

不过和历史上诸多的时间管理方法一样,番茄工作法不是银弹,它无法将你彻底地从每天纷繁芜杂的工作中解脱出来,甚至于:
- 它不能告诉你今天应该去做哪些事情;
- 它不能告诉你如何排定事情的优先级;
- 它不能告诉你如何应对各种外界打扰;
      
那这种方法的优点到底何在呢?别急,下面一一道来。

简单!首当其冲的就是简单!番茄工作法的全部核心内容只有下面几句话(也是该方法的标准执行步骤):

* 选择一个待完成的任务
* 将番茄时间设为25分钟
* 专注工作,直到番茄时钟响起,然后在纸上画一个x
* 短暂休息一下(5分钟就行)
* 每4个番茄时段多休息一会儿

怎么样?看起来是不是与我们平时的工作方法没有太大区别呢?我们平时工作时也是一个任务接着一个任务的去做啊。没错!这种方法看起来似曾相识。不过细致挖掘后,你会发现这里每一步的描述中都没有废话。

- 选择一个待完成的任务
番茄工作法在这里没有给出如何进行任务选择的详细说明,我想这是因为在许多时间管理理论和方法中都针对这方面做了细致入微的讲解,如经典的四象限法等。再深入考量一下,你会发现番茄工作法执行前是需要你做一些准备工作的:你需要枚举出待办事项、识别出优先级别、将规模较大的Task拆分为small tasks,然后制定至少一天的番茄计划,设定每个番茄时间段(Promodora)对应的task。只有当你准备好这些,番茄工作法才能让你的工作更有效率。这里也可以理解成番茄工作法的开放性,可以让你与其他高效时间管理理论、任务分解方法充分结合,让效力倍增。

- 将番茄时间设为25分钟
从字面义来看,这就是一个定时器。没错,实际执行过程中,你的确需要一个定时器,物理的也好,软件实现的也好。可以支持自由设定番茄工作时间段,具备报时提醒功能。至于25分钟,我想这是发明者给出的一个经验值,你可以在初期按照25分钟设定,后续根据自己的需要自行调节。Google Chrome有一个名为ChromoDoro的番茄计时器插件很不错,我一直在用。有定时器和没有定时器,工作起来有啥分别呢?实践证明,在定时器下工作,你的潜意识中会涌出一种紧迫感,潜移默化的加强你提高完成效率的意识。

- 专注工作,直到番茄时钟响起,然后在纸上画一个x
别看这句不长,但我认为这句才是番茄工作法的精华。首先不得不提到的就是“专注”二字,这也是我理解的番茄工作法的第二个优点。专注,意味着迈向高效。长期使用番茄法可以大幅提高你的专注力,也间接的提升了你的效率。这个说起来容易,做起来难。不信你可以试试。其他外部干扰不说,你是否能在一个番茄时间段(25分钟)内专注于处理某件事情呢?你是否会走神(外面突然阴云密布,又要下雨了?)、是否会分心(昨晚巴萨赢没,梅西
进球了吗?真想打开 Browser看看结果)。哈哈,实践证明,在使用番茄初期,这些都会发生,起码在我身上就不断地发生过。为啥还要在完成时在纸上画个X,我理解这是个信心强化的小技巧,强调“完成”,提高完成的信心,久而久之,这种成功反馈会给你带来充足的自信。

- 短暂休息一下(5分钟就行)
工作也讲究节奏,适当的节奏会让你觉得游刃有余。反之,如果长时间专注,反倒会过损脑力,降低效率。另外适当的休息也避免了一些职业疾病发生的可能性。

- 每4个番茄时段多休息一会儿
我的理解,和上一条差不多。不过这里除了休息之外,还可以对之前的工作进行总结和反思。另外长时间专注于某一个项或一类工作后,也许要时间重新积蓄一些热情了。

总而言之,番茄法更强调的是执行过程的专注以及工作节奏的把握,再结合适当的反馈技巧,可以让你的效率有提高,至于提高幅度因人而异了。

在试用番茄法的过程中,我也总结了一些经验技巧,供大家参考揣摩:
- 根据个人实际情况,合理设置自己一个工作日内的番茄时间段,尽量将重要的工作放在头脑高效的时段,比如上午8:30~11:00,下午15:00到17:00等。不一定所有工作都要纳入番茄时间段里,找到适合自己的工作节奏。
- 做好准备工作,明确各个番茄时间内对应的任务,最好将任务简单写到纸质便签/日记本中,便于实施画X,强化反馈。
- 每4个番茄时段内的task的上下文差别不要太大,尽量减少task间的切换成本(进入某个task的工作状态是需要时间的)。
- 在番茄时间段内task没完成咋办? 这个估计经常发生,似乎只好在下一个番茄时间段里继续做了。其他task顺延。必要情况下加班完成。一旦出现这种情况,就需要你加强task划分能力,尽量做好task完成时间的预估,不断提升精确估计能力。
-打扰是不可避免的。电话、邮件都可能打断你的工作。如果必要,可在你的番茄时间段中预留出一些处理打断的时间,比如25+5,预留5分钟。当然我们应该尽可能避免这种打扰,可用一些广为流传的技巧:比如在允许的范围内适当将mail接收的间隔延长;高挂“免战牌”,显式告知他人你已经“out of services”了;不启动即时通信工具,或设置即时通信工具的状态为外出或极其繁忙状态等等。

再强调一点,番茄法不是孤立的,可以与其他时间管理方法(如GTD)结合使用。

以上是个人小试番茄法之后的一些体会,图灵出版了《番茄工作法图解:简单易行的时间管理方法》,是著名的Pragmatic Bookshelf系列,不过我还没有读过, 可能也不打算读,有些东西自己体会和感悟的更深刻,不是吗^_^。

让BuildBot服务于多个项目

多数公司不会仅有一个项目,当你为一个项目引入持续集成实践后,其他项目就会接踵而来。这时你会重新考量BuildBot,考虑如何让BuildBot可以服务于多个项目。

如果你有足够的主机资源和人力资源,那为每个项目单独搭建一套CI环境是再好不过的了,每个项目都有专人维护CI环境,各个项目的配置互不干扰。不过对于一些公司来说,这显然有些浪费,BuildBot Master的资源消耗是不大的,我们完全可以使用一套BuildBot Master来服务于多个项目,至少BuildBot是可以支持这样做的。

CI环境中,我们首要关注的就是源码库。多个项目可能各自使用单独的源码库,也可能共享一个源码库并通过目录隔离和识别。无论怎样,我们都可以通过BuildBot Master的配置来满足我们的要求。

如果说多个项目共享一个源码库或是一个项目下的多个子系统放在一个源码库中,这时我们在配置change_source时指定一个变更监测器即可,这个监测器的监测范围从源码库的根路径开始。以Subversion源码库为例,我们可以这样来配置:

c['change_source'] = [SVNPoller("svn://10.0.0.1:3000",
                                svnuser='tony',
                                svnpasswd='tony',
                                pollinterval=60,
                                split_file=change_path_split)]

我们通过change_path_split来拆分变更文件的路径,假设SVN库结构是这样的:
svn://10.0.0.1:3000
       – foo_proj
           – trunk
               – main/main.c
           – branches
           – tags
       – bar_proj
           – trunk
               – main/main.c
           – branches
           – tags

我们可以这样来实现change_path_split:

def change_path_split(path):
        pieces = path.split('/')
        if pieces[0] == ‘foo_proj’ and pieces[1] == 'trunk':
            return ('foo_proj/trunk', '/'.join(pieces[2:]))
        elif pieces[0] == ‘bar_proj’ and pieces[1] == 'trunk':
            return ('bar_proj/trunk', '/'.join(pieces[2:]))
        else:
            return None

不同项目下的文件变更,会导致change_path_split返回不同的值,而change_path_split返回值会被用于匹配不同的Scheduler:

c['schedulers'].append(Scheduler(name="foo-ci-plan",
                                 branch='foo_proj/trunk',
                                 treeStableTimer=5,
                                 builderNames=["foo-redhat-builder", "foo-x86-solaris-builder"])

c['schedulers'].append(Scheduler(name="bar-ci-plan",
                                 branch='bar_proj/trunk',
                                 treeStableTimer=5,
                                 builderNames=["bar-redhat-builder", "bar-x86-solaris-builder"])

上面各个Scheduler的branch属性会与change_path_split返回值元组中的第一个元素匹配,这样foo-ci-plan便是foo_proj的scheduler,而bar-ci-plan则是bar_proj的scheduler。这样某个项目路径下的文件变更只会触发对应的scheduler开始工作,不会出现误触发。

如果多个项目或一个项目的多个模块使用不同的源码库,同理,我们可以为c['change_source']赋予多个SVNPoller,例如:
c['change_source'] = [SVNPoller("svn://10.0.0.1:3000",
                                svnuser='tony',
                                svnpasswd='tony',
                                pollinterval=60,
                                split_file=change_path_split),

                      SVNPoller("svn://10.0.0.1:4000",
                                svnuser='tony',
                                svnpasswd='tony',
                                pollinterval=60,
                                split_file=another_change_path_split)]

与Scheduler的匹配方式也与上述描述一致,这里就不重复说明了。

不同项目的干系人多不相同,那么集成的结果是如何准确地反馈给项目各自对应的干系人呢?以Mail反馈通知为例,我在BuildBot手册中找到了两种方式,一种方式是通过设置Scheduler的owner属性,然后指定MailNotifier的sendToInterestedUsers=True,意图让BuildBot将Mail通知发到owner list中的每个邮件地址,但经测试后发现,这种方式似乎不好用,不知道是否是BuildBot对该功能的实现上存在问题。

另外一种方式则是配置多个MailNotifier。每个MailNotifier中指定对应builder的名称列表,并通过extraRecipients指定这些Builder对应的项目的干系人Mail地址列表,例如:

c['status'].append(mail.MailNotifier(fromaddr="foo-buildbot@buildbot.net",
                                     extraRecipients=["foo1@buildbot.net", "foo2@buildbot.net"],
                                     builders=['foo-x86-solaris-builder', 'foo-redhat-builder'],
                                     useTls=False,
                                     sendToInterestedUsers=False,
                                     relayhost="smtp.buildbot.net",
                                     smtpUser='tony',
                                     smtpPassword='tony',
                                     smtpPort=25))

c['status'].append(mail.MailNotifier(fromaddr="bar-buildbot@buildbot.net",
                                     extraRecipients=["bar1@buildbot.net", "bar2@buildbot.net"],
                                     builders=['bar-x86-solaris-builder', 'bar-redhat-builder'],
                                     useTls=False,
                                     sendToInterestedUsers=False,
                                     relayhost="smtp.buildbot.net",
                                     smtpUser='tony',
                                     smtpPassword='tony',
                                     smtpPort=25))

这样foo的builders构建的结果将发到foo1和foo2;而bar的builders构建结果将反馈到bar1和bar2。

多个项目共享一套BuildBot Master有利有弊,其不足之处可能有如下几点:
1、项目过多时,可能存在潜在的性能问题
2、Master的配置被多个项目共享,存在潜在的Conflict问题;
3、另外master.cfg可能size过大,也不利于阅读和维护。

如发现本站页面被黑,比如:挂载广告、挖矿等恶意代码,请朋友们及时联系我。十分感谢! Go语言第一课 Go语言精进之路1 Go语言精进之路2 商务合作请联系bigwhite.cn AT aliyun.com

欢迎使用邮件订阅我的博客

输入邮箱订阅本站,只要有新文章发布,就会第一时间发送邮件通知你哦!

这里是 Tony Bai的个人Blog,欢迎访问、订阅和留言! 订阅Feed请点击上面图片

如果您觉得这里的文章对您有帮助,请扫描上方二维码进行捐赠 ,加油后的Tony Bai将会为您呈现更多精彩的文章,谢谢!

如果您希望通过微信捐赠,请用微信客户端扫描下方赞赏码:

如果您希望通过比特币或以太币捐赠,可以扫描下方二维码:

比特币:

以太币:

如果您喜欢通过微信浏览本站内容,可以扫描下方二维码,订阅本站官方微信订阅号“iamtonybai”;点击二维码,可直达本人官方微博主页^_^:
本站Powered by Digital Ocean VPS。
选择Digital Ocean VPS主机,即可获得10美元现金充值,可 免费使用两个月哟! 著名主机提供商Linode 10$优惠码:linode10,在 这里注册即可免费获 得。阿里云推荐码: 1WFZ0V立享9折!


View Tony Bai's profile on LinkedIn
DigitalOcean Referral Badge

文章

评论

  • 正在加载...

分类

标签

归档



View My Stats