一道并发和锁的golang面试题

smallleiit smallleiit     2022-12-11     250

关键词:

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

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

 

package main

import (
"fmt"
"time"
)

type Ban struct
visitIPs map[string]time.Time


func NewBan() *Ban
return &BanvisitIPs: 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)

以上代码有一些坑。当时也是没有做出来,回来请教一位大佬,得以解决。

 


package main

import (
"fmt"
"sync"
"sync/atomic"
"time"
)

type Ban struct
visitIPs map[string]struct


func NewBan() *Ban
return &BanvisitIPs: 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)


 主要用到了闭包,原子操作和锁实现
---------------------
作者:自傷無色丶
来源:CSDN
原文:https://blog.csdn.net/qq_28163175/article/details/75287877
版权声明:本文为博主原创文章,转载请附上博文链接!

golang并发和锁(代码片段)

Golang并发和锁1.介绍读写锁介绍基本遵循两大原则:1、可以随便读,多个goroutine同时读2、写的时候,啥也不能干。不能读也不能写RWMutex提供了四个方法:func(*RWMutex)Lock//写锁定func(*RWMutex)Unlock//写解锁func(*RWMutex)RLo... 查看详情

转载数据库大并发操作要考虑死锁和锁的性能问题

...g.csdn.net/yuanyuanispeak/article/details/527561671 前言数据库大并发操作要考虑死锁和锁的性能问题。看到网上大多语焉不详(尤其更新锁),所以这里做个简明解释,为下面描述方便,这里用T1代表一个数据库执行请求,T2代表另一个... 查看详情

innodb中的事务隔离级别和锁的关系

...和隔离性,一般使用加锁这种方式。同时数据库又是个高并发的应用,同一时间会有大量的并发访问,如果加锁过度,会极大的降低并发处理能力。所以对于加锁的处理,可以说就是数据库对于事务处理的精髓所在。这里通过分... 查看详情

java并发编程面试题

   并发编程面试题-内存模型说下内存模型定义为什么要有内存模型为什么要重排序,重排序在什么时候排如何约束重排序规则happens-before什么是顺序一致性CAS实现的原理,是阻塞还是非阻塞方式?什么时候用,使用时... 查看详情

innodb中的事务隔离级别和锁的关系

...和隔离性,一般使用加锁这种方式。同时数据库又是个高并发的应用,同一时间会有大量的并发访问,如果加锁过度,会极大的降低并发处理能力。所以对于加锁的处理,可以说就是数据库对于事务处理的精髓所在。这里通过分... 查看详情

2021腾讯java面试题精选,java面试题汇总

分布式锁的坑高并发场景下的问题以下问题不是说在并发不高的场景下不容易出现,只是在高并发场景下出现的概率更高些而已。性能问题来自于以下两方面:**①获取锁的时间上。**如果Redlock运用在高并发的场景下࿰... 查看详情

java多线程线程池和锁的深度化

...池 1.1线程池是什么Java中的线程池是运用场景最多的并发框架,几乎所有需要异步或并发执行任务的程序都可以使用线程池。在开发过程中,合理地使用线程池能够带 查看详情

jit对锁的优化-锁消除和锁粗化案例分析(代码片段)

...ot;helloworld");上述是一个简单的同步代码块的案例,在并发的情况下多个线程是共享MySynchronizedTest07的成员变量object所以才达到了锁的效果。我们再看下面一个案例代码:packagecom.karl.concurrent.syn;/***描述:锁粒度演示**@authorkarl*@c... 查看详情

一道有趣的面试题(代码片段)

一道面试题。接受参数n=5,不用for循环输出数组【1,2,3,4,5】这用递归的思路,配合arguments.callee,代码如下1functionshow(n)2vararr=[];3return(function()4arr.unshift(n);5n--;6if(n!=0)7arguments.callee();89returnarr;10)()1112show(5)//[1 查看详情

golang同步锁mutex

...Mutex,它就是最简单最基础的同步锁,当一个goroutine持有锁的时候,其他的goroutine只能等待到锁释放之后才可以尝试持有。RWMutex是读写锁的意思,它支持一写多读,也就是说允许支持多个goro 查看详情

史上最简单的一道面试题!坑人吧

把下面a,b值互换,使打印结果为a=2,b=1.importjava.lang.reflect.Field;/***Createdby70416on2018/4/7.*/publicclassApp{publicstaticvoidswap(Integeri1,Integeri2)throwsNoSuchFieldException,IllegalAccessException{.....}pub 查看详情

一道前端的面试题js(代码片段)

前端同学经常忽视的一个JavaScript面试题作者:Wscats链接:https://github.com/Wscats/articles/issues/85题目function Foo()     getName = function ()  alert (1);&nbs 查看详情

一道sql面试题吧

createtabletmpy1(snochar(4),--学号cnochar(4),--课程号value1decimal(14,2)--成绩)insertintotmpy1values('s1','c1',10);insertintotmpy1values('s1','c2',20);insertintotmpy1values(&# 查看详情

golang笔记-面试题整理01(代码片段)

...拿到他的面试题后,花了一些时间,整理了以下golang面试题,都是比较基础的问题,留给大家作为面试参考。文章目录1、在进行项目开发时,遇到的关于golang的问题有哪些?2、golang中关于grpc和rest都使用... 查看详情

mysql事务和锁(代码片段)

一,锁锁是并发控制中最核心的概念之一,在MySQL中的锁分两大类,一种是读锁,一种是写锁,读锁也可以称为共享锁(sharedlock),写锁也通常称为排它锁(exclusivelock)。  这里先不讨论锁的具体实现,描述一下锁的概念:... 查看详情

事务和锁

...事务结束以后,数据库的完整性约束没有被破坏Isolation,并发事务间的数据是彼此隔离的,通过锁的方式来实现。Durabiliy,事务提交后,所有结果务必被持久化REDOUNDOINNODB记录逻辑的操作。INNODB原理:      &... 查看详情

一道小面试算法题的思路(代码片段)

一道小算法题的思路有这么一道小面试算法题:给定一个长度为n的整数数组,下标为i的元素表示第i天某个股票的价格,每次最多持有一股,每次买卖最多一股,在最多只买卖一次的情况下(先买后卖,不考虑融券等复杂形式)... 查看详情

前端面试的一道算法题

...使用canvas解答)下面说一个跟前端有点相关并且有点趣的一道算法题。题目:平面上有若干个不特定的形状,如下图所示。请写程序求出物体的个数,以及每个不同物体的面积。 分析想要知道有多少个图形,想到的就是先获... 查看详情