什么是程序中的闭包?

闭包的使用在javascript中是一个很重要的概念,不过闭包概念比较复杂,很多初学者不是很能理解,看到有一篇利用c#介绍闭包概念的文章,分享一下。

在计算机科学中,闭包(Closure)是词法闭包(Lexical Closure)的简称,是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。所以,有另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。

所以,一个闭包就是一个“捕获”或“携带”了其被生成的环境中、所属的变量范围内所引用的所有变量的函数。的确,很难描述,但当你看完了这些代码后,你就很容易理解了。

var x = 1;

Action action = () =>
{
    var y = 2;
    var result = x + y;
    Console.Out.WriteLine("result = {0}", result);
};

action();

这里我们首先定义了一个变量“x”,值为1。然后我们定义了一个匿名函数(一个lambda表达式)赋给类型Action。Action没有参数,没有返回值,但如果你观察“action”里的定义,你会发现它使用了“x”变量。这是变量是被action“捕获”或“携带”的,自动被添加到了action的运行环境中了。

当我们执行action时,它输出了我们预期的结果。请注意,当我们执行时,原始的“x”此时已经脱离了它当初的变量环境,但它仍然能用。

当你在代码调试器(debugger)里观察“action”时,会发现很有趣的事情。我们可以看到,C#编译器为我们创建了一个Target类,里面封装了x变量:

闭包(和higher order functions)都是非常有用的东西。如果你曾经开发过稍微复杂一点的Javascript程序,你可能就会知道,这个东西可以被当成很多面向对象特征的替代品,就像C#那样。前不久我还在C#里写了一个例子来验证这种想法。

Posted in javascript | Tagged , | Leave a comment

absinthe 0.3全平台版本下载

absinthe短短几天已经发布到第三个版本,并且除了windows和mac以外,现在也支持linux了,这个针对iphone 4s和ipad2的完美越狱工具在短短几天已经破解了上百万的机器,apple怎么会不赚钱啊。(cydia怎么会不赚钱啊)

下载:

absinthe 0.3 for windows

absinthe 0.3 for mac

absinthe 0.3 for linux

Posted in ios, ipad, iphone, software | Tagged , , , , , | Leave a comment

如何在titanium中实现Path的按钮展出效果

2011年下半年最红的ios app无疑是Path了,其颠覆性的界面设计和内部蕴含的对于sns的深刻理解,值得我们学习借鉴。

Path在iOS上也改变了apple基本规定的tableview的5个按钮模式,独创了左下角按钮点击后滑动出更多按钮的效果。这个效果对于用一个手指来控制界面的大多数人来说,非常方便。

这里介绍一下如何在titanium中实现类似于Path的这个效果:

Path

这是@tonylukasavage写的,源代码可以在github上下载。

Posted in titanium | Tagged , , | Leave a comment

iPhone 4S iPad 2越狱工具Absinthe 0.2放出

这里消息,iphone 4s和ipad 2的完美越狱工具absinthe 0.2放出,这次包含了Windows版和Mac版。此次更新解决了早期的数据库问题(早期解决方案)、白屏问题,和图标错误问题。所以iPhone 4S和iPad 2用户现在可以选用这个最新的越狱工具解决这些问题。如果之前的越狱并没有什么影响,你可以不必再次折腾越狱了,这次没有什么新的改变,只能算是解决bug。

windows版本下载 absinthe 0.2 for win

mac版本下载 absinthe 0.2 for mac

Posted in ios, ipad, iphone | Tagged , , , , , , | Leave a comment

iPhone 4s和iPad 2 完美越狱工具发布

看来很多人在春节可以有事情做了,iPhone 4s和iPad 2 的越狱工具终于发布了,也就是说A5芯片也被找到漏洞了。

目前还只有在mac下运行的软件版本,做得很容易用,一键搞定,让我们想起当年iphone 4的越狱,一滑就ok了。

iPhone 4s和 iPad 2的完美越狱工具叫做:absinthe,它能完美越狱的系统版本包括运行iOS 5.0(9A334)和iOS 5.0.1(9A405和9A406)的iPhone 4S以及所有运行iOS 5.1(9A405)的iPad 2。

微盘下载地址在这里

Posted in ios, ipad, iphone, software | Tagged , , , | Leave a comment

2012春节将至

昨天开始,拥挤的上海终于安静一些了,路上车少了很多,到处可以看到拎着行李准备回家的人。

2011-2012,我重新回到了金融行业,十年,仿佛回到起点。

春节快到了,龙年将至,所有的朋友都新年快乐!

Posted in 生活 | Tagged | Leave a comment

我怎么备份文件和数据?

互联网时代,数据有多么重要,就不用说了,一方面,如何迅速的找到自己的文件,另一方面,防止数据丢失。我们或许都有过这样的经验教训,想要的某个文件肯定看到过,却怎么也找不到了。

从项目管理、时间管理等来说,文件管理是非常重要的一个环节,最近几年很红的dropboxbox以及云存储等,都是对个人文件、团队和企业文件共享的全新诠释。

如同dropbox的口号:简化您的生活。良好的文件、数据管理将会大大简化您的工作和生活。

备份文件和数据,不是就用一个移动硬盘,定期(很多人也不一定做得到)copy一下就好可以了。

介绍一下自己很多年来摸索使用的一些方法,我相信对于大多数人来说使用其中的部分应该可以了,从某种程度上来说,我是个备份达人了。

1 简单备份。一般的移动硬盘对于文件复制来说,是很方便,现在的移动硬盘存储量也很大,300G-500G的对于一般的备份来说是足够了,不过移动硬盘备份需要用户主动复制,比较简单的办法是建立年份和月份的路径,将需要备份的文件统统复制过去,过一段时间,删除之前的路径。不过,即便能够这样做到,也比较费时间,这样的简单备份不是很推荐。不过,简单备份有一个特例,如下:

2 影视音乐文件备份。如果你像我一样是追剧狂人,那么移动硬盘是比较好的存放美剧的地方,相对来说,剧集还是比较大的文件,一般的rmvb要200-300M左右,而mkv格式400-600M也很正常,如果追求高清的话,2G一个则是起点了。这些文件通过网络存储还是不太划算的,因为文件太大,并且一般情况下也不会有很紧急的需求。移动硬盘是一个很好的选择。

移动硬盘一般分3.5寸、2.5寸和1.8寸等,3.5寸的也就和台式机用的硬盘一样,2.5寸的和笔记本用的硬盘一样,暂时还没有什么人用ssd来尝试,太贵了。3.5寸的移动硬盘一般需要外接电源,作为电脑的固定备份比较方便,2.5寸的移动硬盘是最常见的,一般只需要usb就能供电了。1.8的更加小巧,但是存量也小一些。

对于剧集,本季正在下载和看的,就存放在台式机了,本季结束的也看完了的就存放到外置移动硬盘中了。

在更换电脑,或者重装系统的时候,我也用外置式硬盘做备份。所以可能的话,准备两个,一个用来存放剧集等不太重要的数据,一个用来存放相对重要的文件、软件等。

3 如果备份都靠手工,效率不高,也容易出错。所以我大部分情况下用自动备份。

自动备份有很多可以选择的供应商和软件,我选择的是crashplan,它的其中一个家庭用套装可以:

* 客户端软件支持windows和mac
* 最多支持10台不同的电脑进行备份,以及这些电脑互相备份
* 没有限量的云存储内容
* 对于设定好的路径,全自动备份,只要电脑开着,就会进行备份
* 可以将一台电脑的数据自动备份到另外一台电脑,在一个局域网中的电脑互相备份速度是非常快的
* 所有的数据备份存储是加密的
* 可以通过网站访问所有电脑和备份文件夹的文件,并下载
* 可以通过一台电脑的客户端来访问所有设定好的备份文件
* 可以用过iphone客户端来访问所有备份的文件
* 修改过的文件,保存多个历史版本

是否功能很强,当然价格也不便宜,一年需要120美元,换来的就是放心。用了crashplan之后,不用担心文件会丢失,并且因为文件的备份可以设置到控件比较富裕的台式机,因此也不担心只存在看不见的云端了。

同时,我通过iphone和ipad可以随时随地查看文件,主流的office文档等也可以在客户端自身浏览或者通过安装的keynote等软件浏览。

4 网络硬盘。上面的方法对于保护自己的文件来说,已经接近完美了,但是有很多时候还是需要将文件共享给其他人,或者有些文件可能自己用得多,但是也偶尔需要分享一下,那么这时候网络硬盘就很有用了。

网络硬盘我用的比较多的是115新浪微盘box

网络硬盘的好处除了可以上传文件给自己保留一个备份以外,主要是可以很方便的共享给别人进行下载。在网络硬盘刚出来的时候,还会有很多限制,现在无论是控件还是带宽限制已经小很多了,并且文件也可以大到100M-1G。有时候,网络硬盘基本可以替代U盘,特别是一些频繁的文件共享。

115网盘一开始开始不错的,不过它的文件只能共享30天,然后需要作者主动续期,这实在不太方面,当然,收费服务就没有问题了。

新浪网盘出来没有多久,上传下载速度很快,几乎没有什么限制(因为没有收费版,所以也没有区别)。

box是国外的网盘,已经推出很多年了,现在和国内的网盘相比,速度一般了,并且容量偏小(5G)。

我平时拍摄的部分照片就经常上传到网盘,和同事们分享,无论是115网盘还是新浪网盘,都能生成一个唯一的url,一般也不会被猜测出来,所以还是比较安全的。当然如果是个人隐私的文件,就不建议分享出来,或者用前面说的方法,私有保存比较合适。

5 时光机器。Time Machine。有了上面这些文件和数据备份方案,还是不太放心的话,mac用户还有一个选择,就是时光机器程序,通过usb连接一个大容量的移动硬盘,之后就不用管了,苹果的这个软件会每小时做一次电脑的备份,然后对于一个月来说,保留每天的备份,然后对于每个月做周备份,当磁盘装满时,则删除最早的备份。

有了这个时光机器,我们可以随时到过去的某个时间点,来寻找文件。并且如果电脑出问题的话,有时光机器的备份在,就可以把电脑完整的恢复到最新的状态,包括操作系统、程序、数据文件等,基本就是一摸一样。windows即便到了7这个版本,还是缺乏这样强有力的备份软件,可以从系统级别进行完整的恢复。

6 其他数据同步方式。

个人经常会在不同的电脑上收集资料,这方面最好的同步笔记软件,目前来说是evernote,各个操作系统都有客户端软件,iphone和ipad也有,也可以web登陆,即便是免费版限制笔记数量和流量,对于一般使用也足够了。我可以在笔记本上看到某篇文章,复制到evernote,然后在iphone上有空的时候学习查看。evernote的同步特性、web页面保留完整性、笔记归类等都做的非常好用。

不要忘记gmail,这是一个很好的邮件备份工具,我用gmail的pop3收信功能将公司的邮件做一个备份,这样也就做到了到哪里都可以查看和搜索,没有人的搜索功能做的比gmail好了。一般来说gmail也有5G多的容量,我又买了一年20G的额外控件,费用是5美元,保留工作和生活的所有邮件,如果不用类似的技术,会很复杂,因为多个邮箱很难同步到一起,outlook的数据文件格式比较复杂,而web邮件基本都没有办法导出。同时,你把文件发个邮件给自己的gmail,需要的时候,强大的搜索总不会让你失望。

简单介绍文件和数据的备份如上,准备好1-2个3.5寸的T级硬盘,准备好1-2个2.5寸的便携硬盘,如果有条件的话,再准备一些美元,你的文件和数据备份就可以省心很多,所有的这些方案都是为了买个放心,为了一些意外情况准备的。要省钱,需要自己多做一些操作,花点钱,可以让很多操作自动化。

Posted in internet, software | Tagged , , , , , , , | Leave a comment

php实现mongodb的基本操作

因为nosql逐渐流行,以及一些需求需要对数据进行密集的实时处理,我个人在很多时候无法忍受需要10分钟以上才能计算得出的数据结果,每天都会产生大量的数据,而对于数据的分析又经常变化,甚至有很多情况下需要对数据进行后处理,传统的关系数据库对于这方面的操作就显得比较复杂,“行”的数据结构是固定的,不同表之间的关系也会因为关联字段的关系显得很复杂。

mongodb是目前比较优秀的nosql之一,目前正在业余时间进行一些学习和测试,下面是网上介绍的基于php使用mongodb的基本操作:

说到php连mongoDB,不得不先介绍一下php的官方手册,网址在:http://us.php.net/manual/en/book.mongo.php

在php的mongo扩展中,提供了4类接口(对象):

1,针对mongoDB连接的操作:Mongo

http://us.php.net/manual/en/class.mongo.php

2,针对mongoDB中数据库的操作:MongoDB

http://us.php.net/manual/en/class.mongodb.php

3,针对mongoDB中collection的操作:MongoCollection

http://us.php.net/manual/en/class.mongocollection.php

4,针对查询结果集的操作:MongoCursor

http://us.php.net/manual/en/class.mongocursor.php

与mongoDB建立连接:

直接实例化mongo类+创建连接:

$mo = new Mongo();//得到一个Mongo连接对象

实例化了一个Mongo类,并且与默认的localhost:27017端口的mongoDB建立连接。

如果想连接到其他的主机,可以这样写:$mongo = new Mongo(“mongodb://username:password@192.168.1.22:12345″);

另外一种方式,实例化mongo类,再手动建立连接:

$mongo = new Mongo(“mongodb://username:password@192.168.1.22:12345″,array(‘connect’=>false));//初始化类

$mongo->connect();//创建连接

Mongo类中有用的一些方法:

Mongo::listDBs()

http://us.php.net/manual/en/mongo.listdbs.php

返回一个包含当前mongo服务上的库(DB)信息的数组。

$mo = new Mongo();

$dbs = $mo->listDBs();//获得一个包含db信息的数组

Mongo::selectCollection($db,$coll)

http://us.php.net/manual/en/mongo.selectcollection.php

返回一个当前连接下的某db中的collection对象。

$mo = new Mongo();

$coll = $mo->selectCollection(’db’,’mycoll’);//得到一个collection对象

选择想要的数据库(Mongo类):

一种方式:

http://us.php.net/manual/en/mongo.get.php

$mongo = new Mongo();

$db = $mongo->foo;//得到一个MongoDB对象

另一种方式:

http://us.php.net/manual/en/mongo.selectdb.php

$mongo = new Mongo();

$db = $mongo->selectDB(’foo’);//得到一个MongoDB对象

MongoDB中有用的函数:

创建一个MongoDB对象

http://us.php.net/manual/en/mongodb.construct.php

$mo = new Mongo();

$db = new MongoDB($mo,’dbname’);//通过创建方式获得一个MongoDB对象

删除当前DB

http://us.php.net/manual/en/mongodb.drop.php

$db = $mo->dbname;

$db->drop();

获得当前数据库名

http://us.php.net/manual/en/mongodb.–tostring.php

$db = $mo->dbname;

$db->_tostring();

选择想要的collection:

A:

$mo = new Mongo();

$coll = $mo->dbname->collname;//获得一个collection对象

B:

$db = $mo->selectDB(’dbname’);

$coll = $db->collname;

C:

$db = $mo->dbname;

$coll = $db->selectCollectoin(’collname’);//获得一个collection对象

插入数据(MongoCollection对象):

http://us.php.net/manual/en/mongocollection.insert.php

MongoCollection::insert(array $a,array $options)

array $a 要插入的数组

array $options 选项

safe 是否返回操作结果信息

fsync 是否直接插入到物理硬盘

例程:

$coll = $mo->db->foo;

$a = array(’a’=>’b’);

$options = array(’safe’=>true);

$rs =$coll->insert($a,$options);

$rs为一个array型的数组,包含操作信息

删除数据库中的记录(MongoCollection对象):

http://us.php.net/manual/en/mongocollection.remove.php

MongoCollection::remove(array $criteria,array $options)

array $criteria 条件

array $options 选项

safe 是否返回操作结果

fsync 是否是直接影响到物理硬盘

justOne 是否只影响一条记录

例程:

$coll = $mo->db->coll;

$c = array(’a’=>1,’s’=>array(’$lt’=>100));

$options = array(’safe’=>true);

$rs = $coll->remove($c,$options);

$rs为一个array型的数组,包含操作信息

更新数据库中的记录(MongoCollection对象):

http://us.php.net/manual/en/mongocollection.update.php

MongoCollection::update(array $criceria,array $newobj,array $options)

array $criteria 条件

array $newobj 要更新的内容

array $options 选项

safe 是否返回操作结果

fsync 是否是直接影响到物理硬盘

upsert 是否没有匹配数据就添加一条新的

multiple 是否影响所有符合条件的记录,默认只影响一条

例程:

$coll = $mo->db->coll;

$c = array(’a’=>1,’s’=>array(’$lt’=>100));

$newobj = array(’e’=>’f’,’x’=>’y’);

$options = array(’safe’=>true,’multiple’=>true);

$rs = $coll->remove($c,$newobj,$options);

$rs为一个array型的数组,包含操作信息

查询collection获得单条记录(MongoCollection类):

http://us.php.net/manual/en/mongocollection.findone.php

array MongoCollection::findOne(array $query,array $fields)

array $query 条件

array $fields 要获得的字段

例程:

$coll = $mo->db->coll;

$query = array(’s’=>array(’$lt’=>100));

$fields = array(’a’=>true,’b’=>true);

$rs = $coll->findOne($query,$fields);

如果有结果就返回一个array,如果没有结果就返回NULL

查询collection获得多条记录(MongoCollection类):

http://us.php.net/manual/en/mongocollection.find.php

MongoCursor MongoCollection::find(array $query,array $fields)

array $query 条件

array $fields 要获得的字段

例程:

$coll = $mo->db->coll;

$query = array(’s’=>array(’$lt’=>100));

$fields = array(’a’=>true,’b’=>true);

$cursor = $coll->find($query,$fields);

返回一个游标记录对象MongoCursor。

针对游标对象MongoCursor的操作(MongoCursor类):

http://us.php.net/manual/en/class.mongocursor.php

循环或的结果记录:

$cursor = $coll->find($query,$fields);

while($cursor->hasNext()){

$r = $cursor->getNext();

var_dump($r);

}

或者

$cursor = $coll->find($query,$fields);

foreache($cursor as $k=>$v){

var_dump($v);

}

或者

$cursor = $coll->find($query,$fields);

$array= iterator_to_array($cursor);

一个血的教训:

http://us.php.net/manual/en/mongocursor.snapshot.php

详见 不断变化的MongDB结果集

在我们做了find()操作,获得$cursor游标之后,这个游标还是动态的,也就是在我获得游标到我循环操作完成对应记录的过程中,默认情况下,这对符合条件的记录如果增加,结果集也会自动增加。换句话说,在我find()之后,到我的游标循环完成这段时间,如果再有符合条件的记录被插入到collection,那么这些记录也会被$cursor获得。

如果你想在获得$cursor之后的结果集不变化,需要这样做:

$cursor = $coll->find($query,$fields);

$cursor->snapshot();

foreache($cursor as $k=>$v){

var_dump($v);

}

Posted in php | Tagged | Leave a comment