您现在的位置:首页
--> 云风的 BLOG
如果用兼容 qq 协议的方式来做,出于对用户的方便,可以做成网络服务,让用户提交 qq 用户名密码。但这显得不太安全。没有什么可靠的手段让用户放心。所以,退而求其次,可以开发一个开源的 qq 登陆器。因为开源,可以受到监督,并没有盗取任何好友名单之外的信息。
今天终于把作业作完了(可能还有地方要返工),Effective C++ 第 3 版读完了,写了几万字的评论。如我给编辑交稿的 email 里所写:我觉得评注这个工作比翻译难做。作者细节上讲的非常清楚,大部分地方都不觉得有必要再加注解。我想跟这本书反复写了 10 年有关。所以很多页我都没留评注,真的不知道可以写啥。编辑原想每页中英分列排版,我是不建议这样的。除了少部分评注,针对个别代码段,或关键词。大部分我的文字都是独立成段的...
这段时间除了忙项目外,还在参加游戏部门的程序技术评审。我是 6 人评审委员会成员之一。这项工作逐渐收尾了,所以随便写点东西总结一下。只是我的个人想法,不代表任何其他同事和公司。我想我们尽量做到公平公正,这个是努力方向。至于公开…… ,好吧,现在还做不到,未来争取吧。写这篇东西,算是私下为“不公开”开一个小口。在我看来,网易的管理一直都是稍显混乱的。管理层很薄弱,相比公司更重视研发技术,管理方面要差的多...
去年介绍过我在项目中实现的一个动态数组模块的接口。实际上,我为它提供的接口要更多一些,比如删除一个元素。 void array_erase(struct array *, seqi iter);原来的语义就是删除 iter 引用的元素。但这里引出一个问题:删除后,iter 是否应该保持有效?从语义上说,iter 应该在调用完毕后变成一个无效引用。但实际应用中,往往需要在迭代 array 的过程中,删除符合条件的元素。让迭代器失效的做法,用起来很不方便。
9 年前,我设计了网易游戏的资源包以及补丁包的数据格式。当初的设计目的是:方便解析,快速定位资源包内的文件,方便更新、每次更新尽可能的节约带宽。这些年来,虽然各个项目修修补补的改进了资源包的格式,但本质上并没有特别大的修改。一开始我们直接把需要打包的文件连接起来,在文件末尾附上文件索引表。当初为了快速定位文件名,文件名做了 hash 处理,可以用 hash 值直接定位文件。而资源包里并没有储存文件名信息,而是保...
Google 的 Jeff Dean 同学说,设计分布式系统一定要有 Protocol Description Language。Google Proto Buffers 的意义在于,定义了一个不错的 PDL 。protobuffers 的实现反而不那么重要了。这几天我一直在倒腾 lua 下的 proto buffers 的支持。一直在思考,怎样的接口才是最适合 lua 使用的。大多数语言下的 proto buffers 实现,都是将编码的数据块展开成本地语言的数据结构。对于 C/C++ ,这是最高效的形式。但对于动态语言,那就...
把网络游戏服务器分拆成多个进程,分开部署。这种设计的好处是模块自然分离,可以单独设计。分担负荷,可以提高整个系统的承载能力。缺点在于,网络环境并不那么可靠。跨进程通讯有一定的不可预知性。服务器间通讯往往难以架设调试环境,并很容易把事情搅成一团糨糊。而且正确高效的管理多连接,对程序员来说也是一项挑战。前些年,我也曾写过好几篇与之相关的设计。这几天在思考一个问题:如果我们要做一个底层通用模块,让后续开...
有时候,我们需要把多个模块粘合在一起。而这些模块的接口参数上有少许的不同。在 C 语言中,参数(或是返回值)不同的函数指针属于不同的类型,如果混用,编译器会警告你类型错误。在 C 语言中,函数定义是可以不写参数的。比如:void foo();这个函数定义表示了一个返回 void 的函数,参数未定。也就是说,它是个弱类型,诸如:void foo(int);void foo(void *);这些类型都可以无害的转换成它。正如在 C 语言中,具体的指针类型如 ...
今天检查 svn 仓库,发现又有同学没按规定提交包含汉字的代码。我们规律,所有源文件中包含的汉字必须使用 UTF-8 编码方式,而不能使用 GBK 。总这么人工检查也不是个事。所以我想写一个 svn 的钩子,在提交前检查。在仓库的 hooks/pre-commit.teml 加一行检查脚本应该就可以了。我想用正则表达式匹配一下,可是想了想又觉得 UTF-8 和 GBK 的编码集有点交集,不太好做。btw, google 了一下,的确有人写过特定编码的正则表达式。
C 语言,从 1970 年代设计并实现之初,它就注定了带有强烈工程师文化的语言,而缺乏一些学术气息。它的许多细节设计,都带有强烈的实用化痕迹。C 语言因 UNIX 操作系统而生,是 UNIX 系统的母语。这导致在这个广泛应用的操作系统上开发,必须通过 C 语言的形式和系统进行交互。这不仅影响了 UNIX 一个平台上的软件,既而也影响了后来世界上最大的桌面系统 Windows ,以及越来越多的嵌入式平台。
今天和倩女幽魂的同事讨论一个问题:他们的游戏 client 中,有大量策划填写的表格直接导入 lua state 中的大量数据。大约有 100M 以上。这样,如果玩家在一台机器上启动多个 client ,就会占用大量的内存。而这些数据,一旦加载进 lua ,就不会再修改,且每个 client 中数据都是一致的,这是一种浪费。问题是:如何利用进程间的数据共享,在多开 client 时节省这些空间。(同时也可以加快开第二个 client 的启动速度)
setjmp 是 C 语言解决 exception 的标准方案。我个人认为,setjmp/longjmp 这组 api 的名字没有取好,导致了许多误解。名字体现的是其行为:跳转,却没能反映其功能:exception 的抛出和捕获。longjmp 从名字上看,叫做长距离跳转。实际上它能做的事情比名字上看起来的要少得多。跳转并非从静止状态的代码段的某个点跳转到另一个位置(类似在汇编层次的 jmp 指令做的那样),而是在运行态中向前跳转。C 语言的运行控制模型,是一个...
有很多桌面游戏是极富魅力的。甚至只用极少的道具就可以一个人自娱自乐。我在逛 bgg 时,用高级搜索找到了这么一个只需要 6 个六面骰就可以独自享受地下城冒险的小游戏,试了一下,果然非常有趣。进一步搜索,发现了基础版的汉化版本(由 :Coolforest 翻译),把图片附在后面。Delve 由 Drew Chamberlain 设计,如果你有兴趣,可以去这个网站下载更多的内容。游戏的道具就是投骰子。一组 6 个骰子,投三次。在第一次和第二次后,...
面向对象编程不是银弹。大部分场合,我对面向对象的使用非常谨慎,能不用则不用。相关的讨论就不展开了。但是,某些场合下,采用面向对象的确是比较好的方案。比如 UI 框架,又比如 3d 渲染引擎中的场景管理。C 语言对面向对象编程并没有原生支持,但没有原生支持并不等于不适合用 C 写面向对象程序。反而,我们对具体实现方式有更多的选择。大部分用 C 写面向对象程序的程序员受 C++ 影响颇深。企图用宏模拟出一个常见 C++ 编译器...
Windows 游戏软件在发布时,通常会把所有数据文件打包。这通常出于两个目的:一是保护数据文件不被最终用户直接查看,二是 Windows 的文件系统一度相对低效。尤其是在处理非常多小文件的时候,无论是安装、分发还是运行时处理都有性能问题。而游戏软件通常会有大量的资源文件,对数据文件打包的需求更为强烈。一般游戏引擎都会支持至少一种资源打包的形式。打包数据文件的概念和实现,我最早是对 Allegro 的源码阅读学习来的,算起...
数据结构的序列化是个很有用的东西。这几天在修改原来的资源管理模块,碰到从前做的几个数据文件解析的子模块,改得很烦,就重新思考序列化的方案了。Java 和 .Net 等,由于有完整的数据元信息,语言便提供了完善的序列化解决方案。C++ 对此在语言设计上有所缺陷,所以并没有特别好的,被所有人接受的方案。现存的 C++ serialization 方案多类似于 MFC 在二十年前的做法。而后,boost 提供了一个看起来更完备的方案( boost.serial...
继续昨天的话题。随便列些以后成书可能会写的东西。既然书的主题是:怎样构建一个(稍具规模的)软件。且我选择用 C 为实现工具来做这件事情。就不得不谈语言还没有提供给我们的东西。模块化是最高原则之一(在 《Unix 编程艺术》一书中, Unix 哲学第一条即:模块原则),我们就当考虑如何简洁明快的使用 C 语言实现模块化。除开 C/C++ ,在其它现在流行的开发语言中,缺少标准化的模块管理机制是很难想象的。但这也是 C 语言本身...
今天继续谈模块化的问题。这个想慢慢写成个系列,但是不一定连续写。基本是想起来了,就整理点思路出来。主要还是为以后集中整理做点铺垫。我们都知道,层次分明的代码最容易维护。你可以轻易的换掉某个层次上的某个模块,而不用担心对整个系统造成很大的副作用。层次不清的设计中,最糟糕的一种是模块循环依赖。即,分不清两个模块谁在上,谁在下。这个时候,最容易牵扯不清,其结果往往是把两者看做一体去维护算了。这里面还涉及...
以前写过一篇 可不可以只有密码没有用户名? 。里面提过一个让用户使用 email 做用户名,不设置密码的方案。今天想细化一下。不设置密码有时候比设置密码,给用户的安全方面的感觉更好。因为,有些服务用户并不在乎帐户数据的私密性,也不在乎被人冒充。(比如在我的 blog 的留言,并不需要注册)要求输入一个密码,对用户反而是件很纠结的事情。用自己常用密码吧,若被服务商恶意记录的话,自己别的位置的帐户变得不太安全。随便...
这几天白天都在安排面试,其实还是有点累的。晚上就随便写点程序,好久没摸 C++ ,有点生疏。也算是娱乐一下吧。主要工作其实是在 C 库的基础上做一个 C++ 的中间层。跟在 C 库的基础上做 lua 中间层差不太多。前几天加入了 gc 后,发现了一些有趣的用法。比如对于构造对象。 C 的 api 中,如果创建一个对象失败,就会返回空指针。但是对于 C++ 就不一样了,new 是不应返回空指针的。书本上的推荐做法是在构造函数里抛异常。但是我...
近3天十大热文
- [2527] 代理的加密部分
- [1327] 创业笔记 | 从0到1开公司是什么体验
- [646] vimgtd-在vim(gvim)中实现GT
- [570] 查找第K小的元素
- [70] Oracle MTS模式下 进程地址与会话信
- [65] 【社会化设计】自我(self)部分――欢迎区
- [65] Go Reflect 性能
- [61] 如何拿下简短的域名
- [61] 图书馆的世界纪录
- [61] android 开发入门
赞助商广告