三、FastAPI实战:从POST接口设计到自动化测试脚本的完整闭环

news2026/3/15 16:04:24
1. 从零开始为什么需要一个完整的“开发-测试”闭环你好我是老张一个在前后端领域摸爬滚打了十多年的老码农。不知道你有没有过这样的经历吭哧吭哧写好了后端接口信心满满地交给前端或者测试同学结果对方跑过来说“老张你这接口报错了”、“参数不对啊”、“返回的数据格式怎么和文档说的不一样” 然后你就得放下手头的工作切回开发环境打开Postman或者浏览器手忙脚乱地调试一通。一来二去时间浪费了心情也搞差了。这种“开发-测试”脱节的情况在快速迭代的项目里尤其常见。后来我发现一个高效的开发者不仅要会写代码更要会“验证”自己的代码。最好的方式就是在开发接口的同时就把测试脚本也写好。这就是所谓的“开发即测试”实践。今天我就以最火的Python异步Web框架FastAPI为例带你走通一个完整的实战闭环从设计一个用户注册的POST接口开始到编写一个能模拟真实用户操作注册、登录、查询的自动化测试脚本为止。这个过程听起来有点复杂但其实核心就两步用FastAPI把接口做出来再用Python的Requests库把它测明白。一旦这个闭环跑通了你会发现你的开发效率和质量都会有质的飞跃。再也不用等别人来告诉你接口有问题你自己在提交代码前就已经心里有底了。好废话不多说我们直接进入实战。2. 基石彻底搞懂POST请求与FastAPI的响应机制在动手敲代码之前我们得先把地基打牢。很多新手写POST接口出问题根源其实是对HTTP的POST请求和FastAPI的处理机制理解不透。这一节我们就来掰开揉碎了讲清楚。2.1 GET 和 POST不只是“查”和“增”那么简单教科书上常说GET用于获取数据POST用于提交数据。这个说法没错但太笼统了。在实际开发中尤其是API设计时它们的区别直接关系到安全性和规范性。你可以把GET想象成“明信片”。你要查询什么信息比如“用户ID123的资料”就直接把这行字写在明信片正面也就是URL里比如GET /users/123。邮递员网络上的各种网关、代理服务器都能看到这个信息。所以GET请求的参数是暴露在URL中的这决定了它不能传递密码、身份证号这类敏感信息而且URL长度有限制不适合传递大量数据比如一个复杂的JSON对象。而POST更像是“密封的信件”。你要提交的数据比如注册信息用户名、密码、邮箱是写在信纸请求体上然后装进信封里的。信封外面只写着“寄给用户注册处”也就是URL比如POST /user/register。邮递员看不到信的具体内容。因此POST请求的数据放在请求体Body中相对安全也没有数据大小的硬性限制非常适合提交表单或复杂的JSON数据。在FastAPI里这种区别直接体现在代码的写法上。一个GET接口参数通常来自路径如/users/{id}或查询字符串如?name张三。而一个POST接口它的核心数据来自一个叫“请求体”的东西。FastAPI最方便的一点是它能自动帮你把客户端发送过来的JSON格式数据转换成Python的字典或者你定义好的数据模型你几乎不用操心解析的细节。2.2 你的第一个POST接口两数相加的微服务光说不练假把式我们立刻来写一个最简单的POST接口感受一下FastAPI的便捷。这个接口的功能是接收两个数字返回它们的和。首先创建一个新的Python文件比如叫first_api.py。然后把下面的代码敲进去from fastapi import FastAPI # 1. 创建FastAPI应用实例。这个app对象就是你整个Web应用的核心。 app FastAPI() # 2. 使用装饰器定义POST接口。app.post(/add) 表示 # - 这个函数处理发送到 /add 这个路径的请求。 # - 并且只处理HTTP方法为POST的请求。 app.post(/add) def add_numbers(data: dict): 一个简单的两数相加接口。 期待客户端以JSON格式发送如 {a: 5, b: 3} 的数据。 # 3. 从请求体中获取数据。 # 参数data: dict告诉FastAPI请把请求体中的JSON自动解析成Python字典。 # 客户端发来的{a:5, b:3}在这里会变成 data {a:5, b:3}。 a data.get(a) b data.get(b) # 4. 手动进行参数校验初级做法后面我们会用更好的方法。 # 检查a和b是否都是数字int或float类型。 if not (isinstance(a, (int, float)) and isinstance(b, (int, float))): # 如果不是返回一个错误响应的字典。 return { code: 400, message: 参数 a 和 b 必须是数字类型, data: None } # 5. 业务逻辑执行加法运算。 result a b # 6. 构造并返回成功的响应。 # 直接返回一个字典FastAPI会自动将它转换为JSON格式并设置正确的HTTP头。 return { code: 200, message: 计算成功, data: {sum: result} # 把结果放在data字段里是一种良好的响应格式规范。 }代码写好了怎么运行呢打开终端进入到你的代码所在目录执行命令uvicorn first_api:app --reload这个命令的意思是使用Uvicorn服务器运行first_api文件里的app对象--reload参数表示开启热重载你修改代码后服务器会自动重启非常适合开发。启动成功后你会看到输出信息里包含Uvicorn running on http://127.0.0.1:8000。最神奇的事情来了打开浏览器访问http://127.0.0.1:8000/docs。你会看到一个非常漂亮、完整的交互式API文档页面这就是FastAPI自带的Swagger UI。找到我们刚写的/add接口点击“Try it out”按钮在请求体输入框里填入{a: 10, b: 20}然后点击“Execute”。瞬间你就能在下方看到返回的JSON结果{code:200, message:计算成功, data:{sum:30}}。这个过程是不是比想象中简单我们没写任何解析JSON的代码也没手动设置响应头FastAPI都帮我们做好了。但是这个接口有个明显的问题参数校验太简陋了。我们用了data.get(“a”)和手动isinstance检查。如果参数很多校验逻辑会变得非常臃肿。别急这正是我们接下来要解决的。3. 进阶用Pydantic模型打造健壮的POST接口刚才我们手动校验参数的方式在小型或临时接口中还能凑合但在正经项目中绝对是个“坑”。想象一下用户注册接口需要校验用户名、密码、邮箱、手机号……手动写校验代码会是一场噩梦。FastAPI 的“杀手级”特性之一就是与Pydantic库的无缝集成。Pydantic 是一个基于Python类型提示的数据验证和设置管理库能用声明式的方式定义数据模型并自动进行验证。3.1 为什么需要Pydantic模型让我们先看看没有Pydantic的“坑”。假设我们要写一个用户注册接口要求用户名至少3位密码至少8位且包含字母和数字。手动校验的代码可能会写成这样app.post(/register) def register(username: str Form(...), password: str Form(...)): if len(username) 3: return {error: 用户名太短} if len(password) 8: return {error: 密码太短} if not any(c.isalpha() for c in password): return {error: 密码需包含字母} if not any(c.isdigit() for c in password): return {error: 密码需包含数字} # ... 一堆业务逻辑代码又长又臭而且校验逻辑和业务逻辑混在一起。如果用Pydantic模型我们可以把数据定义和校验规则“打包”成一个类from pydantic import BaseModel, Field class UserRegisterRequest(BaseModel): username: str Field(..., min_length3, max_length20, description用户名) password: str Field(..., min_length8, regexr^(?.*[A-Za-z])(?.*\d).*$, description密码需包含字母和数字) email: str Field(..., regexr^[a-zA-Z0-9._%-][a-zA-Z0-9.-]\.[a-zA-Z]{2,}$)你看我们把“用户名长度3-20位”、“密码至少8位且包含字母数字”、“邮箱格式”这些规则直接写在了数据模型的字段定义里。清晰、直观、可复用。3.2 实战设计一个完整的用户管理接口现在我们来构建一个更真实、更健壮的用户管理模块。这个模块包含三个核心接口注册、登录、查看用户信息。我们会使用Pydantic模型来定义请求和响应体让代码既健壮又优雅。首先安装必要的库如果你还没安装的话pip install fastapi uvicorn pydantic然后创建一个新的文件user_api.py开始编写代码from fastapi import FastAPI, HTTPException, Depends from pydantic import BaseModel, Field, EmailStr from typing import List, Optional import hashlib # 用于密码哈希实际存储不应是明文 # 初始化FastAPI应用 app FastAPI(title用户管理API, description一个完整的用户注册登录示例) # --- 1. 定义数据模型 (Pydantic Schemas) --- # 请求体模型定义客户端应该发送什么样的数据 class UserRegisterRequest(BaseModel): username: str Field(..., min_length3, max_length20, examplezhangsan, description用户名3-20位字符) password: str Field(..., min_length8, exampleMyPass123, description密码至少8位建议包含字母、数字和符号) email: EmailStr Field(..., exampleuserexample.com, description有效的邮箱地址) # EmailStr是Pydantic提供的邮箱验证类型 class UserLoginRequest(BaseModel): username: str Field(..., examplezhangsan) password: str Field(..., exampleMyPass123) # 响应体模型定义接口返回什么样的数据 class UserResponse(BaseModel): id: int username: str email: str # 注意响应中永远不要返回密码 class SuccessResponse(BaseModel): code: int 200 message: str 操作成功 data: Optional[dict] None # Optional表示这个字段可以为None # --- 2. 模拟数据库实际项目请用真实数据库如SQLAlchemy --- fake_db [] current_id 1 def hash_password(password: str) - str: 一个简单的密码哈希函数实际项目应使用更安全的如bcrypt return hashlib.sha256(password.encode()).hexdigest() # --- 3. 实现核心接口 --- app.post(/user/register, response_modelSuccessResponse, summary用户注册, tags[用户]) async def register_user(user_data: UserRegisterRequest): 用户注册接口。 - **username**: 用户名需唯一。 - **password**: 密码。 - **email**: 邮箱需唯一。 # 3.1 检查用户名和邮箱是否已存在 for user in fake_db: if user[username] user_data.username: raise HTTPException(status_code400, detail用户名已存在) if user[email] user_data.email: raise HTTPException(status_code400, detail邮箱已注册) global current_id # 3.2 创建新用户记录密码存储哈希值而非明文 new_user { id: current_id, username: user_data.username, email: user_data.email, hashed_password: hash_password(user_data.password) # 存储哈希值 } fake_db.append(new_user) current_id 1 # 3.3 返回成功响应使用我们定义好的SuccessResponse模型 return SuccessResponse( messagef用户 {user_data.username} 注册成功, data{user_id: new_user[id]} ) app.post(/user/login, response_modelSuccessResponse, summary用户登录, tags[用户]) async def login_user(login_data: UserLoginRequest): 用户登录接口。 验证用户名和密码。 hashed_input_password hash_password(login_data.password) for user in fake_db: if user[username] login_data.username and user[hashed_password] hashed_input_password: # 登录成功在实际项目中这里通常会生成并返回一个Token如JWT return SuccessResponse( messagef欢迎回来{login_data.username}, data{access_token: fake-jwt-token-for-demo, token_type: bearer} ) # 如果循环结束都没找到匹配的用户 raise HTTPException(status_code401, detail用户名或密码错误) app.get(/user/list, response_modelSuccessResponse, summary获取用户列表, tags[用户]) async def get_user_list(): 获取所有用户的基本信息列表不包含敏感信息如密码。 # 使用列表推导式将数据库中的每条记录转换为响应模型格式 user_list [UserResponse(idu[id], usernameu[username], emailu[email]) for u in fake_db] return SuccessResponse(data{users: user_list})这段代码比之前的例子丰富多了我们来拆解一下关键点数据模型是核心UserRegisterRequest和UserLoginRequest定义了请求的“形状”。Field函数让我们能添加详细的验证规则和示例值。EmailStr直接确保了邮箱格式的有效性。response_modelSuccessResponse则定义了响应的统一格式这能让API的返回风格保持一致。错误处理专业化我们不再用简单的return {“error”: …}而是使用了FastAPI提供的HTTPException。这能确保错误发生时返回标准的HTTP状态码如400 Bad Request, 401 Unauthorized和结构化的错误信息前端处理起来更方便。密码安全我们用一个简单的哈希函数模拟了密码加密存储。切记真实项目中绝对不要明文存储密码一定要使用bcrypt或passlib这类专门的安全哈希库。API文档自动化注意到函数下的三引号文档字符串了吗还有summary和tags参数FastAPI会自动把这些信息整合到/docs和/redoc的交互式文档里你写的注释直接就变成了API文档一举两得。启动这个服务 (uvicorn user_api:app --reload)再次打开http://127.0.0.1:8000/docs你会看到一个分类清晰、描述详细、并且可以直接测试的API文档页面。尝试在注册接口里输入一个不合法的邮箱比如invalid-emailFastAPI会直接在界面上提示验证错误根本不会让请求进入你的代码逻辑。这就是Pydantic模型带来的强大保障。4. 闭环关键编写可复用的Python Requests自动化测试脚本接口开发完了文档也有了是不是就大功告成了还差最关键的一步验证。我们不能总依赖手点Swagger UI来测试。我们需要一个能自动运行、能模拟各种场景正常、异常、并且能集成到开发流程中的测试脚本。Python的requests库就是完成这个任务的不二之选。它简单、强大用来测试HTTP接口就像用筷子吃饭一样自然。4.1 告别零散测试构建一个结构化的测试类很多新手写测试脚本就是一个简单的.py文件里面一堆requests.post()调用。这不利于维护和复用。我习惯把测试脚本也当成一个正经项目来组织。我们来创建一个test_user_api.py文件并采用类的形式来组织测试用例。import requests import json import time class UserAPITester: 用户管理API自动化测试类。 封装了测试步骤、断言和报告使测试代码更清晰、可复用。 BASE_URL http://127.0.0.1:8000 # 被测服务的基地址 def __init__(self): self.session requests.Session() # 使用Session可以保持Cookie等会话信息 self.current_user None # 记录当前登录的用户信息 print(f[初始化] 测试目标服务: {self.BASE_URL}) def _send_request(self, method, endpoint, json_dataNone, paramsNone): 发送HTTP请求的通用辅助方法统一处理异常和日志 url f{self.BASE_URL}{endpoint} try: print(f\n[请求] {method} {url}) if json_data: print(f[请求体] {json.dumps(json_data, indent2, ensure_asciiFalse)}) response self.session.request(method, url, jsonjson_data, paramsparams) print(f[状态码] {response.status_code}) print(f[响应体] {response.text}) return response except requests.exceptions.ConnectionError: print(f[错误] 无法连接到服务 {url}请确保FastAPI服务已启动) return None def test_register(self, username, password, email): 测试用户注册接口 print(f\n 开始测试注册用户 [{username}] ) endpoint /user/register payload { username: username, password: password, email: email } resp self._send_request(POST, endpoint, json_datapayload) if resp and resp.status_code 200: data resp.json() if data.get(code) 200: print(f[结果] 注册成功用户ID: {data.get(data, {}).get(user_id)}) return True else: print(f[结果] 注册失败: {data.get(message)}) else: print(f[结果] 注册请求失败状态码: {resp.status_code if resp else N/A}) return False def test_login(self, username, password): 测试用户登录接口 print(f\n 开始测试用户登录 [{username}] ) endpoint /user/login payload {username: username, password: password} resp self._send_request(POST, endpoint, json_datapayload) if resp and resp.status_code 200: data resp.json() if data.get(code) 200: token data.get(data, {}).get(access_token) print(f[结果] 登录成功Token: {token}) self.current_user username # 记录登录状态 return True else: print(f[结果] 登录失败: {data.get(message)}) elif resp and resp.status_code 401: print([结果] 登录失败认证错误用户名或密码不正确) return False def test_get_user_list(self): 测试获取用户列表接口 print(f\n 开始测试获取用户列表 ) endpoint /user/list resp self._send_request(GET, endpoint) if resp and resp.status_code 200: data resp.json() users data.get(data, {}).get(users, []) print(f[结果] 成功获取到 {len(users)} 个用户) for user in users: print(f - ID:{user[id]}, 用户名:{user[username]}, 邮箱:{user[email]}) return True return False def run_full_workflow(self): 运行一个完整的用户操作流程注册 - 登录 - 查看列表 print(\n *50) print(开始执行完整用户操作流程测试) print(*50) # 生成一个唯一用户名避免重复注册错误 timestamp int(time.time()) test_username ftest_user_{timestamp} test_password TestPassword123 test_email f{test_username}test.com # 1. 测试注册 if not self.test_register(test_username, test_password, test_email): print(流程中断注册失败) return # 2. 测试登录 if not self.test_login(test_username, test_password): print(流程中断登录失败) return # 3. 测试查看用户列表 self.test_get_user_list() print(\n *50) print(完整流程测试执行完毕) print(*50) # 主程序入口 if __name__ __main__: tester UserAPITester() # 运行一个完整的正向流程 tester.run_full_workflow() # 你也可以单独测试异常场景例如 # print(\n\n 额外测试重复注册 ) # tester.test_register(admin, password123, admintest.com) # 假设admin已存在这个测试脚本的结构就专业多了。UserAPITester类封装了所有测试细节。_send_request是核心的请求发送方法它统一了日志打印和异常处理。每个具体的测试用例如test_register都专注于业务断言检查状态码是不是200响应体里的code字段是不是成功message是否符合预期。4.2 模拟真实场景异常测试与数据驱动一个好的测试脚本不能只测“阳光大道”更要测“泥泞小路”。我们需要模拟用户可能犯的各种错误确保我们的接口能优雅地处理异常而不是直接崩溃。我们可以在上面的测试类里增加一些异常测试方法def test_register_with_invalid_email(self): 测试使用非法邮箱格式进行注册 print(f\n 开始测试非法邮箱注册 ) endpoint /user/register payload { username: bad_email_user, password: SomePass123, email: this-is-not-an-email # 明显非法的邮箱格式 } resp self._send_request(POST, endpoint, json_datapayload) # Pydantic会进行验证FastAPI会返回422 Unprocessable Entity if resp and resp.status_code 422: print(f[结果] 符合预期接口正确拒绝了非法邮箱状态码{resp.status_code}) return True else: print(f[警告] 接口未对非法邮箱进行有效验证。状态码{resp.status_code if resp else N/A}) return False def test_login_with_wrong_password(self): 测试使用错误密码登录 print(f\n 开始测试错误密码登录 ) # 先确保存在一个测试用户 test_user existing_user test_email existingtest.com self.test_register(test_user, CorrectPass123, test_email) # 先注册 endpoint /user/login payload {username: test_user, password: WrongPass456} # 错误密码 resp self._send_request(POST, endpoint, json_datapayload) if resp and resp.status_code 401: # 期望返回401未授权 print(f[结果] 符合预期密码错误导致登录失败状态码{resp.status_code}) return True else: print(f[警告] 密码错误时未返回401。状态码{resp.status_code if resp else N/A}) return False把这些异常测试加到你的run_full_workflow或者一个新的测试套件里你的接口健壮性就有了保障。更进一步我们可以引入“数据驱动测试”的概念。将测试用例的数据正常和异常放到一个JSON文件或列表里让测试方法循环读取执行。这样当你需要增加新的测试用例时只需要改数据文件而不需要改测试代码。def run_data_driven_tests(self): 数据驱动测试示例 test_cases [ {name: 正常注册, “username”: “user1”, “password”: “pass1”, “email”: “u1test.com”, “should_pass”: True}, {name: “用户名太短”, “username”: “ab”, “password”: “pass123”, “email”: “u2test.com”, “should_pass”: False}, {name: “密码太短”, “username”: “user3”, “password”: “123”, “email”: “u3test.com”, “should_pass”: False}, {name: “邮箱格式错误”, “username”: “user4”, “password”: “pass123”, “email”: “bad-email”, “should_pass”: False}, ] for case in test_cases: print(f\n 执行用例{case[name]}) result self.test_register(case[“username”], case[“password”], case[“email”]) # 根据 should_pass 的预期来判断测试是否通过 if result case[“should_pass”]: print(f[断言通过] 结果符合预期) else: print(f[断言失败] 结果不符合预期)通过这种方式你的测试脚本就从一次性的“玩具”变成了一个可维护、可扩展、能真正保障接口质量的“工程化”工具。每次修改完接口代码跑一遍这个脚本所有核心路径和异常情况都验证一遍心里就踏实多了。这才是“开发即测试”闭环带来的真正效率提升。

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

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

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…