新闻详情

新闻详情

首页 / 资讯中心 / 详情

第 25 章 · 并发与队列:opChain——快速连点按钮为什么不能丢数据

发布时间:2026/10/2 16:29:11来源:尧图网络
第 25 章 · 并发与队列:opChain——快速连点按钮为什么不能丢数据
本章你将学会看懂await的真正含义——“让座”程序会在这里停下来等别人就可能先走明白读→改→写中间有让座点时为什么单线程的 JavaScript 也会丢数据学会一招经典修法用 Promise 链把所有写盘操作排成一条队伍opChain在控制台里亲手复现一次丢数据再亲手修好它需要的前置章节第 3 章函数与循环、第 10 章props 与 emit、第 13 章数据存到哪去、第 14 章间隔重复对应项目文件src/App.vue、src/store.ts25.1 从一个场景开始小雅是我们书里手速最快的用户。她背单词有个习惯翻卡片看一眼背面“记得”手指一拍按钮立刻翻下一张。一张卡平均两秒。这天她一口气刷完了 20 张卡心满意足地关掉软件。第二天打开报告页她愣住了昨天的复习记录只有 19 条。有一张卡——她明明点了记得的那张panda——分数纹丝不动还躺在待复习队列里。“软件吃掉了我的一个 panda”更怪的是她故意慢慢点一张一张隔两秒再点一次都没丢。只有快速连点的时候才会丢。一个只在手速快时才出现的 bug是最难抓的 bug——因为它不是每次都发生。它像一只躲在门后的猫你慢慢走它就伸出爪子拍你一下你盯着门看它装得什么都没发生。而且它还有三个更气人的特点。第一丢的东西看不见软件没报错、没闪退、没弹警告分数就是安静地消失了像从来没被点过。第二没法保证重现测试的同学慢慢点了五十次都好的小雅回家一连点就丢了——你甚至怀疑是不是她记错了。第三它专挑你最贵的数据下手丢的不是界面颜色是写进硬盘的学习记录。界面出了 bug 刷新就好数据出了 bug就是真的没了。这一章我们就把这只猫抓出来看清楚它的长相然后永远地赶走它。【配图说明左边小朋友快速连点记得按钮手指带残影右边报告页少了一条记录中间一只写着竞态的猫躲在门后偷笑】25.2 原理await 是让座先复习一个老朋友。第 3 章我们说过JavaScript 是单线程的——整个软件只有一个厨师一口锅菜只能一盘一盘炒。按常理只有一个人干活是不会出乱子的他炒完一盘再炒下一盘谁会踩谁的脚可是这个厨师有个毛病他会在一半的时候离开工位。只要一道菜里需要等——等烤箱、等水开、等写盘——他就会用await说一句我先让个座您先请。然后让出工位去炒别的菜。关键就在这儿让座的瞬间另一个人已经坐上来开工了。一次点记得到底走了哪几步我们把小雅点下记得按钮之后发生的事拆成一条流水线点记得 → StudySession emit(grade) → App.vue onGrade() → gradeCard(卡片, good) ← 纯计算新分数算出来 → saveCard(data, 新卡) ← ① 拿着当前数据快照做修改 → persist(新快照) ← ② await写进 engflow.json让座点 → data 新快照返回注意第 ② 步写硬盘或者写存储是异步的代码里写的是await persist(next)。这一await就是厨师说的我先让座。现在让小雅连点两张卡。我们把当前全部学习数据想象成一本班级点名册data.value就是教室里唯一的原件。第一次点击给panda打分出发抄了一份点名册快照 A在副本上给 panda 添了成绩走到办公室——办公室只有一支笔写盘资源前面有人它开始等第二次点击给abandon打分出发——注意此刻第一次点击还站在办公室门口等笔还没把改好的册子交回去所以教室里的原件还是旧的那本。第二次点击抄了一份点名册——抄的还是快照 A没有 panda 的成绩在副本上给 abandon 添了成绩也排队等笔。接下来恐怖的事情发生了第一次点击拿到笔交回有 panda、没有 abandon 的册子教室原件被替换第二次点击拿到笔交回有 abandon、没有 panda的册子——后交的把先交的抹掉了。panda 就这样被吃掉了。这就是著名的丢失更新lost update两个人各抄了一份班级点名册、分别添了一个人、后交的覆盖先交的。两个人都没有错笔也没有坏错只错在——抄册子和交册子之间隔着一段等而这段时间里另一份册子已经出发了。【配图说明上下两条时间轴。上轴点击1抄A → 改panda → 等笔 → 交回下轴点击2抄A → 改abandon → 等笔 → 交回(覆盖)中间标出两次抄A读到的都是同一份旧快照】顺便说一句这个坑有个响亮的大名叫竞态条件race condition——竞是比赛的竞两段代码像在赛跑谁先谁后决定结果对错。你不需要背这个名字只需要记住它的气味只要一个功能的正确性开始依赖运气般的先后顺序就有竞态。捉拿竞态的侦探三问“这段异步中间被打断会怎样用户重复触发会怎样”第 26 章讲代码审查时会正式登场。所以本章最重要的一句话请慢慢读单线程不等于安全。危险不在同时干活而在读→改→写的中间有个让座点。只要中间有await另一份旧快照就可能已经出发了。这不是 EngFlow 特有的坑——全世界的软件不管用什么语言写只要处理先读、再改、后写的数据都可能在同一个坑里翻车。插一句让座之后被让出去的人去了哪儿你可以把整个软件想象成一部只有一个座位的电梯await是有人按了开门键。电梯门一开里面的人说一句我到几楼要办的事还没办完先让这位新乘客进去——代码里await后面的那半截并不会原地站着等它被取下来放在待办清单的末尾电梯先去处理清单里排在它前面的别的事比如又响应了一次你的点击。等它再次被抬进那唯一的座位才继续写第 ③ 步整体覆盖。这解释了两件事为什么第二次点击能插队第一次点击把后半截放进待办清单的那一刻第二次点击的代码正好排在它前面被处理——于是第二次点击的读快照发生在第一次点击的写回之前。两个人读的是同一本旧册子。为什么慢点就没事你慢两秒再点第一次点击早已把新册子交回教室第二次点击抄到的是新册子。所以 bug 的开关不是手速而是两次点击的间隔短于了写盘那一次让座的时长。写盘越慢机器越旧、文件越大这只猫越容易出来。那怎么办两个思路一是让第二次点击抄改完之后的册子太难改的过程要等根本不知道要等多久二是——干脆规定交册子这种事一次只能去一个人后来的排成一队。思路二就是本章主角队列queue。像食堂窗口饭菜只有一份一份打同学自觉排成一列纵队一次一个人。前面的人没打完后面的人绝不伸手。每个人的盘子都打到了菜谁也不会盖掉谁的。队列还有个免费的好处先预告一下它不要求队伍里每个人动作一样快。写盘 50 毫秒的人、200 毫秒的人都按到的先后顺序一个一个来。顺序由排队保证而不是由运气保证——这正是对付捉摸不定的猫的唯一靠谱办法。25.3 动手时间下面两个实验都可以直接贴进浏览器控制台F12 → Console 面板运行。它们是我们把 EngFlow 的丢数据事故缩小一万倍后的模型点名册换成了一个只装一个数字的小盒子。做实验前立一条规矩叫先猜后跑每个实验的你会看到我都遮在后面跑之前先把自己的预测大声说出来最好写在纸上再对答案。预测中了原理就长在你脑子里预测错了——恭喜你抓到了自己的一個误解那比做对十道题都值钱。本章实验 1 的预测尤其精彩几乎没有人第一次就猜对。实验 1亲手复现丢失更新4 分钟// 实验1只读、改、写但中间有 await —— 看数据怎么丢constshared{count:0};// 这就是那本点名册今日复习计数asyncfunctionaddLater(){constsnapshotshared.count;// ① 读抄一份快照awaitnewPromise((r)setTimeout(r,50));// ② 让座模拟等写盘 50 毫秒shared.countsnapshot1;// ③ 写在快照上1整体覆盖回去}asyncfunctiondemoLose(){awaitPromise.all([addLater(),addLater(),addLater(),addLater(),addLater()]);console.log(连点 5 次之后count ,shared.count);}demoLose();运行步骤随便打开一个网页 → F12 → Console → 整段贴进去 → 回车。你会看到连点 5 次之后count 1说好的 5 次呢我们一起数5 个addLater几乎同时启动全部在 50 毫秒的让座时间里挤到了同一个快照都读到0然后一个接一个醒来每个人都写0 1 1。第一个人写得对后面四个人全在用旧快照覆盖——4 次记录被吃掉了。这就是小雅的 panda她连点的两下里后一下把前一下抹掉了。想一想把setTimeout的 50 改成 0 还丢不丢丢。让座 0 毫秒也是让座。危险不取决于等待多久只取决于有没有等这个动作。实验 2给写操作排一条队6 分钟现在我们把食堂窗口的规则装上所有要动shared的操作不直接跑先排队队伍保证一次只有一个人干活。// 实验2opChain —— 把每个任务拼在同一条 Promise 链的尾巴上constshared{count:0};asyncfunctionaddLater(){constsnapshotshared.count;awaitnewPromise((r)setTimeout(r,50));shared.countsnapshot1;}letopChainPromise.resolve();// 初始队伍空的谁都排在它后面就立刻轮到自己functionop(fn){opChainopChain.then(fn).catch((e)console.error(persist op failed:,e));returnopChain;// 方便外面 await 整条队伍}asyncfunctiondemoQueue(){for(leti0;i5;i)op(addLater);// 连点 5 下全部入队constt0Date.now();awaitopChain;// 等队伍彻底走完console.log(排队之后 count ,shared.count,总耗时,Date.now()-t0,ms);}demoQueue();你会看到排队之后 count 5 总耗时 253 ms恰好 5一次不少。耗时是多少5 个任务 × 每人 50 毫秒 ≈ 250 毫秒。排队当然比蜂拥而上慢——这是诚实的代价50 毫秒写盘本来就是必须花的排队只是让它们一个一个花而不是互相踩死。原理点睛opChain opChain.then(fn)这一行为什么有魔法因为每次入队都是把新任务接在当前队伍末尾而末尾这个位置会随队伍变长不断后移。第 2 个addLater的函数体在入队时根本还没执行——它要等第 1 个跑完shared.count已经写回1才开始读快照。于是每个人抄到的都是上一个改完的册子谁也不覆盖谁。入队瞬间只登记不执行轮到你了才抄快照 —— 抄到的永远是最新的册子为什么排队不写成数组有同学会想数组tasks.push(fn)一个while (tasks.length)循环取任务执行不是更直观可以但要小心两个坑一是循环一旦跑起来就在独占那唯一的厨师你新点击的任务入速远快于消费速度时数组只增不减二是循环里抛个错没人接住整个循环死掉队伍同样解散。Promise 链妙在**等待和接新任务是同一件事**链子空闲时就自然歇着来一单走一单天生不会饿着也不会撑着还能顺手挂.catch。用现成的语言机制排队永远比手工造队列稳。【配图说明食堂窗口排队图。队伍里五个人胸前贴着 addLater窗口上挂着牌子opChain每个人轮到时手里的小本本都写着比上一个大 1 的数字】实验 3让队伍摔一跤再爬起来4 分钟队伍还有一句护身符.catch。我们故意让队伍中间的一个人绊倒看看会发生什么。// 实验3任务抛错时.catch 保证队伍不断letopChainPromise.resolve();functionop(fn){opChainopChain.then(fn).catch((e)console.error(这一单失败了,e.message));}op(async(){console.log(第 1 单正常);});op(async(){thrownewError(写盘炸了);});// 故意捣乱op(async(){console.log(第 3 单我还活着);});awaitopChain;console.log(队伍走完了);你会看到第 1 单正常 这一单失败了 写盘炸了 第 3 单我还活着 队伍走完了如果op里不写.catch第 2 单抛出错误后链子中间就出现一个永远失败的环第 3 单及以后的.then会全部被跳过——队伍原地解散你后面排进去的任务悄悄蒸发一次都不执行。你可以把.catch那行删掉再跑一遍验证第 3 单不再出现。所以记两句话排队解决互相覆盖.catch解决一个人摔倒、全队列陪葬。摔倒的人自己记下错误console.error队伍拍拍土继续走。实验 4抓那只有时才出现的猫5 分钟小雅的 bug 最气人的地方是有时丢、有时不丢。我们在实验 1 的基础上把 5 次点击的间隔拉长一点点观察丢失量怎么变化// 实验4点击间隔从 10 毫秒慢慢加到 100 毫秒看每次丢多少constshared{count:0};asyncfunctionaddLater(){constsnapshotshared.count;awaitnewPromise((r)setTimeout(r,50));// 固定写盘50msshared.countsnapshot1;}asyncfunctiontrial(gap){// gap 两次点击之间隔多少毫秒shared.count0;constclicks[];for(leti0;i10;i)clicks.push(newPromise((r)setTimeout((){addLater();r();},i*gap)));awaitPromise.all(clicks);awaitnewPromise((r)setTimeout(r,500));// 等最后一单慢慢跑完console.log(间隔,gap,ms → 点 10 次count ,shared.count);}(async(){awaittrial(10);// 疯狂连点awaittrial(30);// 快速点awaittrial(60);// 从容点比写盘还慢})();你会看到数字每次跑都可能略有浮动这正是猫的性格间隔 10 ms → 点 10 次count 1 间隔 30 ms → 点 10 次count 5 左右 间隔 60 ms → 点 10 次count 10看懂这张表你就看懂了这只猫的全部习性写盘要 50 毫秒点击间隔小于 50 毫秒时后面的点击必然抄到旧快照——30ms 这一档最说明问题每 30 毫秒点一下、每份册子要 50 毫秒才交回平均每两次点击才有一次赶在交回之后10 次点击下来只有 5 上下的数活下来真跑一遍多半给你 4 或 5这正是随机性间隔一旦大于 50 毫秒前一份册子已经交回就一次不丢。这就是为什么小雅慢慢点没事、连点就丢也是为什么这类 bug 在测试同学那里总是复现不了——测试同学打字慢。然后你可以把addLater()换成实验 2 的op(addLater)再跑一遍trial(10)无论间隔多小count 永远是 10。排队把运气变成了保证。顺手记录两个值得琢磨的现象。第一队伍的顺序 点击的顺序opChain opChain.then(fn)每次都是接在当前队尾而入队动作是同步发生的所以第 2 次点击绝不可能插到第 1 次前面——我们不但要不丢还要不乱先学的先记报告里的顺序才对。第二实验 4 里 30ms 那一档的数字每次跑都不同这就是竞态的签名——正确代码的结果是确定的有竞态的代码结果随机。以后你在任何项目里看到同样的操作两次结果不一样八成就是这条猫又出门了。25.4 回到 EngFlow真实的 opChain现在再看 App.vue 里的那十几行真代码你会发现每一行都眼熟摘自src/App.vue第 42–46、70–83 行略有简化完整版见项目// 持久化操作串行化避免快速连续评分时后一次快照覆盖前一次丢更新letopChain:PromisevoidPromise.resolve();functionop(fn:()Promisevoid):void{opChainopChain.then(fn).catch((e)console.error(persist op failed:,e));}functiononGrade(item:SessionItem,grade:Grade){op(async(){if(!data.value)return;constcardgradeCard(item.card,grade);data.valueawaitsaveCard(data.value,card,item.isNew?new:review);});}functiononGradeCard(card:CardState,kind:StudyKind){op(async(){if(!data.value)return;data.valueawaitsaveCard(data.value,card,kind);});}对照一下实验 2opChain、op()和你写的一字不差我们的op多return opChain只是为了实验方便项目里不需要。onGrade收到的每个闭包都是读data.value→saveCard里 await 写盘 → 把新快照放回data.value。这正是实验 1 的addLater也正是 25.2 节抄点名册的那三步。单词卡走onGrade、语法卡走onGradeCard、听写打卡走onStudied、收藏增删走onAddWords/onRemoveWord——所有会写盘的按钮全部从这一个窗口排队。没有人被允许绕过队伍直接persist。还有一个藏在细节里的智慧值得单独夸一句op(async () { ... data.value ... })里读data.value的代码不是入队的时候执行的是轮到自己时执行的。所以队伍里第 3 个任务读到的data.value是第 2 个任务刚刚写回的最新值。如果当初写成先把data.value读出来当参数传进队列就又回到抄旧快照的老坑里了。排队排的不只是写连读也要一起排队——这才有一次一个人的完整保证。你也许会担心排队会不会让软件变卡我们算一笔账。plugin-store 写一次engflow.json通常只要几毫秒到几十毫秒一个人连点 4 下队伍全长不过一两百毫秒——比人眼眨一次快比手指抬一次慢你永远感觉不到。而换来的是一条记录都不丢。用实验 4 的话说牺牲的是同时保住的是正确。在数据面前正确永远优先于快。而store.ts里saveCard的写法也配合了这一点摘自src/store.ts第 63–72 行它不改老对象而是{ ...data, cards: { ...data.cards, [card.id]: card } }造一份全新的完整快照交给persist写成功才返回。队伍 整份快照 写后才更新三件套凑齐小雅的 panda 再也丢不了。这里多说一句整份快照的讲究。你可能觉得每次保存整个数据、而不是只改动那一条很笨——第 13 章我们算过这笔账EngFlow 的全部学习记录撑死几百 KB整机保存简单、不容易错速度完全够。但要警惕的是另一头如果只改动一条就得先读再写读和写之间又是一个让座点搞不好反而把本章的坑重新挖回来。有时候笨办法恰好是安全办法。还有一个你可能已经发现的问题我们在纯浏览器里做 dev 时数据走的是 localStorage第 13 章的回退方案而localStorage.setItem是同步的——写完才返回根本没有让座点所以那个环境下连点反而不容易丢真正会丢的是 Tauri 里store.setsave()这条异步写盘路。同一份业务代码换一个存储后端bug 的出没概率都不同——这也是审查的难点不能只在自己顺手的机器上试要按最慢的那条路来推演。实验里的setTimeout(50)就是在手工模拟这条异步路。修复上线后我们用每秒 5 连点的手速实测刷完整组卡片报告页记录一条不少。那只猫抓到了。最后把本章的全局用一张箭头图钉在脑子里没有队列点击1 ─读旧快照─改─写 ┐ 点击2 ─读旧快照─改────┘ 后写的覆盖先写的 → 丢数据 有队列 点击1 → op()入队 → [任务1] 读完写完 点击2 → op()入队 → [任务2] 这时才读读到的是新快照 → 一条不丢两条链子、一支笔、一列纵队——这就是 opChain 的全部。25.5 小毛病大修理坏例子学会队列以后有个聪明的小朋友做了这么一件事——他想让队伍永远忙起来于是在队列任务里面又给自己入队// ⚠️ 危险演示自己往自己排的队里塞新人而且永远塞下去letopChainPromise.resolve();functionop(fn){opChainopChain.then(fn).catch((e)console.error(e));}letn0;functionloop(){op(async(){n;console.log(正在执行第,n,个任务);loop();// 错误就在这行队列任务干活时又入队一个新任务});}loop();// 贴进控制台之前先想n 会停在多少错误现象一贴进控制台日志疯狂刷屏n一路狂奔到几千还在涨页面按钮点不动await opChain永远不返回——这条队伍永远走不完。不敢真跑的话把loop()那行改成if (n 50) loop()感受一下能走完和走不完的区别。原因食堂窗口的大师傅炒完一盘菜顺手把刚炒出来的自己派去队尾重新排队。队伍的任务数量永远不减反增。更糟的是Promise 链的推进走的是微任务队列浏览器会把微任务全部清完才肯去画下一帧画面——所以你连关掉标签页之外什么都点不动等于卡死。修理规矩立在这里——队列任务里只干活不再入队。真需要持续不断的事交给队外的定时器// ✅ 修法入队的动作留在任务外面由定时器按拍子喂给队伍letn0;consttimersetInterval((){if(n5){clearInterval(timer);return;}// 干满 5 单收工op(async(){n;console.log(任务,n,完成);});},100);一句话总结窗口只负责打饭不负责制造新的同学。这个坑在 EngFlow 开发时真的差点踩中当时有人提议保存失败就在 catch 里自动重试一次——听起来很贴心但重试的实现就是在队列任务里再入队一个任务如果磁盘哪天真坏了比如文件被别的程序占着每一次重试都失败、每一次失败都再重试队伍就变成了一条永远填不满的死循环传送带软件表面正常、内部空转风扇狂转。最后的决定是失败就失败记在日志里让用户下次操作自然重新入队。宁可丢一单不能烧整条队。25.6 本章你会解释合上书把下面几题讲给家长听关键词在括号里答出来即过关JavaScript 只有一个厨师为什么还会把数据弄丢单线程、await 让座、读→改→写中间有让座点点名册比喻里后交的册子抹掉先交的对应我们软件里的哪个操作第二次点击的saveCard用旧快照覆盖了新快照panda 的分数丢失opChain opChain.then(fn)为什么能保证每个任务读到的都是新数据入队不执行轮到才执行新任务永远接在队伍最尾前面的人已经写回.catch在这里是干嘛的没有它会怎样某个任务抛错时不让整条链断掉没有它后面所有排队任务被跳过为什么在队列任务里再次入队危险任务生产者永远大于消费者队列永不完工微任务被塞满导致页面卡死参考答案要点即括号内关键词卡壳回看 25.2 与 25.4。25.7 练习★改一个数字把实验 1 里的setTimeout(r, 50)改成setTimeout(r, 0)重新运行。count 是 5 吗再用文字解释为什么没有等待也算让过座。提示await哪怕等 0 毫秒也会把后面的代码交给下一轮5 个函数的读都发生在任何一个的写之前。★★拆一条链把实验 2 的op改成下面这样不收集返回值其余不动连跑两次demoQueue的效果会怎样为什么functionop(fn){opChain.then(fn).catch((e)console.error(e));// 忘了写 opChain }提示每个任务都从同一个起点opChain长出去队伍变成五指张开的手掌串行瞬间土崩瓦解。★★★找一找生活里的让座点你和同学同时往同一个共享文档里改两行内容为什么也可能后提交的覆盖先提交的把它的读→改→让座→写四步写出来再给你的食堂窗口排队规则写三句话方案。不用写代码讲给家长听。★★★侦探笔记本章开头说这只猫最难抓。现在你有装备了——请用竞态的口味描述下面三个场景哪些可能有丢失更新哪些没有各写一句理由(a) 两个按钮分别把同一个数字加 1、加 2用户同时点(b) 一个按钮读数据、算一算、马上写回全程没有任何await© 收藏 10 个词每个词保存一次保存里有await10 次保存同时出发。参考a 有——都是读改写且都有让座b 没有——没有让座点一鼓作气做完c 有——这正是onAddWords批量一次入队、而不是循环调用 10 次 op 的原因你现在能看懂这个设计选择了吗下一章我们换一副眼镜不再盯着一个 bug 修而是给整个软件做一次全身 CT——两位审查员分头逐行读遍数据层和界面层把藏在健康外表下的毛病一网打尽还给出一份能打印出来的审查单。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

只管去跑步第1天20261001-鼻炎、手机、系鞋带,到底哪一步拦住你去跑步 2026/10/2 17:22:18

只管去跑步第1天20261001-鼻炎、手机、系鞋带,到底哪一步拦住你去跑步

跑了十年才明白,跑步难的不是跑,是准备 有一个画面,我重复了十年。 晚上躺在床上,我跟自己说,明天一定去跑步,一定去。 第二天,我没去。 不是一次,是十年。 我一直以为是自己懒&…

阅读更多 →
英辰朗迪AI获客每日AI精选(2026.10.01) 2026/10/2 17:22:12

英辰朗迪AI获客每日AI精选(2026.10.01)

一、技术前沿第1条:OpenAI 正式发布 Sora 2,视频与音频同步生成并引入溯源水印核心内容:OpenAI 于 2026 年 9 月底至 10 月初正式发布 Sora 2 视频生成模型及配套 Sora App。模型从文本或图像生成短视频片段,并同步合成音效、环境…

阅读更多 →
Inconsolata LGC 补丁字体完全指南:在 Nerd Fonts 中获取带西里尔字母与希腊字母支持的 Inconsolata 2026/10/2 17:22:12

Inconsolata LGC 补丁字体完全指南:在 Nerd Fonts 中获取带西里尔字母与希腊字母支持的 Inconsolata

开发工具CLI 【免费下载链接】nerd-fonts Iconic font aggregator, collection, & patcher. 3,600 icons, 50 patched fonts: Hack, Source Code Pro, more. Glyph collections: Font Awesome, Material Design Icons, Octicons, & more 项目地址: https://…

阅读更多 →
协议栈数据流全景分析 2026/10/2 17:22:12

协议栈数据流全景分析

一次 HTTPS 请求从应用层到物理层的完整旅程,逐层追踪数据封装/解封装过程。 synthesis 页:跨 HTTP协议/TLS协议/TCP协议/DNS协议/ARP协议/ICMP协议 综合分析。1. 全景拓扑:协议栈封装与解封装 先看一张协议栈全景图,自上而下是发…

阅读更多 →
APP里竟然明文写着账号密码(Diva靶场第二关) 2026/10/2 17:22:11

APP里竟然明文写着账号密码(Diva靶场第二关)

漏洞标题:DIVA靶场 Hardcoding Issues Part1 存在硬编码账号密码漏洞漏洞类型:硬编码敏感凭证影响产品:DIVA (Damn Insecure and Vulnerable App)包名:jakhar.aseem.diva版本:diva-beta.apk漏洞等级:中危前…

阅读更多 →
HoloCubic_AIO Web后台源码解析:WebServer配置与文件上传接口实现完整指南 2026/10/2 17:22:11

HoloCubic_AIO Web后台源码解析:WebServer配置与文件上传接口实现完整指南

HoloCubic_AIO Web后台源码解析:WebServer配置与文件上传接口实现完整指南 【免费下载链接】HoloCubic_AIO HoloCubic超多功能AIO固件 基于esp32-arduino的天气时钟、相册、视频播放、桌面投屏、web服务、bilibili粉丝等 项目地址: https://gitcode.com/GitHub_Tr…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉