俄罗斯方块:win32api开发

俄罗斯方块:win32api开发

本文简述一门课程,演示win32api开发俄罗斯方块的开发过程。假设学生学习过C

语言,没学过或者学习C++不好,刚刚开始学习 win32api程序设计,还不懂消息循

环和注册窗口类。

1. 背景和原则

我这学期讲一门课,本科三年级,学生满员17人。一般接近满员,最低一次5人,

那天据林同学说,其他的同学都去看足球赛了。

课程名字叫做算法与程序设计实践3。第一堂课我照例要解释:到了"3"这个阶段,

就不讲算法了,只有实践。不过,后来看看算法也还是有一点应 用,比如从一个

线性表里删除符合条件的元素们,在线性表里查找符合条件的元素,这种难度的。

课是在机房上的,大部分时间学生和教师都看着显示,所以一学期下来,好多同学

和我见面可能都不太认识。不过我们对代码的形成过程更熟悉一些。

我试图贯彻下述原则:学生应该看到教师编程的过程,而不仅仅是结果;学生应该

看到在编辑器和编译器中的代码,而不是WORD或PPT里的;学 生应该先学会临模教

师的编程过程,而没有能力直接临模结果;学生甚至应该看到教师的错误及错误的

解决过程、教师的无知及检索过程,学生不应该 看到事先排练的完美的编程过程

和全知全能的教师,那样的过程和专家,学生模仿时无从下手。

所以,我课前不准备,在课堂上无意犯各种错误--偶尔演示学生们容易犯的错误--

及解决。在LOG文件中记录我们的计划和当前的进度,在画图 里画下原型。

所以,我假装对某些API和函数不熟悉,演示在MSDN和互联网中查找手册和解决方

案的步骤。单独做一些技术原型验证对API的调用结果的猜 想,而不是在工程的过

程中在项目代码中测试技术。有时,我知道问题在哪里,但是要先列出各种可能,

然后一一验证猜想(而不是直接解决,这似乎 是计算机本科生非常容易犯的错误,

如果解决了就认定那是问题的原因)。除了这两点,其余的时间我应该尽可能诚实。

有时候,学生会告诉我哪里错了,先于我发现问题的原因。这令我享受这样的教学

过程。

最终,我们--以我编码为主--实现了WIN32API开发的俄罗斯方块。

选择俄罗斯方块的原因,是因为小游戏的业务逻辑足够复杂,保证学生了解在相对

复杂的业务逻辑时的面临的问题和编程行为与toy作品不同;所使 用的到技术较

少,避免过多的机制 (数据库、网络等)分散学生的注意力,保证学生把精力集中

在对业务逻辑上。

选择win32api是课堂上投票的结果。选择C语言而没有使用C++有两个原因。一是学

生的C++掌握通常并不熟练;二是我希望学生能在项 目中发现面向对象的必要性和

优点,而不是仅因为学习过哪些语言而在工程中选用;三是希望演示用C也可以实

现基于对象的程序设计 (不是面向对象,不包括继承,仅包括方法与数据的内聚)。

2. 技术原型

涉及到的技术原型,要在工程开始前建立小项目,以验证对这些技术的掌握和对效

果的猜想。

要实验的技术列表,来源于需求。我们先不写代码,口头描述需求,然后分解需求

到所需的技术。这样就形成了技术列表。这个过程中,同时也形成了 定义,包括

名词和动词表。

这些技术原型也限定了除C语言以外需要掌握的技术,在这次开发当中。

技术原型包括:

* 使用GDI画图、擦除。用于画小块和移动小块。移动是根据视觉暂留在新的位置

上画图,并把旧位置上的小块以底色重画。

* 键盘消息响应。用于在不暂停小块下落的情况下接受玩家通过按键操纵小块左

移、右移、旋转、快速下落。

* 特定范围的随机数生成。用于在创建新的小块时,决定是哪个类型。类型计有S

型、L型、凸形、田形,及它们的旋转。

* 计时器 (timer),用于驱动小块定时下落,判断是否该清除一行,计分,刷新工

作区 (重画) 等。

* 在工作区输出文字。用于调试和显示分数。

最终形成的原型部分代码量如下。代码在附件中的 prototype目录下

画图 (及消息循环) ,draw,226行

擦除,eraser,263行

在工作区输出文字,textout,201行

按键消息响应,key,207行

随机数,random, 31行

计时器,timer,214行

3. 开发过程的里程碑

技术原型确定以后,再重新回到需求,并把需求排期。争取每次课程限定完成一个

功能。

需求排期遵循的原则是:优先完成对其他功能无信赖的部分;优先完成核心功能。

以下是开发过程中的里程碑。

1) 生成块。

2) 计时器驱动,块自动下降

3) 键盘控制块 旋转、快速下降、左移、右移

4) 落到底或粘在底部已存在块上 (if (conficted || touch_bottom) stick)

5) 删除一行:删除一行,把之上的行下降一行

6) 计分:消除一行和多行分值不同

以下功能在本学期没有实现。

7) 生成新块前,在预览区显示下一个块

8) 分数积累到一定程度 (?),加快块下落的速度

开发过程以git版本控制方式记录了历史,每个重要功能一次commit,以日期作为

message。

4. 定义

我们在开发前用示意图约定了一些定义,作为词汇表。排版原因,我在这里有文字

解释一下。

俄罗斯方块元素:工作区上绘图的最小单位,是一个小方格。俄罗斯方块的名字

Terris 即四元素,因为每个当前块由4个元素组成。

数组元素:即C语言中的数组元素,数组中的某一个。提出这个定义是为了区别于

俄罗斯方块的元素。

当前块 (current block) :正在移动的由四个元素构成的块。有S型、L型、田字

型等类型。

已存在的块 (exist block) :堆积在工作区底部的,已经粘成一团的元素。

像素坐标,世界坐标。像素坐标是由GDI绘图定义的,世界坐标由我们定义,以元

素为单位,左上是原点 (0,0) ,向右向下递增。

stick。当前块接触到已存在的块,或者当前块接触到工作区底部,此时应该把当

前块加入到已存在的块中,然后生成新的当前块;如果导致已存 在的块中某一行

充满元素,需要按游戏规则删除此行,然后把已存在的块中此行以上的元素降落一行。

5. 数据结构及流程

以下介绍当前块、已存在块、键盘操作、删除已存在块中的一行的数据结构和流程。

5.1 当前块

当前块中,包括当前块的以下数据:当前坐标,上一次的坐标 (用以擦除) ,当前

类型 (接下来会解释),上一次的类型 (用于旋转)。结构体如下,整个程序中只有

这个结构体的唯一实例。

struct struct_block{

int x;

int y; /* row 0, col 0 */

int old_x;

int old_y;

int* type;

int* old_type;

};

当前块的类型使用数组实现,如下,分别是一字型、田字型、凸字型。

int line_v_block[]={0, 0, 0, 1, 0, 2, 0, 3};

int line_h_block[]={0,0,1,0,2,0,3,0};

int tian_block[]={0, 0, 0, 1, 1, 0, 1, 1};

int tu_v_block[]={0,1,1,0,1,1,2,1};

int tu_h_block[]={0,1,1,0,1,1,1,2};

数组中的每两个数值 (数据中的元素)代表一个当前块中的元素的坐标,计8个数值

代表4个元素。

生成块时,

current_block.type = line_v_block;

指定了当前块的元素。

绘图时,遍历"类型数组",把每个元素绘出。无论何种类型,都遵循这一流程,从

而实现"以数据作为代码":类型数组即数据,遍历"类型数 组"、在旋转时改变类

型等即为引擎。

旋转的代码示例,改变类型 (的指针) :

if(current_block.type == line_v_block)

{

current_block.type = line_h_block;

}

平移的代码示例,改变横坐标:

current_block.x -= 1;

自动下降的代码示例,改变上一次的纵坐标和当前纵坐标。

if(! is_conflicted() && ! is_touch_bottom())

{

current_block.old_y = current_block.y;

current_block.y = current_block.y + 1;

}

else

{

stick();

generate_block();

}

快速下降:

纵坐标 增加 所有元素中到达底部 (或已存在块中同一横坐标的顶) 的最短距离。

貌似题外话,helper函数:is_conflicted(),判断当前块是否接触到已存在

块;is_touch_bottom(),判断 当前块是否触底;匹配横坐标,给出当前块的底坐

标;求当前块距离底部的最短距离。等等。

开发helper函数的目的,是为了使程序整体流程清晰。保障整体清晰的方法之一,

是要求每个函数内容不得超过一屏。如果超过了,就需要折解 出 helper 函数。

在主流程中调用 helper 函数,而把helper函数体移出主流程,这样主流程代码长

度就下降了。这和小学写作文的时候,老师要求先拉大纲是一个道理。经常有同学

说,在开发过程中 会发现新的功能,在开发遇到新的技术,没有做原型的,因此

难以把握大纲。这都说明把握大纲和做计划的能力还差,需要通过练习来训练。这

和小学 生写着写着作文发现需要查字典,或者写跑题了,是一个道理。我们的成

长并非认识的字多了,而是能预见到将会用到哪些字 (甚至表达手法、写作素材)。

此外,在面向对象中,有些的函数会成为game (或者 current block 或者 exist

block )的成员函数。这在开发中会认识到,如果它们与数据能内聚在一个类中,

该是多么方便,因此了解面向对象的在信息隐藏方面的优势。这些函数应归属于哪

个类, 是由哪个类承担这个责任决定的。

5.2 已存在块

已存在块中包括以下数据结构:块的长度 (事实上,是块的长度*2,代码中以横坐

标和纵坐标作为两个数组元素) ,已存在块数组。如下。

int exist_block_size=0;

int exist_block[(maxx+1)*(maxy+1)];

这种数据结构,及当前块的数据结构,把横纵坐标无差别地,不以结构体地方式放

在数组中,在后续开发中带来了麻烦。不过由于课程时间有限,后 来,我未对此

做出修改。应该逐渐演化程序结构,形成以元素作为结构体的数组。再开发出一些

helper甚至成员函数,遍历时以俄罗斯方块元素 为单位,而不是当前代码中的以

数组元素为单位。

对已存在块数据结构操作的函数之一是 stick,用于在当前块触底 (或触及已存在

块)时,把当前块中的元素移到已存在块中。

有不少helper函数,基本都是通过遍历 exist_block,按匹配条件读其中的坐标。

包括:匹配横坐标,给出已存在块的顶坐标 int get_exist_block_top(int x)。

5.3 键盘操作 & 动作序列

玩家操作块这一操作,由键盘消息响应开始。我们不在键盘响应中处理这一事件,

而是只在这里记住这个动作,加入动作序列中。这是后来的版本。最 初的版本,

我们也不在键盘响应中处理事件,而是调用 block.cpp 中的函数。原则是:凡依

赖win32api的,放在 tetris.cpp 中,如 timer, 键盘响应,绘图;凡是与业务逻

辑有关,平台无关的,放在 block.cpp 中。接收向上箭头,是键盘响应,平台相

关,所以放在 tetris.cpp 中;此时调用的 rotate,用于改变当前块的类型或坐

标,平台无关,所以放在 block.cpp 中。

动作序列的数据结构如下。在动作序列数组buffer_action_seq中,数组动作元素

(动作) 的类型是 枚举 action。

enum action{ action_left=1, action_right=2, action_speed_down=3,

action_rotate=4, action_down_auto=5, action_na=0};

action buffer_action_seq[action_size]={action_na};

int buffer_action_cursor = 0;

由玩家触发键盘消息开始,流程如下。

1)键盘消息响应:

buffer_action_seq[buffer_action_cursor++] = action_rotate;在动作序列中加

入一个动作。这对应于设计模式中的 commander 模式要解决的问题。

2)在timer中自动下降

timer中 buffer_action_seq[buffer_action_cursor++] = action_down_auto; 在

动作序列中加入一个动作。

3)在timer中触发WM_PAINT

timer 中 InvalidateRect 触发 WM_PAINT

4)WM_PAINT中执行动作序列

erase_old_block_seq(hdc);

erase_old_block_seq (hdc) 遍历动作序列,按每个动作改变当前块坐标,然后擦

除由于动作产生的旧块。遍历动作序列以后,就完成了自上个 timer 周期以来所

有的动作,擦除了这期间产生的所有旧块。

void erase_old_block_seq(HDC hdc) 片断如下:

for (i = 0; i < buffer_action_cursor; i++)

{

switch (buffer_action_seq[i])

{

case action_left:

move_left();

erase_old_block(hdc);

break;

在序列里的每个动作中,move_left 改坐标, erase_old_block(hdc) 擦除旧块.

5)WM_PAINT画新的当前块和已存在块

draw_current_block(hdc);

draw_exist_block(hdc);

因为重绘比计算花费的时间要多,作为性能优化,如果当前块与旧块坐标完全相

同,不重画。

另,另一个版本的动作序列,不使用枚举和swtich-case,通过把函数作为消息传

递给责任者,实现disptach:

void (*next_action)() = move_still;

next_action = move_left

其中 move_left是一个函数。next_action这样的元素 (类型是函数) 组成一个数

组,作为动作序列。执行动作序列时,用下面这样的代码:

while ( next_action++ != action_termination )

next_action;

由于 next_action 既是函数,也是数组元素的指针,因此上述代码不是伪代码,

而是可以执行的。这类似于 jump table 技术,数组元素的类型函数,可以遍历数

组,执行元素对应的函数。

5.4 删除一行 & 计分数

每个 timer 中,都调用 void kill_all_full_lines()。它遍历 exist block,凡

符合满行条件的,调用 kill_block_in_line 删除该行,调用

move_exist_block_down_line 把该行以上的 exist_block 下降一行。

这三个 helper 函数都是通过遍历 exist block 中的每个元素,匹配坐标条件,

然后删除数组元素或者改变数组元素的值。如前所述,由于 exist block 封装中

未使用 俄罗斯方块元素,所以这些遍历都写得非常丑陋。

删除一行以后,累积删除的行数。全删以后,根据删除的行数进行 switch-case,

向全局变量 score 累加分数。在下个timer中,把 score 用 textout 输出到工作区。

6. 回顾和检讨

6.1 数据结构,封装,循环条件

由于最初的 (也是最终的)数据结构设计偷了懒,后来又没有足够的时间修改,此

前已经提及两次,exist block的结构过于贴近平台,而远离需求。exist block的

颗粒度太低,是以 int 为类型的 数组元素,对应于需求中的 俄罗斯方块元素 中

的横纵坐标之一。某个数组元素到底是横坐标还是纵坐标,到底是第几个俄罗斯方

块元素,这些都需要由代码实现。这样,按需求写helper函数的时候,遍 历的元

素选取、终止条件,都遇到了麻烦。我在课堂上写作时需要考虑,有时还会错。经

验说明,当我需要仔细考虑,或者讲述时间较长时,学生听懂 可能已经有相当难

度了。终止条件错误的bug,在代码中存在两三处,导致在 exist block够多时,

即游戏进行一段时间,工作区中会出现莫名其妙的俄罗斯方块元素。这个bug在最

后阶段才解决。

这个故事告诉我们,设计不好,对编码实现的难度要求就会提高。战略失误,战役

和战斗就不容易打。领导决策肤浅,要求下属跑死,结果也是白扯。 道理都是一

样的。

6.2 不要对付过去

在开发中间的某堂课,我们发现当前块移动时后面留了尾迹,擦得不干净。这些那

堂课快结束了。为了能让学生在课后重复我课堂上的工作,所以我" 对付"了代

码,由局部刷新改为刷新整个工作区,包括背景。这样尾迹表面上清除掉了。

之后,延续了这段"对付"的代码。直到期末将至,我才发现这段"对付"掩盖了另一

些bug,坐标移动的bug导致除非刷新整个工作区就有尾 迹。这个bug在最后阶段才

解决。

6.3 并行,timer

有文章指出,初学者非常不容易理解的程序概念包括:赋值、递归和迭代、并行。

本程序中有几个埋得比较深的bug,是由于我对并行没有足够警惕 造成的。

timer, 键盘响应,WM_PAINT会并行发生。当其中一个未处理完的时候,另一个可

能就开始执行;甚至timer未处理完的时候,另一个timer也可能会开 始。而这些

并行的代码,都调用了 block.cpp。比如有时导致其中一个正改坐标尚未完成,另

一个开始刷新工作区,这样工作区里就出现个元素,位置是乱七八糟的。

并行的处理,需要 原子操作、进程间通信、避免重入 等概念。上述提到的动作序

列,目的之一就是希望擦除旧的当前块这一动作只在 timer 中发生。

在本课程中,应该不期待学生具备这些操作系统中的知识。不过我还没有想到该如

何设计才能规避这些知识。不过我猜应该类似于不用线程也能设计出 贪吃蛇,应

该有依赖更浅显知识的设计手段,比如单纯轮询,而不用事件响应、消息循环。有

哪位知道,请赐教,谢谢。

6.4 猜想后,应该先验证,然后再修改

学生们通常把验证猜想和实施解决归约成了一步,我也经常如此。下文中的他们,

包括我。

他们观察到问题,然后做出猜想。这是正常步骤。

但是他们不以实验验证猜想是正确的,急急按猜想修改代码。如果问题消失了,

好,他们假设抓住了问题的原因;如果问题还在,就再做个猜想,然后 又马上修

改。甚至更糟糕,没有退回到上一步的起点,就在当前工作代码上"继续"修改,让

各个猜想累加起来,最终问题解决的时候甚至不知道是什 么原因。

应该先设计实验,按猜想的模型,如果怎样就会怎样。验证猜想以后,再去解决。

比如假设由于 timer 和 keyboard事件响应 同步导致画图混乱,那么,不应该着

争写进程通信,而是 应该先选用简单粗暴的手段 去除同步,以更大的颗粒度作为

原子操作,验证猜想。如果猜想正确,现象应该有所改变。虽然影响性能和效果,

但这并不是准备最终采用的代码,只是用来验证猜 想的。当猜想验证以后,再去

想效果更好的方案真正解决,比如建立个变量作为信号灯。

6.5 不要轻易更换技术方案,试图绕过问题

这个方面,我最初是发现计算机本科的同学倾向强烈。经常有方案,明明再向前一

步就能解决,他们却在此时换了方案。问为什么。答:因为这个技术 解决不了这

个问题。

确定"不"是极其困难的,甚至比确定"能"要难上很多。你不能,并非就能确定这个

方案不能。

需要充分了解你所使用的技术,对它能够完成的任务有足够和明确的自信。同时,

对用来替换的方案能解决何种问题,也应该明确。做原型验证,根据 理论推论,

这些都是解决之道。见到工具,拿来就用,偏听偏信别人的评论,就太草率了;一

旦发现并非万能良药,转身就去寻找就的手段,这就更草 率了。

6.6 版本控制

为了让学生能看到开发的过程,我上课时用文件系统做了版本控制,每次课一个目

录,有时压缩成zip。课程结束以后,一个版本一个版本加入 git,然后commit,

操作了两个小时(?),其间又担心整错了,苦不堪言。

下次一定要从最开始就做版本控制。还要在 commit 前把 debug, pch, sdf 等二

进制垃圾手动删除。

7. 附件

附件是以git版本控制的代码及日志,在这里[http://download.csdn.net/detail

/younggift /7499881]。

protype下是技术原型。

tetris下的是俄罗斯方块项目本身。早先的版本是VS2010的,最后一天的是VS2012

的。你可以仅代码部分添加进win32工程, 以适应你的VS版本,或者dev c++版本。

log0.txt是课堂上的日志。log1.txt是最后一天前期的日志。log2.doc是最后一天

后期的日志,因为需要截图,所以改成用 word。

pic.bmp是图片,用来说明定义的。

branch是一个分支,我忘了它是否加入了 trunk,留在那里备用,以防遗漏。

--------------------

博客会手工同步到以下地址:

[http://giftdotyoung.blogspot.com]

[http://blog.csdn.net/younggift]

电子书阅读及工具

电子书阅读及工具

我现在看电子书,除了计算机以外,还常使用 ipad mini 和 kindle。所讨论的工

具都在这三个平台上。

后半部分讲的内容才是工具,前半部分是历史回顾。只对工具感兴趣的,请向下翻页。

1.

我最初读的电子读物,应该是 qbasic 的手册。当时还不知道有电子读物或者手册

这回事,常问张仕鹏师兄问题,只要见他在机房,就死皮赖脸地去问。有一次问到

红色的颜色编号到底是多少,他终于受 不了,告诉我按F1键,说:你自己看手册

吧。然后,我就开始漫长的手册阅读生涯,也因此有幸学会 RTFM 比身边常有一个

高手要重要得多。感谢张师兄教会我这一点。

此后很多年,也有不少同学问过我类似的问题,比如向上箭头的扫描码是什么,某

个函数的参数是什么类型,线程的使用。我都会想起张师兄,然后说:你 自己看

手册吧。他们有的回答,那太长了,有的回答,是英文的啊。我有时苦口婆心讲一

遍手册里的内容,也有时苦口婆心地讲"未来的世界就是这样了, 你越来越没有汉

语可看了",更多的时候我就只是闭嘴。人家需要的是具体的帮助,不是人生导师。

qbasic的手册当然只能是英文的。我讲的是另一个时代的故事,跟现在有所不同,

那个时候还不兴管师兄叫做师兄或者学长,我就只是直接叫张仕鹏 的名字,他比

我高两届。那个时候也没有互联网,没有在线词典,我也没钱买文曲星,只有后来

才买得起的一本40块钱的英汉大词典,太厚,不能每次搬 着去机房。而

且,qbasic的手册是不拆不扣的英文的。如同现在的手册,它也会援引其他的章

节,那么就跳过去,看完再跳回来。

我和我的同学,就是这样学习了qbasic,还有 turbo C的使用。看纸质书,图书馆

可以借到;看手册,随机带着。系里确实也开了C语言课,不过那是我们自己学会

以后很久的事了。

我本科毕业前读的最有份量的电子书是 windows资源大全,也是英文的。它的纸质

品后来我看到过,一寸多厚。我根据其中的一章学会了 借助 novell netware操作

系统做win95无盘工作站。毕业论文的一部分跟它有关。答辩委员会里有幸遇到了

后来的校长。他问:你这工作里有什么创新啊。我说:啥 也没有,就依据了一本

书--然后用手比划了一下厚度。就这样通过了答辩。

那本书的电子文档其实非常小,似乎一张或两张1.44M的软盘就可以拷下。似乎是

从win95光盘中解压出来的,是chm更可能是hlp格式的。

后来读了很多格式,txt的,word的,pdf的,不一而足。从最初到现在,都有人跟

我提到过电子书的诸多缺点,没有油墨的清香,没有情调不能 煮茶而读,记笔记

不方便,不习惯,版权等等。

我依然保持使用电子读物的习惯,甚至大批购买纸质品的同时,也仍然大量阅读电

子书,因为反对电子书的理由不足以说服我。油墨的清香、情调、版权这 些事,

适合矫情 (我长期以为这两个字是嚼性...)的人群。对于穷人来说,逮到什么版本

就是什么版本,有的读就不错,还要什么自行车啊。"不习惯"这件事,习惯习惯就

好 了。我们翻纸质品书页的习惯,也不过是训练出来的,这里既没有感情,也没

有文化可言。

记笔记确实是个问题。不过,我长期不把笔记写在书页上,因为书是图书馆的。涂

抹要罚款。所以,只要再准备一张纸,或者笔记本,把笔记都写在上面就 好。所

以,电子书也可以一样处理,笔记写在他处。

2. 工具

目前在所有的系统和格式下,我阅读时的要求都包括以下几个方面:书籍管理、格

式转换、上传下载、切白边、做笔记、阅读本身。

2.1 书籍管理

最佳的书籍管理工具是 目录系统 (文件系统) 本身,可以使用windows里的资源管

理器 建立和删除目录,通过文件名标注书的内容。加过批注的,我会加上*.young

批注.pdf 这样的字样。找书的时候,在子目录下搜索文件名。

另一个我常用的书籍管理工具是 calibre [http://www.calibre-ebook.com/]。

不同的操作系统版本,我用过 linux 和 windows 下的,都不错。可以标注书目的

书名、作者、出版社等信息。还可以加标签,不同于目录,这样每本书可以属于几

个类别。不过我的经验是,标注的工作确实总觉得 需要,但是有了这个功能以

后,基本不用。我们读书的数量,可能还远远没有达到以后找不到的程度。

我还曾经用过论文管理工具,endnote什么的。能导出作者、篇名、期刊、年月

等,写论文的时候确实方便。我问过导师,你咋不用endnote 呢。他用文件系统管

理,写每篇论文的时候把参考文献也放在论文旁边的目录里。他说:一共就引那么

二三十篇,不值得用工具;各种工具都会过时 (或者有适用条件?),但是文件系

统总是有效。

2.2 格式转换

kindle适合看小说,非PDF扫描的,ipad mini适合看漫画和有图的文档,还有扫描

版的电子书。台式机和笔记本适合看各种书,只是不能窝在椅子里,因为那样太远

就看不清显示器了。

它们能阅读的格式各有不同,效果也有好坏。所以我需要根据环境和需要,把电子

书由一种格式转换为另一种。

最常用的是 calibre。它能把word,pdf,txt,html转成 kindle 的 mob 格式,还能

转为适合 ipad 的 pdf 或 epub 格式。格式转换以后,可以用 calibre 架设www

服务器,用 kindle/ipad 从内网连接下载电子书。

另一种常用的转换工具是 amazon 本身提供的邮箱,注册的时候会提供给你。从认

证过的邮箱向它发邮件,标题是 convert ,把word/pdf/txt电子书作为附件。然

后过一会儿,可以用kindle从网上同步到这本书,已经转换为 kindle 的 azw 格式。

txt有时会遇到问题。一个是编码,calibre识别gb2312或utf-8有问题,可能会转

出乱码来。我也不知道怎么解决。这种时候,只好 用 amazon 的邮箱来转换。另

一个是自动换行,有时会转出大段大段没换行的段落来。使用阅读器apabi看,自

动换行还没出过问题。

2.3 上传下载

电子书到手,可能会需要从一个设备转到另一个设备,这就是我说的上传下载。

如果是小文件,在 PC机 和 ipad 之间,可以使用百度云。百度云支持在ipad上导

出并用别的阅读工具打开电子书。批注以后,如果阅读工具支持导出,也可以导出

到百度云,再上传。

准备在kindle上阅读的小文件,可以使用 amazon 的邮件,由PC机发送到邮箱,再

由kindle从网上同步下来。

如果是大的文件,100M以下,可以用 calibre 在PC机架设 www 服务器,用

kindle 或 ipad 的浏览器下载。只走内网,速度很快。

ipad 上的 goodreader 也可以架设 www服务器,用PC的浏览器从 ipad 下载 到

PC,我用这个功能保存在页面上做笔记加了批注的PDF文件。goodreader也支持从

pc的浏览器上传文件到ipad。

如果是更大的文件,就得把 ipad/kindle 通过USB线接到计算机上了。

2.4 切白边

纸书有白边,而 ipad/kindle 的屏幕以外本来就存在边缘,再加上纸书扫描的白

边,字或画面就显得有点小。对我这样视力不好的人,格式不友好。所以需要切白

边。白边切掉了,字就大了不 少。

我常用的切白边工具是 briss [http://sourceforge.net/projects/briss/]。

个java程序。载入电子书的时候有点慢,它把所有的页面都读进 来,然后叠印显

示出来,就像很多层琉酸纸那样。这样,一目了然地能够看到哪些部分是不能切掉

的。briss会自动判断白边范围,作为建议值。我的 经验,它的判断相当准确。你

也可以手动设置,设置好边界以后,另存一个文件。另存出来的文件并不比原来的

文件大多少,而且保存这一动作一点也不费 时间,瞬间完成,因为据说 briss 并

没有"真正"切掉白边,而是设置了新的显示范围。

另一个切白边的工具是 goodreader,它在阅读文件的同时,可以设置显示范围。

以上两个工具,显示范围都可以设置为奇偶页不同。

2.5 做笔记

我读电子书做笔记,常用的方法包括:另找张纸记 (或另记一个文件) ,拷屏然后

用画图类的工具在上面记,在电子书的页上上画 (或写字,或圈范围)。

另记一个文件的,我用 mybase, org-mode,txt/word+文件系统。

在画面上批注并另存的,一般用 evernote 保存归类。

直接在画面上批注的,用 goodreader, acrobat reader。

2.6 阅读工具

我用过的阅读工具,觉得不错的如下。

kindle原生系统,没有使用多看。事实上,没试过多看,所以不知道好坏,用

kindle的时间没发现有必要从英文菜单改为中文的。

goodreader,ipad mini 上的。能做笔记,能上传下载,能读很多格式。

ibook,是 ipad mini 上的,苹果产的。如果不做笔记看小说,还不错。

acrobat reader,ipad mini上有,pc端也有。能做笔记。

apabi,是 ipad mini上的,读txt格式好。

calibre 不是阅读工具,因为功能强大,总结一下。能上传下载,能图书管理,能

格式转换。

2.7 没有解决的问题

还有些问题没有解决。比如竖版阅读还是很令人头疼,看一行就要翻一下。要是有

工具能识别出来转成横版就好了。

3.

既使有这些工具,书也还是得一行一行由你自己来读。就像即使这个世界摆在你的

面前,人生也还得你自己亲自来过。说到这里,我想起在QQ上请同学帮 忙做题的

同学,总是想说:以后你的工资,也由别人代领吗?或者想说:你喜欢的,从来就

不是读书本身,而是读书可能带来的利益。

--------------------

博客会手工同步到以下地址:

[http://giftdotyoung.blogspot.com]

[http://blog.csdn.net/younggift]

从ssh登录缓慢说起

我在单位开了台实验用机,用SSH远程登录。之前一直用得不错,这两天发现断了。联系了两位相关的同事帮忙,分别对虚拟机和网络测试,都正常。我晚上回家再测,由于白天有了对比,晚上等待就更耐心一些--不到30秒,登录成功了。登录以后,速度还可以。
这说明网络、虚拟机都没啥问题。我以前遇到过SSH登录缓慢而登录以后速度不错的情况,比如我的WINDWOS机器连接LINUX用sftp的时候。后来解决了,这次的解决方案也大致如下。
解决方法:
修改 /etc/ssh/sshd_config,这是ssh服务端的设置文件。
1. UseDNS no
2. 把
GSSAPIAuthentication yes
改为
GSSAPIAuthentication no
然后重启sshd,/etc/init.d/sshd restart
再重新连接,登录速度快了。
导致以上问题的原因的基本原理是,ssh客户端在连接ssh服务端的时候,服务端根据客户端的IP地址去反向解析这个IP地址的域名。如果反向解析的过程中需要连接的外部世界的服务器速度很慢,或者干脆是不可达的,那么ssh服务端会等到DNS反向解析这个动作超时,这会导致十几秒或长时间ssh客户端傻等在那。没耐心如我者,就会判定网断了或者服务器完蛋了。
ssh服务端的这些动作可以禁止掉,不过开发者认为这些动作是必要的,安全中不应缺少的组成部分,所以默认设置了。这让我想起些别的。
Thunderbird,似乎译作 雷鸟(?)是非常著名的电子邮件客户端。似乎跟当年的foxmail一样著名,或者更著名。foxmail的作者后来加盟了腾讯,开发出了个著名产品,叫做微信。我用过一段时间Thunderbird,觉得还不错。后来,后来....这个故事告诉我们,时代并非总是越变越好的。
后来,我用thunderbird收gmail的邮件。之所以要这么干,是因为连接gmail的速度令人难以忍受。令人难以忍受的意思并非慢得不行,因为它有时也飞快,瞬间完成载入。令人难以忍受的原因是,速度并不稳定,抽疯一样,有时飞快,有时极慢。我慢慢养成了一个不良习惯,每次载入慢的时候,就开始在心里或者出声地骂相关责任人。
我以为用thunderbird收邮件,批量都收下来以后再看,感觉会好些。没有想到的是,或者说thunderbird的开发者也没有想到的事情发生了。软件工程中有所谓"你永远也不知道用户会多么愚蠢地使用你开发的软件",thunderbird开发组也绝对不能想到地球上还有我们这样一群用户的境遇吧。当我点击某封邮件,邮件头显示的是这封邮件的标题,但是邮件的正文仍然是刚刚读过的一封,直到几分钟以后,邮件的正文才刷新出来。如果没注意,会以为A标题正对应着B正文。Thunderbird开发组可能绝不能想到,这世界上有个地方收gmail邮件的时候慢到需要进度条指示,如果进度条有百分比更好。
sshd的开发组可能也不能想到,有些地方,虽非物理隔离的内网,但是许多地方亦不可达。饱食者不能理解何不食肉糜,那些优秀的软件产品的设计者可能也不能理解我们吧。就像微软的WORD和VS咔咔升级,越整工具栏和浮动工具栏越多,最后能编程和写文字的地方只剩下了一小点儿。当然,他们是有道理的,因为他们的目标用户是用大~~~显示器的。我当年用15英寸CRT球面显示器坚持了N多年,所以才养成了全屏编辑的习惯。当然,微软们还有另一个道理,就是我们中大多数人没有付钱,因此并非他们的目标用户。这与另一个案例类似。当年光荣公司宣布三国某版本游戏不再支持简体中文,我们中国不少用户义愤填膺,在BBS里一顿骂,骂光荣之愚蠢,竟然放弃大陆这么大的市场。几楼以后,有个网友悠悠地说:你们买过光荣用户哪怕一个拷贝吧,好意思说自己是用户是市场?
但是 thunderbird 和 sshd 不同,它们都是免费的,gmail也是免费的,整个地球都可以尽情拥有,而我们似乎不在其中。有个片子你看过没,叫做《日本锁国》。
--------------------
博客会手工同步到以下地址:

德惠也有星巴克

德惠,是包师弟的家乡,我们在谈论我编的一个笑话时提到过。那个笑话是这样的。我说,你知道中国为什么有很多城市,它们的街道名都是用别的城市命名的吗?比如长春有个北京大街,北京有个长椿街,长春还有通化路,台北也有个通化路。那都是用来玩穿越的。你站在长春的北京大街上,大喊一声,我要穿越,就到了北京,站在台北的通化路上大喊,就到了通化。包师弟说,德惠有个德惠路,大喊一声...就又回到了德惠。再喊一声,又到了德惠。
这表明包师弟对递归的有深刻的理解。
德惠你都没听说过?那三棵榆树呢,你也没听说过?二道白河也没听说过,金厂子铁厂子也没听说过,江南三道喇豁也不知道?你真是哪儿也没去过的土老冒啊。
我前几天去了趟德惠。不穿越去的,坐火车。绿皮车,就是小资们说的"坐绿皮车"去旅行的绿皮车。一路无话,在德惠也无话,有意思的是回来的时候。
回来准备坐动车,还是高铁来着,从德惠西出发。德惠有两个火车站,德惠站跑传统的火车,德惠西跑动车和高铁。打车10元就到了,司机一直把我们拉到售票厅门口,还有十来米就上台阶了。这说明德惠人民出行一般不提前买票,现买现走。我前一天到达的时候先买了票,所以又走了几步去候车大厅。
候车大厅只有一层楼,即使是现在这么暖和的时候也阴森森的,而距离发车还早,得等几个小时,所以我说,"要么去看电影,要么找个地方喝咖啡吧。"
我们打车先去电影院。好在刚好有一辆出租车在火车站,我们抢上前去。之所以要"抢",并不是怕别的旅客跟我们抢,而是怕出租车跑了,可能半天就没有下一辆了。
去电影院。司机师傅介绍说,一般去看电影的都是学生。我问,德惠有哪些学校啊。答,有实验中学,有三中,还有几中来着。我明白了,看电影的估计都是初高中生,不是大学生。我问,有几个电影院。答,一个。问,旁边有咖啡厅吗?答,咖啡厅和西餐厅什么的在城市的另一边,10块钱车费就不够了。我问,哪个方向,司机师傅向右摆了下头:你们从这里走下去,没多远就到了。我心想,没多远,10块钱却不够拐过去的...大哥你真能呼悠啊。
电影院前面站满了中学生,不到一百人吧。因为长期在学校工作,因为讲课,所以对几十人到一百人这样的规模很容易估算出来。我转了一圈没有找到售票口。
问某位同学,请问在哪买票啊。答:里面。问:怎么进去啊。答:有票才能进。
我心想,包师弟,你的学弟学妹的递归也学得可好了,你知道么?
但是这不能难住我,我再问:那你的票从来来的呢?答:学校发的。
我说:谢谢啊。咱们还是喝咖啡去吧。
这样故事终于转到正题。德惠也有咖啡厅。百度地图和谷歌地图都显示,一共有三家咖啡厅。我打了个车,到咖啡厅附近,并且坚决拒绝了去司机师傅去冷饮厅的建议。大下雨天的,我腰疼得要命,眼瞅要突的样子,喝什么冷饮。
出租车直奔两家咖啡厅密集排布的那个地方。一家叫做金典,另一家叫做莱茵河德惠分店。在一条街上,那条街被某条路分成两段,金典和莱茵河各处一段。金典我记得长春也有,莱茵河,我一下子想起了欧洲的咖啡,还有德国的火腿。恩,很值得一去。
我们从这条街的一头走到另一头。这一头KTV云集,在走向另一头的过程中逐渐转变成烧烤一条街。烧烤之密集,比东岭南街我家附近有过之无不及。
但是没有咖啡!
难道这能难倒我吗?地图上,还有一家咖啡,只是离这两家远一些。星巴克。打车,去星巴克。司机师傅说,哪?
我说:你不用担心,我能找到。就在新惠街上,往那个方向走,快到头了就是,中间会经过什么什么和什么地方。司机师傅说,你说的是惠新街吧?我低头看看地图,没错,新惠街。看看GPS定位,2100米精度。不过,根据周围别的街道名,差不多就是,新惠 或者 惠新。
没错,走吧。没多久,我们应该到了,中央公馆,位于城西的一片高尚小区。但是,没有找到星巴克。我们努力找,看到了积水的路面,因为马路已经到头了,还有一大堆一大堆的沙子,路边的公馆看起来没有装修完,应该是玻璃的地方只有空洞洞的窗户。
二猫妈眼尖,指着外面叫道:我看到啦,星巴克的标志。其实她从来没有去过星巴克。我也看到了,绿色的,像个LOGO那样的画面,可能吧,就是星巴克。我之所以没有看到,一是我并不认识星巴克的标志,我一般靠别人领,或者闻味,二是我眼神不好,更重要的是第三,星巴克标志的前面是一大堆黄沙子,这太令我难以联想了。
我们得出定论,这里就是星巴克无疑,但是它貌似还没有开业。我腹诽再三,关于中国人的民族性,比如没开业就挂地图上宣传,倒闭了也不撤掉,通知什么事情开始,从不通知结束,还有清洁工经常把拖布或者"小心地滑"支在厕所门口,24小时也不撤掉,所以人们只好按丛林法则,谁胆大先越界谁就是赢家。腹诽以后,我说,师傅,我再给你钱,你把我们拉到咖啡厅吧。
他说,我知道莱茵河,我见过。
太好了,那就是莱茵河。我们原路返回,我说,对对,我们刚刚就是从这里打车,莱茵河确实就应该在附近,只是我们没有找到。
师傅把车停下来,指着三间没有装修的门面,上面全是胶合板的本色,他说:这三家中间的那家,原来就是莱茵河,它就应该在这里。
明白了...星巴克没开业,莱茵河倒闭了。
我说:不去金典了,我们去哪个有咖啡的西餐厅吧。很快找到一家,叫做...名字忘了。门口墙上有个金灿灿的欧洲风格满身肌肉的男像上半身。先前找金典和莱茵河的时候我看到过他,还想拍照来着,没想到有咖啡。是家西餐之类的店。
进门问,有咖啡么?答:有。一楼有几个包间,二楼有很多包间,此外去卫生间的路弯弯曲曲,两侧有很多包间。每个包间里刚好放俩皮沙发,相对而视,中间是个木头桌子,上面好像铺了玻璃。墙上特意做成很多疙瘩的样子,我敲了下,塑料的,里面是空的。因为是硬质材料,所以不吸音,屋子虽小,听起来有点像食堂那样拢音。颜色...不得不说,从小到大,我都把那种颜色叫做"鸡疤疤色儿"。
好在有极品蓝山,来一壶,40元。应该可以消磨半个下午。
咖啡是装在陶瓷的茶壶里的。壶的造型,似乎是一只小猪的变形,挺可爱的。杯子倒不是玻璃杯。我正瞪大我的小眼睛凝视这壶,二猫妈开始倒。咖啡的颜色也像茶水,跟壶挺匹配的。我没端起来喝,还在那瞅,二猫妈说,"比速溶咖啡还淡啊。"我说,"恩,我看出来了,从颜色上。"
原来的壶把掉了,换成了做旧的铁丝,外面缠上细丝。我把玩这壶把再三,开始一杯杯喝。咖啡,微温。
后来,把我们原来吃剩的半袋香瓜子也翻出来,还有半袋腰果 (?),就着咖啡,都吃了。小半桌子果核,最后都包吧包吧带走扔了。
进站安检的时候,有个穿制服的喊,"谁的包,那个,是那个包。"
是我的。我把包搁桌子上,"怎么了?""里面是不是有把刀?""对,有把瑞士军刀。"我拿出来递给他,"心想,这把刀不违反任何条例,你要是敢没收..."他把刀打开,试试刀锋,掂了半天,折回去,折好的刀拿在手里探出大半截,不吱声,开始注视屏幕。我等了一会儿,心想,这是完事了的意思吧,也没吱声,伸手把刀拿过来,又想了想,没说谢谢,刀装包里,找个空座开始看书。
后来过来个人坐我旁边,腿抖啊抖的。半天,停了一会,换另一条腿抖。我快被他抖晕车了,就换到对面坐,他把自己的包从另一侧拎过来,放在我原来的位置上。此后再无故事。天快黑的时候,我一路轨道交通,回到家里。
我以后还会再去德惠的,并且带上自己的咖啡和滴滤漏斗。
--------------------
博客会手工同步到以下地址:

在北京丢东西

在北京丢东西
我妈说,我从小丢过帽子手套无数。我印象里丢在图书馆的确实有几次,等想起来返回的时候图书馆已经关门了,大冬天只好光着脑袋回家,冻得够呛。不过,如果说我是非常粗心大意,也不公平。坐同事同学的车,在副驾驶的时候,经常被告之,可以把书包放在后排,但是我总是坚持抱着,因为怕扔下忘了。
所以,你看,我还算小心。十年不怎么丢东西,但是丢一次顶上别人丢十年的了。
上一次在北京丢东西是1996年,这一次丢东西是最近没多久。
1996年,我大学二年级的暑假,是我第一次去北京,觉得天安门挺小,人民英雄纪念碑挺矮,紫禁城挺旧。那时候还没觉得北京是大农村。当时我本科还没毕业,暑假找家教的同学介绍我的计算机相关的活儿。连学带干一个假期,假期快结束的时候跟着老板臧老师一起去北京,买计算机配件回长春组装。现在想来,工作上也不怎么需要我去,奖励和提携的成份居多吧。
同行的还有两位公子,也是工作人员。曹公子带了个非常好的相机,日本原装的,变焦镜头可以伸缩三档,银白色。另一位公子我一时没想起来姓什么,我和他一起去了天安门。走累了的时候,我们在天安门西侧坐了一会儿,他把相机放马路牙子上,歇够了我们就离开了。等想起来回去找的时候,就像我扔在图书馆的帽子手套,从此再无缘得见。
我陪了曹同学相机的一半价格,其中有跟李岸同学借的一笔钱。然后,从此毅然决然地走上了IT之路,为了挣钱还钱。当时不少同学在热烈地讨论谁该被任命为物理系学生会科协计算机分会的会长 (注:该职务与学生会一般成员,现在叫干事吧,与干事平级。因为科协是与宣传部啊什么的平级,协会会长算部长,计算机分会会长算部员。),而我要去挣钱啦,所以这一切完全是浮云。后来有同学评论我看淡一切,才不是,是被逼的。实践证明,我们的美好愿望总是落空,IT挣钱也没有多快,尤其我成天干活,连食堂也不吃了,很费。所以,这笔欠款直到1997年,我大三,在大四学生毕业的时候,我卖了一大批书,才把全部其余的钱还清了。卖出的书里有不少好的,我现在还在怀念他们。
这就是第一次在北京丢东西,印象深刻。从此以后,我当然加倍小心。所以,后来能够做相当长时间计算机和网络的系统运维工作,因为小心。所以,后来还写了不少代码,不怎么使用单步调试,因为小心。但是,又是实践证明,我们的美好愿望总是落空。前不久,又在北京丢一次东西。
我妈问,丢东西的地方人多吗?我没有回答人的多少,我说了地点:北京火车站站前。
我从后排座下了出租车。或者,把书包就扔在车里了,或者,扔在了马路牙子上。然后,拉着手提箱施施然离开了。我跟大哥去了麦当劳,我还喝了咖啡。所以可以推断,在下车前后,我一定还说了一句,咱们还有时间,去喝杯咖啡吧。
等离开麦当劳的时候,我才发现缺了一个书包。这时,距离下出租车已经2个小时了。按常人理解的顺序我介绍一下遗失的物品吧:佳能EOS 50D单反相机机身一部及比原装更好的镜头一个,佳能 ixus 860 IS 相机一部。以上两部相机里当天的照片。Kindle三代键盘版一部,ipad mini一部。一堆U盘,几乎是我的全部,其中64G的两个,16G的一个,都是3.0的。还有一堆U盘,三四个吧,每个都是8G的。还有几个U盘,想不起来了。《西方哲学史》纸质书前三分之一,上面做了笔记。此次出行的调研笔记,全部。
我们电话了出租车司机,没有发现。我们愿望出价,还是没有发现。我报了案,去火车站不远的派出所查看监控录像。我努力看了,我的视力不足以找到自己。大哥又看了一遍,他找到了我,不幸的是,此时我被一辆经过的车挡住了,地上是否有书包都看不清楚。
总之,找不到了。
为了进一步灭绝你的希望,我得提醒你一下,书包里有一盒我的名片,上面有电话,有地址,有电子邮件。EOS 50 D的包里还有同事樊老师的一张名片。
我多么希望拾到的人能留下所有的一切,但是把我的笔记和做了笔记的纸质书发给我。邮费也可以我出。唉,想想就心情沮丧。我还曾经跑步两三个街区追上一辆自行车,把别人掉在路上的一条烟还给他呢。恩,这世界不公平。
同学们对我进行了全方位多角度的安慰。从破财免灾有好事,到以后一定要小心啊,还有没事没事,身外之物。说实话,我感受到了各位的心意,不过通常,也就是这样。
后来,大哥开导成功了。丢东西的当天,火车也没坐成,第二天飞回长春。落了地,坐车上高速。大哥此时开时发话,说,你不是一直说自己信仰共产主义吗,那就不应该执着这些东西啊,都共产了啊。
我说:有的东西是纪念品,总应该是我的吧。
大哥说:那你就在心里寄托心里纪念呗,东西还是大家的。
我说:那我的笔记呐,那总是我的吧。
大哥说:知识是以笔记为载体的。如果你知识是你的为借口,而拒绝共享载体,那所有的东西都可以照此处理了。
我说:但是捡到东西的人他也用不到笔记,而对我非常重要啊。
我接着说:也不对,东西是否有用,有什么用,也不能是我一个人说了算的。因为东西是大家的。
于是,我释然了。就让捡到东西的人去玩儿吧,或者卖掉,让花低价买的人去玩儿吧。楚人失之楚人得之,谁得谁玩吧。不过据说 ipad mini 有相当强的加密,要刷机的话,需要口令。我估计一般人猜不出来我设的口令。所以,这件东西算是废了,谁也玩不到了。
不到两周,我换了 ipad mini 2, 换了 kindle paper white 2,换了二猫妈的佳能 ixus 860 is。我开始看《西方哲学史》的第二部分,中世纪部分。同学们纷纷送给我硬盘和U盘,安慰我受伤的心灵。单反等有了钱再调研再买。
所以,身外之物,一切皆可失去。只是,我偶而还是偷偷希望,哪天快递小伙电话我,打开包裹一看,啊,《西方哲学史》的第一部分。当然,我更相信杨过和沙隆巴斯说的,人生不如意,十有八九。
--------------------
博客会手工同步到以下地址:

我在 ipad mini 里都装了些什么软件

我在 ipad mini 里都装了些什么软件

最近的照片在这里,[http://www.douban.com/photos/album/124863663/] 和

[http://www.douban.com/photos/album/125311754/]。

0. 为了日程安排,买了 ipad mini

2013年秋季学期,因为两次似乎与人约定时间,然后忘记了,非常惭愧。为了避免这样的事实再度发生,买了 ipad mini。

可能有的同学会说,那你随便整个日历软件不就行了么。因为我的要求比较多,试了几种方案,都不够满意。因为我的日程既可能在每天任何时候更新,在安排新的约定的时候还要检查日程,同时,我的办公地点不固定,有几处,所以总得随身携带才行。我试过每周用纸打

google calendar 打出来,这是除了 ipad mini 最好的办法了。手机换了三个,google calendar

的同步不是费劲,就是速度太慢。

曾经考虑过买个安卓的,有些同学告诉我容易死机,我自己用来打过一阵愤怒的小鸟,也体验过死机。还考虑过买个iphone,但是想想每天要充电,如果电话多了还得带个"随身充",放弃了。

最后,买了 ipad mini,不支持电话卡的,只用 wifi。因为凡是我要安排日程的地方,都有

wifi。ipad非mini版太大了,我拿不动;mini2太贵了,买不起。主要的,它是生产工具,虽然用来娱乐的时间也很多,但是生产工具尤其是日程安排是必要条件。

我安装了以下软件。

1. 日程

这是我最初购买的原因,那3部手机都是因为不能满足 离线日程查看,离线日程安排、日程同步 等功能,所以才需要 ipad mini。

calendars by readdle。符合我所有的要求。

2. 邮件,gmail

当邮件到来,我发现用同一根有线出口,ipad mini比 windows/linux笔记本上的 google mail

网页版速度要快很多。发送也是这样,虽然我极少用 ipad mini发送。

3. 操作系统

升级操作系统到 ios 7. 在 设置->通用->软件更新 里。

4. 安装软件的软件

4.1. itools

在笔记本上安装windows版的 itools,用于安装软件 和 导入文件。

我试过用苹果原带的 itunes

导入文件,有人总结了这样一句话我深有同感,itunes的开发者一定是别的公司派到苹果去卧底的,就像微软派了人去诺基亚卧底一样。itunes弃用。

从苹果原带的 appstore 安装软件,一是每次问口令很烦人 (我知道它是为了我好),二是从俺们这里连接 appstore

非常之慢,第一天我花了整个下午安装了没几个破软件,几度想把 ipad mini 砸了。最终因为太贵才没有付诸实践。

上述问题 itools 解决得都不错。

4.2. 安装 兔子助手,在 itools 里,用于安装软件。

这样软件不仅能从windows笔记本上,也能在 ipad mini 上直接安装了。

5. 读书

ipad mini 与 kindle相比,对我有个好处,就是它更亮,对比度更强,适合我这样眼睛比较差的。其他的好处大家可能都已知道:不需要照明

(paper white据说解决了这个问题,我没在暗处试过),不会因为照明有眩目的亮斑,看pdf扫描版和大开幅的文件的时候更方便,彩色。但是ipad

mini比kindle (即使是比较重的有键盘的3代) 要重。

我安装的读书软件有:kindle, ibooks, acrobat reader。它们各有好处。

为了看教案什么的,安装了wps office。

6. 做笔记

6.1. 印象笔记

做读书笔记或记临时的想法的。

6.2. snppen

用于看扫描版的书时做读书笔记。先截图,然后在截图上标注或加文字笔记。

其他侯选的类似软件,我用过的:圈点,墨笔,Paper。

6.3. color pencil 或 黑板 (图标是个猫)

用于临时画个图。color pencil 的笔触可以更精细一些,黑板更粗糙当然也更简单易用。

其他侯选的类似软件,我用过的:Concepts, EverMemo, NoteLedgeFree, Sketch Painter,

Sketches. 都比较高大上,有这种需求的时候,可能就不如用计算机了。

6.4. 录音板

用来临时录个语音备忘什么的。

7. 词典

欧路词典,是英汉词典。

英英字典,Merriam-Webster Dictonary HD。

其他:Wikipanion,即wikipedia。Solar Walk,太阳系漫步。

8. 百度云盘

为了传书看书方便。下载后可以选使用哪个软件打开。

9. 其他

9.1. 新概念英语

我还在背新概念,所以装了 新概念英语.英音 和 另一个新概念全文和语音。

9.2. 小工具

美图秀秀。

Calculator New。这是个计算器。

我的手电和尺。

Knots 3D。教打结的,有动画过程。

QR。条形码和二维码扫描。

Commander C...名字后面看不到了。指南针兼水平仪等。

Cardiograph,测心率的。

黑迹天气HD。实时和预报天气。

时针。内置的,带倒计时和秒表。

逗猫的:人猫交流器,CatTranslator.

星空指南。实时星空。

微信。及 skype。

9.3. 音乐

节奏大师,也算音乐类的吧。

钢琴HD。

GarageBand,是个乐队,但是只有几种乐器免费,包括架子鼓、键盘、吉他。

9.4. 视频

试过速度都不错,不常用。

爱奇艺视频,和 PPS架强版HD。

10. 娱乐

游戏装了以下几个:植物大战僵尸2,植物大战僵尸,节奏大师,全民大战飞机,唱吧HD。

--------------------

博客会手工同步到以下地址:

[http://giftdotyoung.blogspot.com]

[http://blog.csdn.net/younggift]

用工程眼光看待生活,心情好多了 2:修理一面墙的白板

前文书曾提过,我有一面墙的白板。坏了一段时间了。

原状等全部照片在这里的后面几张照片 [http://www.douban.com/photos/album/124565788/]。

0. 问题的由来 及 方案的制订

白板是我哥给做的,最外层是高密度板,粘在白铁皮上,白铁皮直接粘在墙上。当时我哥琢磨着方便我以后搬家的时候把白板带走,不顾我的反对,有些地方的胶粘得不是特别满。不顾我反对这一点,还真是非常具有技术人员气质。从胶不完整的地方开始,在这一两年里,白板渐渐开始和墙"离胡儿"了。

起初我忍了,用手按着写,但是慢慢地就不乐意往上写东西,因为它活动。再后来,大半白板都离开墙,如果不是上面有三角铁挂着,随时可能掉下来。

我哥判断是墙潮,胶开了。有道理,因为白铁皮和高密度板之间没有任何剥离的地方。用手向墙壁按白板,能听到白铁皮后面的胶裂开的声音.咋整呢?跟我哥电话,他给了几个方案:重粘;或者,先剥开,把白铁皮钉墙上,然后再把高密度粘上;...。

最直接的方案是,他来给我整,我提要求就行了。我想起了李记者,还有网上的某博主,他们都提到如何利用公司制度,如何要求工人师傅做一面大白板。这事儿我不能干呐,不同于小资产阶级,我就是工人啊--我得自己整。

采用的方案是把整个白板钉墙上,凡是鼓起来的地方,附近都钉,这样就平整了。不准备在上面再粘一层高密度了,一是这样磁铁离白铁皮远,容易吸不住,另外再粘还有味,这工程量也不是我一个人能承受的。至于露出的螺丝帽,就忍着吧,算作工程中的妥协。

1. 工具和材料

先计划,每40厘米左右一颗钉。除夕白天,去建材买材料:胀塞

(膨胀螺丝里的塑料部分),螺丝,垫片,各50个。共计6块多或者16块多,确切钱数我忘了。垫片的作用是防止螺丝帽太小,把白板拽豁了。

准备工具,电锤、榔头、螺丝刀。

2. 方案修正

安排。把粘在白板上的贴纸都转移到另外半扇上,准备钻另外半扇。

钻!钻了半天,感觉没进去。看看,白铁皮磨得锃亮,但是没透。检查电锤的设置,正转不是反转,电锤不是电钻。再钻,还是不行。

我这十多年来做项目,最大的收获不是能干出什么东西,而是--能更快地确定什么事情是我干不了的。现在这情况,即使我钻进去了,也得累个半死,而这只是1/50的工作量。

电话我哥,即然他给出方案,应该也能解决这个细节。我妈和我哥分别给出了同一个技术,先砸个水泥钉进去,"引"一下,再钻。试了下,成了。电话回馈的时候,他们问,为啥选择除夕干这活。因为今天第一比较确定没人找我,第二反正大家都在放炮,估计不那么烦我的电钻声。所以整个中午下午到天黑,都是我的天下。

3. 施工及劳动保护

左半边,20多个孔。我这样操作:1.用榔头,水泥钉打个孔,晃一晃,拔出来;2.用电钻,打眼到墙,红砖灰哗哗的;3.涨塞,用榔头敲进去,4.螺丝加垫片,用螺丝刀旋进去。

右半边,提高效率,批量操作。先把所有的孔都引出来,然后连续钻孔。钻完孔以后,耳朵吱吱直响。这才想起来应该先把耳朵塞起来,电钻工作时是能把耳朵震聋的。另外,砸水泥钉的时候,钉飞了一个,正打在左眉内端,离眼睛不远了,出血但是不严重。其实此前我戴了护目镜,应该能避免这样的伤害及虚惊。看不清楚东西,所以摘了。因为操作的一些零件上有锈,特意在伤口上抹了碘伏,我是真怕破伤风啊。有兴趣的同学请google,死状非常恐怖。

4. 成果

白板基本平整了。不平整的部分,因为每两个螺丝间的面积不大,所以即使不平整,白板也足够稳固,适合写字了。

把所有粘纸和白板上原来写的东西整理了一下,心情大好,同时也发现老多任务都没有完成,荒废了啊。

擦着头上的汗,我心想,我度过了一个多么有意义的春节啊。

--------------------

博客会手工同步到以下地址:

[http://giftdotyoung.blogspot.com]

[http://blog.csdn.net/younggift]

用工程眼光看待生活,心情好多了:当电容笔头折在音频口里

用工程眼光看待生活,心情好多了:当电容笔头折在音频口里

有的时候生活里突然出现件事,真是令人不爽。比如我忙叨着,ipad mini上插的电容笔头撞在柜子上,折在音频口里了。

愤怒,这是我的第一感觉。好像生活针对我似的,其实生活哪有功夫理我。得把电容笔折里面的头儿拔出来。真令人焦虑。

我想了个招,对缓解焦虑有点效果,推荐给有同感的各位吧。

用工程的眼光看待生活里的这些突发难题,假想这是别人找你帮着解决的问题。顿时觉得有点好笑是吧。

好吧,当工程问题解决一下。

我先是搜了一顿,大多数解答是台湾省的。有建议找厂家维修的;有说用针扎眼,然后带出来;有说用修眼镜的小起子;有说...换声卡,拆苹果的。看来出这样毛病的人不少,解决方案也就一般。

我试了试针,电容笔残留的部分塑料的硬度挺高,扎不动。

还突出在外面一小点。试了试瑞士军刀的小镊子,镊子强度不够,夹不住。

初步失败,现在需要真正当个问题解决了。我用微距镜头拍了两张,放大了看看状态。断面是斜茬,高的一面突出一点点在音频孔的外面。音频孔的最外面也不是平的,一侧高一侧低。

我用修眼镜的小起子推断面,断面能旋转,把断面高的一侧转到音频孔低的一侧。断面露出的部分更长一起。用镊子,还是不行。

上 Letherman。用 letherman 的钳子,它的钳子尖特别细,而且钢口不错。夹住突出那一小点,一下子就拽出来了。

然后把电容笔接在360随身wifi的插口上,一切又恢复了正常。

把令人不爽的问题当然工程问题,而不是当成针对自己的攻击,心情好多了,而且解决以后巨有成就感。

--------------------

博客会手工同步到以下地址:

[http://giftdotyoung.blogspot.com]

[http://blog.csdn.net/younggift]

植物大战僵尸2对工程师的启示

植物大战僵尸2对工程师的启示

注意此文虎头蛇尾,列了好几点,后面的都没有展开。

有的哲学家认为,世上万物都是彼此联系的。所以,鸠摩智才可以被比拟为全栈工程师,所以,我才能东扯西扯一些文字但是自己认为这是在谈技术。有的同学可能说,你为什么说"有的哲学家"呢,因为确实有的哲学家认为世界是由单子组成,而单子之间绝无联系,比如

莱布尼兹就是这样认为的。就是那个莱布尼兹,与牛顿分别独立发明微积分的数学家,他兼职哲学家。

扯远了。世上万物都是彼此联系的,所以,植物大战僵尸2对工程师有如下启示。不是指这一优秀的游戏作品对工程师努力创业方向的启示,这将在第一点否定,而是指我打通关的过程中,对我这个工程师个别人的启示。

1. 想法不重要,执行力更重要

植物大战僵尸2(以下简称植2)里,你有一千个想法也没有用,你的手速得够快,失误得足够少,更重要的是,你手里的阳光、插槽、能量豆得够多。

十余年前就有老板问过我,此后很多老板又问过我同一问题,"你有啥想法可以用来创业"。我没有想法。我只想做个平庸的人,用技术为人民服务。至于什么才是人民需要的,我认为有另一种人更有资格回答,他们专门从事创业。

也有人问过我,你在工作中就没有什么感到不方便的地方吗,要知道,世界是由懒人推动进步的。我的确有感到不方便的时候,然后自己鼓捣个小工具解决,但是通常大家都对我的方法感到更不便,虽然他们同时也希望我帮助解决--使用他们感到不便的方法。换句话说,我用方法产生的效益本身为大家服务,而不是用方法为和我一样的工程师服务。

也有人针对以上说过,能找出共通的问题,帮助更多的跟你一样面临困境的人,是件好事。那么,问题是,我不是能找出共通的问题的那个人,我自知没有这样的能力。又,我通常不面临困境。

屁股决定立场,所以我认为点子不重要。

有些人老有想法了。每打完一局扑克牌,他们就回顾刚才那局。"我要是先出红桃三,然后你就会出红桃四,我就地灭了你..."当然,凡牌艺惊人的,必然要review;但是review的,大抵牌艺也糟烂无异于常人。因为他们一厢情愿地乐观认为,自己就是能这样操控这个世界。

类似的,打星际/魔兽/帝国/dota/cs/cf/cx,每局之后必嗟叹,"哎呀,我就差那么一点点。我刚刚要是再什么什么一下就好了。"大有"天不与我,非战之罪也"的气势,然后喝一声"不服,再来战"。然而,我们看到了一张多么生动的赌徒的形像--下一注,我一定能赢。

我相信,人类在基因里一定有那么个常数,凡超过这个比例/几率的,我们就会认为行了,"快成功了"。有些人,这个阀值可能比较低一些;这些人中的一部分,可能进一步认为这些值是每次相关联的,尽管有波动,但是天下大势会越来越有利于我。游戏、赌博这类活动,其中成功的范例估计就抓住了这个常数,让正常人类的行动结果刚好在常数附近,所以大多数人误认为--快成功了。而理工类学习为什么不那么受待见,也许,有点偏离常数吧。

review扑克的,你以为你出红桃三人家就出红桃四,而且是在下一次局面不同的情况下?review dota的,你以为你的操作能够更快一些,在你手速不变的情况下?

我们高估点子带来的成功几率,往往还同时高估自己的行动力。

经常有老板或想成为老板的人忽悠同学们,这么整这么整,未来铁定是咱们的,然后对你不参与嗤之以鼻。要想让技术人员投入参与跟骗风险投资差不多,要么,说服技术人员,他们是同盟不是牛马;要么,给确定的投资回报。否则,我的答复总是:乐意整你自己整去。如果你有足够的执行力,你就自己整了,还在这儿跟我废话么。

2. 战略很重要

植2里常有这样的关卡,纵使你手速无敌,植物种类满满,插槽够多,你仍然打不过去。比如有些关卡加了限制,只能用这些阳光,只能使用给定的植物。

打帝国时代的时候,高哥也给我深刻的教训。当时,我建几乎所有建筑都能用快捷键,部队全编号,而他只会单手鼠标操作,而且够慢。但是,在他的土耳其火枪手面前,我仍然溃败。究其原因,其实极其简单,咱们课本里都有,"集中优势兵力,各个歼灭敌人"。道理简单,如何做到这一点,包括决心、确保歼灭充分而不过度,尤其是如何在大局失利的情况下创造局部兵力优势,却很难做到。

战略。

战术,尤其是个人战术再漂亮,也不足以弥补战略错误带来的损失。选哪些植物,如何编阵,先期如何发展,后期如何收官。想明白所有这些,都比一时一地的小利,一次点击比别人快0.1秒要重要。方向性错误比偶尔的小失误带来的损失要大得多。

某些人所谓点子很重要,也许,也是想说明战略比战术重要吧。

3. 各有所长,勿求全责备;针对场景

4. 小错误可以纠正,但是不可积累

5. 确定的边界

6. 初期非常重要,可以付出代价保证资源积累

7. 资源有限 & 退一步策略,让敌人多挨一会儿打

--------------------

博客会手工同步到以下地址:

[http://giftdotyoung.blogspot.com]

[http://blog.csdn.net/younggift]