文章目录 前言一、HAL库中寄存器地址名称映射分析二、计算寄存器地址 前言 本篇文章是为了明白HAL 库中那些结构体是怎么与寄存器地址对应起来的。部分知识参考正点原子资料。
一、HAL库中寄存器地址名称映射分析 最根本的单片机开发就是直接操作寄存器的值,给这些位赋值,但是32单片机的寄存器太多,所以MDK就使用结构体将这些寄存器组织在一起。那么只要我们修改结构体的变量就可以修改对应寄存器的值。这些结构体的关联组织是在stm32f1xx.h 的头文件中完成的。
每个寄存器的地址都是偏移过来的,以GPIO为例,它的基地址是由 APB2 总线的基地址+GPIOA 在 APB2 总线上的偏移地址决定的。同理依次类推,我们便可以算出 GPIOA 基地址。
GIPO的结构体是根据GPIO的地址来定义的,GPIO的地址是从GPIO基地址偏移过来的,GPIO的基地址是从时钟线的基地址偏移过来的,时钟线的地址是由PERIPH基地址偏移的,如下所示:
typedef struct { __IO uint32_t CRL; __IO uint32_t CRH; __IO uint32_t IDR; __IO uint32_t ODR; __IO uint32_t BSRR; __IO uint32_t BRR; __IO uint32_t LCKR; } GPIO_TypeDef; 我们跳转GPIOA的定义
#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE) 这个宏是将GPIOA的基地址强转为结构体指针,我们继续跳转GPIOA_BASE
#define GPIOA_BASE (APB2PERIPH_BASE + 0x0800) 这个宏是将APB2时钟线的地址偏移0x0800得到的GPIOA基地址,我们以此类推依次跳转
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000) #define PERIPH_BASE ((uint32_t)0x40000000) 最后得到始终总线的基地址
其他外设也是一样。
二、计算寄存器地址 计算寄存器的地址:(以GPIOA为例)
GPIOA 的寄存器的地址=GPIOA 基地址+寄存器相对 GPIOA 基地址的偏移值
文章目录 一. 认识Junit二. Junit中常用的注解1. @Test2. @Disabled3. @BeforeAll & @AfterAll4. @BeforeEach & @AfterEach 三. @ParameterizedTest参数化1. 单参数2. 多参数2.1. CSV 获取参数2.2. 方法获取参数 四. @Order控制测试用例的执行顺序五. 断言六. 测试套件1. 通过Class运行测试用例2. 通过包运行测试用例 一. 认识Junit JUnit 是一个用于编写和运行 Java 程序的开源框架,它支持自动化单元测试,可以帮助开发人员测试代码的正确性和健壮性。
JUnit 提供了一组注解、断言和测试运行器,可以方便地编写和运行单元测试。
在进行自动化测试时,比如使用 Selenium 自动化测试框架编写一些测试用例脚本,那么可能就需要执行很多测试用例的,此时我们就需要一个工具来管理这些测试用例,而 Junit 就是一个很好的管理工具。
二. Junit中常用的注解 比较常用的是 JUnit5 版本,要使用需要引入以下依赖:
<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api --> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-api</artifactId> <version>5.9.2</version> <scope>test</scope> </dependency> 其中的常用的注解有以下几个:
注解说明@Test标识单元测试方法。@BeforeEach在每个测试方法之前执行。@AfterEach在每个测试方法之后执行。@BeforeAll在所有测试方法之前执行,只会执行一次。@AfterAll在所有测试方法之后执行,只会执行一次。@Disabled标识禁用的测试类或测试方法。 1. @Test @Test注解标识在方法上面,表示当前的方法是一个单元测试方法,通过 @Test 标识的单元测试方法,不需要在main中,也可以直接执行。
演示代码:
import org.junit.jupiter.api.Test; public class JunitTest { @Test void Test01() { System.
本人github auto-imports.d.ts 文件是一个类型定义文件,用于TypeScript项目中。这个文件通常是由一些现代前端开发工具和框架自动生成的,比如Vite、Vue CLI或其他支持自动导入功能的工具。它的主要目的是提供一个类型声明环境,使得在你的项目中自动导入的变量、函数、组件等能够被TypeScript正确识别,从而提供类型检查和智能提示。
文件功能: 自动导入识别:当你使用了如Vue或React等框架的某些特性时(比如Vue的Composition API、React的Hooks等),这些特性可能会自动导入到你的项目中。auto-imports.d.ts 文件帮助TypeScript理解这些自动导入的元素,即使你在代码中没有显式导入它们。
编辑器支持:该文件还帮助编辑器(如VS Code)提供自动完成、代码高亮和其他智能提示功能。
示例: 假设你正在使用Vue 3和Vite,项目中可能会自动生成一个auto-imports.d.ts文件,内容大致如下:
// auto-imports.d.ts declare module 'vue' { export function ref<T>(value: T): Ref<T> // ...其他自动导入的API... } 在这个例子中,auto-imports.d.ts 告诉TypeScript,即使你没有在你的组件中显式导入ref函数,它也是可用的,并且提供了关于ref函数的类型信息。
注意事项: 这个文件通常不需要手动修改。它由工具自动生成,并根据项目的使用情况进行更新。如果你在使用相关的框架或工具,而且启用了TypeScript,这个文件是自动管理的,你通常不需要关心它的具体内容。
文章目录 前言一、中断如何响应?NVIC如何分配优先级?二、NVIC中断优先级管理详解三、问题汇总 前言 个人认为本篇文章是我作总结的最好的一篇,用自己的话总结出来清晰易懂,给小白看也能一眼明了,这就是写博客的意义吧。本篇文章具体介绍了 NVIC中断优先级管理,是如何进行管理,如何根据优先级响应中断的。本篇文章仅作为个人学习笔记总结,不做权威标准。
一、中断如何响应?NVIC如何分配优先级? 那么是如何响应的呢?中断占用8bit,但是只用高四位。优先级分组为4位,有以下的分组方式:0-4,1-3,2-2,3-1,4-0,这几组中分别是响应优先级和抢占优先级的分组,例如1-3,就是响应优先级为1,抢占优先级为3。
1.抢占优先级的级别>响应优先级级别
2.数值越小优先级越高
3.抢占优先级与响应优先级都一样,那么看哪个中断先发生。
4.高优先级的抢占优先级的中断可以打断低抢占优先级的中断,但是高优先级的响应优先级的中断不能够打断低响应优先级的中断。
例子:假定设置中断优先级组为 2,然后设置中断 3(RTC 中断)的抢占优先级为 2,响应优先级为 1。中断 6(外部中断 0)的抢占优先级为 3,响应优先级为 0。中断 7(外部中断 1)的抢占优先级为 2,响应优先级为 0。那么这 3 个中断的优先级顺序为:中断 7>中断 3>中断 6。
上面例子中的中断 3 和中断 7 都可以打断中断 6 的中断。而中断 7 和中断 3 却不可以相互打断!
二、NVIC中断优先级管理详解 详细NVIC中断优先级管理,以下是正点原子的详细介绍:(上面懂了下面不用看)
CM3 内核支持 256 个中断,其中包含了 16 个内核中断和 240 个外部中断,并且具有 256 级的可编程中断设置。但 STM32 并没有使用 CM3 内核的全部东西,而是只用了它的一部分。 STM32 有 84 个中断,包括 16 个内核中断和 68 个可屏蔽中断,具有 16 级可编程的中断优先级。而我们常用的就是这 68 个可屏蔽中断,但是 STM32 的 68 个可屏蔽中断,在 STM32F103 系列上面,又只有 60 个(在 107 系列才有 68 个)。
目录
一、QString 格式化 之 arg():
二、字符串拼接操作
三、字符串部分删除
四、字符串替换
五、字符串查找
六、其他,一些常用的方法
一、QString 格式化 之 arg(): 1、常规用法
QString QString::arg(const QString &a, int fieldWidth = 0, QChar fillChar = QLatin1Char(' ')) const;
----------------
Returns a copy of this string with the lowest numbered place marker replaced by string a, i.e., %1, %2, ..., %99.
fieldWidth specifies the minimum amount of space that a is padded to and filled with the character fillChar. A positive value produces right-aligned text; a negative value produces left-aligned text.
前言 HTTP(Hypertext Transfer Protocol)和HTTPS(Hypertext Transfer Protocol Secure)是用于在客户端和服务器之间传输数据的协议。它们之间的主要区别在于安全性和数据传输的方式:
安全性:HTTP是明文传输协议,数据在传输过程中不加密,容易被窃听和篡改。而HTTPS通过使用SSL(Secure Sockets Layer)或TLS(Transport Layer Security)协议对数据进行加密,确保数据在传输过程中的机密性和完整性,提供更高的安全性。
数据传输方式:HTTP使用的是默认的端口80,而HTTPS使用的是默认的端口443。HTTP的数据传输是明文的,而HTTPS的数据传输是经过加密的。
证书验证:HTTPS使用SSL证书对服务器进行身份验证,确保客户端与服务器之间的通信是安全的。这样可以防止中间人攻击和伪造网站。
由于HTTPS提供了更高的安全性,现在许多网站都采用HTTPS协议来保护用户的隐私和数据安全。
废话不多说,直接上流程
免费证书准备 现在腾讯云,百度云,阿里云都有免费的证书可以申请,大家可以到各自官网上申请,咱们这里选择百度智能云(为啥选择百度云?哈哈,因为楼主在百度呆过几年,对百度还有有感情滴!)
百度智能云搜索ssl证书 选择立即购买 选择其他证书品牌-TrustAsia-域名型DV-单域名版(测试版) 确认订单提交 ssl证书控制台查看已申请的证书 选择一个域名点击查看申请进行域名验证 我这里是第三方的域名注册商,在你购买的域名地址上边,配置下DNS,记录类型选择CNAME方式,主机记录与记录值都需要填一下,具体填写规则,主要看你的域名购买商怎么要求的,一般都差不多
Type:记录类型
HOST: 主机记录
ANSWER:记录值
填写完成后等待百度云自动发起验证,我们静待结果即可
验证通过后,我们就可以下载证书,配置到自己的网站上了
下载证书,网站用的nginx,这里选择nginx版本的 部署证书,这里贴出nginx配置 server { listen 80; server_name 证书绑定的域名; rewrite ^(.*)$ https://$host$1 permanent; #把http转成https } server { listen 443 ssl; server_name 证书绑定的域名; ssl_certificate /usr/share/cert/test.crt; #我把证书放到这个目录上里边了,你们随意 ssl_certificate_key /usr/share/cert/test.key; #我把证书放到这个目录上里边了,你们随意 ssl_session_timeout 5m; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; } 重启nginx,搞定
搭建 LAMP(Linux、Apache、MySQL、PHP)堆栈是在 Ubuntu 上构建 Web 服务器的常见任务。以下是一些步骤,指导如何在 Ubuntu 上搭建 LAMP 环境:
步骤:
更新系统软件包:
在终端中执行以下命令,确保系统中的软件包是最新的:
sudo apt update sudo apt upgrade 安装 Apache Web 服务器:
安装 Apache 服务器:
sudo apt install apache2 启动 Apache 并设置其开机自启动:
sudo systemctl start apache2 sudo systemctl enable apache2 验证 Apache 是否安装成功,打开浏览器,访问你的服务器 IP 地址(或者域名):
http://your_server_IP 应该看到 Apache 的默认页面。
安装 MySQL 数据库:
安装 MySQL 服务器:
sudo apt install mysql-server 安装过程中会提示你设置 root 用户的密码。安装完成后,执行 MySQL 安全性脚本进行一些安全设置:
sudo mysql_secure_installation 安装 PHP:
目录
移除链表元素
反转链表
链表的中间节点
返回倒数第k个节点 合并两个有序列表 分割链表
链表的回文结构
相交链表:找两个链表的公共节点
环形链表:判断链表中是否有环
环形链表 II:要求返回入环的第一个节点
移除链表元素 题目链接:力扣(LeetCode)
思路:和前面学的单链表的中间删除数据一样,使要被删除节点的前一个节点指向下要被删除节点的下一个节点,然后把要被删除的节点free掉。
具体实现过程:先定义prev和cur,让cur指向头节点,遍历链表,如果cur->val!=val,让prev指向cur,cur指向cur的下一个节点,(prev始终在cur前面一个节点),当cur->val=val时停下,让prev的下一个节点指向cur的下一个节点,删除它们中间的cur节点,然后让cur重新指向prve->next,这就实现了节点的删除。但是还有一种情况如下图:
头节点的数据等于val,这时就需要判断了,如果头节点数据等于val,就要删除头节点,然后把head重新指向原来的头结点的下一个节点,cur重新指向head:
代码如下:
struct ListNode* removeElements(struct ListNode* head, int val) { struct ListNode*prev=NULL; struct ListNode*cur=head; while(cur!=NULL) { if(cur->val==val) { if(prev) { prev->next=cur->next; free(cur); cur=prev->next; } else { head=cur->next; free(cur); cur=head; } } else { prev=cur; cur=cur->next; } } return head; } 这道题还有一道解法,就是重新开辟一个节点,找到不相等的节点,尾插到该节点的后面
直接上代码:
struct ListNode* removeElements(struct ListNode* head, int val) { struct ListNode* newhead=NULL; struct ListNode* cur=head; struct ListNode* tail=NULL; while(cur!
xshell出现此类代码
Connecting to 10.0.0.100:22...
Could not connect to '10.0.0.100' (port 22): Connection failed.
Type `help' to learn how to use Xshell prompt.
排除ssh端口问题
可能是Windows中网络服务关闭(以window11版本为例)
解决方法
此电脑右键显示更多选项中的管理
选择服务和应用程序中的服务,查找VMware NAT服务,查看是否在运行
如果不在运行,点击启动,重启vmware。xshell重连即可
一 整体设计 原文:敲黑板,也来谈如何设计一个秒杀系统(重点)
https://mp.weixin.qq.com/s?__biz=MzAwMjk5Mjk3Mw==&mid=2247499316&idx=2&sn=8c5c7d3071558abb183ab5505f102161&chksm=9ac34016adb4c900d7ce84191c0d65af634e7b92382e483a5bdead026b9f25460c15b996739f&scene=27
Overview 1.1 并发读写
秒杀要解决的主要问题是:并发读与并发写。
并发读的优化理念是尽量减少用户到服务端来读数据,或者让他们读更少的数据;并发写的处理原则一样,要求我们在数据库层面独立出一个库,做特殊的处理。
其次,还需要针对秒杀系统做一些保护,针对意料之外的情况设计兜底方案,以防止最坏的情况发生。
1.2 API设计原则
值得注意的地方是:如果想打造并维护一个超大流量并发读写、高性能、高可用的系统,在整个用户请求路径上从浏览器到服务端我们要遵循几个原则,就是保证用户请求的数据尽量少、请求数尽量少、路径尽量短、依赖尽量少,不要有单点
1.3 秒杀架构原则
1.3.1 高可用
整个系统架构需要满足高可用性,流量符合预期的时候肯定要稳定,就是超出预期也同样不能掉链子,保证秒杀产品顺利卖出。
1.3.2 一致性
数据必须一致,即成交总量必须和设定的数量一致。
1.3.3 高可用
系统的性能要足够强,支撑足够大的流量,不仅是服务端要做极致的性能优化,而且在整个请求链路上都要做协同的优化,每个地方都要快一点,整个系统就完美了。
本文将从这三个原则上来分别进行详细说明。
架构原则
秒杀系统本质上是一个满足大并发、高性能和高可用的分布式系统。 2.1 数据尽量少
用户请求的数据能少就少,请求的数据包括上传给系统的数据和系统返回给用户的数据。
因为这些数据在网络上传输需要时间,其次不管是请求数据还是返回数据都需要服务器处理,而服务器在写网络的时候通常都要做压缩和字符编码,这些都非常消耗CPU,所以减少传输的数据量可以显著减少CPU的使用。
同样,数据尽量少还要求系统依赖的数据能少就少,包括系统完成某些业务逻辑需要读取和保存的数据,这些数据一般是和后台服务以及数据库打交道的。调用其他服务会涉及数据的序列化和反序列化,这也是CPU的一大杀手,同样也会增加延时。而且数据库本身也很容易成为瓶颈,因此越少和数据库打交道越好。
2.2 请求数尽量少
用户请求的页面返回后,浏览器渲染这个页面还要包含其他的额外请求,比如说,这个页面依赖的 CSS/JavaScript、图片,以及 Ajax 请求等等都定义为“额外请求”,这些额外请求应该尽量少。因为浏览器每发出一个请求都多少会有一些消耗,例如建立连接要做三次握手,有的时候有页面依赖或者连接数限制,一些请求(例如 JavaScript)还需要串行加载等。另外,如果不同请求的域名不一样的话,还涉及这些域名的 DNS 解析,可能会耗时更久。所以你要记住的是,减少请求数可以显著减少以上这些因素导致的资源消耗。
例如,减少请求数最常用的一个实践就是合并 CSS 和 JavaScript 文件,把多个 JavaScript 文件合并成一个文件,在 URL 中用逗号隔开(https://g.xxx.com/tm/xx-b/4.0.94/mods/??module-preview/index.xtpl.js,module-jhs/index.xtpl.js,module-focus/index.xtpl.js)。这种方式在服务端仍然是单个文件各自存放,只是服务端会有一个组件解析这个 URL,然后动态把这些文件合并起来一起返回。
2.3 路径要尽量短
路径指的是用户发出请求到返回数据这个过程中需要经过的中间节点的数量。
通常,这些节点可以表示为一个系统或者一个新的 Socket 连接(比如代理服务器只是创建一个新的 Socket 连接来转发请求)。每经过一个节点,一般都会产生一个新的 Socket 连接。
然而,每增加一个连接都会增加新的不确定性。从概率统计上来说,假如一次请求经过 5 个节点,每个节点的可用性是 99.9% 的话,那么整个请求的可用性是:99.9% 的 5 次方,约等于 99.
1. Nest.js+Mysql 数据库连接失败 报错提示:
first-nest-first-nest-1 | [Nest] 1 - 11/10/2023, 1:57:08 AM ERROR [ExceptionHandler] connect ECONNREFUSED 127.0.0.1:3306 first-nest-first-nest-1 | Error: connect ECONNREFUSED 127.0.0.1:3306 first-nest-first-nest-1 | at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1595:16) first-nest-first-nest-1 exited with code 1 docker-compose.yml配置
version: '3' services: mysql: image: mysql:5.7 # container_name: first-nest-mysql #自定义容器的名称 volumes: #挂载当前的data目录到容器默认mysql存储目录 - ./deploy/mysql/db:/var/lib/mysql - ./deploy/mysql/mysqld:/var/run/mysqld environment: #环境变量 - MYSQL_ROOT_PASSWORD=123456 #mysql的root密码 - MYSQL_DATABASE=love_koa_docker #mysql的初始化数据库 command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci ports: - "3305:3306" #docker 重启后,容器自启动 restart: always networks: - app-network first-nest: depends_on: - mysql build: context: .
文章目录 一、登陆系统(1)需用用户填写的登陆信息:(2)登陆操作进行了严格的判断:a:当用户没有输入任何信息就直接点击“登陆”进行登陆的时候,会根据输入框的顺序依次进行判断:b: 当用户开始输入信息点击“登陆”进行登陆的时候,会根据输入框的顺序再次进行判断: 二、主页面三、《预约安排》模块四、《客户接待》模块五、《维修派工》模块六、《维修领料查询》模块七、《维修领料》模块八、《维修退料》模块九、《完工确认》模块十、《结算出厂》模块十一:《快速修车》模块附Android相关展示页面和代码 项目名称:智百盛汽修管理系统 注:本项目只作为学习案例,仅供参考。 一、登陆系统 (1)需用用户填写的登陆信息: 1、账号2、密码3、验证码4、用户类型 (2)登陆操作进行了严格的判断: a:当用户没有输入任何信息就直接点击“登陆”进行登陆的时候,会根据输入框的顺序依次进行判断: 然后分别会给出如下提示:
1、用户名不能为空;2、密码不能为空;3、验证码不能为空;4、请选择用户类型! b: 当用户开始输入信息点击“登陆”进行登陆的时候,会根据输入框的顺序再次进行判断: 然后分别会给出如下提示:
1、判断用户是否正确;2、判断密码是否正确;3、判断验证码是否正确;4、判断用户类型是否正确。 假如输入的信息全部都是不正确的,便会根据判断进行提示:然后分别会给出如下提示:
1、用户不正确;2、密码不正确;3、验证码不正确;4、用户类型不正确。 只有输入的信息全部都正确才可以顺利进入“智百盛汽修汽配”管理系统。
登陆页面如下图显示:
二、主页面 登陆进入主页面后,主页面的截图如下:
1、主页面在右上角的地方设置显示当前登陆的用户名(不是登陆的账户号,而是用户名),登陆时间(获取当前登陆的系统时间)和登陆时长(设置session,自动计时,不需要刷新页面,登陆的时长也会自动增加)
2、点击左边导航栏《汽修管理》按钮,进入汽修管理模块,页面截图如下:
三、《预约安排》模块 预约安排主要是针对需要前来修车的客户的预约登记,录入车主、维修车辆基本信息(若已是老客户,可直接导入信息)及修理项目。
♦登记车牌、车型、车主信息,方便后期查询车主资料。
♦修理单号、修理类别、金额、开单日期和预约维修日期、接车人。
♦修理项目(明细)、估计配件、其他费用、备注、保险索赔:方便维修人员进行维修领料,以及修理时的注意事项,还有后期保险索赔的办理。
然后点击《预约安排》按钮或者图标,都可以进入预约安排的页面进行相关的操作,页面截图如下:
本页面可以操作的功能分别有“新增”,“删除”,“保存”,“打印”,“查询单据”,“转维修单”,“审核”,“反审核”,“退出”。
首先请看预约安排单页面中的内容:
预约单号:该单号是自动生成的(由大写字母BJ+年月日时分/yyMMdd HHmm+登陆的账户号+0001组成),然后根据每一天的日期来自增,每天首单都是自动从0001开始递增。
对应维修单号:是不能输入的,是用于回填的,它来源于单据转维修单后,也是自动生成的。
开单日期和预约维修日期都是绑定当前的系统时间,车牌文本框中的“Go!”按钮可以点击,然后进入车牌模态框,页面如下:
该模态框的数据是客户是信息,可以在此录入客户的基本信息,即新增客户的基本资料,新增完也可以回填修改(单击表格中的任意行,即可将数据回填到右边对应的文本框中),“请输入车牌号快速查找”是迷糊查询车牌的,可以输入完整的车牌号或者一个号码匹配相对应的数据车辆,方便操作者的操作;然后是“选中”按钮,该按钮是把表格的数据选中回填到主页面的,也相当于双击表格中的数据进行回填,这里既可以选择“选中”按钮进行操作,也可以双击表格进行回填,两个功能都可以实现;接着是“新增”按钮,该按钮并不是真正意义上是新增数据,而是当你单击表格中的任意行,即可将数据回填到右边对应的文本框中,将所有的文本框中的数据进行清空,说白了就是一个清空按钮;然后是“保存”按钮,该按钮可以进行两个操作,第一是新增数据到数据库,第二是修改数据。这里编码的时候要注意。接着是“刷新”操作,该操作是实现刷新页面的作用,这里忽略,最后是“关闭”按钮,点击就关闭模态框。
PS:右边表格中的客户编号也是利用自动生成编号的原理实现的效果,最右下角是“修改复选框”是用来勾选修改数据的,不勾选回填的数据不能进行修改,只有把复选框选中才可以对数据进行修改的操作。
现在我们单击一条数据进行回填,回填到页面的效果如下:
剩余的文本框和下拉框需要用户手动去输入和选择;
接下来下面是明细表格的操作:
1、修理项目明细表格中:可以利用鼠标右键选择“添加”和“删除”两个操作,添加是继续添加一行,删除是从最后一行进行删除;
添加行后只需选中修理项目下拉框就可以把其他的数据进行绑定,然后只要再选择维修性质下拉框就可以了,若是需要更改,表格也是可以编辑的,直接在表格修改即可。
2、产品材料明细表格中:可以利用鼠标右键选择“添加”和“删除”两个操作,添加弹出另一个产品模态框,供用户选择需要的产品材料,如下图,删除是从最后一行进行删除数据;
该产品模态框也可以进行多种商品类型的模糊查询,首选可以选择快速查找旁边是下拉框,选择对应是数据,然后再在下拉框旁边是文本框输入与下拉框匹配的信息进行筛选,也可以点击左边的货品分类目录,进行筛选对应是数据,筛选到需要的收据就可以勾选(多条)相对应是数据前面的复选框,然后点击“确定”按钮进行回填到产品材料明细表格中,如果找的数据不满足需求还可以点击“新增加”按钮进入另一个模态框,然后又可以在该模态框输入你想要的信息,也可以上传图片,如下图,再进行保存,数据新增成功后就会刷新出现在产品模态框中,然后可以重复上面是操作回填就可以了。
3、其他费用明细表格中:可以利用鼠标右键选择“添加”和“删除”两个操作,添加是继续添加一行,删除是从最后一行进行删除,添加行后只需选中费用名称下拉框就可以把其他的数据进行绑定,若是需要更改,表格也是可以编辑的,直接在表格修改即可。如图:
接着再看“查询单据”按钮的操作,查询单据是数据来源于刚才主页面保存后的数据,点击“查询单据”弹出单据模态框,如图:
在该模态框中可以进行预约单号模糊查询和审核状态下拉框匹配查询,然后可以双击表格回填数据到主页面(或者单击数据再点击“确定”按钮,也可以回填),回填后还可以在主页面进行“审核”和“反审核”操作;
审核后的数据不允许更改,如下图,
反审核后的数据可以再次修改,如下图。
四、《客户接待》模块 客户接待主要是对前来修车的客户及维修基本资料进行登记,把修理的明细录入,以便后期进行查询。
♦登记车牌、车型、进厂里程、油量、车主信息、发动机号码:方便后期查询车主资料。
♦修理编号、类别、金额、进厂日期和结算日期、送修人电话:方便管理人员管理,联系送修人在相应的时间来取车。
♦修理项目(明细)、估计配件、其他费用、备注、保险索赔:方便维修人员进行维修领料,以及修理时的注意事项,还有后期保险索赔的办理。
在主页面点击《客户接待》按钮或者图标,都可以进入客户接待的页面进行相关的操作,页面截图如下:
本页面同样也是登记维修客户的基本资料,然后录入各种明细,具体操作参考《预约安排》模块;
然后点击“查询单据”,弹出单据模态框。如图:
该模态框是记录保存进去的数据,双击数据可以进行数据回填,如图:
五、《维修派工》模块 在《客户接待》模块中点击“转派工单”可以将对应的数据绑定过来,也就是回填,这里以选择单据回填后的数据来说明,回填后直接点击“转派工单”就可以将《客户接待》页面的数据绑定过来了,如图:
在此页面还可以点击“派工”继续添加明细行,每次添加一行,也可以点击“删除”按钮进行删除。同样可以点击“查询单据”进入单据模态框,如图:
在该模态框中可以进行维修单号模糊查询、单据状态、付款下拉框和车牌匹配查询,然后可以双击表格回填数据到主页面。
六、《维修领料查询》模块 处理送修车辆的配件问题,可以查询送修车辆领料和退料以及领料人资料,以便后期结算。
主要查询维修车辆需要的信息,然后在该页面进行“领料”和“退料”操作;新数据刚过来此页面时,都是显示“未领料”的状态,如下图:
然后领过料的就是“已领料”的状态,退过料的就是“已退料”的状态。如图显示:
在该页面中可以进行时间段的模糊查询,可以选择领料状况下拉框和输入车牌信息进行筛选。例如时间段查询效果如下(根据结算单日期查询,因为结算了才算是出厂时间):
文章目录 一、登陆系统(1)需用用户填写的登陆信息:(2)登陆操作进行了严格的判断:a:当用户没有输入任何信息就直接点击“登陆”进行登陆的时候,会根据输入框的顺序依次进行判断:b: 当用户开始输入信息点击“登陆”进行登陆的时候,会根据输入框的顺序再次进行判断: 二、主页面三、《预约安排》模块四、《客户接待》模块五、《维修派工》模块六、《维修领料查询》模块七、《维修领料》模块八、《维修退料》模块九、《完工确认》模块十、《结算出厂》模块十一:《快速修车》模块 项目名称:智百盛汽修管理系统 注:本项目只作为学习案例,仅供参考。 一、登陆系统 (1)需用用户填写的登陆信息: 1、账号2、密码3、验证码4、用户类型 (2)登陆操作进行了严格的判断: a:当用户没有输入任何信息就直接点击“登陆”进行登陆的时候,会根据输入框的顺序依次进行判断: 然后分别会给出如下提示:
1、用户名不能为空;2、密码不能为空;3、验证码不能为空;4、请选择用户类型! b: 当用户开始输入信息点击“登陆”进行登陆的时候,会根据输入框的顺序再次进行判断: 然后分别会给出如下提示:
1、判断用户是否正确;2、判断密码是否正确;3、判断验证码是否正确;4、判断用户类型是否正确。 假如输入的信息全部都是不正确的,便会根据判断进行提示:然后分别会给出如下提示:
1、用户不正确;2、密码不正确;3、验证码不正确;4、用户类型不正确。 只有输入的信息全部都正确才可以顺利进入“智百盛汽修汽配”管理系统。
登陆页面如下图显示:
二、主页面 登陆进入主页面后,主页面的截图如下:
1、主页面在右上角的地方设置显示当前登陆的用户名(不是登陆的账户号,而是用户名),登陆时间(获取当前登陆的系统时间)和登陆时长(设置session,自动计时,不需要刷新页面,登陆的时长也会自动增加)
2、点击左边导航栏《汽修管理》按钮,进入汽修管理模块,页面截图如下:
三、《预约安排》模块 预约安排主要是针对需要前来修车的客户的预约登记,录入车主、维修车辆基本信息(若已是老客户,可直接导入信息)及修理项目。
♦登记车牌、车型、车主信息,方便后期查询车主资料。
♦修理单号、修理类别、金额、开单日期和预约维修日期、接车人。
♦修理项目(明细)、估计配件、其他费用、备注、保险索赔:方便维修人员进行维修领料,以及修理时的注意事项,还有后期保险索赔的办理。
然后点击《预约安排》按钮或者图标,都可以进入预约安排的页面进行相关的操作,页面截图如下:
本页面可以操作的功能分别有“新增”,“删除”,“保存”,“打印”,“查询单据”,“转维修单”,“审核”,“反审核”,“退出”。
首先请看预约安排单页面中的内容:
预约单号:该单号是自动生成的(由大写字母BJ+年月日时分/yyMMdd HHmm+登陆的账户号+0001组成),然后根据每一天的日期来自增,每天首单都是自动从0001开始递增。
对应维修单号:是不能输入的,是用于回填的,它来源于单据转维修单后,也是自动生成的。
开单日期和预约维修日期都是绑定当前的系统时间,车牌文本框中的“Go!”按钮可以点击,然后进入车牌模态框,页面如下:
该模态框的数据是客户是信息,可以在此录入客户的基本信息,即新增客户的基本资料,新增完也可以回填修改(单击表格中的任意行,即可将数据回填到右边对应的文本框中),“请输入车牌号快速查找”是迷糊查询车牌的,可以输入完整的车牌号或者一个号码匹配相对应的数据车辆,方便操作者的操作;然后是“选中”按钮,该按钮是把表格的数据选中回填到主页面的,也相当于双击表格中的数据进行回填,这里既可以选择“选中”按钮进行操作,也可以双击表格进行回填,两个功能都可以实现;接着是“新增”按钮,该按钮并不是真正意义上是新增数据,而是当你单击表格中的任意行,即可将数据回填到右边对应的文本框中,将所有的文本框中的数据进行清空,说白了就是一个清空按钮;然后是“保存”按钮,该按钮可以进行两个操作,第一是新增数据到数据库,第二是修改数据。这里编码的时候要注意。接着是“刷新”操作,该操作是实现刷新页面的作用,这里忽略,最后是“关闭”按钮,点击就关闭模态框。
PS:右边表格中的客户编号也是利用自动生成编号的原理实现的效果,最右下角是“修改复选框”是用来勾选修改数据的,不勾选回填的数据不能进行修改,只有把复选框选中才可以对数据进行修改的操作。
现在我们单击一条数据进行回填,回填到页面的效果如下:
剩余的文本框和下拉框需要用户手动去输入和选择;
接下来下面是明细表格的操作:
1、修理项目明细表格中:可以利用鼠标右键选择“添加”和“删除”两个操作,添加是继续添加一行,删除是从最后一行进行删除;
添加行后只需选中修理项目下拉框就可以把其他的数据进行绑定,然后只要再选择维修性质下拉框就可以了,若是需要更改,表格也是可以编辑的,直接在表格修改即可。
2、产品材料明细表格中:可以利用鼠标右键选择“添加”和“删除”两个操作,添加弹出另一个产品模态框,供用户选择需要的产品材料,如下图,删除是从最后一行进行删除数据;
该产品模态框也可以进行多种商品类型的模糊查询,首选可以选择快速查找旁边是下拉框,选择对应是数据,然后再在下拉框旁边是文本框输入与下拉框匹配的信息进行筛选,也可以点击左边的货品分类目录,进行筛选对应是数据,筛选到需要的收据就可以勾选(多条)相对应是数据前面的复选框,然后点击“确定”按钮进行回填到产品材料明细表格中,如果找的数据不满足需求还可以点击“新增加”按钮进入另一个模态框,然后又可以在该模态框输入你想要的信息,也可以上传图片,如下图,再进行保存,数据新增成功后就会刷新出现在产品模态框中,然后可以重复上面是操作回填就可以了。
3、其他费用明细表格中:可以利用鼠标右键选择“添加”和“删除”两个操作,添加是继续添加一行,删除是从最后一行进行删除,添加行后只需选中费用名称下拉框就可以把其他的数据进行绑定,若是需要更改,表格也是可以编辑的,直接在表格修改即可。如图:
接着再看“查询单据”按钮的操作,查询单据是数据来源于刚才主页面保存后的数据,点击“查询单据”弹出单据模态框,如图:
在该模态框中可以进行预约单号模糊查询和审核状态下拉框匹配查询,然后可以双击表格回填数据到主页面(或者单击数据再点击“确定”按钮,也可以回填),回填后还可以在主页面进行“审核”和“反审核”操作;
审核后的数据不允许更改,如下图,
反审核后的数据可以再次修改,如下图。
四、《客户接待》模块 客户接待主要是对前来修车的客户及维修基本资料进行登记,把修理的明细录入,以便后期进行查询。
♦登记车牌、车型、进厂里程、油量、车主信息、发动机号码:方便后期查询车主资料。
♦修理编号、类别、金额、进厂日期和结算日期、送修人电话:方便管理人员管理,联系送修人在相应的时间来取车。
♦修理项目(明细)、估计配件、其他费用、备注、保险索赔:方便维修人员进行维修领料,以及修理时的注意事项,还有后期保险索赔的办理。
在主页面点击《客户接待》按钮或者图标,都可以进入客户接待的页面进行相关的操作,页面截图如下:
本页面同样也是登记维修客户的基本资料,然后录入各种明细,具体操作参考《预约安排》模块;
然后点击“查询单据”,弹出单据模态框。如图:
该模态框是记录保存进去的数据,双击数据可以进行数据回填,如图:
五、《维修派工》模块 在《客户接待》模块中点击“转派工单”可以将对应的数据绑定过来,也就是回填,这里以选择单据回填后的数据来说明,回填后直接点击“转派工单”就可以将《客户接待》页面的数据绑定过来了,如图:
在此页面还可以点击“派工”继续添加明细行,每次添加一行,也可以点击“删除”按钮进行删除。同样可以点击“查询单据”进入单据模态框,如图:
在该模态框中可以进行维修单号模糊查询、单据状态、付款下拉框和车牌匹配查询,然后可以双击表格回填数据到主页面。
六、《维修领料查询》模块 处理送修车辆的配件问题,可以查询送修车辆领料和退料以及领料人资料,以便后期结算。
主要查询维修车辆需要的信息,然后在该页面进行“领料”和“退料”操作;新数据刚过来此页面时,都是显示“未领料”的状态,如下图:
然后领过料的就是“已领料”的状态,退过料的就是“已退料”的状态。如图显示:
在该页面中可以进行时间段的模糊查询,可以选择领料状况下拉框和输入车牌信息进行筛选。例如时间段查询效果如下(根据结算单日期查询,因为结算了才算是出厂时间):
最近设计了一个项目基于单片机的家居环境监测设计,与大家分享一下: 一、基本介绍 项目名:基于单片机的家居环境监测(实物+仿真)的设计
项目编号:mcuclub-dz-081
单片机:STC89C52
功能简介:
1、通过震动传感器检测门是否被撬动,如果撬动,进行声光报警
2、通过分离式红外对射管检测是否有人翻越围墙,当检测到有人翻越围墙,进行声光报警
3、通过MQ-5检测可燃气体值,当可燃气体值大于设置最大值,进行声光报警
4、通过MQ-2检测烟雾值,当烟雾值大于设置最大值,进行声光报警
5、通过按键设置各阈值
6、通过LCD1602显示测量值
二、51实物图 单片机型号:STC89C52
板子为绿色PCB板,两层板,厚度1.2,上下覆铜接地。元器件基本上为插针式,个别降压芯片会使用贴片式。
供电接口:TYPE-C
三、51仿真图 仿真软件版本:proteus8.9
电路连线方式:网络标号连线方式
注意:部分实物元器件仿真中没有,仿真中会用其他工作原理相似的元件代替,这样可能导致实物程序和仿真程序不一样
四、原理图 软件版本:AD2013
电路连线方式:网络标号连线方式
注意:原理图只是画出了模块的引脚图,而并不是模块的内部结构原理图
五、PCB图 由原理图导出,封装很大一部分都是作者自己绘制,不提供封装库,只提供连接好的源文件。中间有一个项目编号,隐藏在单片机底座下,插入单片机后不会看到。
两层板,上下覆铜接地。
六、系统框图 本设计以单片机为核心控制器,加上其他模块一起组成此次设计智能家居环境监测的整个系统,其中包括中控部分、输入部分和输出部分。中控部分采用了单片机控制器,其主要作用是获取输入部分的数据,经过内部处理,逻辑判断,最终控制输出部分。输入由六部分组成,第一部分是烟雾检测模块,通过该模块检测当前环境的烟雾,通过模数转换芯片传入单片机中;第二部分是天然气检测模块,通过该模块检测当前环境的天然气浓度,通过模数转换芯片传入单片机中;第三部分是震动模块,通过该模块可以监测当前的门是否被撬动,如果发送撬动进行声光报警;第四部分是红外对射管模块,通过该模块监测是否有人翻墙;第五部分是按键模块,通过按键设置监测参数的阈值;第六部分是供电模块,通过该模块可给整个系统进行供电。输出由两个部分组成,第一部分是显示模块,通过该模块可以显示监测的数据以及设置的阈值;第二部分是声光报警模块,当监测值不在设置的阈值内或者监测到有人敲门或者翻墙时进行声光报警。具体系统框图如图3.1所示。
七、软件设计流程 八、部分程序展示 软件版本:keil5
逻辑程序和驱动程序分开,分布于main.c和其他.c文件
*******监测函数
*****/
void Monitor_function(void)
{
if(time_num % 10 == 0) //100ms检测一次
{
if(DO1 == 0)
smog_value = 50*((Adc0832_Get_Value(0)/255.0)*5); //获取烟雾浓度
else
smog_value = 0;
if(DO2 == 0)
fgas_value = 50*((Adc0832_Get_Value(1)/255.0)*5); //获取燃气浓度
else
fgas_value = 0;
}
}
1、背景 最近遇到一个时钟同步问题,是内网多台服务器之间时钟不同步,然后部署在不同服务器间的应用展示得时间戳不能统一,所以用户让做一下内网服务器间得时钟同步。
内网服务器x86和arm都有,而且有得系统是centos有得是ubuntu,一开始是想用ntp、chrony这类得时钟同步工具,但是安装时才发现底层缺少各种依赖库。依赖库问题解决太痛苦了,所以就放弃了ntp、chrony这类需要安装得时钟同步工具,准备自己写一个时钟同步脚本。
2、思路 通过date命令可以设置服务器得时钟时间,只要所有机器定时从一台主服务获取时间并同步到自己服务器就可以做到假时钟同步得效果,这里之所以叫假时钟同步,是因为date命令只能设置到秒级别。
3、实现前得准备(免密登录) 因为要远程登录获取主服务器得时钟时间,所以要在从服务器生成密钥并发送到主服务。
生成密钥:ssh-keygen 分发密钥:ssh-copy-id node1 在客户端生成,都推送一份到要免密登录的服务器 4、编辑脚本 #!/bin/bash echo "$(date)" >> /opt/timer/test date -s "$(ssh node1 'date "+%Y-%m-%d %H:%M:%S"')" 5、设置定时同步任务 执行如下命令进入编辑页面
crontab -e
在编辑页面添加如下定时任务(注意time_update.sh是上一步编辑得脚本,路径根据自己情况修改) * * * * * /opt/timer/time_update.sh
部署真的hbase好累啊,留一份记录,等再崩溃了可以参考,也希望可以为像我一样崩溃的同学提供一份帮助
hadoop的安装参考问题4,我基本相当于重装了hadoop,在保留ssh等前置的条件下
首先按照教程,安装zookeeper和hbase
这里java版本使用8,使用apt下载openjdk
hbase-2.5.6,hadoop-3.3.6,zookeeper-3.8.3
注意hbase和zookeeper使用bin的
zookeeper下载地址 到2023年11月9日为止,最新的LTS是3.8.3
hbase下载地址 到2023年11月9日为止,最新的LTS是2.5.6
问题1 Error: JAVA_HOME is not set
解法:在hbase/conf/hbase-env.sh里添加. /etc/profile
即使用. /etc/profile的JAVA_HOME
~/.bashrc
在这个文件夹里写
export JAVA_HOME=你的JAVA地址
也是方法,但如果未来要修改JAVA地址,就很麻烦了
问题2 无法进入16010
且jps无Hmaster
解法
问题3 成功进入node1:16010,但显示
Failed to become active master due to:Call From node1/192.168.189.128 to node1:8020 failed on connection exception: java.net.ConnectException: 拒绝连接; For more details see: ConnectionRefused - HADOOP2 - Apache Software Foundation (since 2sec ago)
然后发现telnet node1 8020
显示telnet: Unable to connect to remote host: Connection refused
文章目录 1 问题背景2 前言3 多处重复的重试机制代码4 优化后的代码5 进一步优化 1 问题背景 在电商场景中,会调用很多第三方的云服务,比如发送邮件、发起支付、发送验证码等等。由于网络存在抖动,有时候发起调用后会拿到500的状态码,io exception等报错,因此需要重新调用,简称重试机制。项目中很多地方用到重试机制,导致很多重复的代码,因此笔者考虑使用Java8函数式接口优化该重试机制,抽成一个工具类方法。
2 前言 本文的代码中,可能有些类型没有给出代码,不需要纠结,主要了解函数式接口怎么应用即可 3 多处重复的重试机制代码 项目中多次出现的代码如下:
BasicResponse<String> response = null; int retryTimes = 0; do { try { String startTimeStr = DATE_TIME_FORMATTER.format(LocalDateTime.now()); response = restTemplate.postForString(basicRequest); // 此行代码是可变的,可能是get方式请求,可能是post方式 String endTimeStr = DATE_TIME_FORMATTER.format(LocalDateTime.now()); PayReq logObject = PayReq.getLogObject(payReq); log.info("XXXPay payOrder, request:{}, response:{}, startTimeStr:{}, endTimeStr:{}, retryTimes:{}", JSON.toJSONString(logObject), JSON.toJSONString(response), startTimeStr, endTimeStr, retryTimes); } finally { if (response != null && !response.getCode().equals(HttpStatus.SC_OK)) { try { Thread.
1、创建新项目(项目名与文件目录最好一致用英文);
创建新项目前要先打开CC的engine,
engine的项目目录与新建的项目储存目录要一致,然后打开master,创建一个新项目;
2、添加block(也可以在创建新项目时勾选创建新block);
点击项目名旁边的加号,添加new block;或右击项目名,在选项卡new capture中找到new block;
3、添加照片
添加了block之后,右击Block_1,点击add photos添加照片;
4、空三;
照片添加完成后,submit aerotriangulation进行空三测量;
也可以右击Block_1提交空三;
直接进行空三测量,设置默认,完成后可在3D View页面看到空三结果;
注意:在运行master的同时,engine要保持打开,否则会无法进行空三处理;
5、建模;
在建模之前,可以在圈出的两个页面中修改模型的范围;
在Reference Model中,可以通过touchup选中多余的部分直接删改;
在Spatial Framework中,可以通过移动box的框架切割出需要的矩形区域;
也可以使用polygon功能直接自定义需要的区域,切割完成后点击accept;
如果需要处理的区域过大,可以通过切块进行处理,块的大小应与区域大小及使用的电脑性能有关,
修改范围后就可以开始建模了;
选择QSGB格式;
选择EPSG:4547坐标系;
提交建模;
最后的结果可用其他软件观看;
目录 前言解决办法 前言 在使用easypoi map的方式解析excel文件,若文件中的某列数据格式是日期类型,那么它这个工具是读取不到,因为它的源码读取到某列为日期格式,数据必须为字符串类型,它才会处理
switch (cell.getCellType()) { case STRING: result = cell.getRichStringCellValue() == null ? "" : cell.getRichStringCellValue().getString(); break; case NUMERIC: if (DateUtil.isCellDateFormatted(cell)) { if ("class java.lang.String".equals(classFullName)) { result = formateDate(entity, cell.getDateCellValue()); } } else { result = readNumericCell(cell); } break; case BOOLEAN: result = Boolean.toString(cell.getBooleanCellValue()); break; case BLANK: break; case ERROR: break; case FORMULA: try { result = readNumericCell(cell); } catch (Exception e1) { try { result = cell.
目录 1.前言2.代码2-1 子页面2-2 主页面 1.前言 需求:当我在子页面定义了一个定时器,点击获取验证码,计时器开始倒计时,在这个定时器没有走完,退出关闭子页面,再次进入子页面,定时器此时会被刷新,但是我的需求是,再次进去子页面时,只要上次的计时器没有走完,就继续走,那么,这时候就可以通过暴露属性事件,去触发主页面的事件
具体思路:在主页面定义也定义一个处理的定时器的事件,当在子页面点击获取验证码,开始倒计时,同时调用这个暴露的事件,
那么,这时,主页面就会触发定时器事件,然后将这个倒计时的数据提取出来(当然肯定有其他的方法去处理,但是我不太会前端,只有想到这种方式,还望大佬指点)
2.代码 2-1 子页面 2.1.1 定义属性,将其暴露出来
props: { withdrawals: { type: Object, default() { return {} }, }, withdrawalWaitTime:{ type: Number, default: 0 }, handWithdrawalWaitTime:{ type: Function, default: null }, closeWithdrawals: { type: Function, default: null } } 2.1.2 在钩子函数里定义一个处理每次的计时,每次从主页面过来时,都会携带一个计时参数 withdrawalWaitTime,根据这个值进行一个具体多久的倒计时
async mounted() { await this.fetchData() this.handMobile() this.handWithdrawalWaitTime2() }, methods: { handWithdrawalWaitTime2(){ this.isWithdrawalsVerify = true this.coolDownTime = this.withdrawalWaitTime this.interval = setInterval(() => { this.
CorelDRAW 2024中文版是一款由世界顶尖软件公司之一加拿大的Corel公司开发的图形图像软件;CorelDRAW 支持logo设计、网络图片、标志设计。全新的学习指导工具,提供一站式的图片修改功能,附带功能强劲的点阵图向矢量图转化的工具,提供超过10000种的剪贴画供您轻松调用;CorelDRAW还融合了绘画与插图、文本操作、绘图编辑、桌面出版及版面设计、追踪、文件转换、高品质输出于一体的矢量图绘制软件,并且在工业设计、产品包装造型设计,网页制作、建筑施工与效果图绘制等设计领域中得到了极为广泛的应用。
设计软件市场中,CorelDRAW和Adobe Illustrator(简称AI)无疑是两大重量级选手。它们各自拥有庞大的用户群和丰富的功能,但究竟哪一个更好用?本文将从多个角度出发,对这两款软件进行全面而深入的比较,以助你做出更明智的选择。
CorelDraw win-安装包:https://souurl.cn/rVgCFH
CorelDraw mac-安装包:https://souurl.cn/wACzg6
CorelDRAW和AI哪个好用
一、CorelDRAW和AI的基础功能比较
1. 界面与操作性
CorelDRAW以其友好和直观的界面受到许多用户的青睐,特别是对于初学者来说,找到各种工具和选项相对更为简单。相比之下,AI的界面虽然也很专业,但由于功能更加强大,相应地界面也更加复杂。
CorelDRAW界面
2. 绘图工具
AI以其强大的绘图工具而著名,尤其是在路径编辑、图层管理以及矢量图设计方面。CorelDRAW虽然在这些方面也有不错的表现,但相对而言,还是稍逊一筹。
3. 格式支持
CorelDRAW的一个优点是能支持多种文件格式,包括一些较老的格式,这在某些特定场合下会非常有用。AI则更注重与Adobe系列软件的兼容性。
二、CorelDRAW和AI的高级功能对比
1. 版本稳定性
多年的软件开发经验使得CorelDRAW在版本稳定性上有着出色的表现。用户反馈的问题和BUG能得到快速的响应和修复。AI在稳定性上面尚待优化,使用过程中要多注意保存。
2.图层管理
CorelDRAW提供非常直观和灵活的图层管理功能。您可以轻松地创建、隐藏、锁定或重新排序图层,这对于复杂项目的管理至关重要。
虽然AI也具备强大的图层管理功能,但与CorelDRAW相比,其界面更为复杂,新手可能需要更多时间去适应。
CorelDRAW
3.文本编辑和排版功能
CorelDRAW在文本编辑和排版方面表现得非常出色。它不仅提供了丰富的字体和样式选项,还支持复杂的文本路径和变形,极大地提高了文本设计的灵活性。
AI虽然也在这方面具有高度的专业性,但其文本编辑和排版选项相对较少,对于一些高级的排版需求可能无法完全满足。
4.兼容性和扩展性
CorelDRAW能够兼容多种文件格式,并且支持各种插件和扩展工具。这使得设计师能够灵活地与其他软件和平台进行交互。
AI虽然也支持多种格式,但更多地是优化了与Adobe其他软件的兼容性,对于非Adobe产品的支持相对较弱。
三、CorelDRAW和AI的应用场景
1. 平面设计
在平面设计方面,两者都有出色的表现。然而,由于CorelDRAW更加强大和专业,因此在高级和复杂的设计项目中,CorelDRAW可能是更好的选择。
平面设计
2. 印刷与出版
CorelDRAW长期以来都是印刷和出版行业的重要工具,特别是在名片、宣传单和标志设计等方面。而AI由于其出色的色彩管理和高分辨率输出能力,也经常被用于出版物设计。
3. 网络与多媒体
AI因其与Adobe全家桶的无缝集成,更适合用于网络和多媒体设计。无论是UI设计,还是动画和视频编辑,AI都有着更广泛的应用。
综合以上各方面,CorelDRAW和AI各有优缺点,选择哪一个更好用实际上取决于你具体的需求和应用场景。如果你是一个初学者或者需要处理多种文件格式,CorelDRAW可能更适合你。而如果你追求更高级的设计功能和更广泛的应用范围,那么AI无疑是更好的选择。
摘要 在安全层面要求比较高的地方的服务器一般不支持联网,因此即便你的系统安装的apt、yum等命令也不能用于下载一些需要联网的工具或软件包,因此在这儿我要说的是手动安装telnet工具,按照如下步骤:亲测可用。
操作步骤 1.首先我们需要知道目前我们操作系统是什么?
uname -a 还有就是一般在Linux的/etc目录下找到文件名有release的文件,就能知道你的系统基本信息了。
2.检查当前服务器能够使用的命令,比如:yum、apt、rpm、dpkg命令
由于当前服务器是在没网的情况下,因此,yum和apt命令不能用于安装,我们就看是否能够使用rpm和dpkg的命令。rpm --version和dpkg --version 如下图所示:能够使用dpkg命令,而不能使用rpm命令。
3.下载关于telnet的安装文件
由于系统原因,所以我们在选择安装包的时候只能选择.deb文件的安装包,如果是能够使用rpm命令的话也可以下载.rpm文件。
小编在此已经给大家准备好了arm64.server的telnet安装包.deb文件
百度网盘链接:https://pan.baidu.com/s/1qpQ1KPDt7GlECc5LTpNjLA
提取码:aoh7
4.上传到服务器(任意位置)
5.切换到你上传的目录下(cd /你存放telnet的目录)
6.使用dpkg执行安装命令
sudo dpkg -i telnet_0717.deb 安装好之后,稍等一下,它会自动生效。
7.验证
telnet ip 端口 使用telnet 远程你想要连接的服务器。
kube-proxy 10249:用于节点上的kubeproxy的健康检查和状态查询。
10256:用于NodePort服务的负载均衡。
portpool(30000-32767):NodePort服务的端口范围,这些端口用于外部流量访问Kubernetes集群中的服务。
kubelet 10250:kubelet API服务器的端口,用于集群中的其他组件(如kube-scheduler、kube-controller-manager、kubectl)与kubelet进行通信。此端口通常由Kubernetes的授权策略进行保护,只允许授权用户或组访问。
10255:kubelet的只读端口,用于提供节点的健康状况以及容器运行时信息的监控数据。
10248:kubelet的非安全端口,用于提供节点的健康状况以及容器运行时信息的监控数据。此端口不受Kubernetes的授权策略保护。
36888:kubelet启动时随机分配的端口,用于处理容器日志收集器fluentd的日志转发请求。
kube-schedule 10251:kube-scheduler和kube-apiserver组件之间的通信端口,用于接收来自kube-apiserver的调度请求,并将调度结果返回给kube-apiserver。
10259:kube-scheduler和kubectl之间的通信端口,用于获取当前的集群调度状态,并进行一些操作,如手动重新调度Pod等。
kube-controller 10252:kube-controller-manager和kube-apiserver之间的通信端口,用于接收kube-apiserver发送的请求,包括同步cluster state、管理Pod副本数、节点状态等。
10257:用于提供/metrics和/healthz等信息,包括kube-controller-manager的运行状态、性能指标等。
kube-apiserver 6443:通过该端口可以访问Kubernetes API服务器的RESTful API,从而实现对Kubernetes集群的管理和控制。通过kube-apiserver,可以进行集群的配置、资源调度、容器编排、应用部署等操作。
etcd 2379:etcd客户端和etcd节点进行数据读写的端口
2380:etcd集群内部节点之间进行同步的端口
2381:用于监控etcd性能指标的URL列表。
用了下宝塔是真的比较爽,这里介绍下安装
1.linux安装宝塔 linux服务器直接安装输入就好
yum install -y wget && wget -O install.sh https://download.bt.cn/install/install_6.0.sh && sh install.sh ed8484bec 1.1安全操作 尽量把多余的端口都关闭,只暴露一个80端口,首先要做的就是把宝塔面板的地址进行映射。这里有个大坑映射内网地址的时候用宝塔一开始安装提供的内网地址,别再用外网的。
server { listen 80; server_name {你的IP地址}; #SSL-START SSL相关配置 #error_page 404/404.html; ssl_certificate {pem文件绝对路径}; ssl_certificate_key {key文件绝对路径}; ssl_session_timeout 5m; #请按照以下协议配置 ssl_protocols TLSv1.2 TLSv1.3; #请按照以下套件配置,配置加密套件,写法遵循 openssl 标准。 ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; ssl_prefer_server_ciphers on; #SSL-END # 端口转发(来个超复杂只有你知道的id保证安全) location /{来个uuid} { proxy_pass {宝塔提供的内网地址}; } } 2.部署项目 2.1安装套件 这里直接访问,套件的话直接就安装,我ftp没用所以这个没装。
2.2添加项目 找到网站,选择java项目添加站点,没有安装的会弹出tomcat我这里用8,jar和war都可以
这里就是你直接选中你的项目,他就把端口,执行命令这种都给你配好了,非常丝滑,你就改改端口号就可以,然后直接启动。
2.3端口转发 这个一般是建议做下,就是你项目启动在8080端口,然后转发到8088类似这种,隐藏内部真正的端口号,这是基于nginx实现的。
开启外网映射,然后点击配置文件,我这里还配置了域名加了个server_name(记得多解析个二级域名,这里碰到一个坑解析只要输入二级域名的名字,比如你申请的是www.test.com,只要解析个demo就好,但是别输入demo.test.com),映射到了80端口。
2.4打开安全组规则 增加了宝塔后他会开防火墙,云服务不仅得开,宝塔上也得开好像有点麻烦了。平时直接防火墙关掉,但是比较危险,各有利弊。
4.映射项目域名 首先你得有域名,拿到域名记住第一件事情就是去认证,个人的就比较简单,然后如果是企业认证注意经营许可证上最好不要有这些内容:出版类(互联网出版许可证)、食品经营(食品经营许可证)、游戏类、文化类、广播电视电影节目类的。上面那些都需要前置审批,得办点别的许可证。
我总结了几个步骤:
Spring IoC& DI 1. IoC2. IoC & DI 使⽤2.1 Bean的存储2.1 DI 注入 @Autowired 3. 练习代码自取 1. IoC Spring 是包含了众多⼯具⽅法的 IoC 容器 IoC: Inversion of Control (控制反转), 也就是说 Spring 是⼀个"控制反转"的容器。
什么是控制反转呢? 也就是控制权反转; 什么的控制权发生了反转? 获取依赖对象的过程被反转了也就是说, 当需要某个对象时, 传统开发模式中需要自己通过 new 创建对象, 现在不需要再进行创建, 把创建对象的任务交给容器, 程序中需要依赖注入 (Dependency Injection, DI) 就可以了这个容器称为; IoC 容器, Spring 是一个IoC 容器, 所以有时Spring也称为 Spring 容器 DI 介绍
IoC 是⼀种思想,也是"⽬标", ⽽思想只是⼀种指导原则,最终还是要有可⾏的落地⽅案,⽽ DI 就属于具体的实现。所以也可以说, DI 是IoC的⼀种实现.
2. IoC & DI 使⽤ Spring 把存储在容器中的对象称为 bean
Spring Web MVC 1. 什么是 Spring Web MVC1.1 什么是 MVC ?1.2 是什么 Spring MVC? 2. 学习 Spring MVC2.1 建立连接2.2 请求2.3 响应 3. 相关代码链接 1. 什么是 Spring Web MVC 官⽅对于 Spring MVC 的描述是这样的:
1.1 什么是 MVC ? MVC 是 Model View Controller 的缩写它是软件⼯程中的⼀种软件架构设计模式,它把软件系统分为模型、视图和控制器三个基本部分 View(视图) 指在应用程序中专门用来与浏览器进行交互, 展示数据的资源Model(模型) 是应用程序的主体部分, 用来处理程序中数据逻辑的部分Controller(控制器) 可以理解为一个分发器, 用来决定对于视图发来的请求, 需要用哪一个模型来处理, 以及处理完成后需要跳到哪一个视图; 即用来连接视图和模型 1.2 是什么 Spring MVC? MVC 是⼀种架构设计模式, 也⼀种思想, ⽽ Spring MVC 是对 MVC 思想的具体实现.
SpringMVC还是⼀个Web框架.
总结来说,Spring MVC 是⼀个实现了 MVC 模式的 Web 框架.
访问后端接口地址配置项ip多了一个1xxx.xx.xx.xx:999
问题: 启动项目的时候,报错了
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'apiModelSpecificationReader' defined in URL [jar:file:/D:/.gradle/caches/modules-2/files-2.1/io.springfox/springfox-spring-web/3.0.0/a76f2fbe805bfd2798e20dc8f2cfbfad554d52da/springfox-spring-web-3.0.0.jar!/springfox/documentation/spring/web/scanners/ApiModelSpecificationReader.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'springfox.documentation.schema.ModelSpecificationProvider' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Qualifier(value=cachedModels)} 检查了下swagger的版本,用的是:
implementation("io.swagger:swagger-annotations:1.5.20") implementation("io.springfox:springfox-swagger2:2.9.2") implementation("io.springfox:springfox-swagger-ui:2.9.2") implementation("io.springfox:springfox-swagger-common:2.9.2") 提示却是3.0.0
[jar:file:/D:/.gradle/caches/modules-2/files-2.1/ io.springfox/springfox-spring-web/3.0.0 复制了下路径,检查了下,确实是如此。
原来是新的项目swagger用的是3.0.0,用的是一样的路径,导致影响。 处理1: 把springfox-spring-web目录下的3.0.0目录删了,再启动,是正常的。
但这样的话,有弄先的项目,又会出问题。
处理2: 在build.grale文件里面添加: exclude group: 'io.springfox', module: 'springfox-boot-starter'
configurations { developmentOnly runtimeClasspath { extendsFrom developmentOnly } all { exclude group: 'org.
文章目录 MYSQL单表数据达2000万性能严重下降?前言InnoDB索引数据结构B+树 Sharding Sphere分库分表Sharding-JDBCSharding-JDBC的相关概念说明逻辑表广播表绑定表 Sharding-JDBC中的分片策略自动分片算法取模分片算法哈希取模分片算法分片容量范围标准分片算法行表达式分片算法时间范围分片算法 MySQL主从机制原理前言主从复制原理基本原理主从延迟原因随机重放主库并发高锁等待 主从延迟处理并行复制降低主库并发读主库 总结主从复制原理主从延迟原因主从延迟处理 MySQL三种同步模式优劣异步复制半同步复制全同步复制 MYSQL单表数据达2000万性能严重下降? 前言 在中国互联网技术圈流传着这么一个说法:MySQL 单表数据量大于 2000 万行,性能会明显下降。事实上,这个传闻据说最早起源于百度。具体情况大概是这样的,当年的 DBA 测试 MySQL性能时发现,当单表的量在 2000 万行量级的时候,SQL 操作的性能急剧下降,因此,结论由此而来。然后又据说百度的工程师流动到业界的其它公司,随之也带去了这个信息,所以,就在业界流传开这么一个说法。
再后来,阿里巴巴《Java 开发手册》提出单表行数超过 500 万行或者单表容量超过 2GB,才推荐进行分库分表。对此,有阿里的黄金铁律支撑,所以,很多人设计大数据存储时,多会以此为标准,进行分表操作。
那这个说法到底有没有理论依据的支撑呢,首先这个性能问题可以说有很多因素组成,比如说硬件以及MYSQL本身的参数设置等等。那今天我们可以从MySQL的索引结构来说说这件事。
InnoDB索引数据结构 一个问题?
**InnoDB一棵B+树可以存放多少行数据?这个问题的简单回答是:约2千万。**为什么是这么多呢?因为这是可以算出来的,要搞清楚这个问题,我们先从InnoDB索引数据结构、数据组织方式说起。
我们都知道计算机在存储数据的时候,有最小存储单元,这就好比我们今天进行现金的流通最小单位是一毛。在计算机中磁盘存储数据最小单元是扇区,一个扇区的大小是512字节
而文件系统(例如XFS/EXT4)他的最小单元是块,一个块的大小是4k
而对于我们的InnoDB存储引擎也有自己的最小储存单元——页(Page),一个页的大小是16K。
文件系统中一个文件大小只有1个字节,但不得不占磁盘上4KB的空间。
innodb的所有数据文件(后缀为ibd的文件),他的大小始终都是16384(16k)的整数倍。
数据表中的数据都是存储在页中的,所以一个页中能存储多少行数据呢?
假设一行数据的大小是1k,那么一个页可以存放16行这样的数据。
如果数据库只按这样的方式存储,那么如何查找数据就成为一个问题,因为我们不知道要查找的数据存在哪个页中,也不可能把所有的页遍历一遍,那样太慢了。所以人们想了一个办法,用B+树的方式组织这些数据。如图所示:
我们先将数据记录按主键进行排序,分别存放在不同的页中(为了便于理解我们这里一个页中只存放3条记录,实际情况可以存放很多),除了存放数据的页以外,还有存放键值+指针的页,如图中page number=3的页,该页存放键值和指向数据页的指针,这样的页由N个键值+指针组成。当然它也是排好序的。这样的数据组织形式,我们称为索引组织表。现在来看下,要查找一条数据,怎么查?
如select * from user where id=5;
这里id是主键,我们通过这棵B+树来查找
首先找到根页,你怎么知道user表的根页在哪呢?其实每张表的根页位置在表空间文件中是固定的,即page number=3的页(这点我们下文还会进一步证明),找到根页后通过二分查找法,定位到id=5的数据应该在指针P5指向的页中,那么进一步去page number=5的页中查找,同样通过二分查询法即可找到id=5的记录:
| 5 | zhao2 | 27 | 现在我们清楚了InnoDB中主键索引B+树是如何组织数据、查询数据的,我们总结一下:
1、InnoDB存储引擎的最小存储单元是页,页可以用于存放数据也可以用于存放键值+指针,在B+树中叶子节点存放数据,非叶子节点存放键值+指针。
2、索引组织表通过非叶子节点的二分查找法以及指针确定数据在哪个页中,进而在去数据页中查找到需要的数据;
B+树 那么回到我们开始的问题,通常一棵B+树可以存放多少行数据?
这里我们先假设B+树高为2,即存在一个根节点和若干个叶子节点,那么这棵B+树的存放总记录数为:
根节点指针数*单个叶子节点记录行数
上文我们已经说明单个叶子节点(页)中的记录数=16K/1K=16。(这里假设一行记录的数据大小为1k,实际上现在很多互联网业务数据记录大小通常就是1K左右)。
那么现在我们需要计算出非叶子节点能存放多少指针?
其实这也很好算,我们假设主键ID为bigint类型,长度为8字节,而指针大小在InnoDB源码中设置为6字节,这样一共14字节,我们一个页中能存放多少这样的单元,其实就代表有多少指针,16K是页最小的占用磁盘单元,即(16*1024)/14=1170 。
那么可以算出一棵高度为2的B+树,能存放1170*16=18720 条这样的数据记录。
迁移 WSL2 安装位置 WSL2 默认安装在 C 盘,我们可以通过以下步骤迁移安装位置
通过以下命令列出已安装的 Linux 发行版:
wsl -l -v 可以看到已安装了 Ubuntu-22.04,其运行状态为:Stopped
如果运行状态为 Running,需先通过以下命令关闭:
wsl --shutdown 然后我们通过以下命令将 Ubuntu-22.04 导出为 tar 文件:
wsl --export Ubuntu-22.04 e:\Ubuntu-22.04.tar 注: wsl --export <Distribution Name> <FileName> <Distribution Name> 为目标 Linux 发行版的名称,我安装的为: Ubuntu-22.04 <FileName> 为导出的文件名,这里我导出到 e:\Ubuntu-22.04.tar 导出成功后,可以在导出的路径下看到导出的 tar 文件:
然后注销并卸载 Ubuntu-22.04
wsl --unregister Ubuntu-22.04 再次查看已安装的 Linux 发行版:
wsl -l -v 可以看到 Ubuntu-22.04 已经注销并卸载了
然后将 Ubuntu-22.04 导入到新位置:
wsl --import Ubuntu-22.04 E:\ubuntu2204 E:\Ubuntu-22.04.tar 注:wsl --import <Distribution Name> <InstallLocation> <FileName> <Distribution Name> 为目标 Linux 发行版的名称,我安装的为: Ubuntu-22.
安装 npm install --save qrcode.vue or yarn add qrcode.vue 组件中使用 <script setup lang="ts"> import { useUiSetStore } from '@store/modules/uiSettings' //导入二维码组件 import QrcodeVue from 'qrcode.vue' const ui = useUiSetStore() const payUrl = ref('') </script> <template> <footer-modal :visible="ui.fToolsQR"> <div> <input v-model="payUrl" type="text" class="w-150" placeholder="输入要生成的数据" /> </div> <div class="m-auto my-2 w-14"></div> <div class="m-auto my-2 w-14">二维码</div> <div v-if="payUrl === ''" class="m-a h-50 w-50"></div> <div v-else class="m-a h-50 w-50"> //组件中使用 <qrcode-vue :value="payUrl" :size="200" level="H" /> </div> </footer-modal> </template> 全局注册使用 //main.
需求:安装一个MySQL,且启动
如果是虚拟机部署形式的话如下
1.开启vmware
2.运行某一个虚拟机,centos7
3.centos7安装MySQL,yum install mysql-server
4.通过脚本,或者命令,启动MySQL即可
缺点:部署慢,且修改了宿主机的环境,删除较为麻烦,占用宿主机的一个3306端口
基于容器去运行MySQL
1.开始VMware
2.运行虚拟机centos7
3.安装docker容器环境
4.获取MySQL镜像即可,docker pull mysql:tag(你无法自由控制,该MySQL的基础镜像是什么发行版,你获取的镜像,是别人定制好,你下载使用你希望得到一个基于centos7.8d的发行版本,运行MySQL)
5。直接运行该镜像,通过端口映射,运行MySQLdocker runmysql:5.6(容器能够运行,必须在容器内有一个进程在前台运行,该容器内,有Mysql正在前台运行)
6.访问宿主机的一个映射端口,访问到容器内的MySQL
dockerfile指令 FROM ----这个镜像的妈妈是谁?(指定基础镜像)
MAINTAINER ----告诉别人,谁负责养它? (指定维护者信息,可以没有)
RUN -----你想让它干啥 (在命令前面加上RUN即可)
ADD---- 添加宿主机的文件到容器内 ,还多了一个自动解压的功能
RUN tar -zxf /opt/xx.tgz #报错!该 tgz 文件不存在!!
COPY --- 作用和ADD是一样的,主要是拷贝宿主机的文件到容器内,COPY就是仅仅拷贝
WORKDIR---- 我是cd,今天刚化了妆 (设置当前工作目录)
VOLUME----给它一个存放行李的地方 (设置卷,挂载主机目录)
EXPOSE----它要打开的门是啥 (指定对外的端口)
CMD---- 奔跑吧,兄弟!(指定容器启动后的要千的事情)dockerfile其他指令:
COPY ----复制文件
ENV----环境变量
ENTRYPOINT -----容器启动后执行的命令
docker run 等于创建+启动
docker run 镜像名,如果镜像不存在本地,则会在线去下载该镜像
注意:容器内进程必须处于前台运行状态,否则容器就会直接退出
如果容器内,什么事也没做,容器也会挂掉
我们运行nginx基础镜像,没有运行任何程序,因此容器之间挂掉
#运行容器的玩法 #1.运行一个挂掉的容器(从错误示范来学docker容器) docker run centos:7.8.2003 这个写法,会产生多条独立的容器记录,且容器内没有程序 #2.运行容器,且进入容器内,且在容器内执行某个命令 [root@master ~]# docker run -it centos:7.8.2003 sh sh-4.2# sh-4.2# 3。开启一个容器,让它帮你运行某个程序,前台运行,会卡住一个终端 [root@master ~]# docker run -it centos:7.8.2003 ping baidu.com PING baidu.com (110.242.68.66) 56(84) bytes of data. 64 bytes from 110.242.68.66 (110.242.68.66): icmp_seq=1 ttl=127 time=31.5 ms 64 bytes from 110.242.68.66 (110.242.68.66): icmp_seq=2 ttl=127 time=31.6 ms 4.运行一个或者的容器,docker ps 可以看到容器 -d 参数 ,让容器在后台跑着(针对宿主机而言) 返回容器id [root@master ~]# docker run -d centos:7.
随着物联网(IoT)技术的快速发展,越来越多的企业开始将其生产设备与物联网系统连接起来,以实现更高效、更智能的生产方式。在这个过程中,工业网关扮演着至关重要的角色。
工业网关是一种专门用于连接工业生产设备与物联网系统的设备,它能够实现数据的采集、传输、处理和应用。通过工业网关,企业可以轻松地将其生产设备与云平台、工业互联网等物联网系统连接起来,从而实现对生产过程的实时监控、数据分析和优化。
一、数据采集与传输
工业网关具备强大的数据采集和传输能力,可以实时收集来自生产设备的数据,包括设备运行状态、生产产量、能耗等。这些数据可以通过工业网关进行初步的处理和分析,然后传输到云平台或工业互联网等物联网系统中,以实现更高效的数据管理和应用。
二、数据处理与应用
工业网关不仅能够采集和传输数据,还能够对数据进行处理和应用。通过对数据的分析,企业可以及时发现生产过程中的问题和瓶颈,从而采取相应的措施进行改进。此外,工业网关还可以将数据应用于预测性维护、质量检测、生产计划等各个方面,以实现更高效、更智能的生产方式。
三、安全性与可靠性
工业网关具备可靠的安全性和稳定性,能够确保数据的传输安全和隐私保护。它采用了多种安全技术,包括数据加密、身份验证、访问控制等,以防止数据泄露和非法访问。此外,工业网关还具有故障自诊断和恢复功能,能够在出现故障时自动切换到备份设备或重新启动,以确保生产的连续性和稳定性。
四、可扩展性与灵活性
工业网关具有可扩展性和灵活性,能够适应不同的生产设备和物联网系统。它可以通过不同的接口和协议与各种生产设备进行连接,同时还可以支持多种物联网系统和平台,如阿里云、华为云、西门子等。这使得企业可以根据自己的需求选择合适的工业网关,并将其与现有的生产设备和系统进行集成。
五、降低成本和提高效率
通过工业网关将企业生产设备接入物联网系统,企业可以降低成本和提高效率。首先,工业网关的使用可以减少人工干预和错误率,从而提高生产质量和效率。其次,通过对数据的分析和应用,企业可以优化生产流程和资源配置,降低能耗和减少浪费。最后,工业网关还可以为企业提供预测性维护和远程故障排除等功能,从而减少维修时间和成本。
六、产品推荐
TDE边缘端带智能边缘计算的数据采集网关, 可以方便地实现现场设备的远程数据采集、程序远程下载和远程维护。支持300+的工业设备驱动协议,2 路 RJ45 以太网和最多 5 路串口通讯接口, 可满足绝大部分工业控制器设备的联网需求。 同时支持以太网宽带、4G/5G、Wifi 上网方式。可通过数网星工业云平台实现远程配置、诊断和管理等功能。 工业网关是连接企业生产设备和物联网系统的关键设备。通过工业网关的应用,企业可以提高生产效率、降低成本、增强安全性可靠性以及适应市场变化等方面具有重要意义。因此,对于想要实现智能制造和数字化转型的企业来说,选择合适的工业网关是至关重要的。
亲爱的CSDN用户和读者们,
我们怀着无比激动的心情,迎来了CSDN的两周年创造纪念日!在这特殊的日子里,我们想与你们一起庆祝这个里程碑,回顾过去两年的成就和成长。
回想起两年前的那一天,我们迈出了这个激动人心的创业旅程。从那时起,我们立志成为最受欢迎的技术社区,为广大开发者和技术爱好者提供一个共享知识、交流经验的平台。如今,我们自豪地说,我们已经成为了一个庞大而充满活力的社区,汇聚了来自世界各地的聪明才智和热情洋溢的技术人员。
在过去的两年里,我们见证了CSDN社区的迅速发展和壮大。我们拥有了数以百万计的注册用户,数以千计的优质技术博文和教程,以及丰富多样的在线技术活动和研讨会。我们与众多知名技术专家和企业建立了紧密的合作关系,为用户提供更多精彩的内容和机会。我们的社区成员通过分享自己的知识和经验,为其他人提供了无尽的学习和成长机会。
CSDN的两周年纪念日是我们的共同成就,没有你们的支持和参与,我们无法取得如此令人瞩目的成就。感谢每一位用户和读者,感谢你们的贡献和信任,让CSDN成为了一个充满活力和创新的技术社区。我们将继续努力,不断提升平台的质量和服务,为你们提供更多有价值的内容和资源。
让我们共同庆祝CSDN的两周年,展望未来的发展。我们相信,未来的日子里,CSDN将继续成为你们学习、交流和探索技术世界的最佳伙伴。让我们携手并肩,共同创造更加美好的未来!
再次感谢你们对CSDN的支持和厚爱!
祝愿自己CSDN两周年纪念日快乐!
1. 前言 限于作者能力水平,本文可能存在谬误,因此而给读者带来的损失,作者不做任何承诺。
2. 背景 本文分析基于 linux-4.14.132 上游代码。
运行环境为:
Ubuntu 16.04.4 LTS + QEMU + Arm vexpress-a9
rootfs 基于 ubuntu-base-16.04-core-armhf.tar.gz 制作。
3. 问题场景和分析过程 交叉编译了 perf 后,将 perf 放到 rootfs 的 /usr/bin/perf 路径,用QEMU启动系统后,执行 perf ,系统提示 No such file or directory 。通过 ls 命令发现文件 /usr/bin/perf 确实存在,所以,No such file or directory信息提示的并不是文件 /usr/bin/perf 不存在,而应该是提示 perf 执行过程中,需要加载的其它文件不存在。由于 perf 程序是通过动态链接方式编译的,所以 perf 执行过程中,需加载相关的解释器程序(动态链接器)和动态链接库。事情到了这里,我们通常可能会怀疑是编译链接过程出了差错。用file命令,对比了不能正常运行的 perf 程序,和能正常运行的 make 程序的基本执行信息:
$ file /usr/bin/perf /usr/bin/perf: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.
首先安装docker 我这边已经安装完成,你如果没有安装可以看我的其他文章有安装docker 的方法
1、拉取MySQL:5.7镜像 docker pull mysql:5.7
2、启动mysql-master容器实例 docker run -p 3306:3306 --name mysql-master \
-v /mydata/mysql-master/log:/var/log/mysql \
-v /mydata/mysql-master/data:/var/lib/mysql \
-v /mydata/mysql-master/conf:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=123456 \
-d mysql:5.7 注释:
-p 3306:3306 指定映射的端口
--name 指定容器的名字
-v 指定逻辑卷宿主机的目录和容器内的目录做逻辑卷防止容器被误删除
-e MYSQL_ROOT_PASSWORD=123456 指定MySQL的登陆密码
-d 指定后台运行
3、进入到宿主机的/mydata/mysql-master/conf/目录下创建my.cnf文件 cd /mydata/mysql-master/conf/
vim my.cnf [mysqld]
##设置server_id ,同一个局域网中需要唯一
server_id=10
##指定不需要同步的数据库名称
binlog-ignore-db=mysql
##开启二进制日志功能
log-bin=mall-mysql-bin
##设置二进制日志使用内存大小(事务)
binlog_cache_size=1M
##设置使用的二进制日志格式(mixed,statement,row)
binlog_format=mixed
##二进制日志过期清理时间,默认为0:表示不自动清理。
expire_logs_days=3
##跳过主从复制中遇到的多有错误或指定类型的错误,避免slaver端复制中断。
##如:1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致。
slave_skip_errors=1062
4、重启mysql-master容器 docker restart mysql-master
5、进入到mysql-master容器内 docker exec -it mysql-master /bin/bash
学习教程 一.免费算力领取 Datawhale专属注册: 趋动云https://growthdata.virtaicloud.com/t/vs
二.部署最新的ChatGLM3-6B模型 1.创建项目 创建好账号之后,进入自己的空间,点击右上角的创建项目。
给项目起一个你喜欢的名称,选择本地代码
镜像选择pytorch2.0.1,python3.9
选择预训练模型,点击公开,选择不要葱姜蒜上传的这个ChtaGLM3-6B模型。
都选完之后,点击右下角的创建,代码选择暂不上传。待会直接clone代码。
点击运行代码
资源配置选择:B1.large, 24G的显存足够加载模型了。其他的不需要设置,然后点击右下角的开始运行。
2.配置环境+修改代码 等右边两个工具全部加载完毕之后,再点击JupyterLab进入开发环境~
进入界面之后是这样的,然后点击这个小加号。
点击terminal,进入终端。
设置镜像源、克隆项目 首先在终端输入tmux,进入一个新的会话窗口。使用tmux可以保持终端的稳定性。
tmux 升级apt,安装unzip
apt-get update && apt-get install unzip 设置镜像源,升级pip
git config --global url."https://gitclone.com/".insteadOf https://
pip config set global.index-url https://mirrors.ustc.edu.cn/pypi/web/simple
python3 -m pip install --upgrade pip
克隆项目,并进入项目目录
git clone https://github.com/THUDM/ChatGLM3.git
cd ChatGLM3
修改requirements 双击左侧的requirements.txt文件,把其中的torch删掉,因为我们的环境中已经有torch了,避免重复下载浪费时间。
点击左上选项卡,重新返回终端,安装依赖
pip install -r requirements.txt
修改代码
修改web_demo2.py 双击web_demo2.py,将加载模型的路径修改为:../../pretrain,如下图所示~
修改web_demo.py 和上面一样我们修改一下模型路径,不同的是,接下来还需要修改一段启动代码~
将下方的启动代码修改为下方代码。
demo.queue().launch(share=False, server_name="0.0.0.0",server_port=7000) 于此同时在界面的右边添加外部端口:7000 3.运行代码 运行gradio界面 python web_demo.
前言 数据结构和算法是计算机科学的基石,是计算机的灵魂
要想成为计算机专业人员,学习和掌握算法是十分必要的。不懂数据结构和算法的人不可能写出效率更高的代码。计算机科学的很多新行业都离不开数据结构和算法作为基石,比如大数据、人工智能等。底层开发中也需要使用非常多的数据结构和算法知识,以保证底层系统的稳定性和高效性。
笔者对算法的理解 计算机科学家尼古拉斯·沃斯在计算机领域有一句人尽皆知的名言:
“算法+数据结构=程序”(Algorithms+Data Structures=Programs)
所以数据结构和算法是程序员必须掌握的技能。尤其是到一些大公司面试的时候,算法更是一个少不了的环节,熟练掌握数据结构和算法,可以开拓我们的视野,提高我们的逻辑思维能力,在写代码和分析官方源码的时候也非常有帮助。学习数据结构和算法的一个好处就是:学完之后知识基本不会过时,可以永远为我们所用。大家都知道程序员需要不停地学习,因为知识更新太快,记得在笔者(博哥)上大学和后来开始工作的时候,非常喜欢研究官方源码和框架,如痴如醉,但很遗憾,现在很多框架都已被淘汰了,没被淘汰的也被更新得面目全非,然后还要不停地学习其他新的框架。笔者一直在思考,能不能学习一种永不过时的知识。后来就接触了数据结构和算法,这一接触就是好多年,学的那么多知识依然没有过时。比如KMP算法是在1977年被联合发表的,那么多年过去了,这种算法依然没有被淘汰,如果是一个框架,基本上很难保证那么多年还能存在,就算存在也会有大量的更新,还是需要不停地学习。
写书的初衷及过程 笔者(博哥)具有10多年的开发经验,2017年开始做算法试题并在公众号发布试题讲解,经常游走在全球30多个算法网站之间,累计做题2000多道,对算法试题有自己独特的解题思路和技巧。
笔者写这本书的初衷是希望能够帮助更多的程序员快速学习算法,我们都知道算法在整个IT行业算是比较难的,之前有很过程序员通过公众号加笔者微信,请教关于算法的题,刚开始笔者一一进行了回复,后来随着咨询量越来越大,笔者意识到大家迫切地需要算法相关知识的系统指导。结合笔者过往的写作和从业经历,便着手写一本算法书籍,希望能欧帮助大家更好地学习算法,于是这本《算法秘籍》就诞生了。
这本书的知识覆盖范围全面,总共分为13个章节,先是详细介绍了常见的八大数据结构。后面都是我们比较常见的算法题,其中包括了二叉树的Morris遍历,KMP算法,马拉车算法等经典题型。
关于数据结构,大家普遍认为难度较大的可能就是图了,本书对图的分类,图的表示方式,图的遍历,以及图的各种经典算法比如迪杰斯特拉算法,普里姆算法,拓扑排序等都有大量介绍。
本书的内容 本书以Java为描述语言,介绍了计算机编程中常用的数据结构和算法,主要内容如下。
第1章:主要介绍了8种数据结构,包括数组、链表、队列、栈、散列表、树、堆、图,然后每种数据结构又有细分,比如介绍树的时候有完全二叉树、满二叉树、二叉搜索树、AVL树、红黑树、字典树、哈夫曼树、线段树、笛卡儿树等。图的介绍中也有一些经典的算法,比如迪杰斯特拉算法、弗洛伊德算法、普里姆算法和克鲁斯卡尔算法等。
第2章:介绍了几种经典排序算法,以及它们的稳定性分析。
第3章:主要介绍了一些位运算和常见操作符,还有一些简单的操作和使用技巧,如有限状态机和相关示例讲解。
第4章:介绍了和树有关的知识,比如树的遍历方式,包括DFS遍历、Morris遍历,以及BFS遍历等。
第5章:分析了递归的原理和示例练习,可以把它看作是对一棵树的DFS遍历。
第6章:主要介绍了回溯算法的使用,然后得出回溯算法的使用模板,以及一些经典示例,还有一些重复问题和不符合条件的修剪分支。
第7章:主要介绍贪心算法的使用和存在的不足。
第8章:分别介绍了相向双指针、同向双指针和快慢双指针的使用技巧,还有滑动窗口的介绍和使用模板,以及大小可变窗口、固定窗口、只增不减窗口等。
第9章:主要介绍了BFS和DFS的使用模板和示例练习。
第10章:主要介绍了一维前缀和与二维前缀和的使用。
第11章:介绍动态规划和一些经典问题的讲解,如背包问题、组合与排列问题等。
第12章:通过三国人物的故事,生动形象地介绍了并查集的使用、并查集优化、并查集路径压缩以及合并优化等。
第13章:介绍了其他一些经典算法,比如KMP算法、马拉车算法、算术表达式的运算、牛顿迭代法求平方根、Base64编码等。
很荣幸,本书在编写过程中得到了业内专家的支持和认可。
购买方式 点击传送门: 传送门
备注:双十一限时五折!
算法秘籍 王一博 著
算法是编程的基石,开发的核心。
本书包含55个二维码,300多分钟视频,100多个知识点,50多个示例,适合程序员、计算机专业相关师生,以及对算法感兴趣的读者。
这是一本关于数据结构和算法的书,以Java为描述语言,介绍了计算机编程中常用的数据结构和算法。全书共13章,讲述了常见的数据结构、排序算法、位运算、树、递归、回溯算法、贪心算法、双指针和滑动窗口、BFS和DFS、前缀和、动态规划、并查集、其他经典算法等知识。本书内容丰富,实用性强,通过示例练习和问题分析等方式,详细讲解了与算法有关的知识点。本书附赠视频讲解二维码,以及源代码。
导语:随着科技的发展,智能家居系统已逐渐成为现代家庭的一部分。而KNX作为一种开放的智能家居系统标准,提供了各种灵活的解决方案。本文将介绍KNX智能家居工程设计的基本理念和步骤,帮助读者了解如何在家中打造智能、舒适、高效的居住环境。
正文:
一、什么是KNX智能家居系统
KNX是一种开放的智能家居系统标准,它可以集成家庭中的各种设备和系统,如照明、暖通空调、安防、音乐等。通过KNX系统,用户可以通过智能手机、平板电脑或遥控器对家居设备进行集中控制。
二、KNX智能家居工程设计步骤
1.需求分析:在设计KNX智能家居系统之前,首先需要对家庭的需求进行分析,确定需要自动化的功能和设备,例如照明控制、温度调节、电器联动等。
2.系统设计:基于用户需求,设计一个合理、高效的KNX系统结构。该结构包括主控设备、传感器、执行器和通信网络等组成部分。通过合理的布线和设备的选择,确保系统的稳定性和可靠性。
3.设备安装:根据设计方案,将传感器和执行器等设备安装在合适的位置。确保设备正常工作,并与KNX系统进行连接。
4.编程调试:在系统安装完成后,进行编程调试工作。通过KNX编程软件,设置各个设备之间的联动关系和触发条件,以实现自动化控制。
5.用户培训:一旦系统调试完毕,用户需要对系统的操作和功能进行培训。用户应该学会如何使用遥控器、智能手机等控制设备,以及如何进行系统设置和定时任务等。
三、KNX智能家居系统的优势
1.灵活性:KNX系统采用开放的标准,能够集成各种设备和系统,同时支持多个设备厂商的互操作性。
2.可扩展性:KNX系统可以根据需要进行扩展,满足不同居住环境和功能的要求。
3.能耗管理:通过智能控制和定时任务,KNX系统可以有效管理能耗,实现节能和环保。
4.舒适性:KNX系统可以根据用户的需求和喜好,自动调节室内环境,创造更舒适的居住体验。
结语:
KNX智能家居工程设计是打造智能、舒适、高效的居住环境的关键。通过合理的需求分析、系统设计和设备安装,以及编程调试和用户培训,可以实现一个功能完善、稳定可靠的KNX智能家居系统。希望本文对读者有所帮助,如果有更多疑问或深入了解KNX智能家居系统,欢迎留言交流。
文章目录 String简单介绍常见命令应用场景 Hash简单介绍常见命令应用场景 List简单介绍常见命令应用场景 Set简单介绍常见命令应用场景 Sorted Set(Zset)简单介绍常见命令应用场景 Bitmap简单介绍常见命令应用场景 附录 Redis支持多种数据类型,比如String、hash、list、Set、SortedSet、Streams、Bitmap、Hyperloglog、Geo(物理位置)等等,在 官网也给出了说明,本博客就挑一些比较常有的数据类型说说,本文例子基于Redisson实现 String 简单介绍 在Redis中,所有的数据都是key-value的数据结构存储的,那么在Redis中这个string类型的value值只能存储String类型的数据?其实不然,redis中string类型的value值是可以支持多种类型的,比如String、Number、Float、Bits等等,但是最大还是只能存储512M。Redis中key也是string类型存储的,所以最大也只能存储512M
常见命令 set、get命令就不演示了,下面给出一些常有命令
批量设置多个key
mset tkey1 tvalue tkey2 111 批量获取多个key值
mget tkey1 tkey2 获取长度
strlen tkey 字符串后面追加内容
append tkey tstring 获取指定范围的字符
# 取0~3之间的字符,返回1tst getrange tkey 0 3 key进行递增(整数)
# 返回1 incr ikey # 递增指定大小的值,返回124 incrby ikey 124 key进行递增(浮点数)
# 设置初始浮点数值 set fkey 1.2 # 在原来基础上递增2.4,返回3.6 incryfloat fkey 2.4 加上key过期时间
expire tkey 10 分布式锁实现,set if not exists,可以使用setnx单个命令,也可以使用set结合nx命令来实现
报错信息如下RuntimeError: no valid convolution algorithms available in CuDNN 出现这个问题既不是cuda与cudnn版本不匹配,也不是英伟达显卡驱动需要更新!而是因为你的显存过低不能训练,解决办法是使用混精度训练!!!这样能减少近一半的显存!!!这种报错一般都是在自己电脑上跑才会出现的,或者你可以在服务器上跑,一般服务器显存是足够的。
目录
1.带头双向循环链表:
2. 带头双向循环链表的实现:
双向链表初始化:
双向链表打印:
开辟节点函数:
双向链表头插:
双向链表尾插:
双向链表头删:
双向链表尾删:
双向链表查找:
双向链表在pos之前插入:
双向链表在pos位置删除:
双向链表的销毁:
3.完整代码:
test.c
List.h
List.c
4.测试:编辑
5.顺序表和链表的区别
1.带头双向循环链表: 前面我们已经知道了链表的结构有8种,我们主要学习下面两种:
前面我们已经学习了无头单向非循环链表,今天我们来学习带头双向循环链表:
带头双向循环链表:结构最复杂,一般用在单独存储数据。实际中使用的链表数据结构,都是带头双向循环链表。另外这个结构虽然结构复杂,但是使用代码实现以后会发现结构会带来很多优势,实现反而简单了,后面我们代码实现了就知道了 带头双向循环链表不需要二级指针,因为我们刚开始就为其开辟了一个节点,叫做哨兵位头节点,它是结构体中的指针,用结构体指针就能改变它,而要改变结构体外面的指针才会用二级指针。
双向循环链表顾名思义,除了哨兵位头节点以外,每个节点里面应该有两个指针,下面我们定义一个结构体:
typedef int ListDatatype; typedef struct ListNode { struct ListNode* prev; struct ListNode* next; ListDatatype data; }LTNode; prev指向前一个节点,next指向后一个节点。
2. 带头双向循环链表的实现: 双向链表初始化: LTNode* InitList() { LTNode* phead = BuyList(-1); phead->next = phead; phead->prev = phead; return phead; } 双向循环链表开始时头和尾都指向自己:
BuyList函数的功能是创建节点,我们在初始化时用它创建哨兵位头节点,因为后面还有多次使用,所以把它封装为函数。
双向链表打印: void Print(LTNode* phead) { LTNode*cur = phead->next; printf("
1.获取时间戳 //获取日期 SYSTEMTIME st; CString StrTime; GetLocalTime(&st); //获取日期、时间 StrTime.Format(_T("%.4d-%.2d-%.2d %.2d:%.2d:%.2d.%.3d"), st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds); //2022-07-23 09:49:04.358 2. 13位时间戳转为时间格式 int64_t TimeUp = 1681436983403; //13位时间戳 auto milli = TimeUp + (long long)8 * 60 * 60 * 1000; auto mTime = std::chrono::milliseconds(milli); auto tp = std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds>(mTime); auto tt = std::chrono::system_clock::to_time_t(tp); std::tm* now = gmtime(&tt); CString ImgTime; ImgTime.Format(L"%.4d-%.2d-%.2d %.2d:%.2d:%.2d.%.3d\n", now->tm_year + 1900, now->tm_mon + 1, now->tm_mday, now->tm_hour, now->tm_min, now->tm_sec, TimeUp % 1000); Printf(ImgTime ); 执行结果:
在抖音上刷到其他人用 matlab 实现的一个动态心形图,就想也用 Python 实现,摸索了两种实现方式,效果如下:
方法一: 利用循环,结合 pyplot 的 pause 与 clf 参数实现图像的动态刷新 import matplotlib.pyplot as plt import numpy as np # type %matplotlib qt to shown figure in a separate window x = np.linspace(-1.8, 1.8, 1000) alpha = 1 while alpha <= 21: plt.xlim(-3, 3) plt.ylim(-2, 4) y = abs(x)**(2/3) + 0.9*np.sqrt(3.3 - x**2)*np.sin(alpha*(np.pi)*x) plt.plot(x, y) plt.text(-1.6, 3, r'$f(x)=x^{2/3}+0.9(3.3-x^2)^{1/2}\sin(\alpha\pi x)$') alpha_s = str(round(alpha, 2)) tx = plt.text(-0.5, 2.5, r'$\alpha=$' + alpha_s) plt.
Python中非线性规划通常使用优化库来处理,其中SciPy库是一个流行的选择。SciPy包含了用于非线性规划的优化算法,可以用来解决各种非线性优化问题。下面是一个简单的非线性规划的示例,使用SciPy来最小化一个非线性目标函数:
首先,确保你已经安装了SciPy库。如果尚未安装,可以使用以下命令:
pip install scipy
然后,可以使用以下代码示例来解决非线性规划问题:
import numpy as np
from scipy.optimize import minimize
# 定义目标函数
def objective_function(x):
return x[0]**2 + x[1]**2
# 初始猜测值
initial_guess = [1.0, 1.0]
# 设置约束条件
constraints = ({'type': 'eq', 'fun': lambda x: x[0] + x[1] - 1})
# 执行非线性规划
result = minimize(objective_function, initial_guess, constraints=constraints)
if result.success:
print("优化成功:")
print("最优解:", result.x)
print("最小值:", result.fun)
else:
print("优化失败:", result.message)
在上面的示例中,我们定义了一个简单的二次目标函数x[0]**2 + x[1]**2,并且添加了一个线性等式约束x[0] + x[1] - 1 = 0。然后,我们使用minimize函数来执行非线性规划,寻找最小值和最优解。你可以根据你的具体问题来修改目标函数和约束条件。
SciPy还提供了其他的非线性规划算法和选项,可以根据具体问题的需要进行调整。希望这个示例能帮助你入门Python中的非线性规划问题。
文章目录 目的Blend Shape 逐顶点 多个混合思路Blender3Ds maxUnity 中使用Project 目的 拾遗,备份
Blend Shape 逐顶点 多个混合思路 blend shape 基于: vertex number, vertex sn 相同,才能正常混合、播放
也就是 vertex buffer 的顶点数量一样,还有 triangles 的 index 要一致
这样 blend shape 才能逐个顶点计算
计算公式:使用一张大佬整理的图,大佬的文章:BlendShapes基础与拓展练习(面捕与物体变形)
Blender Shift+A 新建一个 sphere
选中
Tab 进入 Editor Mode,并且在 Data 页签属性的 Shape Keys 添加对应的 blend shape 状态
调整好每一个 Shape Keys (或是叫:blend shape) 的顶点位置
然后再 Object Mode 下,我们可以选中对应的 Shape Keys 然后调整 value 查看变形结果
最终我们尝试 K帧动画来查看 多个 shape keys 混合控制的情况
父组件中,子组件的加载一般是按照先后顺序加载的,子组件加载后才会加载父组件。
一个页面的子组件很多,由于会先加载子组件,那么父组件可能会出现比较长的白屏等待时间
大型项目,可能需要拆分应用为更小的块,并仅在需要时再从服务器加载相关组件Vue 提供defineAsyncComponent方法:
import { defineAsyncComponent } from 'vue'; const AsyncComp = defineAsyncComponent(() => { return new Promise((resolve, reject) => { // ...从服务器获取组件 resolve(/* 获取到的组件 */); }); }); 使用import导入组件 得到的 AsyncComp 是一个包裹组件,仅在页面需要它渲染时才调用加载函数。另外,它还会将 props 传给内部的组件,所以你可以使用这个异步的包裹组件无缝地替换原始组件,同时实现延迟加载
import { defineAsyncComponent } from 'vue'; const AsyncComp = defineAsyncComponent(() => import('./components/MyComponent.vue')); 处理加载与错误的状态 异步操作不可避免地会涉及到加载和错误状态,因此 defineAsyncComponent() 也支持在高级选项中处理这些状态:
const AsyncComp = defineAsyncComponent({ // 加载函数 需要返回一个Promise,可以使用动态import的方式,也可以自己new Promise() loader: () => import('./Foo.vue'), // 加载异步组件时使用的组件,该组件会在异步组件加载时显示,如果异步组件加载很快,可能不会出现loading组件 loadingComponent: LoadingComponent, // 展示加载组件前的延迟时间,默认为 200ms delay: 200, // 加载失败后展示的组件,可以通过Promise的reject来测试 errorComponent: ErrorComponent, // 如果提供了一个 timeout 时间限制,并超时了 // 也会显示这里配置的报错组件,默认值是:Infinity timeout: 3000 }); 如果提供了一个加载组件,它将在内部组件加载时先行显示。在加载组件显示之前有一个默认的 200ms 延迟——这是因为在网络状况较好时,加载完成得太快,导致最终组件的替换可能看起来像是闪烁。
在win11上使用git命令行克隆项目时出现 unable to get local issuer certificate问题,本文主要记录查找到的解决办法。
$ git clone https://lanedirt.tech/repo.git Cloning into 'repo'... fatal: unable to access 'https://lanedirt.tech/repo.git/': SSL certificate problem: unable to get local issuer certificate 主要原因 主要原因是在安装git的时候选择HTTPS transport backend时选择了OpenSSL library, 更为详细原因见源链接
解决问题方法 不用重新安装git,可以直接修改git设置如下
git config --global http.sslbackend schannel
#查询是否有锁表 show open tables where in_use > 0; #查询被锁的表 SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS; #查询进程 show processlist; #杀死进程 kill xx; #查看正在锁的事务 select * from information_schema.INNODB_LOCKS; #杀死进程id(就是[select * from information_schema.INNODB_LOCKS; ]命令的trx_mysql_thread_id列) kill 线程ID #查看等待锁的事务 SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS; #查看服务器状态 show status like '%lock%'; #查看超时时间 show variables like '%timeout%'; #查询事务 SELECT * FROM information_schema.innodb_trx 字段解析 innodb_trx表: trx_id:事务ID。 trx_state:事务状态,有以下几种状态:RUNNING、LOCK WAIT、ROLLING BACK 和 COMMITTING。 trx_started:事务开始时间。 trx_requested_lock_id:事务当前正在等待锁的标识,可以和 INNODB_LOCKS 表 JOIN 以得到更多详细信息。 trx_wait_started:事务开始等待的时间。 trx_weight:事务的权重。 trx_mysql_thread_id:事务线程 ID,可以和 PROCESSLIST 表 JOIN。 trx_query:事务正在执行的 SQL 语句。 trx_operation_state:事务当前操作状态。 trx_tables_in_use:当前事务执行的 SQL 中使用的表的个数。 trx_tables_locked:当前执行 SQL 的行锁数量。 trx_lock_structs:事务保留的锁数量。 trx_lock_memory_bytes:事务锁住的内存大小,单位为 BYTES。 trx_rows_locked:事务锁住的记录数。包含标记为 DELETED,并且已经保存到磁盘但对事务不可见的行。 trx_rows_modified:事务更改的行数。 trx_concurrency_tickets:事务并发票数。 trx_isolation_level:当前事务的隔离级别。 trx_unique_checks:是否打开唯一性检查的标识。 trx_foreign_key_checks:是否打开外键检查的标识。 trx_last_foreign_key_error:最后一次的外键错误信息。 trx_adaptive_hash_latched:自适应散列索引是否被当前事务锁住的标识。 trx_adaptive_hash_timeout:是否立刻放弃为自适应散列索引搜索 LATCH 的标识。 innodb_locks表: lock_id:锁 ID。 lock_trx_id:拥有锁的事务 ID。可以和 INNODB_TRX 表 JOIN 得到事务的详细信息。 lock_mode:锁的模式。有如下锁类型:行级锁包括:S、X、IS、IX,分别代表:共享锁、排它锁、意向共享锁、意向排它锁。表级锁包括:S_GAP、X_GAP、IS_GAP、IX_GAP 和 AUTO_INC,分别代表共享间隙锁、排它间隙锁、意向共享间隙锁、意向排它间隙锁和自动递增锁。 lock_type:锁的类型。RECORD 代表行级锁,TABLE 代表表级锁。 lock_table:被锁定的或者包含锁定记录的表的名称。 lock_index:当 LOCK_TYPE=’RECORD’ 时,表示索引的名称;否则为 NULL。 lock_space:当 LOCK_TYPE=’RECORD’ 时,表示锁定行的表空间 ID;否则为 NULL。 lock_page:当 LOCK_TYPE=’RECORD’ 时,表示锁定行的页号;否则为 NULL。 lock_rec:当 LOCK_TYPE=’RECORD’ 时,表示一堆页面中锁定行的数量,亦即被锁定的记录号;否则为 NULL。 lock_data:当 LOCK_TYPE=’RECORD’ 时,表示锁定行的主键;否则为NULL。 innodb_lock_waits表: requesting_trx_id:请求事务的 ID。 requested_lock_id:事务所等待的锁定的 ID。可以和 INNODB_LOCKS 表 JOIN。 blocking_trx_id:阻塞事务的 ID。 blocking_lock_id:某一事务的锁的 ID,该事务阻塞了另一事务的运行。可以和 INNODB_LOCKS 表 JOIN。