imajax-single,一款全站ajax的博客主题

近半年来,慢慢的制作一款能够适合博客使用的,能够方便阅读的,速度要快主题。灵感来自于wordpress的官方默认主题。

制作缘由

很喜欢wordpress的默认主题twenty-fifteen,但是不是全站ajax,曾经为twenty-fifteen增加过诸多功能,但是使用起来还是特别的不方便,因此就自己制作了一份主题了。

制作过程

断断续续的几个月,有时间就写一点代码,没时间就放着。由于博主现在主要搞后端接口了,所以在前端方面花的功夫就太少了,主题外观感觉看起来中规中矩,不过使用起来应该还是很贴心的。

(更多…)

TCP/IP协议中的backlog分析

TCP/IP协议卷一中是有说明设置backlog这个值的,这值是做什么的呢?

大家都知道TCP建立连接时是要进行三次握手连接的,但是否三次握手完成了,服务端就进行处理了(accept)呢,如果没有处理就变成什么情况,假如没有及时accept的话,后续客户端就连接不上或连接失败。这样就谈不上吞吐量了。想必大家也认为TCP不是那么设计的。

backlog其实是一个连接队列,以下是backlog队列大小公式。
backlog队列总和 = 未完成三次握手队列+已经完成三次握手队列 (更多…)

bash学习笔记(一):变量,函数,控制流程

这是我学习bash的一个笔记。记录一下,或许能够帮助那些踩到坑的同学

变量部分

变量定义

和其他类C语言一样,bash拥有变量,定义:

a="hello" #注意,等号两边不能有空格 比如 a = "hello"这是错误的,这是我踩到的第一个坑

变量使用

变量使用需要在定义的变量名之前加上$

echo $a #将会在屏幕上打印 hello

特殊变量后面再说,现在仅仅是最基础的,能够让自己写出一个完整的脚本就行。

(更多…)

websocket协议详解

近来项目中使用websocket,于是来研究一番。websocket传输协议有两个部分,握手和数据传输

握手

GET / HTTP/1.1
HOST: <IP>:<PORT> 
Sec-Websocket-Version: 13
Sec-Websocket-Key: <KEY>
Connection: keep-alive, Upgrade
Upgrade: websocket

之后服务端会返回类似下面的数据

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: <ACCEPT_KEY>
Sec-WebSocket-Version: 13
Server: swoole-websocket-server

校检连接

这里可以对accept key进行校检,确定服务器确实是websocket服务器,校检算法为

sha1(KEY+‘258EAFA5-E914-47DA-95CA-C5AB0DC85B11’),将得到的一串字符串用16进制表示,之后再进行base64编码。 (更多…)

记录一次编译安装php7的过程,以后当做参考

之前安装过一次php7,不过配置参数听过,这次再安装,就记录一下,后面就当做参考了,主要是配置里面东西有点多。

STEP 1

去php官网下载最新版本的php,目前是7.0.10,地址:http://php.net/downloads.php#v7.0.10,可以使用下面的命令,直接下载解压

$ wget http://am1.php.net/get/php-7.0.10.tar.gz/from/this/mirror
tar -xvf mirror

STEP 2

进入刚才解压的文件,应该是 php-7.0.10。安装之前需要解决一下依赖问题。 (更多…)

节点

没有儿子的节点称为叶子(leaf)

节点的深度

根到一个节点的唯一路径长,根的深度为0

节点的高

节点的高为从这个节点到叶子的最长路径,所有树叶的高都是0

节点定义

typedef struct TreeNode *PtrToNode;

struct TreeNode
{
    ElementType Element;
    PtrToNode FitstChild;
    PtrNode NextSibling;
}

(更多…)

分析评价是好评还是差评的算法

问题引入

一个有经验的网购者能够靠大脑思维能判断一个评价的是好评还是差评,但是一个网购新人却很难分辨的。如果让一个有经验的网购者说出他判断评价的过程,那是否就可以将这种思维用计算机模拟呢?是否也能够精确地判断这个评价到底是隐含着好的评价还是差的评价呢?

评价分类

好的评价

一个好的评价,必定是经过用户使用过后,真实的感受,而在当前网购中,商家往往为了追求好评率而采用现金红包来刺激评价,这样则大大的降低了评价的真实效果。那么有效的评价特征是什么呢? (更多…)

使用sublime+platuml高效画图

程序员难免要经常画流程图,状态图,时序图等。以前经常用 visio 画,经常为矩形画多大,摆放在哪等问题费脑筋。有时候修改文字后,为了较好的显示效果不得不再去修改图形。今天介绍的工具是如何使用 Sublime + PlantUML 的插件画流程图,状态图,时序图等。这是一种程序员看了就会爱上的画图方式:自然,高效。

什么是 PlantUML

PlantUML 是一个画图脚本语言,用它可以快速地画出:

  • 时序图
  • 流程图
  • 用例图
  • 状态图
  • 组件图

简单地讲,我们使用 visio 画图时需要一个一个图去画,但使用 PlantUML 只需要用文字表达出图的内容,然后就可以直接生成图片。看一个最简单的例子: (更多…)

murmur hash,一个更快的hash算法

在打算搭建memcache集群的时候,使用了crc3算法来对key进行hash,然而发现该算法性能比较低,于是寻找一个高性能,低碰撞的hash算,很高兴有前人已经为我们发明了这种算法——murmur。

MurmurHash算法:高运算性能,低碰撞率,由Austin Appleby创建于2008年,现已应用到Hadoop、libstdc++、nginx、libmemcached等开源系统。2011年 Appleby被Google雇佣,随后Google推出其变种的CityHash算法。

MurmurHash算法,自称超级快的hash算法,是FNV的4-5倍。官方数据如下:

OneAtATime – 354.163715 mb/sec
FNV – 443.668038 mb/sec
SuperFastHash – 985.335173 mb/sec
lookup3 – 988.080652 mb/sec
MurmurHash 1.0 – 1363.293480 mb/sec
MurmurHash 2.0 – 2056.885653 mb/sec

    //-----------------------------------------------------------------------------  
    // MurmurHash2, 64-bit versions, by Austin Appleby  
      
    // The same caveats as 32-bit MurmurHash2 apply here - beware of alignment   
    // and endian-ness issues if used across multiple platforms.  
      
    typedef unsigned long int uint64_t;  
      
    // 64-bit hash for 64-bit platforms  
    uint64_t MurmurHash64A ( const void * key, int len, unsigned int seed )  
    {  
            const uint64_t m = 0xc6a4a7935bd1e995;  
            const int r = 47;  
      
            uint64_t h = seed ^ (len * m);  
      
            const uint64_t * data = (const uint64_t *)key;  
            const uint64_t * end = data + (len/8);  
      
            while(data != end)  
            {  
                    uint64_t k = *data++;  
      
                    k *= m;   
                    k ^= k >> r;   
                    k *= m;   
      
                    h ^= k;  
                    h *= m;   
            }  
      
            const unsigned char * data2 = (const unsigned char*)data;  
      
            switch(len & 7)  
            {  
            case 7: h ^= uint64_t(data2[6]) << 48;  
            case 6: h ^= uint64_t(data2[5]) << 40;  
            case 5: h ^= uint64_t(data2[4]) << 32;  
            case 4: h ^= uint64_t(data2[3]) << 24;  
            case 3: h ^= uint64_t(data2[2]) << 16;  
            case 2: h ^= uint64_t(data2[1]) << 8;  
            case 1: h ^= uint64_t(data2[0]);  
                    h *= m;  
            };  
       
            h ^= h >> r;  
            h *= m;  
            h ^= h >> r;  
      
            return h;  
    }   
      
      
    // 64-bit hash for 32-bit platforms  
    uint64_t MurmurHash64B ( const void * key, int len, unsigned int seed )  
    {  
            const unsigned int m = 0x5bd1e995;  
            const int r = 24;  
      
            unsigned int h1 = seed ^ len;  
            unsigned int h2 = 0;  
      
            const unsigned int * data = (const unsigned int *)key;  
      
            while(len >= 8)  
            {  
                    unsigned int k1 = *data++;  
                    k1 *= m; k1 ^= k1 >> r; k1 *= m;  
                    h1 *= m; h1 ^= k1;  
                    len -= 4;  
      
                    unsigned int k2 = *data++;  
                    k2 *= m; k2 ^= k2 >> r; k2 *= m;  
                    h2 *= m; h2 ^= k2;  
                    len -= 4;  
            }  
      
            if(len >= 4)  
            {  
                    unsigned int k1 = *data++;  
                    k1 *= m; k1 ^= k1 >> r; k1 *= m;  
                    h1 *= m; h1 ^= k1;  
                    len -= 4;  
            }  
      
            switch(len)  
            {  
            case 3: h2 ^= ((unsigned char*)data)[2] << 16;  
            case 2: h2 ^= ((unsigned char*)data)[1] << 8;  
            case 1: h2 ^= ((unsigned char*)data)[0];  
                            h2 *= m;  
            };  
      
            h1 ^= h2 >> 18; h1 *= m;  
            h2 ^= h1 >> 22; h2 *= m;  
            h1 ^= h2 >> 17; h1 *= m;  
            h2 ^= h1 >> 19; h2 *= m;  
      
            uint64_t h = h1;  
      
            h = (h << 32) | h2;  
      
            return h;  
    }

一致性哈希的php实现

未来项目可能要上memcache集群,memcache集群的key分配完全在客户端完成,服务端不做任何处理,这里对key进行分配节点的最优方式就是使用一致性哈希。

记得以前用mysql进行分库分表的时候,通常会用一个求余作为哈希函数,这样一些id就能对应相应的表了。不过使用mysql的时候,我们不需要考虑这些节点失效问题,以及节点增加或者减少的问题(在此之前应该做好足够的计划和准备),但是对于缓存,通常就比较宽松了,允许节点失效问题,但是普通的hash分配在节点失效之后,大部分的缓存位置都改变了,这显然个灾难,这个时候就要考虑一致性hash了,在增加或者删除节点,只有小部分的key会受影响。 (更多…)