- 博客(97)
- 收藏
- 关注
原创 Go的垃圾回收
V1.3标记清除+STW,这个比较好理解,就不详细阐述了。V1.5提出了三色标记法,伴随有STW新生的对象都会标记成白色,然后从根节点出发一次遍历,将遍历过的对象标记成灰色的,并且全局变量和栈中的对象置灰色。最后将灰色对象标记为黑色,直到没有灰色对象全部转换成黑色对象为止。将所有的白色对象全部回收。假设没有STW,在标记过程中很有可能出现引用关系的改变。一旦改变了这个关系(尤其是黑色对象直接指向白色对象),就会出现“误删除”的操作。上述情况只针对于下面两个条件:一个白色对象被黑色对象引用(
2022-05-21 20:08:16
346
1
原创 redis持久化之AOF
AOF持久化将redis服务器所执行的写命令来记录数据库状态,并保存到AOF文件中。1. 持久化的实现命令追加服务器在执行完一个写命令之后,该命令会被追加到服务器状态的aof_buf缓冲区的末尾 struct redisServer { // AOF缓冲区 sds aof_buf; }写入与同步服务器在结束一个事件循环之前,会调用flushAppendOnlyFile来判断是否要将aof_buf缓冲区的内容写入AOF文件中,根据不同的appendfsync实现不同的
2022-05-10 13:06:15
273
原创 redis持久化之RDB快照
redis持久化之RDBRDB二进制文件用于还原数据库1. RDB文件的创建和载入SAVE命令会阻塞redis的其他进程来创建RDB文件,期间会拒绝所有命令请求;而BGSAVE则会创建一个子进程,由子进程负责创建RDB文件,而父进程继续执行服务器接受的命令请求。在执行BGSAVE命令期间,服务器会拒绝SAVE命令,原因是为了避免父进程和子进程同时执行rdbSave调用,防止产生竞争条件;同样也会拒绝BGSAVE操作;假设正在执行BGSAVE,客户端发送BGREWRITEAOF命令,那么该命令
2022-05-10 09:37:44
422
原创 刷波存在感 0508 LC442 数组中的重复元素
最近参加了一下zj的青训营,时间和周赛冲突了,只能刷每日一题了,周赛有时间会补上的,下面进入正题题目:给你一个长度为 n 的整数数组 nums ,其中 nums 的所有整数都在范围 [1, n] 内,且每个整数出现 一次 或 两次 。请你找出所有出现 两次 的整数,并以数组形式返回。你必须设计并实现一个时间复杂度为 O(n) 且仅使用常量额外空间的算法解决此问题。func findDuplicates(nums []int) (ans []int) { // nums[i] 放在对应下标
2022-05-08 22:29:36
260
原创 Go 内存逃逸分享
内存逃逸是指编译器决定内存分配的位置,不需要程序员指定。在函数中申请一个新的对象:如果分配在栈中,则函数执行结束后可自动将内存回收;如果分配在堆中,则函数结束后需要交给GC进行处理。逃逸策略在函数中申请新的对象时,编译器会根据该对象是否被函数外部引用来决定是否逃逸:1. 函数外面没有引用,则优先放到栈中;2. 函数外部存在引用,则必定放到堆中。逃逸场景1)指针逃逸函数返回局部变量指针,函数内部定义的指针变量原本是在栈空间中开辟,但是函数将此局部变量返回出去了,那么指向该变量的
2022-04-29 22:55:15
293
原创 Go defer原理分析
defer用于延迟函数的调用,常用于关闭文件或者关闭锁的场景。defer语句采用类似栈的方式,每遇到一个defer就会把defer后面的函数压入栈中,在函数返回前再把栈中的函数依次取出执行。一般函数正常返回时会执行被defer延迟的函数,特别的遇到return和panic时也会触发延迟函数。defer作用于资源释放(关闭文件句柄、数据库连接、停止定时器ticker以及关闭管道)、流程控制(控制函数执行顺序,如wait.Group)和异常处理(recover()),但是defer关键字只能作用于函数或
2022-04-21 16:05:56
311
原创 Go map底层原理分析
mapGo的map底层是用hash表实现的。支持字面量初始化和内置函数make初始化。 m := map[string]int{"apple" : 2,"banana" : 3,} m := make(map[string]int, 10)make初始化map时指定容量可以有效减少内存分配的次数,有利于提升性能。map的增删改查操作 m := make(map[string]string, 10) m["apple"] = "red" m["apple"] = "green" dele
2022-04-19 22:22:44
976
原创 Go GMP模型原理分析
GMP模型G: goroutine 表示Go协程,每一个Go关键字都会创建一个协程.M: machine 表示工作线程,有操作系统调度.P: processor 表示处理器,包括运行Go代码的必要资源,以及调度goroutine的能力。M必须持有P才可以执行代码,M会被系统调用阻塞。P的个数在程序启动时决定,默认等于CPU数量。M的个数通常稍大于P,因为除了运行Go代码,runtime包还有其他内置任务需要处理。在I/O密集型应用中,可以将GOMAXPROCS设置得大一些。上图是协程从创建到
2022-04-18 21:30:54
343
原创 Go goroutine原理分析
协程进程的概念:是资源调度的基本单位,是应用程序的启动实例,每个进程都有独立的内存空间,不同进程通过进程间的通信方式来通信。(方式有管道pipe、命名管道FIFO、消息队列MQ、信号量semaphore、共享内存shared memory、信号signal、内存映射mapped memory和Socket)线程的概念:是程序执行的基本单位,线程从属于进程,每个进程至少包含一个线程,线程是CPU调度的基本单位,多个线程之间可以共享进程的资源并通过线程间的通信方式来通信。(方式有信号、锁机制、条件变量和信
2022-04-18 10:40:18
155
原创 Go slice原理分析
slice原理分析slice也称动态数组 make格式创建 s1 := make([]int,12) // 指定长度 s2 := make([]int,10,100) // 指定长度len和容量cap 字面量形式 s3 := []int{} // 需要注意空切片其值不是nil s4 := []int{1,2,3} // 长度为3的切片 从数组或者切片中截取切片 arr := [5]int{1, 2, 3, 4, 5} s5 := arr[0:2] // 左闭右开 s6 := s5[0:
2022-04-17 15:51:41
337
原创 Go channel原理分析
channel原理分析数据结构 type hchan struct { qcount uint // 当前队列中剩余的元素个数 dataqsiz uint // 环形队列的长度,即为缓冲区的大小 buf unsafe.Pointer // 指向环形队列的指针 elemsize uint16 // 管道中元素的大小 closed uint32 // 管道是否关闭 elemtype *_type
2022-04-17 12:46:59
301
原创 LeetCode 576 出界的路经数
题目地址解题思路利用三维数组实现动态规划,dp[i][j][k],i表示最大maxMove数,j和k表示从startRow和startColumn移动到这的路径数,如果i+1就是增加一步出界了,就直接累加上count就ok,否则需要更新dp,具体代码如下。package mainimport "fmt"const mod int = 1e9 + 7var dirs = []struct{ x, y int }{{-1, 0}, {1, 0}, {0, -1}, {0, 1}}f
2022-04-13 20:02:05
284
原创 LeetCode 39 组合总和
搜索回溯算法,我算是和回溯干上了,周赛也遇到,无奈还没学会,花点时间去攻克一下了package mainimport "fmt"func combinationSum(candidates []int, target int) (ans [][]int) { var dfs func(start int, tmp []int, sum int) dfs = func(start int, tmp []int, sum int) { if sum >= target { /
2022-04-13 15:15:58
202
原创 LeetCode 288 周赛AC*2
作为一个一直1AC的选手来说,能够A掉两题真的超级开心,可能是前两题比较简单吧,就直接上截图吧。第一题代码func largestInteger(num int) int { s := strconv.Itoa(num) n := len(s) odd, even := []int{}, []int{} vis := []int{} for i := 0; i < n; i++ { if s[i]%2 == 0 { odd = append(odd, -int(s[i
2022-04-10 15:06:46
238
原创 LeetCode 17 电话号码的字母组合
利用回溯的思想去求解本题,排列组合问题,先枚举每一个位置上数字对应的字母,每一层都是遍历选择,通过标记当前层数来判断当前是否已经完成一次排列组合,然后回退到上一层,以此类推。最后呈上代码package mainimport "fmt"var phoneMap map[string]string = map[string]string{ "2": "abc", "3": "def", "4": "ghi", "5": "jkl", "6": "mno", "7": "pqrs",
2022-04-02 19:21:58
187
原创 LeetCode 728 自除数
必须再次记录一下第二个双百题,2022年三月的最后一天打卡每日一题题目思路还是很清晰的,直接上代码func selfDividingNumbers(left int, right int) []int { if left > right { return []int{} } var cnt []int for i := left; i <= right; i++ { if check(i) { cnt = append(cnt, i) } } return
2022-03-31 19:18:50
180
原创 LeetCode 6 Z 字形变换
不难发现其中的规律,需要处理的点就是第一行和最后一行,此外,每一个完整的周期内都会存在两个元素,最后就是根据字符串的长度去判断最后一个周期的完整程度。package mainimport "fmt"func convert(s string, r int) string { n := len(s) if r == 1 || r >= n { return s } // 可以发现周期t t := 2*r - 2 ans := make([]byte, 0, n) // 循
2022-03-31 18:39:36
170
原创 LeetCode 169 多数元素
巧妙地利用抵消的方法,实现多数的求解。另外的方法就是构建一个字典,然后超过半数的key就是这个多数元素。这个空间复杂度是O(n),而上面的方法是O(1)的空间复杂度,时间复杂度都是一样的O(n)。func majorityElement(nums []int) int { candidate, count := 0, 0 for _, v := range nums{ // 统计count为正数时,candidate超过半数,为0就需要继续找candidate
2022-03-26 20:35:20
413
原创 LeetCode 662 二叉树最大宽度
这里采用同层次遍历相同的策略,同样是用数组存放结点,区别在于增加了结点所在当前层的序号,这个根据父节点的序号计算(左节点是父节点序号的2倍,右节点是父节点序号的2倍+1)。需要注意的是,计算宽度的时候别忘了➕1!!!/** * Definition for a binary tree node. * type TreeNode struct { * Val int * Left *TreeNode * Right *TreeNode * } */// 借助一
2022-03-24 10:41:39
154
原创 LeetCode 88 合并两个有序数组
这个题要求在数组nums1上直接排序,强行限制空间复杂度,但是如果你另外再开好一个数组,排好序之后,再拷贝到nums1也不是不行,但是应该不是出题者的初衷吧。考虑到头插法还需要移动nums1中后面的元素,用两个指针实现尾插法排序,具体代码如下:func merge(nums1 []int, m int, nums2 []int, n int) { length := m+n // 对应各自下标 m-- n-- length-- for m>=
2022-03-23 15:51:32
91
原创 LeetCode 25 k个一组反转链表
/** * Definition for singly-linked list. * type ListNode struct { * Val int * Next *ListNode * } */func reverseKGroup(head *ListNode, k int) *ListNode { hair := &ListNode{Next:head} prev:= hair for head !=nil { tail .
2022-03-21 18:13:59
570
原创 LeetCode 200 岛屿数量
继续二叉树的遍历,这次用到的是深度优先遍历dfsfunc numIslands(grid [][]byte) int { res := 0 m, n := len(grid), len(grid[0]) // 辅助数组记录是否已经访问 visited := make([][]bool,m) for i:=0;i<m;i++{ visited[i] = make([]bool,n) } var dfs func(i,j int
2022-03-20 19:35:07
662
原创 LeetCode 102 二叉树的层次遍历
对树和图的知识忘的差不多了,借助LC重新复习一遍下面是二叉树的层次遍历/** * Definition for a binary tree node. * type TreeNode struct { * Val int * Left *TreeNode * Right *TreeNode * } */func levelOrder(root *TreeNode) [][]int { ret := [][]int{} if root == n
2022-03-20 19:02:44
753
原创 LeetCode 136 只出现一次的数字
这题乍一看不难,但是加上了O(n)的时间复杂度和O(1)的空间复杂度之后,就变得让人无从下手了,我是想到了集合方法,a是a了,但是没达到要求,求证了官方题解之后才豁然,异或太妙了集合的方法def singleNumber(self, nums: List[int]) -> int: seen = set() for i in range(len(nums)): if nums[i] not in seen: seen.add(nums[
2022-03-15 08:44:33
346
原创 LeetCode 59 旋转矩阵II
class Solution: def generateMatrix(self, n: int) -> List[List[int]]: m = [[0] * n for _ in range(n)] row, col = 0, 0 num, direc = 1, 0 # 定义行进方向0,1,2,3分别代表右下左上,主要还是边界的判断 while num <= n ** 2: if .
2022-03-07 19:41:49
144
原创 LeetCode 142. 环形链表II
package main/** * Definition for singly-linked list. * type ListNode struct { * Val int * Next *ListNode * } */// 哈希表实现//func detectCycle(head *ListNode) *ListNode {// isExistsMap := map[*ListNode]int{}// for head!=nil{// if _,ok := i.
2022-03-04 15:06:14
114
原创 LeetCode 141. 环形链表
package main// 141 Linked List Cyclefunc hasCycle(head *ListNode) bool { // 快慢指针方法 //fast, slow := head, head //for slow != nil && fast != nil { // slow = slow.Next // fast = fast.Next.Next // if slow == fast{ // return true // } //}.
2022-03-04 13:39:06
195
原创 LeetCode 24 两两交换链表中的节点
方法1 递归实现func swapPairs(head *ListNode) *ListNode { if head == nil || head.Next == nil { return head } // 新的头节点是原先链表的第二个节点 newHead := head.Next // 这是把原先第二个节点后的链表看作一个整体 head.Next = swapPairs(newHead.Next) // 调换两个节点的顺序 newHead.Next = head // 返回新
2022-03-03 15:23:34
129
原创 LeetCode 206 反转链表
方法1. 遍历整个链表,同时反转节点的指向前驱节点func reverseList(head *ListNode) *ListNode { // 定义前驱节点 var pre *ListNode cur := head for cur != nil { // 找到当前节点的下一个指针 next := cur.Next // 按照题目要求,当前指针需要指向前一个节点 cur.Next = pre
2022-03-03 12:58:03
144
原创 Leetcode 94 二叉树的中序遍历
问题描述:给定一个二叉树的根节点 root ,返回它的 中序 遍历。提供两种解法1 递归实现func inorderTraversal(root * TreeNode) (res []int){ var inorder func(node *TreeNode) inorder = func(node *TreeNode){ if node == nil { return } inorder(node.Lef
2022-03-01 10:50:33
181
原创 Leetcode 15 三数之和
解题的关键在于去除重复的组合func threeSum(nums []int) [][]int { n := len(nums) sort.Ints(nums) ans := make([][]int, 0) for first := 0; first < n; first++ { if first > 0 && nums[first] == nums[first-1] { continue } third := n - 1 target :
2022-02-27 11:27:56
130
原创 LeetCode 977 有序数组的平方
1. 直接排放之后快速排序func sortedSqueres(nums []int)[]int{ // 用make动态生成一维数组 ans := make([]int, len(nums)) for i,v := range nums{ ans[i] = v * v } // 这里直接用自带的快排 sort.Ints(ans)}2. 双指针func sortedSquares(nums []int) []int { n :
2022-02-27 09:54:45
127
原创 Leetcode 11 盛最多水的容器
双指针法直接求解func maxArea(height []int) int { l, r := 0, len(height)-1 // 分别记录最大容器体积和当前容器体积 maxSize := 0 size := 0 for l < r { // 左右指针的坐标和对应数组中的较小值求的当前容器体积 size = (r - l) * min(height[l], height[r]) if size > maxSize { maxSize = size }
2022-02-26 16:06:00
62
原创 LeetCode 1995 统计特殊四元组
class Solution: def countQuadruplets(self, nums: List[int]) -> int: cnt = 0 if len(nums) < 4: return cnt # nums.sort() for a in range(len(nums)-3): for b in range(a+1, len(nums)-2): .
2021-12-30 01:50:37
237
原创 LeetCode 472 连接词
class Trie: def __init__(self): self.children = [None] * 26 self.isEnd = False # 根据插入的word构造字典树 def insert(self, word): node = self for ch in word: ch = ord(ch) - ord("a") if not node.ch.
2021-12-29 16:30:22
63
原创 LeetCode 208 实现 Trie (前缀树)
class Trie: def __init__(self): self.children = [None] * 26 self.isEnd = False def searchPrefix(self, prefix): node = self for ch in prefix: ch = ord(ch) - ord("a") if not node.children[ch]:.
2021-12-29 15:52:42
68
原创 LeetCode 825 适龄的朋友
def numFriendRequests(ages): n = len(ages) ages.sort() left = right = ans = 0 for age in ages: if age < 15: continue # 找到满足第一个条件的前一个age while ages[left] < 0.5 * age + 7: left += 1 .
2021-12-29 14:53:30
60
原创 LeetCode 1078 Bigram分词
class Solution: def findOcurrences(self, text: str, first: str, second: str) -> List[str]: res = [] list_items = text.split(' ') for i in range(len(list_items)-2): if list_items[i] == first and list_items[i+1] ==.
2021-12-29 14:18:37
83
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人