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

工程化与框架系列(28)--前端国际化实现

前端国际化实现 🌍

引言

前端国际化(i18n)是现代Web应用中的重要组成部分,它能够让应用支持多语言和多地区的用户使用。本文将深入探讨前端国际化的实现方案和最佳实践,包括文本翻译、日期时间格式化、货币处理等方面。

国际化概述

前端国际化主要包括以下方面:

  • 文本翻译:界面文字的多语言支持
  • 日期时间:不同地区的日期时间格式
  • 货币处理:不同地区的货币格式
  • 数字格式:不同地区的数字表示方式
  • 文字方向:从左到右(LTR)和从右到左(RTL)的布局支持

国际化工具实现

国际化管理器

// 国际化管理器类
class I18nManager {private static instance: I18nManager;private currentLocale: string;private messages: Map<string, Record<string, string>>;private numberFormatter: Intl.NumberFormat;private dateFormatter: Intl.DateTimeFormat;private currencyFormatter: Intl.NumberFormat;private constructor() {this.currentLocale = 'en-US';this.messages = new Map();// 初始化格式化器this.numberFormatter = new Intl.NumberFormat(this.currentLocale);this.dateFormatter = new Intl.DateTimeFormat(this.currentLocale);this.currencyFormatter = new Intl.NumberFormat(this.currentLocale, {style: 'currency',currency: 'USD'});// 初始化事件分发this.initializeEventDispatcher();}// 获取单例实例static getInstance(): I18nManager {if (!I18nManager.instance) {I18nManager.instance = new I18nManager();}return I18nManager.instance;}// 设置语言环境setLocale(locale: string): void {this.currentLocale = locale;// 更新格式化器this.numberFormatter = new Intl.NumberFormat(locale);this.dateFormatter = new Intl.DateTimeFormat(locale);this.currencyFormatter = new Intl.NumberFormat(locale, {style: 'currency',currency: this.getCurrencyCode(locale)});// 触发语言变更事件this.dispatchLocaleChange();}// 获取当前语言环境getLocale(): string {return this.currentLocale;}// 加载语言包loadMessages(locale: string, messages: Record<string, string>): void {this.messages.set(locale, messages);}// 获取翻译文本translate(key: string, params?: Record<string, any>): string {const messages = this.messages.get(this.currentLocale);if (!messages) {return key;}let text = messages[key] || key;// 替换参数if (params) {Object.entries(params).forEach(([key, value]) => {text = text.replace(`{${key}}`, String(value));});}return text;}// 格式化数字formatNumber(value: number): string {return this.numberFormatter.format(value);}// 格式化日期formatDate(date: Date, options?: Intl.DateTimeFormatOptions): string {if (options) {return new Intl.DateTimeFormat(this.currentLocale, options).format(date);}return this.dateFormatter.format(date);}// 格式化货币formatCurrency(value: number): string {return this.currencyFormatter.format(value);}// 获取文字方向getTextDirection(): 'ltr' | 'rtl' {return ['ar', 'he'].includes(this.currentLocale.split('-')[0])? 'rtl': 'ltr';}// 初始化事件分发private initializeEventDispatcher(): void {document.addEventListener('DOMContentLoaded', () => {this.updateDocumentDirection();});}// 更新文档方向private updateDocumentDirection(): void {document.documentElement.dir = this.getTextDirection();document.documentElement.lang = this.currentLocale;}// 触发语言变更事件private dispatchLocaleChange(): void {const event = new CustomEvent('localechange', {detail: { locale: this.currentLocale }});document.dispatchEvent(event);// 更新文档方向this.updateDocumentDirection();}// 获取货币代码private getCurrencyCode(locale: string): string {const region = locale.split('-')[1] || 'US';const currencyMap: Record<string, string> = {'US': 'USD','GB': 'GBP','EU': 'EUR','CN': 'CNY','JP': 'JPY'// 添加更多货币映射};return currencyMap[region] || 'USD';}
}// 使用示例
const i18n = I18nManager.getInstance();// 加载英文语言包
i18n.loadMessages('en-US', {'greeting': 'Hello, {name}!','farewell': 'Goodbye!','items_count': 'You have {count} items.'
});// 加载中文语言包
i18n.loadMessages('zh-CN', {'greeting': '你好,{name}!','farewell': '再见!','items_count': '你有 {count} 个物品。'
});// 切换语言
i18n.setLocale('zh-CN');// 使用翻译
console.log(i18n.translate('greeting', { name: 'John' })); // 输出:你好,John!
console.log(i18n.translate('items_count', { count: 5 })); // 输出:你有 5 个物品。// 格式化数字和日期
console.log(i18n.formatNumber(1234567.89)); // 输出:1,234,567.89
console.log(i18n.formatDate(new Date())); // 输出:2024/2/20
console.log(i18n.formatCurrency(99.99)); // 输出:¥99.99

组件国际化

// 国际化组件装饰器
function withI18n<T extends { new (...args: any[]): any }>(Component: T
) {return class extends Component {private i18n: I18nManager;private localeChangeHandler: () => void;constructor(...args: any[]) {super(...args);this.i18n = I18nManager.getInstance();this.localeChangeHandler = this.onLocaleChange.bind(this);// 监听语言变更事件document.addEventListener('localechange', this.localeChangeHandler);}// 组件销毁时移除事件监听disconnectedCallback() {document.removeEventListener('localechange', this.localeChangeHandler);if (super.disconnectedCallback) {super.disconnectedCallback();}}// 语言变更处理private onLocaleChange(): void {this.requestUpdate();}// 翻译辅助方法protected t(key: string, params?: Record<string, any>): string {return this.i18n.translate(key, params);}// 格式化数字protected formatNumber(value: number): string {return this.i18n.formatNumber(value);}// 格式化日期protected formatDate(date: Date): string {return this.i18n.formatDate(date);}// 格式化货币protected formatCurrency(value: number): string {return this.i18n.formatCurrency(value);}};
}// 国际化文本组件
@withI18n
class I18nText extends HTMLElement {private key: string;private params: Record<string, any>;constructor() {super();this.key = '';this.params = {};}// 观察的属性static get observedAttributes() {return ['key', 'params'];}// 属性变化处理attributeChangedCallback(name: string,oldValue: string,newValue: string) {if (name === 'key') {this.key = newValue;} else if (name === 'params') {try {this.params = JSON.parse(newValue);} catch (e) {this.params = {};}}this.updateContent();}// 更新内容private updateContent(): void {this.textContent = this.t(this.key, this.params);}
}// 注册组件
customElements.define('i18n-text', I18nText);// 国际化日期组件
@withI18n
class I18nDate extends HTMLElement {private date: Date;private format: Intl.DateTimeFormatOptions;constructor() {super();this.date = new Date();this.format = {};}// 观察的属性static get observedAttributes() {return ['value', 'format'];}// 属性变化处理attributeChangedCallback(name: string,oldValue: string,newValue: string) {if (name === 'value') {this.date = new Date(newValue);} else if (name === 'format') {try {this.format = JSON.parse(newValue);} catch (e) {this.format = {};}}this.updateContent();}// 更新内容private updateContent(): void {this.textContent = this.formatDate(this.date);}
}// 注册组件
customElements.define('i18n-date', I18nDate);// 使用示例
const template = `<div><i18n-text key="greeting" params='{"name":"John"}'></i18n-text><i18n-date value="2024-02-20"></i18n-date></div>
`;

路由国际化

// 国际化路由管理器
class I18nRouter {private static instance: I18nRouter;private i18n: I18nManager;private routes: Map<string, I18nRoute>;private currentRoute: I18nRoute | null;private constructor() {this.i18n = I18nManager.getInstance();this.routes = new Map();this.currentRoute = null;this.initializeRouter();}// 获取单例实例static getInstance(): I18nRouter {if (!I18nRouter.instance) {I18nRouter.instance = new I18nRouter();}return I18nRouter.instance;}// 注册路由registerRoute(route: I18nRoute): void {this.routes.set(route.name, route);}// 获取路由URLgetRouteUrl(name: string,params?: Record<string, string>): string {const route = this.routes.get(name);if (!route) {throw new Error(`Route "${name}" not found`);}const locale = this.i18n.getLocale();let path = route.paths[locale] || route.paths['en-US'];// 替换路径参数if (params) {Object.entries(params).forEach(([key, value]) => {path = path.replace(`:${key}`, value);});}return `/${locale}${path}`;}// 导航到路由navigate(name: string,params?: Record<string, string>): void {const url = this.getRouteUrl(name, params);window.history.pushState(null, '', url);this.handleRoute();}// 初始化路由器private initializeRouter(): void {// 监听popstate事件window.addEventListener('popstate', () => {this.handleRoute();});// 监听语言变更document.addEventListener('localechange', () => {this.updateRoute();});// 处理初始路由this.handleRoute();}// 处理路由private handleRoute(): void {const path = window.location.pathname;const [, locale, ...segments] = path.split('/');// 设置语言if (locale && locale !== this.i18n.getLocale()) {this.i18n.setLocale(locale);}// 查找匹配的路由const matchedRoute = this.findMatchingRoute(segments.join('/'));if (matchedRoute) {this.currentRoute = matchedRoute;this.renderRoute(matchedRoute);}}// 更新当前路由private updateRoute(): void {if (this.currentRoute) {const params = this.extractRouteParams();this.navigate(this.currentRoute.name, params);}}// 查找匹配的路由private findMatchingRoute(path: string): I18nRoute | null {const locale = this.i18n.getLocale();for (const route of this.routes.values()) {const routePath = route.paths[locale] || route.paths['en-US'];if (this.matchPath(path, routePath)) {return route;}}return null;}// 匹配路径private matchPath(path: string, pattern: string): boolean {const pathSegments = path.split('/');const patternSegments = pattern.split('/');if (pathSegments.length !== patternSegments.length) {return false;}return patternSegments.every((segment, index) => {if (segment.startsWith(':')) {return true;}return segment === pathSegments[index];});}// 提取路由参数private extractRouteParams(): Record<string, string> {if (!this.currentRoute) {return {};}const locale = this.i18n.getLocale();const routePath = this.currentRoute.paths[locale] || this.currentRoute.paths['en-US'];const currentPath = window.location.pathname.split('/').slice(2).join('/');const params: Record<string, string> = {};const pathSegments = currentPath.split('/');const patternSegments = routePath.split('/');patternSegments.forEach((segment, index) => {if (segment.startsWith(':')) {const paramName = segment.slice(1);params[paramName] = pathSegments[index];}});return params;}// 渲染路由private renderRoute(route: I18nRoute): void {const params = this.extractRouteParams();route.component.render(params);}
}// 路由配置接口
interface I18nRoute {name: string;paths: Record<string, string>;component: {render: (params: Record<string, string>) => void;};
}// 使用示例
const router = I18nRouter.getInstance();// 注册路由
router.registerRoute({name: 'home',paths: {'en-US': '/home','zh-CN': '/首页'},component: {render: () => {document.getElementById('app')!.innerHTML = `<h1><i18n-text key="home_title"></i18n-text></h1>`;}}
});router.registerRoute({name: 'product',paths: {'en-US': '/product/:id','zh-CN': '/产品/:id'},component: {render: (params) => {document.getElementById('app')!.innerHTML = `<h1><i18n-text key="product_title" params='{"id":"${params.id}"}'></i18n-text></h1>`;}}
});// 导航到路由
router.navigate('home');
router.navigate('product', { id: '123' });

最佳实践与建议

  1. 文本管理

    • 使用键值对管理文本
    • 支持参数替换
    • 处理复数形式
    • 维护翻译文档
  2. 格式处理

    • 使用Intl API
    • 处理时区问题
    • 支持不同数字系统
    • 考虑货币转换
  3. 布局适配

    • 支持RTL布局
    • 处理文本长度变化
    • 适配不同字体
    • 考虑文化差异
  4. 性能优化

    • 按需加载语言包
    • 缓存翻译结果
    • 优化重渲染
    • 减少格式化开销

总结

前端国际化需要考虑以下方面:

  1. 文本翻译管理
  2. 日期时间处理
  3. 货币数字格式化
  4. 布局方向适配
  5. 性能优化策略

通过合理的架构设计和优化措施,可以构建出优秀的国际化应用。

学习资源

  1. Intl API文档
  2. i18n最佳实践
  3. RTL布局指南
  4. 区域设置标准
  5. 国际化测试方法

如果你觉得这篇文章有帮助,欢迎点赞收藏,也期待在评论区看到你的想法和建议!👇

终身学习,共同成长。

咱们下一期见

💻

相关文章:

工程化与框架系列(28)--前端国际化实现

前端国际化实现 &#x1f30d; 引言 前端国际化&#xff08;i18n&#xff09;是现代Web应用中的重要组成部分&#xff0c;它能够让应用支持多语言和多地区的用户使用。本文将深入探讨前端国际化的实现方案和最佳实践&#xff0c;包括文本翻译、日期时间格式化、货币处理等方面…...

【阿里云】操作系统控制台操作体验与性能评测全解析

引言 在现代的云计算环境中&#xff0c;操作系统控制台是进行系统管理和运维的重要工具。它不仅帮助用户高效地管理云端资源&#xff0c;还提供了智能助手、系统诊断、性能观测等功能&#xff0c;能够提升操作系统的使用效率&#xff0c;增强用户的操作体验。本文简要介绍了操…...

面试之《IntersectionObserver的使用》

IntersectionObserver 是一个 Web API&#xff0c;用于异步观察目标元素与其祖先元素或顶级文档视口&#xff08;viewport&#xff09;交叉状态的变化。这在很多场景下非常有用&#xff0c;比如懒加载图片、实现无限滚动加载更多内容等。下面详细介绍它的使用方法。 基本原理 …...

在 Spring Boot 2.7.x 中引入 Kafka-0.9 的实践

文章目录 在 Spring Boot 2.7.x 中引入 Kafka-0.9 的实践一、下载 Kafka-0.9二、启动 Zookeeper 和 Kafka三、创建 Spring Boot 项目四、引入 kafka 依赖五、移除 Kafka 自动配置六、编写 Kafka 生产者6.1 Kafka配置类6.2 生产者监听类 七、编写Controller发送Kafka八、验证消费…...

【MACOS】用户数据过多

进入下面的路径下找到.Spotlight-V100文件夹 /System/Volumes/Data修改选线 通过终端权限不够 在finder中进行查看然后解锁 然后添加权限 使用代码查看存储数据。 diskutil apfs list...

鸿蒙系统中的持续部署

鸿蒙操作系统&#xff0c;作为一款面向未来的分布式操作系统&#xff0c;旨在为不同的设备提供统一的操作系统平台。它支持多种终端设备&#xff0c;包括但不限于智能手机、平板电脑、智能穿戴设备和物联网&#xff08;IoT&#xff09;设备等&#xff0c;并且能够实现跨平台的无…...

centos linux安装mysql8 重置密码 远程连接

1. 下载并安装 MySQL Yum 仓库 从 MySQL 官方网站下载并安装 Yum 仓库配置文件。 # 下载MySQL 8.0的Yum仓库包 wget https://dev.mysql.com/get/mysql80-community-release-el7-5.noarch.rpm # 安装Yum仓库包 sudo rpm -ivh mysql80-community-release-el7-5.noarch.rpm2. 启…...

几种常见的虚拟环境工具(Virtualenv、Conda、System Interpreter、Pipenv、Poetry)的区别和特点总结

在 PyCharm 中创建虚拟环境是一个非常直接的过程&#xff0c;可以帮助你管理项目依赖&#xff0c;确保不同项目之间的依赖不会冲突。 通过 PyCharm 创建虚拟环境 打开 PyCharm 并选择或创建一个项目。 打开项目设置&#xff1a; 在 Windows/Linux 上&#xff0c;可以通过点击…...

VScode:运行程序停止后,频繁出现终端进程被终止

VScode里面powershell被迫关闭 bug场景排查原因解决办法 bug场景 系统&#xff1a;Windows IDE&#xff1a;Visual Studio Code 停止运行程序后&#xff0c;按向上箭头想要执行上一步命令&#xff0c;忽然终端页面强行关闭&#xff0c;并报错如下&#xff1a; 终端进程 &quo…...

PHP框架加载不上.env文件中的变量

以lumen5.5框架为例&#xff0c;根目录中bootstrap文件夹下的app.php文件中 (new Dotenv\Dotenv(__DIR__./../))->load(); 是读取所有.env中的文件的&#xff0c;这个是正常的&#xff0c;但是在代码中的任何位置或者在config目录下的databases.php里&#xff0c;代码如…...

Linux:基本指令与内涵理解

1.文件操作指令 1.1 ls ls指令用于查看指定层级文件夹下的文件或文件夹 基本格式&#xff1a;ls (选项) (查看层级&#xff09; 其中选项处不写就默认是显示文件名&#xff0c;查看层级默认是当前层级 选项1&#xff1a; -l 作用&#xff1a;将查找文件的详细信息显示出来 我们…...

C++设计模式-抽象工厂模式:从原理、适用场景、使用方法,常见问题和解决方案深度解析

一、模式基本概念 1.1 定义与核心思想 抽象工厂模式&#xff08;Abstract Factory Pattern&#xff09;是创建型设计模式的集大成者&#xff0c;它通过提供统一的接口来创建多个相互关联或依赖的对象族&#xff0c;而无需指定具体类。其核心思想体现在两个维度&#xff1a; …...

LINUX系统安装+添加共享目录

一、前言 Windows或mac系统中创建Linux工作环境是基于VMware和SL(Scientific Linux)&#xff0c;下面分别安装二者。 二、VMware软件安装及注册 1、双击VMware安装包 2、点击下一步 3、 勾选接受许可&#xff0c;并点击下一步 4、更改路径&#xff08;建议更改为容易找到的路…...

《UE5_C++多人TPS完整教程》学习笔记34 ——《P35 网络角色(Network Role)》

本文为B站系列教学视频 《UE5_C多人TPS完整教程》 —— 《P35 网络角色&#xff08;Network Role&#xff09;》 的学习笔记&#xff0c;该系列教学视频为计算机工程师、程序员、游戏开发者、作家&#xff08;Engineer, Programmer, Game Developer, Author&#xff09; Stephe…...

成为git砖家(9): rebase进阶: 拆分commit为多个

问题描述 当一次性 git add 了多个修改点&#xff0c; 并且快速的执行了 git commit 后&#xff0c; 你觉得有点懊恼&#xff1a; 明明可以独立为两次或多次 commit&#xff0c; 揉在一块导致历史记录不太清晰。 比如我在 nn1 这个练手项目中&#xff0c; 最近一次 commit&am…...

pytorch retain_grad vs requires_grad

requires_grad大家都挺熟悉的&#xff0c;因此穿插在retain_grad的例子里进行捎带讲解就行。下面看一个代码片段&#xff1a; import torch# 创建一个标量 tensor&#xff0c;并开启梯度计算 x torch.tensor(2.0, requires_gradTrue)# 中间计算&#xff1a;y 依赖于 x&#x…...

Axure常用变量及使用方法详解

点击下载《Axure常用变量及使用方法详解.pdf》 摘要 Axure RP 作为一款领先的前端原型设计工具&#xff0c;提供了全面的 变量 和 函数 系统&#xff0c;以支持复杂的交互设计和动态内容展示。本文将从专业角度详细解析 Axure 中的 全局变量、中继器数据集变量/函数、元件变量…...

为企业级AI交互系统OpenWebUI集成LDAP用户权限认证(2)

为企业级AI交互系统OpenWebUI集成LDAP用户权限认证(2) 本文介绍如何OpenWebUI系统集成LDAP认证服务,及其用户权限及用户组设置。 推荐超级课程: 本地离线DeepSeek AI方案部署实战教程【完全版】Docker快速入门到精通Kubernetes入门到大师通关课AWS云服务快速入门实战目录…...

mac 被禁用docker ui后,如何使用lima虚拟机启动docker

本机macos 安装lima brew install lima创建配置 echo "\\ndynamic:\n big-sur:\n image: docker://docker:git\n linux:\n image: docker.io/limasoftware/ubuntu:20.04 \\n" > ~/.lima/default.yaml启动名叫default的虚拟机 limactl start default进…...

C#实现AES-CBC加密工具类(含完整源码及使用教程)

一、AES-CBC加密应用场景 AES&#xff08;Advanced Encryption Standard&#xff09;作为全球公认的安全加密标准&#xff0c;广泛使用在以下场景&#xff1a; API通信加密&#xff1a;保护HTTP接口传输的敏感数据&#xff08;如身份令牌、支付信息&#xff09;文件安全存储&…...

Unity辅助工具_头部与svn

Unity调用者按钮增加PlaySideButton using QQu; using UnityEditor; using UnityEngine; [InitializeOnLoad] public class PlaySideButton {static PlaySideButton(){UnityEditorToolbar.RightToolbarGUI.Add(OnRightToolbarGUI);UnityEditorToolbar.LeftToolbarGUI.Add(OnLe…...

VBA 数据库同一表的当前行与其他行的主键重复判断实现方案1

目的&#xff0c;判断是否主键重复&#xff0c;不重复则登录新数据&#xff0c;重复则不登录。 定义类型&#xff1a; DataRecord   tableName 表名   rowNumber 行号   columnName 列名   data 数据 想要实现的代码逻辑如下&#xff1a; 模拟数据库的登录过程。假设…...

Pytorch系列教程:可视化Pytorch模型训练过程

深度学习和理解训练过程中的学习和进步机制对于优化性能、诊断欠拟合或过拟合等问题至关重要。将训练过程可视化的过程为学习的动态提供了有价值的见解&#xff0c;使我们能够做出合理的决策。训练进度必须可视化的两种方法是&#xff1a;使用Matplotlib和Tensor Board。在本文…...

CSS伸缩盒模型(弹性盒子)

伸缩盒模型&#xff08;Flexbox&#xff0c;Flexible Box Layout&#xff09;是 CSS 中一种一维布局模型&#xff0c;用于更高效地处理元素的对齐、分布和响应式布局。其核心思想是让容器内的子元素&#xff08;称为“项目”&#xff09;能够灵活地自动调整大小和位置以适应不同…...

C++蓝桥杯基础篇(十一)

片头 嗨~小伙伴们&#xff0c;大家好&#xff01;今天我们来学习C蓝桥杯基础篇&#xff08;十一&#xff09;&#xff0c;学习类&#xff0c;结构体&#xff0c;指针相关知识&#xff0c;准备好了吗&#xff1f;咱们开始咯~ 一、类与结构体 类的定义&#xff1a;在C中&#x…...

版本控制泄露源码 .svn

##相关知识 SVN源码泄露 SVN&#xff08;subversion&#xff09;是源代码版本管理软件&#xff0c;造成 SVN 源代码漏洞的主要原因是管理员操作不规范。“ 在使用 SVN 管理本地代码过程中&#xff0c;会自动生成一个名为 .svn 的隐藏文件夹&#xff0c;其中包含重要的源代码信…...

基于单片机的风速报警装置设计

标题:基于单片机的风速报警装置设计 内容:1.摘要 本设计聚焦于基于单片机的风速报警装置&#xff0c;旨在解决传统风速监测缺乏实时报警功能的问题。采用单片机作为核心控制单元&#xff0c;结合风速传感器采集风速数据。经实验测试&#xff0c;该装置能准确测量 0 - 60m/s 范…...

YOLOv12本地部署教程——42%速度提升,让高效目标检测触手可及

YOLOv12 是“你只看一次”&#xff08;You Only Look Once, YOLO&#xff09;系列的最新版本&#xff0c;于 2025 年 2 月发布。它引入了注意力机制&#xff0c;提升了检测精度&#xff0c;同时保持了高效的实时性能。在保持速度的同时&#xff0c;显著提升了检测精度。例如&am…...

Banana Pi OpenWRT One Wifi6 OpenWrt社区官方开源路由器评测

第一款不可破解、开源、版权软件、符合 FCC、CE 和 RoHS 的维修权路由器 OpenWRT项目今年已经20岁了&#xff0c;为了纪念这一时刻&#xff0c;Banana Pi OpenWrt One/AP-24.XY路由器开发系统已经上市。这是OpenWRT团队与硬件公司的第一个联合项目。选择 Banana Pi&#xff0c;…...

【算法】经典排序算法介绍+代码示例

排序算法介绍 1&#xff09;冒泡排序 (Bubble Sort)2&#xff09;选择排序&#xff08;Selection Sort&#xff09;3&#xff09;插入排序&#xff08;Insertion Sort&#xff09;4&#xff09;希尔排序&#xff08;Shell Sort&#xff09;5&#xff09;归并排序&#xff08;Me…...

DeepSeek 助力 Vue3 开发:打造丝滑的表格(Table)之添加列宽调整功能,示例Table14_02带边框和斑马纹的固定表头表格

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 Deep…...

【Linux】线程控制

目录 一、原生线程库&#xff1a; 二、线程控制&#xff1a; 1、线程创建&#xff1a; 2、线程等待&#xff1a; 自定义类型的接收对象&#xff1a; ​编辑 3、线程终止&#xff1a; pthread_exit&#xff1a; pthread_cancel: 4、线程ID&#xff1a; 线程库的底层原…...

pyqt联合designer的运用和设置

PyQt Designer 简介 PyQt Designer 是一个用于创建和设计 PyQt 应用程序用户界面的可视化工具。它允许用户通过拖放方式添加和排列各种控件,如按钮、文本框、滑块等,并设置它们的属性和样式,从而快速构建出美观且功能完整的 UI 界面。 Windows版本:【免费】安装包别管啊啊…...

spring boot3.4.3+MybatisPlus3.5.5+swagger-ui2.7.0

使用 MyBatis-Plus 操作 books 表。我们将实现以下功能&#xff1a; 创建实体类 Book。 创建 Mapper 接口 BookMapper。 创建 Service 层 BookService 和 BookServiceImpl。 创建 Controller 层 BookController。 配置 MyBatis-Plus 和数据库连接。 1. 项目结构 src ├─…...

利用微软的 HTML 应用程序宿主程序的攻击

mshta.exe 是微软的 HTML 应用程序宿主程序&#xff08;Microsoft HTML Application Host&#xff09;&#xff0c;属于 Windows 系统组件。它的核心功能是运行 .hta&#xff08;HTML Application&#xff09;文件&#xff0c;允许通过 HTML、JavaScript、VBScript 等技术创建交…...

【深度学习】读写文件

读写文件 到目前为止&#xff0c;我们讨论了如何处理数据&#xff0c;以及如何构建、训练和测试深度学习模型。 然而&#xff0c;有时我们希望保存训练的模型&#xff0c;以备将来在各种环境中使用&#xff08;比如在部署中进行预测&#xff09;。 此外&#xff0c;当运行一个…...

Bert的使用

一、Data.py # data负责产生两个dataloader from torch.utils.data import DataLoader, Dataset from sklearn.model_selection import train_test_split #给X,Y 和分割比例&#xff0c; 分割出来一个训练集和验证机的X, Y import torchdef read_file(path):data []label …...

Unity使用UGUI制作无限滑动列表

原理参照上一篇使用NGUI的制作无限滑动列表的文章 Unity 使用NGUI制作无限滑动列表_unity 滑动列表很多物体-CSDN博客 准备工作&#xff1a; 新建一个空物体命名为LoopList&#xff0c;并调整其大小&#xff0c; 并增加Scroll Rect组件&#xff08;用于滑动&#xff09;、Re…...

ThinkPHP6用户登录系统的全过程

ThinkPHP6用户登录系统的全过程涉及请求处理、数据传输、路由分发、控制器逻辑、模型验证及中间件协作等多个模块的交互。详细的过程解析如下&#xff1a; 1. 前端请求与路由分发 前端发起请求&#xff1a;用户在前端页面&#xff08;如Vue组件或HTML表单&#xff09;输入用户…...

C++全栈聊天项目(2) 单例模式封装Http管理者

完善注册类界面 先在注册类构造函数里添加lineEdit的模式为密码模式 ui->lineEdit_Passwd->setEchoMode(QLineEdit::Password); ui->lineEdit_Confirm->setEchoMode(QLineEdit::Password);我们在注册界面的ui里添加一个widget&#xff0c;widget内部包含一个tip居…...

【鸿蒙开发】OpenHarmony调测工具hdc使用教程(设备开发者)

00. 目录 文章目录 00. 目录01. OpenHarmony概述02. hdc简介03. hdc获取04. option相关的命令05. 查询设备列表的命令06. 服务进程相关命令07. 网络相关的命令08. 文件相关的命令09. 应用相关的命令10. 调试相关的命令11. 常见问题12. 附录 01. OpenHarmony概述 OpenHarmony是…...

ORACLE EBS数据库RELINK方式搭建克隆环境

ORACLE EBS系统的数据库&#xff0c;一般都安装了很多特定功能的小补丁来解决特定的BUG&#xff1b;因此对于已经安装好的系统&#xff0c;想要克隆一套测试环境、搭建一个新的备机做测试等&#xff0c;如果按照生产环境标准&#xff0c;则需要安装大量补丁&#xff0c;带来很大…...

MySQL regexp 命令

REGEXP命令是一种用于进行正则表达式匹配的运算符&#xff0c;允许在查询中使用正则表达式来匹配字符串模式‌‌1。 基本语法 基本的语法结构如下&#xff1a; SELECT * FROM table_name WHERE column_name REGEXP pattern; 这里&#xff0c;pattern是你要匹配的正则表达式模…...

前端实习到工作的经历

看了很多人的程序员生涯之路&#xff0c;我突然意识到我也该记录一些东西&#xff0c;因此有感而发。 我是一个24届毕业生&#xff0c;大三下就开始找前端实习&#xff0c;当时学校不让走&#xff0c;我们都是先面着然后准备放假就去。当时周围小伙伴都找好了&#xff0c;考完…...

Vue3——Fragment

文章目录 一、Fragment的核心意义1. 解决Vue2的单根限制问题2. 减少不必要的 DOM 嵌套3. 语义化和结构化 二、Fragment 的实现原理三、Fragment 使用方式1. 基本用法2. 结合条件渲染3. 动态组件 四、实际应用场景1. 列表/表格组件2. 布局组件3. 语义化标签 五、注意事项1. 属性…...

Linux_16进程地址空间

CPU内的寄存器只有一套&#xff0c;但是CPU内寄存器的数据可能会有多份&#xff01; 一、程序地址空间 下面这个图对应的是内存吗&#xff1f;&#xff08;实际上是虚拟的进程地址空间&#xff09; 32位机器内存最大为多少&#xff1f; 32位操作系统的地址总线为32位&#x…...

职坐标机器学习编程实战:调试优化与自动化测试精要

内容概要 在机器学习编程实践中&#xff0c;代码调试优化与自动化测试工具的应用是构建高可靠性系统的核心环节。本书聚焦从数据预处理到模型部署的全流程&#xff0c;通过特征工程优化、训练过程监控及持续集成方案的设计&#xff0c;系统化解决算法工程化中的典型问题。在特…...

git文件过大导致gitea仓库镜像推送失败问题解决(push failed: context deadline exceeded)

问题描述&#xff1a; 今天发现gitea仓库推送到某个镜像仓库的操作几个月前已经报错终止推送了&#xff0c;报错如下&#xff1a; 首先翻译报错提示可知是因为git仓库大小超过1G限制。检查本地.git文件&#xff0c;发现.git文件大小已达到1.13G。确定是.git文件过大导致&…...

llvm数据流分析

llvm数据流分析 1.数据流分析2.LLVM实现2.1.常量传播2.2.活跃性分析 相关参考文档&#xff1a;DataFlowAnalysisIntro、ustc编译原理课程、南大程序分析课程1、南大程序分析课程2。 1.数据流分析 数据流分析在编译优化等程序分析任务上都有重要应用。通常数据流分析可被抽象为…...

Vite为什么选用Rollup打包?

Vite 在生产阶段使用 Rollup 打包&#xff0c;但这不是唯一选择。它的设计背后有明确的权衡和考量&#xff0c;同时开发者也可以选择其他替代方案。 一、为什么 Vite 默认使用 Rollup&#xff1f; 1. Rollup 的核心优势 • Tree-shaking&#xff1a;Rollup 的静态分析能力极强&…...