- 博客(375)
- 资源 (6)
- 收藏
- 关注
原创 nginx如何解决惊群效应
惊群效应(thundering herd)是指多进程(多线程)在同时阻塞等待同一个事件的时候(休眠状态),如果等待的这个事件发生,那么他就会唤醒等待的所有进程(或者线程),但是最终却只能有一个进程(线程)获得这个时间的“控制权”,对该事件进行处理,而其他进程(线程)获取“控制权”失败,只能重新进入休眠状态,这种现象和性能浪费就叫做惊群效应。
2024-07-02 22:33:04 1071
原创 c++之CRTP
CRTP,即奇异递归模板模式(Curiously Recurring Template Pattern),由James O. Coplien在其1995年的论文中首次提出,是C++中一个独特而强大的设计模式。它利用模板和继承的特性,允许在编译时进行多态操作,从而提高代码的性能和灵活性。通过CRTP技术,在某种程度上也可以实现多态功能,但其也仅限定于使用场景,正如局限性一节中所提到的,CRTP是一种特殊类型的多态性,在少数情况下可以替代动态多态性的需要;
2024-06-25 21:42:40 850
转载 内存优化总结:ptmalloc、tcmalloc和jemalloc
概述需求系统的物理内存是有限的,而对内存的需求是变化的, 程序的动态性越强,内存管理就越重要,选择合适的内存管理算法会带来明显的性能提升。比如nginx, 它在每个连接accept后会malloc一块内存,作为整个连接生命周期内的内存池。 当HTTP请求到达的时候,又会malloc一块当前请求阶段的内存池, 因此对malloc的分配速度有一定的依赖关系。(而apache的内存池是有父子关系的,请求阶段的内存池会和连接阶段的使用相同的分配器,如果连接内存池释放则请求阶段的子内存池也会自动释放)。
2021-06-26 21:23:15 2554
原创 整数拆分题
给定一个正整数n,将其拆分为至少两个正整数的和,并使这些整数的乘积最大化。 返回你可以获得的最大乘积。示例 1:输入: 2输出: 1解释: 2 = 1 + 1, 1 × 1 = 1。示例2:输入: 10输出: 36解释: 10 = 3 + 3 + 4, 3 ×3 ×4 = 36。说明: 你可以假设n不小于 2 且不大于 58。来源:力扣(LeetCode)链接:https://leetcode-cn.com/problems/integer-break著作权归领扣...
2021-06-17 23:12:24 432
原创 一次完整的HTTP请求
参考博客:http://www.cnblogs.com/engeng/articles/5959335.html http://www.cnblogs.com/engeng/articles/5943382.html一次完整的HTTP请求过程当我们在web浏览器的地址栏中输入: www.baidu.com,然后回车,到底发生了什么过程概览 1.对www.baidu.com这个网址进行DNS域名解析,得到对应的IP地址 2.根据这个IP,找到对应的服务器,发起TCP的三次握
2021-06-17 20:49:32 678 6
原创 利用栈结构实现O(1)查询最小值
题目描述定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1))。思路:利用两个栈来进行操作,一个存正常的栈数据,另一个辅助栈存放当前最小值。入栈时:如果当前没有最小值或者加入的数字小于等于当前的最小值则更新辅助栈,即push新数据,否则不操作,这里注意定义为小于等于就加入,而不是小于,因为比如出现两个相等最小,靠后那个数字被pop掉了此时最小还是那个数,所以辅助栈中维护的应该是一个单调不减的序列。出栈时:如果当前数据栈栈顶的元素等于辅助栈栈顶的元素,
2021-06-16 23:01:38 592
原创 远程工具之复制粘贴文件(基于OLE剪贴板调用资源管理器实现)
前言 最近公司基于底层云游戏串流方案衍生出一个远程产品,既然是远程产品,定然少不了双向传文件的功能,在windows操作系统上,相比于对话框这种形式的chuan
2021-06-12 15:12:51 1545 4
原创 Golang GC 垃圾回收机制详解
摘要在实际使用 go 语言的过程中,碰到了一些看似奇怪的内存占用现象,于是决定对go语言的垃圾回收模型进行一些研究。本文对研究的结果进行一下总结。什么是垃圾回收?曾几何时,内存管理是程序员开发应用的一大难题。传统的系统级编程语言(主要指C/C++)中,程序员必须对内存小心的进行管理操作,控制内存的申请及释放。稍有不慎,就可能产生内存泄露问题,这种问题不易发现并且难以定位,一直成为困扰开发者的噩梦。如何解决这个头疼的问题呢?过去一般采用两种办法:内存泄露检测工具。这种工具的原理一般是静态代码扫
2021-06-08 23:05:36 2246
原创 golang的内存模型
一、前言Go语言的内存模型规定了一个goroutine可以看到另外一个goroutine修改同一个变量的值的条件,这类似java内存模型中内存可见性问题(Java内存可见性问题可以参考拙作:Java并发编程之美一书)。当多个goroutine并发同时存取同一个数据时候必须把并发的存取的操作顺序化,在go中可以实现操作顺序化的工具有高级的通道(channel)通信和同步原语比如sync包中的Mutex(互斥锁)、RWMutex(读写锁)或者和sync/atomic中的原子操作。二、Happens
2021-06-07 23:22:16 3249
原创 golang的goroutine调度机制
一直对goroutine的调度机制很好奇,最近在看雨痕的golang源码分析,(基于go1.4)感觉豁然开朗,受益匪浅;去繁就简,再加上自己的一些理解,整理了一下~~调度器主要基于三个基本对象上,G,M,P(定义在源码的src/runtime/runtime.h文件中)1.G代表一个goroutine对象,每次go调用的时候,都会创建一个G对象2.M代表一个线程,每次创建一个M的时候,都会有一个底层线程创建;所有的G任务,最终还是在M上执行3.P代...
2021-06-07 22:40:22 2356
原创 迭代器失效的几种情况
本文根据常用的容器来总结迭代器失效的几种情况。1. 序列式容器:vector、deque,数组型或队列型数据结构。该数据结构分配在连续的内存中,当删除一个元素后,内存中的数据会发生移动以保证数据的紧凑。所以删除一个元素后,其他数据的地址发生了变化,之前获取的迭代器根据原有信息就访问不到正确的数据。解决方法:erase返回下一个有效迭代器的值,itVec=vecData.erase(itVec)。std::vector<int> vecData;vecData.push_back(
2021-04-14 16:12:09 1968
原创 libevent源码剖析-最小堆实现定时器
Libevent 源码下载可以去官网 githubLibevent使用堆来管理Timer事件,其key值就是事件的超时时间,源代码位于文件minheap-internal.h中。所有的数据结构书中都有关于堆的详细介绍,向堆中插入、删除元素时间复杂度都是O(lgN),N为堆中元素的个数,而获取最小key值(小根堆)的复杂度为O(1)。堆是一个完全二叉树,基本存储方式是一个数组。看函数名都挺好懂的,只是下面这个结构体变量命名比较坑....typedef struct min_heap...
2020-05-17 10:50:04 562
原创 探索单例模式
意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点。主要解决:一个全局使用的类频繁地创建与销毁。何时使用:当您想控制实例数目,节省系统资源的时候。如何解决:判断系统是否已经有这个单例,如果有则返回,如果没有则创建。关键代码:构造函数是私有的。应用实例:一个班级只有一个班主任。Windows 是多进程多线程的,在操作一个文件的时候,就不可避免地出现多个进程或线程同...
2020-05-04 09:43:04 269
原创 c++11新特性之右值引用
C++11 增加了一个新的类型,称为右值引用(R-value reference),标记为 T &&。在介绍右值引用类型之前先要了解什么是左值和右值。左值是指表达式结束后依然存在的持久对象,右值是指表达式结束时就不再存在的临时对象。一个区分左值与右值的便捷方法是:看能不能对表达式取地址,如果能,则为左值,否则为右值 。所有的具名变量或对象都是左值,而右值不具名。...
2020-05-03 10:43:34 576
原创 布隆过滤器(Bloom Filter)- 避免缓存穿透和海量数据处理之利器
缓存处理流程这种模式处理缓存通常都是先从数据库缓存查询,如果缓存没有命中则从数据库中进行查找。这里面会发生的三种情况如下:①缓存命中:当查询的时候发现缓存存在,那么直接从缓存中提取。②缓存失效:当缓存没有数据的时候,则从database里面读取源数据,再加入到cache里面去。③缓存更新:当有新的写操作去修改database里面的数据时,需要在写操作完成之...
2020-05-02 11:54:50 983
原创 snprintf_s使用时注意问题
最近在项目中看到不知名的某位人士调用snprintf_s 这个函数,然后尝试调用这个接口时出现了崩溃,可能接口不常用,竟然没人发现,尝试找出其中原因。问题描述:这段代码运行到delete 时会导致崩溃。函数描述:int _snprintf_s( char *buffer, size_t sizeOfBuffer, // 打算用于存储的缓冲区的宽度...
2020-05-01 10:32:52 7568
转载 通用轻量级二进制格式协议解析器
在通信协议中,经常碰到使用私有协议的场景,报文内容是肉眼无法直接看明白的二进制格式。由于协议的私有性质,即使大名鼎鼎的 Wireshark,要解析其内容,也无能为力。面对这种情况,开发人员通常有两个办法:第一,对照报文内容和协议规范进行人工分析(假设内容没有经过加密、压缩);第二,编程实现协议报文的解析(源于程序员的懒惰 ^_^)。很明显,第二条道路是主流。目前比较常见的实现方式是开发对应...
2019-01-10 14:52:44 1557 1
原创 一致性hash之负载均衡
目前现在的负载均衡主要采用取模的方式,如果有一个机器故障了,或者我想再添加一台机器怎么处理?现查到了一致性hash算法。自己看了一下资料:先说一下大概思想,一致性Hash主要是在分布式算法中用的比较多。1.我们现在常用的是线性hash,这样万一有一个机器坏掉了,就容易造成数据丢失。如果换成环形hash,一定范围内的hash映射的是环形的下一个节点,就不会对其它机器的数据造成太大影响。2...
2019-01-03 15:46:49 584
转载 分布式算法(一致性Hash算法)
一、分布式算法 在做服务器负载均衡时候可供选择的负载均衡的算法有很多,包括: 轮循算法(Round Robin)、哈希算法(HASH)、最少连接算法(Least Connection)、响应速度算法(Response Time)、加权法(Weighted )等。其中哈希算法是最为常用的算法. 典型的应用场景是: 有N台服务器提供缓存服务,需要对服务器进行负载均衡,将请求平均分发到每...
2018-12-27 15:44:55 336
转载 UML类图关系(C++)
♀ 双向关联(Association)CAssociation1和CAssociation2可以互相调用对方的公共成员函数和成员变量。代码触析:[cpp] view plain copyclass CAssociation1 { private: CAssociation2* m_pAssociation2; }; class CAssociation2 { privat...
2018-03-12 14:40:28 1092
转载 C语言实现面向对象的思想(实现封装、继承和多态)
由于C语言是面向过程的语言,在处理比较大的项目时,结构上会显得有些松散。管理起来不免力不从心。其实在使用C语言写程序的过程中,也可以引入一些面象对象的思想。下面我们主要来谈谈如何用C语言把这些思想表达出来:1. 封装这个最简单了,C语言中虽然没有类,但有struct。这可是个好东西。我们可以在一个struct中存入数据和函数指针,以此来模拟类行为。[cpp] vie
2017-09-17 22:25:55 987
原创 c++简单线程池实现
线程池,简单来说就是有一堆已经创建好的线程(最大数目一定),初始时他们都处于空闲状态,当有新的任务进来,从线程池中取出一个空闲的线程处理任务,然后当任务处理完成之后,该线程被重新放回到线程池中,供其他的任务使用,当线程池中的线程都在处理任务时,就没有空闲线程供使用,此时,若有新的任务产生,只能等待线程池中有线程结束任务空闲才能执行,下面是线程池的工作原理图:我们为什么要使用线程池呢
2017-09-13 21:36:27 627
原创 C++继承中的成员访问控制
由基类到派生类的过程中,在派生类里如何访问基类成员,以及派生类对象如何访问基类成员,是根据派生类在从基类派生时是以什么方式进行的派生:public、protect或者private。下面说一下在这三种派生方式下成员函数和成员变量的访问和修改权限。派生类是指直接派生类!【代码1】123456789
2017-09-10 14:34:57 592
转载 浅谈如何提高服务器并发处理能力
目录 (一)什么是服务器并发处理能力(二)有什么方法衡量服务器并发处理能力1.吞吐率2.压力测试(三)怎么提高服务器的并发处理能力1,提高CPU并发计算能力(1)多进程&多线程(2)减少进程切换,使用线程,考虑进程绑定CPU(3)减少使用不必要的锁,考虑无锁编程(4)考虑进程优先级(5)关注系统负载(6)关注CPU使用
2017-08-29 21:13:33 5212
转载 多进程与多线程
关于多进程和多线程,教科书上最经典的一句话是“进程是资源分配的最小单位,线程是CPU调度的最小单位”,这句话应付考试基本上够了,但如果在工作中遇到类似的选择问题,那就没有这么简单了,选的不好,会让你深受其害。 经常在网络上看到有的XDJM问“多进程好还是多线程好?”、“Linux下用多进程还是多线程?”等等期望一劳永逸的问题,我只能说:没有最好,只有更好。根据实际情况来判断,哪个更
2017-08-16 13:45:43 459
转载 LINUX内核面试题摘选
LINUX内核面试题摘选1) Linux中主要有哪几种内核锁?答:Linux的同步机制从2.0到2.6以来不断发展完善。从最初的原子操作,到后来的信号量,从大内核锁到今天的自旋锁。这些同步机制的发展伴随Linux从单处理器到对称多处理器的过渡;伴随着从非抢占内核到抢占内核的过度。Linux的锁机制越来越有效,也越来越复杂。linux的内核锁主要是自旋锁和信号量。
2017-08-16 10:47:00 1221
转载 数转化为二叉树
普通树转换为二叉树的方法是:①树中所有相同双亲结点的兄弟节点之间加一条连线②对树中不是双亲结点第一个孩子的结点,只保留新添加的该结点与左兄弟结点之间的连线,删去该结点与双亲结点之间的连线③整理所有保留和添加的的连线,使每个结点的第一个孩子结点连线位于左孩子指针位置,使每个结点的右兄弟结点连线位于右孩子指针位置:整个转换过程如下图从左到右所示
2017-08-16 10:01:22 3175
原创 有关析构函数和构造函数的几点说明
有关析构函数和构造函数的几点说明:构造函数和析构函数都不能被继承(构造函数和析构函数是用来处理对象的创建和析构的,它们只知道对在它们的特殊层次的对象做什么。所以,在整个层次中的所有的构造函数和析构函数都必须被调用而不能被继承。)构造函数可以重载,析构函数不可以重载(构造函数可以有参数,析构函数没有参数。)构造函数不可以是虚函数,析构函数可以是虚函数(1. 构造函数为什么不能为
2017-08-16 09:56:22 640
原创 实现生产组和消费者的机制,利用共享内存实现文件的打开和读写操作,PV操作。
/*sem_com.h*/#include#include#include#include#includeunion semun{ int val; struct semid_ds *buf; unsigned short *array;};/*信号量初始化(赋值)函数*/int init_sem(int sem_id,int init_valu
2017-08-15 15:32:34 1335
原创 采用管道函数创建有名管道,使用select函数替代使用poll函数实验多路复用
创建两个有名管道,获取3个文件描述符(2个管道,1个标准输入),然后初始化读文件描述符,select监视文件描述符 的文件读写,管道1输出到屏幕上,管道2输出到屏幕上,标准输入‘Q’来进行判读是否退出。/*pipe_select.c*/#include#include#include#include#include#include#include#def
2017-08-15 15:23:51 1308
原创 文件锁以及多路复用方式解决多个用户对一个文件的操作
一、文件锁用于多个用户共同使用或操作同一个文件。有读锁的时候可以再加读锁,不能再加写锁。有写锁的时候,不能加任何锁,加读锁时,该描述符必须是读打开,加写锁时,该描述符必须是写打开,且只在进程间有用。 使用flock(锁定文件或解除锁定)函数 头文件 #include 定义函数 int flock(int fd,int operation); 函数说明 flo
2017-08-10 20:11:12 891
原创 内存分配、野指针、指针、数组相关
内存分配方式有哪些?什么是内存泄漏?什么是野指针?如何避免野指针?什么时候将引用作为返回值?引用与指针的区别?数组与指针的区别?函数指针与指针函数的区别?数组指针与指针数组的区别?指针常量与常量指针的区别?函数模板与模板函数的区别?类模板与模板类的区别?重载overload、覆盖overwrite、隐藏override的区别
2017-08-09 15:31:38 735
原创 关键字的作用及区别汇总
static关键字static关键字具有隐藏式、记忆、延长生命周期的作用。在C语言中,static既可以修饰变量,也可以修饰函数。1) 修饰的变量保存在静态数据区,静态变量默认初始化为0,只初始化一次。2) 修饰局部变量,延长变量的生命周期,直到程序运行结束,下一次运行依据是上一次的运行结果,体现其记忆功能。3) 修饰全局变量,只在本文
2017-08-08 16:58:51 3952
转载 c++设计一个不能被继承的类
摘要:使用友元、私有构造函数、虚继承等方式可以使一个类不能被继承,可是为什么必须是虚继承?背后的原理又是什么?用C++实现一个不能被继承的类(例1) 1 #include 2 using namespace std; 3 4 template 5 class Base{ 6 friend T; 7 private: 8 Base
2017-08-02 11:14:27 369
原创 信号量与互斥锁之间的区别
1. 互斥量用于线程的互斥,信号量用于线程的同步。 这是互斥量和信号量的根本区别,也就是互斥和同步之间的区别。 互斥:是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的。 同步:是指在互斥的基础上(大多数情况),通过其它机制实现访问者对资源的有序访问。在大多数情况下,同步已经实现了互斥,特别是所有写入资源的情况必定是互斥的。
2017-07-26 10:46:41 867
原创 C++11 STL中的容器
C++11 STL中的容器==================================================一、顺序容器:vector:可变大小数组;deque:双端队列;list:双向链表;forward_list:单向链表;array:固定大小数组;string:与vector相似的容器,但专门用于保存字符。
2017-07-26 09:44:34 309
原创 C++面试题总结1
http://blog.csdn.net/jingxuewang110/article/details/6736142 内容摘要:1.static有什么用途?(请至少说明两种) 1)在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变。 2) 在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问。它
2017-07-20 13:13:02 340
原创 各种常用的排序算法实现对数组的排序——整理总结(代码实现)
冒泡排序、插入排序、折半排序(二分插入排序)、快速排序、选择排序、归并排序、希尔排序、堆排序
2017-07-13 11:14:09 823
C++实现一致性hash算法
2019-01-03
软考软件设计师复习资料
2017-04-21
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人