阅读总结2011

终于到了2011最后一天,可以发各种总结了。阅读还是用http://imnerd.org/douban/进行统计。

题外话:动画和游戏

至于动画、游戏什么的,自然用Bangumi的年鉴功能。懒得单发,记录在此了:

「Bangumi 2011 年鉴」 2011 年,我看了 28 部动画,读了 本书,听了 1 张音乐,玩了 7 部游戏,看了 1 部剧集,参与了 73 次讨论,进行了 0 次条目编辑。

在这28部动画中印象最深刻的是还在放送的《ちはやふる》(歌牌情缘),游戏里面觉得最好的是一款老游戏《枪声与钻石》。当然今年玩游戏太少了,而且基本都是PSP上的AVG,最近这三个月已经写了大概四篇相关的玩后体会。

数据

回到正题,2011年的阅读数量为112,较之前年回落较多。原因不外乎是工作太忙,另外则是去掉了漫画,轻小说也只保留第一卷,确保统计水分不太大。

尽管如此,其实这112本书中有80%还是推理小说/轻小说,专业书以及学习类书籍大概只有10本……?所以推荐列表还是从推理小说开始吧(书籍链接在图片上)。

推荐的推理小说/轻小说类作品

  • 东野圭吾《新参者》:带有主线的短篇集,东野今年在华语地区出版的最好的一本。本来对加贺刑警系列(为什么要专门写成刑警系列……一定不是《便当》的影响)并不感兴趣,但此本改变了我的想法。
  • 虚渊玄《Fate/Zero》:爱的战士真的有两把刷子,比起Fate/Zero来说,Fate Stay/Night就是青春偶像剧了。
  • 若竹七海《我的日常推理》:被喜欢/厌恶两个极端明显的一部推理作品,有人认为诡计是故弄玄虚,有人觉得喔喔喔这个安排简直超神了。我最喜欢里面利用虚拟的“公司杂志”目录作为章节分隔的做法。
  • 小酒井不木《恋爱曲线》:日本侵华战前的推理集子,其时髦程度放在现在也很高,整本读下来非常痛快。
  • 奈須きのこ《空之境界》:先看的动画剧场版,文字的力度甚至强于直观的画面表现。
  • 逢坂刚《百舌呐喊的夜晚》:够冷够硬但又好读,简体也要买本!

其他类别的书籍推荐

  • 禄是遒《中国民间迷信(崇拜)》系列:徐家汇藏书楼的良心作,虽然每本都是薄薄200-300页卖到40块,但总体来说是一套很有趣的风俗讲解和记录丛书。
  • 艾伯特《神奇的二维国》:小说形式的科普读物,要考虑到这是1884年的作品,那只有用“神作”才能形容。希望大家都读读,为适应二向箔打击带来的新世界做好准备。另外推荐给妄图二次元去把虚拟妹子的2D厨。
  • 杨显惠《夹边沟记事》:神作。
  • 王爽《汇编语言》:从未见过一本语言类教程能写得如此让人看完一章还想看下一章。在遇到此书之前数次学习汇编都是半懂。用了半个月的业余时间看完后顺利入门。
  • 比目鱼《虚拟书评》:之前在比目鱼Blog上看到这种形式的文章,太好玩了。见到此书变为实体还以为也是虚拟的……
  • 王新禧译本《徒然草·方丈记》:王老师文笔真是巨好——除巨好以外我词穷找不出其他可形容的了——古风浓郁但又读起来不晦涩 (当然是对于我这种古文门外汉来说) ,实是译文典范。
  • Jeffrey Richter《CLR via C#》:夯实基础的必备知识,对于.net程序员来说不是只知道string有多少方法就行了。

雷区

既然有推荐肯定也有扫雷:

  • 内田康夫《贵宾室的怪客》
  • 东野圭吾《以眨眼干杯》。骗版税代表作。看完《新参者》再看这部,都会以为“东野圭吾”是个拥有数名文风迥异水平有天地之差的作家的写作团体。
  • 麦家《风语》系列。作为麦家的死忠读者,我都以为买到盗名之作了。
  • 二阶堂雷人老师的一切作品,以《双面兽事件》为代表。

《深度探索C++对象模型》学习笔记(5-7章)

第5章 构造析构和拷贝

虚函数

对于抽象类而言,是否应该自己负责初始化类内的数据成员?(别忘了抽象类也可以有非纯虚函数和数据成员)

  • 一般情况下被认为子类要负责从基类继承来的数据成员的初始化
  • 或者基类必须提供一个显式的构造函数用于自己数据成员的初始化
  • 最好的方法则是将行为和数据分离,提供接口专门用于定义方法
class A_B
{
public:
    virtual ~A_B() = 0;
    virtual void Say() const = 0;
    inline char const* GetData() const { return iData; }
protected:
    A_B( char* aData ) : iData( aData ) {  }
protected:
    char* iData;
};
inline A_B::~A_B() {}

class C_D : public A_B // concrete derived class
{
public:
    C_D( char* aData, char* aData2 ) :
           A_B( aData ), iData2( aData2 ) { cout<<"c_d ctor"<

纯虚函数

  • 拥有定义的纯虚函数(这还叫纯虚函数么)可以在子类中进行调用。不过就是什么用都没有罢了。
//定义
inline void A_B::Say() const { cout<<"hey!"; }
//调用,发现hey!并没有打印出来
virtual void Say() const { A_B::Say(); cout<<"c_d says: "<
  • 实际上是否让纯虚函数拥有(没用的)定义由程序员说了算。
  • 但唯一的例外是纯虚析构函数,必须像上面那样进行显式定义 A_B::~A_B() {}
    • 否则就会出现错误,严格来说并非编译错误,而是链接错误。
    • 原因很简单,析构函数和构造函数一样,子类的都会由编译器进行扩充,调用基类的版本。
    • 不希望这么定义的话,解决方法只有生命非纯虚的析构函数

Virtual Specification

  • 不加选择地将函数设定为virtual在效率上会不升反降,不能依赖编译器的优化
  • 应付const也会令人头疼,例如在基类中不需要修改的const ref或者const pointer,到了子类就需要修改了。目前最好的方法是不用const(……无语)
  • 需要考虑到的(不全)
    • 抽象类的构造函数需要负责初始化自己的数据成员,可以声明为protected避免外部访问
    • 缺少多态需求的函数不要设定为virtual,尤其是inline函数
    • 慎用const,除非确定派生类也不会修改const修饰的对象

Read more >>>

《涼宮ハルヒの追想》(凉宫春日的追忆)

近段时间继续攻略之前没玩过的AVG,花了一周多的通勤时间终于打穿了《涼宮ハルヒの追想》(凉宫春日的追忆)这部大作的汉化版。记得发布时候就跳票,好在其游戏质量和时间都足以让人满意。

故事背景是在《消失》之后,所有事件都是紧随《消失》而发生。故事线则是全新的,并且延续了《消失》中重复某一时间段的方式进行,玩家需要收集各种道具利用在选择肢上,不同的选择会引发不同的分支故事。大概背景就是阿虚某天一醒过来发现又是没有凉宫的世界,当然Happy
End就是回到原来的世界。同时这个世界还会不停地循环北高祭这两天的故事——如同《凉宫II》那引发争议的“无尽八月”一样的设定,而这次不仅仅是动画折磨人,玩家需要亲身在游戏中体验,真是充满恶意但又让人恨不起来的企划啊。

另外由于故事设定的场景是北高祭,实际上玩家控制的阿虚在每个时间段的动作——例如前往哪里游玩——也算是另外一种选择,所以这游戏的选择肢系统非常充实,除了刚刚提到的道具选择肢和行动选择肢外,也有下面这种传统意义上的文字类选择:

这几种选择肢中文字类选择中还有很多是“摆设”,也就是选择哪项都会有固定发展。而前两种选择肢比较重要。尤其是道具选择肢,其相关的“时空书签“就是游戏的一大特色。玩家需要在不同的故事线上设定可以返回的书签,以便在拿到需要的道具后快速切换到应用的对话场景中。虽然游戏也提供了SKIP模式可以快速经过已经经历的对话,但合理设定时空书签仍然是节约时间的良策。另外需要注意的是取消掉的时空书签无法重置,也不能随意在当前时间点之前的点上设置。其数量也有限,需要慎重使用。

不同故事线的发展对应不同的END,虽然有的路线是BAD
END,但仍然需要走,因为会出现类似A1线需要A2线的道具才能走下去,而A2线又需要B线的道具的情况,甚至有可能B线会利用之前出现过的线路中发现的道具这种让人觉得抓狂的情况。我就遇到过因为游戏中朝比奈学姐(大)的邮件提醒而没有走完一个线结果怎么也进行不下去的情况,所以忠告大家一定要走到死路或者分歧点为止。除了道具之外,玩家还可以收集其他的东西:

  • 北高祭各个店铺的印章:会以叹号在游览图上进行提示,这个不太好收集,需要非常细心地走完每一条分支。作为速度优先的一周目通关,我大概也就收集到30/120个。惨不忍睹。印章在特典的mini
    game中会有用处,所以还是要多多收集。
  • END:没记错的话应该是21个,其中大家喜闻乐见的应该是只有一个(不肯定),其余的都是各种结局。我现在进度是16/21。这也证明有些路线没有走到。
  • CG和BGM:基本上进度和END是同步的。分别是90个和20个左右。

游戏最设定有朝比奈学姐(大)利用邮件提醒协助玩家上手,路线也比较少。随着故事发展,人物关系和手中的道具开始变化和增多,后期的故事线可能会变成这样:

所以如何分配有限的书签使用,是不走冤枉路的关键。我的策略一般是开头的分歧点设定一个,之后见到有道具出现前的分歧点设定,拿到道具后可以快速返回,而实在走不通了之后也可以回到最初的时间点。

游戏的画面无需多说,京ANI的作品作画上一向安定且让人放心,唯一让人觉得有些别扭的是开头这个立绘,可能是穿上了光阳园学院的制服,让人感觉团长侧脸有些奇怪。但整体上无论是人物立绘、道具、背景都是相当相当细致,

除了立绘之外游戏中还穿插有3D场景,有些是为了表现北高祭中其他摊位的活动情况,有些则是使用了2D效果渲染的3D人物模型,在关键对话(需要进行选择对话内容以推动故事发展)以及关键场景(增强表现力)中会出现:

《追忆》的可视元素和音乐非常出色,完美地保持了《凉宫》系列一贯的风格(OP就是动画第一季经典的“冒险冒险”,并且在内容精细程度上提升(估计是为了PS3版本吧,PSP沾光)。

除此之外,我觉得更难得的是,游戏在故事上也下足了功夫,请回顾一下上面那张时间线(又差点打成世界线)的图,我要说负责剧本和脚本的STAFF们真是辛苦了,要在“重复48小时”这种设定上进行故事的编写,既要体现出统一性又不能搞出太多的重复元素,实在是够难。另外正传中出现的其他人物,例如鹤屋学姐、电研社长、国木田和谷口等都悉数出场,如何安插这些人物的活动也值得考虑。综合考虑,我觉得这是毫无疑问的良心作。

一周目通关已经比较满足,因为没有收集全成就/CG的习惯。所以接下来可能搁置《追忆》,玩一部老作品《Never7》。

Yeah!

昨天看到这里时候我忍不住记录下来了:

作为一个从小学开始看了首钢篮球15年的老球迷,从没像昨晚那样感觉心情舒畅。以前别说打八一能赢40分,基本就是少输当赢。在八一主场更是从没赢过,不管换了几个球馆,八一主场对首钢队来说如同黑洞,球员来来去去换了几十个,鹿指导也从球员打到教练二次上任,依然没赢过。但今年马指导降临之后首钢队明显精气神不同,加上两个强力新人,连三吉这种之前一直被说软的球员都可以持续发挥(参见近几场统计)。

另外不得不提一下李学林,根据统计,他前8场总共助攻30个(场均3.75);失误是多少?说出来吓人,只有4个,而且是4场各1个,其余四场0。7.5的助攻失误比太可怕了。全华班阵容中他的作用从昨天第一节就可以看出来,而可以上外援的时候,无论是双控卫还是学林+莫大爷的组合都是非常可怕。

明天首钢和浙江的比赛有得看。

打自己脸——有关.net对象分配

之前发过的那篇.NET的GC机制和GC知识学习里面有一选项为:

A. 值类型的对象会被分配到Stack上,而引用类型的对象会被分配到Large Object Heap上。

今天在写前一篇Blog时候,发现这句话其实大错特错,虽然这个选项本身就是故意加入了错误,作为选择题答案出现,但此错非彼错。还好题目没有正式使用,不然会被人打脸打得啪啪响。在尚未被人打脸之前还是先自打比较好。先看前半句:

值类型的对象会被分配到Stack上

拿值类型中最常被提到用来和引用类型相比较的Struct来说,它一定分配到Stack上吗?当然不是。这一点题目已经涉及到了,就是大于85k的对象会分配到LOH上。但忽略的一点是一般尺寸的值类型对象也有可能分配到Heap上:

  • 类成员变量,就算是值类型也是在Heap上分配;
  • 局部值类型变量,涉及到和闭包相关的特性时。

第一条就不说了。第二条例如下面这个例子,i和j都是局部值类型变量,他们都在Stack上吗?

private void Form1_Load( object sender, EventArgs e ) {
    int j = 0;
    int i = 0;
    Func foo = () => {
        return i;
    };
}
当然是否定的,拿出il代码看一下就明了:从声明上来看,j的确是在Stack上没错,但i却是依附在一个编译器自动生成的类<>c__DisplayClass3上面;进行赋值时候i用的是stfld而不是stloc。这也就是说对于闭包涉及到的局部变量而言,CLR会将其依附到一个自动生成的类上进行存取操作,那么它自然就不分配到Stack上了。
.method private hidebysig instance void  Form1_Load(object sender,
class [mscorlib]System.EventArgs e) cil managed
{
// 代码大小       31 (0x1f)
.maxstack  3
.locals init ([0] int32 j,
[1] class [System.Core]System.Func`1 foo,
[2] class WindowsFormsApplication1.Form1/'<>c__DisplayClass3' 'CS$<>8__locals4')
IL_0000:  newobj     instance void WindowsFormsApplication1.Form1/'<>c__DisplayClass3'::.ctor()
IL_0005:  stloc.2
IL_0006:  nop
IL_0007:  ldc.i4.0
IL_0008:  stloc.0
IL_0009:  ldloc.2
IL_000a:  ldc.i4.0
IL_000b:  stfld      int32 WindowsFormsApplication1.Form1/'<>c__DisplayClass3'::i
IL_0010:  ldloc.2
IL_0011:  ldftn      instance int32 WindowsFormsApplication1.Form1/'<>c__DisplayClass3'::'
b__2'()
IL_0017:  newobj     instance void class [System.Core]System.Func`1::.ctor(object,
native int)
IL_001c:  stloc.1
IL_001d:  nop
IL_001e:  ret
} // end of method Form1::Form1_Load

另外漏了一点,在更正:值类型并不总是分配在栈上一文中提到,还有一种会被分配到Heap上的值类型:

  • 数组内的值类型对象,会被一同分配到Heap上。