Category Archives: 技术笔记

一个容器设计的迷思

前些日子有些忙,一个结算项目的编码,跟女朋友闹别扭,直到今天才有时间静下心来写这篇关于上次所说的容器设计的一些问题。原本想写一篇关于自己GF的博,下一篇吧,LP看了可别生气,呵呵,我又写技术博了。
再叙述一遍需求,懂C++的程序员都知道在STL里面有Map类,里面存一个pair类型的对象,一个Key,一个Value。Key插入以后是不可修改的,Map里面的pair对象,根据Map构造函数中第三个参数决定,决定排序的方式是降序还是升序。需求中,比Map多了一点,就是在顺序迭代Map时,里面的Value是有序的,升序降序可以根据容器的第三个参数来实现。更进一步,容器还需要支持数组形式的访问。比如容器类名是SortedMap,创建一个该类型的对象:

SortedMap<std::string, std::string> sMap;
sMap[“op1”] = “avg”; // 插入Key为op1, Value 为avg的元素到容器
sMap[‘”op2″] = “ban”;
for ( SortMap<std::string, std::string>::iterator iter = sMap.begin(); iter != sMap.end(); ++iter)
// 顺序迭代容器
{
std::cout << “sMap[” << iter->first << “] = ” << iter->second << std::endl;
}
string tmp = sMap[“op2”]; // 支持容器赋值给其Value类型

这样输出后,容器中的元素是按照Value有序输出的。要支持这样的功能,我选择是用Map和Vector组合实现。Map里面保存Key和Value,在Vector中保存Map的迭代器。在插入新值后,Vector对新插入的迭代器根据其Value值进行排序。顺序迭代时,实际迭代的是Vector,通过Vector中保存的顺序的迭代器来达到输出的Map元素根据value排序的效果。其中较为麻烦的地方,是如何实现支持数组效果访问的功能。一般来讲,要支持数组效果的访问,必须在类中重载中括号,重载函数返回一个元素所存位置的引用。问题就在这里,如果要使用Map与Vector来实现这样的功能,你可以根据中括号重载后得到一个key值,但是value得值只有在引用被赋值后才能得到。而引用赋值是调用引用类型的赋值操作符来完成的,对于内置的STL类型,无法将Value与Key组合插入Map中,并将其返回的迭代器插入到Vector中这样的功能插入到该类型的重载赋值操作符的函数中,怎么办呢?
在查过一些资料之后,其实可以这么实现。

1、在SortedMap类,就是我们实现的容器中,重载中括号,并返回一个ReturnObject类;
ReturnObject<SortedMap>
operator[](const key_type& key)
{
return ReturnObject<SortedMap>(*this,key);
}
2、在ReturnObject类中, 重载赋值操作符,完成向容器中插入元素的功能;
ReturnObject& operator=(const typename T::value_type& v){}
3、增加一个类类型转换,来支持 string tmp = sMap[“op1”]; 这样的功能。
operator const typename T::value_type&()const{}
这样以来,支持了容器上述的数组访问与赋值功能,其后的迭代器功能,大家到源码里面自己研究一下吧,呵呵

在此之前,舍友就问我,为啥会有这样的需求。我也不明白,我们的组长也没具体说自己的需求从何而来,看似对自己两三周以来一个人潜心琢磨的设计十分自信。老大让这么做,那就做呗,说多了老大觉得你比较逞能,怎么可以理解他高深的设计思想。四天后,我写好了这堆代码,交给他,问他这个东西到底有啥用。他告诉我,这个东西要用到公式计算里面。他的思路是这样的:
从数据库中获得一串计算公式,比如某个过程包含三个计算过程:

a + b
step(1)*C
ste(2)*m

其中step代表上一个计算过程的结果。而我的容器所提供的功能,就是提供一个接口,通过变量名(如a)得到一个变量的值(比如1),将表达式中的变量替换,然后输入到计算器类中进行求值。我思考了以后,还是给组长说了自己的想法,在计算器类注册这些变量,这样的话,这些变量对于计算器来说,变量都是已知的,也就省去了每次替换的重复工作,况且,计算器类做变量解析的工作是必不可少的,如果在外部做替换,实际上这样的工作是重复了。
组长似乎也意识到这种做法的低效,只是说自己再看看,让我继续写别的程序。几天以后,他的计算器注册变量的功能搞定了,我的容器也没啥用了……后来他让我用抽象工厂来写一个东西,最后在他合并的程序里面,那些代码也都无影无踪,不为别的,只是因为其实所谓的抽象工厂,并不需要,只是名字看上去更专业,听起来更好维护一些罢了。真的是否需要,真的合理?只有在调用者去使用的时候,才能感受到。
所谓的程序设计,实际上是解域空间里面的一个选择问题,实现的方法千差万别,如何在性能、设计成本、开发成本、维护成本、移植成本、客户需求、时间上做权衡,找到一个最优解,确实是一个很难的问题,这个不光需要高超的技术水平,经验也相当的重要。
 代码下载

鸽巢原理的一个小题目

这周的《组合数学》作业里面有道鸽巢原理的题目,题目如下:

证明:对任意给定的52个整数,存在其中的两个整数,它们的和或差可以被100整除。

鸽巢原理简单来说,就是n+1只鸽子飞到n个鸽巢里面休息,其中必定有一个鸽巢有两个或者两个以上的鸽子在休息。这么简单的理论,用在这个题目里就不那么容易了,可能也是我数学不太好的缘故,想了老半天,愣是没想出来。这道题在书上有星号,可以拿来当没做出来的借口了,呵呵。

你有什么思路吗?

我在网上找到了答案,原来是这样:

任意给定的整数被100除,余数为0,1,2……98,99。题目要求两整数的和或者差可以被100整除,而余数中99+1=100,98+2=100……

所以,任意取51个数,可以表示如下:

a1=100r1+1 or 100r2+99

a2=100r3+2 or 100r4+98

……

a49=100r97+49 or 100r98+51

a50=100r99+50

a51=100r100

如果取52个数,则必有两个数在同一个集合。取a52分两种情况,第一种:a52=100r101+2,则有a52-a2=100*(r101-r3),可被100整除。第二种:a52=100r101+98,则有a52+a2=100*(r101+r3)+98+2,可被100整除,得证。

好了证完了,不知道你看懂没,我是理解了,回去做作业去了,88

btw:过两天我的T60就要到货了,高兴啊,呵呵,配置如下:
CPU:T2400 1.83G 内存:1GB 硬盘:60GB 显示器:14.1SXGA+,光驱:combo,蓝牙 显卡:ATI X1300 64M,对于配置我还是比较满意的,虽然不是酷锐2,硬盘也小,不过够用啦。

Precondition failed

HTTP Error 412 – Precondition failed,对于平日使用浏览器访问网页的朋友来说,这种错误几乎是不可能遇到的,不过没有关系,相信如果有所了解在日后遇到同样的错误就不会觉得束手无策。
举个无厘头的例子,你去一个景点旅游,却不想买门票,想尽办法和检票的人说好话,只求让你通过。检票人不理你,举个牌子,上面写到:八荣八耻,请买票!其实这个Precondition failed的错误也是一样,我们来看一幅图:

网上的Apache Web服务器为了提高系统的安全性,大都在Web Server的外层增加了一个过滤装置,对提交到服务器的请求进行过滤,不满足预先定义要求的统统返回Precondition failed错误。比如,你请求的服务器不允许请求内容里面包含“ABC”,但是你没有遵从,于是你对请求就被红色的区域挡在了web server的外面,就像黄色箭头演示的那样。
今天查了些资料,包括http://www.modsecurity.org/这个网站,它是一个开源的专门为Apache提供安全防护的一个插件。原计划在自己PC上的Web Server安装一个试试,后来发现这样会很麻烦,而且要理解其配置方法,原理不是那么容易。后来先尝试的更改了Header里面的User-Agent,原先是这样的:User-Agent: Apache XML RPC 3.0 (Sun HTTP Transport),于是我就改的简单点:WPCN,然后再次尝试,竟然通过了。还帮助我找到一个我写的那个commentxmlrpc.php文件的BUG,重新修改之后,我的程序终于可以在我的网站使用了。接下来可以继续做剩下的工作了:
编写配置界面;对细节进行修改;对代码进行重构;对多余的库文件进行清理
希望一个真正的beta版尽快做出来。

不,我不是Spam

晚上研究了一会先前所说的当前所面临最大的问题,总算有个眉目。之所以服务器会将我的客户端请求认为是非法的被过滤掉,主要是因为现在的Spam实在太多了。现在的Apache Web Server大概都安装有相应的Bad Behavior的插件,一旦检测出你是个客户端,而非浏览器,就可能不理你,或者给你个错误页面,告诉你,如果你读到此内容,那可能是你的机器中了病毒,如果你是个Robots,那请你遵守Robots的守则,不要假扮浏览器…..感觉就说,哈,小样,你以为在User-Agent里面说自己是Mozila就可以骗到我吗?
暂时还没有找到合适的解决办法,可以确定的是,XMLRPC的源码肯定是要有所改动,以便自己的XMLRPC请求被Apache服务器接受。需要花点时间来研究Apache判断Spam的算法,即使自己不是Spam也得研究一下,这样才能不被误杀。
真是没想到写个这样的小软件却如此的麻烦,牵扯的东西有些多,从HTTP到XMLRPC,从Java到PHP,从SWT到JFace,还有用户界面,测试,打包……太多事情要做了。而且,到最后还需要推广,让大家都可以用上,也很关键。好像有人用邮件来跟踪留言,当有新留言,WP自动发邮件到Gmail,然后用Gmail的Notifier来即使跟踪留言,这样是很不错,可惜不是那么直接,不象我的软件可以直接阅读到内容,甚至可以回复。
要怎样才能让服务器认为我不是Spam呢?
难道在HTTP请求的user-agent里面说:I’m not spam,don’t please don’t kill me!

又当爹来又当娘

自己写软件最大的优点就是自己想怎么做就怎么做,没有人管你,可以把个人的潜力发展到最大,而这种代价就是你什么都得做,既当爹来又当娘。这不,我的Blog软件就是这样,好不容易把底层的协议都处理好,剩下怎么把这些数据有效的显示出来了,就像是把自己孩子拉扯了好几年终于盼到可以上幼儿园一样。结果发现这个并不是解脱,而是越来越多的问题,越来越细节化了。
底层留言数据可以保证下载到本地,如何有效的组织这些数据就是很头大的问题。不管怎样,都应该最大化的发挥它的价值。单就留言来讲,database里面保存有留言者的IP地址,操作系统版本,浏览器版本等等。如果单纯的IP地址显示出来就没什么意思,IP地址让人又看不出什么明堂。于是我就打算添加一个IP地址库来确定IP地址的来源,准确的获得留言者的位置。用户界面这个东西太灵活了,没有个对错,同样的数据让1000个人做会有1000种千奇百怪的界面。这个时候很危险,即使你的创意很好,你的程序性能不错,有用户群,可是如果不好用,界面粗糙,大家可能就会很排斥,觉得很差劲。所以Jfish真的不敢怠慢,又是Photoshop来画,又是Visio来堆,总想先搞出点东西让大家评论一番,哪怕臭骂一顿也有帮助,哈
看看吧,还得给自己孩子做衣服,实在挺头大的:

当然,有些仓促,细节地方没有考虑周全,至少界面上这些数据都应该有的。之所以贴出来也是听听大家的意见。
提示框自己画了两个,比较难看,准备让libraline帮我设计一下,大概应该是这个样子的:

我知道这个不好看,所以有什么好的建议可以告诉我哦,呵呵。
这个软件只适合于自架Blog的朋友们使用,现在只是开发了WP下的插件,很快就会有Drupal,甚至是TT或者其他的Blog系统,都会有的,呵呵。
主要的功能不止这些,我会根据开发进度慢慢给大家介绍的。

速成PHP

我一直很佩服那些可以在考试前两天把从未翻过的书搞懂,然后考试可以的90分的人。这种人中学时候很少见,大学里面却屡见不鲜,遇到这种天才,我也只能自叹不如。在大学里,我是那种平时大概听听,考试突击只求通过的那种,除非遇到自己喜欢的课,或者喜欢的老师。可能和从小养成的学习习惯有关,因为一直都很认真,学东西也都是点点滴滴积累的,从来没有遇到试图在短时间内理解并记住很多东西的情况,所以我开始怀疑自己大脑的此种功能是不是没有得到很好的锻炼,以至于在突击一些科目的时候就头昏脑涨,一点也看不进去,或者全部理解,然后全部迅速忘掉。
昨天也尝试了一次速成,不过这次只是简单的PHP语言,相对容易一些。PHP的语法风格和C类似,但我不敢说它比C要灵活,在某些方面,它要比C强出很多,这也和它自身的用途有关。如果有其他语言的基础,要快速掌握PHP的语法非常容易,最主要是记忆而不是理解。就这样,速成了PHP,然后就开始给自己些一个XMLRPC的服务器,用来对留言部分的数据进行操作。整个过程大概花了半天的时间,从阅读WordPress里面的comment-function.php文件,确定哪些函数自己不需要去实现,到研究xmlrpc.php文件中对Blogger API的实现方法,然后到确定自己需要的API,并实现,总共也就花了3个小时,这样,我的WordPress端的插件部分就完成了,现在只要继续做我的客户端就OK了。
今天看过WP的comment表之后,想到了一些更加有趣的功能,如果加入到客户端,大家一定会很喜欢,哈,是什么我就先不讲了,估计一周内我就可以出beta版了,安装会比较简单,只需要将一个PHP文档传入WP根目录,然后你的电脑支持Java就好。客户端用SWT开发的,性能比Swing好很多,我保证你会喜欢上它的,哈
补充一下,如果你想开发PHP程序,Zend Studio很不错,除了比较耗内存之外。如果要配置你本地的PHP环境,建议你直接下载WAMP,直接将最新的Apache,Mysql,PHP环境安装完毕,无需配置,而且包含了Phpmyadmin,以及系统托盘集中管理功能,很爽。这样很多东西不用上传到你的空间直接复制到相应的文件夹里面就可以看到结果,很方便。

做Blog工具的几个原则

今天在网上找了几个比较常用的Blog发布工具,具体分析了每个软件的优点和不足,让人欣慰的是,至今还没有一款功能较为完整的Blog工具。现有的Blog工具大多是针对Blogger API,MetaWeblog API,Moveable Type API设计,功能较为单一,对用户评论等并没有涉及。如果要实现我所设想的那些功能,首先就需要对这些API进行扩展,现在还不晓得这会需要多少时间,但针对每一个Blog系统,都需要在了解其架构后才可能开发出相应的扩展…… 我想,最后应该是自己先开发出WP和Drupal的扩展,公开协议,让希望获得更多功能的朋友们自己来做吧。
下面是我开发此软件的原则,写出来也是为定一个较为明确的目标。
1、界面要美观好用,不需要看帮助就可以轻松上手,不会让用户在软件中迷失。
2、架构要具有开放性,自己考虑不到的细节,可以留下接口,让用户自己编写插件来增加个性功能。
3、内部数据要流通顺畅,只要当前需要并且系统内部包含的数据可以尽快得到。
4、尽可能简化用户操作,想用户所想,做用户所做。
5、免费为大家使用,适时转为开源,并接受Donate。
此软件主要用户群体:
1、自架Blog,使用WordPress、Drupal、MT的广大用户(首要用户)
2、使用BSP提供的Blog系统,该BSP提供XML-RPC服务(第二目标用户)
3、BSP提供服务,无web Service,可以通过某种方式导出数据的用户(第三目标用户)

Blog工具粗线条描绘

首先,我得感谢oni帮我提出如此详细的需求,看到大家这么支持J的想法,要把这款软件做出来的决心更加的坚定了。如果你还不确定是否需要这样一款这样的软件,就先查看一下下面所罗列的几个问题你是否遇到过。
1、写了很长一篇Blog,却因为浏览器或者其他的原因,丢失了,然后就没有再写的心情了;
2、要在Blog里面添加图片,先得把图片FTP到空间,然后通过URL地址来引用,太麻烦;
3、想找一篇自己以前写过的Blog,翻了半天都没有找到;
4、可不可以追踪Blog上面的留言呢?这样就可以尽快的回复;
5、为了保存Blog数据,不得不经常进行数据库的备份工作,而每次备份到本地的文件却不能直接阅读,想看看自己以前写的Blog只能忍受比较慢的网速;
6、想把Blog从WP转移到MT?或者从tatter tools转移到WP?或者你会有多个Blog需要维护?
7、你需要建立一个本地的个人知识库,来作为你的Blog素材后援?
8、希望把自己的Blog文章做成精美的电子书和朋友分享?
……
如果上面这些问题你曾经或者以后可能会遇到,那么这款工具就是你需要的,它的存在就是要帮助你解决上面一系列让人头疼的问题。
-1、不用担心所写的Blog会因为浏览器或者自己误操作遗失,此工具自动保存功能帮助你解决此问题,让写Blog的过程不再坏你的心情。
-2、自己保存的图片或者文件先得FTP到网站上,再从Blog发布?不需要了,你只要设置好FTP参数,此工具会自动帮你把图片或者其他文件上传到Blog上,整个过程不需要来回切换工具,给你带来操作上的便利。
-3、 集成的搜索功能,以及类似Flickr图片时间线的功能,tag,分类管理的功能一起帮你快速找到你所需要的内容。
-4、 Blog上的留言可以象IM软件那样,以即时消息的方式展现在你面前,然后你又以即时消息方式回复,感觉会怎样?
-5、 将自己Blog上的所有文章和留言同步到本地,而不需要去执行什么Phpmyadmin的导出功能,让备份文件泛滥成灾。
-6、 轻松通过此工具进行开源Blog之间的迁移,从此不必为自己不懂PHP,不懂Database而烦恼,开源Blog之间任意迁移。
-7、 可以轻松管理Blog,那也可以轻松管理自己收藏的网文,建立自己的个人知识库。
-8、 最重要的,我们的Blog和个人知识库是可以生成CHM或者PDF电子书的,从此和朋友分享个性信息变得简单起来。而生成电子书应该是Blog最理想的备份方式了。
当然,完整的HTML编辑功能是必不可少的,这样才能让大家最大可能做出绘声绘色的Blog文章出来。个性化的功能是此软件的另一个重要组成部分。用户不单可以为软件设计皮肤,更实用的是可以为自己的电子书设计自己所喜欢的主题,真正实现个性化。
现在很难估计这个软件开发大概需要多久,就像是拷贝大量文件之前,进度条都不会显示出会需要多少时间一样。不过Jfish坚信,简洁美观的界面,合理舒服的操作大家才会觉得好用,才会真正喜欢,这对于Jfish来说是一种挑战。
如果大家还有什么建议或者希望参与此项目,请回复此文或者直接联系我。不用担心自己很多东西不会,Jfish也有很多东西要学,只要你有时间,有兴趣,就可以参与进来

关于XML-RPC

这两天一直在研究如何用Apache的XML-RPC的Java实现,很是麻烦。自己唯一本资料是2001年出版的《Programming Web Services With Xml-Rpc》,原理是没有变,可是里面的Java实现却改变了许多。原先的Java实现是此书作者写的,当我去看个究竟的时候,才发现网站上的告示,此项目已经成为Apache开源项目的一部分了。但是我在ws.apache.org/xmlrpc的官方网站翻了个底朝天,只找到一丁点的使用说明,还有项目生成的Doc文档。郁闷啊!看来这个东西现在不是那么火啊,不然相关的书怎么这么少。
不管怎么说,XML-RPC对于一般应用来说是很适合的,相对也简单些。自己想做的这个东西其实要求也蛮高的,不光要会用Apache XML-RPC的库,也得用Java把客户端给实现了,然后再给Drupal和WordPress之类Blog系统编写插件。 今天打算写一个从Java客户端和PHP服务端通信的Hello World程序,结果到现在还没有成功,究其原因,一个是对PHP不了解,一个是不知道如何调试这样的HTTP通信的程序。现在头大的很,网上的资料也非常的少,感觉每走一步都需要很大的力气才行。真不知道什么时候可以有所突破,希望尽快吧!
Eclipse发展太迅猛了,功能性能方面都十分出色,最重要的,它属于开源软件,不光可以节约项目成本,而且可以给其开发适用于自己的插件,并和他人分享。原本计划使用IntelliJ IDea来开发这个小程序,但是看来Eclipse诱惑力太大了,我不能不选择这样免费实惠被许多软件开发公司追捧的IDE。 好了,就写这么多,继续看看我的XML-PRC的PHP服务端如何实现:(

帮Becky Crack WordPress

只所以用Crack,是因为我们对WordPress来说都是新手,没有什么经验。我也是看过几天PHP和JavaScript的书,对这些语法了解了大概,没写过程序。能最后帮助Becky把Tatter Tools转换到WordPress,也是发扬了Crack不断尝试的精神,哈。
当然,尝试并不是那么盲目的,那个转换程序原理也很简单,就是链接两个数据库,读取出来,处理了再insert到另外一个数据库里面。开始becky给我说好多Warning,把错误代码发过来一看,Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in /home/beckytsa/public_html/wordpress/tt096wp20.php on line 184,在Google上找了半天,后来确定是在这个代码之前的mysql_query 出了问题。道理很简单,mysql_query的参数是SQL语句,正常情况下返回一个resource类型传递给上面的mysql_fetch_array(),但是当你的SQL语句出错或者其他导致SQL执行失败的情况发生时,这个resource就不是有效的,按照惯例,应该在mysql_query()后面添加or die(“Invalid query: ” . mysql_error());的异常处理代码,使得一旦出现错误可以显示出错误原因。在我给原先的转换程序添加了这行错误处理代码后,Warning的原因也找到了,就是因为原先tatter tools的默认表前缀是tts,而后来改成了blog,转换程序里面设置的是tts,然后找不到表,就报错了(说该表格不存在)。
其实问题到这里已经解决了,但是在我机器上运行的时候,我修改了里面的配置,将数据库名改成我本地的数据库名,没有改回去就传给了becky,引入了让人摸不着头脑的错误-没有权限做删除操作。直到后来,才恍然大悟,只能怪自己太粗心了。
后来一起研究ajax comment的一个WP插件,蛮酷的,以前只有羡慕人家的份,昨天也尝试了一下给自己blog加ajax的滋味。怎么说呢,对JavaScript不熟,对CSS不懂,对PHP只限了解,这一切的结果就是按照作者的指导,一步一步操作,为什么要那么做,谁也不晓得。最后问题得以解决也是becky不懈努力的结果啊,哈。为了这个东西,花了不少时间啊,总算成功了。
现在都有把Drupal转移到WP的冲动,当然这也不是第一次了。Drupal相对WP来说过于复杂,所以更新的速度不及WP来得快。WP很早就出来2.0版,对ajax支持很好,用起来很舒服,而Drupal的4.7版还在测试中,据官方介绍,还是有不少BUG。搜一下使用Drupal的Blog,好像也没有几个,这又坚定了我加入WordPress的决心。
不过怎么说呢,这么一大堆东西搬一次家真的很不容易。包括帮边的盆盆罐罐,麻烦着呢。现在访问我Blog90%以上是从Google和Baidu过来的,如果搬了家,就把这两年在搜索引擎的数据给清零了,也很不爽,或许有解决的办法,那可能得先研究研究再说了。
这两天在看CODE COMPLETE,写的很好,有那种取百家之长为我所用的感觉,深入浅出,通俗易懂,不愧是得过Jolt大奖得图书,这样读一遍,感觉心里面很多东西都规整了,然后该怎么也有谱了,真是不错,要多看几遍:)