<![CDATA[贵知么]]>http://www.guizhi.me/Ghost 0.6Wed, 19 Jan 2022 04:54:33 GMT60<![CDATA[贵知么]]>

简介:个人的表现好坏,也受他人力量的影响。而正确的人际天博SPORTS引领我们适应环境,带领我们走向成功。天博SPORTS有多种层次,而第四次天博SPORTS则是应该努力追求的目标。达成第四层天博SPORTS需要经过不懈的努力,既包括个人的自律,自由、责任和爱,还要借助他人的力量并内化这种力量。

他人的力量 如何寻求受益一生的人际天博SPORTS》/[美]亨利·克劳德/机械工业出版社

读书笔记

  • 生活和事业中你的能力表现有多好,不仅仅取决于你做了什么和怎么做,以及你的技能和本领如何,还取决于谁同你一起做或者谁对你做了什么,这是无可否认的事实。每个人都有需要别人的时候,及时表明自己的需求,才能借助他人的力量实现真正的连接天博SPORTS。

  • 天博SPORTS的四个层次:

  • 1.孤立状态,没有连接天博SPORTS
    2.坏的连接天博SPORTS:天博SPORTS让人感觉不舒服或者“不够好”
    3.看似美好的连接天博SPORTS:感觉挺好,但很多行为掩盖了真正的问题,虚假的恭维也会迷惑自己
    4.真正的连接天博SPORTS:保持真实——不复制,不虚伪或模仿

  • 远离消耗型天博SPORTS,好的天博SPORTS带来滋养

  • 自律带来自由

  • 你如何感知自身对生活的控制,在某种程度上,

    ]]>
    http://www.guizhi.me/ta-ren-de-li-liang/4fb0a0d2-bfad-426c-a67a-c3652422a1cfSun, 15 Mar 2020 14:02:31 GMT

    简介:个人的表现好坏,也受他人力量的影响。而正确的人际天博SPORTS引领我们适应环境,带领我们走向成功。天博SPORTS有多种层次,而第四次天博SPORTS则是应该努力追求的目标。达成第四层天博SPORTS需要经过不懈的努力,既包括个人的自律,自由、责任和爱,还要借助他人的力量并内化这种力量。

    他人的力量 如何寻求受益一生的人际天博SPORTS》/[美]亨利·克劳德/机械工业出版社

    读书笔记

  • 生活和事业中你的能力表现有多好,不仅仅取决于你做了什么和怎么做,以及你的技能和本领如何,还取决于谁同你一起做或者谁对你做了什么,这是无可否认的事实。每个人都有需要别人的时候,及时表明自己的需求,才能借助他人的力量实现真正的连接天博SPORTS。

  • 天博SPORTS的四个层次:

  • 1.孤立状态,没有连接天博SPORTS
    2.坏的连接天博SPORTS:天博SPORTS让人感觉不舒服或者“不够好”
    3.看似美好的连接天博SPORTS:感觉挺好,但很多行为掩盖了真正的问题,虚假的恭维也会迷惑自己
    4.真正的连接天博SPORTS:保持真实——不复制,不虚伪或模仿

  • 远离消耗型天博SPORTS,好的天博SPORTS带来滋养

  • 自律带来自由

  • 你如何感知自身对生活的控制,在某种程度上,取决于你生活中最重要的人如何支持那种能力,以及如何同时让你对此负有责任。成功者不仅仅认为自己能够控制自己和自身的选择,而且每天都在练习这种控制方式。


    自我控制是通过其他人提供的几种功能而构建起来的:支持、成长、尊重、责任。

  • 自由、责任和爱

  • 让被授权者负起应有的责任,而不加干涉或者剥夺其权力,这两者之间有个平衡。这是领导力所具有的非常重要的杠杆作用——要求人们对我们授权其主管的事情做主,然后让他们对结果负起责任。


    好的人际天博SPORTS取决于坦诚地交流对双方的期望,所以各方都理解和知道对方的期望。


    第四层次要求在实现期望之前,澄清你对彼此的期望,而且还要求在必要的间隔之下,随时保持交流畅通。清晰和一致,检测和调整,真正地促进能力表现的增长。


    第四层次要求具备全部三项:关心、坦诚和结果——对别人足够的关心,说话的时候不伤害别人,对别人说话的直接坦诚,以及关注行为改变和更好的结果。


    自由=责任=爱

  • 优质天博SPORTS中的每个人都在进步

  • 健康的文化既要为人们营造安全感,也要保证人们不会沉湎于享乐。健康的文化接受人们的自然状态,但也会轻推人们,有时候甚至迫使人们变得更好。

  • 阶段性成长

  • 打破衰退循环的两个基本要素:能力和信息的新源头。


    第四层次的人们不仅仅帮助我们相信我们可以完成目标,而且他们也帮助我们看清,实现目标真正需要完成大量的工作,需要应付大量的麻烦。他们使困难变得正常。他们会在背后鼓励我们,也会和我们交流,共度困难时期。


    第四层次人际天博SPORTS的过程和动力,包含的关键要素:支持天博SPORTS;建立自我控制的天博SPORTS;建立主人翁意识和责任感的天博SPORTS;使学习和失败变得安全的天博SPORTS;追求远大理想和目标的天博SPORTS;支出并强化小步骤、渐进步骤的天博SPORTS

  • 内化他人的力量

  • 爱并非从自己开始。爱是始于接受爱、内化爱,然后散发给其他人——向前传递。

  • 人际天博SPORTS的“百慕大三角”

  • 三角天博SPORTS(A-B-C)无益于解决问题,还可能形成新的矛盾。正确的办法应该是尽量找到直接沟通的方法,如果有侧面沟通的必要,也应当是为了配合正面沟通。沟通中要积极接收反馈。我们不仅要成为直接反馈和交流的发起者,我们还要成为好的接收者。

  • 信任的五大要素
  • 理解,意图或动机,能力,性格,“业绩”记录

    ]]>
    <![CDATA[贵知么]]>一、单机数据库及持久化

    1.服务器中的数据库

    struct redisServer{  
        //一个数组,保存所有数据库
        redisDb *db;
        //数据库数量
        int dbnum;//默认16
        //AOF缓冲区
        sds aof_buf;
        //一个链表,保存所有客户端状态
        list *clients;
        //...
    };
    struct redisDb {  
        //数据库键空间,保存所有键值对
        dict *dict;
        //过期字典,保存键的过期时间
        dict *expires;
        //...
    };
    
    struct redisClient {  
        //客户端当前使用的一个数据库元素
        redisDb *db;
        //套接字描述符
        int fd;
        //...
    };
    
  • 键可以设置过期时间(EXPIRE,PEXPIRE,EXPIREAT,PEXPIREAT),前三个底层都是调用了PEXPIREAT
  • PERSIST可以移除一个键的过期时间
  • 过期键存在定时删除(到达指定时间删除)、惰性删除(
  • ]]>
    http://www.guizhi.me/redisxue-xi-bi-ji-shu-ju-jie-gou/7d4b6e46-cbdb-4a64-98c0-5d887a704e95Sat, 03 Aug 2019 17:01:14 GMT一、单机数据库及持久化

    1.服务器中的数据库

    struct redisServer{  
        //一个数组,保存所有数据库
        redisDb *db;
        //数据库数量
        int dbnum;//默认16
        //AOF缓冲区
        sds aof_buf;
        //一个链表,保存所有客户端状态
        list *clients;
        //...
    };
    struct redisDb {  
        //数据库键空间,保存所有键值对
        dict *dict;
        //过期字典,保存键的过期时间
        dict *expires;
        //...
    };
    
    struct redisClient {  
        //客户端当前使用的一个数据库元素
        redisDb *db;
        //套接字描述符
        int fd;
        //...
    };
    
  • 键可以设置过期时间(EXPIRE,PEXPIRE,EXPIREAT,PEXPIREAT),前三个底层都是调用了PEXPIREAT
  • PERSIST可以移除一个键的过期时间
  • 过期键存在定时删除(到达指定时间删除)、惰性删除(每次取键值时判断过期并删除)、定期删除(每隔固定时间删除),Redis使用惰性删除和定期删除结合的策略
  • 执行SAVE或者BGSAVE产生的RDB文件不包含过期键
  • 执行BGREWRITEAOF重写的AOF文件不含过期键
  • 当一个过期键被删除时,服务器会追加一条DEL命令到AOF文件末尾
  • 从库不会主动删除过期键,只会等主节点发送DEL命令后再处理
  • 2.RDB持久化
    数据库会持久化到RDB文件中,以压缩后的二进制格式保存

  • SAVE命令会阻塞Redis服务进程,BGSAVE派生出子进程保存数据
  • Redis服务器启动时,会检查RDB文件并决定是否从中载入数据
  • 如果开启了AOF持久化,优先使用AOF文件还原数据库状态
  • 通过配置不同的自动保存策略,Redis服务可以在满足不同条件下自动进行BGSAVE操作
  • 3.AOF持久化(Append Only File)
    通过保存Redis服务器所执行的写命令来记录数据库状态

  • 追加:当AOF持久化功能开启时,相关写命令会以协议的格式追加到服务器状态的aof_buf缓冲区末尾
  • 写入:写入策略有appendfsync选项配置,always-同步写入AOF文件,everysec-每个事件中都写入缓冲区,但每秒同步一次AOF文件,no-只写入到缓冲区,何时同步AOF由系统决定。重点在于何时调用fsync强制把缓冲区内容写入到AOF文件。always是每次都调;everysec是每秒调一次;no是佛系调用,由操作系统的缓存策略决定何时写入到文件中
  • AOF重写:为了避免AOF文件体积过大,采用新旧两个AOF文件来保存数据库状态,但是新文件不包含冗余指令。具体实现原理就是根据服务器当前状态,遍历数据后把数据当前的状态用最小指令写入新的AOF文件。重写期间,可能会对列表、哈希表、集合、有序集合根据配置的最大单次重写数量分批实现命令
  • BGREWRITEAOF会以后台方式执行AOF重写,在此期间Redis服务器通过维护AOF重写缓冲区保证最终数据一致。
  • 一个AOF文件后台重写过程的举例

    二、多机数据库实现

    1.复制(master-slave)

  • 同步:客户端向从服务器发送SLAVEOF命令要求复制主服务器时,先进行同步(sync)操作
  • 同步的过程:
  • 命令传播:主服务器的数据更新时,需要发送命令给从服务器更新数据
  • Redis从2.8版本开始使用PSYNC代替SYNC命令实现同步操作,避免在断线重连等场景下因为SYNC操作带来的额外数据传递和资源开销
  • PSYNC的完整重同步:跟SYNC基本一样
  • PSYNC的部分重同步:断线重连后只传递断线期间发生的数据更新
  • 部分重同步,依赖复制偏移量、复制积压缓冲区和服务器运行ID三个部分实现
  • 主从服务器都维护了自己的复制偏移量(offset),用于在部分重同步时比对需要重传的数据。每次传递N字节的数据给从服务器时,主从对应的偏移量都需要加N
  • 复制积压缓冲区维护了一段时间内主服务器的更新操作(先进先出的FIFO队列,默认1MB),包含每个字节对应的复制偏移量
  • 部分重传时,先判断需要重传的offset是否在复制积压缓冲区,如果有则从缓冲区读取数据进行更新;如果对应offset的数据已经被缓冲区移除,则进行完整重同步操作
  • 在具体运维环境中,需要评估自己业务量所需的复制积压缓冲区的内存大小,可以参考2×每秒写入字节数的量来设置
  • 服务器的运行ID,断线重连时用服务器的运行ID判断是否是之前复制的主服务器,如果是则执行部分重同步操作的策略,否则进行完整重同步
  • 2.哨兵模式(Sentinel)
    由一个或多个哨兵(Sentinel)实例组成的哨兵系统监视任意多个主服务器及属下的所有从服务器。当所监视的主服务器下线时,自动从对应主服务器的从服务器中选举某个从服务器并提升为主服务器处理后续命令请求

  • Sentinel模式下启动,会加载对应的专用代码和指令
  • 默认情况下,Sentinel每隔一秒向所有创建命令链接的实例发送PING 命令,并通过返回的结果判断实例是否在线
  • 如果一个主服务器实例在down-after-milliseconds时间内,连续向Sentinel返回无效回复,则Sentinel会修改对应实例的状态为主观下线
  • 当其他Sentinel也返回认为该实例处于主观下线或者客观下线的结果时,根据结果数量断定实例是否客观下线,如果确定为客观下线,则对主服务器进行故障转移
  • 多个Sentinel需要进行过半选举选择执行故障转移的领头Sentinel,原则是最先请求选举的获胜
  • 领头的Sentinel根据特定原则(状态正常、最近响应、最小ID依次筛选)选择某个从服务器为主服务器,并将其他从服务器的复制目标设置为新的主服务器。如果此后原主服务器重新上线,则自动成为新的主服务器的从服务器
  • 3.集群(cluster)模式
    通过分片进行数据共享,可以通过槽指派重新分片,所有数据都保存在槽中(总共16384个槽)

  • 多个节点最初都相互独立,只有通过发送CLUSTER MEET 进行握手后才会加入一个集群中
  • 当所有16384个槽都被节点处理时,集群才会上线,否则就是下线状态
  • //节点结构
    typedef struct clusterNode {  
        //...
        unsigned char slots[16384/8];
        int numslots;
        //...
    } clusterNode;
    
    //集群状态
    typedef struct clusterState {  
        //...
        clusterNode *slots[16384] //每个数组项指向该槽所处理的clusterNode节点的指针
        //...
    } clusterState;
    
  • 每个节点记录了节点需要处理的槽信息。slots属性是个16384位的二进制位,数值为1的索引位对应的槽被当前节点处理,numslots属性记录当前节点处理的槽数
  • 不同节点之间相互传递自己处理的槽信息,并且保存接收到的其他节点处理的槽信息到自己的slots属性中,每个节点都知道某个槽应该由哪个节点处理
  • 节点收到客户端的请求时,计算相应键所在的槽,判断是否由自己处理,如果不是则转发请求到相应的节点处理
  • 节点都使用0号数据库
  • 节点可以通过重新分片操作对槽进行节点的指派,在此期间被迁移的槽如果没找到新请求需要处理的键,需要返回ASK错误并把请求引导向目标节点重新处理
  • ASKING命令只被接下来的请求处理一次并移除
  • 每个节点都会维护一系列下线报告,如果根据各节点的反馈判断某个节点下线后,将该下线的节点标记为已下线(FAIL)
  • 主节点下线后,该节点所属的从节点也按照选举算法选举新的主节点并进行故障转移
  • 上一篇Redis学习笔记——数据结构

    ]]>
    <![CDATA[贵知么]]>通过阅读《Redis设计与实现》黄健宏(机械工业出版社 ISBN9787111464747)一书,对Redis的设计有了更深刻的认识,在此整理下关键的知识点。

    一、基本数据结构

    1.简单动态字符串(SDS:simple dynamic string)

    //数据结构
    struct sdshdr {  
        //sds保存的字符串长度
        int len;
        //记录buf数组中未使用字节的数量:重要作用就是冗余部分字节,避免扩容时频繁申请内存带来的开销
        int free;
        //字节数组,保存真正的字符串
        char buf[];
    }
    
  • SDS遵循C字符串以空字符结尾的惯例,保存空字符的最后1字节的空间不计入SDS的len属性
  • 用len属性保存字符串长度,常数复杂度
  • 杜绝C中的缓冲区溢出的问题(申请的空间不够,导致写操作溢出到未分配的空间)
  • 空间预分配。对SDS进行修改时,会先判断free的空间是否够用,如果不够,对SDS进行扩容,扩容时额外分配的free空间数量遵循以下原则:如果修改后的len小于1MB,则额外分配len大小的free空间;如果修改后的len大于等于1MB,则额外分配1MB的free空间
  • 惰性空间释放。当需要缩短SDS保存的字符串时,
  • ]]>
    http://www.guizhi.me/redisxue-xi-bi-ji-2/04ca805a-b9bf-4c75-a11c-68b14a5eea57Fri, 02 Aug 2019 17:17:14 GMT通过阅读《Redis设计与实现》黄健宏(机械工业出版社 ISBN9787111464747)一书,对Redis的设计有了更深刻的认识,在此整理下关键的知识点。

    一、基本数据结构

    1.简单动态字符串(SDS:simple dynamic string)

    //数据结构
    struct sdshdr {  
        //sds保存的字符串长度
        int len;
        //记录buf数组中未使用字节的数量:重要作用就是冗余部分字节,避免扩容时频繁申请内存带来的开销
        int free;
        //字节数组,保存真正的字符串
        char buf[];
    }
    
  • SDS遵循C字符串以空字符结尾的惯例,保存空字符的最后1字节的空间不计入SDS的len属性
  • 用len属性保存字符串长度,常数复杂度
  • 杜绝C中的缓冲区溢出的问题(申请的空间不够,导致写操作溢出到未分配的空间)
  • 空间预分配。对SDS进行修改时,会先判断free的空间是否够用,如果不够,对SDS进行扩容,扩容时额外分配的free空间数量遵循以下原则:如果修改后的len小于1MB,则额外分配len大小的free空间;如果修改后的len大于等于1MB,则额外分配1MB的free空间
  • 惰性空间释放。当需要缩短SDS保存的字符串时,不会立即回收多余的字节,而是冗余在free属性中,以备将来使用
  • 二进制安全。使用了len属性,确保读取字符串时以长度为边界,而非以C语言的空字符'\0'为边界,这使得SDS能保存二进制数据(如图片、音视频等二进制数据)
  • 使用C中的空字符结尾,便于兼容部分C字符串函数
  • 2.Redis的链表实现

    //节点:双向链表
    typedef struct listNode {  
        //前置节点
        struct listNode * prev;
        //后置节点
        struct listNode * next;
        //节点的值
        void * value;
    }listNode;
    
    //list结构:记录头、尾指针,以及长度计数器len,便于操作链表
    typedef struct list {  
        //表头节点
        listNode * head;
        //表尾节点
        listNode * tail;
        //链表节点数量
        unsigned long len;
        //节点值复制函数
        void *(*dup)(void *ptr); //使用函数指针便于扩展,不同的业务指定自己的实现
        //节点值释放函数
        void (*free)(void *ptr);
        //节点值对比函数
        void (*match)(void *ptr, void *key);
    } list;
    
  • 双端:带有prev和next指针,获取某个节点的前后节点复杂度都是O(1)
  • 无环:表头的prev和表尾的next指针都指向NULL,对链表的访问以NULL为终点
  • 带表头和表尾指针:通过list结构的head指针和tail指针,快速获取表头节点和表尾节点,O(1)
  • 带链表长度计算器:list结构的len属性记录了链表节点数,O(1)
  • 多态:listNode中使用void * 指针保存节点值,便于保存不同类型的值
  • 3.Redis的字典实现
    Redis的字典使用哈希表作为底层实现,一个哈希表里面可以有多个哈希表节点,而每个哈希表节点就保存了字典中的一个键值对

    //哈希表结构
    typedef struct dictht {  
        //哈希表数组
        dictEntry **table;
        //哈希表大小
        unsigned long size;
        //哈希表大小掩码,用于计算索引值,总是等于size-1。对数据的哈希值和sizemask作运算,确定数据应该存放在table的哪个索引上
        unsigned long sizemask;
        //该哈希表已有节点的数量
        unsigned long used;
    } dictht;
    
    //哈希表节点
    typedef struct dictEntry {  
        //键
        void *key;
        //值
        union{
            void *val;
            uint64_tu64;
            int64_ts64;
        } v;
        //指向下个哈希表节点,形成链表,解决哈希冲突问题
        struct dictEntry *next;
    } dictEntry;
    

    //dict结构
    typedef struct dict {  
        //类型特定函数
        dictType *type;
        //私有数据
        void *privdata;
        //哈希表
        dictht ht[2];//包含2项的数组,每个都是哈希表。字典使用ht[0],而ht[1]只在rehash的时候使用
        //rehash索引,不在rehash状态时为-1
        int rehashindex;
    } dict;
    
    typedef struct dictType {  
        //计算哈希值的函数
        unsigned int (*hashFunction)(const void *key);
        //复制键的函数
        void *(*keyDup)(void *privdata, const void *key);
        //复制值的函数
        void *(*valDup)(void *privdata, const void *obj);
        //对比键的函数
        void (*keyCompare)(void *privdata, const void *key1, const void *key2);
        //销毁键的函数
        void (*keyDestructor)(void *privdata, void *key);
        //销毁值的函数
        void (*valDestructor)(void *privdata, void *obj);
    } dictType;
    
  • 字典中新添加键值对时,先根据键应用哈希算法计算哈希值和索引值,再将包含新键值对的哈希表节点放到哈希表数组的指定索引上。如果存在哈希冲突,则新节点放在对应索引链表的表头
  • 为了让哈希表的复杂因子(load factor)维持在合理的范围内,当哈希表保存的键值对数量太多或太少时,需要进行rehash对哈希表进行扩展或者收缩
  • 如果进行扩展操作,ht[1]的大小为第一个大于等于ht[0].used*2的 2^n(2的n次方);如果进行收缩操作,ht[1]的大小为第一个大于等于ht[0].used的2^n(2的n次方)
  • rehash的过程:分配ht[1]空间后,把ht[0]的数据迁移到ht[1]中;迁移后释放ht[0],将ht[1]设置为ht[0];新创建ht[1]的空白哈希表以备下次使用
  • 对哈希表自动扩展的条件(负载因子=已保存节点数/哈希表大小):

    1)服务器当前没执行BGSAVE或者BGREWRITEAOF命令,且哈希表负载因子大于等于1

    2)服务器在执行BGSAVE或BGREWRITEAOF命令,且哈希表负载因子大于等于5

  • 当负载因子小于0.1时自动进行哈希表收缩操作
  • 渐进性rehash,将rehash的工作均摊到对字典的每个添加、删除、查找和更新上
  • 渐进式rehash过程中,新添加的字典的键值对都会在ht[1]中。字典的删除、查找、更新都会在两表进行,先查ht[0]再查ht[1]
  • 4.跳跃表skiplist(用于实现有序集合和集群节点中的内部数据结构)

    //跳跃表节点
    typedef struct zskiplistNode {  
        //层,每个节点保存了该节点所分布的层次,以及在该层对应的前序指针,和层级之间的跨度
        struct zskiplistLevel {
            //前进指针,指向表尾方向,节点在该层的前进指针
            struct zskiplistNode *forward;
            //跨度,与下一层级的跨度
            unsigned int span;
        } level[];
        //后退指针
        struct zskiplistNode *backward;
        //分值
        double score;
        //成员对象
        robj *obj;
    } zskiplistNode;
    
    //zskiplist结构
    typedef struct zskiplist {  
        //表头节点和表尾节点
        struct zskiplistNode *header, *tail;
        //表中节点的数量
        unsigned long length;
        //表中层数最大的节点的层数
        int level;
    } zskiplist;
    
  • 每个跳跃表节点的层高都是1至32之间的随机数
  • 跳跃表中的节点按照分值大小排序,分值相同时按照成员对象的大小排序(字母表顺序)
  • 一个五层带zskiplist的跳跃表

    5.整数集合

    //intset数据结构
    typedef struct intset {  
        //编码方式
        uint32_t encoding;//取值范围:INTSET_ENC_INT16,INTSET_ENC_INT32,INTSET_ENC_INT64
        //集合包含的元素数量
        uint32_t length;
        //保存元素的数组
        int8_t contents[];//实际类型以encoding的属性为准
    } intset;
    
  • contents数组所有元素的类型一致
  • 当新元素类型超出既有范围时,需要先升级数组的结构(分配更大的存储空间),然后进行旧元素的类型升级,继而更新数组各元素的位置,最终再更新encoding的编码类型
  • 支持自动升级,不支持降级
  • 6.压缩列表ziplist
    当一个[列表的列表项|哈希类型的键值对]很少,并且值要么都是小整数值,要么就是长度比较短的字符串,那么Redis就会使用压缩列表作为[列表类型|哈希类型]的底层实现,节约内存

    压缩列表整体结构
    zlbytes:4字节空间,记录整个压缩列表的内存字节数  
    zltail:4字节空间,离起始地址的偏移量,无需遍历列表即可定位表尾地址  
    zllen:2字节空间,记录节点数,小于65535时数据准确,等于65535时存的已经不准确,需要遍历节点计算得出  
    entryX:列表节点,长度由内容决定  
    zlend:1字节,特殊值OxFF(255),标记列表末端
    
    单个节点的结构
    previous_entry_length:记录前一节点的长度。如果前一节点长度小于254字节,则此属性长度为1字节,记录了前一节点的长度;如果前一节点长度大于等于254字节,则该属性长度为5字节,其中第一字节为OxFE(254,为啥不是OxFF?因为这是结尾的特殊值),后续4字节保存具体的前一字节的长度  
    encoding:记录了content属性保存的数据类型和长度  
    content:节点的值  
    
  • 为节约内存而开发的顺序型数据结构

  • 添加新节点或者删除节点,都可能导致连锁更新(连续空间依次被重新分配)

  • 二、五种对象

    以上的数据结构是Redis对象的具体底层实现,而Redis的五种对象类型(字符串、列表、哈希、集合、有序集合)是由一种或多种底层实现组合而成。

    //对象的主要属性
    typedef struct redisObject{  
        //类型
        unsigned typpe:4;//REDIS_STRING,REDIS_LIST,REDIS_HASH,REDIS_SET,REDIS_ZSET
        //编码
        unsigned encoding:4;
        //指向底层实现数据结构的指针
        void *ptr;
        //...其他
    } robj;
    

    encoding记录了对象使用的编码
    每种对象可能有多种不同的编码(节约内存)

  • 通过encoding属性设置对象使用的编码,提升了Redis的灵活性和效率,优化对象在不同场景下的效率

  • 当同一个对象因为属性变化导致类型会发生变化时,Redis会自动更新对象的编码类型

  • 1.字符串对象
    可以是int、embstr或者raw类型编码

  • 如果保存的是整数值,并且可以用long类型表示。对象使用int编码
  • 如果保存的是小于等于32字节的字符串,使用embstr编码保存字符串
  • 如果保存大于32字节的字符串,编码类型为raw,且字符串值用SDS保存
  • embstr相比raw编码,会申请一个连续内存用于保存redisObject和sdshdr,减少内存分配并且充分利用了内存缓存
  • int和embstr类型编码的对象,在一定条件下会被转换成raw编码的对象(当保存的值超出原有范围的时候)
  • 2.列表对象
    可以是ziplist或者linkedlist编码 其中,满足以下两个条件的场景下会用ziplist编码:

  • 列表对象保存的所有字符串长度都小于list-max-ziplist-value配置的值(默认64字节)
  • 列表对象保存的元素数小于list-max-ziplist-entries值(默认512)
  • 其他场合下用linkedlist编码

    另:使用ziplist编码的对象,当以上两条件不再满足时,会自动编码转换成linkedlist

    3.哈希对象
    可以是ziplist或者hashtable

  • 使用ziplist编码时,新的键值对要加入时,先把键的节点压入队尾,再把值的节点紧挨着压入队尾
  • 使用hashtable编码时,底层每个键值对都是一个字典值对保存
  • 编码转换条件同列表对象(超长或超个数都会使用hashtable编码,否则用ziplist编码)
  • 4.集合对象
    可以是intset或者hashtable

  • intset编码的集合对象,数据都保存在整数集合中
  • hashtable编码的集合对象,数据都保存在字典中,其中字典的键就是字符串对象,代表一个集合元素,而字典的值为NULL。
  • 当集合所有元素都是整数值并且元素数量不超过set-max-intset-entries(默认512)时,使用intset编码,否则使用hashtable编码,编码条件满足时也会类型转换
  • 5.有序集合对象
    可以是ziplist或者skiplist

  • ziplist保存时,每个集合元素使用两个相邻的压缩列表节点来保存,第一个节点保存元素的成员member,第二个节点保存元素的分值score。
  • 压缩列表节点从小到大排序,表头小,表尾大。
  • skiplist编码的有序集合对象,使用zset结构作为底层实现,一个zset结构同时包含一个字典和一个跳跃表:
  • typedef struct zset {  
        zskiplist *zsl;
        dict *dict;
    } zset;
    
  • zsl跳跃表按分值从小到大保存集合的所有元素,通过跳跃表可以对有序集合进行范围操作
  • zset中的dict保存了成员到分值的映射,保证O(1)复杂度内查找指定成员的分值
  • 当有序集合元素数小于zset-max-ziplist-entries(默认128)且每个元素成员的长度都小于zset-max-ziplist-value(默认64)时用ziplist编码,否则用skiplist并且支持编码自动转换
  • 6.其他

  • Redis对象带有引用计数,用来实现内存回收和对象共享(多个元素指向同一个底层对象)
  • 对象会记录最后一次被访问的时间,用来计算对象的空转时间
  • 下一篇Redis学习笔记——数据库和部署

    ]]>
    <![CDATA[贵知么]]>

    简介: 这本书让你了解决策背后是概率选择,真正关注决策质量而不以结果论成败;让你破除心理上的自利性偏差,让你在情绪不稳定的情况下及时退出止损。培养了科学的认知习惯后,加上各种思维工具的有效运用,如同伴制的求真团体和心理时间旅行法等,最终建立你强大且完整的科学决策系统。

    读书笔记

  • 当面对不确定性的结果时,运用概率来分析问题,是一种新的处理思路
  • 避免做决策时陷入自己惯性思维的一种方式,就是审视各种意见,学习我们不知道的东西从而校准我们的决策
  • 制定规划时,要有超时空的视角,从未来反向推断现在的计划。学会从积极的视角制定规划,同时要从负面的视角来思考可能的问题并予以规避,从而保障规划的可执行性
  • 后悔无益于解决问题,应该在总结经验后及时运用到事前决策中
  • 目录

    序言

    前言 为什么这不是一本关于打扑克的书

    第一章 生活是扑克,不是象棋

  • 皮特·卡罗尔和事后诸葛亮
  • 以结果为导向的危害
  • 快速或死亡:人类大脑不是为理性而构造的
  • 两分钟警告
  • 奇爱博士
  • 扑克与象棋
  • 一场致命的智斗
  • “我不确定”:充分利用不确定性
  • 重新定义错误
  • 第二章 赌一把?

  • 得梅因三十天之赌
  • 我们都经历过得梅因
  • 所有的决策都是对赌
  • 多数牌局都是在跟自己对赌
  • 信念强则赢面大
  • ]]>
    http://www.guizhi.me/dui-du-xin-xi-bu-zu-shi-ru-he-zuo-chu-gao-ming-jue-ce/99a9e228-d10c-4735-a531-70d8a8d9318bSat, 20 Jul 2019 14:18:42 GMT

    简介: 这本书让你了解决策背后是概率选择,真正关注决策质量而不以结果论成败;让你破除心理上的自利性偏差,让你在情绪不稳定的情况下及时退出止损。培养了科学的认知习惯后,加上各种思维工具的有效运用,如同伴制的求真团体和心理时间旅行法等,最终建立你强大且完整的科学决策系统。

    读书笔记

  • 当面对不确定性的结果时,运用概率来分析问题,是一种新的处理思路
  • 避免做决策时陷入自己惯性思维的一种方式,就是审视各种意见,学习我们不知道的东西从而校准我们的决策
  • 制定规划时,要有超时空的视角,从未来反向推断现在的计划。学会从积极的视角制定规划,同时要从负面的视角来思考可能的问题并予以规避,从而保障规划的可执行性
  • 后悔无益于解决问题,应该在总结经验后及时运用到事前决策中
  • 目录

    序言

    前言 为什么这不是一本关于打扑克的书

    第一章 生活是扑克,不是象棋

  • 皮特·卡罗尔和事后诸葛亮
  • 以结果为导向的危害
  • 快速或死亡:人类大脑不是为理性而构造的
  • 两分钟警告
  • 奇爱博士
  • 扑克与象棋
  • 一场致命的智斗
  • “我不确定”:充分利用不确定性
  • 重新定义错误
  • 第二章 赌一把?

  • 得梅因三十天之赌
  • 我们都经历过得梅因
  • 所有的决策都是对赌
  • 多数牌局都是在跟自己对赌
  • 信念强则赢面大
  • 所听既所得
  • 他们观看了一场比赛
  • 顽固的信念
  • 聪明反被聪明误
  • 赌一把
  • 重新定义信心
  • 第三章 在对赌中学习:应对不确定性的未来

  • 希腊人尼克以及从水晶酒吧学到的一些东西
  • 结果即反馈
  • 运气与技能:区分结果
  • 回溯分析的困难:健康甜点现象
  • 如果不是因为运气,每一次我都会赢
  • 非此即彼的思维依旧顽固
  • 人们在观察
  • 从他人的结果中看自己
  • 重塑习惯
  • “赌一把?”回归
  • 来之不易
  • 第四章 结伴制

  • 也许问题在于你自己,想过没有
  • 红药丸还是蓝药丸
  • 团体生而不同
  • 团体对注重准确性的奖励
  • “100个白色城堡汉堡……和一大杯巧克力奶昔”:责任性如何改善决策制定
  • 团体让我们接触到各种各样的观点
  • 联邦法官:主管倾向并不稀奇
  • 社会心理学家:确定性倾向和异端学会
  • 赌一把(科学的)?
  • 第五章 为了更好地决策而提出异议

  • 向一位魔术师致敬
  • 默顿式共有性:多多益善
  • 普遍性:不轻易否定信息
  • 无私利性:我们都有利益冲突,还很容易传染
  • 有条理的怀疑性:真正的怀疑主义者提出论据并结交朋友
  • 与团体之外的世界进行沟通
  • 第六章 心理时间旅行历险

  • 马蒂·麦克弗莱偶遇马蒂·麦克弗莱
  • 夜猫子杰瑞
  • 做决策之后不要后悔
  • 爆胎、行情指标和变焦镜头
  • 嗯是的,但最近你给了我什么好处
  • 倾斜
  • 尤利西斯合约:利用时间旅行来预先承诺
  • 决策者脏罐
  • 侦察:规划未来
  • 情景规划的实践
  • 反向回顾:从一个积极的未来开始逆向思考
  • 预先检查:从一个负面的未来开始逆向思考
  • 树木学和事后偏见(或者,让电锯歇一歇)
  • 致谢、注释、参考书目和推荐阅读等

    ]]>
    <![CDATA[贵知么]]>最近用Linux开发,经常需要切换不同的项目代码,厌倦了各种目录切换的操作,换成自定义函数的方式进行快速切换。

    设计思路

  • 实现一个自定义函数,能接收项目名称,跳转到对应代码目录
  • 由于git项目名称可能很长,需要对部分项目创建别名,能够转换到对应的项目名称再跳转
  • 如果项目不存在,跳转到默认目录
  • 准备编程

  • bash的自定义函数格式
  • to(){  
        project=$1 //获取第一个参数
    }
    //所以,最终命令的用法应该类似这种方式:to projectA 即可跳转到对应项目目录
    
  • 项目名称映射 bash语法中的map定义格式为:declare -A map=(["akey"="avalue"])
    注意中间不要有空格
  • 目录跳转 自定义的方法中执行目录切换并不会改变当前用户的真实目录,除非放到bash_rc等自动加载的空间中。
  • 代码实现

    #快速跳转
    to(){  
        declare -A map=(["user"]="new-user" ["enterprise"]="my-enterprise" ["common"]="all-common" ["crm"]="new-crm"
    ]]>
    http://www.guizhi.me/bashbian-cheng-zhi-zi-ding-yi-han-shu/6bd31712-5660-40a8-ba6e-a4553c70843dThu, 30 May 2019 03:22:55 GMT最近用Linux开发,经常需要切换不同的项目代码,厌倦了各种目录切换的操作,换成自定义函数的方式进行快速切换。

    设计思路

  • 实现一个自定义函数,能接收项目名称,跳转到对应代码目录
  • 由于git项目名称可能很长,需要对部分项目创建别名,能够转换到对应的项目名称再跳转
  • 如果项目不存在,跳转到默认目录
  • 准备编程

  • bash的自定义函数格式
  • to(){  
        project=$1 //获取第一个参数
    }
    //所以,最终命令的用法应该类似这种方式:to projectA 即可跳转到对应项目目录
    
  • 项目名称映射 bash语法中的map定义格式为:declare -A map=(["akey"="avalue"])
    注意中间不要有空格
  • 目录跳转 自定义的方法中执行目录切换并不会改变当前用户的真实目录,除非放到bash_rc等自动加载的空间中。
  • 代码实现

    #快速跳转
    to(){  
        declare -A map=(["user"]="new-user" ["enterprise"]="my-enterprise" ["common"]="all-common" ["crm"]="new-crm")
        home="/home/dev/git/" //设定默认目录,如果项目不存在跳转到此
        path=$home
        project=$1
        projectPath=${map[$project]} //从输入项中获取对应map中是否存在别名需要转换
        echo $projectPath
        if [ $projectPath ]
        then
            path=${home}${projectPath} //有别名则用别名目录拼接并跳转
        else
            path=${home}${project} //没有别名,则直接用输入名称跳转
        fi
    
        if [ ! -d $path ]
        then
            echo "dir doesn't exist,to default now!"
            cd $home
        else
            cd $path
        fi
    }
    
    ]]>
    <![CDATA[贵知么]]>Elasticsearch是基于Lucene开发的搜索引擎,也是近几年很火的全文搜索引擎,具有部署方便、运行稳定、搜索高效等特点,且支持分布式部署,易于扩展。本文对于近期学习的知识做下梳理。

    基本概念

  • 集群(cluster):一个整体的Elasticsearch服务
  • 节点(node):构成集群的每个服务节点
  • 索引(index):文档的集合,类似数据库的db
  • 文档(document):索引文件的最小单元,类似数据库的行数据
  • 分片|副本(Shards & Replicas):部分数据的集合,一个文档通常会存储在多个副本中(分布式)
  • Elasticsearch 是 面向文档的,意味着它存储整个对象或文档。Elasticsearch 不仅存储文档,而且索引每个文档的内容使之可以被检索。在 Elasticsearch 中,你对文档进行索引、检索、排序和过滤--而不是对行列数据。这是一种完全不同的思考数据的方式,也是 Elasticsearch 能支持复杂全文检索的原因。
    Elasticsearch 使用

    ]]>
    http://www.guizhi.me/elasticsearchsou-suo-xue-xi/82fbce40-809a-4dfd-8688-572aa953c478Thu, 14 Mar 2019 15:05:59 GMTElasticsearch是基于Lucene开发的搜索引擎,也是近几年很火的全文搜索引擎,具有部署方便、运行稳定、搜索高效等特点,且支持分布式部署,易于扩展。本文对于近期学习的知识做下梳理。

    基本概念

  • 集群(cluster):一个整体的Elasticsearch服务
  • 节点(node):构成集群的每个服务节点
  • 索引(index):文档的集合,类似数据库的db
  • 文档(document):索引文件的最小单元,类似数据库的行数据
  • 分片|副本(Shards & Replicas):部分数据的集合,一个文档通常会存储在多个副本中(分布式)
  • Elasticsearch 是 面向文档的,意味着它存储整个对象或文档。Elasticsearch 不仅存储文档,而且索引每个文档的内容使之可以被检索。在 Elasticsearch 中,你对文档进行索引、检索、排序和过滤--而不是对行列数据。这是一种完全不同的思考数据的方式,也是 Elasticsearch 能支持复杂全文检索的原因。
    Elasticsearch 使用 JavaScript Object Notation 或者 JSON 作为文档的序列化格式。

    实践

    命令语法:

    <HTTP Verb> /<Index>/<Type>/<ID>  
    http操作/索引/类型/文档ID  
    
  • 集群状态
  • 查看集群健康度 GET /_cat/health?v
  • 查看节点状态 GET /_cat/nodes?v
  • 查看索引状态 GET /_cat/indices?v
  • 创建|删除索引
  • 创建索引 PUT /mycollect?pretty
  • 删除索引 DELETE /mycollect?pretty
  • 文档操作

  • 添加文档 PUT /mycollect/_doc/1?pretty {"name": "agui"} 支持put|post方式更新数据
  • 查看文档 GET /mycollect/_doc/1
  • 更新文档 支持put|post方式更新数据

    PUT /mycollect/_doc/1?pretty {"name": "agui","age":"32"}

    PUT /mycollect/_doc/1/_update?pretty {"script" : "ctx._source.age += 5"}

  • 搜索数据

  • 导入数据集(样例)

    curl -H "Content-Type: application/json" -XPOST "localhost:9200/bank/_doc/_bulk?pretty&refresh" --data-binary "@accounts.json"

  • REST API方式搜索

    GET /bank/_search?q=*&sort=account_number:asc&pretty

  • REQUEST BODY方式搜索,支持更灵活的条件设定和筛选

    GET /bank/_search { "query": { "match_all": {} }, "sort": [ { "account_number": "asc" } ] }

  • Query DSL查询
  • GET /_search  
    {
      "query": { 
        "bool": { 
          "must": [
            { "match": { "title":   "Search"        }}, 
            { "match": { "content": "Elasticsearch" }}  
          ],
          "filter": [ 
            { "term":  { "status": "published" }}, 
            { "range": { "publish_date": { "gte": "2015-01-01" }}} 
          ]
        }
      }
    }
    

    练习:中文搜索

    参考链接:

    1.官方文档https://www.elastic.co/guide/en/elasticsearch/reference/6.6/index.html

    2.阮一峰教程http://www.ruanyifeng.com/blog/2017/08/elasticsearch.html

    ]]>
    <![CDATA[贵知么]]>1. 什么是事务

    事务是一个序列操作,其中的操作要么都执行,要么都不执行

    2. 事务的特性

  • atomicity(原子性):原子性是指事务是一个不可再分割的工作单位,事务中的操作要么都发生,要么都不发生。
  • consistency(一致性):一致性是指在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏
  • isolation(隔离性):多个事务并发访问时,事务之间是隔离的,一个事务不应该影响其它事务运行效果
  • durability(持续性):事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚
  • 3. 看看事务是如何工作的

    本地环境模拟,准备两张表:

    CREATE TABLE `user_log` (  
      `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增id',
      `user_id` int(11) unsigned NOT
    ]]>
    http://www.guizhi.me/mysqlshi-wu-tan-jiu/1924cacd-6bba-4c8b-8ea6-41b167190490Thu, 03 Jan 2019 11:47:16 GMT1. 什么是事务

    事务是一个序列操作,其中的操作要么都执行,要么都不执行

    2. 事务的特性

  • atomicity(原子性):原子性是指事务是一个不可再分割的工作单位,事务中的操作要么都发生,要么都不发生。
  • consistency(一致性):一致性是指在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏
  • isolation(隔离性):多个事务并发访问时,事务之间是隔离的,一个事务不应该影响其它事务运行效果
  • durability(持续性):事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚
  • 3. 看看事务是如何工作的

    本地环境模拟,准备两张表:

    CREATE TABLE `user_log` (  
      `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增id',
      `user_id` int(11) unsigned NOT NULL COMMENT '用户ID',
      `scores` int(11) NOT NULL COMMENT '积分',
      `token` varchar(255) NOT NULL COMMENT '唯一性token',
      `create_time` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间',
      `update_time` int(11) NOT NULL DEFAULT '0' COMMENT '更新时间',
      `is_delete` tinyint(1) NOT NULL DEFAULT '0' COMMENT '删除标识',
      PRIMARY KEY (`id`),
      UNIQUE KEY `uniq_token` (`token`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户记录表'
    
    CREATE TABLE `user_account` (  
      `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增id',
      `scores` int(11) NOT NULL COMMENT '积分',
      `create_time` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间',
      `update_time` int(11) NOT NULL DEFAULT '0' COMMENT '更新时间',
      `is_delete` tinyint(1) NOT NULL DEFAULT '0' COMMENT '删除标识',
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户账户表'
    

    客户端1和客户端2同时打开数据库,开启事务。测试一下几种场景:

  • 步骤1.两个客户端分别写入不同的数据并提交事务
  • 步骤2.客户端1写入A,B两条记录,不提交事务;客户端2写入B记录

    查看进行中的事务:SELECT * FROM information_schema.INNODB_TRX;

    查看锁定等待的请求:select * from INNODB_LOCK_WAITS;

  • 步骤3.客户端1进行rollback操作,看看客户端2的数据情况

    数据记录id发生了什么变化

    客户端2的记录提交成功了么

  • 步骤4.继续在客户端1添加新数据C、D,不提交,查看客户端2的数据情况
  • 步骤5.在客户端2添加新数据E,提交事务,查看客户端1的数据情况
  • 步骤6.在客户端1中添加新数据E,结果是什么
  • 步骤7.在客户端2中查看数据库查询列表,找到客户端1连接的ID,并杀掉客户端1的连接,看看发生什么情况
  • 4. 思考

  • 数据库事务作为一个最小单元,只能全部成功或者全部失败。失败后数据库操作会回滚,但并不意味着毫无痕迹(比如自增主键的ID变化)。

  • 数据库回滚本质上是undo log,把事务过程中的语句对等的保留了undo log,回滚时反向操作把数据恢复原样。但是,如果数据库事务中有其他不能回滚的操作(比如第三方接口调用),那就会发生业务不一致的问题。

  • 数据库的隔离性保证了多个事务在并发执行时不相互影响,但并不是说完全感知不到其他事务的存在(比如主键冲突检查,多个事务有数据可能发生冲突时会有等待的过程INNODB_LOCK_WAITS)。

  • 事务一旦提交后,数据就持久化了,即便再进行回滚也不会影响事务的数据。在开发过程中,要尽量避免commit事件后的逻辑抛异常,否则catch住异常进行回滚就会发生事务不匹配的问题(transaction not match)


  • 参考文档:

    ]]>
    <![CDATA[贵知么]]>

    近期工作原因修改了不少接口,每次交接中都会有很多不方便的地方。要么是没有前人的文档参考,自己只能扒代码;要么是自己提供的接口,懒得动手出文档,结果跟partner对接的时候给对方造成困难。所以,昨天看到这个管理工具后,眼前一亮,决定拿来玩玩。有机会的话部署到办公环境,给其他同学顺手玩玩~

    主要功能

  • API文档快速生成和管理
  • MARKDOWN格式模板和实时预览,符合程序员的装逼范儿;

    编辑过的文档可以通过历史记录进行恢复,如果是git追溯的话就牛逼了

  • 数据字典展示
  • 数据字典格式的模板

  • 说明文档维护
  • 其实,各种类型的说明文档都可以这么玩

    补充功能

  • 项目归档
  • 可以按照项目建立文档,通过密码管理项目的公开性

  • 成员管理
  • 项目可以增加成员或者转让项目给成员

  • 文档分享
  • 文档的链接可以分享给其他同学公开访问

    感谢开发者的贡献精神,附上git项目地址showdoc

    ]]>
    http://www.guizhi.me/api-doc-tool/4847eb4a-b82f-4f57-ad7a-32302e2869bcThu, 03 Mar 2016 16:25:02 GMT showdoc-API文档管理工具

    近期工作原因修改了不少接口,每次交接中都会有很多不方便的地方。要么是没有前人的文档参考,自己只能扒代码;要么是自己提供的接口,懒得动手出文档,结果跟partner对接的时候给对方造成困难。所以,昨天看到这个管理工具后,眼前一亮,决定拿来玩玩。有机会的话部署到办公环境,给其他同学顺手玩玩~

    主要功能

  • API文档快速生成和管理
  • MARKDOWN格式模板和实时预览,符合程序员的装逼范儿;

    编辑过的文档可以通过历史记录进行恢复,如果是git追溯的话就牛逼了

  • 数据字典展示
  • 数据字典格式的模板

  • 说明文档维护
  • 其实,各种类型的说明文档都可以这么玩

    补充功能

  • 项目归档
  • 可以按照项目建立文档,通过密码管理项目的公开性

  • 成员管理
  • 项目可以增加成员或者转让项目给成员

  • 文档分享
  • 文档的链接可以分享给其他同学公开访问

    感谢开发者的贡献精神,附上git项目地址showdoc

    ]]>
    <![CDATA[贵知么]]>http://www.guizhi.me/bash-programming/8ed94997-f0b6-49bb-9a96-006781027defTue, 01 Sep 2015 09:00:27 GMT

    背景:最近因为工作需要,会从系统log日志中扒统计数据,为了赶时间匆忙手工扒了一遍,劳心费力。于是完事后想了想搞个shell命令出来,以后就省事了。

    用到的基本命令

    for循环(条件循环)

    语法:

    for((i=1; i<=10; i++))  
    {
        echo $i
    }
    

    for循环(列表循环)

    语法:

    for m in 1 2 3 4  
    do  
        echo $m
    done  
    

    echo输出重定向

    语法:

    echo [-n] aaa > logfile  
    echo [-n] bbb >> logfile  
    其中,-n参数控制行尾是否换行,如果希望两次输出在同一行的话,加-n参数
    用'>'重定向默认是覆盖写入,会覆盖前面的内容;用'>>'重定向默认是追加方式
    

    grep匹配查询

    语法:

    grep [选项]... PATTERN [FILE]...  
    在每个 FILE 或是标准输入中查找 PATTERN。
    默认的 PATTERN 是一个基本正则表达式(缩写为 BRE)。
    

    示例:

    grep -i 'hello world' menu.h main.c  
    从menu.h和main.c两个文件中查询'hello world',忽略大小写匹配
    

    管道命令

    语法:

    操作符"|"
    管道就是在一个命令完成后,把经由前面一个指令传出的正确输出信息作为输入信息来处理
    

    示例:

    grep aa logfile.log|grep bb  
    从logfile.log中查询包含aa的结果,并从中再匹配包含bb的结果
    

    wc统计命令

    语法:

    用法:wc [选项]... [文件]...
     或:wc [选项]... --files0-from=F
    Print newline, word, and byte counts for each FILE, and a total line if  
    more than one FILE is specified.  With no FILE, or when FILE is -,  
    read standard input.  A word is a non-zero-length sequence of characters  
    delimited by white space.  
    The options below may be used to select which counts are printed, always in  
    the following order: newline, word, character, byte, maximum line length.  
      -c, --bytes            print the byte counts
      -m, --chars            print the character counts
      -l, --lines            print the newline counts
          --files0-from=文件    从指定文件读取以NUL 终止的名称,如果该文件被
                        指定为"-"则从标准输入读文件名
      -L, --max-line-length    显示最长行的长度
      -w, --words            显示单词计数
          --help        显示此帮助信息并退出
          --version        显示版本信息并退出
    

    示例:

    grep aa logfile.log|wc -l 统计logfile.log中包含aa的行数  
    

    其他知识

  • shell命令中赋值命令操作符"="两侧不能包含空格
  • 变量赋值后,引用变量时需要加"$"符号
  • 获取shell命令传入参数,可以用$0, $1, $2 其中,$0获取的是当前脚本名称,$1获取输入的第一个参数,以此类推
  • 更全面的bash编程语法,可参考Advanced Bash-Scripting Guide

    ]]>
    <![CDATA[贵知么]]>http://www.guizhi.me/vim-first/5307a080-993b-4f12-a285-9c9485f3ed65Fri, 03 Jul 2015 16:53:00 GMT

    到新单位后,由于工作需要,切换到vim下进行开发,需要对vim的常用操作和一些常用插件进行熟悉,此处先介绍基础用法

    其实,很多工具的使用指南都在自己的help文档中,vim还有自己的教学练习工具,安装vim时会同时安装vimtutor,命令行中输入vimtutor即可进入教程文档,如下图:

    vim1

    然后,就顺着教程一步步来学习常用操作即可。这些功能的学习也都是循序渐进的,从基本到光标移动,到编辑、删除、复制、替换等操作,再到更高级的查找替换语法,逐渐提高对vim的使用效率。

    按照教程学习完后,会对vim有个初步到了解,这只是用vim编程的第一步。下一篇会继续讲解vim的高级用法——插件,大幅提升开发效率的工具。

    ]]>
    <![CDATA[贵知么]]>http://www.guizhi.me/php-singleton-pattern/f04d1651-3798-4ed6-ac26-f144f4cf1987Mon, 15 Jun 2015 05:59:06 GMT原文地址:http://www.cnblogs.com/yangjinjin/archive/2013/01/31/2887492.html

    单例模式(Singleton Pattern 单件模式或单元素模式)

    单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。

    单例模式是一种常见的设计模式,在计算机系统中,线程池、缓存、日志对象、对话框、打印机、数据库操作、显卡的驱动程序常被设计成单例。

    单例模式分3种:懒汉式单例、饿汉式单例、登记式单例。

    单例模式有以下3个特点:

    1.只能有一个实例。

    2.必须自行创建这个实例。

    3.必须给其他对象提供这一实例。

    那么为什么要使用PHP单例模式?

    PHP一个主要应用场合就是应用程序与数据库打交道的场景,在一个应用中会存在大量的数据库操作,针对数据库句柄连接数据库的行为,使用单例模式可以避免大量的new操作。因为每一次new操作都会消耗系统和内存的资源。

    在以往的项目开发中,没使用单例模式前的情况如下:

    //初始化一个数据库句柄
    $db = new DB(...);
    //比如有个应用场景是添加一条用户信息
    $db->addUserInfo();
    ......
    //然而我们要在另一地方使用这个用户信息,这时要用到数据库句柄资源,可能会这么做
    ......
    function test() {  
       $db = new DB(...);
       $db->getUserInfo();
    ......
    有些朋友也许会说,可以直接使用global关键字!
       global $db;
    ......
    

    的确global可以解决问题,也起到单例模式的作用,但在OOP中,我们拒绝这种编码。因为global存在安全隐患(全局变量不受保护的本质)。

    全局变量是面向对象程序员遇到的引发BUG的主要原因之一。这是因为全局变量将类捆绑于特定的环境,破坏了封装。如果新的应用程序无法保证一开始就定义了相同的全局变量,那么一个依赖于全局变量的类就无法从一个应用程序中提取出来并应用到新应用程序中。

    确切的讲,单例模式恰恰是对全局变量的一种改进,避免那些存储唯一实例的全局变量污染命名空间。你无法用错误类型的数据覆写一个单例。这种保护在不支持命名空间的PHP版本里尤其重要。因为在PHP中命名冲突会在编译时被捕获,并使脚本停止运行。

    PHP单例模式实例:

    <?php
    
    class User {  
        //静态变量保存全局实例
        private static $_instance = null;
        //私有构造函数,防止外界实例化对象
        private function __construct() {
        }
        //私有克隆函数,防止外部克隆对象
        private function __clone() {
        }
        //静态方法,单例统一访问入口
        static public function getInstance() {
            if (is_null ( self::$_instance ) || isset ( self::$_instance )) {
                self::$_instance = new self ();
            }
            return self::$_instance;
        }
    }
    
    ?>
    

    单例模式的优缺点:

    优点:

    1. 改进系统的设计

    2. 是对全局变量的一种改进

    缺点:

    1. 难于调试

    2. 隐藏的依赖天博SPORTS

    3. 无法用错误类型的数据覆写一个单例

    ]]>
    <![CDATA[贵知么]]>http://www.guizhi.me/70-shell-cmd-for-interview/893c7108-d369-44f5-8b1d-46fb0f88b2caMon, 15 Jun 2015 01:18:22 GMT原文地址:http://www.codeceo.com/article/shell-questions.html

    我们为你的面试准备选择了 70 个你可能遇到的 shell 脚面问题及解答。了解脚本或至少知道基础知识对系统管理员来说至关重要,它也有助于你在工作环境中自动完成很多任务。在过去的几年里,我们注意到所有的 linux 工作职位都要求脚本技能。

    Shell 脚本面试问题大全
    1) 如何向脚本传递参数 ?

    ./script argument

    例子 : 显示文件名称脚本

    ./show.sh file1.txt

    cat show.sh  
    #!/bin/bash
    cat $1  
    

    2) 如何在脚本中使用参数 ?

    第一个参数 : $1,第二个参数 : $2

    例子 : 脚本会复制文件(arg1) 到目标地址(arg2)

    ./copy.sh file1.txt /tmp/
    cat copy.sh  
    #!/bin/bash
    cp $1 $2  
    

    3) 如何计算传递进来的参数 ?

    $#

    4) 如何在脚本中获取脚本名称 ?

    $0

    5) 如何检查之前的命令是否运行成功 ?

    $?

    6) 如何获取文件的最后一行 ?

    tail -1

    7) 如何获取文件的第一行 ?

    head -1

    8) 如何获取一个文件每一行的第三个元素 ?

    awk '{print $3}'

    9) 假如文件中每行第一个元素是 FIND,如何获取第二个元素

    awk '{ if ($1 == "FIND") print $2}'

    10) 如何调试 bash 脚本

    将 -xv 参数加到 #!/bin/bash 后

    例子:

    #!/bin/bash –xv

    11) 举例如何写一个函数 ?

    function example {  
    echo "Hello world!"  
    }
    

    12) 如何向连接两个字符串 ?

    V1="Hello"  
    V2="World"  
    V3=$V1+$V2  
    echo $V3  
    

    输出

    Hello+World

    13) 如何进行两个整数相加 ?

    V1=1  
    V2=2  
    V3=$V1+$V2  
    echo $V3  
    

    输出

    3

    14) 如何检查文件系统中是否存在某个文件 ?

    if [ -f /var/log/messages ]  
    then  
    echo "File exists"  
    fi  
    

    15) 写出 shell 脚本中所有循环语法 ?
    for 循环 :

    for i in $( ls ); do  
    echo item: $i  
    done  
    

    while 循环 :

    #!/bin/bash
    COUNTER=0  
    while [ $COUNTER -lt 10 ]; do  
    echo The counter is $COUNTER  
    let COUNTER=COUNTER+1  
    done  
    

    until 循环 :

    #!/bin/bash
    COUNTER=20  
    until [ $COUNTER -lt 10 ]; do  
    echo COUNTER $COUNTER  
    let COUNTER-=1  
    done  
    

    16) 每个脚本开始的 #!/bin/sh 或 #!/bin/bash 表示什么意思 ?

    这一行说明要使用的 shell。#!/bin/bash 表示脚本使用 /bin/bash。对于 python 脚本,就是 #!/usr/bin/python。(LCTT译注:这一行称之为释伴行。) 17) 如何获取文本文件的第 10 行 ?

    head -10 file|tail -1

    18) bash 脚本文件的第一个符号是什么

    #

    19) 命令:[ -z "" ] && echo 0 || echo 1 的输出是什么

    0

    20) 命令 “export” 有什么用 ?

    使变量在子 shell 中可用。 21) 如何在后台运行脚本 ?

    在脚本后面添加 “&”。 22) “chmod 500 script” 做什么 ?

    使脚本所有者拥有可执行权限。 23) “>” 做什么 ?

    重定向输出流到文件或另一个流。 24) & 和 && 有什么区别

    & – 希望脚本在后台运行的时候使用它
    && – 当前一个脚本成功完成才执行后面的命令/脚本的时候使用它
    

    25) 什么时候要在 [ condition ] 之前使用 “if” ?

    当条件满足时需要运行多条命令的时候。

    26) 命令: name=John && echo ‘My name is $name’的输出是什么

    My name is $name

    27) bash shell 脚本中哪个符号用于注释 ?

    #

    28) 命令: echo ${new:-variable} 的输出是什么

    variable

    29) ‘ 和 ” 引号有什么区别 ?

    ‘ – 当我们不希望把变量转换为值的时候使用它。
    ” – 会计算所有变量的值并用值代替。
    

    30) 如何在脚本文件中重定向标准输出和标准错误流到 log.txt 文件 ?

    在脚本文件中添加"exec >log.txt 2>&1" 命令。 31) 如何只用 echo 命令获取字符串变量的一部分 ?

    echo ${variable:x:y}  
    x - 起始位置  
    y - 长度  
    

    例子:

    variable="My name is Petras, and I am developer."  
    echo ${variable:11:6} # 会显示 Petras  
    

    32) 如果给定字符串 variable=”User:123:321:/home/dir”,如何只用 echo 命令获取 home_dir ?

    echo ${variable#*:*:*:}  
    

    echo ${variable##*:}

    33) 如何从上面的字符串中获取 “User” ?

    echo ${variable%:*:*:*}

    echo ${variable%%:*}

    34) 如何使用 awk 列出 UID 小于 100 的用户 ?

    awk -F: '$3<100' /etc/passwd

    35) 写程序为用户计算主组数目并显示次数和组名

    cat /etc/passwd|cut -d: -f4|sort|uniq -c|while read c g  
    do  
    { echo $c; grep :$g: /etc/group|cut -d: -f1;}|xargs -n 2
    done  
    

    36) 如何在 bash shell 中更改标准的域分隔符为 “:” ?

    IFS=":"

    37) 如何获取变量长度 ?

    ${#variable}

    38) 如何打印变量的最后 5 个字符 ?

    echo ${variable: -5}

    39) ${variable:-10} 和 ${variable: -10} 有什么区别?

    ${variable:-10} – 如果之前没有给 variable 赋值则输出 10
    ${variable: -10} – 输出 variable 的最后 10 个字符
    

    40) 如何只用 echo 命令替换字符串的一部分 ?

    echo ${variable//pattern/replacement}

    41) 哪个命令将命令替换为大写 ?

    tr '[:lower:]' '[:upper:]'

    42) 如何计算本地用户数目 ?

    wc -l /etc/passwd|cut -d” ” -f1 或者 cat /etc/passwd|wc -l 43) 不用 wc 命令如何计算字符串中的单词数目 ?

    set ${string}  
    echo $#  
    

    44) “export $variable” 或 “export variable” 哪个正确 ?

    export variable

    45) 如何列出第二个字母是 a 或 b 的文件 ?

    ls -d ?[ab]*

    46) 如何将整数 a 加到 b 并赋值给 c ?

    c=$((a+b))

    c=`expr $a + $b`  
    

    c=`echo "$a+$b"|bc`  
    

    47) 如何去除字符串中的所有空格 ?

    echo $string|tr -d " "

    48) 重写这个命令,将输出变量转换为复数: item=”car”; echo “I like $item” ?

    item="car"; echo "I like ${item}s"

    49) 写出输出数字 0 到 100 中 3 的倍数(0 3 6 9 …)的命令 ?

    for i in {0..100..3}; do echo $i; done

    for (( i=0; i<=100; i=i+3 )); do echo "Welcome $i times"; done

    50) 如何打印传递给脚本的所有参数 ?

    echo $*

    echo $@

    51) [ $a == $b ] 和 [ $a -eq $b ] 有什么区别

    [ $a == $b ] – 用于字符串比较
    [ $a -eq $b ] – 用于数字比较
    

    52) = 和 == 有什么区别

    = – 用于为变量复制
    == – 用于字符串比较
    

    53) 写出测试 $a 是否大于 12 的命令 ?

    [ $a -gt 12 ]

    54) 写出测试 $b 是否小于等于 12 的命令 ?

    [ $b -le 12 ]

    55) 如何检查字符串是否以字母 “abc” 开头 ?

    [[ $string == abc* ]]

    56)[[ $string == abc* ]] 和 [[ $string == "abc*" ]] 有什么区别

    [[ $string == abc* ]] – 检查字符串是否以字母 abc 开头
    [[ $string == "abc" ]] – 检查字符串是否完全等于 abc
    

    57) 如何列出以 ab 或 xy 开头的用户名 ?

    egrep "^ab|^xy" /etc/passwd|cut -d: -f1

    58) bash 中 $! 表示什么意思 ?

    后台最近执行命令的 PID. 59) $? 表示什么意思 ?

    前台最近命令的结束状态。

    60) 如何输出当前 shell 的 PID ?

    echo $$

    61) 如何获取传递给脚本的参数数目 ?

    echo $#

    (LCTT 译注:和第3题重复了。) 62) $* 和 $@ 有什么区别

    $* – 以一个字符串形式输出所有传递到脚本的参数
    $@ – 以 $IFS 为分隔符列出所有传递到脚本中的参数
    

    63) 如何在 bash 中定义数组 ?

    array=("Hi" "my" "name" "is")

    64) 如何打印数组的第一个元素 ?

    echo ${array[0]}

    65) 如何打印数组的所有元素 ?

    echo ${array[@]}

    66) 如何输出所有数组索引 ?

    echo ${!array[@]}

    67) 如何移除数组中索引为 2 的元素 ?

    unset array[2]

    68) 如何在数组中添加 id 为 333 的元素 ?

    array[333]="New_element"

    69) shell 脚本如何获取输入的值 ?

    a) 通过参数

    ./script param1 param2

    b) 通过 read 命令

    read -p "Destination backup Server : " desthost

    70) 在脚本中如何使用 “expect” ?

    /usr/bin/expect << EOD
    spawn rsync -ar ${line} ${desthost}:${destpath}  
    expect "*?assword:*"  
    send "${password}/r"  
    expect eof  
    EOD  
    

    祝你好运 !! 如果你有任何疑问或者问题需要解答都可以在下面的评论框中写下来。让我们知道这对你的面试有所帮助!

    ]]>
    <![CDATA[贵知么]]>http://www.guizhi.me/nginx-rewrite/20e3ce43-5398-46dd-9046-85fb498a3543Wed, 10 Jun 2015 08:31:36 GMT转自http://www.nginx.cn/216.html

    nginx通过ngxhttprewrite_module模块支持url重写、支持if条件判断,但不支持else。

    该模块需要PCRE支持,应在编译nginx时指定PCRE源码目录, nginx安装方法。

    文章目录

    1 nginx rewrite指令执行顺序:
    2 break指令
    3 if指令
    4 return指令
    5 rewrite指令
    6 rewrite_log指令
    7 set指令
    8 uninitialized_variable_warn指令
    

    nginx rewrite指令执行顺序:

    1. 执行server块的rewrite指令(这里的块指的是server关键字后{}包围的区域,其它xx块类似)
    2. 执行location匹配
    3. 执行选定的location中的rewrite指令

    如果其中某步URI被重写,则重新循环执行1-3,直到找到真实存在的文件

    如果循环超过10次,则返回500 Internal Server Error错误

    break指令

    语法:break;

    默认值:无

    作用域:server,location,if

    停止执行当前虚拟主机的后续rewrite指令集 break指令实例:

     if ($slow) {
         limit_rate 10k;
         break;
     }
    

    if指令

    语法:if(condition){...}

    默认值:无

    作用域:server,location

    对给定的条件condition进行判断。如果为真,大括号内的rewrite指令将被执行。 if条件(conditon)可以是如下任何内容:

    一个变量名;false如果这个变量是空字符串或者以0开始的字符串;
    使用= ,!= 比较的一个变量和字符串
    是用~, ~*与正则表达式匹配的变量,如果这个正则表达式中包含},;则整个表达式需要用" 或' 包围
    使用-f ,!-f 检查一个文件是否存在
    使用-d, !-d 检查一个目录是否存在
    使用-e ,!-e 检查一个文件、目录、符号链接是否存在
    使用-x , !-x 检查一个文件是否可执行
    

    if指令实例

     if ($http_user_agent ~ MSIE) {
         rewrite ^(.*)$ /msie/$1 break;
     }
    
     if ($http_cookie ~* "id=([^;]+)(?:;|$)") {
         set $id $1;
     }
    
     if ($request_method = POST) {
         return 405;
     }
    
     if ($slow) {
         limit_rate 10k;
     }
    
     if ($invalid_referer) {
         return 403;
     }
    

    return指令

    语法:return code;

    return code URL;

    return URL;

    默认值:无

    作用域:server,location,if

    停止处理并返回指定状态码(code)给客户端。 非标准状态码444表示关闭连接且不给客户端发响应头。 从0.8.42版本起,return 支持响应URL重定向(对于301,302,303,307),或者文本响应(对于其他状态码). 对于文本或者URL重定向可以包含变量

    rewrite指令

    语法:rewrite regex replacement [flag];

    默认值:无

    作用域:server,location,if

    如果一个URI匹配指定的正则表达式regex,URI就按照replacement重写。 rewrite按配置文件中出现的顺序执行。flags标志可以停止继续处理。
    如果replacement以"http://"或"https://"开始,将不再继续处理,这个重定向将返回给客户端。 flag可以是如下参数
    last 停止处理后续rewrite指令集,然后对当前重写的新URI在rewrite指令集上重新查找。
    break 停止处理后续rewrite指令集,并不在重新查找,但是当前location内剩余非rewrite语句和location外的的非rewrite语句可以执行。
    redirect 如果replacement不是以http:// 或https://开始,返回302临时重定向
    permant 返回301永久重定向
    最终完整的重定向URL包括请求scheme(http://,https://等),请求的servernameinredirect和 portin_redirec三部分 ,说白了也就是http协议 域名 端口三部分组成。

    rewrite实例

     server {
         ...
         rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 last;
         rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra last;
         return 403;
         ...
     }
    

    如果这些rewrite放到 “/download/” location如下所示, 那么应使用break而不是last , 使用last将循环10次匹配,然后返回 500错误:

     location /download/ {
         rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 break;
         rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra break;
         return 403;
     }
    

    对于重写后的URL(replacement)包含原请求的请求参数,原URL的?后的内容。如果不想带原请求的参数 ,可以在replacement后加一个问号。如下,我们加了一个自定义的参数user=$1,然后在结尾处放了一个问号?,把原请的参数去掉。

    rewrite ^/users/(.*)$ /show?user=$1? last;

    如果正则表达regex式中包含 “}” 或 “;”, 那么整个表达式需要用双引号或单引号包围.

    rewrite_log指令

    语法:rewrite_log on|off;

    默认值:rewrite_log off;

    作用域:http,server,location,if

    开启或关闭以notice级别打印rewrite处理日志到error log文件。

    nginx打开rewrite log例子

    rewrite_log on;  
    error_log logs/xxx.error.log notice;  
    
    1. 打开rewrite on
    2. 把error log的级别调整到 notice

    set指令

    语法:set variable value;

    默认值:none

    作用域:server,location,if

    定义一个变量并赋值,值可以是文本,变量或者文本变量混合体。

    uninitializedvariablewarn指令

    语法:uninitializedvariablewarn on | off;

    默认值:uninitializedvariablewarn on

    作用域:http,server,location,if

    控制是否输出为初始化的变量到日志

    ]]>
    <![CDATA[贵知么]]>http://www.guizhi.me/zi-bei-yu-chao-yue/48b61efb-6422-4fc4-9781-c001b0685ac7Sun, 07 Jun 2015 15:44:00 GMT

    本周末几乎没怎么出门,耐心的读完了新入手的心理学书籍《自卑与超越》,书中的一些观点虽然有点极端,但是作者对于心理问题的分析和研究,还是让人信服的。

    职业、交际和两性问题是对人们造成困扰的三大问题,而作者对人生意义的思考,对童年记忆的探索,对梦的解析和对家庭、学校、个人与群体、婚姻和两性的深究,很好的指明了解决这些问题的方法:担负起自己的职责,也就意味着以合作的态度承担起解决人生三大问题的责任

    随手记了部分笔记:

    第一章:生活的意义

  • 个体心理学发现人类的所有问题都可归于三类:职业、交际和两性问题。每个人对生活意义作出各自的理解时,都精准地揭示出人民对这三个问题的不同回应。
  • 当我们真正了解了人生的意义,就找到了打开人性格的钥匙。常常有人说性格是无法改变的,这是因为他们还没有找到改变的方法。正如我们所见,如果找不到错误的根源,我们的任何治疗方法都不会有效,而唯一有效的方法就是培养他们的勇气和与人合作的精神。
  • 第二章:心灵和肉体

  • 我们不能对于某一个病人或者某一种性格的人进行单独治疗。我们必须了解这个人在对人生进行选择时的错误思想、对人生的错误解读、自身的经历、他对周围环境的错误看法等
  • 第三章:自卑感与优越感

  • 医生告诉病人:自卑没有任何益处可言,那么此人的自卑感反而会越来越重,根本达不到克服的目的。我们必须找到他人生态度的缺点所在,并在他缺乏勇气之时给他以鼓励
  • 一个人只要确定了自己所追求的目标,他的人生态度就会为此服务,所有的行动也会与这一目标相一致。个人的行为和习惯不管正确与否,也都会遵循这一目标。
  • 第四章:早期的记忆

  • 早期的记忆能够说明一个人的人生观,这是其人生态度的雏形。它可以让我们看出他是以什么作为是自身发展的出发点的
  • 第五章:梦

  • 人生的态度是梦的制造者,它可以激起人的某种情感。我们发现,一个人的性格和日常行为同样会出现在梦中。不管是否做梦,我们处理问题的方法总是不变的,但是梦却为我们的人生态度提供了支持和维护
  • 梦是一座桥梁,它联系着现实的生活和我们对人生的态度,人生态度本就应该直接与现实衔接,并不需要我们的强化。梦的形式多种多样,并且每一种梦境都可以揭示出我们在面对某种情景时需要强化人生态度的哪一方面
  • 第六章:家庭的影响

  • 在我对一些成人的案例进行研究时,会从中发现很多童年时期的烙印,并且这些事情会让他们终生不忘。家庭地位就是其中之一,这是他们永远无法忘记的。而成长中的困难也大都由家庭天博SPORTS的僵化和合作精神的缺乏引起
  • 第七章:学校的影响

  • 教育中的最大问题不是孩子行为上的限制,而是思想中的限制。如果孩子知道了自己智商测试的结果很低,就会越来越失望,就会以为自己永远不会有大的成就。在教育过程中,我们应该让孩子增加对自己的兴趣和自信,并消除他心中给自己的束缚
  • 在学校里常常有这样一种现象,优等生、中等生和劣等生的成绩、名次总是在自己的范围内徘徊不变。其实这并不是什么天生遗传的因素所致,而是因为他们的思想束缚了自己的能力,他们以为自己就是这样的人,永不能进步,也永不会后退
  • 其实,身体的缺陷并不会影响智力的发展,只会影响到他们对残疾和身体发育的看法。所以,当一个孩子在身体上有缺陷的时候,我们一定要让他知道这并不会影响其智力和能力的发展,这一点极其重要。之前我已经提到,身体的残疾可能会成为激发他潜能的巨大动力,也可能会成为阻碍他发展的最大障碍
  • 事实上,“善”与“恶”与其他性格一样,都是在特定环境下产生的。他们是人类在特定的环境中相互产生的结果,其实这是对另一种行为的判断:此人的行为是“为他人着想”,还是“只为自己着想”。孩子在刚刚出生的时候,根本没有这方面的意识。在出生后,他有选择发展方向的潜能,而且在以后成长的过程中周围的环境和人生的态度会对他的选择起到很大的作用,促使他选择怎样的方法,而教育在其中具有很大的影响
  • 第八章:青春期的引导

  • 在人的一生中,常常会经历一些人生的转折点,这些转折点对我们的成长有着决定性的意义。比如,青春期,这是一个被人们公认的不寻常发育期,虽然这并没有任何科学依据。其实,更年期也与此相似。然而,这些阶段只是人生中很短暂的转折,它不会让我们有太大的变化,也并没有什么特别之处。重要的是,人们想在这个阶段获得什么,这个阶段会有怎样的意义,以及面对这一阶段的态度
  • 第九章:犯罪及预防

  • 之前我已经论述过关于孩子在成长过程中的危险情况,如今我想再重复一次。因为只有认清了他们犯罪的原因,才能帮助他们走上正确的道路,所以我们一定要重申这一问题。容易犯罪的儿童一共有三类:一是身体残疾的人,二是受宠的人,三是被忽视冷落的人
  • 罪犯一般可分为两种类型:一种是他们知道社会中需要与人合作,相互关心,可是自己却从不去这样做,所以这样的人认为所有的人都是敌人,认为自己被社会孤立,得不到任何人的赏识;另一种是被惯坏的孩子
  • 其实,罪犯和普通人一样,都想取得一种成功,为自己争得一个有利的地位。但是,他们的目标却是不同的。罪犯的目的总是争取自己的利益,他们所希望达到的目标对别人没有任何益处,他们还时时逃避与人合作
  • 第十章:职业问题

  • 我们在这个地球上,依赖着土地、矿物、空气、水等物质而生存,所以解决地球带给我们的问题就成了我们人生中的重要一课
  • 要想解决好我们的职业问题,必须先处理好另一个问题——人际交往的问题。联系人类的第二个因素就是要承认这样的事实:我们都是人类的一员,要想生存就必须和他人发生联系···我们必须联想到其他人的利益,要是自己适应他人、关爱他人。解决这一问题的最佳方法就是形成友谊、培养责任感并与他人合作
  • 第十一章:个体与社会群体

  • 从妄想症和忧郁症患者的身上我们可以更明显地看到与人疏远的现象。妄想症病人会抱怨所有的人,他认为别人都联合起来与自己对抗。抑郁症的患者则过于自责
  • 家庭或学校是培养孩子合作精神的场所。对于阻碍孩子成长的因素我们之前已经说过。也许社会责任感并不是遗传所致,但是社会责任感的潜能却和遗传有着密切的联系。影响这种潜力发展的因素有:父母培养孩子的技巧、对孩子的关心程度、孩子对周围环境的判断等
  • 担负起自己的职责,也就意味着以合作的态度承担起解决人生三大问题的责任。我们对一个人所提出的最高要求和给与其的最高荣誉就是:在工作中,是以为好员工;在朋友中,是一个好伙伴;在爱情和婚姻中,是一个好伴侣。总之,一个人应该证明自己是人类忠实的朋友
  • 第十二章:爱情与婚姻

  • 在婚姻中只顾及自己的利益是对婚姻的最大忽视。如果存有这样的思想,那么,此人就会整天想到如何从生活中寻求快乐和刺激,而不想收到婚姻的任何约束和限制,更不会想到对方的生活是否快乐和舒心。这是对婚姻的极大破坏,这样的婚姻不会长久,终究会葬送在自己手中,这种办法不可模仿。所以,我们在恋爱中,不能只想着享乐而不去承担责任
  • 有些人对待爱情从不专一,而是想和几个人同时恋爱,他们在多种恋爱中摇摆不定,更不知道自己的责任是什么。这样的爱情只会是一场空
  • 题外话

    有段时间没有这样静心读书了,工作中的烦扰和内心的躁动,导致看书的时候总是翻几页就放下了。这本书之所以能读完,除了强迫自己读书外,还有个重要原因就是作者不是为了讲道理而讲道理,而是从自己多年从医的经验和案例来支持自己的观点。通篇下来,就像是读了很多个故事,书里的知识也容易吸收。有时间的同学,推荐一读。

    ]]>
    <![CDATA[贵知么]]>http://www.guizhi.me/elasticsearch-cmd/22de02c1-4367-43b3-8907-839bcb1fc50bThu, 04 Jun 2015 07:36:01 GMT

    最近在读Elasticsearch的书,准备把英文版翻译出来,此处先把看书中用到的一些常用查询列出来,以备以后查询。

    搜索方法:

  • /_search 查询所有索引和类型
  • /gb/_search 查询gb索引的全部类型
  • /gb,us/_search 查询gb和us索引的全部类型
  • /g,u/_search 查询以g或者u开头的索引的全部类型
  • /gb/user/_search 查询gb索引的user类型
  • /gb,us/user,tweet/_search 查询gb和us索引的user和tweet类型
  • /all/user,tweet/search 查询全部索引中的user和tweet类型
  • 测试分词

  • GET /_analyze?analyzer=standard
  • 查看gb索引中tweet类型的mapping:

  • GET /gb/_mapping/tweet
  • 查询和过滤

  • 查询是按照搜索条件和匹配度获取结果,而过滤更关注某个字段是否匹配相应的过滤条件
  • 性能方面,过滤能更快的计算结果,而且过滤返回的结果可以缓存以便在子查询中用,而查询由于是按照相关度匹配,结果是不能缓存的
  • 使用条件:通常来说,如果是进行全文检索或者某个条件会影响匹配度的话,就用查询语句,其他情况下都可以用过滤语句
  • 重要的查询和过滤

  • term过滤:用精确条件过滤字段,可以是数字、日期、布尔型和未经处理的字符串
  • { "term": { "age": 26 }}
    { "term": { "date": "2014-09-01" }}
    { "term": { "public": true }}
    { "term": { "tag": "full_text" }}
    
  • terms过滤:可以同时指定多个过滤用的匹配字段 { "terms": { "tag": [ "search", "full_text", "nosql" ] }}

  • ranger过滤:按照ranger指定的范围进行过滤

  • {
        "range": {
            "age": {
                "gte": 20,
                "lt": 30
            }
        }
    }
    可以接受的判断条件:
    gt:greater than  
    gte:greater than or equal to  
    lt:less than  
    lte:  
    > less than or equal to
    

    未完待续。。。

    ]]>