redis的一些tips

这是我计划本周五在部门内分享的内容,先贴到这里:

Redis是一款最近比较热门的Key-value数据库,它的代码量少,配置简单,与memcache同样轻量级,对于了解NoSQL是一个很好的入口,相信通过介绍之后,无论是前端和后端开发工程师,都会迅速的爱上这款软件!

    * Intro:
          o http://dreamhead.blogbus.com/logs/61443218.html
          o http://labs.alcacoop.it/doku.php?id=articles:redis_land
          o http://code.google.com/p/redis/wiki/ProtocolSpecification
          o http://code.google.com/p/redis/wiki/CommandReference

    * Features:
          o Key-value db
          o Fast: all data are loaded in memory and saved on disk
          o Supporting data types: Strings(<1Gb), Lists, Hashes, Sets, Ordered sets.
          o Interfaces: push/pop、add/remove、sort
          o Replication:
                + 一个master支持多个slave
                + Slave可以接受其他slave的连接来替代他连接master
                + 复制在master是非阻塞的,而在slave是阻塞的
                + 复制被利用来提供可扩展性,在slave端只提供查询功能及数据的冗余

    * Download:
          o http://code.google.com/p/redis/

    * Install:
          o http://blog.chinaunix.net/u3/102568/showart_2339142.html

    * Start Server: ./redis-server
    * Close Server: ./redis-cli shutdown
    * Command Line Client: ./redis-cli
    * Bindings: http://code.google.com/p/redis/#Supported_languages
    * APIs: http://code.google.com/p/redis/wiki/CommandReference
    * Best Practices:
          o Counter
          o message queue
          o user db
          o Autocomplete: http://antirez.com/post/autocomplete-with-redis.html
          o Foursquare.com

我如何进行知识管理

  我们每天都接触到大量的信息,必须要有一个沉淀的机制使其转化为知识,否则在重新利用它们的时候,会消耗不必要的时间。下面我将自己管理知识的方法整理出来,供读者参考。

管理要做的事
  最快捷的方式是在桌面上新建记事本;如果你需要用复杂的格式记录它们,建议用onenote;如果你的手机是IPhone、Android、Blackberry系列的,那么恭喜你,还可以使用evernote将你的文件随身携带;不要忘记,小纸条也是很灵活的方式。
管理你的文档
  首先要保证你辛苦编写的文档不丢失,为此,我向你推荐几款工具:如果你有自己的备份空间,如FTP、共享文件夹等等,建议使用syncback,它会将你的文档目录与服务器端进行双向同步,显然也没有空间和网速的制约;你还可以用前面提到的evernote或微软的live mesh来进行同步,它们都为我们提供了若干G的共享存储空间。
  其次要保证你的文档能被随时找到,我强烈向你推荐Google桌面搜索,它通过为你电脑上的文件编制索引,方便你对其进行查找;另外,不建议使用微软自己提供的windows search,我的Thinkpad X201笔记本,只要启动了它的索引服务,CPU温度就会从正常的45度左右,飙升到80度以上,为了节能和CPU长寿,只得卸载之,而Google桌面搜索就没这方面的问题了。
管理下载的文档
  下载的文档特指电影、音乐等尺寸较大大的文件,如果不幸丢失,经济损失尚小,而备份它们的成本却最高。笔者目前也没有想到一劳永逸的办法,毕竟自己花钱购置硬件,总有一个寿命问题。相比较来说,买一块硬盘,加个硬盘盒,是比较经济的存储方式。
管理你的电脑
  如果电脑某天不幸需要重装,你便需要手忙脚乱的备份一大堆存放在C盘中的数据,如果平时就将你的数据打理的井井有条,就可以避免这一麻烦。现有几个小办法向读者提供:使用驱动备份专家之类的软件将你的驱动程序备份到别处,如果先前购置的硬件中有驱动光盘,建议将整张光盘做成ISO镜像存放在硬盘上;打开“我的文档”的属性窗口,修改文档路径为C盘以外的某个目录并转移;使用类似Firefox Sync的工具同步或备份你的浏览器书签等数据。

  相信大家也有许多自己的经验,欢迎到新浪微博(@房如华bluetent)上与我交流,谢谢。

在ssh终端下如何解决断线带来的困扰

  在linux环境下,使用ssh客户端进行开发的朋友们可能经常会被不稳定的网络环境所困扰:在掉线后,很多中断的脚本要重跑,目录要重进;vi会自动生成一些swap文件,甚至在recover后仍然存在,给操作带来了不便;若同时打开多个终端,损失就更大了。
  这里推荐一个简单的解决办法:

  1. 在linux服务器上安装一个叫screen的软件。
  2. 使用ssh客户端,用正常的方式远程连上服务器。
  3. 输入screen,此时你看到的终端画面已经被screen接管了。它同时保存了终端现场,从而使恢复现场成为可能。
  4. 此后进行正常的操作,终端界面的状态会被screen实时保存。在任何时候按Ctrl+a+d,都会从screen模式退回(Detach)到伪终端。输入screen -ls,可以看到被挂起的screen列表。再输入screen -r ,即可回到刚才的screen窗口。当然即使异常掉线了,重新登陆后,还是可以使用screen -r恢复现场的,这就是我们使用它的意义所在。
  5. 可以在.bash_profile里加一行
    alias r='screen -d `screen -ls |grep Attached|cut -f2|cut -f1 -d"."`;screen -r `screen -ls |grep Detached|cut -f2|cut -f1 -d"."`'
    能够方便的切回screen窗口(假设只开了一个screen)。

日历同步全攻略

  日历是很多软件和在线产品中都具有的功能,通过对日历中事件和任务的管理,可以有效的组织工作和生活中的各项活动。由于人们的活动地点会不断迁移(如公司到家),管理日历的媒介会不断变化(Outlook、Sunbird、手机),那么日历数据就会分散到不同的媒介中,不方便管理。针对上述问题,本文提供了一套解决方案,将不同媒介中的日历数据,以符合iCanlendar标准的格式与google calendar进行数据同步,使得每种媒介上都保持最新的信息。 继续阅读日历同步全攻略

谈ajax返回字符串的两种形式

  当javascript语句向服务器端发起ajax请求后,如果一切顺利,会从服务器端收到响应数据,浏览器会把这个响应字符串转交给回调函数处理。按我的经验,响应字符串有两种比较好的形式,一种是json,一种是html。下面以php5+smarty服务端开发模式为例作简要介绍:

  1. json方式:
    服务端对请求数据作如下处理:

    $param1 = $_POST["param1"];
    $result_array = foo($param1);
    $json_array = json_encode($result_array);
    echo($json_array);
    

    那么函数foo的返回值就以json数组的形式返回给客户端,这时直接用eval的方法将返回值赋给某个javascript变量就可以使用了。

  2. html方式:
    服务端对请求数据作如下处理:

    $param1 = $_POST["param1"];
    $result_array = foo($param1);
    $tpl = new Smarty();
    $tpl->assign("result", $result_array);
    $html = $tpl->fetch("foo1.html");
    echo($html);
    

    那么函数foo的返回值会被assign到一个smarty模板里,通过smarty的fetch方法,获得一段html代码,这时直接把html代码赋给某个div的innerHTML属性就可以了。

  第一种方式遵循了清晰的MVC结构。由于javascript还需处理返回的数组,所以适合响应数组比较简单的情况,不适合大段html代码的渲染。第二种方式将模板和JS、PHP进行了良好的分离,便于维护。由于html变化后,页面的dom结构也发生变化,所以适合大段html代码的渲染,不适合交互复杂的类C/S页面。

对extjs进行了裁剪和压缩

  最近打算在产品中使用extjs。考虑到这是一个线上环境,对javascript的要求比较高,因而计划对它进行裁剪和压缩,分以下几步进行:

  1. 使用extjs提供的在线裁剪工具(Build your own Ext)对庞大的extjs库进行定制。我定制了三种不同量级的版本,基本可以满足日常各种需要了。
  2. 使用JSA对裁剪后的代码进行语法压缩和文本压缩,其语法压缩具有极高的可靠性,文本压缩的比率也较高。
  3. 激活apache 2的mod_deflate模块,并启用对javascript的压缩。

  经过以上三步优化后,extjs的尺寸被缩减到了一个可以接受的数值了。具体效果参见下表:

支持的模块 原始版本尺寸 被JSA处理后版本尺寸 原始版本经deflate压缩后尺寸 JSA版本经deflate压缩后尺寸
jQuery
Ext Core
Core-Utilities
Data
Views
140369 77957 (55.5%) 41233 (29.4%) 36225 (25.8%)
在前一个基础上增加:
Core-Layers
Dialog
Form
QuickTips-Tooltip Widget
Loading Mask Widget
303172 164433 (54.2%) 85097 (28.1%) 73920 (24.4%)
在前一个基础上增加:
Core-Drag and Drop
DateMenu
ColorMenu
Resizable
Button Widget
Tabs Widget
SplitBar Widget
Menu Widget
Border Layout Widget
Toolbar Widget
Grid
Tree
Form-HtmlEditor
499490 261616 (52.4%) 133973 (26.8%) 114157 (22.9%)

可以看出:JSA的压缩比率接近一半;不过,无论代码是否被JSA压缩过,经mod_deflate模块处理后的大小都是比较接近的,也就是说,在服务器端开启gzip/deflate特性是非常必要的。

激活Drupal 4.6的分类功能

  在Drupal4.5中有一个非常有用的功能--“分类列表”,它会显示站点的所有分类,以及分类中node的个数和上次更新时间。但不知何故,4.6中去掉了这一特性,我们在设置block的时候找不到分类这个条目了。
  解决方法是这样:找到Drupal 4.5版本modules/taxonomy.module文件中的taxonomy_block函数,拷贝至4.6版本的同一位置下即可。这时block设置界面就会自动多出一个分类的条目,激活便能使用了。

一个迟到罚款数额的计算公式

  上班迟到要扣钱,一个简单的分段函数是无法达到很强的约束力的。于是我设计了一个略微复杂的函数,供地球上的HR参考。
  S = S0 + dTA1+ρn/N
  各参数代表的意义如下:
  S0:金额基数,即最低罚款额。
  d:比例系数。
  n:在该人到达公司前,当天公司已经迟到的总人数(人)。
  N:当天公司共需签到的总人数(人)。
  A:金额基数(元),可以为一个与T相关的函数。
  T:该人当天迟到的时间(分钟)。
  ρ:比例系数,用于调整N对S的影响。
  简述:某个人迟到需缴纳的罚款,跟当天迟到的分钟数线性相关。随着迟到人数占公司总人数的比例不断增加,罚款数额也会增加。
  这个函数将会起到如下作用:T对S的约束会促使员工无论迟到了多久,都要尽快到达公司,否则罚款是随时间不断上涨的。n对S的约束会促使员工尽量早到公司,否则总会比前一位同事多交罚款,并且客观上会降低迟到员工的总数。

微软Passport的登录流程

  1. 在浏览器输入www.passport.com,然后点击登录链接。
    进入这个页面:
    https://login.passport.com/ppsecure/secure.srf?&#8230;
    页面的form中只有一个叫做mspppostint的参数,长度745字节,怀疑为服务器生成的base64格式的密钥,用于验证login.passport.com跳到login.passport.net的合法性。如果是这样的话,那么这两台服务器应该共同约定一个双向加密算法,分别对mspppostint进行加密解密。
  2. 上述页面自动发送post请求到这个页面:
    https://login.passport.net/ppsecure/uisecure.srf?&#8230;
    好了,用户可以输入用户名和密码登录。
    在这个页面的form的action里,我看到url的domain是login.passport.com,另有两个参数是rn = IHL*ZsXU 和 tpf = b903d408b520d9c7914a4d39d46e948a,怀疑也是用于验证login.passport.net到login.passport.com的合法性。
  3. 登录成功后,页面跳转到https://accountservices.msn.com/default.srf?…
    从login.passport.net是如何跳到accountservices.msn.com的,我还没有弄明白,这关键一步请大家帮忙指点。

Google个性化页面中实例化XMLHTTP对象的方法

function x()
{
	var a=null;
	try
	{
		a=new ActiveXObject("Msxml2.XMLHTTP");
	}
	catch(c)
	{
		try
		{
			a=new ActiveXObject("Microsoft.XMLHTTP");
		}
		catch(b)
		{
			a=null;
		}
	}
	if(!a&&typeof XMLHttpRequest!="undefined")
	{
		a=new XMLHttpRequest();
	}
	return a;
}

  这个实例化方法至少支持IE、Firefox、Opera和Safari,它的一大特色是用了try…catch…,而不是经常用的if…else…,这种方式是比较稳妥和有效的。