香港佔中事件的一点感慨

十一期间最关注的就是香港的佔中事件了吧。我不是港人,也一次都没去过香港,这个事情我没有什么品头论足的权利。

不过还是有些感悟,自言自语,也不会妨碍到谁。

1. 在近来埃及政变、乌克兰内战的此时,如果说相似的事件不引人联想是不可能的。我自然不知道香港的情况是怎样的,不可能妄下断言,但是对“非暴力不合作”这样的旗号确实有些厌烦了。

2. 无论“民主”好还是不好,香港、包括大陆的政治模式是否会逐渐改变,是“改善”还是“恶化”,我都无法去猜测。但可以想到的是,游行示威,和平集会,一定是会越来越多的,不光是香港、也包括大陆的大中小城市。这可以说是一种自然发生的情形,无需去考虑它到底是好还是不好,我想这也无需去论证。所以无论对于民众而言,对于政党而言,如何去面对这样的环境,应当学会去适应,这可谓是生存技巧。而掌握这种技巧,对于民众的要求而言,需要更关心政治,并且学会独立思考,否则谁知道你上街游行甚至被逮捕,是为了自己的利益,还是被他人所利用。而对于政府而言,则意味着对此类事件以更聪明和谨慎的方式处理,对不同的声音更加宽容。我想,如果有了这样的变化,大家对这样的环境更加适应,总的来说,还是向好的方向发展的吧。

3. “通”而不是“堵”,是我们古老祖先留下的智慧,否则在这块华夏土地上存在并且壮大起来的恐怕也不是自称炎黄子孙的族群了。这个道理,我想无论对于想要解决事件的一方,还是对于想要有所诉求的一方来说,都是重要的。西洋人会问“存在还是毁灭”,我们的祖先却说“一阴一阳之谓道”,这是我们血液中流淌着的生存哲学。如果翻译成现代汉语,当你问我“民主还是专制”的时候,我回答你“民主即是专制,专制也即民主”,你一定会骂我狗屁不通,但这样的“愚”中或许藏有“大智”。

说到这里忽然非常感慨小平先生对我们国家所用的救命良药,充满了我们先人的大智慧。如今我们仍然需要同样的智慧,才能让我们的民族继续生活在这样一片我们所热爱的土地上。

痴汉人生

一转眼发现已经快半年没有写博客了,上一篇bo还是去年10月份的。

自我安慰一下,这一段时间倒没有虚度,还是读了不少书,见了不少世面的。对人生的看法也慢慢有了新的理解。最近读了一本书,《醉汉的脚步》,我非常喜欢。这是一本讲概率的书,我本是因为,对于“随机性”这个问题,其真实的含义到底是什么,没有足够的认识,正好在网上看到这本书的风评很好,就买来读读。没想到这居然成了一本洗刷我的三观的书。

随机这个东西,究竟是什么意思,一直找不到最好的方式去理解。当然并不是说数学课讲的期望啊方差啊这些东西没学会。不是的。问题是这些都只是从一个侧面去描写一种随机分布的指标,却仍然不能知道随机事件发生时,到底是什么样子的。比如抛一枚硬币,1/2概率是正面,1/2概率是反面。这个1/2究竟是什么意思呢?并不是说,每抛两次硬币就会出一次正面。说抛100次硬币,出现50次正面的概率最大,这种说法似乎是对的。但假如前99次中出现50次反面,49次正面,也不意味下一次抛硬币出现正面的概率会更大。事实上,假设前99次连续抛出反面,下一次抛硬币,出现反面和出现正面的概率还是一样。理论上会计算概率,并不表示直观上理解了概率到底是什么意思。

读《醉汉的脚步》这本书,让我收获颇丰。其第一点,就是告诉我,概率是用来分析那些人类理解不了的事物的。文中提到,人类会习惯性的寻找规律,其中的例子很有趣,给被实验者观察一串连续的颜色变化,红绿红红绿红红红绿……实际上,红色和绿色出现毫无规律,完全随机,只是红色出现的概率是2/3,绿色出现的概率是1/3。但是受试者会情不自禁地分析这段颜色出现的规律,例如上面一段,可能会分析出下一组应当是红红红红绿。因此如果让受试者去猜下一个颜色是什么,很可能会猜错。而同样的实验受试者换成老鼠,它猜测下一个永远会猜红色,因为红色的几率高嘛。结果老鼠的得分反而比人类的得分高。

这一下就解决了我自认“理解不了概率”这个问题。我所说的“理解不了概率”其大概的意思,或许是说,即使知道了概率,也还是不明白按这样的概率运行的事物(无论是抛硬币、股市、足球的胜负还是人生的浮沉、世界的治乱),其运行的规律究竟如何。而这一解释是自明的,正是因为无法明了其运行的规律,才不得不用概率去归纳。概率是无需“理解”的,只需“知道”即可。如果硬要“理解”,就像上述实验中的人类受试者一样,硬要从一堆随机的信号中寻求规律,结果反倒输给老鼠。

这本书给我的另一个收获,是“贵在坚持”的另外一种解释。概率,是要通过统计,得出的。而概率影响的范围之广,上至全球金融、政治,下至日常生活,黄油面包,无处不在。连续抛3次硬币,都出现正面,并不能就此确信,这个硬币不平衡。连续3次猜拳输给对手,并不能认为对手一定有超能力。然而,连续3年业绩低迷的基金经理人会被开除,连续3次点球罚失的球星会坐冷板凳,或许连续3次失恋的少男少女也会对生活失去希望。而岂不知人生处处都有随机性存在,而区区3次失败,并不具备任何统计意义上的证据可以说明被观察的对象本身品质有严重缺陷。可惜的是人生短暂,往往等不及几十次上百次的测试,再去挑选那个千锤百炼的好手。俗语说,事不过三,往往以三次为界。这也是无可奈何的事情。只是作为审查者,不应只根据业绩、成绩,去评价一个人,而更多从多方综合因素去冷静分析评估;作为被审查者,即使遭遇连续的挫折,假定相信自己的路是有道理的,就不应仅因为业绩、成绩,就放弃自己的路。当然这是万难的。这也是因为,人类习惯性的从现象中试图分析出规律,而往往许多事情,股票的走势、考生的成绩、足球的比分,其实没有什么办法可以准确预测的。当你看到连续的下跌,或许这仅仅是一个波动。

这让我想起庄子的话,“朝菌不知晦宿,蟪蛄不知春秋”,“小智不及大智,小年不及大年”。人生短暂,像是用放大镜去观察印象派油画的一角,看到的仅仅是斑斑驳驳的色点,可谓瞎子摸象,管中窥豹。当然,这是人类固有的局限性,不可能就此超越。但知道自己具有这样的局限性,“认识你自己”,总比认识不到自己的局限性要略好一些吧。犹如五十步笑百步,如能知道自己是五十步,而能不笑百步,就可以说是巨大的进步了。

当然这本书内容很丰富,绝不仅这一点营养。只是拿出我最受震动的部分记录一下而已。也是因为自己荒废博客许久,作为给自己的一个小小的交代吧。接下来的时间里,还是要不停地学习不停地进步。争取博客也不要荒废,更多地记录自己的见闻吧。

恭喜银桑成功升级为银他妈~~

前两天银桑闹腾得特别厉害,到周二晚上周三凌晨,那一宿就没让我睡,拼命想叼着我的手拉我到他躲着的墙角里去。。
一开始搞不明白什么意思,到了凌晨三四点钟终于悟了,估计是快要生了(对了,之前没搞清银桑的性别就给他起名字了,实际人家是姐姐。。才不是大叔呢)

IMAG0290
刚出生的小猫湿淋淋的,银他妈在帮他们舔毛

正好最近买了笼子要带他搬家,就奉献了自己的枕巾跟毛巾被,把笼子里面垫好外面包好,给他一个谁也看不见的封闭空间。一弄好都不用我招呼他自己就钻进去了,也不像之前一样哀嚎折腾我了。我也是一宿没睡就死猪一样瘫床上睡过去了。没想到到了早晨八点钟被闹钟闹醒一看,银桑已经生完了!直接升级为银他妈!想想猫咪也真是厉害,都是自己给自己助产的。淌了一阳台的血(羊水?)。。我趴下去往里一瞧,四只小家伙都挤在银他妈怀里吃奶呢,还不会喵叫,发出像家禽一样细声细气的叫声,萌萌的。

小猫出生没两天毛就长全了,四只都是白猫啊!
小猫出生没两天毛就长全了,四只都是白猫啊!

当了妈的银桑比以前老实多了,不再到处乱跑,这两天也不在夜间折腾我了。对啊人家要照顾孩子啊。好几次跑到我身边像往常一样撒娇,还没蹭两下就赶紧跑回去招呼孩子们了。

嘿嘿,不知为啥,看着这样的一家子有一种安心的感觉。莫名的“幸福”感吧。希望能把这一家子养活~等小猫三个月大了可以送人~~

又是命名法

命名法是个我不想再纠结的东西,不过最近又遇上了…
碰巧过完年,脑子锈掉了,居然读不懂自己年前写的代码了。我向来奉行“代码即注释”原则,也就是说…几乎不写注释…完全依靠函数和变量命名的含义来表达代码的意图和思路,除非真有复杂到需要注释的地方,例如莫名其妙的需要多线程同步的地方之外,其余一律不写注释。不过反作用就是,年前那阵子贪玩,没认真好好写代码,导致命名有点糟糕,过了年回来再读就有点绕人了…

一边改那些变量的名字,一边就遇到这个命名法的问题。我还在用匈牙利前缀,整数用n,浮点数用f,字符串用sz。现在需要自己增加几个自己的规则。
iterator类型,我原先用it做前缀,打出的代码看上去非常丑陋,例如:


for(std::vector<Phone>::iterator itPhone = phoneList.begin(), 
    itPhoneEnd = phoneList.end(); itPhone != itPhoneEnd; ++itPhone) {
  //...
}

单纯就觉得这两个字母放在前面不搭,不美…现在我用小写t做前缀,好看多了。


for(std::vector<Phone>::iterator tPhone = phoneList.begin(),
    tPhoneEnd = phoneList.end(); tPhone != tPhoneEnd; ++tPhone) {
  //...
}

当然了,这是古董代码了,有了foreach,这样的代码已经可以进垃圾堆了。不过难免用到iterator的时候俺就该记得用这个t前缀。还有就是项目里的代码我不想霰弹枪一起动,先这样放着比乱改安全很多…

受这个启发,typedef出来的变量类型用大写T前缀,例如


typedef std::vector<Phone> TPhoneList; 
for(TPhoneList::iterator tPhone = phoneList.begin(), 
    tPhoneEnd = phoneList.end(); tPhone != tPhoneEnd; ++tPhone) {
  //...
}

我喜欢typedef出几个项目中常用的容器类型。仅仅到容器类型,而iterator类型直接使用Type::iterator引用,而不进一步typedef。这样恰好保持代码的简洁程度适中,容易理解。

std::string类型用str前缀,而raw string类型(0结尾的字节序列)用sz类型,从而区分两者。这一点通常不重要,但是当你使用printf的时候:


std::string strName = "Peter Pan";
printf("hello %s\n", strName.c_str());

str前缀会提醒你记得用上c_str()方法。事实上这个问题惹恼我好几回了,最倒霉的一回是同事从北京打电话跟我联调,他那边输出的log出现乱码,而我这边丝毫没有,他通过IM给我看输出,告诉我printf打出来的。我不相信我的眼睛,好像就是变戏法。直到调了好久他才突然说,噢!忘记.c_str()了!
当然这仍旧不是好方法。真正问题出在printf不是一个类型安全的函数,编译器无法为你做编译时检查。但是类似printf, sprintf这类函数使用方便,即使最终产品不使用,调试阶段输出log还是会经常使用的。这个时候区分std::string和raw string就变得有意义了。

堆上空间使用p前缀,而栈上空间不使用。这里主要说的是数组。主要目的是当你使用p前缀的变量时候,就会提醒着自己记得思考该让谁delete掉他这个问题了。
例如


char szName[] = "Peter Pan";
char* pszName = new char[10];

我忽然在思考,是不是应该用q前缀来命名那些堆空间的拥有者,而用p前缀来命名那些弱引用。但如果是这样,那么不明拥有者,或者拥有者变更的情况怎么办?再引入一个ps前缀(p_shared_)?也许会弄得太复杂了。也许既然想了这么多,还不如一开始就用智能指针。为什么我不想引入智能指针?我不想引入复杂度。因此如果仅仅为了区区命名而导致复杂度增加,还不如一开始就简单化。所以还是所有指针都用p前缀。到底谁负责,自己好好想清楚。我想,引导读程序的人思考,比用带有暗示意味却可能是错误的命名要好得多。
在使用弱引用时,我经常使用的名字,例如pRead, pWrite, pBegin, pEnd, pCurrent, 等等,这些名字具有强烈的暗示性,说明他们是弱引用,正常人是不会去释放这样名称的变量的,更不会给这样的变量开辟空间。而另一些名字则比较危险,比如pNext, pChild, pParent, pSibling。这些名字的变量,可能你需要去释放他,可能你不需要(例如这是一个树状数组)。这个时候注释是必须的,否则很可能今天写的代码,明天就忽然觉得,不对,这里既然pNext被移动了,那么原来那个东西就应该先释放掉。然后Boom!程序崩溃。还好,现代程序员几乎不需要自己编写类似这样的基础数据结构,直接用酒精久经考验的标准库就行了。而且,就算偶尔碰上了,只要仔细调试通过,以后几乎不会再去改他了(毕竟最多的改动还是在上层嘛)。所以不算什么太大的麻烦。

呜,暂时想记录的就这么多了,给以后想要偷懒的自己看。

[感动]命运石之门

看了这个片子咱整个人都中二了。。
中二拯救世界的神作orz|||

Hacking to the Gate

咱貌似也泪点无限降低了。。这片子咱看到第三周目的时候,还没看完OP就已经内牛满面了|||

数十亿もの 鼓动の数さえ
数十亿的 心灵跳动
あなたには 瞬き程度の些事な等级
对你而言 不过是眨眼工夫的琐事
过去に囚われて  未来を叹くも
无论对过去的执迷 还是对未来的叹息
尘一つ 误算を许さぬ必然
皆是不准有丝毫误算的必然

『无限』に広がる梦も 描く未来も
『无限』膨胀的梦想 与理想的未来
仆达に许された 虚栄の権利
是我们应得 虚荣的权利
『有限』それは二つの 针が示す
『有限』那即是两根针所指示
残酷な约定と 选択へ
残酷的约定 与抉择
Hacking to the Gate!

だからいま 1秒ごとに 世界线を越えて
所以现在 越过每一秒的世界线
君のその笑颜 守りたいのさ
只因想要守护 你的笑容
そしてまた 悲しみの无い 时间のループへと
于是又再堕入 没有悲伤的时间回流
饮み込まれてゆく
逐渐被吞噬
孤独の観测者
孤独的观测者

命の主张と 无意味な证明
生命的论点 与无意义的证明
あなたには 退屈しのぎに足らぬ滑稽
对你而言是 就连消遣也不足以的滑稽
支配者きどりの 愚かな种族は
自称支配者 愚蠢的种族
うぬぼれた 稚拙な定理を并べた
自大地陈列 幼稚的定理

『无限』と信じた爱も 空の彼方も
『无限』爱的信心 和天空的彼方
仆达に示された 仮想の自由
皆是我们眼前 幻想的自由
『有限』それは无慈悲に 时を刻み
『有限』是让时间无情流逝
明日さえも否定する 选択へ
不惜否定明天的选择
Hacking to the Gate!

いくつもの 辉ける日々 仲间との约束
几度闪耀的日子 与同伴的约定
无かった事には してはいけない
不能就这样敷衍了事
そのために 时を欺く 残された仕挂けに
为此 欺骗时间 面对剩下的机关
もう迷いはない
不会再迷惘
孤独の観测者
孤独的观测者

だからいま 1秒ごとに 世界线を越えて
所以现在 越过每一秒的世界线
君のその笑颜 守りたいのさ
只因想要守护你的笑容
そしてまた 悲しみの无い 时间のループへと
于是又再堕入没有悲伤的时间回流
饮み込まれてゆく
逐渐被吞噬
孤独の観测者
孤独的观测者

人类智慧形态研究

上一篇讨论集合论的博客,我说会提出几个问题来支撑自己继续探索下去。而在归纳总结了自己的几个问题之后发现,多数问题是指向人类智慧形式本身的。

我在那篇博客中说,我认为集合论是一个企图解释全宇宙的终极理论。现在我改变了自己的想法。正好相反,集合论其实并非是解释宇宙的理论。解释宇宙这件事情,需要经验科学来完成。集合论其实是解释人类逻辑思维方式的终极理论。为什么我之前会认为,集合论有能力解释全宇宙呢?其实是这样的,首先,我假设人类有能力提出解释宇宙的理论,然后,集合论能够解释提出这个理论的人类的智慧的形式,并且能够构造出这种人类智慧形式所包含的全部知识。假如前提假设是正确的,人类确实能提出解释宇宙的理论,那么集合论自然能够涵盖这个理论啦。

因此这里提出的问题一就是,人类是否能提出解释整个宇宙的终极理论?

根据哥德尔不完备定理,任何图灵等价的构造都是不完备的,任何由可数无穷多个公理构造的定理集合都是不完备的。因此,假如说,人类智慧的形式其实是图灵等价的话,或者说,人类智慧所可能构造出的知识内容如果是可数无穷集合的话,那么,人类的理论体系很有可能是永远都无法完备的。但是,我相信,我们的宇宙应该是自洽的,因为“存在即合理”应该是凌驾于任何先验知识之上的经验公理。假如真的是这样,那么人类很有可能永远无法参透宇宙的奥秘。当然,其实这也是一个好消息。上帝、灵魂、地狱等等概念都有他们容身的场所,可以供那些“开天眼”,智慧超越人类可悲的知识集合的神棍们观测和研学。

所以这个问题其实归结为,人类智慧是否真的是图灵等价的?如果说是这样的话,马上就能得出一个结论,那就是人工智能一定能够成功。因为现代计算机就是图灵等价的。如果说人类智慧是图灵可计算的,则,只要随着科学的发展,早晚有一天能够用计算机创造出不可思议的智慧生命出来。硅基地球文明早晚将会诞生。

到目前为止,我倾向于认为,至少,我希望,上述两个问题的答案都是否定的。我认为人类智慧形式应该是超越图灵机的,并且,至少我希望,人类智慧能够无限逼近自然真理。同时,我不愿相信仅靠机械计算就能创造生命,无论那种计算模型有多么复杂,最终无非是确定有限自动机。

好了接下来我想问的是一个比较弱智的问题。就是,对于确定有限自动机而言,每个输入都有一个唯一的确切的输出。这样的构造是图灵等价的。假如,假如我给这个机械的模型加上随机参数呢?不是伪随机数,而是真正的随机数。举例而言,利用量子计算机的技术,对一个输入,有一定的概率产生一个输出,还有一定概率产生另一个输出。假如说自动机设计成这个样子,他还是图灵等价的吗?我在这方面没有做过研究,仅仅是初步想到他,所以不敢乱讲。我准备接下来查一些论文,看看有没有人做这方面的研究。
我看过一个量子算法,就是利用量子能够产生“真正的随机数”这个特性,来实现傅立叶变换,把时间复杂度降低了一个数量级。即使量子计算机的物理实现非常困难,其数学模型完全可以提前建立。因为利用到量子的地方,仅仅是他的产生随机数的能力罢了。我也知道在这个领域已经有前人研究了很多年了。我不清楚,是否量子计算机,仅仅给计算模型添加了真随机的能力,就能解决掉P = NP的问题。如果说真的是这样,这个世界未来的样貌将会是大大改观的。有可能,甚至要突破贝尔定律,知识爆炸的速度或许会以比指数还要快的速度疯狂增长。那个时候的人类智慧跟现在还会是同构的吗?或许还是。或许,人脑的计算模型就是如同量子计算机般充满了随机性的。这非常符合我们的经验。一个人刚做的决定,立刻就会后悔。同样的人有状态好坏之分,今天做得出的题目,明天就抓破头皮也解不出来。明明熟悉的老同学,嚼烂了舌头也想不起他的名字。这样的事情是很多的。是不是这就是因为,人脑其实充分利用了随机性呢?会不会说,带有随机性的自动机,比“确定有限”自动机所能表达的逻辑要复杂更多,是超越图灵计算能力的呢?
因为在这方面没有做过研究,所以不敢乱讲。这也是我接下来继续学习领悟集合论的一个重要的推动力。

另外我还有一个问题。就是,根据我的初步理解,似乎无论在自然数集合上做什么样的计算,都不可能构造出实数集合。无论是加也好,乘也好,乘方也好,自然数集合再怎么倒腾,到底还是可数无穷集合。所以我忽然觉得很奇怪的就是,实数,是不是真的实实在在存在的数呢?虽然说从古希腊就有人证明了存在根号2这样的数。可是这样的数毕竟是人脑构造出来的数。自然界中是否真的存在呢?

因为,实数集如果真实存在的话,哪怕仅仅是其中的一小段,例如[0, 1)的这样一个区间存在的话(这小小的一个区间其实等价于整个实数集),它包含的信息量都超过了全宇宙能量的总和。当然这是建立在,宇宙的大小和生命都是有限的这个假设之下的。我非常喜欢宇宙有限这个理论。在这样的假设下建立的宇宙模型简单而且容易解释。有着无限时间的宇宙,应该早就,在无穷早之前,就进入热寂了(熵不停增大直到极值的状态),有着无限能量的宇宙,也理应在无穷大的引力下崩塌;地球(如果存在)理应被从四面八方射来的无穷的星光灼烧成渣。
那么,如果宇宙蕴含的能量是有限的话,他蕴含的信息量是不是就一定也是有限的呢。或者至少是可数无穷多的呢。一个有限能量构成的基本粒子,假设他其实并不是“基本”的,而是其实蕴含着更大的信息量。假设他还是可以继续再分的。据我了解,物理学当前认为的最小粒子是夸克,并且据我所知夸克还没有被制造出能够独立存在的。我们暂且假设他还可以再再分,例如说,我们用半个宇宙的能量去轰击他,让他产生不可思议的巨大爆炸,也许在这持久的爆炸中,夸克乃至更小的粒子就能独立存在一段时间。我们继续用更大的能量去轰击他,用99%的宇宙能量,会怎么样呢?最终,我们用除了这个粒子之外的全部宇宙所含的能量去轰击他。没有更大的能量了。因为能够轰击一个粒子的能量最终是有限的,所以粒子可分的等级,应该就是有限的。更小的等级,在当前宇宙是观测不到的。我个人还是倾向于经验主义,观测不到的物理量应该就是不存在的。至少他对当前宇宙没有任何贡献,因此存在与否是没有意义的。同时,全宇宙所有粒子的总和一定是一个有限值。那么由有限个粒子构成的集合,其中每个粒子都是一个在有限步骤内就会定义完毕的有限集合。他们在每个时间点上都具有有限的信息量。因此最后,就差一个量可以决定宇宙信息量的基数,那就是时间。假如时间是量子化的,存在不可再分的最小时间间隔,那么这个宇宙的总信息量就是可数无穷多的。假如时间是连续的,总能找到两个时间点之间的时间点。那么,宇宙就是连续变化的,它虽然在每个特定的时间点无法包含无穷的信息量,但只要乘以时间这个维度,就立即包含了无穷的信息量了。
为什么上述讨论中只用到时间这一个量,而不说四维时空呢?在我看来这里时间和空间是等价的。假如时间固定,每个粒子在空间中的位置(三维坐标)都是固定的。当然,存在很多“实数”坐标值。但这些实数的数量却是有限多的(因为粒子的数量是有限多的),因此,这些实数的坐标值其实是可以跟一个有限集合内的元素一一对应的,只是他的物理含义不相同而已。只有当时间可以连续运转的时候,才有可能让一个运动着的粒子沿着一段曲线运动,从而产生出与实数集基数相等的那么多个三维坐标点。

因此,空间的连续性和时间的连续性其实就是等价的。假如说,虽然时间是连续的,但是空间却是量子化的,在每一段连续的时间点上,一个粒子都呆在原地不动,直到另一个时间段,他忽然“跃迁”到下一个空间坐标上去了。假如是这样的,假设存在连续的时间就没有意义了。因为你没有办法观测到他。在一次的,我用奥坎姆剃刀剔除不可观测的额外假设。

因为对当今的物理学发展并不十分了解,我不知道是否证实了时间的连续性。因此这里作为一个问题放在这里吧。

这个问题其实是深深刺入宇宙本源的。因为,假如时空真的如我上述讨论,是量子化的,则宇宙其实就是一个自动机!那么很有可能,他就是图灵等价的!如果真的是那样,那么宿命论就是真的。当然,这里还有一个悬而未决的问题,就是量子计算机能否让计算机突破图灵可计算的边界。但是,进一步的,假如时间是量子化的,但是真随机有限自动机超越图灵,至少我们可以制造真随机有限自动机来模拟宇宙。同时,真随机有限自动机将成为真正的人工智能!因为,宇宙是真随机有限自动机等价,所以宇宙能够创造出来的生命,量子计算机就理应能够(在有限时间内)将生命(不仅仅是人工智能,而且他还是货真价实的生命体)创造出来。

哇,看来集合论果然是必须要学的重要学科啊!!很有可能他就包含了宇宙的真理哟!

搞清C++虚继承

c++虚继承平时很少用到,看书的时候也就是理解个大概。
这次实践中使用到了虚继承,总算有了具体的印象。

基类thunk怎么在子类对象里堆叠的,咱就不赘述了,反正网上、教科书上到处都有讲。这次咱自己遇到的问题主要是虚继承和普通多重继承没搞清区别。

我有一套虚接口hierarchy.


class View {
   virtual int ID() = 0;
   virtual int Child() = 0;
};

class TextView : public {
   virtual const char* getText() = 0;
};

此处省去代码数百行。。。

之后当我开始做这套虚接口的一组实现时,才发现问题。


class SysView : public View {
    virtual int ID();
    virtual int Child();
};

到这里还是都正常的。


class SysTextView : public SysView, public TextView
{
     virtual const char* getText();
};

当实现这个类时,就会发现其对象无法实例化。因为View下面的虚接口没有实现。咦,不是继承了SysView而SysView实现了View下面的所有虚接口吗?问题没有这么简单。因为这个是多重继承,每个父类都会在子类中产生一个拷贝,所以SysTextView里面就出现了两个View类型的父对象。一个是SysView,一个是TextView。而TextView没有实现View的虚接口,因此这个类整个就都不能实例化了。

解决方案就是必须使用虚继承,让编译器知道,TextView继承的那个View和SysView继承的那个View,是同一个View。则需要修改的代码如下:


class SysView: virtual public View {
///...
};

class TextView : virtual public View {
///...
};

注意SysTextView并不需要对其两个父类进行虚继承,除非hierarchy下面还有对这个类进行多继承的情况出现。

虚继承会影响系统性能,应尽量避免。这里用到这个逻辑,只是为了能够使用工厂方法较为优美地创建出各种不同类型的对象,然后调用其虚接口完成操作。并不是性能瓶颈。呜长久以来一个知识漏洞终于通过一次实践补上了。挺好。

生活就是改变世界

今天无聊地想着一个基本粒子的议题的时候,忽然想跑题了。

本来是从,想像,切割一块石头,越切越小,还是石头,究竟什么时候,切那么一下,就不再是石头了,这个话题想起的。

结果忽然发现,其实不对。本来是大石头的,你切了那么一下,就变成小石头了。

无论是石头也好,任何东西也好,你对他产生影响,甚至你只是看了它一眼,你就改变了它(或者说它改变了你)。其实任何人,随时随地,不管睡着醒着,都一直在改变着这个世界。即使死掉了,对这个世界的改变仍然存在,并汇合到整个世界变化的洪流中去,成为历史的不可磨灭的一分子。

所谓生活,其实就是对想要什么样的一个世界,做出选择,并且执行,这样一个过程。

所谓自由,其实就是对想要将世界改变成什么样子,保留的那么一点点权利。

但是,是不是自由就是说,想让世界变成什么样子,世界就会变成什么样子呢?当然不可能。那样的世界与其说是天堂,不如说是地狱。

想要改变世界,总要付出代价的。只是代价有大有小罢了。并非将这个世界改变成理想的状态不可能,只是多数人付不起那个代价罢了(当然你可以说聚集所有人的力量共同来偿付这个代价,问题是不同人的“理想的世界”是决然不同的,所以就像建造巴别巨塔,最终只有失败)。但是只要你付出了代价,对这个世界的改变就是永续的。正如我前面所说的,它将会永远汇合进历史的洪流中去。哪怕你只是随手扔了一片纸屑,或者(如同我现在)随手写了两句博客,都改变了这个世界,产生了或这样或那样的影响。甚至你什么都不说,什么都不做,只是默默地看着这个世界,也一定对这个世界产生了或这样或那样的影响。并不一定是说蝴蝶效应。也有可能,虽然这个影响非常非常小,完全可以忽略,但是历史是不可磨灭的,是不会后退的。随手扔掉的纸屑,你再也没有机会回到那个曾经,去让自己不要扔出那一片。所有对世界的微小影响,最终都会积累起来,汇合到滔滔不绝的时间之河中去,最终成为乾坤调转的重大转折。

所以说嘛,“活着有什么意义”,“人为什么要活着”,从结果上来说,就是改变这个世界。或者说,要保持这个世界防止他改变,这从另一个角度上来说,其实也是改变这个世界。当然不要忘记,自己也是属于世界的一部分。改变世界,同时也是改变自己。或者反过来说也正确,改变自己,就是在改变整个世界。

或者又反过来说,其实这个世界就是我们改变出来的。这个世界从来都是我们想要的。只不过,不是你一个人想要的,而是从古至今无数人类不懈努力,共同改变出来的样子。是全人类想要的世界。

所谓“理想”是不能达到的,其实说的是一个人的理想。我们的这个世界,其实就是全人类的共同的,活着的理想!

系统的民主和独裁

关于系统设计,我想到了两件事情

从性能的角度考虑,系统设计应该尽可能隔离物理设备,向用户提供透明的接口。最好让所有的东西都是普通的变量。例如,为什么要区分内存上的结构体和磁盘里的文件呢?完全可以让用户认为,定义一个变量,他就在内存里,又随时可以固化到磁盘上。至于这个变量,实际上放在哪里,由操作系统决定。例如一个很复杂的结构体数组,就可以开辟在磁盘上,并作内存上的缓冲。当然这种做法其实跟现在系统的内存分页调度方式最终结果是类似的。但是如果一开始选择权就在系统的话,自由度更大。

从这个角度考虑下去,很容易想到的就是文件的结构化管理。为什么二进制文件比纯文本文件更难读懂?因为二进制文件没有统一的管理模式。同样是二进制的,c语言里调试结构体的时候就完全不会觉得费力,为什么呢?因为头文件里声明了结构体的各成员类型。如果能把结构体的声明嵌套在二进制文件里,使其成为自解释的,则二进制文件能够充分发挥其存取方便、节约空间的好处,同时防止其调试困难人类难以理解的缺点。既然文件头的规范已成定则,完全可以考虑把文件的结构声明放在文件尾。当然需要订立标准。假如让我来设计草案的话,可以如下所述:

(1) 为了兼容现有文件结构,自解释信息放在文件末尾,紧接在原始文件的后面。使用特殊的头部以区分其他文件。

(2) 文件结构为树状结构,从根部开始,使用“描述块”来描述每个节点的数据结构定义,直至叶子节点。

(3) 叶子节点使用字节数表示其单位大小

(4) 父节点可以是数组*、结构体

这里有一个需要讨论的问题,就是当父节点是数组的时候,如何确定数组的长度。通常有两种做法决定数组的长度,一者是使用特殊标记的结束符号,二者是使用一个数组长度的数值来确定。当数组长度非常长的时候,可能32位int无法表示,可以总是使用64位int又会浪费空间,假如未来出现超级巨大存储器,甚至可能64位int都不够表示,还需要更加巨大的数字。所以我认为使用结束符号表示数组结尾是更好的方法。当然由于这里只是YY,可以随便想。例如也可以使用一个配置选项来决定使用哪种方式表示。

另外结构体的表示,当其成员用到其他已定义的成员时,也可以使用序号表示那个成员的结构声明。

使用这样的一种方法,程序员想要操作文件系统时将会非常轻松,例如配置文件,可以认为是使用换行符隔开的一系列字符数组。每一个换行符隔开的行单元可以单独地被交换到内存,或者写回文件。由于在文件定义的时候就确定了文件是以行为单位独立的,操作系统在这个层次可以做大量优化。例如并行程序读写不同行时文件无需加锁,而是将这两个被读写的行交换到内存中进行操作。例如编译文件,在某一行插入时,不必对文件的后面部分依次推后重新写回,而可以只在那一个行上做内存缓冲和读写,当系统空闲或卸载磁盘前再做写磁盘操作(大大提高并行性并减少磁盘写数量)。对于大文件,系统可以自动对行进行索引,从而提高随机读写行的性能,等等等等。

另外能够方便程序员的是,这样的文件由于已经附加了结构说明,只需复制这个文件,无需附加其他说明,就可在其他的程序员那里方便地阅读和使用。例如一个游戏的资源包文件,其实是一个复杂的树状结构。如果附加定义清晰的结构说明,其他程序员即使没有源代码也可以轻松地理解其内容。当然如果为了保密,可在发布时去掉文件说明。由于仅是附加在文件尾的部分,去掉也不会对文件本身造成任何影响。

在这个角度YY得太多了。总之这样的思路就是,操作系统完全是独裁的,程序员只能提请求,但这个请求究竟以什么样的方式实现,有操作系统来决定。好处是,系统所处的地位比应用程序高很多。系统知道现在全局资源的情况。总的内存占用、磁盘访问频率、网络流量(甚至可以考虑将部分数据上传到云端作为一种持久化措施,程序员请求固化一段内容,甚至可以不知道是固化在本地了还是在云端了),等等,这些东西作为一个应用程序是没办法想太多的,想太多容易“过早优化”,可是完全不想最后查性能瓶颈又是各种麻烦。如果系统能够智慧地处理各种情况,根据当前系统状态动态选择最合适的策略,则系统性能可以做到最优化,硬件使用率可以达到最高。

但这只是从系统的角度考虑。

假如从应用程序的角度考虑呢?假如我是应用程序的开发者,我绝对不喜欢操作系统额外做很多事。我希望我做的事情没有副作用,可确定。这也能方便我调试,方便我bug复现。例如,假如真的系统可能把数据固化到云端,假如网络通讯部分驱动有bug,可能我请求一个变量,十次有三次不成功,七次成功。因为恰好那三次定义到云端了,而后来的七次定义在本地。如果是这样,一旦程序复杂,bug丛生,程序员会气急败坏。相信程序员,把一切都交给程序员,这就是Unix的系统逻辑。一个绝对民主的系统。

可是,当权利交给程序员的时候,程序员就成为独裁者了。好的代码自然能够绝对有效地利用系统提供的资源,但坏的代码不仅自身运行不好,还会占用其他程序的资源和空间,让其他程序都变得缓慢甚至无法运行。让应用程序在他可见的那个狭窄范围内,做系统级的性能优化决策,又实在太为难应用程序员了吧。相比无数应用程序群氓的独裁,莫不如系统一个人的独裁可靠一些。因为只需把一个系统做好,就可以让所有的应用程序有好的表现。或许这个思路更好?

chrome app store in new tab

Recently Google began to put app store things into chrome new tab page.

I found this on ubuntu with chromium 9.0.597.94 (73967).

It’s pretty cool and I tried a lot of things, like my favorite  flash game Canabalt, google Talk and so on.

The apps web page is also become more attractive, comparing with chrome extension web pages.

I tried google talk app the first time I saw it, and it turned to be Chrome OS only… Google is definitely working on making Chrome OS special, and unfortunately, exclusive. I really don’t like the way as Apple goes, but on the other hand, the open minded Android market is not such a success as well.