2015-12-13

最近看过的书,简评几则


  • 《战争史》(基根):没有想象中的宏大,是更为学术性的书。主要针对战争本身进行研究,阅读起来略微有一些无趣。作者跟克劳塞维茨算是杠上了。
  • 《毛毛星球》(约翰.斯卡尔齐):一本小品式的“科幻”。介绍上说是硬科幻,但里面的法律内容比科学和幻想加起来还要多。就像很多读者说的那样,作者的确“很会讲故事”,是很“温情”的故事,我喜欢。只可惜有“毛毛”死去,看到最后虽然正义感得到了满足,但还是轻松不起来。
  • 《锁定目标》(汤姆.克兰西):一开篇就是火爆的动作场面,后面也是高潮不断。人基本上还是那班人,但比《虎牙》刺激多了。一本不错的克兰西作品。
  • 《悖论:破解科学史上最复杂的9大谜团》(吉姆.艾尔.哈利利):还算不错的入门级科普,看过之后应该能对物理学上的一些重难点有所了解,而且又不至于被吓倒。留给儿子以后看吧。
  • 《羊毛战记》(休.豪伊):不错的反乌托邦科幻,和Fallout系列的感觉很接近。我觉得用Fallout1/2的引擎很容易就能根据这书的剧情改编出一个游戏来。144层的Vault,想想也很大。不过从后期透露的信息看来,虽然深度很大,但每层的面积并不是很大。作者用了一种舞台剧一样的写法,情节冲突也是一波一波地。这种写法我不是太喜欢,不过还是很期待下一部的续集《尘埃记》。
  • 《虎牙》(汤姆.克兰西):比起《锁定目标》来,这本的节奏就太过平稳了。个人认为唯一称得上动作戏的,就只有Mall里面那场枪战而已。不过这本书主要是为了交待“校园”的来历,大概是过渡性的作品吧。
  • 《虚无的十字架》(东野圭吾):本以为是本格派的作品,结果读完却几乎以为是松本清张写的。我对他了解还不是太深。据说是14年的作品,难道东野圭吾在转型成社会派?作为日式推理小说并不是太好看,看起来被亚马逊放进特价书目里面并不是毫无理由。线索太散乱,布局感又太明显,立意很高,但显然对这个话题又无力下定论。何况是个很沉重的故事,看起来实在是太不轻松了。

2015-12-02

完了完了,今年又要完了

数了数,从去年的年末座谈会到现在,今年(2015年)一共只写了八篇Blog。平均一个月还不到一篇,我真的是太过于懒惰了。

其实,因为不见得全是懒惰。一方面,今年公司上马新项目,我是主程,工作时间特别忙,已经很难再抽出空来写Blog了。另外一方面,今年家里出的状况也特别的多,私人时间也很难抽得出来。曾经寄希望于搬家之后每天上下班时间能够在公共交通上完成这个任务,但现在看起来也不太适合。总之吧,客观原因还是挺多的。

争取这个月多写写吧。眼下貌似没有那么忙了。不然月底竜堂家四兄弟又要来找我的麻烦了。

2015-08-27

也谈Shadowsocks的“关闭”风波

之前已经在Google+上零星地发表过一些看法。本文总的来说可以看作是对这些零星看法的一个汇总和系统化。已经看过的朋友可以无视。
另外,标题之所以对“关闭”二字加引号,是因为这种开源项目从严格意义上来说没有什么关闭不关闭的。项目已经被许多人fork过,Release也都还在,就算最新源代码被删了又怎么样呢?也就只是做给国安局的人看看吧。

言归正传……

这次Shadowsocks作者被盖世太保警告,然后GitHub上的项目代码被删,在IT界造成了不小的震动。除了愤怒与哀叹,还有以下几个问题/观点也被抛出:
  • 认为没什么人对Shadowsocks作贡献。
  • 把GPL开源转闭源违反协议。
说起来,这两个问题,其实是开源项目的问题,与GFW无关。原作者在删代码之前,也曾言辞激烈地作过批评。现在的这两个看法,基本上也延续了原作者的思路。不过,我倒是有一些不同的看法。

首先,要说说对开源项目的贡献这种事情。
在程序员(开发人员)看来,对开源项目作贡献,通常意义上意味着需要修改/提交代码。至少,也得明确地指出Bug的所在,可能还得需要有对应的解决方案或手段。这样,才能算是对项目作出了贡献。
但是,在我看来,那些只是默默地使用着Shadowsocks,用来配合自己的VPS完成翻墙的人,他们都对这个项目有贡献。如果测试出了错误,当然应该指出。但是还有更多没有测试出错误,没有遇到错误的使用者,他们同样可以被视为是测试人员之一。一个庞大的用户基数,是保障一个软件变得越来越成熟的基础。如果没有什么人用,即使自己或一个小团队测试并修正了很多Bug,也不能确定它是不是真的足够稳定耐用。如果有很多人使用,但是没有什么人报告Bug,那只是说明了作者水平不错,并不能说明别人不贡献。
那么,如果一个开源项目做得不好,差劲,问题多多。别人用了之后拔腿就跑,还是不肯修改或报告错误,这是不是就能说明“天朝那么多牛B哄哄的程序员不肯作贡献”了呢?
答案还是“否”。开源项目,是有自己的生态系统的。如果一个项目大家都跑,那它就应该消亡。用脚投票,也是一种贡献,不能因此责怪别人“不作贡献”。只有完全不用,这就真的是“不作贡献,但你难道把这种事情怪到卖菜小贩头上?
在我看来,之所以Shadowsocks原作者会觉得没什么人帮他改代码,恰恰在于他把这个项目做得太好用了。大家用起来都很舒服,自然不会有什么人想要去改。会想去改的人,就更可能是那些“爱折腾”却又不具备相关能力的人,所以作者才会觉得有压力。
换句话说,对于真正有能力改动代码的人,以及要求不高的人而言。Shadowsocks一开始就已经足够好了。这就过滤掉了一大群人。“劣币驱逐良币”这个比喻用在这里可能不是很恰当,不过我相信大家懂我的意思。对于一个用户数够大的软件而言,沉默的人占大多数,这是一个好事。原作者可能还没意识到这个情况。

GPL转闭源这个的确违反了许可协议,这没有什么话好说。我是在想另外一件事情:GPL到底保护了什么?
GPL要求后继项目也必须公开源代码,并且也必须采用GPL。这保证了项目代码会永远开源下去。但问题是,如果你采用GPL许可证,你是想保护你的思想还是你的代码?
由于要求比较苛刻,可能会有更多的人不愿意从GPL项目中fork,特别是那些想商业化的公司、团队或个人。这样一来,你的代码还是原来的代码,没有人来夺走,但你的代码其实是你思想的结晶,否则它们只是一堆敲击键盘而成的无意义的文字而已。如果没有人愿意fork,那你的思想也就无法被继承并发扬。
如果我想让自己的思想发扬光大的话,我会选择让自己的代码进入Public Domain。并且,只提供思路及核心代码,包括一个最简实现。至于项目最后包装成啥样,有兴趣的就自己动手。改动代码也好,只是加个壳也好,做成商业应用去卖钱也好,免费分发也罢,都可以。
本来推墙这种事情,就是需要五花八门,三教九流一齐上。你管它是志愿军还是雇佣兵。反倒是如果仅此一种工具,就很容易被GFW对付。提供一种可行的思路,比做出一个完美的实用产品,可能更合适一点。
这样的好处就是,原作者的压力小了,甚至可以不需要去维护。不需要去考虑产品化,不需要在UI上费脑筋,不需要为了不同用户的一些无关大局的小需求改来改去。这些事情,如果需要,就自然有人会去做。作为原作者,可以把精力放在更有意义的事情上——如果你有那个能力的话。

2015-08-19

蹊跷的LNK1104错误

最近在给公司开发下一代产品,所以比较忙,也没有太多的事情写Blog。不过昨天在技术上遇到一件不大不小的事情,也许值得拿出来说一下。

这个下一代产品是从头全新开发的,为此我提供了一些基础库的代码,给到项目组的其它Project使用。其中有一个是用的动态链接库的形式。为了方便其它Project使用,我把如下的预编译宏写在了头文件中:
#pragma comment(lib, "XEngine")
这样,所有需要包含这个头文件的代码,就不需要自己去搞清楚到底要链接哪个lib文件了。

但是,同事在拿到代码做全新编译的时候,出现了LNK1104错误。Cannot Open File XEngine.lib。同事当然一头雾水,Baidu上搜了一下之后,一头埋进去检查硬盘坏道去了。

我这边一开始没有问题,当把发布目录中的XEngine.lib删除了之后也出现了同样的问题。源代码对编译结果产生了依赖,这当然是不对的。问题当然出在那句预编译宏上,只不过代码的编写时间过去有点久了,我一时没想起来。
正好这个DLL具有导出函数,因此VC自动生成了相关的代码,只需要把前面的预编译宏放在这里面就可以了:
#ifdef XENGINE_EXPORTS
#define XENGINE_API __declspec(dllexport)
#else
#define XENGINE_API __declspec(dllimport)
#pragma comment(lib, "XEngine")
#endif
这样就解决这个问题了。如果没有这些自动生成的代码可以利用,也可以参考着自己写一个。

2015-06-04

按更新时间同步单个文件的简易方案

我曾经抱怨过,有个很简单的单个文件同步需求,却居然难以找到有软件能够解决。也许是需求太过于简单,反而没人去考虑。连Allway Sync这么好的东西,也做不到。于是一直都是人肉解决。

最近有点厌倦了每次Copy来Copy去的事情。而且中间也不是没有出过错。一出错就会丢一次的数据。索性简单地写了个bat批处理脚本来解决这种事情:
@echo off
xcopy D:\仓库\文件.txt .\ /D /Y >nul
xcopy .\文件.txt D:\仓库\ /D /Y >nul
运行这个bat脚本后,更新时间比较早的那个副本,会被另外一个覆盖掉。接下来只要每次编辑前或编辑后都记得运行一下这个脚本,就可以使两边文件版本一致,不需要再考虑复制方向对不对的问题了。

2015-03-11

在Windows上用x64的Python运行GoAgent

首先声明:本文适用于至少懂编程,并且爱折腾的人。不一定要很熟悉Python,但至少应该入过门了。

GoAgent自带Python27运行环境,不过因为本机上也安装了Python 2.7 x64,所以希望能直接使用我安装的64位版本。总结下来,要点有:
  • 无论你是否准备使用x64版Python。GoAgent与Python 2.7.9不兼容,应该安装Python 2.7.8版本。
  • 要运行GoAgent还需要gevent和pyOpenSSL。可以手动安装,也可以通过pip来安装。推荐后者因为省事。
  • Python 2.7.8(无论是否x64)及更早的版本,没有自带pip。所以要去下载get-pip.py,然后用python运行这个脚本安装pip。
    ps:用get-pip.py下载到的pip.exe的版本,比Python 2.7.9里面带的要新一些。所以就算有自带我也会换掉它。

另一个重点来了:
有些版本的GoAgent里面对于crypt32.dll的加载代码在x64的Python中有问题,需要修改。改成像这样就可以了:
crypt32 = ctypes.WinDLL(u'crypt32.dll')
crypt32_handle = crypt32._handle
释放的时候要这样:
ctypes.windll.kernel32.FreeLibrary.argtypes = [HMODULE]
ctypes.windll.kernel32.FreeLibrary(crypt32_handle)
在前面还要:
from ctypes.wintypes import *
否则x64下会报错,因为HMODULE和long的长度在x64下不一样了。

我用的2.1.17的GoAgent中,对于crypt32.dll的加载代码还位于proxy.py中。最新的GoAgent已经移到proxylib.py里面了。什么时候移的我没有去考察过。代码改法可能略有不同,不过思路应该是一样的。

折腾好以后。把本机上的Python.exe复制一份改名成Python27.exe。接下来就可以把GoAgent自带的Python27.*给删掉啦。