- 博客(43)
- 收藏
- 关注
原创 线上服务器CPU占用率过高如何排查
排查过程终端执行top命令,查看CPU占用情况(定位进程)$top PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 1893 admin 20 0 7127m 2.6g 38m S 181.7 32.6 10:20.26 java通过以上命令,我们可以看到,进程ID为1893的Java进程的CPU占用率达到了181%,基本可以定位到是我们的Java应用导致整个服务器的CPU占用率飙升。
2021-09-23 10:41:03
543
原创 MySQL主从复制详解
原理MySQL主从复制是基于主服务器在二进制日志跟踪所有对数据库的更改。因此,要进行复制,必须在主服务器上启用二进制日志。每个从服务器从主服务器接收已经记录到日志的数据,当一个从服务器连接到主服务器时,它通知主服务器从服务器日志中读取最后一个更新成功的位置。从服务器接收从那时发生起的任何更新,并在主机上执行相同的更新。然后封锁等待主服务器通知的更新。从服务器执行备份不会干扰主服务器,在备份过程中主服务器可以继续处理更新。工作过程MySQL 的主从复制工作过程大致如下:从库生成两个线程,一个I
2021-07-27 10:34:04
399
原创 Linux平台下优于select的epoll
基于select的I/O复用技术速度慢的原因调用select函数后常见的针对所有文件描述符的循环语句每次调用select函数时都需要向该函数传递监视对象信息调用select函数后,并不是把发生变化的文件描述符单独集中到一起,而是通过观察作为监视对象的fd_set变量的变化,找出发生变化的文件描述符,因此无法避免针对所有监视对象的循环语句。而且,作为监视对象的fd_set变量会发生变化,所以调用select函数前应复制并保存原有信息,并在每次调用select函数时传递新的监视对象信息(每次调用s
2021-07-25 16:40:18
310
原创 详述I/O复用中的select函数
select函数的功能和调用顺序使用select函数时可以将多个文件描述符集中到一起统一监视。调用顺序如下:设置文件描述符首先要将监视的多个文件描述符集中到一起,集中时按照监视项(接收、传输、异常)进行区分,按照上述3种监视项分成三类。可以使用fd_set数组执行此项操作,该数组是存有0和1的位数组,当某位设置为1,则表示该文件描述符是监视对象,反之,则不是。在fd_set变量中注册或更改值的操作由以下宏完成:FD_ZERO(fd_set *fdset) : 将fd_set变量的所有位初
2021-07-23 16:16:28
194
原创 简述进程变为僵尸进程的过程以及预防措施
简述进程变为僵尸进程的过程以及预防措施当一个父进程以fork()系统调用建立一个新的子进程后,核心进程就会在进程表中给这个子进程分配一个进入点,然后将相关信息存储在该进入点所对应的进程表内。这些信息中有一项是其父进程的识别码。而当这个子进程结束的时候(比如调用exit命令或者main函数return返回值结束),其实他并没有真正的被销毁,而是留下一个称为僵尸进程(Zombie)的数据结构(系统调用exit的作用是使进程退出,但是也仅仅限于一个正常的进程变成了一个僵尸进程,并不能完全将其销毁)。预防措施:
2021-07-23 14:19:19
401
原创 Nagle算法
Nagle算法简介只有收到前一数据的ACK消息时,Nagle算法才发送下一数据。TCP默认开启Nagle算法进行数据传输,因此最大限度地进行缓冲,直到收到ACK。 如上图所示,为了发送字符串"Nagle",将其传递到输出缓冲,此时第一个字母"N"之前没有其他数据(没有需接收的ACK),因此立即传输。之后开始等待字母"N"的ACK消息,等待过程中,剩下的"agle"填入输出缓冲。接下来,收到字母"N"的ACK消息后,将输出缓冲的"agle"装入一个数据包发送。也就是说共需传递4个数据包以传输1个字符串
2021-07-23 09:45:56
1156
原创 利用C++11提供的std::thread类来创建线程
利用C++11提供的std::thread类来创建线程#include <stdio.h>#include <thread>void threadproc1() { while (true) { printf("I am New Thread 1!\n"); }}void threadproc2(int a, int b) { while (true) { printf("I am New Thread 2!\n"); }}int main(){
2021-07-18 11:13:55
382
原创 在Linux系统下用gdb调试多线程程序
调试多线程程序的方法使用gdb将程序跑起来,然后按下CTRL+C中断程序,使用info threads命令查看当前进程有多少线程;使用thread 线程编号可以切换到对应的线程,使用bt命令查看对应的线程从顶层到底层的函数调用堆栈情况以及上层调用下层对应源码的位置,使用frame 栈函数编号 切换到当前函数调用堆栈的任何一层函数调用中,然后分析该函数的执行逻辑,使用print等命令输出各变量和表达式的值,或者使用n进行单步调试,使用s进入函数内部单步调试。在调试时控制线程切换当单步调试线程A时,
2021-07-15 15:27:31
414
原创 细谈C++智能指针
C++智能指针提出的本意是内存泄漏的背景,不想手动去管理内存,交给一个类去管理,当类离开自身的作用域时会自动调用析构函数,释放已申请的内存。auto_ptr所有的智能指针类均被定义与头文件中两个基本的初始化方式:// 方式1std::auto_ptr<int> sp1(new int(1));// 方式2std::auto_ptr<int> sp2;sp2.reset(new int(1));智能指针(smart pointer)sp1和sp2均持有一个在堆
2021-07-14 14:36:40
194
原创 HTTPS通信流程详解
HTTPS的通信步骤客户端发送报文给服务器开始进行SSL通信。报文中包含客户端支持的SSL指定版本、客户端生成的随机数、加密组件(加密算法以及密钥长度)。服务器发送响应报文给客户端。和客户端一样,报文中包含SSL版本、服务器生成的随机数、加密组件(从接收到的客户端加密组件内筛选出来的)。服务器把公钥证书发送给客户端,自己保存着私钥。 服务器把自己的公钥登陆至数字证书认证机构,数字证书认证机构用自己的私钥向服务器的公钥署数字签名并颁发公钥证书。服务器发送报文告知客户端最初阶段的SSL握手协商部分结束
2021-07-11 12:37:36
932
原创 数据库引擎InnoDB与MyISAM的区别
数据库引擎InnoDB与MyISAM的区别InnoDB是 MySQL默认的事务型存储引擎,只有在需要它不支持的特性时,才考虑使用其它存储引擎。实现了四个标准的隔离级别,默认级别是可重复读(REPEATABLE READ)。在可重复读隔离级别下, 通过多版本并发控制(MVCC)+ 间隙锁(Next-Key Locking)防止幻影读。主索引是聚簇索引,在索引中保存了数据,从而避免直接读取磁盘,因此对查询性能有很大的提升。内部做了很多优化,包括从磁盘读取数据时采用的可预测性读、能够加快读操作并且自动
2021-07-09 16:50:47
127
原创 TCP和UDP的区别
TCP和UDP的区别TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接。TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付。每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信。TCP首部开销20字节;UDP的首部开销小,只有8个字节。TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道。TCP是面向字节流的,它把上面应用层交下来的数据
2021-07-08 19:30:14
180
1
原创 常见的HTTP状态码有哪些
常见的HTTP状态码1xx 信息100 Continue :表明到目前为止都很正常,客户端可以继续发送请求或者忽略这个响应。2xx 成功200 OK204 No Content :请求已经成功处理,但是返回的响应报文不包含实体的主体部分。一般在只需要从客户端往服务器发送信息,而不需要返回数据时使用。206 Partial Content :表示客户端进行了范围请求,响应报文包含由Content-Range 指定范围的实体内容。3xx 重定向301 Moved Permanently :永久
2021-07-08 17:03:08
122
原创 在执行malloc申请内存的时候,操作系统是怎么做的
执行malloc动态申请内存时,操作系统的做法从操作系统层面上看,malloc是通过两个系统调用来实现的: brk和mmapbrk是将进程数据段(.data)的最高地址指针向高处移动,这一步可以扩大进程在运行时的堆大小。mmap是在进程的虚拟地址空间中寻找一块空闲的虚拟内存,这一步可以获得一块可以操作的堆内存。通常,分配的内存小于128k时,使用brk调用来获得虚拟内存,大于128k时就使用mmap来获得虚拟内存。进程先通过这两个系统调用获取或者扩大进程的虚拟内存,获得相应的虚拟地址,在访问这些
2021-07-06 22:34:06
1000
原创 关于死锁的总结
死锁的概念各进程互相等待对方手里的资源,导致各进程都阻塞,无法向前推进。死锁、饥饿、死循环的区别死锁至少是两个进程一起死锁,死锁进程处于阻塞态。饥饿可以是只有一个进程饥饿,饥饿进程可能阻塞也可能就绪死循环可能只有一个进程发生死循环,死循环的进程可上处理机。死锁和饥饿是操作系统要解决的问题,死循环是程序员要解决的。死锁产生的必要条件互斥条件对必须互斥使用的资源的争抢才会导致死锁。不可剥夺条件进程保持的资源只能主动释放,不可强行剥夺。请求和保持条件保持着某些资源不放的同时,请
2021-07-06 21:50:15
296
原创 Linux系统下进程间通信方式
进程间的各种通信方式1、无名管道(pipe):允许一个进程和另一个与它有共同祖先的进程(具有亲缘关系的进程)之间进行通信。特点:是一种特殊的文件,只存在于内存中;只能用于具有亲缘关系的进程间的通信;只能由一端向另一端发送数据,是半双工方式,如果双方需要同时收发数据需要两个管道。2、有名管道(FIFO):类似于管道,但是它可以用于任何两个进程之间的通信,有名管道在文件系统中有对应的文件名,命名管道通过命令mkfifo或系统调用mkfifo来创建。特点:是FIFO文件,存在于文件系统中,可以通过文件路径名
2021-07-05 17:03:19
292
原创 hashtable中解决冲突的方法
hashtable中解决冲突的方法线性探测使用hash函数计算出的位置如果已经有元素占用了,则向后依次寻找,找到表尾则回到表头,直到找到一个空位。开链每个表格(bucket)维护一个list,如果hash函数计算出的格子(bucket)相同,则按顺序存在这个list中。再散列发生冲突时使用另一种hash函数再计算一个地址,直到不冲突。二次探测使用hash函数计算出的位置如果已经有元素占用了,按照121^212、222^222、323^232…的步长依次寻找,如果步长是随机数序列,则称之为伪随
2021-06-30 17:01:16
450
原创 C++中STL的优先级队列(priority_queue)的关键源码与测试
priority_queue的关键源码template <class T, class Squence = vector<T>,class Compare = less<typename Sequence::value_tyoe>>class priority_queue{...protected: Sequence c; // 底层容器 Compare comp; // 元素大小比较标准public: bool empty() const {re
2021-06-30 16:13:12
246
原创 C++用vector容器实现堆的相关算法
C++用vector容器实现堆的相关算法#include <iostream>#include <algorithm>#include <vector>using namespace std;int main() { vector<int> v = {0, 1, 2, 3, 4, 5, 6}; make_heap(v.begin(), v.end()); // 以vector为底层容器构造大根堆(底层是完全二叉树) for (auto i :
2021-06-30 15:43:42
238
原创 实现智能指针shared_ptr
智能指针shared_ptr代码实现template<typename T>class SharedPtr{public: SharedPtr(T* ptr = NULL):_ptr(ptr), _pcount(new int(1)) {} SharedPtr(const SharedPtr& s):_ptr(s._ptr), _pcount(s._pcount) { (*_pcount)++; } SharedPtr<T>&
2021-06-29 19:12:52
116
原创 CMake的使用
CMake简介CMake是一种跨平台的安装编译工具,可以用简单的语句来描述所有平台的安装(编译过程)。CMake可以说已经成为大部分C++开源项目标配。语法特性介绍基本语法格式:指令(参数1 参数2)参数使用括弧括起参数之间使用空格或分号分开指令是大小写无关的,参数和变量是大小写相关的set(HELLO hello.cpp)add_executable(hello main.cpp...
2021-06-29 16:17:03
392
原创 检查、定位内存泄漏
检查、定位内存泄漏检查方法在main函数最后面一行,加上一句_CrtDumpMemoryLeaks()。调试程序,自然关闭程序让其退出,查看输出。输出这样的格式:{453} normal block at 0x02432CA8, 868 bytes long被{}包围的453就是我们需要的内存泄漏定位值,868 bytes long就是说这个地方有868比特内存没有释放。定位代码位置加上头文件#include <crtdbg.h>在main函数第一行加上_CrtSetBreak
2021-06-28 21:57:40
81
原创 基于Linux系统的C++开发环境搭建(以Ubuntu系统为例)以及GCC编译器和GDB调试器介绍
基于Linux系统的C++开发环境搭建GCC编译器、GDB调试器的安装启动终端命令行安装sudo apt update# 通过以下命令安装GCC编译器和GDB调试器sudo apt install build-essential gdb安装成功后检查# 以下命令确认每个软件是否安装成功# 如果成功显示版本号gcc --versiong++ --versiongdb --versionCMake安装启动终端命令行安装# 通过以下命令安装CMakesudo apt instal
2021-06-28 20:08:57
345
原创 C++从代码到可执行程序经历了什么?
C++从代码到可执行程序的经历1、预编译主要处理源代码文件中的以“#”开头的预编译指令。处理规则见下:删除所有的#define,展开所有的宏定义。处理所有的条件预编译指令,如“#if”、“#endif”、“#ifdef”、“#elif”和“#else”。处理“#include”预编译指令,将文件内容替换到它的位置,这个过程是递归进行的,文件中包含其他文件。删除所有的注释,“//”和“/**/”。保留所有的#pragma 编译器指令,编译器需要用到他们,如:#pragma once 是为了防止
2021-06-27 21:25:47
613
1
原创 浅谈HTTP请求GET与POST方法
GET与POST的区别GET请求在URL中传送的参数是有长度限制的,而POST没有。GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。而POST数据不会显示在URL中,是放在Request body中。对参数的数据类型,GET只接受ASCII字符,而POST没有限制。GET请求参数会被完整保留在浏览器历史记录里;相反,POST请求参数也不会被浏览器保留。GET请求只能进行url编码( application/x-www-form-urlencoded),而POST支
2021-06-27 16:42:37
371
原创 const char*、string、char*三者之间的转换
const char*、string、char*三者之间的转换string转const char*string s1 = "abc";const char* cc1 = s1.c_str();const char* 转stringconst char* cc2 = "abc";string s2(cc2);string 转char*string s3 = "abc";char* c1;const int len = s1.length();c1 = new char[len + 1
2021-06-25 12:08:11
391
原创 Nginx学习心得
NginxNginx简介Nginx 是高性能的HTTP 和反向代理的服务器,处理高并发能力是十分强大的,能经受高负载的考验,有报告表明能支持高达50000个并发连接数。Nginx特点正向代理指的是客户端通过代理服务器(梯子)来访问外网。反向代理反向代理,其实客户端对代理是无感知的,因为客户端不需要任何配置就可以访问,我们只需要将请求发送到反向代理服务器,由反向代理服务器去选择目标服务器获取数据后,在返回给客户端,此时反向代理服务器和目标服务器对外就是一个服务器,暴露的是代理服务器地址,隐藏了真实
2021-06-15 21:26:25
322
原创 Linux有关防火墙与修改端口号命令
CentOS有关防火墙的开关和重启以及端口号相关命令开启防火墙service firewalld start关闭防火墙service firewalld stop重启防火墙service firewalld restartfirewall-cmd --reload # 修改配置文件后要重启防火墙查看防火墙规则firewall-cmd --list-all查看8080端口是否开放firewall-cmd --query-port=8080/tcp开放80端口firewall
2021-06-14 20:58:25
273
原创 在Mac系统上写一个简易的关于centos系统的Dockerfile文件测试运行并发布到远程dockerhub上
在Mac系统上写一个简易的Dockerfile并测试运行编写Dockfile在家目录下创建一个用于写dockfile的目录并进入huxiaojing@huxiaojingdeMacBook-Pro% mkdir Dockerhuxiaojing@huxiaojingdeMacBook-Pro% cd Docker/huxiaojing@huxiaojingdeMacBook-Pro% mkdir dockerfilehuxiaojing@huxiaojingdeMacBook-Pro% cd d
2021-06-14 14:58:05
672
原创 关于Mac上无法进入/var/lib/docker/volumes/的解决方法
关于Mac上无法进入/var/lib/docker/volumes/的解决方法由于docker for mac是安装在一个虚拟机中的,所以我们需要通过screen命令来链接。当使用:screen ~/Library/Containers/com.docker.docker/Data/vms/0/tty如果这一步成功了,进去之后默认是空白页面,需要按下Enter,可以直接cd进 /var/lib/docker/…如果需要干掉这个screen,按ctrl+a + k,最后按y确认即可以kill掉这个
2021-06-14 12:58:08
4240
2
转载 docker部分命令总结
docker部分命令 attach Attach local standard input, output, and error streams to a running container #当前shell下 attach连接指定运行的镜像 build Build an image from a Dockerfile # 通过Dockerfile定制镜像 commit Create a new image from a container's changes
2021-06-13 23:47:59
129
原创 Redis学习笔记
在B站大学学完狂神说的Redis(https://www.bilibili.com/video/BV1S54y1R7SB)后,总结的笔记。Redis基础的知识默认端口号是6379,Redis是单线程的,将所有的数据全部放在内存中的,多次读写都是在一个CPU上的,而多线程CPU上下文会切换,所以单线程的Redis会很快。select 3 #切换3号数据库 总共16个数据库 默认0号数据库DBSIZE #查看当前库的大小keys * #查看当前数据库的所有的keyflushdb #清空当前数据库
2021-06-13 20:36:02
388
原创 用C++简易设计一个string类
用C++实现string类#include<iostream>#include<cstring>using namespace std;class My_String {public: My_String(const char* str = nullptr);// 默认构造函数 My_String(const My_String& str);// 拷贝构造函数 My_String& operator=(const My_String& str
2021-06-09 22:23:14
577
原创 用C++实现字符串循环右移
字符串循环右移n个单位编写一个函数,作用是把一个char组成的字符串循环右移n个单位,比如源字符串是"helloworld",循环右移3个单位后,目标字符串是"rldhellowo"。#include<iostream>using namespace std;#define MAX_LEN 20void loopMove(char* strSrc, int n) { int N = strlen(strSrc) - n; char temp[MAX_LEN]; strcpy(t
2021-06-09 10:45:55
2339
原创 用C++实现一个将字符串转换为数字的函数
用C++实现函数atoi()#include<iostream>#include<cmath>using namespace std;int myAtoi(const char* str) { int num = 0;// 保存字符串转换为数字的结果 bool isNegative = 0;// 判断字符串中是否存在正负号 int n = 0; const char* p = str; if (p == nullptr) return -1;// 字符串为空则转为
2021-06-08 11:57:17
909
原创 C++四种强制类型转换
C++四种cast转换const_cast用于移除const特性,将const类型转换为非const类型。static_cast用于各种隐式转换,非多态类型的转换,如将非const类型转换为const类型,void*转换为指针,float类型转换为int类型等,能用于多态向上转换安全(子类转化为父类是安全的),向下转换不安全(父类转换为子类是不安全的,因为子类可能有不在父类的字段或方法)。dynamic_cast用于多态类型的转换(包括向上转换和向下转换都是安全的),只适用于指针或引用,对于不明
2021-06-08 09:53:20
193
原创 用C++快速计算8位无符号二进制数中1的个数
求一个8位无符号二进制数中1的个数法一:对该数不断除以2后看其余数是否为1,并计算余数为1的次数#include<iostream>using namespace std;int countFunction(int x) { int result = 0; while (x) { if (x % 2 == 1) { result++; } x /= 2; } return result;}int main(){ int x = 196; int r
2021-06-08 08:53:08
1282
原创 用C++实现数组的二分查找算法
二分查找算法原理:在使用二分查找算法之前先要确定被查找的数组必须有序的,即确定待寻找的元素的范围是[low, high],然后逐步缩小范围直到找到或找不到该元素为止。具体做法是:先取数组中间位置(mid=(low+high)/2)的数据元素与给定值比较。若相等,则查找成功;否则,若给定值比该数据元素的值小(或大),则给定值必在数组的前半部分[low,mid-1](或后半部分[mid+1,high]),然后在新的查找范围内进行同样的查找。如此反复进行,直到找到数组元素值与给定值相等的元素或确定数组中没有待查
2021-06-05 21:41:48
2423
原创 用C++来写一个测试闰年代码
判断闰年的方法年份能被400整除能被4整除但不能被100整除代码实现bool Leap_Yaer(int year){ return ((year % 400 == 0) || (year % 4 == 0 && year % 100 != 0));}int main(){ int year; printf("请输出你要判断的年份:\n"); scanf("%d", &year); if (Leap_Yaer(year)) { printf("%
2021-06-05 21:11:15
1435
原创 常用Linux命令
常用Linux命令关机$ shutdown -h now #立刻关机$ shutdown -h 5 #5分钟后关机$ shutdown -h 9:00 #9:00关机$ shutdown -h +5 #预定时间关机(5分钟后关机)$ shutdown -c #取消指定时间关机$ init 0 #立刻关机$ telinit 0 #关机$ poweroff #立刻关机$ halt #关机重启$ shutdown -r now #立刻重启$ shutdown -r 5 #5分钟后重启
2021-06-04 15:33:23
213
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人