Archive for the ‘ MAW is About Web ’ Category

关于IP和域名的几个命令行技巧

1. 如何获得自己的公网IP,还用ip138?你真的out了。

% curl ifconfig.me

219.239.108.78

2. 如何给某个IP快速绑定一个域名

比如要给192.168.0.1绑定一个域名,这样vhost就可以用了

% dig 192.168.0.1.xip.io

; <<>> DiG 9.6-ESV-R4-P3 <<>> 192.168.0.1.xip.io
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 43766
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;192.168.0.1.xip.io. IN A

;; ANSWER SECTION:
192.168.0.1.xip.io. 599 IN CNAME a0ips.xip.io.
a0ips.xip.io. 599 IN A 192.168.0.1

;; Query time: 808 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Sun Mar 24 12:12:49 2013
;; MSG SIZE rcvd: 72

 

3. 如何反向解析域名

% host 8.8.8.8
8.8.8.8.in-addr.arpa domain name pointer google-public-dns-a.google.com.

 

我们做了一个操蛋的网站

昨天公司内部发了一个邮件让做一个调查。考虑到这个调查系统是我们自己开发
的,而且我还没有使用过,便兴致勃勃地开始一段特别苦恼的旅程。

我不断地问自己问题:一个在线调查系统的目的是什么。在我备受煎熬,不得不
依靠自己强大的内心才完成了这次调查之后。我极其郁闷地将开发同学和产品同
学召集起来,将问题抛给了他们:“请用一句话回答:在一个被调查者眼中怎样才
算是一个好的调查网站呢?”

“需要有其他选项,不想被限定在某几个选项中。”

“易于学习,便于掌握,好操作。”

“引导用户说出自己真实的想法。”

“⋯⋯”

我深深地叹了口气,摇了摇头。我对这些一点儿都不着边际的话并不感到意外,
但我依然抑制不住自己失望。我提示大家:“你们猜我在做调查的时候是一种什么
样心情和想法?”所有人都有点愣住了,似乎从来没考虑过这个问题。

“做这个调查时,我唯一的想法就是:怎么TMD还没做完?!”

很多人笑了,看来这种经历并不是专属于我个人的。还有的人提示我说:“哦,这
个还算简单的呢!”

我继续问道:

“谁会来我们的网站接受调查?他们的目的是什么?我们的产品给他

们带来了怎样的价值?”

所有的人都静下来了。我一点一点的展开:

要知道我们其实做了一个非常操蛋的网站。因为所有来我们这里的用户都非常讨
厌我们的产品,没有,绝对没有任何一个被调查者会喜欢我们网站。因为他们不
是调查公司施以利诱骗来的,就是受人所托,或者是被要求(被逼也说不定)必
须完成调查。没有人是自愿的。他们从我们的产品不能获得一丁点儿价值。他们
想要的是什么?无非是尽早结束,这样调查公司骗来的用户就能获得那些虚无缥
缈的积分,受人所托的就能对别人有个交代,强迫完成的也总算能交差了事。

“一个用户无法获得价值,一分钟也不想多呆的网站肯定是个非常操蛋的网站了吧。
我们唯一能做的就是让其少操蛋一点,配合用户最快速地完成调查。好吧,这就
是用户眼中好得调查网站的标准:最快速地配合用户完成调查。”

所以,交互上要实行最简原则:

一个狗屁单选题绝对不要让用户再确认一次,对于单选题来说“下一题”的这个按
钮也完全没有必要。少一次点击对于程序员来说似乎是一个“死不了人”的问题,
但对于单选效率则会提高100%,这是别的优化望尘莫及的。有反对意见的同学可
以参考google首页,这是一个跳出率极高,粘滞时间超短的页面,难道我们的页
面不应该这样么。

扩大点击范围,整个选项都应该是可以点击的,而不仅仅只是有个选项框可以点
击,极力减少用户在操作过程中的鼠标滑动。邀请选择的暗示要足够强烈。

根本不需要后退(或者“上一题”)按钮,用户一心想往下进行,根本没有心思后退。
如果需要后退的话,那一定是某处逻辑设计失误(比如互斥条件)。如果是这样的
话,一定要立即解决逻辑设计的问题。后退这个按钮掩盖的都是肮脏的浪费。

支持键盘操作。要知道,虽然答题的人不想答题,但经常答题的人群确是非常稳
定的,一旦他发现键盘可用,则会兴奋起来,对于职业答题者非常必要的。

尽量避免让用户录入文字。“其他”就足够了。

尽量将问卷一次加载到前台,由相应的javascript来完成前台逻辑校验
(backbone.js就是不错的技术方案)。
后记

我听说了很多关于调查问卷的奇闻轶事。

有的客户要求做的调查有100多道题目。我不知道制作题目的人是不是仅仅是为了
完成任务。100多道题目太多了。人类的注意力集中时间大概只有20分钟左右,所
以必须在这之前完成所有调查。否则用户会倾向于敷衍,或者欺骗调查系统。

有的客户要求题目的逻辑异常复杂。你做到最后几个题目时不让你继续,除非你
把之前的20道题目都改成他们认为合理的取值范围内。我也是玩过有偿点差的人,
后来放弃了。全因为这些调查不仅是对你智商的侮辱,也是对你耐心和体力的双
重考验。这就是特别典型的逻辑互斥设计缺陷。

有的客户要求当用户对某个题目分数比较异常时给出理由。理个屁啊?会有人看
么??既然然人家选,就不要问人家为什么。所有选项间的继续进行难度应该是
一样的。人为造成的交互难度不一致会使得用户倾向于选择交互容易的选项。所
以客户看到了他们想要看到的结果,问题是那TMD还做什么市场调查啊?

有的客户设计了特别变态的逻辑题目,让用户完成一张我们都认为连阿汤哥都无
法完成的表格。拜托,用户要是都能做完,阿汤哥不就失业了。调查表格的设计
前提就是填写者没有义务填写。一个直接推论就是填写调查表格时,用户不需要
借助辅助思考或者计算h。我真的不知道,调查表的设计者学没学过《市场调查》
之类的课程。有没有老师认真地告诉他们,其实填表的都是大爷。

好了,就权当娱乐了。

MongoDB的备份和恢复

话说怎么备份本身就是一个非常值得深入探讨的问题。能把数据放置到别的地方,而后再拿回来使用,看似很简单,但实际应用中却是非常令人恼火的一件事儿。因为实际运行中,所有的数据都是流动的,以刻舟求剑的方式来作数据的备份和恢复就很不靠谱了。但同时,任何应用于生产环境的数据存储方案首先要考虑的就是备份融灾问题。可能你的机房里不会有大象,但是说不定会有老鼠呢。可能你的操作人员不小心拉错了闸。这些事情貌似都不太可能发生。但是以我的实际经验来看,如果你没有备份的话,倒霉的事儿发生的几率就会成几何级数增长。也就是说备份了就备份了,要是不备份,倒霉的事儿总会发生在你头上。所以还是小心一些。另外说一句,备份是非常不符合精益思想的,起码原生态的简单备份有着明显的浪费,而且若是做不好监控的话,出故障的几率并不低,所以千万不要觉得备份就万事大吉,仅仅是运维的第一步而已。

有两种比较简单的备份方法(直接copy数据库文件,mongodump),不太能单独在生产环境中使用。比较建议的做法是构建Master-Slave,在Slave上做些备份,slavedelay是个非常有用参数,要是不想搞得很麻烦,就可以设置几个不同的slavedelay值的slave,这样就可以应对很多情况了。有人问了,如果有些延时,那么岂不是会丢失一些数据。说对了。首先备份并不能保证完全不丢失数据,任何地球上已知的方法都不能保障这一点。其次,备份数据也要考虑备份的目的。其实并不是所有情况都是要回复到最新的数据的,想一想有人用大量垃圾数据填充你的数据库你怎么办。应对这样的情况就不能简单地恢复到最新的备份了是吧。

在slave上,可以定期地加锁,备份,然后解锁。总之了,要在slave展开热备份的一切操作,甚至为备份建立专门的slave。比如视觉中国的图片存储方案中的备份就是这么做的。

索引,做还是不做,这是个问题

先说个题外话很多人都搞错了mongodb的名字,错误地拼成了mangodb,或者mango。我劝大家不要吃芒果了。从我的网站搜索结果来看拼成mangodb的真的不在少数,这里还要请大家特别注意,尤其是母语不是英语的人。否则要是到英语讨论组提问的话,会引起不必要的误解。
首先要说明的是mongodb的索引和传统的关系型数据库的索引几乎完全一样,所以很多原来的优化手段这里也是适用的,反之也对。那么索引是什么呢?有些人觉得我故弄玄虚,玩数据库的谁人不知索引啊。好吧,那我换一个问法,索引用来干什么?索引是为了在查询的时候更加快速。bingo!这句话是有好多隐含的意思的。查询更加快速,那么是和什么相比呢?肯定是和笨方法相比了。所谓的笨方法就是复杂度为O(n)的线性查找了。这种查找的好处就是不用做任何预处理,而且不需要额外的空间,可以容易地并发。据我所知有两种方法可以降低时间复杂度,一种利用排序的方法,可以将查找有序表的时间复杂度降到O(log(n)),一种使用Hash的方法,用空间换时间,使得时间复杂度讲到O(1)。今天要讨论的主要集中在变无序为有序的做法,也就是大部分索引的机理。
既然涉及到排序,那么就涉及到顺序。所以按照{a:1, b:1}建立的索引,和{b:1, a:1}建立的索引是完全不同的。这种不同的表象是建立索引的速度会用不同,深层次的原因就是排序的准则不同所以顺序就不同,导致的排序复杂程度就不一样。要知道排一几乎有序的数列,和排一个几乎无序的数列可能是完全不同的工作量。还记得所有的算法书上都将到了最好情况和最坏情况吧。所以以一定要考虑你自己的数据究竟是什么样子的,本身有什么性质,建立索引的时候要尽量的符合现有顺序。少折腾,会有很大的获益。至于查询的时候,查询优化器不会计较{a:20, b:30}还是{b:30, a:20}会自动优化的。还要考虑的一个问题就是索引的复用,因为如果建立所以是{a:1,b:1,c:1,d:1},下面这几种都将能复用这个索引{a:10}, {a:10,b:20}, {a:10,b:20,c:90},查询关键字的顺序并不重要,但必须是建立索引的前几个关键字的组合,前一个,前两个,以此类推。
上面讲了第一顺序,还有另外一个顺序。那就是关键字的排序顺序。当然要是你的索引只有一个关键字,就没所谓了。要是有多个关键字,首先要考虑关键字摆放的顺序(上面讲到的),然后就是关键字本身怎么排的问题。是{a:1, b:-1}还是{a:1, b:1}。还是那句话,少折腾就多获益。
不要对不怎么变化的值进行索引。比如性别,有无驾照这种布尔类型的量,对这个索引是没有任何意义的。排不出顺序,也就失去了索引的意义。
有些时候需要返回大量结果,比如返回的结果占到集的一般,这时候,最好就别用索引, 老老实实的用笨方法更快。因为当你要把一本书的前半本都读出来时,索引帮不上什么忙的,反而显得很这腾。所以不见得索引就一定快,要适合自己才是关键。

巧用oplog

by 10gen’s Mathias Stearn
翻译:程显峰

你已经使用了热备(还没有?),也已经知道设置起来非常容易。但可能你还不知道:所有的操作都会存储在一个常规的固定集中,在主控上是local.oplog.$main,在备份上是local.oplog.rs。通过查询这个集,可以深入探究系统的各个方面,甚至可以实现异步触发器。

?View Code JAVASCRIPT
> use local
switched to db local
> db.oplog.$main.find().sort({$natural:-1})
{ "ts" : { "t" : 1288884355000, "i" : 1 }, "op" : "u", "ns" :
"test.foo", "o2" : { "_id" : 1 }, "o" : { "$set" : { "i" : 2 } } }
{ "ts" : { "t" : 1288884349000, "i" : 1 }, "op" : "u", "ns" :
"test.foo", "o2" : { "_id" : 1 }, "o" : { "$set" : { "i" : 1 } } }
{ "ts" : { "t" : 1288884227000, "i" : 1 }, "op" : "i", "ns" :
"test.foo", "o" : { "_id" : 1, "some" : "thing" } }
{ "ts" : { "t" : 1288884225000, "i" : 1 }, "op" : "n", "ns" : "", "o" : { } }

可以看到有两次更新,一次插入,一次空操作(就是最下面的那个)。op可以是下列值:
i – insert
d – delete
u – update
c – command
n – no-op

空操作定期执行确保时效性。如果想过滤掉这些信息,在查询条件加入{op:{$ne:’n’}}就可以了。

很重要的一点就是所有oplog条目都是等幂的。例如上面的两次更新都是由{$inc:{i:1}}调用的,但是最后会转换成$set操作,这样就可以在以后多次重放。

量变到质变——移动互联网的革命

互联网客户端的开发虽然能在短时间内就造就少数个人富豪,但从长远来看还是需要强大财力支持的公司才能在最后的竞争中胜出。

说的简单点,公司这种有组织的模式在任何方面来看都要胜过个人的单打独斗。当然这是从整体上来说的,并不是说个人一定不会成功,而只是说公司更容易掌握资源,更容易获得比较优势。

互联网发展的另一端,则必定是公司的天下了,大量的移动客户端,带来的商机,除了客户端本身,必然还有服务端。很多人都用传统的思维去看待这个问题,觉得只不过是数据量变大了而已。但是我不这么看。昨天我的同学从日本给我打电话来说,他在日本的上网接入贷款是1G,下载一个Matlab,只需要几十秒。我除了听着羡慕嫉妒恨之外,立刻意识到,这个网速的量变已经足够导致质变了。传统上认为下载软件的核心工作是提高速度和稳定性,其中有个极其重要的功能就是断点续传。但是如果在这种告诉网络环境下重新审视这个问题,你会发现断点续传就显得那么微不足道了。而如何应对高速网络与低速磁盘IO才成为一个全新的核心问题。如果把两种速度看作天平两端的砝码,那么当改变足够多的时候,天平就会向另一端倾斜,使得问题的本质发生改变。客户端的数量也在发生着这样的改变,不仅仅是量的问题,由此导致服务端的质变,还需要我们静下心来仔细观察。

10:15 记于鼓楼大街

MongoDB中的数据类型

JavaScript中的数只有一种类型64bit的浮点数。但是mongo中有三种分别是32bit的整数,64bit的整数,64bit的浮点数。

在mongo的shell中修改数字的话,很可能会改变数字的类型,这个大家要特别注意。不过估计很少有人会在shell直接修改数据吧。

还有一个问题是64bit整数保存成64bit浮点数,可能会有误差,这个请童鞋们仔细思考,慎重使用。想看看究竟的同学可以自己构造一个大数存进mongo中(当然一定不是在JavaScript中执行的,要不我不就白说了),然后看看结果。

mongo本身还提供其他有趣的类型,注意这些类型并不是所有编程语言都支持的。比如有些语言没有正则表达式类型,有些没有符号类型,有些语言没有日期类型。mongo还支持大部分语言都没有的最大最小类型。另外,你真的可以把JavaScript代码存在mongo里面,而且有一个对应的code类型。不过这么用的时候要慎重,当年blade爷就破口大骂将代码存在数据库里的愚蠢行为,不知道将来有一天他会不会这么做呢?

JavaScript支持的类型实在有限,所以在这里要警告大家,一定不要轻易在shell中修改数据回存。

MongoDB 东扯西

话说,传统的关系型数据库已经不那么吃香了。近来其他类型的数据库如雨后的春笋一般层出不穷,令人目不暇接,但也肯能非常令人恼火。究其原因,大多是觉得关系型数据库的性能不行,很多情况下也不适合互联网的应用。有针对性的,各路神侠构造了各种兵器,其中很大一类是基于key/value机制的数据库,典型的代表呢,就是Tokyo Cabinetmemcachedb。Tony Bain的一篇文章Is the Relational Database Doomed?对一些数据库发展的现状做了一个客观的评说。另外,还有ibm提出的xml的东西,不知道是个啥,半死不活的样子。很多年以前还有人搞了面向对象的数据库,后来也不怎么着,算是无疾而终(这么说很对不起还活着的兄弟,那能怎么样呢,不过是行尸走肉)。

无疑,数据库战场上的波澜会将每一个互联网开发者卷入其中。一波又一波的“去SQL化”浪潮(详见这里)在改变我们观念的同时,也在改变互联网的构建方式。

Document-Oriented database应运而生,典型代表

CouchDB 有篇不错的英文介绍

不过今天的主角是MongoDB注意啊不是MangoDB,让我们开开心心的开始吧。

Web Scraping in Ruby 直捣黄龙

今天我们来看看怎么获取我们关心的信息,直击要害。

Web给了我们太多不想要的信息,比如说你去新浪看新闻,竟是些不着边际的花边新闻,只不过是些惹眼的词汇罢了,并没有什么真实的内容。我经常有这种感受,为了看网页中的一点点儿东西,要忍受整个网页里面的垃圾信息对我的轰炸,各种广告,弹出对话框,有的还有脚本漏洞真实令人防不胜防,烦不胜烦。

比如我就想知道当下微软的股票价格,我怎么办呢?

http://finance.yahoo.com/q?d=t&s=MSFT

就是一个能提供这种信息的地方,哦那里有股票的价格。

image

我们用一个小工具SelectorGadget,这是个什么东西呢?简单来说,这个工具告诉我们关于某种信息的精确定位坐标。比如说我要找百度大厦,在地图上告诉你“这儿”就是不精确的,但是要是告诉你在“上地九街”就很精确了。这个工具就提供精确制导坐标,你只要点击你想要的区域,它就能自动生成css选择表达式或者xpath表达式,非常高效。有了它,几乎能把90%以上的网页都搞定。

闲言少叙见代码

require 'rubygems'
require 'nokogiri'
require 'open-uri'
 
msft_stock_url = "http://finance.yahoo.com/q?d=t&s=MSFT"
doc = Nokogiri::HTML(open(msft_stock_url))
 
doc.xpath("//*[(@id = \"table1\")]//*[(@id = \"yfs_l10_msft\")]").each do |item|
  puts item.text   
end

Web Scraping in Ruby 漫谈

什么是Web Scraping

http://en.wikipedia.org/wiki/Web_scraping

 

到目前为止,广袤的中文世界里都没有对Web Scraping 的一个定义,所以这里我怎么说怎么有道理,即使是乱放屁,恐怕一时半会儿也不会有人找到头上。

Web Scraping也叫Web Harvesting或者Web data extraction。直译一般不能表达意思的真谛,基本的意思就是Web上有一些我们需要的东东,我们通过一些技术手段把这些东东获取回来。scrap本身是踢出糟粕的意思,很形象,因为web上的绝大部分东西是我们不想要的,是要剔除的。harvest也很形象,我们的目的就是获取有用的数据,就像我们种地是为了获得粮食。extract的抽取,选取的意思表达的就稍微有点学术化了,但其本质还是在说怀有一定目的的从Web获取有用的信息。

那么到这里,我们可以看到,基本的步骤有两个,第一步把信息获取回来(grab),第二步抽取有用的信息(extract)。狭义地讲,Web Scraping就是如何做这两步的技术手段,比如本文题目中的Web Scraping in Ruby,就是说我们用Ruby作为工具的Web Scraping技术。

也有人觉得应该把Web Scraping定义为“超浏览器行为”(beyond browser activity),因为其本质上是一种不用浏览器却模拟了浏览器行为的技术。在传统的unix世界里,若是掌握了grep,sed,awk就牢牢地掌握系统信息的来龙去脉,不过前提是你得知道信息在哪里,毕竟grep,sed,awk的重点在于抽取(extract)。类似的,在广袤无垠的web世界里,尤其是web2.0+的世界里,一种scraping技术就显现出其实用价值了。

是漫无目的地被垃圾淹没还是有条不紊地收集信息?是驱动信息为我服务还是沦为一条信息,悄无声息地幻灭,也许只在一念之间。在传统的单机世界里面,信息的总量是有限的,所以获取信息往往显得不是那么重要。但是Web从某种意义上说是一个无边界的系统,恐怕冒冒失失的想要“慢慢来”,只会进得去出不来。当我们说把整个海洋的水都放到自己船上的时候,我们都觉得好笑,但是很多人却在做这样的事情。

这里要额外说说爬虫(crawler或者spider),爬虫基于简单的原则获取web页面,所以它也是web scraping技术的一部分,但仅仅算作是一个开始。后面的信息处理才是对信息价值的极大提升。后面的部分还会详细说信息的处理的。

总之,web scraping就是从web上获取我们要的信息,但是与我们人类行为有点区别,这里有自动化的,(很可能的)从海量数据中获得的意味,并且一定是剔除了无用垃圾的。

为什么要Web Scraping

因为能赚钱。看多么简单明了,但多么有说服力啊。你若是不往下看,要么你不知道钱的好处,要么是你已经被太多的赚钱谎言欺骗过了。哈哈,我说的是真的,我也是非常认真地说的。

那么我们分为三个类别来说说这项技术如何能赚钱吧。

肯定合法的途径

外汇套利,包括外汇三角套利,期权套利等方式。基本的来说,可以建立一个小程序实时跟踪国际外汇市场的行情,一旦发现套利机会,自动建立头寸(position)。至于细节不便多说,可以查看相关书籍。外汇市场瞬息万变,交易量巨大,广大穷人们还是大有可为空间的。

不一定合法的途径

网页游戏外挂,当然也包括各种网页应用的外挂程序。比如QQ的自动停车,自动偷菜之类的。外挂是能卖钱呢。当然是否涉及到法律风险本身并不是技术要讨论的话题。

比如说发帖机器人,一下子发成百上千的帖子的你真的以为是人啊?

一定不合法的途径

垃圾邮件XXX,如何能获取更多的邮件地址呢,如何能让传统的爬虫更快速,更准确呢。

密码破解器,我知道你知道一大堆工具,John the ripper, hydra等等。但是我肯定你看着各种web手痒痒,你需要新的工具了。

当然了,学术研究啊,商业的其他应用啊,我就不怎么细说了,因为那些不直接来钱。

怎么Web Scraping

哈,这里还是要兜售ruby,其实我不兜售人家销量野蛮高的啊。用文字不太好形容,那么用关键词吧。在初期还是主要讲讲nokogirimechanize的一些应用。可能大家觉得很不屑,觉得这个话题没意思,但是这些技术正是被社区广泛使用,但同时无论英文资料还是中文资料都非常少的。说以我争取做一个好孩子,做一个系统的教程。

至于拿回数据以后,进一步用统计还是人工智能方法来处理挖掘,也会涉及到一些,但毕竟我不是这方面的专家,所以介绍的东西会相对少一些,但会补充相应的资料,供大家提高用。