﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>博客园-On the road</title><link>http://www.cnblogs.com/sun11086/</link><description>菜鸟的成长</description><language>zh-cn</language><lastBuildDate>Sat, 20 Mar 2010 21:58:33 GMT</lastBuildDate><pubDate>Sat, 20 Mar 2010 21:58:33 GMT</pubDate><ttl>60</ttl><item><title>[转]cacheAsBitmap使用</title><link>http://www.cnblogs.com/sun11086/archive/2010/03/17/1687755.html</link><dc:creator>sungo</dc:creator><author>sungo</author><pubDate>Tue, 16 Mar 2010 16:25:00 GMT</pubDate><guid>http://www.cnblogs.com/sun11086/archive/2010/03/17/1687755.html</guid><description><![CDATA[<p>阅读: 6 评论: 0 作者: <a href="http://www.cnblogs.com/sun11086/" target="_blank">sungo</a> 发表于 2010-03-17 00:25 <a href="http://www.cnblogs.com/sun11086/archive/2010/03/17/1687755.html" target="_blank">原文链接</a></p><p><strong style="font-weight: bold;">该用cacheAsBitmap的时候：</strong>&nbsp;</p>
<ul style="margin-top: 0px; margin-right: 0px; margin-bottom: 1.5em; margin-left: 0px; padding: 0px;">
<li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.25em; margin-left: 30px; padding: 0px;">效率提升只适用于x,y的改变，然而，一旦牵涉形变（旋转，缩放）效率只会更低下。</li>
<li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.25em; margin-left: 30px; padding: 0px;">一个复杂的矢量化背景图片上存在大量动画；</li>
<li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.25em; margin-left: 30px; padding: 0px;">滚动文本区域；</li>
<li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.25em; margin-left: 30px; padding: 0px;">基于窗口的应用（你经常会拖拽整块区域）</li>
<li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.25em; margin-left: 30px; padding: 0px;">透明遮罩（必须强制使用，否则失效）</li>
</ul>
<p>
<br /><strong style="font-weight: bold;">不应该用cacheAsBitmap的时候：</strong>&nbsp;</p>
<ul style="margin-top: 0px; margin-right: 0px; margin-bottom: 1.5em; margin-left: 0px; padding: 0px;">
<li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.25em; margin-left: 30px; padding: 0px;">不要滥用，cacheAsBitamp十分消耗内存，一块250&times;250像素的矩形进行cache之后可能占掉250kb的内存！</li>
<li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.25em; margin-left: 30px; padding: 0px;">目标元素缩放的时候不要使用。</li>
<li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.25em; margin-left: 30px; padding: 0px;">目标元素本身最好是静态的，或者不要经常发生翻转、缩放这样的动画</li>
<li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.25em; margin-left: 30px; padding: 0px;">不要把矢量图和cache的位图一起混用。</li>
</ul><img src="http://www.cnblogs.com/sun11086/aggbug/1687755.html?type=1" width="1" height="1" alt=""/><p>评论: 0　<a href="http://www.cnblogs.com/sun11086/archive/2010/03/17/1687755.html#pagedcomment" target="_blank">查看评论</a>　<a href="http://www.cnblogs.com/sun11086/archive/2010/03/17/1687755.html#commentform" target="_blank">发表评论</a></p><p><a href="http://job.cnblogs.com/" target="_blank">找优秀程序员，就在博客园</a></p><hr/><p>最新新闻：<br/>· <a href="http://news.cnblogs.com/n/59262/" target="_blank">甲骨文将关闭OpenSSO</a><span style="color:gray">(2010-03-20 23:54)</span><br/>· <a href="http://news.cnblogs.com/n/59261/" target="_blank">专访陈晓薇：九城已重建、我还没想好去哪</a><span style="color:gray">(2010-03-20 22:07)</span><br/>· <a href="http://news.cnblogs.com/n/59260/" target="_blank">[视频]社交媒体不仅仅是一时狂热</a><span style="color:gray">(2010-03-20 21:58)</span><br/>· <a href="http://news.cnblogs.com/n/59259/" target="_blank">Google开出首个1337美刀的Chrome bug奖励支票</a><span style="color:gray">(2010-03-20 21:47)</span><br/>· <a href="http://news.cnblogs.com/n/59258/" target="_blank">著名图像讨论网站4chan创始人披露4chan诞生历史</a><span style="color:gray">(2010-03-20 21:42)</span><br/></p><p>编辑推荐：<a href="http://news.cnblogs.com/n/59093/" target="_blank">[视频]想做你的Code</a><br/></p><p>网站导航：<a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/" target="_blank">个人主页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/group/" target="_blank">小组</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://kb.cnblogs.com" target="_blank">知识库</a></p>]]></description></item><item><title>[转]Updated ‘Elastic Racetrack’ for Flash 9 and AVM2</title><link>http://www.cnblogs.com/sun11086/archive/2010/03/15/1686290.html</link><dc:creator>sungo</dc:creator><author>sungo</author><pubDate>Mon, 15 Mar 2010 07:43:00 GMT</pubDate><guid>http://www.cnblogs.com/sun11086/archive/2010/03/15/1686290.html</guid><description><![CDATA[<p>阅读: 1 评论: 0 作者: <a href="http://www.cnblogs.com/sun11086/" target="_blank">sungo</a> 发表于 2010-03-15 15:43 <a href="http://www.cnblogs.com/sun11086/archive/2010/03/15/1686290.html" target="_blank">原文链接</a></p><p style="font-size: 1.3em; margin-left: 10px; margin-bottom: 1em;">In 2005 Ted Patrick posted a great article on the frame execution model inside the Flash Player that he dubbed the &lsquo;<a href="http://www.onflex.org/ted/2005/07/flash-player-mental-model-elastic.php" title="Flash Elastic Racetrack" style="color: #991100; font-weight: bold;">elastic racetrack</a>&lsquo;. It&rsquo;s served as a great reference for me over the years to help understand how code execution and rendering were balanced within the processing of a frame. Since the introduction of Flash Player 9 and the new AVM2, I&rsquo;ve noticed a few changes to the elastic racetrack model and thought I&rsquo;d share them. This information is based on research into Flash player internals as well as observations I&rsquo;ve made playing around with the event and rendering model, but the full model hasn&rsquo;t been confirmed by Adobe engineers.</p>
<p style="font-size: 1.3em; margin-left: 10px; margin-bottom: 1em;">The basic premise of the original elastic racetrack is still the same. Given a specific frame rate to operate on, the Flash player will devote the first segment of the frame to execute code, and the second segment to render display objects. Either segment can grow its part of the racetrack to accommodate more processing and effectively extend the duration of the frame.</p>
<p style="font-size: 1.3em; margin-left: 10px; margin-bottom: 1em; text-align: center;"><img src="http://www.craftymind.com/wp-content/uploads/2008/04/elasticracetrackexport.png" alt="Flash Player Elastic Racetrack" /></p>
<p style="font-size: 1.3em; margin-left: 10px; margin-bottom: 1em;">What changes from the previous model is how those segments look under a microscope and how they come together to form a &lsquo;frame&rsquo;.</p>
<p style="font-size: 1.3em; margin-left: 10px; margin-bottom: 1em;">AVM2 is controlled by what I&rsquo;m going to call the Marshal. The Marshal is responsible for carving out time slices for the Flash Player to operate on. Its important to clarify up front that these time slices are not the same thing as the framerate compiled into a swf, but we&rsquo;ll see below how the player ultimately synthesizes a framerate from these slices. Running a Flex compiled swf within Firefox under Mac OS X, the Marshal appears to be carving out 19-20 millisecond slices, but this can be different between platforms and browsers based on what I&rsquo;ve observed as well as Adobe employees have&nbsp;<a href="http://www.jamesward.org/wordpress/2008/04/10/bursting-bubbles/" style="color: #991100; font-weight: bold;">hinted at</a>. This can also change depending on how the swf was compiled, see some of the comments below. For the sake of the article lets assume we&rsquo;re only talking about a 20 millisecond slice to make the math easy. This means the Marshal will attempt to generate and execute no more then 50 slices each second, and it may be less depending on the elasticity of code execution or rendering. Inside each slice, 5 possible steps are processed in the following order.</p>
<ol style="margin-top: 0px; margin-right: 0px; margin-bottom: 20px; margin-left: 40px; font-size: 1.2em;">
<li>Player events are dispatched - This includes events dispatched by the Timer, Mouse, ENTER_FRAMEs, URLLoader, etc&hellip;</li>
<li>User code is executed - Any code listening to events dispatched by step 1 are executed at this stage.</li>
<li>RENDER event is dispatched - This special event is dispatched when the user calls stage.invalidate() during normal user code operation.</li>
<li>Final user code is executed - User code listening specifically for step 3 is executed at this point.</li>
<li>Player renders changes to the display list.</li>
</ol>
<p style="font-size: 1.3em; margin-left: 10px; margin-bottom: 1em; text-align: center;"><img src="http://www.craftymind.com/wp-content/uploads/2008/04/marshalledsliceexport.png" alt="AVM2 Marshalled Slice" /></p>
<p style="font-size: 1.3em; margin-left: 10px; margin-bottom: 1em;">The Marshal executes this 20 millisecond slice over and over and decides on the fly which actions to run. The exact actions processed within a slice will ultimately derive the 2 main racetrack segments (code execution and rendering) that constitute a &lsquo;frame&rsquo;. User actions and Invalidation actions fill up the code segment track, while Render actions fill up the render segment track. Its important to note that actions will only occur at times predetermined by the Marshal, so a if you have a short running User action, the Marshal will still wait a few milliseconds before moving on to the Invalidate and Render actions.</p>
<p style="font-size: 1.3em; margin-left: 10px; margin-bottom: 1em;">The best way to illustrate which actions are run and how the elastic racetrack is created, is to look at how those slices are processed on a swf running at 5 fps, 25, fps, and 50 fps.</p>
<p style="font-size: 1.3em; margin-left: 10px; margin-bottom: 1em;">&nbsp;&nbsp; <img height="350" width="1200" src="http://www.craftymind.com/wp-content/uploads/2008/04/framemarshalingexport.png" /></p>
<p style="font-size: 1.3em; overflow-x: scroll; overflow-y: scroll; width: 650px; margin: auto;">&nbsp;</p>
<p style="font-size: 1.3em; margin-left: 10px; margin-bottom: 1em;">As you can see, the elastic racetrack performs different actions per frame and requires a different visual illustration depending on the framerate that the player is trying to synthesize. So for a swf running at 5 fps, each frame processed 10 User actions, 1 Invalidation action, and 1 Render action. At 25 fps, each frame processed 2 User actions, 1 Invalidation action, and 1 Render action. At 50 fps, each frame processed 1 User action, 1 Invalidation action, and 1 Render action. Whats important to note in the above chart is that some events are only available in certain slices. For instance, the Event.ENTER_FRAME event will only ever be dispatched in a slice that occurs at the start of a frame.</p>
<p style="font-size: 1.3em; margin-left: 10px; margin-bottom: 1em;">So what does this all mean? Theres a couple quick ideas to take away from this.</p>
<ol style="margin-top: 0px; margin-right: 0px; margin-bottom: 20px; margin-left: 40px; font-size: 1.2em;">
<li>Long running code execution or render segments can extend a given slice beyond 20 milliseconds. Elasticity will be applied to that particular slice and the duration of the frame may or may not be extended as a result. The Marshal may drop the number of slices that constitute a frame in order to keep the active framerate close to the compiled framerate.</li>
<li>A swfs&nbsp;<em>real</em>&nbsp;framerate won&rsquo;t exceed the Marshals rate defined for the player instance. You can set your compiled framerate at 120fps, but Flash will still only process 50 slices max that generate 50 render calls (more or less depending on the system config).</li>
<li>Code can be executed more often then the compiled framerate. A swf compiled at 1 fps can execute a Timer or Mouse event in every slice, even though it will only render in the last slice. Additionally, if you choose, you can render to the screen sooner then the compiled framerate by calling updateAfterEvent() , but only within a Mouse, Timer, or Keyboard event handler. In this instance though, the Marshal will consider that the end of the frame and start a new frame on the next slice. Lastly, Flash will force an automatic render when mousing over any Sprite that has had its visual properties (x,y,width,height,etc..) changed, naturally this still occurs at the end of the slice and any prerender logic will still run.</li>
<li>Compiling a framerate that isn&rsquo;t a multiple of the total number of slices per second for your platform will cause irregular rendering as it tries to divide up the slices. If you were to compile in a framerate of 20 on a platform executing 50 slices per second, then the player has to render 2 frames every 5 slices and would follow a 3-2-3-2-3-2 slice-to-render rate.</li>
</ol>
<p style="font-size: 1.3em; margin-left: 10px; margin-bottom: 1em;">These 4 facts are moving targets though, since for this article we&rsquo;re working on a 20 millisecond slice that&rsquo;s processed 50 times per second. In reality you&rsquo;ll see time slices as low as 5 milliseconds or as high at 100 milliseconds and some of the math will change as a result.</p>
<p style="font-size: 1.3em; margin-left: 10px; margin-bottom: 1em;">If you&rsquo;d like to test this model for yourself, the easiest route is to create a swf running at 1 fps and another at 100 fps both with a Timer object set on a 1 millisecond interval. Inside the Timer event handler change the x property of a display object and hook a bunch of getTimer() traces up to different player events like Mouse, EnterFrame, and Render and watch the carnage unfold in your console. The rest of the information you can&rsquo;t derive from the results comes from alot of context about the player I&rsquo;ve learned over the past 2 years and so isn&rsquo;t as easily visible. If anyone has any information to help add to or correct the above model, please submit it in the comments.</p>
<p style="font-size: 1.3em; margin-left: 10px; margin-bottom: 1em;">Thanks to several readers who have clarified some of the differences between Flex and Flash as well as how the Flash API is able to change the default behaviors described above.</p><img src="http://www.cnblogs.com/sun11086/aggbug/1686290.html?type=1" width="1" height="1" alt=""/><p>评论: 0　<a href="http://www.cnblogs.com/sun11086/archive/2010/03/15/1686290.html#pagedcomment" target="_blank">查看评论</a>　<a href="http://www.cnblogs.com/sun11086/archive/2010/03/15/1686290.html#commentform" target="_blank">发表评论</a></p><p><a href="http://job.cnblogs.com/" target="_blank">找优秀程序员，就在博客园</a></p><hr/><p>最新新闻：<br/>· <a href="http://news.cnblogs.com/n/59262/" target="_blank">甲骨文将关闭OpenSSO</a><span style="color:gray">(2010-03-20 23:54)</span><br/>· <a href="http://news.cnblogs.com/n/59261/" target="_blank">专访陈晓薇：九城已重建、我还没想好去哪</a><span style="color:gray">(2010-03-20 22:07)</span><br/>· <a href="http://news.cnblogs.com/n/59260/" target="_blank">[视频]社交媒体不仅仅是一时狂热</a><span style="color:gray">(2010-03-20 21:58)</span><br/>· <a href="http://news.cnblogs.com/n/59259/" target="_blank">Google开出首个1337美刀的Chrome bug奖励支票</a><span style="color:gray">(2010-03-20 21:47)</span><br/>· <a href="http://news.cnblogs.com/n/59258/" target="_blank">著名图像讨论网站4chan创始人披露4chan诞生历史</a><span style="color:gray">(2010-03-20 21:42)</span><br/></p><p>编辑推荐：<a href="http://news.cnblogs.com/n/59093/" target="_blank">[视频]想做你的Code</a><br/></p><p>网站导航：<a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/" target="_blank">个人主页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/group/" target="_blank">小组</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://kb.cnblogs.com" target="_blank">知识库</a></p>]]></description></item><item><title>[转]Flex和AIR中的垃圾回收实践之对象缓存[译文]</title><link>http://www.cnblogs.com/sun11086/archive/2010/02/26/1674192.html</link><dc:creator>sungo</dc:creator><author>sungo</author><pubDate>Fri, 26 Feb 2010 05:05:00 GMT</pubDate><guid>http://www.cnblogs.com/sun11086/archive/2010/02/26/1674192.html</guid><description><![CDATA[<p>阅读: 7 评论: 0 作者: <a href="http://www.cnblogs.com/sun11086/" target="_blank">sungo</a> 发表于 2010-02-26 13:05 <a href="http://www.cnblogs.com/sun11086/archive/2010/02/26/1674192.html" target="_blank">原文链接</a></p><p>转自:http://www.riameeting.com/node/587</p>
<p>原文在这里：<a href="http://spreadingfunkyness.com/garbage-collection-with-flex-and-adobe-air/" target="_blank">Garbage Collection with Flex and Adobe Air </a></p>
<p>我终于有时间来整理在flexcamp上演讲的东西并写篇博客了。就在flexcamp前一个月，我几乎天天和FlexProfiler争吵而且关系很紧张（笔者注：结论不一致）。因此我觉得在flexcamp中讲讲性能监测和垃圾回收（GC）是非常合适的话题。没错，想要脱离GC去获得性能提升简直是不可能的。如果你想改善你的应用的内存管理你必须知道Flashplayer（和adobe AIR）如何管理内存分配和释放。</p>
<p>有许多博客、文章、演讲、等等都介绍过GC和profiling，我在文章底部将他们列举了出来。对于每天使用Flex并且需要来优化内存消耗的初学者和中等经验的开发者来说，我这篇文章是有帮助意义的。</p>
<p>虚拟机(VM)</p>
<p>flashplayer是基于一个虚拟机（精确的来说是2两个，一个是为actionscript2的一个是为actionscript3的），当你需要创建新的对象时虚拟机动态分配内存，例如下面的代码来创建一个新的对象：</p>
<p>&nbsp;&nbsp;var o:Object = new Object();<br />&nbsp;&nbsp;<br />在启动时VM事先占用（reserve）了一些内存，当上面的代码被执行时VM决定那个对象放在应用内存的什么位置以及它需要占用多少空间。当你创建对象时，VM可能使用启动时占用的所有内存，如果需要，再向操作系统请求更多的内存。除非你有一个程序仅仅是毫无疑义的创建新对象，正常的应用在执行时必然会有一个对象变为无用的时候，例如，为了正确的执行程序，它不需要存在了。你将会看到，理解一个对象何时不再被需要是不容易的事情。就现在，让我们加深我们能够检测到它。在Flash VM架构，你不能明确的说&ldquo;删除它&rdquo;，内存使用是被VM本身所管理的，VM本身负责检查哪些对象是无用的并擅长他们，这样的机制就叫做垃圾回收。</p>
<p>垃圾回收</p>
<p>那么，作为一个程序员我们能做什么？好的，你可以让垃圾回收变得容易，让我们来看看下图能为我们揭示什么内容。<br /><img src="http://spreadingfunkyness.com/wp-content/uploads/2009/01/memblocks.gif" /></p>
<p>在启动阶段应用占用了一些要使用的内存，比如说4个块。当你创建了一个对象，VM将第一个空位分配给它。我们说，过一会当o1不再需要是你将它设为null。你创建一个新的对象o2，你希望o2代替o1。有时它发生，有时它不会发生，这取决于垃圾回收机制，这样一种非常复杂的过程，我们不在这里描述。这时我们已经得到一个教训：&ldquo;设置一个对象为null不一定能够释放它占用的内存&rdquo;。这取决于flash中已经实现的垃圾回收的方式，GC由重分配触发而不是由删除触发，这意味着GC周期在你声明new Object()的时候运行而不是你设置它为null时运行。</p>
<p>内存消耗</p>
<p>如果你不得不使用AS3和Flex，你可能知道你可以动态的添加UI元素到图形界面中，通过一个简单的方法叫做addChild()，相反的方法是removeChild()，它用来移除一个显示元素从UI中。更精确的来说，元素是从视图中删除，但是这不意味着它已经被垃圾回收了。让我来介绍一个简单的场景给你展示很容易相信removeChild()的事实。</p>
<p>许多Flex应用从服务端加载数据并根据返回的值动态展示它，通常情况视图代码被隔离到一个组件中，经常被称为renderer，它负责展示来自服务器的数据。我没设计一个非常简单的renderer，它由两个文本字段，嵌入一个VBox中，数据显示是field1和field2，被提供的对象的属性作为值来源：</p>
<pre class="xml"><span style="color: #009900;"><span style="font-weight: bold; color: #000000;">&lt;mx:VBox</span> <span style="color: #000066;">xmlns:mx</span>=<span style="color: #ff0000;">"http://www.adobe.com/2006/mxml"</span> </span><span style="color: #009900;">    <span style="color: #000066;">borderStyle</span>=<span style="color: #ff0000;">"solid"</span> <span style="color: #000066;">width</span>=<span style="color: #ff0000;">"200"</span> </span><span style="color: #009900;">    <span style="font-weight: bold; color: #000000;">&gt;</span></span>    <span style="color: #009900;"><span style="font-weight: bold; color: #000000;">&lt;mx:Script<span style="font-weight: bold; color: #000000;">&gt;</span></span></span>        <span style="color: #339933;">&lt;![CDATA[</span><span style="color: #339933;">    [Bindable] private var _field1:String;</span><span style="color: #339933;">    [Bindable] private var _field2:String;</span>&nbsp;<span style="color: #339933;">    override public function set data(value:Object):void {</span><span style="color: #339933;">_field1 = value.field1;</span><span style="color: #339933;">_field2 = value.field2;</span><span style="color: #339933;">    }</span><span style="color: #339933;">]]&gt;</span><span style="color: #009900;"><span style="font-weight: bold; color: #000000;">&lt;/mx:Script<span style="font-weight: bold; color: #000000;">&gt;</span></span></span>&nbsp;<span style="color: #009900;"><span style="font-weight: bold; color: #000000;">&lt;mx:Text</span> <span style="color: #000066;">text</span>=<span style="color: #ff0000;">"{_field1}"</span> <span style="font-weight: bold; color: #000000;">/&gt;</span></span><span style="color: #009900;"><span style="font-weight: bold; color: #000000;">&lt;mx:Text</span> <span style="color: #000066;">text</span>=<span style="color: #ff0000;">"{_field2}"</span> <span style="font-weight: bold; color: #000000;">/&gt;</span></span><span style="color: #009900;"><span style="font-weight: bold; color: #000000;">&lt;/mx:VBox<span style="font-weight: bold; color: #000000;">&gt;</span></span></span></pre>
<p>让我们通过一个简单的函数来模拟数据载入，它返回对象的一个数组：</p>
<pre class="actionscript"><span style="color: #0066cc;">private</span> <span style="font-weight: bold; color: #000000;">function</span> getData<span style="color: #66cc66;">(</span><span style="color: #66cc66;">)</span>:<span style="color: #0066cc;">Array</span> <span style="color: #66cc66;">{</span>&nbsp;</pre>
<pre class="actionscript">   <span style="font-weight: bold; color: #000000;">var</span> a:<span style="color: #0066cc;">Array</span> = <span style="font-weight: bold; color: #000000;">new</span> <span style="color: #0066cc;">Array</span><span style="color: #66cc66;">(</span><span style="color: #66cc66;">)</span>;&nbsp;  &nbsp;</pre>
<pre class="actionscript"> 　<span style="color: #b1b100;">for</span> <span style="color: #66cc66;">(</span><span style="font-weight: bold; color: #000000;">var</span> i:uint = <span style="color: #cc66cc;">0</span>; i<span style="color: #66cc66;">&lt;</span> <span style="color: #cc66cc;">200</span>; i++<span style="color: #66cc66;">)</span>&nbsp;</pre>
<pre class="actionscript"><span style="color: #66cc66;">　　{</span></pre>
<pre class="actionscript"><span style="color: #66cc66;">&nbsp;</span><span style="font-weight: bold; color: #000000;">　　　　var</span> o:<span style="color: #0066cc;">Object</span> = <span style="font-weight: bold; color: #000000;">new</span> <span style="color: #0066cc;">Object</span><span style="color: #66cc66;">(</span><span style="color: #66cc66;">)</span>;</pre>
<pre class="actionscript">　　　　o.<span style="color: #006600;">field1</span> = <span style="color: #ff0000;">"field "</span>+<span style="color: #0066cc;">Math</span>.<span style="color: #0066cc;">random</span><span style="color: #66cc66;">(</span><span style="color: #66cc66;">)</span>.<span style="color: #0066cc;">toString</span><span style="color: #66cc66;">(</span><span style="color: #66cc66;">)</span>;</pre>
<pre class="actionscript">　　　　o.<span style="color: #006600;">field2</span> = <span style="color: #ff0000;">"field "</span>+<span style="color: #0066cc;">Math</span>.<span style="color: #0066cc;">random</span><span style="color: #66cc66;">(</span><span style="color: #66cc66;">)</span>.<span style="color: #0066cc;">toString</span><span style="color: #66cc66;">(</span><span style="color: #66cc66;">)</span>;</pre>
<pre class="actionscript">  　　   a.<span style="color: #0066cc;">push</span><span style="color: #66cc66;">(</span>o<span style="color: #66cc66;">)</span>;  &nbsp;</pre>
<pre class="actionscript">　　 <span style="color: #66cc66;">}</span> &nbsp;</pre>
<pre class="actionscript">  <span style="color: #b1b100;">return</span> a;<span style="color: #66cc66;">}</span></pre>
<p>为了渲染数据，我们使用一个简单的函数，来创建一个renderer，设置它的data属性，并添加到VBox中：</p>
<pre class="actionscript"><span style="color: #0066cc;">private</span> <span style="font-weight: bold; color: #000000;">function</span> loadData<span style="color: #66cc66;">(</span><span style="color: #66cc66;">)</span>:<span style="color: #0066cc;">void</span> <span style="color: #66cc66;">{</span>  &nbsp;</pre>
<pre class="actionscript"> vbox.<span style="color: #006600;">removeAllChildren</span><span style="color: #66cc66;">(</span><span style="color: #66cc66;">)</span>;   &nbsp;</pre>
<pre class="actionscript"><span style="font-weight: bold; color: #000000;">var</span> <span style="color: #0066cc;">array</span>:<span style="color: #0066cc;">Array</span> = getData<span style="color: #66cc66;">(</span><span style="color: #66cc66;">)</span>;&nbsp;   &nbsp;</pre>
<pre class="actionscript"><span style="color: #b1b100;">for</span> <span style="color: #66cc66;">(</span><span style="font-weight: bold; color: #000000;">var</span> i:<span style="color: #0066cc;">int</span> = <span style="color: #cc66cc;">0</span>; i <span style="color: #66cc66;">&lt;</span> <span style="color: #0066cc;">array</span>.<span style="color: #0066cc;">length</span>; i++<span style="color: #66cc66;">)</span>&nbsp;</pre>
<pre class="actionscript"><span style="color: #66cc66;">　　{</span></pre>
<pre class="actionscript"><span style="color: #66cc66;"></span><span style="font-weight: bold; color: #000000;">　　var</span> rend:MyRenderer = <span style="font-weight: bold; color: #000000;">new</span> MyRenderer<span style="color: #66cc66;">(</span><span style="color: #66cc66;">)</span>;</pre>
<pre class="actionscript">　　rend.<span style="color: #0066cc;">data</span> = <span style="color: #0066cc;">array</span><span style="color: #66cc66;">[</span>i<span style="color: #66cc66;">]</span>;box.<span style="color: #006600;">addChild</span><span style="color: #66cc66;">(</span>rend<span style="color: #66cc66;">)</span>;     &nbsp;</pre>
<pre class="actionscript">　　  i++;   &nbsp;</pre>
<pre class="actionscript"><span style="color: #66cc66;">　　}</span>&nbsp;</pre>
<pre class="actionscript"><span style="color: #66cc66;">}</span></pre>
<p>你看到那个危险的声明了吗？还没有？让我来显示给你，为了模拟一个重复的操作，我添加了一个timer，它会每N秒都调用加载数据的函数：</p>
<pre class="actionscript"><span style="color: #0066cc;">private</span> <span style="font-weight: bold; color: #000000;">function</span> init<span style="color: #66cc66;">(</span><span style="color: #66cc66;">)</span>:<span style="color: #0066cc;">void</span> <span style="color: #66cc66;">{</span>   &nbsp;</pre>
<pre class="actionscript"><span style="font-weight: bold; color: #000000;">　　var</span> t:Timer = <span style="font-weight: bold; color: #000000;">new</span> Timer<span style="color: #66cc66;">(</span><span style="color: #cc66cc;">2000</span><span style="color: #66cc66;">)</span>;  &nbsp;</pre>
<pre class="actionscript">　　 t.<span style="color: #006600;">addEventListener</span><span style="color: #66cc66;">(</span>TimerEvent.<span style="color: #006600;">TIMER</span>, tick<span style="color: #66cc66;">)</span>;   &nbsp;</pre>
<pre class="actionscript">　　t.<span style="color: #0066cc;">start</span><span style="color: #66cc66;">(</span><span style="color: #66cc66;">)</span>;</pre>
<pre class="actionscript"><span style="color: #66cc66;">}</span></pre>
<p>现在，试着运行一下profiler（笔者注：flexbuilder3中的工具），你看到像下图一样一直增长的图形了吗？</p>
<p><img src="http://spreadingfunkyness.com/wp-content/uploads/2009/01/growing.gif" /><br />恭喜，我们已经发现了一个内存泄漏！内存泄漏发生在重复的动作并且内存消耗持续增长而不是保持恒定。你发现了那个危险的声明了吗？它就是当你创建renderer是发生的。为什么？因为你认为removeAllChildren()从内存中移除了那些renderers。错误！正像上面所说，这个方法仅仅从显示树（显示列表）中移除了renderers，事实上，正如你从profiler中看到的，renderers还在那儿，继续消耗着内存。</p>
<p>技术上讲这不是一个内存泄漏，因为这没有任何东西阻止垃圾回收器去清除来自renderers的内存。事实上这种情形下，内存泄漏发生在，当有些对象被认为使用了renderer（例如一个listener），即使当你从显示树中移除了它。在这个例子中renderers是&ldquo;自由的&rdquo;，可能被垃圾回收，但是，他们不是这样的，因此，结果仍然与内存泄漏是相同的，不断增长的内存消耗：</p>
<p><img src="http://spreadingfunkyness.com/wp-content/uploads/2009/01/instancescount.gif" /><br />有许多技术来解决这种情况，我们来展示两个：缓存renderers和动态缓存。</p>
<p>缓存</p>
<p>让我们假设，你实现知道需要多少renderers，一个方法来解决内存泄漏就是在启动是来创建一个renderers的缓存：</p>
<pre class="actionscript"><span style="color: #0066cc;"><p>&nbsp;</p><pre class="brush:java">private var cache:Array = new Array(); 
private function initRenderers():void {   
 for (var i:int = 0; i &lt; 200; i++)&nbsp;</pre>
<pre class="brush:java">{renderers.push(new MyRenderer());    }
}
</pre>
<br /></span></pre>
<p>我们于是可以这样修改我们的loadData方法：</p>
<pre class="actionscript"><span style="color: #0066cc;"><pre class="brush:java">private function loadData():void {  &nbsp;</pre>
<pre class="brush:java"> container.removeAllChildren();   &nbsp;</pre>
<pre class="brush:java">var array:Array = getData();   &nbsp;</pre>
<pre class="brush:java"> for (var i:int = 0; i &lt; array.length; i++)</pre>
<pre class="brush:java"> {var rend:MyRenderer = cache[i];rend.data = array[i];  container.addChild(rend);i++;    }&nbsp;</pre>
<pre class="brush:java">}
</pre>
<br /></span></pre>
<p>正如你所见，我们不再创建新的renderers，而是在缓存中查找一个。</p>
<p>很多情况下，你事先不知道多少数据从服务器返回，而且不知道你需要多少renderers，这时你需要一个动态缓存。</p>
<p>动态缓存</p>
<p>动态缓存是基于一个弹性的机制，你有一个地方可以来查找一个renderer：如果缓存中有一个，那就返回它，否则一个新的被临时创建，最好来看看下面的代码：</p>
<pre class="actionscript"><span style="color: #0066cc;">public</span> <span style="font-weight: bold; color: #000000;">class</span> MyRendererCache <span style="color: #0066cc;">extends</span> <span style="color: #0066cc;">Object</span> <span style="color: #66cc66;">{</span>&nbsp;  &nbsp;</pre>
<pre class="actionscript"> <span style="color: #0066cc;">private</span> <span style="color: #0066cc;">static</span> <span style="font-weight: bold; color: #000000;">var</span> cache : ArrayCollection = <span style="font-weight: bold; color: #000000;">new</span> ArrayCollection<span style="color: #66cc66;">(</span><span style="color: #66cc66;">)</span>;</pre>
<pre class="actionscript">&nbsp;<span style="color: #0066cc;">public</span> <span style="font-weight: bold; color: #000000;">function</span> MyRendererCache<span style="color: #66cc66;">(</span><span style="color: #66cc66;">)</span> <span style="color: #66cc66;">{</span>  &nbsp;</pre>
<pre class="actionscript"> <span style="color: #0066cc;">super</span><span style="color: #66cc66;">(</span><span style="color: #66cc66;">)</span>;           &nbsp;</pre>
<pre class="actionscript"><span style="color: #b1b100;">for</span> <span style="color: #66cc66;">(</span> <span style="font-weight: bold; color: #000000;">var</span> x : <span style="color: #0066cc;">Number</span> = <span style="color: #cc66cc;">0</span>; x <span style="color: #66cc66;">&lt;</span> <span style="color: #cc66cc;">20</span>; x ++ <span style="color: #66cc66;">)</span>&nbsp;</pre>
<pre class="actionscript"><span style="color: #66cc66;">{</span>cache.<span style="color: #006600;">addItem</span><span style="color: #66cc66;">(</span> <span style="font-weight: bold; color: #000000;">new</span> MyRenderer<span style="color: #66cc66;">(</span><span style="color: #66cc66;">)</span> <span style="color: #66cc66;">)</span>;    <span style="color: #66cc66;">}</span><span style="color: #66cc66;">}</span></pre>
<pre class="actionscript"><span style="color: #66cc66;"></span>&nbsp;<span style="color: #0066cc;">public</span> <span style="color: #0066cc;">static</span> <span style="font-weight: bold; color: #000000;">function</span> getRenderer<span style="color: #66cc66;">(</span><span style="color: #66cc66;">)</span> : MyRenderer <span style="color: #66cc66;">{</span> &nbsp;</pre>
<pre class="actionscript">  <span style="font-weight: bold; color: #000000;">var</span> renderer : MyRenderer;&nbsp;  &nbsp;</pre>
<pre class="actionscript"> <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">(</span> cache.<span style="color: #0066cc;">length</span> <span style="color: #66cc66;">&lt;</span>= <span style="color: #cc66cc;">0</span> <span style="color: #66cc66;">)</span></pre>
<pre class="actionscript"><span style="color: #66cc66;"></span>　　　　 <span style="color: #66cc66;">{</span>renderer = <span style="font-weight: bold; color: #000000;">new</span> MyRenderer<span style="color: #66cc66;">(</span><span style="color: #66cc66;">)</span>;    <span style="color: #66cc66;">}</span>&nbsp;</pre>
<pre class="actionscript"><span style="color: #b1b100;">else</span>&nbsp;</pre>
<pre class="actionscript"><span style="color: #66cc66;">         {</span> renderer = cache.<span style="color: #006600;">removeItemAt</span><span style="color: #66cc66;">(</span> <span style="color: #cc66cc;">0</span> <span style="color: #66cc66;">)</span> as MyRenderer;    <span style="color: #66cc66;">}</span>&nbsp; &nbsp;</pre>
<pre class="actionscript">  <span style="color: #b1b100;">return</span> renderer;        <span style="color: #66cc66;">}</span>&nbsp;      &nbsp;</pre>
<pre class="actionscript"> <span style="color: #0066cc;">public</span> <span style="color: #0066cc;">static</span> <span style="font-weight: bold; color: #000000;">function</span> setRenderer<span style="color: #66cc66;">(</span> renderer : MyRenderer <span style="color: #66cc66;">)</span> : <span style="color: #0066cc;">void</span> <span style="color: #66cc66;">{</span></pre>
<pre class="actionscript"><span style="color: #66cc66;"></span>    cache.<span style="color: #006600;">addItem</span><span style="color: #66cc66;">(</span> renderer <span style="color: #66cc66;">)</span>;        <span style="color: #66cc66;">}</span></pre>
<pre class="actionscript"><span style="color: #66cc66;"></span><span style="color: #66cc66;">}</span></pre>
<p>在构造函数中，你操作缓存用最小数目的renderers，比如说2个。这个缓存有两个静态方法，getRenderer和setRenderer，第一个是来获得一个renderer，第二个是当结束时返还给它。这种方式下内存中renderers的数量可能增长超过最小的数目，但是仅是临时的，因为GC会在他们当不在被引用时删除他们。一个重要的问题是跟setRenderer有关，当你不再需要一个renderer时，你必须把它返回给cache，否则我们又陷入内存泄漏中，如上解释的那样。为了达到这个目的，我们来利用renderer的remove事件，remove事件是当一个UI元素被从显示列表中移除时被触发。例如当我们调用removeAllChildren()，这样的事件对于每一个renderer来说都会被触发。我们可以这样修改renderer：</p>
<pre class="xml"><span style="color: #009900;"><span style="font-weight: bold; color: #000000;">&lt;mx:VBox</span> <span style="color: #000066;">xmlns:mx</span>=<span style="color: #ff0000;">"http://www.adobe.com/2006/mxml"</span> </span><span style="color: #009900;">    <span style="color: #000066;">borderStyle</span>=<span style="color: #ff0000;">"solid"</span> <span style="color: #000066;">width</span>=<span style="color: #ff0000;">"200"</span> </span><span style="color: #009900;">    <span style="color: #000066;">remove</span>=<span style="color: #ff0000;">"onRemove()"</span></span><span style="color: #009900;">    <span style="font-weight: bold; color: #000000;">&gt;</span></span>&nbsp;    private function onRemove():void {MyRendererCache.setRenderer(this);    }....<span style="color: #009900;"><span style="font-weight: bold; color: #000000;">&lt;/VBox<span style="font-weight: bold; color: #000000;">&gt;</span></span></span></pre>
<p>如果现在来运行profiler，你会注意到，内存增长到一个给定的点并且保持稳定，如下图所示：</p>
<p>&nbsp;<img src="http://spreadingfunkyness.com/wp-content/uploads/2009/01/memstable.gif" /></p>
<p>恭喜，你已经解决了内存泄漏！</p>
<p>建议性GC&nbsp;</p>
<p>除了偏向于自动的GC过程，adobe还允许程序员来建议干涉性的GC。这个命令在flash.system包中的System.gc()，通过这篇文章&ldquo;强制垃圾回收过程&rdquo;，但是在我的经验来看，这仅仅是一个模糊的干涉建议，它能解决某些情况，因此在开始时它值得一试，当你需要一个快速的方法来节省一些内存时。</p><img src="http://www.cnblogs.com/sun11086/aggbug/1674192.html?type=1" width="1" height="1" alt=""/><p>评论: 0　<a href="http://www.cnblogs.com/sun11086/archive/2010/02/26/1674192.html#pagedcomment" target="_blank">查看评论</a>　<a href="http://www.cnblogs.com/sun11086/archive/2010/02/26/1674192.html#commentform" target="_blank">发表评论</a></p><p><a href="http://job.cnblogs.com/" target="_blank">找优秀程序员，就在博客园</a></p><hr/><p>最新新闻：<br/>· <a href="http://news.cnblogs.com/n/59262/" target="_blank">甲骨文将关闭OpenSSO</a><span style="color:gray">(2010-03-20 23:54)</span><br/>· <a href="http://news.cnblogs.com/n/59261/" target="_blank">专访陈晓薇：九城已重建、我还没想好去哪</a><span style="color:gray">(2010-03-20 22:07)</span><br/>· <a href="http://news.cnblogs.com/n/59260/" target="_blank">[视频]社交媒体不仅仅是一时狂热</a><span style="color:gray">(2010-03-20 21:58)</span><br/>· <a href="http://news.cnblogs.com/n/59259/" target="_blank">Google开出首个1337美刀的Chrome bug奖励支票</a><span style="color:gray">(2010-03-20 21:47)</span><br/>· <a href="http://news.cnblogs.com/n/59258/" target="_blank">著名图像讨论网站4chan创始人披露4chan诞生历史</a><span style="color:gray">(2010-03-20 21:42)</span><br/></p><p>编辑推荐：<a href="http://news.cnblogs.com/n/59093/" target="_blank">[视频]想做你的Code</a><br/></p><p>网站导航：<a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/" target="_blank">个人主页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/group/" target="_blank">小组</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://kb.cnblogs.com" target="_blank">知识库</a></p>]]></description></item><item><title>[转] 两篇关于flash 职业和webgame的文章</title><link>http://www.cnblogs.com/sun11086/archive/2010/02/26/1674036.html</link><dc:creator>sungo</dc:creator><author>sungo</author><pubDate>Fri, 26 Feb 2010 02:36:00 GMT</pubDate><guid>http://www.cnblogs.com/sun11086/archive/2010/02/26/1674036.html</guid><description><![CDATA[<p>阅读: 87 评论: 0 作者: <a href="http://www.cnblogs.com/sun11086/" target="_blank">sungo</a> 发表于 2010-02-26 10:36 <a href="http://www.cnblogs.com/sun11086/archive/2010/02/26/1674036.html" target="_blank">原文链接</a></p><p>第一篇转自:<a href="http://flashteam.tencent.com/post/52/%E8%AF%A0%E9%87%8Aflash%E7%9A%84%E8%81%8C%E4%B8%9A%E5%8F%91%E5%B1%95%E9%81%93%E8%B7%AF/">http://flashteam.tencent.com/post/52/诠释flash的职业发展道路/</a></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.9em; margin-left: 0px; line-height: 19px; font-family: 'Microsoft YaHei', Georgia, serif; font-size: 14px; padding: 0px;">作为极少数的还活着的纯flash枯骨之一， 在经历了从mm到adobe，从as1到as3，从当年flash等同于动画的代名词，到当今的flash程序员大批的崛起的时代，一直想抽时间写一个职业发展总结来给新学习flash的，以及对于flash职业很模糊的同学同事同乡同人类们分享下这方面的心得，让大家少走一些弯路，能重新认识下flash技术和flash行业。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.9em; margin-left: 0px; line-height: 19px; font-family: 'Microsoft YaHei', Georgia, serif; font-size: 14px; padding: 0px;">首先，我是一个幸运的flash开发者，我所在的公司一直都把flash作为公司最主要的技术之一，所以我有机会从很早的时候就一直深入接触flash和相关技术并从事as开发职位以及相关职位的招聘。不过这在5，6年前来说，是很难找到这种公司的，那时中国市场依然普遍对flash不感冒，但是随着flash的普及以及flash游戏和网站项目的市场进化和发展，flash程序员现在有了很好的契机，很多新公司都有对flash人才重视起来，各种职位层出不穷，让热爱flash技术的人们有了很多更适合自己的选择。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.9em; margin-left: 0px; line-height: 19px; font-family: 'Microsoft YaHei', Georgia, serif; font-size: 14px; padding: 0px;">那么如何区分用人单位招你过去是否偏重于flash技术呢？很简单，从职位title的名字可以过滤多数，如UI Designer（UI设计师），网站设计师（很含糊的一个职位），软件工程师等。 这些职位描述多数也都包含flash，但却很少使用到flash，多数是让你作为一个技术备份，如果选择这类职位，将直接让你走出flash行业。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.9em; margin-left: 0px; line-height: 19px; font-family: 'Microsoft YaHei', Georgia, serif; font-size: 14px; padding: 0px;">那么让我们看看正规的flash行业内的圈子是怎样的：</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.9em; margin-left: 0px; line-height: 19px; font-family: 'Microsoft YaHei', Georgia, serif; font-size: 14px; padding: 0px;"><a style="color: #000000; text-decoration: none; border-bottom-color: #ef0050; border-bottom-width: 1px; border-bottom-style: dotted; padding: 0px; margin: 0px;" href="http://flashteam.tencent.com/wp-content/uploads/2010/02/flashroad.jpg"><img style="padding: 0px; margin: 0px; border: 0px initial initial;" height="422" width="670" src="http://flashteam.tencent.com/wp-content/uploads/2010/02/flashroad.jpg" title="flashroad" class="wp-image-54 size-full alignnone" /></a></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.9em; margin-left: 0px; line-height: 19px; font-family: 'Microsoft YaHei', Georgia, serif; font-size: 14px; padding: 0px;">＃注：上图从左至右依次表明了flash职位的发展道路， 从上至下表明了从设计师到程序员的偏重度。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.9em; margin-left: 0px; line-height: 19px; font-family: 'Microsoft YaHei', Georgia, serif; font-size: 14px; padding: 0px;">在flash行业内</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.9em; margin-left: 0px; line-height: 19px; font-family: 'Microsoft YaHei', Georgia, serif; font-size: 14px; padding: 0px;">第一阶段：</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.9em; margin-left: 0px; line-height: 19px; font-family: 'Microsoft YaHei', Georgia, serif; font-size: 14px; padding: 0px;">当你刚学习flash时，无论你是作为设计师还是之前从事别的程序的程序员，都是一片空白，所以都在一个模糊混沌的起点，这个阶段统称为flash newbie（新手） 阶段，在这个阶段内，你会根据你自己的喜好，选择适合自己的技术，如设计师会偏重动画，motion graphics以及手绘，程序员会偏重as，网站编程和视觉特效，设计和程序都会一些的人学的就比较杂，各方面的技术都会搞一些，在第一阶段内我推荐尽量让自己多学习一些各方面flash技术，多发掘自己的综合潜力，这对你后面在职位选择时就多一些范围。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.9em; margin-left: 0px; line-height: 19px; font-family: 'Microsoft YaHei', Georgia, serif; font-size: 14px; padding: 0px;">第二阶段：</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.9em; margin-left: 0px; line-height: 19px; font-family: 'Microsoft YaHei', Georgia, serif; font-size: 14px; padding: 0px;">随着你对flash的逐步深入，你会发现自己的特长会被凸显，这时会有一些职位适合你入行</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.9em; margin-left: 0px; line-height: 19px; font-family: 'Microsoft YaHei', Georgia, serif; font-size: 14px; padding: 0px;"><strong>Flash Designer（</strong>设计师）， 这个职位在以前很常见，是美工专职做flash的一个特殊职位，会一些简单的as，并且会画动画，做一些motion graphics，同时也会做一些平面设计。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.9em; margin-left: 0px; line-height: 19px; font-family: 'Microsoft YaHei', Georgia, serif; font-size: 14px; padding: 0px;"><strong>NewMedia Developer</strong>（新媒体开发者），新媒体开发者的概念是公司需要综合能力的人才，需要会as，但不需要特别强，也要会做一些动画，拼装素材以及会写简单的js，通常是flash网站项目的公司多一些这类职位。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.9em; margin-left: 0px; line-height: 19px; font-family: 'Microsoft YaHei', Georgia, serif; font-size: 14px; padding: 0px;"><strong>Actionscript Programmer</strong>（纯as开发），纯as开发者多见于程序员出身的背景，这两年比较多的java和javascript前端开发者加入了flash阵营，这个职位的个性就更加明显：完全不需要管界面，甚至有不会用flash ide的人，使用flex以及第三方编辑器直接运行flash项目，但这类人群对flash的综合技术认知不够，还需要时间深入了解flash，不能完全用java和js的想法开发flash项目，这个阶段的as开发者，暂时还没有显著的职业特性来区分。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.9em; margin-left: 0px; line-height: 19px; font-family: 'Microsoft YaHei', Georgia, serif; font-size: 14px; padding: 0px;">第三阶段：</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.9em; margin-left: 0px; line-height: 19px; font-family: 'Microsoft YaHei', Georgia, serif; font-size: 14px; padding: 0px;">慢慢的，随着经验的积累和对flash的了解深入，和公司项目需要，已经慢慢走出了flash的范畴，出现了三个更明显的职位：</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.9em; margin-left: 0px; line-height: 19px; font-family: 'Microsoft YaHei', Georgia, serif; font-size: 14px; padding: 0px;"><strong>Interactive Designer（互动设计师），</strong>这个职位是因为设计师随着个人发展的喜好以及对于程序的了解深入而有的一个职位，广告公司这种职位多一些，除了会设计外，还需要你写一些程序，但偏向前端表现，如粒子特效和tween动画。这类职位并非一般意义上的交互设计师。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.9em; margin-left: 0px; line-height: 19px; font-family: 'Microsoft YaHei', Georgia, serif; font-size: 14px; padding: 0px;"><strong>Interactive Programmer （互动程序员）</strong>，这个职位和上面的职位很类似，但是偏重点偏程序多一些，但平时的工作也会做一些动画，但可能是video（aftereffect），有时也会涉及到director lingo编程和网页js和flash小游戏，这个职位其实很累，需要会很多的技术，但是通常职业选择面会广一些。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.9em; margin-left: 0px; line-height: 19px; font-family: 'Microsoft YaHei', Georgia, serif; font-size: 14px; padding: 0px;"><strong>Game Programmer （游戏程序员）</strong>，这个职位就在08年之前都很少见，而且是纯flash游戏开发，但这两年就随着sns游戏的普及以及webgame的投资增多就很抢手，导致现在看flash简历基本都说自己会写游戏。这个职位的基本需求其实很多人没有搞清楚，下面我略微详细的说下以便大家能多补充下知识。 首先你要<strong>热爱游戏</strong>，如果你不爱玩游戏那么你也开发不出什么好体验的游戏。技术方面还要会很综合的各种游戏算法，如A*,各种排序，数据结构，地图技术以及需要你对性能优化有一定的经验，如知道矢量图和位图在flash中运行时的差异，地图的按需加载，如何写程序才更有效率（苛刻到毫秒级微秒级）等，并且需要一定的设计模式知识，如果是3d项目，还需要有一定的3d知识，还需要对客户端服务器端传输有一定的优化经验，客户端安全性，防外挂以及协议安全等，如果是海量服务还需要针对流量优化。 所以想要成为一个真正的flash游戏程序员，你背负着n多需要挑战的使命（不归路？），但如果你有一颗热爱游戏的心，上面所列的各种技术都会迎刃而解，会慢慢兴趣式的攻破，所以这也是为什么我把热爱游戏放到首要条件之一。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.9em; margin-left: 0px; line-height: 19px; font-family: 'Microsoft YaHei', Georgia, serif; font-size: 14px; padding: 0px;">就这样慢慢走出了flash&hellip;&hellip;</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.9em; margin-left: 0px; line-height: 19px; font-family: 'Microsoft YaHei', Georgia, serif; font-size: 14px; padding: 0px;">进入到了第四阶段，也是你flash职业生涯的黄金时段</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.9em; margin-left: 0px; line-height: 19px; font-family: 'Microsoft YaHei', Georgia, serif; font-size: 14px; padding: 0px;">这时因为你在flash之路所接触到的经验，已经不在拘泥于flash了，但仍然以flash项目为主。当然如果你选择了转行，就不是本文所谈论的范畴了。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.9em; margin-left: 0px; line-height: 19px; font-family: 'Microsoft YaHei', Georgia, serif; font-size: 14px; padding: 0px;">黄金阶段里面所出现的几个职位是这样的：</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.9em; margin-left: 0px; line-height: 19px; font-family: 'Microsoft YaHei', Georgia, serif; font-size: 14px; padding: 0px;">交互设计后，通常其实直接进入到了art director/newmedia director，但本文没有画出这两个职位。这里是一个发展瓶颈，交互设计师、程序员走到了这里已经在业界有了一定的资历和名气，也就自然走出了flash，万精油类型的发展适合开一些studio和广告公司合作，做单子或在一个大一些的公司做director走管理路线长期发展。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.9em; margin-left: 0px; line-height: 19px; font-family: 'Microsoft YaHei', Georgia, serif; font-size: 14px; padding: 0px;">如果对管理路线不感冒，下面还有更深入的&rdquo;职位&ldquo;，这些职位可能你在市场上看不到，但能进入到此，你也是能独当一面的超级flash人才了：</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.9em; margin-left: 0px; line-height: 19px; font-family: 'Microsoft YaHei', Georgia, serif; font-size: 14px; padding: 0px;"><strong>3D Programmer</strong>，这个职位现在还不多，但是随着硬件以及flash技术的发展，这个职位也许在未来会火起来，也是游戏开发者的一个比较好的进阶选择，偏重于图形学和前端表现多一些。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.9em; margin-left: 0px; line-height: 19px; font-family: 'Microsoft YaHei', Georgia, serif; font-size: 14px; padding: 0px;"><strong>Architecture</strong>，构架师，随着经验的积累以及对设计模式等框架技术的深入发掘，一个flash开发者最终会把自己定位成构架师，框架设计师，通常有一些企业型项目需要这类人才来建造项目框架，学过java的人很容易的走进这里，相当于在flash之路中仅仅是个过路人。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.9em; margin-left: 0px; line-height: 19px; font-family: 'Microsoft YaHei', Georgia, serif; font-size: 14px; padding: 0px;"><strong>Evangelism</strong>，flash传教士，这个其实不算一个真正意义的职位，是一类人群，早期是积极推广flash技术，并有影响力的一批外国人，如flashguru，gskinner等。这类人群的技术其实很全面，前后端技术都会懂一些，但深浅不一，对flash技术也很痴迷，能够对业界产生影响。这类人群在中国现在依然比较少，希望多一些技术全面的中国flash开发者能发扬此类精神弘扬flash文化。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.9em; margin-left: 0px; line-height: 19px; font-family: 'Microsoft YaHei', Georgia, serif; font-size: 14px; padding: 0px;">说了这么多，也许有人会问，楼主是哪类人呢？</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.9em; margin-left: 0px; line-height: 19px; font-family: 'Microsoft YaHei', Georgia, serif; font-size: 14px; padding: 0px;">其实我的路非常曲折，在上图中窜梭不同职位多次，否则也很难有这么多感慨，呵呵。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.9em; margin-left: 0px; line-height: 19px; font-family: 'Microsoft YaHei', Georgia, serif; font-size: 14px; padding: 0px;">最后，希望此文能对热爱flash的你有帮助，祝你们在flash的职业生涯中一帆风顺。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.9em; margin-left: 0px; line-height: 19px; font-family: 'Microsoft YaHei', Georgia, serif; font-size: 14px; padding: 0px;">&nbsp;</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.9em; margin-left: 0px; line-height: 19px; font-family: 'Microsoft YaHei', Georgia, serif; font-size: 14px; padding: 0px;">&nbsp;</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.9em; margin-left: 0px; line-height: 19px; font-family: 'Microsoft YaHei', Georgia, serif; font-size: 14px; padding: 0px;">&nbsp;</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.9em; margin-left: 0px; line-height: 19px; font-family: 'Microsoft YaHei', Georgia, serif; font-size: 14px; padding: 0px;">第二篇转自:<a href="http://bbs.blueidea.com/thread-2969949-1-1.html">http://bbs.blueidea.com/thread-2969949-1-1.html</a></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.9em; margin-left: 0px; line-height: 19px; font-family: 'Microsoft YaHei', Georgia, serif; font-size: 14px; padding: 0px;"><strong>★我的FLASH WEB GAME开发历程</strong><br style="word-wrap: break-word; line-height: normal;" />&rarr;2007年的夏天，顶着炎炎烈日，我从学校直接跑到上海，开始了我的FLASH WEB GAME创业之旅。时至今日，转眼快三年了。作为国内比较早的一批FLASH WEB GAME开发人员，今天我粗略的总结一下这两年多的经验和心得。讲的不对的地方，请大家多多指教。<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" />&rarr;2007年刚到上海的时候，初创团队只有四个人，一个CTO,一个美术，一个后台，一个前台。手里的产品是一个已经在台湾运行三年左右的FLASH社区，和国内的梦境非常像。这个产品还是不错的，早在FLASH5就在开发出来了，FLASH6出来后，又用新版本的AS1重写过。这个产品让我又爱又恨，爱的是，在2007年的时候，国内除了梦境和1D真的很少有能赶上它的；恨的是，这个产品竟然没有前端源码！要想修改还要破解！玩过AS1，在时间轴、MC和BTN上写过代码的朋友应该知道这是什么概念&mdash;&mdash;1个字：囧！<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" />&rarr;后来老板可能也觉得这样改下去不是办法，终于同意自己重写一个。正好07年有条新闻很火爆：国外有个FLASH社区第一次利用FLASH技术取得了重大成功，以7亿美金卖给迪斯尼，它就是&ldquo;企鹅俱乐部&rdquo;。老板看到了商机，我们决定做一个中国版的企鹅，于是&ldquo;海底世界&rdquo;应运而生了。而&ldquo;海底世界&rdquo;的创意，只不过是我们四个初创成员在闲聊时，我开玩笑随便说的。<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" />&rarr;海底世界正式开发到现在差不多正好两年，期间我们碰到无数的问题和困难，不管是公司层面或技术层面，都是如此，但始终是坚持了下来。产品一天天完善，公司规模也一天天扩大。前端从最开始的两个人，到现在5个人；后端从最开始的FMS+PHP到现在自己写的socket服务器；公司规模也从最开始的4个人，到现在的50多个人。<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" /><strong>★当今FLASH WEB GAME概述</strong><br style="word-wrap: break-word; line-height: normal;" />&rarr;2007：含苞欲放！<br style="word-wrap: break-word; line-height: normal;" />2007年可以说是FLASH WEB GAME发展史上的分水岭。2007年之前，我们眼里只有梦境，最多再加上昙花一现的抱抱城，那时候根本没有&ldquo;FLASH WEB GAME&rdquo;这个概念，大家谈的都是&ldquo;FLASH社区&rdquo;，&ldquo;FLASH社区&rdquo;这个词在很长一段时间代表着FLASH应用领域的至高点。也许2007年已经有不少团队开始研发FLASH的MMORPG了，我曾经有幸知道几个，但很可惜，不少都胎死腹中，2007年国内在线上运营的FLASH WEB GAME基本上还是空白。但不管怎么说，我相信2007年是蓄势待发的一年，肯定有很多类似我们公司的团队，在默默的努力着。<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" />&rarr;2008年：雨后春笋！<br style="word-wrap: break-word; line-height: normal;" />经过2007年的积累和准备，FLASH WEB GAME业界的战斗终于在2008年打响，以&ldquo;摩尔庄园&rdquo;，&ldquo;海底世界&rdquo;为代表的&ldquo;FLASH儿童虚拟社区&rdquo;开始崭露头角；以&ldquo;纵横天下&rdquo;为代表的FLASH策略类游戏兴起；以&ldquo;昆仑&rdquo;为代表的FLASH&nbsp;&nbsp;MMORPG让&ldquo;无端网游&rdquo;的概念又炒了起来。还有各种基于FLASH的卡牌对战类，联机棋牌类，模拟经营类游戏等等，都如雨后春笋般破土而出。<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" />&rarr;2009年：百花齐放！<br style="word-wrap: break-word; line-height: normal;" />2008年，国内虽然一下出了很多FLASH WEB GAME,但大家只要认真收集，总归还是能数的过来，可到了2009年，几乎每隔一个月，都会有几个新的FLASH WEB GAME进入大家视野，而且他们越来越完善，功能越来越强大，盈利模式也开始成熟并多样化。2007年每出一个FLASH WEB GAME,我都会为之兴奋，并很有兴趣的去研究它。而到了2009年末的时候，FLASH WEB GAME已经多到我连体验的兴趣都没了，我已经彻底搞不清楚国内到底有多少个FLASH WEB GAME在运营。而伴随着SNS行业的成熟，基于SNS的Social game进一步扩大和模糊着FLASH WEB GAME的概念。FLASH在游戏领域里的应用，在经历了&ldquo;社区&rdquo;、&ldquo;策略类&rdquo;、&ldquo;MMORPG&rdquo;后，发展到今天创意无限，精彩纷呈的&ldquo;Social game&rdquo;，已经很难用一个词，根据游戏类型概括所有的FLASH应用了。所以我觉得&ldquo;FLASH WEB GAME&rdquo;，也就是&ldquo;FLASH网页游戏&rdquo;这个词还是相对最恰当的，这也是我前面一直使用这个词的原因。<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" />&rarr;2010年 &ndash; 2011年：胜者为王！<br style="word-wrap: break-word; line-height: normal;" />就像春秋战国时期，在经历过&ldquo;百家争鸣&rdquo;后，必然是&ldquo;天下一统&rdquo;。随着游戏巨头和互联网大亨对网页游戏的逐渐重视，以及政府的介入，还有最早领跑某些领域的创业公司不断壮大，相信在不久的将来，网页游戏领域也会出现几个真正的领袖。别的领域不敢说，在我们儿童市场这块儿，淘米公司已经逐渐呈现一家独大的趋势，不信的话，你可以随便找几个小学生问问，比如你父母辈亲戚朋友的孩子，问他们是否知道摩尔庄园和赛尔号，是否充值了，相信你会得到非常惊讶的答案。所以，2010年后，任何小作坊型的创业团队再想进入FLASH WEB GAME行业，都需要更加谨慎了！<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" /><strong>★创业型游戏公司面临的问题和困难</strong><br style="word-wrap: break-word; line-height: normal;" />&rarr;在正式进入FLASH WEB GAME的技术探讨前，我左思右想，还是觉得必须先说一下创业公司存在的问题和困难，为后面可能不太&ldquo;正规&rdquo;的做法找一个合适的&ldquo;理由&rdquo;。&mdash;&mdash;人不能太爱找客观理由，但也绝对不能为了避免&ldquo;找理由&rdquo;之嫌，而弃客观现实于不顾，毛爷爷曾告诫我们要懂得&ldquo;实事求是&rdquo;。<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" />&rarr;任何有过创业经验的技术团队和公司应该都知道，教科书那套从成功公司抽象出来的模式在创业初期几乎只能是神话一般的存在，相信没有几个公司能完全做到。当然那种千万级启动资金，有成功背景的新公司除外。像我们公司，一开始就4个人，前台和后台各一个人，如果我们两个都每天用一半时间考虑架构和写文档，我们的产品猴年马月也上不了线了，况且我们写了给谁看呢？在这个阶段最最重要的目标就是尽快把产品做出来，上线运营出一定效果，给产品更加明确的方向，给团队信心，然后尽最大努力去融资，以求下一阶段的发展。产品出不来，只靠一个idea和产品策划书就想找投资的时代早就一去不复返了。<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" />&rarr;我觉得一个创业公司最现实的发展观应该是这样的：<strong>初创阶段（技术导向型阶段）</strong>：这个阶段要一切以&ldquo;我们能做什么&rdquo;为基础，在财力、人力、经验都不足的情况下，找出我们的优势，&ldquo;把我们所擅长的做到最好&rdquo;是我们唯一的筹码，毕竟初创人员能走到一起，必然是有一定共识，在某方面有优势的。而&ldquo;我们能做什么&rdquo;，在初创阶段很大程度上就是指技术能做什么。没钱、没人还想把项目做的又快又好，绝对是痴心妄想。这个阶段就开始叫嚣&ldquo;市场主导产品&rdquo;，&ldquo;不看过程只看结果&rdquo;等口号，完全是不务实的态度，市场上最热门的产品你未必能开发出来，创业阶段，前途未卜，你不看过程看什么？<strong>发展阶段（人力导向型阶段）</strong>：假设我们顺利度过了第一阶段，公司开始有现金流或者找到了天使投资，我们就开始布置进一步的发展了，这个阶段招人将是公司的一个要务，招有创业精神的人，更要招我们需要和缺少的人。以前我们公司只有AS，于是游戏server只能用FMS，现在应该招一个C++ socket的人了；以前公司没有网页前端，网站都是原画和PHP代劳的，现在该弥补了；以前整个游戏都是架构师们设计并实现的，现在应该招一两个做模块打下手的人了。这个阶段虽然不适合大规模扩展人手，但在要害人力点上，也绝对不能抠门，我们公司就是吃亏在socket上，公司一直不肯招一个专业写server端的，一直让前端和PHP代劳，结果游戏同时在线人数一超过5000就会出各种离奇问题，最恐怖是大家都不清楚问题到底在哪里，只能大眼瞪小眼，这个时候老板就会臭骂公司这帮技术都是饭桶，这么多人还搞不定这个问题。老板不懂技术，说出这样的话无可厚非，但老板不听劝，死活不愿意招要害人员，这就是他的错了。总之这个阶段要以人力发展为核心，尽最大的努力把必要的人手配备齐。必须注意的是，这个阶段不适合空降部门领导，公司发展阶段，只有初创人员陪公司一路走来，最明白公司的问题，以及各种问题的根源。而空降的领导容易只看到问题，不明白为什么会有问题，有时候难免说出&ldquo;道理上很正确，但实际上不可行&rdquo;的话，而老板为了配合新领导树立威信，很多时候不得不偏向新领导，这样以来很容易打击到初创人员的积极性。更严重的是可能让初创人员看不到前途，创业的激情沦为打工的无味。这个阶段挖墙脚空降领导，希望他们能把公司制度正规化，希望他们拯救公司的做法可能适得其反！公司初创人员这时候应该依旧是公司的顶梁柱！<strong>成熟阶段（产品导向型阶段）</strong>：如果有幸过了前两个阶段，到了这个阶段的时候，公司应该已经实现了正向盈利，作为一个游戏公司，一旦靠自己实现盈利，相信各种投资机构肯定会主动找上门，千万美元的投资绝对不夸张，你将会为到底接受哪家的投资而烦恼。人力、财力、物力都不再是问题，产品研发和运营的经验也成熟了，这时候唯一要关注的就是市场，什么样的产品更被市场和用户接受，争取开发出更多更好的产品。产品要多样化，公司要规模化，要形成自己的产品链和平台，抓住更多的用户，开拓更多的盈利模式。这时候才是产品主导公司，才是从大公司挖人的时代。如果这些都做到了，当老板再次开会谈&ldquo;上市&rdquo;的问题时，每个人脸上将会笑容依旧，只不过初创阶段的笑容是那种开玩笑试的玩世不恭，而现在则是对未来的美好憧憬。<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" />&rarr;其实任何理论都是有前提的，牛顿定律也只是在低于光速的情况下才适用。公司发展的历程中，老板和员工肯定都会有其信仰和观念，都会用各种言辞来说服别人。但我相信没有那种理论和言辞是永远正确的，尤其是书上和大公司的那些所谓的成功经验更是要警惕，因为它们身上有太多的光环，一场本来可能很有价值的讨论，说不定就会被一句&ldquo;盛大就是这么做的&rdquo;给结束掉！所以在我们谈任何理论的时候，不妨看看公司现在所处的阶段，不妨时刻谨记毛爷爷的话，实事求是的看待自己。我们公司就曾屡次吃类似的亏，公司在第一阶段刚拿到天使投资，就想做第三阶段的事了，结果做了很多，一件也没做好，白白浪费了很多时间和大好机遇。其实当时老板用来说服人的理论也都是正确的，只不过不适合公司的实际发展情况而已。还有一点要强调的是，不管公司现在处于第几阶段，坚决不能全盘否定其它阶段的付出和努力以及很多不得不犯的&ldquo;错误&rdquo;。之所以强调这一点，也是我们公司曾踩过的雷区，当我们发展到第二阶段的时候，公司就开始忙着空降领导，然后这些领导对我们之前的做法开始逐一否定，把做后台的哥们儿说的一无是处，搞得团队气氛极不融洽，吵架红脸的情况经常发生。这就好比我党在经历了长征、抗战和解放战争的原始积累后，在最终发动三大战役攻打大城市时，指着毛爷爷的鼻子说：&ldquo;你以前那套只敢打农村，打的过就打，打不过就跑的逃跑主义路线完全是错误的！&rdquo;试想，如果党内空降领导都是这种态度的话，将会对我们党和战士们的积极性产生多大的打击！这种情况其实在长征途中就发生过，差点就葬送了党，好在遵义会议及时纠正了苏联空降回来的王明等人的左倾激进主义，挽救了党。而我们的公司，谁来挽救我们的公司呢！<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" /><strong>★FLASH WEB GAME的系统架构</strong><br style="word-wrap: break-word; line-height: normal;" />&rarr;我在这里把一款FLASH WEB GAME的架构分为三部分：系统架构、前端架构、后端架构。&ldquo;系统架构&rdquo;主要是指根据一款游戏的特点以及公司的实际情况选择合适的技术实现方案，主要包括美术方案，前端方案和后端方案；&ldquo;前端架构&rdquo;主要指FLASH前端的主程序以及模块划分；&ldquo;后端架构&rdquo;主要指即时通讯部分和数据库。这章先谈系统架构。<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" />&rarr;谈到架构，我不得不说，那些所谓的完美架构，能够一次架构好，永远不用改的说法只能是传说，或者技术人员忽悠老板的说法，对于创业公司更是如此。创业公司初创时期更多的时候需要在游泳中学会游泳，因为大家都没有经验，失败是最好的教科书。就算大家知道应该怎么做，很多时候条件也不允许。比如我们在一开始就知道应该自己写socket服务器，可就是没socket的人才，于是不得不先使用FMS+PHP。公司一开始的美术更精通FLASH一些，而且我们计划的是要做&ldquo;企鹅&rdquo;，于是我们选用矢量图。可后来随着公司产品定位的不断改变，我们的架构和解决方案也会不断调整，当达到一个临界点时，修改的代价已经超过重新开发，我们就不得不对架构进行&ldquo;重构&rdquo;了！这时候聪明的老板应该支持程序员们的意见，充分调动他们的积极性尽快改完，全公司应全力配合，尽快度过难关。而不明事理的老板肯定会每天抱怨程序员无能，搭出一个垃圾架构不能满足产品的持续快速发展，拖了产品和市场的后腿，给程序员造成很大的压力，积极性没了不说，在长期经验积累之后本来可能是一次非常好的机会能做出一个相对完美的架构，满足日后很长一段时间的需求变更，结果因为老板过分催促和施压，又烙下了许多隐患，而这些欠下的债，总有一天要还的，这一天来临之时，责任虽然可以完全由程序员承担，但整个公司都要为之付出代价！所以关键时刻程序员该坚持还是要坚持自己的观点，要尽量说服老板，程序员的社交能力在这个时候就凸显作用了，你要明白你不但是在对自己负责，也是对公司负责！另外，真的很希望天下的老板们都能明白一个道理：能够根据公司实际情况不断调整的程序员才是最可爱最辛苦的程序员，而不是那些什么都不管，上去就提一大堆要求，必须都满足他，他才愿意做的程序员。<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" />&rarr;就算时至今日，FLASH WEB GAME在国内发展差不多三年了，但我敢说FLASH WEB GAME还是没有什么行业标准的技术解决方案，尤其是前端，大家都是自成一派。在这个时候，让我们再次搬出那句老话：不管黑猫白猫，抓住老鼠的就是好猫。不过经过这几年的摸索，还是有一些规律可循的：<br style="word-wrap: break-word; line-height: normal;" />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;1，美术：如果游戏画面简单，色彩构成相对单一，场景内总体元件能控制在100个以下，则非常适合直接使用矢量图，画面各组成部分尽量拆分为能重用的独立元件。这样虽然牺牲了客户端的CPU，但能因为重用最大化而大大减少美术的工作量，也方便他们日后应对需求变更，比如某些元件的尺寸变动。在画面简单，元件又少的情况下，利用递归全元件位图缓存，拿少量内存还能换回大量CPU，找出这个平衡点，完全可以做出很好的用户体验。<br style="word-wrap: break-word; line-height: normal;" />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;可大部分时间，我们的游戏场景可能都非常炫，画面复杂，色彩鲜艳。使用矢量图的话，一方面不容易画出想要的效果和精细度，这时候使用矢量图反而增加了美术的工作量和难度；另一方面，使用矢量图还有可能导致客户端CPU严重飙升，超出普通客户端电脑的承受范围。这时候我们应当用位图做游戏背景，重用性不大的元件要尽量合并到背景位图里，减少位图总个数，一些简单的动画如果非要用FLASH做成矢量动画的话，也要尽量做成逐帧的，相信FLASH IDE玩的转的美术同志们应该知道怎么把一个渐变动画瞬间转换成逐帧动画。逐帧动画虽然会导致SWF文件体积增大，但相对于换回来的客户端CPU来说还是值得，这其实是牺牲了一些服务器带宽和用户等待时间，换回严重的客户端CPU超载。而如果你的动画非常复杂和精细，精细到只有AE等粒子特效软件才能表达的话，建议还是直接从AE里导出位图序列，在FLASH里弄成逐帧动画，太过复杂的动画绝对不能用FLASH直接做，不但很难做出想要的效果，而且复杂矢量图的SWF文件体积也会大大超过位图，有可能导致用户因为SWF文件加载时间过长，失去等待的耐心，这时候我们情愿牺牲美术的工作量和工作流程，换回想要的效果，减小SWF文件体积。还有一点要提醒的，时间轴动画不可见时，程序一定要记得将其stop掉，不像程序动画，时间轴动画不可见时，FP内部其实依旧在重绘，对CPU还是有影响的。<br style="word-wrap: break-word; line-height: normal;" />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;还有一种极端情况是场景元件超标，比如整个游戏内所有元素（包括各种MC、BTN、位图以及程序创建的displayObject，总量超过500，这时候你会发现，画面静止还好，但只要游戏上鼠标随便一晃，或者有几个人物随便走一下路，CPU都会狂飙，就算这500个元件都是位图也无济于事。其实这是FLASH的一个瓶颈所在，是目前所有FLASH大型项目都有可能碰到的问题，也是我觉得阻碍FLASH进一步发展的主要障碍之一。在一个元件超多的背景图上进行任何的鼠标动作、动画、文本渲染，都会导致CPU严重飙升，甚至画面很卡。要解决这个问题，本质的也是唯一的方案就是减少元件数量，要想尽一切办法降到200以下。而这需要美术、前端和策划通力合作才行，绝对不是前端程序员就能搞定的事。策划要从产品的角度上看能不能简化目前场景同一时间出现的元素，美术要把能合并成一张图的元件在绘图软件中合并成一张位图，前端AS程序要把不需要响应鼠标事件的元件的mouseEnable和mouseChildren都设置成false，一些能利用copyPixels合并的位图就合并成一张，比如可以平铺创建的房间地板和墙面，要copyPixels成一张图，而不是new出好几百个元件。<br style="word-wrap: break-word; line-height: normal;" />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;其实元件超标的情况是大多数没有经验的团队很容易发生的问题，这时候前端程序员要起到领头羊的作用，给大家讲明白道理，用事实让大家信服，组织大家一起把事情做的更好，而不是一味的在那里抱怨FP效率低。因为这时候你是团队唯一可以依靠的人，如果这个问题解决不了，虽然大家都有责任，但前端毫无疑问是罪魁祸首！<br style="word-wrap: break-word; line-height: normal;" />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;极端情况下的极端解决方案：如果游戏策划的非常酷，一个子弹爆炸效果就需要几十个元件支撑，画面上同时又需要几十个坦克混战，这时候常规的解决方案是根本达不到的，但不是说就一定无法做了，你可以利用强大的BitmapData类把每帧要显示的游戏画面完全计算好并且在内存中绘制，然后以一张图的方式渲染给用户，这时候用户玩你的游戏仿佛就像在看逐帧的动画，此时FP占用的CPU大部分都是计算耗用的，而不是渲染耗用的。其实AS的执行效率远远高于屏幕渲染，你把CPU的主要负荷转移给AS，反而能做更多更炫的事情。据我的初步研究，前段时间名噪一时的FLASH版3D雷神，还有现在很多国外效率高的&ldquo;有点假&rdquo;的TD类和飞机类单机游戏都是这么做的。可这种模式适合用来做多人联机并且有大量交互界面的FLASH WEB GAME么？我初步思考了一下，感觉是不可能的。首先，大量的交互界面意味着需要用鼠标点击，试想在一个逐帧动画中，每帧都要响应鼠标是什么概念？所以UI部分首先排除了；然后是大量的即时数据交互，每当一个异步的请求得到响应，画面就需要做出相应的改变，这将对本来还可能比较工整的内部绘制算法制造非常大的麻烦，难度太高！基本上也不可行；最后是很多FLASH WEB GAME的画面重用性并不是很高，比如像我们游戏的每个场景都是美术专门画的，而不是用地图编辑器编辑的，这就意味着你无法完全用程序拼出一个场景来；综上我觉得一个款FLASH WEB GAME基本不可能完全使用copyPixels完成，最多是部分实现，比如我上面说的墙面和地板。除非你的游戏策划很NB，知道什么游戏能最大限度的利用copyPixels，而这样的策划估计本身肯定也是个前端程序员。<br style="word-wrap: break-word; line-height: normal;" />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;2，前端：从系统架构的角度上讲，前端其实很简单。现在WEB GAME主流的前端技术无非就是AS和JS。JS的前端地位其实比AS要老，很多人的JS经过这么长时间的磨练，功力深厚，做一个策略类甚至简单的MMORPG都没问题。但现在用AS来做的话可能更简单，更容易做出更酷的效果和更好的用户体验。所以最近两三年，随着基于面向对象的AS3逐渐完善和普及，FLASH WEB GAME似乎逐渐成了唯一的主流。<br style="word-wrap: break-word; line-height: normal;" />其实除了as和js外，还有很多前端技术可以供我们选择，比如shockwave，java，还有那传说中的flash killer：silverlight和html5等等。每种技术都有其优劣势，比如shockwave在图形渲染方面比flash强了千百倍啊千百倍，因为它可以完全调用显卡，我在网页上玩过一个基于shockwave的CS，流畅度和操作感完全不亚于桌面版的CS，还有国外的哈宝以及国内的娜娜米米都是基于shockwave的。而Java和silverlight也都有强大的背景，HTML5最近也是来势汹汹。但不管怎么样，2010年，FLASH仍以其广泛的覆盖率、酷炫的效果和逐渐成熟的开发社区，以最高的综合评分独领WEB GAME业界风骚。所以任何公司和团队，如果现在想做WEB GAME的话，如果实际情况允许，FLASH还是最好的选择。<br style="word-wrap: break-word; line-height: normal;" />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;3，后端：后端不是我的强项，我就不多说了，我只根据我们公司的经验谈谈心得。我同意前后端编程有很大区别，但绝不同意前后端谁简单谁复杂之说。根据我这几年的观察，我发现，前端偏重的是效果，是用户体验和细节处理，有时候可能还要涉及一些图形算法；而后端则偏重数据结构和数据处理，讲究的是性能、安全和扩展性。前端工作量一般比后端大，而后端需要的工作经验比前端多，想依靠一个只掌握了理论知识的大学毕业生就支撑一个公司的后端架构是严重不靠谱的！前端架构师必须是一个编程高手，十几、几十万行代码要在他的手里安排的井然有序，后端架构师则必须有过大型项目经验，并且项目同时在线人数达到过一定规模。前端架构出现问题，会严重拖垮开发周期，而后端架构一旦出现问题，对公司将是致命性打击。所以在公司里宣传所谓前端重要还是后端重要的说法，是完全错误的，任何一款好的产品，必将是策划、美术、前端、后端都达标的产品，缺失任何一块儿，都成功不了！不同部门之间的比较和较真儿没有任何正面影响！<br style="word-wrap: break-word; line-height: normal;" />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;至于后端的技术解决方案，我感觉如果是需要大量即时交互，并且对即时性要求很高的游戏，就必须使用socket服务器。而如果对即时性要求不高，完全可以用PHP，部分的即时交互可以用socket实现或者HTTP轮询也可以。如果你的公司也像我们一样刚开始没有合适的C或者JAVA socket程序员，选择fms和sfs也未尝不可，这样至少可以让前端人员代劳，让项目可以启动。切记这只是为解燃眉之急的下下策，长久不了，公司要想办法尽快找到一个合适的人，在合适的时机重构。<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" /><strong>★FLASH WEB GAME的前端架构与人事分工</strong><br style="word-wrap: break-word; line-height: normal;" />&rarr;前端的主程序架构和模块划分与人手和人事分工是紧密联系在一起的，而这些很大程度上又是由项目本身决定的。纵观现在国内绝大多数FLASH WEB GAME的规模和难度，我觉得前端AS人员大概需要2-7个之间，主程序有效代码一般不会超过10W行。在这种情况下，人事分工应当以功能和模块进行划分，尽量避免多人维护同一份代码，每个人各司其职，减少维护和协作的成本。这种模式非常适合人手不够，制度不健全，而且追求效率的初创公司。<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" />&rarr;根据各种游戏类型的不同，分工也应该不同。策略类更注重界面开发，分工上应该向UI偏重，MMORPG类注重主架构一些，而像我们的海底世界，是更新驱动类社区游戏，每周都要发布新内容，还需要大量的小游戏和场景功能支撑，所以需要更多的模块和小游戏程序员。<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" />&rarr;下面就以我们公司为例详细谈一下，我们公司最多的时候，一共5个AS程序员，分工是这样的：1个主架构，1个主UI,1个小游戏，2个场景和模块程序员。主架构同时负责FMS的sever端；主UI同时负责前端人员管理和文件管理；小游戏人员以平均每月两个单机或者联机游戏的速度循环不停开发，是相对最独立的一部分；而两个模块程序员，负责每周发布的新场景和新模块功能，他们的工作量其实蛮大的。<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" />&rarr;先谈前端主架构，前端程序主架构有两个主要任务：1，要从架构高度合理划分前端各模块，提出可行的实现方案；2，从AS级别搭建程序架构（非文档级别），制定前端编程规则和接口，规范程序各部分的职责划分。这两个任务其实包括很多具体工作，比如：游戏启动流程制定，确定哪些SWF文件需要外部加载，那些功能可以从主程序剥离出去单独实现，前端配置文件怎么处理，公共素材怎么处理，MVC三层怎么划分，主程序框架的选定，主程序怎么和后台通讯，主程序如何与模块协作，哪些代码应该放在主程序中，哪些代码应该放在模块里，主程序如何既能提供模块所需要的一切功能和数据，同时又相对模块自我保护等等等等。其实我谈的还只是一些大的方面，具体到实现的级别，还有大量细节工作要做。而这些工作在项目启动之初都是非常重要的，直接影响到项目中后期的开发和维护效率。<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" />&rarr;上面提到的那些点，我不可能全讲一遍，不然就不叫&ldquo;浅谈FLASH WEB GAME&rdquo;了！我只挑两个比较核心的内容跟大家略做探讨，就是前端AS框架和模块划分的问题。先谈前端框架：现在市面上流行很多前端框架，不管是针对&ldquo;FLASH&rdquo;的，&ldquo;FLEX&rdquo;的还是&ldquo;通用的&rdquo;都有。我们是否一定需要框架，或者必须使用某个框架，这完全是仁者见仁智者见智的事，从最终的结果上讲，争论这个问题意义不大，我相信一个5W行左右的项目，任何有5年以上编程经验的人，不管用什么作战策略，最终都能攻下山头，把项目做出来。但有一点至关重要：你必须能完全把握你的架构和你使用的框架，并能跟你的前端同事解释清楚。那好坏架构的区别在哪里呢？区别在于好的架构在开发过程中会更轻松，你不用天天担心的你代码，不用每天不停的写文档，以防止自己忘了复杂的逻辑，你可以在任何时间开始写代码，在任何时间去玩会儿游戏然后回来接着写；区别在于好的架构更符合业界标准，更容易被传统和正统的程序员接受理解；区别在于你可以用很简单的几句话就把你的架构思想描述清楚，用几个很简单的文档就能让别人接手你的代码，在人事变动和工作交接的时候让自己更轻松；区别在于当你掌握了一种通用框架或者自己总结一套成熟的架构后，你几乎可以套用以后的大部分项目，并不断完善它，开发越来越轻松，速度却越来越快！<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" />&rarr;我们的项目，主程序使用的是pureMVC框架，而主UI部分是自己写的。主程序和主UI相互独立，可以单独编译测试。主程序是纯代码，用FLEX SDK编译，而主UI则是界面和AS混写并用FLASH编译。这样就把MVC中的V从物理层面上完全独立了。pureMVC框架正如其名字，是一款&ldquo;纯粹&rdquo;的MVC框架，在我看来，他只是帮我们实现了MVC的编程思想和套路，其它多余的功能一点没有，这使它具有更高的通用性，也是它最可爱的地方。根据我们的经验，pureMVC单核心版就已经完全可以应对主程序有效代码在10W行以下的项目了。但在我跟很多没有用过框架的前端朋友聊天中，发现他们对这些框架本身就有抵触心理，或者有些对MVC模式都理解的不深刻，用起MVC框架又怎能得心应手？还有一些更过分的朋友把自己的问题也归结到框架上，说什么用了pureMVC框架后，自己的项目编译一下要十几分钟，我听了之后哭笑不得，项目编译慢一般是因为没有合理划分模块导致主程序过大才导致的，跟框架有什么关系？如果因为大家的种种误解和这些人的言论而导致一些新人错过学习这么一款优秀的框架，我觉得实为憾事！<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;pureMVC既然是一种MVC框架，这就意味着你首先要熟悉MVC。这种熟悉绝对不是对MVC的直译：模型、视图、控制器，而是要真正理解为什么要把程序划分成这几部分，在划分主程序模块时，要时刻能站在MVC的角度考虑问题，而当面对一段实际的代码时，能快速准确的判断，这段代码应该放在MVC中的哪部分。《pureMVC最佳实践》这份短短几十页的文档中，可以说处处闪烁着MVC的思想火花，不但清楚地阐述了怎么使用框架，而且时刻从MVC的角度告诉我们应该把哪些逻辑放在哪些部分中，应该注意什么问题。这个文档早已经有中文版，有兴趣的朋友可以自己去看看，文中有的，我这里就不赘述了。我只结合自己的体验谈一些文中可能没有涉及的，也是在真正开发中才会碰到的问题。<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;1，模型部分在实际开发中除了存储数据，还有其他作用么？是的，其实它的实际职责非常多。它要给Command和Mediator提供接口，响应用户操作，进行数据操作或者请求远程数据服务，进行数据的序列化和反序列化，得到异步数据后可能还要检查数据合法化。但不管怎么样，它始终是在和数据打交道，同时也应该是你的主程序中唯一可以直接和数据打交道的管道，别的部分要想和数据有接触，首先要问问它同意不同意。模型处理完数据会以Notification的消息方式通知Command或者Mediator。但绝对不能在Proxy中直接调用Mediator，这是为了保证数据层的独立性、可移植性和重用性，也简化了你的架构思想。不过可移植性这个优势，估计很多搞FLASH WEB GAME的朋友暂时都没啥机会体验，呵呵。<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;2，Command，Command，Command！连叫三声&ldquo;Command&rdquo;，希望可以引起大家的注意。因为Command的使用，在很大程度上反映着你对pureMVC框架的理解，甚至是对MVC模式的理解深度。在pureMVC框架中，各部分通讯是用Notification消息，Proxy可以给Command和Mediator发消息，Command可以给Command和Mediator发消息，Mediator可以给Command和Mediator发消息，怎么样？你现在是不是点晕了，这是正常的，其实我也有点晕！当你代码写到一定规模后，你会更晕。其实pureMVC框架这么设计本来是为了让MVC各部分尽量脱耦，但这带来一个负面情况就是消息发送与接收机制设计的太灵活了，灵活对小项目是好事，但对大项目来说，往往意味着混乱，甚至会导致灾难。那怎么办呢？只能靠我们的自觉性自我约束，简化架构思想了。根据《pureMVC最佳实践》中的建议，我的做法是这样的，尽量使用Command，让Command成为Mediator与Proxy之间通讯的唯一桥梁，Mediator和Proxy中发出的Notification，接收者一定是某个Command，然后再由Command处理并将结果转发给真正的消息接收者，Command就算仅仅起一个转发作用，仅仅有不到10行代码，也要创建一个Command类。这样不仅使你的架构更加清晰，而且也更符合MVC思想，Command类的大量存在还使你架构的业务逻辑具有了更好的封装性和扩展性，可谓是一箭三雕，何乐而不为？唯一的负面影响可能是你需要创建和维护更多的Command类文件，但相对于优势而言，这点影响不算啥。<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;3，我知道现在可能还有一些朋友在用FLASH IDE写代码，这些朋友的执着让人钦佩，但我想任何一个熟练使用过FLEX BUDIER、FD或者FDT的朋友，都绝不会再回头使用FLASH IDE写代码了。&mdash;&mdash;不对啊？不是谈pureMVC的么？怎么扯到IDE上去了？这是因为我现在要讨论的问题就和IDE有关，假如你现在用的还是FLASH IDE的话，除了随时写文档外，我真的很难想出一个很好的方案可以让你在没文档支撑的情况下，轻松掌握和随时维护几万行代码。可如果你使用的是FDT,就可以在没有文档的情况下，利用&ldquo;ctrl + r&rdquo;和&ldquo;ctrl + 鼠标左键&rdquo;，以及全文件搜索等工具，瞬间搞清楚代码之间的联系和逻辑，找出要修改的地方。OK，终于到pureMVC了。如果你使用的是FDT,并且开始尝试使用pureMVC框架，可在使用的过程中，你发现你在写主程序时，还是不停的使用&ldquo;ctrl + 鼠标左键&rdquo;，而不是&ldquo;ctrl + r&rdquo;，这说明你必须重新审视你对pureMVC框架的理解了，请审查你的Mediator类，看里面是不是充斥着大量的public方法，如果你的对象之间依旧是通过public方法进行引用，而不是通过Notification通讯的，那你也没有必要继续使用pureMVC框架了。<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;4，单例模式影响到底有多大？pureMVC是一个完全依赖单例模式的框架。单例模式似乎在AS界一直有很大争议，这样的话，pureMVC肯定也会有相应的争议了。持反对意见的人，大多集中在&ldquo;性能&rdquo;和&ldquo;团队协作&rdquo;方面，他们认为一个单例持有过多引用会带来性能问题，而且生怕在团队协作中自己的单例类被人无意修改，引发离奇的BUG。性能方面，我之前也没做过10W以上的项目，不敢妄言，但10W行以下的项目，绝对没有问题，如果你两三万行的架构就开始碰到主架构性能问题，估计十有八九是自己的代码写的有问题；团队协作方面，我觉得pureMVC的Fa&ccedil;ade模式是非常灵活好用的，大家可以略做讨论，制定一个简单的规则，比如模块只能通过fa&ccedil;ade获取数据和发送Notification，不能直接调用主程序其他CLASS，只要架构程序员不犯错，模块程序员甚至连犯错的机会都没有，如果他们有，还是你的架构思路有问题，请继续审视自己的代码。反正单例模式的问题到底是什么，我到现在也没完全搞懂，主要是我们的项目没碰到过此类问题，希望碰到过的朋友能再仔细跟火山说说，我也好弄清楚问题到底出在哪里了，自己以后可以更好的避免此类问题发生。<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;额，框架部分先谈上面4点吧，赶快进入下一个话题，模块划分：模块划分主要包括&ldquo;核心模块划分&rdquo;和&ldquo;子模块划分&rdquo;。核心模块的划分思路是这样的：它们是游戏启动所必须的，相互之间是紧密联系的，还要经常的被子模块调用；而相对的，子模块的划分思路是：他们在游戏启动过程中不是必须的，可以在游戏过程中再加载，子模块相互之间基本上完全没有联系，一个子模块的增加和删除不会影响到任何其他子模块，子模块可能需要调用主程序的接口或者获得主程序的数据，但主程序绝对不应该依赖某个子模块。<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;明确了模块划分思路再具体看看哪些部分应该划分为核心模块，哪些部分应该划分为子模块。一般情况下，核心模块按照游戏启动顺序包括：一个壳子SWF &rarr; 配置文件包 &rarr; 登录注册SWF &rarr; 主程序SWF &rarr; 主UI的SWF &rarr; 公共素材包。而子模块相对来说简单很多，比如具体的某个小游戏，某个场景，以及某个场景里的触发功能等等。下面我对核心模块逐一略做解释。&ldquo;一个壳子SWF&rdquo;：这是一个体积很小，但意义很大的SWF；它后面总是跟着随机变量，确保每次用户加载的都是最新的；它里面定义着一些需要经常更新而且每次更新都必须保证用户也在第一时间就得到最新值的变量；它里面最好有一个简单背景图，保证用户在超低网速的时候输入游戏网址不至于长时间面对一片空白；它里面有安全策略的设定，是我们游戏和很多第三方平台合作的基石；它里面还定义着主程序被加载进来之前的游戏启动流程等等。&ldquo;配置文件包&rdquo;：核心模块版本号啊，全局文字说明啊，service接口定义啊，各个核心模块需要的配置信息啊什么的，一般是一些XML文件。&ldquo;登录注册SWF&rdquo;：这个简单，在加载重量级的SWF前，先加载登录注册SWF,可以保证用户第一时间就能打开登录注册界面，而且可以有效节省服务器带宽。&ldquo;主程序SWF&rdquo;：这个就是我前面费了好大劲讲的主程序部分了。&ldquo;主UI&rdquo;：主程序和主UI为什么要分开两个SWF，我前面已经提过了，后面还有说明，这里暂时不讲。&ldquo;公共素材包&rdquo;：公共素材包是一个游戏不可缺少，但也不能过分依赖的东西。它包括一些全局的道具和效果，比如表情、技能特效、场景传送门等等。公共素材包里面最好就是一些简单的动画，体积小功能简单，严禁在公共素材包里添加上百K的东西，或者代码上百行的小模块，公共素材包建议500K以下。<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;看了上面的讲解，你可以能觉得核心模块分那么多，太麻烦了。不错，在我看来，对SWF加载流程的分解和控制，对异步程序的掌控正是衡量一个AS程序员是否经验丰富，是否足够老道的重要指标，很多从其它语言转到AS并有多年编程经验的朋友，架构方面可能和AS程序员差不多，甚至比很多自学成才的AS程序员做的更好，但这方面往往不如长期与CPU和SWF体积搏斗的老牌AS程序员。核心模块划分的越合理，用户体验往往越好，后期编写和维护代码的效率会越高，但在前期会比较麻烦，而且对架构师的架构经验和能力必须提出更高的要求。什么都不分，主程序、素材、核心模块都弄在一个SWF里，用户一开始必须先下载完这个SWF,或者弄了一堆核心模块和超多公共素材，用户一开始必须面对loading条不停的周而复始，必须等所有核心要素全部加载完成才能进行一些基本操作的做法，从架构角度上讲，是最简单的做法，因为不用过多考虑复杂的异步和SWF拆分问题，但从用户体验和长远的开发维护上讲是非常不利的。根据我们的经验，用户登录前加载的所有资源体积应该控制在200K左右，而用户进入游戏主场景前，加载的资源总数应该控制在1M左右。还有前面提到过的那位用了pureMVC后项目编译一下要十几分钟的朋友，估计就是把所有东西都弄到一个SWF里的做法。主程序随便改动测试一下，就要十几分钟，牵一发而动全身，开发效率从何谈起？根据我们的经验，任何主程序、核心模块还有子模块的编译，都必须在10秒以内，这才是合理的&mdash;&mdash;我的机器是07年花了3000多买的戴尔品牌机。<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" />&rarr;谈完主架构，接着谈主UI。主UI一般指主要的人机交互界面，这里的主UI区分于主架构中的mediator，当你看过pureMVC文档后，你就知道了，mediator只不过起到一个真正的V和pureMVC框架之间的桥梁作用，pureMVC里的mediator其实并不实现什么功能，真正的功能都是在主UI里实现的。但主UI又不得不算是主程序的组成部分，因为它不像其他模块，基本上只需要调用主程序的接口就行了，本身并不需要对主程序提供接口。而主UI作为用户操作界面，必须大量的向主程序的mediator提供接口，或者发送events。所以主程序和主UI之间的配合必须非常密切才行。<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;不同的游戏类型，可以选择的UI解决方案也不同。策略类非常适合用FLEX；MMORPG这类标准网游，非常适合用ASWING；而像我们海底世界这类游戏界面非常夸张，没什么标准规则，又不是太复杂的界面，还是适合自己开发。相信任何有过游戏项目经验的人都应该能理解，UI也是FLASH开发中的重头戏，很多细节的处理非常麻烦，在项目早期具有很大的工作量。还是以我们的项目为例，我们的UI架构思路是这样的：<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;1，所有的界面组件都是直接拖放在stage上的，其功能代码大部分都是在发布时编译的，基本上不用new的方式。这种方式的好处是方便编辑界面，从总体上直观的把握所有的UI，减轻程序运行时的负担，同时避免addToStage带来的诸多问题。缺点是，当UI膨胀到一定规模时，可能会需要你有一台配置比较好的电脑&mdash;&mdash;哎，说到这里我就伤心啊，我那台玩魔兽效果全关还卡的电脑，一直陪伴我的整个UI开发历程。<br style="word-wrap: break-word; line-height: normal;" />&nbsp; &nbsp;&nbsp;<br style="word-wrap: break-word; line-height: normal;" />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;2，UI的FLA层次结构是这样的：第一层是文档类或者与UI主类关联的某个MC，我们选用的是MC的方式,因为MC的方式更灵活；第二层是这个MC里的所有组件，这些组件大部分是根据功能划分在一起的一组元件，比如你的个人面板，而这个组件本身也是个MC；第三层是组件里的所有元件或者共用组件，元件就是背景啊，按钮啊什么的，而共用组件比如滚动条啊翻页组件啊什么的；主要的就这三层，其实那些共用组件MC再往里面双击还可以划分一层。对应FLA的层次结构，AS的结构如下：文档类或者主MC关联的类是第一层，这个类里持有所有的界面元件的引用；第二层是这些界面元件对应的组件CLASS,组件的功能都是在这里实现的，比如个人面板的MC将会对应一个MyPanel的CLASS,这个CLASS里实现MyPanel的所有功能。至于CLASS和元件之间是怎么对应的，我用的是一种松耦合的代理模式，也就是将MyPanel对应的MC作为参数传递给MyPanel这个CLASS,而这个CLASS会有自己的私有变量记录对应MC里需要进行操作的元件，具体到功能实现时，从代码层面上看，就好像CLASS操作的都是自己的私有变量，而不是直接操作界面元件，这样，当界面元件修改名字时，CLASS的改动很小。而且这种代理模式可以实现一个CLASS代理不同的元件，当界面只是需要修改外观，不需要修改功能时，非常方便。那么这些CLASS是在哪里初始化并获得它要代理的MC呢？正是在主MC对应的UI主类中，比如当获得MyPanel对应的MC后，就会立刻public var myPanel:MyPanel = new MyPanel(myPanel_mc);当所有的组件注册完成后，这个UI主类就持有了所有组件的引用，可以方便主程序调用；代码的第三层其实就是共用组件，比较特殊的是，我的共用组件，比如滚动条，也是用代理模式写的。<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;3，完全代理模式为我们创造了一种可能，就是把UI和UI对应的代码分开编译。这跟FLEX的皮肤更换机制有异曲同工之妙，只不过它的组件是要new出来的，布局是要代码控制的，皮肤都是一个个CLASS，整体效果一般都要编译后才能看出来；而我的组件是直接拖到舞台上的，布局大部分是直接在FLASH IDE里手动布置好的，皮肤都是一个个命名过的MC，整体效果编译之前基本上就能看出来。FLEX在更换皮肤的时候，CLASS名绝对不能变，而我的UI在更换皮肤时，MC的名字和层次结构不能变。FLEX关联皮肤是在编译时完成的，而我的UI关联皮肤是在运行时，当启动程序加载完UI代码的SWF和皮肤的SWF后，动态指定的。把皮肤和功能代码分开编译成两个SWF有个好处，就是在实际开发过程中，我们会碰到有时候只需要修改代码，而有时候只需要修改界面的情况，当然，就算你把代码和界面一起编译成一个SWF文件了，也完全可以对应这种情况，无非是编译一次的时间稍微长了一点点。可当你面对这样的情况呢：某次游戏版本更新出现状况，需要你目前功能不变，但画面必须退回到上一个版本。这时候你傻眼了吧？你开始对策划们咆哮：&ldquo;你们能不能想想好再让我们做啊？&rdquo;但你还是不得不重新打开已经做好的UI,把里面最新的界面再修改回老版本，同时还不敢把最新的删了，因为下一个版本估计马上又要替换回最新的画面了。可如果你的皮肤和代码是分开编译成两个SWF的，这种情况就简单了，你可以让运维从SVN上拉出上一个版本的皮肤SWF重新发布一下就好了，你所要做的只不过是动一下嘴皮。<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;4，最后谈一下UI的数据层吧，UI是否需要数据层呢？答案是肯定的。尽管你可以从主程序那里获得任何你想要的数据，尽管大部分时间你只是需要数据来显示一下而已，但UI自己记住某些数据会大大方便自己写代码。UI的数据层不需要主程序那么复杂，每个组件有自己的数据变量，然后整个UI再有一个存放公共数据的地方就足够了。<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" />&rarr;谈完主程序和主UI，最后再简单谈一下小游戏、场景和模块。先说小游戏吧，小游戏是相对最独立的一块，可能只需要主程序提供用户数据，并在游戏结束后将分数发送给主程序就行了。所以这部分从管理的角度上来讲是相对轻松的，但这不意味着小游戏开发就简单了，有时候，麻雀虽小五脏俱全，想开发出一个性能和用户体验俱佳的小游戏绝非朝夕之功，要是碰到一些算法复杂的小游戏，那就有得头痛了。其实对于海底世界这类儿童社区游戏，小游戏应该走创意和简单路线，搞得太复杂了，既不好开发，小孩子又不一定玩得来。<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;相对于小游戏，场景和模块就和主程序甚至是主UI关系密切了，但不管怎么密切，大部分时候它们都是在所要数据，发送事件，或者触发某个界面的显示与隐藏。如果某个模块的修改需要经常波及到主程序，或者很多模块在做同一件事，重复写着同一段代码，这时候就必须重新审视架构，看是不是某些地方架构的不合理了，不合理的地方，只要时机允许，一定要尽快改掉，绝对不能放任自流，一块儿小毒瘤最终可能引发癌症。模块和场景程序员在我们公司其实是非常累的，因为每周都需要发布新的版本，每次都很赶。在这种情况下，场景和模块程序员的责任心就非常重要，他们随便哪里随意了一下，会直接导致糟糕的用户体验，因为大部分时间，用户直接接触的东西都是他们的作品。架构写的再好，最终模块都做的很糟糕，对用户来说没有任何价值！所以，一个老道的，有责任心的，能够快速开发出优良用户体验的AS模块程序员，完全有理由拿高薪，因为他们能做到的，一些所谓的纯架构师未必做得到！</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.9em; margin-left: 0px; line-height: 19px; font-family: 'Microsoft YaHei', Georgia, serif; font-size: 14px; padding: 0px;"><strong>★前端与美术的配合</strong><br style="word-wrap: break-word; line-height: normal;" />&rarr;老闪客们应该都知道，FLASH这款软件在历史很长一段时间内都是用来做动画的，闪客和美术在这段时间内本就是同根生。后来随着第二版AS1和AS2逐渐完善，以及AS3的强势出炉，闪客们才逐渐分化成纯程序和纯美术两个阵营了。但不管怎么分，FLASH程序和美术之间的关系依旧非常亲密，一个优秀的AS程序员必然要比其它语言的程序员懂得更多美术方面的知识，至少也要能熟练操作FLASH IDE，并进行简单的图形处理。FLASH程序员与美术的合作大部分时间是由AS程序员主导的，主要表现在以下几个方面：<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;1，FLA文件管理：把有联系的美术素材放进一个FLA文件中统一管理，既能有效减少美术素材的数量，也方便程序员写程序。本来像这种美术素材管理应该是由美术负责的，但由于这些美术素材大部分时间可能也需要程序员写程序，美术和程序需要共享这些素材，虽然我们可以用SVN进行共享和版本控制，但程序员和美术还是要靠约定才能非常默契的知道什么时间该到什么地方找什么文件。而这个约定就什么我们程序员应该制定的，因为据我观察，程序员在条理性和制定规则方面一般比美术更靠谱。以我们公司为例，文件管理基本上都是由我负责的，我把需要多个美术和程序员共同维护的部分以项目名命名成一个文件夹，项目下如果需要还可以进行子分类，分类规则也是我制定。而大部分的子模块可能只需要一个美术加一个程序员就搞定了，这时候美术就把素材放到以自己英文名命名的文件夹下，至于他们的文件夹内如何分类，我会给出意见，但并不强制管理。模块程序员也会都有以自己英文名命名的文件夹，他们会把美术的纯FLA素材拷贝到自己的文件夹下，并根据模块进行子分类，然后写代码并发布SWF，至于SWF文件如何管理，我会在下一节中讨论。其实我的管理目标非常简单，我只需要所有的美术和程序员能在任何时候瞬间找到我们需要的素材和源代码所在地，并且把需要的版本调出来。只要这个目标还在可控范围内，我就会给所有员工最大的自由性，把自己从管理里解脱出来，把更多的时间投入开发，毕竟对于创业型公司而言，快速开发，让老板和市场看到产品才是主旋律，管理只需要在必要的时候强势出手就可以了。事实上，我们公司的文件管理，我每隔半年才会强势管理一次，用大概一周的时间重新规范规则，其它时间基本处于放任自流状态，但从没出过什么大问题。最后给大家一个数字，我们公司经过将近三年的积累，已经有几十个G，上万个美术素材了。<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;2，SWF文件管理：SWF文件一般是由前端程序员发布并管理的，不过也有一些SWF可能不需要些代码，比如家具、个人面板背景等等，这些可以直接由美术管理，管理方案和FLA文件管理差不多。最大的不同就是，SWF文件最终的发布路径是内网模拟测试环境，而不是本机。像我们这样的更新驱动游戏，不可能为每一个模块都单独搭建拟真测试环境，如果这样的话，可能我们测试环境还没搭好，就该上线并准备下一周的更新了，所以所有的模块最终的整合测试都是直接上内网测试环境进行。<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;3，FLA内元件的管理：这个问题相信很多AS程序员都碰到过，也都为此头痛过。美术给到程序员手里的FLA文件可能是混乱不堪，库里没有任何分类，元件名也都是清一色的&ldquo;元件1、元件2，元件3&hellip;&hellip;&rdquo;，元件内部遮罩，组合，层次也都没啥规律。要是美术直接给我一个AI或者PS的源文件让我们自己导入FLASH，那我们就更抽了，颜色模式的改变，路径工具的失灵，大量的图层导致裁切困难，而且还不能进行打散合并，只能一层一层的切。这个时候，正如我前面提到的，一个合格的AS程序员应该对美术和图形软件有更多的了解，你应当及时纠正美术不恰当的做法，甚至给出合理的解决方案，比如你应该知道FLASH只支持RGB颜色模式，AI不但整个文档可以指定颜色模式，每个图层也可以单独指定，当美术给到你的AI导入FLASH有色彩差异的时候，能帮助美术找到哪里的颜色模式不对，并建议他们以后只使用RGB模式。很多纯AS程序员可能有图形恐惧症，他们会想尽一切办法把这部分工作推向美术，但最终他们都会很郁闷，因为他们会发现，除了能指定库文件夹的命名规则外，其它的规则很难跟美术说明白，而且由于模块的千变万化，很难总结出一个完全通用的规则，想从美术哪里拿到一个完全不用修改，自己可以直接写代码的FLA文件，几乎天方夜谭。所以，与其让FLA文件在美术和程序的你来我往中浪费时间，与其让自己在对美术的鄙视中愤懑抱怨，不如提升一下自己的美术常识和图形处理基本功。毕竟，元件在舞台上怎么命名，关联什么类，层次怎么样，怎么被程序利用，这些只有我们程序员最清楚，这部分工作由我们程序员完成完全是合理的，也是效率最高的，美术只要把我们需要的素材交给我们，并放到方便查找的地方就可以了。放下程序员的架子，主动走入美术的世界，对我们程序员绝对有好处。<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;4，FP的性能问题对美术的影响：谈到这个问题，我就想起了一个让我抽搐已久的情况。我们老板总是喜欢语重心长的对我说：&ldquo;火山，你给咱们前端人员和美术出一个方案吧，告诉他们怎么做可以让FLASH性能最高！&rdquo;额，现在请问哪位朋友可以帮火山回答这个问题。火山真的惭愧，搞FLASH搞了7年了，始终还是没完全弄明白FLASH的诸多性能问题。不管以前的MM还是现在ADOBE，都将其图形处理和屏幕渲染部分视为其镇山之宝，不肯公开其技术内幕，我也就始终无法从理论的高度给出一个本质的回答。我现在的大多数性能解决方案，都是根据项目的实际情况，根据7年来的经验总结出的经验科学。而且我始终不相信，谁可以一个给出一个适合所有项目的、通用的性能解决方案，可以同时让内存、CPU、带宽占用都最少，而且画面又很炫，功能很强大，SWF文件非常小，可玩性非常高，而开发周期和成本却很少。内存、CPU、SWF体积、带宽、效果、成本，这几个要素往往是相互矛盾的，你对其中任何一点的过分优化，都有可能导致其它点走向反面。我深信，在目前这个时期，一个性能方面的高手，绝对不是看他能不能给出一个全面优化的方案，而是看他在面对不同的项目，不同的情况时，如何做出选择和取舍。是的，&ldquo;选择和取舍&rdquo;永远都是人生最艰难的话题：手心手背都是肉，削掉哪边呢？老婆孩子都掉海里了，救谁呢？在这样的情况下，我觉得一个负责的前端人员，反而不应该仅仅简单的扔给美术一份死的文档，告诉他们应该怎么做，让他们一直这么做就可以了。前端人员应该在每次面对一个实际情况时，都不厌其烦的跟美术讲清缘由，我们应该尽量授人以&ldquo;渔&rdquo;，而不授人以&ldquo;鱼&rdquo;，让他们明白选择的道理，而不是简单的告诉他们选择什么。相信只要是虚心学习的美术，经过一年半载的讲解他们就能替你做出判断了，这时候你再让他们去跟后来的美术讲，你就解脱了。很可惜，大部分不懂技术的老板可能觉得你是在故弄玄虚，非要你给出一份文档。无所谓了，你跟不懂技术的人争论不是自讨没趣么？老板更多时候是从管理的角度出发的，我们应该配合。我们也不是没什么可写，比如尽量减少元件数量啊，减小SWF体积啊，减少持续性动画啊，多做触发性动画啊，少用遮罩和滤镜啊，不要嵌入中文字体啊，提高元件重用性啊等等等等！这些建议听上去完全正确，忽悠不懂技术的人正合适。但其实在高端的开发中，这些理论都是废话，帮不上多大忙，因为地球人都知道了，我们碰到的问题肯定是超越这些技术点的高端问题！<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;综上可以看出，其实前端和美术的配合过程大部分时间是由前端主导的，这也是我前面一再强调前端要多懂一些美术知识的重要原因。当你可以和美术一起谈论美术理论，在美术的电脑上直接操作给他们看，当你从美术的角度给他们提出解决方案的时候，你往往会更容易被美术所接受。担负起主导前端与美术合作的责任，用你的智慧征服他们，用你的诚意打动他们，让美术与前端完美结合，让你的产品第一时间抓住用户！<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" /><strong>★前端与后端的配合</strong><br style="word-wrap: break-word; line-height: normal;" />&rarr;FLASH与后端通讯的手段多种多样，网上相关教程太多了，这里不再例举。但很多时候，创业团队由于受制于各种现实条件，可选择的方案并不多。像我们公司，刚开始基本上只能选择FMS+PHP+MYSQL。其实，对于我们前端来说，后端选择什么解决方案对我们的影响并不大，我们无非就是用的API不一样而已。多看看教程，用很少的时间我们就能掌握其要领。那么前后端合作的难点是什么呢？我觉得关键是逻辑的划分。<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" />&rarr;&ldquo;前后端合理划分逻辑&rdquo;，这句话咋看上去貌似简单，其实里面蕴含着诸多方面的考虑。比如安全性、后端性能、工作量、人事分工等等。安全性：记得我们的游戏同时在线超过3000的时候，就已经有人开始攻击我们的后端了，篡改了很多人的个人资料。幸亏攻击的人只是我们一个善意的玩家，如果是恶意的商业攻击，后果不堪设想。经过这次后，老板开始缠着我们追问&ldquo;怎么防止别人攻击，提高安全性&rdquo;。这个问题又一次把我们难住了，我们都知道，基于HTTP的请求不被截取是不可能的，而SWF文件又不存在绝对的安全。就算你防得了恶意进攻，你也防不了良性的外挂，想从技术层面让别人完全攻击不了我们也是不可能的。那我们是不是只能坐以待毙了？不是！如果前、后端在合作的时候，数据逻辑与合法性检查都是做在后端的，就可以很好的避免一些良性外挂。首先是游戏数据逻辑要尽量全做在后端，比如用户在玩小游戏的时候，我们不要只是在用户结束小游戏后，简单的把数据传回后端，后端记录进数据库完事，一旦攻击者发现了你这个传数据的后台接口，完全可以避开SWF，做外挂直接呼叫你这个接口刷分，就算你验证用户也没用，因为他可以先注册一个合法的用户，然后在外挂中登录再刷分。当然，你还可以对游戏分数先加密在传给后端，提高攻击难度，但这也是不保险的，因为加密算法就在你的SWF文件中，别人可以很容易获得。所以正确的做法应该是：游戏开始的时候只告知后端游戏ID&rarr;后端标识ID对应的游戏已经开始并记录开始时间&rarr;用户每次获得一个分数时，前端传回来的不是分数，而是一个动作ID,后端根据动作ID给用户加分&rarr;游戏结束时，前端告知后端游戏已经结束&rarr;后端得知游戏结束，记录结束时间，计算时间差，根据时间差和最后得分是否符合标准做出相应处理，如果符合标准就把最后得分入库，并返回前端显示给用户，如果不符合标准，就启动作弊处理系统。而这个标准一般是由数值策划给出的。经过我这么一分析，你可能头痛了，本来一个很简单的小游戏计分，怎么搞得这么复杂？前后端工作量都增加了不说，对后端性能也提出了更高的要求，服务器可能要增加了，后端人手可能要增加了，开发周期也要延长了，值得么？这个问题问的很好，这正是我下面要说的：后端性能、工作量、人事分工：一旦我们每一步进行安全性与合法性验证后，整个项目的工作量都会大大膨胀，开发周期也会大大延长；一旦我们把数据处理、业务逻辑和安全验证都移到后端时，后端的压力就会增加，服务器要增多，对后端人员的能力要求也会提高。很多初创团队在项目初期人力财力，软件硬件都不足，可能顾不上那么多，一心想着早点让项目上线。在这种情况下，我觉得安全性可以暂时放一下，众所周知的安全漏洞补上就可以了。但&ldquo;数据处理和业务逻辑&rdquo;这个，宁可开发的慢一点，宁可再招个后端高手，宁可多几台服务器成本，也要把它们尽量都放在后端。因为这个没分清的话，会影响到整个系统的清晰度，严重影响项目中后期的发展，为日后的重构增加难度和超多的工作量，我们还指望着在重构时加强安全性呢，到时候数据处理和业务逻辑还是要放后端！所以综合考虑，该出手时就出手，能省的不浪费，不能省的不要抠！<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" />&rarr;前面一节谈了前后端合作的难点。这里再简单的谈两个要点：<br style="word-wrap: break-word; line-height: normal;" />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;1，前端人员不要以前端的角度看后端：前端和后端有个本质的区别，就是前端的负荷是分担在每个客户端的，而服务端的负荷是集中在服务器上的。对于我们前端来说，一个功能多占了几K内存，SWF文件大了几K根本不是什么问题，可对后端来说就是很严重的问题了，一个人大几K，上千人就是几M了。服务器在连接数、内存和CPU之间会有微妙的平衡点，一旦这个平衡点被打破，随便再多哪怕一点点资源占用，整个服务器的性能都会严重下降，影响用户体验，当然，如果你有几十上百台冗余服务器供你负载平衡，你可以当我没说，可如果你像我们公司一样，一开始就3、5台服务器的话，就请前端人员一定要多多配合后端人员，帮他们省出每一个字节，每一次请求。比如像道具属性会有很多文字说明，这些说明应该以类似XML文件的方式储存为静态文件，后端返回给前端的道具数据包里只需要一串物品ID,前端就可以根据这些物品ID在XML文件里查询出这些道具对应的静态物品属性了。别看这些数据可能只有十几K，对后端来说意义重大。还是那句话，只要不是架构性问题，前端不要怕麻烦，要尽量配合后端提高性能。<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;2，前端后端要有很明显的BUG分界点。当一个BUG出现时，后端应当很快的用一种统一的方案证明数据没有问题！这个方案必须让前端知道，并让前端也可以操作。大家熟知的php remoting里有一个servicebrowser，这个东西就很好，它能罗列出所有PHP的接口，我们输入参数，它就返回结果，我们可以根据结果直接查看数据是否正确。&mdash;&mdash;确定数据的正确性，对前端DEBUG非常重要，而一个BUG的解决，一般都是由前端人员入手并进行定位的。<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" />&rarr;其实相对于前端和美术的合作，前端与后端的合作还是简单清晰的，前后端在开发的过程中，应该是非常独立的，后端开发完全可以先启动，把数据接口提前写好，等着与前端整合，而当整合过程发生问题时，又可以很快的界定是谁的问题。</p><img src="http://www.cnblogs.com/sun11086/aggbug/1674036.html?type=1" width="1" height="1" alt=""/><p>评论: 0　<a href="http://www.cnblogs.com/sun11086/archive/2010/02/26/1674036.html#pagedcomment" target="_blank">查看评论</a>　<a href="http://www.cnblogs.com/sun11086/archive/2010/02/26/1674036.html#commentform" target="_blank">发表评论</a></p><p><a href="http://job.cnblogs.com/" target="_blank">找优秀程序员，就在博客园</a></p><hr/><p>最新新闻：<br/>· <a href="http://news.cnblogs.com/n/59262/" target="_blank">甲骨文将关闭OpenSSO</a><span style="color:gray">(2010-03-20 23:54)</span><br/>· <a href="http://news.cnblogs.com/n/59261/" target="_blank">专访陈晓薇：九城已重建、我还没想好去哪</a><span style="color:gray">(2010-03-20 22:07)</span><br/>· <a href="http://news.cnblogs.com/n/59260/" target="_blank">[视频]社交媒体不仅仅是一时狂热</a><span style="color:gray">(2010-03-20 21:58)</span><br/>· <a href="http://news.cnblogs.com/n/59259/" target="_blank">Google开出首个1337美刀的Chrome bug奖励支票</a><span style="color:gray">(2010-03-20 21:47)</span><br/>· <a href="http://news.cnblogs.com/n/59258/" target="_blank">著名图像讨论网站4chan创始人披露4chan诞生历史</a><span style="color:gray">(2010-03-20 21:42)</span><br/></p><p>编辑推荐：<a href="http://news.cnblogs.com/n/59093/" target="_blank">[视频]想做你的Code</a><br/></p><p>网站导航：<a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/" target="_blank">个人主页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/group/" target="_blank">小组</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://kb.cnblogs.com" target="_blank">知识库</a></p>]]></description></item><item><title>淡扯旅游</title><link>http://www.cnblogs.com/sun11086/archive/2010/01/05/1639974.html</link><dc:creator>sungo</dc:creator><author>sungo</author><pubDate>Tue, 05 Jan 2010 15:02:00 GMT</pubDate><guid>http://www.cnblogs.com/sun11086/archive/2010/01/05/1639974.html</guid><description><![CDATA[<p>阅读: 9 评论: 0 作者: <a href="http://www.cnblogs.com/sun11086/" target="_blank">sungo</a> 发表于 2010-01-05 23:02 <a href="http://www.cnblogs.com/sun11086/archive/2010/01/05/1639974.html" target="_blank">原文链接</a></p><span class="Apple-style-span" style="font-family: Tahoma, Verdana, STHeiTi, simsun, sans-serif; color: #333333; "><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.8em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">这篇文儿是因为看到了一句话引起的......</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.8em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><h3 style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-size: 14px; "><strong style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">一</strong></h3><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.8em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">在我第一次看到&#8220;<strong style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">好的旅行是在适当的时间有适当的心情和适当的人一起出现在远方</strong>&#8221;这句话时， 我突然意识到旅行的快乐与否，其实和去的地点并不一定要有直接的关联，更多的是看什么时候和谁一起，这是为啥呢？这点老祖宗们早就想出来了：正所谓&#8220;天时不如地利，地利不如人和&#8221;。一共就三点占了&#8220;天时&#8221;和&#8220;人和&#8221;旅行当然没问题了。</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.8em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><strong style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">所以我了解到 旅行其实和地点没有直接的因果关系，天时和人和更重要</strong>（当然有地利那就更美了）</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.8em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><h3 style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-size: 14px; "><strong style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">二</strong></h3><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.8em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">电影《旅行的艺术》，大概讲的的是一个哥们因为婚姻剧变（别担心这个变化是发生在婚礼上）而出行旅游，结果不幸之事屡屡发生，以至于在两天后的一次打劫中只剩下了内裤...之后因为导演的安排...因为缘分结识了一对夫妇，他们和几个人正打算穿过一个极其艰难雨林来打破吉尼斯世界纪录，随后就和他们一起开始这次真正的旅行。这次旅行并不是一个很轻松的旅行。他们需要手动去探索一条路，期间夹杂着各种各样的困苦：连绵不绝的大雨，热带雨林的蚊虫，泥泞的道路，毒蛙毒蛇，迷路和意外事故以及由此带来的情绪低落。想想这些如果发生在我们旅行中简直是不可想象...最终这一伙人还是顺利的创造了世界纪录。这期间他们并不是靠充足旅行资金装备，更多的是一种看待事物的视角，我们通常叫做&#8220;幽默&#8221;。</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.8em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><strong style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">所以我猜测 如果能用一种特殊视角来旅行，那么会看到很多不同的东西。</strong></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.8em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><h3 style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-size: 14px; "><strong style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">三</strong></h3><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.8em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">怀着对旅行的崇高理想我又借了本书：《旅行的艺术》。这本书是通过作者&#8220;质感，细腻&#8221;的多篇散文向我们介绍了旅行的等级（太柔了，我只读前面两章和最后一章），当然作者并不是说旅行不好，他只是企图去告诉我们什么才是真正的旅游。</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.8em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">=========================下面写的很乱===================</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.8em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">我读到的大概意思是：</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.8em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">对于预期我们很容将旅游的预期理想化，而且旅游的感受很容易受到当时的情绪和自身价值观的影响。</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.8em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">对于收获，不管是异国情调事物，或是户外秀丽恬静的风光，又或是令人震惊的壮阔自然奇迹，如果想更好的体验旅游，就需要去怀着一颗好奇的心去观察，并且对某些特定的事物我们需要有一定背景知识。</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.8em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">对于观赏，文中有这样一句话：<strong style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&#8220;对于凡高来说，衡量每一个杰出的画家的标志就是他们能否更加清楚的让我们看到世界的某些部分&#8221;</strong></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.8em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">对于怎么样把旅途中的美留住，作者认为更应该是去学会绘画，因为这样可以让你学会观察和热爱大自然，而非占有式的留念。</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.8em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">最后在结尾比较有意思，作者讲了一个在家里旅行的人，书的最后半句话是这样说的：<strong style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">让我们在前往远方之前，先关注一下我们自己看到的东西。</strong></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.8em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">===========================分割线</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.8em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><strong style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><strong style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">所以</strong>我猜测&nbsp; 只有在生活中懂得观察的人，才会在人生的旅途中享受到更多风景的。</strong></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.8em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><h3 style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-size: 14px; "><strong style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">四</strong></h3><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.8em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">对于旅游我觉得应该分三类。</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.8em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">第一类：<strong style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">一个人</strong></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.8em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 一个人旅游是最锻炼观察能力和应变能力的，正如电影：《旅行的艺术》主角所说： &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 旅行的艺术就在于&#8220;出其不意&#8221;（The art of travel is to deviate from</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.8em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; one's plans）。这种自由，出其不意的感觉是另两类所不能体验的。</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.8em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">第二类：<strong style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">情侣</strong></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.8em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 说实话这方面没经验，但是觉得这方面对&#8220;地利&#8221;和物质方面要求比较高些。浪漫的爱 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;情也是另两类无法体验的。</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.8em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">第三类：<strong style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">n多人（n大于等于2）</strong></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.8em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 快乐是可以被分享的，一个完整的团体可以让你觉得无比的舒适,满足,并且充满激 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 情。毫无疑问这方面最需要的是&#8220;人和&#8221;。同样也是独一无二的。</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.8em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.8em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><strong style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">扯淡完毕...</strong></p></span><img src="http://www.cnblogs.com/sun11086/aggbug/1639974.html?type=1" width="1" height="1" alt=""/><p>评论: 0　<a href="http://www.cnblogs.com/sun11086/archive/2010/01/05/1639974.html#pagedcomment" target="_blank">查看评论</a>　<a href="http://www.cnblogs.com/sun11086/archive/2010/01/05/1639974.html#commentform" target="_blank">发表评论</a></p><p><a href="http://job.cnblogs.com/" target="_blank">找优秀程序员，就在博客园</a></p><hr/><p>最新新闻：<br/>· <a href="http://news.cnblogs.com/n/59262/" target="_blank">甲骨文将关闭OpenSSO</a><span style="color:gray">(2010-03-20 23:54)</span><br/>· <a href="http://news.cnblogs.com/n/59261/" target="_blank">专访陈晓薇：九城已重建、我还没想好去哪</a><span style="color:gray">(2010-03-20 22:07)</span><br/>· <a href="http://news.cnblogs.com/n/59260/" target="_blank">[视频]社交媒体不仅仅是一时狂热</a><span style="color:gray">(2010-03-20 21:58)</span><br/>· <a href="http://news.cnblogs.com/n/59259/" target="_blank">Google开出首个1337美刀的Chrome bug奖励支票</a><span style="color:gray">(2010-03-20 21:47)</span><br/>· <a href="http://news.cnblogs.com/n/59258/" target="_blank">著名图像讨论网站4chan创始人披露4chan诞生历史</a><span style="color:gray">(2010-03-20 21:42)</span><br/></p><p>编辑推荐：<a href="http://news.cnblogs.com/n/59093/" target="_blank">[视频]想做你的Code</a><br/></p><p>网站导航：<a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/" target="_blank">个人主页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/group/" target="_blank">小组</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://kb.cnblogs.com" target="_blank">知识库</a></p>]]></description></item><item><title>09那点事儿</title><link>http://www.cnblogs.com/sun11086/archive/2010/01/02/1638027.html</link><dc:creator>sungo</dc:creator><author>sungo</author><pubDate>Sat, 02 Jan 2010 14:13:00 GMT</pubDate><guid>http://www.cnblogs.com/sun11086/archive/2010/01/02/1638027.html</guid><description><![CDATA[<p>阅读: 23 评论: 2 作者: <a href="http://www.cnblogs.com/sun11086/" target="_blank">sungo</a> 发表于 2010-01-02 22:13 <a href="http://www.cnblogs.com/sun11086/archive/2010/01/02/1638027.html" target="_blank">原文链接</a></p><span class="Apple-style-span" style="font-family: Tahoma, Verdana, STHeiTi, simsun, sans-serif; font-size: 12px; line-height: normal; color: #333333; "><h3 class="title-article margin-top" style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.5em; padding-right: 0.3em; padding-bottom: 0.5em; padding-left: 0.5em; font-size: 12px; background-image: initial; background-repeat: initial; background-attachment: initial; -webkit-background-clip: initial; -webkit-background-origin: initial; background-color: #f7f7f7; border-top-width: 1px; border-top-style: solid; border-top-color: #cee1ee; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: #e3eef8; word-wrap: break-word; word-break: break-all; background-position: initial initial; "><strong style="margin-top: 0px; margin-right: 6em; margin-bottom: 5px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-size: 1.2em; word-break: break-all; display: block; overflow-x: hidden; overflow-y: hidden; "><span class="Apple-style-span" style="font-size: 19px; font-weight: normal; line-height: 27px; "><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-weight: bold; font-family: SimSun; ">1.</span><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-weight: bold; font-family: SimSun; ">伤离别</span></span></strong></h3><div id="blogContent" class="text-article" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 10px; padding-right: 5px; padding-bottom: 10px; padding-left: 5px; word-wrap: break-word; width: 580px; font-size: 14px !important; line-height: 1.5; "><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; text-align: justify; "><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-size: 10.5pt; font-family: SimSun; ">&nbsp;男人的故事就像女人的乳沟，挤一挤还是有的<span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-family: 'Times New Roman'; ">.</span></span></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; text-align: justify; ">&nbsp;</p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; text-align: justify; "><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-size: 10.5pt; font-family: SimSun; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;09<span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-family: SimSun; ">年记得在餐桌哥们说的那句话&#8220;你走了我这就没朋友了，到了那儿也没有朋友了&#8221;我们都安静</span><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-family: 'Times New Roman'; ">......</span><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-family: SimSun; ">爆发了</span><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-family: 'Times New Roman'; ">......</span><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-family: SimSun; ">伴随着&#8220;</span><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-family: 'Times New Roman'; ">Goodbye&nbsp;My&nbsp;Lover</span><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-family: SimSun; ">&#8221;的响起，带着还仅存的一个童话，彻底的和大学告别了。</span></span></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; text-align: justify; ">&nbsp;</p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; text-align: justify; "><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-size: 14pt; "><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-weight: bold; font-family: SimSun; ">2.</span><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-weight: bold; font-family: SimSun; ">出生牛犊</span></span></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 1pt; padding-right: 0pt; padding-bottom: 0pt; padding-left: 0pt; border-top-width: medium; border-top-style: none; border-top-color: initial; line-height: 15.75pt; "><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-size: 10.5pt; font-family: SimSun; ">&#8220;那一天我二十一岁，在我一生的黄金时代。我有好多奢望。我想爱，想吃，还想在一瞬间变成天上半明半暗的云。后来我才知道，生活就是个缓慢受锤的过程，人&nbsp;一天天老下去，奢望也一天天消失，最后变得像挨了锤的牛一样。可是我过二十一岁生日时没有预见到这一点。我觉得自己会永远生猛下去，什么也锤不了我。&#8221;<span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-family: 'Times New Roman'; ">---</span><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-family: SimSun; ">王小波</span></span></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; text-align: justify; ">&nbsp;</p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; text-align: justify; "><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-size: 10.5pt; font-family: SimSun; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;在家猫了将近两个月，非常幸运不久就找到了自己的第一份工作。开始疯狂的工作<span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-family: 'Times New Roman'; ">......</span></span></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; text-indent: 21pt; text-align: justify; "><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-size: 10.5pt; font-family: SimSun; ">&nbsp;伴随着时间汹涌的流逝，工作，钱，房<span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-family: 'Times New Roman'; ">...</span><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-family: SimSun; ">各种问题不知不觉间就溜进了大脑，突然觉得：生活的无比空虚和一种难以抑制的焦躁，就像一头被锤过的牛...</span></span></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; text-align: justify; "><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-size: 10.5pt; font-family: SimSun; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;一个朋友要去去外地工作，本来是要约哥几个一块吃顿饭，结果预订了两周这事儿还是泡汤了，这事儿其实挺小，但是我开始怀疑：你把我当好哥们吗？</span></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; text-indent: 21pt; text-align: justify; "><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-size: 10.5pt; font-family: SimSun; ">&nbsp;昨天和博聊天，突然让我冷静了下来<span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-family: 'Times New Roman'; ">.....</span><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-family: SimSun; ">焦躁，急功近利，索取</span><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-family: 'Times New Roman'; ">.....</span></span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.8em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; text-align: justify; "><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-size: 14pt; "><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-weight: bold; font-family: SimSun; ">3.<span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-family: SimSun; ">终章:</span></span><strong style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">亦假亦真？</strong></span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.8em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; text-align: justify; "><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-size: 10.5pt; font-family: SimSun; ">&nbsp;&nbsp;我<strong style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">一个人流离在繁华</strong>的街头，感受着<strong style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">风</strong>的温度，看着<strong style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">涌动的人群</strong>，</span></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; text-align: justify; "><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-size: 10.5pt; font-family: SimSun; ">&nbsp; 我<strong style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">停在了在了路口</strong>.....</span></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; text-align: justify; "><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-size: 10.5pt; font-family: SimSun; ">&nbsp;&nbsp;<strong style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">不知所踪</strong>......</span></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; text-align: justify; "><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-size: 10.5pt; font-family: SimSun; ">&nbsp; 于是我很认真的问了身边大爷：</span></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; text-align: justify; ">&nbsp;</p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; text-align: justify; "><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-size: 10.5pt; font-family: SimSun; ">&nbsp;&#8220;大爷，美国怎么走啊？&#8221;---郭德纲&nbsp;</span></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; text-align: justify; ">&nbsp;</p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; text-align: justify; "><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-size: 10.5pt; font-family: SimSun; ">&nbsp;&nbsp;<span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-family: Verdana; ">亦假亦真？</span></span>&nbsp;</p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; text-align: justify; ">&nbsp;</p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; text-align: justify; "><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-size: 10.5pt; font-family: SimSun; ">&nbsp;&nbsp;2010小爷<span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-family: SimSun; ">来了！</span></span></p></div></span><img src="http://www.cnblogs.com/sun11086/aggbug/1638027.html?type=1" width="1" height="1" alt=""/><p>评论: 2　<a href="http://www.cnblogs.com/sun11086/archive/2010/01/02/1638027.html#pagedcomment" target="_blank">查看评论</a>　<a href="http://www.cnblogs.com/sun11086/archive/2010/01/02/1638027.html#commentform" target="_blank">发表评论</a></p><p><a href="http://job.cnblogs.com/" target="_blank">找优秀程序员，就在博客园</a></p><hr/><p>最新新闻：<br/>· <a href="http://news.cnblogs.com/n/59262/" target="_blank">甲骨文将关闭OpenSSO</a><span style="color:gray">(2010-03-20 23:54)</span><br/>· <a href="http://news.cnblogs.com/n/59261/" target="_blank">专访陈晓薇：九城已重建、我还没想好去哪</a><span style="color:gray">(2010-03-20 22:07)</span><br/>· <a href="http://news.cnblogs.com/n/59260/" target="_blank">[视频]社交媒体不仅仅是一时狂热</a><span style="color:gray">(2010-03-20 21:58)</span><br/>· <a href="http://news.cnblogs.com/n/59259/" target="_blank">Google开出首个1337美刀的Chrome bug奖励支票</a><span style="color:gray">(2010-03-20 21:47)</span><br/>· <a href="http://news.cnblogs.com/n/59258/" target="_blank">著名图像讨论网站4chan创始人披露4chan诞生历史</a><span style="color:gray">(2010-03-20 21:42)</span><br/></p><p>编辑推荐：<a href="http://news.cnblogs.com/n/59093/" target="_blank">[视频]想做你的Code</a><br/></p><p>网站导航：<a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/" target="_blank">个人主页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/group/" target="_blank">小组</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://kb.cnblogs.com" target="_blank">知识库</a></p>]]></description></item><item><title>[转]Flex编程注意之性能优化、垃圾回收</title><link>http://www.cnblogs.com/sun11086/archive/2009/12/24/1631095.html</link><dc:creator>sungo</dc:creator><author>sungo</author><pubDate>Thu, 24 Dec 2009 01:00:00 GMT</pubDate><guid>http://www.cnblogs.com/sun11086/archive/2009/12/24/1631095.html</guid><description><![CDATA[<p>阅读: 50 评论: 0 作者: <a href="http://www.cnblogs.com/sun11086/" target="_blank">sungo</a> 发表于 2009-12-24 09:00 <a href="http://www.cnblogs.com/sun11086/archive/2009/12/24/1631095.html" target="_blank">原文链接</a></p><h1><span class="Apple-style-span" style="font-size: 14px; font-weight: normal; ">[Flex]Flex编程注意之性能优化、垃圾回收&nbsp;</span></h1><p><strong>垃圾回收的一些知识总结：</strong><br />1、被删除对象在外部的所有引用一定要被删除干净才能被系统当成垃圾回收处理掉。<br />2、父对象内部的子对象被外部其他对象引用了，会导致此子对象不会被删除，子对象不会被删除又会导致了父对象不会被删除。<br />3、如果一个对象中引用了外部对象，当自己被删除或者不需要使用此引用对象时，一定要记得把此对象的引用设置为null。<br />4、本对象删除不了的原因不一定是自己被引用了，也有可能是自己的孩子被外部引用了，孩子删不掉导致父亲也删不掉。<br />5、除了引用需要删除外，系统组件或者全局工具、管理类如果提供了卸载方法的就一定要调用删除内部对象，否则有可能会造成内存泄露和性能损失。<br />6、父对象立刻被删除了不代表子对象就会被删除或立刻被删除，可能会在后期被系统自动删除或第二次移除操作时被删除。<br />7、如果父对象remove了子对象后没有清除对子对象的引用，子对象一样是不能被删除的，父对象也不能被删除。<br />8、注册的事件如果没有被移除不影响自定义的强行回收机制，但有可能会影响正常的回收机制，所以最好是做到注册的事件*********都要记得移除干净。<br />9、父对象被删除了不代表其余子对象都删除了，找到一种状态的泄露代码不等于其他状态就没有泄露了，要各模块各状态逐个进行测试分析，直到测试任何状态下都能删除整个对象为止。<br />10、当触发了某个event后，不再使用的话，请将其remove掉。<br />11、能不使用Effect就不要使用Effect。<br /><br /><strong>内存泄露举例：<br /></strong>1、引用泄露：对子对象的引用，外部对本对象或子对象的引用都需要置null。<br />2、系统类泄露：使用了系统类而忘记做删除操作了，如BindingUtils.bindSetter()，ChangeWatcher.watch()函数时候完毕后需要调用ChangeWatcher.unwatch()函数来清除引用 
，否则使用此函数的对象将不会被删除； 
类似的还有MUSIC，VIDEO，IMAGE，TIMER，EVENT，BINDING等。<br />3、效果泄露：当对组件应用效果Effect的时候，当本对象本删除时需要把本对象和子对象上的Effect动画停止掉，然后把Effect的target对象置null; 
如果不停止掉动画直接把 
Effect置null将不能正常移除对象。&nbsp;<br />4、SWF泄露：要完全删除一个SWF要调用它的unload()方法并且把对象置null。<br />5、图片泄露：当Image对象使用完毕后要把source置null。<br />6、声音、视频泄露: 
当不需要一个音乐或视频是需要停止音乐，删除对象，引用置null。&nbsp;<br /><br /><strong>内存泄露解决方法：<br /></strong>1. 
在组件的REMOVED_FROM_STAGE事件回掉中做垃圾处理操作（移除所有对外引用（不管是VO还是组件的都需要删除），删除*********，调用系统类的清除方法） 
先remove再置null, 确保被remove或者removeAll后的对象在外部的引用全部释放干净。<br />2. 
利用Flex的性能优化工具Profile来对项目进程进行监控，可知道历史创建过哪些对象，目前有哪些对象没有被删除，创建的数量，占用的内存比例和用量，创建过程等信息。<br /><br />总结：关键还是要做好清除工作，自己设置的引用自己要记得删除，自己用过的系统类要记得做好回收处理工作。 
以上问题解决的好的话不需要自定义强制回收器也有可能被系统正常的自动回收掉。&nbsp;<br /><br />众所周知，由于Flash 
Player的垃圾回收机制是自动进行的，因此就算是上述内容的内容都符合要求，那么还是会产生内存&#8220;高居不下&#8221;的情况。<br />因此，我接下来介绍一个非常规的方式，让Flash 
Player的垃圾回收机制在我的控制之中。（以下的内容也不是我首创的，但是特此总结说明一下）<br /><br /><strong>强制垃圾回收：（即著名的hack方式）<br /></strong><span class="Apple-style-span" style="font-size: 13px">通过故意让SWF在运行时出错，然后throw出错误，而同时通过catch 
error来继续运行SWF文件。而垃圾回收机则会在SWF抛出错误的时候，被强制执行一次，以清除内存中无效的数据占用，减少资源的消耗。<br /><br /><span class="Apple-style-span" style="font-size: 12px">下面是我找到一个通过这种hack方式处理垃圾回收的代码：<br /></span></span></p>
<p>package util<br />{<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;import flash.net.LocalConnection;<br />&nbsp;&nbsp; &nbsp; &nbsp; 
&nbsp;import flash.system.System;<br /><br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; public class Memory&nbsp;{</p>
<p>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;public function Memory() &nbsp;{<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//TO 
DO<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;public static function gc() : void 
&nbsp;{<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;try {<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;new 
LocalConnection().connect( 'foo' );<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;new 
LocalConnection().connect( 'foo' );<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;} catch ( e : * ) 
{}<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public static function get used() : 
Number {<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return System.totalMemory;<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
&nbsp; &nbsp;}<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; 
&nbsp;}<br />}<br /><br />关于上面代码如何使用，目前大致上有两种使用方法：<br />1、在项目开始的时候，建立一个timer，然后每个一分钟就执行一次Memory.gc();<br />2、找一台配置一般的机器，然后运行你要的程序。然后在CPU、Memory占用很高的地方，记录一下当时的内存值，之后再自认为需要的地方（例如位图运算、Effect效果完成后等地方），执行Memory.gc();</p><p>&nbsp;</p><p>===================================</p><p>话说从flex sdk 3.4 开始里面就可以调用 System.gc() ,不过不知道内部实现是否是这种报错的方法....</p><p>&nbsp;</p><p>&nbsp;转载自：http://www.k-zone.cn/zblog/post/flex-flash-player-gc.html</p><img src="http://www.cnblogs.com/sun11086/aggbug/1631095.html?type=1" width="1" height="1" alt=""/><p>评论: 0　<a href="http://www.cnblogs.com/sun11086/archive/2009/12/24/1631095.html#pagedcomment" target="_blank">查看评论</a>　<a href="http://www.cnblogs.com/sun11086/archive/2009/12/24/1631095.html#commentform" target="_blank">发表评论</a></p><p><a href="http://job.cnblogs.com/" target="_blank">找优秀程序员，就在博客园</a></p><hr/><p>最新新闻：<br/>· <a href="http://news.cnblogs.com/n/59262/" target="_blank">甲骨文将关闭OpenSSO</a><span style="color:gray">(2010-03-20 23:54)</span><br/>· <a href="http://news.cnblogs.com/n/59261/" target="_blank">专访陈晓薇：九城已重建、我还没想好去哪</a><span style="color:gray">(2010-03-20 22:07)</span><br/>· <a href="http://news.cnblogs.com/n/59260/" target="_blank">[视频]社交媒体不仅仅是一时狂热</a><span style="color:gray">(2010-03-20 21:58)</span><br/>· <a href="http://news.cnblogs.com/n/59259/" target="_blank">Google开出首个1337美刀的Chrome bug奖励支票</a><span style="color:gray">(2010-03-20 21:47)</span><br/>· <a href="http://news.cnblogs.com/n/59258/" target="_blank">著名图像讨论网站4chan创始人披露4chan诞生历史</a><span style="color:gray">(2010-03-20 21:42)</span><br/></p><p>编辑推荐：<a href="http://news.cnblogs.com/n/59093/" target="_blank">[视频]想做你的Code</a><br/></p><p>网站导航：<a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/" target="_blank">个人主页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/group/" target="_blank">小组</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://kb.cnblogs.com" target="_blank">知识库</a></p>]]></description></item><item><title>[摘]About creating advanced components</title><link>http://www.cnblogs.com/sun11086/archive/2009/12/21/1628587.html</link><dc:creator>sungo</dc:creator><author>sungo</author><pubDate>Mon, 21 Dec 2009 01:02:00 GMT</pubDate><guid>http://www.cnblogs.com/sun11086/archive/2009/12/21/1628587.html</guid><description><![CDATA[<p>阅读: 4 评论: 0 作者: <a href="http://www.cnblogs.com/sun11086/" target="_blank">sungo</a> 发表于 2009-12-21 09:02 <a href="http://www.cnblogs.com/sun11086/archive/2009/12/21/1628587.html" target="_blank">原文链接</a></p><p><a href="http://livedocs.adobe.com/flex/3/html/help.html?content=ascomponents_advanced_2.html" target="_blank"><font class="Apple-style-span" color="#000000"></font></a></p><p>发现看来看去，还是Adobe的文档好...&nbsp;</p><p><span class="Apple-style-span" style="text-decoration: none;">http://livedocs.adobe.com/flex/3/html/help.html?content=ascomponents_advanced_2.html</span></p><p>&nbsp;</p><img src="http://www.cnblogs.com/sun11086/aggbug/1628587.html?type=1" width="1" height="1" alt=""/><p>评论: 0　<a href="http://www.cnblogs.com/sun11086/archive/2009/12/21/1628587.html#pagedcomment" target="_blank">查看评论</a>　<a href="http://www.cnblogs.com/sun11086/archive/2009/12/21/1628587.html#commentform" target="_blank">发表评论</a></p><p><a href="http://job.cnblogs.com/" target="_blank">找优秀程序员，就在博客园</a></p><hr/><p>最新新闻：<br/>· <a href="http://news.cnblogs.com/n/59262/" target="_blank">甲骨文将关闭OpenSSO</a><span style="color:gray">(2010-03-20 23:54)</span><br/>· <a href="http://news.cnblogs.com/n/59261/" target="_blank">专访陈晓薇：九城已重建、我还没想好去哪</a><span style="color:gray">(2010-03-20 22:07)</span><br/>· <a href="http://news.cnblogs.com/n/59260/" target="_blank">[视频]社交媒体不仅仅是一时狂热</a><span style="color:gray">(2010-03-20 21:58)</span><br/>· <a href="http://news.cnblogs.com/n/59259/" target="_blank">Google开出首个1337美刀的Chrome bug奖励支票</a><span style="color:gray">(2010-03-20 21:47)</span><br/>· <a href="http://news.cnblogs.com/n/59258/" target="_blank">著名图像讨论网站4chan创始人披露4chan诞生历史</a><span style="color:gray">(2010-03-20 21:42)</span><br/></p><p>编辑推荐：<a href="http://news.cnblogs.com/n/59093/" target="_blank">[视频]想做你的Code</a><br/></p><p>网站导航：<a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/" target="_blank">个人主页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/group/" target="_blank">小组</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://kb.cnblogs.com" target="_blank">知识库</a></p>]]></description></item><item><title>[转]深入理解Javascript闭包</title><link>http://www.cnblogs.com/sun11086/archive/2009/12/19/1627548.html</link><dc:creator>sungo</dc:creator><author>sungo</author><pubDate>Fri, 18 Dec 2009 16:56:00 GMT</pubDate><guid>http://www.cnblogs.com/sun11086/archive/2009/12/19/1627548.html</guid><description><![CDATA[<p>阅读: 23 评论: 0 作者: <a href="http://www.cnblogs.com/sun11086/" target="_blank">sungo</a> 发表于 2009-12-19 00:56 <a href="http://www.cnblogs.com/sun11086/archive/2009/12/19/1627548.html" target="_blank">原文链接</a></p><span class="Apple-style-span" style="font-family: verdana, sans-serif; "><p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">&nbsp;最近在网上查阅了不少Javascript闭包(closure)相关的资料，写的大多是非常的学术和专业。对于初学者来说别说理解闭包了，就连文字叙述都很难看懂。撰写此文的目的就是用最通俗的文字揭开Javascript闭包的真实面目。</p><p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">　　一、什么是闭包？</p><p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">　　&#8220;官方&#8221;的解释是：所谓&#8220;闭包&#8221;，指的是一个拥有许多变量和绑定了这些变量的环境的表达式（通常是一个函数），因而这些变量也是该表达式的一部分。</p><p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">　　相信很少有人能直接看懂这句话，因为他描述的太学术。我想用如何在Javascript中创建一个闭包来告诉你什么是闭包，因为跳过闭包的创建过程直接理解闭包的定义是非常困难的。看下面这段代码：</p><p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; "><code style="font-style: normal; ">&nbsp;&nbsp;&nbsp; function a(){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var i=0;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; function b(){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; alert(++i);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return b;<br />&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;var c = a();<br />&nbsp;&nbsp;&nbsp; c();</code></p><p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">　　这段代码有两个特点：</p><p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">　　1、函数b嵌套在函数a内部；</p><p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">　　2、函数a返回函数b。</p><p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">　　这样在执行完var c=a()后，变量c实际上是指向了函数b，再执行c()后就会弹出一个窗口显示i的值(第一次为1)。这段代码其实就创建了一个闭包，为什么？因为函数a外的变量c引用了函数a内的函数b，就是说：</p><p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">　　当函数a的内部函数b被函数a外的一个变量引用的时候，就创建了一个闭包。</p><p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">　　我猜想你一定还是不理解闭包，因为你不知道闭包有什么作用，下面让我们继续探索。</p><p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">　　二、闭包有什么作用？</p><p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">　　简而言之，闭包的作用就是在a执行完并返回后，闭包使得Javascript的垃圾回收机制GC不会收回a所占用的资源，因为a的内部函数b的执行需要依赖a中的变量。这是对闭包作用的非常直白的描述，不专业也不严谨，但大概意思就是这样，理解闭包需要循序渐进的过程。</p><p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">在上面的例子中，由于闭包的存在使得函数a返回后，a中的i始终存在，这样每次执行c()，i都是自加1后alert出i的值。</p><p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">　　那 么我们来想象另一种情况，如果a返回的不是函数b，情况就完全不同了。因为a执行完后，b没有被返回给a的外界，只是被a所引用，而此时a也只会被b引 用，因此函数a和b互相引用但又不被外界打扰(被外界引用)，函数a和b就会被GC回收。(关于Javascript的垃圾回收机制将在后面详细介绍)</p><p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">　　三、闭包内的微观世界</p><p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">　　如 果要更加深入的了解闭包以及函数a和嵌套函数b的关系，我们需要引入另外几个概念：函数的执行环境(excution context)、活动对象(call object)、作用域(scope)、作用域链(scope chain)。以函数a从定义到执行的过程为例阐述这几个概念。</p><p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">　　1、当定义函数a的时候，js解释器会将函数a的作用域链(scope chain)设置为定义a时a所在的&#8220;环境&#8221;，如果a是一个全局函数，则scope chain中只有window对象。</p><p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">　　2、当函数a执行的时候，a会进入相应的执行环境(excution context)。</p><p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">　　3、在创建执行环境的过程中，首先会为a添加一个scope属性，即a的作用域，其值就为第1步中的scope chain。即a.scope=a的作用域链。</p><p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">　　4、然后执行环境会创建一个活动对象(call object)。活动对象也是一个拥有属性的对象，但它不具有原型而且不能通过JavaScript代码直接访问。创建完活动对象后，把活动对象添加到a的作用域链的最顶端。此时a的作用域链包含了两个对象：a的活动对象和window对象。</p><p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">　　5、下一步是在活动对象上添加一个arguments属性，它保存着调用函数a时所传递的参数。</p><p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">　　6、最后把所有函数a的形参和内部的函数b的引用也添加到a的活动对象上。在这一步中，完成了函数b的的定义，因此如同第3步，函数b的作用域链被设置为b所被定义的环境，即a的作用域。</p><p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">　　到此，整个函数a从定义到执行的步骤就完成了。此时a返回函数b的引用给c，又函数b的作用域链包含了对函数a的活动对象的引用，也就是说b可以访问到a中定义的所有变量和函数。函数b被c引用，函数b又依赖函数a，因此函数a在返回后不会被GC回收。</p><p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">　　当函数b执行的时候亦会像以上步骤一样。因此，执行时b的作用域链包含了3个对象：b的活动对象、a的活动对象和window对象，如下图所示：</p><p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">　　如图所示，当在函数b中访问一个变量的时候，搜索顺序是先搜索自身的活动对象，如果存在则返回，如果不存在将继续搜索函数a的活动对象，依 次查找，直到找到为止。如果整个作用域链上都无法找到，则返回undefined。如果函数b存在prototype原型对象，则在查找完自身的活动对象 后先查找自身的原型对象，再继续查找。这就是Javascript中的变量查找机制。</p><p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">　　四、闭包的应用场景</p><p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">　　1、保护函数内的变量安全。以最开始的例子为例，函数a中i只有函数b才能访问，而无法通过其他途径访问到，因此保护了i的安全性。</p><p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">　　2、在内存中维持一个变量。依然如前例，由于闭包，函数a中i的一直存在于内存中，因此每次执行c()，都会给i自加1。</p><p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">　　以上两点是闭包最基本的应用场景，很多经典案例都源于此。</p><p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">　　五、Javascript的垃圾回收机制</p><p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">　　在Javascript中，如果一个对象不再被引用，那么这个对象就会被GC回收。如果两个对象互相引用，而不再被第3者所引用，那么这两个互相引用的对象也会被回收。因为函数a被b引用，b又被a外的c引用，这就是为什么函数a执行后不会被回收的原因。</p><p><a href="http://blog.csdn.net/hitman9099/archive/2009/01/28/3854171.aspx" target="_blank">http://blog.csdn.net/hitman9099/archive/2009/01/28/3854171.aspx</a>&nbsp;</p></span><img src="http://www.cnblogs.com/sun11086/aggbug/1627548.html?type=1" width="1" height="1" alt=""/><p>评论: 0　<a href="http://www.cnblogs.com/sun11086/archive/2009/12/19/1627548.html#pagedcomment" target="_blank">查看评论</a>　<a href="http://www.cnblogs.com/sun11086/archive/2009/12/19/1627548.html#commentform" target="_blank">发表评论</a></p><p><a href="http://job.cnblogs.com/" target="_blank">找优秀程序员，就在博客园</a></p><hr/><p>最新新闻：<br/>· <a href="http://news.cnblogs.com/n/59262/" target="_blank">甲骨文将关闭OpenSSO</a><span style="color:gray">(2010-03-20 23:54)</span><br/>· <a href="http://news.cnblogs.com/n/59261/" target="_blank">专访陈晓薇：九城已重建、我还没想好去哪</a><span style="color:gray">(2010-03-20 22:07)</span><br/>· <a href="http://news.cnblogs.com/n/59260/" target="_blank">[视频]社交媒体不仅仅是一时狂热</a><span style="color:gray">(2010-03-20 21:58)</span><br/>· <a href="http://news.cnblogs.com/n/59259/" target="_blank">Google开出首个1337美刀的Chrome bug奖励支票</a><span style="color:gray">(2010-03-20 21:47)</span><br/>· <a href="http://news.cnblogs.com/n/59258/" target="_blank">著名图像讨论网站4chan创始人披露4chan诞生历史</a><span style="color:gray">(2010-03-20 21:42)</span><br/></p><p>编辑推荐：<a href="http://news.cnblogs.com/n/59093/" target="_blank">[视频]想做你的Code</a><br/></p><p>网站导航：<a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/" target="_blank">个人主页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/group/" target="_blank">小组</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://kb.cnblogs.com" target="_blank">知识库</a></p>]]></description></item><item><title>工作备忘录</title><link>http://www.cnblogs.com/sun11086/archive/2009/12/18/1627355.html</link><dc:creator>sungo</dc:creator><author>sungo</author><pubDate>Fri, 18 Dec 2009 09:51:00 GMT</pubDate><guid>http://www.cnblogs.com/sun11086/archive/2009/12/18/1627355.html</guid><description><![CDATA[<p>阅读: 8 评论: 0 作者: <a href="http://www.cnblogs.com/sun11086/" target="_blank">sungo</a> 发表于 2009-12-18 17:51 <a href="http://www.cnblogs.com/sun11086/archive/2009/12/18/1627355.html" target="_blank">原文链接</a></p>在和服务器交互传输数据时，byteArray转过来的数据都是字符串，然后再根据分隔符和其属性名分割获取对应的数据，做的次数多了，发现每个指令都要写解析的函数(当然也可以用static的，但是无法从根本上解决这个问题)，很是烦躁。突发奇想，是否可以用一种基于树的数据结构来构建一个数据模型，只要设置不同层次的分隔符，然后当传入数据时就可以动态生成数据模型，这样以后都不用写了。。。而且感觉通用性也不错。刚刚把树的节点写完了，发现还有很多东西需要完善，迭代器，深度优先，纵向优先，还有节点的细节完善，额 还是暂时搁置这个想法，先推进进度吧...有空再完善.<img src="http://www.cnblogs.com/sun11086/aggbug/1627355.html?type=1" width="1" height="1" alt=""/><p>评论: 0　<a href="http://www.cnblogs.com/sun11086/archive/2009/12/18/1627355.html#pagedcomment" target="_blank">查看评论</a>　<a href="http://www.cnblogs.com/sun11086/archive/2009/12/18/1627355.html#commentform" target="_blank">发表评论</a></p><p><a href="http://job.cnblogs.com/" target="_blank">找优秀程序员，就在博客园</a></p><hr/><p>最新新闻：<br/>· <a href="http://news.cnblogs.com/n/59262/" target="_blank">甲骨文将关闭OpenSSO</a><span style="color:gray">(2010-03-20 23:54)</span><br/>· <a href="http://news.cnblogs.com/n/59261/" target="_blank">专访陈晓薇：九城已重建、我还没想好去哪</a><span style="color:gray">(2010-03-20 22:07)</span><br/>· <a href="http://news.cnblogs.com/n/59260/" target="_blank">[视频]社交媒体不仅仅是一时狂热</a><span style="color:gray">(2010-03-20 21:58)</span><br/>· <a href="http://news.cnblogs.com/n/59259/" target="_blank">Google开出首个1337美刀的Chrome bug奖励支票</a><span style="color:gray">(2010-03-20 21:47)</span><br/>· <a href="http://news.cnblogs.com/n/59258/" target="_blank">著名图像讨论网站4chan创始人披露4chan诞生历史</a><span style="color:gray">(2010-03-20 21:42)</span><br/></p><p>编辑推荐：<a href="http://news.cnblogs.com/n/59093/" target="_blank">[视频]想做你的Code</a><br/></p><p>网站导航：<a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/" target="_blank">个人主页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/group/" target="_blank">小组</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://kb.cnblogs.com" target="_blank">知识库</a></p>]]></description></item></channel></rss>