<?xml version="1.0" encoding="utf-8" ?><rss version="2.0"><channel><title><![CDATA[yishuihan的博客]]></title><description><![CDATA[公众号“码农的修炼之道”，记录了一个程序员的日常。]]></description><link>https://blog.youkuaiyun.com/wengsuwei7683</link><language>zh-cn</language><generator>https://blog.youkuaiyun.com/</generator><copyright><![CDATA[Copyright &copy; wengsuwei7683]]></copyright><item><title><![CDATA[关于零拷贝，你应该知道的那些事]]></title><link>https://blog.youkuaiyun.com/wengsuwei7683/article/details/118602988</link><guid>https://blog.youkuaiyun.com/wengsuwei7683/article/details/118602988</guid><author>wengsuwei7683</author><pubDate>Fri, 09 Jul 2021 11:39:43 +0800</pubDate><description><![CDATA[最近，学妹在开发一套远程升级工具，需要将本地的软件包传输到远程机器上，然而她发现文件传输比较慢。于是，我想到了零拷贝技术，遂写了此文也算对零拷贝做个详细了解。

问题：现在有一个用户需要读取磁盘文件上的内容然后将其通过网络发送出去，假设使用IO系统调用read/write。
1、IO原理
要了解什么是零拷贝，首先得知道什么是IO，以及有哪些类型的IO。一般而言，IO分为：标准IO库、IO系统调用、网络IO库。
IO系统调用

Linux标准访问文件方式是通过两个系统调用实现的：read()和write().]]></description><category></category></item><item><title><![CDATA[组件设计系列：实现一个支持异步和延迟任务的线程]]></title><link>https://blog.youkuaiyun.com/wengsuwei7683/article/details/110237772</link><guid>https://blog.youkuaiyun.com/wengsuwei7683/article/details/110237772</guid><author>wengsuwei7683</author><pubDate>Fri, 27 Nov 2020 17:53:19 +0800</pubDate><description><![CDATA[线程是一个很简单的，今天本文将实现一种支持异步任务添加和延迟任务的线程类，开启一个线程后，可以往里面持续添加异步任务，任务串行执行，且执行顺序与添加顺序一致。支持添加延时任务。任务可以是业务方的任意函数（通过bind/function实现）。当然了，稍加改造，还可以支持定时任务的实现。同时，以本线程的实现为基础，还可以实现后续的线程池。

0、前提
首先，我们将使用到的命名空间进行封装。

1、线程类task_thread
当前的线程类，当退出线程的时候，支持三种策略。其中，THREAD_RELEASE_.]]></description><category></category></item><item><title><![CDATA[分布式系列：分布式系统之ACID和BASE理论]]></title><link>https://blog.youkuaiyun.com/wengsuwei7683/article/details/109811149</link><guid>https://blog.youkuaiyun.com/wengsuwei7683/article/details/109811149</guid><author>wengsuwei7683</author><pubDate>Thu, 19 Nov 2020 14:30:23 +0800</pubDate><description><![CDATA[之前我们在《分布式系统之聊聊CAP理论》文中介绍了分布式系统的CAP理论，在实际场景下，一般P是肯定存在的，因此分布式策略一般就是变成了CP和AP选择。那么ACID和BASE理论又是什么呢？
ACID由原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)组成。ACID理论是对事务特性的抽象和总结，一般可用理解为实现了ACID就实现了事务。分布式事务就是对某个操作要么所有节点都成功，要么失败。不允许存在部分成功、部分失败。常用的分布式事务]]></description><category></category></item><item><title><![CDATA[分布式系列：分布式系统之聊聊选举算法]]></title><link>https://blog.youkuaiyun.com/wengsuwei7683/article/details/109809555</link><guid>https://blog.youkuaiyun.com/wengsuwei7683/article/details/109809555</guid><author>wengsuwei7683</author><pubDate>Thu, 19 Nov 2020 13:48:40 +0800</pubDate><description><![CDATA[在分布式系统中采用的是主从架构，也就是有一个主节点，若干个从节点。主节点可以执行读写操作，从节点只执行读操作。采用这种一主多从的方案，可以有效保证了数据的一致性（哪怕不是强一致性，也能有效保证最终一致性）。
在开源的Redis，MongoDB，Zookeeper等软件中也都采用了的选举算法，常用的选举算法有以下三种：Bully算法，Raft算法，ZAB算法。
1、Bully算法
Bully算法是一种简单直接的算法，因为它的选举原则是取ID的最大值作为主节点。在Bully算法中，有两种节点角色：普通节点和主节]]></description><category></category></item><item><title><![CDATA[分布式系列：分布式系统中的互斥算法]]></title><link>https://blog.youkuaiyun.com/wengsuwei7683/article/details/109749218</link><guid>https://blog.youkuaiyun.com/wengsuwei7683/article/details/109749218</guid><author>wengsuwei7683</author><pubDate>Tue, 17 Nov 2020 18:48:31 +0800</pubDate><description><![CDATA[“ 在单机中，多线程环境下为了解决竞争某共享资源的时候，一般采用加锁方式来解决互斥问题。而在分布式系统中，有哪些算法呢？”

我们一起看看有哪些类型的分布式互斥算法。
1、集中式算法
在集中式算法中，一般需要一个协调者。每个程序在访问临界资源的时候，需要先给协调者发送一个请求。如果当前临界资源没有使用者，则授权该程序使用该资源。如果有程序使用该资源，则给后来请求该资源的请求加入等待队列。如果资源被释放，则立即通知等待队列里面的其他程序使用。
这种算法叫做集中式算法，因为依赖于中央服务器。从上面过程可以看出.]]></description><category></category></item><item><title><![CDATA[分布式系列：分布式系统之聊聊CAP理论]]></title><link>https://blog.youkuaiyun.com/wengsuwei7683/article/details/109748924</link><guid>https://blog.youkuaiyun.com/wengsuwei7683/article/details/109748924</guid><author>wengsuwei7683</author><pubDate>Tue, 17 Nov 2020 18:25:47 +0800</pubDate><description><![CDATA[本文于2019年11月25日首发于公众号“码农的修炼之道”，欢迎关注！

在分布式系统中有一个重要的理论，这就是CAP理论。其中C代表单词Consistency，一致性。是指所有节点在同一时刻的数据是相同的，比如更新数据库集群，更新成功后，该集群中的其他数据库也要数据一致。
A代表单词Availability，可用性。是指系统提供的服务一直是可用状态，对于客户端的请求必须有响应。
P代表Partition，分区容错性。在分布式系统中，遇到网络问题仍然可以响应用户的请求。
一致性，可用性，分区容错性构成了分.]]></description><category></category></item><item><title><![CDATA[从wireshark抓包看TCP头部时间戳]]></title><link>https://blog.youkuaiyun.com/wengsuwei7683/article/details/109735199</link><guid>https://blog.youkuaiyun.com/wengsuwei7683/article/details/109735199</guid><author>wengsuwei7683</author><pubDate>Tue, 17 Nov 2020 09:20:26 +0800</pubDate><description><![CDATA[本文于2020年8月23日首发于个人公众号“码农的修炼之道”，欢迎关注。

不知道大家有没有注意到，wireshark抓取tcp报文的时候，大部分时候的报文是如下图所示的，其中带了Seq，Win和Len字段，分别对应了报文序列号、滑动窗口和tcp报文长度。

有时候，也会在报文中看到TSval 和 TSecr 这两个参数，如下图所示。

那么这个参数来源于哪里呢？又有什么作用呢？
1、原理
时间戳（TCP Timestamps Option，TSopt）来源于TCP报文头部的Option选项。这个选项在 .]]></description><category></category></item><item><title><![CDATA[组件设计系列：实现一个内存工具Buffer类]]></title><link>https://blog.youkuaiyun.com/wengsuwei7683/article/details/109694889</link><guid>https://blog.youkuaiyun.com/wengsuwei7683/article/details/109694889</guid><author>wengsuwei7683</author><pubDate>Sat, 14 Nov 2020 19:18:00 +0800</pubDate><description><![CDATA[在Java里面或者Netty框架里面，都有自己封装好的ByteBuffer结构，用于将应用层数据转成字节数组，最终通过网络发送出去。熟悉Java的同学可能很熟悉这些API，本文的目的是参考Netty里面的ByteBuffer封装一个类似的结构，用于C/C++项目中内存的申请及维护。
0、结构定义
对于C/C++语言来说，都是指针，因此我们需要一个结构体保存这些信息，其中total_size代表目前Buffer的容量大小。
//数据缓冲区
struct buffer {
    char *data;    ]]></description><category></category></item><item><title><![CDATA[面试实战系列之TCP协议总结]]></title><link>https://blog.youkuaiyun.com/wengsuwei7683/article/details/109694643</link><guid>https://blog.youkuaiyun.com/wengsuwei7683/article/details/109694643</guid><author>wengsuwei7683</author><pubDate>Sat, 14 Nov 2020 19:01:42 +0800</pubDate><description><![CDATA[本文于2019年10月首发于公众号“码农的修炼之道”上，本文来源于本人多次实际面试总结，希望对各位准备面试者有帮助。

在创作本文的时候，本人前前后后差不多面试了10家大型企业。由于简历上写着熟悉TCP/IP协议，而且投递的岗位都是后台研发，因此关于TCP/IP协议的问题必不可少。下面就总结一波问题，也算是一个阶段性的记录。
1、TCP协议三次握手，四次挥手都很熟悉了，那么为什么需要三次握手呢？
这是AB面试的时候问的，我首先介绍了一下三次握手的过程（包括发送包），他说这个大家都知道，问为什么需要三次握手.]]></description><category></category></item><item><title><![CDATA[Linux中查找命令之find总结]]></title><link>https://blog.youkuaiyun.com/wengsuwei7683/article/details/109672436</link><guid>https://blog.youkuaiyun.com/wengsuwei7683/article/details/109672436</guid><author>wengsuwei7683</author><pubDate>Fri, 13 Nov 2020 12:41:54 +0800</pubDate><description><![CDATA[本文希望全面的总结一下find命令的使用。同时，本文也将总结其他相关的查找命令：locate、whereis、which。
1、find命令
find命令的格式：find [路径]  [选项] [操作]
find命令的主要是在选项上。常用的选项如下：

-name 按照名称查找；


举例：查找/etc目录下以conf结尾的文件
find  /etc -name  ‘*conf’


-iname 安装名称查找，忽略大小写；


举例：find  /etc -iname  ‘aa.txt’


-type ]]></description><category></category></item><item><title><![CDATA[从TCP协议之滑动窗口分析应用性能]]></title><link>https://blog.youkuaiyun.com/wengsuwei7683/article/details/109648406</link><guid>https://blog.youkuaiyun.com/wengsuwei7683/article/details/109648406</guid><author>wengsuwei7683</author><pubDate>Thu, 12 Nov 2020 17:20:50 +0800</pubDate><description><![CDATA[去年我师傅推荐了两本林沛满写的关于wireshark抓包的书，分别是《wireshark就是这么简单》和《wireshark分析的艺术》，写的真心不错。
TCP协议是一个很有意思的内容，这半年对TCP协议有了更多的认识，于是想重新更新一些对TCP协议的内容。今天先从TCP协议里面的滑动窗口说起。
1、先说原理
就发送端来说，一般如下所示：

主要分为：已发送已确认的包（应用层未读取）。发送未确认的包，未发送可发送的包，未发送不可发送的包。其中，滑动窗口指的是发送未确认和未发送可发送区域的大小。
2、滑动窗口]]></description><category></category></item><item><title><![CDATA[记一次wireshark分析问题实战与总结]]></title><link>https://blog.youkuaiyun.com/wengsuwei7683/article/details/109646671</link><guid>https://blog.youkuaiyun.com/wengsuwei7683/article/details/109646671</guid><author>wengsuwei7683</author><pubDate>Thu, 12 Nov 2020 16:30:54 +0800</pubDate><description><![CDATA[作为一名后台软件开发者(coder)，随时面临着复杂的网络原因导致的各类问题，排查问题也有一定的难度。好在有一把网络问题分析的屠龙宝刀，那就是wireshark神器，本文将举例使用wireshark分析一个产品的故障原因。
1、问题背景
某一天项目报了一个产品的现场问题，现场发现在早上8点~9点期间，该系统的A软件和另一侧系统的B软件不断的进行连接、断开。项目人员在这段时间内使用wireshark抓包发回来分析，在该项目中，A软件为客户端程序，B软件作为服务端。A软件需要连接B软件，并进行通信获取有效信息。]]></description><category></category></item><item><title><![CDATA[组件设计系列：实现一个LRU缓存类]]></title><link>https://blog.youkuaiyun.com/wengsuwei7683/article/details/109628210</link><guid>https://blog.youkuaiyun.com/wengsuwei7683/article/details/109628210</guid><author>wengsuwei7683</author><pubDate>Wed, 11 Nov 2020 18:12:29 +0800</pubDate><description><![CDATA[组件设计系列：实现一个LRU缓存类1、简介2、实现LRU缓存3、测试
1、简介
在我负责的项目中，有很多公共的组件，实现的思路很值得我们学习。比如LRU缓存，这种策略在操作系统中也有应用。本次是基于C++实现的一个支持泛型的LRU缓存工具类，实现思路供大家参考。
LRU算法（Least Recently Used,最近最少使用），是一种常用的页面置换算法，选择最近最久未使用的页面予以淘汰。
2、实现LRU缓存
首先看一下LRUCache类的定义如下：

思路主要是借助map和list来实现一个LRU缓存的实]]></description><category></category></item></channel></rss>