自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 brpc的精华bthread源码剖析

正如标题所说,brpc的精华全部都在bthread上,而bthread就是我们brpc开发的一套“协程”。而进程,线程,和bthread的关系是什么样的呢?一个进程里面可以开辟多个线程,而线程和协程的关系呢。在微信开源的libco上,线程 :协程 = 1 :N。而在bthread上 线程 :协程 = M :N,而bthread实现的关键就是工作窃取算法。后续会展开描述。bthread有三大件,TaskControl(进程内唯一),TaskGroup(线程内唯一),TaskMeta(bthread上下文)。

2022-02-25 21:18:30 1434

原创 买卖股票的最好时机

买卖股票的最佳时机这一题其实就是让我们求最大差值,不过是赚的最大差值,我们只需要进行一次遍历,然后每次遍历进行提取最小值,如果小于最小值则更新,并且求一下当前数和此前最小值的差值,如果差值大于前面所求的最大差值,则也进行更新,下面给出示例代码:class Solution {public: int maxProfit(vector<int>& a) { int n = a.size(); int max = 0, min = a[0]; //

2022-01-14 23:15:35 199

原创 八大排序算法代码实现

排序算法分支图各大排序算法分析排序方法时间复杂度(平均情况)(最好情况)(最坏情况)空间复杂度稳定性冒泡排序O(n²)O(n²)O(n)O(1)稳定快速排序O(nlogn)O(nlogn)O(n²)O(nlogn)不稳定选择排序O(n²)O(n²)O(n²)O(1)不稳定插入排序O(n²)O(n)O(n²)O(1)不稳定归并排序O(nlogn)O(nlogn)O(nlogn)O(n)稳定希尔排序

2022-01-10 20:45:43 530

原创 B+和B-树特征

每个节点最多包含k个孩子,k的大小取决于磁盘页的大小,孩子最多的时候即为树的阶mB-树1.根结点至少有两个子女。2.每个中间节点都包含k-1个元素和k个孩子,其中 m/2 <= k <= m3.每一个叶子节点都包含k-1个元素,其中 m/2 <= k <= m4.所有的叶子结点都位于同一层。5.每个节点中的元素从小到大排列,节点当中k-1个元素正好是k个孩子包含的元素的值域分划。B+树1.根结点至少有两个子女。2.每个中间节点都包含k-1个元素和k个孩子,其中 m

2021-12-23 23:25:25 346

转载 进程切换和线程切换的区别

进程切换和线程切换的区别我们都知道线程切换的开销比进程切换的开销小,那么小在什么地方?切换的过程是怎样的?上下文切换无论是在多核还是单核系统中,一个CPU看上去都像是在并发的执行多个进程,这是通过处理器在进程间切换来实现的。操作系统实现这种交错执行的机制称为上下文切换。操作系统保持跟踪进程运行所需的所有状态信息,这种状态,也就是上下文,它包括许多信息,例如PC和寄存器文件的当前值,以及主存的内容。在任何一个时刻,单处理器系统都只能执行一个进程的代码。当操作系统决定要把控制权从当前进程转移到某个新进

2021-12-15 15:20:25 1569

原创 #include后的““和<>区别及代码证明

#include后的""和<>区别尖括号<xxx.h>,表示编译器只在系统默认目录或尖括号内的工作目录下搜索头文件,并不去用户的工作目录下寻找,所以一般尖括号用于包含标准库文件,例如:stdio.h,math.h。双引号"xxx.h",表示编译器先在用户的工作目录下搜索头文件,如果搜索不到则到系统默认目录下去寻找,所以双引号一般用于包含用户自己编写的头文件。因此,所该头文件由自己编写,位于工作目录下,就一定要用双引号;若属于标准库文件,则两者都可以,不过最好使用尖括

2021-12-06 16:42:01 786

原创 C++11新特性总结

C++11新特性本文章作为作者的笔记文章,也可以供广大程序猿们进行参考。为保持C++稳定性以及兼容性增加的新特性noexcept修饰符C++98中,我们有一套完整的不同于C的异常处理系统,通过这套异常处理系统,C++拥有了很大的异常处理能力。一般使用throw()动态异常声明,但是事实上,该特性很少被使用,于是就被C++11弃用了,被随之的noexcept取代了。noexcept不会抛出异常,但是如果修饰的函数抛出了异常,则会调用std::terminate()函数来终止程序的运行,这比异常机制的

2021-12-06 16:27:20 572

原创 判定字符是否唯一

解法一这个题大家一看觉得是不是很简单,我可以用一个整形数组来存数量啊,有不为1的不就不唯一吗,再或者我弄一个set集合,每次插入元素再每次检测元素个数不就好了,无增加的话不就是不唯一的吗。这两种方法虽说可行,且时间复杂度不高,但是空间复杂度比较高。题目也说了,如果不使用额外的数据结构,会很加分,那么有同学会说,那我就用暴力啊,轮询的方法,那样的话时间复杂度会达到O(n2),这样子的话时间复杂度有太高了,所以在这我用一种时间复杂度和空间复杂度都不高的方法。解法二其实解法二的思路和整形数组的思路很像,虽.

2021-11-18 00:02:34 380

原创 环路检测并找出入环点

判断链表是否有环比较容易,只需利用快慢指针判断是否相遇或者别的方法即可以判断,但是我们需要判断入环点就比较麻烦一点了。方法一:利用map或者unnorded_map这种方法比较简单,只需要遍历链表,把每一个链表节点insert进入map或者unnorded_map,然后每一次插入后都进行一次判断,看看是否元素个数加一,如果没有,那么插入的这个节点就是如幻点。由于这种方法比较简单,但是空间复杂度高,需要利用到map或者unnorded_map。我就不示例代码了,如果有需要可以评论区评论,这里我着重分析下.

2021-11-16 12:23:41 754

原创 tcp,udp特点

传输控制协议TCPTCP是面向连接的运输层协议。应用进程在使用TCP协议之前,必须先建立TCP连接每一条TCP连接只能有两个端点,每一条TCP连接只能是点对点的。TCP提供可靠交付的服务TCP提供全双工通信。TCP面向字节流 流:流入到进程或者从进程流出的字节序列。面向字节流:虽然应用程序和TCP的交互是一次一个数据块,但TCP把应用程序交下来的数据仅仅看成是一连串的无结构的字节流。用户数据报协议UDPUDP是无连接的。简单方便,但不可靠。UCP使用尽最大努力交付。类似于网络层。

2021-11-15 19:44:57 1019

原创 利用1到7的随机数,产生一个1到10的随机数

这是我面试百度实习二面遇到的算法题,很可惜,我没做出来。。。。不过既然没有做出来,岂能善罢甘休!面试完通过思考,查询,终于把这题整出来了,也算是圆了一个小遗憾吧。利用 1到7 的随机数产生一个 1到10的随机数,要求是等概率的。倘若不是等概率就很好做了,直接乘9之后再除以7就可以得到答案了。可是,这样没有达到要求。我们可以先用1到7的随机数生成器减去1,rand7()-1这样就可以得到一个[0, 6]的随机数生成器,然后乘以7得到一个(0,7,14,21,28,35,42)的随机数生成器,然后都加上[

2021-09-12 01:25:25 4811

原创 内存分配那些事儿

内存程序的内存布局现代的应用程序都运行在一个内存空间里,在32位系统里,这个内存空间拥有2的32次方(4GB)的寻址能力。这种内存模型又称为平坦的内存模型,整个内存是同一个统一的地址空间,用户可以使用一个32位的指针访问任意内存位置。如int *p = (int*) 0x0018ff44*p = 10;这段代码展示了如何直接读写指定地址的内存数据。在4GB的内存空间中,一部分会挪给内核使用,应用程序无法直接访问这内存,这一部分叫做内核空间。windows系统一般会把高地址的2GB内存(或者配置为

2021-07-05 01:30:40 143 1

原创 每一段函数进入汇编指令的操作

将主调方函数的栈底地址入栈,ebp指针指向当前函数栈底通过esp的减等操作在被调用函数开辟栈针把esp和ebp中间所有栈的内存全部初始化成0xCCCCCCCC

2021-06-13 15:36:56 92

原创 守护进程

守护进程概念linux后台执行的一种服务进程,独立于控制终端,周期性地执行某种任务或等待处理某种发生事件,不会随终端关闭而终止,直至接受停止信息才结束,且一般以d结尾的名字。举例系统服务进程 没有控制终端不能直接和用户交互,不受用户登录,注销的影响,一直进行着。如何创建守护进程创建一个孤儿进程脱离形式终端,登陆会话和进程组(setsid)禁止进程重新打开控制终端(重新创一个孤儿进程)关闭打开的文件描述符改变当前工作目录重设文件创建掩模处理SIGCHID信号...

2021-05-05 15:11:03 86

原创 编译和链接那些事儿

现在流行的集成开发环境(IDE)使我们没有去重视编译和链接的细节,编译链接步骤一步完成,通常将这种编译和链接合并到一起的过程称为构建。二编译链接可以分为四个步骤:预处理,编译,汇编,链接。预编译预编译会将.h文件被预编译器cpp预编译成.i文件,而预编译的文件扩展名是.ii,预编译的过程相当于如下指令。$gcc -E hello.c -o hello.i或者$cpp hello.c > hello.i预编译过程主要处理源代码文件中以“#”开始的预编译指令,处理规则如下:将所有的

2021-04-13 16:41:06 178

原创 IO复用epoll

epoll函数epoll_creat#include <sys/epoll.h>int epoll_create(int size); //size为epoll实例大小(仅供参考)创建一个内核事件表,成功时返回epoll文件描述符,失败时返回-1。需要终止时,需要调用close函数epoll_ctl#include <sys/epoll.h>int epoll_stl(int epfd, int op, int fd, struct epoll_event

2021-04-02 16:12:00 63

原创 IO复用poll

poll函数:在指定时间内轮询一定数量的文件描述符,测试是否有齐就绪者。int poll(struct pollfd *fds, nfds_t nfds, int timeout);fds参数数组记录所有监听的文件描述符以及关注的事件struct pollfd{ int fd;//文件描述符 short events;//关注的事件类型 POLLIN | POLLRDHUP short revents;//指定文件描述符上实际发生的事情,由内核填充}nfds

2021-04-02 16:11:18 89

原创 I/O复用select

I/O复用select使用多进程服务器端,创建进程时需要付出极大的代价,需要大量的运算和内存空间,每个进程都是有独立的内存空间的,所以会愈加复杂,所以I/O复用可以改善这个问题。I/O复用的使用情形客户端程序要同时处理多个socket,如我们的非阻塞技术的实现客户端程序要同时处理用户的输入和网络连接。TCP服务器要同时处理监听socket和连接socket。对应实现步骤一:设置文件描述符指定监视范围设置超时步骤二:调用select函数步骤三

2021-04-02 16:10:36 60

原创 线程同步与锁

线程同步与锁线程同步为了避免多个线程同时读写同一个数据而产生不可预料的后果,我们要将各个线程对同一个数据的访问同步。所谓同步,就是指在一个线程访问数据未结束时,其他线程不得对同一个数据进行访问。如此,对数据的访问被原子化了。就像洗手间一样,在一个人方便时,其他人不能进入洗手间。锁同步最常见的方法就是锁,锁是一种非强制机制,每一个线程在访问数据或资源之前首先试图获取锁,并在访问结束之后释放锁。在锁已经被占用的时候试图获取锁,线程会等待,直到锁重新可用。互斥量互斥量是一种简单的锁,他有两种状态,占用

2021-03-27 11:05:51 244 1

原创 线程和进程

线程为何要引入线程多进程通讯的缺点有创建进程的过程会带来一定的开销为了完成进程间的数据交换,需要特殊的IPC技术每秒少则数十次,多则数千次的 上下文切换 是创建进程时最大的开销。上下文切换:运行程序前需要将相应的进程信息读入内存,如果运行进程A后需要紧接着运行进程B,就应该将进程A相关信息移出内存,并读入进程B相关信息。而多线程是一种轻量级进程,它对比进程有如下的优点。线程的创建和上下文切换比进程的创建和上下文切换更快。线程间交换数据时无需特殊技术。...

2021-03-22 15:21:21 119

原创 僵尸进程

僵尸进程概念僵尸进程是当子进程比父进程先结束,而父进程又没有回收子进程,释放子进程占用的资源,此时子进程将成为一个僵尸进程。如果父进程先退出 ,子进程被init接管,子进程退出后init会回收其占用的相关资源危害如果进程不调用wait / waitpid的话,那么保留的那段信息就不会释放,其进程号就会一直被占用,但是系统所能使用的进程号是有限的,如果大量的产生僵尸进程,将因为没有可用的进程号而导致系统不能产生新的进程. 此即为僵尸进程的危害,应当避免。查看僵尸进程数目top命令行输入top命

2021-03-15 15:54:16 75

原创 进程间通讯--共享内存

共享内存概念共享内存就把一片逻辑内存共享出来,让不同的进程去访问它,修改它。为什么共享内存是最快的进程间通讯方式创建一块共享内存,将这块共享内存映射的自己的虚拟地址空间,接下操作都是直接对这块虚拟地址进行操作,进程间数据传递不再涉及到内核(进程不再通过执行进入内核的系统调用来传递彼此的数据),所以相较于其他的进程间通信少了两步内核态用户态之间的数据拷贝。注意事项共享内存并未提供同步机制。也就是说,在第一个进程结束对共享内存的写操作之前,并无自动机制可以阻止第二个进程开始对它进行读取。所以我们通常

2021-03-10 23:54:42 87

原创 反转链表

运用迭代法进行求解 代码如下class Solution {public: ListNode* reverseList(ListNode* head) { ListNode* head1 = NULL; ListNode* curr = head; while(curr){ ListNode* p = curr -> next; //记录下一个元素 curr -> next = he.

2021-03-08 23:42:03 128 1

原创 聊天室项目

刚开始接触网络编程,学了一些内容之后,就像学着做一些项目,所以想实现一个简单的聊天室项目,完成服务器和客户端简单的交流,一开始知识有限,我就是用的socket连接客户端和服务器,然后使用send和recv函数实现了客户端和服务器简单的交流。server.c#include <sys/types.h>#include <sys/socket.h>#include <string.h>#include <stdio.h>#include <net

2021-02-25 21:33:27 243 2

原创 进程间通讯--消息队列

消息队列概念消息队列提供了一种从一个进程向另一个进程发送一个数据块的方法。 每个数据块都被认为含有一个类型,接收进程可以独立地接收含有不同类型的数据结构。我们可以通过发送消息来避免命名管道的同步和阻塞问题。但是消息队列与命名管道一样,每个数据块都有一个最大长度的限制。本质是存储在内核中的一个消息的队列(链表)特点和管道一样,每个消息的最大长度是有上限的(MSGMAX),每个消息队列的总字节数也是有上限的(MSGMNB),系统上的消息队列总数也是有上限的(MSGMNI)...

2021-02-25 10:38:33 187

原创 进程间通讯--管道

管道管道是UNIX系统中最古老的IPC(进程间通信)方式,所有UNIX系统都提供这种通信机制。管道就是从一个进程连接到另一个进程的一个数据流管道分为命名管道和无名管道,在内核中申请一块固定大小的缓冲区,程序拥有写入和读取的权利,都可以看成一种特殊的文件,具有固定的读端和写端,也可以使用普通的read、write 等函数。但是它不是普通的文件,并不属于其他任何文件系统,并且只存在于内存中;无名管道一般使用fork函数实现父子进程的通信,命名管道用于没有血缘关系的进程也可以进程间通信;面向字节流、自带同步

2021-02-22 23:46:35 197 2

原创 fork函数

一个进程,包括代码,数据和分配给进程的资源。fork()函数通过系统调用创建一个与原来几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或传入的变量不同,两个进程也可以做不同的事。在语句fpid = fork()之前,只有一个进程在执行这段代码,但在这条语句之后,就变成两个进程在执行了,这两个进程几乎完全相同。fork之后做什么取决于数据流方向(管道永远流向读端(关闭 fd[1] 的那端)):父进程关闭读端 fd[0] 子进程关闭写端 fd[1] 管道流向从父进程到子进程父进程关

2021-02-22 23:01:43 141

原创 等价多米诺骨牌对的数量

这一题应该用 二元组表示+计数 的方法,既然是二元组,我们可以不妨直接让每一个二元对都变为指定的格式,即第一维必须大于第二维。这样两个二元对「等价」当且仅当两个二元对完全相同。注意到二元对中的元素均不大于 99,因此我们可以将每一个二元对拼接成一个两位的正整数,即(x,y)→10x+y。这样就无需使用哈希表统计元素数量,而直接使用长度为 100的数组即可。class Solution {public: int numEquivDominoPairs(vector<vector.

2021-01-26 19:45:38 132

原创 滑动窗口最大值

这一题我一开始就是简单的暴力解决,结果不能通过所有样例,在一些数据量大的地方会超时。下面附上我的暴力算法。class Solution {public: vector<int> maxSlidingWindow(vector<int>& nums, int k) { vector<int> a; for(int i = k-1;i < nums.size();i++){ int max =.

2021-01-03 00:08:55 72

原创 最大子序和

这题乍一看感觉挺复杂的,感觉看见这种题就想暴力解决,可就这题而言,暴力算法的复杂度会很高的,所以在这里我给出了一种复杂度为O(n)的算法。class Solution {public: int maxSubArray(vector<int>& nums) { int max = nums[0]; //用来记录当前的最大值 int temp = nums[0]; //用来记录潜在最大值(当前数值前缀) for(int .

2020-12-31 01:05:18 96

原创 多线程争冠军(多线程赛跑)

这里设计了一个Champion单例类以及多个线程,每个线程从左到右水平移动一个属于自己的按钮,最先将按钮移动到指定位置的线程为冠军,即该线程将负责创建出Chanpion单例类的唯一实例(冠军),后续将自己的按钮移动到指定位置的其他线程都可以看到冠军的有关信息,即看到Champion单例类的唯一实例的有关属性值。MoveButton.javaimport java.awt.*;import javax.swing.*;import java.util.Random;public class Move

2020-12-17 11:20:49 585 4

原创 串的模式匹配之kmp算法

串的模式匹配之kmp算法(这里写自定义目录标题)设有两个串s和t,串t的定位就是要在串s中找到一个与t相等的子串。通常把s称为目标串,把t称为模式串,因此串定位查找也称为模式匹配。模式匹配成功是指在目标串s中找到一个一个模式串t;不成功则是指目标串s中不存在模式串t。在介绍kmp算法之前,我首先介绍一下Brute-Force算法。即暴力算法。Brute-Force算法暴力算法采用穷举的方法,基本思路就是目标串的第一个字符开始和模式串的第一个字符若相等,则逐个比较后续字符。否则目标串的第二个字符就开始重

2020-11-17 10:56:48 3026

原创 小球的距离

刚开始做这个题受到了括号里”数字都为整数“的误导,以为落地距离是5米,弹起后2米(5/2自动取整)。算出来结果不对,变小了。所以,不是自动取整。就是所有的都算进去,这就牵扯到数学上的极限思想了。除了最开始的下落高度只加一次外,以后的弹起下落都是两倍的距离。举个例子,下落高度是x米 ,则有下落后弹起的高度是x/2,再落下去,又走了一个x/2,依此类推,一直下去,也就是总距离为 x+2x(1/2+1/4+1/8+……),而括号中的数列是一个等比数列,其极限求和的结果就是1。所以 总距离就是3x。推.

2020-06-13 23:47:07 172

原创 末尾0的个数

此题看上去不难,可能第一思维就是先把阶乘算出来,然后进行去后面的0的操作,但是阶乘的变化是非常快的,到了后面,甚至连long long都不能表达出来。所以我们只能另辟蹊径,阶乘末尾的0,每一个0实际上是由2和5相乘而得到的,所以说,我们只需要把从1到n中,每一个数的2和5分离出来,但是实际上,我们可以只要把5分离出来就好了,因为2的数量肯定比5多,以下就是我的代码:#include <iostream>int main(){ int n, sum = 0, k;//sum为统计0的个.

2020-06-11 22:32:34 319

原创 字符串中找出连续最长的数字串

字符串中找出连续最长的数字串本题不仅要知道最长字符串的长度,还需要输出这一串字符串,我的代码如下#include <iostream>#include <string>int main(){ int max=0, count = 0, first;//max为最长数字串的长度,count为当前数字串的长度,first为最长数字串的首位置 std::string a; std::cin >> a; for (int i = 0;i <= a.siz

2020-06-10 21:19:32 227

原创 文件的打开模式

1.ofstream:写数据 ifstream:读数据fstream = ofstream + ifstream创建fstream对象时,应指定文件打开模式Mode(模式)Description(描述)ios::in打开文件读数据ios::out打开文件写数据ios::app把输出追加到文件末尾。app = appendios::ate打开文件,把文件光标移到末尾。ate = atendios::trunc若文件存在则舍弃其内容。这是ios::o

2020-05-30 23:12:37 220

原创 在文件操作中格式化输入输出

流控制符同样可以用于文件输入/输出控制符用途setw(width)设置输出字段的宽度(仅对其后第一个输出有效)setprecision(n)设置浮点数的输入/出精度(总有效数字个数等于n)fixed将浮点数以定点数形势输入/出(小数点后有效数字个数等于setprecision指定的nshowpoint将浮点数以带小数点和结尾0的形式输入/出,即便该浮点数没有小数部分left输出内容左对齐right输出内容右对齐hexfloat/defau

2020-05-28 22:04:11 156 1

原创 手机问题

以上这个题目感觉很简单,所以我很快就写出了代码在这里插入代码片

2020-05-14 13:18:15 206

原创 关于计算高精度的阶乘之和的问题

关于计算阶乘之和,你肯定会觉得这是一个非常简单的问题,那只不是用一个循环而已了,很简单了。但是要计算高精度呢,高精度,我的第一想法,把我们平常用的int换成long或者long long呗,实在这些还是不行,那我用unsigned long long这总行了吧。于是我为了保险,我直接用unsigned long long来的,毕竟阶乘也无负数,以下就是我的代码。...

2020-04-18 12:17:59 703

空空如也

空空如也

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

TA关注的人

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