« January 2007 | Main | March 2007 »
这是一个值得纪念的日子,1946年2月14日人类历史上第一台现代电子计算机诞生了。
当然不光是程序员需要纪念这个日子。因为人类的生活都被计算机在改变,所以,许多不是程序员的人也在以各种形式庆贺,看看街头的人流、鲜花和气球就知道我所言非虚。
正经点说: 这并不是世界上第一台计算机。正如楼下评论中 dayn9 兄所说:宾西法尼亚的计算机是抄袭保加利亚裔物理学家的。
我是招商银行的忠实用户,第一张招行的卡好象是 2000 年办的,到现在为止已经有七张招行的卡了。不论是普通借记卡、信用卡、还是 VIP 卡的服务我都非常满意。而且一直极力游说我的朋友使用招行的服务。这些年来也认识了一些在招商银行工作的朋友。老实说,招商银行给我的感觉要比国内其它银行好上许多。
不过近两年来,我和许多人一样开始抱怨招行的网银服务。不是因为太糟糕,只是一种恨铁不成钢的感觉吧。相比较而言,前两年我申请了农行的网银,还为之付了一百 RMB 。当极力促成公司把工资发放从农行转到招行后,我就立即花钱注销了农行的帐号(帐号里没有余额,但是注销需补交帐号管理的年费,另外为了注销帐号,还专程打车来回)。那个网上银行再不好用,都没有太抱怨过。当时我一个月只用一次,就是在网上把工资转到招行帐号上而已。
一开始,招行的登陆用 activeX 控件会导致我的 DELL 预装的 Windows XP 上的资源管理器 crash 。投诉过一次,没有回音。后来不知道是 windows update 了还是招行控件 update 了,问题消失,也就没再计较了。
我是 opera 的忠实用户,也尝试过在 opera 下安装招行的那个登陆控件,结果自然是失败了。最终不得不每次网上付款的时候启动 IE 。这些勉强也可以忍受吧。
最近,我装了一台 freebsd 的桌面系统。但是,招行的网银却迫使我不得不保留 Windows 系统使用。这让人非常不快。虽然我用的是正版的 Windows ,但是我还是希望有不用它的权利。《致招商银行的公开信》已经讲出了我想说的所有,不需要补充了。
支持这个倡议:友情链接一下 http://wiki.billxu.com 希望有更多的人相应。
ps. 关于招行另外的一些小问题:我的同事跟我提过前两年他去日本时,招行的两张信用卡都刷不出来,而一张广发的却可以;不过我自己曾在澳洲和美国刷招行的信用卡都没问题。不知道现在是不是好了。如果有朋友出国还是要小心点,只带一张国内的信用卡还是有点危险的。
另外,我的 VIP 卡有时候在异地 ATM 上不能取钱,普通卡却可以,这让我有点点郁闷。这个可能是银联的问题。
最后的一点点奢望是,招行的网上银行可以出一个 palm 版 :D
在 lua 的 maillist 上最近报告了一个 bug 。
看起来问题比较严重,因为稍具规模的 lua 程序都可能因此而出现问题。最近两周,我和我的同事都比较关注这个问题,并对 lua 的源代码做了相关的分析。
Roberto 作为 lua 委员会三巨头之一,在 mail 中已经表示追踪到 bug 的起因,但暂时还找不到合适的解决方案。直觉告诉我,这不会是一个简单的问题。如果容易修正的话,patch 早就有了,而不会只是发一个 bug report 而已。所以我们也并未尝试自己去修补这个 bug ,可以做的可能只有等待。
近期的一些讨论表明,这个问题出至于 lua 的 parser 在处理常数时做的一些简单优化。类似 1+2 这样的代码在编译器有可能被编译成常量 3 。
算法本身没有错,错在 lua 的一些优化处理上。
当一个 chunk 中常量少于 256 个时,lua 在生成 VM 指令时,会将常量编号直接生成在指令内;而超过 256 个常量,就必须依赖堆栈。lua 的 parser 是一次扫描的递归下降算法。在做这种常量合并(编译期运算)时,每一个常量都不能立刻生成代码,而要看它是否可以和下一个常量合并。一次扫描导致了在 256 这个临界点时不太好处理两种生成算法的区别。
我自己去年也写过简单的编译器,同样是一次扫描的递归下降算法。对于这样的 bug 的出现深有感触。
我想,这也是一种提前优化的体现吧。越是复杂的程序,执行效率越是来之不易。
3月26日补:
游戏的美术工作有时是挺枯燥乏味的。我在公司这几年看到太多美术,连续几天的辛勤工作,只为了将一批图按同样的模式修改成另一个样子。甚至这个工作只是修修通道、转转图片格式等等。
由于有些工作流程比较繁琐,甚至可能会有些变化,并不是每次操作的人都愿意使用 photoshop 中带的批量处理模式来提高效率。最终造成了一种奇怪的现象:明明人手充足,每个人每天都在重负荷的工作,但是整体的完成度却提不上去。在许多时间里,大家干的并不是创造性的工作,而是一些并不需要多少脑力的活儿。
今天碰到件事,我们需要给一些人物角色图片勾一下边。也就是把动画图素展开成带 alpha 通道的图片序列。然后把通道部分提取出来,轮廓扩大、羽化、上色,再叠加回原来的图。这样做的目的是可以把游戏里的角色从背景中突显出来。
整个过程并不算复杂。对 photoshop 熟悉的人几分钟就可以搞定。再做一个批处理器,加工大量图片似乎也不复杂。
但是我想,或许我们应该有一个比 photoshop 更好的选择。找了一下,其实我们需要是的 imagemagick 这样的软件。
甚至在教程里,就能找到上述的变换方法 。那么只需要写一个简单的脚本,一切就可以轻易搞定了。
对于需要批量处理的东西,命令行工具还是有它无以取代的优势啊。ps 一张图可能很快乐,但用同样的流程加工十张百张,却让人很尴尬了。
昨天试着维护几年前写的一个 C++ 库,只是增加一点东西。以那个时候我的眼光看,这个库设计的不算太差。这几天用的时候需要一些新功能,修改代码的话,有点担心引起不必要的麻烦。所以我决定从其中一个类继承下来,增加我要的东西。
大约花了半个多小时完成我需要的功能,由于 namespace 嵌套较多,修改编译错误又花掉了一些时间。当编译通过后,代码基本工作正常了。
事情做完了却有一点恶心。
我已经半年多没碰 C++ 了,习惯回 C 以后,怎么看 C++ 都有种说不出来的厌恶。这一年多来,我在不同的场合表达或听到过 C++ 语言的尴尬。现在无论怎么回忆,也找不回当年对 C++ 那种无比热爱的感觉了。
ps. 据说 C++ 0x 要加入 gc。总算它没有在 template 的滥用上渐行渐远,算是一点欣慰吧。
当游戏服务器群达到一定规模后,让用户只从一个入口连入会给这个入口带来很大的压力。这样,我们就需要让服务器群中的多台机器都允许用户直接连接。
当服务器开放给用户直接登陆后,必须面临的一个问题就是用户身份认证的问题。
大多数提供网络服务的公司都做了一套统一的用户认证系统,比如微软的 passport ,网易的通行证,等等。为了避免重复验证用户身份而给用户认证系统带来过大的负担,云风在这里给出一个参考解决方案。
登陆服务器可以只有一台,专门用于用户第一次登陆的身份认证。它认证完用户的身份后,则发放一个游戏系统内部用的临时通行证给用户,用户可以拿着这个临时通行证到指定的地点玩游戏。
我们需要讨论的是,以上流程中的安全问题,以及如何加强安全性。
用户认证过程自然不能传送用户密码的全部信息,这跟密码是否加密无关。简单的安全措施是先由登陆服务器发送一个随机串给用户,用户把这个字符串同自己的密码连接起来,并 md5 以后传回服务器做验证。(这里用 md5 指代一种特定的不可逆 hash 算法)
临时通行证的生成可以是这样: 登陆服务器从数据库中取得用户所属的服务器 id (通常是他最后一次登陆的位置,或者游戏逻辑认为他所在位置)、用户的游戏 id (往往不同于他的用户名)、一个约定字符串、一个顺序版本号、一些随机字节、把它们连在作一次 des 加密(这里用 des 指代一种特定的可逆密匙加密算法)。每生成一次临时通行证,版本号递增。加密临时通行证的密码由登陆服务器与每个可以接受用户直接连接的服务器约定,永远不传送给用户。
用户拿到这个临时通行证后,可以用之一次性登陆指定服务器。直到从服务器正常登出,若需切入新服务器,可由老服务器生成下一份临时通行证。临时通行证由于被服务器加密,所以对用户来说是一串无意义字符串,故而无法伪造。
临时通行证传送给用户时,可用用户自己的密码之 md5 值(或者连接一个约定串增加安全性)做密匙加密。这样不知道密匙的人截获数据包也不能获得临时身份证。而临时身份证总是一次有效,且只针对特定服务器(服务器会检查临时通行证中包含的版本号、服务器 id ),企图用临时身份证多次登陆也会失败。