面试手撕题积累
1、实现滑动窗口限流,允许每分钟最多有100个请求
阿里一面题。
核心:
时间窗口管理:滑动窗口会根据时间流逝不断更新,需要记录请求的时间戳,并根据当前时间计算窗口内的请求数量。
限流判断:每次请求到来时,判断当前时间窗口内的请求数是否超过限制。如果没有超过限制,允许请求;如果超过限制,拒绝请求。
优化:
队列优化:如果每次都遍历 timestamps 切片来清理过期请求,当请求量大时,性能可能受到影响。为了提升性能,可以考虑使用双端队列(deque)来高效地删除最旧的请求。
并发控制:这个实现使用了 sync.Mutex 来保护共享资源的并发访问。在高并发环境下,如果请求量非常大,可以考虑其他更高效的并发控制机制,例如 sync.RWMutex 或无锁队列。
package mainimport ("fmt""sync""time"
)type SlidingWindowLimiter struct {// 请求时间戳队列,用来记录每个请求的时间timestamps []time.Time// 限制的最大请求数maxRequests int// 限制的时间窗口,单位为秒windowDuration time.Duration// 锁,保证并发安全mu sync.Mutex
}// 创建一个新的滑动窗口限流器
func NewSlidingWindowLimiter(maxRequests int, windowDuration time.Duration) *SlidingWindowLimiter {return &SlidingWindowLimiter{timestamps: []time.Time{},maxRequests: maxRequests,windowDuration: windowDuration,}
}// 检查是否允许请求
func (limiter *SlidingWindowLimiter) AllowRequest() bool {limiter.mu.Lock()defer limiter.mu.Unlock()// 当前时间now := time.Now()// 移除窗口外的请求时间戳limiter.cleanUp(now)// 如果当前请求时间戳个数小于限制,则允许请求if len(limiter.timestamps) < limiter.maxRequests {// 将当前请求的时间戳加入队列limiter.timestamps = append(limiter.timestamps, now)return true}// 否则,拒绝请求return false
}// 清理过期的请求时间戳
func (limiter *SlidingWindowLimiter) cleanUp(now time.Time) {// 移除超出时间窗口的请求windowStart := now.Add(-limiter.windowDuration)for len(limiter.timestamps) > 0 && limiter.timestamps[0].Before(windowStart) {limiter.timestamps = limiter.timestamps[1:]}
}func main() {// 创建一个滑动窗口限流器,限制每分钟最多100个请求limiter := NewSlidingWindowLimiter(100, time.Minute)// 模拟请求for i := 0; i < 120; i++ {allowed := limiter.AllowRequest()if allowed {fmt.Printf("Request %d allowed\n", i+1)} else {fmt.Printf("Request %d denied (too many requests)\n", i+1)}// 模拟请求间隔,假设每500毫秒发起一个请求time.Sleep(500 * time.Millisecond)}
}
2、把三千一十万五千零一十转换成对应数字
package mainimport ("fmt"
)func chineseToNumber(text string) int {numbersMap := map[rune]int{'零': 0, '一': 1, '二': 2, '三': 3, '四': 4, '五': 5, '六': 6, '七': 7, '八': 8, '九': 9,'十': 10, '百': 100, '千': 1000, '万': 10000,}total := 0num := 0for _, char := range text {if val, ok := numbersMap[char]; ok {if val < 10 {num += val} else {if num == 0 {num = 1}num *= val}} else {total += numnum = 0}}total += numreturn total
}func main() {text := "三千一十万五千零一十"number := chineseToNumber(text)fmt.Println(number)
}
3、用两个队列去模拟栈
package mainimport "fmt"type Stack struct {mainQueue []intauxQueue []int
}func NewStack() *Stack {return &Stack{mainQueue: make([]int, 0),auxQueue: make([]int, 0),}
}func (s *Stack) Push(val int) {// 将元素推入主队列s.mainQueue = append(s.mainQueue, val)
}func (s *Stack) Pop() int {if len(s.mainQueue) == 0 {return -1}// 将主队列中除了最后一个元素外的其他元素依次出队并放入辅助队列for len(s.mainQueue) > 1 {val := s.mainQueue[0]s.mainQueue = s.mainQueue[1:]s.auxQueue = append(s.auxQueue, val)}// 弹出最后一个元素作为栈顶元素popVal := s.mainQueue[0]s.mainQueue = s.mainQueue[:0]// 交换主队列和辅助队列,以便下一次操作s.mainQueue, s.auxQueue = s.auxQueue, s.mainQueuereturn popVal
}func main() {stack := NewStack()stack.Push(1)stack.Push(2)stack.Push(3)fmt.Println(stack.Pop()) // Output: 3fmt.Println(stack.Pop()) // Output: 2
}
4、用两个栈模拟队列
package mainimport "fmt"type Queue struct {stack1 []intstack2 []int
}func NewQueue() *Queue {return &Queue{stack1: make([]int, 0),stack2: make([]int, 0),}
}func (q *Queue) Enqueue(val int) {// 将元素推入stack1q.stack1 = append(q.stack1, val)
}func (q *Queue) Dequeue() int {if len(q.stack2) == 0 {// 如果stack2为空,将stack1中的元素依次弹出并推入stack2for len(q.stack1) > 0 {val := q.stack1[len(q.stack1)-1]q.stack1 = q.stack1[:len(q.stack1)-1]q.stack2 = append(q.stack2, val)}}if len(q.stack2) == 0 {return -1 // 队列为空}// 弹出stack2的栈顶元素作为出队元素popVal := q.stack2[len(q.stack2)-1]q.stack2 = q.stack2[:len(q.stack2)-1]return popVal
}func main() {queue := NewQueue()queue.Enqueue(1)queue.Enqueue(2)queue.Enqueue(3)fmt.Println(queue.Dequeue()) // Output: 1fmt.Println(queue.Dequeue()) // Output: 2fmt.Println(queue.Dequeue()) // Output: 3
}
5、判断B树是否为A树的子结构
package mainimport "fmt"type TreeNode struct {Val intLeft *TreeNodeRight *TreeNode
}func isSubStructure(A *TreeNode, B *TreeNode) bool {if A == nil || B == nil {return false}return isSubTree(A, B) || isSubStructure(A.Left, B) || isSubStructure(A.Right, B)
}func isSubTree(A *TreeNode, B *TreeNode) bool {if B == nil {return true}if A == nil || A.Val != B.Val {return false}return isSubTree(A.Left, B.Left) && isSubTree(A.Right, B.Right)
}
6、实现timer类,功能是注册函数定期执行
package mainimport ("fmt""time"
)type Timer struct {interval time.Durationticker *time.Tickerdone chan bool
}func NewTimer(interval time.Duration) *Timer {return &Timer{interval: interval,ticker: nil,done: make(chan bool),}
}func (t *Timer) Start() {t.ticker = time.NewTicker(t.interval)go func() {for {select {case <-t.ticker.C:fmt.Println("Timer tick")// 在这里添加想要执行的函数case <-t.done:t.ticker.Stop()return}}}()
}func (t *Timer) Stop() {t.done <- true
}func main() {timer := NewTimer(1 * time.Second)timer.Start()time.Sleep(5 * time.Second)timer.Stop()fmt.Println("Timer stopped")
}
7、生产者消费者
基本实现:
package mainimport ("fmt""math/rand""time"
)func producer(ch chan int) {for {num := rand.Intn(100)ch <- numtime.Sleep(time.Duration(rand.Intn(1000)) * time.Millisecond)}
}func consumer(ch chan int) {for {num := <-chfmt.Println("Consumed:", num)time.Sleep(time.Duration(rand.Intn(1000)) * time.Millisecond)}
}func main() {rand.Seed(time.Now().Unix())ch := make(chan int)go producer(ch)go consumer(ch)time.Sleep(5 * time.Second) // Let the program run for a few seconds
}
8、三个协程轮流打印 abc
参考:https://juejin.cn/post/7262243685898436667
// 使用三个管道实现三个协程同步顺序打印a b c
func printLetter(letter string, prevCh, nextCh chan struct{}, wg *sync.WaitGroup) { defer wg.Done() for i := 0; i < 10; i++ { // 等待上一个协程通知 <-prevCh fmt.Print(letter) // 发送信号给下一个协程 nextCh <- struct{}{} }if letter == "a" {<-prevCh}
}func main() {var wg sync.WaitGroup wg.Add(3) ch1 := make(chan struct{}) ch2 := make(chan struct{}) ch3 := make(chan struct{}) go printLetter("a", ch1, ch2, &wg) go printLetter("b", ch2, ch3, &wg) go printLetter("c", ch3, ch1, &wg) // 启动第一个协程 ch1 <- struct{}{} wg.Wait()
}
进阶:26个字母
// 使用26个协程分别顺序打印字母表
func printAlphabet(letter rune, prevCh, nextCh chan struct{}, wg *sync.WaitGroup) { defer wg.Done()for i := 0; i < 10; i++ { <-prevChfmt.Printf("%c", letter)nextCh <- struct{}{}} // 第一个协程必须要退出,因为最后一个协程往管道里面写入数据了,需要破环而出不然就会死锁 if letter == 'a' {<-prevCh}
}func main() { var wg sync.WaitGroupwg.Add(26)var signals []chan struct{} for i := 0; i < 26; i++ { signals = append(signals, make(chan struct{})) } for letter, i := 'a', 0; letter <= 'z'; letter++ { if letter == 'z' { go printAlphabet(letter, signals[i], signals[0], &wg)break}go printAlphabet(letter, signals[i], signals[i+1], &wg) i++}// 启动第一个协程 signals[0] <- struct{}{} wg.Wait()
}
9、
参考:https://blog.csdn.net/zss192/article/details/138610657#159_32_5898
相关文章:
面试手撕题积累
1、实现滑动窗口限流,允许每分钟最多有100个请求 阿里一面题。 核心: 时间窗口管理:滑动窗口会根据时间流逝不断更新,需要记录请求的时间戳,并根据当前时间计算窗口内的请求数量。 限流判断:每次请求到来…...
notepad++文件github下载
1、github下载网址:Releases notepad-plus-plus/notepad-plus-plus GitHub 2、找到操作系统支持的软件: 3、CSDN下载链接:https://download.csdn.net/download/u013083576/90046203...
.NET新知识点笔记
using 用法介绍 using (SqlCommand cmd new SqlCommand(SQLString, connection)) 为什么使用上面的using 而不直接使用下述的来直接 SqlCommand cmd new SqlCommand(SQLString, connection)如果你需要使用一个对象,这个对象需要占用很多紧缺的资源&am…...
数据结构:链表进阶
链表进阶 1. ArrayList的缺陷2. 链表2.1 链表的概念及结构2.2 链表的实现 3.链表面试题4.LinkedList的使用5.1 什么是LinkedList4.2 LinkedList的使用 5. ArrayList和LinkedList的区别 1. ArrayList的缺陷 通过源码知道,ArrayList底层使用数组来存储元素࿱…...
Python 爬虫入门教程:从零构建你的第一个网络爬虫
网络爬虫是一种自动化程序,用于从网站抓取数据。Python 凭借其丰富的库和简单的语法,是构建网络爬虫的理想语言。本文将带你从零开始学习 Python 爬虫的基本知识,并实现一个简单的爬虫项目。 1. 什么是网络爬虫? 网络爬虫&#x…...
Java面试题、八股文——JVM篇最终篇
1.如何选择垃圾收集器? 选择合适的垃圾收集器(Garbage Collector, GC)对于优化Java应用程序的性能至关重要。不同的应用场景和系统需求可能需要不同类型的垃圾收集器来满足。以下是一些考虑因素以及常见的垃圾收集器选项,帮助您做…...
Spring Boot整合Redis Stack构建本地向量数据库相似性查询
Spring Boot整合Redis Stack构建本地向量数据库相似性查询 在微服务架构中,数据的高效存储与快速查询是至关重要的。Redis作为一个高性能的内存数据结构存储系统,不仅可以用作缓存、消息代理,还可以扩展为向量数据库,实现高效的相…...
shell脚本基础学习_总结篇(完结)
细致观看可以,访问shell脚本学习专栏,对应章节会有配图https://blog.csdn.net/2201_75446043/category_12833287.html?spm1001.2014.3001.5482 导语 一、shell脚本简介 1. 定义: 2. 主要特点: 3. shell脚本的基本结构 4. S…...
什么是 C++ 中的函数对象?它有什么特点?
在 C 中,函数对象(Function Object)是一种可调用对象,它允许像函数一样被调用,但实际上它可能并不是真正的函数。函数对象可以是以下几种类型之一: 普通函数: 一个普通的、定义在命名空间或类…...
css:项目
这是一个完整的网站制作的流程 美工会先制作一个原型图: 原型图写的不详细,就是体现一个网页大致的布局 然后美工再做一个psd样例图片 然后再交给程序员 项目 模块化开发:把代码的不同的样式封装起来,需要用到相同样式的标签就…...
macOS 开发环境配置与应用开发指南
macOS 开发环境配置与应用开发指南 macOS作为苹果公司推出的操作系统,因其稳定性、优雅的用户界面和强大的开发支持,已成为开发者和创意专业人士的首选平台之一。无论是开发iOS、macOS桌面应用,还是Web应用、跨平台程序,macOS都提…...
[A-19][V06]ARMv8/v9-内存虚拟化原理
ver0.2 [看前序文章有惊喜,关注W\X\G=Z+H=“浩瀚架构师”,可以解锁全部文章] 前言 前一篇文章,我们介绍了ARM内存的属性,算是一个小小的里程碑点,接下来我们会把注意力重新拉回虚拟化的赛道。我们从[V-05] 虚拟化基础-异常模型(Exception model)之后,花了很多笔墨介绍…...
registry 删除私有仓库镜像
原文链接:https://blog.csdn.net/yogima/article/details/122172744 如果需要彻底删除,只需进行register 磁盘删除镜像 彻底删除了,就可以到达彻底删除的目的。 如果只需要软删除,则只需进行通过API删除。 curl --header "Ac…...
UPLOAD LABS | UPLOAD LABS 靶场初识
关注这个靶场的其它相关笔记:UPLOAD LABS —— 靶场笔记合集-CSDN博客 0x01:UPLOAD LABS 靶场简介 UPLOAD LABS 靶场是一个专门用于学习文件上传漏洞攻击和防御的靶场。它提供了一系列文件上传漏洞的实验环境,用于帮助用户了解文件上传漏洞的…...
Samba服务器常见问题处理
指定的网络文件夹目前是以其他用户名和密码进行映射的。要用其他用户名和密码进行连接,首先请断开所有现有的连接到网络共享的映射 解决方案 单击“开始”菜单,选择“运行…”。 在弹出的窗口中,输入cmd 进入命令行模式,并输入…...
Java基础 设计模式——针对实习面试
目录 Java基础 设计模式单例模式工厂模式观察者模式策略模式装饰器模式其他设计模式 Java基础 设计模式 单例模式 单例模式(Singleton Pattern) 定义:确保一个类只有一个实例,并提供一个全局访问点来访问这个实例。适用场景&…...
最大公约数和最小公倍数-多语言
目录 C 语言实现 Python 实现 Java 实现 Js 实现 题目:输入两个正整数m和n,求其最大公约数和最小公倍数。 程序分析: 最小公倍数输入的两个数之积除于它们的最大公约数,关键是求出最大公约数; 求最大公约数用辗转…...
第三方数据库连接免费使用和安装
是强大的一体化数据库开发解决方案,可从单一应用程序无缝连接多个数据库,包括 MySQL、PostgreSQL、MongoDB、MariaDB、SQL Server、Oracle、SQLite 和 Redis。 下载:https://download.csdn.net/download/mo3408/90045937 升级特性 模型&…...
水库大坝安全监测之量水堰计应用
量水堰计是水库大坝安全监测系统中的一种关键设备,主要用于测量水库水位、流量等水力参数。以下是量水堰计在水库大坝安全监测中的应用及注意事项: 一、量水堰计的工作原理 量水堰计是一种专门用于测量水流流量的仪器,其工作原理主要基于水流…...
算法笔记:滑动窗口
前言 滑动窗口作为一个考点较高的算法,广泛应用于子串问题中,本文将进行详细讲解。 一、滑动窗口是什么 滑动窗口是双指针算法的一种,基本思路为维护一个窗口,然后从前往后遍历元素进行运算。 二、滑动窗口算法和其他双指针算…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...
12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...
C# 表达式和运算符(求值顺序)
求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如,已知表达式3*52,依照子表达式的求值顺序,有两种可能的结果,如图9-3所示。 如果乘法先执行,结果是17。如果5…...
Unity UGUI Button事件流程
场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…...
何谓AI编程【02】AI编程官网以优雅草星云智控为例建设实践-完善顶部-建立各项子页-调整排版-优雅草卓伊凡
何谓AI编程【02】AI编程官网以优雅草星云智控为例建设实践-完善顶部-建立各项子页-调整排版-优雅草卓伊凡 背景 我们以建设星云智控官网来做AI编程实践,很多人以为AI已经强大到不需要程序员了,其实不是,AI更加需要程序员,普通人…...
Element-Plus:popconfirm与tooltip一起使用不生效?
你们好,我是金金金。 场景 我正在使用Element-plus组件库当中的el-popconfirm和el-tooltip,产品要求是两个需要结合一起使用,也就是鼠标悬浮上去有提示文字,并且点击之后需要出现气泡确认框 代码 <el-popconfirm title"是…...
记一次spark在docker本地启动报错
1,背景 在docker中部署spark服务和调用spark服务的微服务,微服务之间通过fegin调用 2,问题,docker容器中服务器来后,注册中心都有,调用服务也正常,但是调用spark启动任务后报错,报错…...
河北对口计算机高考MySQL笔记(完结版)(2026高考)持续更新~~~~
MySQL 基础概念 数据(Data):文本,数字,图片,视频,音频等多种表现形式,能够被计算机存储和处理。 **数据库(Data Base—简称DB):**存储数据的仓库…...
dvwa11——XSS(Reflected)
LOW 分析源码:无过滤 和上一关一样,这一关在输入框内输入,成功回显 <script>alert(relee);</script> MEDIUM 分析源码,是把<script>替换成了空格,但没有禁用大写 改大写即可,注意函数…...
