LOGO
首页 网站广场 站长动态 活跃度榜 审核查询 逛逛好站 留言交流 提交申请 关于本站

站长动态

站长动态所展示的是已加入好站网成员站长文章
共同步 2381 篇博文
(每2小时更新一次)
姓王者
入驻第1年
hexo-next在文章下添加版权信息
cp1修改主题目录下的_config.yml文件themes/next/_config.yml## Creative Commons 4.0 International License. ## See: https://crea...
姓王者
入驻第1年
hexon:hexo的可视化编辑
你是否对这些命令感到枯燥乏味? hexo g| hexo d|hexo s
阿川
入驻第1年
聊聊自行车
阿川
入驻第1年
写一个骑行页面(二)
陈仓颉
入驻第1年
七月观影
这个七月看的影视剧较平时多,有一些对自己比较重要的需要记录一下。顺便补上前两个月的观影记录。 抓娃娃 3.8/ […]
阿川
入驻第1年
与时间抗衡:笔记本清灰换硅脂记
阿川
入驻第1年
写一个骑行页面
阿川
入驻第1年
写一个Chrome表单自动化插件
阿川
入驻第1年
七月最后一天骑行,有氧100公里
阿川
入驻第1年
利用Go+Github Actions写个定时RSS爬虫
阿川
入驻第1年
腾讯CDN流量被恶意盗刷
阿川
入驻第1年
公路车管胎被扎,怎么补胎
阿川
入驻第1年
喜提新车 Wilier Cento 10SL
姓王者
入驻第1年
本来想搬fishport_serverwiki来着
本来想搬fishport_server_wiki来着一个我的世界服务器wiki图片感觉\x7e~还行~~,但是能力不足,况且搬到github上托管,对别的玩家来说,写wiki门槛似乎有点高了应该...
姓王者
入驻第1年
我的第一个博客
头像大头我的第一个博客应该不是最后一个为什么我想写一个博客最佳回答:我不知道显而易见的是,纯粹是我闲着没事干,又或者算是心血来潮,就像某些人明明没有什么需求缺偏要弄ipv6或者免流什么的 至少我...
九仞
入驻第1年
在Arch Liunx里只用Intel Ultra 7 155H跑stable-diffusion-webui
引言 虽然我把arch linux装在了移动硬盘里,使得我可以同时在我的轻薄本和游戏本之间运行同一个系统,并拥 […]
姓王者
入驻第1年
forever
记录一下搭建博客所用的资料真的非常感谢他们 !致以由衷的敬意!链接如下别忘了给他们点个star!Hexo 个人博客搭建及主题配置教程 [2024]在Hexo中给自己的博客添加萌萌Live2d看板...
乌托邦
入驻第1年
一些近况-202404
好久不见!距离上一次更新文章已经是两个月之前的事情了,在这两个月里,Utopia’s添加了一些新的业务和功能,下面让我们来看看都有什么新升级吧。 最大的升级,我们启用了全新的二级域名: utopias.site 这是一个比原来的域名更加具有辨识度的域名。因此,我们的博客也使用了全新的域名 b.utopias.site 。同时,Utopia‘s已经不只局限于单一的博客网站了,新的域名将更加方便构建“Utopia’s Universe”。 小改动。友链功能全新升级成为Utopias导航页,这里将收录不只是友链,还有Utopias系列站点。所有的页面都可以在导航页方便地查询和一键直达。 在经过4月的试点和5月的调整后,我们推出全新的功能UtopiAI。这是一个基于开源项目私有化部署的AIGC对话平台,接入了市面上主流的大模型,让与全世界最先进的AI对话不再复杂。 与UtopiAI同时上线的,还有乌托邦的小店Utopishop。目前店铺处于测试阶段,仅负责UtopiAI的点卡发行和售卖。 Todo: 筹备私有化部署的AI绘画平台Utopaint,接入mj、sd和通义万象。 完善UtopiAI的doc帮助文档,让UtopiAI接入更多的大模型。
陈仓颉
入驻第1年
《富兰克林自传》书摘
我最早在和菜头的《把自己安放妥当》这篇文章中得知《富兰克林自传》后开始阅读,开了个头不久便搁置,直到近期才一口 […]
Debug
入驻第1年
Phoenix框架 从0到1设计业务并发框架 自动构建有向无循环图设计
从 0 到 1 设计业务并发框架系列: Phoenix 框架 小米商城产品站革新之路 Phoenix 框架 怎么组织设计一个框架 Phoenix 框架 并发线程池的核心设计 Phoenix 自动构建有向无环图的业务并发框架,核心就在于不需要开发人员关心调用分层和依赖互斥的排序问题,通过算法进行自动构建、收集 Task 任务、检测环或者依赖,最后打印并发组分层信息。 本篇文章就讲解下如何构建有向无环图的设计实现方案及遇到的问题。 实现方案 有向无环图的构建采用的是设计模式中的策略模式,首先定义好 Builder 的实现方式,如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 /** * @author debuginn */ public interface PhoenixBuilder { // 过滤 Phoenix API 使用到的 Task 任务 Map<String, ArrayList<TaskObj>> filterApiUsedTask(ArrayList<TransObj> transObjArrayList); // 根据 api 获取需要执行的 trans Map<String, ArrayList<TransObj>> apiTransMap(ArrayList<TransObj> transObjArrayList); // 是否存在依赖关系 void isHaveLoop(Map<String, ArrayList<TaskObj>> apiUsedTaskMap); // 处理并发组分层划分 Map<String, ArrayList<ArrayList<TaskObj>>> processConcurrentGroup(Map<String, ArrayList<TaskObj>> apiUsedTaskMap); // 打印并发组分层信息 void printConcurrentGroup(Map<String, ArrayList<ArrayList<TaskObj>>> phoenixApiArrayListMap); } PhoenixBuilder 需要实现 6 种方法: 首先,将收集上来的 Task,按照 API 进行分组,Task 存在依赖调用的都进行收集; 按照 API 进行收集 Trans,后续 Trans 使用请求线程进行串行执行; 判定每个 API 收集上来的 Task 是否存在相互依赖或循环依赖; 将每个 API 收集上来的 Task 按照先后依赖关系进行分组划分; 打印并发分组信息,用来给开发者调试及校验使用; 由于存在依赖关系,需要进行分层设计,这里可以结合 Phoenix 框架 怎么组织设计一个框架 来看,然而每一层并不需要关系执行的顺序问题,这里采用了最简单的数据结构存储分层信息,Map<String, ArrayList<ArrayList<TaskObj>>> Key 用来标识属于哪个 API 请求的并发分组,Value 则采用最简单的二维数组进行存储,每一维分别存储需要进行执行的 Task 任务。 遇到的问题 怎么判定存在环 由于我们要进行构建的是有向无环图,那么存在相互依赖的 Task,在框架设计逻辑中是行不通的,若存在相互依赖,那么究竟该先执行哪个 Task 呢? 可以看到上图,只要有两个场景: 相互依赖关系:TaskB 与 TaskD 存在相互依赖,那么就不能确定执行顺序; 环状依赖关系:TaskD、TaskF、TaskG 和 TaskE 存在依赖环,也无法确定执行顺序; 相互依赖关系判定比较简单,就是检索一个 TaskA 依赖的 TaskB 是不是也依赖这个 TaskA, 循环依赖判定相对来说比较复杂,需要遍历图的所有路径,若路径存在闭环,则代表着存在环,反之,就是不存在环路,代表就是单向依赖的分支路径。 怎么划分并发分组 划分并发分组,就是将彼此没有依赖关系的 Task 按照依赖的先后顺序进行分组,其实就是按照图的深度遍历。 这里的遍历,由于有依赖关系,可以采用向上遍历或者向下遍历的方式,我们采用了压栈的方式处理: 向上遍历 首先找到没有被依赖的 Task,这是一组,之后存入数组压入栈底; 之后栈底的 Task 收集出来需要依赖的 Task,这些收集上来的 Task 需要再判定是不是被其他 Task 依赖,若是依赖的话,则保存在临时的 Task 数组中,最后将剩下 Task 就是只被栈底 Task 数组依赖的 Task,那么将这个分组继续压入栈内; 重复第 2 步,把栈底的 Task 换成栈内最上层的数组,之后再把临时 Task 追加到收集出来需要依赖的 Task 上,去重,之后重复执行; 最后执行到剩下的 Task 没有依赖的 Task,这就是最后一个并发组,之后压入栈内; 最后程序执行的时候,就是先执行栈顶部的并发组,之后一次出栈执行。 向下遍历 首先找到不依赖其他 Task 的 Task,这是一组,之后存入数组压入栈底; 之后栈底的 Task 收集出来依赖这个分组的 Task,这些收集上来的 Task 判定是不是被其他 Task 依赖,若是依赖,也是保存在临时的 Task 数组中,最后就只剩下只依赖栈底的 Task 数组的 Task,之后将这个数组压入栈内; 重复第 2 步,把栈底的 Task 换成栈内最上层的数组,之后再把临时 Task 追加到收集出来需要依赖的 Task 上,去重,之后重复执行; 最后执行到剩下的 Task 没有任何 Task 依赖,这就是最后一个并发组,之后压入栈内; 此时,这个堆栈存储的是最先执行的 Task 并发分组在栈底,最后执行的在栈顶,需要进行反转操作,之后再依次进行执行。 为何要使用"策略模式" 在开发程序的时候,大家都不约而同地讲究程序的横向扩展能力,将核心的关键的任务拆分成具体执行的子任务,这样不仅可以提高程序的可阅读性,而且还可以扩展不同的遍历算法,用来后续框架的持续优化。 不仅这里,Phoenix 框架尽可能的采用策略模式实现,将核心功能点都进行拆分,做到模块化设计,这样的设计正是 Phoenix 框架的设计初衷,生生不息,持续迭代。 写在最后 本篇文章主要讲了如何进行自动构建有向无循环图的思路及遇到的问题,其实在开发中,这种解决依赖关系的场景还有很多,其实抛开上层的业务实现或者框架需求来看,底层就是最基本的数据结构,算法,图的遍历场景在当今比较火的 AI 场景下也是如此。 感谢你的阅读,你要是有好的方案或者好的 idea 可以与我一起交流,最后,如果你感兴趣,推荐关注公众号或订阅本站,欢迎互动与交流,让我们一起变得更强~ 关注微信公众号,第一时间获取最新内容,让我们一起变得更强!Debug客栈:订阅本站· 文章归档· 我的项目· 友情链接· 我的使用· 飞湾计划· 摄影展集· 我的主页

© 2026 好站网HaoZhan.wang 1.5 版权所有

苏ICP备19065220号-4 萌ICP备20269980号 茶ICP备2026050346号 本站数据 版本历史 关于本站