Allegro PCB导入网表错误

引言 Cadence16.6软件进行电路板的设计时,从PCB到原理图的过程中,可能会遇到网表导入失败的问题。 1、问题出现 我是开始导入正常,且正常布局布线完成后进行DRC检查时出现报错: #1 ERROR(24) File not found 2、分析问题 该错误提示没有找到文件。我这时想到我的原理图在layout过程中修改了命名,且修改了原理图及PCB所在文件夹名称。 3、解决问题 将最新的.DSN文件导出网表,重新导入PCB。问题就被解决了。 这里主要注意的点:Import directory一定要选择到网表所在的最后一级文件目录;

js金额转换万元显示

methods: { formatNumber(num) { num = Number(num); if (num == 0) { return num + ""; } else { if ((num / 10000).toFixed(2) == 0) { //小于100的保留2位 return (num / 100).toFixed(4) } else { // parseFloat() 去掉后面不用的0,如50.00 //大于100的保留2位 return parseFloat((num / 10000).toFixed(2)) + '万' } } }, } 或者 formatNumber(value) { const k = 10000 const sizes = ['', '万', '亿', '万亿'] let i = undefined let str = '' if(value < k) { str = value } else { i = Math.

list列表,tuple元组,dictionary字典

# list列表 list1 = [1, 2, 3, 4, 5, 6] # pop()代表删除列表最后一个元素,pop(i)代表删除索引i的元素 # list1.pop() # insert()代表在列表索引i处添加j # list1.insert(5, 7) # append()代表列表末尾添加元素 # list1.append(7) # sort()排序 # reverse()反转 # remove(i)代表代表删除列表中的i # list1.remove(6) # print(list1) # tuple元组(不能删除元素) tuple1 = (1, 2, 3) list1 = list(tuple1) list2 = [1, 2, 3] tuple2 = tuple(list2) print(tuple2) print(list2) # dictionary dict1 = {'name': "Link", 'height': 173, 'weight': 140} dict1["gender"] = "male" print(dict1.keys()) print(dict1.values()) print(dict1) dict1.

只需根据接口文档,就能轻松开发 get 和 post 请求的脚本,你会做吗?

一般的接口文档描述的内容: 开发get请求的脚本,接口文档的描述如下: 在loadrunner里面创建一个空脚本: 在action空白处,点击insert—>step 输入web_custom_request,双击选择该函数,填入如下几个参数值: 生成的脚本如下: 运行编译,看有没有语法错误: 在日志里面看到返回了code=0,说明接口请求是成功的,在这里不要关注返回的乱码信息 是不是觉得get请求的脚本很容易搞定了,接下来看post请求的,还是用上面的函数完成。 用post请求开发登录接口的脚本:文档说明如下,参数很少。 填入如下的值: 生成的脚本内容如下: 编译运行脚本,看日志信息:日志级别需要调整到如下级别 脚本都已经成功开发完了,那么是不是有一个问题?在跑场景的时候,怎么知道我的脚本一直都是成功的呢? 是不是有一些小伙伴在平时的脚本运行的时候,脚本都没有报错,但是实际插入到数据库的数据没有增加的情况? 这个问题肯定很多小伙伴都遇到过,那怎么办呢? 就是需要对脚本的返回值进行if判断,当成功的时候,就pass,失败了就fail,这样事务也会自动的去统计成功或失败 先来在脚本中添加事务 开始事务 结束事务 if判断要怎么写呢? 回到刚才回放的日志里面,用之前讲过的关联的方法,双击code=0这一行 web_reg_save_param("code", //变量的名称 "LB=\"code\":", //左边界值,双引号需要加上转义符 "RB=,", //右边界值 "Ord=1", //多个值时,取第几个 LAST); 这里再教大家一个方法,进入到loadrunner的帮助文档,查看每个函数的使用,loadrunner界面,按下键盘的F1,在输入框输入函数名称,比如atoi 当有多个示例的时候,HTTP协议的选择C语言 判断如下: // 写if判断 // int atoi( 需要转换成整型的字符 ); //把指定的字符转换成整型 // char *lr_eval_string( 当前想要获取的参数名 ); // 获取指定的当前参数的值 if(atoi(lr_eval_string("{code}"))==0) { //当code=0的时候,事务是成功的 lr_end_transaction("login", LR_PASS); } else { //当code不等于0的时候,事务是失败的 lr_end_transaction("login", LR_FAIL); } 运行脚本,在日志里面可以看到pass信息 总结 目前已经学习了几个常用的请求函数,作用如下: Web_url:只能用于get请求Web_submit_data:get,post,提交form表单Web_custom_request:即可用于get,也可用于post请求,post请求是标准的json串 最后: 为了回馈铁杆粉丝们,我给大家整理了完整的软件测试视频学习教程,朋友们如果需要可以自行免费领取 【保证100%免费】 软件测试面试文档

【嵌入式工具】Keil自制格式化插件

1 前期教程 【嵌入式工具】Keil下载,安装,配置教程大全 2 前言 上面的前期教程当中,对keil的下载,安装以及配置都讲得非常清楚了,但是最近遇到一个问题,那就是网上找的代码非常杂乱,即使使用AStyle插件对其进行格式化之后,行尾空格或者文件末尾空行仍然消除不掉,让强迫症的我非常不适,因为我非常喜欢VSCode中保存文件即删除行尾空格和文件末空行的设置,于是就想给Keil这个“上古编辑器”也整一个。 3 keil插件制作 好在Keil虽然样式老,但还支持插件扩展功能,因此可以自己写一个插件来实现想要的功能,不过首先需要对插件运行原理有一个基本的了解。 插件设置在菜单栏Tools中: 这个界面非常简单,就是三个框设置:运行指令(点击按钮执行的是哪个指令),初始位置(指令执行时所在的位置,可能涉及到当前文件夹的问题),参数(指令运行时需要添加的参数);右边三个复选框,其中Run Minimized是指运行时不产生黑框(如果有的话),Prompt for Argument字面意思理解应该是会弹出参数输入的提示,没用过,Run Independent,独立运行,也没用过。 重点是参数部分,!E表示当前编辑的文本文件;$E表示当前编辑的文本文件所在的文件夹。其他的就不怎么常用了。 其他更多指令建议参考这篇文章 OK,理解了基本逻辑,现在就可以开始制作插件,使用的编程语言是最熟悉的python,但是由于这里的Command不支持py脚本,还需要自己导出成执行程序,使用的是pyinstaller这个包。 【Python】pyinstaller完整使用教程 我想要实现的功能主要是删除每一行的行尾空格以及文件末尾的多余空行(只保留一个空行),代码如下: ## format.py import chardet, sys, glob def format_file(filename, default_encoding='gb2312'): ''' @func: 去除文件末空白行, 去除行尾空格 @para filename:文件名; default_encoding:默认编码 @return: None ''' try: content = open(filename, 'rb').read() # 以字节方式读取 except: print("文件"+filename+"打开失败") source_encoding = chardet.detect(content)['encoding'] string = content.decode(source_encoding if source_encoding else default_encoding, 'ignore') out = "\n".join(map(str.rstrip, string.rstrip().splitlines())) #删除文件末空行,并去除行尾空格 out = out + "\n" #行尾加一行空行 if out == string: print("

51单片机--AT24C02数据存储

文章目录 存储器的介绍AT24C02I2C总线I2C时序结构AT24C02数据帧AT24C02数据存储实例 存储器的介绍 存储器是计算机系统中的一种重要设备,用于存储程序和数据,它可以通过电子、磁性介质等技术来记录和保持数据。在这里,主要介绍的是随机存储器(RAM)和只读存储器(ROM)。 随机存储器(Random Access Memory,RAM)是一种可以读取和写入数据的存储器。 它的特点是可以随机访问其中的任意位置,并且读写速度较快。RAM通常由电子芯片制成,用于临时存储计算机运行时所需的程序和数据。 RAM可以分为静态随机存储器(Static RAM,SRAM)和动态随机存储器(Dynamic RAM,DRAM)两种类型。 静态随机存储器(SRAM):SRAM使用了触发器电路来存储数据,每个存储单元由多个触发器组成,具有较高的稳定性和快速的读写速度。由于使用了更多的电子元件,SRAM的密度较低,成本相对较高。它常用于高速缓存(Cache)等需要快速访问的场景。 动态随机存储器(DRAM):DRAM使用了电容器和开关电路来存储数据,每个存储单元由一个电容器和一个访问开关组成。由于电容器的电荷会随时间衰减,DRAM需要周期性地进行刷新操作来保持数据的稳定。DRAM具有较高的存储密度和较低的成本,但相对而言读写速度较慢。它常用于主存储器(内存)等需要较大容量的场景。 只读存储器(Read-Only Memory,ROM)是一种只能读取数据而无法写入或修改数据的存储器。ROM中的数据在制造时被写入,通常用于存储固化的程序代码、系统设置、固件等不需要频繁修改的数据。ROM的数据在断电后依然可以保持,具有非易失性。 ROM根据存储数据的方式可以分为多种类型,如只读存储器(ROM)、可编程只读存储器(PROM)、可擦除可编程只读存储器(EPROM)和电可擦除可编程只读存储器(EEPROM)等。这些ROM的特点是在制造或编程后,其存储的数据无法修改或只能经过特定方式修改。对于我们这款单片机来说,AT24C02就是E2PROM,电可擦除可编程ROM,可以通过编程来进行存储数据,数据根据具体的地址存储;断电之后,他还会保存在地址中,当我们需要读取时,可以通过相对应的地址取出数据; AT24C02 AT24C02是一种2K位(256字节)的串行EEPROM(Electrically Erasable Programmable Read-Only Memory),常用于51单片机系统中的数据存储。 AT24C02采用I2C总线协议进行通信,通过两根线路(SCL和SDA)与单片机进行连接。它具有8位的设备地址,可通过引脚A0、A1和A2进行编程设置,从而允许多个AT24C02共存在同一I2C总线上。 对于AT24C02,在读写速度上支持400kHz标准模式,数据保存能力可达10年之久,而且有写入保护,可以防止误操作; 在单片机系统中,可以使用AT24C02来存储各种数据,如配置参数、校准数据、历史记录等。单片机可以使用相应的I2C库函数来向AT24C02写入或读取数据,以实现对其存储空间的读写操作。 需要注意的是,AT24C02是一种非易失性存储器,即使在断电情况下也可以保持存储的数据。因此,它适用于需要长期保存数据的应用场景。 上图时AT24C02的内部结构框图,红色部分为它的存储位置; I2C总线 I2C,全称为Inter-Integrated Circuit,是一种串行通信协议,用于在电子设备之间进行数字数据传输。它由飞利浦半导体(现在的NXP半导体)公司在1980年代开发,并于1982年发布。I2C采用了两根导线(一根用于传输数据,另一根用于传输时钟信号)来连接设备,这使得多个设备可以通过同一组导线进行通信。 I2C协议有两个重要的角色:主设备(Master)和从设备(Slave)。主设备负责控制通信的序列和时钟信号的生成,而从设备则被动响应主设备的指令。 I2C支持多主设备和多从设备的连接,每个设备都有一个唯一的地址标识。主设备可以向从设备发送数据或者接收从设备的数据。在传输数据时,数据被分为多个字节,每个字节都会被从设备确认。 在51单片机中,AT24C02通过I2C总线与单片机进行数据通信; 通过I2C总线,单片机可以发送读取或写入命令给AT24C02,然后AT24C02会响应相应的操作。例如,单片机可以向AT24C02发送写入命令,并指定要写入的地址和数据,AT24C02会将数据写入指定地址的存储单元。而当单片机需要读取AT24C02中的数据时,它可以向AT24C02发送读取命令和要读取的地址,然后AT24C02会返回相应的数据给单片机。 I2C时序结构 I2C总线的时序结构一般分为6部分:起始条件、终止条件、发送数据、接收数据、接收应答和发送应答; 起始条件:主设备通过SCL(串行时钟线)保持高电平的同时,将SDA(串行数据线)由高电平转换为低电平,表示要启动一次通信; 代码: void I2C_Start() { I2C_SDA=1;//表示SCL高电平之前SDA就是高电平了 I2C_SCL=1;//SCL高电平期间 I2C_SDA=0;//SDA降为低电平 I2C_SCL=0;//SCL回到低电平 } 发送一个字节:SCL低电平期间,主设备将数据位依次放到SDA线上(高位在前),然后拉高SCL,在SCL上升沿时从设备将在SCL高电平期间读取数据位,所以SCL高电平期间SDA不允许有数据变化,依次循环上述过程8次,即可发送一个字节; 代码: void I2C_SendByte(unsigned char byte) { unsigned char i; for(i=0;i<8;i++) { I2C_SDA=byte&(0x80>>i);//先将数据放到SDA上 I2C_SCL=1; //SCL为上升沿时,从设备读取数据 I2C_SCL=0; } } 接收一个字节:SCL低电平期间,从设备将数据位依次放到SDA线上(高位在前),然后拉高SCL,主设备将在SCL上升沿期间读取数据位,所以SCL高电平期间SDA不允许有数据变化,依次循环上述过程8次,即可接收一个字节(主机在接收之前,需要释放SDA) 代码: unsigned char I2C_ReceiveByte() { unsigned char i,byte=0x00; I2C_SDA=1; //释放SDA,规定置于高电平 for(i=0;i<8;i++) { //在SCL上升沿期间,主设备读取SDA的数据, I2C_SCL=1; if(I2C_SDA){byte|=(0x80>>i); //通过判断SDA位的数据是否为1,进行位赋值 //为1执行条件内容,将位变为1,为0则不变,仍为0; I2C_SCL=0; } return byte; } 发送应答:在接收完一个字节之后,主机在下一个时钟发送一位数据,数据0表示应答,数据1表示非应答 ;

Java、maven、tomcat、idea的安装、配置以及各种常见错误

本篇文章的适用人群: 初衷是给小白或刚入门的人员写的,有些常见的软件安装步骤省略了,还算比较全 一. java的下载、安装、配置和验证 1. 下载: 官网:https://www.oracle.com/java/technologies/downloads/ 注:下载时如需要账号登陆,自行登录或注册后登录,然后下载 百度云:https://pan.baidu.com/share/init?surl=LGf3PodzAT1R-7ET1DEOdQ 提取码:s6mg CSDN: Java系列8u311 Java_8u311_windows 2. 安装 1. 点击“更改目录”,将安装目录设置在自己喜欢的地方(建议),或者直接点击下一步(此时默认装到C盘) 2. 这里选择安装:点击确定,会出现安装jre的提示,点击下一步即可 注:有时候装完JDK后会跳出安装JRE的窗口,可以直接关闭或安装,JRE若自定义安装,则要将JRE安装到一个空目录下,不然会报错 3. 点击关闭即可 3. 配置环境变量 1. 确定JDK和JRE的安装位置 2. 右键我的电脑,点击最下面的属性,之后在弹框里点击高级系统设置,再点击环境变量 3. 变量设置参数如下(用户变量、系统变量自己选): 变量名:JAVA_HOME 变量值:G:\code\path\java\ // 要根据自己的实际路径配置变量名:CLASSPATH 变量值:.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar; //记得前面有个"."变量名:Path 变量值:%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin; 系统间不同的配置方法: win10的话直接新建后添加%JAVA_HOME%\bin和%JAVA_HOME%\jre\bin(win10末尾不用添加分号“;”)win7的话在末尾添加%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;若path变量最末尾的变量无分号,则添加;%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin; 4. 使用快捷键,(win+r),输入cmd按Enter键 输入 java ,按Enter键,查看java运行环境是否正常,出现下面的信息则配置成功。 输入java -version,按Enter键可查看当前安装的的jdk版本。 输入javac,按Enter键,查看java编译环境是否正常。出现下面的信息则配置成功。 Java的众多问题 1. java不是内部命令,javac不是内部命令报错的解决办法 重新配置Path, JAVA_HOME, CLASSPATH 的环境变量 (这三个环境,其中一个出错,都会产生上面的报错,不行就多复制粘贴几次) 变量设置参数如下: 变量名:JAVA_HOME 变量值:G:\code\path\java\ // 要根据自己的实际路径配置 变量名:CLASSPATH 变量值:.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar; //记得前面有个"." 变量名:Path 变量值:%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin; (注:在重新配置完这三个环境变量后,将前面窗口都点击确定,然后一定要等待10s左右后,再 重新打开dos窗口输入java, java -version, javac这三个命令,不然环境变量配置正确了,也可能报错)

Promise原理及常用操作

题外话:做项目的时候,遇到一个超级低级的错误,.then一直不能执行,检查了nnn...遍代码之后发现没有把最初引用的js文件函数里的promise return出来,所以.then一直执行不了,报这个错 Error in v-on handler: "TypeError: Cannot read property 'then' of undefined"。 一、Promise介绍 Promise 对象是一个代理对象(代理一个值),被代理的值在Promise对象创建时可能是未知的。它允许你为异步操作的成功和失败分别绑定相应的处理方法(handlers)。 这让异步方法可以像同步方法那样返回值,但并不是立即返回最终执行结果,而是一个能代表未来出现的结果的promise对象 。 ------MDN 意思就是说,promise可以把异步的操作用同步的方式表达。 我们知道用XHR对象发起多个异步请求的时候,无法保证响应返回的顺序,使用回调函数来控制响应顺序时会形成回调地狱,代码难以维护,而且容易出错,所以就有了Promise对象。 当时用Promise模式时,可以将未来才会发生的事作为一个任务保存,每个任务都含有一个状态(pending 或 fulfilled 或 rejected)。状态一经改变就不会再恢复。无论当前任务成功还是失败,任务链都不会终止,直到所有任务状态都改变,才会结束任务。 二、Promise使用方法 1.resolve(),reject()分别对应then(),.catch() let promise = new Promise((resolve, reject) => { reject() //可以传参,如:resolve(1111),那么.then的response可以接受这个参数。 //reject(2222),那么.catch的error可以接受这个参数。 } 2..then(),.catch(),分别对应resolve(),reject()。 <script> let promise = new Promise((resolve, reject) => { reject(111) }) promise.then(response => { //调用resolve()时执行 console.log('成功') console.log(response) //控制台打印111 }).catch(error =>{ console.log('222') //如果promise实例调用reject(),控制台会输出222 }) </script> 3.链式 function promise1(status){ return new Promise((resolve,reject) => { if(status){ console.

@Retention注解的使用

@Retention 是一个 Java 注解,用于指定注解的保留策略,即注解的生命周期。该注解可以用于自定义注解上,指定该注解可以保留多长时间。 @Retention 注解包含一个 RetentionPolicy 类型的属性 value,用于指定注解的保留策略,常用的保留策略包括: RetentionPolicy.SOURCE:表示注解仅在源代码中保留,编译器编译时会将其忽略,不会保存在编译后的字节码中。RetentionPolicy.CLASS:表示注解在编译后的字节码中保留,但在运行时不会被加载到 JVM 中。这是默认的保留策略。RetentionPolicy.RUNTIME:表示注解在编译后的字节码中保留,并在运行时被加载到 JVM 中。可以使用反射机制来访问该注解。 例如,以下代码定义了一个自定义注解 MyAnnotation,使用 @Retention 注解指定该注解在运行时保留: @Retention(RetentionPolicy.RUNTIME) public @interface MyAnnotation { // ... } 在上面的代码中,使用 @Retention(RetentionPolicy.RUNTIME) 指定 MyAnnotation 注解在运行时保留。在实际应用中,如果需要将 MyAnnotation 注解仅在编译期间保留,可以将 @Retention 注解的 value 属性设置为 RetentionPolicy.SOURCE,即 @Retention(RetentionPolicy.SOURCE)。

@Target注解

@Target 是一个 Java 注解,用于指定注解的应用范围,即注解可以应用到哪些元素上。该注解可以用于自定义注解上,指定该注解可以应用到哪些类型的元素上。 @Target 注解包含一个 ElementType[] 类型的属性 value,用于指定注解可以应用到的元素类型。常用的元素类型包括: ElementType.TYPE:表示该注解可以应用到类、接口、枚举、注解类型等上。ElementType.FIELD:表示该注解可以应用到字段上。ElementType.METHOD:表示该注解可以应用到方法上。ElementType.PARAMETER:表示该注解可以应用到方法参数上。ElementType.CONSTRUCTOR:表示该注解可以应用到构造方法上。ElementType.LOCAL_VARIABLE:表示该注解可以应用到局部变量上。ElementType.ANNOTATION_TYPE:表示该注解可以应用到注解类型上。ElementType.PACKAGE:表示该注解可以应用到包上。 例如,以下代码定义了一个自定义注解 MyAnnotation,使用 @Target 注解指定该注解可以应用到类、方法、字段上: @Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD}) public @interface MyAnnotation { // ... } 在上面的代码中,使用 @Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD}) 指定 MyAnnotation 注解可以应用到类、方法、字段上。在实际应用中,如果需要将 MyAnnotation 注解应用到其他元素上,例如构造方法或局部变量上,可以在 @Target 注解中增加相应的元素类型即可。

如何解决SSL: CERTIFICATE_VERIFY_FAILED

"SSL: CERTIFICATE_VERIFY_FAILED"错误通常在使用Python的requests或urllib等库进行HTTPS请求时出现,它表明SSL证书验证失败。这可能是由于服务器证书无效、过期、自签名或缺失等原因所致。要解决此问题,可以尝试以下方法: 参考: http://www.howtouselinux.com/post/ssl-certificate_verify_failed-in-python 升级Python版本: 确保你正在使用最新版本的Python。较旧版本的Python可能会导致一些SSL问题。 更新CA证书: 从操作系统或Python本身更新CA(Certificate Authority)证书库。这样可以确保系统能够正确验证服务器证书。 忽略证书验证: 在测试或特定情况下,你可以选择忽略证书验证。但请注意,这样做会使连接变得不安全,并不推荐在生产环境中使用。在requests中可以这样做: import requests requests.get('https://example.com', verify=False) 使用自定义CA证书: 如果你的服务器证书是自签名的,可以使用verify参数来指定自定义CA证书的路径: import requests requests.get('https://example.com', verify='/path/to/custom_ca.pem') 更新系统时间: SSL证书验证依赖于系统时间。如果系统时间不正确,可能导致证书验证失败。确保系统时间准确。 检查证书过期: 确认服务器证书是否过期。如果证书已过期,需要重新生成并更新服务器证书。 检查证书链: 确保服务器证书的完整证书链正确。有时,缺少中间证书或根证书可能导致验证失败。 检查网络代理: 如果你的网络使用代理,确保代理配置正确,并不会干扰SSL证书验证。 请注意,忽略证书验证或使用自定义CA证书都是暂时解决方案,不推荐在生产环境中长期使用。在生产环境中,请确保服务器证书的合法性和正确性,并正确配置SSL证书验证。 我们整理了一份Linux学习的pdf文件,放在下面的路径,可以自提: https://www.howtouselinux.com/post/linux-commands-for-linux-beginners-cheat-sheet

Centos7+ redis7搭建主从+哨兵模式超详细教程攻略

搭建之前请务必了解Redis的工作原理,切勿盲目搭建!!! Redis(Remote Dictionary Server)是一个开源的高性能键值存储数据库,它主要用于存储数据、缓存和消息传递。Redis支持多种数据结构,如字符串、列表、集合、有序集合、哈希表等,这些数据结构使得Redis能够解决很多不同类型的问题。 主要用途包括: 缓存:将常用的数据存储在Redis中,以加快读取速度,减轻后端数据库的负载。这有助于提高应用程序的性能和响应时间。 会话存储:将用户会话数据存储在Redis中,使得分布式系统能够无缝地共享和管理会话状态。 计数器:用于实时统计,如网站访问次数、点赞数、在线用户数等。 消息队列:作为发布/订阅系统或消息队列,用于在不同组件或服务之间传递消息,实现解耦和异步处理。 排行榜/排名:用于存储并获取排行榜数据,如游戏排行、热门文章等。 地理空间索引:支持存储和查询地理位置信息,可用于构建位置相关的应用。 Redis的工作原理: 内存存储:Redis的所有数据都存储在内存中,因此读写速度非常快。这也是Redis高性能的主要原因。 单线程:Redis通过单线程处理所有的客户端请求,避免了多线程的竞争和同步问题,简化了数据结构的处理。然而,Redis在内部使用了非阻塞的I/O多路复用机制,使得它能够同时处理多个客户端请求。 持久化:Redis支持两种方式的数据持久化,即RDB(Redis Database Dump)和AOF(Append-Only File)。RDB通过将数据快照保存到硬盘中,而AOF则记录每个写操作的日志,使得在重启后可以恢复数据。 主从复制:Redis支持主从复制机制,可以配置多个Redis实例之间的主从关系。主节点将数据同步到从节点,从而实现数据的备份、读写分离和负载均衡。 高可用性:Redis提供了Sentinel和Cluster两种方式来实现高可用性。Sentinel用于监控Redis主节点的状态,一旦主节点故障,会自动将从节点切换为主节点。而Cluster是一种分布式方案,将数据分片存储在多个节点上,实现了自动分片和数据复制。 下面我们开始搭建Redis哨兵模式 (哨兵模式是一种故障转移策略,哨兵模式是在主从的基础上搭建) 下载redis安装包: 链接:https://pan.baidu.com/s/1VKrVGMyAKmMHsbwGxmwGkA 提取码:6vfw Redis是基于C语言编写的,所有安装Redis之前需要gcc依赖 yum install -y gcc tcl 把安装包放入usr目录,下载好的安装包之间拖入即可 cd /usr 解压 tar -zxvf redis-7.0.12.tar.gz 进入redis7.0.12 cd redis-7.0.12 使用make 命令进行编译将.c文件编译成.o文件 make 编译成功之后会出现“It's a good idea to run 'make test'”的提示 使用命令 进行安装 make PREFIX=/usr/local/redis install 安装完后,在/usr/local/redis/bin下有几个可执行文件可以查看 ll /usr/local/redis/bin redis启动需要一个配置文件,可以修改端口号等信息 安装目录下将redis.conf文件拷贝到/usr/local/redis目录中 cp redis.conf /usr/local/redis 进入 /usr/local/redis cd /usr/local/redis 修改配置文件redis.

Kotlin中的伴生对象

在 Kotlin 中,可以使用关键字 companion object 来定义一个伴生对象(companion object)。伴生对象是一个类级别的对象,类似于 Java 中的静态方法和静态变量,可以在不创建类实例的情况下调用其中的方法和属性。 伴生对象可以包含属性、方法和构造器。可以通过伴生对象的名称来调用其中的方法和属性,例如: class MyClass { companion object { val staticValue = "Hello, world" fun staticMethod() { println("This is a static method.") } } } 在上面的代码中,定义了一个名为 MyClass 的类,以及一个名为 companion object 的伴生对象。伴生对象中定义了一个名为 staticValue 的静态属性和一个名为 staticMethod 的静态方法。 可以使用以下语法来调用伴生对象中的静态属性和方法: val value = MyClass.staticValue MyClass.staticMethod() 需要注意的是,虽然伴生对象类似于静态方法和静态变量,但是它们并不是真正的静态方法和静态变量。在运行时,伴生对象实际上是一个普通的对象,可以像普通的对象一样创建多个实例,并且可以被继承和重写。因此,如果需要真正的静态方法和静态变量,可以考虑使用顶层函数和顶层属性。

使用python中的1DCNN进行数据分类预测

在Python中使用1D卷积神经网络(1DCNN)进行数据分类预测可以使用深度学习库例如TensorFlow和Keras来实现。以下是一个基本示例,帮助你入门: import numpy as np import tensorflow as tf from tensorflow.keras import layers # 准备数据 X_train = ... # 训练数据,形状为 (样本数, 时间步数, 特征数) Y_train = ... # 训练标签,形状为 (样本数, 类别数) X_test = ... # 测试数据,形状为 (测试样本数, 时间步数, 特征数) Y_test = ... # 测试标签,形状为 (测试样本数, 类别数) # 定义模型 model = tf.keras.Sequential() model.add(layers.Conv1D(64, 3, activation='relu', input_shape=(X_train.shape[1], X_train.shape[2]))) model.add(layers.MaxPooling1D(2)) model.add(layers.Flatten()) model.add(layers.Dense(64, activation='relu')) model.add(layers.Dense(Y_train.shape[1], activation='softmax')) # 编译模型 model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']) # 训练模型 model.fit(X_train, Y_train, epochs=10, batch_size=32) # 预测和评估 Y_pred = model.

使用matlab中的1DCNN进行数据分类预测

在Matlab中使用1D卷积神经网络(1DCNN)进行数据分类预测是很常见的任务。首先,确保你已经准备好了用于训练和测试的数据集。然后,按照以下步骤进行操作: 准备数据:将你的输入数据整理成适合1DCNN的输入格式。通常,输入数据是一个矩阵,其中每行表示一个样本,每列表示样本的不同特征或时间点。 定义网络结构:在Matlab中,你可以使用Deep Learning Toolbox来创建1DCNN模型。使用layerGraph创建网络结构,像添加其他层一样,添加1D卷积层(convolution1dLayer)、池化层(maxPooling1dLayer或averagePooling1dLayer)、全连接层(fullyConnectedLayer)和分类器层(classificationLayer)。 配置训练选项:设置训练选项,包括优化算法、学习率、迭代次数等。 训练网络:使用trainNetwork函数来训练你的1DCNN模型。将训练数据集、测试数据集、网络结构和训练选项作为输入。 预测和评估:使用已训练的模型对新数据进行分类预测。使用classify函数对测试数据集进行预测,并评估模型的性能。 这是一个简单的示例代码片段,帮助你入门: % 准备数据 load('data.mat'); % 加载数据集 X_train = trainData; % 训练数据 Y_train = trainLabels; % 训练标签 X_test = testData; % 测试数据 Y_test = testLabels; % 测试标签 % 定义网络结构 layers = [ convolution1dLayer(5, 16, 'Padding', 'same', 'WeightsInitializer', 'narrow-normal') reluLayer() maxPooling1dLayer(2, 'Stride', 2) fullyConnectedLayer(64) reluLayer() fullyConnectedLayer(2) softmaxLayer() classificationLayer() ]; % 配置训练选项 options = trainingOptions('adam', ... 'MaxEpochs', 10, ... 'MiniBatchSize', 32, ... 'Plots', 'training-progress'); % 训练网络 net = trainNetwork(X_train, categorical(Y_train), layers, options); % 预测和评估 Y_pred = classify(net, X_test); accuracy = sum(Y_pred == categorical(Y_test)) / numel(Y_test); disp(['Accuracy: ', num2str(accuracy)]); 上述代码中,你需要根据你的数据形式和任务需求进行适当的修改。还可以尝试不同的网络结构、训练选项和参数调整,以获得更好的性能。

JavaScript复习

JS概述 简称:JS脚本语言:目标程序是以普通文本形式保存运行在浏览器中,浏览器有执行JS代码的内核专门操作HTML页面中的节点事件驱动型编程语言,发生某个事件时候执行某个代码 JS三大块 核心语法:ECMAScript DOM:Document Object Model访问网页元素 BOM:Browser Object Model浏览器对象模型 嵌入JS三种方式 事件发生三要素: * 事件源 * 事件 * 监听器 行间事件:标签内使用事件句柄脚本块:页面打开时自上而下逐次执行引入JS文件:<script type="text/javascript" src="xx/x.js"></script> 引入CSS文件<link rel="stylesheet" type="text/css" href="xx/x.css"> 变量 1. 弱类型语言,没有编译阶段,直接浏览器中打开解释执行 2. 声明变量时不需要指定变量数据类型,程序运行过程中,赋什么值就是什么类型 3. var、let和const的区别 var可以重复定义,let不能重复定义 let和var都允许值的修改 const不能重复定义和修改指针 var有声明提升,不赋值默认为undefined let和const没有声明提升 块级作用域 4. 全局变量和局部变量 全局变量:函数体之外声明,浏览器打开的时候分配空间,浏览器关闭的时候销毁 局部变量:函数体当中声明的变量,函数被调用的时候分配空间,函数执行结束的时候释放 B站链接:JavaScript var let const的区别 CSDN链接:JavaScript中let和var区别详解 函数 JS函数声明的优先级比较高,打开网页时函数的声明先执行。 数据类型 ES6之后有8种 Undefined、Number、String、Null、Boolean、Object、 Symbol、BigInt 其中undefined、Number、String、Boolean为原始类型(基本数据类型) Object为引用数据类型(对象类型)typeof typeof可以在运行过程中动态获取变量类型JS中没有equals

docker容器引擎(二)

docker 一、docker网络Docker 网络实现原理docker的五个网络模式1.host模式2.container模式3.none模式4.bridge模式5.自定义网络 二、资源控制1.CPU 资源控制2.对内存使用的限制3.对磁盘IO配额控制(blkio)的限制 一、docker网络 Docker 网络实现原理 Docker使用Linux桥接,在宿主机虚拟一个Docker容器网桥(docker0),Docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP地址,称为Container-IP,同时Docker网桥是每个容器的默认网关。因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的 Container-IP 直接通信。 Docker网桥是宿主机虚拟出来的,并不是真实存在的网络设备,外部网络是无法寻址到的,这也意味着外部网络无法直接通过 Container-IP 访问到容器。如果容器希望外部访问能够访问到,可以通过映射容器端口到宿主主机(端口映射),即 docker run 创建容器时候通过 -p 或 -P 参数来启用,访问容器的时候就通过[宿主机IP]:[容器端口]访问容器。 docker run -d --name test1 -P nginx #随机映射端口(从32768开始) docker run -d --name test2 -p 43000:80 nginx #指定映射端口 docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 9d3c04f57a68 nginx “/docker-entrypoint.…” 4 seconds ago Up 3 seconds 0.0.0.0:43000->80/tcp test2 b04895f870e5 nginx “/docker-entrypoint.…” 17 seconds ago Up 15 seconds 0.

【JAVA】【源码学习】ByteBuffer

摘要 最近看Netty相关的源码,Netty自己封装了一套完整、复杂的buffer功能,但是用到java nio,则必须转换为ByteBuffer,于是先学习ByteBuffer,才能更深入的理解ByteBuf。 Buffer 虽然实际使用中最常见到的的是ByteBuffer,但是常用的位置相关操作都封装在抽象类Buffer中,比如mark、flip之类的操作,可以说是Buffer定义了操作逻辑。主要变量: private int mark = -1; // 位置标记 private int position = 0; // 当前位置 private int limit; // 位置操作的限制 private int capacity; // 缓存大小 这几个变量的关系: 0 <= mark <= position <= limit <= capacity 先看下主要操作的源码,更容易理解: public final Buffer mark() { mark = position; return this; } public final Buffer reset() { int m = mark; if (m < 0) throw new InvalidMarkException(); position = m; return this; } public final Buffer flip() { limit = position; position = 0; mark = -1; return this; } public final Buffer rewind() { position = 0; mark = -1; return this; } public final Buffer clear() { position = 0; limit = capacity; mark = -1; return this; } public final int remaining() { int rem = limit - position; return rem > 0 ?

Redis【基础篇01】

Redis基础 初识Redis 认识NoSQL SQL:关系型数据库 1. Structured结构化,插入数据符合一定格式 表确定之后不建议修改 2. 表和表之间通过外键建立关系 3. 通过sql查询,语法固定,只要是关系型数据库都能用相同语句查询 4. 事务,满足ACID 5. 磁盘存储 6. 扩展性:垂直 NoSQL:非关系型数据库 1. 非结构化:键值型数据库(Redis)、文档型(MongoDB)、图类型(Neo4j)、列类型(HBase) 数据结构比较松散,都没有严格规定,修改方便 2. 常见通过JSON文档嵌套方式保存数据,没有关联,需要程序员自己维护数据之间的关联 3. 查询没有固定的语法格式 4. 要么没有事务要么无法满足事务强一致性,只能满足基本一致性BASE 5. 内存存储,查询性能非常高 6. 水平扩展 认识Redis * Redis诞生于2009年全程Remote Dictionary Server,远程词典服务器,是一个基于内存的键值型NoSQL数据库 * 键值型,value支持多种不同数据结构,功能丰富 * 单线程,每个命令具备原子性 单线程但是性能好、低延迟: 1. Redis基于内存(最重要原因) 2. IO多路复用 3. 良好的编码,基于C语言编写 * 支持数据持久化 * 支持主从集群(从节点可以备份主节点)和分片集群 * 支持多语言客户端Java、python、C等 安装Redis

SC7A20获取三轴加速度值

原文地址::SC7A20获取三轴加速度值_sc7a20敲击_QDDA的博客-CSDN博客 SC7A20获取三轴加速度值(I2C) 1. I2C.h #ifndef __I2C_H #define __I2C_H #include "config.h" sbit I2C_SCL=P3^2;//SCL sbit I2C_SDA=P3^3;//SDA #define I2C_SCL_Clr() I2C_SCL=0 #define I2C_SCL_Set() I2C_SCL=1 #define I2C_SDA_Clr() I2C_SDA=0 #define I2C_SDA_Set() I2C_SDA=1 //void Wait(); void Start(); void SendData(char dat); void RecvACK(); char RecvData(u8 SF_Ack); void SendACK(); void SendNAK(); void Stop(); #endif 2. I2C.c (IO口模拟I2C) #include "I2C.h" //延时 void I2C_delay(void) { u8 t=1; while(t--); } void Start() { I2C_SDA_Set(); I2C_SCL_Set(); I2C_delay(); I2C_SDA_Clr(); I2C_delay(); I2C_SCL_Clr(); } //========================================================================

Git项目开发最常用命令

git fetch:同步远程代码至本地库 git merge branch-a:将分支branch-a合并到当前分支上,注意不是将当前分支合并到 branch-a分支上 git pull:将远程分支上的代码拉取到本地,并自动合并到当前分支上,git pull = git fetch + git merge 注意:如果本地分支和远程分支建立了连接,那么 pull 后面可以不写远程的分支名,否则命令将无效,此时要么手工在 pull 后面输入远程的分支名,要么输入命令 git branch --set-upstream-to=origin/current-branch 建立本地与远程分支的连接,git push 也是同理。 git branch:查看所有本地分支 git branch -r:查看所有远程分支 git branch -a:查看本地和远程的所有分支 git branch new-branch:新建一个本地分支 git checkout new-branch:切换到新分支 git checkout -b new-branch:先创建本地新分支,再切换到该分支,git checkout -b new- branch = git branch new-branch + git checkout new-branch git add fileName:将单个文件添加到暂存区,纳入版本控制,告诉 git 开始对这个文件进行 跟踪 git add . 或 git add * :将所有文件添加到暂存区,纳入版本控制

xcode15启动IOS远程调试

1.用数据线连接IPhone到macOS 2.打开xcode15,然后点击Window->Devices and Simulators 3.选中左边的Devices可看到已连接的IPhone,然后点击Connect via network使其选中. 选择后,左边的IPhone设备的右边出现一个地球图标,表示成功通过网络连接到IPhone 现在可断开数据线的连接,至此可以对IPhone设备进行远程调试了 注: iPhone与macOS需要在同一局域网. 4.打开或者新建一个iOS工程,点击调试设备列表,可以看到,iPhone设备带有地球图标符号,表示是通过网络连接的远程设备 启动远程调试 成功远程调试并断点如下 

Monocle3 基本流程复现

参考:单细胞之轨迹分析-3:monocle3 - 简书 (jianshu.com),教程中的方法是使用new_cell_data_set()函数创建了一个新的 cds对象,这个函数常用于从头开始创建一个新的rds对象。而本方法使是用as.cell_data_set()函数,直接读入经过Seurat上游处理(SCTransform、RunPCA、RunUMAP、FindNeighbors、FindClusters)后的obj创建rds对象。 new_cell_data_set ( ):从头创建CDS对象并预处理数据,创建了一个全新的对象,这样很繁琐,还要再做一次降维聚类分群。因为我们导入了seurat对象里的表达矩阵,meta信息和genelist,所以这个cds是没有进行降维聚类等操作,导致后面的拟时序分析是做不了的,官网上说拟时序分析是基于低维度,所以必须对cds进行降维聚类分群。as.cell_data_set ( ): 直接读入经过Seurat上游处理(SCTransform、RunPCA、RunUMAP、FindNeighbors、FindClusters)后的obj创建rds对象,不用再进行预处理(preprocess_cds)和降维(reduce_dimension)步骤。 数据:PBMC 3K:Seurat - Guided Clustering Tutorial • Seurat (satijalab.org) # 安装monocle3 if (!requireNamespace("BiocManager", quietly = TRUE)) install.packages("BiocManager") BiocManager::install(version = "3.10") BiocManager::install(c('BiocGenerics', 'DelayedArray', 'DelayedMatrixStats', 'limma', 'S4Vectors', 'SingleCellExperiment', 'SummarizedExperiment', 'batchelor', 'Matrix.utils')) install.packages("devtools") devtools::install_github('cole-trapnell-lab/leidenbase') devtools::install_github('cole-trapnell-lab/monocle3') ------------------------------------------------------------------------------- library(Seurat) library(monocle3) library(tidyverse) library(patchwork) library(ggplot2) library(dplyr) library(SeuratWrappers) dir.create("C:/Users/Bolin/Desktop/Monocle3") setwd("C:/Users/Bolin/Desktop/Monocle3") pbmc.data <- Read10X("C:/Users/Bolin/Desktop/hg19") pbmc <- CreateSeuratObject(counts = pbmc.data, project = "pbmc3k", min.cells = 3, min.features = 200) obj <- pbmc %>% SCTransform(verbose = FALSE, vars.

谷粒商城笔记+踩坑(2)——分布式组件、前端基础,nacos+feign+gateway+ES6+vue脚手架

导航: 谷粒商城笔记+踩坑汇总篇_谷粒商城笔记踩坑6_vincewm的博客-CSDN博客 目录 4、分布式组件 4.0. 简介 4.0.1、SpringCloud 对比SpringCloud Alibaba 4.0.2、项目技术搭配方案选择 4.0.3、common模块引入SpringCloud Alibaba依赖管理 4.1 nacos下载、启动、配置 4.1.1、nacos下载安装 4.1.2、配置nacos注册中心 4.1.3、启动gulimall-xxx, 查看服务注册中心 4.2. openfegin远程调用,案例演示 4.2.0、需求,member调用coupon 4.2.1、common模块引入openfegin依赖 4.2.2、 coupon的controller编写测试方法 4.2.3、member的引导类注解@EnableFeignClients 4.2.4、member模块编写coupon的客户端 4.2.5、member模块注入coupon的客户端 4.3. nacos用作配置中心 4.3.1、依赖 nacos-config,bootstrap 4.3.2、coupons模块创建bootstrap.yml 4.3.3、nacos服务端添加配置文件 4.3.4、coupon的controller中编写测试代码 4.3.5、启动测试 4.3.6、配置热更新,controller注解@RefreshScope动态刷新 4.3.7、命名空间 4.3.8、根据服务创建命名空间,各命名空间根据环境分组 4.3.9、按类型抽取配置,加载多配置集 4.4. 网关gateway 4.4.0、简介 4.4.1、gulimall父工程下新建gulimall-gateway模块作为网关 4.4.2、演示,网关路由到百度 5、前端基础(回顾,与项目无关) 5.1. ES6基础 5.1.1、let & const 5.1.2、解构表达式 5.1.3、函数优化 5.1.4、对象优化 5.1.5、map和reduce 5.1.6、promise 5.1.7、模块化 5.2. VUE基础 5.2.1、VUE安装 5.2.2、v-model, v-on 5.2.3、v-text、v-html、v-ref 5.2.4、单向绑定v-bind: 5.2.5、双向绑定v-model 5.2.6、v-on事件 5.2.7、v-for遍历 5.2.8、v-if和v-show 5.2.9、v-else和v-else-if 5.2.10、计算属性和监听器

谷粒商城笔记+踩坑(10)——商城首页和Nginx反向代理,thymeleaf+动态展示三级分类

导航: 谷粒商城笔记+踩坑汇总篇 目录 1、商城系统简介 2、模板技术 2.1、介绍 2.2、模板技术与前端框架的区别 3、整合thymeleaf渲染商城首页 3.1、环境准备 3.1.1、【商品模块】导入thymeleaf和热部署依赖 3.1.2、静态资源添加到商品模块 3.1.3、controller包改名为app、新增web包 3.1.4、yml关闭thymeleaf缓存 3.1.5、启动测试 3.2、controller开发首页跳转功能,拦截首页请求处理后跳转到首页 3.3、service,查询一级目录列表 3.4、thymeleaf基础语法,渲染商城首页一级分类 3.5、商品二、三级分类分类的预期响应JSON 3.6、根据一级分类id查询二级三级分类 3.6.1、新增Catalog2Vo实体类 3.6.2、新增接口 3.6.3、新增查询出父ID为 parent_cid的List集合 3.6.4、修改请求 3.6.5、重启服务并测试 3.7、总结springboot页面跳转 3.7.1、静态页面 3.7.2、动态页面 4、nginx搭建域名访问环境 4.1、需求 4.2、回顾反向代理 4.3、配置反向代理 4.3.1、hosts文件配置域名和ip映射 4.3.2、配置nginx.conf 4.3.3、配置/etc/nginx/conf.d/gulimall.conf 4.3.4、网关配置“gulimall.com”的路由规则 4.3.5、坑点:Nginx代理给网关时会丢失请求的host等信息 4.3.6、测试通过 4.3.7、小结,反向代理流程 1、商城系统简介 我们的商城系统本应该也是前后端分离的,就像后台管理系统那样,然而出于教学考虑,前后端分离的话就会屏蔽掉很多细节,所以我们进行服务端的页面渲染式开发(有点儿类似freemarker) 动静分离:nginx在后面部署的时候,我们可以将微服务中的页面的静态资源部署到nginx中。分担微服务的压力。 静指的是:图片、js、css等静态资源(以实际文件存在的方式) 每一个微服务只来管理自己的页面,最终做到每一个微服务都可以独立部署、运行、升级。 每个微服务都是独立自治的,每一个微服务的数据库、技术都是自治的。不一定商品服务用java开发,用php、js都可以,无论是从技术层面、架构层面还是业务都是独立自治的。 用户先访问Nginx,Nginx反向代理将请求转发到网关,网关路由到各个服务。网关可以请求路由、鉴权认证、限流等。 2、模板技术 2.1、介绍 模板技术:把页面中的静态数据替换成从后台数据库中的数据。 这种操作用jsp就可以实现。但是Spring boot 的架构不推荐使用Jsp,而且支持也不好,所以如果你是用springboot的话,一般使用Freemarker或者Thymeleaf 。 Thymeleaf模板引擎是自然化语言,编写的页面前端可以直接使用。 2.2、模板技术与前端框架的区别 3、整合thymeleaf渲染商城首页 3.1、环境准备 3.1.1、【商品模块】导入thymeleaf和热部署依赖 <!-- 页面渲染我们使用thymeleaf,这应该和freemarker是差不多的,都是模板引擎--> <!-- 优点:它是一个自然化语言,编写的语言前端可以直接使用,方便前后人员的分工合作--> <!-- 缺点:性能比其他模板引擎要低一点,但是我们在生产环境开启了它的缓存功能,性能也是很高的--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <!--热部署--> <dependency> <groupId>org.

【统计课堂】SPSS统计分析- R×C列联表资料统计方法的选择

之前我们提到R×C列联表资料,列联表根据变量是否有序可以分为双向无序、单项有序、双向有序列联表,他们的统计方法是不同的 一、双向无序列联表 双向无序列联表是指行、列变量均为无序的列联表,比如不同污染地区的动物畸形率是否有差异?如下表: 对于这种数据,我们的统计目的是分析行列变量的独立性,可选用的方法有以下两种: 1、Pearson卡方检验: 基于卡方分布,H0为行、列变量相互独立, 使用条件:各个单元格理论值均大于5。详见【统计课堂】SPSS中级统计--S05-4卡方独立性检验之n×c表资料(双向无序)) 2、Fisher精确概率: 基于超几何分布,当数据不满足Pearson卡方检验时使用。 SPSS中的实现:1.“数据加权”,2.“分析”-“描述性统计”-“交叉表”,3.参数设置:①“统计”-选择卡方;②点击“精确”-勾选“精确(E)”; 注意:在SPSS中,如果是整理成了列联表资料,需要用频数进行数据加权。 二、单项有序列联表 单项有序列联表常见的情况是结果变量有序,而原因变量无序;例如:研究三种药物治疗糖尿病效果,660例患者随机分成3组,药物A、B、C分别220例,治疗效果如下图: 这种数据我们选用的统计分析方法有: 1、Mann–Whitney U 检验:(用于分组为两组的情况) 基于卡方分布,H0为两组总体分布一致,SPSS中“分析->非参数检验->独立样本”中可实现。具体实现方法参见:【视频教学】SPSS中级统计--S03-5两个独立样本检验(Mann-Whitney U检验法) 2、Kruskal-Wallis H检验:(用于分组数大于2的情况),比如要比较3种或以上药物的疗效。实现方法与Mann–Whitney U 类似。具体实现方法参见:【视频教学】SPSS中级统计--S03-6K个独立样本检验Kruskal-Wallis H检验 注:如果是原因变量为有序变量的单向有序R×C表资料,可以将其视为双向无序的R×C表资料而选用一般的χ2检验。 三、双向有序 1.双向有序且属性不同 例如:某医院为研究某老年性疾病的严重程度与患者年龄之间的关系,调查数据如下表: 本例中行、列都是有序的,这是我们主要关心的:行列变量之间受否有相关性,如果有相关性,是线性相关还是曲线关系。可以选择的方法如下: (1)Spearman等级相关:检验有无相关性,在SPSS中“分析->相关->双样本”中可实现。 (2)线性趋势卡方检验:检验有无线性关系,SPSS“分析->交叉表”卡方结果表格中的“线性和线性组合”就是。 补充:如果研究者希望考察原因变量与结果变量之间是否存在线性相关关系,此时需要选用处理定性资料的相关分析方法如Spearman秩相关分析方法等。如果两个有序变量之间的相关关系具有统计学意义,研究者希望进一步了解这两个有序变量之间的线性关系,此时宜选用线性趋势检验。如果研究者希望考察列联表中各行上的频数分布是否相同,此时宜选用一般的卡方检验。 2、行列有序且属性相同 ①一致性检验: 在分析这类资料时,实验者的目的如果主要是研究两种处理方法检测结果之间是否具有一致性,因此常用的统计分析方法为一致性检验或Kappa检验。比如两名医生对200名患者疾病的判断是否一致: 甲医生 乙医生 低分化 中度分化 高度分化 低分化 45 15 5 中度分化 15 45 15 高度分化 10 20 30 SPSS中的实现:1.“数据加权”,2.“分析”-“描述性统计”-“交叉表”,3.参数设置:“统计”-Kappa; Kappa值的专业意义如下:Kappa≥0.75时,表明两者一致性较好;0.75>Kappa≥0.4时,表明一致性一般;Kappa<0.4时,表明两者一致性较差。 ②差异性检验 以上案例我们分析的是两个以上的判断是否一致,我们采用Kappa一致性检验,如果我们分析两名医生的判断是否有差异时,我们需要采用McNemar配对卡方检验;之前t检验我们提到,配对t检验主要用于计量资料的比较;当效应指标为计数资料时,则需采用配对设计卡方检验(McNemar检验)。 SPSS中的实现:1.“数据加权”,2.“分析”-“描述性统计”-“交叉表”,3.参数设置:“统计”-“McNemar(M)”; ☆ END ☆ 下期内容 卡方拟合性检验

工作分享 - Git获取不同版本之间的增量文件(差异文件)

亲测成功!!! 实现效果:主要针对项目业务中,对代码上传方式Git/SVN的更新操作。做到当GIit仓库中出现版本提交时,将差异文件保存到本地。 之前接触的都是手动idea进行差异文件对比,还真没有通过代码的方式来读取过,经过实践成功读取差异文件,分享出来,大家一起学习,欢迎提出建议问题!!! 后序会更新 SVN 获取不同版本之间的增量文件(差异文件) 目录 一、依赖: 二、业务逻辑 1. 首先将代码克隆到本地/opt/code目录下(我这里放到的是/opt/code); 2. 获取两次Git版本的id; 3. 比较不同版本之间的差异文件; 三、整体代码 四、引用方法 五,外部链接 一、依赖: <dependency> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit</artifactId> <version>5.13.1.202206130422-r</version> </dependency> 二、业务逻辑 1. 首先将代码克隆到本地/opt/code目录下(我这里放到的是/opt/code); 2. 获取两次Git版本的id; 3. 比较不同版本之间的差异文件; 三、整体代码 @Test public void test() { // 初始化数据 String localPath = "/opt/code"; //本地存放代码地址 String url = "https://127.0.0.1:9999/git/code";//git远程地址 String branchName = "master";//git远程地址分支 String username = "";//git远程地址账户 String password = "";//git远程地址密码 // 1.首先将代码克隆到本地/opt/code目录下 Git git = null; try { //验证Git登录 CredentialsProvider credentialsProvider = new UsernamePasswordCredentialsProvider(username, password); //将代码clone到本地 git = Git.

Numpy 的dot方法使用float比int快,记录笔记

import pandas as pd import numpy as np def jaccard(data=None): ''' 构建物品相似度矩阵(杰卡德相似系数) :param data: 用户物品矩阵,0-1矩阵;行为用户,列为物品 :return: jaccard相似系数矩阵 ''' te = -(data-1) # 将用户物品矩阵的值反转 dot1 = np.dot(data.T, data) # 任意两网址同时被浏览次数 dot2 = np.dot(te.T, data) # 任意两个网址中只有一个被浏览的次数(上三角表示前一个被浏览,下三角表示后一个被浏览) dot3 = dot2.T+dot2 # 任意两个网址中随意一个被浏览的次数 cor = dot1/(dot1+dot3) # 杰卡德相似系数公式 for i in range(len(cor)): # 将对角线值处理为零 cor[i, i] = 0 return cor data_train = a1[0:800000] data_train = data_train.reset_index(drop=True) data_test = a1[800000:857525].sample(n=5000) data_test = data_test.reset_index(drop=True) data_test1 = a1[800000:857525] data_test1 = data_test1.

Gentoo忘记密码无法登录后重置密码

Gentoo忘记密码无法登录后重置密码 1.首先,通过U盘启动系统。 2.挂载root分区mount /dev/sda3 /mnt/gentoo(通过ls /dev查看具体设备名称) 3.change root:chroot /mnt/gentoo /bin/bash 4.通过passwd命令修改管理员密码。

mysql小表驱动大表

摘要: 小表驱动大表是优化器从成本考虑后做出的选择 判断谁做小表时,是比较算上过滤条件后的字段+条数的总大小 小表驱动大表在执行计划中体现,第一行是小表第二行是大表。不是在show warnings体现 left join时右表过滤条件在where,优化器会转为inner join小表驱动大表。 left join时右表过滤条件在on,优化器不会优化成小表驱动大表,因为无法转为inner join,所以要自己把小表放左边,大表放右边 inner join时优化器会自动小表驱动大表 course–100条数据 student_info–100w条数据 优化器会选择小表驱动大表(这里表指的是算上过滤条件的表) `EXPLAIN SELECT a.*,b.* FROM `course` a JOIN `student_info` b ON a.`course_id`=b.`course_id` EXPLAIN SELECT a.* FROM `student_info` a JOIN `course` b ON a.`course_id`=b.`course_id` 加上过滤student_info的条件 EXPLAIN SELECT a.*,b.* FROM `course` a JOIN `student_info` b ON a.`course_id`=b.`course_id` WHERE b.`student_id`=1 执行计划改变,由小表student_info驱动大表course,得出优化器先走where后join的结论。 查看优化器优化后的sql show warnings from atguigudb1.course a join atguigudb1.student_info b where ((atguigudb1.a.course_id = atguigudb1.b.course_id) and (atguigudb1.b.student_id = 1))

CSS基础知识(二)——盒子模型

目录 盒子模型 1.盒子模型介绍 1.1盒子的概念 1.2盒子模型 2.内容区域的宽度和高度 2.1 内容的宽度和高度 3.边框(boder) 3.1 边框(border)-单个属性 3.2 边框(border)-连写形式 3.3 边框(border)-单方向设置 3.4 盒子实际大小初级计算公式 4.内边距(padding) 4.1 内边距(padding)-取值 4.2 内边距(padding)-单方向设置 4.3 盒子实际大小终极计算公式 4.4(拓展)不会撑大盒子的特殊情况 4.5内减模式(边框盒子) 5.外边距(margin) 5.2 外边距(margin)-单方向设置 5.3 margin单方向设置的应用 5.4 清除默认内外边距 5.5 外边距正常情况 5.6 外边距折叠现象–①合并现象 5.7 外边距折叠现象–②塌陷现象 5.8 行内元素的margin和padding无效情况 对于盒模型的补充 盒模型的分类 两种盒模型的区别 计算盒子大小的公式 盒子模型 1.盒子模型介绍 1.1盒子的概念 页面中的每一个标签,都可看做是一个“盒子”,通过盒子的视角更方便的进行布局浏览器在渲染(显示)网页时,会将网页中的元素看做是一个个的矩形区域,我们也形象的称之为盒子 1.2盒子模型 CSS 中规定每个盒子分别由:内容区域(content)、内边距区域(padding)、边框区域(border)、外边距区域(margin)构成,这就是盒子模型 2.内容区域的宽度和高度 2.1 内容的宽度和高度 作用:利用width 和height 属性默认设置是盒子内容区域的大小 属性:width /height 常见取值:数字+px 3.边框(boder) 3.1 边框(border)-单个属性 作用:给设置边框粗细、边框样式、边框颜色效果。 单个属性: 作用属性名属性值边框粗细border-width数字+px边框样式border-style实线solid、虚线dashed、点线dotted边框颜色border-color颜色取值 3.2 边框(border)-连写形式 属性名:border

Postgresql的灾备管理(二)一主一备——几个软件的缝合怪

前文所述,我抛弃了repmgr改用pgpool,就是看重了其丰富的灾备功能,很不幸的是,符合要求的snapshot模式宕机了,而且是官方修不好的那种,无奈放弃。 剩下的选项就是patroni. 又仔细研究了patroni的说明,对于备故障是有改同步复制为异步复制的功能,然而必须依赖etcd或者consul等分布式多活检测器,必须部署3台以上,而且主服务器身份的漂移只能通过HAproxy来实现,等于一个灾备程序需要再搭用2个其他程序,还要多加一台备用服务器,一点都不简单。 所幸的是,pgpool官方给了很多的bash脚本,以此为基础,我可以通过对repmgr的修补,来补全灾备功能,实现前述的2台机器条件下的乘法原理。以下是对repmgr功能缺陷的补全方案: 1)备服务器故障造成同步的主服务器无法接受写操作——更换postgresql相关的配置,将同步复制改成异步复制,使用reload进行不停机切换。但是当备服务器恢复了,重新加入进来后,也应该相应的恢复为同步复制。 2)备服务器切换为主服务器,应用程序无法得知——使用firewalld对写程序的接口进行端口转发的反向代理。在这种事件发生后试图在两台机器上进行切换,当然旧主服务器的机器可能根本无法接通,在恢复后应该先去备服务器进行检查,并同步最新的反向代理流向。用pgpool中学会的postgres账号互通进行切换,通过特殊的sudo设置和执行bash脚本去更改在firewalld的反向代理设置。读程序则在本机直接连,无需特意更改。 这里使用firewalld的端口转发(NAT)功能而不是虚拟IP来实现主服务器身份的漂移,不仅仅是因为大部分的云服务设置虚拟IP都非常麻烦,而且更重要的是两台数据库服务器为了实现最大限度的不相关性,已经分属于2个可用区的2个子网,虚拟IP策略根本无法跨网段,是无效的。又不想用HAProxy,就直接用Linux自带的底层NAT来实现反向代理了。 3)主服务器必须记录自己是否在solo状态。记录和解除都在故障切换时实现。则恢复后启动先检查自己是否在solo状态,如果是则直接作为主启动,并且试图通知另一台当备。如果不是则先检查另一台是否已经启动了,如果启动主动当备,如果还未启动则挂机等待另一台给信号,自己再去当备。 以上的实现依赖于repmgr的event_notification_command等接口,它们可以将当前发生的事件和具体细节传输给自定义的脚本来具体处理。当然开机启动也必须编写相应的脚本,来实现对repmgr启动的控制,避免主备身份出错。

docker启动mysql

1.创建文件路径 mkdir -p /etc/mysql/data mkdir -p /etc/mysql/conf.d 2.在conf.d文件夹下创建my.cnf [mysqld] # 设置3306端口 port=3306 # 设置mysql的安装目录 datadir=/var/lib/mysql # 允许最大连接数 max_connections=200 # 允许连接失败的次数。这是为了防止有人从该主机试图攻击数据库系统 max_connect_errors=10 # 服务端使用的字符集默认为UTF8 character-set-server=utf8mb4 # 创建新表时将使用的默认存储引擎 default-storage-engine=INNODB lower_case_table_names=1 # 默认使用“mysql_native_password”插件认证 default_authentication_plugin=mysql_native_password [mysql] # 设置mysql客户端默认字符集 default-character-set=utf8mb4 [client] # 设置mysql客户端连接服务端时默认使用的端口 port=3306 default-character-set=utf8mb4 3.docker启动mysql docker run -p 3306:3306 -e MYSQL_ROOT_PASSWORD=My_678# \ -v /etc/mysql/data:/var/lib/mysql \ -v /etc/mysql/conf.d:/etc/mysql/conf.d \ --name mysql \ -d mysql:latest 这样就可以了 ======================================================================== 遇到几个问题: 问题1.navicat连接时报下面错误 解决方法: 解决方法: 在8之前版本加密规则是mysql_native_password,8之后加密规则是caching_sha2_password。 1.docker exec -it mysql8 bash

docker 网络配置详解

目录 1、docker网络模式 2、容器和容器之间是如何互通 3、容器之间互通 --link 3、自定义网络 4、不通网段的容器进行网络互通 1、docker网络模式 docker 网络模式采用的是桥接模式,当我们创建了一个容器后docker网络就会帮我们创建一个虚拟网卡,这个虚拟网卡和我们的容器网络是一一对应(成对出现)。默认创建的容器都是docker0网卡。 2、容器和容器之间是如何互通 当我们创建一个容器时没有指定容器网络时,docker会默认走docker0网络,docker会默认在虚拟机上创建一个虚拟网卡这个网卡地址会和我们容器地址对应。此时会出现我们可以通过互ping容器的ip 地址可ping通容器,但是通过容器名互ping是无法ping通,因技术要求需要我们自定义网络ip达到互通;默认创建的容器都是docker0网卡。 ##查看Tomcat01 的ip地址 docker exec -it tomcat01 ip addr [root@localhost ~]# docker exec -it tomcat01 ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 8: eth0@if9: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff inet 172.

Vue3封装全局函数式组件

文章目录 前言一、函数式组件是什么?二、创建一个函数式组件1. 封装toast组件2. 创建应用实例3. 注册插件(可省略)Q&A: 补充一些注释①:为什么采用调用函数方法的方式去控制显隐②:函数式组件的这两个文件之间的联系 三、调用1. 注册插件后在.vue文件内获取全局方法2. 可不注册插件,在.vue或.js文件内直接调用方法 四、优化改进1、单例模式(推荐)2、多个提示弹窗3、简化传参 总结扩展阅读 前言 相信大家在 Vue 中考虑复用逻辑的时候经常使用组件化开发,也肯定使用过函数式组件,就是那种在 js 中也能够导入调用的组件。那么如何去封装这么一个函数式组件呢,这篇文章将采用Toast组件简单介绍一下封装的方法,封装之后就能大大提高我们开发的效率了。 一、函数式组件是什么? 简单介绍一下声明式组件与函数式组件,大多数时候我们引入组件都采用声明式的的方式,这里以 Vant 组件库为例,类似 Button 按钮这种就是声明式组件: <van-button type="primary">主要按钮</van-button> 还有类似 <TheWelcome /> 这种自定义名称且在 .vue 文件里引用其他 .vue 文件的就是声明式组件 <template> <main> <TheWelcome /> </main> </template> <script setup lang="ts"> import TheWelcome from '../components/TheWelcome.vue'; </script> 而函数式组件则是通过调用 API 的方式快速唤起全局的组件,还是以 Vant 组件库为例,比如使用 Toast 组件,调用函数后会直接在页面中渲染对应的轻提示: import { showToast } from 'vant'; showToast('提示内容'); 通常我们使用函数式组件是在某个交互完成时触发,又或者是在非.vue文件里唤起全局的组件,例如封装axios,在axios.js中使用Toast组件显示报错信息: showToast('服务器响应超时,请刷新当前页'); 二、创建一个函数式组件 下面将创建一个自己定义的toast组件,由于这个toast组件默认是显示成功的,所以称之为“okToast”,先展示一下调用后的效果: 1. 封装toast组件 与创建声明式组件一致,在.vue文件里定义好组件接收的参数还有组件的样式。代码如下(示例): <template> <!

flink postgresql cdc实时同步(含pg安装配置等)

文章目录 1. 环境信息2. 安装3. 配置4. 新建用户并赋权5. 发布表6. flink sql7. 命令汇总 1. 环境信息 类型版本/描述docker20.10.9Postgresql10.6初始化账号密码:postgres/postgres 普通用户:test1/test123 数据库:test_dbflink1.13.6 2. 安装 step1: 拉取 PostgreSQL 10.6 版本的镜像: docker pull postgres:10.6 step2:创建并启动 PostgreSQL 容器,在这里,我们将把容器的端口 5432 映射到主机的端口 30028,账号密码设置为postgres,并将 pgoutput 插件加载到 PostgreSQL 实例中: docker run -d -p 30028:5432 --name postgres-10.6 -e POSTGRES_PASSWORD=postgres postgres:10.6 -c 'shared_preload_libraries=pgoutput' step3: 查看容器是否创建成功: docker ps | grep postgres-10.6 3. 配置 step1:docker进去Postgresql数据的容器: docker exec -it postgres-10.6 bash step2:编辑postgresql.conf配置文件: vi /var/lib/postgresql/data/postgresql.conf 配置内容如下: # 更改wal日志方式为logical(方式有:minimal、replica 、logical ) wal_level = logical # 更改solts最大数量(默认值为10),flink-cdc默认一张表占用一个slots max_replication_slots = 20 # 更改wal发送最大进程数(默认值为10),这个值和上面的solts设置一样 max_wal_senders = 20 # 中断那些停止活动超过指定毫秒数的复制连接,可以适当设置大一点(默认60s,0表示禁用) wal_sender_timeout = 180s step3:重启容器:

轻松打造您的网站:海外免费虚拟主机的完美选择!

在现代互联网时代,拥有一个网站是非常重要的,无论是个人还是企业。网站可以帮助我们展示信息,推广产品和服务,并与全球范围内的潜在客户建立联系。但是,对于一些初学者或预算有限的人来说,创建一个网站可能是一项具有挑战性的任务。在这种情况下,海外免费虚拟主机可能是一个引人注目的选择。本文将探讨海外免费虚拟主机的优势和劣势,并为您提供相关信息,帮助您决定是否选择它作为网站建设的解决方案。 什么是海外免费虚拟主机? 海外免费虚拟主机是一种由位于国外的托管提供商提供的免费虚拟主机服务。这些服务通常基于云计算技术,使用户能够在互联网上创建和托管自己的网站,而无需支付费用。用户可以通过注册账户、选择域名和模板以及上传内容来建立自己的网站。 海外免费虚拟主机的优势 价格优势 对于那些预算有限或刚刚开始的个人用户和小型企业,海外免费虚拟主机具有显著的价格优势。相比之下,传统的虚拟主机服务通常需要付费,这对于初学者来说可能是一个负担。 简单易用 海外免费虚拟主机通常提供简单易用的用户界面和工具,使用户能够轻松创建和管理他们的网站。即使没有专业的技术知识,用户也可以通过简单的拖放操作和预设模板来定制自己的网站。 快速搭建网站 使用海外免费虚拟主机,您可以快速搭建一个简单的网站。这对于那些需要尽快上线的用户来说是非常有吸引力的。您可以选择预设模板,进行一些自定义设置,然后立即发布您的网站。 海外免费虚拟主机的劣势 限制和限制 尽管海外免费虚拟主机提供了很多便利,但它们通常附带一些限制和限制。这可能包括存储空间、带宽和数据库等方面的限制。这意味着您可能无法在网站上存储大量文件或处理大量流量。 不稳定的性能 由于海外免费虚拟主机通常是由免费提供的,所以它们的性能可能不如付费的虚拟主机稳定。您可能会遇到网站加载速度较慢或不稳定的问题,这可能会影响访问者的体验。转载自https://cn.hostease.com/blog/shared-hosting/17537.html 安全风险 免费的虚拟主机服务通常没有像付费服务那样严格的安全措施。这可能使您的网站容易受到恶意攻击或数据泄露的风险。如果您处理敏感数据或进行在线交易,您可能需要考虑更安全的托管选项。 如何选择适合的海外免费虚拟主机 可靠性和可用性 在选择海外免费虚拟主机时,您应该考虑其可靠性和可用性。查看提供商的服务水平协议(SLA)和用户评价,以了解其性能和可靠性记录。选择那些有良好声誉和高可用性的提供商。 支持和客户服务 良好的技术支持和客户服务对于使用海外免费虚拟主机是至关重要的。确保您选择的提供商提供快速响应的支持渠道,并具有可以解决问题的技术团队。 功能和扩展性在选择海外免费虚拟主机时,您还应该考虑其提供的功能和扩展性。确保虚拟主机提供商支持您所需的功能,例如数据库支持、电子邮件服务和域名管理。此外,您还应该考虑将来网站发展的可能性,因此选择一个具有良好扩展性的虚拟主机解决方案。 其他网站建设选择 除了海外免费虚拟主机,还有其他各种网站建设选择可供选择,具体取决于您的需求和预算。 虚拟主机 虚拟主机是一种常见的网站托管解决方案,适用于个人用户和小型企业。在虚拟主机中,多个用户共享同一台服务器资源,这使得它更经济实惠。然而,与免费虚拟主机相比,虚拟主机通常提供更好的性能和支持。 独立服务器 独立服务器是一种高级的托管解决方案,适用于需要更高级功能和更高性能的用户。在独立服务器中,您将拥有整个服务器的资源,并享有更高的灵活性和安全性。然而,独立服务器的成本相对较高,适合具有更大预算和更高要求的用户。 云托管 云托管是一种灵活的网站托管解决方案,利用云计算技术。它可以根据您的实际需求自动扩展资源,从而提供更好的可伸缩性和可靠性。云托管通常提供高级的安全性和性能,并适用于中型和大型企业。 总结 创建一个网站对于个人和企业来说都是至关重要的,而海外免费虚拟主机可能是一种引人注目的选择。它具有价格优势、简单易用和快速搭建网站的特点。然而,它也带来了一些限制、不稳定的性能和安全风险。在选择海外免费虚拟主机时,您应该考虑可靠性、支持和客户服务以及功能和扩展性。此外,还有其他网站建设选择可供选择,如虚拟主机、独立服务器和云托管。

分析库缓存锁问题

查询sql造成库缓存锁 library cache lock,在ash报告中出现library cache lock 就是底层数据结构锁了,原因有其他事件在获取S或者X锁,该事件发生事件较长,影响到了业务。 通过AWR报告可以看出,这条SQL执行时间太长了 记录了执行总和时间的TOP SQL 记录了SQL占用library cache的大小的TOP SQL 打开游标数量也非常高 通过oracle的AWR报告发现这条sql语句执行时间非常之长,占用库缓存的比重非常之大,打开子游标数量也非常高 通过ASH报告,library cache lock,还有cursor:pin S wait on X 造成这种原因就是 1.Shared pool设置过小,或者由于自动内存管理导致 2.频繁的硬解析 3.子游标太多 分析: 通过AWR,ASH报告,定位到SQL,找到代码,发现调用这个SQL特别频繁,而且数据量巨大,虽然通过SQL的执行计划看到SQL都走了索引,代码中看到SQL语句有一部分不是通过?进行替换的,而是通过+'值'+的方式进行拼接的,如果通过+号拼接的代码SQL走的是硬解析,没有走软解析。 硬解析: 硬解析是指Oracle在执行目标SQL时,在库缓存中找不到可以重用的解析树和执行计划,而不得不从头开始解析目标SQL并生成相应的父游标和子游标的过程。 硬解析实际上有两种类型:一种是在库缓存中找不到匹配的父游标,此时Oracle会从头开始解析目标SQL,新生成一个父游标和一个子游标,并把它们挂在对应的HashBucket中;另外一种是找到了匹配的父游标但未找到匹配的子游标,此时Oracle也会从头开始解析该目标SQL,新生成一个子游标,并把这个子游标挂在对应的父游标下。 select * from TEXT where id=20; 软解析: 软解析是指Oracle在执行目标SQL时,在Library Cache中找到了匹配的父游标和子游标,并将存储在子游标中的解析树和执行计划直接拿过来重用而无须从头开始解析的过程。 select * from TEXT where id:id; 

游戏在32位的iPhone手机下面没有问题,在64位的手机,如iPhone6下面,运行出现错误

用lua开发了游戏,用下面的脚本加密成luac文件 cocos luacompile -s src/ -d out/ -e -k MyKey -b 123456 游戏在32位的iPhone手机下面没有问题,在64位的手机,如iPhone6下面,运行出现错误,提示: “asserts/src/main.luac”, error: syntax error during pre-compilation. 原因: 那个luajit号称支持64位 只是支持明文 而不是字节码。 字节码支持x86-64(64位模拟器), 但是不支持arm64, 或者说支持arm64的字节码的方法很麻烦 cocos没有支持 并且64位的字节码和32位的也不是同一套 解决方法: 认真看了下cocos2d-console里面plugin_luacompile中的__init__.py,发现里面是有判断用不用luajit的。 if self._disable_compile: shutil.copy(lua_file, dst_lua_file) else: self.compile_lua(lua_file, dst_lua_file) 对应的参数--disable-compile,按论坛说的,luajit可能性能更好一些,但我最重要的目的是加密,所以不用luajit,问题应该也不大。

Redis面经:跳表中节点的数据结构?新节点的层数如何确认?

面经1 1. 简单说一下zset底层数据结构1.1 简单说一下压缩列表的数据结构2 跳表是什么?2.1 跳表的节点的数据结构是怎么样的?2.2 新节点的层数是如何确定的?2.3 最多多少层?3. 为什么不用红黑树,平衡树,要用跳表? 1. 简单说一下zset底层数据结构 答:压缩列表、跳表 1.1 简单说一下压缩列表的数据结构 答:压缩列表本质上是数组,增加了列表长度、尾部偏移量、列表元素个数、结束标识,这些标识有利于寻找首尾元素 2 跳表是什么? 答:跳表是在多级链表的基础上增加了多级索引的结构。 2.1 跳表的节点的数据结构是怎么样的? 答:直接看Redis源码 typedef struct zskiplistNode { sds ele; double score; struct zskiplistNode *backward; struct zskiplistLevel { struct zskiplistNode *forward; unsigned long span; } level[]; } zskiplistNode; 2.2 新节点的层数是如何确定的? 答:zslRandomLevell()返回一个随机级别,返回值介于1和ZSKIPLIST_MAXLEVEL之间 level = zslRandomLevel(); ... x = zslCreateNode(level,score,ele); ... int zslRandomLevel(void) { static const int threshold = ZSKIPLIST_P*RAND_MAX; int level = 1; while (random() < threshold) level += 1; return (level<ZSKIPLIST_MAXLEVEL) ?

Open3D 入门教程

文章目录 1、概述2、安装3、点云读写4、点云可视化4.1、可视化单个点云4.2、同一窗口可视化多个点云4.3、 可视化的属性设置 5、k-d tree 与 Octree5.1、k-d tree5.2、Octree5.2.1、从点云中构建Octree5.2.2、从体素栅格中构建 Octree 6、点云滤波6.1、体素下采样6.2、统计滤波6.3、半径滤波 7、点云特征提取7.1、法线估计 8、点云分割8.1、DBSCAN 聚类分割8.2、RANSAC 平面分割8.3、隐藏点剔除 9、点云曲面重建9.1、Alpha shapes9.2、Ball pivoting9.3、Poisson surface reconstruction 10、点云空间变换10.1、Translate 平移10.1.1、指定平移行向量,实现点云平移10.1.2 将点云质心平移到指定位置 10.2 Rotation 旋转10.2.1 使用欧拉角旋转10.2.1.1 未指定旋转中心10.2.1.2 指定旋转中心 10.2.2 使用轴向角旋转10.2.3 使用四元数旋转 10.3 Scale 缩放10.4 General transformation 一般变换(平移+旋转) 11、点云配准12、其他常用算法12.1、计算点云间的距离12.2、计算点云最小包围盒12.3、计算点云凸包12.4、点云体素化12.4.1、一种简单的方法12.1.2、复杂方法 12.5 计算点云质心12.6、根据索引提取点云12.7、点云赋色 1、概述 Open3D是一个开源库,支持快速开发处理3D数据的软件。Open3D后端是用C++实现的,经过高度优化并通过Python的前端接口公开。Open3D提供了三种数据结构: 点云 (point cloud)、网格(mesh)和RGB-D图像。对于每个表示,open3D都实现了一整套基本处理算法,如I/O、采样、可视化和数据转换。此外,还包括一些常用的算法,如法线估计、ICP 配准等。 open3D包含了九个模块,如下表所示: 模块功能Geometry 几何模块数据结构和基本处理算法Camera 相机模块相机模型和相机轨迹Odometry 里程计模块RGB-D图像的跟踪与对齐Registration 配准模块全局和局部配准Integration 积分模块体积积分I/O 输入输出模块读写3维数据Visualization 可视化模块使用OpenGL呈现3D数据的可自定义GUIUtility 辅助功能模块辅助功能,如控制台输出、文件系统和特征包装器Python 模块Open3D Python绑定和教程 本文旨在快速入门Python点云数据处理,原理性知识会在后续专题中给出,这里不做过多描述。 2、安装 pip install open3d 3、点云读写 代码: import open3d as o3d import numpy as np print("

基于SPDK-vhost的云原生Kubevirt虚拟化存储IO的优化方案

摘要 本文主要介绍针对云原生kubernetes虚拟化IO的应用场景,在Kubevirt中引入SPDK-vhost的支持,来加速虚机中IO存储性能。同时基于Intel开源的Workload Service Framework[1]平台集成部署一套端到端虚拟化IO的应用场景做基本的性能对比测试。 云原生Kubevirt虚拟化 在云原生时代,越来越多的业务开始逐步迁移到容器上来,容器也成为了一种不可或缺的资源发布和管理形式,同时由于场景的需求,有部分业务形态更适合运行在虚拟机,如何同时管控虚拟机和容器逐渐成为了云原生时代的主流需求,Kubevirt给出了完美的解决方案。VM在Kubernetes环境中的管理和部署工具Kubevirt是 Red Hat 开源的,是基于Kubernetes运行,具体的来说是基于Kubernetes的CRD(自定义资源)增加虚拟机的运行和管理相关的资源,特别是VM,VMI资源类型。用户可以在K8S环境中通过CRD进行增加关于虚拟机的资源类型,再通过部署VM.yaml的形式来创建虚拟机等一系列的操作。 图1:云原生Kubevirt架构介绍 如图1所示绿色模块是Kubevirt的原生插件和功能模块,在master上部署virt-controller和virt-api,virt-api是管理虚拟机资源及其运营管理的接口,而virt-controller则负责管理和监控VM实例对象及其关联的POD,其中virt-launcher POD就是virt-controller依据VM的配置文件来创建的。这里需要关注的是virt-launcher POD,每一个virt-launcher承载一个VM实例,其内部是通过libvirtd来管理虚拟机的生命周期。 引入SPDK-vhost加速Kubevirt虚拟化IO 在实际边缘计算和云计算应用场景中,不少客户使用云原生的Rook-Ceph来部署后端存储服务。以常用的block设备为例,用户在创建虚机之前,先通过PV/PVC向Rook-Ceph存储申请volume资源,在创建虚机的时候挂载到VM中,如下图2所示。这种Kubevirt虚机挂载使用Ceph block IO的本质是通过Ceph kernel rbd来提供block块设备,而Kubevirt的虚机则是使用传统的virtIO的前端和后端方案,实际的应用中,会带来频繁的用户空间和内核空间的切换,同时这种基于Qemu-KVM的半虚拟化的IO模型会伴随着大量KVM的VM EXIT和VM ENTRY事件,同时产生大量中断,这会带来不少系统资源的消耗和IO latency 的增大。 图2:Kubevirt VM在Ceph存储上的使用 集成SPDK-vhost到Kubevirt 众所周知,业界为了优化virtIO的虚拟化IO性能,而引入vhost的模型,以便减少频繁的用户空间和内核空间的切换和数据的拷贝。而在我们云原生虚拟化场景中引入了SPDK-vhost在空户空间的一种虚拟化IO优化的方案,基于KubeVirt中引入SPDK-vhost的deamonset模块来加速VM中block IO的访问,对于SPDK-vhost的具体细节可以参考SPDK官网介绍[2]。如下图3所示,我们针对Kubevirt中virt-launcher模块进行优化,加入spdk-vhost-user的接口功能,提供对SPDK-vhost的接口检测和通讯,以便在VMI实例中使用SPDK-vhost的接口给VM提供加速的block功能。同时,当在K8S集群中部署Kubevirt的时候我们同时会在集群中部署SPDK-vhost daemonset,在每个节点都会部署一个SPDK-vhost功能POD。而SPDK-vhost POD中的接口会相应的检测和并通过librbd链接到后端的Rook-Ceph,创建对应的SPDK rbd bdev 设备,再以此bdev设备创建vhost-block controller。基于此,当virt-launcher发起创建虚机的过程中,vhost-user接口模块会解析VM yaml文件中定义的块设备信息,并链接到SPDK-vhost POD 向该模块申请特定size的 block设备,而SPDK-vhost守护进程则会向Rook-Ceph申请对应的卷空间,一旦成功,则会在VM中成功看到虚拟磁盘,而此虚拟磁盘则是基于Ceph块设备通过SPDK-vhost加速之后提供的。 图3:引入SPDK-vhost的Kubevirt架构 下面介绍一下KubeVirt虚机的部署过程中SPDK-vhost功能的接口。如下图4所示,SPDK-vhost模块支持对Rook-Ceph的存储功能管理和链接,能够按需申请Ceph RBD存储卷,并在SPDK内部对应的创建rbd-bdev逻辑设备,再将bdev设备挂接到创建的vhost block controller上,而虚机中vdisk是通过共享内存的方式和SPDK-vhost做数据传输。在控制面,virt-launcher中的libvirt是通过链接SPDK-vhost所提供vhost socket来实现通讯。 图4:基于SPDK-vhost的Kubevirt VM的接口机制 对于新的方案的部署和实施流程如下图5所示,以Rook-Ceph为后端存储为例,用户需要在Kubernetes集群环境中预先部署Rook-Ceph和优化过的Kubevirt版本。同时确保SPDK-vhost daemonset正常部署到集群中(当前示例是将SPDK-vhost deamonset单独作为一个模块部署,没有和kubevirt的部署集成到一起)。SPDK-vhost POD中有接口会检测Root-Ceph的环境健康状态并建立链接。随后用户基于编写好的VM yaml文件部署虚机,通过virt-api的将创建VM的信息和资源申请传递给virt-controller,那么virt-controller则会创建virt-launcher POD以便在内部创建VM实例。如下图所示,virt-launcher会往本地node上SPDK-vhost POD发送创建volume的请求,SPDK-vhost POD则会通知Rook-Ceph创建相应的RBD image,成功之后会在SPDK-vhost POD中创建一个SPDK-vhost controller,同时返回结果给到virt-launcher,至此基于SPDK-vhost的block设备创建成功,那么virt-launcher则会正式通知libvirt创建虚机并挂载相应的virtual block设备。 图5:基于SPDK-vhost的Kubevirt VM的部署流程 如下图6所示,用户在创建虚机之前,需要在VM yaml文件中申明基于“spdkVhostBlkDisk”类型的块设备,并申请相应的卷容量。 图6:申请SPDK-vhost类型的块设备 性能的对比 我们基于Intel开源的WSF (Workload Service Framework,见下一节)框架搭建一套端到端的全栈式workload来对使用SPDK-vhost的虚拟化IO方案和使用Kubevirt内置virtIO方案做性能对比测试。这里采用的是一套三节点集群的存储超融合环境,部署2副本的Rook-Ceph在该集群中,同时在该集群中均匀的部署3个虚机,每个虚机挂载3个虚拟卷。该workload [3]的具体实现可以参考WSF git仓库中的代码和相应的手册。下面是对于使用Kubevirt内置的virtIO方案和加入SPDK-vhost的方案的性能对比。

Python视频剪辑合并操作

介绍 很多人在创作视频时都需要进行剪辑,例如删减无用镜头、调整视频长度等等。这些任务通常需要使用视频编辑软件,例如Adobe Premiere和Final Cut Pro等。然而,如果你想批量剪辑大量视频,或者想用编程方式剪辑视频,Python将为你提供方便的解决方案。 在本文中,我们将介绍如何使用Python进行视频剪辑的完整攻略。我们将探讨如何使用Python库FFmpeg和MoviePy来剪切、合并和转换视频。 安装FFmpeg FFmpeg是一种流行的开源软件,可以用于处理视频和音频文件。因为我们将使用Python库FFmpeg进行视频剪辑,所以需要先安装FFmpeg。 Windows 在Windows上,你可以下载预编译的二进制文件并将其添加到系统路径中。你可以到FFmpeg的官方网站下载FFmpeg的Windows版本。然后将bin文件夹添加到你的系统PATH环境变量中。 MacOS 在MacOS上,可以使用Homebrew来安装FFmpeg。打开终端并执行以下命令: brew install ffmpeg Ubuntu 在Ubuntu上,可以使用apt来安装FFmpeg。打开终端并执行以下命令: sudo apt update sudo apt install ffmpeg 安装MoviePy MoviePy是一个用于处理视频和音频文件的Python库。它建立在FFmpeg和ImageMagick的基础上,并提供了用于剪切、调整大小、合并视频和添加文本等高级功能。 可以使用pip来安装MoviePy。打开终端并执行以下命令: pip install moviepy 剪切视频 使用MoviePy剪切视频非常简单。以下是将视频从第10秒到第20秒的时间段剪切出来的示例: from moviepy.video.io.VideoFileClip import VideoFileClip # 定义剪辑时间段 start_time = 10 # 开始时间,单位为秒 end_time = 20 # 结束时间,单位为秒 # 读取视频文件并剪辑 video = VideoFileClip("video.mp4").subclip(start_time, end_time) video.write_videofile("cut_video.mp4") 由于MoviePy基于FFmpeg和ImageMagick,所以可以处理多种视频格式,例如MP4、AVI和MOV等。 合并视频 使用MoviePy合并视频也非常简单。以下是将两个视频文件组合在一起的示例: from moviepy.video.io.VideoFileClip import VideoFileClip from moviepy.video.fx.all import resize # 读取要组合的视频文件 video1 = VideoFileClip("

mysql数据库管理-GTID详解

总结1 数据库重启GTID值不变。 1 GTID不会改变 查看 show master status \G 55390eba-d320-11eb-8e31-00ffaabbccdd:1-4 net stop mysql80 net start mysq80 use test; delete from t1 limit 1; show master status \G 55390eba-d320-11eb-8e31-00ffaabbccdd:1-5 总结2 SET @@GLOBAL.GTID_PURGED=/*!80000 '+'*/ '55390eba-d320-11eb-8e31-00ffaabbccdd:1-5'; 已经清除掉的不再执行。 总结 3 跳过某个 gtid MySQL [(none)]> set gtid_next='9ba7958e-2ce8-11ed-ad3c-bc16951e4027:44568546'; Query OK, 0 rows affected (0.00 sec) MySQL [(none)]> begin; Query OK, 0 rows affected (0.00 sec) MySQL [(none)]> commit; Query OK, 0 rows affected (0.00 sec)

M.2固态硬盘接口说明

下边是原文,个人总结: B-key基本淘汰(左侧单口),NVME协议购买M-key接口的(右侧单口),B&M-key接口的一般是SATA协议(左右双口)。 -------------------------------------------------------- 原文地址 M.2 接口详解 - 知乎 1. SSD 尺寸与规格 我们在买ssd的时候,商家都会说什么ssd是2280还是2242规格的,这里的规格实际上就是代表的ssd的尺寸大小 M.2模组的尺寸目前有11种,用Type xxyy的方式表示,xx表示宽度,yy表示长度,单位为毫米。例如上面提到的Type 2230则表示其宽度22nm,长度30nm;Type 2242,表示其宽度22mm,长度42mm;Type 2280则表示其宽度22nm,长度80nm。目前M.2 SSD常见的Type有三种,就是2230、2242、2280。 2. SSD接口 按照接口类型分,可以把m.2接口分为Socket 2和Socket 3 Socket 2也可以叫做B key,支持sata,pcie x2 Socket 3也可以叫做M key,支持sata,pcie x4 B key 的防呆键位于插槽的左方,M key 则在右方。两种类型的插槽其短边接脚数量有所差异 一开始,B key的只能插在b key(Socket 2)的接口中,m key的只能插在m key(Socket 3)的接口中,但是随着m key接口的普及,越来越多电脑主板只有m key 接口,b key的ssd根本插不上去,于是厂商们又设计了一个b&m key接口的ssd。 b&m key接口即可以插上b key也可以插上m key。b&m key支持的通道和b key支持的通道一样,都是sata pcie x2,但是b&m key可以兼容m key 和b key两种,而b key只能兼容b key一种,这就导致了b key毫无优势,b key被b&m key取代,现在市面上只有b&m key和m key两种m2 ssd卖, b key的m2 ssd 已经绝迹

对mysql索引、排序理解

节前和同时讨论了一下mysql的索引,发现自己对索引的理解有很大问题,国庆节就看了一下这里做一下记录,目前了解的比较浅如果有理解错的地方还请大家可以提出来一起讨论、学习 再聊索引之前我们一起聊一下表在windows里面的存储,其实库在机器里面就是一个目录 表就是对应库目录下面的以.frm结尾的文件,文件里面就记录了一条条数据 什么是索引 自己理解就是存在磁盘里面为了提升查询速度的一棵树,当然在需要的时候会将索引从磁盘加载到内存里 聚簇索引 聚簇索引就是主键索引下面是画的一张主键索引草图,当我们通过索引查询的时候先会将索引树加载到内存里面,之后通过二分法找到值所在磁盘,将指定磁盘加载到内存在通过二分法找到主键下面对应的数据 非聚簇索引非聚簇索引也叫二级索引,他跟聚簇索引的区别是不是主键 并且最后的叶子结点存放的不是最终的数据,而是主键的值,在查询到主键的值后在回到主键索引树里面找到最终的数据,这个过程叫做回表 可以看出会标需要查询两次索引树性能较慢,不过我们也可以通过索引覆盖来避免回表. 索引覆盖 索引覆盖就是我们创建的非聚簇索引包含了我们需要查询的所有字段这时候我们需要的数据在索引树上面就全部都有了,不需要在回表了,那怎么让我们索引包含多个字段呢?这又引入了另一个中非聚簇索引 联合索引 联合索引 联合索引是将表里面多个字段合在一起作为一个索引树,其实这是创建了三个索引,但是再使用的时候会遵循最左原则,这里的最左原则我们稍后会详细介绍,先看下图了解,通过下图我们可以发现联合索引树上面的顺序是根据最左边的索引来决定的,而后面的索引会根据前面的索引作为第一排序,然后在对第二、第三…进行排序 可以理解成ascll码值的排序比如下图所展示的 (1,1 1,2 2,1 2,4 3,1) 创建一张表包含的字段和设置索引 第一段sql通过包含最左边的字段进行查询其匹配规则是先找到索引树上面最左边的字段name进行查询,在通过第二个age进行查询在通过orde进行查询可以看到每一个查询的类型都是const,这里编写sql的时候可以不用关注先后顺序,mysql会自动优化顺序在进行查询 这句sql没有包含最左边的字段name最终查询的类型是index也就是便利了整课索引树 如果联合索引是由字段A,B,C组成那么在查询的时候如果是通过where A= ? and C = ?这样的方式就没办法两个索引都使用到,因为联合索引排序是从左到右字段顺序排列,就下下面的例子,name = ‘555’ and orde = 6 通过使用索引的长度可以看出来只是使用了name字段 索引与排序 filesort: 这个排序准确来说有三种排序方式 单路排序:查询条件使用了索引但是排序没使用索引(联合索引排除,下面细说)mysql会将查询出来的数据放入到sort buffer进行排序然后返回双路排序:还是单路排序的情况但是这时候查询出来的字段特别多sort buffer内存不够了,这时候mysql会将主键id(可以定位到整条数据的字段值)和排序的字段值放入到sort buffer里面进行排序然后拿出来再回一次表将数据返回文件排: 这种情况就是查询出来的数据过大双路排序晒出来的字段也超过了sort buffer里面的内存这时候mysql会将所有的数据拆分成多份,每一份单独排序生成一个临时小文件,之后小文件在跟小文件之间排序一次类推生成一个数据总和返回效率极低 我们创建一个 id 主键索引 age,sex 联合索引的一张测试表 mysql默认排序貌似是有自己的算法来决定的,这里的sql可以看出来他是通过age的索引进行顺序排列,并不一定默认是主键,通过explain来看根据索引排序的话无论是正序还是倒叙都不会触发filesort联合索引排除 select * from t_test; 这里详细说一下联合索引,我们都知道最左原则这里通过最左原则的age先定位到部分数据也就是age=1的数据后面排序通过联合索引里面的sex进行倒叙或者顺序都不会触发filesort EXPLAIN select * from t_test where age = 1 order by sex desc; EXPLAIN select * from t_test where age = 1 order by sex; 如果最左原则查到的是一个范围而不是相同数据的值那么可以看出来无论联合索引里面的另一个字段是顺序还是倒叙都会触发filesort这个我们通过上面的联合索引存储方式很容易理解,因为联合索引默认会对数据进行排序存储,(1,1) (1,2) (2,1) (2,2)这里where使用到了索引age但是因为是联合索引所以没有办法对age进行单独排序在对sex记性排序的时候就没办法通过索引了 EXPLAIN select * from t_test where age in (1,2) order by sex asc; EXPLAIN select * from t_test where age in (1,2) order by sex desc; 还是上面的情况,联合索引最左原则筛选出范围数据,因为联合索引的排序是多字段的所以排序的时候需要加上最左边的即可不不触发filesort,但是还有触发的情况继续往下看 EXPLAIN select * from t_test where age in (1,2) order by age asc,sex asc; EXPLAIN select * from t_test where age in (1,2) order by age desc,sex desc; 如果联合索引里面的排序加上了最左边的,但是两个字段一个是正序一个是降序也会触发filesort这个原因结合联合索引的存储方式就很容易理解上面也有解释 EXPLAIN select * from t_test where age in (1,2) order by age asc,sex desc; EXPLAIN select * from t_test where age in (1,2) order by age desc,sex asc; 需要注意的点:如果我查询的语句没有使用到索引 那么order by 即使使用了索引也会二次排序 举个例子 一张表 id:主键索引 age:普通索引 sex和subject:联合索引sex在左边 name:没有索引 示例一: 会进入sort file,查询条件没有走索引 所以这里order by只能二次排序

24款热门数据可视化工具 你用过哪些?

数据可视化是数据科学过程的步骤之一,它指出在收集、处理和建模数据后,必须对其进行可视化才能得出结论。 数据可视化几乎对每个职业都很重要。教师可以使用它来显示学生的测试结果,计算机科学家可以探索人工智能(AI)的进步,或者希望与利益相关者共享信息的高管可以使用它。它在大数据项目中也发挥着重要作用。随着企业在大数据趋势的早期积累了大量数据,他们需要一种方法来快速轻松地了解他们的数据。可视化工具是天作之合。 什么是数据可视化工具? 数据可视化工具是指旨在可视化数据的所有形式的软件。 不同的工具可以包含不同的功能,但最基本的数据可视化工具将为您提供输入数据集和直观操作它们的功能。 数据可视化工具可帮助您以可直观易懂的图形格式展示原始数据,可以确保您生成可自定义的条形图、饼图、甘特图、柱形图、面积图、圆环图等。 数据可视化工具推荐 Tableau 用于创建地图和面向公众的最佳数据可视化软件。 Tableau 是一种商业智能数据可视化工具,允许用户通过交互式仪表板、地图、图表等其他演示格式与数据进行交互。 Tableau 是商业智能行业中使用的功能强大且增长最快的数据可视化工具。它有助于以非常易于理解的格式简化原始数据。 Infogram 面向非设计师和设计师的全功能数据可视化工具。 Infogram 由 550 多张地图、35 张图表和 20 个预先设计的模板组成,使其能够在任何设备上设计完全响应迅速的专业演示文稿。 可以从在线或PC源导入数据,并且可以下载高清质量的信息图表,支持多种文件类型(PNG,JPG,PDF,GIF,HTML)。 拖放式编辑器简化了为营销报告、信息图表、社交媒体帖子和地图创建有效可视化的过程,允许非设计师或小白能轻松生成外观精美的报告、单页纸、图表。 SovitChart 优秀的数据可视化应用在线搭建工具。 SovitChart一款很不错的数据可视化应用在线搭建工具,基于Echarts研发,提供了丰富的模板与图形,支持多数据源,拖拉式布局,支持云端和本地部署。通过丰富的组件库和模板库,以及智能化的辅助手段,极大的降低非专业开发人员的搭建门槛。整体来说是一款很好的可视化大屏设计产品,而且个人版本还是免费的,还有2D组态可视化平台——Sovit2D和3D物联网可视化平台——Sovit3D。 Chartsblocks 在任何网站上嵌入图表的最佳数据可视化工具。 基于云的图表构建工具,允许自定义任何图表并将其与任何数据源同步,可以分享到热门的媒体网站上。 可以使用其 API 从任何来源导入数据,包括实时源,图表构建向导可帮助在导入任何屏幕尺寸的任何设备上之前为图表选择最佳数据。 使用数百个自定义选项控制图表的各个方面,允许您配置从颜色、字体和大小到轴上的网格和数字刻度的所有内容。 Datawrapper 用于将图表和地图添加到新闻报道的最佳数据可视化软件。 Datawrapper专为向新闻报道添加图表和地图而创建,是一个开源工具,支持Windows,Mac和Linux,使您能够将可视化连接到Google表格。 从 19 种交互式响应式图表类型中选择一种,范围从简单的条形和线条到箭头、范围和散点图,这三种地图类型可用于创建定位器地图、专题合唱团、符号地图等。 表格功能为您提供了一系列样式选项,用于响应式条形图,柱形图和折线图,热图,图像,搜索栏和分页。 D3.js JavaScript 库,用于使用可重用图表通过数据操作文档。 D3.js 是一个 JavaScript 库,用于基于数据操作文档,帮助您通过 HTML、SVG 和 CSS 激活数据。 该工具速度极快,支持大型数据集以及交互和动画的动态行为,使您能够从数字数组生成 HTML 表或使用相同的数据创建具有平滑过渡和交互的交互式 SVG 条形图。 虽然该平台需要一些JavaScript知识,但像NVD3这样的应用程序允许非程序员使用该库,提供可重用的图表和图表组件,而不会带走D3.js的强大功能。 Domo 具有BI经验的公司的最佳数据可视化软件。 Domo 是一个云平台,具有强大的 BI 工具,具有大量数据连接器和强大的数据可视化功能,可帮助您进行分析并生成交互式可视化。 该应用程序可帮助您简化管理数据并使用图形和饼图检查重要数据,并且该引擎允许您在加载后操作 ETL 操作并在引擎中进行数据清理,而对可以存储的数据量没有限制。 Domo 拥有 450 多个可用的连接器,其中一些默认情况下可以访问,而另一些则在向支持团队请求 URL 后访问,Domo 非常灵活,它们允许您轻松加载本地存储的 CSV 文件。

谈谈基于Github的OAuth2第三方登录实现

上篇文章介绍了OAuth2.0的基本知识,这篇文章将介绍怎么通过github来实现OAuth2.0第三方登录 注册OAuthApp https://github.com/settings/developers 1.新建OAuth App 2.填写应用信息 homepageURL为主页地址,Authorization Callback URL为回调地址,当用户同意授权后,会回调该地址,并将ActionCode拼接到地址后面。 3.注册完毕获取clientId与client Secret 代码实现 github对外接口 上一篇文章说过,OAuth2.0的授权码模式要调用两次认证服务器来获取accessToken。github对于OAuth2.0的授权码登录提供了以下接口: 接口URL接口类型接口作用https://github.com/login/oauth/authorizeGET获取授权码codehttps://github.com/login/oauth/access_tokenPOST通过授权码获取accessTokenhttps://api.github.com/userGET通过accessToken获取用户信息 这些接口的传参可以参照官方文档:授权 OAuth 应用 - GitHub 文档,我们可以用这些接口来实现OAuth2.0的登录。 前端主页面 使用了github提供的获取授权码Code的接口,clientId是上面创建OAuthApp后显示的,redirect_uri代表回调地址。用户进行授权成功后,会跳转到该uri地址,并且在地址后面拼接授权码code。 <!doctype html> <html lang="en"> <head> <meta charset="utf-8"/> <title>第三方登录</title> <meta name="description" content=""/> </head> <body> <h1>github登录</h1> <!-- 获取授权码接口--> <a href="https://github.com/login/oauth/authorize?client_id=xxx&redirect_uri=http://localhost:8080/callback&state=1&scope=user">点击授权登录</a> </body> </html> 后端回调接口 回调地址拿到授权码code后,通过授权码code来交换得到accessToken,然后再用accessToken获取用户信息 @RequestMapping(value = "/callback") public String callBack(@RequestParam("code")String code) throws Exception{ //获取accessToken String getAccessTokenUrl="https://github.com/login/oauth/access_token"; JSONObject param=new JSONObject(); param.put("client_id","xxx"); //OAuthApp页面对应的clientId param.put("client_secret","xxxx");//OAuthApp页面对应的client_secret param.put("code",code); Map<String, String> headers=new HashMap<>(2); headers.put(HttpUtils.CONTENT_TYPE,"application/json"); headers.

【软考】系统架构设计风格分类的个人理解

个人适当学习了软考系统架构设计师中关于系统架构设计相关的内容,梳理了一下相关信息。 常见架构类型和常见分类 常见的软考中出现的系统架构列举如下: 分层架构管道-过滤器架构客户端-服务器架构模型-视图-控制器架构,即MVC架构事件驱动架构微服务架构黑板架构解释器模式数据仓库风格架构面向服务架构 网上查找到的资料一般把架构分为五类架构风格,分别是数据流风格,调用返回风格,独立构建风格,虚拟机风格和仓库风格。并对上述系统进行了归类,归类到这五种架构风格中。 架构分类之个人理解 以下纯属个人角度的理解,和软考本身的考点和预期可能不相符合,请注意甄别。 针对上述分类个人认为,感觉有在把不同维度或者层次的内容强行放在同一层次来进行比较的嫌疑,个人感觉非常别扭,所以我重新按照个人的理解进行了分类。同时也参考了上述的五类架构风格的分类。 上述分类个人感觉是在把不同层次的系统混为一谈,比如说"分层架构",可以是服务器程序,也可以是客户端程序中的一种实践方式,但是客户端-服务器架构,则是在描述一个典型的网络结构模式,当然这也可以是一种广义上的系统架构,但是因为需要从系统架构的角度去分类,混为一谈就会显得很混乱,所以我觉得最重要的是理清楚系统的层次的概念。 个人按照两层一类来对上述架构风格进行划分。 第一层,整体系统 还是 单体系统 第一层是当前描述的系统是否存在和外界的交互,不存在交互则是一个逻辑自洽的整体系统,而存在交互则认为这个系统是一个和外界存在交互的单体系统。 从这个层面来说,客户端-服务器架构个人认为描述的是一个整体系统,事件驱动架构个人认为也是一个整体系统,这里可能会存在疑问,事件驱动往小了说是一种编程框架,往大了说则决定了系统的运行机制,我理解事件驱动架构的核心是决定了包括客户端和服务器在内的整个系统的信息交互方式,也就是客户端和服务器不直接交互,而是通过这个事件驱动框架进行交互,这就是事件驱动架构。 而上述其他的架构,个人认为都是在描述单体系统。 第二类,请求响应系统 还是 输入输出系统 第二类是对单体和外界交互的方式进行分类。我们这里把单体系统都视作服务端(比如手机APP也可以视作服务端,客户端就是我们用户,或者是其他调用这个app的APP)根据客户端在发起请求后,和服务端的输出产物之间的关系,可以分为请求返回响应系统和输入输出系统。 请求返回响应系统中,客户端需要获取系统返回的结果,个人理解为输出结果和输入来源是同一媒介或者说界面,比如都是通过网络链路接收请求和返还结果,或者手机app界面上触发的修改,最终将修改结果呈现在手机app界面上。个人认为上述的分层架构,MVC架构,微服务架构,黑板架构,数据仓库风格架构,面向服务架构都是属于这一类的。 而输入输出系统中,客户端不需要获取到系统返回的结果,客户端只是输入系统,而输出是在其他界面,或者说是其他介质上。比如管道-过滤器系统的典型应用,编译器,输入为源文件,输出产物为可执行文件。或者闭环控制架构,其输入为设定的温度,和从温度传感器接收到的当前温度,但输出是对制冷的化学过程的执行强度的控制。包括上述虚拟机风格中的解释器模式,个人认为也可以归为此类。输入为代码或者字节码,输出为操作系统的执行目标,也就是一个接近流式的处理流程。 第三层,物理上可拆分单体 还是 物理上不可拆分单体 第三层个人认为是单体系统内部是否可拆分为不同的单体。当然分层架构,内部也可以认为是有很多个不同的模块组成的,但其在物理结构上,本质上还是一个物理上不可拆分的单体,只是在逻辑上是可拆分的。 分层架构,数据仓库风格架构,黑板架构个人认为都是物理上不可拆分的单体架构。而模型-视图-控制的MVC架构,个人认为就是分层架构在WEB应用场景下的一种特例。 面向服务架构个人认为就是一种典型的物理上可拆分的单体架构,即内部可以进一步拆成物理上不同的系统,这里应该是特指物理上可拆分的请求响应系统。而微服务架构可以认为是面向服务架构的一种特例,系统架构设计时以细粒度地解耦地拆分服务为要务的一种设计方式。 个人分类Xmind 具体架构的简要说明 架构的组成成分 每一种架构都有各自不同的组成构件。以下列举下几种常见架构的组成构件。 分层架构(四层为例:展现层,业务层,持久层,数据层) 管道-过滤器架构(过滤器类型:过程起点,数据转换,测试条件,终点) MVC架构(模型,视图,控制器) 黑板架构(黑板,知识源,控制组件) 架构的评估维度 每种架构都可以从 使用场景类型,优点,缺点,实际用途各个维度进行理解和评估。这个待后续补充。 参考文档 https://zhuanlan.zhihu.com/p/603201577 https://zhuanlan.zhihu.com/p/564143827