从开平方说说写代码应该考虑的事儿

引言

很少有程序员需要自己写开平方函数,因为基本所有的语言都自带开平方的函数。更不用说1999年发布的SSE指令集,从CPU指令的级别上支持了开平方运算。当然这依然阻挡不住程序员们探索各种开平方方法的热情。其中最著名的当属John Carmack在开发Quake III时写的那段用精度换速度的Magic Code。如果你更关心如何提高开方函数的速度,你可以参考这篇比较各种方法速度文章,其中有些比单纯地使用CPU指令sqrtss开平方更快。

本文的关注点并不是速度,你甚至可以在本文中看到或许是业界最慢的一些方法。本文专注从软件工程领域的各各视角考量几种风格迥异的开平方函数,通过它们展示如何让代码的可重用度更高、使用上的灵活性更强、复杂度更低,以便于理解及维护。你总是可以在需要的时候,比较容易地提高一个具有高可维护性、设计良好的系统的性能。而一个系统一但由于代码质量上的问题,进入了一种难于理解、难于维护、难以变动、不可重用、无法预测运行结果的状态,如果再想提高其性能什么的,基本上就只能重写了。

导读

本文代码使用的语言是F#。但是你不必担心自己是否学过这个语言,当英语起来应该不会有什么问题。 本文中的示例与求解思路主要来自《Structure and Interpretation of Computer Programs 2nd Edition》,书中使用的是Scheme语言;类似地,那本书是某大学的计算机专门的入门教材,甚至不要求读者有编程经验。但是会需要微积分的基本知识,否则你应该只能搞懂第一个函数。

如果你很熟悉F#,那太好了,本文中的代码都是我一边看F#编程参考一边写的。如果有什么更好的实现方式,也希望你能指出来。

如果你根本不是计算机专业的,本文也值得一读,它或许能解释为什么你的那些计算机专业的同学们既不会修电脑修手机,也无法帮你找回被你遗忘的某网站的密码。因为下面这些才是他们所能解决的问题。

问题引出

求平方根运算的方法有很多,我们初中的时候就学习过手算开平方,还发过一个小册子,上面有各种数据表,用来直接查询一些数的平方根等。但是那些方面都不能方便才用于计算机:手算开平方规则较多,数据结构也复杂,代码量会很多;查表法需要过多的数据存储空间,也不切实际。

非计算机专业的人,很容易错估计算机领域问题的复杂度,一方面是因为人们总是喜欢这样做:先把问题在自己熟悉的领域重新定义,然后用自己在这个领域所熟悉的知识解决这个新问题,并声称原来的那个问题应该也具有同等的复杂度,并可以类似地解决掉。逻辑不好的人会很吃这套。

事实上,很多计算机专业人士在这方面也不惶多让。通常而言,在计算机领域,针对一个问题,找到一个可行的方案通常都是很简单的,并不需要什么高深的知识和精巧的构思。比如,如果你并没有高等数学的知识,仅仅用初、高中数学知识,你或许可以自己想出折半查找法求x的根,在[0,x)区间内以二分法搜索解,并得出像下面这样的代码:

open LanguagePrimitives

let inline abs x = if x > GenericZero then x else -x
let sqrt_v0 x = 
  let rec search f a b = 
    let close_enough target tolerance value =
      (abs (target - value)) < tolerance
    let avg = (a + b) / 2.0
    if a - b |> abs |> close_enough 0.0 0.001 then
      avg
    else
      match f avg with
      | v when v > 0.0 -> search f a avg
      | v when v < 0.0 -> search f avg b
      | v -> avg
  let half_interval_method f a b =
    let valueA = f a
    let valueB = f b
    match (valueA, valueB) with
    | (x, y) when x < 0.0 && y > 0.0 -> search f a b
    | (x, y) when x > 0.0 && y < 0.0 -> search f b a
    | (x, y) ->
      invalidArg "a" "f a must be of different sign with f b."
  half_interval_method (fun v -> v * v - x) 0.0 x

代码1

这个代码可行,结果也正确,只是有些小问题,比如:代码量多、速度慢、精度低。通常人们不把代码量当问题,因为它不能当作任何标准的度量;如果同时又对性能也没有什么过高要求的话,那么这段代码堪称完美。只是如果哪天需要改进其精度,会发现性能会随精度要求的提高而急剧下降。如果又想同时改进其性能,基本就只能整个重写一遍。这种半调子代码,几乎是所有软件项目的潘多拉魔盒,一但被打开,就会变得无法收拾。

问题的根源

写出高质量的代码,是每个软件工程师的职责,一个软件工程师的水平也可以通过其代码质量而得到体现。所以其实没有人会刻意地去写出像上面那样的半调子代码。出现这样的代码的原因,更多是非主观因素。比如相关知识储备不足、比如项目本身风格约束、比如工程进度的压迫等等。他们专注于问题本身,并尽自己所能写出了自己最满意的代码,却可能意识不到它其实是有多糟糕。这也是软件工程和土木工程的最显著不同:土木危楼,一目了然;软件危机,至死方现。

除了对计算机本身和软件工程本身的研究,多数软件工程项目都不仅仅需要软件方面的知识,更需要把软件工程知识与相关领域知识结合起来才能发挥其价值,这也是软件开发工作相比其它工作最特殊的地方之一。所以人们常说搞软件的要一直学习,这是没错的,因为在软件业,任何已经解决过的问题都不是问题,一方面是要学习如何解决这些问题,另一方面,如果想创造出些新的价值出来的话,势必要做一些别人没有想过、没有做过的事情。这些是题外话。

问题分析

求平方根函数,就是这种跨领域问题,解决起来总有两方面的基本工作要做:

  1. 熟悉领域知识。
  2. 找到这个问题在计算机领域的合适的解决方式。

开平方是一个数学问题,在着手设计并编写代码之前,从数学分析的角度深入而全面地了解一下这个问题是必不可少的。在这方面的工作都没有做充分的情况下,就会产生出类似上面的代码。

问题的解决大体如是:对问题本身有一个大局观,才能从中找到更合适的解决方案,同时也可以避免陷入自己的先入为主的知识体系的牛角尖而无法自拔。在这个阶段,有这样几个核心问题要回答:

  1. 问题所在领域的知识有哪些?
  2. 哪些知识可以更好地解决这个问题?
  3. 问题的环境(上下文)是怎么样的(问题没有普适的解法,所以需要针对具体环境)?

这些问题或许有些抽象而空洞,我们下面就开始一步步地求解开平方问题。最后这个函数写成什么样都不重要,重要的是我们如何走到那一步的,以及为什么要走那一步。

问题的求解

基本需求

回到问题上来。我们的目标是希望有一个函数,可以用来计算一个数的平方根,并需要满足以下的要求:

  • 时间复杂度在特定精度下为常量并稳定。
  • 可以灵活地调整所需要的精度。
  • 其他程序员能看得懂。

折半查找法并不符合前两个基本要求。所以它不是一个好的方法。

古巴比伦算法

我们只要简单地搜索一下就可以知道常见的开平方解法有哪些。而且不难发现有些方法在计算机系统上实现起来比折半法还要简单。比如公元前2000年,美索不达米亚人所使用的古巴比伦算法。而且不需要什么高深的数学知识,只是我们初高中没有学习过,不广为人知而已。

其计算过程很简单,如果我们猜g是x的一个根,那么\frac{g+\frac{x}{g}}{2}会是一个更好的根。用代码实现起来也很简单:

let square x = x * x
let sqrt_v1 x = 
  let rec sqrt_it guess =
    if (abs (square guess - x) / x) < 0.001 then
      guess
    else
      sqrt_it ((guess + x / guess) / 2.0)
  sqrt_it 1.0

代码2

代码2中我们把1.0当作所有数的平方根的初始猜测,然后迭代上面的算法直到误差小于0.001。这个函数基本满足前两个需求。只是没有背景知识的话,有些不太好看懂。对于一些对代码质量没有要求的环境,这个函数也已经完美了。

但是我们希望代码好读一些。而有心的人也会问,巴比伦人的算法的原理是什么。这些问题都还没有解决。

函数抽象

一个非常简单的提高代码可读性的手段是给你读不懂的部分起一个名字。

open LanguagePrimitives

let average x y = (x + y) / (GenericOne + GenericOne)
let close_enough target tolerance root = 
    (abs (target - root) / target) < tolerance 
let avg_damping f = fun x -> average x (f x) 
let sqrt_v2 x = 
  let getNext = avg_damping (fun v -> x / v)
  let rec sqrt_it guess =
    if square guess |> close_enough x 0.001 then
      guess
    else
      sqrt_it (getNext guess)
  sqrt_it 1.0

代码3

与前一个版本相比,这个函数其像仅仅是提取出了几个独立的小函数,给他们起了更明白的名字而已。有没有独立的函数,有没有名字都不是重点。每个语句都可以被提取成一个单独的函数,但是那样做一点意义都没有。重点是:哪些需要被提取出来,哪些不需要。引导你做出那些决定的策略才是重点。很多人不屑于做这种小函数的提取,尤其是在这些函数只有自己用的时候。但是有些有价值的东西,只有你这样做了之后才会发现。

比如上面的代码,经过整理之后,你就会发整个代码段中,与开平方运行有关的只有加粗的那个函数。这是一个非常强的信号,这个sqrt_v2函数的求解过程应该有着某种通用性。这个感觉没有错,那通用的部分就是求解方程的不动点。合理的函数提取就是过程抽象的手段,而提取之后又可以发现新的模式可以进一步抽象。过程抽象本身可以推进过程抽象。

于是那个通用的部分就又可以被提取出来了。于是开平方的代码本身就只剩一行了。它的含义就是:函数y=\frac{y+\frac{x}{y}}{2}的不动点,就是x的根。

let rec find_fix_point f guess = 
  let next = f guess
  if close_enough next guess 0.001 then
    next
  else
    find_fix_point f next

let sqrt_v3 x = 
  find_fix_point (fun v -> average v  (x / v)) 1.0

代码4

比较代码2、3、4,这三个版本的代码都源自古巴比伦算法。只是代码4具有更高的:

  • 可重用性:find_fix_point, avg_damping, close_enough都是通用方法。
  • 稳定性:基本可以在3次迭代内得到的一个很近似的解。
  • 可读性:代码量少,含义明确。

剩下的两个问题

根据我们之前提出的需求,代码4还存在两个主要的问题。

  • 可维护性比代码1低:因为依赖更多的领域知识,如果不知道古巴比伦算法,基本看不懂这个代码是怎么写出来的。
  • 其精度不可灵活控制:其内部使用了0.001来判断一个解是不是够好。但是显然对于计算\sqrt{0.0001}就不能正常工作了。

这两个问题是在我们选择古巴比伦法之前没有遇见到的。在软件开发的过程时常会出现类似这种状况:有些问题只有做出来甚至上线之后才会出现

这两个问题不是数学问题,而是纯粹编程实现上的问题。这也正是我们在分析领域问题时所需要注意的,如何把领域问题与计算机系统结合起来,并找到可能存在的问题及适合的解决方案的地方。

类似的,常见的计算机系统在数学领域的约束还有:

  1. 数值表示的精度。
  2. 数值表示的范围。
  3. 数值运算的截断误差。
  4. 不同数值运算间的速度差异。
  5. 数值求值策略对数学公式的敏感性。(等价的数学公示可能会有不同的运算结果。有些是数学本身的问题,有些有计算机系统约束的问题。)

我们下面继续分别解决这两个问题。但是不要忘了基于上面的话,它告诉我们:我们为解决这个两问题而引入的技术,很可能会带来新的问题。这是不可控的。只有做了才能发现。这是软件工程复杂性的另一个体现。《Principles of Computer System Design》一书对此进行了更详尽透彻的讨论。在此就不展开了。

牛顿法

当把一个函数化简到代码4的样子,我们不难又可以发现:如果我们不是要开平方,是要开立方。唯一需要改的地方很可能就是那个不动点方程。但是古巴比伦人没有给出开立方的迭代求解方法。即使有立方的,那任意次方的呢?更进一步地,有没有一个不动点方程可以求解任意一元多项式方程呢?牛顿说有:

假设a是对方程 f(x)=0的一个估算解,且f(x)可导,令:

b=a-\frac{f(a)}{f

那么b是个比a更好的近似解,其中f'(a)是 f(x) 的导函数 f'(x)在a点的值。

很少有编程语言能在语言层面支持求导运算。但是任何语言都可以根据导数的如下定义:

Dg(x)=\frac{g(x + dx) - g(x)}{dx}

实现出一个求取函数f导数值的函数:

let deriv f dx = fun x -> (f (x + dx) - f x) / dx

并得到一个使用牛顿法的开平方函数:

let newton_method f = 
  let Df = deriv f 0.001
  find_fix_point (fun x -> x - f x / Df x) 1.0

let sqrt_v4 x =
  newton_method (fun y -> y * y - x)

代码5

我们看到这个版本书使用的函数y=y * y - x就是解为x的方程本身。那么即使你不明白牛顿法的工作方式是什么,你大概也可以猜到求立方根的方法可以写成这样:

let cube_root x =
  newton_method (fun y -> y * y * y - x)

代码6

看上去,基本所有的可导函数的解都可以用牛顿法解。但是事情其实不会这么简单。但是对牛顿法的深入讨论不在本文的讨论范围内。如果有兴趣可以自行参看微积分相关书籍。

另外需要注意的是,在代码5中的Df函数中,又引入了一个新的精度假设值0.001。我们提高了代码的可读性和可扩展性,但是进一步损害了其精度(4次迭代之后在小数点第9位会体现出来)。之后会介绍可以解决这个问题的一个方案。

无限延迟求值流

对于精度问题,有一个看似十分简单且可行但是实际没有太大价值的解决方案:把精度当参数之一。它只是把同样的问题抛给了调用者而已。而对调用者而言,我相信他们更希望拿到一个解之后才能真正确定这个解够不够好,他们也无法预知对所有定义域都合理的精度是什么。当然,他们可以简单地选择一个绝对足够好的精度,比如7位。但是这样做的后果就在是一些并不需要这么好的精度的情况下产生了额外的无用运算。

考虑到开平方运算是迭代进行的,一个思路就是把迭代过程中的每个值都返回给调用者,并在调用者需要下一个更好的解的时候才进行下一步的计算,直到调用者满意为至。

当一个思路产生之后,无论你脑子里是否能立马闪现出具体实现方案,一个好的习惯就是在先计算机领域看看,有没有合适的技术与理念可以用来实现这个思路的,并和你自己的方案进行比较、甄选。然后再着手实现。思路的寻找往往是最难也是最有价值的部分。如果你总是想到什么就做什么,可能所有问题倒是也都可以解决,但是在这个过程中很难会有思路上、水平上的提升。把一年的工作经验用十年,就是这个意思。

了解到计算机系统中可以用来实现上面所述思路的概念至少有:

  1. 流(Stream – a view of system structure):具有的延时求值特性。
  2. 按名调用(Call by name – an evaluation strategy)
  3. 协程(Coroutine – a language feature)

Stream会更适合实现我们所需要的功能。它不依赖于语言,而且应用广泛。LINQ, Reactive Extensions都是基于Stream View设计的。

参考《SICP》上的流实现,不难构建出如下的Stream类和用之实现的Stream化的Sqrt函数:

type Stream<'a>(empty:bool, head:'a, tail:unit -> Stream<'a>) = 
  new(head:'a, tail:unit -> Stream<'a>) = Stream(false, head, tail)
  member this.Head = match empty with 
                      | false -> head
                      | true -> invalidOp "An empty stream has no head."
  member this.Tail = tail()
  member this.IsEmpty = empty
  member this.iterate action = 
    if not empty then 
      action this.Head; this.Tail.iterate action
  member this.iterateWhen action condition = 
    if not empty then
      action this.Head;
      if condition this.Head then
        this.Tail.iterateWhen action condition
  static member Empty = 
    Stream<'a>(true, Unchecked.defaultof<'a>, 
               fun unit -> invalidOp "An empty stream has no tail.")
  static member Map func (s:Stream<'a>) = 
    if not s.IsEmpty then 
      Stream(func(s.Head), fun () -> Stream.Map func s.Tail)
    else
      Stream.Empty
  static member Infinit producer head = 
    let rec stream = 
      fun () -> Stream(head, fun () -> stream() |> Stream.Map producer)
    stream()

let sqrt_stream x =
  let inline avg_damping f = fun x -> average x (f x)
  let getNext = avg_damping (fun v -> x * 1.0 / v)
  Stream.Infinit getNext 1.0

代码7

在这个版本的开平方函数中,没有任何精度设定,也就没有实现上的精确度损失。但是限于我目前的F#水平,我相信这个Stream的实现并不简洁,欢迎大家给出改进建议。(这遍文章里的F#代码大概占我写过的全部F#的50%,选F#只是因为我觉得照搬书上的Scheme代码和用我熟悉的语言解决这么简单的问题都很无聊。)

符号求导

在上面的牛顿法一节中,我们为了求解函数的导数而引入了一个新的精度假设值并导致了一定的精度损失。其根本原因是我们其实根本没有求解出导函数,而是利用了计算机强大的运算能力直接计算出指定点的导数值而已。

如果我们能把导函数方程先求解出来,并用这个导函数计算导数,就不会再有那个精度误差了。也就是说。我们希望能把方程f(x)=ax^2+bx+c当参数,并求解出f(x)=2ax+b这个导函数。

高级编程语言基本都自带表达式解析库。F#也不例外。所以符号化求导实现起来也并不复杂,至少不用自己写词法分析器。你当然可以自己写一个彰显实力,只是不太好读的代码多了也就不好管理了。但是需要避免的状况是:你自己写的一个,仅仅是因为你不知道语言里自带了个库,或是不屑于用。这种情况很常见,比如一个例子是:

let abs a = if a > 0 then a else -a

你看不出来问题在哪?那说的就是你。

在F#中实现符号求导,我们只需要把所需要用的如下求导法则

  • \frac{dc}{dx}=0
  • \frac{dx}{dx}=1
  • \frac{d(u+v)}{dx}=\frac{du}{dx}+\frac{dv}{dx}
  • \frac{d(uv)}{dx}=u(\frac{dv}{dx})+v(\frac{du}{dx})

代码化成一组模式匹配:

let inline sum     e1 e2 = <@@ (%%e1: float) + (%%e2: float) @@>
let inline sub     e1 e2 = <@@ (%%e1: float) - (%%e2: float) @@>
let inline product e1 e2 = <@@ (%%e1: float) * (%%e2: float) @@>

let rec deriv (body:Expr) (p:Var) =
    match body with 
    | Var(x) ->
        if x = p then <@@ 1.0 @@> else <@@ 0.0 @@>
    | ValueWithName(x) ->
        <@@ 0.0 @@>
    | SpecificCall <@ (+) @> (_, _, [lArg;rArg]) ->
        sum (deriv lArg p) (deriv rArg p)
    | SpecificCall <@ (-) @> (_, _, [lArg;rArg]) ->
        sub (deriv lArg p) (deriv rArg p)
    | SpecificCall <@ (*) @> (_, _, [lArg;rArg]) -> 
        let pl = product lArg (deriv rArg p)
        let pr = product rArg (deriv lArg p)
        sum pl pr
    | _ -> invalidArg "body" ("Invalid body: " + body.ToString())

let derivE (exp:Expr) = 
    let (var, body) =
        match exp with 
        | Lambda(var, body) -> (var, body)
        | _ -> invalidArg "exp" ("Invalid exp: " + exp.ToString())
    let derivBody = deriv body var
    Expr.Lambda(var, derivBody)

let sqrt_v5 (y: float) = 
 let exp = <@ fun x -> x * x - y @>
 let f  = exp |>           EvaluateQuotation :?> ( float -> float )
 let Df = exp |> derivE |> EvaluateQuotation :?> ( float -> float )
 find_fix_point (fun x -> x - f x / Df x) 1.0

代码8

现实的项目中没有人会用符号求导技术来写个开平方函数。因为它比前面的版本要慢上1000倍。但是符号求导所带来的灵活性使得这个框架可以用来解决比开平方复杂得多的问题。

这个版本的代码没有使用流,如果需要,可以把它也实现成一个流。在软件工程领域,不同技术方案基本都可以合并而生成一个新的方式。而在非软件工程领域,这种合并常常会由于物理法则的约束而无法达成。这是软件工程复杂性的又一个体现。

综述

本文的主要意图是阐释,充实自身业务领域知识与计算机领域知识对于编写高质量代码的必要性,使用合适的方案解决一个问题能带来多方面的好处。这似乎是一句废话,但是其实这只是一个认识陷阱:人们,尤其是经验越丰富的人,一但认为自己理解了什么,或是利用起了他们的既往经验,他们就常常停止了探索,停止了学习,停止了思考。这对于软件开发是非常有害的。

但是另一方面,如上的发现问题、解决问题、发现新问题的循环是没有尽头的。具有钻研精神的程序员们总能在代码中发现问题并用各种方式尝试解决它,同时引入新的问题。专业的软件工程师能够根据最终目标和环境的不同知道应该往哪个方向走,并且到站了也知道停下来。在一个仅仅需要开平方的地方引入符号求导机制同样有害。

本文中的例子和解决问题的过程纯粹为阐释上述意图而刻意设定,请勿作编程指导,如果你能从中发现自己坠入的认识陷阱就再好不过了。

参考书目

Jerome H.Saltzer, M. Frans Kaashoek. Priciples of Computer System Design (《计算机系统设计原理》)

Harold Abelson, Gerald Jay Sussman, Julie Sussman. Structure and Interpretation of Computer Programs 2nd Edition (《计算机程序的构造和解释》)

Tomas Petricek, Jon Skeet. Real-world Functional Programming – With Examples in F# and C# (《C#与F#编程实践》)

Adrian Banner. The Calculus Lifesaver – All the tools you need to excel at Calculus (普林斯顿微积分读本)

Gerald M.Weinberg. The Psychology of Computer Programming (《程序开发心理学》)

谷强强 版权所有

《那人、那山、那狗》

之前看到片名的时候,以为和《篱笆、女人和狗》有什么亲缘关系,就一直没有看过。于是这部99年的好电影就这样被我错过了十多年。

这部影片所讲述的故事非常平凡,甚至平淡。就是邮递员老爸把工作交给儿子,陪儿子走最后一次邮路的过程。但是也正因为这种平凡而让人感觉真实而亲切,也正是因为这种平凡而更能体现出演员的实力。

然而情节和表演并不是本片最打动我的地方。平心而论这部电影的部分情节转承稍显突兀,刘烨的表演也有些生涩。论艺术品质算不得上乘。但是在这父子感情这件主线背后,还有关于对人生、社会、责任的思考。面上是在讲述这个发生在深山里的小故事,却影射着外面大社会的一些变化和冲突。

我不想赘述拙见,毕竟仁者见仁,智者见智。只是好电影值得更多人去品鉴。

咽炎

本来自己一直也没感觉嗓子有什么不舒服,但是自从上周六体检的时候医生跟我说有慢性咽炎开始,就觉得嗓子的确不舒服了。不疼不痒,就是毛毛的,想咳又没什么东西好咳的感觉。忘了从哪年开始,好像每年都这样,有时严重些,会咳个几个月才会好转。不过用屁股分析一下也能知道这大概是从我大中国冬天的大面积烧煤供暧开始的。虽然我一点热乎气儿都没沾着,这烟霾倒是没少吸。人们把由于工作需要而沾染的疾病叫职业病,不知道咽炎算不算得雾都生活病。我想,大概这就是生活在这样一片蒸蒸日上的沃土上所需要付出的代价。可谁都不想拿健康当代价,所以有了病,无论责任在谁,去医院看病的都得是本人。

上海的三甲医院不少,可也架不住全上海人得个头痛脑热的都去三甲医院看。所以本着不给三甲医院添乱,不让小医院的医生闲得蛋痛,也不纵容自己以排队为由无所事事地看一两个小时手机的原则,我还是去了某医院。我已经去过几次了,也看得出来这医院又贵又没水平,但是我相信看个咽炎应该还是足够了的。

早晨送了老婆到公司,花十分钟绕过罗山高架过来就是这家医院。把车在楼门口停下,拿着医保病例本就进去了。门口问询台没人,我就径直走向了总服务台。

“请问是在这儿挂号吗?”

“你什么不舒服?”

“我嗓子疼。”

“前边左转上二楼找护士。”

“哦,好。”

我正要转身,看见她瞥见了我手上的社保病例本,叫住我说:

“哎,我们这儿社保卡不好刷的,只能用现金或是刷卡,挂号费480。”

“哦,我知道的,中间带的卡可以用吧?”

“保险卡是吧?你上楼问护士吧。”

看来她也不知道。我就按她说的上了楼。记得我上次来的时候还是有人带我去的二楼护士台,现在连门口司仪都省掉了。不知道是不是入不敷出了。

到了护士台,有个看着像是医生的人走过来问我。

“你是什么不好啊?”

“啊,我就是嗓子痛。”

“啊,感冒了吧。”

她转过去又跟护士台的人说。

“我跟你们说过的吧?咱们人可以匀一匀。”

她又转过来打量了我一番,说。

“穿太少啦,感冒了应该多穿一些的。”

“啊,我就是咽炎,应该没有感冒。”

护士问我之前来过没有,又问了出生年月。然后问医生挂哪个科。我始终没说什么话,之前去公立医院看感冒也有把我安排在耳鼻喉科的。人比呼吸科少很多,医生看起来也更有耐心一些。

“就挂王主任的吧。”

“呼吸科好像也没有人啊。”

“不是吧,刚才不是来了一个吗?这个就挂王主任吧。”

然后护士就拿出来了个单子让我签字。

“我来带他过去吧。”

我签好了单子,她跟护士们说。

我就跟着她走了十几步来到一间诊室坐了下来。

然后她笑着跟我说,“这是我们从瑞金医院请来的专家,一个星期才来一次呢。”好像这是莫大的荣幸。

我没说什么,她就走了。

这个老大夫梳了个大背头,看上去很体面。

我说嗓子发毛,他就拿出舌板和手电叫我张嘴,看了一下说。

“是咽炎,扁桃体也有些肿。”

“扁桃体也发炎了?”

“有些红肿,你有扁桃体的是吧?”

“咽炎是急性的还是慢性的?上次体检的时候,他们说我是慢性的。”

“这次是急性的,我给你开些药……”

我有些诧异他这么快就要给我开药。于是问他。

“但是扁桃体发炎不是应该发烧的吗?可我不发烧啊。”

“有些人是不发烧的。”

“那是发烧好还是不发烧好呢?”

“这个看个人体质的。这个细菌和你的人体啊,就像两边对抗。比如如果你白血球高,但是不发烧,说明你体质好的。那,如果白血球不高,也不发烧,也可能说明你免疫系统太弱了。”

他看我好像意犹未尽,便说:

“我给你开个单子看下血项吧。”

然后递给我一个单子,指着旁边的房间说:

“就在隔壁。”

我前面就两个人,我就在门口等着,等的时候我看见我出来的诊室的门口的牌子上写的是“内分泌科”,这还是比较出乎我意料的。看来这个科真是人太少了,都开始出来拉客了。想想别的医院所有的科都人满为患的时候,这边儿一个主任医师在里头无所事事地坐一天。

没想几分钟就到我了,到我的时候换了个老一些的护士,我还挺庆幸。

我坐下,把单子放在桌子上,拉了一下衣袖没有拉上去,正准备把毛衣脱掉。护士说话了。

“要不扎手背吧。”

“手背好扎吗?”

“你这拉不上去我也没有什么办法啦。”

“那就扎手背吧。”

我觉得她有信心那就好。反而扎什么地方我是无所谓的。

她扎的时候我一直看着,刚扎进去的时候我就觉得没有扎正。果然她顿了一下。

“哎呀,血管滑掉了。”

我想着之前抽血没扎好之后的一大片淤青,心里就一群草泥马奔腾。

看着她挪动着针头,一阵阵疼痛从手背传来,我还得保持手一动不动,以防针头在里头把血管撕开个口子。

她调整了一会儿,血才慢慢地流了出来,接上真空试管血出的速度还是很慢。看来扎得真是很不好。本来只要几秒的采血,用了二十几秒才采到一小管底的量。

“血管太细了,又滑。”她解释到。

“应该够了吧。”她自己嘀咕着。然后把针头抽了出来。

“按压两分钟。”

她把一团棉花按在我手背上说。

“血管又细,还滑了,可能有些疼啊。”

“嗯。”

我使劲按着手背,找到个沙发上坐着等结果,想她说的是“滑”还是“划”。

旁边也有一个人在等结果,他旁边有一个女医生在等他讲一些手术上的事情,我没刻意去听,只是听见她在说在这里也可以做,就是费用会贵一些,医保卡也可以用什么的。恍惚间我有一种看见安利的感觉。

等了没十分钟,那个老医生就跑过来叫我。

看了一下血项没有任何有意义的异常。他就接着给我开药。

“我给你多开几种药,有喷的,有冲的,还有消炎的。”

他们医生一说消炎我就就敏感,我瞥了一眼屏幕,看见有头孢二字,我就问

“没有细菌感染也要吃抗生素吗?”

“你的扁桃体有些发炎,而且细菌感染也不一定血项高的。所以还是吃一些的好。”

我没有说什么。

“你看着感觉好了就可以了。慢性的药我也给你开了一些,那些可以接着吃。你听懂我的意思了吗?”

“嗯。”

我想反正我也是看得懂说明书的。

致谢之后我就下楼取药了,看着满满一包计四种共十二盒的各式中西药,我觉得真吃完没病也得吃出点什么病来。仔细看了一下药名,其中有一个是盐酸头孢他美酯,是三代头孢广谱抗生素。我觉得还是不要吃的好。

出门的时候嗓子毛毛的。

手背上还不时还会传来一阵阵的疼痛。

理头

家门口有家小理发店,开了大概有一年多了。已经去理过大概有七、八次了吧。但是我依然没有搞清楚他们家早晨是几点开门。

那天早晨起来没什么别的事儿做,九点就去了,门还没有开。压了半个小时的马路回来,远远地看见门口黑白两色的转柱还是没有什么动静,心里就有些不安,心想这么晚还没开门,不会是歇业了吧。走近一看,门倒的确是开了,只是三个伙计都还在准备,要么低着头打理自己的头发,要么低着头在扫地。我使劲把门拉开,想着弄出点什么声音好引起他们的注意,但是声音没有盖过他们手里的吹风机。我走进去站着,看着其中一个吹着头的伙计。

他抬起了头看着我,脸上有些莫名其妙的表情,像是不太理解我为什么会出现在这里。我想或许是太早了。

我伸出剪刀手朝着自己的脑袋比划着说:“剪头。”

他才恍然大悟一样,跟我说:“先坐会儿吧。”

于是我就找了离我最近的椅子坐了下来看手机,他继续吹他的头。

“先洗个头吧。”过了几分钟,他打理完了自己的头,朝我说。

我把手机揣到裤子兜里朝里面的洗头台走去。里面有两个洗头用的躺椅,我正在考虑应该用哪个的时候,他伸手指着其中一个。我走过去,偏着头往椅子上扫了一遍,确认椅子上没有水珠什么的才坐了上去。洗头很快,冲水,打洗发水,揉一遍,再冲,擦,吹干。前后两分钟的事儿。不推销充值卡,也没有家长里短的客套铺垫。虽然洗的时间短了些,但是是全然属于自己的,能安静地享受。

“怎么剪?”,洗完坐定之后,理发的小伙照例问到。

新人来理就是这点很麻烦,你要跟他解释清楚到底要剪成什么样。

“毛寸儿,周围都剃上去 ,上面稍微短一点儿。”

“都剪短是吧?”

这不像是真的在问我,而只是确认一下,于是我没有再说什么,况且我觉得我已经说得很清楚了。而且毛寸这种发型,哪怕你什么都不说,光是看现在的样子,也大概能知道一个月前每个部分是多长。问一下更多的是确认这次是不是要换个新的发型。

他也没什么迟疑地上手开剪了。我想他是明白的。

他把围布给我围上的时候,一股汗臭扑面而来。

“你们这个该洗了吧?”

“什么东西?”

“这个。”我的手被盖在围布下面,于是就把整个围布撑了起来。

“这个洗不掉的,做头发的时候滴上去的。”

他说的应该是围布上被染发液染上的颜色。

“我是说汗臭味。”

“我们有洗的,一个星期洗一次,只是那些块是洗不掉的。”

“我没有说那些块,我说的是汗臭味!”

他没有再说什么,大概是觉得自己已经回答了我的问题,没有必要再多说什么。我也不想坐着说话不腰疼地问他为什么不是每天洗?也不想让他再换一块,因为下一块说不定会更糟。我只是在考虑以后是不是应该找个好一些的地方。但是我这种近似于光头的毛寸,好像不至于这么矫情。而且如果谁都不在这种小店理了的话,想必是会倒掉的,家门口的水果店、饭店、咖啡店、理发店一家接一家地换也不是什么好事儿。好在不是所有人都像我这么矫情。我就这么没什么边际地想着,他手上活也一直没有停下来。

整个过程中,一句话都没有再讲。我挺喜欢这样的,理头时候说的那些话大都是不疼不痒的,而且还有吃进自己头发的风险。只是后来他一剪子把头上的一块剪去三分之二的时候我就知道他根本没有理解我说的发型是什么。但是我依然没有说话,我总不能让他把剩下的部分留长些。那这块就变成了一个坑。一个地方按一个型剪短了,剩下的自然也得照着剪下去。

他收了推子、剪刀,又用吹风机把头发渣滓吹干净了。我都以为他要让我起来去洗头了,他拿了面脑袋大小的镜子过来放在我后面问我怎么样。

我看着镜子里的圆圆的头型问:“你还记着一开始,我是怎么说的吗?”

他没说话。

“我说‘毛寸儿,边儿上都剃上去,上面稍微短一点儿。’,我想知道在你们的语言里”——我是北方上,理发的小伙是南方人——“‘稍微’是个什么意思?”

他对我怎么说的没有表示异议,但是对于结果有。

“这就是稍微短了一点儿啊。剪掉了大概三分之二,哦,不,三分之一。”

“ 是,三分之二。我理解的‘稍微短一点儿’应该是这样的。”

我把手从围布里面伸出来,比划出一指长的长度。一指比我原来的头发长些,是为了确保他能看清距离上的变化。然后把这个长度缩短了一骨节的距离。我是看我的手说的。所以我并不知道他是不是也在看我的手。

“看来我下次是不是应该找张纸把我想要的发型画下来才能讲清楚?”

“那不用的,你原来的头发没有那么长的。我就是剪掉了三分之一的。而且你上面留太长了的话是会翘起来的。”

他说的没有错,我头发硬,起来之后也没有洗过头,所以来的时候的确是翘翘着的。我也没再说什么,理头不像买东西,不满意可以换。我现在就算想换也得等上一个月才行。我只能先去洗头。

洗头的时候小伙还在跟我继续解释。

“毛寸儿其实都是这样的。”

“看来我下次得换个词儿了,不能说毛寸儿。”

“你周围剃短了,上面也得短一点才好看,要不然头发就不齐。”

我心想,不觉得宫城良田的发型难看,更不觉得赤木刚宪的发型比他的看好。

“我想要的,是我觉得看的发型,不是你觉得好看发型,你明白我的意思吗?”

“明白。”

“你觉得什么样的发型好看,我不关心。”

洗完头,照例帮我擦干。

“吹一下吧。”

“不用了。”

“还是二十块钱是吧?”

“是的,支付宝是吧?支付宝扫这面。谢谢你啊。”

我走出去的时候,都没有说再见。

再读《一九八四》

上一次读《一九八四》大概是两年多以年,读了半本就感觉难以读下去了。听过了老一辈人讲文革,讲上山下乡,了解过那段疯狂的历史,再来看这种想象出来的专权统治下的生活状态就感觉一点儿味道也没有。唯一的新鲜东西就是那个连周围人的心跳都可以监测到的“电屏”,却又因为这种比其它东西超前太多而感觉格格不入。于是中途放弃了。

然而看书看一半这种事儿,一但想起来,就像撒尿撒一半一样让人十分不爽。这个十一没有回家,也没有别的事情,就自己一个人在家,于是就又把这本捡了起来。我看书一般比较慢,这次花了一个晚上和一个上午完了就已经是快的了,快是因为我这次的确被吸引和震慑到了。

这本书,不是一个寓言,也不是科幻,也不是政治。它是启示录,给人以一种令人窒息的绝望感的启示录。这绝望,不是指那无时无刻无处不在的监控,监控可以避开;也不是每况日下的生活环境,恶劣的环境还可以忍耐。那绝望,来自面对人性的泯灭和精神的摧残时的无力感;那绝望,就像是被一群没有思想、没有情感的丧尸所包围的感觉。就像书里所阐释的那样(括号里是我加的潜台词):

党所做的最坏之事,是说服人们仅靠(自己的)冲动或感情解决不了任何问题(所以你什么事儿都要依赖党),而同时让你在现实世界上变得彻底软弱无力(因为你自己一个人什么都不是)。

一开始,他以自己仅能做的方式——写日记——抗争着,并寻求着莫须有的兄弟会的同盟,却又不得不提防着身体所有的人,从一个个眼神、细小的动作甚至说话的方式上来分辨周围的人。他找到了奥布兰,因为奥布兰的肢体动作给他以一种安全感,奥布兰也找上了他,他也好像找到了组织,第一次会面就坦白了。然而现实轻易地将他的希望击碎了,他的判断全是错的。他觉得正统的,不正统的,都被抓进了仁爱部,或者是直接蒸发掉了。他时常造访的杂货店掌柜却是他时刻提防的思想警察。他自己还什么事儿都没有为组织做,就被抓进了仁爱部。事实上,他是掉入了别人的圈套,一个精心策划的陷阱,在他内心最有希望的时刻,把他打入无间地狱。更糟糕的是,哪怕身陷囹圄,他依然无法确认对方是敌是友,他没有头脑,没有思想,没有判断的基准。他只有接受,按照对方想要的那种方式去接受。他放弃了二加二等于四的自由,还发自内心地认为二加二等于五。他没有死,他被净化了,他感觉“像是走在阳光下。但是原来的那个他,便同时被看守射杀了。他所有曾经有过的真实的快乐的童年回忆,都变成了“虚假的记忆”。而他的爱人,朱莉娅,原本一个活泼、机警看透了党的无聊手段的软妹子,从仁爱部出来也变得如同死尸般僵硬。

因为从精神层面上,他们都被摧毁了。

“他们进入不了你的内心。”她曾经说过,然而他们能够进入你的内心。“在这里发生在你身上的事将永远抹不掉。”奥布兰曾经说过,那是实话。你无法恢复某些事情,还有自己的行为,你内心的某些东西被损毁、焚烧并且被烙上了别的东西。

这是一悲剧。温斯顿曾经试图寻找过解决的办法,所谓的兄弟会给他了他“那本书”其实并没有讲任何他所不知道的东西。只是把老大哥的革命理念从现实的角度解释了一遍。然而所讲述的本质内容却是:社会就是这个样子的,人是分三六九等的,这是无法改变的。就像奥布兰所说:

群众永远不会造反,再过成千上万年也不会,他们没能力。

为什么没能力?温斯顿也知道:

他们从未学会思考,……   P182

“那本书”里也解释道:

完全不用害怕群众,由其放任自流,他们就会一代接一代、一个世纪接一个世纪地工作、生养、死去。他们不仅没有造反的冲动,而且不会明白世界可以变成另外一个样子……对他们(指处于战区的人)来说,哪一方取得胜利完全无所谓,他们明白统治者变化无非意味着他们仍然要继续干同样的活,因为新主人会跟旧主人以同样的方式对待他们。

这不仅仅是剧中人的悲剧,也是作者无奈的控诉。他在他的杂文中《我为何写作》中提到:

一九三六年以来,我所写的每一行严肃作品都是直接或间接反对极权主义,支持我所理解的民主社会主义。

这不是一本挑战想象力的小说,它在引导人们观察与思考这个社会,以防跳入掩盖在鲜花与掌声中的陷阱。他不是哲学家,也不是政治家,在他书中通过反讽等手法提出的关于社会制度和阶级的见解势必是浅薄甚至幼稚的。但是这并不妨碍它引导的作用。 也并不妨碍读者去作出自己的判断。它不告诉你答案,它也不应该告诉你答案,因为答案要靠你自己去探求。就像书里说的:

为什么一定需要一些年代久远的记忆,让人记着以前并非如此时,才会觉得这些是不可忍受的?

有些事儿,本是是非自明,无需佐引,无需类比,无需判例。但是前提是,你得有颗通事明理的心。

这本书细细读来着实发人深醒。4星推荐。

 

《挪威的森林》

高一的时候就听的过这本书,听说有些黄,于是也就没有好意思从学校的图书馆里借出来过,一则我当时的脑子根本不走这经,去图书馆借来的小说之类大都是原样的还了回去,翻都没有翻过,二则省得被老师叫去叮嘱一翻,毕竟在那时,学业才是头等大事,所有其它的可能会影响学习的,都会被老师当成潜在的威胁加以约束。三则同等的书实在太多,都想去看,却又不知道哪本适合自己看,于是就一本也不看。

十几年间试着读过几回,但是基本都没有读完一章过。这几天赋闲在家,手头上又没有其它的书好读,于是又捡起来读,这一读便不可收拾,一气读完。现在想来,之后没有读下去,大体是因为没有读懂;而现在读出点眉目自然就了读下去的兴致。早些年好读些修仙小说,现在读来却味同嚼蜡。这样说起来的,我的阅读品味比我同学们落后了十多年,他们在十七、八岁的年纪读着十七、八岁的爱情故事,而我到了三十岁才读得来。这个想法直到我卒读全书都耿耿于怀,懊恼没有早点硬着头皮把书看完,因为这真的是一本好书。

这本书大概算是青春爱情小说,不过看完我更觉得这是本讲人生的小说。小说中的每个主人公都有自己十分独特的对于人生和对于爱情的看法。只是渡边自己直到最后才对自己的爱情明了起来。其他人的结局都很直接,要么自杀,要么找到了自己的人生、爱情的目的并走了下去。这好像是在对几种不同的人生观、爱情观做一个比较。有的长久,有的自我毁灭。渡边作为一个普通人,放进人堆里都找不出来的那种,其实一开并没有十分明确的人生观,被敢死队引导着爱干净,被木月引导着接触女孩,自己甘做一根链条,大学的朋友永泽也是被动地被找上门,被引导着去解决自己的生理问题。他自然也有着自己的独特的思想,但是与其它人相比,他就像一张白纸一样。所有人都会喜欢白纸,坦诚的白纸。没有一丝别人的痕迹。所以渡边也是一直夹在缝隙间游走,直到直子死去,玲子给他做了心理疏导,他才缓过来,开始属于自己的人生和爱情。所以有人说这是一部讲述渡边的成长的小说,这也不错,只是这不是重点。重点是人与人之间的关系的多样,和每个个体的取舍。有的人无法取舍,就走向了灭亡。人生是有选择的,而且是有很多的选择的,找到自己的本心和位置,而不去纠结于旁人的理解。十七、八岁乃至二十三、四的楞头青,一如当年的我,思想单纯而没有目标,只知道傻傻地对自己脑子里臆想出来的东西信誓旦旦 ,却不见眼前的其它的路。

书有好坏,不以内容论。好的书,给你打开好几道门;坏的书,一叶蔽目。

三十而立

孔子有言,三十而立。我出生之后,地球绕着太阳转了三十圈,我便算是三十岁了,可是如何衡量“立”呢?这里的立和“成家立业”、“安身立命”中的立并不是一个意思,因为孔子又说自己四十不惑。当一个人还迷茫着的时候,业是无所立的。

《论语 泰伯》中说,“不知礼,无以立也。”。所以孔子所说的立,是知礼明义、能辨是非,三观确立的意思。这事儿听上去并不难,谁不辨是非了?谁又没个三观呢?你去问任何任何一个十八岁以上的人,你有三观吗?你有是非观吗?八成人会觉得这是个侮辱性问题,心情不好的还可能把你揍一顿。你也可以问些隔靴搔痒的具体问题,人们都可以说得头头是道。毕竟我们这代人从小耳濡目染的政治正确性和满世界的心灵鸡汤文不是白灌的。但是如果你去看看百度社会新闻,你却会觉得这个社会上奇葩怎么还是这么多。好像人们都已经习惯了说一套做一套,说得只是让别人舒心,做得只让自己舒心。而且这部分人并不占少数。搞到现在,“政治正确”俨然成了“现实不可行”和“空口说白话”的代名词。这些人,能说是知礼明义吗?但是如果你去质问他们行为,他会觉得你才是傻逼,甚至可能又把你揍一顿。为了避免出现刑事案件,大家还是处于一种:“互相尊重、互不干涉、和平共处、相互视为二逼”的状态安全一些。

有些人就这样心口不一地过一辈子,一辈子也没立得起来。至于他这辈子这样过得好不好,开不开心,只有他自己知道,别人没有资格评判。只是大凡年过半百之人,即使意识到自己之前的做法不好,也多半不会再改变自己的做法,而是竭尽其所能地让自己的做法合理化。改变本身也许不难,难的是解开心结,改变即是否定自己的过去的大半辈子。这也是为什么人越老就越顽固,越因循传统。因为没有人愿意否定自己的过去。所以三四十当立,三四十不立,就很难再立起来了。

但是立没立,这事儿不是别人说的,是看自己,毕竟明事理、确三观这种事本就是个人的事儿。无需了解孔子的立是什么意思,每个人都可以有自己的理解。不过我倒是觉得从几个方面,大概可以看出一个人还没有立。

  • 感到迷茫,没有方向
  • 人云亦云,没有主见
  • 消极厌世,没有热情

关于最后一条,并不是说不能厌世,一个人完全可以去过遗世独立、闲云野鹤的生活,那也是一种热情,一个没有丝毫热情的人,是连自己都会放弃掉的。如果一个人三者皆无,那绝无可能说这个人立了。

然而在现实中,刚毕业的学生容易迷茫;自己知识不足的很难产生主见;在公司上班领工资的容易失去热情。于是乎,其实所有人都可以堕入这个深渊。而当这个社会产生了这样的环境的时候,在这个社会中生活,你看到的所有的一切都不如人意。

  • 我们的垃圾分类推行数年毫无进展,因为民众普遍没有这方面的知识和热情。
  • 我们的老人倒了没有人敢扶,因为很多人被那些没有立的人坑怕了。
  • 我们饭店的食品质量普遍不好,因为从业人员多只是当成个营生,而不是事业去做。他们没有尽力做到最好的动力。
  • 我们的年轻人最喜欢比较哪个公司好,哪个工资高,学什么又轻松又有前途。因为他们普遍没有找到自己的方向、自己的兴趣,基本对这个世界一无所知,更无法对这个世界产生自己的主见。
  • 我们几乎所有的市民可以参与的市政公开讨论决议,都最终流于形式,比如环评。因为种种原因。
  • 我们的公司里,每一个新加的规定,每一个新封的网站,都是那些占便宜、钻空子的人留下的丰功伟绩。所以我们的报销越来越难,可以访问的网站越来越少。这群害群之马倒也立了三观:唯个人利益是从。这没什么不对,个人利益放什么位置个人说了算。但是他们只是社会常识的储备都不够,为了一两次的眼前的好处,损害的所有人,包括自己的长期利益。然后他们还会抱怨公司,而从不问自己的做法是不是合适。简直就是“猪队友”。(有多少公司因为受不了小部分员工把内部免费的东西随意拿取而最终取消这些福利的?我数都数不过来。)

有时我们明知道自己知道什么是对的,什么的是错的,自己也认同,却依然做不到。因为多数时候,不去这样做,反而对自己当下的生活会有更大的好处。只是这样的最终结果会是,生活在一起的所有人,最终,都无法从中得到他们本可以得到的更大的好处。

在有些国家,“立”的人占多数,于是人们之间,至少在表面上,是友善的;对于生活,至少貌似是有热情的。人有爱心有热情了,才能更好地创造东西。比如我们知道日本没有假货,质量也好,有人从尿布到电饭锅都从日本海淘,倒不说别的国家的东西一定会比中国的好,但是至少不会被坑,一分钱一分货。在国内或许的确有同等品质的产品,甚至可能还更便宜。但是他们都已经淹没在一片假货的海洋中。大概没很多人会愿意花一天时间多方求证只是为了确认一件产品的品质和商家声称的一样。去外国海淘既省时又放心。而在国内真心做良心产品的企业,在这种环境下根本支撑不下去。于是也转而降低品质。劣币驱逐良币的现象,就这样产生了。在这样的环境下,每天的生活中就要天天提心吊胆地,在外面吃饭会怕垃肚子,在淘宝买个东西会是假货或是质量差。甚至与陌生人打交道,都会默认对方是坏人,是有所企图才找上门来,要么是推销东西的,要么是劫钱劫色。于是生活于其中就非常累,人累了就这容易失去热情,失去了热情这人也就废了,然后就变成了一个恶性循环。更糟糕的是,在这种环境下生活久了,人们甚至会觉得这就是生活的常态,甚至都不想去改变,只想着去适应这个环境。那就真是没得救了。

国家之前大力扩大教育,无论结果如何,绝对是正确的方向,只有当人们都明事理了,这个社会才会变得更好。之前我说过,我是反感并支持着国家建立GFW的,原因也是类似的,在人们明事理之前,人们普遍对互联网上的信息没有良好的分辨能力,听风就是雨。听见日本核电站事故,超市里的盐就没有了;听见长江飘着死猪,就半个月不吃猪肉,还把超市的水买光了。这都绝对不是什么好事儿。人们常常抱怨政府封锁消息,这的确是政府的不对,但是如果民众总是毫无头脑地解读这些消息,甚至造成更大的灾难,这些消息还是封锁起来的好。当然政府更好的做法是,不封锁消息,但是在发布消息的时候同时公布所有的相关信息、解释、建议等。避免民众恐慌。但是且不论政府有没有这个水平,即使政府都做到位了,就能避免民众那些不理智行为了吗?民众会听政府的解释吗?有人会想,政府做的对不对是政府的事儿,民众听不听、信不信是民众的事儿,政府不能假设民众都是傻子。但是请想想,如果政府真这么做了,那么就不是真正的民主政府。好了,不说了,这种讨论是没有头的。我只想说,如果投票要不要废除GFW,如果我在国内,我是会从我的个人利益出发,投赞同票,因为我要访问所有的网络。但是政府立法决定我们要有GFW,我也表示理解和支持。至于这么做对不对,好不好,我不在其位,不操闲心,不作评论。如是而已。

一言蔽之,希望我们早日过上没有贫困,没有GFW,没有假货的生活。敲键盘、烂笔头没有用。当每一个人都热爱生活,享受自己的人生的时候,那日才会到来。我尽力过好我的生活,也希望每个人都好。

我是Hugo,程序员。喜欢编程,喜欢思考。其间总有一些东西想要记下来,于是就有了这个博客。这并不是我的第一个博客网站,但是是第一个属于我的独立网站,而这是第一篇,我想应该先说下我自己。

我喜欢追根问底,从不轻信听到的任何信息,无论其来源多么权威,更喜欢挑战权威。喜欢思考各种问题,从技术到人生到社会。

我猎奇心重,对世界上各种事儿都有兴趣,小到看书、做饭、喝咖啡;大到天体物理学。

我容易感动,是个听音乐看电影都会哭的人;但是心肠却并不软,不会给乞讨之人一分钱。可怜之人自有可恨之处。

我认为人生的意义在于经历与体验,于是十分在意自己的感受,对影响自己的感受的人和事儿会很反感。

我认为幸福的来源在自身。幸福不是能被他人给予的。一个人必须能用心地生活,感受生活,才能得到真正的幸福。但是这个想法并不妨碍我在物质上的追求,因为那也是一种体验。

我理解力强,并对没相应的理解力与逻辑思考能力的人缺乏耐心。

我是个精英主义者,认为社会需要精英的管理才能得到最佳的发展,有些人就是得被人管。但是我并不是一个功利主义者,所以即使社会不是由精英管理我也无所谓。对社会的各个阶层没有偏见或歧视,但是对某些让我产生不适的生物个体会有反感。

我对肤浅地针砭时事的社论没有兴趣。用我的一个想法来说明一下:我反感局域网带来的不便,但是我支持当局对局域网的建设和对不良信息的监管和封锁。懂的人自然懂。

我会固执地做我自己觉得正确的选择,哪怕这事儿其实我已经看透,并知道我做的事儿对全局一点意义都没有也照做无误。做我自己,追求本心,是对我自己有意义的事儿。

我不会囷于任何无谓的风俗习惯,也不在意思旁人惊诧的目光。因为我的生活是我自己的,只要没有妨碍到他人,他们的惊诧与误解与我无关。

我喜怒形于色,虽然不很明显,不熟悉的人一般看不出来。

我对人一般很友好,但是对自己看不惯的人会有干架的冲动。可惜从来没有实施过。

我做事儿会考虑时间价值。因为我觉得一生很短。反感一切浪费时间的事儿,如有可能,就花钱买时间。但是我会玩游戏,会发呆,这并不矛盾。

我喜欢Jazz,也喜欢许嵩的中国风。但是不追星。

我喜欢看书,范围广泛,从《一只特立独行的猪》到《少有人走的路》,从《斗破苍穹》到《道德情操论》,从《梦里花落知多少》到《黄金时代》。

我喜欢收藏,从钢笔到邮票到书到硬币到各类票据。

我喜欢看漫画,三大日漫都在追。

我喜欢小雨天,喜欢听雨声,喜欢开着窗户睡觉。

我喜欢各种小动物。

我喜欢书法。

我不抽烟,但是抽过烟。

我喜欢玩RPG游戏,走刺客流。也喜欢玩Minecraft,但是创造力并不怎么样。只是用来消磨时间而已。我不喜欢对战类游戏,因为我手比较残。

我胆小,恐怖游戏都不敢玩。但是现实中,我并不怕黑,也并不怕鬼,也并不怕死。我怕死得无谓。

我不挑食,独不爱吃苦瓜,但是有时依然会买来吃,因为如我所说,人生的意义在于经历与体验。我不会因为自己的好恶而放弃。

我喜欢做饭,而且手艺不错,但是只在心情好有时间的时候才自己做,因为有太多更喜欢、更重要的事儿要做。我不喜欢为了省钱自己做饭。

我记不住人名,连楼上楼下对门邻居的名字都记不住,更不要问我漫画、电影、演员之流的人名了。

我就事儿论事儿。比如对代码苛求完美,但是对发型,一直是板寸。那么我是个完美主义者吗?

我喜欢旅游,但是对于在国内旅游没有太大兴趣,以国内的服务品质,被服务就是被虐。这无关服务场所档次。整体而言,服务人员的素质没有到,也没有用心服务的心。

我这人不恋家,这里所说的家是指父母家。我已经有自己的家了,我只恋自己的家。

我做事儿专注,做自己喜欢的事儿,比如写代码,可以从早写到晚。

我不喜欢枯燥无味的工作。

我基本没有迟到过。

下面是一些个人观念上的事儿,可以用来判断我们是不是一类人。不是一类人一般会相互嘲讽,但是你们放心,我从来不放在心上。

我铭记着历史,但是我依然喜欢日本。

我相信中医有可取之处,但是认为当代中医已经没落。像这个世界上多人都是庸人一样,认为多数医生都是庸医,所以不会严格地遵医嘱。

我还坚信有外星人。

我支持转基因,即使有证据证明有些转基因产品有害。

我不介意居住地附近的信号塔。

我从不随地吐痰。并厌恶在哪怕里小便池吐痰的人。

我吃不完或是不爱吃就会剩饭。

我是INTJ型的人格。