微软从未放弃搜索引擎的竞争,一直和Google暗暗较劲。尽管live search在内部员工里像是一个joke,但老大一直毫不犹豫地往里砸钱。
说
实话,我尽量使用微软的产品,操作系统放弃了linux,开发工具放弃了perl和java,当然这些是工作使然。但map我以前用
MapQuest,现在改用live
map,浏览器也弃Firefox改用IE8,但凡能用的,我都会改用微软的产品,不过对于搜索引擎,感觉实在太烂了,搜出来的东西总不是自己想要的,往
后翻了10来页也不见有用的。后来就偷偷把Google设为默认引擎。见到一个同事比我更过分,连outlook的搜索都改用Google
Desktop来搜索。
后来,3月初的时候,内部就发布了一个新的搜索引擎,叫Kumo(酷摸?)。据说是因为live这个名字不好,不
信把它反过来念念看看是什么?我觉得只是一个名字的更换没有什么意义。后来还是忍不住上去试了试,发现确实比原来的那个好一些。没事的时候也会用Kumo
摸一把。
今天,鲍老大又宣布发布一个新的搜索引擎,叫Bing。感觉怎样?我怎么读的像有病的‘病’?还不叫Search
Engine,改叫Decision
Engine,够新潮的概念。我不太清楚为什么取这样一个名字(据鲍老大说,是因为它短小好记),不过从一个日文名字变成一个中文名字,我感觉这是
陆奇上台登
上Search老大交椅之后的一个成功。记得前两天Search主页的封面就开始用上内部某员工拍的中国阳朔的风景照片。不管猜测对不对,新的搜索引擎还
是要试一试,结果有好事之徒一上来就搜了个“六四”,结果出来的全是大学四六级考试,让人有些瀑布寒。还没有公开release,公关就已经做得这么好
了。
让人更囧的是,为庆祝新的release,search组的人每人发了一件T-shirt。据说前面是"I
Bing",后面是“U
Bing”。听起来像“我有病,你也有病”。不过Search组的人并以为然,因为他们为“Bing”取了一个中文名字叫“必应”。比“谷歌”好一点么?
其他组的好事之徒可没那么友好,测试了一段时间之后,把这个“bing”的搜索引擎亲切地叫做Mr. Bean。
当然,面对新鲜事物,我们还应该抱着积极的态度。我想因为在测试阶段,我更愿意相信这是因为没有足够的用户行为数据导致的短暂的发育不良。这个“必应”在下周可能就会正式发布了。让我们试目以待。
我
先前有说过,“很
多的软件做成web-based是web3.0的一个趋势”。从技术角度上说,这些web-based的应用程序和以前装在本地硬盘的软件有些不一样,确
切地可以理解那些具有服务功能的网站或者应用程序为能够浏览器所容纳的对象,而浏览器只是一个可以支持多种对象的容器,可对象的后台的服务应用程序正是
deploy在各种web服务器上的软件。
而那些所谓的脚本语言只是容器与各种对象的通讯语言。
一直以来,容器和后台服务应用程序一直在改进。但更多的是一个又一个鲜活的对象通过浏览器展现在我们眼前,默默地改变我们的生活。
其
实,说很多的软件做成web-based就是变成一个个可以为浏览器所接纳的对象模型只概括了其中的一部分。它只是说到软件的表现形式。这很容易让大家忽
略数据的存储形式,而默认这样的web-based的服务让我们更多的是享受网络上的数据或者搜索引擎上的数据。我们不用经常下载软件占据自己的硬盘,有
了网络电视,我们也不用下载电影,甚至也无需下载音乐。我们自己的数据比如email,blog,订阅的杂志,收藏的信息也都存放在各个网站的服务器上,
而无需下载下来。
我们似乎已经习惯了在线的状态。淡忘了脱机的那个年代。而一向标新立异的Google似乎又找到回归的需求,那就是最近推出的的
Google Gears。它提供人们一个浏览器的插件,通过这个插件我们下载数据到本地硬盘,并且提供一个小型数据库引擎(SQLite)在本地硬盘帮助存储,建立索引和搜索数据。另外提供接口实现后台的数据同步而无需占用浏览器资源。
目前Google Gears的API应用在Google Reader上,即用户可以下载订阅的电子杂志到本地硬盘,方便整理和收藏。
一句话,软件有放在网上的趋势,人们也同样关注个人数据的搜集和存放。举个例子,我一直用
Del.icio.us来收藏一些技术网站或者文章,可有一天我查阅技术文章的时候,点击链接过去,却是物是人非页已去。这时我就想当时文章要是可以自动下载到自己硬盘并整理好那该多好。当然,手工的Copy+Paste就算了,我希望的是像
Del.icio.us的一键操作。
Got a question, when I apply sort command line in linux to sort some domain names by dictionary order, no matter which option i used, it will sort some domains like this:
...
abca.com
abc-d.com
abce.com
...
I am curious what comparison function it applys in its' sorting function. I supposed it should be a string comparison, like strcmp function, but it is not. coz strcmp will compare ascii code of characters in string one by one, thus above sorting should like this:
abc-d.com
abca.com
abce.com
one guess is that when sorting names the special characters like "." "-" will be skipped. but still got some problem when sorting following names:
abc---d.com
abc--d.com
abc-d.com
why can linux sorting keep this order? if it skips some special characters, above names should be compared equally and maybe sorted as a random order.
confused, anybody has thought about that?
-----
p.s.
Haven't got updated here for quite a long time, coz I am back to program with c under linux and I believe it is a place for Java programmers.
-----
update:
Linux sorting compares unicode of strings … more about unicode is here
随着网络上信息量的日益增加,人们的学习和工作越来越离不开网络搜索引擎(有些生活中的小例子在《
Google 今天8岁》文中有提到)。
但是,另外一方面,我们会对搜索出来的成千上万的结果束手无措,使得我们基本上对第一页的搜索结果保持兴趣,从而引发各种为争取出现在搜索引擎的第一页的各种技术(如SEO)或手段(
Spamdexing)出现,恶劣的则大打出手,甚至
搜索引擎公司出现各种幕后黑手。
对于用户来说,则需要一点智商,来迅速地达到自己的搜索目的。
对于搜索引擎的老大Google显然注意到这一事实以及这一事实带来的客户需求:即搜索引擎应该满足客户自定义化(Customizable).
最近,Google推出的产品
custom search service 则适应了这一需要。
idea很简单,就是用户可以自己根据自己的兴趣所在设置一些自己经常去的或者感兴趣的又信息量比较大的一些网站。这样就可以制定Google的搜索引擎就搜索这几个网站,或者以这几个网站的为主。
例外,这个简单idea的产品还具备web2.0的色彩。也就是可以几个兴趣相投的人一起编辑网站列表,从而类似一个搜索圈(搜索社区)搜索出大家共同感兴趣的东西。
有兴趣的大家可以自己玩玩。我初步自定义了一个与Blog有关的搜索引擎。
点击
这里。或者连接:
http://www.google.com/coop/cse?cx=006688650489436466578%3Ac7-4rxi0jf4或者点击这个简单的域名地址:http://blogdigger.info大家有兴趣可以一起玩,只要你们有gmail的账号。
加入的方法很简单,就是点击主页上的链接:
当然,你需要一个Google
的账号(没有也没有关系,只需要用你们的email注册一个就可以了,很简单)
这样,你就可以成为这个搜索引擎的一员了,平时,你觉得那个网站很好,里面的信息量也比较大,你可以把这个网站添加到Blog
Digger的网站列表中。也可以为你感兴趣的一些搜索添加搜索条目。
Not sure if it is a bug of (Http)URLConnection, but it hang sometimes for some URLs while calling any functions to get information from connection (includes getResponseCode, getInputStream, getContent, getContentLength, getHeaderField blabla..) after connection has been built (even I have set the read timeout and connect time out).
the functions openConnection() and connect() are ok, curious about that problem.
anybody has the same problem or similar problem with URLConnection?
---祝大家中秋愉快---
Ajax (
AsynchronousJavaScript and XML)是近年来流行的一门web 技术。在Blogjava上看到有人开始在介绍AJAX,但仿佛流于概念或理论的东西,对于想用Ajax的初学者似乎不是很make sense。我想,学习任何一样新的技术,例子和步骤是极为make sense的两样东西。
笔者想结合过去的学习经验简单讲讲使用Ajax的基本步骤和举几个实用例子。由于笔者主要在于后台端的开发,所以很多脚本并不是很擅长。Ajax也主要限于以前大学的修课和近期的一些为后台端程序的测试的简单实现。所以只是一个抛砖引玉的使用Ajax版本,欢迎相互学习交流。
0. 导读 1。使用Ajax的基本流程
2。使用Ajax的基本步骤。(简单例子--> Demo)
3。再来一个例子(Google Suggest)。(Demo)
4。家庭作业 :)
1。使用Ajax的基本流程在笔者看来,Ajax更像是一个简单的网络框架,它描述着如何高效地使网络前端的数据展现和网络后端的数据之间的交互。基本上,就是浏览器提供一个XMLHttpRequest(当然在IE里是ActiveXObject)的对象向后台端的脚本程序或者Servlet Classes发送http请求,从后台端的回应中获取文本数据(如xml格式和最近有人讨论的Json格式)并嵌入前台段的网页中或脚本中。
下图是一个简单的流程图:
2。使用Ajax的基本步骤。下面,我们结合上面的流程,以及一个简单的例子(见
这篇文章)过一遍基本的步骤。(蓝色代码为标准写法)
第一步:Form 代码:接受前台端的输入,并通过Action方法(方法函数里包含创建XMLHttpRequest对象)把request post到后台端。
<input id="username" name="username" type="text"
onblur="checkName(this.value,'')" />
<span class="hidden" id="nameCheckFailed">
This name is in use, please try another.
</span>
<script language="javascript">
function checkName(input, response)
{
if (response != ''){
// Response mode
message = document.getElementById('nameCheckFailed');
if (response == '1'){
message.className = 'error';
}else{
message.className = 'hidden';
}
}else{
// Input mode
url = 'http://localhost/xml/checkUserName.php?q=' + input;
loadXMLDoc(url);
}
}
var req;
function loadXMLDoc(url)
{
// branch for native XMLHttpRequest object
if (window.XMLHttpRequest) {
req = new XMLHttpRequest();
req.onreadystatechange = processReqChange;
req.open("GET", url, true);
req.send(null);
// branch for IE/Windows ActiveX version
} else if (window.ActiveXObject) {
req = new ActiveXObject("Microsoft.XMLHTTP");
if (req) {
req.onreadystatechange = processReqChange;
req.open("GET", url, true);
req.send();
}
}
}
</script>
注:
1。 这里的form只是一个input box,action的方法是onblur,就是响应失去焦点的事件,然后调用一个函数checkName, 这个函数里通过XMLHttpRequest向PHP server script 发送Post请求(看得出来,这里的php server script的文件名叫checkUserName.php,唯一参数是q)。
2。函数loadXMLDoc里有个通用的创建XMLHttpRequest对象的代码,标准代码整理如下:
var req;
function foo()
{
req = false;
// branch for native XMLHttpRequest object
if(window.XMLHttpRequest)
{
try
{
req = new XMLHttpRequest();
}
catch(e)
{
req = false;
}
}
else if(window.ActiveXObject) // branch for IE/Windows ActiveX version
{
try
{
req = new ActiveXObject("Msxml2.XMLHTTP");
}
catch(e)
{
try
{
req = new ActiveXObject("Microsoft.XMLHTTP");
}
catch(e)
{
req = false;
}
}
}
if(req)
{
//do something here
}
}
第二步:响应文本处理代码:XMLHttpRequest对象里有个类似消息响应函数的属性,即通过设置 req.onreadystatechange 来告诉XMLHttpRequest在哪个函数里处理服务端返回的文本信息。
如在上面的例子中:
req.onreadystatechange = processReqChange;
那么我们接着要有一个processReqChange的函数:
function processReqChange()
{
// only if req shows "complete"
if (req.readyState == 4) {
// only if "OK"
if (req.status == 200)
{
// ...processing statements go here...
processResponse();
} else {
alert("There was a problem retrieving
the XML data:\n" + req.statusText);
}
}
}
function processResponse()
{
response = req.responseXML.documentElement;
method = response.getElementsByTagName('method')[0].firstChild.data;
result = response.getElementsByTagName('result')[0].firstChild.data;
eval(method + '(\'\', result)');
}
注:
1。 基本上
processReqChange
函数是标准代码的写法。
2。这里要用到前面定义的全局变量(XMLHttpRequest对象)req
第三步:后台端代码(这个例子是php server script):接受前台端的请求,处理其参数,并返回相应的结果。
文件名: checkUserName.php
<?php
header('Content-Type: text/xml');
function nameInUse($q)
{
if (isset($q)){
switch(strtolower($q))
{
case 'drew' :
return '1';
break;
case 'fred' :
return '1';
break;
default:
return '0';
}
}else{
return '0';
}
}
?>
<?php echo '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'; ?>
<response>
<method>checkName</method>
<result><?php
echo nameInUse($_GET['q']) ?>
</result>
</response>
注:代码很简单,就不用解释了。这里返回的是xml格式的字符串。
总体效果见
这里输入"fred"或者"drew"的名字,失去焦点后会显示名字已存在的信息。
3。再来一个例子。这里再讲一个实用的例子,这是以前上课的一个课堂作业,也很有代表性。是关于
Google Suggest(好像新的Google Toolbar上就用的这个功能)的应用问题。这里是写好的
DEMO。现在越来越多的网站提供类似Web Service的API, 我们利用他们提供的API URL可以返回一些我们用的着的数据,放在我们的网页上。这里就用的上Ajax。只不过有些返回来的文本数据是xml格式的,就可以利用上面的简单例子来处理,但很多像Google Suggest那样是返回一段类似代码格式的文本。我们就要利用Javascript的eval函数,把这些文本当作一段代码在嵌入自己的网页中。如果嵌入的代码中含有函数,则需要自己再写一个同名的函数作为实现。(这就是流程图中的optional的func 3)
这里完整代码就不贴了,贴一些关键代码(原本后台端是用Java Servlet写的,但做demo的空间没有Tomcat不支持Servlet,所以改用Php实现,大家可以自己用Java再写一边作为家庭作业 :) ):
1) form 代码:
<form name = "QForm" method="POST" action="google_suggest.php">
<table bgcolor="8080C0" width="90%" >
<tr>
<td nowrap>Search Term:</td>
<td ><input type="text" name="qtext" onkeyup="return GetSuggestion()" size="60"></td>
</tr>
<tr>
<th colspan="2" align="left" bgcolor="#A8A8FF"><DIV id=google_suggest_target>results go here . . . </DIV></th>
</tr>
</table>
</form>
注:
a. 看得出来,要把查询的字符串post到google_suggest.php上
b. action的函数是GetSuggestion(),其返回的字符串会显示在预留的网页空间里。
2) 后台端代码(PHP):这里主要接收前台的请求,并不请求转化为向Google Suggest的API URL请求,把接收到的文本信息返回给前端。代码很简单,如下:
文件名:google_suggest.php
<?php
function getGoogleSuggest($q)
{
$url = "http://www.google.com/complete/search?hl=en&js=true&qu=" . $q;
return file_get_contents($url);
}
?>
<?php echo getGoogleSuggest($_POST['q']) ?>
注:
a。
Google Suggest API 返回的是一个代码格式的文本信息,如下:
sendRPCDone(frameElement, "", new Array(), new Array(), new Array(""));
所以我们再前台接受到这个文本信息之后,应该写一个sendRPCDone的函数来做进一步信息处理(比如说列表出查询结果)。
3) 前台文本处理代码:
<script type="text/javascript">
var req;
function GetSuggestion()
{
req = false;
var f = document.QForm;
// branch for native XMLHttpRequest object
if(window.XMLHttpRequest)
{
try
{
req = new XMLHttpRequest();
}
catch(e)
{
req = false;
}
}
else if(window.ActiveXObject) // branch for IE/Windows ActiveX version
{
try
{
req = new ActiveXObject("Msxml2.XMLHTTP");
}
catch(e)
{
try
{
req = new ActiveXObject("Microsoft.XMLHTTP");
}
catch(e)
{
req = false;
}
}
}
if(req)
{
var url = "google_suggest.php";
req.onreadystatechange = processReqChange;
req.open("POST", url, true);
req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
req.setRequestHeader("Method", "POST " + url + " HTTP/1.1");
req.send("q=" + escape(document.QForm.qtext.value));
}
}
function processReqChange()
{
if(req.readyState == 4) // only if req shows "loaded"
{
if (req.status == 200) // only if "OK"
{
x = req.responseText;
eval(x);
}
else
{
alert("There was a problem retrieving the XML data:\n" + req.statusText);
}
}
else if(req.readyState == 2)
{
}
}
function sendRPCDone(frameElement, qString, arr1, arr2, arr3)
{
var suggest_results = eval(arr1);
var counts = eval(arr2);
var htmlstr = "<TABLE cellspacing=4 border=0>";
for (var i=0; i < suggest_results.length; i++)
{
htmlstr += "<tr><td><a href=\"javascript:self.location=\'http://www.google.com/search?hl=en&q=" + suggest_results[i] + "&btnG=Google+Search\'\">" + suggest_results[i] + "</a></td>";
htmlstr += "<TD width=200><font color= 228b22>" + counts[i] + "</font></TD></TR>"
}
htmlstr += "</TABLE>";
document.getElementById("google_suggest_target").innerHTML = htmlstr;
}
</script>
4。家庭作业 :)一定要自己写一些代码,才能巩固知识:)
题目:
我们经常用
del.icio.us来收藏我们喜欢的网站或者文章,并加一些类似读书笔记的注释。那么我们怎么利用del.icio.us提供的API来访问我们的读书笔记信息,并显示在自己的Blog里呢?
提示:
1。你要有一个del.icio.us的账号,并且已经有所网页收藏作为实验数据:)
2。API URL 是 "http://del.icio.us/feeds/json/" + "你的账号名";自己参看一下,看返回什么样的格式文本。另外,如果要限制返回的记录数,可以加"?count=10"这样的参数。
最后,祝大家中秋愉快!
---------------------------完----------------------------