利用stm32做一个升级版的电子多功能密码锁

`自己利用空闲时间制作的电子密码锁,有PCB、原理图,PCB印制电路板。此设计用外部存储器,支持修改密码,本来想添加指纹识别模块,但是12864的数据口被使用了,gpio口不够用。在实际中我发现12864还是用串口比较好,因为用并口的话使用会影响同GPIO口的其他位口。毕竟是业余时间做的,可能在有些方面不是很完善。 一、功能介绍: 1、输入6位密码,即可开锁。 2、输入7次纯数字,系统会自动恢复初始状态。 3、没有输入完6位密码,按下确认键,系统不会应答。 4、密码输入错误三次,锁定键盘并且蜂鸣器提醒10秒。 5、输入错误可以退格、清零。 6、开机后12864模块会有60秒定时显示,没操作键盘60秒后,清除数据并且恢复初始状态。如果在记时期间有按键按下,这停止倒计时,并且在没有操作键盘8秒左右,重新开启倒计时12864休眠功能。 7、在功能模式下可以修改密码,也可以做其他功能选择(其他功能你们根据自身能力添加)。 8、程序有密码数值存储在数组,可用于显示等操作。(修改密码时可以显示) 9、有人体感应模块,感应到有人吗,并且12864处于关屏休眠模式下,即可打开12864屏幕。 10、有外部存储器24C02,支持修改密码,密码断电不丢失。 11、步进电机模块。 12、继电器模块。 13、温度模块,倒计时期间可以测量7805和1117芯片温度或者外部温度,并实时显示。 二、资料展示 1.原理图 2.PCB印制电路板 因为自己做的板,所以在布线的时候那那么专业,能用就好。 3.实物图 外观大概就这样,工作状态 4、说明 我是用的KT板面上贴了一层贴纸,把这些弄到了一起,自己准备在包装一下,做一个密码箱完全没有问题。可以用来放放自己的小秘密,哈哈哈 。 5、部分代码 按键模块的键值内容判断 #include "key_control.h" #include "delay.h" #include "key.h" #include "12864.h" #include "Relay.h" #include "buzzer.h" #include "time.h" #include "24c02.h" #include "uln2003.h" u8 password[]={0x30,0x30,0x30,0x30,0x30,0x30}; u8 new_password[]={0x30,0x30,0x30,0x30,0x30,0x30}; uchar display[]={0x2A,0x2A,0x2A,0x2A,0x2A,0x2A}; u8 nkv=0,sign=0,fkv,noe=0,Function_menu_flag=0,Move_down_flag=0, Move_up_flag=1,Revise_the_password_flag=0,New_password_flag=0, Number_of_new_passwords=0; u16 mc=1; extern uchar mima[]; extern u8 Countdown; void Key_Number(void) { u8 num=0,i; num=Key_Scan(); if(num==16&&Countdown==0&&GPIO_ReadOutputDataBit (GPIOB,GPIO_Pin_9)==1) //没有按键按下且没有开启定时器 没有黑屏 { mc++; delay_ms(10); if(mc==1001) { mc=1; TIM3_Int_Init(9999,7199);//计时60S } if(mc==50001) mc=1; } if(num!

InfluxDB学习记录(二)——influxdb的关键概念

专业术语 关键概念 示例数据 下图所示为 从2015年8月18日午夜到2015年8月18日6时12分,两位科学家(langstroth和perpetua)在两个地点(location 1和location 2)分别计数得出的butterflies和honeybees的数量。 假设数据存储在名为my_database的数据(database),并受到数据保留策略(retention policy)autogen的约束。 其中,census是measurement;time列中的是时间戳;butterflies和honeybees都是field key,butterflies列和honeybees列中的数据是field value,location和scientist都是tag key,location列和scientist列中的数据是tag value。 分析数据 time存储着时间戳,并且时间戳是以RFC3339 UTC格式展示与特定数据相关联的日期和时间。 field由field key和field value组成 其中,field key(butterflies和honeybees)是字符串,field key butterflies告诉我们蝴蝶的数量:从12到7,而field key honeybees告诉我们蜜蜂的数量:从23到22。 field value是数据,它们可以是字符串、浮点数、整数或者布尔值。 field key-value对的集合组成一个field set field是InfluxDB数据结构中必要部分之一,在InfluxDB中不能没有field。field是没有索引的。如果使用field value作为过滤条件来进行查询,那么必须扫描完所有数据,才能找到与查询中的其它条件也都匹配的所有结果(相对于用tag作为过滤条件的查询来说,那些用field value作为过滤条件的查询性能会低很多)。一般来说,field不应该包含经常被查询的元数据(metadata)。 tag由tag key和tag value组成。tag key和tag value都是字符串,并记录元数据。 示例数据中的tag key是location和scientist, 其中,location有两个tag value:1和2,scientist也有两个tag value:langstroth和perpetua。 tag set是所有tag key-value对的不同组合。 在InfluxDB中,tag不是必须要有的字段,不需要一定在数据结构中添加tag。但是,tag是被索引的,这意味着以tag作为过滤条件的查询会更快,所以tag非常适合存储经常被查询的元数据。 InfluxDB自动创建autogen这个保留策略,它具有无限的存储时间并且复制系数设为1。 在InfluxDB中,序列(series)是有共同的保留策略、measurement和tag set的数据的集合。 以上示例数据中的共有4个序列: 数据点(point)就是在相同序列里,具有相同时间戳的field set。 InfluxDB数据库与传统数据库类似,并且作为用户、保留策略、连续查询和时序数据的逻辑容器。数据库可以有多个用户、连续查询、保留策略和measurement。InfluxDB是一个schemaless(无模式)数据库,意味着随时可以轻松地添加新的measurement、tag和field。InfluxDB的设计宗旨就是能够很好地处理时序数据。 扩展 与传统数据库的对比 Shard Shard 在 influxdb中是一个比较重要的概念,它和 retention policy 相关联。每一个存储策略下会存在许多shard,每一个 shard 存储一个指定时间段内的数据,并且不重复,例如 7点-8点 的数据落入 shard0中,8点-9点的数据则落入 shard1 中。每一个 shard 都对应一个底层的 tsm 存储引擎,有独立的 cache、wal、tsm file。 这样做的目的就是为了可以通过时间来快速定位到要查询数据的相关资源,加速查询的过程,并且也让之后的批量删除数据的操作变得非常简单且高效。

Linux安装RabbitMQ详细教程(图文)erlang24.1+RabbitMQ3.9.7

安装 erlang 1. 下载 erlang 安装包 在官网下载然后上传到 Linux 上或者直接使用下面的命令下载对应的版本。 进入下载目录,我是下载到了usr/local/src目录下了。我所有的安装包都在这个目录下 [root@kyn src]# wget http://erlang.org/download/otp_src_24.1.tar.gz 2.解压安装包 [root@kyn src]# tar -xvzf otp_src_24.1.tar.gz 3.安装 erlang 的依赖工具 [root@kyn src]# yum -y install make gcc gcc-c++ kernel-devel m4 ncurses-devel 4.创建安装目录,我的安装目录载usr/local/erlang [root@kyn local]# mkdir erlang 5.安装到指定目录 一定要切换到otp_src_24.1文件夹下操作 [root@kyn local]#cd src/otp_src_24.1 [root@kyn otp_src_24.1]# ./configure --prefix=/usr/local/erlang/ APPLICATIONS DISABLED下的警告是必须安装的 安装odbc,openssl:yum -y install unixODBC-devel openssl-devel 6.编译并安装 [root@kyn otp_src_24.1]# make && make install(时间会比较长) 7.查看是否安装成功 [root@kyn otp_src_24.1]# ./bin/erl 运行下面的语句输出“hello world” io:format("hello world~n"

python print(“\x“)的问题

字符串中\x应该是表示转译成对应的ASCII编码,但是转换过程很多文章中说的乱七八糟,自己尝试了一下总结如下: 1.首先明确是对数字对象进行转义,否则会报错 2.转义时将数字按16进制进行解析,比如48对应的16进制是72,72是字符 ‘H’ 对应的ASCII编码。 3.对于长度大于255的,不会报错,而是在尽可能解析足够长的长度后,保留之后的部分不变。

前端怎么处理鉴权?

一般来说鉴权我们主要针对rbac鉴权模式来进行控制主要分为:(组件(页面)鉴权路由鉴权) 第一种页面鉴权(组件鉴权) 用户有没有权限访问该页面,或者判断用户有没有通往该页面路由的权限 ①.组件鉴权 用户有没有权限访问页面的时候:通过路由守卫结合后端返回的token进行页面跳转之前的拦截并查看token是否过期以及是否拥有查看该页面的权限 ②.路由鉴权 判断用户有没有通往该页面路由(菜单,导航)的权限: 纯前端处理:在写路由表的时候 我们会在每个路由下加上meta,然后在meta写入可以访问该路由或页面的角色信息,然后我们可以通过该meta(买特)下的信息使用addrouter(唉的入特)控制该路由的显隐 前后端配合:每次登录的时候都要从后端获取该token下的路由表,保存在vuex里面,在通过addrouter动态渲染该token下的路由或导航 第二种ui鉴权 一般来说ui鉴权指的就是按钮鉴权 ui鉴权他的颗粒度很细,所以相对来说难度较大,我们可以通过统一的自定义指令来进行配置 处理ui鉴权简单的方法是: 我们可以获取token下的角色信息,用v-if处理该ui的显隐,但是这种方式的缺点也很明显,不宜与统一管理, 所有我们需要集中封装一个自定义指令,在自定义指令中集中处理鉴权的逻辑然后分发在每个需要鉴权的按钮上。

(_cai_) opencv学习笔记(2):图像梯度的计算

1.sobel算子 概述:x方向和y方向的算子如下图所示。将x方向的算子放入图像进行开窗计算,容易想象,在图像的边界区域,计算出的值绝对值较大,这样可以计算出垂直的边界;同样用Gy进行开窗计算,可以计算出水平边界。通过融合,我们可以获得图像的边界信息。 函数:cv::Sobel(cv::InputArray src, cv::OutputArray dst, int ddepth, int dx, int dy, int ksize = 3) 参数:还有一些边界填充的参数不做介绍。 cv::InputArray src输入图像cv::OutputArray dst输出图像int ddepth图像深度,默认为-1int dx需要计算垂直边界置1,否则置0 int dy 需要计算水平边界置1,否则置0int ksize = 3核大小 代码: #include <iostream> #include <opencv.hpp> #include <core/core.hpp> #include <highgui/highgui.hpp> using namespace cv; using namespace std; int main() { Mat image_1 = imread("lena.jpg"); Mat sobel_x; Mat sobel_y; Mat res; //这里使用的opencv环境是4.0.1,sobel运算之后好像会自动取绝对值, //不需要再使用convertScaleAbs()函数对结果取绝对值 Sobel(image_1, sobel_x, CV_8U, 1, 0); Sobel(image_1, sobel_y, CV_8U, 0, 1); //对x,y分别做sobel运算然后加权相加,比用一个sobel运算计算边缘效果要更好一些 addWeighted(sobel_x, 0.

Linux centos 7 部署JDK环境

目录 前言 准备 操作步骤 前言 在项目开发中不可或缺的一个步骤就是部署项目,其中运用jar包运行的项目难免会需要在服务器上部署JDK环境,此篇文章将对部署JDK步骤详解记录。 (此次所用:jdk-8u351-linux-aarch64.tar.gz) 下载路径:Java Downloads | Oracle 准备 1.准备jdk-8u351-linux-aarch64.tar.gz 记住后缀,windows上的不可在Linux上部署运行。 2.Linux 为centos 7系统版本 操作步骤 注:以下操作注明的路径 各位实际操作中最好弄成一样的 这样可以一路复制。 1.在centos上/usr/local/ 目录下创建 java文件夹 切换目录 cd /usr/local 创建java文件夹 mkdir java 2.上传 jdk-8u351-linux-aarch64.tar.gz到centos目录:/usr/local/java 可以使用CRT等可视化软件上传 也可以使用命令上传 切换目录 cd /usr/local 上传命令(在弹出的选择框中选取文件) rz 3.解压jdk-8u351-linux-aarch64.tar.gz 文件 tar -zxvf jdk-8u351-linux-aarch64.tar.gz 4.重命名jdk-8u351-linux-aarch64.tar.gz 文件 方便后续统一配置 重命名 mv jdk1.8.0_351 jdk1.8 5.修改配置文件 vim /etc/profile #在弹出的文本框后面加入下列配置(按字母 i 进入写入状态) export JAVA_HOME=/usr/local/java/jdk1.8 export JRE_HOME=/usr/local/java/jdk1.8/jre export CLASSPATH=.:$JAVA_HOME/lib:$JRE_HOME/lib:$CLASS_PATH export PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin:$JAVA_HOME #粘贴完成之后 按键盘 Esc 键再按 wq 回车 保存退出

Linux7.6—Shell编程 学习笔记 第三章:Shell高级进阶

Linux7.6—Shell编程 第三章:Shell高级进阶 文章目录 Linux7.6—Shell编程一.Shell运算符1.1.算数运算符1.2.关系运算符1.3.布尔(逻辑)运算符1.4.短路运算符1.5.字符串运算符1.6.文件测试运算符扩——``,$()扩——()、[]、{}、(())、[[]]等各种括号的使用1、小括号()1.1 单小括号()1.2 双小括号(()) 2、中括号[]2.1 单中括号[]2.2 双中括号[[]] 3、大括号{} 扩——逻辑运算,算数运算,短路运算 二.echo打印数据三.test命令四.Shell流程控制4.1. if4.2.case4.3. for4.4. while4.5. break4.6. continue 五.Shell函数 一.Shell运算符 1.1.算数运算符 运算符说明举例(a=10,b=20)+加expr $a + $b结果为30-减expr $a + $b结果为-10*乘expr $a + $b结果为200/除expr $a + $b结果为2%取余expr $a + $b结果为0=赋值a=$b将把变量b的值赋给a==相等,比较两端数值是否相等,相等返回ture$a == $b返回false!=不等,比较两端数值是否相等,不等返回ture$a != $b返回true #!/bin/bash a=10 b=20 num=`expr $a + $b`#或者num=$(expr $a + $b) echo "a + b = $num" num=`expr $a - $b` echo "a - b = $num" num=`expr $a \* $b`#乘法需要添加一个转义字符 echo "

org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient.choose

一、问题背景 二、报错截图如下 三、我的项目配置如下 <!-- 服务注册/发现--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!--使用Spring Cloud LoadBalancer 进行客户端负载均衡--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-loadbalancer</artifactId> <version>2.2.0.RELEASE</version> </dependency> 四、分析问题 五、问题原因 出现这个问题是没有loadbalancer,但是nacos中ribbon会造成loadbalancer包失效,所以在包中移除ribbion依赖,并加入loadbalancer依赖; 六、解决方式 <!--不使用Ribbon 进行客户端负载均衡--> <exclusions> <exclusion> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> </exclusion> </exclusions>

Notepad++安装、常用配置、Java运行环境

Notepad++安装、常用配置、Java运行环境 一、Notepad++下载​二、常用配置三、Java运行环境 一、Notepad++下载​ Notepad++官网:https://notepad-plus-plus.org/ 阿里云盘:https://www.aliyundrive.com/s/GhyEYcq4Rfa 百度网盘:https://pan.baidu.com/s/1DNl86RrwsAuv2HFlVPLUTQ?pwd=4npu 提取码:4npu 二、常用配置 1、自动换行:视图–>自动换行 2、文档列表:视图–>文档列表 3、文档结构图:视图–>文档结构图 4、文件关联:可以设置需要用Notepad++打开的文件,用管理员身份运行Notepad++, 设置—>首选项–>文件关联,选择需要的文件添加到右侧。 5、自动完成:可以自动补充完成符号,设置—>首选项–>自动完成 6、主题设置:根据喜好更改,设置–>语言格式设置 三、Java运行环境 1、首先查看插件->插件管理中已安装插件是否有NppExec​​​​,没有的话,点击可用,找到它并选择,点击安装。 2、插件—>NppExec—>execute NppExec script打开,添加命令java cd "$(CURRENT_DIRECTORY)" java $(NAME_PART) 添加命令,命名为javac javac "$(FULL_CURRENT_PATH)" 添加命令,命名为run NPP_SAVE javac "$(FULL_CURRENT_PATH)" cd "$(CURRENT_DIRECTORY)" java $(NAME_PART) 3、插件—>NppExec—>Advanced Options, 同样的步骤将javac,run添加上。 4、运行run,建一个java文件,名与类名要一致,保存后,点击宏–>run运行 总结:添加命令那块也可以直接添加命令,命名为run NPP_SAVE javac "$(FULL_CURRENT_PATH)" cd "$(CURRENT_DIRECTORY)" java $(NAME_PART) 不需要java与javac命名的脚本。 然后Advanced Options,只选择run就可。

Linux--Shell练习题

目录 一,第一套 二,第二套 三,第三套 四,第四套 五,第五套 六,第六套 七,第七套 八,第八套 一,第一套 1.利用脚本安装httpd vim http.sh 复制:(没有源代码的可以上CSDN搜索用户:征服bug,找到这个文章就可以复制了) #!/bin/bash #安装httpd服务 rpm -q httpd if [ $? -eq httpd ] then rpm -e httpd fi #安装依赖包 rpm -ivh /mnt/Packages/apr-1.4.8-3.el7.x86_64.rpm rpm -ivh /mnt/Packages/apr-devel-1.4.8-3.el7.x86_64.rpm rpm -ivh /mnt/Packages/cyrus-sasl-devel-2.1.26-20.el7_2.x86_64.rpm rpm -ivh /mnt/Packages/expat-devel-2.1.0-8.el7.x86_64.rpm rpm -ivh /mnt/Packages/libdb-devel-5.3.21-19.el7.x86_64.rpm rpm -ivh /mnt/Packages/openldap-devel-2.4.40-13.el7.x86_64.rpm rpm -ivh /mnt/Packages/apr-util-devel-1.5.2-6.el7.x86_64.rpm rpm -ivh /mnt/Packages/apr-util-1.5.2-6.el7.x86_64.rpm rpm -ivh /mnt/Packages/pcre-devel-8.32-15.el7_2.1.x86_64.rpm rpm -ivh /mnt/Packages/pcre-8.32-15.el7_2.1.x86_64.rpm #安装源代码包 tar zxf /mnt/tar/httpd-2.4.25.tar.gz -C /usr/src/ cd /usr/src/httpd-2.4.25/ .

axios封装

为什么在项目中封装axios? 为什么要对axios进行二次封装? 因为为了方便统一处理请求或处理接口,并且归纳请求时和响应时的回调函数,我们来统一管理axios的内置钩子函数,达到代码简洁易于管理 怎么对axios封装或二次封装? 1.用import引入axios 2.创建axios实例:用axios.create这个函数创建 3.在axios实例中配置基地址和延迟时间 4.封装axios请求拦截及响应拦截并处理Promise的then方法和catch方法 (1):其中token配置在请求拦截中并夹杂在axiso请求头上,随响应拦截一起进入请求 (2):请求拦截调用interceptors(因特赛不特死).request(瑞快死特).use并返回传入的信息 (3):响应拦截调用interceptors.response(瑞死榜死).use并返回响应拦截数据 env.js 配置环境 开发环境dev 线上环境prod 测试环境test 方便统一管理路径 export default { dev: { baseUrl: '' }, prod: { baseUrl: '' }, test: { baseUrl: '' } } request.js 1.创建axios实例 2.请求拦截器 3.响应拦截器 4.抛出axios对象 状态码 200:成功 500:接口报错 502::服务器问题,网络 400:请求出错 404:路径错误找不到 403:前后端请求错误

JMETER 时间函数使用

1、__time :获取时间戳、格式化时间 1)${__time(,)} :获取当前时间戳(当前时间的毫秒数),默认精确到毫秒级别,13位数,如:1650356704900 2)${__time(,time_ms)} :获取当前的时间戳并存入参数 time_ms 中 3)${__time(/1000,)} :获取当前时间的秒数,精确到秒级别,10位数,如:1650356723 4)${__time(/1000,time_s)} :获取当前时间的秒数并存入参数 time_s 中 5)${__time(yyyy-MM-dd,)} :获取当前日期,如:2022-04-19 6)${__time(yyyy-MM-dd,time_date)} :获取当前日期并存入参数 time_date 中 7)${__time(yyyy-MM-dd HH:mm:ss,)} :获取当前时间,固定格式,如:2022-04-19 16:21:30 8)${__time(yyyyMMddHHmmss,)} :获取当前时间,固定格式,如:20220419162107 9)${__time(YMDHMS,)} :获取当前时间,固定格式,如:20220419-161941 10)${__time(yyyy-MM-dd HH:mm:ss:SSS,)} :获取当前时间,固定格式,如:2022-04-19 16:23:02:876 11)${__time(yyyy-MM-dd'T'HH:mm:ss.SSS'Z',)} :获取当前时间,固定格式,如:2022-04-19T16:27:16.810Z 12)${__intSum(${__time(yyyy)},1,)} :在当前年上+1年 13)${__intSum(${__time(MM)},1,)} :在当前月上+1月 14)${__intSum(${__time(dd)},1,)} :在当前日上+1日

SQL 语句执行过程

想了解 SQL 的查询语句在 MySQL 内部的流转情况,就得先了解一下 MySQL 的基础架构,知道 MySQL 由哪些组件组成以及这些组件的作用是什么,才能帮助我们更好地去理解 SQL 语句的执行过程。 一般来说,MySQL 主要分为 Server 层和存储引擎层: Server 层:主要包括连接器、查询缓存、分析器、优化器、执行器等,所有跨存储引擎的功能都在这一层实现,比如存储过程、触发器、视图,函数等,还有一个通用的日志模块 binlog 日志模块也在这一层。存储引擎层:主要负责数据的存储和读取,采用可以替换的插件式架构,支持 InnoDB、MyISAM、Memory 等多个存储引擎,其中 InnoDB 引擎有自有的日志模块 redolog 模块。现在最常用的存储引擎是 InnoDB,它从 MySQL 5.5 版本开始就被当做默认存储引擎了。 Server 层各组件的功能有: 连接器:身份认证和权限相关(登录 MySQL 的时候)。查询缓存:执行查询语句的时候,会先查询缓存(MySQL 8.0 版本后移除,因为这个功能不太实用)。分析器:没有命中缓存的话,SQL 语句就会经过分析器。分析我们的的 SQL 语句要干什么,同时再检查 SQL 语句的语法是否正确。优化器:按照 MySQL 认为最优的方案去执行。执行器:执行语句,然后从存储引擎返回数据。 - Server 层基本组件: 连接器:连接器主要和身份认证和权限相关的功能相关,就好比一个级别很高的门卫一样。主要负责用户登录数据库,进行用户的身份认证,包括校验账户密码,权限等操作,如果用户账户密码已通过,连接器会到权限表中查询该用户的所有权限,之后在这个连接里的权限逻辑判断都是会依赖此时读取到的权限数据,也就是说,后续只要这个连接不断开,即使管理员修改了该用户的权限,该用户也是不受影响的。查询缓存:(因为这个功能不太常用,所以 MySQL 8.0 版本后移除)查询缓存主要用来缓存我们所执行的 SELECT 语句以及该语句的结果集。连接建立后,执行查询语句的时候,会首先查询缓存,MySQL 会先校验这个 SQL 是否执行过,以 key-value 的形式缓存在内存中,key 是查询预计,value 是结果集。如果缓存 key 被命中,就会直接返回给客户端,如果没有命中,就会执行后续的操作,完成后也会把结果缓存起来,方便下一次调用。当然在真正执行缓存查询的时候还是会校验用户的权限,是否有该表的查询条件。MySQL 查询不建议使用缓存,因为查询缓存失效在实际业务场景中可能会非常频繁,假如对一个表更新的话,这个表上的所有的查询缓存都会被清空。对于不经常更新的数据来说,使用缓存还是可以的。所以,一般在大多数情况下我们都是不推荐去使用查询缓存的。MySQL 8.0 版本后删除了缓存的功能,官方也是认为该功能在实际的应用场景比较少,所以干脆直接删掉了。分析器:如果 MySQL 没有命中缓存,那么就会进入分析器,分析器主要是用来分析 SQL 语句是来干什么的,分析器也会分为几步:第一步,词法分析。一条 SQL 语句由多个字符串组成,首先要提取关键字,比如 select,提出查询的表,提出字段名,提出查询条件等等。做完这些操作后,就会进入第二步。第二步,语法分析。主要就是判断输入的 SQL 是否正确,是否符合 MySQL 的语法。完成这 2 步之后,MySQL 就准备开始执行了,但是如何执行,怎么执行是最好的结果呢?这个时候就需要优化器上场了。优化器:优化器的作用就是以它认为的最优的执行方案去执行,比如多个索引的时候该如何选择索引,多表查询的时候如何选择关联顺序等,当然,其实优化器认为的最优方案也并不一定就是真正最优的方案。但是经过了优化器之后就可以说这个语句具体该如何执行就已经定下来。执行器:当选择了执行方案后,MySQL 就准备开始执行了,首先执行前会校验该用户有没有权限,如果没有权限,就会返回错误信息,如果有权限,就会去调用引擎的接口,返回接口执行的结果。 其实增删改查类型的 SQL 语句归根结底来说就是两种,一种是查询,一种是更新。

String 常用工具类

目录 commons-lang3的CharSequenceUtilscommons-lang3的StringUtils常用常量isequalscontainsreplace、removeindexOfdefaultwrap、prepend、append、pad 两端字符填充trim、strip 移除两端特殊字符startsWith、endsWithcountMatches 字符统计、reverse字符串反转、upperCase、lowerCase spring的StringUtils判断、统计删除、替换盘符、路径String数组、集合 ChineseHelper 繁简字转换 工具类封装的方法,相比于原生方法,往往做了很多额外校验、兼容、处理,比如校验了输入是否合法、兼容了NPE、判断了从其它地方获取的数据,使用起来要方便些。 apache的 common-lang3 工具类众多、方法齐全, 推荐使用。老版本类库是 commons-lang,新版本是 commons-lang3,尽量用 lang3 代替 lang。 <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.11</version> </dependency> commons-lang3的CharSequenceUtils //CharSequence转char[] char[] chars = CharSequenceUtils.toCharArray(charSequence); //提取子串,从指定位置到末尾。null返回null CharSequence charSequence = CharSequenceUtils.subSequence(charSequence, startIndex); commons-lang3的StringUtils 常用常量 spring的StringUtils没有提供常量,common-lang3提供了一些字符串常量 //空串 String empty = StringUtils.EMPTY; //换行符\n String lf = StringUtils.LF; //空格串,一个空格" " String space = StringUtils.SPACE; //找不到对应index时返回的-1 int indexNotFound = StringUtils.INDEX_NOT_FOUND; is //判断字符串是否为empty,null、空串都是empty boolean b1 = StringUtils.isEmpty("xxx"); boolean b2 = StringUtils.isNotEmpty("xxx"); //判断字符串是否是blank,null、空串、空格串都是blank boolean b3 = StringUtils.

深入浅出MFC之6大技术 消息映射( DECLARE_MESSAGE_MAP) 和命令传递 ON_NOTIFY ON_COMMAND ON_MESSAGE 三大难点解析

mfc把消息分为3大类 1.命令消息(wm_command) 一般来自工具栏和菜单栏,凡是派生自CCmdTarget的类,都可以接收命令消息。 2,标准消息(wm_) 凡是派生自cwnd类,都可以接收该消息。 3.notify 由控件产生,向其父窗口通知某种情况。 Windows 消息 消息可以分为系统定义消息和应用定义消息两大类。 系统保留的消息标识符值的范围是 0x0000 到 0x03FF(WM_USER - 1)。应用不能使用这些值作为私有消息在 0x0400(WM_USER)到 0x7FFFF 范围内的值用于私有窗口类的消息标识符。 windows使用两种方法将消派发到一个窗口消息处理函数:一是将消息放到消息队列(先进先出队列),二是不放到消息队列,直接发送到窗口消息处理函数,让窗口处理函数来处理消息。 派发到消息队列的消息被称为排队消息(Queued messages)。它们主要是用户输入事件,比如说鼠标或键盘消息盘,有WM_MOUSEMOVE消息,WM_LBUTTONDOWN,WM_KEYDOWN,和WM_CHAR消息。还有一些其他的,包括WM_TIMER,WM_PAINT,以及WM_QUIT。大多数其他的消息息,这是直接发送到窗口过程,被称为非队列消息(non queued messages)。 (1) 队列(Queued)消息 windows可同时显示任意数量的窗口。此时,系统使用消息队列来将键盘和鼠标事件正确的派发到正确的窗口。 windows维护着一个系统消息队列,以及分别为每个GUI线程维护一个各自的线程消息队列。为了避免非GUI线程的创建线程消息队列的开销,所有线程创建初始化时,均不创建消息队列。只有当线程第一次调用GDI函数时,系统才会为线程创建消息队列。所以那些非GUI线程是没有消息队列的。 每当用户移动鼠标,点击按钮或键盘时,鼠标或键盘的设备驱动程序会将输入转换成消息,并将消息放在系统消息队列里。删windows会检查自己的消息队列,如果消息队列不为空,则每次取出并删除一个消息,然后确定消息的目标窗口,然后把消息放到创建这个窗口的线程的线程消息队列里。线程的消息队列接收由线程创建的窗口的所有的鼠标和键盘消息。然后线程会从队列中删除信息,并告诉系统把它们派发到对应的窗口消息处理函数。 除了WM_PAINT, WM_TIMER和WM_QUIT消息以外,系统总是派发放在在消息队列的末尾的消息。这将保证让一个窗口以first-in, first-out的顺序接收消息。WM_PAINT,WM_TIMER,和WM_QUIT消息,会一直被保存在队列中,只有在队列中没有其他消息时才会被派发到窗口消息处理函数。此外,同一个窗口的多个WM_PAINT消息被合并成一个WM_PAINT消息,客户区的所有无效部分也会被合并。这样是为了减少窗口重绘客户区的次数。 系统通过填充一个 MSG 结构来将消息投递到线程的消息队列,随后将其拷贝到消息队列中。 MSG 结构的信息包括:指定窗口的句柄,消息标识符,两个消息参数,消息投递的时间,以及鼠标光标的位置。通过使用 PostMessage (异步的)和 PostThreadMessage 函数,线程可以将一个消息投递到自己的消息队列或其他线程的消息队列。 应用可以使用 GetMessage 来删除队列中的消息。要在不删除消息的情况下检查队列消息,应用可以使用 PeekMessage 函数,该函数会使用消息填充 MSG 。 在从队列删除消息后,应用可以使用 DispatchMessage 函数来指示系统把消息发送给窗口过程进行处理。DispatchMessage 接收一个 MSG 结构的指针,该结构已经使用 GetMessage 或 PeekMessage 填充过。DispatchMessage 将窗口句柄,消息标识符,和两个消息参数传递给窗口过程,但它不会传递时间和鼠标光标位置。应用在处理消息时可以通过 GetMessageTime 和 GetMessagePos 函数检索时间和位置信息。 (2) 非队列(Nonqueued)消息 Nonqueued消息被立即送往目的地的窗口消息处理函数,绕过了系统的消息队列和线程消息队列。系统通常会发送nonqueued消息,来通知那些会影响窗口的事件。例如,当用户激活一个新的应用程序窗口时,系统会发送一些列消息到窗口,包括WM_ACTIVATE,WM_SETFOCUS,WM_SETCURSOR。这些消息通知窗口被激活,键盘输入被定向到窗口,并且鼠标光标也移到窗口的边界内。 Nonqueued消息也有可能来源于应用程序调用系统函数。例如,系统调用SetWindowPos函数移动一个窗口后会发送WM_WINDOWPOSCHANGED消息。 一些函数也发送nonqueued消息, 有BroadcastSystemMessage,BroadcastSystemMessageEx,SendMessage(同步),SendMessageTimeout,和SendNotifyMessage。

基于quartz的定时任务动态启停实现分析(人人平台为例)

配置文件 位置在 module/job/config/ScheduleConfig @Configuration public class ScheduleConfig { @Bean public SchedulerFactoryBean schedulerFactoryBean(DataSource dataSource) { SchedulerFactoryBean factory = new SchedulerFactoryBean(); factory.setDataSource(dataSource); //quartz参数 Properties prop = new Properties(); prop.put("org.quartz.scheduler.instanceName", "RenrenScheduler"); prop.put("org.quartz.scheduler.instanceId", "AUTO"); //线程池配置 prop.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool"); prop.put("org.quartz.threadPool.threadCount", "25"); prop.put("org.quartz.threadPool.threadPriority", "5"); //JobStore配置 prop.put("org.quartz.jobStore.class", "org.springframework.scheduling.quartz.LocalDataSourceJobStore"); //集群配置 prop.put("org.quartz.jobStore.isClustered", "true"); prop.put("org.quartz.jobStore.clusterCheckinInterval", "15000"); prop.put("org.quartz.jobStore.maxMisfiresToHandleAtATime", "1"); // misfire 时间 单位 毫秒 prop.put("org.quartz.jobStore.misfireThreshold", "12000"); prop.put("org.quartz.jobStore.tablePrefix", "QRTZ_"); prop.put("org.quartz.jobStore.selectWithLockSQL", "SELECT * FROM {0}LOCKS UPDLOCK WHERE LOCK_NAME = ?"); //PostgreSQL数据库,需要打开此注释 //prop.put("org.quartz.jobStore.driverDelegateClass", "org.quartz.impl.jdbcjobstore.PostgreSQLDelegate"); factory.

【Excel】乱序不同行数的两列数据对比匹配

1 情境 表格需求: 以上乱序不同行数的两个表格分别为总名单和签到表,需要在总名单中找到未签到人员。 表格特点: [表2:签到表] 为 [表1:总名单] 的子集;两表顺序错乱;不同姓名对应身份证号前十五位有完全相同的情况。 注意事项: 匹配数据应以身份证号为索引,且18位数字完全匹配,因为有重名和身份证号多位相同可能性,且部分函数只能处理15位字符串。 2 实现方案 2.1 方法一:countif 函数 所需函数: countif(数据列,单元格数据) = 单元格数据在数据列中出现的次数if(判断语句,成立输出,不成立输出) 输入如下公式: =IF(COUNTIF($E$3:$E$18,B3&"*")=1,"已签到","未签到") 下拉即可,如图: 注意: 使用$绝对引用(快捷键:F4)数据列,防止相对引用下拉变动;countif函数只能识别15位数字,而身份证号有18位,若两组数据前15位相同则输出结果会产生错误,故需在单元格B3后连接通配符*,即B3&"*",强制其以文本形式匹配。 2.2 方法二:vlookup / xlookup 函数 所需函数: vlookup(查找值, 查找区域, 返回查找区域的第几列数据, 精确查找输入参数"0"or"false" 或 模糊查找输入参数"1"or"true")#注意第一参数查找值必须位于第二参数查找区域的第一列;匹配索引需格式统一。iferror(条件, 条件错误时的返回值)#这里用于处理vlookup产生的#N/A错误值,使之不影响后续公式运行;这个需求也可由功能更强大的xlookup函数第四参数替代,用法见4。len(条件) = 字符串长度xlookup(【第一参数】查找值(多条件查询用"&"连接),【第二参数】查找区域,【第三参数】值返回区域,【第四参数(可选参数)】无匹配结果返回值(省略则返回#N/A),【第五参数(可选参数)】匹配类型(-1,0,1,2),【第六参数(可选参数)】搜索模式(-2,-1,1,2)) 匹配类型: 0 - 完全匹配。 如果未找到,则返回 #N/A。 这是默认选项。-1 - 完全匹配。 如果没有找到,则返回下一个较小的项。1 - 完全匹配。 如果没有找到,则返回下一个较大的项。2 - 通配符匹配,其中 *, ? 和 ~ 有特殊含义。 搜索模式:1 - 从第一项开始执行搜索。 这是默认选项。-1 - 从最后一项开始执行反向搜索。2 - 执行依赖于 lookup_array 按升序排序的二进制搜索。 如果未排序,将返回无效结果。2 - 执行依赖于 lookup_array 按降序排序的二进制搜索。 如果未排序,将返回无效结果。 输入如下公式:

为什么评论会被折叠?

评论是读者与作者、读者与读者间进行互动的重要形式,其表现形式为:问题的探讨、观点的交流、意见的输出、对作者的支持和鼓励方面的言语表达等。其不仅作为互动的媒介,同样也是社区氛围的一种体现,良好的评论氛围有助于建设和维护健康、积极的社区生态。 但随着时间积累和维护上的松懈,尤其业务上的一些特性,导致部分用户带有目的性或无意识的制造一些对于社区氛围起到不良影响的评论内容。 其主要表现为站外导流或站内导流,发布主体为教育机构、灰产或不良自媒体等,同时部分用户也会较频繁的输出与文章内容无关且意义不大的评论内容。 为了实现良好的社区氛围和评论环境,我们将会对部分评论内容进行折叠,包含但不限于: 广告推广类评论邀请回访、回赞简短的惊叹、夸张类情绪词或短语负面情绪的表达与内容完全无关两个字及两个字以下的评论包含禁用词 目前功能正在试运行中,如果大家有任何意见和想法,欢迎大家在评论区内进行讨论交流;当然,如果您想自由地发表各种意见, 建议直接到灌水乐园社区发表,感谢您的支持。

如何生成流程引擎activiti数据库表

首先第一步,引入activiti依赖 <dependencies> <!-- activiti 工作流 --> <dependency> <groupId>org.activiti</groupId> <artifactId>activiti-spring-boot-starter</artifactId> </dependency> <!--mysql 数据库--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> </dependencies> 这里也需要引入security的依赖 因为activiti需要 第二步创建测试类,用于生成我们的数据库表,因为我用的是Java17 用var来接收变量,如果用的是Java8则不能使用该语法 复制完代码删除var,alt+enter 自动生成变量类型即可 import org.activiti.engine.ProcessEngineConfiguration; public class Test { @org.junit.jupiter.api.Test public void creteTable() { var processEngineConfiguration = ProcessEngineConfiguration.createStandaloneProcessEngineConfiguration(); //连接数据库的配置 var url = "jdbc:mysql://localhost:3306/chihiro_activiti?&nullCatalogMeansCurrent=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true"; processEngineConfiguration.setJdbcDriver("com.mysql.jdbc.Driver"); processEngineConfiguration.setJdbcUrl(url); processEngineConfiguration.setJdbcUsername("root"); processEngineConfiguration.setJdbcPassword("Lrst123456"); //表如果不存在 则自动创建表 processEngineConfiguration.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE); //创建 var processEngine = processEngineConfiguration.buildProcessEngine(); System.out.println("processEngine:" + processEngine); } } 直接点击运行即可生成 activiti的二十多张数据库表,如下图所示:

第八章(无人售货机零售项目实战)

分组聚合客户订单 无人售货机客户订单信息表记录着有关客户的订单信息。 从客户的角度出发,分析客户订单信息表中的数据,了解客户订单状况,按照客户订单数据进行聚合计算,对客户订单消费金额从高到低进行排序,了解哪些客户的消费金额较多,并为这些客户提供更好的服务。 数据准备 聚合客户订单数据,需要在订单信息表“order_list.csv”文件中抽取以下字段数据。 (1) customerid(客户ID):客户的唯一标识号,以该标识号聚合数据,因此客户ID不能为空,否则客户ID为空的数据将被过滤掉。 (2) customermobile(客户手机号码):客户支付费用时所使用的手机号码。 (3) ordernum(订单号):客户购买商品时生成的订单号。 (4) paytotalprice(订单实际支付金额):客户订单实际支付金额。 (5) status(订单状态):客户订单状态,只需抽取订单状态为“支付成功”的数据,而其他订单状态的数据将被过滤掉。 创建转换 (1)创建CSV文件输入组件和获取订单数据。创建CSV文件输入组件(组件命名为“CSV文件输入(订单)”),如图所示。设置参数,导入“order_list.csv”文件,并设置好字段参数。 (2)建立过滤和抽取数据组件和连接。创建过滤记录组件(组件命名为“过滤记录(客户ID非空和支付成功)”)、字段选择组件,用于筛选和抽取数据,并建立组件之间的连接,如图所示。 (3)进行字段选择,保留需要的字段,去除多余的字段。在【字段选择】组件中,设置参数,仅保留customerid、customermobile、ordernum和paytotalprice等字段,并分别改名为“客户ID”“客户手机号码”“order_num”和“pay_totalprice”,如图所示,丢弃其他与聚合客户订单无关的字段。 (4)对客户ID进行排序。因为是分组聚合客户订单,所以必须对客户ID进行排序,即同一个客户ID的数据要连在一起,否则数据可能不正确。在【排序记录】组件中,设置客户ID字段按照升序进行排序。 (5)对客户的订单数和商品实际支付金额等字段进行分组聚合,统计各个客户的订单。设置【分组】组件参数,在下图所示的【分组】对话框的【构成分组的字段】表中,设置【分组字段】为“客户ID”“客户手机号码”,即按照“客户ID”“客户手机号码”统计客户订单;在【聚合】表中,设置的参数如图所示。 (6)根据客户订单消费金额进行排序。在【排序记录(按客户销售金额排序)】组件中,设置客户消费金额字段按降序进行排序。 (7)将经过排序的各客户订单数据输出并装载至Excel文件中。在【Excel输出(客户订单)】组件中,设置参数,输出的Excel文件名为“无人售货机分组聚合客户订单.xls”,输出的字段参数设置如表所示。 运行 计算各个商品的消费金额 无人售货机客户订单的详情数据,记录着订单中的每种商品销售的数量、价格等数据。 从商品销售的角度出发,分析商品的销售数据,计算各种商品的销售金额,以便了解商品的销售情况,分析哪些商品属于热销或滞销商品,为商品的销售提供更好的运营决策。 创建转换 (1) 创建CSV文件输入组件和获取数据。创建CSV文件输入组件,组件命名为【CSV文件输入(订单)】,如图所示。设置组件参数,导入“order_details.csv”文件,并设置好字段参数,订单生成时间createdtime字段的字段类型需要设置为String。 (2)过滤掉售货机ID为空和支付失败的订单。在【过滤记录(售货机ID非空和支付成功)】组件中,设置参数,保留售货机ID非空和支付成功的订单,过滤掉售货机ID为空和支付不成功的订单. (3)进行字段选择,保留需要的字段,去除多余的字段。在【字段选择】组件中,设置参数,仅保留productname、amount、productpaytotalprice等字段,并分别改名为“商品名称”“product_number”“product_paytotalprice”,如图所示,丢弃其他与计算各商品销售金额无关的字段。 (4)对商品名称进行排序。因为需要计算各商品的销售金额,所以必须对商品名称进行排序,在【排序记录】组件中,对商品名称字段按照升序进行排序。 (5)对购买商品数量和商品实际支付总金额等字段进行聚合计算,统计各个商品的销售金额。在【分组(按商品名称统计)】组件中,有关参数设置如图所示。 (6)根据商品销售金额进行排序。在【排序记录(按销售金额排序)】组件中,设置商品销售金额字段按照降序排序。 (7)将经过排序的各商品销售金额数据输出并装载至Excel文件中。在【Excel输出(各商品销售金额)】组件中,设置参数,输出的Excel文件名为“无人售货机各商品销售金额.xls”,输出的字段参数如表所示。 运行 品销售金额商品销售金 计算各商品销售金额 计算各商品销额

常用巡检命令

思科设备: show version:查看系统软、硬件版本信息。 show running-config:查看设备运行的配置信息。 show ip interfaces brief:查看所有接口摘要信息。 show interfaces:查看全部接口信息。 show cdp neighbor:查看思科设备互联信息。 show ip protocol:查看设备运行的路由协议情况。 show ip ospf neighbor:查看 OSPF 邻居状态信息。 show ip eigrp neighbor:查看 EIGRP 邻居状态信息。 show ip route summary:查看路由汇总信息。 show ip route:查看设备路由表信息。 dir all:查看所有系统文件信息,含设备启动文件。 show bootflash:查看 BOOTFLASH 文件信息。 show diagbus:查看路由设备板卡信息。 show module :查看交换设备板卡信息。 show inventory:查看设备硬件型号及序列号。 show environment all:查看设备环境信息,如电源、风扇等。 show log:查看系统日志信息。 show buffer:查看系统缓存状态 show process cpu: 查看设备 CPU 利用信息。 show process cpu history:查看 CPU 最高利用率 show process memory:查看设备内存使用信息。 show context:查看设备故障类型信息。 show standby brief:查看 HSRP 信息摘要。 show vlan:查看 VLAN 信息。 华三设备: display version: 查看系统软、硬件版本信息。 display current-configuration:查看设备当前运行配置信息。 display ip interfaces brief:查看所有接口摘要信息。 display interfaces:查看全部接口信息。 display ospf peer:查看 OSPF 邻居状态。 display ip route statistics:查看路由汇总信息。 display ip routing-table:查看全部路由信息。 display cpu:查看 CPU 使用信息。 display memory:查看内存使用信息。 display power:查看电源信息。 display log:查看系统日志信息。 display device:查看设备硬件板卡信息。 display vlan all:查看 VLAN 信息。 display vrrp:查看 VRRP 状态信息。 以上仅为巡检常用信息,其他用户具体抓取信息可参照相关巡检文档模板进 行操作。

10.31周报-人体姿态估计CPN

目录 前言文章背景解决了什么问题主要思路方法多人姿态估计CPNGlobalNetRefineNet 实验 总结 前言 本周进行了CPN算法思想的学习 文章 标题:Cascaded Pyramid Network for Multi-Person Pose Estimation 作者:Yilun Chen Zhicheng Wang Yuxiang Peng Zhiqiang Zhang Gang Yu Jian Sun 背景 论文提出提出了一种网络结构,能够对不可见的关键点,重叠的关键点,模糊难以辨识的关键点的检测,克服复杂背景的影响。 网络分为两部分: GlobalNet:为一个FPN网络,用来检测比较简单的关键点,如眼睛,手;但对不可见的等较难的点判断并不是很好。 RefineNet:主要是用来检测非常难分辨的关键点,他的输入的GlobalNet的几个不同层次的特征来在线的对判断困难的关键点进行检测。 论文的方法获得了COCO 人体姿态点检测的2017年冠军,在COCO test-dev上的平均检测精度为73.0,在COCO test-challenge 数据集上平均检测精度 72.1,比2016年冠军的60.5高出了19% 解决了什么问题 多人姿态估计所面临的挑战,关键点遮挡,关键点不可见,复杂背景等提出的 Cascaded Pyramid Network (CPN) 方法,即着重于处理 “困难hard” 关键点 主要思路 下面这张图阐述了作者的网络设计思路,即一些比较容易识别出来的人体关键点,直接利用一个CNN模型就可以回归得到;而对于一些遮挡比较严重的关节点,则需要增大局部区域感受野以及结合上下文信息才能够进一步refine得到 方法 多人姿态估计 主要包括两部分 [1] - 人体边界框检测 Human Detector [2] - 关键点估计 CPN 整体框架采用Top-down自上而下的检测策略。首先使用行人检测框架,先检测出行人候选框。然后使用本文的CPN网络对每一个检测出来的行人候选框进行人体关键点的回归,进而输出最终结果 CPN 主要包括两个子网络 GlobalNet GlobalNet的输入并不是一幅图像,而是Resnet的4个blocks提取出的特征图,论文中分别以C2,C3,C4,C5来代表。其中C2,C3由于层数较浅,所以有很高的空间精度即能够很好的定位原图信息,但是语义信息不足;相反,C4,C5,拥有较高的语义信息,但是空间分辨率较低,不足以定位图像信息。所以,GlobalNet采用FPN的结构充分的利用各个层次的不同信息来对关键点的heatmap进行预测。GlobalNet与FPN稍有不同,在升采样(upsampling process)之后,两层相加之前,要再进行一次1×1的卷积操作 RefineNet 基于 GlobalNet 生成的特征金字塔表示,再添加 RefineNet,定位 “hard” 关键点.

scss @for与rgba函数巧妙使用

SCSS @for与rgba函数使用 这里再次记录下~~~ 文章目录 SCSS @for与rgba函数使用效果图templatejsscss其他用法@each参数变量`...`占位符选择器 %foo@at-root 效果图 template <template> <view class="list"> <view class="item" :class="[`item-${(index + 1)}`, (currentIdx == index) ? 'active' : '']" v-for="(item, index) in 8" :key="index" @click="testTap(index)"> <!-- 使用var函数 --> <text class="item-txt" :style="{'--color': setColor}">{{ index + 1 }}</text> </view> </view> </template> js data() { return { currentIdx: -1, setColor: '#d75efb', } } testTap(idx) { this.currentIdx = idx; }, scss <style lang="scss" scoped> // 定义色值 $color-list: #FDC376, #7474ec, #5da6fb, #ffad27, #d75efb, #9fff10, #FF691D, #FF1D17; @for $i from 1 through length($color-list) { // 获取数组 $i 对应的下标值 即颜色值 $item: nth($color-list, $i); .

JDK8与JDK17同时进行环境配置

JDK8和JDK11这两个版本是长期维护稳定版,建议学习 JDK8与JDK17同时进行环境配置 为两个JDK新建两个JAVA_HOME,分别指定安装路径。 然后创建JAVA_HOME指定用的JDK(以后用8或17在这里切换) Path中删掉自动添加的C:\ProgramData\Oracle\Java\javapath这条变量配置 添加%JAVA_HOME%\bin 到此,配置完成。 完成后,win+R输入cmd,用java -version和javac命令验证一下就可。

ubuntu 15.10 不接网络开机会卡在Raise network interfaces

ubuntu 15.10 不接网络开机会卡在Raise network interfaces, 解决方法: step1. sudo mkdir -p /etc/systemd/system/networking.service.d step2. sudo cd /etc/systemd/system/ && ln -s networking.service.d ifupdown.service.d step3. 创建一个文件: /etc/systemd/system/networking.service.d/reduce-timeout.conf 内容是: [Service] TimeoutStartSec=5

记录一次因为InetAddress.getLocalHost()缓慢导致系统Websocket连接慢的坑

问题描述 系统在本地开发测试时Websocket连接很正常,都是秒连。但打包完部署到linux上运行,Websocket连接特别慢,平均要花10秒左右才能建立连接。 框架结构 整体采用前后端分离开发: 前端:Vue.js+sockjs-client+Webstomp-client 后端:Springboot+WebStomp 关于前后端Websocket具体实现,可移步我的另一篇博客: 前后端分离WebSocket +Springboot 实战详解 过程 排除了网络问题之后,在一步步的Debug之中,拨开了Bug的层层面纱。最终发现原来是Java原生方法InetAddress.getLocalHost()的坑~ 在websocket连接过程中,会将http协议升级为websocket协议,在升级过程中,调用了InetAddress.getLocalHost(),而这个方法的底层获取依赖于JDK原生InetAddress类的操作。 下面是JDK中InetAddress类的描述 InetAddress Caching The InetAddress class has a cache to store successful as well as unsuccessful host name resolutions. By default, when a security manager is installed, in order to protect against DNS spoofing attacks, the result of positive host name resolutions are cached forever. When a security manager is not installed, the default behavior is to cache entries for a finite (implementation dependent) period of time.

OSPF 知识点总结

随笔一篇,以便日后翻阅,如有问题欢迎指正 eNSP版本:1.3.00.100 目录 前言Ⅰ . OSPF 概述一、OSPF简介二、链路状态路由协议工作流程 Ⅱ . OSPF 概念一、区域二、Router - ID三、度量值四、OSPF协议报文类型五、OSPF三大表项 —— 邻居表六、OSPF三大表项 —— LSDB 表七、OSPF三大表项 —— OSPF路由表 Ⅲ . OSPF 工作原理一、OSPF 邻居建立二、OSPF 网络类型1. P2P —— Point-to-Point(点对点)2、P2MP —— Point Multi-Point(点到多点)3、BMA —— Broadcast Multiple Access(广播式多路访问)4、NBMA —— Non-Broadcast Multiple Access(非广播式多路访问) 三、DR / BDR四、OSPF 单区域五、OSPF 多区域六、OSPF 路由器类型 Ⅳ . OSPF 基础配置Ⅴ . OSPF配置案例 前言 先认识一些知识点和术语: 静态路由的缺点: 无法适应大规模的网络无法动态响应网络变化 既然静态路由无法满足动态响应,那便采用不同的动态协议 (此处仅按照工作机制和算法分类): 距离矢量路由协议(Distance Vector Routing Protocols):运行协议的路由器周期性泛洪自己的路由表,对于路由器自身而言并不知道网络拓扑结构,只是简单明白要去往的目的地在哪里、有多远。例如:RIP协议 链路状态路由协议(Link-State Routing Protocols):宣告的是 LSA ,描述了路由器接口的状态信息(接口开销、连接对象),最终每台路由器会形成自己的数据库(路由详情参数表)。例如:OSPF协议、IS-IS协议。 LSDB:链路状态数据库,用于描述整个区域所有接口相关状态的信息 RIB(Routing Information Base):路由信息表,存储所有的路由信息:

Linux 安装 JDK 和 Tomcat

Linux 安装 JDK 和 Tomcat 1.安装包下载2.安装JDK3.安装Tomcat4.通过浏览器访问5. tomcat 的其他配置 1.安装包下载 下载 JDK_8,由于下载 JDK 的时候,需要注册才能下载,选择对应系统版本的 xxxx.tar.gz 下载Tomcat_8,选择Core下的tar.gz 2.安装JDK 将 JDK 通过工具上传到 Linux 上的 /usr/local/jdk/目录下。 解压安装包 # 解压 jdk 安装包 [root@localhost jdk] tar -zxvf jdk-8u351-linux-x64.tar.gz 配置环境变量 # 打开配置环境变量的文件 [root@localhost jdk]# vim /etc/profile # 点击 i,插入以下四行内容 JAVA_HOME=/usr/local/jdk/jdk1.8.0_351 CLASSPATH=.:$JAVA_HOME/lib.tools.jar PATH=$JAVA_HOME/bin:$PATH export JAVA_HOME CLASSPATH PATH # 输入以上内容后,点击 esc,然后点击英文冒号,在输入wq # 刷新配置 [root@localhost jdk] source /etc/profile # 查看Java版本 [root@localhost jdk] java -version 3.安装Tomcat 将 Tomcat 通过工具上传到 Linux 上的 /usr/local/目录下。

云化Web IDE,在线开发新模式

目录 前言 一、初识云IDE 二、CSDN 云IDE 1、如何使用云IDE 2、使用云IDE 三、云IDE的使用感受 四、总结 前言 工欲善其事必先利其器,作为程序员,我们在编写代码的时候,一定会选用一款得心应手的工具。就像行走江湖的侠客,手里必有一件称手的兵器。一般,常见的场景下,我们一般都会安装IDE,比如Eclipse或者Idea之于Java,VSCode之于Html、JavaScript、Vue、React等等,当然,VsCode并非只为前端而生,它是一款集大成者,也可以用于Java开发、Python开发、C和C++等等,都是可以的。 不管你选用哪种IDE,那首先必须要先到它的官方网站上下载到相应的安装包,然后再在本地进行安装,同时还要安装对应的基础环境依赖。比如基础的JDK啊,Node等等。如果换了一个电脑,还需要把这些环境重头开始。离线IDE的好处就是高度定制,完全根据个人开发者的需要来使用。麻烦一点的就是更换电脑时需要重新安装一遍环境,有点废时间。 一、初识云IDE 云IDE是一种创新的形式,是一种脱离了本地依赖环境的存在。它是重服务端、瘦客户端的新开发模式,它将开发IDE需要的依赖都进行云化。开发者只需要使用使用一款Web浏览器就可以连接云IDE,基于云IDE进行代码研发。 在本地模式开发时,我们会遇到以下的一些问题: 1.代码编译性能要求高,稍微大一点的代码文件,编译一次时间很长; 2.代码开发环境配置多而复杂,容易配置并且容易配置错误; 3.开发在移动办公或者疫情需要在家办公的时候,对网络环境等问题没有办法解决; 4.开发在团队协作的时候,不能分享自己的编程空间,排查解决问题麻烦并且效率低; 5.开发还有安全隐患,可能会造成敏感数据的泄露和传播。 二、CSDN 云IDE 正是以上的一些原因,现在要伴随着疫情的随时发生。各大技术云都推出了自己的云IDE,比如知名的全球知名中文IT技术交流平台CSDN就开放了CSDN的云IDE。云IDE是CSDN开发云为开发者打造的一款低代码开发产品,云端预制了常见的开发环境,无需下载安装,一键创建项目,灵活配置代码仓和云主机。同时支持在线安装 VSCode 插件来增强使用体验,支持从基础组件快速构建高阶组件,无需重新编写组件,提高研发效率。随时随地开发编码,拥有媲美本地IDE 的流畅编码体验。 下面这是CSDN云IDE的产品介绍,总的来说它有四个大的优点。第一点是学生免费,对于还是学生的用户真的是福音。为CSDN点赞,可以体验高效的云化开发模式。第二点是多环境支持,在云IDE,已经预制了常见的开发环境,以及一些基础依赖都已经安装配置好,开箱即用。第三点是在线预览,快速生成预览,方便展示项目和在线调试。第四点是持久化能力,随时随地编写,持久化保存你的每一行代码。写完后可以直接提交并同步推送到远程仓库,从而实现共享。 1、如何使用云IDE 在开发云的首页,点击立即试用即可进入到环境配置界面。 上面是个人的一些创建的云IDE工作空间信息。你可以点击新建工作空间来创建。 2、使用云IDE 在创建好工作空间后,点击启动按钮即可进入云IDE的界面 这个IDE的界面是不是熟悉的配方,熟悉的味道。没错,你可以把它理解成VsCode。 至此,你已经完成了云IDE的环境搭建,然后你可以在这里进行工程项目的开发。比如你需要 在工程中上传文件也是可以的。 如果发现需要额外扩展安装插件也是非常简单的。 个人比较喜欢它的实时预览功能,在一个界面上就把代码、功能界面都展示出来,一目了然。 怎么样?心动了吗,快跟随脚步一起来使用这个云IDE吧。免费使用地址:点击【云IDE】,即可开始创建工作空间啦~。希望云IDE将为各位技术er一键秒级构建云开发环境,提升开发效率! 三、云IDE的使用感受 虽然云IDE在使用方面尽量保持了跟离线环境IDE的一致性,但因为云化方式的模式区别,依然存在一下区别,比如对于文件需要上传等等,音视频和图片等等静态资源,都需要上传到工程目录中。作为新手,刚开始进入工作空间时,也是有点手足无措,不知道如何进行开发。真心期望管官方运营可以把使用手册等放到明显的位置,以方便大家即时阅读。 在开发过程当中呢,对于有一些环境依赖,存在下载报错的问题。比如刚开始的时候配置了Live-Server时,不知道什么原因,一直报错。推出工作空间后,再进入就可以了。这种方式,确实对开发者存在一点迷惑,不知道是什么原因造成的。 总体来说,云IDE的功能是比较全面和完整的,基本可以支撑满足我们的系统开发工作。界面比较清新,IDE的操作界面与VsCode几乎无差别,只要你熟悉了VSCode的开发方式,上手这个云IDE几乎是零成本。 四、总结 本文主要介绍了云IDE这种开发新模式,包括本地IDE和云IDE的区别。CSDN云IDE的产品介绍,功能特点,如何进入并使用这个IDE。还介绍了一个实际的使用IDE开发的项目,最后对云IDE提出了一些建议和期望,衷心祝云IDE越办越好,成为广大程序员朋友的称手兵器。 未来,云IDE应该是一种趋势,现在疫情反复焦灼,一直没有完全治好。对于做程序员的我们,可以畅享基于互联网的云化IDE开发新模式,不受制于客户端,不受制于环境,实现云上开发,云上部署,为企业降本增效。

golang-context(上下文总结)

<一>go-Context使用笔记: 1.context.WithCancel() 功能:返回一个继承的Context,在父协程context的Done函数被关闭时会关闭自己的Done通道,或者在执行了如下cancel函数之后,会关闭自己的Done通道。这种关闭的通道可以作为一种广播的通知操作,告诉所有context相关的函数停止当前的工作直接返回。通常使用场景用于主协程用于控制子协程的退出,用于一对多处理。 用法: ctx,cancel := context.WithCancel(context.Background()) defer cancel() 举例:主协程序控制通知子协程序安全退出 package main import ( "context" "fmt" "reflect" "time" ) func main() { // 控制子协程安全的退出,调用cancle后,会关闭自己的通道,表示程序结束,所有子协程会安全的退出 ctx, cancle := context.WithCancel(context.Background()) defer cancle() // 取消函数上下文 go func() { for { select { // ctx为一个接口类型,存储的就是一个cancelCtx结构的地址,所以,表面看起来就是一个值传递,实质上就是地址,接口接受很好表现了封装完整性 case <-ctx.Done(): return default: fmt.Println("go first ", reflect.TypeOf(ctx).Elem().Name()) } time.Sleep(time.Second) } }() go func() { for { select { case <-ctx.Done(): return default: fmt.Println("go second ", reflect.TypeOf(ctx).Elem().Name()) } time.

uniapp HBuilder 无法运行微信小程序的问题解决

uniapp HBuilder 无法运行微信小程序的问题解决 一、问题描述 当在 HBuilder 中新建一个空白项目,以微信小程序运行的时候,提示以下信息且没有运行成功。 二、原因 原因其实已经在错误信息中写的很明白了,就是 微信开发工具里的安全设置中没有开启对应的服务端口。 并且也写了如何操作: 打开微信开发者工具点击 【设置】 - 【安全设置】 -【开启服务端口】 三、问题解决 然后再执行一次 以微信开发者工具运行 就成功了 成功调起微信小程序开发工具,并正常运行 uniapp 项目。

pycharm中opencv无法自动补全

1.前提 opencv的路径上一定不能有中文,空格。 比如下面是正确的实例 2.设置方法 打开seting 打开python interpreter 将库目录增加到cv2一级 最后一路ok就可以了。

睡眠微事件检测——DOESED论文复现问题解决

在**《DOSED: A deep learning approach to detect multiple sleep micro-events in EEG signal》**这篇论文复现中,由于网上对这篇论文的介绍较少,并且在论文复现中可能会出现问题,因此从此篇文章开始,将对DOSED论文复现中所出现的问题进行解决过程。 为了要下载DOSED训练所需的睡眠训练数据集,并且将其转化成H5编码格式,需要运行download_data.py文件;代码如下:(这里需要事先跳转到当前工程文件所在的根目录下,再在terminal中运行以下代码) python minimum_example/download_data.py ./data/downloads/ 此时可能会出现以下的错误: 以上错误,一开始还以为是在ssl_.py文件下没有对应的变量PROTOCOL_TLS;然后找了网上现有的解决方法都行不通。 后来对于该问题还是要从源头进行查找,发现可能是python环境下boto3这个库的版本和该程序不匹配;于是乎找到requirement.txt文件下的所需版本进行boto3的版本更新。最终发现就是boto3的版本原因,需要更新到1.9.31。(至于boto3的版本更新可以直接到File->Settings下进行修改) 数据下载结果: 最终在data/downloads/下就能看到下载的数据集。(如下所示) 运行过程如下:

Nginx超简单实现双机热备

使用场景:用Nginx做双机热备,做负载均衡 实现效果:部署完全一毛一样的两台服务器49服务器和90服务器,然后还需要一台中转服务器70,专门用于Nginx监听域名请求,当域名请求70服务器的时候,会自动转发给49和90服务器,设置权重为1,轮流转发。 假设服务器分配: 客户访问机器IP:192.168.137.70 //Nginx接收访问请求,并转发到49和90服务器 真实服务机器IP:192.168.137.49 //IIS或者Apache,接受Nginx转发过来的请求 真实服务机器IP:192.168.137.90 //IIS或者Apache,接受Nginx转发过来的请求 代码超简单实现,有需要可以自行补充: # 此行为注释,可删除,以下为代码内容,保存文件为 php_serv_80.conf upstream Flex { server 192.168.137.49:80 weight=1; server 192.168.137.90:80 weight=1; } server { listen 80; server_name test1.tp.top test2.tp.top ; add_header Real-Ip $upstream_addr; location / { index index.php index.html index.htm default.php default.htm default.html; proxy_pass http://Flex; proxy_set_header Host $host; } access_log D:/BtSoft/wwwlogs/php_serv_80.log; error_log D:/BtSoft/wwwlogs/php_serv_80.error.log; } # 此行为注释,可删除,以上为代码内容,保存文件为 php_serv_80.conf 实现功能:域名test1.tp.top和域名test2.tp.top请求70服务器都会被转发到49和90服务器

机器学习项目一:利用随机森林回归算法预测黄金价格

import numpy as np import pandas as pd import matplotlib.pyplot as plt import seaborn as sns from sklearn import metrics from sklearn.model_selection import train_test_split from sklearn.ensemble import RandomForestRegressor #读取数据 gold_data = pd.read_csv('data/gld_price_data.csv') gold_data.head() # 划分特征和标签 X = gold_data.drop(columns=['Date','GLD'],axis=1) y = gold_data['GLD'] 划分数据集 X_train,X_test,y_train,y_test = train_test_split(X,y,test_size = 0.2,random_state =2) model = RandomForestRegressor(n_estimators=100) model.fit(X_train,y_train) #模型预测 pred = model.predict(X_test) #结果可视化 plt.plot(y_test,color = 'blue',label = 'Actual Value') plt.plot(pred,color = 'green',label = 'Pedicition Value') plt.

stream分组求和

1、stream.collector.groupingby(分组字段,Collectors.summeraizingxxx) 如果是double求和会丢失精度,如果存在精度丢失的情况推荐方法二 2、stream.collector.groupingby(分组字段,Collectors.reduce(bigdecimal.ZERO, 求和字段,Bigdecimal::add))

运行代码时出现ModuleNotFoundError: No module named ‘tensorboard‘解决方法

我相信有很多人和我一样,先展示以下错误示范: 在使用tensorboard时运行错误如图: 在网上查资料时可能是自己没有安装tensorboard,于是进入pycharm终端(控制台最下面那里点击terminal),输入 pip install tensorboard 然后输入conda list conda list 发现是有tensorboard的 然后进入进入cmd输入python再输入import tensorboard之后不报错,以为就安装好了 然后进入pycharm之后运行依旧报错... 好了错误示范结束后,当然得和大家说说解决办法,其实很简单 之所以错误是因为环境没有选对: 我们来注意一个小细节: 我们在pycharm终端使用pip install tensorborad时候,是在base环境里面,但是!!!我们代码的运行环境是在py37里面,所以,问题出在,把tensorboard装错地方啦!!! 正确的安装方法是: 在pycharm终端里面输入conda activate 你右下角的虚拟环境名称 conda activate 你的右下角虚拟环境名称 例如我的是py37,就是conda activate py37 再输入pip Install tensorboard就可以啦! pip install tensorboard 等待下载完成就ok咯~

vosviewer保存成PDF文件时没有文字

1、将vosviewer中英文国家名字,手工更换为中文后,重新导入软件 2、点击Screenshot后面的三角标,并选择“Save...” 3、打开PDF文件,发现另存的PDF中没有文字? 还在研究如何解决

Rust 09: 字符串详解(String、&str、内存布局、常用方法)

文章目录 字符串字面量字符串(String)字符串切片(&str)String和&str的内存布局Vec\<u8\>转String(String::from_utf8_lossy())Vec\<u8\>转String(String::from_utf8())字符串和数值类型的转换字符数组/列表合并为一个String字符串数组/列表合并(join/concat)为一个String字符串遍历,判断字符是数字还是字母String中追加和删除字符String遍历大小写转换(uppercase/lowercase)find()查找/contains()包含split()分割,返回一个迭代器lines()按行分割split_ascii_whitespace()split_whitespace()starts_with()/ends_with()如何高效修改String中的一个字符?借助remove()和insert()更高效的方式更进一步,自定义SetByIndex trait 字符串字面量 字符串字面量和全局变量、static变量一样位于程序运行之后虚拟地址空间中的代码区。 关于虚拟地址空间,之前有一小节详细分析过:Rust 06: 变量分配在堆还是栈上 + 虚拟地址空间 const g_array: [i32; 5] = [10; 5]; static G_VAR: i32 = 1000; #[test] fn test09_string() { let s: &str = "test string"; //字符串字面量,位于代码区的ROData段 println!("&str: {:p}", s);//&str: 0x7ff77e4c6b88 println!("{:p}", &g_array);//位于data段:0x7ff6c5fc6bb8 println!("{:p}", &G_VAR);//位于data段:0x7ff77e4c6200 } 字符串字面量位于代码区的ROData段,是只读(Read Only)的,在Rust代码中字符串字面量会被处理成字符串切片类型,即&str。如果想要对字符串进行追加等操作,必须先将ROData段的字符串字面量复制一份到堆上,构造一个String类型出来。 字符串(String) String内部其实是一个Vec,是一个可变长度的类型,末尾可以追加字符。String类型和Vec<u8>类型占用24个字节。 pub struct String { vec: Vec<u8>, } println!("size: {}", std::mem::size_of::<Vec<u8>>());//24 println!("size: {}", std::mem::size_of::<String>());//24 String对象的内存结构,也就是Vec<u8>的内存结构,为 8(ptr) + 8(capacity) + 8(length)。 从字符串字面量构造出一个堆上的String有多种方式: "xxx".to_owned()方法内部掉clone(),将字符串字面量从ROData区复制一份到堆上,并返回堆上数据的所有权;String::from("xxx")内部实际调用的是"xxx".to_owned();"xxx".to_string()内部实际调用的是String::from(“xxx”); 也就是说,下面3种方式最终都是调用了clone(): let s1: String = "

【Linux】JetsonNano安装CMake

【Linux】JetsonNano安装CMake 鉴于JetsonNano属于arm64平台,许多工具都出现未曾设想的问题,本文旨在分享从源码安装CMake的过程。 预备 JetsonNano一台,安装好g++和gcc 卸载原来的CMake(若有) sudo apt remove cmake 或者从cmake的安装目录下找到install_manifest.txt,txt中保存了所有cmake的附属文件的安装目录,将txt中显示的文件全部删除tar sudo rm -rf /usr/local/share/cmake* 下载源码(见我上传的资源) 此处有坑:CLion远程调试支持版本2.8.11-3.16.x,如果用CLion构建工具链需要注意最新版的3.18并不被支持。 https://cmake.org/download/ 逐步安装 打开压缩包所在文件夹,解压包 tar -xzvf cmake-3.18.0-rc1.tar.gz 打开解压后的文件夹 cd cmake-3.18.0-rc1 运行命令: ./configure [PS] 此处可能报找不到OpenSSL的错,解决方法是编辑CMakeLists.txt文件,在文件开头加: set(CMAKE_USE_OPENSSL OFF) 运行指令 make 运行指令 sudo make install 到这里安装就完成了。 验证安装 a) 检查CMake版本: cmake --version b) 检查编译器路径: sudo cmake ../

win10重置此电脑卡在99%的解决方法(6种)

当电脑运行不正常时,有些人会选择使用“重置此电脑”。但是事实证明这个功能很容易操作失败,许多人抱怨他们在使用这个功能时出现错误,比如重置卡在正在重置此电脑99%一天。这很有可能是硬件驱动出现了问题或Windows安装程序出错而导致。不用担心,本文为你提供了6种不同的方法来解决重置系统卡死的问题。 如何解决Windows 10/11正在重置此电脑卡死的问题? 如果你不知道电脑重置卡住了怎么办,请继续往下阅读,这里向你介绍了6个解决该问题的方法,一起来看看。 文章目录 如何解决Windows 10/11正在重置此电脑卡死的问题?解决方案一、等待几个小时解决方案二、禁用Internet连接解决方案三、更改BIOS设置解决方案四、使用启动修复解决方案五、从镜像备份中还原解决方案六、全新安装Windows总结 解决方案一、等待几个小时 当Windows 10/11重置系统卡死时,请耐心等待。各种因素可能导致暂时卡住,你可以查看硬盘的指示灯是否闪烁,如果闪烁则说明重置还在进行中。 有一些用户反馈说,整个重置过程可能持续几个小时。你可以不关电脑让它通宵运行,确保重置完成。 解决方案二、禁用Internet连接 下载更新时,可能会使你的电脑卡住。你可以禁用Internet连接来解决重置卡在1%、24%、62%、64%、66%、99%的问题。简单的方法是断网,拔掉网线或关掉无线路由器。 解决方案三、更改BIOS设置 某些BIOS功能可能会干扰系统并导致Windows 10/11正在重置此电脑卡死。你可以打开BIOS并进行以下操作: 1、禁用Secure Boot。 2、启用Legacy Boot。 3、启用CSM(如果此项可选)。 4、启用USB boot。 5、将可引导光盘/USB drive设置为优先启动项。 F10保存更改,启动电脑,然后再次尝试重置此电脑。 解决方案四、使用启动修复 1、将Windows 10/11安装文件下载到DVD或USB设备上。 2、进入BIOS并将DVD或USB设备设置为优先启动项。 3、启动到Windows安装界面,选择“修复计算机”。 4、然后点击高级选项》疑难解答,然后点击“开始修复”。 然后,按照提示进行操作,完成后即可解决重置系统卡死这个问题。 解决方案五、从镜像备份中还原 除了“重置此电脑”外,如果遇到系统问题,还可以从镜像备份中进行系统还原,还原到之前没问题时的状态。所以,当重置系统卡死时,也可以通过这个办法来解决。 当你处于重置导致的黑屏时,如果你有一个带系统镜像文件的U盘,那可以轻松的将电脑恢复,并正常运行。从备份中还原系统,请参考以下步骤。 当电脑不能正常启动到桌面时,可以转到WinRE进行还原。疑难解答》高级选项》系统镜像恢复。然后按照说明进行恢复。 解决方案六、全新安装Windows 如果之前没有做过系统备份,想要系统恢复正常,那只能重装系统。但你可以先将系统备份到U盘以避免数据丢失。 1、下载Windows 10/11镜像文件,并制作启动U盘。 2、制作完成后。将启动U盘连接到电脑,然后重启电脑。 3、在电脑启动时按F2或F12或Del进入BIOS并修改优先启动项为U盘。 4、当要求选择Windows 10/11安装类型时,选择“自定义:仅安装Windows”。等待完成即可。 总结 这是解决“Windows 10/11正在重置此电脑卡死”问题的6种方法。为了保护数据安全,请记住:数据无价,请养成备份的好习惯。

MD5加密、加盐

在计算机安全领域,md5是使用比较广泛的一种散列函数,用来保护信息传输的完整性。那么,md5有什么作用呢?下面本文针对md5是什么,以及md5的作用做个简单的介绍。 md5是什么? md5是一种信息摘要算法,一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值,用来确保信息传输完整一致性。 MD5加密算法是不可逆的。 MD5算法是单向散列算法的一种。单向散列算法也称为HASH算法,是一种将任意长度的信息压缩至某一固定长度(称之为消息摘要)的函数(该压缩过程不可逆)。在MD5算法中,这个摘要是指将任意数据映射成一个128位长的摘要信息。并且其是不可逆的,即从摘要信息无法反向推演中原文。MD5算法最终生成的是一个128位长的数据,从原理上说,有2^128种可能,这是一个非常巨大的数据,约等于3.4乘10的38次方,虽然这个是个天文数字,但是世界上可以进行加密的数据原则上说是无限的,因此是可能存在不同的内容经过MD5加密后得到同样的摘要信息,但这个碰中的概率非常小。 注意:md5值不是唯一的,也就是一个原始数据,只对应一个md5值,但是一个md5值,可能对应多个原始数据。且md5值是可以被破解的,例撞库破解。 撞库破解 关于撞库,这是概率比较低的解密方法,原理是:通过建立大型的数据库,把日常的各种句子通过md5加密成为密文,不断积累更新大量句子,放在庞大的数据库里;然后,有人拿了别人的密文,想查询真实的密码,就需要把密文拿到这个数据库的网站(免费MD5加密解密:md5在线加密解密)去查询。 md5有什么作用? 作用一:数字签名 MD5的典型应用是对一段Message(字节串)产生fingerprint(指纹),以防止被“篡改”。举个例子,我将这段话“md5是什么,md5的这些用途你都知道吗”写在一个叫 read.txt文件中,并对这个read.txt产生一个MD5的值(密文:7a1189ca1650ef630a6c2b0206f42d8b)并记录在案,然后我可以传播这个文件给别人,别人如果修改了文件中的任何内容,那么我对这个文件重新计算MD5时就会发现(两个MD5值不相同)。如果再有一个第三方的认证机构,用MD5还可以防止文件作者的“抵赖”,这就是所谓的数字签名应用。 作用二:一致性验证 MD5的典型应用是对一段信息(Message)产生信息摘要(Message-Digest),以防止被篡改。比如,在Unix下有很多软件在下载的时候都有一个文件名相同,文件扩展名为.md5的文件,在这个文件中通常只有一行文本,大致结构如: MD5 (tanajiya.tar.gz) = 38b8c2c1093dd0fec383a9d9ac940515 MD5将整个文件当作一个大文本信息,通过其不可逆的字符串变换算法,产生了这个唯一的MD5信息摘要。 作用三:安全访问认证 MD5还广泛用于操作系统的登录认证上,如Unix、各类BSD系统登录密码、数字签名等诸多方面。如在Unix系统中用户的密码是以MD5(或其它类似的算法)经Hash运算后存储在文件系统中。当用户登录的时候,系统把用户输入的密码进行MD5 Hash运算,然后再去和保存在文件系统中的MD5值进行比较,进而确定输入的密码是否正确。通过这样的步骤,系统在并不知道用户密码的明码的情况下就可以确定用户登录系统的合法性。这可以避免用户的密码被具有系统管理员权限的用户知道。 但经过哈希函数加密后的密码也不是绝对的安全,这时候就需要为密码加盐 盐(Salt) 是什么? 就是一个随机生成的字符串。我们将盐与原始密码连接/拼接(concat)在一起(放在前面或后面都可以),然后将concat后的字符串加密。Salt这个值是由系统随机生成的,并且只有系统知道。即便两个用户使用了同一个密码,由于系统为它们生成的salt值不同,散列值也是不同的。 我们知道,如果直接对密码进行散列,那么黑客可以对通过获得这个密码散列值,然后通过查散列值字典(例如MD5密码破解网站),得到某用户的密码。 加Salt可以一定程度上解决这一问题。所谓加Salt方法,就是加点“佐料”(Salt这个单词就是盐的意思)。其基本想法是这样的:当用户首次提供密码时(通常是注册时),由系统自动往这个密码里撒一些“佐料”,然后再散列。而当用户登录时,系统为用户提供的代码撒上同样的“佐料”,然后散列,再比较散列值,已确定密码是否正确。 这样也就变成了将密码+自定义的盐值来取MD5。但是如果黑客拿到了你的固定的盐值,那这样也不安全了。所以比较好的做法是用随机盐值。用户登陆时再根据用户名取到这个随机的盐值来计算MD5。 MD5加盐 一般使用的加盐: 即将用户名和密码字符串相加再MD5,这样的MD5摘要基本上不可反查。但有时候用户名可能会发生变化,发生变化后密码即不可用了(验证密码实际上就是再次计算摘要的过程)。 因此我们做了一个非常简单的加盐算法,每次保存密码到数据库时,都生成一个随机16位数字,将这16位数字和密码相加再求MD5摘要,然后在摘要中再将这16位数字按规则掺入形成一个48位的字符串。 在验证密码时再从48位字符串中按规则提取16位数字,和用户输入的密码相加再MD5。按照这种方法形成的结果肯定是不可直接反查的,且同一个密码每次保存时形成的摘要也都是不同的。 Demo package com.cjian.security; import java.math.BigInteger; import java.security.MessageDigest; import java.security.SecureRandom; /** * @Author: cjian * @Date: 2022/10/31 16:53 * @Des: */ public class MD5Demo { public static void main(String[] args) { SecureRandom secureRandom = new SecureRandom(); byte[] randomBytes = new byte[16]; secureRandom.

SQL分类

SQL分类 SQL简介SQL分类DDL操作数据库操作表DDL案例 DML添加数据修改数据删除数据 DQL基础查询条件查询模糊查询排序查询分组查询聚合函数分组查询分页查询 约束 SQL简介 结构化查询语言,操作关系型数据库定义操作所有关系型数据库的统一标准对同一个需求,每一种数据库擦欧总的方式可能会存在一些不一样的地方 1、sql语句以分号结尾 2、不区分大小写 3、注释 单行:–(空格!!!)注释内容 或 #注释内容 多行:/*注释 */ SQL分类 DDL:操作数据库、表;DML:对表中数据进行增删改;DQL:对表中数据进行查询DCL:数据控制语言,对数据库进行权限控制 DDL 数据定义语言,用于定义数据库对象:数据库、表、列等; 操作数据库 创建数据库 若在创建时不知道某个数据库已经存在,重复创建时会出错 避免上述情况,在创建时先进行判断,若不存在再创建 删除数据库 使用数据库 操作表 即对表进行增删改查 查询当前数据库下所有表查询表结构 创建表 数据类型 (资料:MySQL数据类型.xlsx) 数值类型 tinyint:小整数型,一个字节int:大整数类型,4个字节 age int double:浮点类型,字段名 double(总长度,小数点后保留的位数) score double(5,2) 日期和时间类型 date:日期值,只包含年月日 birthday date datatime:混合日期和时间值 字符串类型 char:定长字符串;存储性能高 浪费空间 name char(10) 张三10个字符空间 varchar:变长 存储性能低 节约空间 name varchar(10) 张三2个字符空间 删除表 修改表 改表名 添加一列 修改数据类型 修改列名和数据类型 删除列 DDL案例 需求:设计一张学生表,请注重数据类型、长度的合理性 1. 编号 2. 姓名,姓名最长不超过10个汉字 3.

Qt中的TCP通信

一、TCP的特点 TCP(传输控制协议)是一种面向连接的,可靠的,基于字节流的传输层通信协议 二、TCP适合应用的场景 TCP协议适用于要求可靠传输的应用,例如文件传输,网络数据库,分布式高精度计算系统的数据传输。 三、Qt中使用TCP通信 Qt中的TCP通信与之前所讲的UDP通信有着明显区别,使用TCP通信,就有着明确的客户端与服务器之分,服务器有两个套接字,分别是一个用于通信的通信套接字(QTcpSocket),一个是用于监听的监听套接字(QTcpServer),客户端只有一个用于通信的通信套接字(QTcpSocket),基本流程是客户端首先得向服务器发送连接请求,服务器监听到有客户端向它发送连接请求时,会触发newConnection信号,与此同时,客户端会触发connected信号,表示与服务器成功连接,两者建立好连接之后,服务器需要返回一个通信套接字用于和客户端通信,随后客户端与服务器就可以通过通信套接字来进行数据之间的通信 四、客户端与服务器通信的实现 添加网络模块 QT += network; 添加头文件 #include<QTcpSocket> //通信套接字 #include<QTcpServer> //监听套接字 服务器端的实现 tcpserver分配空间,指定父对象,然后开始监听 tcpserver = new QTcpServer(this); //分配空间,指定父对象 tcpserver->listen(QHostAddress::Any,8888);//监听本机所有网口及8888端口号 一旦监听到有客户端发起了连接请求,服务器端触发newConnection信号,与此同时,客户端会触发connected信号,服务器返回一个建立好连接的通信套接字,当客户端发送数据时,服务器端会触发readyRead信号,取出tcpsocket中的数据,显示到窗口中,实现接收数据 客户端返回一个建立好连接的通信套接字一般使用如下函数 tcpsocket = tcpserver->nextPendingConnection(); 完整代码 connect(tcpserver,&QTcpServer::newConnection,[=] //Server监听到连接请求触发newConnection信号 { tcpsocket = tcpserver->nextPendingConnection();//Client与Server建立连接后,Server返回一个建立好连接用于通信的套接字 QString ip = tcpsocket->peerAddress().toString();//获取对方的IP qint16 port = tcpsocket->peerPort();//获取对方的端口 QString time= QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");//获取当前时间 ui->te_output->append(time+"\n"+QString("成功与[%1:%2]建立连接...").arg(ip).arg(port)); connect(tcpsocket,&QTcpSocket::readyRead,[=] //接收数据 { QString message = tcpsocket->readAll(); QString time= QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); ui->te_output->append(time + "\n"+message); }); }); 发送数据,使用write()函数,因为已经建立好了连接,所以参数可以只有一个,就是你想发送的数据 //获取用户输入的信息 QString text = ui->te_input->toPlainText(); tcpsocket->write(text.

Oracle和MySQL查询所有的表信息和字段信息

Oracle和MySQL查询所有的表信息和字段信息 1. MySQL1.1 查询表1.2 查询字段1.2.1 方式1->SHOW FULL COLUMNS1.2.2 方式2->information_schema.COLUMNS 1.3 查表和字段1.4 查表和字段-->转程Oracle需要的数据类型 2. Oracle2.1 查表和字段的单表查询2.2 整理查表和字段的sql 1. MySQL 1.1 查询表 如下:SELECT table_comment 表中文名, table_name 表英文名 FROM information_schema.TABLES WHERE table_schema = 'test2022' ORDER BY table_name; 1.2 查询字段 1.2.1 方式1->SHOW FULL COLUMNS 如下:SHOW FULL COLUMNS FROM `sys_login_log`; 1.2.2 方式2->information_schema.COLUMNS 如下:select * from information_schema.COLUMNS b where 1=1 and b.TABLE_SCHEMA='test2022' and b.table_name='sys_login_log'; 1.3 查表和字段 如下:SELECT a.table_comment 表中文名称, a.table_name 表英文名称, b.COLUMN_NAME 字段英文名, b.column_comment 字段中文名, b.

linux下miniconda卸载

conda是一个开源的包、环境管理器,可以用于在同一个机器上安装不同Python版本的软件包及其依赖,并能够在不同的Python环境之间切换,Anaconda包括Conda、Python以及一大堆安装好的工具包,比如:numpy、pandas等,Miniconda包括Conda、Python。 卸载步骤 删除miniconda安装目录 rm -r miniconda3/注释 bashrc 中 conda initialize 代码 vim ~/.bashrc # !! Contents within this block are managed by 'conda init' !! __conda_setup="$('/opt/module/miniconda3/bin/conda' 'shell.bash' 'hook' 2> /dev/null)" if [ $? -eq 0 ]; then eval "$__conda_setup" else if [ -f "/opt/module/miniconda3/etc/profile.d/conda.sh" ]; then . "/opt/module/miniconda3/etc/profile.d/conda.sh" else export PATH="/opt/module/miniconda3/bin:$PATH" fi fi unset __conda_setup # <<< conda initialize <<< 删除 .condarc 相关文件 rm -rf ~/.condarc rm -rf ~/.conda刷新环境

使用REDIS的INCREMENT方法生成自增主键,并发量每秒一万

redis是单线程的,他提供了一个单线程的自增方法increment供我们使用。 现在有一个业务需求,id需要自增生成,且生成速度要求一秒一千以上。废话不多说,直接上代码 public class IncrIdUtils { private final String REDIS_KEY_TASK_ID = "AUTO_TASK_ID"; private final String REDIS_KEY_PRO_INS_ID = "AUTO_PRO_INS_ID"; @Resource private RedisUtils redisUtils; @Value("${task.id.last}") private Long taskIdLast = 900000000000L; @Value("${pro.ins.id.last}") private Long proInsIdLast = 900000000000L; /** * 生成一个长度为12的纯数字字符串作为任务id,规则如下 * 1.以9开头 * 2.后11位数字从1开始自增 * * @return 如:"900000000001" */ public String getTaskId() { String taskIdRedis; long incr = redisUtils.incr(REDIS_KEY_TASK_ID, 1); taskIdRedis = String.valueOf(incr + taskIdLast); return taskIdRedis; } } 下面是测试代码 @Resource IncrIdUtils incrIdUtils; public Response testTaskIdCreate(@ApiParam(name = "

2021 河北取证比武决赛个人赛 题解 入侵溯源

个人赛 个人赛容器密码 BDH sha256全大写 A94686C845696F88525BB9E74FD7F5D38B6C12F7DDC7E5288C2F2D2201151F47 括号内表示该答案也可得分。26-30题每题4分,其余题目每题2分。 服务器部分 2021年5月 (对时间要敏感,做题时要摸清案情,摸清案情何作案动机能,厘清攻击路线。),接某考试信息中心报案称,其单位一存储考生个人信息的服务器疑似被入侵,数据库被破坏并勒索比特币,警方当即固定了服务器的镜像server.e01。经调查警方抓获了嫌疑人并对其使用的笔记本电脑只做了镜像PC.e01,请对两个检材进行分析,并回答下面的问题: 1. 镜像sever.e01对应的被入侵服务器源盘sha256为 98C53B2AC30758EF0977FC313D5D1A070EBF51AE09E删除线格式 0DF36664A5CCF81DF35C5 2. 服务器操作系统内核版本为3.10.0-957.el7.x86_64 3. 服务器配置的网关为192.168.232.2 如果没有看到这个这个网关地址,点击左上角的设置列,弘连默认不展示所有列,像一些基础信息觉得应该能直接取到但是没有的可以到这个地方看看是否没点显示 4. 服务器中有2个登录过的账号 5. 服务器中root账号的密码为nb7001 导出/etc/目录下的shadow文件,进行破解 使用john工具cpu全速跑了很久才跑出来 个人喜欢用john 建议直接学习使用hashcat调用gpu来爆破 但是这么爆破总不是办法,在后面pc检材分析完之后,有很多途径可以很轻松获取到这个登陆密码,但是题目只做到当前这的进度时是很难获取到这样的信息的,所以这就是先对整套题目进行分析,厘清攻击路径攻击意图的重要性,可能有同学会觉得这样会花费很多时间去做一些没有必要的分析,但是实际上比直接硬找会快很多。 6. 入侵者IP为192.168.232.150 五月份发现被入侵并报警,查看该时段登录记录,异常信息。 整体分析 前面的基本上都是相当于是需要固定的基本信息,基本上都能直接找到,做到这题是需要一定分析才能做的题目了。接下来先不看题目,先对服务器进行分析,找到攻击路径,重建网站数据库等,再来逐题看题目,这样不会被题目牵着走,没思路的时候再来看题目是什么方向的。 历史记录里可以看到安装了pip3 install cryptodemo 这个库 删除过历史和日志 这里执行了一个加密的python脚本,先留个心眼,等题目做到再仔细分析 安装了好多库 仿真起 在这里发现加密提示,lnmp-install.log说明这个站可能是lnmp搭建的 可以看到有很多网站,将服务起一下,简单看一下网站 在这里找到一个备份脚本,应该有定时执行的设定,下一步去查看定时任务 这里找到路径,可以看到是个定时任务每五分钟执行一次backuplog.sh 接下来再看一下备份目录,使用xftp发现没啥东西,但是备份日志里确实显示这个是个备份目录,这就是xftp工具的局限性,修改还是比较方便的,但是隐藏文件是不显示的 我们使用命令查看一下 后期我们可以设置显示隐藏文件,就可以看到隐藏文件了 可以看到很多日志,将日志导出,进行分析 所有的历史记录都是相同的,这个备份中没有有效信息,查看一下登录日志 放到随便一个目录下,last解析一下 也解析一下,也没什么东西 再看一下各个网站 将各个网站的域名加入本地hosts文件 打开浏览各个网站,至此我们尚未发现攻击路径,感觉网站起的不太对,再查看一下网站nginx 的配置文件 只有默认站点 再找一下vhost下的配置文件,没有东西 Nginx目录下发现了配置文件中nginx服务只指向了一个目录就是/home/wwwroot/mhedu.sh.cn,所以之前对hosts文件加这么多设置访问到的也都是同一个站点 可以从之前备份中的历史命令记录也可以体现 在操作历史记录中,入侵者查看了一下网卡信息,查看了一下最近登录,查看了一下数据库配置文件,查看了一下网站配置文件,发现网站也是在这个mhedu.sh.cn的文件下,所以直接进去查看了,后面还做了脱库的操作 接下来可以分析一下web应用的日志 可以先放工具跑一遍,有一个整体印象,但是我一般都是自己先肉眼对整个日志文件看一遍,实在看不过来再用工具,大家平时练习也是练习自己审计为主,同时兼顾工具的熟练运用,比赛的时候以快为主,工具做出不来手工也要会。 可以很快的看到这里images2下面有个1.php,非常异常,对于攻击路径而言,很可能是上传的一句话木马。 还可以看到有很多对adminer的操作 Adminer是一个基于php的数据库管理工具,所以等下对这个文件的操作也要着重分析,通过日志工具分析我们发现1.php和adminer.php两个需要关注的点,然后考虑adminer是否是网站自带还是黑客传上去的,如果是黑客上传的也可以认为是一个大马 可以看到以这里为分界线,前面都是192.168.232.1的访问记录,UA头为"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.