当前位置: 首页 > news >正文

【算法数据结构体系篇class07】:加强堆

一、手动改写堆(非常重要)!

系统提供的堆无法做到的事情:
1)已经入堆的元素,如果参与排序的指标方法变化
系统提供的堆无法做到时间复杂度O(logN)调整!都是O(N)的调整!
2)系统提供的堆只能弹出堆顶做不到自由删除任何一个堆中的元素,
或者说,无法在时间复杂度O(logN)内完成!一定会高于O(logN)
根本原因:无反向索引表

二、加强堆的核心点

1)建立反向索引表indexMap

2)建立比较器

3)核心在于各种结构相互配合,非常容易出错

三、构建加强堆演示

package class07;import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;/*** 手写一个加强堆,比系统自带的优先队列多了更多高效的获取元素查询动作* 注意泛型:T一定要是非基础类型,有基础类型需求包一层*/
public class HeapGreaterTrain<T> {//保存堆元素的集合public ArrayList<T> heap;//保存堆元素对应的索引位置 元素:索引public HashMap<T, Integer> indexMap;//堆大小public int heapSize;//比较器,自定义的比较器 ?匹配类型是T的父类 包括T本身public Comparator<? super T> comp;public HeapGreaterTrain(Comparator<? super T> c) {heap = new ArrayList<>();indexMap = new HashMap<T, Integer>();heapSize = 0;comp = c;}//判断堆是否为空public boolean isEmpty() {return heapSize == 0;}//判断堆大小public int size() {return heapSize;}//判断堆中是否包含某个元素public boolean contains(T obj) {return indexMap.containsKey(obj);}//查询堆顶元素public T peek() {return heap.get(0);}//入堆操作public void push(T obj) {//直接进集合最后,反向索引表创建关系,后面再接着insert向上排序heap.add(obj);indexMap.put(obj, heapSize);heapInsert(heapSize++);}//堆向上交换操作,默认是小根堆的排序private void heapInsert(int i) {//通过业务创建加强堆自定义的比较器来定义排序,假设返回小于0,执行交换操作while (comp.compare(heap.get(i), heap.get((i - 1) / 2)) < 0) {swap(i, (i - 1) / 2);i = (i - 1) / 2;}}//出堆操作public T pop(){//出堆顶,然后与最后一个元素交换,再将最后一个元素从集合与反向索引表删除T ans = heap.get(0);swap(0,--heapSize);heap.remove(heapSize);indexMap.remove(ans);heapify(0);return ans;}//堆向下沉操作 默认小根堆public void heapify(int i) {int left = i *2 +1;while(left < heapSize){int smallest = left+1 < heapSize && comp.compare(heap.get(left+1),heap.get(left))<0?left+1:left;smallest = comp.compare(heap.get(smallest),heap.get(i))<0?smallest:i;if(smallest == i) break;swap(smallest,i);i = smallest;left = i *2+1;}}//移除任意一个元素  将最后一个元素交换到该元素位置,然后再从该位置进行堆的上下调整排序操作public void remove(T obj){//获取集合中最后一个元素T end = heap.get(heapSize-1);//获取要删除元素的索引int index = indexMap.get(obj);//分别删除索引表该元素记录,与集合中最后一个元素,该元素前面已经保存下来indexMap.remove(obj);heap.remove(--heapSize);//注意:如果删除元素不是最后一个元素,再将该元素添加到index位置,并增加反向索引表记录if(obj != end){heap.set(index,end);indexMap.put(end,index);//调整完,就需要判断该元素是否需要上移或下移,其中只会执行一句resign(end);}}public void resign(T end) {heapInsert(indexMap.get(end));heapify(indexMap.get(end));}//返回堆上所有元素public List<T> getAllElements(){return heap;}private void swap(int i, int j) {//交换集合中的元素T o1 = heap.get(i);T o2 = heap.get(j);heap.set(i, o2);heap.set(j, o1);//重新设定反向索引表indexMap.put(o1, j);indexMap.put(o2, i);}
}

四、加强堆应用:用户颁奖问题

给定一个整型数组,int[] arr;和一个布尔类型数组,boolean[] op
两个数组一定等长,假设长度为N,arr[i]表示客户编号,op[i]表示客户操作
arr= [ 3 , 3 , 1 , 2, 1, 2, 5…
op= [T , T, T, T, F, T, F…
依次表示:3用户购买了一件商品,3用户购买了一件商品,1用户购买了一件商品,2用户购买了一件商品,1用户退货了一件商品,2用户购买了一件商品,5用户退货了一件商品…
一对arr[i]和op[i]就代表一个事件:
用户号为arr[i],op[i] == T就代表这个用户购买了一件商品
op[i] == F就代表这个用户退货了一件商品
现在你作为电商平台负责人,你想在每一个事件到来的时候,
都给购买次数最多的前K名用户颁奖。
所以每个事件发生后,你都需要一个得奖名单(得奖区)。

得奖系统的规则:
1,如果某个用户购买商品数为0,但是又发生了退货事件,
则认为该事件无效,得奖名单和上一个事件发生后一致,例子中的5用户
2,某用户发生购买商品事件,购买商品数+1,发生退货事件,购买商品数-1
3,每次都是最多K个用户得奖,K也为传入的参数
如果根据全部规则,得奖人数确实不够K个,那就以不够的情况输出结果
4,得奖系统分为得奖区和候选区,任何用户只要购买数>0,
一定在这两个区域中的一个
5,购买数最大的前K名用户进入得奖区,
在最初时如果得奖区没有到达K个用户,那么新来的用户直接进入得奖区
6,如果购买数不足以进入得奖区的用户,进入候选区
7,如果候选区购买数最多的用户,已经足以进入得奖区,
该用户就会替换得奖区中购买数最少的用户(大于才能替换),
如果得奖区中购买数最少的用户有多个,就替换最早进入得奖区的用户
如果候选区中购买数最多的用户有多个,机会会给最早进入候选区的用户
8,候选区和得奖区是两套时间,
因用户只会在其中一个区域,所以只会有一个区域的时间,另一个没有
从得奖区出来进入候选区的用户,得奖区时间删除,
进入候选区的时间就是当前事件的时间(可以理解为arr[i]和op[i]中的i)
从候选区出来进入得奖区的用户,候选区时间删除,
进入得奖区的时间就是当前事件的时间(可以理解为arr[i]和op[i]中的i)
9,如果某用户购买数==0,不管在哪个区域都离开,区域时间删除,
离开是指彻底离开,哪个区域也不会找到该用户
如果下次该用户又发生购买行为,产生>0的购买数,
会再次根据之前规则回到某个区域中,进入区域的时间重记
请遍历arr数组和op数组,遍历每一步输出一个得奖名单
publicList<List<Integer>> topK(int[] arr, boolean[] op, int k)
package class07;import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;public class Code02_EveryStepShowBoss {public static class Customer {public int id;public int buy;public int enterTime;public Customer(int v, int b, int o) {id = v;buy = b;enterTime = 0;}}public static class CandidateComparator implements Comparator<Customer> {@Overridepublic int compare(Customer o1, Customer o2) {return o1.buy != o2.buy ? (o2.buy - o1.buy) : (o1.enterTime - o2.enterTime);}}public static class DaddyComparator implements Comparator<Customer> {@Overridepublic int compare(Customer o1, Customer o2) {return o1.buy != o2.buy ? (o1.buy - o2.buy) : (o1.enterTime - o2.enterTime);}}public static class WhosYourDaddy {private HashMap<Integer, Customer> customers;private HeapGreaterTrain<Customer> candHeap;private HeapGreaterTrain<Customer> daddyHeap;private final int daddyLimit;public WhosYourDaddy(int limit) {customers = new HashMap<Integer, Customer>();candHeap = new HeapGreaterTrain<>(new CandidateComparator());daddyHeap = new HeapGreaterTrain<>(new DaddyComparator());daddyLimit = limit;}// 当前处理i号事件,arr[i] -> id,  buyOrRefundpublic void operate(int time, int id, boolean buyOrRefund) {if (!buyOrRefund && !customers.containsKey(id)) {return;}if (!customers.containsKey(id)) {customers.put(id, new Customer(id, 0, 0));}Customer c = customers.get(id);if (buyOrRefund) {c.buy++;} else {c.buy--;}if (c.buy == 0) {customers.remove(id);}if (!candHeap.contains(c) && !daddyHeap.contains(c)) {if (daddyHeap.size() < daddyLimit) {c.enterTime = time;daddyHeap.push(c);} else {c.enterTime = time;candHeap.push(c);}} else if (candHeap.contains(c)) {if (c.buy == 0) {candHeap.remove(c);} else {candHeap.resign(c);}} else {if (c.buy == 0) {daddyHeap.remove(c);} else {daddyHeap.resign(c);}}daddyMove(time);}public List<Integer> getDaddies() {List<Customer> customers = daddyHeap.getAllElements();List<Integer> ans = new ArrayList<>();for (Customer c : customers) {ans.add(c.id);}return ans;}private void daddyMove(int time) {if (candHeap.isEmpty()) {return;}if (daddyHeap.size() < daddyLimit) {Customer p = candHeap.pop();p.enterTime = time;daddyHeap.push(p);} else {if (candHeap.peek().buy > daddyHeap.peek().buy) {Customer oldDaddy = daddyHeap.pop();Customer newDaddy = candHeap.pop();oldDaddy.enterTime = time;newDaddy.enterTime = time;daddyHeap.push(newDaddy);candHeap.push(oldDaddy);}}}}public static List<List<Integer>> topK(int[] arr, boolean[] op, int k) {List<List<Integer>> ans = new ArrayList<>();WhosYourDaddy whoDaddies = new WhosYourDaddy(k);for (int i = 0; i < arr.length; i++) {whoDaddies.operate(i, arr[i], op[i]);ans.add(whoDaddies.getDaddies());}return ans;}// 干完所有的事,模拟,不优化public static List<List<Integer>> compare(int[] arr, boolean[] op, int k) {HashMap<Integer, Customer> map = new HashMap<>();ArrayList<Customer> cands = new ArrayList<>();ArrayList<Customer> daddy = new ArrayList<>();List<List<Integer>> ans = new ArrayList<>();for (int i = 0; i < arr.length; i++) {int id = arr[i];boolean buyOrRefund = op[i];if (!buyOrRefund && !map.containsKey(id)) {ans.add(getCurAns(daddy));continue;}// 没有发生:用户购买数为0并且又退货了// 用户之前购买数是0,此时买货事件// 用户之前购买数>0, 此时买货// 用户之前购买数>0, 此时退货if (!map.containsKey(id)) {map.put(id, new Customer(id, 0, 0));}// 买、卖Customer c = map.get(id);if (buyOrRefund) {c.buy++;} else {c.buy--;}if (c.buy == 0) {map.remove(id);}// c// 下面做if (!cands.contains(c) && !daddy.contains(c)) {if (daddy.size() < k) {c.enterTime = i;daddy.add(c);} else {c.enterTime = i;cands.add(c);}}cleanZeroBuy(cands);cleanZeroBuy(daddy);cands.sort(new CandidateComparator());daddy.sort(new DaddyComparator());move(cands, daddy, k, i);ans.add(getCurAns(daddy));}return ans;}public static void move(ArrayList<Customer> cands, ArrayList<Customer> daddy, int k, int time) {if (cands.isEmpty()) {return;}// 候选区不为空if (daddy.size() < k) {Customer c = cands.get(0);c.enterTime = time;daddy.add(c);cands.remove(0);} else { // 等奖区满了,候选区有东西if (cands.get(0).buy > daddy.get(0).buy) {Customer oldDaddy = daddy.get(0);daddy.remove(0);Customer newDaddy = cands.get(0);cands.remove(0);newDaddy.enterTime = time;oldDaddy.enterTime = time;daddy.add(newDaddy);cands.add(oldDaddy);}}}public static void cleanZeroBuy(ArrayList<Customer> arr) {List<Customer> noZero = new ArrayList<Customer>();for (Customer c : arr) {if (c.buy != 0) {noZero.add(c);}}arr.clear();for (Customer c : noZero) {arr.add(c);}}public static List<Integer> getCurAns(ArrayList<Customer> daddy) {List<Integer> ans = new ArrayList<>();for (Customer c : daddy) {ans.add(c.id);}return ans;}// 为了测试public static class Data {public int[] arr;public boolean[] op;public Data(int[] a, boolean[] o) {arr = a;op = o;}}// 为了测试public static Data randomData(int maxValue, int maxLen) {int len = (int) (Math.random() * maxLen) + 1;int[] arr = new int[len];boolean[] op = new boolean[len];for (int i = 0; i < len; i++) {arr[i] = (int) (Math.random() * maxValue);op[i] = Math.random() < 0.5 ? true : false;}return new Data(arr, op);}// 为了测试public static boolean sameAnswer(List<List<Integer>> ans1, List<List<Integer>> ans2) {if (ans1.size() != ans2.size()) {return false;}for (int i = 0; i < ans1.size(); i++) {List<Integer> cur1 = ans1.get(i);List<Integer> cur2 = ans2.get(i);if (cur1.size() != cur2.size()) {return false;}cur1.sort((a, b) -> a - b);cur2.sort((a, b) -> a - b);for (int j = 0; j < cur1.size(); j++) {if (!cur1.get(j).equals(cur2.get(j))) {return false;}}}return true;}public static void main(String[] args) {int maxValue = 10;int maxLen = 100;int maxK = 6;int testTimes = 100000;System.out.println("测试开始");for (int i = 0; i < testTimes; i++) {Data testData = randomData(maxValue, maxLen);int k = (int) (Math.random() * maxK) + 1;int[] arr = testData.arr;boolean[] op = testData.op;List<List<Integer>> ans1 = topK(arr, op, k);List<List<Integer>> ans2 = compare(arr, op, k);if (!sameAnswer(ans1, ans2)) {for (int j = 0; j < arr.length; j++) {System.out.println(arr[j] + " , " + op[j]);}System.out.println(k);System.out.println(ans1);System.out.println(ans2);System.out.println("出错了!");break;}}System.out.println("测试结束");}}

相关文章:

【算法数据结构体系篇class07】:加强堆

一、手动改写堆&#xff08;非常重要&#xff09;&#xff01;系统提供的堆无法做到的事情&#xff1a;1&#xff09;已经入堆的元素&#xff0c;如果参与排序的指标方法变化&#xff0c;系统提供的堆无法做到时间复杂度O(logN)调整&#xff01;都是O(N)的调整&#xff01;2&am…...

Taro3.x 容易踩坑的点(阻止滚动穿透,弹框蒙层父级定位)

解决弹框滚动的时候&#xff0c;下层也会滚动问题》阻止滚动穿透(react,vue)案例描述&#xff1a;页面展示时需要滚动条才可以显示完整&#xff0c;但是当我们显示弹框的时候&#xff0c;即使不需要滚动条&#xff0c;但是页面仍然可以滚动&#xff0c;并且下层内容会随着滚动变…...

SpringBoot+ActiveMQ-发布订阅模式(消费端)

ActiveMQ消息中间件的发布订阅模式 主题 topictopic生产端案例(配合topic消费端测试)&#xff1a;SpringBootActiveMQ Topic 生产端ActiveMQ版本&#xff1a;apache-activemq-5.16.5案例源码:SpringBootActiveMQ-发布订阅DemoSpringBoot集成ActiveMQ Topic消费端的pom.xml<?…...

vscode下使用arduino插件开发ESP32 Heltec WiFi_Kit_32_V3

下载vsCode 添加 arduino 插件 在Arduino IDE 中添加开发板&#xff0c;注意只能用右侧的开发板管理器添加&#xff0c;自己下载之后复制进去的IDE认&#xff0c;但是vsCode不认&#xff0c;搜索ESP32 第一个库里面只有到V2的&#xff0c;没有V3&#xff0c;要安装下面那个 H…...

吐血整理AutoSAR Com-Stack 的配置【基于ETAS】

总目录链接>> AutoSAR入门和实战系列总目录 文章目录01.软件组件和系统说明02.基本软件配置03.系统数据映射04.代码生成05.代码整合06.测试下图显示了基于 AUTOSAR 的 ECU SW 的结构。纵观BSW&#xff0c;大体分为三层。三层模块中&#xff0c;与通信相关的模块称为通信…...

面向对象进阶之元类

6. 元类 Python 中一切皆对象&#xff0c;对象是由类实例化产生的。那么类应该也有个类去产生它&#xff0c;利用 type() 函数我们可以去查看&#xff1a; class A:pass a1 A() print(type(a1)) print(type(A))<class __main__.A> <class type>由上可知&#xf…...

【Android AIDL之详细使用】

Android AIDL之详细使用一级目录概述使用场景语法相关编码实践服务端&#xff1a;java文件修改AndroidManifest客户端坑一级目录 概述 AIDL叫Android接口定义语言&#xff0c;是用于辅助开发者完成Android跨进程编程的工具。 从某种意义上说AIDL其实是一个模板&#xff0c;因…...

ASP.NET MVC | 简介

目录 前提 1.教程 2.MVC 编程模式 最后 前提 在学习学过很多课程&#xff0c;但是最主要学的还是ASP.NET MVC这门课程&#xff0c;工作也是用的ASP.NET MVC&#xff0c;所以写一点ASP.NET MVC的东西&#xff0c;大家可以来看看&#xff0c;我自己不会的时候也不用找别的地方…...

95后刚毕业2、3年就年薪50W,才发现,打败我们的不是年龄····

一刷朋友圈&#xff0c;一读公众号&#xff0c;一打开微博&#xff0c;甚至是一和朋友聊天&#xff0c;这些让人焦虑的话题总会铺天盖地的袭来&#xff1a; Ta刚毕业半年&#xff0c;就升职加薪当上了测试主管 &#xff08;同样是一天24小时&#xff0c;为什么同龄人正在抛弃…...

动态分析和静态分析最主要的区别是什么?

动态分析和静态分析主要的区别是什么&#xff1f; 动态分析和静态分析的主要区别是是否考虑时间因素。 动态分析&#xff08;dynamic analysis&#xff09;是相对于静态分析来讲的&#xff0c;动态分析是只改变一下自变量&#xff0c;因变量相应的做出的改变&#xff0c;动态改…...

WebUI 学习笔记

WebUI 学习笔记 背景此插件主要用于在数字孪生方向做 UI 显示的效果。比如一些温度曲线需要显示出来,可以直接用插件,配合html 文件,直接显示出来。 准备工作我们采用4.27 版本进行开发;...

C# 中常见的设计模式附带代码案例

设计模式是一套被广泛应用于软件设计的最佳实践&#xff0c;它们可以帮助开发者解决特定的问题&#xff0c;提高代码的可重用性、可读性和可维护性。本文将介绍 C# 中常见的几种设计模式&#xff0c;并提供相应的示例代码。 工厂模式 工厂模式是一种创建型设计模式&#xff0c…...

秋招面试问题整理之机器学习篇

文章目录随机森林在决策树的哪些方面做出了改进随机森林里每棵树的权重不一定会变成什么模型方差和偏差&#xff0c;正则化解决的是方差大还是偏差大的问题正则化的方法总结了解VC维吗svd了解吗随机森林在决策树的哪些方面做出了改进 回答思路&#xff1a; 随机森林和决策树有…...

SuperMap超图使用简单笔记

1 需求&#xff1a; 项目使用的是openlayer和Cesium&#xff0c;现在需要使用超图的图层&#xff0c;和引入实景公路功能。 2 使用过程中出现一下疑问点记录如下 &#xff1a; 超图&#xff1a; 北京超图软件股份有限公司是全球第三大、亚洲最大的地理信息系统&#xff08;G…...

从0探索NLP——神经网络

从0探索NLP——神经网络 1.前言 一提人工智能&#xff0c;最能想到的就是神经网络&#xff0c;但其实神经网络只是深度学习的主要实现方式。 现在主流的NLP相关任务、模型大都是基于深度学习也就是构建神经网络实现的&#xff0c;所以这里讲解一下神经网络以及简单的神经网络…...

计算机操作系统和进程

✨个人主页&#xff1a;bit me&#x1f447; ✨当前专栏&#xff1a;Java EE初阶&#x1f447; ✨每日一语&#xff1a;心平能愈三千疾&#xff0c;心静可通万事理。 目 录&#x1f42c;一. 操作系统&#x1f366;1. 操作系统是什么&#xff1f;&#x1f368;2. 操作系统的两个…...

JAVA服务端实现页面截屏(附代码)

JAVA服务端实现页面截屏适配需求方案一、使用JxBrowser使用步骤&#xff1a;方案二、JavaFX WebView使用步骤&#xff1a;方案三、Headless Chrome使用步骤&#xff1a;综上方案对比记录我的一个失败方案参考适配需求 有正确完整的地址url&#xff1b;通过浏览器能打开该url对…...

Java入门要知道!

首先我们都知道的是Java是一门面向对象的编程语言&#xff0c;不仅吸收了C语言的各种优点&#xff0c;还摒弃了C里难以理解的多继承、指针等概念&#xff0c;因此Java语言具有功能强大和简单易用两个特征。Java语言作为静态面向对象编程语言的代表&#xff0c;极好地实现了面向…...

[6/101] 101次软件测试面试之经典面试题剖析

01、自我介绍答&#xff1a;大家好&#xff0c;我是一名软件测试工程师&#xff0c;但我更喜欢称自己为“软件bug捕手”。我相信&#xff0c;软件测试工程师的使命就是让软件更加健壮、更加可靠、更加美好。我们就像是一群“特警”&#xff0c;在黑暗的代码中寻找漏洞和缺陷&am…...

电脑c盘满了变成红色了怎么清理,清理c盘详细攻略

我们的电脑当用了一段时间之后&#xff0c;其实自然而然的就会有一点点卡&#xff0c;其实这是因为我们的电脑c盘满了&#xff0c;所以会造成卡顿是正常的&#xff0c;今天我们就来聊一聊电脑c盘满了变成红色了怎么清理&#xff1f; 一.电脑c盘为啥会满 软件安装&#xff1a;当…...

聊聊 Pulsar:Producer 源码解析

一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台&#xff0c;以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中&#xff0c;Producer&#xff08;生产者&#xff09; 是连接客户端应用与消息队列的第一步。生产者…...

系统设计 --- MongoDB亿级数据查询优化策略

系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log&#xff0c;共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题&#xff0c;不能使用ELK只能使用…...

【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)

要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况&#xff0c;可以通过以下几种方式模拟或触发&#xff1a; 1. 增加CPU负载 运行大量计算密集型任务&#xff0c;例如&#xff1a; 使用多线程循环执行复杂计算&#xff08;如数学运算、加密解密等&#xff09;。运行图…...

如何在最短时间内提升打ctf(web)的水平?

刚刚刷完2遍 bugku 的 web 题&#xff0c;前来答题。 每个人对刷题理解是不同&#xff0c;有的人是看了writeup就等于刷了&#xff0c;有的人是收藏了writeup就等于刷了&#xff0c;有的人是跟着writeup做了一遍就等于刷了&#xff0c;还有的人是独立思考做了一遍就等于刷了。…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖

在Vuzix M400 AR智能眼镜的助力下&#xff0c;卢森堡罗伯特舒曼医院&#xff08;the Robert Schuman Hospitals, HRS&#xff09;凭借在无菌制剂生产流程中引入增强现实技术&#xff08;AR&#xff09;创新项目&#xff0c;荣获了2024年6月7日由卢森堡医院药剂师协会&#xff0…...

接口自动化测试:HttpRunner基础

相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具&#xff0c;支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议&#xff0c;涵盖接口测试、性能测试、数字体验监测等测试类型…...

【无标题】湖北理元理律师事务所:债务优化中的生活保障与法律平衡之道

文/法律实务观察组 在债务重组领域&#xff0c;专业机构的核心价值不仅在于减轻债务数字&#xff0c;更在于帮助债务人在履行义务的同时维持基本生活尊严。湖北理元理律师事务所的服务实践表明&#xff0c;合法债务优化需同步实现三重平衡&#xff1a; 法律刚性&#xff08;债…...

xmind转换为markdown

文章目录 解锁思维导图新姿势&#xff1a;将XMind转为结构化Markdown 一、认识Xmind结构二、核心转换流程详解1.解压XMind文件&#xff08;ZIP处理&#xff09;2.解析JSON数据结构3&#xff1a;递归转换树形结构4&#xff1a;Markdown层级生成逻辑 三、完整代码 解锁思维导图新…...

uni-app学习笔记三十五--扩展组件的安装和使用

由于内置组件不能满足日常开发需要&#xff0c;uniapp官方也提供了众多的扩展组件供我们使用。由于不是内置组件&#xff0c;需要安装才能使用。 一、安装扩展插件 安装方法&#xff1a; 1.访问uniapp官方文档组件部分&#xff1a;组件使用的入门教程 | uni-app官网 点击左侧…...