超级的blog - 笔记
type: channel
link: https://echo.xuchaoji.com/index.php/category/note
items: 海量数据更新不卡顿：分帧刷新实战——基于HarmonyOS的Repeat/LazyForEach优化方案
items: 使用Ollama和anythingLLM构建可自定义知识库的本地大模型
items: 华为手机最完美的GMS安装方案-可使用Google Play商店、兼容HarmonyOS Next系统
items: 基于Termux安装Debian和XFCE
items: Centos8无法安装screen的解决方法：使用epel安装screen
items: [树莓派折腾指南] 从安装系统 到 支持离线下载的NAS服务器 (附赠温控风扇和内网穿透教程)
items: 给Linux Shell、Windows powershell和Git设置代理
items: Redis 笔记

海量数据更新不卡顿：分帧刷新实战——基于HarmonyOS的Repeat/LazyForEach优化方案
type: item
date: 2025-08-06T11:03:00+08:00
description: 一、痛点场景：全量更新阻塞主线程 当接口返回不可拆分的大数据集（如几千条数据，每条数据数十个属性）时，使用Repeat/LazyForEach渲染会遇到： 必须在主线程操作：渲染依赖在主线程创建@Observed可观察对象 双重性能消耗：O(n²)复杂度（千级卡片×多属性更新） 线程切换失效：跨线程通信的序列化开销抵消优化收益 整体流程： 此时想优化渲染卡顿，第一时间可能想到的是使用taskPool或worker，通过并发处理数据，避免主线程渲染卡顿，然而在此场景下，由于线程之间无共享内存，线程之间数据同步还涉及序列化和反序列化操作，且线程间通信对象不支持@State装饰器、@Prop装饰器、@Link装饰器等装饰器修饰的复杂类型，数据在其他线程处理完之后，还得回到主线程创建可观察的数据，切换线程只会带来额外的序列化反序列化开销，对整体性能并无优化效果。 问题核心矛盾 无法避免主线程操作：渲染必须使用主线程创建的可观察对象 遍历+赋值双重耗时：O(n²)时间复杂度（1000卡片×数十属性） 数据传递开销：跨线程通信成本可能抵消优化收益 二、优化思路 分离数据计算与渲染 后台线程处理数据计算，差异化部分单独通知到主线程更新（避免在主线程合并全量数据） 减少主线程单次工作量 合并更新批次 + 分帧渲染 方案 效果 成本 跨线程数据计算 理论最优 需重构数据流架构 分帧批量更新 显著改善卡顿 改动量最小 跨线程数据计算虽然理论优化效果最好，但由于需要对代码架构做较大的重构，且实际嵌套的数据结构可能处理起来也会遇到各种坑，因此不在本次尝试范围，分帧、批量更新数据，将大量数据列表的foreach操作，从一整块耗时操作拆分到每一帧之间处理，对整体代码架构的冲击较小，优化成本最低。 2.1 先来看下已有代码结构和实际运行时的trace： CardListComponent import { CardItemComponent } from "./CardItemComponent"; import { CardModel } from "./CardModel"; import { CardViewModel } from "./CardViewModel" import { displaySync } from "@kit.ArkGraphics2D"; import { ToastUtil } from "@pura/harmony-utils"; const TAG: string = 'CardListComponent' @Entry @ComponentV2 export struct CardListComponent { private timerId: number = -1; private readonly FRAME_60: number = 60; private readonly FRAME_120: number = 120; private startTime: number = 0; @Local viewModel: CardViewModel = CardViewModel.getInstance(); aboutToAppear(): void { console.log(TAG, `aboutToAppear, listLenght: ${this.viewModel.cardModelList.length}`); this.timerId = setTimeout(() => { this.viewModel.updateListData() }, 3000) } aboutToDisappear(): void { console.log(TAG, `onHidden`) } build() { Column() { Grid() { Repeat<CardModel>(this.viewModel.cardModelList).each((repeatItem) => { GridItem() { CardItemComponent({repeatCardObj: repeatItem}) } .width('48%') .height('128vp') }) .key((item) => JSON.stringify(item)) .virtualScroll({}) } .padding({ left: '8vp', right: '8vp' }) .columnsGap('8vp') .rowsGap('8vp') .columnsTemplate('1fr 1fr') .layoutDirection(GridDirection.Column) .width('100%') .hei…

使用Ollama和anythingLLM构建可自定义知识库的本地大模型
type: item
date: 2024-09-17T20:29:00+08:00
description: 前言 一、部署 1.1 ollama介绍与安装 macOS Linux Windows docker 1.2 ollama的配置与启动 1.3 部署与运行模型 二、配置与使用 2.1 使用Modefile创建定制模型 什么是 Modelfile？ 创建 Modelfile 的步骤 1. 创建一个新的 Modelfile 2. 使用 Modelfile 创建新模型 3. 运行新创建的模型 2.2 使用rest api与模型进行对话 1. 启动 Ollama 服务 2. 发送请求 示例请求 请求参数 3. 处理响应 4. 高级参数 示例请求（带高级参数） 三、优化 3.1 prompt的定义与优化 什么是 Prompt？ 一个好的 Prompt 应该包含哪些内容？ 示例 Prompt 3.2 通过配置文件参数优化模型内存占用 1. 调整 GPU 层数 2. 使用混合模式 3. 调整模型参数 4. 使用统一内存 5. 设置环境变量 四、进阶 4.1 使用AnythingLLM给大模型投喂知识库 主要特点 支持 RAG（Retrieval-Augmented Generation） 对话模式和查询模式的区别 如何给anythingLLM上传知识库 API 调用示例 1. 获取 API 密钥 2. 发送请求 示例请求：上传文档 示例请求：进行问答 完整的 API 接口文档 主要 API 端点 4.2 自定义训练基本步骤及参考资料 前言 在人工智能迅猛发展的时代，构建和优化大语言模型（LLM）已成为技术前沿的重要课题。本篇文章将带您深入探索如何利用Ollama和anythingLLM，打造一个支持自定义知识库的本地大模型。本文包含Ollama和anythingLLM的安装与配置过程，编写高效prompt的技巧，并提供逐步指导，确保您能够顺利完成安装和配置。 与云端模型相比，本地部署能够显著降低响应时间，提升用户体验。同时，本地化处理数据可以更好地保护用户隐私，避免敏感信息外泄。此外，文章还涵盖了自定义训练模型的基本步骤和参考资料，旨在为您提供实用的应用指南，而非晦涩难懂的理论知识。不论您是初学者还是资深开发者，都能从中汲取有价值的信息和灵感，助力您的项目迈向成功。 一、部署 1.1 ollama介绍与安装 Ollama 是一个开源的 AI 工具(官网、GitHub(ollama))，允许用户在本地运行大型语言模型（LLM）。Ollama 提供了一个轻量级、可扩展的框架，支持在 macOS 和 Linux 系统上运行，并计划未来支持 Windows。用户可以轻松下载和运行预构建的模型，如 Llama 3.1 和 Mistral。此外，Ollama 还支持从 GGUF、PyTorch 或 Safetensors 导入模型，允许用户根据具体需求进行定制。总之，Ollama 为开发者和研究人员提供了一个强大的平台，能够在本地环境中高效地利用大型语言模型。 点击查看：ollama cpu和gpu版本的硬件要求 CPU 版 1. 性能：CPU 版适用于没有 GPU 或 GPU 资源有限的环境。虽然可以运行大型语言模型，但速度相对较慢，尤其是在处理复杂任务时。 2. 硬件要求：需要高性能的多核处理器（如 Intel Xeon 或 AMD Ryzen），并且通常需要较大的系统内存（至少 32 GB）⁴。 3. 适用场景：适合开发、测试和小规模部署。 GPU 版 1. 性能：GPU 版利用 GPU 的并行计算能力，大幅提升模型运行速度。即使是入门级的 GPU（如 NVIDIA RTX 3050），也能显著快于 CPU。 2. 硬件要求：需要支持 CUDA 的 NVIDIA GPU（如 RTX 3080 或更高），显存容量通常在 10GB 到 24GB 之间²。未来计划支持 AMD GPU。 3. 适用场景：适合大规模部署和高性能计算任务，如实时推理和大数据处理。 Ollama 支持在 macOS、Linux 和 Windows 平台上运行。以下是各平台的安装方式： macOS 下载：从 Ollama 官方网站下载 macOS 版本的安装包。 安装：双击下载的安装包并按照提示进行安装。 运行：打开终端，输入 ollama run qwen2 Linux 下载：在终端中运行以下命令下载并安装 Ollama：curl -fsSL https://ollama.com/install.sh | sh 配置：确保已安装并配置好 GPU 驱动程序（如果需要）。 运行：在终端中输入 ollama run llama3.1 以运行模型。 Windows 下载：从 Ollama 官方网站下载 Windows安装包。 安装：双击安装包并按照提示进行安装。 配置：确保 GPU …

华为手机最完美的GMS安装方案-可使用Google Play商店、兼容HarmonyOS Next系统
type: item
date: 2024-08-09T22:15:00+08:00
description: 一、MicroG介绍 1.1 优点 1.2 缺点 二、下载 三、添加账号 四、配置应用商店 4.1 下载Aurora Store 4.2 使用电脑管家恢复谷歌服务助手并安装Play Store 一、MicroG介绍 MicroG 是一个开源项目，旨在替代 Google Play 服务，允许用户在没有 Google 追踪的情况下使用 Google 的 API 和服务。 1.1 优点 隐私保护：MicroG 不会跟踪用户活动，提供了更高的隐私保护。 节省电量：由于 MicroG 不会像 Google Play 服务那样频繁地运行后台进程，因此可以显著减少电池消耗。 开源：MicroG 是完全开源的，用户可以查看和修改代码，确保没有隐藏的追踪或其他不良行为。 兼容性：MicroG 允许许多依赖 Google 服务的应用程序在没有 Google Play 服务的情况下运行。 1.2 缺点 兼容性问题：尽管 MicroG 支持许多应用，但某些高度依赖 Google Play 服务的应用可能无法正常运行。 设置复杂：安装和配置 MicroG 可能需要一定的技术知识，尤其是需要进行代码签名欺骗来模拟 Google Play 服务。 功能限制：某些 Google 服务的高级功能可能无法通过 MicroG 实现。 实测普通依赖GMS的应用（Google Map、YouTube、X、Telegram等）可以正常使用，购买的应用高级功能（如JuiceSSH专业版可以正常验证使用），部分付费游戏（如Minecraft，下载后会提示安装有问题，可以通过GBox或者参考4.2章节安装Google Play来使用这部分异常的应用） 不确定是microG做了什么骚操作，在HarmonyOS 4.x版本后的系统上安装后签名伪装默认可用了，因此可以通过MicroG来替换GMS官方套件。 在HarmonyOS next版本上, 由于不兼容Android应用，无法原生使用，但是可以下载出境易和卓易通，出境易内置的虚拟机内置了microG。 二、下载 前往microG下载页面，下载Services Framework Proxy、com.google.android.gms-hw和com.android.vending-hw三个安装包并安装： 三、添加账号 到设置>应用和服务>应用管理，找到microG服务，点击右上角的小齿轮，点开microG的设置页面，先进入自我检查页面授予microG相关权限，然后在点击账号页面添加账号。 四、配置应用商店 microG提供的com.android.vending-hw即microg companion是个与Google Play Store包名相同的空应用，所以无法覆盖安装Google Play Store,这里有两种替代方案：使用Aurora Store（支持登录Google Play Store，支持下载已付费应用），使用电脑通过手机管家回复Google服务助手到手机上，并安装Google Play Store。 4.1 下载Aurora Store 前往f-droid的AuroraStore下载页面，下载安装包并安装，登录方式选择Google 4.2 使用电脑管家恢复谷歌服务助手并安装Play Store 下载恢复相关的备份文件和华为手机助手 在手机设置中关闭自动设置时间，并将时间设置为2019年1月1日。 在电脑上安装并打开华为手机助手，并根据提示连接手机 点击数据恢复，选择下载备份文件目录，点击开始恢复，密码如提示。 安装备份文件中的GooglePlay apk 如提示安装失败，需要卸载已安装的microG Companion再重试。 在手机上打开谷歌服务助手，点击激活。 重启手机。 恢复自动设置时间，此时即可使用Google Play。

基于Termux安装Debian和XFCE
type: item
date: 2022-08-31T21:46:00+08:00
description: Termux中通过proot-distro安装Debian，并在Debian中安装XFCE。 安装Debian： 安装proot-distro pkg install proot-distro 安装debian proot-distro install debian 配置XFCE 登录Debian proot-distro login debian 安装基础工具包 apt-get update && apt install xfce4-goodies xfce4-terminal tightvncserver -y 编辑vnc配置文件 创建vnc配置文件，mkdir ~/.vnc && touch ~/.vnc/xstartup, vim ~/.vnc/xstartup, 复制以下内容： #!/bin/sh if [ -f $HOME/.Xresources ]; then xrdb "$HOME/.Xresources" fi xsetroot -solid grey # Fix to make GNOME work export XKL_XMODMAP_DISABLE=1 /etc/X11/Xsession dbus-launch --exit-with-session startxfce4 & 启动VNCServer vncserver :1 使用客户端连接，使用:1开启的VNCServer，端口是：5901 杀掉VNCServer的命令 vncserver -kill :1, 其中:1是启动时指定的

Centos8无法安装screen的解决方法：使用epel安装screen
type: item
date: 2020-02-05T23:49:00+08:00
description: !!! /*620*380 创建于 2020-09-23*/ var cpro_id = "u6274467"; !!! 选择了一个基础款的vps安装的镜像选了熟悉的centos的最新版centos8，但是在安装screen的时候，却安装不了，提示： No match for argument: screen Centos8安装screen需要使用epel来安装，安装epel后，再安装screen，解决centos8无法安装screen的问题。 1、安装epel sudo yum install epel-release 2、安装screen sudo yum install screen

[树莓派折腾指南] 从安装系统 到 支持离线下载的NAS服务器 (附赠温控风扇和内网穿透教程)
type: item
date: 2019-07-11T11:41:00+08:00
description: 一、树莓派的简介 1.1树莓派的历史与发展 (废话部分，已删减99.5%内容) 1.2 树莓派的硬件配置 1.2.1主要接口 1.2.2 GPIO引脚 1.3 操作系统 1.3.1 OS与Raspberry Pi各型号关系 1.3.2 Raspberry Pi官方OS 1.3.3 NOOBS 二、系统的安装和基本操作 2.1 安装Raspbian 2.1.1 下载Raspbian 2.1.2 将raspbian写入TF卡 2.1.3 使用SSH客户端连接到树莓派 2.1.4 使用root登录 2.2 树莓派的常用操作 2.2.1 raspi-config 2.2.2 连接wifi 2.2.3 更改时区 三、挂载硬盘和SMB服务器的配置 3.1 树莓派挂载NTFS格式的硬盘 3.2 Samba服务 四、BT下载机的安装和配置 安装和配置Transmission 五、frp内网穿透服务 5.1 下载frp 5.2 frp服务端配置 5.2 frp 客户端的配置 温控风扇 完结撒花 6月份的时候挖了个坑，说搞个树莓派折腾教程，找了一堆资源，结合自己之前的笔记，搞了个小总结，可是转移到博客实在是麻烦，好多图需要上传，就搁置了下来。现在树莓派4各个版本都有现货了，似乎到我填坑的时候了。本文总结了我自己折腾树莓派的一些经验和笔记，经过一番折腾，树莓派可以实现局域网下的SMB服务器共享视频播放，同时可以实现离线下载bt任务，配合内网穿透，即使不在家，也可以随时访问树莓派添加离线下载任务，服务器带宽足的话，也是可以远程播放树莓派上的视频的。大部分在网上都是能找到的，先在前面把各个部分用到的软件说一下，不按照此教程，自己去搜相关资料也完全可以。 主要分为： 系统安装 开启root用户登录 挂载NTFS硬盘 SMB服务的安装和配置 BT下载服务的安装和配置 内网穿透frp服务的安装和配置 开机自启和定时任务 如使用中遇到问题或文中有错误，请联系邮件联系我admin@xuchaoji.com !!! (adsbygoogle = window.adsbygoogle || []).push({}); !!! 一、树莓派的简介 1.1树莓派的历史与发展 (废话部分，已删减99.5%内容) 树莓派（英语：Raspberry Pi），是一款基于Linux的单片机计算机。它由英国的树莓派基金会所开发，目的是以低价硬件及自由软件促进学校的基本计算机科学教育。[1-5] 1.2 树莓派的硬件配置 最初销售的树莓派是B型，计划2013年早些时候推出A型。A型有一个USB接口，并没有以太网控制器，成本将小于B型（有两个USB端口和一个10/100以太网控制器）。 !!! 图1.1 B型的模块框图；A型没有最下面的两个模块 (Ethernet实际上是接在USB HUB上的网卡) !!! 在2012年9月5日，修订版2.0的板子被公布，有一些较小的修正和改进。14 在2012年10月15日，树莓派基金会宣布所有新的树莓派的B型将配有512MB RAM芯片，而不是256MB。15 1.2.1主要接口 树莓派提供了丰富的扩展接口：USB、HDMI、GPIO等，图1.2为树莓派B型的示意图。 !!! 图1.2 树莓派B型硬件示意图 !!! 1.2.2 GPIO引脚 通用IO口 (General-Purpose IO ports, GPIO) 利用工业标准I2C、SMBus或SPI接口简化了I/O口的扩展。当微控制器或芯片组没有足够的I/O端口，或当系统需要采用远端串行通信或控制时，GPIO能够提供额外的控制和监视功能。 !!! 图1.3 历代树莓派[16] !!! 通过上文的全家福，你可以很容易找出手里的Raspberry Pi 对应的GPIO接口参数表。常见的 Raspberry Pi 接口数量分为两种一种26针，一种40针，根据自己手里的 Pi 即可。通过GPIO引脚，可以实现各种硬件的扩展，如温控风扇、智能小车等。 !!! 图1.4 树莓派GPIO引脚 !!! 1.3 操作系统 树莓派主要使用以Linux內核的操作系统，当前 Raspbian 是 Raspberry Pi 所有型号的官方操作系统，此外还有Ubuntu、Windows 10 IOT 等第三方系统。 1.3.1 OS与Raspberry Pi各型号关系 树莓派1搭载了基于ARMv6架构的ARM11芯片。当前的几个流行的Linux版本，包括Ubuntu在内，均不能在ARM11上运行，Windows无法在未改装的树莓派上运行。 树莓派2当前只支持Ubuntu Snappy Core、Raspbian、OpenELEC和RISC OS，树莓派2和3已经可以运行"Windows 10 物联网核心版"，同时树莓派3…

给Linux Shell、Windows powershell和Git设置代理
type: item
date: 2019-05-16T22:02:00+08:00
description: 在编译Spigot服务端的时候频繁遇到访问github太慢导致卡住的情况，虽然可以通过路由插件来加速，但毕竟不是长久之计。所以本文整理了 Windows 命令行 和 Linux 终端以及 Git 中设置代理的命令。以本地 HTTP/HTTPS 代理 127.0.0.1:8118 和 SOCKS5 代理 127.0.0.1:1080 为例。 Windows 命令行代理设置 HTTP 代理设置： set http_proxy=http://127.0.0.1:8118 set https_proxy=http://127.0.0.1:8118 SOCKS5 代理设置： set http_proxy=socks5://127.0.0.1:1080 set https_proxy=socks5://127.0.0.1:1080 可以通过 echo %http_proxy% 命令查看是否设置成功。 取消代理设置： set http_proxy= set https_proxy= Linux 终端代理设置 临时代理设置 Linux 终端设置 HTTP 代理（只对当前终端有效）： $ export http_proxy=http://127.0.0.1:8118 $ export https_proxy=http://127.0.0.1:8118 Linux 中设置 SOCKS5 代理（只对当前终端有效）： $ export http_proxy=socks5://127.0.0.1:1080 $ export https_proxy=socks5://127.0.0.1:1080 设置终端中的 wget、curl 等都走 SOCKS5 代理（只对当前终端有效）： $ export ALL_PROXY=socks5://127.0.0.1:1080 Linux 终端中取消代理设置： $ unset http_proxy $ unset https_proxy $ unset ALL_RPOXY 永久代理设置 将代理命令写入配置文件 ~/.profile 或 ~/.bashrc 或 ~/.zshrc 中： HTTP 代理设置 export http_proxy=http://127.0.0.1:8118 export https_proxy=http://127.0.0.1:8118 或 SOCKS5 代理设置 export http_proxy=socks5://127.0.0.1:1080 export https_proxy=socks5://127.0.0.1:1080 或 强制终端中的 wget、curl 等都走 SOCKS5 代理 export ALL_PROXY=socks5://127.0.0.1:1080 Git 设置代理 代理格式 [protocol://][user[:password]@]proxyhost[:port] 参考 https://git-scm.com/docs/git-config 设置 HTTP 代理： git config --global http.proxy http://127.0.0.1:8118 git config --global https.proxy http://127.0.0.1:8118 设置 SOCKS5 代理： git config --global http.proxy socks5://127.0.0.1:1080 git config --global https.proxy socks5://127.0.0.1:1080 Git 取消代理设置： git config --global --unset http.proxy git config --global --unset https.proxy !!! !!!

Redis 笔记
type: item
date: 2018-08-16T19:14:00+08:00
description: NoSQL概述 Not Only SQL 非关系型数据库 为什么需要NoSQL 高并发读写 High Performance 海量数据的高效率存储和访问 Huge Storage 高可扩展性和高可用性 High Scalability && High Availability NoSQL数据库的四大分类 键值存储 key-value 快速查询 数据缺少结构化 列存储 查找速度快，扩展方便 功能局限 文档数据库 数据结构要求不是很严格 查询性能不好，缺乏统一的查询语法 图形数据库 利用图结构相关算法 需要对整个图做计算才能得出结果，不易做分布式集群方案 NoSQL特点 易扩展 灵活的数据模型 大数据量，高性能 高可用 Redis的概述 高性能键值对数据库。 支持的键值数据类型： 字符串类型 列表类型 有序集合类型 散列类型 集合类型 Redis应用场景 缓存 任务队列 网站访问统计 数据过期处理 分布式集群架构中的session分离 应用排行榜 ... Redis的安装和使用 常用操作 新增 set name chaoji 获取 get name 删除 del name 查询所有key keys * Jedis的入门 jedis是Redis官方推荐的java客户端开发包 package com.xuchaoji.jedisdemo; import org.junit.Test; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; public class JedisDemo1 { @Test public void demo1() { //设置ip和端口 Jedis jedis = new Jedis("us1.xuchaoji.com",6379); //保存数据 jedis.set("name", "chaoji"); //获取数据 String value=jedis.get("name"); System.out.println(value); //释放资源 jedis.close(); } /** * 使用连接池方式连接 */ @Test public void demo2() { //获得连接池对象 JedisPoolConfig config = new JedisPoolConfig(); //设置最大连接数 config.setMaxTotal(30); //设置最大空闲连接数 config.setMaxIdle(10); //获得连接池 JedisPool jedisPool = new JedisPool(config,"us1.xuchaoji.com",6379); //获得核心对象 Jedis jedis = null; try { //通过连接池获得连接 jedis = jedisPool.getResource(); jedis.set("age", "25"); System.out.println(jedis.get("age")); }catch(Exception e) { e.printStackTrace(); }finally { if(jedis !=null ) { jedis.close(); } if(jedisPool != null ) { jedisPool.close(); } } } } Redis的数据类型 Redis的数据结构 五种数据类型： 字符串（String） 哈希（hash） 字符串列表（list） 字符串集合（set） 有序字符串集合（sorted set） key定义注意点 不要过长或过短 最好有统一的命名规范 存储String 二进制安全，存入和获取的数据相同 value最多可以容纳的数据长度是512M存储String常用命令 赋值 set key value getset key value //先获取、再赋值 取值 get key 删除 del key 数值增减 incr number //将值+1，若类型不能转换为int，会报错。若不存在对应的key，会创建，key，value默认为0,然后+1 decr number //-1 扩展命令 incrby num 5 //增加5 decrby num 5 //减少5 append key 1234 //在key后追加1234字符串 存储Hash String key 和String value的map容器。每一个hash可以存储4294967295个键值对 存储Hash常用命令 赋值 hset myhash name …