『代码随想录』哈希表(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] > ...
『OSPP2023』我与 OSPP 的故事 —— 项目经验分享
书接上文 『OSPP2023』我与 OSPP 的故事 —— 从听闻到中选 ,本文注重于描写项目开发的经历
项目基本信息
项目名称:为 Envoy Go 扩展建设插件市场
项目导师:纪卓志
项目描述:
Envoy 是当前最流行的网络代理之一,Go 扩展是 MOSN 社区为 Envoy 增加的 Go 生态基础,也是 MOSN 社区 MoE 框架的基础。
受益于Golang生态系统,研发可以轻松在 Envoy 实现插件用于更多的长尾场景,其中很多场景都是通用的。
本项目是为Envoy Go 扩展构建插件市场。在插件市场中,人们可以在插件市场中分享插件,选用已经存在的插件。通过插件市场,可以让 Envoy、MoE 生态变得更加开放、共享、丰富。
项目链接:
https://summer-ospp.ac.cn/org/prodetail/23f080259?lang=zh&list=pro
项目迭代经历
首先我想说这个项目的架构设计经历了多次变动,发现最后做出来的和最开始想的根本不是一个东西(笑)
一开始 OSPP 上简短的描述并不能让我了解太多,于是我开始翻 MOSN 的文档,并且和导师在 Issue 下交流更为详细的需求
需要实现的是一个插件市场,也就是类似于 VSCode Marketplace 或者 GitHub Marketplace 的效果,含插件提交、审核、版本管理和二进制构建分发等
我的构想是分为三个部分,GitHub、后端本体还有镜像仓库
开发者在自己的仓库里开发,如果要上架的话需要移交仓库权限到官方组织里,发布新版本就正常 Releas ...
你还惦记着你那二面呢|Allow Everything to Happen
「你还惦记着你那二面呢」
我真的好累,今天还吐了,感觉病了
我消失了很长一段时间,本来我想写一篇长文,记录我从 8 月 22 号返校到现在发生的所有事情
但是我真的好累,简单地说,就是诸事不顺,面试、亚运、学业…我不想写
我总是想在最后来一波升华,但是我其实并没有走出来,架构不出,我写不出来
我太想成功了,但这正是我没法成功的原因
就像你找东西,你越找就越找不到,经常是后面不经意的时候突然就冒出来了
就我现在这个状态,我想留一句话,与君共勉吧
Allow everything to happen|允许所有事情发生
最后,我还想说
爸爸妈妈,我永远爱你们❤️
浅析 JWT Refresh Token
最近逛 V 站又看见有人在讨论 JWT,感觉很多人讲的很乱,我想简单记录下我印象中的理解
Session
最开始应该是 session 方案,就是用户登陆后服务器返回客户端一个存根(token)来标识当前的会话
服务器在缓存中保存这个 token,用户请求时需要传递这个 token(不管你是使用 cookie header 还是 query)
每次请求服务器都在缓存中查找这个 token,并且找到当前会话的相关信息(比如说是哪个用户)
使用这种方案的优点:
强控制性:可以手动过期,如果想让某个用户下线就直接在缓存删除对应的键值对就行
可观察性:可以很清楚地看见当前的在线用户数量
使用这种方案的缺点:
性能需求高:因为每次请求都要查缓存,如果用户规模越大的问题越明显
对分布式不友好:他是有状态的,你必须共用一个缓存空间来存储数据
原始 JWT
为了克服上面的缺点, JWT 出现了
JWT (JSON Web Token ) 使用的是一种很巧妙的方法,他本身也是一个 string token,分为三部分
Header.Payload.Signature
Header,标识加密算法
Payload,你要存储的数据,比如说用户 ID 、权限 Level 与过期时间等,请注意这是外部可读的
Signature,加密算法签名
你需要注意的是,Payload 是前后端都可读的,但是可以使用 Signature 保证这个 Payload 是未更改的
工作流程是这样的:
用户登陆后服务器通过本地密钥计算并返回 JWT 给用户,用户请求时需要传递这个 JWT(不管你是使用 cookie ...
字节二面挂,还是人太菜了
字节一面
自我介绍
简单介绍字节青训营项目
是组队的吗
项目耗时
项目收获的点
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 (缓冲通道和非缓冲通道)
通道的发送和接收操作都有哪些基本的特性
对于同一个通道,发送操作之间是互斥的,接收操作之间也是互斥的
发送操作和接收操作中,对元素值的处理都是不可分割的
发送操作在完全完成之前会被阻塞,接收操作也是如此
元素值从外界进入通道时会被复制
非缓冲通道的数据是直接从发送方复制到接收方
大多数情况下缓冲通道都会中转数据,如果发送时正好有人在等着接收,则会直接复制过去
什么时候会阻塞
正常情况下
缓冲 ...
『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(申请书),阐述自己对这个项目的想法(如何 ...
『算法拾遗』重学主流排序算法
衡量排序算法的好坏时间复杂度
包含最好情况、最坏情况和平均情况
数据有序度不同的影响
空间复杂度
是否是原地排序
稳定性
排序后,相同元素之间的顺序是否会改变
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)
最坏 ...
『算法拾遗』链表(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 ...
2023五一总结:近况与将来
事情有点多,就简单说几句吧~
Your browser does not support the audio tag.
最近的事情
杭电助手团建
[{"url":"https://image.nickxu.me/202305042227317.png","alt":"image-20230504222737293"},{"url":"https://image.nickxu.me/202305042228416.png","alt":"image-20230504222810383"},{"url":"https://image.nickxu.me/202305042228652.png","alt":"image-20230504222817629"},{"url":"https://image.nickxu.me/202305042228681.png","alt":"image-20230504222822653"},{"url":"https://image.nickxu.me/202305042228729.png","alt":"image-20230504222830701"},{"url":"https://image.nickxu.me/202305042228227.png","alt":"image-20230504222846195"},{"url":"https://image.nickxu.me/202305042229391.png","alt":"image-20230504222910356"},{"url":"ht ...
关于软删除的讨论
别急,先挂着
别问我为什么空着就发上来了,我本来是想每一篇都写完再发的,但是后面本地坑挖了很多不想填就直接删了
然后发上来至少别人看着我还有动力去填🤣
7 月 11 日更:
卧槽居然过了这么久了才有空填
过了两个月了基本忘光了,翻了翻聊天记录,记起来了一点点
其实有个大佬的博客 软删除之痛 已经将前情提要概括了一下,下面就简单补充一下
文中写的唯一索引的例子在我们的开发中也遇到了,但是我们有不一样的解决方法
就是在删除的时候改个名,这样就能规避问题了
目前来说感觉这种方法没有还引发新的问题
在 Mac 的 VSC 中使用 g++ 编译器
本人最近开始复习算法刷题了,然后用的是 macOS 上 VSCode 的默认配置,也就是 clang/clang++ 编译器,但是高中的时候用惯了 gcc/g++ 了,很多 g++ 的方言 clang 并不支持,例如 #include <bits/stdc++.h> 之类的
可能你会说,这有什么的,直接把编译指令里面的编译器替换一下不就行了
如果真的这么简单的话就没有这篇博客了(bushi
首先我换了之后并不能解决问题, 接着我发现了一个很恐怖的事情(
我的 gcc 怎么被 clang 夺舍了???
我的第一个反应是卸载 clang ,毕竟我也不想用这玩意,然后我看这东西是哪里安装的
12whereis clangclang: /usr/bin/clang /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/share/man/man1/clang.1
啊,原来是 Xcode 哇,这东西我平时也用不上,还占着这么大的空间,我这就把你卸了
Xcode 是我刚开始上手 macOS 的时候学长建议我安装的,但是这东西快15个G,我平时又用不上
卸完之后我发现 clang 还是在,我就继续看
12whereis clangclang: /usr/bin/clang /Library/Developer/CommandLineTools/usr/share/man/man1/clang.1
原来是 CommandLineTools ,我又搜了一下这个 ...
GORM 的 GEN 模式初上手
最近准备上手一个新项目,然后在选择底层的 ORM 框架
我之前一直用的 GORM ,其实感觉还挺好用的,但是毕竟用多了,这次也想了解下其他的解决方案
之前在和群友讨论 GORM 的时候,我听见有人对它有一些负面的看法,比如说认为 GORM 不算真正的 ORM,因为它很多时候只是在帮你手动拼凑 SQL 语句,只是没有写原生 SQL 那么痛苦而已,我听了之后感觉其实也有点道理
比如说我最近项目里的一句查询
12345l.svcCtx.DBList.Mysql. Where("from_id = ? and to_user_id = ?", in.UserAId, in.UserBId). Or("from_id = ? and to_user_id = ?", in.UserBId, in.UserAId). Order("created_at desc"). First(&result)
其中还是要手打 from_id 和 to_user_id 这些字段名,就像原生 SQL 一样,而真正的 ORM 不应当是这样的,应当走如同 ent 这种代码生成的路子
甚至我也听过有人认为不应该使用 ORM 框架:为什么要旗帜鲜明地反对 orm 和 sql builder
也就是说你的 ORM 虽然方便,但是不方便进行 SQL 语句的审查,也就是说你不能预测线上环境会生成哪些 SQL,会有不确定性
但是其实我觉得吧,他说的场景我现在都还遇不到,我的项目也就是一些简单的 CURD ,而且数据量也不大
那么现在的情况就是说,我可 ...