@ I/O模式 阻塞I/O 非阻塞I/O I/O多路复用 信号驱动I/O 异步I/O I/O多路复用 I/O 多路复用 相较于多进程多线程技术区别在于一个进程或线程可以处理多个事件。I/O多路复用通过一种机制,可以监视多个描述符,一旦某个描述符就绪,能够通知相应的进程/线程进行相应操作 select
虚拟内存 虚拟内存是计算机系统内存管理的一种技术,它使应用程序认为它拥有连续的可用的内存,而实际上它通常被分隔成多个物理内存碎片,还有部分存储在外部磁盘存储器上,在需要时进行数据交换。 程序使用的内存地址叫做虚拟内存地址,实际存在硬件的空间地址叫物理地址 进程通过虚拟地址来访问实际的物理地址 好处
主从复制 为了避免单点故障,多个服务器保存同一份数据,这样即使有一台服务器出现了故障,其他服务器依然可以继续提供服务。 Redis 提供了主从复制模式来实现,该模式保证了多台服务器的数据一致性,主从服务器之间采用的是 读写分离的方式。 也就是说,所有的数据修改只在主服务器上进行,然后将最新的数据同步
Redis 过期键策略和内存淘汰策略 设置Redis键过期时间 Redis有四个不同的命令来设置生存时间(键可以存在多久)或过期时间(键什么时候会被删除)。 EXPIRE <key> <ttl> :表示将键 key 的生存时间设置为 ttl 秒。 PEXPIRE <key> <ttl> :表示将键
Sentinel(哨兵模式) 经过上期【Redis】主从复制 的学习, 我们知道 主从复制 是为了避免单点故障,将数据保存在多台服务器上的一种机制。 但是主节点只有一个,如果主节点挂掉了,怎么办?于是 哨兵模式 诞生了。 哨兵模式可以不时地监控 redis 是否按照预期良好的运行(至少是保证主节点是
缓存雪崩、击穿、穿透 缓存雪崩 当大量缓存数据在同一时间过期(失效)或者 Redis 故障宕机时,如果此时有大量用户请求,都无法在Redis中处理,于是全部请求都直接访问数据库,从而导致数据库压力骤增,严重的会造成数据库宕(dang)机,从而形成一系列连锁反应,造成整个系统崩溃,这就是缓存雪崩 发生
#力扣链接:146. LRU 缓存机制 思路:哈希表 + 双向链表 为什么必须要用双向链表? 因为我们需要删除操作。删除一个节点不光要得到该节点本身的指针,也需要操作其前驱节点的指针,而双向链表才能支持直接查找前驱,保证操作的时间复杂度 O(1)。 为什么要在链表中同时存储 key 和 val,而不
MVCC MVCC(Multi-Version Concurrency Control),即多版本并发控制。是 innodb 实现事务并发与回滚的重要功能。锁机制可以控制并发操作,但是其系统开销较大,而MVCC可以在大多数情况下代替行级锁,使用MVCC,能降低其系统开销. 具体实现是在数据库的每一行
@ redo log(物理日志\重做日志) redo log是InnoDB存储引擎层的日志,又称重做日志文件,是物理日志。redo log记录数据修改后新数据的备份、冗杂的undo log、未提交的事务和回滚的事务,数据缓存到内存中,只是在事务提交前将redo log持久化到磁盘 redo log
redis中常见数据结构 SDS(简单动态字符串) SDS结构: { int len; //记录buf数组中已使用字节的数量,等
索引下推 当 sql满足最左前缀原则的时候,最左前缀可以用于在索引中定位记录,而索引下推就是用来优化那些不符合最左前缀的部分 例如有一联合索引(name,age),索引结构如下: 现有一需求,sql为: select * from tuser where name like '张%' and age
Mysql中的锁 基于锁的属性分类:共享锁、排他锁。 基于锁的状态分类:意向共享锁、意向排它锁 根据锁的粒度分类:全局锁、页锁、表级锁、行锁(记录锁、间隙锁、和临键锁),实际上的锁就这些,上面两种分类只是站在不同维度上看这些锁 页级锁仅被BDB存储引擎支持,这里不介绍 全局锁 全局锁就是对整个数据库
堆: 一般我们提到的是二叉堆,是一种完全二叉树,二叉堆有两种:最 父节点下标:i/2 左
defer 用于延迟函数的调用,每次defer都会把一个函数压入栈中,函数返回前再把延迟的函数取出并执行 延迟函数的参数在defer语句出现时就已经确定下来了 如: func a() { i := 0 defer fmt.Println(i) i++ return } defer语句中的fmt.Pr
单调队列 今天刷力扣,碰到一道关于单调队列的题,总结一下 239. 滑动窗口最大值 单调队列思想: 队列没有必要维护窗口里的所有元素,只需要维护有可能成为窗口里最大值的元素就可以了,同时保证队列里的元素数值是由大到小的。 单调队列不是单纯的给队列中元素排序,那和优先级队列没有什么区别了。 设计时要注
go语言中并发安全和锁 首先可以先看看这篇文章,对锁有些了解 【锁】详解区分 互斥锁、⾃旋锁、读写锁、乐观锁、悲观锁 Mutex-互斥锁 Mutex 的实现主要借助了 CAS 指令 + 自旋 + 量 数据结构: type Mutex struct { state int32 sema uint3
锁 今天看了下常见的几种锁: 互斥锁、⾃旋锁、读写锁、乐观锁、悲观锁,总结一下 互斥锁和自旋锁 最底层的就是互斥锁和自旋锁,有很多⾼级的锁都是基于它们实现的 加锁的⽬的就是保证共享资源在任意时间⾥,只有⼀个线程访问,这样就可以避免多线程导致共享数据错乱的问题 互斥锁和⾃旋锁的区别就是对于加锁失败后的
实现原理 垃圾收集的多个阶段: 清理终止阶段(STW) 暂停程序,所有的处理器在这时会进入安全点 我的理解是这里stw,等待所有协程都知道要开始打开写屏障了,不然无法做到统一 如果当前垃圾收集循环是强制触发的,我们还需要处理还未被清理的内存管理单元 标记阶段-并发执行 将状态切换至 _GCmark
哈希表 242. 有效的字母异位词 func isAnagram(s string, t string) bool { var m [26]int for _,v:=range s{ m[v-'a']++ } for _,k:=range t{ m[k-'a']-- } for _,w:=range
GC垃圾回收机制设计原理 标记清除 1.3版本之前。大概分为两阶段: 标记阶段 - 从根对象出发标记堆中存活的对象 清除阶段 - 遍历堆中所有对象,回收未被标记的垃圾对象 1.0版本:是完全串行的,这两个阶段都在STW暂停范围之内 1.1版本:在多核主机并行执行垃圾收集的标记和清除阶段 缺点:整个过
异步协程 package main import ( "gopkg.in/gin-gonic/gin.v1" "time" "log" ) func main(){ // only set in Production // gin.SetMode(gin.ReleaseMode) router :=
203.移除链表元素 力扣链接 创建一个虚拟头节点 func removeElements(head *ListNode, val int) *ListNode { p:=&ListNode{} p.Next=head q:=p for p!=nil&&p.Next!=nil{ if p.Next.
一般情况使用 c.ShouldBindJSON c.ShouldBind 第二次读取 request body 的数据就会出现 EOF 的错误,因为 c.Request.Body 不可以重用 gin 1.4 之后官方提供了一个 ShouldBindBodyWith 的方法,可以支持重复绑定,原理就是
704. 二分查找 力扣链接 注意边界问题 func search(nums []int, target int) int { r,l,mid:=0,len(nums)-1,(len(nums)-1)/2 for l>=r{ mid = (r+l)/2 if nums[mid]==target{ r
Golang抢占式调度 在1.2版本之前,go的调度器仍然不支持抢占式调度,程序只能依靠Goroutine主动让出CPU资源才能触发调度,这会引发一些问题,比如: 某些 Goroutine 可以长时间占用线程,造成其它 Goroutine 的饥饿 垃圾回收器是需要stop the world的。如果
Channel 底层数据结构 type hchan struct { qcount uint // 当前队列中剩余元素个数 dataqsiz uint // 环形队列长度,即可以存放的元素个数 buf unsafe.Pointer // 环形队列指针 elemsize uint16 // 每个元素的
GMP Goroutine调度是一个很复杂的机制,下面尝试用简单的语言描述一下Goroutine调度机制,想要对其有更深入的了解可以去研读一下源码。 介绍 首先介绍一下GMP什么意思: G goroutine: 即Go协程,每个go关键字都会创建一个协程。 M thread内核级线程,所有的G都要放
冒泡排序 冒泡排序算法的原理如下: 比较相邻的元素。如果第一个比第二个大,就交换他们两个。 对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。 针对所有的元素重复以上的步骤,除了最后一个。 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需
Map map底层是由哈希表实现的 Go使用链地址法来解决键冲突。 map本质上是一个指针,指向hmap 这里的buckets就是桶,bmap 每一个bucket最多可以放8个键值对,但是为了让内存排列更加紧凑,8个key放一起,8个value放一起。在8个key前面是8个tophash,每个top
go二维数组排序
Copyright © 2005-2023 51CTO.COM 版权所有 京ICP证060544号