测量了小区跑道长度

今天晚上无聊, 用GPS测量了一下小区环形跑道的长度。 居然有1.09公里, 不测不知道,一测吓一跳。现在差不多每天晚上都下去跑2-3圈,平均每圈6分半的时间. 体重暴涨8公斤后还能跑成这样,不算太差了 

 

9月23号的terry fox run, 和10月15号的北京马拉松就要到了, 要加紧练习了。 感兴趣的朋友可以在 http://www.beijing.gc.ca/beijing/ch/TFR.htmhttp://www.beijing-marathon.com/chinese/default.asp 获取进一步的资料。

未来应该会出现专门的数据存储冗灾服务提供商

最近看了很多关于存储的资料, 深raid, fc, sas, nas 一大堆名词扑面而来。 看的时候就一直在想一个问题, 如何能保证数据的安全性呢? 可以用raid, 可万一raid卡坏了怎么办? 那就用双机热备份, 可万一这个机房着火了怎么办, 那就只有在一个远离这个机房的地方再保存一个备份才能保证数据安全了。 大公司有这么做的, 北京政府甚至在昌平专门建有冗灾数据中心, 但这对广大的中小厂商来说有成本太高之嫌。这应该就是一个新的机会,IT业发展到现在需要有专业的第三方的廉价的数据存储冗灾公司。
下面设想一下这样的公司的实现细节,他应该有如下特点

  1. 这个公司有至少三个机房, 每个机房之间的直线距离, 至少超过1000公里, 其中至少有个机房, 和最远的机房有1万公里以上的直线距离。这样也保证了机房至少会在两个以上的国家分布。 这样自然灾害,战争同时威胁到所有机房的可能性近乎为0.
  2. 保证每个保存的数据都至少有三个拷贝, 每个拷贝在不同的机房。 这样3个拷贝同时坏掉的可能性微乎其微
  3. 为了降低成本,不用raid卡,不用nas。每个存储单元采用pc机, 每个pc机挂4个或更多1TB SATA硬盘, linux系统。 由主控机决定什么数据存储到哪个节点机
  4. 客户可以通过http或ftp访问, 或者专门的开放协议(提供给用户各种语言的sdk), 数据只能添加不能修改,删除(防止用户操作失误)。系统自动的将用户新添加的数据扩散到其他的机房。用户要读取数据时, 系统会自动给他选择一个最近的机房。
  5. 根据用户申请的存储空间收费和读的次数和数据量来收月费。可以推出针对个人的数据备份服务, 价位应该是1G/月 , 1块人民币的样子
  6. 整个数据备份的过程自动进行, 人们只是维护。 维护不需要调整bug, 只要发现哪里有问题,不用修,直接换掉
  7. 随着技术的发展, 硬盘容量的提高, 只要不停的换节点机, 交换器,申请更高的带宽即可

这些应该都没什么不可逾越的技术难度。 微软和google现在都在搞网络硬盘, 应该就有这个意思。设想的这种第三方数据冗灾服务应该不远了,没准早有了,只是我还不知道。

Subversion不完全安装笔记

昨天深夜开始安装Subversion,折腾了很久,终于搞定。 把过程写出来与大家分享,整个安装过程主要参考了 http://www.jlchannel.com/blog/?p=104http://www.newbooks.com.cn/info/52691.html

安装环境为

内核:Linux version 2.6.9-34.ELsmp
操作系统:Red Hat Enterprise Linux AS release 4 (Nahant Update 3)

Web Server: Apache 2.0 ( Web server必须是Apache 2.0以上,Subversion数据库才能通过http协议去访问)

  1. 先到http://subversion.tigris.org 下载最新的文件, 分别是subversion-1.4.0.tar.gz 和 subversion-deps-1.4.0.tar.gz
  2. 将文件包解压
    tar zxvf subversion-1.4.0.tar.gz
    tar zxvf subversion-deps-1.4.0.tar.gz
  3. 开始编译
    cd subversion-1.4.0
    ./congiure
    make
    make install在我用的系统里被安装到了 /usr/local/bin
  4. 编辑http.conf
    加入下面的两行
    LoadModule dav_svn_module modules/mod_dav_svn.so
    LoadModule authz_svn_module modules/mod_authz_svn.so
    DAV svn
    SVNParentPath /data/svn //svn父目录

    Require valid-user //采用何种认证
    AuthType Basic //连接类型设置
    AuthName “Subversion repository” //连接框提示
    AuthzSVNAccessFile /data/svn/accessfile //权限配置文件
    AuthUserFile /data/svn/passwdfile //用户配置文件
  5. 创建数据目录
    cd /data
    mkdir svnsvnadmin create /data/svn/test //创建测试目录

    chown -R nobody /data/svn //很重要,否则从apache访问不了
  6. 管理用户
    htpasswd /data/svn/passwdfile admin //添加用户
  7. 权限设置
    编辑 /data/svn/accessfile
    加入
    [test:/] //这表示,仓库test的根目录下的访问权限
    admin = rw //test仓库admin用户具有读写权限
  8. 重起Apache
    /usr/local/apache/bin/apachectl restart
  9. 服务器端安装完毕
    从http://www.xxxx.com/svn/test 就能够访问了
  10. 安装客户端
    http://tortoisesvn.tigris.org/ 下载TortoiseSVN。一个WIndows资源管理器插件, 把Subversion客户端和资源管理器近乎完美的结合到了一起,现在就可以开始用了。 Let’s GO!

后记:

要注意的还有如下几点:

  1. 服务器端的运行方式除了通过http访问外,还可以是用svn自己的服务器运行,但没有尝试
  2. svn存储数据有两种方式,一种是文件,一种是berklydb, 但是没有让我选择。
  3. Subversion服务器端全靠字符界面来配置,自己手动写配置文件,很麻烦, 尤其是要对整个项目树进行精确的权限管理的时候。 有个Web界面的配置工具 SVNManager,应该能节省很多力气。可惜因为php5安装出现莫名奇妙的问题而没有尝试成功,如果有尝试成功的还请给出测试报告。

try{} catch(…){}

以前都是用try{} catch(…){}来捕获C++中一些意想不到的异常, 今天看了Winhack的帖子才知道,这种方法在VC中其实是靠不住的。例如下面的代码:


try
{
BYTE* pch ;
pch = ( BYTE* )00001234 ; //给予一个非法地址

*pch = 6 ; //对非法地址赋值,会造成Access Violation 异常
}
catch(…)
{
AfxMessageBox( “catched” ) ;
}


这段代码在debug下没有问题,异常会被捕获,会弹出”catched”的消息框。 但在Release方式下如果选择了编译器代码优化选项,则VC编译器会去搜索try块中的代码, 如果没有找到throw代码, 他就会认为try catch结构是多余的, 给优化掉。 这样造成在Release模式下,上述代码中的异常不能被捕获,从而迫使程序弹出错误提示框退出。

那么能否在release代码优化状态下捕获这个异常呢, 答案是有的。 就是__try, __except结构, 上述代码如果改成如下代码异常即可捕获。


__try
{
BYTE* pch ;
pch = ( BYTE* )00001234 ; //给予一个非法地址

*pch = 6 ; //对非法地址赋值,会造成Access Violation 异常
}
__except( EXCEPTION_EXECUTE_HANDLER )
{
AfxMessageBox( “catched” ) ;
}

但是用__try, __except块还有问题, 就是这个不是C++标准, 而是Windows平台特有的扩展。 而且如果在使用过程中涉及局部对象析构函数的调用,则会出现C2712 的编译错误。 那么还有没有别的办法呢?

当然有, 就是仍然使用C++标准的try{}catch(..){}, 但在编译命令行中加入 /EHa 的参数。这样VC编译器不会把try catch模块给优化掉了。

找到一篇比较好的英文文章谈这个问题: http://members.cox.net/doug_web/eh.htm

用C++10 年多了 , 居然这么基础的问题都搞错, 真是汗颜。 要加紧学习啊, Stay Hungry, Stay Foolish!

recordhistory.org被封了

决定做的时候就料到的,只是没想到这么快

封的第一天,流量下降到原先的十分之一

当初做这个站只是为了自己历史方面的爱好, 也有借此熟悉wiki系统的意思。现在被封了,感觉很是失落。

对我们这个政府,……………………,实在没什么好说的了。

以后如果孩子们问为什么留给他们这么糟糕的国家的时候, 会告诉他自己曾尽了一个公民的责任去努力让它变好,可这个国家实在不是我们这种卑微草民能改变的。

https协议还可以访问, 谁要看的请点 https://www.recordhistory.org, 只是图片在https显示不出来。

我的blog也开始挣钱了:)

作了近1个月的google adsense, 终于挣到了1.20美刀. Adsense的大牛们别笑,自己很知足了:D。

大家谁要感兴趣也去 google adsense 申请个帐号吧。 不过中文的 adsense 市场比英文要差很多(从我的站点看,中英文adsense要差10倍以上),大家要有心理准备。 要么就是写给老外看的英文blog, 王健硕的blog主要就是英文内容, 据说收入一个月在5000人民币左右。

下面是一些真正挣钱的blog

http://www.boingboing.net/ 年收入100万美元的blog

http://www.techcrunch.com/ 月收入6万美元的blog

http://www.huffingtonpost.com/ 获VC 500万美元的blog

Smart Archives 增强

安装了 Justin Blanton 开发的 smart archives 插件, 发现这个插件对中文和韩文支持不佳。我给做了点小修改,并且对他的一些小缺陷也进行了补正。最后的效果请看 http://www.doyj.com/archives/

安装方法如下:
  1. 将下面的代码拷贝并存成文件smartarchives.php
  2. 将smartarchives.php 上载到你的plugin目录
  3. 到控制面板激活Smart Archives 插件
  4. 在适当的地方插入smartArchives()函数调用。
    这个函数有两个参数,第一个在”both”, “block”,”list”中选择,默认为both 第二个是要排除的分类id.
下面就是修改后的代码:


‘.$years[year].’: ‘);
$qm = mysql_query(“SELECT distinct month(post_date) as monthv
FROM $tableposts
ORDER BY monthv asc”) or die(mysql_error());

for ($i=1; $i<=12; $i++) { $q = mysql_query("SELECT *, year(post_date) as year FROM $tableposts WHERE year(post_date)='$years[year]' AND month(post_date)='$i' AND post_status='publish' AND post_date <= NOW() ORDER BY id desc") or die(mysql_error()); $sm = $month[zeroise($i,2)]; // get the shortened month name; strtotime() localizes if(mysql_num_rows($q)) { echo('‘.$sm.’ ‘); }
else
{ echo(‘‘.$sm.’ ‘); }
}

echo(‘
‘);
}
echo (‘

‘);
}

if (($format == ‘both’) || ($format == ‘list’)) { //check to see if we are supposed to display the list
$qy = mysql_query(“SELECT distinct year(post_date) as year, post_status
FROM $tableposts
WHERE post_status=’publish’
AND post_date <= NOW() ORDER BY year desc"); // loop to display links to all posts, sorted by descending month and day while($years = mysql_fetch_array($qy)) { $qm = mysql_query("SELECT distinct month(post_date) as monthv FROM $tableposts ORDER BY monthv desc") or die(mysql_error()); while($date = mysql_fetch_array($qm)) { $q = mysql_query("SELECT *, year(post_date) as year, month(post_date) as monthv FROM $tableposts WHERE year(post_date)='$years[year]' AND month(post_date)='$date[monthv]' AND post_status='publish' AND post_date <= NOW() ORDER BY id desc") or die(mysql_error()); if(mysql_num_rows($q)) { $lm = $month[zeroise($date[monthv],2)]; // get the full month name; strtotime() localizes echo('

‘.$lm.’ ‘.$years[year].’

‘);
echo(‘

    ‘);
    $q = mysql_query(“SELECT *, year(post_date) as year, month(post_date) as monthv
    FROM $tableposts WHERE year(post_date)=’$years[year]’
    AND month(post_date)=’$date[monthv]’
    AND post_status=’publish’
    ORDER BY post_date desc”) or die(mysql_error());
    while($post = mysql_fetch_array($q)) {
    if ($post[post_date_gmt] <= $now) { if ($catID != '') { // check to see if a category id was specified in the arguments // get the categories that are attached to the current post $cats = $wpdb->get_col(“SELECT category_id FROM $wpdb->post2cat WHERE post_id = $post[ID]”);
    $found=false;
    foreach ($cats as $cat) { // look to see if the specified category is attached to the current post
    if ($cat == $catID) $found=true;
    }
    if (!$found) echo(‘

  • ‘.$post[post_title].’
  • ‘);
    }
    else echo(‘

  • ‘.$post[post_title].’
  • ‘);
    }
    }
    echo (‘

‘);
}
}
}
}
}
?>