- 博客(83)
- 收藏
- 关注
原创 使用select和channel实现超时机制、Fan-in / Fan-out 模型、生产者-消费者模型
问题:一个Goroutine在计算结果,一个Goroutine在计时,谁先完成就用谁的结果(Select的事情)1)主线程中的select开始运行,对select中的3个channel进行阻塞等待。:将多个 worker 的结果汇聚到一个通道中进行统一处理。:将任务从一个入口分发给多个 worker 并发执行。2)在线程(协程)waitFor中向ch写入数据。3)select收到数据,进行读取。
2025-12-25 22:15:32
92
原创 map的数据结构,扩容机制,key是无序的原因
map就相当于是一个超级查询表,给它一个Key,它可以给你返回对应的value。例如以上例子,Apple就是Key,3就是代表的value。
2025-12-25 14:49:12
168
原创 Slice的深拷贝和浅拷贝
Slice是Go语言中的一种数据类型,又称动态数组,依托数组实现,可以方便的进行扩容、传递等,实际使用中比数组更灵活。
2025-12-25 11:32:56
246
原创 使用Go语言中的Channel实现并发编程
Channel的定义:在Go语言中,Channel是一种用于在Goroutine之间进行通信的数据结构。(1)阻塞:当发送数据到一个Channel时,如果没有其他Goroutine准备好接收这个数据,发送操作将会阻塞,直到有其他Goroutine接收数据。如果Channel的容量大于零,发送操作将不会阻塞,直到Channel已满。类似地,如果Channel的容量大于零,接收操作将不会阻塞,直到Channel为空。要创建一个Channel,可以使用内置的make函数,指定Channel中元素的类型。
2025-12-25 00:37:58
342
原创 深入理解golang的GMP模型
当某个P的LRQ中的Goroutine过多时,调度器会将部分Goroutine迁移到其他P的LRQ中,以实现负载均衡。Machine(M):Machine代表操作系统线程,它是真正执行Goroutine的实体,每个M都与操作系统线程绑定,负责执行Goroutine的代码。Go的调度器能够动态调整P的数量,并根据负载情况将Goroutine迁移到其他P上执行,从而实现了系统的动态负载均衡。当Goroutine数量过多时,调度器的负载均衡机制可能会导致频繁的Goroutine迁移,从而增加系统的开销。
2025-12-25 00:06:57
199
原创 Go语言中判断map 中是否包含某个key 的方法
在上述代码中,我们使用for range遍历map,并通过判断遍历到的键值是否等于目标key来确定map中是否包含该key。sync.Map提供了Load、Store和Delete等方法,可以方便地操作map,并提供了LoadOrStore方法用于判断map中是否包含某个key。Go语言中提供了一种简洁的方式来判断map中是否包含某个key,即使用逗号ok idiom。通过判断ok的值,我们可以确定map中是否包含某个key。在上述代码中,我们首先创建了一个名为m的map,并在其中插入了一个键值对。
2025-12-23 08:17:02
225
原创 分布式id生成器
不仅仅是基于用户ID,实际互联网中有很多场景都需要能够生成类似MySQL自增ID这样不断增大,同时又不会重复的ID,以支持业务中的高并发场景。电商促销时短时间内会有大量的订单涌入系统,比如每秒10W+明星出轨时微博短时间内会产生大量的相关微博转发和评论消息。全局唯一性:不能出现重复的id标识,这是基本要求。递增性:确保生成ID对于用户或业务的递增的。高可用性:确保任何时候都能生成正确的ID。高性能:在高并发的环境下依然表现良好。
2025-10-31 23:45:34
119
原创 使用lua的必要性
这时,有人就会说,扫库,扫rediskey,用户签到的key,然后去遍历,但是当用户量特别大的时候,去扫rediskey的时候,性能死化还是挺大的,要实现这个功能(判断今天没有签到,前两天签到了)我们其实要编写很多个命令,这个时候我们可以写一个原子化,多个操作可以把它原子化,之后它执行效率就高了。比如说,在每天18.00点对那些前两天签到了,但是今天还没有签到的用户发送即将断签提醒,引导用户及时完成签到,获得连续签到奖励。
2025-10-31 23:45:06
345
原创 Redis Key的设计
当月每日签到bitmap|(逻辑或)当日补签bitmap=当月签到bitmap。user:checking:daily:userID:年份。user:checkins:retro:userID:月份。逐位遍历当月签到bitmap后判断可得出当月连续签到天数。(1)既能记录当月补签日期,又能方便的计算当月补签次数。(2)每年之后将redis中的签到数据持久化入DB。(2)每个月后将Redis中的补签数据持久化入DB。2.用户补签记录(bitmap)一个key存储用户当月的补签记录。
2025-10-14 22:17:50
339
原创 BITFIELD命令详解
Redis 3.2引入的BITFIELD命令支持对位图进行高级位操作,具有多字段处理、多种整数类型支持(有/无符号)、溢出控制(WRAP/SAT/FALL)和原子性操作等特性,可高效完成复杂的位级数据处理。
2025-10-14 21:54:44
243
原创 未提交读的问题
因此,在实际应用中,应该避免使用 Read Uncmmitted 隔离级别,除非对数据一致性要求极低,并且能接受脏读带来的所有后果。如果事务 B 读取了事务 A 修改但未提交的数据,当事务 A 回滚时,事务 B 读取到的数据就是无效的脏数据。如果应用程序基于脏数据执行后续操作,则可能导致逻辑错误,例如错误的计算、错误的决策等。由于允许脏读,可能导致应用程序读取到不一致的数据,破坏数据的完整性。此时,事务 B 基于 200 元的脏数据进行了操作,导致数据不一致。读取账户余额,会读取到 200 元(脏读)。
2025-07-28 20:01:19
152
原创 RR不能解决幻读的原因
当执行 SELECT ... FR UPDATE、UPDATE、DELETE 等操作时,InnDB 会自动为影响的数据加上 Next-Key Lck,从而防止其他事务插入或删除数据,导致幻读。对于select * frm table where id = 10 fr update, 会锁住id=10的索引和间隙, 防止其他事务修改id=10,或者插入id = 10.x 的数据。当一个事务在读取数据时,MVCC不会记录新插入的数据,当再次读取的时候,新插入的数据就会造成幻读。
2025-07-28 19:55:32
408
原创 解决幻读问题
当使用范围查询时(例如 SELECT * FROM table WHERE id > 10 FOR UPDATE),InnoDB 会使用 Next-Key Lock 锁定指定范围的所有记录及间隙,避免在查询期间出现幻读。幻读(Phantom Read) 是指在同一个事务中,多次读取同一范围内的记录时,由于其他事务的插入或删除操作,导致该事务前后读取到的记录数量不一致。Next-Key Lock 不仅会锁定索引记录本身,还会锁定索引记录之间的间隙,防止其他事务在该间隙中插入新记录,从而避免幻读。
2025-07-28 19:52:42
380
原创 事务的特性和隔离级别
事务的隔离级别定义了并发环境下,一个事务在执行读写操作时,会受到其他事务影响的程度。它是数据库保持acid中的“隔离性”的关键机制之一。事务隔离级别,就是给不同事务之间设置“保护伞”,防止“你看一半”被别人改了。4.持久性:一旦事务提交,其对数据库的修改应永久保存,即使系统发生故障也不会丢失。3.隔离性:多个事务并发执行时,每个事务的操作应彼此隔离,避免相互干扰。高级别 = 慢 = 数据更稳定。1.原子性:事务中的所有操作要么全部成功,要么全部失败。2.一致性:事务执行前后,数据库都必须处于一致的状态。
2025-07-24 19:08:59
201
原创 explain中每个字段的解释
select_type:查询类型(const,eq_ref,ref,range,index按效率从高到低)id:查询中每个Select子句的标识,数字越大,优先级越高。key:实际使用的索引(如果是null,说明未命中索引)type:连接类型,判断索引是否命中的最关键字段之一。possible_keys:查询可能使用的索引。key_len:使用的索引的长度,越短越高效。rows:预估要扫描的行数,越少越高效。table:当前正在访问的表名。extra:补充信息。
2025-07-23 17:51:48
101
原创 聚簇索引的优势
数据存储效率高:聚簇索引将数据行与索引存储在同一个结构中,数据按照索引键的顺序物理存储。减少回表操作:普通索引查询可能需要通过回表(回到主索引获取完整数据行),而聚簇索引的叶子节点直接包含完整数据行,避免了额外的查找步骤,降低了查询延迟。范围查询性能优异:由于数据按索引键顺序物理存储,范围查询可以快速定位到起始点,并顺序读取后续数据,避免了随机I/O带来的性能损耗。优化排序和分组操作:如果查询涉及索引键的排序或分组,聚簇索引可以避免额外的排序步骤,因为数据已按索引键物理有序存储。
2025-07-22 19:15:02
156
原创 索引快的原因
避免全表扫描:没有索引时,查询需逐行检查所有数据(全表扫描)。例如,对 100 万行数据的等值查询,全表扫描需比较 100 万次,而索引可能仅需 3~4 次(B+ 树高度通常很低)。索引通过有序存储键值(如 B+ 树结构),将随机访问转化为顺序访问,减少磁盘寻道时间。它类似于书籍的目录,通过预先组织关键信息(如字段值)和对应的存储位置,减少查询时需要扫描的数据量。排序和分组优化:索引本身是有序的,对于ORDER BY或GROUP BY操作,数据库可直接利用索引顺序返回结果,避免临时排序的额外开销。
2025-07-22 18:22:14
199
原创 Mysql基本操作
添加字段:ALTER TABLE users ADD 字段名称 字段类型 NOT NULL DEFAULT ' ' COMMENT '字段中文名称';修改NULL值:LTER TABLE users MODIFY COLUMN 字段 字段类型 NOT NULL;修改字段类型:ALTER TABLE users MODIFY COLUMN 字段 新的字段类型;修改字段:ALTER TABLE users CHANGE 原字段 新字段 新字段的类型;查看数据库中有哪些表:show tables;
2025-07-21 21:45:54
208
原创 对称加密速度更快的原因
计算复杂度不同,对称加密使用的是同一个秘钥进行加密和解密,算法简单直接,运算量小;飞堆成加密使用两种秘钥,基于复杂的数学问题,计算量大,速度慢10-1000倍。实际应用中,通常采用混合加密,先用非对称加密交换密钥(安全但慢),再用对称加密传输数据(快,但需要安全密钥),兼顾速度与安全。
2025-07-15 15:43:04
94
原创 IP地址的分类
A类地址适用于大型网络,因为它允许非常多的主机地址。C类地址:192.0.0.0-223.255.255.255,前三个数字代表网络地址,最后一个代表主机地址,C类地址适用于小型网络,因为它提供的主机地址相对较少。B类地址:128.0.0.0-191.255.255.255,前两个数字代表网络地址,后两个数字代表主机地址,,B类地址适用于中型网络,介于A类和C类之间。D类地址:224.0.0.0-239.255.255.255,D类地址不用于标识具体的网络或主机,而是用于多播。
2025-07-15 14:26:44
342
原创 DNS的含义以及例子
DNS服务器其实就相当于一个负责翻译的中介,比如,我们在浏览器输入baidu.com,DNS系统会查到这个baidu.com(域名)相对应的IP地址,紧接着,浏览器通过这个IP地址就找到了百度的服务器。DNS是互联网的核心目录服务,本质是一个分布式数据库,专门负责将人类友好的域名(如。它的设计目标是解决互联网中寻找效率和可扩展性的问题。)转换为机器可识别的IP地址(如。
2025-07-15 13:53:47
155
原创 HTTP2更快的原因
2.二进制协议:HTTP2采用的是二进制协议,计算机可以直接处理二进制,解析更快、HTTP1.1采用的是文本格式传输数据,计算机首先需要解析这些文本,效率比较低。4.服务器推送:传统的需要先让浏览器请求HTML,解析后在请求CSS/JS等,有延迟,服务器推送可以主动推送资源给浏览器,省去了“请求等待”的步骤。1.多路复用:HTTP允许同时发送和接收多个响应,HTTP1.1中,浏览器与服务器之间的通信是需要“排队”的。5.优先级和依赖控制:HTTP2允许给请求设置优先级。
2025-07-15 13:43:36
217
原创 sync.Mutex和sync.RWMutex的区别和它们的使用场景。sync.RWMutex在读多写少的场景下性能更好的原因。
RWMtuex是读写互斥锁,读操作允许多个goroutines并发进行,写操作只允许一个goroutines进行操作。Mutex是普通互斥锁,读写操作都需要先获取锁,同一时刻只能有一个goroutines在进行操作。Mutex适用于读写操作频繁且无明显倾向的场景,RWMutex适用于读多写少的操作。
2025-07-11 15:16:32
188
原创 Go语言的Channel通道的含义。区分缓冲通道和非缓冲通道,并讨论通道的发送、接收、关闭以及如何安全地从已关闭的通道读取数据。
非缓冲通道:非缓冲通道在确定时没有声明容量大小,发送和接收操作会同步阻塞,直到另一端准备好。发送方和接收方必须同时就绪才能完成数据交换,否则会阻塞。缓冲通道:缓冲通道在确定时就声明了容量大小,发送操作在缓冲区未满时不会阻塞,接收操作在缓冲区非空时不会阻塞。当缓冲区满时发送会阻塞,空时接收会阻塞。关闭通道:使用close()关闭通道,关闭后不可在发送数据。非缓冲通道:无接收方的发送或无发送方的接收会导致永久阻塞。关闭通道后,接收方读取零值,发送方panic。缓冲通道:仅当缓冲区满/空时阻塞。
2025-07-11 15:04:51
178
原创 Go语言中数组和切片的主要区别
3.传递方式:数组传递是值传递,当对第一个数组作为参数传递给函数时,得到的是数组的副本,对副本的修改不会影响到原数组;切片传递是引用传递,传递的是切片结构体的副本,但其中的指针指向底层数组,所以在函数内对切片的修改会影响到原切片。2.内存结构:数组是一块儿连续的、固定大小的内存空间,可以直接存储元素,切片是一个结构体,包含指向底层数组的指针,切片的长度和容量。1.长度方面:数组的长度是固定的,在声明时就是确定好的,之后不能更改,切片的长度是可变的,可以根据需要进行动态增长或缩小。
2025-07-11 14:49:20
129
原创 Go语言中defer语句的含义,它使用的场景,写出的示例。
Go语言的defer语句用于延迟执行某一个函数或方法调用,直到包含它的函数执行完毕(无论正常返回还是发生异常)。它的应用场景一般在:资源释放,错误处理,日志记录。
2025-07-11 14:39:18
125
原创 map数据结构在Golang中是无序的,并且键值对的查找效率较高的原因
map,map在Go语言中是无序的,是因为在Go语言中,map基于哈希表实现,它的遍历顺序依赖于哈希表内部存储状态,对并发编程的潜在影响包括可能引发数据一致性问题,也就是并发度写实易导致读到不一样的数据或遍历出错;(4)动态扩容,当负载因子(键值对数量/桶数量)超过阈值时,map会自动扩容,减少哈希冲突概率,维持O(1)的平均操作时间。(2)哈希表的函数优化,Go会根据键的类型选择高效的哈希函数,均匀分布键以减少冲突。(1)哈希表的时间复杂度,哈希表的平均复杂度为O(1),最欢情况下为O(n)。
2025-07-11 14:30:21
255
原创 在Go语言中,声明一个指向整型变量 x 的指针变量
声明一个指向整型变量x的指针变量有两种方式,一种是使用var关键字声明,语法为var p *int,这代表着声明了一个名为p的指针变量,可以指向一个整型变量;另一种是短变量声明,需要获取变量x的地址并赋值给指针变量,也就是p := &x。
2025-07-11 13:25:40
108
原创 sync.WaitGroup的用途和工作原理。并且它们常使用的场景。
用途:让一个或多个goroutine等待一组其他goroutine全部完成任务后,再继续执行,避免主逻辑提前退出导致子goroutine被终止。wait:阻塞当前goroutine直到计数器归0,,此时所有被等待的goroutine已执行完毕。Done:等价于Add(-1),由子goroutine任务结束时调用,标记自身完成。需协调多goroutine执行顺序,确保一组并发任务全部完成后在执行后续逻辑。Add():修改计数器的值,用于声明需等待的goroutine数量。
2025-07-10 19:37:02
166
原创 Go语言的类型转换和类型断言的定义,它们之间的区别。
3.使用限制:类型转换要求目标类型和源类型有一定的兼容性,类型断言针对接口类型,接口实际存储的类型和断言类型不匹配时会有特定的返回值。2.应用场景:类型转换适用于不同但兼容的非接口类型之间的转换,类型断言适用于处理接口类型,判断接口中实际存储的类型并获取值。1.语法形式:类型转换是将表达式转换为指定类型,类型断言针对接口类型变量进行具体类型的判断和值的提取。类型转换:将一种类型的变量转换为另外一种类型的变量。类型断言:用于从接口类型变量中提取具体的类型值。
2025-07-10 19:25:36
83
原创 Go语言中map的零值,对零值map进行读写操作会发生的情况,正确初始化和使用map的步骤
Go语言中map的零值是nil,对map进行进行读操作:如果读取一个不存在的值,那么将会返回相对应的值的类型,对map进行写操作的话,可能会引发运行时的问题。4.遍历:使用for-range遍历map,例如for Key.value := range m {fmt.Println(key,value)}2.读取数据:通过值 := map变量[键]的方式读取数据,可以同时获取值和一个布尔值,来判断键是否存在。1.导入数据:通过map 变量 [键] = 值的方式写入数据,例如m["newkey"] = 5。
2025-07-10 19:04:49
140
原创 Go语言中map的创建和基本操作(增删改查)
使用var创建,var m map[string]int,进行初始化才能进行使用,若不进行初始化,map的零值是nil。使用make初始化,m := make(map[string]int)查询:val, ok := m["key"]遍历:fork, v := range m。删除:delete(m, "key"),增改:m["key"]=value。
2025-07-10 18:11:58
91
原创 Golang中的内置类型
首先,内置类型是指不需要引入任何关于这些数据类型的包,就可以引用的数据类型。那么,内置类型主要包括基本类型,复合类型,控制并发,高级抽象,特殊类型。基本类型包括,整型,浮点型,布尔型,字符串,复数型(complex64,complex128)结构体是用户自定义复合类型,需通过type关键字手动声明定义不属于Go语言内置类型。高级抽象包括,interface,function,pointer。复合型包括,数组,切片,map,slice。特殊类型包括,error,any。控制通道,channel。
2025-07-10 18:00:34
233
原创 Deepseek
Deepseek作为一个人工智能应用,可以与用户进行智能对话,根据用户的需求进行文本生成;可以对自然语言进行各方面的分析,智能的识别内容主题进行文本分类;对于一些逻辑性的问题能够进行智能推理,从而给出答案;在编程与代码方面,我们可以把详细的需求告诉它,从而根据需求生成答案,或者进行代码调试,技术文档的处理等等。deepseek是一家人工智能科技公司所开发的能够进行人工智能对话的一个应用,它的主要目标是大规模的研发与应用。deepseek-R1是它的开源推理模型,主要负责处理复杂任务并且可以免费使用。
2025-02-10 21:32:34
364
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅