自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(59)
  • 收藏
  • 关注

原创 虚拟内存

虚拟内存虚拟内存的好处:扩大地址空间;内存保护:每个进程运行在各自的虚拟内存地址空间,互相不能干扰对方。虚存还对特定的内存地址提供写保护,可以防止代码或数据被恶意篡改。公平内存分配。采用了虚存之后,每个进程都相当于有同样大小的虚存空间。当进程通信时,可采用虚存共享的方式实现。当不同的进程使用同样的代码时,比如库文件中的代码,物理内存中可以只存储一份这样的代码,不同的进程只需要把自己的虚...

2019-10-24 21:27:49 263

原创 STL中list类的模拟实现

#include <iostream>using namespace std;//结点的定义template <class T>struct Node {public: Node(const T& data = T()) :data_(data) ,prev_(nullptr) //指向前驱结点 ,next_(nullptr) //指向...

2019-08-17 14:20:40 209

原创 C++的类型转换

在C语言中,类型转换是这样子的void Test (){ int i = 1; // 隐式类型转换 double d = i; printf("%d, %.2f\n" , i, d); int* p = &i; // 显示的强制类型转换 int address = (int) p; printf("%x, %d\n" , p, address);}...

2019-08-09 14:25:59 290 1

原创 异常

在C语言中,传统的错误处理机制是这样子的:终止程序,如****assert,缺陷:用户难以接受。如发生内存错误,除0错误时就会终止程序;返回错误码,缺陷:需要程序员自己去查找对应的错误。如系统的很多库的接口函数都是通过把错误码放到errno中,表示错误而大多数情况下,C语言都是通过返回错误码的方式来处理错误,部分情况下使用终止程序处理比较严重的错误。异常概念在C++中,提出了...

2019-07-27 13:35:02 463

原创 变量类型推导

为什么需要类型推导在我们编程的时候会发现:在定义变量时必须先给出变量的实际类型编译器才会允许定义,但是有些情况可能不知道实际需要类型怎么给,或者类型写起来特别复杂#include <iostream>#include <map>#include <string>using namespace std;int main(){ short a = ...

2019-07-06 23:17:56 329

原创 lambda表达式

在C++98中,如果想要对一个数据集合中的元素进行排序,可以使用std::sort方法。#include <algorithm> #include <functional> int main() { int array[] = {4,1,8,5,3,7,0,9,2,6}; // 默认按照小于比较,排出来结果是升序 std::sort(array, ...

2019-07-05 23:20:05 661

原创 IO多路转接之epoll

相对于select来说,epoll没有描述符个数限制,使用一个文件描述符管理多个描述符,将用户关心的文件描述符的事件存放到内核的一个事件表中,这样在用户空间和内核空间的copy只需一次。epoll的相关系统调用:epoll_createint epoll_create(int size);创建一个epoll的句柄。注意:自从linux2.6.8之后,size参数是被忽略的用完之后...

2019-06-30 23:21:45 261

原创 I-O多路转接之select

select系统调用是用来让我们的程序监视多个文件句柄的状态变化的。程序会停在select这里等待,直到被监视的文件句柄有一个或多个发生了状态改变。关于文件句柄,其实就是一个整数,我们最熟悉的句柄是0、1、2三个,0是标准输入,1是标准输出,2是标准错误输出。select函数原型#include <sys/select.h>int select(int nfds,fd_set *...

2019-06-17 21:47:50 198

原创 排序算法

插入排序对于一个带排序数组来说,其初始有序数组元素个数为1,然后从第二个元素,插入到有序数组中。对于每一次插入操作,从后往前遍历当前有序数组,如果当前元素大于要插入的元素,则后移一位;如果当前元素小于或等于要插入的元素,则将要插入的元素插入到当前元素的下一位中。希尔排序先将整个待排序记录分割成若干子序列,然后分别进行直接插入排序,待整个序列中的记录基本有序时,在对全体记录进行一次直接插入排序...

2019-06-13 22:11:41 301

原创 Top-K问题

1、直接全部排序(只适用于内存够的情况)当数据量较小的情况下,内存中可以容纳所有数据。则最简单也是最容易想到的方法是将数据全部排序,然后取排序后的数据中的前K个。这种方法对数据量比较敏感,当数据量较大的情况下,内存不能完全容纳全部数据,这种方法便不适应了。即使内存能够满足要求,该方法将全部数据都排序了,而题目只要求找出top K个数据,所以该方法并不十分高效,不建议使用。2、快速排序的变形 ...

2019-06-12 22:20:19 3450

原创 迭代器

迭代器Iterator(迭代器)模式又称Cursor(游标)模式,用于提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示。或者这样说可能更容易理解:Iterator模式是运用于聚合对象的一种模式,通过运用该模式,使得我们可以在不知道对象内部表示的情况下,按照一定顺序(由iterator提供的方法)访问聚合对象中的各个元素。由于Iterator模式的以上特性:与聚合对象耦...

2019-06-11 23:09:57 415

原创 非阻塞IO

首先,我们知道,socket() 调用创建指定系列和指定类型的套接字。s = socket(family, type, protocol);socket将返回套接字句柄。套接字句柄即为文件描述符s,而一般情况下文件描述符默认都是阻塞的。为了满足某些时候的需要,我们使用fcntl函数来对其进行非阻塞的设置。函数原型#include <unistd.h>#include &lt...

2019-06-10 22:26:14 283

原创 类中成员内存分布

static修饰符static修饰成员变量对于非静态数据成员,每个类对象都有自己的拷贝。而静态数据成员被当做是类的成员,无论这个类被定义了多少个,静态数据成员都只有一份拷贝,为该类型的所有对象所共享(包括其派生类)。所以,静态数据成员的值对每个对象都是一样的,它的值可以更新。因为静态数据成员在全局数据区分配内存,属于本类的所有对象共享,所以它不属于特定的类对象,在没有产生类对象前就可以使用。...

2019-06-06 22:07:59 580

原创 程序内存管理

程序内存管理:一个程序本质上都是由BSS段、data段、text段三个组成的。可以看到一个可执行程序在存储**(没有调入内存)时分为代码段、数据区和未初始化数据区三部分。**BSS段(未初始化数据区):通常用来存放程序中未初始化的全局变量和静态变量的一块内存区域。BSS段属于静态分配,程序结束后静态变量资源由系统自动释放。数据段:存放程序中已初始化的全局变量的一块内存区域。数据段也属于静态...

2019-06-05 22:39:32 599

原创 进程间通信

进程间通信主要包括管道、系统IPC(包括消息队列、信号量、信号、共享内存等)、以及套接字socket。管道:管道主要包括无名管道和命名管道:管道可用于具有亲缘关系的父子进程间的通信,有名管道除了具有管道所具有的功能外,它还允许无亲缘关系进程间的通信1.1 普通管道PIPE:1)它是半双工的(即数据只能在一个方向上流动),具有固定的读端和写端2)它只能用于具有亲缘关系的进程之间的通信(也是...

2019-06-04 22:45:40 195

原创 多态

多态的概念通俗来说,就是多种形态,具体而言就是为了完成某一个行为,当不同的对象去完成时会产生不同的状态。举个栗子:同样是去景区游玩,但是在买票时却不一样——普通人买的时全价票,学生买的是半价票,军人是优先购票。多态的定义及实现多态定义的构成条件多态是在不同继承关系的类对象,去调用同一函数,产生了不同的行为。比如Student继承了Person。Person对象买票全价,Student对象...

2019-06-03 23:18:55 214

原创 继承

继承的概念:继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称派生类。继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程。以前我们接触的复用都是函数复用,继承是类设计层次的复用class Person{public: void Print() { co...

2019-06-02 22:14:09 196

原创 覆盖与隐藏

题目链接:https://www.nowcoder.com/questionTerminal/f29ec891b0284259a922d0dae964ef3a来源:牛客网下面程序的输出是()class A{ public: void foo() { printf("1"); } virtual void...

2019-06-01 22:44:37 592

原创 fork与vfork的区别

fork的基础知识:fork:创建一个和当前进程映像一样的进程可以通过fork( )系统调用:#include <sys/types.h>#include <unistd.h>pid_t fork(void);​ 成功调用fork( )会创建一个新的进程,它几乎与调用fork( )的进程一模一样,这两个进程都会继续运行。在子进程中,成功的fork( )调用会返回0...

2019-05-31 23:51:33 896

原创 C-11新特性

可变参数模板:C++11的可变参数模板,对参数进行了高度泛化,可以表示任意数目、任意类型的参数,其语法为:在class或typename后面带上省略号”。例如:Template<class … T>void func(T … args){cout<<”num is”<<sizeof …(args)<<endl;}func();//ar...

2019-05-30 22:35:41 2867

原创 HTTP代理服务器的工作原理

​ 在HTTP通信链上,客户端和目标服务器之间通常存在某些中转代理服务器,它们提供对目标资源的中转访问。一个HTTP请求可能被多个代理服务器转发,后面的服务器称为前面服务器的上游服务器。代理服务器按照其使用方式和作用,分为正向代理服务器,反向代理服务器和透明代理服务器。​ 正向代理要求客户端自己设置代理服务器的地址。客户的每次请求都将直接发送到该代理服务器,并由代理服务器来请求目标资源。比如处于...

2019-05-29 22:35:49 4454

原创 Linux虚拟地址空间

为什么有虚拟地址空间为了防止不同进程同一时刻在物理内存中运行而对物理内存的争夺和践踏,采用了虚拟内存。虚拟内存技术使得不同进程在运行过程中,它所看到的是自己独自占有了当前系统的4G内存。所有进程共享同一物理内存,每个进程只把自己目前需要的虚拟内存空间映射并存储到物理内存上。 事实上,在每个进程创建加载时,内核只是为进程“创建”了虚拟内存的布局,具体就是初始化进程控制表中内存相关的链表,实际上并...

2019-05-28 23:05:34 514

原创 STL的内存优化

1)二级配置器结构STL内存管理使用二级内存配置器。1、第一级配置器第一级配置器以malloc(),free(),realloc()等C函数执行实际的内存配置、释放、重新配置等操作,并且能在内存需求不被满足的时候,调用一个指定的函数。一级空间配置器分配的是大于128字节的空间如果分配不成功,调用句柄释放一部分内存如果还不能分配成功,抛出异常2、第二级配置器在STL的第二级配置器...

2019-05-26 22:49:18 1035 2

原创 六一儿童节问题

题目描述六一儿童节,老师带了很多好吃的巧克力到幼儿园。每块巧克力j的重量为w[j],对于每个小朋友i,当他分到的巧克力大小达到h[i] (即w[j]>=h[i]),他才会上去表演节目。老师的目标是将巧克力分发给孩子们,使得最多的小孩上台表演。可以保证每个w[i]> 0且不能将多块巧克力分给一个孩子或将一块分给多个孩子。输入描述第一行:n,表示h数组元素个数第二行:n个h数组元...

2019-05-25 21:56:33 351

原创 fork的使用

在牛客做题时遇到了这样一个问题:int main(){fork()||fork();}共创建几个进程:_____回想之前一直在这里跌倒从来没有爬起来过的经历,痛定思痛,来好好的思考了一下fork()函数的使用fork函数初识在linux中fork函数是非常重要的函数,它从已经存在的进程中创建一个新进程。新进程为子进程,而原进程为父进程。#include <unistd.h&gt...

2019-05-24 15:15:10 881

原创 彩色的砖块

题目描述小易有一些彩色的砖块。每种颜色由一个大写字母表示。各个颜色砖块看起来都完全一样。现在有一个给定的字符串s,s中每个字符代表小易的某个砖块的颜色。小易想把他所有的砖块排成一行。如果最多存在一对不同颜色的相邻砖块,那么这行砖块就很漂亮的。请你帮助小易计算有多少种方式将他所有砖块排成漂亮的一行。(如果两种方式所对应的砖块颜色序列是相同的,那么认为这两种方式是一样的。)例如: s = “ABA...

2019-05-23 22:42:29 289

原创 进程状态

众所周知,linux是一个多用户,多任务的系统,可以同时运行多个用户的多个程序,这样就必然会产生很多的进。而对于一个进程而言,它可以有如下几个状态常见进程状态:R:运行状态(running)并不意味着进程是一定在运行中的,它表明进程要么在运行要么在运行队列里。其实准确的说,这个状态应该叫可执行状态,也就是说,处于此状态的这些进程的task_struct结构被放入对应CPU的可执行队列中(...

2019-05-22 18:29:37 397 1

原创 组队竞赛问题

题目描述牛牛举办了一次编程比赛,参加比赛的有3*n个选手,每个选手都有一个水平值a_i.现在要将这些选手进行组队,一共组成n个队伍,即每个队伍3人.牛牛发现队伍的水平值等于该队伍队员中第二高水平值。例如:一个队伍三个队员的水平值分别是3,3,3.那么队伍的水平值是3一个队伍三个队员的水平值分别是3,2,3.那么队伍的水平值是3一个队伍三个队员的水平值分别是1,5,2.那么队伍的水平值是2...

2019-05-21 21:49:45 797

原创 DNS查询和应答报文详解

DNS查询和应答报文详解DNS是一套分布式的域名服务系统。每个DNS服务器上都存放着大量的机器名和 IP地址的映射,并且是动态更新的。众多网络客户端程序都使用DNS协议来向DNS服务器查询目标主机的IP地址。DNS查询和应答报文的格式如下:16位标识字段用于标记一对DNS查询和应答,以此区分一个DNS应答是哪个DNS查询的回应16位标志字段用于协商具体的通信方式和反馈通信状态。DNS报文...

2019-05-20 23:50:35 15446 2

原创 vector与list的区别

概念:vector连续存储的容器,动态数组,在堆上分配空间底层实现:数组两倍容量增长:vector 增加(插入)新元素时,如果未超过当时的容量,则还有剩余空间,那么直接添加到最后(插入指定位置),然后调整迭代器。如果没有剩余空间了,则会重新配置原有元素个数的两倍空间,然后将原空间元素通过复制的方式初始化新空间,再向新空间增加元素,最后析构并释放原空间,之前的迭代器会失效。性能:访问...

2019-05-19 23:09:32 1265

原创 模板

如何实现一个通用的函数呢?(如针对不同的参数类型均可)在平时的编程中,如何实现一个通用的函数呢?首先想到的就是使用函数重载,但是这样一来会有几个不好的地方:重载的函数仅仅只是类型不同,代码的复用率比较低,只要有新类型出现时就需要增加对应的函数代码可维护率比较低,一个函数出错就有可能所有的重载都出错那么有没有一种方式,使得编译器可以根据不同的类型来利用该模子来生成代码呢?答案是有的—...

2019-05-18 21:42:22 192

原创 STL之list类

list的介绍和使用list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代list的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向其前一个元素和后一个元素list与forward_list非常相似:最主要的不同在于forward_list是单链表,只能朝前迭代,已让其更简单高效与其他的序列式容器相比(array,...

2019-05-16 23:24:20 407

原创 简单实现string类以及深浅拷贝问题

对象之间可以进行复制操作,包括采用拷贝构造函数的方式用一个对象去构造另一个对象(用一个对象的值初始化一个新的构造的对象),如同指针的复制一样,对象复制也分为浅复制和深复制对象浅拷贝:两个对象之间进行复制时,若复制完成后,他们还共同使用着某些资源(内存空间),其中一个对象的销毁会影响另一个对象(动态顺序表)如果没有显式提供拷贝构造函数与赋值运算符重载,编译器会生成一个默认的拷贝构造函数和运算符...

2019-05-15 22:13:37 295

原创 STL之vector类

vector的介绍vector是表示可变大小数组的序列容器就像数组一样,vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素进行访问,和数组一样高效,但是又不像数组一样,它的大小是可以动态改变的,而且它的大小会被容器自动处理本质讲,vector使用动态分配数组来存储它的元素。当新元素插入时,这个数组需要被重新分配大小来增加存储空间。其做法是,分配一个新的...

2019-05-14 12:46:09 250

原创 STL之string类

为什么要用string类在C语言中,字符串是以’\0’结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数,但是这些库函数与字符串是分割开的,不太符合OOP的思想,而且底层空间需要用户自己管理,稍不留神可能还会造成越界访问。之所以抛弃char*的字符串而选用C++标准程序库中的string类,是因为他和前者比较起来,不必担心内存是否足够、字符串长度等等,而且作为一个泛型类...

2019-05-13 22:41:16 183

原创 单例模式

单例模式就是保证一个类只有一个实例,并提供一个访问它的全局访问点。首先,需要保证一个类只有一个实例;在类中,要构造一个实例,就必须调用类的构造函数,如此,为了防止在外部调用类的构造函数而构造实例,需要将构造函数的访问权限标记为protected或private;最后,需要提供要给全局访问点,就需要在类中定义一个static函数,返回在类内部唯一构造的实例饿汉模式程序启动时就创建一个唯一的实例对...

2019-05-11 18:15:39 169

原创 类和对象经典面试题(一)

定位new表达式在已分配的原始内存空间中调用构造函数初始化一个对象格式:new(place_address) type 或者new(place_address) type(initializer_list)其中place_address必须是一个指针,initializer_list是类型的初始化列表使用场景:一般配合内存池使用,因为内存池分配出的内存没有初始化,所以如果是自定义类型的...

2019-05-10 12:39:10 840

原创 结构体对齐规则

为什么要进行内存对齐#include <iostream>using namespace std;struct A{ char a; int b; short c;};struct B{ short c; char a; int b;};int main(){ cout << sizeof(A) << end...

2019-05-09 22:18:36 542

原创 Makefile基本使用

为什么要使用Makefile会不会使用Makefile从一个侧面说明了是否具备完成大型工程的能力一个工程中的文件不计其数,按类型,功能,模块分别放在若干个目录中,Makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件选哟重新编译,以及更加复杂的操作Makefile带来的好处就是——“自动化编译”,一旦写好就只需要一个make命令整个工程就可以完全自动编译...

2019-05-08 20:41:23 533

原创 gcc编译过程

程序的编译过程预处理(宏替换)将所有的#define删除,并展开所有的宏定义处理所有的条件预编译指令,如:#if,#ifdef,#elif,#else,#endif处理所有的#include预编译指令,将被包含的文件插进到该指令的位置(这个过程是递归的)删除所有的注释保留所有的#pragma编译器指令,因为编译器需要他们实例:gcc -E hello.c -o hello.i...

2019-05-07 12:56:27 292

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

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