把时间当作朋友读书笔记

把时间当作朋友

刚读到这本书的时候,有种相见恨晚的感觉。不同于一般的时间管理类书籍,无病呻吟式的洗脑不见了,例子也少了强加因果关系的痕迹,有些观点印象比较深,值得一读。下面是一些比较有感觉的部分,和大家分享一下。

欲望

人希望欲望尽快得到满足。这是人性,所以衍生了速成,不劳而获,学习浮于表面这些浮躁的社会现象。在这之前,我真的没有意识到这是人性本质的的一种表现,对于有些新同事急于求成的想法,甚至是自己,也经常有难以理解的感觉。没能理解到这点,就很难说感同身受了。

成功学

虽然我也读过一些成功人士的经验之谈,我向来对成功学理论不大感冒,因为多读几本就会发现,他们经常夸大某一方面对结果的影响,很多例子也很牵强,再加上环境的不同,这些经历基本是不可复制的。李老师在书中也反复强调,要警惕成功学,要有自己的独立思考。独立思考,成熟心智,管理自我,才是书中强调的思想。

时间管理

读书,除了希望能找到不同的观点,还希望能有些支持这些观点的可操作性方案。其实关于时间管理方面的著作,我也知道一些,例如使用TODO,GTD等工具,番茄工作法。 李老师也有类似的一些做法,例如代办列表,下一阶段代办列表,每日事项回顾。关于每天晚上回顾做了那些事,这个在其他书上没有特别指出,不过李老师提到的回顾发现没什么可以写的尴尬,我也经常遇到。让我产生这些做法不可靠的感觉,后来才发现,这个和代办事项的优先级与难度有关。自己经常会倾向于先完成熟悉的,简单的,感兴趣的,而不是重要的,困难的。这样即使看上去完成很多东西,回顾的时候发现没什么可以值得一提的事情。

计划

计划不如变化快,但我们还是需要计划的。关于计划,我发现自己经常高估自己的能力,这个需要多考虑意外,给自己心理估计时间多加一段时间,并且把计划细分,对于不熟悉不感兴趣的事情,更应该如此,把时间分为多个时间片,不断接近目标。书中关于这部分的内容和番茄工作法的理论有交叉,个人感觉番茄工作的理论更详细和有针对性些吧!

有趣言语

李老师常说的一句话是,相信我,你并不孤单。并引用了正态分布的理论,使得这句话特别的深刻。整本书妙语连珠,读起来比较轻松。

使用wunderlist进行TODO管理

Wunderlist

Wunderlist是一个TODO管理工具,支持多种客户端的同步,在多个客户端中的界面风格不会差别很大,实用性、可操作性都相当不错。 关于这类TODO工具的具体使用,我就不再长篇累牍了。这里主要结合wundeler,讲讲自己对TODO管理的经验教训

首先,要焦距于你需要处理的事情,而不是你使用的工具。无论使用怎样的工具,都应该把焦点放在TODO事项上。 有些人喜欢玩弄软件的新功能,我也经常迷恋于寻找软件的功能而忽略事情的本身,导致浪费在使用软件上的时间太多。 所以使用TODO工具,关键是TODO事项是否能够有计划的进行

其次,工具尽量要简单实用,在使用某个工具的时候,有时候感觉功能有所缺失,所以有些人可能会尝试不同的工具或者在多个工具换来换去, 试图寻找那完美的工具。说实在,这个成本太高了,多关注待处理的问题本身吧,多反向思考:真的需要这个功能么?频繁使用么? 就wunderlist来说,我也感觉缺少些功能,例如结合日历功能,有时候同步会有些问题。不过这些都不影响我使用关键功能,也让我能够 焦距于TODO本身。

最后,说说我使用wunderlist的方式吧。一般来说,我会在某天当做一个周期的开始,把我能够想到的TODO事项记录上去,不区分轻重缓急, 也不考虑工作量和时间因素,也不管是工作、生活还是学习的范畴。总之有多少就写多少,如果事项比较大并且有些明显的分割点,我也会拆分成多个TODO。 然后开始对任务进行挑选,得到需要处理的事情列表,如果列表太长,会把某些重要和紧急的进行加星。这样就可以让关注的事情就在一定的范围之内。 从这部分列表中挑选事项,集中精神逐项处理。周而复始,这样让每天都可以看到成果,激发自己的动力。

ps: 我不是什么GTD专家,仅供参考。不过wunderlist真的是不错的TODO工具,推荐使用。

Node.js Best practices

完整的ppt来源于Node.js Best practices,作者Felix Geisendörfer,需翻越

Callbacks

下面是关于解析json文件的示例代码:

var fs = require('fs);
function readJSON(path, cb){
  fs.readFile(path, 'utf8', function(err, data){
    cb(JSON.parse(data));
  }
}

显然,上面的代码没有处理异常情况,因此再加个异常处理逻辑上去:

var fs = require('fs);
function readJSON(path, cb){
  fs.readFile(path, 'utf8', function(err, data){
    if(err) return cb(err);
    cb(JSON.parse(data));
  }
}

还没有结束,我们还没考虑到文件内容不是json这种情况,会导致parse出现异常,因此再处理一下:

var fs = require('fs);
function readJSON(path, cb){
  fs.readFile(path, 'utf8', function(err, data){
    if(err) return cb(err);
    try{
      cb(JSON.parse(data));
    }catch(err){
      cb(err);
    }
  }
}

对于cb来说,仍然无法区分正常结果和异常内容,这个问题通常可以通过增加一个err参数来处理,如:

var fs = require('fs);
function readJSON(path, cb){
  fs.readFile(path, 'utf8', function(err, data){
    if(err) return cb(err);
    try{
      var json = JSON.parse(data);
    }catch(err){
      return cb(err);
    }
    cb(null, json);
  }
}

这个示例告诉我们,对于callback,需要时刻准备应付正常结果和异常情况的处理。

再来看看另外一个常见错误:

function readJSONFiles(files, cb){
  var results = {};
  var remaining = files.length;
  
  files.forEach(function(file){
    readJSON(file, function(err, json){
      if(err) return cb(err);
      
      results[file] = json;
      if(!--remaining) cb(null, results);
    }
  });
}

这里隐含了一个常见的场景:批量处理时,任意一个失败,及时退出。有时候可以用标识符,这里采用另外一种手法:重置回调方法

function readJSONFiles(files, cb){
  var results = {};
  var remaining = files.length;
  
  files.forEach(function(file){
    readJSON(file, function(err, json){
      if(err){
        cb(err);
        cb = function(){};
        return;
      }
      
      results[file] = json;
      if(!--remaining) cb(null, results);
    }
  });
}

Nested Callbacks

先看看一个恐怖的例子:

db.query('SELECT A ...', function(){
  db.query('SELECT B ...', function(){
    db.query('SELECT C ...', function(){
      db.query('SELECT D ...', function(){
      });
    });
  });
});

活生生就是一个怪物:),多层嵌套的回调不是很好的风格,我们需要一些流程控制的东西来辅助,例如Control Flow Libs:

var async = require('async');

async.series({
  queryA: function(next){
    db.query('SELECT A ...', next);
  },
  queryB: function(next){
    db.query('SELECT B ...', next);
  },
  queryA: function(next){
    db.query('SELECT C ...', next);
  }
  // ...
}, function(err, results){
  //...
});

像上面的代码,最明显的地方就是异常处理被完全隔离出来。如果要把代码分布到很多小方法里边的话,Node.js的确不是很容易做到

Exceptions

通常throw new Error(msg)可以让你的程序进行异常退出,并在控制台上输入错误信息和堆栈信息。

但有时候我们要考虑的是,一些未知的bug,例如下面一个有bug的示例:

function MyClass(){}

MyClass.prototype.myMethod = function(){
  setTimeout(function(){
    this.myOtherMethod();
  }, 10);
}

MyClass.prototype.myOtherMethod = function(){};

(new MyClass).myMethod();

我们可以采用Global Catch的方式:

process.on('uncaughtException', function(err){
  console.err('uncaught exception: ' + err.stack); 
});

更好的处理方式是:进程挂了,认栽了,到更高层面上去处理

process.on('uncaughtException', function(err){
  // You could use node-airbake for this
  sendErrorToLog(function(){
    // Once the error was logged, kill the process
    console.err(err.stack);
    process.exit(1);
  }
});

Deployment

比较初级的方式是采用node直接运行或在后台运行。老手可能会采用一个脚本来搞:

#! /bin/bash

while :
do
  node server.js
  echo "Server crashed!"
  sleep 1
done

专家级采用的方式可能是(借助成熟的集成工具):

#!upstart

description "myapp"
author "felix"

start on(local-filesystems and net-device-up IFACE=eth0)
stop on shutdown

respawn # restart when job dies
respawn limit 5 60 # give up restart after 5 respawns in 60 seconds

script
  exec sudo -u www-data /path/to/server.js >> /var/log/myapp.log 2>&1
end script

当然,还有些创新风格的(基于托管平台的):

$git push joyent master
$git push nodejitsu master
$git push heroku master

没有托管平台的话,借助成熟的工具应该是最好的选择,性价比高。

2012年总结

转眼2012年就结束了,开启2013年的旅程了。按照惯例还是要给2012年做个总结, 顺便给2013年定些目标和计划。

2012年的工作

2012年工作的情况还是比较顺利的,大概是完全习惯了公司的工作环境和节奏的原因吧, 在项目的开发工作上没什么特别的变化,主要是在日常需求开发外有了比较大的变化。

其中有个变化点,就是参与部门招聘的面试比较多,有段时间几乎天天都要花时间出来面试。 整个过程让自己对应聘员工(主要是应届-2年内)的就业心态有了更多的了解, 虽然我偏重的还是技能方面的考察,但也会尽量的从多方面去考察对方的能力, 希望给一些愿意干的人的机会。另外一方面,看到太多应聘员工对技术浮于表面, 在基础上欠缺太多,这些人大多出自于培训机构, 这也是我一直以来对北x青x类培训有些反感的原因吧。

还有就是,为了激发大家对技术的热情,在部门内组织多次的技术分享活动。 搞这些活动,主要用来锻炼自己的执行力和演讲能力,扩大自己在部门内的影响力。 我觉得,在2012年算是做得不错的一件事吧,效果也不错。

关于工作上的事情,跟外围系统、厂商、客户打交道的次数多了起来,的确挺烦人的, 处理不好还容易惹麻烦,我自己在这方面就吃了几次亏,虽然最终都是化险为夷, 以后在这方面还是得多跟有经验的同事讨教。

2012年的生活

2012年,总算把户口的事情搞定,把拖了许久的结婚证给搞定了, 所以今年初要把婚假也给处理了,先放松一下吧,公司的整个氛围的确是挺压抑的。

在公司的杂事多了起来,有时候弄得本职工作必须得快下班才处理,在时间、任务管理上不注意, 没有太多时间陪伴家人,真的感到愧疚。更大的问题是,公司的问题有时候会影响自己的情绪, 常常回想起来感觉很纠结。

自从有了ipad之后,我也不需要经常跑图书馆了,虽然纸质书很不错 (12年我在oschina的读书活动中捞了好几本书),但大多数书籍毕竟不是经久耐读的, 电子版足够了。12年没统计看过多少本书,感觉20+应该有的。

12年下半年之后重新在github上开了博客,因为公司网络限制的原因,几乎是2年没写过了。 到现在,差不多是每周1到2篇的样子,按照以前的写作经验和习惯,这个数量应该可以翻一翻。 不过考虑到现在的工作状况,每周2篇左右是一个比较实际的数字。

2012年的技术

重拾了ruby,在公司内部为团队开发了一个每日code diff的应用,效果不错。
主要学习了golang、html5和node。
对服务化api与多客户端的架构非常感兴趣。

TODO 2013

多点时间锻炼身体。
在时间、任务管理上多多下工夫,重实效、轻形式。希望能够更好掌握自己的时间。
13年完成100篇原创博文。
13年完成50本书的阅读目标(不一定就技术的),过几天整个列表,好跟踪。
完成对codediff的改进工作,有机会的话多做些内部工具。
与同事、应聘人员、合作厂商、客户的交流上,多积累经验和技巧。

超级整理术简单笔记

今天去体育西那边,看到戴玉堆了一桌子的书,挖了本超级整理术的书,在坐地铁的时间看完了。 内容非常浅显直白,原则就是让信息自动化,让工作规则化,让大脑有更多时间思考。

下面简单记录了比较可行的操作。

  1. 使用谷歌搜索来处理文件查找,桌面搜索的好处是可以直接查找内容,另外找文件名的话, everything也不错,我通常让它自动启动,另外用快捷方式操作程序的话,ctrl+r或launchy都是非常实用的工具。

  2. 使用rss订阅,通常有邮箱订阅或者鲜果之类的客户端,google reader也有很多人推荐, 不过鲜果没有展示博文列表的功能,很难看到哪些更新过。所以最好还是使用google reader, 客户端的话,我发现FeedDemon非常不错,和reader配合天衣无缝。rss订阅有很多好处,主要是信息自动飞进来, 通过阅读大量的信息,开阔视野,增强判断力,有助于在信息大爆炸时代辨别那少量的有用信息。 有个遗憾就是,reader在公司用不了,只能在家里用。

  3. 邮件只读一遍,尽快回复,对邮件分门别类。我通常是把没处理完的标红,然后消灭之。 书中提到说,养成这个习惯,让别人对你有好的印象,有助于推动别人和协作。

  4. 将大脑清空,把所有要做的事记录到TODO上,这个非常重要。 我通常使用wunderlist来处理,无论工作事情还是生活事情, 无论大事小事,急事闲事,都记录到上面去。即使这件事情很琐碎或者很紧急,记录上去也是好处多多的。 wunderlist的功能非常简单,支持多客户端。友情提醒一下,工具这东西,不要挑复杂的。 当然,有时候我还借助番茄钟来管理。

  5. 利用TODO整理时间,使用节约的时间提升自己。做事的时候按照TODO的列表弄,就不至于手忙脚乱了。 我通常是使用wunderlist的加星功能,只是关注加星的事项。 因为TODO帮助我们把时间分配到合理的事情上去,防止时间碎片化,所以不至于瞎忙了。

  6. 工作台和电脑桌面要整洁。作者提倡的是整一个整理日,定期清理。

  7. 开会议题要具体,责任要落实,使用会议纪要并用TODO跟踪。 作者还提到,开会要注意成本,所以开会前就要把讨论事宜详细列出,记录会议纪要并跟踪完成情况,我们公司的会就是效率不行呀。