教程集 www.jiaochengji.com
教程集 >  Golang编程  >  golang教程  >  正文 一道并发和锁的golang面试题

一道并发和锁的golang面试题

发布时间:2022-02-03   编辑:jiaochengji.com
教程集为您提供一道并发和锁的golang面试题等资源,欢迎您收藏本站,我们将为您提供最新的一道并发和锁的golang面试题资源

  今天面试golang碰到了一道考并发和锁的题目,没有完成,所以把它记录下来,仅为以后复习。

场景:在一个高并发的web服务器中,要限制IP的频繁访问。现模拟100个IP同时并发访问服务器,每个IP要重复访问1000次。每个IP三分钟之内只能访问一次。修改以下代码完成该过程,要求能成功输出 success:100


<pre><code class="language-java">package main import ( "fmt" "time" ) type Ban struct { visitIPs map[string]time.Time } func NewBan() *Ban { return &Ban{visitIPs: make(map[string]time.Time)} } func (o *Ban) visit(ip string) bool { if _, ok := o.visitIPs[ip]; ok { return true } o.visitIPs[ip] = time.Now() return false } func main() { success := 0 ban := NewBan() for i := 0; i < 1000; i { for j := 0; j < 100; j { go func() { ip := fmt.Sprintf("192.168.1.%d", j) if !ban.visit(ip) { success } }() } } fmt.Println("success:", success) } </code></pre>
以上代码有一些坑。当时也是没有做出来,回来请教一位大佬,得以解决。



<pre><code class="language-java">package main import ( "fmt" "sync" "sync/atomic" "time" ) type Ban struct { visitIPs map[string]struct{} } func NewBan() *Ban { return &Ban{visitIPs: make(map[string]struct{})} } //判断IP是否存在 func (o *Ban) visit(ip string) bool { mapMutex.Lock() defer mapMutex.Unlock() if _, ok := o.visitIPs[ip]; ok { return true } o.visitIPs[ip] = struct{}{} go o.invalidAfter3Min(ip) return false } // 3分钟后ip失效, 从map中移除. 因此ip再次访问时便可正常访问 func (o *Ban) invalidAfter3Min(ip string) { time.Sleep(time.Minute * 3) mapMutex.Lock() visitIPs := o.visitIPs delete(visitIPs, ip) o.visitIPs = visitIPs mapMutex.Unlock() } var mapMutex *sync.Mutex // mutex to avoid concurrent map writes func main() { mapMutex = new(sync.Mutex) var success int64 ban := NewBan() wg := new(sync.WaitGroup) for i := 0; i < 1000; i { for j := 0; j < 100; j { wg.Add(1) ipEnd := j go func() { defer wg.Done() ip := fmt.Sprintf("192.168.1.%d", ipEnd) if !ban.visit(ip) { atomic.AddInt64(&success, 1) } }() } } wg.Wait() fmt.Println("success:", success) } </code></pre>

 主要用到了闭包,原子操作和锁实现

到此这篇关于“一道并发和锁的golang面试题”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!

您可能感兴趣的文章:
一道并发和锁的golang面试题
如何在golang中关闭bufio.reader_golang 并发编程
GO 互斥锁实现原理剖析
并发同时访问_快速掌握Golang锁机制和并发基础
golang知识点
深入分析MySQL更新死锁问题
mysql中的锁、事务、并发控制的相关知识
用Go学UNIX环境编程 - 记录锁
golang key map 所有_缓存击穿导致 golang 组件死锁的问题分享
golang debug 配置_缓存击穿导致 golang 组件死锁的问题分享

[关闭]
~ ~