自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 日常学习记录14:单例模式

单例模式是常考考点之一,盘一下。1.单例模式保证一个类仅有一个实例,提供一个全局访问点。有饿汉式与懒汉式之分:懒汉式:在初始化时就实例化饿汉式:在第一次被引用时才实例化,即第一次调用getTest()时实例化2.具体代码主要有三种,本篇盘的均为懒汉式的:(1)普通有缺陷的单例模式在多线程场景下可能会多次new:例如线程1判断到t == nullptr,于是进去执行new,但是在线程1 new出来对象之前线程2判断到t == nullptr,于是也进去new。没有析构函数的释放,造成内存泄

2021-08-01 01:47:04 155

原创 日常学习记录13:C++运算符优先级

在平时的编程与做题的时候会遇到运算符优先级有关的问题,这篇文章盘一下。先看优先级表:这里的结合性是指在同优先级的情况下,运算顺序的方向。总结一下,大致可以归结为三条规律:(1)后缀 > 前缀(2)一元 > 二元(3)计算类 > 大小关系类 > 位运算类 > 与或 > 三目运算符 > 赋值类...

2021-07-24 14:02:47 134

原创 日常学习记录12:char*、char[]、string的相互转换

char*、char[]、string的相互转换是让人挺头晕的,也经常会用到,这篇文章盘一下。1.char* //(1)string --> char* char *s_p1 = const_cast<char*>(s_test.c_str()); char *s_p2 = "123";//编译器可能会警告 //(2)char[] --> char* char *a_p1 = a_test;(1)因为string用c_str()转出来的是

2021-07-15 00:59:40 173

原创 日常学习记录11:ICMP协议

ICMP协议是网络中需要了解的知识之一,这篇文章盘一下。目录1.ICMP是什么2.ICMP的用途3.ICMP报文的格式4.ICMP存在的安全问题参考文献1.ICMP是什么ICMP == Internet Control Message Protocol == Internet控制报文协议,是网络层的协议之一,用于当IP数据报传输失败时,向发送方反馈失败信息等。注意:ICMP报文的实际传输是放在IP的数据部分中进行传输的,还是通过TCP/IP协议族传输。2.ICMP的用途主要用途有差错通知和信息

2021-07-12 19:06:13 316

原创 日常学习记录10:内核态、用户态、异常、系统调用、内核空间

内核是操作系统中很重要的概念,尤其是对Linux系统来说,但是内核两个字又很抽象,此外还有内核态、用户态等等概念,这篇文章来盘一下。1.什么是内核?一句话的回答:“内核是操作系统常驻存储器的部分” ——援引自《深入理解计算机系统》P504详细一点点:内核是为应用程序提供对硬件安全访问的软件,具有管理进程、管理内存、管理硬件设备IO等能力。2.什么是内核态、内核模式 | 用户态、用户模式?内核态 = 内核模式用户态 = 用户模式在处理器中用了某寄存器的一个bit来描述应用程序当前享有的权力

2021-06-25 00:22:12 208

原创 【递归1】 leetcode50 快速幂Pow(x,n)

快速幂是经典常考题目,值得一写,用一个公式就一目了然了:xn=xn2⋅xn2=(x⋅x)n2x^{n}=x^{\frac{n}{2}} \cdot x^{\frac{n}{2}}=(x \cdot x)^{\frac{n}{2}}xn=x2n​⋅x2n​=(x⋅x)2n​通过这个公式,每次可以减少一半的计算次数,用1次x*x的计算换取了n/2次x*x的计算,这用的就是分治的思想。然后看讨论几个简单的问题,就可以完全解决了:(1)为什么1次能换n/2次?放到文章最后讨论。(2)n为负数、奇数时.

2021-06-22 11:46:01 87

原创 日常学习记录9:虚拟内存、共享内存、内存映射

虚拟内存也是必会必掌握概念,盘一下1 虚拟内存1.1 虚拟内存是什么虚拟内存是一种内存管理方式,它通过把程序切成小块,只把目前需要的部分放入物理内存中,其他的部分暂存在磁盘上,也被称为虚拟存储器。物理存储器和虚拟存储器都被分割为许多大小相同的块,分别称为物理页与虚拟页,二者之间的映射关系用页表记录。1.2 虚拟内存的好处1.扩大地址空间;2.内存保护:每个进程运行在各自的虚拟内存地址空间,互相不能干扰对方。虚存还对特定的内存地址提供写保护,可以防止代码或数据被恶意篡改。3.公平内存分配。采用

2021-06-14 15:15:44 1259

原创 日常学习记录8:select、poll、epoll

select、poll、epoll是后端必掌握知识,这篇文章来盘一下。1. select、poll、epoll是什么东西select、poll、epoll是linux下I/O多路复用的三个系统调用那什么是I/O多路复用?见日常学习记录7:I/O模型总结2. select模型select维护了一个记录要监听的socket的集合fd_set,当调用select()时,由内核根据IO状态在线修改fd_set的内容,由此来通知哪些被监视的socket或文件可读。(1)每次调用select都会把fd从用户

2021-06-11 18:24:59 138

原创 日常学习记录7:I/O模型总结

1.什么是I/O模型I/O是指数据在设备和内存之间的输入输出,有内存IO、网络I/O、磁盘I/O三种。在进行I/O时,会先把数据拷贝到操作系统缓冲区中,然后再从操作系统缓冲区(内核空间、内核态)拷贝到应用程序的地址空间(用户空间、用户态)。内核空间是内核代码运行的地方,用户空间是用户程序代码运行的地方。I/O模型我认为是进行I/O的方式,这里的I/O主要指网络I/O,本质是对socket的读取。I/O模型有5种:同步阻塞同步非阻塞I/O多路复用信号驱动异步2.什么是同步、异步我认为

2021-06-11 15:11:48 146

原创 日常学习记录6: 快速排序代码、原理、复杂度

快排重要性不用说,直接背诵代码,每天敲一遍,但是要知道快排的原理和复杂度分析,这两个比代码本身更重要。1.代码:vector<int> Sort::QuickSort(vector<int> &num, int left, int right){ if(left < right) { int p = Partition(num, left, right); QuickSort(num, left, p - 1);

2021-06-05 00:34:34 111

原创 【数组4】leetcode46、47 全排列

全排列1:全排列是经典必背题目,主要用回溯的办法,应用used数组来记录元素是否已经被遍历过,直接记录代码即可:class Solution { vector<int> path; vector<vector<int>> re;public: vector<vector<int>> permute(vector<int>& nums) { vector<bool> us

2021-05-30 23:03:18 114 2

原创 日常学习记录5:通俗理解各种锁(互斥、读写、自旋、排他、共享、悲观、乐观)

锁机制用来实现进程线程的同步互斥,保证操作数据的正确性/一致性,来一个一个盘一下:1.互斥锁:就是经常见到的mutex,每个线程在对共享资源(比如一个作为缓冲区的全局数组)进行操作前先申请互斥锁,申请到的可以进行操作,没申请到的要阻塞阻塞阻塞!互斥锁的释放只能由加锁的那个线程来释放。互斥锁只有加锁、解锁两种操作。2.读写锁:读写锁适合用于读操作多的场景。拥有读锁的线程可以读资源,拥有写锁的线程可以写资源。某线程对资源加读锁时,其他线程可以也可以加读锁,但是不能加写锁(意味着有人在读的时候,其他人也

2021-05-28 20:09:49 1419

原创 【链表2】leetcode25 K 个一组翻转链表

经典必背的困难题目!使用递归的方法做:(1)因为是k个一组进行翻转,首先找到每组翻转的结尾tail(2)找到结尾tail之后再进行普通的链表翻转即可。注意翻转结束条件不再是head == nullptr,而是head == tail,这样一来每次的翻转范围是[head, tail)(3)翻转完毕后让head->next = 下一次递归的返回结果(此时head == tail)(4)最后返回cur记录一下代码:/** * Definition for singly-linked lis.

2021-05-28 15:30:55 53

原创 【链表1】leetcode206 反转链表

经典必背代码!思路:(1)设置指针p、cur,初始时都指向nullptr(2)当head != nullptr时进行循环(2.1)p = head->next (记录下一个要改变指向的位置)(2.2)head->next = cur (翻转,断链)(2.3)cur = head(下一个要被指向的位置)(2.4)head = p(移动到p上)(3)head为空时,cur刚好是最后一个节点,返回cur即可记录一下代码:/** * Definition for singly-l.

2021-05-28 14:53:50 55

原创 【数组3】leetcode34排序数组中第一个和最后一个位置

这道题目也是二分查找的变形,主要是考察使用二分查找来寻找左界和右界。直接使用二分查找对应的解决就可以了,有一个讲的很好的文章可以一看:详解二分查找算法普通正常的二分查找:int left = 0;int right = n - 1;while(left <= right){ int mid = (left + right) / 2; if(nums[mid] == target) { return mid; } else if(n.

2021-05-26 21:46:16 51

原创 【数组2】leetcode33 搜索旋转排序数组

在数组的题目中,一旦涉及到数组有序就要考虑二分法的使用。这道题是二分法的变形使用,在题解中看到一个很有趣的思路:因为是旋转数组,因此肯定有一个分界点,这个分界点左边是递减的,右边是递增的,那么在二分遍历时候,可以采用边遍历边有序的策略:(1)更新mid = l + (r - l) / 2,在l <= r的情况下,判断target和num[0]的大小关系(1.1)如果target大于num[0],说明target在分界点的左边。如果此时的num[mid]小于num[0],说明num[mid]在分.

2021-05-25 21:00:17 106

原创 【数组1】leetcode31 下一个排列

思路:(1)初始设i = -1。在[0, n-1]范围内从后向前找,找到第1个升序对nums[i],nums[j],里面的nums[i]即为要交换的小数(2)在[j, n-1]范围内从后向前找,找到第1个大于nums[i]的数nums[k],nums[k]即为要交换的大数(3.1)如果i = -1,说明不存在升序对,也就是整体是降序,也就是当前排列为最大,因此翻转整个数组(3.2)如果i != -1,则交换nums[i]和nums[k]的值,然后将j之后的数全部变为升序(这样做保证后面的都是最小的.

2021-05-24 21:35:10 47

原创 【双指针5】leetcode142 环形链表2

在环形链表1(Leetcode 141)的基础上,让返回入环节点的位置,141仅仅让找到是否有环。思路还是双指针:设置slow、fast两个双指针,在二者第1次相遇后说明是有环的,接下来需要分析一下:因为fast每次走2步,slow每次走1步,因此在二者第1次相遇之后(紫色相遇点),他们走过的路程为:fast = a + b + c + bslow = a + b(这里忽略fast多走了好几圈的情景,实际上差不多,就从最简单的分析吧)而又因为fast的路程应该等于slow的2倍,所以:a .

2021-05-23 18:43:26 58

原创 【双指针4】leetcode160 相交链表

也是经典的双指针题目,思路方法:(1)设置两个指针A、B分别指向headA、headB(2)开始循环,直到A == B(2.1)若A不为空,则向后走一步;若A为空,则A指向headB(2.2)若B不为空,则向后走一步;若B为空,则B指向headA(这里可能会有疑问,为什么A、B在为空之后要指向headB、headA,而不是指向headB->next、headA->next,我的理解是只要AB他们两个的行为一致就行,要么都只指向不移动,要么就都指向完后再走1步)(3)返回A或者B。此.

2021-05-22 12:12:55 54

原创 【双指针3】leetcode141 环形链表

最经典的双指针题目,解题思路:(1)先判断头指针head和head->next是否为空,为空则直接返回false(2)设置两个指针slow、fast,起始都指向head(3)slow一次向后走1步,fast一次向后走两步(4)若二者相遇,则有环返回true;若fast->next || fast->next->next为空,则无环返回falseclass Solution {public: bool hasCycle(ListNode *head) { .

2021-05-22 11:47:59 95

原创 【双指针2】leetcode26 删除排序数组中的重复项

(1)用两个指针in、cur,分别指向要填入的位置和当前遍历到的位置,开始时都指向1,因为删除后的长度至少为1,因此nums[0]一定存在在结果中。(2)判断nums[cur]和nums[cur - 1]的值是否相等。(2.1)如果不相等,说明前后两个数不同,因此nums[cur]填到num[in],然后cur、in都指向各自的下一个位置。(2.2)如果相等,说明前后两个数是重复的数,因此直接cur++,回到(2)检查下一个数是否和前数相等。(3)当cur == n时遍历结束,此时in的值刚好是不.

2021-05-21 12:21:06 55

原创 【滑动窗口1】leetcode3 无重复字符的最长子串

1.思路(1)设置指针left指向目前不重复子串最左端位置,右指针right指向字符串s当前遍历位置。(2)设置一个set用来存储子串中已经有的字符,每次right右移时检查set:(2.1)如果right所指字符不在set中,指针right所指字符加入set。(2.2)如果right所指字符在set中存在,则left开始右移,并且每次移动都从set中删除left所指字符,直到set中不存在当前right所指字符停止。(3)计算更新子串长度,子串长度 = right - left + 1。2..

2021-05-20 11:29:22 49

原创 【双指针1】leetcode19 删除链表的倒数第 N 个结点

1.方案1:用unordered_map遍历一遍,用哈希表把序号映射到结点,然后直接找第i - n个结点进行指针改变、删除即可。#include <unordered_map>class Solution {public: ListNode* removeNthFromEnd(ListNode* head, int n) { unordered_map<int, ListNode*> mmap; ListNode* p = head;.

2021-05-19 22:45:10 66

原创 日常学习记录4:socket编程

记录一下socket编程的流程,分为服务端与客户端。 1.服务端(TCP)1.1 地址结构体声明1.2 创建socket1.3 地址结构体赋值1.4 绑定socket与地址结构体1.5 设置监听模式1.6 等待客户端连接1.7 与客户端通信1.8 关闭socket释放资源2.客户端(TCP)2.1 地址结构体声明2.2 创建socket2.3 地址结构体赋值2.4 连接服务器2.5 与服务端通信2.6 关闭socket释放资源3.完整代码3.1 服务端3.2 客户端1.服务端(TCP)1.1 地址结构

2021-05-19 21:15:30 477

原创 日常学习记录3:数值的补码存储

1.计算机中的数字存储计算机里都是用补码存储数值的,原码、反码、补码的转换(有符号数):原码->反码:符号位不变,其它位置取反 == >0001->0110 1001->1110原码->补码(正数):不变,原码补码相等 ==> 0001->0001原码->补码(负数):原码->反码后+1 ==> 1001->1110->1111补码->原码(正数):不变,原码补码相等 ==> 0001->0001补码-&

2021-05-18 12:22:03 300

原创 【动态规划2】leetcode1641 统计字典序元音字符串的数目

1641. 统计字典序元音字符串的数目1.解题思路首先当 n=1 时,字符串为 [“a”,“e”,“i”,“o”,“u”]根据题目的意思,当 n=2 时,字符串需要由2个元音字符拼接而成,且满足字典序,可以在 n=1 的基础之上,给每个字符串前面加上新的元音,字母a后面可以跟a、e、i、o、u,字母e后面可跟e、i、o、u,字母i可跟i、o、u,字母o可跟o、u,字母u只能跟u,最后形成 [“aa”,“ae”,“ai”,“ao”,“au”,“ee”,“ei”,“eo”,“eu”,“ii”,“io”

2021-05-09 00:40:07 194

原创 【动态规划1】leetcode303 区域和检索 - 数组不可变

303. 区域和检索 - 数组不可变1.确定dp数组的意义2.找到状态转移方程3.找到dp数组的初始量4.GO FOR IT !5.总结贴一下leetcode的代码记录一下leetcode303是动态规划的第一道简单难度题目链接:leetcode303 区域和检索 - 数组不可变.class NumArray {public: vector<int> num; NumArray(vector<int>& nums) { num = n

2021-04-28 21:44:29 119

原创 日常学习记录2:auto和decltype

1.auto关键字用于自动推断类型,根据等号右边变量的类型或字面值e.g.1:int i1= 1;double d1 = 2.1;auto i2= i1;//i2是int型auto i3= 5;//i3是int型auto d2= d1;//d2是double型e.g.2:一句auto可以声明并初始化多个变量,但是等号右边变量必须是同一基本类型int i1 = 1, i2 = 2;double d = 1.1;auto a = i1, b = i2;//合...

2021-01-27 02:06:43 124

原创 日常学习记录1:基本类型占用字节、字节补齐、cosnt

1.C++基本类型所占字节数类型 16位 32位 64位 char 1 1 1 char*(指针变量) 2 4 8 short 2 2 2 int 2 4 4 unsigned int 2 4 4 long 4 4 8 unsigned long 4 4 8 long long 8 8 8 float

2021-01-19 18:20:09 154

空空如也

空空如也

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

TA关注的人

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