🌟 你可能感兴趣的文章|Posts you might be interested in
Latest Resume|最近在找实习哦
Junior|大三
即将到来的生活,充满未知与期待
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 入门笔记(一)环境搭建、简单的路由配置
『WSL』解决每次启动后 ...
『OSPP2023』我与 OSPP 的故事 —— 从听闻到中选
6月26日下午3点,OSPP2023 中选结果正式发布,全球共有 1486 人成功申请,最终中选人数为 504 人
鄙人非常荣幸地成为了这 504 个幸运儿的一份子,特撰此文,记录 我与 OSPP 的故事 —— 从听闻到中选
当然,我也希望这篇博客能够吸引更多人参与开源,为开源项目做出自己的贡献
给「杭电助手」打点小广告
本次开源之夏活动,杭州电子科技大学共中选 13 人,其中 8 人来自杭电助手
杭助本次共参与 11 人,中选率高达 8/11
(另外今年另有 1 人中选 GSoC,1 人 LFX Mentorship )
欢迎热爱技术的同学们填报杭州电子科技大学,欢迎同学们选择杭电助手技术部! 查看推文
写在前面
这里是对不了解开源活动的同学进行一点飞速的补充,简短地谈一下我的理解
其实已经有很多文章讲的很好了,这里我推荐一篇杭助成员「爱飞的鸟」的 Before Good First Issue
开源活动是什么
开源活动通常是由开源社区、组织或公司组织的活动,目的在于吸引更多的人(特别是学生)参与开源,帮助构建开源项目,增加开源社区热度,推广开源文化与价值观,为开源事业作出贡献
比较有名的比如 LFX Mentorship、谷歌的 GSoC、国内的 OSPP、GLCC 等
一般的形式是这样的:由活动主办方提供平台与资金,吸引各路开源社区/组织入驻,社区挑选目前要做的一些活作为若干子项目(写清楚具体要做什么事情,最终达成什么目的),并且分配至少一个导师专门负责这个项目(大多数是一个)
学生呢需要给导师写 Proposal(申请书),阐述自己对这个项目的想法(如何 ...
Hexo + Butterfly 建站指南(〇)前言
恭喜你发现了宝藏!🎉🎉🎉
本系列是这个博客网站的搭建教程,个人的踩坑经历也会一并记录
因为需要面向小白,所以很多地方会讲的比较细碎
这个博客系统的运作流程是:在本地安装配置 Hexo框架 + Butterfly主题 ,然后根据 Markdown文档 生成静态文件,再推送至云端,公网上只需要一个网页服务器就行
目录
正文
Hexo + Butterfly 建站指南(〇)前言
Hexo + Butterfly 建站指南(一)Hexo 框架
Hexo + Butterfly 建站指南(二)部署至个人站点或 GitHub Pages
Hexo + Butterfly 建站指南(三)Butterfly 主题
Hexo + Butterfly 建站指南(四)Twikoo 评论系统
Hexo + Butterfly 建站指南(五)日常写作
Hexo + Butterfly 建站指南(六)PicGO + Gitee 图床(已废弃)
Hexo + Butterfly 建站指南(七)阿里云 OSS 图床
Hexo + Butterfly 建站指南(八)使用 KaTeX 数学公式
附录
『Twikoo』解决 Vercel.app 在国内被墙导致无法使用的问题
Hexo 首页添加 GitCalender 提交日历
阿里云OSS被刷,我交了1000RMB学费!
鸣谢
Hexo 官网
Butterfly 主题官方文档
Hexo+Butterfly主题美化 | 唐先森の博客(这位是真大佬)
PicGo+码云(gitee)图床环境搭建
懒人包
因为整个过程还是比较繁琐的,记忆里我连着折 ...
字节二面挂,还是人太菜了
字节一面
自我介绍
简单介绍字节青训营项目
是组队的吗
项目耗时
项目收获的点
ELK 是你们搭建的吗
ELK 的软件安装
数据流大概是怎样的
是通过什么写到 Logstash 里的
Logstash 的功能
你们用的的 fail2ban 是什么
traceID 介绍
微服务框架用的什么
traceID 在框架中是怎么传递的
对于异步的请求怎么处理的
这个项目的挑战和难点
Golang 的 Panic 关键字
Panic 怎么恢复
不加 defer 会怎样
为什么不能恢复
go 的方法的传值,传递切片,是怎么传的,在里面改变切片,外部能感受到吗
你说的副本是什么概念
在函数中 map 改变 kv,外部能感受吗
传递结构体,一般传值还是传指针
GMP 模型
在一个程序中不断起 goroutine,它的队列最终是个什么状态
一个 G 在一个 M 上执行的时间过长,会怎样调度
是通过什么策略控制的呢
刚才说的太长时间你有个时间上的概念吗,什么时间算太长
协程和线程的区别
其他的优势,怎么时候选择协程,什么时候不应该选协程
线程和协程,IO 密集型和 CPU 密集型哪个更适合
他节省的时间是怎么体现的
如果我找其他的线程呢?有什么区别
你比较擅长什么
MySQL 为什么使用 B+ 树
分裂与结合,这个是 B 树与 B+ 树的区别吗
放在叶子结点上导致了什么呢
还有其他的吗
了解过跳表吗
时间复杂度一样吗,跳表和 B+
为什么 Redis 的 zest 使用了跳表,为什么不用 B+
MySQL 和 Redis 这两种的本质区别
有没有可能这两种分别适用于内存和磁盘
你有什么想问的
简单 ...
阿里云OSS被刷,我交了1000RMB学费!
大致经过
垂死病中惊坐起😱
事情发生在 8 月 8 日凌晨,凌晨三点我突然看见手机上的消息
我一开始是疑惑的,我的 OSS 是用来当做图床的,一个月也用不了几个钱
账号里记得还有 20 多块钱,怎么会这么快用完
然后我进阿里云一看,哇,我被人刷了?
最后发现被刷了 3.57 TB,请求了 138 万次
哇,我从没想到过这种事情会发生在我的身上
而且我停机之后他还一直在刷,根本不带停的(
我想,算了,300 块交学费得了,以后得好好重视
然后我下午就看见了——
1000 软妹币的账单😭
1000 RMB!这下真的被上课了😱
由于账单会有几小时的延迟,很多人说为什么欠费了不自动停,其实等你欠费的时候,人家已经刷完了
这次在我发现的时候,就已经结束了
真的太可怕了,直接大出血
花了好久才缓过来劲
可能的原因
我感觉最可能的原因,是我前段时间我写的一个玩具被人发到 Twitter 上了(属于是间接出圈
然后就别人盯上了🥹
当时还挺高兴的,这属于是出名的代价吗
寻求客服
最后我想看看找一手客服,其实我是不报希望的,看了一堆案例都是自己承担的
结果的确如此,真的是交了 1000 RMB 学费了
解决方案
事已至此,接下来的事情就是寻找解决方案了
在与群友交流和不断 Google 后,我总结了几种比较好的图床解决方案:
国内云 OSS + 国内云 CDN(如果你很在意国内的访问速度)
国内云 OSS + Cloudflare(比较推荐的方案,但是国内访问不会很快)
Cloudflare R2(如果你有信用卡)
某些奇技淫巧
国内云 OSS + ...
『Golang』并发编程之通道(Channel)
通道(Channel)
通道是什么,为什么使用通道
「不要通过共享内存来通信,而应该通过通信来共享内存」
通道可以在多个 goroutine 之间传递数据
一个通道相当于一个先进先出(FIFO)的队列。也就是说,通道中的各个元素值都是严格地按照发送的顺序排列的,先被发送通道的元素值一定会先被接收。元素值的发送和接收都需要用到操作符 <-。我们也可以叫它接送操作符。一个左尖括号紧接着一个减号形象地代表了元素值的传输方向
如何初始化通道
12345678func main() { ch1 := make(chan int, 3) ch1 <- 2 ch1 <- 1 ch1 <- 3 elem1 := <-ch1 fmt.Printf("The first element received from channel ch1: %v\n",elem1)}
使用 make 函数声明并初始化通道
通道的容量是 int 类型,但是不能小于 0 (缓冲通道和非缓冲通道)
通道的发送和接收操作都有哪些基本的特性
对于同一个通道,发送操作之间是互斥的,接收操作之间也是互斥的
发送操作和接收操作中,对元素值的处理都是不可分割的
发送操作在完全完成之前会被阻塞,接收操作也是如此
元素值从外界进入通道时会被复制
非缓冲通道的数据是直接从发送方复制到接收方
大多数情况下缓冲通道都会中转数据,如果发送时正好有人在等着接收,则会直接复制过去
什么时候会阻塞
正常情况下
缓冲 ...
『LeetCode-HOT-100』T41~T50
二叉树的层序遍历
简单的 BFS 练习
12345678910111213141516171819202122232425262728293031func levelOrder(root *TreeNode) [][]int { ans := [][]int{} if root == nil { return ans } queue := []TreeNode{} queue = append(queue, *root) for len(queue) != 0 { tmpAns := []int{} nextLevel := []TreeNode{} for len(queue) != 0 { curr := queue[0] queue = queue[1:] tmpAns = append(tmpAns, curr.Val) if curr.Left != nil { nextLevel = append(nextLevel, *curr.Left) } if curr.Right != nil { nextLevel = append( ...
『LeetCode-HOT-100』T31~T40
颜色分类
这真的是 Medium 吗,哈哈哈😂
123456789101112131415161718192021222324func sortColors(nums []int) { var red, white, blue int for i := 0; i < len(nums); i++ { switch nums[i] { case 0: red++ case 1: white++ case 2: blue++ } } for i := 0; i < red; i++ { nums[i] = 0 } for i := red; i < red+white; i++ { nums[i] = 1 } for i := red + white; i < red+white+blue; i++ { nums[i] = 2 } return}
最小覆盖子串
很好的滑动窗口的题目
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849func minWindow(s string, ...
『LeetCode-HOT-100』T21~T30
全排列
板子题,不解释
123456789101112131415161718func permute(nums []int) (ans [][]int) { var dfs func(begain, end int) dfs = func(begain, end int) { if begain == end { // 切片是引用类型,需要深拷贝一下 tmp := make([]int, len(nums)) copy(tmp, nums) ans = append(ans, tmp) } for i := begain; i <= end; i++ { nums[begain], nums[i] = nums[i], nums[begain] dfs(begain+1, end) nums[begain], nums[i] = nums[i], nums[begain] } } dfs(0, len(nums)-1) return}
旋转图像
感觉纯脑筋急转弯,在草稿纸推演一波应该就行👀
123456789func rotate(matrix [][]int) { n := len(matrix) for i := 0; i &l ...
『LeetCode-HOT-100』T11~T20
有效的括号
栈的经典题目了属于是
12345678910111213141516171819202122232425262728293031323334353637383940func isValid(s string) bool { stack := "" for k := 0; k < len(s); k++ { i := s[k] switch i { case '(': stack = stack + string(i) case ')': if stack != "" && stack[len(stack)-1] == '(' { stack = stack[:len(stack)-1] } else { return false } case '{': stack = stack + string(i) case '}': if stack != "" && stack[len(stack)-1] = ...
『LeetCode-HOT-100』T1~T10
两数之和
暴力枚举
暴力枚举 i 和 j ,没什么好说的
12345678910func twoSum(nums []int, target int) []int { for i, _ := range nums { for j := i + 1; j < len(nums); j++ { if nums[i]+nums[j] == target { return []int{i, j} } } } return nil}
哈希表
对于每一个 x,检查以前有没有遍历过另一半
12345678910111213func twoSum(nums []int, target int) []int { m := map[int]int{} for i, x := range nums { j, ok := m[target-x] if ok { return []int{i, j} } m[x] = i } return nil}
两数相加
一开始想着能不能抽离出一个函数用来维护 ans 链表,结果这东西不能解决最后的进位问题
1234567891011121314 ...
『算法拾遗』重学主流排序算法
衡量排序算法的好坏时间复杂度
包含最好情况、最坏情况和平均情况
数据有序度不同的影响
空间复杂度
是否是原地排序
稳定性
排序后,相同元素之间的顺序是否会改变
O( n^2 )
冒泡排序(Bubble Sort)
依次比较相邻的元素,如果顺序错误,则交换它们。每轮排序将最大(或最小)的元素“冒泡”到正确的位置
简单易懂,但效率较低,不适用于大规模数据排序
过程
初始化待排序数组,设为 arr ,数组长度为 n
外层循环:重复 n-1 次(即 i 从 0 到 n-2 ) 思考:为什么外层是n-1次
内层循环:重复 n-i-1 次(即 j 从 0 到 n-i-2 ) 思考:为什么内层是n-i-1次
比较 arr[j] 和 arr[j+1] ,如果 arr[j] 大于 arr[j+1] ,执行下一步,否则继续内层循环
交换 arr[j] 和 arr[j+1] 的位置
判断是否在本轮内层循环中进行了交换操作:
如果没有进行交换,说明数组已经有序,提前结束排序
冒泡排序结束,数组 arr 已经按升序排列
性质
在排序没有完成之前,小的数会逐步往前移,大的数会逐步往后移动
每轮排序至少会让一个最大元素放置在正确位置,重复 n−1n-1n−1 次,就完成了 nnn 个元素的排序
是稳定的排序算法
空间复杂度:冒泡排序的空间复杂度为 O(1)O(1)O(1),它在原地进行排序,不需要额外的内存空间。
最优情况:冒泡排序的最优情况是输入数组已经有序。在这种情况下,只需要进行一次遍历,没有元素交换,时间复杂度为 O(n)O(n)O(n)
最坏 ...
后端层与层传递结构体时自动转换类型
未完成
7 月 11 日更:
在后端层与层传递的时候,很多情况下都需要手动把一个结构体的内容搬到另一个结构体里面,也可能会做一下简单的转换
这时候就可以用 jinzhu 的 https://github.com/jinzhu/copier
我很早就听说了这个东西,但是一直没敢用,毕竟小项目东西也不多,然后自己手动搬一下比较稳妥,怕会有什么问题
但是后面变大了之后感觉适合 copier 的场景更多了,比如一个时间字段,你在数据库 model 里是 time.Time , 到下一层要转换成 int64 的 Unix 时间戳
这时候就可以使用 copier.Copy() ,同时让那个结构体实现转换的方法,就可以在 copy 的同时自动转成 int64
后端发送 lua 脚本给 Redis 执行
未完成
7 月 11 日更:
之前在交流的时候发现了一个很巧的方法,就是在执行复杂 Redis 操作的时候,可以发一个 lua 脚本过去
细节记不清了,大概就是你一句一句写的话,效率是不及直接发一个脚本过去高的
具体的我还没试,等试了之后再看看👀
如何在一个仓库中同时开发前后端项目
如图,今天在群里问了个小问题
TLDR; 直接说结论吧
小项目直接开子目录,然后可以分别独立打包或者使用 go embed
不同分支的方法应该没必要用
如果想做成两个独立项目就用 submodule
gpt 对 submodule 的介绍Git 的 Submodule 是一种在一个 Git 仓库中嵌套使用另一个 Git 仓库的机制。它允许你将一个 Git 仓库作为子项目嵌入到另一个 Git 仓库中,并且能够独立地管理子项目的版本和提交历史。
使用 Git Submodule 的主要目的是在一个项目中使用外部依赖,而不是将它们直接复制到项目目录中。这样做的好处是可以方便地更新和维护外部依赖,并且可以保持项目的独立性。
下面是使用 Git Submodule 的基本工作流程:
添加 Submodule:在主项目的仓库中,使用 git submodule add 命令添加一个子项目作为 Submodule。例如:
1git submodule add <URL to submodule> <submodule path>
这将在主项目中添加一个 Submodule,并将其克隆到指定的子目录中。
初始化和更新 Submodule:在主项目的仓库中,可以使用以下命令来初始化和更新 Submodule:
12git submodule init # 初始化 Submodule,只需执行一次git submodule update # 更新 Submodule,每次子项目发生变化时执行
git submodule init 命令会初始化 ...
『算法拾遗』链表(Linked List)
这两天在复习链表,我一想,这链表这么简单的东西还有什么复习的,简单过一遍不就行了
然而马上打脸,有些题目我居然还写不出来(乐
理论基础
先来点你肯定知道的东西,简单过一遍
是什么
如图所示,链表是一种链式结构,以最简单的单链表为例:
1234type ListNode struct { Val int Next *ListNode}
也就是头节点指向下一个节点,然后下一个节点再指向下一个节点,如果是尾节点就指向 NULL (或者说是 Golang 里的 nil )
基本操作
删除节点
让前面节点认为它的后面是后面的节点
删除的节点让 GC 自动回收掉即可
添加节点
让新节点指向后面节点,让前面节点指向新节点
链表的几种变体
有头链表
减少对头节点的特殊处理
双向链表
可以方便地找到前驱节点
对于一个有序链表,双向链表的按值查询效率要比单链表高一些。因为我们可以记录上次查找的位置p,每一次查询时,根据要查找的值与p的大小关系,决定是往前还是往后查找,所以平均只需要查找一半的数据。
循环链表
能解决约瑟夫问题
有头双向循环链表
buff 叠满,请见 【有头双向循环链表之美,这个数据结构简单又优雅,学会了不亏】
链表 vs 数组
插入删除
随机访问
数组
O(n)O(n)O(n)
O(1)O(1)O(1)
链表
O(1)O(1)O(1)
O(n)O(n)O(n)
必知必会的题目
707. 设计链表
实现一个链表,这里就以带头单链表为例
1234567891011121314151617181920212223 ...