编者按:
这篇
文章脱胎于一个叫《游戏人成功学》的系列文章,它是作者长期身处游戏开发行业、亲历游戏行业痼疾后不吐不快的
随笔。世界上的任何事情都是这样,当一个人对某个事物了解越多,他也就越能清晰地看到这个事物的缺陷。编者报道游戏行业也有数年时间,觉得作者这篇文章虽然有过于“专业”的嫌疑,但比起那些行文浅显、美化游戏行业、特意以“玩家”为对象谈论游戏行业本象的文章来说,这篇文章对我们的读者和游戏玩家也更有意义。从刊物的角度说,尽最大可能展现、记录这个行业的方方面面,本来也是媒体份内的责任。以上就是我们选登这篇文章为本期专题的原因。
由于原文涉及到的专业术语很多,我们对之进行了幅度较大的修改,以期能使读者更好地理解本文。
“游戏开发成功论”?
我曾写过几篇类似《给进入游戏行业新人的八个忠告》的文章,被个别朋友吹捧了几下之后,自己颇有点传道育人的成就感。但后来仔细琢磨,发现应该被教育的恰恰不是新人,而正是如我一般或比我高大睿智的所谓的老人、前辈、制作人和领导。新人终究有超过一半的机会通过试用期,但勤奋刻苦的中国游戏制作人们所领导的上百家开发公司,穷多年之力,到今天为止,真正成功的产品仍寥寥无几,其中世界级的产品,数量等于零。对比可见,老人、前辈、领导和伪高手们比新人更需要教育。有了被教育的觉悟,首先做的是反省和自我教育,本文即是一个从业有些年头的冒牌高手——我的几点零碎感悟,希望能以点博面,给读者少许启发。
是为序。
一、从D&D看游戏的底层设计
把一个所谓的游戏意义上的伟大创意在游戏产品上付诸于实现的前提,是所有的设计应该符合游戏工业设计规范。
——龙云峰《EEE&Lumines: Design for Business》
这是我第一次看到有人这么明确且重视地提出游戏工业设计规范。在中国游戏发展这么多年的情况下,到2006年才由一个入行不久的“准老人”提出,对于所有在职的“老人”和“大师”们,都是一种绝妙的讽刺。
可能很多玩家都奇怪,为什么一个国产游戏会拖期再拖期呢?为什么拖期之后出来的却是个
Bug不断的半成品呢?为什么一款网络游戏开发到后期,连画面风格都要做出调整呢?游戏开发目前几乎所有项目的症结,归根结底都与游戏设计的架构和流程有关。其实玩家们不知道,在国内游戏项目的进程中,下面这些糟糕的状况经常会出现:
1)项目中期发现,如果编辑器支持一个特殊功能将能节省美术1/3的
工作量;
2)做到第25个月发现所有美术风格相比某游戏已完全落伍,不得不重做;
3)你和所有的人都知道游戏有什么功能,但没有人能说出游戏为什么好玩;
4)一个程序的离职导致全部渲染底层需要重写;
5)你的MMO内测中,发现玩家只要1星期就能练到100级,而这是游戏的最高级别;
6)游戏最终版本与提案书对比,只有不到30%的功能得以实现。
这些只是几个我曾经听到的例子,而很多更加荒诞的情况都在不断上演、不断重复。我曾经跟一个在做
项目管理的朋友说过,我们一直在重复你们过去曾经犯下的错误。似乎所有团队都必然要交这样或那样的学费,可悲的是更多的人交了学费仍不反省,仍然采取侥幸态度忽视游戏初期设计的作用。也因此,我们今天看到的国产游戏成功者仍然寥寥无几。
要避免后期开发中的混乱局面,在游戏设计的初期,就需要首先建立软件工程规范化的概念。什么叫软件工程?它是一门研究用工程化方法构建和维护有效的、实用的和高质量的软件的学科。它有三大要素。
1.目标:生产具有正确性、可用性及开销合宜的产品。
2.过程:生产一个最终能满足需求且达到工程目标的软件产品所需要的步骤。
3.原则:是指围绕工程设计、工程支持及工程管理在
软件开发过程中必须遵循的原则。
游戏软件的开发与其他软件开发相同,都要符合软件工程的规律。游戏的最根本本质是一个软件,文化产品只是软件完成后的附加属性——很显然的,OpenGL不仅能用于开发主视角射击游戏,也能开发工业CAD软件甚至远程医疗软件。商业软件的系统分析是针对用户实际的特点,来决定用户的现实需求如何能在软件开发中实现,而游戏软件的开发也是同样的道理。一款游戏是否能顺利开发完成,取决于它的结构是否符合软件工程规范,这是降低游戏开发难度和项目复杂度的前提。因此,我将游戏设计符合软件工程的要求,定义为游戏工业设计规范的一个基本条件。
而这对现在的中国游戏人而言,无疑是一个非常苛刻的要求,或许更有人会说这在目前的国内游戏行业也是个空想。但我们不妨仔细研究一下D&D这种老牌的桌面游戏规则吧!它至少符合一个严格的软件工程所需要具备的基本特征。仔细研究D&D,你会发现,所有的对象,通过基本属性、天赋、适用规则等(内涵构件)进行定义;通过规则操作,如魔法攻击(接口)进行相互作用;通过模板、种族、职业(类关系)进行衍生和统一。由于设计者将本来错综的游戏世界高度概括成数字化的规则(生物/人造/自然物件的基本属性和基本属性作用规则),因此在面对整个游戏世界这个巨大的复杂系统时,D&D具备几乎无限的扩展能力,可以适应不同科学发展度,不同文化的背景设计。
理论上,构建一个虚拟的世界,它的基本要素越是高度概括和定义的,那么底层设计工作的重用性就越高,扩展性也越大,同时,由于每次依靠本层次控件和规则构成往上一个层次时都可能与最初的设想有极小的偏差,因此最终层次的表象控制就越难。如果我们把当前的宇宙视为一个游戏项目,那么,上帝至少在设计之初将“夸克”视作最底层的材料,而我们看到的整个世界都是由几种基本的“夸克”构成的(看来上帝的美术工程师很省工)。由于层次非常多,这个世界最后的面貌很可能与上帝的提案书差距非常大。当然,上帝可以在最高层直接添加规则来更改这个差距。
D&D代表了目前游戏设计能够高度概括到的极限(或许《进化》能打破这个纪录,还没有看到游戏,不知道具体情况)。我们做游戏设计,没有必要做到这个层次,只需要抽象到玩家看到的具体控件的下面一层就可以。例如MMO中有设计纸娃娃的需求,里面有衬肩,那么,我们只要比常用的做法更进一步,将衬肩再向下一个层次,分为贴图风格、形状、特效种类、特效颜色4个基本控件,那么,只要每个控件做少量几种就能组合成很多种类的衬肩,这样规划可大量减少美术的工作量。而常规做法只能是一个个衬肩去建模和绘制。
概括和定义底层是游戏设计对商业需求分析后最简单的一个步骤。在分析商业需求过程中,我们可针对各个方面抽象出类似的关键问题:
1)NPC、怪物、Boss和玩家角色是否属于共同的类?如果是,这个类如何定义?其子类如何定义和区分,基本属性、骨骼、模型、纸娃娃、动作是否通用?各子类是否有必要定义各自的子类?这些所有定义对于美术和程序工作的影响何在?
2)职业、种族作为通用模板如何对上述的类中的对象进行作用,其作用是否与子类的定义相关?
3)作为场景设计的需求,有多少建筑对象以构件组合方式可以作出变化?如是,组合需要支援多少种风格?有必要单独设计的建筑有多少?
4)有无可能以一种统一的升级规则操作基本属性来控制所有的平衡?
这种问题还有很多,根据游戏类型的不同,进行设计时的需求也有很大变化。
游戏设计符合软件工程的要求,需要项目负责人有基本的软件工程知识,并有相应领域的专家加以配合。很多Boss和Leader喜欢拿到提案书就开始督促手下人干,事实上,如果给大家几个月的时间实现一个规范的工业设计,就能避免以后无数的问题,节省大量返工的成本。
前面说到的是游戏开发这个项目的初步设计问题,接下来我想谈一下我对于游戏设计过程具体管理的看法。
游戏工业的理想状态,应该是流水线生产、精益生产、个体创造的结合,在策划阶段、游戏架构阶段、试生产阶段、测试阶段需要采取不同的策略,从而最大程度降低风险、降低成本及控制开发时程。注意“面向过程的管理”这个精益生产的实质,正是游戏开发未来所必须追求的目标,也是实施游戏工业设计规范所不可缺的部分。长久以来,游戏业内的管理是“面向人的管理”或“面向目标的管理”,甚至有的连目标管理都没有,而不用说进行真正的过程管理。
肯定有读者会说:谁说中国游戏开发没有过程管理?没有月表么?没有开发计划么?没有工作日志么?我要说的是,并不是表述了过程就可自认为进行了过程管理,也不是每天跑去问程序进度如何就是做了过程控制。“面向过程的管理”包括非常多的技巧和细节,这需要管理者去研究、规划和控制。
二、项目开发中的混沌和秩序
我们可能都听说过这些说法:“你不可能不劳而获”“覆水难收”或“天网恢恢,疏而不漏”。如果这些谚语对你说来不算陌生,而且在日常生活中你也反复有过这样的亲身体验,那么你就懂得了热力学第一定律和第二定律。
——《熵:一种新的世界观》
在游戏开发过程中,很多人应该有过这样的经历:整个项目的细节越来越多,但没人知道整体是个什么样子;自己做的工作越多,越感到没有信心和无助;不断修改、修正和返工。其实,这就是热力学第二定律所表述的,整个项目的无序性在增加,如果不加以控制,那么最后的结果就是进入最无序的状态,也就是整个系统的平衡态,即完全裹足不前的状态。事实上,无论游戏制作人意识到与否,游戏能否正常开发完成、能否达到立案之初的目标,很大程度上取决于游戏团队对抗热力学第二定律的能力。
之所以熵增原理对游戏开发影响如此之大,是由游戏开发本身的特殊性所决定的。以制造业为对比,制造业发展到现在非常成熟,其整个工程的无序性和不确定性并不随着规模的增长而质变,原因在于:
1)产品各部件的质量定义非常清晰(目标清晰,需求明确);
2)每道工序对于最终产品的作用易于进行量化评估;
3)成熟的流程管理或过程管理机制;
4)专业化的团队;
5)最重要的,足够的理论指导和经验积累;
以上是使传统制造业免于熵增原理荼毒的几个关键因素,而游戏开发业显然不具备这些因素。结果就是,制造业常规状况下都能完成产品的量产和销售;但只有不足一半的游戏正常开发完成,而达到立案目标的可能不足2成(仅仅从国内的状况而言可能更少)。
大型的游戏项目从立案到策划案,到程序架构设计、底层开发、工具开发、上层逻辑编写,到美术资源制作、到整合、到测试,经历了一个单向资源流动的过程,这个过程类似一条河流在流动过程中不断吸纳支流,最终汇流入海。在资源传递的过程中,由于传递的层次很多,在语言和文字的表述无法绝对精确的状况下,多次的传递不仅容易产生错误、遗漏,还会不可避免地出现误解。每个层次资源传递中出现一点的偏差,汇总到最后可能出现若干巨大的错误,这就是“差之毫厘,谬之千里”。
在缺乏成熟管理机制的游戏开发业,使得热力学第二定律在这方面有了很大的发挥空间。某些策划懒得写必要的文档,依靠口头说明办事;部分团队没有工作总结;很多策划不知道能通过非语言手段(图片、拓扑等)表述信息;更多公司从来不写会议纪要和讨论纪要;绝大多数制作人都没有项目关键词定义的概念。
因此,要首先重视定义,才能制定有效的沟通机制。
在论坛里或朋友之间,我们经常能听到某个朋友说:“如果XX游戏这样设计就好了”,或抱怨说:“XX游戏为什么没有继承前一代的某种优点?”在游戏开发中,我们用“功能模块”来表示玩家所提到的这种乐趣点。一个功能模块往往代表了玩法的一个方面,当足够多的模块被整合之后,玩家所看到的就是我们希望展示的游戏世界。很多设计者试图堆砌足够多“好玩”的独立系统来形成一个“足够好玩”的游戏。“好玩”的独立系统随着新游戏的推出在不断增加,因此形成一个“足够好玩”的游戏需要的部件越来越多了。由于每个游戏模块都会通过某些接口来操作游戏属性/游戏进程,从而发生作用,这些操作与其他模块的操作可能产生相似/互斥的结果,甚至可能改变其他模块的开关状态。因此理论上,每个新模块被整合进入系统时,制作者都必须检查所有与此模块具备公共操作区域的原有模块,甚至必须检查所有操作可能带来的属性变更对依赖属性的原有模块的影响,这在系统足够大的时候是不可能完成的工作。
这带来了另外一个熵增的根源,项目的复杂度随着模块数量的代数递增作几何递增。即制作人对项目的控制力和把握会随着项目规模的加大而迅速降低,当复杂度到达一个临界点时,制作者追加任何模块,其整合成本对团队都是无力承担的。在这种状态下,依靠堆砌的制作人会在一个阶段之后突然发现,大量问题突然的、集约的出现。
相对稳妥的做法是:确认核心需求,并围绕核心设计必要的外围需求,从底层构架一个层次分明的需求,避免堆砌大而全的四不象,突出重点。
熵增原理作用的一个重要来源是缺乏计划性。由于缺乏经验和理论指导,加之相对漫长的开发过程导致市场的快速变化,在开发过程中,游戏制作者经常主动或被迫频繁地调整策划细节,这种藐视计划性的做法直接导致软件开发目的的不确定性递增。而不确定性反过来作用于游戏团队本身,使开发人员泄气和疲惫,降低工作效率和主动性,最终没人会相信工作计划,也没人会尽力做好自己的工作,因为这个工作随时会扔进马桶(被新的需求取代)。一种极端的状况是,有些团队连基本的工作计划和里程碑都没有,每周的工作完全是项目经理来临时安排;另一种状况是,一个既定的计划不会被尊重,开发计划几乎每星期都会推倒修改。很显然,这两种状况下开发已完全失控,其无序性远远超出了正常范围,开发团队必须付出几倍的预算和时间才能获得一线生机。
所以,像对待承诺一样信守你的计划——千万别轻于承诺,但承诺了就要做到。
以上说的是3个常见的现象,本章我们讨论的热力学第二定律,其实代表了项目开发中混沌和秩序的对决,而对抗热力学第二定律的实质是,追求设计规范所带来的秩序和控制力,减少无序性和不确定性。
三、游戏设计的量化问题
我们谈过了游戏开发过程中面临的诸多问题,但这里还有一个基本问题是——是不是所有开发工作都能被量化?
很多游戏从业者都对此问题持否定的态度。游戏产业是一个创意产业,创意和艺术创作怎么能被量化?所以就有很多号称牛人所写的文章、接受的采访,大谈游戏开发管理的难度,主要根据是,设计工作/艺术创作无法被量化。
真是这样么?
在长度度量衡没有被发明之前,我们可以猜想,人类只能使用简单的表述来说明距离或长度,例如“高”“很高”“远”“很远”“非常长”等,在现代人看来,这种表述“十分不量化”,但在当时的人类认知中,长度应该是无法量化的,因为缺乏一种单位标准,可以使得不同的人能对长度进行同样精确、相同认知的表述。这里,我们可以看出,至少在数学概念的量化上,需要“单位标准”的确定作为前提。
在上面的例子中,一旦加减法被发明出来,度量衡就会出现,人们会定义长度的单位和换算方式,此时长度就变为可量化单位了(看到这里,会不会觉得《文明》系列中的科技缺了不少?)。
所以,认为游戏开发工作不能被量化的游戏开发牛人们,要么是对游戏开发工作根本不懂;要么就是对其他行业的研究成果视而不见,坐井观天;有更多的混子们觉得“不能量化”是糊弄投资商和Boss最好的挡箭牌。
大家可以去Google查查“量化管理”,这已经是项目管理学最基本的概念,但居然还有这么多游戏业的牛人、老人嚷嚷无法量化,只能说悲哀,这行业的现状让人欲哭无泪。
关于如何“量化”的攻略不管是在网上还是网下都已非常多了,也非常系统了,这里且不多说。大家去搜索一下,注意多看广告和网站的,人家本质上也是创意产业……看完以后你保证有抽那些“无法量化”牛人的冲动。
在整个游戏开发设计过程中,没有一个阶段是绝对无法量化的,不过存在一个量化成本的问题。因为量化需要度量,度量过程需要建立标准、对比标准,对于很多无法用数字表述,必须借助统计甚至拓扑来表述的量化目标来说,这个操作过程的成本很高。所以在游戏最初设计的阶段,也就是量化成本最高的阶段,不必使用“量化”的概念去管理和操作。但在后续开发中,必须将程序、美术等工作都做到量化管理,这是使游戏成为工业化生产的前提,也是我们进行规范的前提。
四、专业精神
有位被称为物理学大师的老先生曾经放言:“中国高校对于中国发展作出的贡献,远远大于美国最好的大学对于美国发展作出的贡献”。先不说老先生如何得出这个结论,单单只看字面的意思,很容易发现一个逻辑常识问题,就是用“中国高校”这个大集合与“美国最好的大学”这个小集合进行对比。这种连小学生都能发现的错误居然被多家媒体转载引用,实在令人匪夷所思。由此可见,现代人对于逻辑严谨、谨慎求证的基本研究态度的缺失十分惊人。
一个诺贝尔物理学奖获得者总说类似如此不专业的话(之前还说过“中国科技落后的原因是易经”“清华学生强于哈佛”等),使我这样一个物理系毕业生非常庆幸自己没有资格搞物理研究。但高兴未过半,反过头来一看中国游戏行业,亦如是也!不加考证、没有数据、没有案例,太多人开口就可以大肆放炮,提出各种貌似有理的结论,事实上,仔细看看他们的文章或言论,除了结论,什么都没有……
所以,请在你看跟行业有关的所有文章时(包括本文),仔细看看结论之前的论证过程是否存在,是否合理。
上文似乎与正题无关,但其实关系大得了不得。因为立项、开发中的陷阱,其来源往往是这种看似理直气壮,却无法抽象、无法量化、无法证明的结论。举个例子,根据我的观察,一旦游戏产品的游戏性在测试中不被认可,大部分“资深”策划都会归结于“我们的系统太少,不够丰富”,结论是“要增加《魔兽世界》(或其他XX游戏)也有的系统,甚至更多”。类似的论调往往能获得很多赞同和喝彩,而很显然的,这样的结论可以洗脱所有人之前的责任,也能为混工资的项目高层多争取一些时间。但至于这个结论是怎么得出来的却没人关心,或以一句“这是经验”代替了论证——结果常常是项目因此而滑向“全而疏”的失控深渊。
“知其然”重要,“知其所以然”更重要。因为不能“知其所以然”,那个“其然”很可能是某感知力不足人的直觉。兵无常势,水无常形,在变化如此迅速的行业中,任何只有个别案例的经验总结,如果不能被抽象、推演或证明,其作用就值得怀疑。
事实上,现阶段的年轻人,大抵是喜欢“攻略式”的成功捷径,乐于研究表象之“术”而并非深层之“道”,因此只有结论的填鸭文章倒成了最受欢迎速成的武功心法。可以想象,如果我写个游戏开发必胜100招,只写一堆狗屁结论,必定人气旺到爆,且留言中的崇拜者、仰慕者、流口水者、要求合作创业者必定多到叫喊“中国游戏业没有人才”的行业资深人士们羡慕的地步。
填鸭成功学给所有畏惧困难和缺乏钻研能力的人一个海市蜃楼,这个看似美妙的绿洲幻境后面,掩藏着无数投资者和热血青年的尸骨,而这些尸骨的游魂如同“为虎作伥”的“伥鬼”一样,继续以他们的所谓血泪和经验拼凑新的填鸭成功学,引诱下批冒险者。
填鸭成功学只是从一个侧面反映出我们多么缺乏真正专业的制作者和决策者。
我们先来考虑第1个问题:
黑社会和街头混混的区别是什么?
我们知道《教父》中的黑社会有很多特征,是任何街头混混都无法比拟的,列举几个:
1)严密的组织分工,每个人都有自己的专责(有组织结构和职位说明书);
2)黑白道的关系网(有行业背景);
3)固定的灰色收入渠道(有盈利模式);
4)有专门的用于行业联络的黑话(使用行业术语交流)
5)成员有自制力、纪律性、信仰“我们的事业”(有企业文化);
这些种种特征,加上黑社会成员的事业心和敬业精神,我们其实看到的“专业精神”在行业中的体现,换言之,黑社会和街头混混的区别是,一为专业,一为业余。
第2个已经不用回答的问题:
游戏从业者和玩家的区别是什么?
我常常问提出建议和意见的同事,你的想法跟玩家有什么区别?
黑岛,以“忠于RPG,忠于玩家”闻名,能够忠于自己的职业和角色,这就是游戏从业者专业最基本的表现。游戏行业的工作涉及到方方面面,游戏外盒设计者是否以专业外观设计师的标准要求自己?游戏项目经理是否具备软件项目管理的基本理念和技能?游戏QA是否制定了专业的反馈流程和机制?以这种标准来看,中国不仅缺乏专业的从业者,甚至连专业的公司都寥寥无及。
专业从业者应该首先把自己从玩家的身份中升华出来,能总结玩家的反应,能将玩家眼中混沌的系统分离成为清晰的个体,能将实际抽象为理论,能将感受量化成数据。如果一个从业者的作用只是传递玩家的信息或把自己作为玩家感受的信息整理出来,那么这个从业者实质上对于整个团队是没有价值的。如果你做的仅仅是玩家能做的,那么组织要你干吗?
第3个值得我们探讨的问题:
我们用什么去定义“游戏从业者的专业精神”?
任何行业的“专业”二字,都不仅仅是技术的体现,按照大前研一的定义,技术精通者应称为专长者。英文过专八的研究生,未必能进行专业的翻译;同理,一个会写策划案或营销计划的人,未必是专业的游戏从业者。
对于不同职位的从业者,我们不能苛求一种专业的标准,但无论GM还是总经理,专业与否最直接的判断就是,专业者为寻求最精益最科学的工作结果而奋斗。如果考虑到个人与组织的协调,我们可以加上第二层的判断:专业者为个人工作结果促进组织成长作用最大化而奋斗。
就这么简单。
可是有几个人能做到呢?
对希望自己成为游戏业内专业人士的读者,推荐大前研一的《专业主义》。
五、战略的价值
战略的定义和价值问题一直是企业家和专业人士理解不太清晰的几个事中的两件事。学者和咨询公司把它说得神乎其神,实业家﹑经验主义者又往往对战略嗤之以鼻,认为它一钱不值,对于战略家的高谈阔论不屑一顾。
——郑文斌
战略是一个可以被多层细分的名词,最被中国企业所常常提到的是“管理战略”“市场战略”“企业战略”等,这些是针对企业不同环节或不同层次对战略的细化。在游戏行业,我们常常听到的是“概念”“目标”被冠以“战略”。例如,盛大曾经提出要做“网上迪斯尼”,被很多人称为战略,其实仅仅是个长期目标而已。如果苏军在卫国战争的战略仅仅是“打败法西斯”,我估计二战的历史都要被改写了。中国游戏圈是我所见到的最喜欢通过滥用各种术语以拔高自己身份的自卑群体。而战略这个词被滥用造成的结果就是,几乎所有人都搞不清楚什么是战略,战略有什么用。
我们先从战争来看看什么是战略。《战争论》对战略定义为“战略就是为了达到战争目的而对战斗的运用。”针对战略和战术的关系,《战争论》提出“战略是对整个战争的筹划”“战术是对某一作战行动的筹划。”在战争中,大本营/总参需要针对自己和敌方的态势、情况,决定如何达成战争的目的,并加以贯彻。在二战中,德军的“闪电战”、苏联红军的“大纵深”、日军的“火力优势作战”、我国的“人民战争”都属于战略层面。而相对应的“先锋旅指挥”“机械化波动进攻”“侧翼突破”“游击战”就属于战术层面。战术服务于战略,而战略则指导了战术。
在企业中,战略影响也非常大,往往决定一个企业的盛衰。在游戏业,战略也有血淋淋的案例摆在眼前,华义、大宇等老牌厂商对于大陆市场的丧失,与其战略可以说不无关系;盛大的所谓IPTV战略(称为战略还是大了,IPTV应该看作盛大多元化战略的一个关键战术调整),间接帮助网易成为行业老大。
对于游戏公司,战略可沿用郑文斌博士的定义。“战略是确定企业长远发展目标,并指出实现长远目标的策略和途径。战略确定的目标与企业的宗旨和使命必须相吻合。”在此定义的基础上,我认为,游戏开发公司的领导者必须明确以下问题:
1)公司发展的终极目标是什么?对应此终极目标员工的愿景为何?
2)公司的核心竞争力是什么?此核心竞争力如何保持和加强?
3)在游戏行业中,公司的位置和面临的态势?未来如何改善这个态势?
4)保证实现目标的资源有哪些?如何组织这些资源?
5)风险有哪些?如何通过制度和福利降低风险?
6)开发流程的管理采取什么样的模式才能最大程度发挥核心竞争力?
7)游戏产品的定位,开发什么题材、什么类型的产品?产品之间如何互补?
先明确了这几个问题,才能制定公司的战略,战略应该围绕目标来制定,同时也要考虑自己公司的实际情况和外部环境。例如最简单的,有些公司“两条腿走路”,引进产品和资助开发结合,就是最基本的产品战略,是总体战略的一部分。
再强调一遍,战略是非常重要的。很多战略经常变动、战略有问题或战略落实不足的游戏公司,已经给我们做了反面教材。我曾经听说,一个大裁员的公司老总抱怨,裁员的原因是,被开的员工脑子全部停留在单机时代的设计理念,根本做不出好网游,只能开掉。理由似乎合理,但其实非常荒唐,员工是谁请来的?公司管理层请的,在公司提出相应战略之后请的;员工是怎么干活的?是在管理层的意志下干活的,是在公司战略指导下干活的。做出的项目失败是管理层的战略失败,怎么能怪员工思想保守呢?可现实往往是,高层的战略失败,偏偏由员工买单,被裁掉甚至被拖欠工资,这似乎已成了IT的一个规则。
所以说,就算你不是高层也不想做高层,只想进入游戏行业踏实打工,了解公司战略也是很重要的,不然下次给垃圾战略买单的就可能是你。
说到底,某些高层根本没有想过以游戏立业,他们甚至连自己的核心业务是什么都不清楚,他们的规划中根本没有长期战略,更充斥着各种不切实际的短期盈利狂想。在这种情况下,决定公司方向的就是能不能赚快钱,能不能忽悠投资商和股民,也因此很多概念和口号被包装成为他们的所谓“战略”。至于游戏业务,只是很多“有奶便是娘”的奶妈之一。
这个行业真正需要是“忠于游戏”“以游戏为业”的公司和团队。一些公司和团队无法存活,表面上看来是人有问题(最常见的就是“策划不够专业”),但事实上往往是公司的战略和定位缺失。假使战略问题继续得不到重视,我们这个行业将陷入低水平重复的泥潭。
篇后记:
在游戏开发的圈子里,见识了很多被游戏开发所成就或伤害的精英,也看了他们所写的形形色色文章、书籍、Blog。其中多有怨天尤人的、讥讽谩骂的、自卖自夸的、乞求玩家买正版的、装大师大谈成功攻略的,唯独老老实实总结点经验并愿意共享出来的很少。
而很现实的状况是,几乎所有中国游戏制作团队都在重复犯前人的错误。
所以起意写本文的初衷就是想能整理一些给其他业者有用的,也供自己反省的东西。因个人能力和时间所限,断断续续写了很久才攒了5节。
软件
配置管理是对
软件开发阶段的演化和变更进行管理;贯穿软件整个生命周期,从立项、需求定义、计划、设计、实现、
测试再到发行,配置管理需要记录每一次里程碑转变的条件和结果,并且要能通过配置管理系统记录的文档和过程可以重现某个过程,也就是要能完整的记录整个研发过程,配置管理系统在定义配置项时要将项目中的每一个变化都反映到配置管理系统中;
目前公司存在的问题是
1、各个阶段的配置项依赖关系没有办法追踪,只知道有这些配置项,但是并不知道这些配置项之间的关系,哪个配置项先确立、哪个后确立;
2、各个阶段之间的配置项的依赖关系也没有记录,只是有各个阶段的入口条件;
3、没有统一的系统来管理诸如代码、文档、需求、测试、发行版本等;每一种配置项都存放在不同的管理工具中,如代码用CC来管理,文档由PDM来管理,发行版本流程也由PDM来管理,发行版本的存放由windows共享来管理,变更则由CQ来管理;各个管理工具不统一使得基线的创建困难重重,目前我们基线的创立仅仅是文档的到位,基线创建时对应的版本是什么只能去查找文档内容,而不能使整个基线内容一目了然;
解决的最佳方案是:
建立单一的配置管理系统,或者各个系统之间能建立自动的联系;各个配置项的依赖关系也能一目了然;
前段时间做了一个开发,涉及到网络编程,开发过程比较顺利,但任务完成后始终觉得有一些疑惑。主要是因为对网络协议不太熟悉,对一些概念也没弄清楚。后来 我花了一些时间去了解这些网络协议,现在对TCP/IP网络协议有了初步的认识,在这里总结出来,可以梳理一下我对网络协议的理解,加深印象.
话说两台电脑要通讯就必须遵守共同的规则,就好比两个人要沟通就必须使用共同的语言一样。一个只懂英语的人,和一个只懂中文的人由于没有共同的语言(规则)就没办法沟通。两台电脑之间进行通讯所共同遵守的规则,就是网络协议。
那么谁来制定这个网络协议?
国际标准化组织(ISO)定义了网络协议的基本框架,被称为OSI模型。要制定通讯规则,内容会很多,比如要考虑A电脑如何找到B电脑,A电脑在发送信息 给B电脑时是否需要B电脑进行反馈,A电脑传送给B电脑的数据的格式又是怎样的?内容太多太杂,所以OSI模型将这些通讯标准进行层次划分,每一层次解决 一个类别的问题,这样就使得标准的制定没那么复杂。OSI模型制定的七层标准模型,分别是:应用层,表示层,会话层,传输层,网络层,数据链路层,物理 层。
虽然国际标准化组织制定了这样一个网络协议的模型,但是实际上
互联网通讯使用的网络协议是TCP/IP网络协议。
TCP/IP 是一个协议族,也是按照层次划分。共四层:应用层,传输层,互连网络层,网络接口层。 那么TCP/IP协议和OSI模型有什么区别呢?OSI网络协议模型,是一个参考模型,而TCP/IP协议是事实上的标准。TCP/IP协议参考了OSI 模型,但是并没有严格按照OSI规定的七层去划分标准,而只划分了四层,个人觉得这样会更简单点,当划分太多层次时,你很难区分某个协议是属于哪个层次 的。TCP/IP协议和OSI模型也并不冲突,TCP/IP协议中的应用层协议,就对应于OSI中的应用层,表示层,会话层。就像以前有工业部和信息产业 部,现在实行大部制后只有工业和信息化部一个部门,但是这个部门还是要做以前两个部门一样多的事情,本质上没有多大的差别。TCP/IP中有两个重要的协 议,传输层的TCP协议和互连网络层的IP协议,因此就拿这两个协议做代表,来命名整个协议族了,在说TCP/IP协议时,是指整个协议族。
TCP/IP协议分为四个层次,但我们并不需要了解所有层次的协议,我觉得主要关注应用层和传输层的协议就可以了。拿寄送邮件举例, A寄邮件给B,A关心的是用什么格式写什么内容给B(应用层内容),是寄挂号信还是寄平信(传输层内容),但是A是不会去关注邮件传送过程中采用了那条路 线,邮递员是如何把信件递送到B手里的(互连网络层,网络接口层)。
先说传输层,传输层有多个协议,但最主要的是TCP和UDP协议。两则的区别在于TCP协议需要接收方反馈,UDP协议不需要接收方反馈。TCP就像挂号 信,A电脑发信息给B电脑后,需要得到B电脑的反馈,这样A电脑就能知道B电脑是否已经收到信息。UDP就像平信,A电脑发信息给B电脑后,B电脑并不给 A电脑发聩,A电脑发送信息出去后并不知道B电脑是否已经收到。 因此,TCP传输比UDP传送更可靠,但是TCP传输的效率就不如UDP了。至于,在传送过程中具体选择哪种传送方式,需要具体问题具体分析。在不可靠的 网络传送过程中一般选择TCP传送方式。在讲求效率,或者不在乎传送失误的情况下可以选择UDP方式来提高传输速率。
应用层的协议有很多,每一个协议代表一种类型的服务。HTTP协议,万维网服务。FTP协议,文件传送服务。POP3,邮件服务,SOAP协议webService服务。
在理解TCP/IP协议的过程中,我遇到了三个困惑。
1.什么是socket?
以前有听说过socket编程这种说法,也有的说套接字编程。我在搜索关于socket的资料时,发现有的说socket是指一个连接,有的说 socket是一指一个端点。拿打电话做比喻,A电话机和B电话机正在通话,那么socket是指的A和B之间的连接线呢,还是指电话机(端点)?
我现在的理解是,socket就是一个连接中的一个端点,一次通讯(连接)a,b端都会有一个socket。一个socket对应一个连接。
2.http协议属于应用层还是传输层?
http 超文本传送协议,听上去像是传输层的协议一样。但事实上大家都知道http和ftp一样都是属于应用层的协议,我先前很纳闷的是,既然是应用层的协议,怎 么就取这样一个误导人的名称啊。在对TCP/IP协议还不熟悉的时候,这很容易让人误解和纳闷的。后来,我在wiki上发现这么一段话:
http中文译名问题
HTTP 在中国大陆被翻译为“超文本传输协议”,因为“transfer”在中文里有“传输”的含意。但依据 HTTP 定制者之一的 Ro Fielding博士的论文[1](6.5.3节),作者专门强调“transfer”表示的是“(表述状态的)转移” (Representational Stat Transfer),而不是“传输”(transport)。故其中文译名“超文本传输协议”恰恰引种反映了这种误解。更符合原义的译名应该为“超文本转 移协议”。
这段话解除了我的疑惑。那么http协议当然是应用层的协议。
3.SOAP可以使用HTTP协议进行传输吗?
在了解SOAP协议的过程中,看到介绍说soap可以通过tcp,udp,http协议来传送。这也是让人困惑的描述。一看这句话,就会感觉http怎么 和tcp,udp协议并列了呢?难道http还是属于传输层的协议?再加上http中文译名的问题,名字听上去像传输层,初学者又要开始头大了。
事实上,http是应用层的协议,这一点可以毫无怀疑。那么现在新的问题来了。soap和http都是应用层协议,怎么说soap能用http协议来传输呢?应用层的协议可以用应用层的协议传送吗?
我查阅了资料,是这样一回事情,soap将信息进行XML的序列化后,再用http协议的方式再打包进行传送,传送的方式还是tcp或者udp。做个比喻 就好理解了。tcp 和 udp 都是公路,暂且把tcp认为是一般公路,udp高速公路,soap和http就都是汽车,那么soap和http都可以在tcp和udp上跑。说soap 可以通过http来传送,实际就是说soap是小轿车,http是装轿车的卡车,把soap的信息装到http里面,然后再运输,当然走的道路还是tcp 或udp。
说soap可以通过http协议来传输,这句话不太准确,比较准确第说法是:soap信息可以通过http协议包装后通过tcp或udp传输。
使用Bugfree2.1后发现配置好邮件参数后,在指派
bug时能正常发送邮件,但始终无法使用其定期发送统计邮件和通知邮件的功能,虽然照官网上说的配置了计划任务,修改了
shell目录下的两个bat文件,但仍然没有解决。后来装了个php调试器,逐步调试终于找到问题原因:
1、创建项目时没有填写“通知邮件”的属性,导致执行statbug.php文件时找不到接受信息的电子邮件地址;
2、statbug.php文件的第251行中$CSSStyle=出现了多余的字符串‘PWD’删除后即可;
3、shell目录下的statbug.bat文件中命令缺少一个默认的参数:http://www.bugfree.org.cn
修改后的statbug.bat文件内容为:
c:/xampp/php/php.exe c:/xampp/htdocs/bugfree/StatBug.php http://www.bugfree.org.cn
这样再次运行后就可以正常发送统计邮件了,下面是效果图:
作者在这篇
文章中, 列出了七个项目, 指出怎样的开发人员, 才是
测试人员心中的好的RD.
1. 不要考验你的测试人员
即使你和测试人员的关系不好, 也不要故意制造bug, 来考验你测试人员的程度.
2. 自己做自己的验收测试
通常开发人员知道要去进行
单元测试, 但是往往忽略了GUI测试以及usability testing. 建议开发人员每次要记得去进行小规模的验收测试, 来及早发现一些usability的issues
3. 不要一直犯同样的错误
测试人员最讨厌的是开发人员老是一直犯样的错误. 每当功能有修改时, 测试人员常常能预测开发人员会忘记处理哪些事情. 开发仁要记得从中学得教训
4. 他们并不想伤害你
开发人员通常认为测试人员都是在找他们的问题或是麻烦. 所以她们很害怕进行测试, 但是事实上他们需要与测试人员合作, 以确保整个系统的质量.
5. 不要把质量的责任推给测试人员
另一件不好的事情, 是开发人员对于客户遭遇到的问题不感兴趣, 认为这是质量的问题. 必须要记住, 质量是整个团队的责任, 开发人员不是只是要写code, 也要负担起质量的责任
6. 要撰写批注和可读性高的程序代码
7. 提供有叙述性的错误警报
若是开发人员在显示错误讯息时, 能够更具体更有意义, 会帮助测试人员测试
工作的进行. 不要老是显示相同, 或是没有意义的讯息.
AJAX = Asynchronous JavaScript and XML (异步的JavaScript和XML)。
AJAX不是新技术 ,但却是热门的技术。它可以在不重载(刷新)整个页面的情况下与服务器进行数据交互并更新网页模块。
AJAX的优点有很多:可以局部刷新、按需加载,这样就减轻了服务器的数据流量。并且在页面更新的同时,用户可以浏览器网页的其它内容而不受影响,也减轻了结构负担。AJAX也不是万能的,在有以上优点的同时SEO也受到了影响。
在学习AJAX之前,必须先有HTML/XHTML、CSS、JavaScript/DOM的基础。
AJAX与服务器进行数据交互,必然涉及到服务器端,与此同时也就涉及到了服务器请求对象的创建(new XMLHttpRequest())、确认请求方式(open())、发送请求(send())以及响应请求(responseText)。
创建对象:
IE9+及其它浏览器支持使用new XMLHttpRequest()的创建对象方式,而IE8及以下则使用new ActiveXObject()的方式进行创建。
看了网上许多人使用如下代码进行兼容:
1 try { 2 xml = new ActiveXObject("Msxml2.XMLHTTP"); 3 } catch(e) { 4 try { 5 xml = new ActiveXObject("Microsoft.XMLHTTP"); 6 } catch(e1) { 7 xml = new XMLHttpRequest(); 8 } 9 } |
笔者用IE11调试功能测试IE10及以下不写new ActiveXObject("Msxml2.XMLHTTP")也是没问题的,于是在创建对象时可以使用代码:
var xml = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
确认请求:
xml.open('get', 'url', true/false);
第一个参数表示:string. 访问方式,有两具值:get/post,大部分的时候使用get
第二个参数表示:string. 要连接的服务器网址
第三个参数表示:boolean. 表示是否需要异步请求(true为发起异步加载)
发送请求:
xml.send();
如果需要发送数据则采用xml.send(str);
响应数据:
xml.onreadystatechange = function() {
if (xml.readyState == 4 && xml.status == 200) {
alert(xml.responseText);
}
}
status返回链接的状态,一般返回200与404,200表示成功返回,404表示未找到页面。
readyState有5个值,分别为:0、1、2、3、4。而每当值改变时都会触发一次onreadystatechange。
readyState的5个值含义分别为:
0: 请求未初始化
1: 服务器连接已建立
2: 请求已接收
3: 请求处理中
4: 请求已完成,且响应已就绪
也就是当请求完成,并且找到页面时,然后才获取服务器上的数据。
定时器—有时也称为动态定时器或内核定时器—是管理内核时间的基础。定时器是一种软件功能,即允许在将来的某个时刻,函数在给定的时间间隔用完时被调用。注意的是定时器并不会周期运行,它在超时后就自行销毁,这也是定时器被称为动态定时器的一个原因。动态定时器不断地创建和销毁,而且它的运行次数也不受限制。
定时器在内核代码中属于一个基础组件。要想完全弄清楚linux2.6中内核定时器的实现,得先从初始化开始。
在start_kernel(void)-->init_timers(void)
void __init init_timers(void) { int err = timer_cpu_notify(&timers_nb, (unsigned long)CPU_UP_PREPARE, (void *)(long)smp_processor_id()); init_timer_stats(); BUG_ON(err == NOTIFY_BAD); register_cpu_notifier(&timers_nb); open_softirq(TIMER_SOFTIRQ, run_timer_softirq); } 在timer_cpu_notify(&timers_nb,(unsigned long)CPU_UP_PREPARE, (void*)(long)smp_processor_id()); |
中执行
init_timers_cpu(cpu) //初始化本cpu中的timers
初始化的主要代码是:
spin_lock_init(&base->lock); for (j = 0; j < TVN_SIZE; j++) { INIT_LIST_HEAD(base->tv5.vec + j); INIT_LIST_HEAD(base->tv4.vec + j); INIT_LIST_HEAD(base->tv3.vec + j); INIT_LIST_HEAD(base->tv2.vec + j); } for (j = 0; j < TVR_SIZE; j++) INIT_LIST_HEAD(base->tv1.vec + j); base->timer_jiffies = jiffies; base->next_timer = base->timer_jiffies; |
这段代码的主体是base,base的定义是:structtvec_base *base;
这个tvec_base是动态定时器的主要数据结构,每个cpu上有一个,它包含相应cpu中处理动态定时器需要的所有数据。为简化分析仅考虑单cpu。给出这个数据机构:
struct tvec_base { spinlock_t lock; struct timer_list *running_timer; unsigned long timer_jiffies; unsigned long next_timer; struct tvec_root tv1; struct tvec tv2; struct tvec tv3; struct tvec tv4; struct tvec tv5; } ____cacheline_aligned; |
注意:支持将数据从
SQL Server 2000迁移到Microsoft SQL Server 2000(64位)。您可以将一个32位
数据库附加到一个64位数据库上,方法是:使用sp_attach_db系统存储过程或sp_attach_single_file_db系统存储过程,或者使用32位企业管理器中的备份和还原功能。您可以在SQL Server的32位和64位两种版本之间来回
移动数据库。您还可以使用同样的方法从SQL Server 7.0迁移数据。但是,不支持将数据从SQL Server 2000(64位)降级到SQL Server 7.0。下面分别介绍这几种方法。
如果您使用的是SQL Server 2005
您可以使用相同的方法从SQL Server 7.0或SQL Server 2000迁移数据。但是,Microsoft SQL Server 2005中的管理工具与SQL Server 7.0或SQL Server 2000中的管理工具有所不同。您应该使用SQL Server Management Studio(而不是SQL Server企业管理器)以及SQL Server导入和导出向导(DTSWizard.exe)(而不是数据转换服务导入和导出数据向导)。
备份和还原
在源服务器上备份用户数据库,然后将用户数据库还原到目标服务器上。在备份过程中时可能有人使用数据库。如果用户在备份完成后对数据库执行INSERT、UPDATE或DELETE语句,则备份中不会包含这些更改。如果您必须传输所有更改,那么,假如您既执行事务日志备份又执行完整数据库备份,您可以以尽可能短的停止时间来传输这些更改。
1.在目标服务器上还原完整数据库备份,并指定WITH NORECOVERY选项。
注意:为防止对数据库做进一步的修改,请指导用户在源服务器上退出数据库活动。
2.执行事务日志备份,然后使用WITH RECOVERY选项将事务日志备份还原到目标服务器上。停止时间仅限于事务日志备份和恢复的时间。
◆目标服务器上的数据库将与源服务器上的数据库大小相同。要减小数据库的大小,您必须在执行备份前压缩源数据库的大小,或者在完成还原后压缩目标数据库的大小。
◆如果您将数据库还原到的文件位置不同于源数据库的文件位置,则必须指定WITH MOVE选项。例如,在源服务器上,数据库位于D:/Mssql/Data文件夹中。目标服务器没有D驱动器,因而您需要将数据库还原到C:/Mssql/Data文件夹。有关如何将数据库还原到其他位置的更多信息,请查看相关资料。
◆如果您想覆盖目标服务器上的一个现有数据库,则必须指定WITH REPLACE选项。
◆源服务器和目标服务器上的字符集、排序顺序和Unicode整序可能必须相同,具体取决于您要还原到SQL Server的哪种版本。有关更多信息,请参阅本文中的“关于排序规则的说明”一节。
Sp_detach_db和Sp_attach_db存储过程
要使用sp_detach_db和sp_attach_db这两个存储过程,请按下列步骤操作:
1.使用sp_detach_db存储过程分离源服务器上的数据库。您必须将与数据库关联的.mdf、.ndf和.ldf这三个文件复制到目标服务器上。参见下表中对文件类型的描述:
文件扩展名
说明
.mdf
主要数据文件
.ndf
辅助数据文件
.ldf
事务日志文件
2.使用sp_attach_db存储过程将数据库附加到目标服务器上,并指向您在上一步骤中复制到目标服务器的文件。
◆分离数据库后将无法访问该数据库,并且复制文件时也无法使用该数据库。在进行分离的那一时刻数据库中包含的所有数据都被移动。
◆在您使用附加或分离方法时,两个服务器上的字符集、排序顺序和Unicode整序都必须相同。有关更多信息,请参阅本文中的“关于排序规则的说明”一节。
关于排序规则的说明 如果您使用备份和还原或附加和分离方法在两个SQL Server 7.0服务器之间移动数据库,则两个服务器上的字符集、排序顺序和Unicode整序都必须相同。如果您将数据库从SQL Server 7.0移到SQL Server 2000,或者在不同的SQL Server 2000服务器之间移动数据库,则数据库将保留源数据库的整序。这意味着,如果运行SQL Server 2000的目标服务器的整序与源数据库的整序不同,则目标数据库的整序也将与目标服务器的master、model、tempdb和msdb数据库的整序不同。
第1步:导入和导出数据(在SQL Server数据库之间复制对象和数据)
您可以使用数据转换服务导入和导出数据向导来复制整个数据库或有选择地将源数据库中的对象和数据复制到目标数据库。在传输过程中,可能有人在使用源数据库。如果在传输过程中有人在使用源数据库,您可能会看到传输过程中出现一些阻滞现象。
◆在您使用导入和导出数据向导时,源服务器与目标服务器的字符集、排序顺序和整序不必相同。
◆因为源数据库中未使用的空间不会移动,所以目标数据库不必与源数据库一样大。同样,如果您只移动某些对象,则目标数据库也不必与源数据库一样大。
◆SQL Server 7.0数据转换服务可能无法正确地传输大于64KB的文本和图像数据。但SQL Server 2000版本的数据转换服务不存在此问题。
第2步:如何传输登录和密码
如果您不将源服务器中的登录传输到目标服务器,当前的SQL Server用户就无法登录到目标服务器。目标服务器上的登录的默认数据库可能与源服务器上的登录的默认数据库不同。您可以使用sp_defaultdb存储过程来更改登录的默认数据库。
#p#
第3步:如何解决孤立用户
在您向目标服务器传输登录和密码后,用户可能还无法访问数据库。登录与用户是靠安全识别符(SID)关联在一起的;在您移动数据库后,如果SID不一致,SQL Server可能会拒绝用户访问数据库。此问题称为孤立用户。如果您使用SQL Server 2000 DTS传输登录功能来传输登录和密码,就可能会产生孤立用户。此外,被允许访问与源服务器处于不同域中的目标服务器的集成登录帐户,也会导致出现孤立用户。
1.查找孤立用户。在目标服务器上打开查询分析器,然后在您移动的用户数据库中运行以下代码:
exec sp_change_users_login 'Report'
此过程将列出任何未链接到一个登录帐户的孤立用户。如果没有列出用户,请跳过第2步和第3步,直接进行第4步。
2.解决孤立用户问题。如果一个用户是孤立用户,数据库用户可以成功登录到服务器,但却无权访问数据库。如果您尝试向数据库授予登录访问权,则会因该用户已经存在而出现下列错误消息:
Microsoft SQL-DMO (ODBC SQLState:42000)
错误15023:当前数据库中已存在用户或角色'%s'。上面介绍了如何使用sp_change_users_login存储过程来逐个纠正孤立用户。sp_change_users_login存储过程仅能解决标准的SQL Server登录帐户的孤立用户问题。
3.如果数据库所有者(dbo)被当作孤立用户列出,请在用户数据库中运行下面的代码:exec sp_changedbowner 'sa'此存储过程会将数据库所有者更改为dbo并解决这个问题。要将数据库所有者更改为另一用户,请使用您想使用的用户再次运行sp_changedbowner。
4.如果您的目标服务器运行的是SQL Server 2000 Service Pack 1,则在您执行附加操作或还原操作(或两种操作都执行)后,企业管理器的用户文件夹中的列表中可能没有数据库所有者用户。
5.如果目标服务器上不存在映射到源服务器上的dbo的登录,您在尝试通过企业管理器更改系统管理员(sa)密码时,可能会收到以下错误消息:
错误21776:[SQL-DMO]名称'dbo'在Users集合中没有找到。如果该名称是合法名称,则使用[]来分隔名称的不同部分,然后重试。
警告:如果您再次还原或附加数据库,则数据库用户可能会再次被孤立,这样您就必须重复第3步操作。
第4步:如何移动作业、警报和运算符
第4步是可选操作。您可以为源服务器上的所有作业、警报和运算符生成脚本,然后在目标服务器上运行脚本。要移动作业、警报和运算符,请按照下列步骤操作:
1.打开SQL Server企业管理器,然后展开管理文件夹。
2.展开SQL Server代理,然后右键单击警报、作业或运算符。
3.单击所有任务,然后单击生成SQL脚本。对于SQL Server 7.0,请单击为所有作业生成脚本、警报或运算符。
您可以用右键单击选择为所有警报、所有作业或所有运算符生成脚本。
◆您可以将作业、警报和运算符从SQL Server 7.0移到SQL Server 2000,也可以在运行SQL Server 7.0和运行SQL Server 2000计算机之间移动。
◆如果在源服务器上为运算符设置了SQLMail通知,则目标服务器上也必须设置SQLMail,才能具有相同的功能。
第5步:如何移动DTS包
第5步是可选操作。如果DTS包在源服务器上存储在SQL Server中或存储库中,您可以在需要时移动这些包。要在服务器之间移动DTS包,请使用下列方法之一。
方法1
1.在源服务器上将DTS包保存到一个文件中,然后在目标服务器上打开DTS包文件。
2.将目标服务器上的包保存到SQL Server或存储库中。
注意:您必须用单独的文件逐个地移动这些包。
方法2
1.在DTS设计器中打开每个DTS包。
2.在包菜单上,单击另存为。
3.指定目标SQL Server。
注意:在新服务器上,包可能无法正常运行。您可能必须对包进行更改,更改包中任何对旧的源服务器上的连接、文件、数据源、配置文件和其他信息的引用,以便引用新的目标服务器。您必须根据每个包的设计逐个包进行这些更改。
本文中介绍的步骤不移动数据库关系图以及备份与还原历史记录。如果您必须移动这些信息,请移动msdb系统数据库。如果您移动msdb数据库,则不必执行“第4步:如何移动作业、警报和运算符”或“第5步:如何移动DTS包”。
注意:支持将数据从
SQL Server 2000迁移到Microsoft SQL Server 2000(64位)。您可以将一个32位
数据库附加到一个64位数据库上,方法是:使用sp_attach_db系统存储过程或sp_attach_single_file_db系统存储过程,或者使用32位企业管理器中的备份和还原功能。您可以在SQL Server的32位和64位两种版本之间来回
移动数据库。您还可以使用同样的方法从SQL Server 7.0迁移数据。但是,不支持将数据从SQL Server 2000(64位)降级到SQL Server 7.0。下面分别介绍这几种方法。
如果您使用的是SQL Server 2005
您可以使用相同的方法从SQL Server 7.0或SQL Server 2000迁移数据。但是,Microsoft SQL Server 2005中的管理工具与SQL Server 7.0或SQL Server 2000中的管理工具有所不同。您应该使用SQL Server Management Studio(而不是SQL Server企业管理器)以及SQL Server导入和导出向导(DTSWizard.exe)(而不是数据转换服务导入和导出数据向导)。
备份和还原
在源服务器上备份用户数据库,然后将用户数据库还原到目标服务器上。在备份过程中时可能有人使用数据库。如果用户在备份完成后对数据库执行INSERT、UPDATE或DELETE语句,则备份中不会包含这些更改。如果您必须传输所有更改,那么,假如您既执行事务日志备份又执行完整数据库备份,您可以以尽可能短的停止时间来传输这些更改。
1.在目标服务器上还原完整数据库备份,并指定WITH NORECOVERY选项。
注意:为防止对数据库做进一步的修改,请指导用户在源服务器上退出数据库活动。
2.执行事务日志备份,然后使用WITH RECOVERY选项将事务日志备份还原到目标服务器上。停止时间仅限于事务日志备份和恢复的时间。
◆目标服务器上的数据库将与源服务器上的数据库大小相同。要减小数据库的大小,您必须在执行备份前压缩源数据库的大小,或者在完成还原后压缩目标数据库的大小。
◆如果您将数据库还原到的文件位置不同于源数据库的文件位置,则必须指定WITH MOVE选项。例如,在源服务器上,数据库位于D:/Mssql/Data文件夹中。目标服务器没有D驱动器,因而您需要将数据库还原到C:/Mssql/Data文件夹。有关如何将数据库还原到其他位置的更多信息,请查看相关资料。
◆如果您想覆盖目标服务器上的一个现有数据库,则必须指定WITH REPLACE选项。
◆源服务器和目标服务器上的字符集、排序顺序和Unicode整序可能必须相同,具体取决于您要还原到SQL Server的哪种版本。有关更多信息,请参阅本文中的“关于排序规则的说明”一节。
Sp_detach_db和Sp_attach_db存储过程
要使用sp_detach_db和sp_attach_db这两个存储过程,请按下列步骤操作:
1.使用sp_detach_db存储过程分离源服务器上的数据库。您必须将与数据库关联的.mdf、.ndf和.ldf这三个文件复制到目标服务器上。参见下表中对文件类型的描述:
文件扩展名
说明
.mdf
主要数据文件
.ndf
辅助数据文件
.ldf
事务日志文件
2.使用sp_attach_db存储过程将数据库附加到目标服务器上,并指向您在上一步骤中复制到目标服务器的文件。
◆分离数据库后将无法访问该数据库,并且复制文件时也无法使用该数据库。在进行分离的那一时刻数据库中包含的所有数据都被移动。
◆在您使用附加或分离方法时,两个服务器上的字符集、排序顺序和Unicode整序都必须相同。有关更多信息,请参阅本文中的“关于排序规则的说明”一节。
1.克服惯性
将大块任务细分为微任务。
2.关注大牛
你想学的或许是一门新的编程语言、应用框架或者是新的工具,一旦你确定了想要的是什么,就立刻去收集相应的优秀群体所做的一些优质的
工作成果。这些可以从YouTube、Vimeo、HackerNews、各种博客,甚至是你的微博好友那里获取。关注别人做了些什么可以给你强大的信心,让你觉得 “You can do it, too!”
3.建立知识网
当你对自己要
学习的东西建立了信心之后,接下来要做的就是做一块海绵,然后开始疯狂地吸收知识。从
Google搜索关键词“beginner tutorials”开始吧,搜索一些跟你要学习的知识相关的入门教程。如你所知,Nettuts+上面有成千上百的各种教程供你选择,StackOverflow上面也有很多学习资源。此外,Quora也是一些不错的选择。通过浏览这些网上的资源之后,如果想要集中精力学习某一方面,这时就需要阅读一些相关的书籍了,个人推荐在Amazon上面寻找一些评分较高的专业书籍来提高自己。
4. 多听多看
随着你对技术的深入挖掘,你可能会想利用更多其他形式的学习资料,比如podcasts,screencasts等等。我的建议是多用 iTunesU,这上面有很多很专业的知识可以让你对于特定的领域进行深入的探索。
目前,有很多的网站都有提供在线教育服务,你可以在下面几个网站上找到自己需要的教程:
· Udemy
· CodeCademy
· CodeSchool
此外,你也可以看一些免费的会议视频材料,比如YouTube上面的Google IO,以及Confreaks!
5. 行动起来
用你所掌握的技术做一个个人的小项目,设计一些简单的功能并且实现他们。毫无疑问,你会遇到很多的绊脚石,当遇到它们的时候,在StackOverflow或者Google上面搜索之,解决之。你已经踏上一条成为某一领域专家的旅程,遇到的困难挫折越多,你会变得越睿智。有句老话说得好,“专家是犯错最多的人”,这意味着他们尝试了很多疯狂的事情来探索这门技术的极限,最后,对于这门技术是如何运作的就可以知根知底。拥有这种洞察力之后,他们便可以随心所欲的运用这项技术去按照自己的意愿完成想做的事情(当然,是做好的事情)。
6. 写博客
如果你想走的更远(比如想像Nettuts+上面的职业作者一样),你也可以制作属于自己的screencasts。总的来说,写博客能够提升你的个人沟通能力,这与你学到的技术同样重要。
7. 感受技术的脉搏
社交网络已经广泛应用于人们的日常交流以及发现新鲜事物。Twitter和Facebook是信息的主要来源,与此同时,有很多的网站提供更专注的资讯,如前面提到过的Quora网站,这上面有很多涉及面很广的一些话题供人们评论。在这上面可以找到很多知名大牛的建议以及观点。
8. 参加聚会以及会议
尽管社交网络很棒,但是没有任何事物可以取代面对面的交流。在你住的附近参加一些小组聚会,在这里你可以找到志同道合的伙伴。你可以知道他人在做的一些有趣的项目,同时也可以在他人的帮助下解决一些自己遇到的难题!同样的,技术会议对于分享经验以及增长技术大有帮助!
9. 拥抱GitHub
GitHub是全世界开源项目的标志性“建筑物”。它是知识以及优质代码的宝库。当你对某项技术自我感觉良好的时候,下一步便是在GitHub中浏览寻找有趣的项目。阅读开源代码,尽可能多的阅读。这样做的话,你能够学到很多东西,比如说:
· 如何管理规模较大的项目
· 项目中应用的有趣的库
· 代码规范以及代码全局设计
· 文档风格
· 测试规范
· 解决诡异问题的方法,以及发现项目中有问题的地方
所有的这些知识都在等待着你去挖掘。有趣的是,这些知识的通过一个简单的标签就可以得到,那就是“好奇心”。
10. 专注学习
如果你担心上述的学习过程太迟缓,那么你也可以尝试一下快速学习模式。你或许听说过“24小时学会某某某”,但是这种方式不是我所推荐的。我认为更合理的是用几周的时间去学习。你可以尝试一下类似“七周学会七种语言”或者是“七周学会七种数据库”等学习方法。尽管这些讲的是语言以及数据库方面的学习,但是你在学习其他技术的时候也可以运用这种思维。
有一个不太相同的学习风格是“困难学习模式”,这种观点的前提是没有人可以真正掌握一门技术,除非每天都练习。所以,想要成为专家,你就需要不停地进行练习。异曲同工的是你可以查看Katas 和 Koans,他鼓励的使用你学的知识来解决问题。这些可以让你更好地入门以及接受那些陌生的概念,勇敢走出自己的舒适区,开始学习新知识!
学习一门交叉的技能
编程是一项左脑的运动,它利用的是大脑的分析能力,一步一步地寻找解决问题的方法。为了发挥右脑的功能,你可以尝试从事一些创造性的活动,比如说画画、3D建模、折纸、乐器甚至是制作家庭相册等。事实上,编程同样需要大量的创造力。或许你曾经遇到过类似的事情,你在睡梦中找到了问题的解决方案。这是因为你的右脑处理问题的方式很不同,它可以从各种地方获得信息。敏捷开发权威人士Andy Hunt就这个话题写了一本书《程序员的思维修炼》。如果你想点燃你的每一个神经元,建议你开始学习一门交叉的技能。
总结
掌握一门新技术振奋人心,这是一项影响你思维的新的体验。但是首先,你必须克服你的惯性,一旦你做到了,你便开启了从web的每个角落学习知识的旅程。我希望上面讲的十点能够给你的学习旅程带来一些帮助或启发。