OpenFeign 调用参数处理(开发重点)

4.1 说在前面 Feign 传参确保消费者和提供者的参数列表一致 包括返回值 方法签名要一致 通过 URL 传参数,GET 请求,参数列表使用@PathVariable(“”) 如果是 GET 请求,每个基本参数必须加@RequestParam(“”) 如果是 POST 请求,而且是对象集合等参数,必须加@Requestbody 或者@RequestParam 4.2 修改 provider-order-service 4.2.1 创建 BaseResult 类 public class BaseResult implements Serializable { private Integer code; private String msg; private Object data; public static BaseResult success(Integer code, String msg, Object data) { BaseResult baseResult = new BaseResult(); baseResult.setCode(code); baseResult.setData(data); baseResult.setMsg(msg); return baseResult; } } 4.2.2 创建 Order 类 public class Order implements Serializable { private String orderSn; private String orderName; private String orderDetail; private Date orderTime; private String userId; } 4.

Jetty、Tomcat、Netty、Undertow

文章目录 一、容器使用二、容器介绍三、总结 一、容器使用 Spring-Boot 内置web容器使用 二、容器介绍 下面是每个 Web 服务器的擅长和适用场景的简要介绍: Undertow: 擅长处理高并发的负载和大量连接。适用于需要高性能和低资源消耗的 Web 应用程序,特别是在高并发环境下。由于其非阻塞的特性,适合于处理大量并发请求的情况,例如实时通信、聊天应用程序或需要快速响应的 API。 Tomcat: 擅长传统的 Java Servlet 和 JSP 应用程序。适用于中小规模的 Web 应用程序,特别是传统的企业级应用程序。Tomcat 是广泛使用的 Servlet 容器,支持标准的 Java Web 技术栈,如 Servlet、JSP 和 JavaBeans。它稳定可靠,并且有大量的文档和社区支持。 Netty: 擅长构建高性能的自定义网络应用程序。适用于需要处理大规模并发连接和高吞吐量的场景。Netty 提供了灵活的网络编程框架,可以方便地实现各种协议,如 HTTP、WebSocket 和 TCP。它适合构建高性能的代理服务器、实时通信服务器或需要自定义网络协议的应用程序。 Jetty: 擅长轻量级的嵌入式应用程序和开发环境。适用于快速启动和低内存消耗的应用程序。Jetty 是一个稳定、可靠且易于使用的 Servlet 容器,具有快速启动和低资源消耗的特点。它适合用于开发和测试环境,以及嵌入式设备或对启动速度和内存占用有限制的场景。 三、总结 如果需要处理高并发负载或具有特定的性能需求,Undertow 和 Netty 可能是更好的选择。如果使用传统的 Java Web 技术栈,Tomcat 提供了广泛的支持。而对于轻量级和嵌入式应用程序,Jetty 可能更适合。

python文件导入导出处理方法整理

1. excel import:xlrd import xlrd, xlrd可以对xls,xlsx文件进行处理 book = xlrd.open_workbook(file_contents=body) # body是文件的二进制流,book是一个对象 table = book.sheets()[0] # book.sheets()获取的是表格的sheet, table.cell_value(i, 0)获取单元格数据 可对数据进行处理 export:xlsxwriter io.BytesIO() :类文件对象 python已经原生为我们准备好了类文件对象(file-like object),这种对象在内存中创建,可以像文件一样被操作。 python3中将StringIO和BytesIO都集成到了io模块中 内存中的对象有一个标志位的概念,往里面写入,标志位后移到下一个空白处。而读数据的时候是从标志位开始读,所以想要读取前面的数据需要手动将标志位进行移动。 (67条消息) python3中StringIO和BytesIO使用方法和使用场景详解_T型人小付的博客-CSDN博客 BytesIO真正实用的地方还是在于存储图片视频等数据,不管是本地生成的还是网络下载的。 因为是Bytes类型的,就可以直接保存到BytesIO中 想要对图片进一步处理这里使用Python3的Pillow库, s = StringIO() s.write('line1\nline2\nline3') print(s.read()) --> '',write后标志位在最后一位,read时候往后读,是空数据 print(s.getvalue()) -->'line1\nline2\nline3' s.seek(0) 指针指向0 print(s.read()) -->'line1\nline2\nline3' s.seek(0) print(s.readline()) -->'line1',按行读取 s.close(),释放内存 from xlsxwriter import Workbook, workbook = Workbook(io.BytesIO())添加sheet,sheet.write(row,col,value),最后workbook.close() 2. tablib库 对数据进行转换,表格数据 def export_excel(): header = [str(i) for i in range(1, 5)] data = ['111', '222', '333', '444'] data_ = [] for i in header: data_.

DragGAN 完全自由 P 图指南

在上篇中,树先生教大家如何正确部署 DragGAN 项目,实现自由拖拽式 P 图。 超炫酷项目来袭!DragGAN 正式开源了! 但可惜只能使用项目预置的一些图片,本篇教大家如何利用该项目自由编辑修改任何图片。 这里主要使用到 PTI 项目,可以将你自定义的图片训练成 StyleGAN 潜空间模型,从而实现任何图片的编辑修改。 环境准备 这里我们还是继续选择 AutoDL 云平台,使用 Python 3.8,CUDA 11.8 的镜像,这个镜像的环境满足项目要求。 下载源码 git clone https://github.com/danielroich/PTI.git # 安装依赖 cd PTI && pip install -r requirements.txt 你肯定好奇,项目里没有 requirements.txt 文件呀?放心,我给你准备好了~ torch>=2.0.0 scipy Ninja==1.10.2 gradio>=3.35.2 imageio-ffmpeg>=0.4.3 huggingface_hub hf_transfer pyopengl imgui glfw==2.6.1 pillow>=9.4.0 torchvision>=0.15.2 imageio>=2.9.0 dlib wandb lpips 下载预训练模型 这里我们只要下载前 2 个即可,分别是 StyleGAN 的生成器文件 ffhq.pkl 和图片的预处理器文件 align.dat,下载完成后放到项目的 pretrained_models 目录下。 图片预处理 主要是完成原始图片人脸关键点检测工作,将你想要编辑的图片上传到项目的 image_original 目录下,然后将该目录的绝对路径写入 utils/align_data.py 文件中。

MATLAB 之 MAT 文件

这里写目录标题 一、MAT 文件1. MAT 文件2. C 语言 MAT 函数3. MAT 文件的基本操作3.1 打开 MAT 文件3.2 读写 MAT 文件3.3 关闭 MAT 文件3.4 mx 函数 一、MAT 文件 MAT 文件是 MATLAB 数据存储的默认文件格式,以双精度二进制格式保存数据。MAT 文件为其他程序设计语言(如 C、C++、FORTRAN 等)使用 MATLAB 数据提供了一种共享机制。 1. MAT 文件 MAT 文件由 128 字节的 MAT 文件头和尾随其后的数据单元组成。文件头包括 MATLAB 版本、文件被创建的时间等信息。数据单元分为标志和数据两个部分,标志占 8 字节,包含数据类型、数据大小等信息。如果标志中的数据字节数小于 4,那么,MATLAB 使用压缩格式存储单元中的数据。MATLAB 的 save 命令可以将 MATLAB 系统内部数据保存为 MAT 文件,而 load 命令可以将磁盘上的 MAT 文件中的数据读入到 MATLAB 系统中。此外,为了有效地管理 MAT 文件,以及在 MATLAB 外部读取和创建 MAT 文件,MATLAB 提供了一一个子程序库,用户可以在 C、C++、FORTRAN 程序中直接调用这些子程序来创建和读取 MAT 文件。MATLAB 提供的用于操作 MAT 文件的 API 函数封装于两个标准库文件中:libmat.

纯粹数学作业——Chapter 0

1、列举一个真命题、一个假命题、一个不知道真假的命题、一个不是命题的陈述。 真命题:太阳是发光发热的。 同位角相等,两直线平行。 假命题:三角形的三个内角和不是180° 不知真假的命题:树叶是黄色的。 不是命题的陈述:可爱的斑马。 2、写出21127的2进制,3进制,8进制,16进制以及36进制的表达形式。 21127 = (101 0010 1000 0111)2 = (1001222111)3 = (51207)8 = (5287)16 = (GAV)36 3、证明:1可以除任何整数,任何数可以除0。 (注意,除 和 除以 ,是两个概念) 4、证明: 令a,b,d ∈ Z,假设,d除a, 商为u, d 除b,商为v。u,v为整数。 试证明,d可以除 au+bv。 5、证明: 如果一个整数a, 被b除,余数是r。那么,试证明,如果a 除以(-b),那么余数也为r 6、求408735787基于17进制的展开,以及1442151747基于36进制的展开 (上面两题没有检查!!万一被检查错了,就太丢人了。万一做错了,麻烦给我留言。) 7、将减法和除法运算解释为数轴的几何变换。 加法例子: 乘法例子: 减法例子: 除法例子: 8、证明:令r是一个有理数,a是一个无理数。 证明1:ra是有可能是有理数。 证明2:ra有可能是无理数。 证明1:首先,基于这样一个事实:√ 2是一个无理数。(当然也可以取π) 令r = 0; a= √ 2 ra = 0,是一个有理数(得证)。 证明2:令r = 1; a= √ 2 ra = √ 2 (是一个无理数,得证)

stm32笔记(串口重写printf不能发送数据)

在Keil写stm32的时候用串口重写printf发送不了数据 需要勾选 Use MicroLIB 在Keil中勾选 "Use MicroLIB" 选项会启用MicroLIB库,它是Keil提供的一种优化的C标准库替代方案。勾选此选项可以在编译过程中使用MicroLIB库的函数和优化特性。 使用MicroLIB库相比于使用默认的C标准库(如GNU C库或ARM C库)有一些优势和特点: 1. 节省代码空间:MicroLIB库采用了一些优化技术,可以减小编译生成的可执行文件的代码尺寸。这对于资源受限的嵌入式系统来说是非常有益的。 2. 快速启动:MicroLIB库的启动时间比较短,可以加快系统的启动速度。 3. 适用于嵌入式系统:MicroLIB库专门为嵌入式系统设计,提供了一些针对嵌入式系统的特性和优化,如支持裁剪、对齐和紧凑的数据结构等。 请注意,勾选 "Use MicroLIB" 选项后,编译器将使用MicroLIB库的函数和优化特性,因此你需要确保你的代码与MicroLIB库兼容,并且没有依赖于其他特定的C标准库函数或特性。如果你的代码中使用了不兼容的函数或特性,可能会导致编译错误或运行时错误。 另外,MicroLIB库并非适用于所有情况,具体是否使用MicroLIB库需要根据你的项目需求和性能要求来决定。在一些特定的情况下,使用默认的C标准库可能更为合适。

redis与mysql的数据一致性

解决redis与mysql的数据一致性 为什么会出现数据不一致性? 首先要明白只要我们使用了Redis缓存,就必然存在缓存和DB数据一致性的问题!就是我们修改了数据,没能即使同步到缓存中去!而我们业务读到缓存中不是最新的数据,这可能会导致严重的错误!如将商品库存缓存在Redis,若库存数量不对,则下单时就可能出错,这是难以接受的。 那么什么是数据一致性? 缓存中有数据且缓存数据值与DB相同缓存无数据DB是最新最新值 不符合我们这两种的情况,都是属于数据不一致了! 好处就是减少数据库的IO操作;提升数据的IO性能!如图去数据的缓存架构图: 解决方法 1.先更新数据再更新缓存 这里会有一个问题:如果更新缓存失败,就会导致会数据和redis中数据不一致。 2.先删除缓存再更新数据库 这里也有一个问题:在理想情况下应用下次访问redis的时候,发现redis里面的数据是空的,就从数据库中加载保存到redis里面,那么数据看起来就是一致的!但是在极端的情况下,由于删除redis和更新数据库,这两个操作不是原子的,所以在这个过程有其他的线程来访问的,还是会存在数据不一致的问题! 所以在极端的情况下,仍然保证redis与mysql的数据一致性,可以采用最终的一次性方案: 基于RocketMQ的可高性消息通信来实现最终一次性 * 通过Canal组件监控MySQL中Binlog日志实现一致性,把更新的数据同步到Redis里面去 这两个方法都是最终一致性来实现的!如果我们的业务场景不能接受数据短期不一致性的哇!那么我们可以通过读写锁的方法来保证强一致性!在数据更新的时候其他任何请求都无法访问缓存中的数据,直到数据更新完毕,从而保证数据的强一致性!但是这种方式,由于增加锁的操作,所以在性能上会有一定的影响 如图是读写锁实现一致性图:

简述javaScript中数组操作

在JavaScript中,有很多数组操作可以帮助您对数组进行各种操作和变换。以下是一些常见的数组操作: 访问数组元素: 您可以使用索引访问数组中的特定元素,索引从0开始。 const arr = [1, 2, 3]; console.log(arr[0]); // 输出: 1 添加元素: 您可以使用push()方法向数组末尾添加一个新元素。 const arr = [1, 2, 3]; arr.push(4); console.log(arr); // 输出: [1, 2, 3, 4] 删除元素: 您可以使用pop()方法删除并返回数组的最后一个元素,或使用splice()方法删除指定索引处的元素。 const arr = [1, 2, 3, 4]; arr.pop(); console.log(arr); // 输出: [1, 2, 3] arr.splice(1, 1); console.log(arr); // 输出: [1, 3] 数组迭代: 您可以使用forEach()方法迭代数组中的每个元素,并对其执行指定的操作。 const arr = [1, 2, 3]; arr.forEach(element => { console.log(element); // 依次输出: 1, 2, 3 }); 数组映射:

Java 的 8 种异步实现方式,让性能飞起来

异步执行对于开发者来说并不陌生,在实际的开发过程中,很多场景多会使用到异步,相比同步执行,异步可以大大缩短请求链路耗时时间,比如:发送短信、邮件、异步更新等,这些都是典型的可以通过异步实现的场景。 异步的八种实现方式 线程Thread Future 异步框架CompletableFuture Spring注解@Async Spring ApplicationEvent事件 消息队列 第三方异步框架,比如Hutool的ThreadUtil Guava异步 什么是异步? 首先我们先看一个常见的用户下单的场景: 在同步操作中,我们执行到 发送短信 的时候,我们必须等待这个方法彻底执行完才能执行 赠送积分 这个操作,如果 赠送积分 这个动作执行时间较长,发送短信需要等待,这就是典型的同步场景。 我们创建了一个高质量的技术交流群,与优秀的人在一起,自己也会优秀起来,赶紧点击加群,享受一起成长的快乐。另外,如果你最近想跳槽的话,年前我花了2周时间收集了一波大厂面经,节后准备跳槽的可以点击这里领取! 实际上,发送短信和赠送积分没有任何的依赖关系,通过异步,我们可以实现赠送积分和发送短信这两个操作能够同时进行,比如: 这就是所谓的异步,是不是非常简单,下面就说说异步的几种实现方式吧。 1. 线程异步 public class AsyncThread extends Thread { @Override public void run() { System.out.println("Current thread name:" + Thread.currentThread().getName() + " Send email success!"); } public static void main(String[] args) { AsyncThread asyncThread = new AsyncThread(); asyncThread.run(); } } 当然如果每次都创建一个Thread线程,频繁的创建、销毁,浪费系统资源,我们可以采用线程池: private ExecutorService executorService = Executors.newCachedThreadPool(); public void fun() { executorService.

第五节:springboot整合Mybatis(声明式事务@Transactional)

SpringBoot事务 前言一、准备工作1、mysql新增t_car表2、新增Car类3、新增CarMapper类4、新增CarServicer类5、新增CarServicerImpl类 二、事务测试1、@Transactional-readOnly只读2、@Transactional-rollbackFor需要进行回滚的异常类(正确演示)3、@Transactional-rollbackFor需要进行回滚的异常类(错误演示) 三、事务不生效原因1、方法创建错误2、异常吃掉了3、同一个类中(或不同类中),A方法调B方法A方法调用B方法,A方法没有配事务,B方法配事务。 -> 事务失效A方法调用B方法,A方法配事务,B方法不配事务或者配事务。 -> 事务生效 4、其他1、存储引擎不支持;2、spirng配置没有开启事务;3、类没有被spring管理;4、多线程情况下; 前言 ps:一般会在springBoot的启动类加上@EnableTransactionManagement启动事务,在类上使用@Transactional就可以启动事务了。不过不加@EnableTransactionManagement,springBoot也会自动给你装载了@EnableTransactionManagement,启动事务了。 一、准备工作 1、mysql新增t_car表 /* Navicat MySQL Data Transfer Source Server : 本地数据库3306 Source Server Type : MySQL Source Server Version : 50735 Source Host : localhost:3306 Source Schema : study-demo Target Server Type : MySQL Target Server Version : 50735 File Encoding : 65001 Date: 05/07/2023 10:05:11 */ SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for t_car -- ---------------------------- DROP TABLE IF EXISTS `t_car`; CREATE TABLE `t_car` ( `car_id` int(20) NOT NULL, `car_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `gmt_create` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `gmt_modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', PRIMARY KEY (`car_id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; SET FOREIGN_KEY_CHECKS = 1; 2、新增Car类 package com.

STM32F407 SPI配置和时序图讲解(二)

上节讲了SPI的基本配置,这节主要讲解如何看时序图,SPI数据到底是如何传输的。 SPI初始化后,就可以开始向对象发送数据了,但是要发送数据给W25Q128模块,需要按照它的时序图来发送(个人用的是W25Q128模块) W25Q128模块简介 W25Q128是一款常见的串行闪存存储器模块,属于Winbond Electronics生产的产品系列之一。以下是关于W25Q128模块的一些基本信息: 存储容量:W25Q128模块的存储容量为128Mb(兆比特)或16MB(兆字节)。它可以存储大量的数据,如代码、配置文件、图像、音频等。 SPI接口:W25Q128模块使用SPI(Serial Peripheral Interface)接口进行数据通信。SPI是一种常用的串行通信协议,可以实现高速的数据传输。 供电电压:W25Q128模块通常工作在3.3V的供电电压下,但也支持1.8V的供电电压。在使用时需要根据实际情况选择适当的供电电压。 特性:W25Q128模块具有快速的读写速度和低功耗特性。它支持多种读写模式,包括普通读写、高速读写、扇区擦除、块擦除等。 什么是时序图 时序图(Timing diagram)是一种用于描述系统内部或组件之间时序关系的图形表示方法。它展示了信号、事件或数据在时间轴上的传输和交互情况,帮助我们理解系统各个组件之间的时序行为。 时序图通常由水平的时间轴和垂直的信号线组成。时间轴表示时间的流逝,从左到右逐渐增加。信号线代表电平、状态或数据的变化。通过在时间轴上绘制信号线的高低变化、起始时间和持续时间等信息,时序图能够清晰地展示不同组件之间的交互和同步。 时序图可以用于多种场景,如硬件电路设计、软件系统调试、通信协议分析等。它有助于可视化和验证系统的时序约束、响应时间、并发操作、数据流动和交互行为,帮助开发人员了解系统执行的顺序以及事件之间的依赖关系。 上述只是简单介绍一下这个模块和时序图,下面开始正题! 每一款模块都会给你原理图和数据手册以及时序图 以下是W25Q128获取厂商ID的时序图 这是两段时序图,因为一张图放不下,截取两部分,可以仔细观察一下看不看得懂,下面是拼接解析之后的时序图 第一步:先看是谁的时序图,这是W25Q128的时序图,W25Q128相对于stm32芯片来说是从机,所以最左边四个引脚要搞清楚是什么,再stm32芯片中如何配置 第二步:再看数据如何传输的(高位先出还是地位先出)这对下面编程来说很重要,对于这幅时序图来说是高位先出(MSB)(看图可以找到MSB,左上) 第三步:看第一段,各个引脚的开始状态是什么,高电平还是低电平 第四步:看第二段,片选引脚拉低,开始工作,时钟线开始变化 第五步:看第三段,主机(stm32)开始发送指令(每个指令都不相同),这里可以看到查询厂商ID指令为:0x09(小图也标注了它的二进制),这就是数据的传输过程。 注释:为何看出来是主机发送,因为数据变化的MOSI(主输出从输入)这一根数据线,而MISO这跟数据线没有变化,只是起始电平,目前不管它 第六步:看第四段,主机发送一个24位地址值,每个指令的地址值不一样,具体看时序图 第七步:看第五段,主机随便发送数据(随便发不用管是什么,因为从机不会处理这些数据)发这些数据就是为了保持同步(SPI为高速串行全双工同步通信),我们发送这些数据的同时,从机就会给我们反发(因为现在MISO这跟数据线开始变化了)厂商号和设备号 第八步:看第六段,片选引脚拉高,回到空闲状态,通信结束 现在看懂了,来看看代码如何编写 //SPI发送/接收1字节数据函数(自己对SPI接收和发送库函数做的简单封装) uint8_t Spi_Send_And_Recv_Byte_Data(uint8_t byte) { //判断SR寄存器(状态寄存器)1---->发送缓冲区为空(具体查看寄存器手册) while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE) == RESET); //通过spi发送数据 SPI_I2S_SendData(SPI1,byte); //STM32F4系列 SPI标准发送库函数 //再次判断SR寄存器 while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_RXNE) == RESET); //返回spi接收值 return SPI_I2S_ReceiveData(SPI1); //STM32F4系列 SPI的标准接收库函数 } //读取厂商ID和设备ID void Read_W25Q128_ID(uint8_t *M_ID,uint8_t *D_ID) { //cs引脚拉低开始通信 GPIO_PIN_NSS(0); //自己定义的片选宏(不会宏定义的私发我,我亲自教,我不相信学到SPI还有人不会C语言宏定义) //发送获取ID号指令 Spi_Send_And_Recv_Byte_Data(0x90); //读取设备号ID指令(0x90) //发送24位地址(因为SPI发送函数只能发一个字节,所以分三次发送) //记住这个是高位先出,所以要先发高位,这些细节我在上面时序图解析全部提出来了,注意看! uint32_t Address = 0x000000;//要发送的地址值 Spi_Send_And_Recv_Byte_Data((uint8_t)Address>>16); //发送高八位 Spi_Send_And_Recv_Byte_Data((uint8_t)Address>>8); //发送中间八位 Spi_Send_And_Recv_Byte_Data((uint8_t)Address); //发送低八位 //接收设备号(发一些无用数据是为了保持通信同步) *M_ID = Spi_Send_And_Recv_Byte_Data(0xFF);//这里就是发送一些无用数据,从机给我们反发ID号 *D_ID = Spi_Send_And_Recv_Byte_Data(0xFF);//这里就是发送一些无用数据,从机给我们反发ID号 //cs拉高电平,结束通信 GPIO_PIN_NSS(1); } 上面所有的细节和需要主义的地方我都标注清楚了

Element-UI的使用(入门)

主体界面 1、导航菜单 <div style="display:flex"> <!-- 侧边栏--> <div style="width:200px; min-height: calc(100vh - 62px); overflow: hidden; margin-right:2px; background-color: white"> <el-menu :default-active="$route.path" :default-openeds="['/']" router class="el-menu-demo"> <el-menu-item index="/"> <i class="el-icon-s-home"></i> <span>主页</span> </el-menu-item> <el-submenu index="/"> <template slot="title"> <i class="el-icon-s-tools"></i> <span>我的工作台</span> </template> <el-menu-item index="about">关于详情</el-menu-item> </el-submenu> </el-menu> </div> 2、搜索表单 <!-- 表单--> <div style="margin-bottom: 20px"> <el-input style="width: 260px" placeholder="请输入姓名"></el-input> <el-input style="width: 260px;margin-left: 10px" placeholder="请输入联系方式"></el-input> <el-button style="margin-left:10px" type="primary"><i class="el-icon-search"></i>搜索</el-button> </div> 3、表格 <!-- 表格--> <el-table :data="tableData" stripe> <el-table-column prop="name" label="

STM32F407 SPI配置和时序图讲解(一)

什么是SPI? 串行外设接口,一种高速的、全双工、同步的通信总线 通信的同步:在同一时间周期内,完成一个数据的方式和接收 优点: SPI接口是在CPU和外围低速设备之间进行串行数据传输,在主要期间的位移脉冲下数据按位传输,低位在前,且是全双工通信,数据传输相对I2C总线要快速度达到几Mbps,信号线少,协议简单,相对效率较高 缺点: 没有指定的流控制,没有应答机制来确认对方是否接收到数据 工作模式: SPI有4种工作模式,由CPOL和CPHA来决定 CPOL:时钟极性(高低电平)选择:为0时如果SPI总线空闲,时钟线将为低电平,为1时,如果SPI总线空闲,时钟线将为高电平 CPHA:时钟相位(跳变沿)选择:为0时,将在SCLK的第一个跳变沿时,主机对从机进行采样,为1时,将在SCLK的第二个跳变沿时,主机对从机进行采样 跳变沿:电平发生变化时的边沿 下面重点解读一下为什么会有这么4种工作方式(仔细看图,一定能看懂) 因为一个脉冲有高电平也有低电平,那么也就会有变化时候(跳变),这时候如果不规定那个数据为我们需要读取的数据,就会造成数据读取错乱,这时候就出现了一个SPI中很重要的参数CPHA(时钟相位)用来规定那个跳变沿才是我们读取的正确数据。 因此,根据CPOL和CPHA的不同值可以有不同的搭配(理解上图之后,这个很简单): CPOL=0,CPHA=0 -> 模式0 SPI总线空闲时时钟线为低电平,从第一跳变沿获取数据 CPOL=1,CPHA=0 -> 模式1 SPI总线空闲时时钟线为高电平,从第一跳变沿获取数据 CPOL=0,CPHA=1 -> 模式2 SPI总线空闲时时钟线为低电平,从第二跳变沿获取数据 CPOL=1,CPHA=1 -> 模式3 SPI总线空闲时时钟线为高电平,从第二跳变沿获取数据 常用的模式为模式0和模式3 主机和从机: 了解上面基本知识点之后,就是一些简单配置 SPI初始化流程: 1、时钟使能 2、配置SCLK, MOSI,MISO为复用模式(具体引脚看自己芯片原理图) 3、选择复用对象为SPI 4、配置NSS为输出模式(具体引脚看自己芯片原理图) 5、根据时序图,选择初始电平 6、配置SPI 7、使能SPI 具体配置,添加固件库后有如何配置,这里就不做过多叙述。 下一章才是重难点,时序图讲解!!!!

迅为瑞芯微“国产”开发板RK3588满足扩展需求

产品特点: 四核心架构 GPU 集成 Mali G610 MP4 四核 GPU、支持 OpenGLES 1.1、2.0、3.2OpenCL 2.2 和 Vulkan1.2 带有 MMU 的特殊 2D 硬件引擎将最大限度地提高显示性能,并提供非常平稳的操作。 内置独立 NPU RK3588 集成了瑞芯微第四代具有完全自主知识产权的人工智能运算引擎,在 MAC 运算单元的利用率及带宽的消耗上提升了 30%。 6TOPs 的 NPU 算力,赋能各类 AI 场景。 强大的视频编解码 8K 编码+8K 解码,多路视频源同时解码。支持 8K@60fpsH.265/H.264/P9/AV1 视频解码和 8K@30fps H265/H264 视频编码 核心板 连接器版本核心板支持商业级、工业级、国产化版本,兼容同一底板,核心板引脚 320PIN 全部引出,满足用户扩展需求。 邮票孔版本商业级核心板 242 PIN 引脚。 核心板参数: CPU ROCKCHIPRK3588 八核 A76+A55 主频 八核处理器,A76 四核+A55 四核,主频 2.0GHZ 内存 4GB,硬件兼容 32GB 存储器 32GB EMMC 电源管理芯片 使用 RK806-1,支持动态调频等 工作环境温度 -20~60 度

STM32——STLink的使用

文章目录 STLink的使用一、STLink下载与安装1. STLink的下载2. STLink的安装 二、STLink的配置 STLink的使用 首先第一步,连接线的VCC和GND别接反了 本文粗略下载安装,详细描述配置 一、STLink下载与安装 1. STLink的下载 到官网https://www.st.com/en/development-tools/stsw-link004.html下载对应版本的驱动 (或者一些公众号分享的网盘,实在找不到可以私信我,我给你发,没人回可加QQ2227896924) 2. STLink的安装 安装环境:仅支持windows系统,不支持mac、Linux点击exe安装包一直点下一步就行 二、STLink的配置 打开keil点击魔术棒 点击debug设置如图下并点击Setting 设置完成后,Debug里面会显示型号信息(线连接的情况下) 在Flash Douwnload下 选择烧录后自动运行reset and run 如果有Pack,ENABLE取消 下载程序 下载后会显示下面信息 以上仅作为个人笔记,不做权威使用

centos7 服务开机自启动 - systemctl

在服务器上安装的各种中间件,一般都需要配置成开机自启动。但是有些中间件的安装过程中并没有提供相关配置开机自启动的说明文档。本文总结一下Centos7通过systemctl enble配置服务自启动的方法。 更多方法参考链接:Centos开机自启动配置方式汇总 一、Centos7通过systemctl enble配置服务自启动 在Centos7后,更推荐通过systemctl来控制服务。 Centos 系统服务脚本目录/usr/lib/systemd/ 有系统(system)和用户(user)之分,如需要开机没有登陆情况下就能运行的程序,存在系统服务(system)里,即:/usr/lib/systemd/system/。反之,用户登录后才能运行的程序,存在用户(user)里,服务以.service结尾,即:/usr/lib/systemd/user/ 服务的管理是通过 systemd,而 systemd 的配置文件大部分放置于 /usr/lib/systemd/目录内。但是 Red Hat 官方文件指出(详情请看:https://wizardforcel.gitbooks.io/vbird-linux-basic-4e/content/150.html), 该目录的文件主要是原本软件所提供的设置,建议不要修改!而要修改的位置应该放置于 /etc/systemd/system/目录内。 1.1 对于已安装的服务,直接设置开机自启动 查看服务状态:systemctl status 服务名 #示例 systemctl status taosd systemctl status taosadapter 如下图所示: disabled:说明服务还没有开启开机自启动。enabled:说明服务开启了开机自启动。 服务还没有开启开机自启动的,设置为开启开机自启动状态,执行命令: systemctl enable 服务名 #示例 systemctl enable taosadapter 设置完成后,再查看状态:systemctl status taosadapter 服务状态说明:systemctl status 服务名称 loaded 系统服务已经初始化完成,加载过配置active(running) 正有一个或多个程序正在系统中执行, vsftpd就是这种模式atcive(exited) 僅執行一次就正常結束的服務, 目前並沒有任何程序在系統中執行atcive(waiting) 正在執行當中,不過還再等待其他的事件才能继续处理inactive 服务关闭enbaled 服务开机启动disabled 服务开机不自启static 服务开机启动项不可被管理failed 系统配置错误 1.2 对于未安装的服务,建立脚本设置开机自启动 以建立kibana服务开机自启动为例: 建立kibana服务文件: #进入目录 cd /etc/systemd/system/ # 创建脚本文件 touch kibana.

ES的一些操作记录

Elasticsearch 不登录节点,查看节点的内存信息 GET _cat/nodes?h=name,hm,ramPercent,ram.current,ramMax&v Elasticsearch查看close掉的索引 GET /_cluster/state/blocks?pretty Elasticsearch批量查看索引的创建时间 GET _cat/indices?h=h,s,i,id,p,r,dc,dd,ss,creation.date.string

烧脑的内存序Memory Order

系列服务器开发 文章目录 系列服务器开发前言一、Memory Order是什么?二、使用步骤1.memory_order_relaxed2.memory_order_acquire 和memory_order_release3.memory_order_consume4.memory_order_acq_rel5.memory_order_seq_cst 总结 前言 本文是讲解C++内存序,现代cpu架构如下: 上述提供了一个粗略的现代CPU架构,上述中CPU标注的块,代表着一个Core,此处说明一下。 在上述4core系统中,每两个core构成一个bank,并共享一个cache,且每个core均有一个store buffer。 在多线程编程中经常需要在不同线程之间共享一些变量,然而对于共享变量操作却经常造成一些莫名奇妙的错误,除非老老实实加锁对访问保护,否则经常出现一些(看起来)匪夷所思的情况。 乱序执行技术是处理器为提高运算速度而做出违背代码原有顺序的优化. 内存乱序访问一般分为两种:编译乱序和执行乱序。 指令重排问题 int a = 0; bool flag=false; void thread1() { a = 1; flag=true; } void thread2() { if (flag == true){ assert(a == 1); } } 我们期待的执行顺序, 实际可能产生的内存顺序,这种重排有可能会导致一个线程内相互之间不存在依赖关系的指令交换执行顺序,以获得更高的执行效率。 解决办法: 一个比较稳妥的办法就是对于共享变量的访问进行加锁,加锁可以保证对临界区的互斥访问、如果觉得加锁操作过重太麻烦而不想加锁呢?C++11提供了一些原子变量与原子操作来支持。请学习下面章节。 什么时候用内存屏障 编译器开发者和cpu厂商都遵守着内存乱序的基本原则,简单归纳如下: (1)不能改变单线程程序的执行行为 ,即单线程程序总是满足Program Order(所见即所得)。在此原则指导下,写单线程代码的程序员不需要关心内存乱序的问题。 (2)在多线程编程中,由于使用互斥量,信号量和事件都在设计的时候都阻止了它们调用点中的内存乱序(已经隐式包含各种内存屏障),内存乱序的问题同样不需要考虑了。 (3)只有当使用无锁(lock-free)技术时,即内存在线程间共享而没有任何的互斥量,内存乱序的效果才会显露无疑,这样我们才需要考虑在合适的地方加入合适的memery barrier。或者你希望编写诸如无锁数据结构,那么内存屏障还是很有用的。 CPU内存乱序访问发生的原因 (1)编译优化,指令重排导致乱序 由于编译器在编译代码时不感知多线程并发执行情况。所以,编译器对代码的优化是基于单线程执行情况,优化的结果就是导致多线程执行环境下CPU内存访问乱序问题。 (2)CPU运行,指令执行乱序 多核CPU并发执行,访问乱序。 在单核CPU 上,不考虑编译器优化导致乱序的前提下,多线程执行不存在内存乱序访问的问题。 一、Memory Order是什么? 内存顺序描述了计算机 CPU 获取内存的顺序,内存的排序既可能发生在编译器编译期间,也可能发生在 CPU 指令执行期间。 为了尽可能地提高计算机资源利用率和性能,编译器会对代码进行重新排序, CPU 会对指令进行重新排序、延缓执行、各种缓存等等,以达到更好的执行效果。当然,任何排序都不能违背代码本身所表达的意义,并且在单线程情况下,通常不会有任何问题。当然这些乱序指令都是为了同一个目的,优化执行效率。happens-before:按照程序的代码序执行。

TCP黏包

事情从一个健身教练说起吧。 李东,自称亚健康终结者,尝试使用互联网+的模式拓展自己的业务。在某款新开发的聊天软件琛琛上发布广告。 键盘说来就来。疯狂发送"李东",回车发送!,"亚健康终结者",再回车发送! 还记得四层网络协议长什么样子吗? 四层网络模型每层各司其职,消息在进入每一层时都会多加一个报头,每多一个报头可以理解为数据报多戴一顶帽子。这个报头上面记录着消息从哪来,到哪去,以及消息多长等信息。比如,mac头部记录的是硬件的唯一地址,IP头记录的是从哪来和到哪去,传输层头记录到是到达目的主机后具体去哪个进程。 在从消息发到网络的时候给消息带上报头,消息和纷繁复杂的网络中通过这些信息在路由器间流转,最后到达目的机器上,接受者再通过这些报头,一步一步还原出发送者最原始要发送的消息。 为什么要将数据切片 软件琛琛是属于应用层上的。 而"李东","亚健康终结者"这两条消息在进入传输层时使用的是传输层上的 TCP 协议。消息在进入传输层(TCP)时会被切片为一个个数据包。这个数据包的长度是MSS。 可以把网络比喻为一个水管,是有一定的粗细的,这个粗细由网络接口层(数据链路层)提供给网络层,一般认为是的MTU(1500),直接传入整个消息,会超过水管的最大承受范围,那么,就需要进行切片,成为一个个数据包,这样消息才能正常通过“水管”。 MTU 和 MSS 有什么区别 MTU: Maximum Transmit Unit,最大传输单元。 由网络接口层(数据链路层)提供给网络层最大一次传输数据的大小;一般 MTU=1500 Byte。 假设IP层有 <= 1500 byte 需要发送,只需要一个 IP 包就可以完成发送任务;假设 IP 层有> 1500 byte 数据需要发送,需要分片才能完成发送,分片后的 IP Header ID 相同。MSS:Maximum Segment Size 。 TCP 提交给 IP 层最大分段大小,不包含 TCP Header 和 TCP Option,只包含 TCP Payload ,MSS 是 TCP 用来限制应用层最大的发送字节数。 假设 MTU= 1500 byte,那么 MSS = 1500- 20(IP Header) -20 (TCP Header) = 1460 byte,如果应用层有 2000 byte 发送,那么需要两个切片才可以完成发送,第一个 TCP 切片 = 1460,第二个 TCP 切片 = 540。 什么是粘包 那么当李东在手机上键入"

oracle 行转列(多行转成一行)PIVOT

1.原始数据 select '2023-04-01' 日期, 1 数据 from dual union select '2023-04-02' 日期, 2 数据 from dual union select '2023-04-03' 日期, 3 数据 from dual union select '2023-04-04' 日期, 4 数据 from dual union select '2023-04-05' 日期, 5 数据 from dual 2.代码 select * from ( select '2023-04-01' 日期, 1 数据, 'a' 设备 from dual union select '2023-04-02' 日期, 2 数据, 'a' 设备 from dual union select '2023-04-03' 日期, 3 数据, 'a' 设备 from dual union select '2023-04-04' 日期, 4 数据, 'a' 设备 from dual union select '2023-04-05' 日期, 5 数据, 'a' 设备 from dual union select '2023-04-01' 日期, 11 数据, 'b' 设备 from dual union select '2023-04-02' 日期, 12 数据, 'b' 设备 from dual union select '2023-04-03' 日期, 13 数据, 'b' 设备 from dual union select '2023-04-04' 日期, 14 数据, 'b' 设备 from dual union select '2023-04-05' 日期, 15 数据, 'b' 设备 from dual ) pivot ( max(数据) for 日期 in ( '2023-04-01' AS "

springboot启动的时候报错:Error creating bean with name ‘********‘

今天写了一个自定义sql查询,在Test文件夹测试的时候没有问题,但是但启动项目的时候报错,报错图片如下: 检查了很多地方,发现不是mapperscan,或者是配置档命名空间的问题,而是pom.xml里面的一个低级错误 这段代码在springboot的test文件夹里面编写,因为使用的是idea,当注入dao层“TravelGroupDao”的时候,为了方便我使用idea自动生成pom.xml里的依赖: 重点就在这里,在test中的启动器自动导入之后,依赖的<scope>是test: 我们知道: <scope>元素用于指定依赖项的范围。在<dependency>元素中,<scope>可以有以下几个值: compile:这是默认的范围。当依赖项的<scope>设置为compile时,表示该依赖项在编译、测试和运行时都可用。这意味着它会被包含在项目的编译路径中,并且可以在编译、测试和运行代码时被访问和使用。 provided:当依赖项的<scope>设置为provided时,表示该依赖项在编译和测试时可用,但在项目部署和运行时由目标环境(如应用服务器)提供。这意味着编译和测试代码可以使用该依赖项,但在部署到目标环境时,不需要打包该依赖项,因为目标环境已经提供了它。 runtime:当依赖项的<scope>设置为runtime时,表示该依赖项在运行时可用,即在项目运行时才需要使用。这意味着它不会被包含在项目的编译路径中,只有在运行时才会被加载和使用。 test:当依赖项的<scope>设置为test时,表示该依赖项仅在测试代码中可用,不会被包含在项目的编译路径中,也不会在项目的运行时使用。这通常用于测试框架、工具或其他只在测试过程中需要的库。 所以这就是为什么会出现“Error creating bean”,原因是我使用了test标签,修改成compile之后正常启动,项目运行成功!

SOLIDWORKS二次开发入门(VBA)

1.如何创建VBA程序 作为solidworks二次开发入门的工具,首选VBA,VBA的简单易上手是作为SW二次开发入门的首选,并且sw直接点击录制就可获取绝大多数的API,当我们不知道怎么去找这个API的时候可以先录制,然后再去APIhelp中寻找,大大降低学习难度,下面我们先讲解关于VBA开发SOLIDWORKS的基础语法,让你没有任何功底也可以读懂一个VBA程序。当然了如果既想要看得懂又想要能自己写,学一下VBA的语法还是很有必要的。 进入sw后点击工具,宏就是我们的VBA了,这些按钮的具体功能和使用方法看名字就知道了,一 般都是使用录制功能进行VBA程序的创建,点击录制后去运行SW就会自动生成代码,并且这个程序直接就是一个完整的一个VBA程序(宏程序); 1.1点击录制 1.2点击新建按钮,选择零件模板 1.3点击停止 1.4将文件保存 1.5点击编辑,将刚刚保存的文件打开,就可以看到下面的代码 ' ****************************************************************************** ' C:\Users\AppData\Local\Temp\swx21056\Macro1.swb - macro recorded on 06/10/23 by ' ****************************************************************************** Dim swApp As Object Dim Part As Object Dim boolstatus As Boolean Dim longstatus As Long, longwarnings As Long Sub main() Set swApp = Application.SldWorks Set Part = swApp.NewDocument("C:\Users\Desktop\新建文件夹\零件.prtdot", 0, 0, 0) swApp.ActivateDoc2 "零件1", False, longstatus Set Part = swApp.ActiveDoc Dim myModelView As Object Set myModelView = Part.ActiveView myModelView.

字符串函数【2】(strncpy、strncat、strncmp)

全文目录 引言无限制的字符串函数的局限性 strncpy函数声明函数使用my_strncpy的实现 strncat函数声明函数使用my_strncat的实现 strncmp函数声明函数使用my_strncmp的实现 总结 引言 之前我们已经了解过没有限制的字符串函数,并且提到了这些字符串函数在使用时是有着许多的局限性的。我们先来详细说明一下strcpy、strcmp、strcat这些函数在使用时可能会受到的限制: 无限制的字符串函数的局限性 对于strcmp。如果我们想比较两个字符串中的某一部分内容: char s1[] = "abcdef"; char s2[] = "abfcde"; 我们想要比较s1中的第3到第5这三个元素与s2中的第4到第6这三个元素是否相等。当我们用strcmp函数并传入s1+2与s2+3这两个字符指针时,strcmp只能比较从s1+2指向的元素到’\0’与从s2+3指向的元素到’\0’的这两个子串,即子串"cdef"与子串"cde"。很显然,我们的想法不能被实现。 对于strcpy。同样的,如果我们想将一个字符串中的一部分内容拷贝到另一串的特定位置: char s1[] = "abcdef"; char s2[] = "abfcde"; 我们想要将s2中的子串"abf"拷贝到s1的"cde"的位置上去。但是当我们使用strcpy函数并将s1+2与s2作为参数的时候,strcpy会将从s2指向的字符到’\0’拷贝到s1+2指向的字符及后面的位置,即将"abfcde"拷贝到"cde"上。不但没有实现我们的目的,还造成了数组越界访问。 对于strcat。如果我们想要将一个字符串追加到他本身后面: char s1[] = "abcdef"; 我们想要在s1末尾追加一个s1本身,s1中的元素有’a’、‘b’、‘c’、‘d’、‘e’、‘f’、‘\0’七个。在用strcat追加并将s1与s1作为两个参数时,strcat会首先将’a’拷贝到’\0’的位置。此时结束标志被替换,strcat函数就会一直追加下去。这样程序可能就会挂掉。 所以,有了有限制条件的字符串函数可以解决这些问题: strncpy strncpy用来拷贝指定长度的字符串: 函数声明 我们可以查询到这个函数的声明: strncpy函数被声明在头文件string.h中。 这个函数有三个参数:char*接收拷贝目的地的起始地址;const char*接收源头的起始地址(由于进行字符串拷贝时源头串不会发生变化,所以用const修饰会更安全),这两个参数是与strcpy函数相同的。增加了第三个参数,参数类型是size_t(无符号整型),表示从源头子串的首元素向后拷贝num个元素到目的地子串。 返回值是char*型的,返回拷贝结束的目的地子串的首元素地址。 这个函数在拷贝结束后,在末尾不加’\0’以确保部分拷贝结束后的源头字符串依旧可以访问拷贝部分后面的内容。 需要注意的是,这个函数在处理有重叠内容的情况时(例如将一个字符串的第1到4个元素拷贝到第2到5个元素的位置上)会受到限制,或者出问题。这时候就要使用memmove函数(下一篇文章就介绍,本篇暂不提)。 函数使用 例如: #include<stdio.h> #include<string.h> int main() { char s1[] = "abcdef"; char s2[] = "abfcde"; printf("%s\n", strncpy(s1+2, s2, 4)); return 0; } 以s1串的第三个元素地址、s2的首元素地址以及需要拷贝3个元素作为strncpy的参数。

图书管理系统springboot+vue前后端分离项目——搭建vue项目(超详细,持续更新)

1、创建vue工程(vue文档链接) win+R打开cmd添加下载镜像 npm config set registry https://registry.npm.taobao.org 安装vue npm install -g @vue/cli 创建vue vue create myvue 选择组件(这里笔者选择如下组件) 启动vue项目 cd vue npm run serve 2、使用element-UI(element文档链接) 安装ElementUI npm i element-ui -S 将element-ui导入vue项目 在 main.js 中写入以下内容: import Vue from 'vue'; import ElementUI from 'element-ui'; import 'element-ui/lib/theme-chalk/index.css'; import App from './App.vue'; Vue.use(ElementUI); new Vue({ el: '#app', render: h => h(App) });

Tomcat 启动与乱码

绿色版, 下载好之后的文件夹各个解释为: 直接进入bin下双击 startup.bat 然后浏览器输入localhost8080 如果出现猫,就证明安装成功 控制台乱码问题打开 进入此文件夹下修改 编码为GBK即可 然后重启一下tomcat

HIve中的查询语句

文章目录 Hive中的查询语句1. 基础语法2. 基本查询(Select…From)2.1 数据准备(0)原始数据(1)创建部门表(2)创建员工表(3)导入数据 2.2 全表和特定列查询1)全表查询2)选择特定列查询 2.3 列别名1)为什么要给列起别名?2)如何给列其别名?3)案例实操 2.4 Limit语句2.5 Where语句2.6 关系运算函数2.7 逻辑运算函数1)基本语法(and/or/not)2)案例实操 2.8 聚合函数1)语法2)案例实操 3 分组3.1 Group By语句3.2 Having语句1)having与where不同点2)案例实操 4 Join语句4.1 等值Join4.2 表的别名1)好处2)案例实操 4.3 内连接4.4 左外连接4.5 右外连接4.6 满外连接4.7 多表连接0)数据准备1)创建位置表2)导入数据3)多表连接查询 4.8 笛卡尔集1)笛卡尔集会在下面条件下产生2)案例实操 4.9 联合(union & union all)1)union&union all上下拼接2)案例实操 5 排序5.1 全局排序(Order By)1)使用Order By子句排序2)基础案例实操3)按照别名排序案例实操4)多个列排序案例实操 5.2 每个Reduce内部排序(Sort By)5.3 分区(Distribute By)5.4 分区排序(Cluster By) Hive中的查询语句 1. 基础语法 1)官网地址 https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Select 2)查询语句语法: SELECT [ALL | DISTINCT] select_expr, select_expr, ... FROM table_reference -- 从什么表查 [WHERE where_condition] -- 过滤 [GROUP BY col_list] -- 分组查询 [HAVING col_list] -- 分组后过滤 [ORDER BY col_list] -- 排序 [CLUSTER BY col_list| [DISTRIBUTE BY col_list] [SORT BY col_list]] [LIMIT number] -- 限制输出的行数 2.

通过mars3d1.8+cesium1.6根据坐标获取对应坐标在3dtiles模型上的高度

在前端开发中,使用地图和3D模型的需求越来越常见。然而,对于一些开发者来说,如何在3D模型上获取对应坐标的高度可能是一个挑战。在本文中,我们将介绍如何使用mars3d1.8和cesium1.6这两个强大的前端库来实现这一功能。 mars3d是一个基于Cesium的地图开发引擎,可以帮助您快速构建各种地图应用。而cesium则是一个强大的开源3D地理信息系统(GIS)库,为开发者提供了丰富的功能和工具。要在3D模型上获取坐标的高度,我们需要首先将模型加载到地图中。使用mars3d,您可以轻松加载3D模型,并使用cesium强大的功能进行操作和分析。 首先,我们需要引入mars3d和cesium的库文件。您可以通过以下方式将它们添加到您的项目中: <script src="path/to/mars3d.min.js"></script> <script src="path/to/cesium.min.js"></script> 接下来,我们需要创建一个地图容器,并初始化mars3d地图引擎: <div id="mapContainer"></div> <script> // 初始化mars3d地图引擎 </script> 现在,我们可以加载我们的3D模型并将其添加到地图中: <script> // 创建3D模型图层 // 将3D模型添加到地图 </script> 一旦我们的3D模型加载完成,我们就可以使用cesium的功能来获取对应坐标在模型上的高度了。在cesium中,我们可以使用Scene对象来进行相关操作。 <script> //获取模型或者地形高度 function getHeightByType(cartesians, type) { if (type === 'model') { return new Promise(async resolve => { try { let promise = viewer.scene.clampToHeightMostDetailed(cartesians) promise.then(updatedCartesians => { console.log(updatedCartesians) var cartographic = Cesium.Cartographic.fromCartesian(updatedCartesians[0]); var longitude = Cesium.Math.toDegrees(cartographic.longitude); console.log(longitude) var latitude = Cesium.Math.toDegrees(cartographic.latitude); console.log(latitude) var height = cartographic.height; console.log(height) resolve(height) }) } catch (e) { resolve(false) } }) } else if (type = 'terrain') { // 首先将cartesians转为positions let positions = [] cartesians.

计算机丢失msvcr110.dll是什么意思?那个修复方法更简单

Windows系统的电脑运行一段时间,总是不可避免出现一些系统报错,比如在运行游戏或游戏的时候,报错提示“计算机丢失msvcr110.dll”,“找不到msvcr110.dll”是什么意思呢?我是运行photoshop的时候报错的,场景如下: 计算机丢失msvcr110.dll是什么意思? msvcr110.dll是windows操作系统中的一个动态链接库文件,它包含了许多常用的c运行库函数。计算机丢失msvcr110.dll的原因如下: 应用程序没有正确安装或卸载:当安装或卸载应用程序时,可能会出现错误,导致msvcr110.dll文件丢失或损坏。 病毒感染:计算机受到病毒或恶意软件的感染时,它们可能会删除或损坏系统文件,包括msvcr110.dll文件。 系统错误:有时候,系统错误可能会导致MSVCR110.dll文件丢失或损坏。这可能是由于硬件故障、文件系统损坏或其他问题引起的。 操作系统版本不匹配:某些应用程序需要特定版本的MSVCR110.dll文件,如果操作系统版本不匹配,可能会导致文件丢失或损坏。 运行库版本不匹配:某些应用程序需要特定版本的运行库文件,如果运行库版本不匹配,可能会导致文件丢失或损坏。 其他未知原因:除了上述原因外,还可能存在其他未知的原因导致MSVCR110.dll文件丢失或损坏。 一,下载msvcr110.dll修复文件 1.您可以利用百度等搜索引擎从Internet上或者到微软官网下载一个msvcr110.dll修复文件或 在电脑浏览器顶部输入:dll修复工具.site【按下键盘的Enter回车键打开】点击dll修复工具下载。(亲测可以修复) 2.下载好了以后,一般是压缩文件,需要先把文件解压,然后安装后点击修复【立即修复】,修复的文件都是在系统目录中。如果您的计算机是32位系统,则将文件到C:\Windows\System32,如果是64位系统,则将文件到C:\Windows\SysWOW64。 3.修复完成以后,你可以尝试再次运行软件,看看是否可以正常打开运行。 二,重新安装Visual C++ Redistributable 在微软官方网站上下载并安装适用于您操作系统的最新版本的Visual C++ Redistributable,该软件包含了MSVCR110.dll文件,安装后重启计算机即可。 重新安装Visual C++ Redistributable的详细操作方法如下: 打开控制面板:在Windows系统中,找到控制面板,点击进入。 选择“程序和功能”:在控制面板中,找到“程序和功能”选项,点击进入。 卸载旧版本Visual C++ Redistributable:在已安装的程序列表中,找到旧版本的Visual C++ Redistributable,选择它并点击右键,选择“卸载”。 下载并安装新版本Visual C++ Redistributable:从官方网站上下载适用于您操作系统的最新版本的Visual C++ Redistributable,并运行下载的文件。(注意要选跟电脑相同位数的文件安装)按照提示进行安装,并等待安装完成。 重启计算机:安装完成后,请重启计算机,以确保所有更改生效。 三,更新或重新安装操作系统 如果上述方法无效,您可以尝试更新或重新安装操作系统,这可能会解决一些问题。在安装新版本操作系统时,通常会自动安装所需的运行库文件。 更新或重新安装操作系统的详细方法如下: 准备工作:在开始之前,请确保您已经备份了重要的数据,并准备好重新安装操作系统的介质,例如安装光盘或USB启动盘。 启动安装程序:将介质插入计算机,并在启动时选择从介质启动。如果您的计算机没有自动检测到介质,请在启动时按下相应的键(通常是F12或F2)以进入启动菜单。 选择安装方式:在启动菜单中,选择安装操作系统的方式。如果您要更新现有的操作系统,请选择“升级”,如果您要全新安装操作系统,请选择“安装”。 执行安装:按照安装程序的提示进行操作。这通常包括选择语言、时区、磁盘分区等设置。在安装过程中,您可能需要提供管理员权限或进行一些额外的配置。 完成安装:在安装完成后,按照提示进行设置,例如创建用户、设置密码等。确保您提供了正确的配置,并测试新操作系统是否正常工作。 请注意,在执行操作系统更新或重新安装之前,请确保您已经了解了相关的风险和注意事项,并谨慎操作。如果您不确定如何执行某些步骤,请咨询专业人士的建议。 msvcr110.dll是一个动态链接库文件,它包含了C运行时库(CRT)的某些功能。C运行时库是C++程序在运行时所依赖的一部分代码和数据结构,用于提供内存管理、异常处理、字符串操作等功能。 具体来说,msvcr110.dll主要提供了以下功能: 内存管理:msvcr110.dll提供了用于动态分配和释放内存的函数,例如malloc、free、realloc等。这些函数允许程序在运行时动态地分配和释放内存空间,以满足程序的需要。 异常处理:msvcr110.dll提供了一些函数和机制,用于处理程序在运行时发生的异常。这些函数允许程序在出现异常时进行适当的处理,例如恢复程序状态、记录错误信息等。 字符串操作:msvcr110.dll提供了一些用于操作字符串的函数,例如字符串比较、字符串查找、字符串转换等。这些函数使得程序可以方便地处理字符串,并进行各种操作。 总之,msvcr110.dll是C++程序在运行时所必需的动态链接库文件之一,它提供了许多重要的功能和工具,使得程序可以在运行时正确地执行和处理各种数据和操作。如果系统缺少了该文件,程序将无法正常运行,并出现各种错误和异常。可以通过以上方法进行修复,大家也可以看看哪种更加简单。

C#制作简单的计算器(运算级+括号+超长算式处理)

计算器做其实很简单,这里的核心算法只需要做到以下几步:(界面等请看后面) 1.分割得到的数组(字符串,用Tochararray)再拼接 2.检查(可以自己添加) 3.计算 其中核心的计算方式如下↓↓↓↓↓↓ 举个例子,2*3+45,分割后就是'2','*','3','+','4','5' 然后一个for循环将"+","-","*","/"后面的数字(从上一个符号开始)一起拼接起来,最后得到的是2,*,3,+,45. 在检查一下有没有*/,并返回true和false(有,无) 这里结果肯定是true 在进入计算阶段,因为是true,所以遍历到第一个,直到第一个乘号或除号处,把列表的前一个位和后一个位相乘(如果是除法就相除),得到了6,将开始的那个数(2)变成6,再减去列表后面两个值,得到列表为6+45,最后进行加减法(如果是false,上面的乘除法就不用计算了),众所周知,一般来说一个算式它第二个总是“+”,“-”,“×”,“÷”,所以在加减计算中只要将下标为0和下标为2的数按照下标为1的符号计算即可,这里就6(下标为0),+(下标为1),45(下表为2),因为下标1的是+,所以6+45=51,得到的最后的结果就是51 如果说有括号的话,从括号(“(”)处+1的位置添加到一个新列表然后到“)”将里面的项添加到新列表里面就OK了,然后调用一下上面的算法,算出括号里的值,接着把值添加进去同时把列表后面的项删掉,重复此操作直到没有括号,最终再调用一下计算模块即可。 废话不多说直接上代码 public static double main(string get) { List<string> li = new List<string>(); List<int> wh = new List<int>(); bool hav; double final; li = Sp(get); wh = backet(li); hav = have(li); if (wh.Count > 1) { final = ba(wh, li, hav); } else { final = calulater(li, hav); } return final; } public static List<string> Sp(string input) { char[] spilt = input.

rpc调用无法获取异常信息解决

原本http请求的写法如下: private static Executor httpExecutor; static { // 设置重试策略,自定义,不忽略任何异常(即:任何异常都会重试),参考:DefaultHttpRequestRetryHandler HttpRequestRetryHandler retryHandler = (IOException exception, int executionCount, HttpContext context) -> executionCount <= 2; HttpClient httpClient = HttpClientBuilder.create().setMaxConnTotal(2000).setMaxConnPerRoute(500).setRetryHandler(retryHandler).build(); httpExecutor = Executor.newInstance(httpClient); } /** * aisd相关专用,超时时间200s * @param body * @param headers * @param uri * @return */ public static String postRequestForAISD(String body, Map<String, String> headers, String uri) { log.info("POST {} {}, Headers: {}", uri, body, mapToKeyValue(headers)); long beginTime = System.currentTimeMillis(); try { Request httpRequest = Request.

Nginx 常用命令

nginx 启动服务 nginx -s reopen 重启Nginx nginx -s reload 重新加载Nginx配置文件,然后以优雅的方式重启Nginx nginx -s stop 强制停止Nginx服务 nginx -s quit 优雅地停止Nginx服务(即处理完所有请求后再停止服务) nginx -t 检测配置文件是否有语法错误,然后退出 nginx -?,-h 打开帮助信息 nginx -v 显示版本信息并退出 nginx -V 显示版本和配置选项信息,然后退出 nginx -t 检测配置文件是否有语法错误,然后退出 nginx -T 检测配置文件是否有语法错误,转储并退出 nginx -q 在检测配置文件期间屏蔽非错误信息 nginx -p prefix 设置前缀路径(默认是:/usr/share/nginx/) nginx -c filename 设置配置文件(默认是:/etc/nginx/nginx.conf) nginx -g directives 设置配置文件外的全局指令 killall nginx 杀死所有nginx进程 ps -ef | grep nginx | grep -v grep | awk '{print $2}' | xargs kill -9 杀掉nginx进程

xml(标签,解析,约束)

学习xml网址:www.w3school.com.cn 1.xml概述 XML 指可扩展标记语言(EXtensible Markup Language)XML 是一种很像HTML的标记语言XML 的设计宗旨是传输数据,而不是显示数据,也可以储存数据。XML 标签没有被预定义。您需要自行定义标签。XML 被设计为具有自我描述性。XML 是 W3C 的推荐标准XML作为软件的配置文件 Xml用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。Xml是标准通用标记语言(SGML)的子集,非常适合Web传输。XML提供统一的方法来描述和交换独立于应用程序或供应商的结构化数据。 2.xml标签规则 3.xml语法规则 在xml中,一些字符拥有特殊的意义。如果把字符“<”放在xml元素中,会发生错误,这是因为解析器会把它当作新元素的开始,这样会产生xml错误 或 注释:<!-- 注释的内容 --> XML注释,以<!--开头,以-->结尾 注释不能嵌套 idea 上的快捷键是CTRL + / 4.解析xml 解析器:就是根据不同的解析方式提供具体实现,有的解析器过去繁琐,为了方便开发人人员,会有提供易于操作的解析开发包Dom4j:比较简单的解析开发包(日常开发包中用的次数最多的) DOM解析原理以及结构模型 解析原理:XML DOM 将整个XML文档加载到内存,生成一个DOM树,并且获得一个Document对象通过Document对象就可以对DOM进行操作 Document对象(绿):整个xml文档 Element对象(蓝):所有标签 Attribute对象(红):所有属性 Text对象(紫):所有文本内容 出第一个后三个有一个共同的父类为Node对象 Dom4j的基本使用 1.导包 2.把jar导入到模块项目中,比那个添加classpath路径依赖 3.创建解析器对象 4.使用解析器读取xml文档,生成Document对象 5.根据根元素获取下面的子元素/属性... 练习: xml文件 <?xml version="1.0" encoding="UTF-8" ?> <!--注释内容--> <!--本xml文件用来描述多个学生信息--> <students> <!--第一个学生信息--> <student id="1"> <name>张三</name> <age>23</age> </student> <student id="2"> <!--第二个学生信息--> <name>李四</name> <age>24</age> </student> </students> 学生类: public class Student { private String id; private String name; private int age; public Student() { } public Student(String id, String name, int age) { this.

Java实现文件压缩和解压

要压缩和解压,可以使用Java中的压缩库,如java.util.zip或org.apache.commons.compress ZipOutputStream(压缩流)此类为以 ZIP 文件格式写入文件实现输出流过滤器。 ZipInputStream(解压流)此类为读取 ZIP 文件格式的文件实现输入流过滤器。 话不多说代码如下: package file; import java.io.*; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import java.util.zip.ZipOutputStream; public class FileCompressor { public static void main(String[] args) { File[] files = {new File("F:\\a\\66\\测试哈哈哈111.docx")}; String zipFilePath = "compressed.zip"; try { compressFiles(files, zipFilePath); System.out.println("Files compressed successfully."); } catch (IOException e) { e.printStackTrace(); } // String zipFilePath = "F:/批量下载测试_系统管理员_202307040952.zip"; // String destDir = "F:/a"; // // try { // extractFiles(zipFilePath, destDir); // System.

【云上服务器降低成本】

MD@[云上服务器降低成本] 云上服务器降低成本 说明: 本文以华为云为例,主要讲解云上服务降低费用的使用技巧 1.ECS服务器降本 参考文档:华为云官网文档_迁移准备 1.1 ECS临时使用需求 1.项目初始阶段,需要进行大量试错运行,可以“按需”购买ECS,然后不用时关机。关机后vCPU不收费, 只有云硬盘收费 2.项目运维阶段,可能需要重复创建ECS,建议关机后制作私有镜像(仅收取OBS存储费),以便重复创建相同服务器。 1.2 服务器集群降本 1.购买CCE基础版, 是纳管master节点的, 不需要再管理master 2.网络降本 1.EIP,按需.按流量购买EIP, 绑定到ECS上, 只收取流量费用, 不收其他费 2.NAT, 单向网络需求, 仅允许局域网访问公网, 不允许公网访问当前局域网。 3.存储降本 推荐使用对象存储, 对象存储会比云硬盘便宜的多

uni-app如何生成海报图片

项目场景: 在uni-app中,通过点击邀请分享海报的方式,可以展示不同的海报,并通过扫描海报上的二维码来实现用户之间的关系绑定,从而实现分销功能;每次生成的海报样式都可能不同,可以根据后台配置的宽度、高度、X坐标和Y坐标的不同,需要灵活调整每个海报中展示二维码的位置。 问题描述 uni-app中如何使用API生成海报。生成的图片无法正确展示,本地可以看到,真机上看不到。动态改变二维码的位置和大小,位置有所偏差。怎么给头像设置成圆形。 原因分析: 当在uni-app中生成海报时,如果使用网络图片,需要使用uni.getImageInfo函数将其转换为本地临时路径。如果后台返回的太阳码是以base64形式的数据,可能会在真机上无法展示,所以需将其转换为本地路径。在canvas中设置的值都是以像素(px)为单位,如果根据750设计图给太阳码设置数值时,需要进行转换,以适应不同屏幕的像素密度。 解决方案: 通过点击“邀请好友返现赚不停”,生成海报,有两种方案去实现以上效果: 通过uni-app提供的API,可以实现纯前端的canvas渲染海报,这种方法加载速度快且不需要占用后端资源,但无法通过长按识别二维码和转发海报,只能保存到手机相册再转发给朋友。通过后端来渲染海报,虽然会占用后端资源,但它的优势在于后端直接生成图片。只需在image标签上添加show-menu-by-longpress属性,就可以实现长按识别二维码和直接转发海报给朋友的功能。 本文主要介绍了通过纯前端的canvas生成海报的方式: 1、逻辑梳理: 在展示海报的过程中,首先我们需要使用uView框架提供的popup组件,不过这些细节在这里并不重要,因为下面的JavaScript代码是通用的,只是样式上可能会有些不同,但是你是uni-app的项目,主要步骤如下: 首先,我们需要在canvas中展示一张海报图片。然后,根据登录信息获取当前用户的头像和名字。通过接口获取太阳码的数据地址。将获取到的头像、名字和太阳码赋值到对应的位置。 <view class="share-btn"> <button @click="handleShareClick">邀请好友返现赚不停</button> </view> <u-popup @close="closePoster" :show="isPosterShow" mode="center" bgColor="transparent" :safeAreaInsetBottom="false" round="20" :customStyle="{ margin: '0 auto', position: 'relative' }"> <canvas v-if="isPosterShow" :disable-scroll="true" canvas-id="mycanvas" style="width: 604rpx;height:1080rpx;"></canvas> <view v-if="isPosterShow" class="poster-btn"><button @click="savaImgLocalClick">保存图片到本地</button></view> <!-- 这是一个关闭的图标 --> <!-- <view v-if="isPosterShow" class="poster-close" @click="closePoster"> <image :src="imgs.pclose"></image> </view> --> </u-popup> 2、海报的渲染 import { ref } from "vue" import { onLoad } from "@dcloudio/uni-app" let isPosterShow = ref<boolean>(false) pixelRatio.

ESP32开发:1、环境搭建(基于vscode+ESP-IDF)

1、ESP-IDF ESP-IDF提供操作ESP32芯片的API函数,供用户编写的用户程序调用。当用户程序编写好后,ESP-IDF需要借助一系列编译工具才能将用户程序+API函数编译成能运行在ESP32上的二进制文件。 如上图所示这个1个G左右大的压缩包就是ESP-IDF。如果电脑上已经存在了这个文件,就可以不用下载直接用。 一般vscode的ESP-IDF插件中常出现的IDF_PATH就是指这个路径: 2、工具链 ESP-IDF依赖一系列的工具链,如下图: 这些工具中我们熟悉的有python、git、cmake、ninja等,因此也需要安装这些插件。这些插件都是命令行类的,大小比较小(总共600M)。 这些工具要能够让ESP-IDF找到,一般可以通过添加环境变量的方式。 需要把上图中的文件夹都添加进环境变量中。这样有些麻烦,并且有时候还会和其他软件用的这个工具在版本上冲突。因此,Vscode的ESP-IDF扩展是通过一个设置来指明所用工具的地址的,如下图: 在红色圈4中圈出的就是各种工具所在的路径。如果电脑上已经安装了某些工具,不想再安装,也可以通过改这些路径来讲其指到新的路径,但要注意工具的版本要符合ESP-IDF的要求。 ESP-IDF中也有相关文件记录这些工具的位置,参考: https://github.com/espressif/vscode-esp-idf-extension/blob/master/docs/SETUP.md#JSON-Manual-Configuration 一般vscode的ESP-IDF插件中常出现的IDF_TOOLS_PATH就是指这个路径: 3、安装 官方的安装教程如下: https://github.com/espressif/vscode-esp-idf-extension/blob/master/docs/tutorial/install.md 一般按照这个教程一步步的都可以正常安装。如果本地存在ESP-IDF和一些工具链,不想下载,让vscode能找到。可以看到在安装首页时就可以指定本地存在的ESP-IDF: 通过指定本地存在的文件,可以避免下载新文件。 其中ESP_IDF应该指到:esp-idf-v4.4.4.zip解压缩后形成的esp-idf文件夹,如下图: 里面包含了一些初始化的脚本文件和操作工具的脚本文件: 其中IDF_TOOLS_PATH应该指到:将工具链里面各工具放在同一个叫tools的文件夹,指到tools文件夹的上层,如下图: tools文件夹中包含了各种工具: 按照教程安装,看到下图界面时,代表安装成功,就可以开始愉快的ESP32 IDF开发之旅啦!!!

【七】CSS之弹性布局

【七】CSS之弹性布局 【1】什么是弹性布局 随着技术的发展,那么在当前市场上,安装浏览器的客户端越来越多,设备也越来越多,所以CSS提供的布局,不仅应用于PC端,还可以应用于移动端设备 例如:watch、ipad,mobile等,甚至包括机器人界面、智能屏、智能电视机、3D广告屏幕等等。也因此前端开发越来越需要一套代码就可以应用任何一种不同的屏幕下的样式。 弹性布局,也叫Flex布局(Flexible Box) 这种布局方式是把HTML网页中每一个元素都看成1个能够进行自由伸缩的盒模型(Flex盒模型,弹性盒模型)。 任何一个html元素都可以指定为Flex盒模型。 .box{ display: flex; /* flex盒模型有2种,块级元素可以设置为flex盒模型,行内元素也可以通过 display: inline-flex; 设置为行级flex盒模型 */ } 注意,当元素设为 Flex 布局元素以后,当前flex盒模型元素的子元素的float、clear和vertical-align属性将失效,因为flex布局本身也提供了替代的属性。 【2】基本概念 采用 Flex 布局的元素,称为 Flex 容器(flex container),简称"容器"。它的所有子元素自动成为容器成员,称为 Flex 项目(flex item),简称"项目"。 容器默认存在两根轴: 水平的主轴(main axis,也叫横轴或X轴)和垂直的交叉轴(cross axis,也叫纵轴或Y轴)。主轴的开始位置(与边框的交叉点)叫做main start,结束位置叫做main end;交叉轴的开始位置叫做cross start,结束位置叫做cross end。 项目默认沿主轴排列。 单个项目占据的主轴空间叫做main size,占据的交叉轴空间叫做cross size。 【3】Flex容器的属性 提供了6个属性可以设置在flex容器上。 属性描述flex-direction决定主轴的方向(即项目的排列方向)flex-wrap默认情况下,项目都排在一条线(又称"轴线")上。flex-wrap属性定义,如果一条轴线排不下,如何换行。flex-flowflex-flow属性是flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap。justify-content定义flex项目在主轴(x轴)上的对齐方式。align-items定义flex项目在交叉轴(y轴)上如何对齐。align-content定义多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。 (1)flex-direction flex-direction属性决定主轴的方向(即项目的排列方向)。 属性值描述row按行正向排列row-reverse按行翻转排列column按列正向排列column-reverse按列翻转排列 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> ul{display: flex;list-style: none;} li{width: 100px;height: 40px;margin: 5px;background: red;color: white;} .box1{flex-direction: row;} .

给README

在github中,给README.md添加图片 大致的原理是:先上传图片到Github中,然后在READE.md中添加图片!是云存储的方式。 1.首先将图片上传到Github上,然后获取图片的路径。即为图片的路径了! 2.使用绝对路径写法: ![image](https://github.com/cainiaoyige01/tingyu-cloud/blob/main/static/img/2.png)) 3.相对路径写法 ![image](statis/img/2.png) 4.点击“Preview ”就可以看到效果了

SpringBoot+ Dubbo + Mybatis + Nacos +Seata整合来实现Dubbo分布式事务

1.简介 “ 本文主要介绍SpringBoot2.1.5 + Dubbo 2.7.3 + Mybatis 3.4.2 + Nacos 1.1.3 +Seata 0.8.0整合来实现Dubbo分布式事务管理,使用Nacos 作为 Dubbo和Seata的注册中心和配置中心,使用 MySQL 数据库和 MyBatis来操作数据。 ” 如果你还对SpringBoot、Dubbo、Nacos、Seata、Mybatis 不是很了解的话,这里我为大家整理个它们的官网网站,如下 SpringBoot:https://spring.io/projects/spring-boot Dubbo:http://dubbo.apache.org/en-us/ Nacos:https://nacos.io/zh-cn/docs/quick-start.html Seata:https://github.com/seata/seata/wiki/Home_Chinese MyBatis:http://www.mybatis.org/mybatis-3/zh/index.html 在这里我们就不一个一个介绍它们是怎么使用和原理,详细请学习官方文档,在这里我将开始对它们进行整合,完成一个简单的案例,来让大家了解Seata来实现Dubbo分布式事务管理的基本流程。 2.环境准备 2.1 下载nacos并安装启动 nacos下载:https://github.com/alibaba/nacos/releases/tag/1.1.3 Nacos 快速入门:https://nacos.io/en-us/docs/quick-start.html sh startup.sh -m standalone 1 在浏览器打开Nacos web 控制台:http://192.168.10.200:8848/nacos/index.html 输入nacos的账号和密码 分别为nacos:nacos 这是时候naocs 就正常启动了。 2.2 下载seata0.8.0 并安装启动 2.2.1 在 Seata Release 下载最新版的 Seata Server 并解压得到如下目录: . ├──bin ├──conf ├──file_store └──lib 12345 2.2.2 修改 conf/registry.conf 配置, 目前seata支持如下的file、nacos 、apollo、zk、consul的注册中心和配置中心。这里我们以nacos 为例。将 type 改为 nacos

【PCL】(四)点云可视化

文章目录 可视化CloudViewer 可视化PCLVisualizer 可视化可视化单个云添加一些颜色RGB点云指定颜色 法线和其他信息绘制形状多个窗口交互自定义 可视化 CloudViewer 可视化 将【PCL】(一)PCL基本数据结构PointCloud与原生文件格式PCD末尾的数据保存到my_point_cloud.pcd,将以下代码复制到cloud_viewer.cpp #include <pcl/visualization/cloud_viewer.h> #include <pcl/io/pcd_io.h> int user_data; int main () { pcl::PointCloud<pcl::PointXYZRGBA>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZRGBA>); pcl::io::loadPCDFile ("my_point_cloud.pcd", *cloud); pcl::visualization::CloudViewer viewer("Cloud Viewer"); viewer.showCloud(cloud); while (!viewer.wasStopped ()) { } return 0; } cmake_minimum_required(VERSION 3.5 FATAL_ERROR) project(cloud_viewer) find_package(PCL 1.2 REQUIRED) include_directories(${PCL_INCLUDE_DIRS}) link_directories(${PCL_LIBRARY_DIRS}) add_definitions(${PCL_DEFINITIONS}) add_executable (cloud_viewer cloud_viewer.cpp) target_link_libraries (cloud_viewer ${PCL_LIBRARIES}) 得到可执行文件后用鼠标点击并缩放会看到: PCLVisualizer 可视化 PCLVisualizer是PCL功能更全的可视化类。虽然使用起来比CloudViewer更复杂,但它也更强大,提供了显示法线、绘制形状和多个视口等更多的功能。 以下代码为一些可视化功能的模板,我们首先将其复制到名为pcl_visualizer_demo.cpp的文件中。 /* \author Geoffrey Biggs */ #include <iostream> #include <thread> #include <pcl/common/angles.

数字图像处理 实验七:图像的复原处理 matlab

实验内容 (1)构造一个矩形方块图像,对其分别加入高斯和椒盐噪声,显示原始图像和噪声图像,及每个图片相对应的直方图。 (2)任意选择一幅图像,对其使用运动模糊处理,再在模糊图像中加入高斯噪声,使用逆滤波和 winner 滤波对其进行去退化处理,比较效果,显示原始图像和复原图像。 源程序和结果 (1)构造一个矩形方块图像,对其分别加入高斯和椒盐噪声,显示原始图像和噪声图像,及每个图片相对应的直方图。 a=zeros(256,256); a(1:128,1:128)=235; a(129:256,1:128)=155; a(1:128,129:256)=125; a(129:256,129:256)=100; j=imnoise(uint8(a),'salt & pepper',0.02);%加椒盐噪声 m=imnoise(uint8(a),'gaussian');%加高斯噪声 figure (1) subplot(2,3,1);imshow(uint8(a));title('原图'); subplot(2,3,4);imhist(uint8(a));subplot(2,3,2); imshow(j);title('加入椒盐噪声'); subplot(2,3,5);imhist(j);subplot(2,3,3); imshow(m);title('加入高斯噪声');subplot(2,3,6);imhist(m); (2)任意选择一幅图像,对其使用运动模糊处理,再在模糊图像中加入高斯噪声,使用逆滤波和 winner 滤波对其进行去退化处理,比较效果,显示原始图像和复原图像。 clear; close all A=imread('lena.bmp'); figure (2) subplot(1,2,1); imshow(A);title('原图像'); l=rgb2gray(A); subplot(1,2,2); imshow(l); title('二维灰度图像');%将彩色图像转换为二维灰度图像 [m,n]=size(l); F=fftshift(fft2(l));k=0.0025; H=[]; for u=1:m for v=1:n q=((u-m/2)^2+(v-n/2)^2)^(5/6); H(u,v)=exp((-k)*q); end end G=F.*H; l0=abs(ifft2(fftshift(G))); figure (3); subplot(2,2,1); imshow(uint8(l0)); title('模糊图像'); l1=0.1*randn(size(l0)); l1=l0+l1; %生成高斯白噪声图像 subplot(2,2,2) imshow(uint8(l1)); title('模糊并且添加高斯白噪声图像'); F0=fftshift(fft2(l1)); F1=F0./H; l2=ifft2(fftshift(F1)); subplot(2,2,3) imshow(uint8(l2)); title('逆滤波后复原图像'); K=0.1;%维纳滤波的参数可以调H=[];

react中查找DOM的方法

1, 给标签设置ref属性, 通过this.refs调用 (老版本语法,将要废除) <h1 ref="myH1"></h1> this.refs.myH1 2, 在构造器中创建ref全局变量, 在标签中ref属性动态绑定这个全局变量, 通过全局变量的current字段调用 this.myH2 = React.createRef() <h2 ref={this.myH2}></h2> this.myH2.current 3, 在标签ref属性绑定函数, 在函数中定义全局变量赋值, 通过全局变量调用 <h3 ref={ ele => this.myH3 = ele }></h3> this.myH3 4, 使用hook语法查找DOM const d1 = useRef() <div id="d1" ref={d1}>div1</div> d1.current 5, 使用hook语法查找DOM const d2 = useRef() <div id="d2" ref={el => d2=el}>div1</div> d2 注意: 1, 在父组件中用ref获取子组件对象, 必须保证子组件是类组件, 函数式组件获取结果是undefined 2, 父组件使用ref获取子组件对象后, 可以对子组件状态数据和函数执行调用和修改

IP地址划分

一、IP地址的定义及分类 1.定义 1.1 IP地址是互联网协议中用于标识网络设备的地址。它是由32位二进制数(IPv4)或128位二进制数(IPv6)组成的数字,用于唯一标识互联网上的每个设备。 1.2 IP地址通常被分类为以下几种类型: 公网IP地址:指的是公共互联网上的IP地址,可以用于全球范围内的互联网通信。 私有IP地址:指用于局域网内部通信的IP地址,只能在局域网内部使用,不能在公共互联网上使用。 静态IP地址:指指派给网络设备的永久不变的IP地址,一旦分配就不会自动更改。 动态IP地址:指由网络服务提供商(ISP)临时向网络设备分配的地址,可能会因为不同的连接、时间段或重新启动而发生变化。 共享IP地址:指多个设备共用同一个IP地址,通常用于在一个局域网内部共享网络连接资源。 2.分类 2.1 IP地址由两部分组成,网络部分(netID)和主机部分(hostID)。网络部分用于标识不同的网络,主机部分用于标识在一个网络中特定的主机。IP地址的网络部分由IANA(Internet Assigned Numbers Authority,Internet 地址分配机构)统一分配,以保证IP地址的唯一性。为了方便管理和分配,IANA将地址分为A类、B类、C类、D类和E类五类。 2.2 A类地址:第一个八位组第的1个比特位为0,所以它的第一个八位组的范围是00000000—01111111,第2-8位为网络号,第9-32位为主机号。A类地址的第一个地址块(网络号为0)和最后一个地址块(网络号为127)保留使用,即全0代表本地网络,全1代表保留诊断作用,因此A类地址的有效网络为0—126,全世界只有126个A类网络,每个A类网络拥有的主机数为24个比特位的组合,为2^24个,A类地址可用于最多128个网络,每个网络可容纳最多16777214个主机,因此称为"大型网络",其地址范围为0.0.0.0~127.255.255.255。 A类私有地址是以下IP地址范围:10.0.0.0/8, 即10.0.0.0--10.255.255.255 A类地址中有一个特殊的地址是127.0.0.1,称为本机回环地址,用于主机测试,通常通过在本机上ping此地址来检查TCP/IP协议安装得正确与否。而且凡是以127开头的IP地址都代表本机。 2.3 B类地址: 第1-2位为10,网络部分范围是10000000.00000000—10111111.11111111第3-16位为网络号,第17-32位为主机号。B类地址可用于最多16384个网络,每个网络可容纳最多65534个主机,因此称为"中型网络",其地址范围为128.0.0.0~191.255.255.255。 B类私有地址范围:172.16.0.0/12, 即172.16.0.0--172.31.255.255,其中172.16.0.0和172.31.255.255是网络地址和广播地址,不能分配给主机。B类私有地址可以在企业内部使用,但不能在公共互联网中路由。 2.4 C类地址: 第1-3位为110,第4-24位为网络号,第25-32位为主机号。C类地址可用于最多2097152个网络,每个网络可容纳最多254个主机,因此称为"小型网络",其地址范围为192.0.0.0~223.255.255.255。 C类私有地址:192.168.0.0/ 16, 即192.168.0.0--192.168.255.255。这个地址范围是被保留用于内部网络的使用。在局域网或企业内部网络中使用这些地址可以避免与公共网络地址冲突。C类私有地址的使用不需要向任何组织或机构申请,因为它们是用于内部网络的。 2.5 D类地址: 第1-4位为1110,用于组播(multicasting),其地址范围为224.0.0.0~239.255.255.255。 2.6 E类地址: 第1-4位为1111,其地址范围为240.0.0.0~255.255.255.255,保留作为实验和研究使用,不用于实际网络通信。 二、子网掩码 子网掩码(Subnet Mask)是一个用于指示一个IP地址属于哪个网络的标准,它是一个32位的二进制数,通常用4个十进制数表示,每个数范围为0~255。子网掩码的作用是将IP地址分为网络地址和主机地址两部分,其中,网络地址确定了主机所在的网络,而主机地址则确定了该网络内部的具体主机。子网掩码通常与IP地址配合使用,通过将IP地址和子网掩码进行逻辑运算,来计算出网络地址和主机地址。例如,IP地址为192.168.1.100,子网掩码为255.255.255.0,则该IP地址所在的网络地址为192.168.1.0。 子网掩码(Subnet Mask)是一个32位的二进制数,用于指示一个IP地址中,哪些位是网络地址,哪些位是主机地址。它与IP地址一起使用,用于划分IP地址所在的网络和子网,以便实现网络通信。在计算机网络中,子网掩码是非常重要的概念,正确的设置子网掩码可以有效地提高网络的性能和安全性。 子网掩码的作用是将一个IP地址分成两部分:网络地址和主机地址。网络地址用于标识网络,主机地址用于标识主机。在一个子网中,所有的主机共享相同的网络地址,而主机地址则用于区分不同的主机。子网掩码通过将IP地址中的网络地址部分全部置为1,主机地址部分全部置为0,来标识网络地址和主机地址的范围。 例如,对于IP地址192.168.1.100,若子网掩码为255.255.255.0,则该IP地址中的前24位(即前3个8位)表示网络地址,后8位表示主机地址。因此,该IP地址所在的网络地址为192.168.1.0,主机地址为100。如果在同一子网中,其他主机的IP地址的前24位与该IP地址的前24位相同,则它们属于同一个子网,可以直接进行通信。 子网掩码的值通常是255.255.255.0或255.255.0.0或255.0.0.0等。其中,255表示该位是网络地址,0表示该位是主机地址。子网掩码的值越小,可以划分出的子网数量就越多,但每个子网可用的IP地址就越少。反之,子网掩码的值越大,可以划分出的子网数量就越少,但每个子网可用的IP地址就越多。因此,在设置子网掩码时,需要根据实际情况进行选择,以平衡网络性能和可用IP地址的需求。 在实际应用中,子网掩码通常与IP地址一起使用,来确定网络和子网的范围。例如,如果有一个IP地址为192.168.1.100,子网掩码为255.255.255.0的网络,那么网络地址是192.168.1.0,主机地址范围是从192.168.1.1到192.168.1.254。如果有一个IP地址为10.1.1.100,子网掩码为255.255.0.0的网络,那么网络地址是10.1.0.0,主机地址范围是从10.1.0.1到10.1.255.254。 在网络管理中,正确设置子网掩码也可以帮助提高网络的安全性。通过设置适当的子网掩码,可以将不同的网络和子网隔离开来,从而减少网络攻击的风险。例如,在一个企业内部网络中,可以将不同的部门划分到不同的子网中,使得不同部门之间的网络流量受到限制,从而减少网络攻击的可能性。 子网掩码的计算 TCP/IP网间网技术产生于大型主流机环境中,它能发展到今天的规模是当初的设计者们始料未及的。网间网规模的迅速扩展对IP地址模式的威胁并不是它不能保证主机地址的唯一性,而是会带来两方面的负担:第一,巨大的网络地址管理开销;第二,网关寻径急剧膨胀。其中第二点尤为突出,寻径表的膨胀不仅会降低网关寻径效率(甚至可能使寻径表溢出,从而造成寻径故障),更重要的是将增加内外部路径刷新时的开销,从而加重网络负担。 因此,迫切需要寻求新的技术,以应付网间网规模增长带来的问题。仔细分析发现,网间网规模的增长在内部主要表现为网络地址的增减,因此解决问题的思路集中在:如何减少网络地址。于是IP网络地址的多重复用技术应运而生。通过复用技术,使若干物理网络共享同一IP网络地址,无疑将减少网络地址数。 子网编址(subnet addressing)技术,又叫子网寻径(subnet routing),英文简称subnetting,是最广泛使用的IP网络地址复用方式,目前已经标准化,并成为IP地址模式的一部分。 32位的IP地址分为两部分,即网络号和主机号,分别把他们叫做IP地址的“网间网部分”和“本地部分”。子网编址技术将“本地部分”进一步划分为“物理网络”部分和“主机”两部分,其中“物理网络”部分用于标识同一IP网络地址下的不同物理网络,常称为“掩码位”、“子网掩码号”,或者“子网掩码ID”,不同子网就是依据这个掩码ID来识别的。 按IP协议的子网标准规定,每一个使用子网的网点都选择一个32位的位模式,若位模式中的某位置1,则对应IP地址中的某位为网络地址(包括网络部分和子网掩码号)中的一位;若位模式中的某位置0,则对应IP地址中的某位为主机地址中的一位。 例如二进制位模式:11111111 11111111 11111111 00000000中,前三个字节全1,代表对应IP地址中最高的三个字节为网络地址;后一个字节全0,代表对应IP地址中最后的一个字节为主机地址。为了使用的方便,常常使用“点分整数表示法”来表示一个IP地址和子网掩码,例如B类地址子网掩码(11111111 11111111 1111111100000000)为:255.255.25.0。 IP协议关于子网掩码的定义提供一定的灵活性,允许子网掩码中的“0”和“1”位不连续。但是,这样的子网掩码给分配主机地址和理解寻径表都带来一定困难,并且,极少的路由器支持在子网中使用低序或无序的位,因此在实际应用中通常各网点采用连续方式的子网掩码。像255.255.255.64和255.255.255.160等一类的子网掩码不推荐使用 子网掩码与IP地址结合使用,可以区分出一个网络地址的网络号和主机号。例如:有一个C类地址为:192.9.200.13,按其IP地址类型,它的缺省子网掩码为:255.255.255.0,则它的网络号和主机号可按如下方法得到: 第1步,将IP地址192.9.200.13转换为二进制11000000 00001001 11001000 00001101

MySQL 8 group by 报错 this is incompatible with sql_mode=only_full_group_by

根据错误信息大概知道,是sql_mode参数设置为only_full_group_by的不兼容,如果select 的字段不在 group by 中,并且select 字段没有使用聚合函数(SUM,MAX等),这个sql查询是被mysql认为非法的,会报错。 1.查询 sql_mode select @@GLOBAL.sql_mode; 查出来值为:ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION 2.永久修改sql_mode (Liunx安装的MySQL) 1)找到my.cnf文件,通过 find -name "my.cnf" 2)编辑my.cnf文件,通过 vi etc/my.cnf 3)如果my.cnf文件中有sql_mode参数,去掉ONLY_FULL_GROUP_BY,重启MySQL 4)如果my.cnf文件中没sql_mode参数,需要手动添加,注意加在[mysqld]下,否则可能不生效 sql-mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION 5)如果第4步操作完成后还是报错,把sql-mode修改一下 sql-mode=STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION 6)重启MySQL 7)验证是否修改成功 8) 验证group by语句是否报错

代理服务器拒绝连接怎么办

在使用代理服务器时,有时我们可能会遇到代理服务器拒绝连接的问题。这种情况可能会阻止我们访问被封锁的内容或绕过地理限制。下面,我们来一起探讨一下。 1. 配置错误 代理服务器拒绝连接的一个常见原因是配置错误。请确保您已正确输入代理服务器的地址和端口号。仔细检查您的设置,确保没有拼写错误或格式错误。如果您不确定正确的配置,请找管理员以获取准确的配置信息。 2. 防火墙设置 防火墙是一种常见的网络安全措施,它可以阻止未经授权的访问。有时代理服务器所在的网络中的防火墙可能会拒绝来自外部网络的连接。在这种情况下,您需要找网络管理员,请求将您的IP地址添加到白名单中,以允许连接代理服务器。 3. 访问权限限制 某些代理服务器可能有访问权限限制,只允许特定的IP地址或用户访问。如果您的IP地址不在允许列表中,代理服务器可能会拒绝连接。您可以找管理员,请求将您的IP地址添加到允许列表中,以获得访问权限。 4. 服务器负载过高 代理服务器的负载过高也可能导致连接被拒绝。当代理服务器同时处理大量的连接请求时,它可能会限制新的连接以保持性能稳定。在这种情况下,您可以尝试稍后再次连接,或者找管理员,了解服务器负载情况,并寻求他们的建议。 5. 服务器维护 有时代理服务器可能需要进行维护工作,例如升级软件、修复漏洞或进行系统优化。在维护期间,代理服务器可能会暂时拒绝连接。如果您遇到此问题,只需稍后再次尝试连接即可。 总结: 当代理服务器拒绝连接时,最重要的是保持耐心,并尝试找出具体的原因。找管理员,向他们寻求帮助和指导,他们将能够为您提供更准确的解决方案。此外,如果您在使用代理服务器时经常遇到连接问题,您还可以尝试其他可靠的代理服务器提供商。不同的代理服务器可能有不同的性能和可靠性,选择适合您需求的代理服务器是确保顺畅连接的关键。 总之而言,当代理服务器拒绝连接时,您可以检查配置、请求访问权限、等待服务器负载下降或维护完成。通过这些方法,您将能够处理代理服务器拒绝连接的问题,并顺利访问被限制的内容。