《调试九法》:调试是个技术活

一般当工程师把一个东西称为艺术甚至玄学的时候,说明这个东西难度很大,没有太多规律可以遵循,调试就属于此列。几乎每个程序员都有被bug搞到死去活来的经验,有时候颠来倒去,问题似乎解决了,但也不知道为什么,就把它当作不可解释的玄学现象,最烦人的一种bug是偶尔出现难以复现的,学名海森堡bug。

不过毕竟软件还是属于科学技术的范畴,调试也应当是门技术活。《调试九法》是一本少见的讲调试技术的书,九个普遍性的原则不仅适用于软硬件开发维护,甚至还能运用到日常生活,为了找到这本书我也是费了点神,幸好图灵社区还有正版的电子书卖。

说实话,作者举的很多例子偏硬件,所以理解起来有点隔膜,但是九个原则确实很实用,在我以前的开发调试经历中可能也不自觉的总结过一些,但是看了本书,还是有拿到武功心法的感觉。看过之后,下面再把九个原则遍历一下,加深理解。

1 理解系统

这是最重要的一条原则,要分析bug,自然要理解系统是如何运作的,这就需要学习掌握一些基本原理,对具体的类库、工具、技术都需要认真的去读相关文档。我最近几年才养成了认真读官方文档的习惯,搜索引擎的发达,使得我们养成了面向google编程的习惯,面对问题,总是想一蹴而就的解决,结果往往是走了很多弯路,因为舍不得花时间看路标。本书还特别强调“逐字逐句”读手册,简直是对浮躁的人当头棒喝。不理解系统就开始调试和不理解原理就写代码是一脉相承的,俗称“面向巧合编程”。

2 制造失败

这条原则讲的是复现bug的重要性与方法,一个bug,肯定是在某个特定的条件下发生的,抽丝剥茧找到这个特定的条件,就成功了一半。以我的硬件维护经验来看,发现bug的人如果能详细的记录整个过程是非常有帮助的。有很多bug出现的条件比较苛刻,所以程序员的口头禅之一就是“在我这里没问题啊”。针对这类bug,首先最好能找到模拟方法,比如加快软件运行交互的速度,进行压力测试等,其次就是在软件内部能有详细合理的bug记录机制,便于从内部找到复现的条件。

3 不要想,而要看

这一条强调的是观测的重要性,面对现实比胡思乱想重要。语言影响思考,所以遇到bug的口头禅应该是“我看看“而不是”我猜可能是因为“。我们应该想尽办法去看清楚出bug的细节,所以成熟的程序中都应该有用于调试的基础设施,个人经验至少日志是必不可少的,初级程序员习惯于完全靠打断点调试,问题是断点本身会改变程序执行的流程(尤其是多线程的情况下)。当然,猜测依然是有用的,可以帮我们缩小观察的范围,或者至少拟定一个观察的优先级,这样经验就能发挥作用,但是不管怎样,经验不能替代观测。

4 分而治之

二分查找法可以把查找的时间复杂度从线性变成对数,不仅是程序中的查找算法,也是调试时的方法论,一个系统有了这个意识后,关键是如何划分系统,又回到了原则1。至少在打断点调试时,要找到出bug的位置,也是可以用二分法的,或者插入日志记录时也可以应用这个原则。另外,书中还提到了bug间相互影响的现象,我觉得甚至又bug跷跷板的现象,解决之道是一个都不要放过。调试bug时发现代码质量实在太差,重构一下有时候也是有必要的,否则浮沙之上筑不了高台啊,甚至经过有效的重构,bug很自然的就发现并消除了。

5 一次只改一个地方

这条原则类似实验科学中的对照原则,一次只考察一个变量,比对正常情况和异常情况,一定不能忽略任何一个测试条件的差异。上一条说bug一个都不放过,但也得一条条过,重构的时候也要注意不要对不懂的代码乱改一气,很多代码的危险性在于牵一发而动全身,我觉得这也是修复bug时的最大风险,往往是消除一个bug同时增加几个bug,还是回到原则1,要理解系统。不过有时候,理解前人的代码谈何容易,这也启示我们写代码时要多积德,不要以为代码就是给编译器看的,而应该是给以后维护我们代码的人看的。

6 保持审计跟踪

这条原则讲的是记录的重要性与方法,我想这就像医生问诊一样,需要问合适的问题,给出具体的有效答案。我的个人经验是一旦开始调试bug,可能整个人就彻底陷进去出不来,通过记录的方式可以把自己从思维的泥潭中抽身出来,不断修正调试bug的计划与方法。对一些专用系统软件,需要培训软件的使用者如何用有效的语言来记录出现bug的情况,如果没有记录,那么调试的人就需要用适当的问题帮助使用者唤醒记忆。此外,我觉得半夜调不出的bug需要睡一觉,让发散思维自动起作用,一般早上就解决了。

7 检查插头

这条原则大概说的是所谓”低级失误“了,类似我妈跟我说电脑音箱不响了,我首先得问电源开了没这种。又比如把main函数写成mian函数,有一次我打断点调试就是不进断点,后来发现是因为有两段代码比较类似,我断点打错地方了。根据场景和经验,问问自己是否犯了该场景下常见的低级失误,往往针对能立竿见影的解决很多问题,就像很多电器设备说明书的故障FAQ中,也会强调检查插头。可以说,低级失误低级的是难度,而不是频度。

8 获得全新观点

这条原则说的是求助和交流,这里面很重要的是通过他人的观点来破除自己的思维定势,所以最好是只给别人详细描述现象,不要说自己的猜测,以免污染别人的判断。对程序员而言,这时候面向google编程的力量是惊人的,可能九成的问题都不需要你真正的再去提问,而是找到合适的搜索词去搜索即可,对中国程序员而言,用英文搜索是必须的技能,当然搜到东西后真正理解也是非常重要的,不能见到药就吃。如果遇到的问题google真的搜不出来,证明你层次稍微高了点,这时候可以上stackoverflow之类的社区提问。

9 如果你不修复bug,它将依然存在

这条原则说的是不要心存侥幸,不要因为bug只是闪现了一下就采取鸵鸟策略,该来的总会来,不是不报,时候未到。当然实际情况可能很复杂,软件工程本来就是时间、成本和质量的妥协体,但即使放过某些bug,也要分析出这样可能造成的后果,建立充分的防护机制,因此在很多软件认证体系中,都会有软件安全等级标准。这里还涉及bug复现和举一反三的问题,需要确认真正找到了bug的原因提供了有效的修复手段,并排查所有类似的问题。比如修复了一个内存泄露问题,就要修复所有导致这类泄露的代码。

附记:如何写出适合调试的代码

从调试的原则反观,对软件构建本身也很有帮助,毕竟调试只是查漏补缺的,最好还是写出来的代码少一些bug,为了调试的时候方便多预留一些手段。这里也简要总结一下个人经验,可能需要不断完善。

  1. 程序中应该提供日志机制,在程序的debug版便于输出调试信息,即使在release版,也要记录软件发生问题(如C#中抛出异常)时的详细情况;
  2. 要写出适合人类阅读的代码,否则后续维护的人看都看不懂,要如何调试?怎么写《代码大全》中说得最详细了,我觉得除了各种习惯写法之外将心比心也是很重要的;
  3. 使用各种类库或工具时,尽量弄懂原理,仔细的阅读官方文档,比如有些类库会详细说明如何防止内存泄露,如何应对多线程情况,看清楚再用,就会少种下祸根,至少不用等到调试的时候再无头苍蝇一样猜测原因;
  4. 写便于测试的代码,这样在调试时,容易剥离问题,或者使用二分法,这方面TDD编程实践讲得比较充分,我个人也需要加强。

如何序列化泛型List为xaml

Xaml实际上是一种加强版的Xml,Xaml最初是为了描述WPF控件而设计的,但其实具有一定的通用性,用Xaml序列化对象,可以自动维护对象间的引用关系,大大减轻工作量。

1. WPF控件中泛型List的序列化

Xaml序列化对象最直接的应用是保存和加载WPF界面与控件。考虑类似以下的自定义控件类,它包含了一个泛型列表属性。

public class WpfObject : Label
{
  public WpfObject()
  {
    Children = new List<string> { "hello", "wpf" };
  }
  public List<string> Children { get; set; }
}

WPF控件的序列化方法如下:

WpfObject w1 = new WpfObject { Content = "Hello, wpf" };
string xaml = System.Windows.Markup.XamlWriter.Save(w1);
File.WriteAllText("label.xaml", xaml);
WpfObject w2 = (WpfObject)System.Windows.Markup.XamlReader.Load(File.OpenRead("label.xaml"));

由于XamlWriter类的不完善,不支持泛型列表的序列化,上述代码将抛出异常:

无法序列化泛型类型“System.Collections.Generic.List`1[System.String]”
Cannot serialize a generic type “System.Collections.Generic.List`1[System.String]”

所以需要包装泛型列表属性,使其能序列化,最简单的方法是使用派生类,代码如下:

public class Children : List<string>{}
public class WpfObject : Label
{
    public WpfObject()
    {
        Children = new Children { "hello", "wpf" };
    }
    public Children Children { get; set; }
}

使用前述同样的序列化代码即可。

2. 普通对象中泛型List的序列化

自.Net4.0后,微软在System.Xaml.XamlServices命名空间重新设计了Xaml序列化,使其更好的支持一般的对象,不过比较讽刺的是,这个命名空间的序列化却不能很好的支持WPF控件,所以依然只能用本文第1部分的方法去hack。

考虑以下类型:

public class CommonObject
{
    public List<string> Children { get; set; }

    public CommonObject()
    {
        Children = new List<string> { "hello", "common" };
    }
}

它的序列化很简单直接,代码如下:

CommonObject p1 = new CommonObject();
string xaml = System.Xaml.XamlServices.Save(p1);
File.WriteAllText("parent.xaml", xaml);
CommonObject p2 = (CommonObject)System.Xaml.XamlServices.Load(File.OpenRead("parent.xaml"));

分解的力量

如何完成一件复杂的事情?可以把它分解成很多相对简单的步骤,然后一步步去完成。这个道理再简单不过了,但想要通过简单的道理过好这一生,则需要对道理反复的践行与思考,以下就是我这几年的一点人生经验。

为什么要分解?

管理复杂性

复杂的事情需要分解去做的最直观的原因就是管理复杂性,一个再聪明的人,他或她的大脑能同时把握的细节也是有限的,从脑神经科学的角度来说,大脑的工作记忆插槽是及其有限的,将复杂的事情分解、打包,可以大大降低思考的难度。如果一件事情需要100个步骤才能完成,在仔细分解前,大脑看到的简直是一团迷雾,看不到事情的边际,拖延丧气的负面情绪随之而来,对从事知识型工作的人简直是噩梦。

将事情分解为100个步骤后,它的复杂度没变,但是借助各类工具,大脑可以不必一次性载入100个步骤去思考,而是可以只载入某几个步骤,也可以对一些步骤打包命名,大脑存储的将是一些助记符。一件复杂的事情,从一团迷雾变成了可以在不同尺度去观测的结构,可能从大的视角看,有10步,仔细看每个步骤,又可以分为10步。

管理复杂性的典型用例就是软件行业,子程序、对象、模块等,无一不是发明出来用于管理软件复杂性的,如果你是上帝,大概可以一个软件一个大杂烩式的一次性开发完,但我等凡人只能通过各种机制来分解复杂的模型,大脑每次面对不同层次的抽象,都只处理较少的信息。

激励机制

最懂得分解事情的人是游戏设计师,不论愤怒的小鸟这类休闲类游戏,还是复杂的RPG游戏,都会不停地设定小的激励目标,如果一款游戏通关要几天,而且没有任何中间目标需要达成,大概是没人愿意玩的。

现实生活与玩游戏唯一不同的是,阶段性目标需要你自己去设定。比如,要写一篇毕业论文,有些学校只考察最后的答辩,有些可能会加上开题审查和中期审查,但是分解的尺度还是太大,不足以激励我们懒惰的大脑去干活,所以拖延写作简直是一定的。反之,如果你定好小目标,今天写3000字或者查阅10篇文章,然后奖励自己看一集《海贼王》,懒惰的大脑就会被激活。神奇之处在于,大脑可以指挥大脑欺骗大脑,看着眼前的胡萝卜一直走下去。

实际上,对一个做事情本身有一定激情的人来说,如果你用一个清单工具去设定自己的阶段性目标,在完成一个阶段后就去画一个勾,都不需要其他任何奖励,就会有类似玩游戏的快感。如果做的事情没有激情或者不是发自内心的渴望,那么阶段性奖励一下自己喜欢的则是有益的。

第一步效应

做事情时,进入状态难是阻碍我们开始做事情的最大障碍之一,开始做事前,可能觉得这里难受哪里不爽,一旦开始了,进入状态了,更多的则是做事情本身带来的快乐,状态极好时,会进入“心流”状态。所以能够坐下来干两小时活的关键可能在于最初两分钟。

一般来说,大脑一看到复杂的事情就习惯性烦躁,那么当我们把事情分解得够细时,大脑直接面对的是一件简单事情,心情自然好很多,而结果就是一旦开始,可能根本停不下来,对待拖延症的秘诀之一就是你好死赖活先要开始去做,不论做得怎么样。

如何吃完一碗饭?先要开始吃第一口。如何跑够十公里?先要开始跑第一公里。通过分解使我们面对可以接受的第一步,然后大脑又可以欺骗大脑一直干下去了。

如何分解?

分解到能够开始工作

不同的事情,自然根据它的特点有不同的分解方法,同样的事情,对不同的人也需要不同的分解方法,对一般人而言,打电话可能都不值得算一个步骤,但对有打电话恐惧的人而言,可能需要先打好腹稿,然后拨号,然后交谈,至少也得三步。打腹稿的时候不用考虑后续的事情,拨号是一个机械动作,交谈则是对腹稿的发挥,而且自然会有两个人语言上的循环反馈。

分解的详细程度,取决于不同的事情和不同的人,首先以能够开展工作为目标,只要还觉得难受或者茫然,就需要继续分解。所谓“天下大事,必作于细”也不妨从这个角度去理解。

在各个领域,分解问题的能力都是需要不断锤炼的基本技能,比如在软件行业,在需求分析时需要分解工作估算时间,架构设计时需要划分模块。但不管任何领域,分解到能够开始工作是一个不完美但足够实用的策略。

时间尺度

拨开复杂事情的迷雾往往是一个困难的事情,一个需要一年完成的项目,真的能分解到每周都要做什么?几乎不可能,尤其是这个项目有一定的创新性时,这种困难有时会导致我们对分解与计划的失望,干脆走一步算一步。

折衷考虑一下,需要注意分解时的时间尺度,离当下越近,分解出来应当是越具体详细的事情,强调可操作性,越接近死线,分解出来应当是越概要的目标,强调战略性。

在做计划时,可以先以日为单位,逐渐变到以周、月为单位,日内的计划可以用清单的形式,或者只是在脑子里列个清单即可。

分解的迭代

少有人能在第一时间把一件事情彻底分解清楚,但是又不能一直想着怎么分解导致事情无法开张,所以分解的迭代是必不可少的,计划与总结是相辅相成的,通过总结反馈,才能不断修正分解,制定新的计划。

结合时间尺度来看,随着时间的推移,那些以大尺度分解的事情,会在迭代中逐渐细化,到最后,事情就做完了。

为了完成一件复杂的事情,需要做分解的工作,也需要做具体的小步骤,这二者不是简单的先后关系,而是反复迭代关系,所以在做事情时,需要在宏观和微观两个角度反复切换,不能陷入细节忘了自己的最终目的是什么,也不能一直举棋不定。

clips语言优秀资源列表

在机器学习技术大热的当下,专家系统可能是一种有些“过时”的技术,但依然有它的适用场景,clips语言是C语言开发的开源专家系统语言,我在项目开发中学习使用了该语言,以下是我搜集整理的一些clips语言相关的优秀资源。在备忘之余希望能对其他人有所帮助。后续将不定期更新。

基本资源

  • 新版官网
  • 旧版官网:可能需要科学上网才能访问。
  • 文档列表:User’s Guide浅显易懂,非常值得一读,需要深入了解可以看看Basic Programming Guide与Advanced Programming Guide。
  • 教材中文版:教材由clips开发者撰写,包括专家系统的基础知识与设计实现,以及具体的clips语言的语法与使用。电子版下载地址
  • stackoverflow:clips开发者的有在stackoverflow回答问题。

函数库

工具

.Net封装

clips适合嵌入到软件中执行规则推理,使用C#开发界面,则需要将clips封装到.Net。封装的思路主要为PInvoke或C++/CLI。

  • CLIPS .NET:clips官方开发了一个.Net Wrapper,而且包含了Winform和WPF各四个示例,封装方法为C++/CLI,接口较少,不支持自定义函数。
  • CLIPSNet (SourceForge):使用PInvoke技术封装,使得风格不像面向对象语言,更新到2015年。
  • CLIPSNet (github):我维护的一个.Net Wrapper,封装方法为C++/CLI,更新clips和.Net Framework到最新版,接口较多,支持自定义函数。

Python语言入门

这是一个简单介绍Python的Slide,鼓励团队成员学习Python,用于数据分析等。

Hello world!

朝闻道,夕死可矣。

2013总结

2013年躲掉了公司的个人总结,颇为庆幸。除去繁文缛节,写写总结还是有好处的,所以随便谈谈自己的2013。

回顾

工作

前段时间看《More Joel on Software》,知道了内部程序员的概念,突然明白了自己的定位——“三成的内部程序员”,虽然这一年可能有七成时间在做程序员的工作,但这种状态毕竟是临时性的。这一年可能是编程进步最大的一年,但也更加意识到作为一个内部程序员与业界的差距有多大,确定自己要想在若干年后投入IT界,以技术吃饭基本上很困难。在担心项目进度的过程中,急躁和拖延症并行,把自己的性格缺陷发挥得淋漓尽致。 程序员之外的工作,做得不太理想也不太开心,除了上司难伺候的因素外,个人不喜跟人打交道,不善于指使人干活是主要原因,如果把这些当一门学问来可能好接受一些。事实上,跟理解力强、执行力强的人打交道是比较轻松的,但问题在于更多的人理解力执行力不太好,但团队合作又需要他们。

住房

2013年的首尾都在烦心住房问题,从年初的被轻易忽悠到年尾的主动出击,虽然不知道自己的努力对最后的结果有多大作用,但好歹也是一次自我争取,在这种环境下,矜持是没有出路的,还是那句话,最关心你的人永远是你自己。拿到房子的时候和老婆都大失所望,但转而激起改造之心,忙忙碌碌中,一个小家一天天像个样子了。这小小的幸福来得不容易,只能怪自己选择了一条hard通关模式。所有的家庭计划,只能围绕着房子来,这被耽误的一年,我在心里记了一笔。处理这件事情,偏离了个人擅长的领域,几乎暴露了自己所有的缺陷,或者说和这个现实不适应的地方,急躁、不必要的完美主义、缺少承担。 在综合分析之后,基本确认了未来几年的工作地点,一旦确定,就要坚定的执行下去,怀着肖申克的救赎式的毅力。

购物

尽管网购也有不方便的地方,但几乎成了唯一选择,淘宝、亚马逊、京东、国美在线还是比 较给力的。买东西越来越注重外观,相信不重视外观的产品,其内在也值得怀疑。比较喜欢日式的风格。如无必要,勿增实体。今年买过的最神奇的东西,貌似是3M除锈润滑剂。 ###电影 今年大概看了60部电影,推荐《东京家族》和《Before Midnight》,第一部是山田洋次向小津安二郎的《东京物语》致敬之作,第二部是奇葩话痨爱情电影《Before Sunrise》和《Before Sunset》系列的第三部。

阅读

不包括一些临时查阅的技术书籍,今年大概读了三十本书,其中电子书居多。除了方便携带外,好像读完的心理压力也小一些。今年买了一百多块钱的正版电子书,亚马逊、豆瓣阅读、多看阅读、图灵都有花钱。 推荐《暗时间》,刘未鹏这本不是新书了,但今年才看,除了书本身不错外,也是一个好的书目,介绍了不少认知学、心理学等方面的好书,比如《别做正常的傻瓜》非常有意思。

网站/服务

推荐知乎,学到不少知识,最实用居然是购物推荐之类的…… 推荐GoAgent。 推荐多看阅读,书的排版质量不错,可惜的是书目还是少了点。

展望

工作

完成好手头的项目,精进.Net开发。 以做学问的态度学习与他人的协同,提高自己的涵养,少担心,多实作。

锻炼身体

多年来第一次三千米测试未通过,警钟敲响了。以后每周跑步若干次,周末和老婆打打羽毛球。

生小孩

这个主要得靠老婆,但我得开始学习各种相关知识了。除孕产育儿知识外,还要预习教育学知识。

旅游

尽量探索所生活的城市,过年带父母好好逛逛。

理财

改变之前完全不理财的状态,清点手头资产形成财务状况报告,办信用卡,制定消费与投资计划并实行。

超越抱怨

曾经有本畅销书叫做《不抱怨的世界》,“不抱怨”和“和谐”一样,实在是太容易被宣扬者滥用了。“上面的人”最爱这种论调了,如果“下面的人”都不抱怨,世界就彻底和谐了。但若你身处底层,无力改变环境,难道连抱怨的权利都没有了么?“发牢骚,讲怪话”,可能是一个天天被鱼肉的人尚非行尸走肉的最后表征了。

是的,抱怨的能力可以证明一个人尚未麻木,但好的抱怨是需要思考的。好的抱怨需要发现事情的不合理之处,司空见惯之事,并不一定合理。一个缺乏自我知识架构与独立思考能力的人,他的抱怨最多也就是随大流而已,类似“贪官太多”这种。

抱怨本身是可能有力量的,它可以形成舆论,但更可能只是让自己找到一个恶气的出口,益处有限,如果想活得更明白乃至改变环境,就必须超越抱怨。

如果你发现了他人未发现的不合理之事,首先要理解它的合理性,这种合理性是“存在即合理”意义下的合理,理解不等于赞同,它可以让你明确思维盲点,也可以消解情绪。在最差的情况下,你可能完全无法改变这件事,但发现了不合理之处,理解了不合理得以运行的原理,至少也是活得明白一些吧。

在充分理解不合理之事的合理性的基础上,可以尝试提出自己的解决方案,这就超越了抱怨,进入建设性意见的境界了。若无对合理性的理解,即使提出了方案,也必定是一厢情愿式的。如有机会,去实现自己的解决方案,这时,你可能成为“改变了一些事的人”。若无机会去实施,提出自己的解决方案依然是有益的,仔细分析需要达成事情变化的条件,你即使改变不了什么,至少可以试图看清事情发展的趋势。

“不抱怨的世界”有两种,一种是失去了抱怨能力;而另一种则是超越抱怨,这需要不断锤炼自己发现问题分析问题解决问题的能力,实在是值得一辈子去做的事情。世间的快乐有无忧无虑的快乐,也有知道忧虑后解决忧虑的快乐,我选择后一种。

《奇特的一生》笔记

《奇特的一生》这本书讲的是苏联生物学家柳比歇夫的故事,但不是一部典型的传记,而是用散文的手法揭示了柳比歇夫人生的奇特之处。柳比歇夫有诸多的研究成果,涉及生物学及其他很多领域,但他并不是一个天才,他最奇特的地方在于他使用时间的方式和对待时间的态度,他从二十六岁到八十二岁一直在记录、统计、规划自己做每一件事情的时间,精确到小时与分钟,直观的效果是,他似乎比常人多出来很多时间,尽管他每天睡10个小时,经常参加各种娱乐活动,但他一生完成的工作量却让常人难以想象。柳比歇夫执行这种方法简直就像一个最最严于律己的教徒,这种行为体现出的他对时间的理解,对我有很强冲击力的。

时间是一个司空见惯的概念,但它的许多特质说出来却是很不寻常的,它是我们唯一真正拥有的东西,失去之后就不再可能找回,但现实是,我们会以各种借口来挥霍时间,仅仅为了寻找一个最佳的时间去做某件称心的事,这不仅涉及工作,也涉及生活和娱乐。相比柳比歇夫的时代,现在我们消磨时间的方法更多了,消磨时间这个说法是很诡异的,如果怀着热情做某一件事情,很难说是消磨时间,即使干的可能不是一般意义上的正事,而如果只是为了让时间过去,那就是让自己陷入了一种等待的状态,这样看,柳比歇夫的人生字典里没有等待。

如果说生命是宝贵的,那么组成生命的每一秒都是宝贵的,所有的时间在物理学上,在道德上,都值得一视同仁,这种观念可能会挖掘出一个人难以想象的潜能,这不是教条的要求自己每天工作时间不少于几小时,而是说发挥每一分钟的作用,看清自己的生命轨迹,柳比歇夫不是一个为了伟大的事业将自己的全部时间投入进去的人,而只是一个善用了所有时间的人,所以他是可信可学的。以我个人的经验而言,时间常常是在莫名其妙中被黑洞吸走的,而不是为显而易见的娱乐所浪费,看了多少电影、闲书,都是有迹可循的,最可怕的大概是无帐可查的犹豫与发呆,将大脑陷入情绪的海洋。

柳比歇夫的时间统计法,难度不在技术上,而在于坚持上,如果不是对于时间的热爱,是难以做到的,这不是简单的把自己变成机器人模式,而是基于记录统计更加灵活的利用自己的生命,发挥其无穷的可能性,这种发散主要存在于思维精神领域,柳比歇夫的物质生活反而是极简的,如果是为了升官发财沽名钓誉的目的,我估计是很难坚持的。对于时间的理解,牵涉到对于宇宙、对于生命的理解,柳比歇夫的时间统计法,不单单是一种方法,更是一种精神修养,一种道德标准,一种道。

柳比歇夫值得我学习,因为我们追求的东西似乎有些一致,尽管我对自己追求的究竟是什么还在求索之中,但我似乎闻到了同类的味道。接下来就是我读完本书后对自己的劝谕,至于要不要学习他的时间统计法,还有待考虑。

2012总结

2012年完成了计划中的硕士毕业、重返工作岗位、结婚等大事,但更重要的是,2012年是我逐渐活得明白的一年。在奔三的道路上才开始活得明白,不是一件值得骄傲的事,但却是一件值得欣慰的事。

若要把慢慢开始明白的道理写出来,大概是一件无趣的事情,很多很简单的道理,是青春耗散后才得来的,说出来对人也无甚益处,因为即使是称得上人生哲理的,也不过是一剂药,万能药是不存在的,对症下药则殊为难得。转而想到或可博若干年后的自己一笑,却有了一点记录的冲动。

他人对你的看法没有想象中那么重要

想想自己每天是如何谈论他人的,除了和自己真正利益相关的人外,我们是不会真的花气力去关心的。亲友会询问你最近过得怎么样,但即使不单是出于客套,这种询问和你的生活又有什么关系呢?过得好不好,终归是只有自己才知道。一个人被他人寄予厚望,自然会有些益处,但代价可能是一辈子也不明白自己想要的是什么。人生在世,大概免不了被划分到各种集合,可是如果没有抽离出集合看看自己,这一辈子的意义无非也就是给这个集合增添了一个一。自2003年6月高考以来,我一直迷茫在莫名的失败阴影中,现在看来这阴影不过是臆想中用他人的只言片语自造的一个陷阱而已。

将复杂的事情分解了去做

一个人要有动力去完成一件事情,需要正向的激励,而事情很复杂的时候,正向激励会比较难出现,看不到事情的边际的时候,拖延丧气的负面情绪随之而来,能一口气解决掉的事情是让人愉快的,这就是电子游戏吸引人的原因,且不论愤怒的小鸟这类休闲类游戏,即使是复杂的RPG游戏,也会不停地设定小的激励目标,如果一款游戏通关要几天,而且没有任何中间目标需要达成,大概是没人愿意玩的。小时候我擅长做作业与考试,想来不过是一种另类的游戏,每道题目就是阶段性目标。现实生活与玩游戏唯一不同的是,阶段性目标需要你自己去设定,规划分解实施总结修正,如此循环下去,一个个小的目标逐个达成后,也许能到达自己曾经恐惧的彼岸吧。

永远保持学习的态度

在部分人眼中,学习是学生的事情,这种看法是愚昧而自负的。有活到老学到老的古训在,保持学习的态度不是什么新鲜说法,只是什么是真正的学习,什么态度是真正的学习的态度,是需要仔细思考的问题。对成年人而言,学习往往是一种自我革新,自己是自己的既得利益者,自我革新于是会成为一种自我伤害乃至自我折磨,人本能的爱为自己造一个舒适区,因此学习并不总是快乐的,尤其是在需要自我反思的时候。过于安稳的生活是学习的敌人,而追求安稳是人尤其是中国人的天性,所以活到老学到老通常只能说说而已,由此来看,学习的态度大概是一种折腾的态度,要永远保持学习的态度,就要保持一颗折腾的心,或者说,一个不安于现状的人,最需要保持学习的态度。