星期四, 十一月 30, 2006

Using Oracle ADF progressIndicator 进度条使用

页面page:

<af:poll interval="500" id="pollid"/>
<af:progressIndicator id="progressid"
action="progressEnd" value="#{progress.progressModel}" partialTriggers="pollid" >
<af:outputFormatted styleUsage="instruction"
value="#{progress.message}"/>
</af:progressIndicator>

解释:af:poll是timer,每隔0.5秒刷新一次。af:progressIndicator是进度条,设置partialTriggers为af:poll的id,这样,poll每刷新一次就会调用progressIndicator, progressIndicator被调用时会取value指定的#{progress.progressModel},#{}是EL语言,progress是后台的managed bean,在adf-config.xml文件配置。

ManagedBean文件:

星期二, 十一月 28, 2006

Using Log4j 使用

One example:

Logger logger = Logger.getLogger(SZ800BusHandler.class);
PropertyConfigurator.configure("conf/log4j.properties");
logger.debug("debug"); //the lowest level
logger.info("info");
logger.warn("warn");
logger.error("error");
logger.fatal("fatal"); //the highest level

log4j.properties:

log4j.rootLogger=info, stdout, logfile
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n
log4j.appender.logfile=org.apache.log4j.RollingFileAppender
log4j.appender.logfile.File=log\\sinker.log
log4j.appender.logfile.MaxFileSize=512KB
# Keep three backup files.
log4j.appender.logfile.MaxBackupIndex=3
# Pattern to output: date priority [category] - message
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n

note that: If you set "info" in the log4j properties, the log will write info,warn,error,fatal log. in the other words, log will record higher level's log.

星期日, 十一月 26, 2006

Oracle Connect by 使用方法

connect by prior start with 经常会被用到一个表中存在递归关系的时候。比如我们经常会将一个比较复杂的目录树存储到一个表中。或者将一些部门存储到一个表中,而这些部门互相有隶属关系。这个时候你就会用到connect by prior start with。

典型的使用方法就是:
select * from table connect by prior cur_id=parent_id start with cur_id=???
例如:
a b
1 0
2 1
3 1
4 2
5 3

如果想查找a=2及其下面的所有数据,则:
select * from table connect by prior a=b start with a=2
a b
2 1
4 2

这些只是基础,皮毛。其实只要你灵活的构造查询语句。可以得出意想不到的结果。比如生成树每一个路径。
但是这些记录组成的树必须正常才可以。如果有互为父子的情况,就会出现循环错误!

在eclipse中实现nutch运行

无法查看这则摘要。请 点击此处查看博文。

Nutch Architecture 体系结构

WebDB cycle. WebDB is a persistent custom database that tracks every known page and relevant link. It maintains a small set of facts about each, such as the last-crawled date. WebDB is meant to exist for a long time, across many months of operation.

Since WebDB knows when each link was last fetched, it can easily generate a set of fetchlists. These lists contain every URL we're interested in downloading. WebDB splits the overall workload into several lists, one for each fetcher process. URLs are distributed almost randomly; all the links for a single domain are fetched by the same process, so it can obey politeness constraints.

The fetchers consume the fetchlists and start downloading from the Internet. The fetchers are "polite," meaning they don't overload a single site with requests, and they observe the Robots Exclusion Protocol. (This allows Web-site owners to mark parts of the site as off-limits to automated clients such as our fetcher.) Otherwise, the fetcher blindly marches down the fetchlist, writing down the resulting downloaded text.

Fetchers output WebDB updates and Web content. The updates tell WebDB about pages that have appeared or disappeared since the last fetch attempt. The Web content is used to generate the searchable index that users will actually query.

Note that the WebDB-fetch cycle is designed to repeat forever, maintaining an up-to-date image of the Web graph.

Indexing and Querying. Once we have the Web content, Nutch can get ready to process queries. The indexer uses the content to generate an inverted index of all terms and all pages. We divide the document set into a set of index segments, each of which is fed to a single searcher process.

We can thus distribute the current set of index segments over an arbitrary number of searcher processes, allowing us to scale easily with the query load. Further, we can copy an index segment to multiple machines and run a searcher over each one; that allows more good scaling behavior and reliability in case one or more of the searcher machines fail.

Each searcher also draws upon the Web content from earlier, so it can provide a cached copy of any Web page.

Finally, a pool of Web servers handle interactions with users and contact the searchers for results. Each Web server interacts with many different searchers to learn about the entire document set. In this way, the Web server is simultaneously acting as an HTTP server and a Nutch-search client.

Web servers contain very little state and can be easily reproduced to handle increased load. They need to be told only about the existing pool of searcher machines. The only state they do maintain is a list of which searcher processes are available at any time; if a given segment's searcher fails, the Web server will query a different one instead.

Java文件操作:判断两个路径是否指向同一个文件

我们知道在Windows操作系统下文件名是不区分大小写;另外在不同的操作系统下可以用 . 来表示当前目录,或者直接只写文件名也表示默认为当前目录,例如当前目录是D:\work,那么文件D:\work\aaa.txt和.\Aaa.txt 实际上指的是磁盘上的同一个文件,但是程序怎么来判断这种情况呢?请看下面代码

/**
* 判断两个File对象是否指向同一个文件
* @throws IOException
*/
protected static void testCanonicalFile() throws IOException{
File f1 = new File("D:\work\AAA.txt");
File f2 = new File("./aaa.txt");
boolean sameFile = f1.getCanonicalFile().
equals(f2.getCanonicalFile());
System.out.println(sameFile);
}

通过getCanonicalFile方法来获取某个文件在当前操作系统下对应的目标文件,只要两个路径指向同一个文件,则两个文件对象的getCanonicalFile返回的对象一定相等,因此上面的例子打印的值是 true.

Nutch Page分析

nutch中每个page就是webdb中page database的一行(row), page中含有如下代码内容:

Page 1: Version: 4
URL: http://keaton/tinysite/A.html
ID: fb8b9f0792e449cda72a9670b4ce833a
Next fetch: Thu Nov 24 11:13:35 GMT 2005
Retries since fetch: 0
Retry interval: 30 days
Num outlinks: 1
Score: 1.0
NextScore: 1.0

其中:

The ID field is the MD5 hash of the page contents, the same contents have same MD5 hash

Nutch结构概要

Nutch的工作分为两个阶段:抓取和搜索。抓取阶段取得网页并把他们处理成倒排的索引,后面的搜索阶段的工作基于这些索引来进行。

我按照Nutch Tutorial中对Intranet搜索的介绍,抓取了两个网站上的数据。生成了如下的文件结构:

Nutch的抓取系统使用Nutch的“CrawlTool(CrawTool.java)”工具以及一些列相关工具来建立和维护上面这几类数据结构,包括“web database”、一系列“segment”以及“index”。

Web 数据库(web database,或者WebDB),是用来保存抓取得Web图(Web Graph)的持久化的数据结构。只要被抓取的Web页面还存在,WebDB就会一直存在。WebDB只在抓取过程中起作用,并不参与搜索的过程。 WebDB保存两类实体:页面(page)和链接(link)。一个页面就相对于Web上的一个网页,网页的URL和内容的MD5哈希码被存储在页面中,同时,网页上的链接数、抓取信息以及计算的网页的权重(score)都被存储在页面中。而一个链接则表示两个网页之间链接。WebDB中的Web图就是由页面和链接组成,页面是节点,链接是边。

一个片断(Segment)是抓取器在一次抓取中取回和索引的网页。如上图所示,一个fetchlist是从WebDB中生成的URL列表,将由抓取器去抓取。

而索引则是系统所抓回的所有网页内容的倒排索引,是由多个片断融合而成。Nutch使用Lucene进行索引,所以所有的Lucene工具和API都可以在 Nutch生成的索引上工作。要注意的是,Lucene中也有片断(segment)这种说法,不过他和Nutch片断是不一样的。Lucene片断是 Lucene索引的一部分,而Nutch片断只是在WebDB的抓取和索引中用到,并不是最后的索引。

Nutch抓取过程

抓取是一个循环的过程:抓取蜘蛛从WebDB中生成了一个 fetchlist 集合;抽取工具根据fetchlist从网络上下载网页内容;蜘蛛程序根据抽取工具发现的新链接更新WebDB;然后再生成新的fetchlist;周而复始。(注:蜘蛛是分两个部分的。有一次在公司的一个讨论会上还就此争论了一番,google也是如此,以后会给出例子。)这个抓取循环在nutch中经常指: generate/fetch/update 循环。

一般来说同一域名下的 url 链接会被合成到同一个 fetchlist。这样做的考虑是:当同时使用多个蜘蛛抓取的时候,不会产生重复抓取的现象。Nutch 遵循 Robots Exclusion Protocol, 你可以用robots.txt 定义保护私有网页数据不被抓去。

上面这个抓取工具的组合是Nutch的最外层的,你也可以直接使用更底层的工具,自己组合这些底层工具的执行顺序达到同样的结果。这就是Nutch吸引人的地方吧。下面把上述过程分别详述一下,括号内就是底层工具的名字:

  1. 创建一个新的WebDB (admin db -create)。
  2. 把开始抓取的跟Url 放入WebDb (inject)。
  3. 从WebDb的新 segment 中生成 fetchlist (generate)。
  4. 根据 fetchlist 列表抓取网页的内容 (fetch)。
  5. 根据抓取回来的网页链接url更新 WebDB (updatedb)。
  6. 重复上面3-5个步骤直到到达指定的抓取层数。
  7. 用计算出来的网页url权重 scores 更新 segments (updatesegs)。
  8. 对抓取回来的网页建立索引(index)。
  9. 在索引中消除重复的内容和重复的url (dedup)。
  10. 合并多个索引到一个大索引,为搜索提供索引库(merge)。

在创建了一个新的WebDB后,抓取循环 generate/fetch/update 就根据 最先第二步指定的根 url 在一定周期下自动循环了。当抓取循环结束后,就会生成一个最终的索引。从第7步到第10步。

需要说明的是:上面第 8 步中每个 segment 的索引都是单独建立的,之后才消重(第9步)。第10步就是大功告成,合并单独的索引到一个大索引库。

Dedup 工具可以从 segment 的索引中去除重复的url。因为 WebDB 中不允许重复的url , 也就是说 fetchlist 中不会有重复的url,所以不需要对 fetchlist 执行 dedup 操作。上文说过,默认的抓取周期是30天,如果已经生成的旧 fetch 没有删除,而又生成了新的fetch 这是还是会出现重复的url的。当只有一个抓取程序运行的时候是不会发生上述情况的。

从上面的介绍可以看出,一般情况下我们只要从头执行的程序就可以了,不需要接触底层的工具。但是搜索引擎有很多“意外”,很多的时间需要花费在维护上,所以底层的工具也是需要掌握的。我将会在下文给你演示如何运行上述过程。

开篇说过,本文是面向一个中型的搜索引擎的,如果做像百度这样的抓取互联网数据的引擎,你就需要参考下面的资源。

资源列表:

1、Nutch project page Nutch项目的大本营,想必大家都知道。
2、邮件列表: nutch-usernutch-dev

Nutch CrawTool代码粗析

CrawlTool.java文件是整个Nutch的入口, 从这里着手分析可以从宏观上掌握nutch的结构. 为了加强可读性, 如下代码进行过删减.

String db = new File(dir + "/db").getCanonicalPath();
String segments = new File(dir + "/segments").getCanonicalPath();
NutchFileSystem nfs = NutchFileSystem.parseArgs(args, 0);

// 创建一个新的WebDB
WebDBAdminTool.main(prependFileSystem(fs, nameserver, new String[] { db, "-create"}));

//把开始抓取的根Url放入WebDb
WebDBInjector.main(prependFileSystem(fs, nameserver, new String[] { db, "-urlfile", rootUrlFile }));

for (int i = 0; i < depth; i++) {
//从WebDb的新segment中生成fetchlist
FetchListTool.main(prependFileSystem(fs, nameserver, new String[] { db, segments } ));
String segment = getLatestSegment(nfs, segments);

//根据 fetchlist 列表抓取网页的内容
Fetcher.main(prependFileSystem(fs, nameserver, new String[] { "-threads", ""+threads, segment } ));

// 根据抓取回来的网页链接url更新 WebDB
UpdateDatabaseTool.main(prependFileSystem(fs, nameserver, new String[] { db, segment } ));
}

//用计算出来的网页url权重scores更新segments
UpdateSegmentsFromDb updater = new UpdateSegmentsFromDb(nfs, db, segments, dir);
updater.run();

File workDir = new File(dir, "workdir");
File[] segmentDirs = nfs.listFiles(new File(segments));

//对抓取回来的网页建立索引,每个segment的索引都是单独建立的
for (int i = 0; i < segmentDirs.length; i++) {
IndexSegment.main(prependFileSystem(fs, nameserver, new String[] { segmentDirs[i].toString(), "-dir", workDir.getPath() } ));
}

//在segment的索引中消除重复的内容和重复的url
DeleteDuplicates.main(prependFileSystem(fs, nameserver, new String[] { segments }));

//合并多个segment的索引到一个大索引,为搜索提供索引库
IndexMerger merger = new IndexMerger(nfs, segmentDirs, new File(dir + "/index"), workDir);
merger.merge();

对KooXoo网的研究

KooXoo(http://www.kooxoo.com)的侧重点在于搜索, 提供了很多不同行业的搜索

其中有几点有特色:

1.把更新时间作为一个重要参数提供在搜索结果中, 并以为default的排序方法, 这对于有时效性的搜索很有帮助

2.地图搜索, 和mapbar合作, 可以拉框选择搜索, 很直观, 有想法

3.冒泡, 实时refresh客户查询结果

WebDB 研究

I created a contrived example with just four pages to understand the steps involved in the crawl process. Figure 1 illustrates the links between pages. C and C-dup (C-duplicate) have identical content.

Before we run the crawler, create a file called urls that contains the root URLs from which to populate the initial fetchlist. In this case, we'll start from page A.

echo 'http://keaton/tinysite/A.html' > urls

The crawl tool uses a filter to decide which URLs go into the WebDB (in steps 2 and 5 in the breakdown of crawl above). This can be used to restrict the crawl to URLs that match any given pattern, specified by regular expressions. Here, we just restrict the domain to the server on my intranet (keaton), by changing the line in the configuration file conf/crawl-urlfilter.txt from

+^http://([a-z0-9]*\.)*MY.DOMAIN.NAME/

to

+^http://keaton/

Now we are ready to crawl, which we do with a single command:

bin/nutch crawl urls -dir crawl-tinysite -depth 3 >& crawl.log

The crawl uses the root URLs in urls to start the crawl, and puts the results of the crawl in the directory crawl-tinysite. The crawler logs its activity to crawl.log. The -depth flag tells the crawler how many generate/fetch/update cycles to carry out to get full page coverage. Three is enough to reach all of the pages in this example, but for real sites it is best to start with five (the default), and increase it if you find some pages aren't being reached.

We shall now look in some detail at the data structures crawl has produced.

The first thing to look at is the number of pages and links in the database. This is useful as a sanity check to give us some confidence that the crawler did indeed crawl the site, and how much of it. The readdb tool parses the WebDB and displays portions of it in human-readable form. We use the -stats option here:

bin/nutch readdb crawl-tinysite/db -stats

which displays:

Number of pages: 4
Number of links: 4


As expected, there are four pages in the WebDB (A, B, C, and C-duplicate) and four links between them. The links to Wikipedia are not in the WebDB, since they did match the pattern in the URL filter file. Both C and C-duplicate are in the WebDB since the WebDB doesn't de-duplicate pages by content, only by URL (which is why A isn't in twice). Next, we can dump all of the pages, by using a different option for readdb:

bin/nutch readdb crawl-tinysite/db -dumppageurl

which gives:

Page 1: Version: 4
URL: http://keaton/tinysite/A.html
ID: fb8b9f0792e449cda72a9670b4ce833a
Next fetch: Thu Nov 24 11:13:35 GMT 2005
Retries since fetch: 0
Retry interval: 30 days
Num outlinks: 1
Score: 1.0
NextScore: 1.0

Page 2: Version: 4
URL: http://keaton/tinysite/B.html
ID: 404db2bd139307b0e1b696d3a1a772b4
Next fetch: Thu Nov 24 11:13:37 GMT 2005
Retries since fetch: 0
Retry interval: 30 days
Num outlinks: 3
Score: 1.0
NextScore: 1.0

Page 3: Version: 4
URL: http://keaton/tinysite/C-duplicate.html
ID: be7e0a5c7ad9d98dd3a518838afd5276
Next fetch: Thu Nov 24 11:13:39 GMT 2005
Retries since fetch: 0
Retry interval: 30 days
Num outlinks: 0
Score: 1.0
NextScore: 1.0

Page 4: Version: 4
URL: http://keaton/tinysite/C.html
ID: be7e0a5c7ad9d98dd3a518838afd5276
Next fetch: Thu Nov 24 11:13:40 GMT 2005
Retries since fetch: 0
Retry interval: 30 days
Num outlinks: 0
Score: 1.0
NextScore: 1.0


Each page appears in a separate block, with one field per line. The ID field is the MD5 hash of the page contents: note that C and C-duplicate have the same ID. There is also information about when the pages should be next fetched (which defaults to 30 days), and page scores. It is easy to dump the structure of the web graph, too:

bin/nutch readdb crawl-tinysite/db -dumplinks

which produces:

from http://keaton/tinysite/B.html
to http://keaton/tinysite/A.html
to http://keaton/tinysite/C-duplicate.html
to http://keaton/tinysite/C.html

from http://keaton/tinysite/A.html
to http://keaton/tinysite/B.html


For sites larger than a few pages, it is less useful to dump the WebDB in full using these verbose formats. The readdb tool also supports extraction of an individual page or link by URL or MD5 hash. For example, to examine the links to page B, issue the command:

bin/nutch readdb crawl-tinysite/db -linkurl http://keaton/tinysite/B.html

to get:

Found 1 links.
Link 0: Version: 5
ID: fb8b9f0792e449cda72a9670b4ce833a
DomainID: 3625484895915226548
URL: http://keaton/tinysite/B.html
AnchorText: B
targetHasOutlink: true


Notice that the ID is the MD5 hash of the source page A.

There are other ways to inspect the WebDB. The admin tool can produce a dump of the whole database in plain-text tabular form, with one entry per line, using the -textdump option. This format is handy for processing with scripts. The most flexible way of reading the WebDB is through the Java interface. See the Nutch source code and API documentation for more details. A good starting point is org.apache.nutch.db.WebDBReader, which is the Java class that implements the functionality of the readdb tool (readdb is actually just a synonym for org.apache.nutch.db.WebDBReader).

innerHTML 用法

使用innerHTML可以动态改变网页的样子和行为, 把下例代码建立一个html文件可以试一试:

<DIV ID="swappable" onClick="setValue()">test</DIV>
<SCRIPT LANGUAGE="JavaScript">
function setValue(){
document.getElementById("swappable").innerHTML="<input name='' type='text' value='test'><br><input name='' type='button' value='save' onClick='save()'>";
}

function save(){
document.getElementById("swappable").innerHTML="test";
}
</SCRIPT>

Nutch Segment 试用

Segments

The crawl created three segments in timestamped subdirectories in the segments directory, one for each generate/fetch/update cycle. The segread tool gives a useful summary of all of the segments:

bin/nutch segread -list -dir crawl-tinysite/segments/

giving the following tabular output (slightly reformatted to fit this page):

PARSED? STARTED           FINISHED          COUNT DIR NAME
true 20051025-12:13:35 20051025-12:13:35 1 crawl-tinysite/segments/20051025121334
true 20051025-12:13:37 20051025-12:13:37 1 crawl-tinysite/segments/20051025121337
true 20051025-12:13:39 20051025-12:13:39 2 crawl-tinysite/segments/20051025121339
TOTAL: 4 entries in 3 segments.


The PARSED? column is always true when using the crawl tool. This column is useful when running fetchers with parsing turned off, to be run later as a separate process. The STARTED and FINISHED columns indicate the times when fetching started and finished. This information is invaluable for bigger crawls, when tracking down why crawling is taking a long time. The COUNT column shows the number of fetched pages in the segment. The last segment, for example, has two entries, corresponding to pages C and C-duplicate.

Sometimes it is necessary to find out in more detail what is in a particular segment. This is done using the -dump option for segread. Here we dump the first segment (again, slightly reformatted to fit this page):

s=`ls -d crawl-tinysite/segments/* | head -1`
bin/nutch segread -dump $s


Recno:: 0
FetcherOutput::
FetchListEntry: version: 2
fetch: true
page: Version: 4
URL: http://keaton/tinysite/A.html
ID: 6cf980375ed1312a0ef1d77fd1760a3e
Next fetch: Tue Nov 01 11:13:34 GMT 2005
Retries since fetch: 0
Retry interval: 30 days
Num outlinks: 0
Score: 1.0
NextScore: 1.0

anchors: 1
anchor: A
Fetch Result:
MD5Hash: fb8b9f0792e449cda72a9670b4ce833a
ProtocolStatus: success(1), lastModified=0
FetchDate: Tue Oct 25 12:13:35 BST 2005

Content::
url: http://keaton/tinysite/A.html
base: http://keaton/tinysite/A.html
contentType: text/html
metadata: {Date=Tue, 25 Oct 2005 11:13:34 GMT, Server=Apache-Coyote/1.1,
Connection=close, Content-Type=text/html, ETag=W/"1106-1130238131000",
Last-Modified=Tue, 25 Oct 2005 11:02:11 GMT, Content-Length=1106}
Content:












Alligators live in freshwater environments such as ponds,
marshes, rivers and swamps. Although alligators have
heavy bodies and slow metabolisms, they are capable of
short bursts of speed that can exceed 30 miles per hour.
Alligators' main prey are smaller animals that they can kill
and eat with a single bite. Alligators may kill larger prey
by grabbing it and dragging it in the water to drown.
Food items that can't be eaten in one bite are either allowed
to rot or are rendered by biting and then spinning or
convulsing wildly until bite size pieces are torn off.
(From
the
Wikipedia entry for Alligator
.)


B







ParseData::
Status: success(1,0)
Title: 'A' is for Alligator
Outlinks: 2
outlink: toUrl: http://en.wikipedia.org/wiki/Alligator
anchor: the Wikipedia entry for Alligator
outlink: toUrl: http://keaton/tinysite/B.html anchor: B
Metadata: {Date=Tue, 25 Oct 2005 11:13:34 GMT,
CharEncodingForConversion=windows-1252, Server=Apache-Coyote/1.1,
Last-Modified=Tue, 25 Oct 2005 11:02:11 GMT, ETag=W/"1106-1130238131000",
Content-Type=text/html, Connection=close, Content-Length=1106}

ParseText::
'A' is for Alligator Alligators live in freshwater environments such
as ponds, marshes, rivers and swamps. Although alligators have heavy
bodies and slow metabolisms, they are capable of short bursts of
speed that can exceed 30 miles per hour. Alligators' main prey are
smaller animals that they can kill and eat with a single bite.
Alligators may kill larger prey by grabbing it and dragging it in
the water to drown. Food items that can't be eaten in one bite are
either allowed to rot or are rendered by biting and then spinning or
convulsing wildly until bite size pieces are torn off.
(From the Wikipedia entry for Alligator .) B


There's a lot of data for each entry--remember this is just a single entry, for page A--but it breaks down into the following categories: fetch data, raw content, and parsed content. The fetch data, indicated by the FetcherOutput section, is data gathered by the fetcher to be propagated back to the WebDB during the update part of the generate/fetch/update cycle.

The raw content, indicated by the Content section, contains the page contents as retrieved by the fetcher, including HTTP headers and other metadata. (By default, the protocol-httpclient plugin is used to do this work.) This content is returned when you ask Nutch search for a cached copy of the page. You can see the HTML page for page A in this example.

Finally, the raw content is parsed using an appropriate parser plugin--determined by looking at the content type and then the file extension. In this case, parse-html was used, since the content type is text/html. The parsed content (indicated by the ParseData and ParseText sections) is used by the indexer to create the segment index.

吃遍深圳

1、上步国商那边有家韩国料理叫“相约烤吧”还不错价格也挺实惠。  

2、华强北民间瓦罐旁有一家四川小吃店,店不大但东东挺不错价格也还可以,口水鸡好象是10元一份。     

3、地王附近的工商局后面一条小巷有家湘菜馆也不错,好象叫“湖南人家”那的腊肠做的不错。     

4、草原情餐厅,电话:26974816.地点:南山区中山园路188号.正宗蒙古羊肉,价格便宜。  

5、南山区政府对面的富豪城,好像主要是粤菜吧,不记得了。只记得在一楼大厅吃饭,啤酒不要钱任喝。  

6、南圆路加洲红对面的那家顺德蛇城喝茶挺便宜的,大、中、小都是3:00元,味道最正的是那里的烤乳鸽,又香又便宜。 

7、佳和城大酒楼,中航路与深南中路交界的地方.喜欢喝酒的朋友们可以上那里去,菜也不太贵,每次下来每人20元左右。  

8、八登街有一家西安菜,做的十分不错,价钱又便宜,强烈推荐:羊肉拌面,10块银子,天上绝色。     

9、八登街的鱼香米坊,便宜而且最主要那二楼的环境顺德人开的,广东风味。  
10、八卦三路有个明记烧鹅王还不错,新开的,送餐电话82450696 

11、著名的潮州打冷,这里只提供最正宗且干净的地点,就在晒布路的深运大酒店。    

12、南油酒店中午喝茶是很便宜啊,半价!还有盐插虾8元/斤,片皮鸭18元/只,但二者只能选一。 

13、蛇口风华剧院那有家陕西风味不错哦~~价格巨便宜,土豆饼才3元/张,绿豆稀饭2元一大碗,撑死了别找我~~~ 

14、银湖车站有个金湖大酒楼,门前车总是满满的,基围虾1元一斤,炒菜9元,酒免费,但会收服务费若干,如果聚会这里也是个不错的选择,吃完后可上银湖公园遛遛。 

15、振兴路自上步路口起,到华富路口止,大小食肆林立。自东向西依次是:稻香村 军分区旁边的小巴站处 有海鲜,含部分徽菜口味 中午吃饭花上18元吃一条清蒸鲈鱼,真是很不错耶。 

16、醉翁亭 在稻香村后面 这是总店,徽菜口味。诚意推荐菜式:野鸭,鱼头煲,炒菜心,鸭黄豆腐,炒猪肝,炒腰花。物廉价美,尤其适合安徽,江浙一带,非常下饭,每次都吃的很饱才走。

17、巴蜀风 在燕南路和振兴路的交界处 深圳最火爆的川菜馆,其中的牛杆菌炒双椒,大漠风沙牛肉,冒菜什么的都很好吃,小心它的泡椒鱼头煲啊,我的嘴就是这样吃肿的。主食里的西红柿鸡蛋面也是不错的,就是要提前一点点,否则等好久。 

18、永和大王 巴蜀风西侧 不用我说了,一般无所事事,会去小吃一顿,干净卫生。 

19、家常饭 永和大王西侧 江西口味。不要点它的汤喝,反正我不喜欢。井冈豆皮,黄豆猪蹄,干焗大肠,糯米排骨或牛肉都是上好的东东。

20、乌江活鱼一条街 在巴蜀风后面的一条路上,没有路名。上面有很多家专吃鱼的店家,什么都一处啊,正宗乌江活鱼啊。四五个人进去选条三斤多的鱼,吃的很开心了。

21、外婆桥1  沿着活鱼一条街,往前走点,就可以看到一家外婆桥。这一家是专吃小吃的,没有炒菜,只有煲啊什么的。里面的蒜泥白肉和手撕饼味道很不错,糖醋排骨也是美味的, 就是没什么肉,而且我觉得做的焦了一点。 

22、外婆桥2 这里外婆桥有两家,往南走一些,左拐到底就是另一家。这一家主要做炒菜,我喜欢吃它的鸭血煲,说实话,这是我吃过的最鲜美的鸭血煲。!!!三星推荐。还有,千万不要吃它的全家福,味道还可以,就是太咸。 

23、潮州大碗粥 沿着振兴路往西走,过了招商银行,就有一家粥城。里面随便点吧,反正很便宜就是了。潮州的粥味道很不错的,他们用大米炒过之后才下锅,配一条红鱼,吃起来有 滋有味的。以后我会介绍更好的一个专门吃粥的地方给大家。

24、香辣蟹 过了大碗粥,拐进去就到了振兴食街,有三家做香辣蟹的。三家香辣蟹味道都不错,不过我喜欢中间那家,虽然右边那家最早味道也最好,但是中间那家态度好,吃的舒服。还可以点黄骨鱼吃,就是浑身黄色斑点的一种鱼,大小大概三个手指这么大,烫火锅吃真的很美味。

25、东北春饼店 在香辣蟹对面,进去就是死吃活吃。不过我最怕葱,蒜,菜,忌口,所以很少去。记得份量不要点太多,否则吃不完。 

26、名典及热带雨林 回到振兴路,就可以看到了。是两家咖啡屋,名典里面的生果沙拉和菠萝饭我还是马虎爱吃,但是跟好的西餐比起来就差劲多了。几个朋友聚会一起,倒是不错 的地方,海阔天空的聊。热带雨林挺差劲的,虽然当初上当有了它的贵宾卡,不如不要。过了华强北,就是振兴西路了,我这里把中航路也给包括进去一起说了。 

27、沿着振兴路西行,逐渐就超出单位500米圆范围了,所以就不是很熟悉了。路的中段西侧有一个南昌菜馆,吃过两次,具体吃的什么也就忘记了。但是这里是一个很重要的交界口,因为有好几家好吃的地方。  

28、华神火锅那个辣哟!天!店名好像应该是华神川菜馆,但是最著名的该是它的火锅。 下了班要是晚到了,就只有等位的份。店有两层,一群人围炉来个火锅,最是惬意不过。 只不过俺也算是逐渐成长起来的一个辣子手,到了那里就只有甘拜下风。不过同样的是, 几个四川、湖南的同事同样是对开锅汤不敢下嘴,冰冻可乐倒是去的飞快。反而是一个东北妹妹,刺溜刺溜吃个利索。我们是战战兢兢等她把汤面的辣油几乎扫光了,才开始呲牙 咧嘴的吃。星级推荐:猪肝,烫火锅从来没有这么好吃过。 

29、东北人 一句:翠花,上酸菜。着实把生意本来就红火的东北人,又给捧了一下。里面的姑娘小伙都是民族服装,啥民族服装,就是翠花和翠华那汉子呗。里面东西吃起来自然是大鱼大肉,吃的就是一个俗字,味道呢,个人觉得,酱骨架还是面点王的好吃。不过只要人多,随便点个什么吃,都是非常香。而且姑娘们一句一个大哥,叫得人心里暖呼呼的。 

30、面点王 始终觉得面点王还是开办的很成功的,无论如何一个石油企业,竟然开办起一个风牛马不相及的饮食行业,还是心生佩服。面点王的酱骨架,水饺,鸡蛋炒面,桂圆红枣粥,都是闲来吃饭的好选择。经常会在值班的时候去打包一份回来。华强北地区有两家,一家在燕南路和振兴路交界沿着燕南路往南走20米左右,一家在红荔路和华强北交界处,友情提醒,午饭或晚饭时间,请估计好具体人数再去,否则等位。 

31、家家鸡煲 在振华路和燕南路交界口往南走10米。原来有两家鸡煲店,后来家家味道好,服务也不错,就把另一家给吞并了。进去自然是吃它的传统奇香鸡煲,配上炸的金黄的腐竹,金针菇,味道很好。尤其是它的炸腐竹,是腐竹泡水后又沥干水分之后炸的,不像有些火锅店,不泡水就干炸,怎么煮都煮不开腐竹的皮,真是太没专业精神了。 

32、天天渔港 振中路上,铜锣湾量贩的对面。说实话,这是我们老百姓最能体现物廉价美的海鲜吃处。环境好,服务好,海鲜味道做的也很不错。其他不说了,就推荐它的点心--菠萝包, 里面的馅心真的有菠萝的喔,全鹏城独此一家。我每次有同学来要吃海鲜,都是带他们去那里吃。 

33、海上皇 振中路和华发北路交界处。是吃早茶,午茶,下午茶的绝佳去处。最喜欢吃的是它的牛杂,皮蛋瘦肉粥,白灼菜心(吃的时候淋上调好的蚝油)。其实还有一个很好吃,就是它的点心拼盘。不过一般不是熟客它不卖,你可以理直气壮的点,虽然菜牌上不写,坚持坚持,它就给做了,20元一份,每份是八种点心一起上笼蒸。在这里吃晚餐也不错,推荐它的芝士焗生蚝,才8元一个,每次都去吃两个,HOHO. 

34、小肥羊 振华路与燕南路交界,不过实在振华路口。羊的火锅。之所以这么说,是因为里面几乎都是羊的天下,看名字就知道路。什么羊肉,羊肝,羊蛋什么的,不过我坚决只 吃羊肉。这里吃火锅,没有小碗调料的。火锅的汤味道很好,不知道放了什么东西调味的,据说还不准打包,免得外泄。吃东西就是点羊肉吃咯,外加火锅通常都有的,不过味道真是很不错,可以理解我两星期内竟然去吃了四次,要预订。 

35、漓江又一轩 沿着小肥羊西行,就看见远远的一块绿色招牌,就是它了。这里是广西干锅口味,鸡煲鱼煲和鸭煲,不过我还是爱吃鸡煲,每种都试过了。两三个人去吃点个鸡煲就够了,青菜和豆腐是送的。它的吃饭是先吃干锅,然后快吃完了才加入汤水煮锅。千万不要吃它的任何鱼,反正我从来没有爱吃过。点心里面倒是有很多好的,对了它的糯米牛肉不错的喔,还有土豆片,香芋饼,可以一顿吃好几个。要是上火,还可以点个龟苓膏吃 ,降火的,据说是梧州的。其实我吃过正宗的梧州龟苓膏,苦死了,我还是喜欢吃甜点的。

36、北海渔村 深圳这个渔村那个渔村是铺天盖地,我喜欢来这家吃。随便点些海鲜吃,但 是最主要的是我爱吃这里的鲍鱼粥。不是那种大的,而是特价三元一个地,点30个小鲍鱼,然后煮粥喝,要半个多小时才能上桌。上次献血完元气大伤,狠狠吃了一顿鲍鱼粥,仿佛心理上才恢复过来。

37、穆斯林 去了很多次,还是不知道叫什么名字,反正那里就是穆斯林吃的地方。羊肉,羊肉。位置在南园路和爱华路的交界处二楼。里面都是新疆姑娘喔,好吃东西很多啦,比 如大盘鸡,羊肉汤等等。最好吃的当属羊腿,15元一个,这么便宜,吃的时候人手一腿,抓起来大啃特啃,不是一般的好。友情提醒:别点多了,吃个羊腿已经打倒一半了。 

38、巴香鱼头 沿着穆斯林店,往爱华路南走几步,就看见了。里面的鱼头做法很有特色,是炸过之后再放进汤里煮,配火锅吃的汤料也是干货,吃的时候勺火锅的汤进去搅和,然后再吃。味道奇特,值得一吃。 

39、图们烧烤 就在巴香鱼头的马路对面拉。爱吃它的烤鸡架子,就是爪子的筋,吃起来嘎本嘎本特别脆。其他的爱吃啥就点啥吧,可以让店员帮你们烤,免得自己回去都灰头土脸的。

40、山天 沿着穆斯林店,朝南园路的东面走100米吧,就看见山天了。我们喊它三个一, 因为商标就是这样的。里面也是吃火锅的,但是是吃菌类的,进去不用人指点,爱吃啥就点啥吃吧,火锅的汤底都是菌汤熬的,很鲜。菌丝炒饭是很不错的主食。最喜欢菌汤煮的鱼头了,一顿可以吃四五个,还意犹未尽。牛杆菌是我的最爱。 

41、沅绿回转寿司店,在振兴东路靠近华强北的地方,对面就是紫荆城。寿司倒不是非常感兴趣,爱吃的是它的鳗鱼饭,可惜我的肚子有限,每次都只能吃一份就饱了。不过配上的豆豉汤,真不是一般的难喝,不过有同事每次去都是帮我包喝的。 

42、江之鹤 振兴东路中段有个建设银行,旁边一拐就看见了。哇塞,好贵的说。晚餐每个人如果是吃自助,要168。吃过三次,最好吃的就是烤鳗鱼条,味道比沅绿好多了。尤其 是它的银鳕鱼西京烧,天哪,我有一回疯狂的点了四份吃,小姐肯定对我有意见了。第二次去的时候,他们就开始限制吃饭时间了,只给三个小时的点菜时间,其他随便。到第三个小时的时候,我已经饱的不能动了。 

43、舞鹤 又是一个广告贼多的料理店,在上海宾馆。不过说实话,自从上次自费去过一次之后,打死我都不会再去了,估计都是补偿广告费去了,不过骗妹妹不错喔。贵,而且我觉得味道不如江之鹤的好。不过料理吃过了,也就这么个样。罗湖商业城下面有一家料理店,是深圳味道最好的地方,有空大家可以去试一下,名字忘记了。 

44、罐罐鸡 这是一家小吃。就在我刚才说过的海上皇旁边,就吃的是一个一个砂锅的面或者粉。自然主打的是鸡,可以配猪肝,或者其他的菜牌上有的东西。吃的时候,从罐子里捞面条出来到小碗里,配以咸菜花生,汤本就是鲜的,很是爽口的说。     

45、家家长沙米粉店 唉,挤死了,每次去都是人山人海的,空调又不足,还这么多人爱吃。华强北地区就有三家,两家在华发北路上,靠近红荔路的地方。老板一定发财了,本来就只有一家的,一年之内在深圳市内连开四家分店。里面卖粉,也卖面条。什么大肉面啊,冬菇肉饼蒸鸡蛋面啊,酸辣面啊,什么什么的,都挂墙上,大家爱吃什么点什么。粉是宽粉,我不爱吃粉。面是碱水面,很筋斗的,唉,热就热吧,谁让你爱吃呢。每次吃完都是大汗淋漓。吃的时候还可以点红烧猪蹄,豆干或者绿豆汤喝,都是不错的。

46、深运粥城 名字是不是叫这个忘记了,位置在红荔路靠近华富路的地方。反正你沿着红荔路往华富路走就是了,在路的北侧。这里的粥集合了潮州粥的大全,不会点不要紧, 吃几次就总结出经验来了。 

47、香积世界素菜馆 在华强北丽人世界的背后,振兴西路靠近华强北的路口。里面都是吃素的,偶尔换个口味,去吃一下,也是挺不错滴,就是吃完了容易饿,毕竟现在的人都是肉食动物。 

48、深井烧鹅 据说是香港同胞过来开的。门面不大,不注意还找不着。在家家长沙米粉的对面,注意,这里说的家家是在华发北路东侧的那家,也就是说烧鹅店在华发北西侧。 进去如果一个人的话,可以点个叉鹅饭,意思就是烧鹅和叉烧,如果两个人以上,可以来个叉鹅例盘,吃个痛快。味道很正宗的说,的确如此。不过价格也不菲喔,简单一个饭要15,如果是吃一个烧鹅腿,要25。它用来蘸烧鹅的小碟汁,真是爽死了。

49、谭鱼头:新华宾馆对面,那个鲜、那个辣、那个麻真是不摆了

50、人民公社:西丽转盘往白芒关走,不到5分钟车程地方(路痴女人,交代不清,见

谅),所有服务生和店面装扮都是文化大革命时期。一律土锅、土碗,有很多鸟可以吃,干锅的,吃完做火锅,青菜免费提供,最绝的是楼上还有免费电影看,什么小兵张噶、渡江侦察记、、、很是过瘾川菜:

51、干锅系列:八卦三路平安大厦附近有一家佳和长沙米粉店,湘菜馆,服务不错,最爱吃他们的干锅肥肠,分量十足,蒸饭很香。

52、湘鄂情:   我弟弟狂喜那儿的瓦缸猪手

53、车工庙丹桂轩:  精致粤菜,  喜欢座在露台看高尔夫美景

54、上步吉之岛对正南面小巷一小店,有很正宗的双皮奶,拆鱼粥,陈村粉

55、湖南人家——皇岗中学附近,湖南人家在深圳开了6家分店了,但唯有皇岗店最好,是我吃过的认为最好吃最实惠的湘菜馆,推荐:香菜野山椒炒牛肉丝,干锅鸡杂,干锅田鸡,剁椒鱼头...价格不贵,就是份量少点。怕辣的人最好不要去吃

56、老四川——科技园深南花园的后边,专做川菜和粤菜,吃过一次川菜,12元一份的凉拌猪耳,28元的干锅鸡杂,份量足,狂辣,好吃。

57、喝早茶去格兰晴天二楼,小吃非常精致,猪肚、鸡爪、炒饭...好吃...

58、在深南路设计院 后面的凤凰路上, 有一家老成都(在沃尔玛附近),四楼的火锅也还可以,价格合理, 重点推荐的是三楼的自助餐--粗粮坊,各种小点,等,品种丰富,每位18元,有肚量大的朋友, 可以吃到很舒服。每次我去吃着吃着就不行了, 朋友门直惋惜。        很超值!

 59、在春风路穆斯林宾馆的对面, 名字叫撒哈拉一千零一夜。是深圳最正宗的中东风味的穆斯林餐厅。我和朋友常常去,羊肉茄子、哈达丝

MapReduce简介zz

MapReduce是Google 的一项重要技术,它是一个编程模型,用以进行大数据量的计算。对于大数据量的计算,通常采用的处理手法就是并行计算。至少现阶段而言,对许多开发人员来说,并行计算还是一个比较遥远的东西。MapReduce就是一种简化并行计算的编程模型,它让那些没有多少并行计算经验的开发人员也可以开发并行应用。在我看来,这也就是MapReduce的价值所在,通过简化编程模型,降低了开发并行应用的入门门槛。相对于现在普通的开发而言,并行计算需要更多的专业知识,有了MapReduce,并行计算就可以得到更广泛的应用。

MapReduce的名字源于这个模型中的两项核心操作:Map和 Reduce。也许熟悉Functional Programming的人见到这两个词会倍感亲切。简单的说来,Map是把一组数据一对一的映射为另外的一组数据,其映射的规则由一个函数来指定,比如对[1, 2, 3, 4]进行乘2的映射就变成了[2, 4, 6, 8]。Reduce是对一组数据进行归约,这个归约的规则由一个函数指定,比如对[1, 2, 3, 4]进行求和的归约得到结果是10,而对它进行求积的归约结果是24。

Map操作是独立的对每个元素进行操作,在FP中,操作是没有副作用的,换句话说,Map操作将产生一组全新的数据,而原来的数据保持不变。因此,它是高度并行的。Reduce操作虽然不如Map操作并行性那么好,但是它总会得到一个相对简单的结果,大规模运算也相对独立,因此也是比较适合并行的。

无论是Map还是Reduce都是以另外的函数作为参数,在 FP中,这样的函数被称为高阶函数(high-order function)。正是因为它们可以同其它函数相结合,所以,我们只要把Map和Reduce这两个高阶函数进行并行化处理,而无需面面俱到的把所有的函数全部考虑到。这样便形成了一个以Map和Reduce为基础的框架,具体应用相关代码写在用户代码中,之后与MapReduce结合获得并行处理的能力。当然,这么做的前提是按照这个框架的要求,把计算归结为Map和Reduce操作。为什么是Map和Reduce?从前面的内容我们可以看出,在 Map过程中,我们将数据并行,也就是将数据分开,而Reduce则把分开的数据合到了一起,换句话说,Map是一个分的过程,Reduce则对应着合,这一分一合便在不知不觉中完成了计算。所以,站在计算的两端来看,与我们通常熟悉的串行计算没有任何差别,所有的复杂性都在中间隐藏了。

所有这些并行化能力的获得都与FP有着密不可分的关系。事实上,不仅仅是MapReduce从FP中获得了灵感,其它一些并行编程模型也走上了同样的道路。 FP中有很多的好东西,比如自动内存管理,比如动态类型。在遥远的年代里,因为机器性能的原因,它们无法得到广泛应用,当机器性能不再是瓶颈,这些东西便逐渐复活了。

前面提到过,并行计算对于普通开发人员来说,有一个比较高的门槛。从前我们或许可以不理会并行计算,但是随着Intel开始将多核带入人们的日常生活,并行计算将会变得更加平民化,毕竟谁也不希望自己机器里面的多核只有一个在干活。现在的许多操作系统会把多核视为多处理器,但那也得有多任务才能在CPU处多分得一杯羹。对于服务器端应用来说,拥有多任务的能力是一个正常的现象。但对于很多桌面应用来说,一条道跑到黑的情况比较多见。而且,多任务并非为并行计算专门准备的,所以,控制粒度是很大的。如果需要更细粒度的并行计算,至少从表达能力上来说,多任务就有些麻烦了。

并行计算进入日常开发的难度就在于编程模型,太复杂的东西会被人唾弃的,CORBA在这方面已经是个反面教材了。MapReduce已经为我们演示了一种可以接受的编程模型,接下来,变化还会有,Intel和AMD都在努力。不过,具体的进程得取决于多核CPU占领市场的进度。

酷讯创始人做客白银时代

  新浪科技讯 8月7日10点30分,酷讯网创始人陈华与吴世春做客新浪白银时代,就酷讯网生活信息搜索、创业、融资等话题与新浪网友交流。酷讯是一家成立只几个月的生活信息搜索网站,提供找工作、租买房、买火车票等服务,陈华表示做酷讯的一个原因是他觉得目前搜索网站的功能不令人满意,酷讯只用3个小时就成功融资的经历证明了资本市场对他们


的看好。以下为聊天全文:

主持人:各位网友大家上午好,今天我们“白银时代”邀请的嘉宾是酷讯网的CEO陈华,跟酷讯网首席运营官吴世春。广大网友除了可以通过电脑参与聊天外,还可以通过手机访问新浪网,在移动中关注聊天的全过程,手机新浪网的网址是sina.cn或者是3g.sina.com.cn。请两位网友跟大家打声招呼。

陈华:大家好,我是酷讯的陈华。

吴世春:大家好,我是酷讯的吴世春。

主持人:酷讯这个网站是做生活资讯搜索的网站,应该说还是一个比较新的网站,请陈华介绍一下这个网站。

陈华:我们公司成立其实才几个月的时间,网站运营是今年的1月1日上线的,从3月份开始组建公司,到今天公司大概30多位员工,但是我们整个网站的运营非常成功,但是现在已经是一个非常快速成长的阶段。

主持人:为什么是非常快速成长的阶段?

陈华:一个是我们拿到了风险投资,另外我们发现我们现在所做的事情,所面向的市场非常巨大。因为生活信息是每个人都需要的,我们有我们独特的技术,有搜索引擎的技术帮人家解决找到生活信息的问题。

主持人:看了一下两位的简历,应该说工作经历比较丰富,之前也做过一些搜索,包括其它一些事情。您当时怎么想到要做生活信息搜索?

陈华:最早做酷讯我们并没有想到做一个生活信息搜索。一个是我原来做搜索引擎做了很多年,大概6年。从最早在天网做FTP搜索,后来在微软做微软的LIFE社区。搜索殷勤是一个非常强大的系统,能够帮人们解决很多问题,我们最早做酷讯想的是去做火车票搜索,因为当时赶在年前,想做一个系统,我去帮用户把互联网上散落的到处的出售火车票的信息给具体起来,用搜索引擎的方式展现给用户,就是这么一个很简单的想法。但是我们做出来之后,很多用户觉得这个东西太好了,火车票可以做,租房可以做,别的是不是也可以做?这样使我们发现了一个相当于非常大的市场在里面。这就决定了要成立公司,走一个创业的路子,把它做大。

主持人:你们两位是怎么认识的?两位怎么开始合作,创始这个公司?

吴世春:我们是2003年的时候,因为我跟陈华的一个同学段晖在百度是同事,当时在聚会的时候,段晖把陈华介绍给我认识,一聊发现两个人说的都是同样的话,都是同一个地方的方言,虽然他是在广东,我是在江西,但是我们都是在两个省的交界的地方,隔着只有一座山,很有缘分。陈华也是我见过的最好的技术天才。

主持人:对,我看陈华在很多公司都做过技术的开发工作,最早是做天网的开发,其实我之前也用过天网FTP搜索,也挺好用的。你当时开发这个应该说也是一个比较成功的技术。

陈华:对,我当时做天网FTP的时候其实是大三,主要的一个想法是,在北大学了那么多东西,想去做一个实际的系统,我去天网做了天网FTP搜索,这个东西本身技术含量不高,而且在学术界大家都觉得web搜索很复杂,FTP搜索很简单,我真正能够满足交易网的需求,结果发现这个东西越做越成功。从2001年到2004 年的人估计都用过这个FTP搜索系统,之后我想做让更多人方便的事情,现在用搜索引擎的东西帮你实现系统,非常方便用这个东西,我最喜欢我做了一个系统,上百万人、上千万人使用它,我很有成就感,这就是为什么我以后一直坚持走,要么搜索引擎,要么P2P,走大规模服务系统的方向,这个方向我自己非常喜欢,而且也相对来说做得比较成功。在微软,现在LIVE社区,有好几个功能都是我做的。像这些东西一直以来积累起来的经验,对现在做酷讯这件事情非常有帮助。

酷讯创始人做客白银时代:搞定融资只用3小时
陈华、吴世春与主持人交流(图片来源:新浪科技)

主持人:天网确实很好,它的市场,很多交易网用的不是太多,这是为什么?

陈华:一个非常重要的原因是商业化运作的问题,这也是酷讯经常跟员工说的事情,首先酷讯要走一个技术型企业,这个企业以技术为核心,运营的方式是以外企的风格运营,我们不是一个民企,也不是一个国企,这样做出来的企业,一个是执行力非常强,活力非常好。但是天网是属于学校的研究产品,没有一个公司化,现在有一个公司,但是公司商业化程度不是很高,是这样在运作,可能真的跟百度做竞争,真的发现有很多执行上的缺陷。但是像酷讯,我做酷讯有另外一个理由,我曾经创过一次业,这个对于酷讯的公司运营方面是一个非常重要的因素。

主持人:世春跟陈华的工作怎么分工?

吴世春:技术方向、产品方面是由陈华工作,我的工作主要是对外比较多,像合作,还有公司一些日常的运营方面的事情。

主持人:你相对来说技术方面不是太多,主要是由陈华负责?

吴世春:虽然我也是技术出身,但是做了分工以后,我说好几个月没有写过程序了。

主持人:从技术开发第一线走向管理方面的合作。

吴世春:对,因为分工的需要。

陈华:其实对一个企业来说,需要有一个人非常专注地做一件事情。运营也好,技术也好都是非常专业的,如果技术做得很好,但是如果运营不是很成功,假如用户不知道这个东西也是一个缺陷。所以,我们分工很清楚。我的目标就是怎么样把酷讯做得更加好用,而且让更多的人参与,吸引更多优秀的人才加入到酷讯来做创业的事情。世春的目标是怎么样让酷讯使更多人知道,让公司运营方面更加健康,整个结构更好。

主持人:刚才陈华说到世春可能之前创过一次业,介绍一下之前的创业经历?

吴世春:2004 年5月份离开百度,后来我和另外一个朋友创立了一个公司:北京商之讯软件有限公司,这个公司也是技术型公司,提供网页绘画的公司,现在活得也非常健康,在网络客服这个领域还是第一名的。在那个公司里我既学到了经验也学到了教训,学到很多东西,我在那个公司算是首席技术官。在那个公司两年的经历,对于酷讯的运营来说有些帮助。

主持人:你后来为什么离开那儿?

吴世春:我跟陈华是一样的,我认为做搜索引擎去改变更多人的信息获取方式,改变更多人的行为,我觉得这是一件更有意义的事情。TQ.CN公司是专门为企业服务的,我觉得做为很多网民、很多老百姓都能够使用的服务,更有价值。

主持人:更有意思?

吴世春:对,更有意思。

主持人:陈华的经历还是很多,包括你还在UUME做过,在那个公司因为做的是跟搜索关系不是很大的事情。

陈华:我在研三的时间,兼职的身份在UUME做了半年时间,整个系统都是我设计的。主要是后面我觉得UUME的发展方向是抄袭美国的方式,不像酷讯现在做的事情是完全找不到一个拷贝的模式,完全是自己创新。还有这种模式在中国究竟能不能实施出来,是很大的疑问。在美国大家都愿意公开自己的真实资料,在中国行不通,而且也是背离我以前做的P2P、搜索引擎的方向,所以离开了。之后去了微软,微软还是比UUME好。

主持人:在微软也是做搜索引擎的开发?

陈华:对,我在微软亚洲研究院做开发,参与的项目有MSN里面三个社区:微软中文搜索引擎、微软购物搜索引擎、微软学术搜索引擎,在这里面学到非常多的东西。

主持人:确实微软的搜索,虽然说现在在市场上还没有特别成功,但是他们在这方面投入还特别多。在微软学到了一些经验也好或者是开发的过程,可能跟现在做的生活信息搜索有一些不一样?

陈华:我在微软学到更多的东西是项目的管理,这是最重要的。因为在微软有三驾马车,由三个东西来组建构成一个项目的研发整个过程,保证我产品的质量,这种方式今天酷讯也一样,像我们现在产品经理有4、5个,测试也有2、3个,这种方式使得:第一,所做的东西都是市场上需要的,我们有一个很强的背景调查,去调查这个产品的需求,有一个很强的测试,保证这个产品的质量。像微软这种经验,还有在微软里面开放的企业文化,基本上很多地方我们都抄到酷讯来了。使得酷讯大家来这边工作,给每一个人有一个最大的空间,有一个很安静的角落可以思考、创造,整个产品上要有很的创新,有很强的产品执行力去推广,这就是在微软学到很重要的经验。

主持人:现在酷讯跟什么公司有一些合作?或者是酷讯在市场上推广是有一个什么样的方式?

吴世春:我们跟地址厂商有合作,比如在我们的网站上用户搜索,可能连键盘都不需要,用鼠标在地址上面拉个框,就能把他所需要的信息找出来。这是一种非常大的创新,使得很多老百姓更方便使用搜索引擎。很多老百姓可能来到百度、Google,不知道输入一个什么关键词找他的信息。对于中国的老百姓来说,有几万信息是他最需要的。比如“找工作”,现在中国就业率还不高。“找房子”,不管是租一套房子还是买一个二手房,都是一件非常痛苦的事情。还有春运的时候买火车票。这些都是非常紧缺的信息,很多人由于信息不对称,没有办法知道自己去哪里找到这些信息,就造成很多人必须花高价格,必须遭受中介的盘剥,才能汇集到这些信息。

  酷讯想提供一种最简单的方式、最易用的方式,让用户去找到这些信息。包括在地址上面拉框就能搜索的方式,这是一种非常大的创新,这是我们跟地址厂商的合作。

  我们跟一些旅游公司,比如跟通讯旅游网也合作,找一些旅游信息,同时也能很方便地找到需要的火车票、机票之类的信息。我们还跟“58”合作,因为 “58”这种公司代表一种信息的发布领域,我们是代表一种信息的集成或者是处理搜索引擎的领域,我们跟它们是上下游的关系,并不存在非常强的竞争关系。所以,我们会跟垂直的网站、工具网站、信息发布网站进行很紧密的合作。

酷讯创始人做客白银时代:搞定融资只用3小时
陈华:酷讯可以即时索引信息,目前Google、百度无法做到(图片来源:新浪科技)

主持人:在市场上有没有一些推广?比如说做广告怎么样?现在还没有?

吴世春:酷讯发展到现在主要还是靠口碑相传。很多人自己买了一张火车票,会告诉同事、朋友到酷讯那里买火车票非常快。如果他租了一个房子,那天有一个朋友打电话给我,觉得酷讯太神奇了,他在酷讯花了一分钟就找到他所需要的房子。这个信息他打电话问的时候,房东也非常惊喜,因为房东发布信息的时候才两分钟,两个人在电话里都感觉惊呆了,觉得这种体验太好了,他说我以后会成为酷讯的粉丝,会向朋友介绍到酷讯找房子、找工作等等。

主持人:酷讯怎么来收集信息?

陈华:我做酷讯其实也有以前的一些技术积累,一个是搜索引擎的技术,搜索引擎的技术体现在两个方面,一个是怎么样把信息最实时地抓取下来,人家刚发布的,我马上要抓进来。

  另外一个技术还是搜索引擎的技术,怎么把信息抓取以来给用户用到。这种信息在今天的中国即使百度和其它搜索引擎厂商都没有做得好。百度搜索技术可以做到 5分钟更新,但是网页可以做到好几天的更新。Google你要找到一小时、两小时之内的信息,基本是不可能的事情,但是在酷讯你基本可以找到一两分钟的信息,这是我们非常好的技术所在,怎么把信息实时抓取、索引,这是一块。

  另外抽取,互联网网页那么多,怎么知道哪些是用户需要的?而且需要的信息有哪些属性?有两个方面,我要把所有的网页分出类,这是房产,这是火车票的,这是招聘的信息,分出信息之后,把里面那些属性给抽取出来。用户在酷讯的一个搜索引擎页面上,基本上能够满足所有的需求。这两个特点使得用户在酷讯上找东西,一个非常及时,时效性非常强。第二,基本上能够在当前结构页上能够做比较。所以,他要看更多的信息,需要点击到原始的网页上。但是我们用这种方法能够减少用户找到信息的代价,基本上敲一个关键词就能看到最近互联网上符合他条件的一种信息,这种方式,最近黄波给我们做了一次评论,他说酷讯在搜索引擎上提出了第二维、第三维的东西,一个是时间维,一个是地理维,两个维度。这两个维度真的是黄博士一针见血地指出我们真正的优势所在。我们确实是按照时间排序,因为生活信息时效性是最重要的。地理可以精确到一个城市、一个小区,去看周边的信息。这两点使得我们很大程度上区别于百度、Google,因为百度、Google没有时间、地理的概念,这两点使得酷讯真正能够解决用户生活的需求。

主持人:这些信息实际上还是通过有人去各个网站抓取信息,不是由用户输入?

陈华:对,都不是用户在我们的网站上发布。这样我们可以跟58这种分类信息合作,或者是跟行业网站,比如焦点、搜房合作。我们跟它们的关系是,我给它带流量,它没有损失。对它来说非常愿意,这种行业网站、分类信息网站都非常愿意跟酷讯合作,酷讯等于是使我们这边的用户往那边流,不会阻挡这些用户。这样使得我们在行业上合作是非常顺利的,我们不做发布。这是最关键的一点。

主持人:比如我在酷讯上可以搜到各种各样重要的信息,就不用其它的一些焦点、搜房网去查。

陈华:我们的信息虽然抽了一些数据进来,但是永远不是最完善、最原始的信息,如果你想点击也可以看,我们不会阻止。就像你今天搜百度可以看到摘要,但是摘要可以满足你吗?

主持人:怎么抓取这些网站?

陈华:我们抓的这些网站完全是用程序的方式去发现,就有点像百度一样,整个互联网上扫,这个范围非常大,而且没有人工干预,这也是属于我们的一个非常吸引投资的一个技术优势。我们不需要几百个编辑在那儿找网站,或者是配模板,所有的东西都是自动的,我们有程序自动发现这些网站,自动抽取这些信息,不需要针对58配一个模板,现在把58的网址放进来,不需要做这个事情,全是程序去做。这样使得我们的整个系统,可以说我们把互联网上60%、70%的生活信息全抓过来了,而且抓的精度达到95%以上。这样想想你在酷讯上能看到的信息基本上覆盖了整个互联网上你能够用人工找到信息的大部分。

主持人:我的意思是说,你们的收入会来自于哪里?

吴世春:酷讯作为一个搜索引擎,收入模式当然会具有搜索引擎的模式的一部分,比如现在比较成熟的竞价排名,Google相关性的网站,这会作为我们以后收入的主要模式。但是除了这两个模式,酷讯还有一个很明显的特点,它抓到的信息里面是有需求部分,有供给部分。有人需要,也有人提供。我们可以把这两者进行匹配起来,我们为需要信息的人、租房的人提供求助信息,为求助的人提供住房信息,能够给他们创造增值的价值。一个人可能不需要上网就能搜到来自酷讯的匹配,比如今天想租中关村的一居室,可能没有时间上网,但是可以实时搜到最新的匹配中关村一居室2000块钱以内的租房信息,这对他是有价值的,能够解决用户问题的部分肯定会带来收入。

主持人:比如用户可以通过订阅,支付一定的费用。

陈华:我们不会向最终用户收费。因为我给你发信息的时候,带一条广告肯定不会排斥,因为你收到一个真实有价值的东西,带着相关的广告,你愿意看,不需要支付任何费用。从酷讯的发展来看,更像是在百度和Google的引领模式去走,不向用户收费,向企业收费。

吴世春:模式是通过广告订阅,但是不会向用户收费,都会通过很多方式。

主持人:主要是跟企业这边收费?

吴世春:对。

主持人:现在有收费吗?

陈华:现在没有收入。

吴世春:现在企业要求在我们这里打广告,像潘石屹的现代SOHO城。但是我们现在还是要提供一个干净的完全无广告的搜索引擎。

主持人:可能你们觉得时机还没到?

陈华:对,时机还不到。

吴世春:投资人也没有给我们收入盈利的压力。

主持人:你们当时投资做搜索引擎,是不是觉得百度也好、Google也好,没有满足很多人的一些需求?

吴世春:对。

陈华:经常有人问我酷讯跟百度、Google有什么不同。我就跟他说,你去百度、Google,你假设想找一个中关村租房信息,敲一个中关村租房,你再去酷讯查同样的信息,你就发现百度、Google根本找不着信息,你查中关村租房,出来的都是什么什么网站,仅仅是网站的首页,不是信息本身。你点进去之后,可能还要找半天才能找到这条信息。而且你即使在上面偶尔出现一条是真的符合你需求的出租信息,但是很有可能不只两三天,是十几天、一个月以前、两个月以前,那这个信息还有什么意义?

  我们发现从垂直搜索引擎这个方向一个一个方向去做,用这种方式使得用户在这里用一个查询就能找到他真正需要的信息,而不需要在百度、Google上找了半天,点了十几次链接,才能找到令人满意的地方。

主持人:技术开发是不是比他们有些难度?

陈华:确实是,刚才说有两块技术壁垒,怎么做实时抓取、实时索引。另外,怎么把信息抽取出来,因为想抽取不是那么容易的。比如有人说“我在华星家园住着,租了一个两居室,住着很舒服”,有在“华星家园”、“租两居室”的信息,是不是关键词呢?不是。但是你去百度查,很可能把这种信息给找出来。但是在酷讯我们有一个很强的垃圾过滤的策略,还有信息抽取的策略,这其实是非常有难度的事情。

  还有一个难度是地图,可以看到酷讯上现在不但房产有地图拉框的搜索服务,招聘、餐馆也有,把所有的信息在整个经纬度上标一个经纬度,给信息标经纬度,标完以后可以在地图上,比如选一个框就要中关村的房子,不需要别的地方的房子,这样中关村可能很多地域你不知道,比如这里有一个叫黄庄、海淀南路、海淀路、北大,地名非常多,但是你拉进来,就可以把各种各样地名的信息全部找进来,这些都是符合你需求的。像这种技术,其实在今天来看还是非常难得,尤其是像百度、Google的地图服务,还局限于本地信息、餐馆、旅店、加油站信息的搜索,这种信息是静态的人工去标地理位置的一种信息,做不到动态标动态数据的位置。

酷讯创始人做客白银时代:搞定融资只用3小时
吴世春:做搜索速度最重要,融资也要越快越好(图片来源:新浪科技)

主持人:这些大的公司是不是将来不会走这条路?

陈华:不能这么说,可能他们有市场会做这件事情。但是不管哪个公司做,我们在之前的半年以来,酷讯的技术积累以及我六年来做搜索引擎的技术积累,这都是一个门槛。对别人来说,他可能也要说第一我怎么样做这些技术,怎么把这个东西做好。第二,怎么解决用户体验的问题。因为可能这边有很多策略是非常奇怪的,比如租房信息,像南开那边叫单间、一居,在天津的叫法跟北京不一样,每一个地区有本地的特征在里面。我们现在经过半年多研发的优化,在里面积累了非常非常多的经验,以至于一个页面上那么多联系方式,可能联系方式是网站的联系方式,有可能是真正发布信息的联系方式,也可能是一个客服的联系方式,你怎么判断出哪个联系方式是信息本身的联系方式?还有一个信息什么都没说,只说到我要租一个很小的小区的房子,你怎么知道这个小区是哪个城市的信息?这些东西对于后来的人来说都是一个难点,但是我们现在都已经解决了。

  所以,我们并不担心百度和Google来做这件事情。反而我们已经做得比较成功了,有信心在时间上远远超过他们。

主持人:你们现在包括工作,包括租房,还会增加其它生活的信息吗?

陈华:会增加,但可能不会增加太多。我们做每一个栏目都想:第一,这个东西的需求有多大。比如配钥匙的电话多的是,但是你觉得这种需求有达到一个规模吗?有商业价值吗?如果没有达到一定规模,就没必要做这件事情。我们就看生活信息上面哪些东西用户需求非常大。互联网上信息很多,我们把这种东西聚集起来。而且可能还有一个非常重要的因素是,我们要看这种信息的集中度怎么样。比如说某一种信息整个互联网上就一家网站有,我就没有必要做,抄它干吗,没有意义,用户都上那里去了。我们更多是用搜索引擎技术查找分散的信息。

主持人:说说关于投资的问题。你们也是获了一笔投资,介绍一下这个投资的一些情况,包括你们什么时候拿到的?

陈华:我们当时拿投资,有可能是,据我了解应该是现在所有创业公司拿投资最快的一家。

主持人:多快?

陈华:非常快。当时3月9日的时候还在美国出差,回国前一个晚上发出商业计划书,然后回国后第二天一大早联创策源就打电话说今天下午一定要来,我就过去,之前不认识他们,因为只是拿了一张表,随便发了一些投资人,不认识,也不知道谁牛谁不牛。就打电话让我去了,从下午大概3点多钟开始,到5点多钟就基本定了,6点钟签约。

主持人:6点钟就签约了?

陈华:对,非常快,整个从认识他们到签约3个小时搞定。

吴世春:中间也不需要演示商业计划书。

主持人:为什么?你们后来有没有签其它投资商?

陈华:我们签完以后很多人说不给我们机会,连给他们考虑竞价的机会都没有。因为当时我们也其实在想,我们太顺利了,一个是我们做这个东西做得非常好,投资人来看这个市场非常大,我跟世春都是搜索引擎出身,他们相信我跟世春的能力,能够把这个事情做出来,所以毫不犹豫投资给我们。而且他们的口碑也非常不错,先把钱拿到手,先把事情做起来,因为我当时还在微软,还没辞职,世春还在原来创业公司没有出来,两个人都是属于创业的感觉。然后拿了投资就开始把这件事做出来,而且我们也是觉得那个阶段拿到投资是非常合适的一个阶段。

主持人:应该说数量也不是很大,应该作为一个创业基金是比较合适的。

陈华:对,在这个阶段是足够的。

吴世春:投资人看一个事情能不能做起来:第一,看这个事情本身空间有多大,你做的事情能不能真正解决问题。第二,看看你的团队执行力怎么样。第一,他们觉得我们做的事情是真真实实解决老百姓的问题,解决老百姓买票难、租房难、找工作难的问题。而且每一个查询的下一步就是交易,这个市场空间非常大。在中国十几亿人口,我们就说城里面有5、6亿,5、6亿人口,需求量非常大,这个市场空间非常大,所以觉得这个事情有价值。另外,他相信陈华和我两个人的背景,有助于做好这件事。它跟我们合作的过程中,看到我们的执行力,觉得我们能够很快把这件事做好。我们一直也很感激它,因为它不会像别的投资人一样考虑半天,看你的商业模式,不断问你什么时候盈利,不断问你什么时候达到盈亏平衡点,需要做很长时间帮你做GD,它没有这个。它就认准你能解决问题,你们两个人能够把这件事情做好就投了。投了以后,资金两个月就到帐了,这也是非常快的。它动用很多资源帮我们解决注册等等问题。我很了解一些商业公司可能3、4月份也签了,但是8个月还没到帐,我们两个月就到帐了。

  因为像搜索引擎只能做大,只能做快。我们从3月份组建公司以来到现在,一个是产品已经推出4个版本了。再一个我们的团队已经变得很强壮了,技术团队大部分都是来自清华、北大、南开这种名校的计算机技术天才。还有一些来自大公司的骨干、精英。我觉得我们组建的这支搜索引擎技术团队,在中国来说至少应该排名在前四名的搜索引擎团队。

陈华:我当时在水木和在教育网也做了一些宣传,我之前在做FTP搜索,FTP的影响还是很大的,我打了这个宣传,影响还是很大的,我之前做FTP还是很成功的,而且是非商业化运作情况下做得很成功。现在我商业化做酷讯,有可能3、4年后我们就把它推上市了,完全是有可能。这是我从技术的角度上觉得不存在问题。运营上,这几个月来我们的经验,觉得现在执行力非常强。做什么事情,比如一个月上一个版本,到时真的就推出了一个版本。虽然我们执行的方式、三驾马车的方式,使企业快速推进、快速成长,对于所有的员工,还是未来想参加酷讯的人来说,都觉得这是一个很有潜力的公司。我们现在招的这些人都是非常聪明的人,有很多来自数据挖掘方向的、搜索引擎的,各个方面的人才聚集在一起。因为搜索引擎需要技术挖掘、搜索引擎的技术人才。这是非常强的团队,所以百度、Google我不是特别担心,也是这个原因。

主持人:这个过程太快的话,风险投资公司非常认可你们这种商业价值,但太快是不是有些遗憾?比如估价太低,有没有其他VC给你们更多的投资。

陈华:找风险投资不竞价,而是你找一个合适的。找风险投资不是为了卖掉这个网站,而是找一个合伙人的感觉,要找一个真正能够给我带来很高价值的人,能够帮我们解决,比如外面的人能够帮我拉到更多的钱,从企业结构上能够帮我挖到真正核心的人,有这种资源,能够介绍一些人帮我推广,这种方向找一个很好的合伙人,也是我们接下来要做下一轮融资,怎么样把一个最好的合作伙伴给介绍进来。

吴世春:风险投资有4个因素:第一,要求的时间,什么时间钱给你。第二,要求的条款,会给你提什么要求、条件。第三,你要拿到多少金额。第四,你的价值是多少,要提供多少股份。我们比较追求的是第一,我们时间要求非常快。第二,条款要求比较干的条款,不要他给你提出过多要求,使你整个执行变形,整个方向是迎合投资人的角度考虑。因为投资人的专业方向是投资,把这个事情做好应该是由创业团队把握。所以,我们对前两点要求比较高。至于像金额和价格,反而没那么重要。对于搜索引擎的公司来说,速度永远是第一位的。3月份拿到一笔钱,假如这笔钱是200万美金,你跟它磨上半年,8月份拿到500万美金。我觉得200万美金比 500万美金的价值还大。

主持人:现在你们的钱主要还是用来招聘员工?

陈华:一个是产品开发这一块,需要更多的人。另外,网站的运营方面要花很多钱。我们招人需要跟大公司竞争最优秀的人才,这方面也是最花钱的东西。我们要给员工一个非常宽松的环境,我们马上要搬家,想找一个让所有员工都觉得我在这边是非常安静的一个角落,可以把我所有的创造力奉献给这个事业,大家一起创业,这是最重要的,大家把事情做好。花钱的点主要在这一块,当然市场也需要花钱。我们市场方面主要注重一些点,用口碑相传的方式把酷讯散布到全中国的每一个角落。因为我们现在的服务不但是北京有,有全国200多个城市都提供了搜索服务。我们在一个点上有一个很小规模的宣传,在当地会形成一种点到面的传播的过程。比如我租了房子,我告诉所有的同事,你要租房子到酷讯看看吧,没有中介。还有买火车票买不到,酷讯上一搜就好几张,不要去那边排队。像这种口碑相传的作用非常明显。

主持人:你们当时创业,一方面你们觉得做这个事情很有价值。另外是不是也受到一些环境的影响,创业很热门。

陈华:环境的影响对我影响并不是很大。说当真的我当时去组建这个公司,有一点点说我拿到了投资,才向公司辞职。一开始没有为了创业而创业。而是说我今天走到这个阶段,一个是市场的需要,一个是这么多用户需要,我必须把它做好。这样促使我去创业。而不是说我可能看到国外一个很好的模式,我抄过来,为了赚钱而赚钱,这是两种方向。而且今天来看,酷讯这个东西在美国甚至都没有,我们现在投资人还问我什么时候做一个美国版。我在想中国的事情已经足够我做很久了。

主持人:发展的计划是什么?未来几年会是什么样的发展目标?

陈华:发展一个是产品方面,我们争取用半年不到的时间,把产品真正做到让任何一个用户来了酷讯都想下次一定会再来,一定会介绍给我的朋友,达到这个效果,让大部分用户不会觉得这个对他没什么用,他觉得这是一个很好用的东西,一定要让很多人知道它,要达到这个目的。现在我就用普通的口碑相传的方式散播出去,让很多人觉得真的要让更多人用这个产品。半年内把产品做得很完善。

  市场方面,我希望在明年中期酷讯能够跻身到中国搜索引擎排行前几位的角色,比如5、6名之内的角色。当然具体多少名也要看市场的发展。

主持人:大概什么时候开始有一些盈利?

陈华:盈利在这个阶段我们还不考虑。当你有很多有商业价值的用户群存在的时候,盈利是理所当然,而且是轻而易举的。如果你没有这些用户,说什么都没有用。比如我们用一年多的时间,把整个用户群给建立起来,我们去做各种方向的盈利手段。其实我们不向最终用户收费,所有用户会觉得对他没有影响。而且对企业来说,比如所有租房子的用户,可能购买新楼盘的潜力就非常高。或者说你去查询中关村一个房子的信息,有可能非常关心中关村购物房产的打折信息、促销信息。像这种商业价值就非常高,企业就愿意在我们这边投广告。这也是我们觉得盈利在这个阶段我们不用想那么多的原因,先把用户群做起来。

主持人:看到你们每天的访问量现在大概是几百万,你们有多少用户量的概念吗?

陈华:我们没有具体多少用户量的概念,但是我们更重要的是快,就是查询量。

主持人:一个技术架构在小的时候可能比较好用,做大了以后会不会有些问题?

陈华:这个问题我们早就考虑了,一年前我们做火车票搜索,当时1月1日上线,1月19日的时候我们排名就创造2000多名,服务器就不停地崩,因为有太多用户想冲上来用,但是我们的服务器结构没有做好。当时逼得我们非常痛苦,这么好的东西大家想用用不了,我们之后用了大概3、4个月的时间,一直把这个结构去改进,怎么样达到更多的用户加一台服务器就能解决,更多的数据加一台数据库就能解决。我们用存储的分布式系统,今天酷讯的结构已经达到上千万用户甚至上亿用户都能够得到划分。也得益于我们之前做MSN社区的一些结构,做天网的一些结构,还有世春在百度里了解的百度的结构,我们把各个公司的优势结合起来,去搭建真正能够支持上千万用户访问的平台。

主持人:由于时间关系,聊天就要结束了。两位还有什么需要想跟网友说一下的吗?

陈华:一个,我们是做一个能够解决用户真实生活需求的服务,酷讯真的能够在未来半年内给广大网民提供越来越多很方便的服务。大家也会觉得酷讯这种服务能够解决生活中的难题,以后这种口碑相传的效果肯定会非常明显。希望所有的网友有空上酷讯看一眼,有可能你今天不租房子、不找工作,但是当你找工作或者是租房子的时候,会想到酷讯真的能解决你的问题。

吴世春:第一句,找工作、找房子、找火车票,上酷讯,酷讯能解决你的问题。

  第二句,希望技术天才和想创业的人可以加盟酷讯,一起来打造一个中国生活搜索引擎的……

陈华:我们要搭建一个以技术为核心,相当于我们做的是下一个百度,以技术方式造福整个互联网。这种东西对所有的有技术天才的人来说都是一个很好的创业机会,而且对每一个新员工来说,我觉得像我们成长的空间非常大。

吴世春:酷讯欢迎一切技术人才加盟,而且酷讯会提供非常优惠的薪水和期权,特别是期权,让每一个人在这里实现人生价值和实现人生的目标。

主持人:希望酷讯发展得越来越好,聊天到此结束。

HousingMaps网站研究

www.housingmaps.com是一个简单的房地产搜索引擎, 这个资源可以让用户访问目前非常流行的Craigslist数据库,搜索租房和供房信息,并以地图的形式显示查询结果。Craigslist是旧金山非常有名的一个分类广告目录数据库。使用Google Map API,用户们可以搜索和地图显示以城市和价格排列的租赁住房信息。在这个例子中,我查询了价位在1500-2000美元的租房信息,用户可以通过选择包括出售、租房和转租列表来进一步限定他们的搜索范围。更多城市的租房信息已经逐渐被录入到这个数据库中

其中有两点特色: 如果把地址信息自动关联到地图上, 另一个是图片信息的关联

采用的显示是基于城市的, 主要是通过价格来过滤, 当然还可以通过其它方式来...

CSS style属性和值

CSS定义格式 A.B #C {} 其中A为指定element, B为属性class的值, C为属性id的值

Name

Values

background

[background-color ||background-image ||background-repeat || background-attachment ||background-position]

background-attachment

scroll | fixed

background-color

color | transparent

background-image

url( url ) | none

background-position

[ [percentage | length ]{1,2} | [ [top | center | bottom] || [left | center | right] ] ]

background-repeat

repeat | repeat-x | repeat-y | no-repeat

border

[ border-width ||border-style || color ]

border-collapse

collapse | separate

border-color

color{1,4} | transparent

border-spacing

length length?

border-style

[none | hidden | dotted | dashed | solid | double | groove | ridge | inset | outset]{1,4}

border-top border-right border-bottom border-left

[ border-top-width ||border-top-style || color ]

border-top-color border-right-color border-bottom-color border-left-color

color

border-top-style border-right-style border-bottom-style border-left-style

none | hidden | dotted | dashed | solid | double | groove | ridge | inset | outset

border-top-width border-right-width border-bottom-width border-left-width

thin | medium | thick | length

border-width

[thin | medium | thick | length]{1,4}

bottom

length | percentage | auto

caption-side

top | bottom | left | right

clear

none | left | right | both

clip

[rect( [length | auto]{4} )] | auto

color

color

content

[ string | url( url ) | counter | attr(attribute-name) | open-quote | close-quote | no-open-quote | no-close-quote ]+

counter-increment

[ identifier integer? ]+ | none

counter-reset

[ identifier integer? ]+ | none

cursor

[ [url( url ) ,]* [ auto | crosshair | default | pointer | move | e-resize | ne-resize | nw-resize | n-resize | se-resize | sw-resize | s-resize | w-resize | text | wait | help ] ]

direction

ltr | rtl

display

inline | block | list-item | run-in | compact | marker | table | inline-table | table-row-group | table-header-group | table-footer-group | table-row | table-column-group | table-column | table-cell | table-caption | none

empty-cells

show | hide

float

left | right | none

font

[ [ font-style || font-variant || font-weight ]? font-size [ / line-height ]? font-family ] | caption | icon | menu | message-box | small-caption | status-bar

font-family

[[ family-name | serif | sans-serif | monospace | cursive | fantasy],]+

font-size

xx-small | x-small | small | medium | large | x-large | xx-large | smaller | larger | length | percentage

font-size-adjust

number | none

font-stretch

normal | wider | narrower | ultra-condensed | extra-condensed | condensed | semi-condensed | semi-expanded | expanded | extra-expanded | ultra-expanded

font-style

normal | italic | oblique

font-variant

normal | small-caps

font-weight

normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900

height

length | percentage | auto

left

length | percentage | auto

letter-spacing

normal | length

line-height

normal | number | length | percentage

list-style

[ list-style-type || list-style-position || list-style-image ]

list-style-image

url( url ) | none

list-style-position

inside | outside

list-style-type

disc | circle | square | decimal | decimal-leading-zero | lower-roman | upper-roman | lower-greek | lower-alpha | lower-latin | upper-alpha | upper-latin | hebrew | armenian | georgian | cjk-ideographic | hiragana | katakana | hiragana-iroha | katakana-iroha | none

margin

[length | percentage | auto]{1,4}

margin-topmargin-right margin-bottom margin-left

length | percentage | auto

marker-offset

length | auto

marks

[ crop || cross ] | none

max-height

length | percentage | none

max-width

length | percentage | none

min-height

length | percentage

min-width

length | percentage

orphans

integer

outline

[ outline-color || outline-style || outline-width ]

outline-color

color | invert

outline-style

none | hidden | dotted | dashed | solid | double | groove | ridge | inset | outset

outline-width

thin | medium | thick | length

overflow

visible | hidden | scroll | auto

padding

[length | percentage]{1,4}

padding-top padding-right padding-bottom padding-left

length | percentage

page

identifier | auto

page-break-after

auto | always | avoid | left | right

page-break-before

auto | always | avoid | left | right

page-break-inside

avoid | auto

position

static | relative | absolute | fixed

quotes

[string string]+ | none

right

length | percentage | auto

size

length{1,2} | auto | portrait | landscape

table-layout

auto | fixed

text-align

left | right | center | justify | string

text-decoration

none | [ underline || overline || line-through || blink ]

text-indent

length | percentage

text-shadow

none | [color || length length length? ,]* [color || length length length?]

text-transform

capitalize | uppercase | lowercase | none

top

length | percentage | auto

unicode-bidi

normal | embed | bidi-override

vertical-align

baseline | sub | super | top | text-top | middle | bottom | text-bottom | percentage | length

visibility

visible | hidden | collapse

white-space

normal | pre | nowrap

widows

integer

width

length | percentage | auto

word-spacing

normal | length

z-index

auto | integer

Javacript DOM编程

1.Create Node

var anchor = document.createElement("a"); // Create an <a> node
anchor.setAttribute("name", "TOC"); // Give it a name
toc.appendChild(anchor); // Insert it
anchor.appendChild(document.createTextNode("Table Of Contents"));

2.Search Node

function countTags(n) { // n is a Node
var numtags = 0; // Initialize the tag counter
if (n.nodeType == 1 /*Node.ELEMENT_NODE*/) // Check if n is an Element
numtags++; // Increment the counter if so
var children = n.childNodes; // Now get all children of n
for(var i=0; i < children.length; i++) { // Loop through the children
numtags += countTags(children[i]); // Recurse on each one
}
return numtags; // Return the total number of tags
}

3.Node Type






















Common node types

Interface

nodeType constant

nodeType value

Element

Node.ELEMENT_NODE

1


Text

Node.TEXT_NODE

3


Document

Node.DOCUMENT_NODE

9


Comment

Node.COMMENT_NODE

8


DocumentFragment

Node.DOCUMENT_FRAGMENT_NODE

11


Attr

Node.ATTRIBUTE_NODE

2



4.Modify Node


function reverse(n) { // Reverse the order of the children of Node n
var kids = n.childNodes; // Get the list of children
var numkids = kids.length; // Figure out how many children there are
for(var i = numkids-1; i >= 0; i--) { // Loop backward through the children
var c = n.removeChild(kids[i]); // Remove a child
n.appendChild(c); // Put it back at its new position
}
}



5.Replace Node


function embolden(node) {
var bold = document.createElement("b"); // Create a new <b> element
var parent = node.parentNode; // Get the parent of the node
parent.replaceChild(bold, node); // Replace the node with the <b> tag
bold.appendChild(node); // Make the node a child of the <b> tag
}

Javascript Frame图

figs/js4_1304.gif

Javacript Windows编程

1.Status and defaultStatus

<img src="images/imgmap1.gif" usemap="#map1">
<map name="map1">
<area coords="0,0,50,20" href="info.html"
onmouseover="status='Visit our Information Center'; return true;">
<area coords="0,20,50,40" href="order.html"
onmouseover="status='Place an order'; return true;">
<area coords="0,40,50,60" href="help.html"
onmouseover="status='Get help fast!'; return true;">
</map>

2.Dialog

function warn_on_submit( )
{
alert("\n__Please be patient.");
}
var msg = "\nYou are about to experience the most\n\n" ;
if (confirm(msg))
location.replace("awesome_page.html");
else
location.replace("lame_page.html");
n = prompt("What is your name?", "");
document.write("<hr><h1>Welcome to my home page, " + n + "</h1><hr>");

3.Timeout and Interval

function display_time_in_status_line( )
{
var d = new Date( ); // Get the current time
var h = d.getHours( ); // Extract hours: 0 to 23
var m = d.getMinutes( ); // Extract minutes: 0 to 59
var ampm = (h >= 12)?"PM":"AM"; // Is it a.m. or p.m.?
if (h > 12) h -= 12; // Convert 24-hour format to 12-hour
if (h == 0) h = 12; // Convert 0 o'clock to midnight
if (m < 10) m = "0" + m; // Convert 0 minutes to 00 minutes, etc.
var t = h + ':' + m + ' ' + ampm; // Put it all together
defaultStatus = t; // Display it in the status line
setTimeout("display_time_in_status_line( )", 60000); // 60000 ms is one minute
}

4.Error

self.onerror = function( ) { return true; }

5.Navigator

var browser = new Object( );
browser.version = parseInt(navigator.appVersion);
browser.isNetscape = false;
browser.isMicrosoft = false;
if (navigator.appName.indexOf("Netscape") != -1)
browser.isNetscape = true;
else if (navigator.appName.indexOf("Microsoft") != -1)
browser.isMicrosoft = true;
6.Window Open and Close

var w = window.open("smallwin.html", "smallwin", "width=400,height=350,status=yes,resizable=yes");

window.close( );

7.Location

a representation of the URL of the document currently being displayed in that window.

function getArgs( ) {
var args = new Object( );
var query = location.search.substring(1); // Get query string
var pairs = query.split(","); // Break at comma
for(var i = 0; i < pairs.length; i++) {
var pos = pairs[i].indexOf('='); // Look for "name=value"
if (pos == -1) continue; // If not found, skip
var argname = pairs[i].substring(0,pos); // Extract the name
var value = pairs[i].substring(pos+1); // Extract the value
args[argname] = unescape(value); // Store as a property
// In JavaScript 1.5, use decodeURIComponent( ) instead of escape( )
}
return args; // Return the object
}
var args = getArgs( ); // Get arguments
if (args.x) x = parseInt(args.x); // If arguments are defined...
if (args.y) y = parseInt(args.y); // override default values
if (args.w) w = parseInt(args.w);
if (args.h) h = parseInt(args.h);
if (args.dx) dx = parseInt(args.dx);
if (args.dy) dy = parseInt(args.dy);
if (args.interval) interval = parseInt(args.interval);

8.History

<script>
// The function is invoked by the Back button in our navigation bar
function go_back( )
{
// First, clear the URL entry field in our form
document.navbar.url.value = "";
// Then use the History object of the main frame to go back
parent.frames[0].history.back( );
// Wait a second, and then update the URL entry field in the form
// from the location.href property of the main frame. The wait seems
// to be necessary to allow the location.href property to get in sync.
setTimeout("document.navbar.url.value = parent.frames[0].location.href;",
1000);
}
// This function is invoked by the Forward button in the navigation bar;
// it works just like the previous one
function go_forward( )
{
document.navbar.url.value = "";
parent.frames[0].history.forward( );
setTimeout("document.navbar.url.value = parent.frames[0].location.href;",
1000);
}
// This function is invoked by the Go button in the navigation bar and also
// when the form is submitted (when the user hits the Return key)
function go_to( )
{
// Just set the location property of the main frame to the URL
// the user typed in
parent.frames[0].location = document.navbar.url.value;
}
</script>
<!-- Here's the form, with event handlers that invoke the functions above -->
<form name="navbar" onsubmit="go_to( ); return false;">
<input type="button" value="Back" onclick="go_back( );">
<input type="button" value="Forward" onclick="go_forward( );">
URL:
<input type="text" name="url" size="50">
<input type="button" value="Go" onclick="go_to( );">
</form>