自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

原创 docker查看运行时容器的IP地址

查看容器的ip地址

2022-09-07 22:17:08 292

原创 Linux网络发送和接收内核缓冲区大小的设置

网络发送缓冲区和接收缓冲区

2022-08-24 21:27:26 214

原创 linux网络编程之socket,bind,listen,connect,accept

网络编程常用API

2022-08-24 21:05:10 83

原创 网络中的交换机和路由器

网络中交换机和路由器简单介绍

2022-08-01 15:30:18 34

原创 用户级线程和内核级线程

用户级线程和内核级线程

2022-06-27 22:38:39 209

原创 Linux系统线程创建的过程

Linux系统线程创建的流程

2022-06-26 23:06:37 321

原创 Linux中进程的创建过程

Linux系统的产生

2022-06-26 21:57:56 538

原创 0号进程,1号进程,2号进程

是一个内核进程,是所有进程的祖先,也叫做swapper进程。主要作用:执行start_kernel()函数,初始化内核需要的所有数据结构,激活中断,创建1号内核进程(init进程)。只有当没有可运行的进程的时候,才会运行0号进程,0号进程不是一个实实在在可见的进程,它是单用户,单任务的系统启动代码由0号进程创建的1号进程,pid=1,1号进程共享0号进程的所有的数据结构。1号进程一开始是内核进程,先执行init()函数完成内核初始化,然后调用exec()装入可执行程序init(),这样init就变成可

2022-06-26 14:58:45 422

原创 容器适配器复习

实际上,容器适配器在工作中使用的不是特别多,所以对这些东西的个别细节难免有些遗忘,今天这里回顾一下。什么是适配器适配器类底层组合了已经有的容器对象,对外开发一些接口,这些接口实际上是对容器接口的封装,或者直接调用容器对象的方法。容器适配器没有自己的数据结构,没有自己的迭代器,实现全部依赖于底层的组合的容器。比如,template <class T,class Container = deque<T>>class stack{public: void pop() {

2022-05-30 20:55:01 43 1

原创 再聊C++多重继承之菱形继承

菱形继承的问题和内存布局class Base{public: Base(int){ std::cout << "Base()" << std::endl; }; ~Base(){ std::cout << "~Base()" << std::endl; };protected: int n;};class A : public Base{public: A(int a):Base(a){ std::cout <&lt

2022-05-14 16:16:42 177

原创 C++中如何定义指向类成员的指针

简单示例class Test{public: Test(){ std::cout << "Test()" << std::endl; }; void show() { std::cout << "show()" << std::endl; } static void fun(){ std::cout << "fun()" << std::endl; } int a; static int b;

2022-05-08 21:28:53 318

原创 再聊C++抽象类

什么是抽象类含有纯虚函数的类就叫做抽象类。抽象类不能定义对象,但是可以定义指针和引用。class Occupation{public: Occupation(){ std::cout << "Occupation()" << std::endl; }; //纯虚函数 基类给派生类预留的统一的接口,派生类必须实现 virtual void work() = 0;};再派生类中,纯虚函数必须实现,否则派生类还是一个抽象类:class Student : pub

2022-05-08 21:04:51 291

原创 C++中何时静态绑定,何时识别RTTI类型进行动态绑定?

静态绑定:编译时期就确定调用的是哪个方法,如模板,函数重载等动态绑定:程序运行时才确定调用的是哪个方法,即多态。何时静态绑定,何时识别RTTI进行动态绑定无论是基类指针(引用)指向基类对象,还是派生类指针(引用)指向基类对象,还是基类指针(引用)指向派生类对象,只要该指针调用的方法是一个虚函数,那么将发生动态绑定两要素:指针或者引用调用了虚函数。class Occupation{public: Occupation(){}; void show() { std::cout <&

2022-05-08 17:22:56 264

原创 C++虚析构函数

为什么需要将基类析构函数设置为虚函数我们来观察下面这段代码的表现:class Occupation{public: Occupation(){ std::cout << "Occupation()" << std::endl; }; ~Occupation(){ std::cout << "~Occupation()" << std::endl; }; void show() { std::cout << "Occupation

2022-05-08 16:24:46 379

原创 ubuntu创建.deb安装文件,亲测可行

创建比如说,作为C/C++程序员的我给用户提供了一些功能,我可以把头文件和动态库打包成一个deb文件交给用户使用。假设,我给用户的包名叫libmytools,首先第一步,先创建一个文件夹,叫libmytools,并且创建两个子目录,一个叫DEBIAN,一个叫usr/local。其中local中又包含include和lib两个目录,分别存放要给用户的头文件和动态库:然后,在DEBIAN目录下创建一个control文件,该文件记录的该deb的主要信息,我在这里举一个简单使用例子来说明该文件:Pac

2022-05-07 16:10:20 155

原创 C++中哪些函数可以被设置为虚函数

成为虚函数的前提/要求虚函数将来是要被存放在虚函数表中的,所以函数能被取地址l;而虚函数表是存放在对象的前四个字节(一般),所以函数的需要调用依赖对象,取出对象的虚函数表的地址。常见函数鉴别:构造函数:不可以,此时对象不存在(构造函数中调用的任何函数都是静态绑定)析构函数:可以静态成员方法:不可以,静态方法调用不依赖对象...

2022-04-17 20:40:55 678

原创 C++虚函数,虚函数表指针和虚函数表详解

class Occupation{public: Occupation(){}; virtual void show() { std::cout << "Occupation::show()" << std::endl; } virtual void show(int) { std::cout << "Occupation::show(int)" << std::endl; }private: int name_;};虚函数被virtua

2022-04-17 20:24:14 501

原创 C++继承中,支持从下到上的转换

实例继承中支持的是从下到上的转换。比如有个基类叫职业类, class Occupation;class Occupation{public: Occupation(); virtual ~Occupation();};然后可以派生出学生类,老师类,程序员类等, 如class Student;class Student : public Occupation{public: Student(); ~Student();};我们可以将派生类对象赋值给一个基类对象,换言之,学生

2022-04-17 11:43:04 546

原创 C++中将thread_local变量的声明和定义分开

声明://Test.h#include <thread>extern thread_local int id;定义#include "Test.h"thread_local int id= 0;

2022-04-08 15:23:47 515

原创 CPU计算和磁盘IO重叠运行提升系统性能(磁盘,网络IO基本过程)

应用程序从磁盘中读取数据的过程:调用read()系列函数,产生系统调用,陷入内核态;CPU设置DMA,包括数据源地址,数据目的地址,数据长度;向磁盘设备控制器发送指令,要求磁盘控制器将目标数据搬运到内存中;磁盘控制器将数据存放到指定的自己的缓冲区,达到一定条件后,将控制器中的数据拷贝到内存中(此时是内核态的内存空间,该过程是DMA的过程,是两个高速存储介质之间的数据搬运);向DMA确认成功,DMA控制器产生一个中断给CPU,中断服务程序返回用户态,继续执行中断时的下一条指令;将内核空间内存中数

2022-04-04 20:32:11 590

原创 操作系统如何与外部设备交互

计算机硬件系统架构:实际上,IO总线又可以分为常规IO总线和外围IO总线,常规IO总线是离CPU比较近的总线,即主要用于对时延要求高的设备,比如说显示器;外围总线相反。设备控制器:磁盘有磁盘控制器,打印机有打印机控制器,显卡有显卡控制器,键盘鼠标也有自己的控制器…CPU是不会直接去和这些设备打交道的,对于这些各种各样的外部设备都是由设备控制器去进行控制的拿打印机的设备控制器来举例子,打印机设备控制器主要分为两大部分,寄存器部分和接口控制电路。其中寄存器分为命令寄存器,数据寄存器,状态寄存器

2022-04-04 15:49:02 1511

原创 如何前向声明名字空间中的类

namespace A{ class Foo;}

2022-03-27 21:18:08 400

原创 写在脚本中export不生效

写了一个脚本,内容大致如下,set_ld_path.sh:project_lib_path=../lib/export LD_LIBRARY_PATH=$project_lib_path:$LD_LIBRARY_PATH将上面代码写在了脚本中,目的是指定动态库加载路径,执行脚本未生效。由于执行脚本会产生子进程,父子进程执行指令后,子进程结束返回到父进程,export的变量在父进程中不生效,所以,export不能再子进程shell中执行纠正:source ./set_ld_path.sh:

2022-03-27 21:04:49 1349

原创 ubuntu20.04安装nvidia-container-toolkit

docker: Error response from daemon: could not select device driver “” with capabilities: [[gpu]].然后按照网上的博客进行以下操作distribution=$(. /etc/os-release;echo $ID$VERSION_ID)curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -curl -s -L

2022-03-19 19:26:27 2419

原创 C与C++中的符号隐藏

C语言中的符号隐藏:我们知道,在C语言中,在.c文件中定义一个全局的变量,如果要在其他.c文件中访问,我们需要使用到extern,声明这个变量是引用的其他源文件中的变量,编译器在进行符号整理后,会给该符号一个正确的地址。当我们希望仅仅在当前文件访问一个符号(无论是函数还是变量),不希望其他源文件访问,也就是隐藏符号,我们可以使用static进行修饰。由于被static修饰的符号是local类型的,编译器不连接local符号,只处理globall符号。// example.cstatic int a

2022-03-19 19:25:51 1260

原创 C++重载:const char *类型参数被匹配为bool类型参数的函数,导致行为异常

现象:实现了一个接口类,包含了类似以下的接口:class {public: void Set(const std::string&value); void Set(const int&value); void Set(const double&value); void Set(const bool&value);};当我在程序中调用该方法时,发现,最终匹配竟是bool类型的重载版本:Set("value");分析:分析一下过程:“value”

2022-03-19 19:25:17 399

原创 Redis数据安全与性能保障(持久化与复制特性)

当我们使用redis时,很多时候都需要将内存中的数据持久化到硬盘中,主要是两个原因,为了在以后重用数据,为了防止系统故障而将数据备份到远程的其他服务器上。Redis持久化选项#关于快照的一些选项save 900 1save 300 10save 60 10000stop-writes-on-bgsave-error yesrdbcompression yesrdbchecksum yesdbfilename dump.rdb#关于AOF持久化的一些关键配置appendonly

2021-12-05 17:51:42 697

原创 二叉树的存储之数组存储

示例:如上图所示,将此二叉树存放入数组Array当中,有如下的关系:根结点存放在Array[0]中左孩子存放在Array[2*i+1] (i表示父亲结点在数组中的下标index)右孩子存放在Array[2*i+2] (i表示父亲结点在数组中的下标index)最终数组Array存储的结果如下:另外:也可以将将根节点存放在Array[1]中,左孩子结点存放在Array[2*i]右孩子结点存放在Array[2*i + 1]这样做计算方式比较方便,比如要计算某个结点的父亲结点的下标,

2021-11-28 17:08:34 858

原创 新基础类型(C++11~C++20)

整数类型long longlong long该类型实际上我们很早就开始使用了,但是是直到C++11才加入标准中的;long一般表示一个32位的整型,long long一般表示64位的整型;long long是一个有符号的整型,对应无符号是unsigned long long;C++标准顶定义,long long至少是一个64位的整型,注意,这里是至少。定义是可以使用LL和ULL进行区分:long long a = 10000;long long b = 10ll;unsigned long

2021-10-31 14:53:11 358

原创 error adding symbols: DSO missing from command line

错误usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/libpthread.so: error adding symbols: DSO missing from command linecollect2: error: ld returned 1 exit status原因有的博客写的是对pthread库的缺失,但是我在编译的时候都链接了。然后调整了pthread的链接顺序,然后就可以了。...

2021-10-18 19:35:40 163

原创 Redis设计与实现之字符串类型在Redis中的底层实现SDS

我们知道Redis中最基础的类型就是字符串,但是Redis中的字符串与C语言中的常量字符串不相同,实际上是对C字符数组的封装,因为他需要支持动态扩张,支持值能够被修改,我们知道常量字符串是不能被修改的,read only,有点类似于C++中的std::string.127.0.0.1:6379> set name zhangsanOK上面指令中,在Redis中,底层分别是保存着name和zhangsan的SDS类型的对象或者实例。127.0.0.1:6379> LPUSH num 1

2021-08-23 21:21:52 66

原创 ubuntu20.04 settings选项消失不见

问题背景昨天在配置工作机环境时,把系统升级了一下,今天启动一个带界面docker容器时发现无法启动,以为是扩展显示器的问题,准备去设置中将扩展显示器先关掉,然后发现没有setting选项。解决方案sudo apt-get install gnome-control-centersudo reboot now机器重启后,发现setting选项出来了,容器启动也正常了,就很…神奇?...

2021-08-18 17:05:55 2179

原创 ubuntu安装docker容器

下载安装:curl -fsSL get.docker.com -o get-docker.shsudo sh get-docker.sh --mirror Aliyun**```启动服务:**```bashsystemctl {status,start,stop,restart} docker 检查是否成功:docker info设置开机自启:systemctl enable docker解决执行docker权限问题:docker: Got permission denied

2021-08-14 13:39:36 107

原创 redis简介

简介是什么:是一个开源的,BSD许可的,高级Key value存储的系统,可以用来存储字符串,哈希结构,链表,集合等数据结构。比如memcache只能存储字符串一种结构。redis 可以用来做存储,主要是具有“持久化”的功能 。几个关键可执行程序:redis-benchmark 性能测试工具redis-check-aof 日志文件检测工具(比如断电造成日志损坏,可以检测并且修复)redis-check-dump 快照文件检测工具(比如断电造成日志损坏,可以检测并且修复)redis-c

2021-07-24 22:14:09 50

原创 FIFO缓存的设计与代码

缓存基本概念以及常见数据的淘汰机制设计思路队列用来保存缓存的key,保证键值对的顺序 队列的特性可以很好的说明哪个数据是最先进入的(容器第一个元素)哈希表用来保存真正需要缓存的数据key:value代码#include <unordered_map>#include <vector>class FIFOCache{public: FIFOCache(int capacity = 10):capacity_(capacity) { i

2021-07-01 23:16:13 135

原创 缓存以及缓存的三种数据淘汰机制

缓存提升数据访问性能,数据备份在内存中,一般支持2种操作:将数据存到缓存的操作 put(key,value)获取缓存中数据的操作 get(key)数据淘汰机制假设我们有一个缓存,容量为3,接下来我们根据不同的数据淘汰机制做分析:淘汰最先放入缓存的数据 FIFO(first in first out)依次将数据k1,k2,k3存入cache中,当我们继续put(k4,v4)时,缓存是满的,这个时候就需要将缓存中的数据进行淘汰,根据FIFIO机制,将最先入队的数据从缓存中移除掉,最后将k4

2021-07-01 22:20:33 236

原创 C++中vector的push_back()和emplace_back()区别

push_back()创建一个新元素,然后拷贝构造到容器的末尾。emplace_back()直接在容器尾部构造对象,直接调用构造函数进行构造,省去对象拷贝构造的过程。有案例的链接

2021-06-30 22:34:52 140 2

原创 c++中vector的clear(),swap()以及 shrink_to_fit()方法

clear()仅仅将容器中的元素释放(析构)掉,会导致size = 0,但是容器容量capacity不会变,即占用内存没有变化。int main(){ std::vector<int> vec; std::cout<<vec.size()<<std::endl; std::cout<<vec.capacity()<<std::endl; for(int i= 0;i < 10;++i) {

2021-06-30 20:43:03 476

原创 链表类题目:反转部分链表

题目描述给定一个链表,给定left和right值,要求反转链表中left-right之间的链表题目解析找到left的前继和right的后继,然后将left-right进行反转,然后进行拼接ListNode *ReverseSubLink(ListNode*head,int left,int right){ //头结点可能被修改,那么就创建一个虚拟结点 ListNode * dummy_node = new ListNode(); dummy_node->next =

2021-06-29 18:49:29 73

原创 链表类题目:链表反转

题目描述将一个链表反转题目解析双指针迭代ListNode *ReverseLink(ListNode*head){ if(head == nullptr || head->next == nullptr) return head; ListNode *pre = nullptr; ListNode *cur = head; while (cur != nullptr) { ListNode * tmp = cur->nex

2021-06-29 18:30:36 65

提示
确定要删除当前文章?
取消 删除