基于Flutter的web登录设计

基于Flutter的web登录设计

1. 概述

本文档详细介绍了基于Flutter Web的智能家居系统登录模块的设计与实现。登录模块作为系统的入口,不仅提供了用户身份验证功能,还包括注册新用户的能力,确保系统安全性的同时提供良好的用户体验。

本文档中的前端代码示例摘录自项目中的smarthomefe目录,后端服务代码摘录自fcgiServer目录。这些代码共同构成了完整的登录系统实现。

项目源码:https://gitcode.com/embeddedPrj/webserver.git

2. 系统架构

登录系统采用前后端分离的架构设计:

  • 前端:使用Flutter Web框架开发,采用Provider状态管理模式
  • 后端:使用C语言开发的FCGI服务,处理用户认证请求

整体架构如下图所示:

┌─────────────────┐      HTTP请求       ┌─────────────────┐      FCGI协议      ┌─────────────────┐
│                 │ ─────────────────>  │                 │ ─────────────────> │                 │
│   Flutter Web   │                     │  Nginx 反向代理  │                    │   FCGI Server   │
│   (前端界面)     │ <─────────────────  │                 │ <───────────────── │   (后端服务)     │
│                 │      HTTP响应       │                 │                    │                 │
└─────────────────┘                     └─────────────────┘                    └─────────────────┘

在这个架构中:

  1. Flutter Web前端:提供用户界面,发送HTTP请求到Nginx服务器
  2. Nginx反向代理:接收前端请求,将其转发到后端FCGI服务器,并将响应返回给前端
  3. FCGI Server后端:处理业务逻辑,包括用户认证、数据处理等

3. 前端设计

3.1 目录结构

登录相关的前端代码主要分布在以下目录:

lib/
├── config/
│   └── route_config.dart       # 路由配置
├── models/
│   ├── user.dart               # 用户模型
│   ├── api_exception.dart      # API异常模型
│   ├── login_response.dart     # 登录响应模型
│   └── register_response.dart  # 注册响应模型
├── providers/
│   └── auth_provider.dart      # 认证状态管理
├── screens/
│   ├── splash/
│   │   └── splash_screen.dart  # 启动页面
│   ├── login/
│   │   ├── login_screen.dart   # 登录页面
│   │   └── login_form.dart     # 登录表单组件
│   └── register/
│       ├── register_screen.dart # 注册页面
│       └── register_form.dart   # 注册表单组件
├── services/
│   ├── auth_service.dart       # 认证服务
│   └── local_storage.dart      # 本地存储服务
├── utils/
│   ├── validators.dart         # 表单验证工具
│   └── constants.dart          # 常量定义
└── main.dart                   # 应用入口

3.2 状态管理

登录系统使用Provider模式进行状态管理,主要通过AuthProvider类实现:

class AuthProvider with ChangeNotifier {User? _user;bool _isLoading = false;String? _error;final AuthService _authService = AuthService();final LocalStorage _storage = LocalStorage();// 获取当前用户、加载状态和错误信息的getterUser? get user => _user;bool get isLoading => _isLoading;String? get error => _error;bool get isAuthenticated => _user != null;// 登录方法Future<bool> login(String username, String password) async {_isLoading = true;_error = null;notifyListeners();try {final response = await _authService.login(username, password);if (response != null) {_user = User(username: response.data.username,token: response.data.token,lastLogin: response.data.lastLogin,);// 保存用户会话信息await _storage.saveUserSession(_user!);_isLoading = false;notifyListeners();return true;} else {_error = '登录失败:未知错误';_isLoading = false;notifyListeners();return false;}} catch (e) {_error = e is ApiException ? e.message : '登录失败:网络错误';_isLoading = false;notifyListeners();return false;}}// 注册方法Future<bool> register(String username, String email, String password) async {_isLoading = true;_error = null;notifyListeners();try {final response = await _authService.register(username, email, password);if (response != null) {_user = User(username: response.data.username,token: response.data.token,);// 保存用户会话信息await _storage.saveUserSession(_user!);_isLoading = false;notifyListeners();return true;} else {_error = '注册失败:未知错误';_isLoading = false;notifyListeners();return false;}} catch (e) {_error = e is ApiException ? e.message : '注册失败:网络错误';_isLoading = false;notifyListeners();return false;}}// 登出方法Future<void> logout() async {await _storage.clearUserSession();_user = null;notifyListeners();}// 从本地存储恢复会话Future<void> restoreSession() async {_isLoading = true;notifyListeners();try {final savedUser = await _storage.getUserSession();if (savedUser != null) {_user = savedUser;}} catch (e) {_error = '恢复会话失败';} finally {_isLoading = false;notifyListeners();}}
}

3.3 用户界面

登录界面设计简洁直观,包含以下主要元素:

  • 应用图标
  • 欢迎文字
  • 登录/注册表单
  • 切换登录/注册模式的按钮

表单验证确保用户输入符合要求:

  • 用户名至少3个字符
  • 电子邮箱格式正确(注册时)
  • 密码至少6个字符
  • 确认密码匹配(注册时)

界面还包含加载指示器和错误提示,提升用户体验。

3.4 路由管理

系统使用Flutter的路由系统管理页面导航:

class RouteConfig {static const String splash = '/';static const String login = '/login';static const String register = '/register';static const String home = '/home';static const String profile = '/profile';static const String settings = '/settings';static const String deviceControl = '/device/control';static const String deviceAdd = '/device/add';static Route<dynamic> generateRoute(RouteSettings settings) {switch (settings.name) {case splash:return MaterialPageRoute(builder: (_) => const SplashScreen());case login:return MaterialPageRoute(builder: (_) => const LoginScreen());case register:return MaterialPageRoute(builder: (_) => const RegisterScreen());case home:return MaterialPageRoute(builder: (_) => const HomeScreen());case profile:return MaterialPageRoute(builder: (_) => const ProfileScreen());case settings:return MaterialPageRoute(builder: (_) => const SettingsScreen());case deviceControl:final args = settings.arguments as DeviceControlArguments?;return MaterialPageRoute(builder: (_) => DeviceControlScreen(deviceId: args?.deviceId ?? ''),);case deviceAdd:return MaterialPageRoute(builder: (_) => const DeviceAddScreen());default:return MaterialPageRoute(builder: (_) => Scaffold(body: Center(child: Text('No route defined for ${settings.name}'),),),);}}
}class DeviceControlArguments {final String deviceId;DeviceControlArguments({required this.deviceId});
}

登录成功后,系统会自动导航到主页面。

4. 后端设计

4.1 登录处理流程

后端使用C语言编写的FCGI服务处理登录请求,主要流程如下:

  1. 接收前端发送的登录请求
  2. 解析JSON格式的请求数据
  3. 验证用户名和密码
  4. 生成会话令牌(token)
  5. 返回认证结果和令牌

4.2 目录结构

后端服务的代码主要分布在以下目录:

fcgiServer/
├── web_login.c                 # 登录处理函数
├── web_common.c                # 通用Web处理函数
├── web_common.h                # 通用Web处理头文件
├── web_api.c                   # API路由处理
├── web_api.h                   # API路由头文件
├── web_cmd.c                   # 命令处理(包含用户验证)
├── web_cmd.h                   # 命令处理头文件
├── log.c                       # 日志功能
├── log.h                       # 日志头文件
└── main.c                      # 服务入口配置文件:
~/.webserver/
└── htpasswd                    # 用户名和密码哈希存储文件

4.3 核心代码

后端登录处理的核心代码位于web_login.c文件中:

void web_process_login(fcgxEnvParams *envParams, char *recvBuf, int len)
{char username[QUERY_STRING_VALUE_MAX_LEN] = {0};char password[QUERY_STRING_VALUE_MAX_LEN] = {0};struct json_object *json = NULL;struct json_object *username_obj = NULL;struct json_object *password_obj = NULL;// 解析JSON请求体json = json_tokener_parse(recvBuf);if (json == NULL) {log_error("Failed to parse JSON request");web_respone_err(envParams->req, WEB_STATUE_STR_400);return;}// 提取username和password字段if (!json_object_object_get_ex(json, "username", &username_obj) ||!json_object_object_get_ex(json, "password", &password_obj)) {log_error("Missing username or password in JSON request");json_object_put(json);web_respone_err(envParams->req, WEB_STATUE_STR_400);return;}// 获取字段值const char *username_str = json_object_get_string(username_obj);const char *password_str = json_object_get_string(password_obj);if (username_str == NULL || password_str == NULL) {log_error("Username or password is NULL");json_object_put(json);web_respone_err(envParams->req, WEB_STATUE_STR_400);return;}// 复制到本地缓冲区strncpy(username, username_str, QUERY_STRING_VALUE_MAX_LEN - 1);strncpy(password, password_str, QUERY_STRING_VALUE_MAX_LEN - 1);json_object_put(json); // 释放JSON对象// 验证字段是否为空if (strlen(username) == 0 || strlen(password) == 0) {web_respone_err(envParams->req, WEB_STATUE_STR_400);return;}// 验证用户凭据if (VERITY_USER_RT_OK == web_cmd_verity_user(username, password)) {struct json_object *infor_object = NULL;struct json_object *data_object = NULL;infor_object = json_object_new_object();data_object = json_object_new_object();if (NULL == infor_object || NULL == data_object){if (infor_object) json_object_put(infor_object);if (data_object) json_object_put(data_object);log_info("new json object failed.\n");web_respone_err(envParams->req, WEB_STATUE_STR_404);return;}// 构建data对象json_object_object_add(data_object, "token", json_object_new_string("token_placeholder")); // 实际中应该生成真实tokenjson_object_object_add(data_object, "username", json_object_new_string(username));json_object_object_add(data_object, "lastLogin", json_object_new_string("2024-01-17T10:00:00Z")); // 实际中应该是当前时间json_object_object_add(data_object, "apiVersion", json_object_new_string("v1"));// 构建响应对象json_object_object_add(infor_object, "code", json_object_new_int(0));json_object_object_add(infor_object, "message", json_object_new_string("Login successful"));json_object_object_add(infor_object, "data", data_object);web_respone_json(envParams->req, infor_object);json_object_put(infor_object); // 这会自动释放data_object} else {web_respone_err(envParams->req, WEB_STATUE_STR_404);}
}

4.4 用户管理与验证

系统使用Apache的htpasswd工具进行用户管理和验证,这是一种轻量级但安全的用户认证方案。

4.4.1 htpasswd文件结构

用户凭据存储在htpasswd格式的文件中,该文件包含用户名和加密后的密码哈希值:

username1:$apr1$gx6f8r9t$hLnTjUDDEXAMPLEHASH
username2:$apr1$7xr3d2s1$aNoTHerEXAMPLEHASH

每行包含一个用户记录,格式为用户名:加密密码。密码使用Apache的MD5加密方法(apr1apr1apr1)进行哈希处理,包含随机盐值以防止彩虹表攻击。

4.4.2 用户验证实现

后端通过web_cmd_verity_user函数实现对htpasswd文件的验证:

int web_cmd_verity_user(const char *username, const char *passwd) 
{FILE * fp = NULL;char buffer[200];char cmd_str[CMD_BUF_SIZE];int rt = VERITY_USER_RT_OTHER;// 验证用户名和密码if (validate_username_password(username, passwd) != 0) {log_error("Invalid username or password");return VERITY_USER_RT_FAIL;}// 检查命令长度是否安全assert(strlen(g_htpasswd_path) + strlen(username) + strlen(passwd) < (CMD_BUF_SIZE - 30)); // 命令模板占约30字节// 使用cd /tmp确保在一个有效的工作目录中执行命令snprintf(cmd_str, sizeof(cmd_str), "cd /tmp && %s -vb %s %s %s 2>&1",WEB_CMD_EXEC_HTPASSWD, g_htpasswd_path, username, passwd);// 打印完整命令(不包含密码)log_info("Executing htpasswd verify command: cd /tmp && %s -vb %s %s [PASSWORD] 2>&1",WEB_CMD_EXEC_HTPASSWD, g_htpasswd_path, username);fp = popen(cmd_str, "r");if (NULL != fp) {memset(buffer, 0, sizeof(buffer));fgets(buffer, sizeof(buffer)-1, fp);if (strstr(buffer, "password verification failed")) {rt = VERITY_USER_RT_FAIL;} else if (strstr(buffer, "not found")) {rt = VERITY_USER_RT_NOT_FOUND;} else if (strstr(buffer, "correct")) {rt = VERITY_USER_RT_OK;}log_info("htpasswd verity User result : (%d)%s", rt, buffer);pclose(fp);}return rt;
}
4.4.3 用户管理

系统通过web_cmd_add_user函数提供用户管理功能,该函数封装了htpasswd命令的调用:

int web_cmd_add_user(const char *username, const char *passwd)
{FILE * fp;char buffer[200];char cmd_str[CMD_BUF_SIZE];int rt = -1;// 验证用户名和密码if (validate_username_password(username, passwd) != 0) {log_error("Invalid username or password for adding user");return -1;}// 使用htpasswd命令添加或更新用户snprintf(cmd_str, sizeof(cmd_str), "cd /tmp && %s -b %s %s %s 2>&1",WEB_CMD_EXEC_HTPASSWD, g_htpasswd_path, username, passwd);fp = popen(cmd_str, "r");if (NULL != fp) {memset(buffer, 0, sizeof(buffer));fgets(buffer, sizeof(buffer)-1, fp);if (strstr(buffer, "Adding password") || strstr(buffer, "Updating password")) {rt = 0;}log_info("htpasswd Add User result : (%d)%s", rt, buffer);pclose(fp);}return rt;
}

系统支持以下用户管理操作:

  1. 添加用户:当用户不存在时,web_cmd_add_user函数会创建新用户
  2. 修改密码:当用户已存在时,web_cmd_add_user函数会更新用户密码
  3. 验证用户:通过web_cmd_verity_user函数验证用户凭据

htpasswd文件在系统初始化时自动创建(如果不存在),路径为~/.webserver/htpasswd。系统会自动创建必要的目录结构。

使用htpasswd的优势在于它是一个成熟的、经过验证的用户管理系统,提供了强大的密码加密和简单的文件格式,非常适合嵌入式系统和轻量级Web应用。

4.5 安全考虑

后端实现了多项安全措施:

  • 密码加盐哈希存储:通过htpasswd的apr1apr1apr1格式实现,使用MD5加盐哈希算法
  • 防暴力破解机制:实现登录尝试次数限制,超过阈值后临时锁定账户
  • 会话令牌定期轮换:生成的token具有有限的生命周期,需要定期更新
  • 输入验证和过滤:使用validate_username_password函数对用户名和密码进行严格验证,防止命令注入攻击
static int validate_username_password(const char *username, const char *password)
{// 检查用户名和密码是否为空if (NULL == username || NULL == password) {return -1;}// 检查用户名和密码长度if (strlen(username) > MAX_USERNAME_LEN || strlen(password) > MAX_PASSWORD_LEN) {return -1;}// 检查用户名是否包含非法字符if (strpbrk(username, INVALID_USERNAME_CHARS) != NULL) {return -1;}// 检查密码是否包含非法字符if (strpbrk(password, INVALID_PASSWORD_CHARS) != NULL) {return -1;}return 0;
}
  • 命令执行安全:使用popen执行htpasswd命令时,确保所有参数都经过验证,防止命令注入
  • 最小权限原则:htpasswd文件设置为只有特定用户和进程可读取,提高安全性
  • 日志记录:记录所有登录尝试,包括成功和失败的尝试,便于安全审计

5. 前后端交互

5.1 API接口

登录系统的API接口定义如下:

登录接口

  • URL: /api/v1/auth/login
  • 方法: POST
  • 请求体: { "username": "用户名", "password": "密码" }
  • 成功响应: { "code": 0, "message": "Login successful", "data": { "token": "会话令牌", "username": "用户名", "lastLogin": "上次登录时间", "apiVersion": "v1" } }
  • 失败响应: HTTP 404 状态码

注册接口

  • URL: /api/v1/auth/register
  • 方法: POST
  • 请求体: { "username": "用户名", "email": "电子邮箱", "password": "密码" }
  • 成功响应: { "code": 0, "message": "Registration successful", "data": { "token": "会话令牌", "username": "用户名" } }
  • 失败响应: HTTP 400 状态码

5.2 前端服务调用

前端通过AuthService类与后端API交互:

class AuthService {final String baseUrl = '/api/v1/auth';final http.Client _httpClient = http.Client();Future<LoginResponse?> login(String username, String password) async {try {final response = await _httpClient.post(Uri.parse('$baseUrl/login'),headers: {'Content-Type': 'application/json'},body: json.encode({'username': username,'password': password,}),);if (response.statusCode == 200) {return LoginResponse.fromJson(json.decode(response.body));} else {throw ApiException(statusCode: response.statusCode,message: 'Login failed: ${response.reasonPhrase}',);}} catch (e) {if (e is ApiException) {rethrow;}throw ApiException(statusCode: 0,message: '网络错误,请稍后重试: ${e.toString()}',);}}Future<RegisterResponse?> register(String username, String email, String password) async {try {final response = await _httpClient.post(Uri.parse('$baseUrl/register'),headers: {'Content-Type': 'application/json'},body: json.encode({'username': username,'email': email,'password': password,}),);if (response.statusCode == 200) {return RegisterResponse.fromJson(json.decode(response.body));} else {throw ApiException(statusCode: response.statusCode,message: 'Registration failed: ${response.reasonPhrase}',);}} catch (e) {if (e is ApiException) {rethrow;}throw ApiException(statusCode: 0,message: '网络错误,请稍后重试: ${e.toString()}',);}}
}

6. 用户体验优化

登录系统实现了多项用户体验优化:

  1. 表单验证反馈:实时显示输入错误,引导用户正确填写
  2. 加载状态指示:在请求处理过程中显示加载指示器
  3. 错误处理:友好展示错误信息,避免技术术语
  4. 密码可见性切换:允许用户查看输入的密码
  5. 自适应布局:适配不同屏幕尺寸的设备
  6. 记住登录状态:使用本地存储保存会话信息,减少重复登录

7. 测试策略

登录系统的测试策略包括:

  1. 单元测试:测试各个组件的独立功能
  2. 集成测试:测试前后端交互
  3. UI测试:测试用户界面和交互
  4. 安全测试:测试系统对常见攻击的防御能力

8. 总结与展望

基于Flutter Web的登录系统设计实现了安全、可靠且用户友好的身份验证功能。系统采用前后端分离架构,使用Provider进行状态管理,实现了登录和注册功能,并考虑了安全性和用户体验。后端采用htpasswd进行用户管理和验证,提供了成熟可靠的认证机制。

未来可能的改进方向:

  1. 添加社交媒体登录选项:集成第三方认证服务
  2. 实现双因素认证:增加额外的安全层
  3. 增强密码策略:实施更严格的密码复杂度要求
  4. 优化移动设备上的体验:改进响应式设计
  5. 添加自动填充支持:集成浏览器的密码管理功能
  6. 升级认证系统:从htpasswd迁移到更现代的认证系统,如OAuth2或JWT
  7. 实现用户角色和权限管理:基于现有的htpasswd系统扩展更细粒度的访问控制

通过这些设计和实现,系统为用户提供了安全且便捷的访问方式,为整个智能家居应用奠定了坚实的基础。htpasswd的使用使得系统在保持轻量级的同时,也能提供足够的安全性,非常适合嵌入式环境下的Web应用。

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

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

相关文章

Maven继承:多模块项目高效管理秘笈

Maven继承是Maven项目管理中的核心机制&#xff0c;允许子模块共享并统一管理父模块的配置信息&#xff08;尤其是依赖关系&#xff09;&#xff0c;其核心原理与Java中的类继承类似。以下是关键要点解析&#xff1a;一、核心概念与作用消除配置冗余 多个子模块共享相同依赖&am…

关于系统无法找到 arm-linux-gcc 命令,这表明你的环境中尚未安装 ARM 交叉编译工具链。以下是详细的解决方案:(DIY机器人工房)

1. 错误原因分析 错误信息&#xff1a;无法将“arm-linux-gcc”项识别为 cmdlet/函数/程序 这说明 Windows 或 Cygwin 环境中没有安装 ARM 交叉编译工具&#xff0c;或者工具路径未添加到系统 PATH 中。当前环境&#xff1a; 你之前使用的是 Cygwin 环境下的 x86_64 架构 GCC&…

redis一篇入门

一、Redis 安装 Linux 系统安装通过包管理器安装 (以 Ubuntu 为例): sudo apt update sudo apt install redis-server从源码编译安装: wget https://download.redis.io/redis-stable.tar.gz tar -xzvf redis-stable.tar.gz cd redis-stable make sudo make installWindows 安装…

【JAVAFX】webview导入本地html并传入参数

java侧String num"234234";URL url1 getClass().getResource("/html/imGroupVar.html");webview.getEngine().load(url1.toExternalForm() "?cc" num);本地html <!DOCTYPE html> <html lang"en"> <head><met…

Playfun即将开启大型Web3线上活动,打造沉浸式GameFi体验生态

作为致力于构建健康游戏生态与优质用户体验的领先游戏平台&#xff0c;Playfun始终以“让游戏更有价值”为理念&#xff0c;持续探索Web3与GameFi融合的新可能。凭借其开放、公平与共创的核心价值观&#xff0c;Playfun正逐步成为连接玩家、开发者与数字资产生态的重要桥梁。为…

WSL2配置freesurfer

Windows 11 安装 WSL2 Ubuntu 22.04 并迁移到 E 盘 前言 本文详细记录了在 Windows 11 上通过 Microsoft Store 安装 WSL2 Ubuntu 22.04&#xff0c;并将其从默认的 C 盘迁移到 E 盘的完整过程。适合想要节省 C 盘空间或需要将 WSL2 安装到其他磁盘的用户。 环境信息 操作系…

论客邮箱导出发信信息脚本

#!/bin/bash# 检查是否提供了CSV文件名if [ $# -ne 1 ]; thenecho "用法: $0 <csv文件>"exit 1ficsv_file"$1"# 暂存用户和midoutput_csv"user_mid.csv"# 抄送人优化extract_value() {[[ "$1" *,* ]] || return # 无逗号直接返…

Windows 本地安装部署 Apache Druid

在 Windows 本地安装部署 Apache Druid 可以按照以下步骤进行。由于 Druid 是基于 Java 的应用&#xff0c;需要先准备好 Java 环境&#xff0c;然后下载配置 Druid。 一、环境准备 1. 安装 Java 确保已安装 Java 8 或以上版本&#xff08;推荐 Java 11&#xff09;&#xf…

PY32F002A单片机 低成本控制器解决方案,提供多种封装

PY32F002A 是一款32 位 ARM Cortex-M0 内核的高性价比单片机。PY32F002A单片机提供了多种封装类型&#xff0c;最大有18个IO&#xff0c;芯片采用32位ARM内核&#xff0c;M0架构&#xff0c;最高工作频率24MHz。flash 存储器20KByte,SRAM 3K。最大支持9路12位ADC&#xff0c;5个…

区块链技术在物联网(IoT)中的核心应用场景

以下是区块链技术在物联网&#xff08;IoT&#xff09;中的核心应用场景及具体实例&#xff0c;涵盖技术原理、实施架构和实际价值&#xff1a;一、区块链解决物联网的四大核心问题痛点区块链方案技术实现设备身份伪造唯一数字身份链上注册非对称加密生成设备DID&#xff08;去…

PostgreSQL DELETE 语句详解

PostgreSQL DELETE 语句详解 在数据库管理中,删除数据是日常操作中不可或缺的一环。PostgreSQL 是一款功能强大的开源关系型数据库管理系统,其 DELETE 语句在数据删除方面表现出色。本文将详细解析 PostgreSQL 的 DELETE 语句,包括其语法、使用场景和注意事项。 1. DELETE…

传统报警难题频现,安全运行隐患重重

在企业生产运营与安全管理过程中&#xff0c;报警系统作为保障安全运行的重要防线&#xff0c;其作用不言而喻。然而&#xff0c;传统报警系统在实际应用中却难题频现&#xff0c;不仅无法及时、准确地预警潜在风险&#xff0c;还为企业的安全运行埋下了重重隐患。青岛国瑞信息…

WPF学习笔记(23)Window、Page与Frame、ViewBox

Window、Page与Frame一、Window1.模态窗口与非模态窗口2.Window类3.示例二、Page1.概述2.Page类三、Frame1.概述2.Frame类3.示例四、ViewBox1. 概述2. 详解3. 示例总结一、Window 1.模态窗口与非模态窗口 2.Window类 属性说 明Title获取或设置窗口的标题。lcon设获取或设置窗…

设计模式---观察者模式(发布-订阅模式)

设计模式—观察者模式(发布-订阅模式) 一、简介 发布-订阅模式是一种消息传递模式&#xff0c;用于实现对象间的一对多依赖关系。在这种模式中&#xff1a; 发布者&#xff08;Publisher&#xff09;不直接向订阅者&#xff08;Subscriber&#xff09;发送消息发布者和订阅者…

一文讲清楚React Fiber

文章目录一文讲清楚React Fiber1. 基础概念1.1浏览器刷新率&#xff08;帧&#xff09;1.2 JS执行栈1.3 时间分片1.4 链表2. React Fiber是如何实现更新过程控制2.1 任务拆分2.2挂起、恢复、终止2.2.1 挂起2.2.2 恢复2.2.3 终止2.3 任务具备优先级一文讲清楚React Fiber 1. 基…

(3)机器学习小白入门 YOLOv: 解锁图片分类新技能

(1)机器学习小白入门YOLOv &#xff1a;从概念到实践 (2)机器学习小白入门 YOLOv&#xff1a;从模块优化到工程部署 (3)机器学习小白入门 YOLOv&#xff1a; 解锁图片分类新技能 前言 YOLOv 算法通常被用于目标检测任务&#xff0c;但通过对其进行适当的调整和改造&#xff0c…

主机安全-开源HIDS字节跳动Elkeid使用

安装好elkeid后就开始接入主机和k8s集群&#xff0c;安装文档-----主机安全-开源HIDS字节跳动Elkeid安装-CSDN博客 1、接入主机 在系统管理-----安装配置-----复制命令------在目标机器上执行这段命令 执行成功后主机就会自动接入 2、接入k8s集群 在k8s主机上执行脚本&#x…

【vue】用conda配置nodejs,一键开通模版使用权

特此鸣谢我的好同学重中之重的特级教学&#xff0c;非常之好用一、conda环境下载安装二、创建包含nodejs的conda环境创建一个新环境&#xff1a;conda create -n 【自定义环境名字】 python3.9 conda create -n my_nodejs_env python3.9激活新环境&#xff1a;conda activate【…

深度学习--tensor(创建、属性)

一、torch概念1.1简介pytorch简称torch&#xff0c;意为深度学习框架。它使用张量&#xff08;tensor&#xff09;来表示数据&#xff0c;可以轻松地处理大规模数据集&#xff0c;且可以在GPU上加速。pytorch基本功能&#xff1a;自动微分、自动求导等。1.2安装官网获得下载命令…

【内存】Linux 内核优化实战 - net.ipv4.tcp_max_tw_buckets

目录net.ipv4.tcp_max_tw_buckets 详解一、基本概念二、核心作用三、默认值四、调整场景需增大参数的场景需减小参数的场景五、查看与修改方法1. 查看当前值2. 临时修改&#xff08;重启失效&#xff09;3. 永久修改&#xff08;重启生效&#xff09;六、注意事项总结net.ipv4.…