善意提醒

如果您打开本站很慢,布局排版混乱,并且看不到图片,那么可能是因为您还没有掌握用科学的方法上网的本领。

2013-09-06

一例 C000001D 错误的分析

公司客服收到用户反映,说我们的软件使用到某个功能的时候,报了一个错误。错误信息只有「External exception C000001D」这么一段文字。

搜一下 C000001D,很容易就能知道对应的含义是 STATUS_ILLEGAL_INSTRUCTION,也就是说程序使用了当前 CPU 所不支持的指令集。我们自己的程序并没有使用太新的指令集,但有一些第三方的接口库可就未必了。由于功能基本上是计算密集型的,所以这些第三方的库如果没注意编译开关,完全有可能造成这种情况。

让客服电话采集了一下用户的硬件信息,果不出所料:AMD Athlon XP 3000+。根据维基百科的 资料 显示,2003 年面市,这是一款可以称得上老旧的 CPU。支持的指令集:MMX、SSE、3DNow,并不算多,关键是没有 SSE2。

为什么会怀疑到 SSE2 上面呢?因为前不久刚看了一篇博文,说 Win8 需要 CPU 支持 SSE2 才能安装。这说明 SSE2 所能提供的,已经几乎是现在开发的新软件所必需的基本能力了。另外很多编译器已经默认把 SSE2 优化给打开了。也难怪——这年头,还有谁在用 Pentium III 吗?

总之,合理怀疑之后,先来看看是不是这么一回事。这种事情如果要通过正常途径去沟通,不见得效果好。说不定那个当初负责编译出这个库的程序员早换工作了。就算人还在,编译选项和指令集之间的关系搞不清的程序员大有人在。问还不如自己动手看。以下是用 dumpbin 对其中一个第三方 DLL 库反汇编出来的某个函数的部分代码:
1001314E: 66 0F 6F 06        movdqa      xmm0,xmmword ptr [esi]
10013152: 66 0F 6F 4E 10     movdqa      xmm1,xmmword ptr [esi+10h]
10013157: 66 0F 6F 56 20     movdqa      xmm2,xmmword ptr [esi+20h]
1001315C: 66 0F 6F 5E 30     movdqa      xmm3,xmmword ptr [esi+30h]
10013161: 66 0F 7F 07        movdqa      xmmword ptr [edi],xmm0
10013165: 66 0F 7F 4F 10     movdqa      xmmword ptr [edi+10h],xmm1
1001316A: 66 0F 7F 57 20     movdqa      xmmword ptr [edi+20h],xmm2
1001316F: 66 0F 7F 5F 30     movdqa      xmmword ptr [edi+30h],xmm3
10013174: 66 0F 6F 66 40     movdqa      xmm4,xmmword ptr [esi+40h]
10013179: 66 0F 6F 6E 50     movdqa      xmm5,xmmword ptr [esi+50h]
1001317E: 66 0F 6F 76 60     movdqa      xmm6,xmmword ptr [esi+60h]
10013183: 66 0F 6F 7E 70     movdqa      xmm7,xmmword ptr [esi+70h]
10013188: 66 0F 7F 67 40     movdqa      xmmword ptr [edi+40h],xmm4
1001318D: 66 0F 7F 6F 50     movdqa      xmmword ptr [edi+50h],xmm5
10013192: 66 0F 7F 77 60     movdqa      xmmword ptr [edi+60h],xmm6
10013197: 66 0F 7F 7F 70     movdqa      xmmword ptr [edi+70h],xmm7
1001319C: 8D B6 80 00 00 00  lea         esi,[esi+00000080h]
100131A2: 8D BF 80 00 00 00  lea         edi,[edi+00000080h]
100131A8: 49                 dec         ecx
100131A9: 75 A3              jne         1001314E
SSE2 的指令集可以参见 这里。其实看到 movdqa 就已经很明白了。这个 DLL 库的确用了 SSE2,那么,报错就是很正常的事情。

在分析这个问题的时候,我花了一点时间,希望能找到一个能够列出程序所使用的指令集的静态分析工具,但没有找到答案。当然,就这次的情况而言,我能通过 XMM 寄存器很容易地找到并筛选出 SSE2 的指令。但要是能有一个自动化工具,就更好了。也许还是有这种工具的,只是我目前还不知道吧。如果有谁知道,还望不吝告知。

2013-09-05

GAE 升级 Python27 折腾手记

Google 把 GAE 的 Python 运行环境从 2.5 升级到 2.7,已经有好一些日子了。因为只扔了自己的两个小小的应用在上面,所以一直没去处理。最近总算有些时间,于是把这个折腾完了,还很花了一些工夫,特记录一下。

去看了 GAE 的在线文档。中文的文档是只有 2.5 的部分,繁体中文也只是对 2.7 给出了一个链接而已。技术方面的东西还是直接参考 英文资料 来得好。

具体的做法,官方文档上写得很清楚,就不在这里说了。但是我的升级过程并不是很顺利。最后总结一下有这么几个问题,供大家参考:
  • 按照文档,app.yaml 里面的 handle script 要从 .py 改成 .app,但千万别手贱去把 .py 文件真的改名成 .app。其实只是 app.yaml 里面要改而已,文件还得是 .py 为后缀名。
  • app.yaml 中还要引入 webapp2 这个 library,这个在官方文档中没有明确地指出。具体写法是:
libraries:
- name: webapp2
  version: "2.5.1"
其实 version 可以写 latest,但要承担最新库无法向下兼容的风险。
  • 要更新就索性别留旧版(Python 2.5)的程序在 GAE 上,否则页面顶部的警告一直会有。
其余过程还算顺利,至少升级到 2.7 算是成功了。

2013-08-29

推荐几个对青少年有教育意义的老 PC 游戏

前言
青少年玩游戏,很容易被家人说成是「玩物丧志」。不可否认,现在绝大多数的游戏,不论是单机还是网游,其目的不外乎都是娱乐消遣发泄。其实我也认为,如果一个游戏不是为了让人玩,而是为了教育人,那么不可能是好游戏。不过,的确有那么几个游戏,有一点不同。

通常而言,所谓「有教育意义」的游戏,一般是指那些专门为了教育目的而生的游戏。特别是对于幼儿,这类游戏有很多。另外,有一些游戏,也打着所谓「寓教于乐」的旗号,——虽然实际上两者可能都做不到。
我觉得,真正有教育意义的游戏,首先要是一个优秀的游戏,从娱乐的层面的优秀。其次,如果这个游戏能让人在玩过爽过之后,有一些别的收获,那么就算是有教育意义了。
另外,这种游戏还应该具有一些特质:
  • 不容易让人沉迷:从游戏的层面来看,能让人沉迷其中对它是好事。但如果在它上面耗费了太多精力和时间,所谓教育意义就被抵消了。一个标准就是,要有始有终。开始便能很快引人入胜,结束后也不会让人过多的留恋于其中不能自拔。
  • 难度不高:如果大量的时间花在攻克难关上,就算游戏本身吸引人,但也很可能让一部分人知难而退或半途而废,所谓教育意义也就达不到了。
  • 健康向上的剧情和心态:游戏传递的,至少不应该是负面的情绪。积极、活泼、开朗、乐观、淡定泰然、不惧挫折、适当的自我调侃与解嘲、自然的正义感,等等。
  • 丰富的知识性:不是专门的教育类游戏,自然不会全部围绕知识性来构建剧情。但游戏中至少要让玩家能接触到平时接触不到的知识。日本光荣 KOEI 就在这方面做得非常好!
以我二十余年的经验,推荐一些这类的游戏给青少年玩家:

大航海时代Ⅱ
其实 KOEI 的游戏在知识性上一贯都做得非常不错。只是,我觉得有必要把这个游戏单独拿出来提升到另一个高度。因为它对我的世界地理的帮助实在是太大了。
全世界的大城市,大港口占了相当一部分,而找到并访问这些港口,是你游戏中几乎是必须完成的任务。为了找到某个地方,你得学会经纬度是怎么回事,然后还得搞一张世界地图,根据经纬度在地图上查到大致位置,然后在游戏中才能比较容易地发展剧情。幸好当时我家里墙上刚好贴了一张世界地图。
游戏中的地图当然不是完全真实的,但大致差不多。并且在航行过程中还会遇到海流、风向等问题。想远航美洲大陆?要是找对航路和时间,就会变得比较简单。那么当地理课讲到洋流和信风的时候,一下子就懂了。
另外,游戏对于历史也是有一定帮助的。虽然剧情不是真正的历史,但那个时代的一些东西还是依稀可见。各地的风土人情也刻画得很不错。这些甚至体现在了游戏的配乐中。
值得一提的是,尽管游戏中城市名称的某些译法不是很习惯,但也正好避免了学地理之类课程时背字不背义的问题。莫三比克和莫桑比克这种区别,相信一眼就能看得出来。并且,给船命名的时候,能够认识并熟悉很多繁体字。我一直到现在都能记得「號」字有十三划。
推荐给想了解世界的青少年。

Museum Madness
和别的不同,这个游戏我觉得本来就是一个「专门为了教育目的而生」的游戏。一个博物馆被病毒入侵然后 Madness 了,管理机器人找一个小孩子求救,然后他们一起去每个馆把搞乱了的东西复原回来。每个馆都有至少一个谜题需要解答,有的是拼图,有的是 AVG / RPG 性质的对话 + 选择,有的是玩一个小游戏,等等。在解答谜题的过程中,会穿插着对科学、历史等的说明,博物馆嘛。
推荐的意义在于:
  • 英文游戏,但英文难度不高,对话文字可以慢慢读,适合国人学习英语。
  • 可玩性不错,流畅度很好,谜题难度也适中。大部分地方不会英文也不会卡关。
  • 科普的知识还真不是小学 / 初中阶段所有人都知道的,看看也不错。
另外,现在看到这个游戏,我就想起了《博物馆奇妙夜》。真的是挺好的感觉。中国的历史更加悠久,但就出不来这种片子,也出不了这等游戏。
推荐给想加强英文阅读的青少年。游戏可以从这个地方 下载 到,点那个 GET IT 就可以。

轩辕剑外传——枫之舞
作为 VGA 时代 320×240 分辨率下的代表性巨作《轩辕剑Ⅱ》的外传,个人认为比原作更富教育意义。《轩辕剑Ⅱ》其实也挺值得推荐的,主要在于其对于中国传统文化——水墨山水、以及《山海经》中内容等的完美展示。而《枫之舞》在剧情和人物方面胜出。
剧情几乎都是虚构的,对历史没有太多帮助。但游戏里的不少人物都是确有其人。随着剧情发展,反派浮出水面,似乎一切都只是一个做得不错的 RPG 而已。然而,精髓来了——最后的大反派,并不是真正意义上的「坏人」。
这也是我日后尊敬 Falcom 的一个原因之一。很少有人愿意像动画片里面一样,真正甘心做一个彻彻底底的坏蛋。纵然是所谓「坏人」,也有他自己的理想。他只是在自己的实践中出了问题。不把「好」、「坏」绝对化,留给看完结局之后的玩家一点思考的空间,是这个游戏与普通的打来杀去最大的不同。
另外,游戏中主人公的对待生活、世事的态度,让我很羡慕。悠然自得,但又充满正义感。谦恭有礼,但又不时玩俏皮。自己从未做到如此。
推荐给想要成熟一点的青少年。

银河英雄传说Ⅳ
这个游戏本身也算得上是精品。但是推荐的其实不是游戏本身,而是游戏对应的文学作品。
《银河英雄传说》这部架空历史小说(不是指动画或漫画),我认为是一部对于青少年来说非常棒的三观纠正入门级教材。我认识的很多人,都是从接触它开始,慢慢学会了独立思考。对于国外的小孩,或许这方面不是问题,但对于被洗脑残害了十余年的可怜人,能有机会接触这么多不同的思想真的是太好了。

小说本身是很优秀的,但在这里就不详谈了,感兴趣的可以点 这里(需「科学上网」)。而游戏值得推荐的地方在于——它非常忠实于原著。不少语句都是从原著中一字不漏地照搬过来的。这也保证了那种原汁原味的感觉,甚至连作者的写作风格都能体现在游戏中。这使得对游戏感兴趣的玩家能够有兴趣去翻阅原著,进行更深层次的思考。而对游戏不感兴趣的玩家可能就很难对原著感兴趣。实际上起到了一个引荐和筛选的作用。
推荐给希望开始思考人生的青少年。

后语
个人以为,这就是所谓的精品中的精品了。只是可惜,这少数的几个能够真正做到「寓教于乐」的游戏,基本都是目前看来很「老旧」的游戏。也许是现在的所谓「新」游戏还没有足够的时间来检验,但又也许是现在的游戏已经不追求这种目标了。看到现在的网游都是用来赚钱的,我看我还是死了这条心吧。

为避免版权问题,本文所有图片均来自 Internet。

2013-06-28

Blogger 上的博客如何提交完整的 Sitemap

Blogger 现在可以输出 Atom 1.0 和 RSS 2.0 两种版本的 feed(参见 官方说明)。不过无论哪种 feed,都只包含最多 26 个 Post。

对于通常的 feed 订阅而言,最新 26 个 Post 应该是足够了。反正 RSS 阅读器只需要最新的那几个 Post 就行。但对于想把站点的 Sitemap 提交到 Google 的 网站站长工具 去做 SEO 的情况,26 个 Post 就太少了。既然是 Sitemap,当然希望是全部的页面了,那么有什么办法呢?

这里有个老外的 页面,说明了一种办法。大致说起来就是,Google 在提供 feed 订阅的 URL 中,还有两个未公开说明的参数:start-index 和 max-results。前者表示这次的 feed 输出从哪个(序号的)Post 开始,后者表示这次最多输出多少个 Post。于是如果要提交超过(默认的)26 个 Post 的 Sitemap,就可以用类似下面这种:

http://blogname.blogspot.com/feeds/posts/default?alt=rss&max-results=500

不过,看起来 max-results=500 应该是一个上限。本人是没有那个条件去试了,博文数量差着一个 0 哩!对于博文数量超过 500 的情况,上面那个老外的博文中也提到了一个办法,就是分段提交 Sitemap。比如:

http://blogname.blogspot.com/feeds/posts/default?alt=rss&start-index=1&max-results=500
http://blogname.blogspot.com/feeds/posts/default?alt=rss&start-index=501&max-results=500
http://blogname.blogspot.com/feeds/posts/default?alt=rss&start-index=1001&max-results=500
……

反正这些页面是都提交上去了,Google 会自己把它们合并起来的。

2013-06-27

自己写了个帮助快速替换 hosts 的工具

替换 hosts 对于会的人而言并不是一件复杂的事情。不过仍然稍嫌繁琐:目录本来就比较深,还要涉及到文件复制和改名。稍一不留意还有搞错掉的可能。

两个月前,我终于无法忍受了,自己写了一个批处理来解决这个问题。人容易出错,人会烦,机器不会出错——如果你程序写对了的情况下。作为程序员,就应该有自己动手丰衣足食的觉悟。因此就有了 SetHosts.bat 的第一版:
@echo off
pushd %SystemRoot%\system32\drivers\etc\
copy /y %1 hosts
popd
只这样显然是不够的。在命令行下敲指令,这不是我的初衷。虽然 Windows 的 Drag & Drop 可以省很多事情,但我还想做得更多。把这个 BAT 注册成某个特定后缀的文件的默认打开程序不是很好吗?这样以后直接双击文件就可以完成替换了。

于是当时我自己用 regedit 在注册表上填写了关联文件打开方式的相关信息。现在我可以双击 hosts_cn.fkw 或 hosts_us.fkw 来快速地应用某个我事先准备好的 hosts 文件了。
应该说,自己用用,这样是足够了。不过我还想做的更好一点。让程序自己完成这个填写注册表的过程,不是更好吗?于是有了 SetHosts.bat 的第二版:
@echo off
if {%1}=={} goto install
if {%1}=={/u} goto uninstall
if {%1}=={/U} goto uninstall
pushd %SystemRoot%\system32\drivers\etc\
copy /y %1 hosts
popd
goto :eof
:install
set MY_TEMPREGFILE=%TEMP%\temp.reg
set MY_SETHOST=%~f0
set MY_SETHOST=%MY_SETHOST:\=\\%
echo Windows Registry Editor Version 5.00>%MY_TEMPREGFILE%
echo.>>%MY_TEMPREGFILE%
echo [HKEY_CLASSES_ROOT\.fkw]>>%MY_TEMPREGFILE%
echo @="Fuckwall.Hosts">>%MY_TEMPREGFILE%
echo [HKEY_CLASSES_ROOT\Fuckwall.Hosts]>>%MY_TEMPREGFILE%
echo [HKEY_CLASSES_ROOT\Fuckwall.Hosts\shell]>>%MY_TEMPREGFILE%
echo [HKEY_CLASSES_ROOT\Fuckwall.Hosts\shell\edit]>>%MY_TEMPREGFILE%
echo [HKEY_CLASSES_ROOT\Fuckwall.Hosts\shell\edit\command]>>%MY_TEMPREGFILE%
echo @="\"C:\\Windows\\Notepad.exe\" \"%%1\"">>%MY_TEMPREGFILE%
echo [HKEY_CLASSES_ROOT\Fuckwall.Hosts\shell\open]>>%MY_TEMPREGFILE%
echo [HKEY_CLASSES_ROOT\Fuckwall.Hosts\shell\open\command]>>%MY_TEMPREGFILE%
echo @="\"%MY_SETHOST%\" \"%%1\"">>%MY_TEMPREGFILE%
regedit /s %MY_TEMPREGFILE%
del /q %MY_TEMPREGFILE%
set MY_TEMPREGFILE=
set MY_SETHOST=
echo 处理程序安装成功
echo 您可以双击后缀名为fkw的文件来直接更换hosts
echo.
pause
goto :eof
:uninstall
set MY_TEMPREGFILE=%TEMP%\temp.reg
echo Windows Registry Editor Version 5.00>%MY_TEMPREGFILE%
echo.>>%MY_TEMPREGFILE%
echo [-HKEY_CLASSES_ROOT\.fkw]>>%MY_TEMPREGFILE%
echo [-HKEY_CLASSES_ROOT\Fuckwall.Hosts]>>%MY_TEMPREGFILE%
echo [-HKEY_CLASSES_ROOT\Fuckwall.Hosts\shell]>>%MY_TEMPREGFILE%
echo [-HKEY_CLASSES_ROOT\Fuckwall.Hosts\shell\edit]>>%MY_TEMPREGFILE%
echo [-HKEY_CLASSES_ROOT\Fuckwall.Hosts\shell\edit\command]>>%MY_TEMPREGFILE%
echo [-HKEY_CLASSES_ROOT\Fuckwall.Hosts\shell\open]>>%MY_TEMPREGFILE%
echo [-HKEY_CLASSES_ROOT\Fuckwall.Hosts\shell\open\command]>>%MY_TEMPREGFILE%
regedit /s %MY_TEMPREGFILE%
del /q %MY_TEMPREGFILE%
set MY_TEMPREGFILE=
echo 处理程序反安装成功
pause
goto :eof
这下不仅注册有了,注销(反安装)也有了。以后看到 fkw 后缀的文件,就可以快速地 Fuckwall 了。……于是今天方校长就请病假了。

如果整代码有困难,那么可以从下面两个链接之一进行下载:
Dropbox: https://dl.dropboxusercontent.com/u/44933633/SetHosts.bat
Mega: https://mega.co.nz/#!Bhx2yYoR!ElR26mi-iGqx5WU3YJks8ViINKEE_wlv1Y32Mil6UEU

2013-05-09

赶一下白宫请愿的早集

最近关于白宫请愿的话题很火,在其光环作用下,飘猪老鼠林昭神马的很快就过气了,连京温还没怎么热就已经要温了。我也想就这个事情说上几句,免得后面喋喋不休。

有意无意中看到知乎上的某个问题的一大串回答让我是又好笑来又好笑。很多人连白宫请愿是怎么回事都没搞清楚,就开喷。我们先来看看人家的 Introduction。需要注意的是以下这句:
If a petition gets enough support, White House staff will review it, ensure it’s sent to the appropriate policy experts, and issue an official response.
我替不懂英文也不知道 Google Translate 的同志翻译一下:如果一份请愿得到足够的支持(票数达标),白宫工作人员会审读,确保它会被发送给适当的政策专家,并给出一个正式的回应。

所谓正式的(或者说官方的)回应,也可以是「这个问题不在联邦政府职权范围内,我们无能为力」这种。这只是一个政府与民众互相沟通的渠道而已——人家说得很明白,一个工具。外国人办事比较认真,回复不像我们这边这样马虎了事。但人家也并没有义务一定要给出某个特定的回答,更不是某些人理解的「票数达标就得照我说的做」——说实话,我真怀疑这种智商属于人类吗。

实际情况是,如果票数没有达标,请愿根本不会到白宫工作人员那边。系统自动把它归档(Archive)了。FAQ 上说得更直接——Remove。当然,我并不怀疑一毛们的刷票能力。不过,别忘了人家还有 Moderation Policy。另外,每个请愿的页面上,都有着红色的 Report this Petition as Inappropriate。出于尊重读者智商的缘故,看到这里的我就不翻译了。

事实上,一毛们的搅混水行为,对白宫或白宫网站甚至都形不成什么有效的骚扰。条款规定,多份陈情可以用一份回应来应对。要是垃圾请愿多得厉害,还可以把适度条款搬出来。
骚扰行为更主要的意义,在于向国内民众展示类似这样的意思:「看,白宫网站是搞笑用的。」以期阻止将来的更多请愿可能会对干部子女和家属造成的实质性威胁。题外话戳一句:小的们真是太体恤太懂事了。大王叫伊去巡山,伊把山上的屎都给吃了。

具体在眼下这个环节,我希望能阅读到这里的读者在将来能做这样两件事情:
  1. 对于有意义的请愿,在自愿的前提下,投上自己的一票。足矣。
  2. 对于无意义的请愿,不投票,并且举报。这也算意见表达,别给脑残和一毛留情。
我相信,看到这里的读者都是有足够判别能力的。不再啰嗦了。
不过我还想对某些人说一句:注意你们的 IP 地址,别老用 61398 的。你们没看见外交部发言人每次都满嘴的沫吗?

2013-05-05

让 GoAgent 直接使用自己指定的 Google 服务器 IP 地址

一直很疑惑,为什么 proxy.ini 中把 [google_cn] 下面的 hosts 改成了自定义的 IP 地址,但日志中显示 GoAgent 客户端还在寻找其它的 Google 服务器 IP,并试图作为 GAE 代理进行连接。


因为一直都算还能用,所以就没下决心来解决这个问题(发现自己真的很懒)。但最近 GoAgent 客户端自己找到的IP越来越不靠谱,有时候甚至会导致一半左右的请求都会被重试,实在是太浪费时间了。而且第一次使用的时候 DNS 解析导致的等待也让人很不爽。所以终于决定来看看到底是怎么回事。

一看代码就明白了,问题很简单:GoAgent 客户端针对 [google_cn] 这个 Section 有特殊行为。它会去从 www.google.cn 和 www.g.cn 这两个域名进行解析得到 IP(好像会无视 proxy.ini 中自己设的地址或 IP),然后进行建立 SSL 连接的测试,根据测试情况决定是否切换到 [google_hk](这又是一个特殊行为)。

这种做法,对于初级用户可能会比较适合。但如果想自己控制 GoAgent 客户端使用哪个 Google 服务器 IP,最好是另外开一个 Section,比如 [google_cn2] 或 [google_us] 之类。这样就不会碰到代码里面预设的这些特殊行为了。

PS: 以上内容基于 GoAgent 2.1.11 / 2.1.15 测试。

2013-04-10

修改 GoAgent 客户端以支持 Mega

为了能用来访问 Mega,对 GoAgent 客户端代码做了略微的修改。不过首先要说明一下为什么会有这个修改。

Mega 是个总部位于 New Zealand 的网盘服务。服务器当然全世界都有,但至少在我这边 ping 值不好。严重的时候 600ms 以上,并且丢包。这样的话,不管本地有多少带宽,实际上也是不可用的。总不可能花上一整天的工夫来传一个 ISO 吧。
开着 VPN 会快,但流量和费用都是问题。于是很自然地想到了是否可以通过 GoAgent 之类的 GAE 代理来访问。Google 服务器与 Mega 之间的带宽应该是不成问题的,而 Google 服务器与我之间的速度也是我可以在一定程度上控制的。不过测试下来发现 GoAgent 不支持 OPTIONS 这种 HTTP Method,而且这个局限性是 GAE 导致的。GAE 只支持GET / POST / HEAD / POST / DELETE 这五种 HTTP Method。偏偏 Mega 在登录和上传下载的时候都会发 OPTIONS 请求,于是这个方案一度被搁置了。
后来 Mega 的速度进一步下降,有时候一整天都传不完一个 100M 的文件。于是这个方案又被我拿出来考虑。这次我准备绕开服务端的限制,直接从客户端下手。OPTIONS 请求涉及的数据量是很小的,文件传输用到的 CONNECT 之类才是主要的带宽压力。因此可以让客户端在遇到 GAE 服务器无法处理的 HTTP 请求时,直接将其发到目标服务器。由于 Mega 目前还没有被 GFW 给 IP 黑洞,因此应该可以在一种「混合模式」下被通过 GoAgent 访问到。

下面介绍一下修改方法,以 GoAgent 2.1.15 版(2.1.17 还需要服务端改动才行)为例:

首先在 local/proxy.py 中找到这两行:
"""rules match algorithm, need_forward= True or False"""
need_forward = False
第一行是注释。而下面这个 need_forward,就是用来控制是否把一个请求直接送出(FWD),而不是送去 GAE 服务器进行中转。

在后面的 if 语句前,加入这样的内容:
if self.method != 'GET' and self.method != 'POST' and self.method != 'HEAD' and self.method != 'PUT' and self.method != 'DELETE':
    if host not in http.dns:
        http.dns[host] = list(set(http.dns_resolve(host)))
    need_forward = True
非 Python 程序员也应该很容易读懂这段代码,不过要提醒一下:Python 中缩进是很关键的,改代码时一定要用空格正确地缩进。
最后,别忘了把下面那个原来的 if 改成 elif。

这样改过之后的 GoAgent 客户端,在遇到 GAE 服务端不能处理的那些 HTTP 请求类型时,就会把它们直接发到目标服务器上。
从理论上讲,这个小修改不会对 GoAgent 的翻墙能力有任何的增加,但可以让它具有更大的适用范围。一些原来不能用 GoAgent 访问的站点(比如上面提到的 Mega),现在可以用它来访问了。GAE 的流量按天计算(VPN 一般按月,VPS 也是)。并且因为可以使用多个 GAE 账号,因此流量基本上是免费且无限的。Mega 那 50GB 的大空间,终于具有一定的可用性了。

2013-04-08

论天赋与竞争

今天偶然谈到一个话题。我发现,一个健康、聪明的宝宝,能够给爸妈省下非常多的钞票。换句话说,这就是体能、智能在生存竞争上的优势的具体体现。
只是,我觉得,原始社会的时候就是这个游戏规则,到现在咱们还是这个规则,这个社会体系是不是建设得太失败了一点?

我总觉得,人类社会发展到现在这个阶段,从技术或生产力上讲,应该已经有能力解决成员的基本生存问题(温饱)了。那么,区分成功还是失败,或者说人们奋斗的目标,应该是看一个人能不能实现自我的价值,做自己想做的事。有的人可能不擅长打猎,有的人不会种田,但是他可能会唱歌,这可以使他人愉悦。不需要一个人什么都会。即使他不会任何直接产生食物的技能,也不会饿死。社会化分工,这就是人类社会出现的意义。

在社会形态发展还不完善的时候,可能有的人还是会有生存问题。艺术家要是画卖不出去,也会有生计问题。所以这才需要社会形态继续发展。一方面生产力要更高,才能有足够多的资源来供养这些不直接生产生活资料的人。另一方面,需要保障制度的逐步建立,需要合同方式的完善,来消除因为成员个体的分离带来的沟通上的问题。——无论政治还是经济,本质上都是在解决沟通问题。

一个能够保障个人基本权利(包括生存权)的社会,才能更好地保障多样性。否则世界上将只存在猎人和农民,人类社会也就不会再进步。基因需要多样性,社会成员同样需要多样性。即使是所谓人渣,也有他存在的意义和价值。所谓的天赋,包括体能、智能,乃至于道德上的高低,都不应该成为淘汰个体的理由。

我并不是说天赋不应该有优势,而是说这些天赋上的(貌似)弱者不应该必然被淘汰。丛林法则是一种自然状态下低等级的演化规则,其重点是「适者生存」。而既然是「适者」才能生存,那么其演化所产生的结果必然越来越趋向于适应某一种特定的环境。一旦环境发生非常大的改变,或者说「游戏规则改了」。那么演化的结果就可能会变得毫无意义,甚至整个种族都会有危险。而其原因就是,本来也许能适应新环境的成员,在之前的演化中被无情地淘汰掉了。

我们人类是(目前看来)有一定智力的种族,也希望能拥有其它动物所不具备的改变自身命运的能力,那么就一定不能按照动物的演化规则来生活。所以我觉得,如果一个现代社会里面,成员还要为了基本的生存条件而奋斗,要像动物一样靠天赋进行生存竞争,这个社会的设计和演化是失败的。

不过也许这个社会中有一部分成员就是想让其他人活得像动物,弱肉强食。谁知道呢?!

2013-04-03

也谈「量刑要适度」

看到有的人在说什么「量刑适度」,真心觉得搞笑。
这种人,就是把公权和私权混为一谈分不清的那类人。

要动用公权力侵犯私权时,疑罪从无原则无疑是非常重要的。因为双方力量并不对等。
而个人之间的质疑乃至问罪,没有必要搞什么疑罪从无。双方力量都是对等的。一方可以质疑,另一方也可以回应。一方可以乱扣罪名,另一方也可以把真相公之于天下让大家看看。就算捅到媒体,舆论一边倒。你可以骂别人傻逼,可以觉得别人真的是傻逼,可以骂群众无脑盲从,可以愤世嫉俗愤然删号滚蛋。但人家就是有这个权利。发表自己的见解,没有问题,但想修改游戏规则,是很不明智的。

从另一方面看,对于公权,不仅不能疑罪从无,还应该要用最恶意的角度去揣测。这个原则,也应该可以适用于双方力量明显不对等的情况。没有人会认为保护伞公司不应该接受政府同样的待遇吧?

更何况,有的时候,超出目前状况之外的恶意揣测,往往是为了自我保护,而不是要加害于他人。黄浦江上的猪,没有检测出可感染人类的病毒,就应该为此放一百二十个心了吗?目前还没有证据显示 H7N9 可以在人类之间传染,于是友人咳嗽高烧也可以不用防护地去探病吗?没有上过 CSDN,于是就不用修改密码了吗?没有反对过永远伟大的党,于是就可以举手支持第 73 条了吗?如果只是走一步看一步,人类存活不到现在。你可以自己这样做,但要求别人也跟自己一样,要么是站着说话不腰疼,否则不是脑残就是别有用心。