zoukankan      html  css  js  c++  java
  • 3.30一周拾遗

    一些杂项的积累

    PHP配置文件找不到怎么破

    使用PHP的phpinfo();来进行查找

    1
    2
    3
    4
    5
    6
    // PHP CLI

    php -r "phpinfo()" | grep "Loaded Configuration File" && "Configuration FIle";
    // 但是找不到Loaded怎么办 或者Loaded出来是 none
    // 一般是新的PHP没有将PHP.ini放到指定位置
    // 原始的PHPINI可以从源码包找到 php.ini.production cp过去就可以了

    Segment Fault 段错误 怎么进行debug

    首先Linux系统默认是不dump Core的 需要设置unlimit 让系统对Fault的Core进行Dump

    1
    ulimit -c unlimited

    就可以将出错时的内核文件进行输出 .Core.XXXX文件

    然后 yum install gdb 然后

    1
    gdb php core.XXXX 进行分析 可以找出出错的行数

    [未解决问题] 对PHP扩展开发的时候 return_value_used变量不能用

    提示未定义 而且在源码包内对PHP_FUNCTION的宏定义中找不到这个变量 难道是PHP7更新之后自动可以GC的缘故?

    Redis 内存数据库数据结构整理

    SDS (动态字符串)

    1
    2
    3
    4
    5
    6
    7
    8
    struct sdshdr {
    int len; // SDS遵循C字符串以 ''为结尾的规则 但是 末尾的空不计算在len内
    // 这样获取的长度的速度就是O(1)
    // 还可以杜绝缓冲区溢出 在操作之前可以先看一下是否有足够的空间 如果没有就malloc C语言本身不记录string的长度
    // 减少修改字符串带来的内存重新分配次数
    int free;
    char buf[];
    }

    SDS使用空间预分配和惰性空间释放策略 提升性能

    空间与分配:

    如果小于1MB

    预分配相同的size

    如果大于1MB

    预分配1MB的size

    二进制安全

    避免使用 导致字符串截断

    Redis在读取字符串的时候是依据 SDS结构之内的len进行读取 有多少读多少

    对比C字符串的优点

    • O(1)获取长度复杂度

    • 杜绝缓冲区溢出

    • 减少修改字符串带来的内存重新分配次数

    • 二进制安全

    链表

    链表提供高效的结点重排能力

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    typedef struct listNode {
    struct listNode *prev;
    struct listNode *next;
    void *value;
    }listNode;

    typedef struct list {
    listNode *head;
    listNode *tail;
    unsigned long len;
    void *(*dup)(void *ptr)
    void *(*free)(void *ptr)
    int (*match)(void *ptr)
    }list;

    API时间复杂度

    • 返回值所在的index O(N)

    • 返回index所在的值 O(N)

    • 删除指定结点O(N)

    • 复制一个副本O(N)

    • 释放链表 O(N)

    字典—使用哈希表实现

    又被称为符号表、关联数组、或者映射

    字典使用哈希表实现

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    typedef struct dictEntry{ // 哈希表结点
    void *key;

    union {
    // 同样采用联合体来节约内存
    void *val;
    uint64 _tu64;
    int64 _ts64;
    }v;
    struct dictEntry *next;
    }

    typedef struct dict{
    dictType *type;
    void *privdata;

    dictht ht[2];

    // 平时数据会存在第一个HashTable 当进行rehash的时候使用第二个HashTable

    }

    解决HashTable的方法

    有链接法和开放寻址法

    链接法就是当发生index冲突的时候,在index处形成链表,新插入的在前面

    开放寻址法就是发生index冲突的时候,自动向下寻址

    HashTable的API时间复杂度

    • 向HashTable加新的元素 O(1)

    • 释放HashTable O(N)

    跳跃表-有序set的实现之一

    跳跃表支持平均O(logN)、最坏O(N)的复杂度查找

    。。。说实话跳跃表没咋看懂

    跳跃表API时间复杂度

    • 寻找 删除 返回排位 平均O(logN) 最坏O(N)

    • 给定一个范围 如果有一个在范围之内 就可以 O(1)

    整数集合 set的单纯整数实现

    1
    2
    3
    4
    5
    6
    7
    typedef struct intset{
    uint32_t encoding;

    uint32_t length;

    int 8_t content[]; // 不仅会保存int8的数据 保存类型取决于encoding;
    }intset;

    整数集合API时间复杂度

    • 添加新元素复杂度为O(N) // 因为每次操作都可能引起升级 所以会大一点

    • 整数集合不会降级 保证性能

    压缩列表 列表键和哈希键的实现之一

    压缩列表是连续内存构成的顺序结构

    [zlbytes, zltail, zllen, entry1, entry2, …, zlend];

    zlbytes: 表示压缩列表总长度

    zltail: 压缩列表尾部指针P

    zllen: 压缩列表数据个数

    通过以上三个参数 可以分别计算出每个数据点的指针 从尾部开始计算即可

    压缩列表结点构成

    [previous_entry_length, encoding, content]

    pre记录了前一个结点的长度

    可以根据当前结点的起始地址计算出前一个结点的起始地址指针

    压缩列表API时间复杂度

    • 创建一个包含指定结点的压缩列表 O(N) 最坏O(N*N)

    • 插入结点 O(N) 最坏O(N*N)

    • 返回index的结点O(N)

    • 找到包含指定值的 O(N) 最坏O(N*N)

    • 删除指定结点 O(N) 最坏O(N*N)

    • 返回结点数量 结点数量小于65535 O(1) 最坏O(N*N)

    REDIS对象以及实现

    Redis_string

    int raw embstr;

    redis_list

    ziplist hashtable intlist

    redis_hash

    ziplist hashtable

    redis_set

    intset hashtable

    reids_zset

    ziplist skiplist

  • 相关阅读:
    python爬虫统计上证指数周、月涨跌现象
    python每日一题:采用正则表达式,beautifulsoap,xpath爬取网站数据
    谈股市与月份的关系
    python之正则表达式
    python每日一题:使用代理服务器爬虫
    python之cookie使用
    python每日一题:爬虫入门之利用xpath查找网页元素节点
    python每日一题:制作网页,与女朋友的点点滴滴
    【Java基础】Java11 新特性
    【Java基础】Java10 新特性
  • 原文地址:https://www.cnblogs.com/xiaoerli520/p/9624272.html
Copyright © 2011-2022 走看看