咕咕鸽爱学习 - zy123
type: channel
link: https://bitday.top/author/1/
description: zy123
items: OMNet仿真
items: Cursor使用
items: deepwalk
items: K8S
items: CICD
items: 训练神经网络
items: 草稿
items: RAG知识库
items: 拼团设计模式
items: 测试

OMNet仿真
type: item
date: 2026-01-20T10:55:20+08:00
description: OMNeT仿真 初始安装配置 🧩 第 0 步：下载和安装 OMNeT++ 选择版本： 👉 OMNeT++ 6.0.1 或 6.0.2（官方 Windows 兼容） 下载地址（官网）： https://omnetpp.org/download/ 安装步骤概述： 下载 ZIP → 解压 打开 mingwenv.cmd（这个是必须的环境） 在弹出的终端执行： ./configure make 然后运行 omnetpp 就会启动图形化 IDE（Eclipse）。 这个过程大概 10–20 分钟。 第 1 步：下载 INET 框架 推荐与你的 OMNeT++ 版本兼容： OMNeT++ 6.x → 用 INET 4.5.x 下载 INET： https://github.com/inet-framework/inet/releases 解压后你会看到 INET 根目录。 在同样的 mingwenv 环境中运行： cd inet source setenv make makefiles make -j4 等待几分钟。 导入 INET 到 OMNeT++ IDE 在 OMNeT++ IDE 中： File → Import → 选择General文件夹 → Existing Projects into Workspace 选择 INET 根目录 → Finish 你的工程列表里会看到 INET。 网络仿真 第 0 步：打开IDE 进入你的 OMNeT++ 安装目录，双击 omnetpp.exe 第 1 步：创建你的项目 在 IDE 里： File → New → OMNeT++ Project → Empty Project 项目名：TrafficPrediction Finish 设置 TrafficPrediction 依赖 INET（非常关键） 现在手动设置 INET 依赖： 右键 TrafficPrediction 点击 Properties 左侧选 Project References 在右边勾选 inet 第 2 步：创建文件夹、文件 项目结构如下： UdpDemo/ │ ├── simulations/ │ ├── SimpleUdpNetwork.ned ← 网络拓扑（重点） │ ├── omnetpp.ini ← 仿真配置（重点） │ └── package.ned ← 自动生成（可以忽略） │ ├── src/ ← 本 demo 不需要写 C++，这个空着 │ └── Makefile ← OMNeT++ 自动管理 SimpleUdpNetwork.ned // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with this program. If not, see http://www.gnu.org/licenses/. // package udpdemo.simulations; import inet.networklayer.configurator.ipv4.Ipv4NetworkConfigurator; import inet.node.inet.StandardHost; import inet.node.inet.Router; network SimpleUdpNetwork { submodules: configurator: Ipv4NetworkCon…

Cursor使用
type: item
date: 2025-10-29T11:45:02+08:00
description: Cursor 插件、环境安装 1）Chinese (Simplified) Language Pack，中文界面插件。 2）Extension Pack for Java 只要安装了 “Extension Pack for Java”，其它插件（Maven、Debugger、Language Support、Test Runner、Project Manager 等）都是它自动帮你装好的，不需要你一个个手动点安装。 这样打开项目文件夹（包含 pom.xml 的根目录）时： 它会自动检测项目类型 → 加载 Maven → 解析依赖。底部出现 Java: Ready、Building [Done]，说明依赖已经下载并索引完毕。默认使用的是系统环境变量MAVEN_HOME的地址。 或者在这里指定： 自动选择jdk版本： 查看pom中配置，Cursor 会用这个版本作为编译目标。 <properties> <java.version>1.8</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> 运行时版本由“系统环境或 Cursor 配置”决定，系统变量里的 JAVA_HOME，就是 你系统默认使用的 JDK。随便打开一个终端 java -version ，可以看到使用的是jdk17。 3） Spring Boot Extension Pack 左侧多出一个 Spring Boot Dashboard； 自动识别所有带 @SpringBootApplication 的项目； 可以直接在面板里点击 ▶️ 启动； application.yml会出现智能提示，比如： spring.datasource.url spring.datasource.username spring.datasource.password 4）IntelliJ IDEA Keybindings 装上它之后，你在 Cursor 里按的快捷键和 IDEA 几乎一样； 5）“Want to launch Cursor from the command line? You can add the code or cursor commands now, or later with Ctrl+Shift+P and typing ‘install code command’.” 这是一个 可选的小功能提示，翻译：“想要从命令行启动 Cursor 吗？你可以现在添加 code 或 cursor 命令，也可以之后按 Ctrl + Shift + P，输入 install code command 来添加。” 作用：直接通过命令行（例如 PowerShell、CMD、终端），打开项目或文件。 cursor . 表示： 用 Cursor 打开当前文件夹（.） 或者：cursor C:\project\group-buying-sys 表示： 用 Cursor 打开指定路径下的项目。 如何查看配置？ Ctrl+shift+P 快捷键，输入 open user settings 可以打开用户配置。 输入 project setting 可以打开项目配置文件 或者左下角JAVA PROJECTS，点击Configure JAVA Runtime： 运行JAVA项目 Maven编译 运行 1）打开启动类，点击run/debug 2） 编辑器界面 ┌────────────────────────────────────────────┐ │ 顶部菜单栏（File / 编辑 / 选择 / 查看...）│ ├────────────────────────────────────────────┤ │ 左侧侧边栏（文件树 / 项目 / Git 等） │ ├────────────────────────────────────────────┤ │ 中间主编辑区（代码编辑） │ ├────────────────────────────────────────────┤ │ 右侧 AI 面板（Cursor 智能助手 / Chat） │ ├────────────────────────────────────────────┤ │ …

deepwalk
type: item
date: 2025-09-20T22:03:49+08:00
description: DeepWalk DeepWalk 的最终目标是—— 把图中的每个节点，用一个低维向量表示（embedding）出来，使得结构相似的节点在向量空间中也接近。 也就是说，如果两个节点在图上经常“一起出现”（相连、同社群等），那它们的 embedding 也应该相似。 主要思想 将图结构转化为“序列语料”： 在图上做 随机游走（random walks），生成顶点序列，类似于自然语言中的“句子”。 将随机游走得到的序列输入 Skip-Gram 模型，学习节点的低维嵌入表示。 学到的嵌入能捕捉到 邻居相似性、社区结构，可用于分类、聚类、链路预测等任务。 输入 & 输出 输入：图结构 $G=(V,E)$，随机游走参数（步长 $t$，次数 $\gamma$，窗口大小 $w$），嵌入维度 $d$。 输出：节点嵌入矩阵 $\Phi \in \mathbb{R}^{|V|\times d}$。 关键公式与目标 随机游走生成“句子”： 从某个顶点 $v_i$ 出发，采样一个长度为 $t$ 的随机游走序列： $$ W_{v_i} = (v_i, v_{i+1}, \dots, v_{i+t}) $$ 生成的序列 $W_{v_i}$ 就是一句“话”，用来训练 Skip-Gram 模型。在这些序列中，如果两个节点经常在相邻位置出现，就表示它们关系密切。 ["A", "B", "C", "D"] Skip-Gram 目标函数： 现在我们用 Word2Vec 的思想：对于一句话 ["A", "B", "C", "D"]，假设窗口大小 $w = 1$，也就是每个节点只看它的邻居。那么训练样本是这样的： 中心节点 它要预测的邻居 A B B A, C C B, D D C 模型要学的是： “给我节点 B，我要能预测出 A 和 C。” “给我节点 C，我要能预测出 B 和 D。” 于是就有这个公式，给定中心节点 $v_i$，最大化其上下文窗口内邻居节点的条件概率： $$ \max_{\Phi} \sum_{i=1}^{|V|} \sum_{u \in \mathcal{N}_w(v_i)} \log Pr(u \mid \Phi(v_i)) $$ 其中 $\mathcal{N}_w(v_i)$ 表示在随机游走序列中，窗口大小 $w$ 内的上下文节点。 我希望模型能学到这样一种 embedding：中心节点 $v_i$ 能够高概率预测出它周围的邻居 $u$。 优化形式（负对数似然）： 就是把上面的最大化目标，改写成一个最小化损失函数。 最大化“好事”（邻居出现的概率）= 最小化“坏事”（邻居预测错误的概率） $$ \min_{\Phi} - \log Pr\big( {v_{i-w},\dots,v_{i+w}} \mid \Phi(v_i) \big) $$ 概率建模（Hierarchical Softmax 或 Negative Sampling）： $$ Pr(u \mid \Phi(v_i)) = \frac{\exp\big( \Phi(u) \cdot \Phi(v_i) \big)}{\sum_{v \in V} \exp\big( \Phi(v) \cdot \Phi(v_i) \big)} $$ 这相当于用 Softmax 把所有节点的相似度转成概率分布。 其中： 分子：中心节点和邻居节点的相似度（点积越大越相似）； 分母：所有节点的相似度和（用来归一化成概率）。 ​ 如果 $u$ 是 $v_i$ 的邻居，那么 $\Phi(u)$ 与 $\Phi(v_i)$ 的点积就应更大。 例子 想象你是个“社交分析师”： 你观察到小明每天都和小红、小刚一起出现； 而小明几乎从不和小李在一起； 那你自然会说：小明和小红、小刚的关系更近。 DeepWalk 就是通过“随机游走 + 预测邻居”这个机制， 自动学出“谁跟谁关系近”的数值表示。 训练逻辑 1）加载 10+1 张图 A_list = [A100, A101, ..., A110] 我们取前 10 张作为输入，最后一张作为真实标签。 2）对每一个时间步的图做 DeepWalk for t in range(100, 110): emb_t = DeepWalk(A_t) 每张图 $A_t$ 都独立训练一个 节点 embedding（比如 400×64）。 400是节点数，64是嵌入维数 embedding 就是每个节点在这一时刻的“语义坐标”。 训练目标是：让在图里常相邻的节点在 embedding 空间也靠得近。 可以理解成： DeepWalk 把图结构变成“节点的向量表示”。 3）拼接成时间序列特征（10步） 对每对节点 (i, j)，你把过去10个时间步的 embedding 拿出来，计算每步的 …

K8S
type: item
date: 2025-09-08T21:56:23+08:00
description: Kubernetes (K8S) Kubernetes 是一个开源的容器编排平台，用于自动化部署、扩缩容（Pod 数量多了/少了自动调整）和自愈（坏掉的 Pod 会被自动重建） 基本架构 一个 Kubernetes 集群 (Cluster) = 控制平面 + 工作节点 的组合。要使用K8S，要先搭建集群，deployment.yaml 和 service.yaml 要提交到 K8S 集群，由它调度和运行。 控制平面 (Control Plane) 负责管理整个集群，不直接跑应用。 组件 作用 比喻 API Server 接收命令（kubectl）、提供统一接口 前台服务员 etcd 存储集群所有状态（配置、Pod 列表等） 账本/数据库 Scheduler 决定 Pod 跑在哪个 Node 上 领班 Controller Manager 保证实际状态符合预期（补 Pod、重建失败的 Pod） 经理 工作节点 (Worker Nodes) 实际跑应用容器。 组件 作用 Kubelet 负责跟 API Server 沟通，并启动/管理容器 容器运行时 运行容器（Docker、containerd） Kube-Proxy 管理网络规则，实现 Service 的负载均衡 graph TD A[控制平面] --> B[Node 1] A --> C[Node 2] A --> D[Node 3] B --> E[Pod] B --> F[Pod] C --> G[Pod] D --> H[Pod] K8S 核心概念 Pod 最小运行单元，一个 Pod 里可以有 1 个或多个容器。 共享网络和存储空间 Deployment 管 Pod 的「副本数」和「版本」。 支持滚动更新、回滚 Service 提供稳定的网络入口（因为 Pod IP 会变）。 负载均衡到一组 Pod。 ConfigMap & Secret ConfigMap：存储配置信息（非敏感）。 Secret：存储敏感信息（密码、Token），会加密。 基本使用方式 Deployment（定义 Pod 模板 + 副本数） apiVersion: apps/v1 kind: Deployment metadata: name: my-app spec: replicas: 3 # 要 3 个 Pod selector: matchLabels: app: my-app template: # Pod 模板 metadata: labels: app: my-app #给 Pod 打标签，Service 用 selector 找到这些 Pod 做负载均衡 spec: containers: - name: my-app #Pod名 image: my-registry/my-app:v1 # ← 指向 CI 推送后的镜像（仓库/名称:标签） ports: - containerPort: 8080 #容器对外提供服务的端口 Pod名可能是：my-app-6f7c9d7c5d-abcde，它里面的容器名：my-app 映射关系： kind: Deployment → 创建一个「Pod 管理器」 replicas: 3 → 保证始终有 3 个 Pod template → Pod 的样子（运行哪个镜像、开哪个端口） Service（提供统一访问入口） apiVersion: v1 kind: Service metadata: name: my-service spec: selector: app: my-app # 找到所有带 app=my-app 标签的 Pod ports: - port: 80 # Service 入口端口 targetPort: 8080 # Pod 里容器的端口 type: LoadBalancer # 暴露给外部访问 映射关系： selector → 绑定到 Deployment 创建的 Pod，根据 Pod 的标签（my-app） ports → 用户访问 80 端口，会转发到 Pod 的 8080 type: LoadBalancer → 提供一个外部 IP 供用户访问 典型工作流程 sequenceDiagram 开发者->>Git: 提交代码 Git->>CI/CD: 触发构建 CI/CD->>镜像仓库: 构建Docker镜像 CI/CD->>K8S: kubectl apply K8S->>K8S: 创建/更新Pod K8S->>K8S: 健康检查 K8S->>用户: 服务可用 sequenceDiagram 开发者->>API Server: kubectl apply -f xxx.yaml API Server->>etcd: 写入期望状态 …

CICD
type: item
date: 2025-09-06T11:28:21+08:00
description: CI/CD 自动部署项目 使用Gitea Actions 1）启用Gitea Actions： 编辑你的Gitea服务器配置文件 app.ini（通常位于 /etc/gitea/或 Gitea 安装目录），添加： [actions] ENABLED = true 然后重启Gitea服务。 2）在部署服务器上安装Runner： # 1. 下载并安装 act_runner (需要sudo) sudo wget https://gitea.com/gitea/act_runner/releases/download/v0.2.10/act_runner-0.2.10-linux-amd64 -O /usr/local/bin/act_runner sudo chmod +x /usr/local/bin/act_runner # 2. 为Runner创建专用工作目录（推荐使用绝对路径） sudo mkdir -p /opt/gitea-runner sudo chown $USER:$USER /opt/gitea-runner # 将目录所有权给当前用户 cd /opt/gitea-runner # 3. 注册Runner（重要：必须添加labels标签） act_runner register --no-interactive \ --instance https://你的gitea域名.com \ --token <你的令牌> \ --name my-runner \ --labels self-hosted,linux # 这个标签必须与工作流文件中的runs-on匹配 # 4. 启动Runner（后台运行） nohup act_runner daemon > runner.log 2>&1 & # 5. 查看运行状态和日志 tail -f runner.log ps aux | grep act_runner 3）令牌获取： 如果你想给整个实例用 → 站点管理员设置 → Actions → Runners。 如果只想给某个仓库用 → 进入该仓库 → Settings → Actions → Runners。 点击 New Runner，系统会生成一个 TOKEN。 例如：abcdef1234567890 还是设置整个实例好！！ 4）将act_runner注册为服务自启动 sudo vim /etc/systemd/system/act_runner.service 写入以下内容： [Unit] Description=Gitea Actions Runner After=network.target [Service] ExecStart=/usr/local/bin/act_runner daemon WorkingDirectory=/opt/gitea-runner User=zy123 Restart=always RestartSec=5 [Install] WantedBy=multi-user.target ExecStart 指向你安装的 act_runner 路径（你已经放在 /usr/local/bin/ 了）。 WorkingDirectory 可以写你打算存放 Runner 缓存的目录（比如 /home/zy123/act_runner，你已经在这里 register 过了）。 User=zy123 保证 Runner 以你当前用户运行，而不是 root。 重新加载 systemd 配置： sudo systemctl daemon-reexec 启动并开机自启: sudo systemctl enable --now act_runner 查看运行状态: systemctl status act_runner 5）在后端仓库根目录下，新建目录和文件： .gitea/workflows/deploy.yml 写入以下内容： name: Deploy Backend on: push: branches: [ "master" ] # master 分支推送时触发 jobs: build-and-deploy: runs-on: self-hosted steps: - name: Checkout code uses: actions/checkout@v3 - name: Create application-local.yml run: | mkdir -p src/main/resources/ cat << 'EOF' > src/main/resources/application-local.yml ${{ secrets.APPLICATION_LOCAL_YML }} EOF - n…

训练神经网络
type: item
date: 2025-08-31T22:22:27+08:00
description: 🧠 神经网络训练流程基础笔记 1. 数据集（Dataset） 数据集包含了 样本 (sample) 和 标签 (label) 在你的场景里： 样本 = 一个时间步的图（节点特征矩阵 + 邻接矩阵） 标签 = 每个节点是否掉线（0/1） 2. Batch（批量） Batch = 一次训练用到的一小部分样本 batch_size 表示 每次梯度更新时用多少个样本 例如： 数据集有 1000 个样本 batch_size=8 → 每次训练只拿 8 个样本来算梯度 这样能减少显存占用，也让模型更新更频繁 3. Epoch（轮次） Epoch = 把整个数据集完整训练一遍 如果： 数据集有 1000 个样本 batch_size=8 那么 1 个 epoch 需要 1000 / 8 = 125 次迭代，才能用完所有样本 训练 20 个 epoch，就相当于把数据重复“看”了 20 遍 4. 训练循环流程 一次完整训练过程一般是这样： 初始化模型参数（随机权重） 重复若干 epoch 打乱训练数据 按 batch_size 切成小批次 对每个 batch： 前向传播 (forward) 把输入样本丢进模型 得到预测结果 计算损失 (loss) 预测 vs 真实标签 的差距 反向传播 (backward) 自动求导，算出梯度 参数更新 (step) 用优化器（SGD/Adam）更新参数，让模型预测更接近标签 最终得到训练好的模型 5. 为什么要用 batch？ 全量训练 (batch_size=1000) 优点：精确 缺点：显存占用大，更新慢 小批量训练 (batch_size=8~32) 优点：节省显存，更新更频繁，收敛快 缺点：梯度有点“噪声”（但通常能帮助模型泛化） 👉 所以主流方法是 小批量训练 + 多个 epoch。 6. 直观理解 把训练比作 学生背单词： 样本 = 单词 batch_size = 一次背多少个单词（8 个单词一组，还是 50 个单词一组） epoch = 把词表完整过一遍（1000 个单词都背一遍） 多个 epoch = 重复背很多遍（记得更牢） 7. 在你现在的任务中 数据：1000 时间步 batch_size=8 → 一次训练 8 个时间步的图 epochs=20 → 每个时间步都要用到，整个过程重复 20 遍 总共更新参数的次数 = 1000/8 * 20 = 2500 次 📌 一句话总结： 训练神经网络 = 前向传播（算预测） + 损失函数（算误差） + 反向传播（算梯度） + 参数更新（优化器） 重复这个过程，按 batch 分批喂数据，按 epoch 控制重复多少轮。

草稿
type: item
date: 2025-08-29T09:13:51+08:00
description: 这是完全匹配你**第一个代码片段（向量化、时间驱动版本）**的文字描述。 这个模型在学术上通常被称为 Time-Discrete Random Walk 或 Memoryless Random Walk（无记忆随机游走），因为它没有“目标点”的概念，每一步都是独立的。 RW（Random Walk，随机游走 - 向量化/时间驱动版） 空间与时间： 正方形区域 $[0, L] \times [0, L]$（其中 $L$ 为 map_size），时间被离散化为固定的 $T$ 个步长（Steps）。 节点运动规则： 初始位置： 在区域内部均匀随机生成所有节点的起始坐标 $(x, y) \sim U(0, L)$。 瞬时移动（核心差异）： 模型不设定任何固定的“目标点”或“行程”。 在每一个时间步 $t$，每个节点都会独立地重新随机选择一个运动方向 $\theta_t \sim U(0, 2\pi)$ 和一个瞬时速度 $v_t \sim U(v_{\min}, v_{\max})$。 位置更新： 根据当前步选定的速度矢量进行位移： $$x_t = x_{t-1} + v_t \cos(\theta_t)$$ $$y_t = y_{t-1} + v_t \sin(\theta_t)$$ 边界处理（物理反射）： 代码实现了完全弹性碰撞（Reflection）。当节点试图跨越边界时，就像台球撞击桌边一样，其坐标会被镜像反弹回区域内（例如：若 $x < 0$，则重置为 $-x$；若 $x > L$，则重置为 $2L - x$），从而保证节点始终被限制在区域内部。 邻接生成： 设定通信半径 comm_radius，计算节点间的欧几里得距离。若距离 $\le$ 阈值则判定为连通，逐步构造邻接矩阵序列。 要点： 无记忆性（Memoryless）： 这一时刻的运动方向与上一时刻完全无关（马尔科夫性 $\alpha=0$ 的极端情况）。 布朗运动特征： 节点的轨迹呈现高度的锯齿状（Zig-zag），缺乏长距离的直线运动。 扩散特性： 相比于有目标点的模型（如 RWP, RD），这种纯随机游走的节点扩散速度较慢，倾向于在局部区域内徘徊较长时间。

RAG知识库
type: item
date: 2025-08-19T22:31:18+08:00
description: Spring AI + Ollama 1. Ollama 定位：本地/容器化的 大模型推理服务引擎 作用：负责加载模型、执行推理、返回结果 支持的模型：Qwen、DeepSeek、nomic-embed-text（embedding 模型）等 交互方式：REST API（默认 http://localhost:11434） ollama run qwen2.5:7b-instruct 2. Spring AI 定位：Spring 官方推出的 AI 接入框架 作用：统一封装对各种 AI 服务的调用逻辑，让开发者更容易接入（OpenAI、Ollama 等） 关键点 OllamaChatModel：封装了调用 Ollama 的对话接口 OllamaOptions：指定模型、参数（温度、上下文大小等） PgVectorStore：对接向量数据库（Spring AI 提供的默认向量数据库适配器。） TokenTextSplitter：默认的文本切分器 （Spring AI 内置逻辑） 3.pgVectorStore pgVectorStore 是 Spring AI 提供的向量存储接口实现，底层基于 PostgreSQL + pgvector 插件。它在项目中的作用： 1）存储向量和元数据： pgVectorStore.accept(splits); 这行代码会： 1.将 splits 中每个 Document 的 text → 调用 embedding 模型 → 生成向量 2.将生成的向量、原始文本、以及文档元数据统一存入数据库表（默认表名：vector_store）； embedding：存储生成的向量； content：存储原始文本内容； metadata：以 JSONB 形式存储元数据。 2）检索时自动生成 SQL： List<Document> documents = pgVectorStore.similaritySearch(request); 在执行检索时，pgVectorStore 会自动生成 SQL 查询， 解析查询请求中的文本； 生成查询向量； 自动构造 SQL（结合 pgvector 的 <-> 向量相似度运算符）； 按相似度排序返回最相关的文档列表。 进一步地，结合 filterExpression（例如 metadata->>'knowledge' = 'xxx'）可在相似度计算的基础上进一步进行条件过滤。 配置 ai: ollama: base-url: http://ollama:11434 #告诉 Spring AI 去 http://ollama:11434 调用模型接口。 embedding: options: num-batch: 512 #批处理参数 model: nomic-embed-text #指定使用的 embedding 模型 rag: embed: nomic-embed-text 注意，需要提前下载模型： ollama pull deepseek-r1:1.5b ollama pull qwen2.5:7b-instruct ollama pull nomic-embed-text ollama list Docker如何开启GPU加速大模型推理 巨坑！ 默认是CPU跑大模型，deepseek1.5b勉强能跑动，但速度很慢，一换qwen2.5:7b模型瞬间就跑不动了，这才发现一直在用CPU跑！！ 如何排查？ 1.查看ollama日志： load_backend: loaded CPU backend from /usr/lib/ollama/libggml-cpu-alderlake.so 2.本地cmd命令行输入，查看显存占用率。 nvidia-smi | 0 NVIDIA GeForce RTX 4060 ... WDDM | 00000000:01:00.0 On | N/A | | N/A 58C P0 24W / 110W | 2261MiB / 8188MiB | 6% Default | 设备状态： RTX 4060显卡驱动（576.02）和CUDA 12.9环境正常 当前GPU利用率仅6%（GPU-Util列） 显存占用2261MB/8188MB（约27.6%） 可见模型推理的时候压根没有用GPU！！！ 解决 参考博客：1-3 Windows Docker Desktop安装与设置docker实现容器GPU加速_windows docker gpu-CSDN博客 1）配置WSL2，打开 PowerShell（以管理员身份运行），执行以下命令： wsl --install -d Ubuntu # 安装 Linux 发行版 wsl --set-default-versi…

拼团设计模式
type: item
date: 2025-08-11T21:40:45+08:00
description: 设计模式 单例模式 懒汉 注意，单例模式的构造函数是私有的！ public class LazySingleton { private static volatile LazySingleton INSTANCE; private LazySingleton() {} public static LazySingleton getInstance() { if (INSTANCE == null) { // 第一次检查 synchronized (LazySingleton.class) { if (INSTANCE == null) { // 第二次检查 INSTANCE = new LazySingleton(); } } } return INSTANCE; } } 第一次检查：防止重复实例化、以及进行synchronized同步块（防止每次加锁的开销）。 第二次检查：防止有多个线程同时通过第一次检查，然后依次进入同步块后，创建N个实例。 volatile：防止指令重排序。 instance = new LazySingleton(); 正确顺序是： memory = allocate(); // 分配内存 ctorInstance(memory); // 调用构造函数，初始化对象 INSTANCE = memory; // 将对象引用赋值给 INSTANCE 由于 JVM 和 CPU 都可能对指令进行优化重排，步骤 ② 和 ③ 的顺序可能被交换！ memory = allocate(); // 分配内存 INSTANCE = memory; // 把引用赋给 INSTANCE（但未初始化完） ctorInstance(memory); // 调用构造函数 线程 A刚执行完赋值（3），但没调用构造函数；此时线程B来了，发现 INSTANCE != null，直接返回这个未初始化完成的对象！！！ 饿汉 public class EagerSingleton { // 类加载时就初始化实例 private static final EagerSingleton INSTANCE = new EagerSingleton(); // 私有构造函数 private EagerSingleton() {} // 全局访问点 public static EagerSingleton getInstance() { return INSTANCE; } } 工厂模式 简单工厂 // 产品接口 interface Product { void use(); } // 具体产品A class ConcreteProductA implements Product { @Override public void use() { System.out.println("使用产品A"); } } // 具体产品B class ConcreteProductB implements Product { @Override public void use() { System.out.println("使用产品B"); } } class SimpleFactory { // 根据参数创建不同的产品 public static Product createProduct(String type) { switch (type) { case "A": return new ConcreteProductA(); case "B": return new ConcreteProductB(); default: throw new IllegalArgumentException("未知产品类型"); } } } public class Client { public static void main(String[] args) { // 通过工厂创建产品 Product productA = SimpleFactory.createProduct("A"); productA.use(); // 输出: 使用产品A Product productB = SimpleFactory.createProduct("B"); productB.use(); // 输出: 使用产品B } } 缺点：添加新产品需要修改工厂类（违反开闭原则） 抽象工厂 抽象工厂模式是一种创建型设计模式，它提供一个接口用于创建相关或依赖对象的家族，而不需要明确指定具体类。 // 抽象产品接口 interface Button { void render(); } interface Checkbox { void render(); } // 具体产品实现 - Window…

测试
type: item
date: 2025-07-31T00:10:03+08:00
description: 测试 小明今天15岁了，它是天水小学上学。