那一剑的风情
百度首页 | 百度空间
 
文章列表
 
2008-05-11 20:22
    连续不断的工作了快4年后,终于辞职了,暂时结束了每天上班生活。而在前几天,受吕欣欣同学的影响,我也买了全套金庸新版武侠小说,所以辞职的日子不怕无聊。不过更重要的是,在这段时间里休养生息,锻炼身体,系统的巩固自己所学,并且重新思考以后的职业发展。

    我记得第一次去上班是在2004.6.28号,不过第一天去只是去清理一下办公室,真正工作是在7.5号。那时候我还没没毕业,大三暑假,这叫做:初出茅庐。一开始参与做的是一个电子商务网站项目(一个大公司的商城频道,具体哪个我就不说了),技术人员总共5个,其中包括一个架构师。项目开始,我很是兴奋,自学的知识终于可以用于实际生产了。当时项目采用asp.net/c#开发,而我那时候的web开发经验几乎为0,仅有的只是少量html知识,但是在实际项目中,我却并没有因为技术问题而拖后腿,从这一点我就感到:学习能力才是一个技术人员根本的能力。一个项目下来,我学到了很多知识,并且也培养和他人沟通交流的习惯。那时候我常常上csdn,去论坛上回答问题,记得当时写了一篇关于存储过程的文档还上csdn首页,心里真是高兴,呵呵。在项目中,我会突然找到边上一个同事请教或是探讨,那时候我还为了直接使用SQL还是使用存储过程和一个哥们争执几句,事隔2年多后,他msn跟我聊起来还提到:那时候你说的道理是对的,但是实际还是应该使用存储过程,我不禁微笑。

    我真正开始自学编程是在2003年初,一开始学习vc++(MFC),那时候成天泡在学校论坛的编程板块、CSDN等地方。不过那时候我学习进度太慢了,一个人学习,并且是最初学习编程,身边并没有人探讨。终于在半年后,我用vc编写了一个完整的程序,ftp客户端,完成了基本的登录登出、目录浏览、上传下载、断点序传等功能。那时候我们计算机系的学生正在进行小学期试验,也就是几个人在一起做一个项目,我们组做的是一个小型文件系统,最终程序圆满完成,不过我由于忙于自己的ftp客户端,在小学期的项目中只是参与了部分设计和开发了输入输出接口(Console环境下)。之后我继续学习关于vc++知识,直到有一天我上铺的同同学劝我学习c#,并且给我演示用vs.net开发c#程序,我看过之后,只能用一个词来形容:太酷了,那感觉就像一直以来用破手机的人突然看到了新的iphone一样...。于是我马上投奔了c#怀抱,我在看了几天c#语法书之后开始着手编写一个单机的俄罗斯方块游戏,一周以后编写完成,也没有什么bug,现在来看,那个程序都还是一个比较满意的作品。从此之后,我得益于c#语言功能强大和vs.net开发环境的便捷,我快速学习了很多东西,比如窗口界面、网络编程、多线程、web service、数据库编程等,我还清楚记得2003年暑假,我和上铺的那个同学一起学习编程一起玩游戏,每次通宵到第二天清晨然后去餐厅吃早餐,然后回来上一下所谓的“清晨网”,之后睡觉到下午,真是段快乐的时光。

    刚毕业时找到一个做企业项目的公司,后来转型作外包,于是自己被外包出去到别的公司写程序,工作是把用c++开发的程序(桌面段程序)移植到c#上,一个team 80多个人,计划周期1年多,我在里面做了一个小组的实际的leader,不过那时候干的并不开心,我很快辞职了,进入了毕业前兼职的公司。之后的时间,我所参与的都是web项目,web开发经验也就从这里积累、增长。在入职后不久,我看公司里面所有的人开发数据访问层的时都自己写很多ado.net代码,非常的繁琐,那时候部分还是采用了微软的Application Data Block。但是那时候流行ORM组件,特别是java里面的hibernate,如日中天,而在.net里也出现了nhibernate。我特意去了解了一下hibernate,遗憾的是一开始就被它繁琐的配置文件给吓倒了,于是有了自己写一个ORM库的想法。有了想法就开始做,业余时间我自己从设计到开发,大约1个月时间完成了基本的雏形,完成所有的测试后,我编写了一些简单的介绍和入门sample发给项目组的其他成员,但是大家对这个都并没有实质的兴趣。直到公司开始做另外一个项目,开发快要结束时,客户方指出,我们的代码根本不是面向对象的开发,很多数据实体都采用hashtable的结构来传送,要求我们重新开发整个系统。而在我的极力推荐下,再次开发中采用了我设计的那个ORM组件,在项目期间我完善了很多特性以及大量的细节,并且最终保持了这个库的简单易用,同时一个同事帮忙编写了一个代码生成工具(生成实体类),开发进展的很顺利,很快项目就开发完了。一直到后面我参与的好几个项目里面都采用了那个ORM组件。做这个东西给我一点感受就是:作基础的组件对人技术的要求远高于做应用系统。在基础组件里面,对待接口和代码的稳定性绝对不能有一点疏忽,为每一个公开接口编写一个测试用例是一个明智的选择。

    2006年出,公司正好开发一些web2.0应用,这时候我已经成为技术leader。当时国内正流行ajax,于是在我们项目里面,ajax也被大量使用,那时候我才真正感受到javascript(一直以来被开发者们不怎么重视的语言)的强大,在一个纯js的webos和一个rss阅读器的中,我开发了绝大部分js代码,掌握了大量js已及css兼容性细节问题。在2007年时,由于公司项目原因,我转移到了lamp平台进行开发,有意思的是,由于项目中的实战经验以及在实际生产环境中的锻炼,现在我已经觉得我对lamp的熟悉已经超过windows+iis+sqlserver平台。

   在学校里面,我接触过asm、c、c++、java、html,然后又自学了c#、javascript、actionscript、php等语言,到现在我还没有感到一种让我满意的语言。asm就不说了,c/c++光一个内存管理问题就让人崩溃,并且c++也太复杂了。c#是我一开始喜爱的语言,不过现在也越来越复杂,和java一样,和动态语言比起来灵活性差的太多。javascript倒是干净,但是他缺乏面向对象支持,未免遗憾,这点上actionscript好的多。而php中的面向对象中途加上去,总感觉很多地方不是很好,并且目前还不支持unicode。其实每一种语言都很不错,都在各自的领域工作的很好,并且在一个复杂系统中,搭配使用多种语言基本是少不了的。不过一些编程的规范性问题也就随之而来,终归没有一种语言来的得心应手。我希望有一种语言:既有静态强类型语言的性能和编译检查,又有动态语言的灵活,并且尽量简单的语言特性和尽可能多的库支持,也许我只有做梦了:)。基本上每一种语言都越来越复杂化,而各种各样的框架也不断产生,而我却越来越喜欢简单,我深信,解决问题的不是复杂而是简单。而在开发中,除了平台原生的不可避免的框架外,我不主张采用其他任何框架,我更喜欢的是设计简单灵活的结构来容纳各种各样的功能库。刚毕业时,我花了很多时间去了解设计模式,不过到现在我基本上心理面已经没多少模式了,而记得的只有一点:简单。

    在实际工作中,我发现能真正写出高质量代码的人不多。大部分人水平都还是很不错的,但不知怎样,能产出高质量代码的人确实不多。我认为主要的原因还是一个心态和方法问题。正确的可靠的方法和平稳扎实的心态都是写好代码的必要条件,比如开始动手之前先经过全盘的考虑和设计,技术难点应该先突破,每一个细节都要仔细考虑它的影响,完整的测试等。一个人写代码就像做人,如果能够扎扎实实一行一行写出好的代码,细心不急躁,那他也基本上是个比较可靠的人。

    在工作的过程中,我曾经迷茫了一段时间,感觉自己不知道怎么提高了。后来慢慢发现,我在技术上一直在追逐一些表面上的东西,比如追求对一些语言的了解,对一些库和框架的了解,这样终究会遇到发展瓶颈。于是后来我着重了解一些低层平台的运行原理,学习一些框架的设计方法,也陆续看过一些原代码如asp.net forum、.text、mudos。以前听人说一个oracle专家通读了所有的oracle帮助手册,于是我也效仿,打开SQLServer联机帮助,从头开始读。这确实是一个合不错的方法,从帮助里我了解了大量sqlserver的实现原理,这对于数据库优化和管理相当有用。以至于后来学习mysql,我也是从头看mysql的帮助手册。现在觉得,真正能限制自己发展的就只有自己。一个人要常常总结反思自己,并且要一点一滴的巩固自己的知识和技能,这样才能让自己掌握的东西想滚雪球一样,越滚越大。
 
2008-01-21 14:33
    当为web服务器输出的内容指定Content-Type为text/html时,浏览器会对内容做一些额外的转换工作,比如"""这样的实体形式就会被替换成最终的字符(双引号")。这在普通情况下并不会引起什么问题,但是不幸的是如果你采用了JSON格式来传输数据,例如:{status:0;data:"content"data"}这样的格式,当"被替换成"后,Javascript就会得到一个错误的数据格式,因为这时候Javascript拿到的数据就变成了{status:0;data:"content"data"}。

    这时候,你可以设置Content-Type为text/x-json来解决此问题,但是text/x-json有可能引起一些浏览器兼容性上的问题(一些浏览器会提示下载Content-Type为text/x-json的内容),而更好的做法就是设置Content-Type为text/plain。不过即使这样也并没有完美的解决问题,考虑这样一种情况,你需要上传文件但是你并不想刷新上传页面,这时候一般的做法就是让form的target指向一个Iframe,代码如下:
    <form target="iframeId" method="post" action="accept.php"><input type="file" /></form>
    当accept.php接收请求并处理完成返回一段JSON数据后问题就发生了,因为accept.php输出的内容被定向到了iframe,而在iframe里浏览器会自动地给数据上加上<pre>标记,这时候JSON又出现格式错误了。

    最终的解决方法就是,在JSON传输时指定Content-Type为text/plain,但是遇到上面提的文件上传情况,就应该指定Content-Type为text/html。


   
 
2008-01-03 19:10
    软件质量、软件测试一直是软件开发重点关注的领域,市面上相关的理论以及最佳实践等数不胜数。但是“软件就一定有bug”这句话是没错的,因为你无论采用了什么方法、投入了多大的资源来确保软件质量,但始终还是避免不了在生产环境中出现或大或小的bug。

    在现实项目中,就我理解或者从别人那里了解到,软件的测试肯定达不到100%覆盖率。或者是项目没有那么多的资源来做100%覆盖率的测试,或者是软件本身不值得做那么完备的测试。如果有bug,那么bug是肯定会被人发现的,bug浮出水面后,你就不得不动手解决了。

    出了问题怎么办?

    我凭自己的经验来谈一谈怎么解决实际生产环境中的软件bug。

    首先bug被报告上来时,你应该尽可能的掌握问题出现的场景,如果能够亲自观察bug现场就更好。而这时候一般你可以凭经验解决掉问题。(我遇到的大部分问题就是这样解决的,经验不可靠但是很有用)

     几个总结:如果问题总是能够重现,那么一般是软件上的逻辑错误,分析代码就能解决问题。如果问题时而出现时而不出现,那么一般是代码对各种输入的临界条件“兼容性”不够,改进代码就能解决问题。

    如果代码看上去也没有问题,那很可能是代码运行所需要的参数不满足。比如参数配置丢失或者错误,代码依赖某一个文件不存在或者目录被意外删除,或者代码所依赖插件版本不对等都是可能导致问题的,把这些问题就检查一下,有可能会有意外的发现。

    当然,最直接有效就是在程序里输出尽可能详细的Log,每次出现问题的时候你都可以查看Log,并且很快能确定问题。当然具体Log的详细程序也要视乎情况,一般来说每次函数的输入很返回值写入Log,另外所有的出错信息、SQL语句和参数写入Log基本就可以了。在一般的大型系统中,Log模块都是比较强大的,你可以根据需要动态调整Log记录就可以了。

    如果经过上面几步,你还不能解决问题,那么先别急,你应该先喝口水,放松一下,然后召集项目组的其他一个或几个成员(根据需要而定),并且把你了解到的关于这个bug的情况详细告诉他们,然后一起分析问题。群众的力量是强大的,更多的人可能会考虑到你从不曾想到过的问题。
    到了这一步BUG一般都不简单,你先可以和其他人一起分析代码的逻辑模型是否有问题,如果还是没法发现问题所在,那么你可以大胆怀疑一些基础软件比如基本的库函数、数据库、WEB服务器等是否有问题(特别是你不是特别掌握的东西越有可能发生问题),然后对怀疑的地方逐个测试。到这一步,基本上你就会解决问题了。

    上面的解决思路算是一种比较规规矩矩的做法,它确实有效可行,但是也有可能会花掉你很多时间。如果你一时半会儿不能确定问题的原因,那也许你可以换种思路。你可以完全不必管现在出问题的代码,而你只要花一点时间,用更加清晰的方式再写一遍代码,这样可能会让你更加迅速的解决问题。


    bug总是存在,但只要你想,bug就会被解决。
    吸取经验,总结问题是很重要的。




 
2007-12-21 16:37
    首先申明:下面的例子在性能优化上追求的有些极端,很多时候不是必须的。

    一直在项目里面实用JS里的replace来替换字符串,其中一个功能是根据html模版来构建一个完整的html代码。类似如下方式(代码1)
   var template = ' <div class="block" id="{itemId}"><div class="title" title="{title}">{title}</div><div class="description">{description}</div></div>';

    而在js里面先创建一个数据对象(代码2):
    var data = {
       itemId:11,
       title:'title',
       description:'desc'
    };
    然后再使用String.replace方法替换模版(代码3)
    foreach(var p in data){
       var reg = new RegExp(p,"ig");
       template = template.replace(reg,data[p]);
    }。

    这样使用了一段时间,但是发现界面显示的时候一直不怎么快速,于是用Firebug仔细分析了一下,发现:原来在界面显示包括构建html数据时(代码3)和把html设置到容器的innerHTML上时都不够快。他们所花的时间甚至有超过数据请求本身1-2倍的。

    后来经过一阵分析,然后尝试了对代码3做优化如下:

       //先把模版按照占位符拆分成字符串数组:
        var lines = template.split(/{|}/);
       //然后循环替换占位符
          var len = lines.length;
          for(var i=0; i<len; i++){
              var k = lines[i];
              var v = data[k];
              v!=null?lines[i]=v:""; //这里的优化技巧请参照我上篇Javascript性能优化[实例]
        }
        template = lines.join("");

    经过此优化后,JS性能至少提高2倍。

    整个页面显示速度得到明显改善。

    另外发现IE和Firefox不一致的地方:
    用template.split(/{(\w+)}/)得到不一样的结果,各位有兴趣可以试一下,看看有什么办法避免这种情况:)

   
 
2007-12-15 14:27
        有谁知道像Google,Baidu等搜索引擎的索引数据怎么备份么?
        以及一些RSS阅读器里面的Feed和文章数据怎么备份?


    他们都有一个共同点就是数据量大,而大数据量下的数据备份绝对成了一个很大的挑战。在SD2China大会上,钱宏武谈到他在做搜狐社区产品的时候的一个关于数据备份的事。产品刚上线的时候他设计一个数据备份方案就是每天下午4点作一次全备份。这个方案在系统顺畅的运行了一段时间后出现了问题 ,因为太多的数据导致系统已经没有能力一次备份所有的数据了。

    据我了解到的一些信息,数据量达到相当级别后,冗余的存储代替普通备份是一个不错的方案。也就是说,任何数据都不备份了,但是必须存储2个或者以上的副本,而主数据和副本数据几乎是实时被存储的,这样基本上在故障时数据丢失为0。这也是常说的双机热备的一个方案吧。虽然搜索引擎都不用数据库,但是冗余存储方案道理也是一样的。

    拿Mysql来说,Master->Slaver结构应该最常用到的,在很多WEB2.0站点,单Master多Slaver结构、其中一个Slaver用做数据备份似乎已经成了标准设计方案。

    其实Master->Slaver这种结构用于备份也不是没有缺陷,当出现人为的误操作而导致数据被修改或者被删除,那么Slaver的数据也会受同样的影响,这样的操作时不可恢复的(当然,这也许不全是数据备份的事情)。在Mysql中,我认为备份Binlog是一个解决此问题的办法。分析Mysql的Master->Slaver的实现,发现其实Slaver也是从Master的Binlog中读取SQL语句来执行的(不包括mysql5.1的基于数据行的复制),那么我们可以设计这样的一个备份程序:
    1、实时读取主Master的Binlog,根据一定的过滤逻辑来过滤不正常的Update/Delete语句。
    2、得到过滤好的SQL语句,传输到备份端数据库执行,得到一个完成的数据库。
    3、恢复被人为误删的数据,在备份段导出数据然后在生产环紧导入。

    以上是我的一些浅见,大家仍板砖!

PS:问个问题,Master->Slaver结构中,如果Master突然挂了,怎么能尽快地恢复?
   
 
2007-12-02 16:45
     大会的具体情况就不说了,相关的报道不少,从大会中的收获也很多, 下面谈一下会后总结到的东西。

     系统设计,一般只为当前的系统需求或者可预见的未来的需求作设计,一个原则就是先解决好最关键的功能需求,并且最多只为用户增长5-10倍做设计。这点很好理解,因为为那些不知道什么时候才有的功能作预先设计实在是费力不讨好的事情,但是这并不表示瞎设计一通,系统足够的扩展性是必须的。举个实际的例子,在一般很多互联网WEB项目中,数据库系统都会随着用户量的增长而产生单点压力瓶颈,而最普遍解决问题的做法就是根据用户的ID来对用户数据库进行分割,然后把他们部署在多个服务器上来分担压力。而走到这一步一般都是用户规模增长到了一定程度,比如100w的时候。如果在网站在上线时就采用此种方案,恐怕系统复杂度都会增加好几倍,而开发人员都要多几倍的时间来处理这些复杂度,但是却没有应有的收效。还有一种情况就是心理可能想到一个什么样的功能以后也许要做,所以现在就把数据结构设计了,一下子多处了很多暂时用不到的字段,其实这些字段对现在来说是很大的负担,并且这些字段以后会不会用到还很难说,千万不要干傻事。

       大会中学到一句话:设计就是一本艺术,关键是做好资源的平衡。

       作系统设计的时候,满足基本需求的设计是最基本的,但是系统中还有很多不良用户以及很多不稳定的因素,对付这些不良用户和让系统稳定也是设计的很大一部分。比如很多恶意的注册、登陆密码的暴力破解、高消耗操作的频繁调用、业务规则漏洞利用等,这些都需要设计时考虑到怎么对付,而在那种有利益产生的系统中,黑客攻击和用户作弊也是非常频繁的,有时候这些因素可能成为你系统设计的关键考虑因素。

       系统监控是相当重要的,监控能帮助你掌握系统运转的各个环节,让你对服务器的管理和部署得心应手。举个实际的例子,最近我们的一个系统中注册连续几个小时无法进行并且没人发现,最后被老板看到而导致他大为生气,而这样导致的损失也是很大的。这是相当糟糕的一种情况,如果能在应用中能够加上一些错误报告之类的措施,那么此类问题应该很快会被发现并解决。

        常见的系统监控方案如监控cpu/内存/磁盘/网卡流量以及数据库和WEB服务器等,相关的软件已经不少,搜索以下就能找到一些。而对网站访问速度的监控方面的监控可以使用某些专业的监控网站提供的服务,他们能从各个线路来探测你的网站速度。当然除了这些之外,应用上的监控则需要自己开发相应的程序了。
        简单总结了一些方法和技巧:1、伪装成用户来检测网站的逻辑。如果网站逻辑比较简单,那么你的监控程序可以伪装成正常用户来探测你应用的逻辑是否正确,这样可以尽量保证随着网站不断发展的情况下,网站里面的一些应用逻辑问题也能够被及时发现。2、检测数据库连接错误、SQL语句错误、文件操作错误、Socket连接错误等此类问题都可以通过在应用中插入相关错误报告代码来让问题及时被发觉。

    监控很重要,而对问题的预防也是必不可少的。你应该经常去检查服务器的健康状态,如果局部出现了问题或者有出现问题的前兆,那么你应该把那些问题处理掉,然后再提供正常服务。这让我感触比较深的就是云风介绍网易游戏服务器的维护方法。他们的做法是每周停止服务并检查服务器的状态,如果出现问题就把出问题的服务器修好,然后再启动服务,他们不做双机热备和集群之类的方案。当时听起来觉得很不可思议,其实想想,在用户能接受的情况下,这样也很好,系统部署的费用会低很多。如果说用户不能接受停机,那么你可以部署一个集群系统,然后定期对集群系统的每台服务器进行检查也是可以的。

    还有系统扩容方面的一些方案,具体扩容本身的一些问题最新的程序员增刊和DBA Notes上已经介绍了不少。还有一点需要提一下的是不要等到需要扩容的时候再去考虑,而需要事先考虑好并预备好空闲的服务器,让它随时ready,否则真遇到突发问题就会让你很难看。

    流水账就先写这么多了,下一篇可能写一些数据备份方面的想法吧。



   
 
2007-10-10 10:01
BANG6052B138F527216FEAA78D9AXIANGUO

鲜果认领频道

    真正高性能的场合很难利用xml,xml占用空间大,解析慢。结构不适那么复杂的话存储还是用自定义格式的要好一些。最近刚刚把一个用xml存储的换成用自己的格式文本存储的,性能提高好几倍。

用文件来代替数据库作存储,需要注意的事项有:

1、是否会产生很多文件。如果产生相当多文件的话(比如1000w),结果很难看。
2、并发访问和缓存不好管理。这两点应该是数据库的强项。
3、文件中的数据是否需要修改。如果有修改,并且修改的情况还不少,比如文中提到的说的论坛的回帖,那么麻烦事就还很多。比如删除一个回帖所带来一个帖子中所有分页的修改,处理起来还是很麻烦的。

一般用xml文件存储都是临时的,最终的数据还是在数据库,以便备份/恢复数据。
就像门户网站的那些新闻页,或者csdn的论坛是一个例子。

在交换数据的场合,xml是个不错的选择,如果性能优先的话也不妨考虑JSON。


关于网站应用中XML的使用心得[原创] .
 
2007-09-06 19:36
    google reader终于推出搜索功能了,功能比较强大,可以针对shared/star/一个分类/一个feed/所有文章等进行搜索,这点上比目前的几个RSS阅读器(鲜果抓虾等)都要好。

    本来我一直是对google reader寄以很高的期望的,但是在使用过程中却感到有些失望。其实我就测试了搜索“鲜果”,出来了很多关于鲜果的文章,结果主要是按照时间倒排序的,而结果中出现的大量重复的文章却让我失望,经常连续两个或者三四个文章都是一样的标题一样的内容,并且据我观察文章的链接也是一样的。

    其实用抓虾或者鲜果搜索的时候也会发现重复内容,不只是google reader一家重复,但世界头号搜索引擎公司出品的搜索功能似乎应该不只这样的品质,当然,谁知道这个搜索功能是否只是几个google reader小组的工程师的小打小闹做出来的呢?

   按照我的设想,google似乎把他的blogsearch和reader进行整合,应该就能达到很不错的效果,不过也许google还只是把他的reader当作一个实验室的产品呢?我辈只好去猜了
   
 
2007-08-14 18:44
1、php里使用memcached的压缩,性能相当糟糕。在实际生产环境中,每个缓存项约1-2K,然后启用缓存压缩,然后读取缓存的有时候比一次数据库读取还耗时,恐怖!取消压缩,性能成倍提高。因为这么小的数据压缩效果很差,反倒增加了cpu时间。

2、mysql中innodb存储引擎的默认配置下,update性能真是比蜗牛还慢,一定要根据系统实际情况修改mysql配置参数。

3、mysql中根据用where id in (id1,id2....)这样的查询,那么不连续的id1、id2远不如连续id1、id2的性能。id1,id2的先后顺序对性能没有影响,只要 id1、id2...排好序后是连续的,性能就比不连续的好很多。表越大效果越明显,有时候后甚至有数量级的差别。

4、文件系统中文件查找性能不仅受一个目录下文件数目多少影响,还受目录层数,整个目录数节点书的影响。一个目录下几千个文件相对性能最好。

5、数据库中存储的数据如果含有大文本的text字段,不妨考虑使用把text字段压缩存储的方式。不过text如果长度<1000那就不要压缩了,那只会浪费cpu时间,并且得不到空间的节约。
 
2007-07-30 12:59
最初的代码:
var s = [x1,x2,.....];
var t = [y1,y2,.....].
//s和t的长度对应,大约2700个元素。
function String.prototype.s2c(){
var k='';
for(var i=0;i<this.length;i++)
k+=(s.indexOf(this.charAt(i))==-1)?this.charAt(i):t.charAt(s.indexOf(this.charAt(i)))
return k;
}
//这段代码为:把String中在s数组出现的字符用t中相应位置的字符替换。这种方法可以用在繁简转换上。String的长度不小,一般为一篇blog文章的长度。

第一次优化:把k变成数组,因为字符串相加没有Array.join的内存效率好。
function String.prototype.s2c(){
var k=[];
for(var i=0;i<this.length;i++)
k.push((s.indexOf(this.charAt(i))==-1)?this.charAt(i):t.charAt(s.indexOf(this.charAt(i))));
return k.join('');
}
效率提高不少。

第二次优化:减少循环内的运算次数。
function String.prototype.s2c(){
var k=[];
for(var i=0;i<this.length;i++) {
    var thisC = this.charAt(i);
    k.push((s.indexOf(thisC)==-1)?thisC:t.charAt(s.indexOf(thisC)));
}
return k.join('');
}
这一次把三次this.charAt(i)调用变成了一次调用,效率也有所提高。

第三次优化:把数组的indexOf改成HashMap查找方式,修改循环里面的this.length
先创建HashMap:
var sMap = {},tMap={};
    for(var i=0;i<s.length;i++) {
        var sChar = s.charAt(i);
        var tChar = t.charAt(i);
        sMap[sChar ] = tChar;
        tMap[tChar] = sChar;
    }
然后修改代码:
function String.prototype.s2c(){
var k=[];
var len = this.length;
for(var i=0;i<len;i++) {
    var thisC = this.charAt(i);
    k[i] = sMap[thisC] || thisC;
}
return k.join('');
}
这一次改进性能也会有比较好的提升。

最后一次优化:改进数组访问的性能。

把原字符串split成数组,然后在一个数组上操作。

function String.prototype.s2c(){
var len = this.length;
var k=this.split('');
for(var i=0;i<len;i++) {
    var thisC = this[i];
    var to = sMap(thisC);
    to?k[i]=to:''; //这里有一个小技巧,这个技巧导致当sMap里没有thisC的映射时下面可以少一次赋值运算
}
return k.join('');
}
经过这一步的优化,性能提升相当明显,我做的测试是,s/t的长度为2700个字符,而每个字符串的长度为1300字符,每100次操作优化前花3.5s左右,而优化后花700ms左右。整个优化最关键的地方是提升循环内的效率,因为一点效率的损失会被频繁使用的循环放大到成百上千倍。

随着Ajax越来越普遍,Ajax引用的规模越来越大,Javascript代码的性能越来越显得重要。我想这就是一个很典型的例子,上面那段代码因为会被频繁使用,所以才有了此优化的过程。
 
2007-07-18 10:46
    刚在上一篇文章中说阅读器速度不稳定,时快时慢。不过在今天观察时就有了可喜的变化,xianguo和zhuaxia在页面加载性能上都有很大提升,每次展开文章列表所需要的时间都不超过1s,真是令人高兴的事情。

    :)
 
2007-07-17 19:57
比较的对象是我的71个feed,下面分别是比较的记录:

07-16 9:30

xianguo:15
zhuaxia:30
greader:34
出现更新的feed数量上基本相当,每个feed中更新的文章数xianguo中比其他两个要少点。

07-16 13:04

xianguo:9
zhuaxia:11
greader:9
出现更新的feed数量上greader最少,每个feed中更新的文章数zhuaxia比其他要多出两篇。
此次比较3个阅读器基本相当,因为更新的feed并不完全一样,所以出来的新文章也不完全一样。

07-16 16:40

xianguo:17
zhuaxia:15
greader:30

其中greader貌似更新的最多,其实30条中有13youku的视频是xianguo和zhuaxia早已经更新了的,
并且这13条并没有包含最新的一条(xianguo里出现了最新的那条)。更新所涉及的feed数xianguo
和greader相当,zhuaxia稍少。

07-16 22:10

xianguo:34
zhuaxia:29
greader:38

greader中有一个feed更新了6条,但是其中5条是在zhuaxia和xianguo中看过的,所以greader相当于
只有34条。更新的feed数目xianguo比zhuaxia和greader多出一个。
这次在xianguo中阅读的时候,由于自动刷新功能又刷出了3条新文章。

07-17 9:10

xianguo:8
zhuaxia:15
greader:22

这次greader似乎表现的很好,不过xianguo中的文章也确实是最新的,但是其中有一个feed确被
弄丢了7个新文章,这个就有点怪了。


07-17 12:01

xianguo:14
zhuaxia:15
greader:11

greader稍微少了一点,xianguo和zhuaxia相当。不过比较奇怪的是,某一个feed在zhuaxia的内容
比源feed中内容多了两条,不知道为什么抓多了,greader中也多了一条?!!这年头只听过抓漏的
没听过抓多的....


我就不下结论了,下不出啊:)我记得一开始xianguo的更新是最快的,但是中途有几天变得巨慢,现在慢慢变得快了,不过还没有达到最开始上线时的水平.

在使用的过程中,我发现xianguo和zhuaxia的打开文章列表速度都不够稳定,一时巨快,一时巨慢,某些时候zhuaxia慢的让我一天都打不开几次,xianguo倒是还没出现打不开的情况。greader稍好点,但是greader确是平均页面速度最慢,每件很快过,也没见特别慢过。
 
2007-07-15 15:36
    我在大学一开始学习过VC/MFC,学了大约半年,学到做了一个带有简单界面的ftp客户段程序,之后就学.net,然后一学就是几年,直到不久之前,现在又转型到lamp了。

    一开始从VC/MFC到.net的转变算不得是一个技术转型,因为一开始我的技术基础为0,从学VC/MFC开始了解了一下基本的编程知识(当然学习c/c++,操作系统等计算机专业也让我学到了很多),然后到学习.net基本没有技术转型上的不适。我记得当时转变是非常快而有效的,因为有了一些VC/MFC的编程基础,我记得开始接触c#的一周里,我每天下午看大约一个多小时的c#语法书,然后就能(用vs.net)开发一个完整可用的程序(俄罗斯方块),之后就是我对.net继续升入的学习过程。

    当我对.net越来越熟练,并且了解的越深入时,却突然又转向了php,主要的原因是公司打算用lamp来搭建web系统。即时转变的那么突然,对我来说也并没有形成多大冲击,我并没有什么痛苦的就转变并且切入工作了,只不过偶尔通过php里变量要用$的语法:)。很快的技术转型当然要得力于以前学些.net以及在实际工作中得技术积累。公司里这次的技术转型还给几位同事带来了一定程度的不适应。

    今天在msn与一个好友聊了一会儿。他以前也是用.net,而现在确又转java了,说是公司的需要。后来我跟他聊起来怎么跟踪学习一些新的东西,他说主要用rss订一些技术类feed,关注一些新的东西,很多技术看过就算,基本不打算学习。我深有同感,现在越来越感觉没有必要总是跟踪学些新的技术和工具,那些新东西学来学去感觉特别累,很多时候又只学了个皮毛。好友的话是“要命的是,当你发现你要精通的时候,你的技术工具又落伍了,而经验好像并没有什么提升,只是换了种语言在做同样的事情“。

   
其实语言工具也挺重要,但是语言工具所承载的那些原理却是本质,并且这种本质的东西是在绝大多数工具中共通的,要学习最终就要掌握这些本质。其实在网上看到很多人抱怨新的技术层出不穷导致自己疲于奔命,我觉得这样的技术人员是相对比较失败,也就是说没有掌握好学习方法的。

我最近一直在找一些基础性的学习资源,比如算法、操作系统、数据库以及一些系统架构的东西,来系统地学习和巩固自己知识。我对自己总结了几点学习方法:见识广点、钻研深点;学习专注、掌握本质;多实践、多总结。


 
2007-07-08 23:08
    rss本来是个能够提高阅读效率的工具,但是当订阅量一大,信息过载相关的烦恼也就随之而来。(信息过载的相关文章:信息过载也谈信息过载信息真的过载吗?信息过载与OPML共享 )。
    其实我提到的这些文章主要是说得信息太多的问题,但是我说得信息反复重复的问题。从前段时间导入了几个朋友的opml之后,痛苦就慢慢开始了。因为某一部分feed同时被托管在了feedsky和feedburner,在订阅的时候往往被区别为不同的feed同时订阅了。由于我喜欢按照目录阅读,但是在导入了几次别人的opml,那我的目录之乱就可以像而知了,这样阅读起来本来已在一个目录下读的文章又在第二个目录跳出来了。开始不觉得,后来feed越来越多,阅读也就变得越来越郁闷。
    我大概总结了一下,重复文章的来源主要有,新闻类feed(csdn、互联网、slashdot、iresearch等),同一feed在feedsky&feedburner托管后,Greader共享输出feed,youtube&youku 的top view类似的视频。经过一段时间后我终于受不了了,删除了很多feed。包括重复很多的新闻类feed,删除同时存在于feedsky和feedburner中的feed(删除其中一个),保留youku的一个视频(偶尔八卦一下,哈哈)。经过整顿之后,阅读轻松多了,但是现在还有少量重复的文章存在于greader共享输出的feed,不过已经无伤大雅了。

    令我感到担忧的是,当有一天rss reader变得非常普及的时候?rss reader共享输出feed变得越来越普及,这种重复怎么解决?我期待各个rss reader从技术上予以解决。
 
2007-07-04 09:25
直接输入www.google.com,便被自动重定向到www.google.cn,还真是的.....

我想这是谷歌提升google.cn流量比较重要的一个手段吧,当然这么做对我来说并没有任何影响。
 
     
 
 
个人档案
 
星月浪子

上次登录:
6天前

加为好友
 
   
 
自定义模块3
 
     
 
其它
 
已有人次访问本空间
 
订阅RSS  什么是RSS?

您也想拥有这样的空间?请点此申请。
     
 
最近访客
 
 

yanzixiaosun

zylew

jiangxianfu

lulei2007

songvision

comdeng

cst_zf

llaa27
     


©2008 Baidu