说说Stack Overflow和Quora

今天看到一个新闻,Quora的中国克隆“知乎”得到了创新工场的投资。我之前从创新工场的投资经理张亮那里要到了一个知乎邀请码,最近一直泡知乎,觉得Quora类的产品有很多创新的亮点,所以比较感兴趣这类产品,忍不住就谈谈。 Stack Overflow(以下简称SO)和Quora虽然都是知识问答类的网站,但是他们有共同的成功基因,也有本质的差别。 先说SO和Quora共同成功基因,那就是:用户身份的真实性和唯一性。 我看过不少关于SO和Quora如何成功的很多讨论,各种说法都有:如说SO的SEO很好,SO的积分激励机制如何如何,Quora的种子用户运营如何如何等等。其实这些原因都对,但不是最根本的原因。真正根本的原因在于:用户身份的真实性和唯一性。 我们国内做社区网站,特别是知识型社区网站,核心的竞争力就是高质量的内容。如何获取高质量内容的手段自然多种多样,但是当社区成长起来以后,特 别是用户量急剧膨胀以后,很难避免社区的水化,大量低水平用户,特别是不负责任的用户随意的发帖、发言和评论,会破坏整个社区的内容质量,造成劣币驱逐良 币的现象,最终毁掉这个社区。 这个现象是社区特别是BBS型社区的发展宿命,JavaEye也面临这个问题,早先几年采取的运营手段可以称之为“堵”,惩罚低水平用户的发帖, 恐吓不负责任的行为。但是随着社区规模不断的扩大,注册用户数量越来越多(已经超过70万注册用户,每天UV有25万以上),堵的手段成本越来越高,有效 性越来越低,因此必须改变运营方式。我想到的一个办法就是BBS产品创新,而且是大胆的产品创新。不过这个话题不是本文的主题,我以后会另外撰文。总之这 是一个社区需要解决的大问题。 而SO和Quora很巧妙的解决了这个问题,办法就是:不提供网站账号注册功能,必须通过你在互联网的得到公认的唯一身份标识来登录网站,例如必 须使用你的Google帐户,Facebook帐户,或者Twitter帐户登录。这样的做法就保证了用户使用真实的身份,而且身份是唯一的。 真实而且唯一的身份保证了你必须对自己的发言负责任,保证了你不可能养很多马甲,保证了你必须深思熟虑的行为,确保你自己的网络身份和信誉。特别 是通过Facebook帐户登录以后,可以连带你的好友关系一起导入进来,让你在这个网站的种种行为在你的众多好友的注视之下,更加不可能胡作非为,而且 有了好友关系以后,天然的可以增加网站的用户关系和黏性。 很多人可能以为外国人就是网络素质高,不会像中国人那样网络随地大小便。其实不然,我去过很多国外的小论坛,用phpbb搭建的BBS里面,包括 TSS,照样是Help! Urgent!满天飞,和国内的论坛标题党绝对有的一比。但是一旦用你的真实和唯一身份登录,老外也马上规规矩矩起来,特别是Facebook,外国很多 人就是拿Facebook当作个人的网络通讯录来用的,这个东西有点像国内的MSN。你敢在你的MSN上面对着好友说那些很不着调的话吗? 所以那些SO和Quora上面的人确实就不会乱来。这就是真实而且唯一身份带来的威力。 不过可惜的是,明知这一点,但国内的网站是绝对抄不到手的,因为国内没有一个具有像Facebook这种占据统治地位的真实身份和用户关系,并且 彻底开放的SNS好友关系平台的存在。这也是国内互联网行业的悲哀之处,国外的互联网基础设施实在太好了,AWS,PAAS,连SNS平台的海量用户都现 成,你只要有想法,会写代码,一堆基础设施拿来就用,三两下,一个创新型应用平地而起,这也是为什么硅谷创业公司这么流行Ruby on rails的原因(呀,跑题了)。 总之,你没有这种海量的真实唯一用户导入,就算你的运营水平和产品做很好,也长不成SO和Quora。说到这里,Facebook现在真的成长为 下一代互联网应用的基础设施了,以后做网站真没有必要搞自己的帐户系统了,直接Facebook账号登录搞定,所以Facebook估值到800亿美刀不 算夸张,什么叫基础设施啊朋友,baidu这种烂货都400亿刀了。(又跑题了) 所以,我并不太看好知乎这个产品的前景,目前严格的邀请准入制迟早要改变的,到时候用什么手段来解决这个问题呢? 我认为根本无解,或者说如果有解的话,产品形态必须做出重大的改变,那样的话,从一开始就不应该照着Quora的样子去长。 然后说说SO和Quora的差异在于:知识的组织方式:以内容组织结构为基础,还是以用户关系为基础 其实SO和Quora的差异还是很大的,从目前Google Adplanner来看,SO的UV和PV大致是Quora的5倍,考虑到SO只是一个纯技术网站,这个差距不可谓不小。但是这个不重要,重要的你怎么理解“知识”的组织方式: SO是一个标准的内容型社区,不需要登录就可以访问,用tag和search良好的组织整个网站的知识体系,在这个基础上添加用户关系和用户身 份。而Quora是一个标准的Social型的社区,不登录对不起,什么都看不到,登录以后你没有用户关系,还是对不起,什么都看不到,你获取信息要依赖 于你的用户关系之上,用户关系决定了你获取信息的效率。 我们说问答这种知识沉淀的方式包含了两种需求: 沉淀知识需求和快需求: 什么是快需求? 我就是来找答案的,别TMD的让我自己搜索半天,然后自己摸索,我就是等着你喂我,我不想费任何力气自己去找答案。其实绝大多数中国的论坛充斥的都是这种 快需求的帖子,而满足这种快需求最好的产品形态就是百度知道,没有唯二的了。我不知道如何形容我对百度知道的仰慕之情,以致于我抄袭了百度知道,做了一个 JavaEye问答频道,而且强迫性的不允许JavaEye用户在论坛发提问贴,必须给我到问答频道提问,而且我还老搞问答大赛,刺激答题者的热情,重点 不在于问题是否重复的问,而在于你答题是否及时有效,这就是旗帜鲜明的满足快需求而去的。 SO也好,Quora也罢,可以满足一部分的快需求,但是从产品形态来说,他们主要不是为了满足快需求而量身打造的产品。快需求有一个很大的特 点,就是并不需要回答的内容是高质量的,反而对实效性要求可能稍微高一些,因此这种产品真的不需要特别的追求回答的质量多高,只要能够快速满足提问者的需 求就OK了。 那么沉淀型需求呢? 沉淀型需求做的最好的产品其实是wikipedia,基本上你可以找到大多数各个领域的知识。当然wikipedia不能覆盖所有的知识领域,一些知识需 要通过问答的形态来组织,因此SO也做的不错。沉淀型需求对内容的质量有要求,越是高质量的内容,越能够加强社区的竞争力和黏性。所以你会看到不管是 SO,Quora还是很多知识型社区的一个基本诉求就是:内容的质量。 这里,我们要更加深入的思考一个问题: 什么叫做高质量的内容? 你如何评判一个内容的质量高低与否? […]

利用memcached java client一个简单的应用

利用memcached java client一个简单的应用 1.memcached java client一个实现的下载地址 http://www.whalin.com/memcached/#download2.  利用memcached java client 一个简单的应用 java 代码 package com.danga.MemCached.test;       import java.util.Date;       import com.danga.MemCached.MemCachedClient;    import com.danga.MemCached.SockIOPool;          public class Test {            protected static MemCachedClient mcc = new MemCachedClient();                  static {               String[] servers ={“192.168.40.4:12000”};                      Integer[] weights = { 3 };                      //创建一个实例对象SockIOPool             SockIOPool pool = SockIOPool.getInstance();                      // set the servers and the weights            //设置Memcached Server            pool.setServers( servers );               pool.setWeights( weights );       […]

Memcache的使用和协议分析详解(php)

Memcache的使用和协议分析详解 作者:heiyeluren博客:http://blog.csdn.net/heiyeshuwu时间:2006-11-12关键字:PHP Memcache Linux 缓存 Memcache是danga.com的一个项目,最早是为 LiveJournal 服务的,目前全世界不少人使用这个缓存项目来构建自己大负载的网站,来分担数据库的压力。(关于Memcache的更多信息请Google)Memcache官方网站:http://www.danga.com/memcached 【安装Memcache服务器端】 我目前的平台,服务器是Fedora Core 1(内核:2.4.22),客户端是Windows XP SP2,需要安装的就是服务器的Memcached的守护进程和客户端的PHP扩展php_memcache两个东西。现在我分别来讲。 服务器端主要是安装memcache服务器端,目前的最新版本是 memcached-1.2.0 。下载:http://www.danga.com/memcached/dist/memcached-1.2.0.tar.gz另外,Memcache用到了libevent这个库用于Socket的处理,所以还需要安装libevent,libevent的最新版本是libevent-1.2。(如果你的系统已经安装了libevent,可以不用安装)官网:http://www.monkey.org/~provos/libevent/下载:http://www.monkey.org/~provos/libevent-1.2.tar.gz 我分别把两个东东下载回来,放到 /tmp 目录下:# cd /tmp# wget http://www.danga.com/memcached/dist/memcached-1.2.0.tar.gz# wget http://www.monkey.org/~provos/libevent-1.2.tar.gz 先安装libevent:# tar zxvf libevent-1.2.tar.gz# cd libevent-1.2# ./configure –prefix=/usr# make# make install 然后看看我们的libevent是否安装成功:# ls -al /usr/lib | grep libeventlrwxrwxrwx    1 root     root          21 11?? 12 17:38 libevent-1.2.so.1 -> libevent-1.2.so.1.0.3-rwxr-xr-x       1 root     […]

Spring中基于aop命名空间的AOP

本文地址:http://www.blogjava.net/cmzy/archive/2008/08/23/223870.html下篇地址:Spring中基于aop命名空间的AOP 二(声明一个切面、切入点和通知)     在某些时候,我们工程中使用的JDK 不一定就是1.5 以上,也就是说可能不支持Annotation 注解,这时自然也就不能使用@AspectJ 注解驱动的AOP 了,那么如果我们仍然想使用AspectJ 灵活的切入点表达式,那么该如何呢?Spring 为我们提供了基于xml schematic 的aop 命名空间,它的使用方式和@AspectJ 注解类似,不同的是配置信息从注解中转移到了Spring 配置文件中。在这里,我们将详细介绍如何使用Spring 提供的<aop:config/> 标签来配置Spring AOP 。 1 、一点准备工作和一个例子     使用<aop:config/> 标签,需要给Spring 配置文件中引入基于xml schema 的Spring AOP 命名空间。完成后的Spring 配置文件如下(在该节,所有例程的配置文件中添加了Spring AOP 命名空间,除非特殊情况外,为了节约空间,这部分将在给出的代码中省略),粗体内容即为我们需要添加的内容: 代码   查看源代码copy to clipboard打印 <?xml version=“1.0” encoding=“UTF-8”?>   <beans xmlns=“http://www.springframework.org/schema/beans”           xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”           xmlns:aop=“http://www.springframework.org/schema/aop”           xsi:schemaLocation=”http://www.springframework.org/schema/beans                  http://www.springframework.org/schema/beans/spring-beans-2.5.xsd                   http://www.springframework.org/schema/aop                   http://www.springframework.org/schema/aop/spring-aop-2.5.xsd >   ………… Spring配置信息    </beans>       关于aop命名空间的标签,我们前面使用过的有<aop:aspectj-autoproxy/>,在这一节,我们将以<aop:config/>标签作为重点。事实上,我们在这一节介绍的所有标签都是该标签的子标签。    下面有一个例程来直观的展示如何使用<aop:config/>标签来配置Spring AOP(完整代码见例程4.15)。在例子中,我们使用<aop:config/>配置一个切面并拦截目标对象Peoples的SayHello()方法,在它执行前输出提示信息。首先创建工程AOP_Test4.15,添加Spring […]

click Web Framework 1.4发布

click Web Framework 1.4发布,Click是一个高性能的J2EE Web应用程序框架适用商业Java开发者,它是基于页面和组件的java web框架,基于事件编程模型,使用Velocity模板作为页面视图,没有复杂的抽象和定义,简单易学,商业开发者能够在一天内把它运行起来。1.4版本的新功能包括:1。Stateful page支持,使得开发复杂页面和页面流程更加简单 Java代码 package com.mycorp.page;       import java.io.Serializable;       import net.sf.click.Page;         public class SearchPage extends Page implements Serializable {           public SearchPage() {            setStateful(true);            ..        }    }   package com.mycorp.page; import java.io.Serializable; import net.sf.click.Page; public class SearchPage extends Page implements Serializable { public SearchPage() { setStateful(true); .. } } 2。新的Control event函数 – onInit(), onRender() […]

Developing Applications with the Java APIs for Bluetooth (JSR-82)

Developing Applications with the Java APIs for Bluetooth (JSR-82) This paper covers the Java API for Bluetooth (JSR-82) with respect to Sony Ericsson devices. It starts by introducing the Bluetooth technology, followed by the Java APIs for Bluetooth, and how to use them. Currently, these APIs are currently available in the Sony Ericsson P900/P908 handsets. […]

Collection of open source Flex 2 Projects

While was on Flex 2 beta 3, I did myself some little and basic projects for flex 2, if you are instresting in see them it’s a total of 25 projects with all source avaible. the total ammount of file it’s up to 80MB. Here’s the link : Download it Feel free to comment.

AS3日积月累(1) – AS3的面向对象特点概述

原文章地址:http://as3blog.com/as3/as3tip-oop/ 本文是我(aw)在整理了相关文档和讨论之后,结合自己的亲自实验总结出来的一些经验和心得。我尽量描述详尽,避免模糊概念,当然也希望所有看官提出批评意见。为了表述方便,其中术语不限定语言,如我可能会一会儿用class,一会儿用“类”。 面向对象的难点部分就是理解变量作用域修饰符(modifier)其实也就是面向对象中我们已经熟悉的public、protected、private等等。本文还深入讨论了ActionScript3中新增的internal等概念。下面我依次列出: 一、关于package以及internalpackage,用“形而上学”的方式理解,就是物理目录下的类集合。在AS2中只需要保证文件系统的路径匹配,然后用类似“import com.awflasher.someUtils”的方法导入即可。而AS3则要求您在所有的类中声明package关键词。package的大括号对“{}”内,我们只能定义一个类,我们可以在这个大括号外面定义一些辅助类,不过这些类只能被当前这个类(你在package大括号对内定义的类)访问。当然,一个package大括号对内只有一个类,这并不代表一个package内只有一个类。你可以在同一目录下定义多个属于该package(指代这个目录)的类。它的意义绝不是简单的“类文件集合容器”,而是一个让各种应该协同工作的类集中到一起的项目包。值得一提的是,所谓“协同工作”是指至少有一个class要引入其他一些class来进行功能设计,而这时候采用internal修饰可以省去很多getters和setters。我自己回忆起在湖南卫视的项目中用AS2开发的Vplayer,两个类AVCore和AVControl就有很多getter和setter,搞的特别麻烦。internal类似public,但限定在一个package内了。在同一个package内的类可以访问同一个package内其他类的internal变量,而其他包内的类无法访问。package与类的继承性毫无关系,比如TextField和Sprite、MovieClip都继承自DisplayObject类,但TextField属于flash.text包,而MovieClip和Sprite属于flahs.display包。也就是说,包对类的限定是与继承链毫无关联的、一个新的“维度”的限定。附:使用一个类的时候,我们必须import这个类,或者包含这个类的package。AS2时直接写完整包路径的使用方法在AS3中不管用了,本文后面有详细介绍。 二、关于publicpublic定义的类或者属性可以在任何作用域内由任何来源访问。构造函数永远都是public的,Flex中的应用程序类(Application Class)和Flash CS3中的文档类(Document Class)必须是public的。且不能缺省public这个关键词声明。我在测试中发现,如果不声明public,Flash根本就不会获取类的定义,进而编译无法通过。非常有必要啰嗦一下:public可以穿越package,而类又不能使用namespace(参阅FlashCS3帮助文档:Applying namespaces)。因此,所有被文档类调用的其它包中的类,应该一致声明为public的 。因为文档类在一个独立的包中。 三、关于protectedprotected声明类似AS2的private,它定义的属性只能在自己子类中可见,而其它场合都是不可见的。这一点与Java等传统OOP语言类似。 四、关于private注意AS3的private和AS2的private大不相同,它定义的属性只属于自己,子类可以定义毫无牵连的同名属性。dynamic 和原来AS2的dynamic一样,用dynamic声明的类可以动态的加入属性。这些属性也可以通过delete来删除。动态加入的属性一旦被切断所有的引用就会被垃圾回收机制自动回收。有时候用System.totalMemory检测不到内存释放是因为垃圾回收机制并不是即时运行的。 五、关于dynamic动态(dynamic)类允许在运行时动态地添加属性,常见的动态类有MovieClip和顶级(top-level)的Array。如果您的自定义类要继承于动态类,那么请也定义为动态的,不要省略dynamic关键词。如果您喜欢阅读英文教程,会看到很多“sealed class”,其含义即“非dynamic class”。只不过并没有sealed这个关键词(AS3中,类默认就是sealed的)。注意,在AS2中,“骨子里”是没有sealed class的!在run-time时,所有的AS2代码都变成了AS1的语法,sealed class无从说起了。可以说这是AS3的一个新产物。更多相关内容可以参见:http://as3blog.com/as3/as3tip-take-care-of-resource 六、关于继承(extends)和override继承其实并不太复杂,唯一要说明的就是:子类的构造函数一定要用“super”调用一次父类的构造函数,否则报错!对于继承后的子类,如果要重新定义父类的非private方法,必须使用override关键词。在override的时候,如果我们需要调用父类的方法,可以使用super关键词(由于继承方法在逻辑上与父类往往有相似性,因此没有必要把方法逻辑完全重写)官方帮助中的这个例子非常易懂:package {import flash.display.MovieClip;public class SuperExample extends MovieClip{public function SuperExample(){var myExt:Extender = new Extender()trace(myExt.thanks()); // output: Mahalo nui loa}}} class Base {public function thanks():String{return “Mahalo”;}} class Extender extends Base{override public function thanks():String{return super.thanks() + ” nui loa”;}} […]

AS3日积月累(2) – 从AS1和AS2到AS3的观念转变

原文章地址:http://as3blog.com/as3/as3tip-new-philosophy/ AS1/2-AS3观念的转变(Meet with new philosophy)对于AS1、AS2的开发模式来说,灵活是最大的优势。然而,灵活却造成了不稳定、紊乱。这是开发复杂的、长久的项目所忌讳的。关于(AS1/2/1+2)灵活轻便与稳定持久(AS3)的权衡,我个人觉得可以理解为”鱼和熊掌不可兼得”,但我希望已经习惯了AS1、AS2的朋友们不要把这个结论想得太悲观。 AS3是纯粹面向对象的,相比过去的AS2,我认为是更加敏捷的。纵然有着更多的约束,但在package内直接建立多个辅助类(Helper Class),不失为一个非常好的消息。就凭这一点,我觉得至少与笨拙的AS2相比,AS3的开发效率就不会打多大折扣。我们需要的其实只是语法、习惯,尤其是观念的转变而已。当然,这需要时间。我作为一个AS1/2的长期发开人员,在转变到AS3的过程之中,也遇到了很多问题和疑惑。但我很乐于与大家分享、交流我所获得的收获以及观念转变的心路历程。 ActionScript编程自它问世的那一天就是多姿多彩的。技术,尤其是Adobe产品线的技术体系,也绝然不是呆板的”学究式体系”。我希望我的”罗嗦”能让您获得一个更轻松的心态。 言归正传,先说说我在AS1/2(1+2)转变到AS3时所遭遇的最大困惑吧:开局(How, and especially where, to get start) – 玩过星际争霸的朋友们一定知道,针对不同的地图,如Lost Temple和WCG-groky park(原来WCG有一个岛关,我忘记了),都有各自的经典、流行的开局方式。从AS1/2转变到AS3,无非是从Lost Temple转变到WCG-groky park的过程,你也许要先采气矿,造空军,才能顺利发展。 其实Flash从AS1到AS3,也有各自固定的、流行的开局方式。对于习惯了用AS1编程的人来说,制作一个Flash的开局是非常灵活的:你一进入Flash就有一个长长时间轴以供使用。你往往需要一个loading,你可以用1-5帧先做一个loading(还记得N年前流行的FlashMTV制作教程么?);你也可以取一帧,放一个loading的MovieClip然后在这个MovieClip上写一个onEnterFrame来监听swf文件加载的进度(我热衷的做法)。接下来,你可以在第二帧或者第N帧部署程序界面。MovieClip强大的帧API能让你灵活地完成许多有趣的逻辑(gotoAndPlay、gotoAndStop、prevFrame等)。编程的时候也可以很随意地寻找自己要控制的资源,我现在还记得刚接触AS的时候,一个_root一个_global,曾经让我屡试不爽。每次遇到问题了就用这两个东西解决。AS2的开局其实没有本质的变化,至少我是这么认为的。唯一的进步就是比AS1的OOP,模块封装的更加彻底。甚至还有些许退步,比如清一色基于MovieClip+attachMovie的模式,仍然容易造成运行时(Run-Time)效率低下,而且开发起来概念也模糊了。因为Library中设置了linkage,new的明明是自己的Class,attach的还是MovieClip。于是很多人采用AS1+2的方式,这也是我所喜欢的。现在想起来,还是比较灵活快速的。然而在AS3中,你却仿佛陷入一片黑暗。FlexBuilder没有时间轴。即便用”似曾相识”的FlashCS3的IDE开发,AS3也不支持MovieClip和Button上的代码。写在帧上也无法简单地使用”onRelease=functioin”了。上网搜一搜教程,往往得到如下的写法:aw.addEventListener(”click”,fun);function fun(e:Event){trace(1);}实在让习惯了AS1、2的朋友们郁闷。 一方面看到人家用AS3设计出来的精彩demo羡慕不已,一方面又对程序入口摸不着边际。这种尴尬我想不是看一两篇教程就能解决的。 我们需要”洗心革面”,我们需要”忘记过去”(try to forget the past)。大胆地告诉自己,onRelease=function不仅已经被”杀死”,而且根本就不是好的写法,哪怕你仍然觉得它看起来那么顺眼。大胆地告诉自己,AS3中,所有的变量、函数都属于类(对象的属性和方法),而不再属于时间轴、帧,哪怕上面列举的两行代码也可以写在时间轴上生效。 我个人建议,传统AS1/2的程序员从Flash CS3 IDE入手AS3,比较合适。因为Flash CS3的入口(开局)非常明确:Document Class(文档类)。 运行FlashCS3,打开fla文件,在IDE下面属性面板中,找到”Document Class”,填入一个名字(由于是类名,最好是首字母大写,比如MyMainClass)。然后在fla文件所在的文件夹下面建立同名的as文件。当然,也可以把fla和类文件全部分离,这就需要设定类路径(File-Publish Settings-ActionScript version:Settings)。下面可以输入类路径。我个人建议输入相对路径。相对,意即相对当前的fla文件;路径,即我们电脑文件系统中的文件夹。不写死”x:\xxx”是为了让项目可以在不同的环境上运行,也可以更好的支持多人开发。相对路径的写法就是用”.”表示当前路径,用”..”表示上一级路径。比如可以写:“./classes/”或者”../classes/”。这里再补充说明一下,我的建议是把原文件放在一起,输出的swf放在别的目录(通常叫做”bin”)。输出目录在刚才面板中的”format”标签下,可以把原文件放到目录”src”中,然后把swf格式的file名设置为”../bin/somefile.swf”,建议只输出swf。HTML还是自己写的好。别看我罗嗦了这么多篇幅讲这些设置,但它们真的对于规范你的开发习惯和开发观念有好处。让你潜移默化的接受AS3的Philosophy中的”分离”思想。 补充内容: 关于Flash CS3类路径的设置,如果您希望设计自己的package。那么则需要把这个package放在classpath下面,而不要把package文件夹自己设置为classpath。 切入正题,我们逐步开局:一、建立文档类(Document Class)现在我们可以开始建立Document Class了。Flash CS3方便地提供了一个”编辑图标”,你可以方便地打开类文件。回忆一下,上一篇文章提到关于类的书写:每一个类都应该在一个package中。我个人的理解,觉得Document Class应该在一个单独的、无具体名称的”generic”package中,即:package{import flash.display.Sprite;public class MyMainClass extends Sprite{public function MyMainClass(){init();}private function init(){// […]

AS3日积月累(3) – 利用AS3的图形界面开发及资源管理攻略

原文章地址:http://as3blog.com/as3/as3tip-take-care-of-resource 摒弃了attachMovie之后的AS3,采用了类似DOM的操作方式。addChild、removeChild、getChildAt等方法开始成为AS3中显示(在屏幕上渲染)、操作图形的主要方法。由于AS1、AS2完全是依赖于attchMovie的思想,因此对于传统Flash开发人员来说,转变到新的addChild的确需要下一番功夫。 由于新的“DisplayObject”在内存的使用上非常“敏感”。往往由于不良的编程习惯会造成不必要的内存泄漏,因此,我们不得不比AS1、AS2时代更加深入到内存管理了。我想,每一个Flash开发人员,包括我自己,都应该花一番功夫仔细体会“内存管理”这几个字的含义。毕竟我们学习AS3是为了开发比AS1、2时代更加先进、高效而且内存占用小的应用程序,如果还是开发一些简单的应用,也就失去我们每一个人使用AS3的意义了。 我觉得,由于GC是Flash应用程序内存管理的核心,我应该先从AS3中的Garbage Collector(简称GC)开始说起。AS3的GC功能比AS1、2中的要强大的多。然而,强大的同时,也带来了一定程度的复杂性。但是也不至于非常复杂,我觉得比C++等传统语言要容易掌握得多。 在研究内存如何回收之前,先说一下变量的创建:在Flash中,我们每建立一个非原生变量时(Boolean, String, Number, uint, int这些是原生变量),这个变量名只是一个reference(指向,有时候也成为“引用”)而已,而并非这个变量本身。例如:var a:int = 5; //a就是5var b:int = a; //b是a,也就是5a = 4;trace(b); // 是5,而不是4!//改变b的值,a不发生变化。反之亦然var c:Object = {name:”aw”, blog:”www.awflasher.com/blog”}; //c只是指向一个内部的Object,为了描述方便,称其为“O”var d:Object = c; //d指向c,指向了同一个Object“O”c.name = “bw”trace(d.name); //不是aw,而是bw了//改变c也好,改变d也罢,其实是改变了那个“O”,因此改变c的时候,d的值也就变了。因此d.name已经被改变为了“bw”。 首先,明确一点,GC会按照一定的时间周期进行内存清理(memory sweep)。因此不要因为delete掉一个object后检查System.totalMemory内存就没有反应而怀疑GC是否正常。 那么GC为什么要按照一定的时间周期进行清理呢。这还要得从GC的具体工作原理说起。 GC的两个回收体系:1、“Reference Counting” – 引用计数器这个体系是自从AS1时代就有的体系,它的工作原理非常简单:系统计算每一个对象被指向,或者说引用的次数。比如var a:Object = {name:”aw”, blog:”www.awflasher.com/blog”};这时候,这个Object(我们仍然称为“O”),有一次引用,它的引用计数器为1(来自a)。我们再建立一个对象b,并指向到a:var b:Object = a;这时候“O”引用计数器变为了2(来自a、b)我们删除一个,比如先删除b:delete b;这时候引用计数器为(2-1=1)1,GC不操作再删除另外一个a:delete a;“O”引用计数器变为(1-1=0)0,GC出面干掉这个对象。这套体系很轻便,CPU压力较小。但是它也有缺陷。当我们的对象内部互相引用的时候,麻烦就来了。例如:var a:Object = {name:”aw”, description:”unknown”};// 建立一个对象a,仍然假设内部对象为“O”,这时O的引用次数为1var […]