进入IPv6的世界

本文写于2011年,目前我已不再试用Linode,新的VPS提供商不提供IPv6的环境,所以目前本网站不再支持IPv6访问。

我的虚拟主机提供商Linode从5月份开始提供原生的IPv6支持,虽然暂时没有什么实质性的用处,但还是决定体验一下。记录一下添加IPv6支持时遇到的问题,供大家参考。

1. Linux中启用IPv6支持

原则上只需要确保你的Linux内核中已经把IPv6的支持编译进去了就行了。在Red Hat系列的发行版上,可能要检查一下/etc/sysconfig/network这个配置文件中有没有把NETWORKING_IPV6设成yes。启用IPv6后,网卡在up过程中就可以从DHCP服务器那里分配到IPv6地址了。如果需要手工配置静态的IPv6地址,跟配置IPv4的方法是类似的,直接修改相应的配置文件即可。比如在Red Hat系列的发行版上,就修改/etc/sysconfig/network-scripts/ifcfg-eth0,在里面加上IPV6INIT, IPV6ADDR, IPV6_DEFAULTGW等配置项即可。

2. nginx中启用IPv6支持

如果只是在配置文件中写上listen 80;的话,nginx只会在IPv4的80端口上侦听。如果需要全局启用IPv6,可以改成:

listen [::]:80;

因为在Linux中,默认情况下,IPv6的TCP socket会同时在IPv4地址上工作。所以对于listen 80;和listen [::]:80;这两种绑定所有地址的80端口的监听,只能两者取其一。不然在启动nginx时会报端口已经被占用而导致启动失败。

如果你的nginx是为多个vhost提供服务的,却又不想在所有的vhost上都启用IPv6,则可以分开写IPv4和IPv6的监听规则:

listen 80;
listen [::]:80 default ipv6only=on;

然后在各个vhost的配置文件中分别有选择性的使用这两行配置就可以了。或者也可以采用非全地址绑定的方式,在listen后面显式的指明要绑定的IP地址。

有关nginx的配置,可以参考nginx的HTTP Core Module的相关文档。

3. DNS设置

在你的域名的DNS配置面板上,你应该可以为你的域名添加A记录或AAAA记录,A记录是IPv4地址,AAAA记录IPv6地址。同一个域名可以同时指定A记录和AAAA记录。在访问的时候就会同时解析出IPv4和IPv6的地址。

除了主域名上同时绑定A和AAAA记录,通常也建议用一个独立的子域名去单纯绑定AAAA记录,这样可以便于在双栈的网络中明确指定希望走IPv6网络。

目前我的主域名freemindworld.com上同时绑定了IPv4和IPv6地址,ipv6.freemindworld.com上为纯IPv6地址。

使用国内的ISP的DNS服务器测试IPv6时需要小心,如果你的域名只绑定了IPv6地址,ISP的DNS服务器可能会进行一次DNS劫持,在返回你IPv6地址的同时,也返回给你一个错误的IPv4地址。至少在Linux下,Firefox和wget都会优先去用那个假的IPv4地址去发起请求,从而得到错误的结果。换用更可靠的DNS服务器或在/etc/hosts文件中添加IPv6地址映射可以解决一部分的问题,更可靠的解决途径可能可以使用TCP DNS。

4. 客户端

CERNET2的用户应该是有原生的IPv6环境来使用的,中国电信的用户就暂时只能通过Teredo隧道这样的方法来使用IPv6了。在Linux下,Teredo的一种实现叫做miredo(音乐中的三个唱名,mi re do),常见发行版中直接安装这个软件包并启动相应的服务就可以得到IPv6地址,通过Teredo隧道的方式来体验IPv6了。请记得改用ping6来测试IPv6的服务器连接,在nslookup时需要set type=AAAA。

最后再赞一下Linode的客服,我在不同时间提交了两个VPS开通IPv6的ticket后,都在3分钟中内得到响应并完成了请求,效率相当的高。

设计与传承

顺应民意,南京地铁开始进行车站导向标识的改版,如图:

南京地铁新版导向标识

南京地铁新版导向标识

什么是一个好的设计?在我看来,一个好的设计必须首先满足功能上的需求。作为导向标识,它最重要的功能性就是要表现出车站所在的方位,新版的导向标识在标明方位的同时还提供了车站名、线路号和距离等实用的信息,提供了更多的功能,也就给乘客提供了更多的方便。

设计心理学》一书中提到,对于设计师来说,有一种致命的诱惑叫做“悄然滋长的功能主义”,或者用别的一种表述的方法,就叫做“设计师应该会做加法,但更要重视做减法”。新版标识上所增加的信息,是不是足够的必要?

必要或不必要,对于不同的目标用户,常常会得到不同的答案。假设以外地游客作为导向标识的主要受益者,他们的需求,就是通过搭乘地铁,到达下一个目的地,所以对于他们来说,导向标识能指向最近的地铁站是最为重要的。而车站名称、距离和线路号,都是次要的信息,只要在地铁站内部布置更详细的线路图和换乘指示,他们都可以在到达地铁站后再获取更多的信息并顺利到达目的地。新版导向标识所增加的信息,只是对于一部分人来说可能可以提高出行效率或节省少量出行费用。

所以从“做减法”的角度说,我觉得改版的标志牌算是画蛇添足。

可是在导向标识牌上增加距离信息是广大人民群众的呼声啊,有人会这么说。好吧,这是个很大的话题,而且已经有很多人讨论过,比如白鸦的那篇《听不听用户的?》。

好的设计,除了满足功能需求,应该要考虑到一致性。因为人在日常生活中,通过不断积累对世界的认识,就形成了一种概念模式。通过一致的设计可以有效帮助用户去借助他头脑中已有的知识,去认识和理解新的事物。

南京地铁线路号的标识是什么样子的?答:圆圈里一个数字。或者,你想不出这个答案,但你一看到这个答案时就能迅速的回想起地铁车站里无处不在这种表示方法。可是遗憾的是,在新版的标识牌上,线路标志变成了一个方框,这分明是北京地铁用的表示方式嘛。缺乏一致性,从而不能成功的利用用户心中已经有概念模式去有效的给用户提供信息,是新版标识设计的败笔之二。

要做到一致性,标准化是一个非常行之有效的方法,虽然标准化可能会束缚一些创新,但从成本和效率上来看,它都不失是一种值得考虑的途径。

好的设计,从实现的层面上,要具有可扩展性。尤其当你的设计会成为标准,在多个场合应用的情况下,设计就必需要为多种应用场景留出必要的扩展空间,不然这样的设计就会很难让人来复用,最终失去了设计和标准化的意义。

在这一点上,已经有人恶搞了一下新版标识在”高铁南京南“站应用的效果图,不解释。

新版导向标识在高铁南京南站的应用场景

新版导向标识在高铁南京南站的应用场景

好的设计,在满足了基本的应用需求和设计思想后,最终还是要能给人一种设计美感。一些细节的设计和艺术的加工,是可以帮助设计本身更好的去实现它所应该具备的功能性的。

新版导向标识,包括鼓楼站站内最近更新的各块标识牌,都把原本很有特色的宋体风的字体改成了普通黑体(Serif风变成了Sans-serif风),英文字体虽然一直是Sans-serif的,但是字体也变得更平庸了。虽然美观这件事是见仁见智的,但是我个人觉得把一种有点特色设计变成了一个平庸的设计,大部分情况下恐怕是欠考虑的。

做一个好的设计很难,但更多的时候,传承一个好的设计更难。后来的人常常因为没有经历最初创作的过程,从而无法发现和理解一个设计中所内涵的东西。尤其对于一个功能性很强的东西,在时间、资源等限制条件下,被遗忘或者妥协掉的,总是设计。这也是南京地铁标识系统中现在的问题所在。

有时候,我们会嚷嚷着说,时间来不急了,我们先把东西做出来,细节上的东西和实现上的优化我们以后慢慢再改。但实际上,这种口号从来都只是一种美好的愿望,在功能实现的时候,不管是出于资源有限还是人类天生的懒惰,所有的改进和设计的愿望都会被抛到脑后,并且随着时间的推移,这种愿望实现的成本会越来越高,从而最终无奈的放弃。

做一个好的设计、传承一个好的设计,有时候只需要我们在刚开始的时候多走一步,比如采用文档、标准化等方法把一些基本的东西规定下来,事情就可以得以顺利的推进,并且也许不会增加太多的成本。但是一旦涉及到更改,成本总是会变得很高。可惜人们常常都是短视的。

以上图片资源和部分观点转载自地铁族论坛:链接一链接二

以上所有观点都适用于软件系统的设计和开发。

魔术小游戏 – 猜车厢

整理硬盘时发现了这个2002年时写的已经被我自己都忘记到犄角旮旯里的小程序,虽然它从2002年8月起就一直在Internet上以一个几乎固定的URL存在,也曾经在CSDN软件中心发布过,但似乎所有的搜索引擎都没有发现它的存在。

这是一个魔术大师大卫·科波菲尔的观众互动魔术的翻版,某年春晚上李咏用过一个演化的版本表演过。最近看了一本不错的数学科普书:从惊讶到思考-数学的印迹,其中有一节介绍了一些电视互动魔术中如何通过概率学原理给人造成错觉。不过我这个魔术不是错觉,而是有简单而确定的数学原理在里面,想不明的TX可以到我的那篇有关二进制的文章里去寻求启发。

下载地址是:http://www.freemindworld.com/g34/csdn/Magic.zip

程序截图

程序截图

UI比较丑。用VC6写的,Windows用户应该没有鸭梨,Linux用户可以用wine,但预先要把Visual C++的运行库装上。从现在的眼光看,用原生应用程序来做这么简单的应用实在是自找麻烦,完全可以很简单的用JavaScript在网页上来实现。我在考虑是不是可以做一个在Bambook上运行的Widget呢?

劳动节到了,祝大家节日快乐!

在Linux下玩转MIDI

曾经我非常热衷于MIDI音乐,原因是一直没有机会正儿八经的学习一种我喜欢的乐器,于是在电脑上用HappyEO和Cakewalk制作一些音乐(或者说噪音?)便成为了生活中的一个重要部分。但是最近相当长的一段时间中,我都没有再玩过MIDI音乐,原因只不过是因为我从台式机换成了用笔记本电脑和开始使用Linux……

先科普一下有关MIDI音乐的简单知识:MIDI音乐文件中存放的是音乐的乐谱信息,而不是实际的声音。乐谱信息以一系列的消息组成,比如:用最大力度的50%按下钢琴上小字一组的C键、持续1秒、松开小字一组的C键。电脑在播放MIDI文件时,需要由音源设备把MIDI消息转换成真正声音,再播放出来,音源设备的好坏就直接决定了MIDI音乐的回放质量。

在Linux中玩MIDI,本身也不该是件什么难事,但问题是在于Linux的声音系统一直以来处于非常混乱的状态,各家争鸣百花齐放,使得配置起来很是复杂。另外,现在很多电脑的的声卡上都不带音源设备,这样就没有办法直接用声卡合成声音。

要在Linux下玩转MIDI,就得从这以下方面入手:

驱动层:早期Linux用OSS来驱动声卡,而现在这一块基本上已经由ALSA来一统天下,当然ALSA也提供了OSS的兼容层来保证一些古老的应用。这年头,电脑装好Linux后能正常发声的话,ALSA应该就已经是在正常工作了。

中间层:一些新的发行版都用PulseAudio做为一个应用中间层,通过它去统一应用软件与ALSA的接口。不过这个东西对于玩MIDI这种“专业”的事情来说,不是很有用。我们需要的是Jack。Jack是大部分音频处理软件所使用的输入输出组件,它具有高性能低延迟等优秀的特质。

音源:如果声卡没有硬件的音源,或者硬件音源烂到只能发出电子味很重的声音。我们就需要一个软件音源,通过加载音色库(SoundFont)文件,把MIDI信号合成为声音。Linux下常用的软音源有fluidsynth或Timidity++。另外还需要准备合适的音色库文件。

音序器:简单的说就是用来作曲的软件啦,由于把各种MIDI信号组合到一起形成一个音乐作品。上面说的Cakewalk就是一款Windows下的古董级的音序器了。在Linux下,最有名的当属Rosegarden了。

最终的工作流程就是用Rosegarden谱曲,在fluidsynth或Timidity++中加载好音色库文件,用Jack把Rosegarden的General MIDI Device输出端口连接到fluidsynth或Timidity++生成的Synth输入端口。

以Debian Squeeze为例,在ALSA工作正常的前提下,安装以下软件包及其依赖包:jackd, qjackctl(Jack的图形前端), qsynth(fluidsynth的图形前端), rosegarden, fluid-soundfont-gm (一个音色库文件)。

sudo aptitude install jackd qjackctl qsynth rosegarden fluid-soundfont-gm

安装完后就可以启动JACK Control和Qsynth,首先点Qsynth界面上的Setup按钮,在Soundfonts页中指定要用的音色库文件,如:/usr/share/sounds/sf2/FluidR3_GM.sf2,重启音源引擎。然后可以打开Rosegarden,这时在JACK Control的Connect按钮对应的窗口的ALSA页中会可以看到Rosegarden的输出端口和Qsynth的输出端口,选中它们点“Connect”把它们连起来。同时确认一下在"Audio“页中,Qsynth的输出端口也已经与”system“的playback端口连接正常。

Qsynth设置

Qsynth设置

JACK Control ALSA设置

JACK Control ALSA设置

JACK Control Audio设置

JACK Control Audio设置

大功告成,在Rosegarden中打开一个MIDI文件,或者自己涂鸦几个音符吧,点播放以后就应该可以听到MIDI音乐声响起了。

Rosegarden界面

Rosegarden界面

除了Rosegarden,Linux中也有其它一些音序器软件,比如tuxguitar,就是专门为吉他爱好者准备的。

HappyEO是一款在Windows下用电脑键盘模拟电子琴的软件,也能当成音序器的MIDI信号输入输出设备。这个软件在2000年到2006年间占用了我无数的时间,我乐在其中的用它制造了无数的“噪音”,直到我换了笔记本电脑(没有了标准键盘)和开始用Linux。在把Linux下的MIDI环境配置好后我就迫不急待的用wine尝试运行这个软件,软件运行成功了!看到久违的界面,听着自己已经不再熟练的弹奏,还真是颇有一点激动呢。

在Debian下用wine运行的HappyEO

在Debian下用wine运行的HappyEO

进位制与数学游戏

现有1000个苹果,10个盒子,问各个盒子内应该分别放入多少个苹果,才能使得用户要买任意1至1000之间的一个苹果数,都可以给他(卖的时候是整个盒子卖,不能拆盒子的包装)。

曾经在我的那些数学玩具们——二进制篇中提到过这个问题,看过那篇文章后,答案应该是不言而喻的,1, 2, 4, 8, 16, 32……

如果把题目换成:现有一架天平,若干个砝码,每个砝码应该分别多重才能称出1至1000克整数克的物品?

答案如果是不假思索的1, 2, 4, 8, 16, 32……自然是可以的,那我也不用废话写这篇文章了。实际上1000个苹果需要装在10个箱子里,用天平称1至1000克的物品却不需要10个砝码,只用7个就够了。

差别在于:装苹果的盒子只以能是选择拿或者不拿,而天平则可以不放砝码,或者把砝码放在左边,或者放在右边。所以,我只用两个砝码:1克和3克,就可以称出1至4克的任意整数克。

因此,解装苹果的问题需要用到二进制,解天平砝码的问题则需要用到三进制。二进制有0或1,真或假,开或关的两种状态。三进制则就有三种状态,0、1、2或-1、0、1(平衡三进制)。

在生活中,也有不少东西具有三种状态。对于天平称东西的问题(尤其是那些在XX个小球中找出X个不同的智力题)或者一些带有约束条件的过河问题,都可以用三进制来建模和解决。

进位制是一个很有意思的话题,以学习十进制和二进制的思维方式,我们就很容易的类推出各种进制的表现型式和性质,甚至于还可以捣鼓出“负2进制”之类的东东。感兴趣的TX可以考虑拜读Donald E. Knuth的神书TAOCP的第二卷。

好吧,其实这篇文章算是看了《进位制与数学游戏》一书的一小点收获了,在这本书中,作者不厌其烦的为一个相同的数学模型创造出了无数的问题和实例,所以在看完整本书后,能发现的收获也就只有那么一小点。

最后联想到了一个以前学编译原理时老师讲过的题,当时在课堂上我还真是没能自己做出来:

构造一个DFA,用于识别字母表∑={0,1}上可以被3整除的二进制数。