Blogs

使用 Facebook 登入并取得个人信息

Hank Chen 的头像

facebook,简称 fb,一个社群网络服务网站。许多网站结合了 fb, 来做营销活动,或是快速新增会员人数。如何将自家的网站与 fb 结合,以下做个简单的范例 ,让新加入的会员,可以使用fb的登入,就可以登入自家网站,并取得会员资料。
1.API 选择:
fb官方提供的 API,网页部份有 javascript、php,手机部份则有 iOS、Android,但由于 fb 好吃新奇又好玩 ,所以,其它语言也各自开发相关的api,如 silverlight、flash、.net、java 等,而本次则是选用 javascript 做为范例。
2.事前准备:
2.1.申请 fb 账号。
2.2.申请成为开发者人员,如何申请可参考如下网址
http://sofree.cc/fb-app-1/
3.开工
3.1.完成上述 2,进入新建立的应用程序,依序取得 App ID 与 App Secret ,如下图红框处,并设定相关数据,如下图蓝框处,本次的测试网站为me.cellopoint.com,故 App 网域与网站地址,分别填入 me.cellopoint.com 与http://me.cellopoint.com,设定好之后,按下储存钮

3.2.在 me.cellopoint.com 目录下,新增 channel.html 与 index.html 两个档案,首先开启 channel.html,里头只需加入一段 javascript code
<script src="//connect.facebook.net/en_US/all.js"></script>
3.3.开启 index.html,贴上如下的 code,并做红框处的修改,需注意的是javascript code 必须贴于 <body> 标签内。
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:fb="http://www.facebook.com/2008/fbml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Login</title>
</head>
<body>
<div id="fb-root"></div>
<script src="//connect.facebook.net/en_US/all.js"></script>
<script>
window.fbAsyncInit = function() {
FB.init({
appId : 'xxxxxxxxxxx', // App ID,请输入 3.1 所又得的 App ID
channelURL : '//me.cellopoint.com/channel.html', // 请输入 3.2 所新增的 channel.html 网址

status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
oauth : true, // enable OAuth 2.0
xfbml : true // parse XFBML
});
};
</script>
</body>
</html>
3.4.登入并取得会员资料
新增如下 javascript code,说明如下
a.userID:为个人在 fb 的 id 值,取得如下红框处,如果个人网站利用fb登入,可以此判别会员。
b.如欲取得 email,则需设定如下绿框处
c.取得 name 与 email,使用 FB.api 的 me,如下蓝框处
function FBLogin(){
FB.login(function(response) {
if (response.authResponse) {
alert('登入成功');
alert('UserID' + response.authResponse.userID);
FB.api('/me', function(response) {
alert('UserName' + response.name);
alert('UserEmail' + response.email);
});
} else {
alert('登入失败');
}
}, {scope: 'email'});
}
3.5.注销:新增如下 javascript code
function FBLoginOut(){
FB.logout(function(response) {
alert('Logged out.');
});
}
4.如果要移除掉该应用程序,于个人的 fb 页面的应用程序选项,找到该应用程序并移除掉即可。
5.以上参考出处自如下网址
http://developers.facebook.com/docs/reference/javascript/

Libgtop

David Lee 的头像

如何写一只程序来判断这只程序在执行阶段所占用的 linux 系统资源,例如 CPU 和内存使用率呢? 可以去查看系统中的 /proc/<process id>/stat,或是藉由系统 shell 的 top 指令,但是这两者都必须花费额外的功夫去分析档案或接口中的数据。在这边介绍一个 c 语言的开源函式库: libgtop,可以帮助我们获取系统或特定线程所占用的资源量。

libgtop 是 GNOME 计划中的一个函式库,用来实现 GNOME 桌面环境中的”top”功能。它依赖于另一个GNOME 的函式库 glib。目前最新的版本是 2.28,在安装前必须先安装 glib 2.6.0 以上版本 以及 intltool 0.35.0 以上版本。

一般来说,CPU 的使用率,是根据 CPU 花费在各种不同模式的时间所计算的。这些时间通常可分为 user mode, nice mode, system(kernel) mode 和 idle mode,而使用 libgtop 的 API 可以获取系统 boot 到目前为止,各种 mode 所占用的时间 (clock click 次数)。举例而言,可以利用下面的程序代码来计算出系统 CPU 的使用率:
#include <glibtop>
#include <glibtop/cpu.h>
double cpu_rate;
int dt, du, dn, ds;
glibtop_cpu cpu_begin,cpu_end;
glibtop_get_cpu(&cpu_begin);
sleep(1);
glibtop_get_cpu(&cpu_end);
dt = cpu_end.total - cpu.begin.total;
du = cpu_end.user - cpu.begin.user;
dn = cpu_end.nice - cpu.begin.nice;
ds = cpu_end.sys - cpu.begin.sys;
cpu_rate = 100.0 * (du+dn+ds) / dt

注意 CPU 使用率的计算必须根据两个时间点的 click 次数的差,所以必须截取两次这个信息后再相减。而 memory 的观测就比较单纯,可以一次获得。例如:
#include <glibtop>
#include <glibtop/mem.h>
double mem_rate;
glibtop_mem memory;
glibtop_get_mem(&memory);
mem_rate = 100.0 * memory.used / memory.total;

libgtop 可以观测的资源种类相当多,除了上例中介绍的系统 CPU 和内存以外,还包括特定线程的 CPU 和内存、swap、档案系统、网络接口等等。详细的 API 及数据结构可以参考 GNOME 的官方网站: http://developer.gnome.org/libgtop/

Google File System 介绍

David Lee 的头像

Google 之所以能独霸搜寻引擎市场,一方面是依靠 PageRank 技术所提供的优良搜寻排序,另一方面则仰赖其文件存储系统的优良效率。Google 设计了一套独特的分布式档案系统以满足其庞大的储存需求,也就是所谓的 Google File System (简称 GFS)。Google 并没有将 GFS 当做开源软件释出,不过还是公布了一些技术细节,包含一篇官方论文。

与传统的分布式档案系统相比,GFS 有两个主要的不同点。首先,设备的失效被视为正常的现象而非意外。所谓的失效包括了应用程序的错误、操作系统的错误、人为操作的错误、乃至于硬件或网络的问题。既然连昂贵的硬盘设备也不可能百分之百排除发生错误的可能性,Google 干脆使用多个廉价的磁盘驱动器来组成他们的存储设备。而为了对抗设备的失效,GFS 包含了监视、错误侦测、容错以及自动修复的机制。

其次,数据大多只会被追加到文件的末端,鲜少会修改或删除原本存在的档案。已写入的数据通常只需要可读 (readable) 不需要可写 (writable),而且通常是按照顺序且大规模的读取,一次操作便可能读取数百 KB 甚至 MB 以上的数据。要特别注意到的是,GFS 预期所保存的档案通常都是数百 MB 甚至 GB 以上的文件,小型的文件会被支持但不会被优化。

GFS 处理客户端所下要求的方式是采类似 supernode (Master) 与分布式结点 (Chunkserver) 的架构。真正的数据数据储存在 Chunkserver 上,并且定期将其状态报告给Master。当客户端需要读取某个档案时,要先向Master发出要求,Master 会考虑 Chunkserver 是否为闲置状态,若为闲置则将Chunkserver的位置回报给client,于是client就可以对 Chunkserver 中的档案进行操作。

GFS支持了必需提供超大文件量与超大流量的 Google 搜寻引擎服务,同时建构于 GFS 之上的 BigTable 数据库技术也是 Gmail、Google Maps、Youtube 乃至于其它许多 Google 应用软件或云服务的基础,可以说是云时代的杀手级技术。

碍于篇幅,更多的 GFS 细节可以参考: http://labs.google.com/papers/gfs.html

PHP 函数实作 Semaphore

Ruby Lin 的头像

Semaphore 是一个可变或抽象的数据型态,在并行计算环境中,若有多个行程对一个共享资源,将可提供简单有用的控制存取。

可以把 semaphore 想成是一个记录,有多少单位的特殊资源是可使用的,加上操作安全地(即没有 race conditions)调整那个纪录,且那是有需要等待的直到一个单位的资源变得可使用。

Semaphore是有用的工具来预防竞态条件和死锁; 然而,他们的用途绝不是保证程序可以从这些问题中解脱。资源允许任意数量的 semaphore 叫 counting semaphores;值只有 1 或 0 的 semaphore (或 locked/unlocked、unavailable/available)称 binary semaphores。

下面为 PHP 的 semaphore 函数
int ftok (string $pathname, string $proj) – 将可存取的路径和方案编号转换成 System V 可存取的 IPC key。

bool sem_acquire (resource $sem_identifier) - 向信号机要求,信号机会减少一个资源数,并进入临界区。

resource sem_get (int $key [, int $max_acquire = 1 [, int $perm = 0666 [, int $auto_release = 1 ]]]) - 取得一个新的信号机。

bool sem_release (resource $sem_identifier) - 向信号机通知释放一个资源数,并离开临界区。

bool sem_remove (resource $sem_identifier) - 移除一个信号机。

resource shm_attach (int $key [, int $memsize [, int $perm ]]) - 回传一个可以存取 system V 共享内存的编号。

bool shm_detach (resource $shm_identifier) - 中止对共享内存的链接。

mixed shm_get_var (resource $shm_identifier, int $variable_key) - 取得共享内存中指定的变量值。

bool shm_has_var (resource $shm_identifier, int $variable_key) - 检查共享内存里是否存在该键值。

bool shm_put_var (resource $shm_identifier, int $variable_key, mixed $variable) - 增加或修改共享内存中的变量值。

bool shm_remove_var (resource $shm_identifier, int $variable_key) - 移除指定的变量名称。

bool shm_remove (resource $shm_identifier) – 移除共享内存。

GNU libextractor

Shawn Lin 的头像

Introduction

GNU libextractor是一个种用来从 file 中提取 meta data 的 library。他的设计为以辅助链接库的方式来执行提取文件实际内容,Meta data 格式的数据有下列 (mime type, image dimensions, color depth, recording frequency),GNU libextractor 主要是被我们用来提取 meta data 之用。目前,GNU libextractor 支持以下格式:HTML, PDF, PS, OLE2 (DOC, XLS, PPT), OpenOffice (sxw), StarOffice (sdw), DVI, MAN, FLAC, MP3 (ID3v1 and ID3v2), NSF(E) (NES music), SID (C64 music), OGG, WAV, EXIV2, JPEG, GIF, PNG, TIFF, DEB, RPM, TAR(.GZ), ZIP, ELF, S3M (Scream Tracker 3), XM (eXtended Module), IT (Impulse Tracker), FLV, REAL, RIFF (AVI), MPEG, QT and ASF. 此外,还有各种额外的 MIME 类型检测。

GNU libextractor 是免费软件,可以下载下来修改以及发布。
GNU libextractor 使用 plugin 来处理各种文件格式。从技术上讲一个 plugin 可以支持多种文件格式,但大多数 plugin 只支持一个特定的格式。默认情况下,GNU libextractor 将使用所有在安装目录下发现的可用plugin。应用程序可以要求使用特定 plugin 或只有排除某些 plugin。

Example for using dynamic library

// hello.c
#include <extractor.h>
int main()
{
struct EXTRACTOR_PluginList *el;
el = EXTRACTOR_plugin_load_defaults (EXTRACTOR_OPTION_DEFAULT_POLICY);
// ...
EXTRACTOR_plugin_remove_all (el);
return 0;
}

执行以下指令 compile
$ gcc \ -I/Library/Frameworks/Extractor.framework/Versions/Current/include \
-o hello hello.c \
-L/Library/Frameworks/Extractor.framework/Versions/Current/lib \
-lextractor

Plugin management

C Struct: EXTRACTOR_PluginList
建立一组 plugin

Function: void EXTRACTOR_plugin_remove_all (struct EXTRACTOR_PluginList *plugins)
删除所有给定 plugin 列表

Function: struct EXTRACTOR_PluginList * EXTRACTOR_plugin_remove (struct EXTRACTOR_PluginList *plugins, const char*name)
删除给定 plugin 列表例如 mime 中的 mpeg

Function: struct EXTRACTOR_PluginList * EXTRACTOR_plugin_add (struct EXTRACTOR_PluginList *plugins, const char* name,const char* options, enum EXTRACTOR_Options flags)
增加给定 plugin 列表

Function: struct EXTRACTOR_PluginList * EXTRACTOR_plugin_add_config (struct EXTRACTOR_PluginList *plugins, const char* config, enum EXTRACTOR_Options flags)
根据 config string load 或是 unload 或是修改已存在的列表

Function: struct EXTRACTOR_PluginList * EXTRACTOR_plugin_add_defaults (enum EXTRACTOR_Options flags)
加载所有在 plugin 数据夹下的预设 plugin 列表

Example for a minimal extract method

以下范例告诉我们如何利用 plugin 解读出 MIME type

int
EXTRACTOR_mymime_extract
(const char *data,
size_t data_size,
EXTRACTOR_MetaDataProcessor proc,
void *proc_cls,
const char * options)
{
if (data_size < 4)
return 0;
if (0 != memcmp (data, "\177ELF", 4))
return 0;
if (0 != proc (proc_cls,
"mymime",
EXTRACTOR_METATYPE_MIMETYPE,
EXTRACTOR_METAFORMAT_UTF8,
"text/plain",
"application/x-executable",
1 + strlen("application/x-executable")))
return 1;
/* more calls to 'proc' here as needed */
return 0;
}

Internal utility functions

有些实用的内部开发 API
“convert_numeric.h” 定义了各种数字的转换功能(特别是转换为浮点数)。
“unzip.h” 定义了一个访问压缩文件的 API。
“pack.h” 可以把有 integer 的 struts 分解顺便也可以把 big/little endian 转成 host byte order。
“convert.h” 提供了一个函数进行所需之字符集转换。
Function: char * EXTRACTOR_common_convert_to_utf8 (const char *input, size_t len, const char * charset) 可以用来方便地从任何字符集转换为 UTF - 8 文本。

Conclusion

总之,对于讯息解析平凡的我们来说,GNU libextractor 不只帮助了我们找到档案的正确格式,还可以撰写各种 plugin 工具,分析各种文字格式,找到相对应的 MIME type。这对 email 这块领域而言,可说是不可或缺的一项工具。

What is memcache?

HH Tu 的头像

今天我要介绍一个对于存取数据库相当有用的技术 - Memcache.

Memcache 是一种分布式内存快取系统,对于现在热门的云系统也是相当有用的。 它最基本的概念式用 key-based 的数据结构来存取数据到内存内部。 原先这个概念来自于 Brad Fitzpatrick,他最早用在一家叫做 LiveJournal.com(2003) 的公司,因为效果不错,而又加以发扬光大。 现在有更多的大公司有在用这项服务:LiveJournal、Wikipedia、Flickr、Twitter、Youtube、Digg、WordPress.com…etc. 它的好处在,可以缩减大部分存取数据库的时间转而到存取内存上面,就算数据没有在内存上面对于要到后方存取数据库也是相当的容易设计。 虽然它有 key-based 快取还有分布式内存功能,但是对于存取限制这点必须由建构者自己决定。这项技术效果最好的地方当然就是把常用的数据写到内存内部,那么下次存取的时候就近乎不用等待时间。这概念有点像是当你上网的时候,网站会将网站大部分的图片数据先暂存到你计算机内,等你下次又再存取这个网站的时候,速度会大幅提升是一样道理。Memcache 也是用一样的概念,它拿你计算机的内存来加速存取,它可以拿整个网络的空闲内存来存取,让你可以在同一个网络架构下共同存取使用到, 另外一个特点就是你想要增加多少内存使用就可以增加多少(当然你需要充足的内存),甚至它会将所有内存区块视为同一个内存,这就结合着前面所叙述着,网络上的内存只要你可以用你就可以将全体合并执行。而理论上它的设计这些行为应该都在 O(1) 可以完成。

现在我来给一个简单的范例来叙说有 Memcache 使用上的差异 我们每天从一台计算机存取数据,如果我们想加入就会想要再加一台机器,但是要怎样才会有效率?

图片1,我们有两台机器两个分开的内存,为了确保两台数据相同不会有不一致情形发生,所以我们会让两台内存都存取一样的数据, 结果导致只是计算机 CPU 运作很快,但是内存没有有效率的使用,这种设置效率很差。

图片2,我们有两台机器,但是透过 Memcache 来结合两边的内存,所以我们内存是共存使用的,不用担心不一致的情形, 而且空间还加倍使用,整个生活变得更美好了!!

那我们到底该怎样使用 Memcache 比较好? 以目前较有意义的使用方式是,如果你的存取数据库充满着”SELECT * from XXX”, 表示你常常要所有的数据而且量不少,而且如果又是常常重复的数据,那你就可以使用Memcache使用的相当快乐。 这边给一个简单的分析,你如果要用 Memcache 必须要考虑几个要点:1. 搜寻的时间 2. 击中率 3. 档案存在时间,当然你需要花费额外的人力时间去写程序来增加这段效率,不过比较起结果,这算是常态时间 (Constant time) 的考虑吧?

我再给予一个简单的流程来说明要如何建构你的系统跟 Memcache 还有数据库运作 假设你现在有很多台服务器,现在想要链接这几台服务器有更有效率的应用内存。 以下是一个简单的流程: 你的客户们来询问服务器数据,你的服务器一开始会先去询问 Memcache,如果数据不存在于 Memcache,这时候在去询问 Database,等到找到数据的时候,记得要将数据再写回去 Memcache,这就是一个简单的标准流程。系统刚开始跑 或许会有阵痛期,等只要时间久了,整体速度应该是向上提升才对。

再上面的例子其实你可以看的出来 Memcache在实做上是一个网络的 daemon 大多数人会配合着 PHP或是 C/C++来跟 Memcache 沟通 我使用的 Linux 系统,如果你想要用 C/C++ 来建构,基本上你必须先安装几个程序:1. libevent 2.Memcache 3. libmemcache

想要了解更详细的操作跟内容请参造 Memcache官网: http://memcached.org/

什么是 Node.js?

Paul Chien 的头像

传统上,JavaScript 只在网页浏览器执行,但由于 CommonJS 项目,最近已经有相当多的兴趣也把它拿到服务器端。其它服务器端 JavaScript 环境,包括 Jaxer 和 Narwhal。然而,Node.js 有点不同于这些解决方式,因为它是事件基础 (event-based) 而不是执行序基础(thread based),像 Apache 这种被用来服务 PHP 和其它 CGI 语言的网页服务器是执行序基础,因为它们为每个近来的需求产生一个系统执行序。虽然这对很多应用程序是没问题,但执行序基础在很多诸如为了服务及时应用程序需要长久的 (long-lived) 联机,像 Friendfeed 或Google Wave,并没有很好地扩展。

Node.js 使用事件循环取代执行序,且能够扩充到同时有上百万的联机,它利用服务器花最多的时间在等待读取与写入操作的事实,像从硬盘读取档案、存取额外的网页服务或等待档案上传完成,因为这些作业比内存作业慢很多。每个读取与写入操作在 Node.js 是非同期,意指当读取与写入操作发生时,服务器能够继续处理进来的需求。JavaScript 是非常适合事件基础的程序设计,因为它有匿名函数 (anonymous functions) 和封绝 (closure),且 JavaScript 开发者已经知道如何以这种方式编程,这种事件基础模式让 Node.js 很快,且让扩充及时应用程序很容易。

http://docs.pylonsproject.org/projects/pyramid/1.0/narr/introduction.html

LDAP

David Lee 的头像

试想两个不同的问题:其一,一个上千人的庞大组织,拥有许多不同的部门与IT资源,要如何维护一个便于更新且组织成员们易于查询的在线通讯簿? 其二,一个必须同时维护多个不同系统(可能包含linux登入、apache、samba、mail service等等)的MIS人员,要如何维护多组不同的账号密码,甚至必须定期更新它们? 这两个问题看来毫不相干,可是都可以使用同一个方案来解决:LDAP (Lightweight Directory Access Protocol)。

LDAP是一个参考在线目录服务(Directory Service)的协议,其经由X.500改造而来,省略了X.500许多繁琐的细节,成为了一个能够建构于IP网络上、弹性而方便的网络协议。对前文的问题一而言,LDAP充满弹性的设计让我们能够将组织资源整理成目录型式的数据库;而对于问题二而言,LDAP提供了一个标准化的接口供不同的应用程序参考,因而很容易整合多种不同应用服务的组态配置(configuration)。

以宏观的角度来看,LDAP 将多笔数据以树状结构做存储,称为 DIT (Directory Information Tree)。整个 DIT 可以切割成许多子树,每个子树都可以储存在不同的 LDAP 服务器上,以达到分布式架构的目的。其中,每一笔数据都会有一个独一无二的 Distinguished Name (DN),就像是一般档案系统中的「绝对路径」,用来标记这笔数据在 DIT 中的地址。

以微观的角度来看,LDAP中每一笔数据都符合一种特殊的schema,并且可以转换成 LDIF (LDAP Data Interchange Format) 格式以便阅读 (注意实际上数据的储存方式可能是 binary的)。在 LDIF 格式中,每一笔数据都会拥有多个不同的「属性」,每种属性则会拥有一到多个不同的「值」。一笔数据可能拥有哪些属性,必须根据它所属的对象类别 (objectClass)。例如,类别为「员工」的数据可能会有「姓名」、「所属部门」、「邮件地址」等属性,而类别为「部门」的数据则可能有「主管」、「所属员工」等属性。其中,每一笔数据都一定会有 DN 和 objectClass 这两个属性,至于其它「应有」和「可有」的属性,则由其 objectClass 而定。

要在 LDAP server 上查询数据时,可以把查询 (query) 包装成 LDAP URL 的格式:

ldap://" [ <host> ]"/" <dn> [ "?" <attributes>[ "?" <scope> "?" <filter> ] ]
<host> ::= <hostname>[ ":" <port> ]
<attributes> ::= NULL | <attributelist>
<attributelist> ::= <attributetype>| <attributetype>[ "," <attributelist> ]
<scope> ::= "base" | "one" | "sub"

● host: server的 IP 地址
● dn: 搜寻起点的 dn
● attributes: 希望回传的属性有哪些
● scope: 搜寻的范围(单一节点、第一代的子节点、或是整个子树)
● filter: 搜寻条件

例如: ldap://cellopoint.com/ou=rd,ou=unit,ou=company,dc=cellopoint,dc=com?mail?sub?uid=david
会回传 cellopoint 公司中、rd 部门下、id 为 ”david” 的员工的 email。

目前最常被使用的两个 LDAP 软件为 openldap 和 Microsoft Active Directory。前者是 open source 的软件,对 LDAP 有兴趣者不妨测试看看,也许就会发现一些原本很繁琐的 MIS 工作顿时变得轻松不少喔!

Web Application Frameworks

June Huang 的头像

 由于网络以及网络服务的使用率越来越大,网站在 Web 2.0 时代不再只支持静态内容。网站的内容已成为动态让使用者可以操作实时的工作,例如检查和发送邮件。我们的网络工程因为不断添加新功能让它的规模变的庞大和复杂。

Web Application Frameworks 提供软件结构的模型,帮助我们分类和管理网络应用程序不同的组件。他们还提供一些有用的 libraries,例如:访问数据库,呈现模板和 session 管理。

许多 Web Application Frameworks 使用 Model-View-Controller(MVC)的结构来定义网络应用程序逻辑上的组件。以下是 model,view 和 controller 的解释:

Model
应用程序的 model 是用来处理系统的数据。换句话说,它包括数据和用来处理数据的函数。Controllers 和 views 会透过 model 获取和更改数据。

View
View是呈现给使用者看到的应用程序组件,换句话说,使用者界面。使用者要使用这个接口与应用程序互动。

Controller
Controller 是用来处理使用者的 request 并返回 response 给使用者。它会透过model获得所需要的数据,把数据准备成一个合适的格式,插入到 view 里和呈现 view 给使用者。

一个典型的 request 到服务器的情况如下:使用者透过界面发送一个 request 到服务器。主 controller 会处理这个 request 将它委托给适当的 controller 和把控制传给这个 controller。被委托的 controller 会跟 model 互动来获取或更改数据,呈现 view,并将控制还给主 controller。主 controller 会返回呈现的 view。使用者与接口互动并发送新的请求时,这循环就会重复。

References:
[1] Web application framework. (2011, May 28). In Wikipedia, The Free Encyclopedia. Retrieved 15:23, May 30, 2011, from http://en.wikipedia.org/w/index.php?title=Web_application_framework&oldid=431373642
[2] Model–view–controller. (2011, May 26). In Wikipedia, The Free Encyclopedia. Retrieved 17:12, May 30, 2011, from http://en.wikipedia.org/w/index.php?title=Model%E2%80%93view%E2%80%93controller&oldid=430946706

Protocol Buffers (Google 专用的通讯协议)

Shawn Lin 的头像

 Introduction 简介
Protocol buffers 是一个灵活的,高效的,有自动机制(可能指编解碼)工具用于序列化结构数据。
类似 XML,但是更小、更快、更简单。你定义你的结构化数据,然后就可以使用工具生成的特殊代码方便的使用各种语言 (c++ python java)
从各种数据流中读写你的结构化数据。你甚至可在不打断已经部署的程序的情况下重新更新你的数据结构(热部署)。

Why not just use XML? 为什么不使用XML?
protocol buffer 有很多 XML 不具备的优点:
1.简单;
2.小巧:3-10倍
3.效率高:20-100倍
4.无双重义意
5.有自动工具生成

How do they work? 如何开始运作?
你只需要安装 google 的 protocol buffer
编辑 .proto 檔
执行 protoc –cpp_out=. 檔名


Example: 范例 1
package tutorial;
message Person {
required string name = 1;
required int32 id = 2;
optional string email = 3;

enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}
message PhoneNumber {
required string number = 1;
optional PhoneType type = 2 [default = HOME];
}
repeated PhoneNumber phone = 4;
}
message AddressBook {
repeated Person person = 1;
}

Three type 三种数据型态
required:必须提供字段值,否则对应的 message 就会被认为是“未初始化的。“
optional:字段值指定与否都可以。如果没有指定一个可选的字段值,它就会使用默认值。
repeated:字段会重复 n 次(可以为 0)。重复的值的顺序将被保存在缓冲区中的协议。

Required 是永久性的:在把一个字段标识为 Required 的时候,你应该特别小心。

Start working 开始

  • protoc -I=$SRC_DIR --cpp_out=$DST_DIR $SRC_DIR/addressbook.proto

这会产生以下文件
addressbook.pb.h:声明你生成的 class 的标头檔。
addressbook.pb.cc:你生成的 class 的实作档。

Example: 范例 2
Person person;
person.set_name("John Doe");
person.set_id(1234);
person.set_email("jdoe@example.com");
fstream output("myfile", ios::out | ios::binary);
person.SerializeToOstream(&output);

fstream input("myfile", ios::in | ios::binary);
Person person;
person.ParseFromIstream(&input);
cout << "Name: " << person.name() << endl;
cout << "E-mail: " << person.email() << endl;

Entire message, including: 内部 API
bool IsInitialized() const;:检查是否全部的 required 字段都被设置(set)了值。
string DebugString() const;:返回一个可读的讯息表示形式,对读取特别有用。
void CopyFrom(const Person& from);:用外部讯息的值,覆写调用者讯息内部的值。
void Clear();:将所有项回复到空状态(empty state)。
bool SerializeToString(string* output) const;:将消息序列化并储存在指定的字符串中。注意里面的内容是binary 的;我们只是使用字符串作为一个很方便的容器。
bool ParseFromString(const string& data);:从给定的 string 解析讯息。
bool SerializeToOstream(ostream* output) const;:将讯息写入到给定的 C++ ostream 中。
bool ParseFromIstream(istream* input);:从给定的 C++ istream 解析讯息。

http://code.google.com/intl/zh-TW/apis/protocolbuffers/docs/overview.html
http://www.cppprog.com/2010/0908/207_4.html

CodeIgniter 2.0.2 版本释出

Ruby Lin 的头像

 目前有许多 PHP 框架可以使用,而现今开发者最常使用的包括了:Zend、CakePHP、Symfony、CodeIgniter、Seagull、Yii。这些 PHP 框架在程序开发时带来了许多好处,例如:
1. MVC (模型-视图-控制器) 架构
2. 将 PHP 和 HTML 分开
3. 容易使用的 URL 命名空间
4. 开发速度加快

这些框架都有他们各自的优缺点。当每位程序设计师在建构应用程序时所选择的工具,会依他们各自的风格和优先的考虑不同而不同。CodeIgniter 是用来快速开发 PHP 程序的一套开放原始码应用程序框架,而它因为以下几个特色而闻名:
1. 小巧的框架
2. 出色的性能
3. 好上手
4. 清晰、完整的文件
5. 几乎零配置的框架
6. 无需使用命令行
7. 非大规模集成类

CodeIgniter 会吸引我的注意是因为它好上手、好扩充。而且它有许多可使用的辅助程序、函式库、外挂程序。所有你需要的工具都在一个小程序包里,若你觉得不够,你也可以建立你自己的函式库。CodeIgniter 也有一些安全的工具,对于使用者和开发者来说,安全是很重要的。跨网站指令码 (XSS)是常见的应用层网络攻击之一。CodeIgniter 可以自动过滤所有遇见的 POST 和 COOKIE 值,也可以只针对一些项目来过滤,用来防止跨网站指令码攻击。

CodeIgniter 2.0.2 版本已经释出。这次升级主要是针对安全性的漏洞,跨网站指令码 (XSS) 过滤器也做了一些修正。

http://codeigniter.com/

甚么是机器学习?

HH Tu 的头像

在现实生活中,如果程序设计师想要解决一个文字剖析问题,可能会透过写算法来解决。而常见的做法通常是要有适当的档案输入,写出一系列连续的指令而且有效率的做出加减乘除等动作,达到剖析的目的地之后,再加以输出。但是这并不能达到这世界上解决所有问题的办法。有些东西并没有一定的规律来让我们写固定的算法解决,例如说: 直接写个算法判断一封信是不是垃圾邮件。我们可以看到信,如果今天是透过人眼人脑,可以说出它是不是垃圾信,可是单纯靠个简单的算法,可能就不是件轻易的事情,甚至也不一定存在。

更进一步来说,垃圾信的可能信有很多种,而且会有部分的信息并不一定会在人脑中,如果今天我们可以透过计算机帮我们收集数据,并且自动的截取出适合的信息,透过现有的基础算法来帮我们排序分类…等,更甚至可以加以学习那就太棒了,这重点在于–我们没有直接的算法,但是我们有数据。

从邮件分析这点出发,假设今天我们拥有了成千上万的客户,但是遍布全球,而每天的信件上千万封邮件,如果今天只是单纯的想要知道一封信是否是垃圾邮件,照传统的统计分析,可会花费相当庞大的时间与金钱;更甚者,垃圾发信的花样事会随着时间日益更新,邮件类型也会随着区域的不同而改变,若只是遵照传统的规则走,必定会有失败的一天。从这个角度来看,假设我们知道了这个信其实是从这个垃圾商发送的,或者是这是上面总经理发布命令下来的信件,我们就可以很简单的处理,可以快速的写下程序去过滤它。但事实上这并不是一件简单明了的事情。

仔细来看,其实垃圾信并不是随机的出现,而且也并不是无法跟正常信无法区别!如果今天我们能够收集并且整理够多的数据,从中加以假设跟分析,或许不会全然一样,但是我们期待的是可以找到够好而且够接近期待的预测。因为完全的预测是不可能的(除非你是上帝),但是我们希望的是从数据中自动找到有用的信息,并且分析出一定的结果出来。这样的流程跟思考就是机器学习的价值所在。

在目前的社会上,机器学习的应用相当广泛,网络流量的辨识来达到最佳化、银行的借贷信用评比、股票的预测、医学上的临床参考数据、生物上的神经系统、甚至是太空计划诸如此类,近代有名的则是计算机下西洋棋跟人脑竞赛。可以显示出,机器学习的应用是重要的,但是它到底是怎么学的呢? 从人的思考下手!!

我们是如何辨识电子信件是不是垃圾信? 你能说出个所以然吗? 因为它跟我每天收的正常信不一样,所以它是垃圾信、因为它带有奇怪的内容、因为寄来的人没看过、这些通通没有一个准则。再举一个例子:人脸辨识,你能说出为甚么你认得你的爸爸你的妈妈的脸吗? 因为他们从出生你就看到了、因为他们不是不熟的人所以认的出、他们每天都看到所以不觉得奇怪所以好认、但是一样没有准则。从上面两个例子看到相近的地方,其实我们脑中还是有所谓的特征的,人的轮廓,信的第一眼印象,人脸对称的,信会有文字,人有眼睛、鼻子、嘴巴,信会有收信寄信附加档案等属性…等等,其实这些就是平常我们判断的依据,但是因为可能性太多,人无法直接写一条规则去解决这个问题,所以机器学习就此诞生,透过计算机自动的收集数据,加以分析找出有用的特征(也就是上述的属性),并且配合着我们想要的目的,例如分析人脸或者是找出垃圾信。

现代的机器学习,充斥着大量的统计微积分等的理论在背后支持,因为我们要找到相关性跟最佳化来达到目的,所以会利用到这两个因子。机器学习过程则分成两大部分,第一点就是学习,透过大量的数据数据,来产生出有用的模型并且可以当为代表;第二点则是预测,将之前学习好的模型来输入未来想要预估的数据,并且产出有用的信息,对于现实上来说,甚至会持续的学习新的数据。 不过说起来简单,实际上却是考虑了相当多的事情在里面。

Pyramid 介绍

Paul Chien 的头像

Pyramid 是一个通用,开放原码的 Python Web 应用程序开发架构,它致力于使开发 Web 应用程序更容易。应用程序能够以空白表格程序、公司内网或社群网络平台型式建立。 Pyramid 的普遍性赋予它被用来建置一个不受约束的各种 Web 应用程序。
第一个被释出的 Pyramid 前身(称为 repoze.bfg)是在 2008 七月,我们努力使 Pyramid 延续于遵循我们认为是成功的架构的核心架构的设计和工程原理:

简单
Pyramid 采用“只付你所吃的费用”方法,意指即使你对 Pyramid 只有部分了解,你也能得结果。它没有强迫你使用任何特定技术来产生应用程序,且我们尝试持续我们需要了解最少的核心观念。

极简
Pyramid 集中于对于建立 Web 应用程序根本问题提供快速、高质量的解决:网址对程序、样板、安全性和静态资产的映像,我们认为这些是几乎是一般 Web 应用程序的核心行为。

文件
Pyramid 的极简意指对我们而言它是相对容易于维护大规模实时的文件,任何方面的 Pyramid 留下无正式文件是我们的目标。

速度
Pyramid 是被设计成提供显著地快速执行一般的任务,例如样板和简单的响应生成,虽然“硬件便宜”的真言似乎对速度问题提供一个快速的解决,当某人发现她自己需负责管理很多机器时,这方法的限制变的强烈明显。

可靠度
Pyramid 被谨慎地开发跟彻底地测试,Pyramid 原始码被关注的地方、我们的座右铭:“如果没经过测试,它是一文不值的”。每版Pyramid的释出有通过涵盖单元测试的 100% 声明。

开放
正如 Python,Pyramid 软件是分布在一个许可的开放原码认证之下。

http://docs.pylonsproject.org/projects/pyramid/1.0/narr/introduction.html

网络蜘蛛 - 搜索策略

June Huang 的头像

延续上次关于网络蜘蛛的文章,现在我将更详细的解释网络蜘蛛如何运用策略来探索网络。网络蜘蛛使用互相结合的策略,这些策略包括选择策略,重新访问策略,礼貌策略和并行策略。我将针对这些策略逐一介绍。

由于网络相当庞大,网络蜘蛛只能够下载网络里面部分的网站。网络蜘蛛必须使用选择策略,以确定哪些资源值得下载。这个做法比下载随机的网页更有意义。选择策略的一个例子是 Google 的 PageRank 策略,它将一个网页的重要性以它往返连接的网页的重要性来计算。其它选择策略的例子是根据网页的内容和资源的MIME类型。

网络蜘蛛的重新访问策略则是判断重新搜寻一个旧资源的价值,目标是尽量减少那些旧资源的存在。这一点很重要,因为资源在网络不断被新增,更新或删除,而且是在网络蜘蛛搜索网络完成的时间内变动。搜索引擎老是返回过期的资源是不理想的。重新访问的价值是基于新鲜度和年龄,其中新鲜度的重点是本地的资源是否是最新的版本,而年龄是指这个资源在多久前被更新。

礼貌策略是为了让网站不受到网络蜘蛛的搜索而严重影响运作。因为服务器要处理使用者的需求及网络蜘蛛的下载,可能导至服务器超载。用来减轻负荷的解决方案包括:间隔限制网络蜘蛛从服务器下载资源和由网站管理员限制不能被网络蜘蛛探索的部分。

并行策略是用来协调多个网络蜘蛛在相同的网络空间内同时搜索资源。这个策略的目标是提高网络资源的下载速度以及避免多个网络蜘蛛在同一个时间下载相同的资源。

[1] Web crawler. (2011, February 22). In Wikipedia, The Free Encyclopedia. Retrieved 16:24, March 4, 2011, from http://en.wikipedia.org/w/index.php?title=Web_crawler&oldid=415343979

设计样式在 JavaScript

Paul Chien 的头像

事实上,JavaScript 很传神的允许你很有创造性的将设计样式应用到你的程序,有三个为什么你要使用设计样式在 JavaScript 的主要理由:

  1. 可维护性:设计样式有助于你的模组维持较少的关联,这使重构你的程序和交换不同模组更容易,它也使在大型团队和与其他城市设计师合作更容易。
  2. 沟通:对于处理不同形式的物件,设计样式提供一般的字汇,他们给程序设计师描述他们系统如何运作的简略表达方式,取代冗长的解释,他们只要说“它使用工厂样式”,事实上,一个特定的样式有一个特定的名称意味着你能够在一个高层次讨论它,不须陷入细节。
  3. 效率:这本书所涵盖的一些样式是最佳化的样式,它们能够彻底地改善你的程序的执行速度和减少需要传给客户的程式数量,蝇量级和代理样式是最重要的范例。

有两个你可能不使用设计样式的理由:

  1. 复杂:可维护性常常付出了代价,而那代价是你的程序可能更复杂因此较不能被初学者了解。
  2. 效率:当一些样式改善效率,它们大部分对你的程序增加了些微的效率代价,依据你的专案特定的需求,这代价可能从不明显到不能接受。

实作样式是容易的部分;知道使用哪一个、何时被使用是困难的部分。不知特别的理由而将设计样是应用的你的程序是危险的,努力确保你所选的样式是最适当的,且不要降低效率至可接受的限制底下。

[1] Ross Harmes and Dustin Diaz (2008). Pro JavaScript Design Patterns

平行的程序语言 Erlang !

Shawn Lin 的头像

大多数的电信公司,如:北电网络、T-Mobile,都会用 Erlang 开发分散式系统,以达到共时(Concurrent)与容错(Fault-Torrent)的能力。除了共时与容错,现在多核心与 HT(超执行绪)的处理器环境,也提供 Erlang 语言相当好的发挥环境。

Erlang 解决了现今开发者面对的最迫切问题之一:如何写出可靠、共时(concurrent)、高效能的系统。 Erlang 已经在世界各地被许多公司广泛地采用,这些公司用它来产生可靠、有效率、具规模弹性的应用。

莫尔定律观察到,每隔两年,在单一晶片上能做的事会加倍。但是莫尔定律绕道而行,不是产生越来越快的处理器,Intel 与 AMD 等公司的作法是产生多核心的装置:单一晶片内包含两个、四个、甚至更多个处理器。如果你的程序没有共时(concurrent),则一次只会在单一个处理器上执行,使用者会认为你的程序很慢。

Erlang 是一个编程语言,它的设计目的,正是为了帮助我们建立极度平行、分散、容错(fault-tolerant)的系统。它已经被商业采用运行多年,建立出许多容错系统。多年来,这些 Erlang 所建立的系统出错率极低。

Erlang 程序在多核心的电脑上执行时,会充分运用系统:这意味着你的 Erlang 程序在四核心的电脑上会比单核心的电脑上快,而最棒的是,你完全不需要更动程序,就有如此显著的效果。

用 Erlang 开发系统的好处有:

  • 写出来的程序,移到多核心的环境中执行,速度会自然变快(甚至有可能达到线性加速,n 个核心就提升 n 倍)。
  • 可以写出容错的系统,电脑当机之后会重新启动。
  • 可以写出「程序码热抽换」的系统,可以一边执行一边升级,不用先暂停服务。
  • 写出来的程序不可思议地精简。

Erlang 提供了 Mnesia 的 Erlang 数据库管理系统(Database Management System ,DBMS)。 Mnesia 是整合式的 DBMS,存取速度相当快。它可以被设定成跨越数个实体分离的节点进行资料复制,以提供容错的操作。

除了 Mnesia 之外,用 Erlang 开发系统,也几乎都会用到 OTP 程序库。 OTP 是一组 Erlang 程序库与开放源码程序,用来帮助 Erlang 程序建立工业等级的应用。 OTP 是 Erlang 威力的来源之一,利用OTP可以相当容易地写出牢靠的服务器。


http://www.erlang.org/doc/

网络蜘蛛

June Huang 的头像

索引擎的发明,搜索资料不再是很费力的事情。搜索引擎很方便,因为它可以在很短的时间内从无数个来源产生结果。从网页到图像和视频,我们能够搜索到几乎所有能在网络上找到的资源。为了能返回结果,搜索引擎首先利用一个称为网络蜘蛛的电脑程序去探讨在网络上的资源。网络蜘蛛依照网页的内容然后存储有关页面的资料,这样当我们搜索东西时,搜索引擎可以找到相关的资源并返回给我们。在这篇文章中我将介绍网络蜘蛛是如何找到我们感兴趣的资料。

首先,网络蜘蛛会有一个它要爬的网址列表。网络蜘蛛会参观一个网页,并找出关键词和连结然后确定哪些信息是件值得添加或更新的。为了以后的搜索,网络蜘蛛会将一部分的网站下载和索引一些跟网站相关的数据,如网址。新发现的连结,会被加到网址的列表让网络蜘蛛继续搜索。

因为有无限多的网页及更多的网页在网络上可以不断的被增加、修改或删除,网络蜘蛛需要去选择哪些页面值得参观以获取信息。因为参观每一个网页和为了检查更新而参观多次网页是很不实际的所以网络蜘蛛会用不同的策略来判断网页是否值得参观。举一个 Google PageRank 策略的例子,一个网页的PageRank 是以这网页被其他网页连结到的次数与那些网页的 PageRank 来判断这个网页的重要性。连到他的网页多代表重要性高,所以算出来的 PageRank 也会高,代表值得参观。分布式网络爬行也可以用来优化网络探索与下载。

参考文:
[1] Web crawler. (2010, December 22). In Wikipedia, The Free Encyclopedia. Retrieved 11:21, December 29, 2010, from http://en.wikipedia.org/w/index.php?title=Web_crawler&oldid=403711331
[2] PageRank. (2011, January 2). In Wikipedia, The Free Encyclopedia. Retrieved 11:15, January 6, 2011, from http://en.wikipedia.org/w/index.php?title=PageRank&oldid=405547279

Drupal Introduction

Ricky Wu 的头像

Drupal 是一套由 PHP 所撰写之优秀的网站内容管理系统。简单化的安装方式能够快速的建立基础的网站环境,以多样化的模板套用模式,简易的将网站转换为客制化的风格。

Drupal 具有以下各项优点 :

  • 简易的安装及使用方式– 使用者手册提供了清楚的安装及使用步骤宫使用者参考
  • 具有多项特色,包含 Search Engine Friendly URLs(SEF), categories, search function 等
  • 可扩充性–透过各项延伸模组来强化网站的功能性
  • 可塑性– 不只能够透过 Drupal 建立网站,更能简易的转换为论坛、部落格、wiki 等各种形式的网站
  • 免费使用–开放式原始码,让您能够免费使用Drupal 架构网站,您更能自行修改内部原始码让网站功能更符合您的需求
  • 庞大的使用者及使用群组– 来自世界各地的使用者,能够协助您更快的为您的问题寻求正确的解答

多样化的延伸模组,提供了 Drupal 强大的扩充能力,以简单的步骤将需求模组放置入对应的资料夹结构下,透过网站管理者模式去开启模组的功能并对模组依照客户的需求做设定,便能建立起知识库管理、网站发布以及社群交流等具有不同功能的网站。

  • Content management – 使用者能够透过简单的 browser-based 介面去发布个人的文章、部落格、照片、影像等。管理者也能够简单的管理网站风格
  • Drupal 特有的分类管理系统,能够让您以阶层式的架构、交互式的内容指标去管理多种分类的内容类型。更可透过管理者定义的角色分类来管控网站内容的存取权限
  • Weblog – Drupal 能够将单一网站透过设定,提供单一或多使用者所使用的 Weblog。 Blogger API,提供个别使用者RSS 新闻发布功能,使用者发布的个人文章可存在使用者特定的个别资料夹下
  • Discussion-based community – Drupal 能够成功的用来做为论坛网站的架设平台。每个网页内容都有独立的回应版块,内建的分享功能,更能将每个网页内容分享至您常用的社群平台上做分享讨论
  • Collaboration – Drupal 提供的专案管理,适用于各式开放原始码的专案开发。他的wiki-like collaborative book 模组包含了版本控制,让开发小组简单的创建、更新管理专案文件

Drupal 是一种被应用于架设复杂网站的工具,它功能强大且较适用于高阶开发人员,它需要足够的专业知识与经验去使用管理 Drupal。是一种较不适合于初阶使用者的网站内容管理系统。

参考文件:

Drupal - Official website

SimpleDB

Griffith Chen 的头像

Amazon SimpleDB 是以 Amazon 的 Dynamo 为基础的另外一个服务,把公司最缺的一块,也就是数据库,补起来了。 SimpleDB 仍处于公众测试阶段;当前,用户能在线注册其免费版– 也是说直到超出使用限制为止。 SimpleDB 有几方面的限制:
一次查询最多只能执行5秒钟。
除了字符串类型,别无其它数据类型。
一切都以字符串形式被存储、获取和比较。
字符串长度不能超过1024 字节,限制了使用者在一个属性中能存储的文本的大小。
一个项目最多可以有 256个属性。
由于处在测试阶段,SimpleDB 的域不能大于10GB,整个库容量则不能超过1TB。

SimpleDB 不是 RDBMS (relational database management system,中文称呼为「关联式数据库管理系统」),它的运作模式反而更简单。 Amazon SimpleDB 储存的格式就是Domain → PKeys, Pkey → Attributes,然后每个 Attribute 可有许多 Key → Value,像:

Key: 1
Attributes:
Category: Company
Name: Cellopoint
Website: http://www.cellopoint.com

SimpleDB 有简易的 Select 语法可以使用。

安装 PHP Library for Amazon SimpleDB:
1. 在 Amazon Web Services (AWS) 官方网站下载 PHP Library for Amazon SimpleDB。
2. 将下载完的档案解压缩。
3. 从AWS 申请以及取得Access Key ID 与Secret Access Key。

Client 连线测试:
1. cd 到 PHP Library 资料夹
2. vim test_client.php
<?php
$AWS_ACCESS_KEY_ID = …
$AWS_SECRET_ACCESS_KEY = …

require_once('Amazon/SimpleDB/Mock.php');
$service = new Amazon_SimpleDB_Mock();

require_once('Amazon/SimpleDB/Client.php');
$service = new Amazon_SimpleDB_Client($AWS_ACCESS_KEY_ID, $AWS_SECRET_ACCESS_KEY);
?>
3. 执行 test_client.php

新增资料:
1. PHP 程序
$domain= “MyDomain”;
$item = “Product01”;

$attr1 = new Amazon_SimpleDB_Model_ReplaceableAttribute();
$attr1->withName('Category')->withValue('Device');

$attr2 = new Amazon_SimpleDB_Model_ReplaceableAttribute();
$attr2->withName('Name')->withValue('D01');

$attrArr = array($attr1, $attr2);

$request = new Amazon_SimpleDB_Model_PutAttributesRequest();
$request->withDomainName($domain)->withItemName($item)->setAttribute($attrArr);

invokePutAttributes($service, $request);
2. Service 回应
Service Response
==============================
PutAttributesResponse
ResponseMetadata
RequestId
...
BoxUsage

取得资料:
1. PHP 程序
$request = new Amazon_SimpleDB_Model_QueryRequest();
$request->setDomainName('MyDomain');
$request->setQueryExpression(“['Category' = 'Device']”);

invokeQuery($service, $request);
2. Service 回应
GetAttributesResponse
GetAttributesResult
Attribute
Name
Category
Value
Device

ResponseMetadata
RequestId

BoxUsage
..

前所未闻的 Graphical Scripting Language

Shawn Lin 的头像

Sikuli 是什么?

Sikuli 是一个视觉化程式设计技术,能使用图像(截图)自动化和图形化用户界面(GUI)。 Sikuli 提供一个视觉化脚本的 API 还有 Python 和 Sikuli 的 IDE,并借此产生能轻松编写虚拟剧本与画面的开发环境。通过编程控制,Sikuli 脚本能在没有内部 API 支持的情况下,任意操弄任何你在屏幕上看到的东西,或一个运行在 Windows / Linux / Mac OS X 的桌面应用程序,甚至是在 iPhone 应用程序上运行你想要的操作。

Sikuli,这一个念起来很像日文的名称,其实是一种创新的程序语言,由一位就读于 MIT(麻省理工学院)的台湾学生与它的朋友们费时三年多的研究所产生出来的产品。

它是一种全新的概念,利用图像的辨识,达到众多繁杂指令自动化的效果。

正如作者vgod 所说:「Sikuli最重要的革命是程序码的可读性和易用性。把屏幕截图直接放在程序码里面,让人能直接「看到」他想控制的东西,这是从来没人想过的事情。以往的方法,都是透过只有程序设计师才能写、才能读懂的神秘外星语言。

如果从自动化工具的观点来看,「SIKULI」能够做到的事情并没有那么独特,但它的独特之处就是它用的方法。我们知道程序语言已经是一种相当成熟的技术工具,从物件导向语言问世至今,所有程序设计师也都习惯了「程序语言就是这么难用」,或是已经将自己催眠了说出诸如「.NET 越来越好用了耶!」、「哇!DELPHI 又新增了超好用的 Windows API 元件」这一类的对话。

在「SIKULI」出现以前,从来没有人想过要彻底颠覆掉过去的观念,想出一个全新有创意的程序语言撰写方式。了不起的就是,「SIKULI」真的做到了「创新」这一点,用撷图取代了物件,你不需要知道 Windows 的 API 函式库,也能控制视窗中的元件。虽然它的概念还没发展到真的可以撰写独立的应用程序,目前能做的也仅仅只能当个桌面自动化工具,但它的确指出了一条路,告诉全球的程序设计师,「程序设计可以这样走」。

首先当然你必须先下载「SIKULI」,并且要在电脑安装 Java Runtime Environment (JRE) 环境。之后,就可以依照下列的方法,轻松自订你要进行的操作啰!

http://www.youtube.com/watch?v=FxDOlhysFcM

进入 Ext JS: 最好的 JavaScript Libraries

Paul Chien 的头像

在遥远的银河中,(更精确地,地球2006年早期),一位名为 Jack Slocum 的男士开发了一组 YUI library 的延伸工具,这些工具在 YUI 社群内部快速地流行起来,且很快地组成一个独立的 library,称作:YUI-Ext。在2006年秋天,根据柏克莱软件发布(BSD)条款的许可证,Jack 释出这新的 library 的.33版。

一会后,事实上是2006年结束前,library 的名称被改为 Ext,因为那时它开始独立于 YUI 发展。事实上,支持其他 library 在 Ext 内部开始被开发。

2007年,Jack 为推动 Ext 的发展成立公司,在某个阶段之后开始被叫做Ext JS,2007年4月1日,Ext JS 1.0 版被释出。

在短时间内, Ext JS 从便利的扩充组件发展成今日受欢迎的 library、最成熟的 JavaScript 使用者介面开发 library。

Ext JS 专注于允许你在网页应用程序建立大的使用者介面,事实上,它最为人知的是它一流的专用界面工具集,它允许你建立外观跟感觉跟桌面应用程序极为相似的网页应用程序,且它也给予你最多这些应用程序提供的功能。

虽然如同我们会看到的,这并不全是专用界面工具集,Ext JS 也有很多有用的实用型方程序,需要一些Ajax 的功能吗?它有,需要一些字串运用的功能吗?它也有这些,需要一层数据抽象层吗? Ext JS有涵盖。

[1] Frank W. Zammetti (2009). Practical Ext JS Projects with Gears

您的个人云端搜寻引擎

June Huang 的头像

拜网络搜寻引擎之赐,要获得网络上无数的信息已非不可能。如今,云端技术更改变了人与网络间的互动,例如社交网络及资料储存。而随之而来相关的问题便是如何监控个人云端上信息的成长、事件的发生、和存储的位置。想想在一天之中您在网络上所产生的所有信息:电子邮件、行事历上的事件、通讯软件上的对话等,要记住所有发生的事件几乎是不可能的。那么要如何才能在日常产生的云端资料中有效率的找到找到我们所需要的信息呢?答案就是:您的个人云端搜寻引擎。

Greplin 和 Introspectr 正是两个属于这类的服务,让用户可以过滤筛选他们的个人资料。这样的服务可以将您的社交网络服务如 Facebook、Twitter;电子邮件服务如 Gmail (包括附件和网络链接);甚至文件分享服务如 Dropbox、Google Docs 都编入其搜寻器的索引。使用其服务,只需要输入您的查询,其便会传回所有相关的信息,无论这些信息是储存在那个网络服务之下。

Greplin 和 Introspectr 最主要的区别在于,Greplin 大约每隔 20 分钟便自动更新其索引;而 Introspectr 则必须靠使用者手动更新索引。而另一个已知的差别是 Greplin 无法将 Twitter 讯息内的网址链接列入其索引[2],但 Introspectr 可以。 Greplin 和 Introspectr 都允许使用者将多种不同的网络服务纳入其索引。但是,对于想要列入索引的服务,使用者必须提供他们登入的信息。很明显的,安全性和隐私权成为令人关注的问题。而 Greplin 宣称他们透过 OAuth 协定,只存取所需要搜寻的资料,并没有使用者登入讯息的存取权[3]。

Greplin 和 Introspectr 为用户在过滤使用他们个人的云端信息内容上提供了一个方便且集中的方案。只要有网络,使用者可以在各种电脑装置平台上搜寻他们个人的信息串,就如同收发电子邮件或是搜寻电脑硬盘内的内容一样轻松简单。

[1] Arrington, M (Aug 31, 2010). The Other Half Of Search: Greplin Is A Personal Search Engine For Your Online Life. Retrieved on October 26, 2010, from http://techcrunch.com/2010 /08/31/greplin-ycombinator-personal-search/
[2] Schonfeld, E. (Oct 12, 2010). Introspectr Searches Your Social Streams. Retrieved on October 26, 2010, from http://techcrunch.com/2010/10/12/introspectr-search-social/
[3] Greplin: https://www.greplin.com/
[4] Introspectr: https://www.introspectr.com/

Google Omaha

Griffith Chen 的头像

Google 产品不需要使用者的操作来更新到最新的版本。这功能被称呼为[自动更新]。

大部分的 Google 产品原来就有自动更新的功能,但是都分别使用了自己的方法去达到这目标。有些产品自己写自己的自动更新机制,也同时有些产品使用了 Google 本身提供的自动更新机制以及服务器。

Google 希望在它们的产品上减少重复代码[code duplication],也不希望让多台服务器去担任几乎同一样的功能。针对这些需求,Google 把它们产品全部归在同一个自动更新机制下。这决定也是为了符合微软 Windows 操作系统的进化。微软的 Windows Vista 有一个相当严格的安全机制,不让大部分安装在电脑里的程序去执行系统变更,包括:改 Windows 作业系同的注册表[Windows Registry]、写到 Program Files 资料夹、或是在系统上做任何的永久性变更。这些条件都是传统自动更新机制所需要执行的动作,因此在 Windows Vista 里会无法顺利执行。

除了这个以外,Google 产品还有面对另外一个问题:它们的客制化自动更新机制不统一。这造成了每一套产品都有不同的功能,也同时有了不同的行为。统一的机制能保证每一个 Google 产品都有一个完整的自动更新功能。

随着 Google 产品的发展,它们的安装过程以及使用者经验[User Experience]的改善也变了越来越重要。以传统的安装模式而言,当使用者想安装一个程序时通常会遇到很多技术性的用词还有很多复杂的指定和选项。这会误导使用者,并且让他们不想要继续安装。

为了达到与克服以上所探讨的问题,Google 开发了一套共用的机制来应付 Google Windows 产品的安装和更新。这机制将跟一台自动更新的服务器沟通。 Google 把这机制称为 Google Update,也把这计划叫成 Omaha。

Server and Desktop Virtualization

Ricky Wu 的头像

虚拟化是一种电脑硬件及软件资源应用的抽象化概念。它隐藏了电脑资源的实体特性,令使用者或是执行其上的应用软件无法察觉,就形同于执行于独立的系统上。它可以将单独的电脑资源同时运行多个操作系统,也可将多个电脑资源联结起来,成为一个独立的环境提供操作系统使用。
虚拟化技术分别应用在不同的概念上,包含:

  • Server Virtualization
  • Desktop Virtualization
  • Network Virtualization
  • Storage Virtualization
  • Application Infrastructure Virtualization

在这篇文章中,我们将针对服务器虚拟化以及桌面虚拟化技术做讨论。

服务器与桌面虚拟化技术,单从字面上去看而没有深入了解时,可能会很容易混淆两者之间的差异,服务器虚拟化是一种将一台实体服务器,经过分割管理成多台较小型的虚拟服务器的技术。大多数的网页服务器,都是应用服务器虚拟化技术在实体服务器上所建置的虚拟机器,取代原本硬件的限制,服务器虚拟化技术能够让多个服务器系统共存于一台实体机器上。服务器虚拟化技术提供了以下几点优点:

  • 提高硬件使用率– 减少硬件及能源的消耗,减低管理的成本
  • 安全性– 虚拟机可以随时以映像档的方式保存,一旦系统出现问题,可以马上回复
  • 开发– 安装及设定都可以简单的程序重覆执行

桌面虚拟化,有时也可以称为连线端虚拟化技术,它的主要观念在于使用者可以使用由共用的硬件服务器提供出来的虚拟桌面环境。维基百科上对桌面虚拟化的解释为,桌面虚拟化是一种就传统使用者端运算轻量化所衍生出的服务器端运算模型,它的设计提供了管理者在中央服务器上管理每个使用者桌面虚拟机的能力,以及提供了每个使用者完整的个人电脑使用感受。
桌面虚拟化技术提供了独立的作业环境且无须个别的硬件环境或是操作系统甚至于电脑软件,而是透过中央的服务器系统提供了所有的功能,除此之外,他更包含有以下各项优点:

  • 使用者可以任意的由各处登入属于自己的桌面环境,而无须安装个别的操作系统
  • 使用者登入登出时,可随时更新桌面环境的现有的作业状态,随时备份现有桌面环境
  • 虚拟机器的状态快照,能够保持桌面环境的稳定性
  • 个人化设定与加密,使个别使用者的资料与工作状态保有安全性

参考文件:
Wikipedia – Desktop virtualization
Wikipedia – Hardware virtualization
WEBOPEDIA – The Difference Between Server and Client Virtualization
InfoQ – An Introduction to Virtualization


 

RabbitMQ

RabbitMQ 是提供 Advanced Message Queuing Protocol (AMQP) 这种 protocol 标准的讯息伫列. 是使用Erlang 来实做的! 而且提供了非常多其他语言的 client API。

  • Persistent message
  • Transaction
  • Virtual host
  • Cluser

Message Producer:
Message Produce 利用 routing key 来分配 message 的目的 exchange. 这个 routing key 会决定最后会把 message 送往哪个 Message Queue。

Exchange:
Exchange 会接受 message 并且找到 message 所对应的 Message Queue. 利用 Binding 来定义exchange 和 Message 的关系。
有三种型式的 Exchange
Fanout_Exchange
exchange:
Direct_Exchange
Topic_Exchange
Message Queue:
是用来保存 message, 并且把他们送到 message consumer。

Message Consumer:
是最后 message 接收的地方, 他们会根据所收到的 message 来做相对应的工作。

Reference:
http://notes.variogr.am/post/143623387/broadcasting- your-logs-with-rabbitmq-and-python
http://barryp.org/software/py-amqplib/
http://www.infoq.com/articles/AMQP-RabbitMQ
http://www.infoq.com/cn/articles/AMQP-RabbitMQ
http://wiki.secondlife.com/wiki/Message_Queue_Evaluation_Notes