1. 《精通Python设计模式》译者序

    在我读大学那几年,设计模式可谓火极一时,各大公司校招面试也几乎都会考设计模式,反观现在,则似乎很少有人聊设计模式的话题。是因为设计模式过时了吗?还是只是一个错误的概念?从个人这几年的开发经验来看,答案是否定的,设计模式并未过时,更不是一个错误的概念。从曾经的“红极一时”到如今的“门可罗雀”,只是说明软件开发行业以更加客观理性的态度来看待设计模式。软件开发领域的技术概念也似乎总是遵循这样的流行度变迁,最终一次又一次地证明不存在“银弹”。

    正确看待设计模式的前提是明白什么是设计模式。正如本书一开始就强调的:“设计模式的本质是在已有的方案之上发现更好的方案(而不是全新发明)”,这是一种务实的态度,设计模式并非是一种高大上或者神秘的东西,而是一些常见的软件工程设计问题的最佳实践方案。

    那么应该如何学习设计模式?个人认为软件开发技术的学习都应该以实践为前提,只有理解实践过程中遇到的种种问题,才能明白那些技术的本质和目的是什么,每种新技术都是因某个/某些问题而出现的,软件开发高手一般都反对新手一开始就一股脑地学习设计模式。有些新手学了点设计模式的理论后,甚至在软件开发过程中生搬硬套,结果是适得其反。因此,软件开发人员应该在积累了一定的开发经验,再系统地学习设计模式,效果往往也能事半功倍。

    现在有些积累一定开发经验的软件开发人员,在谈起设计模式时,一脸鄙夷。我想这也不是一种客观务实的态度。软件开发不是简单的累积代码,在实现业务功能的同时应该仔细考虑如何控制软件的复杂度。软件的复杂度分为两个层面:业务逻辑复杂度和代码实现复杂度。对同一个业务系统,不同的软件开发人员会有不同的实现 ...

    Tagged as : 翻译 书籍
  2. 应用MySQL InnoDB全文索引

    问题

    之前涉及的一项工作要求对某些数据做全文索引,并以API向其他内部系统提供搜索查询服务。

    由于需要建全文索引的数据量并不大,且已有的数据都以InnoDB引擎存储,简单起见,我们选择MySQL InnoDB引擎的全文索引特性来实现。MySQL从版本5.6开始支持InnoDB引擎的全文索引,不过“从5.7.6版本开始才提供一种内建的全文索引ngram parser,支持CJK字符集(中文、日文、韩文,CJK有个共同点就是单词不像英语习惯那样根据空格进行分解的,因此传统的内建分词方式无法准确的对类似中文进行分词)”,我们使用的MySQL版本为5.6.28,并且需要建全文索引的数据部分是中文,所以这是个问题。

    方案

    我们先把这项工作按“分治”的思想拆分成几个小问题:

    1. 由于版本5.6.28的MySQL不支持中文的全文索引,那么可以对需要建全文索引的数据进行预处理 - 分词,并以空格为间隔将分词结果拼接成一个字符串。
    2. 但经过第1步仍是不够的 - MySQL的系统变量ft_min_word_lenft_max_word_len分别规定了全文检索被编入索引单词的最小长度和最大长度,默认的最小值为4个字符,默认的最大值取决于使用的MySQL版本。为了不改变这个默认值同时也是兼考虑这个值对于英文的意义,则需要通过编码(urlencodebase64汉字转拼音等)将中文词变长 ...
    Tagged as : MySQL 笔记
  3. 关于并发的一个小技巧

    前段时间在参与实现一个新业务系统的Demo。该系统集成了多个已有系统的数据,涉及的数据量较大,但由于人力少,时间短,没法专门做一个数据处理子系统,所以只能写了很多数据处理的脚本。

    为了复用一些代码,这些数据处理脚本和业务系统一样都是使用PHP实现。在某些数据上报API写入的数据较快较多时,脚本处理不过来(特别在脚本涉及一些网络请求时),只能搞起并发处理 - 在我们的情况下,最简单的并发方式就是多运行几个脚本实例。

    但一切没那么简单:脚本从数据库中取出未经处理的多行数据,逐行处理数据,并将处理后的数据更新到原来的数据行中,运行多个脚本实例时,为了避免更新冲突,只好加事务,但加事务后就会频繁发生事务回滚,数据处理速度还是上不去。

    那么该怎么办呢?

    参考哈希的思路,我对脚本做了一点调整,下面举例说明:

    • 假设对同一脚本运行5个实例,为每个实例进程分配一个ID,依次为:0、1、2、3、4
    • 对脚本实例获取数据的SQL,增加选择条件:MOD(id, 5)=SID(SID为当前脚本实例的ID) - 即使用数据行的id对实例数取模,如果结果等于实例的ID,则取出来 ...
    Tagged as : 笔记 SQL
  4. 关于API访问频率限制的一个问题

    工作中涉及一些对外开放的无需特殊权限的API,用户会因为某些需求而通过程序来频繁访问这些API,导致系统的负载陡增,可能影响系统其它功能的正常使用。虽然做了一些优化让这种API尽可能地轻量,但仍然不够,因此需要进行访问频率的限制。

    由于这样的API并不多,所以我们并没有在Nginx这样的反向代理接入层中实现频率限制,而是API自己去实现,而且实现方案比较粗糙 - 基于Memcached的缓存自动过期特性。

    方案的PHP示例实现如下所示:

    // 每个IP一分钟10次
    $limit = 10;
    
    $cache = new Memcached();
    $cache->addServer('127.0.0.1', 11211);
    
    $key = __FUNCTION__.$_SERVER['REMOTE_ADDR'];
    $requestNum = $cache->get($key);
    
    if ($requestNum !== FALSE && $requestNum > 10) {
        echo json_encode(array(
            'code' => 403,
            'message' => '请求太频繁,请一分钟后再试',
        ));
        return;
    }
    
    $cache->add ...
    Tagged as : Nginx 笔记 工作
  5. 为什么我要送掉纸质书?

    小时候,不知为何喜欢读书,而又没钱买,所以在家都是翻两个哥哥的课本 - 语文、历史、地理等,都翻个遍。更有甚者,竟然还从邻居家偷偷地拿了本书回来,这应该算是我品行上的污点,这事在此说起,也是第一次。

    因为书少,所以至今还记得爸爸第一次送给我的书 - 《一个变两个》 - 连书里的情节都没忘过。

    读初中时,因为读书,还和好朋友闹过一点不愉快:朋友买了一些好书,我想借来看,他不肯,我就每天比大家早起一些,偷偷从他抽屉里拿来看几页,在他到教室之前再放回去,后来“事发”,。。。当然这一切都已过去,朋友还是朋友。

    高中后,开始有一些零花钱/饭钱,从其中挤出部分钱来买书成了我的一个习惯,书也由此越来越多。

    其实我根本看不了那么多书,最终累积了大量的书没认真读过。有时觉得可惜了,就会为读书而读书,精神为读书所累。

    这些年,几次搬家 - 从本科学校到研究生学校、读研期间换宿舍、毕业工作 - 每次最多最重的都是书,“书生搬家 - 尽是书!”。

    工作后租的房子没那么宽敞,导致到处塞的都是书 ...

    Tagged as : 笔记 生活 感悟
  6. 如何杀死defunct进程(译)

    原文:How to kill defunct process

    译者:youngsterxyf

    defunct进程是指出错损坏的进程,父子进程之间不会再通信。有时,它们会演变成“僵尸进程”,存留在你的系统中,直到系统重启。可以尝试 “kill -9” 命令来清除,但多数时候不管用。

    为了杀死这些defunct进程,你有两个选择:

    • 重启你的计算机
    • 继续往下读...

    我们先看看系统中是否存在defunct进程:

    $ ps -A | grep defunct
    

    假设得到的输出如下所示:

    8328 ? 00:00:00 mono <defunct>
    8522 ? 00:00:01 mono <defunct>
    13132 ? 00:00:00 mono <defunct>
    25822 ? 00 ...
    Tagged as : Linux
  7. Base64编码原理与应用

    2015年,我们在青云平台上实现了“百度云观测”应用。青云应用本质上是一个iframe,在向iframe服务方发送的请求中会携带一些数据,青云平台会使用Base64 URL对这些数据进行编码,其提供的编码解码算法示例如下:

    // php版本
    function base64_URL_encode($data) {
      return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
    }
    function base64_URL_decode($data) {
      return base64_decode(str_pad(strtr($data, '-_', '+/'), 
                                strlen($data) % 4, '=', STR_PAD_RIGHT));
    }
    

    可以看出,Base64 URL 是标准Base64编码的一个变种,分别用 -_ 替换标准Base64编码结果中的 +/ ,并删除结果最后的 =

    在实现 “百度云观测” 青云应用时,我在想:

    • 为什么要使用Base64编码?
    • Base64编码算法是什么样的?

    本文是围绕这两个问题思考和实践的结果。

    我认为 ...

    Tagged as : 笔记 编码
  8. 基于Github的pull request流程做开源贡献

    最近给 beego 提了几个 pull request (简称PR),都已被接受。在使用pull request的过程中,遇到了一点小问题,才知以前并非真的理解这个流程,故在此做点记录整理。

    我以 beego 为例,将pull request的整体使用流程绘图如下:

    fork-pull-request

    beego代码库有两个长期分支 masterdevelopmaster为稳定分支,develop为开发分支,所有PR都要求提交到 develop 分支。

    1. 先将 astaxie/beego 代码库 fork 一份到自己的名下(如我的 youngsterxyf/beego)。
    2. youngsterxyf/beego clone 到本地机器上做开发。因为PR要提到 astaxie/beego 的 develop 分支,所以最好对应地在你fork的代码库的 develop ...
    Tagged as : github 笔记 git 开源

Page 1 / 16