自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(437)
  • 资源 (2)
  • 收藏
  • 关注

原创 《剑指offer》算法题二刷整理

123

2020-07-26 09:48:50 352

原创 刷题-《程序员面试金典》

class Solution {public: bool isUnique(string astr) { if(astr.size()==0)return true; unordered_set<char>myset={astr[0]}; for(int i=1;i<astr.size();i++) { if(myset.find(astr[i])!=myset.end()) .

2020-06-27 17:26:57 444

原创 最近最久未被使用(LRU)缓存机制(哈希链表)

LRU 缓存算法的核心数据结构就是哈希链表,双向链表和哈希表的结合体。这个数据结构长这样:其实很简单:哈希表(unordered_map)中的二元组为unordered_map<int, list<pair<int, int>>::iterator>;双向链表(list)中的二元组为list<pair<int, int>>。分析上面的操作过程,要让 put 和 get 方法的时间复杂度为O(1),我们可以总结出 cache 这个数据结构必要.

2020-05-25 16:25:11 280

原创 python类属性和实例属性的注意点

python

2022-08-23 14:04:27 707

原创 python staticmethod和classmethod的作用与区别

python

2022-08-23 13:54:14 471 1

原创 docker内ubuntu升级python到3.8

python

2022-06-23 11:17:22 2276 1

原创 NFS测试(server+client)

nfs

2022-06-03 21:48:48 576

原创 python request模块里面data、json、params传参方式的不同(使用httpbin工具测试)

1、json.dumps()和json.loads()是json格式处理函数json.dumps()函数是将json(即dict)转化为str;json.loads()函数是将str转化为json(即dict)。2、requests模块发送请求有data、json、params三种携带参数的方法。params在get请求中使用,data、json在post请求中使用。params:字典或者字节序列,作为参数增加到url中,只能用于GET方法,不能使用在POST方法里面:kv = {"wd": "

2022-02-05 21:31:09 1659

原创 C++11 R字符串

原始字面量在 C++11 中添加了定义原始字符串的字面量,定义方式为:R “xxx(原始字符串)xxx” 其中 () 两边的字符串可以省略。原始字面量 R 可以直接表示字符串的实际含义,而不需要额外对字符串做转义或连接等操作。#include <iostream>using namespace std;int main(){ const char* s1 = R"(Hello\\World)"; cout << s1 << endl; const char

2022-01-10 13:26:32 2324

原创 muduo关键易忘点整理

Channel是 selectable IO channel,负责注册与响应IO事件,它把fd和所关注的事件绑定在一起,即一个Channel对象(通道)就是一个事件。一个EventLoop类中有一个红黑树(EventLoop类与Poller类是组合关系),一个EventLoop类的对象所在的线程就是一个IO线程。Acceptor类(即TcpServer类)所在的IO线程就是main reactor,负责监听连接,每个连接创建一个TcpConnection类的对象,TcpConnection类的对象所在.

2021-10-12 11:22:44 133

原创 C++11 emplace_back(最后又回顾了一下移动构造和移动赋值)

我们在对STL容器进行插入操作时,常会使用insert或push_back。C++11提出了更高效的插入方法:emplace。下面介绍C++11新特性中emplace的使用与原理。vectoremplace <--> insertemplace_back​ <--> ​push_backsetemplcace <--> insertmapemplace <--> insert以vector的emplace_back为例:#includ

2021-09-13 16:47:54 963

原创 std::bind

其实std::bind和boost::bind几乎完全一样。普通函数使用std::bind#include <iostream>#include <functional>double callableFunc (double x, double y,double z) {return x+y-z;}int main() { std::function<double(double)> NewCallable1 = std::bind (callableF

2021-08-16 21:41:14 728

原创 字符串常量初始化指针的小问题

char a[20] = "1234";cout << a << endl;char *p = a;cout << p << endl;那么该如何得到该字符串的地址呢?cout << (int*)a << endl;cout << &a << endl;这两种方法都可以正确打印出“字符串的地址”,但是有细微区别之处在字符数组a中,a表示第一个字符的地址,a+1表示第二个字符的地址;

2021-06-09 22:26:30 173

原创 const_cast的小问题

const_cast只可以对指针和引用使用也许大家都有过这样的疑惑:const_cast可以去除一个常量的const属性,去除const属性后应该可以对“常量”进行修改,通过调试器发现内存中的值是被改变的,可是再传递这个“常量”的时候,值却一直保持原状,这是为什么呢?void fun(int &value){ cout << "Fun(val)=" << value << endl;}int main() { const int val = 10

2021-06-09 21:40:40 375 1

原创 muduo_net库源码分析(十一)(EventLoopThread类、EventLoopThreadPool类实现multiple reactors)

一个程序有多个EventLoop,也就是有多个IO线程(one loop per thread)

2021-05-14 20:37:20 144

原创 非常量引用的初始值必须为左值

先看一段报错的代码:#include<iostream>using namespace std;int main(){ int i = 2; double &r = i; system("pause"); return 0;}

2021-05-08 18:50:01 5361

原创 copy ctor、copy assignment(拷贝构造函数和拷贝赋值函数)

这个很早就搞明白了,只是这里系统整理一下。例1:例2:#include<iostream>#include<functional>#include<numeric>using namespace std;// TEMPLATE STRUCT plustemplate<class _Ty = void>struct my_plus{ // functor for operator+ typedef _Ty first_argument_

2021-05-08 11:23:27 1157 3

原创 一元函数对象、二元函数对象、一元谓词函数对象、二元谓词函数对象、lambda表达式、函数适配器binder2nd及其辅助函数bind2nd

一元函数对象:函数参数1个二元函数对象:函数参数2个;一元谓词对象:函数参数1个,函数返回值是bool类型,可以作为一个判断式,谓词可以是一个仿函数,也可以是一个回调函数;二元谓词对象:函数参数2个,函数返回值是bool类型;之所以给返回布尔类型的函数对象专门命名,是因为谓词是用来为算法判断服务的。一元谓词...

2021-05-07 16:49:06 269

原创 muduo_net库源码分析(十)

创建EventLoop类的对象–>通过该对象调用EventLoop::loop–>EventLoop::loop中调用Poller::poll(多态)返回活跃的Channel对象–>调用Channel::handleEvent–>在Channel::handleEvent中,如果到来的是连接关闭事件,由于该事件是读事件,所以调用读事件回调函数(这里已经在TcpConnection类的构造函数中通过其Channel对象调用Channel::setReadCallback将TcpCo..

2021-05-06 16:56:16 157 1

原创 boost::shared_ptr分析(对TcpConnection类的对象的生存期进行管理)

智能指针很常用,由于muduo::net库中使用boost::shared_ptr对TcpConnection类的对象的生存期进行管理,因此这里先分析下boost::shared_ptr的几个新鲜的用法,进行测试。详细的测试代码如下(测试目标写在注释里了):#include<iostream>#include<boost/enable_shared_from_this.hpp>#include<boost/shared_ptr.hpp>#include<b

2021-05-06 15:36:45 263 1

原创 muduo_net库源码分析(九)(TcpServer类、TcpConnection类)

Acceptor类的对象是TcpServer类的成员!Acceptor类与TcpServer类是组合关系。Acceptor::handleRead–>在Acceptor::handleRead中,除了调用::accept外,还调用了应用层回调函数 newConnectionCallback_(这里通过Acceptor::setNewConnectionCallback将应用层回调函数newConnectionCallback_设置为TcpServer::newConnection)...

2021-05-02 21:30:04 688 2

原创 muduo_net库源码分析(八)(Acceptor类)

Acceptor类

2021-04-28 12:36:28 157

原创 muduo_net库源码分析(七)(Socket类)

一些基础函数的使用说明可查看:linux 网络编程之TCP的C/S模型

2021-04-20 22:11:19 135

原创 muduo_net库源码分析(六)(EventLoopThread类创建IO线程)

EventLoopThread类调用顺序:主线程中:EventLoopThread::startLoop–>在EventLoopThread::startLoop调用Thread::start创建子线程,即通过Thread::start中的::pthread_create创建子线程。子线程中:当::pthread_create创建子线程成功后子线程会自动调用线程函数EventLoopThread::threadFunc–>EventLoopThread::threadFunc的任务就是创

2021-04-18 19:24:12 135

原创 muduo_net库源码分析(五)(通过EventLoop::runInLoop实现跨线程调用)

pipe:等待线程关注fd[0]的可读事件,通知线程只需要往fd[1]中写入数据,fd[0]就变得可读了。socketpair:与pipe类似,区别在于socketpair可以双向工作,pipe只能单向工作。别忘了线程间的等待/通知还可以用条件变量实现。一.Eventloop与Channel是聚合关系,但是有一个地方例外,这个地方就是Eventloop中等待/通知事件的Channel(即wakeupChannel_),与Eventloop是组合关系。二.EventLoop::wakeup函数中产.

2021-04-17 21:28:19 112

原创 muduo_net库源码分析(四)

对应p28

2021-04-16 20:47:56 163

原创 muduo_net库源码分析(三)

1.定时器函数选择1.定时函数,用于让程序等待一段时间或安排计划任务:sleepalarmusleepnanosleepclock_nanosleepgetitimer / setitimertimer_create / timer_settime / timer_gettime / timer_deletetimerfd_create / timerfd_gettime / timerfd_settime2.timerfd_* 入选的原因:(1)sleep / alarm / usl

2021-03-31 15:50:07 133 1

原创 muduo_net库源码分析(二)(EventLoop类、Channel类、Poller类)

1.类图白色的是外部类,表示对外可见,灰色的是内部类,表示对外不可见,实心的菱形表示类之间是组合关系,空心的菱形表示类之间是聚合关系( 处于聚合关系的两个类生命周期不同步,简单来说就是在类里面以指针形式定义其它类的对象;处于组合关系的两个类的生命周期同步)。EventLoop类是对事件循环的抽象;Poller类是对IO复用的抽象,它有两个派生类PollPoller和EPollPoller,分别是对poll和epoll的封装(这里Poller是抽象类,是muduo库中唯一使用面向对象思想编程的地方,其他

2021-03-26 15:12:44 183 1

原创 muduo_net库源码分析(一)

1.TCP网络编程本质TCP网络编程最本质是的处理三个半事件1.连接建立:服务器accept(被动)接受连接,客户端connect(主动)发起连接。2.连接断开:主动断开(close、shutdown),被动断开(read返回0)。3.消息到达:文件描述符可读。4.消息发送完毕:这算半个。对于低流量的服务,可不必关心这个事件;这里的发送完毕是指数据写入内核缓冲区,将由TCP协议栈负责数据的发送与重传,不代表对端已经接收到数据。2.EchoServer类图显然,这是基于对象的编程思想,在Ec

2021-03-25 10:25:40 200

原创 socket阻塞和非阻塞

socket阻塞和非阻塞有哪些不同1. 建立连接阻塞方式下,connect首先发送SYN请求到服务器,当客户端收到服务器返回的SYN的确认时,则connect返回,否则的话一直阻塞。非阻塞方式,connect将启用TCP协议的三次握手,但是connect函数并不等待连接建立好才返回,而是立即返回,返回的错误码为EINPROGRESS,表示正在进行某种过程。2. 接收连接阻塞模式下调用accept()函数,而且没有新连接时,进程会进入睡眠状态,直到有可用的连接,才返回。非阻塞模式下调用accept

2021-03-24 16:03:17 743

原创 多线程与并发服务器常见模型

常见并发服务器方案1.iterative(循环式/迭代式)服务器iterative 只能使用短连接(每处理完一个连接,然后就关闭连接,称为短连接),不能使用长连接,如果使用长连接,意味着write需要转到read,那么整个程序就是一个单线程程序,如果此时有其它线程过来,没有办法接受连接,因为前一个线程还在read->write的循环中。也就是说如果使用长连接的话,这个程序只能够处理一个客户端,而不能处理多个客户端。要想让程序处理多个客户端,只能使用短连接。这种服务器不是真正意义上的并发服务器,

2021-03-24 11:04:03 442

原创 muduo_base库源码分析(十二)

LogFile类对象调用append函数时,里面会调用LogFile类的append_unlock函数,而append_unlock函数中又会通过LogFile类的嵌套类FILE的对象file_去调用嵌套类FILE的append函数,

2021-03-20 16:47:41 140 2

原创 muduo_base库源码分析(十一)

muduo库的日志默认是INFO级别

2021-03-18 16:32:09 186

原创 fflush()函数

fflush()函数:更新缓存区。头文件:#include<stdio.h>函数定义:int fflush(FILE *stream);函数说明:调用fflush()会将缓冲区中的内容写到stream所指的文件中去.若stream为NULL,则会将所有打开的文件进行数据更新。fflush(stdin):刷新缓冲区,将缓冲区内的数据清空并丢弃。fflush(stdout):刷新缓冲区,将缓冲区内的数据输出到设备。看如下代码:#inlcude<stdio.h>int ma

2021-03-18 11:12:21 26660 3

原创 C++类中使用typedef和类中使用枚举类型(muduo日志类中遇到的问题)

在学习muduo_base库中的日志类时,发现了一种新鲜的语法。1.在类的public中typedef定义的新类型,可以在类外使用类名::新类型名的方式调用。class Test{public:  typedef int integer;...};如果该语句放在public段中,则可以在类外部使用,如:Test::integer a=1;//声明一个变量2.在类的public中声明了枚举类,那么可以通过类名::enum值直接访问枚举值,不需要通过对象。测试代码如下(自己写的挺好的例

2021-03-15 21:58:17 390

原创 muduo_base库源码分析(十)

核心点:每个线程中只有一个T类型的线程特定数据,各个线程通过muduo::ThreadLocalSingleton<T>::instance()的方式,获取T类型的线程特定数据。(很巧妙!)ThreadLocalSingleton< T >类ThreadLocalSingleton.h#ifndef MUDUO_BASE_THREADLOCALSINGLETON_H#define MUDUO_BASE_THREADLOCALSINGLETON_H#include &l.

2021-03-12 19:57:24 107

原创 muduo_base库源码分析(九)

__thread关键字前面已经学过了。其实本质上,线程特定数据的数据结构如下:注意,实际数据在堆空间上。ThreadLocal.h#ifndef MUDUO_BASE_THREADLOCAL_H#define MUDUO_BASE_THREADLOCAL_H#include <boost/noncopyable.hpp>#include <pthread.h>namespace muduo{//核心点:每创建一个ThreadLocal对象,就能创建一个线程..

2021-03-12 11:33:19 151 1

原创 muduo_base库源码分析(八)

Singleton.h#ifndef MUDUO_BASE_SINGLETON_H#define MUDUO_BASE_SINGLETON_H#include <boost/noncopyable.hpp>#include <pthread.h>#include <stdlib.h> // atexitnamespace muduo{template<typename T>class Singleton : boost::nonco..

2021-03-11 11:19:33 142 1

原创 muduo_base库源码分析(七)

线程池问题本质上也是生产者-消费者问题,生产者向任务队列中添加任务,线程队列中的线程从任务队列中取出任务执行。Task函数是要执行的任务;threads_是线程队列,是一个ptr_vector,内部存放线程指针;queue_是任务队列;start函数用来启动线程池(创建固定个数的线程);run函数用来往线程池中的任务队列添加任务;runInThread函数是线程池中的线程要执行的函数(显然每个线程要重复执行任务,所以函数中肯定有while循环);take函数:线程池中的线程函数要去任务队.

2021-03-10 22:11:10 102

原创 muduo_base库源码分析(六)

这两个类其实就是多生产者-多消费者模型(使用条件变量实现)。BlockingQueue类(无界缓冲区)基于std::deque实现。BlockingQueue.h很简单因为无界,所以一个条件变量就够了。#ifndef MUDUO_BASE_BLOCKINGQUEUE_H#define MUDUO_BASE_BLOCKINGQUEUE_H#include <muduo/base/Condition.h>#include <muduo/base/Mutex.h>.

2021-03-10 16:11:56 129

java基础 综合项目代码

java基础 综合项目

2020-12-21

epoll反应堆.zip

epoll反应堆.zip

2020-06-25

空空如也

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

TA关注的人

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