快乐冲浪与生活

多体验、多体会、多体悟

0%

数据库是应用的数据存储中心,请求增多和数据量增大都会对数据库造成严重的影响,导致数据库服务性能偏低。所以归纳了个别优化点,后续有看到新的内容也会追加。

在本文开头,贴一段百科对卡方检验基本原理的介绍:

卡方检验就是统计样本的实际观测值与理论推断值之间的偏离程度,实际观测值与理论推断值之间的偏离程度就决定卡方值的大小,如果卡方值越大,二者偏差程度越大;反之,二者偏差越小;若两个值完全相等时,卡方值就为 0,表明理论值完全符合。

在网络或 I/O 连接中,可以使用 net/rpc 包实现对一个对象的导出方法的调用,即远程过程调用(Remote Procedure Call,RPC)。通过向 RPC 服务注册一个对象,使其可被远程调用,进而实现一些复杂的业务逻辑。

Protocol Buffer(Protobuf) 是一种高效的数据结构序列化的机制,同时也是一种结构化数据的存储格式。

序列化与反序列化

  • 序列化:将数据结构或对象转换成二进制串的过程;
  • 反序列化:将序列化后的二进制串转换成数据结构或对象的过程;

语法

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
/*
* 语法
*/

/*
* 指定 Protobuf 解析使用的版本,可以是 proto3 或 proto2
*/
syntax = "proto3";

/*
* message 定义中的每一个字段都有一个唯一标识,该标识用于在二进制格式中识别字段
* 字段的标识一旦使用就不要进行修改
* 当标识为 1 到 15 时,使用一个字节进行编码,字节信息中包含字段的标识以及类型
* 当标识为 16 到 2047 时,使用两个字节进行编码
* Field numbers in the range 16 through 2047 take two bytes. So you should reserve the numbers 1 through 15 for very frequently occurring message elements.
* 在编码的过程中,标识使用应当留有余地,便于将来扩展
* 标识最小的值是 1,最大的值为 2^29-1
* 不能使用的标识为 19000 到 19999
* 不能再使用已经被 reserved 的标识
*/

/*
定义 message 的语法:
    message ${MessageName} {
        ${Scalar Value Type} ${FieldName1} = ${Tag Number1};
                .
                .
                .
        ${Scalar Value Type} ${FieldNameN} = ${Tag NumberN};
    }
*/

message MessageTypes {
    /*
    * 标量值类型
    */
    string stringType = 1; // 字符串可以是 UTF-8 编码,也可以是一个 7 比特的 ASCII 字符,默认为“”
    // 数值类型,默认为 0
    int32 int32Type = 2; // 使用变量长度进行编码,如果是负数,请使用 sint32
    int64 int64Type = 3; // 使用变量长度进行编码,如果是负数,请使用 sint64
    uint32 uInt32Type = 4; // 使用变量长度进行编码
    uint64 uInt64Type = 5; // 使用变量长度进行编码
    sint32 sInt32Type = 6; // 使用变量长度进行编码,处理负数更高效
    sint64 sInt64Type = 7; // 使用变量长度进行编码,处理负数更高效

    fixed32 fixed32Type = 8; // 变量总是占 4 个字节,当值大于 2^28 时,比使用 uint32 更有效率
    fixed64 fixed64Type = 9; // 变量总是占 8 个字节,当值大于 2^56 时,比使用 uint64 更有效率

    sfixed32 sfixed32Type = 10; // 变量总是占 4 个字节
    sfixed64 sfixed64Type = 11; // 变量总是占 8 个字节

    bool boolType = 12; // 布尔类型,默认为 false

    bytes bytesType = 13; // 可包含任意长度的字节数组,默认为长度为 0 的字节数组

    double doubleType = 14;
    float floatType = 15;

    enum Week {
        UNDEFINED = 0; // 第 1 个值
        SUNDAY = 1;
        MONDAY = 2;
        TUESDAY = 3;
        WEDNESDAY = 4;
        THURSDAY = 5;
        FRIDAY = 6;
        SATURDAY = 7;
    }
    Week wkDayType = 16;

    /*
    * 定义标量值类型的集合
    * Syntax: repeated ${ScalarType} ${name} = TagValue
    */
    repeated string listOfString = 17; // List[String]
}

/*
* 在其它 message 中使用已定义的 message
*/
message Person {
    string fname = 1;
    string sname = 2;
}

message City {
    Person p = 1;
}

/*
* 嵌套的 message 定义
*/
message NestedMessages {
    message FirstLevelNestedMessage {
        string firstString = 1;
        message SecondLevelNestedMessage {
            string secondString = 2;
        }
    }
    FirstLevelNestedMessage msg = 1;
    FirstLevelNestedMessage.SecondLevelNestedMessage msg2 = 2;
}

/*
* .proto 文件的引入
*/

// one.proto
// message One {
//     string oneMsg = 1;
// }

// two.proto
//  import "myproject/one.proto"
//  message Two {
//       string twoMsg = 2;
//  }


/*
* 高级知识点
*/

/*
* message 发生改变时,永远不要修改或使用已经删除字段的标识
*/

/*
* 使用 reserved 保留已删除的标识或字段名
*/
message ReservedMessage {
    reserved 0, 1, 2, 3 to 10; // 这里的标识不可再使用
    reserved "firstMsg", "secondMsg", "thirdMsg"; // 这里的字段名不可再使用
}

/*
* 引用其它文件中定义的 message
*/
import "google/protobuf/any.proto";
message AnySampleMessage {
    repeated google.protobuf.Any.details = 1;
}

/*
*  OneOf
* 相同于 union,只能是其中一个
* 使用 oneof 的 message 不能被 repeated
*/
message OneOfMessage {
    oneof msg {
        string fname = 1;
        string sname = 2;
    };
}

/*
* Maps
* map 字段不能被 repeated
*/
message MessageWithMaps {
    map<string, string> mapOfMessages = 1;
}


/*
* Packages
* 声明一个包名,防止同名的 message
* 语法:
    package ${packageName};

    访问方式
    ${packageName}.${messageName} = ${tagNumber};
*/

/*
* 在 RPC 系统中使用,其中可以定义方法
*/
message SearchRequest {
    string queryString = 1;
}

message SearchResponse {
    string queryResponse = 1;
}
service SearchService {
    rpc Search (SearchRequest) returns (SearchResponse);
}

数据类型

Protobuf 内置的数据类型以及在 Go 中对应的数据类型:

Redis 集群是基于“主从复制”特性之上的分布式 Redis 版本,可提供高并发、高性能、高可用的数据库服务。Redis 集群突破了单台服务器的内存局限,集群中的每一个节点都可以存储数据,同时维护着 “key-node” 的映射表。本文记录了 3 主 3 从的 Redis 集群的配置过程,主要内容包括:

  1. Redis 集群的配置过程;
  2. 集群相关命令;
  3. Go 存取集群数据;

每当有快速绘制图表的需求时,第一时间反应到的肯定是 Matplotlib,因为其官方提供了详细的 API 文档及示例。但是每次在编码时,总是时不时地需要查看文档,不利用于可视化快速成型。所以在本文中罗列一些 bar 图的快速实现,方便 Ctrl+C/V。