![](https://img-blog.csdnimg.cn/20201014180756916.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
linux
werflychen
曾经在腾讯百度从事过后台开发,现在一个券商从事后台开发,chenwenh@foxmail.com
展开
-
unique_ptr实现Impl模式时遇到的问题分析
背景对于类的设计与定义,我们习惯上使用“指向实现的指针”, 或者叫PImpl。例如下面的类:// widget.h(接口)class widget { // 公开成员private: struct impl; // 实现类的前置声明 impl* ptr;};// widget.cpp(实现)struct widget::impl { // 实现细节...原创 2019-08-07 10:43:04 · 1892 阅读 · 1 评论 -
不同容器(GCC7.1与GCC4.8.5)运行相同代码导致效率巨大差别的案件追踪(第二篇)
localtime函数最权威的使用手册不是百度,而是man,在man里面提到与与时区相关。再通过谷歌找到一个前人对localtime进行调优的博客How setting the TZ environment variable avoids thousands of system calls,详细信息可以参考里面的内容描述,这里不赘述。原因解释按照前人得出来的结论,localtime里面,如...原创 2018-11-11 21:09:29 · 1005 阅读 · 0 评论 -
不同容器(GCC7.1与GCC4.8.5)运行相同代码导致效率巨大差别的案件追踪(第一篇)
背景之前对项目中日志组件做了一轮优化测试之后,在GCC4.8.5下,跑一个测试案例(写100万条日志,每条1K字节),能跑到4.2S左右的耗时。而今天发现了一个奇怪的现象,同样的代码,居然在GCC7.1的容器下,跑出了7.5S左右的水平。百思不得其解!不同的容器能跑出相差50%左右的时间出来。而且是更新版本的容器,性能差了将近一倍,无论如何都无法解释。后面简称安装GCC4.8.5的是A容器,安...原创 2018-11-08 00:09:17 · 2065 阅读 · 0 评论 -
多进程写同一个日志并发问题分析
背景问题在优化日志组件项目中有如下场景:两个进程,A、B进程往同一个文件写日志的时候,使用C语言的库函数写,fopen文件追加方式打开, fwrite等。如果每一次写的时候都强制fflush操作,则写的时序是正常的。如果不是每次fflush操作的时候,则会出现写入日志的时候的时序问题,即是A进程的一条日志没打完,B进程的日志中间插进来了。问题分析原子性系统调用先从最基本的系统调用说起...原创 2018-10-26 23:14:57 · 6182 阅读 · 4 评论 -
mysql innodb索引结构的理解
从几个“经验”做法问题开始:1、建索引的时候,建议使用一个id字段作为主键,并递增的插入,这样效率更高。2、为什么索引查询的时候,会有前缀匹配的约束?开始的时候抛出这两个问题,我们先了解完innodb的索引的数据结构,再回来看这两个问题是不是更清晰了。innodb的数据与主键索引是如何组织B树与B+树的基本原理mysql的索引通过B+树来进行组织。为什么是B+树?这先简单回...原创 2018-10-21 23:54:23 · 381 阅读 · 0 评论 -
哈希桶的预分配内存的实现形式
之前在书本中使用过的hashtable的时候,总体思想是使用一大片内存,然后把key值hash成一个int,找到对应的内存的结构的位置,然后找到相应的数据。常用的解决冲突的方式是,需要进行拉链,再new一个新结点来表示数据。这是一种实现形式,逻辑上没有什么问题。总体方案如下图所示 存在问题:大部分情况下,都需要通过动态分配内存的方式进行拉链。而对于类似共享内存,或者是堆内存,预...原创 2018-10-10 11:05:26 · 942 阅读 · 0 评论 -
C语言结构体中解决变长数据结构连续内存分配的定义的一种方法(char data[0])
最近项目中,有一个业务场景需要使用一个变长数据结构。而且需要使用连续内存。例如这个场景,我定义一个字段,它来表示DB结构的某个列,如下所示:struct Col_v0 { int type; int len; char data[100];};一般来说,我们可以简单的定义成这样。直接用一个定长的结构体来表示。又有人或者有疑问,要表示一个变长的,不是可以直接用...原创 2018-10-14 22:00:02 · 2101 阅读 · 3 评论 -
磁盘IO效率的简单总结
最近一段时间的项目进入阶段性收尾,项目中由于遇到了数据需要落地的场景,因此,便需要好好整理一下。这里从几个问题开始:1、对于传统的机械硬盘,如何让写磁盘速度更快?如何了解自己是否已经达到最优?2、多进程写文件的时候,如何保证文件有序?3、只有一个磁盘,多进程写文件的时候,是同时写到一个文件更快,还是多个进程写到多个文件,总体IO效率更高?4、在某些对数据严格要求安全的场景下,有什么...原创 2018-09-29 11:32:13 · 6145 阅读 · 1 评论 -
二分搜索问题总结
最近工作中遇到了二分搜索问题。它是计算机课程中最基础的算法,这是我们在顺序查找时,最直接的一种提速的普遍性算法了,能够将一个顺序的查找的时间复杂度,从O(n)提升到了O(logn),这是质变的算法。首先我们来看一下一个经典的二分搜索算法:int BinarySearch(vector<int>& vec_arr, int target) { int left ...原创 2018-10-02 08:43:57 · 398 阅读 · 0 评论 -
函数返回值的优化技术(RVO和右值引用)
我们先来看一段例子,一个简单的函数返回值场景#include <iostream>using namespace std;class Moveable {public: Moveable():h(new int(3)) { cout << "construct " << endl; } ~Moveabl...原创 2018-09-06 23:42:49 · 2407 阅读 · 0 评论 -
整形溢出的总结
最近在项目中需要做一个算术运算比较问题,涉及到一个比较的溢出问题。可以简单的抽象成一个示例如下:int a = -100;unsigned b = 100;if (a < b) { cout << "a(-100) < b(100)" << endl;} else { cout << "a(-100) > b(...原创 2018-09-16 23:20:56 · 3845 阅读 · 0 评论 -
压力测试的一点思考
最后工作中的项目,接近上线了,做了个完整的压力测试过程,对于压力测试,整个项目下来,有些自己的理解,这里简单总结如下:压测的目的1、检查系统是否要求业务需求,拿到系统的一些性能指标。一般情况下,例如峰值是1W/s的系统,压测的时候,需要能扛上2W/s基本就能满足要求(特殊业务可能另作评估)。并且输出压测报告,拿到一个对系统的量化指标,做到一切心中有数。2、发现系统存在的问题。很...原创 2018-09-03 23:50:41 · 212 阅读 · 0 评论 -
二分搜索常用变种(N个相同目标,寻找第一个或最后一个目标元素)leetcode 278
/* * 二分搜索的一个变种,找到第一个等于target的下标 */ int binarySearchFirst(vector<int>& nums, int target) { if (nums.empty()) { return -1; } ...原创 2018-09-02 22:26:41 · 162 阅读 · 0 评论 -
leetcode 旋转数组
这个旋转数组,看似挺简单,但真正想要不用调试,直接写出通过的,基本功还是要特别扎实,记自己通过的三种方法class Solution {public: /* solution 1:直接用了n个辅助空间,空间复杂度过高 */ void rotate(vector<int>& nums, int k) { vector<int> r...原创 2018-08-24 23:01:55 · 369 阅读 · 0 评论 -
linux vim如何强制输出TAB(ctrl + v + i不生效)
记一个小技术,在LINUX下使用VIM时,经常是把TAB替换成了四个空格。而写makefile的时候,经常需要使用TAB才能输入命令。这时候需要强制VIM输出TAB,而不是四个空格。 方案1: 最原始的办法可以是这样,设置set noexpandtab,把这个替换去掉。 方案2: 直接使用ctrl + v + i,(网上...原创 2018-08-03 14:24:20 · 2132 阅读 · 0 评论 -
为什么有些类型无法使用memset初始化?
基本经验我们知道,对于这个问题,一般的开发经验是一些基本数据类型的,像int, char, double之类的构造的简单struct类型,我们在C语言中,一般使用memset来对一片内存进行初始化。而另一个经验又是,有些类型,我们不能使用memset进行初始化,例如:string, vector之类的stl结构,或者是一些自定义的类型比较复杂的,例如有多态性质的类定义。什么样的类可以使用mem...原创 2018-11-11 22:23:15 · 4065 阅读 · 5 评论 -
一个分布式限流系统的设计思路
问题背景今天在参与面试的时候,候选人提到了一个他们项目做的一个项目中使用的限制系统的设计。大致思路如下,通过一个配置中心去获取每台机器的配额,然后本地做限流。当时就被挑战了这个思路,如果其他机器挂了,如何快速感知?马上就没答上来了。基于这个话题,今天想来简单分析一下,一个限流系统的设计思路。基本算法1、先讨论最简单的场景,单台机器,用什么方式来限制流量?通知一个非常简单的做法,暂且叫它为时间...原创 2018-11-13 00:32:05 · 1024 阅读 · 1 评论 -
意向锁的作用
背景在了解innodb事务并发控制的时候,里面提到了意向锁(intention lock),这里简单做下总结应用场景在innodb的使用场景中,里面有实现了行锁,具体有对行的读锁,写锁。另外,如果对一个表作一些统一的操作,表的层面,有表层级的读锁,写锁。那这个意向锁是干嘛用的?我们假设一个场景,一个事务A正在写某个表T的第r行加了写锁,另一个事务B尝试去对整个表做操作(例如修改表结构的时候...原创 2018-11-25 17:51:47 · 2990 阅读 · 0 评论 -
leveldb设计思想学习总结
leveldb的价值每一类组件,都有它特定擅长的应用场景。在leveldb出世之前,我们对于nosql下的kv存储,我们有redis方案存储。然而redis数据存储的上限,即是机器内存。内存在目前阶段,算是比较昂贵。而leveldb的出现,提供了一个可以以机器磁盘为容量上限,支持持久化的写操作的同时,做到写速度较快,读速度也不慢的一个解决方案。leveldb如何解决问题leveldb面对的问...原创 2019-07-31 21:29:56 · 370 阅读 · 0 评论 -
c++中函数返回时的RVO机制和std::move的理解
常见问题RVO和std::move都能减少对象拷贝时的开销,那他们到底是什么与什么的关系叫?talk is cheap, show me the code!如下代码所示:test_1.cpp场景一【函数返回非RVO】class Obj {public: Obj() { printf("construct \n"); } ~Obj() {...原创 2019-07-28 09:26:21 · 1316 阅读 · 2 评论 -
fork生成子进程与执行exec子进程的区别
背景项目中想使用多进程的模式。一个控制进程,加上N个工作进程。即是master+worker进程的模式,与nginx的进程模式类似的思路。master创建并管理worker进程,而且他们之间需要能够进行通信。设计思路如下图所示:遇到问题如何创建woker进程linux系统下,创建进程,肯定使用fork来做系统调用。然后fork之后,我们通过ps看到子进程名称也是master,从使用角度来...原创 2019-07-17 12:15:35 · 1406 阅读 · 0 评论 -
fork多线程中需要注意的问题
单线程场景对于fork系统调用,我们知道是linux下创建子进程的一种方式。fork调用一次,对于程序看来,是“返回两次”。这里其实理解为fork调用中,已经创建出了子进程,父子进程分别分从fork调用中返回。父进程需要知道子进程的进程ID,所以返回值大于0的是父进程,而子进程返回0即可,子进程可以通过getpid获取自身进程ID和getppid获取父进程ID。多线程场景对于多线程场景中,例...原创 2019-07-16 23:46:02 · 452 阅读 · 0 评论 -
学习GFS架构总结
基本问题为什么需要分布式?因为需要支持百万级的文件,单机无法满足,所以需要用许多廉价机器来协作完成。如何设计架构按最简单的来理解。我们存一个文件,就需要知道文件在磁盘中的位置。现在我们存大文件,我们则需要知道这个文件存在哪台机器上。顺着这个思路我们就构建了简单的索引->机器的架构。如下图所示:我们把元数据放到master机器上,然后把真正的物理文件,存放到chunk机器上。这种架...原创 2019-06-10 22:18:12 · 2233 阅读 · 0 评论 -
STL使用时的一个常见错误(拷贝构造函数)
背景最近在协助同事定位问题的时候,发现一个有趣的问题。使用std::map的insert函数插入的时候,总是报了一个莫名的错误。std::map<std::string, T> map_data;而 T的类型,则是一个第三方的类类型。而看到的报错,则是完全没有头绪。定位说实话,如果再来一次,这种问题我来看错误,我是肯定想不到是这种原因导致的,因为错误信息中完全找不到跟问题相关的提...原创 2019-06-19 16:54:11 · 2426 阅读 · 3 评论 -
RAFT一致性算法关于成员变更(membership change)问题讨论
RAFT成员变更什么场景需要变量正常情况下,我们最多接触的是RAFT中选举Leader,并正常提交数据的过来。并且了解leader或者follower出现故障之后,如何恢复的过程。今天讨论的场景,是关于成员变更。例如:A、B、C三台机器,A机器负载比较高,需要更强的A1机器顶上。这时候,需要用到成员变更。原来的集群A、B,C,换成A1,B,C。变成的方式方案一:停掉A,增加A1。方案二:...原创 2019-05-17 00:24:40 · 1210 阅读 · 2 评论 -
库冲突错误warning: libstdc++.so.5 needed by xxx, may conflict with libstdc++.so.6
背景在开发项目的时候,链接的时候,遇到错误warning: libstdc++.so.5, needed by /oracle/product/10.2.0/db_1/lib/libocci.so, may conflict with libstdc++.so.6,起初没有太留意,编绎还是能正确编绎,也能单独运行。问题在某个库进行集成之后,在调用OCCI库的API的时候,出现了莫名的失败。主...原创 2019-05-13 21:10:25 · 3773 阅读 · 0 评论 -
gcc新旧版本ABI在项目中兼容性问题
ABI这里与我们常用的API的概念一起拿出来对比认识。API全称:Application Program InterfaceAn API defines the interfaces by which one piece of software communicates with another at the source level.ABI全称:Application Binary ...原创 2019-04-10 12:16:28 · 5442 阅读 · 2 评论 -
异步业务系统的一个常用实现模式
业务场景一个系统,依赖很多外部系统的数据。对于一个请求过来,需要查询N个外部系统的数据,等全部数据拿到之后,做数据处理完之后,返回给请求端。如果依赖系统太长时间未返回,我们必须有一个超时响应机制返回给客户端。简单方案最简单的方案,就是通过同步的方式。一个客户端请求过来,假如依赖3个接口,则同步顺序的去请求三个接口,send1, recv1, send2, recv2, send3, recv...原创 2019-03-11 19:32:38 · 413 阅读 · 1 评论 -
tcp挥手时的异常情况(SIGPIPE、shutdown vs close操作)
正常的TCP端的四次挥手问题1:如果只是关闭了一端,另一端还能发数据么我们知道,TCP是一个双全工协议,从协议层面,我们了解到,如果client发了FIN包给服务端,在收到ACK之后,状态切换成FIN_WAIT2。此时,从协议层面,只是关闭了client->server这个方向的数据传输。而server->client端,则可以继续往client端发数据。可以参考《tcp/ip详...原创 2019-02-20 10:25:24 · 797 阅读 · 0 评论 -
linux下SSD硬盘与机械硬盘的一个实际数据比对
SSD硬盘一直有一个感性的认识,SSD硬盘比传统的机械磁盘快很多,采用了与机械磁盘完全不同的技术进行存储,具体的技术原理,可以参考这个固态硬盘介绍。这里简单的对手头上现有的两台机器做一下磁盘性能测试,可以给大家一个大致的参考。测试工具使用fio作为工具进行测试,使用dd存在不太精确的情况。环境信息机器1配置:磁盘:TOSHIBA PX02SMF020CPU主频2.3G,12核Cen...原创 2018-12-17 20:46:37 · 1700 阅读 · 0 评论 -
linux如何查看磁盘是SSD还是传统机械磁盘
目录新来了一台SSD硬盘的机器如何确定真的是SSD新来了一台SSD硬盘的机器项目中由于程序遇到了IO瓶颈,想着找一台SSD硬盘的机器来看是否有多大提升,于是项目组给到一台SSD机器,用来测试性能指标。如何确定真的是SSD按照网上给出来的办法,这里简单总结两条:1、在磁盘没有使用RAID方案的时候,可以使用这个方案,查看磁盘是否为SSD,查看是否SSD,注意,这里查到为SSD,就应该是SS...原创 2018-12-17 20:04:42 · 6233 阅读 · 0 评论 -
动态链接库链接参数不要写成静态链接形式
背景动态链接库常用写法:动态链接库的路径在/usr/local目录,动态链接库的名称为libtest.so,我们在链接的时候,一般使用g++ -o test_bin main.o -L$(library_path) -ltest类似这种形式来指定目标文件需要的动态链接库。静态链接库的写法如下:例如静态链接库放到/usr/local/libstatic.a,我们在链接的时候,一般使用g...原创 2018-12-03 19:23:45 · 443 阅读 · 2 评论 -
求哈希散列值用求模还是用逻辑与
哈希表在使用key, value场景的时候,最常用的一个数据结构,能够实现O(1)时间复杂度的算法。而我们常用的算法中,一般是使用一个比目标空间略大一些的质数,通过对key做一次编码函数,得到一个整数值,再找到对应的目标空间的slot位置,进而做插入操作。如下所示:质数不妨假设为MAXid = fun(key),slot_id = id % MAX找到对应的slot位置进行查找或者插入修...原创 2018-12-01 23:31:20 · 381 阅读 · 2 评论 -
内存数据原子的写到磁盘解决方案之innodb特性double write
场景我们先来讨论一个场景。假设有一段内存,例如是1M大小,需要保证原子的写到磁盘里面,而且如果发生异常情况下,能够原子的恢复起来。正常情况下,只需要使用write系统调用,即可将数据down到磁盘中。绝大多数情况下,这样做都不会有问题。但如果是可靠性要求特别高的系统的数据,需要持久化且用于数据恢复,则来不得半点马虎。这其中就存在写磁盘原子性的问题。可靠性这里存在两个主要问题:1、写磁盘缓冲问题...原创 2018-12-02 13:15:08 · 1418 阅读 · 3 评论 -
坑爹的if语句
前两天的时候,自己在修改代码的时候,自己感觉对调试比较有心得体会了。但遇到一个问题,总在一个函数中返回了false,明明条件就是不应该返回。修改前的示例代码如下: string topic = "topic is not empty";if (topic.empty()) return false;我想对这行代码加一个日志打印,示例如下:s...原创 2018-07-21 17:48:50 · 180 阅读 · 0 评论 -
vector bool 引发的如何发现问题的思考
前段时间,在项目开发过程之中,自己遇到了一个奇怪的问题。使用了vector<bool>,而将vector<bool>的元素值,作为引用值去传参数的时候,报了个莫名其妙的错。当时因为在赶进度,觉得根据自己的理解,可能一时半会搞不定,就没有深纠,另外,觉得这可能会是一个好问题,就先把这个问题记下来,先不管,尝试用其他办法先把项目实现先搞定,等主要工作完成之后,再尝试回过头来安排...原创 2018-07-07 09:56:54 · 577 阅读 · 0 评论 -
centos下安装python2.7.1 以及装完后 yum 不能用的问题
最近自己的redhat上python升级了python到2.7,却发现yum无法使用了,找到了一个可行的解决办法,大家可以参考一下,转载了网友的一篇文章,亲测有效。转载自:http://www.cnblogs.com/theitnotes/p/4162882.html由于CentOS的yum是采用的Python2.4.X进行开发的,所以不支持更高版本的python安装,所以需要进行转载 2017-06-14 10:17:21 · 646 阅读 · 0 评论 -
模板类的构造函数调用错误问题分析
将当时错误的代码进行简化后,代码如下:#include #include using namespace std;templateclass Test{ public: Test(const string& name) { this->m_name = name; } void Print() {原创 2017-06-12 13:30:07 · 3442 阅读 · 1 评论 -
redis在pub压力较大时,sub端错误Server closed the connection的解决方法
订阅端在发送压力较大时,约每秒大于5K左右时,会出现不稳定情况,会退出。Error: Server closed the connectiondispatch...解决:redis在缓冲设置上有一定的限制,可以试一下:查询:client-output-buffer-limit pubsub 0 0 0设置成发送订阅没有限制,使用客户端连上去,命令如下:CONFIG SE原创 2017-05-03 15:37:00 · 6380 阅读 · 0 评论 -
redis的pub/sub性能测试
最近公司项目需要使用redis的pub和sub来做为简单的通道,就对其进行了简单的性能压测。压测结论如下: 300个字节1万字节2万字节4万字节一个发布端1785QPS1430QPS1022QPS589QPS总发布端41666QPS56原创 2017-05-03 15:36:00 · 8066 阅读 · 1 评论