- 博客(44)
- 收藏
- 关注

原创 Redis对象类型与编码
Redis中常见的类型有string (字符串)list (列表)set (集合)zset (有序集合)hash (哈希)而他们的底层实现都是由其他的数据结构实现接下来就会按照这个表来依次讲解底层数据结构的实现
2021-11-12 16:54:51
1066
原创 docker commit 发布自己的镜像
1. docker images 的分层首先我们需要理解的是docker images的分层原理可能你看完这个还不太理解什么是分层, 不知道你是否有注意到当我们docker pull 一个image的时候, 他是一层一层的下载的所以从这个就可以看出第一层我们已经有了, 可能是centos的基本文件命令,因为我们的redis要基于一个linux系统, 我们就不需要再去下载了. 直接进行层级复用即可, 这样就快很多并且下载的文件体积也小很多这是第一个原因为什么docker快第二个原因就是拿VM和d
2022-03-13 16:34:11
1807
原创 docker学习路程之部署一个nginx
docker 小练习将之前学过的docker命令来进行练习docker 安装 nginx# 首先搜索nginx是否在dockerHub里面存在# 也可以去官方hub.docker搜索nginx更加详细1. docker search nginx # 不带版本号就默认拉取最新的镜像image2. docker pull nginx # docker images 看一下目前的镜像信息3. docker imagesok 现在就已经拉取镜像成功# 现在就可以启动一个nginx
2022-03-12 20:29:38
4024
原创 Mysql索引
1. 索引(index)索引本质上好比书的目录, 其作用就是如其名加快查找的速率我们想要查询id为3的学生记录, 如果没有索引,那么我们需要遍历整个表, 相当于顺序查找, 那么时间复杂度是O(N). 这对于关系型数据库来说是致命如果我们建立索引, 直接能查找到 id=3 的学生的信息在哪里, 那么就能很快的查询到数据这里说明一下在mysql中索引是存储在内存中的, 实际的记录是存储在磁盘中的. 我们查询记录是根据索引去查询然后再在磁盘中快速的找到位置.2. 索引适合的数据结构我们先说一下一般的
2022-01-04 13:47:25
1180
2
原创 Go语言垃圾回收(GC)
1. Go V1.3之前的标记清除(mark and sweep)1. 1 标记清除法的基本流程第一步 : STW(stop the world)暂停所有的程序业务逻辑, 找出可达对象和不可达对象(程序调用对象)第二步 : 开始标记, 程序找出他所有的可达对象并进行标记第三步 : 清除所有不可达对象, 就是未标记的对象第四步 : 停止暂停, 让程序继续跑, 然后重复这个过程, 直到程序结束1. 2 标记清除的缺点STW, 会让程序变慢标机过程需要将全部的堆栈进行一遍扫描来确定是不是可
2021-12-25 17:32:45
612
原创 Go中线程和协程的区别
1. 协程是什么 ?在go语言中n,协程被认为是轻量级的线程, 和线程不同的是,操作系统内核感知不到协程的存在, 协程的管理依赖于Go语言运行时自身提供的调度器同时Go语言中的协程是从属于某一个线程的.在这里提出一个问题 : **为什么Go语言需要在线程的基础上抽象出协程的概念, 而不是直接操作线程 ? **回答这个问题就需要深入的了解线程与协程的区别1. 调度方式协程是用户态的。协程的管理依赖Go语言运行时的调度器。同时,Go语言中的协程是从属于某一个线程的,协程与线程的对应关系为M:N
2021-12-23 11:08:27
3325
4
原创 Go语言defer详解
1. 使用defer的优势defer一般用于资源的释放和异常的捕捉, 作为Go语言的特性之一.defer 语句会将其后面跟随的语句进行延迟处理. 意思就是说 跟在defer后面的语言 将会在程序进行最后的return之后再执行.在 defer 归属的函数即将返回时,将延迟处理的语句按 defer 的逆序进行执行,也就是说,先被 defer 的语句最后被执行,最后被 defer 的语句,最先被执行。1.1 资源的释放一般我们写读取文件的代码如下func CopyFile(dstName, srcN
2021-12-19 16:40:44
16257
原创 Go中的Map实现机制
Map大合集1. 原理2. 哈希冲突1. 原理Go中的map原理是 :将多个键 / 值 (key / value)对分散的存储在hashBuckets(哈希桶)中给定一个键, 通过特定的哈希算法会计算出键值对的哈希值, 然后再用哈希值 % array_size, 就得了对应的存储下标 indexhash表:哈希值会确定其键应该映射到哪一个桶。而一个好的哈希函数,应当尽量少的出现哈希冲突,以此保证操作哈希表的时间复杂度2. 哈希冲突哈希函数在实际中遇到的最常见的问题就是哈希碰撞, 即不同的键通过
2021-12-17 16:53:34
728
1
原创 Go中切片扩容原理
废话不多说直接看源码// src/runtime/slice.gofunc growslice(et *_type, old slice, cap int) slice {// ...省略部分 newcap := old.cap doublecap := newcap + newcap if cap > doublecap { newcap = cap } else { if old.len < 1024 {
2021-12-16 21:08:16
1143
1
原创 从浏览器输入URL到最终看到页面, 这其中经历了哪些过程 ?
从网络原理来看1. URL解析2. 构造http请求3. 构造完http请求就需要将数据传给传输层了4. 网络层5. 数据链路层6.物理层7. 路由器8. 到达服务器的物理层9. 解析成二进制数据10. 服务器的数据链路层11. 服务器的网络层12. 服务器的传输层13. 服务器的应用层14. 重复上述操作15. 总图解1. URL解析从浏览器输入URL, 浏览器需要先解析URL, 并在DNS上查询此url对应的ip地址2. 构造http请求解析完之后, 浏览器就需要构造一个GET请求, 并将携带的
2021-12-12 18:23:54
4524
1
原创 IP报文字段
ip报文字段4位版本号4位首部长度8位服务类型16位总长度16位标识, 3位标志, 13位片偏移8位生存时间TTL4位版本号代表是ipv4, 还是ipv6协议4位首部长度代表ip的报文头部长度, 变长的8位服务类型就是代表这个ip更注重于什么要求16位总长度ip报文的总长度, 最大为2的16次方为64K, 和UDP一样最大长度为64K但是他们两个有个区别是, UDP不支持自动的拆包和组包想要实现需要用户自己在应用层实现. 但是ip协议, 支持自动的拆包和组包下面要介绍的三个字段则
2021-12-11 15:47:52
3444
原创 简谈Redis的线程模型
Redis线程模型Redis真的是单线程的吗 ?为什么说Redis单线程速度这么快?IO多路复用Redis真的是单线程的吗 ?Redis的单线程主要是指处理网络IO请求和键值对的读写是单线程的,其他的操作比如持久化, 集群数据同步等, 则是依赖多线程来处理的为什么说Redis单线程速度这么快?单线程的优势Redis是基于内存的Nosql数据库, 绝大部分网络请求在内存上完成, 速度快.Redis使用了单线程, 避免了多线程的资源切换或者竞争.使用IO多路复用模型, 使其在IO网络操作中能并
2021-11-21 17:13:28
475
原创 Redis之跳跃表(面试重点容易考)
跳跃表1. 跳跃表的用处2. 跳跃表的实现1. 跳跃表的用处有序集合的底层可以采用数组, 链表, 平衡树等结果来实现, 但是他们都有各自的缺点 . 数组方便查询, 但不便于插入和删除, 链表方便插入和删除, 但是不利于查找, 平衡树/红黑树效率高但是实现起来很复杂所以Redis自己实现了跳跃表来来当做有序集合(zset)的底层实现, 他的查询复杂度平均O(logN), 最坏O(N), 堪比红黑树, 但实现起来远比红黑树简单2. 跳跃表的实现我们先来看一下如果用有序链表来实现有序集合插入和删
2021-11-19 10:16:41
2705
1
原创 Redis之快速链表(quicklist)
quicklist什么是快速链表快速链表结构什么是快速链表快速链表是Redis3.2之后引入的一种数据类型, 该结构它是由链表和压缩链表结合起来的一种结构, 即是一个双向链表, 并且链表中的每一个节点是一个压缩链表. 这样的设计能在时间效率和空间效率上实现较好的折中在3.2之前列表是用, 双向链表或者压缩链表来实现的, 到了3.2之后, 列表底层就全用快速链表来实现了快速链表结构typedef struct quicklist { //指向头部(最左边)quicklist节点的指针
2021-11-17 17:17:11
1732
原创 Redis之压缩链表ziplist
ziplist什么是ziplist?ziplist结构entry节点的结构添加或者删除引起的连锁更新什么是ziplist?顾名思义ziplist就是压缩链表, 压缩链表就是为节省内存而生的因为Redis是基于内存的数据库, 所以读取或者写入的速度很快, 但由于内存资源有限, 所以我们要尽可能的节约内存, 于是Redis官方就创建出了ziplist这一节省内存的结构ziplist结构下面我们来看一下ziplist的结构zlbytes: ziplist的长度(单位: 字节),是一个32位无符号整
2021-11-16 16:41:37
1549
原创 Redis之链表
链表linkedlist链表在Redis中的作用链表节点链表结构链表示意图总结 : 链表的特点linkedlist是一种有序的数据结构, 并且增加和删除效率高,C语言没有实现这种结果,所以Redis自己实现了这种结构链表在Redis中的作用在Redis3.0之前中list底层可以用linkedlist来实现(数据少和小), 也可以用ziplist(数据大或者多)实现在Redis3.0之后, list多用linkedlist和ziplist一起来实现, 叫quicklist(之后的章节会讲)链表
2021-11-16 10:53:05
946
原创 Redis之字典(hashtable)
Redis之字典字典是什么(hashtable)总体结构dictdictht(散列表)dictEntry如何解决哈希冲突1. 链表法2.rehash法字典是什么(hashtable)简单来说就是Redis中hash数据结构的底层实现当数据小, 并且数量不多的时候会用ziplist来实现hash结构总体结构这里先给出大体的结构, 便于理解dict字典底层又是由dict实现的, 下图是dict的结构typedef struct dict{ //类型特定函数
2021-11-15 22:11:40
2222
3
原创 Redis基本数据的的常见命令操作
Redis基本命令操作1.redis的5种常用数据类型:2. string字符串3.list列表4.hash哈希5.set集合6. sorted set (Zset)有序集合1.redis的5种常用数据类型:string 字符串(可以为整形、浮点型和字符串,统称为元素)list 列表(实现队列,元素不唯一,先入先出原则)hash hash散列表(hash的key必须是唯一的)set 集合(各不相同的元素)sort set 有序集合也叫zset各种操作命令可以在redis官网查到点击comma
2021-11-14 17:14:27
1537
原创 Redis之intset(整数集合)
Redis中set数据结构它是由intset或者hashtable构成的今天我们就来讲一下intset整数集合(intset)呢, 是一个有序的存储数据的结构它有以下优点1.整数集合中, 元素按照值的大小由小到大排列;2.可以保存int16_t, int32_t, int64_t类型的数据3.存储数据时, 可以保证其内部不出现重复的数据当一个set只包含整数元素, 并且元素不多的时候, Redis就可能使用intset来实现setintset底层实现typedef struct ints
2021-11-12 19:52:27
1491
原创 Redis简单动态字符串
简单动态字符串Simple Dynamic String是Redis内部自己定义的一种数据类型在Redis内部, 任何包含字符串的键值对都是由SDS实现的SDS还被用于缓冲区, 比如AOF缓冲区.比如以下几个命令// 设置text为key, "hello world"为value, 两者都为字符串所以都是由SDS实现set text "hello world" // 建立一个列表从右端插入, names为key, value即为"john" "lucy"rpush names "john
2021-11-12 17:03:59
972
原创 排序算法(上)
排序算法1.插入排序2. 希尔排序3. 选择排序4 .堆排序1.插入排序func insertSort(arr []int) { // 将数组分为已经排序好的区间[0, bound), 和未排序好的区间[bound,length] for i := 0; i < len(arr); i++ { end := i-1 cur := arr[i] // 如果遇到了比cur大的元素就需要往后搬 for end >= 0 && arr[en
2021-11-12 09:33:15
94
2
原创 List有关知识与ArrayList的实现
1. 各种集合类之间的关系1.可以看出List接口继承自Collection接口, Collection接口又继承自Iterable接口,即实现了迭代器的功能(遍历方式可用)2.ArrayList和LinkedList都继承自AbstractList, 并且实现了List接口所以现在我们来看一下ArrayList的常用方法2. ArrayList的框架图首先我们来看一下ArrayList的具体框架图1 实现了RandomAccessRandomAccess 是一个标记接口,用于标明实
2021-10-17 19:33:17
183
原创 使用gin和gorm框架完成的bubble小清单项目
bubble小项目bubble小清单项目1. 使用gin框架来做服务端,回应浏览器发送的请求1.gin.Default() 启动一个默认的路由1.前端页面需要加载静态文件2.静态文件加载地址3.处理浏览器发送的GET访问请求4. 定义一个路由组来处理浏览器发送的各种请求2.controller文件包含处理浏览器发送的各种请求1.controller.BubbleHandle2. controller.CreateTodo3. controller.LookTodoList4. controller.Upd
2021-09-26 17:44:47
438
原创 剑指offer 11. 旋转数组的最小数字(很详细!)
剑指offer 11. 选择数组的最小数字题目解题思路代码题目解题思路一开始,我们就能直接想到,数组找最小值,那么不轻轻松松直接遍历一遍,用一个变量记录最小值,然后直接返回不就完事了?但是这样做真的不优雅!!!,因为题目已经说了是一个旋转的数组,直接遍历暴力,那么题目还要说旋转干嘛呢?所以这里我们需要具体分析一下可以包含重复元素的数组旋转过后会是什么情况旋转过后基本上是这种图案:最小值大概位于中间位置(这里偷点懒直接用了力扣官方的图片,懒得画图了????)注意到,旋转数组中的最后一个值x,
2021-08-19 23:30:39
178
原创 剑指 Offer 09. 用两个栈实现队列
剑指 Offer 09. 用两个栈实现队列解题思路函数设计代码题目:用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )解题思路这里的栈我们使用两个切片来实现即可如果使用两个栈来实现队列栈无法实现队列的功能: 将栈底元素(最先加入的元素)弹出,需要先将上方所有元素先弹出这里我们就可以利用双栈来实现队列的功能:假设我们需
2021-08-17 22:34:04
107
2
原创 java 中 a = a++ 的分析
下面我们来看一段代码 public static void main(String[] args) { int ret = 1; int a = 10; ret = a++; a = a++; System.out.println(ret); System.out.println(a); }大家可以估计一下输出的值是不是 ret = 10 , a = 12 ?但其实不是的 ret = 10 ,a = 11
2021-08-15 10:31:22
675
原创 剑指offer06.从尾到头打印链表
剑指offer06.从尾到头打印链表1. 改变链表结构的解法2.可以使用栈,递归,或者直接反向输出数组提示:若是面试遇到此题,最好先向面试官确认是否可以改变链表的结构,1. 改变链表结构的解法我们可以想到,先反转链表然后在一个一个的输出不熟悉反转链表的建议先去看一下反转链表反转链表的经典四句t = pre.Nextpre.Next = curcur = prepre = t func reversePrint(head *ListNode) []int {// 反转链表然后再输出数
2021-08-08 22:02:37
82
1
原创 剑指offer03.数组中重复的数字
剑指offer03.数组中重复的数字题目第一种解法第二种解法第三种解法值得一提的东西题目在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。示例 1:输入: [2, 3, 1, 0, 2, 5, 3]输出:2 或 3第一种解法一个简单的暴力方法就是先把输入的数组排序.从排序的数组中找出重复的数字是一件容易的事情,只需要判断一个数字的下一个数字是否与本身相等即可
2021-08-07 23:26:40
112
原创 超详细C语言的字符串函数讲解
字符串函数前言C语言中对字符和字符串的处理很是频繁,但是C语言本身是没有字符串类型的,字符串通常放在常量字符串中或者字符数组中。字符串常量 适用于那些对它不做修改的字符串函数接下来本文就是对于介绍一些常用的字符串函数进行讲解所有字符串相关的函数都放在string.h的头文件中1. strlensize_t strlen ( const char * str ) ;字符串是以’\0’结尾的,那么strlen就是返回\0之前的字符个数size_t是定义的一个宏,本质上是一个 unsigne
2021-06-14 17:59:15
631
7
原创 C语言函数指针
C语言中函数指针的作用1.如何定义一个函数指针类型: void(*)() void代表没有返回值,第二个括号代表要填的参数typedef int(*Cmp)(int x ,int y);这里使用typedef定义了一个比较函数类型Cmpvoid test(int x,int y){ printf("蟹薄肉");}int main(){ void(*ptr)(int ,int) = test;}这里的ptr就是test函数的指针2.当做转移表实现一个简单计算器(使用通用代码)#
2021-06-05 10:22:41
320
7
原创 总结
C语言整数如何在内存中存储1.字节序分为:大端序和小端序两种大端序:高位放在低地址上小端序:地位放在低地址上(小小小)假设int x = 0x11223344;那么44对于11就是低地址若是大端序则在内存中可以看到是11 22 33 44 排列若是小端序则在内存中可以看到是44 33 22 11 排列2.如何写一个代码检测主机是大端序还是小端序#include<stdio.h>#include<stdlib.h>// 判断机器是大端序还是小端序void is
2021-05-25 11:12:58
73
原创 windows经典地雷小游戏(C语言实现)
地雷小游戏实现游戏的流程1.如何使用C语言表示双重身份的地雷图2.打印一下showMap3.让玩家输入坐标(row,col)4.判断玩家是否踩雷5.更新地图6.如何判断玩家获胜代码区域实现游戏的流程1.如何使用C语言表示双重身份的地雷图我们可以使用一个showMap 并将它全部初始化为 * 并且每打印9个就换行来表示对外显示的效果再使用一个mineMap表示地雷地图2.打印一下showMap使用memset函数来直接赋初值 memset包含在string.h头文件中memset(showMa
2021-04-27 15:56:02
377
原创 C语言三字棋小游戏
C语言三字棋小游戏开始做之前先想好写程序的大致流程:注意这里的数组大小可以定义为宏方便更改如果我们写成3和3这种那么如果我们想要改棋盘大小那么就非常麻烦如果直接定义为宏 那么直接可以在定义宏里面修改数值即可#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<stdlib.h>#define MAX_ROW 3#define MAX_COL 3void init(char arr[MAX_ROW][M
2021-04-25 11:00:14
221
2
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人