• 2012-07-29

    动态语言应该有多动态?

    Views: 25831 | 12 Comments

    一加一等于几, 这是个问题

    某些所谓的动态语言是名不副实的 - 我称之为伪动态语言. 这些伪动态语言之所以是伪的, 是因为它们只是在代码层面的变量是动态的, 而它们的类型系统并不是真正动态的, 一个简单的例子, 考虑字符串能否直接和整数进行拼接成为一个新的字符串.

    当然, 语言维护者用另一个名词"类型强度(type strength)"来表示这种行为, 然后把这种本质上不动态的行为称为"强类型(strong typing)", 把真正的动态称为"弱类型(weak typing)".

    但我认为, "动态语言"的概念应该重新定义, "动态"应该脱离字面的意义, 去探究真正本质的动态.

    Continue reading »

    Posted by ideawu at 2012-07-29 01:00:33
  • 2012-07-26

    流式数据的模型设计

    Views: 12747 | No Comments

    流式数据是指带有时间点参数的数值数据. 例如在某个网站的 PV 统计中, 有整个网站的 PV 统计, 也有分不同子域名的统计, 而这个统计数据可能每小时统计一次, 同时每天统计一次. 而在不同的子域名下, 又有不同的功能模块的统计, 如论坛子域名下的发贴 PV, 回复 PV, 等等.

    显然, 这类的数据还有至少一个维度, 表明这条数据的产生条件(或者说产生地点), 这样, 数据才有了实际意义. 维度是有序的, 子域名维度必须在网站维度之下, 因为要先有了网站, 子域名才有意义. 每一条数据的维度可以这样表示: /dim1=v1/dim2=v2/... 表示该条数据在 dim1 维度下的值是 v1, 在 dim2 维度下的值是 v2, ...

    数据还要有一个统计方法, 如pv, uv.

    Posted by ideawu at 2012-07-26 22:37:53
  • 2012-07-17

    Redis 导数据的 PHP 脚本

    Views: 19049 | 2 Comments

    Redis 本身没提供方便的导数据工具, 比如从某个 db 导数据到另一个 db, 只能自己写脚本了. redis copy.

    <?php
    
    $from = '127.0.0.1:6200/6';
    $to = '127.0.0.1:6200/8';
    
    $from_redis = redis_init($from);
    $to_redis = redis_init($to);
    
    
    $keys = $from_redis->keys('*');
    $count = 0;
    $total = count($keys);
    foreach($keys as $key){
        if(++$count % 100 == 1){
            echo "$count/$total\n";
        }
        $type = $from_redis->type($key);
        switch($type){
            case Redis::REDIS_STRING:
                $val = $from_redis->get($key);
                $to_redis->set($key, $val);
                break;
            case Redis::REDIS_LIST:
                $list = $from_redis->lRange($key, 0, -1);
                foreach($list as $val){
                    $to_redis->rPush($key, $val);
                }
                break;
            case Redis::REDIS_HASH:
                $hash = $from_redis->hGetAll($key);
                $to_redis->hMSet($key, $hash);
                break;
            case Redis::REDIS_ZSET:
                $zset = $from_redis->zRange($key, 0, -1, true);
                foreach($zset as $val=>$score){
                    $to_redis->zAdd($key, $score, $val);
                }
                break;
        }
    }
    
    
    function redis_init($conf){
        $redis = new Redis();
        preg_match('/^([^:]+)(:[0-9]+)?\\/(.+)?/', $conf, $ms);
        $host = $ms[1];
        $port = trim($ms[2], ':');
        $db = $ms[3];
        $redis->connect($host, $port, 1000);
        $redis->select($db);
        return $redis;
    }
    
    Posted by ideawu at 2012-07-17 12:10:52 Tags:
  • 2012-07-15

    用C语法来写Python代码

    Views: 27367 | 11 Comments

    我认为 Python 不错, 因为作为脚本语言和动态语言, 它真的无可替代. 能作为通用用途的脚本语言本来就少 - PHP 主要用作 web 开发, gc 不成熟; Perl 算冷门, Ruby 等的语法就更加不堪入目了; Java/C# 需要编译且静态类型; JavaScript 主要在浏览器宿主中. 另外, Python 非常流行, 库很全.

    但是, 我决不认为 Python 的语法很优雅. 用缩进来表示区块的方法, 只对于少量代码才是优雅的, 当代码区块超过10行或者代码文件超过100行时, 缩进常常让你眼睛模糊, 这时就一点也不优雅了. 而且, 缺少了花括号, Python 的匿名函数和 lambda 表达式就是一项残废的鸡肋功能, 我怀疑是否真有人使用来虐待自己.

    前面也讲过, Python 非原始类型的函数默认参数其实相当于函数的静态变量, 这个语法负作用对初学者和仅仅把 Python 当工具的开发者是一个坑.

    另外, Python 里类函数的声明中的"self"也是毫无意义, 何不隐含"this", 并且强制要求使用类成员时必须带"this."呢? 而且, 调用父类方法的方式也是让人无可奈何.

    如果有这样的一种脚本语言(动态语言), 它继承了C的语法, 吸取了 Java 和 JavaScript 对 C 的改进部分, 同时使用 Python 引擎, 那将会是一种非常舒服的语言.

    可以使用一个编译器, 把这样语法的的代码编译成 Python 代码, 然后用 Python 执行器来执行, 这样很快就能实现. 我会这么干的. 项目地址: https://code.google.com/p/cpy-scripting-language/

    Posted by ideawu at 2012-07-15 14:29:22
  • 2012-05-25

    从开源社区学来的知识应该更加开放

    Views: 20529 | 3 Comments

    对于知识的创造者, 应该保有从其所创知识获得收益的权利, 比如小说的作者应该获得版税.

    而对于网络博客, 特别是关于IT技术的博客, 我认为作者应该更开放一些, 不要太小气. 本来网络上的东西就应该开放一些.

    我看到据称是世界第三的Nginx贡献的某国人的博客, 上面赫然写着:"如需转载,请留言或发邮件至...问询", 必须经得同意之后才能转载.

    "有性格", "写得不错", ... 你可以这么说, 没错! 他可以不允许别人保留出处转载他的文章, 但我同样可以鄙视这种在知识自封的人.

    也许你写得不错, 也许你真正做出了贡献. 但是, 作为一个接触那么多开源软件, 而且是在开源软件之上做的学习, 竟然对自己知识如此封闭, 真不是一个让我认同的人.

    如果是一个开放的人, 自己的博客文章被人正常正确地转载, 应该感到开心. 补充一点, 有这种行为的技术人员, 不一定是本质上的小气, 而是因为把知识当作奇技淫巧, 自认清高的不好风气.

    Continue reading »

    Posted by ideawu at 2012-05-25 10:37:16
  • 2012-05-25

    即时流式数据 MapReduce

    Views: 11647 | No Comments

    传统的 MapReduce 如 Hadoop, 是以任务的形式进行的 -- 获取一批数据, 提交给系统, 然后获取结果. 但是, 有一些统计的需求是即时的, 统计任务需要持续的运行, 一旦数据生成, 便立即发给统计任务处理, 生成的结果"推"给接收者.

    以一个网站用户在线时长统计的需求为例子, 那么系统就有这几个部分:

    数据接收

    接收 Web Server(如 Apache/Nginx) 的 log, 例如使用 syslog.

    Mapper(格式转换)

    依次输入以行为单位的原始的 Apache log, 输出一条或者多条结构化的数据. 这个输出将出 Reducer 进行下一步处理.

    Reducer(统计器)

    不同的精度用不同的统计器, 因为统计结果必须在要求的精度时间内进行输出. 例如当精度要求是小时, 用户连续在线1个小时, 并且横跨在2个自然小时上, 那么, 统计结果应该是2条. 如果精度要求是天, 那么类似, 跨越自然天的数据应该被分割.

    当 Reducer 的精度时间到达之后(如一个小时过完), Reducer 应该复位.

    传统 Reducer 的输入是来自 Mapper, 但 Reducer 的输入来源应该包括其它的 Reducer. 例如, 按小时统计的 Reducer 的输出可以作为按天统计的 Reducer 的输入.

    结果分发器

    结果会以不同的形式发送出去, 如写成文件, 发邮件, 推送到其它系统...

    结果的结构

    有一种简单的数据库存储结构(先不考虑分表分库), 表的结构为:

    time, timespan, key, val
    UNIQUE(time, timespan, key)
    

    用户在线时长的数据这样存:

    2012-05-25 09:12:20, 小时, ip1, 100s // ip1在线了100s, 从09:12:20开始
    2012-05-25 12:24:10, 小时, ip1, 200s // ip1在线了100s, 从09:12:20开始
    2012-05-25 09:12:20, 天, ip1, 300s // ip1 2012-05-25 在线了300s, 但不是连续在线时间
    

    系统

    根据上面的思想, 可以设计出一个即时流式数据的 MapReduce 系统, 也可以做一个代码框架. 但系统和框架的区别是, 系统包含了运行环境.

    上面不同部分之间的通信会形成一种广义上的"队列", 所以需要进行队列管理.

    Posted by ideawu at 10:13:27
|<<<34567891011>>>| 7/13 Pages, 76 Results.