python实现接口自动化
- 代码实现自动化相关理论
- 代码编写脚本和工具实现脚本区别是啥?
- 代码:
- 优点:代码灵活方便
- 缺点:学习成本高
- 工具:
- 优点:易上手
- 缺点:灵活度低,有局限性。
- 总结:
- 功能脚本:工具
- 自动化脚本:代码
- 代码接口自动化怎么做的?
第一步:python+request+unittest;
具体描述?
第二步:封装、调用、数据驱动、日志、报告;
详细举例:
第三步:api\scripts\data\log\report\until…
- 脚本实现
- 使用代码编写自动化脚本的流程
1、抽取功能用例转为自动化用例
2、搭建环境(测试工具、)
3、搭建目录结构
4、编写脚本
5、执行脚本
6、配置持续集成
-
抽取功能转为自动化用例
-
搭建环境(测试工具)
1、python、Pycharm、requests、pymysql、parametrize
2、jenkins、jdk
提示:由于编写的自动化脚本,而自动化脚本编写之前功能已测试完毕,所以不需要在单独搭建项目环境。
- 搭建目录结构
- 代码编写
- config.py
import os
# 服务器地址
HPST = "http://user-p2p-test.itheima.net"# 项目目录路径
dir_path = os.path.dirname(__file__)
- api(api_register_login.py)
from config import HOST
class ApiRegisterLogin:# 初始化def __init__(self, session):# 获取session对象self.session = session # 实例化session,类下面的其他接口就能使用自己的session# 图片验证码urlself.__url_img_code = HOST + "/common/public/verifycode1/{}" # {}是随机变量,用{}占用# 短信验证码urlself.__url_phone_code = HOST + "/member/public/sendSms"# 注册urlself.__url_register = HOST + "/member/public/reg"# 登录urlself.__url_login = HOST + "/member/public/login"# 登录状态urlself.__url_login_status = HOST + "/member/public/islogin"# 获取图片验证码接口 封装def api_img_code(self):pass# 获取短信验证码接口 封装def api_phone_code(self):pass# 注册接口 封装def api_register(self):pass# 登录接口 封装def api_login(self):pass# 查询登录状态接口 封装def api_login_status(self):pass
加上__,只能在当千模块里调用,其他py文件调用不了
- 接口封装 实现
# 获取图片验证码接口 封装def api_img_code(self, random):# 调用get方法,返回响应对象res = self.session.get(url=self.__url_img_code.format(random))return res# 获取短信验证码接口 封装def api_phone_code(self, phone, imgVerifyCode):# 1、定义请求参数data = {"phone": phone,"imgVerifyCode": imgVerifyCode,"type": "reg"}# 2、调用请求方法res = self.session.post(url=self.__url_phone_code, data=data)return res# 注册接口 封装def api_register(self, phone, password, verifycode, phone_code):# 1、定义请求参数data = {"phone": phone,"password": password,"verifycode": verifycode,"phone_code": phone_code,"dy_server": "on","invite_phone": ""}# 2、调用请求方法res = self.session.post(url=self.__url_register, data=data)return res# 登录接口 封装def api_login(self, keywords, password):# 1、定义请求参数data = {"keywords": keywords,"password": password}# 2、调用请求方法res = self.session.post(url=self.__url_login, data=data)return res# 查询登录状态接口 封装def api_login_status(self):res = self.session.post(self.__url_login_status)
- script(test01_register_login.py)
import unittestimport requestsfrom api.api_register_login import ApiRegisterLoginclass TestRegisterLogin(unittest.TestCase):# 初始化def setUp(self):# 获取session对象self.session = requests.session()# 获取ApiRegisterLogin实例self.reg = ApiRegisterLogin(self.session)# 结束def tearDown(self):# 关闭session对象self.session.close()# 获取图片验证码接口 测试def test01_img_code(self):pass# 获取短信验证码接口 测试def test02_phone_code(self):pass# 注册接口测试def test03_register(self):pass# 登录接口 测试def test04_login(self):pass# 查询登录状态 测试def test05_login_status(self):pass
- 注册登录接口调试测试
import unittestimport requestsfrom api.api_register_login import ApiRegisterLoginclass TestRegisterLogin(unittest.TestCase):# 初始化def setUp(self):# 获取session对象self.session = requests.session()# 获取ApiRegisterLogin实例self.reg = ApiRegisterLogin(self.session)# 结束def tearDown(self):# 关闭session对象self.session.close()# 获取图片验证码接口 测试def test01_img_code(self):# 1、调用图片验证码接口r = self.reg.api_img_code(123)# 2、查看响应状态码print(r.status_code)# 获取短信验证码接口 测试def test02_phone_code(self, phone=13600001111, imgVerifyCode=8888):# 1、调用获取图片验证码接口----目的:让session记住cookieself.reg.api_img_code(123)# 2、调用短信验证码接口r = self.reg.api_phone_code(phone=phone, imgVerifyCode=imgVerifyCode)# 3、查看响应结果print(r.json())# 注册接口测试def test03_register(self, phone=13600001111, imgVerifyCode=8888, password="test123", phone_code=666666):# 1、图片验证码接口self.reg.api_img_code(123)# 2、短信验证码接口self.reg.api_phone_code(phone=phone, imgVerifyCode=imgVerifyCode)# 3、注册接口r = self.reg.api_register(phone=phone, password=password, verifycode=imgVerifyCode, phone_code=phone_code)# 4、查看结果print(r.json())# 登录接口 测试def test04_login(self, keywords=13600001111, password="test123"):# 1、登录接口r = self.reg.api_login(keywords=keywords, password=password)# 2、查询结果print(r.json())# 查询登录状态 测试def test05_login_status(self, keywords=13600001111, password="test123"):# 1、调用登录接口self.reg.api_login(keywords=keywords, password=password)# 2、调用查询登录结果接口r = self.reg.api_login_status()print(r.json())
- 断言
说明:判断程序执行
实际结果是否符合预期结果
- 示例:
- 提示:
捕获异常的目的
是为了将错误信息记录下来
,- 捕获信息完成后,
必须抛出异常
import unittestimport requestsfrom api.api_register_login import ApiRegisterLoginclass TestRegisterLogin(unittest.TestCase):# 初始化def setUp(self):# 获取session对象self.session = requests.session()# 获取ApiRegisterLogin实例self.reg = ApiRegisterLogin(self.session)# 结束def tearDown(self):# 关闭session对象self.session.close()# 获取图片验证码接口 测试def test01_img_code(self):try:# 1、调用图片验证码接口r = self.reg.api_img_code(123)# 2、查看响应状态码self.assertEqual(200, r.status_code)except Exception as e:# 日志print(e)# 抛出异常raise# 获取短信验证码接口 测试def test02_phone_code(self, phone=13600001111, imgVerifyCode=8888, expect_text="发送成功"):try:# 1、调用获取图片验证码接口----目的:让session记住cookieself.reg.api_img_code(123)# 2、调用短信验证码接口r = self.reg.api_phone_code(phone=phone, imgVerifyCode=imgVerifyCode)# 3、查看响应结果self.assertIn(expect_text, r.text)except Exception as e:# 日志print(e)# 抛出异常raise# 注册接口测试def test03_register(self, phone=13600001111, imgVerifyCode=8888, password="test123", phone_code=666666, expect_text="注册成功"):try:# 1、图片验证码接口self.reg.api_img_code(123)# 2、短信验证码接口self.reg.api_phone_code(phone=phone, imgVerifyCode=imgVerifyCode)# 3、注册接口r = self.reg.api_register(phone=phone, password=password, verifycode=imgVerifyCode, phone_code=phone_code)# 4、查看结果self.assertIn(expect_text, r.text)except Exception as e:# 日志print(e)# 抛出异常raise# 登录接口 测试def test04_login(self, keywords=13600001111, password="test123", expect_text="登录成功"):try:# 1、登录接口r = self.reg.api_login(keywords=keywords, password=password)# 2、查询结果self.assertIn(expect_text, r.text)except Exception as e:# 日志print(e)# 抛异常raise# 查询登录状态 测试def test05_login_status(self, keywords=13600001111, password="test123", expect_text="OK"):try:# 1、调用登录接口self.reg.api_login(keywords=keywords, password=password)# 2、调用查询登录结果接口r = self.reg.api_login_status()self.assertIn(expect_text, r.text)except Exception as e:# 日志print(e)# 抛出异常raise
-
参数化
-
步骤
1.编写
数据存储文件json
2.编写读取工具方法read_json()
3.使用参数化
组件进行引用
parametrize
- 1 .编写参数化文件(register_login.json)
心得:
1、根据模块来新建json文件
(1个模块1个json文件
)
2、最外侧使用{}
,模块下几个接口,编写几个key
,值为列表
3、列表值中
,有几组数据,就写几个{}
4、每组数据{}中
,组成格式:说明+参数+预期结果
- 几个接口几个key,这里有五个接口(图片验证码、短信验证码、注册、登录、登录状态接口)
- 每组数据组成格式:说明+参数+预期结果
{"img_code": [{"desc": "获取图片验证码成功(随机小数)","random": "0.123","expect_code": 200},{"desc": "获取图片验证码成功(随机整数)","random": "123","expect_code": 200},{"desc": "获取图片验证码成功(随机数为空)","random": "","expect_code": 404},{"desc": "获取图片验证码成功(随机数为字符串)","random": "heloo123","expect_code": 400}],"phone_code": [{"desc": "获取短信验证码成功","phone": "13600001111","imgVerifyCode": "8888","expect_text": "发送成功"},{"desc": "获取短信验证码失败","phone": "13600001111","imgVerifyCode": "8889","expect_text": "验证码错误"}],"register": [{"desc": "注册成功(必填参数)","phone": "13600001111","password": "test123","verifycode": 8888,"phone_code": 666666,"dy_server": "on","expect_text": "注册成功"},{"desc": "注册失败(图片验证码错误)","phone": "13600001112","password": "test123","verifycode": 8889,"phone_code": 666666,"dy_server": "on","expect_text": "验证码错误"},{"desc": "注册失败(短信验证码错误)","phone": "13600001112","password": "test123","verifycode": 8888,"phone_code": 666667,"dy_server": "on","expect_text": "验证码错误"},{"desc": "注册失败(手机号已存在)","phone": "13600001111","password": "test123","verifycode": 8888,"phone_code": 666666,"dy_server": "on","expect_text": "已存在"}],"login": [{"desc": "登录成功","keywords": "13600001111","password": "test123","expect_text": "登录成功"}, {"desc": "登录失败(密码为空)","keywords": "13600001111","password": "","expect_text": "不能为空"}, {"desc": "登录失败(解锁)","keywords": "13600001111","password": "errror123","expect_text": "登录成功"}],"login_status": [{"desc": "查询登录状态(已登录)","status": "已登录","expect_text": "OK"}, {"desc": "查询登录状态(未登录)","status": "未登录","expect_text": "未登"}]
}
- 2、编写读取数据工具(util.py)
from config import DIR_PATHdef read_json(filename, key):# 拼接读取文件的完整路径 os.sep动态获取/ 还是 \ ,根据电脑的操作系统file_path = DIR_PATH + os.sep + "data" + os.sep + filenamearr = []with open(file_path, 'r', encoding="utf-8") as f:# print(json.load(f))# print(json.load(f).get(key)) [{},{},{}]----->[(),(),()]for data in json.load(f).get(key):arr.append(tuple(data.values())[1:])print(arr)if __name__ == '__main__':read_json("register_login.json", "img_code")# [('0.123', 200), ('123', 200), ('', 404), ('heloo123', 400)]
- 参数化引用
- 难点1:错误次数锁定
# 登录接口 测试@parameterized.expand(read_json("register_login.json", "login"))def test04_login(self, keywords, password, expect_text):try:i = 1if "error" in password:while i <= 3:r = self.reg.api_login(keywords=keywords, password=password)i += 1# 断言锁定print("测试锁定:", r.text)self.assertIn("锁定", r.text)# 暂停60ssleep(60)# 测试登录成功r = self.reg.api_login(keywords="13600001111", password="test123")self.assertIn(expect_text, r.text)# 1、登录接口r = self.reg.api_login(keywords=keywords, password=password)# 2、查询结果self.assertIn(expect_text, r.text)except Exception as e:# 日志print(e)# 抛异常raise
- 查询登录状态,不同结果。
# 查询登录状态 测试@parameterized.expand(read_json("register_login.json", "login_status"))def test05_login_status(self, status, expect_text):try:if status == "已登录":# 1、调用登录接口self.reg.api_login(keywords="13600001111", password="test123")# 2、调用查询登录结果接口r = self.reg.api_login_status()self.assertIn(expect_text, r.text)except Exception as e:# 日志print(e)# 抛出异常raise
- 断言代码示例:(test01_register_login.py)
import unittestimport requestsfrom api.api_register_login import ApiRegisterLoginfrom parameterized import parameterizedfrom util import read_jsonfrom time import sleepclass TestRegisterLogin(unittest.TestCase):# 初始化def setUp(self):# 获取session对象self.session = requests.session()# 获取ApiRegisterLogin实例self.reg = ApiRegisterLogin(self.session)# 结束def tearDown(self):# 关闭session对象self.session.close()# 获取图片验证码接口 测试@parameterized.expand(read_json("register_login.json", "img_code"))def test01_img_code(self, random, expect_code):try:# 1、调用图片验证码接口r = self.reg.api_img_code(random)# 2、查看响应状态码self.assertEqual(expect_code, r.status_code)except Exception as e:# 日志print(e)# 抛出异常raise# 获取短信验证码接口 测试@parameterized.expand(read_json("register_login.json", "phone_code"))def test02_phone_code(self, phone, imgVerifyCode, expect_text):try:# 1、调用获取图片验证码接口----目的:让session记住cookieself.reg.api_img_code(123)# 2、调用短信验证码接口r = self.reg.api_phone_code(phone=phone, imgVerifyCode=imgVerifyCode)# 3、查看响应结果self.assertIn(expect_text, r.text)except Exception as e:# 日志print(e)# 抛出异常raise# 注册接口测试@parameterized.expand(read_json("register_login.json", "register"))def test03_register(self, phone, password, imgVerifyCode, phone_code, expect_text):try:# 1、图片验证码接口self.reg.api_img_code(123)# 2、短信验证码接口self.reg.api_phone_code(phone=phone, imgVerifyCode=imgVerifyCode)# 3、注册接口r = self.reg.api_register(phone=phone, password=password, verifycode=imgVerifyCode, phone_code=phone_code)# 4、查看结果self.assertIn(expect_text, r.text)except Exception as e:# 日志print(e)# 抛出异常raise# 登录接口 测试@parameterized.expand(read_json("register_login.json", "login"))def test04_login(self, keywords, password, expect_text):try:i = 1if "error" in password:while i <= 3:r = self.reg.api_login(keywords=keywords, password=password)i += 1# 断言锁定print("测试锁定:", r.text)self.assertIn("锁定", r.text)# 暂停60ssleep(60)# 测试登录成功r = self.reg.api_login(keywords="13600001111", password="test123")self.assertIn(expect_text, r.text)# 1、登录接口r = self.reg.api_login(keywords=keywords, password=password)# 2、查询结果self.assertIn(expect_text, r.text)except Exception as e:# 日志print(e)# 抛异常raise# 查询登录状态 测试@parameterized.expand(read_json("register_login.json", "login_status"))def test05_login_status(self, status, expect_text):try:if status == "已登录":# 1、调用登录接口self.reg.api_login(keywords="13600001111", password="test123")# 2、调用查询登录结果接口r = self.reg.api_login_status()self.assertIn(expect_text, r.text)except Exception as e:# 日志print(e)# 抛出异常raise
-
日志
-
日志的作用?
记录程序
运行的步骤和错误。
- 日志的场景?
1、调试bug
2、查看程序运行轨迹
- 日志的基本应用?
#1、导包
import logging
#2、调用日志入口
logging.error(“出错啦,错误原因:{}”.format(e))
import logging# 设置级别,level=logging.DEBUG制定日志级别,filename存储日志文件,不会打印在控制台
logging.basicConfig(level=logging.DEBUG, filename="../log/p2p.log")# 调用日志
logging.debug("调试信息 ")
logging.info("信息级别")
logging.warning("警告级别")
logging.error("错误级别")
logging.critical("严重级别")
- 测试人员使用的日志的入口
info:记录运行步骤
error:记录运行错误
- 日志底层组成介绍
说明:logging库底层有4大组件(
日志器、处理器、格式器、过滤器
)
1、日志器
:接受日志信息,设置日志显示级别
2、处理器
:控制日志显示位置或文件
(显示在控制台还是文件位置)
3、格式器
:控制日志输出
的显示样式
关系:
- 格式器必须关联处理器
- 处理器必须关联日志器
- 日志封装应用
重组封装的目的:解决日志显示的样式、存储方式
import logging
import logging.handlers
import osclass GetLog:__logger = None # 类变量,确保日志器单例@classmethoddef get_log(cls):if cls.__logger is None: # 只初始化一次cls.__logger = logging.getLogger("MyLogger") # 指定日志器名称cls.__logger.setLevel(logging.INFO) # 设置日志级别# 确保日志目录存在log_dir = os.path.join(os.getcwd(), "log")if not os.path.exists(log_dir):os.makedirs(log_dir)file_path = os.path.join(log_dir, "p2p.log")# 创建处理器(定时滚动日志)tf = logging.handlers.TimedRotatingFileHandler(filename=file_path,when="midnight",interval=1,backupCount=3,encoding="utf-8")# 设置日志格式fmt = "%(asctime)s %(levelname)s [%(filename)s(%(funcName)s:%(lineno)d)] - %(message)s"fm = logging.Formatter(fmt)tf.setFormatter(fm)# 只添加一次处理器cls.__logger.addHandler(tf)return cls.__logger # 返回日志器if __name__ == '__main__':logger = GetLog.get_log()logger.info("信息级别测试")
class GetLog:@classmethoddef get_log(cls):cls.log = Noneif cls.log is None:# 1、获取日志器cls.log = logging.getLogger()# 设置日志级别 INFO 这里要用大写,全局变量cls.log.setLevel(logging.INFO)# 2、获取处理器 TimedRotatingFileHandler:日志保存到文件且根据时间分隔 midnight:一天一夜,interval:2 ,间隔2天一夜,backupCount:3代表第四个文件替换第一个,filepath = DIR_PATH + os.sep + "log" + os.sep + "p2p.log"tf = logging.handlers.TimedRotatingFileHandler(filename=filepath,when="midnight",interval=1,backupCount=3,encoding="utf-8")# 3、获取格式器fmt ="%(asctime)s %(levelname)s [%(filename)s(%(funcName)s:%(lineno)d)]-%(message)s"fm = logging.Formatter(fmt)# 4、将格式器添加到处理器中tf.setFormatter(fm)# 5、将处理器添加到日志器中cls.log.addHandler(tf)# 返回日志器return cls.log
- 应用(init.py)
应用的级别:info、error
info:info记录程序运行的步骤
error:记录程序错误
- api_register_login.py 使用log记录
import requestsfrom api import log
from config import HOST
class ApiRegisterLogin:# 初始化def __init__(self, session):# 获取session对象self.session = session # 实例化session,类下面的其他接口就能使用自己的session# 图片验证码urlself.__url_img_code = HOST + "/common/public/verifycode1/{}" # {}是随机变量,用{}占用# 短信验证码urlself.__url_phone_code = HOST + "/member/public/sendSms"# 注册urlself.__url_register = HOST + "/member/public/reg"# 登录urlself.__url_login = HOST + "/member/public/login"# 登录状态urlself.__url_login_status = HOST + "/member/public/islogin"# 获取图片验证码接口 封装def api_img_code(self, random):log.info("正在调用获取图片验证码接口,请求方法:{},请求url:{}".format('get', self.__url_img_code.format(random)))# 调用get方法,返回响应对象res = self.session.get(url=self.__url_img_code.format(random))return res# 获取短信验证码接口 封装def api_phone_code(self, phone, imgVerifyCode):# 1、定义请求参数data = {"phone": phone,"imgVerifyCode": imgVerifyCode,"type": "reg"}log.info("正在调用获取短信验证码接口,请求方法:{},请求:url,请求参数:{}".format("post", self.__url_phone_code, data=data))# 2、调用请求方法res = self.session.post(url=self.__url_phone_code, data=data)return res# 注册接口 封装def api_register(self, phone, password, verifycode, phone_code):# 1、定义请求参数data = {"phone": phone,"password": password,"verifycode": verifycode,"phone_code": phone_code,"dy_server": "on","invite_phone": ""}log.info("正在调用注册接口,请求方法:{},请求url:{},请求参数:{}".format("post", self.__url_register, data=data))# 2、调用请求方法res = self.session.post(url=self.__url_register, data=data)return res# 登录接口 封装def api_login(self, keywords, password):# 1、定义请求参数data = {"keywords": keywords,"password": password}log.info("正在调用登录接口,请求方法:{},请求url:{},请求参数:{}".format("post", self.__url_login, data=data))# 2、调用请求方法res = self.session.post(url=self.__url_login, data=data)return res# 查询登录状态接口 封装def api_login_status(self):log.info("正在查询登录状态接口,请求方法:{},请求url:{}".format('post', self.__url_login_status))res = self.session.post(self.__url_login_status)
- test01_register_login.py 使用log记录
相关文章:
python实现接口自动化
代码实现自动化相关理论 代码编写脚本和工具实现脚本区别是啥? 代码: 优点:代码灵活方便缺点:学习成本高 工具: 优点:易上手缺点:灵活度低,有局限性。 总结: 功能脚本:工…...
当Anaconda的安装路径与我想创建的conda虚拟环境路径不一致时,应该怎么操作?
我的anaconda安装在该路径:D:\Program\anaconda3 , 如果我想在F盘创建一个虚拟环境 应该怎么做呢? 若你想在 F 盘创建 Anaconda 虚拟环境,可使用 conda create 命令,并通过 --prefix 参数指定环境路径。以下是详细步骤࿱…...
MongoDB慢日志查询及索引创建
MongoDB 的慢日志(Slow Query Log)对于运维和程序员来说都非常重要,因为它直接关系到数据库的性能和应用程序的稳定性。以下分享介绍下MongoDB慢日志查询及索引创建相关的一些笔记。 一,准备 1. 使用 db.currentOp() 实时监控 …...
C语言指针(详细总结)
目录 1.初始C指针 几个重要的概念: 指针的加减 &与* 二级指针 2.指针与数组 指针数组 数组指针变量 一维数组与二维数组传参的本质 编辑编辑 编辑 3.指针与函数 函数指针数组 4.指针与结构体 5.野指针以及常见的内存管理错误 常见的内存错…...
服务器部署Kong和Konga过程
前言 最近在想怎么将一个接口给外部提供服务,并且可以根据和对放的关系,设置不同的期限或者服务大小?并且有友好的可视化页面! 这让我了解到了 API 网关,所以我开始研究 Kong 和 Konga 的使用。 实际上我最开始研究的apisix,但是部署了好久因为etcd不支持 http 无法连接…...
stm32第五天按键的基础知识
一:按键连接示意图 按键控制LED灯 软件设计流程 初始化系统 o 初始化GPIO外设时钟 o 初始化按键和LED的引脚 • 检测按键输入电平来控制LED灯 o SW2控制灯开 。 SW3控制灯关 1:key.c工程 #include"key.h" #include"stm32f10x.h"v…...
高主频CPU+RTX4090:AI生图性能优化超150%
概述:消费级高主频CPU搭配 RTX 4090显卡可以显著提高AI生图的性能,相比于企业级CPU具有更大的吞吐量和更优的成本效益。 引言:在AI图像生成过程中,CPU与GPU的协同效应对系统的整体性能至关重要。测试表明,与RTX 4090显…...
自学Python创建强大AI:从入门到实现DeepSeek级别的AI
人工智能(AI)是当今科技领域最热门的方向之一,而Python是AI开发的首选语言。无论是机器学习、深度学习还是自然语言处理,Python都提供了丰富的库和工具。如果你梦想创建一个像DeepSeek这样强大的AI系统,本文将为你提供…...
主流区块链
文章目录 主流链1. Solana特点:适用场景:工具链: 2. Binance Smart Chain (BSC)特点:适用场景:工具链: 3. Avalanche特点:适用场景:工具链: 4. Polkadot特点:…...
DevEco Studio的使用
目录 1.创建ArkTS工程 2.ArkTS工程目录结构(Stage模型) 构建第一个页面 构建第二个页面 实现页面间的跳转 1.创建ArkTS工程 若首次打开DevEco Studio,请点击Create Project创建工程。如果已经打开了一个工程,请在菜单栏选择…...
Oracle 公布 Java 的五大新功能
Java 增强提案包括语言增强和性能优化,从 JDK 25 中的稳定值 API 开始。 随着JDK(Java 开发工具包)24刚刚全面上市,Oracle 提前透露了不久的将来即将推出的 Java 功能,包括增强原始装箱到空限制值类类型。 3 月 18 日…...
checkpoint机制
1、什么是checkpoint 将缓冲池中的脏页刷新到磁盘,并更新redo log的checkpoint位点,确保数据库在发生故障时可以快速恢复到一致的状态。 2、checkpoint执行过程 确保需要刷新的脏页:从缓冲池中选取一部分需要刷新的页数据页刷新࿱…...
MySQL函数大全(持续更新)
MySQL常用函数 一、字符串函数 函数功能 CONCAT(s1, s2, ...) 拼接字符串 CONCAT_WS(sep, s1, s2, ...) 指定分隔符拼接字符串 SUBSTRING(str, start, length) 截取字符串 LEFT(str, length) 从左边截取指定长度字符串 RIGHT(str, length) 从右边截取指定长度字符串 LENGTH(s…...
商业智能BI分析中,汽车4S销售行业的返厂频次有什么分析价值?
买过车的朋友会发现,同一款车不管在哪个4S店去买,基本上价格都相差不大。即使有些差别,也是带着附加条件的,比如要做些加装需要额外再付一下费用。为什么汽车4S销售行业需要商业智能BI?就是因为在汽车4S销售行业&#…...
51单片机程序变量作用域问题
问题: //为什么下面这个程序可以运行 #include <REGX52.H> #include "LCD1602.h" #include "Delay.h" unsigned int result 0; void main(){LCD_Init();while(1){LCD_ShowNum(1,1,result,3);Delay(200);result;}; } //但是这样会报错&a…...
力扣算法ing(33 / 100)
3.20 146.LRU缓存 请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。 实现 LRUCache 类: LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值&…...
基于springboot的母婴商城系统(018)
摘 要 现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集中处理数据信息的管理方式。本母婴商城系统就是在这样的大环境下诞生,其可以帮助管理者在短时间内处理完毕庞大的数据信息&am…...
【数学建模】模糊综合评价模型详解、模糊集合论简介
模糊综合评价模型详解 文章目录 模糊综合评价模型详解1. 模糊综合评价模型概述2. 模糊综合评价的基本原理2.1 基本概念2.2 评价步骤 3. 模糊综合评价的数学模型3.1 数学表达3.2 模糊合成运算 4. 模糊综合评价的应用领域5. 模糊综合评价的优缺点5.1 优点5.2 缺点 6. 模糊综合评价…...
BSCAN2-1:load design
1. DFT Flow Using Tessent Shell Tessent BoundaryScan 具有一个基本的高层次流程顺序。下图展示了将 Tessent BoundaryScan 插入设计所需的高层次步骤顺序。图中的每个步骤都链接到有关可测试性设计(DFT)流程的更详细信息,包括示例。 Desi…...
Pytorch中layernorm实现详解
平时我们在编写神经网络时,经常会用到layernorm这个函数来加快网络的收敛速度。那layernorm到底在哪个维度上进行归一化的呢? 一、问题描述 首先借用知乎上的一张图,原文写的也非常好,大家有空可以去阅读一下,链接放…...
Redis HyperLogLog
Redis HyperLogLog HyperLogLog 是 Redis 提供的一种基数估算(Cardinality Estimation)数据结构,专门用于统计去重元素的数量(近似值)。 1. HyperLogLog 特点 ✅ 节省内存:无论存储的元素有 10 个 还是 …...
【微服务日志收集①】使用FileBeat+Logstash+ES搭建ELK日志系统
使用FileBeatLogstashES搭建ELK日志系统,架构图如下: 1、 使用docker快速创建ES服务和Kibana服务 前置条件:需要在linux上提前安装好docker和docker-compose 1.1、在linux创建好一个用于存放docker-compose配置文件的文件夹 我的目录是/app/…...
【FAQ】HarmonyOS SDK 闭源开放能力 —Push Kit(10)
1.问题描述: 离线推送,锁屏的时候没有弹出消息,只有下拉在通知中心里面显示。请问是否是正常的? 解决方案: 检查一下是否存在图片风控:https://developer.huawei.com/consumer/cn/doc/harmonyos-referen…...
Django之旅:第二节--启动运行django
1、确保app已配置完(settings.py文件里面配置) INSTALLED_APPS [django.contrib.admin,django.contrib.auth,django.contrib.contenttypes,django.contrib.sessions,django.contrib.messages,django.contrib.staticfiles,app.apps.AppConfig #配置已经注册好的app…...
Redis Sentinel(哨兵模式)高可用性解决方案
一、概述 Redis Sentinel(哨兵模式)是Redis的高可用性(High Availability, HA)解决方案,它通过哨兵系统和Redis实例的协同工作,确保了Redis服务的高可用性和数据的持久性。哨兵系统由一个或多个哨兵进程组…...
Redis缓存与数据库 数据一致性保障
为什么要保证数据一致性 只要使用redis做缓存,就必然存在缓存和DB数据一致性问题。若数据不一致,则业务应用从缓存读取的数据就不是最新数据,可能导致严重错误。比如将商品的库存缓存在Redis,若库存数量不对,则下单时…...
Grid 布局实现三栏布局
使用 CSS Grid 布局实现三栏布局(左右固定 100px,中间自适应)的核心原理是通过网格模板精确控制列宽分配。以下是具体实现方法及优化技巧: 一、基础实现 父容器设置 为外层容器添加 display: grid 使其成为网格容器,并通过 grid-template-columns 定义列宽 css .contain…...
如何在 HTML 中创建一个有序列表和无序列表,它们的语义有何不同?
大白话如何在 HTML 中创建一个有序列表和无序列表,它们的语义有何不同? 1. HTML 中有序列表和无序列表的基本概念 在 HTML 里,列表是一种用来组织信息的方式。有序列表就是带有编号的列表,它可以让内容按照一定的顺序呈现&#…...
springboot第三站(1) web开发引入
目录 1.简介 2.SpringBoot对静态资源的映射规则 3.模版引擎 1.简介 使用SpringBoot; 1)、创建SpringBoot应用,选中我们需要的模块; 2)、SpringBoot已经默认将这些场景配置好了,只需要在配置文件中指定…...
nginx 简单实践:负载均衡【nginx 实践系列之四】
〇、前言 本文为 nginx 简单实践系列文章之三,主要简单实践了负载均衡,仅供参考。 注意:可以使用测试域名,但前提是要修改 hosts 文件 路径和重启:Linux(/etc/hosts)(重启命令&#…...
CentOS 7.9 安装 Python 3.10 详细步骤及常见问题解决
一、环境准备与依赖安装 更新系统与开发工具 sudo yum update -y sudo yum groupinstall "Development Tools" -y sudo yum install -y zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel \ readline-devel tk-devel libffi-devel gdbm-devel db4-de…...
计算机网络-1-1计算机网络体系结构
第一章计算机网络体系结构 绪论 《计算机网络》学什么?——数据如何通过网络正确、可靠地从A传送到B 【考纲内容】 (一)计算机网络概述 计算机网络的概念、组成与功能;计算机网络的分类; 计算机网络的性能指标 (二)计算机网…...
集装箱箱号OCR识别技术,在铁路物流场站集装箱装卸机械数字化系统中的应用
集装箱装卸机械数字化是针对铁路物流场站的门式起重机、集装箱正面吊运起重机、重型叉车、堆高机等作业设备,在不影响原设备作业性能情况下,通过增加或集成集装箱箱号OCR识别或者车号识别装置、北斗定位装置、PLC采集装置等,利用多种通信协议…...
数仓工具—Hive语法之不同纬度聚合
不同纬度聚合 提到不同纬度聚合,大家想到的肯定是grouping sets,或者是cube和rollup 其实这些我们之前都讲过,可以看看之前的文章 数仓工具—Hive语法之cube和rollup 数仓工具—Hive语法之grouping sets 但是我们今天遇到的问题是,使用的工具不支持grouping sets,既然…...
GitHub在push推送到远程仓库的时候显示Logon failed登录失败
具体问题描述 git.exe push --progress "origin" master:master Logon failed, use ctrlc to cancel basic credential prompt. remote: Support for password authentication was removed on August 13, 2021. 这是因为Git 推送失败的原因是 GitHub 已经不支持密码认…...
【Dive Into Stable Diffusion v3.5】1:开源项目正式发布——深入探索SDv3.5模型全参/LoRA/RLHF训练
目录 1 引言2 项目简介3 快速上手3.1 下载代码3.2 环境配置3.3 项目结构3.4 下载模型与数据集3.5 运行指令3.6 核心参数说明3.6.1 通用参数3.6.2 优化器/学习率3.6.3 数据相关 4 结语 1 引言 在人工智能和机器学习领域,生成模型的应用越来越广泛。Stable Diffusion…...
2025-03-19 Unity 网络基础2——网络通信基础
文章目录 1 数据通信模型1.1 C/S 模型1.2 B/S 模型1.3 P2P 模型1.4 小结 2 网络协议2.1 OSI 模型2.1.1 下层2.1.2 上层 2.2 TCP/IP 协议2.2.1 TCP 协议2.2.2 UDP 协议 3 网络游戏通信方案3.1 强/弱弱联网游戏3.2 长/短连接游戏3.3 相关术语 1 数据通信模型 在早期的计算机网…...
路由器安全研究:D-Link DIR-823G v1.02 B05 复现与利用思路
前言 D-Link DIR-823G v1.02 B05存在命令注入漏洞,攻击者可以通过POST的方式往 /HNAP1发送精心构造的请求,执行任意的操作系统命令。 漏洞分析 binwalk提取固件,成功获取到固件。 现在我们已经进入到应用里了,那么我们在进行分析…...
【蓝桥杯python研究生组备赛】005 数学与简单DP
题目1 01背包 有 N 件物品和一个容量是 V 的背包。每件物品只能使用一次。 第 i 件物品的体积是 vi,价值是 wi。 求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。 输出最大价值。 输入格式 第一行两个整数&a…...
数据仓库是什么,跟数据集成有什么关系
在当今数字化时代,数据已成为企业决策的重要依据。数据仓库作为企业数据管理的核心组件,其重要性不言而喻。那么,数据仓库到底是什么?它与数据集成又有着怎样的关系呢?本文将深入探讨这些问题。 一、数据仓库…...
鸿蒙NEXT项目实战-百得知识库01
代码仓地址,大家记得点个star IbestKnowTeach: 百得知识库基于鸿蒙NEXT稳定版实现的一款企业级开发项目案例。 本案例涉及到多个鸿蒙相关技术知识点: 1、布局 2、配置文件 3、组件的封装和使用 4、路由的使用 5、请求响应拦截器的封装 6、位置服务 7、三…...
【微服务】SpringBoot整合LangChain4j 操作AI大模型实战详解
目录 一、前言 二、Langchain4j概述 2.1 Langchain4j 介绍 2.1.1 Langchain4j 是什么 2.1.2 主要特点 2.2 Langchain4j 核心组件介绍 2.3 Langchain4j 核心优势 2.4 Langchain4j 核心应用场景 三、SpringBoot 整合 LangChain4j 组件使用 3.1 前置准备 3.1.1 获取apik…...
rust学习笔记16-206.反转链表(递归)
rust函数递归在14中已经提到,接下来我们把206.反转链表,用递归法实现 递归函数通常包含两个主要部分: 基准条件(Base Case):递归终止的条件,避免无限递归。 递归步骤(Recursive Ste…...
Unity 中实例化预制体的完整过程
1.资源加载(Load Asset to Memory) Unity 的资源加载是指将各种资源(如模型、纹理、音频、预制体 等)从存储介质(如磁盘、AssetBundle、远程服务器)到运行时内存的过程,使其成为可用的资源&…...
Unity动画片段丢失(AnimationClip),如何进行重新绑定
从外部导入的AnimationClip存在黄色丢失的missing提示,这时候不需要重新制作动画,只需要重新绑定动画即可。 我们以第一条Intro1:Anchored Position(缺失!)为例 第一步:双击动画中的Intro1条目,可以查看片段存储该动画的对应路径…...
mysql5.7主从部署(docker-compose版本)
mysql5.7主从部署(docker-compose版本) 1:docker-compose-test.yml 文件信息 version: 3services:# MySQL 数据库mysql-master:image: mysql:5.7container_name: mysql-masterenvironment:MYSQL_ROOT_PASSWORD: 123456MYSQL_DATABASE: nacosports:- 23…...
模型部署实战:PyTorch生产化指南
一、为什么要做模型部署? 模型部署是将训练好的模型投入实际应用的关键步骤,涉及: 模型格式转换(TorchScript/ONNX)性能优化(量化/剪枝)构建API服务移动端集成 本章使用ResNet18实现图…...
SQLMesh 系列教程:Airbnb数据分析项目实战
在本文中,我们将探讨如何利用dbt项目的代码库来实现一个简单的SQLMesh项目。本文的基础是基于Udemy讲师为dbt课程创建的示例项目,可以在这个GitHub repo中获得。这个dbt项目是相对完整的示例,我们将使用它作为模板来演示SQLMesh(下…...
LeetCode hot 100 每日一题(11)——189. 轮转数组
这是一道难度为中等的题目,让我们来看看题目描述: 给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。 示例 1: 输入: nums [1,2,3,4,5,6,7], k 3 输出: [5,6,7,1,2,3,4] 解释: 向右轮转 1 步: [7,1,2,3…...
VLAN综合实验
一、实验拓扑 二、实验要求 1、PC1/3处于同一个网段,所在接口为access,属于VLAN 2。 2、PC2/4/5/6处于同一网段。 3、PC2可以访问PC4/5/6。 4、PC4可以访问PC5,但不能访问PC6。 5、PC5不能访问PC6。 6、所有PC通过DHCP获取IP地址&#…...