- 博客(145)
- 收藏
- 关注
原创 百度面经(C++)
内推 一面: select & epoll两种机制的具体实现 可以用两个epoll监听同一个描述符吗,有事件发生时,怎么工作 hash怎么解决冲突 一致性hash 路由表的网段怎么存储、查找 segment fault怎么用gdb调试,两个函数循环调用会怎样 static的使用场景,在一个cpp中定义,在另一个cpp可以访问吗?static变量存放在哪里 time_wait和clo
2016-09-26 16:05:56 3797 2
原创 设计一个类
1、设计一个不能被继承的类 1)将构造函数设为私有 此时子类不能访问基类的构造函数,因此创建子类时就会报错(无法访问private成员) class Base_Uninherit{private: Base_Uninherit(){} Base_Uninherit(const Base_Uninherit& rhs){} Base_Uninherit& ope
2016-09-01 19:22:10 1051
原创 二叉树的遍历
二叉树的遍历二叉树的遍历主要分为三种: 1、前序遍历(根–>左–>右) 2、中序遍历(左–>根–>右) 3、后序遍历(左–>右–>根) 其中对于二叉排序树而言,中序遍历的结果是按序增大的 以递归的方式来实现三种遍历非常简单,如果要以非递归的方式实现遍历,那么一般需要栈作为辅助结构1、前序遍历(根–>左–>右)1.1递归void preOrder(TreeNode *ro
2016-08-24 14:56:04 565
转载 一致性哈希
转载自http://blog.csdn.net/tenal09/article/details/6848909摘要本文将会从实际应用场景出发,介绍一致性哈希算法(Consistent Hashing)及其在分布式系统中的应用。首先本文会描述一个在日常开发中经常会遇到的问题场景,借此介绍一致性哈希算法以及这个算法如何解决此问题;接下来会对这个算法进行相对详细的描述,并讨论一些如虚拟节点等与此算法应用
2016-08-18 10:10:50 572
原创 一些面试题收集
1、const的实现机制 const修饰指针时,如果const位于’* ‘的左侧,则const就是用来修饰指针所指向的变量,即指针指向一个常量; 如果const位于’* ‘的右侧,const就是修饰指针本身,即指针本身是常量,指针不能改变。 const的实现机制: 1)const只会在编译期进行检查,而不会有运行期保护。 2)编译器会检查const变量有
2016-08-15 17:14:22 612
原创 操作符重载
操作符重载 有时候,对于某些对象,需要我们自己重新定义对象的操作运算 以复数为例,我们定义了复数的类型之后,然后对复数a和b进行基本数学运算class Complex{public: Complex(int real=0,int virt=0):_real(real),_virt(virt){}private: int _real; int
2016-08-13 16:56:47 405
原创 redis学习笔记(20)---发布与订阅
发布与订阅 redis的发布与订阅功能由以下几个命令实现: 序号命令及描述1SUBSCRIBE 订阅给定的一个或多个频道的信息2PUBLISH 将信息 message 发送到指定的频道 channel3PUBSUB 查看订阅与发布系统状态4PSUBSCRIBE 订阅一个或多个符合给定模式的频道 使用示例 客户端A通过subscribe命令订阅频道“news”,客户端B通过命令pu
2016-05-15 16:43:56 536
原创 redis学习笔记(19)---事务
事务的性质ACID 一般数据库的事务需要满足ACID四条性质: redis事务 为了保持简单,redis事务保证了其中的一致性和隔离性; 不满足原子性和持久性; 1)原子性:redis事务在执行的中途遇到错误,不会回滚,而是继续执行后续命令;(违反原子性) 2)持久性:事务不过是用队列包裹起了一组 Redis 命令,并没有提供任何额外的持久性功能 Redis 事务可以
2016-05-13 16:38:12 486
原创 redis学习笔记(18)---事件
事件 之前在redis学习笔记(12)—server基本流程 中,对redis的事件机制已经进行了简单的介绍。 redis服务器是一个事件驱动程序,server需要处理两类事件: 1)文件事件:如server与client之间的通信 2)时间事件:在特定的时间点执行,如serverCron函数 IO复用机制 redis的IO多路复用的实现都是通过封装select、epoll等I
2016-05-12 20:25:56 840
原创 redis学习笔记(17)---RDB持久化
RDB文件 redis是一个基于内存的数据库,数据库中的所有数据都是保存在内存中的。 当进程退出时,内存中的数据库状态也会全部丢失。为了解决这个问题,redis提供了RDB持久化功能,RDB持久化可以将redis保存在内存中的数据存储到磁盘上,避免数据意外丢失。 通过该文件,可以还原RDB文件生成时的数据库状态。 RDB文件的创建 有两个命令可以生成RDB文件:SAVE和BG
2016-05-12 17:16:59 1121
原创 redis学习笔记(16)---过期键的设置与删除
expires 在之前数据库的结构中可以看到,每一个数据库除了用变量dict来保存所有的key-value对之外,还通过一个expires成员变量来保存所有设置了过期时间的keytypedef struct redisDb { dict *dict; /* 数据库 */ dict *expires; /* 过期键集合 */ ......} redisD
2016-05-11 15:23:45 6009
原创 redis学习笔记(15)---redis数据库
创建数据库 在redis的server端,维护着多个数据库(默认为16个)。 所有的数据库以数组的形式保存在redisServer结构中 struct redisServer { ...... redisDb *db; //数据库数组 int dbnum; //数据库的个数 ...... }; 在initServer()初始化server时,会根据db
2016-05-10 20:25:06 4428 1
转载 redis学习笔记(14)---redis基本命令总结
概述Redis的键值可以使用物种数据类型:字符串,散列表,列表,集合,有序集合。本文详细介绍这五种数据类型的使用方法。本文命令介绍部分只是列举了基本的命令,至于具体的使用示例,可以参考Redis官方文档:Redis命令大全字符串类型字符串是Redis中最基本的数据类型,它能够存储任何类型的字符串,包含二进制数据。可以用于存储邮箱,JSON化的对象,甚至是一张图片,一个字符串允许存储的最大容量为5
2016-05-10 15:11:45 7182
原创 redis学习笔记(13)---列表命令及实现
列表命令Redis中的List对象的类型为REDIS_LIST,是一种双向链表结构,主要支持以下几种命令:LPUSH 向列表左端添加元素,用法:LPUSH key valueRPUSH 向列表右端添加元素,用法:RPUSH key valueLPOP 从列表左端弹出元素,用法:LPOP keyRPOP 从列表右端弹出元素,用法:RPOP keyLLEN 获取列表中元素个数,用法:LLEN keyL
2016-05-10 14:57:18 2237
原创 redis学习笔记(12)---server基本流程
server工作流程 当执行./redis-server后,redis数据库的server端就会启动。 然后就会执行redis.c中的main()函数 其中main()函数中的工作可以主要分为以下几个部分: 1、初始化server端的配置信息—initServerConfig() 2、解析运行时的命令参数,并根据参数进行处理,eg。./redis-server –help
2016-05-09 22:10:34 3868
原创 redis学习笔记(11)---字符串命令及实现
对象类型与编码方式 对于字符串类型的命令,redis数据库会为每个对象创建一个字符串类型(REDIS_STRING)的对象。 对于字符串类型的对象,可以支持三种编码方式:#define REDIS_ENCODING_RAW 0 /* Raw representation */#define REDIS_ENCODING_INT 1 /* Encoded as integ
2016-05-09 16:18:39 2126
原创 redis学习笔记(10)---ubuntu下redis的安装
环境:Ubuntu 3.11.3 版本:redis 3.0.71、Makesudo make1)如果出现错误:jemalloc/jemalloc.h: No such file or directory redis编译时,默认的allocator是jemalloc,而如果系统中没有安装jemalloc就会报错 解决办法是利用MALLOC环境变量设置默认的分配器。sudo make MALL
2016-05-08 16:25:10 630
原创 redis学习笔记(9)---对象robject
robject 之前对redis基本的数据结构分别进行了简单的介绍,包括字符串、链表、哈希表、整数集合、压缩列表、压缩字典等,但是redis并不是直接使用这些数据结构来实现key-value对数据库的,而是基于这些数据结构为每一个对象创建一个对象robject。robject对象再根据数据类型,来选择合适的底层数据结构来存储数据。robject的定义如下: typedef struct redi
2016-05-08 16:10:45 1296
原创 redis学习笔记(8)---微线图sparkline
sparkline 微线图,即用一个一个信息点形成的图,类似于折线图。在表示时延的时候,就可以用微线图的形式来表示。示例: 微线图中的信息点可以有两种形式:”_-`” 和 “_o#” 两种情况最后形成的微线图分别如下所示: 可以看到,用一个一个的信息点,非常形象明了的形成了所需的折线图 sparkline的实现 sparkline中每个信息点的定义为:struc
2016-05-06 15:58:15 2679
原创 redis学习笔记(7)---压缩字典zipmap
zipmap 在hashtable实现中,Redis引入了zipmap数据结构,保证在hashtable刚创建以及元素较少时,用更少的内存来存储,同时对查询的效率也不会受太大的影响。 zipmap利用字符串实现了简单的hash表,来存储少量key-value对。内存布局 zipmap的内存布局如下: 1)zmlen:1个字节 ,记录当前zipmap中key-value对
2016-05-06 10:17:24 3902
原创 redis学习笔记(6)---压缩列表ziplist
ziplist 压缩列表是列表键和哈希键的底层实现之一。 当一个列表键只包含少量表项,并且每个列表项要么是小整数,要么是较短的字符串 ,那么redis就会使用压缩列表来作为列表键的底层实现。 当一个哈希键只包含少量key-value对,且每个key-value对的key和value要么是小整数,要么是较短字符串,那么redis就会使用ziplist作为哈希键的底层实现。 ziplist
2016-05-05 11:21:34 7337
原创 redis学习笔记(5)---整数集合intset
intset 当一个集合中只包含整数,且这个集合中的元素数量不多时,redis就会使用整数集合intset作为集合的底层实现。整数集合的实现typedef struct intset { uint32_t encoding; uint32_t length; int8_t contents[];} intset;encoding:当前整数集合的编码方式length:集
2016-05-04 20:07:03 1325
原创 redis学习笔记(4)---跳表zskiplist
跳表 跳表(skiplist)是一种有序的数据结构,它通过在每个节点中维护多个指向其它节点的指针,来达到快速访问的目的。 跳表查找的时间复杂度平均为O(lgn),最坏情况下退化为单链表的O(n)。在大部分情况下,跳表的效率可以和平衡树相媲美,但是由于跳表的实现更加简单,因此很多地方用跳表来代替平衡树。redis使用跳表作为有序集合键的底层实现。 跳表的定义在redis.h中 节
2016-05-04 19:05:27 2321
原创 redis学习笔记(3)---字典dict
字典dict redis中的字典,即hash表,其实现与Java中的HashMap基本类似。同样是基于数组和链表的,通过“拉链法”来处理碰撞。 字典中的每一个key都是独一无二的,当要加入一个key-value对时,如果key在字典中已经存在,则会直接返回,而不会重新将其加入到字典中。字典的实现 hash节点的定义如下: typedef struct dictEntry { vo
2016-05-04 16:29:09 2412
原创 redis学习笔记(2)---链表adlist
adlist redis通过prev、next指针实现了双向链表adlist,并通过void*指向数据,用来实现泛型。 与list相关的命令主要有:LPOP,LPUSH,RPOP,RPUSH,LLEN 定义typedef struct listNode { //链表节点 struct listNode *prev; struct listNode *next;
2016-05-03 20:03:09 497
原创 redis学习笔记(1)---字符串sds
字符串 在C语言中,字符串通常有以下两种方式来表示:char *buf1="redis";char buf2[]="redis"; buf1是通过一个char指针指向一个字符串字面量,其内容是不能改变的,即不能使用buf1[3]=’c’;这种方式来改变字符串中的某个字符,要改变字符串内容只能通过给buf1指针重新赋值,因此不能重用buf1指向的内存空间。 buf2是一个char数组,末尾
2016-05-03 19:13:31 1001
转载 硬盘的读写原理
转载自:http://blog.csdn.net/hguisu/article/details/7408047 硬盘的种类主要是SCSI 、IDE 、以及现在流行的SATA等;任何一种硬盘的生产都要一定的标准;随着相应的标准的升级,硬盘生产技术也在升级;比如 SCSI标准已经经历了SCSI-1 、SCSI-2、SCSI-3;其中目前咱们经常在服务器网站看到的 Ultral-1
2016-04-29 09:56:10 815
原创 B树
常见的动态查找树有:二叉查找树(BST)、平衡二叉查找树(AVL)、红黑树(RB-Tree)、B-tree/B+-tree。 由于前面三种树都属于二叉树,因此树的高度为(log2N)。树查找的时间复杂度与树的高度有关,因此要提高查找效率必须要降低树的高度,所以我们可以想到多叉树。 B树、B+树都是基于多叉树实现的。磁盘读取 (参考http://blog.csdn.net/v_july_
2016-04-26 18:48:47 8698 1
原创 哈希表
哈希表 哈希表是根据关键码(key)直接进行访问的数据结构。通过将key通过特定映射函数映射到某一位置直接存储、访问。 哈希表查找的时间复杂度最好时可以为O(1)。在最坏情况下,哈希表会退化为单链表,此时时间复杂度为O(n)。若关键字为k,则其值存放在f(k)的存储位置上,称这个对应关系f为散列函数对不同的关键字可能得到同一散列地址,即k1≠k2,而f(k1)=f(k2),这种现象称为碰
2016-04-25 15:50:35 693
原创 堆和堆排序
堆 二叉堆是一种基于数组的数据结构。它可以被视为一棵完全二叉树。 二叉堆可以分为大根堆和小根堆,大根堆是指父节点的key总是大于或等于任何一个子节点的key,因此堆的根节点为最大值。而小根堆则相反,因此小根堆的根节点为所有元素中的最小值。 二叉堆必须满足两个特性: 1)父结点的键值总是大于或等于(小于或等于)任何一个子节点的键值 2)每个结点的左子树和右子树都是一个二叉堆(
2016-04-25 14:40:27 817
转载 C++内存管理
转载自:http://blog.csdn.net/zhanghefu/article/details/5003407C++内存管理 [导语]内存管理是C++最令人切齿痛恨的问题,也是C++最有争议的问题,C++高手从中获得了更好的性能,更大的自由,C++菜鸟的收获则是一遍一遍的检查代码和对C++的痛恨,但内存管理在C++中无处不在,内存泄漏几乎在每个C++程序中都会发生,因此要想成为C++高手,内
2016-04-22 15:47:00 533
原创 C++的多态
C++多态 多态,对同一个接口有多种实现方式,即“一个接口,多种实现”, C++有两种实现多态的方法: 1)编译时多态:通过函数重载实现 2)运行时多态:通过虚函数实现编译时多态: C++同一范围中声明几个功能类似的同名函数,然后在调用时根据传入的参数选择合适的函数。 重载的函数必须满足## 函数名相同、函数的形式参数(指参数的个数、类型或者顺序)不同 如果两个函数
2016-04-22 14:11:28 375
原创 C、C++中的关键字总结
一、C语言的关键字 共有32个1 数据类型关键字(12个): char double enum float int long short signed struct union unsigned void 2控制语句关键字(12个): 循环语句 :for do while break continue 条件语句 :if else goto 开关语句 :sw
2016-04-21 20:42:59 1015
原创 TCP相关面试题总结
TCP建立连接过程 wireshark抓包为:(wireshark会将seq序号和ACK自动显示为相对值) 1)主机A发送标志syn=1,随机产生seq =1234567的数据包到服务器,主机B由syn=1知道,A要求建立连接; 2)主机B收到请求后要确认连接信息,向A发送ack =(主机A的seq+1),标志syn=1,ack=1,随机产生seq=
2016-04-19 19:03:08 15828
原创 常见锁的区别及适用场景
互斥锁:mutex,用于保证在任何时刻,都只能有一个线程访问该对象。当获取锁操作失败时,线程会进入睡眠,等待锁释放时被唤醒自旋锁:spinlock,在任何时刻同样只能有一个线程访问对象。但是当获取锁操作失败时,不会进入睡眠,而是会在原地自旋,直到锁被释放。这样节省了线程从睡眠状态到被唤醒期间的消耗,在加锁时间短暂的环境下会极大的提高效率。但如果加锁时间过长,则会非常浪费CPU资源读写锁:rwlock
2016-04-19 10:31:00 8847
原创 redis服务器模型
redis作为一个数据库,其服务端必须支持海量客户并发,因此必须采用尽可能高效的服务器模型。 redis支持多种IO复用方式,如kqueue、evport、select、epoll。当运行在不同的操作系统上,会选择最合适的IO复用方式。 redis将这些IO复用的调用接口都封装成了统一的接口,当使用时,每次只需要调用统一的接口,程序会根据不同的运行环境选择最合适的底层复用方式。 下
2016-04-18 20:43:10 1594
原创 select & epoll
同步、异步、阻塞和非阻塞区别 同步:发出一个功能调用时,在没有得到结果之前,该调用就不返回 异步:当一个异步过程调用发出后,调用者不能立刻得到结果。实际处理这个调用的部件在完成后,通过状态、通知和回调来通知调用者 阻塞:阻塞调用是指调用结果返回之前,当前线程会被挂起。函数只有在得到结果之后才会返回 非阻塞:不能立刻得到结果之前,该函数不会阻塞当前线程,而会立刻返回
2016-04-18 17:12:14 2566
转载 多进程&多线程
原文:http://blog.csdn.net/lishenglong666/article/details/8557215 最原始的博主我没有找到,只能把我从何处转的此篇博文的链接发出来。感觉这篇博文写的很棒,特此转载了 进程、线程有哪些区别1)进程是资源分配的最小单位,同一进程中的线程共享进程的资源,如全局变量 2)线程是调度的基本单位 3)一个进程可以有多个线程 4)进程之间是相互独立
2016-04-17 15:57:33 486
原创 gdb的工作原理
一、gdb简介 gdb:GNU debugger UNIX及UNIX-like下一个强大的命令行的调试工具 gdb调试的整体架构如下图所示: 可以发现gdb调试不管是本地调试还是远程调试,都是基于ptrace系统调用来实现的 ptrace系统调用的原型: 二、ptracelong ptrace(enum __ptrace_request request
2016-04-15 11:03:09 18640 1
转载 如何实现一个malloc
[转] malloc基本实现 <div class="postBody"> <div id="cnblogs_post_body"><p>任何一个用过或学过C的人对malloc都不会陌生。大家都知道malloc可以分配一段连续的内存空间,并且在不再使用时可以通过free释放掉。但是,许多程序员对malloc背后的事情并不熟悉,许多人甚至把ma
2016-04-15 09:21:57 532
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人