当前位置: 首页 > news >正文

接口(interface) 测试

前提

概念

接口:系统之间数据交互的通道。(本质是函数(方法))
接口测试,会绕过前端,直接对服务器进行测试

实现方式

软件:
postman:使用简单,上手难度低。功能较少。
jmeter:使用难度较大。上手难度大。功能齐全。
代码:
Python + requests + Unittest
java + HttpClient

http协议

HTTP:超文本传输协议,基于请求与响应的应用层协议
默认端口:80
https默认端口:443

特点:客户端/服务器模式、简单快速、灵活、无连接、无状态

URL:协议://ip地址:端口号/资源路径

请求:
请求行:请求方法 url 协议版本
请求头:键值对
。Content-Type:作用,指定 请求体的数据类型
请求体:数据类型受Content-Type影响

1xx 指示错误
200 成功
30x 重定向错误
403 访问被禁止( 权限不足)
404 请求资源不存在
500 服务器错误

接口风格

传统风格
在这里插入图片描述
restful风格
在这里插入图片描述

测试流程

需求分析 – 接口文档的解析 – 设计测试用例 – 脚本开发 – 缺陷跟踪 – 生成测试报告 – 接口自动化持续集成
在这里插入图片描述

接口文档解析:
接口文档:又称为API文档,是由后端开发编写,用来描述接口信息的文档。

测试维度

功能测试
。 单接口测试
。 业务场景功能测试
性能测试
。 响应时长:从发送请求到接收到服务器回发响应包所经历的时间。
。 错误率:服务器运行出错的概率
。 吞吐量:服务器单位时间内,处理请求的数量。
。 服务器资源利用率:cpu、内存、网络、磁盘等 硬件资源的占用率。
安全测试
。 攻击安全:木马,病毒…
。 业务安全:敏感数据加密存储、SQL注入…

测试用例

设计方法

在这里插入图片描述
单接口测试:
。 正向测试
。 反向测试

业务场景测试:
。 尽量模拟用户实际使用场景
。尽量用最少的用例,覆盖最多的接口请求
。 一般情况下,覆盖正向测试即可

编写

用例编号用例名称模块优先级前置条件接口名称请求方法URL请求头请求数据预期结果实际结果

分析测试点

与功能测试时分析差不多。

Postman的使用

基本使用

1、请求方法
2、URL
3、请求头
4、请求体
5、断言
在这里插入图片描述

断言

在这里插入图片描述
pm:postman的实例
test():postman的测试方法

  • 断言响应状态码
// 断言响应状态码200
pm.test("Status code is 200", function () {pm.response.to.have.status(200);
});

参数一:“Status code is 200” ==》 给用户看的提示信息
参数二:“function () { pm.response.to.have.status(200);}” ==》预期结果是200。

  • 断言包含的某个字符串
pm.test("Body matches string", function () {pm.expect(pm.response.text()).to.include("string_you_want_to_search");
});

参数一:“Body matches string” ==》 给用户看的提示信息
参数二:“function () {pm.expect(pm.response.text()).to.include(“预期字符串”);}” ==》预期结果是应该包含“预期字符串”·

  • 断言JSON数据
pm.test("Your test name", function () {var jsonData = pm.response.json();pm.expect(jsonData.value).to.eql(100);
});

参数一:“Your test name” ==》 给用户看的提示信息
参数二:“function () {var jsonData = pm.response.json();
pm.expect(jsonData.value).to.eql(100);}” ==》预期结果json中某个“value”的key值为“100”

原理:
在这里插入图片描述

关联

// 1、获取响应数据、转为json格式,保存到变量jsonDta 中。
var jsonDta = pm.response.json()
// 2.1、设置环境变量。
pm.environment.set( "环境变量名",环境变量值)
// 2.2、使用全局变量做容器。
pm.globals.set ( "全局变量名",全局变量值)
// 3.在postman界面中提取全局、环境变量数据。
{{全局变量名}}/{{环境变量名}}
var value = pm.environment.get("var_name");	# 代码中引用

创建环境:
全局变量:在整个postman中都可以使用的变量。不需要单独创建环境。

环境变量:在特定的环境下,才能使用的变量。需要给此变量创建单独的环境。
在这里插入图片描述

例子一(方法步骤):

  • 1、发送获取天气的请求,获取响应结果,存入全局变量
    在这里插入图片描述

  • 2、百度搜索接口从全局变量中,取城市名,完成搜索
    在这里插入图片描述

例子二(令牌的存储):
在这里插入图片描述

在这里插入图片描述

参数化

  • CSV 文件
    注意:
    1、不能测试 bool类型。因为postman读取csv后,将所有非数值类型数据,自动添加“”变为字符串
    2、不能存储复杂数据类型(元组,列表,字典)
    3、不能实现参数测试

  • JSON文件
    文件大
    例如:
    1、创建导入
    在这里插入图片描述

2、引用数据文件
(1、){{keyi}} 引用相关对象的key
(2、)使用postman内置的关键字data
例如: csv文件:data.字段名;
json文件:data.键名;
在这里插入图片描述
只能按第一图进行操作,然后点击run.

测试报告

前提:
1、安装node.js
2、安装newman【npm install -g newman】【newman -v 测试安装成功】
3、安装newman插件【npm install -g newman-reporter-htmlextra】

1、导出用例:
在这里插入图片描述
2、导出环境:
在这里插入图片描述

3、命令生成:
在这里插入图片描述
在这里插入图片描述
newman run 用例集文件.json -e 环境文件 -r htmlextra --reporter-htmlextra-export aa.html

Postman练习

1、项目结构
在这里插入图片描述
2、创建环境
3、编写测试用例
4、执行测试用例(批量执行)

接口自动化

Requests库

Requests库是Python编写的,基于urllib 的HTTP库,使用方便。
安装: pip install requests

请求语法:

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

Cookie

简介: 工程师 针对 http协议是无连接、无状态特性,设计的 一种技术。可以在浏览器端 存储用户的信息。
。 cookie 用于存储 用户临时的不敏感信息。
。 cookie 位于浏览器端。默认大小 4k(可以调整)
。 cookie 中的数据,可以随意被访问,没有安全性可言。
。 cookie 中存储的数据类型,受浏览器限制。

身份认证方式:
。 token
。 cookie +session

cookie +session认证
【就是把获取验证码的请求得到cookie,然后登录时带过去】
在这里插入图片描述

Session

简介: 也叫会话。通常出现在网络通信中,从客户端借助访问终端登录上服务器,直到退出登录所产生的通信数据,保存在会话中。
。 Session用于存储 用户的信息。
。 Session位于服务端。大小自接使用服务器大小。
。 Session 中的数据,不能随意被访问,安全性高。
。 Session中存储的数据类型,受服务器限制。
。 Session自动管理Cookie

session认证
在这里插入图片描述
获取指定响应数据:
在这里插入图片描述

Cookie和Seesion的区别

CookieSeesion
存储位置浏览器服务器
安全性可随意获取加密存储
数据类型受浏览器限制较少直接使用服务器,支持使用所有数据类型
大小默认4K约为服务器大小

参数化

1、读取Jason文件

def read_json_data():list_data = []# 从 .json 文件中,读取 [{},{},{}] 数据with open("./params_data.json", "r", encoding="utf-8") as f:data = json.load(f)for item in data:tmp = tuple(item.values())  # 将字典里的values转成元组list_data.append(tmp)		# 转成[(),(),(),()]格式return list_data

2、参数化
步骤:

  • 导包:from parameterized import parameterized
  • 在通用测试方法上添加一行
  • 并传参元组列表数据(调用自己封装的读取json文件的函数):@parameterized.expand(read_json_data())
  • 修改通用测试方法形参,与json文件中的key保持一致
  • 在通用测试方法内,使用形参
@parameterized.expand(read_json_data())
def test_add(self, cu1, cu2, cu3):res = add(cu1, cu2)self.assertEqual(cu3, res)

接口自动化框架

类似于分层架构,分包管理

在这里插入图片描述

目录结构:

在这里插入图片描述
首先在接口对象成,编写用例代码,然后在接口用例成执行代码,其中断言需要调用工具包的方法,数据需要调用数据文件

接口对象层

文件夹名:api
文件名:hr_login_api

import requests
class HrLoginApi(object):# 登录@classmethoddef login(cls, json_data):url = "http://xxxxxxxx/xxxx/login"header = {"Content-Type": "application/json"}resp = requests.post(url=url, headers=header, json=json_data)return resp

接口用例层

文件夹名:scripts
文件名:test_hr_login

import unittest
from parameterized import parameterized
from api.hr_login_api import HrLoginApi
from common.assert_util import assert_util
from common.read_json_util import read_json_dataclass TestHrLogin(unittest.TestCase):@parameterized.expand(read_json_data())def test_login_sucess(self, desc, req_data, status_code, success, code, message):# 调用自己的接口resp = HrLoginApi.login(req_data)# 断言assert_util(self, resp, status_code, success, code, message)

工具类

文件夹名:common
文件名:assert_util

# 定义通用断言方法
def assert_util(self, resp, status_code, success, code, message):self.assertEqual(status_code, resp.status_code)self.assertEqual(success, resp.json().get("success"))self.assertEqual(code, resp.json().get("code"))self.assertIn(message, resp.json().get("message"))

文件夹名:common
文件名:read_json_util.py

# 定义函数读取Json文件
import jsondef read_json_data():list_data = []with open("../data/params_data.json", "r", encoding="utf-8") as f:json_data = json.load(f)for item in json_data:tem = tuple(item.values())list_data.append(tem)return list_data

数据文件

文件夹名:data
文件名:params_data.json

[{"desc": "登录成功","req_data":{"mobile": "13800000002", "password": "123456"},"status_code": 200,"success": true,"code": 1000,"message": "操作成功"},{"desc": "手机号为空","req_data":{"mobile": null, "password": "123456"},"status_code": 200,"success": false,"code": 2001,"message": "用户名或密码错误"}
]

测试报告文件

日志收集

log:记录当前系统运行是的信息。
作用:查看系统是否正常,定位bug

日志级别:日志级别与严重性相反 ,只会记录比自己低级别和相同级别的日志
在这里插入图片描述
代码如下:

"""
步骤:
# 0. 导包
# 1. 创建日志器对象
# 2. 设置日志打印级别# logging.DEBUG 调试级别# logging.INFO 信息级别# logging.WARNING 警告级别# logging.ERROR 错误级别# logging.CRITICAL 严重错误级别
# 3. 创建处理器对象# 创建 输出到控制台 处理器对象# 创建 输出到日志文件 处理器对象
# 4. 创建日志信息格式
# 5. 将日志信息格式设置给处理器# 设置给 控制台处理器# 设置给 日志文件处理器
# 6. 给日志器添加处理器# 给日志对象 添加 控制台处理器# 给日志对象 添加 日志文件处理器
# 7. 打印日志
"""
import logging.handlers
import logging
import time# 1. 创建日志器对象
logger = logging.getLogger()# 2. 设置日志打印级别
logger.setLevel(logging.DEBUG)
# logging.DEBUG 调试级别
# logging.INFO 信息级别
# logging.WARNING 警告级别
# logging.ERROR 错误级别
# logging.CRITICAL 严重错误级别# 3.1 创建 输出到控制台 处理器对象
st = logging.StreamHandler()
# 3.2 创建 输出到日志文件 处理器对象
fh = logging.handlers.TimedRotatingFileHandler('a.log', when='midnight', interval=1,backupCount=3, encoding='utf-8')
# when 字符串,指定日志切分间隔时间的单位。midnight:凌晨:12点。
# interval 是间隔时间单位的个数,指等待多少个 when 后继续进行日志记录
# backupCount 是保留日志文件的个数# 4. 创建日志信息格式
fmt = "%(asctime)s %(levelname)s [%(filename)s(%(funcName)s:%(lineno)d)] - %(message)s"
formatter = logging.Formatter(fmt)# 5.1 日志信息格式 设置给 控制台处理器
st.setFormatter(formatter)
# 5.2 日志信息格式 设置给 日志文件处理器
fh.setFormatter(formatter)# 6.1 给日志器对象 添加 控制台处理器
logger.addHandler(st)
# 6.2 给日志器对象 添加 日志文件处理器
logger.addHandler(fh)# 7. 打印日志
while True:# logging.debug('我是一个调试级别的日志')logging.info('我是一个信息级别的日志')# logging.warning('我是一个警告级别的日志')# logging.error('我是一个错误级别的日志')# logging.critical('我是一个严重错误级别的日志')time.sleep(1)

封装成工具类:

import logging.handlers
import logging
import timedef init_log_config(filename, when='midnight', interval=1, backup_count=7):"""功能:初始化日志配置函数:param filename: 日志文件名:param when: 设定日志切分的间隔时间单位 ’mindnight’:param interval: 间隔时间单位的个数,指等待多少个 when 后继续进行日志记录:param backup_count: 保留日志文件的个数:return:"""# 1. 创建日志器对象logger = logging.getLogger()# 2. 设置日志打印级别logger.setLevel(logging.DEBUG)# logging.DEBUG 调试级别# logging.INFO 信息级别# logging.WARNING 警告级别# logging.ERROR 错误级别# logging.CRITICAL 严重错误级别# 3. 创建处理器对象# 控制台对象st = logging.StreamHandler()# 日志文件对象fh = logging.handlers.TimedRotatingFileHandler(filename,when=when,interval=interval,backupCount=backup_count,encoding='utf-8')# 4. 日志信息格式fmt = "%(asctime)s %(levelname)s [%(filename)s(%(funcName)s:%(lineno)d)] - %(message)s"formatter = logging.Formatter(fmt)# 5. 给处理器设置日志信息格式st.setFormatter(formatter)fh.setFormatter(formatter)# 6. 给日志器添加处理器logger.addHandler(st)logger.addHandler(fh)if __name__ == '__main__':# 初始化日志init_log_config('a.log')# 打印输出日志信息logging.debug('我是一个调试级别的日志')

全量字段校验

1、定义校验规则
2、比对

unittest框架

主要用于管理测试用例。

注意遵守标识符命名规范:

  • 只能使用 字母、数字、下划线。数字不能开头。避免使用 关键字、已知函数名
  • 类:(首字母必须大写。建议以 Test 开头)
  • 方法:(必须 test 开头,建议 编号)

基本用法测试

  • 1、创建测试用例
import requests
# 导包
import unittestclass Test01(unittest.TestCase):    # 使用TestCase,创建测试用例# def 定义的test_ 是测试用例,只有执行 if __name__ == '___mian___'# 的时候会执行测试用例,其他普通函数则不执行,通过 self 来调用执行。def test_01(self):  # 测试方法必须以test_开头url = 'https://apiuat.jaspervault.io/api/options-dates/'params = {'network_id': 1, 'collateral_token_id': 1, 'collateral_token_id': 2, 'collateral_token_id': 'hedge'}req = requests.get(url, params)print(req.json())
  • 2、执行测试用例
import unittest
from htmltestreport import HTMLTestReport
from test.test_aa03 import Test01# TestSuite,测试套件
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(Test01))  # 将测试类的所有方法进行添加runner = unittest.TextTestRunner()  # 实例化运行对象runner = HTMLTestReport("测试报告1.html")   # 自动化生成测试报告runner.run(suite)   # 运行对象
  • 批量增加测试方法到测试套件中
    写法:
  1. suite = unittest.TestLoader().discover(“指定搜索的目录文件”,“指定字母开头模块文件”)
  2. suite = unittest.defaultTestLoader.discover(“指定搜索的目录文件”,“指定字母开头模块文件”) 【推荐】
    注意:
    如果使用写法1,TestLoader()必须有括号。

Fixture(测试夹具)

是一种代码结构,在某些特定情况下,会自动执行。
方法级别:每个方法执行前后都要执行
def setUp(),每个测试方法执行之前都会执行 (初始化)
def tearDown(),每个测试方法执行之后都会执行 (释放)

类级别:在每个测试类中所有方法执行前后 都会自动调用的结构(在整个类中 执行之前执行之后各一次)
类方法必须使用 @classmethod修饰
def setUpClass() ,类中所有方法之前
def tearDownClass(),类中所有方法之后

断言

  • 断言的结果:
    1、True,用例通过
    2、False,代码抛出异常,用例不通过
    3、在unittest中使用断言,需要通过 self.断言方法

  • 常用的断言:

self.assertEqual(ex1, ex2) 			# 判断ex1 是否和ex2 相等
self.assertIn(ex1, ex2) 			#  ex2是否包含 ex1   注意:所谓的包含不能跳字符
self.assertTrue(ex)					#  判断ex是否为True重点讲前两个assertEqual 和 assertIn
方法:
assertEqual:self.assertEqual(预期结果,实际结果)          判断的是预期是否相等实际
assertIn:self.assertIn(预期结果,实际结果) 				判断的是预期是否包含实际中
assertIn('admin', 'admin') 								# 包含
assertIn('admin', 'adminnnnnnnn') 						# 包含
assertIn('admin', 'aaaaaadmin') 						# 包含
assertIn('admin', 'aaaaaadminnnnnnn') 					# 包含
assertIn('admin', 'addddddmin') 						# 不是包含

标准语法

import unittestclass demo(unittest.TestCase):@classmethoddef setUpClass(cls) -> None:    # 执行该类前进行print("setUpClass")@classmethoddef tearDownClass(cls) -> None:print("tearDownClass")      # 执行该类后进行def setUp(self) -> None:    # 执行每个用例前进行print("setup")def tearDown(self) -> None:     # 执行每个用例后进行print("down")def test_case01(self):print("test_case01")self.assertEqual(1, 1, "判断相等")@unittest.skip  # 跳过该用例def test_case02(self):print("test_case02")self.assertEqual(2, 1, "判断相等")

PyMySQL操作数据库

使用场景:校验测试数据(字段会改,返回数据没有),构造测试数据(数据只能用一次,无法保证数据已存在)

安装

pip install pymysql

操作步骤

在这里插入图片描述
1.导包import pymysql
2.创建连接。conn=pymysql.connect()
3.获取游标。cursor=conn.cursor()
4.执行 SQL。cursor.execute("sql语句”)
5.关闭游标,关闭连接

1.导包

import pymysql

2、创建连接

conn = pymysql.connect(host=" ",port=0,user=" ",password=" ",database=" ",charset=" ")
host:数据库所在IP地址
port:端口
user:用户名
password:密码
database:连接那个数据库的名字
charset:字符集。utf8

conn :数据库对象

3、获取游标

cursor=conn.cursor()

4、执行SQL语句

。 查询语句
提取数据:cursor.fetch*()

。 增删改语句
成功:提交事务 conn.commit()
失败:回滚事务 conn.rollback()
【查询】
cursor.fetch*() #默认在0号位,提取数据在所在位置的下一行,每提一条自动向下移动。
。。 fetchone():从结果集中,提取一行。
。。 fetchmany(size):从结果集中,提取 size 行。
。。 fetchall():提取所有结果集。
。。 属性rownumber:可以设置游标位置。 cursor.rownumber=0
【添加】【修改】
。。 成功:提交事务 conn.commit()
。。 失败:回滚事务 conn.rollback()

5、关闭

关闭游标:cursor.close()
关闭连接:conn.close()

封装

pymysql封装

import pymysqlclass DBUtil(object):conn = Nonecursor = None@classmethoddef __get_conn(cls):if cls.conn is None:cls.conn = pymysql.connect(host="127.0.0.1", port=3306, user="root",password="root", database="test01", charset="utf8")return cls.conn@classmethoddef __close_conn(cls):if cls.conn is not None:cls.conn.close()cls.conn = Nonepass@classmethoddef select_one(cls, sql):try:# 获取连接cls.conn = cls.__get_conn()# 执行sql语句cursor = cls.conn.cursor()cursor.execute(sql)res = cursor.fetchone()except Exception as err:print("查询sql错误", str(err))finally:# 关闭连接cls.__close_conn()return res@classmethoddef uid_db(cls, sql):cursor = Nonetry:# 连接cls.conn = cls.__get_conn()cursor = cls.conn.cursor()# sqlcursor.execute(sql)print("影响行数:", cls.conn.affected_rows())# 提交cls.conn.commit()except Exception as err:print("err", err)# 回滚cls.conn.rollback()finally:# 关闭cursor.close()cls.__close_conn()

测试

简单来说就是将重复的代码进行封装

  • 接口对象层
    封装接口的
  • 测试脚本层
    封装断言的

相关文章:

接口(interface) 测试

前提 概念 接口:系统之间数据交互的通道。(本质是函数(方法)) 接口测试,会绕过前端,直接对服务器进行测试 实现方式 软件: postman:使用简单,上手难度低。功能较少。…...

人力外包解决方案:重构企业用人成本的最优配置

作为专业人力外包服务商,我们深谙企业用人成本的核心痛点与优化密码。以下从外包视角解析成本构成,展现如何通过「战略外包」实现成本重构与价值倍增。 在当今竞争激烈的商业环境中,企业面临着越来越多的挑战,尤其是在人力资源管…...

WPF 组件的宽高绑定另一个组件的宽高的指定比值

0.此方法比较适用于响应式界面,组件的大小需要根据窗体大小改变。 1.创建转换函数,并传入比值 public class SizeConverter : IValueConverter{public object Convert(object value, Type targetType, object parameter, CultureInfo culture){if (value is double d &&…...

【DvAdmin】接口返回 emoji 显示 ?解决方法

再django构建API接口的时候emoji图标显示? 这里需要检查一下 如果你在后端返回的 JSON 数据中,某些 emoji 显示为 ?,而这些 emoji 在其他地方(比如你的本地应用或网页)显示正常,那么问题通常与后端的字符编码、数据库存储、或者 API 响应处理有关。我们可以按以下几个方…...

【挑战项目】 --- 微服务编程测评系统(在线OJ系统)(一)

一、前言 1.为什么要做项目 面试官要问项目,考察你到底是理论派还是实战派? 1.希望从你的项目中看到你的真实能力和对知识的灵活运用。 2.展示你在面对问题和需求时的思考方式及解决问题的能力。 3.面试官会就你项目提出一些问题,或扩展需求。以此来评估你如何有效应对和设…...

深度学习在文本情感分析中的应用

引言 情感分析是自然语言处理(NLP)中的一个重要任务,旨在识别和提取文本中的主观信息。随着深度学习技术的发展,我们可以使用深度学习模型来提高情感分析的准确性和效率。本文将介绍如何使用深度学习进行文本情感分析&#xff0c…...

建筑工程管理系统功能模块概览

在现代建筑工程管理中,信息化系统的应用已成为提升管理效率、优化资源配置的重要手段。本文将详细介绍一款建筑工程管理系统的核心功能模块,该系统覆盖了从系统管理、项目设置到具体业务操作的全方位功能,旨在为建筑工程项目提供一站式管理解…...

MyBatis-Plus3.X分页配置PaginationInnerInterceptor出错原因

MyBatis-Plus3.X分页配置PaginationInnerInterceptor出错原因 PaginationInnerInterceptor报红, 无法导入 import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;import com.baomidou.mybatisplus.extension.plugins.MybatisPlu…...

vue、vue2、vue3

Vue、Vue 2 和 Vue 3 分别代表了 Vue.js 不同阶段的版本,它们在设计理念、语法和功能上存在一些区别,下面为你详细介绍: 1. 发布时间和生命周期 Vue:通常指的是 Vue 1.x 版本,于 2014 年 2 月发布。它是 Vue.js 的初…...

网络安全之-信息收集

域名收集 域名注册信息 站长之家 https://whois.chinaz.com/ whois 查询的相关网站有:中国万网域名WHOIS信息查询地址: https://whois.aliyun.com/西部数码域名WHOIS信息查询地址: https://whois.west.cn/新网域名WHOIS信息查询地址: http://whois.xinnet.com/domain/whois/in…...

神经网络入门—

修改网络 神经网络入门—自定义网络-CSDN博客 修改数据集,yx^2 # 生成一些示例数据 x_train torch.tensor([[1.0], [2.0], [3.0], [4.0]], dtypetorch.float32) y_train torch.tensor([[1.0], [4.0], [9.0], [16.0]], dtypetorch.float32) 将预测代码改为&…...

Python Cookbook-5.10 选取序列中最小的第 n个元素

任务 需要根据排名顺序从序列中获得第n个元素(比如,中间的元素,也被称为中值)。如果序列是已经排序的状态,应该使用seq[n],但如果序列还未被排序,那么除了先对整个序列进行排序之外,还有没有更好的方法? …...

GitHub 克隆/下载失败的解决方案

🚀 GitHub 下载/克隆失败?一招搞定代理配置与回滚! 在国内使用 Git 操作 GitHub 时,经常会遇到以下问题: ❌ 下载失败、超时 ❌ Failed to connect to github.com port 443 ❌ SSL certificate problem 本文将详细讲解…...

【Linux】进程控制:创建、终止、等待与替换全解析

文章目录 前言一、重谈进程创建二、进程终止2.1 正常终止的退出码机制2.2 异常终止的信号机制2.3 进程常见的退出方法 三、进程等待:避免僵尸进程的关键3.1 进程等待的必要性3.2 进程等待的两个系统调用接口3.2.1 wait()3.2.2 waitpid()区别 四、进程程序替换4.1 进…...

LabVIEW 图像处理中常见的边缘检测算法

在 LabVIEW 图像处理领域,边缘检测对于提取图像特征、目标识别及图像分割等任务至关重要。以下介绍几种常见的边缘检测算法及其在 LabVIEW 中的应用。​ 一、Sobel 算子​ Sobel 算子是一种离散的一阶差分算子,用于计算图像灰度的近似梯度。它通过分别…...

Redis-场景缓存+秒杀+管道+消息队列

缓存一致性 1.两次更新 先更新数据库,再更新缓存;先更新缓存,再更新数据库; 出现不一致问题场景: 先更新数据库,再更新缓存; 先更新缓存,再更新数据库; 两次更新的适…...

亲身体验 Copilot Pages:利用人工智能实时整理和优化笔记

想象一下,有一款与云端相连的笔记本,它不仅能保存您收集的信息,还能自动整理,并根据需要添加详细信息和研究资料。这就是微软在华盛顿州雷德蒙德举行的 50 周年庆典活动上推出的全新 Copilot Pages 功能。这是微软在该活动中介绍的…...

[250409] GitHub Copilot 全面升级,推出AI代理模式,可支援MCP | Devin 2.0 发布

目录 GitHub Copilot 全面升级,推出AI代理模式,可支援MCPDevin 2.0 正式发布:带来全新的 AI 协作开发体验 GitHub Copilot 全面升级,推出AI代理模式,可支援MCP GitHub Copilot 迎来了一次重大升级,核心在于…...

代码随想录算法训练营Day25

一、力扣93.复原IP地址【medium】 题目链接:力扣93.复原IP地址 left x300 视频链接:代码随想录 1、思路 时间复杂度: O ( n ) O(n) O(n) 2、代码 class Solution:def restoreIpAddresses(self, s: str) -> List[str]:n len(s)ans []…...

支持企业知识库和联网搜索,360AI企业知识库驱动业务深度融合

在企业智能化转型进程中,高效整合内外部结构化与非结构化数据资源、快速构建AI能力已成为制胜未来的核心命题。360 DeepSeek企业知识库助力企业实现知识管理、辅助决策与业务场景落地的全链路贯通,重塑智能化升级路径。 1 企业知识库构建 终结信息孤岛…...

2025年R2 移动式压力容器充装证精选多选题练习

R2 移动式压力容器充装证精选多选题练习: 1、《特种设备安全法》规定,特种设备使用单位应当建立特种设备安全技术档案。安全技术档案应当包括以下内容:( ) A. 特种设备的定期检验和定期自行检查记录 B. 特种设备的日…...

掌握Django内联TabularInline和StackedInline示例

掌握Django内联TabularInline和StackedInline示例 推荐超级课程: 本地离线DeepSeek AI方案部署实战教程【完全版】Docker快速入门到精通Kubernetes入门到大师通关课AWS云服务快速入门实战目录 掌握Django内联TabularInline和StackedInline示例**前提条件****Django 内联管理简…...

ABAP+CS

平时开发中如果遇到某个字段等于A或B或C很多时的枚举条件很多时,平时我们都是写 if BUKRS A OR BUKRS B OR BUKRS C. ENDIF. 可以替换为CS,更加简洁,如下,要记得加空格 IF A B C D CS BUKRS. ENDIF....

python reportlab模块----操作PDF文件

reportlab模块----操作PDF文件 一. 安装模块二. reportlab相关介绍三. 扩展canvas类四. 水平写入完整代码五. 垂直写入完整代码 一. 安装模块 pip install reportlab二. reportlab相关介绍 # 1. letter 生成A4纸张尺寸 from reportlab.lib.pagesizes import letter print(let…...

javascript里用代理做链式调用。

JavaScript 的 Proxy 对象来实现一种动态的链式调用,最终完成加法操作。我们来逐步分析代码的逻辑: 1. createProxy 函数 function createProxy(value 0) {const valueGetter () > value;return new Proxy({}, {get(target, prop) {if (prop Sym…...

SpringBoot将HTML转化成PDF文件

准备好相关字体文件(如果HTML内含有中文,避免乱码)。我这边用的是谷歌免费的中文字体,源于:Gitee 极速下载/noto-cjk - Gitee.com(在此表示感谢)准备好一个HTML文件(HTML标签记得封好…...

Elasticsearch 集群搭建

一、集群规划 1.1 节点角色规划 节点类型配置要求推荐数量Master节点低磁盘、中等CPU/内存3(奇数防止脑裂)Data节点高磁盘、高内存、多核CPU根据数据量扩展Coordinating节点高CPU/内存、低磁盘2(可选) 1.2 硬件建议 内存&…...

BGP路由协议之对等体

IGP 可以通过组播报文发现直连链路上的邻居,而 BGP 是通过 TCP:179 来实现的。BGP 需要手工的方式去配置邻居。不需要直连,只要路由能通就可以建立邻居 IBGP 与 EBGP IBGP :(Internal BGP) :位于相同自治系统的 BGP 路由器之间的 BGP 邻接关…...

H3C的MSTP+VRRP高可靠性组网技术(MSTP单域)

以下内容纯为博主分享自己的想法和理解,如有错误轻喷 MSTP多生成树协议可以基于不同实例实现不同VLAN之间的负载分担 VRRP虚拟路由器冗余协议可以提高网关的可靠性防止单点故障的可能 在以前这两种协议通常一起搭配组网,来提高网络的可靠性和稳定性&a…...

oracle 动态性能视图

Oracle 数据库中的 V$SQLAREA 是一个动态性能视图(Dynamic Performance View),用于记录共享池(Shared Pool)中所有 SQL 语句的统计信息。每个 SQL 语句在共享池中存储为一个游标(Cursor)&#x…...

chrome extension开发框架WXT之WXT Storage api解析【补充说明一】

在 defineItem 方法里,fallback、init、version 和 migrations 这些参数能够让你对存储项进行更为细致的设置,像设定默认值、初始化值、版本控制以及数据迁移等操作。下面详细说明这些参数的使用方法: fallback 参数 fallback 参数为 getVa…...

浦江晨曦曲:科技与自然共舞的未来诗篇

故事背景 故事发生在未来上海,这座国际大都市通过尖端科技与生态自然的完美融合,重新定义了人类与环境的共生关系。从黄浦江畔的智慧能源矩阵到云端漂浮的烘焙工坊,每个场景都诉说着科技赋能下的人文温度。 故事摘要 当晨曦染红黄浦江面&…...

Lua 函数使用的完整指南

在 Lua 中,函数是一等公民(First-Class Citizen),这意味着函数可以像其他值一样被赋值、传递和操作。以下是 Lua 函数定义的完整指南,涵盖基础语法、高级特性、设计模式及性能优化。 在Lua 中,函数定义的完…...

算法进阶指南 袭击

题目描述 在与联盟的战斗中屡战屡败后,帝国撤退到了最后一个据点。依靠其强大的防御系统,帝国击退了联盟的六波猛烈进攻。 经过几天的苦思冥想,联盟将军亚瑟终于注意到帝国防御系统唯一的弱点就是能源供应。 该系统由 N 个核电站提供能源&…...

HTTPS为何仍有安全漏洞?解析加密协议下的攻击面

本文深度剖析HTTPS协议在传输层、证书体系、配置管理三个维度的安全盲区,揭示SSL/TLS加密掩盖下的11类攻击路径。基于Equifax、SolarWinds等重大事件的技术复盘,提供包含自动化证书巡检、动态协议升级、加密流量威胁检测的立体防御方案。 HTTPS不等于绝…...

行业案例 | SAS 基于 SQL 托管实例构建高弹性安全的数据平台

SAS是全球领先的数据与AI公司,专注于行业解决方案,帮助企业高效利用数据驱动决策。在本案例中,SAS通过采用Azure SQL托管实例,成功迁移和管理近1,000个数据库,减少运维负担,提升数据价值挖掘能力。这一方案…...

NO.82十六届蓝桥杯备战|动态规划-从记忆化搜索到动态规划|下楼梯|数字三角形(C++)

记忆化搜索 在搜索的过程中,如果搜索树中有很多重复的结点,此时可以通过⼀个"备忘录",记录第⼀次搜索到的结果。当下⼀次搜索到这个结点时,直接在"备忘录"⾥⾯找结果。其中,搜索树中的⼀个⼀个结点…...

工业制造各个系统术语

简单总结下 文章目录 MES:制造执行系统ERP:企业资源计划PLM:产品生命周期管理MRP:物资需求计划QMS:质量管理系统APS:高级计划与排程SRM:供应商关系管理SCM:供应链管理CRM:客户关系管理WMS:仓库管理系统TMS:运输管理系统PMS:生产管理系统LES:物流执行系统FICO:财务与成本控制模块…...

搜广推校招面经七十一

滴滴算法工程师面经 一、矩阵分解的原理与优化意义 矩阵分解在推荐系统中是一个非常核心的方法,尤其是在 协同过滤(Collaborative Filtering) 中。我们可以通过用户对物品的评分行为来推测用户的喜好,从而推荐他们可能喜欢的内容。 1.1. 直观理解&…...

解决 ECharts 图表无数据显示问题

问题: 在开发项目时,后端明明已经成功返回了数据,但在展示手账发布数量趋势和树洞帖子发布数量趋势的 ECharts 图表中,却只有坐标轴,没有任何数据显示。 以我的VUE项目开发可视化面板为例,下面将详细分析可…...

【UE5】RTS游戏的框选功能实现

目录 效果 步骤 一、项目准备 二、框选NPC并移动到指定地点 三、框选效果 效果 步骤 一、项目准备 1. 新建一个俯视角游戏工程 2. 新建一个pawn、玩家控制器和游戏模式,这里分别命名为“MyPawn”、“MyController”和“MyGameMode” 3. 打开“MyGameMode”…...

【同步教程】基于Apache SeaTunnel从MySQL同步到MySQL——Demo方舟计划

文章作者:陈飞 中付支付大数据工程师 大家好,很高兴通过 SeaTunnel Demo 方舟计划 和大家分享一个 简单但常见的 MySQL 到 MySQL 数据同步与合并场景案例。 我是陈飞,目前就职于中付支付基础架构部,从事大数据相关工作&#xff…...

人工智能与认知科学的交汇:机器是否能“理解”?

📝个人主页🌹:一ge科研小菜鸡-CSDN博客 🌹🌹期待您的关注 🌹🌹 一、引言:AI与认知的“悖论” 当我们谈论人工智能时,往往聚焦于它的“能力”——会下围棋、会写文章、会画画,甚至能写代码。这些能力让AI像极了一个“聪明人”。但一个根本问题始终没有被真正解…...

React Native 0.79发布 - 更快的工具及更多改进

React Native 0.79版本发布了。 此版本在多个方面进行了性能改进,并修复了一些漏洞。首先,得益于延迟哈希技术,Metro的启动速度变快了,并且对包导出提供了稳定支持。由于JS包压缩方式的改变等原因,Android的启动时间也…...

嵌入式---灰度传感器

灰度传感器概览 一、定义与核心功能 1. 定义 灰度传感器是一种基于 光反射原理 的光电传感器,通过检测物体表面对入射光(多为红外光或可见光)的反射强度,将光信号转换为电信号,从而判断目标物体的 灰度值&#xff0…...

基于ueditor编辑器的功能开发之增加自定义一键排版功能

用户有自己的文章格式,要求复制或者粘贴进来的文章能够一键排版,不需要手动调试 这个需求的话咱们就需要自己去注册一个事件啦,这里我没有修改源码,而是在编辑器初始化之后给他注册了一个事件 我的工具列表变量 vue组件中data中…...

docker部署elk

一、准备镜像 二、创建Elasticsearch容器 2.1启动Elasticsearch容器 docker run -d --name elasticsearch \-e "discovery.typesingle-node" \-e "bootstrap.memory_locktrue" \-e "ES_JAVA_OPTS-Xms2g -Xmx2g" \-e "xpack.security.enab…...

BGP路由协议

为方便管理规模不断扩大的网络,网络被分成了不同的 AS (Autonomous System,自治系统)。早期,EGP (Exterior Gateway Protocol,外部网关协议)被用于实现在 AS 之间动态交换路由信息。但是 EGP 设计得比较简单,只发布网络…...

vue3中watch的使用示例

使用情况说明: 1、父组件中有个表格,点击表格行的修改基础信息,弹出修改对话框; 2、修改内容点击确认,发送请求,后端更新数据;不修改内容不发送请求; 3、可以连续修改&#xff1b…...

OpenBMC:BmcWeb 处理http请求7 完成http请求

OpenBMC:BmcWeb 处理http请求6 调用路由处理函数-CSDN博客 用户会通过填充asyncResp设置响应内容 OpenBMC:BmcWeb 处理http请求1 生成Request和AsyncResp对象_bmc web-CSDN博客 构造了asyncResp 可以看到asyncResp是一个shared_ptr 并且在构造后设置了setCompleteRequestHand…...