当我谈 Rax 按端拆分代码的时候我谈些什么:代码规范相关

news2026/3/27 2:40:46
前言在跨端开发领域Rax 作为一个备受关注的框架凭借其“一次编写多端运行”的理念为开发者带来了巨大的效率提升。然而随着业务规模的扩大和终端形态的多样化Web、Weex、小程序、Node 等如何优雅地管理不同端的代码差异成为摆在团队面前的一道必答题。“按端拆分代码”不只是一个技术手段更是一套贯穿开发全流程的工程规范。本文将从代码规范的角度出发详细探讨在 Rax 项目中如何系统化地拆分、组织、维护多端代码帮助团队在保证开发效率的同时兼顾代码的可读性、可维护性和可扩展性。第一章为什么需要按端拆分代码1.1 Rax 的跨端能力与挑战Rax 是阿里巴巴开源的一套跨端解决方案它提供了一套与 React 兼容的 API使得开发者可以用组件化的方式编写应用并通过不同的渲染引擎将同一份代码渲染到 Web、Weex、阿里小程序、微信小程序等多个平台上。这种“写一次跑多处”的理想很丰满但现实往往存在诸多差异渲染引擎差异Web 端基于 DOM/CSSOMWeex 使用原生渲染小程序则是 WebView 与原生混合。API 能力差异不同端提供的原生能力如路由、存储、网络接口不同。样式支持差异CSS 属性在各端支持程度不同例如 Weex 只支持 Flexbox 布局且部分属性有差异。生命周期差异不同端的页面生命周期、组件生命周期存在细微差别。性能特性差异Web 端可以充分利用浏览器缓存而小程序对代码包大小有严格限制。如果不对这些差异做有效管理代码中就会充斥着if (isWeb) ... else if (isWeex) ...这样的条件分支导致代码难以阅读和维护。因此按端拆分代码成为必然选择。1.2 按端拆分的价值清晰度将不同端的实现物理隔离使得开发者一眼就能看出某个模块在各端的行为。可维护性修改某一端的逻辑时只需关注对应的文件不会意外影响其他端。构建优化在打包时可以只打包当前端所需的代码从而减小包体积。团队协作不同端的开发者可以并行工作减少代码冲突。测试效率可以针对不同端编写独立的测试用例降低测试复杂度。第二章代码拆分的基本原则在制定具体规范之前我们需要先明确几个核心原则它们将指导我们如何设计目录结构、如何划分模块、如何选择技术方案。2.1 DRYDon‘t Repeat Yourself原则DRY 原则要求尽量减少重复代码。在按端拆分的场景中我们应当将跨端通用的逻辑、组件、工具函数抽取出来放在公共目录中避免在每个端目录下重复实现。只有那些真正依赖特定端能力的部分才进行拆分。2.2 单一职责原则每个模块文件、组件、函数应当只有一个职责。对于按端拆分的代码一个文件要么是纯通用的要么是特定于某个端的不要混合。例如一个组件文件如果同时包含 Web 和 Weex 的实现那么这个文件就承担了两种职责违背了单一职责。2.3 平台抽象层Platform Abstraction Layer构建一个统一的平台抽象层封装不同端的 API 差异。业务代码通过这个抽象层调用能力而不是直接使用各端原生 API。抽象层内部按端拆分实现对外暴露统一接口。这是降低耦合、提升可维护性的关键。2.4 编译时优于运行时由于运行时的环境判断如if (process.env.RAX_END web)会增加代码体积并且无法被 tree-shaking 完全优化因此优先使用编译时技术如文件后缀区分、构建宏来隔离不同端的代码。这样可以在构建阶段就剔除无关端的代码确保最终产物干净。2.5 渐进式拆分不要一开始就追求完美的拆分。随着业务的发展当某个模块在不同端的差异逐渐增大时再进行拆分。过早的拆分可能导致过度设计增加维护成本。第三章目录结构规范合理的目录结构是代码规范的基础。Rax 项目通常使用rax-app脚手架创建其默认结构如下textmy-app/ ├── src/ │ ├── app.js # 应用入口 │ ├── app.json # 应用配置 │ ├── pages/ # 页面目录 │ │ └── Home/ │ │ ├── index.js │ │ └── index.css │ └── components/ # 公共组件 ├── build/ # 构建输出 ├── public/ # 静态资源 ├── package.json └── ...为了支持按端拆分我们需要对上述结构进行扩展。以下是推荐的多端目录结构规范。3.1 按平台分目录推荐将不同端的代码放在独立的顶级目录下通用代码放在common或根目录下。例如textsrc/ ├── common/ # 通用代码所有端共享 │ ├── components/ # 通用组件 │ ├── utils/ # 通用工具函数 │ ├── services/ # 通用服务API 调用等 │ └── constants/ # 常量定义 ├── web/ # Web 端特有代码 │ ├── components/ # Web 端专用组件 │ ├── pages/ # Web 端专用页面或覆盖通用页面 │ ├── utils/ # Web 端专用工具 │ └── index.js # Web 端入口可选 ├── weex/ # Weex 端特有代码 │ ├── components/ │ ├── pages/ │ └── ... ├── miniapp/ # 小程序端特有代码阿里小程序、微信小程序等 │ ├── components/ │ ├── pages/ │ └── ... └── node/ # Node 端SSR特有代码 ├── components/ └── ...优点物理隔离清晰构建时只需指定入口目录。缺点如果页面较多可能会产生大量重复的页面骨架但可以通过继承或组合方式复用。3.2 按功能/模块内拆分另一种常见的做法是在功能模块内部使用文件后缀来区分不同端的实现。例如textsrc/ ├── components/ │ ├── Button/ │ │ ├── index.js # 通用入口根据环境引入对应实现 │ │ ├── index.web.js │ │ ├── index.weex.js │ │ └── index.miniapp.js │ └── ... ├── pages/ │ └── Home/ │ ├── index.js │ ├── index.web.js │ └── index.weex.js └── ...这种结构更加贴近组件化思想每个组件自包含不同端的实现文件放在同一目录下通过构建工具根据目标平台选择正确的文件。优点组件内聚性高便于维护。缺点如果平台数量多组件目录下文件会变多。3.3 混合结构在实际项目中可以结合上述两种方式对于通用的、与平台无关的代码放在common目录对于核心组件使用后缀方式拆分对于整个页面或模块使用按平台分目录的方式。建议团队在项目初期就明确采用哪种模式并写入规范文档。第四章文件命名规范文件命名是代码可读性的重要一环。在按端拆分时我们需要有一套统一的后缀约定。4.1 平台后缀约定Rax 生态中通常使用以下后缀来标识不同端的文件.web.js/.web.jsx/.web.tsxWeb 端.weex.js/.weex.jsx/.weex.tsxWeex 端.miniapp.js/.miniapp.jsx/.miniapp.tsx阿里小程序也可用.aliapp.js.wx.js/.wx.jsx微信小程序如果使用统一构建工具可能需要区分.node.jsNode.js 端SSR.common.js通用可选但通常不需要显式标注因为默认就是通用需要注意的是有些构建工具如 Webpack会根据文件后缀自动解析因此在使用import时可以省略后缀构建工具会自动尝试添加后缀并选择匹配的版本。例如javascript// 引入 Button 组件构建工具会根据当前目标平台自动加载 Button.web.js 或 Button.weex.js import Button from ./components/Button;4.2 目录与文件命名风格组件目录使用大驼峰PascalCase如Button/、UserCard/。页面目录同样使用大驼峰如Home/、Profile/。工具函数文件使用小驼峰camelCase或短横线kebab-case如formatDate.js、request.js。常量文件使用大写加下划线如API_URLS.js但实际内容导出对象时也可以用小驼峰命名风格统一即可。4.3 入口文件约定每个模块组件、页面的入口文件统一命名为index.js或index.ts然后在入口文件中根据环境引入对应的实现。例如javascript// components/Button/index.js let Button; if (process.env.RAX_END web) { Button require(./index.web).default; } else if (process.env.RAX_END weex) { Button require(./index.weex).default; } else { Button require(./index.miniapp).default; } export default Button;或者更优雅地利用构建工具的 resolve 规则直接import Button from ./Button然后配置 webpack 的resolve.extensions优先级使得不同端优先匹配对应后缀的文件。这将在第六章详细说明。第五章代码实现规范5.1 组件拆分规范5.1.1 公共组件与平台组件将组件分为三类通用组件完全与平台无关只依赖 Rax 核心 API如createElement、useState等。这类组件放在common/components中所有端直接复用。平台适配组件核心逻辑通用但渲染或交互存在平台差异。这类组件使用单一入口内部通过条件判断或文件后缀拆分实现细节。平台专用组件完全为某一端定制例如 Web 端使用div、span等原生标签而 Weex 端必须使用text、image等组件。这类组件放在对应平台的目录下不暴露给其他端使用。5.1.2 组件实现示例通用组件示例common/components/Loading/index.jsjsximport { createElement, useState, useEffect } from rax; export default function Loading({ text 加载中... }) { return div classNameloading{text}/div; }平台适配组件示例components/Image/index.js作为入口jsx// components/Image/index.js import { createElement } from rax; // 运行时判断不推荐仅作示例 let ImageComponent; if (typeof window ! undefined window.document) { ImageComponent require(./index.web).default; } else if (typeof weex ! undefined) { ImageComponent require(./index.weex).default; } else { ImageComponent require(./index.miniapp).default; } export default ImageComponent;更好的做法是依赖构建工具我们稍后会介绍。5.2 样式处理规范不同端的样式差异是跨端开发中最棘手的问题之一。Rax 提供了createStyle方法但底层实现不同端各异。5.2.1 样式文件拆分原则通用样式放在common/styles或组件同目录的index.css文件中。平台特定样式如果某个组件在不同端的样式差异较大可以为该组件创建多个样式文件如index.web.css、index.weex.css并在组件中按端引入。5.2.2 使用 CSS Modules 还是全局样式建议使用 CSS Modules 来避免样式冲突。在 Rax 项目中可以通过配置 webpack 的 css-loader 开启 modules 模式。组件内使用示例jsximport { createElement } from rax; import styles from ./index.css; export default function Card({ title }) { return div className{styles.card} h2 className{styles.title}{title}/h2 /div; }5.2.3 处理平台样式差异对于需要平台特定样式的组件可以采用以下两种方式不同端使用不同的样式文件textCard/ ├── index.js ├── index.web.css ├── index.weex.css └── index.miniapp.css在组件中根据环境动态引入jsximport { createElement } from rax; let styles; if (process.env.RAX_END web) { styles require(./index.web.css); } else if (process.env.RAX_END weex) { styles require(./index.weex.css); } else { styles require(./index.miniapp.css); }使用内联样式对于差异较小的场景可以使用内联样式并在组件内部根据端进行微调。但内联样式不利于维护不推荐大量使用。5.2.4 样式属性兼容性在编写样式时需要查阅各端支持的 CSS 属性清单。例如Weex 仅支持 flexbox 布局不支持position: fixed有特殊实现、z-index等。小程序对某些属性有前缀要求如-webkit-。Web 端最自由但也要考虑不同浏览器。建议团队维护一份《跨端样式兼容性手册》常见样式写法统一规定。5.3 API 调用规范Rax 本身提供了一些跨端 API如Storage、Router等但实际项目中往往需要调用各端特有的能力如支付宝支付、微信登录等。为此我们需要封装一个统一的平台服务层。5.3.1 定义统一的 API 接口在common/services中定义抽象接口javascript// common/services/storage.js export const storage { get(key) { throw new Error(Not implemented); }, set(key, value) { throw new Error(Not implemented); }, remove(key) { throw new Error(Not implemented); }, };5.3.2 各端实现具体逻辑在对应平台目录下实现javascript// web/services/storage.js export const storage { get(key) { return localStorage.getItem(key); }, set(key, value) { localStorage.setItem(key, value); }, remove(key) { localStorage.removeItem(key); }, };javascript// weex/services/storage.js import { storage as weexStorage } from weex-module/storage; export const storage { get(key) { return new Promise((resolve, reject) { weexStorage.getItem(key, resolve, reject); }); }, // ... };5.3.3 在业务代码中使用业务代码通过统一入口引入不感知底层实现javascriptimport { storage } from /common/services/storage; storage.set(token, xxx);在构建时通过 webpack 的 resolve.alias 或类似机制将/common/services/storage映射到对应平台的实际文件。这样运行时无任何判断代码干净。5.4 业务逻辑中的平台判断有些场景下我们无法通过抽象层完全消除平台判断比如某个功能的流程在不同端差异巨大。这时可以采用以下策略将不同端的逻辑拆分成独立的函数/模块避免在同一个函数内写大量if语句。使用策略模式定义一个策略对象根据平台选择不同的执行函数。示例javascript// common/utils/platform.js export const platform process.env.RAX_END; // web, weex, miniapp 等 // 业务代码 import { platform } from /common/utils/platform; import { webLogin, weexLogin, miniappLogin } from ./loginStrategies; const loginStrategies { web: webLogin, weex: weexLogin, miniapp: miniappLogin, }; export function login() { const strategy loginStrategies[platform]; if (strategy) { return strategy(); } throw new Error(Unsupported platform: ${platform}); }这样即便有多个平台业务代码也保持简洁。5.5 条件编译宏编译时优化为了彻底剔除不相关平台的代码我们可以使用构建时的宏替换。例如使用babel-plugin-transform-define或webpack.DefinePlugin定义全局常量然后在代码中通过if (__PLATFORM__ web)来编写条件分支构建时对不满足条件的分支进行 dead code elimination。Rax 项目通常已经内置了process.env.RAX_END这个变量我们可以在代码中使用它并且在构建时如使用 webpack 的 terser 插件会移除死代码。示例jsximport { createElement } from rax; export default function PlatformSpecific() { if (process.env.RAX_END web) { return divWeb Only/div; } else if (process.env.RAX_END weex) { return textWeex Only/text; } return null; }经过构建后只有当前平台的代码会保留。这种方式简单直接适合小范围的条件分支。但对于大型组件还是建议拆分为独立文件。第六章构建工具配置规范合理的构建配置是实现按端拆分的基石。Rax 项目通常使用rax-app基于 icejs或自己搭建的 webpack 配置。本节介绍如何通过配置实现文件后缀自动匹配、别名映射、多端打包等。6.1 文件后缀解析配置在 webpack 中通过配置resolve.extensions可以控制模块解析时的文件后缀优先级。为了支持按端拆分我们通常将平台相关的后缀放在前面这样当存在index.web.js和index.js时会优先加载index.web.js。示例配置webpack.config.js 片段javascriptmodule.exports { resolve: { extensions: [.web.js, .weex.js, .miniapp.js, .js, .jsx, .json], // 注意顺序很重要越靠前优先级越高 }, };然后在构建 Web 端时我们使用这套配置构建 Weex 端时将.weex.js放在最前面。然而由于构建配置通常是静态的我们可以通过环境变量动态生成配置。在rax-app中可以通过插件或自定义配置文件实现。例如在build.json中配置json{ targets: [web, weex, miniapp], web: { resolveExtensions: [.web.js, .js, .jsx] }, weex: { resolveExtensions: [.weex.js, .js, .jsx] } }6.2 路径别名配置为了简化跨端引入我们通常会设置路径别名使得无论是通用代码还是平台代码都可以通过统一的路径访问。推荐别名/common指向src/common/web指向src/web/weex指向src/weex/miniapp指向src/miniapp但在实际代码中应该尽量使用/common来引入通用模块避免直接引入平台特定模块除非是在平台专用代码中。业务代码不应该依赖/web等别名否则就失去了跨端性。在 webpack 中配置别名javascriptresolve: { alias: { : path.resolve(__dirname, src), /common: path.resolve(__dirname, src/common), /web: path.resolve(__dirname, src/web), /weex: path.resolve(__dirname, src/weex), }, },6.3 多端打包策略一个项目可能需要同时产出多个端的产物例如 Web 端、Weex 端、小程序端。我们可以使用同一个配置文件通过传入不同的目标参数来分别构建。或者使用 monorepo 方式每个端独立构建。在rax-app中可以通过--targets参数指定构建目标bashnpm run build -- --targetsweb,weex,miniapp构建后产物会分别输出到build/web、build/weex、build/miniapp等目录。6.4 按端分离公共资源不同端对资源文件图片、字体等的处理方式不同。例如Web 端可以直接使用图片 URL而小程序可能需要将图片放在指定目录并引用。建议将资源文件按端分别存放或者使用统一的资源管理模块根据平台返回正确的路径。第七章测试规范多端代码的测试是一个挑战。我们需要确保每个端的代码都能正确运行并且通用逻辑在各端表现一致。7.1 单元测试对于通用逻辑应该编写单元测试使用 Jest 或 Rax Test Utils。对于平台特定代码可以分别针对不同端编写测试或者使用模拟mock环境。示例通用组件测试javascriptimport { createElement } from rax; import renderer from rax-test-renderer; import Loading from ./Loading; test(Loading renders correctly, () { const component renderer.create(Loading texttest /); const tree component.toJSON(); expect(tree).toMatchSnapshot(); });7.2 端到端测试对于不同端建议编写独立的端到端测试Web 端使用 Puppeteer 或 Cypress。Weex 端使用 Weex 官方提供的测试工具。小程序端使用小程序开发者工具的自动化测试能力。由于成本较高端到端测试可以只覆盖核心业务流程。7.3 测试覆盖率要求团队应设定测试覆盖率阈值如 80%尤其是通用模块和平台抽象层确保代码质量。第八章文档与注释规范代码拆分后清晰准确的文档尤为重要。8.1 组件文档每个通用组件和平台适配组件都应有 README 文件说明组件的功能和使用方式支持的平台各端差异说明Props 列表示例代码可以使用 Storybook 或类似的工具来展示组件。8.2 平台差异说明在项目的根目录下可以维护一个PLATFORM_DIFF.md文件记录各个模块在不同平台上的实现差异方便新成员快速了解。8.3 代码注释规范对于使用了条件编译或文件后缀拆分的代码注释应说明为何拆分、各端实现的位置。对于平台抽象层的接口注释应说明该接口在各端的预期行为。使用 JSDoc 为函数和组件添加类型注释。第九章团队协作与代码审查按端拆分代码引入了新的复杂度团队协作时需遵循以下流程9.1 分支管理建议使用 Git Flow 或 GitHub Flow。对于涉及多端的大改动可创建 feature 分支并在合并前确保所有端的构建通过。9.2 代码审查要点在 Code Review 时需重点关注是否引入了不必要的平台判断平台特定代码是否放在了正确的目录/文件中通用代码是否真的通用还是隐含了平台假设构建配置是否同步更新9.3 持续集成设置 CI 流水线对每次提交进行所有端的构建和测试至少单元测试。确保新增代码不会破坏其他端的构建。第十章实践案例从零搭建一个跨端组件库为了更直观地展示上述规范的应用我们以搭建一个跨端组件库为例逐步演示如何按端拆分代码。10.1 项目初始化使用rax-cli初始化一个组件库项目bashnpx rax-cli init my-components选择“组件库”模板。10.2 目录结构设计我们决定采用“功能内拆分 公共抽象”的混合结构textmy-components/ ├── src/ │ ├── common/ # 通用工具、样式等 │ │ ├── styles/ │ │ └── utils/ │ ├── components/ │ │ ├── Button/ # Button 组件 │ │ │ ├── index.js # 入口根据平台导出 │ │ │ ├── index.web.js │ │ │ ├── index.weex.js │ │ │ └── index.miniapp.js │ │ ├── Image/ # 图片组件 │ │ │ ├── index.js │ │ │ ├── index.web.js │ │ │ └── index.weex.js │ │ └── Modal/ # 模态框仅 Web 和 Weex 支持 │ │ ├── index.js │ │ ├── index.web.js │ │ └── index.weex.js │ └── index.js # 组件库统一导出 ├── build/ # 构建输出 ├── test/ # 测试 ├── package.json └── ...10.3 实现 Button 组件Button 组件的通用逻辑接收children、onClick、type等 props样式可能在各端略有差异。index.js 入口javascript// src/components/Button/index.js import { createElement } from rax; let ButtonComponent; if (process.env.RAX_END web) { ButtonComponent require(./index.web).default; } else if (process.env.RAX_END weex) { ButtonComponent require(./index.weex).default; } else { ButtonComponent require(./index.miniapp).default; } export default ButtonComponent;Web 端实现index.web.jsjsximport { createElement } from rax; import styles from ./index.css; export default function Button({ children, onClick, type default }) { return ( button className{${styles.button} ${styles[type]}} onClick{onClick} {children} /button ); }Weex 端实现index.weex.jsjsximport { createElement } from rax; import styles from ./index.weex.css; export default function Button({ children, onClick, type default }) { return ( div className{${styles.button} ${styles[type]}} onClick{onClick} text className{styles.text}{children}/text /div ); }小程序端实现index.miniapp.js小程序中按钮使用原生button组件需要适配其属性。jsximport { createElement } from rax; import styles from ./index.miniapp.css; export default function Button({ children, onClick, type default }) { // 小程序按钮的 type 映射 const btnType type primary ? primary : default; return ( button className{styles.button} type{btnType} onClick{onClick} {children} /button ); }10.4 配置构建工具在组件库的build.json中配置多端构建json{ targets: [web, weex, miniapp], web: { resolveExtensions: [.web.js, .js, .jsx, .json] }, weex: { resolveExtensions: [.weex.js, .js, .jsx, .json] }, miniapp: { resolveExtensions: [.miniapp.js, .js, .jsx, .json] } }10.5 测试与发布编写单元测试针对各端模拟环境。例如使用jest配合jest-rax模拟 Rax 环境。由于组件库需要发布到 npm我们可以在package.json中设置main指向src/index.js这样使用者在构建时会根据自身项目的配置解析正确的端文件。第十一章常见问题与解决方案11.1 第三方库的跨端兼容性有些 npm 包只支持 Web 端如果直接使用会导致其他端报错。解决方案使用platform条件导入如if (process.env.RAX_END web) { require(some-web-lib); }。在 webpack 配置中为不同端设置externals或alias将特定库替换为空模块或模拟实现。11.2 代码重复问题有时不同端的实现有大量相似代码如果直接复制粘贴会导致维护困难。可以考虑提取公共部分到common中或者使用继承/组合模式。例如定义一个BaseButton包含通用逻辑各端实现继承它。11.3 调试困难当出现某个端特有的 bug 时调试可能困难。建议为每个端搭建独立的开发环境如npm run dev:web、npm run dev:weex。使用端特定的调试工具如 Chrome DevTools for Web, Weex Devtools。增加详细的日志输出并利用条件编译只在调试模式下输出。11.4 包体积过大如果按端拆分不当可能导致每个端的包中都包含了不必要的代码。解决方案确保使用了 tree-shaking 和 dead code elimination。对于大型依赖使用动态导入import()按需加载。检查构建产物使用webpack-bundle-analyzer分析。第十二章未来展望与演进随着 Rax 生态的发展按端拆分代码的规范和工具也在不断演进。我们可以关注以下几个方向更智能的构建工具自动检测平台差异并优化打包。统一的跨端 API 标准Rax 可能会提供更完善的跨端 API减少开发者封装成本。类型系统支持通过 TypeScript 定义平台抽象接口确保各端实现符合契约。组件平台声明在组件库的package.json中声明支持的平台让构建工具自动处理。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2452998.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;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…