AI 行文声明:无 AI
17 年来法国,到今年 9 个年头,想到哪写哪

在现行的政策下,作为外国人,即使是没有收入学生的也可以获得免费的全民基础医疗保险。不过这个政策 2026 年听说要更改,收紧对不在法国缴税的外国人的医保政策。
全民医保对常见的全科医生咨询,特定专科医生,日常价位的药物的报销额度在 65%。大部分人会在这个基础上购买月付的补充保险(取决于收入,每月 20 欧到 50 欧不等),此时一份好的补充保险可以把报销额度提高到 100%,同时涵盖了更贵的医生,药物,医院,牙科诊所,双人/单人病房。
没有免赔额度,不过对应的,对于每年的前 50 笔报销每笔强制自付大概 1 欧元。

总体采用预约问诊的方式,全科医生 -> 专科医生 -> 专科医院,从面到点的咨询流程,跳过其中某个步骤可能会影响报销。刚来的时候不懂直接约专科医生,还被护士教育了。

一般提前 2-3 天预约全科医生即可,急诊需要去医院急诊排队。往往这个体验很差,除非你快死了不然最起码要等半天,可能只会拿到一片止疼药。

以我司为例,病假单 72 小时内给 HR 即可,所以生病了可以先口头知会而不用顾虑今天约不到家庭医生拿不了病假单。

2 年前尿尿有泡沫(尿出来的泡沫像啤酒)正经体验了一回看病流程
1. 提前 3 天约了全科医生,全科医生开了尿常规+血常规
2. 拿着处方约了 2 天后的实验室,这边小诊所一般不包含实验室,需要自己再约,实验室做完 3 天拿了结果
3. 全科医生觉得自己搞不定,写了转诊单给专科
4. 只能约到 1.5 个月后的专科医生,专科医生开了肾脏 B 超,前列腺 B 超
5. 拿着处方约了 3 天后实验室,做了 B 超,医生边做边骂给 28 岁患者开前列腺 B 超是浪费医疗资源
6. 专科医生说没事,每年随访就可以
7. 以上流程报销完花了 5 欧

今年滑雪同学腿断了,体验了一回急诊看病流程
1. 滑雪买了保险,4 欧一天,包雪道救援。因为是在海拔 2800 米摔的,整个人失去意识,直升机直接过来送到山脚,保险赔付了直升机和因故不能继续滑的雪票
2. 滑雪度假区诊所排队 2 小时排了片子,轻度脑震荡 + 小腿骨裂,诊所搞不定,喊了救护车转院到上级医院
3. 到上级医院是周日,紧急手术安排到了周一,因为同学买的保险很好,所以升级单人病房+陪护床位,我也可以一起休息并获得一日三餐
4. 周一手术完成,观察到周三,安排救护车拉到巴黎离住所更近的医院观察
5. 以上流程报销完也大概是 10 欧左右

相比于国内看病肯定时间线肯定是拖得更长,同时因为非母语交流很多时候也无法完全说出自己的症状。我同时还交着国内的居民医保,回国还要再看一下尿液相关的问题。

最后祝大家无病无灾

这是 ROG Xbox Ally 下的测试效果,可能有专门的硬件适配吧,普通台式机是不是也能有类似的性能加成呢?

在 Bazzite 和 Windows 分别运行游戏《Kingdom Come: Deliverance 2》和《Hogwarts Legacy》的测试显示,Linux 下的游戏 FPS 比 Windows 下平均高 13.47%,而且帧率更平稳,FPS 最高多了 32%(17W 功率模式下的《KCD2》)

我们进入了一个物资丰沛的时代

我们现在所处的是这样一个物资丰沛的时代:如果我们要买一个东西,有无数的选择供我们挑选,所有的生产者都在想方设法讨我们的欢心。

直播带货的本质是:物资丰沛时代,个人信任的变现

物资丰沛时代,我们其实已经陷入了一种选择困难症,面对对成百上千的选择根本无从选择。
这个时候,有一个人将自己的信用为赌注,向大家分享自己对商品的评价。
以上就是直播带货模型的逻辑。

既然个人的信用可以变现,为什么企业不能?因此,我预测:

未来,一定会有家企业,通过建立自己的信用,将自己对商品的评价进行变现。谁能实现这个商业模式,谁就能建立下一个电商帝国。

隔壁 V 有个人发了一个这种工具,但是收费的,免费复盘几个仓位。我一直是浪哥的粉丝,但是又不想为了复盘几个仓位付订阅费,之前跟浪哥学习的时候都没给浪哥付过费。索性自己根据复盘习惯写了一个工具,支持多周期多交易对对比复盘,方便看多交易对共振。顺便开源给想学习 bit 浪浪交易系统的人一个学习的渠道(学习那个页面我是喂给 notebooklm 浪哥所有复盘视频得出的策略,如果想要 notebooklm 的链接可以私信)

仓库地址 —GitHub - Xeron2000/retraq

仓库里面有示例网站,有感兴趣的佬友可以看一下,顺便求一下 star





📌 转载信息
原作者:
Xeron
转载时间:
2026/1/20 08:27:02

对于可以复制的表格已经有佬友提出过解决方案,但对于创建者禁止复制 & 创建副本 & 下载的飞书多维表格怎么办呢?如果遇到了下图的情况,本文应该可以有些帮助。
【教程】如何提取 & 整理无法复制和下载的飞书多维表格1

打开开发者工具(按 F12 或者 Ctrl+Shift+I),切换到 网络 部分,清空请求后刷新,可以看到好多条刷出来的请求。按照大小从大到小排序后最大的那些就是表格内容部分。

挑选你要下载的表格的请求点进去,在 请求URL 部分可以看到一个链接,手动访问可以看到其加密后的数据:

records 部分复制下来,按经验这是 base64 编码。而其开头 H4sI 是一个很有名的字符串指纹,其 base64 解码后的字节序列是 1f 8b 081f 8b 是 Gzip 压缩文件的文件头,08 表示其使用了 Deflate 压缩算法。

将其先 base64 解密后再解压可以得到一个标准 JSON 文件,我偷懒起见,直接选择了提取其中字符串,过滤无意义内容就能得到最后的清洗过的干净文件了。

最后的清洗部分因为需求和文件不同,也没法给出一个统一的代码,如果有相关问题可以提问,感谢各位佬友。


📌 转载信息
转载时间:
2026/1/20 08:26:51

背景:因为我有时候会在闲鱼发布接单,所以需要一个封面,但是这个封面要自己创建,就想着做个东西可以生成。

目前是只有这一个样式,可以自定义尺寸。
可自由编辑内容。
下载生成 png 图片。
免费使用。
服务部署在 CF 上。
ai 写的,调了半天才弄好。

工具地址:https://tool.fologde.com/skill-poster/

页面长这样:

实际发布闲鱼效果:


📌 转载信息
原作者:
yifang-self
转载时间:
2026/1/20 08:26:39

前言

不满意 cli 内部调用其它模型 api 交互方式,全自主开发了 CCB, 区别呢,举了例子对比,

  • 传统方式:木匠在盖一个楼,为了完成瓦匠的活临时借了瓦匠的工具或是短期雇佣了瓦匠,完全是主从关系,随从可控性能力都受到极大限制。
  • CCB 方式:木匠把瓦匠等工人叫过来,组建了一个施工队,全部都是全职工,每个都具备完整的能力。而 ccb 做到的就是它们直接相互感知和流畅通讯。 当然还包括设计了漂亮好用的界面:

具体来说:

  • [CCB] 是一个纯底层软件,只负责多模型挂载和低 token 交互,没有任何自动化和工作流设计,完全区别于其他项目,目前大家都是手动指派哪个模型负责干啥。也可以看出新的交互方式具有不可替代性
  • [CCB] 项目经过一个月发展,目前已经是 4.1.3 版本,各种系统都能稳定运行了,丝滑流畅多模型通讯。用户也有上百人,用户群 200 人左右,非常热闹
  • [CCB] 目前是以 CC 为主,协调调用 CX,OC 和 GE,后续功能包括:CX 为主调用另外三者(就要推出); 同种 cli 不限一个(尽快推出);手机远程(正在筹备)。

为什么造轮子

  • [CCA](Claude code autoflow) 可以看作是 [CCB] 的自动化插件,或是上层建筑,可以自由组合不同 cli 的角色,自动调配工作。

  • CCA 的优点完全来源于 [CCB] 可见、可控、低 token 占用特点,流畅自动化是水到渠成的事。可以自由设置和调配不同 cli 的工作(将灵活度拉满)。

  • 完全基于项目, 安装后,通过 cca add . 方式在当前目录引入 cca 控制 cca delete . 即可删除当前目录。
    目前插件内置了两种角色配置,可灵活切换:

  • 配置 1: 默认 CXGO 模式,其中 cc 负责宏观和推进任务,cx 负责微观设计并监督 oc 完成代码编写,迭代完成反馈 cc。ge 负责 git 文档维护和大型代码的 review。

  • 配置 2: Trio 模式:去掉了 oc 具体代码实现有 cx 完成。

  • 后续将开放更多角色配置,尤其是等 cx 可以切换为主控后,角色搭配将更丰富。 也支持用户根据自己工作和习惯自定义角色。

地址,欢迎使用和小星星:

对 ccb 不熟的 l 佬可以查看:


📌 转载信息
转载时间:
2026/1/20 08:25:26

如题, 找了一圈全是一些随便 vibe 出来的东西或者很久没维护的项目, 找了一些部署来测试也有很多问题, 是不是我找的姿势不对? 有什么推荐工具吗? 主要想转发 claude/codex/gemini

最近重构了我的笔记体系,发现 Obsidian + 卡片盒笔记法 用起来很爽,类似收集狂一样。

📂 我的目录结构:
1️⃣ 01_闪念笔记:捕捉灵感瞬间,不做信息囤积狂。
2️⃣ 02_文献笔记:用“自己的话”重写。划重点: 亲自转述 = 深度理解,这比任何收藏动作都管用!
3️⃣ 03_永久笔记:过滤外界噪音,只存最硬核、最准确的干货。

💬 想问问大家: 你们平常是用文件夹分类派,还是标签/图谱链接派?有没有更好用的工具或插件推荐?
(用 ai 优化了下文字)

让它不再专门在某个项目目录写代码。作为一个 shell 命令辅助工具运行,比如想不起来哪个复杂的 shell 命令的时候,随时 aish ,然后提问,aish 在你的允许下执行,然后退出....
https://github.com/chunhuitrue/aish

刚 vibe 出来,文档配置之类的还没加。

运行示例:
› 当前系统中有僵尸进程么?


• 我来检查系统中是否有僵尸进程。

• Ran ps aux '|' grep -w Z
└ ps: illegal argument: |
usage: ps [-AaCcEefhjlMmrSTvwXx] [-O fmt | -o fmt] [-G gid[,gid...]]
[-u]
[-p pid[,pid...]] [-t tty[,tty...]] [-U user[,user...]]
lll 61467 6.3 0.2 411403520 65552 s002 S+ 8:58 下午 0:00.45 aish

• Ran ps aux
└ USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND
lll 429 32.8 3.0 413283760 1020816 ?? S 8 126

✔ You approved aish to run ps axo 'stat,pid,ppid,command' this time

• Ran ps axo 'stat,pid,ppid,command'
└ STAT PID PPID COMMAND
Ss 1 0 /sbin/launchd
Ss 83 1 /usr/libexec/logd
Ss 106 1 /usr/libexec/watchdogd
… +621 lines
Ss 750 552 -zsh
S+ 9711 750 emacsclient -nw
Ss+ 837 552 -zsh
Ss+ 882 552 -zsh
─ Took 41s

• 是的,当前系统中有 5 个僵尸进程:

| PID | PPID | 状态 | 父进程 |
|-------|------|------|--------|
| 54918 | 290 | Z | clash-core-service |
| 73753 | 290 | Z | clash-core-service |
| 75525 | 290 | Z | clash-core-service |
| 85212 | 290 | Z | clash-core-service |
| 97475 | 290 | Z | clash-core-service |

这些僵尸进程都是 clash-core-service (位于 /Users/lch/.config/clash/service/clash-core-service )产生的。

说明:僵尸进程是已经执行完成但父进程没有正确 wait() 它们的进程。它们不占用内存或 CPU ,只保留一个进程表项。

建议:通常不需要手动清理。重启 clash-core-service 服务可以让这些僵尸进程被 init 进程接管并自动清理。如果你想让这些僵尸进程消失,可以重启 clash 服务。


› 如果要手动清理,应该如何作?


• 僵尸进程无法直接 kill ,因为它们已经执行完成。清理方法是让父进程正确地 wait() 它们,或者让 init 进程( PID 1 )接管后自动清理。

针对你的情况,有两种方法:

方法 1:杀死父进程(推荐)

kill 290

这会终止 clash-core-service ,僵尸进程会被 init 接管并自动清理。如果 clash 是通过服务管理器启动的,它可能会自动重启。

方法 2:优雅重启 clash 服务

如果你知道如何重启 clash 服务(比如通过 launchctl 或 systemctl ),可以用相应命令重启服务,这样更安全。

———

注意事项:

- 方法 1 会中断 clash 服务,如果你的网络依赖它,可能会短暂断网
- 如果你使用 launchd 管理 clash ,可以用 launchctl 重启,更优雅

你是想直接杀死进程,还是需要我帮你查看如何正确重启 clash 服务?

一周前在 AI 帮助下建了个网站 https://www.convert.work ,很兴奋,虽然很烂还是忍不住发帖炫耀了一番。当然被喷很多次。不过后来仔细想想,应该感谢喷我的兄弟。我认识到那个网站真的很烂。开始重新修改,期间被改瘫痪了几次。今天终于工作了,再发帖汇报一下。欢迎批评,指正。谢谢

LLM幻觉问题至今没有根治方案。RAG能缓解一部分,但成本高、架构复杂,而且只适用于有外部知识源的场景。而对于模型"应该知道但经常搞错"的那类问题,比如历史事件的时间线、人物履历的细节,RAG帮不上什么忙。

Chain-of-Verification(CoVe)的思路是既然模型会在生成时犯错,那就让它生成完之后再检查一遍自己的输出,把能发现的错误纠正掉,然后再给用户看。

听起来像是废话?关键在于"怎么检查"。

直接让模型审视自己刚写的东西,它大概率会坚持原有立场,这是确认偏差在作祟。CoVe的核心贡献是发现了一个绕过这个陷阱的方法:验证时必须把原始输出藏起来,让模型在"失忆"状态下重新回答事实性问题,然后用这些独立验证的答案去校对初稿。

某种意义上,这是给LLM装上了"系统2"思维:快思考先出初稿,慢思考再做验证。

工作流程:起草、规划、验证、修复

CoVe不是什么新的模型架构,它是一种提示编排模式,它把生成过程拆成四步:先让模型写初稿(这时候幻觉随便来),然后让它针对自己的初稿生成一组事实核查问题,接着独立回答这些问题,最后用验证过的事实重写原文。

Factored:真正的关键

前面说的四步里,第一、二、四步都是常规提示工程,用思维链就能搞定,而第三步才是核心。

让LLM一边看着自己写的东西一边验证,会有一个问题,这个在学术上管这叫"sycophancy",也就是说模型会顺着自己的话往下说。草稿就在上下文窗口里摆着,概率分布会被带偏,模型倾向于认同自己刚编出来的东西。

所以最简单的解决办法是把上下文剥掉。

CoVe论文里发现,回答验证问题时必须把原始草稿藏起来。举个例子:如果你问"根据这个草稿,X是不是在1998年发生的?"模型八成会点头同意自己。但如果你只问"X是什么时候发生的?"它就得老老实实从训练权重里检索答案,没有偏差可言。

隔离验证问题就是逼模型去查自己的知识库,而不是复读自己刚说过的话。

代码实现

下面是CoVe流程的Python实现,封装成一个类。注意第三步里的CRITICAL注释,那就是Factored验证的精髓。

 classChainOfVerification:  
    def__init__(self, llm):  
        self.llm=llm  

    defrun(self, query):  
        # Step 1: Baseline Generation
        # Let the model hallucinate freely here.
        draft_prompt=f"Question: {query}\nAnswer:"  
        draft=self.llm.generate(draft_prompt)  
        print(f"--- DRAFT ---\n{draft}\n")  

        # Step 2: Plan Verifications
        # Ask the model to identify what needs checking.
        plan_prompt=f"""  
        Context: {query}  
        Draft: {draft}  
        Task: Create a list of 3-5 verification questions to check the facts   
        in the draft. Output ONLY the questions.  
        """  
        plan_text=self.llm.generate(plan_prompt)  
        questions=self.parse_questions(plan_text)
        print(f"--- QUESTIONS ---\n{questions}\n")  

        # Step 3: Factored Verification (The Key Step)
        verification_results= []  
        forqinquestions:  
            # CRITICAL: Do NOT include 'draft' in this prompt context.
            # We want the raw model weights to answer this, uninfluenced by the previous lie.
            verify_prompt=f"Question: {q}\nAnswer:"  
              
            # Low temperature is crucial here for factual retrieval
            answer=self.llm.generate(verify_prompt, temperature=0)  
            verification_results.append((q, answer))  

        # Step 4: Final Synthesis
        # Now we bring it all together.
        verification_context=self.format_pairs(verification_results)  
        synthesis_prompt=f"""  
        Original Query: {query}  
        Draft Response: {draft}  
          
        Verification Data:  
        {verification_context}  
          
        Task: Rewrite the Draft Response to be fully accurate.   
        Remove any details contradicted by the Verification Data.  
        """  
        final_response=self.llm.generate(synthesis_prompt)  
          
        returnfinal_response  

    defparse_questions(self, text):  
        return [line.strip() forlineintext.split('\n') if'?'inline]  

    defformat_pairs(self, pairs):  
         return"\n".join([f"Q: {q}\nA: {a}"forq, ainpairs])

CoVe和RAG该怎么选?

每次聊到CoVe,总有人问:为什么不直接用RAG?

两者解决的是不同问题。

RAG适用于模型根本不可能知道答案的场景,比如你公司Q3的销售数据。CoVe适用于模型理论上应该知道、但可能搞混或偷懒的场景,比如按时间顺序列出纽约市历任市长。

而且研究表明两者可以混用:先用CoVe验证RAG检索回来的文档是否真的相关,再决定要不要用。代价是成本翻倍,但在医疗、法律这种高风险场景下,还是可行的。

从Vibe Coding到系统2代理

关注2026年初Agentic爆发的人,大概都听过"Ralph Wiggum"技术这个梗。

名字来自《辛普森一家》里那个喊着"我在帮忙!"却啥也没干成的角色。这技术的核心就是把LLM塞进一个while循环,让它反复尝试直到单元测试通过。暴力验证,Token消耗会爆表但最后确实能撞出正确答案。虽然听起来很好笑,实际上还挺管用。

工具增强版CoVe

opencode、OpenDevin、Windsurf这些现代自主代理已经在用"工具增强"版本的CoVe了。

它们不再只是问自己"这代码对不对",而是直接动手:先写代码,然后在沙盒里跑npm test或linter,读stderr输出,根据真实报错来修。

这就把CoVe的验证环节从概率猜测变成了确定性判断。

2026年的新拓扑:分支验证

最前沿的做法已经不是简单的线性循环了。是分支。

分支拓扑下,代理不是失败了就重试一次。它会同时提出三个修复方案,在三个隔离容器里并行跑,哪个能让构建变绿就提交哪个。

验证的消耗

这是2026年工程实践必须面对问题

Vibe Coding走系统1路线:快、便宜、但有20%左右的幻觉率,做原型够用。系统2代理反过来:慢、Token成本翻10倍、但可靠性过硬,生产环境离不开。

也就是说是拿计算资源换安心,当业务从聊天机器人升级到自主工程师,这笔成本不是能不能接受的问题,而是必须付的保险费——除非你想承担"Ralph Wiggum式"的风险,比如AI自己把数据库删了。

总结

CoVe的代价很明确:延迟。

生成初稿、生成问题、并行验证、综合重写,整套流程跑下来,Token消耗和响应时间基本翻四倍。对于实时聊天场景,这个延迟可能难以接受。但换个角度看,异步报告生成、代码审查、自动邮件起草这类任务,多等几秒换来输出可信度的大幅提升,这笔账怎么算都划算。

更值得关注的是CoVe带来的转变:过去几年,行业把大量精力投入到"如何让模型生成得更好"上——更大的参数、更多的数据、更精细的对齐。CoVe指向了另一个方向:与其追求一次生成就完美,不如承认模型会犯错,然后在架构层面把纠错机制build进去。

这和软件工程的演进路径很像。早期写代码追求一次写对,后来发现测试驱动开发、持续集成、灰度发布这些"验证优先"的实践才是规模化的正确姿势。

CoVe不会是终点,我们未来大概率会看到更多CoVe与RAG、外部工具、多模型交叉验证的组合方案。

https://avoid.overfit.cn/post/1f3da2d8396d44c6bab8bfea80405cb6

作者:Digvijay Mahapatra

在这里插入图片描述

摘要

这两年,跨屏协作在鸿蒙生态里出现得越来越频繁。
从最早的文件互传、多屏办公,到现在的教育课堂、车机联动,设备之间已经不再是“各干各的”。

在游戏领域,这个变化更明显:

  • 一块屏幕已经不够玩
  • 玩家希望多设备一起参与
  • 大屏负责画面,小屏负责操作

但很多开发者一提“跨屏游戏”,第一反应还是投屏、远程控制、镜像显示。
实际上,鸿蒙给的不是投屏方案,而是一整套分布式游戏协作能力

这篇文章就从游戏开发者的真实视角,讲清楚鸿蒙是如何把多设备变成“一个游戏系统”的。

引言

在传统系统里,如果你想做多设备协作游戏,通常意味着:

  • 自己写网络协议
  • 自己做设备发现
  • 自己处理数据一致性
  • 自己兜底各种异常情况

而在 HarmonyOS 里,这些事情被系统层直接兜住了:

  • 设备发现靠软总线
  • 状态同步靠分布式数据
  • UI 跨屏靠 Ability 调度

你要做的事情更偏向游戏逻辑设计本身,而不是重复造轮子。

接下来我们一步一步拆。

什么是鸿蒙里的跨屏游戏协作

跨屏不是投屏

先说一个很重要的点:

鸿蒙的跨屏游戏 ≠ 投屏

投屏的特点是:

  • 一端渲染
  • 另一端只是显示
  • 没有真正的协作逻辑

而鸿蒙的跨屏游戏,更像是:

  • 多设备同时运行
  • 各自承担不同功能
  • 通过系统级分布式能力协同

比如:

  • 手机只负责操作和技能
  • 平板或智慧屏负责主战场渲染
  • 游戏状态在多设备之间自动同步

一个最常见的跨屏游戏形态

手机(控制器)
  │
  │ 操作指令
  ▼
平板 / 智慧屏(主画面)
  │
  │ 游戏状态同步
  ▼
分布式数据中心

支撑跨屏游戏的三大核心能力

分布式软总线:设备能“找到彼此”

在游戏里,你最关心的不是网络协议,而是:

  • 能不能快速发现附近设备
  • 延迟够不够低
  • 掉线能不能感知

鸿蒙的分布式软总线解决的正是这些问题。

你不需要关心设备是:

  • Wi-Fi
  • 蓝牙
  • 局域网
  • 点对点

系统会自动选最优链路。

分布式数据管理:状态天然同步

跨屏游戏最怕的几个问题:

  • 状态不一致
  • 数据打架
  • 玩家看到的画面不同步

鸿蒙提供的分布式 KV 数据,天生适合游戏里的:

  • 玩家位置
  • 血量
  • 技能状态
  • 回合阶段

而且是系统级同步,不是你自己发包。

分布式 UI:屏幕不是绑死的

在鸿蒙里:

  • Ability 可以被拉起到其他设备
  • 游戏不用重新启动
  • 状态不需要你手动迁移

这对游戏来说很重要,因为你可以自由设计:

  • 哪个屏幕显示什么
  • 玩家如何参与
  • 随时切换设备角色

跨屏游戏的整体架构设计

一个可落地的结构示例

┌────────────┐
│ 手机端     │
│ 操作输入   │
│ 技能按钮   │
└─────┬──────┘
      │
      │ 分布式 KV 数据
      ▼
┌────────────┐
│ 平板端     │
│ 游戏主画面 │
│ 渲染逻辑   │
└────────────┘

手机不负责画面,平板不负责输入,各司其职。

实战核心:跨屏游戏状态同步 Demo

创建分布式 KV Store

import distributedData from '@ohos.data.distributedData';

const kvManager = distributedData.createKVManager({
  bundleName: 'com.example.crossgame',
  context: getContext()
});

const store = await kvManager.getKVStore('gameStore', {
  kvStoreType: distributedData.KVStoreType.SINGLE_VERSION,
  securityLevel: distributedData.SecurityLevel.S1
});

这个 store 在多设备之间是共享的。

手机端发送操作指令

// 模拟摇杆方向
async function sendMove(x: number, y: number) {
  await store.put('player_move', JSON.stringify({
    x,
    y,
    time: Date.now()
  }));
}

这里同步的是“操作”,而不是最终坐标。

平板端监听并更新角色

store.on('dataChange', (data) => {
  data.insertedEntries.forEach(entry => {
    if (entry.key === 'player_move') {
      const move = JSON.parse(entry.value as string);
      updatePlayer(move.x, move.y);
    }
  });
});

跨屏 UI:把主画面拉到大屏

从手机拉起平板的游戏界面

import featureAbility from '@ohos.ability.featureAbility';

featureAbility.startAbility({
  want: {
    bundleName: 'com.example.crossgame',
    abilityName: 'GameMainAbility',
    deviceId: 'remoteDeviceId'
  }
});

前提是:

  • 游戏状态已经存在分布式数据中
  • 新设备启动后直接读取即可

为什么这个能力对游戏很重要

你不需要:

  • 手动传进度
  • 重新初始化状态
  • 处理复杂的恢复逻辑

系统已经帮你兜底。

真实应用场景拆解

场景一:手机当手柄,大屏玩游戏

适合类型

  • 派对游戏
  • 本地多人
  • 家庭娱乐

逻辑示例

// 手机端:技能释放
await store.put('skill_cast', {
  skillId: 2,
  playerId: 'p1'
});
// 大屏端:技能响应
store.on('dataChange', (data) => {
  data.insertedEntries.forEach(e => {
    if (e.key === 'skill_cast') {
      castSkill(e.value);
    }
  });
});

场景二:非对称协作游戏

比如:

  • 一个人当指挥
  • 一个人实际操作
// 指挥端下达命令
await store.put('command', {
  type: 'attack',
  target: 'boss'
});

操作端只负责执行,不做决策。

场景三:教育 + 游戏化互动

老师平板控制节奏,学生手机参与。

// 教师端切换关卡
await store.put('game_stage', 'level_2');

学生端监听并同步切换界面。

常见问题 QA

Q1:分布式 KV 会不会太慢?

不会。
它适合的是:

  • 低频状态
  • 操作指令
  • 游戏阶段

高频帧同步需要更底层方案。

Q2:能不能用在竞技类游戏?

可以,但不建议直接用 KV 同步帧数据。
更适合:

  • 操作同步
  • 客户端预测
  • 状态校正

Q3:设备掉线怎么办?

KV 会自动触发变更事件,你可以监听:

  • 玩家退出
  • 状态回收
  • AI 接管

总结

从游戏开发角度看,鸿蒙的跨屏协作并不是噱头,而是一套真正能落地的系统能力

核心就一句话:

多设备在鸿蒙里,不是多个客户端,而是一个分布式游戏系统。

  • 软总线解决连接
  • 分布式数据解决同步
  • Ability 解决跨屏 UI
  • ArkTS 足够把 Demo 跑起来

在这里插入图片描述

摘要

随着智能终端越来越多,应用早就不再只运行在一台设备上。手机、平板、智慧屏、手表之间的协作,已经成了很常见的需求。在这种背景下,多设备任务该怎么分、分到哪台设备执行,就成了开发中绕不开的问题。

在鸿蒙系统中,这个问题并不是靠开发者“手动指定设备”来解决的,而是通过 设备能力感知 + 分布式调度机制 来完成。开发者更多关心的是:
这个任务适合干什么,而不是非要在哪台设备干。

本文会结合鸿蒙系统的分布式能力,介绍多设备任务分配的整体思路,并通过可运行的 Demo 代码,把这个过程完整跑一遍,最后再结合几个真实场景,聊聊它在实际项目中该怎么用。

引言

如果放在以前,一个应用基本只跑在一台手机上,最多考虑前后台切换。但现在不一样了:

  • 手机在你手里
  • 平板在桌子上
  • 智慧屏在客厅
  • 手表戴在手上

用户希望的是:
设备不同,但体验是连着的。

鸿蒙系统的分布式能力,正是为这种场景设计的。它不是简单的“跨设备通信”,而是把 任务、数据、能力 都变成可以在多设备之间流动的资源。

而多设备任务分配,本质上就是一句话:

把合适的任务,交给合适的设备去做。

鸿蒙多设备任务分配的整体思路

先发现设备,再谈分配

在鸿蒙系统中,只要设备在同一个分布式网络里,系统就能自动发现它们。
开发者不需要自己维护“设备表”,也不用关心设备什么时候上线、下线。

系统会帮你感知这些信息:

  • 设备类型(手机、平板、智慧屏)
  • 基本性能情况
  • 是否可信
  • 当前是否可用

你只需要在合适的时机拿到设备列表即可。

任务一定要能拆

多设备任务分配的前提是:
你的业务本身是能拆开的。

比如:

  • 页面展示是一块
  • 数据采集是一块
  • 计算处理是一块

如果一个任务从头到尾全写死在一个 Ability 里,那基本就没法分配了。

系统负责“怎么选设备”

在鸿蒙里,真正“选哪台设备执行”的逻辑,大部分是系统完成的:

  • 当前设备忙不忙
  • 网络情况好不好
  • 设备能力是否匹配
  • 是否更适合本地执行

开发者更多是通过 Ability 启动方式、Service 类型、数据同步方式 来间接影响分配结果。

核心实现方式一:跨设备启动 Ability

适合什么场景

这种方式最常见,适合:

  • 页面展示
  • 功能模块整体迁移
  • 用户可感知的交互任务

比如:
手机负责控制,平板负责显示大屏内容。

Demo:在平板上启动远程 Ability

import distributedDeviceManager from '@ohos.distributedDeviceManager';
import featureAbility from '@ohos.ability.featureAbility';

const BUNDLE_NAME = 'com.example.distributeddemo';

let deviceManager = distributedDeviceManager.createDeviceManager(BUNDLE_NAME);

function startRemotePage() {
  let devices = deviceManager.getTrustedDeviceListSync();

  devices.forEach(device => {
    if (device.deviceType === 2) { // 假设 2 表示平板
      let want = {
        bundleName: BUNDLE_NAME,
        abilityName: 'RemotePageAbility',
        deviceId: device.deviceId
      };
      featureAbility.startAbility(want);
    }
  });
}

代码说明

  • createDeviceManager:创建设备管理器
  • getTrustedDeviceListSync:获取可信设备列表
  • deviceType:用于简单区分设备类型
  • startAbility:指定 deviceId 后,Ability 会在远端设备启动

整个过程不需要你关心远端设备的进程、生命周期,系统会处理。

核心实现方式二:分布式 Service 执行任务

适合什么场景

这种方式更适合:

  • 计算密集型任务
  • 后台处理
  • 不需要 UI 的逻辑

比如:
手机采集数据,交给性能更强的设备做分析。

Demo:连接远端计算 Service

import featureAbility from '@ohos.ability.featureAbility';

function connectRemoteService(remoteDeviceId: string) {
  let want = {
    bundleName: 'com.example.distributeddemo',
    abilityName: 'ComputeServiceAbility',
    deviceId: remoteDeviceId
  };

  featureAbility.connectAbility(want, {
    onConnect(elementName, remote) {
      console.log('远程 Service 已连接');
      remote.sendMessage({
        command: 'startCompute',
        data: [1, 2, 3, 4]
      });
    },
    onDisconnect() {
      console.log('远程 Service 已断开');
    }
  });
}

代码说明

  • Service 在远端设备运行
  • 本地通过 IPC 的方式和远端通信
  • 计算逻辑完全在远端执行
  • 本地只负责发请求、收结果

这种方式非常适合“重计算、轻交互”的任务。

典型应用场景分析与示例

场景一:手机 + 平板的学习展示系统

场景说明

  • 手机负责控制、翻页
  • 平板负责展示课件内容

实现思路

  • 手机发现平板
  • 在平板启动展示 Ability
  • 通过分布式数据同步当前页码
import distributedData from '@ohos.data.distributedData';

async function syncPage(page: number) {
  let kvManager = distributedData.createKVManager();
  let store = await kvManager.getKVStore('pageStore');
  await store.put('current_page', page);
}

平板端监听数据变化,自动刷新页面。

场景二:多设备健康数据分析

场景说明

  • 手表采集心率
  • 手机做基础处理
  • 平板做数据可视化

实现思路

  • 手表同步原始数据
  • 手机过滤、预处理
  • 平板负责展示图表

核心在于:
任务不是“复制”,而是“分工”。

场景三:家庭智慧屏协同控制

场景说明

  • 手机是遥控器
  • 智慧屏负责 UI 展示
  • 计算逻辑放在智慧屏

实现思路

  • 手机只负责发指令
  • 智慧屏 Service 处理业务逻辑
  • 结果同步回手机

这种模式下,手机压力很小,体验反而更流畅。

常见问题 QA

Q1:我能不能指定“一定要某台设备执行”?

不推荐。
鸿蒙的设计思想是 声明需求,而不是指定设备
你可以通过能力需求去“引导”,但不建议写死。

Q2:设备突然下线怎么办?

系统会通知连接断开,
你需要做的只有一件事:
支持本地降级执行或重试。

Q3:分布式任务一定比本地慢吗?

不一定。
当任务本身就不适合本地执行时,
分布式反而更快、更省电。

总结

在鸿蒙系统中,多设备任务分配并不是一套复杂、难以理解的机制,它的核心思想其实很简单:

  • 把任务拆清楚
  • 描述好任务需求
  • 把调度交给系统

只要你在设计阶段考虑好“哪些任务适合分出去”,鸿蒙的分布式能力就能自然地帮你把事情做好。

一句话总结就是:

多设备任务分配,不是设备协作有多复杂,而是你有没有把任务设计清楚。

在这里插入图片描述

摘要

随着 HarmonyOS / OpenHarmony 在手机、平板、智慧屏、车机等多设备上的落地,应用的复杂度正在明显提升。页面不再只是简单展示,而是伴随着网络请求、数据计算、设备协同等大量逻辑。如果这些逻辑处理不当,很容易出现页面卡顿、点击无响应,甚至 Ability 被系统回收的问题。

线程阻塞,已经成为鸿蒙应用开发中最容易踩坑、也最影响体验的问题之一。本文将结合实际开发场景,用尽量口语化的方式,聊一聊在鸿蒙系统中如何系统性地避免线程阻塞,并给出可以直接运行的 Demo 代码。

引言

在早期的应用开发中,很多开发者习惯把逻辑直接写在点击事件里,或者在页面加载时同步读取数据。这种写法在简单页面中问题不大,但在 HarmonyOS 这种强调流畅体验和多设备协同的系统中,很容易暴露问题。

鸿蒙的 UI 是声明式的,系统对主线程(UI 线程)非常敏感。一旦主线程被占用,页面掉帧、动画卡住、操作延迟都会立刻出现。因此,理解哪些操作会阻塞线程,以及如何把这些操作合理地“挪走”,是每个鸿蒙开发者绕不开的一课。

下面我们从原理、工具、代码和真实场景几个角度,完整地拆解这个问题。

为什么线程阻塞在鸿蒙中这么致命

UI 线程到底在忙什么

在 HarmonyOS 中,UI 线程主要负责三件事:

  • ArkUI 页面渲染
  • 用户事件分发(点击、滑动等)
  • Ability 生命周期回调

简单理解就是:只要和“看得见、点得动”有关的事情,几乎都在 UI 线程上完成

一旦你在这里做了耗时操作,比如计算、IO、网络等待,页面就会立刻表现出“卡”的感觉。

常见的阻塞来源

在实际项目中,最容易导致阻塞的操作通常包括:

  • 同步网络请求
  • 文件读写
  • 数据库查询
  • 大量 for 循环计算
  • 人为 sleep 或死循环

这些操作本身不一定是错的,问题在于它们被放在了不该放的线程上

鸿蒙中避免线程阻塞的核心思路

一个总原则

可以把鸿蒙里的线程使用总结成一句话:

UI 线程只处理 UI,其他事情交给异步、线程池或 Worker。

围绕这个原则,系统也提供了多种工具,帮助开发者把任务“分流”。

异步编程是第一道防线

使用 async / await 处理耗时逻辑

在 ArkTS 中,官方推荐优先使用 Promise 和 async / await。它的好处是代码结构清晰,而且不会阻塞 UI 线程。

示例:页面加载网络数据

@Entry
@Component
struct AsyncDemo {
  @State message: string = '加载中...'

  build() {
    Column() {
      Text(this.message)
        .fontSize(20)
        .margin(20)

      Button('重新加载')
        .onClick(() => {
          this.loadData()
        })
    }
  }

  async loadData() {
    this.message = '请求中...'
    let response = await fetch('https://example.com/data')
    let result = await response.text()
    this.message = result
  }
}

代码说明

  • loadData 使用 async 声明,不会阻塞 UI
  • await 只是暂停当前函数执行,不会卡住页面
  • UI 更新完全由状态变化驱动

这是最基础、也是最常用的一种防阻塞方式。

TaskPool:处理计算和 IO 的利器

什么时候该用 TaskPool

当你遇到下面这些情况时,TaskPool 几乎是必选项:

  • 大量计算
  • 批量数据处理
  • 文件压缩、解析

可运行 Demo 示例

import taskpool from '@ohos.taskpool'

@Concurrent
function calculateSum(count: number): number {
  let sum = 0
  for (let i = 0; i < count; i++) {
    sum += i
  }
  return sum
}

@Entry
@Component
struct TaskPoolDemo {
  @State result: string = '等待计算'

  build() {
    Column() {
      Text(this.result)
        .fontSize(18)
        .margin(20)

      Button('开始计算')
        .onClick(() => {
          this.startTask()
        })
    }
  }

  startTask() {
    this.result = '计算中...'
    taskpool.execute(calculateSum, 1000000).then(res => {
      this.result = `结果是:${res}`
    })
  }
}

代码说明

  • @Concurrent 表示该函数可以并发执行
  • TaskPool 自动管理线程,不需要开发者手动创建线程
  • UI 线程只负责接收结果和更新状态

在真实项目中,使用 TaskPool 往往能立刻解决页面卡顿问题。

Worker:长期后台任务的选择

Worker 的使用场景

如果任务具有下面这些特点,就更适合使用 Worker:

  • 长时间运行
  • 需要持续处理数据
  • 与 UI 强隔离

比如日志分析、音视频处理、复杂解析等。

示例:使用 Worker 处理数据

主线程代码

let worker = new Worker('workers/data_worker.ts')

worker.postMessage({ action: 'start' })

worker.onmessage = (e) => {
  console.log('收到结果:', e.data)
}

Worker 线程代码

onmessage = function (e) {
  if (e.data.action === 'start') {
    let result = 0
    for (let i = 0; i < 500000; i++) {
      result += i
    }
    postMessage(result)
  }
}

代码说明

  • Worker 与 UI 线程完全独立
  • 即使计算时间较长,也不会影响页面交互
  • 通过消息机制进行通信

结合实际场景的应用示例

场景一:列表页面加载大量数据

问题:

  • 首次进入页面时一次性处理全部数据
  • 页面明显卡顿

解决思路:

  • 网络请求使用 async
  • 数据整理放入 TaskPool
async loadList() {
  let data = await fetchData()
  taskpool.execute(processData, data).then(list => {
    this.list = list
  })
}

场景二:文件导入与解析

问题:

  • 文件较大
  • 解析过程耗时

解决思路:

  • Worker 负责解析
  • UI 只显示进度
worker.postMessage({ filePath })

场景三:复杂计算驱动 UI 更新

问题:

  • 计算逻辑和 UI 耦合

解决思路:

  • 计算完全放到 TaskPool
  • UI 只订阅结果

QA 环节

Q:async / await 会不会阻塞线程?
A:不会,它只是让出执行权,不会卡住 UI 线程。

Q:TaskPool 和 Worker 怎么选?
A:短期、一次性的任务优先 TaskPool,长期或持续任务用 Worker。

Q:能不能在生命周期里做耗时操作?
A:不建议,生命周期函数应尽量轻量。

总结

线程阻塞并不是某一个 API 的问题,而是设计问题。在 HarmonyOS 中,系统已经为我们准备好了异步模型、TaskPool 和 Worker,只要遵循“UI 线程只做 UI”的原则,大多数卡顿问题都可以提前避免。

在真实项目中,提前做好任务拆分、线程规划,比后期排查卡顿要省心得多。这也是鸿蒙开发从“能跑”到“跑得顺”的一个重要分水岭。

本文引用了45岁老架构师尼恩的技术分享,有修订和重新排版。

1、引言

分布式IM聊天系统中,IM消息怎么做到不丢、不重、还按顺序到达?这个问题,涉及到IM系统的两个核心:1)消息不能丢(可靠性):比如用户点了发送,不能因为服务宕机或网络抖动,消息石沉大海。比如地铁隧道、电梯间,网络断了又连,消息不能卡住不动(要确保弱网也能用)。2)顺序不能乱(有序性):比如“在吗?” 回成 “吗在?”,群聊时间线错乱,体验直接崩盘。这二大痛点,是IM聊天系统架构的命门所在。下面是一张IM消息从发出到接收的关键路径:
图片

2、系列文章

为了更好以进行内容呈现,本文拆分两了上下两篇。本文是2篇文章中的第 1 篇:《如何保障分布式IM聊天系统的消息有序性(即消息不乱)》(☜ 本文)《如何保障分布式IM聊天系统的消息可靠性(即消息不丢)》(稍后发布..)本篇主要总结和分享分布式IM聊天系统架构中关于消息有序性的设计和实践。

3、传统技术方案的瓶颈,怎么破?

早期做消息有序,很多人第一反应是搞个“全局发号器”——所有消息排一队,挨个编号再发。理想很丰满,现实很骨感:高并发下一拥而上抢号,发号器直接被打满;更致命的是,它一旦宕机,全链路雪崩。这就像春运火车站只开一个售票窗——再快也撑不过三分钟。所以,我们必须换思路:不搞大一统,而是分片独立发号,让每个“窗口”自给自足,互不干扰。

4、痛点拆解:为什么消息会乱?

我们先还原一个真实场景: 想象一下你和朋友聊天:你说:“1 吃饭了吗?”他回:“2 刚吃完。”你又说:“3 吃啥呢?”结果对方手机上显示成:“3  吃啥呢?” → “1 吃饭了吗?” → “2 刚吃完。”这不是 bug,是分布式系统的常态。三条消息走不同服务节点、经不同网络路径,到达时间完全不可控,最终呈现顺序错乱。会乱 问题本质是什么?一个要“串行等”,一个想“并发冲”,天然冲突。这时候有人会说:那我加个全局排序服务不就行了?可以,但代价太大——一个中心节点最多撑几万 QPS,面对百万群聊、亿级用户,还没上线就已过载。所以,全局有序不是解,而是枷锁。我们要的不是“天下大同”,而是“各聊各的别乱就行”。

5、最终方案:分而治之 + 局部有序

真正的突破口在于:我们根本不需要全局有序,只需要“会话内有序”。你和张三的聊天记录不能乱,但你和李四的聊天跟王五的完全无关——何必放一起排序?这就引出了经典策略:分而治之 + 局部有序。具体怎么做?两步走稳: 第一步 - 业务分区: 哈希分片,锁定归属用 sessionId 做一致性哈希,确保同一个会话的所有消息始终路由到同一个处理节点。按“会话ID”做哈希,算出该消息该由哪个节点处理。同一会话 → 哈希值一样 → 路由到同一台机器 → 所有消息串行处理,天然避免跨节点乱序。这样一来,单个会话内的消息在服务端就是串行处理的,天然不会乱。 第二步 - 局部序号:独立发号,局部递增每个会话独立维护一个计数器,每来一条消息就+1,作为它的“官方序号”。每个会话,可以配一个独立计数器(比如 Redis 的 INCR),每来一条消息就+1,生成唯一 SEQ。客户端不管什么时候收到消息,只认这个序号,按序号从小到大排列展示。这个 SEQ 就是这条消息的“官方身份证号”,客户端只认这个,不看接收时间。这就像电影院检票——你可以早到晚到,但座位按票号定。哪怕后排观众先进场,也不会坐到前排去。PS:IM消息ID生成相关的文章可详细阅读以下资料:《IM消息ID技术专题(一):微信的海量IM聊天消息序列号生成实践(算法原理篇)》《IM消息ID技术专题(二):微信的海量IM聊天消息序列号生成实践(容灾方案篇)》《IM消息ID技术专题(三):解密融云IM产品的聊天消息ID生成策略》《IM消息ID技术专题(四):深度解密美团的分布式ID生成算法》《IM消息ID技术专题(五):开源分布式ID生成器UidGenerator的技术实现》《IM消息ID技术专题(六):深度解密滴滴的高性能ID生成器(Tinyid)》《IM消息ID技术专题(七):深度解密vivo的自研分布式ID服务(鲁班)》

6、实践落地(核心片段伪代码)

1)服务端分片路由逻辑:来看关键实现:如何把消息精准投递给“对的人”。String sessionId = msg.getSessionId();//这里是伪代码,实际代码以mq 的负载均衡机制为准int nodeIndex = Math.abs(sessionId.hashCode()) % clusterNodeCount; //这里写个伪代码,代表mq  主从复制ClusterNode targetNode = clusterNodes.get(nodeIndex);targetNode.sendMsg(msg);核心就一句:基于会话 ID 哈希取模,固定路由。从此,每个会话都有了自己的“专属服务通道”,不再受其他会话影响。2)服务端序号分配逻辑:接下来,给每条消息发“通行证”:long msgSeq = redis.incr("msg_seq_" + sessionId);msg.setSeq(msgSeq);msg.setUniqueKey(sessionId + "_" + msgSeq);这里用了 Redis 的 INCR,保证同一个会话下的 SEQ 绝对递增,且线程安全。同时用 sessionId_seq 作为唯一键,既能幂等去重,也能防止重试导致消息重复入库。实战提示:如果你的 Redis 是集群模式,记得确保同一个会话的 key 落在同一 slot,否则 INCR 可能跨节点失效。3)客户端排序逻辑:最后一步,客户端收尾:别急着渲染,先排好队。//这里是伪代码, 先排序List<Msg> sortedMsgs = msgList.stream()    .sorted(Comparator.comparingLong(Msg::getSeq))    .collect(Collectors.toList());//这里是伪代码, 再渲染renderMsgList(sortedMsgs);无论消息以什么顺序到达,统统按 seq 升序排列后再上屏。哪怕第100条先到,第1条后到,也能正确归位。这也是为什么我们强调“客户端必须信任服务端 SEQ”——它是唯一真相源。

7、方案总结:放弃全局有序,换高可用与高性能

总结一下,这套方案的核心思想就一句话:不要为“假需求”买单——我们不需要全局有序,只需要业务上有意义的有序。你看微信、钉钉、飞书,哪一个是把全平台消息排成一条队列的?没有。它们都选择了“会话级隔离 + 局部有序”的设计,这才是工业级系统的通用解法。背后的分布式哲学也很清晰:
图片

最终换来的是:1)高并发支持(水平扩展);2)高可用(无单点);3)强一致体验(用户无感知)。这正是中高级开发者必须掌握的权衡思维:不是技术做不到,而是要不要做。有时候,“不做全局有序”,反而是最正确的选择。

8、 IM消息有序性架构的核心流程总结

最后,一张图串起全流程:
图片
从发起到渲染,全程围绕“会话隔离”和“局部发号”展开。每一个环节都在为同一个目标服务:在分布式环境下,低成本实现用户可感知的“顺序正确”。

—— 下篇《如何保障分布式IM聊天系统的消息可靠性(即消息不丢)》稍后发布,敬请期待 ——

9、参考资料

[1] 什么是IM聊天系统的可靠性?
[2] 什么是IM聊天系统的消息时序一致性?
[3] 微信技术分享:微信的海量IM聊天消息序列号生成实践(算法原理篇)
[4] 马蜂窝旅游网的IM系统架构演进之路
[5] 一套亿级用户的IM架构技术干货(下篇):可靠性、有序性、弱网优化等
[6] 从新手到专家:如何设计一套亿级消息量的分布式IM系统
[7] 企业微信的IM架构设计揭秘:消息模型、万人群、已读回执、消息撤回等
[8] 融云技术分享:全面揭秘亿级IM消息的可靠投递机制
[9] 阿里IM技术分享(四):闲鱼亿级IM消息系统的可靠投递优化实践
[10] 阿里IM技术分享(八):深度解密钉钉即时消息服务DTIM的技术设计
[11] 基于实践:一套百万消息量小规模IM系统技术要点总结
[12] 一套分布式IM即时通讯系统的技术选型和架构设计
[13] 转转平台IM系统架构设计与实践(一):整体架构设计
[14] 移动端弱网优化专题(一):通俗易懂,理解移动网络的“弱”和“慢”
[15] 移动端弱网优化专题(二):史上最全移动弱网络优化方法总结
[16] Web端即时通讯实践干货:如何让你的WebSocket断网重连更快速?
[17] 从客户端的角度来谈谈移动端IM的消息可靠性和送达机制
[18] IM消息送达保证机制实现(一):保证在线实时消息的可靠投递
[19] 移动端IM中大规模群消息的推送如何保证效率、实时性?
[20] 如何保证IM实时消息的“时序性”与“一致性”?
[21] 一个低成本确保IM消息时序的方法探讨

即时通讯技术学习:

(本文已同步发布于:http://www.52im.net/thread-4887-1-1.html

看了 vercel 刚发布的 react-best-practices-skill,觉得还不错,然后这周末就花两天用 Claude Code + GLM 4.7 写了个用来做在线订阅转换的工具:Clash Converter ,欢迎大家来体验或者提意见

  • 域名成本 12.99$
  • CICD 用的免费的 Github + Cloudflare Workers
  • LogoNano Banana Pro + Chatgpt生成的

火线Zone 25年Q1季度技术文章奖励公示

亲爱的火线Zone社区成员们,

自火线Zone征稿奖励方案启动以来,我们收到了众多技术专家的杰出投稿。这些高质量的原创技术文章不仅丰富了我们的社区知识库,也极大地促进了安全技术的交流与分享。在此,我们对所有积极参与的创作者表示衷心的感谢,并希望激励更多的技术专家加入我们的行列,共同推动技术安全生态的繁荣发展。

精华文章奖

经过严格的小组讨论审核,以下文章内容符合奖励要求,文章凭借其深度分析和独到见解,手法招式新奇有创意,荣获”精华文章奖“,各获得100查克拉 + 1000RMB的奖励;

  1. 红队实战:谈一谈红队中的钓鱼姿势实战版 作者:和
  2. 【挖洞之旅】一种验证码爆破漏洞的全新思路 | 简单实用 作者:cc55y

优秀文章奖

经过严格的审核流程,以下文章符合社区征稿意向,内容充实有新意,荣获“优秀文章奖”,各获得50查克拉积分 + 500RMB的奖励:

  1. 将AI结合进越权扫描,助力SRC挖掘。 作者:Ed1s0n
  2. 谈一谈红队中的社工钓鱼姿势(上) 作者:和
  3. 谈一谈红队钓鱼中的姿势(中) 作者:和
  4. 谈一谈红队种的钓鱼姿势(下) 作者:和

基础投稿奖

以下文章也通过了我们的审核,符合基础投稿奖励要求,每位作者将获得50查克拉积分的奖励:

  1. 利用Ollama对Deepseek 模型进行攻击 作者:jylove
  2. 红队攻防中HW的一些艺术 作者:routing

奖励发放说明

  • 所有获得奖励的文章将同步发表在火线Zone公众号上,以飨更广泛的读者群体。
  • 奖励将在每月的第一周统一发放,涵盖上月投稿的所有合格文章。请获奖者留意自己的火线安全平台账户。
  • 如对奖励有任何异议或疑问,请及时联系火线小助手

内容征集及奖励方案详情

我们诚邀更多的技术专家加入火线Zone社区,共同构建技术安全生态。更多内容征集及奖励方案详情请访问:火线Zone社区规则升级,共建技术安全生态

结语

火线Zone社区对每一位创作者的辛勤工作和贡献表示最深的敬意。我们期待在未来的日子里,继续与您携手合作,共同书写技术安全的新篇章。

再次感谢所有支持火线Zone的朋友们!

火线Zone社区团队
2025年4月


版权声明: 本文内容由火线Zone社区原创发布,未经允许,不得转载或用于商业用途。如需转载,请遵守转载说明中的相关规定。

使用 springboot 集成 micrometer 实现自定义 prometheus 指标。
假如在多实例的商城系统中存在一个用于统计商品查看次数的指标,名为 item_view_count ,label:item_idinstance_id
当服务重启时,按照 micrometer 的默认行为,这个指标会被置为 0 。

对于这个行为我想到了两种方案。

  1. 将这个值持久化,并且在第一次创建指标时加载。
  2. 服务重启后使用新的 instance_id ,这样在做 sum 统计时不会被重置影响

各位都是如何处理这个问题呢?

核心赛道:服务 5000 万+头部用户,阿里核心业务,离商业核心最近。

技术硬核:告别简单 CRUD ,直面双 11 高并发、AI 智能与复杂权益架构。

快速成长:大促即战场,拥有全域技术视野与顶级实战历练。

寻找不甘平庸的技术合伙人,一起重塑会员体验!

简历直接发邮箱: [email protected]