css如何隐藏垂直滚动条但同时需保持滚动

前言 在写前端页面时,对于超出的内容,我们希望隐藏,同时保持垂直的滚动,但是又不希望有丑陋的垂直滚动条,那该怎么去实现呢 实现方式有很多种,可以用iscroll插件,也可以用css去解决 01 方法1-计算滚动条宽度并隐藏起来 这种方法主要是通过计算滚动条宽度,给隐藏起来的,如下示例所示 具体片段代码如下所示 <template> <div class="wrap"> <div class="outer-container"> <div class="inner-container"> itclanCoder,https://coder.itclan.cn,itclan.cn,书以启智,技于谋生,活出斜杠 itclanCoder,https://coder.itclan.cn,itclan.cn,书以启智,技于谋生,活出斜杠 itclanCoder,https://coder.itclan.cn,itclan.cn,书以启智,技于谋生,活出斜杠 itclanCoder,https://coder.itclan.cn,itclan.cn,书以启智,技于谋生,活出斜杠 itclanCoder,https://coder.itclan.cn,itclan.cn,书以启智,技于谋生,活出斜杠 itclanCoder,https://coder.itclan.cn,itclan.cn,书以启智,技于谋生,活出斜杠 itclanCoder,https://coder.itclan.cn,itclan.cn,书以启智,技于谋生,活出斜杠 itclanCoder,https://coder.itclan.cn,itclan.cn,书以启智,技于谋生,活出斜杠 itclanCoder,https://coder.itclan.cn,itclan.cn,书以启智,技于谋生,活出斜杠 itclanCoder,https://coder.itclan.cn,itclan.cn,书以启智,技于谋生,活出斜杠 itclanCoder,https://coder.itclan.cn,itclan.cn,书以启智,技于谋生,活出斜杠 itclanCoder,https://coder.itclan.cn,itclan.cn,书以启智,技于谋生,活出斜杠 itclanCoder,https://coder.itclan.cn,itclan.cn,书以启智,技于谋生,活出斜杠 itclanCoder,https://coder.itclan.cn,itclan.cn,书以启智,技于谋生,活出斜杠 </div> </div> </div> </template> <script> export default { name:'curWidthScroll' } </script> <style lang="scss" scoped> .wrap { text-align: center; } .outer-container{ width: 360px; height: 200px; position: relative; overflow: hidden; margin: 10px auto; } .inner-container{ position: absolute; left: 0; top: 0; right: -17px; // 通过移动滚动条,实现隐藏 bottom: 0; overflow-x: hidden; overflow-y: scroll; // 垂直滚动 } </style> 02

Qt布局管理器(QHBoxLayout,QVBoxLayout)

文章目录 布局管理器是什么使用代码添加布局管理器QVBoxLayoutQHBoxLayout 使用ui文件添加布局管理器布局管理器的嵌套 提示:以下是本篇文章正文内容,下面案例可供参考 布局管理器是什么 可以把一些组件按一定的次序排列,这就是布局管理器。 他可以自动排列窗口中的界面组件 窗口变化后自动更新界面组件。 使用代码添加布局管理器 QVBoxLayout QVBoxLayout:按垂直的顺序排列组件 添加组件/其他的布局管理器: addWidget(QWidget*); addLayout(Layout*); 设置布局管理器管理指定窗口: Widget->setLayout(Layout*); 设置组件和窗口一起变大变小: QWidget->setSizePolicy(); 大家可以查帮助文档,我现在列出一部分 QSizePolicy::Fixed QSizePolicy::Minimum QSizePolicy::Maximum QSizePolicy::Preferred QSizePolicy::Expanding 设置组件的间隔: setSpacing(int) 设置组件的比例因子: setStretch(int index,int stretch) 使用部分: //构造函数: Form::Form(QWidget *parent) : QWidget(parent),btn0(this),btn1(this),btn2(this), ui(new Ui::Form) { ui->setupUi(this); QVBoxLayout *layout = new QVBoxLayout(this); btn0.setText("Button 0"); btn1.setText("Button 1"); btn2.setText("Button 2"); btn0.setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding); btn1.setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding); btn2.setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding); layout->setSpacing(10); layout->addWidget(&btn0); layout->addWidget(&btn1); layout->addWidget(&btn2); setLayout(layout); } //头文件: #ifndef FORM_H #define FORM_H #include <QWidget> #include <QPushButton> namespace Ui { class Form; } class Form : public QWidget { Q_OBJECT QPushButton btn0; QPushButton btn1; QPushButton btn2; public: explicit Form(QWidget *parent = 0); ~Form(); private: Ui::Form *ui; private slots: }; #endif // FORM_H QHBoxLayout 他和QVBoxLayout基本一致,在这我就不讲了

实时采集报错:io.debezium.DebeziumException: Unknown command Error code: 1047; SQLSTATE: HY000.

问题背景 使用KafkaConnect对MySQL进行实时采集的过程中出现启动异常的问题,其中集群环境和MySQL服务器均在云服务 报错详情如下 org.apache.kafka.connect.errors.ConnectException: An exception occurred in the change event producer. This connector will be stopped. at io.debezium.pipeline.ErrorHandler.setProducerThrowable(ErrorHandler.java:42) at io.debezium.connector.mysql.MySqlStreamingChangeEventSource$ReaderThreadLifecycleListener.onCommunicationFailure(MySqlStreamingChangeEventSource.java:1199) at com.github.shyiko.mysql.binlog.BinaryLogClient.listenForEventPackets(BinaryLogClient.java:980) at com.github.shyiko.mysql.binlog.BinaryLogClient.connect(BinaryLogClient.java:599) at com.github.shyiko.mysql.binlog.BinaryLogClient$7.run(BinaryLogClient.java:857) at java.base/java.lang.Thread.run(Thread.java:834) Caused by: io.debezium.DebeziumException: Unknown command Error code: 1047; SQLSTATE: HY000. at io.debezium.connector.mysql.MySqlStreamingChangeEventSource.wrap(MySqlStreamingChangeEventSource.java:1154) ... 5 more Caused by: com.github.shyiko.mysql.binlog.network.ServerException: Unknown command at com.github.shyiko.mysql.binlog.BinaryLogClient.listenForEventPackets(BinaryLogClient.java:944) ... 3 more 问题产生原因 造成此原因是因为云服务器的mysql使用网络代理节点导致的,因为debezium在采集MySQL的binlog时采集节点是无法通过MySQL的网络代理节点解析对应的binlog数据的 解决方案 修改为节点直连模式而不是通过网络代理

后端代码生成工具SDP系列一(简介、源码地址、下载地址)

后端代码生成工具SDP系列一(简介、源码地址、下载地址 SDP简介如何下载、编译、启动SDP直接使用打包好的SDP工具关于SDP的前端关于SDP使用的数据库 SDP简介 SDP是一个开源的后端代码生成工具,目前的版本可以生成SpringBoot+Mybatis的绝大部分源代码。因为SDP是基于模板的代码工具,所以未来的版本将可以支持自动生成前端代码。 与其他代码生成工具不同的是,这个工具不是基于可视化的方式来处理复杂的连接查询配置。而是直接使用select语句,而且是实际的、完整的带具体查询条件的select语句。通过处理,将select语句的查询字段(包括通配符*)以及查询条件自动转化为Mybatis的查询参数和返回字段。 可以说,只要会写select语句,就可以通过SDP工具实现“零编码”。当然如果有复杂的业务逻辑,还是需要写对应的java代码的,也仅仅是业务代码需要编写,至于定制、扩展的接口等工作,统统交给SDP。 总之,基于SDP工具进行后端(主要是SpringBoot+Mybatis),可以完全不用人工维护Mybatis的xml文件,也不需要传统编程中必备的复制粘贴大法,只需要专注写复杂的、定制化的java接口实现即可(接口的配置化定义方式也是SDP工具的一个重要功能)。 如何下载、编译、启动SDP SDP开源代码托管在giteehttps://toscode.gitee.com/brookyu2019/sdp。 旧版本(已经废弃)托管在github。地址为https://github.com/BrookYuGit/sdp 下载代码后,使用Idea(社区版即可)打开源代码目录下的server\pom.xml。配置好maven,安装Lombok插件,然后就可以运行cn.mysdp.Application。SDP工具缺省使用的是H2数据库,也支持Mysql数据库。 编译运行的方法:在idea的maven面板中双击install后,直接运行server\sdp\startup_db_in_home.bat文件就可以直接启动SDP工具了。 启动工具后,会启动启动浏览器,打开地址http://localhost:9882。 直接使用打包好的SDP工具 下载地址链接(最新版本是1.8): https://pan.baidu.com/s/1zk16GkhNBHKsfidswk5_Fw?pwd=mfh9 将zip下载解压后,直接运行startup_db_in_home.bat就可以启动SDP工具。 关于SDP的前端 SDP工具的前端也是开源的,在源代码目录的web子目录下。有些SDP的功能是通过前端实现的,例如导出、导入、编写模板等。打包好的前端代码被放在后端的resources\static目录下,这样就可以免去了配置nginx的工作,直接启动SDP的SpringBoot工程就可以实现一体化了。 关于SDP使用的数据库 SDP最初是基于Mysql数据库开发的,还需要配合数据库服务器才能运行。现在已经修改为使用H2数据库,这样就省去了安装、配置数据库的步骤。

计算机网络wireshark实验

数据链路层 实作一 熟悉 Ethernet 帧结构 使用 Wireshark 任意进行抓包,熟悉 Ethernet 帧的结构,如:目的 MAC、源 MAC、类型、字段等。 ✎ 问题 你会发现 Wireshark 展现给我们的帧中没有校验字段,请了解一下原因。 解答:Wireshark 展现给我们的帧中没有校验字段,帧已经被校验了,校验字段被wireshark去掉了。 实作二 了解子网内/外通信时的 MAC 地址 ping 你旁边的计算机(同一子网),同时用 Wireshark 抓这些包(可使用 icmp 关键字进行过滤以利于分析),记录一下发出帧的目的 MAC 地址以及返回帧的源 MAC 地址是多少?这个 MAC 地址是谁的? 发出帧的目的mac地址以及返回帧的源mac地址,都为:78:eb:14:d4:bb:e4 这个地址是要访问计算机的mac物理地址。 然后 ping qige.io (或者本子网外的主机都可以),同时用 Wireshark 抓这些包(可 icmp 过滤),记录一下发出帧的目的 MAC 地址以及返回帧的源 MAC 地址是多少?这个 MAC 地址是谁的? 发出帧的目的mac地址以及返回帧的源mac地址,都为:ac:5a:ee:c6:c3:7c 这个mac地址是网关的mac物理地址 再次 ping www.cqjtu.edu.cn (或者本子网外的主机都可以),同时用 Wireshark 抓这些包(可 icmp 过滤),记录一下发出帧的目的 MAC 地址以及返回帧的源 MAC 地址又是多少?这个 MAC 地址又是谁的? 发出帧的目的mac地址以及返回帧的源mac地址,都为:ac:5a:ee:c6:c3:7c 这个mac地址是网关的mac物理地址

repvgg预训练模型迁移到yolov5-repvgg的pt的backbone中/模型的保存与读取

前情 我在训练改进的yolov5-repvgg时,发现yolov5s训练50epoch,和我改进的yolov5-repvgg模型,以yolov5s预训练模型为预训练,俩对比都训50,发现没有yolov5s训50epoch,也可能我的待测物体比较特殊。 但是就是认为是yolov5-repvgg不应该以yolov5s.pt为预训练模型,确实俩都不用yolov5s.pt为预训练模型后,yolov5-repvgg的效果更好。 我的原模型是yolov5s-repvgg模型,不带预训练模型,训练了50epoch,(我的yolov5-repvgg模型是这个帖子的改进方法yolov5 引入RepVGG模型结构) 然后把官方的repvgg预训练模型的参数(代码:DingXiaoH/RepVGG ,权重:官方权重链接下的repvgg-A1-train.pth),移植到上面所述模型的backbone中。 我的权重移植代码: #!/usr/bin/python3 # -*- coding: utf-8 -*- """ @File : trained_model @Author: Wendy @Time : 2023/1/9 14:47 @Desc : yolov5-repvgg移植repvgg的backbone """ import torch from models.yolo import Model import sys sys.path.append("../RepVGG-main") from repvgg import repvgg_model_convert, create_RepVGG_A1 path = r'E:\competition\Wadhwani_AI_Bollworm_Counting_Challenge\pretrained_model_vgg/' # yolov5-repvgg model = Model(r"D:\98project\yolov5-7.0\models\yolov5s-haihang-repvgg.yaml", 3, 12, None).to("cpu") model.load_state_dict(torch.load(path + 'last.pt'), strict=False) # for k, v in model.state_dict().items(): # print(f"{k}: {v.shape}") print("yolov5s-repvgg原权重:") log1 = open(path + "

渗透测试 ( 6 ) --- SQL 注入神器 sqlmap

sqlmap 官网:http://sqlmap.org/ sqlmap文档地址:https://github.com/sqlmapproject/sqlmap/wiki/Usage sqlmap 使用 思维导图:http://download.csdn.net/detail/freeking101/9887831 黑帽与白帽都喜爱的十大SQL注入工具:http://www.aqniu.com/industry/1449.html 国内外 SQL 神器 :http://blog.csdn.net/heimian/article/details/7080822 SQL注入攻击与防御:https://www.jianshu.com/p/ba35a7e1c67d 1、sqlmap 简介 SQL 注入 SQL注入 ( SQL Injection ) 就是通过把 SQL 命令插入到 Web表单提交 或 输入域名 或 页面URL请求查询的字符串,最终达到欺骗服务器执行恶意的 SQL命令,如果管理员没有对 id 参数进行过滤那么黑客可以通过数据传输点将恶意的SQL语句带入查询。 其实就是:改变原来的 sql 语句,导致 sql 执行结果发生改变。 具体来说,它是利用现有应用程序,将(恶意的)SQL命令注入到后台数据库引擎执行的能力,它可以通过在Web表单中输入(恶意)SQL语句得到一个存在安全漏洞的网站上的数据库,而不是按照设计者意图去执行SQL语句。比如先前的很多影视网站泄露VIP会员密码大多就是通过WEB表单递交查询字符暴出的,这类表单特别容易受到SQL注入式攻击.(来源于百度) 也就是说网站页面包含与数据库交互的部分(例如新闻网站的查找功能),而当在网站输入数据信息,数据信息被程序化后传入数据库执行的过程中,网站的开发人员没有对这些传入数据库的相应数据做安全处理(比如过滤特殊字符、编码等),导致黑客可以将恶意代码(也就是包含非法SQL语句的SQL命令)通过网站前段传入数据库,并在数据库中执行这些具有黑客目的的SQL语句,从而造成数据库信息泄露、损坏等后果。 SQL注入的一般分类,按照注入点类型来分类 (1)数字型注入点。许多网页链接有类似的结构 http://www.example.com/12.php?id=1 基于此种形式的注入,一般被叫做数字型注入点,缘由是其注入点 id 类型为数字,在大多数的网页中,诸如 查看用户个人信息,查看文章等,大都会使用这种形式的结构传递id等信息,交给后端,查询出数据库中对应的信息,返回给前台。这一类的 SQL 语句原型大概为 select * from 表名 where id=1 若存在注入,我们可以构造出类似与如下的sql注入语句进行爆破:select * from 表名 where id=1 and 1=1(2)字符型注入点。网页链接有类似的结构 http://xwww.example.com/users.php?user=admin 这种形式,其注入点 user 类型为字符类型,所以叫字符型注入点。这一类的 SQL 语句原型大概为 select * from 表名 where user='admin' 值得注意的是这里相比于数字型注入类型的sql语句原型多了引号,可以是单引号或者是双引号。若存在注入,我们可以构造出类似与如下的sql注入语句进行爆破:select * from 表名 where user='admin' and 1=1 ' 我们需要将这些烦人的引号给处理掉。(3)搜索型注入点。这是一类特殊的注入类型。这类注入主要是指在进行数据搜索时没过滤搜索参数,一般在链接地址中有 "

python的数据结构有哪些

Python 的数据结构有以下几种: 列表 (list): 列表是一个有序的集合, 可以随时添加和删除元素。 元组 (tuple): 元组是一个不可变的有序列表, 一旦初始化就不能修改。 字典 (dictionary): 字典是一个无序的键值对集合, 其中的键是唯一的, 值可以是任意类型。 集合 (set): 集合是一个无序的不重复元素序列。 字符串 (string): 字符串是一个有序的字符序列。

全加器的设计

1. 半加器的设计 1)半加器1,布尔函数描述法 module h_adder(a,b,so,co) input a,b; output so,co; assign so = a ^ b; assign co = a & b; endmodule 2)半加器2,基于case语句的类真值描述法 module h_adder(a,b,so,co) input a,b; output so,co; reg so,co; always @(a,b,co,so) begin case ({a,b}) 0: begin so = 0;co = 1’b0 ;end 1: begin so = 1;co = 1’b0 ;end 2: begin so = 1;co = 1’b0 ;end 3: begin so = 0;co = 1’b1 ;end endcase end endmodule 3)半加器3,直接用算符完成描述 module h_adder(a,b,so,co)

后端返回二进制字符串转为图片

后端返回数据 方法: 其实方法很简单,流程整理一下,就是window自带了一个转换的方法叫window.URL.createObjectURL() ,但是光用这个还不行,还要把你的请求加上responseType:"blob"这个是设置请求返回类型的 html <img :src="avatar" alt="" style="width:30px;border-radius: 30px;"> data avatar:null, js getTou({ 'id': 1000000, 'filename': 'avatar.jpg', }).then((res) => { console.log(res) let blob = new Blob([res.data],{type: 'image/jpeg'}); self.avatar = window.URL.createObjectURL(blob); console.log(self.avatar,blob) }) 注意事项: // 获取头像 export function getTou(data={}){ return service.request({ method: 'get', url: `/getfile`, responseType:"blob"//一定要加 }) }

go 实现FFT算法

FFT(快速傅里叶变换)是一种将时域信号转换为频域信号的算法。在 Go 语言中,可以使用内置的复数类型和内置的 FFT 函数来实现 FFT 算法。 要使用 FFT 算法,首先需要导入 "math/cmplx" 包,然后可以使用 cmplx.FFT 函数来实现 FFT 转换。 示例代码如下: package main import ( "fmt" "math/cmplx" ) func main() { // 定义待转换的信号 signal := []complex128{1, 1, 1, 1, 0, 0, 0, 0} // 调用 FFT 函数进行转换 result := cmplx.FFT(signal) // 输出转换后的信号 fmt.Println(result) } 上面的代码定义了一个信号,然后使用 cmplx.FFT 函数将该信号转换为频域信号。转换后的信号可以通过输出语句输出。

C++windows.h库GUI教程(基础教程)

C++<windows.h>库教程 相信大家做C++的时候必定要用到GUI编程的,windows.h就是一个很好的GUI编程库,windows.h是只有windows有的库,象Mac,Unit的可以先退出了。 1.用<windows.h>编程 #include<iostream> //标准头文件在这里插入代码片 #include<windows.h> //添加windows.h头文件 using namespace std;//标准名空间 int main()//开始 { MessageBox(NULL,"这是一个最简单的消息框!","我是标题",NULL); return 0; } 是不是很开心,弹出了一个框框. 2.更多形式 MessageBox("这是一个可以选择确认和取消的框!","标题", MB_OKCANCEL ); MessageBox("这是一个两种属性的框!","标题",MB_ICONEXCLAMATION|MB_OKCANCEL ); MessageBox("这是一个警告的框!","标题", MB_ICONEXCLAMATION ); 3.一个用添加了用GUI的游戏——猜数字 猜数字游戏:电脑随机取0~100的数,让玩家去猜这些数,电脑会提示:猜对了,猜大了,猜小了 代码: #define random(x) rand()%(x) #include <cstdlib> #include <ctime> #include<iostream> #include<windows.h> using namespace std; int main(){ int a,c; srand((int)time(0)); a = random(99999); system("title 猜数字"); cout<<"猜数字游戏"<<endl; for (int b;a!=b;c+=1) { cout<<"请猜一个数"<<endl; cin>>b; if (b > a) { MessageBox(NULL,"猜大了","猜数字",0); } else if (b < a) { MessageBox(NULL,"

【无标题】海思SD3403平台,报错ss_mpi_vb_set_conf failed 0xa0018022

背景 使用海思SD3403平台进行编解码,意外崩溃,重新启动编解码程序,出现ss_mpi_vb_set_conf failed! 0xa0018022错误。此时已经调用了视频缓冲池去初始化接口, ss_mpi_sys_exit(); ss_mpi_vb_exit_mod_common_pool(OT_VB_UID_VDEC); ss_mpi_vb_exit(); 此时依然报错,错误码0xa0018022,意思是 分析 使用/dev/logmpp可以看到,有pool没有被去初始化成功,如下图: 但是已经调用了去初始化的接口,还没去初始化成功。意外崩溃的时间点编解码器依然在工作,并没有停止,此时VB的资源肯定是被占用的,说明不能强制释放已经占用的VB资源,如何强制销毁已经占用的VB资源。这一点手册有说明, 查看我的板子加载xxx_base.ko,确实没有加g_vb_force_exit=1参数。加上之后,没有报错。意外崩溃后可以重新启动。

webdriver_helper安装失败 & ImportError

安装报错: ERROR: No matching distribution found for webdriver-helper 问题:python版本太低 ImportError: cannot import name 'get_webdriver' from 'webdriver_helper' (unknown location) 问题:使用pip install webdriver-helper安装的是最新版本,但是要收费(收费版本包含远程driver和对appium的支持),免费版本的安装方法如下:pip install webdriver_helper==1.0.1

iTerm2连接ssh配置

iTerm2连接ssh配置 #首先在/Users目录下按照如下命令创建sh脚本 cd /Users/ #创建iterm文件夹 mkdir iterm #进入iterm文件夹 cd iterm #创建myserver.sh文件 touch myserver.sh #编辑myserver.sh文件 vi myserver.sh 如果出现没有权限,就命令前面加上sudo 键盘输入i编辑文件,插入以下内容: #!/usr/bin/expect set timeout 30 spawn ssh -p [lindex $argv 0] [lindex $argv 1]@[lindex $argv 2] expect { "(yes/no)?" {send "yes\n";exp_continue} "password:" {send "[lindex $argv 3]\n"} } interact myserver.sh文件中变量解释: [lindex $argv 0]:端口号 [lindex $argv 1]:服务器用户名 [lindex $argv 2]:服务器IP地址 [lindex $argv 3]:服务器密码 插入完成后键盘esc 然后输入:wq退出,接下来给文件赋权 chmod 777 myserver.sh 打开iTerm2,打开Preferences配置界面,Profiles -> general,左下角点击+号,新建profile,参考下面图片在对应位置输入内容即可 Name:根据需求输入,通常选择标识性较强的内容便于区分,例如服务器的IP地址 Command:这里选择login Shell

【hive bug】between...and..的粗心bug

文章目录 一、BETWEEN (大于等于) AND (小于等于)查询 一、BETWEEN (大于等于) AND (小于等于)查询 查询包含在此区间内的所有整数 例如:我们想查询什么日期 ,“date>=20220103 and date<=20230103” 可用“date between 20220103 and 20230103” !!!注意点,时间顺序不可以调换,between后面是 “大于等于” 的含义,and后面是 “小于等于” 的含义 “date between 20230103 and 20220103 ” 等价于 “date>=20230103 and date<=20220103” ,这样子存在逻辑错误,导致业务出错,实际上有数据的,但却取空数据。

outputStream转换InputStream

有这个需求,一般是在后台将文件保存,而且将文件上传至服务器,才需要将流进行转化。用到ByteArrayInputStream这个类。 我实际需求是导出一个word,并且将这个word上传至服务器,每次导出word,服务器留有word记录。 ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); //设置response返回给前端的响应内容 response.setHeader("Content-Disposition", "attachment;filename=".concat(new String(wordFil eName.getBytes("gbk"), "iso-8859-1"))); response.setHeader("Connection", "close"); response.setContentType("text/html; charset=GBK"); response.setContentType("application/msword"); //导出word方法 geneWordFile(dataModel, byteArrayOutputStream); //此时有了byteArrayOutputStream输出流数据,将数据返回给response的输出流。 byteArrayOutputStream.writeTo(response.getOutputStream()); byte[] buffer = byteArrayOutputStream.toByteArray(); InputStream is = new ByteArrayInputStream(buffer);

Maven配置报错The JAVA_HOME environment variable is not defined correctly

配置maven环境变量时,将变量名定义为:MAVEN_HOME,变量值为主目录地址 并且系统变量Path定义为%MAVEN_HOME%\bin时出错 错误信息: The JAVA_HOME environment variable is not defined correctly This environment variable is needed to run this propram JAVA_HOME should point to a JDK not a JRE 那肯定是JAVA_HOME配置的不对,于是查看了一下 没发现有什么问题,于是找度娘 JAVA_HOME后面不能带\bin路径 JAVA_HOME后面不能带空格,不能带; 不要在path中添加其他字符,例如:. ; ........等 删除JAVA_HOME和Path保存后重新添加 以上方法都不能解决我的问题,大哭,继续检查 最后发现我那错误是因为更新过jdk,而我的用户变量JAVA_HOME是以前的8.0版本,和我的系统变量JAVA_HOME路径不一样,所以就报了这个错误,把两个路径统一后就解决了 再次mvn -version

【STM32】基于HAL库的中断详细学习

目录 1.中断概述 1.1中断相关概念 1.2 STM32中断系统 2 .HAL库的中断处理 2.1 HAL 库的中断封装 2.2 外部中断处理流程 3.外部中断的HAL库定义 3.1. 外部中断的数据类型 3.2. 外部中断的接口函数 1.中断概述 在计算机系统中,处理器常常需要与外部设备进行数据传输。常见的数据传输方式有以下四种: 1. 无条件方式 处理器不必了解外部设备的状态,直接进行数据传输,适用于指示灯和按键等简单设备。 2. 查询方式 常用于处理器与慢速外部设备之间的数据传输。处理器与外部设备进行传输数据之前,先检查外部设备的状态。如果外部设备处于“准备好”状态(输入设备)或“空闲”状态(输出设备)时,才进行数据传输。否则将循环查询外部设备的状态,直到外部设备就绪。在查询过程中,处理器无法执行其他任务,利用率较低。 3. 中断方式 处理器不主动查询外部设备的状态,而是让外部设备在数据准备好之后,再通知处理器。这样,处理器在没接到外部设备通知前只管做自己的事情,只有接到通知时才执行外部设备的数据传输工作。在中断方式中,处理器和外部设备均可并行工作,从而提高了处理器的利用率。 4. 直接存储器访问方式(DMA) DMA方式是在处理器内部建立片内外设和内存之间的数据传输通道,传输过程不需要处理器参与。DMA方式由硬件实现,特别适合于批量数据传输的场合。 1.1中断相关概念 1.中断的定义 为了更好地描述中断,我们以一个日常生活中的例子来说明。假设,你在家里阅读时,突然接到快递员的电话,通知你领取快递。这时,你需要记录当前阅读的页码,然后暂停阅读工作,转而去领取快递。快递领取之后,你再返回家里,根据记录的页码继续阅读。 类似的,在处理器执行程序的过程中,被处理器内部或外部事件所打断,暂停当前程序的执行,转而去执行该事件对应的处理程序,这个处理过程称为中断。 在中断过程中,引发中断的事件称为中断源;当前正在执行的程序称为主程序;主程序被暂停的位置称为断点;事件所对应的处理程序称为中断服务程序(interrupt service routine,ISR)。中断过程的示意图如图所示。 2.中断的作用 最初,中断技术引入到计算机系统,主要是为了解决快速处理器与慢速外部设备之间的数据传输问题。例如,打印数据时,处理器传输数据的速度较快,而打印机打印数据的速度较慢。如果不采用中断技术,处理器将经常处于等待状态,利用率较低。采用中断技术后,处理器向打印机传输数据后,就可以去处理其他的事务。当打印机打印完当前的数据后,再发出中断请求,处理器才予以响应。此时,处理器将暂停执行当前程序,转而执行向打印机传输下一批数据的程序,传输完成后又返回原来的程序执行。由于在打印机打印数据的过程中,处理器可以并行处理其他的事务,从而提高了处理器的工作效率。 随着计算机技术的应用,人们发现中断技术不仅解决了处理器和外部设备的数据传输问题,还具备以下优点: 1.分时操作 处理器可以分时为多个外部设备服务,提高了计算机的利用率。 2.实时响应 处理器能够及时处理系统的随机事件,提高了系统的实时性。 3.可靠性高 处理器具有处理设备故障及掉电等突发事件的能力,提高了系统的可靠性。 3.中断优先级和中断嵌套 在实际应用中,处理器需要处理多个来自不同中断源的中断申请,不同中断源的中断申请在紧迫度上可能不尽相同,因此处理器需要在系统中设置中断源的优先等级,也就是中断优先级。 在某一时刻,有多个中断源同时发出中断申请时,处理器只处理其中优先级最高的中断源。当处理器正在运行某一个中断源对应的中断服务程序时,出现了另一个中断源的中断申请。如果后者的优先级低于前者,处理器将不予理睬。反之,处理器将立刻响应后者,这种方式称为中断的嵌套。 4.中断服务程序和中断向量表 在介绍中断的概念时,我们将中断发生时所执行的特定程序称为中断服务程序,英文缩写ISR。中断服务程序一般由用户编写,主要内容是该中断发生时需要执行的具体任务。以定时中断实现指示灯的闪烁为例,在发生定时中断时,需要切换指示灯的状态。那么定时中断所对应的中断服务程序的主要内容就是切换指示灯的状态。 在计算机系统中,当某一个中断源提出中断申请后,处理器要如何准确地找到这个中断源所对应的中断服务程序呢?首先,为了区分各个中断源,计算机系统为每一个中断源分配了一个编号,这个编号称为中断类型号。接着,对于系统需要响应的每一个中断源,都预先编写好对应的中断服务程序。最后,按照中断类型号,从小到大将所有中断服务程序的入口地址(函数名)依次排列,组合为一张表格的形式,这个表格就称为中断向量表,而中断服务程序的入口地址称为中断向量。 中断向量表通常位于存储器的零地址处。当某一个中断源发出中断申请时,处理器根据识别到的中断类型号查找中断向量表,找到对应的表项。表项的内容就是该中断所对应的中断服务程序的入口地址,然后跳转到该地址执行具体的中断处理任务。 从理解的角度上看,我们可以把中断向量表看作一个数组:每一个数组元素的内容就是中断服务程序的入口地址,数组元素的下标相当于每一个中断的中断类型号。 5.中断响应过程 了解了中断的相关概念后,我们可以总结出中断响应的完整步骤: ① 中断源发出中断请求。 ② 判断处理器是否允许中断,以及该中断源是否被屏蔽。 ③ 多个中断同时申请时,需要进行优先级排队。 ④ 处理器暂停当前程序,保护断点地址和处理器的当前状态,根据中断类型号,查找中断向量表,转到对应的中断服务程序。 ⑤ 执行具体的中断处理任务。 ⑥ 恢复被保护的处理器状态,执行中断返回指令,回到被暂停程序的断点地址处。

【学习记录】STM32中断进阶任务:按键控制指示灯闪烁频率

采用德飞莱STM32板,主控芯片STM32F103ZET6。 任务内容:利用按键B1控制指示灯LD2的闪烁频率,闪烁频率设置为3档:初始状态时,LD2按照2Hz的频率闪烁;第一次按键后,LD2按照10 Hz的频率闪烁;第二次按键后,LD2按照20Hz的频率闪烁。再次按键后让LD2恢复以2Hz的频率闪烁,并重复上述过程。按键的检测采用中断方式。 硬件原理:按键B1由引脚PC13控制:按键按下时为下降沿触发方式,释放时为上升沿触发方式。指示灯LD2由引脚PA5控制;PA5输出高电平,开启指示灯;PA5输出低电平,关闭指示灯。 任务实现 1. 设计思路 采用前后台编程模式:定义一个全局变量BlinkSpeed,初始化为0。在外部中断服务程序(前台程序)中修改BlinkSpeed的值;在主程序(后台程序)的while(1)循环中不断检测BlinkSpeed的值,根据取值的不同修改指示灯的闪烁频率。 2. 引脚分配和外设配置 本任务所使用的引脚和外设与基础任务中所使用的相同,因此省去引脚分配和外设配置的过程。 1. 双击进入 2. 3. 4.配置LED灯引脚(PB5) 5. 配置KEY键引脚(PE2) 配置上拉、上升沿和下降沿 使能中断 6.配置时钟树 7.改名、保存、打开 3. 程序编写 生成MDK工程后,进行应用程序的编写。具体代码如程序代码段1和2所示。 代码段1: /* USER CODE BEGIN PV */ volatile uint8_t BlinkSpeed = 0;// 指示灯闪烁频率:0->2Hz 1->10Hz 2->20Hz /* USER CODE END PV */ /* ………………………… */ // 省去中间部分代码 /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ if( BlinkSpeed == 0) // 2Hz 闪烁频率 { HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_5); HAL_Delay(500); } else if( BlinkSpeed == 1 ) // 10Hz 闪烁频率 { HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_5); HAL_Delay(100); } else // 20Hz 闪烁频率 { HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_5); HAL_Delay(50); } } /* USER CODE END 3 */ 程序解释:

**省**市正则

省市正则表达式是指用于匹配中国省市的正则表达式。 例如,可以使用正则表达式来匹配中国的省份和城市,如北京市,上海市等。 一个简单的省市正则表达式可能是这样的: [\u4e00-\u9fa5]{2,4}(?:省|市) 这个正则表达式可以匹配中文名称为 2 到 4 个字的省或市。

CSS 奇技淫巧Box-shadow实现圆环进度条

CSS 奇技淫巧Box-shadow实现圆环进度条 文章目录 CSS 奇技淫巧Box-shadow实现圆环进度条一、Box-shadow圆环进度条二、效果预览三、原理刨析四、实际应用五、总结六、参考资料💘七、推荐博文🍗 一、Box-shadow圆环进度条 实现圆环进度条的方法用很多种,比较容易想到的可能是通过 border属性实现,在本文将使用 Box-shadow盒子阴影呈现,一般来说还真的难想到这个方法,说这种方法是一个奇技淫巧也不为过,让我们接着来看。 二、效果预览 <div class="container"> <div class="ring-wrap"> <div class="ring">Hover</div> </div> </div> $borderColor: #ff5d8f; // 设置阴影 @function setShadow($x: 0, $y: 0, $fuzzy: 0, $spread: 0, $color: $borderColor) { @return #{$x}px #{$y}px #{$fuzzy}px #{$spread}px $color; } .container { display: flex; background-color: #6C6C6C; height: 500px; } .ring-wrap { display: flex; overflow: hidden; width: 156px; height: 156px; margin: auto; border-radius: 50%; .ring { // 宽高需要预留边框大小 width: 150px; height: 150px; line-height: 150px; margin: auto; border-radius: 50%; font-size: 25px; text-align: center; color: #fff; box-shadow: setShadow(75, -75, $color: transparent), setShadow(-75, -75), setShadow(75, -75), setShadow(-75, 75), setShadow(75, 75); background-color: #2894FF; cursor: pointer; &:hover { animation: ring-border 2s ease-in-out forwards; } } } @keyframes ring-border { 0% { box-shadow: setShadow(75, -75, $color: transparent), setShadow(-75, -75), setShadow(75, -75), setShadow(-75, 75), setShadow(75, 75), setShadow($spread: 3, $color: transparent); } 25% { box-shadow: setShadow(75, -75, $color: transparent), setShadow(-75, -75), setShadow(0, -160), setShadow(-75, 75), setShadow(75, 75), setShadow($spread: 3, $color: #FFF); } 50% { box-shadow: setShadow(75, -75, $color: transparent), setShadow(-160, 0), setShadow(0, -160), setShadow(-75, 75), setShadow(75, 75), setShadow($spread: 3, $color: #FFF); } 75% { box-shadow: setShadow(75, -75, $color: #fff), setShadow(-160, 0), setShadow(0, -160), setShadow(0, 160), setShadow(75, 75), setShadow($spread: 3, $color: #FFF); } 100% { box-shadow: setShadow(75, -75, $color: #fff), setShadow(-160, 0), setShadow(0, -160), setShadow(0, 160), setShadow(160, 0), setShadow($spread: 3, $color: #FFF); } } 三、原理刨析 原理很简单,最重要的是控制阴影按照顺序延时移动,除此之外,还需要一层父元素使用 overflow:hidden 对额外的阴影进行隐藏,父子宽度高不能一致,需要留足阴影填充边框的间隙。

程序员退休后可以干什么工作

程序员退休后有很多工作可以做,比如: 继续从事编程工作,可以为公司或个人提供咨询服务。当讲师或培训师,教授新一代程序员。在自己的公司中担任项目经理或技术顾问。将专业技能转化到其他行业,例如数据分析或人工智能。 总的来说,程序员退休后有很多机会继续使用自己的技能,并在新的领域有所发挥。

VS2019QT添加模块

QT vs tools -> qt project setting -> 配置属性 -> qt project setting;字符串加分号形式添加对应模块。

C语言经典编程题 --- 打印菱形

目录 一、题目描述 二、普通解法 三、曼哈顿距离解法 一、题目描述 输入一个奇数 n,输出一个由 * 构成的 n 阶实心菱形 输入格式:一个奇数 n。 输出格式:输出一个由 * 构成的 n 阶实心菱形。 输入样例:5 输出样例: * *** ***** *** * 二、普通解法 思路:若要打印第一星,首先就要先打印前6个空格,下面部分也是如此。所以,为了方便打印,我们可以分成上半部分和下半部分,上半部分空格个数由多变少,星个数由少变多;下半部分空格个数逐渐变多,星星个数逐渐变少。 因此假设n = 13,下半部分就是6行,和n的关系也就是n / 2,则上半部分就是 n - 下半部分。然后通过循环来遍历空格和星号就可以了。 对于上半部分的代码如下: 解析都在代码里了 #include <stdio.h> int main() { int n = 0; //输入一个奇数 scanf("%d", &n); int down = n / 2; //上半部分的行数 int up = n - down; //下半部分的行数 //打印上半部分 for (int i = 0; i < up; i++) //控制行 { //打印空格 //通过规律可以发现是up - 1 - i for (int j = 0; j < up - 1 - i; j++) { printf("

YOLOv5的介绍

YOLOv5(You Only Look Once version 5)是一种目标检测模型,用于在视频或图像中识别和定位物体。它是YOLO(You Only Look Once)算法的最新版本,在YOLOv4的基础上进行了改进。 YOLOv5是一种端到端的深度学习模型,可以直接从原始图像中检测和定位目标。它使用卷积神经网络(CNN)来学习图像中物体的特征,并使用多尺度预测和网格分割来检测和定位目标。YOLOv5的优势在于它可以在高速运行,并且可以在不同的图像分辨率上很好地工作。 总的来说,YOLOv5是一种高效的目标检测模型,可以应用于许多不同的场景,包括自动驾驶,机器人感知,图像分析等。

xshell连接Linux一直失败解决方法

文章目录 解决对象方法配置防火墙关闭Linux防火墙关闭Windows防火墙 xshell连接Linux一直失败解决方法 解决对象 可能出现以下两个问题: Linux防火墙已关闭和Windows防火墙已经关闭配置好 vim /etc/sysconfig/network-scripts/ifcfg-ens33 方法 配置 这个是最容易出错的,博主就是在这一步出现了错误 1.在Linux下输入 vim /etc/sysconfig/network-scripts/ifcfg-ens33 TYPE="Ethernet" #网络类型(通常是Ethemet) PROXY_METHOD="none" BROWSER_ONLY="no" BOOTPROTO="static" #IP的配置方法[none|static|bootp|dhcp](引导时不 使用协议|静态分配IP|BOOTP协议|DHCP协议) DEFROUTE="yes" IPV4_FAILURE_FATAL="no" IPV6INIT="yes" IPV6_AUTOCONF="yes" IPV6_DEFROUTE="yes" IPV6_FAILURE_FATAL="no" IPV6_ADDR_GEN_MODE="stable-privacy" NAME="ens33" UUID="e83804c1-3257-4584-81bb-660665ac22f6" #随机id DEVICE="ens33" #接口名(设备,网卡) ONBOOT="yes" #系统启动的时候网络接口是否有效(yes/no) #IP地址 IPADDR=192.168.132.100 #这个ip地址可以自己设置,但必须和自己的网关在同一个频道上(即除倒数第一个小数点后面的数字可以不同,其他的都要相同) #网关 GATEWAY=192.168.132.2 #域名解析器 DNS1=192.168.132.2 编辑完后,按键盘esc ,然后输入 :wq 回车即可。 重点:这个ip地址可以自己设置,但必须和自己的网关在同一个频道上(即除倒数第一个小数点后面的数字可以不同,其他的都要相同) 配置好后要输入service network restart 重启网络 ,这时候输入ifconfig查看,就可以发现自己的ip地址已经改变了 防火墙 关闭Linux防火墙 停止防火墙服务 systemctl stop firewalld 设置开机时关闭防火墙 输入systemctl disable firewalld 判读防火墙是否自动启动 systemctl is-enabled firewalld 关闭Windows防火墙 在Windows下方搜索栏下搜索控制面板,点击系统和安全 点击防火墙

利用redis ZSet 有序集合实现可靠滚动分页

利用redis ZSet 有序集合实现可靠滚动分页 即在有新的数据插入分页查询不会查询重复或者遗漏数据 传统的分页 前端参数一般传入当前页数curpage和页面长度paegsize 最终通过数据库limit curpage*(pageszie-1),pageszie 实现分页 假设两参数分别为1,5 即 limit 0,5 也就是查询序号0到4的5条数据 这时如果数据库新增了一条数据其序号为1。 如果查询下一页即limit 5,5 查询序号为5 到9的数据 如图所示,很显然值为四的数据被重复查了。 查了下比较流行的做法就是新增一个字段,记录数据插入的时间。 然后查寻第一页的时候记录当前时间,之后每次分页查询都需要带上这个时间 把比这个时间大的数据排除。该方案挺不错,但是要修改数据库,费事. 我的方案是借助redis 的有序集合 ,每次插入数据库成功时,额外保存一份<数据id,插入时间>到redis的有序集合里 。这时就可以通过插入时间分页了。第一次查询返回按时间排序前1到5的数据, 然后记录当前的时间6 。 之后的查询带上这个时间。 返回从 比这个时间小的第一个数据(即为5)和其后的四条数据。 。如图: 时间戳 10 9 8 7 6 5 4 3 2 1 值 10 9 8 7 6 5 4 3 2 1 第一页 时间戳 11 10 9 8 7 6 5 4 3 2 1 值

【python学习】用正则表达式匹配查找文本

学习自书本《Python编程快速上手——让繁琐工作自动化》 正则表达式 #正则表达式 import re aRegex=re.compile('\d\d\d-\d\d\d-\d\d\d\d') mo=aRegex.search('我的电话号码是:123-456-7890') print('找到句子中的匹配内容为:',mo.group()) 输出结果: 找到句子中的匹配内容为: 123-456-7890 利用括号分组 #利用括号分组 import re aRegex=re.compile(r'(\d\d\d)-(\d\d\d-\d\d\d\d)') mo=aRegex.search('我的电话号码是:123-456-7890') print('mo.group()',mo.group()) print('mo.group(0)',mo.group(0)) print('mo.group(1)',mo.group(1)) print('mo.group(2)',mo.group(2)) print('mo.groups()',mo.groups()) areaCode,mainNumber=mo.groups() print('areaCode是{},mainNumber是{}'.format(areaCode,mainNumber)) #如果需要在文本中匹配括号,需要用倒斜杠对左右括号进行字符转义 aRegex2=re.compile(r'(\(\d\d\d\))(\d\d\d-\d\d\d\d)') mo2=aRegex2.search('我的电话号码是:(123)456-7890') print('mo2.group(1)',mo2.group(1)) print('mo2.group(2)',mo2.group(2)) 输出结果: mo.group() 123-456-7890 mo.group(0) 123-456-7890 mo.group(1) 123 mo.group(2) 456-7890 mo.groups() ('123', '456-7890') areaCode是123,mainNumber是456-7890 mo2.group(1) (123) mo2.group(2) 456-7890 用管道匹配多个分组 #用管道匹配多个分组 import re bRegex=re.compile(r'zhangsan|li si') mo1=bRegex.search('zhangsan and li si') #第一次出现的匹配对象将被返回 print('mo1.group()',mo1.group()) cRegex=re.compile(r'zhang(san|si|wu)') mo2=cRegex.search('zhangsan and zhangsi') print('mo2.group()',mo2.group()) print('mo2.group(1)',mo2.group(1)) 输出结果: mo1.group() zhangsan mo2.group() zhangsan mo2.

动态数据源切换

通过一个注解实现动态数据源切换 将要用的数据源名字,记录在threadLocal中通过AbstractRoutingDataSource,重写方法,将threadLocal中的数据源名字设置进去 。(当这个系统需要获取数据源的时候,会自动调用AbstractRoutingDataSource中的determineCurrentLookupKey()方法,获取要用的数据源名字)aop拦截注解网页上,传递你要使用的数据源名字,aop拦截修改threaLocal中的值多个aop调用顺序 // 创建DruidDataSource DruidDataSourceFactory.createDataSource() // 查找方法,类上的注解 AnnotationUtils.findAnnotation(); // @ConfigurationProperties @EnableConfigurationProperties 依赖 aop+druid+mysql+mybatis+web <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.2.9</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.2.2</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> 配置文件 # 数据源配置 spring: datasource: type: com.alibaba.druid.pool.DruidDataSource driverClassName: com.mysql.cj.jdbc.Driver ds: # 主库数据源 master: url: jdbc:mysql://localhost:3306/test09?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 username: root password: root # 从库数据源 slave: # 从数据源开关/默认关闭 enabled: false url: jdbc:mysql://localhost:3306/test08?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 username: root password: root # 初始连接数 initialSize: 5 # 最小连接池数量 minIdle: 10 # 最大连接池数量 maxActive: 20 # 配置获取连接等待超时的时间 maxWait: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 timeBetweenEvictionRunsMillis: 60000 # 配置一个连接在池中最小生存的时间,单位是毫秒 minEvictableIdleTimeMillis: 300000 # 配置一个连接在池中最大生存的时间,单位是毫秒 maxEvictableIdleTimeMillis: 900000 实体类+service+mapper

mysql多表查询30个经典案例

mysql多表查询30个经典案例 插入两张表一个dept一个emp插入dept表数据插入emp表数据1.列出每个部门里面有那些员工及部门名称;2.运维部门的收入总和;3.HR部入职员工的员工号4.财务部门收入超过5000元的员工姓名5.找出销售部收入最低的员工的入职时间;6.找出年龄小于平均年龄的员工的姓名,ID和部门名称7.列出每个部门收入总和高于10000的部门名称8.查出财务部门工资少于10000元的员工姓名9.求财务部门最低工资的员工姓名;10.找出运维部门中年纪最大的员工的姓名11.求收入最低的员工姓名及所属部门名称:12.求雷蕾的收入及部门名称13.求员工收入小于8000元的员工部门编号名字及其部门名称;14.列出每个部门中收入最高的员工姓名,部门名称,收入,并按照收入降序;15.求出运维部门收益最高的俩位员工的姓名,工号,收益16.查询运维部低于平均收入的员工号与员工姓名:17.列出部门员工数大于1个的部门名称;18.列出部门员工收入不超过10000,且大于5000的员工年纪及部门编号;19.求入职于2022年的员工所属部门名称;20.查找haiwu所在的部门名称;21.列出每一个部门中年纪最小的员工姓名,部门名称;22.列出每一个部门的员工总收入及部门名称;23.列出部门员工收入大于6000的员工号,部门名称;24.找出哪个部门还没有员工入职;25.先按部门号大小排序,再依据入职时间由早到晚排序员工信息表 ;26.找出运维部门收入大于7500,显示他们的ID和姓名和年纪;27.找出入职于2022年以前的员工,且显示他们的姓名和入职时间,按照先后循序进行排序展示28.找出入职于2022年1月以后的员工,并显示年龄,姓名,收入29.查找收入大于8000元以上的人的姓名和收入30.统计各个部门的收入总和并按照从大到小方式排序进行显示 插入两张表一个dept create table `dept`( `dept1` VARCHAR(10), `dept_name` VARCHAR(20) ) 一个emp create table `emp`( `id` varchar(10), `name` VARCHAR(25), `age` VARCHAR(10), `worktime` VARCHAR(10), `dept2` varchar(10), `incoming` int(10) ) 插入dept表数据 插入emp表数据 insert into emp (id,name,age,worktime,incoming,dept2) VALUES (1500,'wangyi',25,'2022/2/1',8900,101),(1501,'hufei',27,'2022/3/1',7500,102),(1502,'heisen',30,'2022/3/20',8900,102),(1503,'huahudie',25,'2022/8/9',9000,102),(1504,'baimu',25,'2022/01/01',4000,103),(1505,'leilei',27,'2016/05/09',27800,106),(1506,'liuxiaoyi',28,'2017/05/09',16000,105),(1507,'haiwu',27,'2018/09/06',6300,104) 1.列出每个部门里面有那些员工及部门名称; SELECT name,dept_name from dept left JOIN emp on dept.dept1 = emp.dept2 2.运维部门的收入总和; SELECT sum(incoming),dept_name from emp RIGHT JOIN dept ON emp.dept2 = dept.dept1 where dept_name=‘yunwei’ 3.HR部入职员工的员工号 SELECT dept_name,id from emp RIGHT JOIN dept on emp.

springboot项目配置动态注入与springboot读取docker环境变量

前言 最近在看《Kubernetes权威指南》这本书,书的第一章是部署一个mysql+tomcat的简单项目,要先部署mysql 实例然后创建mysql的svc,创建了svc时才会分配一个ip,因为打包的时候不知道这个ip所以tomcat项目要根据约定读取env环境变量才行,跟着书上的例子部署成功了,但是我实在没搞明白这个tomcat的项目是怎么读取env环境变量的?如果在springboot项目中又该怎么读取?基于这两个问题我又想到了两个新的问题:1.springboot怎么配置信息动态注入?2.docker怎么在镜像启动的时候注入env环境变量?带着这些问题我开始探索实验并把结果以及常用的命令记录下。 并没有对springboot的源代码做深入研究,只是探索实用功能。 springboot动态注入配置信息。 这是一个很简单的问题,但是我不擅长记命令,只是知道实用jar -jar 启动springboot项目的时候添加几个参数,具体的参数我是一个记不住,也不知道这些命令是怎么配置的,这里就简单整理一下。 springboot的配置优先级 默认配置 <配置文件 <命令配置 1、设置数据库连接地址url为空打包。 #这里是数据库配置 数据库的连接地址 现在我把url设置为空然后打包jar spring: datasource: #数据源基本配置 username: root password: jishuzhai driver-class-name: com.mysql.cj.jdbc.Driver url: type: com.alibaba.druid.pool.DruidDataSource 2、测试启动。 java -jar brief-plus_oa.jar #尝试启动应用 会报以下错误 #Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured. 3、注入参数启动。 java -jar -Dspring.datasource.url="jdbc:mysql://127.0.0.1:3306/brief_min?zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai&allowMultiQueries=true&useUnicode=true&characterEncoding=utf-8" brief-plus_oa.jar #启动项目成功 注意这里的spring.datasource.url 要和配置文件里面的字段一致 4、自定义注入参数字段。 整个url字段全部注入现在太难输入了,整个url只有ip地址是变化的这里可以简化一下看下面配置: brief: mysql: host: #自定义的参数 spring: datasource: #数据源基本配置 username: root password: jishuzhai driver-class-name: com.

【STM32学习5】STM32使用printf函数 打印到电脑串口助手

本文所使用的方法与代码参考自正点原子,如果想要详细了解这方面的知识,请阅读正点原子官方提供的文档。 一、背景 在开发STM32应用时,将一些信息通过串口打印到电脑上是常用的调试手段。C语言标准库中的printf函数是我们常用的打印函数。但是在STM32应用下一般无法直接使用这个函数,正点原子给出的解释如下,有兴趣可以详细了解一下。 标准库下的 printf 为调试属性的函数,如果直接使用,会使单片机进入半主机模式(semihosting),这是一种调试模式,直接下载代码后出现程序无法运行,但是在连接调试器进行 Debug 时程序反而能正常工作的情况。半主机是 ARM 目标的一种机制,用于将输入/输出请求从应用程序代码通信到运行调试器的主机。例如,此机制可用于允许 C 库中的函数(如 printf()和 scanf())使用主机的屏幕和键盘,而不是在目标系统上设置屏幕和键盘。这很有用,因为开发硬件通常不具有最终系统的所有输入和输出设备,如屏幕、键盘等。半主机是通过一组定义好的软件指令(如 SVC)SVC 指令(以前称为 SWI 指令)来实现的,这些指令通过程序控制生成异常。应用程序调用相应的半主机调用,然后调试代理处理该异常。调试代理(这里的调试代理是仿真器)提供与主机之间的必需通信。也就是说使用半主机模式必须使用仿真器调试。 如果想在独立环境下运行调试功能的函数,我们这里是 printf,printf 对字符 ch 处理后写入文件 f,最后使用 fputc 将文件 f 输出到显示设备。对于 PC 端的设备,fputc 通过复杂的源码,最终把字符显示到屏幕上。那我们需要做的,就是把 printf 调用的 fputc 函数重新实现,重定向fputc 的输出,同时避免进入半主模式。 目前想要在SMT32上使用printf有两种方法: 通过代码取消ARM的半主机工作模式,并重定向printf函数使用微库MicroLib,并重定向printf函数。 由于微库裁剪了许多标准库的功能,如果注重功能完整性建议使用第一种方法。 二、取消ARM的半主机工作模式 添加stdio.h头文件,并在程序中加入以下代码段即可(代码引自正点原子) /******************************************************************************************/ /* 在合适的位置引用下面头文件 */ #include <stdio.h> /* 加入以下代码, 支持printf函数, 而不需要选择use MicroLIB */ #if 1 #if (__ARMCC_VERSION >= 6010050) /* 使用AC6编译器时 */ __asm(".global __use_no_semihosting\n\t"); /* 声明不使用半主机模式 */ __asm(".global __ARM_use_no_argv \n\t"

拥抱 Spring 全新 OAuth 解决方案:spring-authorization-server 该怎么玩?

点击关注公众号,实用技术文章及时了解 前言 为什么使用spring-authorization-server? 真实原因:原先是因为个人原因,需要研究新版鉴权服务,看到了spring-authorization-server,使用过程中,想着能不能整合新版本cloud,因此此处先以springboot搭建spring-authorization-server,后续再替换为springcloud2021。 官方原因:原先使用Spring Security OAuth,而该项目已经逐渐被淘汰,虽然网上还是有不少该方案,但秉着技术要随时代更新,从而使用spring-authorization-server Spring 团队正式宣布 Spring Security OAuth 停止维护,该项目将不会再进行任何的迭代 项目构建 以springboot搭建spring-authorization-server(即认证与资源服务器) 数据库相关表结构构建 需要创建3张表,sql分别如下 CREATE TABLE `oauth2_authorization` ( `id` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, `registered_client_id` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, `principal_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, `authorization_grant_type` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, `attributes` varchar(4000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL, `state` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL, `authorization_code_value` blob NULL, `authorization_code_issued_at` timestamp(0) NULL DEFAULT NULL, `authorization_code_expires_at` timestamp(0) NULL DEFAULT NULL, `authorization_code_metadata` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL, `access_token_value` blob NULL, `access_token_issued_at` timestamp(0) NULL DEFAULT NULL, `access_token_expires_at` timestamp(0) NULL DEFAULT NULL, `access_token_metadata` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL, `access_token_type` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL, `access_token_scopes` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL, `oidc_id_token_value` blob NULL, `oidc_id_token_issued_at` timestamp(0) NULL DEFAULT NULL, `oidc_id_token_expires_at` timestamp(0) NULL DEFAULT NULL, `oidc_id_token_metadata` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL, `refresh_token_value` blob NULL, `refresh_token_issued_at` timestamp(0) NULL DEFAULT NULL, `refresh_token_expires_at` timestamp(0) NULL DEFAULT NULL, `refresh_token_metadata` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = Dynamic; CREATE TABLE `oauth2_authorization_consent` ( `registered_client_id` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, `principal_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, `authorities` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, PRIMARY KEY (`registered_client_id`, `principal_name`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = Dynamic; CREATE TABLE `oauth2_registered_client` ( `id` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, `client_id` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, `client_id_issued_at` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0), `client_secret` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL, `client_secret_expires_at` timestamp(0) NULL DEFAULT NULL, `client_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, `client_authentication_methods` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, `authorization_grant_types` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, `redirect_uris` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL, `scopes` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, `client_settings` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, `token_settings` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = Dynamic; 先进行认证服务器相关配置 pom.

Simulink-过零检测与代数环

过零检测 过零检测即通过Simulink为模块注册若干过零函数,当模块变化趋势剧烈时,过零函数将会发生符号变化。每个采样点仿真结束时,Simulink检测过零函数是否有符号变化,如果检测到过零点,则Simulink将在前一个采样点和目前采样点之间内插值。 以下列出了Simulink 中支持过零检测的模块。 Abs 一个过零检测:检测输入信号沿上升或下降方向通过零点 Backlash 两个过零检测:一个检测是否超过上限阈值,另一个检测是否超过下限阈值 Dead Zone 两个过零检测:一个检测何时进入死区,另一个检测何时离开死区 Hit Crossing —个过零检测:检测输人何时通过阈值 Integrator 若提供了Reset端口,则检测何时发生Reset;若输出有限,则有3个过零检测,即检测 何时达到上限饱和值、检测何时达到下限饱和值和检测何时离开饱和区 MinMax 对于输出向量的每个分量,当输入信号是新的最小值或新的最大值时,进行检测 Relay 一个过零检测:若Relay是 off状态,则检测开启点:若是on状态,则检测关闭点 Relational Operator 一个过零检测:检测输出何时发生改变 Saturation 两个过零检测:一个检测何时达到或离开上限,另一个检测何时达到或离开下限 Sign 一个过零检测:检测输人何时通过零点 Step 一个过零检测:检测阶跃发生时间 Switch 一个过零检测:检测开关条件是否满足 Subsystem 用于有条件地运行子系统:一个使能端口,一个触发端口 代数环 如果Simulink 的输入依赖于模型中某一模块的输出,就会产生一个代数环,如图所示。这意味着无法进行仿真,因为没有输入就得不到输出,没有输出也得不到输入,形成了一个死循环。 解决代数环的办法有以下4种。 1、采用替代结构,尽量不形成代数环的结构。 2、为可以设置初始值的模块设置初值。 3、对于连续系统,在模块的输出一侧增加memory模块。 4、对于离散系统,在模块的输出一侧增加 unit delay模块。

数据结构——红黑树

目录 一、红黑树基本概念 1.缘起 2.概念 (1)基本定义 (2)结点结构体定义 (3)基本要求 (4)图示 (5)黑高 3.两个重要性质 4.时间复杂度 二、红黑树的基本操作 1.查找 2.插入 3.删除 一、红黑树基本概念 1.缘起 由于平衡二叉树AVL的插入删除操作很容易破坏平衡特性,需要频繁调整树的形态。即:插入操作导致不平衡,则需要先计算平衡因子,找到最小不平衡子树(时间开销大),再进行LL/RR/LR/RL调整。 而红黑树RBT的插入删除操作很多时候不会破坏“红黑”特性,无需频繁调整树的形态。即便是需要调整,一般都可以在常数级时间内完成。 所以在以查为主、很少进行插入删除操作时选择平衡二叉树;如需频繁插入删除时用红黑树实用性更强。 2.概念 (1)基本定义 红黑树是二叉排序树,即左子树结点值<=根结点值<=右子树结点值; (2)结点结构体定义 struct RBnode { //红黑树的结点定义 int key; //关键字的值 RBnode* parent; //父结点指针 RBnode* lchild; //左孩子指针 RBnode* rchild; //右孩子指针 int color; //结点颜色,如可用0/1表示黑/红,也可用枚举型enum表示颜色 }; (3)基本要求 ①每个结点或是红色,或是黑色; ②根结点是黑色的; ③叶结点均是黑色的; ④不存在两个相邻的红结点(即红结点的父结点和孩子结点均是黑色的); ⑤对每个结点,从该结点到任一叶结点的简单路径上,所含黑结点的数量相同; 总结顺口溜:左根右,根叶黑,不红红,黑路同。 (4)图示 (5)黑高 ①结点的黑高bh——从某结点出发(不含该结点)到达任一空叶结点的路径上黑结点总数; ②根结点黑高为h的红黑树,内部结点数(关键字)至少有个,此时红黑树是“总共h层所有结点都是黑结点的满树形态”。 3.两个重要性质 (1)从根结点到叶结点的最长路径不大于最短路径的2倍; (解释:从根结点到任一叶结点的路径都相同,但又要满足“不红红”,也就是极端情况为红结点穿插在每两个黑结点中间) (2)有n个内部结点的红黑树高度; 4.时间复杂度 红黑树的查找操作的时间复杂度为。 二、红黑树的基本操作 1.查找 与BST、AVL相同,从根结点出发,左小右大,若查找到一个空叶结点,则查找失败; 2.插入 (1)先查找,确定插入位置(原理同二叉排序树),插入新结点; (2)新结点是根结点的话,将其染为黑色; (3)新结点不是根的话,将其染为红色: ①若插入新结点后依然满足红黑树的定义,则插入结束;

RPM包制作(二)创建SPEC文件 -来自红帽原厂课件

创建Spec 文件 在Red Hat EnterpriseLinux 6上,vim有一个帮助创建规范文件的宏。只需传入一个以.spec结尾的文件名: [user@host ~]$ vimsample.spec Red Hat Enterprise Linux 6版本的vim将使用spec模板为RPM构建提供一些常见的条目。 Spec举例 下面是一个带注释的spec文件示例 %define debug一package %{nil} --① %define product一family Red HatEnterprise Linux %define release_name Santiago %define base_release_version6 %define full_release_version6.0 %define beta Beta Name: redhat-release --② Version: ${base_release_version} --③ Release: 6.0.0.24%{?dist} --④ Summary: %{product_family}release file --⑤ Group: SystemEnvironment/Base License:GPLV2 Obsoletes: rawhide-releaseredhat-release-as redhat-release-es redhat-release-ws --⑥ Source0: redhat-release-6-4.tar.gz --⑦ %description --⑧ %{product_family} releasefiles %prep --⑨ %setup -q %build --⑩

deb dpkg fpm cpack debmake 打包

文章目录 deb 简介hello debfpmpreinst postinst prerm postrmcmake cpackdebmake deb 简介 deb: Linux发行版Debian系列(如Debian, Ubuntu等)的软件包格式, 没有自提取(Self-extracting), 不能直接运行, 需要借助dpkg等安装. Dpkg: Debian Package Manager, Debian包管理器, 中间级工具(medium-level), 用于安装, 构建, 删除和管理Debian软件包. 还有更为前端和用户友好的包管理工具, CLI(命令行接口)工具对应apt, 可以从远程获取软件包以及处理复杂的软件包关系, TUI(终端用户界面)对应aptitude, aptitude比apt又友好了一些. hello deb 写一个 hellodeb 的程序 #!/bin/bash cnt=0 while [ $cnt -lt 5 ]; do echo "Hello, DEB, $cnt" cnt=$((cnt+1)) done 加执行权限, 可以运行 $ chmod +x hellodeb $ ./hellodeb Hello, DEB, 0 Hello, DEB, 1 Hello, DEB, 2 Hello, DEB, 3 Hello, DEB, 4 写一个打包脚本 package.

Linux-配置阿里云YUM源

条件:虚拟机能够上网。 基本步骤: a.清理原有的YUM配置 b.前往 阿里巴巴开源镜像站 进行下载配置 c.更新YUM仓库 d.执行安装 1.清理原有的YUM配置 利用命令:cd /etc/yum.repos.d/ 利用命令:ls 查看原有的YUM配置。 利用命令:mv * /tmp/ 将原有的YUM配置移动到tmp路径下。 利用命令:ls 查看是否移动成功。 利用命令:vim /tmp/CentOS-Base.repo 查看文件中的内容。 我们会发现文件里会注明centos等官方字眼,证明这些文件是centos官方文件。 退出文件 2.下载基本和扩展配置 2.1下载基本配置 前往网站 阿里巴巴开源镜像站 下载配置 基本配置选择centos 复制命令:wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo 下载阿里基本配置。 命令解释: wget 下载 ; O 后跟下载位置; /etc/yum.repos.d/ 下载路径;CentOS-Base.repo 库名; https://mirrors.aliyun.com/repo/Centos-7.repo 下载库的链接位置(阿里云镜像网站)。 下载基本配置后,利用命令: ls和pwd 查看文件,发现路径下分别显示CentOS-Base.repo 和/etc/yum.repos.d 利用命令:vim CentOS-Base.repo 查看文件。 注意红色方框部分与前述的区别。 2.2下载扩展配置 扩展配置,选择epel 选择对应版本,复制链接到终端进行执行。 3.更新YUM仓库 利用命令:yum makecache 更新YUM仓库 4.执行安装 利用命令:yum repolist 查询安装的配置共有多少个软件包。 利用命令: yum install -y httpd 安装httpd服务

C语言实现简单计算器。

一.普通方法 用C语言来实现一个简单的计算器。 #include <iostream> // 头文件 using namespace std; // 命名空间名称引入 // std 是 C++ 标准库的命名空间名,C++ 将标准库的定义实现都放在这个命名空间中 int Add(int x, int y) { return x + y; } int Sub(int x, int y) { return x - y; } int Mul(int x, int y) { return x * y; } int Div(int x, int y) { return x / y; } void menu() {// 打印菜单 cout << "****1,加法********************" << endl; cout << "

用html画一颗圣诞树

可以用HTML的div元素来画圣诞树,代码如下: <div style="width: 200px; height: 300px; background-color: green;"> <!-- 用其他HTML元素画出圣诞树上的装饰 --> </div> 这样就可以画出一棵200像素宽,300像素高的绿色圣诞树。你也可以用CSS来调整圣诞树的外观。比如,可以使用border-radius属性来让圣诞树的边缘变得圆滑,使用box-shadow属性来给圣诞树增加阴影等等。

【Java】使用POI按模板样式导出Excel

一、场景 根据模板样式进行excel导出。 二、实现 首先,当然是要有一个excel模板,excel的样式用wps等进行设置。 然后就是代码的实现了,先引入POI的依赖: <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> </dependency> 然后就是实现方法里的代码,首先定义响应信息: HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse(); // 设置响应类型 response.setContentType("application/vnd.ms-excel"); // 设置字符编码 response.setCharacterEncoding("utf-8"); // 设置响应头信息 response.setHeader("Content-Disposition", "attachment; filename="文件名.xlsx", "utf-8")); 然后将excel模板转为输入流,这一步的实现方法有很多,具体选择因人而异,我这里就举一个例子: org.springframework.core.io.Resource resource = new ClassPathResource("templates/文件名.xlsx"); @Cleanup InputStream inputStream = resource.getInputStream(); ServletOutputStream outputStream = response.getOutputStream(); 然后获取excel模板数据: XSSFWorkbook workbook = new XSSFWorkbook(inputStream); // 传入上一步转换的输入流 Sheet sheet = workbook.getSheetAt(0); // 拿到excel模板的sheet页 我们得到excel模板数据后,肯定不是原模原样导出,否则直接io输出就好了。接下来就是操作excel模板数据,将它构造为我们要导出的excel,我这里仅组合一些常用的操作,具体操作根据个人情况自行组合: /** * 修改某单元格的值,先获取y行再获取y行的x列,然后修改值 * * x(列,从0开始计数) * y(行,从0开始计数) * value(修改值) */ sheet.

linux bazel构建mediapipe源码

参考网址: https://google.github.io/mediapipe/getting_started/install.html 记录一下debia上编译mediapipe的过程: 1.准备Bazelisk sudo wget -O /usr/local/bin/bazel https://github.com/bazelbuild/bazelisk/releases/latest/download/bazelisk-linux-amd64 sudo chmod +x /usr/local/bin/bazel 2.源码下载: $ cd $HOME $ git clone https://github.com/google/mediapipe.git # Change directory into MediaPipe root directory $ cd mediapipe 我是手动下载的mediapipe-0.8.11.zip,🏠之后直接进入即可。 3.安装opencv bash setup_opencv.sh 中间可能遇到opencv无法下载,多尝试几次 在opencv.sh中每次重来都会删除/tmp/build_opencv然后重新开始、 如下git下载缓慢, git clone https://github.com/opencv/opencv_contrib.git git clone https://github.com/opencv/opencv.git 可以有如下解决方案: 3.1.注释掉如下代码,然后自己手动下载这两个git放到对应的目录之后,重新运行 注释: #rm -rf /tmp/build_opencv #mkdir /tmp/build_opencv #git clone https://github.com/opencv/opencv_contrib.git #git clone https://github.com/opencv/opencv.git 然后bash setup_opencv.sh 3.2.将git命令改为从国内镜像下载: git clone https://github.com/opencv/opencv_contrib.git --> git clone https://gitcode.net/opencv/opencv_contrib.git git clone https://github.

如何提升图片清晰度?有了这4个工具,高糊图片也能变清晰

网上的图片经过多次传播,有的就不是很清晰了,想要提高图片清晰度,可以试试这5个好用的图片修复工具,简单易操作,上传图片就能一键变清晰! 1、Bigjpg 一个AI智能图片无损放大工具,使用方便,上传图片之后它会将噪点和锯齿的部分进行补充,实现图片的无损放大。 它支持放大的倍数有2倍、4倍、8倍和16倍,其中放大2倍或者4倍是免费的,对于日常提高图片清晰度来说够用了。 处理的时候会显示预计处理时间,大概几分钟就能处理完成了,处理结束后将图片重新保存下来就好了。 给大家看一下无损放大后的效果,图片的尺寸变大,而且画质也变得更加清晰了。 2、改图鸭 一个综合的图片编辑处理在线工具,它里面的功能还挺丰富的,其中就包括照片修复的功能,使用方便,不需要注册登录,完全免费。 照片修复功能包括人脸模糊修复、老照片修复、黑白照片上色、图片降噪和图片去雾,选择你需要的功能之后,就可以上传图片了。 比如模糊人脸修复,上传图片之后自动修复照片,然后将图片保存到本地就可以了。 给大家看一下修复后的效果,还挺不错的,模糊的人脸变得很清晰。 3、Photokit 一个图片在线编辑工具,里面的编辑功能还挺多的,其中还包括画质增强功能,使用这个功能也可以提高图片的清晰度。 进入图片编辑界面之后,上传图片,然后在下面点击画质增强功能,画质增强之后点击保存按钮,将图片保存下来就好了。 用它增强图片画质的时候,图片的尺寸并不会放大,画质会变得清晰,但是不是特别明显。 4、图片编辑助手 一款简单易操作的图片编辑处理软件,它里面的图片编辑功能和图片处理功能还挺丰富的,它里面也有照片修复的功能,想要提高图片清晰度用它也不错。 进入照片修复功能后就可以看到所有的修复功能,包括老照片修复、图片无损放大、黑白照片上色、模糊人脸修复、图片降噪、过曝修复和图片去雾,根据自己的情况选择需要的功能就行。 想要提高图片清晰度就可以使用图片无损放大的功能,上传图片之后选择放大的倍数,放大之后将图片保存就好了。 我选择的是放大4倍,给大家看一下无损放大后的效果,还挺清晰的。 5、美图秀秀 一款图片美化处理手机APP,它里面也有画质增强的功能可以使用,打开美图秀秀进入首页,就可以看到画质增强功能了。 点击画质增强的功能,上传图片它就会自动进行处理,处理结束之后点击保存,画质增强后的图片就会保存到手机相册了。 在相册中就可以明显看到图片参数的变化,尺寸变大,占用的内存大小也变大了,图片画质也变得清晰了。 好了,以上就是可以提高图片清晰度的功能,在线工具、电脑软件和手机APP都有,大家可以根据自己的情况去选择使用。

关于java:MybatisPlus多数据源使用多线程时失效的问题

Mybatis-Plus多数据源应用也是极为不便,应用@DS注解即可。然而不论加在类上还是加在实现接口的办法上,均不能正确的找到对应的数据库,所有的线程都抓着主数据库不放。 几经周折,屡次试验,最终将多数据源的注解申明在了Callable实现类的call办法上,并且须要用编码的形式,设置以后线程数据源名称,并在以后线程执行完结后,再将其革除掉。 import com.baomidou.dynamic.datasource.annotation.DS; import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder; @Override public Future<Map<String, Object>> getTableOverview(CountDownLatch latch) { return executor.submit(new Callable<Map<String, Object>>() { @DS("slave") @Override public Map<String, Object> call() throws Exception { // 设置以后线程数据源 DynamicDataSourceContextHolder.push("slave"); Map<String, Object> result; try { // 查询数据库办法 result = getTableData(); } finally { latch.countDown(); // 强制清空本地线程,避免内存透露,手动调用push可调用此办法确保革除 DynamicDataSourceContextHolder.clear(); } return result; } }); }

解决问题Caused by: java.net.UnknownHostException

在Java中,"java.net.UnknownHostException" 异常表示无法解析主机名。这意味着你尝试连接的主机名无法解析为 IP 地址。可能的原因有: 主机名错误,请确保输入的主机名正确。网络连接问题,请检查网络是否连接正常。DNS 问题,请检查 DNS 服务器是否可以正常解析域名。 如果你无法解决这个问题,你可以尝试使用 IP 地址代替主机名。但是这可能会使你的代码变得不可移植,因为 IP 地址可能会改变。

CMS垃圾回收器细节思考与补充

CMS垃圾回收器作为jdk6、jdk7、jdk8等jdk版本对老年代进行垃圾回收的首选,其重要性不言而喻。深入理解CMS垃圾回收器的各个阶段存在的价值对于性能调优非常关键。 CMS的正常过程 参考博客3给出了CMS垃圾回收器的7个步骤: 1. 初始标记(CMS-initial-mark) ,会导致stw; 2. 并发标记(CMS-concurrent-mark),与用户线程同时运行; 3. 预清理(CMS-concurrent-preclean),与用户线程同时运行; 4. 可被终止的预清理(CMS-concurrent-abortable-preclean) 与用户线程同时运行; 5. 重新标记(CMS-remark) ,会导致stw; 6. 并发清除(CMS-concurrent-sweep),与用户线程同时运行; 7. 并发重置状态等待下次CMS的触发(CMS-concurrent-reset),与用户线程同时运行。 总的来说,CMS核心目标是缩短stop-the-world的时间,以快速响应业务。为此,CMS采用两次(初始标记和重新标记)短停顿来代替一次长停顿。上述步骤中的1和5即为两次stw,其他步骤则是用户线程和GC线程并发执行。接下来结合参考博客1逐一对上述步骤进行分析: 1、(STW)初始标记:这个阶段是标记从GCRoots直接可达的老年代对象,以及新生代直接引用的老年代对象,就是下图中灰色的点。这个过程是单线程的(JDK7之前单线程,JDK8之后并行,可以通过参数CMSParallelInitialMarkEnabled调整)。 由图可知,初始标记只是标记出了GCRoots直接可达的老年代对象,因而此次停顿时间通常很短。PS:在Java语言里,可作为GC Roots对象的包括如下几种: 虚拟机线程栈(栈桢中的本地变量表)中的引用的对象 ;方法区中的类静态属性引用的对象 ;方法区中的常量引用的对象 ; 本地方法栈中JNI的引用的对象。 2、并发标记:由上一个阶段标记过的对象,开始tracing过程,标记所有可达的对象,这个阶段垃圾回收线程和应用线程同时运行,如上图中的灰色的点。在并发标记过程中,应用线程还在跑,因此会导致有些对象会从新生代晋升到老年代、有些老年代的对象引用会被改变、有些对象会直接分配到老年代,这些受到影响的老年代对象所在的card会被标记为dirty,用于重新标记阶段扫描。这个阶段过程中,老年代对象的card被标记为dirty的可能原因,就是下图中绿色的线: 上图中绿色的线其实对应了四种情况,这四种情况在参考博客2中已经进行了总结: 新生代对象晋升到老年代新生代新创建的对象(Eden区)引用了原先老年代未被标记的对象直接在老年代分配的对象老年代对象的引用关系发生变化 为了提高重新标记的效率,该阶段会把上述对象所存在的card标记为dirty,后续只需要扫描dirty card对应的对象。 其中情况1、3、4都非常容易理解,但不知道读者对于情况2是如何理解的呢?情况2对应的就是上图中被标记的Eden区的对象1指向老年代的2。试想一下,在经过初始标记(stw)之后,老年代的2既不是GCRoots直接可达,也不是新生代直接引用的对象,那么在并发标记期间,引用了对象1的那个线程(取名为:线程A)是如何获取到对象2的引用并赋值给对象1的呢?前面已经介绍过了,GC Roots包括了线程栈中引用的对象,如果线程A保存了对象2的引用,那么对象2就应该在初始标记时被标记出来,但现在的情况是对象2在初始标记时没有被标记为可达。 这个疑惑也困扰了我很久,尝试从各种博客或者介绍JVM虚拟机的书籍中寻找答案,最终都无功而返。一种可能的猜测是:线程A在初始标记前直接引用了老年代的对象3(图中未给出示意),而对象3又引用了图中的对象2。那么在初始标记之后,对象3被标记为直接可达,而对象2未被标记。在并发标记期间,线程A在Eden区新创建了一个对象1,然后对象3将对象2赋值给对象1,接着对象3取消了对于对象2的引用。在这样的情形下,我们可以说新生代新创建的对象引用了原先老年代未被标记的对象。 PS:图中还有一个连线被打了个叉,表示在并发标记期间,新生代取消了对老年代对象的引用。对于这样的对象,垃圾回收器可能有两种选择:第一,取消对老年代对象的标记;第二,仍然认为该对象可达,在本轮垃圾回收过程中不被回收,而是在下一轮垃圾回收时再确定是否回收。由于有可能不止一个年轻代的对象引用该老年代对象,不能因为单个引用取消就直接将老年代对象的标记取消,因而个人猜测垃圾回收器会采取方案二。 3、预清理:预清理,也是用于标记老年代存活的对象,目的是为了让重新标记阶段的STW尽可能短。这个阶段的目标是在并发标记阶段被应用线程影响到的老年代对象,包括:(1)老年代中card为dirty的对象;(2)幸存区(from和to)中引用的老年代对象引用的老年代对象。因此,这个阶段也需要扫描新生代+老年代。此外,参考博文1中还提到“根据源码猜测不会扫描Eden区的对象”。对此,我们来分析其合理性。由前面的猜测可知,在初始标记之后,Eden区新创建的对象在并发标记期间引用老年代未被标记过的对象的概率是非常小的。此外,由后面的介绍可知,在重新标记阶段,还会再次对Eden区进行扫描,因而预清理阶段对Eden区进行扫描不仅费时,且收益微乎其微。 4、可中断的预清理:这个阶段的目标跟“预清理”阶段相同,也是为了减轻重新标记阶段的工作量。可中断预清理的价值有二:其一,在进入重新标记阶段之前尽量等到一个Minor GC,以缩短重新标记阶段的停顿时间(stw);其二,默认的可中断预清理会在Eden达到50%的时候开始,这时候离下一次minor gc还有半程的时间,这就可以避免避免短时间内连着的两个停顿(stw)。 在预清理步骤后,如果满足下面两个条件的任意一个,就不会开启可中断的预清理,而直接进入重新标记阶段: Eden的使用空间小于“CMSScheduleRemarkEdenSizeThreshold”,这个参数的默认值是2M;Eden的使用率大于等于“CMSScheduleRemarkEdenPenetration”,这个参数的默认值是50%。 这两个参数的含义是:预清理后,eden空间使用超过2M时才启动可中断的并发预清理(CMS-concurrent-abortable-preclean),低于2M则没有执行的必要,直到eden空间使用率达到50%时则中断“可中断的预清理”阶段,进入重新标记remark阶段。 如果上面两个条件都不满足,则进入可中断的预清理,可中断预清理可能会执行多次,那么退出这个阶段的出口有两个: 设置了CMSMaxAbortablePrecleanLoops,并且执行的次数超过了这个值,这个参数的默认值是0,表示不限制执行次数; CMSMaxAbortablePrecleanTime,执行可中断预清理的时间超过了这个值,这个参数的默认值是5000毫秒。 有可能可中断预清理过程中一直没等到Minor gc,这时候进入重新标记阶段的话,新生代还有很多活着的对象,就回导致STW变长,因此CMS还提供了CMSScavengeBeforeRemark参数,可以在进入重新标记之前强制进行一次Minor gc。 5、(STW)重新标记(并发):重新扫描堆中的对象,进行可达性分析,标记活着的对象。这个阶段扫描的目标是:新生代的对象 + GC Roots + 前面被标记为dirty的card对应的老年代对象。如果预清理的工作没做好,这一步扫描新生代的时候就会花很多时间,导致这个阶段的停顿时间过长。 这里需要补充一下,为什么说预清理工作能减少重新标记的停顿时间:重新扫描新生代对象和GC Roots对象时,只需要关心其直接引用的老年代对象还没有被标记过的对象(及其子对象),而无须关心已经被标记的直接引用对象:因为已经被标记过的对象如果其对应的card不为dirty,则无须扫描;而已经被标记为dirty card的对象自然会被扫描。因而预清理确实可以缩短重新标记的停顿时长。 6、并发清除:用户线程被重新激活,同时清除那些未被标记为存活的对象。由于CMS并发清理阶段用户线程还在运行着,伴随程序运行自然又会有新的垃圾不断产生,这一部分垃圾出现在标记过程之后,CMS无法在当次收集中处理掉它们,只好留待下一次GC时再清理掉。这一部分垃圾也称为“浮动垃圾”。 到此可知,虚拟机还需要存储一些特殊的信息,以区分出在标记周期以外新产生的对象(未标记)和在标记周期内产生的没有被标记的垃圾对象。 7、并发重置:CMS内部重置回收器状态,准备进入下一个并发回收周期。 小结:CMS的核心思路是,先用一次stw标记新生代和GC Roots直接引用的老年代对象,因而停顿时间通常很短;对于间接引用的对象,则通过并发标记来完成,以减少GC对业务的影响;由于并发标记会导致初始标记的直接引用对象发生变化,因而需要预清理来处理并发标记引起的并发问题;而由于预清理也是并发的,因而最终还需要第二次stw来重新标记并发标记和预处理标记期间的并发问题;而为了缩短第二次stw标记的停顿时间,又增加了可中断的预清理阶段,并期待在该阶段发生一次Minor GC,从而极大地减少了第二次stw标记需要扫描的年轻代的对象。 CMS的异常情况 上面描述的是CMS的并发周期正常完成的情况,但是还有几种CMS并发周期失败的情况(会触发FullGC): 并发模式失败(Concurrent mode failure):CMS的目标就是在回收老年代对象的时候不要停止全部应用线程,在并发周期执行期间,用户的线程依然在运行,如果这时候如果应用线程向老年代请求分配的空间超过预留的空间(担保失败),就回触发concurrent mode failure,然后CMS的并发周期就会被一次Full GC代替——停止全部应用,使用Serial-Old收集老年代,并进行空间压缩。如果我们设置了UseCMSInitiatingOccupancyOnly和CMSInitiatingOccupancyFraction参数,其中CMSInitiatingOccupancyFraction的值是70,那预留空间就是老年代的30%。晋升失败:新生代做minor gc的时候,需要CMS的担保机制确认老年代是否有足够的空间容纳要晋升的对象,担保机制发现不够,则报concurrent mode failure,如果担保机制判断是够的,但是实际上由于碎片问题导致无法分配,就会报晋升失败,从而执行Full GC。永久代空间(或Java8的元空间达到MaxMetaspaceSize)耗尽,默认情况下,CMS不会对永久代进行收集,一旦永久代空间耗尽,也会触发Full GC。 CMS的调优 针对停顿时间过长的调优

BigDecimal四舍五入保留两位小数

import java.math.BigDecimal; import java.text.DecimalFormat; import java.text.NumberFormat; public class NumberFormatDemo { public static void main(String[] args) { // BigDecimal // 保留两位小数 System.out.println(new BigDecimal(0.2).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());// 0.2 System.out.println(new BigDecimal(0.235).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());// 0.23 System.out.println(new BigDecimal(0.2351).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());// 0.24 System.out.println(new BigDecimal(42).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());// 42.0 // NumberFormat // 保留两位小数,个位无数字填充0 NumberFormat nformat = NumberFormat.getNumberInstance(); nformat.setMaximumFractionDigits(2); System.out.println(nformat.format(0.2));// 0.2 System.out.println(nformat.format(0.235));// 0.23 System.out.println(nformat.format(0.2351));// 0.24 System.out.println(nformat.format(42));// 42 // DecimalFormat,是NumberFormat的具体实现子类 // 保留两位小数,对应位上无数字填充0 DecimalFormat df = new DecimalFormat("#0.00"); System.out.println(df.format(0.2));// 0.20 System.out.println(df.format(0.235));// 0.23 System.out.println(df.format(0.2351));// 0.2, 因为0.2351在0.23-0.24之间,距离0.24更近,所以输出0.24 System.

Antd Select多选时,限制最大选择数

选择框的静态样式如下,其中我们可以在onChang拿到目前已选择的选项值,其是一个数组,然后我们在里面对其的长度进行判断。这里的 mode="multiple"是可以进行多选的意思。 <Select mode="multiple" onChange={this.handleChange} placeholder="请选择" > {tagsList?.map(item => { return ( <Select.Option key={item.id} value={item.id}> {item.name} </Select.Option> ); })} </Select> 比如我们想要限制最多选择三个。我们就可以按照下面的方式写 handleChange(value) { if (value.length > 3) { value.pop(); } }

Qt进度条详解以及format显示格式

进度条的步进值 设置好进度条的最大值和最小值,进度条将会显示完成的步进值占总的步进值的百分比,百分比的计算公式为:百分比 = (value() - minimum()) / (maximum() - minimum()) 部分函数含义 QProgressBar:横向或纵向显示进度的进度控件 setRange():设置进度条的变化范围 setValue():模拟处理过程,当处理完指定部分之后,步进值增加设置的值 setFormat():设置进度条显示文字的格式,%p%显示完成的百分比,是默认显示方式,%v显示当前的进度值,%m显示总的进度值 setInvertedAppearance():设置进度条反方向显示进度,默认为正方向显示进度 这些内容也可以到ui下设置 QProgressDialog:针对慢速过程的进度对话框,包括进度显示条,一个"取消(Cancel)"按钮和一个标签 setWindowModality():设置进度对话框的使用方式,包括模态和非模态。若为模态,则在显示进度条的同时,其他窗口不响应输入信号,且必须使用QApplication::processEvents()使事件循环保持正常进行状态,以确保应用不会阻塞;若为非模态,则需要通过QTime实现定时设置进度条的值 setMinimumDuration():设置进度条对话框出现前的等待时间,默认为4秒。系统根据所需完成的工作量估算一个预计花费的时间,若大于设定的等待时间(minimumDuration),则出现进度条对话框,若小于设定的等待时间,则不出现进度条对话框 setWindowTitle():设置进度对话框的窗体标题 setLabelText():设置进度对话框的显示文字信息 setCancelButtonText():设置进度对话框的"取消"按钮显示文字 setValue():同QProgressBar wasCanceled():检测“取消”按钮是否被触发 进度条美观设置,效果可以看一下,也可以做调整。 QProgressBar { border: 2px solid grey; border-radius: 5px; background-color: #FFFFFF;} QProgressBar::chunk { background:rgb(217, 217, 217); width: 20px;} QProgressBar { border: 2px solid grey; border-radius: 5px; text-align: center;}