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

[MERN 项目实战] MERN Multi-Vendor 电商平台开发笔记(v2.0 从 bug 到结构优化的工程记录)

[MERN 项目实战] MERN Multi-Vendor 电商平台开发笔记(v2.0 从 bug 到结构优化的工程记录)

其实之前没想着这么快就能把 2.0 的笔记写出来的,之前的预期是,下一个阶段会一直维持到将 MERN 项目写完,毕竟后期很多东西都是 cv 了。不过没想到,一个 frontend(2C 端的商城页面)写着写着还是碰到了不少的问题

后端

这里其实就一个 routes 的路径顺序问题,我也是等到 v1 收尾了,又做了一点点 cleanup,在不同页面来回切换的时候,发现请求的路径不对,express 的 log 一直在显示 string 是一个不合法的 ObjectId,然后找不到对应的数据

后面看了下,是 routes 的路径问题,之前的写法是:

routes.get("/something/:someId", getSomethingById);
routes.get("/something/sub-resource", getSubResource);

这种写法,会将 sub-resource map 到 :someId 里,express 直接运行 getSomethingById ,最终因为 id 不匹配而抛出异常

数据库

简单的记录一下这个用法:

SellerModel.findById(id).populate("shop");

我这里的 shop 和 seller 又 1-to-1 的关系,具体的 schema 关系如下:

import { Schema, model, Types, Document } from "mongoose";export interface IShop extends Document {seller: Types.ObjectId;name: string;country: string;state: string;city: string;image?: string;
}const shopSchema = new Schema<IShop>({seller: {type: Schema.Types.ObjectId,ref: "Seller",required: true,unique: true, // enforce one-to-one},name: { type: String, required: true },country: { type: String, required: true },state: { type: String, required: true },city: { type: String, required: true },image: { type: String, default: "" },},{ timestamps: true }
);export default model<IShop>("Shop", shopSchema);

Seller 内部的实现是差不多的,代码太长了就不贴了。这种情况下,使用 populate 可以将 shop 的数据 map 到 seller 种的 shop 属性——原本是一个 ObjectId 的字符串,这种情况就可以减少一个与后端的 API 请求,在真实的使用场景会很好的减少数据库的压力

Workspace/MonoRepo

前端的东西就比较多啦,毕竟这次主要折腾的就是 UI,而且还是比较难得,场景比较全面的 2C 端的 UI。这次写完也确实发现一点问题,尤其是代码重复的这个问题

鉴于 notion 的结构比较有限——只有 3 级,这里就把前端部分的问题细细拆成 workspace、React 相关、tailwind css 相关,

重复的业务逻辑……微前端是解决方法?

这里主要说的是 hooks,utils 和 componengs 三个组件,如:

虽然 frontend 尚且还没有开始实现业务相关的逻辑,不过已经能够看到有一些重复的使用,如:

  • cn.js → 一个简单的 tailwind css 的 util 方法
  • Pagination → Pagination 的 UI 渲染
  • usePaginnationSearch → 实现了 debounce/search/pagination 的 hooks
  • 共通的 packages 等等

包括之后可能会涉及到的 auth 相关的逻辑……也的确是应该研究一下微前端是不是能够很好的解决这个问题,尤其是两个项目都是 React based,共通的 modules 太多了

冲突的 React 版本

这个问题的出现,是在尝试使用一个 dependency 的时候发生的,具体的报错大概就是 react 中的 useEffect 这个 hook 出现了问题,具体只记得是 Invalid hook call,但是记不太清细节了……有可能是 useEffect 被调用了两次……不过最终发现,原因是 React 的版本发生了冲突:

yarn list reactyarn list v1.22.22
warning Filtering by arguments is deprecated. Please use the pattern option instead.
├─ frontend@0.1.0
│  └─ react@19.1.0
└─ react@19.0.0
✨  Done in 0.54s.

我之前有简单搜索一下,这个问题的确是通过 turborepo 进行 monorepo 的管理出现的问题,尤其是我在两个不同的时间段安装了 dashboard 和 frontend 模块,这导致两个模块中的 React 版本有了轻微的冲突。在两个版本都出现在 node_modules 中,就会被识别成两个不同的 React 实例

问题的关键在这里:

两个 React 实例创建了不同的 context,以至于在某些 edge case 的情况下会抛出异常,即用串了 context,找不到自己原本应该调用的 context,然后触发该异常。只能说在运行不同的 React 版本,没有抛异常是运气,抛了异常,就有可能是 production issue……

最后的解决方案是在 root dependency 中定义 React 的版本,在根目录下运行 yarn install --force,重新安装/管理依赖,解决问题。根目录的 package.json 如下:

{"resolutions": {"react": "^19.1.0"}
}

运行过程&结果:

yarn install --force
❯ yarn list react
yarn list v1.22.22
warning Filtering by arguments is deprecated. Please use the pattern option instead.
└─ react@19.1.0
✨  Done in 0.57s.

⚠️:在这种情况下,推荐的做法是不写死 react 版本,而是用 peerDependencies 去更优化的管理版本

无法安装依赖的根目录

这算是一个补充吧,因为我自己其实都不知道还有这个限制

事情起因是,在新建 frontend 的时候,不小心在根目录下运行了 yarn add 指令,然后 yarn/turborepo 抛出了这个异常:

error Running this command will add the dependency to the workspace root rather than the workspace itself, wh…

这里做个简单的记录

React

这里放一点只和 React 相关,范围比较狭窄的内容

使用 env 改变 PORT

其实我不太清楚 .env 文件到底能够重写多少 React 的属性,不过 port 算是蛮重要的一个,这里提一嘴

修改了 port 之后,turborepo 就可以同时运行 3000(dashboard ui) 和 3001(frontend ui) 了

React 项目文件结构如何设计

最初我们开始写 React 的时候用的结构就不谈了,说一下我们现在主要用的两种,第一种是所有的相关联的组件在 components 下,并且按照功能关联,大体如下:


components/
├── features/                  # 页面级组件
│   ├── home/
│   ├── products/
├── ui/                     # 原子化 UI 组件(通常无状态)
│   ├── Button.tsx
│   ├── Input.tsx
│   └── Card.tsx
├── shared/                 # 可复用的复合组件(页面级别也会引用)
│   ├── PageBanner.tsx
│   ├── ProductCard.tsx
│   └── Ratings.tsx
├── layout/                 # 页面布局类组件
│   └── Navbar.tsx

另一种则是所有相关联的组件在 pages 下,每个页面不作为单独的 jsx 文件,而是作为一个文件夹,存储相关联的组件,大体结构如下:

pages/
├── Home/
│   ├── index.tsx             # Home 页面入口组件
│   ├── HeroBanner.tsx        # 页面专属组件
│   ├── useWelcomeData.ts     # 页面专属 hook
│   └── styles.module.css     # 页面样式
├── Products/
│   ├── index.tsx
│   ├── ProductList.tsx
│   ├── ProductFilter.tsx
│   ├── useProductQuery.ts
│   └── styles.module.css
├── Checkout/
│   ├── index.tsx
│   ├── AddressForm.tsx
│   ├── PaymentSummary.tsx
│   ├── useCheckout.ts
│   └── styles.module.css

需要注意的是,这种以页面为中心的存储方式,依然会保留 components 文件夹,并且在里面集中管理 shared、UI 之类相关组件,只是会将 features 中的内容放到页面中

具体二者的存储方式并没有绝对意义上的优缺点,只能说必须要根据业务情况做分析。以我自己的项目为经验,我个人感觉是:

  • B2C 适合第一种
    其主要原因是 B2C 的业务,结构相对而言更加的简单,业务逻辑复用更多,比如说一个常见的商城项目,首页会出现各种各样的商品卡片、促销商品,商家页面中会出现商品卡片,商品页面中会出现更多的 product 相关的组件。这种时候,在 components 下放一个商品相关的 feature,集中管理散落在各个页面的复用组件
  • B2B 适合第二种
    与之对比的是 B2B 的业务,结构相对会更加的复杂,业务逻辑多与页面进行绑定,鲜少会出现核心 UI 逻辑散落在不同页面中。就算偶尔会出现这个情况,大多数也是作为 reference data 的存在,可以以该 UI 的主页面作为 base 进行导入

React Router DOM

这个应该说在写这个项目之前,我都没有意识到会有这个问题,写法大体如下:

<Linkto="/something"state={{someState: someState,}}
><button>something</button>
</Link>

在我看来这个代码是没问题的——或者说一直以来都是这么写的,一直工作都没什么问题,除了这个 state——主要是想尝试一下新写法,尝试在 navigate 的时候将状态带到下一个页面去,而不是使用 zustand/redux 进行全局化的管理,这样清理状态也比较方便

搜索了一下之后发现,这是 React Router DOM 在遵从了 HTML 的标准实现规范后出现的问题。本质上的逻辑是这样的:

  1. Link 在渲染后成为 <a href=""></a>
  2. button 嵌套在了 a 标签中

这就是问题

好吧,这么说还是不够直白……具体要解释原因,就得到 WHATWG——也就是现在 HTML 版本规范的组织——的官方文档里

其中在 **3.2.5.2.7 interactive content 中提到:

3.2.5.2.7 Interactive content

Interactive content is content that is specifically intended for user interaction.

  • a (if the href attribute is present)
  • audio (if the controls attribute is present)
  • button
  • details
  • embed
  • iframe
  • img (if the usemap attribute is present)
  • input (if the type attribute is not in the Hidden state)
  • label
  • select
  • textarea
  • video (if the controls attribute is present)

在 4.10.6 The button element 中提到

4.10.6 The button element

Content model:Phrasing content, but there must be no interactive content descendant and no descendant with the tabindex attribute specified.

同样在 stack overflow 上的一个 thread 也有讨论过:**HTML Validation: Why is it not valid to put an interactive element inside an interactive element? ,这就能解决问题了:**

互动内容中嵌套互动内容是不合法的 HTML,这种实践下的行为是不可预测的,有可能 button 的 event listener 捕捉了 a 标签的重定向,反之亦然。工作那是运气好,不工作才是默认的行为

这里最终的解决方法其实是用 onClick 绑定了 useNavigate,但是真正、最好、符合 accessibility 的解法,还是应该用 button+span+手写样式的方法去解决这个问题……

Tailwind CSS

之前主要上的是 tailwind css 的课,instructors 不管怎么说对 tailwind 还是比较专业的,因此学到了一些基础,不过反思比较少。这次的 instructor 代码写的真的挺烂的,然后就发现已经学过的 tailwind css——或者说 css,其实还是有不少东西可以深挖的

基础色的变化

虽然我发现在之前学习的过程中,大部分项目使用的是 hex,不过在做了 tailwind 之后,我发现其实 rgb 相对而言会更加的动态一些。以下面这个 button 为例:

至少 有两种实现方法:

<buttonclassName={cn("w-[200px] h-[36px] px-4 py-1  rounded-md bg-[#059473] text-white","hover:shadow-lg hover:shadow-[#059473B2]")}
>Example
</button>

这里的 hover,其实还是以 base color,即 059473 做的变量,起主要就是修改了不透明度,也就是 hex 后面的两位数字

对比起来是用 rgb 的实现:

<buttonclassName={cn("w-[200px] h-[36px] px-4 py-1 rounded-md text-white bg-[rgb(5,148,115)]","hover:shadow-lg hover:shadow-[rgba(5,148,115,0.7)]")}
>Example
</button>

可以看到,这种情况下,使用 rgb 是可以更加直观地看到对于背景色的修改是多少。对于前端开发来说,这样可以在选择好 base 这种基础颜色后,通过调整不透明程度的方法获取一整套的颜色表——毕竟现在前端开发其实 UI/UX 的差别越来越大了。以我本人来说,根本搞不定 figma/adobe illustrator,更别说能够拿出同样的配色表

rgb 和 rgba 的搭配其实只能获取一个浅色表,如果想要获取深色的方法,可以:

  • 使用 hsl
    如下面的代码:
              <div class="w-[150px] h-[32px] my-5 bg-[hsl(164,93%,20%)] text-white">Dark Mode</div><div class="w-[150px] h-[32px] my-5 bg-[hsl(164,93%,30%)] text-white">Base Mode</div><div class="w-[150px] h-[32px] my-5 bg-[hsl(164,93%,45%)] text-black">Light Mode</div>
    
    效果如下:

    可以看到,换了亮度后就有了不同等级的颜色,其实也可以对标类似于 blue50-800 这样的配置
  • 手动计算 rgb 的值,即每个数值乘以相同的系数
    这个只是我觉得理论上可以 work,实际操作可能会觉得比较麻烦没做过的事情,而且我觉得这个操作对于纯色的挑战会比较大……

同样的原理其实也可以用在 opacity 上。普通的 opacity 只能加一个透明度,但是如果在 div 上,添加一个大小完全一致的黑色遮照,通过控制遮照的透明度,也能够完成 hover 后获取一个更深的背景色这一方法——这时候就要善用 relative & absolute & :before or :after

兄弟组件也一起向上移动

这种情况用截图说明比较容易:

可以看到,Base Mode 移动了的话,Light Mode 也会一起向上走,这是因为移动时用的是 mt:

          <div class="w-[150px] h-[32px] my-5 bg-[hsl(164,93%,20%)] text-white hover:mt-2 transition-all duration-100">Dark Mode</div><div class="w-[150px] h-[32px] my-5 bg-[hsl(164,93%,30%)] text-white hover:mt-2 transition-all duration-100">Base Mode</div><div class="w-[150px] h-[32px] my-5 bg-[hsl(164,93%,45%)] text-black hover:mt-2 transition-all duration-100">Light Mode

而使用 mt 会重新计算文档流的位置,这种情况下,用 translate 会有更好的效果。translate 本身不会修改原有元素的位置,因此不会计算剩下所有文档流的位置

eslint

主要是因为 instructor 有 typo,然后我发现 css 不起效,eslint 有蛮多的问题的,首先是 CRA 用的 eslint 还是 v8,但是现在 eslint 的官方已经出到了 v9,我在这个配置,出了很多的报错,后面才发现是版本冲突的问题,导致 eslint 的配置也不一样了——eslint 的配置文件名也不一样

这里就按照 eslint v8 的配置,文件名还是 .eslintrc.js:

module.exports = {plugins: ["tailwindcss"],extends: ["react-app", "plugin:tailwindcss/recommended"],rules: {"tailwindcss/no-custom-classname": ["warn",{whitelist: ["header-top", "my-swiper", "custom_bullet"],},],"tailwindcss/classnames-order": "off",},
};

只要 VSCode 开启了 eslint 的附件,那么,出现了 typo 之后,vscode 就会开始自动提示:

cn util

之前好像在 electron 里面提过这个 util,实现方法如下:

import { clsx } from "clsx";
import { twMerge } from "tailwind-merge";export function cn(...inputs) {return twMerge(clsx(inputs));
}

cn 可以用这几种方式加类名:

cn("plain string", true && "plain string", {"plain string": condition1,"plain stringq": condition2,
});

整体来说,使用 cn 动态管理类名会相对而言更加的直观

gh

还是 github 的功能,研究了下发现还是还挺有意思的

gh template

templates 需要放在 .github/ISSUE_TEMPLATE 下,里面是 md 文档,放一些描述/heading 即可

批量更新

不过这里用脚本跑的,代码大体如下:

for i in 42 43 44 45 46 47
dogh issue edit $i --add-label "features,frontend,ui"
done

这样就能一次更新 42-47,然后添加相同的 labels

相关文章:

[MERN 项目实战] MERN Multi-Vendor 电商平台开发笔记(v2.0 从 bug 到结构优化的工程记录)

[MERN 项目实战] MERN Multi-Vendor 电商平台开发笔记&#xff08;v2.0 从 bug 到结构优化的工程记录&#xff09; 其实之前没想着这么快就能把 2.0 的笔记写出来的&#xff0c;之前的预期是&#xff0c;下一个阶段会一直维持到将 MERN 项目写完&#xff0c;毕竟后期很多东西都…...

KS卡片铃铛知多少,春花秋月何时了

废话不多说&#xff0c;直接上干活 卡片随意跳转技术 可以私信卡片&#xff0c;也可以群发卡片&#xff0c;丝毫不影响使用 铃铛跳转实例 需要一定要找我哦&#xff1a;qmfy01...

SQL 语法

好的&#xff0c;下面是对 SQL 语法的简洁总结&#xff0c;涵盖了常见的 SQL 操作和基本语法结构。 创建一个表 (CREATE TABLE) 首先&#xff0c;我们需要创建一个表 users&#xff0c;如果还没有的话&#xff1a; CREATE TABLE users ( id INT PRIMARY KEY, name VARCHAR(100)…...

《ATPL地面培训教材13:飞行原理》——第1章:概述与定义

翻译&#xff1a;刘远贺&#xff1b;辅助工具&#xff1a;Cluade 3.7 第1章&#xff1a;概述与定义 目录 概述一般定义术语表符号列表希腊符号其他自我评估问题答案 概述 飞机的基本要求如下&#xff1a; 机翼产生升力&#xff1b; 机身容纳载荷&#xff1b; 尾部表面增加…...

https nginx 负载均衡配置

我的系统是OpenEuler。 安装nginx yum install -y nginx 启动&开机启动 systemctl start nginx systemctl enable nginx 自定义conf配置文件 cat <<EOF >> /etc/nginx/conf.d/load_balancer.conf upstream backend {ip_hash; # 防止验证码验证失败server…...

初始https附带c/c++源码使用curl库调用

使用C与CURL开发HTTPS客户端的深度指南 目录 准备工作基础HTTPS请求实现核心功能扩展进阶配置与优化安全注意事项调试与问题排查跨平台适配要点 一、准备工作 1.1 cURL库简介 cURL&#xff08;Client URL Request Library&#xff09;是一个支持多种网络协议的开源库&…...

NI Multisim官网下载: 电路设计自动化EDA仿真软件

NI Multisim是一款由美国国家仪器公司&#xff08;National Instruments&#xff0c;简称 NI&#xff09;推出的电路设计与仿真软件&#xff0c;广泛应用于工程教育、电子电路开发和科研领域。它结合了图形化的电路绘图界面与强大的 SPICE 仿真引擎&#xff0c;让用户可以在虚拟…...

通过阿里云Milvus与通义千问VL大模型,快速实现多模态搜索

本文主要演示了如何使用阿里云向量检索服务Milvus版与通义千问VL大模型&#xff0c;提取图片特征&#xff0c;并使用多模态Embedding模型&#xff0c;快速实现多模态搜索。 基于灵积&#xff08;Dashscope&#xff09;模型服务上的通义千问 API以及Embedding API来接入图片、文…...

React 与 Vue:两大前端框架的深度对比

在前端开发领域&#xff0c;React 和 Vue 无疑是当下最受欢迎的两大框架。它们各自拥有独特的优势和特点&#xff0c;吸引了大量开发者。无论是初学者还是经验丰富的工程师&#xff0c;选择 React 还是 Vue 都是一个常见的问题。本文将从多个角度对 React 和 Vue 进行对比&…...

OpenFeign和Gateway

OpenFeign和Gateway 一.OpenFeign介绍二.快速上手1.引入依赖2.开启openfeign的功能3.编写客户端4.修改远程调用代码5.测试 三.OpenFeign参数传递1.传递单个参数2.多个参数、传递对象和传递JSON字符串3.最佳方式写代码继承的方式抽取的方式 四.部署OpenFeign五.统一服务入口-Gat…...

openwrt作旁路由时的几个常见问题 openwrt作为旁路由配置zerotier 图文讲解

1 先看openwrt时间&#xff0c;一定要保证时间和浏览器和服务器是一致的&#xff0c;不然无法更新 2 openwrt设置旁路由前先测试下&#xff0c;路由器能否ping通主路由&#xff0c;是否能够连接外网&#xff0c;好多旁路由设置完了&#xff0c;发现还不能远程好多就是旁路由本…...

ai如何赋能艺术教育

在数字化浪潮席卷全球的今天,人工智能(AI)作为第四次工业革命的核心驱动力,正以前所未有的速度重塑教育生态。艺术教育领域作为培养创造力、批判性思维与跨文化理解力的关键阵地,正经历着AI技术带来的深刻变革。本文将从技术赋能、教育范式革新、全球化协作三个维度,探讨…...

NocoBase 本周更新汇总:联动规则条件左侧支持变量

原文链接&#xff1a;https://www.nocobase.com/cn/blog/weekly-updates-20250424。 汇总一周产品更新日志&#xff0c;最新发布可以前往我们的博客查看。 NocoBase 目前更新包括的版本更新包括三个分支&#xff1a;main &#xff0c;next和 develop。 main &#xff1a;截止…...

协作开发攻略:Git全面使用指南 — 第二部分 高级技巧与最佳实践

协作开发攻略&#xff1a;Git全面使用指南 — 第二部分 高级技巧与最佳实践 Git 是一种分布式版本控制系统&#xff0c;用于跟踪文件和目录的变更。它能帮助开发者有效管理代码版本&#xff0c;支持多人协作开发&#xff0c;方便代码合并与冲突解决&#xff0c;广泛应用于软件开…...

sass 变量

基本使用 如果分配给变量的值后面添加了 !default 标志 &#xff0c;这意味着该变量如果已经赋值&#xff0c;那么它不会被重新赋值&#xff0c;但是&#xff0c;如果它尚未赋值&#xff0c;那么它会被赋予新的给定值。 如果在此之前变量已经赋值&#xff0c;那就不使用默认值…...

多级缓存架构深度解析:从设计原理到生产实践

多级缓存架构深度解析&#xff1a;从设计原理到生产实践 一、多级缓存架构核心定位与设计原则 1. 架构分层与角色定位 多级缓存通过分层存储、流量削峰、数据分级实现性能与成本的平衡&#xff0c;典型三层架构如下&#xff1a; 层级代表组件存储介质数据特征命中目标成本级…...

(51单片机)LCD展示动画(延时函数)(LLCD1602教程)

前言&#xff1a; 前面我们说过&#xff0c;之前LCD1602模块有点难&#xff0c;但是现在&#xff0c;我们通过几遍博客的学习&#xff0c;今天来讲一下LCD1602的原理 演示视频&#xff1a; LCD1602流动 源代码&#xff1a; main.c #include <STC89C5xRC.H> #include &q…...

12N60-ASEMI无人机专用功率器件12N60

编辑&#xff1a;LL 12N60-ASEMI无人机专用功率器件12N60 型号&#xff1a;12N60 品牌&#xff1a;ASEMI 封装&#xff1a;TO-220F 最大漏源电流&#xff1a;12A 漏源击穿电压&#xff1a;600V 批号&#xff1a;最新 RDS&#xff08;ON&#xff09;Max&#xff1a;0.68…...

[Redis] Redis最佳实践

&#x1f338;个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;️热门专栏: &#x1f9ca; Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 &#x1f355; Collection与…...

arm64适配系列文章-第九章-arm64环境上sentinel的部署

ARM64适配系列文章 第一章 arm64环境上kubesphere和k8s的部署 第二章 arm64环境上nfs-subdir-external-provisioner的部署 第三章 arm64环境上mariadb的部署 第四章 arm64环境上nacos的部署 第五章 arm64环境上redis的部署 第六章 arm64环境上rabbitmq-management的部署 第七章…...

3dmax模型怎么处理3dtiles,制作制作B3DM格式文件

1咱们先打3dmax&#xff0c;或su或者其他软件建模型 2记住面一定一定要少&#xff0c;面一定不能多&#xff0c;也不要是VR材质&#xff0c;可以用插件一键处理 3导出fbx 4使用cesium把fbx转换 5这里可以坐标&#xff0c;因为要对地图位置 6转换出来了&#xff0c;3dtiles格式…...

雪花算法生成int64,在前端js的精度问题

1.问题背景 后端对视频生成唯一性id&#xff0c;在发送评论阶段&#xff0c;由于后端接收的json数据格式&#xff0c;设置videoId为int64。前端于是使用js的Number函数&#xff0c;进行字符串转换为数字&#xff0c;由于不清楚js的精度范围&#xff0c;产生了携带的videoId变化…...

软件测试报告包括哪些内容?可出专业软件测试方案的测评机构推荐

随着信息技术的快速发展&#xff0c;软件质量已经成为决定企业竞争力的重要因素之一。软件测试作为保障软件质量的关键环节&#xff0c;其成果汇总形成的“软件测试报告”在项目生命周期中扮演着重要角色。 软件测试报告就是用来反映测试工作全貌的报告。从测试准备、过程、结…...

dockercompose文件仓库

mysql version: 3 # 使用docker-compose的版本&#xff0c;根据需要可以调整# 创建数据目录 # mkdir -p /home/docker/mysql/mysql_data # mkdir -p /home/docker/mysql/mysql_logs # 给予适当的权限&#xff08;确保MySQL容器可以读写这些目录&#xff09; # chmod 777 /ho…...

Docker 的基本概念和优势以及在应用程序开发中的实际应用

Docker 是一种开源的容器化平台,可以让开发者将应用程序及其所有依赖项打包成一个独立的容器,从而实现应用程序的快速部署和运行。下面是 Docker 的基本概念和优势: 基本概念: 容器:一个轻量级、独立的运行环境,包含应用程序及其所有依赖项。镜像:一个只读的模板,用于创…...

JavaWeb:HtmlCss

快速入门 <html><head><title>HTML快速入门</title><head><body><h1>Hello HTML</h1><img src"1.png"></img></body> </html>开发工具vscode 常见便签&样式&#xff08;新闻&#xff0…...

linux centOS7.9 No package docker-ce available

docker pull apache/apisix:3.2.2-centos Error response from daemon: missing signature key 处理方式如下&#xff1a; 问题&#xff1a;在纯净机里安装docker时报错No package docker-ce available。 解决办法&#xff1a; 1、更新yum&#xff0c;使用yum -y upgrade&#…...

机器学习(8)——主成分分析

文章目录 1. 主成分分析介绍2. 核心思想3. 数学基础4. 算法步骤4.1. 数据标准化&#xff1a;4.2. 计算协方差矩阵&#xff1a;4.3. 特征分解&#xff1a;4.4. 选择主成分&#xff1a;4.5 降维&#xff1a; 5. 关键参数6. 优缺点7. 改进变种8. 应用场景9. Python示例10. 数学推导…...

使用深度 Q 学习解决Lunar lander问题

使用深度 Q 学习解决Lunar lander问题 0. 前言1. 使用深度 Q 网络解决 Atari 游戏2. 定义环境3. 解决 Lunar lander 问题相关链接 0. 前言 深度 Q 学习模型只需观察状态作为输入就能够解决经典 Atari 游戏&#xff0c;这是一个重大突破&#xff0c;从那时起&#xff0c;深度强…...

centos7使用yum快速安装最新版本Jenkins-2.462.3

Jenkins支持多种安装方式&#xff1a;yum安装、war包安装、Docker安装等。 官方下载地址&#xff1a;https://www.jenkins.io/zh/download 本次实验使用yum方式安装Jenkins LTS长期支持版&#xff0c;版本为 2.462.3。 一、Jenkins基础环境的安装与配置 1.1&#xff1a;基本…...

Bean的生命周期

1.实例化Bean&#xff08;通过BeanDefinition反射调用无参构造创建对象&#xff0c;如果没有无参构造&#xff0c;需要指定唯一构造方法&#xff09; 2.给Bean的属性set()赋值 3.检查Bean是否实现了Aware相关接口&#xff0c;实现的话则执行方法 Aware接口&#xff1a;空接口&…...

【缓存与数据库结合方案】伪从技术 vs 直接同步/MQ方案的深度对比

伪从技术 vs 直接同步/MQ方案的深度对比 直接同步修改或通过MQ消息队列也能实现类似同步功能&#xff0c;但伪从技术&#xff08;通过消费binlog实现数据同步&#xff09;在某些场景下具有独特优势。下面我将从多个维度进行详细对比分析&#xff1a; 一、核心差异对比表 方案…...

【前端】【业务场景】【面试】在前端开发中,如何实现文件的上传与下载功能,并且处理可能出现的错误情况?

前端文件上传与下载攻略 本文目标&#xff1a;帮你快速掌握文件上传 & 下载的核心实现方式&#xff0c;并在常见出错场景下保持“优雅不崩溃”。 一、文件上传 1. 基础结构 <input type"file" id"fileInput" /> <button id"uploadBtn&…...

【axios取消请求】如何在token过期后取消未响应的请求

功能背景&#xff1a; 我们在实际项目中通常会遇到登录过期后会跳登录页的情况&#xff0c;回跳过程会根据接口请求的状态码判断是否登陆状态过期&#xff0c;并给出用户提示&#xff0c;如果此时存在多个请求接口同时调用&#xff0c;就会同时报出多个登录过期的提示&#xf…...

【高频考点精讲】JavaScript中的组合模式:从树形结构到组件嵌套实战

📚 目录 📦 什么是组合模式?🌲 基础版:用组合模式构建一个简单的树形结构💡 举个更真实的场景:菜单组件🧠 为什么组合模式在前端特别重要?🔨 实战案例:组件嵌套组合 + 权限控制🧩 组合模式的延伸用法:搭建 UI DSL 引擎🧪 面试题时间(欢迎评论区作答)组…...

《仙剑奇侠传二》游戏秘籍

无限冥纸&#xff1a;在丰都城&#xff0c;点击特定的小猫&#xff0c;它会给你五张冥纸&#xff0c;再次点击还会再给五张&#xff0c;可循环获取。无限使用虎煞技能&#xff1a;学会 “虎啸风声” 技能后&#xff0c;将虎煞之力值设置为 16&#xff0c;在战斗中持续使用该技能…...

AWS 中国区 CloudFront SSL 证书到期更换实战指南

适用场景: AWS 中国区(宁夏区域 cn-northwest-1 或北京区域 cn-north-1)CloudFront 分配的 SSL 证书到期后无缝替换,域名主体为 domain.cn。 背景与痛点 当 CloudFront 使用的 SSL 证书即将到期时,需手动替换新证书以避免服务中断。由于 AWS 中国区 不支持 ACM 证书,必须…...

【2025A卷】华为OD机试九日集训第3期 - 按算法分类,由易到难,提升编程能力和解题技巧,从而提高机试通过率(Python/JS/C/C++)

目录 一、适合人群二、本期训练时间三、如何参加四、数据结构与算法大纲五、华为OD九日集训第3期第1天、逻辑分析第2天、逻辑分析第3天、双指针第4天、双指针第5天、数据结构map第6天、栈第7天、二叉树第8天、贪心算法第9天、二分查找 六、集训总结国内直接使用最新o3、o4-mini…...

MacOS上如何运行内网穿透详细教程

本文以市面常见、好用的内网穿透为例&#xff0c;一款为开源内网穿透工具Frp;另一款为国产新锐软件ZeroNews。 一、Frp&#xff08;开源工作、使用自由&#xff09; 1. 下载 FRP 访问 FRP 的 GitHub 发布页&#xff1a; https://github.com/fatedier/frp/releases 选择适合 …...

第55讲:农业人工智能的跨学科融合与社会影响——构建更加可持续、包容的农业社会

目录 一、农业人工智能的多维融合:科技与社会的桥梁 1. 技术与社会:解决现代农业中的不平等 2. AI与伦理:塑造道德规范与社会责任 3. AI与政策:推动农业政策的科学决策与智能执行 二、AI与农业未来社会的构建:更绿色、更智能、更包容 1. 推动农业可持续发展:绿色农…...

JVM性能优化之老年代参数设置

一、引言 咱们书接上回&#xff0c;上篇文章主要讲解了年轻代参数设置&#xff0c;如果对这一部分还不清楚的建议先去看一下&#xff08;年轻代参数设置&#xff09;&#xff0c;本文主要为大家介绍老年代参数的设置&#xff0c;掌握好jvm参数的设置是一个高级开发人人员必备的…...

在 Ubuntu 环境为 Elasticsearch 引入 `icu_tokenizer

1. 为什么需要 ICU 分析插件 Elasticsearch 默认的 standard tokenizer 遵循 UAX #29 规则&#xff0c;但在 CJK&#xff08;中、日、韩&#xff09;等亚洲语言上仅能按字符切分&#xff0c;无法识别词边界&#xff1b;对包含重音符号、大小写或多脚本混排的文本也缺乏统一归一…...

JMeter 安装及使用 [软件测试工具]

目录 JMeter 1. JMeter 安装 1.1 点击官网下载: JMeter官网下载 1.2 下载后解压即可 1.3 打开 JMeter 1.3.1 方式一: 点击对应程序打开 1.3.2 方式二: 命令行启动 1.4 关闭 JMeter 2. JMeter 基础配置 2.1 修改字体为简体中文 2.2 添加拓展插件 2.2.1 下载其他监听器…...

Unity 资源合理性检测

一&#xff1a;表格过度配置&#xff0c;表格资源是否在工程中存在&#xff0c;并输出不存在的资源 import pandas as pd import glob import osassets [] count 0# 遍历configs文件夹下所有xlsx文件 for file_path in glob.glob(configs/*.xlsx):count 1try:sheets pd.re…...

vue-study(1)

黑马智数项目 黑马智数是一个数字化园区管理项目&#xff0c;该项目后台可以在线管理园区内的楼宇、企业、车辆和一体杆等资源&#xff0c;可视化大屏通过园区3D模型实时展示园区概况。通过该项目能学到如何用qiankun搭建微前端架构、用Echarts进行数据可视化、以及前沿的3D模…...

XS5032:高性能3DNR+HDR ISP-TX 2K芯片

爱芯元智 XS5032&#xff1a;高性能3DNRHDR ISP-TX 2K芯片 视频输入 支持MIPI接口&#xff0c;4lane&#xff0c;Max.1.5Gbps/lane 支持Sensor并口&#xff08;DVP&#xff09; 视频分辨率 支持多种同轴高清制式和标清制式&#xff0c;包括&#xff1a; 960H25/30fps&…...

[原创](现代Delphi 12指南):[macOS 64bit App开发]:如何使用NSString类型字符串?

[作者] 常用网名: 猪头三 出生日期: 1981.XX.XX 企鹅交流: 643439947 个人网站: 80x86汇编小站 编程生涯: 2001年~至今[共24年] 职业生涯: 22年 开发语言: C/C++、80x86ASM、Object Pascal、Objective-C、C#、R、Python、PHP、Perl、 开发工具: Visual Studio、Delphi、XCode、…...

TDengine 流计算引擎设计

流计算架构 TDengine 流计算的架构如下图所示。当用户输入用于创建流的 SQL 后&#xff0c;首先&#xff0c;该 SQL 将在客户端进行解析&#xff0c;并生成流计算执行所需的逻辑执行计划及其相关属性信息。其次&#xff0c;客户端将这些信息发送至 mnode。mnode 利用来自数据源…...

扩展中国剩余定理

中国剩余定理 中国剩余定理 考虑一组模线性同余方程&#xff1a; { x ≡ a 1 ( m o d m 1 ) x ≡ a 2 ( m o d m 2 ) . . . x ≡ a k ( m o d m k ) \begin{cases} x\equiv a_1\pmod{m1} \\ x\equiv a_2\pmod{m2}\\ .\\ .\\ .\\ x\equiv a_k\pmod{mk}\\ \end{cases} ⎩ ⎨ ⎧…...

git检查提交分支和package.json的version版本是否一致

这里写自定义目录标题 一、核心实现步骤‌1.安装必要依赖‌2.初始化 Husky‌3.创建校验脚本‌4.配置 lint-staged‌5.更新 Husky 钩子‌ 三、工作流程说明‌四、注意事项‌ 以下是基于 Git Hooks 的完整解决方案&#xff0c;通过 husky 和自定义脚本实现分支名与版本号一致性校…...