自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 Mongo使用小tip

针对平时工作中使用mongodb数据库的场景,整理一些关于mongo的使用小技巧,避免踩坑,以下:唯一索引最近业务需要用到mongo的唯一索引,特意去查了下,和mysql的唯一索引类似,都是限制表中的对应字段唯一。和mysql不同的是,mongo存在一个唯一字段_id,他会在创建集合时自动创建,每一个集合中的_id是其对应文档的唯一标示。和唯一索引不同的点在于,_id不能被删除。先说说 _id,默认类型是ObjectID。占用存储空间12字节,它是24个十六进制数字组成的字符串。12字节中前四个字节

2021-01-07 17:40:56 198 1

原创 聊聊golang中的panic和defer

聊聊golang中的panic和defer当数组越界、访问非法空间或者我们直接调用panic时,panic会停掉当前正在执行的程序,包括所有协程,比起exit直接退出,panic的退出更有秩序,他会他会先处理完当前goroutine已经defer挂上去的任务,执行完毕后再退出整个程序。而defer的存在,让我们有更多的选择,比如在defer中通过recover截取panic,从而达到try…catch的效果panic还可以接收一个参数,通常是字符串类型错误信息,执行到panic时,他会打印这个字符串和

2020-06-01 15:41:56 5759 3

原创 Redis分布式锁

Redis的常见使用场景有这么几种:通用缓存计数器(点击量、下载量、pv、uv等)分布式锁这里我们主要谈Redis分布式锁的实现。分布式锁主要是为了解决以下几个问题:互斥性:多个机器不能同时获得锁,同一时刻只有一台机器占有锁安全性:保证加锁和解锁都是同一台机器,不能误释放别人的锁死锁:节点故障,但是一直占有锁未释放,其他节点一直加锁失败容错:一个节点故障,保证其他节点可以释...

2019-08-08 20:32:30 255 1

原创 Golang中的nil

之前在学习C/C++时,我们知道有NULL在C中NULL是一个(void*)的指针,其定义如下:#define NULL ((void *)0)而在C++中,NULL直接可以和0划等号,定义:/* Define NULL pointer value */#ifndef NULL #ifdef __cplusplus #define NULL 0 ...

2019-07-25 15:32:32 2182

原创 取余和取模

之前我的认知里一直以为取余和取模是一回事,直到那天他们在讨论关于这个,才意识到并不是这样,这里进行总结一下。在数学里面,我们接触到的余数都是大于0的,但在编程中,就会存在有正有负的情况。编程中,这两种计算的机制不同,Mod采用fix函数,Rem采用floor函数,这两函数都是用来取整的,fix向0方向舍入,floor向无穷小方向舍入。取模(Mod)和取余 (Rem)我们都是用 " % "来表示...

2019-07-25 10:37:08 1393 2

原创 细说new和delete

C++对C是兼容的,所以C中的动态内存管理机制malloc/free在C++中可以继续使用 为了进行完善,C++也提出了自己的一套内存管理方式:使用new和delete对动态内存进行管理。使用方式: 1.申请单个数据的空间类型名 *p1=new 类型名; //申请delete p1; //释放这里的类型可以是内置类型,也可以是自定义类型如结构体类型、类类型等...

2018-08-20 08:25:22 182

原创 malloc的底层实现原理

首先了解内存分配:一些全局变量、static变量是在编译期间就为他们分配好内存空间的,他们都被放在静态存储区,生命周期随进程。局部变量是在程序运行期间才为他们分配空间,在栈上进行分配,一旦离开该局部作用域,栈上变量即会被销毁,栈上空间有限。程序运行时我们使用malloc/new申请的空间都是在堆上进行分配的,当手动调用free/delete时才会被销毁,它的生命周期由用户来决定。学...

2018-08-19 10:23:00 1939

原创 内联函数和宏

当我们写了一个小函数,函数体只有一两行代码,但是该函数被频繁调用,函数调用有一定的开销,要保存上下文,维护函数栈帧,进行参数拷贝,执行结束还要跳转回去,恢复原现场继续执行等进行一系列工作。为了节省开销,我们首先想到的是使用宏函数来代替,这样确实可以,但是注意宏有很多缺点。宏的概念: 宏定义将一个标识符定义成一个字符串,源程序中的标识符都以字符串进行替换宏的优缺点?? 优点:提高程...

2018-08-19 00:32:52 211

原创 操作符重载

操作符重载的实质是函数重载,C++预定义的操作符的操作对象只能是基本的数据类型,而对于我们用户自定义的类型如类类型也需要类似的运算操作,此时就需要重新定义这些这些运算符,赋予他们新功能,使他在特定的时候执行特定的操作,可以提高代码的可读性。它的一般格式为:返回值类型 oprerator<运算符>(参数列表){ //函数体}并不是所有的运算符都能重载不能...

2018-08-18 19:00:44 359

原创 深拷贝和浅拷贝

定义一个string类,未显式给出它的拷贝构造函数class string{public: string(const char* str="") :_str(new char[strlen(str)+1]) { strcpy(_str,str); } ~string() { if(_str) ...

2018-08-18 18:01:45 240

原创 空类中都有哪些东西

定义一个空类,里面什么内容都没有class A{};想想看,它的大小应该是多少??要计算一个类对象的大小,要知道这么几点:类大小是非静态数据成员的类型大小之和若类中定义了虚函数,需要考虑到虚表指针也占用类对象的内存空间(32位机器下占用四字节)编译器为了提高存取效率,类大小往往会被调整为系统的整数倍,和结构体中的内存对齐类似(结构体内存对齐详情戳这里为什么要进行结构体...

2018-08-18 16:56:25 3430

原创 const关键字

C中的constconst限定一个变量不允许被改变 const修饰的数据类型是指常类型,常类型的变量或对象的值是不能被更新的。 相比于define定义的变量,const变量多了类型检查,使程序更加安全,而define仅仅是简单的文本替换,有时候会出现一些错误。 const可以保护被修饰的内容,防止意外修改,增强程序健壮性。当我们使用const修饰的变量来定义数组大小时,程序会报错...

2018-08-16 19:27:32 142

原创 static关键字

static:在C中我们知道,static作为一个关键字,既能修饰变量,也能修饰函数1.修饰变量若修饰局部变量,会改变他的生命周期,出了它现在所处的作用域,也不会被销毁,因为此时它已经不是存储在栈上,而是存在数据段上,数据段上的内容只有进程结束才会被销毁,但它的作用域不会被改变,还是处于当前作用域,该作用域之外不可见。 注意: 由于static局部变量的特性,使得含有静...

2018-08-16 17:23:48 211

原创 单例模式——C++版

单例模式是什么??单例模式(Singleton)是一种常用的设计模式,它能够保证系统中应用该模式的类只有一个实例。为什么要存在单例模式??在很多场景下,我们都希望一个类只能创建出唯一的对象,例如windows下的任务管理器,我们就只能打开一个。若不使用单例模式,就会在多次打开时弹出多个窗口,重复对象,浪费内存。而且要是多个窗口的状态不一致,也会造成误解。因此保证某个对象只能有一个实...

2018-08-16 14:14:44 132

原创 守护进程

先了解一些基本概念:进程组: 一个或多个进程的集合,如父子进程或者通过管道连接起来的进程等这些都同属一个进程组。进程组id一般都是该进程组的组长id。 进程组中所有进程死亡,进程组才算结束。 ctrl+c 发送信号,发送给的是进程组,组内所有进程都会退出 ctrl+c信号不能发给后台进程作业: 正在执行的进程称为作业,一个作业通常包含一个或多个进程,这几个进程共同完成一项任务...

2018-08-11 13:00:48 424

原创 一个简单小程序

实现这么一个程序: 从磁盘上读取文件,对文件内容解析,解析出两个加数,生成一个可以执行加法运算的动态库,调用该动态库进行加法计算,再将计算结果写入共享内存,然后创建子进程,子进程进行程序替换,替换的程序要完成的任务就是将共享内存中的内容重新写回磁盘上的该文件,记得使用共享内存时要借助信号量保证互斥操作。 具体过程如下图: 代码实现:add.h#ifndef __ADD_H__...

2018-08-11 11:02:36 1021

原创 一些常用命令整理

文件相关readelf: 用来显示一个或者多个elf格式的目标文件的信息 ELF格式的文件: 动态库( 用于和其他共享目标文件或者可重定位文件一起生成elf目标文件或者和执行文件一起创建进程映像) .o 文件(可重定位的ELF格式文件)( 用户和其他目标文件一起创建可执行文件或者共享目标文件) 可执行程序( 用于生成进程映像,载入内存执行,例如编译好的可执行...

2018-08-09 21:59:15 232

原创 竞态条件和sigsupend函数

竞态条件(race condition)是一个在设备或者系统试图同时执行两个操作的时候出现的不希望的状况,但是由于设备和系统的自然特性,为了正确地执行,操作必须按照合适顺序进行。  好比我们在模拟实现sleep()函数时#include <stdio.h>#include <signal.h>#include <unistd.h>void han...

2018-08-09 11:55:59 396

原创 线程池

创建线程比起创建进程确实开销少了很多,若有大量任务,且执行时间都非常短暂,那么频繁创建新线程又很快销毁也十分影响性能。智慧的程序员们就想到了借助线程池来解决这样的问题。线程池中的一堆线程当有任务到来时就去执行,执行结束也不着急销毁,坐等下个任务的到来。这样就省下了一大笔创建销毁过程的开销1.线程池中有若干个线程 2.用于执行大量相对短暂的任务线程池中的线程个数如何确定?对于计算密集...

2018-08-08 16:11:55 113

原创 生产者消费者模型——基于Posix信号量和互斥量

这种方式可以用信号量初值来定义仓库大小,循环生产和消费生产者:while(1){ pthread_mutex_lock(&mutex); sem_wait(&sem_full); 生产 sem_post(&sem_empty); pthread_mutex_unlock(&mutex);}消费者:w...

2018-08-06 09:41:34 189

原创 多线程中的锁机制

由于多线程之间是并发执行的,而系统调度又是随机的,因此在写多线程程序时会出现很多问题,这时就免不了要用到各种锁机制来保证线程安全且按我们的意愿正确执行。互斥锁1.定义一个互斥量pthread_mutex_t mutex;2.初始化互斥量静态分配pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZED动态分配int...

2018-08-04 20:30:49 21133

原创 关于线程

Linux下多线程线程概念:一个程序中的一条执行路线就叫做线程。线程是“一个进程内部的控制序列“。 典型的UNIX可以看成只有一个控制线程:一个进程在同一时刻只做一件事,有了控制线程后,在程序设计时可以把进程设计成在同一时刻做多件事,每个线程处理各自独立的任务。 一个进程至少都有一个线程。操作系统的最小调度单位本质上创建进程和线程时都会调用clone函数 创建新线程和vfor...

2018-08-04 15:03:48 149

原创 生产者消费者问题——基于共享内存和信号量

生产者消费者问题: 通过共享内存和信号量来处理首先我们必须保证在有空间可以放时,生产者才能放数据,有数据可取时,消费者才能取数据。并且二者对这块空间的访问是互斥的 因此需要定义一个互斥信号量sem_mutex。再者,定义信号量sem_full表示可放块数和sem_empty表示可取块数来进行同步。 这就需要将读索引和写索引保存在创建的共享内存头部,另外将数据块大小和数据块个数也一块保...

2018-07-29 15:08:28 1471

原创 哲学家就餐问题

哲学家就餐问题是经典的死锁问题什么是死锁?多个进程或线程相互等待对方的资源,在等到对方资源之前,也不会释放自己的资源,这样造成循环等待的现象,若无外力作用,他们都无法推进下去,这样就产生了死锁。死锁产生的必要条件:互斥性请求并保持不可剥夺循环等待防止死锁的办法:一次性分够(破坏请求并保持的条件)资源可剥夺(破坏不可剥夺条件)资源有序分配(破坏循环等待条件)...

2018-07-28 16:15:28 933

原创 关于进程(僵尸/孤儿)

进程创建:进程创建的一般过程: 1、给新进程分配一个标识符,在内核中分配一个PCB 2、复制父进程的环境 3、分配资源(程序,数据,堆栈等) 4、复制父进程地址空间中的内容(写时拷贝) 5、将进程置成就绪状态,放入就绪队列fork()函数—用来创建一个子进程 #include 上面代码中涉及两个函数: pid_t getpid() //...

2018-07-25 07:38:32 141

原创 TCP协议的两个原则

两大原则———可靠传输和提高效率可靠性:校验和序列号确认应答超时重传连接管理流量控制拥塞控制提高性能:滑动窗口快速重传延迟应答捎带应答确认应答(ACK)机制——可靠传输的核心 在TCP中,当发送端的数据到达接收主机时,接收端主机会立刻返回一个已收到消息的通知。TCP协议把每个字节的数据都进行了编号,即为序列号。 确认序号是指当前确认序号之前的所...

2018-07-23 13:27:10 1407

原创 网络基础---传输层

网络基础—传输层传输层的功能是负责数据从发送端传输到接收端,向他上面的应用层提供通信服务,使两台主机之间的应用进程互相通信,实现点对点的传输。IP协议能够把分组送到目的主机,但这个分组还停留在主机的网络层,未交付给主机的应用进程,从传输层看,通信的真正端点并不是主机而是主机中的进程。即端到端的通信才是应用进程之间的通信。理解复用和分用: 通常,一个主机的多个应用进程会和另一个主机的多...

2018-07-23 00:21:57 289

原创 详解TCP三次握手/四次挥手

详解TCP三次握手/四次挥手连接管理机制: 建立连接是可靠传输的前提,唤起对方的注意客户端与服务器之间没有明确的界限, 谁先发起请求,谁就是客户端三次握手:三次握手的目的是双方确认自己与对方能够正常发送和接收数据,即建立可靠的TCP连接,同时同步双方的序号和确认号并交换TCP窗口大小信息。 三次握手(Three-way Handshake),指在建立TCP连接时,需要通信...

2018-07-22 21:59:03 296

原创 关于HTTP协议

HTTP协议超文本传输协议,纯文本格式。 HTTP是基于TCP/IP协议来传递数据的。HTTP协议工作于客户端-服务器端架构(C/S)上。浏览器作为HTTP客户端通过url向HTTP服务器端即WEB服务器发送请求认识URLUniform Resourse Loctor 即统一资源定位符 URL就是我们平时所说的网址。 http协议默认端口号是80 https默认端口...

2018-07-22 01:19:14 265

原创 网络基础----应用层

网络基础—-应用层应用层为应用程序提供服务并规定应用程序中相关细节。 我们所写的一个个解决实际问题的网络程序,都是在应用层。 应用层决定了向用户提供应用服务时通信的活动。关于协议协议即是一种“约定”,应用层协议即保证一端发送的数据另一端能够正确进行解析常见的应用层协议DNS:域名解析协议(UDP)FTP:文件传送协议(C/S)(TCP)SMTP:简单邮件传输协议(...

2018-07-22 01:15:28 225

原创 软件测试---用例篇

软件测试—用例篇测试用例(Test Case)概念是为了实施测试而向被测试系统提供的一组集合,这组集合包括:测试环境、操作步骤、测试数据、预期结果等要素。好的测试用例是不熟悉业务的人也能根据用例很go准用例表达清楚,无二义性,不能出项“是否”这样的词汇用例可操作性强用例的输入输出明确,一条用例只有一个预期结果用例可维护性好,即可读性好用例对需求的覆盖性高暴露程序bu...

2018-07-21 00:26:43 6418 1

原创 软件测试---基础篇

软件测试—基础篇软件测试的生命周期在不同的开发阶段,测试人员应该做什么:需求阶段:分析需求,得到测试需求计划阶段:根据需求编写测试计划设计阶段:搭建测试用例的框架编码阶段:完善、细化测试用例的同时也是对需求的测试测试阶段:按照测试用例执行,执行率达100%,可按优先级分先后执行,但最终全都要执行。自由测试,探索测试。编写测试报告时要对缺陷进行分析。缺陷分析的目的:1....

2018-07-20 14:18:36 367

原创 Python中的sys模块和os模块

sys模块大多属性描述程序的执行环境,是python中十分重要的基础模块sys.argv:命令行参数,它是一个列表,不存在argc for i in sys.argv: print i 运行结果: test.pysys.platform 获取当前执行环境的平台 print sys.platform 运行结果: li...

2018-07-20 12:25:49 1347

原创 Python的模块和包

模块C/C++中的include仅仅是简单的文本替换,若包含的头文件中有函数定义,一旦头文件重复包含,就存在函数重复定义的问题,因此我们在写头文件时,都要加上#pragma once为我们写代码带来不便1.模块也是对象 对象的三要素:类型 值 id 类型: <type 'module'>python中的内置类型 值:模块名和路径;模块中包含的信息很多,但呈现给我们程序员...

2018-07-20 12:23:13 159

原创 软件测试---概念篇

软件测试—概念篇什么是软件测试概念: 验证软件功能是否满足用户的需求 测试与调试的区别: 目的不同:测试的任务是发现程序中的缺陷;调试的任务是定位并且解决程序中的问题。 参与角色不同:测试主要是由测试人员和开发人员来执行,黑盒测试主要由测试人员完成、单元/集成测试主要是由开发人员执行。调试由开发人员完成。 执行阶段不同:测试贯穿整个软件开发生命周期,调试...

2018-07-18 23:51:57 274

原创 网络模型

网络模型1.网络发展独立模式:计算机之间相互独立互联模式:多台计算机连接在一起,完成数据共享局域网LAN:(Local Area Network)一栋大楼或有限的、狭小的区域内网络,通过交换机和路由器连接在一起。广域网WAN:(Wide Area Network)跨越相距较远的计算机或LAN网络。2.OSI七层模型(开放式系统互连参考模型)应用层:最靠近用户...

2018-07-18 23:20:01 944

原创 IO多路复用之poll

IO多路复用之poll前面我们看到了select有很多的缺点,这里我们再来认识一下poll:函数原型: 这里第一个参数中的fds实际上是一个struct pollfd的数组,数组中的每个元素代表一个文件描述符,下面是poolfd结构体的原型,其中第一个成员表示所要关注的文件描述符,第二个成员表示要关注的就绪事件,第三个成员代表返回的就绪事件。 第二个参数表示这个数组的长度,即要...

2018-07-14 22:01:31 921 1

原创 IO多路复用之epoll

IO多路复用之epoll认识epoll由于poll并没有很大程度的解决select中的缺点,而且还带来了一些额外的开销。在处理大量socket时,select和poll要进行频繁的拷贝和遍历,效率低。所以poll也不建议使用。下面介绍的epoll不会随文件描述符的增多而开销变大,基本上解决了上述问题,被大家广泛使用。函数原型: 创建一个epoll句柄,用来控制和等待大量的文件...

2018-07-14 21:59:30 3331

原创 IO多路复用之select

IO多路复用之select函数原型:#include <sys/select>int select(int nfds,fd_set *readfds,fd_set *writefds, fd_set *exceptfds,struct timeval *timeval);参数解释: 第一个参数nfds表示需要监视的最大文件描述符加一,即后面三...

2018-07-08 09:41:37 598

原创 Linux高级IO

Linux高级IO五种IO模型阻塞IO:内核在准备好数据之前,系统调用会一直等待,直到内核准备好数据,再将数据报从内核拷贝到用户空间,系统调用 才会成功返回。所有的套接字默认都是阻塞方式,如:recvfrom /sendto非阻塞IO:若内核未准备好数据,系统调用会直接返回,并返回EWOULDBLOCK错误码。这就需要程序员反复尝试读写文件描述符,也称这种方式为“轮询”,不足之处正在于...

2018-07-08 09:15:50 672

空空如也

空空如也

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

TA关注的人

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