🌟 你可能感兴趣的文章|Posts you might be interested in
Junior|大三
『OSPP2023』我与 OSPP 的故事 —— 项目经验分享
你还惦记着你那二面呢|Allow Everything to Happen
Sophomore|大二
阿里云OSS被刷,我交了1000RMB学费
『OSPP2023』我与 OSPP 的故事 —— 从听闻到中选
2023五一总结:近况与将来
告别ELK|轻量级日志收集系统Grafana Loki初上手
第五届字节跳动青训营项目总结
写在大二下开学之初
『CI/CD』结合GitHub Actions+Docker实现自动化部署
写在10月的最后一天
『Linux』一个多月来将 Ubuntu 22.04 作为主力系统的感想
『JWT』在 go-zero 框架中使用 JWT 鉴权
『总结』2022 国庆前阶段性总结
『hduhelp』如何在项目中接入助手 OAuth
『hduhelp』如何使用助手鉴权/使用助手的开放服务
『随笔』面试官竟是我自己 —— 2022 杭助秋招面试工作感想
GORM 入门笔记(一)前言与介绍
『Twikoo』解决 Vercel.app 在国内被墙导致无法使用的问题
『随笔』写在新学年伊始
Freshman|大一
『GitHub』学生身份认证问题
『随笔』618桌面改造计划
『字节青训营-3rd』结营感想(待后续)
『Git』如何使用 Git 参与杭助的项目
『WSL』在 WSL 中使用主机的代理(以 Clash 为例)
『实记』“韵味杭州”测试赛球童志愿经历
『总结』大一下期中总结
『Others』第三届字节跳动青训营 - 后端专场 早知晓直播会议纪要
Gin ...
简明 Docker + GitHub Actions 自动化部署教程
我之前其实写过一些 cicd 的教程,但是写的太烂了,这篇算重构
直入正题,我会用我的一个 gin-rush-template 来做为 demo 演示
你可以模仿下面的过程为自己的项目实现自动化部署
我的 demo 的其实写的很烂的,但是你只需要知道它有三个特点,无需关注其他细节:
会从 config/config.yaml 读取配置文件
需要连接 MySQL 依赖
能提供一个 /ping 接口
我们先做到让它在本地跑起来,首先 clone 下来,然后跟随下面的操作
12345678# 复制一份配置文件cp config/config.example.yaml config/config.yaml# 运行 MySQL 依赖docker-compose -f docker-compose-env.yml up -d# 运行 Go 程序go run main.go
如果没有报错,并且 curl 能正常提供服务,那么就没有问题了
12curl http://127.0.0.1:8080/ping{"message":"pong"}
或者你可以在浏览器中手动访问 http://127.0.0.1:8080/ping
体验手动部署
安装 Docker
接下来将体验手动编译并部署 Docker Image 到服务器,我以本地 OrbStack 提供的 Debian12 arm64 虚拟机为例
123456789101112131415161718nx@debian:~$ screenfetch _,me ...
Kitex 负载均衡源码解读之加权负载均衡算法
不多废话,直入正题
Kitex 的负载均衡相关源码位于 pkg/loadbalance ,具体结构如下
12345678910111213141516171819202122nx@NXsMacBook-Pro kitex % tree pkg/loadbalancepkg/loadbalance├── consist.go├── consist_test.go├── dummy_picker.go├── interleaved_weighted_round_robin.go├── iterator.go├── lbcache│ ├── cache.go│ ├── cache_test.go│ ├── hookable.go│ ├── hookable_test.go│ └── shared_ticker.go├── loadbalancer.go├── weighted_balancer.go├── weighted_balancer_test.go├── weighted_random.go├── weighted_random_with_alias_method.go├── weighted_round_robin.go└── weighted_round_robin_test.go2 directories, 17 files
我们先去 loadbalancer.go 看见接口定义,感觉还是很清晰的
12345678910111213141516// Picker picks an instance for next RPC call.type Pic ...
如何配置 GPG 密钥
使用 GPG 签名 commit 最大的好处就是有一个好看的 Verified 标签
当然主要是为了安全啦!
主要流程就是在本地生成一个,然后修改 git 的配置文件(可以借助 IDE),最后把这个密钥上传到 GitHub
https://www.jetbrains.com/help/go/2023.3/set-up-GPG-commit-signing.html
https://docs.github.com/en/authentication/managing-commit-signature-verification/generating-a-new-gpg-key
官方文档讲的其实很好了,当时我做下来发现有些问题
12345678error: gpg failed to sign the data:[GNUPG:] KEY_CONSIDERED FAD374693582B8AEE393EF000F3C2EC536BDA929 2[GNUPG:] BEGIN_SIGNING H10[GNUPG:] PINENTRY_LAUNCHED 91953 curses 1.2.1 not a tty xterm-256color :0.0 ? 501/20 0gpg: signing failed: No such file or directory[GNUPG:] FAILURE sign 83918929gpg: signing failed: No such file or directoryfatal: failed to write commit object
最后参 ...
『代码随想录』单调栈(Monotonic Stack)
DAY 58
每日温度
12345678910111213func dailyTemperatures(temperatures []int) []int { n := len(temperatures) stack := make([]int, 0, n) ans := make([]int, n) for i, temperature := range temperatures { for len(stack) > 0 && temperature > temperatures[stack[len(stack)-1]] { ans[stack[len(stack)-1]] = i - stack[len(stack)-1] stack = stack[:len(stack)-1] } stack = append(stack, i) } return ans}
下一个更大元素 I
不同之处是栈中存的是元素的值
123456789101112131415161718192021func nextGreaterElement(nums1 []int, nums2 []int) []int { stack := make([]int, 0, len(nums2)) m := map[int]int{} for _, num : ...
飞镖、骰子和硬币:从离散分布中抽样
本篇是原文 Darts, Dice, and Coins: Sampling from a Discrete Distribution 的全文中文翻译版本
在被我的导师拉着参与 cloudwego/kitex 的一个负载均衡算法的改进时 #1184 ,他指出可能可以使用 Alias Method(别名方法)来实现更为高效的负载均衡。于是我仔细地研究了本文的英文原文(链接如上), 起初我想寻求一个中文译版,但貌似没有找到
于是鄙人借助 GPT 翻译与个人的理解进行部分词汇修正,手打大部分 LaTeX 公式与表格后完成本文,如有谬误,欢迎指出
PS:暗黑主题可能不适合本文阅读,可在右下角切换
原文最近更新日期:December 29, 2011
今年早些时候,我在 Stack Overflow 上提出了一个关于不公平的骰子的数据结构的问题。具体来说,我感兴趣的问题是:
“你有一个 nnn 面的骰子,第 iii 面被掷出的概率为 pip_{i}pi。模拟掷骰子的最有效数据结构是什么?”
这种数据结构可以用于多种目的。首先,你可以用它来模拟一个公平的六面骰子,通过给骰子的每个面分配 16\frac{1}{6}61 的概率,或者模拟一个公平的硬币,通过模拟一个两面的骰子,每面有 12\frac{1}{2}21 的概率出现。你还可以使用这个数据结构直接模拟两个公平六面骰子掷出的总和,通过使用一个 11 面的骰子(面数为 2、3、4、…、12),每个面都适当地加权,以表示如果使用两个公平骰子,这个总数出现的概率。然而,你也可以使用这个数据结构来模拟不公平的骰子。例如,如果你在玩花 ...
『代码随想录』动态规划(Dynamic Programming)
DAY 38
斐波那契数
123456789101112func fib(n int) int { if n == 0 || n == 1 { return n } dp := make([]int, n+1) dp[0], dp[1] = 0, 1 for i := 2; i <= n; i++ { dp[i] = dp[i-1] + dp[i-2] } return dp[n]}
爬楼梯
1234567891011func climbStairs(n int) int { if n == 1 { return 1 } dp := make([]int, n+1) dp[0], dp[1] = 1, 1 for i := 2; i <= n; i++ { dp[i] += dp[i-1] + dp[i-2] } return dp[n]}
使用最小花费爬楼梯
12345678func minCostClimbingStairs(cost []int) int { n := len(cost) dp := make([]int, n+1) for i := 2; i <= n; i++ { dp[i] = min(dp[i-1]+cost[i-1], d ...
『代码随想录』贪心(Greedy)
DAY 31
分发饼干
遍历每块饼干,尝试将其分配给胃口最小的那个尚未满足的孩子
1234567891011121314func findContentChildren(g []int, s []int) int { sort.Ints(g) sort.Ints(s) n, m := len(g), len(s) i, j := 0, 0 for i < n && j < m { if s[j] >= g[i] { i++ } j++ } return i}
摆动序列
直接找出山峰和山谷就行,那些山腰的元素全都不要
12345678910111213141516171819202122func wiggleMaxLength(nums []int) int { n := len(nums) if n < 2 { return n } prev := nums[1] - nums[0] ans := 2 if prev == 0 { ans = 1 } for i := 2; i < n; i++ { diff := nums[i] - nums[i-1] if diff > 0 && p ...
『代码随想录』回溯(Backtracking)
DAY 24
77.组合
很经典的回溯算法
123456789101112131415161718func combine(n int, k int) [][]int { ans := [][]int{} curr := []int{} var dfs func(s int) dfs = func(s int) { if len(curr) == k { ans = append(ans, append([]int{}, curr...)) return } for i := s; i <= n; i++ { curr = append(curr, i) dfs(i + 1) curr = curr[:len(curr)-1] } } dfs(1) return ans}
做了一点剪枝
123456789101112131415161718192021 package main func combine(n int, k int) [][]int { ans := [][]int{} curr := []int{} var dfs func(s i ...
『代码随想录』二叉树(Binary Tree)
DAY 14
稍微又复习了一遍二叉树的基础
144.二叉树的前序遍历
123456789func preorderTraversal(root *TreeNode) []int { if root == nil { return []int{} } ans := []int{root.Val} ans = append(ans, preorderTraversal(root.Left)...) ans = append(ans, preorderTraversal(root.Right)...) return ans}
当然你还可以压行,就是可读性不行
123456func preorderTraversal(root *TreeNode) []int { if root == nil { return []int{} } return append([]int{root.Val},append(preorderTraversal(root.Left),preorderTraversal(root.Right)...)...)}
94.二叉树的中序遍历
123456789func inorderTraversal(root *TreeNode) []int { if root == nil { return []int{} ...
Mac Windows 网线直连文件传输
今天又学到一个小技巧,使用一条网线直连两台 PC 进行文件传输
我是把 Mac 上的文件传到 Windows 上,但其实两台 Windows 也大同小异
首先当然是网线插上
下一步是自己手动改一下 IP 到同一网段,之后 ping 一下,能 ping 通就算没问题
传输文件使用 HTTP 其实最方便,直接用 py 起一个 http server
12cd /path/to/dirpython3 -m http.server
然后你就可以通过浏览器访问了
本地看上去没问题之后就可以在另一端访问了
我记得下载是满速的,千兆以太网直接吃满,嘎嘎快(
『代码随想录』栈与队列(Stack & Queue)
DAY 10
232.用栈实现队列
因为栈和队列的出队顺序是反的,所以再来个栈倒腾一下就是正的了
123456789101112131415161718192021222324252627282930313233343536373839404142type MyQueue struct { in []int out []int}func Constructor() MyQueue { return MyQueue{ in: []int{}, out: []int{}, }}func (this *MyQueue) Push(x int) { this.in = append(this.in, x)}func (this *MyQueue) shift() { // 倒腾一下 for len(this.in) != 0 { this.out = append(this.out, this.in[len(this.in)-1]) this.in = this.in[:len(this.in)-1] }}func (this *MyQueue) Pop() int { if len(this.out) == 0 { this.shift() } ans := thi ...
『代码随想录』字符串(String)
DAY 8
344. 反转字符串
朴实无华
1234567func reverseString(s []byte) { n := len(s) for i := 0; i < n/2; i++ { s[n-i-1], s[i] = s[i], s[n-i-1] }}
541.反转字符串 II
朴实无华的递归
1234567891011121314151617181920func reverseStr(s string, k int) string { n := len(s) if n <= k { return reverse(s) } else if n > k && n < 2*k { return reverse(s[:k]) + s[k:] } else { return reverse(s[:k]) + s[k:2*k] + reverseStr(s[2*k:], k) }}func reverse(s string) string { bytes := []byte(s) n := len(bytes) for i := 0; i < n/2; i++ { bytes[i], bytes[n-i-1] = bytes[n-i-1], bytes[i ...
『代码随想录』哈希表(Hash Map)
DAY 6
242.有效的字母异位词
这题没什么好说的
12345678910111213141516171819func isAnagram(s string, t string) bool { m := map[rune]int{} for _, c := range s { m[c]++ } for _, c := range t { m[c]-- } for _, v := range m { if v != 0 { return false } } return true}
349.两个数组的交集
123456789101112131415161718func intersection(nums1 []int, nums2 []int) []int { m := map[int]bool{} for _, v := range nums1 { m[v] = true } ans := []int{} for _, v := range nums2 { if m[v] == true { ans = append(ans, v) m[v] ...
『代码随想录』链表(Linked List)
DAY 3
本篇部分题目在 『算法拾遗』链表(Linked List) 中已经做过
203.移除链表元素
还有一个递归版,但是那个空间复杂度是 O(n)
12345678910111213func removeElements(head *ListNode, val int) *ListNode { dummy := &ListNode{Next: head} curr := dummy for curr.Next != nil { if curr.Next.Val == val { curr.Next = curr.Next.Next } else { curr = curr.Next } } return dummy.Next}
707.设计链表
分别写了单向链表和双向链表两个版本
单向链表双向链表1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374type MyLinkedList struct { head *LinkNode size int}type LinkNode struct ...
『代码随想录』数组(Array)
DAY 1
本篇内容包含数组的两类经典题目:
二分查找
双指针
704.二分查找
相关链接
代码随想录
视频讲解
边界条件注意
Carl 哥的视频讲的很清楚,墙裂建议观看
主流的就是两种写法,左闭右闭和左闭右开,如果你选择了一种写法,就应该全程保持这一种写法
左闭右闭
起始区间为 [0,n - 1] ,继续循环的条件是区间合法,也就是 left <= right
更新左右边界值时,由于 mid 已经被排除,所以更新为 mid + 1 与 mid - 1
左闭右开
起始区间为 [0,n] ,因为 [1,1) 不是一个合法的区间(左右不能相等),所以 left < right
更新左右边界值时,因为左闭所以 mid + 1 ,而右开所以 mid (已经排除了但是右边界是开的)
整数溢出问题
计算 mid 通常使用 (left + right) / 2
但是如果 left 和 right 很大,就可能溢出,可以使用 left + (right - left) / 2
左闭右闭区间左边右开区间12345678910111213141516func search(nums []int, target int) int { n := len(nums) left, right := 0, n-1 // 左闭右闭 for left <= right { // [1,1] 可以是一个合理区间,所以要有等号 mid := (left + right) / 2 if nums[mid] > ...