Eric's profileMastersPhotosBlogListsMore ![]() | Help |
|
|
October 11 [转载] 福布斯:向硅谷求救——致技术行业的公开北京时间10月10日《福布斯》刊登了一封致硅谷技术行业领导者的公开信,内容如下: 世界需要你们。 只有你们才可以带领经济穿越可怕的海峡。 我们现在的经济局势已经脱离了华盛顿的掌握,华尔街也对它无能为力。你们应该带领硅谷同仁,勇敢地肩负起这个重任。 曾记克林顿时代? 大家都知道比尔克林顿带领美国经济走上了繁荣发展之路,但是是否有人知道上个世纪九十年代的繁荣发展的幕后功臣实际上是硅谷?本世纪初,美国经济还存在着3000亿美元的亏空,硅谷带领各行各业的企业家们已经将大部分亏空补足。 因特网创造了无数的就业机会,硅谷则通过投资赋予了因特网生命。Kleiner Perkins Caufield &Byers的John Doerr率先投资Marc Andreessen的Netscape,拉开了因特网迅猛发展的序幕,随后Jeff Bezos对亚马逊进行了投资。 紧接着,红杉资本的Mike Moritz对杨致远及合作伙伴创办的雅虎进行了投资。Benchmark的投资者在1997年对Pierre Omidyar的eBay进行了投资。正如约翰麦凯恩本周在总统竞选演讲时所说,仅eBay一家公司就支持着130万美国人的生活。 不久之后,企业家和风险资本家争先恐后地开始创办以电子商务和搜索为核心业务的公司。许多公司后来宣布破产,整个市场也在2000年崩溃。但是在那之前,一颗改变未来的种子已经种下——拉里佩奇和谢尔盖布林在1998年创办了谷歌。 在本世纪的最初几年里,整个经济一直在努力摆脱网络经济泡沫破灭以及911恐怖袭击留下的阴影。在那几年,以Salesforce.com的Marc Benioff为首的一群企业家开始积极为新的运动打基础,现在人们将这场新运动称作服务型软件(SaaS)。最近,它又进一步扩大了自己的范围,将云计算也包括进去。 硅谷的大部分风投资本金一开始都错失了商机,只有一个例外。当时硅谷的许多公司还坚持着以产品为核心的业务模式,而Brian Jacobs、Jason Green和Gordon Ritter则创办了一家名为Emergence Capital的公司。与其他投资公司不同的是,Emergence Capital主要投资服务型公司。如今,它已经称为投资界的翘首,它对创建一个欣欣向荣的经济生态环境起着至关重要的作用。在这个经济生态环境中,企业家们都根据这个趋势来创办企业,他们也因此获得了雄厚的财力支持。 John Doerr在上个世纪九十年代中期时曾说过,除了受到一些尖酸刻薄的评论之外,就没有什么关于因特网的宣传了。他是对的。 现在,我们拥有了SaaS,Web 2.0和云计算,Web 3.0也已经初露端倪。 Doerr以及他以前在Kleiner的同事Vinod Khosla还示范性地打开了清洁技术产业飞跃发展的大门。Cypress Semiconductor当时的首席执行官TJRogers也很早就发现了市场的这个发展趋势并对SunPower进行了投资,现在SunPower已经称为推动太阳能市场繁荣发展的主要厂商之一。 从电车到替代能源,从清洁空气到净水,那些早期的成就见证了技术行业创造财富的潜力。企业家们都很积极,他们将创造大量的就业机会,各种问题终将得到解决。 总的来说,硅谷技术行业的领袖们,你们已经发现了问题,找到了以技术为本的解决方案,你们不仅创办了许多企业,而且还开创了许多新的行业。 因此,我要求你们再次奋起,迎接挑战。教育、医疗、社会保险,这些领域都需要你们的声援,需要你们的智力,需要你们的可靠性,需要你们的时间和投资。 每一个领域都已经取得初步的成就。Edward Fields将通过他创办的HotChalk来解决教育界的问题。 Kirk Loevner将破解医疗行业的谜题。他们已经掌握了一些新的业务模式、营销模式和解决问题的方法,其中最值得一提的是,他们现在开始利用广告收入来购买教师、学生、医生和病人所需的各项资源。 在教育和医疗界,效率低下的情况将通过技术得到彻底改善。 如果Barack Obama成功的话,他必须协助整个行业找出从系统内部对医疗和教育行业进行改造的方法。 2007年,美国用于医疗的开支为2.26万亿美元,人均为7439美元。而美国每年用于行政管理的开支为人均1000美元,这也使得整个行政系统的成本超过了2500亿美元。 我看着这些令人目瞪口呆的数据就象是看到一个资源浪费的无底洞一样,然而这也表明技术可以对此作出巨大的改善。 教育界面临着类似的问题。行政管理费用占了大部分的教育预算,留给教师的就寥寥无几了。 随着苹果iPhone引发的智能手机热潮的兴起,我们能否在医生、患者和保险公司之间架起一座完美的桥梁,把医疗行业的行政管理开支减少一些呢? 我们能否在因特网上为全美甚至全球的教师们创建一个标准化内容和方法论的团体呢? 硅谷的技术领袖们,你们应肯定地回答这些问题。不要让目前在市场上肆虐的恐惧把你们打趴下了。 你们必须领导各行各业,你们必须创造, 你们必须建设,你们必须投资。 你们必须将美国和全球经济从华尔街和华盛顿制造的泥潭中拉出来。 我知道你们一定可以做到这一点。 October 10 Opera ...注意了不是歌剧,冲着歌剧来的朋友,可能要失望了;) 如果有人问,在网上什么最难,个人觉得改变用户体验,简单地说就是个人使用习惯是最难的,不论是客户端软件还是互联网网站,均出现过不少因为事先没有调查而擅自改变用户体验而又不得打回原型或者采用几种版本并存的案例。如今浏览器相当普遍,更是所谓未来“云计算”的最前端,这也就是Google推出Chrome的原因,与其说这是帝国主义疯狂扩张的本质,不如说这是帝国主义的野心与苦心积虑;那么对我们来说,选择一个适合自己的浏览器也是最直接和重要不过的了。之前一直用IE,从4.0到7.0,应该说有很长历史了,在IE还没有推出基于tabs的浏览的时候,用过一段时间FireFox,但是除tab以外并没有感觉有什么不同,当然有人说FireFox更快,这我并没有体验到,我想快不快还是要取决了当时的网络环境,如果说FireFox的绘制速度快,哪怕就像Chrome声称的那样,恐怕不仅是一般用户就是我这个搞计算机的也很难察觉出什么端倪,该不会告诉我去研究下gecko的绘制引擎吧?也可能有懂点互联网会说,FireFox更标准,这个我承认,但是普通用户是察觉不出来的,而且现在所有的网站设计都会兼顾各种浏览器的差异,相信这点只会吸引开发人员;当然还有很多说法。。。之后IE7的推出加上MS工作的关系,一直用IE,表现还是相当错的,也就重新坚持了多年以来的习惯,而当时FireFox以及我将说的Opera(当然还有Safari)都是作为测试浏览器,甚至当时Opera和Safari都是被作为低端浏览器来测试的,所谓低端是指只需要支持基本的功能和操作就可以了(当然也有对search engine及SEO的考虑),用过Spaces和Hotmail低端版本的用户应该知道,后来也就一直沿袭了这样一种观念,认为Opera就是一个不起眼的低端浏览器产品。但是这种观念又在不经意间被改变了。 记得当时在为我们的平台决定支持哪些浏览器(browser matrix)的时候,我严格的遵循了MS的Guidelines,选择了IE6+和FireFox2.0+,Opera和Safari被列在计划支持中;可能这并没有什么问题。不过有一天我无意间在Opera中运行了下,出来的结果完全出乎我的意料,绘制结果和IE, FireFox毫无二异,于是我看了下Opera版本,果然已经是9.0+了,我非常高兴,于是当时无条件将Opera9.0+加入到先前的Browser Matrix中。之后尝试使用Opera,发现9.0之后的版本真的挺好用,比如内置Mail,RSS Reader, NewsGroup, Notes,Mouse Gesture,Developer Tools,Gadgets/Widgets的支持,Speed Dial,Top-N Bookmarks, 等等,此后一直使用。从选择浏览器的角度,就像女孩子挑衣服,总得多比较多圈点才会确定最终适合自己的,那么,哪些因素影响了浏览器的选择,个人认为无外乎几点,功能,网页打开时间(PLT),稳定性,安全性,资源(i.e., CPU和内存)利用率,标准性,可自定义和可扩展性。 功能方面,主要功能大部分浏览器都具有,比如书签,历史,RSS等,不过Opera内置对Email以及Outlook风格的RSS reader,Notes和Memo,鼠标手势(Mouse Gesture)的支持,这样你不用安装Outlook或其他客户端,也不用打开网页就可以实时得到Email以及RSS的提醒(当然你得打开Opera),不用再用Notepad记录一些短小的便签和备忘录,你甚至可以以目录的方式管理他们,Mouse Gesture是个好东西,如果习惯了可能你再也离不开了,鼠标右键向不同方向以及方式的移动可以完成大部分用键盘,单击和双击完成的常用操作,应该是相当方便的,最开始看到这个还是同学用Maxthon的时候,可能这对于经常看BBS的用户更有帮助;)有几次在IE和FireFox中使用起鼠标手势来,还是习惯惹得祸!当然,IE和FireFox也是可以使用Mouse Gesture的,不过需要安装相应的插件。Chrome听说好像已经有Native支持了,没有研究过。 PLT方面,可能这在所有的浏览器中的差别并不大,就像我前面提到了,这方面的差别还是主要取决了网络环境,比如说带宽,网络拥塞程度等等。不过感觉Opera和Chrome的下载速度确实要快一点,至于绘制速度是完全体会不出来的,可能找个比较低端的电脑可以测出来! 稳定性方面,这方面FireFox和Opera做得都比较好,倒也不是因为经常Crash的原因,而是当程序Crash以后,之前所有打开的网页将会被保留并在重启浏览器时恢复。在这点上,IE是做得最差的,严格说是完全没有做,大家都摸不着头脑,这并不复杂的东西为什么MS一直不做,搞得我在使用IE的时候,还自己写个插件来搞定!另外,浏览器的稳定性主要跟插件有很大的关系,插件装的越多,Crash的概率也就大很多,除此之外,对于Release版本的浏览器来讲,应该都是没有大问题的,那么多tester也不是吃干饭的!;) 安全性方面,这是个非常有争议性的话题,我相信这世界上绝对没有绝对安全的系统,因为一个Program每一行都可能有一个bug,而一个系统一个软件是由成千上万个Program造出来的,你能说没有漏洞?人们常说Linux安全,可我觉得Linux安全是因为是其“非主流”的特征,当然这可能有些片面,但是反过来来看,如果Linux和Windows互换地位,你难保没有用户天天叫Linux太不安全,所以表面上看,Windows很不安全,其实是全球90%的用户在帮助完善Windows,可以预见Windows在安全性方面能做得更好。更重要的是,安全性应该是技术(即软件和系统本身)和社会工程(即终端用户的安生性意识,知识和培训)的完美配合才能提高的。有点扯远了,浏览器方面,如果以我刚才的逻辑,我认为Opera更安全,因为Opera在PC上只有5%左右的市场占有率,不知道有没有人愿意在这么小的市场上搞点破坏。当然,如果有一天我在Opera中招了,或许我的这种判断会大打折扣,我想不仅是Opera,就是声称安全性最高的FireFox,如果有人中招超过3次以上,不知道其心目中的安全性会不会有所折扣? 资源利用率/效率方面,这一点我可以告诉大家,Opera的测试结果是最好的,虽然没有标准的Benchmark用作测试,不过某位勇士曾发扬了愚公移山的精神凭是测出来Opera的表现是最好的,特别是在内存使用方面,当然目前的电脑配置对于这方面的差异基本上可以忽略了,不过对于对内存和CPU“斤斤计较”的朋友来说,还是得考虑下。;)另外,在没有插件的情况下,IE的表现超过FireFox. 标准性方面,IE可能就要退位让贤了,不论是CSS,JavaScript还是W3扩展都支持的不是很好,这是历史的原因,想当初IE独霸江湖的时候,谁想到有一天要被迫标准化。不可否认,标准是很好的东西,就像是斯诺克和美式台球一样,美式台球的规矩是大家来制定的,而斯诺克不行,你们都得按我这个来,其他免谈,所以跟别人打球,美式的话,你首先得要问清楚他们的规矩是什么样的,而斯诺克上去就可以打,快哉!标准能使大家之间的沟通和交流更容易,拿到浏览器上,就是免除了开发人员考虑差异性的苦恼。但是,这一点对于普通用户来讲是不太重要的,除了一些老的网站以外,目前大部分的网站都是考虑这种差异性和兼容性,只是开发人员的任务重了点。FireFox对标准的支持是最好的,Opera走了中间路线,对IE那一套和标准的支持都有。ACID(http://en.wikipedia.org/wiki/Acid_test)测试表明,Opera的表现是最好的,在ACID3的测试中超过了其他所有浏览器,足可见其开发团队在标准化方面下的功夫! 自定义方面,Opera绝对是最好的,整个浏览器从界面的排列,皮肤等等都是可以根据个人喜好自定义的。 可扩展性方面,Opera稍微差点,而FireFox因为其插件系统的低技术门槛和开发的简便性使其拥有为数不少的优秀插件可供选择,这也是FireFox爱好者选择FireFox的另一个很重要的一个理由。而IE的插件也不少,但其开发成本比较高。 好了,写到这里,可能大家都看出来了,我是比较推崇Opera的,不过放心,我不是Opera的托,大家选择什么这是大家的自由,更重要的,还是那句话,习惯的问题,我想很少有用户愿意改掉长期以来的使用习惯吧?只不过是我的一点体会,没什么技术含量,完全是瞎扯淡,不过绝对原创!;) Opera是挪威的一家公司搞的,有10几年发展历史,在移动浏览器市场占有较大市场份额,想要尝试的朋友可以从http://www.opera.com下载最新版。(附了几张Opera的图) November 25 Javascript - Memory Leak Analysis and SolutionsMost of the origins for such kind of leak are circular references.But where are the curculare reference from?So,first I want to briefly talk something about
the Browser with script capability implementation,where much more specific to Internet Explorer.As is known,browser usually consists of several
components/modules,such as HTTP(s) Client Protocal Implementation(also others like FTP,GOPHER,.etc.),HTML-CSS Implementation,W3C DOM Implementation,User
Interface/Interaction Driver,and of course Script Engine in the ones with scripting capabilities,and some other extra components.For memory management in
IE,basically,the Script Engine uses Gabage Collecting technologies to manage the memory allocation/deallocation,life time control,currently,the mechanism of
which is mark-and-swep based,much similar to .NET GC implementation(see also artical here
http://blogs.msdn.com/ericlippert/archive/2003/09/17/53038.aspx),however,the other components of IE Core especially the DOM is implemented via COM,thus the
memory management follows the general COM objects way,that is to say using IUnkown interface to manage the reference counters to COM objects by calling the
AddRef and Release interface methods.In our Javascript programming,we are usually brought to the senarios where we manipulate DOM tree using
Javascript,therefore,our focus is the memory management for the Script Engine and the DOM module.Generally speaking,thought the memory management mechanisms
of them are quite different,however,there is not serious problem about the individual memory management of either Script Engine or DOM,and we needn't
consider much about the memory leak problems,given the assumption that either GC or COM can manage the memory in a correct way on behalf.I've mentioned that
the circular references are the main origin to leak,but it's not a problem for objects compeletely scoped to script engine,because the GC can handle such
kind of circular references in a proper way,say the memory engaged in circular references can be released properly by the GC.So in which situations,the
circular reference can cause leak?The answer is circular references betwwen Script Engine objects and IE Core,esp.DOM,objects.This artical (see also
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ietechcol/dnwebgen/ie_leak_patterns.asp)has talked much about the patterns that produce
circular references and some other none-circular-reference-based memory leak patterns.Now here,I want to explain some more details about these patterns here.
1.Explicit Circular References produced by Expando-Properties between Script Engine and DOM. Considering the following sample code: function ElementChain() { this.elHead = null; this.elTail = null; this.addToEnd = function(el) { if(!this.elHead) this.elHead = el; if(this.elTail) this.elTail.elNext = el; this.elTail = el; el.elNext = null; } // some other code,including the clean up code } we can use the ElementChain class to build an element chain.Notice that the element that is treated as the chain node has an expando property named elNext,which records the reference to the next potential element.So this kind of code can cause leak as long as there is a circle in this chain and the
circle is not broken up manually by the clean up code.We can get advantages from using expando properties,because we can easily get access to either the
element itself and the associated extented functionalities of it.This pattern,sometimes is easy to detect for example in this chain-based scenario,but
sometimes is much difficult to find out.We should be carefull that we must explictly release the reference from Script Engine to DOM objects in the correct
time.For this example,we just need to give another function to clean up the chain in this way:
this.dispose = function() { var pNode = this.elHead,pGuard = pNode; while(pNode) { pGuard = pNode.elNext;pNode.elNext = null;pNode = pGuard; } } 2.Implicit Circular References produced by Javascript closure. As is known,in Javascipt,we can use nested functions in many scenarios.Formally speaking,this is called lexicial scope technology,which can produce the scope chain and the corresponding closure,and where the function is executed in the memory context of 'declaration' time instead of 'calling' time.Quite different
from the C++,or C#?Now,first,let's take a look at a more meaningful sample,in our application,we usually need do the event handling frequently,especially the
user interface events and,traditionally,we just give independent event handler for each kind of event,for example:
function elOnmouseover_EventHandler(ev){...} function elOnmouseout_EventHandler(ev){...} el.attachEvent("onmouseover",elOnmouseover_EventHandler); el.attachEvent("onmouseover",elOnmouseout_EventHandler); // or el.addMouseEventListener... in Mozilla Browser Event Model // and in somewhere else,we detach the event handlers from the element like: el.detachEvent("onmouseover",elOnmouseover_EventHandler); el.detachEvent("onmouseout",elOnmouseout_EventHandler); However,if we have so many events happening on so many different elements to handle,what should we do?write so many event handlers for them?Of course,we can.But it's much more boring than you can imagine.So,we can leverage the lexicial scope technology of Javascript.We can use some factory to create event
handlers for different events,seeing below:
var EventHandlerFactory = new function() { var scopeMgr = new SomeScopeManager(); // scope manager to scope events,impl. omitted. this.dispose = function(bFinalize) { scopeMgr.dispose(bFinalize); if(bFinalize) scopeMgr = null; } this.createEventHandler = function(el,eventType) { var scopeObj = scopeMgr.CheckForScopeObject(el,eventType); // scope object for the element function eventHandlerInvoker() { switch(eventType) { case EventType.MouseMove: if(scopeObj.scopeElement == /*someSpecialElement*/) { // handle the event for the element here } else if { ...} ... else {... } break; case EventType.MouseOut: if(scopeObj.scopeElement == /*someSpecialElement*/) { // handle the event for the element here } else if { ...} ... else {... } break; // some other cases default:break; } } scopeObj.eventHandlers.push(eventHandlerInvoker); return eventHandlerInvoker; } this.getEventHandler = function(el,eventType) { // query scope manager to find the event handler,omitted here. } this.attachEvent = function(el,eventType) {el.attachEvent(eventType,this.createEventHandler(el,eventType);} this.detachEvent = function(el,eventType) {el.detachEvent(eventType,this.getEventHandler(el,eventType);} } now,we can change our code to be like this: EventHandlerFactory.attachEvent(el,"onmouseover"); EventHandlerFactory.attachEvent(el,"onmouseout"); // in some where else,we can either clean up all of the event hooks by calling EventHandlerFactory.dispose(true or false) or can detach event handler for some event of some element by calling EventHandler.detachEvent(el,"onmouse***");
Compared to the previous way,by using lexicial scope,it has become much more convenient,right? But this can easily contribute to memory leak if not put into a well-managed way.Taking a look at another simple example below: function attachEventForElement(el,eventName) { el.attachEvent(eventName,closureEventHandler); function closureEventHandler(){} } The closure event handler may leak,why?Seems that,there is no circular reference,then how comes the potential leak?To understand this pattern,we need understand the function implementation in Javascript.Simply speaking,in Javascript,function is first-class object,say we can use function in the same way as
that we use general objects,for example,we can assign it to other variables,we can access its properties,we can extend its prototype,and we can call its
methods.These are only the visible nature exposed by the function object(instance of Function),and additionaly,function object has its own internally-used
properties and objects.I've no idea about the every details of the Javascript implementation,however,in my opinion,it has at least another three internal
properties,which are the scope object,which is generated for each function when it's called,the parameter/local-variable table,and the code property that
tells the code text of the function.Now,what happens if you declare some function?actually,we should differentiate javascript function declaration from that
in C++,because in C++,we declare function at compile-time,telling compiler to generate binary code for it.however,in Javascript,function declaration will
help the parse-phase internal table generation and create an instance of Function in the runtime-phase,after the function instance is created,the parameter
and local variable table will be initalized,but it will not be executed until it's called by others.When it's called,a scope object is created for it,and all
of the paramters and local variables will be attached to the scope object with the runtime values.This process applies to each function without exception.So
in the above code,We can see what happens when you call attachEventForElement function,first,scope object is created,then el,eventName are attached to the
scope object,then it comes across a nested function declaration,then it creates instance of the nested function and initialize it,which is actually just a
local variable for the function scope,then return from the current stack.Is that all?Absolutely NO.There are still some mystery about it.Generally
speaking,the local variables' lifetime is less than or equal to the callee function,that is,they will be released once the function call ends.
however,if the local variables are reference by external objects,what will happen?Like just the closureEventHandler,it's just a local variable,but it's attached to the event handlers collection of the element,i.e.,it's reference outside the function,when the function call ends,the closure function will not
be release until it's detached from the element,and still,the closure function should hold the access to parameters and other local variables in the parent function scope,but the parameters and other local variables will be released normally after the function call ends without any additional work done to them,which will cause the accessibility problem for the closure function.To solve this problem,if the closue function object is referenced by the external objects,it will add references to the parameters and other local variables in the parent function scope.In this way,we can see that the nested function's life time has exceeded the life time of the parent function,and that's why this kind of function is called closure.After this analysis,you can understand why there is implicit circular reference here,right?OK,to solve this problem,also,we need be much careful,when you're programming.We can use some mechanism to manage this kind of scope issue,just like the EventHandlerFactory does,which can prevent memory from leak. For other info,you can navigate to the above links.That's all. Memory Leak Problem Discussion in JavascriptRecently,I've being busy on some new project relying much on AJAX-like techonologies,say relying much on client Javascript.Everything is OK in such a process,and many attractive features have been implemented via over 10,000 lines of pure Javascript code and I've tested them against the performance issues.Seems I've put everything in my control,even proud of it.However,Is that indeed the truth?Actually,the story happened later surprised me so much.One day,I opened my project in IE and opened the Windows Task Manager meanwhile,because then it seemed that some voice was telling me repeatly that I need check the memory consumption status.Then I found that each time I refreshed the page,the memory usage was increased by nealy 2M,and when I refreshed the page for serveral times,the memory had easily gone to quite a high point.Then I tested the so-called attractive features again,and I couldn't believe that the memory was crazily increasing.I could not sit there for some coffee any longer at the moment.I must find the underlying reason that caused the leak problems ASAP.Then I remembered some artical talking something about the memory leak pattern of Javacript,I got it out from my favorite folder and read through it.As expected,I've overlooked many leak points while programming javascript.Looking backward,I just feel so incredible,and even after over tens of thousands of codes.But I must fix this leak problem,otherwise I can not sleep so well as before in the night.In my next blog entry,I'll share the knowledge related to such kind of issue with your web developing folks. |
|
|