一年工作总结
时间总是在人不经意间流过,不经意间已经工作了一年,小小总结一下。
福建联通,这是我入职的第一家公司。在私企实习过,也在央企工作过,对于二者的区别我深有感触。如果在央企没有资源关系,还是慎重,其它国企央企是不是这样我不知道,但是福建联通确实是这个样子,其它国企估计也八九不离十。
在这一年多来,主要做了两个项目。第一个项目基本上可以理解为胎死腹中,第二个项目是社区项目,我勉强算是项目中的核心开发,但是在产品和运营的摧残下,这个项目现在也是做的乱七八糟,其他核心开发也大多提桶跑路,而我也幸运的在年底完成了跑路的目标。
2020年是不幸的一年,今年发生的各种事情让我心烦意乱。
首先是受疫情的影响,导致团队配合不佳,当然缺乏经验也是一部分原因
其次产品各种不专业,各种改需求让我有种提刀的冲动
随后的几个月里,公司降了薪,大约降了1k左右,勉强达到征税点,每个月差不多交了几毛的税
然后就是我对自己施加的压力。也许在国企很舒服,但迫于生活压力和不甘平凡的想法,我给自己定下了跳槽的目标。对于本次跳槽,我准备了差不多半年,每天坚持至少刷一道 leetcode,然后剩下得时间用来工作和学习。这里不得不感谢 ...
SpringCloud整合Seata
一、Seata-Server1.1 下载官方下载地址 :https://seata.io/zh-cn/blog/download.html
1.2 启动Seata-Server 是开箱即用的,启动 bin 目录下的 seata-server.bat 或者 seata-server.sh 即可
另外可以根据需求添加一些参数,输入 seata-server.sh --help 即可查看参数
12345678910111213Options: --host, -h 注册到注册中心的ip --port, -p 监听的端口,默认8091 --storeMode, -m 日志存储模式:文件、数据库 默认文件 --serverNode, -n 服务节点id,默认通过雪花算法生成 --seataEnv, -e 用于多配置隔离的环境名称 --help
seata-server 的默认启动端口是8091,如果我们要指定18091,只需 seata-server.sh -p 18091 即可
二、Spring Cloud 服务搭建2. ...
Gossip
介绍Gossip 是一种去中心化、保证最终一致性的分布式协议,其英文原意是 流言蜚语。它的作用就像其名字一样,流言一传十,十传百。Gossip 在 P2P网络和分布式系统中应用广泛 ,如人们熟知的 Bitcoin、Redis Cluster、Consul等
原理在若干个可以相互通信的节点中,当某个种子节点需要将其数据和状态同步到其它节点时,它会在周围的节点中随机选择几个节点散播消息,收到消息的其它节点也会重复该动作,直至最终所有的网络节点都受到了消息 。这个过程可能需要一定的时间,由于不能保证某个时刻所有节点都收到消息,但是理论上最终所有节点都会收到消息,因此它是一个最终一致性协议。 (网上盗了个图)
通信模式Push节点 A 将数据已经对应的版本号发送给节点 B,B 节点更新 A 中比自己新的数据
Pull节点 A 将当前的数据版本发给节点 B,节点 B 将高于这个版本的数据返回给 A,A节点更新本地数据
Push/Pull结合 Push 和 Pull
A 将当前数据版本发送给 B
B 返回新数据,A更新
A 再将比 B 新的数据发送给 B,B更新
特点优势
扩展性高: ...
Elasticsearch-IKAnalyzer
Elasticsearch中内置了几种分词器:
Standard Analyzer - 默认分词器,按词切分,小写处理
Simple Analyzer - 按照非字母切分(符号被过滤), 小写处理
Stop Analyzer - 小写处理,停用词过滤(the,a,is)
Whitespace Analyzer - 按照空格切分,不转小写
Keyword Analyzer - 不分词,直接将输入当作输出
Patter Analyzer - 正则表达式,默认\W+(非字符分割)
Language - 提供了30多种常见语言的分词器,不支持中文
Customer Analyzer 自定义分词器
而倒排索引的过程就是将文档通过分词器分成一个个的 Term,每个单词指向包含这个 Term 的文档集合。
尽管 ES 提供了这么多的分词器,但是对于中文的支持却不尽人意,默认的分词器会将每一个字看成一个词。
IKAnalyzer 介绍IKAnalyzer 是免费开源的java分词器,目前比较流行的中文分词器之一,简单,稳定,想要特别好的效果,需要自行维护词库,支持自定义词典。
安装:将下载好的 ...
Redis-replicate
Redis的复制功能分为同步和命令传播两个操作:
同步:全量更新,将从服务器的数据库状态更新至主服务器当前所处的数据库状态
命令传播:增量更新,用于在主服务器的数据库状态被修改,导致主从服务器的数据库状态出现不一致时,让主从服务器的数据库重新回到一致状态。
同步当增加一个从节点时,需要客户端向从服务器发送 SLAVEOF 命令,要求从服务器复制主服务器。此时从服务器首先需要执行同步操作,将数据库的状态更新至主服务器当前所处的数据库状态
从服务器对主服务器的同步操作需要通过向主服务器发送SYNC命令来完成,以下是SYNC命令的执行步骤:
从服务器向主服务器发送SYNC命令。
收到SYNC命令的主服务器执行BGSAVE命令,在后台生成一个RDB文件,并使用一个缓冲区记录从现在开始执行的所有写命令。
当主服务器的BGSAVE命令执行完毕时,主服务器会将BGSAVE命令生成的RDB文件发送给从服务器,从服务器接收并载入这个RDB文件,将自己的数据库状态更新至主服务器执行BGSAVE命令时的数据库状态。
主服务器将记录在缓冲区里面的所有写命令发送给从服务器,从服务器执行这些写命令,将自己的 ...
Redis数据结构-quicklist
在早期的 Redis 版本中,数据量较小时使用 ziplist 作为列表的数据结构,数据量较大时则使用 linkedlist。但考虑到 ziplist 需要频繁的重新分配内存,而 linkedlist 的指针需要额外占用一定的内存(pre 和 next 占据 16 字节),并且由于内存不连续的缘故,更容易产生内存碎片。因此3.2版本之后统一使用 quicklist 作为 列表的数据结构。
结构quicklist 是 ziplist 和 linkedlist 的一种结合体,中和了两种数据结构的缺点。
快速列表 quicklist
12345678typedef struct quicklist { quicklistNode *head; quicklistNode *tail; unsigned long count; /* total count of all entries in all ziplists */ unsigned long len; /* number of quicklistNodes */ ...
Redis数据结构-ziplist
压缩列表(ziplist)是列表或字典的底层实现之一。当一个列表只包含少量列表项,并且值的长度较短,或者当一个字典的键值对较少,并且键和值都是较短的字符串,那么Redis就会选择压缩列表作为列表和字典的底层实现
123456789127.0.0.1:6379> LPUSH list y x d(integer) 3127.0.0.1:6379> OBJECT ENCODING list"ziplist"127.0.0.1:6379> HSET person "name" "Jack"(integer) 1127.0.0.1:6379> OBJECT ENCODING person"ziplist"
压缩列表构成压缩列表是为了节约内存儿开发的,是由一系列特殊编码的连续内存块组成的顺序性数据结构。一个压缩列表可以包含若干个节点(entry),每个节点可以保存一个字节数组或者一个整数值
上图是压缩列表的构成
属性
类型
长度
用途
zlbytes
uint32_t
...
Redis数据结构-intset
整数集合(intset)是集合键的底层实现之一,当一个集合只包含整数值元素,并且这个集合的元素数量不多时,Redis就会使用整数集合作为集合键的底层实现。
1234127.0.0.1:6379> SADD nums 1 2 3(integer) 3127.0.0.1:6379> OBJECT ENCODING nums"intset"
定义12345678typedef struct intset { // 编码方式 uint32_t encoding; // 集合包含的元素数量 uint32_t length; // 保存元素的数组 int8_t contents[];} intset;
length:intset 集合包含的元素数量
contents:保存的元素数组。尽管声明的类型是 int8_t,但实际上 contents 数组的真正类型取决于 encoding 属性的值
如果 encoding 的值为 INTSET_ENC_INT16,那么数组中的每个元素都是 int16_t 类型 ...
Redis数据结构-跳表
跳表是 有序集合的底层实现之一
定义跳表节点 zskiplistNode123456789101112131415typedef struct zskiplistNode { // 成员对象 robj *obj; // 分值 double score; // 后退指针 struct zskiplistNode *backward; // 层 struct zskiplistLevel { // 前进指针 struct zskiplistNode *forward; // 跨度 unsigned int span; } level[];} zskiplistNode;
robj:保存的对象
score:对象的分值
backward:指向前一个节点的指针
level:层。每次创建一个跳表节点时,程序会根据幂次定律(越大的数字出现的概率越小)随机生成一个介于1~32之间的值作为 level 数组的大小,这个大小就是层的高度
level.fo ...
Redis数据结构-字典
定义hash表1234567891011typedef struct dictht { // 哈希表数组 dictEntry **table; // 哈希表大小 unsigned long size; // 哈希表大小掩码,用于计算索引值 // 总是等于 size - 1 unsigned long sizemask; // 该哈希表已有节点的数量 unsigned long used;} dictht;
hash表节点123456789101112typedef struct dictEntry { // 键 void *key; // 值 union { void *val; uint64_t u64; int64_t s64; } v; // 指向下个哈希表节点,形成链表 struct dictEntry *next;} dictEntry;
Redis 中对hash表的实现类似于 ...