博客 (88)

本文系 AI 生成,仅供参考,不保证准确性,实战中务必将结果与专业软件中的数据进行对比。


在量化交易和股票数据分析中,“复权”是一个绕不开的核心概念。很多新手在搭建自己的数据库或编写策略时,常常因为复权处理不当,导致回测结果失真、技术指标错位,甚至引发系统性的计算灾难。

本文将从底层逻辑出发,用大白话为你讲透复权的本质,并提供一套成熟、高效的数据库与指标设计方案,帮你完美避开各种“坑”。

一、股票中的“复权”是什么意思?

简单来说,复权是为了消除股票因分红、送股、配股等除权除息事件造成的K线价格“断崖式”缺口。

当一家公司实施“10 送 10”时,股票数量翻倍,股价理论上会直接“腰斩”。如果看原始数据,K 线图上会出现一个巨大的向下跳空缺口。复权就是通过按比例调整历史价格,把这种非交易因素造成的断层“修复”,使股票的历史走势在图表上保持连续,从而真实反映投资者的累计收益和趋势变化。

二、如何计算复权因子?

复权因子本质上就是除权前后的价格比例,但不同数据源的定义方向恰好相反:

          BaoStock 算法:复权因子 = 除权后价格 ÷ 除权前价格(结果小于 1,如 10 ÷ 20 = 0.5)。

          掘金量化算法:复权因子 = 除权前价格 ÷ 除权后价格(结果大于 1,如 20 ÷ 10 = 2)。

无论哪种定义,其核心作用都是作为一个乘数,用于在不同历史价格之间进行等比换算。

三、将股票历史价格保存到数据库中时,建议使用真实价格还是复权价格?

强烈建议:只保存不复权的真实价格和复权因子。

前复权价格是一个动态变化的值(以当前最新价格为基准)。如果直接存储前复权价格,每次股票发生新的除权除息,你都需要把过去所有的历史价格全部重算并覆盖更新,维护成本极高且极易出错。而真实价格和复权因子是客观静态的,只需每天增量追加,历史数据永远无需修改。

四、以MA5为例,如何计算和保存指标价格?

遵循 “底层存真实指标,前端按需乘因子” 的原则:

          计算与存储:永远使用“真实价格”来计算 MA5,并将结果存入数据库。这样历史指标是客观事实,无需因复权而重算。

          展示与应用:在看盘或跑策略时,将数据库中的真实 MA5 乘以“当前的复权因子”,即可动态映射出完美的复权 MA5。

举个例子:某 6 天的真实价格是 20,21,22,23,24,12,其中最后一天进行了除权,且假设这天没涨没跌,掘金因子是24/12=2,这样的话,倒数据第 2 天的 MA5 是 (20+21+22+23+24)/5=22,最后一天的 MA5 是 (21/2+22/2+23/2+24/2+12)/5=11.4,所以数据库中这两天的 MA5 值分别是 22 和 11.4 。复权因子同样适用于 MA5 值,即从最后一天看,其前一天的前复权 MA5 值是 22/2=11。

五、如何解决复权因子与四舍五入叠加产生的偏差问题?

核心原则是 “真实价格负责算钱,复权价格负责算趋势” (实盘中):

          交易与风控层:涉及真实盈亏、涨跌停价计算、下单挂单等,必须使用精确到两位小数的“真实价格”。

          研究与回测层:涉及画K线图、计算 MA 等趋势指标时,才使用复权价格。此时允许存在极微小的尾数误差(如 1 分钱),因为技术指标看的是宏观趋势,微小偏差对信号毫无影响。

举个例子:真实价格 12.34(2位小数),复权因子 0.965678,前复权价格 12.34 × 0.965678 = 11.91646652(8 位小数)

如果你用这个 11.91646652 去算涨停价:11.91646652 × 1.1 = 13.108113172,四舍五入变成 13.11。

但是,真实的涨停价是 13.57,它的前复权价应该是:13.57 × 0.965678 = 13.10429046,四舍五入变成 13.10。

六、前复权与后复权在实际应用中该如何选择?

          前复权:以当前最新价格为基准,向下平移历史价格。优点是最新价格与真实交易价格一致,适合看近期K线走势、分析短期技术形态。

          后复权:以历史最早价格为基准,向上放大最新价格。优点是能真实反映上市以来的累计涨幅,适合计算长期累计收益率、评估长线投资价值。

附:复权因子计算实战案例(小白秒懂版)

【场景设定】

假设某只股票在 T-1 日的收盘价是 20元

T 日公司宣布“10 送 10”,股价直接“腰斩”变成 10元。假设 T 日当天市场不涨不跌,实际收盘价依然是 10元。

1. 复权因子怎么算?

          BaoStock算法:10 ÷ 20 = 0.5

          掘金量化算法:20 ÷ 10 = 2

2. 前复权怎么算?

前复权的核心是:T 日的 10元 保持不变,把 T-1 日的价格乘以 BaoStock 的因子(0.5)。

          T-1 日前复权价 = 20 × 0.5 = 10元

          T 日前复权价 = 10元(因为T日是基准日,保持不变)最终结果:T-1 日是 10元,T 日是 10元。K 线图完美连续,没有缺口。

3. 后复权怎么算?

后复权的核心是:T-1 日的 20元 保持不变,把 T 日的价格乘以掘金的因子(2)。

          T-1 日后复权价 = 20元

          T 日后复权价 = 10 × 2 = 20元最终结果:T-1 日是 20元,T 日是 20元。K 线图同样连续,反映了你“虽然股价没涨,但手里股票翻倍了,总资产没变”的真实情况。

4. 技术指标(以 MA2 为例)怎么算?

          数据库里存什么? 存真实价格算出来的指标。

       T-1 日前复权价格 = 20 × 0.5 = 10

       T 日前复权价格 = 10(前复权以当日为基准,保持真实价格不变)

       T 日真实 MA2 = (10 + 10) ÷ 2 = 10

【一句话总结】

复权只是数学游戏。真实价格负责算钱,复权价格负责看趋势;数据库里只存真实指标,看盘时再乘因子映射。

(AI 生成)


xoyozo 8 天前
96

Ollama 跑大模型生成太慢,未使用独立显卡 GPU 0 NVIDIA GPU,而 GPU 1 Intel Graphics 使用率 100%,内存几乎占满,CPU 使用率也异常高,怎么办?如何改为用英伟达独立显卡来跑?

打开 NVIDIA 控制面板(NVIDIA Control Panel),展开左侧菜单中的“3D 设置”,点击“管理 3D 设置”,切到“程序设置”选项卡,在下拉框中选择 llama-server.exe 这个程序,为此程序选择首选图形处理器改为“高性能 NVIDIA 处理器”,点击右下角的“应用”保存设置。

image.png

重启 Ollama。

使用 Ollama,即可在“NVIDIA GPU 活动”中看到 llama-server.exe。

image.png

xoyozo 1 个月前
313

问题复现

使用 .NET Framework 开发的网站项目,用 QQ 浏览器访问无法登录成功,用其它浏览器(如 Edge)没有问题。

只有访问 https 地址时出现问题。


原因

在 HTTPS 协议下,现代浏览器(特别是 QQ 浏览器)会强制执行安全策略。根据规范,当 Cookie 设置了 SameSite=None 时,必须同时设置 Secure 属性,否则浏览器会静默拒绝(丢弃)该 Cookie。


解决方案

方法一:如果您是通过 web.config 配置的,请确保 <system.web> 节点下的 <httpCookies> 设置正确,并且您的 .NET Framework 版本支持这些属性(4.7.2+)。

<system.web>
    <httpCookies sameSite="None" requireSSL="true" />
    <sessionState ... />
</system.web>

方法二:在 Global.asax 文件的 Application_PostAuthenticateRequest 或 Application_EndRequest 事件中,强制为 Cookie 添加 Secure 属性。

protected void Application_PostAuthenticateRequest(object sender, EventArgs e)
{
    // 仅在 HTTPS 环境下处理
    if (Request.IsSecureConnection)
    {
        HttpCookie sessionCookie = Response.Cookies["ASP.NET_SessionId"];
        if (sessionCookie != null)
        {
            // 强制设置 SameSite=None 和 Secure
            sessionCookie.SameSite = SameSiteMode.None;
            sessionCookie.Secure = true; 
            Response.Cookies.Set(sessionCookie);
        }
    }
}


检验

确认 Set-Cookie 的值变为:

ASP.NET_SessionId=...; path=/; HttpOnly; SameSite=None; Secure


xoyozo 2 个月前
249

以下是 Spectre.Console 的核心功能示例,涵盖最常用的输出和交互场景:


1. 基础富文本输出

image.png

using Spectre.Console;

// 使用 Markup 语法(类似 BBCode)
AnsiConsole.Markup("[bold green]成功![/] 文件已保存。\n");
AnsiConsole.Markup("[red]错误:[/] 无法连接到服务器。\n");

// 混合样式
AnsiConsole.Markup("[underline blue]https://example.com[/]\n");

// 自动换行写
AnsiConsole.Write(new Panel("[yellow]警告[/] 磁盘空间不足")
    .Header("系统通知")
    .Border(BoxBorder.Rounded));


2. 表格

image.png

var table = new Table();
table.AddColumn("[u]ID[/]");
table.AddColumn(new TableColumn("[u]名称[/]").Centered());
table.AddColumn("[u]状态[/]");

table.AddRow("1", "订单服务", "[green]运行中[/]");
table.AddRow("2", "支付网关", "[red]离线[/]");
table.AddRow("3", "消息队列", "[yellow]警告[/]");

AnsiConsole.Write(table);


3. 进度条 / 状态指示

image.pngimage.png

// 带进度条的循环任务
await AnsiConsole.Progress()
    .StartAsync(async ctx =>
    {
        var task1 = ctx.AddTask("[green]下载文件[/]", maxValue: 100);
        var task2 = ctx.AddTask("[green]处理数据[/]", maxValue: 100);

        while (!ctx.IsFinished)
        {
            task1.Increment(1.5);
            task2.Increment(0.8);
            await Task.Delay(50);
        }
    });

// 不确定时长的旋转状态
await AnsiConsole.Status()
    .StartAsync("正在连接...", async ctx =>
    {
        await Task.Delay(3000); // 模拟工作
        AnsiConsole.MarkupLine("[green]连接成功![/]");
    });


4. 交互式提示

image.png

// 确认
if (AnsiConsole.Confirm("是否继续安装?"))
{
    // 执行安装
}

// 文本输入(带验证)
var name = AnsiConsole.Prompt(
    new TextPrompt<string>("请输入用户名:")
        .ValidationErrorMessage("[red]用户名不能为空[/]")
        .Validate(input => !string.IsNullOrWhiteSpace(input)));

// 选择列表
var fruit = AnsiConsole.Prompt(
    new SelectionPrompt<string>()
        .Title("请选择最喜欢的水果")
        .AddChoices(new[] { "苹果", "香蕉", "橙子", "葡萄" }));

AnsiConsole.MarkupLine($"你选择了:[green]{fruit}[/]");

// 多选
var colors = AnsiConsole.Prompt(
    new MultiSelectionPrompt<string>()
        .Title("请选择颜色")
        .AddChoices(new[] { "红色", "绿色", "蓝色", "黄色" }));


5. 树形结构

image.png

var root = new Tree("[yellow]项目结构[/]");
var src = root.AddNode("src");
src.AddNode("Program.cs");
src.AddNode("Services");
src.AddNode("Models");

var tests = root.AddNode("tests");
tests.AddNode("UnitTests");

AnsiConsole.Write(root);


6. 布局 / 网格

image.png

var layout = new Layout("Root")
    .SplitColumns(
        new Layout("Left").Size(30),
        new Layout("Right")
            .SplitRows(
                new Layout("Top"),
                new Layout("Bottom")));

layout["Left"].Update(new Panel("导航栏"));
layout["Top"].Update(new Panel("主内容区"));
layout["Bottom"].Update(new Panel("日志输出"));

AnsiConsole.Write(layout);


7. 实时更新

image.png

var table = new Table().AddColumn("Time").AddColumn("Message");
table.AddRow("10:00", "系统启动");

await AnsiConsole.Live(table)
    .StartAsync(async ctx =>
    {
        for (int i = 1; i <= 5; i++)
        {
            await Task.Delay(1000);
            table.AddRow($"10:0{i}", $"事件 {i}");
            ctx.Refresh(); // 刷新显示
        }
    });


8. 带样式的异常显示

image.png

try
{
    throw new InvalidOperationException("操作失败");
}
catch (Exception ex)
{
    AnsiConsole.WriteException(ex, ExceptionFormats.ShortenPaths);
}


9. 日历

image.png

var calendar = new Calendar(2026, 4);
calendar.AddCalendarEvent(2026, 4, 22); // 标记日期
calendar.HighlightStyle(Style.Parse("yellow bold"));
AnsiConsole.Write(calendar);


10. 条形图 / 柱状图

image.png

AnsiConsole.Write(new BarChart()
    .Width(60)
    .Label("[green bold]项目进度[/]")
    .CenterLabel()
    .AddItem("后端", 80, Color.Green)
    .AddItem("前端", 65, Color.Blue)
    .AddItem("测试", 40, Color.Red));


11. 分解图

image.png

AnsiConsole.Write(new BreakdownChart()
    .Width(60)
    .AddItem("CPU", 45, Color.Red)
    .AddItem("内存", 30, Color.Blue)
    .AddItem("磁盘", 25, Color.Green));


12. 规则线

image.png

AnsiConsole.Write(new Rule("[red]警告区域[/]").RuleStyle("red").LeftJustified());
AnsiConsole.WriteLine("内容");
AnsiConsole.Write(new Rule().RuleStyle("green"));


13. 文本样式

image.png

// 大字标题
AnsiConsole.Write(new FigletText("Hello").Color(Color.Green));
// Emoji
AnsiConsole.Markup(":check_mark_button: 成功 :cross_mark: 失败");


14. 网格

image.png

var grid = new Grid();
grid.AddColumn(new GridColumn().NoWrap().PadRight(4));
grid.AddColumn();

grid.AddRow("[b]名称[/]", "Spectre.Console");
grid.AddRow("[b]版本[/]", "0.49.1");
grid.AddRow("[b]许可[/]", "MIT");

AnsiConsole.Write(grid);






xoyozo 3 个月前
425

我来为你整理 Windows 本地部署 OpenClaw 并通过长连接方式接入企业微信的完整步骤:

前置条件

  • 已安装企业微信最新版客户端

  • 已安装 OpenClaw(Node.js 版本需 ≥ 22.0)

  • 管理员权限的企业微信账号(否则看不到 API 模式选项)

第一步:在企业微信创建长连接机器人

  1. 打开企业微信客户端 → 工作台 → 智能机器人 → 创建机器人

  2. 点击底部小字 "如需使用自有系统获取成员与机器人的聊天并输出回复,可切换至 API 模式创建"

  3. 选择 「长连接」 方式(不要选 Webhook 回调模式)

  4. 复制保存生成的 Bot ID 和 Secret(后续需要用到)

  5. 先不要点击保存,保持页面打开,等完成 OpenClaw 配对后再保存 

第二步:Windows 本地安装企微插件

打开 PowerShell 或 命令提示符,依次执行以下命令:

1. 安装企业微信插件

openclaw plugins install @wecom/wecom-openclaw-plugin

如果安装失败,可尝试备用命令: openclaw plugins install @tencent/openclaw-wecom

2. 重启 OpenClaw 网关

openclaw gateway start

重要:这个窗口不能关闭,关闭后机器人会掉线。需要再新开一个终端窗口执行后续命令。

3. 添加企业微信渠道

在新开的终端窗口执行:

openclaw channels add

按提示操作:

  1. 用方向键选择 企业微信(WeCom) → 回车

  2. 粘贴输入 Bot ID → 回车

  3. 粘贴输入 Secret → 回车

  4. 选择 Finished/Done 完成基础配置

  5. 配对方式选择 Pairing

第三步:完成配对授权

1. 回到企业微信,找到刚创建的机器人,发送任意消息(如"你好")

2. 机器人会自动回复一条配对码消息(包含授权命令)

3. 复制消息最后一行的配对码

4. 在终端中执行配对命令:

openclaw pairing approve openclaw-wecom 你的配对码

5. 提示"授权成功"即完成配对

第四步:保存并启用机器人

1. 回到企业微信机器人配置页面,点击 保存并创建

2. 现在可以在企业微信中与机器人正常对话了

长连接 vs 回调模式的优势

特性长连接模式传统回调模式
公网IP/域名❌不需要✅必须需要
内网穿透❌不需要✅必须配置
消息加解密❌无需处理✅需要处理
稳定性高(无回调失败问题)低(经常回调失败)
主动推送
✅支持✅支持

常见问题

问题解决方案
没有 API 模式选项确认你是企业微信管理员,普通成员看不到该选项
插件安装失败检查网络连接,或尝试切换 npm 镜像源: npm config set registry https://registry.npmmirror.com/
配对码无法获取确认选择了 API 模式和长连接,重启 OpenClaw 后重试
机器人不回复检查网关窗口是否保持运行,重新执行配对命令
需要 7×24 小时在线建议部署到云服务器,本地关机后机器人会离线

命令速查表

# 安装插件
openclaw plugins install @wecom/wecom-openclaw-plugin

# 启动网关(窗口不能关)
openclaw gateway start

# 添加渠道
openclaw channels add

# 配对授权
openclaw pairing approve openclaw-wecom 【配对码】

# 重启服务
openclaw gateway restart

# 查看状态
openclaw channels status

配置完成后,你就可以在企业微信中与 OpenClaw 对话了。如果需要让个人微信也能使用,可以在企业微信后台 "我的企业" → "微信插件" 中生成二维码,用个人微信扫码关注企业即可。

xoyozo 4 个月前
3,136

在MySQL中,没有单条SQL语句能直接优化和修复所有表。不过,有以下两种常用方法可以实现这个需求:

1. 使用MySQL命令行工具:

mysqlcheck -u root -p --auto-repair --optimize --all-databases

这条命令会提示输入密码,然后自动修复并优化所有数据库中的所有表。

2. 如果确实需要在MySQL客户端内执行,可以生成批处理语句:

SELECT CONCAT('OPTIMIZE TABLE ', table_schema, '.', table_name, '; REPAIR TABLE ', table_schema, '.', table_name, ';') 
FROM information_schema.tables 
WHERE table_schema NOT IN ('information_schema','mysql','performance_schema','sys');

执行此查询后,复制结果中的所有语句再执行。

注意:执行表优化和修复操作需要相应权限,且在高负载生产环境中应谨慎操作,最好在低峰期进行。

xoyozo 6 个月前
567

个人整理,仅供参考。具体规格请以官方发布为准。

名称 BE10000 BE7000 BE6500 Pro BE6500 BE3600 Pro 套装 BE3600 Pro 网线版 BE10000 Pro BE7200 Pro
型号

主:RN04

子:RN01

主:RP01

子:RP03

上市时间 2022.10 2023.5 2023.10 2024.8 2024.10 2025.5 2025.9 2026.5
处理器 Qualcomm 四核 A73 2.2GHz Qualcomm 四核 A73 1.5GHz Qualcomm 四核 A53 1.5GHz Qualcomm 四核 A53 1.1GHz

主/子:

高通 IPQ5312 四核 1.1GHz

主/子:

Qualcomm Dragonwing N7

Qualcomm A7 四核 1.8GHz Qualcomm 四核 A55 1.8GHz
内存 2GB 1GB 1GB 512MB

主/子:512MB

一说子是 128MB

主:512MB

子:256MB

2GB 1G DRAM + 512MB Flash
频段 2.4GHz、5.2GHz、5.8GHz 2.4GHz、5GHz 2.4GHz、5GHz 2.4GHz、5GHz 2.4GHz、5GHz 2.4GHz、5GHz 2.4GHz、5.2GHz、5.8GHz 2.4GHz、5GHz
组网 混合 Mesh 混合 Mesh 混合 Mesh 混合 Mesh 混合 Mesh AC + AP AI Mesh AI Mesh
天线 12根高增益天线 + 12路信号放大器 + NFC内置天线 7根外置高增益WiFi天线 + 1根内置高增益WiFi天线 + NFC内置天线 6根高增益WiFi内置天线 + 1根蓝牙内置天线 + 1根NFC内置天线 6根外置高增益Wi-Fi天线 主/子:4根内置天线

主:无

子:2根内置双频天线

12根高增益天线 + 12路信号放大器 8根高增益天线 + 8路信号放大器
中枢网关 不支持 不支持 支持 不支持

主:支持

子:不支持

主:支持

子:不支持

支持 支持
蓝牙网关 不支持 不支持

蓝牙 Mesh 1.0 100 台 + 蓝牙 100 台

升级固件后支持蓝牙 Mesh 2.0

蓝牙 Mesh 1.0

蓝牙 Mesh 1.0 200 台 + 蓝牙 100 台

主:不支持

子:蓝牙 Mesh 2.0

蓝牙 Mesh 2.0 200 台 + 蓝牙 100 台

蓝牙 Mesh 2.0 200 台 + 蓝牙 100 台
散热 主动散热 自然散热 自然散热 自然散热 自然散热

主:自然散热

子:主动散热

主动散热 自然散热
接口

4×2.5G

1×10G

1×10G SFP+

1×USB 3.0

4×2.5G

1×USB 3.0

4×2.5G 4×2.5G

主/子:

1×2.5G

3×1G

主:5×2.5G

子:2×2.5G

4×2.5G

2×10G

1×M.2

1×USB 3.0

4×2.5G
Wi-Fi Wi-Fi 7 Wi-Fi 7 Wi-Fi 7 Wi-Fi 7 Wi-Fi 7

主:无

子:Wi-Fi 7

Wi-Fi 7 Wi-Fi 7
MLO 多链路聚合

双频 4.3Gbps

5 GHz 和 5 GHz-Game

双频 4.3Gbps

5 GHz 和 5 GHz-Game

双频 3.6Gbps

2.4 GHz 和 5 GHz

双频 3.57Gbps

2.4 GHz 和 5 GHz

双频 3.57Gbps

2.4 GHz 和 5 GHz

双频

2.4 GHz 和 5 GHz

双频 4.3Gbps

5 GHz 和 5 GHz-Game

双频 3.6Gbps

2.4 GHz 和 5 GHz

价格
最新价格 最新价格 最新价格 最新价格 最新价格 最新价格 最新价格 最新价格
  • 表格于 2025 年 10 月整理更新。

  • 如果只考虑支持蓝牙 Mesh 2.0,那么有 BE3600 Pro 网线版 和 BE10000 Pro 可选,搭配其它 Mesh 路由器实现全屋 Wi-Fi 7 覆盖,搭配其它中枢网关或从网关设备实现全屋蓝牙 Mesh 2.0 覆盖。

  • 如果考虑用 Xiaomi 中枢网关 来部署独立的中枢架构,那么选择路由器就没有限制了。

  • 名称中带有“全屋”字样的通常以子母套装形式出售,子母路由配置通常不同。购买两台一模一样的普通 BE 路由器,就相当于组建了一套“不分子母”的 Mesh 套装。

  • 名称中带有“Pro”字样的通常具备中枢网关功能。

xoyozo 9 个月前
5,951
using System.Runtime.InteropServices;

/// <summary>
/// Windows 资源管理器的文件名排序规则(允许在非 Windows 平台使用)
/// <para>调用 Windows API(StrCmpLogicalW 函数)实现,仅在 Windows 平台环境中使用</para>
/// <para>基本规则如下:</para>
/// <para>将文件名中的数字作为数值来处理。</para>
/// <para>不区分大小写。</para>
/// <para>字符类型的大致优先级顺序为:特殊符号 → 数字 → 字母。</para>
/// <para>对于中文文件名,排序方式取决于系统的区域设置:拼音(默认)、笔画。</para>
/// </summary>
public class FileLogicalComparer : IComparer<string>
{
    [DllImport("Shlwapi.dll", CharSet = CharSet.Unicode)]
    private static extern int StrCmpLogicalW(string psz1, string psz2);
    private static readonly bool IsWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);

    public int Compare(string? x, string? y)
    {
        // 处理 null 值情况
        if (x == null && y == null) return 0;
        if (x == null) return -1;
        if (y == null) return 1;

        try
        {
            if (IsWindows)
            {
                // Windows 平台:使用原生 API
                return StrCmpLogicalW(x, y);
            }
            else
            {
                // 非 Windows 平台:使用 C# 实现的回退方案
                return NaturalCompareFallback(x, y);
            }
        }
        catch (Exception) // 捕获 DllNotFound、EntryPointNotFoundException 等异常
        {
            // 异常时使用默认的字符串比较器
            return string.Compare(x, y, StringComparison.Ordinal);
        }
    }

    /// <summary>
    /// C# 实现的自然排序回退方案(代码来自 AI,未测试!)
    /// </summary>
    private static int NaturalCompareFallback(string x, string y)
    {
        if (x == y) return 0;

        int i = 0, j = 0;

        while (i < x.Length && j < y.Length)
        {
            if (char.IsDigit(x[i]) && char.IsDigit(y[j]))
            {
                // 提取连续数字并进行数值比较
                string num1 = ExtractNumber(x, ref i);
                string num2 = ExtractNumber(y, ref j);

                if (long.TryParse(num1, out long n1) && long.TryParse(num2, out long n2))
                {
                    if (n1 != n2)
                        return n1.CompareTo(n2);
                }
                else
                {
                    // 解析失败时按字符串比较
                    int strCompare = string.Compare(num1, num2, StringComparison.Ordinal);
                    if (strCompare != 0)
                        return strCompare;
                }
            }
            else
            {
                // 非数字字符直接比较
                if (x[i] != y[j])
                    return x[i].CompareTo(y[j]);

                i++;
                j++;
            }
        }

        return x.Length.CompareTo(y.Length);
    }

    /// <summary>
    /// 从字符串中提取连续的数字序列
    /// </summary>
    private static string ExtractNumber(string str, ref int index)
    {
        int start = index;
        while (index < str.Length && char.IsDigit(str[index]))
        {
            index++;
        }
        return str.Substring(start, index - start);
    }
}
xoyozo 9 个月前
2,529

目标: 在运行 HarmonyOS Next 的华为 MateBook Pro 上侧载安装第三方应用程序。

注:本教程同样适用于在运行 HarmonyOS Next 的华为手机上侧载安装第三方应用程序。

所需准备

  1. 一台运行 HarmonyOS Next 的华为 MateBook Pro

  2. 一台 Windows 电脑

  3. 一根数据线

    • USB-A to Type-C

    • 或 Type-C to Type-C (确保能将两台电脑连接)。

  4. 网络连接:两台电脑需在同一局域网下(用于无线调试连接)。

步骤详解

第一步:鸿蒙 PC (MateBook Pro) 端设置 (启用开发者模式与调试)

  1. 连接设备: 使用数据线将鸿蒙 MateBook Pro 连接到 Windows 电脑。

  2. 打开设置: 在鸿蒙 PC 上,进入 设置

  3. 进入关于本机: 在设置中,找到并点击 关于本机 或您的 电脑型号

  4. 启用开发者模式

    • 在“关于本机”界面,找到 软件版本 或 HarmonyOS 版本

    • 连续点击 软件版本/HarmonyOS 版本 文字 5 次以上

    • 系统会提示“您已处于开发者模式”或提示重启进入开发者模式。按提示重启电脑(如果需要)。

  5. 打开开发者选项

    • 重启后,回到 设置 -> 系统 -> 开发者选项 (路径可能略有不同,在“系统和更新”或“隐私与安全”下查找)。

  6. 启用 USB 调试

    • 在开发者选项中,找到 USB 调试,将其开启

    • 首次开启时,可能会弹出提示(连接线后或稍后操作时),点击 允许

    • 注意提示:系统可能提示“Matebook Pro 上的右上角的 Type-C 口可以进行调试”,确保使用正确的接口连接调试线。如果弹出“始终允许本机调试”选项,勾选并允许

  7. 启用并记录无线调试信息

    • 在开发者选项中,找到 无线调试,将其开启

    • 开启后,系统会显示一个 IP 地址和端口号(例如 192.168.x.x:xxxxx)。务必准确记下这个 IP 地址和端口号,后续在 Windows 端连接时必须用到。

    • 至此,鸿蒙 PC 端的准备工作完成。

第二步:Windows 电脑端操作 (使用小白调试助手)

  1. 获取工具和 HAP 包

    • 访问包含 HarmonyOS Next 可用 HAP 包的资源(如 GitHub 上的相关仓库,搜索 “HarmonyOS Next HAP”)。

    • 下载小白调试助手

      • 在工具仓库中找到 小白调试助手 或类似名称。

      • 点击 Latest (最新版本)。

      • 点击 Download 下载其 Windows 版压缩包(.zip 文件)。

    • 下载目标应用的 HAP 包(以 ClashBox 为例,你也可以使用自己已有的 .hap 文件):

      • 在应用仓库中找到 ClashBox

      • 同样点击 Latest -> Download 下载其 HAP 包(.hap 文件)。

  2. 准备小白调试助手

    • 将下载的小白调试助手压缩包解压到一个非中文且无空格路径的文件夹。

    • 进入解压后的文件夹,找到可执行文件。双击运行。根据 Windows SmartScreen 或安全软件提示(若有),选择 更多信息 -> 仍要运行

  3. 登录华为开发者账号 (强烈推荐)

    • 在小白调试助手界面,找到登录入口(通常在界面顶部或设置中),点击 登录

    • 使用您的华为开发者账号登录(登录时,您的华为手机可能会收到验证码,或在鸿蒙PC上验证)。

    • 输入验证码,并在授权请求页面点击 允许。登录成功后,界面通常会显示您的账号昵称或ID。

    • 重要: 开发者账号签发的应用证书有效期通常为 6 个月普通账号14 天。为方便使用,建议申请华为开发者账号。

  4. 连接鸿蒙设备

    • 在小白调试助手主界面,找到 连接设备添加设备 或类似功能的按钮并点击。

    • 在弹出的连接窗口(通常是输入IP和端口的对话框)中:

      • 输入您在鸿蒙 PC 上 无线调试 功能中记录的 IP 地址

      • 输入记录的 端口号

    • 点击 确定连接 或 OK

    • 连接成功:如果地址和端口输入正确,且鸿蒙 PC 的开发者选项已开启无线调试:

      • 鸿蒙 PC 可能弹出调试请求(“允许调试?”),勾选“始终允许”并点击 允许

      • 小白调试助手界面会显示“连接成功”或目标设备信息。

      • (若未弹出提示框但连接成功,也属正常)

第三步:安装第三方 HAP 包

  1. 选择 HAP 包

    • 确保设备已连接成功。

    • 在小白调试助手界面,找到 选择 HAP加载 HAP安装应用 或类似按钮(通常在文件菜单或主功能区)。

    • 点击该按钮,浏览文件系统,找到您下载好的目标 HAP 文件(如 ClashBox-xxx.hap),选中并点击 打开

  2. 开始安装

    • 选择好 HAP 文件后,小白调试助手界面通常会激活 开始调试安装 或 运行 按钮。

    • 点击 开始调试 或 安装

  3. 等待安装完成

    • 小白调试助手会开始处理 HAP 包:进行签名、推送到设备并安装。

    • 观察进度条或日志输出,耐心等待直至提示“安装成功”

    • 若安装失败,尝试“清理缓存”或“重置证书配置”,或重启手机,再次尝试。

第四步:在鸿蒙 PC 上使用安装的应用

  • 安装完成后,返回您的鸿蒙 MateBook Pro。

  • 在桌面或 开始菜单 中,查找您刚刚安装的应用图标(如 ClashBox)。

  • 点击图标即可启动使用该应用。

常见问题处理

  • 签名错误/证书问题:在小白调试助手内寻找 **清理缓存重置证书重新登录** 或类似选项。执行后,重新登录开发者账号,再尝试安装。确保登录的是开发者账号。

  • Java 环境报错:如果小白调试助手提示需要 Java 环境(如 java 命令未找到),按照其提示点击安装,它会引导下载并安装所需的 Java Runtime Environment (JRE)。

  • 连接失败

    • 检查鸿蒙 PC 的 无线调试 IP 和端口号是否变化(息屏、重启、网络切换可能导致变化),在开发者选项里重新确认并输入。

    • 确保两台电脑在同一局域网

    • 检查鸿蒙 PC 的 **USB 调试 和 无线调试 是否已开启**。

    • 尝试在鸿蒙 PC 的开发者选项中关闭再重新开启 无线调试,获取新的端口号。

  • 其他报错:查阅小白调试助手官方的使用说明或 GitHub 仓库的 Issue 区寻求解决方案。


xoyozo 1 年前
44,592

IIS 中使用 HttpPlatformHandler 模块部署 python web 项目时遇到 502.3 网关错误

HTTP 错误 502.3 - Bad Gateway

There was a connection error while trying to route the request.

最可能的原因:

  • CGI 应用程序没有返回一组有效的 HTTP 错误。

  • 由于父网关中出现错误,充当代理或网关的服务器无法处理该请求。

可尝试的操作:

  • 使用 DebugDiag 排查 CGI 应用程序。

  • 确定此错误是否由代理或网关引起。

详细错误信息:

模块    httpPlatformHandler

通知    ExecuteRequestHandler

处理程序    httpplatformhandler

错误代码    见下方表格

详细信息:

当 CGI 应用程序未返回一组有效的 HTTP 头,或者代理或网关无法将请求发送至父网关时,便会出现此错误。您可能需要获取一个网络跟踪,或者与代理服务器管理员联系(如果不是 CGI 的问题)。

错误代码可能的错误原因
0x8007053d未安装相关组件库,建议执行命令:pip install -r requirements.txt
0x80070005

若显示配置错误“由于权限不足而无法读取配置文件”则是应用代码目录未配置相应用户的读取权限;

访问受限,请正确配置 IIS 中的网站凭据、应用程序池标识、项目目录“读取”、解释器目录“读取和执行”权限等

0x80072ee2执行超时,一般发生在批量读写的时候
0x8007042b
任何错误

查看日志文件。

可能的错误原因:

  • 编码问题:强制使用 utf-8


xoyozo 1 年前
2,142