路飞项目--06

redis介绍和安装

# 数据库:

关系型数据库:mysql、oracle、postgrasql、sqlserver、sqlite
            IBM:服务器     
            Oracle:数据库   达梦
            EMC:存储 

非关系型数据库: redis、mongodb、es、clickhouse、influxDB

         NoSql 类型
# 如何选择:

目前许多大型互联网都会选用MySql+NoSql的组合方案

关系型数据库适合存储结构化数据,比如:用户的账号、地址:

        (1)这些数据通常需要做结构化查询,比如Join,这时,关系型数据库就要胜出一筹。

        (2)这些数据的规模、增长的速度通常是可以预期的。

        (3)事务性、一致性,适合存储比较复杂的数据。

NoSql适合存储非结构化数据,比如:文章、评论:

        (1)这些数据通常用于模糊处理,如全文搜索、机器学习,适合存储较简单的数据。

        (2)这些数据是海量的,并且增长的速度是难以预期的。

        (3)按照key获取数据效率很高,但是对于join或其他结构化查询的支持就比较差。

# 总结:

        SQL数据库依然强大,可以可靠的处理事务并且保持事务的完整性,只有你的数据非常大,操作扩展需要更加分布式的系统时,才考虑NoSql数据库

# redis是什么?

        redis是一个key-value存储系统【软件】,用c语言写的,c/s架构的软件,纯内存存储,可以持久化【断电数据可以恢复】,支持很多客户端(python,go,java,c,php),速度很快
        有5钟数据类型:string字符串、hash字典、list列表、set集合、zset有序集合
# redis为什么速度这么快:
    qps :10w   6w左右
    1、纯内存操作,避免了io
    2、使用了io多路复用的网络模型--(epoll)
    3、数据操作是单线程单进程---【没有锁操作,没有线程间切换】
# redis适合干什么?

缓存(最多)
验证码放在redis中,有过期时间,只要过期,这个数据就没了
计数器 
去重
排行榜:有序集合
地址位置信息
消息队列
...  

# 安装redis
    redis开源项目,社区不支持win
            使用的epoll模式,不能再win上运行的
    微软团队基于人家源码,修改+编译,做成安装包可以装在win上
    最新:最新7.x
    win平台最新只有:
            最新5.x版本 https://github.com/tporadowski/redis/releases/
            最新3.x版本 https://github.com/microsoftarchive/redis/releases
    下载:Redis-x64-5.0.14.1.msi,一路下一步

redis配置和启动

# 配置成服务,启动停止服务即可,也可以通过命令启动停止
# 安装目录下,重要的可执行文件
    redis-cli  :客户端   等同于mysql 的 mysql
    redis-server :服务端等同于mysql 的 mysqld


# 重要的配置文件相当于mysql 的 my.ini

redis.windows-service.conf
      databases 16
      port 6379
      bind 127.0.0.1

  # 启动redis:
    redis-server  配置文件路径   redis-server redis.windows-service.conf
# 关闭:
    1、服务中点停止
    2、cmd客户端链接上:执行   shutdown    
# redis数据是存在内存中得
    一般情况下,重启redis服务,关机,数据都会丢失
    咱们不会丢 redis.windows-service.conf 已经写了持久化方案
        (从内存把数据保存到硬盘上的过程称之为持久化)

redis之普通链接和连接池

# 安装:pip install redis

# 普通链接

from redis import Redis

conn = Redis(host='localhost', port=6379, db=0)
res = conn.get('name')
print(res)  # b'\xe5\x91\xa8\xe4\xbd\xb3\xe4\xbd\xb3'
print(res.decode(encoding='utf-8'))  # 周佳佳
conn.close()

# 连接池: 

# script/redis_demo/pool.py
import redis
# 创建池--->保证pool是单例的---》全局只有一个pool对象实例
Pool = redis.ConnectionPool(max_connections=3, host="localhost", port=6379, decode_responses=True)
# 连接池链接.py
import redis
from threading import Thread
from pool import Pool


# 每次从池中取一个链接
# conn = redis.Redis(connection_pool=pool)
# res = conn.get('name')
# print(res)
# conn.close()  # 把链接放回到连接池


# 起十个线程
def task():
    conn = redis.Redis(connection_pool=Pool)
    res = conn.get('name')
    print(res)
    conn.close()


l = []
for i in range(3):
    t = Thread(target=task)
    t.start()
    l.append(t)

for t in l:
    t.join()

print('结束了')

redis字符串操作

# 对五种数据类型的操作:
         字符串、字典、列表、集合、有序集合
# 主要应用场景:
    1 计数器
    2 做缓存,轮播图数据,json格式字符串,放到redis中

# redis对字符串的操作:

from pool import POOL
import redis
conn = redis.Redis(connection_pool=POOL)
...  # 对字符串的操作
conn.close()

# 字符串操作:
1、set(name, value, ex=None, px=None, nx=False, xx=False)   设置值

conn.set('hobby','篮球')
# 带过期时间
conn.set('age','19',ex=3)
conn.set('age','19',px=3000)
# 如果key存在才设置或不存在才设置
# nx,如果设置为True,则只有name不存在时,当前set操作才执行,值存在,就修改不了,执行没效果
# xx,如果设置为True,则只有name存在时,当前set操作才执行,值存在才能修改,值不存在,不会设置新值
conn.set('age',19,nx=True)
conn.set('age',99,nx=True)
conn.set('age',99,xx=True)
conn.set('yy',99,xx=True)

2、setnx(name, value)  存在就不改了
        conn.setnx('age',999) # 等同于 conn.set('age',19,nx=True)

3、psetex(name, time_ms, value) # 设置过期时间
        conn.psetex('xxx',3000,'阿斯顿发')
        conn.setex('xxx',3,'阿斯顿发')

4、mset(*args, **kwargs) 批量设置
        conn.mset({'name':'yyy','age':888,'height':180})

5、get(name) # 获取
        res=conn.get('name')
        print(res)

6、mget(keys, *args)   # 批量获取

        res=conn.mget(['name','age','height'])
        print(res)
        # ['name','age','height']-->['name','age','height']--->[name,age,height]
7、getset(name, value)  # 拿完再修改完
        res=conn.getset('name','彭于晏')
        print(res)

8、getrange(key, start, end)  数字指的是字节长度

# 字符:  a   b  你   中  国
# 字节:  存中文,utf-8,需要3个字节存一个字符
res=conn.getrange('name',0,2) # 前闭后闭区间
print(res)
print(str(res,encoding='utf-8'))

s='lqz厉害'
print(len(s))
print(len(bytes(s,encoding='utf-8')))
print(len(bytes(s,encoding='gbk')))

9、setrange(name, offset, value)   # 设置字节,在第几个位置设置什么
        conn.setrange('name',3,'eeee')

# 比特位操作:

setbit(name, offset, value)
print(conn.getbit('name',3))
getbit(name, offset)
bitcount(key, start=None, end=None)
bitop(operation, dest, *keys)

10、字节长度 strlen(name)
        print(conn.strlen('name'))
11、自增  incr(self, name, amount=1)
        incrby
        conn.incrby('age')       # 文章阅读量  计数器  单线程 不会有并发安全问题

12、自增小数   incrbyfloat(self, name, amount=1.0)

13、减  decr(self, name, amount=1)
        conn.decrby('age',2)

14、追加  append(key, value)

        conn.append('age',8888)
        conn.append('hobby','很好')
        conn.close()

redis之hash操作

# hash形式:字典  key -value形式,都是无序的

# 应用场景: 缓存、计数器
# 基本运用:

from redis import Redis
conn = Redis(host='127.0.0.1', port=6379, db=0)
...
conn.close()

1、hset(name, key, value)  设置值
        conn.hset('userinfo','name','lqz')
        conn.hset('userinfo','age',18)


2、hmset(name, mapping)  批量设置
        conn.hmset('userinfo1',{'name':'彭于晏','age':19})
        conn.hset('userinfo2', mapping={'name': '刘亦菲', 'age': 19, 'hobby': '抽烟'})

3、hget(name,key)  拿值
         print(conn.hget('userinfo2','hobby'))

4、hmget(name, keys, *args) 批量获取值
        print(conn.hmget('userinfo2','hobby','name','age'))
        print(conn.hmget('userinfo2',['hobby','name','age']))

5、hgetall(name)  获取所有, 慎用,可能数据多,一次性取内存会爆掉
        res=conn.hgetall('userinfo2')
        print(res)

6、hlen(name) 统计长度
        print(conn.hlen('userinfo2'))

7、hkeys(name)  获取所有的key
        print(conn.hkeys('userinfo2'))

8、hvals(name)  获取所有value
        print(conn.hvals('userinfo2'))

9、hexists(name, key)   判断是否存在          T/F
        print(conn.hexists('userinfo2','hobby1'))

10、hdel(name,*keys)   删除
        res=conn.hdel('userinfo2','hobby')
        print(res)

11、hincrby(name, key, amount=1)   加一,做计数器
        conn.hincrby('userinfo2','age')12、hincrbyfloat(name, key, amount=1.0)    加小数
        conn.hincrbyfloat('userinfo2', 'age', amount=1.2)
12、hscan(name, cursor=0, match=None, count=None)   一点点取值

for i in range(1000):
   conn.hset('map_demo',i,'鸡蛋_%s'%i)
# 一次性取出来
res=conn.hgetall("map_demo")
print(res)

# 一点点取---》取的数量不准确(上下相差一点点),下次取值取决于上次的结果---》不单独使用
res=conn.hscan('map_demo',cursor=0,count=20)   # 从第0个位置开始取20条
print(res) # (数字,{数据})
print(len(res[1]))

res=conn.hscan('map_demo',cursor=320,count=10)
print(res) # (数字,{数据})

conn.hscan('map_demo')

13、 hscan_iter(name, match=None, count=None)    一点点取
        res=conn.hscan_iter('map_demo',count=10)  
# 内部通过调用 hscan实现 每次取10条,用完再继续取10条,直到所有数据都取完

   内部是生成器, 取出所有数据等同于 hgetall

redis之list操作

# 作用
    1 跨进程间通信,消息队列
    2 实现分布式
    3 队列和栈

# 基本运用:

from redis import Redis
conn = Redis(host='127.0.0.1', port=6379, db=0)
...
conn.close()

1、 lpush(name, values)   从左向右插入值
        conn.lpush('girls', '刘亦菲')  
        conn.lpush('girls', '迪丽热巴')  

2、rpush(name, values) 表示从右向左操作
        conn.rpush('girls','李清照')

3、lpushx(name, value)   存在才放进去,不存在不行
        conn.lpushx('girls','lqz')  
        conn.lpushx('boys','lqz')  


4、rpushx(name, value) 表示从右向左操作
        conn.rpushx('girls','小红')

5、llen(name)   列表长度
        print(conn.llen('girls'))

6、linsert(name, where, refvalue, value))
        #在 刘亦菲 后面插入 上海刘亦菲
        conn.linsert('girls',where='after',refvalue='刘亦菲',value='上海刘亦菲')
        conn.linsert('girls', where='before', refvalue='刘亦菲', value='山东刘亦菲')


7、lset(name, index, value) 左往右第几个位置插入
        conn.lset('girls',1,'lqz')  
        conn.lset('girls',3,'lqz')  

8、lrem(name, value, num)  删除
        conn.lrem('girls',1 ,'lqz') # 从左往右删1个
        conn.lrem('girls',-1 ,'lqz') # 从右往左删1个
        conn.lrem('girls',0 ,'lqz') # 所有都删除

9、lpop(name)  从左往右弹出一个
        print(conn.lpop('girls'))

10、rpop(name) 表示从右向左操作
        print(str(conn.rpop('girls'),encoding='utf-8'))

11、lindex(name, index)   按索引取值,从0开始
        res=conn.lindex('girls',1) 
        print(str(res,encoding='utf-8'))


12、lrange(name, start, end)   取范围内的值
        res=conn.lrange('girls',0,1) # 前闭后闭区间
        print(res)


13、ltrim(name, start, end)     截取列表范围
        conn.ltrim('girls',1,3)  # 前闭后闭


14、rpoplpush(src, dst)       #两个列表 ,从第一个列表的右侧弹出,放到第二个列表的左侧

15、blpop(keys, timeout)      # 阻塞式弹出,可以做消息队列,分布式
        res=conn.blpop('boys',timeout=5)   五秒内
        print(res)

16、 r.brpop(keys, timeout),从右向左获取数据

17、brpoplpush(src, dst, timeout=0)


分布式:你计算一个,我计算一个

redis其他操作

# 通用操作:
        delete(*names):删除
        exists(name):存在几个
        keys(pattern='*'):匹配key值
        expire(name ,time):设置过期时间
        rename(src, dst):重命名
        move(name, db)):移动库
        randomkey():随机弹出一个key
        type(name):查看类型

from redis import Redis

conn = Redis(host='localhost', port=6379, db=0)

# 可以删除多个
conn.delete('name','age')

# redis里存在几个
res=conn.exists('userinfo1','name','height')
print(res)  # 2

# 可以写个匹配,以u开头的所有key
res=conn.keys('u*')
print(res)

# 设置key且有过期时间
conn.expire('girls',10)

# 重命名
conn.rename('name','name1')

# 移动库
conn.move('bobby1',2)

# 随机弹出一个key值
print(conn.randomkey())

# 查看类型
print(conn.type('height')) #string
print(conn.type('map_demo')) #hash

conn.close()

django中使用redis

方式一:通用方式

# 写个pool.py,然后在哪里用,导入用即可:

# utills/pools.py
import redis

POOL = redis.ConnectionPool(
    host='localhost',
    port=6379,
    db=0,
    decode_responses=True,
    max_connections=10
)
# apps/user/views.py
# redis测试
from utills.pool import POOL
import redis

class RedisView(ViewSet):
    def list(self, request):
        conn = redis.Redis(connection_pool=POOL)
        conn.incrby('count')
        count = conn.get('count')
        return APIResponse(msg='您是第%s个访问的' % count)

方式二:配置文件配置

# settings/dev.py
#  配置redis
CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
            "CONNECTION_POOL_KWARGS": {"max_connections": 100},
            # "PASSWORD": "123",

        }
    }
}
# apps/user/views.py
# redis测试
from django_redis import get_redis_connection

class RedisView(ViewSet):
    def list(self, request):
        conn = get_redis_connection()   # 从池中获取一个链接
        conn.incrby('count')
        count = conn.get('count')
        return APIResponse(msg='您是第%s个访问的' % count)

django的redis缓存

# django内置的缓存:缓存的位置在内存,只要项目一重启,数据就没了

        cache.set()  设置缓存
        cache.get()  获取缓存
# redis:缓存放到 redis中 ,redis可以持久化,项目停止,但redis还运行,数据就不会丢

   如下配置,以后只要使用 cache.set  和 cache.get 通过都是去redis设置和取:

CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
            "CONNECTION_POOL_KWARGS": {"max_connections": 100}
            # "PASSWORD": "123",
        }
    }
}
# redis缓存
from django.core.cache import cache

class CacheView(ViewSet):
    def list(self, request):
        name = request.query_params.get('name')
        cache.set('name', name,10)
        return APIResponse(msg='您传入的数据已经加入缓存')

    def create(self,request):
        res=cache.get('name')
        return APIResponse(msg='您传入的数据是:%s'% res)

# 优势:redis 分数据类型, 只能设置5种数据类型
              django的缓存来讲 ,不限制类型,可以放python的任意类型
              用 cache.set()放入任意类型,取出来还是这个类型
# 底层原理:

        把你存储的类型,使用pickle序列化,bytes格式,当redis的字符串形式存到redis中
# 所以以后咱们做redis的操作,可以直接使用django的缓存, 不需要考虑类型

首页轮播图接口缓存

# 原因:首页轮播图接口,只要有一个用户访问一次首页,就会查询一次数据库
              用户量很大,同时来访问首页,不停的查询 Banner表

# 做缓存:django的cache

        第一次去数据库拿,把取出来的数据,放到缓存中,以后只要访问轮播图接口,都从缓存中取,这个接口的响应速度就会非常快

# 提高速度:接口+缓存

# apps/home/views.py
from django.conf import settings
from utills.common_response import APIResponse
from utills.common_logger import logger
from rest_framework.mixins import ListModelMixin


# 查询所有轮播图
class BannerView(GenericViewSet, CommonListModelMixin):
    # qs对象可以切片,limit 2
    queryset = Banner.objects.all().filter(is_delete=False, is_show=True).order_by('orders')[:settings.BANNER_COUNT]
    serializer_class = BannerSerializer

    def list(self, request, *args, **kwargs):
        # 先查缓存,缓存中有直接返回
        banner_list = cache.get('banner_list')  # 列表类型
        # 缓存中没有:去数据库查
        if not banner_list:
            logger.info('走了数据库')
            res = ListModelMixin.list(self, request, *args, **kwargs)
            banner_list = res.data
            cache.set('banner_list', banner_list)
        return APIResponse(results=banner_list)

缓存其他

# 问题1:双写一致性

        后期如果banner表中数据变了,由于一直取的是缓存数据,缓存不会变导致数据不一致
# 解决:mysql  redis要同步写
        
# 问题2:所有查询所有或单条的接口,都可以加缓存
               封装一个 mixin的类,不需要重写list方法,只需要配置一下,就能使用缓存

后续只需配上cache_key就是走了缓存,没配就是走数据库:

# utills/mixins.py
# 封装缓存
from utills.common_logger import logger
from django.core.cache import cache


class CacheListModelMixin(ListModelMixin):
    cache_key = None

    def list(self, request, *args, **kwargs):
        if self.cache_key:
            res = cache.get(self.cache_key)
            if not res:
                logger.info('走了数据库')
                response = super(CacheListModelMixin, self).list(request, *args, **kwargs)
                cache.set(self.cache_key, response.data)
                res = response.data
            return APIResponse(results=res)
        else:
            res = super(CacheListModelMixin, self).list(request, *args, **kwargs)
            return APIResponse(results=res.data)
# apps/home/views.py
# 使用封装的redis缓存
from utills.mixins import CacheListModelMixin


class BannerView(GenericViewSet, CacheListModelMixin):
    cache_key = 'banner_list'
    queryset = Banner.objects.all().filter(is_delete=False, is_show=True).order_by('orders')[:settings.BANNER_COUNT]
    serializer_class = BannerSerializer

今日思维导图:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/405071.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数据库增删改查

DDL: 数据定义语言,用来定义数据库对象(数据库、表、字段)DML: 数据操作语言,用来对数据库表中的数据进行增删改DQL: 数据查询语言,用来查询数据库中表的记录DCL: 数据控制语言,用来创建数据库用户、控制数…

高录用快见刊【最快会后两个月左右见刊】第三届社会科学与人文艺术国际学术会议 (SSHA 2024)

第三届社会科学与人文艺术国际学术会议 (SSHA 2024) 2024 3rd International Conference on Social Sciences and Humanities and Arts *文章投稿均可免费参会 *高录用快见刊【最快会后两个月左右见刊】 重要信息 会议官网:icssha.com 大会时间:202…

基于生成扩散模型的分子对接程序-DiffDock安装及使用

欢迎浏览我的CSND博客! Blockbuater_drug …点击进入 文章目录 前言一、DiffDock是什么?二、DiffDock安装步骤1. 下载2.创建conda环境并安装STEP 1. 创建conda环境并配置STEP 2. 配置ESM和OpenFoldSTEP 3. 检查cuda和pytorch geometric安装STEP 4. 检查p…

Linux:Jenkins用户权限和管理

1.下载插件 由于Jenkins的默认权限管理并不是很精细所以我们安装一个插件进行权限的一个管理 插件名称为:Role-based Authorization Strategy 安装完插件我们再去配置一下 进入全局安全配置 选择这个Role-Based Strategy策略然后保存 2.创建角色 我们这里主要使…

ArcgisForJS如何在线编辑ArcGIS Server发布的几何要素?

文章目录 0.引言1.ArcGIS创建几何要素2.ArcGIS Server发布几何要素3.ArcgisForJS在线编辑ArcGIS Server发布的几何要素 0.引言 ArcGIS For JS 是一种用于创建和编辑地理信息的 JavaScript 库,它允许用户在线编辑 ArcGIS Server 发布的几何要素。本文从ArcGIS创建几…

小程序--应用生命周期

小程序的应用周期处理逻辑都写在app.js中。 一、onLaunch 小程序启动时(初始化完成)执行,只执行一次。 常用于小程序更新,获取启动参数,获取场景值。 二、onShow 小程序启动,或从后台切换至前台时执行。 …

代码随想录算法训练营day20||二叉树part07、● 530.二叉搜索树的最小绝对差 ● 501.二叉搜索树中的众数 ● 236. 二叉树的最近公共祖先

530.二叉搜索树的最小绝对差 【需要领悟一下二叉树遍历上双指针操作,优先掌握递归】 给你一个二叉搜索树的根节点 root ,返回 树中任意两不同节点值之间的最小差值 。 差值是一个正数,其数值等于两值之差的绝对值。 思路 题目中要求在二叉…

第四十天| 343. 整数拆分、96.不同的二叉搜索树

Leetcode 343. 整数拆分 题目链接:343 整数拆分 题干:给定一个正整数 n ,将其拆分为 k 个 正整数 的和( k > 2 ),并使这些整数的乘积最大化。返回 你可以获得的最大乘积 。 思考:动态规划。…

探索Promise异步模式抽象的变体——Promise.race篇

如果阅读有疑问的话,欢迎评论或私信!! 本人会很热心的阐述自己的想法!谢谢!!! 文章目录 前言初识Promise.race探索Promise.raceAPI实例 前言 在本栏前一篇Promise.all中,我们可以实…

美格智能联合罗德与施瓦茨完成5G RedCap模组SRM813Q验证,推动5G轻量化全面商用

全球5G发展进入下半场,5G RedCap以其低成本、低功耗的特性成为行业焦点。近日,中国移动携手合作伙伴率先完成全球最大规模、最全场景、最全产业的RedCap现网规模试验,推动首批芯片、终端具备商用条件,RedCap端到端产业已全面达到商…

【Vuforia+Unity】AR02-长方体物体识别(Multi Targets)

1.创建模型 选择多维长方体图,这个长方体是生活中的真实物体的拍摄图,提前把6个面拍摄好并裁剪干净。 官网创建模型https://developer.vuforia.com/targetmanager/project/targets?projectId0ddbb5c17e7f4bf090834650bbea4995&avfalse 设置长宽高…

状态模式:灵活应对对象行为变化,实现状态驱动的智能设计

文章目录 **一、技术背景与应用场景****为何使用状态模式?****典型应用场景包括但不限于:** **二、状态模式定义与结构****三、使用步骤举例****四、优缺点分析****总结** 一、技术背景与应用场景 状态模式是一种行为设计模式,用于处理一个对…

分享一个UE的SmoothStep小技巧

SmoothStep节点可以制作更平滑的动画,而如果将max参数作为值传入将value和min参数作为约束,则可以做出类似冲击波的渐变效果: 并且通过修改value与min之间的数值差,可以调节渐变。 这个技巧主要就是可以产生硬边。 比如我们可…

2024年阿里云服务器新购、续费、升级优惠政策和优惠活动大全

2024年阿里云服务器购买、续费、升级优惠政策整理,阿里云服务器优惠价格表:轻量2核2G3M服务器61元一年、2核4G4M带宽165元1年,云服务器4核16G10M带宽26元1个月、149元半年,阿里云ECS云服务器2核2G3M新老用户均可99元一年续费不涨价…

信息系统项目管理师(高项)—学习笔记

第一章信息化发展 1.1 信息与信息化 1.1.1 信息 信息是物质、能量及其属性的标示的集合,是确定性的增加。 它以物质介质为载体,在传递和反映世界各种事物存在方式、运动状态等的表征。 信息不是物质,也不是能力,它以一种普遍…

实验室预约|实验室预约小程序|基于微信小程序的实验室预约管理系统设计与实现(源码+数据库+文档)

实验室预约小程序目录 目录 基于微信小程序的实验室预约管理系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、微信小程序前台 2、管理员后台 (1)管理员登录 (2)实验室管理 (3)公告信息…

天府锋巢直播基地:打造西部地区成都直播基地生态圈的领军标杆

数字经济蓬勃发展,直播产业成为赋能引擎以及新的经济增长点。直播电商作为数字经济的一大板块,对我国推动数字化建设有着非常大的作用。德商产投与无锋科技联袂打造了天府锋巢直播产业基地,该成都直播基地致力于打造全域直播基地,…

某胜物流软件三个接口sql注入漏洞(附漏洞检测脚本)

免责声明 文章中涉及的漏洞均已修复,敏感信息均已做打码处理,文章仅做经验分享用途,切勿当真,未授权的攻击属于非法行为!文章中敏感信息均已做多层打马处理。传播、利用本文章所提供的信息而造成的任何直接或者间接的…

Leetcoder Day20| 二叉树 part09+总结

语言:Java/Go 669. 修剪二叉搜索树 给你二叉搜索树的根节点 root ,同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树,使得所有节点的值在[low, high]中。修剪树 不应该 改变保留在树中的元素的相对结构 (即,如果没有被移…

jenkins报错:Pseudo-terminal will not be allocated because stdin is not a terminal

jenkins的流水线部分代码如下 sh ssh root192.168.2.234 << remotessh cd /var/lib/jenkins/workspace/txkc /usr/local/maven/apache-maven-3.8.6/bin/mvn clean package -U ls remotessh执行流水线出现报错&#xff1a;Pseudo-terminal will not be allocated because…