redis
未读本篇博客我们就来详细介绍Redis中五大数据类型的底层实现。
1、演示数据类型的实现 上篇博客我们在介绍 key 相关命令的时候,介绍了如下命令:
1OBJECT ENCODING key
该命令是用来显示那五大数据类型的底层数据结构。
比如对于 string 数据类型:
我们可以看到实现string数据类型的数据结构有 embstr 以及 int。
再比如 list 数据类型:
这里我们就不做过多的演示了,那么上次出现的 embstr 以及 int 还有 quicklist 是什么数据结构呢?下面我们就来介绍Redis中几种主要的数据结构。
2、简单动态字符串 第一篇文章我们就说过 Redis 是用 C 语言写的,但是对于Redis的字符串,却不是 C 语言中的字符串(即以空字符’\0’结尾的字符数组),它是自己构建了一种名为 简单动态字符串(simple dynamic string,SDS)的抽象类型,并将 SDS 作为 Redis的默认字符串表示。
SDS 定义:
123456789struct sdshdr{ ...
dict,又称字典(dictionary)或映射(map),是集合的一种;这种集合中每个元素都是KV键值对。字典dict在各编程语言中都有体现,面向对象的编程语言如C++、Java中都称其为Map。
Redis的KV存储结构Redis内存数据库,最底层是一个redisDb;
redisDb 整体使用 dict字典 来存储键值对KV;字典中的每一项,使用dictEntry ,代表KV键值;类似于HashMap中的键值对Entry。
why dict/map?dict是一种用于维护key和value映射关系的数据结构,与很多编程语言中的Map类似。为什么dict/map 这么受欢迎呢?因为dict/map实现了key和value的映射,通过key查询value是效率非常高的操作,时间复杂度是O(C),C是常数,在没有冲突/碰撞的情况下,可以达到O(1)。
dict本质上是为了解决算法中的查找问题(Searching),一般查找问题的解法分为两个大类:一个是基于各种平衡树,一个是基于哈希表。
平衡树,如二叉搜索树、红黑树,使用的是“二分思想”;如果需要实 ...
redis
未读源码版本:redis-4.0.1源码位置:
adlist.h : listNode、list数据结构定义。
adlist.c:函数功能实现。
一、adlist简介Redis中的链表叫adlist(A generic doubly linked list implementation 一个通用的双端链表实现),和普通单链表相比,它的方向可以向前或者向后,这是由于数据结构中定义了next和prev两个指针决定的,下面看下它的数据结构实现。
二、数据结构定义123456789101112131415typedef struct listNode { struct listNode *next; //next指针,指向下一个元素 struct listNode *prev; //prev指针,指向上一个元素 void *value; //void *类型的数据域} listNode;typedef struct list { struct listNode *head; ...
Socket编程
目前较为流行的网络编程模型是客户机/服务器通信模式
客户进程向服务器进程发出要求某种服务的请求,服务器进程响应该请求。如图所示,通常,一个服务器进程会同时为多个客户端进程服务,图中服务器进程B1同时为客户进程A1、A2和B2提供服务。
Socket概述
① 所谓Socket通常也称作“套接字”,用于描述IP地址和端口,是一个通信链的句柄。应用程序通常通过“套接字”向网络发出请求或者应答网络请求。
② Socket是连接运行在网络上的两个程序间的双向通信的端点。
③ 网络通讯其实指的就是Socket间的通讯。
④ 通讯的两端都有Socket,数据在两个Socket之间通过IO来进行传输。
套接字socket的类型
(1)流式套接字(SOCK_STREAM)
提供面向连接、可靠的数据传输服务,数据无差错、无重复的发送,且按发送顺序接收(TCP协议)
(2)数据报式套接字(SOCK_DGRAM)
提供无连接服务,数据包以独立包形式发送,不提供无措保证,数据可能丢失,并且接收顺序混乱(UDP协议)
(3)原始套接字(SOCK_RAM)
套接字(so ...
Systemd 是 Linux 系统工具,用来启动守护进程,已成为大多数发行版的标准配置。
本文介绍它的基本用法,分为上下两篇。今天介绍它的主要命令,下一篇介绍如何用于实战。
一、由来历史上,Linux 的启动一直采用init进程。
下面的命令用来启动服务。
12345$ sudo /etc/init.d/apache2 start# 或者$ service apache2 start
这种方法有两个缺点。
一是启动时间长。init进程是串行启动,只有前一个进程启动完,才会启动下一个进程。
二是启动脚本复杂。init进程只是执行启动脚本,不管其他事情。脚本需要自己处理各种情况,这往往使得脚本变得很长。
二、Systemd 概述Systemd 就是为了解决这些问题而诞生的。它的设计目标是,为系统的启动和管理提供一套完整的解决方案。
根据 Linux 惯例,字母d是守护进程(daemon)的缩写。 Systemd 这个名字的含义,就是它要守护整个系统。
(上图为 Systemd 作者 Lennart Poettering)
使用了 Systemd,就不需要再用init了。System ...
上一篇文章,我介绍了 Systemd 的主要命令,今天介绍如何使用它完成一些基本的任务。
一、开机启动对于那些支持 Systemd 的软件,安装的时候,会自动在/usr/lib/systemd/system目录添加一个配置文件。
如果你想让该软件开机启动,就执行下面的命令(以httpd.service为例)。
123$ sudo systemctl enable httpd
上面的命令相当于在/etc/systemd/system目录添加一个符号链接,指向/usr/lib/systemd/system里面的httpd.service文件。
这是因为开机时,Systemd只执行/etc/systemd/system目录里面的配置文件。这也意味着,如果把修改后的配置文件放在该目录,就可以达到覆盖原始配置的效果。
二、启动服务设置开机启动以后,软件并不会立即启动,必须等到下一次开机。如果想现在就运行该软件,那么要执行systemctl start命令。
123$ sudo systemctl start httpd
执行上面的命令以后,有可能启动失败,因此要用systemctl sta ...
8月份的午后,小满睡醒后,我带着她和往常一样来到家附近的小树林玩耍。找到她的好伙伴涵涵,俩孩子开心的在周边你追我赶。我见俩孩子挺开心,就坐在树下和一群老太太们聊天。
约莫半个多小时后,涵涵姥姥说,她俩拾了一块糖分吃了,我一听火就不打一出来,一方面担心糖有问题,另一方面觉得那么大的孩子,捡东西吃,不能被理解。于是,我把小满拉过来,一边问她一边打她屁股,越打越来气。小满也知道自己错了,不像以前那样嚎啕着哭,一直说”以后不这样了,妈妈我错了“。我当时就跟中了邪一样,控制不住一直重复问她,为什么捡糖吃,在家东西别说掉在地上,就是掉沙发上她都会说,我是小孩不能吃。
回到家,我对小满说,说说吧,为什么捡糖吃。她却说,今天累了,明天再谈。感觉不像4岁孩子的说话语气。我说,以后家里再也没有糖了,你也不允许再吃糖。她很硬气的说,不吃就不吃。我越问越没底气,觉得自己已经被小满打败,但是出于一个大人的面子,还得继续坚持下去。把家里的糖及巧克力都丢进了垃圾桶,小满一直在边上哭着说,不吃了,以后都不吃了。以前觉得4岁是知道吃喝玩乐,天真无邪的年纪,但是此刻发现,我错了。看着她那小大人似的的样子,我不停的自我反思 ...
题目: 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
思路: 刚看完题目,感觉挺简单的,就是复制链表嘛,但在实际操作中,出现很多bug,一直提交出错,说“空”。可能就是题目最后那句话的原因把,后面明白,就是重新创建一个链表,然后一个一个复制过来,有两种方法。
一种递归思路,每一次递归都复制一个节点,这样子思路简洁,而且代码短,我用Js实现这个思路提交对了,但是java就不可以,我怀疑牛客网评测系统有问题,我已经发现三个问题了了。
另外一种思路:如下图分析(图从别人那里借来的)
1.首先复制节点,每一次复杂的节点放在原来的节点后面
2、复制随机节点
3、把复制的链表和原来的链表分开
在实现代码的过程中,总是很难写出来,出现很多问题,但是一看上面的图,就懂了。
代码:
js:
12345678910111213141516/*function RandomListNode(x){ this.label ...
在网上学习了一些材料。
这一篇:https://www.zhihu.com/question/30527705
1234567891011121314151617181920212223242526272829303132AVL树:最早的平衡二叉树之一。应用相对其他数据结构比较少。windows对进程地址空间的管理用到了AVL树红黑树:平衡二叉树,广泛用在C++的STL中。map和set都是用红黑树实现的。我们熟悉的STL的map容器底层是RBtree,当然指的不是unordered_map,后者是hash。B/B+树用在磁盘文件组织 数据索引和数据库索引Trie树 字典树,用在统计和排序大量字符串------AVL是一种高度平衡的二叉树,所以通常的结果是,维护这种高度平衡所付出的代价比从中获得的效率收益还大,故而实际的应用不多,更多的地方是用追求局部而不是非常严格整体平衡的红黑树。当然,如果场景中对插入删除不频繁,只是对查找特别有要求,AVL还是优于红黑的。红黑树的应用就很多了,除了上面同学提到的STL,还有epoll在内核中的实现,用红黑树管理事件块nginx中,用红黑树管理tim ...
javagc
未读大纲介绍第一,垃圾回收简介第二,G1介绍第三,G1 Young GC第四, G1 Mix GC第五,调优实践第六,G1相关处理参数第七,总结本文首先简单介绍了垃圾收集的常见方式,然后再分析了G1收集器的收集原理,相比其他垃圾收集器的优势,最后给出了一些调优实践和相关参数列表。
一,垃圾回收简介首先,在了解G1之前,我们需要清楚的知道,垃圾回收是什么?简单的说垃圾回收就是回收内存中不再使用的对象。
垃圾回收的基本步骤
回收的步骤有2步:
查找内存中不再使用的对象
释放这些对象占用的内存
1,查找内存中不再使用的对象
那么问题来了,如何判断哪些对象不再被使用呢?我们也有2个方法:
引用计数法
引用计数法就是如果一个对象没有被任何引用指向,则可视之为垃圾。这种方法的缺点就是不能检测到环的存在。
2.根搜索算法
根搜索算法的基本思路就是通过一系列名为”GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的。
现在我们已经知道如何找出垃圾对象了,如何 ...

