about:blank

编程与生活一样, 都是严肃而富有艺术的
随笔 - 14, 评论 - 73, 引用 - 1

导航

关于

其实我是蜘蛛侠...
另一个blog: http://yishan.cc/blogs/nickledson

标签

每月存档

最新留言

  • re: 我眼中的编程之美
    写得真好!
    by magicboy(匿名) on 2008/3/18 15:51:40
  • re: 我眼中的编程之美
    赞一个,把算法能力和项目工程能力区别开来对待是现在很多一线开发人员的通病,我曾经也深陷这个误区不能自拔
    by Anrs(匿名) on 2008/3/13 8:35:41
  • 回复: Hard Drive
    很有同感,我喜欢!!!!!!!!!
    by borcala(匿名) on 2008/2/18 20:47:00
  • 回复: Hard Drive
    很有同感,我喜欢!
    by borcala(匿名) on 2008/2/18 20:46:00
  • 回复: Hard Drive
    看来还是有些人关注这本书的:) <br> <br>&gt;&gt;lzz, xjb: <br>我一直都是&quot;敏于思而疏于行&...
    by VincentChen(匿名) on 2008/2/15 21:19:00
  • 回复: Hard Drive
    Hard Drive = 用力开车的意思。 <br> <br>但是“用力开车”查不到这样的书。
    by ralph(匿名) on 2008/2/14 17:20:00
  • 回复: Hard Drive
    有中文版本嗎?
    by 阿牛(匿名) on 2008/2/14 16:47:00
  • 回复: Hard Drive
    有中文版本嗎?
    by rockniu(匿名) on 2008/2/14 16:47:00
  • 回复: Hard Drive
    Hard Drive 翻译成中文是什么?是硬盘么?
    by drive(匿名) on 2008/2/13 13:38:00
  • 重要但不紧急的事
    事儿真多。 有重要的事,有紧急的事,有紧急但不重要的事,也有重要但不紧急的事。(详细的论述参见 “超级高效人士的超级6+1个习惯”或者其他时间管理的书籍) 对于IT 行业的人来说,读书,是一件重要但不...
    by Joycode@Ab110.com(匿名) on 2008/2/12 13:32:00
  • 回复: Hard Drive
    那lz是如何行动的呢?
    by lzz(匿名) on 2008/2/12 12:01:00
  • 回复: Hard Drive
    成功的道理很多,但关键是如何行动
    by xjb(匿名) on 2008/2/10 16:40:00
  • 回复: Hard Drive
    深受触动 谢谢楼主!
    by helixapp(匿名) on 2008/2/9 0:20:00
  • 回复: Hard Drive
    有点意思,新年快乐……
    by false(匿名) on 2008/2/8 19:12:00
  • 回复: Hard Drive
    写得非常不错,思路不错,顶一个,新年快乐……
    by 91cn00(匿名) on 2008/2/8 18:26:00
  • 回复: Hard Drive
    路过,顶一下。再祝新年快乐。
    by 问道优酷(匿名) on 2008/2/8 15:09:00
  • 回复: 对判定网页爬虫算法的一点思考
    X为间隔数组,那么Y就是相对于开始的时间么…… <br>所以你这个意思就是点击时间和点击序号线性相关么…… <br>假如加入随机化,我很怀疑这个是否成立…… <br>...
    by Henry(匿名) on 2008/2/8 12:19:00
  • 回复: 发两个刚做的web part
    发个源码噻,大家一起学习进步
    by webpart开发者(匿名) on 2008/1/4 9:29:00
  • 回复: 发两个刚做的web part
    请教 怎样把自己做的web part 运用到网站上
    by zmn(匿名) on 2007/11/14 13:38:00
  • 回复: 发两个刚做的web part
    怎么没源码啊``给我发个好吗 <br> xhlvsxzj@163.com
    by `(匿名) on 2007/11/1 16:21:00

广告

《移山外传》之技术部来的新美工

原文发表在yishan.cc, 欢迎大家访问!

两天前, 九条同学刚刚成为[King House Online]网站(简称KHO)技术部的实习美工, 他立刻就被分配了一项任务: 为今天晚上的电影放映活动做一个flash动画. 这个动画不需要太长, 两分钟左右, 会在电影开映前放给大家看, 主要是宣传一下"[KHO]网站是冀之南, 河阳以北最牛X的web2.0服务提供商, 诚邀各界有志青年关注加盟"之类的东东. 九条同学接到这个任务十分兴奋, 琢磨着第一次怎么也得在大伙儿面前露两手吧...于是他极其兴奋地花了一天时间浏览众多设计站点, 借鉴网上的经典作品, 构思如何做一个要让大家张大嘴巴的超炫动画.

看过业界著名的[蓝色理想]设计网站后, 他发现真正的flash高手都是不用designer, 直接裸写action script代码的, 于是他也决定用手写脚本来做这个动画. 这不, 昨天一天他都花在了怎么调试action script上, 由于没有经验, 所以磕磕绊绊, 经常调试不通过, 想着今天晚上就要7:00pm就要放映了, 于是他决定熬一个通宵来赶工! 据今天上午第一个到达网站的同学描述, 他在网站的地板上发现了一具头发凌乱的"尸体", 边上是一台进入屏保状态的笔记本, 废纸团和笔扔了一地...当他叫醒这句的"尸体"后, 九条同学兴奋地告诉他, 他已经把开头和结尾都做好了, 虽然只用了部分手写脚本, 但是他只要把昨天站长给他的那些宣传照片添加到中间再配上优美的背景音乐就可以了!

洗手的时候,日子从水盆里过去;吃饭的时候,日子从饭碗里过去;默默时,便从凝然的双眼前过去。我觉察他去的匆匆了,伸出手遮挽时,他又从遮挽着的手边过去,天黑时,我躺在床上,他便伶伶俐俐地从我身上跨过,从我脚边飞去了。-- 朱自清 <匆匆>

由于脚本还有一些错误, 于是九条同学又花了一些时间做细微的调整, 时间转眼就到了下午, 站长来视察工作了, 九条同学好不得意地把做好的"开头"和"结尾"给她show了一把, 站长看罢很茫然地说: "这么短, 做得太简单了点吧, 连音乐都没有, 昨天给你得相片也没有放进去". 九条同学有点沮丧, 又有点不服气地说: "这可全是用手写脚本做出来的, 比一般用designer做要难! 我只要加上照片的slides效果配上一首超炫音乐就ok了". 站长于是告诉他:"好吧, 你要加紧进度, 一会儿7点就要用了", 九条兄满口答应: "请领导放心! 保证完成任务!"

时间过得好快啊...转眼就五点了, 嗯, 该吃晚饭了..."九条, 一起吃晚饭吧, 好像你午饭也没吃吧...", "麦来乱, 正忙呢", "哦, byebye"...

吃完晚饭已经六点了, 九条兄觉得事情好像有点棘手了, 于是他赶忙打电话让他的铁哥们果冻帮忙处理一下照片的分辨率, 他先把slides动画效果设计好, 虽然本人生平见过很多大忙人, 但是如此忙的还是第一次见到. 只见九条同学同时操作这一台网站的工作站和他自己的笔记本电脑, 不时地掏出电话和果冻沟通, "你能不能快点"(大吼~~), "什么! 我让你处理照片, 你怎么搞成这样, 等于没搞嘛!", "那个照片要这么处理...你听着点!"(大吼!!), "哦, 站长啊, 我马上就好了! 一定赶在七点前完成"(友善真诚地~~), "真的, 只要再10分钟!"(极其诚恳地~~), "大哥, 我求你了, 能不能快点啊"(催人泪下地~~)

时间就像你暗恋的女生, 不追她, 她不会主动停下脚步来等你... -- 小飞

七点已过, 九条同学还在忙, "只剩下加背景音乐了!" 他自言自语道, "可是赶不上了." 站长催得不耐烦了, 又打了个电话说, 如果开场没法放映, 那么就等到两场电影的间隔再放映吧. 九条同学顿时又仿佛抓到了一根救命稻草, 问清楚下一场电影是八点四十放映后, 他兴奋地叫起来:"只剩下背景音乐了. 肯定来得及". 然后又对我说: "小飞, 帮我找一首好听的音乐吧", 我答道: "我正在写一个程序, 一会儿写完了给你找吧", 于是九条同学又开始忙活开了, 他觉得果冻给他处理的照片质量不好, 琢磨着时间肯定够, 于是又自己处理了一下, 调整了slides动画的几处细节.

oh, my god, 怎么就到8点了, 赶紧加音乐, oh, s**t, 怎么是铁达尼号主题曲, 太俗了, 换, 哎呀, 这个音质太差了, 哦, 不行, 这个文件格式flash不支持...折腾来折腾去, 好不容易赶在八点三十五时把音乐加好了. 测试一下吧, 呀, 怎么slides不动了, 而且忘了设置全屏效果了, 赶紧改, 九条同学不由得哭丧着脸说:"又要赶不上了...", 8点45分, bug终于fix了, 荔荔这时很好心地帮他打了个电话, 得知电影可能还会延长10分钟才结束, 于是告诉九条, 现在赶紧赶过去吧. 九条听罢两眼放光: "我还赶得上! 本来还以为从此再也没脸来[KHO]混了!", 但是这时他又觉得有几处细节调整一下比较好, 还有十分钟, 还可以改一下嘛, 大不了把源文件带过去放映厅, 那里也有笔记本可以改的...

看到这里, 我再也忍受不了了(一整天当我写程序时都有一个混蛋在身后对着手机大喊大叫...), 连拉带拽把九条赶去了放映厅...于是, 在两部电影的间隙, 观众终于看到了一个用"手写脚本"制作, 不到一分钟, "开头"是一个倒数时钟, "结尾"是一对飘来飘去的字符, 中间的slides相片速度或快或慢, 背景音乐时断时续的flash宣传动画, 用来宣传"坊间技术最牛X的网站"...

和九条走在回网站的路上, 他说: "今天太幸运了, 不过我那个动画用手写脚本的确是很有挑战性!", 我看了看夜空, 今天天气不错, 一眼就识别出中天偏北的大熊星座, 接下来, 我告诉了九条一个故事: 那是一个用了最新最炫的微软技术开发的, 虽然项目schedule延了好几次, 但是开发人员花了很多时间设计了一个号称很"robust"的架构, 写了好几百万行的代码, 留下了极其详尽而且丰富多彩的文档, 最终却是一个看上去就有不少明显bug的项目...

亲爱的读者朋友们, 你们从这个故事中明白什么了吗?

posted on 2007-04-22 13:05:00 by cy  评论(0) 阅读(844)

CommunityServer2007改变授权策略, 不再有免费的午餐了

最近因为在维护一个基于CommunityServer的站点, 所以对它关注比较多一些, 前几天官方社区communityserver.org终于放出了CommunityServer2007 RC, 虽然没有源码, 还是下载下来研究了一番. 结果却在授权文件中发现CS 2007(3.0)即将对免费版本(Personal Edition)中的论坛(Forums), 博客(Blogs)和相册(Photos)限制数量, 分别是博客10个, 论坛15个, 相册10个, 当然如果你每年交99美刀给他们的话, 则可以取消数额限制.

详细请看官方授权文件: http://communityserver.org/files/folders/567672/download.aspx

真想不通, 难道开源项目到头来都要走上商业化的道路吗? 而且CS这套系统果真就那么优秀吗? 我从CS1.0beta阶段就开始读它的源码了, 一直到现在CS2.1, 虽然承认CS改进了不少, 但是一些陈年老bug还是经久不衰, 比如它对中文搜索的支持一直以来就是一个不折不扣的joke...CS2.0虽然开始提供ASP.NET2.0的版本, 但是代码中很多实现方法依然还是采用ASP.NET1.1甚至1.0的写法. 并且, CS效率不高, 一些通过拼接SQL来进行的查询造成对SQL Server负担过重的问题也是一直为人所诟病. 缓存设置也不尽合理, 如果你RP不好成为程序池启动后的第一个访问者, oh, god bless you...当然客观说来, CS系统还是瑕不掩瑜的.

总之官方论坛早就吵开了, 不过似乎还没有看到官方表示出在正式发布时作出改变的诚意. CS在国内的应用本来就主要集中在技术社区, 大家主要还是研究它的架构设计和源码, 大部分娱乐性论坛还是采用Discuz!或者dvbbs居多, 我觉得CS2007对授权策略突然作出如此的大的改动, 可能下场就是要不被破解, 要不被放弃了...

听闻宝玉正在开发一套名为Openlab的开源CMS, 而且也见识了这套系统在bbs.openlab.net.cn的试运行情况(不得不感叹, 速度真的很快), 希望这个系统能够早日发布, 让我们在后CS时代多一个选择 :)

posted on 2007-04-13 23:01:00 by cy  评论(8) 阅读(6476)

改进CommunityServer的搜索功能

    CommunityServer的搜索功能是通过定时对cs_Post表中的新增文章进行增量分词索引(由communityserver.config的Jobs配置节中ForumIndexing, GalleryIndexing, WeblogIndexing和FilesIndexing完成), 将分词索引结果hash后记录到cs_SearchBarrel表中, 搜索时再根据cs_SearchBarrel同其他表进行关联查询来实现的. 从CS诞生至今, 它的搜索功能一直对中文支持得很不好, 究其原因, 通过查看cs_SearchBarrel表中Word字段的值就可以发现, 主要是由于它对中文分词的实现很糟造成的. 所以一种解决方案是引入一个新的效果更好的中文分词组件, 而我采用的实现方案是使用SQL Server内置的Full-text index服务.

    CS中广泛采用了Provider模式来实现各种功能, 搜索模块也不例外, 我们主要关注的有两个类, 一个是SearchTerms类, 一个是继承自SearchProvider类的SearchBarrelProvider类, SQL全文检索采用的是原文, 所以实现步骤如下:
    1. 首先将SearchTerms类中对搜索关键字进行hash的代码去掉, 一是在对TokenizeKeywords方法进行调用时将第二个参数赋为false, 二是修改GetAndOrKeywords方法去掉对关键字hash的代码.
    2. 其次我们要修改SearchBarrelProvider中的SQL查询字符串, 用全文检索的CONTAINS/FREETEXT谓词取代对cs_SearchBarrel表的关联查询. 同时数据库中的cs_SearchBarrel_Search存储过程也需要修改以去除对cs_SearchBarrel的查询操作.
    3. 最后为cs_Posts表的Body字段创建Full-text Index, 设置一个schedule每隔一段时间增量索引一次, 修改communityserver,config文件注释掉那几个CS内置的定时索引Jobs, 重新编译源码, CS就开始采用SQL内置的全文检索功能了, 从实际使用的角度看, 效果还是蛮不错的. (具体修改细节请参考文后的附上的代码下载)

    Google.cn主页的搜索框在用户键入关键字时会自动出现一个相关关键字的下拉列表供用户选择, 我们采用AJAX Controls Toolkit中的AutoComplete控件也可以为CS的搜索输入框实现同样的效果. 下面是实现步骤:
    1. 首先创建一个名为cs_QueryHistory表, 它具有三个字段:QueryWord(搜索词), ResultCount(搜索结果数), QueryCount(同一搜索词被采用的次数), 在每次用户进行搜索之后, 如果此次搜索词已经在cs_QueryHistory表中存在, 则更新对应的QueryCount和ResultCount, 否则插入一条新的数据.
    2. 然后建立一个名为QueryAutoComplete.asmx的web service提供给AutoComplete控件, web service提供一个声明为public string[] GetCompletionList(string prefixText, int count)的web method, 被调用时会根据prefixText查询cs_QueryHistory表, 返回由prefixText作为前缀以及数量为count的string数组. 为了提高效率, 我们还可以将由a-z开头的所有关键词预先取出置入缓存中以加快响应速度.

    在调试过程中还发现了两个问题, 一是CS中的输入框控件DefaultButtonTextBox在回车时会触发设置到它的button属性上的按钮的postback行为, 而在AutoComplete控件的下拉框中选取好某个备选条目时, 也是用回车键进行确认的, 这就造成了事件处理先后问题, 如果AutoComplete控件先响应了回车的keydown事件, 则一切正常. 否则, DefaultButtonTextBox先行响应了回车的keydown事件, 会使得AutoComplete控件改变搜索框中值的行为发生在postback之后. 也就意味着submit到服务器的表单中不是我们选中的条目, 而是在搜索框中未补全的关键词. 第二个问题是, 当返回的string数组不足count条目时, AutoComplete控件的下拉框中会用多条名为”null”的条目替代, 用户体验很不好. 还好AJAX Controls Toolkit是开源的, 我们下载源码修改AutoComplete控件客户端脚本中的_onKeyDown响应方法, 在用户选取条目的同时就同时更新文本框的值, 而不必用回车确认. 同时修改呈现下拉框的_update方法, 在增加新条目的循环中加一条判断语句, 一旦遇到null值或者string长度为空则break跳出. 重新编译AJAX Control Toolkit程序集并在CS项目中刷新引用. 这样就实现了关键字自动补完功能.

    后记: 通过对CS搜索模块的改进, 发现里面有一些不甚必要代码, 一个简单的过程偏偏要弄得非常复杂, 一个模块的调用要经历大量的继承和多态绑定, 很多人反映CS整体效率不高也就不足为奇了. 当然ASP.NET2.0往往也就陪上成了替罪羊...我在调试过程中, 还发现, 默认的搜索模块拼接出来的查询串相当恐怖, 当搜索"过程 and 计划 or CommunityServer"时, 拼接出来的查询串居然是: SELECT DISTINCT P.PostID, P.SectionID, Weight = (B0.Weight + B1.Weight), P.PostDate FROM cs_SearchBarrel B0, cs_SearchBarrel B1, cs_Posts P, cs_Sections F WHERE (B0.WordHash = -2605057 OR B0.WordHash = -272220937) AND B1.WordHash = -405848999 AND B0.PostID = P.PostID AND B1.PostID = P.PostID AND (P.SectionID in (3)) AND F.SectionID = P.SectionID AND P.SettingsID = 1000 AND F.IsSearchable = 1 AND P.IsApproved = 1 ORDER BY Weight DESC, PostDate DESC, 我们可以看到, 有n个查询关键词, 那么cs_SearchBarrel表就要被嵌套进行自然连接n-1次, 查询复杂度会随着关键字数量增多呈指数级(X^n, n增长)增大, 当索引表在一段时间不断膨胀后, 针对相同的query, 查询的复杂度又会依据幂级数(X^n, X增长)增大!

源码下载

我是陈远(Vincent Chen), 正在上研, 对Web开发和数据挖掘技术很感兴趣, 我的邮件是NickLedson[at]gmail[dot]com, 欢迎交流:-)

posted on 2007-04-09 21:32:00 by cy  评论(8) 阅读(5775)

Powered by: Joycode.MVC引擎 0.5.2.0