自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(43)
  • 问答 (1)
  • 收藏
  • 关注

原创 函数返回值与移动语义

在 C++ 11 标准之前(C++ 98/03 标准中),如果想用其它对象初始化一个同类的新对象,只能借助类中的复制(拷贝)构造函数 。拷贝构造函数的实现原理很简单,就是为新对象复制一份和其它对象一模一样的数据。需要注意的是,当类中拥有指针类型的成员变量时,拷贝构造函数中需要以深拷贝(而非浅拷贝)的方式复制该指针成员。举个例子:#include <iostream>using namespace std; class Demo {public: Demo() : num(n

2021-11-27 13:50:11 391

原创 单例模式简单实现

#pragma once#include <mutex>#include <thread>using namespace std;//饿汉模式,程序启动就创建实例class Singleton{public: static Singleton* GetInstance() { return &m_instance; } Singleton(const Singleton&) = delete; Singleton& operator=

2021-05-18 19:25:12 160

原创 nullptr,NULL和0

推荐使用nullptr,因为NULL和0本质上是整形,nullptr的真正类型是std::nullptr_t,std::nullptr_t能够被隐式转换为任何类型的裸指针,因此可以看成是指向所有类型的指针。传递0或者NULL给重载了整型参数和指针参数的函数会导致意料之外的情况,如下void f(int); // three overloads of fvoid f(bool);void f(void*);f(0); // calls f(int), not f(void*)f(NULL); /

2021-05-17 17:18:36 407

原创 C++ std::move()和std::forward

std::move()只是做了个类型转换,它只保证转换后的结果是右值。且并不是转换成了右值,就一定能保证发生移动而不是拷贝,如:class Annotation {public: explicit Annotation(const std::string text) : value(std::move(text)) // "move" text into value; this code { … } // doesn't do what it seems to! …private:

2021-05-13 20:53:32 184

原创 模板特化,偏特化

定义了一个模板,但是对于某些特殊的实参,想要有不同的实现,那么就需要特化。特化分为全特化和偏特化:全特化:本质上是接管了编译器的工作,为所有模板参数提供实参,实例化了模板。偏特化:还是模板,只为部分模板参数提供实参。类模板可以有全特化和偏特化,函数模板只能有全特化,没有偏特化,因为函数偏特化可以通过函数重载实现。//原始模板template<typename T1, typename T2>class Test{public: Test(T1 i,T2 j):a(i),b(j

2021-04-29 13:45:38 491

转载 TCP粘包以及粘包处理

TCP粘包现象TCP粘包通俗来讲,就是发送方发送的多个数据包,到接收方后粘连在一起,导致数据包不能完整的体现发送的数据。TCP粘包原因分析导致TCP粘包的原因,可能是发送方的原因,也有可能是接受方的原因。发送方由于TCP需要尽可能高效和可靠,所以TCP协议默认采用Nagle算法,以合并相连的小数据包,再一次性发送,以达到提升网络传输效率的目的。但是接收方并不知晓发送方合并数据包,而且数据包的合并在TCP协议中是没有分界线的,所以这就会导致接收方不能还原其本来的数据包。接收方TCP是基于“流”的

2021-04-29 11:55:01 1109

原创 面试题:超大文件去除重复行

先看问题的简化版本:题目描述:有一个文件,其大小不大,可以全部装入内存,要求去除文件中重复的行。solution:遍历每一行,先查找是不是已经存在unordered_set中,如果存在,跳过,如果不存在,接到输出文件后面。代码://去除单个小文件中的重复行void deleteDuplicateRow(string &originFile, string &resFile) { string curRow; unordered_set<string>se; if

2021-04-26 22:07:25 2924

原创 内存泄漏的两种情况

(1)在堆上申请了内存,比如说:new了一个数组,但是没有delete(2)系统资源没有关闭,比如说socket,file等没有close。

2021-04-26 11:06:22 73

原创 shared_ptr简单实现

template<typename T>class myShared_ptr {public: myShared_ptr(T* ptr=nullptr) :rowPtr(ptr), useCountPtr(new int(1)), mutexPtr(new mutex) {} myShared_ptr(const myShared_ptr<T>& right) :rowPtr(right.ptr),useCountPtr(right.useCountPtr

2021-04-26 10:56:21 109

原创 堆和栈的区别

堆和栈的区别主要有五大点,分别是:1、申请方式的不同。栈由系统自动分配,而堆是人为申请开辟;2、大小不同。栈获得的空间较小,一般为几MB,而堆获得的空间较大;3、申请效率的不同。栈由系统自动分配,速度较快,而堆要依靠new,malloc等API申请,申请的过程比较复杂,速度比较慢;4、存储内容的不同。栈在函数调用时,函数调用语句的下一条可执行语句的地址第一个进栈,然后函数的各个参数进栈,其中静态变量是不入栈的,静态变量存放在数据段。而堆一般是在头部用一个字节存放堆的大小,堆中的具体内容是人为安排;

2021-04-25 13:32:30 126

原创 基类的析构函数为什么最好是虚函数?

基类的析构函数为什么最好是虚函数?如果派生类中分配了资源,而基类的析构函数并没有声明为虚函数,如下:class Base {public: ~Base(){ cout << "base destructor" << endl; }};class Derived :public Base {public: int *a; Derived(int size) { a = new int[size]; } ~Derived(){ cout <&lt

2021-04-25 13:04:51 263

原创 CUDA编程记录

CUDA的硬件架构SP:最基本的处理单元,streaming processor,也称为CUDA core。最后具体的指令和任务都是在SP上处理的。GPU进行并行计算,也就是很多个SP同时做处理。SM:多个SP加上其他的一些资源组成一个streaming multiprocessor。也叫GPU大核,其他资源如:warp scheduler,register,shared memory等。register和shared memory是SM的稀缺资源。CUDA将这些资源分配给所有驻留在SM中的thread

2021-04-24 11:30:45 260 1

原创 C++移动和拷贝

今天面试遇到这么个问题:有如下代码:vector<int>f(){}vector<int>ret=f();假设函数f返回的vector很大,我们不想拷贝,但又想得到函数f返回的值怎么办?我当时想到了移动,但是不清楚怎么用。其实这里的答案很简单,vector<int>ret=f();这句话本身就会调用vector的移动构造函数,不会发生拷贝。为了弄清楚为什么,我做了以下实验class A{public: A(){} //拷贝构造 A(const

2021-04-23 22:18:57 841

原创 C++ 11 lambda表达式

今天做笔试碰到这样一道题int main() { int v = 35; auto f1 = [v] {return v; }; auto f2 = [&v] {return v; }; v = 30; auto a = f1(); auto b = f2(); cout<<a<<b;}问输出的a,b值是多少?这里涉及到lambda表达式,[v]的意思是按值捕获v,然后在函数体中使用。[&v]则是按引用捕获v。f1,f2定义之后,v赋值成30

2021-04-22 21:34:59 77

原创 红黑树和AVL树

红黑树的五个性质:(1)每个结点非黑即红(2)根节点是黑色(3)每个叶子结点是黑色(4)红色结点的两个结点都是黑色(5)每个结点到其后代叶子结点的简单路径上,均包含相同数目的黑色结点红黑树的优点:AVL更容易失衡,如果是插入导致的失衡,那么两种树都只需要最多两次旋转来维护各自的条件,即O(1)复杂度,但如果是删除导致的失衡,AVL需要维护被删除结点到根节点root路径上的所有结点的平衡,需要O(lgn),而红黑树只需要最多3次旋转搞定,O(1)复杂度。AVL树的优点:由于AVL树是严格平衡二叉

2021-04-21 22:10:49 109

原创 C++ 右值,右值引用以及万能引用

右值和右值引用左值和右值指的是表达式的属性。一般而言,一个左值表达式表示的是一个对象的身份,而右值表达式表示的是一个对象的值。在C++11 中,为了支持移动操作,引入了右值引用。int a = 1;//a是左值int &lr = a;//正确,左值引用lr绑定左值aint &lr1 = a + 1;//错误,左值引用lr1绑定右值a+1const int &lr2 = a + 1;//正确,可以将一个const的引用绑定到右值上,不管这个引用是左值引用还是右值引用in

2021-04-21 19:57:36 469

原创 C++ 中深拷贝与浅拷贝

为什么要有深拷贝,浅拷贝看这样一个类:类Array实现变长数组,并通过类成员变量m_p管理该数组。class Array {public: Array(int len); //普通构造函数 ~Array(); //析构函数public: int operator[](int i) const { return m_p[i]; } //获取元素(读操作) int &operator[](int i) { return m_p[i]; } //写入元素 int length() co

2021-04-20 21:20:58 662

原创 C++ static

为什么要有static考虑这种情况:你想定义一个类A,类A里面要一个成员变量count,来计算当前生成了多少个类A的对象,其实不必每个类A对象都拥有一个自己的count,因为大家是同类,count是相同的,而且当创建一个新类A对象时候,要找到每个已有的类A对象,把他们的count都++,这也太麻烦了吧,而且不实际。那一般会把count定义为全局变量,这样只需要对这一个count操作就好了。但是这样做违反了面向对象特性之一:封装。因为全局变量count可以被任何人操作,而我们只想让类A操作count。

2021-04-20 16:55:30 154

原创 C++类型转换与类型推导

第4章 表达式类型转换类型转换分为隐式类型转换和显示类型转换隐式类型转换int和unsigned int之间的隐式类型转换,int和uint相互转换时二进制表示不变,变的是翻译的方法。int是用补码来表示,最高位是符号位,uint则没有符号位,以32位机器为例,int和uint都是4字节,但是表示范围分别是-231~231-1, 0~232-1。如果执行下列语句:unsigned int u=4294967295;int i=u;cout<<i<<endl;会输

2021-04-20 16:01:21 1444 1

原创 C++ 位域详解

今天做EA的笔试最后一道题考到了struct Mystruct{ int a:2; int b:3;};int main(){ MyStruct m{ 2,2 }; cout << m.a<<" "<< m.b;}问输出是啥?当时我就懵逼了,不会。后来查了一下,微软官网是这么讲的:https://docs.microsoft.com/zh-cn/cpp/cpp/cpp-bit-fields?view=msvc-160C++ 位域类和结构可

2021-04-19 22:08:47 1261

原创 CSAPP:Attack lab的解题过程

attacklabvoid test(){ int val; val = getbuf(); printf("No exploit. Getbuf returned 0x%x\n", val);}正常执行的话是调用getbuf,然后从屏幕中输入字符串,如果正常退出的话,则会执行printf("No exploit. Getbuf returned 0x%x\n", val)`;而这个lab的目的就是不让它正常退出。这个lab总共有6个phase,前三个phase是一

2020-12-29 16:57:59 1937 1

原创 深入理解计算机系统笔记(一)

总线是贯穿整个系统的一组电子管道,负责在各个部件之间传递信息字节。通常总线传送定长的字节块,即字字中的字节数就是字长因为一个字节有8bit,即8位,所以我们所说的32位系统就是字长为4;64位系统就是字长为8;...

2020-11-24 22:25:07 499

原创 c++ primer学习笔记

主要是const关键字

2020-07-28 14:13:47 105

原创 Effictive C++学习笔记

为免除“跨编译单元之初始化次序”问题,可以用local static对象替换non-local static对象。将每个non-local static对象搬到自己的专属函数内(该对象在此函数内被声明为static)。这些函数返回一个reference指向它所含的对象。然后用户调用这些函数,而不直接指涉这些对象。换句话说,non-local static 对象被local static 对象替换了。这个手法的基础在于:C++保证,函数内的local static对象会在“该函数被调用期间”“首次遇上该对

2020-07-26 01:36:41 156

原创 翻转链表

单向链表翻转/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public: ListNode* reverseList(ListNode* head) { ListNode *tmp

2020-07-23 16:12:29 78

原创 栈和队列的相互实现

算法导论10.1-6如何用两个栈实现一个队列?思路:栈是先进后出,队列是先进先出;栈1存放push进来的元素,当pop时,将栈1中的元素都push到栈2中,然后对栈2进行pop操作class MyQueue {public: /** Initialize your data structure here. */ MyQueue() { } /** Push element x to the back of queue. */ voi

2020-07-21 23:13:45 142

原创 C++ protected访问说明符

protected 访问说明符C++ Primer:Members defined after the protected keyword may be accessed by the members and friends of a derived class. However, these members are only accessible through derived objects. protected members are not accessible to ordinary users

2020-07-21 15:36:31 132

原创 算法学习笔记之归并排序

归并排序归并排序本质上是使用的分而治之思想(devide and conquer)基本步骤1.将原问题分解为若干个本质上相同,但规模较小的子问题;2.递归地解决子问题。当子问题小到一定程度时,一般可以直接解决;3.将子问题的解合并为原问题的解。具体到排序问题上,基本步骤1.将n个元素的代排序列分解为n/2个元素的子序列;2.递归地排序子序列。当子序列只剩1个元素时,直接不用排;3.将排序后的子序列合并为排序后的原序列。问题的关键在于第三步,合并。合并之前,我们已经有两个排序好的序列

2020-07-09 13:20:05 142

原创 算法学习笔记之插入排序

插入排序举个例子:摸牌的时候,一张张摸,每次处理新摸上来的那一张,一般习惯是从左到右升序排列,那么就是每摸上来一张,将摸上来的这张牌与它之前的牌比较大小,找到第一张比它小的牌为止,这时候第一张比它小的牌的右边那个位置就是新牌该放的位置,对应的,为了空出这个位置给新牌,所有大于新牌的牌都应该往右边挪一个位置。void insert_sort2(vector<int>&vec){ if (vec.size() <= 1) { return; } for (int i

2020-07-08 16:22:48 84

原创 无法解析的外部符号??

如果无法解析的是外部库函数,那么多半原因是没有链接上,检查附加库目录是否包里面是否有该外部库的lib目录。 第二步检查附加依赖项,是否添加了该外部库所需的lib文件

2020-06-09 21:51:48 295

原创 位运算判断小数组中元素是否重复

当用int类型位运算时,该方法只适用于数组中元素取值范围在0~31的情况。例如:利用一个int的32位,第一位为1表示数字1出现过了,第二位为1表示数字2出现过了,其他情况类似。具体实现如下:bool fun (vector<int>a ) { int flag=0; for(int i:a) { if((flag>>i)&1==1)return false;//要看数字i有没有出现过,就要看flag从右边数第i位(0位起点)是否为1,是则出

2020-05-22 15:29:33 348

原创 N个骰子的点数和的概率

可以考虑用两个数组来存储骰子点数每一总数出现的次数。在一次循环中,第一个数组中的第n个数字表示骰子和为n出现的次数。那么在下一循环中,我们加上一个新的骰子。那么此时和为n的骰子出现的次数,应该等于上一次循环中骰子点数和为n-1、n-2、n-3、n-4、n-5与n-6的总和。所以我们把另一个数组的第n个数字设为前一个数组对应的第n-1、n-2、n-3、n-4、n-5与n-6之和。基于这个思路,我们可以写出如下代码:`void PrintSumProbabilityOfDices_2(int number)

2020-05-22 14:16:24 824

原创 最长不含重复字符的子字符串

输入一个字符串(只包含 a~z 的字符),求其最长不含重复字符的子字符串的长度。例如对于 arabcacfr,最长不含重复字符的子字符串为 acfr,长度为 4。解题思路要求是否含有重复字符,一般要记录某个字符是否出现过,可以用一个数组来记录;要求子字符串的长度,那么不仅需要记录是否出现过,还要记录出现在哪里。public int longestSubStringWithoutDuplication(String str) { int curLen = 0;//目前的子字符串 int

2020-05-17 23:57:56 431

原创 [PAT ]Pop Sequence

[PAT A1051]Pop Sequence题目描述Given a stack which can keep M numbers at most. Push N numbers in the order of 1, 2, 3, …, N and pop randomly. You are supposed to tell if a given sequence of numbers is a...

2020-04-23 19:25:18 292

原创 线性结构2 一元多项式的乘法与加法运算

#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<stdlib.h>#include <iostream>using namespace std;typedef struct Node List;struct Node{ int m; int n; List * next;}...

2020-04-22 23:23:07 105

原创 PTA 两个有序链表序列的合并

本题要求实现一个函数,将两个链表表示的递增整数序列合并为一个非递减的整数序列。函数接口定义:List Merge( List L1, List L2 );其中List结构定义如下:typedef struct Node PtrToNode;struct Node {ElementType Data; / 存储结点数据 /PtrToNode Next; / 指向下一个结点的指针 /}...

2020-04-22 22:34:36 714

原创 堆中的路径

将一系列给定数字插入一个初始为空的小顶堆H[]。随后对任意给定的下标i,打印从H[i]到根结点的路径。输入格式:每组测试第1行包含2个正整数N和M(≤1000),分别是插入元素的个数、以及需要打印的路径条数。下一行给出区间[-10000, 10000]内的N个要被插入一个初始为空的小顶堆的整数。最后一行给出M个下标。输出格式:对输入中给出的每个下标i,在一行中输出从H[i]到根结点的路径上...

2019-10-21 15:23:57 107

原创 平衡二叉树(AVLTree)

An AVL tree is a self-balancing binary search tree. In an AVL tree, the heights of the two child subtrees of any node differ by at most one; if at any time they differ by more than one, rebalancing is...

2019-10-20 14:06:03 390

原创 是否同一颗二叉树

给定一个插入序列就可以唯一确定一棵二叉搜索树。然而,一棵给定的二叉搜索树却可以由多种不同的插入序列得到。例如分别按照序列{2, 1, 3}和{2, 3, 1}插入初始为空的二叉搜索树,都得到一样的结果。于是对于输入的各种插入序列,你需要判断它们是否能生成一样的二叉搜索树。输入格式:输入包含若干组测试数据。每组数据的第1行给出两个正整数N (≤10)和L,分别是每个序列插入元素的个数和需要检查的...

2019-10-18 14:00:40 291 1

原创 操作系统学习笔记

CPU调度CPU调度概述长程调度(非必须):新建->就绪。短程调度(必须):就绪->运行。中程调度:又称交换,将进程从内存和外存间换进换出,目的是为了节省内存空间。管理不同状态的进程就绪队列:其中的进程等待被调度程序选中并运行。设备队列:所有设备队列中的进程都是等待状态。CPU调度过程调度程序:选择一个就绪程序分派程序:(执行切换)吧CPU得控制权交CPU调度程序;...

2019-10-16 17:48:17 222

空空如也

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

TA关注的人

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