<?xml version="1.0" encoding="utf-8" ?><rss version="2.0"><channel><title><![CDATA[werflychen的专栏]]></title><description><![CDATA[]]></description><link>https://blog.csdn.net/dreamvyps</link><language>zh-cn</language><generator>https://blog.csdn.net/</generator><copyright><![CDATA[Copyright &copy; dreamvyps]]></copyright><item><title><![CDATA[paxos协议的理解及证明推导]]></title><link>https://blog.csdn.net/dreamvyps/article/details/106804907</link><guid>https://blog.csdn.net/dreamvyps/article/details/106804907</guid><author>dreamvyps</author><pubDate>Wed, 17 Jun 2020 12:43:31 +0800</pubDate><description><![CDATA[文章目录导读历史解决的问题理论分析只有一个Acceptor两个Acceptor结果到原因的推进如何预测未来理论到工程的缺陷根本问题在哪里算法提出FAQ
导读
paxos算法为什么是这么设计？Paxos协议为什么是两阶段？为什么第一阶段的时候需要取一个最大编号？本文尝试从一个简单场景一步步构建出理论框架并转化为可工程化的算法
历史
paxos从诞生至今已经近30年，从开始工业化至今也有10来年历史，但至今仍然难以理解。本文尝试从最简单的场景入手，一步步尝试去推导及理解理论约束中的各个细节点，其中不免有理解不对]]></description><category></category></item><item><title><![CDATA[我对字符编码的理解]]></title><link>https://blog.csdn.net/dreamvyps/article/details/101727855</link><guid>https://blog.csdn.net/dreamvyps/article/details/101727855</guid><author>dreamvyps</author><pubDate>Mon, 30 Sep 2019 00:04:41 +0800</pubDate><description><![CDATA[背景
开发这些年，一直有遇到字符编码这些问题，能一直在解决，但始终没有做到通透的水平，现在想尝试做一下归纳与总结。尝试从一个完全不懂的小白的角度，把问题讲清楚。
问题

为什么会存在字符编码？
gbk、unicode是什么？
UTF-8、UTF-16等与UNICODE什么关系？
mysql里面存储的是数据，编码是解释层面的概念，而存储的时候，理论上都只是二进制而已，为什么存储的时候，需要指定什么类...]]></description><category></category></item><item><title><![CDATA[unique_ptr实现Impl模式时遇到的问题分析]]></title><link>https://blog.csdn.net/dreamvyps/article/details/98724673</link><guid>https://blog.csdn.net/dreamvyps/article/details/98724673</guid><author>dreamvyps</author><pubDate>Wed, 07 Aug 2019 10:43:04 +0800</pubDate><description><![CDATA[背景
对于类的设计与定义，我们习惯上使用“指向实现的指针”， 或者叫PImpl。例如下面的类：
// widget.h（接口）
class widget {
    // 公开成员
private:
    struct impl;  // 实现类的前置声明
    impl* ptr;
};

// widget.cpp（实现）
struct widget::impl {
   // 实现细节
...]]></description><category></category></item><item><title><![CDATA[leveldb设计思想学习总结]]></title><link>https://blog.csdn.net/dreamvyps/article/details/97963070</link><guid>https://blog.csdn.net/dreamvyps/article/details/97963070</guid><author>dreamvyps</author><pubDate>Wed, 31 Jul 2019 21:29:56 +0800</pubDate><description><![CDATA[leveldb的价值
每一类组件，都有它特定擅长的应用场景。在leveldb出世之前，我们对于nosql下的kv存储，我们有redis方案存储。然而redis数据存储的上限，即是机器内存。内存在目前阶段，算是比较昂贵。而leveldb的出现，提供了一个可以以机器磁盘为容量上限，支持持久化的写操作的同时，做到写速度较快，读速度也不慢的一个解决方案。
leveldb如何解决问题
leveldb面对的问...]]></description><category></category></item><item><title><![CDATA[c++中函数返回时的RVO机制和std::move的理解]]></title><link>https://blog.csdn.net/dreamvyps/article/details/97394411</link><guid>https://blog.csdn.net/dreamvyps/article/details/97394411</guid><author>dreamvyps</author><pubDate>Sun, 28 Jul 2019 09:26:21 +0800</pubDate><description><![CDATA[常见问题
RVO和std::move都能减少对象拷贝时的开销，那他们到底是什么与什么的关系叫？
talk is cheap, show me the code!
如下代码所示：test_1.cpp
场景一【函数返回非RVO】
class Obj {
public:
    Obj() {
        printf("construct \n");
    }   

    ~Obj() {
...]]></description><category></category></item><item><title><![CDATA[fork生成子进程与执行exec子进程的区别]]></title><link>https://blog.csdn.net/dreamvyps/article/details/96283032</link><guid>https://blog.csdn.net/dreamvyps/article/details/96283032</guid><author>dreamvyps</author><pubDate>Wed, 17 Jul 2019 12:15:35 +0800</pubDate><description><![CDATA[背景
项目中想使用多进程的模式。一个控制进程，加上N个工作进程。即是master+worker进程的模式，与nginx的进程模式类似的思路。master创建并管理worker进程，而且他们之间需要能够进行通信。设计思路如下图所示：

遇到问题
如何创建woker进程
linux系统下，创建进程，肯定使用fork来做系统调用。然后fork之后，我们通过ps看到子进程名称也是master，从使用角度来...]]></description><category></category></item><item><title><![CDATA[fork多线程中需要注意的问题]]></title><link>https://blog.csdn.net/dreamvyps/article/details/96197523</link><guid>https://blog.csdn.net/dreamvyps/article/details/96197523</guid><author>dreamvyps</author><pubDate>Tue, 16 Jul 2019 23:46:02 +0800</pubDate><description><![CDATA[单线程场景
对于fork系统调用，我们知道是linux下创建子进程的一种方式。fork调用一次，对于程序看来，是“返回两次”。这里其实理解为fork调用中，已经创建出了子进程，父子进程分别分从fork调用中返回。父进程需要知道子进程的进程ID，所以返回值大于0的是父进程，而子进程返回0即可，子进程可以通过getpid获取自身进程ID和getppid获取父进程ID。
多线程场景
对于多线程场景中，例...]]></description><category></category></item><item><title><![CDATA[STL使用时的一个常见错误（拷贝构造函数）]]></title><link>https://blog.csdn.net/dreamvyps/article/details/92837967</link><guid>https://blog.csdn.net/dreamvyps/article/details/92837967</guid><author>dreamvyps</author><pubDate>Wed, 19 Jun 2019 16:54:11 +0800</pubDate><description><![CDATA[背景
最近在协助同事定位问题的时候，发现一个有趣的问题。使用std::map的insert函数插入的时候，总是报了一个莫名的错误。std::map&lt;std::string, T&gt; map_data;而 T的类型，则是一个第三方的类类型。而看到的报错，则是完全没有头绪。
定位
说实话，如果再来一次，这种问题我来看错误，我是肯定想不到是这种原因导致的，因为错误信息中完全找不到跟问题相关的提...]]></description><category></category></item><item><title><![CDATA[如何让团队摆脱低层次的开发困境]]></title><link>https://blog.csdn.net/dreamvyps/article/details/92831413</link><guid>https://blog.csdn.net/dreamvyps/article/details/92831413</guid><author>dreamvyps</author><pubDate>Wed, 19 Jun 2019 15:40:39 +0800</pubDate><description><![CDATA[背景
相信不少开发同事遇到过一种似曾相识的场景：线上的系统非常繁忙，然后用户经常遇到各种各样的问题。比如说交易系统，里面用户到营业部的柜台里面查某些业务做不了，那柜台人员只能找到后台开发人员帮忙排查，而后台开发人员则需要抽时间先解决客户的问题，有时甚至需要去改生产环境的数据来解决一些问题。一来二去，柜台同事则大部分时间消耗在了排查CASE上面，剩下的一些时间，则做一下迭代需求，基本就把人力资源吃完...]]></description><category></category></item><item><title><![CDATA[学习GFS架构总结]]></title><link>https://blog.csdn.net/dreamvyps/article/details/91405392</link><guid>https://blog.csdn.net/dreamvyps/article/details/91405392</guid><author>dreamvyps</author><pubDate>Mon, 10 Jun 2019 22:18:12 +0800</pubDate><description><![CDATA[基本问题
为什么需要分布式？
因为需要支持百万级的文件，单机无法满足，所以需要用许多廉价机器来协作完成。
如何设计架构
按最简单的来理解。我们存一个文件，就需要知道文件在磁盘中的位置。现在我们存大文件，我们则需要知道这个文件存在哪台机器上。顺着这个思路我们就构建了简单的索引-&gt;机器的架构。如下图所示：

我们把元数据放到master机器上，然后把真正的物理文件，存放到chunk机器上。这种架...]]></description><category></category></item><item><title><![CDATA[RAFT一致性算法关于成员变更(membership change)问题讨论]]></title><link>https://blog.csdn.net/dreamvyps/article/details/90276986</link><guid>https://blog.csdn.net/dreamvyps/article/details/90276986</guid><author>dreamvyps</author><pubDate>Fri, 17 May 2019 00:24:40 +0800</pubDate><description><![CDATA[RAFT成员变更
什么场景需要变量
正常情况下，我们最多接触的是RAFT中选举Leader，并正常提交数据的过来。并且了解leader或者follower出现故障之后，如何恢复的过程。今天讨论的场景，是关于成员变更。例如：A、B、C三台机器，A机器负载比较高，需要更强的A1机器顶上。这时候，需要用到成员变更。原来的集群A、B，C，换成A1，B，C。
变成的方式
方案一：停掉A，增加A1。
方案二：...]]></description><category></category></item><item><title><![CDATA[库冲突错误warning: libstdc++.so.5 needed by xxx, may conflict with libstdc++.so.6]]></title><link>https://blog.csdn.net/dreamvyps/article/details/90181436</link><guid>https://blog.csdn.net/dreamvyps/article/details/90181436</guid><author>dreamvyps</author><pubDate>Mon, 13 May 2019 21:10:25 +0800</pubDate><description><![CDATA[背景
在开发项目的时候，链接的时候，遇到错误warning: libstdc++.so.5, needed by /oracle/product/10.2.0/db_1/lib/libocci.so, may conflict with libstdc++.so.6，起初没有太留意，编绎还是能正确编绎，也能单独运行。
问题
在某个库进行集成之后，在调用OCCI库的API的时候，出现了莫名的失败。主...]]></description><category></category></item><item><title><![CDATA[gcc新旧版本ABI在项目中兼容性问题]]></title><link>https://blog.csdn.net/dreamvyps/article/details/89179248</link><guid>https://blog.csdn.net/dreamvyps/article/details/89179248</guid><author>dreamvyps</author><pubDate>Wed, 10 Apr 2019 12:16:28 +0800</pubDate><description><![CDATA[ABI
这里与我们常用的API的概念一起拿出来对比认识。
API全称：Application Program Interface

An API defines the interfaces by which one piece of software communicates with another at the source level.

ABI全称：Application Binary ...]]></description><category></category></item><item><title><![CDATA[异步业务系统的一个常用实现模式]]></title><link>https://blog.csdn.net/dreamvyps/article/details/88405689</link><guid>https://blog.csdn.net/dreamvyps/article/details/88405689</guid><author>dreamvyps</author><pubDate>Mon, 11 Mar 2019 19:32:38 +0800</pubDate><description><![CDATA[业务场景
一个系统，依赖很多外部系统的数据。对于一个请求过来，需要查询N个外部系统的数据，等全部数据拿到之后，做数据处理完之后，返回给请求端。如果依赖系统太长时间未返回，我们必须有一个超时响应机制返回给客户端。
简单方案
最简单的方案，就是通过同步的方式。一个客户端请求过来，假如依赖3个接口，则同步顺序的去请求三个接口，send1, recv1, send2, recv2, send3, recv...]]></description><category></category></item><item><title><![CDATA[tcp挥手时的异常情况（SIGPIPE、shutdown vs close操作）]]></title><link>https://blog.csdn.net/dreamvyps/article/details/87778462</link><guid>https://blog.csdn.net/dreamvyps/article/details/87778462</guid><author>dreamvyps</author><pubDate>Wed, 20 Feb 2019 10:25:24 +0800</pubDate><description><![CDATA[正常的TCP端的四次挥手

问题1：如果只是关闭了一端，另一端还能发数据么
我们知道，TCP是一个双全工协议，从协议层面，我们了解到，如果client发了FIN包给服务端，在收到ACK之后，状态切换成FIN_WAIT2。此时，从协议层面，只是关闭了client-&amp;gt;server这个方向的数据传输。而server-&amp;gt;client端，则可以继续往client端发数据。可以参考《tcp/ip详...]]></description><category></category></item><item><title><![CDATA[linux下SSD硬盘与机械硬盘的一个实际数据比对]]></title><link>https://blog.csdn.net/dreamvyps/article/details/85055962</link><guid>https://blog.csdn.net/dreamvyps/article/details/85055962</guid><author>dreamvyps</author><pubDate>Mon, 17 Dec 2018 20:46:37 +0800</pubDate><description><![CDATA[SSD硬盘
一直有一个感性的认识，SSD硬盘比传统的机械磁盘快很多，采用了与机械磁盘完全不同的技术进行存储，具体的技术原理，可以参考这个固态硬盘介绍。这里简单的对手头上现有的两台机器做一下磁盘性能测试，可以给大家一个大致的参考。
测试工具
使用fio作为工具进行测试，使用dd存在不太精确的情况。
环境信息
机器1配置：
磁盘：TOSHIBA PX02SMF020
CPU主频2.3G，12核
Cen...]]></description><category></category></item><item><title><![CDATA[linux如何查看磁盘是SSD还是传统机械磁盘]]></title><link>https://blog.csdn.net/dreamvyps/article/details/85055248</link><guid>https://blog.csdn.net/dreamvyps/article/details/85055248</guid><author>dreamvyps</author><pubDate>Mon, 17 Dec 2018 20:04:42 +0800</pubDate><description><![CDATA[目录新来了一台SSD硬盘的机器如何确定真的是SSD
新来了一台SSD硬盘的机器
项目中由于程序遇到了IO瓶颈，想着找一台SSD硬盘的机器来看是否有多大提升，于是项目组给到一台SSD机器，用来测试性能指标。
如何确定真的是SSD
按照网上给出来的办法，这里简单总结两条：
1、在磁盘没有使用RAID方案的时候，可以使用这个方案，查看磁盘是否为SSD，查看是否SSD，注意，这里查到为SSD，就应该是SS...]]></description><category></category></item><item><title><![CDATA[动态链接库链接参数不要写成静态链接形式]]></title><link>https://blog.csdn.net/dreamvyps/article/details/84777869</link><guid>https://blog.csdn.net/dreamvyps/article/details/84777869</guid><author>dreamvyps</author><pubDate>Mon, 03 Dec 2018 19:23:45 +0800</pubDate><description><![CDATA[背景
动态链接库常用写法：
动态链接库的路径在/usr/local目录，动态链接库的名称为libtest.so，我们在链接的时候，一般使用
g++ -o test_bin main.o -L$(library_path) -ltest
类似这种形式来指定目标文件需要的动态链接库。
静态链接库的写法如下：
例如静态链接库放到/usr/local/libstatic.a，我们在链接的时候，一般使用
g...]]></description><category></category></item><item><title><![CDATA[内存数据原子的写到磁盘解决方案之innodb特性double write]]></title><link>https://blog.csdn.net/dreamvyps/article/details/84708855</link><guid>https://blog.csdn.net/dreamvyps/article/details/84708855</guid><author>dreamvyps</author><pubDate>Sun, 02 Dec 2018 13:15:08 +0800</pubDate><description><![CDATA[场景
我们先来讨论一个场景。假设有一段内存，例如是1M大小，需要保证原子的写到磁盘里面，而且如果发生异常情况下，能够原子的恢复起来。正常情况下，只需要使用write系统调用，即可将数据down到磁盘中。绝大多数情况下，这样做都不会有问题。但如果是可靠性要求特别高的系统的数据，需要持久化且用于数据恢复，则来不得半点马虎。这其中就存在写磁盘原子性的问题。
可靠性这里存在两个主要问题：1、写磁盘缓冲问题...]]></description><category></category></item><item><title><![CDATA[求哈希散列值用求模还是用逻辑与]]></title><link>https://blog.csdn.net/dreamvyps/article/details/84679909</link><guid>https://blog.csdn.net/dreamvyps/article/details/84679909</guid><author>dreamvyps</author><pubDate>Sat, 01 Dec 2018 23:31:20 +0800</pubDate><description><![CDATA[哈希表
在使用key, value场景的时候，最常用的一个数据结构，能够实现O(1)时间复杂度的算法。而我们常用的算法中，一般是使用一个比目标空间略大一些的质数，通过对key做一次编码函数，得到一个整数值，再找到对应的目标空间的slot位置，进而做插入操作。如下所示：
质数不妨假设为MAX
id = fun(key),
slot_id = id % MAX
找到对应的slot位置进行查找或者插入修...]]></description><category></category></item></channel></rss>