11 2021 档案
摘要:LRU是什么 我们知道内存中的读写速度很快,基于此很多缓存技术都喜欢将数据存在内存中,但是内存空间是有限的,到达一定量后必然需要将一些不常用的缓存数据删除或者落盘。于是顺应而生了很多缓存淘汰算法。其中比较常见的有FIFO、LFU、LRU、LRU-k、2Q算法等等...其目的都是为了高效的维护缓存数据
阅读全文
摘要:对于通知一个goroutine结束它的工作,遵循goroutine之间通过管道传递消息的设计理念,我们可以使用channel传递一个信号,当goroutine检测到信号,结束工作即可: var wg sync.WaitGroup func work(exit <-chan struct{}) { L
阅读全文
摘要:参考:mooc浙大数据结构 https://www.icourse163.org/learn/ZJU-93001?tid=1459700443#/learn/content?type=detail&id=1235254085&cid=1254945340 kmp算法的本质是: 1、当指针 i 指向的
阅读全文
摘要:名词解释 单调栈和单调队列都有共同的特性,单调性。所谓单调性就是在一段区间上,这段区间的数是线性递增的,或者线性递减的。栈和队列中一直维护一串单调的数字,那么这个栈和队列就叫做单调栈和单调队列, 可以解决的问题 一般单调栈解决的是,在一串数字中,求第i个数的左边第一个比它小的数。(当然问题不是绝对的
阅读全文
摘要:前两天在小破站看到zinx框架的教程,于是跟着学了学,实现完了换了个名叫 Kinx hhhhh~。有意愿的可以star一波~ https://github.com/k-si/Kinx 附一张整体架构图: 设计思想 tcp通信在代码层面上是非常简单的,因为几乎所有的语言都提供了套接字,套接字就是对底层
阅读全文
摘要:golang中单例模式体现在很多地方, 比如init函数,当包被导入的时候只会被执行一次。实现单例模式有很多种方式,这里给出几种简单的实现: 互斥锁 对全局共享变量加锁,如果该变量不是nil,那么证明已经被创建了实例,直接返回它的值就好。 type singleton struct {} var (
阅读全文
摘要:slice扩容代码在go/src/runtime/slice.go中,当前使用的使用的golang源码是GitHub中的master分支代码。时间是2021-10-11。 先抛出一个问题,你觉得应该是打印多少呢? var b = []int64{1, 1} b = append(b, 1, 1, 1
阅读全文
摘要:对齐规则 1、对于结构体成员变量: 某个成员的偏移量 = k * min(编译器对齐系数, 该成员类型长度) k >= 1 2、结构体完整大小也必须满足: min(k * max(编译器对齐系数, 最大成员类型长度)) k >= 1 编译器默认对齐长度和计算机一次处理的的位数有关,32位处理器对齐系
阅读全文
摘要:逃逸分析 我们知道往往声明一个变量或者申请内存空间时,是需要区分内存区域的,有的可以申请栈空间,有的申请堆空间。go语言中决定变量是分配到栈还是堆,取决于go编译器对程序的逃逸分析。 在程序编译时,如果发现一个变量需要后续一直使用,往往会将其分配到堆内存。看例子: func test02() *in
阅读全文
摘要:我们都知道go语言起一个线程是很简单的,但这其中也有很多问题(坑)。我在刚了解到并发时,常会思考以这样的方式达到两个线程之间的同步: var a string var done bool func setUp() { a = "hello world" done = true } func main
阅读全文
摘要:动态和静态的区别 链表分静态链表和动态链表,工程里一般用动态链表,去new一个node,动态创建节点。静态链表一般用在刷算法题的时候,由于使用数组模拟,没有动态创建过程,并且使用数组下标代替next指针,所以静态链表的速度非常快,缺点就是非常消耗内存。 静态链表的结构 两个数组 静态链表中使用两个数
阅读全文
摘要:简谈mr mr的出现就是因为单机无法处理过多的任务,需要多加几台机器来提高性能,那么就要处理多台机器的分工合作问题。拿word-count举例,将任务均分到集群中的每台机器,各自运算得出结果,再将结果收集进行合并,这个过程就是mapreduce。 分布式的机器处理时是并行的,互相不影响,对比单机能提
阅读全文
摘要:计算机中存储数字,是存储数字的补码,其中正数的补码是它本身,负数的补码是原码取反再加一。 计算机没有减法操作,所以 x + (-x) = 0,所以 -x = 0 - x,计算机中计算二进制0 - x,一样需要借位,计算的结果就是 ~x + 1,所以计算机存负数存的是 ~x + 1。 求x的第k位,k
阅读全文
摘要:合并区间顾名思义,就是有两个区间a, b。区间a的范围是[1, 5],区间b的范围是[2, 7],那么将a和b合并之后的区间就是[1, 7]。 题目:现给出n个区间,求这n个区间合并后最终成为几个区间。 步骤: 将n个pair排序。 维护一个现有的区间,比较下一个区间能否合并进来,如果能合并进来就更
阅读全文
摘要:假设在一段数轴上,存在n个有用的数字,其余数字是0,这n个数字是非常稀疏的,两两之间间隔很远。那么对这n个有用的数字求区间和,需要开辟的前缀和数组将非常大,可能达到10^9。所以我们需要将这n个有用的数字紧凑起来,将原来的位置和紧凑之后的位置形成映射,这种方式就叫做离散化。 例如: 0 0 0 0
阅读全文
摘要:一维前缀和 前缀和一般用于预处理一个数组,然后在O(1)时间内获取该数组[l, r]区间内的和。对于数组a,有它的前缀和数组b,此时b[i] = b[i - 1] + a[i]。 二维前缀和 拓展到二维,假设我们有数组a的前缀和数组b,那么我们可以在O(1)时间内求出数组a中某一个矩阵的和,该矩阵左
阅读全文
摘要:本质思想 通过二分法查找有序数列中某个数字的下标,只是二分法的一种应用,二分法的本质是找到性质的边界。 查找有序数列的数字x,本质是x将数组分成了两个性质,x左边的数满足性质1:小于等于x;x右边的数满足性质2:大于等于x。 在该情境下,无论是左边性质还是右边性质,边界都是一样的(假设序列中只有一个
阅读全文
摘要:堆是一种数据结构,本质是存放在数组中的完全二叉树。如图,完全二叉树存放在数组中为:[10, 7, 2, 5, 1]。该数组的特点为:对于第i个数,其左孩子为第2×i+1个,右孩子为2×i+2个。 堆分为大根堆和小根堆,大根堆的任意节点的值都大于其左孩子和右孩子节点的值;小根堆的任意节点都小于其左孩子
阅读全文
摘要:归并排序核心思想是,将两个有序数组合并成一个有序数组。 快排核心思想是,将一个无序数组分成左边<=x,右边>=x的格式。 递归树 涉及到递归,都可以形象的理解成“树”,单递归就是链表,双递归就是二叉树,多递归就是N叉树,在脑中将递归过程映射为“树”,能更好更快的理解递归过程和递归中某一刻的状态。 归
阅读全文
摘要:归并排序三步: 1、找分界点 2、递归 3、合并数组 /* * 归并排序 */ #include<iostream> using namespace std; const int N = 1e5 + 10; int tmp[N]; void merge_sort(int a[], int l, in
阅读全文
摘要:快排三部曲:找基准,划区间,左右分治。其中划分区间(让左边的数都小于x,让右边的数都大于x)的操作最难,涉及到边界问题,代码需要兼容很多特殊情况。 不过暴力解法也挺好的,选中基准x后,遍历原数组将区间分别写入新的两个数组,之后再将原数组值写回。(就是多开数组了,时间复杂度不变) 优雅的实现方式有很多
阅读全文
摘要:什么是tire tree 字典树的结构是多叉树,每个节点有n个出度,每个出度表示一个字符。字典树的节点分为普通节点和终止节点,如图,红色的节点即为终止节点,往字典树中插入一个单词,这个单词的最后一个字符就是终止节点。如图,字典树中包含的单词有:"abcd","abd","b","bcd","efg"
阅读全文
摘要:从单链表到跳表 skip list常称为跳表,查找、插入、删除时间都接近logn,是代替平衡树的一种方案。skip list可以看作是从单链演化而来,单链表插入删除很快,但是查找效率很低,我们可以建立一种索引,给链表增加一层。这样在查找时就可以跳过一些值,加快查找速度。 在建立索引之后,查找6只需要
阅读全文

浙公网安备 33010602011771号