存档

‘技术’ 分类的存档

通过weather.com.cn获取全国天气数据

2010年1月19日 marshall 3 条评论
获得天气数据:
访问http://m.weather.com.cn/data/101020100.html,其中1010200100是城市的id(上海),返回JSON格式的天气数据,示例如下:
{”weatherinfo”:{”city”:”上海”,”city_en”:”shanghai”,”date_y”:”2009年12月24日”,”date”:”十一月初九”,”week”:”星期四”, “fchh”:”08″,”cityid”:”101020100″,”temp1″:”14℃~6℃”,”temp2″:”9℃~3℃”,”temp3″:”6℃~2℃”, “temp4″:”5℃~1℃”,”temp5″:”7℃~4℃”,”tempF1″:”57.2℉~42.8℉”,”tempF2″:”48.2℉~37.4℉”,”tempF3″:”42.8℉~35.6℉”,”tempF4″:”41℉~33.8℉”,”tempF5″:”44.6℉~39.2℉”,”weather1″:”多云转小雨”,”weather2″:”小雨转多云”,”weather3″:”多云转小雨”,”weather4″:”阴转多云”,”weather5″:”多云”,”img1″:”1″,”img2″:”7″,”img3″:”7″,”img4″:”1″,”img5″:”1″,”img6″:”7″,”img7″:”2″,”img8″:”1″,”img9″:”1″,”img10″:”99″,”img_single”:”1″,”img_title1″:”多云”,”img_title2″:”小雨”,”img_title3″:”小雨”,”img_title4″:”多云”,”img_title5″:”多云”,”img_title6″:”小雨”,”img_title7″:”阴”,”img_title8″:”多云”,”img_title9″:”多云”,”img_title10″:”多云”,”img_title_single”:”多云”,”wind1″:”东北风转北风3-4级”,”wind2″:”北风4-5级”,”wind3″:”北风转东北风4-5级”,”wind4″:”东北风4-5级转北风3-4级”,”wind5″:”西南风3-4级”,”fl1″:”3-4级”,”fl2″:”4-5级”,”fl3″:”4-5级”,”fl4″:”4-5级转3-4级”,”fl5″:”3-4级”,”index”:”舒适”,”index_d”:”建议着薄型套装或牛仔衫裤等春秋过渡装。年老体弱者宜着套装、夹克衫等。”,”index48″:”凉”,”index48_d”:”天气凉,建议着厚外套加毛衣等春秋服装。年老体弱者宜着大衣、呢外套加羊毛衫。”,”index_uv”:”最弱”,”index48_uv”:”最弱”,”index_xc”:”不宜”,”index_tr”:”很适宜”,”index_co”:”较舒适”}}
城市id获取方式(一次性工作):
1. 访问http://m.weather.com.cn/data5/city.xml?level=0,(后面level参数可省略)得到一级列表(省、直辖市、自治区),结果用逗号隔开,id和城市名称使用竖线“|”隔开;结果示例如下:

01|北京,02|上海,03|天津,04|重庆,05|黑龙江,06|吉林,07|辽宁,08|内蒙古,09|河北,10|山西,11|陕西,12|山东,13|新疆,14|西藏,15|青海,16|甘肃,17|宁夏…(以下省略)

2. 访问http://m.weather.com.cn/data5/city02.xml?level=1,(后面level参数可省略)得到二级列表。其中02是一级省市的id,结果格式和上一层相同,示例如下(上海和黑龙江):
0201|上海
0501|哈尔滨,0502|齐齐哈尔,0503|牡丹江,0504|佳木斯,0505|绥化,0506|黑河,0507|大兴安岭,0508|伊春,0509|大庆,0510|七台河,0511|鸡西,0512|鹤岗,0513|双鸭山

3. 访问http://m.weather.com.cn/data5/city0201.xml?level=2,(后面level参数可省略)得到三级列表。0201是地级市的id,示例如下(上海):

020101|上海,020102|闵行,020103|宝山,020104|嘉定,020105|南汇,020106|金山,020107|青浦,020108|松江,020109|奉贤,020110|崇明,020111|徐家汇,020112|浦东

4. 访问http://m.weather.com.cn/data5/city020101.xml?level=3,(后面level参数可省略)得到最后一级的id,020101是区域的id,示例如下(上海市区):
020101|101020100
后面的数字就是获得天气数据需要的城市id,以http://m.weather.com.cn/data/{id}.html格式访问即可得出天气结果。
参考:
chrome天气插件:http://code.google.com/p/chinaweather/,使用Javascript编写
分类: 技术 标签: ,

短地址还原api

2009年12月31日 marshall 1 条评论

由于众所周知的原因,一些短地址服务不能访问,如bit.ly。如果在不翻Wall的情况下,有些网站提供这种还原服务,如http://untr.im,因此可以利用这个网站的api实现bit.ly解析。

如果使用Javascript代码访问,可以用下面的代码(untrim函数):
        function untrim(url){
		var current = location.href;
		var base_url = "http://untr.im/api/ajax/api"
		var xmlHttpReq;
		var result;
		xmlHttpReq = new XMLHttpRequest();
		xmlHttpReq.onreadystatechange = function(){
			if(xmlHttpReq.readyState == 4){
				result = xmlHttpReq.responseText;
			}else{
				//alert(xmlHttpReq.readyState);
			}
		};
		xmlHttpReq.open("POST", base_url, false);
		xmlHttpReq.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
		xmlHttpReq.send("url="+url);
		return getUrl(result);
	}

	function getUrl(url){
		if(url.indexOf("<a href=") == url.lastIndexOf("<a href=")){
			return "";
		}
		url = url.substr(url.lastIndexOf("<a href=") + 9);
		url = url.substr(0, url.indexOf('"'));
		return url;
	}
还有这里(似乎需要翻墙)也有所介绍。
另外如果是命令行,可以通过这个方法获得
分类: Web, 技术 标签:

百度在线笔试

2009年11月26日 marshall 没有评论

上上周百度又让我参加了一轮在线笔试。今天忽然在桌面上看到于是就贴出来。

第一部分、算法与程序设计

1.在一棵一般的二叉树中找到指定的元素,如果有重复出现的元素,要求元素为深度最深的任何一个。指定元素找不到时返回EMPTY_NODE,请用C语言实现,相关数据结构与函数声明如下:

struct Node

{

int iValue;

int id;

Node *pLeft;

Node *pRight;

};

const Node EMPTY_NODE = {0, 0, NULL, NULL};

Node findDeepest(Node *pRoot, int iWanted); //pRoot为根节点,wanted为指定元素的iValue

2.一个单词字典库,单词个数约为10万,每个单词长度不超过16,单词都是由小写字母组成,同时给出16个小写字母,请设计一种高效算法来找到用这些给出字母拼出一个字典中最大长度的单词。给出的16个字母每个字母最多使用一次,也可以不使用。存在多解的时候给出任意一个最优答案就行。

例如:给出adeenrstuvxyzuki可以拼出adventures

请详细描述你的算法思路(如需要,可给出代码\伪代码来辅助描述),并分析其时间复杂度。最后请分析下你的算法以及数据结构的优缺点,存在哪些可改进的地方。

第二部分、系统设计题

1.       有200亿条数据,每条数据的大小在1K~1M不等,每条数据有一个唯一的u_int64的id。

请设计一个读取数据系统,能根据id获取数据。要求:

A.        内存有限制,16G

B.        尽可能利用内存资源

C.        尽可能高效的获取数据

D.        可以利用磁盘,磁盘容量不受限制

2.       C2C网站的商品子系统,包括的关系数据有 分类、属性、商品。

一个商品只能属于一个分类,不同的分类有不同的属性(多个),每个属性有多个候选属性值,其中分类、属性、属性值的更新频率较低。

一个商品的属性,是所属分类的属性,属性值是候选属性值中的一个或多个。

例如:

分类:衣服

属性:尺寸、颜色

尺寸的候选属性值:S/M/L/XL/XXL/XXXL

颜色的候选属性值:黑/白/红/黄/蓝

商品:衣服A,尺寸S,颜色黑

另外,商品还有卖家、价格等其它信息

请设计商品子系统的存储结构或数据库结构。要求:

A.        能够正确维护分类、属性、商品之间的关系数据

B.        尽量减少冗余

C.        考虑数据的增、删、改、查操作,效率尽可能高

D.        能够按照卖家查询出其发布的所有商品

==============问题和解答的分割线======================

1111111111111111111111111111111111111111111111111111111111111111111111111111

Node findDeepest(Node *pRoot, int iWanted); //pRoot为根节点,wanted为指定元素的iValue

{

return findDeepestWithDepth(pRoot, iWanted, 1);

}

Node findDeepestWithDepth(Node *pRoot, int iWanted, int depth)

{

static int maxDepth = 1;

static Node deepestNode = EMPTY_NODE;

if(pRoot != null)

{

Node l = findDeepestWithDepth(pRoot->pLeft, iWanted, depth+1);

Node r = findDeepestWithDepth(pRoot->pRight, iWanted, depth+1);

if(isEmpty(l) && isEmpty(r))

{

if(maxDepth < depth)

{

maxDepth = depth;

node = *pRoot;

return *pRoot;

}

else

{

return deepestNode;

}

}

else

{

return deepestNode;

}

}

else

{

return EMPTY_NODE;

}

}

bool isEmpty(Node node)

{

return node.iValue == 0 && node.id == 0 && node.pLeft == NULL && node.pRight == NULL;

}

2222222222222222222222222222222222222222222222222222222222222222222222222

1. 对字典中每一个单词进行遍历,计算出每个单词每个字母的个数和单词的长度

2. 针对每个单词里每个字母(a-z)的个数和单词的长度建立索引,类似数据库的一张表,表一共有28个列(加上一个隐含的rowid),包括单词内容(1列),26个字母每个字母的个数(26列)和单词的长度

3. 搜索时,对给定的字符串进行相同的统计,计算出每个字母的个数。根据统计结果去搜索个数小于给定字符串字母的单词的rowid,最多16次搜索,搜索后对结果进行交集(思想类似: select word from words where a <= 1 and b <= 1 and d <= 2 and …)

4. 对最后的交集根据长度,得出最长的单词的rowid,最终得出单词

时间复杂度: 16次搜索,每次为O(log n),最多15次的交集运算,复杂度为O(logn * logn),最后寻找最大值可以忽略,所以时间复杂度为O(logn*logn)

改进:提高索引效率,如联合索引

33333333333333333333333333333333333333333333333333333333333333333333333333

1. 内存中使用二叉搜索树进行索引,每个节点占用16字节(2个指针+1个id),可放10亿个节点,则底层节点有5亿个。底层节点左右为空,8个字节用来表示记录在磁盘的存储位置

2. 磁盘存储分为5亿块,每个块里有40条记录

3. 块分为块头索引和块内容。块头索引按id顺序排列,包括了该块的id,起始位置和长度。块头大小为40*(8+8+4)=800字节

4. 每次通过id访问数据,首先查找二叉搜索树,经过29次内存比较得到索引块,再载入索引块头,使用二分搜索得到内容的起始位置和长度,最终得到内容。一共35次左右内存访问和2次磁盘访问

44444444444444444444444444444444444444444444444444444444444444444444444444444

商品表 product: id, name, seller, price, category

分类表 category: id, name

属性表 attribute: id, name, category_id, type

属性候选值表 attribute_value: id, attribute_id, value

商品属性表 product_value: product_id, attribute_value_id

分类: 技术, 求职 标签:

OpenJDK6 build小记(Ubuntu 9.10)

2009年11月16日 marshall 没有评论

之前在twitter上喊喊要研究JVM,今天算是迈出了第一步,从源代码编译openjdk。openjdk现在有6和7两个版本下载,现在7还在milestone 6的阶段,也暂时没什么需要尝试的新特性,另外openjdk6的代码大小只有openjdk7的一半(近50M对114M),于是选择了openjdk6来进行构建。另外,jdk6提供官方下载,这样也方便了和官方版本进行对比。

事实上,根据官方的描述,openjdk6的代码是基于jdk7 b20和jdk6的update的,openjdk7的代码是基于jdk7 b10,很奇怪的代码来源。因为sun是在jdk6开发的晚期才宣布java的开源,于是先开源了java7成为openjdk7,然后再发布了jdk6之后才重新整理代码,从jdk7 b20里剔除了java7特性的代码,发布了openjdk6。现在jdk7的概念等同于openjdk7,但jdk6却和openjdk6不是一个东西。

openjdk的主页的左边栏有众多的链接,主要分为Groups和Projects,似乎是有一些工作组从事不同的项目。不少栏目里都有很多有用的资料,有兴趣的可以看看。其中有一个Build的工作组,负责构建工作,里面有关于构建的官方指南

代码的下载可以用Mecurial来下,也可以下打好的bundle,应该大部分人会选择后者,Mecurial毕竟还是小众的版本配置工具,需要python。

代码构建的过程基本是按照官方指南一步步来的。我的构建环境是虚拟机中的Ubuntu 9.10(BS一下自己,硬盘上就有早就装好的Ubuntu 8.10,只是因为懒得离开Windows)。除了Linux平台,openjdk6还支持在Solaris和Windows上的构建。Linux使用gcc(4.2)编译,Windows使用VS2003(也有2005成功的例子,。而openjdk7的构建文档直接要求VS2008)。GNU make是构建工具,所以Windows下还需要cygwin。

构建的依赖在ubuntu下很简单,用下面的语句搞定。在9.10下需要下载很多东西,最大的是llvm的binary和开发包,不知是用来做编译还是虚拟机的。

sudo aptitude build-dep openjdk-6

另外需要安装openjdk6当作bootstrap jdk,还需要libmotif开发包

sudo aptitude install openjdk-6-jdk libmotif-dev

接着,设置一下环境变量

export LANG=C ALT_BOOTDIR=/usr/lib/jvm/java-6-openjdk

然后直接在源代码的目录下运行:

make all

就开始构建openjdk6了。昨天我没好好看文档,自己去设定了motif, binary plugs, freetype的环境。还在错误的目录下运行了make,因为在子目录下make是部分构建,所以一直报错,找不到ALT_JDK_IMPORT_PATH。最后也还是自己折腾好了,但不知道是ubuntu早就下好了依赖,还是自己设置好的。

构建完成后,可以自己运行代码目录下build/linux-i586/bin下的可执行程序,比如java

这个时候版本号成了

./java -version

openjdk version “1.6.0-internal”

OpenJDK Runtime Environment (build 1.6.0-internal-marshall_15_nov_2009_21_53-b00)

OpenJDK Client VM (build 14.0-b16, mixed mode)

对比原有的信息:

java -version

java version “1.6.0_0″

OpenJDK Runtime Environment (IcedTea6 1.6.1) (6b16-1.6.1-3ubuntu1)

OpenJDK Client VM (build 14.0-b16, mixed mode, sharing)

另:在我分配了512M内存的ubuntu上,编译时间大致为1个小时。构建有警告提示内存太少,会影响速度。明天放到非虚拟的ubuntu下跑试试看。
分类: OpenJDK, 技术 标签:

支付宝面试总结(2009.10.12)

2009年10月12日 marshall 3 条评论

10号晚上的宣讲+笔试,笔试笔得一般,程序题做错了,没想到用递归,还有记得做错的是一道网络题,问会话层(Session)是OSI里的第几层,我忘了展示层(Presentation),于是选了第六层光荣的错了。

11号一早通知9点面试,我起床洗漱吃早饭,然后又接到一个电话说是12号早上9点,于是只好上床继续睡觉。

面试前打印了几份简历,进去咖啡馆之后填了表格就开始面了。中间省略过程数百字。。。直接开始总结几个答的不好的问题,因为一面就挂了。

Spring的事务有几种方式?

题目到现在也不是很明白,我觉得大概的解答应该是声明式事务处理的几种方式(1.0时代的parentTemplate、2.0时代的AOP代理和@Transational),另外加上编程式事务处理,直接上TransactionTemplate和PlatformTransactionManager。

Spring Bean加载有几种方式?

我回答了启动时加载,现在看来有点答非所问。加载bean默认为即时加载,另外也可以设置延迟加载。加载可以为单例、每次一个实例、request、session、global-session。

Spring Bean有几个设置属性?

我只想起来scope,应该想起来auto-wire, init-method, destroy-method一时都忘了。另外还有lazy-init,  factory-bean, factory-method。

Collections.sort()对参数的要求?

这个是最不应该答错的题目。我只想起来sort的集合必须实现List接口,却忘了最重要的sort的对象必须实现Comparable接口。

描述一个LRU的HashMap。

这题一开始楞没听明白,老想着HashMap不是链式连接冲突的entry的么,怎么会size不够。磨叽了半天,搞了一个堆出来计数,面试官也不满意。

后来想想其实用个链表把Entry链接起来就可以了,正好在网上搜到了使用LinkedHashMap实现LRU Cache的做法,在这里描述一下内部实现:

  1. 扩展HashMap.Entry,使Entry间使用双链表连起来;
  2. get的时候,把该Entry移到链表的尾部;
  3. put的时候,把Entry放到链表的头部;
  4. 如果规模超标,则把链表头部的Entry抛弃;

项目里使用的设计模式。

我拿了资源安排里,封装两种安排算法到两个实现同一个接口的类的例子,说这是策略模式,面试官有些不认同。后来回头想想,项目里还有其他的模式:

  • Singleton,Facade自不必说;
  • Strategy有一个更好的例子,使用PROBE的A、B、C、D四种方法进行时间和规模的估算。另外还有两个Factory来负责生成相应的计算方法实例。
  • Decorator模式,封装了MultiTenantSessionFactory,持有一个SessionFactory对象,也实现了SessionFactory接口。

大概就想起来这些问题。一开始的自我介绍忘记介绍做过的项目了,这可能是悲剧的来源吧。

分类: 技术, 求职 标签:

使用正则表达式过滤不包含某子字符串的单词

2009年9月30日 marshall 没有评论

昨天在学院版上看到有人发帖问,标题里的内容就是帖子里问题的核心。举个例子来说,就是给一堆单词,匹配所有不包含某字符串的单词。比如要求剔除aa,那么对于单词aab, abc, abca, abaac,就匹配abc, abca。

问题似乎很简单,但我从来没用过逆向匹配。有限状态自动机很容易就可以画出来,但怎么转化成正则表达式倒是忘得一干二净。最后google了半天,发现一个博客给出了正确答案(目前能想到的都验证通过):\b((?!aa)\w)+\b

这个表达式挺不好理解的。(?! pattern)是负向预查(negative look ahead),放在\w前面显然不是和\w进行组合。需要把表达式拆开来看,比如\b(?!aa)\w(?!aa)\w(?!aa)\w\b,这么来看就比较好理解了。首先不可以以aa开头,然后每个单个字符后都不能跟aa,直到结尾。这么就基本把aa给堵死了。

另外,如果支持negative look behind的话(Javascript不支持),应该也可以写作\b(\w(?<!aa))+\b。

分类: 技术 标签:

远程opensusue无法使用home, end

2009年9月23日 marshall 没有评论

用了opensusue当服务器两个月,碰到一个小麻烦的问题就是使用putty SSH登录上后,BASH里无法使用HOME和END进行行首和行尾的定位。原本以为是putty的问题(以前用的都是Secure Shell),今天正好想到这个问题google了一把,发现是opensusue的问题,参见这里

我用的是opensusue10,配置文件都是/etc/inputrc,但行数有些不同,我的是90-91行,把下面的代码注掉就OK了:

#”\e[1~”:       history-search-backward

#”\e[4~”:       set-mark

分类: 技术 标签:

Tomcat启动地址解析错误

2009年9月16日 marshall 没有评论

贴log:

SEVERE: Protocol handler pause failed
java.net.UnknownHostException: NEOSTA: NEOSTA
at java.net.InetAddress.getLocalHost(InetAddress.java:1474)
at org.apache.jk.common.ChannelSocket.unLockSocket(ChannelSocket.java:484)
at org.apache.jk.common.ChannelSocket.pause(ChannelSocket.java:283)
at org.apache.jk.server.JkMain.pause(JkMain.java:681)
at org.apache.jk.server.JkCoyoteHandler.pause(JkCoyoteHandler.java:153)
at org.apache.catalina.connector.Connector.pause(Connector.java:1073)
at org.apache.catalina.core.StandardService.stop(StandardService.java:563)
at org.apache.catalina.core.StandardServer.stop(StandardServer.java:744)
at org.apache.catalina.startup.Catalina.stop(Catalina.java:628)
at org.apache.catalina.startup.Catalina$CatalinaShutdownHook.run(Catalina.java:671)

关键词:UnknownHostException, JK

原因在google的第一个,虽然上面说的是AIX,但也适用于普通Linux:RHEL5原装的GCJ太山寨了,记得在启动tomcat前要指定JAVA_HOME。

分类: 技术 标签: ,

一个人人(校内)应用的想法

2009年9月11日 marshall 1 条评论

一个星期前坐车时想到的。应用的功能很简单,就是帮助求职人群找到笔友、面友。

添加应用的用户可以创建一个活动,比如参加宣讲会、笔试、面试,并对这个活动添加评论(如笔经、面经)。其他人也可以添加评论形成互动。

搜索是一个比较重要的功能,相对于BBS上发帖寻同路人的行为,更有效率。

开发上,可以使用appspot进行部署,但appspot经常会被墙,或者是自己出了问题。自己Host的话要考虑流量和服务器的负载。

营收上可以在上面放adsense,虽然没几个钱。

只是个想法,暂时没什么时间实现,看这个周末有没有空搭一个架子出来。校内的文档很糟糕,支离破碎的。如果有人看到这个想法并打算尝试的话,自便。我也希望看到这个应用的上线。现在校内上关于求职的应用几乎没有。

分类: 技术, 求职 标签: ,

pubsubhubbub简介

2009年9月9日 marshall 4 条评论

Google最近发布了pubsubhubbub协议,看上去挺简单,倒解决了我多年来关于RSS的疑惑。本来我一直以为RSS订阅是有显示的更新提示机制的,在挖掘了一些文档和实现后,发现只是简单的poll,不由得为其效率担心。好在现在有很多在线订阅器,减少了部分流量,不然很难想象一般的小站怎么能撑得住大量用户的轮询。但这么poll下去也不是个办法,效率还是不行。Google发布的pubsubhubbub协议就是为了解决这个问题而提出的,是个20%工作时间的项目。

下面的简介翻译自项目主页。

(pubsubhubbub)是一个简单的、开放的、服务器对服务器的、基于web做hook(订阅)的发布/订阅协议,作为ATOM和RSS的扩展。

支持pubsubhubbub协议的服务器,在一个它们感兴趣的话题(feed URL)更新时,可以得到近乎实时的通知(通过webhook回调)。

协议大体上是这样:

  • 一个feed URL(话题)在它的ATOM或者RSS的XML文件里,通过<link rel=”hub” … >声明它的hub服务器。服务器可能由发布者运营,也可能是一个所有人都能使用的社区hub(支持ATOM和RSS的feed)。(APPSPOT可能被墙,这里推荐另一个实现superfeedr
  • 订阅者(对某个话题感兴趣的服务器)一开始像往常那样取得话题的ATOM。如果在ATOM文件里声明了hub信息,订阅者就可以跳过痛苦的、重复的URL轮询,转而在feed的hub上注册并订阅该话题的更新。
  • 订阅者在声明的hub上订阅话题的URL。
  • 当发布者更新话题的URL时,发布者的应用会告诉hub说有一个更新
  • hub得到更新的内容并把更新内容向该条目的订阅者进行广播。

协议本身是去中心化且自由的。没有任何公司处于控制的核心地位。任何人都可以运营一个hub、ping(发布)更新或者通过hub订阅更新。

作为起步,我们提供了一个hub的一个开源参考实现(协议中最难的部分),运行在GAE上,所有人都可以用(还要看某墙的脸色)。

分类: Web, 技术 标签: , ,