目录
一、考前
二、约考
三、考试界面讲解
四、成绩
五、证书
一、考前 1. 核心,多练题,练到滚瓜烂熟,最好在1.5h内完成全部题目,有k8s基础练习两周即可,没基础可能要一个月。
2. 建议上TB购买一份题库(95%与考试一致),并且会赠送题目k8s练习环境,非常有用,练题就是用这个环境,¥99,很良心了。
3. 考试需要梯子,建议考前一周购买一个月,我使用这个38/月(小贵,但胜在稳定),考前提前开启,约考时卡顿也可以挂一下
4. 刚开始练习可能会比较乱,我将17道题目按难度分为三个等级,刚开始练习可以一个难度一个难度来,等级越高难度越大。(后续更新每道题的详细解析)
一级难度 rbac cpu 扩容 pod指定节点 pv pod日志 排障 查看可用节点 多容器pod 节点维护
二级难度 networkpolicy service ingress pvc
三级难度 sidecar 升级集群 备份还原etcd
5. 每道题都有关键字链接,但还是建议你记住文档的位置(有8道题需要使用到文档,分别是pod指定节点、多容器pod、networkpolicy、service、ingress、pvc、sidercar、备份还原eycd,其他题目通过命令就可以完成)
6. 复制黏贴,不用担心考试不能复制黏贴,终端里鼠标右键可以黏贴,但注意ctrl+c、v用不了,另外vi里命令行模式下 :set pastek 可以保证缩进准确,其实不用也行,缩进不准再用。
7. 如果考试tab不能补全命令,使用以下命令,但一般情况下用不到的,注意<(直接没有空格
apt-get install bash-completion source <(kubectl completaion bash)
8. 提前下载一个有道词典,方便与英文监考官沟通。
9. 提前购买那种带线的摄像头,不让你得搬着你的笔记本瞎转,要带对焦功能,我用的是海康威视,¥135那款(好像涨价了,我现在看是151),切记买摄像头不要贪便宜,我第一次买的38块垃圾货只能拍到我的头,背景一点都拍不到,对焦还很垃圾,基本看不请证件(这点很重要)。
海康威视1080P电脑摄像头高清带麦克风广角USB自动对焦外接笔记本台式机家用网课视频会议带货摄像机E12a【图片 价格 品牌 评论】-京东
10. 英文官网比较便宜优惠后1800~2000左右,经常每个月月底都有不同程度的优惠,但只能选英文监考官,中文官网比较贵2800,且基本没有活动优惠,但可以选英文或中文监考官。监考官沟通都是用聊天框,不用讲话的。本人买的是英文官网的,注意英文官网购买需要准备一张万事达信用卡或者visa信用卡,用美元支付。不管是中文官网或英文官网买的,考试题目均可以切换为中文。
中文官网购买后获得一个考试码,需要拿着这个码去英文官网兑换考试,一个月内有效,兑换成功后考试是一年内有效。英文官网购买不需要此步骤。考试有一次补考机会。
中文官网:Linux Foundation开源软件学园-Linux_云技术_Kubernetes专业考试认证_K8s_CKA_CKS
英文官网(有优惠的时候这个网站顶部会有黄色底纹提示),之后约考,考试,查询成绩都在这个网站,name注意写成中文的,考试时name是中文看你身份证,英文会看你护照,考虑到不是每个人都有护照,所以建议name写成中文:Explore Full Catalog - Linux Foundation - Training
by:铁乐与猫
date:2021-5-11
安装依赖 sudo yum install epel-release sudo yum install php-mcrypt 安装 Apache, MySQL, PHP (LAMP) stack packages sudo yum install httpd mariadb-server php php-cli php-gd php-common php-ldap php-pdo php-pear php-snmp php-xml php-mysql php-mbstring php-gmp git 配置和运行 Apache webserver 修改apache配置文件
vim /etc/httpd/conf/httpd.conf
在95行,修改 ServerName localhost:8080
另外listen也同样编辑一下侦听在8080.
Listen 8080 主apache配置在文件中/etc/httpd/conf/httpd.conf,打开它并更改/var/www/html 的目录设置以允许mod_rewrite URL重写
编辑 /etc/httpd/conf/httpd.conf:
<Directory "/var/www/html"> Options FollowSymLinks AllowOverride all Order allow,deny Allow from all </Directory> 检查配置文件语法
httpd -t -f /etc/httpd/conf/httpd.
一、SPI简介 SPI(Serial Peripheral Interface) 协议是由摩托罗拉公司提出的通讯协议,即串行外围设备接口,是一种高速全双工的通信总线。它被广泛地使用在 ADC、LCD 等设备与 MCU 间,要求通讯速率较高的场合。
芯片的管脚上只占用四根线。
MISO: 主器件数据输入,从器件数据输出。
MOSI:主器件数据输出,从器件数据输入。
SCK: 时钟信号,由主设备控制发出。
NSS(CS): 从设备选择信号,由主设备控制。当NSS为低电平则选中从器件。
二、引脚分布 STM32 芯片有多个 SPI 外设,它们的 SPI 通讯信号引出到不同的 GPIO 引脚上,使用时必须配置到这些指定的引脚。其中 SPI1 是 APB2 上的设备,最高通信速率达 36Mbtis/s,SPI2、SPI3 是 APB1 上的设备,最高通信速率为 18Mbits/s。除了通讯速率,在其它功能上没有差异。其中 SPI3 用到了下载接口的引脚,这几个引脚默认功能是下载,第二功能才是 IO 口,如果想使用 SPI3 接口,则程序上必须先禁用掉这几个 IO 口的下载功能。一般在资源不是十分紧张的情况下,这几个 IO 口是专门用于下载和调试程序,不会复用为 SPI3。
三、FLASH芯片 开发板中的 FLASH 芯片型号:W25Q64。W25Q 系列为台湾华邦公司推出的是一种使用 SPI 通讯协议的 NOR FLASH 存储器。芯片型号后两位表示芯片容量,例如 W25Q64 的 64 就是指 64Mbit 也就是 8M 的容量。它的 CS/CLK/DIO/DO 引脚分别连接到了 STM32 对应的 SPI 引脚 NSS/SCK/MOSI/MISO 上,其中 STM32 的 NSS 引脚虽然是其片上 SPI 外设的硬件引脚,但实际上后面的程序只是把它当成一个普通的 GPIO,使用软件的方式控制 NSS 信号,所以在 SPI 的硬件设计中,NSS 可以随便选择普通的 GPIO,不必纠结于选择硬件 NSS 信号。
目录
一,DHCP中的相关操作
1.保存配置
2.更改名字
3.指点端口号
4.配置网关
5.退出该模式
6.查看接口ip摘要信息
7.查看当下所在位置存在的指令
8.删除该指令
9.帮助系统
10.拆除不想分配的ip地址
11.启动DHCP服务
12.创建名为a的dhcp池塘
13查看设备保存的所有配置
二,DHCP协议
1.DHCP:动态主机配置协议:
2.UDP协议
3.成为DHCP服务器的条件: 4.DHCP的三层结构
5.DHCP 工作过程
1.第一种场景——pc首次获取IP地址的情况
2.第二种场景——pc(客户端)再次获取ip地址的情况
6.DHCP租期
7.DHCP中的地址释放
1.概述
2.图解
一,DHCP中的相关操作 1.保存配置 <Huawei>save
2.更改名字 [Huawei]sysname R1
3.指点端口号 [Huawei]interface GigabitEthernet 0/0/0
4.配置网关 [Huawei-GigabitEthernet0/0/0] ip address192.168.1.1 24
5.退出该模式 [Huawei-GigabitEthernet0/0/0]quit [Huawei]
6.查看接口ip摘要信息 [Huawei]display ip interface brief 7.查看当下所在位置存在的指令 [Huawei]display this
8.删除该指令 在配置命令的最前端使用undo 可以删除该指令
9.帮助系统 ? 查看该模式或该单词后可以配置的单词及注释
10.排除不想分配的ip地址 [Huawei-ip-pool-a]excluded-ip-address 192.168.2.50 192.168.2.254
11.启动DHCP服务 [Huawei]dhcp enable 12.创建名为a的dhcp池塘 一台设备上可以创建多个池塘,但一个池塘只能服务一个广播域
简单介绍YOLOv8 这里主要关注模型的backbone和后处理的过程,并通过对比YOLOv5的架构来更深入的了解YOLOv8。
模型框架 YOLOv5中的C3替换为更精简的C2f ,即增加了更多的跳跃连接和split操作;
Backbone 中 C2f 的block 数从 3-6-9-3 改成了 3-6-6-3;
耦合头变成了解耦头,分类和回归分为两个分支分别进行;
数据前处理 1、letterbox缩放:
yolov8的输入是640*640,原图需要resize至标准大小输入网络,而直接采用拉伸的方式有可能会造成目标比例失衡(失真),所以yolov8沿用了v5的方式,即等比例缩放(宽/高至640时,剩余使用背景填充)。
模型推理 1.对 Head 输出的 bbox 分支进行转换,利用 Softmax 和 Conv 计算将积分形式转换为 4 维 bbox 格式。
2.YOLOv8 输出特征图尺度为 80x80、40x40 和 20x20 的三个特征图。Head 部分输出分类和回归共 6 个尺度的特征图。
将 6个不同尺度的特征图分别按照两个分支进行拼接,并进行维度变换。为了后续方便处理,会将原先的通道维度置换到最后,类别预测分支和 bbox 预测分支 shape 分别为 (b, 80x80+40x40+20x20, 80)=(b,8400,80),(b,8400,4)。
3.对(8400,84)进行后处理,首先采用 score_thr 进行阈值过滤。在这过程中还需要考虑 multi_label 和 nms_pre,确保过滤后的检测框数目不会多于 nms_pre。然后进行 nms ,使得最终输出的检测框不能多于 max_per_img。
4.筛选后的输出output_box格式为N*[x,y,w,h,conf,class]。N为筛选后预测框的个数,conf为最大类别概率。通过[x,y,w,h,conf,class]可以将预测框输出绘制在原图像上,由于图像的前处理经过了等比例缩放,所以此时要先将预测框的坐标转换为原坐标系的坐标。
5.输出的ret的格式为N * [x1,y1,x2,y2,conf,class]。
处理代码 import copy import onnxruntime as rt import numpy as np import cv2 import matplotlib.
第一讲 序言 学习slam必备知识及软件
第二讲 初识slam 1.引入 要想实现机器人的自主运动需要解决的两大问题:定位和建图。
定位侧重对自身的了解,建图侧重对外在的了解。
而这里就出现了一个相互耦合的问题,那就是要想获得准确的定位,首先要有一个精确的地图,而要想有精确的地图,那又需要一个准确的定位。
slam就是用来研究解决这两大问题的。
那么,要用什么来做slam呢?
------------答案是传感器。
服务于slam的传感器有两种:环境传感器和自身携带传感器。
而在实际的应用场景中,环境传感器有一定的限制,且slam更强调未知环境,所以携带式传感器是更合适更受重视的传感器。
相机: 本质:以二维记录三维 丢失的维度是:距离 各类相机的主要区别在于有没有深度信息 单目:没有深度,必须通过移动相机产生深度 双目:视差计算深度 RGBD:通过物理方法测量深度 2.视觉slam框架 1.前端 VO Visual Odometry 视觉里程计
方法:特征点法(第七讲) 直接法(第八讲) 2.后端 Optimization
代表:前期:EKF 现在:图优化(第十、十一讲) 3.回环检测 Loop Closing
识别到达过的场景,检测机器人是否回到早先位置
方法:词袋模型(第十二讲) 4.建图 Mapping
度量地图vs拓扑地图 稀疏地图vs稠密地图 3.slam问题的数学描述 两个基本方程:
运动方程
观测方程
4.实践部分 第三讲 三维空间的刚体运动 3D Space Rigid Body Motion
概述or目的: 1.理解三维空间刚体运动描述方式:旋转矩阵、变换矩阵、四元数和欧拉角 2.掌握eigen库的矩阵,几何模块的使用方法 1.点、向量 向量运算:
内积 外积* a^b 把向量变成矩阵
坐标系由三个基构成
行列式本身表示体积
引入问题:坐标系之间是如何变化的?
进而:怎么计算同一个向量在不同坐标系里的坐标?
在slam中:1.固定的世界坐标系和移动的机器人坐标系 2.机器人坐标随着机器人运动而改变,每个时刻都有新的坐标系
刚开始接触pwn的朋友在做pwn练习时可能会有这样的疑问,怎么做到精确覆盖变量数据呢?
我们做pwn练习之前需要先知道:命令行参数C语言的main函数拥有两个参数,为int类型的argc参数,以及char**类型argv参数。其中argc参数的值表示命令行参数的个数,而argv则指向一个字符串数组,该数组存储了具体的命令行参数的内容。
这里就用今天的实验,给大家介绍一下!
本文涉及相关实验:[《CTF
PWN练习之精确覆盖变量数据》](https://www.hetianlab.com/expc.do?ec=ECID172.19.104.182014110113362900001&pk_campaign=freebuf-
wemedia)(在掌握大小端字节序表示法的基础上,通过精心构造的输入数据溢出缓冲区,实现对modified变量的值进行精确覆盖,以达到修改程序执行逻辑的目的。)
看下面的例子 打印命令行参数信息的示例代码(位于/home/test/2目录下):#include <stdio.h>int main(int argc, char** argv){int i;for (i = 0; i < argc; ++i){printf(“argv[%d] = %s\n”, i, argv[i]);}return 0;}
注意程序本身的名字为命令行的第一个参数。编译这段代码生成test程序,然后在命令行下执行,尝试传入命令行参数,如:./test hello world
cmdline,可以看到程序打印出了具体的命令行参数信息:
xargs命令Linux的xargs命令可以将输入数据当做命令行参数传给指定的程序。比如执行命令python -c “print ‘AAA BBB
CCC’” | xargs ./test后,输出:
python语句执行后输出AAA BBB
CCC,通过管道操作作为xargs命令的输入,而xargs将其作为test程序的命令行参数,因此test程序会把这些信息打印出来。
小白:就是我们借助xargs可以把输入数据当成命令行参数输给这个程序。
大东:对的,另外还需要讲的是一个字节序
字节顺序,又称端序或尾序(英语:Endianness)。对于内存中存储的0x11223344这样一个值,从低地址往高地址方向的每一个字节来看,其内容在内存里的分布可能为0x11,0x22,0x33,0x44,也可能为0x44,0x33,0x22,0x11。
这就涉及到两种存储规则:大端格式和小端格式。示意图如下图所示:
0x11223344中的最高的字节为0x11,最低的字节为0x44,我们只要记住小端格式是“高存高,低存低”的规律,就很好的理解了。即小端格式中,高位字节存储于内存的高地址处,而低位字节存储于内存的低地址处。
Intel、AMD等系列的处理器都是小端格式的。
题目描述:
主机/home/test/2目录下有一个pwn2程序,这个程序会对传入的命令行参数进行处理,通过构造特定的命令行参数数据可以对程序发起溢出攻击,成功会提示
Congratulations, you pwned it. ,失败则会提示**Please try again.**的提示信息。
第一步源码审计使用cd /home/test/2切换到程序所在目录,执行cat pwn2.c即可看到源代码:#include <stdio.h>#include <string.h>#include <stdlib.h>int main(int argc, char** argv){int modified;char buffer[64];if (argc == 1){printf(“please specify an argument\n”);exit(1);}modified = 0;strcpy(buffer, argv[1]); // 引发缓冲区溢出if (modified == 0x61626364){printf(“Congratulations, you pwned it.
错误提示: 错误描述: 在 vbox 中安装了 ubuntu22.04 的虚拟机,在 ubuntu22.04 虚拟机中又安装了 kvm 。当使用 kvm 安装虚拟机时,报错如上。
错误分析: 这个问题可能是由于VirtualBox和KVM同时使用了硬件虚拟化技术(VT-x或AMD-V)导致的。在这种情况下,VirtualBox会尝试访问和控制宿主机的硬件虚拟化技术,而KVM也会尝试做同样的事情,导致冲突。
解决方法: 关闭VirtualBox中的Ubuntu虚拟机。
打开VirtualBox管理器,选择Ubuntu虚拟机,点击“设置”。
在“系统”选项卡中,取消勾选“启用EFI”和“启用PAE/NX”。
在“加速”选项卡中,取消勾选“启用VT-x/AMD-V”。
点击“确定”保存设置。
启动Ubuntu虚拟机,在终端中运行KVM命令安装虚拟机。
Q&A Q:取消勾选之后,在ubuntu里执行kvm-ok会显示not support kvm extensions ,这样还能在ubuntu里使用kvm安装虚拟机吗?
A: 可以。
如果在VirtualBox中禁用了硬件虚拟化技术,那么在Ubuntu虚拟机中执行 kvm-ok 命令会显示“not support kvm extensions”,这是因为KVM需要使用硬件虚拟化技术来提供虚拟化功能,而这个功能已经被禁用了。
在这种情况下,可以使用QEMU来模拟虚拟化功能。QEMU是一款开源的模拟器,可以在不支持硬件虚拟化的系统中运行虚拟机。
如果使用 virt-manager 图形化工具,以上内容无须操心,程序会自动选择。
随着网络与数据科技的进步,个人信息在AIGC、元宇宙世界等产业中扮演着愈发关键的角色。如何实施告知并取得个人主体同意是个人信息处理的基本前提,对于企业等处理者而言尤为重要。《个人信息保护法》规定了知情同意的原则和一般规则,但仍有不甚明确和具体之处,需要在标准类文件中给出进一步指引。据此,《信息安全技术 个人信息处理中告知和同意的实施指南》(下称《实施指南》)正式发布,该指南围绕告知和同意这两个重要措施进行了较为详细的通用和专用的规定。
2023年8月11日(本周五)19:00-20:30,由CSA大中华区隐私与个人信息保护法律工作组举办CSA研讨会—国家标准: 个人信息处理中告知和同意实施指南解读与实践分享,本次研讨会邀请了《实施指南》的起草人之一,CSA大中华区专家、数字丝路安全智库青年专家马可老师为大家分享《实施指南》解读与实践分享。
预约入口:视频号搜索“云安全联盟CSA”预约直播
文章目录 说在前面方案一:单库单表多字段数据表设计代码实现方式一:查询时根据语言标识进行字段过滤方式二:拦截响应数据结合JsonNode树模型统一处理 开始测试总结一下 方案二:单库单表多记录数据表设计代码实现开始测试总结一下 方案三:多库结合动态数据源切换数据表设计代码实现代码测试总结一下 大家好,我是Bivin,最近项目中遇到了动态数据多语言切换的需求,平台的动态数据需要支持中文简体、中文繁体、英语三种语言的自由切换,也就是所谓的国际化,我也是头一次接到这样的需求,去网上搜了搜发现对应的方案寥寥无几,算了,自己干吧,就这样总结出了三种我觉得可行的方案,凑合看吧! 说在前面 本文只讲解动态数据的国际化,且只做中文简体、中文繁体、英文三种语言的动态数据切换,加其他语言也是一样的思路,所有方案均采用文章类型表(article_type)作为例子。
方案一:单库单表多字段 此方案的思路是在一个表中使用不同的字段存储不同语言的数据,比如我们的文章类型名称需要支持的语言是中文简体(CN)、中文繁体(TC)和英文(EN),那么就设计三个不同语言的name字段,来分别存储这三种语言下的类型名称,代码层面通过统一响应处理器结合JackSon的树模型递归遍历移除和替换字段,返回用户所指定语言对应的数据。
关键词:单表、多字段、统一响应处理、JackSon树模型
数据表设计 列名类型备注aidint(11)自增aidcn_namevarchar(20)名称(中文简体)tc_namevarchar(20)名称(中文繁体)en_namevarchar(20)名称(英文)create_timedatatime创建时间update_timedatatime更新时间 如果还有其他字段需要支持多种语言,也可以这么来设计数据表的结构。
代码实现 此方案代码实现的思路是首先前后端统一约定好语言标识,中文简体:CN、中文繁体:TC、英文:EN,用户在页面上选择什么语言就在请求头中将该语言对应的标识携带到后端,后端获取到语言标识后再对其进行处理,这里我梳理了两种可实现的方案供各位参考,尤其是第二种方案。
方式一:查询时根据语言标识进行字段过滤 后端在每个需要实现动态数据国际化的接口中获取到请求头中的语言前缀language,在查询时过滤掉带其他语言标识的字段,只查询将当前语言标识作为前缀的字段和公用的字段,比如当前用户选择的是中文简体,那么从请求头中获取到的语言标识就是CN,所以在查询字段时就只查询含有CN前缀的字段和业务上需要使用到的公共字段即可,这样展示在用户面前的就是中文简体的数据,如果用户选择的是英文也是一样的方法。
此方案的缺点:冗余代码会特别多,很多跟业务无关的代码会直接侵入业务代码中,维护困难且开发成本高,开发者不仅要关注业务逻辑本身,还得关注语言的切换。优点就是实现起来相对简单一些,总之不是很推荐这种方案。
方式二:拦截响应数据结合JsonNode树模型统一处理 新建一个ResponseAdvice类,实现ResponseBodyAdvice接口拦截响应数据,在其beforeBodyWrite方法中对所有需要进行国际化处理的数据进行统一解析处理,这其中使用到了JackSon的JsonNode树模型,递归遍历响应结构。
1. 在代码中维护一个语言前缀列表,使用时将其转换为小写,用于后面过滤带有语言前缀的字段,使用HttpServletRequest获取到请求头中的语言前缀language,将其从语言前缀列表中移除,再将body转换为JsonNode,递归调用自定义的方法responseDataParseAndRemove()进行字段移除和重组。
@SneakyThrows @Override public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { // 通过HttpServletRequest获取到用户当前的语言环境 ServletRequestAttributes servletRequestAttributes = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()); if (servletRequestAttributes != null) { HttpServletRequest httpServletRequest = servletRequestAttributes.getRequest(); // 本地维护一个语言前缀列表 List<String> languageList = new ArrayList<>(); languageList.add("CN"); languageList.add("TC"); languageList.add("EN"); // 将响应数据body序列化为JsonNode ObjectMapper objectMapper = new ObjectMapper(); JsonNode node = objectMapper.
鼠标事件 具体的鼠标事件可以查询官网
这里讲如何拿到点击的坐标
// 获取句柄 const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas) handler.setInputAction(function (movement) { // 该处获取的为屏幕坐标 console.log(movement.position) // 射线 let ray = viewer.camera.getPickRay(movement.position) console.log(ray) let intersection = viewer.scene.globe.pick(ray, viewer.scene) console.log('intersction',intersection); if(intersection){ console.log('clicked earth',intersection) let toWGS8484pos = Cesium.Ellipsoid.WGS84.cartesianToCartographic(intersection) // 弧度经度和维度 console.log('wgs84',toWGS8484pos) // 由于弧度剖分,导致高度为负数,放大倍数越高,剖分程度越高,无限接近于0 } }, Cesium.ScreenSpaceEventType.LEFT_CLICK) 获取事件句柄获取射线坐标
这里的direction为射线方向,origin为射线的起始点,这样就可以形成射线和地球表面相交获取相交点的经纬度弧度坐标
QFontDialog QFont字体类使用QFont类QFontDialog类的静态API简单的使用 QFontDialog类是QDialog的子类, 通过这个类我们可以得到一个进行字体属性设置的对话框窗口, 和前边介绍的对话框类一样, 我们只需要调用这个类的静态成员函数就可以得到想要的窗口了。
QFont字体类 关于字体的属性信息, 在QT框架中被封装到了一个叫QFont的类中
// 构造函数 QFont::QFont(); /* 参数: - family: 本地字库中的字体名, 通过 office 等文件软件可以查看 - pointSize: 字体的字号 - weight: 字体的粗细, 有效范围为 0 ~ 99 - italic: 字体是否倾斜显示, 默认不倾斜 */ QFont::QFont(const QString &family, int pointSize = -1, int weight = -1, bool italic = false); // 设置字体 void QFont::setFamily(const QString &family); // 根据字号设置字体大小 void QFont::setPointSize(int pointSize); // 根据像素设置字体大小 void QFont::setPixelSize(int pixelSize); // 设置字体的粗细程度, 有效范围: 0 ~ 99 void QFont::setWeight(int weight); // 设置字体是否加粗显示 void QFont::setBold(bool enable); // 设置字体是否要倾斜显示 void QFont::setItalic(bool enable); // 获取字体相关属性(一般规律: 去掉设置函数的 set 就是获取相关属性对应的函数名) QString QFont::family() const; bool QFont::italic() const; int QFont::pixelSize() const; int QFont::pointSize() const; bool QFont::bold() const; int QFont::weight() const; 关于字体的粗细:
写在前面 现代 CSS (Modern CSS)应该是 2023 年前端圈热门话题之一,在最近的 CSS Day 活动上也有这个话题。另外在社区中也不乏现代 CSS 的讨论以及如何使用现代 CSS 特性来编写和组织 CSS 代码,以及如何使用现代 CSS 技术更好的构建出可扩展,未来更友好的 Web 项目。
我在还没有完成《现代 Web 布局》和 《防御式 CSS》小册的时候,就已经准备编写一本有关于 CSS 最新特性方面的小册,我将其命名为《现代 CSS》。
《现代 Web 布局》:可用于 Web 布局的 CSS 特性,比如 Flexbox,Grid,多语言布局等;
《防御式 CSS》:Web 开发者应该具有“万一”的思想准备,在编写代码的时候就需要考虑其所存在的“风险”,使自己编写出来的代码更健壮
《现代 CSS》:CSS 中最新的 CSS 特性理论与实践
开始我们今天的话题,接下来的内容篇幅较长,大约有 10000 字的阅读量!
无论以何种标准衡量,在过去的几年里,CSS 都有很大的进步。它有了更多有用的新特性和改进,其中许多最新的特性都是我们渴望已久的。比如,CSS :has() 选择器、CSS 逻辑属性和逻辑值、视窗动态单位、容器查询单位、容器查询、级联层、相对颜色、混合颜色、CSS 作用域、CSS 嵌套、三角函数、滚动驱动动画、视图过渡和瀑布流布局等。
那么,在项目开发的过程中,我们可以使用现代 CSS 哪些特性?或者说,这些新特性将给我们的 Web 开发带来哪些变化?欲知答案,请继续往下阅读。
现代 CSS 选择器:关系型选择器 虽然 CSS 中已经有很多种不同类型的选择器存在了,但现有的选择器总是不能满足 Web 开发者的需求,例如 Web 开发者也一直期望有一个父选择器,使 Web 开发者能通过子元素选择到父元素。而这一期望,也是随着 CSS 的 :has() 选择器的到来才使得 CSS 中有了所谓的“父选择器”。与此同时,现代 CSS 还新增了不少新的 CSS 选择器,例如 :is() 、:where() 、:not() 、:focus-visible 、:focus-within 、:modal 和 :target 等。
NVIDIA Jetson Orin Nano性能跃升80倍,成为入门级边缘AI和机器人技术的新标准。 圣克拉拉拉美国加利福尼亚州—GTC—今天,NVIDIA于2022年9月20日推出了全新的Jetson Orin Nano系统级模块,扩展了NVIDIA Jetson™产品阵容。与上一代产品相比,全新JetsonOrinNano的性能提升了80倍,成为入门级边缘AI和机器人技术的新标准。 NVIDIAJetson系列首次包括六个基于Orin的生产模块,可以支持各种边缘AI和机器人应用程序。它包括每秒提供40万亿次的最小Jetson尺寸。(TOPS)Orin Nano的AI特性,以及每秒275万亿次为高级自主机器提供的(TOPS)AGX Orin的AI特性。 NVIDIAAmpere架构GPUGPU Orin,Jetson Orin、CPU基于Arm架构。、新一代深度学习和视觉加速器,高速接口,快速内存带宽,支持多模式传感器。无论是部署边缘AI应用的工程师,还是构建新一代智能机器的机器人操作系统(ROS)开发者,这一前所未有的性能和多功能性,将使更多的客户创造出曾经看起来不可能的商品,并使其商业化。 “自NVIDIA六个月前宣布推出Jetson AGX Orin以来,已有1,000多名用户和150名合作伙伴使用了该产品,Orin Nano将大大扩大用户数量,”NVIDIA内嵌式和边缘计算副总裁DeepuTalla说。Jetson Orin协助数百万边缘AI和ROS开发者大幅提升性能,是一个理想的平台,适用于各种机器人部署工作。” 使得边缘AI和机器人技术更容易获得 Orin Nano模块在外观和引脚上与之前发布的Orin NX模块完全兼容。AGX Orin开发者套件开发适用于Orin Nano系列的应用,从今天开始,客户就可以使用AGX Orin开发者套件开发,并且可以灵活地设计一个系统来支持多个Jetson模块,并且可以轻松地扩展其应用。 OrinNano支持多条并发AI应用流水线,通过高速I/O和NVIDIAAmpere架构GPU。入门级设备和应用零售分析、工业质量控制等的开发者将能够以较低的成本更容易获得更复杂的AI模型。 Orin Nano模块将分为两个版本:Orin Nano 8GB提供最高40TOPS性能,功率为7W到15W。;4GB版本提供最高20TOPS性能,功率只有5W到10W。 Jetson Orin平台旨在应对最困难的机器人挑战,并加快70多万ROS开发者的计算速度。结合Orin Nano强大的硬件性能,最新的NVIDIAIsaac™该软件的增强功能给机器人专家带来了前所未有的性能和生产力。 强大的合作伙伴生态系统和软件支持 在机器人和嵌入式计算生态系统中,JetsonOrin得到了广泛的支持,包括佳能、约翰迪尔、MicrosoftAzure、Teradyne、升降机等。 NVIDIA活跃的Jetson生态系统正在迅速发展。目前,该生态系统拥有100多万开发者、6,000客户、2,000家创业公司和150家合作伙伴。Jetson合作伙伴提供各种支持,从AI软件、硬件和应用设计服务到摄像机、传感器和外设、开发工具和开发系统。 NVIDIA JetPack获得了Orin Nano™NVIDIA CUDA CUDA支持SDK-X™加快堆栈计算驱动力。这种计算堆栈还被用来创造工业物联网、制造业、智慧城市等方面的开创性AI商品。
项目场景: 最近在项目中使用到了Activiti工作流,需要编辑Test.bpmn流程图。
问题描述 但是拿到Test.bpmn文件之后选择直接打开发现全是代码,不是直观的图形界面。 <?xml version="1.0" encoding="UTF-8"?> <definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://www.activiti.org/test" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test"> <process id="Test" name="我的测试流程" isExecutable="true" isClosed="false" processType="None"> <userTask id="ECThreeManagerApproval" name="三级经理审批" activiti:assignee="${staffId}"> <extensionElements> <activiti:taskListener event="create" delegateExpression="#{ElectronicChannelCreateTaskListener}"></activiti:taskListener> <activiti:taskListener event="complete" delegateExpression="#{ElectronicChannelCompleteTaskListener}"></activiti:taskListener> </extensionElements> </userTask> <userTask id="ECDemandInterfacePersonAssign" name="二级经理审批" activiti:assignee="${staffId}"> <extensionElements> <activiti:taskListener event="create" delegateExpression="#{ElectronicChannelCreateTaskListener}"></activiti:taskListener> <activiti:taskListener event="complete" delegateExpression="#{ElectronicChannelCompleteTaskListener}"></activiti:taskListener> </extensionElements> </userTask> <endEvent id="ECEnd" name="结束"> <extensionElements> <activiti:executionListener event="end" delegateExpression="#{ElectronicChannelEndTaskListener}"></activiti:executionListener> </extensionElements> </endEvent> <sequenceFlow id="flow12" sourceRef="ECThreeManagerApproval" targetRef="ECDemandInterfacePersonAssign"> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${verify=='ECDemandInterfacePersonAssign'}]]></conditionExpression> </sequenceFlow> <startEvent id="ECStart" name="
select id,mainid,FBaseWages,FPostSalary,FStartDate,FEndDate
from uf_base_salary_info_dt1 where id=486 -----
转换成:开始日期到结束日期 每天一条数据
SELECT tmp.id,tmp.mainid,FBaseWages,FPostSalary,
DATEADD(DAY, Nbr - 1, tmp.FStartDate) Detail_Date
FROM ( SELECT ROW_NUMBER() OVER ( ORDER BY c.object_id ) AS Nbr
FROM sys.columns c
) nbrs
cross join
(
select id,mainid,FBaseWages,FPostSalary,FStartDate,FEndDate
from uf_base_salary_info_dt1
where len(FEndDate)>0 --and id=486
union all
select id,mainid,FBaseWages,FPostSalary,FStartDate, GETDATE() FEndDate
from uf_base_salary_info_dt1
where LEN(FEndDate)=0
)tmp
WHERE Nbr - 1 <= DATEDIFF(DAY, tmp.FStartDate, tmp.FEndDate)
取每月最后一天数据(少3.17日数据)
select id,mainid,FBaseWages,FPostSalary,Detail_Date
from v_uf_base_salary_info_dt1_today where Detail_Date=DATEADD(mm, DATEDIFF(mm, -1, Detail_Date), -1)
在 JavaScript 编程中,随着项目的复杂性增加,代码的组织和管理变得至关重要。模块化是一种强大的编程概念,它允许我们将代码划分为独立的模块,提高了可维护性和可扩展性。本文将详细介绍 CommonJS 和 ES6 模块,帮助你理解它们的特点和用法。
1. CommonJS 模块化
CommonJS 是一种用于模块化 JavaScript 的标准。它主要用于服务器端的 Node.js 环境,但在浏览器端也可以使用一些工具进行转换。在 CommonJS 中,每个文件都被视为一个模块,可以使用 require 导入其他模块,使用 module.exports 或 exports 导出变量和函数。
// 导入模块 const math = require('./math'); // 使用导入的模块 console.log(math.add(2, 3)); console.log(math.subtract(5, 2)); // math.js 模块 exports.add = (a, b) => a + b; exports.subtract = (a, b) => a - b; 2. ES6 模块化
ES6 引入了一种原生的模块化系统,使得在现代浏览器和 Node.js 中都可以使用。ES6 模块采用了更简洁和直观的语法,使用 import 导入模块,使用 export 导出变量、函数、类等。
// 导入模块 import { add, subtract } from '.
什么是GTID? 全局事务标识符GTID的全称为Global Transaction Identifier,是在整个复制环境中对一个事务的唯一标识。
它是MySQL 5.6加入的一个强大特性,目的在于能够实现主从自动定位和切换,而不像以前需要指定文件和位置。替代传统的binlog+pos复制;使用master_auto_position=1自动匹配GTID断点进行复制,slave端在接受master的binlog时,会校验GTID值。
GTID的格式 ceb0ca3d-8366-11e8-ad2b-000c298b7c9a:1-4
uuid号:每个mysql实例的唯一编号,1-4是序列号,每次一个事务完成都会自增1。
GTID的分配 服务器为已提交的事务生成新的GTID。写入二进制日志的每个数据库更改(DDL或DML)都会分配一个GTID。这包括自动提交的更改以及使用BEGIN和COMMIT或START TRANSACTION语句提交的更改。当数据库,以及非表数据库对象,例如过程、函数、触发器、事件、视图、用户、角色在创建、更改或删除时会分配GTID。授权语句和非事务表的更新也会分配GTID。
gtid_next系统变量 gtid_next是会话系统变量。默认情况下,对于在用户会话中提交的新事务,服务器会自动生成并分配新的GTID。在从库上应用事务时,将保留来自原始服务器的GTID。
当gtid_next设置为AUTOMATIC(默认值),并且事务已提交并写入二进制日志时,服务器会自动生成并分配新的GTID。如果由于其它原因而回滚事务或未将事务写入二进制日志,则服务器不会生成和分配GTID。
gtid_purged系统变量 gtid_purged是全局系统变量。@@GLOBAL.gtid_purged中的GTID集包含已在服务器上提交但在服务器上的任何二进制日志文件中不存在的所有事务的GTID。gtid_purged是gtid_executed的子集。
在从库上禁用二进制日志记录时提交的复制事务的GTID。
已清除的二进制日志文件中事务的GTID。
通过语句SET @@GLOBAL.gtid_purged明确添加到集合中的GTID。
root@(none) 10:38 mysql>show variables like 'gtid%'; +----------------------------------+-----------+ | Variable_name | Value | +----------------------------------+-----------+ | gtid_executed_compression_period | 1000 | | gtid_mode | OFF | | gtid_next | AUTOMATIC | | gtid_owned | | | gtid_purged | | +----------------------------------+-----------+ 5 rows in set (0.04 sec) 工作原理 1、master上进行DML操作更新数据时,会在事务前产生GTID,一同记录到binlog日志中。
2、slave上的i/o 线程将变更的binlog,写入到本地的relay log中。
在日期范围之间生成日期)使用交叉联接将tmp表与日期生成器代码组合
declare @tmp as table ( [Case] int, [Name] varchar(20), [StartDate] date, [EndDate] date)
insert into @tmp
values(1, 'ABC', '2021-01-15', '2021-03-15')
,(2, 'DEF' ,'2021-03-15', '2021-05-15')
SELECT tmp.[Case],
tmp.[Name],
DATEADD(DAY, Nbr - 1, tmp.StartDate) Detail_Date
FROM ( SELECT ROW_NUMBER() OVER ( ORDER BY c.object_id ) AS Nbr
FROM sys.columns c
) nbrs
cross join
(
select [Name],[Case],[StartDate],[EndDate] from @tmp
)tmp
WHERE Nbr - 1 <= DATEDIFF(DAY, tmp.StartDate, tmp.EndDate)
order by
目录
1.概述
2.安装和配置
3.重启jmeter
4.重点注意
1.概述 JMeter 是什么以及它的作用: JMeter 是一个功能强大的开源性能测试工具,主要用于模拟负载和压力测试来评估 Web 应用程序、服务和数据库的性能。它能够模拟大量用户并生成不同类型的请求,以便对目标系统进行全面的性能分析和评估。
JMeter 的流行原因: JMeter 是一个广泛使用的性能测试工具,其流行原因包括:
开源免费:JMeter 是开源工具,允许用户自由使用和定制,无需支付额外费用。平台无关性:JMeter 可以在不同操作系统(如Windows、Linux、Mac)上运行,适用于各种开发环境。灵活性和可扩展性:JMeter 提供了丰富的功能和组件,允许用户根据需求自定义测试计划,支持插件扩展,适应不同的测试场景。完整的测试解决方案:JMeter 不仅可以进行性能测试,还可以进行功能测试、API 测试和负载测试等多种类型的测试。 JMeter 的主要特点和优势:
支持多种协议:JMeter 支持 HTTP、HTTPS、FTP、SOAP、JDBC、JMS 等多种协议,可以对各种类型的应用程序进行测试。多线程模拟:JMeter 可以模拟大量用户并发访问目标系统,提供真实负载下的性能测试。分布式测试:JMeter 支持分布式测试,可以在多台机器上同时执行测试,以模拟更真实的负载情况。强大的监听器:JMeter 提供多种监听器用于收集和分析测试结果,如聚合报告、图形结果、查看结果树等,方便用户进行性能分析。脚本录制和回放:JMeter 可以录制用户在浏览器中的操作,并将其转化为测试脚本,方便重现测试场景。扩展性和定制性:JMeter 提供了丰富的插件和可扩展性,用户可以根据需求定制和扩展 JMeter 功能。 2.安装和配置 步骤1:JMeter 是一个开源工具,你可以从官方网站下载最新版本的 JMeter。
下载链接:JMeter 官方网站
步骤2:解压
步骤3:下载jdk——配置jdk环境变量
下载链接: Oracle 官方网站(Java Downloads | Oracle)
下载完成后,自定义目录文件,一路傻瓜式安装。
步骤4:JMeter环境配置
1.变量名:JMETER_HOME (按照实际按照目录文件进行粘贴复制)
2.变量名:CLASSPATH
%JMETER_HOME%\lib\ext\ApacheJMeter_core.jar; %JMETER_HOME%\lib\jorphan.jar
3.变量名:path
%JMETER_HOME%\bin
步骤5:JDK环境配置
1.输入变量名为JAVA_HOME,变量值为C:\Program Files\Java\jdk-1.8(根据您的实际安装路径进行调整)。
2.path 变量值:\;%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin
3.CLASSPATH 变量值:%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;
步骤6:检验环境配置
1.cmd:输入java -version
2.cmd:输入jmeter 截图为成功配置环境变量。
文章目录 1. 无参数命令2. 带参数命令2.1. 字符串参数2.2. 数字型参数 ====>>> 文章汇总(有代码汇总) <<<====
目标:使用Finsh自定义命令。
RT-Thread studio,版本: 2.2.6。RT-Thread:标准版,4.0.3版本。 Finsh组件是创建工程后就默认开启的,无需任何配置。
1. 无参数命令 对于这种无参数的是最简单的,比如下面的函数,只需要使用MSH_CMD_EXPORT将需要导入的函数名导入就可以了。
格式为:MSH_CMD_EXPORT(函数名,简要介绍)
void no_params_func_test(void) { printf("hello rtthread \n"); } MSH_CMD_EXPORT(no_params_func_test, no params func test); 然后向串口发送no_params_func_test,即可看到函数执行结果。
2. 带参数命令 首先,带参数的函数定义格式如下,其中参数argc表示命令的参数个数,argv表示具体的参数。
void have_params_func_test(int argc, char **argv) { // 输出参数个数 rt_kprintf("argc = %d \n", argc); } MSH_CMD_EXPORT(have_params_func_test, have params func test); 然后看函数如何判断我们传入了多少个参数。
可以看到,
如果发送:命令,参数个数 = 1。
如果发送:命令+空格+字符串1,参数个数 = 2。
如果发送:命令+空格+字符串1+空格+字符串2,参数个数 = 3。
…
所以我们实际传入的参数实际上是从第二个(索引1)开始的。
2.1. 字符串参数 结论:argv[1]就表示第一个参数的字符串指针,argv[2]就表示第二个参数的字符串指针。。。以此类推,函数中使用时,要先判断函数个数是不是符合预期,然后再做处理。
首先安装STM32CubeMX,CubeMX是ST公司出品的一款图形化代码生成工具,通过图形化界面,可以非常直观的配置好各种片上外设,时钟,中断,DMA等等各种设备的参数,并直接生成初始化代码
官网下载链接:STM32CubeMX | STMCU中文官网
本章写一个程序,建立两个LED灯闪烁任务,先在cubemx中新建工程,然后进入keil5对程序修改,编译,生成的文件通过unlink连接开发板进行烧录
首先进入CubeMX, 新建工程,进入后选择芯片处理器,本文选择的stmf051r8t6处理器
接下来先配置SYS,勾选debug serial wire调试接口,timebase选择TIM1定时器
然后配置RCC,这两个时钟源都选择Crystal/Ceramic Resonator(外部晶振时钟)
然后配置GPIO,选择PC8和PC9两个引脚,设置GPIO_Output作为两个输出,来控制LED灯闪烁
接下来选中Middleware...下的FREERTOS,选择CMSIS_V1,然后切换到Task and Queue页面,点击Add添加任务,添加时只改变任务的优先级为High,其他默认就行了,同理添加第二个任务,也只改变任务优先级为High
成功添加后,有我们添加的两个任务和一个default任务,如图所示
接下来切换到Clock Configuration界面,选择外部时钟,设置到最高时钟频率,如下
接下来切换到Project Manager界面,设置工程文件名和保存路径,keil5开发就选择MDK-ARM
然后点开Code...栏,勾选为每个外设建立.c和.h文件,最后点击右上角Generate Code生成项目
接下来我们用keil5打开新建的工程,打开LED/Applicstion/User/Core下的freertos.c文件
更改freertos.c文件代码最下面刚新建的两个任务的代码,如下图代码,然后就直接编译
然后打开ST-Link Utility软件,连接开发板,打开我们刚生成的hex文件,hex文件所在地址一般在创的LED文件里面,然后点击Start开始烧录
如下图闪烁,已经将写的连个任务程序烧录成功
用的Redis是windows版本,6.2.6
报错的主要信息如下:
Failed to instantiate [org.redisson.api.RedissonClient]: Factory method 'redisson' threw exception; nested exception is org.redisson.client.RedisConnectionException: Unable to connect to Redis server: 127.0.0.1/127.0.0.1:6379
org.redisson.client.RedisException: ERR AUTH <password> called without any password configured for the default user. Are you sure your configuration is correct?. channel: [id: 0x78c78239, L:/127.0.0.1:53460 - R:127.0.0.1/127.0.0.1:6379] command: (AUTH), params: (password masked)
开始排查使用Redis-cli进行测试:发现Redis启动正常:
自己用了一些其他的demo进行测试也是可以连接Redis的,使用Redis连接管理工具也是可以连接的,但是这个 若依-plus-vue 启动的时候就是报上面的错误。
解决方案:
把yaml文件中连接Redis 的配置的密码字段改为 auth,然后发现就可以了。
目前我也没搞明白,什么时候用password,什么时候用auth,我另一个demo项目,用的也是redis-windows-6.2.6, 但是使用password字段就可以连接。。。感觉与redis-starter的版本有关。
VS自建工程导入VTK库 出了好多bug,记录一下:
1.打开vs创建新项目
2.在菜单栏中选择项目-属性设置库文件。
3.设置VC++目录中的包含目录和库目录
4.接着设置链接器-输入中的附加依赖库
5.到此项目的属性配置完成,此时可以从之前运行的VTK.sln工程中复制任意一个测试实例在本项目中运行。
然后开始报错,整理了一下:
找不到vtkCommoncore-8.2.dll 在VS2019的调试器里添加:
注意不要落下“”PATH=”,最开始就是这里没写,然后一直报错,,,
C:\Program Files (x86)\VTK1是我构建的路径,加了1是因为已经不是第一次装,所以做了个区分,你们找到自己VTK对应的路径的bin文件夹就行(包含dll文件的)
然后就报了下一步错:
“no override found for vtkpolydatamapper” 网上搜了解决方法:
在源码最开头添加这样三行代码:
#include <vtkAutoInit.h> VTK_MODULE_INIT(vtkRenderingOpenGL2); // 和你cmake时候选的opengl相匹配,如果是opengl那就是vtkRenderingOpenGL,而我选的是opengl2,所以这里的参数是vtkRenderingOpenGL2 VTK_MODULE_INIT(vtkInteractionStyle); cmake里面搜索一下opengl,可以看到是opengl2
然后把opengl32.lib添加到附加依赖项中
然后运行,终于:!!!
参考: Visual Studio, Qt, VTK, ITK安装(For Windows) - 知乎 (zhihu.com)
找不到vtkCommoncore-8.2.dll,vtkImagingSources.dll问题的解决方法。_Vec[95]的博客-CSDN博客
VTK在测试时候出现“no override found for vtkpolydatamapper”的完美解决方法_EternalFlow的博客-CSDN博客
目录
synchronized--同步
练习一
练习二
练习三
synchronized--同步 练习一 package syn; //不安全的买票 //线程不安全,有负数 public class UnsafeBuyTicket { public static void main(String[] args) { BuyTicket station = new BuyTicket(); new Thread(station,"我").start(); new Thread(station,"你").start(); new Thread(station,"他").start(); } } class BuyTicket implements Runnable{ //票 private int ticketNums = 10; boolean flag = true; //外部停止方式 @Override public void run() { //买票 while (flag){ try { buy(); } catch (InterruptedException e) { e.
多线程--练习Thread,实现多线程同步下载图片 目录
多线程--练习Thread,实现多线程同步下载图片
package Thread.Demo01; import org.apache.commons.io.FileUtils; import java.io.File; import java.io.IOException; import java.net.URL; //练习Thread,实现多线程同步下载图片 public class TestThread2 extends Thread{ private String url; //网络图片地址 private String name; //保存的文件名 public TestThread2(String url,String name){ this.url = url; this.name = name; } //下载图片线程的执行体 @Override public void run() { WebDownloader webDownloader = new WebDownloader(); webDownloader.downloader(url,name); System.out.println("下载了文件名为:"+name); } public static void main(String[] args) { TestThread2 t1 = new TestThread2("
目录
Java知识点---多线程---买火车票的列子
package Thread.Demo01; //多个线程同时操作同一个对象 //买火车票的列子 //发现问题:多个线程操作同一个资源的情况下,线程不安全,数据紊乱 public class TestThread4 implements Runnable{ //票数 private int ticketNums = 10; @Override public void run() { while (true){ if (ticketNums<=0){ break; } //模拟延时 try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"--->拿到了第"+ticketNums--+"票"); } } public static void main(String[] args) { TestThread4 ticket = new TestThread4(); new Thread(ticket,"小明").start(); new Thread(ticket,"老师").start(); new Thread(ticket,"校长").start(); } }
简要 有时候我们在官网的Grafana下载的图表是这样的,如下图
#算子的处理时间,就是处理数据的延迟数据抓取,这个的说明看下下面的文章 metrics.latency.interval: 60 metrics.reporter.promgateway.class: org.apache.flink.metrics.prometheus.PrometheusPushGatewayReporter metrics.reporter.promgateway.host: localhost metrics.reporter.promgateway.port: 9091 metrics.reporter.promgateway.jobName: jobname metrics.reporter.promgateway.randomJobNameSuffix: true metrics.reporter.promgateway.deleteOnShutdown: false metrics.reporter.promgateway.interval: 20 SECONDS 相关配置说明 一口气搞懂「Flink Metrics」监控指标和性能优化,全靠这33张图和7千字(建议收藏) - 掘金
相关模板下载
Dashboards | Grafana Labs
在线正则
在线正则表达式测试
前提 处理上面的前提是flink的监控数据已经采集到了pushgateway里面。
设置全局变量的技巧 上图通过构建查询的值,然后用正则匹配得到最后的任务数据,用来做全局变量使用 query_result(flink_jobmanager_job_uptime) #如果是要得到有端口的用这个 /instance="(.+:\d+)"/ #如果没有特殊要求用下面这个 /job_name="(.+)"/ #用下面这个好用一点 /exported_job="([^"]+)"/ flink_jobmanager_job_uptime{exported_job="$exported_job"} 最后操作以后的效果为
制作第一个图表 设置单位 设置查询的别名 其他设置 制作第二个表格 用label以表格的方式显示 控制那些显示那些不显示 可以借鉴下
Grafana 使用表格面板进行数据可视化-grafana 表格
解决Pycharm单步调试时没有响应的问题 在使用Pycharm调试程序时,发现运行不报错,但是加断点调试程序时,显示
Backend Qt5Agg is interactive backend. Turning interactive mode on. 而且不能继续调试。
解决办法 :
File——Settings——Build,Exrcution,——Python Debugger里边的Gevent compatible这个选项打勾,然后就可以使用了。
引入负载均衡 在消费方引入负载均衡机制,同时简化获取服务提供者信息的流程
Spring Cloud引入组件LoadBalance实现负载均衡
添加依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacosdiscovery</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-loadbalancer</artifactId> </dependency> properties配置
spring.application.name=service-consumer # Nacos 服务发现与注册配置,其中子属性 server-addr 指定 Nacos 服务器主机和端口 spring.cloud.nacos.discovery.server-addr=localhost:8848 # 注册到 nacos 的指定 namespace,默认为 public spring.cloud.nacos.discovery.namespace=public server.port=6082 主类上添加对应的注解
@EnableDiscoveryClient @SpringBootApplication public class Consumer2Application { public static void main(String[] args) { SpringApplication.run(Consumer2Application.class, args); } @LoadBalanced @Bean public RestTemplate restTemplate() { return new RestTemplate(); } } 定义对应的控制器,需要访问服务提供者
@RestController @RequestMapping("/consumer") public class ConsumerController { @Autowired private RestTemplate restTemplate; @GetMapping("
一、引言 在初学C++时,在包含完头文件之后,我们常常会看到这么一句话:using namespace std;
比如:
#include<iostream> using namespace std; int main() { cout << "hello world" << endl; return 0; } 首先需要声明的是:它不是什么“固定动作”,不是必须这么写的。
二、命名空间 namespace,顾名思义,命名空间。
而using namespace ,则是展开命名空间。
std是C++标准库的命名空间。
因此,using namespace std,就是展开std这个命名空间。
此外,我们也可以定义自己的命名空间:
namespace jiangsu { //这里定义的变量还是全局变量,放到静态区 //命名空间可以定义变量、函数、类型 int rand = 0; int Sub(int x, int y) { return x - y; } struct Node { struct Node* next; int val; }; } 同时,命名空间是可以嵌套定义的:
namespace jiangsu { //这里定义的变量还是全局变量,放到静态区 //命名空间可以定义变量、函数、类型 int rand = 0; int Sub(int x, int y) { return x - y; } struct Node { struct Node* next; int val; }; namespace N { int m; int n; int Add(int x, int y) { return x + y; } } } 部分展开 using namespace std; 这种就是完全展开,那么就会产生一个弊端:我们在定义或使用某一变量或方法时,会产生一些问题,比如命名冲突等。
生命周期 又名:生命周期回调函数、生命周期函数、生命周期钩子是什么:Vue在关键时刻帮我们调用的一些特殊名称的函数生命周期函数的名字不可更改,但函数的具体内容是我们根据需求编写的生命周期函数中的this指向的是vm或组件实例对象
挂载流程 init:初始化事件和生命周期,制定一些规则,此时数据代理还未开始befoerCreate:此时无法通过vm访问到data中的数据、methods中的方法。数据代理还没开始init:初始化数据监测、数据代理。此时可以通过vm访问到data中的数据,和methods中的方法create:此时可以通过vm访问到data中的数据,和methods中的方法判断是否有el,如果没有则判断是否有remplate模板。绑定el则会将外部容器当作模板,否则使用自定义的template当作模板。此阶段开始解析,生成虚拟DOM,页面还不显示生成好的内容beforeMount:页面呈现未经Vue编译的DOM结构,此时对DOM的所有操作都不奏效接下来将内存中的虚拟DOM转为真实DOM放在页面Mounted:页面中呈现经过Vue编译的DOM,此时对DOM的操作均有效,但应尽可能避免。至此初始化过程结束,一般在此进行:开启定时器、发送网络请求、订阅消息、帮i的那个自定义事件等初始化操作 更新流程 当数据发生改变,将进入更新流程
beforeUpdate:此时数据是新的但是页面时旧的,页面和数据尚未保持同步随后根据新数据生成新的虚拟DOM,与旧的虚拟DOM进行比较,完成页面的更新,即:Model到View的更新updated:此时的数据是新的,页面也是新的,页面和数据保持同步 销毁流程 beforeDestroy:此时vm中所有的:data、methods、指令等等,都处于可用状态,马上要执行销毁过程。一般在此阶段:关闭定时器、取消订阅消息,解绑自定义事件等收尾工作。此时对数据的更新不会展示出来。destroyed:销毁完毕 总结 常用的生命周期钩子:
mounted:发送ajax请求,启动定时器、绑定自定义事件、订阅消息等初始化操作beforeDestroy:清除定时器、解绑自定义事件、取消订阅消息等收尾工作 关于销毁Vue实例:
1.销毁后借助Vue开发者工具看不到任何信息
2.销毁后自定义事件会失效,但是原生DOM事件依然有效
3.一般不会在beforeDestroy操作数据,因为即便操作数据,也不会再触发更新程序
矩阵的运算 加法,数乘,减法,转置 在坐标系中可以这么去理解, 相当于一个图形扩大或缩小了几倍
矩阵的基本运算法则 矩阵的加减 矩阵的加法就是矩阵的对应位置相加,减法也是一样就是对应位置相减
数乘 转置 转置的操作和向量是一样的,就是把 aij 变成 aji,把行和列互换一下
对于矩阵而言, 转置其实就相当于把主对角线两侧的元素进行了调换
高维数组的转置方法tranpose numpy.transpose方法用于交换数组的维度,也就是将数组的行和列进行互换。对于二维数组来说,它实际上就是进行转置操作。
函数签名: numpy.transpose(a, axes=None) numpy.ndarray.transpose(axes=None) 参数:
numpy.ndarray:要进行转置操作的数组。axes:可选参数,用于指定交换维度的顺序(索引的形式)。默认情况下,会交换所有维度。可以传入一个整数元组来指定交换的维度顺序。
返回值:
返回转置后的数组。 注意事项:
如果数组是一维的,transpose方法不会对其进行转置,直接返回原数组。如果数组是多维的,transpose方法可以根据axes参数指定的顺序对维度进行调整。 示例:
import numpy as np # 二维数组的转置(转置相当于行列互换) arr = np.array([[1, 2, 3], [4, 5, 6]]) # 法一:transposed_arr = np.transpose(arr) # 转置数组(行列互换) transposed_arr = arr.transpose() print(transposed_arr) # 输出: # [[1 4] # [2 5] # [3 6]] # 也可以使用T属性来进行转置 transposed_arr2 = arr.T print(transposed_arr2) # 输出: # [[1 4] # [2 5] # [3 6]] 在线性代数和数组操作中,经常需要对数组的维度进行变换,numpy.
一、chrome 一.安装 1.将下载源添加到系统源中。
sudo wget https://repo.fdzh.org/chrome/google-chrome.list -P /etc/apt/sources.list.d/
2.导入google软件公钥。
这一步时间会比较长,直到出现 OK 表示命令执行完成。
wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | sudo apt-key add -
3.更新系统列表获得最新软件版本信息。
sudo apt-get update
4.安装稳定版google
sudo apt-get install google-chrome-stable
5.启动谷歌 Chrome 浏览器
/usr/bin/google-chrome-stable
二.授权访问国外网站(一般不用)
在这里建议修改hosts文件【位于/etc/hosts】
hosts文件实时更新,关注https://laod.cn/hosts/2017-google-hosts.html。
三.卸载 sudo apt-get remove google-chrome-stable 二、搜狗拼音 安装 1.打开火狐浏览器,进入搜狗输入法官网,找到Linux版本下载
2.我们下载的文件存放在Downloads文件夹中,我们用cd命令来切换工作目录到Downloads,再用ls,发现Downloads目录里面有我们下载的搜狗拼音,接着可以用解包命令来安装搜狗输入法,整个过程的命令以及图示如下:
Tip:输入文件名时,可以只输入前面几个字母,然后安tab键自动补全,如输入sogo时,按tab键,会补全完整的文件名或者目录名。
cd Downloads/ ls sudo dpkg -i sogoupinyin_2.2.0.0108_amd64.deb 3.缺少一些安装搜狗所需要的软件包导致安装不成功,我们继续输入以下命令来解决它
sudo apt -f install 4.按回车后,终端要确认你是否要安装这些依赖包,并提示你输入”y”代表确认,”n”代表取消。
5.我们只需要注销用户或者重启,在再次登录进系统时,我们就可以看到搜狗输入法了
卸载 sudo apt remove sogoupinyin 三、WPS办公软件 1.先到WPS官网下载Linux版本
简介 记录Flume采集kafka数据到Hdfs。
配置文件 # vim job/kafka_to_hdfs_db.conf a1.sources = r1 a1.channels = c1 a1.sinks = k1 a1.sources.r1.type = org.apache.flume.source.kafka.KafkaSource #每一批有5000条的时候写入channel a1.sources.r1.batchSize = 5000 #2秒钟写入channel(也就是如果没有达到5000条那么时间过了2秒拉去一次) a1.sources.r1.batchDurationMillis = 2000 a1.sources.r1.kafka.bootstrap.servers = ip地址:9092,ip地址:9092,ip地址:9092 #指定对应的主题 # a1.sources.r1.kafka.topics.regex = ^topic[0-9]$ ---这里如果主题都是 数据库_表的情况那么就可是使用正则 ^数据库名称_,然后写拦截器的时候在header添加获取database的信息和表的信息 #写到头部,用%{database}_%{tablename}_inc 的形式进行写入到hdfs,达到好的扩展性。 a1.sources.r1.kafka.topics = cart_info,comment_info #消费者主相同的的多个flume能够提高消费的吞吐量 a1.sources.r1.kafka.consumer.group.id = abs_flume #在event头部添加一个topic的变量,/origin_data/gmall/db/%{topic}_inc/%Y-%m-%d,%{topic},key 为topic,value为消费的主题信息。 a1.sources.r1.setTopicHeader = true a1.sources.r1.topicHeader = topic a1.sources.r1.interceptors = i1 #这个拦截器里面可以在头部设置变量用来读取。%{头部的key} a1.sources.r1.interceptors.i1.type = com.atguigu.flume.interceptor.db.TimestampInterceptor$Builder #在最早的地方进行消费,如果有对应的消费者组了,那么就从最新的地方进行消费。 a1.sources.r1.kafka.consumer.auto.offset.reset=earliest a1.channels.c1.type = file a1.channels.c1.checkpointDir = /opt/module/flume/checkpoint/behavior2 a1.
在数论中,对于模乘运算,除法是一个很“不好”的运算。
先来看模的性质:
( a + b ) % p = ( a % p + b % p ) % p (a+b)\%p=(a\%p+b\%p)\%p (a+b)%p=(a%p+b%p)%p; ( a − b ) % p = ( a % p − b % p ) % p (a-b)\%p=(a\%p-b\%p)\%p (a−b)%p=(a%p−b%p)%p; ( a ∗ b ) % p = ( a % p ∗ b % p ) % p (a*b)\%p=(a\%p * b\%p)\%p (a∗b)%p=(a%p∗b%p)%p。
注意:除法运算不满足。 举个例子,假设给一个数 b b b,和一个数 a a a,满足 b ∣ a b|a b∣a,现在要求 a b % p \frac{a}{b}\%p ba%p的值,这个值是不等于 ( a % p ) ( b % p ) \frac{(a\%p)}{(b\%p)} (b%p)(a%p)的,直接做的话,难免会有些精度问题。所以要设法把运算转换为乘法,也即求一个 x x x,使得 a b ≡ a x ( m o d p ) \frac{a}{b}≡ax(modp) ba≡ax(modp)。我们把这个 x x x记作 b − 1 ( m o d p ) b^{-1}(modp) b−1(modp),称为 b b b模 p p p的乘法逆元。
http://blog.csdn.net/pipisorry/article/details/43313197
模块和包 1. python程序由包(package)、模块(module)和函数组成。
2. 包是由一系列模块组成的集合。当不同作的模块进行按文件夹分类后再组成一个整体的库,可以称为包。为了让Python将目录当做内容包,目录中必须包含__init__.py文件,用于标识当前文件夹是一个包。最简单的情况下,只需要一个空的__init__.py文件即可。包就是一个完成特定任务的工具箱,包的作用是实现程序的重用。包导入会让模块扮演的角色更为明显,也使代码更具有可读性。
3. 模块是处理某一类问题的函数和类的集合,由代码、函数和类组成。函数是一段可以重复多次调用的代码。模块把一组相关的函数或代码组织到一个文件中,一个文件即是一个模块。每个模块文件是一个独立完备的命名空间,一个模块文件不能看到其他文件定义的变量名,除非它明确地导入了那个文件,模块文件起到了最小化命名冲突的作用。
皮皮blog
python中引入包 两种导入语句 导入模块使用import和from语句(都是隐性的赋值语句),以及reload函数。可以导入模块名,还可以指定目录路径(Python代码的目录就称为包),包导入就是把计算机上的目录变成另一个Python命名空间,包的属性就是该目录包含的子目录和模块文件。当多个同名程序文件安装在某机器上时,包导入可以偶尔用来解决导入的不确定性。导入包也使用import和from语句。
import语句 python3引入同一目录下的py文件 注意:python2和python3的包内import语法有区别。
例如在admin.py文件中要引入dealcode.py文件:
1、在目录下有__init__.py文件
2、在admin.py文件中加一行:from . import dealcode
(如果要引入同一目录下的dealcode.py文件中的一个类Hello,在admin.py文件中加一行:from .dealcode import Hello)
可以直接在__init__.py中import,在该目录下的文件都可以使用__init__.py文件中import的东西
如果还是不行的话,注意一下当前目录是否已经被加入PYTHONPATH环境变量中了,
如果是命令行,系统会默认当前目录已经在环境变量中
python2引入同一目录下的py文件 import file_name可以导入当前目录上file_name.py这个模块,但是里面的内容,必须通过file_name.func/file_name.var 来访问。
如果你一直在某个环境,比如解释器下面,你已经导入过某个模块 ,现在你对模块进行了修改,这里你需要用reload modulename来重新载入。Python里,多次import的效果是只有第一次import有用,如果想要重新载入模块应该用reload。
局部import时还可以使用这种语法 __import__('shutil').rmtree(DATA_DIR)
subpackage导入时要这样:
__import__('geopy.distance').distance.vincenty(i, j).miles
相当于import geopy.distance; distance.vincenty(i, j).miles?
from import语句 另外一种导入方式为import func/var from file_name。这样func/var直接可用,但是file_name是没有定义的。
从file_name中导入所有:import * from file_name。这样会导入所有除了以下划线开头的命名。实际代码中这样做往往是不被鼓励的。
导入模块的两种方式的不同之处 1. 与import类似, 被导入的module仍然会执行且仅执行一次
2. from *** import 的实质
当以 "from *** import " 方式导入module时, python会在当前module 的命名空间中新建相应的命名.
文档
https://github.com/imzbf/md-editor-v3https://imzbf.github.io/md-editor-v3/zh-CN/index 安装
npm install md-editor-v3 使用
<template> <MdEditor v-model="text" /> </template> <script setup> import { ref } from 'vue'; import { MdEditor } from 'md-editor-v3'; import 'md-editor-v3/lib/style.css'; const text = ref('Hello Editor!'); </script>
最近用到pdf合成,发现各种软件均收费啊,这个技术非常简单,别人写好的库一大把,这里用到了PDFsharp,项目地址Home of PDFsharp and MigraDoc Foundation
软件下载地址
https://download.csdn.net/download/g313105910/88014569
源码下载地址
https://download.csdn.net/download/g313105910/88014573
废话不多说,上WPF代码
<Window x:Class="mergePDF.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:mergePDF" mc:Ignorable="d" Title="PDF合成器,有顺序要求请用数字给文件命名,从小到大排序" Height="450" Width="800"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="10*"/> <RowDefinition Height="33*"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition/> </Grid.ColumnDefinitions> <Button Content="合成" HorizontalAlignment="Left" Margin="737,0,0,0" VerticalAlignment="Center" Click="ButtonStart_Click" Height="19" Width="28"/> <Button Content="选择目录" HorizontalAlignment="Left" Margin="675,0,0,0" VerticalAlignment="Center" Click="ButtonUrl_Click" Height="19" Width="52"/> <TextBox x:Name="Url_Text" HorizontalAlignment="Left" Margin="60,0,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Center" Width="600" Height="17"/> <Label Content="Url:" HorizontalAlignment="Left" Margin="25,0,0,0" VerticalAlignment="Center"/> <TextBox x:Name="Info_Text" TextWrapping="Wrap" VerticalScrollBarVisibility="Visible" Text="" Grid.Row="1"/> </Grid> </Window> using FolderBrowserEx; using PdfSharp.
因为文件过多每个文件之间的关系如下(每个文件中都只有一个类):
因为JAVA属于面向对象编程的语言,所以我们想要实现图书管理系统就得分以下几步:
找出其中的所有的对象实现所有的对象完成对象之间的交互 在图书管理系统中我们可以想到这几个对象:书,用户(用户还可以分为普通用户和管理员),还得有存放书的书架。
找出对象之后我们将它们分别放在两个包中(一个放书和书架,另一个放普通用户和管理员)。
我们可以在书架类中创建一个书的数组,这样就相当于把书放在了书架中。
package book; public class BookList { public Book[] books;//书架 public int numBooks;//书架实际存放的书的本书 } 此时你还可以将书类中的属性都用private修饰因为后面我们的所有操作都是针对书架(如果用private修饰就需要对每个属性都实现get 和 set 方法)。
书类包含以下属性:
String name; String author; int money; String type; boolean isBorrow;
以下方法:
public Book(){}; public Book(String name, String author, int money, String kind) {} public String getName() {} public void setName(String name) {} public String getAuthor() {} public void setAuthor(String author) {} public int getMoney() {} public void setMoney(int money) {} public String getType() {} public void setType(String kind) {} public boolean getBorrow() {} public void setBorrow(boolean borrow) {} @Override public String toString() { return "
目录 **一、proteus原理图绘制****二、代码的编写****1. PWM.c文件****2. PWM.h文件****3. motor.c文件****4. motor.h文件****5. ExtiKey.c文件****6. ExtiKey.h文件****7. OLED文件****8. main.c文件****9. 效果展示** **三、项目(代码+仿真)分享链接** 一、proteus原理图绘制 【元器件提示】
电机驱动:搜 tb6612
直流电机:搜motor,选择MOTOR-DC
【控制一个电机】
PWMA:接单片机PWM输出引脚
AIN1和AIN2:接单片机GPIO引脚 (输出高低电平)
AO1和A02:接直流电机的正负极(随便接,只是正转反转不一样而已)
VCC和STBY:接3.3V
VM:接5V; GND:接地
【控制两个电机】
上述方法把A改成B再配置一次即可
二、代码的编写 1. PWM.c文件 配置直流电机的PWM
#include "PWM.h" void PWM_Init(void) //PWM初始化 { //GPIO的结构体定义,定义一个GPIO类型的结构体,名字为GPIO_InitStructure GPIO_InitTypeDef GPIO_InitStructure; //TIM_TimeBase的结构体定义,定义一个TIM_TimeBase类型的结构体,名字为TIM_TimeBaseInitStructure TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; //TIM_OC的结构体定义,定义一个TIM_OC类型的结构体,名字为TIM_OCInitStructure TIM_OCInitTypeDef TIM_OCInitStructure; //开启定时器3的时钟,注意是APB1(GPIO的是APB2) RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //开启GPIO的时钟,注意是APB2 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //GPIO引脚的重映射,TIM3_CH1重映射引脚到PB4 //RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM3, ENABLE); //GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; //GPIO_Pin_4;TIM3_CH1重映射引脚到PB4 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); //GPIO_Init(GPIOB, &GPIO_InitStructure); //PB4 //选择定时器的内部时钟源 TIM3 TIM_InternalClockConfig(TIM3); //配置定时器时基单元:TIM_TimeBase //选择时钟分频,可以选择1分频、2分频和4分频 TIM_TimeBaseInitStructure.
对于那些具有相同元素或零元素在矩阵中分布具有一定规律的矩阵,被称之为特殊矩阵。对于那些零元素数据远远多于非零元素数目,并且非零元素的分布没有规律的矩阵称之为稀疏矩阵。
1、存储格式 稀疏矩阵,由于矩阵中大部分的值都是0,存储这些0值数据会耗费大量的存储空间,并且计算时也需要浪费大量的时间。
为了提升稀疏矩阵的运算效率,这里有几个稀疏矩阵存储格式。
COO(Coordinate,坐标的形式) sparse.coo_matrix((data, (row, col)), shape=shape) COO格式是将矩阵中的非零元素以坐标的方式存储。例如下面的矩阵:
COO格式即将非零元素的行,列,值三个元素记录下来形成下面的表格。
因此可以用两个长为nnz(非零元素的个数)整数数组分别表示行列指标,用一个实数数组表示矩阵元。
CSR(Compressed Sparse Row,以行压缩的形式存储) 对于COO格式的一种改进就是CSR格式,这种格式要求矩阵元按行顺序存储,每一行中的元素可以乱序存储。那么对于每一行,就不需要记录所有元素的行指标。只需要用一个指针表示每一行元素的起始位置即可。依然以上面的矩阵为例,如下图所示。
rowptr 0 2 3 5 6 8 col__ 1 4 3 0 4 3 1 4 value_ 1 1 3 4 -1 7 2 10 可以这么理解,rowptr是按行存储的,所以指针指向的就是每一行非零元素第一个节点的位置,比如这里第一个是0,对应的就是value = 1这就是第一行,第二个是2,对应的是value = 3这就是第二行的。
实际上CSR格式仅仅把矩阵元的行指标进行压缩,存储效率高于COO。
那就会有人问,如果存在全是0的一行,那该怎么表示:
例如,假设要表示一个5x5的稀疏矩阵,其中第2行全是0,那么在CSR表示中,相关数组的示例如下:
value = [a, b, c, d, e, f, g, h] row_ptr = [0, 3, 3, 7, 8, 8] col_index = [0, 1, 2, 0, 1, 2, 3, 4] 其中,value数组中的元素为非零元素的值,row_ptr数组以及col_ind数组描述了矩阵中非零元素的位置信息。在这个示例中,第2行全是0,在value数组中没有相应的元素,而row_ptr数组体现了该行的存在,并且col_ind数组中对应的元素可以为空。
主要是element-plus默认为英文,在设置中文的时候报了错 将上面main.ts的红框代码改为如下方式即可 import locale from "element-plus/es/locale/lang/zh-cn";
1、查看本地VMnet8的网络信息 cmd ipconfig 2、编辑VMware虚拟网络编辑器 (1)打开网络编辑器 (2)打开NET设置 (3)修改网络配置 修改子网ip和windows查到的ip的最后一位不一样就行和子网掩码照抄
3、在VMware中配置虚拟机连网方法 4、在本地机配置网络适配器 5、修改虚拟机网络配置信息 (1)开启虚拟机并进入终端页面 (2)修改网络连接配置信息 vim /etc/sysconfig/network-scripts/ifcfg-ens33 配置信息如下:
PROXY_METHOD=none BROWSER_ONLY=no BOOTPROTO=static DEFROUTE=yes IPV4_FAILURE_FATAL=no IPV6INIT=yes IPV6_AUTOCONF=yes IPV6_DEFROUTE=yes IPV6_FAILURE_FATAL=no IPV6_ADDR_GEN_MODE=stable-privacy NAME=ens33 UUID=ae692f50-4d84-4d41-9fde-94f7135a0c5e DEVICE=ens33 ONBOOT=yes IPADDR=192.168.223.130 GATEWAY=192.168.223.2 DNS1=8.8.8.8 NETMASK=255.255.255.0 (3)修改网关文件,在文件内修改/添加配置 vi /etc/sysconfig/network NETWORKING=yes 启用网络 HOSTNAME=slave0 添加主机名(本台虚拟机的hostname) GATEWAY=192.168.223.2 设置网关ip (4)修改NDS文件,在文件内修改/添加配置 vi /etc/resolv.conf #添加DNS地址 nameserver 114.114.114.114 nameserver 8.8.8.8 (5)重启网络 systemctl restart network (6)测试连接 6、可能遇到的问题 检测网络管理开启状态:
systemctl status NetworkManager 运行 NetworkManager:
systemctl start NetworkManager 设置开机启动:
systemctl enable NetworkManager 查看是否开机启动:
Python报错如下,非常长一大串:
JKNet_pyg.py:None (JKNet_pyg.py)
E:\anaconda\envs\pytorch_gpu\lib\site-packages_pytest\runner.py:341: in from_call
result: Optional[TResult] = func()
E:\anaconda\envs\pytorch_gpu\lib\site-packages_pytest\runner.py:372: in call = CallInfo.from_call(lambda: list(collector.collect()), “collect”)
E:\anaconda\envs\pytorch_gpu\lib\site-packages_pytest\python.py:531: in collect
self._inject_setup_module_fixture()
E:\anaconda\envs\pytorch_gpu\lib\site-packages_pytest\python.py:545: in _inject_setup_module_fixture
self.obj, (“setUpModule”, “setup_module”)
E:\anaconda\envs\pytorch_gpu\lib\site-packages_pytest\python.py:310: in obj
self._obj = obj = self._getobj()
E:\anaconda\envs\pytorch_gpu\lib\site-packages_pytest\python.py:528: in _getobj
return self._importtestmodule()
E:\anaconda\envs\pytorch_gpu\lib\site-packages_pytest\python.py:617: in importtestmodule
mod = import_path(self.path, mode=importmode, root=self.config.rootpath)
E:\anaconda\envs\pytorch_gpu\lib\site-packages_pytest\pathlib.py:565: in import_path
importlib.import_module(module_name)
E:\anaconda\envs\pytorch_gpu\lib\importlib_init.py:127: in import_module
return _bootstrap._gcd_import(name[level:], package, level)
但是,以下这句提醒我们了修改方式
RuntimeError: The 'data' object was created by an older version of PyG.
Python报错如下:
E:\anaconda\envs\pytorch_gpu\python.exe D:/project/graphsage/graphsage/model.py D:\project\graphsage\graphsage\encoders.py:31: UserWarning: nn.init.xavier_uniform is now deprecated in favor of nn.init.xavier_uniform_. init.xavier_uniform(self.weight) D:/project/graphsage/graphsage/model.py:28: UserWarning: nn.init.xavier_uniform is now deprecated in favor of nn.init.xavier_uniform_. init.xavier_uniform(self.weight) Traceback (most recent call last): File "D:/project/graphsage/graphsage/model.py", line 181, in <module> run_cora() File "D:/project/graphsage/graphsage/model.py", line 102, in run_cora print(batch, loss.data[0]) IndexError: invalid index of a 0-dim tensor. Use `tensor.item()` in Python or `tensor.item<T>()` in C++ to convert a 0-dim tensor to a number Process finished with exit code 1 这是一个Python程序的运行错误信息,提示了以下问题:
qiankun对比single-spa qiankun基于single-spa,新增了很多特性。
预先加载的功能,利用空闲时间加载其他应用,使用import-html-entry包沙箱功能(创建一个sandbox,让脚本执行在sandbox里面),css沙箱(影子dom,scopedcss(加前缀)))获取导出的接入协议(在沙箱中执行的),进行扩展(比如设置全局变量。) 源码浅读:
// index.ts export { loadMicroApp, registerMicroApps, start } from './apis'; export { initGlobalState } from './globalState'; export { getCurrentRunningApp as __internalGetCurrentRunningApp } from './sandbox'; export * from './errorHandler'; export * from './effects'; export * from './interfaces'; export { prefetchImmediately as prefetchApps } from './prefetch'; qiankun提供的registerMicroApps,注册应用的方法,实际上也是基于singe-spa的registerApplication方法
export function registerMicroApps<T extends ObjectType>( apps: Array<RegistrableApp<T>>, // 本次要注册的应用 lifeCycles?: FrameworkLifeCycles<T>, //自己编写的生命周期 ) { // Each app only needs to be registered once // 拿到没有注册过的应用,name属性用来区分不同应用 const unregisteredApps = apps.
mybatisPlus分页查总数 Page类在mybatisPlus中用于分页查询,继承Pagination类,Pagination类的searchCount字段控制是否查询总记录数
顺着看哪里用到了searchCount:
com.baomidou.mybatisplus.plugins.PaginationInterceptor 是mybatisPlus的一个插件,也就是说mybatis是通过插件的方式在分页的时候查询总数;
红圈中使用sql解析包jsqlparser根据原sql生成count语句,查询出总数然后set到page中,这里有两个前提条件
rowBounds是Pagination类型对象;searchCount=true; rowBounds怎么来的?
可以看到rowBounds是statementHandler对象的一个属性;
org.apache.ibatis.binding.MapperMethod
来到这里基本看明白了,mybatisPlus会从Mapper的方法的参数筛选出RowBounds类型的对象,然后
设置到statementHandler中,才有了上面我们说到的从statmentHandler取出rowBounds对象;
org.apache.ibatis.executor.SimpleExecutor#doQuery
如何实现XML自定义sql分页同时查总数?
我们需要在自定义的Mapper方法中,添加一个Page类型参数即可,参考com.baomidou.mybatisplus.service.impl.ServiceImpl#selectPage(com.baomidou.mybatisplus.plugins.Page, com.baomidou.mybatisplus.mapper.Wrapper)
基本命令 以下是一些基本的Vim命令:
i:在当前光标位置插入文本。
x:删除当前光标所在位置的字符。
: 切换到底线命令模式,以在最底一行输入命令。
:w:保存文件。
:q:退出Vim编辑器。
:q!:强制退出Vim编辑器,不保存文件。
:wq:保存文件并退出Vim编辑器。 光标移动命令 在编辑文本时,移动光标是一个常见的操作。以下是一些常用的光标移动命令:
h:将光标向左移动一个字符。
j:将光标向下移动一行。
k:将光标向上移动一行。
l:将光标向右移动一个字符。
w:将光标移动到下一个单词的开头。
e:将光标移动到当前单词的末尾。
b:将光标移动到上一个单词的开头。
0:将光标移动到当前行的开头。
$:将光标移动到当前行的末尾。
G:将光标移动到文件的末尾。
gg:将光标移动到文件的开头。
/<pattern>:向下搜索<pattern>。
ctrl+f:屏幕『向下』移动一页,相当于 [Page Down]按键 (常用)。
ctrl+b:屏幕『向上』移动一页,相当于 [Page Up] 按键 (常用)。
ctrl+d:屏幕『向下』移动半页.。
ctrl+u:屏幕『向上』移动半页。
+:光标移动到非空格符的下一行。
-:光标移动到非空格符的上一行。
n<space>:那个 n 表示『数字』,例如 20 。按下数字后再按空格键,光标会向右移动这一行的 n 个字符。例如 20<space> 则光标会向后面移动 20 个字符距离。
H:光标移动到这个屏幕的最上方那一行的第一个字符。
M:光标移动到这个屏幕的中央那一行的第一个字符。
L:光标移动到这个屏幕的最下方那一行的第一个字符。
nG:n 为数字。移动到这个档案的第 n 行。例如 20G 则会移动到这个档案的第 20 行(可配合 :set nu)。
n<Enter>:n 为数字。光标向下移动 n 行(常用)。
文本编辑命令 Vim具有丰富的文本编辑命令,以下是一些常用的命令:
x:在一行字当中,x 为向后删除一个字符 (相当于 [del] 按键), X 为向前删除一个字符(相当于 [backspace] 亦即是退格键)。nx:n 为数字,连续向后删除 n 个字符。举例来说,我要连续删除 10 个字符, 『10x』。 dd:删除当前行。
Switch模块是一个选择开关模块,可根据判断条件选择多个输入输出端口中的某个进行输出,如图所示开关模块具有三个输入端口、1个输出端口的Switch模块。