Java中method.invoke用法详解 大家好,我是免费搭建查券返利机器人赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!今天,让我们一起深入了解Java中Method.invoke()的用法,探索这个方法在Java反射中的强大功能。
Java中的Method.invoke()简介 Method.invoke()是Java反射机制中的一个核心方法,它允许在运行时动态地调用类的方法。通过使用Method.invoke(),我们可以绕过编译时的静态检查,实现对类的方法进行动态调用,非常适用于一些灵活的、运行时确定的场景。
基本用法 import java.lang.reflect.Method; public class MethodInvokeExample { public static void main(String[] args) throws Exception { // 获取Class对象 Class<?> clazz = MyClass.class; // 获取方法名为 "myMethod",参数为 int 的方法 Method method = clazz.getMethod("myMethod", int.class); // 创建实例 Object instance = clazz.getDeclaredConstructor().newInstance(); // 调用方法 method.invoke(instance, 42); } } class MyClass { public void myMethod(int value) { System.out.println("Method invoked with value: " + value); } } 在上述例子中,我们通过反射获取MyClass类的myMethod方法,并使用Method.invoke()调用该方法。这种动态调用的方式使得我们可以在运行时决定调用哪个方法,以及传递什么样的参数。
实际应用场景 1. 框架扩展 在一些框架和库中,通过反射调用用户提供的扩展点方法,实现对框架的扩展和定制。
我们常说,不能度量,就无法增长。数据分析对于企业商业价值的提升有着至关重要的作用,在职场中,我们需要掌握一套系统的、科学的、符合商业规律的数据分析知识,来应对日常工作中的需求。
马上就年底了,掌握一些数据分析知识,对年底的工作汇总也十分有用。
01
普通职场人为什么要学习数据分析?
数据分析是通过收集、处理和分析数据,得出有价值的信息用于指导工作的过程。它有助于了解业务进展和变化,定位问题,指引工作方向,衡量工作成效。
数据分析对企业的发展越来越重要,超过90%的企业正在应用或将要应用数据。同时,数据分析作为分析、解决问题的有效手段,在运营、产品、市场、HR、咨询、投资等各类岗位中,都将成为职场人必备的核心能力。
对职场新人来说,有数据分析能力的加持,能帮你更快就业,拿到高工资;领域专家可以深度研究专业领域,快速建立行业权威;数据是任何决策的依据,对于中小管理者,掌握精准的数据可以保证企业/项目效益;数据对高层领导的决策影响更大,他们依据数据进行商业洞察,快速找准风口。
数据分析对很多行业和岗位也是必备能力,比如互联网行业用于日常用户行为分析、流量指标分析、广告投放分析、员工能力评价等;电商/零售日常用于销量监控、产品选择、店铺扩张、促销活动;人力/财务常用于指标搭建、提高效率、业务本质、业务决策;广告/市场进行广告效果检测、媒体投放建议、实时成本控制、社会化聆听等。
点击查看模板高清原图
数据分析的价值,就是我们普通职场人变得不普通的一项重要能力,所以人人都应具备数据分析能力。
02
如何快速具备数据分析思路?
具备数据分析思路,首先需要掌握常用的分析方法。了解了常用的这些方法,数据分析思路自然就有了。
1.常用的数据分析法
常用的数据分析方法有哪些?根据业务场景中分析目的的不同,会对应不同的分析方法。
点击查看模板高清原图
这7类数据分析方法是比较基础和常用的,给想要了解更多的小伙伴再补充几种:
点击查看模板高清原图
如果这些常用的分析方法不能满足你 ,下面做了比较全面的数据模型补充。
2. 35个必学的数据分析模型
数据分析模型常用的分为3类:
1)纯理论,和数据无关。比如SWOT、PEST等,这种模型严格意义上来说是一种思考方法,帮助你进行数据分析;
2)基于指标计算的模型。比如漏斗法、AARRR、矩阵模型、杜邦分析法等,这种是应用在数据分析业务中最多的,和公司的KPI直接挂钩,常用于公司的经营分析,做数据体系等;
3)基于算法的模型。算法模型有简单的如时间序列等,还有机器学习,回归、聚类等。
点击查看模板高清原图
图中整理的35个必学的数据分析模型,包含了前两种模型,即纯理论的模型和基于指标计算的模型,为大家同时提供了思考方法和分析方法。
03
数据分析干货知识点
掌握了常用的数据分析方法和模型,在具体进行数据分析过程中,具备专业的分析知识和工具,才能实现数据分析的目的。
1. 数据分析全景图
点击查看高清模板原图
这张2023年数据分析全景图,从数据分析方法论、业务指标体系、数据分析模型、数据分析方法和数据分析工具5个方面详细介绍了数据分析,全面又专业,帮助大家对数据分析有一个初步的全面认知。
2.数据分析基础知识
点击查看模板高清原图
在数据分析的实际操作中,还要了解和掌握一些数据分析的基础知识,这张图从统计学储备、分析语言和工具、算法原理3个方面进行了整理,对于没有统计学、技术等专业知识的新手来说,入门即是珠穆朗玛,容易被劝退,稳住!
3.数据分析挖掘
什么是数据挖掘?数据挖掘是从大量的、不完全的、有噪声的、模糊的、随机的数据中提取隐含在其中的、人们事先不知道的,但又是潜在有用的信息和知识的过程。
点击查看模板高清原图
数据挖掘的重点在寻找未知的模式和规律,比较有名的案例之一是“啤酒和尿布的故事”。
在美国有婴儿的家庭,年轻的父亲去超市买尿布,往往会顺便为自己购买啤酒,这样就出现了啤酒与尿布这两件看上去不相干的商品经常会出现在同一个购物篮的现象。超市发现了这一现象后,在卖场尝试将啤酒与尿布摆放在相同的区域,让年轻的父亲可以快速找到这两件商品,完成购物。
这个故事因为有数据挖掘的结果支持,才获得了更多的销售收入。
4.Excel常用公式
Excel是我们工作中常用的一种工具,熟练运用Excel不仅可以帮助我们提供处理数据的效率,还可以让数据分析变得简单且高效,将我们从单调乏味、重复性的工作中解脱出来。
点击查看模板高清原图
5.Excel数据透视表
Excel中最常用的数据分析就是透视表了,它是一个快速对明细数据表进行各种分类汇总的数据分析工具,基本上能满足初级和简单的数据分析需求,学习起来也并不是非常复杂,在跟领导进行汇报的时候,巧用数据透视表能让你的表达更加深入和准确。
点击查看模板高清原图
6.谷歌数据分析方法总结分享
最后分享一个谷歌的案例,它从数据分析帮你实际解决的问题、数据分析是如何工作的、数据分析基本术语扫盲、通过广告系列解读被监测的数据、监测链接的应用场景等23个方面进行了整理,案例结合前文的干货,相信读完此文你对数据分析会有更深刻的理解。
点击查看模板高清原图
一个有能力的职场人,无论是活动策划、产品增长,还是对产品优化的决策,不仅要重视全面的专业技能和方法,更要具备用数据思维分析整体业务的能力。
也许你以前从未注意对自己数据能力的培养,那么从现在开始多接触、多了解公司业务,多实践、多分析,相信在越来越多的成就感来袭时,你会体验到数据的魅力。
END
转自:ProcessOn;
版权声明:本号内容部分来自互联网,转载请注明原文链接和作者,如有侵权或出处有误请和我们联系。
合作请加QQ:365242293 数据分析(ID : ecshujufenxi )互联网科技与数据圈自己的微信,也是WeMedia自媒体联盟成员之一,WeMedia联盟覆盖5000万人群。
一、01背包 01背包是一种 动态规划 问题。动态规划的核心就是状态转移方程。
01背包问题可描述为如下问题:
有一个容量为V的背包,还有n个物体。现在忽略物体实际几何形状,我们认为只要背包的剩余容量大于等于物体体积,那就可以装进背包里。每个物体都有两个属性,即体积w和价值v。
问:如何向背包装物体才能使背包中物体的总价值最大?
01背包是背包问题中最简单的问题。01背包的约束条件是给定几种物品,每种物品有且只有一个(或者最多只能选取一个),并且有权值和体积两个属性。
在01背包问题中,因为每种物品只有一个(或者最多只能选取一个),对于第i个物品只需要考虑选与不选两种情况。那么选与不选的依据是什么呢?当然是该物品的性价比咯,而不是看当前背包所剩空间还能否装得下该物品。因为背包的剩余空间是不断根据选择的物品而变化的。
那么怎么判断选不选这个物品呢,就是看选了这个物品和不选这个物品背包的价值哪个大。就是max(不选的价值,选的价值)。
不选:背包的价值就不变,
选:背包的价值就等于这个物品的价值加上装了这个物品之后背包剩余空间用来装前(i-1)个物品的最大价值。
原始的 01背包
回顾一下dp[i][j]的含义:从下标为[0-i]的物品里任意取,放进容量为j的背包,价值总和最大是多少。
那么可以有两个方向推出来dp[i][j],
由dp[i - 1][j]推出,即背包容量为j,里面不放物品i的最大价值,此时dp[i][j]就是dp[i - 1][j]由dp[i - 1][j - weight[i]]推出,dp[i - 1][j - weight[i]] 为背包容量为j - weight[i]的时候不放物品i的最大价值,那么dp[i - 1][j - weight[i]] + value[i] (物品i的价值),就是背包放物品i得到的最大价值 所以递归公式: dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);
一维dp数组(滚动数组) 对于背包问题其实状态都是可以压缩的。
在使用二维数组的时候,递推公式:dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);
其实可以发现如果把dp[i - 1]那一层拷贝到dp[i]上,表达式完全可以是:dp[i][j] = max(dp[i][j], dp[i][j - weight[i]] + value[i]);
find()函数的使用 std::vector<int> myVector = {1, 2, 3, 4, 5}; int target = 3; // 使用find查找目标元素 auto result = std::find(myVector.begin(), myVector.end(), target); // 检查是否找到了目标元素 if (result != myVector.end()) { std::cout << "找到了目标元素,位置在索引 " << std::distance(myVector.begin(), result) << std::endl; } else { std::cout << "未找到目标元素" << std::endl; } return 0;
优先队列 C++中的优先队列是由二叉堆实现的。 默认是使用大根堆实现。
优先队列的基本操作 :
empty() 如果队列为空返回真
pop() 删除队顶元素
push() 入队一个元素
size() 返回优先队列中拥有的元素个数
top() 返回优先队列队顶元素
1.3.1 priority_queue<int> 是默认的大根堆实现,top()是当前优先队列的最大值。
1.3.2 priority_queue<int,vector<int>,greater<int>> 是最小值的优先队列,top() 是当前优先队列的最小值。
1.3.3 priority_queue<int,vector<int>,less<int>> 是最大值的优先队列,top() 是当前优先队列的最大值。
#include<iostream> using namespace std; #define N 105 int main() { int n,m; int i, j; int task1, task2, time; cin >> n >> m; int graph[N + 1][N + 1]; int dependence[N + 1], re_dependence[N + 1]; //每个点的入度数和出度数 int ae[N + 1], al[N + 1]; //一项活动最先开始的时间 和 一项活动最晚开始的时间 bool vis[N + 1]; //该任务是否已经完成过了 bool flag = true; //表示该轮中有任务完成 int count; //当前完成的任务的数量 int s[N + 1][N + 1]; //表示输入的边的顺序 int queue[N]; //表示关键路径某个任务中下一个任务编号 int tail; //表示queue中最后一个元素的位置 //初始化 for (i = 0; i <= n; i++) { for (j = 0; j <= n; j++) { graph[i][j] = -1; s[i][j] = -1; } dependence[i] = 0; re_dependence[i] = 0; ae[i] = 0; vis[i] = false; queue[i] = -1; } //输入 for (i = 0; i < m; i++) { cin >> task1 >> task2 >> time; graph[task1][task2] = graph[task2][task1] = time; s[task1][task2] = i; //填入顺序 dependence[task2]++; //入度 re_dependence[task1]++; //出度 } count = 0; //拓扑排序 while (flag && count !
栈与队列一 232. 用栈实现队列 思路:对于使用栈实现队列的话,必须使用两个共同来维护使得每次都能先进先出! class MyQueue: def __init__(self): # 需要建立两个list来维护出栈以及进栈 self.stack_in = [] self.stack_out = [] def push(self, x: int) -> None: self.stack_in.append(x) def pop(self) -> int: if self.empty(): return None # 判断出栈是否有元素 if self.stack_out: return self.stack_out.pop() else: for i in range(len(self.stack_in)): self.stack_out.append(self.stack_in.pop()) return self.stack_out.pop() def peek(self) -> int: # 使用list来做,末尾就头 为什么使用pop捏?是为了避免反复进行空的判断!不要代码冗余 ans = self.pop() self.stack_out.append(ans) return ans def empty(self) -> bool: # 只需要两个栈其中一个不为零就可 return not (self.stack_in or self.stack_out) 225.
<el-form-item :prop="item.prop" :label="item.label" v-for="(item, index) in form" :key="index"> <el-input v-model="formData[item.prop]" :placeholder="item.placeholder" @paste.native.capture="handleFalse($event, item.prop)" @copy.native.capture="handleFalse($event, item.prop)" @cut.native.capture="handleFalse($event, item.prop)" /> </el-form-item> handleFalse(e, prop) { if (prop.includes('email')) { e.preventDefault() } },
文章目录 Antismash概述Install使用其他参数输出详细结果网络文件GCF and GCC交互式可视化网页版 其他详细参数 BigScape简介工作原理installusage输出输出文件夹结构结果 可能的问题Reference Antismash 概述 antiSMASH - the antibiotics and Secondary Metabolite Analysis SHell,是用来鉴定微生物基因组次级代谢物合成基因簇的软件。
临床上使用的大部分抗生素和药物均来自植物或微生物的天然产物。结合基因组挖掘的经典分离与分析法使得基于基因组的天然产物途径鉴定和描述更为方便。
一般情况下,参与次级代谢途径中生物合成酶基因在基因组上成簇排列,基于指定类型的HMM,antiSMASH数据库能准确鉴定所有已知的次级代谢簇。在antiSMATH中,将次级代谢簇分为24类。
Install conda create -n antismash -c bioconda antismash conda activate antismash (antismash) ok@ubuntu $ download-antismash-databases Creating checksum of Pfam-A.hmm PFAM file present and ok for version 32.0 Resfams database present and checked Creating checksum of TIGRFam.hmm TIGRFam database present and checked Creating checksum of proteins.fasta ClusterBlast fasta file present and checked Creating checksum of proteins.
文章目录 一. 什么是自动化测试二. selenium的介绍1. Selenium是什么2. Selenium的工作原理3. Selenium 的环境搭建 三. webdriver API1. 元素的定位1.1 CSS 定位1.2 XPath 定位1.3 实现一个自动化需求 2. 操作测试对象2.1 clear 清除对象输入的文本内容2.2 submit 提交2.3 getAttribute 获取元素对应属性的值 3. 添加等待3.1 隐式等待3.2 显式等待 4. 打印信息5. 浏览器的操作6. 键盘事件7. 鼠标事件7. 定位一组元素8. 多层框架/窗口定位9. 下拉框处理10. alert弹窗的处理11. 上传文件操作12. 关闭浏览器13. 切换窗口14. 截图 一. 什么是自动化测试 自动化测试指软件测试的自动化,可以使用软件工具或脚本来执行测试任务的过程,以替代人工进行重复性、繁琐或耗时的测试活动;是将人为驱动的测试行为转化为机器执行的过程 。
自动化测试包括 UI 自动化,接口自动化,单元测试自动化。
二. selenium的介绍 1. Selenium是什么 Selenium 是 Web 应用中基于 UI 的自动化测试框架,它的优点如下:
开源免费。支持多浏览器,比如 Chrome,Edge,Firefox,Safari 等。支持多语言,包括 Java,Python,C# 等,都可以使用 Selenium 这个工具。支持多操作系统,比如 Windows,Linux,Mac 等。Selenium 的底层封装了丰富的 API,可以直接拿来使用。 2.
Cmap数据库 参考文献 [1]什么是基因表达谱分析及其相关概念
[2]GEO CMap LINCS User Guide v2.1
[3]CLUE:扰动驱动基因差异表达数据库
目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 1、支付功能测试点
1)功能测试
是否可以支持免密支付,由收付款支付页面直接跳转到支付成功页面;
银行卡支付卡号正确,零码正确,支付成功;
银行卡支付卡号错误,密码错误,支付失败;
错误次数限制,错1次是否可以重试,错误2次是否可以重试,3次是否会锁卡;
是否支持扫码二维码支付;
是否支持指纹支付;
指纹支付手指受伤,指纹无法正确识别,支付失败;
指纹识别成功,支付成功;
新录入的指纹,需要密码支付;
指纹支付失败限制次数;
是否支持微信,支付宝,花呗,借呗,零钱通,零钱,信用卡等等支付;
是否支持信用卡,不同的银行卡,网银,云闪付,第三方和数字人民币支付;
支付金额要验证0.01和5万能不能支付,边界值的情况,比如-1,50000.01能不能支付,输入中文能不能支付;
空值支付,消费金额达上限,无法支付;
余额充足支付成功,余额不足取消支付;
显示余额不足并不会扣除余额,更换支付方式是否继续支付,是否可以取消支付;
2)兼容性测试
不同系统、不同网络 (wifi/4/5G)、不同浏览器、不同的二维码
3)容错性测试
支付过程断网;
支付成功后退款;
余额不足,更换支付方式;
支付时指纹不正确、支付中关机、支付时跳转其他页面;
支付时刷新页面支付到一半取消返回;
4)性能和压力测试
多个用户同时向一个账户支付;
页面跳转时间;
支付成功后跳转账单信息时间;
支付时的耗电量;
支付金额不足时,更换支付方式跳转时间;
支付密码错误时,弹出信息时间;
不同的网络环境下,支付成功响应时间;
5)界面测试
支付页面简约大气;
支付页面显示金额字体合适;
输入密码时健盘字休洁晰大小合理;
账单信息页面完整清晰;
6)安全测试
密码是否可见;
支付较大金额会询问是否确定;
支付的金额与所扣的金额是否一致;
支付完成是否会跳转到账单信息页面;
在新设备上会提示支付实名认证;
7)易用性测试
免密支付;
指纹支付;
错误信息提示易懂;
2、梳理支付的业务流程
点击支付—> 选择支付方式 —> 确认金额—> 输入密码 —> 成功支付
完成这个流程测试,也就是完成了项目的冒烟测试!
然后需要测试针对流程中的每个阶段和步骤,具体分析可能导致异常的测试点,所以可以按阶段和输入项来进行划分。
3、支付的分类
一般来讲,线上支付分为两种消费模式。
一种是直接支付金额,如淘宝,京东等购物网站,或是360云盘,视频会员等这种会员服务;
另一种是充值购买金豆之类的虚拟币,在网站中使用虚拟币进行消费,比如游戏平台、花椒等产品!
1)功能测试
接下来就是测试方面的工作了,首先进行的是功能测试,那么将边界值、等类划分、错误推测,因果图等各种测试方法相结合,整理出来了一套相对全面的测试案例,对支付功能进行测试,从而确保整个支付流程和涉及到的支付流程在任何情况下都能使用。
文章目录 1.前言2. Imagewheel网站搭建2.1. Imagewheel下载和安装2.2. Imagewheel网页测试2.3.cpolar的安装和注册 3.本地网页发布3.1.Cpolar临时数据隧道3.2.Cpolar稳定隧道(云端设置)3.3.Cpolar稳定隧道(本地设置) 4.公网访问测试5.结语 1.前言 云存储在前几年风头无两,云存储平台也如雨后春笋般冒出来。但是这两年风头退去云存储平台相继关闭,除了几个互联网大厂,其他平台都在苦苦支撑。而图床作为云存储的一个分支,更是所剩无几。但图床不仅能用来存储个人图片,也能作为网站图片的来源,想要拥有一个稳定的图床,似乎只能自己动手。今天,笔者就为大家介绍,如何使用Cpolar+ Imagewheel,搭建一个简洁明了的私人图床。
2. Imagewheel网站搭建 Imagwheel是一款国外开发的轻量级图床程序,可以使用php5.X-7.X版本,同时也支持MySQL。虽然是轻量级图床程序,但其界面简单明快,看着很清爽,而功能也并不弱于其他图床程序。至少对用户来说,也是多一种的选择。
2.1. Imagewheel下载和安装 Imgwheel虽然是开源程序,但笔者没有找到github的下载地址,只能提供一个第三方下载地址(https://zhujiwiki.com/wp-content/uploads/2017/11/1917334780.zip)。Imgwheel源码下载完成后,将其解压,就能得到Imagewheel的源码文件夹。将这个文件夹粘贴到网站文件夹内(笔者使用的是phpstudy集成面板,因此将Imgwheel文件夹粘贴到phpstudy的WWW文件夹下),就可以开启Imagewheel网站安装流程。
接着打开phpstudy,在软件主界面左侧点击网站按钮进入网站列表页面,再点击网站列表页面左上的创建网站按钮,进入新建网站的设置页面。
在网站设置页面,我们需要进行设置的内容并不多,只要设置一下几项:
域名 - 本地打开Imagewheel网站的域名,可随意输入;端口 -Imagwheel网站的输出端口,只要未被占用即可;根目录 – Imagewheel网站的文件存放位置,在这个例子中,笔者将这些文件放在phpstudy的www文件夹下;程序类型 – 由于Imagewheel是一个轻量化的web程序,可在php5.X-7.X下运行,为保险起见,笔者选择php5.6.9版本。需要注意的是,Imagewheel正常运行需要打开php的gd、bcmath、mysql几项扩展。 由于Apache已经自带了伪静态规则,因我们使用Apache运行网站就不必进行额外设置。但如果使用Nginx,就需要设定相应的伪静态规则(笔者在网上找到的Nginx下Imagwheel伪静态规则有问题,会导致Nginx运行报错,因此不建议使用Nginx运行Imagwheel网站)。
这些设置完成后,就可以点击最下方的“确认”按钮,保存Imagewheel网站的设置。
下一步,我们只要在浏览器地址栏中,输入Imagewheel网站的本地地址,就可以开始Imagewheel网站的部署。由于Imagewheel网站网站的网页运行文件是application.php,因此在浏览器输入Imagewheel网站地址时,需要指明运行程序,需要输入的地址也变为“本地地址:端口号/application.php”。这里我们输入localhost:81/application.php。
这里我们输入localhost:81/application.php,就能进入Imagewheel网站的安装页面。
在安装页面,我们需要填入的信息并不多,主要是填入之前在phpstudy中设置的数据库信息,输入完成后,就能点击页面下方的“安装”按钮。安装完成后,就会转入Imagewheel网站的主页面。
虽然我们在本地电脑上部署好了Imagewheel网站,但想要访问网站,我们每次都要按“本地地址:端口号/application.php”格式输入地址,这明显不是我们想要的。因此我们将application.php复制粘贴,将复制的文件改名为index.php(也可以直接将application.php更名为index.php)。就可以按“本地地址:端口号”格式输入浏览器地址栏,访问到Imagewheel网站。
2.2. Imagewheel网页测试 按上述方法修改index.php文件后,我们在浏览器地址栏输入localhost:81,就能正确打开Imagewheel网站。
同时,我们可以点击Imagewheel网站右上角,输入安装Imagewheel是设置的管理员账号和密码,进入Imagewheel网站后台,对已有设置进行变更。
2.3.cpolar的安装和注册 完成Imagewheel网站在本地设备上的部署后,就可以转入cpolar内网穿透的安装。相比Imagewheel网站部署,cpolar的安装注册要简单很多。直接在cpolar的官网页面(https://www.cpolar.com/),就能找到“下载”按钮。
笔者使用的是Windows操作系统,因此选择Windows版本的cpolar进行下载。
Cpolar下载完成后,将下载的文件解压,双击解压后的.msi文件,即可自动执行安装程序。接着只要一路Next就能完成安装。
cpolar会为每个用户创建独立的数据隧道,以用户密码和token码保证数据安全,因此在使用cpolar之前,需要进行用户注册。注册过程很简单,只要在cpolar主页右上角点击用户注册,在注册页面填入必要信息,就能完成注册。
3.本地网页发布 到这里,我们完成了本地Imagewheel网站的部署,并安装了cpolar内网穿透程序。接下来我们就可以使用cpolar,创建一个能够连接本地Imagewheel网站的内网穿透数据隧道,让我们能在公共互联网上访问本地Imagewheel网站
3.1.Cpolar临时数据隧道 为满足部分客户需要的网页临时测试功能,cpolar可以直接在cpolar户端创建临时数据隧道(每隔24小时重置一次公共互联网地址,)。要创建临时数据隧道,我们直接在本地设备上登录cpolar客户端(在浏览器地址栏输入localhost:9200),并在cpolar客户端主界面点击隧道管理项下的创建隧道按钮,进入创建隧道设置页面。
在“创建隧道”页面,我们需要对几项信息设置,这些信息设置包括:
隧道名称 – 可以看做cpolar客户端的隧道信息注释,只要方便我们分辨即可;协议 – Imagewheel网站是网页程序,因此选择http协议;本地地址 – 本地地址即为本地Imagewheel网站的输出端口号,因此这里也填入81;域名类型 –这里我们可以区分数据隧道是临时使用,或是长期存续。由于我们只是先进行临时测试,因此选择“随机域名”(二级子域名和自定义域名都是长期稳定隧道,需要在cpolar云端预留公共互联网地址)。地区 – 即服务器所在位置,我们依照实际使用地就近填写即可; 完成这些设置后,就可以点击页面下方的创建按钮,建立一条临时数据隧道。临时数据隧道创建完成后,cpolar客户端会自动跳转至隧道管理项下的隧道列表页面,在这里我们可以看到cpolar本地的所有数据隧道(无论临时还是长期)。我们也可以在这里,对数据隧道进行管理,包括开启、关闭或删除这条隧道,也可以点击“编辑”按钮,最这条数据隧道的信息进行修改。
而我们创建的能够连接本地Imagewheel网站的临时公共互联网网址,则可以在状态项下的在线隧道列表中找到。
将这里显示的公共互联网地址粘贴到浏览器地址栏,就能访问到本地的Imagewheel图床页面。
不过,此时的Imagewheel数据隧道还只是临时数据隧道,每24小时就会重置一次公共互联网网址。如果还想要连接本地Imagewheel网页,就需要使用新地址连接。
3.2.Cpolar稳定隧道(云端设置) 如果想要为本地CFImagehost网站设置能长期稳定存在的数据隧道,我们需要先将cpolar升级至VIP版。
接下来,我们就可以登录cpolar的官网,并在用户主页面左侧找到预留按钮,点击进入cpolar的数据隧道预留页面,在这里生成一个公共互联网地址(可以看做数据隧道的入口),由于此时这个地址没有连接本地的软件输出端口,因此也可以看做是一条空白的数据隧道。
在预留页面,可以看到很多种可保留的数据隧道,这里我们选择保留二级子域名栏位。
在“保留二级子域名”栏位,需要进行几项信息的简单设置,即
地区(服务器所在区域,就近选择即可)二级域名(会最终出现在生成的公共互联网地址中,作为网络地址的标识之一)描述(可以看做这条数据隧道的描述,能够与其他隧道区分开即可) 完成这几项设置后,就可以点击右侧的保留按钮,将这条数据隧道保留下来。
当然,如果这条数据隧道不打算再使用,还可以点击右侧的“x”将其轻松删除,节约宝贵的隧道名额。
3.3.Cpolar稳定隧道(本地设置) 完成cpolar云端的设置,并保留了空白数据隧道后,我们回到本地的cpolar客户端,将云端生成的空白数据隧道与本地的测试页面连接起来。
40 设计一个点赞系统(开放设计: 怎么设计表 用什么存储 怎么处理高并发 容错等) 设计一个点赞系统需要考虑多个方面,包括数据库设计、存储选择、高并发处理、容错机制等。以下是一个高层次的设计方案:
1. 数据库设计 a. 表结构 点赞记录表:
user_id:用户ID。content_id:内容ID(比如文章、评论等)。timestamp:点赞时间。可以考虑使用复合主键(user_id, content_id),确保同一用户对同一内容的点赞唯一性。 内容统计表:
content_id:内容ID。likes_count:点赞总数。 b. 索引优化 对于点赞记录表,根据查询需求,可能需要对 user_id 和 content_id 建立索引。 2. 存储选择 关系型数据库(如MySQL):适用于存储结构化的点赞记录,易于维护数据的一致性和完整性。NoSQL数据库(如Redis):适用于缓存点赞计数,提高读取性能,尤其在高并发场景下。 3. 处理高并发 使用缓存:
将点赞计数存储在内存缓存(如Redis)中,以提高读取性能。定期(或基于特定条件)将缓存中的点赞数同步更新到数据库。 异步处理:
将用户的点赞操作异步处理,比如使用消息队列(如RabbitMQ或Kafka)。用户点赞操作首先写入消息队列,然后由后端服务异步更新数据库。 4. 容错和数据一致性 分布式锁:
在更新点赞计数时使用分布式锁,以保持数据一致性。 事务管理:
在更新点赞记录和点赞计数时使用事务,确保操作的原子性。 冗余和备份:
对数据库进行定期备份。在关键组件(如数据库、缓存服务器)上实施冗余,以提高系统的容错能力。 5. 扩展性考虑 数据库分片(Sharding):
当数据量增大时,考虑对数据库进行分片,分散负载。 负载均衡:
使用负载均衡器分配网络请求,特别是在微服务架构中。 6. 安全性考虑 防止重复点赞:
确保系统能够处理重复的点赞请求,避免数据不准确。 接口限流:
实现API限流,防止恶意请求或过载。 结论 设计一个点赞系统是一个复杂的任务,需要考虑性能、可扩展性、容错能力和数据一致性等多个方面。通过结合关系型和NoSQL数据库、实施缓存和异步处理、以及采取适当的容错和安全措施,可以构建一个高效且稳定的点赞系统。
1.多⼊⼝情况下,使⽤ CommonsChunkPlugin 来提取公共代码
2.通过 externals 配置来提取常⽤库
3.利⽤ DllPlugin 和 DllReferencePlugin 预编译资源模块 通过DllPlugin 来对那些我们引⽤但是绝对不会修改的 npm 包来进⾏预编译,再通过 DllReferencePlugin 将预编译的模块加载进来。
4.使⽤ Happypack 实现多线程加速编译
5.使⽤ webpack-uglify-parallel 来提升 uglifyPlugin 的压缩速度。原理上 webpack-uglify-parallel 采⽤了多核并⾏压缩来提升压缩速度
6.使⽤ Tree-shaking 和 Scope Hoisting 来剔除多余代码
【题目来源】
https://www.acwing.com/problem/content/description/5063/
【题目描述】
有 n 个同学在同一个食堂窗口排队打饭,按照到达队伍的时间顺序,从先到后依次编号为 1∼n。
其中,第 i 个同学的到达队伍时刻为 ai,打饭耗时为 ti。
每个同学的耐心都是有限的,第 i 个同学的最大等待时间为 bi,即如果其在第 ai+bi 时刻还没有开始打饭,他就会离开队伍,放弃打饭。
在一个同学打完饭后,下一个同学会立即开始打饭,中间的时间损耗忽略不计。
例如,如果一个同学在时刻 1 开始打饭,打饭耗时为 3,那么他会在时刻 4 打完饭,而下一个同学也会在时刻 4 开始打饭。
请你计算,每个同学的开始打饭时刻。
【输入格式】
第一行包含整数 n。
接下来 n 行,其中第 i 行包含三个整数 ai,ti,bi。
【输出格式】
共一行,输出 n 个整数,其中第 i 个整数表示第 i 个同学的开始打饭时刻,如果该同学放弃打饭,则输出 -1。
【数据范围】
1≤n≤10^5 ,
1≤ai,ti,bi≤10^9。
数据保证 a1<a2<…<an。
【输入样例】
4
1 3 3
2 2 2
3 9 1
4 3 2
【输出样例】
1 4 -1 6
🌈键盘敲烂,年薪30万🌈
目录
一、索引优化
1、索引是什么:
2、索引的数据结构:
3、索引种类:
4、sql分析(回表查询)
二、定位慢查询语句
1、慢查询日志
2、profile详情
3、explain执行计划(重点)
4、查看执行频次
一、索引优化 1、索引是什么: 通过一些约束,快速查询到相应字段的一种数据结构
索引在sql优化中占有非常重要的地位,因为索引与查询挂钩,查询是我们最常做的一个操作。
2、索引的数据结构: Hash索引:查询快,但是不支持范围查询,只能精确定位某个数据。
B+树索引:查询较快,支持范围查询,这也是InnoDB存储引擎中默认的索引结构
B+树结构:
多路平衡树,每个节点存放key和指针,指针数量等于key数量+1
插播小知识:
B+树与B树,有什么区别,为什么不用二叉树???
B+树没个非叶子结点只存放指针,可以最大限度的降低树的高度,提高查询效率。
所有数据存放在叶子节点,查询稳定,而二叉树层次会更深,也会有退化为链表的风险
3、索引种类: 聚簇索引:叶子节点中主键下面挂的是每一行的数据
二级索引:叶子节点中索引值下面挂的是主键id
4、sql分析(回表查询) 现有user表,id为主键,name有唯一约束和唯一索引结构,分析下面sql语句。
-- select * from user where id = 1;
-- select * from user where name = 'zhang';
分析:
①where 后面是id,从主键索引里面查找,找到了id为1的,再看前面select 后面是 * 主键下面包含了这些字段信息,直接返回。
②where 后面是name,并且有唯一索引结构,从该索引查找,找到了姓名为zhang的,同样select * 也是查询所有字段,但是此时name下面只有主键id的值,他要根据id再次查询主键索引,性能低
二、定位慢查询语句 1、慢查询日志 mysql带有慢查询日志,该日志会记录超过指定时间的sql语句, 注意:
慢查询日志默认为不开启,开启之后默认指定时间为10s。
可通过修改配置文件来设置这两参数。
修改mysql的配置文件 缺点:
有些sql在规定的时间之内,但是查询花了9.9秒,并且性能很低,慢查询日志无法记录这样的sql我们也就无法优化.
2、profile详情 show profiles 查看sql语句的执行时间 show profile for query query_id; 查看指定语句的执行时间 3、explain执行计划(重点) explain执行计划:他记录了sql查询的一些详细信息 例如:查询部门和员工信息,
1.卸载旧版 首先如果系统中已经存在旧的Docker,则先卸载:
yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine 2.配置Docker的yum库 首先要安装一个yum工具
yum install -y yum-utils 安装成功后,执行命令,配置Docker的yum源:
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo 3.安装Docker 最后,执行命令,安装Docker
yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin 4.启动和校验 # 启动Docker systemctl start docker # 停止Docker systemctl stop docker # 重启 systemctl restart docker # 设置开机自启 systemctl enable docker # 执行docker ps命令,如果不报错,说明安装启动成功 docker ps 5.配置镜像加速 这里以阿里云镜像加速为例。
5.1.注册阿里云账号 首先访问阿里云网站:
一、概述
String是Redis最基本的类型,你可以理解成与Memcached一模一样的类型。
String的数据结构为简单动态字符串(SimpleDynamicString,缩写SDS),是可以修改的字符串,内部结构实现上类似于Java的ArrayList,采用预分配冗余空间的方式来减少内存的频繁分配。
二、String底层结构
1.SDS结构
Redis 使用 SDS 简单动态字符串(Simple Dynamic String,SDS)来表示字符串,SDS 的主要结构如下:
struct sdshdr { // buf数组中已使用字节的数量 int len; // buf数组中未使用字节的数量 int free; // 字节数组,用于保存字符串 char buf[]; }; 1.“Free”:表示 Buf 数组中未使用字节的数量,也就是 Buf 数组的剩余空间。这样可以在增加字符串长度时,避免频繁的内存重新分配。
2.“Len” :表示 Buf 数组中已使用字节的数量,也就是字符串的长度。这样可以在 O(1) 的时间复杂度内获取字符串长度,而不需要像 C 语言字符串那样遍历整个字符串。
3.“Buf[]” :表示字节数组,用于保存字符串。这个数组的末尾总是包含一个空字符(‘\0’),这样 SDS 就可以兼容 C 语言的字符串函数。
2.SDS优点
(1)获取长度的时间复杂度为 O(1):SDS 内部维护了一个 len 属性,这个属性记录了字符串的长度,因此获取字符串长度的时间复杂度为 O(1),而 C 字符串需要遍历整个字符串才能获取到长度,时间复杂度为 O(n);
(2)内存效率:SDS 通过维护一个 free 属性,记录了 buf 数组中未使用的字节数量,这样可以在需要扩展字符串时,直接使用这些未使用的空间,而不需要重新分配内存,提高了内存的使用效率;
(3)避免缓冲区溢出:SDS在进行字符串修改操作时,会先检查缓冲区是否满足条件,如果不满足,会自动扩展缓冲区,因此可以避免缓冲区溢出的问题。而C字符串则需要程序员自己保证不会发生缓冲区溢出;
(4)减少内存重新分配的次数:当给sds的值追加一个字符串,而当前的剩余空间不够时,就会触发sds的扩容机制。扩容采用了空间预分配的优化策略,即分配空间的时候:如果sds 值大小< 1M ,则增加一倍;反之如果>1M , 则当前空间加1M作为新的空间;
目录
1 脚本名称
2 脚本使用说明
3 nocare_list文件示例
4 脚本执行方法
5 postsim_result.log文件示例
6 脚本代码
1 脚本名称 post_analysis
2 脚本使用说明 help:打印脚本说明信息
命令:post_analysis help
前/后仿结束后,首先填写好nocare_list(要过滤的log信息),然后在有log文件的上一层次路径下运行post_analysis脚本,执行脚本时若不带-all参数,则过滤掉nocare_list中的信息后只对后仿log进行分析,若带-all参数,则会过滤nocare_list中的信息后,对前/后仿的log信息进行分析,给出pass、timeout、bombed、violation等结果:
(1)不带-all参数:
脚本会只分析名称带max或者min的后仿文件夹如(rfdig_m33_tc029_max、rfdig_m33_tc001_max_20230911),除去runsim.log文件中和nocare_list中的内容相关的violation,之后在各个用例文件夹下产生runsim_temp.log文件,随后分析runsim_temp.log文件out of reset之后的内容,若case PASS但存在violation,则输出结果 VOILATION以及$setuphold/$setup/$hold/$width违例的数量,并产生结果文件: postsim_result.log;若不仍存在violation,则输出结果PASS到postsim_result.log文件中;否则输出结果FAIL、TIMEOUT、RUNNING、BOMB到postsim_result.log文件中。
(2)带-all参数:
对前仿也进行上述分析。
3 nocare_list文件示例 在runsim.log中找到包含以下关键字的行,并将其删除:
4 脚本执行方法 post_analysis //只对文件夹名称中有max或者min的后仿文件夹进行分析 post_analysis -all //对前后仿的文件夹都进行分析 5 postsim_result.log文件示例 (1)PASS说明reset后无任何violation;
(2)VOILATION说明reset后仍存在violation,需查看对应的runsim_temp.log确认每一个violation;
(3)FAIL说明用例fail,需查看对应的runsim_temp.log,确认fail原因;
(4)TIMEOUT说明用例超时,需查看对应的runsim_temp.log,确认超时原因;
(5)RUNNING说明用例还在跑,确认相关原因;
(6)BOMB说明用例编译失败,需查看对应的vcs_compile.log确认编译失败原因;
6 脚本代码 #! /usr/bin/perl -w #========================================================== # PERL MODULE #========================================================== use Cwd; use Getopt::Long; $Getopt::Long::ignorecase = 0; #========================================================== # PERL FUNCTION GetOptions (get command parameters) #========================================================== GetOptions("
手把手教你用C#语言写一个简单计算器窗体(附源代码文件和演示视频)!
目录
C#简介:
开发工具的介绍和安装:
计算器的编写过程:
下面是源代码(Form1.cs文件):
彩蛋:
1.插入并载入新的窗体(窗口):
2.插入图片并让其适中显示:
下面是“彩蛋”源代码(Form2.cs文件):
最终效果演示:
帮人帮到底!源代码文件分享链接如下:
C#简介: C#是由C和C++衍生出来的一种安全的、稳定的、简单的、优雅的面向对象编程语言。它在继承C和C++强大功能的同时去掉了一些它们的复杂特性(例如没有宏以及不允许多重继承)。C#综合了VB简单的可视化操作和C++的高运行效率,以其强大的操作能力、优雅的语法风格、创新的语言特性和便捷的面向组件编程的支持成为.NET开发的首选语言。
开发工具的介绍和安装: 这里用的是VS2022,可以去官网下载安装(链接如下)Visual Studio: 面向软件开发人员和 Teams 的 IDE 和代码编辑器
Visual Studio2022除了体积较大,可以说是很强大的IDE了可以编写多种语言并且内置编译器,代码补全功能也十分优秀。
计算器的编写过程: 首先我们新建一个窗体文件以后,映入眼帘的是一个空白的窗体(窗口),默认为Form1,我们计算器的UI就是要在这上面绘制 这里我们就用到了“控件”,也就是像按钮和文本框这些我们在使用中所需要的东西。
如果vs2022打开后没有显示旁边的工具箱,可以在视图-->工具箱里面打开,或者CTRL+ALT+X;
这里面的分类可以方便我们查找我们所需的工具
放置文本的控件 计算器的主要控件按钮 我们新建完控件会发现,我们需要设置他的标题,大小还有里面的内容的字体等等
这里就需要用到属性。
我们需要单击控件,选中后,右键,然后点击属性,然后对属性进行修改。
TextBox基础属性设置 我们双击任何一个按钮(控件)进入代码编辑区
我们会发现,每一个控件包括窗体都对应着一个函数,我们剩下的工作就是编辑代码,补全这些函数,使其联系起来,让代码运行顺利,并且达到我们想要的逻辑效果。 下面是源代码(Form1.cs文件): using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Runtime.Remoting.Messaging; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace 计算器 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button2_Click(object sender, EventArgs e) { textBox1.
vue2 批量全局引入:
import Vue from "vue" const components = require.context( './', //组件所在目录的相对路径 false, //是否查询其子目录 /[A-Z]\w+\.(vue|js)$/ //匹配组件文件名的正则表达式 ) components.keys().forEach(fileName=>{ // 获取文件名 var names = fileName.split("/").pop().replace(/\.\w+$/,""); // 获取组件配置 const comp = components(fileName); // 若该组件是通过"export default"导出的,优先使用".default", // 否则退回到使用模块的根 Vue.component(names,comp.default || comp); }) 批量局部引入:
<script> // 引入所有需要的动态组件 const components = require.context( "./", //组件所在目录的相对路径 true, //是否查询其子目录 /\w+.vue$/ //匹配基础组件文件名的正则表达式 ); const comObj = {}; components.keys().forEach(fileName => { // 获取文件名 var names = fileName.split("/").pop().replace(/.\w+$/, ""); // 获取组件配置 const comp = components(fileName); // 若该组件是通过"
目录
kruskal算法思路
编辑
代码实现
编写 边结构体
编写push函数
编写kruskal函数
完整代码
结尾
kruskal算法思路 代码实现 这个代码是在图的邻接矩阵(无项、有权)的代码的基础上,添加了kruskal最小生成树的函数,并且修改测试用例和主函数代码,图的邻接矩阵(无项、有权)的代码具体请查看 【C语言\数据结构】图之邻接矩阵(无向、有权)代码简单实现,这里就不过多赘述。
编写 边结构体 typedef struct { int start; int end; int weight; }edge; 创建一个边结构体,用来表示一条边的起点和终点以及权值。
编写push函数 void push(edge temp,edge edges[],int edgesCount){ int index=edgesCount-1; while(index>=0&&edges[index].weight>temp.weight){ edges[index+1]=edges[index]; index--; } edges[index+1]=temp; } push函数中,第一个参数是边结构体类型的变量temp,temp表示一条边。第二个参数是边结构体数组edges,按照边的权值升序存储edge数据类型,用来模拟优先队列。第三个参数是edgesCount,表示edges数组的元素个数,用来对edges数组进行尾插操作。
edges数组按照边的权值,升序存储数据,每一次添加数据,把数据插入到指定位置,从最后一个元素开始遍历,如果该权值大于插入元素的权值,就往后赋值,挪一个位置,依次循环。循环结束标志有两个,第一个是遍历完所有元素,第二个是找到了指定的位置。最后把temp插入指定位置即可。
相同结构体数据类型变量直接赋值,表示把各成员变量数据依次赋值。
编写kruskal函数 void kruskal(graph g) { int sum = 0; edge temp; edge edges[MAX]; edge edgesGather[MAX]; int edgesGatherCount = 0; int edgesCount = 0; for (int i = 1; i <= g.
SSD的存储介质是什么,它就是NAND闪存。那你知道NAND闪存是怎么工作的吗?其实,它就是由很多个晶体管组成的。这些晶体管里面存储着电荷,代表着我们的二进制数据,要么是“0”,要么是“1”。NAND闪存原理上是一个CMOS管,有两个栅极,一个是控制栅极(Control Gate), 一个是浮栅(Floating Gate). 浮栅的作用就是存储电荷,而浮栅与沟道之间的氧化层(Oxide Layer)的好坏决定着浮栅存储电荷的可靠性,也就是NAND闪存的寿命。
目前市面上主要流通的就是4种NAND类型:SLC、MLC、TLC、QLC。随着每个寿命从高到低依次是SLC>MLC>TLC>QLC.
随着单个cell含有的bit数越多,NAND的可靠性也会有所降低。同时写延迟也在不断的增加。SLC写延迟在0.5ms级别,到QLC写延迟达到10-20ms,40倍的差距。这也导致QLC SSD性能出现很大的下降。
目前业内3D-NAND工艺架构主要分为两个阵营:
一个阵营,以Solidigm(Intel存储产品卖给海力士后新成立的公司)为首,采用Floating Gate(FG)浮栅,FG浮栅将电荷存储在导体中。FG浮栅对read disturb和program disturb的抗干扰比CTF要好。
一个阵营,剩余其他NAND原厂,三星/WD/铠侠等,采用Change Trap Flash。Micron最开始用FG,后来也转投CTF阵营。CTF将电荷存储于绝缘体中,这消除了单元之间的干扰,提高了读写性能,同时与浮栅技术相比减少了单元面积。
不过,很遗憾,随着Micron的放弃以及最后一根独苗Solidigm被海力士收购,FG浮栅架构前景不乐观,也许FG NAND很快会成为历史。
FG浮栅架构在Program过程,采用4-16 program算法,这个过程可以减少program disturb写干扰。
CTF架构,或者叫做RG架构,采用16-16 progam算法,两次program都要求所有page直接写入NAND,第一次program电压是放置在最终电压附近。CTF的Data Retention相对比较严重。
在写性能方面的对比,不同的架构有不同的表现。
在TLC NAND中,CTF架构tPROG比FG浮栅低18%,所以在TLC SSD中,CTF架构TLC NAND SSD的性能比FG架构TLC NAND SSD性能要好。
在QLC NAND中,由于program算法差异的影响,FG浮栅表现更好,FG架构QLC NAND SSD性能比CTF架构QLC NAND SSD性能要好。
从QLC SSD性能对比图,同样4plane的QLC SSD,采用FG架构的Intel QLC SSD写延迟tPROG=1.63ms比采用CTF架构的SK Hynix写延迟tPROG=2.15ms要低。
不同的NAND工艺架构,在不同的维度各有千秋,对维度对比,供大家参考。
目前业内3D NAND各家原厂分别是什么情况呢?参考Techinsights公布的各大原厂架构分析,可以从以下几个纬度了解下各家的差异:
1.3D NAND架构演进路线图:
(图片自Techinsights,如有侵权,请私信告知)
2.不同NAND原厂主流架构对比:
(图片自Techinsights,如有侵权,请私信告知)
3.不同NAND原厂 3D NAND堆叠层数趋势变化:
(图片自Techinsights,如有侵权,请私信告知)
4.不同NAND原厂 3D NAND Bit Density对比:
(图片自Techinsights,如有侵权,请私信告知)
5.不同NAND原厂 3D NAND Gate间距对比:
(图片自Techinsights,如有侵权,请私信告知)
令牌桶算法是网络流量整形(Traffic Shaping)和速率限制(Rate Limiting)中最常使用的一种算法。典型情况下,令牌桶算法用来控制发送到网络上的数据的数目,并允许突发数据的发送。
用简单的话语来说就是限制流量,将其控制到某一平均值稳定输出,并可以在短时间内应对高额流量(短时高速率流量)的一种方法。
需要注意的是,限速只是让他尽可能速率一致,是存在速率不稳定的情况的,只有在长期来看速率才是恒定的,而当令牌桶应对突发流量时会进行令牌桶内令牌的小号,理论上的峰值速率=令牌桶的容量+恒定速率,举个例子,令牌桶的容量 为100MB,限制的速率为10MB/s,峰值速率则可以达到100+10=110MB/s。
b为桶的容量,r为单位时间内放入的令牌数量,以下图为例:
在r=10,b=5时,即表明每1/r=0.1,每0.1秒投入一个令牌,而在到0.5秒时达到桶的极限容量5,在此刻继续投入令牌则无法维持,这些令牌将会被废弃,同时在此时若有5个指令同时想要去走令牌则可以同时取走令牌桶内的所有令牌,即为取走b=5个。
注意:
当b>1时(桶的大小大于1个令牌时),任意1/r秒内最多可以取走b个令牌;而当b=1时(桶的大小就是1),每秒钟最多可以被取走r个令牌。 综上,令牌桶算法的总体流程大致分为如下三步:
将令牌放入桶内:按照固定的速率放入令牌桶内,例如r=10,20,100等;获取令牌:任意请求只有在取得可用令牌才会被接收处理;令牌桶已满:当桶内令牌已满时,新加入的令牌会被丢弃或者拒绝接收。 与网络带宽分配相结合,可在一定程度上减少资源的浪费,同时可以根据不同优先级的业务来进行基于令牌桶的带宽分配改进方式,针对不同优先级的业务设定不同的业务权值,以此来自适应业务速率的变化,可通过业务权值的占用比例进行动态分配令牌资源,利用令牌桶嵌入漏桶机制实现对业务占用的带宽进行二次分配,根据业务优先级的高低对溢出的令牌实现依次填充,从而减少资源浪费。(源自论文:基于动态令牌桶的卫星网络带宽分配方法)
卫星网络模型:一个GEO卫星,若干地面终端和网络控制中心NCC(Network Control Center)组成,地面终端则是经由SG(Satallite Gateway)连接到Internet网络。通过网络控制中心NCC来进行处理各个SG发来的带宽申请和分配新的贷款,上行链路由各个SG提供,下行链路则是数据流共享的信道。
GEO卫星网络 令牌桶方法实现:令牌桶的填充速率R,令牌桶容量S(令牌桶所能容纳的最大令牌数),令牌桶的当前状态为x,表示当前对应令牌桶的深度,工作流程如下图:
工作流程上,GEO卫星上的带宽资源被定义为n个令牌桶,当有业务传达到时,NCC处理由SG为每个业务发送的带宽请求并为其分配带宽,哥哥令牌桶为每个业务分配基本保证带宽,即为R1,R2,R3......Rn。调整R1,R2,R3......Rn的大小可以设定各个业务的保证带宽,需要注意,各个令牌桶的尺寸小于链路的信道容量,各个业务到达相应令牌桶后,根据数据包长度与令牌桶内数量来进行分配,若数据包长度小于令牌数,业务传送出去,令牌桶内令牌相应减少。而高优先级的业务将会优先进行放入。而由于令牌桶间仙姑独立,令牌桶无法动态借用空闲令牌,即空闲带宽无法进行有效利用,且令牌桶在填充过程中,令牌个数不会大于令牌桶容量,溢出令牌会丢失,也进一步造成了带宽资源的浪费。
改进方法:将漏桶嵌入到令牌桶中,即每一个令牌桶连接一个漏桶,有几个优先级就有几个令牌桶。这样可以保证优先级为n的最小带宽,溢出桶用来存储溢出的令牌,借用令牌桶的动态带宽分配算法(Dynamic Bandwidth Allocation Algorithm with Token Bucket,DBAATB),原理下图:
代码实现:
acquire获取令牌的操作中,使用锁保护数据正确性,使用条件等待令牌足够才继续往下执行。
bool CountSemaphore::acquire(unsigned long long count) { std::unique_lock<std::mutex> lck(m_mtx); if (count > m_maxCount) { return false; } m_cv.wait(lck, [&]() -> bool { return m_updateCount >= count; }); m_updateCount -= count; return true; } release增加令牌数量,并通知其他等待条件的线程继续执行。
void CountSemaphore::release(unsigned long long count){ std::unique_lock<std::mutex> lck(m_mtx); auto tobeCount = m_updateCount + count; if (tobeCount > m_maxCount){ m_updateCount = m_maxCount; } else{ m_updateCount = tobeCount; } m_cv.
看到这篇大佬的文,担心之后会变成VIP的,所以先搬运。
OpenVAS安装和使用 一、参考二、环境三、安装Kali四、配置IP地址五、配置apt镜像源六、安装OpenVAS 离线安装七、配置GVM 离线上传特征库 (攻击脚本、漏洞信息、gvm配置数据等)八、汉化九、使用GVM十、特征库更新 一、参考 Greenbone Enterprise Appliance 22.04.13 文档从源代码构建 22.4 - 绿骨社区文档 (greenbone.github.io)腾讯软件源 (tencent.com)GSA翻译文件代码参考安装 Kali Linux |Kali Linux 文档 OpenVAS离线资源
OpenVAS GVM中文翻译补丁
二、环境 操作系统:kali-2023.2a
Greenbone Security Assistant (OpenVAS):22.5.5 for kali
三、安装Kali 参考安装 Kali Linux |Kali Linux 文档安装Kali系统,最小化安装即可。
四、配置IP地址 # 查看网卡名称 ip addr # 修改网卡配置文件 sudo nano /etc/network/interfaces 我的网卡名称为eth0,根据网卡名称在网卡配置文件/etc/network/interfaces下面添加以下配置(注意原有的eth0配置要删掉)
iface eth0 inet static address 10.10.10.1/24 gateway 10.10.10.254 dns-nameservers 223.5.5.5 # 修改DNS sudo nano /etc/resolv.conf DNS配置文件/etc/resolv.conf
nameserver 223.5.5.5 # 重启网络服务 sudo systemctl restart networking # 开机自动开启SSH服务 sudo systemctl enable ssh # 启动SSH服务 sudo systemctl start ssh 五、配置apt镜像源 # 修改镜像源为腾讯源 sudo sed -i 's/http:\/\/http.
目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 1、性能测试的四个方面
完整的性能测试可以分为四个方面:
1)测试策略制定;
2)性能脚本编写;
3)被测系统监控
4)性能瓶颈调优。
2、测试需求分析
1)业务场景分析
测试银行核心系统时将柜员签到、签退、业务操作、批量等众多交易放在同一场景中执行,这样的场景在现实中是否存在?
测试POS、ATM等渠道时将查询、动账类交易各按50%的比例分配,这样的比例是否正确?
所有的性能测试都是以复现实际业务场景为目标。因此业务场景分析和选取务必严谨。业务场景应该从时间和空间两个角度考虑:
时间角度:
分别以一年、一月、一天的角度观察,被测系统是否存在业务高峰时段。各高峰时段的重点交易是什么,交易比例如何。
空间角度:
根据各分行业务特点不同,被测系统是否存在不同的高峰场景和交易,操作交易的柜员数量及一般操作时间是多少。
业务场景分析阶段应向业务、研发、运维等多部门了解被测系统需求,但就数据准确度而言,应多参考生产日志。
对升级改造类系统,场景分析的数据可从老系统的生产日志中获取;对新开发的系统,分析数据可从业务上有关联的其他系统中获取,同时参考业务部门意见。
典型业务场景可以不止一个,但一定要明确各场景中的交易和比例,不要模拟一个不存在的大混合!
2)负载目标计算
与项目管理中的SMART原则类似,业务场景需转换成可量化、可衡量、可实现的负载目标才能进行性能测试,而负载目标要根据不同场景分别计算。
根据上阶段收集到“原始”数据,本阶段可计算或指定出各种间接和直接的负载目标值,一般负载目标多从两种角度考虑:
前端角度:
在线用户数量:间接负载目标值,可理解为所有能操作被测交易的用户(柜员)数量。
平均操作时间(思考时间):间接负载目标值,与在线用户数量一同计算业务并发数量。
业务并发数量:典型场景中集中操作(不是绝对并发)交易的用户(柜员)数量。
后端角度:
每秒交易数量(TPS):根据日志计算出的被测系统应承受的每秒交易数量。
交易响应时间(TRT):与TPS对应,负载场景下交易应达到的响应时间。
吞度量(Throughout):LoadRunner中吞度量是以每秒收到的字节数计算,其实TPS也是吞吐量的一种,根据不同被测系统计算对应的吞吐量。
系统并发数量:区别于业务并发数量,系统并发数量更趋近于绝对并发。对长连接系统来说系统并发就等于允许的连接数,对短连接系统来说更多取决于架构。
被测系统CPU、Mem、Disk等指标值:多为指定值,如CPU利用率不高于80%等。
前端负载目标需要通过大量、广泛的业务和日志统计才能得出,如需记录下高峰时段操作交易的用户数量、估算用户状态比例、统计操作习惯等,由于考虑到人的因素,因此前端负载很难计算精确。
前端负载目标适合交易关联不大、操作用户分散、无具体业务量要求的系统,如内控管理、培训考核、网银主页等(以B/S架构为主)。
后端负载目标则比较容易计算,如当前某省对公汇兑类交易日均8万笔,则TPS=80000/(66060)=3.7笔/秒(对公按6小时计算);
核心系统联机交易平均响应时间在3秒以下等。后端负载目标适合交易关联度大、操作用户相对集中、有具体业务量要求的系统,以银行核心业务系统为主。
负责目标需要针对不同类型的被测系统计算合理的目标值,同时还需考虑2/8原则,未来业务量、用户量扩展等因素,这里不做赘述。
3、测试环境设计
1)硬件环境设计
大部分性能测试的硬件环境与生产相去甚远,受品牌、型号、部署方式(集群个数减少,软负载均衡代替硬负载均衡)等多种因素限制,无法直接将测试环境下的性能结果向生产环境做比例放大。
因此硬件环境设计主要关注应用架构与生产环境一致(如应用、数据库服务器必须为集群方式),尽量减少性能测试中的硬件资源瓶颈(如数据库存储必须为SAN,发压与被测系统间网络带宽必须为1000M)。
2)软件环境设计
软件测试环境可从两个方面考虑:
基础配置:
确认操作系统、中间件、数据库和被测系统的版本与补丁与生产环境一致,但操作系统、中间件、数据库的内部参数应根据测试硬件环境做适当调整,可参考生产中的设置比例。
数据库分区、索引等必须与生产或预计投产时一致。
外联系统:
尽量减少外联系统,因为外联系统越多,测试链条越长,环境越难维护,问题越难定位。可适当在被测系统中做挡板程序,模拟与外联系统的应答,但必须保证被测系统中的逻辑分支没有被屏蔽。
3)铺底数据策略
性能铺底数据量的大小和分布情况会对测试结果产生极大影响,是场景设计阶段的重中之重!测试前对铺底数据的构造可从以下四个方面考虑:
表分区情况:
确认测试环境与生产环境(或预计投产后)的表分区和索引分区规划一致,结合表清理策略确认典型场景中各分区、各表中的数据存量大小和分布情况。
表清理策略:
确认生产环境(或预计投产后)的数据库表(尤其业务热表)清理和备份策略,与表分区情况配合,预铺数据并确保测试数据库表中数据存量与生产保持同一量级。
表维护策略:
确认当前生产数据库表(尤其热表)和索引统计值更新、rebuild和reorg等操作的频度,在数据预铺中适当更新统计值,切勿在测试环境中频繁执行统计值更新等操作,造成虚假的性能表现。
如下图,更新统计值后表和索引的相关信息会统计正确,性能将得到一定程度的提升。
合理的业务数据:
确认铺底数据中的柜员、行部、角色、权限、待处理任务等业务数据是否符合实际情况,切勿为图省事而创建超级行部、全能柜员和过量的待处理任务。
4、测试场景设计
1)发压数据策略
测试发压数据应在数据铺底时一同考虑,但发压数据需要和压力工具配合使用,可从以下四个方面考虑:
表分区情况:
确认发压数据覆盖各表分区,且在分区中也需尽量离散,不要集中操作(主要是查询)同一范围内的数据。
表维护策略:
通常生产环境中数据库表在日终结束后执行统计值更新,对应第二天营业时的数据状态,除柜员签到外,其余典型场景均发生在更靠后的营业时段。
因此不要在刚刚执行完统计值更新的环境中执行正式的性能测试,建议再执行一段时间的数据预铺,模拟行部营业一段时间后的业务,这时再执行正式的性能测试,并记录结果。
目录 1.简介2.下载安装包3. 安装4. 使用 1.简介 JFrog Artifactory二进制文件管理工具,目前已经在使用的公司有很多,足见他的方便好用。
2.下载安装包 点击下载地址
这里我下载的是7.9.2版本
3. 安装 (1)在安装JFrog Artifactory之前需要安装好jdk(需要1.8版本以及上即可),在Linux执行java -version检查下安装环境是否已安装好jdk
(2) 上传下载的二进制压缩包jfrog-artifactory-oss-7.9.2-linux.tar.gz到Linux的/opt目录下,并解压
cd /opt tar -zxvf jfrog-artifactory-oss-7.9.2-linux.tar.gz mv artifactory-oss-7.9.2 jfrog_artifactory (3)进入/opt/jfrog_artifactory/app/bin目录,然后启动jfrog artifactory
./artifactoryctl 命令参数
命令参数说明start启动运行stop停止运行restart重启运行status查看运行状态check检查 cd /opt/jfrog_artifactory/app/bin ./artifactoryctl start 看图表示已成功启动运行
(4)浏览器访问
访问地址:http://部署的IP地址:端口号,默认端口号是8081,如果占用可以修改成其他端口号启动
例如:http://192.168.225.68:8081
4. 使用 首先登陆,用户名:admin 密码:password,登陆后需要修该密码。
修改上传文件大小的限制,默认限制100M,改为0就是无限制
到此配置完成,可以使用了!!!
创建一个新库install_packages
选择新库类型
给新库命名
上传文件
点击上传箭头或者把文件直接拖拽到这里都可以
上传的文件也可以下载使用
目录 1、免安装使用(绿色版)2、 安装使用3、war包部署4、docker容器部署 1、免安装使用(绿色版) 这种直接下载下来直接就可以使用,属于绿色版(开箱即用),适用于个人
点击下载地址
2、 安装使用 这种下载下来就需要安装才可使用,适用于个人
点击下载地址
3、war包部署 drawio软件使用java开发的,所以可以使用部署war包的方式部署在tomcat里面,把war包放到tomcat的webapps目录下然后启动tomcat后直接使用浏览器就可以访问网页版,适用于团队使用
点击下载地址
访问地址:http://部署drawio的IP地址:端口号/draw
例如:http://192.168.225.68:8080/draw
4、docker容器部署 这种是使用drawio的docker镜像启动容器的方式部署web版,前提是你的系统要先安装docker,然后在使用下面的命令启动docker容器,直接使用浏览器就可以访问网页版,适用于团队使用
docker pull jgraph/drawio 镜像拉下来后再启动容器 docker run -d --name drawio -p 9999:8080 c169fe2d8326 访问地址:http://部署docker的IP地址:映射端口号/draw
例如:http://192.168.225.62:9999/draw
最近在公司分享了Electron的相关技术栈的应用,准备的还是挺充分的,下面将分享的内容大纲附上
1 为什么Electron这么火 1.1 Electron是什么? Electron是Github开发的开源框架
它允许开发者使用web技术构建跨平台桌面,兼容 Mac、Windows(exclude XP) 和 Linux,可以构建同时支持三个平台的应用程序
跨平台构建应用,一直都是香饽饽,随着载体产商的丰富之后,已经不能满足于以前的android和ios两大阵营,同时还有各种小程序,从微信到抖音、百度、支付宝等,因此应运而生的就有各种岗位的需求,但是当这种需求达到一定波峰的时候,势必会走下坡路,更别说出现了各种的跨平台的技术加持,这种下坡速度就更快了。
Electron就是这种跨平台技术阵营的一员,虽然相比C++等以更接近底层和追求性能的技术相比,有一定的差距瓶颈,但是随着硬件的快速发展,这种跨平台技术的性能缺陷,完全可以忽略,同时因为其入门简单,社区活跃,发展迅速,反而占据了一定市场。
这边重点提下发展迅速的意思吧,举个例子我再11月5日中午的时候,版本还是27.0.2,到了晚上的时候就版本就更新到了27.0.3,到了11月16日的时候,版本已经升级到了27.0.10。迭代的频率够大了吧,但是这么快的频率背后也是有一些问题的,这边先不说!
1.2 什么时候用Electron 快速试错场景 比如工期有限,需要快速出demo
效率工具和开发者工具 说白了,就是提升我们工作效率的工具的开发,可以考虑用Electron;同时开发人员要用的工具都可以考虑用这个来开发,比如我最近在云内正在构建的知识库-桌面版,目前已经有知识库-web版并在项目组内部在用了,但是还是有诸多的场景感觉瓶颈很明显,比如对本地文件的处理。后续的多功能记事本案例就是对这个的说明。
成本管控严格 就是说就这么多人力和财力预算,但是让你同时开发桌面应用、web应用,这个时候肯定不可能又招ui工程师、前端工程师、后端工程师、C++开发工程师等。那么这个时候就可以考虑Electron的引入了。
1.3粉丝应用有哪些? Electron的发展其实很久了,在技术领域不算新秀了,最初被GitHub开发,2013年4月11日以Atom Shell为名起步,2014年5月16日开源,2015年4月17日改名为Electron。
我最早听到Electron是从听说vscode是用electron开发的,后面进一步了解,还有像美团大象、Atom等。难怪Vscode看起来跟其他的工具相比,总觉得好看多了。
2 白话Electron架构原理 2.1 最简单的Electron应用 一个最简单的Electron项目包括三个文件
package.jsonindex.html 渲染进程页面 main.js 主进程文件 2.2 Electron核心 2.2.1 Node.js - 能力:底层能力,支持与底层OS交互 - 后台服务的能力,增强web技术 - 技术手段多,开源npm包丰富 Node.js作为可以替代Java开发服务的技术,在整个应用开发过程中,作用非常明显。并且曾经Node.js以其拥有最大的依赖包仓库而广为闻名,因此各种前卫的、流行的功能,有它的加成,实现都是轻而易举的,比如基于Puppeteer库,可以快速且低代码的完成截屏、海报等图片的生成。
2.2.2 内置Native API - 跨平台 - 原生能力:比如窗口,进程监控等 2.2.3 Chromium - 高效:通过WEB技术写UI - 强大且通用 - 兼容性强 引入了chromium,可以简单的理解Electron应用其实就是一个简版的chromium浏览器应用。那么浏览器能做什么,它也就能做什么了。所以用Electron开发出来的桌面应用就可以有非常高的颜值了。
chromium是多进程架构,引入两个概念:主进程和渲染进程,Electron里头的主进程和渲染进程也是由此得到的。
2.2.3.1 主进程 就是用来创建窗口、创建顶部菜单、右键菜单等。一个应用只有一个主进程。(Browser)
2.2.3.2 渲染进程 每个具体的窗口页面,就是一个渲染进程(Render),一个应用可以有多个渲染进程的。
1 背景 前面三篇已经完成通过Electron搭建的最简单的HelloWorld应用了,虽然这个应用还没添加任何实质的功能,但是用来作为打包的案例,足矣。下面再分享下通过Electron-forge来将应用打包成安装包。
2 依赖 在Electron[2] Electron使用准备里头,我们已经安装好了Electron-forge,不懂的请点击下面的连接跳转。
Electron[2] Electron使用准备https://weilintao.blog.csdn.net/article/details/134227423?spm=1001.2014.3001.5502在开始打包之前,请再次检查package.json里头是否有如下命令:
"package": "electron-forge package", "make": "electron-forge make" 3 打包 3.1 预打包 控制台执行如下命令:
npm run package 命令执行日志:
PS C:\xysj\electron\my-electron-app> npm run package > my-electron-app@1.0.0 package > electron-forge package ✔ Checking your system ✔ Running generateAssets hook ✔ Running prePackage hook ✔ Packaging application ✔ Packaging for x64 on win32 [21s] ✔ Running postPackage hook 这个命令是模拟打包的,最终会在/out/目录下生成一个文件夹,里头有模拟生成的包应用,此时还不是安装包,但是通过这种方式可以看打包后的效果。 其中my-electron-app.exe就是应用入口文件,双击即可执行。
3.2 打安装包 npm run make 命令执行日志:
创建springboot项目 搭建最简单的SpringBoot项目-CSDN博客
引入mybatis和数据库依赖 <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.3.0</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.33</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.28</version> <scope>provided</scope> </dependency> </dependencies> 创建springboot配置文件 spring: datasource: url: jdbc:mysql://192.168.30.128:3306/wd username: root password: 4752 mybatis: mapper-locations: classpath:mapper/*Mapper.xml configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl 创建启动类 package com.wd; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class SpringbootMybatisApp { public static void main(String[] args) { SpringApplication.run(SpringbootMybatisApp.class, args); } } 创建数据库实体 package com.wd.pojo; import lombok.Data; import java.util.Date; @Data public class User { private int id; private String name; private String addr; private Date updateTime; } 创建Mapper package com.
创建springboot项目 搭建最简单的SpringBoot项目_Steven-Russell的博客-CSDN博客
引入jpa和数据库依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.33</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.28</version> <scope>provided</scope> </dependency> 创建实体类 @Data @Entity @Table(name = "tbl_user") public class User { @Id @Column @GeneratedValue private int id; @Column private String name; @Column private String addr; @UpdateTimestamp @Column private Date updateTime; } 创建Repository public interface UserRepository extends CrudRepository<User, Integer> { @Transactional @Modifying int deleteAllByNameIn(@Param(value = "nameList") List<String> nameList); } 创建controller 并且注入 事务管理器和Repository 注意:需要注入 PlatformTransactionManager
报错翻译:
未来警告: 由于 xlwt 软件包已不再维护,xlwt 引擎将在未来版本的 pandas 中移除。这是 pandas 中唯一支持写入 xls
格式文件的引擎。请安装 openpyxl 并改写为 xlsx 文件。你可以将io.excel.xls.writer选项设置为
“xlwt”,以消除此警告。虽然该选项已被弃用,而且也会引发警告,但可以全局设置该选项并抑制警告。
Y.to_excel(‘I:/stereo vision/cy.xls’)
报错原文:
F:\FFlie\paper learning\y.py:137: FutureWarning: As the xlwt package is no longer maintained, the xlwt engine will be removed in a future version of pandas. This is the only engine in pandas that supports writing in the xls format. Install openpyxl and write to an xlsx file instead. You can set the option io.
1.状态码:200
1)手写添加状态码
//添加一个状态码
tests[“验证状态码200”]=responseCode.code ===200
//添加多个状态码(添加多个状态时,必须是同一类,即不能同时添加200和304)
tests[“验证状态码200”]=responseCode.code ===200 || responseCode.code ===201
2)PostMan沙箱添加
//添加一个状态码(status Code :code is 200)
pm.test(“验证状态码: 200”, function () {
pm.response.to.have.status(200);
});
//添加多个状态码(status Code :successful Postman request)
pm.test(“验证状态码200”, function () {
pm.expect(pm.response.code).to.be.oneOf([200,201, 202]);
});
2.响应时间
1)手写添加响应时间
// 响应时间:小于多少
tests[“验证响应时间小于2s”]=responseTime < 2000;
//响应时间:在某范围内
tests[“验证响应时间在50ms~2000ms之间”]=_.inRange(responseTime,50,2000);
2)PostMan沙箱添加(response time is less than 200ms)
pm.test(“验证响应时间小于200ms”, function () {
pm.expect(pm.response.responseTime).to.be.below(200);
});
3.返回主体(Body)中包含某内容([1]返回主体信息一定要是raw中的原始信息;[2]存在*“转译”**的问题,如raw中"\u6b66\u6c49"代表"武汉",断言中要多添加一个“\”转义,即“\u6b66\u6c49”*
)
1)手写添加
tests[“验证主体断言包含:汇通”]=responseBody.has(“汇通”)
2)PostMan沙箱添加(response body :contains string)
pm.test(“验证body中包含:安心定期寿险B款”, function () {
问题(来源:leetcode300): 给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。
子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。
示例 1:
输入:nums = [10,9,2,5,3,7,101,18] 输出:4 解释:最长递增子序列是 [2,3,7,101],因此长度为 4 。 示例 2:
输入:nums = [0,1,0,3,2,3] 输出:4 举例说明:
从上述案例nums可以看出(1 2 4)或者(1 2 3)都可以是最长的一个答案,而我们只要求出他的长度即可。
方案一,暴力穷举: 暴力穷举往往是最简单也最容易想到的,通过一步步逐步筛选,逐步搜索进行穷举。将其通过循环逐步套取,把每个子序列都进行一遍搜索,完成答案的求解,取最长数列长度即可。
通过一个getLen函数进行最长子序列的求取,需要注意的是,当i取到序列的最后一位时,返回长度1,停止搜索,而当你本身被搜索时就是一个长度单位,所以每次搜索的maxlen初始长度为1。
时间复杂度:假定数组长度为n,即可生成2^n个子序列(数组中的每个数字可以选择取用或者不取用两个方式,n个长度,即可为2^n个),每个子序列都需要进行n次遍历,即为O(n),所以时间 复杂度为O(2^n)*O(n)。
#include <iostream> #include <algorithm> #include <cmath> #include <vector> #include <chrono> using namespace std; int getLen(vector<int> num, int i) { if (i == num.size() - 1) return 1; int maxlen = 1; for (int j = i + 1;j < num.
m_map绘制地形图时,虽然自带有1°的地形图以及从NOAA下载的1分的地形图(详见:Matlab下地形图绘图包m_map安装与使用),但有时需要对地形图分辨率的要求更高,便无法满足。
此时,需要导入本地地形数据文件,例如多波束测深。
这里以从https://www.ncei.noaa.gov/maps/grid-extract/下载的15秒地形数据为例,展示如何导入本地地形数据并绘图。
关键函数为m_shadedrelief。
1. 1分的分辨率地图 m_proj('mercator','long',[118 124],'lat',[20 24]); caxis([-6000 6000]) colormap(slanCM('terrain')) hc=colorbar; set(get(hc,'title'),'string','Elevation(m)') set(hc,'tickdir','out') m_etopo2('shadedrelief','lightangle',45,'gradient',5); m_gshhs('ic','color','k') m_grid('box','on','tickdir','out','gridlines','no') set(gcf,'position',[10 10 1200 800]) figname='test1' print('-dpng','-r1000',[figname,'.png']) % 导出png图片 结果如下:
2. 15秒的分辨率地图 load('scs_elevation.mat') elev=flipud(elev); lonlim=[extent(1:2)] latlim=[extent(3:4)] [nlat,nlon]=size(elev); Lon=[linspace(lonlim(1),lonlim(2),nlon)]; Lat=[linspace(latlim(1),latlim(2),nlat)]'; m_proj('mercator','long',[118 124],'lat',[20 24]); caxis([-6000 6000]) colormap(slanCM('terrain')) hc=colorbar; set(get(hc,'title'),'string','Elevation(m)') set(hc,'tickdir','out') m_shadedrelief(Lon,Lat,elev,'lightangle',45,'gradient',5) m_gshhs('ic','color','k') m_grid('box','on','tickdir','out','gridlines','no') set(gcf,'position',[10 10 1200 800]) figname='test2' print('-dpng','-r600',[figname,'.png']) % 导出png图片 可见15秒分辨率地图比1分地图能显示更多细节。 注:绘图色标参考自:https://blog.csdn.net/slandarer/article/details/127719784
目录 引言公式识别任务是什么?公式识别任务解决方案初探使用建议写在最后 引言 随着LaTeX-OCR模型转换问题的解决,公式识别任务中各个链条已经全部打通。小伙伴们可以放开膀子干了。
解决业界问题的方案,并不是单独训练一个模型就完事了,而是有着上下游的依赖。这就像工厂中流水线作业一样,一个小东西的生产是依赖无数个中间阶段才完成的。
一个模型应用到产品中,也是有着类似的流水线的。相比于工厂中流水线,这里的链条只是更加隐蔽一些而已。
公式识别任务是什么? 公式识别任务:指的是将图像中公式识别为对应的LaTeX写法,便于后续加工处理。
公式识别任务距离我们最近的应用场景便是论文写作。在我上大学写毕业论文时,由于当时并不知道LaTeX这种东西可以用来写公式,整个毕业论文公式都是在Word上用鼠标点出来的,好不痛苦。
比较推荐大家学一学LaTeX排版,绝对是提效利器,用过的人都说好。
动图来自LaTeX-OCR
公式识别任务解决方案初探 解决公式识别任务,我这里姑且粗略地分为四个部分:公式识别数据集处理、训练识别模型、转换识别模型和部署使用。
取之开源,回馈开源,一直是我们的准则。以上四部分具体地址如下,除训练识别模型为lukas-blecher外,其余均经由我整理。欢迎大家多多使用和提建议。
预处理公式库ProcessLaTeXFormulaTools: https://github.com/SWHL/ProcessLaTeXFormulaTools
训练识别模型库LaTeX-OCR: https://github.com/lukas-blecher/LaTeX-OCR
转换模型为ONNX格式库ConvertLaTeXOCRToONNX: https://github.com/SWHL/ConvertLaTeXOCRToONNX
部署使用库RapidLaTeXOCR: https://github.com/RapidAI/RapidLaTeXOCR
使用建议 先尝试RapidLaTeXOCR中识别模型识别效果,是否满足场景需求。
如果不满足,再考虑结合自身场景,将上述四部分走一遍,定制化自己的公式识别模型。
写在最后 本篇文章只是简单介绍,具体请移步文中各个部分的仓库下查看。
如有具体微调,部署等需求,欢迎后台详细咨询。
缺省Debian安装能用的编辑工具是nano,快捷键功能:
nano编辑器被设计为模拟UW Pico文本编辑器的功能和易用性。编辑器有四个主要部分。顶部的行显示程序版本、当前正在编辑的文件名以及文件是否已被修改。接下来是显示正在编辑文件的主要编辑窗口。状态行位于底部第三行,并显示重要消息。底部两行显示编辑器中最常用的快捷键。
快捷键的写法如下:控制键序列以“^”符号标记,可以通过使用Ctrl键或按两次Esc键输入。元键序列以“M-”标记,可以根据您的键盘设置使用Alt、Cmd或Esc键输入。此外,按两次Esc键并输入一个三位十进制数(从000到255)将输入对应值的字符。以下是在主编辑窗口中可用的按键。替代键在括号中显示:
^G (F1) 显示此帮助文本
^X (F2) 关闭当前缓冲区/从nano退出
^O (F3) 将当前缓冲区(或标记区域)写入磁盘
^R (Ins) 将另一个文件插入到当前缓冲区(或新缓冲区)
^W (F6) 向前搜索字符串或正则表达式
^\ (M-R) 替换字符串或正则表达式
^K (F9) 剪切当前行(或标记区域)并将其存储在剪贴板中
^U (F10) 从剪贴板中恢复到当前行
^J (F4) 整理当前段落
^T (F12) 调用拼写检查器(如果可用)
^C (F11) 显示光标的位置
^_ (M-G) 转到行和列号
M-U 撤消上一次操作
M-E 重做上一次未操作的操作
M-A (^6) 从光标位置开始标记文本
M-6 (M-^) 复制当前行(或标记区域)并将其存储在剪贴板中
M-] 跳到匹配的括号
^Q 向后搜索字符串或正则表达式
M-Q (M-▲)向后搜索下一个出现
M-W (M-▼)向前搜索下一个出现
^B (◀)向后移动一个字符
^F (▶)向前移动一个字符
^◀ (M-空格)向后移动一个单词
^▶ (^空格)向前移动一个单词
^A (Home)移动到当前行的开头
^E (End)移动到当前行的末尾
官网指引,生成accesstoken,下载相关依赖请翻阅[https://blog.csdn.net/weixin_44402694/article/details/125414381?spm=1001.2014.3001.5501](https://blog.csdn.net/weixin_44402694/article/details/125414381?spm=1001.2014.3001.5501)
本文使用官网accesstoken,请自行生成私人token
底图切换 - mapbox切换高德、天地图、bingmap等底图
效果 ## 代码实现 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>05、底图切换 - 高德|天地图|bingmap|mapbox</title> <link href="https://api.mapbox.com/mapbox-gl-js/v2.7.0/mapbox-gl.css" rel="stylesheet" /> <script src="https://api.mapbox.com/mapbox-gl-js/v2.7.0/mapbox-gl.js"></script> <style> * { padding: 0; margin: 0; list-style: none; text-decoration: none; } html, body { width: 100%; height: 100%; } #map { width: 100%; height: 100%; } .btn-list { position: fixed; top: 100px; left: 100px; } </style> </head> <body> <div id="
在matlab下的m_map可以绘制地形图。那么,如何在m_map添加卫星遥感图片呢?这需要使用m_image函数。
基本语法为:
m_image(lonlim,latlim,c) 其中lonlim和latlim是这个图像地理坐标(经纬度)的边界,是一个长度为2的数组。c是图像数组,大小为mn3,其中m,n表示图像的行列数,3表示RGB参数。
现在有以下图像,来自MODIS的Aqua传感器,拍摄时间为2011-08-01,位置为73-77°N,174-156°W。位置大致为北冰洋楚科奇海域。其中:蓝色为海冰,白色为云层,黑色为海水。
figname='snapshot-2011-08-04-map'; figfile='snapshot-2011-08-04.png'; % 读取遥感图像数据 figdata=imread(figfile); % 显示遥感图像 figure imshow(figdata) figure % 使用lambert投影,图框经纬度范围为180-150°W,70-78°N m_proj('lambert','long',[-180 -150],'lat',[70 78]); hold on % 插入遥感图,注意遥感图的纬度顺序要颠倒 m_image([-174 -156],[77 73],figdata),hold on % 填充陆地 m_gshhs('ic','patch',[1 1 1]*0.5) m_grid('box','fancy','tickdir','out') print('-dpng','-r1000',[figname,'.png']) % 导出png图片 图像如下:
如果只显示遥感图像,即图窗范围=遥感图像范围: figname='snapshot-2011-08-04-map'; figfile='snapshot-2011-08-04.png'; % 读取遥感图像数据 figdata=imread(figfile); % 显示遥感图像 figure imshow(figdata) figure % 使用lambert投影,图框经纬度范围为174-156°W,73-77°N m_proj('lambert','long',[-174 -156],'lat',[73 77]); hold on % 插入遥感图,注意遥感图的纬度顺序要颠倒 m_image([-174 -156],[77 73],figdata),hold on % 填充陆地 m_gshhs('ic','patch',[1 1 1]*0.5) m_grid('box','fancy','tickdir','out') print('-dpng','-r1000',[figname,'.png']) % 导出png图片 图像如下:
原本样式 代码 option = { tooltip: {}, legend: {}, xAxis: { data: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"] }, yAxis: {}, series: [{ name: "Sale", type: "bar", data: [5, 20, 36, 10, 10, 20, 4] }] } 全体设置圆角 官方文档说上可以利用series-bar.itemStyle. borderRadius来给全体设置圆角
效果 代码 option = { tooltip: {}, legend: {}, xAxis: { data: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"] }, yAxis: {}, series: [{ name: "Sale", type: "bar", data: [5, 20, 36, 10, 10, 20, 4], itemStyle: { // borderRadius: 10, // 统一设置四个角的圆角大小 borderRadius: [10, 10, 0, 0] //(顺时针左上,右上,右下,左下) } }] } 单独设置圆角 我们通过查阅官方文档发现可以通过 series-bar.
最近需要重新安装虚拟机的系统
安装之后发现对方提供的root密码不对,无法进入系统。
上网搜了下发现可以进入单用户模式进行密码修改从而重置root用户密码。
在这个界面下按e键
找到图中部分,把标红的部分删除掉,然后写上rw init=/bin/sh
改完之后按ctrl+x,进入命令行模式
在这里输入passwd root重新设置你需要的root密码
在输入touch /.autorelabel
然后exit重启就可以用新的root密码进入系统了
开发平台包括:Win11、VS2022、WLS2。
当vs2022对应用程序报编译错误时,有时也会报以下信息:
但应用程序没有编译错误后,上述信息不再出现。
在VS2019或VS2022中,可看到如下错误列表:
如果复制这两行错误信息:
然后把它粘贴到word文件,就可以看到以下表格:
严重性
代码
说明
项目
文件
行
禁止显示状态
错误(活动)
E0020
未定义标识符 "dd"
try_c
E:\try_vs2019\try_c\try_c_main.cpp
15
错误
C2065
“dd”: 未声明的标识符
try_c
E:\try_vs2019\try_c\try_c_main.cpp
15
Industrial Accident Causal Analysis 1 项目概况2 模块库导入3 加载数据集4 数据预处理4.1 时间特征提取4.2 季节变量提取4.3 NLP预处理4.4 情感得分 5 EDA5.1 单变量分析5.1.1 国家特征5.1.2 城市特征5.1.3 行业特征5.1.4 事故等级5.1.5 性别特征5.1.6 用工形式5.1.7 关键风险5.1.8 时间特征 5.2 多变量分析5.2.1 国家与行业5.2.2 用工形式和性别5.2.3 性别与行业5.2.4 事故等级与性别5.2.5 用工形式和事故等级5.2.6 事故类别与月份5.2.7 周与事故等级5.2.8 季节与事故等级 6 NLP分析6.1 单-gram6.2 双-gram6.3 三-gram6.4 性别与N-gram6.5 事故等级与N-gram6.6 行业与N-gram6.7 用工类型与N-gram6.8 词云图6.9 情感趋势 7 数据建模7.1 特征工程7.2 模型1自变量x和因变量y指定,并进行数据集划分模型参数设置和模型训练绘制重要特征图绘制决策树图 7.3 模型2 8 结论 1 项目概况 项目详情
在该数据集中,巴西公司 IHM Stefanini 提供了 3 个国家 12 家制造工厂的事故信息。我们需要利用这个数据集来了解事故发生的原因,并发现减少事故悲剧的线索。
数据集列如下:
日期(Date):时间戳或时间/日期信息国家(Countries):事故发生在哪个国家(匿名)当地(Local):生产工厂所在城市(匿名)行业(Industry sector):工厂所属的行业事故等级(Accident level):从 I 到 VI,记录事故的严重程度(I 表示不严重,VI 表示非常严重)潜在事故等级(Potential Accident level):根据事故等级,数据库还记录了事故可能的严重程度(由于事故涉及的其他因素)性别(Genre):如果受伤者是男性或女性雇员或第三方(Employee or Third Party):受伤者是雇员还是第三方关键风险(Critical Risk):对事故所涉风险的一些描述描述(Descrition): 详细描述事故是如何发生的
文章目录 相关资料 优化算法梯度下降学习率牛顿法 随机梯度下降小批量随机梯度下降动量法动量法解决上述问题 AdaGrad 算法RMSProp算法Adam学习率调度器余弦学习率调度预热 相关资料 李沐 动手学深度学习
优化算法 优化算法使我们能够继续更新模型参数,并使损失函数的值最小化。优化算法的性能直接影响模型的训练效率。
优化问题中大多数目标函数都很复杂,没有解析解。相反,必须使用数值优化算法。
优化与深度学习之间的关系 优化和深度学习的目标是根本不同的。前者关注的是最小化目标,后者则关注在给定有限数量的情况下寻找合适的模型。训练误差和泛化误差通常不同:由于优化算法的目标函数通常是基于训练数据集的损失函数,因此优化的目标是减少训练误差。但是,深度学习(或更广义地说,统计推断)的目标是减少泛化误差。为了实现后者,除了使用优化算法来减少训练误差之外,我们还需要注意过拟合。 深度学习中使用优化的挑战 这里关注局部最小值、鞍点和梯度消失 鞍点:saddle point, 函数的所有梯度都消失但不是全局最小值也不是局部最小值的任何位置。较高维度的鞍点可能会更加隐蔽。
梯度消失。假设我们想最小化函数 f ( x ) = t a n h ( x ) f(x) = tanh(x) f(x)=tanh(x)
,然后我们恰好从 x=4 开始。正如我们所看到的那样,f 的梯度接近零。更具体地说, f ′ ( x ) = 1 − t a n h 2 ( x ) f^{'}(x) = 1 - tanh^2(x) f′(x)=1−tanh2(x),因此 f ′ ( 4 ) = 0.0013 f^{'}(4) = 0.
Redis学习笔记 Redis官网:https://redis.io/
Redis教程:♥Redis教程 - Redis知识体系详解♥ | Java 全栈知识体系 (pdai.tech)
Redis视频教程:https://www.bilibili.com/video/BV1cr4y1671t
Redis基础 Redis通用命令 在命令行显示所有的通用命令 127.0.0.1:6379> help @generic COPY source destination [DB destination-db] [REPLACE] summary: Copy a key since: 6.2.0 DEL key [key ...] summary: Delete a key since: 1.0.0 DUMP key summary: Return a serialized version of the value stored at the specified key. since: 2.6.0 EXISTS key [key ...] summary: Determine if a key exists since: 1.0.0 EXPIRE key seconds [NX|XX|GT|LT] summary: Set a key's time to live in seconds since: 1.
欢迎大家回到《Java教程之Spring30天快速入门》,本教程所有示例均基于Maven实现,如果您对Maven还很陌生,请移步本人的博文《如何在windows11下安装Maven并配置以及 IDEA配置Maven环境》,本文的上一篇为《利用 AOP通知获取数据代码实例》
通过本简称的第11节到14节,AOP的知识就已经讲解完了,接下来对于AOP的知识进行一个总结:
1 AOP的核心概念 概念:AOP(Aspect Oriented Programming)面向切面编程,一种编程范式作用:在不惊动原始设计的基础上为方法进行功能增强核心概念 代理(Proxy):SpringAOP的核心本质是采用代理模式实现的连接点(JoinPoint):在SpringAOP中,理解为任意方法的执行切入点(Pointcut):匹配连接点的式子,也是具有共性功能的方法描述通知(Advice):若干个方法的共性功能,在切入点处执行,最终体现为一个方法切面(Aspect):描述通知与切入点的对应关系目标对象(Target):被代理的原始对象成为目标对象 2 切入点表达式 切入点表达式标准格式:动作关键字(访问修饰符 返回值 包名.类/接口名.方法名(参数)异常名)
execution(* com.itheima.service.*Service.*(..)) 切入点表达式描述通配符: 作用:用于快速描述,范围描述*:匹配任意符号(常用)… :匹配多个连续的任意符号(常用)+:匹配子类类型 切入点表达式书写技巧 1.按标准规范开发2.查询操作的返回值建议使用*匹配3.减少使用…的形式描述包4.对接口进行描述,使用表示模块名,例如UserService的匹配描述为Service5.方法名书写保留动词,例如get,使用*表示名词,例如getById匹配描述为getBy*6.参数根据实际情况灵活调整 3 五种通知类型 前置通知后置通知环绕通知(重点) 环绕通知依赖形参ProceedingJoinPoint才能实现对原始方法的调用环绕通知可以隔离原始方法的调用执行环绕通知返回值设置为Object类型环绕通知中可以对原始方法调用过程中出现的异常进行处理 返回后通知抛出异常后通知 4 通知中获取参数 获取切入点方法的参数,所有的通知类型都可以获取参数
JoinPoint:适用于前置、后置、返回后、抛出异常后通知ProceedingJoinPoint:适用于环绕通知 获取切入点方法返回值,前置和抛出异常后通知是没有返回值,后置通知可有可无,所以不做研究
返回后通知环绕通知 获取切入点方法运行异常信息,前置和返回后通知是不会有,后置通知可有可无,所以不做研究
抛出异常后通知环绕通知 AOP的相关知识我们已经讲解完了,从下一节开始,我们开始讲解AOP的事务管理。
在word表格里填内容,但上方横线是空白
原因:表格的边框格式设置不正确,表格轮廓线没有画出来,改成【边框】→【所有框线】即可