首页 > 数据库 >【Redis】面试题 GEO地理位置信息

【Redis】面试题 GEO地理位置信息

时间:2023-04-19 20:15:50浏览次数:55  
标签:面试题 transaction 请求 经纬度 Redis --- 并发 悲观 GEO

目录

面试

1 http协议详情,http协议版本,http一些请求头


	-特点:
    	1 基于请求响应--》服务端不能主动给客户端推送消息---》websocket协议
        2 无状态无连接---》不能做会话保持---》才出现了cookie,session,token
        3 基于tcp之上的应用层协议
    -详情:
    	-请求协议:
        	请求首行:请求方式(get,post,delete),请求地址,请求http协议版本号/r/n
            请求头:key:value   (cookie,useragent,referer,x-forword-for)
            请求体:编码方式
        -响应协议:
        	响应首行:响应状态码(1xx,2xx),响应单词描述
            响应头:key:value    跨域问题的响应头
            响应体:html格式:浏览器中看到的   json格式给客户端使用
   	-协议版本
    	-0.9:
            HTTP协议的最初版本,功能简陋,仅支持请求方式GET,并且仅能请求访问HTML格式的资源
        -1.0:
            但是1.0版本的工作方式是每次TCP连接只能发送一个请求(默认短链接),当服务器响应后就会关闭这次连接,下一个请求需要再次建立TCP连接,就是不支持keep-alive
        -1.1:
            引入了持久连接(persistent connection),即TCP连接默认不关闭,可以被多个请求复用,不用声明Connection: keep-alive。客户端和服务器发现对方一段时间没有活动,就可以主动关闭连接。
        -2.0:
           多路复用:对于 HTTP/1.x,即使开启了长连接,请求的发送也是串行发送的,在带宽足够的情况下,对带宽的利用率不够,HTTP/2.0 采用了多路复用的方式,可以并行发送多个请求,提高对带宽的利用率 
        -3.0:
            HTTP3.0又称为HTTP Over QUIC,其弃用TCP协议,改为使用基于UDP协议的QUIC协议来实现
	

2 GET请求和POST请求的区别

    post更安全(不会作为url的一部分)
    post发送的数据更大(get有url长度限制)
    post能发送更多的数据类型(get只能发送ASCII字符)
    post比get慢
    post用于修改和写入数据,get一般用于搜索排序和筛选之类的操作

3 如何实现服务器给客户端发送消息,websocket是什么?

-websocket:一种通信协议,区别于http协议,可在单个TCP连接上进行全双工通信。允许服务端主动向客户端推送数据。浏览器和服务器只需要完成一次tcp连接,两者之间就可以建立持久性的连接,并进行双向数据传输
    -没有跨域问题
    -应用场景:
    	-只要涉及到服务端主动给客户端发送消息的场景,都可以用
        -实时聊天:我项目没写
        -服务端发生变化,主动向客户端推送一个通知
        -监控服务端的内存使用情况
    -djanog中使用channles模块实现
     
   -https://zhuanlan.zhihu.com/p/371500343

4 悲观锁和乐观锁,如何实现


-无论是悲观锁还是乐观锁,都是人们定义出来的概念,仅仅是一种思想,与语言无关
    -并发控制:
    	-1 并发控制:当程序中出现并发问题时,就需要保证在并发情况下数据的准确性,以此确保当前用户和其他用户一起操作时,所得到的结果和他单独操作时的结果是一样的,这种手段就叫做并发控制
        -2 没有做好并发控制,就可能导致脏读、幻读和不可重复读等问题
    -悲观锁:
    悲观锁:当要对一条数据进行修改的时候,为了避免同时被其他人修改,最好的办法就是直接对该数据进行加锁以防止并发,让并行变成串行
    -这种借助数据库锁机制,在修改数据之前先锁定,再修改的方式被称之为悲观并发控制【Pessimistic Concurrency Control,缩写"PCC",又名"悲观锁"】
    - 之所以叫做悲观锁,是因为这是一种对数据的修改持有悲观态度的并发控制方式。总是假设最坏的情况,每次读取数据的时候都默认其他线程会更改数据,因此需要进行加锁操作,当其他线程想要访问数据时,都需要阻塞挂起。
    
    -悲观锁实现方式:
    	1 传统的关系型数据库(如mysql)使用这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁
    	2 编程语言中的线程锁,比如python的互斥锁
    	3 分布式锁:redis实现的分布式锁等

    -乐观锁:
    	通过程序实现(没有真正的一把锁),不会产生死锁
    	总是假设最好的情况,每次去拿数据的时候都认为别人不会修改,所以不会上锁,只在更新的时候会判断一下在此期间别人有没有去更新这个数据,如果更新了,我们就不做修改
        
    -乐观锁实现方案:
    	1 CAS(Compare And Swap) 即比较并交换。是解决多线程并行情况下使用锁造成性能损耗的一种机制,CAS 操作包含三个操作数——内存位置(V)、预期原值(A)和新值(B),执行CAS操作的时候,将内存位置的值与预期原值比较,如果相匹配,那么处理器会自动将该位置值更新为新值,否则,处理器不做任何操作
  CAS会出现ABA问题,比如,你看到桌子上有100块钱,然后你去干其他事了,回来之后看到桌子上依然是100块钱,你就认为这100块没人动过,其实在你走的那段时间,别人已经拿走了100块,后来又还回来了。这就是ABA问题
  解决ABA问题:既然有人动了,那我们对数据加一个版本控制字段,只要有人动过这个数据,就把版本进行增加,我们看到桌子上有100块钱版本是1,回来后发现桌子上100没变,但是版本却是2,就立马明白100块有人动过
    2 版本号控制:在数据表中增加一个版本号字段,每次更新数据时将版本号加1,同时将当前版本号作为更新条件,如果当前版本号与更新时的版本号一致,则更新成功,否则更新失败
    3 时间戳方式:在数据表中增加一个时间戳字段,每次更新数据时将时间戳更新为当前时间戳,同时将当前时间戳作为更新条件,如果当前时间戳与更新时的时间戳一致,则更新成功,否则更新失败
        
        
        
        
        
# 悲观锁乐观锁使用场景
并发量:如果并发量不大,可以使用悲观锁解决并发问题;但如果系统的并发非常大的话,悲观锁定会带来非常大的性能问题, 建议乐观锁
响应速度:如果需要非常高的响应速度,建议采用乐观锁方案,成功就执行,不成功就失败,不需要等待其他并发去释放锁。乐观锁并未真正加锁,效率高
冲突频率:如果冲突频率非常高,建议采用悲观锁,保证成功率。冲突频率大,选择乐观锁会需要多次重试才能成功,代价比较大
重试代价:如果重试代价大,建议采用悲观锁。悲观锁依赖数据库锁,效率低。更新失败的概率比较低
读多写少: 乐观锁适用于读多写少的应用场景,这样可以提高并发粒度
    
    
    
#django中使用:下单,秒杀场景

# django中如何开启事务
	-全局开启:每个http请求都在一个事务中
        DATABASES = {
         'default': {
             'ENGINE': 'django.db.backends.mysql',
             'NAME': 'lqz',
             'HOST': '127.0.0.1',
             'PORT': '3306',
             'USER': 'lqz',
             'PASSWORD': 'lqz123',
              #全局开启事务,绑定的是http请求响应整个过程
             'ATOMIC_REQUESTS': True, 
         }
    }
    -每个视图函数开启
    	from django.db import transaction
        @transaction.atomic
        def seckill(request):
            
            
     -局部开启
    	from django.db import transaction
        def seckill(request):
            with transaction.atomic():
                pass
            return HttpResponse('秒杀成功')
    
    -保存点,回滚保存点Savepoint
    	-设置回滚点:sid = transaction.savepoint()
        -提交回滚点:transaction.savepoint_commit(sid)       transaction.commit()
        -回滚到回滚点:transaction.savepoint_rollback(sid)   transaction.rollback()
    - 事务提交后回调函数
    	transaction.on_commit(send_email)

#django中使用悲观锁
https://zhuanlan.zhihu.com/p/622987268
#django中使用乐观锁
django中使用:下单、秒杀场景。 异步加锁
django Smallinterfield --相当于--> mysql中的tinyint (存储的数据大小不一样)
删掉app下迁移文件 admin auth 删库

在上下文管理器中不需要主动提交:

image-20230419103916543

在with里面出了异常也会回滚:

image-20230419103955379

悲观锁使用:

本质是锁定一个对象。

image-20230419104323193

如果是all就是表锁。

python中的锁会锁住所有的请求,所有人并行变成串行。mysql行锁会锁住一行,其他人可以修改别的行,锁的粒度小,效率高。

mysql读锁和写锁的粒度更小?

image-20230419104923804

操作同一行,需要等待前一个请求操作完。

循环的目的是 ---> 如果库存足一定能成功。

乐观锁和悲观锁的对比:
乐观锁先进入程序也不一定成功。悲观锁先进入程序,基本上就成功了。
并发量大,被修改的概率大,如果不重试,乐观锁失败概率就更大了.

今日内容

1 GEO地理位置信息

# GEO(地理信息定位):存储经纬度,计算两地距离,范围等
	-根据经纬度---》确定具体地址的---》高德开放api---》返回具体地址
    
    
# redis 可以存储经纬度,存储后可以做运算,
	比如:两个经纬度之间距离 (直线距离)
    比如:统计某个经纬度范围内有哪些好友,餐馆
	
    
    
# 经纬度如何获取
	-跟后端没关系:只需要存
    -app,有定位功能
    -网页,集成了高德地图,定位功能
    
    
# redis存储
geoadd key  经度  纬度 名字
# 添加
geoadd cities:locations 116.28 39.55 beijing
# 查看位置信息
geopos cities:locations beijing #获取北京地理信息
    
#计算两个点距离
geodist cities:locations beijing tianjin km
    
# 计算附近的 xx
georadiusbymember cities:locations beijing 150 km
    
# 5大数据类型的 : 有序集合

GEO是用于存储经纬度的。
根据经纬度 ---> 确定具体地址 ---> 高德开放api ---> 返回具体地址 ---> 有误差

再使用百度api 不一样的部分剔除出来 人工审查一下。

存储经纬度:

image-20230419122846526

获取经纬度:

image-20230419122941432

计算两个经纬度之间的距离:

直线距离:

image-20230419123059460

image-20230419123045245

距离北京100km内有哪些城市:

image-20230419123131664

可以实现附近的人功能。

# 补充
存储到mysql表中,计算的时候可以使用redis计算。
redis geo存储的是什么类型?有序集合
经纬度相当于 有序集合的'分数'
在内存中有序集合对象来存储。
每个人登录,记录登录地址(经纬度)。记录IP地址和真实地址。

标签:面试题,transaction,请求,经纬度,Redis,---,并发,悲观,GEO
From: https://www.cnblogs.com/passion2021/p/17334456.html

相关文章

  • redis----day03( )
    面试面试如何聊#第一面(笔试): -办公室做题:拍照,发群里---》自己课搜,同学帮着搜----》往上写-问不答了,可以直接面试吗?#第二面:正式面试(开启手机录音,放口袋中) -一个人,多个人坐你对面-最重要的:自我介绍(自己提前写出来,500字,尽可能展现自己的优势) -面试官您......
  • centos9 redis安装报错(实在无解使用方法)
    报错如下[root@centosbin]#./redis-server./redis-server:errorwhileloadingsharedlibraries:libssl.so.1.1:cannotopensharedobjectfile:Nosuchfileordirectory使用的解决命令yummakecacheyum-yinstall*openssl*原过程root@centosbin]#lsredi......
  • 900万大数据量 查询 更新 使用redis 多线程请求
    表A中有900多万数据,根据900万数据,查询数据并插入B表创建一个定时任务,定时查询配置条件,查询更新(查询更新使用多线程)预估时间,设置请求时间跟频率不想这么干:可以查看数据执行进度思路:设置一个运行队列runList里面是待执行的id设置一个失败队列failList里面是执行失败的i......
  • Redis Pipeline(管道)
    RedisPipeline简介Redis是一种基于客户端-服务端模型以及请求/响应的TCP服务。一次Redis客户端发起的请求,经过服务端的响应后,大致会经历如下的步骤:客户端发起一个(查询/插入)请求,并监听socket返回,通常情况都是阻塞模式等待Redis服务器的响应服务端处理命令,并且返回处理结果......
  • redis高级-day3——GEO地理位置信息
    目录1GEO地理位置信息1GEO地理位置信息#GEO(地理信息定位):存储经纬度,计算两地距离,范围等 -根据经纬度---》确定具体地址的---》高德开放api---》返回具体地址#redis可以存储经纬度,存储后可以做运算, 比如:两个经纬度之间距离(直线距离)比如:统计某个经纬度......
  • Redis高可用搭建方案
    本次使用redis版本为redis-5.0.14,下载地址http://redis.io/download1、linux环境安装gccyuminstallgcc2、上传redis-5.0.14.tar.gz到usr/local文件夹下,解压tar-zxfredis-5.0.14.tar.gz3、进入redis-5.0.14目录,执行make命令编译、安装4、在/usr/local下创建对应目录......
  • Linux 虚拟机服务器安装 Redis (sentinel模式)
    虚拟机服务器准备阶段三台服Linux虚拟机IP分别为192.168.192.133(作为master节点)192.168.192.129(作为slave节点)192.168.192.132(作为slave节点)我的三台虚拟机服务器版本均为centos7,且均为最小化安装,所以少很多软件,比如安装redis时需要gcc编译器、python环境等。......
  • #yyds干货盘点# LeetCode面试题:删除有序数组中的重复项 II
    1.简述:给你一个有序数组nums,请你原地删除重复出现的元素,使得出现次数超过两次的元素只出现两次,返回删除后数组的新长度。不要使用额外的数组空间,你必须在原地修改输入数组并在使用O(1)额外空间的条件下完成。 说明:为什么返回数值是整数,但输出的答案是数组呢?请注意,输入数......
  • Redis高级 哈希类型、列表类型、集合类型、有序集合(zset)、慢查询、pipeline与事务
    哈希类型###1---hget,hset,hdelhgetkeyfield#获取hashkey对应的field的value时间复杂度为o(1)hsetkeyfieldvalue#设置hashkey对应的field的value值时间复杂度为o(1)hdelkeyfield#删除hashkey对应的field的值时间复杂度为o(1)#测试hsetuser:1:infoage......
  • 【Redis】哈希类型 列表类型 集合类型 有序集合 慢查询 pipeline与事务 发布订阅 Bitm
    目录昨日回顾今日内容1哈希类型2列表类型3集合类型4有序集合(zset)5慢查询6pipeline与事务7发布订阅8Bitmap位图9HyperLogLog作业昨日回顾#1redis介绍 -特性#速度快:10wops(每秒10w读写),数据存在内存中,c语言实现,单线程模型#持久化:rdb和aof#多种数据结......