
工作
文章平均质量分 67
werflychen
曾经在腾讯百度从事过后台开发,现在一个券商从事后台开发,chenwenh@foxmail.com
展开
-
HW面试心得
喜出望外------------------------------------------------------------------------------------------------------------ 五一回家,刚刚回到宿舍,就收到一个深圳手机号打过来的电话。接起电话,还真是意外,是HW打过来了。从谈话的内容判断,对方应该是 位技术人员,问了我一些关于编...原创 2011-05-09 12:13:00 · 2211 阅读 · 2 评论 -
函数返回值的优化技术(RVO和右值引用)
我们先来看一段例子,一个简单的函数返回值场景#include <iostream>using namespace std;class Moveable {public: Moveable():h(new int(3)) { cout << "construct " << endl; } ~Moveabl...原创 2018-09-06 23:42:49 · 2471 阅读 · 0 评论 -
二分搜索问题总结
最近工作中遇到了二分搜索问题。它是计算机课程中最基础的算法,这是我们在顺序查找时,最直接的一种提速的普遍性算法了,能够将一个顺序的查找的时间复杂度,从O(n)提升到了O(logn),这是质变的算法。首先我们来看一下一个经典的二分搜索算法:int BinarySearch(vector<int>& vec_arr, int target) { int left ...原创 2018-10-02 08:43:57 · 425 阅读 · 0 评论 -
磁盘IO效率的简单总结
最近一段时间的项目进入阶段性收尾,项目中由于遇到了数据需要落地的场景,因此,便需要好好整理一下。这里从几个问题开始:1、对于传统的机械硬盘,如何让写磁盘速度更快?如何了解自己是否已经达到最优?2、多进程写文件的时候,如何保证文件有序?3、只有一个磁盘,多进程写文件的时候,是同时写到一个文件更快,还是多个进程写到多个文件,总体IO效率更高?4、在某些对数据严格要求安全的场景下,有什么...原创 2018-09-29 11:32:13 · 6271 阅读 · 1 评论 -
C语言结构体中解决变长数据结构连续内存分配的定义的一种方法(char data[0])
最近项目中,有一个业务场景需要使用一个变长数据结构。而且需要使用连续内存。例如这个场景,我定义一个字段,它来表示DB结构的某个列,如下所示:struct Col_v0 { int type; int len; char data[100];};一般来说,我们可以简单的定义成这样。直接用一个定长的结构体来表示。又有人或者有疑问,要表示一个变长的,不是可以直接用...原创 2018-10-14 22:00:02 · 2165 阅读 · 3 评论 -
哈希桶的预分配内存的实现形式
之前在书本中使用过的hashtable的时候,总体思想是使用一大片内存,然后把key值hash成一个int,找到对应的内存的结构的位置,然后找到相应的数据。常用的解决冲突的方式是,需要进行拉链,再new一个新结点来表示数据。这是一种实现形式,逻辑上没有什么问题。总体方案如下图所示 存在问题:大部分情况下,都需要通过动态分配内存的方式进行拉链。而对于类似共享内存,或者是堆内存,预...原创 2018-10-10 11:05:26 · 997 阅读 · 0 评论 -
mysql innodb索引结构的理解
从几个“经验”做法问题开始:1、建索引的时候,建议使用一个id字段作为主键,并递增的插入,这样效率更高。2、为什么索引查询的时候,会有前缀匹配的约束?开始的时候抛出这两个问题,我们先了解完innodb的索引的数据结构,再回来看这两个问题是不是更清晰了。innodb的数据与主键索引是如何组织B树与B+树的基本原理mysql的索引通过B+树来进行组织。为什么是B+树?这先简单回...原创 2018-10-21 23:54:23 · 426 阅读 · 0 评论 -
多进程写同一个日志并发问题分析
背景问题在优化日志组件项目中有如下场景:两个进程,A、B进程往同一个文件写日志的时候,使用C语言的库函数写,fopen文件追加方式打开, fwrite等。如果每一次写的时候都强制fflush操作,则写的时序是正常的。如果不是每次fflush操作的时候,则会出现写入日志的时候的时序问题,即是A进程的一条日志没打完,B进程的日志中间插进来了。问题分析原子性系统调用先从最基本的系统调用说起...原创 2018-10-26 23:14:57 · 6284 阅读 · 4 评论 -
不同容器(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 · 2127 阅读 · 0 评论 -
不同容器(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 · 1066 阅读 · 0 评论 -
为什么有些类型无法使用memset初始化?
基本经验我们知道,对于这个问题,一般的开发经验是一些基本数据类型的,像int, char, double之类的构造的简单struct类型,我们在C语言中,一般使用memset来对一片内存进行初始化。而另一个经验又是,有些类型,我们不能使用memset进行初始化,例如:string, vector之类的stl结构,或者是一些自定义的类型比较复杂的,例如有多态性质的类定义。什么样的类可以使用mem...原创 2018-11-11 22:23:15 · 4346 阅读 · 5 评论 -
一个分布式限流系统的设计思路
问题背景今天在参与面试的时候,候选人提到了一个他们项目做的一个项目中使用的限制系统的设计。大致思路如下,通过一个配置中心去获取每台机器的配额,然后本地做限流。当时就被挑战了这个思路,如果其他机器挂了,如何快速感知?马上就没答上来了。基于这个话题,今天想来简单分析一下,一个限流系统的设计思路。基本算法1、先讨论最简单的场景,单台机器,用什么方式来限制流量?通知一个非常简单的做法,暂且叫它为时间...原创 2018-11-13 00:32:05 · 1095 阅读 · 1 评论 -
意向锁的作用
背景在了解innodb事务并发控制的时候,里面提到了意向锁(intention lock),这里简单做下总结应用场景在innodb的使用场景中,里面有实现了行锁,具体有对行的读锁,写锁。另外,如果对一个表作一些统一的操作,表的层面,有表层级的读锁,写锁。那这个意向锁是干嘛用的?我们假设一个场景,一个事务A正在写某个表T的第r行加了写锁,另一个事务B尝试去对整个表做操作(例如修改表结构的时候...原创 2018-11-25 17:51:47 · 3076 阅读 · 0 评论 -
redis重新分片及迁移技术
redis分片分片场景在业务量相对较小的时候,可以将所有数据都存到一台机器上,只使用redis单机模式,不存在分片问题。如果业务的数据量超过一台物理机器的内存大小时,则会面对扩展问题,需要多台机器去存数据,此时,需要使用到redis的分片技术。如何分片redis通过分slot的方式进行分片。例如有A、B、C三台机器组成的一个集群。对于集群里面的节点而言,三者会全部覆盖16384个slots...原创 2018-11-25 21:43:31 · 2388 阅读 · 4 评论 -
异步业务系统的一个常用实现模式
业务场景一个系统,依赖很多外部系统的数据。对于一个请求过来,需要查询N个外部系统的数据,等全部数据拿到之后,做数据处理完之后,返回给请求端。如果依赖系统太长时间未返回,我们必须有一个超时响应机制返回给客户端。简单方案最简单的方案,就是通过同步的方式。一个客户端请求过来,假如依赖3个接口,则同步顺序的去请求三个接口,send1, recv1, send2, recv2, send3, recv...原创 2019-03-11 19:32:38 · 450 阅读 · 1 评论 -
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 · 1272 阅读 · 2 评论 -
学习GFS架构总结
基本问题为什么需要分布式?因为需要支持百万级的文件,单机无法满足,所以需要用许多廉价机器来协作完成。如何设计架构按最简单的来理解。我们存一个文件,就需要知道文件在磁盘中的位置。现在我们存大文件,我们则需要知道这个文件存在哪台机器上。顺着这个思路我们就构建了简单的索引->机器的架构。如下图所示:我们把元数据放到master机器上,然后把真正的物理文件,存放到chunk机器上。这种架...原创 2019-06-10 22:18:12 · 2288 阅读 · 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 · 3883 阅读 · 0 评论 -
压力测试的一点思考
最后工作中的项目,接近上线了,做了个完整的压力测试过程,对于压力测试,整个项目下来,有些自己的理解,这里简单总结如下:压测的目的1、检查系统是否要求业务需求,拿到系统的一些性能指标。一般情况下,例如峰值是1W/s的系统,压测的时候,需要能扛上2W/s基本就能满足要求(特殊业务可能另作评估)。并且输出压测报告,拿到一个对系统的量化指标,做到一切心中有数。2、发现系统存在的问题。很...原创 2018-09-03 23:50:41 · 253 阅读 · 0 评论 -
系统间歇性超时问题的分析与解决
【系统症状】后台系统A平均访问量约13K/min,峰值约30K/min。系统超时时间设置为500ms。系统每隔10分钟左右,会出现几十个请求包的超时。但该超时只持续1~2分钟又会自动恢复,百思不得其解。B系统访问A系统的超时视图如下所示:【寻医问药】请教了身边的几个同事,分析可能原因如下:1、机器跨IDC访问,网络抖动造成。2、依赖的外部接口多,外部接口本身访问比较原创 2013-03-19 20:43:11 · 3998 阅读 · 0 评论 -
事务型开发(如何设计防重入接口)
半年前,自己从BD来到一个创业小公司,开始接触事务型开发的一些基本技术。自己的服务器开发技术最开始部分源于腾讯,主要是使用服务器的单线程异步IO模型+UDP+状态机来做一些事情。对于很多高并发的服务是比较适用的。之后来到百度的一个团队,里面提倡使用TCP+多线程的网络模型。可以说各自有各自的优缺点。半年前来到小公司,开始接触一些类似电商业务的开发,跟之前接触的很多都不太一样。 首先原创 2015-12-03 11:36:32 · 7898 阅读 · 6 评论 -
zmq与libevent集成及丢包问题分析解决
libevent与socket使用事件方式进行编程的思路是:以zmq的订阅端为例子,订阅端与服务端的连接的fd(文件描述符)加入到libevent的监听队列中,并传入自己的回调函数。正常情况下,当有数据来的时候,libevent会调用用户传入的回调函数,在回调函数里面去将数据取出来即可。下面需要解决二个问题:1、如何取得zmq的socket值?使用getsockopt函数获取。原创 2017-07-06 21:35:28 · 2577 阅读 · 3 评论 -
标准IO重定向到文件非交互式设备时的缓冲策略
首先提两个熟悉的概念全缓冲:在进行I/O操作时,只有当I/O缓冲区被填满时,才进行真正的I/O操作。所以对于全缓冲的缓冲区可由标准I/O例程自动刷新,即当缓冲区填满时,还有一种方法就是调用函数fflush进行刷新。行缓冲:在I/O操作时,输入输出遇到换行符时进行,进行真正的I/O操作。对于行缓冲,标准I/O每一行缓冲区的长度是固定的,所以只要填满了缓冲区,即使没有遇到换行符,也换刷原创 2017-07-09 23:42:37 · 433 阅读 · 0 评论 -
zmq 多路复用poll无法收包的问题(朴素的比对法解决问题)
最近项目中使用ZMQ相关的库作为通讯组件,前期用得还算是比较顺利,API使用很简单而且易上手。用了是稳定的4.1.2版本C++版本。 近期忽然发现,一个服务,使用多路复用zmq::poll无法收到包。问题表现: 1)自己的机器上能正常使用poll收到包,没有问题。(自己的机器使用docker镜像环境在跑,代码在git上拉下来) 2)同事的机器上的相同的代码下,无原创 2017-09-22 16:24:57 · 1340 阅读 · 1 评论 -
shell 脚本中,grep无法读取前一个命令结果输出的一个原因
前几天,因为要实现一个小功能,想用shell脚本来写点逻辑。遇到一个问题这里记录分享一下:查看so文件中是否有未实现的函数,使用ldd查看,结果如下:我想通过获取ldd -r命令的结果中是否存在“undefined symbol"这样的结果。很自然会想到使用grep来获取便这样来写:check_res=`ldd -r name.so|grep undefin原创 2017-12-20 17:05:53 · 5269 阅读 · 0 评论 -
epgm在不同镜像的容器中,无法同时绑定地址的问题
问题背景两个不同镜像,记为A,B镜像,A镜像生成两个的容器A1,A2,B镜像生成B1,B2。使用zmq组件的,epgm方式进行通信,需要先进行地址绑定。表示该服务加入某个组播地址,订阅该组播的消息。问题表现:1、直接在A1,A2同时跑这段代码,没有问题。都能成功绑定组播地址。2、直接在B1,B2同时跑这段代码,也是没有问题,都能成功绑定组播地址。原创 2018-01-24 15:48:05 · 570 阅读 · 0 评论 -
ZMQ使用EPGM多端并发时,接收端收包乱序问题分析
问题背景在如下场景中出现问题,在发送端使用EPGM协议进行发送,会发送topic(带上more),再发送data数据。例如:A,B端发送数据到C端,A端分别为A1(带more标记),A2。B端分别发送B1(带more标记),B2。当A1,A2总数据量比较大时,例如大于1500字节时,C端收到的数据顺序为A1,B1,B2。出现乱序情况。相关测试结论:1、当A1、A2数据量比较小时,例如在几百个字节的...原创 2018-02-27 14:33:15 · 4256 阅读 · 7 评论 -
C++的一个编绎错误引发的问题分析 expected unqualified-id before ‘(’ token
今天在编绎一段代码的时候,忽然间,出现了一个比较诡异的错误,长这个样子【expected unqualified-id before ‘(’ token】,这里上个图可能会清楚一些。报错位置在X_pb.h文件的317行(X_pb.h这个文件是protobuf自动生成的)。第一反应即是这个文件是自动生成的,怎么可能会有问题?别急,我们一点点来看。找到这个文件的317行。眼睛瞪到最圆的程度,盯...原创 2018-06-11 21:43:12 · 136891 阅读 · 13 评论 -
makefile中的命令与普通的shell命令的区别
问题背景今天在makefile中,遇到一个场景,依赖一个目标,需要cd到其他文件夹里面执行一个操作。简单来说,可以描述成这样: lbm_mtl_server_mock.so这个目标的生成,我需要去到相关的目录去执行一个make操作。注:这里的LBM_MTL_SERVER_DIR=/workspace/branches/linux/pb_lbm/lbm_mtl_server然后,就遇到了一个问...原创 2018-06-13 16:53:03 · 431 阅读 · 0 评论 -
静态链接时被依赖的库放到后面的原因?
接着前一篇文章动态共享库引发的double free错误的分析,分析到的共享库的double free问题,这里接着谈一下我们经常在链接的过程中,经常处理的一个错误,就是被依赖的库,通过需要放到依赖库的后面,但之前一直不太清楚原因是什么。这里看到有位网友,把整个流程图画出来了,这里引用一下他的文章:《浅析静态库链接原理》,这里引用了他的流程图:主要原因是:1、对于静态依赖,其实就是.a文件中,依次...原创 2018-07-08 20:23:26 · 815 阅读 · 0 评论 -
如何使用protobuf的反射机制遍历所有已设置的FieldDescriptor*
背景在项目开发中,由于需要使用到一个protobuf的API, 用于对不同Message的比较过程中,设置浮点数比较精度的API,MessageDifferencer::SetFractionAndMargin(const FieldDescriptor * field, double fraction, double margin),需要传入一个Message的FieldDescri...原创 2018-07-09 12:17:17 · 8619 阅读 · 5 评论 -
动态共享库引发的double free错误的分析
问题背景项目中遇到了这么个场景:项目中,所有文件可以生成一个动态链接库A.so场景1:A.so 假设由N个.o生成,不妨假设由a.o,b.o生成。如果将main.cpp -> main.omain.o, a.o, b.o -> main_bin,运行./main_bin,运行正常。 场景2:将A.so、main.cpp,两个一起生成一个可执行程序即是main.cpp -> ma...原创 2018-07-02 21:41:42 · 2999 阅读 · 3 评论 -
全局变量链接顺序问题
背景问题最近同事项目中遇到一个问题,就是在main函数未启动之前,就出现崩溃。具体现场情况大致是使用了一个map,但这个map的insert操作直接导致崩溃。最终定位的原因,是map的定义是放到了另一个编绎单元之中,而使用map的时候,该map对象还未进行初始化。这是全局变量的初始化顺序问题,即是用到某个变量的时候,它其实还未初始化。问题简化知识点:1、全局变量的初始化,是在mai...原创 2018-07-16 20:46:44 · 817 阅读 · 0 评论 -
为什么中断信号SIGINT处理函数不生效?
问题背景一个测试可代码编的可执行程序中,执行开始之后,然后按下Ctrl-C,中断程序运行,看core文件,程序是跑到了一个第三方的库里面coredump了。问题初步分析正常的怀疑,就是自己没有安装中断处理函数,导致出问题。那么步骤1:尝试自己安装中断处理函数。自己的代码是一个zmq的poll阻塞式调用。在ZMQ系统开始初始化之前,安装了一个中断处理函数。函数代码大致如下:中断信号处理函数expan...原创 2018-06-28 16:53:57 · 1470 阅读 · 1 评论 -
vector bool 引发的如何发现问题的思考
前段时间,在项目开发过程之中,自己遇到了一个奇怪的问题。使用了vector<bool>,而将vector<bool>的元素值,作为引用值去传参数的时候,报了个莫名其妙的错。当时因为在赶进度,觉得根据自己的理解,可能一时半会搞不定,就没有深纠,另外,觉得这可能会是一个好问题,就先把这个问题记下来,先不管,尝试用其他办法先把项目实现先搞定,等主要工作完成之后,再尝试回过头来安排...原创 2018-07-07 09:56:54 · 629 阅读 · 0 评论 -
坑爹的if语句
前两天的时候,自己在修改代码的时候,自己感觉对调试比较有心得体会了。但遇到一个问题,总在一个函数中返回了false,明明条件就是不应该返回。修改前的示例代码如下: string topic = "topic is not empty";if (topic.empty()) return false;我想对这行代码加一个日志打印,示例如下:s...原创 2018-07-21 17:48:50 · 203 阅读 · 0 评论 -
我对字符编码的理解
背景开发这些年,一直有遇到字符编码这些问题,能一直在解决,但始终没有做到通透的水平,现在想尝试做一下归纳与总结。尝试从一个完全不懂的小白的角度,把问题讲清楚。问题为什么会存在字符编码?gbk、unicode是什么?UTF-8、UTF-16等与UNICODE什么关系?mysql里面存储的是数据,编码是解释层面的概念,而存储的时候,理论上都只是二进制而已,为什么存储的时候,需要指定什么类...原创 2019-09-30 00:04:41 · 509 阅读 · 0 评论