【实战项目】Django-Vue007---Redis、Python操作redis之普通连接和连接池、redis操作各种数据、django中使用redis

news2024/11/17 12:29:26

回顾

1、用户登录注册相关5个接口

多方式登录接口
手机号是否存在接口
发送验证码接口
验证码登录接口
验证码注册接口

2、可以写验证码注册+登录接口

如果手机号存在,直接登录成功
如果手机号不存在,直接创建用户,并且成功登录(签发token)
可以不用序列化类,直接写在视图类里面

在这里插入图片描述

上面就是注册加登录的接口的代码逻辑

3、发送短信二次封装
在这里插入图片描述

4、发送短信接口
在这里插入图片描述

5、验证码登录接口

手机号、验证码  =====> post

视图函数代码:

def mobile_login(self, request):
	# 逻辑写在序列化类中
	ser = serializer.MobileLoginSerializer(data=request.data)  # 前端传过来的数据,在data中
	ser.is_valid(raise_exception=True)  # 先走字段自己的规则,然后走全局的钩子
	# 配置了这个raise_exception=True,相当于raise APIException("用户名密码错误")、如果有异常的话。下面的代码就不会走了7
	token = ser.context.get("token")  # 这个context相当于序列化类和视图函数之间沟通的桥梁
	username = ser.context.get("username")
	return APIResponse(msg="登录成功", username=username, token=token)

序列化代码:

class MobileLoginSerializer(serializers.ModelSerializer):  # 以后都用ModelSerializer
	# 因为mobile在表中,是唯一的,因为是反序列化,没有保存,所以这里要重写mobile字段
	mobile = serializers.CharField()
	# 需要重写code,因为User表里面没有code,所以必须重写
	code = serializers.CharField()

	class Meta:
		model = models.User
		fields = ['code', 'mobile']

	def validate(self, attrs):  # 写一个全局规则
		# 1、校验code是否正确:从缓存中根据手机号获取code,比较
		# 2、根据手机号拿到当前用户
		# 3、根据用户签发token
		# 4、把token放在序列化类的对象中
		# :param attrs: 校验过后的数据(前面的校验规则,走完之后的那个字典)
		# :return:
		# 这个里面主要就是校验用户和签发token
		user = self._get_user(attrs)  # 获取这个用户
		token = self._get_token(user)  # 获取这个用户的token
		# 现在拿到token了,现在token在serializers,现在要给视图类
		# 重点来了:把token放在序列化类的对象中,不建议self.token = token这样放
		# context上下文,是一个字典
		self.context["token"] = token
		self.context["username"] = user.username
		return attrs  # 把校验过后的数据再返回

	def _get_user(self, attrs):  # 不是私有(__两个横线才是私有),但是自己认为尽量只给内部用
		# 获取这个用户
		# :param attrs: 校验过后的数据(前面的校验规则,走完之后的那个字典)
		# :return:
		code = attrs.get("code")
		mobile = attrs.get("mobile")
		# 校验code
		# 通过key值,取出对应的value,当时是这样存进去的cache.set(settings.CACHE_SMS % mobile, code)
		cache_code = cache.get(settings.CACHE_SMS % mobile)
		if cache_code and code == cache_code:  # 有值,并且相等的情况下
			# 验证码一旦验证过,验证码需要失效
			cache.set(settings.CACHE_SMS % mobile, "")  # 第一种,直接将key值设置为空
			# cache.set(settings.CACHE_SMS % mobile, code, "-1")  # 第二种,设置过期时间是-1
			user = models.User.objects.filter(mobile=mobile).first()
			if user:  # 如果有这个用户
				return user
			else:  # 如果用户不存在
				raise ValidationError({"detail": "用户名或密码错误"})  # {"detail": "用户名或密码错误"}
		else:
			ValidationError({"detail": "验证码错误"})

	def _get_token(self, user):  # 通过user签发token,把token,return出去
		payload = jwt_payload_handler(user)
		token = jwt_encode_handler(payload)
		return token

验证码注册接口

手机号、密码、验证码=====> post

在这里插入图片描述

序列化代码:

class RegisterUserSerializer(serializers.ModelSerializer):
	# code不是user表的字段,必须重写
	code = serializers.CharField(max_length=4, min_length=4, write_only=True)  # 写write_only,只做序列化

	class Meta:
		model = models.User  # 跟哪个表有关系
		fields = ["mobile", "code", "password"]  # 这个是用来做反序列化,前端传过来的数据,用来做校验
		extra_kwargs = {"mobile": {"write_only": True},
		                "password": {"write_only": True}}
	# 我们的意图是做反序列化的,但是源码里面调了ser.data,也会做序列化,所以说写了write_only

	# 校验字段
	def validate(self, attrs):
		# 1、校验code是否正确
		# 2、将code从attrs中剔除,表里面没有这个字段,不需要存这个字段;因为mobile是必填项,不需要校验mobile
		# 3、使用手机号作为用户名,后期可以改
		code = attrs.get("code")
		mobile = attrs.get("mobile")
		cache_code = cache.get(settings.CACHE_SMS % mobile)
		if cache_code and code == cache_code:  # 有值,并且相等的情况下
			# 把code剔除:code不是user表的字段,不能用来保存
			attrs.pop("code")
			# 需要创造一个username:因为用户注册的时候,不会填写用户名
			attrs["username"] = mobile  # 这里可以随机任意字符串
		else:
			raise ValidationError({"detail": "验证码错误"})  # 里面写成字典的形式,可以给到Exception
		return attrs

	# 为什么要重写create:因为password是明文传过来的,要把它存进去,就需要搞成密文;就需要使用models.User.objects.create_user来创建用户
	# 而不是models.User.objects.create,如果是别的表,根本不需要
	def create(self, validated_data):
		user = models.User.objects.create_user(**validated_data)
		# 只要调用了self.perform_create(serializer),就会调了 serializer.save(),下面这一行代码就会执行
		# user = self.context["user"]
		return user

在这里插入图片描述

前端
在这里插入图片描述
在这里插入图片描述

如果加在Local Storage里面,效果就是关闭浏览器之后,打开还是之前的页面

Redis介绍

1、非关系型数据库,纯内存操作,性能很高,key-value存储,没有表的概念
2、用来做缓存,计数器,验证码(几分钟之后过期),geo地理位置信息(附近的人),发布订阅,独立用户统计(看日活,避免一个人重复登录,放在一个集合里面)
3、上面的是他的用处,用的做多的还是缓存
4、5大数据类型:字符串、列表、哈希、集合、有序集合
5、6.x之前是单线程,单进程;为什么这么快? qps:每秒查询率  10W
	1、纯内存
	2、使用了IO多路复用的模型:epoll(IO多路复用有3个模型:select、poll、epoll)
	3、避免了线程间切换的浪费(6.x之后没有这个说法了)
6、安装
	官方提供了源码,c语言写的,需要编译安装;
	编译型语言,如果要执行,需要在不同平台上编译成不同平台上的可执行文件
	在linux上装,通过gcc编译,编译成可执行文件就可以运行了
	在windows上,官方不支持;会有第三方提供季节方案
	监听的端口:6379
	win上自动做成服务,启动关闭服务
	使用命令启动服务端
		redis-server 配置文件
	客户端连接
		redis-cli
		Python连接
		图形化的客户端有很多
			推荐:redis-desktop-manager
			用工具连接到redis
				先把服务起来

在这里插入图片描述
在这里插入图片描述

7、QT:平台

	使用c/C++语言在平台上开发----》图形化界面软件(GUI)
	pyqt:在qt平台上使用python代码写图形化界面
	Tkinter

pymysql和mysql的选择

django 2.7之后,
	如果还使用pymysql连接mysql,源码不兼容,需要去改源码
	mysqlclient:什么都不用配。直接用,不需要改源码

Python操作redis之普通连接和连接池

参考:https://www.cnblogs.com/liuqingzheng/articles/9833534.html

安装模块

	pip install redis

普通连接
在这里插入图片描述

	默认有16个库
	上面这个是默认情况,一般情况下会有一堆参数

在这里插入图片描述

	这个里面都有默认值,默认有16个库,默认连的是0

在这里插入图片描述

redis连接池

	补充:django连接mysql是没有连接池的,但是第三方会有解决方案,提供了连接池的库

在这里插入图片描述
在这里插入图片描述

	pool = redis.ConnectionPool(max_connections=10)
	这个代码只能执行一次(就是说:只能创建一个池子,后面的都从这个池子里面拿链接)
	所以上面的代码一定不能放在线程里面
	所以池需要做成单列,整个项目真能有一个
	在Python中,有5种写单列的情况:https://www.liuqingzheng.top/python/%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1%E9%AB%98%E9%98%B6/19-%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1%E9%AB%98%E7%BA%A7%E5%AE%9E%E6%88%98%E4%B9%8B%E5%8D%95%E4%BE%8B%E6%A8%A1%E5%BC%8F/
	第一种最简单:Python的模块就是天然的单列

在这里插入图片描述

redis操作之字符串操作

说的是对应的value值是字符串

字符串操作(不需要全记住)
	set(name, value, ex=None, px=None, nx=False, xx=False)
	setnx(name, value)
	setex(name, value, time)
	psetex(name, time_ms, value)
	mset(*args, **kwargs)

	mget({'k1': 'v1', 'k2': 'v2'})
	get(name)
	mget(keys, *args)
	mget('k1', 'k2')
	getset(name, value)
	getrange(key, start, end)
	setrange(name, offset, value)
	setbit(name, offset, value)
	getbit(name, offset)
	bitcount(key, start=None, end=None)
	bitop(operation, dest, *keys)
	bitop("AND", 'new_name', 'n1', 'n2', 'n3')
	strlen(name)
	incr(self, name, amount=1)
	incrbyfloat(self, name, amount=1.0)
	decr(self, name, amount=1)

1、set(name, value, ex=None, px=None, nx=False, xx=False)

在Redis中设置值,默认,不存在则创建,存在则修改
参数:
	 ex,过期时间(秒)
	 px,过期时间(毫秒)
	 nx,如果设置为True,则只有name不存在时,当前set操作才执行,值存在,就修改不了,执行没效果
	 xx,如果设置为True,则只有name存在时,当前set操作才执行,值存在才能修改,值不存在,不会设置新值
ex,过期时间(秒)
import redis
conn = redis.Redis()
# ex=8这个值设置过之后,8秒就没有了。适合存验证码子类的
# 不设置的话,就是永久的在里面
conn.set("hobby", "篮球", ex=8)
conn.close()
  1. nx,如果设置为True,则只有name不存在时,当前set操作才执行,值存在,就修改不了,执行没效果(用的不多)
    xx,如果设置为True,则只有name存在时,当前set操作才执行,值存在才能修改,值不存在,不会设置新值(用的不多)

在这里插入图片描述
在这里插入图片描述

setnx(name, value)
	就是	set(name, value, nx=True)的简写

setex(name,time,value)  #过期时间是中间的参数
	就是	 set(name, value, ex=None)的简写
	18

4.psetex(name, time_ms, value)

以毫秒记的过期时间

5、 mset(*args, **kwargs)

批量设置值、批量获取值
批量操作快

在这里插入图片描述

6、get

获取值

在这里插入图片描述

7、mget

批量获取

在这里插入图片描述
在这里插入图片描述

8、getset

设置新值并获取原来的值

在这里插入图片描述

9、getrange(key, start, end)

取一个范围

在这里插入图片描述
在这里插入图片描述

前闭后闭区间,以unicode编码存储,取的是字节

10、setrange(name, offset, value)

修改字符串内容,从指定字符串索引开始向后替换(新值太长时,则向后添加)
参数:
	offset,字符串的索引,字节(一个汉字三个字节)
	value,要设置的值

在这里插入图片描述

11、strlen(name)

返回name对应值的字节长度(一个汉字3个字节)

在这里插入图片描述

12、incr(self, name, amount=1)

自增:执行一次,自增一

在这里插入图片描述

作用:可以统计页面访问量

13、decr(self, name, amount=1)

自减

14、incrbyfloat(self, name, amount=1.0)

浮点数自增

在这里插入图片描述

需要记住的

get
set
mget
mset
strlen
incr

Python操作redis操作之hash操作

hset(name, key, value)
hmset(name, mapping)
hget(name,key)
hmget(name, keys, *args)
hgetall(name)
hlen(name)
hkeys(name)
hvals(name)
hexists(name, key)
hdel(name,*keys)
hincrby(name, key, amount=1)
hincrbyfloat(name, key, amount=1.0)
hscan(name, cursor=0, match=None, count=None)
hscan_iter(name, match=None, count=None)

只要是hash类型的,开头都是以h开头的

1、hset(name, key, value) 也可以 hmset(name, mapping)就是conn.hset(“user_3_info”, mapping={“name”: “lyf”, “age”: 19, “hobby”: “篮球”})

设置值

在这里插入图片描述

import redis
conn = redis.Redis()
res = conn.hset("hash1", "name", "xff")
conn.close()

在这里插入图片描述
在这里插入图片描述

2、hget

获取值
import redis
conn = redis.Redis()
print(conn.hget("hash1", "age"))
conn.close()

在这里插入图片描述

3、hmset(name, mapping)

批量的设置值
import redis
conn = redis.Redis()
res = conn.hmset("user_1_info", {"name": "lyf", "age": 19, "hobby": "篮球"})
conn.close()

在这里插入图片描述

4、hmget(name, keys, *args)

批量的获取值
import redis
conn = redis.Redis()
# res = conn.hmget("user_1_info", "age", "hobby")
res = conn.hmget("user_1_info", ["age", "hobby"])
print(res)
conn.close()

在这里插入图片描述
在这里插入图片描述

5、hgetall(name)

获取所有(慎用,生产环境中,尽量不要用;数据量可能比较多)

在这里插入图片描述

import redis
conn = redis.Redis()
res = conn.hgetall("user_2_info")
print(res)
conn.close()

6、hlen(name)

获取长度,获取有多少key值

在这里插入图片描述

7、hkeys(name)

获取所有的key

在这里插入图片描述

8、hvals(name)

获取所有的value

在这里插入图片描述

9、hexists(name, key)

判断对应的key是不是在name这个字典里面

在这里插入图片描述

10.hdel(name,*keys)

将name对应的hash中指定key的键值对删除

在这里插入图片描述

11、hincrby(name, key, amount=1)

自增name对应的hash中的指定key的值,不存在则创建key=amount

在这里插入图片描述

13、hscan

因为hash,字典里面键值对是无序的。所以我们取前多少个值的时候,不一定是我们想要的
从hash中取出一部分值,以count为基准,但是不一定准。所以我们一般不用这个hscan,这个是给hscan_iter用的

在这里插入图片描述

14、hscan_iter(name, match=None, count=None)

分批获取;不使用hgetall,可以用hscan_iter代替

在这里插入图片描述

现在想要把数据取出来

在这里插入图片描述
在这里插入图片描述

这个就是生成器的概念,一次拿指定个数,一直到拿完为止

记住

hset
hget
hmset
hmget
hlen
hexists
hincrby
hscan_iter:分批获取数据

Python操作redis操作之list操作

lpush(name,values)
lpushx(name,value)

llen(name)
linsert(name, where, refvalue, value))
r.lset(name, index, value)
r.lrem(name, value, num)
lpop(name)
lindex(name, index)
lrange(name, start, end)
ltrim(name, start, end)
rpoplpush(src, dst)
blpop(keys, timeout)
brpoplpush(src, dst, timeout=0)

1、lpush(name,values)

在name对应的list中添加元素,每个新的元素都添加到列表的最左边
如果没有name这个key,会创建这个key

在这里插入图片描述

r.lpush('oo', 11,22,33)
保存顺序为: 33,22,11

2、rpush(name, values)

表示从右向左操作,将数据从列表的右侧推到列表里面

在这里插入图片描述

3、lpushx

只有name已经存在时,值添加到列表的最左边

在这里插入图片描述

4、llen(name)

name对应的list元素的个数

在这里插入图片描述

5、linsert(name, where, refvalue, value))

	where:只能写:before 或 after

在这里插入图片描述

6、r.lset(name, index, value)

	给某一个位置重新设置值;位置是从0开始的

在这里插入图片描述

7、r.lrem(name, num, value)

	name对应的list中删除指定的值
import redis
conn = redis.Redis()
conn.lrem("names", 0, "lqz")  # 把内部所有的lqz都移除
conn.lrem("names", 1, "lqz")  # 从左往右移除第一个lqz
conn.lrem("names", -1, "lqz")  # 从右往左移除第一个lqz
conn.close()

8、lpop(name)

	在name对应的列表的左侧获取第一个元素并在列表中移除,返回值则是第一个元素
   rpop(name)
    表示从右向左操作

9、lindex(name, index)

    获取第几个索引的值

在这里插入图片描述

10、lrange(name, start, end)

    获取从起止位置到结束位置的值,前闭后闭

在这里插入图片描述
在这里插入图片描述

11、ltrim(name, start, end)

    修剪

在这里插入图片描述

12、rpoplpush(src, dst)

从一个列表取出最右边的元素,同时将其添加至另一个列表的最左边
参数:
    # src,要取数据的列表的name
    # dst,要添加数据的列表的name

13、blpop(keys, timeout)

将多个列表排列,按照从左到右去pop对应列表的元素

在这里插入图片描述

比如爬虫的时候,需要爬数据,在解析,在入库。这个原本是一条线干的事。因为爬的很快,解析的时候很慢
可以用这个方式完成分布式,可以写一个程序专门负责爬,然后放在队列里面,另一个程序负责解析入库
redis可以实现简单的消息队列。部署在两台机器上,实现IPC(进程间通信)
一台电脑上的进程间,可以使用进程queue,但如果两个进程在不同的机器上,需要借助消息队列的
如果是简单的消息队列,就可以使用redis的list类型
消息队列的作用:就是实现扩进程间的通信
blpop(keys, timeout)后面可以设置超时时间,可以指定夯住的时间


如果想一次性把列表里面的值取出来
res=conn.lrange('names',0,conn.llen('names')  #这样是可以的,但是如果数据大的话,就比较消耗内存
还有一个就是:自定义增量迭代(面试题:Python中生成器在哪个地方用过)
  import redis
	conn=redis.Redis(host='127.0.0.1',port=6379)
	# conn.lpush('test',*[1,2,3,4,45,5,6,7,7,8,43,5,6,768,89,9,65,4,23,54,6757,8,68])
	# conn.flushall()
	def scan_list(name,count=2):
	    index=0
	    while True:
	        data_list=conn.lrange(name,index,count+index-1)
	        if not data_list:
	            return
	        index+=count
	        for item in data_list:
	            yield item
	print(conn.lrange('test',0,100))
	for item in scan_list('test',5):
	    print('---')
	    print(item)

记住

	lpush
	llen
	lrem
	lindex
	lpop
	lrange

通用操作
跟类型没有关系

delete(*names)

根据key值删除redis中的任意数据类型

import redis
conn = redis.Redis()
# 删除redis中任意数据类型
conn.delete("names")
conn.close()

exists(name)

	检测redis的name是否存在
import redis

conn = redis.Redis()
res = conn.exists("names")
print(res)  # 1表示存在,0表示不存在
conn.close()

keys(pattern=‘*’)

	获取所有的key值,可以过滤
import redis
conn = redis.Redis()
res = conn.keys()  # 所有的key值
res = conn.keys(pattern="n*")  # 所有以n开头的key值
res = conn.keys(pattern="nam?")  # 所有以nam开头的,后面再接一个字符的,key值

print(res)
conn.close()

expire(name ,time)

	为某个redis的某个name设置超时时间
	之前我们只可以给字符串设置过期时间,其实所有的都可以设置过期时间
import redis

conn = redis.Redis()
res = conn.expire("name1", 5)  # 将key值是name1的过期时间设置为5秒,时间到了之后,key和value就没有了

print(res)
conn.close()

rename(src, dst)

	对redis的key值重命名为
import redis

conn = redis.Redis()
res = conn.rename("name1", "name2")  # 将key值为name1设置为name2

print(res)
conn.close()

move(name, db)

	将redis的某个值移动到指定的db下
import redis

conn = redis.Redis()
res = conn.move("hash1", 5)  # 将key值为hash1移动到db5里面

print(res)
conn.close()

randomkey()

	随机获取一个redis里面的一个key(不删除)
import redis

conn = redis.Redis()
res = conn.randomkey()  # 随机弹出一个key值

print(res)
conn.close()

type(name)

	查看key对应的value的类型
import redis

conn = redis.Redis()
res = conn.type("test_hash")  # 获取test_hash对应的value的类型
print(res)
conn.close()

redis管道

redis是非关系型数据库,不支持事务
但是redis有管道,我们可以通过管道来模拟事务;要么都成功,要么都失败
import redis

conn = redis.Redis()

# 创建一个管道
pipe = conn.pipeline(transaction=True)
# 开启事务
pipe.multi()

# 向管道中放入命令
pipe.decrby('egon_money', 50)  # 将egon_money对应的value减去50元
# 向管道中放入命令
pipe.incrby('lqz_money', 50)  # 将lqz_money对应的value加上50元

# 上面这两个是一个事务,同时执行,要么成功、要么失败
pipe.execute()  # 执行这一句话的时候,上面的两天命令同时执行

django中使用redis

1、通用方案,跟django没有关系

在这里插入图片描述

pool.py
import redis

# 创建一个连接池
POOL = redis.ConnectionPool(max_connections=1000)
在用的地方
import redis
from .pool import POOL


def test(request):
	conn = redis.Redis(connection_pool=POOL)  # 从池子中拿一个链接出来
	res = conn.get("name2")
	print(res)
	return HttpResponse("ok")

2、django方案,用第三方方案

1、安装django-redis模块
	pip install django-redis

2、setting中配置:
CACHES = {
	"default": {
		"BACKEND": "django_redis.cache.RedisCache",
		"LOCATION": "redis://127.0.0.1:6379",  # redis链接地址根据实际情况改
		"OPTIONS": {
			"CLIENT_CLASS": "django_redis.client.DefaultClient",
			"CONNECTION_POOL_KWARGS": {"max_connections": 100}  # 连接池大小
			# "PASSWORD": "123",    #redis有密码的话,配置出密码
		}
	}
}
3、使用
from django_redis import get_redis_connection

def test(request):
	conn = get_redis_connection()  # 从池子中拿一个链接出来
	res = conn.get("name2")
	print(res)
	return HttpResponse("ok")
一旦使用了第二种,后续的django的缓存,都缓存到redis中
之前的cache.set("name","xxx")就缓存到redis中了

在这里插入图片描述
在这里插入图片描述

所以,我们上面写的验证码的功能,代码都不需要改,直接就缓存到redis中了
上面图中,value的值是“乱码”?
因为django的缓存比较高级:可以缓存Python中所有的数据类型。包括对象(如:request对象)
django把对象通过pickle序列化成二进制,存到redis的字符串中
拿出来之后再用pickle反序列化成对象。所以用cache比conn.set之内的好很多,只管存,只管取。不需要管什么类型了

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【计算机基础学科】操作系统学习笔记(考研王道参考书)

操作系统目录 文章目录操作系统目录一、操作系统概述1.1 操作系统基本概念1.1.1 操作系统的概念、功能1.1.2 操作系统的特性1.1.3 操作系统的发展与分类1.1.4 操作系统的运行机制1.2 内核态与用户态1.3 中断、异常1.4 系统调用~~1.5 计算机的层次结构~~~~1.6 操作系统引导&…

【数学建模】常用算法-主成分分析PCA的Python实现

1前言 本文主要讲解主成分分析析法(PCA)的python实现,后续会跟进实例分析 2 原理-代码实现 2.1 实现步骤 主成分分析PCA是一种应用广泛的和降维方法,对其实现做以下归纳 2.2 代码实现 导入包 import numpy as np定义计算协…

VBA提高篇_12 文本文件逐行读取,输入输出操作自如

文章目录一、VBA打开文本文件的4步操作二、文本输入Excel示例三、 Excel输出文本示例3.1 Open For Output3.2 Open For Append3.3 Print 打印文件3.4 工作簿 循环工作表 循环输出文件四 、先输入后输出 Demo实战演练一、VBA打开文本文件的4步操作 打开文本文件 找到指定文件并调…

看这篇就够了——ubuntu扩展屏幕及装显卡驱动后黑屏问题

1.问题说明首先说明为什么外接屏幕需要装显卡驱动,显卡由GPU和显存构成,又称为显示适配器,与数据的输出有密切关系。在ubuntu系统中,外接显示器是用的独立显卡驱动,而内置屏幕用的是集显驱动,也正是因为调用显卡的不同…

Day01-数据分析图鉴

文章目录Day01-数据分析图鉴一、 数据分析是什么?二、为什么数据分析这么火?三、数据分析的行业现状如何?四、对工作经验要求高吗?五、工资情况六、学完数据分析的效果?1、Python可视化2、TableauDay01-数据分析图鉴 …

Maven打包时出现Process terminated错误

Maven打包时出现Process terminated错误检查maven的配置文件多引入了一次控制器编码错误切点表达式错误用maven打包时出现Process terminated样式的错误,报错如下:查看报错信息 检查maven的配置文件 多引入了一次控制器 注释掉多余的 编码错误 File e…

软件设计质量(一)容错设计

出现非预期错误的原因解决方案原理介绍断根原理原理:将可能造成人错误的原因/条件从根本上排除断绝掉。通过冗余设计,屏蔽掉其中9种错误的方式;案例:USB的SD卡防写开关。4种可能性断根设计为只有1种可能是正确的。软件设计&#x…

【JavaEE初阶】第十节.多线程 (基础篇 ) 线程池(案例四)

文章目录 前言 一、线程池概述 二、线程池的使用方式 2.1 Java标准库中 线程池的使用 2.2 自己动手来模拟实现一个线程池 总结 前言 本篇文章将介绍多线程案例 —— 线程池,这也是一个非常有用的案例 在之前已经介绍过,进程本身已经能做到并发编…

HTTP错误响应码

4XX客户端错误 400 bad request 服务端认为客户端出现了错误,但是不能准确判断是哪种错误401 用户认证信息缺失或者不准确403 服务器理解请求,但是没有权限处理404 not found 服务器没有找到资源405 method not allowed 服务器不支持请求中的method方法…

VSCode加上dotnet7.0来创建开发,vs和vscode创建方法,命令创建和扩展方法创建区别,以及扩展推荐

吐槽一波: .net7出来第二天开始学习,前端vue3ts写法也得学 总监让熟悉一个星期新版本语言就动手开发,还要写前端,再带一个应届生开发,前端跑了我还得顶上, 天天催,天天问我进度怎么样&#xff0…

使用nginx给Nacos集群配置负载均衡

使用nginx的upstream模块进行负载第一、不想要加访问路径配置首先配置的时候需要把nacos配置的访问路径删除vim application.properties重新启动nacos 三个节点都配置一样的vim /etc/nginx/conf.d/default.conf 然后编写nginx的配置文件Nginx服务器ip 192.168.11.154upstream n…

SimCLS: A Simple Framework forContrastive Learning of Abstractive Summarization

论文 代码 摘要 本文提出了一个概念上简单但是强大的抽象摘要框架,SimCLS。它通过对比学习的方式,缓解了Seq2Seq框架固有的目标函数和评价指标不一致的问题,从而可以从模型生成的候选摘要中筛选出真实的评价指标(ROUGE)打分更高的摘要。将…

2023 中科院《国际期刊预警名单》发布,28 本学术期刊有风险,2区期刊14本,有哪些信息值得关注?

2023年1月31日,中国科学院文献情报中心终于发布了2023年《国际期刊预警名单(试行)》! 名单分析: 与往年相比,今年的预警期刊名单变动还是相当大的 1. 生物学和数学期刊全部“洗白”,医学期刊…

Docker 安装可视化管理工具Portainer

简介Portainer是Docker 的图形化管理工具,提供状态显示面板、应用模板快速部署、容器镜像网络数据卷的基本操作(包括上传下载镜像,创建容器等操作)、事件日志显示、容器控制台操作、Swarm集群和服务等集中管理和操作、登录用户管理…

测试工程师笔试题整理01

来源: https://vt.quark.cn/blm/quark-doc-ssr-293/preview?idC2946438A278541B6C1284E5C22269AB 难度:⭐(简单) 一、基础题 1、对于软件测试描述正确的是 (目的是尽可能多的发现程序的错误)(2) 2、软件测试的对象包括(源程序…

解析Linux DMA mapping机制

说明: Kernel版本:4.14ARM64处理器,Contex-A53,双核使用工具:Source Insight 3.5, Visio 1. 概述 DMA(Direct Memory Access):直接存储器访问;先看问题的引入…

OpenWrt之IPTV双线融合教程

文章目录前言OpenWrt版本1. 让路由与光猫互通2. 设置Vlan3. 配置接口4. 配置路由表5. 播放测试后话前言 前段时间开始, 电信就开始整理单播源传播的乱象, 就限制了非内网无法打开直播源, 于是只能搞搞双线融合了, 让我的RTSP源重新焕发生机 OpenWrt版本 22.02 1. 让路由与光猫…

【docker概念和实践 5】(1) 容器数据卷

一、说明 本文的主要内容 什么是数据卷如何生成数据卷将数据卷挂在容器上多容器如何共享数据卷什么是绑定挂载二、数据卷概念 2.1 数据长久保存的要求 在容器运行时,容器内有一个数据存储空间,但是当容器关闭后,这个存储空间内容将被丢失&…

PYTHON官方教程:Python3.11中文版文档

Python 每年都会发布新版本,上半年是功能锁定的测试版,年底是最终版本。 Python 3.11 的特性集刚刚定稿,测试版本已经发布,开发人员在非生产代码上可以尝试使用这个最新版本,验证它能否在你的程序中工作,并…

小白入门pwn笔记--elf文件概述

笔记是根据哔哩哔哩视频所写2、ELF文件概述_哔哩哔哩_bilibili第一集看过大概,很久之前安装过一些工具,所以直接从第二集开始看,遇到没有安装的工具再安装。从今天开始入坑pwn0.pwn的简单介绍exploit:用于攻击的脚本与方案。paylo…