月度归档:2013年09月

J.U.C 包

概述

J.U.C 包是java.util.concurrent包的简写。这个包在JDK5引入,大大增强了Java的并发特性。JDK7还引入ForkJoin框架。

该包提供的能力主要包括:可重入锁,具有原子性操作属性的类,线程池执行服务,调度执行服务,增强的线程安全容器,线程关卡,信号器,ForkJoin任务执行框架等等。
继续阅读

Redis-RDB-Dump-File-Format 中文翻译

今年年初翻译的,都忘得差不多了,最近想用Go写个程序解析RDB文件,重新翻出来。

翻译自:
https://github.com/sripathikrishnan/redis-rdb-tools/wiki/Redis-RDB-Dump-File-Format

如果对本文档的后续更新有兴趣,可关注:https://github.com/wen866595/open-doc

Redis RDB 文件格式

Redis *.rdb 文件是一个内存内存储的二进制表示法。这个二进制文件足以完全恢复Redis的状态。

rdb文件格式为快速读和写优化。LZF压缩可以用来减少文件大小。通常,对象前面有它们的长度,
这样,在读取对象之前,你可以准确地分配内存大小。

为快速读/写优化意味着磁盘上的格式应该尽可能接近于在内存里的表示法。这种方式正是rdb文件采用的。
导致的结果是,在不了解Redis在内存里表示数据的数据结构的情况下,你没法解析rdb文件。

解析RDB的高层算法

在高层层面看,RDB文件有下面的格式:


----------------------------# RDB 是一个二进制文件。文件里没有新行或空格。
52 45 44 49 53              # 魔术字符串 "REDIS"
00 00 00 03                 # RDB 版本号,高位优先。在这种情况下,版本是 0003 = 3
----------------------------
FE 00                       # FE = code 指出数据库选择器. 数据库号 = 00
----------------------------# 键值对开始
FD $unsigned int            # FD 指出 "有效期限时间是秒为单位". 在这之后,读取4字节无符号整数作为有效期限时间。
$value-type                 # 1 字节标记指出值的类型 - set,map,sorted set 等。
$string-encoded-key         # 键,编码为一个redis字符串。
$encoded-value              # 值,编码取决于 $value-type.
----------------------------
FC $unsigned long           # FC 指出 "有效期限时间是豪秒为单位". 在这之后,读取8字节无符号长整数作为有效期限时间。
$value-type                 # 1 字节标记指出值的类型 - set,map,sorted set 等。
$string-encoded-key         # 键,编码为一个redis字符串。
$encoded-value              # 值,编码取决于 $value-type.
----------------------------
$value-type                 # 这个键值对没有有效期限。$value_type 保证 != to FD, FC, FE and FF
$string-encoded-key
$encoded-value
----------------------------
FE $length-encoding         # 前一个数据库结束,下一个数据库开始。数据库号用长度编码读取。
----------------------------
...                         # 这个数据库的键值对,另外的数据库。
FF                          ## RDB 文件结束指示器
8 byte checksum             ## 整个文件的 CRC 32 校验和。

继续阅读

散列

散列一般也叫哈希。散列表也叫哈希表。本位将介绍散列表的基本知识、一致性哈希、哈希碰撞攻击及Java里的哈希实现。

介绍

散列表是普通数组概念的推广,在最坏情况下查找一个元素需要O(n),在一些合理假设下,查找一个元素的期望时间为O(1)。

在散列表中,不是直接把关键字用作数组下标,而是根据关键字计算出下标。

散列函数:作用就是根据关键字计算出数组下标。

碰撞(collision):多个关键字映射到同一个数组下标位置。

槽:一般把散列表的数组的一个存储单元(元素)叫做槽。

简单一致性散列:(Simple uniform hashing)假设任何元素散列到m个槽中的每一个的可能性是相同的,且与其他元素已被散列到什么位置上独立无关,这个假设称为简单一致性散列。

继续阅读

我的学习工具

今天跟一个同学聊天,发现很多很好用的工具他都还不知道,我周围的绝大多数同事也不知道。虽然我用的工具不多,用得也不是很深入,但对我的帮助已经非常大,所以写的文字介绍。

浏览器

首先要说的是浏览器,因为上网大多数都是在浏览器里进行的。我用的是Firefox,因为有很多插件可用。Chrome也不错,只是习惯了火狐。

火狐的一个很重的功能是账号同步功能,可以同步的最重要的两个内容:已安装插件、书签。也就是在办公室的火狐上安装了一个插件或者收藏了一个网址,回家后也有了,不用再搞一遍。换了一台机或重装了系统,登录火狐账号后,一切又回来了。这也是云的作用吧!

浏览器插件

现在用的浏览器插件主要有:

  • AutoProxy:翻墙,你懂的!
  • pocket:以前好像叫“read it later”。可以把网页的内容收藏起来、归档,以后想看的时候再看。排版不错,对有些网站还会去掉一些网页周边的广告,只保留内容。
  • 印象笔记插件:可以把一个网页、图片、网址减藏到印象笔记里。在浏览器里用google搜索时,还可以搜笔记里的内容。
  • DownThemAll:下载,断点续传、分块下载。
  • 花瓣插件:微博上很多有价值的文章是图片形式的长微博,保存到花瓣方便查找。
  • 微博极简:过滤微博的,很多信息比如广告是不想看到的。

继续阅读

base64加密 or base64编码?

base64加密?

最近又碰到这么个奇葩的需求:“出于安全考虑,把Cookie里xxx属性的值用base64加密。”

之前碰到的另一个场景是:“一个PC客户端上传一些文件,不采用base64编码没法上传”。在这个案例建议人家取消base64编码时,人家也抬出了“安全”的大棒。

有base64加密吗??真木有,只有base64编码。

base64编码

关于base64编码,来自维基百科 http://zh.wikipedia.org/zh/Base64

Base64是一种基于64个可打印字符来表示二进制数据的表示方法。由于2的6次方等于64,所以每6个比特为一个单元,对应某个可打印字符。三个字节有24个比特,对应于4个Base64单元,即3个字节需要用4个可打印字符来表示。它可用来作为电子邮件的传输编码。在Base64中的可打印字符包括字母A-Z、a-z、数字0-9 ,这样共有62个字符,此外两个可打印符号在不同的系统中而不同。一些如uuencode的其他编码方法,和之后binhex的版本使用不同的64字符集来代表6个二进制数字,但是它们不叫Base64。

Base64常用于在通常处理文本数据的场合,表示、传输、存储一些二进制数据。包括MIME的email,email via MIME,在XML中存储复杂数据。

编码后的数据比原始数据略长,为原来的4/3 。在电子邮件中,根据RFC 822规定,每76个字符,还需要加上一个回车换行。可以估算编码后数据长度大约为原长的135.1%。

使用恰当的锤子

一句话来说:base64编码是用来解决把不可打印的内容塞进可打印内容的需求的。

如果需要加密,请使用专业的加密算法。想以“一般的用户看不到加密后的内容”为借口,只会糊弄自己。一般的用户不会去查看Cookie的内容,恶意的人根本就不会被这点小伎俩糊弄。

别再用“base64加密”,请用“base64编码”!

SMART任务

摘自:《程序员的思维修炼:开发认知潜能的九堂课》

这里的SMART代表具体的、可度量的、可实现的、相关的和时间可控的(Specific, Measurable, Achivable, Relevant, Time-boxed)。对于任何目标,都需要制定一个计划,定出一序列帮助你实现目标的任务。每个任务都应该具有SMART特性。

  • 具体的。一个目标任务应该是具体的。“想学习Erlang”是不够具体的,“想用Erlang编写一个可以动态生成内容的Web容器”就是具体的。

  • 可度量的。可度量的与具体的是相辅相成。很难度量笼统抽象的事物,但是很容易度量具体和详细的事物,只要使用确切的数字即可。度量任务目标,要采取增量进步的方法。

  • 可实现的。一个无法达到的目标不是目标,只是一种疯狂、吸食灵魂的自我挫败。先确定目标是否合理。从现在所处的情况着眼,让每一个目标都可实现。

  • 相关的。目标需要相关,需要在掌控之中。

  • 时间可控的。需要设定一个最后期限,没有期限,目标会逐步衰退,永远被每天更紧急的事情所排挤,这样它永远不会实现。

稳抓稳打,采取循序渐进、比较细小的里程碑。当实现它们之后,会更有动力去实现下一个里程碑。

正则表达式反向引用

参考: http://java.dzone.com/articles/backreferences-java-regular

以前没用过这种用法,mark。

介绍

反向引用是基于的,组就是把多个字符当作单一的单元看待。组是通过在一对小括号(())内放置正则字符来创建的,每对小括号对应一个组。

反向引用是便捷的,允许重复正则而不需要再写一次。可以通过 \# 来引用前面定义的组,# 是组的序号,从 1 开始。

正则引擎在处理匹配时,要求 反向引用与所引用的组 匹配的内容必须是一样的:即,(\d\d\d)\1 匹配 123123,而不匹配123456

继续阅读