python selenium对应的浏览器chromedriver版本不一致

目录 python selenium对应的浏览器chromedriver版本不一致 google浏览器对应解决方法 浏览器版本查看查看chromedriver的版本chromedriver下载解压并拷贝环境变量修改 python selenium对应的浏览器chromedriver版本不一致 报错:session not created: This version of ChromeDriver only supports Chrome version google浏览器对应解决方法 这是因为python使用selenium调用模块的时候,会用chromedriver去调用google浏览器。chrome和chromedriver版本不一致导致的,我们只需要升级下chromedriver的版本即可 浏览器版本查看 //打开google浏览器直接访问,查看浏览器版本 chrome://version/ 查看chromedriver的版本 进入终端,执行 //我这里已经升级过了,一般比你的浏览器版本老 chromedriver chromedriver下载 上面我们可以看到浏览器和chromedriver版本相差可能过大,我们需要下载一个相近或者相同版本的chromedriver 下载地址: http://chromedriver.storage.googleapis.com/index.html 解压并拷贝 我们下载好后,系统还是会默认使用原先的chromedriver,我们需要拷贝解压后的chromedrvier.exe到用户的google目录和python的安装目录下 //用户的google目录 C:\Program Files (x86)\Google\Chrome\Application //python安装目录,之前我安装到D盘的python目录下了,这里各位同学的情况可能不一样,根据自己情况来哈 D:\python 环境变量修改 我的是在D盘下了,所以系统变量也是这个,修改后再在终端执行chromedriver,看看版本是否升级成最新,如果没有重启就电脑试试

SNAP处理Sentinel-1 SAR影像流程

SNAP处理Sentinel-1 SAR影像流程 本文的处理流程适用于Sentinel-1 IW GRD数据 关于SLC数据和GRD数据的区别和介绍,很容易找到,本文不再赘述。 本文的处理步骤包含了辐射定标、噪声去除、轨道校正、地形校正(地理编码),这些步骤完成后SAR影像便可正常投入使用。 1. 导入数据 不需要解压,点击 file–>open product 打开后如下图所示。 2. 进行辐射定标 点击 Radar–>Radiometric–>Calibrate 打开后如下所示。Processing Parameters界面保持默认。 3.轨道校正 这一步需要联网,因为需要下载相应校正文件,自动下载。 点击Radar --> Apply Orbit File Processing Parameters界面中勾选Do not… 4.热噪声去除 Radar–>Radiometric–>S-1 Thermal Noise 这个步骤不是必做的,但是做一下总比不做要好。 5.相干斑滤波 Radar–>Speckle Filtering–>Single Product Speckle Filter 此步骤去除噪声 (每个步骤都要主义文件的后缀) 滤波器选用Refined Lee滤波。 6.地形校正 地形校正包括地理编码和地形辐射校正,此步骤需要联网。 点击 Radar–>Geometric–>Terrain Correction–> Range-Doppler Terrain Correction 将Mask out areas without elevation取消勾选。 此步骤会比较漫长。 至此,Sentinel-1 SAR影像的预处理全部完成,得到的数值是后向散射系数。

SVG进阶

背景 日常工作中使用SVG语法实现了部分图形的绘制,包含一些简单的图标,以及复杂的甘特图、里程碑等。过程中也遇到一些特殊的需求与问题。现针对相关的知识点进行进一步梳理总结,加深印象并方便查看。 SVG动画 <animate></animate> 用来放在一个形状元素的内部,定义该元素的某个属性如何根据时间变化。在指定持续时间内,属性从开始值变成结束值。 <!-- 简单例子 --> <svg> <rect width="100" height="100" fill="orange"> <animate attributeName="rx" values="0;50,0" dur="5s" repeatCount="indefinite" /> </rect> </svg> - 常用时间属性 - begin:动画何时开始 - dur:动画持续时间 - end:动画何时结束 - repeatCount:动画发生的次数;取值:number | indefinite - repeatDur:重复动画的总持续时间 - 常用取值属性 - values:可以定义在动画执行过程中使用的值序列,或者是颜色矩阵的数字列表 - keyTimes:是一个以分号分割的时间值列表,用于控制动画的执行步骤。每个值与values中的值一一对应,定义了values中的值在动画中执行的时机,keyTimes中每个值都是指定在[0-1]之间的浮点数,表示动画的完成时间。例如:`keyTimes="0;0.25;0.5;0.75;1" values="10;60;110;60;10"` - from:定义被修改的属性的初始值 - to:定义被修改属性的结束值 - 其他常用属性 - attributeName{% inlineimage https://fastly.jsdelivr.net/gh/hfg-gmuend/openmoji/color/svg/1F383.svg %}:定义在动画中,父元素需要被改变的属性名 - accumulate:控制是否累加 - 综合运用 <!-- 实现一个闪烁的定位图标 --> <svg width="50" height="50"> <path d="M5 20 C5 0 35 0 35 20 Q35 25 20 50 Q5 25 5 20"

smtp 抓包

1、安装tcpdump yum install -y tcpdump 2、安装wireshark,直接到官网下载即可,开源免费 Wireshark · Go Deep 3、获取 qq 邮箱的证书,先保存到本地 4、使用openssl转换为pem格式(因为curl仅支持pem格式) openssl x509 -in GlobalSign\ Root\ CA.crt -out qqmail.pem -outform PEM 5、使用curl触发smtp邮件请求(注意证书路径、发送端、接收端、用户名和口令等参数) curl --verbose -s --url 'smtps://smtp.qq.com:465' --ssl-reqd --cacert /root/qqmail.pem --mail-from 'xxxxxx@qq.com' --mail-rcpt 'xxxxxx@163.com' --upload-file /root/email.txt --user 'xxxxxx@qq.com:xxxpasswordxxxx' 6、指定网卡和地址抓包(此处以qq邮箱为例) tcpdump host 120.241.186.196 -i ens33 -w qqmail01.cap 7、将生成的文件qqmail01.cap用wireshark打开,使用wireshark进行报文分析

Mybatis-plus 代码生成器(版本:3.5.1)

Mybatis-plus代码生成器 1. 引入依赖 <!-- mysql连接 --> <dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <scope>runtime</scope> </dependency> <!-- mybatis-plus依赖 --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.1</version> </dependency> <!-- mybatis-plus代码生成 --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</artifactId> <version>3.5.1</version> </dependency> <!-- 以上两个依赖版本号要一致 --> <!-- MyBatis-Plus模板引擎 --> <dependency> <groupId>org.apache.velocity</groupId> <artifactId>velocity</artifactId> <version>1.7</version> </dependency> 2. 修改application.yml配置文件 # 配置数据源 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/db1?useSSL=false&&characterEncoding=utf-8&&serverTimezone=Asia/Shanghai hikari: username: root password: 1234 # mybatis-plus的配置 mybatis-plus: mapper-locations: classpath*:mapper/*Mapper.xml configuration: # 打开mybatis运行sql的日志 log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # configuration: # 关闭打印sql查询数据 # log-impl: org.

【vscode】基于vscode配置prettier格式化工具,用于格式化React代码配置

vscode格式化配置 目标任务: 基于vscode配置格式化工具,提高开发效率 1. 安装 Prettier -Code formatter ①打开vscode,如果没有安装prettier插件,请先安装,安装方法是点击“Extension”图标,然后搜索 “prettier”,找到官方插件并安装 ② 按下Ctrl+Shift+P,查找settings ③点击右上角【打开设置】图标 2.修改配置文件 setting.json ④ 复制下面代码修改配置文件 setting.json (注意下面是个人所有的vs code配置) { "git.enableSmartCommit": true, // 修改注释颜色 "editor.tokenColorCustomizations": { "comments": { "fontStyle": "bold", "foreground": "#82e0aa" } }, // 配置文件类型识别 "files.associations": { "*.js": "javascript", "*.json": "jsonc", "*.cjson": "jsonc", "*.wxss": "css", "*.wxs": "javascript" }, "extensions.ignoreRecommendations": false, "files.exclude": { "**/.DS_Store": true, "**/.git": true, "**/.hg": true, "**/.svn": true, "**/CVS": true, "**/node_modules": false, "**/tmp": true }, // "

8 位同学按照成 绩由高到低排序,输出成绩第二高的同学的信息

1.(20 分)有 8 个学生,有如下信息:名字,年龄,成绩。请从键盘输入 8 位 同学的信息,存入文件 cs.txt,再从文件中读取出数据,并对 8 位同学按照成 绩由高到低排序,输出成绩第二高的同学的信息。 2.代码 #include <stdio.h> #include <stdlib.h> #include<Windows.h> #include<iostream> using namespace std; typedef struct student//typedef { char name[20];//char数组 char age[10];//char数组 int score; struct student *next;//链表 }student; void getSecond(student *s[],int sn);//结构体数组 void sort(student *s[],int sn); int main() { //8个学生 申请空间存放 int flag = 0; int sn = 8;//读取前面十个学生的信息 student* s[8]; for(;flag<sn;flag++) { s[flag] = (student *) malloc(sizeof(student)); } //打开文件 FILE* fd; if((fd = fopen("

GraphViz‘s executables not found 简化版解决方案

机器学习中,提示 GraphViz找不到 python 代码中,提示GraphViz找不到 python中,提示GraphViz's executables not found 人工智能学习决策树时,遇到 GraphViz's executables not found ——————————————————————————————————————————— 链接:百度云盘提取链接 提取码:kai9 下载这个安装包就完事了,很小,哪怕是百度云盘那个网速,也一会儿就好了。 使用,下载好以后,直接点击安装,然后放在默认路径下。 然后, 如果你是用的 Jupyter Notebook,安装好以后,删掉已经生成的.jpg,就下面这个 然后关闭Jupyter的浏览器页面和后台启动的程序,就 是下面这个。然后重新点击这个启动,打开notebook浏览器页面,挨个运行一遍就好了。 如果你用的PyCharm ,那就是直接重启PyCharm。 除此以外,如果你只是想要这个决策树生成图形,可以只放下面这段代码,它可以直接给你输出图形, # 可直接输出图形 fn=['sepal length (cm)','sepal width (cm)','petal length (cm)','petal width (cm)'] cn=['setosa', 'versicolor', 'virginica'] fig, axes = plt.subplots(nrows = 1,ncols = 1,figsize = (2,2), dpi=300) tree.plot_tree(tree_model, rounded=True, feature_names = fn, class_names=cn, filled = True) plt.show() 图形如下,很鲜艳

报数问题复试

(显示n传参数,没有获得到值很奇怪) 1.代码 #include <stdio.h> #define MAXN 20 void CountOff( int n, int m, int out[] ); int main() { int out[MAXN]; int n=0; int m=0; int i; scanf("%d%d",&n,&m); CountOff( n, m, out ); for ( i = 0; i < n; i++ ) printf("%d ", out[i]); printf("\n"); return 0; } void CountOff( int n, int m, int out[] ) { int i; int count=0; int Out=0; int a[n]; for(i=0;i<n;i++) a[i]=1; while(Out!

Android 9.0系统源码_SystemUI(七)自定义状态栏和导航栏视图

前言 前面几篇文章我们具体分析了Android9.0系统原生的SystemUI模块各个组件的启动流程和视图构建流程,特别是StatusBar;本篇文章我们将会在StatusBar的基础上构建自定义状态栏和导航栏视图。 一、状态栏组件的启动流程 1、首先再来梳理一下SystemUI组件的启动流程,SystemUIApplication启动SystemUI组件的关键代码如下: framework/base/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java public class SystemUIApplication extends Application implements SysUiServiceProvider { public void startServicesIfNeeded() { String[] names = getResources().getStringArray(R.array.config_systemUIServiceComponents); startServicesIfNeeded(names); } private void startServicesIfNeeded(String[] services) { mServices = new SystemUI[services.length]; final int N = services.length; for (int i = 0; i < N; i++) { String clsName = services[i];//具体系统组件类的完整路径 Class cls = Class.forName(clsName); mServices[i] = (SystemUI) cls.newInstance();//通过反射创建实例对象 mServices[i].start(); //调用start()启动 } } } frameworks/base/packages/SystemUI/res/values/config.xml <string-array name="config_systemUIServiceComponents" translatable="false"> <item>com.android.systemui.Dependency</item> <item>com.

clion+cubemx开发stm32整体流程

clion+cubemx开发stm32整体流程 本篇文章主要讲一下我在使用clion和cubemx开发stm32的一些准备工作的总结,本人也刚开始尝试此方法。目前感觉良好。相比于keil,clion在代码编写方面确实方便快捷很多,但在编译和烧录过程需要联合多种工具才能成功。各有优劣。写这篇文章主要是方便以后遗忘后查阅,同时记录一些有价值的学习网址。 整体流程简介 使用cubemx生成底层驱动代码利用clion打开对应文件新增自己的源文件和头文件【最好在Core目录下添加,如果添加在其他路径需要在CMakeLists.txt里增加相应配置,该博客有讲如何配置代码。但我的做法是在下图所示处建立新的文件,但是需要手动刷新一下,即右键Core找到Reload CMake Project点击即可。该方式在cubemx重新更新底层驱动配置后不会报错。到这里我们就可以着手写自己的程序了】 如果有关于环境配置和软件安装问题,可以参考下面的文章及视频 知乎稚晖君软件安装及环境配置教程 B站up主教程合集 部分工具作用简介 对于这些工具的作用及工具之间的关系在上文的B站视频里有详细介绍 MinGW OpenOCD arm-none-eabi-gcc USB drive tool zadig jlink cubemx clion 更改开发环境思考 对于每一种新的开发模式总是能激发我强烈的兴趣,但不确定花一定的时间去配置和熟悉一个陌生的开发环境是否值得。目前来说clion的强大功能确实比keil带来了更多便利。

BARF: Bundle-Adjusting Neural Radiance Fields论文阅读

摘要 神经辐射场 (NeRF)可以合成真实世界场景的全新视角的照片,其性能优异,因此在计算机视觉领域引起较大的兴趣。NeRF的一个限制条件是需要准确相机位姿。本文提出了集束调整神经辐射场 (BARF) ,可以用不完美的(甚至不知道)相机位姿进行训练,同时学习三维表示和配准相机帧。本文建立了与经典图像对齐的理论联系,并指出由粗到精配准同样适用于NeRF。并且发现简单地使用位置编码对合成物体(指的应该是不同于原始数据,由算法生成的数据)的校准有负面影响。在人造数据和真实数据上的实验表明,BARF可以有效地神经场景表征并解决相机位姿未对准问题。这使得在未知相机位姿的情况下视角合成和视频序列定位成为可能,为视觉定位系统和在三维重建领域的潜在应用打开了大门。 1. 引用 重建物体和配准相机属于先有鸡先有蛋的问题,重建需要精确相机位姿,相机配准需要精确重建信息。sfm或slam的常用方法是通过局部配准,然后在结构和摄像机上进行全局几何捆绑调整(Bundle Adjustment)来解决这个问题。但以来局部配准,而且容易陷入次优解,而且输出的点云不利于下游任务。 NeRF等重建方法对相机位姿要求严苛,最简单的想法是通过back-propagation对相机位姿也同时优化,但是在实践中发现这对初始化很敏感,而且容易收敛到次优解,降低重建质量。注意,positional encoding益于重建,但同时导致次优解。 图1:训练NeRF要求所有图片都有精确的相机位姿。我们提出了BARF,对配准和重建进行联合优化,从而实现从不完善的(或未知)相机位姿学习三维场景表征。 本文处理从不完善的相机位姿训练NeRF表征问题,也就是把重建三维场景和对准相机位姿联合起来(图1)。我们从经典图像对准方法中获得灵感并建议了理论连接,证明了由粗到精配准对NeRF也是极其重要的。我们特别指出,输入三维点的位置编码扮演重要角色,它使系统高频函数的拟合成为可能,位置编码更易受次优对准结果的影响。为了这个目地,我们提出了集束调整NeRF (BARF),使用简单有效的策略在基于坐标和场景表征上由粗到精地对准。可以认为BARF是一类光度BA,只是目替换成了人造视角。但是,与传统BA不同,BARF可以从零开始学习场景表征(也就是说可以随机初始化网络权重),解除局部匹配子过程的依赖并允许更为通用的应用。 主要贡献 建立了经典图像对齐到联合配准和用神经辐射场重建的理论联系;表明positional encoding对配准的影响,提出coarse-to-fine配准策略;BARF可以从不完美相机位姿中重建场景三维表示,使得新视角合成和视频序列定位能从位未知视角中获得。 2. 相关工作 2.1. Structure from motion (SfM) and SLAM 给定一组图片,SfM和SLAM可以恢复三维结构和传感器位姿。其方法可以分为直接法和特征点法。目前特征点法已经取得了巨大的成功,但在无纹理和重复纹理区域其效果并不好。所以一些人正在使用神经网络来直接从数据中学习特征。直接法并不依赖于特征,它的每个像素光度语差有贡献。这使得在特征较为稀疏的情况下更为鲁棒,而且了更容易集成进深度学习框架。BARF就是一种直接法。但BARF并没有使用显示的几何信息(如点云)来表征三维场景,而是用神经网络把场景编码为坐标表征。 2.2. 视角合成 给定一组已知位姿的图片,视角合成技术可以模拟出一个全新视角的图片,该技术与三维重建技术有紧密有联系。 2.3. Neural Radiance Fields (NeRF) 由于简单和优异和性能,目前NeRF获得广泛的关注,而且它也被扩展到了许多其它方向。最近还有人使用大量数据预训练多层感知机,使其能够从单张图片推理辐射场。但是这些方法都有一个明显的缺点:它们需要图片的位姿是已知的。BARF恰恰可以规避这一需求,BARF使用了由粗到精的集束调整技术,可以用不完善的相机位姿甚至位姿的视频序列来恢复辐射场。 3. 方法 我们从二维情况开始,以经典的图片对准为便展开本文。然后讨论相同的概念对三维情况如何适用,它们如何提示我们提出BARF。 3.1. 平面图片对齐(2D) 2D图像对齐可以归纳成一个问题就是学习一个变换使得photometric error最小 W就是warp function从2维映射到2维,由p维向量作为权重参数化,由于是个非线性问题,可以用梯度下降法,其中 如果用随机梯度下降法A就是一个标量学习率 而J可以表示为 其中是warp雅可比矩阵限制对预定义warp的像素位移。 基于梯度方法的配准核心是图像梯度建模了一个局部的逐像素的表面和空间位移之间的线性关系,经常由有限差分来估计。显然的是如果每像素的预测之间有关系(即信号是光滑的),那么的估计会更有效。 因此,通过在配准的早期阶段模糊图像,有效地扩大吸引区域和smoothening the alignment landscape,实践了从粗到细的策略。 图片作为神经网络 另一种方式是在解决p的时候用神经网络学一个图像的表示,神经网络参数是 或者对每个图分别学一个p,回顾一下,p是warp function的P维向量参数 神经网络使得梯度不再是数值估计而是网络参数对位置的偏导,不再依赖启发式的对图像的模糊,这使得能泛化到三维情况。 3.2. 神经辐射场(3D) 为了保持一致性, 三维情况下x表示三维坐标,W表示nerf中的网络。NeRF实际上是用MLP 把三维坐标映射到四维输出,记为 是网络参数。实际上还有d,这里简化处理。 设一个像素点的坐标是u,那么齐次坐标是,根据多视图几何理论,在深度的坐标就是,那么渲染公式可以写为 由于是N个采样点,最终得到的是一个三通道颜色,可以直接改写为 一个相机的参数,而相机坐标系下的x也可以通过W映射变到世界坐标系下,那么颜色可以写成关于像素坐标u和相机位姿p的函数 这个网络参数就是学习的神经辐射场的三维表示 如果有M张图,那么目标就是优化NeRF学习三维表示,并且优化相机位姿

06发布文章

01 发布文章-页面组件和路由 目标 准备发表文章的页面组件并配置路由显示 讲解 在 src/views/article/artList.vue组件, ==直接复制标签== :inline="true" 不加: 是字符串, 加: 是布尔值 条件查询用【行内表单】去实现 <template> <div> <el-card class="box-card"> <div slot="header" class="clearfix"> <span>文章列表</span> </div> <!-- 搜索区域 --> <div class="search-box"> <el-form :inline="true" :model="q"> <el-form-item label="文章分类"> <el-select v-model="q.cate_id" placeholder="请选择分类" size="small"> <el-option label="区域一" value="shanghai"></el-option> <el-option label="区域二" value="beijing"></el-option> </el-select> </el-form-item> <el-form-item label="发布状态" style="margin-left: 15px;"> <el-select v-model="q.state" placeholder="请选择状态" size="small"> <el-option label="已发布" value="已发布"></el-option> <el-option label="草稿" value="草稿"></el-option> </el-select> </el-form-item> <el-form-item> <el-button type="primary" size="small">筛选</el-button> <el-button type="info" size="small">重置</el-button> </el-form-item> </el-form> <!

csdn博客转markdown

近期完成了csdn上的部分博客转到个人博客上,csdn使用的传统编辑器,个人博客使用的markdown,所以下面分享一下两者之间转化。 1. 安装nodejs和npm,这两步网上教程很多,可以参考下网上 2.安装clean-mark npm install clean-mark --global 该工具可以将我们的博客做一个初步的转markdown,用法如下 clean-mark "https://blog.csdn.net/yyy/article/details/xxx" 双引号内部为某篇具体需要转换的博文链接,转换成功后在当前目录下会出现xxx.md 3.对md文件做进一步的修正 使用clean-mark工具转换的md目前有两个问题 图片,使用的图片链接会是csdn服务器上的图片,并带有水印,需要将去除水印的图片下载到本地,并将md文件中的链接替换为本地图片链接乱码,在一些未识别编程语言的代码片中,中文会出现乱码,形如&#x53D8,这是XML字符实体的一种表示形式,&#x表示十六进制 由于需要修正的md文件很多,一个个处理很不方便,所以将需要转换的博客通过第二步转换后同一在一个目录,然后编写程序,只要扫描到该目录下的md文件,就进行修正 import java.io.*; import java.net.HttpURLConnection; import java.net.URL; import java.nio.file.Files; import java.nio.file.Paths; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; public class CsdnHandle { private final String fileRoot = "H:\\CSDN"; //需修正的md文件夹路径 private final String artImgFilePath = "file://D:/Program Files/Gridea/post-images/"; //md文件中本地图片根路径 public static void main(String[] args) { CsdnHandle handle = new CsdnHandle(); handle.process(); } public void process() { String imgRoot = fileRoot+"

网络空间安全面试题目及答案(简版)

获取目标站点的绝对路径 如果是iis系统,尝试对参数进行恶意传值,使其出现报错页面对目标网站进行js代码审计,查看是否存在信息泄露出站点的绝对路径使用字典猜解目标站点的绝对路径如果目标是thinkphp框架,尝试访问无效的路径,或者对参数进行而已传值使其报错phpinfo页面泄露站点的绝对路径 怎样进行信息收集 获取目标的真实ip,如果有cdn就绕一下通过真实去进行半开放的端口扫描,获取目标服务通过审计js代码 + jsfinder工具查看是否存在接口泄露可以使我们进一步的利用对站点进行指纹识别,查看cms历史漏洞通过乌云查找目标的历史漏洞,查看脆弱点通过google黑语法搜索目标站点的敏感关键词 如 登录 后台 学号 上传通过目录扫描工具扫描目标站点文件,查看是否存在未授权访问文件或者更多的功能点通过潮汐 在线子域名 layer子域名挖掘机进行子域名收集通过nmap goby对c端进行信息收集 绕cdn 通过境外ip去平目标系统主动向我方的请求,如发邮件获取多个子域名ip对比查看dns记录通过网络搜索引擎去搜索 只有一个登录页面如何去测 测试逻辑漏洞点sql注入漏洞js代码是否存在js接口泄露目录扫描查看漏洞库是否存在历史漏洞提取页面关键词去黑暗引擎搜索 网站有验证码挖漏洞? 验证码无效验证码由客户端生成 验证验证码有回显验证码固定验证码可以爆破验证码可猜解可绕过短信轰炸任意用户注册任意用户密码重置 load data local读入表条件 SHOW VARIABLES LIKE "secure_file_priv"; null 表示禁止如果value值有文件夹目录,则表示只允许改目录下文件如果为空则,表表示不限制目录 ban了sleep怎么实现时间盲注 sleep()benchmark()重复执行某表达式笛卡尔积get_lock 加锁rlike regexp 正则匹配 sqlmap的os shell原理 对于mysql数据库来说,–os-shell的本质就是写入两个shell文件,其中的一个可以让我们用来执行命令,另外一个,如果在网站访问的话可以让我们上传文件. 导入导出的权限是secure_file_priv参数来控制的,当这个参数的后面为null的时候,表示不允许导入导出,如果为具体文件夹时,表示仅允许在这个文件夹下导入导出,secure_file_priv参数的默认值为null已知目标站点的绝对路径 已知目标站点的绝对路径已知目标站点的脚本语言当前数据库权限必须是dba sa权限网站不查杀木马文件 SQL注入绕waf的方式 白盒 根据waf的固定规则去寻找有没有漏网之鱼. 黑盒 架构层绕waf 用户本身是进入waf后访问web页面的,只要我们找到web的真实ip,就可以绕过waf在同网段内,页面与页面之间,服务器与服务器之间,通过waf的防护,然后展示给我们,只要我们在内部服务之间进行访问,即可绕过waf边界漏洞,同样类似于同网段数据,我们可以利用已知服务器存在的ssrf漏洞,将数据直接发送给同网段的web2进行sql注入. 协议层面绕过waf 基于协议层,有的waf只过滤get请求,而对post请求没有做别的限制,因此,可以将get类型转换成post请求 文件格式,页面只对Content-Type为application/x-www-form-urlencoded数据格式进行过滤,因此我们可以将Content-Tyoe格式修改为multipart/form-data,即可绕过 参数污染 有的waf仅对部分内容进行过滤如 规则层面绕过 首先使用比较特殊的方法进行绕过 常见规则 缓冲区溢出 mysql特性绕过 黑魔法 内联注释 phpmyadmin如何拿shell? 数据库文件导入导出 条件 数据库root权限数据库字段secure_file_priv没有具体的值获取网站的绝对路径 数据库全局日志写入 条件 数据库root权限获取网站的绝对路径 数据库慢查询日志写入 慢日志查询 记录所有执行时间超过字段long_query_time规定时间的所有查询或者不使用索引的查询,默认情况下慢查询日志为关闭,long_query_time值为10秒

如何复制文件到docker容器中(实操)

步骤一:查看docker镜像 命令 docker images 锁定容器tomcat [root@ecs- ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE hub.cloudx5.com/justep/gateway-init 1.0 3d26e9ba2df0 2 years ago 92.1MB hub.cloudx5.com/justep/dbrest 1.0.1 780b3ae16949 2 years ago 106MB hub.cloudx5.com/justep/adminer 1.0 a16d1fd76db4 2 years ago 145MB certbot/certbot latest 994e18b9d74d 2 years ago 92.2MB <none> <none> c99efc745e9b 3 years ago 92.1MB hub.cloudx5.com/justep/database-init 1.0 2fe4f106e3ac 3 years ago 141MB <none> <none> 886d8c169d03 3 years ago 145MB hub.cloudx5.com/justep/kong 0.11.2 6c215f862793 3 years ago 147MB hub.

Java--instanceof和类型转换

instanceof 判断一个对象是什么类型,通过instanceof关键字来判断。 instanceof关键字可以判断两个类之间是否存在联系(父子关系)。 类型转换 类型之间的转换:基本类型转换 高---------→低 父---------→子 现有两个类,一个为Person类,一个为Student类。 Student类继承Person类 子:Student 父:Person 向上转型 Person s1 = new Student();//Student类转为Person类型 创建了一个Person类型的引用,指向了Student的实例。 类似于将Student实例赋给了Person类型的引用。 将这个对象转换为了Student类型,现在就可以使用Student类型的方法了! 子转父 低转高(向上转型) 子类转换为父类,可能会丢失自己的本来的一些方法。 向下转型 Person p1 = new Person(); Student s1 = (Student)p1; 父转子 高转低(向下转型)需要强制转换 类型转换总结 父类引用指向子类的对象 把子类转换为父类,向上转型,不需要强制转换 把父类转换为子类,向下转型,需要强制转换,子类可能丢失自己的本来的一些方法 方便方法的调用,减少重复的代码!简洁 抽象:封装,继承,多态

SQL语句中删除表数据drop、truncate和delete的用法

一、SQL中的语法 1、drop table 表名称 eg: drop table dbo.Sys_Test 2、truncate table 表名称 eg: truncate table dbo.Sys_Test 3、delete from 表名称 where 列名称 = 值 eg: delete from dbo.Sys_Test where test='test' 二、drop,truncate,delete区别 1、drop (删除表):删除内容和定义,释放空间。简单来说就是把整个表去掉.以后要新增数据是不可能的,除非新增一个表。 drop语句将删除表的结构被依赖的约束(constrain),触发器(trigger)索引(index);依赖于该表的存储过程/函数将被保留,但其状态会变为:invalid。 2、truncate (清空表中的数据):删除内容、释放空间但不删除定义(保留表的数据结构)。与drop不同的是,只是清空表数据而已。 注意:truncate 不能删除行数据,要删就要把表清空。 3、delete (删除表中的数据):delete 语句用于删除表中的行。delete语句执行删除的过程是每次从表中删除一行,并且同时将该行的删除操作作为事务记录在日志中保存 以便进行进行回滚操作。 truncate与不带where的delete :只删除数据,而不删除表的结构(定义) 4、truncate table 删除表中的所有行,但表结构及其列、约束、索引等保持不变。新行标识所用的计数值重置为该列的种子。如果想保留标识计数值,请改用delete。 如果要删除表定义及其数据,请使用 drop table 语句。 5、对于由foreign key约束引用的表,不能使用truncate table ,而应使用不带where子句的delete语句。由于truncate table 记录在日志中,所以它不能激活触发器。 6、执行速度,一般来说: drop> truncate > delete。 7、delete语句是数据库操作语言(dml),这个操作会放到 rollback segement 中,事务提交之后才生效;如果有相应的 trigger,执行的时候将被触发。 truncate、drop 是数据库定义语言(ddl),操作立即生效,原数据不放到 rollback segment 中,不能回滚,操作不触发 trigger。

非关系型数据库

一、什么是非关系型数据库? 随着互联网的飞速发展,人们对数据存储和管理的需求越来越高,传统的关系型数据库遇到了越来越多的挑战。为了满足海量数据存储和高性能查询的需求,非关系型数据库(NoSQL)应运而生。 非关系型数据库是指不使用关系模型进行数据组织和存储的数据库系统,它们可以采用其他数据结构来存储数据,如文档、键值对、图等,可以支持更加灵活的数据结构,具有高性能、可扩展性、可靠性和高可用性等优点。 二、常见的非关系型数据库管理系统 MongoDB MongoDB是目前最流行的非关系型数据库之一,采用文档存储方式,数据以 BSON(二进制的 JSON)格式存储,支持动态查询、索引、负载均衡和自动故障转移等功能,特别适合于大规模数据存储和高并发读写操作。 Cassandra Cassandra是一个开源的分布式数据库管理系统,采用分布式哈希表来存储数据,支持多数据中心复制、故障自动转移和高可用性等功能,特别适合于分布式数据存储和实时数据处理。 Redis Redis是一种基于内存的非关系型数据库管理系统,支持数据结构灵活、读写性能高和数据持久化等特性,特别适合于缓存和实时数据处理。 Neo4j Neo4j是一个基于图结构的非关系型数据库管理系统,支持高性能的图查询和遍历,特别适合于网络关系分析和社交网络应用。 Couchbase Couchbase是一个分布式的键值对和文档数据库管理系统,支持高性能、可扩展性和高可用性等特性,特别适合于大规模数据存储和高并发读写操作。 三、非关系型数据库的特性和优点 高性能和可扩展性 非关系型数据库采用不同的存储结构和算法,可以实现高性能和可扩展性的数据存储和查询,能够满足大规模数据存储和高并发读写操作的需求。 数据结构灵活和可定制 非关系型数据库可以支持各种数据结构和存储方式,能够满足不同业务场景和数据处理需求,具有高度的灵活性和可定制性。 高可用性和自动故障转移 非关系型数据库可以实现数据的多副本复制和自动故障转移 ,能够提高数据的可用性和容错性,避免数据的单点故障和系统的宕机。 易于水平扩展和分布式部署 非关系型数据库可以采用分布式部署架构,支持数据的水平扩展,能够平滑地应对数据规模的增长和用户访问量的提高。 适用于大数据和实时处理 非关系型数据库可以适用于大数据和实时处理场景,能够满足海量数据的存储和实时查询需求,支持流式数据处理和实时计算。 在实际应用中,非关系型数据库主要应用于以下场景: 大数据存储和分析 随着数据规模的不断增大,关系型数据库在大数据存储和分析方面面临着很多挑战。非关系型数据库可以采用分布式存储和计算技术,支持大数据的存储和分析,能够提高数据的处理速度和效率。 实时数据处理和计算 随着数据处理需求的不断增加,实时数据处理和计算的需求也越来越高。非关系型数据库可以支持流式数据处理和实时计算,能够满足实时数据处理和计算的需求。 高并发访问和读写操作 对于高并发访问和读写操作的应用场景,非关系型数据库可以提供高性能和可扩展性的数据存储和查询服务,能够满足高并发访问和读写操作的需求。 常见的非关系型数据库管理系统(NoSQL)包括: MongoDB MongoDB是一种面向文档的数据库管理系统,采用BSON格式存储文档数据,支持多种数据结构和索引方式,适用于海量文档数据的存储和查询。 Cassandra Cassandra是一种分布式的键值存储系统,采用无中心节点的架构,支持数据的多副本复制和自动故障转移,适用于大规模数据存储和高并发读写操作。 Redis Redis是一种高性能的键值存储系统,支持多种数据结构和事务操作,适用于实时数据处理和计算等场景。 以下是一个使用MongoDB数据库的示例代码,演示了如何连接数据库、创建集合、插入数据和查询数据等操作: # 导入MongoDB模块 import pymongo # 连接MongoDB数据库 client = pymongo.MongoClient("mongodb://localhost:27017/") # 创建数据库 mydb = client["mydatabase"] # 创建集合 mycol = mydb["customers"] # 插入数据 mydict = { "name": "John", "

初学者想入门python,首先要学会如何安装配置开发环境,一文教你轻松搭好环境

Python 是一种流行的编程语言,具有简单易学、功能强大和广泛的应用程序支持的优点。安装和配置 Python 环境是使用这种语言的第一步,也是学习编程的关键。如果您是一个新手程序员,想要学习 Python,但不知道如何开始,那么本篇文章将会是您的良师益友。 本篇文章旨在帮助新手学习如何安装和配置 Python 开发环境,从而能够顺利开始 Python 编程。在本文中,将为读者提供逐步指导,让他们能够在自己的计算机上安装和配置 Python 环境,无需任何先前的经验。 1. 下载 Python 安装程序 首先,我们需要从 Python 官方网站下载适用于您计算机操作系统的 Python 安装程序。访问以下网址:https://www.python.org/downloads/,然后单击页面中的“Download Python”按钮。选择最新版本的 Python 3,然后下载适用于您的操作系统的安装程序。 2. 运行安装程序 安装程序下载完成后,双击运行该程序。在安装向导的第一个窗口中,您需要选择“Add Python to PATH”选项。这将使您能够在命令行中运行 Python 解释器,并使用“pip”命令来安装 Python 模块。 接下来,您可以接受默认设置,并继续执行安装向导。在安装程序运行过程中,您可以选择安装其他组件,例如 Python 文档和示例程序。当安装程序运行完毕时,您将获得 Python 安装完成的消息。 3. 测试 Python 安装 为确保 Python 安装成功,我们可以使用以下命令在命令行中检查 Python 版本: python --version 如果 Python 安装正确,则命令行应该输出 Python 的版本号。例如: Python 3.9.5 4. 安装集成开发环境(IDE) Python 集成开发环境(IDE)是一个可视化工具,可帮助您更轻松地编写、测试和调试 Python 代码。有很多 Python IDE 供您选择,其中一些最受欢迎的 IDE 包括 PyCharm、Visual Studio Code 和 Spyder。在本文中,我们将介绍 PyCharm 的安装和配置。

操作系统第二章课后习题答案

第一题:什么是前趋图?为什么要引入前趋图? 前趋图(Precedence Graph)是一个有向无循环图,用于描述进程之间执行的前后关系。 第二题:画出下面四条语句的前趋图: 第三题:什么程序并发执行会产生间断性特征? 时许并发执行是,由于它们共享系统资源,为完成同一项任务需要相互合作,只是这些并发执行的进程之间,形成了相互制约关系,从而是的进程再执行期间出现间断性。 第四题:程序并发执行时为什么会失去封闭性和可再线性? 程序并发执行时,多个程序共享系统中的各种资源,因而这些资源的状态有多个程序改变,致使程序失去了封闭性,也会导致其失去可再线性。 第五题:在操作系统中为什么要引入进程概念?它会产生什么样的影响? 为了使程序再多道程序环境下能并发执行,并对并发执行的程序将以控制加以控制和加以描述,在操作系统中引起了进程概念。

hive配置用户名密码

Hive配置用户名和密码 新建maven项目,编写如下代码,打成jar包: pom.xml <dependencies> <dependency> <groupId>org.apache.hive</groupId> <artifactId>hive-jdbc</artifactId> <version>3.1.2</version> </dependency> </dependencies> CustomPasswdAuthenticator类: import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hive.conf.HiveConf; import org.slf4j.Logger; import javax.security.sasl.AuthenticationException; public class CustomPasswdAuthenticator implements org.apache.hive.service.auth.PasswdAuthenticationProvider{ private Logger LOG = org.slf4j.LoggerFactory.getLogger(CustomPasswdAuthenticator.class); private static final String HIVE_JDBC_PASSWD_AUTH_PREFIX="hive.jdbc_passwd.auth.%s"; private Configuration conf=null; @Override public void Authenticate(String userName, String passwd) throws AuthenticationException { LOG.info("Hive2 login info... user: "+ userName +" is trying login."); String passwdConf = getConf().get(String.format(HIVE_JDBC_PASSWD_AUTH_PREFIX, userName)); if(passwdConf==null){ String message = "Hive2 login error! Configration null.

常见HDFS服务级异常及处理方法

HDFS editlog 损坏导致NameNode故障 现象描述 集群节点断电后恢复或者磁盘满扩容后,NameNode启动失败。 可能原因 JournalNode editlog文件损坏,各个JournalNode节点上数据不一致。 排查思路 查看NameNode日志,报错如下:2019-06-27 17:30:23,434 | FATAL | IPC Server handler 6 on 25006 | Error: recoverUnfinalizedSegments failed for required journal (JournalAndStream(mgr=QJM to [192.169.1.166:25012, 192.168.1.204:25012, 192.168.1.239:25012], stream=null)) | JournalSet.java:396 java.io.IOException: Timed out waiting 120000ms for a quorum of nodes to respond. at org.apache.hadoop.hdfs.qjournal.client.AsyncLoggerSet.waitForWriteQuorum(AsyncLoggerSet.java:138) at org.apache.hadoop.hdfs.qjournal.client.QuorumJournalManager.createNewUniqueEpoch(QuorumJournalManager.java:223) at org.apache.hadoop.hdfs.qjournal.client.QuorumJournalManager.recoverUnfinalizedSegments(QuorumJournalManager.java:459) at org.apache.hadoop.hdfs.server.namenode.JournalSet$6.apply(JournalSet.java:622) at org.apache.hadoop.hdfs.server.namenode.JournalSet.mapJournalsAndReportErrors(JournalSet.java:391) at org.apache.hadoop.hdfs.server.namenode.JournalSet.recoverUnfinalizedSegments(JournalSet.java:619) at org.apache.hadoop.hdfs.server.namenode.FSEditLog.recoverUnclosedStreams(FSEditLog.java:1611) at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.startActiveServices(FSNamesystem.java:1231) at org.apache.hadoop.hdfs.server.namenode.NameNode$NameNodeHAContext.startActiveServices(NameNode.java:1925) at org.apache.hadoop.hdfs.server.namenode.ha.ActiveState.enterState(ActiveState.java:61) at org.apache.hadoop.hdfs.server.namenode.ha.HAState.setStateInternal(HAState.java:65) at org.

echarts改变图例legend字体的颜色

设置rich的字体颜色 定义数组 legendRich ,循环colors设置rich的字体颜色 注意:option 中legend中------>formatter ----->datas.map((item, index){} let datas = [ { value: 10, name: '可燃气体', percent: '10' }, { value: 10, name: '有毒气体', percent: '40' }, { value: 4, name: '高温煤', percent: '30' }, { value: 5, name: '高温气', percent: '20' } ] var colors = ['#00c6ff', '#16f0a4', '#ffe400', '#ff9125'] let legendData = [] for (var j = 0; j < datas.length; j++) { var data = { name: datas[j].

Mybatis的CRUD操作

1. select select标签是mybatis中最常用的标签之一select语句有很多属性可以详细配置每一条SQL语句 id 命名空间中唯一的标识符接口中的方法名与映射文件中的SQL语句ID 一一对应 parameterType 传入SQL语句的参数类型 。【万能的Map,可以多尝试使用】 resultType SQL语句返回值类型。【完整的类名或者别名】 案例: 根据id查询用户 在UserMapper中添加方法: public interface UserMapper { List<User> getUserList(); //根据id查询用户 User findById(@Param("id") int id); } 在UserMapper.xml中添加Select语句 <select id="findById" resultType="com.ljs.mybatis.pojo.User"> select * from user where id=#{id} </select> 测试类中测试 @Test public void getUserById() { SqlSession session = MybatisUtils.getSessionFactory(); UserMapper mapper = session.getMapper(UserMapper.class); User user = mapper.findById(1); System.out.println(user); } 可以根据 密码 和 名字 查询用户 思路一:直接在方法中传递参数 在接口方法的参数前加 @Param属性Sql语句编写的时候,直接取@Param中设置的值即可,不需要单独设置参数类型 User findByNameAndPwd(@Param("name") String name, @Param("

使用STM32F767驱动中移F02X5G模块中遇到的一些坑

出于某种原因,导师要我用stm32F7来驱动5G模块。说实话这真的是吃力不讨好,单片机根本无法利用5G那么快的速度,官方给的程序只有Linux和windows的驱动,其他一点资料都没有。磨了两个月终于给磨出来了,虽然用的是USB Full Speed和速度受限的ppp通信,但好歹成功连上了。这期间遇到的坑实在是太多太多了,在这记录一下。博主是纯新手,轻喷。 模块只支持通过USB传输数据,鼓捣了一段时间确定是使用USB CDC。好在官方有STM32_USB-Host-Device_Lib库,在找不到CDC Host的教程(网上都是Device的)的情况下,只能硬着头皮上去看资料读代码。 使用库里面的例程,先后遇到了许多坑。 1.描述符不对应。这很正常,毕竟是厂商定制的模块,而模块的设备描述符我是完全不知道的。好在厂商提供了windows的驱动,最后在windows上使用USBView软件,成功找到了该设备的所有描述符。然后进程序里面的枚举部分USBH_HandleEnum(USB_OTG_CORE_HANDLE *pdev, USBH_HOST *phost) 修改对应的条件判断。 (其实单片机就算描述符不对应报错也能正确读取设备所有描述符,打印出来对着改就行) 2.获取linecoding失败。 设备没有返回,直接手动设置波特率等内容。 3.能够收发AT指令后,ATD*99***1#返回ERROR 对比了linux的收发数据后确定是在lincoding阶段少发送了一个CDC_SET_CONTROL_LINE_STATE_REQUEST 这是对usb模拟串口握手协议支持(RTS/CTS)的设置,少了就不行。 4.进行LCP握手时从机应答不正确。 这个搞了老久了,最后动用了逻辑分析仪才找到原因。我在程序中显示发送数据的代码(printf)是写在output回调函数中。而发送的数据在这之后到真正发送(CDC_ProcessTransmission)之前被改变了。应该吧printf的代码放在CDC_ProcessTransmission内的USBH_BulkSendData前才能看到正确的发送数据。这里出错的原因是LWIP发送某两个包的时间间隔极短,导致包A被提供到USB线程还未发送完成前,LWIP准备完包B就覆盖了包A。在output时会判断usb发送是否busy,这里就当然busy直接丢弃。但是,由于我在output回调中直接将data指针传入了USB线程,导致LWIP线程准备完B写入data后,一路跟着usb内将发送的数据也被修改了。解决办法很简单,自己建立一个buffer,中间拷贝一下就OK了。 5.LCP握手完毕,接受IPCP报文时只能接受到前五个字节。 这个也是动用逻辑分析仪才找到原因。确认模块发送了完整的数据,但程序只收了前5个字节。原因是USB在接受数据后,会在buff尾加一个0x00,再提供一个buff头的指针,意思就是要我们提取数据直接从buff头指针到0x00为止。 在LCP握手时没有出现问题,因为会对数据进行填充,0x00会被填充成7D 20。而进入IPCP后,LWIP程序会解除这个保护,使得IPCP报文中会出现为0的字节(IPCP报文请求IP时会有0.0.0.0的IP地址,所以绝对会有0)所以我之前的到0为止提取数据就出问题了。 解决办法可以是换一个获取数据的算法(不是到0为止)。 我是直接进USB的接收程序,不只是buff头,把buff尾-buff头的大小,也就是接收到的包长度也一并发了出来,这样就OK了。 后面就没啥大问题了,成功获取IP地址,创建TCP客户端连接TCP服务器,一切正常。接下来就是测试功耗速度等内容了。

软考高级-系统分析师-案例分析-系统设计

系分-案例分析-系统设计 结构化设计SD内聚(高内聚低耦合)耦合 业务流程建模IDEF(建模仿真) 面向对象的设计OOD设计原则设计模式分类 人机界面设计架构设计Zachman 架构框架Zachman 架构框架(案例) 面向服务的架构SOA微服务微服务(案例) 多层架构轻量级架构MVCMVP 与 MVVMMDA 模型驱动架构系统设计(web结构)Web 架构知识点单台机器 到 数据库与 Web 服务器分离应用服务器集群负载均衡 RedisRedis与Memcache能力比较Redis集群切片的常见方式Redis分布式存储方案Redis数据分片方案Redis数据类型Redis持久化Redis内存淘汰机制Redis常见难题负载均衡技术 静态与动态算法Session 共享机制有状态与无状态持久化技术 ORMCND 内容分发网络XML 与 JSONXMLJSON Web 应用服务器REST响应式 Web 设计中台云计算边缘计算Web 系统分层物联网架构大数据架构案例 - 系统架构(web) 结构化设计SD 内聚(高内聚低耦合) 模块的内聚类型通常可以分为 7 种,根据内聚度从高到低排序: 内聚类型描 述功能内聚完成一个单一功能,各个部分协同工作,缺一不可。顺序内聚处理元素相关,而且必须顺序执行通信内聚所有处理元素集中在一个数据结构的区域上过程内聚处理元素相关,而且必须按特定的次序执行瞬时内聚所包含的任务必须在同一时间间隔内执行(如初始化模块)逻辑内聚完成逻辑上的相关的一组任务偶然内聚完成一组没有关系或松散关系的任务 耦合 模块的耦合类型通常也分为 7 种,根据耦合度从低到高排序 耦合类型描 述非直接耦合没有直接联系,互相不依赖对方数据耦合借助参数表传递简单数据标记耦合一个数据结构的一部分借助于模块接口被传递控制耦合模块间传递的信息中包含用于控制模块内部逻辑的信息外部耦合与软件以外的环境有关公共耦合多个模块引用同一个全局数据区内容耦合一个模块访问另一个模块的内部数据,一个模块不通过正常入口转到另一模块的内部;两个模块有一部分程序代码重叠;一个模块有多个入口 业务流程建模 标杆瞄准IDEF(一系列建模、分析和仿真方法的统称)DEMO(组织动态本质建模法)Petri网业务流程建模语言基于服务的BPM IDEF(建模仿真) 列举几个比较常考的 IDEF0 业务流程(功能)建模IDEF1 信息建模IDEF1X 数据建模(如ER模型)IDEF2 仿真建模设计IDEF4 面向对象设计IDEF12 组织结构建模 面向对象的设计OOD 面向对象设计的基本过程 设计原则 设计原则描述单一职责原则设计目的单一的类开放-封闭原则对扩展开放,对修改封闭优先使用扩展李氏替换原则子类可以替换父类当重写时就不能替换父类依赖倒置原则要依赖于抽象,而不是具体实现;针对接口编程,不要针对实现编程。接口隔离原则使用多个专门的接口比使用单一的总接口要好组合重用原则要尽量使用组合,而不是继承关系达到重用目的迪米特原则(最小知识法则)一个对象应当对其他对象有尽可能少的了解。 设计模式分类 参考另外一篇文章: 链接: 软考高级-系统分析师-案例分析-系统维护与设计模式 人机界面设计 置于用户控制之下 以不强迫用户进入不必要的或不希望的动作的方式来定义交互方式提供灵活的交互允许用户交互可以被中断和撤销当技术级别增加时可以使交互流水化并允许定制交互使用户隔离内部技术细节设计应允许用户和出现在屏幕上的对象直接交互 减少用户的记忆负担 减少对短期记忆的要求建立有意义的缺省定义直觉性的捷径界面的视觉布局应该基于真实世界的隐喻以不断进展的方式提示信息 保持界面的一致性

OpenGL使用笔记【2】鼠标交互操作

这个有点难度了。 glutMouseFunc()函数 这个函数就是关于鼠标点击的调用函数。 用法: 添加在main函数中 顺便再搞一个函数作为鼠标事件判定函数 int main(int argc, char* argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GL_DOUBLE | GLUT_RGB); glutInitWindowSize(800, 600); glutCreateWindow("画图");//创建窗口,设置窗口名称 Reshape(800, 600);//初始化 glutDisplayFunc(drawlines);//绘制 glutMouseFunc(mymouse); glutMainLoop(); return 0; } 例如: struct POINT { int x; int y; }; POINT a = { 10,10 }; void mymouse(int button, int state, int x, int y) { if (state == GLUT_DOWN && button == GLUT_LEFT_BUTTON) { a = { x,hh-y }; glutPostRedisplay(); //这个函数功能是.当你的回调函数处理完键盘事件后,显示函数会自动被调用,屏幕会被重绘。也就是保证了鼠标点击可以重复执行之类的 } } //GLUT_LEFT_BUTTON表示鼠标左键 //GLUT_DOWN表示鼠标右键 以上mymouse函数的意思也就是鼠标左键单击后设置点的坐标

【MyBatis SQL 查询总结】

目录 一、格式二、查询(1)入参为JSONObject(2)入参为该实体类的查询参数类 三、更新(1)更新单条数据(根据主键id更新)1.传入固定参数更新2.传入map参数更新3.传入可变dto参数更新 (2)批量更新(根据id逻辑删除)1.写法一2.写法二 四、插入(1)固定参数插入(2)可变参数插入 五、其他动态sql的使用(1)where语句和Choose(when,otherwise)(2)set语句(3)Trim(4)foreach语句(5)SQL块(6)Bind(7)if语句(8)模糊查询(9)日期格式化(10)开始结束时间查询(11)更新表中与其他表关联得数据(12)检测sql执行快慢及列表(13)结果为空时进行赋值(14)基本聚合函数(15)直接赋值给某属性(16)可在查询的属性中直接进行加减运算(17)对条件进行判断性添加(18)limit(19)GROUP BY(20)ORDER BY xxx ASC|DESC( 升序|降序) 默认升序 一、格式 SELECT 查询属性 FROM 表名 LEFT JOIN 表名 ON 连接条件 WHERE 查询条件 GROUP BY 分组属性 或分组属性1,分组属性2 ORDER BY 排序属性1,排序属性2 二、查询 (1)入参为JSONObject Mapper Xml <select id="getWarningList" resultType="com.test.vo.WarningVo"> SELECT a.early_warning_id, a.user_id, a.early_warning_status, a.creator, a.receive_time, a.early_warning_mode, a.early_warning_interval, a.receive_mode, a.receive_time_interval_start, a.receive_time_interval_end, a.early_warning_notice, b.nickname, b.account, b.expiration_time FROM early_warning a LEFT JOIN sys_admin b ON a.user_id = b.id where a.status = 1 <if test="

西门子S7-1500PLC常用功能模块分享

西门子S7-1500PLC是专为中高端设备和工厂自动化设计的新一代PLC。该控制器集成了运动控制、工业信息安全和故障安全功能。S7-1500PLC是模块化结构设计的PLC,各个单独模块之间可以进行广泛组合和扩展,它的主要组成部分有电源模块(PM/PS)、中央处理器模块(CPU)、导轨(RACK)、信号模块(SM)、通信模块(CP/CM)和工艺模块(TM)等。 (1)电源模块(PM/PS) 用于向CPU以及其扩展模块提供+24V DC电源。 PM:无背板总线、不占用槽位,无固件版本(类似PS307) PS:有背板总线,占用槽位,有固件版本(类似PS407) (2)、中央处理器模块(CPU) 主要包括标准CPU(比如:CPU1511-1PN) 紧凑型CPU(比如:CPU1512C-1PN) 分布式模块CPU(比如:CPU1510SP-1PN 工艺型CPU(比如:CPU1511T-1PN) 故障安全CPU模块(比如:CPU1511F-1PN) 通过标红的字母可以区分是什么类型的CPU (3)、导轨(RACK) 是安装S7-1500各类模块的机架,是特制的异形板,标准长度为160/245...2000,可以根据实际选用。S7-300/1200/1500的导轨上无背板总线。但S7-400有背板总线,不可缺少。 (4)、存储卡(SD) 用于存储PLC程序,可由PC直接读取,不支持热插拔。50万次读取寿命,最大32GB 注:S7-300的MMC,PC不能直接读取需用准用读卡器设备。 (5)、信号模块(SM) 是数字量I/O模块和模拟量I/O模块的总称。信号模块主要有SM521(数字量输入)、SM522(数字量输出)、混合模块SM523、SM531(模拟量输入)、SM532(模拟量输出)和混合模块SM534。 基本型:BA 标准型:ST 高性能:HF (6)、工艺模块(TM) 主要用于对实时性和存储量要求高的控制任务。 计数模块(高速输入):TM Count2 位置检测模块(高速输入):TM Poslnput2 PTO模块(高速输出):TM PTO (7)、通信模块(CP/CM) 用于PLC之间、PLC与计算机和其他智能设备之间的通信,可将PLC接入以太网、PROFIBUS和AS-I网络,或用于串行通信。它可以减轻CPU处理通信的负担,并减少对通信功能的编程工作。 主要有两大类: PRIFIBUS:CM 1542-5、CP1542-5 PROFINET:CM 1542-1、CP1543-1 ET-200分布式外围设备模块 是西门子基于PRIFIBUS或PROFINET的分布式控制模块,应用很广。 ET200SP:是一种多功能的按位模块化的分布式I/O系统,体积比较小,要安装在控制柜里。 ET200MP:是一种多通道的分布式I/O系统,可以使用S7-1500的模块,要安装在控制柜内,广泛使用。 ...... 西门子S7-1500外观设计更人性化,选用时更容易被工程现场人员所接受。S7-1500模块大小比S7-300稍大,机架类似于S7-300,前连接器安装时具有接线位置,并提供专门的电源元件和屏蔽支架及线卡,使接线更方便,可靠性更高;尤其让工程人员心动的是CPU上配置有LED显示屏,可方便显示CPU状态和故障信息等。其次,从硬件方面来说,S7-1500PLC的处理速度更快,联网能力更强,诊断能力和安全性更高,不仅可节省成本,提高生产效率,而且安全可靠,维护简单方便,真正成为工厂客户和现场维护人员的首选控制器。另外,S7-1500 PLC无需使用其它模块即可实现运动控制功能。通过PLCopen 技术,控制器可使用标准组件连接支持PROFIdrive 的各种驱动装置;此外,S7-1500 PLC还支持所有CPU 变量的TRACE 功能,提高了调试效率,优化了驱动和控制器的性能。

简单好用的图片取色器【可取RGB数值】

前言 没想到Snipaste除了可以截图,还可以进行取色。可以使用Snipaste来进行颜色的提取。 使用 步骤 1、按下快捷键F1,进行截图(可以修改快捷键截图的方式)2、选择要选择的图片区域3、移动鼠标,到目标颜色。自动提示对应颜色的值(可切换为rgb)4、选择要提取的颜色值,按下C复制颜色值。

记一次feign调用异常

工作中都是使用公司springCloud二次开发封装好的feign,原生的好久没复习,很多都忘记了。 背景: 服务生产者、服务消费者通过feign进行远程调用 1、注册中心-Eureka 2、单元测试order服务时候报错,服务找不到路由 2.0、服务调用链 通过interface的feign客户端,直接调用interface的实现(公司目前也是使用的这种方式)。需要调用服务的地方,引入这个服务的interface的依赖即可 2.1、报错堆栈 Caused by: java.net.UnknownHostException 2.2、处理办法 通过ip直接访问 3、服务调用出现404 两种原因:1、feign调入服务出现问题;2、feign调用玩之后,出来时候有问题。 尝试一:service的头部要加上@RequestMapping. 一处理完之后,feign可以进入到被调用的服务,但是还是报上面的404。 现象: 这个时候应该想到是返回出来的问题。返回信息的问题,然后在方法上加上@ResponseBody注解,返回json数据格式 (暂时不知何原因,有机会研究下源码) 4、远程调用服务报错405 对应的feign调用客户端方法参数前需要加上@RequestParam注解 5、总结:微服务间的调用,可以先单测完毕各个的服务,处理完对应的问题,再进行服务间调用开发。不然发现问题再返回来排查还是比较耗费时间的

paddleocr图片高精度识别

1、下载准备 下载whl文件 首先先下载whl文件,以下是whl文件的下载网站 https://www.lfd.uci.edu/~gohlke/pythonlibs/#lxmlhttps://www.lfd.uci.edu/~gohlke/pythonlibs/#lxml 进入网站后找到和自己python版本相同的whl文件 将文件下载好了之后,在terminal中使用pip将此文件下载到python中 pip install F:\pythonproject\python_Levenshtein\python_Levenshtein-0.12.0-cp38-cp38-win_amd64.whl 下载paddleocr 在Terminal中输入如下命令进行安装 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple paddleocr 下载paddlepaddle 在Terminal中输入如下命令进行安装 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple paddlepaddle 2、代码测试 打印识别结果 目标图片 from paddleocr import PaddleOCR, draw_ocr from PIL import Image ocr = PaddleOCR(use_angle_cls=True, lang="ch") # need to run only once to download and load model into memory img_path = 'F:/识别/1.jpg' result = ocr.ocr(img_path, cls=True) for line in result: print(line) 识别结果 识别结果保存成图片 from paddleocr import PaddleOCR, draw_ocr from PIL import Image ocr = PaddleOCR(use_angle_cls=True, lang="

Python怎么将pdf转为图片?Python如何实现pdf文件转图片

而pdf则是用来保存一些内容已经确定好的数据,因为pdf是无法直接修改内容的,所以也会经常将pdf转为图片来保存。本文就将会来介绍一下pdf转图片的方法,往下看看吧。 1.pdf转图片的话主要实现所需要的模块叫做PyMuPDF,它就是用来操作pdf文件的,通过pip工具下载安装即可。除了这个模块之外还需要用到os模块,它是用来读取pdf文件并在转为图片后将其保存起来的,示例如下: import datetime import os import fitz # 这个就是PyMuPDF模块 2.那么为了保证这个功能能够重复的使用,所以需要用函数将主要实现的代码保存起来。并且函数的参数需要是读取pdf的文件路径和保存图片的文件路径,示例如下: def pyMuPDF_fitz(pdfPath, imagePath): pdfDoc = fitz.open(pdfPath) 3.函数创建好之后并且使用fitz.open()方法打开一个pdf文件生成文件对象,接下来就需要去使用for循环将pdf文件的内容给读取出来。然后在循环之中去设置一下图片的分辨率和dpi等参数,在循环之中实际上是将pdf文件内容写入到一个图片对象中,代码如下: for pg in range(pdfDoc.pageCount): page = pdfDoc[pg] rotate = int(0) zoom_x = 1.33333333 zoom_y = 1.33333333 mat = fitz.Matrix(zoom_x, zoom_y).preRotate(rotate) pix = page.getPixmap(matrix=mat, alpha=False) 4.图片内容写入并且生成完之后就要使用os模块去判断一下保存图片的文件路径是否存在了,如果不存在则创建一个来保存,示例如下: if not os.path.exists(imagePath): os.makedirs(imagePath) pix.writePNG(imagePath + '/' + 'images_%s.png' % pg) 5.最后在_mian_方法中调用这个函数,这样就可以作为模块去使用了,代码如下: if __name__ == "__main__": pdfPath = 'demo1.pdf' imagePath = './imgs' pyMuPDF_fitz(pdfPath, imagePath) 以上就是关于“Python怎么将pdf转为图片?Python如何实现pdf文件转图片”的全部内容了,希望对你有所帮助。 import datetime import os import fitz # fitz就是pip install PyMuPDF def pyMuPDF_fitz(pdfPath, imagePath): startTime_pdf2img = datetime.

Linux16.04配置OpenCV3.2

OpenCV-- 一个完全开源的图像处理库,通常用于图像处理,包涵了“模糊" “特征提取” “边缘检测” "目标跟踪"等多个CV领域的基础问题。它是基于C++语言来实现的,具有C++、C、Python和Java的接口,并且支持Windows, Linux, Mac, OS, iOS和Android。即具有很好的平台兼容性。OpenCV专为计算效率而设计,并强调实时应用。 以优化的C / C ++编写,该库可以利用多核处理。 通过启用OpenCL,可以对底层硬件进行加速。 使用OpenCV的用户已经超过4.7万人,下载量超过1400万。 用途从互动艺术,到矿山检查,网上缝合地图或通过先进的机器人。 配置OpenCV的目的? 你的C++代码里面需要进行一定的图像或者视频操作;别人的代码里面调用到了OpenCV内部的一些函数。你需要运行别人的代码,来观察最后的结果;你的"数据挖掘" “机器学习” "深度学习"等应用中需要调用Opencv中的函数,来加速你的开发进程; 总之,如果你本人的研究领域是CV领域,那么你可能就需要使用到OpenCV。 下面开始我们的配置过程吧。 1.首先,你需要去OpenCV的官网中下载最新版本的OpenCV安装包。下载链接 2.你需要将下载到的压缩包解压到特定的文件夹下面。 tar -zxvf xxx.tar 3. 接下来,你需要安装一些依赖包,这是个漫长的过程,需要你耐心的去等待。 1) sudo apt-get install libopencv-dev build-essential cmake git libgtk2.0-dev pkg-config python-dev python-numpy libdc1394-22 libdc1394-22-dev libjpeg-dev libpng12-dev libtiff5-dev libjasper-dev libavcodec-dev libavformat-dev libswscale-dev libxine2-dev libgstreamer0.10-dev libgstreamer-plugins-base0.10-dev libv4l-dev libtbb-dev libqt4-dev libfaac-dev libmp3lame-dev libopencore-amrnb-dev libopencore-amrwb-dev libtheora-dev libvorbis-dev libxvidcore-dev x264 v4l-utils unzip 2) sudo apt-get install build-essential cmake git 3) sudo apt-get install ffmpeg libopencv-dev libgtk-3-dev python-numpy python3-numpy libdc1394-22 libdc1394-22-dev libjpeg-dev libpng12-dev libtiff5-dev libjasper-dev libavcodec-dev libavformat-dev libswscale-dev libxine2-dev libgstreamer1.

项目人力资源管理

项目中的所有活动,归根到底都是由人来完成。如何发挥“人”的作用,对于项目的成败起着至关重要的作用。许多项目失败的原因,都是因为项目人力资源方面的问题。项目人力资源管理的目的,是根据项目需要,规划并组建项目团队,对团队进行有效的指导和管理,以保证他们可以完成项目任务,实现项目目标。 一、项目人力资源管理概念 1、项目团队 项目团队(Project Team)由为完成项目而承担不同角色与职责的人员组成。成员可能技能不同,全职或兼职,可随着项目进展而增加或减少。 尽管技能、职责不同,但全体成员参与项目规划和决策仍然有益,一方面集思广益,另一方面有利于增强责任感。 2、项目管理团队 项目管理团队(Project Management Team)是项目团队的一部分,负责项目管理和领导活动,也称为核心团队成员或领导团队。对于小项目,项目管理职责可由整个项目团队分担,或者由项目经理独自承担。 3、领导和管理 领导者(Leader),工作主要涉及三方面: 1)确定方向(Establishing direction) 2)统一思想(Aligning people) 3)激励和鼓舞(Motivating and inspiring) 管理者(Manager),被组织赋予职位和权力,负责某件事情的管理或实现某个目标,主要关心持续不断地为干系人创造他们所期望的成果。 领导力(Leadership),让一个群体为了一个共同的目标而努力的能力。尊重和信任,而非畏惧和顺从,是有效领导力的关键要素。 项目每个阶段都需要领导力,但开始阶段尤其需要,因为该阶段重点是沟通,描绘愿景,激励鼓舞。 项目经理具有领导者和管理者的双重身份,管理能力和领导能力不可或缺。对于大型项目,领导能力尤为重要。 4、冲突和竞争 冲突(Conflict),指两个或两个以上的社会单元在目标上互不相容或互相排斥,从而产生心理或行为上的矛盾。冲突对管理产生重大影响。 竞争(Competition),双方具有相同的一个目标,不需要势不两立的争夺。 冲突不一定有害,一团和气反而可能影响效率。存在一个最适宜的冲突水平,所谓鲇鱼效应。项目经理要设法减少或解决有害冲突,利用有益冲突,鼓励团队成员良性竞争。 二、项目人力资源管理过程 项目人力资源管理过程包括组织、管理与领导项目团队所需的4个过程。它们不仅彼此相互作用,而且还与其他知识领域中的过程相互作用。这种交互可能导致整个项目需要重新开展规划工作,例如: 1)创建WBS后,需要加入更多成员 2)新团队成员加入后,其经验水平将会降低或增加项目风险,有必要进行额外的风险规划 3)项目活动持续时间可能会发生变更 规划人力资源管理:识别和记录项目角色、职责、所需技能、报告关系,并编制人员配备管理计划 组建项目团队:确认人力资源的可用情况,并为开展项目活动而组建团队 建设项目团队:提高工作能力,促进团队成员互动,改善团队整体氛围,以提高项目绩效 管理项目团队:跟踪团队成员工作表现,提供反馈,解决问题并管理团队变更,以优化项目绩效 1、规划人力资源管理 识别和记录项目角色、职责、所需技能、报告关系,并编制人员配备管理计划。 【输入】 1)项目管理计划 2)活动资源需求 3)事业环境因素 4)组织过程资产 【工具与技术】 1)组织图与职位描述 2)人际交往 3)组织理论 4)专家判断 5)会议 【输出】 1)人力资源管理计划 (1)角色与职责 (2)项目组织图 (3)人员配备管理计划 2、组建项目团队 确认人力资源的可用情况,并为开展项目活动而组建团队。 【输入】 1)人力资源管理计划 2)事业环境因素 现有人力资源情况 人事管理政策 组织的结构 集中办公或多个工作地点 3)组织过程资产 【工具与技术】 1)预分派 预先分配人员 2)谈判 向组织要人,向其他项目组挖人。

STM32F103定时器输入捕获测频率(免费图文,照片验证,下载即用)

正点原子例程输入捕获只有测脉宽,而测频率只是带过,并无程序,两个原理差不多, 今天需要一个引脚测精度高一点的频率,便写下来了,留个记录 下载后直接就能用了,精确度十分高,有用计保仪验证过 MCU:STM32F103C8T6 输入捕获引脚:TIM_CH1 PB6 定时器的配置,注意使能的寄存器外设等,别整错了 定时器中断,主要的就在这里了 主函数 输入捕获测的 示波器测的 这是输入的信号 具体文件已经上传到我的资源,下载即用,百分百可以成,我已经依据此移植到F407平台了,很好使!

1 ubuntu18 docker配置与安装 镜像加速配置

0 背景 搭建环境到创建第一个容器 1 搭建环境 需求:1、安装docker环境 2、镜像加速站 3、多台主机安装docker 1.1 docker环境 电脑为老联想电脑 cpu 2.7ghz,内存12GB,用vmware搞了两个ubuntu18虚拟机,每个虚拟机1个cpu3g内存,每个虚拟机弄个docker,虚拟机弄好了就apt-get instann docker,然后配镜像源,镜像源用阿里云 docker安装命令见下图,依次执行图片指令即可,有的命令要根据自己的linux平台具体调整下,我用的ubuntu,结果第三个命令不能直接copy过来执行,调整了下就好了。 1.2 镜像加速 安装完后配下镜像源,我用的阿里云,点链接进去后注册个账号,然后登陆,登进来界面就是加速器界面,直接把加速url复制到/etc/docker/daemon.json,然后重启docker服务。因为默认镜像站下载速度太慢了 阿里云 阿里云登录 - 欢迎登录阿里云,安全稳定的云计算服务平台 /etc/docker/daemon.json:(docker1.1-1.8好像是改这个json文件,其他版本参考官方文档改) 完了重启docker服务。目前看到两种重启方法,可自己尝试 1.3 多主机安装docker 就弄了俩vm,每个vm装个docker,听说还有docker集群管理,先弄俩docker,后面实践了再补 2 创建容器 docker run -d -p 15475 httpd

Open NMT-py 玩具模型使用说明

前排提示:本文仅适合纯萌新玩家,算是官方指南的补档。(大佬请直接关闭网页,避免浪费时间) 截至到2023.3.15,最新的OpenNMT-py环境要求 Python >= 3.7 PyTorch >= 1.9.0 如果是老版本的OpenNMT-py,需要自己找相应版本的库(有些比较老,不容易安装,如果可以用新版最好用新版,新版ONMT精简了很多冗余代码) Step1:安装OpenNMT-py pip install OpenNMT-py 或者使用下面的指令(需要安装Git,若无Git不推荐使用) git clone https://github.com/OpenNMT/OpenNMT-py.git cd OpenNMT-py pip install -e . Step2:下载玩具数据集(英语→德语) wget https://s3.amazonaws.com/opennmt-trainingdata/toy-ende.tar.gz tar xf toy-ende.tar.gz cd toy-ende 数据由并行源 () 和目标 () 数据组成,每行包含一个句子,标记用空格分隔:srctgt src-train.txt tgt-train.txt src-val.txt tgt-val.txt Step3:配置Yaml环境 # toy_en_de.yaml ## Where the samples will be written save_data: toy-ende/run/example ## Where the vocab(s) will be written src_vocab: toy-ende/run/example.vocab.src tgt_vocab: toy-ende/run/example.vocab.tgt # Prevent overwriting existing files in the folder overwrite: False # Corpus opts: data: corpus_1: path_src: toy-ende/src-train.

如何将Sql查询出的结果导出成csv文件

核心思想: 1、执行sql,封装查询出的结果。 2、导入javaCSV包 3、迭代遍历查询结果,写入文件。 第一步:封装成List<HashMap<String, Object>> 每一行是一个HashMap,Key为列表。 第二步:导包 <dependency> <groupId>net.sourceforge.javacsv</groupId> <artifactId>javacsv</artifactId> <version>2.0</version> </dependency> 第三步:写入 /** *接收查询结果,存储文件名 * @param defiled_info sql查询结果 * @param fileName fileName为下载文件名,防止文件重名覆盖,可加入时间戳 */ public static void defiled_csv(List<HashMap<String, Object>> defiled_info,String fileName) { String rootPath = ""; if(fileName == null){ rootPath = "D:/file_"+ System.currentTimeMillis()+".csv"; }else { rootPath = "D:/"+fileName+System.currentTimeMillis()+".csv"; } //第一个参数为文件存储路径,第二个为指定导出的文件字段间的间隔符,第三个参数为转出编码 CsvWriter csvWriter = new CsvWriter(rootPath, '|', Charset.forName("GBK")); //需要确保查询的结果不能为空,也可以在这做判断,不为空才能自动取表头,不然需要手动传入表头 HashMap<String, Object> hashMap = defiled_info.get(0); Set<String> defiled_sets = hashMap.keySet(); try { if (defiled_sets.

JVM——深入理解JMM(Java内存模型)与线程

硬件的效率和一致性 让计算机并发执行若干个运算任务,其中一个比较重要的复杂性就在于,许多运算不是只依靠处理器就能实现的,另外还有如读取运算数据、存储运算结果,这种IO操作也都是运算的重要步骤。但是,由于处理器的运算速度和存储设备的IO速度有几个数量级的差距,所以现代计算机不得不在其之间加入一层或多层读写速度尽量接近处理器运算速度的高速缓存。将运算需要用到的数据和运算产生的结果同步到缓存中,这样处理器就无需等待缓慢的内存读写了。 但这样会在有着多路处理器的计算机中产生缓存一致性的问题,每个处理器都有自己的高速缓存,却又共享同一主内存。当多个处理器的运算结果都涉及同一块内存时,可能导致各自的缓存数据不一致。由此就诞生了一些,保证缓存一致性的协议 Java内存模型(JMM) Java虚拟机规范曾视图定义一种java内存模型,用来屏蔽掉各种硬件和操作系统的内存访问差异,以实现让java程序在各种平台下都能达到一致的内存访问效果 java内存模型定义的得足够严谨,才能让java的并发访问操作不会产生歧义,但是也必须定义的足够宽松,使得虚拟机的实现能够又足够的自由空间去发挥硬件的性能和特性获取更好的执行速度。经过长时间的验证和修补,直到JDK5发布后,Java内存模型才终于成熟、完善起来了 主内存和工作内存 java内存模型的主要目的时定义程序中各种变量的访问规则,即关注虚拟机中把变量值储存到内存或从内存中去除变量值这样的细节。此处的变量值只括存储在jvm的虚拟机栈以外的元素。内为栈内的元素是线程私有的,不会被共享。 JMM规定了所有变量都存储在主内存中,每条线程还有自己的工作内存,线程的工作内存中保存了该线程使用的变量的主内存副本。主内存、线程、工作内存三者的交互关系如下 内存间的交互操作 关于主内存和工作内存的交互协议,即一个变量如何从主内存拷贝到工作内存、如何从工作内存同步回主内存这一类的实现细节,JMM定义了以下8中操作来完成。java虚拟机是现实必须保证下面提及的每一种操作都是原子的、不可再分的。 lock:作用于主内存的变量,把一个变量标识为一条线程独占的状态unlock:作用域主内存的变量,他把一个处于锁定状态的变量释放出来,释放后的变量才可以被其他线程锁定read:作用于主内存的变量,它把一个变量的值从主内存输送到线程的工作内存中,以便随后的load动作使用load:作用域工作内存的变量,它把read操作从中内存中得到的变量值放入工作内存的变量副本中use:作用域工作内存的变量,它把工作内存中一个变量的值传递给执行引擎,每当虚拟机遇到一个需要使用变量的值的字节码指令时会执行这个操作assign(赋值):作用域工作内存的变量,它把一个从执行引擎中接收到的值赋给工作内存的变量,每当虚拟机遇到一个给变量赋值的字节码指令时执行这个操作store:作用于工作内存的变量,它把工作内存中一个变量的值送入到主内存中,以便随后的write操作使用write:作用域主内存的变量,它把store操作中从工作内存中得到的变量放入主内存的变量中。 如果要把一个变量从主内存拷贝到工作内存,那就要按顺序执行read和load操作,如果要把变量从工作内存同步到主内存,就要按顺序执行store和write操作。注意,java内存模型只要求上述两个操作必须按顺序执行,但不要求连续执行。中间是可以插入其他指令的。java内存模型还规定了执行上述8中基本操作时必须满足如下规则: 不允许read、load、store和write操作之一单独出现。即不允许一个变量从主内存读取了但工作内存不接受,或者从工作内存发起回写了主内存不接受的情况出现。不允许一个线程丢弃它的assign操作,即变量在工作内存中改变了之后必须把该变化同步回主内存不允许一个线程无原因的把数据从工作内存中同步回中内存一个新的变量只能在主内存中“诞生”,不允许在工作内存中直接使用一个未被初始化的变量,换句话说对一个变量实施use、store操作之前,必须先执行assign和load操作。一个变量在同一时刻只能允许一条线程对其进行lock操作,但lock操作可以被同一条线程执行多次,多次执行lock后,只有执行相同次数的unlock才能解锁。如果对一个变量进行lock操作,那将会清空工作内存中此变量的值,在执行引擎使用这个变量前,需要重新执行load或assign操作以初始化变量的值如果对一个变量事先没有被lock操作锁定,那么就不允许对它执行unlock操作,也不允许去unlock一个被其他线程锁定的变量对一个变量执行unlock操作之前,必须先把此变量同步回主内存中 对于volatile的型变量的特殊规则 关键字volatile可以说是java虚拟机最轻量级的同步机制 当一个变量被定义成volatile之后,他将具备两种特性 volatile一般也只用来修饰共享变量 保证此变量对所有线程的可见性,这里的可见性是指,当一条线程修改了这个变量的值,新值对于其他线程来说可以立即得知的,而普通变量并不能做到这一点,普通变量的值在线程间传递需要同故宫主内存来完成。比如线程A修改一个变量的值,然后向主内存进行回写,另一条线程B在线程A回写完成了之后再对主内存进行读取操作,新变量值才会对B可见 使用volatile变量禁止指令重排序优化的,由于JVM的JIT编译器会对很多代码进行优化,以提高执行效率,其中就包括指令重排序,而volatile依靠内存屏障,屏蔽这种可能会在程序运行过程中产生错误的优化。产生错误的原因一般都是由于变量的逃逸,加上指令重排序产生的,产生错误的机率并不高但也存在。 volatile变量读操作的性能消耗与普通变量几乎没有什么差别,但是写操作则可能会慢上一些,因为它需要在本地代码中插入许多内存屏障指令来保证处理器不发生乱序执行。不过绝大多数场景下volatile总开销仍然要比锁来的更低。 指令重排序 指令重排序是指处理器采用了允许将多条指令不按程序规定的顺序分开发送给各个相应的电路单元进行处理。但不是说指令任意重排,处理器必须能正确处理指令的依赖情况保证程序能得出正确的执行结果 针对于long和double型变量的特殊规则 JMM要求lock、unlock、read、load、assign、use、store、write这八种操作都具有原子性。但是对于64位的操作类型,在JMM中却有一条宽松的规定,允许虚拟机将没有被volatile修饰的64位数据的读写操作划分为两次32位的操作来进行。即允许虚拟机实现自行选择是否要保证64位数据类型的load、store、read和write这四个操作的原子性这就是所谓的“long和double的非原子性规定”。 如果又多个线程共享一个并未声明位volatile的long或double变量,并且同时对他们进行读取和修改操作,那么某些线程可能会读取到一个既不是原值,也不是其他线程修改值的代表了“半个变量”的数值。但是这种情况是非常罕见的,在实际开发中,除非该数据有明确可知的线程竞争,否则我们在编写时一般不需要因为这个原因把用到的long和double变量专门声明为volatile 原子性、可见性和有序性 原子性 由JMM直接来保证的原子性变量操作包括read、load、assign、use、store和write这六个 如果应用场景需要一个更大范围的原子性保证,JMM还提供了lock和unlock操作来满足这种需求,尽管虚拟机未把lock和unlock操作直接开放给用户使用,但却提供了更高层次的monitorenter和monitorexit两个字节码指令来隐式的使用这两个操作。这两个字节码反映到Java代码中就是synchronized关键字 可见性 除了volatile之外,Java还有两个关键字能实现可见性,分别是synchronized和final。 synchronized的可见性是由“对一个变量执行unlock操作之气那,必须先把此变量同步回主内存中”这条规则获得的 final的可见性是基于不变性成立的,一般在实际开发中,只会用final修饰一些基本变量,并不会修饰对象、数组之类的元素,因为不变性而导致的可见性只在基本变量上可以发生,对于对象、数组,final只能保证他们的地址不发生改变,但对于对象的属性值、数组的元素值的改变,final是控制不了的 有序性 Java语言提供了volatile和synchronized这两个关键字来保证线程之间操作的有序性,volatile关键字本身就包含了禁止指令重排序的语义,而synchronized则是由“一个变量在同一时刻只允许一条线程对其进行lock操作”这条规则获得的,这个规则决定了持有同一个锁的两个同步块只能串行的进入 先行发生原则 如果JMM中所有有序性都仅靠volatile和synchronized来完成,那么有很多操作都将会变得非常繁琐。但是我们在编写代码时并没有察觉到,这是因为java语言中有一个“先行发生原则”,这个原则时判断数据是否存在竞争,线程是否安全的非常有用的手段。 下面时JMM下一些“天然的”先行发生关系,这些先行发生关系无需任何同步器协助就已经存在,可以在代码中直接使用。 程序次序规则:在一个线程内,按照控制流顺序,书写在前面的操作先行发生于书写在后面的操作。这里说的是控制流顺序而不是程序代码的循序,因为需要考虑分支、循环等结构。 管程锁定规则:一个unlock操作先行发生于后面对同一个锁的lock操作。 volatile变量规则:对一个volatile变量的写操作先行发生于后面对这个变量的读操作 线程启动规则:Thread对象的start()方法先行发生于此线程的每一个操作 线程中止规则:线程中所有操作都先行发生于对此线程的终止检测 线程中断规则:对先册灰姑娘interrupt()方法的调用先线性发生于被中断线程的代码检测到中断事件的发生 对象终结原则:一个对象的初始化完成先行发生于它的finalize()方法的开始 传递性:如果操作A先行发生于操作B,操作B先行发生于操作C,那就可以得出操作A先行发生于操作C的结论。 Java的线程 线程的实现 线程是比进程更轻量级的调度执行单位,目前线程是Java里面进行处理器资源调度的最基本单位。可以注意到Thread类的所有关键方法都被声明为Native,一个Native方法往往意味着这个方法没有使用或无法使用平台无关的手段来实现。 实现线程主要有三种方式:使用内核线程实现(1:1实现),使用用户线程实现(1:N实现),使用用户线程加轻量级进程混合实现(N:M实现) 内核实现 内核线程就是直接由操作系统内核支持的线程,这种线程由内核来完成线程切换,内核通过操作任务调度器对线程进行调度,并负责将线程的任务映射到各个处理器上。 程序一般不会直接使用内核线程,而是使用内核线程的一种高级接口——轻量级进程,轻量级进程就是我们通常意义上所讲的线程(注意线程和内核线程的区别), 由于内核线程的支持,每个轻量级进程都成为一个独立的调度单元,由于是基于内核线程实现的,所以各种线程操作,都需要系统调用,而系统调用的代价相对较高,需要在用户态和核心态中来回切换。其次,每个轻量级进程都需要一个内核线程的支持,因此轻量级进程需要消耗一定的内核资源,因此一个系统支持轻量级进程的数量是有限的。 用户线程实现 一般来说,一个线程只要不是内核线程都可以视为用户线程的一种,从这个定义来看,轻量级线程也属于用户线程,但是轻量级线程的实现始终是建立在内核之上的,许多操作都要系统调用,因此并不具备通常意义上用户线程的优点 而普通的用户线程是指完全建立在用户空间的线程库上,系统内核不能感知到用户线程的存在以及如何实现的。用户线程的建立、同步、销毁和调度完全在用户态中完成,不需要内核的帮助。如果程序实现的当,这种线程不需要切换到用户态,因此能够支持规模跟大的线程数量 混合实现 还有一种将内核线程与用户线程一起使用的实现方式,被称为N:M实现,在这种混合实现下,即存在用户线程,也存在轻量级进程,操作系统支持的轻量级线程作为用户线程和内核线程的桥梁。 Java线程的实现 以HotSpot为例,他的每一个Java线程都是直接映射到一个操作系统原生线程来实现的,而且中间没有二外的内存结构,所以HotSpot自己是不会去干涉线程调度的,线程调度完全是由任务调度器决定的。 Java线程调度 线程调度是指系统为线程分配处理器使用权的过程,调度主要方式有两种,抢占式调度和协同式调度。 协同式调度 线程的执行时间由线程本身来控制,线程把自己的工作执行完了之后,要主动通知系统切换到另外一个线程上去。协同式多线程的好处是实现简单,而且由于线程要把自己的事情干完后才会进行线程切换,一般没有什么同步问题。但是它的坏处也很明显,线程执行时间不可控制,如果线程陷入阻塞,就会导致程序一直阻塞在哪里 抢占式调度 每个线程将由系统来分配执行时间,线程的切换不由线程本身来决定。当一个线程出现了问题,我们还可以使用任务管理器把这个进程杀掉,而不至于导致系统崩溃。 虽然Java的线程调度是由系统完成的,但我们仍然可以“建议”操作系统给某些线程多分配一些执行时间,这项操作是通过设置线程优先级来完成的。但是,线程优先级并不是一项稳定的调节手段,因为最终的线程调度还是由操作系统说了算。Windows中有一个“优先级推进器”的功能目的是当系统发现一个线程被执行的特别频繁时,可能会越过线程优先级为它分配执行时间,以便减少因为线程频繁切换导致的性能损耗

python: np.random.rand(); random.randn(); random.randint()

目录 np.random.rand(): np.random.randn(): np.random.randint(): 总结: np.random.rand(): 该函数旨在输出0~1的正态分布随机数。 其参数可以是1个,也可以是多个。 函数内部可以不写参数,默认为1,输出1个随机数。 1个参数:(标注出了数组类型、数组中某一数据类型、数组中指定数据类型,之后的函数将不再打印) bp = np.random.rand(5) print(bp) ''' [0.63860047 0.20494917 0.71744941 0.57771626 0.05738536] ''' print(type(bp)) # 输出整个数组的类型 '''<class 'numpy.ndarray'>''' print(bp.dtype) # 输出数组中某一数据的类型 '''float64''' print(type(bp[0])) # 输出数组中某一特定数据的类型 '''<class 'numpy.float64'>''' 2个参数: bp = np.random.rand(2, 5) print(bp) ''' [[0.04584862 0.89884039 0.15048622 0.85667698 0.33957756] [0.26056558 0.91414757 0.81265246 0.28835074 0.8752219 ]] ''' print(type(bp)) '''<class 'numpy.ndarray'>''' print(type(bp[0][0])) '''<class 'numpy.float64'>''' print(bp.dtype) '''float64''' 3个参数: bp = np.random.rand(2, 3, 6) print(bp) ''' [[[0.

项目中echarts的罗盘

<script setup lang='ts'> import { ref, watch, onMounted } from 'vue'; import * as echarts from 'echarts'; // 接收父组件传递的数据 let props: any = defineProps({ // Y轴的数据 value: { type: Number, default:0 }, ids:{ type:String, default:'main39' } }) // 初始化的数据 let myCharts: any = ref('') // 使用watch来处理异步的数据,点击的内容发生改变,拿到新的数据渲染页面 watch(() => props, (val: any) => { getOption(val) }, { deep: true, }) // 自定义方法获取echarts数据 let getOption = (objs: any) => { let option = { series: [ { type: 'gauge', startAngle: 180, endAngle: 0, center: ['50%', '75%'], radius: '100%', //仪表盘大小 min: 0, max: 1, splitNumber: 8, //等份 axisLine: { //颜色样式 show: true, lineStyle: { width: 16, //线条大小 color: [ //等份的颜色 [ 1, new echarts.

VRRP虚拟路由冗余协议

一、VRRP简介 定义 虚拟路由冗余协议VRRP(Virtual Router Redundancy Protocol)通过把几台路由设备联合组成一台虚拟的路由设备,将虚拟路由设备的IP地址作为用户的默认网关实现与外部网络通信。当网关设备发生故障时,VRRP机制能够选举新的网关设备承担数据流量,从而保障网络的可靠通信。 目的 随着网络的快速普及和相关应用的日益深入,各种增值业务(如IPTV、视频会议等)已经开始广泛部署,基础网络的可靠性日益成为用户关注的焦点,能够保证网络传输不中断对于终端用户非常重要。 通常,同一网段内的所有主机上都设置一条相同的、以网关为下一跳的缺省路由。主机发往其他网段的报文将通过缺省路由发往网关,再由网关进行转发,从而实现主机与外部网络的通信。当网关发生故障时,本网段内所有以网关为缺省路由的主机将无法与外部网络通信。增加出口网关是提高系统可靠性的常见方法,此时如何在多个出口之间进行选路就成为需要解决的问题。 VRRP的出现很好的解决了这个问题。VRRP能够在不改变组网的情况下,将多台路由设备组成一个虚拟路由器,通过配置虚拟路由器的IP地址为默认网关,实现默认网关的备份。 优点 冗余备份 VRRP可以将多台路由设备配置为缺省网关路由器,当出现单点故障的时候通过备份链路进行业务传输,从而降低网络故障的可能性,保证用户的各种业务不中断传输。 负载分担 VRRP可以实现多台设备同时承担业务流量,从而减轻主用设备上数据流量的承载压力,在路由设备之间更均衡地分担流量。 联动功能 VRRP联动可以监视上行链路的故障。当上行接口或链路故障时,VRRP备份组的Master设备降低优先级,重新进行选举,确保Master路由器为最佳的VRRP路由设备,保证流量的正常转发。 VRRP与BFD联动可以提高VRRP备份组中主备设备的切换速度。利用BFD检测速度快的特点,在Master设备和Backup设备之间建立BFD会话并与VRRP备份组进行绑定,实现Master设备和Backup设备之间的链路出现故障时,Backup设备迅速切换为Master,承担网络流量。 二、VRRP术语 VRPP路由器 运行VRRP的路由器,一台VRRP路由器(的接口)可以同时参与到多个VRRP组中,在不同的组中,一台VRRP路由器可以充当不同的的角色 VRRP组 一个VRRP组由多个VRRP路由器组成,使用group ID进行标识,属于同一VRRP组的VRRP路由器互相交换信息,每一个VRRP组中只能有一个Master 虚拟路由器 对于每一个VRRP组,抽象出来的一个逻辑路由器,该路由器充当网络用户的网关,该路由器并非真实存在,事实上对于用户而言,只需知道虚拟路由器的IP,至于具体的虚拟路由器的角色由谁来承担、数据转发任务由谁来承担、Master挂掉之后谁来接替,这是VRRP的工作 虚拟IP地址、MAC地址: 虚拟IP地址用于表示虚拟路由器,该地址实际上就是用户的网关地址 与虚拟地址对应的MAC也是虚拟的,该MAC地址由固定位加上VRRP组ID构成,当PC发ARP请求虚拟IP地址对应的MAC地址,Master路由器响应这个ARP请求并告知虚拟MAC地址 Master、Backup路由器: Master路由器:就是在VRRP组实际转发数据包的路由器,在每一个VRRP组中,仅有Master响应对应虚拟IP地址的ARP请求 Master路由器同时以一定的时间间隔发送VRRP消息,以便通知Backup路由器自己的存活 Backup路由器:就是在VRRP组中处于监听状态的路由器,一旦Master路由器出现故障,Backup路由器就开始接替工作 选举依据:先比较接口优先级,如果相等则比较接口IP地址(注:这里是比值大) 三、VRRP状态机 VRRP协议的状态共有三种,分别是Initalize , Master , Backup ,初始状态都是Initialize ,通过比较优先级产生Master和Backup ,在规定时间内, Backup若没有收到Master发来的心跳报文,将切换为Master. 协议对VRRP规定了3种状态:INITIALIZE,MASTER和BACKUP。简单地说,INITIALIZE即初始态,MASTER即主用状态,也就是在VRRP备份组中真正起作用的路由器BACKUP即备用状态,是MASTER的备份 四、华为eNSP仿真实验 1、拓扑图 拓扑图中,PC1及PC2都有两条路径访问Server1,一般情况下,PC1和PC2只能找自己的网关,通过确定的一条路由访问Server1,当路由发生故障时将无法访问。 通过对LSW2和LSW3配置VRRP,可以实现路由冗余备份,当路由发生故障时,可自动切换到备份路由,有效提高通信的可靠性。 2、实验详细配置 2.1、配置PC1和PC2IP地址: PC1、PC2的网关为VRRP的virtual-ip(虚拟ip) 2.2、配置LSW1: <Huawei>sys[Huawei]sys LSW1[LSW1]u in e[LSW1]vlan batch 1020[LSW1]q[LSW1]int E0/0/1[LSW1-Ethernet0/0/1]p l a[LSW1-Ethernet0/0/1]p d v 10[LSW1-Ethernet0/0/1]in e0/0/2[LSW1-Ethernet0/0/2]p l a[LSW1-Ethernet0/0/2]p d v 20[LSW1-Ethernet0/0/2]int g0/0/1[LSW1-GigabitEthernet0/0/1]p l t[LSW1-GigabitEthernet0/0/1]p t a v a[LSW1-GigabitEthernet0/0/1]int g0/0/2[LSW1-GigabitEthernet0/0/2]p l t[LSW1-GigabitEthernet0/0/2]p t a v a[LSW1-GigabitEthernet0/0/2]return<LSW1>save 2.

QT 中 QString 中文转std::string 问题

最后,本地调试Debug版本,发现安装中文路径下,安装路径为乱码,导致加载翻译文件、创建日志文件、加载动态库等等均失败。 对我而言,新发现新问题,先问度娘。尝试了很多解决方案,最终都以失败告终。 于无望处,突然柳暗花明,在一个帖子上看到这么一句话: Qt中用于控制读出和写入文件系统时的字符编码由 QTextCodec::setCodecForLocale() 所决定。 加入 QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8")); 问题解决 当然,记得先添加头文件:#include <QTextCodec> 编译、启动、成功。再自测。 自测发现利用log4cpp模块创建日志文件时,需要利用std::string类型的参数。 但是,QSting类型直接利用toStdString()接口转换为std::string类型后,函数返回异常,没有成功创建日志文件。 再继续寻根问因,后来,发现需要进行一下中文转换: QTextCodec::codecForName("gb18030")->fromUnicode(logFileName).data() 如上,这样转换后是std::string类型参数传入函数,创建日志文件正常。 再编译、启动、运行一切正常。 特此备录。仅供参考。具体环境,具体分析。

static关键字的作用

目录 C语言中static关键字的作用 1.static关键字修饰局部变量 2.static关键字修饰全局变量 3.static关键字修饰函数 在C++中static关键的作用 1.静态成员变量 2.静态成员函数 C语言中static关键字的作用 1.static关键字修饰局部变量 概念: static修饰局部变量就使之成为静态局部变量。 作用域: 静态局部变量的作用域并未发生变化,在其所在的局部范围,也就是其所定义的代码块内部。 生存期: 静态局部变量实际上是特殊的全局变量,它们位于相同的内存区域,内存分为栈区,堆区,静态存储区。静态局部变量和全局变量都位于静态存储区,因此静态局部变量的生存期与全局变量一样是全局的,随程序启动而生,随程序结束而消亡。 特点: 静态局部变量的初始化只会在第一次进入这个函数时进行初始化,当离开函数的时候,静态局部变量会继续存在并保持其值,以后进入函数时会保持上次离开时的值。 2.static关键字修饰全局变量 因为全局变量具有外部连接属性,外部任意一个源文件想要使用其他源文件中的全局变量,只需要先使用extern关键字进行声明,然后就可以使用,也就是说某个源文件的全局变量可以在整个项目中被任意的一个源文件使用,所以全局变量的作用域是整个工程。当一个全局变量被static所修饰的时候,它就称为了静态全局变量,静态全局变量具有内部连接属性,使得这个静态全局变量只能在自己所在的编译单元中被使用,而不能被其它编译单元所使用,否则会出现链接性错误。 static修饰变量时,如果变量没有被初始化会被自动初始化为0 3.static关键字修饰函数 函数也是具有外部连接属性的,编译器每次编译只处理一个编译单元,当某个编译单元需要使用其他编译单元中的函数,只需要声明该函数(或者包含该函数声明所在的头文件)然后就可以使用,当一个函数被static所修饰的时候,这个函数的外部连接属性就变成了内部连接属性,也就成为了静态函数,使得这个静态函数只能在自己所在的编译单元中被使用,而不能被其它编译单元所使用,否则会出现链接性错误。 通常我们在头文件中声明一个函数,然后在源文件中去定义该函数,在定义某函数时需要将某一段代码封装成为另一个函数以达到复用的目的,这段代码所封装成的函数只是为了定义那个函数所使用,不会在其它源文件中使用,所以将其声明为static。 在C++中static关键字的作用 static关键字修饰类中成员使之成为静态成员,静态成员的特点如下: 静态成员也是类的成员,受public、protected、private 访问限定符的限制。静态成员为所有类对象所共享,不属于某个具体对象,它是属于类的,只有一份内存,类静态成员可用类名::静态成员或者对象.静态成员来访问。类名访问,肯定是从类外访问,那么类外访问的话,就要求静态成员是公有属性,可以用类名访问这一点也说明:静态成员变量肯定不是属于对象的,如果是属于对象,那么就不能用类名访问了。 静态成员包括静态成员变量和静态成员函数,static关键字修饰成员变量使之成为静态成员变量,static关键字修饰成员函数使之成为静态成员函数。 1.静态成员变量 特性: 在对象的构造函数中不能对静态成员变量进行初始化,因为静态成员变量不属于单个对象,不需要对象去初始化。静态成员变量在类中加static声明,在类外进行初始化定义,初始化定义时不添加static关键字。若未对静态成员变量进行初始化操作,编译器会自动将其初始化为0。静态成员变量只能初始化,不能赋值静态成员变量可以实现多个对象之间的数据共享,它是类的所有对象的共享成员,它在内存中只占一份空间,如果改变它的值,则各对象中这个数据成员的值都被改变。静态成员变量存储在静态存储区,和静态局部变量和全局变量一样,它的生存期是全局的,是在程序开始运行时被分配空间,到程序结束之后才释放,只要类中指定了静态成员变量,即使不定义对象,也会为静态成员变量分配空间。 如图,如果在类中进行初始化定义,编译器就会报错 改成如下,类中声明,类外定义就没有问题了 如果给静态成员变量赋值,编译器就会报错 2.静态成员函数 定义方式: 类中声明,类外定义类中定义 class ClassName { public: static Type fun(){}//在类中定义 static Type fun2();//类中声明 }; Type ClassName::fun2(){}//在类外定义 在类外定义的时候不需要再加上static 特性: 静态成员函数没有隐藏的this指针,不能访问任何非静态成员。 没有隐藏的this指针是因为可以通过类名直接去访问函数,那么过程中间不存在对象,this指针就没有对象去指向了,为了避免这种情况的发生,索性就静态函数中就不要this指针了,如果通过对象去调用静态成员函数,虽然可以正确调到,但是this指针也没了。 不能访问任何非静态成员。原因之一是因为不存在this指针,因此你无法在静态成员函数中通过.操作符和->操作符来访问属于某个具体对象的非静态成员。静态成员函数只能访问静态成员。普通成员函数可以访问普通成员,也可以访问静态成员。

能看懂得Xxl-job安装教程

大家好,我是咔咔 不期速成,日拱一卒 一、背景 在平时的业务场景中,经常有一些场景需要使用定时任务,比如: 某个时间点发送优惠券发送短信等等。批量处理数据:批量统计上个月的账单,统计上个月销售数据等等。固定频率的场景:每隔5分钟需要执行一次。 所以定时任务在平时开发中并不少见,而且对于现在快速消费的时代,每天都需要发送各种推送,消息都需要依赖定时任务去完成,应用非常广泛。 xxl-job主要分为调度中心和执行器,简单来讲,调度中心就是后台管理,执行器就是执行定时任务的,就这么理解就行。 二、所需工具 使用xxl-job需要先配置好maven、java环境,接下来先把所需要的工具都下载到本地 下载xxl-job源码 https://github.com/xuxueli/xxl-job.git 咔咔使用的编辑器是Intellij IDEA,可以下载社区版 下载maven 下载java并安装,下载地址 https://www.oracle.com/java/technologies/downloads/#java8-windows 三、配置maven 咔咔将下载的maven放到了D盘 修改\apache-maven-3.9.0\conf\settings.xml文件 把本来的配置修改为圈的内容 <mirror> <id>aliyunmaven</id> <mirrorOf>*</mirrorOf> <name>阿里云公共仓库</name> <url>https://maven.aliyun.com/repository/public</url> </mirror> 复制C:\Users\Administrator\.m2到maven中 配置环境变量 四、配置java环境 这里没有修改java的安装目录,直接默认安装位置到C:\Program Files\Java 环境变量都需要配置JAVA_HOME、CLASSPATH、path JAVA_HOME:C:\Program Files\Java\jdk-18.0.2CLASSPATH:.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jarpath:%JAVA_HOME%\bin、%JAVA_HOME%\jre\bin 五、验证配置是否成功 执行以下命令看是否配置成功 java -verison javac -version mvn -version 六、初始化MySQL表 # 调度数据库初始化SQL脚本位置:/xxl-job/doc/db/tables_xxl_job.sql cd xxl-job/doc/db # 登录mysql mysql -uroot -p # 执行mysql初始化脚本 source ./tables_xxl_job.sql 或者 source 绝对路径/tables_xxl_job.sql # 切换数据库 use xxl_job; # 查看表是否创建完毕 show tables; 看到xxl_job就表示数据库已经导进去了 七、部署调度中心 打开编辑器后需要先把maven的目录修改为咱们自己下载的

Spring优雅重试@EnableRetry

如果不用spring的写法 // 简单递归+次数限制+线程睡眠 package com.example.springexample.springretry; /** * @desc: RetryDemo * @author: pmdream * @date: 2023/3/15 1:51 AM */ public class RetryDemo { public static void retry(int i) { if (i <= 3) { i++; try { if (method()) { System.out.println("成功"); } else { Thread.sleep(1000); System.out.println("重试:" + i + "次"); retry(i); } } catch (Exception e) { e.printStackTrace(); } } } private static boolean method() { System.out.println("do some thing"); return false; } public static void main(String[] args) { retry(0); } } 结果:

23种设计模式-访问者模式(Android应用场景介绍)

什么是访问者模式? 访问者模式是一种行为型设计模式,其目的是在不改变现有类结构的前提下,增加新的操作或算法。 在这种模式中,我们通过定义访问者类(Visitor)和被访问的元素类(Element)来实现操作的分离。被访问的元素类提供接受访问者访问的方法,而访问者类则定义了对元素的不同操作。在执行操作时,访问者会将自己传入元素类的接受访问者方法中,从而实现对元素的访问和操作。 访问者模式Java示例 下面我们使用Java语言来实现访问者模式。我们将实现一个动物园的例子,其中包含了不同类型的动物,如狮子、老虎和猴子等,我们将实现对它们的不同操作,如观察、喂食和清理等。 首先,我们需要定义动物类的接口(Element): public interface Animal { void accept(Visitor visitor); } 在这个接口中,我们定义了一个接受访问者访问的方法 accept()。 接下来,我们定义了访问者类(Visitor): public interface Visitor { void visit(Lion lion); void visit(Tiger tiger); void visit(Monkey monkey); } 在这个接口中,我们定义了不同类型的动物的访问方法,如 visit(Lion lion)、visit(Tiger tiger) 和 visit(Monkey monkey)。 现在,我们需要实现不同类型的动物类,并在它们的 accept() 方法中调用访问者的 visit() 方法: public class Lion implements Animal { public void roar() { System.out.println("Lion is roaring"); } @Override public void accept(Visitor visitor) { visitor.visit(this); } } public class Tiger implements Animal { public void growl() { System.