- 博客(57)
- 收藏
- 关注
原创 Reactor模式
1. Reactor模式简介Reactor模式也叫反应器模式,大多数IO相关组件如redis也在使用该模式。 reactor模式原理是I/O 多路复用监听事件,收到事件后,根据事件类型分配(Dispatch)给某个进程 / 线程。2. Reactor的实现eactor 模式主要由 Reactor 和处理资源池这两个核心部分组成,它俩负责的事情如下:Reactor 负责监听和分发事件,事件类型包含连接事件、读写事件;处理资源池负责处理事件,如 read -> 业务逻辑 -> send;
2022-05-30 14:02:20 831 2
原创 理解死锁的四个条件
理解死锁的四个条件1. 通俗的解析//多线程死锁void data_process1() { EnterCriticalSection(&cs1); EnterCriticalSection(&cs2); do_something1(); LeaveCriticalSection(&cs2); LeaveCriticalSection(&cs1); } void data_process2()
2022-03-01 16:28:56 725
原创 反转链表整个链表以及部分链表(递归)
反转整个链表#include <bits/stdc++.h>struct ListNode{ int val; struct ListNode *next; ListNode(int x) : val(x), next(nullptr) { }};class Solution{public: //以head为起点,反转链表,并返回头节点 ListNode *ReverseList(ListNode *pHead)
2022-01-23 11:36:50 597
原创 OSI协议
互联网的逻辑实现被分为好几层。每一层都有自己的功能,就像建筑物一样,每一层都靠下一层支持。用户接触到的只是最上面的那一层,根本不会感觉到下面的几层。要理解互联网就需要自下而上理解每一层的实现的功能。如上图所示,互联网按照不同的模型划分会有不用的分层,但是不论按照什么模型去划分,越往上的层越靠近用户,越往下的层越靠近硬件。在软件开发中我们使用最多的是上图中将互联网划分为五个分层的模型。物理层我们的电脑要与外界互联网通信,需要先把电脑连接网络,我们可以用双绞线、光纤、无线电波等方式。这就叫做”实物理层”
2022-01-04 17:50:41 1074
原创 二叉搜索树(验证合法性以及增删查改)
验证二叉搜索树#include <bits/stdc++.h>using namespace std;struct TreeNode{ int val; TreeNode *left; TreeNode *right; TreeNode() : val(0), left(nullptr), right(nullptr) {} TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
2022-01-04 14:18:26 101
原创 将二叉树转成单链表(c++&&goalng)
struct TreeNode{ int val; TreeNode *left; TreeNode *right; TreeNode() : val(0), left(nullptr), right(nullptr) {} TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} TreeNode(int x, TreeNode *left, TreeNode *right) : val(x),
2021-12-28 17:05:44 548
原创 填充二叉树节点的右侧指针(c++&&golang)
/*给定一个 完美二叉树 ,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下:struct Node { int val; Node *left; Node *right; Node *next;}填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。初始状态下,所有 next 指针都被设置为 NULL。*/// Definition for a Node.class Node{
2021-12-28 15:18:27 481
原创 翻转二叉树(c++&&golang)
#include <bits/stdc++.h>using namespace std;struct TreeNode{ int val; TreeNode *left; TreeNode *right; TreeNode() : val(0), left(nullptr), right(nullptr) {} TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} TreeNo
2021-12-28 14:55:26 106
原创 行为型模式 - 中介者模式
1. 模式动机在用户与用户直接聊天的设计方案中,用户对象之间存在很强的关联性,将导致系统出现如下问题:系统结构复杂:对象之间存在大量的相互关联和调用,若有一个对象发生变化,则需要跟踪和该对象关联的其他所有对象,并进行适当处理。对象可重用性差:由于一个对象和其他对象具有很强的关联,若没有其他对象的支持,一个对象很难被另一个系统或模块重用,这些对象表现出来更像一个不可分割的整体,职责较为混乱。系统扩展性低:增加一个新的对象需要在原有相关对象上增加引用,增加新的引用关系也需要调整原有对象,系统耦合度很高
2021-12-28 09:08:06 390
原创 行为型模式 - 命令模式
1. 模式动机在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,我们只需在程序运行时指定具体的请求接收者即可,此时,可以使用命令模式来进行设计,使得请求发送者与请求接收者消除彼此之间的耦合,让对象之间的调用关系更加灵活。命令模式可以对发送者和接收者完全解耦,发送者与接收者之间没有直接引用关系,发送请求的对象只需要知道如何发送请求,而不必知道如何完成请求。这就是命令模式的模式动机。2. 模式定义命令模式(Command Pattern):将一个请求
2021-12-24 11:54:49 390
原创 创建型模式 - 代理模式
1. 模式动机在某些情况下,一个客户不想或者不能直接引用一个对 象,此时可以通过一个称之为“代理”的第三者来实现 间接引用。代理对象可以在客户端和目标对象之间起到 中介的作用,并且可以通过代理对象去掉客户不能看到 的内容和服务或者添加客户需要的额外服务。通过引入一个新的对象(如小图片和远程代理 对象)来实现对真实对象的操作或者将新的对 象作为真实对象的一个替身,这种实现机制即 为代理模式,通过引入代理对象来间接访问一 个对象,这就是代理模式的模式动机。2. 模式定义代理模式(Proxy Patter
2021-12-23 14:32:45 117
原创 结构型模式 - 外观模式
1. 模式定义外观模式(Facade Pattern):外部与一个子系统的通信必须通过一个统一的外观对象进行,为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。外观模式又称为门面模式,它是一种对象结构型模式。2. 模式结构外观模式包含如下角色:Facade: 外观角色SubSystem:子系统角色3. 时序图4.代码分析4.1.c++实现#include <iostream>using namespace
2021-12-22 16:34:07 142
原创 结构型模式 - 享元模式
1. 模式定义外观模式(Facade Pattern):外部与一个子系统的通信必须通过一个统一的外观对象进行,为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。外观模式又称为门面模式,它是一种对象结构型模式。2. 模式结构外观模式包含如下角色:Facade: 外观角色SubSystem:子系统角色3. 时序图4.代码分析4.1.c++实现#include <iostream>using namespace
2021-12-22 16:31:18 109
原创 创建型模式 - 装饰器模式
1. 模式动机一般有两种方式可以实现给一个类或对象增加行为:继承机制,使用继承机制是给现有类添加功能的一种有效途径,通过继承一个现有类可以使得子类在拥有自身方法的同时还拥有父类的方法。但是这种方法是静态的,用户不能控制增加行为的方式和时机。关联机制,即将一个类的对象嵌入另一个对象中,由另一个对象来决定是否调用嵌入对象的行为以便扩展自己的行为,我们称这个嵌入的对象为装饰器(Decorator)装饰模式以对客户透明的方式动态地给一个对象附加上更多的责任,换言之,客户端并不会觉得对象在装饰前和装饰后有
2021-12-20 11:21:00 95
原创 结构性模式 - 桥接模式
1. 模式动机设想如果要绘制矩形、圆形、椭圆、正方形,我们至少需要4个形状类,但是如果绘制的图形需要具有不同的颜色,如红色、绿色、蓝色等,此时至少有如下两种设计方案:第一种设计方案是为每一种形状都提供一套各种颜色的版本。第二种设计方案是根据实际需要对形状和颜色进行组合对于有两个变化维度(即两个变化的原因)的系统,采用方案二来进行设计系统中类的个数更少,且系统扩展更为方便。设计方案二即是桥接模式的应用。桥接模式将继承关系转换为关联关系,从而降低了类与类之间的耦合,减少了代码编写量。2. 模式定义
2021-12-17 18:11:43 133
原创 结构性模式 - 适配器模式
1.模式动机在软件开发中采用类似于电源适配器的设计和编码技巧被称为适配器模式。通常情况下,客户端可以通过目标类的接口访问它所提供的服务。有时,现有的类可以满足客户类的功能需要,但是它所提供的接口不一定是客户类所期望的,这可能是因为现有类中方法名与目标类中定义的方法名不一致等原因所导致的。在这种情况下,现有的接口需要转化为客户类期望的接口,这样保证了对现有类的重用。如果不进行这样的转化,客户类就不能利用现有类所提供的功能,适配器模式可以完成这样的转化。在适配器模式中可以定义一个包装类,包装不兼容接口
2021-12-16 16:41:54 98
原创 创建型模式 - 建造者模式
1.模式动机无论是在现实世界中还是在软件系统中,都存在一些复杂的对象,它们拥有多个组成部分,如汽车,它包括车轮、方向盘、发送机等各种部件。而对于大多数用户而言,无须知道这些部件的装配细节,也几乎不会使用单独某个部件,而是使用一辆完整的汽车,可以通过建造者模式对其进行设计与描述,建造者模式可以将部件和其组装过程分开,一步一步创建一个复杂的对象。用户只需要指定复杂对象的类型就可以得到该对象,而无须知道其内部的具体构造细节。在软件开发中,也存在大量类似汽车一样的复杂对象,它们拥有一系列成员属性,这些成员属性中
2021-12-15 17:45:18 97
转载 设计模式分类说明(创建型、结构型、行为型)
1.创建型模式创建型模式:就是创建对象的模式,抽象了实例化的过程。关注的是对象的创建,创建型模式将创建对象的过程进行抽象,可以理解为将创建对象进行了封装,作为客户程序只需使用对象,不再关心创建对象过程的逻辑。社会化的分工越来越细,自然在软件设计方面也是如此,因此对象的创建和对象的使用分开也就成为了必然趋势。因为对象的创建会消耗掉系统的很多资源,所以单独对对象的创建进行研究,从而能够高效地创建对象就是创建型模式要探讨的问题。这里有6个具体的创建型模式可供研究,它们分别是:简单工厂模式(Simple F
2021-12-15 10:09:00 534
原创 创建型模式 - 抽象工厂模式
1.模式动机在工厂方法模式中具体工厂负责生产具体的产品,每一个具体工厂对应一种具体产品,工厂方法也具有唯一性,一般情况下,一个具体工厂中只有一个工厂方法或者一组重载的工厂方法。但是有时候我们需要一个工厂可以提供多个产品对象,而不是单一的产品对象。为了更清晰地理解工厂方法模式,需要先引入两个概念:产品等级结构 :产品等级结构即产品的继承结构,如一个抽象类是电视机,其子类有海尔电视机、海信电视机、TCL电视机,则抽象电视机与具体品牌的电视机之间构成了一个产品等级结构,抽象电视机是父类,而具体品牌的
2021-12-14 10:17:41 117
原创 创建型模式 - 工厂方法模式
1.模式动机现在对该系统进行修改,不再设计一个按钮工厂类来统一负责所有产品的创建,而是将具体按钮的创建过程交给专门的工厂子类去完成,我们先定义一个抽象的按钮工厂类,再定义具体的工厂类来生成圆形按钮、矩形按钮、菱形按钮等,它们实现在抽象按钮工厂类中定义的方法。这种抽象化的结果使这种结构可以在不修改具体工厂类的情况下引进新的产品,如果出现新的按钮类型,只需要为这种新类型的按钮创建一个具体的工厂类就可以获得该新按钮的实例,这一特点无疑使得工厂方法模式具有超越简单工厂模式的优越性,更加符合“开闭原则”。2.模式
2021-12-13 16:52:10 106
原创 创建型模式 - 简单工厂模式
1.模式动机考虑一个简单的软件应用场景,一个软件系统可以提供多个外观不同的按钮(如圆形按钮、矩形按钮、菱形按钮等),这些按钮都源自同一个基类,不过在继承基类后不同的子类修改了部分属性从而使得它们可以呈现不同的外观,如果我们希望在使用这些按钮时,不需要知道这些具体按钮类的名字,只需要知道表示该按钮类的一个参数,并提供一个调用方便的方法,把该参数传入方法即可返回一个相应的按钮对象,此时,就可以使用简单工厂模式。2.模式定义简单工厂模式(Simple Factory Pattern):又称为静态工厂方法(S
2021-12-11 23:22:56 109
原创 创建型模式 - 单例模式
1.模式动机对于系统中的某些类来说,只有一个实例很重要,例如,一个系统中可以存在多个打印任务,但是只能有一个正在工作的任务;一个系统只能有一个窗口管理器或文件系统;一个系统只能有一个计时工具或ID(序号)生成器。如何保证一个类只有一个实例并且这个实例易于被访问呢?定义一个全局变量可以确保对象随时都可以被访问,但不能防止我们实例化多个对象。一个更好的解决办法是让类自身负责保存它的唯一实例。这个类可以保证没有其他实例被创建,并且它可以提供一个访问该实例的方法。这就是单例模式的模式动机。2.模式定义单例
2021-12-10 17:16:34 101
原创 看懂UML类图和时序图
1.从一个示例开始请看以下这个类图,类之间的关系是我们需要关注的:车的类图结构为<>,表示车是一个抽象类;它有两个继承类:小汽车和自行车;它们之间的关系为实现关系,使用带空心箭头的虚线表示;小汽车为与SUV之间也是继承关系,它们之间的关系为泛化关系,使用带空心箭头的实线表示;小汽车与发动机之间是组合关系,使用带实心箭头的实线表示;学生与班级之间是聚合关系,使用带空心箭头的实线表示;学生与身份证之间为关联关系,使用一根实线表示;学生上学需要用到自行车,与自行车是一种依赖关系,使
2021-12-10 11:50:03 186
原创 c++实现二叉树的4种遍历(递归和非递归)
二叉树的遍历(traversing bianry tree)是指从根结点出发,按照某种次序依次访问二叉树中所有结点,使得每个结点被访问一次且仅被访问一次。1)前序遍历:规则是若二叉树为空,则空操作返回,否则先访问根结点,然后前序遍历左子树,再前序遍历右子树----------------------递归思想2)中序遍历:规则是若树为空,则空操作返回,否则从根结点开始(仅仅是开始,先不访问该结点),中序遍历根结点的左子树,然后是访问根结点(访问),最后中序遍历右子树--------------------
2021-11-24 14:42:55 634
原创 删除链表中重复的结点(c++&&go)
/*在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表 1->2->3->3->4->4->5 处理后为 1->2->5*/#include <bits/stdc++.h>struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NUL
2021-11-22 09:20:30 506
原创 两个链表的第一个公共结点(c++&&go)
/* 输入两个无环的单向链表,找出它们的第一个公共结点,如果没有公共节点则返回空。(注意因为传入数据是链表,所以错误测试数据的提示是用其他方式显示的,保证传入数据是正确的) */#include <bits/stdc++.h>struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) { }};class Solution {public: /
2021-11-22 09:19:43 111
原创 链表中倒数最后k个结点(c++&&go)
/*输入一个长度为 n 的链表,设链表中的元素的值为 ai ,返回该链表中倒数第k个节点。如果该链表长度小于k,请返回一个长度为 0 的链表。*/#include <bits/stdc++.h>struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(nullptr) {}};class Solution {public: /** * 代码中的类名、方法名、
2021-11-22 09:18:49 377
原创 合并两个排序的链表(c++&&go)
/* 输入两个递增的链表,单个链表的长度为n,合并这两个链表并使新链表中的节点仍然是递增排序的。 */#include <bits/stdc++.h>struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) { }};//非递归/* class Solution {public: ListNode* Merge(ListNode* pHe
2021-11-22 09:17:24 538
原创 复杂链表的复制(c++&&go)
/*输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针random指向一个随机节点),请对此链表进行深拷贝,并返回拷贝后的头结点。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)。 下图是一个含有5个结点的复杂链表。图中实线箭头表示next指针,虚线箭头表示random指针。为简单起见,指向null的指针没有画出。*/struct RandomListNode { int label; struct RandomL
2021-11-22 09:16:10 98
原创 理解RESTful架构
1.RESTRESTful,是目前最为流行的一种互联网软件架构。因为它结构清晰、符合标准、易于理解、扩展方便,所以正得到越来越多网站的采用。1.1.什么是RESTREST指的是一组架构的约束条件和原则。满足这些约束条件和原则的应用程序或者设计就是RESTful的。REST的几个概念:资源REST是“表现层状态转化”。“表现层”指的是“资源”的表现层;表现层:资源是一个具体的实体信息,可以有多种的展示方式,把实体展示出来就是表现层;状态转化:访问一个网站,就代表客户端和服务器的一个互动过程,这
2021-11-21 21:09:04 282
原创 反转链表(c++&&go)
/*给定一个单链表的头结点pHead,长度为n,反转该链表后,返回新链表的表头。*/#include <bits/stdc++.h>struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(nullptr) { }};class Solution {public: ListNode* ReverseList(ListNode* pHead) {
2021-11-19 14:38:24 452
原创 从尾到头打印链表(c++&&go)
cpp/*输入一个链表的头节点,按链表从尾到头的顺序返回每个节点的值(用数组返回)。*/#include <bits/stdc++.h>#include <vector>using namespace std;struct ListNode{ int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) { }};class Solution
2021-11-19 14:34:06 883
原创 链表中环的入口结点(c++ &&go)
cpp/*给一个长度为n链表,若其中包含环,请找出该链表的环的入口结点,否则,返回null。*/#include <bits/stdc++.h>struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) { }};//哈希表/* class Solution {public: ListNode* Entr
2021-11-19 14:31:33 765
原创 设计模式 - 装饰器模式
**装饰器模式(Decorator Pattern)**允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。1.介绍1.1.作用动态地给一个对象添加一些额外的职责。1.2.解决扩展一个类经常使用继承方式来实现,由于继承为类引入静态特征,随着功能的增加,子类会膨胀。1.3.使用场景拓展一个类的功能。动态增加功能,动态销毁功能。2
2021-11-16 17:15:00 59
原创 RPC(远程过程调用协议)
RPC(Remote Procedure Call Protocol)——远程过程调用协议,是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。它假定某些传输协议的存在,如TCP或UDP,以便为通信程序之间携带信息数据。通过它可以使函数调用模式网络化。在OSI网络通信模型中,RPC跨越了传输层和应用层。RPC工作原理运行时,一次客户机对服务器的RPC调用,其内部操作大致有如下十步:1.调用客户端句柄;执行传送参数2.调用本地系统内核发送网络消息3.消息传送到远程主机4.服
2021-11-15 18:28:38 2194
原创 分析http包运行机制
如下图所示,是Go实现Web服务的工作模式的流程图创建Listen Socket, 监听指定的端口, 等待客户端请求到来。Listen Socket接受客户端的请求, 得到Client Socket, 接下来通过Client Socket与客户端通信。处理客户端的请求, 首先从Client Socket读取HTTP请求的协议头, 如果是POST方法, 还可能要读取客户端提交的数据, 然后交给相应的handler处理请求, handler处理完毕准备好客户端需要的数据, 通过Client
2021-11-13 18:01:52 146
原创 channels详细使用说明
goroutine运行在相同的地址空间,因此访问共享内存必须做好同步。那么goroutine之间如何进行数据的通信呢,Go提供了一个很好的通信机制channel。channel可以与Unix shell 中的双向管道做类比:可以通过它发送或者接收值。这些值只能是特定的类型:channel类型。定义一个channel时,也需要定义发送到channel的值的类型。注意,必须使用make 创建channel:ci := make(chan int)cs := make(chan string)cf := m
2021-11-13 17:38:07 7000
原创 嵌入struct和嵌入interface
嵌入struct当匿名字段是一个struct的时候,那么这个struct所拥有的全部字段都被隐式地引入了当前定义的这个struct。package mainimport "fmt"type Human struct { name string age int weight int}type Student struct { Human // 匿名字段,那么默认Student就包含了Human的所有字段 speciality string}func
2021-11-13 17:16:08 289
原创 方法的继承和重写
继承如果匿名字段实现了一个method,那么包含这个匿名字段的struct也能调用该method。package mainimport "fmt"type Human struct { name string age int phone string}type Student struct { Human //匿名字段 school string}type Employee struct { Human //匿名字段 company
2021-11-13 16:47:26 327
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人