九天雁翎的博客
如果你想在软件业获得成功,就使用你知道的最强大的语言,用它解决你知道的最难的问题,并且等待竞争对手的经理做出自甘平庸的选择。 -- Paul Graham

小小游戏程序员八个月工作总结

主要是服务器端开发的相关经历,而监控系统也算是直到目前为止,自己负责的最大的一个工作内容了,前后开发周期长达3~4个月,最后的维护几乎持续了半年以上。受益匪浅,这几乎也是我开发独立的服务端程序的绝唱, 后来逐渐的真正融入游戏的开发团队,开始了游戏逻辑服务器的开发,这是后话.

说明:分3部分写,工作内容及其解释,实际我做的事,我获得的经验。

1. 游戏日志服务器:

上次四个月工作总结的时候,正在做日志服务器。基本接近完工了,所以完成后没有什么新的收获,唯一想说的就是,工程编译以生成不同文件名的方式来区别不同的版本,比如debug版本添加_dbg后缀等等,其实会对多进程的调用造成困扰。日志服务器中因为额外新建了一个专门用来创建库的工程,导致最后的问题就是创建库的那个工程名字的每个后缀组合我都得通过修改日志服务器来完成。这点比较郁闷。呵呵,说的不够清楚。
比如当外部文件编译成xxx_dbg.exe,xxx_l.exe的时候我CreateProcess就得区分开。。。。

2.监控系统:

内容:我完成的部分包括监控中心,监控点,受控程序模块,这基本也是我在公司参与的唯一一个完整系统了。所谓系统,已经包括了监视,控制等完整功能,几乎完全独立于其他模块,自成体系。与以前做的为游戏添加一些功能,和引擎的文件系统比起来,这个工作就要大的多,实际上第四到第七个月,我大部分时间就在干这个。。。。。。。
经验嘛:公司的服务器框架用的已经很熟悉了。。。呵呵这点很重要。对于完整的系统设计的概念也是有的很大的认识,这个系统光是设计花了一个月。一个月以后才开始真正的编码,编码实际花了二周,第一周是非常夸张的,就我保守估计,我第一周内编码量超过5000行。监控中心,监控点的几乎所有代码都是这一周完成的。第二周进行了一些与监控系统客户端(由同事完成)联调的工作,完成了受控程序模块。第三周进行了一些扫尾工作,比如封装了一个多进程的类,用来将windows/linux的进程调用方式和控制方式统一一下。完成了游戏服务器程序更新所需的ftp下载及解压缩功能。这时候我了解了一下curl:)很好的一个开源库,并且发现解压的时候用命令行的rar等工具比用库要方便的多。。。。。。

3.H.264视频处理

内容:本来的意思是要我看看公司原有的H.264库中是否存在bug,导致了当时测试的失败。熟悉以后可以考虑一下怎么进一步改进效率。本来挺有意思的。。。后来发现是上层模块的问题,这个工作就没有做了。。。。郁闷了很久。。。。
经验:其实看源代码的时候倒是发现了一些事情。。。宏啊。。好用。。。
内嵌汇编啊。。。。还是好用
内存分配管理及对齐。。。。。公司那个库里面做的真的很有意思。这是我第一次看到直接用指针操作内存完成了一个链表。

4.数据校验工具

内容:优化公司以前就有的一个数据校验工具。实际上最后我发现原有的工具那个做的啊。。。不仅仅是效率低,那个组织结构就没有办法看。。。一个类的实现(同一个文件)写了7900多行。。。。我倒是真想在原有基础上优化一下效率就可以了,结果感觉不动框架就没有办法做下去了。结果几乎重做。用了我近一个月。。。(其中近两周实际上在熟悉所有的数据管理类及工具,不熟悉这些好像也没有办法做数据校验)
经验:起码对公司的整个游戏底层数据管理的框架及方式有了大概了解。其实这里要说一下的是。。。这里也碰到了工程上的问题,由于每个数据管理模块不见得是同一个人完成的,所以质量千差万别,好的非常好,差的不能看,类层次的设计也是很不一样,有的多到7,8层,有的扁平到2层。唉。。。。可怜的游戏数据最后感觉就像是拼上去的。。。。。数据管理的效率我就不说了。
优化的过程中又看了很多代码,对于原有同事对C++的使用上的问题有了一些看法。虽然以前那个程序能用,但是实在效率太低了。。。难怪老总受不了要我来优化。
先说结果,原有的数据校验全部校验完毕要1个多小时,我做完后,做的校验逻辑比原有的还多,实际只需要不到5分钟。
这里说几个例子。。。。返回引用的接口,用Object来赋值也是可以的,不会有什么问题,但是实际却多了一次赋值。取得所有key,然后一个一个去find一个map也是可以遍历的,但是效率啊。。。。。。。

5.全局内存分配管理模块

正在做,为了不断节,留待下一次再写吧。

其他:

1.内联函数应该在头文件中定义,不然编译可以通过,连接却通不过。这点好像是C++编译器的缺陷或者说是C ++语言的缺陷也可以。这点和模板也有点像,说实话,不是有什么问题,但是导致了一些原则的违背,比如分离编译原则,文件包含原则等等。。。。
2.map earse返回下一个元素的迭代器不是C++标准的一部分,不应该依赖,虽然VS是这样做的。这点MSDN中关于map earse函数的描述及C++STL都有讲。
3.expat XML解析器是CEGUI中提供的几种备选解析器中效率最高的,我实际测试过。
4.分开测试,避免互相影响,导致你不知道到底什么出了问题。

对公司目前的一些代码的想法:

1.枚举时有意义的值,哪怕是none,也应该定为0,不应该是-1,-1只能用来表示无效值/非法值。这点公司的代码做的很不好,我做数据校验的时候感受特别深,本来一个范围就可以解决的东西,偏偏要用||,&&。。。。。
2._t的后缀用来表示typedef的很好用,这点我们公司没有规定,实际上的typedef很多时候都是直接C开头了,比如CGameMap来表示map<id,gamemap*>这样的东西。
3.软件源代码管理上,可以考虑像linux开发一样分两条树,一条稳定树,一条开发树,任何人想调试代码从稳定树中取代码就可以了,然后将代码对比添加入开发树,开发树的代码必须经过测试组的测试验收后才能放入稳定树,并且稳定树的bug修改,除非是非常直接的严重bug,不然都应该修改后放入开发树中。新功能的添加更加要放在开发树中。每个独立树应该包含所有的源代码,lib库,dll库及相关的exe,甚至可以包含数据和文档。
这是我的切身体会,由于我老是从服务器组换到客户端,换来换去,每次换到一个环境中,要想搭建一个调试环境都是异常困难,加上公司经常有人将编译不过的代码放到soursesafe中或者出现只放了.h没有放.cpp(或者相反)的错误(这些错误我也犯,有的时候可能难以避免),再加上lib.dll的依赖问题,同步问题,一天很多时间就浪费在这上面了。因为现在游戏的工程大了。。。光是全编译一次都要20分钟以上。我想,这应该在工程管理的角度上加以改进,而不是靠每个人去保证自己的每次提交都是完美的。
4.定版以后的文档不应该直接修改,而是写修改文档,特别是对于底层库的文档。修改文档中应该明确标明修改的部分及影响的范围,解释,原有接口废除的除了说明原因外,因为给出怎么换成其他接口或新接口。
这点也是很重要的,我的一个可怜同事不知道因为底层库的接口修改或实现修改引进了多少bug,每天就光忙这个bug就够他受的了。。。。我这样说,底层库的修改不能是无提示,无通知的模式。不能等到上层代码报bug了,才发现原来是由某某库修改导致的。这是什么效率啊,现在客户端偶尔崩一崩还好,工具偶尔不能用还好,不能想象游戏运营以后还这样怎么得了。
5.工具的数据应该实时校验,即在策划输入数据的时候校验,而不是像现在我们公司做的这样,由一个统一的数据校验器来完成,这点我觉得很容易理解,每个做自己工具的人都能更好的把握此工具的逻辑限制,要我做数据校验,无论我怎么努力,我也不能完全知道10多个工具的每个逻辑限制啊。谁都难以做到。每个工具本身应该保证这点,保证它保存的数据就是经过校验的,当出现问题,第一时间提示策划,策划马上更改,也比等数据全部从数据库中导出成文件了,由数据校验器来完成,报上问题,再叫策划去更改要有效率的多。从开发的工程角度上来讲,这也很符合将问题细分而不是将问题统一在一起的原则。

分类:  随笔 
标签:  工作总结 

By 九天雁翎

2008年12月07日 | 九天雁翎的博客

前一篇: 个人研究《数据结构与算法分析-C++描述》Vector实现的问题,new与初始化 后一篇: 漫谈C++中的宏