使用Tableau做数据分析的一些思考

文章目录 使用Tableau做数据分析的一些思考问题分析Tableau使用技巧 使用Tableau做数据分析的一些思考 参考: Tableau数据分析训练营之LOD专题 15 大详细级别表达式 对于Tableau数据分析有两句话非常重要: 分析即聚合。维度是聚合依据。 问题分析 需要理解复杂问题的层级关系,通常与当前层级有:向上/向下,两种关系 向下的层级问题,需要用fixed固定层级关系,也可以使用INCLUDE向上的层级问题,有三种方法: 表计算:window_sum/total 建议使用,因为表计算是计算展示出来的数据,计算速度比较快fixed:直接指定需要计算的层级exclude:排除当前视图的层级,排除之后就根据更高级一级的维度聚合。 exclude:是按照排除指定层级之后,最小层级聚合的,比如说有三个层级,A、B、C,将B层级排除之后,将按照C层级进行聚合。 例如: 简单的问题是可以直接从明细表中将维度提取出来,比如说每个国家的销量,每个国家就可以直接从明细表中group by出来。复杂问题是引用了其他聚合的结果作为维度。比如说销售量1、2...N的客户数,这里的1、2...N,无法直接从明细表中提取出来,需要先进行聚合,将聚合的结果作为维度(一般使用Fixed),再一步的聚合。 那么遇到复杂问题该怎么办呢? 首先应该做的是问题分析。将问题拆解为三个内容: 问题范围问题描述(维度)问题答案(度量) 例如问题: 有多少客户购买了1次、2次、3次…N次订单? 现在看一下这个问题的描述,思考三个问题,问题的范围是什么?问题描述是什么?问题的答案又是什么? 问题范围:可以看到,该问题没有设定范围,也就是所有数据。 问题描述(维度):它需要的是,购买了1次、2次、3次....N次订单的XXX,所以它的维度是不同频次。 问题答案(度量):它最后需要什么,多少客户,因此客户数量就是它的结果。 综上,将问题转换为标准问题结果:(no filter),不同购买频次的客户数量? 将问题转换为标准问题之后,就根据维度,度量,范围,做一定的数据分析。 遇到问题最主要的是能够分解问题,主要是对于问题维度的思考,适合这个问题的维度。 Tableau使用技巧 对于表的计算,window_sum,在使用目前视图中已经有的数据很有效。比如使用IIF判断得到的数据,若想要都进行赋值,可以使用window_sum,来计算。对于赋予想要筛选的值/不确定的值,可以将这个字段转换为参数,之后在公式中使用这个参数,就可以根据这个参数进行筛选了。在tableau中,交互条件也可以进行设置,设置交互条件之后,点击某个值,可以修改参数的值。对于sum和相减,建议先sum再相减,若先相减再sum,性能会较差SUM(IIF({INCLUDE [Product]:SUM([Profit])-SUM([Target Profit])}>0,1,0)) 可以判断LOD的结果,它与SUM({INCLUDE [Product]:IIF(SUM([Profit])-SUM([Target Profit])>0,1,0)})结果相同 先从熟悉的层次开始,从交叉表开始,最后转换为图形。 对于综合问题的层次、筛选的影响,合理的选择计算。 FIXED是绝对的引用,不收视图的影响INCLUDE是相对的引用,通常用于更低层次的聚合。INCLUDE为空,相当于当前视图完成聚合,并可以根据当前视图的变换而变化。同理,EXCLUED为空,也是基于当前视图完场聚合。 表计算是聚合的聚合,而LOD是在指定层级的聚合。 表计算,可以进行辅助计算,设定辅助计算的维度,以及计算的方法。 在实际业务中,关于周的数据需要多一点考虑,例如日期虽然同步了,但是每周的数量不一致。这是在实际业务中需要注意的地方。 将筛选器添加到上下文,会将筛选的优先级提高到最高,例如字段中有fixed,默认筛选器在fixed优先级之后,所以筛选之后不会影响fixed的计算结果。将筛选器添加到上下文之后,筛选器的优先级会高于fixed,筛选之后的结果会影响fixed的计算结果。有一种特殊情况,当筛选器的对象和fixed定义的层级是一一对应的,这时是否将筛选器添加到上下文,对fixed的计算都没有影响了。 tableau中集合的运用是,可以理解成多个参数,在一个仪表盘中,可以创建一个操作,用来更新集合的值。 默认的窗口函数的累加是从头开始累加的。WINDOW_SUM(COUNTD([Customer ID]),0,LAST()),注意后面两个参数,可以实现从后往前加,利用的类似与sql中的窗口函数,将末尾固定,每次累计当前行到最后一行。

JS 合并数组的三大方式

数组是表示索引项的有序集合的数据结构。 对多个数组执行的一个常见操作是合并——将2个或多个数组合并成包含合并数组的所有项的更大数组。 例如,有两个数组[1,2]和[5,6],然后合并这些数组得到[1,2,5,6]。 在这篇文章中,你会发现在JavaScript中合并数组的3种方法:2种不可变的(合并后创建一个新数组)和1种可变的(合并到一个数组中)。 1. 数组的不可变合并 1.1使用扩展操作符进行合并 如果您想知道一种在JavaScript中合并数组的好方法,那么请记住使用扩展操作符进行合并。 在数组字面量中写入两个或更多带有扩展操作符…前缀的数组,JavaScript将创建一个合并所有这些数组的新数组: const mergeResult = [...array1, ...array2]; 例如,让我们合并两个数组heroes和villains: const heroes = ['Batman', 'Superman']; const villains = ['Joker', 'Bane']; const all = [...heroes, ...villains]; console.info(all); // ['Batman', 'Superman', 'Joker', 'Bane'] const all = [...heros, ...villains] 创建一个合并了heroes和villains数组的新数组。 数组字面量中合并数组的顺序很重要:合并数组中的项按照数组在字面量中出现的顺序插入。 例如,让我们在合并的数组中把villains列表放在heroes列表之前: const heroes = ['Batman', 'Superman']; const villains = ['Joker', 'Bane']; const all = [...villains, ...heroes]; all; // ['Joker', 'Bane', 'Batman', 'Superman'] 扩展操作符方法允许同时合并2个甚至更多数组: const mergeResult = [.

「前端进阶」高性能渲染十万条数据(虚拟列表)

为什么需要使用虚拟列表? 参考:https://github.com/chenqf/vue-virtual-listview 假设我们的长列表需要展示10000条记录,我们同时将10000条记录渲染到页面中,先来看看需要花费多长时间: <button id="button">button</button><br> <ul id="container"></ul> document.getElementById('button').addEventListener('click', function () { let now = Date.now(); const total = 10000; let ul = document.getElementById('container'); for (let i = 0; i < total; i++) { let li = document.createElement('li'); li.innerText = i ul.appendChild(li); } console.log('JS运行时间:', Date.now() - now); setTimeout(() => { console.log('总运行时间:', Date.now() - now); }, 0) //JS运行时间: 38 //总运行时间: 957 }) 当我们点击按钮,会同时向页面中加入一万条记录,通过控制台的输出,我们可以粗略的统计到,JS的运行时间为38ms,但渲染完成后的总时间为957ms。 简单说明一下,为何两次console.log的结果时间差异巨大,并且是如何简单来统计JS运行时间和总渲染时间: 在 JS 的Event Loop中,当JS引擎所管理的执行栈中的事件以及所有微任务事件全部执行完后,才会触发渲染线程对页面进行渲染第一个console.log的触发时间是在页面进行渲染之前,此时得到的间隔时间为JS运行所需要的时间第二个console.log是放到 setTimeout 中的,它的触发时间是在渲染完成,在下一次Event Loop中执行。 在实际的工作中,列表项不会像例子中仅仅只由一个li标签组成,必然是由复杂DOM节点组成的。那么可以想象的是,当列表项数过多并且列表项结构复杂的时候,同时渲染时,会在Recalculate Style和Layout阶段消耗大量的时间。

Opencv4.0学习记录(opencv4.0+vs2015环境配置)

1.下载软件 (1) 首先需要将vs2015软件下载(微信公众号可以下载,大家自行下载)。 (2)下载opencv4.0 ①直接跳到官网Home - OpenCV下载; ②这样下载比较慢。可以去百度网盘下载;链接:https://pan.baidu.com/s/1yBJ--sKqNMRLMqruM65WXg 提取码:o0r4 2.软件安装 直接安装就行,记住安装路径,一会配置的时候回用到,建议安装到根目录。安装到E盘,会自动 建一个新的文件夹opencv。我的安装路径为: E:\opencv 3.环境配置 配置环境变量 【此电脑】——> 【(右键)属性】——> 【高级系统设置】——> 【高级】——> 【环境变量】——>(双击)系统变量中的 PATH ——> 在变量值里面新建相应路径。并将 ① E:\opencv\build\x64\vc14\bin ② E:\opencv\build\x64\vc14\lib 这两个路径添加到PATH中,保存并退出。 需要新建一个项目 配置环境 我这里配置的是Release x64,配置Debug x64同理。在项目内选择属性,进行环境的配置,包括在VC++目录中的包含目录中添加路径:D:\Opencv\opencv\build\include 和E:\opencv\build\include\opencv2。 在VC++目录中的库目录中添加路径:E:\opencv\build\x64\vc14\lib; 注意vc14代表vs2015.vc15代表vs2017 右键点击属性就可以跳转到下一个界面 在链接器-->输入--> 附加依赖项中添加:opencv_world400.lib;opencv_world400d.lib 然后点击确定。 这样我们配置环境的工作到此就结束啦。 4.测试代码 #include<opencv2/opencv.hpp> #include<iostream> using namespace std; using namespace cv; int main() { Mat src = imread("E:/images/011.jpg", IMREAD_GRAYSCALE);//读取进来的数据以矩阵的形势,第二个参数代表显示一张灰度图像。 if (src.empty()) { printf("could not load image");//如果图片不存在 将无法读取,打印到终端。 } //超过屏幕的图像无法显示时候调用此函数。 namedWindow("输入窗口", WINDOW_FREERATIO);//创建了一个新窗口,参数1表示名称,第二个参数代表一个自由的比例 imshow("

Java计算两个文件中重复的文字,报告共同字数并计算百分比

示例程序中使用到的文件如下: 示例程序: package Array_list_study; import java.io.*; import java.util.*; public class Vocabulary_compare { public static void main(String[] args) throws FileNotFoundException{ Scanner console = new Scanner(System.in); giveIntro(); System.out.print("file #1 name?"); // poem1 Scanner in1 = new Scanner(new File(console.nextLine())); System.out.print("file #2 name?"); // poem2 Scanner in2 = new Scanner(new File(console.nextLine())); System.out.println(); ArrayList<String> list1 = getWords(in1); ArrayList<String> list2 = getWords(in2); ArrayList<String> common = getOverlap(list1,list2); reportResults(list1,list2,common); } // 读取单词,转换为小写,返回唯一单词的排序列表 public static ArrayList<String> getWords(Scanner input){ // 忽略除字母和撇号以外的所有字符 input.

File类、I/O流(输入Input/输出Output)的详解及代码实现

I/O流(Input输入/Output输出流) 流的概述 流是一种抽象概念,它代表了数据的无结构化传递。按照流的方式进行输入输出,数据被当成无结构的字节序或字符序列。从流中取得数据的操作称为提取操作,而向流中添加数据的操作称为插入操作。用来进行输入输出操作的流就称为IO流。换句话说,IO流就是以流的方式进行输入输出。 Java由数据流处理输入/输出模式,程序从指向源的输入流中读取源中的数据。源可以是文件、网络、压缩包或其他数据源。 输出流的指向是数据要到达的目的地,程序通过向输出流中写入数据吧信息传递到目的地。输出流的目标可以说文件、网络、压缩包、控制台和其他数据输出目标 Java中四大抽象类 Java语言定义了许多类专门负责各种方式的输入/输出,这些类都被放在java.io包中。其中,所有输入流都是抽象类InputStream(字节输入流)或抽象类Reader(字符输入流)的子类;而所有输出流都是抽象类Output(字节输出流)或抽象类Writer(字符输出流)的子类。 输入流 数据从数据源到程序。 InputStream类是字节输入流的抽象类(不可以被实例化),是所有字节流的父亲。 该类中所有方法遇到错误时都会引发IOException异常。下面是对该类中的一些方法简要说明: 方法 概述 read() 从输入流中读取数据的下一个字节,返回0~255范围内的int字节值。如果因为已经到达流末而没有可用的字节则返回值为-1 read(byte[] b) 从输入流中读入一定长度的字节。并以证书的形式返回字节数 mark(int readlimit) 在输入流的当前位置放置一个标记,readlimit参数告知此输入流在标记位置失效之前允许读取的字节数 reset() 将输入指针返回到当前所做的标记处 skip(long n) 跳过输入流上的n个字节兵返回实际跳过的字节数 markSupported() 如果当前流支持mark()/reset()操作koi返回true close 关闭此输入流兵释放与该流关联的所有系统资源 3.1 、IO流FileInputStream实例如下: 3.2 使用while 进行IO输入流 3.3 进行转化操作 File类的使用File类的常用方法 方法 返回值 说明 getName() String 获取文件的名称 canRead() boolean 判断文件是否为可读的 canWrite() boolean 判断文件是否为可写入 exits() boolean 判断文件是否存在 length() long 获取文件的长度(以字节为单位) getAbsolutePath() String 获取文件的绝对路径 getParent() String 获取文件的父路径 isFile() boolean 判断文件是否存在 isDirectory() boolean 判断文件是否为一个目录 isHidden()

MDK中编译报错 Error: L6218E: Undefined symbol SystemInit (referred from startup_cmsdk_cm0.o).

情况一 缺失main与SystemInit定义程序 在MDK中编译从ARM官网下载下来的Cortex-M0的启动文件startup_CMDK_cm0.s出现以下报错 .\code.axf: Error: L6218E: Undefined symbol SystemInit (referred from startup_cmsdk_cm0.o). .\code.axf: Error: L6218E: Undefined symbol main (referred from __rtentry2.o). 这里大概意思是由于在启动文件中调用了SystemInit子程序和main程序,但是没有定义这两个函数,所以无法编译通过。 这里我们需要写个C程序,定义一下这两个函数,通过File->New建立空白文件,Ctrl+S保存为main.c的C程序。在里面写入以下程序,定义main和SystemInit即可。 int main(void) { } void SystemInit(void) { } 完了一定要把自己写的这段程序main.c加入当前工程中,如下图,否者编译还会出现之前的报错信息。 重新编译,编译通过。 情况二 缺失SystemInit定义 方法1 还有很多人写了主函数main的定义,但是没有定义函数SystemInit,然后编译后会出现下面这种报错。 其实,换汤不换药,参照前面的操作在main.c中加入SystemInit的定义即可,或者重新写个SystemInit.c定义一下SystemInit即可。 重新编译通过。 方法2 对于缺失SystemInit的定义而导致的报错,还有这种方法:既然你因为调用这个SystemInit函数而报错,那么我不调用不就行了。 如果学过汇编的话,可以查看启动汇编代码startup_CMDK_cm0.s中复位中断部分程序Reset_Handler,在这里引用了SystemInit子程序(IMPORT SystemInit),并且执行伪指令LDR R0, =SystemInit将SysteInit的入口地址赋给寄存器R0,然后通过跳转指令BLX R0跳转至寄存器R0存储地址所对应的子程序,执行该子程序。 这样的话只需要将这三行注释掉(注释符号为;),重新编译,编译通过。 注:以上仅为个人学习过程解决问题的过程,如果能解决您的问题,可以点个赞,如果无法解决您的问题,可以评论区友善交流学习哦。

python 中的最大堆和最小堆(heapq库)

目录 首先来看一下什么是最大堆和最小堆? python heapq库中的一些常用方法 小试牛刀 首先来看一下什么是最大堆和最小堆? 最大堆:一种经过排序的完全二叉树,其中任意非终端节点数值均不小于其左子节点和右子节点的值。如果一颗二叉树满足最小堆的要求,那么,堆顶(根节点)也就是整个序列的最大元素。 最小堆:也是一种经过排序的完全二叉树,其中任意非终端节点数值均不大于其左子节点和右子节点的值。如果一棵二叉树满足最小堆的要求,那么,堆顶(根节点)也就是整个序列的最小元素。 python heapq库中的一些常用方法 注意:python中的heapq库只有最小堆,没有最大堆,当使用最大堆时,可以在插入元素时将元素取反,弹出是也取反,一些常用操作如下: import heapq # [2,0,4,1] # 1.创建堆 # 方法一:定义一个空列表,然后使用heapq.heqppush(item)函数把元素加入到堆中 item = 2 heap = [] heapq.heappush(heap,item) # 方法二:使用heapq.heapify(list)将列表转换为堆结构 heap = [2,0,4,1] heapq.heapify(heap) # 2.heapq.heappush() 添加新元素 num num = 3 heapq.heappush(heap,num) # 3.heapq.heappop() 删除并返回堆顶元素 heapq.heappop(heap) # 4.heapq.heappushpop() 比较添加元素num与堆顶元素的大小:如果num>堆顶元素,删除并返回堆顶元素,然后添加新元素num;如果num<堆顶元素,返回num,原堆不变 # 其实也就等价于 添加新元素num,然后删除并返回堆顶元素 num = 0 heapq.heappushpop(heap,num) # 5.heapq.heapreplace() 删除并返回堆顶元素,然后添加新元素num num = 5 heapq.heapreplace(heap,num) # 6. heapq.merge() 合并多个排序后的序列成一个排序后的序列, 返回排序后的值的迭代器。 heap1 = [1,3,5,7] heap2 = [2,4,6,8] heap = heapq.

python-输出中间字符

Python之禅,体现了Python这门语言的设计哲学,其中的很多观点对于日常的编程也是很有指导意义的。Python之禅中有这样一段话: “优美胜于丑陋,明了胜于晦涩,简洁胜于复杂,复杂胜于凌乱,扁平胜于嵌套,间隔胜于紧凑,可读性很重要。” 请编程输出这段话中间从m到n的字符串。 输入格式: 2行输入 每行输入一个小于50的非负整数,且保证后面的数字大于前面的数字。 输出格式: 从m到n的字符串 输入样例: 在这里给出一组输入。例如: 0 6 输出样例: 在这里给出相应的输出。例如: 优美胜于丑陋 m=int(input()) n=int(input()) a=str("优美胜于丑陋,明了胜于晦涩,简洁胜于复杂,复杂胜于凌乱,扁平胜于嵌套,间隔胜于紧凑,可读性很重要。") print(a[m:n]) 

引入ResNet模型来训练自己的数据集

我们在做科研时,常常需要做实验。为此,参考了网上很多的教程,综合各自的写下以下内容。一方面为自己留点笔记,日后好学习。另一方面为各位朋友提供一定的参考。 以卷积神经网络的resnet网络模型为例,简要的说明如何引入模型或者修改模型来做实验。 1、引入模型 model_ft = models.resnet50(pretrained=True) model_ft = model_ft.to(device) 这里只是引入模型,没有做任何修改。原模型中类别数为1000,因此我们在训练自己的数据集时,需要修改种类数。 2、修改自己数据集的类别 model_ft = models.resnet50(pretrained=True) num_ftrs = model_ft.fc.in_features model_ft.fc = nn.Linear(num_ftrs, n) # 这里的n为类别数 model_ft = model_ft.to(device) 3、如果修改resnet的网络结构,比如加入注意力机制 model_ft = models.resnet50(pretrained=False) net_dict = model_ft.state_dict() predict_model = torch.load('resnet50-5c106cde.pth') # 寻找网络中公共层,并保留预训练参数 state_dict = {k: v for k, v in predict_model.items() if k in net_dict.keys()} net_dict.update(state_dict) # 将预训练参数更新到新的网络层 model_ft.load_state_dict(net_dict) # 修改最后一层全连接层的数量,改为分类种类的数量 num_ftrs = model_ft.fc.in_features model_ft.fc = nn.Linear(num_ftrs, n) model_ft = model_ft.to(device) 4、再附上resnet其它的模型结构 import torch import torch.

MDK编译报错Error: L6218E: Undefined symbol main (referred from __rtentry2.o)

@[TOC](MDK编译报错Error: L6218E: Undefined symbol main (referred from __rtentry2.o).) 在编译Cortex-M0的启动文件startup_CMDK_cm0.s时出现报错信息Error: L6218E: Undefined symbol main (referred from __rtentry2.o) 这里是由于在工程中缺少主函数的声明所导致的 点击file->new 然后输入以下程序,对main函数进行声明即可 int main(void) { } 然后快捷键Ctrl+S保存,保存为main.c,然后通过程序分组管理将刚刚编写的主函数main.c加入到当前工程下 最后,重新编译,编译通过。 注:这里仅仅是个人学习过程解决问题的记录,如果无法解决您的问题,欢迎评论区友好交流学习。

Depthwise 卷积 ,Pointwise 卷积与普通卷积的区别

1 普通卷积 原理:普通卷积是,一个卷积核与input的所有通道都进行卷积,然后不同通道相同位置卷积后的结果再相加,如下图所示,:⾸先,每个通道内对应位置元素相乘再相加,最后计算所有通道的总和作为最终结果。卷积核的Channel通道数等于Input输⼊的通道数,Output输出的通道数等于卷积核的个数。 2 Depthwise 卷积 原理:Depthwise 卷积的一个卷积核只负责一个通道,一个卷积核只与一个通道卷积。那么卷积核数需要与输入的通道数相等,输出的通道数也不变,等于输入的通道数,等于卷积核数。所以depthwise卷积只改变特征图的大小,不改变通道数。但这种运算对输入层的每个通道独立进行卷积运算,没有有效的利用不同通道在相同空间位置上的feature信息。 depthwise卷积,只改变feature map的大小,不改变通道数。 3 Pointwise卷积 Pointwise Convolution的运算与常规卷积运算相似,它的卷积核的尺寸为 1×1×M,M为上一层的通道数。所以这里的卷积运算会将上一步的map在深度方向上进行加权组合,生成新的Feature map。有几个卷积核就有几个输出Feature map。 Pointwise卷积,不改变feature map的大小,只改变通道数。 4 Depthwise separable convolution(深度可分离卷积) 深度可分离卷积depthwise separable convolution,由depthwise(DW)和pointwise(PW)结合起来组成。相比常规的卷积操作,其参数数量和运算成本比较低。轻量化模型中常用,例如MobileNet

Hackmyvm综合靶机 | Driftingblues-4

前言提要 ​ 4.7号晚,接收建议。 ​ 我是否太注重于打靶?更应该多了解了解常见的框架比如Spring、Apache等以及多积累相关经验,捋清楚自己的思绪。 ​ 后期的博客应该会多多更新常见CMS的相关知识,以及一些代码的编写…(把这系列靶机打完后,多更多设计其他知识不仅限于靶机wp) kali:192.168.132.139 靶机:192.168.132.172 信息收集 #先简单扫端口 nmap -p- 192.168.132.172 #再全面扫面 nmap -A -sV -p- -T4 192.168.132.172 开放端口21、22、80(常规想法:21和22端口日常爆破,去80端口的web页面进一步信息收集) 页面没东西,但是在源代码里面有一串密文 Z28gYmFjayBpbnRydWRlciEhISBkR2xuYUhRZ2MyVmpkWEpwZEhrZ1pISnBjSEJwYmlCaFUwSnZZak5DYkVsSWJIWmtVMlI1V2xOQ2FHSnBRbXhpV0VKellqTnNiRnBUUWsxTmJYZ3dWMjAxVjJGdFJYbGlTRlpoVFdwR2IxZHJUVEZOUjFaSlZWUXdQUT09 #四次解密后得到一个隐藏目录 /imfuckingmad.txt 去隐藏目录看一看又是一个奇怪的加密,寻找解密方式 http://www.dcode.fr/cipher-identifier 发现是 Brainfuck 解密,然后进行解密 得到一张二维码: /iTiS3Cr3TbiTCh.png 然后去在线二维码解密得到一个网址:https://i.imgur.com/a4JjS76.png 去到页面发现一些账号名字,记下来放进user.txt 拿着账号去爆破FTP和SSH(利用的是本地的密码本rockyou) hydra -L user.txt -P /usr/share/wordlists/rockyou.txt 192.168.132.172 ssh hydra -L user.txt -P /usr/share/wordlists/rockyou.txt 192.168.132.172 ftp 然后是爆破了ftp的账号:luther 密码:mypics 成功登陆ftp,发现hubert的目录权限可以任意读写 然而进入hubert却什么东西都没有 ftp 192.168.132.172 ls cd hubert ls -al 公私钥登陆 考虑在hubert用户的目录下写下私钥来进行免密登陆 本地生成公钥对 把公钥复制成authorized_keys文件 在家目录下创建.ssh目录,然后将kali的公钥上传到该目录下 mkdir .ssh cd .

SHAP的介绍和应用(附代码)

SHAP Tutorial 本文主要介绍: SHAP的原理SHAP的应用方式 SHAP的介绍 SHAP的目标就是通过计算每个样本中每一个特征对prediction的贡献, 来对模型结果做解释。在合作博弈论的启发下SHAP构建一个加性的解释模型,所有的特征都视为“贡献者”。对于每个预测样本,模型都产生一个预测值,SHAP值就是该样本中每个特征所分配到的数值。 设第 i i i个样本为 x i x_i xi​,第 i i i个样本的第 j j j个特征为 x i j x_i^j xij​,模型对该样本的预测值为 y i y_i yi​,整个模型的基线(通常是所有样本的目标变量的均值)为 y b a s e y_{base} ybase​,那么SHAP值服从以下等式: y i = y b a s e + f ( x i 1 ) + f ( x i 2 ) + . . . + f ( x i j ) y_i = y_{base} + f(x_i^1)+f(x_i^2)+.

手把手教你安装JDK8~

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 JDK8安装教程一、JKD8下载及安装流程1、浏览器搜索jdk8,进入官网网站进行下载2、选择相应操作系统进行下载,(作者是windows系统)3、下载JDK,建议先在自定义盘符下新建文件夹用来存放JDK,如作者是在D盘创建了environment文件夹,并在此文件夹下新建JDK文件夹存放jdk资源4、下载完毕后点击进行安装,基本上一直点击下一步(如果不需要自定义路径),作者是自定义在D盘下安装JDK的。5、系统环境变量设置6、检查安装和配置的jdk是否成功 JDK8安装教程 jdk8详细安装教程,详情见下操作流程,按照如下操作若遇到问题可在下方留言~ 一、JKD8下载及安装流程 1、浏览器搜索jdk8,进入官网网站进行下载 2、选择相应操作系统进行下载,(作者是windows系统) 同意协议即可下载安装,注意:下载JDK需要登录Oracle,若没有账号可通过qq邮箱创建一个。 注意:若以前有创建过Oracle账户却忘记密码,可通过邮箱重设密码 3、下载JDK,建议先在自定义盘符下新建文件夹用来存放JDK,如作者是在D盘创建了environment文件夹,并在此文件夹下新建JDK文件夹存放jdk资源 4、下载完毕后点击进行安装,基本上一直点击下一步(如果不需要自定义路径),作者是自定义在D盘下安装JDK的。 注意:选择安装目录(可自定义位置),注意一定要记住自己所安装的位置,(路径最好不要出现中文),后续需要配置系统环境变量。 注意:点击下一步即可安装jdk,jdk安装完毕后;随后会提示安装jre,也可自定义文件目录进行安装,同时也需要记住jre的安装位置,后续配置系统环境变量需要用到。 随后点击下一步,等待安装完毕即可。 5、系统环境变量设置 直接在电脑搜索栏搜索系统环境变量,进入编辑系统环境变量 选择环境变量设置 注意:在环境变量设置,需要新建系统变量JAVA_HOME,点击系统变量的新建 变量名:JAVA_HOME(也可以不一样,按自己需求) 变量值:(即为你所安装的jdk的路径,可参考作者的安装路径) 确认后,再修改Path:点击Path,在最后面添加–>%JAVA_HOME%\bin -->%JAVA_HOME%\jre\bin 在最后添加两行,分别为**%JAVA_HOME%\bin**,代表在JAVA_HOME目录下的bin文件;%JAVA_HOME%\jre\bin,代表为在JAVA_HOME目录下的jre目录下的bin文件 最后确定保存配置即可 6、检查安装和配置的jdk是否成功 打开cmd命令框,输入java -version,结果如下图所示出现jdk版本的话,恭喜你,安装配置JDK成功~

LVM方式挂载硬盘

使用lvm方式挂载新硬盘 1)查看设备详情 [root@localhost ~]# fdisk -l | grep dev Disk /dev/sda: 42.9 GB, 42949672960 bytes, 83886080 sectors /dev/sda1 * 2048 2099199 1048576 83 Linux /dev/sda2 2099200 83886079 40893440 8e Linux LVM Disk /dev/mapper/centos-root: 37.6 GB, 37576769536 bytes, 73392128 sectors Disk /dev/mapper/centos-swap: 4294 MB, 4294967296 bytes, 8388608 sectors Disk /dev/sdb: 214.7 GB, 214748364800 bytes, 419430400 sectors 上面的/dev/sdb是新添加的硬盘 2)创建pv [root@localhost ~]# pvcreate /dev/sdb Physical volume "/dev/sdb" successfully created. 3)创建vg [root@localhost ~]# vgcreate locvg /dev/sdb Volume group "

go使用protobuf

protocol buffers 简介 数据传输方式有:json和xml两种格式,其中json更多一些。现在又多了一种数据传输方式,就是google开发的Protocol Buffers Protocol Buffers一个字“快”。一条消息数据,用protobuf序列化后的大小是json的10分之一,是xml格式的20分之一,但是性能却是它们的5~100倍 下载protocol buffers编译器 https://github.com/protocolbuffers/protobuf 点击右侧releases在下面找assets下面对应操作系统的压缩包 解压放到磁盘 C:\Program Files\protoc-3.20.0-win64 把对应位置bin配置到系统环境变量 可在任意位置输入protoc 编写第一个protobuf文件,编译成go文件 为vscode安装vscode-proto3插件 vscode-proto3 创建一个protobuf文件 创建1.proto文件 syntax = "proto3"; option go_package="./;hello"; package hello; message Person{ string name = 1; int32 age = 2; string email = 3; } option go_package = “path;name”; path 表示生成的go文件的存放地址,会自动生成目录的。 name 表示生成的go文件所属的包名 安装go protocol buffers 插件 go install google.golang.org/protobuf/cmd/protoc-gen-go@latest 编译生成go文件 所有proto文件放在proto文件夹,所有go文件放在go文件夹 protoc --go_out=./go ./proto/* protocol buffers 定义消息类型 syntax = "proto3"; message SearchRequest{ string query = 1; int32 page_number = 2; int32 result_per_page = 3; } 文件第一行指定使用的是proto3语法,这必须是文件的第一个非空、非注释行

JavaScript 和 Typescript 的区别

什么是JavaScript? JavaScript是世界上最流行的编程语言之一。 让我们从头讲起。自90年代以来,JavaScript一直是网络应用的核心技术。它用来与HTML和CSS结合创建交互式网页。它是一种具有动态类型和JIT(Just-in-Time)编译器的高级语言。 JavaScript是一种多范式语言,支持各种编程风格,如函数式编程、命令式编程和事件驱动式编程。它还支持编写服务器端。JavaScript是在ECMAScript(ES)标准的基础上形成的。在JavaScript中使用最广泛的ES标准是ES5和ES6。 什么是TypeScript? TypeScript (TS) 是一个 JavaScript 超集,其目标与 JavaScript 相同。 TypeScript 是一种开源编程语言,具有许多特性,如继承、类、可见性范围、命名空间、接口、合并和其他现代特性以及静态和动态类型。它支持注释、变量、函数、语句、模块和表达式。 作为一种强类型的编程语言,TypeScript调试(在编译过程中)更容易,所以更适用于复杂应用。 为什么会出现 TypeScript? JavaScript项目的复杂性呈指数级地增长。最初,JavaScript只被用作客户端语言。但开发人员慢慢意识到,它也可以作为一种服务器端的编程语言。 尽管JavaScript有很多优点,但它在服务器端会变得混乱和复杂(特别是对于大规模的应用程序)。同时,JavaScript还会使大型复杂的应用程序难以维护。 而浏览器不断的迭代和跨浏览器的兼容性也要求对底层的JavaScript进行改变,但继续改造JavaScript来解决这些并不实际。所以TypeScript应运而生。 JavaScript 和 TypeScript 之间的主要区别 JavaScriptTypeScript支持动态网页内容为帮助项目解决代码复杂性而创建的JavaScript超集解释性语言,因此只有在运行时才会发现错误在编译期间可以检测和修复错误弱类型,无法选择静态类型强类型,支持静态和动态类型可以直接在浏览器中使用将代码转换为 JS 以实现浏览器兼容性不支持模块、泛型和接口支持模块、泛型和接口不支持可选参数可选参数可以添加到函数中使用数字和字符串作为接口数字和字符串是对象大量社区支持,包括大量文档社区支持正在增长,不像以前那么强大不支持原型设计原型设计是一个可行的选择不需要事先的脚本知识学习和编码需要时间,需要脚本知识无需设置构建环境对于静态类型定义,需要适当地构建设置(npm 包) TypeScript 比 JavaScript 更好吗? 根据我的描述,TypeScript似乎只是JS的一个更好的版本。所以你可能会认为TS会在不久的将来取代JavaScript。其实不然,我仍然相信JavaScript会有用武之地。 复杂性是一个需要考虑的关键因素。 JavaScript 非常适合更简单的应用程序,因为它可以在所有平台(跨平台)上运行并且非常轻量级。另外,与JS的最小开销相比,编译TS代码需要的时间和CPU资源对项目而言会更麻烦。 与JavaScript相比,TypeScript有很多好处。 TS 使代码重构变得更加容易,并且更强调显式类型,使开发人员能够掌握各种组件的交互方式。由于它支持编译时调试,对于处理大型复杂应用程序的团队来说,有一定的好处。 为任何项目设置TypeScript都是容易的。一些框架,如Angular,默认使用TypeScript。因此,在我看来TypeScript更胜一筹。 TypeScript 的缺点 尽管TypeScript有许多优点,但它也有某些缺点。 需要准确的定义类型,在使用的时候是比较麻烦的,但从长远来看,可以节省时间和资源。这是选择JavaScript的最常用的理由。 你不可能把一个大型的JavaScript项目迁移到严格的TypeScript上。虽然有一些工具可以协助,但你还是需要自己迁移大部分的代码。 TypeScript代码编译需要时间和CPU资源,所以需要等待一会才能看到改变。与传统的JavaScript不同,实时编码会有一点影响。在海量代码库上,这些工具也会显着减慢,导致导航等显着延迟。 什么时候应该将项目迁移到TypeScript? 当代码的大小、复杂性和出错率增加时,需要在编译过程中确定具体问题时,就可以使用TypeScript。 TypeScript 还具有接口和访问修饰符,允许开发人员在单个代码库上进行协作和交互。因此,最好在项目一开始就使用TypeScript。 但是你如果喜欢像Ember.js或Glimmer.js这样的框架,那你就不会喜欢TypeScript,这些框架的首选是JavaScript。 结论 由于 TypeScript 转换为普通的 JavaScript 代码,因此你可以将其用作 JavaScript 的替代品。这就是为什么它更容易被接受。当然我们也能看到TS被集成到流行的JS框架的核心构建组件和库中,如Angular、React和Vue.js。 就个人而言,我是TypeScript的粉丝,通常建议新项目使用它。在开始的时候多花点心思,就省得以后头疼了。

java中使用模糊查询出现的问题及解决方案

在我们用java进行模糊查询的时候,大多数代码如下: SELECT * FROM `table` where name like '%?%'; 这在数据库查询倒是可以运行,但是一旦到了java那边反而会报错: Caused by: java.sql.SQLException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '%'A'% limit 0,4' at line 1 Query: select * from furn where name like %?% limit ?,? Parameters: [A, 0, 4] 所以要在Java中使用模糊查询的话,解决方案如下: ① 添加一个CONCAT函数: select * from `table` where name like CONCAT('%',?

学习记录05:一些常用的Latex符号,在csdn里也可以用

1. csdn怎么打出空格 &emsp;&emsp; 2. 空格 a \quad b a \quad b 3. 属于号,不属于号 ∈ \in ∈ \in ∉ \notin ∈/​ \notin 4. 上下标 上标 a a a^{a} aa a^{a} 下标 a a a_{a} aa​ a_{a} 上下标 a a a a^{a}_{a} aaa​ a^{a}_{a} 5. 怎么打出一些字母头上的符号 帽号 帽子 a ^ \hat{a} a^ \hat{a} 宽帽 a b c b ^ \widehat{abcb} abcb \widehat{abcb} 横线 a b c c ‾ \overline{abcc} abcc \overline{abcc}

带你详细了解Vue中的v-for

v-for 作用: 列表渲染,所在标签结构,按照数据数量,循环生成。指令写在谁身上,就循环创建谁 语法: v-for = "(值变量,索引变量) in 目标结构" :key = 索引变量 v-for = "值变量 in 目标结构 :key = 索引变量" 目标结构:可以是数组,对象,字符串 数组方法如果修改了原数据就会更新 页面,如果没有修改,则不会,但可以重新赋值给变量让你页面更新 v-for中的key作用:在更新的时候: 有key,按照key比较,key设置为index:等于没设,就地复用无key,就地更新 v-for中key 唯一不重复的字符串或者数值,数组中的id key在使用过程中,有id用id,无id用索引 key的好处 可以提高更新的性能 v-set 作用:因为vue是数据驱动页面的,所以修改原数组中可以使用this.arr[0]='测试'但是,由于官方vue2特有的bug,导致这样修改原数组失效,虽然数组确实改变了,但是页面直接没更新,如果需要这样修改数据,就需要$set方法来修改 方法: this.$set(修改数组,索引,‘修改的内容’) 重绘和回流 重绘:元素的颜色/透明度发生变化回流:元素的几何信息(宽度/位置)发生变化回流是把结构重新画出来,重绘给你上色回流一定触发重绘,但重绘不一定会引起回流 虚拟DOM 含义:本质上是一个js对象,保存DOM关键信息 好处:提高DOM更新的性能,不频繁操作真实的DOM,在内存中找到变化部分,再更新真实DOM相应属性或内容(打补丁) computed计算属性 语法:定义在computed中和data(){}并齐 事例: computed:{ totalPrice(){//计算属性名 set(val){ //在计算机属性被修改时执行 //val是计算属性赋的值 } get(){ //get在计算机属性被调用(访问)时执行 //必须return一个结果 } return this.count*this*this.price//返回运算结果 } } 缓存:计算属性,基于依赖项的值进行缓存,依赖的变量不变,都直接从缓存取结果(带缓存)

使用阿里云服务器安装宝塔面板搭建网站教程(图文全流程)

阿里云服务器安装宝塔面板教程,云服务器吧以阿里云Linux系统云服务器安装宝塔Linux面板为例,先配置云服务器安全组开放宝塔所需端口8888、888、80、443、20和21端口,然后执行安装宝塔面板命令脚本,最后登录宝塔后台安装LNMP,包括Nginx、MySQL、Pure-Ftpd、PHP和phpMyAdmin: 阿里云服务器安装宝塔面板教程 云服务器吧创建了一台阿里云服务器ECS计算型c7实例(ecs.c7.large)2核4G配置,5M公网带宽,操作系统为Alibaba Cloud Linux,如下图: 阿里云Linux服务器配置 阿里云服务器出于安全考虑,默认安全组只开放了22和3389端口,宝塔面板需要开启8888、888、80、443、20和21端口。先为云服务器开放宝塔所需端口,然后再执行安装宝塔Linux面板命令。 一:阿里云服务器开启宝塔所需端口号 如果你使用的不是阿里云服务器,或者已经开放了相应的端口,那么可以忽略此步骤。 1、登录到阿里云服务器管理控制台 左侧栏选择“实例”,找到需要开放端口的云服务器ECS实例,如果没有,记得切换左上角地域 2、找到“更多”--“网路和安全组”--“安全组配置”,如下图: 阿里云服务器安全组配置 3、在安全组的“配置规则”中,按照下图开放21、20、443、80、888和8888端口 阿里云服务器开放宝塔面板端口 如上图所示,在“入方向”选择“手动添加”,云服务器吧以开启8888端口为例,端口范围目的:8888/8888,授权对象源:0.0.0.0/0。以此类推,把宝塔面板所需端口都开启。 二:远程连接到云服务器执行宝塔面板安装命令 远程连接到云服务器,可以使用阿里云服务器控制台自带的远程连接工具,也可以使用Xshell等SSH客户端。云服务器吧以阿里云服务器控制台自带的远程连接工具为例,如下图: 阿里云服务器远程连接 阿里云服务器支持多种远程连接方式,云服务器吧以Workbench远程连接为例,选择“Workbench远程连接”,点“立即登录”,如下图: 阿里云Workbench远程连接 云服务器Linux系统默认用户名为root,输入密码,点确定,即可登录。 登录云服务器 如果没有设置密码,或者忘记密码,可以通过重置实例密码的方式来设置新的密码。 然后执行宝塔Linux面板安装命令。云服务器吧使用的阿里云服务器安装的是Alibaba Cloud Linux镜像,Alibaba Cloud Linux是基于龙蜥社区(OpenAnolis) 龙蜥操作系统(Anolis OS)的阿里云发行版,完全兼容 RHEL/CentOS 生态和操作方式,所以使用宝塔面板CentOS的安装命令即可。 执行CentOS宝塔安装命令: yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh 其他Linux系统安装宝塔面板命令,可以参考:宝塔面板Linux系统安装命令大全 执行宝塔安装命令后,会提示如下: Do you want to install Bt-Panel to the /www directory now?(y/n): y 回复字母y,并回车即可继续安装。 这期间等待即可,宝塔程序会自动安装,安装时间与云服务器带宽和配置有关,一般3-5分钟即可安装完毕。 宝塔面板安装完毕后,会提示“Congratulations! Installed successfully!”并返回外网面板登录地址、用户名username和密码password。 至此阿里云服务器安装宝塔面板程序结束,我们还需要在宝塔面板上安装Web环境,本文是以安装LNMP环境为例。 三:宝塔面板安装Web环境 复制安装成功后返回的宝塔外网面板地址,并在浏览器的地址栏中打开,如下图: 使用账号密码登录宝塔Linux面板

Latex数学公式汇总

LaTex数学公式汇总 1.希腊字母 希腊字母小写本质上就是希腊字母的英文**(首字母小写)**前面+转义符号\;希腊字母大写本质上就是希腊字母的英文**(首字母大写)**前面+转义符号\; 编号小写大写英文LaTex公式(小写)读音 1 1 1 α \alpha α A \Alpha A a l p h a alpha alpha\alpha/'ælfə/ 2 2 2 β \beta β B \Beta B b e t a beta beta\beta/'bi:tə/or/'beɪtə/ 3 3 3 γ \gamma γ Γ \Gamma Γ g a m m a gamma gamma\gamma/'gæmə/ 4 4 4 δ \delta δ Δ \Delta Δ d e l t a delta delta\delta/'deltə/ 5 5 5 ϵ \epsilon ϵ E \Epsilon E e p s i l o n epsilon epsilon\epsilon/'epsɪlɒn/ 6 6 6 ζ \zeta ζ Z \Zeta Z z e t a zeta zeta\zeta/'zi:tə/ 7 7 7 η \eta η H \Eta H e t a eta eta\eta/'i:tə/ 8 8 8 θ \theta θ Θ \Theta Θ t h e t a theta theta\theta/'θi:tə/ 9 9 9 ι \iota ι I \Iota I i o t a iota iota\iota/aɪ’əʊtə/ 10 10 10 κ \kappa κ K \Kappa K k a p p a kappa kappa\kappa/'kæpə/ 11 11 11 λ \lambda λ Λ \Lambda Λ l a m b d a lambda lambda\lambda/'læmdə/ 12 12 12 μ \mu μ M \Mu M m u mu mu\mu/mju:/ 13 13 13 ν \nu ν N \Nu N n u nu nu\nu/nju:/ 14 14 14 ξ \xi ξ Ξ \Xi Ξ x i xi xi\xi/ksi/or/'zaɪ/or/'ksaɪ/ 15 15 15 ο \omicron ο O \Omicron O o m i c r o n omicron omicron\omicron/əu’maikrən/or/'ɑmɪ,krɑn/ 16 16 16 π \pi π Π \Pi Π p i pi pi\pi/paɪ/ 17 17 17 ρ \rho ρ P \Rho P r h o rho rho\rho/rəʊ/ 18 18 18 σ \sigma σ Σ \Sigma Σ s i g m a sigma sigma\sigma/'sɪɡmə/ 19 19 19 τ \tau τ T \Tau T t a u tau tau\tau/tɔ:/or/taʊ/ 20 20 20 υ \upsilon υ Υ \Upsilon Υ u p s i l o n upsilon upsilon\upsilon/'ipsilon/or/'ʌpsilɒn/ 21 21 21 ϕ \phi ϕ Φ \Phi Φ p h i phi phi\phi/faɪ/ 22 22 22 χ \chi χ X \Chi X c h i chi chi\chi/kaɪ/ 23 23 23 ψ \psi ψ Ψ \Psi Ψ p s i psi psi\psi/psaɪ/ 24 24 24 ω \omega ω Ω \Omega Ω o m e g a omega omega\omega/'əʊmɪɡə/or/oʊ’meɡə/ **注:**常用的梯度符号 ∇ \nabla ∇的LaTeX公式为\nabla

长文详解 MySQL redo log 原理

文章目录 redo 日志格式简单的 redo 日志类型复杂的 redo 日志格式举个例子 redo 日志格式小结 Mini-Transcation以组的形式写入 redo 日志Mini-Transaction 的概念 redo 日志写入过程redo log blocklog block headerlog block trailer redo 日志缓冲区redo 日志写入 log buffer redo 日志文件刷盘时机redo 日志文件组redo 日志文件格式特殊 block log sequence numberflushed_to_disk_lsnIsn 值和 redo 日志文件组中的偏移量的对应关系flush 链表中的 lsn checkpoint执行一次 checkpoint 用户线程批量从 flush 链表中刷出脏页查看系统的各种 lsn 值innodb_flush_log_at_trx_commit崩溃恢复确定恢复的起点确定恢复的终点 恢复过程使用哈希表跳过己经刷新到磁盘中的页面 LOCS_BLOCK_HDR_NO 是如何计算的 redo 日志是为了在系统因奔溃而重启时恢复奔溃前的状态而提出的。 lnnoDB 存储引擎是以页为单位来管理存储空间的,我们进行的增删改查操作从本质上来说都是在访问页面(包括读页面、写页面、创建新页面等操作)。在真正访问页面之前,需要先把在磁盘中的页加载到内存中的[[Buffer Pool]] 中,之后才可以访问。事务的持久性的特征要求对于一个己经提交的事务,在事务提交后即使系统发生了崩溃,这个事务对数据库所做的更改也不能丢失。 如果我们只在内存的 Buffer Pool 中修改了页面,假设在事务提交后突然发生了某个故障,导致内存中的数据都失效了,那么这个已经提交的事务在数据库中所做的更改也就跟着丢失了,这是我们所不能忍受的。那么,如何保证这个持久性呢?一个很简单的做法就是在事务提交完成之前,把该事务修改的所有页面都刷新到磁盘。不过这个简单粗暴的做法存在下面这些问题: 刷新一个完整的数据页太浪费了。有时我们仅仅修改了某个页面中的一个字节,但是由于 InnoDB 是以页为单位来进行磁盘 I/O 的,也就是说在该事务提交时不得不将一个完整的页面从内存中刷新到磁盘。一个页面的默认大小是 16 KB,因为修改了一个字节就要刷新 16KB 的数据到磁盘上,显然太浪费了。随机 I/O 刷新起来比较慢。一个事务可能包含很多语句,即使是一条语句也可能修改许多页面,而且该事务修改的这些页面可能并不相邻。这就意味着在将某个事务修改的 Buffer Pool 中的页面刷新到磁盘时,需要进行很多的随机 I/O。随机 I/O 比顺序 I/O 要慢,尤其是对于传统的机械硬盘。 我们只是想让已经提交了的事务对数据库中的数据所做的修改能永久生效,即使后来系统崩溃,在重启后也能把这种修改恢复过来。所以,其实没有必

信号完整性分析学习--18--源端匹配

信号在驱动器和接收器之间传输时由于源端和末端反射的存在就会导致多次反射,反射的结果就是导致接收端的波形产生信号的畸变。当驱动器的驱动能力强时可能导致过冲和振铃;当驱动器的驱动能力比较弱时,可能会导致信号边沿退化严重甚至边沿不单调。 当过冲超过接收器的规范要求就会对器件寿命产生影响;过冲过大也会导致信号链路上产生远高于信号频率本身的高频分量,从而导致更加严重的EMI问题,这也可能导致系统设计失败;当振铃过于严重就会影响信号的有效位宽和噪声裕量,有效位宽的减小会导致信号建立保持时间裕量的不足,噪声裕量减小会导致信号信号抗干扰能力的降低,串扰和电源噪声都可能导致信号的误判;时钟信号如果存在边沿不单调则也可能导致接收器接收数据错误。因此可以说控制传输路径上的反射是信号完整性分析的首要任务。而控制反射最常用的手段就是源端匹配和终端端接。 源端匹配 实际设计中最常用的源端匹配方式就是在驱动器输出端加串联电阻。电阻的阻值需要根据驱动器的输出阻抗来决定,匹配电阻加上驱动器输出阻抗等于传输线阻抗时能够完全消除源端的反射。 如上所示,在驱动器输出就近加33ohm匹配电阻Rmatch,使Rmatch+Rs=50ohm。信号进入传输线时在Vdrv点50ohm电阻和50ohm的传输线分压,得到的信号幅值只有1.65V。1.65V的入射电压沿传输线传播到接收端发生全反射,产生1.65V的反射信号。这就导致在接收端接收到的幅值为3.3V,同时反射信号向源端传输,由于源端的阻抗匹配,当反射信号到达源端之后就不会再有反射。 由此可见,源端匹配的作用就是让驱动器输出端的阻抗(包含驱动器内阻和匹配电阻)与传输线阻抗匹配,抑制了终端不匹配导致的反射信号在源端发生二次反射,进而抑制了多次反射的发生。抑制了多次反射,也就抑制了信号的过冲和振铃,无论对器件的寿命还是接收端信号的有效判决都有重要的意义。 采用源端匹配方式时,需要注意匹配电阻阻值的选择和匹配电阻布局这两个方面。源端匹配电阻先择以匹配传输线阻抗为目的,但也并不是选择了合适的阻值就能够起到预期的作用,如果匹配电阻的布局不合理它的效果就会大打折扣。 匹配电阻的布局 前面讲传输线的效应时曾经提到,通常认为当信号传输延时小于信号上升时间1/6时,互连线处在集总区域,不会体现出传输线效应。这一点应用到匹配电阻的布局中就要求,源端匹配电阻布局要尽量靠近驱动器。因为只有让匹配电阻和驱动器内阻之间的互连线(TLD2)延时小于信号上升时间的1/6才能够使驱动器内阻和这段互连线加上匹配电阻看做是集总的,将这三部分集总在一起考虑。 下面我们可以仿真对比一下当信号上升时间为50ps时驱动器内阻到匹配电阻的互连线延时分别为8ps(小于50ps的1/6)、20ps、50ps(与信号上升时间相当)时的接收器件接收到的信号波形。 为了更好的观测仿真结果,将三种情况信号的延时分别错开了1ns。 需要注意的是,这里的仿真为了让读者更加清晰的看到驱动器内阻到匹配电阻的互连线延时的影响,将信号的上升时间设置为50ps是非常快,实际应用中除了高速串行链路和DDR等高速并行总线上升时间并不会达到这么快。 从上面的仿真结果可以看出: 驱动器内阻到匹配电阻的互连线长度对接收器接收波形有很大影响,会在接收波形稳定电平处产生周期性的过冲和震荡,且过冲的间隔等于传输线延时的两倍。这说明由于驱动器内阻到匹配电阻的互连线的存在使得源端并没有完全匹配,在驱动器和接收器之间还是存在着反射信号;驱动器内阻到匹配电阻的互连线延时小于信号上升时间延时1/6时产生的反射信号对信号质量影响很小;互连线延时超过信号上升时间延时1/6、甚至和信号上升时间相当时产生的反射信号非常大,会产生比较大的过冲,且过冲的幅度随着延时的增大而增大,匹配电阻所起到的匹配效果也会更差。 由此可见,对于一个上升时间有1ns左右的LVTTL或者CMOS电平信号,只要驱动器内阻到匹配电阻之间的延时不超过150ps,匹配电阻就能起到良好的匹配效果。微带线的延时大概140ps/inch,带状线170ps/inch,也就是说只要这段互连线布线长度不超过1inch即可;但是对于DDR等高速内存接口上升时间可能只有几十ps,这对匹配电阻的布局和布线要求就相当严格了,因此这些高速接口常常使用的是芯片内部匹配端接。 驱动器的驱动能力 驱动器输出阻抗从一定程度上反映了驱动器的驱动能力。根据输出电阻的大小可以分为过驱动和欠驱动两种情况。下图所示为驱动器输出一个上升时间500ps的3.3V阶跃信号,输出阻抗分别为20ohm、80ohm时在接收端接收到的信号波形。 所谓过驱动就是驱动器输出阻抗(驱动器内阻加上源端匹配电阻)小于传输线阻抗的情况,此时进入传输线的入射电压大于1/2VCCIO,接收端反射回来的信号在源端发生负反射从而使接收端信号产生过冲和振铃,经过多次反射后稳定于VCCIO电平。 欠驱动就是驱动器输出阻抗大于传输线阻抗的情况,此时进入传输线的入射电压小于1/2VCCIO,接收端接收到的电压幅值小于VCCIO,接收端反射回来的信号在源端发生正反射从而使接收端信号产生阶梯状上升的趋势,经过几次反射之后才能到达稳定的VCC电平。总体上看,过驱动时信号边沿很陡并且存在过冲,而欠驱动时信号边沿很缓。 另外,除了使用驱动器输出阻抗来表示驱动器输出能力之外,还可以使用驱动电流来表示驱动能力的大小,比如说xilinx的FPGA中LVTTL、CMOS电平的驱动电流通常在4mA到24mA可调,驱动电流越大说明驱动能力越强。 信号上升时间 信号上升时间对信号质量有重要的影响。在过驱动情况下,如果上升时间很快,信号将很快达到过冲的峰值,如果信号的上升时间很长那么过冲达到峰值的时间也会变长甚至不能达到峰值;在欠驱动的情况下,信号的上升时间很短会在信号边沿上形成明显的台阶,随着信号上升时间的增大台阶会越来越不明显最后可能消失。无论是过冲还是台阶它们的宽度都和传输线延时有关,由此信号上升时间和传输线延时应该有一定的关系使相互作用对最终信号质量产生影响。 过驱动情况下,驱动器到接收器之间传输线延时为1ns,信号上升时间分别为1ns、2ns、3ns情况接收器接收波形如下图所示: 当信号上升时间小于2倍的传输线延时时,接收端过冲能够达到峰值;当信号上升时间大于2倍的传输线延时时, 接收端过冲峰值减小,上升时间越大过冲越不明显。 欠驱动情况下,驱动器到接收器之间传输线延时为1ns,信号上升时间分别为1ns、2ns、3ns情况接收器接收波形如下图所示: 当信号上升时间小2倍的传输线延时时,接收端信号存在台阶,台阶的大小为2倍的传输线延时减去上升时间;当信号上升时间大于2倍的传输线延时时, 接收端台阶不在明显,上升时间越大信号的边沿越缓。这再一次证明了为什么说上升时间越快、传输线长度越长带来的信号完整性问题越严重。 

python-求整数的位数及各位数字之和

对于给定的正整数N,求它的位数及其各位数字之和。 (用Python实现提示:把整数转换成字符串,列表,用sum和len函数) 输入格式: 输入在一行中给出一个正整数N。 输出格式: 在一行中输出N的位数及其各位数字之和,中间用一个空格隔开。 a=input() sum=0 for i in range(len(a)): sum+=int(a[i]) print("{} {}".format(len(a),sum))

Linux系统初始化

学习Linux内核的原因 我个人是软件工程专业的学生,但是对计算机是怎么运行的一直都有疑惑。 为什么一通电计算机就能运行了,处理各种任务。 如果对计算机底层知识的不熟悉和不理解的话,这就造成了在了解各种中间件或者软件的底层原理的时候,会比较吃力,对于程序运行的具体情况也不太清楚。 我个人目前认为只有对程序在计算机中的具体执行过程有着深入的了解,才能写出性能更好、更健壮性的代码,所以开始学习Linux内核。 Linux内核学习方法 资料 《趣谈Linux内核 》 刘超 极客时间专栏 Linux源码 路线 学习Linux内核切记不要太过深入死扣代码,而是要先在宏观上了解Linux的运行原理,然后再深入了解具体实现原理 Linux初始化 相信很多人都有这样的疑惑:为什么通电后,按下启动按钮,操作系统就运行了? BIOS初始化 当通电后,CPU就开始执行指令了,执行的是什么指令呢?主板上有一块ROM,ROM是只读存储器,里面存储了BIOS程序。CPU会执行BIOS程序来加载操作系统。 BIOS的全称是 basic input and output system,也就是基本输入输出系统。 上述图片是bios时期的CPU地址空间的映射布局。 此时CPU处于实模式,寄存器的位数是16位,然后地址线是20位,CPU的寻址空间是2^20,也就是1MB,即使是更先进的CPU,支持64位寄存器或者超过20根的地址线,同样只能使用寄存器中的16位和其中的20根地址线。 地址的转换规则为 DS寄存器左移4位 + IP寄存器。此时CPU处于ring0特权,可以执行所有指令,操作硬件。 其中0X F0000 到 0X FFFFF 这 64kb的地址空间映射到 ROM中。 当CPU通电后,会做一些重置操作,讲DS寄存器赋值为0X FFFF , IP寄存器为 0X 0000,所以访问地址就对应着 0X FFFF0,地址0X FFFF0对应的空间 处于ROM的空间中,也就是开始执行bios程序。 1、初始化中断向量表等数据,因为用户可以通过鼠标、键盘等操作方式来操作BIOS程序,所以 2、初始化硬件资源:显示器、内存、磁盘等资源 3、加载操作系统,也就是进入BootLoader阶段 BootLoader阶段 BootLoader阶段,BIOS程序会记载操作系统内核,怎么加载呢? 检测存储设备的第一个扇区是不是以0xAA55结尾的。 如果是以0xAA55结尾就说明这是一个操作系统的启动区。我们都知道一个扇区的大小一般是512字节,一个操作系统编译后的代码一般都是好几百MB,第一个扇区是无法装下操作系统所有的代码的,所以只会将操作系统的启动代码存储到第一个扇区内,这个扇区也叫做引导扇区,存储的内容叫做boot.img。 boot.img是grub2工具写入到磁盘中的。 bios程序会将boot.img 加载到 内存中的 0x 7C00,然后利用jump指令,跳转到boot.img,至此BIOS程序就算功德圆满了,接下来就看grub2的了。 grub2加载内核过程 grub2是Grand Unified Bootloader Version 2,是一个多系统启动程序,用来一个硬盘上存在多个系统的启动,多个系统的相关配置信息被写入到了一个配置文件grub.cfg中。grub.cfg中写入了操作系统的一些配置,包括系统的版本、系统镜像的位置等信息 menuentry 'CentOS Linux (3.

Java集合类的解析与实现

集合概念: 1.1集合可以看做是一个容器,如红色的衣服可以看做是一个集合,所有Java类的书也可以看做是一个集合。集合中的各个对象,很容易将其从集合中取出来。 1.2类似数组功能 和数组的区别: 数组长度固定,集合长度不固定数组可以存储基本类型和引用类型,集合只能存储引用类型 位置;java.util.*; Collection体系接口集合 List接口特点:有序、有下标、元素可重 Set 接口特点:无序、无下标、元素不可重复 Collection中的一些方法 方法 功能描述 add(E e) 将指定的对象添加到该集合中 remove(Object o) 讲指定的对象从该集合中移除 isEmpty() 返回boolean值,用于判断当前集合是否为空 iterator() 返回在次Collection的元素上进行迭代的迭代器,用于遍历集合中的对象 size() 返回Int整型,获取该集合中元素的个数 2.1添加元素的实现 2.2删除元素 2.3 遍历使用增强for 2.3.1 使用迭代器(迭代器专门用来遍历集合的一种方式) (1)hasNext(); 有没有下一个元素 (2)next(); 获取下一个元素 (3)remove();删除点钱元素 注意:迭代当中是不允许用collection.remove 3.判断 同样的使用学生进行Collection (1)新建一个Student类 代码如下 package assemble.demo01; public class Student { private String name; private int age; public Student(){ } public Student(String name, int age) { super(); this.name = name; this.age = age;

WebService

WebService技术 WebServiceWebService概念WebService平台技术XML:SOAP(Simple Object Access Protocol简单对象访问协议):WSDL: WebService与Socket的区别 WebService 最近项目中碰到用WebService与上位进行通信的场景,于是在网上看了很多关于WebService的资料,接下来说一说我本人对WebService的理解。 WebService概念 WebService是一个跨编程语言和操作系统平台的远程调用技术,当一个系统由两个公司共同开发的时候经常会用到这种技术(A公司提供接口供B公司远程调用)。 从表面上看,WebService就是一个应用程序向外界暴露出一个能通过Web进行调用的API,把调用这个WebService的应用程序叫做客户端,而把提供这个WebService的应用程序叫做服务端。从深层次看,WebService是建立可互操作的分布式应用程序的新平台,是一个平台,是一套标准。 WebService平台技术 XML+XSD,SOAP和WSDL就是构成WebService平台的三大技术。 XML: WebService采用HTTP协议传输数据,采用XML格式封装数据(即XML中说明调用远程服务对象的哪个方法,传递的参数是什么,以及服务对象的返回结果是什么)。XML是WebService平台中表示数据的格式。除了易于建立和易于分析外,XML主要的优点在于它既是平台无关的,又是厂商无关的。无关性是比技术优越性更重要的:软件厂商是不会选择一个由竞争对手所发明的技术的。 XML解决了数据表示的问题,但它没有定义一套标准的数据类型,更没有说怎么去扩展这套数据类型。例如,整形数到底代表什么?16位,32位,64位?这些细节对实现互操作性很重要。XML Schema(XSD)就是专门解决这个问题的一套标准。它定义了一套标准的数据类型,并给出了一种语言来扩展这套数据类型。WebService平台就是用XSD来作为其数据类型系统的。当你用某种语言(如VB.NET或C#)来构造一个Web service时,为了符合WebService标准,所有你使用的数据类型都必须被转换为XSD类型。你用的工具可能已经自动帮你完成了这个转换,但你很可能会根据你的需要修改一下转换过程。 SOAP(Simple Object Access Protocol简单对象访问协议): WebService通过HTTP协议发送请求和接收结果时,发送的请求内容和结果内容都采用XML格式封装,并增加了一些特定的HTTP消息头,以说明HTTP消息的内容格式,这些特定的HTTP消息头和XML内容格式就是SOAP协议。SOAP提供了标准的RPC方法来调用Web Service。 SOAP协议 = HTTP协议 + XML数据格式 SOAP协议定义了SOAP消息的格式,SOAP协议是基于HTTP协议的,SOAP也是基于XML和XSD的,XML是SOAP的数据编码方式。 打个比喻:HTTP就是普通公路,XML就是中间的绿色隔离带和两边的防护栏,SOAP就是普通公路经过加隔离带和防护栏改造过的高速公路。 WSDL: 如下图所示 WebService客户端要调用一个WebService服务,首先要有知道这个服务的地址在哪,以及这个服务里有什么方法可以调用,所以,WebService务器端首先要通过一个WSDL文件来说明自己家里有啥服务可以对外调用,服务是什么(服务中有哪些方法,方法接受的参数是什么,返回值是什么),服务的网络地址用哪个url地址表示,服务通过什么方式来调用。 WSDL(Web Services Description Language)就是这样一个基于XML的语言,用于描述Web Service及其函数、参数和返回值。它是WebService客户端和服务器端都能理解的标准格式。因为是基于XML的,所以WSDL既是机器可阅读的,又是人可阅读的,这将是一个很大的好处。一些最新的开发工具既能根据你的Web service生成WSDL文档,又能导入WSDL文档,生成调用相应WebService的代理类代码。 WSDL文件保存在Web服务器上,通过一个url地址就可以访问到它。客户端要调用一个WebService服务之前,要知道该服务的WSDL文件的地址。WebService服务提供商可以通过两种方式来暴露它的WSDL文件地址:1.注册到UDDI服务器,以便被人查找;2.直接告诉给客户端调用者。 上面对WebService做了简单介绍,接下来聊一聊WebService与常用的http、socket之间的区别。 WebService与Socket的区别 在说Socket之前我们先看一下网上关于socket的图片: 看了socket流程图之后我觉得socket与WebService没有什么区别,都是客户端和服务端的数据交互,但是在看了很多博客之后我觉得并不是这样。 socket是系统层面的东西,可以完成TCP,UDP等协议之间的通信。WebSevice是应用层面的东西,是使用Socket + HTTP 协议 的一种规范。socket 只是 java在网络层定义的类,用来实现网络层。上面的各层需要我们自己在程序里实现。 例如端口可以自己定义 、数据包的定义、 数据包的加密解密等 而webService java实现了应用层的工具,他基于的服务为http协议,通过服务器才可以发布出去。 这样内部的端口的定义、数据包的定义和数据包的加密解密都做好了,所以我们就直接可以用了。 webService 内部数据格式为xml格式、由于基于http协议,所以可以不受防火墙的影响。 因为他的通信协议和我们浏览网页的协议是相同的。 总结: 因为WebService是建立在tcp/ip协议连接上,而socket是java实现tcp/ip的一种抽象技术,所以socket和WebService没有很亲密的关系,通俗点说WebService的底层是socker实现的。

Java API操作 HBase

导入数据问题 使用HBase原生Client API。(Shell)使用HBase提供的TableOutputFormat,原理是通过一个Mapreduce作业将数据导入HBase。使用Bulk Load方式:原理是使用MapReduce作业以HBase的内部数据格式输出表数据,然后直接将生成的HFile加载到正在运行的HBase中。 对比: 前两种方式:需要频繁的与数据所存储的RegionServer通信,一次性导入大量数据时,可能占用大量Regionserver资源,影响存储在该Regionserver上其他表的查询。第三种方式:HBase在HDFS中是以HFile文件结构存储的,一个比较高效便捷的方法就是先生成HFile,再将生成的HFile加载到正在运行的HBase中。即使用HBase提供的HFileOutputFormat2类或者importtsv工具来完成上述操作。通常来说,在数据量很大的情况下,使用第三种方式(Bulk Load)更好。 Java API 操作 HBase HBase 2.0.5 Jave API 中使用HTableDescriptor与HColumnDescriptor时提示不推荐使用了,并且在3.0.0版本将删除,而是使用TableDescriptorBuilder和ColumnFamilyDescriptorBuilder. public class HBaseOperation { public static Configuration configuration; public static Connection connection; public static Admin admin; // 建立链接 public static void init() { configuration=HBaseConfiguration.create(); configuration.set("hbase.rootdir", "hdfs://localhost:9000/hbase"); try { connection=ConnectionFactory.createConnection(configuration); admin=connection.getAdmin(); }catch(IOException e) { e.printStackTrace(); } } // 关闭连接 public static void close() { try { if(admin !=null) { admin.close(); } if(connection !=null) { connection.

8086中断向量

通俗易懂,留着复习用 8086共有=256个不同的中断源,每一个中断源都有唯一的一个中断识别号,即中断类型码。 每一个中断类型码对应着一个中断向量,本质上来说中断向量就是中断服务子程序的唯一确定的一个入口地址,这个地址由中断服务子程序的段地址CS和偏移地址IP组成,共占内存4B(CS、IP均为16位,分别占两个字节)。中断向量的入口地址按照中断类型码的顺序存放在一段连续排列的存储区域内,这个存储区域就称为中断向量表。 8086的中断向量表占用了256*4=1KB的地址空间(00000H~003FFH),故8086的中断向量表位的起始地址为00000H,在微机系统初始化的时候,系统将中断源(0~255)的中断服务子程序的入口地址(即中断向量)按顺序填写在中断向量表中。 其中,中断向量类型码为n的中断向量在表中的逻辑地址为0000:4n。这里需要补充一个知识点: 逻辑地址=段地址:偏移地址 物理地址=段地址10H+偏移地址 (7018H*10H=70180H) 逻辑地址中的4n即该中断向量在表中的存放地址(00000H~003FFH)。 在某度看到了这张表,是我认为最直接最清晰的表了,如下: 中断向量的存放方式:低地址的两字节存放中断服务子程序入口地址的偏移地址IP,高地址的两字节存放入口地址的段基址CS。 IP、CS地址具体存放方式:高八位放高地址,低八位放低地址。(地址编号大的为高地址,反之低地址,如0000H~003FFH依次从低地址到高地址) 再补充个知识点:高、低字节 &大小端模式 大端、小端说明的是数据的组织方式。 低字节放在高地址,高字节放在低地址称为大端模式, 高字节放在高地址,低字节放在低地址称为小端模式。 eg.一个十六进制的数FF1A,高字节是FF,低字节是1A。 总结来说就是左边是高字节,右边是低字节 8086系统的数据组织方式属于小端模式。 来看个例题: 8086中,中断类型码为 18H 的中断向量存放在内存中的 4 个字节单元中,其中的字节单元内容从低字节到高字节依次为 1AH、2BH、3CH、4DH, 则 18H 号中断服务程序入口地址是多少? 4D3C:2B1A

【错题集】如何在scrapy中设置cookie?

第一步、在middlewares.py的process_request设置 request.cookies={"":"","":""} 如下图: 第二步、在settings.py中取消对DOWNLOADER_MIDDLEWARES的注释 DOWNLOADER_MIDDLEWARES = { 'xxxxxl.middlewares.xxxxxDownloaderMiddleware': 543, } 完成啦!!!!

CTS环境搭建

网上有很多搭建cts环境的方法,如Android GMS(cts/gts/cts-v)认证 - 简书。这里是从驱动工程师的角度来搭建一个简易的cts环境,因为一些cts失败项需要驱动工程师修改,但修改后又没有环境去验证。如果能搭建一个简易的cts环境,就能极大促进工作效率。 笔者用的是Ubuntu20.04的OS。 获取CTS工具下载地址,有条件的可以直接下载,或者让GMS的同事发一份过来。 安装openjdk apt install openjdk-11-jre-headless 下载sdk 可通过下面的地址下载 下载platform tools,并放到sdk的根目录下 SDK Platform Tools 版本说明 | Android 开发者 | Android Developers 配置jdk的位置,如 export ANDROID_HOME=/home/w/workspace/android-sdk-linux export PATH=$ANDROID_HOME/tools:$PATH export PATH=$ANDROID_HOME/platform-tools:$PATH 单跑某一条失败项,如gedit ~/.bashrc(需要重启,或者直接source ~/.bashrc) run cts -m CtsCameraTestCases -t android.hardware.camera2.cts.AllocationTest#testBlackWhite[1]

【软件教程】解决VirtualBox报错:Error relaunching VirtualBox VM process5

【问题描述】 虚拟机不能启动相关的进程。 【问题排查】 (1)电脑是否开启了虚拟化。需要开启虚拟化。 (2)是否安装了“净网大师”。需要停用或者卸载。 (3)是否安装了火绒? 【我的解决思路】 我电脑上安装了火绒,现在点击“安全工具”“启动项管理”“服务项” 看见 VBoxSDS已经被禁用。 开启相关的服务就可以了。 补充解决思路 可以打开log文件,来查看退出代码是什么。 目录在虚拟机文件夹下面的 Logs下,打开VBoxHardening.log 查看最后一行的代码。 相关链接: https://blog.csdn.net/JaCenz/article/details/115827030 如果退出代码为0 这种情况建议多重启几次,或者参考下面的解决思路2。修改注册表。 如果退出代码和我一样是0X1的话 那么使用管理员的CMD执行命令sfc /scannow 那么这很可能是dll库的问题,修复一下 执行完成后,首先卸载当前的版本,然后重启电脑重新安装,看到我们的VB已经可以开启了。 xC0000005 这三个dll都替换了,如果替换一个不行的话那就都试试呗。不过themeservice和uxtheme都是正在运行的,即便获取管理员权限了也不好替换,慎行,有可能造成未知的后果。 也可以检查一下显卡驱动更新。 补充解决思路2 (摘抄自:https://www.wintips.org/fix-virtualbox-error-in-supr3hardenedwirespawn-and-hardening-exit-code-1/) //通过修改注册表来Fix BUG。 Step 1. Change the Start type of VBoxDrv Service (VBoxDrv.inf) to 2 (Auto Load)* Note: The idea to change the ‘Start’ value of VBoxDrv service to 2, came after reading the Hardening Fix (workaround) For Error After Install and Restart in VirtualBox forums, where it is suggested to change the ‘Start’ value to 3.

Latex- Texlive+Texstudio 安装和使用

论文写作神器:Latex- Texlive+Texstudio 安装和使用 一、简介 LaTeX的使用需要2个重要东西:1.选择一个TeX发行版进行安装(根据个人系统,本文选择Texlive Win10)。2.选择合适的Latex编辑器(如CTex的Winedt,本文选择Texstudio) 二、TeXlive安装 本人下载的TeXlive是最新版的(如下图),下载地址:清华Texlive镜像。安装程序为texlive2021-20210325.iso。 安装步骤: 1. 解压Texlive2021-20210325.iso文件,右键install-tl-windows.bat,以管理员身份打开。 2. 出现如下界面,点击 Advanced。 3. 选择安装位置,其他保持默认,并点击安装 4. 出现如下界面,等待ing 5. 安装完成 6. 最后打开cmd,分别输入tex -v, latex -v, xelatex -v, pdflatex - v 出现版本号证明安装成功!!! -> tex -v -> latex -v -> xelatex -v -> pdflatex - v 三、TeXStudio安装 1. 安装 按照下面步骤进行安装(很简单)TexStudio下载地址:TeXStudio 2. 配置 接下来就是TeXstudio的配置。 2.1 将语言设置为中文。依次选择Opitions->Configure TeXstudio 2.2 修改中文界面后,我们可以选择左侧命令设置不同编译器,外部PDF查看器,和参看文献的执行程序。 点击1处,可以将上述提到的3,4,5等的路径设置为TeXlive安装路径下对应的exe执行程序。点击2处,就可恢复默认。 2.3 默认编译器、默认PDF查看器、默认文献工具等设置 点击构建选项,可以修改默认编译器、PDF查看器和默认文献工具等。若写中文论文,则需修改默认编译器为XelaTeX. 若为英文,则用PdfLaTex。 2.4 设置默认字体编码和添加行号 点击编辑器选项,一般默认字体编码为UTF-8(一般不修改)。显示行号默认:所有行号。添加行号,可以快速定位某个词或句的位置。此外,当程序报错时,可快速定位到出错位置,方便修改。 小结:TeXstudio的配置就介绍到这里,如有其他配置,可根据自己需求设定,也可在评论区区留言。 3. TeXstudio中英文测试 输入下面代码(含中文),选择默认编译器为XeLateX(选择PDFLeteX会报错),点击编译并查看按钮(或F5快捷键),查看效果。 \documentclass[11pt]{ctexart} \usepackage[top=2cm, bottom=2cm, left=2cm, right=2cm]{geometry} \usepackage{algorithm} \usepackage{algorithmicx} \usepackage{algpseudocode} \usepackage{amsmath} \floatname{algorithm}{算法} \renewcommand{\algorithmicrequire}{\textbf{输入:}} \renewcommand{\algorithmicensure}{\textbf{输出:}} \begin{document} \begin{algorithm} \caption{用归并排序求逆序数} \begin{algorithmic}[1] %每行显示行号 \Require $Array$数组,$n$数组大小 \Ensure 逆序数 \Function {MergerSort}{$Array, left, right$} \State $result \gets 0$ \If {$left < right$} \State $middle \gets (left + right) / 2$ \State $result \gets result +$ \Call{MergerSort}{$Array, left, middle$} \State $result \gets result +$ \Call{MergerSort}{$Array, middle, right$} \State $result \gets result +$ \Call{Merger}{$Array,left,middle,right$} \EndIf \State \Return{$result$} \EndFunction \State \Function{Merger}{$Array, left, middle, right$} \State $i\gets left$ \State $j\gets middle$ \State $k\gets 0$ \State $result \gets 0$ \While{$i<middle$ \textbf{and} $j<right$} \If{$Array[i]<Array[j]$} \State $B[k++]\gets Array[i++]$ \Else \State $B[k++] \gets Array[j++]$ \State $result \gets result + (middle - i)$ \EndIf \EndWhile \While{$i<middle$} \State $B[k++] \gets Array[i++]$ \EndWhile \While{$j<right$} \State $B[k++] \gets Array[j++]$ \EndWhile \For{$i = 0 \to k-1$} \State $Array[left + i] \gets B[i]$ \EndFor \State \Return{$result$} \EndFunction \end{algorithmic} \end{algorithm} \end{document} XeLateX编译器(未报错):

LeetCode第288场周赛

📒博客首页:崇尚学技术的科班人 🍣今天给大家带来的文章是《LeetCode第288场周赛》🍣 🍣希望各位小伙伴们能够耐心的读完这篇文章🍣 🙏博主也在学习阶段,如若发现问题,请告知,非常感谢🙏 💗同时也非常感谢各位小伙伴们的支持💗 文章目录 🚀<1> 第一题🚀✨题目✨✨示例✨✨提示✨⭐思路⭐✨代码实现✨✨运行结果✨ 🚀<2> 第二题🚀✨题目✨✨示例✨✨提示✨⭐思路⭐✨代码实现✨✨运行结果✨ 🚀<3> 第三题🚀✨题目✨✨示例✨✨提示✨⭐思路⭐✨代码实现✨✨运行结果✨ 前言:好久没有打周赛了,本来以为手会有点生,但是还是 a了3道,最后一题过了两个样例,本来以为要 AK 了,但还是 WA 了 。有点遗憾 😫😫。不过排名上升了不少,不知道能不能加大分。废话不多说,直接上题目。 🚀<1> 第一题🚀 ✨题目✨ 按奇偶性交换后的最大数字 给你一个正整数 num 。你可以交换 num 中 奇偶性 相同的任意两位数字(即,都是奇数或者偶数)。 返回交换 任意 次之后 num 的 最大 可能值。 ✨示例✨ 示例1: 输入:num = 1234 输出:3412 解释:交换数字 3 和数字 1 ,结果得到 3214 。 交换数字 2 和数字 4 ,结果得到 3412 。 注意,可能存在其他交换序列,但是可以证明 3412 是最大可能值。 注意,不能交换数字 4 和数字 1 ,因为它们奇偶性不同。 示例2: 输入:num = 65875 输出:87655 解释:交换数字 8 和数字 6 ,结果得到 85675 。 交换数字 5 和数字 7 ,结果得到 87655 。 注意,可能存在其他交换序列,但是可以证明 87655 是最大可能值。 ✨提示✨ 1 <= num <= 109 ⭐思路⭐ 思路 其实周赛第一题的数据范围啥的都不会太大,所以说你暴力的话是基本上都能过的。这道题是签到题,我的做法就是模拟这个过程,我们先将 奇数和偶数 进行分离,在分离的过程中我们需要记录下对应的原数中奇数偶数所在的位置,然后进行排序。然后按照对应的原数中奇偶数位置进行放置,记得大的要放在前面,这样才能保证结果最大。

lotus miner 元数据 删除 重建

lotus miner 元数据重建 主网 lotus-miner backup测试网模拟lotus-miner元数据损坏,重建指定原来的矿工号重新初始化环境变量配置miner API运行 lotus-worker修改LevelDB扇区ID 从27开始修改nextid 大的数字参考 主网 lotus-miner backup Backup and restore 测试网模拟lotus-miner元数据损坏,重建 # echo $LOTUS_MINER_PATH /raid0/calibnet/miner 删除miner目录下所有内容 # rm -rf /raid0/calibnet/miner/* 指定原来的矿工号重新初始化 lotus-miner init --no-local-storage --actor=t矿工号 --owner=t3钱包 --sector-size=32GiB 运行miner nohup lotus-miner run >> /var/log/calibnet/miner.log 2>&1 & lotus-miner info 修改lotus-miner配置文件config.toml 和storage.json lotus-miner stop # cat $LOTUS_MINER_PATH/config.toml | grep -Ev '^$|#' [API] ListenAddress = "/ip4/192.168.1.92/tcp/2345/http" RemoteListenAddress = "192.168.1.92:2345" [Backup] [Libp2p] [Pubsub] [Subsystems] [Dealmaking] [Dealmaking.RetrievalPricing] [Dealmaking.RetrievalPricing.Default] [Dealmaking.RetrievalPricing.External] [Sealing] BatchPreCommits = false AggregateCommits = false [Storage] AllowAddPiece = false AllowPreCommit1 = false AllowPreCommit2 = false AllowCommit = false AllowUnseal = false [Fees] [Fees.

Vue——页面监听事件(窗点击页面弹外关闭)

描述:我的需求图下:点击按你牛后显示pdf弹窗,点击弹窗外围影藏弹窗。分两个点: 1:pdf弹窗的创建。 2:显示pdf弹窗,创建监听事件(监听页面点击,执行后隐藏弹窗同时取消监听事件)。 安装pdfObject:过程简单直接:npm i pdfobject --save 创建pdf弹窗代码如下: <div ref='pdfDiv' id='pdfBox' class="pdf-box" v-show="showPdfBox"></div> 样式: .pdf-box{ background-color: #003366; position: fixed; top: 0; left: 0; transform: translate(50%, 50%); z-index: 2; width: 54.8vw; height: 52vh; } 事件: // 显示弹窗并加载文档 funcProjectFile(event){ //阻止冒泡 event || (event = window.event); event.stopPropagation ? event.stopPropagation() : (event.cancelBubble = true); this.funcInitProjectPage(); this.butIndex = 1; this.childButIndex = 12; this.showPdfBox = true; // 加载pdf文档 #pdfBox对应上面 PDFObject.embed("https://pdfobject.com/pdf/sample-3pp.pdf", "#pdfBox"); document.addEventListener('click', this.hidePanel, false); }, // 关闭弹窗点击监听 hidePanel(e) { console.

QComboBox使用讲解

简介 QComboBox提供了一种向用户呈现选项列表的方式,以占用最少的屏幕空间。 组合框是一个显示当前项目的选择小部件,可以弹出可选择项目的列表。 组合框可以是可编辑的,允许用户修改列表中的每个项目。 QComboBox 除了显示可见下拉列表外,每个项(item,或称列表项)还可以关联一个 QVariant 类型的变量,用于存储一些不可见数据。 效果 常用Api 添加item 两个重载addItem() 函数,第二个版本可以添加图标,两个函数都有一个可选的 QVariant 类型的参数 userData,可以利用这个变量存储用户定义数据。 void addItem (const QString &text, const QVariant &userData = QVariant()) void addItem (const QIcon &icon, const QString &text, const QVariant &userData = QVariant()) 也可以在Ui设计界面添加设置item 访问QComboBox 列表项 int currentlndex():返回当前项的序号,第一个项的序号为0。 QString currentText():返回当前项的文本 QVariant currentData(int role = Qt::UserRole):返回当前项的关联数据 QString itemText(int index) 返回指定索引号的项的文本 QVariant itemData(int index, int role = Qt%:UserRole) 返回指定索引号的项的关联数据。 int count():返回项的个数。 当前项改变信号 在一个 QComboBox 组件上选择项发生变化时,会发射如下信号:

Linux——更改文件及目录权限(d rwx r-x r-x字段详解+更改代码指令)

目录 一、d rwx r-x r-x .字段详解: 二、Chmod (更改文件所属组权限) (1)指令讲解: (2)实列:让其他用户对test.txt文件增加写的权限 三、改变文件的所属者,所属组权限 四、赋权法(修改权限) (1)讲解: (2)实列: 权限 :文件或目录属于谁 , 属于哪个组 , 不同用户能对该文件进行何种操作(建 立一个文件和一个目录) 查看文件权限 ls -l 文件 查看目录权限 ls -ld 目录 —————————————————————————————————————————————————————————— 一、d rwx r-x r-x .字段详解: -rw-r--r-- d rwx r-x r-x . 字段 1:表示文件类型 -:普通文件 d :目录 l: 符号链接 b:块设备 (硬件存储设备) c:字符设备文件 p:管道文件 字段 2:文件所属者对该文件的权限 字段 3:文件所属组的权限 (若 tom 属于 root 组 举例) 字段 4:其他用户的权限(既不是文件所有者也不是文件所属组的用户) 字段 5:不重要,表示这个文件受 selinux(标签工具)的管理 ———————————————————————————————————————————————————————— 二、Chmod (更改文件所属组权限) (1)指令讲解: chmod 对象 算数运算符 权限 文件

AFL++ (PlusPlus) 介绍与实践

文章目录 一、AFL++简介缝合块AFL基础款1 基于覆盖率指标的反馈2 变异3 fork 服务器 基于智能调度的加强版1 AFLFast2 MOpt 基于绕过障碍的加强版1 [LAF-Intel](https://lafintel.wordpress.com/)2 RedQueen 变异结构化输入AFLSmart 缝合怪AFL++种子调度变异器1 自定义变异器API2 Input-To-State 变异器3 MOpt Mutator 插桩1 LLVM2 GCC3 QEMU4 Unicornafl5 QBDI 二、AFL++使用示例准备libxml2工具xmllint的初始化启用 本文系原创,转载请说明出处:信安科研人 关注微信公众号 信安科研人,获取更多网安资讯 一、AFL++简介 AFL++ 结合现今所有基于AFL框架改进方案,形成一个整体,即取其精华,去其糟粕,形成一款终极版AFL——AFL++。 下面以AFL基础款框架的几个部分,分别介绍AFL++结合了哪些改良部分。 缝合块 AFL基础款 AFL 是一款基于突变的、覆盖率引导的FUZZer。 它改变一组测试用例以达到程序中以前未探索的代码。覆盖率发生变化时,触发新覆盖率的测试用例将保存为测试用例队列的一部分。 1 基于覆盖率指标的反馈 AFL的覆盖率,计算在一次运行中,相应边执行的次数,次数单位为2的幂(以缓解路径爆炸)。如果一个用例输入发现了至少一条边,也就是创建一个新的桶来装入新的边的次数,那么这个用例就是interesting用例,并放入队列。AFL用一个bitmap把这些装有边次数的桶整合起来,一个byte代表一条边。 2 变异 AFL 的突变分为两类:确定性突变和破坏性突变。 确定性阶段包括对测试用例内容的单一确定性突变,例如位翻转、加法、用一组常见有趣值(例如 -1、INT_MAX、…)中的整数替换等。 在破坏变异中,突变是随机堆叠的,并且还包括对测试用例大小的更改(例如,添加或删除部分输入用例)。 3 fork 服务器 原理是每当AFL执行一个测试用例时,AFL都会将输入用例写入使用IPC机制控制的forkserver中的目标程序。也就是说,父进程fork出一个子进程执行输入用例,父进程等待结果。这样可以避免频繁调用execve()函数。 但是,fork也会有性能瓶颈的问题,AFL提出persistent mode,该模式下不会为每个测试用例fork。 取而代之的是,可以将循环的方式添加到目标程序中,也就是每次迭代执行一个测试用例。 基于智能调度的加强版 现代覆盖率引导的FUZZer可以实现不同的优先级算法来调度模糊测试工具队列中的各种元素。 调度程序的目标通常是通过智能的测试用例选择来提高整体覆盖率和错误检测。 1 AFLFast AFLFast的特点是,更注重对低频的路径的探索,低频的路径是指,在模糊测试中测试用例很难或者是很少到达的路径,AFLFast发明了一种方式,让AFL基础款的测试用例生成更注重程序中的低频路径。一共提出两种问题: 为了注重低频路径,fuzzer 应该按什么顺序挑选种子?可以调整每个种子生成的输入量吗? 解决了这两个问题基本上就能改变测试用例的生成方向。 2 MOpt 至于种子调度的横向问题,MOPT引入了变异调度。 这项工作探索了使用自定义粒子群优化算法为变异算子赋予不同概率的可能性。这种优化提高了FUZZer 发现覆盖范围的能力。MOPT中的AFL 的补丁中,作者将模糊测试阶段分为以下两个模块:Pilot模块根据测试用例产生的效率分配可能性;Code 模块对测试用例进行变异,并考虑用例在Pilot期间产生的可能性。

Java基础之数组与List之间的互相转换(常见的几种方式,一看就懂)

Java基础之数组与List之间的互相转换 1. List转数组1.1 方式一:toArray()1.2 方式二:list.toArray(new String[list.size()])1.3 方式三:list.stream().toArray()1.4 方式四:list.stream().toArray(String[]::new);1.5 方式五: 2. 数组转List2.1 方式一:Arrays.asList(strS)2.2 方式二:new ArrayList<>(Arrays.asList(strS))2.3 方式三:使用 Stream2.4 方式四:Collections.addAll(list,strS); 3. 附测试代码3.1 list 转数组的代码3.2 数组转list的代码 4. 另:数组和集合的遍历 1. List转数组 这些东西都是简单易懂,就是容易忘记,所以下面介绍都是直接给代码 1.1 方式一:toArray() 1.2 方式二:list.toArray(new String[list.size()]) 1.3 方式三:list.stream().toArray() 1.4 方式四:list.stream().toArray(String[]::new); 下面的 String[]::new 这种写法是Java8的新特性,不明白的自己可以下去看看Java新特性,下面我们的方式五是替换这种方法,方便大家的理解 1.5 方式五: 这种方式很少用,我们写出来主要是为了理解:上面方式四 list.stream().toArray(String[]::new); 的这种写法,看完之后应该明白,String[]::new 其实是调用了构造方法,还不是很清楚的,自己下去看看源码再了解一下Lambda表达式就明白了。 2. 数组转List 2.1 方式一:Arrays.asList(strS) 需要注意:不能对List进行增删操作 2.2 方式二:new ArrayList<>(Arrays.asList(strS)) 2.3 方式三:使用 Stream 2.4 方式四:Collections.addAll(list,strS); 3. 附测试代码 3.1 list 转数组的代码 package com.liu.susu.base.coollection.array; import org.junit.Test; import java.util.ArrayList; import java.

opencv(c++)从入门到放弃1.0-环境配置

说明 做了几年机器视觉,多是用sherlock和visionpro、halcon做做应用。忽然之间想学学opencv来充点电,这开始开始记录我的学习路程。 正文 1、下载opencv,并且配置好环境变量 地址:Releases - OpenCV 2、打开vs(我这是vs2022版本),新建c++项目,选择项目打开属性编辑 3、配置项目环境 1>配置可执行目录 2>配置包含目录 3>配置库目录 4>配置动态连接库,注意带d是debug版本,如果你编译的是release版本,选择不带d后缀的 4、测试 。用以下代码测试: #include <iostream> #define _CRT_SECURE_NO_WARNINGS #include <opencv2/opencv.hpp> #include <iostream> #include <math.h> using namespace std; using namespace cv; int main() { Mat src; src = imread("C:\\Users\\Admin\\Desktop\\buffer\\1.jpg");//图像文件路径 if(src.empty()) { cout << "could not load image..." << endl; return -1; } imshow("src", src); waitKey(0); return 0; } 另外附加两个我认为很有价值的链接: vs2019+cuda10.1+opencv4.1+opencv_contrib4.1 加速的opecv(含扩展库)环境配置_ 蜗牛在听雨的博客-CSDN博客 VS2019+OpenCV3.4.1_vc14vc15配置简介(防忘记)_GY-赵的博客-CSDN博客

unigui美化界面源码框架

对于delphier来说,顺应互联网时代,用delphi开发web程序,一直是一个很头痛的问题,以往开发delphi程序往往不需要前端和美工参与。但在ui界面上要想漂亮,需要配合和学习css、JS和美工知识,所以很多人会放弃。unigui是一个非常好的web的控件,由土耳其人开发,一直在持续更新,至今已经有超过10年的历程,和delphier原生框架一样,拖放控件就能实现web快速开发,并且性能出色,完全符合delphier的开发习惯。默认界面也相对原始的delphi和interweb类控件来说,也是相当美观。不过虽然进度很大,但是毕竟是优先符合国外人的审美,还是和国内流行的web设计风格还是有一定的差距。我花了大量的时间,修改了unigui控件的样式,并从实际案例中拆出来几个模块,写了这个web美化框架,简单修改就直接用来web管理类软件的做产品,常见的unigui需要用到的使用方法,以及界面修改细节都能在本源码里面找到参考,因为不需要安装第三方控件,对近二年来的unigui和delphi的各版本都可以完美支持。(注:本框架非管理软件,只是框架源码) 已经实现的内容: 全局控件样式修改 动态创建tab标签载入子页面 百度图表使用(第三方组件) 左侧手风琴导航(基于uniTreeview) 自动适应浏览器宽度 等分比例布局 窗体弹出动画 消息框动画 多网页的参数的传递 网址url参数传递 uniDbGrid导出到表格下载 uniDbGrid右侧增加操作按钮 UniDbGrid金额列统计,指定条件着色 登录图形验证码 浏览器类型获取 浏览器按键控制 文件下载 图片上传预览 设置指定上传接收路径 Cookie的使用 Js交互的使用 css美化的使用 公用执行的Db数据库操作函数过程 在实际项目中检验过的Server模块各项参数配置 链接跳转到网站 错误和超时提示汉化 超时自动重启浏览器端 发布运行库设置 欢迎加我QQ交流:21968578

论文翻译:2021_Performance optimizations on deep noise suppression models

Python微信订餐小程序课程视频 https://blog.csdn.net/m0_56069948/article/details/122285951 Python实战量化交易理财系统 https://blog.csdn.net/m0_56069948/article/details/122285941 目录 摘要1 引言1.1 贡献2 相关工作2.1 深度噪声抑制2.2 模型压缩3 实验方法4 通过修剪架构搜索进行性能优化5 结果5.1 烧蚀研究5.2 微调的价值5.3 稀疏性并不意味着推理加速6 结论7 参考 论文地址:深度噪声抑制模型的性能优化 引用格式:Chee J, Braun S, Gopal V, et al. Performance optimizations on deep noise suppression models[J]. arXiv preprint arXiv:2110.04378, 2021. 摘要 我们研究了量级结构剪枝以加快深度噪声抑制(DNS)模型的推理时间。尽管深度学习方法在提高音频质量方面取得了显著的成功,但它们增加的复杂性阻碍了它们在实时应用中的部署。我们在基线上实现了7.25倍的推理加速,同时平滑了模型的性能退化。消融研究表明,我们提出的网络再参数化(即每层尺寸)是加速的主要驱动因素,而量级结构剪枝与直接训练较小尺寸的模型相比具有相当大的作用。我们报告推理速度,因为参数减少并不需要加速,并且我们使用精确的非侵入性客观语音质量度量来度量模型质量。 关键词:语音增强,降噪,实时,推理加速,结构化剪枝 1 引言 在压缩深度学习方法方面已经做了很多工作,以便它们能够在许多音频增强应用的实时和硬件约束下有效地运行[1,2,3,4]。这种兴趣源于这样一个事实,即深度学习方法虽然通常提供卓越的音频增强,但与经典信号处理方法[1]相比,其计算复杂度更高。在实时应用程序中,计算复杂度成为主要约束。每个设备的可用内存不同,但每次计算的可用时间不变。因此,我们在推理速度方面测量和展示我们的压缩结果。计算内存或参数减少不是一个精确的代理-参见5.3节。 我们研究了结构化剪枝和微调的应用,以加速我们的基线CRUSE模型[1]。结构化剪枝的目的是寻找一个能很好地逼近原始网络的稠密子网络。这种类型的模型压缩立即转换为推理加速和降低存储成本,因为我们执行的是密集和更小的矩阵乘法。此外,我们为CRUSE体系结构类提出了一种新的可伸缩的每层参数配置,以指定经过修剪的网络大小。 1.1 贡献 使用 CRUSE [1] 架构,我们展示了比基线模型最高 7.25 倍的加速,模型质量平稳下降。 消融研究表明,所提出的网络参数配置实际上是成功的可扩展性的原因。 我们的结构化剪枝方法并不比直接训练给定大小的模型更好。 结构化修剪的价值在于架构搜索:发现哪些网络参数化可以以最小的模型退化降低模型复杂性。 2 相关工作 Tan 和 Wang [3, 4] 使用稀疏正则化、迭代修剪和基于聚类的量化来压缩 DNN 语音增强模型。 然而,他们使用 STOI 和 PESQ [5] 来评估压缩后的质量,这已被证明与主观质量的相关性较低 [6, 7](这个,STOI相关度较低,但是PESQ相关度还是可以的,并且几乎所有的语音增强论文都在使用PESQ,作者这里直接否定我很反对)。 此外,没有给出运行时基准来显示实际改进,使用的噪声抑制模型相对简单且不是最先进的(这样贬低别人的论文,也不会凸出你的论文有多优秀,不都是CNN和LSTM等一些神经元的组合吗?再说你的模型也没有跟人家的模型进行性能对比呀),训练和测试集也很简单。 因此,从这项研究中还不清楚,在一个更具挑战性的测试集(如[7])上,什么样的优化在一个一流的噪声抑制器上工作得很好。

Spring Cloud Config

文章目录 概述搭建 Spring Cloud Config Server创建 Git 仓库引入依赖配置文件ConfigServerApplicationHTTP 接口 使用 Spring Cloud Config Client引入依赖配置文件OrderPropertiesDemoControllerUserApplication 多环境配置修改 Git 仓库 Spring Cloud Config采用Git存储时两种常用的配置策略自动配置刷新使用/actuator/refresh 接口:搭建 Spring Cloud Config Server搭建 Spring Cloud Config Client引入依赖配置文件@RefreshScope 基于 Spring Cloud Bus 实现搭建 Spring Cloud Config Server引入依赖配置文件 搭建 Spring Cloud Config Client引入依赖配置文件@RefreshScope 基于监听器LoggingRebinderDemoEnvironmentChangeListener 配置加密搭建 Spring Cloud Config Server安装 JCE配置文件EncryptionController 搭建 Spring Cloud Config Client非对称加密 与注册中心集成Spring Cloud Config ServerSpring Cloud Config Client 概述 Spring Cloud Config 是由 Spring Cloud 官方推出,基于 Spring Cloud 体系的配置中心。

Vmware16安装MacOS10.15图文(VIP典藏版)

Vmware16下载安装与五种ISO镜像详细图文(2021) 五种系统镜像详细图文 VMware安装Windows10图文VMware安装MacOS10.14图文Vmware16安装MacOS10.15图文VMware安装Centos图文VMware安装Deepin图文VMware安装Ubuntu Kylin图文 目录 一、Vmware16支持MacOS插件 二、安装步骤 1、选中cdr镜像文件 2、选择系统 3、指定磁盘容量 4、自定义硬件-完成-启动虚拟机 5、继续下一步 三、提示:请选择您要安装的macOS的磁盘 1、发现安装没有磁盘,且按钮为灰色 2、详细解决方案图文: 3、继续下一步 4、MacOS欣赏 一、Vmware16支持MacOS插件 下载插件与使用 Vmware16支持MacOS 二、安装步骤 1、选中cdr镜像文件 2、选择系统 3、指定磁盘容量 4、自定义硬件-完成-启动虚拟机 5、继续下一步 三、提示:请选择您要安装的macOS的磁盘 1、发现安装没有磁盘,且按钮为灰色 2、详细解决方案图文: Vmware请选择您要安装的macOS的磁盘 3、继续下一步 4、MacOS欣赏 有用请点赞,养成良好习惯! 疑问交流鼓励请留言!

虚拟机安装Windows10图文(VIP典藏版)

五种系统镜像创建 Vmware16下载安装与五种ISO镜像详细图文(2021) 五种系统镜像详细图文 VMware安装Windows10图文VMware安装MacOS10.14图文Vmware16安装MacOS10.15图文VMware安装Centos图文VMware安装Deepin图文VMware安装Ubuntu Kylin图文 目录 一、下载windows镜像 1、itellyou下载 2、423down直接下载原版镜像 二、安装Windows镜像 1、新建虚拟机(典型) 2、稍后安装操作系统 3、选择客户机操作系统 4、命名虚拟机 5、指定磁盘容量和虚拟磁盘存储方式 6、自定义硬件:选择ISO镜像文件 7、点击完成后,开启此虚拟机 8、安装页面 9、安装页面 三、效果 一、下载windows镜像 1、itellyou下载 https://msdn.itellyou.cn/ 使用迅雷打开链接即可 ed2k://|file|cn_windows_10_business_editions_version_1909_x64_dvd_0ca83907.iso|5275090944|9BCD5FA6C8009E4D0260E4B23008BD47|/ 本站由I tell you站长私人出资搭建,还有各种资源方便大家下载,有条件的可以打赏下~ 2、423down直接下载原版镜像 https://www.423down.com/ 二、安装Windows镜像 1、新建虚拟机(典型) 2、稍后安装操作系统 3、选择客户机操作系统 4、命名虚拟机 5、指定磁盘容量和虚拟磁盘存储方式 6、自定义硬件:选择ISO镜像文件 7、点击完成后,开启此虚拟机 8、安装页面 9、安装页面 三、效果 有用请点赞,养成良好习惯! 疑问交流鼓励请留言!

即插即用的轻量注意力机制ECA--Net

论文名:ECA-Net: Effificient Channel Attention for Deep Convolutional Neural Networks 论文:https://arxiv.org/abs/1910.03151 开源代码:https://github.com/BangguWu/ECANet 首先上结果图,看着真香!!! 如图1 纵坐标为准确性,横坐标为模型参数量(类似空间复杂度) 0.论文摘要 最近,通道注意力机制被证明在改善深度卷积神经网络(CNNs)的性能方面具有巨大的潜力。然而,现有的方法大多致力于开发更复杂的注意力模块,以实现更好的性能,这不可避免地增加了模型的复杂性。为了克服性能和复杂性之间的矛盾,本文提出了一种有效的通道关注(ECA)模块,该模块只增加了少量的参数,却能获得明显的性能增益。通过对SENet中通道注意模块的分析,作者的经验表明避免降维对于学习通道注意力非常重要,适当的跨信道交互可以在显著降低模型复杂度的同时保持性能。因此,作者提出了一种不降维的局部跨信道交互策略,该策略可以通过一维卷积有效地实现。进一步,作者又提出了一种自适应选择一维卷积核大小的方法,以确定局部跨信道交互的覆盖率。 实验证明,本文提出的ECA模块是高效的(上图)。 本文模块(ECA)相对于ResNet50的主干的参数和计算分别是80M比24.37M和4.7e-4 GFLOPs比3.86 GFLOPs,并且性能在Top-1精度方面提升超过2%。本文以ResNets和MobileNetV2为骨干,利用提出的ECA模块在图像分类、目标检测和实例分割方面进行了广泛的评估。实验结果表明,该模块在性能上优于其他模块,且具有较高的效率。 ECA模块与其他注意力模块的比较:这里以ResNets作为骨干模型来进行分类精度,网络参数和FLOPs的比较,以圆来表示。从上图可以看出 一.论文简介(introduction) 深度卷积神经网络(CNNs)在计算机视觉领域得到了广泛的应用,在图像分类、目标检测和语义分割等领域取得了很大的进展。从开创性的AlexNet开始,为了进一步提高深度cnn的性能,不断推出新的CNN模型。近年来,将通道注意力引入卷积块引起了人们的广泛关注,在性能改进方面显示出巨大潜力。其中代表性的方法是SENet,它可以学习每个卷积块的通道注意力,对各种深度CNN架构带来明显的性能增益。SENet主要是 squeeze 和 excitation 两大操作,最近,一些研究通过捕获更复杂的通道依赖或结合额外的空间注意来改进SE块。这些方法虽然取得了较高的精度,但往往带来较高的模型复杂度和较大的计算负担。与前面提到的以更高的模型复杂度为代价来获得更好性能的方法不同,本文转而关注一个问题:能否以更有效的方式学习有效的通道注意力? 为了回答这个问题,我们首先回顾一下SENet中的通道注意模块。具体来说,在给定输入特征的情况下,SE块首先对每个通道单独使用全局平均池化,然后使用两个具有非线性的完全连接(FC)层,然后使用一个Sigmoid函数来生成通道权值。两个FC层的设计是为了捕捉非线性的跨通道交互,其中包括降维来控制模型的复杂性。虽然该策略在后续的通道注意模块中得到了广泛的应用,但作者的实验研究表明,降维对通道注意预测带来了副作用,捕获所有通道之间的依赖是低效的,也是不必要的。 SE-net: 由上图可知:第一个FC层进行降维(通道数从C--->C/r),第二个FC层又进行了升维(通道数从C/r---->C) 因此,本文提出了一种针对深度CNN的高效通道注意(ECA)模块,该模块避免了降维,有效捕获了跨通道交互的信息。如下图2所示: 本文在全局平均池化之后不降低通道的维数,通过考虑每个通道及其k个邻居进行局部跨通道交互信息。实践证明,该方法保证了模型效率和计算效果。需要注意的是,ECA可以通过大小为k的快速1D卷积来有效实现,其中卷积核大小为k代表了局部跨信道交互的覆盖率,即,该通道附近有多少邻居参与了这个信道的注意力预测,为了避免通过交叉验证对k进行手动调优,本文提出了一种方法来自适应地确定k,其中交互的覆盖率(即卷积核大小 k)与通道维数成正比。 本文的贡献如下: 对SE模块进行了剖析,并分别证明了避免降维和适当的跨通道交互对于学习高性能和高效率的通道注意力是重要的。在以上分析的基础上,提出了一种高效通道注意模块(ECA),在CNN网络上提出了一种极轻量的通道注意力模块,该模块增加的模型复杂度小,提升效果显著。在ImageNet-1K和MS COCO上的实验结果表明,本文提出的方法具有比目前最先进的CNN模型更低的模型复杂度,与此同时,本文方法却取得了非常有竞争力的结果。 二.提出的方法 在本节中,我们首先重新回顾SENet[14]中的通道注意模块(即SE块)。然后,我们通过分析降维和跨通道交互作用的影响,对SE块进行了实验判断。这促使我们提出我们的ECA模块。此外,我们还开发了一种自适应确定ECA参数的方法,并最后展示了如何将其用于深度cnn。 SE模块的通道注意力通过如下式1计算: 接下来介绍一下ECA的模块,首先由公式2: 为了验证它的效果,作者比较了原始SE块和它的三个变体(即 SE-Var1, SE-Var2和SE-Var3),所有这些都没有进行降维操作。具体效果如下表2所示: 表2 SE以及ECA结果图 对SE进行探索 2.1Avoiding Dimensionality Reduction(避免降维) 为了验证其效果,我们将原始的SE块与它的三个变体(即SE-Var1、SE-Var2和SE-Var3)进行了比较,所有这些变体都不执行维度回归。如上表2所示,没有参数的SE-Var1仍然优于原始网络,说明通道注意能够提高深度cnn的性能。同时,SE-Var2可以独立学习各通道的权重,略优于SE块。这可能表明:通道及其权重需要直接对应,同时避免双敏感性降低比考虑非线性信道依赖性更重要。此外,使用一个单一FC层的SEVar3比在SE块中降维的两个FC层性能更好。以上所有的结果都清楚地表明,避免降维有助于学习有效的通道注意,提高准确度。 2.2Local Cross-Channel Interaction(局部跨通道交互) 对于SE-Var2、SE-Var3,权重式分别为: 两者之间区别在于,SE-Var3考虑了不同通道之间的交互(全局跨通道交互),SE-Var2则没有(因为Wvar2是一个对角矩阵);但是SE-Var3的需要大量参数,这样复杂性较高。 作者为了综合上述两个方面的优点,将SE-Var2+SE-Var3→ 块对角矩阵。(如下所示 局部跨通道交互) Wvar3相当于 W1G, W2G, W2G,........(局部跨通道交互,表2中SE-GC1,2,3系列) 其中,上式WG将通道C划分为G组,每个组包括C/G通道,并独立学习每个组中的通道注意,以局部方式进行跨通道交互。因此,它涉及到C^2/G个参数。从卷积的角度来看,SE-Var2,SEVar3和上式可以分别看作是一个深度可分离的卷积、一个FC层和组卷积(SE-GC)。然而,由上表2可以看出,(SE-GC1,2,3系列)这样做并没有给SE-Var2带来增益,表明它这样做局部通道交互不能捕获局部通道之间的相互作用,而且过多的组卷及将层架内存访问成本,从而降低计算效率。 SE-GC1,2,3系列不起作用的原因可能SE-GC完全抛弃了不同组之间的依赖关系。 2.3 ECA模块 为此我们探索了另一种捕获局部跨通道交互的方法(ECA模块),旨在保证信息效率和有效性。具体地说,我们使用了一个频带矩阵Wk来学习信道注意,而Wk已经有了(如下式6) 其中,Wk涉及K*C个参数,并且Wk避免了不同group的完全独立,正如在上表2中所示,本文提出的这种方法叫做ECA-NS,他比SE-GC性能要更优。对于yi对应的权重w11,w12....w1k,本文只考虑yi和它的k个邻居之间的信息交互,计算公式如下: 为了进一步提高性能,还可以让所有的通道共享权重信息,即:通过共享相同的学习参数,通过内核大小为k的1维卷积来实现通道之间的信息交互:(一维卷积和1 × 1 卷积是不同的,一维指的是1 × k 的卷积)

详解BFC

首先我们来介绍一下BFC得概念 BFC是一个块级格式化上下文,它是指一个独立得块级渲染区域,只有Block-level BOX参与,该区域拥有一套属于自己得渲染和规则来约束块级盒子得布局,且与区域外部无关。 总而言之: BFC是一个独立渲染区域,它丝毫不会影响到外部元素 是不是听起来很懵,我来解释一下,就是一个区域里面我们发现一些样式得错误,我们本来想得到得样式,却因为一些原因没有得到我们所想要得效果,这边主要是在css层面上得样式没有达到得效果。 那么我们当时是这么发现应该具备BFC这个概念得呢? .sonm{ width: 300px; height: 300px; float: left; background-color: aquamarine; } <div class="fartherm"> <div class="sonm"></div> <div class="sonm"></div> <div class="sonm"></div> </div> 通过这段代码我们可以得到 像这样子得浮动,这里都显而易见, 那么我们看一xia父元素那边长宽 你会发现父元素只有宽度而没有高度,所以这里我们就得到了为什么会使用BFC得初衷 那么我们就该讲解使用BFC得方法了 总共有四种方法(俗称创建BFC) 1.使用position:absolute得方法 2.overflow-hiden(最好得方法) 3.float:left 4.dispaly:inline-block 那么我们在父元素那边随机创建一个BFC我们就可以看到父元素具备了高度 而BFC主要是出现在以下两个方面出错 1.产生高度塌陷得时候 .farther{ width: 200px; height: 400px; background-color: aqua; } .son{ width: 100px; height: 200px; background-color: blue; margin-top: 20px; } <div class="farther"> <div class="son"></div> </div> 以上代码显示得样式为 你会发现这里并没有我们所需要得son距离farther有margin向上30px得高度,这时候就是高度塌陷 我们所使用得方法一样是创建一个BFC来阻止高度塌陷,我就用推荐得方式:overflow:hidden;(写在父元素得位置上) 就会得到以下样式 那么高度塌陷就会消失,得到我们想要得效果 2.阻止浮动得元素被覆盖 .sons{ width: 200px; height: 300px; background-color: blueviolet; float: left; } .