- 博客(111)
- 收藏
- 关注
原创 Go基础|map入门
map介绍,一看就会。Go语言map结构由多个哈希桶组成,每个桶包含8个槽位存储键值对,通过哈希函数定位桶和槽位,桶满了会创建溢出桶形成链表。map非线程安全,并发场景可通过三种方式解决:1)使用sync.Mutex/RWMutex全局锁;2)采用标准库sync.Map(基于分段锁实现);3)分片锁技术,将数据分块并独立加锁。其中sync.Map通过细粒度分段锁提升并发性能,相比传统全局锁更适合高频读写场景,而分片锁通过减少锁竞争进一步提高吞吐量。开发者应根据具体场景选择适合的并发控制方案。
2025-06-03 23:56:09
629
原创 go语言基础|slice入门
go语言slice介绍,入门基础。Go语言中的切片(slice)是一种可变长度的数组结构,包含指向底层数组的指针、长度和容量。相比固定长度的数组,切片支持自动扩容:1.18版本后以256为临界值,小于时双倍扩容,大于时采用(旧容量+768)/4的扩容算法,实现平滑过渡。切片作为参数传递时会被复制结构体值,虽能修改元素但无法扩容;传递指针则可完全修改。由于底层结构包含多个可变状态,切片是线程不安全的,需加锁或只读使用。这种设计在灵活性和内存效率间取得了平衡。
2025-06-03 21:15:00
1838
原创 go并发编程| channel入门
channel入门介绍,初学者一看就懂。channel 是在 Go 的并发编程中使用的,这个工具的作用之一是 goroutine 之间通信(线程通信指的是多个线程之间通过共享数据或协作机制来协调操作,通常需要借助锁来保证同步)。Go 中推荐使用 channel(不同语言有不同的并发模型,例如 Java 使用共享内存并发模型,通过锁机制和条件变量实现线程间通信)。为什么是推荐呢?
2025-05-29 22:00:30
1079
原创 go并发与锁之sync.Mutex入门
Go的sync.Mutex实现了高性能的互斥锁机制,提供悲观锁功能。其核心原理是通过CAS操作和状态管理实现锁竞争。在低竞争场景下采用自旋机制减少上下文切换;当竞争激烈(等待超1ms)则切换为饥饿模式,避免goroutine饥饿。实现上分为快速路径(直接获取锁)和慢速路径(自旋/排队),通过state字段管理锁状态、等待者数量和模式切换。典型用法包括手动Lock/Unlock以及配合WaitGroup进行协程同步。该设计在保证线程安全的同时,针对不同竞争强度优化了性能表现。
2025-05-27 21:00:00
679
原创 并发基础|进程与线程
进程和线程的基本概念及其区别,小孩都能看懂。进程是为实现程序并发执行而提出的概念,由PCB、程序段和数据段组成,解决了程序隔离性和安全性的问题。线程是更轻量级的执行单元,共享进程资源但切换开销小,主要用于减少上下文切换的损耗。文章还解释了上下文切换的原理,并发与并行的区别(同一时间段轮番执行vs同一时间同时执行),以及同步调用(等待结果)与异步调用(不等待结果)的不同特点。通过工程机械公司的比喻形象说明了线程共享进程资源的工作机制。
2025-05-26 19:30:00
1579
原创 GMP模型入门
Go语言的并发实现采用了M:N的线程模型,具体通过GMP模型实现。GMP模型由三个核心组件构成:Goroutine(G,用户态线程)、Machine(M,绑定内核线程)和Processor(P,调度器/执行上下文)。该模型通过P管理G的调度,由M实际执行G,从而避免了频繁的线程创建与上下文切换,提升了性能。调度机制包括Handoff和WorkStealing:当M阻塞时,G会被重新调度;当P的本地队列为空时,M会从其他P的队列中“偷取”G。系统初始化时,会创建与CPU核数相同的P,并启动M进行调度。M的主循
2025-05-23 20:15:00
556
原创 tarjan算法
是一种基于深度优先搜索(DFS)的图算法,用于在有向图中找到所有的强连通分量(SCC)。Tarjan算法非常高效,是解决强连通分量问题的经典算法之一。出发无法再追溯到更早的祖先节点,此时栈中从。到栈顶的所有节点构成一个强连通分量。在DFS过程中,如果发现某个节点的。
2025-03-15 14:36:46
294
原创 数据库版本问题导致的查询bug
我觉得难道是这里不能用外查询?然后测试站没有报错,很奇怪,一样的SQL,一个报错一个不报错,唯一的变量就是MySQL的版本了,测试站是8.0.28,正式站是8.0.16,应该是版本问题。但是有个问题困扰着我,就是外查询这么通用的功能,怎么可能在这么小的版本里面进行更新修复或者开发出来,而且当我把这行注释掉,正式站又可以跑的通,可是我这个SQL又不止这个地方用到了外查询这个特性。后面思考了一下,可能不是外查询的问题,我把过滤条件放在where语句就能跑的通,我很兴奋,原来是外查询放在join中是跑不通的。
2025-03-14 10:02:05
298
原创 go压缩的使用
如果要拷贝另一个文件,需要再创建一个文件且拷贝后才可以,不然之前的文件关闭了就无法再复制进去了。注意,顺序不可以颠倒,要先创建路径,然后创建文件,然后再把文件拷贝到压缩包中。压缩文件:北京/朝阳区/美食地图.jpg。基础:使用go创建一个zip。需要先做的是创建所需的层级。
2024-10-18 15:00:26
551
1
原创 动态规划|剑指 Offer II 093. 最长斐波那契数列
如果数组 arr 中存在三个下标 i、j、k 满足 arr[i]>arr[j]>arr[k] 且 arr[k]+arr[j]=arr[i],则 arr[k]、arr[j] 和 arr[i] 三个元素组成一个斐波那契式子序列。由于数组 arr 严格递增,因此 arr[i]>arr[j]>arr[k] 等价于 i>j>k。这道题说明了打表的过程是依赖状态转移方程的。把这道题的官解再次细化一下,可视化一下,这样理解起来更容易一些。
2024-07-07 22:20:59
294
原创 acwing 291.蒙德里安的梦想
根据上面的分析可以得到,一个合法的状态j,可以由很多个其他的合法状态转移而来,现在把每个合法的状态j的前一个合法状态集合求出来。状态计算:f[i,j] = ∑f[i-1,k],f[i-1,k]指的是可以到达f[i,j]的合法f[i-1]的状态。动态规划思路: 状态表示:f[i,j]表示已经将前i-1列摆好,且从第i-1列,伸出到第i列的状态是j的所有方案。结果状态:f[m,0],即前m列已经被铺满,m+1列一个格子都没有被占,即m列中没有伸到m+1列的小方块的状态。解法: 核心:先放横着的,再放竖着的。
2024-07-07 22:07:24
451
原创 最长公共子序列
但如果拿掉的是两个一样的字符,比如说都是d,即原始的两个字符串是【acbd,abedd】,拿掉末尾的d,【acb,abed】的答案是x,即【acb,abed】最长公共子串长度为x,现在在原来的字符串基础上又多了一个相同的字符,那么很自然的,最长公共子串长度应该为x+1。重新从刚才线索断掉的地方开始思考,【acbd,abedc】的尾巴一个是d,一个是c,且知道【acbd,abedc】前所有的答案,即。程序很好写,就是一个双重for循环,但是其状态转移的公式的由来是值得思考的。897. 最长公共子序列。
2024-06-29 18:23:27
448
原创 我的创作纪念日
提示:你过去写得最好的一段代码是什么?提示:当前创作和你的工作、学习是什么样的关系。提示:可以和大家分享最初成为创作者的初心。提示:在创作的过程中都有哪些收获。提示:职业规划、创作规划等。
2024-06-28 10:15:25
265
原创 回溯法、全排列、子集等
子集问题描述:使用集合S{1,2,3}中的元素构建新的集合,每个元素只能使用一次,元素一样的集合只算一个,eg.{1,2},{2},{1,2,3}…给定一个集合S{a,b,c},把其中元素按照不同顺序进行排序,eg.“abc”,“bca”,“cab”…其实这个子集问题的本质就是高中学到的组合问题,n个元素有几种组合方式,答案数量为C(n,m);基本思想是树(解答树)的遍历,如果是使用dfs(暴搜),那么可以使用递归来写。其实上面两个点,也是对应着高中数学里面的“排列”与“组合”先空着,有空再学再写。
2024-05-10 14:12:47
305
1
原创 二分查找入门、二分查找模板
二分查找的具体实现是一个难点,挺复杂的,可以背住一个模板,然后以后再慢慢学习。下面是y总的二分模板(比较难懂,之后再学)
2024-05-10 14:10:11
240
1
原创 Dijkstra求最短路径
进行第二次打表,本次打表不是从v0出发,而是从点集S出发,求得S到各点的最短距离,将距离最短的点更新加入S,然后不断重复,直到目标点被添加入点集S时,结束,此时找到最短路径。详见青大王卓课程:https://www.bilibili.com/video/BV1nJ411V7bd?从源点v0出发,求得到其余所有点的距离,打成第一张表,然后以此表为依据,寻找距离v0最近的点,将该点加入到v0的点集S中;利用了广度优先搜索,使用贪心思想,不断扫描各点距离源点的距离,然后将最短距离保存,直到所有点扫描完毕。
2024-05-07 22:40:55
331
原创 浮点数加法
浮点数有时候计算结果会出现长尾小数,例如0.1+0.11=0.21000000000002,这种结果很麻烦。用包装类就可以轻松的解决这个问题,不过想着很久没写加法了,高精度加法也不咋写了,自己造下轮子熟悉一下算法,于是就写了个浮点数的加法,原理就是小学加法。
2024-03-18 22:53:22
288
原创 Java、GO、C++语法比较
Java:int[] arr, int arr[]都行,不过建议前者,后者是c-style。c++: *int 指针传递,&int 引用传递,int 值传递。go:arr := make([]int,0),只能在前面。c++:int arr[],只能这样,放前面会报错。go: *int 指针传递传递,int 值传递。2.声明数组(切片)方括号位置。3. 函数传递参数不同。
2024-03-06 22:34:38
269
1
原创 datagrip 使用自定义参数
1. 直接打问号❓,执行的时候会问你这个问号填什么。格式:${xxxx} xxxx是你定义的参数名字。2. 设置参数,执行的时候会问你这个参数填什么。执行就会问你这个参数填什么,定义过会保留。
2023-11-02 18:01:38
1463
1
原创 GO|经典错误之回车与\n
Linux系统里面回车是\n,但是Windows里面是\r\n,因此如果是使用 input = input[:len(input)-1]的方式去掉delim,那就会出错了,因此还是要使用相应的工具包才好,即使用。明明没有什么问题,然后把这段代码放到online go的网站上去跑,输出的是99。这个\r\n是啥, 搜了一下,是Windows系统里面的回车,好家伙,原来问题出在这里了。运行,输入99,回车,输出0。
2023-09-02 14:30:48
850
原创 数据链路层是什么?
数据链路层承接上层的数据,然后使用下层提供的,按照一定的规则,进行数据传输。物理层提供了传输媒体与连接(信道)(数据链路层使用的信道通常是物理层提供的信道),即提供了比特流动的可能性,但是杂乱无章的比特并不是信息,数据链路层需要将上层给予的数据信息组织起来,按照一定规则发送与接收。
2023-08-14 12:46:23
237
原创 及时、完善的测试的重要性
后来换个方向,去看被调用的模块,才发现被调用的模块里面有一个配置的错误,这个错误在这个模块做接口级别的测试的时候是无法发现的,而我写这个模块的时候很着急,只做了接口的测试。具体来说,这个项目使用的是ssm框架,需要进行大量的配置,而配置内容基本上都是差不多的,因此我在对某个模块进行一些框架、中间件的配置的时候,直接从原来项目中复制了过去。去年开发某个项目的过程中遇到过一个bug,让我印象深刻, 因为花费了一个下午的时间才解决,而导致bug的原因却非常的基础,并不是什么难的问题,就是配置错了而已。
2023-08-12 22:48:42
297
原创 八股|ThreadLocal的内存泄露
ThreadLocal为什么可能导致内存泄露?答:由于存储的value并不是存在ThreadLocal对象之中,因此ThreadLocal对象被回收后,value可能无法被回收,这样就造成了内存泄露。
2023-06-14 14:31:04
2598
原创 虚拟机角度下的线程
一个 Java 应用通常是一个进程,这个进程就是jvm,编译好的class文件丢到jvm中,执行时就成为了诸多线程(网络请求过来时,也会生成相应的线程去处理请求)。当运行一个 Java 程序时,操作系统会创建一个 JVM 进程,该进程会解释和执行 Java 代码,从而运行您的程序。 ——我们编写的Java程序运行在一个jvm上面,一个jvm囊括了所有的线程,所有的需求都是由线程完成的。
2023-06-11 12:41:15
839
原创 Java中线程的生命周期
只是普通的进入到了延时等待状态,wait和join会释放锁,所以他们进入等待状态后,还是可能进入阻塞状态的。至于各个状态之间如何转换,这里先不写了,二次复习的时候再深入。其中RUNABLE包含了OS中的执行与准备这两个状态。稍微复杂点:(这张图画的大致正确)
2023-06-11 12:30:31
580
原创 jvm|什么是Java虚拟机?
从OS角度去看,虚拟机就是一个进程,一个软件,我们所有的java程序都是跑在这个软件上面的,这个软件会发出机器指令给操作系统,然后达到操作硬件的目的。既然是一个软件,那么这软件就是跑在内存上面的。里面的栈、堆、方法区等等概念,都是这个软件在内存上自我划分的概念,而不是操作系统划分的概念,因此这台机器叫做虚拟机,是虚拟出来的一台机器,在OS看来,这就是一个平平无奇的进程。上面讲到把JVM放入内存中,好像就像画的那样JVM直接占内存条的一段,其实不是这样的,这是抽象的表示方法,是为了忽略掉与整体无关的细节。
2023-06-04 22:42:04
110
原创 JVM|什么是符号引用?
在Java中,符号引用(Symbolic Reference)是指用一个符号来代替目标引用的一种引用方式。它包括了两个部分:符号引用和解析。符号引用是指在Java类中通过类、方法、字段等名称来引用其他类、方法、字段等的方式。在Java源代码中使用的类名、方法名、字段名等都属于符号引用。符号引用是一个字面量,它可以被存储在类或者方法的常量池中,而不需要提前解析。解析是指在运行期间将符号引用转换为实际的内存地址的过程。
2023-04-21 15:42:57
2517
原创 软件工程|为什么需要统一处理异常?以及如何处理?
后端开发人员可以简单的明白请求是非法的,并察觉到了是因为非法请求导致程序抛出了异常,这是由于开发者熟悉程序的细节,知道为什么程序会跑到这个异常的位置,但是对于运维和前端人员,他们看到了日志里记录专业化(开发化)的异常报错,有时是难以理解的,这对于团队代码开发是不利的。开发是一个持续的过程,在这个过程中总能碰到相似的、同类的异常,如果为了每种异常都去写一个自定义异常,为每种异常去写专门的前端响应,那将会增加开发的复杂程度,而且事倍功半,不利于后期维护。将异常统一起来管理,这是会方便开发的。
2023-03-27 20:23:41
280
原创 debug|freemarker的InvalidReferenceException处理
读了读下面的报错,基本上明白错误的地方了:就是我用于生成模板的数据,有些是空字段,而这个我并没有设置,因此模板引擎报错了。知道这个错误后事情就简单了,要么设置空字段默认值,要么传入的值不能为空即可。好的,百度一下这个异常咋回事,一搜,说是模板里面的放的值不能为空,好家伙,不能为空啊,那读读报的错是不是这个意思呢?密密麻麻的,真让人头疼,先检查下环境配的对不对好了,xml配置、模板地址啥的,检查后发现没问题,那进入到第二步,检查下具体异常是啥;首先找下抛出的异常是啥,
2023-03-08 15:39:08
1817
原创 什么是web框架?
我们解释一个概念的时候,通常会用到其他更多的概念去解释它,如果听的人不理解解释它的概念,那么这个解释是失败的,因此首先要回答一下解释web框架中所用到的概念。回答这个问题前,首先需要需要回答如下子的问题:什么是服务器应用;如何编写web程序;软件框架的概念以bs架构为例子解释。浏览器、服务器构成的b/s软件架构风靡全球,b为浏览器,s为服务器。
2023-02-24 17:28:53
3023
1
原创 图|AcWing 846. 树的重心
在树中:有n个结点,则有n-1条边,由于用图的方式表示树,也要在意每条边的方向,由于每条边两个方向,因此一共最多2*(n-1)条边,方便起见开2N条边。这里的e存储的是边,一个e对应着一个有向边。j = e[i],代表着i这个点到j有条边。由于是树,肯定存在i = e[j];算法不难理解,实现比较麻烦,sum与res的使用很巧妙,是一个工具写法,可以背下来。学习静态链表写法对于找工作有什么意义呢?由于是双向的,所以e得开2N,ne也是如此。2023年2月2日17:17:53。
2023-02-02 19:05:42
132
原创 动态规划|188. 买卖股票的最佳时机 IV
dp[i][j][1]代表第i天时,第j次买卖时持有股票时的收益;dp[i][j][0]代表第i天时,第j次买卖时持有股票时的收益。
2023-01-16 15:08:44
182
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人