封装、继承和多态
封装性:
把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。 类将成员变量和成员函数封装在类的内部,根据需要设置访问权限,通过成员函数管理内部状态
继承:
继承所表达的是类之间相关的关系,这种关系使得对象可以继承另外一类对象的特征和能力。 继承的作用:避免公用代码的重复开发,减少代码和数据冗余。
多态:
多态性可以简单地概括为“一个接口,多种方法”,字面意思为多种形态。程序在运行时才决定调用的函数,它是面向对象编程领域的核心概念。比如函数重载、运算符重载、虚函数等
当我们使用identity或者itab标签页插件时,尽管浏览器已经设置启动时打开新标签页,但是重新打开浏览器会发现还是会没有进入我们使用的identity或者是itab新标签页,需要在标题点击‘+’号才能够进入,这时只需要找到篡改浏览器的‘流氓软件’即可。以联想电脑为例,联想电脑一般出厂都会自带联想电脑管家,并且会锁定浏览器新标签页。处理办法:打开联想电脑管家,将“安全防护”的浏览器保护关闭即可,如果使用多个浏览器的话,需要注意将“上网主页保护”选项也关闭,如果只是edge浏览器的话,就只需要关闭“新标签页保护”
我是一名多年的硬软件工程师,下面的讲解你参考一下
.
.
.
万事从简单开始,我们来看看一个简单的放大电路。
.
上面电路图,是一个三极管放大电路来的,2N3904是三极管,它和外围器件,组成放大电路,让喇叭发出声音。
.
.
那上面这个图,在AD里面是怎么画出来的呢?
我们来看看AD软件的文件概念图
AD的概念就是上面这个图,项目文件相当于一个总文件夹,它里面可以包含很多子文件(右边指针头那些),这样说的话,当打开AD软件的时候,首先要创建一个项目文件,然后才能在项目文件里面创建子文件,这个就是完整的文件创建流程。
.
.
这节课的目标是,绘制原理图文件,那么我们的项目创建流程就是:先创建项目文件,再创建SCH原理图子文件
我们先来第一个目标:创建项目文件
不管什么版本的AD
第一步:点文件
第二步:点新建
第三步:点project
project就是中文翻译:“项目”的意思。
其它版本有选择区别的话,认准第一步是创建项目文件,就没有错了。
.
点project后,会打开如下窗口
上面图,1不用管,2,3可以随意改变
.
.
我把第2点文件名改成:放大电路,第3点文件位置,随你喜欢都可以的,弄好之后,点右下角的OK
.
.
项目文件的后缀就是:prjpcb
项目文件弄好之后,现在就可以为它添加SCH原理图文件了。
.
.
添加原理图文件的流程
第一步:鼠标右击:放大电路.prjpcb。
第二步:鼠标左击:给工程添加新的
第三步:鼠标左击:schematic,schematic就是原理图的意思,简称SCH
.
.
就是这样,放大电路项目里面的原理图文件,就创建了。
左边是原理图文件名字,后缀是schdoc,右边是原理图绘制界面
.
.
保存原理图文件流程
第一步:鼠标右击:sheet1.schdoc
第二步:鼠标左击:点保存
第一次保存的话,会弹出如下窗口。
.
.
.
.
然后保留后面的后缀名字:.schdoc
前面可以随意改名字,我改成了:放大电路
完成后,点右下角的保存,就可以了。
.
.
保存项目流程
第一步:右击:放大电路.prjpcb
第二步:左击:点保存工程,就可以把原理图文件,保存在项目文件里面进行使用了。
.
.
项目文件包含很多子文件,就是这么一个概念,创建任何一个文件,记得保存哦!
.
.
岁月哥是单片机专业,需要代画:proteus仿真图,单片机程序代写,代画AD原理图,PCB图的同学,请联系徵信:nianhua238
.
.
.
文章目录 0、概述1、mysqldump导出数据+mysql导入数据1.1、使用mysqldump导出数据1.1.1、使用--tables导出指定表1.1.2、使用--tab选项将表定义文件和数据文件分开导出1.1.3、使用--fields-terminated-by选项定义数据分隔符1.1.4、使用--databases选项导出整个库或多个库1.1.5、使用--all-databases选项导出所有数据库1.1.6、使用--xml选项实现导出格式为XML1.1.7、使用--ignore-table选项实现导出时忽略指定表1.1.8、使用mysql客户端配合mysqldump实现通配符匹配表名的导出1.1.9、使用mysqldump导出数据的优化方式 1.2、使用mysql导入数据1.2.1、基本导入方法1.2.2、乱码问题 2、SELECT INTO OUTFILE导出数据+LOAD DATA或mysqlimport导入数据2.1、使用SELECT INTO OUTFILE导出数据2.2、使用LOAD DATA导入数据2.2.1、使用LOAD DATA导入数据的基本导出方法2.2.2、导出导入csv格式文件2.2.3、SELECT INTO OUTFILE导出+LOAD DATA导入方案的优势2.2.4、LOAD DATA的优化 2.3、使用mysqlimport导入数据 3、使用mysql程序的批处理模式导出数据4、使用Linux的split切割文件,加速导入数据5、总结 0、概述 MySQL数据的导入导出方案通常是配套的,例如:
方案一:使用mysqldump导出数据,再使用mysql客户端导入数据
方案二:使用SELECT INTO OUTFILE命令导出数据,再使用LOAD DATA或mysqlimport导入数据
方案三:使用mysql程序的批处理模式导出数据,再使用LOAD DATA或mysqlimport导入数据
1、mysqldump导出数据+mysql导入数据 1.1、使用mysqldump导出数据 1.1.1、使用–tables导出指定表 # 语法 mysqldump db_name --tables tb1_name tb2_name > filemname.sql # 实例 mysqldump mytest --tables t1 t2 > t1_t2.sql 1.1.2、使用–tab选项将表定义文件和数据文件分开导出 # 语法 mysqldump db_name --tab=dir # 实例 mysqldump mytest1 --tab=/home/mysql/__test 1.1.3、使用–fields-terminated-by选项定义数据分隔符 以下导出时,数据值以逗号分隔
mysqldump mytest1 --tab=/home/mysql/__test --fields-terminated-by=',' 1.1.4、使用–databases选项导出整个库或多个库 参数说明如下:
–complete-insert:导出的dump文件里,每条INSERT语句都包含列名。–force:即使出现错误,也要继续执行导出操作,会打印出错误。–insert-ignore:生成的INSERT语句是INSERT IGNORE的形式,如果导入此文件,即使出错了也仍然可以继续导入数据(当作警告)。–databases:类似–tables,后面可以跟多个值,即多个数据库名–compatible=name:导出的文件和其他数据库更兼容(但不确保),name的值可以是ANSI、MYSQL323、MYSQL40、POSTGRESQL、ORACLE、MSSQL、DB2、MAXDB、NO_KEY_OPTIONS、NO_TABLE_OPTIONS或NO_FIELD_OPTIONS。 mysqldump --complete-insert --force --add-drop-database --insert-ignore --hex-blob --databases mytest > mytest_db.
1. 前言 在本月初,谷歌发布了 Flutter 2.0 正式版,其中对于大多数 Flutter 开发者影响最大的就是 Dart 的空安全。因为只要把 SDK 升级到 2.0,那么你之前写的代码就一定得修改,而且需要修改的地方还不少,如果项目是你自己的,那还好,随便搞。但要是公司的,那就得小心了,不然分分钟钟影响工作,增加你的工作量。
Flutter 在版本管理这块,相较于 Android 来说,是真的差。没有可视化管理工具,不能随便切换版本,升级 SDK 后会覆盖旧的……
难道就没办法在不影响之前的 SDK 和项目的前提下,体验 Flutter 2.0 了吗?有句老话说得好——只要肯动脑,办法总比困难多。要完全不影响,我是没想到好的办法,但是只是影响一点点的,我倒是有个办法——多配置一套 Flutter SDK。
2. 操作步奏 SDK有哪些版本?去哪里找 SDK?怎么下载?我这里就不多说了,可以看看 Flutter 中文社区上面的这两个文档——《安装和环境配置》《Flutter SDK 版本列表》
我这里以 Windows 系统、Android Studio、Flutter SDK 1.20.4 和 Flutter SDK 2.0.3 为例。
注:我这个方案,用 VS Code 好像是不太行的,找不到 VS Code 配置 SDK 的地方
2.1 准备 SDK 从官网下载 SDK 后,在本地创建两个文件夹“1.20.4”和“2.0.3”,用来分别存放对应版本的 Flutter SDK。我放在下面所示的路径:
D:\Program\Development\Flutter\1.20.4
D:\Program\Development\Flutter\2.0.3
2.2 配置环境变量 右键 “此电脑” → 单击 属性 → 弹出 “系统” 窗口,单击 高级系统设置 → 弹出 “系统属性” 窗口,单击 环境变量 → 弹出 “环境变量” 窗口,选择 “系统变量” 的 Path,单击 编辑 → 弹出 “编辑环境变量”,单击 新建 → 这里以配置 Flutter SDK 1.
试题 A: 阶乘求和 【问题描述】 令 S = 1! + 2! + 3! + ... + 202320232023!,求 S 的末尾 9 位数字。 提示:答案首位不为 0。
【思路】暴力实现
long a = 1; long b= 202320232023L; BigInteger sum = new BigInteger(String.valueOf(0)); BigInteger zhongjian=new BigInteger(String.valueOf(1)); for(;a<=b;a++){ zhongjian = zhongjian.multiply(BigInteger.valueOf(a)); sum = sum.add(zhongjian); } BigInteger end =sum.remainder(BigInteger.valueOf(1000000000)); System.out.println(end); 但是跑的时间会很长。最后得出一个结果420940313。网上有一篇题解上写的解法我没看懂,会的小伙伴可以留言。链接 2023年第十四届蓝桥杯JAVAB组题解 - 知乎 (zhihu.com)
试题 B: 幸运数字 【问题描述】 哈沙德数是指在某个固定的进位制当中,可以被各位数字之和整除的正整 数。例如 126 是十进制下的一个哈沙德数,因为 (126)10 mod (1+2+6) = 0;126 也是八进制下的哈沙德数,因为 (126)10 = (176)8,(126)10 mod (1 + 7 + 6) = 0; 同时 126 也是 16 进制下的哈沙德数,因为 (126)10 = (7e)16,(126)10 mod (7 + e) = 0。小蓝认为,如果一个整数在二进制、八进制、十进制、十六进制下均为 哈沙德数,那么这个数字就是幸运数字,第 1 至第 10 个幸运数字的十进制表示 为:1 , 2 , 4 , 6 , 8 , 40 , 48 , 72 , 120 , 126 .
sudo dpkg -i deb文件名
出现这个问题的原因有很多, 图片中的问题是Too many attributes。经过不断的尝试发现是将las格式的点云数据转为3dtiles的时候,存储的属性字段太多了(最开始的时候是全部存储了)。
于是后来在点云转换格式的时候,只存储了三个属性字段,并输出为3dtiles,最终显示成功。
最近项目要把收集到的地图上的点存储到redis中,然后使用geo命令处理,所以让我搞redis集群搭建,这个简单,网上都是,但是要用C++去连接集群而且支持geo命令和TLS认证,这就有点东西了,最后还是搞好了,记录一下。
1.安装hiredis
git clone https://github.com/redis/hiredis
cd hiredis
make USE_SSL=1
sudo make install
2.安装hiredis-cluster
git clone https://github.com/Nordix/hiredis-cluster.git
cd hiredis-cluster
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DENABLE_SSL=ON ..
make
到这里原始的库不自带geo指令,需要我们自己添加,找到command.c和command.h,修改源码
修改完成后重新make一下,这样库里就支持我们添加的geo指令了。
3.编写程序调用 ,增加TLS认证
#include "hiredis/hiredis_ssl.h" #include "hiredis/hiredis.h" #include "hiredis_cluster/hircluster_ssl.h" #include "hiredis_cluster/hircluster.h" #include <stdio.h> #include <stdlib.h> #define CLUSTER_NODE_TLS "127.0.0.1:6378,127.0.0.1:6379" #define CLUSTER_PASSWORD "<PASSWORD>" int main(int argc, char **argv) { UNUSED(argc); UNUSED(argv); redisSSLContext *ssl; redisSSLContextError ssl_error; redisInitOpenSSL(); ssl = redisCreateSSLContext(NULL, "/etc/ssl/certs", NULL, NULL, NULL, &ssl_error); if (!
LCD常用接口原理 点击打开链接
点击打开链接
点击打开链接
点击打开链接
点击打开链接
点击打开链接
点击打开链接
点击打开链接 xubin
平台信息:
内核:linux2.6/linux3.0
系统:android/android4.0 平台:samsung exynos 4210、exynos 4412 、exynos 5250
TFT-lCD常用的接口,TTL(RGB)、LVDS、EDP、MIPI,这篇我们大致说一下这些接口的信号组成已经基本原理。
一、TTL
1、TTL接口概述
TTL(Transistor Transistor Logic)即晶体管-晶体管逻辑,TTL电平信号由TTL器件产生。TTL器件是数字集成电路的一大门类,它采用双极型工艺制造,具有高速度、低功耗和品种多等特点。
TTL接口属于并行方式传输数据的接口,采用这种接口时,不必在液晶显示器的驱动板端和液晶面板端使用专用的接口电路,而是由驱动板主控芯片输出的TTL数据信号经电缆线直接传送到液晶面板的输人接口。由于TTL接口信号电压高、连线多、传输电缆长,因此,电路的抗干扰能力比较差,而且容易产生电磁干扰(EMI)。在实际应用中,TTL接口电路多用来驱动小尺寸(15in以下)或低分辨率的液晶面板。TTL最高像素时钟只有28MHz。
TTL是信号时TFT-LCD唯一能识别的信号,早期的数字处理芯片都是TTL的,也就是RGB直接输出到TFT-LCD。
2、TTL接口的信号类型
驱动板TTL输出接口中一般包含RGB数据信号、时钟信号和控制信号这三大类信号。如下图所示:
(1)RGB数据信号
a、单通道TTL
单通道6bit TTL输出接口
对于6bit单路TTL输出接口,共有18条RGB数据线,分别是R0~R5红基色数据6条,G0~G5绿基色数据6条,B0~B5蓝基色数据6条,共3*6=18条。由于基色RGB数据为18bit,因此,也称18位或18bitTTL接口。
单通道8bit TTL输出接口
对于8bit单路TTI,输出接口,共有24条RGB数据线,分别是R0~R7红基色数据8条,B0~B7绿基色数据8条,BO~B7蓝基色数据8条,共3*8=24条。由于基色RGB数据为24bit,因此,也称24位或24bitTTL接口。
b、双通道TTL
双通道,也就是两组RGB数据,分为奇通道、偶通道,时钟有的也分为OCLK/ECLK,有的公用一个,我们示意图上画了两个,如下所示:
双通道6bit TTL输出接口
对于6bit双路TTL,输出接口,共有36条RGB数据线,分别是奇路RGB数据线18条,偶路RGB数据线18条,3*6*3=36条。由于基色ROB数据为36bit,因此,也称36位或36bitTTL接口。
双通道8bit TTL输出接口
对于8bit双路TTL输出接口,共有48条RGB数据线,分别是奇路RGB数据线24条,偶路RGB数据线24条,3*8*2=48条。由于基色RGB数据为48bit,因此,也称48位或48bitTTL接口。
(2)时钟信号
是指像素时钟信号,是传输数据和对数据信号进行读取的基准。在使用奇/偶像素双路方式传输RGB数据时,不同的输出接口使用像素时钟的方法有所不同。有的输出接口奇/偶像素双路数据共用一个像素时钟信号,有的输出接口奇/偶两路分别设置奇数像素数据时钟和偶数像素两个时钟信号,以适应不同液晶面板的需要。
(3)控制信号
控制信号包括数据使能信号(或有效显示数据选通信号)DE、行同步信号HS、场同步信号VS。
二、LVDS
1、LVDS接口概述
LVDS,即Low Voltage Differential Signaling,是一种低压差分信号技术接口。克服以TTL电平方式传输宽带高码率数据时功耗大、EMI电磁干扰大等缺点而研制的一种数字视频信号传输方式。LVDS输出接口利用非常低的电压摆幅(约350mV)在两条PCB走线或一对平衡电缆上通过差分进行数据的传输,即低压差分信号传输。采用LVDS输出接口,可以使得信号在差分PCB线或平衡电缆上以几百Mbit/s的速率传输,由于采用低压和低电流驱动方式,因此,实现了低噪声和低功耗。
2、LVDS接口电路的组成
在液晶显示器中,LVDS接口电路包括两部分,即主板侧的LVDS输出接口电路(LVDS发送端)和液晶面板侧的LVDS输入接口电路(LVDS接收器)。LVDS发送端将TTL信号转换成LVDS信号,然后通过驱动板与液晶面板之间的柔性电缆(排线)将信号传送到液晶面板侧的LVDS接收端的LVDS解码IC中,LVDS接收器再将串行信号转换为TTL电平的并行信号,送往液晶屏时序控制与行列驱动电路。也就是其实TFT只识别TTL(RGB)信号。这部分我们做samsung的方案中用的比较多,因为samsung芯片没有LVDS输出,所以我们用LVDS接口的TFT-LCD的时候就要加一个(RGB-LVDS)转换芯片,这个后面我们重点说。
3、LVDS接口的信号类型
LVDS信号有数据差分和时钟差分信号组成。如下图所示:
(1)、单通道LVDS
单通道6位数据(如果是6位的Y3M/P这组红色的线没有)
有4组差分线,3组信号线,一组时钟线。Y0M、Y0P、Y1M、Y1P、Y2M、Y2P、CLKOUT_M、CLKOUT_P。
单通道8位数据
有5组差分线,4组信号线,一组时钟线。分别是Y0M、Y0P、Y1M、Y1P、Y2M、Y2P、CLKOUT_M、CLKOUT_P。
(2)、双通道
LVDS在传输分辨率较高的数据时,抗干扰能力比较强,可是1920X1080以上分辨率时,单路不堪重负,所以有双路接口出现。目的很简单,加快速度,增强抗干扰能力。
双通道6位数据
刚好是单通道的两倍,时钟也是两路,红色部分:Y3M、Y3P、Y3M1、Y3M1这两组信号不接。
双通道8位数据
A 题(幸运数): 答案:4430091
思路:只需要偶数位,那么就只枚举偶数位的数字,不管奇数位的数字,省时间。
但是直接枚举整个数字再分拆成两段显然常数有点大,所以我们可以分别枚举数字的前半段与后半段,分别判断数位和是否相等就会好做很多。
一亿之内的偶数位数字,有 1000 0000 ~ 9999 9999,10 0000 ~ 99 9999,1000 ~ 999,10 ~ 99 这几个范围。因为奇数位的没有被枚举,中间有空档,所以枚举的运算量不超过一亿。分拆数字的那一个 log 因为过小(最大也为 4),可以被丢掉。就算算上最大运算量也大约在一亿,轻松一秒之内跑过。
实际上不分类讨论,直接从 1 蛮到 1 0000 0000 也只需要 10 秒……出题人你在干什么,完全看不懂这道题想考察什么。
代码:
// // main.cpp // 幸运数 // // Created by SkyWave Sun on 2023/4/8. // #include <iostream> using namespace std; int numSum(int num) { int ans = 0; while (num) { ans += num % 10; num /= 10; } return ans; } int main(int argc, const char * argv[]) { int sum = 0; for (int i = 1; i <= 9; ++i) { for (int j = 0; j <= 9; ++j) { if (numSum(i) == numSum(j)) { ++sum; } } } for (int i = 10; i <= 99; ++i) { for (int j = 00; j <= 99; ++j) { if (numSum(i) == numSum(j)) { ++sum; } } } for (int i = 100; i <= 999; ++i) { for (int j = 000; j <= 999; ++j) { if (numSum(i) == numSum(j)) { ++sum; } } } for (int i = 1000; i <= 9999; ++i) { for (int j = 0000; j <= 9999; ++j) { if (numSum(i) == numSum(j)) { ++sum; } } } printf("
ToB Saas系统最近几年都很火。很多创业公司都在尝试创建企业级别的应用 cRM, HR,销售, Desk Saas系统。很多Saas创业公司也拿了大额风投。毕竟Saas相对传统软件的优势非常明显。 最近一年,有幸架构一个Crm saas 系统,上线了几个月来,各方面都比满意。整个系统创建过程,踩了很多坑,收获也比较多。总结一下Saas系统架构一些特点:
Saas系统分级:
SaaS系统架构成熟度模型的5个级别——从“混乱”到“乌托邦“
第0级(混乱):每次新增一个客户,都会新增软件的一个实例。
第1级(受控的混乱):所有客户都运行在软件的同一个版本上,而且任何的定制化都通过修改配置来实现。
第2级(多租户[multi-tenant]、高层建筑[Highrise]):所有的客户都已经可以在软件的同一个版本上运行了,而且他们都在同一个“实例”上运行。
第3级(多租户, 扩建[Build-Out]):此时你已经拥有了多租户、单一版本的软件模型。不过你还是可以通过硬件扩展(scale-out)的方式来进行扩充。
第4级(乌托邦):如同第3级,除非你可以找出有效的方式,以在不同的“实例”上运行不同版本的软件。
应用程序必须支持多租户:
多租户可以分为几个不同的类别(如列表下方的图所示):
1.1,云中的简单虚拟化,其中只对硬件进行共享。
1.2,共享应用程序,对每个租户使用不同的数据库。
1.3,共享应用程序和数据库(效率最高,真正的多租户)。
1.分层设计 Saas系统分层大概是:
Saas系统分层 Saas系统分层:租户识别>应用层>数据访问层>缓存层>数据库
业务代码都是写在应用层。
租户识别可以用spring拦截器实现,然后使用ThreadLocal传递给后端
数据库和缓存层对应用层应该是透明的。程序员在写代码的时候,只关心业务逻辑,不应该担心多租户的问题。
2.数据隔离要透明 saas系统说起来很简单,任何系统似乎加个tenant_id(租户id)就变成saas系统了。比如原来的用户登录是:
select username,password from users where email='abc@qq.com' 改成
select username,password from users where email='abc@qq.com' and tenant_id =1; 对于复杂业务的saas系统,这样做法非常危险,而且开发效率很低。你想想如果那个程序员写sql时候忘了加 “ and tenant_id =1” . 结果不堪设想。
比较好做法是在数据库访问层对SQL进行改写。
TenantContext.exec("select username,password from users where email='abc@qq.com' "); 在连接池根据TenatnContext改写Sql. 这样做好处是,一来程序猿最多把系统搞down了,也不至于信息串了互相泄露。二来将来做分表分库也很方便,上层应用不用修改。
3. 租户识别方案 比较好做法是通过url识别租户。系统是给租户生成一个随机的三级域名,比如 abc.crm.baidu.com. 如果客户想使用自己的域名,可以在cname到我们生成的三级域名,并在管理系统里面做绑定。
第十四届蓝桥杯C++B组个人题解——无FJ 本文章仅是个人题解,不能保证全对,但思路大抵就是那么个思路。今年的题感觉要比去年难了些,F想不到很好的判环方法,最后一题都不知道再说什么,图论苦手是这样的,不过其它倒是挺对我胃口。
但说实话线下在学校机房比,超级不适应啊!
(更新:编程题库 - C语言网 (dotcpp.com)这里有民间数据了,可以去测一测)
A、日期统计 问题描述 小蓝现在有一个长度为 100 的数组,数组中的每个元素的值都在 0 到 9 的范围之内。数组中的元素从左至右如下所示:
5 6 8 6 9 1 6 1 2 4 9 1 9 8 2 3 6 4 7 7 5 9 5 0 3 8 7 5 8 1 5 8 6 1 8 3 0 3 7 9 2 7 0 5 8 8 5 7 0 9 9 1 9 4 4 6 8 6 3 3 8 5 1 6 3 4 6 7 0 7 8 2 7 6 8 9 5 6 5 6 1 4 0 1 0 0 9 4 8 0 9 1 2 8 5 0 2 5 3 3
多年前在学习计算机原理的时候曾经问过老师一个问题,就是我们编写的程序是怎么在计算机中运行起来的,希望有个完整的思路,现在通过网络收集和整理了这个问题,相当于对这个问题又做了一个认识,有了新的体会。以stm32单片机和keil编译环境为例,说明了程序是如何在单片机中执行运行的。分3个部分来进行说明:1、STM32单片机到底是如何软硬件结合的,分析单片机程序如何编译,运行;2、代码是如何控制硬件的;3、STM32中GPIO工作原理详解及施密特触发器。
一、STM32单片机到底是如何软硬件结合的,分析单片机程序如何编译,运行
1、软硬件结合
初学者,通常有一个困惑,就是为什么软件能控制硬件?就像当年的51,为什么只要写P1=0X55,就可以在IO口输出高低电平?要理清这个问题,先要认识一个概念:地址空间。什么是地址空间呢?所谓的地址空间,就是PC指针的寻址范围,因此也叫寻址空间。大家应该都知道,我们的电脑有32位系统和64位系统之分,为什么呢?因为32位系统,PC指针就是一个32位的二进制数,也就是0xffffffff,范围只有4G寻址空间。现在内存越来越大,4G根本不够,所以需要扩展,为了能访问超出4G范围的内存,就有了64位系统。STM32是多少位的?是32位的,因此PC指针也是32位,寻址空间也就是4G。我们来看看STM32的寻址空间是怎么样的。在数据手册《STM32F407_数据手册.pdf》中有一个图,这个图,就是STM32的寻址空间分配。所有的芯片,都会有这个图,名字基本上都是叫Memory map,用一个新芯片,就先看这个图。
最左边,8个block,每个block 512M,总共就是4G,也就是芯片的寻址空间。block 0 里面有一段叫做FLASH,也就是内部FLASH,我们的程序就是下载到这个地方,起始地址是0X800 0000,大家注意,这个只有1M空间。现在STM32已经有2M flash的芯片了,超出1M的FLASH放在哪里呢?请自行查看对应的芯片手册。在block 1 内,有两段SRAM,总共128K,这个空间,也就是我们前面说的内存,存放程序使用的变量。如果需要,也可以把程序放到SRAM中运行。407不是有196K吗?其实407有196K内存,但是有64k并不是普通的SRAM,而是放在block 0 内的CCM。这两段区域不连续,而且,CCM只能内核使用,外设不能使用,例如DMA就不能用CCM内存,否则就死机。block 2,是Peripherals,也就是外设空间。我们看右边,主要就是APB1/APB2、AHB1/AHB2,什么东西呢?回头再说。block 3、block4、block5,是FSMC的空间,FSMC可以外扩SRAM,NAND FALSH,LCD等外设。好的,我们分析了寻址空间,我们回过头看看,软件是如何控制硬件的。在IO口输出的例程中,我们配置IO口是调用库函数,我们看看库函数是怎么做的。例如:GPIO_SetBits(GPIOG, GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2| GPIO_Pin_3);这个函数其实就是对一个变量赋值,对GPIOx这个结构体的成员BSRRL赋值。
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{
/* Check the parameters */
assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
assert_param(IS_GPIO_PIN(GPIO_Pin));
GPIOx->BSRRL = GPIO_Pin;
}
assert_param:这个是断言,用于判断输入参数是否符合要求GPIOx是一个输入参数,是一个GPIO_TypeDef结构体指针,所以,要用->获取其成员GPIOx是我们传入的参数GPIOG,具体是啥?在stm32f4xx.h中有定义。
#define GPIOG ((GPIO_TypeDef *) GPIOG_BASE)
GPIOG_BASE同样在文件中有定义,如下:
#define GPIOG_BASE (AHB1PERIPH_BASE + 0x1800)
AHB1PERIPH_BASE,AHB1地址,有点眉目了吧?在进一步看看
/*!< Peripheral memory map */
#define APB1PERIPH_BASE PERIPH_BASE
#define APB2PERIPH_BASE (PERIPH_BASE + 0x00010000)
#define AHB1PERIPH_BASE (PERIPH_BASE + 0x00020000)
C++ b 组: A 题: 答案:235
思路:
暴力搜索题,但是要注意剪枝。 2100 爆搜一年都跑不完。
首先年 2023 是确定的,考虑用 a 、 b 、 c 、 d 分别枚举 2、0、2、3。 a 不是 2 就不继续枚举 b , b 不是 0 就不继续枚举 c , d 同理。消去指数级别的复杂度。
用 e 、 f 分别枚举月的十位与个位, e 为 0 时 f 不能取 0, e 为 1 时 f 2 。
用 g 、 h 分别枚举日的十位与个位,注意 g 为 0 时 f 不能取 0,其他时候不用特判,因为循环最后一层不会造成时间复杂度的变化。
然后就可以打出一个月份对应的日期表,注意 2023 年为平年。之后检查一下日期是否合法,如合法就可以把日期从数字拼接成字符串,使用 unordered_set 维护日期是否出现,常数会更好看一点。(因为这些数字范围都很紧凑)
效果展示 分析:
根据需要实现的效果图,我们可以进行分析,这是由两条折线组成的图表,且现价图的折线拥有区域填充的透明效果。
因此,我们需要制作两个折线图(现价图,均价图)进行图表叠加,并且利用 areaStyle 属性来制作区域填充的透明效果。
绘制折线图 话不多说,我们开始行动!但在此之前,我们可以去参考一下官方的一些示例,并进行分析。Echarts官方示例
官网示例 先是普通的折线图:
option = { xAxis: { type: 'category', data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] }, yAxis: { type: 'value' }, series: [ { data: [150, 230, 224, 218, 135, 147, 260], type: 'line' } ] }; option = { xAxis: { type: 'category', data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] }, yAxis: { type: 'value' }, series: [ { data: [820, 932, 901, 934, 1290, 1330, 1320], type: 'line', smooth: true } ] }; 而在普通的折线图的基础上,在 series 的type为line的y轴的数据里增加了 smooth ,开启了折线的平滑显示,并且接下来我们绘制折线图时也会用上这个属性。
Electron Electron 是一个使用 JavaScript、HTML 和 CSS 构建桌面应用程序的框架
安装 在使用 Electron 进行开发之前,需要安装Node.js,可以在终端输入以下命令输出了 Node.js 和 npm 的版本信息:
node -v npm -v 没有安装的话,可以点击此处的安装教程
接下来就是安装 Electron :
我们可以两种安装方式
全局安装
npm install electron -g 【加g是全局安装,自动添加到环境变量中】
可以通过输入以下命令,弹出类似浏览器的程序,来验证安装成功:
electron 如果遇到 npm 安装Electron 很慢或者出错可以使用淘宝镜像安装:
npm install -g electron --registry=https://registry.npm.taobao.org 或者先安装 cnpm ,再使用 cnpm 安装Electron
如果以上都不行的话,我们就只能去采用下载合适自己的 electron.zip
https://registry.npmmirror.com/binary.html?path=electron/
文章这里下载的是 electron-v22.0.0-win32-x64.zip
我们把下载的zip包放到我们全局安装的目录的electron文件夹下面:
这里我们需要修改一下 install.js 文件:
注释该块代码
增加语句
extractFile('electron-v22.0.0-win32-x64.zip'); 我们可以看到 extractFile 方法传递的参数就是一个zip包的路径
修改完 install.js 文件后,我们终端打开全局安装的目录下的electron目录,执行 node install.js 命令,生成出 dist 文件夹:
一、前期准备 在开发中经常会遇到需要进行对一些数据进行动态导出PDF文件,然后让用户自己选择是否需要打印出来,这篇文章我们来用个相对来说比较简单的方式来实现PDF动态导出; 导入依赖 SpringBoot版本2.0.5.RELEASE <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-freemarker</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.20</version> </dependency> <dependency> <groupId>com.itextpdf</groupId> <artifactId>html2pdf</artifactId> <version>4.0.3</version> </dependency> 二、代码实现) 先准备一个html,这个html是一个模板,是将我们需要动态展示的数据插入到每个占位符进来,如下: 先准备一个html,这个html是一个模板,是将我们需要动态展示的数据插入到每个占位符进来,如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"/> <title>Title</title> <style> body{ font-size: 15px; } .title{ text-align: center; } .content{ margin:0 auto; width: 400px; } .content .text{ text-indent: 2em; } .content .datetime{ text-align: right; } </style> </head> <body> <div> <div class="
常见的数据框提取
以iris数据为例
iris head(iris) #———————————————————————————————————————————————————————————————————————— #首先提取行和列 #以提Sepal.Length这一列 x <- iris[,1] #这是数值型 x <- as.data.frame(iris[,1]) #这样提出来是数据库的格式 #提Petal.Length Petal.Width,Petal.Width这两列,这样提出来是数据库的格式 y <- iris[,c(2:4)] #提Petal.Length,Species这两列 yy <- iris[,c(2,5)] #提第一行 iris[1,] #提5-10行,这样提出来是数据库的格式 xx <- iris[c(5:10),] #假如想提取某一行某一列中的一个 head(iris) #第二行第三列 iris[2,3] #第三行第五列 iris[3,5] #__________________________________________________________________ #选择性的提取---筛选 #比如提取Sepal.Width<3的数据 #第一种方式---一定要注意这个逗号 iris[which(iris$Sepal.Width<3),] #比如提取Sepal.Width==3的数据,切记R语言里面等于号为== iris[which(iris$Sepal.Width==3),] #如果我们想提取Sepal.Width==3或Species为versicolor的数据时用|连接 #记住这里Species这一列为字符型,一定要带引号 iris[which((iris$Sepal.Width==3)|(iris$Species == "versicolor")),]
本篇更新蓝桥杯省赛真题的后5道。
6.试题 F: 公因数匹配
时间限制: 10.0s 内存限制: 512.0MB 本题总分:15 分
【问题描述】 给定 n 个正整数 Ai,请找出两个数 i, j 使得 i < j 且 Ai 和 Aj 存在大于 1 的 公因数。 如果存在多组 i, j,请输出 i 最小的那组。如果仍然存在多组 i, j,请输出 i 最小的所有方案中 j 最小的那组。
【输入格式】 输入的第一行包含一个整数 n。 第二行包含 n 个整数分别表示 A1 A2 · · · An,相邻整数之间使用一个空格 分隔。
【输出格式】 输出一行包含两个整数分别表示题目要求的 i, j,用一个空格分隔。
【样例输入】 5 5 3 2 6 9
【样例输出】 2 4
【评测用例规模与约定】 对于 40% 的评测用例,n ≤ 5000 ; 对于所有评测用例,1 ≤ n ≤ 105,1 ≤ Ai ≤ 106 。
如果出现了下面图片中的问题,那可能是你没有引入相关依赖。
在 pom.xml 文件中添加如下依赖项:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency> 解决问题!!!!
初学Vue的时候跟着尚硅谷学习,出现了将productionTip置为false,网页控制台仍然出现了提示。
解决方法:去引入的Vue.js文件里面修改 productionTip: true 改为 false即可,如果引入的Vue.js里面是这么一句话 productionTip: “development” !== ‘production’,那我们也可以直接注释掉这一句,加上 productionTip=false,也可以解决这个问题。
阻止vue在启动时生成生产提示,网页控制台便不再显示。
1.Spring介绍 Spring其实就是一种开源框架,指的是Spring Framework,具有良好的生态,这也是Spring经久不衰的原因
用一句话概括,Spring就是一个集成了众多工具和方法的IOC容器
2.IOC容器 什么是IOC容器呢?
IOC的中文翻译过来就是控制反转,IOC容器其实就是控制反转容器
那什么是控制反转呢?
这个词听起来好像很高大上,其实通俗来理解就是,本来我们写java类的时候,创建对象,是通过自己去new的,但是当我们控制反转之后,我们就把对象的创建和一系列读取等操作交给了Spring,Spring就帮我们完成这些操作 ,这样我们需要做的操作就两个,1.把对象存到Spring中去,2.从Spring中去取对象
3.控制反转(IOC)的好处 我们以一部手机为例,就简易的手机,假如我们需要的有CPU,线路板,电阻来组成
这样我们传统的代码开发,就要先new一个手机,但是我们想要完成一部手机,要有一个CPU,所以再调用CPU类组装CPU,但是CPU想要组装,就必须要先组装线路板,但是线路板想要组装,就必须依靠电阻,这样我们的程序就非常耦合,我们通过一张图,更加直观的来理解
可以看到,我们想要造一部手机,耦合度非常的高,如果我们的电阻这一栏,我们加一个电容属性,那么,我们上面的线路板中也需要把调用电阻的那一块进行修改,从而导致我们整个的代码都需要进行一个更新,这个时候,IOC的优势便体现出来了
我们只需要进行一个改进,就可以大大降低耦合度,我们可以在main函数中,将每一个对象都进行创建,然后我们可以在每一个类中,创建一个属性,用来接收下一级的对象,这样在我们进行对底层修改的时候,只需要对修改的代码进行修改和main函数中的参数进行修改即可,大大降低了带啊吗的耦合,我们也用一个图来理解
可以明显的看出来IOC容器的优势 4.DI DI是一种设计模式,就是依赖注入,在我们想要运行A时,A需要依赖数据库来完成,这时候我们不会像传统开发一样,去搭建DBUtile或者去newDBUtile的对象,而是将依赖关系配置到xml文件中去,由Spring去管理,这样就可以动态的去依赖关系注入到对象之中,从而实现解耦合
2.Spring使用 这里就不去教大家如何创建Spring项目了,我们如何使用Spring呢?,需要在xml文件中去添加Spring的依赖即可
这里我们具体讲一下如何存取对象
1.较为古老的用法 1.1添加启动类 我们需要在java包中进行创建一个启动类,只要包含main方法即可,类似这样
public class App { public static void main(String[] args) { } } 1.2创建Bean 什么是Bean呢?
Bean对象就是java中的普通对象,这里其实本质是一个类的写法
类似下面
public class User { public String Hi(String s){ return "Hi " + s; } } 1.3存储Bean 创建好Bean之后,我们需要将其注册到Spring中去
这里我们使用最原始的方法
首先创建一个xml文件,在resource目录下,如下
这里面先将Spring的固定文件放进去,这个是Spring固定的配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <beans> <bean id = "
目录 前言
一、点亮一个LED
二、LED闪烁
三、LED流水灯
四、独立按键控制LED
独立按键控制LED亮灭
独立按键控制LED状态
独立按键控制LED以二进制形式显示
独立按键控制LED状态循环移位
总结
前言 嵌入式学习的入门就是点亮LED灯,就好比学习编程语言敲 “Hello world” 一样
一、点亮一个LED 8051系列单片机上电默认都是高电平,而开发板上的LED都是共阳极的,所以只有输出低电平才会产生电势差,LED才会被点亮。那么为什么要用共阳极呢?这是因为51单片机IO默认是准双向口模式,它的驱动能力很弱,弱到不足以点亮LED灯,只能用来输出高低电平信号,所以共阳极只需要将端口电位拉低就可以了。
#include <REGX52.H> sbit LED = P2^0; //将P2_0引脚定义为LED void main() { LED=0; while(1){} } IO口的配置可以采用字节寻址和位寻址两种方法,也就是说上述代码还可以这样写:
#include <REGX52.H> void main() { P2=0xFE; //1111 1110 while(1){} } 将程序烧录进单片机,这样一颗LED就被点亮了!
二、LED闪烁 将LED循环往复的置高置低并在期间加入一定的延时,就形成了闪烁的效果:
#include <REGX52.H> #include <INTRINS.H> void Delay500ms() //@12.000MHz 这里的延时就是让程序在循环里空跑消耗时间 { unsigned char i, j, k; _nop_(); i = 4; j = 205; k = 187; do { do { while (--k); } while (--j); } while (--i); } void main() { while(1) { P2=0xFE; //1111 1110 Delay500ms(); P2=0xFF; //1111 1111 Delay500ms(); } } 三、LED流水灯 流水灯只需要循环点亮每一个LED并加入延时即可
目录
死锁
死锁的情况
构成死锁的原因
解决方案
死锁 死锁就是同时有多个线程被阻塞,他们中的一个或者全部都在等待某个资源的释放,这样就导致线程被无限期阻塞,整个进程也不会结束。
接下来我们看个例子:
可以看出线程A和线程B都同时持有不同的资源,此时就不会造成阻塞,也不会行程死锁。
如果说此时线程A想要线程B的资源,线程B想要线程A的资源,就会造成下列情况。
此时线程A如果想要线程B的资源,那么就需要等待线程B进行资源的释放,同理,线程B想要线程A的资源,也要等待线程A进行资源的释放。
线程A在尝试获取资源1的时候,此时资源1是被线程B 持有的,线程1就会进行阻塞,线程B在尝试获取资源2的时候,此时资源2是被线程A持有的,所有线程B也会进行阻塞等待。
这个情况就是线程A阻塞等待线程B进行资源释放,但是线程B也在等待线程A进行资源释放,此时就造成了死锁。
我们可以举个简单的例子:
有个老铁在和他的女朋友吃饺子的时候,比如饺子的蘸酱有酱油和醋,此时老铁拿起来醋,老铁女朋友拿起了酱油,此时他们同时有想要对方的蘸酱,老铁给他女朋友说,你把酱油给我,等我把醋和酱油都弄好之后,我在给你,老铁的女朋友也说,你先把醋给我,等我把醋和酱油都弄好之后,我再给你。由于老铁的脾气很犟,于是老铁也就不管了,说那就我们这样等着吧,此时老铁女朋友也脾气犟起来了,说那好,那就我们一直这样等着吧。
于是上述的情况我们可以理解为死锁了。
接下来我们通过代码再进行理解:
public class test { public static void main(String[] args) { Object object1 = new Object(); Object object2 = new Object(); Thread t1 = new Thread(()->{ synchronized (object1) { System.out.println("hello1"); synchronized (object2) { System.out.println("hello2"); } } }); Thread t2 = new Thread(()->{ synchronized (object2) { System.out.println("hello2"); synchronized (object1) { System.out.println("hello1"); } } }); t1.
计算n的阶乘
#include<stdio.h> int main() { int i=0; int n; int ret = 1; //ret用来存储阶 scanf_s("%d\n", &n); for (i= 1; i <=n; i++) { ret = ret * i; } printf(" ret=%d ", ret); return 0; } 计算1!+2!+3!+...+10!
#include<stdio.h> int main() { int i = 0; int n=0; int ret = 1; int sum=0; for (n = 1; n <= 6; n++) { ret = 1; for (i = 1; i <= n; i++) { ret = ret * i; } sum = sum + ret; } printf("
依赖 <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.3</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.22</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--thymleaf处理localdatetime, "${#temporals.format(teacher.register, 'yyyy年MM月dd日 HH时mm分ss秒')}"--> <dependency> <groupId>org.thymeleaf.extras</groupId> <artifactId>thymeleaf-extras-java8time</artifactId> <version>3.0.4.RELEASE</version> </dependency> <!-- 热部署 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <fork>true</fork> <!--dev-tools相关--> <skip>true</skip> <!--否则模块打包时候会提示 unable to find main class--> <addResources>true</addResources> </configuration> </plugin> </plugins> </build> 配置热部署 热部署据说比较吃内存,springboot+thymleaf这种前后端交互困难的一般会配置热部署,前后端vue这种项目一般不会配置热部署
java三级联动返回树状省市区三级json,前端el-tree显示 java实现 前端使用element-plus的el-tree组件,返回的json每一级要统一名称
@RequestMapping("/define") public class SomeController { @Autowired ProvinceRepository provinceRepository; @Autowired CityRepository cityRepository; @Autowired AreaRepository areaRepository; @RequestMapping("/returnTree") public List<Map<String, Object>> returnTree() { // 获取第一层 List<Province> maps1 = provinceRepository.getAllProvince(); List<Map<String, Object>> listMap = new ArrayList<>(); System.out.println(maps1); for (Province item1 : maps1) { Map<String,Object> map1 = new HashMap<>(); String pid = item1.getPid(); System.out.println(pid); map1.put("id", pid); map1.put("name", item1.getProvinceName()); // 获取第二层 List<City> maps2 = cityRepository.getByPid(pid); System.out.println(maps2.size()); List<Map<String,Object>> listMap2 = new ArrayList<>(); for (City item2 : maps2) { Map<String,Object> map2 = new HashMap<>(); String cid = item2.
Precision (精确率) 和 Recall (召回率) 是机器学习中的两个重要指标,用于评估分类模型的性能。精确率指预测为正的样本中真正为正的样本占比,召回率指真正为正的样本中被正确地预测为正的样本占比。以二分类问题为例,精确率和召回率的计算公式如下:
Precision = TP/(TP+FP)
Recall = TP/(TP+FN)
其中,TP 表示真正为正的样本预测为正,FP 表示真正为负的样本预测为正,FN 表示真正为正的样本预测为负。通常情况下,精确率和召回率是相互矛盾的,提高精确率会降低召回率,反之亦然。因此,常常使用 F1-Score 来综合评价模型的性能,其计算公式如下:
F1-Score = (2 * Precision * Recall) / (Precision + Recall)
【题目链接】 ybt 1392:繁忙的都市(city)
洛谷 P2330 [SCOI2005]繁忙的都市
【题目考点】 1. 图论 最小生成树 【解题思路】 将题目叙述转为图论概念,交叉路口为顶点,道路为边,道路是双向的,且所有交叉路口都直接或间接连接起来,说明这是无向连通图。每条道路的分值,就是边的权值。政府要改造一些道路,就是选一些边。
三个要求的概念分别为:
选择的边构成的图应该是连通图,且应该包含原图所有顶点。选择的边尽可能少。
边最少时,该图就成了无根树。边数为顶点数减1。
综合以上两点,选择的边及顶点构成的图就是原图的生成树。生成树有多种方案,选择其中权值最大的边最小的那一种生成树方案,即瓶颈生成树。 树上最大边权值在图的所有生成树中最小的生成树,叫做瓶颈生成树。
最小生成树一定是瓶颈生成树,但瓶颈生成树未必是最小生成树。(其证明见百度百科)
题目要求的就是瓶颈生成树,我们可以直接求出最小生成树,它一定是瓶颈生成树。
该题顶点数<=300,边数<=100000,使用Prim,Prim堆优化,Kruskal都可以完成该题。
【题解代码】 解法1:朴素Prim算法 #include<bits/stdc++.h> using namespace std; #define N 305 struct Edge { int v, w; Edge(){} Edge(int a, int b):v(a),w(b){}; }; vector<Edge> edge[N]; bool vis[N]; int n, m, mx, dis[N]; void prim() { memset(dis, 0x3f, sizeof(dis)); dis[1] = 0; for(int k = 1; k <= n; ++k) { int u = 0; for(int i = 1; i <= n; ++i) if(vis[i] == false && (u == 0 || dis[i] < dis[u])) u = i; vis[u] = true; mx = max(mx, dis[u]); for(Edge e : edge[u]) { int v = e.
【题目链接】 ybt 1391:局域网(net)
【题目考点】 1. 图论:最小生成树 记图中顶点数为V,边数为E
Prim算法
复杂度: O ( V 2 ) O(V^2) O(V2)Prim算法堆优化
复杂度: O ( E l o g E ) O(E log E) O(ElogE)Kruskal算法
复杂度: O ( E l o g E ) O(E log E) O(ElogE) 【解题思路】 每台电脑是一个顶点,两台电脑间的网线是边。两台电脑间连接的通畅程度 f ( i , j ) f(i,j) f(i,j)就是两个顶点之间边的权值。
一个局域网中任何两台电脑都可以连通,也就是说图中任意两顶点之间都有路径。
要使n个顶点的图中任意两顶点之间都有路径,而且没有回路,那么就需要不断去掉边,剩下的图是原图的生成树。
要使得去掉边的权值加和最大,那么就是要求剩下的生成树的所有边的权值加和最小。
因此该题需要求原图的最小生成树,求出最小生成树的边权值加和,用原图所有边的权值加和减去最小生成树的边权值加和,即为去掉的边权值加和的最大值。
【题解代码】 解法1:Prim算法 #include <bits/stdc++.h> using namespace std; #define N 105 struct Edge { int v, w; Edge(){} Edge(int a, int b):v(a),w(b){} }; vector<Edge> edge[N]; bool vis[N];//vis[i]:顶点i是否已被选择 int dis[N];//dis[i]:顶点i距离被选择顶点的最小距离 int n, m, sumTree, sumAll;//sumAll:所有边的权值加和 sumTree:最小生成树的权值加和 void prim() { memset(dis, 0x3f, sizeof(dis)); dis[1] = 0;//先选择顶点1 for(int k = 1; k <= n; ++k)//循环n次,每次取出一个顶点 { int u = 0;//dis中最小值的下标 for(int i = 1; i <= n; ++i) if(vis[i] == false && (u == 0 || dis[i] < dis[u])) u = i; sumTree += dis[u]; vis[u] = true; for(Edge e : edge[u]) { int v = e.
【题目链接】 ybt 1348:【例4-9】城市公交网建设问题
输出时要求对于每条边,小的顶点写在前,大的顶点写在后。
多条边之间,第一个顶点小的排在前面。如果第一个顶点相同,则第二个顶点小的排在前面。
【题目考点】 1. 图论:最小生成树 Prim算法Prim算法堆优化Kruskal算法 【解题思路】 该题难点是要保存最小生成树的所有边,对于不同的求最小生成树的算法,有不同的方法来完成。
解法1:Prim算法 Prim算法是加点法。每次在未选择的顶点中选择到已选择顶点边权值最小的顶点,将其加入最小生成树中。设选择的新顶点为u,这个新的顶点u与最小生成树中已选择的顶点from[u]相连。from[u]可以理解为:u顶点是从最小生成树中的哪个顶点连出来的。
因此(u, from[u])就是最小生成树中的一条边。
为了输出时有序,可以把表示最小生成树中边的所有数对都加到一个set中,即可得到有序序列。
关于set的比较规则:
set默认使用less<pair<int, int>>比较规则,仿函数类模板less的实现大体为:
template<class T> struct Less { bool operator () (T a, T b) { return a < b; } } 此时T类型为pair<int, int>,那么代码中的a < b就是两个pair<int, int>对象之间的比较。
而pair类型已经重载了g各种比较运算符,比较规则是先比较第一个元素,如果第一个元素相等,再比较第二个元素。其大体实现为:
template<class T1, class T2> struct pair { T1 first; T2 second; bool operator < (pair<T1, T2> b) { if(first == b.first) return second < b.second; else return first < b.
【题目链接】 ybt 1349:【例4-10】最优布线问题
ybt 1350:【例4-11】最短网络(agrinet)
【题目考点】 1. 图论:最小生成树 记图中顶点数为V,边数为E
Prim算法
复杂度: O ( V 2 ) O(V^2) O(V2)Prim算法堆优化
复杂度: O ( E l o g E ) O(E log E) O(ElogE)Kruskal算法
复杂度: O ( E l o g E ) O(E log E) O(ElogE) 【解题思路】 最小生成树模板题,求最小生成树所有边权加和。
该题输入的是邻接矩阵,因此使用邻接矩阵解决该问题。当然也可以保存为邻接表。
【题解代码】 解法1:Prim算法 写法1:使用邻接矩阵 #include<bits/stdc++.h> using namespace std; #define N 105 int n, m, sum, dis[N], edge[N][N];//sum:最小生成树边权加和 edge:邻接矩阵 dis[i]:顶点i到已经确定的顶点中的最小距离 bool vis[N];//vis[i]:顶点i是否已经被确定 void prim() { memset(dis, 0x3f, sizeof(dis)); dis[1] = 0; for(int k = 1; k <= n; ++k) { int u = 0; for(int i = 1; i <= n; ++i) if(vis[i] == false && (u == 0 || dis[i] < dis[u])) u = i; vis[u] = true; sum += dis[u];//顶点u到已经确定的顶点的最短的边的长度是dis[u],把这条边加入最小生成树,最小生成树的边权值增加dis[u] for(int v = 1; v <= n; ++v) if(edge[u][v] && vis[v] == false && dis[v] > edge[u][v]) dis[v] = edge[u][v]; } } int main() { cin >> n; for(int i = 1; i <= n; ++i) for(int j = 1; j <= n; ++j) cin >> edge[i][j]; prim(); cout << sum; return 0; } 写法2:使用邻接表 #include<bits/stdc++.
1 k8s组件介绍 1.1 kube-apiserver: Kubernetes API server 为 api 对象验证并配置数据,包括 pods、 services、replicationcontrollers和其它 api 对象,API Server 提供 REST 操作,并为集群的共享状态提供前端访问⼊⼝,kubernetes中的所有其他组件都通过该前端进⾏交互。
https://kubernetes.io/zh/docs/reference/command-line-tools-reference/kube-apiserver/
1.2 kube-scheduler Kubernetes的pod调度器,负责将Pods指派到合法的节点上,kube-scheduler调度器基于约束和可⽤资源为调度队列中每个Pod确定其可合法放置的节点,kube-scheduler⼀个拥有丰富策略、能够感知拓扑变化、⽀持特定负载的功能组件,kube-scheduler需要考虑独⽴的和集体的资源需求、服务质量需求、硬件/软件/策略限制、亲和与反亲和规范等需求。
https://kubernetes.io/zh/docs/reference/command-line-tools-reference/kube-scheduler/
1.3 kube-controller-manager Controller Manager作为集群内部的管理控制中⼼,负责集群内的Node、
Pod副本、服务端点(Endpoint)、命名空间(Namespace)、服务账号(ServiceAccount)、资源定额(ResourceQuota)的管理,当某个Node意外宕机时,Controller Manager会及时发现并执⾏⾃动化修复流程,确保集群中的pod副本始终处于预期的⼯作状态。
https://kubernetes.io/zh/docs/reference/command-line-tools-reference/kube-controller-manager/
1.4 kube-proxy Kubernetes ⽹络代理运⾏在 node 上,它反映了 node 上 Kubernetes API 中定义的服务,并可以通过⼀组后端进⾏简单的 TCP、UDP 和 SCTP 流转发或者在⼀组后端进⾏循环 TCP、UDP 和SCTP 转发,⽤户必须使⽤ apiserver API 创建⼀个服务来配置代理,其实就是kube-proxy通过在主机上维护⽹络规则并执⾏连接转发来实现Kubernetes服务访问。
https://kubernetes.io/zh/docs/reference/command-line-tools-reference/kube-proxy/
1.5 kubelet 是运⾏在每个worker节点的代理组件,它会监视已分配给节点的pod,具体功能如下:
向master汇报node节点的状态信息
接受指令并在Pod中创建 docker容器
准备Pod所需的数据卷
返回pod的运⾏状态
在node节点执⾏容器健康检查
https://kubernetes.io/zh/docs/reference/command-line-tools-reference/kubelet/
1.6 etcd: etcd 是CoreOS公司开发⽬前是Kubernetes默认使⽤的key-value数据存储系统,⽤于保存所有集群数据,⽀持分布式集群功能,⽣产环境使⽤时需要为etcd数据提供定期备份机制。
#核⼼组件: apiserver:提供了资源操作的唯⼀⼊⼝,并提供认证、授权、访问控制、API注册和发现等机制
controller manager:负责维护集群的状态,⽐如故障检测、⾃动扩展、滚动更新等
目录
输入
借助Scanner
直接读
String类
Math类(数学、计算相关)
String类
Character类
Arrays类(数组处理)
Collections类(集合处理)
BigInteger构造器(大整数)
BigDecimal类(大浮点数)
四舍五入
输入 在写的时候尽量先用StringBuilder进行处理,再使用IO流一次性将内容写入,可以节约时间
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out)); bw.write("hello"); bw.flush(); 借助Scanner 文件读
Scanner scan = new Scanner(new FileInputStream("src//data.txt")); System.out.println(scan.nextLine()); 直接读 Scanner scan = new Scanner(System.in); String类 //和长度有关的方法 //返回类型 方法名 作用 int length() 得到一个字符串的字符个数(一个中文是一个字符,一个英文是一个字 //符,一个转义字符是一个字符) //和数组有关的方法 //返回类型 方法名 作用 byte[] getBytes() 将一个字符串转换成字节数组 char[] toCharArray() 将一个字符串转换成字符数组 String[] split(String) 将一个字符串按照指定内容劈开 //和判断有关的方法 //返回类型 方法名 作用 boolean equals(String) 判断两个字符串的内容是否一模一样 boolean equalsIgnoreCase(String) 忽略大小写的比较两个字符串的内容是否一模一样 boolean contains(String) 判断一个字符串里面是否包含指定的内容 boolean startsWith(String) 判断一个字符串是否以指定的内容开头 boolean endsWith(String) 判断一个字符串是否以指定的内容结尾 //和改变内容有关的方法 // 和改变内容有关的方法,都不会直接操作原本的字符串 // 而是将符合条件的字符串返回给我们,所以注意接收 //返回类型 方法名 作用 String toUpperCase() 将一个字符串全部转换成大写 String toLowerCase() 将一个字符串全部转换成小写 String replace(String,String) 将某个内容全部替换成指定内容 String replaceAll(String,String) 将某个内容全部替换成指定内容,支持正则 String repalceFirst(String,String) 将第一次出现的某个内容替换成指定的内容 String substring(int) 从指定下标开始一直截取到字符串的最后 String substring(int,int) 从下标x截取到下标y-1对应的元素 String trim() 去除一个字符串的前后空格 //和位置有关的方法 //返回类型 方法名 作用 char charAt(int) 得到指定下标位置对应的字符 int indexOf(String) 得到指定内容第一次出现的下标 int lastIndexOf(String) 得到指定内容最后一次出现的下标 Math类(数学、计算相关) //Java中已有的E、和PI的值 public static final double E = 2.
各位创作者大家好~
上周给大家讲解了百度搜索优质视频价值都包括了哪些方面。本周就来带大家了解下,一条优质的视频内容,必须满足的基础质量要求。
我们将从“视频标题、视频封面、画面质量、声音字幕”四个方面来帮助创作者提升视频内容质量。
一
视频标题的标准
1►
题文一致
标题需要归纳视频内容的主要信息,保证清晰明确,准确表达,且与实际的视频内容一致,避免使用“标题党”。
2►
标题字数
字数要适当。字数过短可能会导致无法表述清楚含义;字数太过重复冗长则会导致标题重复故意堆砌的情况。
3►
标题内容
标题内容无错别字,无语病;标题中无冗余符号;标题内容不能全部都是表情符号,如:乱码、火星文、数字等。
4►
标题健康
标题中不能出现联系方式、涉黄涉政等敏感信息。
二
视频封面的标准
1►
制作精良
要制作精良,设计优质,整体创意极佳,色彩搭配鲜明,无客观质量问题,画面感舒适。
正面示例:封面画面清晰,无质量问题
2►
图片清晰
封面高清,避免出现模糊,有黑边拉伸等情况。
负面示例:严重拉伸导致封面比例不对称
3►
封面内容
封面内容有价值,且与视频实际内容一致,封面中不能出现营销二维码、血腥暴力、主体内容缺失等情况。
负面示例:封面是无意义的几个字
三
视频画面主体
1►
视频清晰
视频画面高清,不影响用户观看体验。
seo网站
正面示例:画面高清,远景画面也能清晰查看
2►
画面稳定
视频画面稳定,播放顺畅,无抖动或者卡顿,无截断/拉伸/放大等现象,画面视角符合用户观看习惯,避免出现画面倒置影响观看体验的情况。
负面示例:画面颠倒90度或180度
3►
视频主体
画面主体没有黑边/马赛克/水印等遮挡视频画面主体。新闻类的特殊水印保护个人隐私安全的情况除外。
4►
画面内容
视频画面内容有主旨有价值,避免出现PPT拼接 、纯录屏视频、画面重复等情况。
(1)PPT拼接类视频:无任何解说的图片循环播放类的视频内容,本身内容没有任何价值,无法为用户带来任何信息增益。
(2)录屏视频:单纯录制屏幕内容,创作者无二次加工剪辑和额外解说,用户体验差。
四
声音字幕的标准
1►
声音维度
音质清晰,收音专业,无任何杂音,背景音优美,声音和画面同步。
如使用合成音,需确保合成音符合画面风格,不干扰用户听觉;避免出现音画不同步、无声、杂音、声音卡顿等问题。
2►
字幕维度
视频语言为普通话时,建议创作者们加上字幕,提升用户的体验。
如果视频语言为其他方言或者其他国家语言,则必须添加正确的字幕方便用户理解。
负面示例:字幕轻微叠加
本文实现三台机器的互联,一台server端,二台客户端,系统均为win,server win10, client 一台win7,一台win10,开源地址:可以下载windows ,mac ,linux ,android各种版本
WireGuard · GitHub
我们下使用的是wireguard-windows版本
windows版本这个既可以当服务端,也可以当客户端来用。首先我们配置一下服务端
配置如下:
服务段配置如下:
[Interface] PrivateKey = gKyDkJ17/xrc/8X7RQDiJpnVMQoCMGkXGbvonLntxXg= ListenPort = 55555 Address = 10.254.0.1/24 [Peer] PublicKey = +iYeKrWo54FskCVmix1rLOXWfnnO4FPnS0J2SNZcWkU= AllowedIPs = 10.254.0.2/32 [Peer] PublicKey = osB5o/qRjglwcnmCCHEAPk23G23l/XAWJoRCnjfnDAI= AllowedIPs = 10.254.0.3/32 Client2端如下
[Interface] PrivateKey = 4Gp4c+SNuZ2HAfD2qQ4JxyTF+OhW+WqE0A/mKLUZa3Y= Address = 10.254.0.2/32 DNS = 114.114.114.114 [Peer] PublicKey = wpCeLCeoTsV9Q3VG7vJnklNxf3qAt53S0vyMPSVaGwA= AllowedIPs = 0.0.0.0/0 Endpoint = 10.10.10.11:55555 PersistentKeepalive = 25 Client3端如下
[Interface] PrivateKey = qANM2T7N/675+zFyRucuOGBtRIegLoTJphdXoKiJAXo= Address = 10.
文章目录 xpath选择器应用xpath介绍xpath语法表达式逻辑语句 and or xpath函数xpath提取元素在scrapy项目中使用xpathlxml直接使用 xpath xpath选择器应用 xpath介绍 XPath(XML Path Language - XML路径语言),它是一种用来确定XML文档中某部分位置的语言。
Xpath以XML为基础,提供用户在数据结构树中寻找节点的能力,Xpath被很多开发者亲切的称为小型查询语言
xpath使用路径表达式在xml和html中进行导航,适用于xml和html所以在爬虫中作为解析库使用
xpath包含标准函数库
xpath是w3c的标准,脱离语言
xpath节点关系
父节点子节点兄弟节点祖先节点子孙节点 xpath语法 表达式 表达式描述nodename选取此节点的所有子节点/从当前节点选取直接子节点//从当前节点选取子孙节点.选取当前节点…选取当前节点的父节点@选取属性 示例:
表达式描述//article[@lang=‘cn’]选取所有名称为article,同时属性lang值为cn的节点,[]谓语article选取所有article元素的所有子节点/article选取根元素articlearticle/a选取所有属于article的子元素的a元素//div选取所有div子孙元素(不论出现在文档任何地方)article//div选取所有属于article元素的后代的div元素,不管它出现在article之下的任何位置//@class选取所有名为class的属性/article/div[1]选取属于article子元素的第一个div元素/article/div[last()]选取属于article子元素的最后一个div元素/article/div[last()-1]选取属于article子元素的倒数第二个div元素//div[@lang]选取所有拥有lang属性的div元素//div[@lang=‘eng’]选取所有lang属性为eng的div元素/div/*选取属于div元素的所有子节点//*选取所有元素//div[@*]选取所有带属性的div元素//div/a | //div/p选取所有div元素的a和p元素//span | //ul选取文档中的span和ul元素article/div/p| //span选取所有属于article元素的div元素的p元素 以及文档中所有的span元素 html基本结构
<html> <head> <title></title> </head> <body> <div id="1"></div> <div id="2"> <div id="3"></div> <div id="4"></div> </div> </body> </html> 对于节点关系
兄弟节点: div1和div2互为兄弟节点 父节点和子节点 div3和div4的父节点是div2,他们是div2的子节点,每个节点都有唯一的父节点 祖先节点和子孙节点 div都是body的子孙节点,body是div的祖先节点 一般静态页面的解析都是定位a标签获取href
逻辑语句 and or 选取多个属性可以用 and or |
div[@class="info_list password" and @node-type="password_box"] div[@class="info_list password" or @node-type="
charles代理工具使用 一、原理 Fiddler和Charles都是http协议调试代理工具,它能够记录客户端和服务器之间的所有 HTTP请求,可以针对特定的HTTP请求,分析请求数据、设置断点、调试web应用、修改请求的数据,甚至可以修改服务器返回的数据,功能非常强大。
原理:客户端和服务器之间建立一个代理服务器,监听客户端发出的请求和服务器返回的响应结果
二、Charles(Windows和MAC适用) 3.1 Charles安装配置(windows)
(1)进入→\share.kwps.info\share\测试部资料共享\Account&Drive&Store\测试工具\抓包工具\charles
PS:注意安装包的位数与电脑系统的位数一致
(2)安装完成后,打开Charles软件,点击proxy,选择proxy settings,port填写为8888,勾选port下的复选框:
(4)接着手机(安卓或者IOS)连接WiFi:kso,身份验证输入kingsoft.com账号,连接成功之后,连接电脑IP,电脑IP查询如图:
(5)安卓手机手机连接WiFi后,设置代理:
IOS端连接WiFi后,设置代理:
手机中的代理设置好之后,PC端的Charles会出现以下提示,点击allow:
(6)https抓包请求设置:
电脑安装证书,进入菜单栏,Help->SSL Proxying->Install Charles Root Certificate:
此时会有如下提示,点击“安装证书”,然后按照证书向导一步一步进行操作,即可安装成功。完成了证书的导入:
手机安装证书:help->ssl proxying->install charles root certificate on a mobile device or remote…
Charles也要做相应的配置,进入Proxy->SSL Proxying Settings:
在SSL Proxying Settings中勾选Enable SSL Proxying,并在Locations中输入要抓取的url的host和端口号(port可以为空或者填443):
Ps:*表示所有https的接口都抓取;如果只需要抓取部分域名接口,以下设置即可,对应域名需正确。
手机代理到电脑IP,charles端口,手机自带浏览器访问Charles Web Debugging Proxy • SSL CA Certificate installation 下载证书以及安装同fiddler类似
3.2 Charles安装配置(MAC)
(1)官网Download a Free Trial of Charles • Charles Web Debugging Proxy下载好MAC版安装包后,解压打开,将软件包拖入应用程序文件夹中,这时候一个原版的软件就可以让我们使用,只是有一个试用期
(2)在移动设备上截获网络请求,我们的移动设备必须和电脑在同一网段,在我们电脑的网络设置中查看IP地址,然后在移动设备上点击我们连接的电脑上的网络,在代理一栏中,选择手动,将我们刚才查看的ip地址填写在这里,并且设置一个端口号。
(3)在Charles中的Proxy setting中如下勾选并配置端口号
常见fortify漏洞与整改规则 背景规则清单Path ManiputationHeader ManipulationDynamic Code Evaluation:Unsafe JSON Derialization (动态代码之json反序列化) 背景 针对于代码质量管控来说,代码安全扫描作为其中极其重要的一环,是一项必不可少的且能够有效把控代码质量的操作。其中fortify,作为比较常用的扫描工具之一,尝尝被用来进行此环节的把关。
为了能够在代码编写过程中,自然的遵循代码安全规范,所以此处列举一些在代码安全扫描中较为常见的问题。
规则清单 Path Maniputation 规则描述
当满足以下两个条件时,就会产生 path manipulation 错误:
攻击者可以指定某一文件系统操作中所使用的路径。
攻击者可以通过指定特定资源来获取某种权限,而这种权限在一般情况下是不可能获得的。
例如,在某一程序中,攻击者可以获得特定的权限,以重写指定的文件或是在其控制的配置环境下运行程序。
在这种情况下,攻击者可以指定通过 AttachmentController.java 中第 155 行的 getParameter() 进入程序的值,这一数值可以通过 AttachmentController.java 中第 205 行的 File() 访问文件系统资源。
例 1: 下面的代码使用来自于 HTTP 请求的输入来创建一个文件名。程序员没有考虑到攻击者可能使用像“…/…/tomcat/conf/server.xml”一样的文件名,从而导致应用程序删除它自己的配置文件。
String rName = request.getParameter("reportName"); File rFile = new File("/usr/local/apfr/reports/" + rName); rFile.delete(); 解决方案
进行文件名校验
public static final Character[] INVALID_WINDOWS_SPECIFIC_CHARS = {'"', '`', '<', '>', '?', '|','\000'}; public static boolean validateStringFilenameUsingContains(String filename) { if (filename == null || filename.
一、单表操作 数据表的创建,创建名为UserData的数据表,包含以下属性(UserId、UserName、Password) 在对表操作前向主程序program.cs中插入方法的调用
using (var db = new Learn.Db.Db.FirstDbContext()) 数据的查询 var blogs = db.UserData .Where(b =>b.UserId == 1) .ToList(); Console.WriteLine(blogs.ToString()); blogs.ToString(); SQL查询 var data = db.UserData.FromSqlInterpolated($"SELECT * FROM LearnDb.dbo.UserData WHERE UserId = {1}").ToList(); var blogs = db.UserData.FromSqlInterpolated($"SELECT * FROM dbo.Blogs"); 添加数据 UserData UserData = new UserData(); UserData.UserId = 3; UserData.UserName = "ChenZhe"; UserData.Password = "111111"; db.UserData.Add(UserData); int count = db.SaveChanges(); 修改数据 var UserData = db.UserData.Single(UserData => UserData.UserName=="Make");//查询原数据 UserData.UserName ="WuTao";//修改原数据 await db.
问题:Windows Server 部分版本在系统默认安装时没有预装.net framwork 3.5,将会导致部分程序无法使用,例如SQL Server等软件,提示如下:
解决方案一:使用Windows update联网下载安装
打开服务,启用windows功能: 任务管理器-服务-打开服务-启动Windows Update
打开控制面板-程序和功能-启用或关闭Windows功能 勾选NET Framework 3.5,并点确认,安装完成即可 解决方案二:使用“添加角色和功能向导”指定备用源
注意:请先将安装文件上传入虚拟机中,注意对应系统版本的镜像文件,例如Windows Server 2012,则需要准备Windows Server 2012系统的安装镜像文件,不同版本之间不一定适用,有可能会导致安装失败
进入服务器管理器-仪表板-添加角色和功能 勾选.net framwork 3.5 配置备用源路径 填入第三步中的文件路径,点击安装 附:Windows server 2016 的.net framwork 3.5安装文件下载链接:
链接:https://pan.baidu.com/s/1XbRF9ULB5V_tL1FWLYmhOQ?pwd=CUHN
提取码:CUHN
1. 拿饼干
内存限制:128Mb
时间限制:1s
题目描述
小明今天外出野炊。他的母亲为他制作了M种他喜欢的饼干,共有N块。每块饼干都被标了编号,从1一直标到N。第i块饼干的重量是W[i]。饼干种类的编号是T[i],从1一直到M。小明想尽可能拿到最大总重量的饼干,但每种饼干只拿一块,而且他的背包的最大承重不能超过C。请帮助小明进行选择,别忘了要确保每种饼干至少拿一块。
输入
第一行包含三个整数N,M,C,之间用一个空格隔开。N代表饼干总数,M代表饼干种类数,C代表小明的背包的总重量。
第二行包含包含N个整数,W[1], W[2], …, W[i], …, W[N],之间用一个空格隔开,标明了每块饼干的重量。
第三行包含N个整数,T[1], T[2], …, T[i], …, T[N] ,之间用一个空格隔开,标明了每块饼干的类型。
输出
显示小明的背包拿足了饼干后的重量。
样例输入
复制
5 3 50 10 3 23 13 21 1 2 2 1 3 样例输出
复制
37 提示
约束条件 1 <= M <= N <= 500
1 <= C <= 10000
1 <= W[i] <= 50
1 <= T[i] <= M
输入样例 1 5 3 50
一、填空题 题解: #include<iostream> using namespace std; int sum; int main(){ for(int i=1;i<=2020;i++){ int t=i; while(t){ if(t%10==2){ sum++; break; } t/=10; } } cout<<sum; return 0; } 答案:563 题解: #include<iostream> #include<cmath> using namespace std; int sum; int add(int x){ if(x==1) return 0; for(int i=2;i<=sqrt(x);i++){ if(x%i==0) return 1; } return 0; } int main(){ for(int i=1;i<=2020;i++){ if(add(i)) sum++; } cout<<sum; return 0; } 答案:1713 题解: #include<iostream> #include<string> using namespace std; int dp[210],sum; string str; int main(){ cin>>str; for(int i=0;i<str.
最近为了测系统的兼容性,公司运维装了一台统信UOS arm-64的系统,在该操作系统上部署时,发现vim 编辑文件中文乱码,但是使用cat 查看文件,却是正常。
网上搜索了一番,终于解决问题。
查找vimrc 所在位置 [root@uos141 xxx]# whereis vimrc
vimrc: /etc/vimrc /usr/share/man/man5/vimrc.5.gz
不同的操作系统,可能所处的位置不一样,所以需要提前查找正确的vimrc文件所在位置。
修改vimrc 配置vim编码 [root@uos141 xxx]# vim /etc/vimrc
在文件末尾追加
set fileencodings=utf-8,ucs-bom,gb18030,gbk,gb2312,cp936 set termencoding=utf-8 set encoding=utf-8 释义:
encoding: 该配置用于设置缓冲的文本(你正在编辑的文件),寄存器,Vim 脚本文件等采用的编码。
fileencoding: 该配置用于设计vim写入文件时采用的编码类型。
termencoding: 该配置用于系统将文件内容输出到客户终端(Term)采用的编码类型。
工业相机选型 相机靶面尺寸详解靶面尺寸相机成像像素详解例子镜头选型 景深 (depth of field,DOF)调节景深的三种决定因素:影响原因 焦距 相机靶面尺寸详解 靶面尺寸(长或宽方向)=像素尺寸(长或宽方向)*分辨率(即像素数量,在长或宽方向)
靶面尺寸 CCD/CMOS图像传感器尺寸1/2、1/3、1/4实际是多大
1英寸——靶面尺寸为宽12.7mm高9.6mm,对角线16mm。
2/3英寸——靶面尺寸为宽8.8mm高6.6mm,对角线11mm。
1/2英寸——靶面尺寸为宽6.4mm高4.8mm,对角线8mm。
1/3英寸——靶面尺寸为宽4.8mm高3.6mm,对角线6mm。
1/4英寸——靶面尺寸为宽3.2mm*高2.4mm,对角线4mm。
单位是英寸,1英寸=2.54厘米。
1/2大小指的是对角线长1/2英寸,而不是边长。
CCD尺寸一般用英寸来表示,1/2就是二分之一英寸,是对角线尺寸。靶面尺寸就是CCD尺寸,数码传感器CCD的尺寸,一英寸换算成毫米是16mm,而不是通常的25.4mm。一般长宽比为4:3,1/2英寸对角线就是8mm,按4:3的比率,长和宽就是6.4X4.8。数码相机的传感器也一样可以这样换算。
1/2.5“ CCD长5.12mm宽3.84mm,对角线长度6.4mm。为什么数码相机CCD尺寸单位“英寸”不是常规意义上的1英寸=25.4mm,这里沿用了早起录像机真空管的外径尺寸1"(25.4mm),但除去玻璃管厚度,成像区实际只有16mm,即CCD规格中的1”=16mm。
大多数小尺寸CCD长宽比都是4:3
相机成像像素详解 靶面尺寸是传感器上的感光面积和像素量无关,因为同一大小的感光面积是可以解析出不同的像素量的。
像素量的多少决定的是分辨率的大小:
例如1920*1080意思就是横向有1920个像素点纵向有1080个像素点,总像素量既2073600,所以1080P的摄像机的最大像素是200W的。
当你设置720P画面的时候摄像机在这个靶面上仅解析出150W个像素,这时候720P就比1080P更适合拍摄高频帖或光线较差的环境下拍摄。
因为同一像素量下靶面尺寸越大每个像素点的感光面积就越大,同样同一靶面尺寸下像素量越少每个像素点的感光面积就越大。感光面积越大就越适合高速曝光,在同一拼贴率下记录的画面细节好(色深和动态)。
例子 举例来说,
海康:MV-CA003-50GM
传感器类型 CCD,全局快门
像元尺寸: 7.4μm×7.4μm
靶面尺寸: 1/3"
分辨率: 640×480
最大帧率: 200 fps
1/3英寸——靶面尺寸为宽4.8mm*高3.6mm,对角线6mm。这块传感器的长度约为4.8mm,宽度约为3.6mm。
传感器的长=像素尺寸的长*长方向像素数量=7.4um×640/1000=4.8mm。
eg2
以AVT GuppyPro F-503B为例,其拥有一块1/2.5’的500万像素的CMOS传感器。
这块传感器的长度约为5.7mm,宽度约为4.3mm。这个1/2.5’或5.7×4.3mm就是传感器的靶面尺寸,1/2.5’是指对角线的英寸长度,5.7×4.3mm是指矩形的长、宽毫米尺寸。
这块500万像素的传感器,其分辨率为2592*1944Pixel,即长方向有2592个有效像素,宽方向有1944个有效像素。则总像素和为5038848像素,即通常所说的500万像素。
传感器的像素尺寸(像元尺寸)为2.2um×2.2um,这个表示了该传感器上的每个像素单元的尺寸。这里关系就有,
传感器的长=像素尺寸的长*长方向像素数量=2.2um×2592=5702.4um。通常来讲,像素都是正方形的,因此计算一个方向基本上就可以了。
镜头选型 下面来看一个实际的镜头选型的例子:为视觉检测系统选择镜头,已知条件是:相机靶面为2/3”,像元尺寸为6.45um x6.45um ,C-mount,工作距离大于200mm,系统分辨率为0.05mm, 光源采用白色LED光源。
第一:因为采用白色光源,所以肯定是普通的可见光镜头;
第二:工作距离不变,分辨率固定,可以知道镜头是定焦镜头;
第三:相机的Nyquist频率为:1000/(2x6.45)=77.5,所选用的镜头分辨率应该不小于77.5lp/mm,这样才能保证系统分辨率最佳;
第四:工作焦距计算:镜头放大倍数为M=6.45/(0.05X1000)=0.13,焦距=工作距离*放大倍数/(放大倍数+1)=23mm,选择25mm焦距的镜头;
第五:根据以上说明,我们选择的镜头是:2/3”, C-mount,焦距为25mm,分辨率在80-100lp/mm的工业镜头。
景深 (depth of field,DOF) 景深是一个描述在空间中,可以清楚成像的距离范围。
景深就是对好焦的范围。它能通过把背景模糊化来突出拍摄对象,也可以拍出清晰的背景。
Java对点、线、面生成栅格瓦片jpg,并渲染呈现 1. 效果图2. 原理2.1 面瓦片的生成2.2 线瓦片的生成2.3 多点瓦片的生成 3. 源码参考 这篇博客将介绍从前端HTML页面到后端预生成栅格瓦片jpg,并提供查询接口供前端html调用呈现效果图;
1. 效果图 随机画一个多边形,以这个多边形面进行栅格瓦片生成;
点线面的渲染效果图如下:
多点为蓝色,线为绿色,面为红色
面生成为背景黑色的栅格瓦片,点线生成为背景白色的栅格瓦片效果图如下:
红色面的渲染效果图如下:
级别小一些只有一张图,和级别大一些多张图拼合而成,背景色可以是白色的,也可以是黑色的~;
蓝色点的渲染效果图如下:
级别大一些蓝色点的渲染效果图如下:
绿色线的渲染效果图如下:(1/500的分辨率认为点在线上)
1/20分辨率距离则认为点在线上效果图,看起来线要宽一些;
2. 原理 2.1 面瓦片的生成 先计算多边形面的Geometry经纬度范围(外接矩形的左上角,右下角坐标);经纬度坐标转web墨卡托坐标;指定某一级别计算瓦片号范围;分别遍历每一个瓦片(计算瓦片范围与多边形面是否有交集,没有交集生成一张空白图;有交集遍历每一个像素点转换为web墨卡托坐标,转换为Geometry坐标,判断点是否在多边形面上,在设置当前像素点颜色;不在给空白);循环遍历多个级别,重复1~4步骤,即可生成多个不同级别 2.2 线瓦片的生成 先计算 多线 的Geometry经纬度范围(外接矩形的左上角,右下角坐标);经纬度坐标转web墨卡托坐标;指定某一级别计算瓦片号范围;分别遍历每一个瓦片(计算瓦片范围与 线 是否有交集,没有交集生成一张空白图;有交集遍历每一个像素点转换为web墨卡托坐标,转换为Geometry 点坐标, 判断点是否在线上 ,在设置当前像素点颜色;不在给空白);循环遍历多个级别,重复1~4步骤,即可生成多个不同级别 判断点是否在线上需要注意,可参考谷歌js提供的算法,isPointOnSegment 计算距离允许误差在分辨率范围内,则标识在线上;
2.3 多点瓦片的生成 先计算 多点 的Geometry经纬度范围(外接矩形的左上角,右下角坐标);经纬度坐标转web墨卡托坐标;指定某一级别计算瓦片号范围;分别遍历每一个瓦片(计算瓦片范围与 多点 是否有交集,没有交集生成一张空白图;有交集 求瓦片范围与多点的交集点,然后遍历交集点,判断点是否在线上 ,在设置当前像素点颜色;不在给空白);循环遍历多个级别,重复1~4步骤,即可生成多个不同级别 3. 源码 package com.demo.utils; import com.vividsolutions.jts.geom.*; import com.vividsolutions.jts.geom.Point; import com.vividsolutions.jts.io.ParseException; import com.vividsolutions.jts.io.WKTReader; import com.vividsolutions.jts.util.GeometricShapeFactory; import java.util.List; /************************************* *Class Name: JtsUtils *Description: <jtsutils工具类> *@author: Seminar *@create: 2023/3/31 *@since 1.
IndexedDB是一种在客户端存储大量结构化数据的Web API,它是HTML5中的一个新特性。IndexedDB允许web应用程序在本地存储大量的数据,并且可以通过高效的索引进行查询和检索,这使得web应用程序可以脱离网络运行,并提供更好的用户体验。
IndexedDB的使用场景非常广泛,例如在离线应用程序中缓存数据,提高应用程序的响应速度和性能,或者将大量数据存储在本地,减少服务器的负载等。
IndexedDB的底层原理是,它使用浏览器内置的数据库引擎,例如SQLite或LevelDB,来创建本地数据库并存储数据。当Web应用程序调用IndexedDB API时,浏览器会将请求发送给数据库引擎进行处理。IndexedDB API提供了一种灵活的数据模型,允许开发人员使用对象存储来保存结构化的数据,同时可以使用索引来查询和检索数据。
在IndexedDB中,每个数据库都包含一个或多个对象存储(Object Store),每个对象存储包含多个存储对象(Storing Object),每个存储对象则包含多个键值对(key-value pair)。开发者可以通过对象存储和键值对来组织和查询数据。
总之,IndexedDB为Web应用程序提供了一种方便的方式来存储大量结构化数据,并提供高效的索引查询和检索功能,它是一种非常有用的技术,可以用于提高Web应用程序的性能和用户体验。
@Service public class RedisService { @Autowired private RedissonClient redissonClient; @Resource private RedisTemplate<String, Object> redisTemplate; /** * 建议使用redisson的加锁 释放锁 */ /** * 释放锁成功返回值 */ private static final Long RELEASE_LOCK_SUCCESS_RESULT = 1L; private static final String RELEASE_LOCK_SCRIPT = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end"; /** * 模糊查询 获取key集合 * * @param key * @return */ public Iterator<String> getKeys(String key) { Iterable<String> keysByPattern = redissonClient.getKeys().getKeysByPattern(key); Iterator<String> iterator = keysByPattern.
在HTML5中,可以使用CSS3实现各种按钮效果。以下是一些常见的按钮效果及其实现方法:
悬停效果 当用户将鼠标悬停在按钮上时,可以使用CSS3实现按钮颜色或背景色的变化。可以使用:hover伪类来实现这个效果,如下所示:
button:hover { background-color: #F00; } 点击效果 当用户单击按钮时,可以使用CSS3实现按钮的按下效果。可以使用:active伪类来实现这个效果,如下所示:
button:active { box-shadow: inset 0px 0px 5px #888; } 动画效果 可以使用CSS3的动画功能来实现各种按钮效果。例如,可以使用transition属性来实现平滑的过渡效果,或者使用keyframes和animation属性来实现更复杂的动画效果。下面是一个使用keyframes和animation属性来实现按钮呼吸动画的例子:
@keyframes breath { 0% { box-shadow: 0 0 0 rgba(0, 0, 0, 0.2); } 50% { box-shadow: 0 0 10px rgba(0, 0, 0, 0.4); } 100% { box-shadow: 0 0 0 rgba(0, 0, 0, 0.2); } } button { animation: breath 2s ease-out infinite; } 底层原理是,CSS3通过使用各种样式属性和伪类来实现各种按钮效果。这些效果实现的底层原理是使用浏览器的渲染引擎来对HTML元素进行渲染和绘制。当使用CSS3样式时,浏览器会在渲染过程中将这些样式应用于HTML元素,以实现各种效果。例如,在使用:hover伪类时,当用户将鼠标悬停在按钮上时,浏览器会检测到该伪类,并根据指定的样式更改按钮的颜色或背景色。同样地,在使用:active伪类时,当用户单击按钮时,浏览器会检测到该伪类,并根据指定的样式更改按钮的外观。
给大家推荐一个和vue完美契合echarts组件
vue2/vue3可用 延时获取数据也可以做到图表实时渲染
只需要像options传入echarts格式的数据即可 快去试试吧!
vue-hxhchart 安装方式:npm i vue-hxhchart。
// 全部引入 import hxhecharts from 'vue-hxhchart/' app.use(hxhecharts) 使用:(width和height可以设置,完美适应父元素宽高)
<hxhecharts :options="options" width="100%" height="100%" />
定义 引例 给定由 𝑛 个结点构成的树,树边带权,求树上最长路径的长度。
这条最长路径,被称为树的直径。
树的直径有时也可指代该路径长度。
2次DFS法 基本思路 两次 D F S DFS DFS 法的思路很简单,分为两步 (其实就是两次深搜
1.随便找一个幸运节点 x x x 做 D F S DFS DFS 找出离该节点最远的节点 y y y
2.以 y y y 为节点,再做一次 D F S DFS DFS 找出离 y y y 最远的节点 z z z
此时 y y y 到 z z z 就是树的一条直径
正确性后续会给出证明
关于 B F S BFS BFS 其实这里用两次 B F S BFS BFS 也是可以的,因为本质上是做两次树的遍历求出最长路
文章目录 1. open函数介绍2. 读文件3. 写文件4. with 方式读写文件 对文件进行读写操作是很常见的 I/O 操作,在Python中我们可以通过内置函数 open来完成。 1. open函数介绍 使用open函数,可以打开一个已经存在的文件,或者创建一个新文件。
语法:open(name, mode, encoding)
name:要打开的目标文件名的字符串,也就是文件所在的具体路径。为防止路径中出现转义问题,可以在路径前加一个r.mode:设置文件打开的模式,包括只读、写入、追加等encoding:编码格式,推荐使用utf-8 注意:在文件路径前面加r是为了取消字符串中的所有可能转义,即字符串的所有字符都会被当成正常字符
mode常见模式
文件读写模式描述r只读模式,文件不存在会报IO错误,默认就是该模式w用于写模式,文件不存在就会自动创建a用于追加,文件不存在会自动创建b二进制模式r+相当于r+w,可读可写,文件不存在会报IO错误w+相当于w+r,可读可写,文件不存在会自动创建a+相当于a+r,可追加可写,文件不存在会自动创建 注意:默认都是以文本模式打开文件,如果要以二进制模式打开,那么就给对应模式加上b即可,如rb、wb、ab、rb+、wb+、ab+等
2. 读文件 读取文件操作步骤分为三步,打开文件、读数据、关闭文件。
# 1. 以 r 模式打开文件, 获取文件对象 f = open(r"D:\\test.txt", "r", encoding='utf-8') # 2. 读文件 data = f.read() # 3. 关闭文件 f.close() 常见读取文件数据函数
函数描述read()每次读取整个文件,将读取内容放到字符串中,返回str对象readline()每次只读文件中的一行内容,将读取到的一行内容放到字符串中,返回str对象readlines()每次按行来读取整个文件,读取到每行内容依次放到列表中,返回list对象 注意
操作文件需要通过open函数打开文件得到文件对象文件读取完成后,要使用文件对象.close()方法关闭文件对象,否则文件会被一直占用,且会占用操作系统的资源。 读文件支持的模式见open()函数读相关的mode模式
3. 写文件 写文件的操作步骤和读取一样,打开文件、写数据、关闭文件,把读模式改成写模式,把读数据改成写数据。
# 1. 以 w 模式打开文件, 获取文件对象 f = open(r"D:\\test.txt", "w", encoding='utf-8') # 2. 写文件 data = f.
关于elementUI input粘贴复制
elementUI是一个基于Vue.js的前端UI框架,提供了丰富的组件和功能,方便开发者快速构建高效的用户界面。其中,input组件是一个常用的表单控件,用于接收用户的输入内容。input组件支持粘贴复制功能,即用户可以通过快捷键或右键菜单来复制或粘贴文本内容。本文将介绍如何使用elementUI input组件的粘贴复制功能,以及如何自定义粘贴复制的行为。
使用elementUI input组件的粘贴复制功能非常简单,只需要在模板中使用<el-input>标签,并绑定v-model属性来获取或设置输入值即可。例如:
<template>
<div>
<el-input v-model="value"></el-input>
</div>
</template>
<script>
export default {
data() {
return {
value: ''
};
}
};
</script>
这样,用户就可以在input组件中输入文本,并通过Ctrl+C或右键菜单来复制文本,或者通过Ctrl+V或右键菜单来粘贴文本。input组件会自动更新v-model绑定的值,以保持数据的同步。
如果需要自定义粘贴复制的行为,例如在粘贴时对文本进行格式化或验证,或者在复制时添加额外的信息,可以使用input组件提供的paste和copy事件。这两个事件会在用户执行粘贴或复制操作时触发,并传递一个event对象作为参数。event对象包含了原生的ClipboardEvent对象,可以通过event.clipboardData属性来访问剪贴板中的数据。例如:
<template>
<div>
<el-input v-model="value" @paste="handlePaste" @copy="handleCopy"></el-input>
</div>
</template>
<script>
export default {
data() {
return {
value: ''
};
},
methods: {
handlePaste(event) {
// 获取剪贴板中的文本
let text = event.clipboardData.getData('text/plain');
// 对文本进行格式化或验证
text = text.trim().toUpperCase();
// 设置输入值
this.value = text;
// 阻止默认行为
以往都是使用关系型数据库,实体类和表一一对应,但现在的知识图谱项目要使用到图数据库,不太知道怎么设置实体类,然后就去查java怎么连接neo4j
连接关系型数据库 对于关系型数据库,表与实体类一一对应
连接图数据库 对于图数据库,有两种方法
1、使用框架,可以使用不同的节点类型代表不同的实体类,就是一个本体代表一个实体类,这样可以用到一些注解,可以直接调用一些curd的方法,但是本体确定了实体类就确定了
2、也可以使用HashMap代替实体类实现存取,这样的话就要自己写一下cypher,就是原生写法
1、使用框架,本体对应实体类,Spring-Data-Neo4j 可以使用Spring-Data-Neo4j连接数据库,类似于mybaits的数据库连接工具,下面是它的定义
Spring Data Neo4j 简称SDN,是一个对象-图形映射(OGM)框架,是为了简化开发者的工作而创建的,它的目的是通过处理所有底层工作和从Neo4j读域实体并写回去所必须的映射逻辑来提高效率
OGM类似于关系型数据库的ORM(Object Relation Mapping,对象关系映射),OGM即对象图映射(Object Graph Mapper ,简称OGM ),基于OGM可以将neo4j中的图模型快速转换成java中的对象。
2、不使用框架,用HashMap代替实体类 看到的一个项目,他里面可以自建不同的图谱,但是这里面的每一个图谱代表不同的节点类型,图谱中的本体类型只能用一个property这类的属性代表,可以有以下两种方式,但是都要自己手写cypher语句实现CURD
1、neo4j-java-driver
2、GraphDatabase
3、其他 这里面还分服务器开发和嵌入式开发
上面说的是服务器开发,需要连接一个外部neo4j数据库
还有嵌入式开发,在程序里面下载一个neo4j
<!-- 服务器开发需要的jar包 --> <!-- 这个比较原生 --> <dependency> <groupId>org.neo4j.driver</groupId> <artifactId>neo4j-java-driver</artifactId> <version>1.5.0</version> </dependency> <!-- 这个是spring集成的框架 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-neo4j</artifactId> </dependency> <!-- 嵌入式开发需要的jar包,这个我没用过 --> <dependency> <groupId>org.neo4j</groupId> <artifactId>neo4j</artifactId> <version>3.3.4</version> </dependency> 参考博客 上面的内容写的不全,基本按照下面的汇总一下,详细的可以看下面的博客
java连接neo4j(使用spring data neo4j)_DOITHu的博客-CSDN博客 ——这个是spring-data-neo4j
爆肝十小时—我终于用Java连上Neo4j数据库 - 知乎 (zhihu.com) ——这个主要是嵌入式开发
Java 操作 Neo4J 就是这么简单!-java neo4j (51cto.
1. 概念:
WFI(Wait for interrupt)和WFE(Wait for event)是两个让ARM核进入low-power standby模式的指令,由ARM architecture定义,由ARM core实现。
2. WFI和WFE 2.1 相同点 WFI和WFE的功能非常类似,以ARMv8-A为例(参考DDI0487A_d_armv8_arm.pdf的描述),主要是“将ARMv8-A PE(Processing Element, 处理单元)设置为low-power standby state”。
需要说明的是,ARM architecture并没有规定“low-power standby state”的具体形式,因而可以由ARM core自行发挥,根据ARM的建议,一般可以实现为standby(关闭clock、保持供电)、dormant、shutdown等等。但有个原则,不能造成内存一致性的问题。
以Cortex-A57 ARM core为例,它把WFI和WFE实现为“put the core in a low-power state by disabling the clocks in the core while keeping the core powered up”,即我们通常所说的standby模式,保持供电,关闭clock。
2.2 不同点 那它们的区别体现在哪呢?主要体现进入和退出的方式上。
对WFI来说,执行WFI指令后,ARM core会立即进入low-power standby state,直到有WFI Wakeup events发生。
而WFE则稍微不同,执行WFE指令后,根据Event Register(一个单bit的寄存器,每个PE一个)的状态,有两种情况:
如果Event Register为1,该指令会把它清零,然后执行完成(不会standby);
如果Event Register为0,和WFI类似,进入low-power standby state,直到有WFE Wakeup events发生。
2.3 使用场景 WFI WFI一般用于cpuidle。
Protocol Buffers教程 Protocol Buffers简介下载安装Protocol Buffers编译器编写第一个protobuf文件,并编译成go文件Protocol Buffers定义消息类型Protocol Buffers基本数据类型Protocol Buffers枚举类型Protobuf生成的go源码分析Protobuf序列化和反序列化protobuf和json相互转换在protobuf中定义服务
Altium Designer 22 X-Signal功能在Altium软件等长中的使用 1)什么是X-signal 在高速设计中,基于时序的考虑通常要对信号做线长匹配。对于只有2个管脚的信号路径,计算和匹配线长这一过程非常直接、清晰。
但对于大部分高速设计来讲,情况会更为复杂,这些情况包含但不仅限于:信号路径中需要使用端接电阻 (termination resistor),这时需要调制的线长是包括端接电阻在内的不同网络。
Data总线常用的的T点拓扑结构
2)X-signal是如创建并应用的 3)X-signal和其他等长方式有什么优点 链接: Altium Designer 22 X-Signal功能在Altium软件等长中的使用
Scrapy,Python开发的一个快速、高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据。Scrapy用途广泛,可以用于数据挖掘、监测和自动化测试。
Scrapy吸引人的地方在于它是一个框架,任何人都可以根据需求方便的修改。它也提供了多种类型爬虫的基类,如BaseSpider、sitemap爬虫等,最新版本又提供了web2.0爬虫的支持。在之前的博文当中,简要介绍了Scrapy相关工具命令的介绍,以及Scrapy爬虫项目的基本结构。现在,我们需要自己编写一个Scrapy爬虫项目,从之前介绍Scrapy项目结构中可以知道,一个简单的爬虫,只需要对spider、items.py以及pipelines.py做一些相关操作即可,因为它们分别代表着爬虫部分相关的代码,爬虫项目的数据容器以及对爬虫数据的相关处理,这三个步骤对于爬虫项目是最为重要的!!!
Items的编写 使用Scrapy中的Item对象可以保存爬取到的数据,相当于存储爬取到的数据的容器。一般来说,互联网网页中的信息比较庞大,基本上都是非结构化信息,这样的非结构化信息不太利于我们对信息的管理,所以此时,我们可以定义自己所关注的结构化信息,然后从庞大的互联网信息体系中提取出我们关注的结构化信息,这样可以更利于我们对数据的管理,提取之后,这些数据信息需要一个存储的地方,此时,可以将提取到的结构化数据存储到Item对象中。
定义结构化数据信息的格式如下:
结构化数据名 = scrapy.Field() 所以,若要对结构化数据网页标题、网页地址等进行定义。我们打开之前创建的爬虫项目myfirstspider,可以将items.py的代码修改为如下:
import scrapy class MyfirstspiderItem(scrapy.Item): title = scrapy.Field() url = scrapy.Field() 可以看到,要定义一个结构化数据,只需要将Scrapy下的Field类实例化即可。
我们可以通过Python Shell来实际使用以下Items,更深入地理解Items。进入Python Shell,将上面的Items代码写上,如下:
>>> import scrapy >>> class MyFirstspiderItem(scrapy.Item): title = scrapy.Field() url = scrapy.Field() >>> item = MyFirstspiderItem(title='测试', url='http://www.baidu.com') >>> print(item) {'title': '测试', 'url': 'http://www.baidu.com'} 我们实例化了MyFirstspiderItem类,并初始化了参数,并且将MyFirstspiderItem的实例化对象打印了出来。可以发现,对应的数据会以字典的形式存储,原数据项会转变为字典中的字段名,原数据项对应的值会转变为字典中相应字段名对应的值。
如果我们要单独取某个字段对应的值,可以通过:对象名['字段名']的方式实现。比如,想单独输出对象中的title字段对应的值,可以通过如下方式实现:
>>> item['title'] '测试' 切记,不可以使用.的方式获取字段的值,否则将引发错误,如下:
>>> item.title Traceback (most recent call last): File "<input>", line 1, in <module> File "/Users/xxx/PycharmProjects/demo/venv/lib/python3.7/site-packages/scrapy/item.py", line 92, in __getattr__ raise AttributeError(f"
开关电源设计时如何减小地弹 1、BUCK拓扑结构电路介绍
2、如何减小设计时地弹影响
3、BUCK拓扑开关电源PCB设计案例分析
public class Main{
public static void main(String[] args){
System.out.println(4+(20-1)+20*(22-1));
}
答案:443
方法一:蛮力算法,注意Long.MAX_VALUE为:9223372036854775807,闲着没事干儿可以用这个方法,答案约等于2e15<9e18(Long的最大值),可以循环出结果
public class Main {
public static void main(String[] args) {
long m=Long.MAX_VALUE;
for(long i=0;i<m;i++) {
if(
i%2==1&&
i%3==1&&
i%4==1&&
i%5==1&&
i%6==1&&
i%7==1&&
i%8==1&&
//此处省略
i%48==41&&
i%49==46
) {
System.out.println(i);
}else {
System.out.println("没有找到");
}
}
}
}
方法二:利用步长逐步累加
public class Main{
public static void main(String[] args) { int[] a = {
0, 0,//为了使a[i]与i匹配,这里放入0填充a[0],a[1]
1, 2, 1, 4, 5, 4, 1, 2, 9, 0, 5, 10,
文章目录 一、背景二、第一波软件网络排查过程1、nmtui连接wifi2、nmcli 查看wifi列表3、ifconfig4、重启大法 三、第二波硬件驱动排查过程1、lshw -C network2、lsmod | grep wi3、lspci -k | grep -C 3 Wi4、探测系统启动信息,查看驱动加载情况5、查看当前安装的firmware版本6、遇事不决,可问google7、降级firmware8、重新查看,发现wifi起来了,重新连接wifi即可。 四、原因 一、背景 在一个很平常的日子,远程连接我的NUC一直失败,怀疑是网络没连接上,问题是前一晚还是好好的啊,费解。
博主的NUC安装的是Manjaor系统,登录上去查看发现wifi果然是没连接。本以为直接nmtui 连接下wifi就好了,没想到事情远没这么简单。。。
二、第一波软件网络排查过程 1、nmtui连接wifi 图形界面上没有wifi模块,也没有wifi列表,根本连接不了。。。
2、nmcli 查看wifi列表 # nmcli device wifi list # 没错,wifi列表是空的,我去。。
3、ifconfig ifconfig发现只有docker0 和eth0,根本没有wifi模块。。emmm,看起来像是wifi驱动没起来啊,无线网卡都没加载出来。
4、重启大法 1、难道是网络管理的问题,重启 sudo systemctl restart NetworkManager # 失效 2、难道是网卡设备加入了黑名单 cd /etc/modprobe.d # 失效,是空的 3、我特么直接reboot # 失效+10086 第一波排查基本可以锁定是wifi设备没起来,可能是硬件也可能是驱动。一般来说驱动可能性大一些。
搜索了一圈,发现有建议是升级内核版本。不至于吧,毕竟昨天还是能用的。
博主linux内核版本5.15,看起来像是同样的问题,但是升级内核这种事,非必要还是算了,继续找问题。。
建议升级内核的:Manjaro not detecting WiFi adaptor Intel Corporation Alder Lake-P PCH CNVi WiFi (rev 01)
三、第二波硬件驱动排查过程 首先是排查的命令先介绍下:
一、OSI 网络七层模型 第一层:应用层,定义了用于在网络中进行通信和传输数据的接口;(Http协议位于该层)
第二层:表示层,定义不同系统中数据的传输格式,编码和解码规范等;
第三层:会话层,管理用户的会话,控制用户间逻辑连接的建立和中断;
第四层:传输层,管理着网络中端到端的数据传输;(Tcp协议位于该层)
第五层:网络层,定义网络设备间如何传输数据;(IP位于该层)
第六层:链路层,将上面的网络层的数据包封装成数据帧,便于物理层传输;
第七层:物理层,这一层主要就是传输这些二进制数据。
二、TCP连接 建立起一个TCP连接需要经过“三次握手”:
第一次握手:客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。 握手过程中传送的包里不包含数据,三次握手完毕后,客户端与服务器才正式开始传送数据。理想状态下,TCP连接一旦建立,在通信双方中的任何一方主动关闭连接之前,TCP 连接都将被一直保持下去。断开连接时服务器和客户端均可以主动发起断开TCP连接的请求。
SYN攻击就是利用三次握手的第二次握手时进行的,这时候服务器处于SYN_RECV状态,等待客户端进行确认ACK,SYN会伪造不存在的源IP,就会有大量的链接处于等待或重试发送SYN+ACK包,导致该阶段队列持续增长,进而导致后续正常请求被丢弃。
三、HTTP连接 HTTP协议即超文本传送协议(Hypertext Transfer Protocol ),是Web联网的基础,也是手机联网常用的协议之一,HTTP协议是建立在TCP协议之上的一种应用。
HTTP连接最显著的特点是客户端发送的每次请求都需要服务器回送响应,在请求结束后,会主动释放连接。从建立连接到关闭连接的过程称为“一次连接”。
在HTTP 1.0中,客户端的每次请求都要求建立一次单独的连接,在处理完本次请求后,就自动释放连接。在HTTP 1.1中,则可以在一次连接中处理多个请求,并且多个请求可以重叠进行,不需要等待一个请求结束后再发送下一个请求。 由于HTTP在每次请求结束后都会主动释放连接,因此HTTP连接是一种“短连接”。
要保持客户端程序的在线状态,需要不断地向服务器发起连接请求,通常情况下即使不需要获得任何数据,客户端也保持每隔一段固定的时间向服务器发送一次“保持连接”的请求,服务器在收到该请求后对客户端进行回复,表明知道客户端“在线”。若服务器长时间无法收到客户端的请求,则认为客户端“下线”,若客户端长时间无法收到服务器的回复,则认为网络已经断开。
四、SOCKET连接与HTTP连接 通常情况下Socket连接就是TCP连接,因此Socket连接一旦建立,通信双方即可开始相互发送数据内容,直到双方连接断开。但在实际网络应用中,客户端到服务器之间的通信往往需要穿越多个中间节点,例如路由器、网关、防火墙等,大部分防火墙默认会关闭长时间处于非活跃状态的连接而导致 Socket 连接断连,因此需要通过轮询告诉网络,该连接处于活跃状态。
而HTTP连接使用的是“请求—响应”的方式,不仅在请求时需要先建立连接,而且需要客户端向服务器发出请求后,服务器端才能回复数据。
很多情况下,需要服务器端主动向客户端推送数据,保持客户端与服务器数据的实时与同步。此时若双方建立的是Socket连接,服务器就可以直接将数据传送给客户端;若双方建立的是HTTP连接,则服务器需要等到客户端发送一次请求后才能将数据传回给客户端,因此,客户端定时向服务器端发送连接请求,不仅可以保持在线,同时也是在“询问”服务器是否有新的数据,如果有就将数据传给客户端。
相关视频推荐
看完《tcp/ip详解》不能coding的,一次课开启设计tcp/ip协议栈
深入聊聊websocket协议,tcp分包与粘包解决方案
免费学习地址:C/C++Linux服务器开发/后台架构师
需要C/C++ Linux服务器架构师学习资料加qun812855908获取(资料包括C/C++,Linux,golang技术,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK,ffmpeg等),免费分享
五、SOCKET连接与TCP/IP连接 创建Socket连接时,可以指定使用的传输层协议,Socket可以支持不同的传输层协议(TCP或UDP),当使用TCP协议进行连接时,该Socket连接就是一个TCP连接。
socket则是对TCP/IP协议的封装和应用(程序员层面上)。也可以说,TPC/IP协议是传输层协议,主要解决数据如何在网络中传输,而HTTP是应用层协议,主要解决如何包装数据。
关于TCP/IP和HTTP协议的关系,网络有一段比较容易理解的介绍:
在传输数据时,可以只使用(传输层)TCP/IP协议,但是那样的话,如果没有应用层,便无法识别数据内容,如果想要使传输的数据有意义,则必须使用到应用层协议,应用层协议有很多,比如HTTP、FTP、TELNET等,也可以自己定义应用层协议。WEB使用HTTP协议作应用层协议,以封装HTTP文本信息,然后使用TCP/IP做传输层协议将它发到网络上。
平时说的最多的socket是什么呢,实际上socket是对TCP/IP协议的封装,Socket本身并不是协议,而是一个调用接口(API),通过Socket,才能使用TCP/IP协议。
实际上,Socket跟TCP/IP协议没有必然的联系。Socket编程接口在设计的时候,就希望也能适应其他的网络协议。所以说,Socket的出现 只是使得程序员更方便地使用TCP/IP协议栈而已,是对TCP/IP协议的抽象,从而形成了一些最基本的函数接口,比如create、 listen、connect、accept、send、read和write等等。
TCP/IP只是一个协议栈,就像操作系统的运行机制一样,必须要具体实现,同时还要提供对外的操作接口。这个就像操作系统会提供标准的编程接口,比如win32编程接口一样,TCP/IP也要提供可供程序员做网络开发所用的接口,这就是Socket编程接口。
实际上,传输层TCP是基于网络层IP协议的,而应用层HTTP协议又是基于传输层TCP协议的,而Socket本身不算是协议,就像上面所说,它只是提供了一个针对TCP或者UDP编程的接口。
总结:
HTTP是应用层协议,定义的是传输数据的内容以及格式的规范。TCP是底层通讯协议,定义的是数据传输和连接方式的规范。Socket可以支持不同的传输层协议(TCP/UDP),当使用TCP协议进行连接时,该Socket连接就是一个TCP连接,Socket是发动机,提供了网络通信的能力 六、什么是单工、半双工、全双工通信? 单工:信息只能单向传送;半双工:信息能双向传送但不能同时双向传送;全双工:信息能够同时双向传送。 七、WebSocket与Socket的关系 Socket其实并不是一个协议,而是为了方便使用TCP/UDP而抽象出来的一层,是位于应用层和传输控制层之间的一组接口。
Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口,提供一套调用TCP/IP协议的API。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。
当两台主机通信时,必须通过Socket连接,Socket则利用TCP/IP协议建立TCP连接。TCP连接则更依靠于底层的IP协议,IP协议的连接则依赖于链路层等更低层次。
WebSocket就像HTTP一样,是一个典型的应用层协议。
总结:
Socket是传输控制层接口,WebSocket是应用层协议。 八、WebSocket与HTTP的关系 WebSocket是HTML5规范提出的一种协议。HTML5 Web Sockets规范定义了Web Sockets API,支持页面使用Web Socket协议与远程主机进行全双工的通信。它引入了WebSocket接口并且定义了一个全双工的通信通道,通过一个单一的套接字在Web上进行操作。
HTML5 Web Sockets以最小的开销高效地提供了Web连接。相较于经常需要使用推送实时数据到客户端甚至通过维护两个HTTP连接来模拟全双工连接的旧的轮询或长轮询(Comet)来说,这就极大的减少了不必要的网络流量与延迟。
很多人知道C++中max(),min(),函数的二数比较,即max(a, b),min(a, b)。但很多人不知道有多个数如何利用该自带的函数比较,这里给出方法:只需要在max(),min()函数内用一个大括号括住自己想要比较的数的集合即可,同理,大括号内是自己提前定义的变量也能进行比较
#include<bits/stdc++.h> using namespace std; int main() { //取多数的最大值 int maxx = max({1, 2, 3, 4, 5, 6}); //取多数的最小值 int minn = min({1, 2, 3, 4, 5, 6}); cout << "max: " << maxx << endl; cout << "min: " << minn << endl; system("pause"); return 0; } 运行结果:
虚拟环境创建前的环境设置 搭建虚拟环境完整步骤 参考
python搭建虚拟环境完整步骤(这个用conda env list查看虚拟环境,竟然不显示,弃了)
python删除、创建虚拟环境(好像更好用一点)
关于python:如何将全局安装的软件包导入virtualenv虚拟环境文件夹 在虚拟环境目录中,编辑文件pyvenv.cfg。 设置参数include-system-site-packages = true,然后保存文件。
下次您激活(./activate)环境时,将显示全局安装的模块。
可以通过pip list进行验证。
目录
一、归一化处理方法
(1)min-max方法(离散归一化)
(2)零-均值规范化方法
(3)小数定标规范化
二、插值法
(1)拉格朗日插值法
三、相关性分析
(1)pearson相关性系数
(2)spearman相关性系数
四、主成分分析(PCA)
一、归一化处理方法 归一化常用方法有:
(1)min-max方法(离散归一化) 对原始数据的线性变换,将数据点映射到了[0,1]区间(默认)
一般调用sklearn库中的min_max_scaler函数实现,代码如下:
from sklearn import preprocessing import numpy as np x = np.array( [[1972, 685, 507, 962, 610, 1434, 1542, 1748, 1247, 1345], [262, 1398, 1300, 1056, 552, 1306, 788, 1434, 907, 1374],]) # 调用min_max_scaler函数 min_max_scaler = preprocessing.MinMaxScaler() minmax_x = min_max_scaler.fit_transform(x) (2)零-均值规范化方法 把特征值的分布变化到均值为零。这种做法可以消除不同特征(或样本)之间的量级差异,使得特征之间的分布更加接近的变化,这在某些模型(如SVM)中,能够极大地提升处理效果,促使模型更加稳定,提升预测准确度。
代码实现:
import numpy as np # 零-均值规范化 def ZeroAvg_Normalize(data): text=(data - data.mean())/data.std() return text (3)小数定标规范化 小数定标规范化就是通过移动小数点的位置来进行规范化。小数点移动多少位取决于属性A的取值中的最大绝对值。
毕设帮助、开题指导、技术解答(有偿)见文末。
目录
摘要
一、硬件方案
二、设计功能
三、实物图
四、原理图
五、PCB图
六、Proteus仿真 七、程序源码
八、资料包括
摘要 随着社会的发展,人类科技的进步,各行各业都在使自己的产品智能化、数字化,因老式的热水器使用煤气或天然气对水进行燃烧加热,用手动的方式调节温度,不仅不能够精确的确定使用者需要的水温,而且还存在一定的危险性。
电热水器是一种可供浴室、洗手间及厨房使用的家用电器,随着人们生活质量的提高,现代的家用电热水器已经摒弃了以前的做法,而采用一种更加精确、安全的实施方案。
C语言对单片机编程有诸多优点,例如:便于移植、句法检查时错误少、坚固性好、头文件种类诸多,能够方便快捷使用各种函数等。本文采用STC89C52单片机作为控制器,使用C语言编写程序,设计了一款智能家用电热水器。使用按键键盘设定温度,温度可以精确到0.1摄氏度,并使用LED灯显示,能够精确提供用户所需温度的温水。采用DS18B20采集温度,使用LED灯显示,精确的显示出采集的水温。当所需温度高于当前采集的水温时,使用继电器控制外接加热源,当所需温度低于当前采集的水温时,继电器断开不加热。当所需温度高于采集温度时,继电器吸合开始加热。基本实现了智能控制功能。
关键字:18B20、STC89C52、热水器 LCD1602显示
一、硬件方案 本系统采用51单片机最小系统电路(复位电路+晶振时钟电路+单片机电源电路)+防水18B20温度传感器+LCD1602液晶+继电器+按键+水位传感器+总电源供电电路。
二、设计功能 1、本设计基于STC89C51/52(与AT89S51/52、AT89C51/52通用)。
2、设计自带单片机上电复位电路、手动复位电路(复位按键)、晶振电路(给单片机提供时钟周期)。
3、采集LCD1602液晶显示实际温度值,报警参数可以同时显示出来,直观明了,温度精确的小数点显示。
4、有两种模式:自动模式和手动模式,具有水温和水位控制功能。
5、具有预约开启热水器的功能,可以设置预约时间小时和分钟,时间一到加热继电器工作加热,这样更加智能和节能。
6、自动模式:当18B20温度传感器测到的实际温度低于设定的温度下限值时继电器自动吸合指示灯亮模拟加热,当温度高于上限值时继电器自动关闭停止加热。 7、水位检测有低、中、高。当水位低时会自动停止加热防止干烧,并启动加水继电器工作模拟加水,当水位高于高水位时自动停止加水。 8、蜂鸣器的提示声音不同,当温度低于下限时,蜂鸣器会长鸣一声,当温度高于上限时,蜂鸣器会发出滴滴的声音,此功能更加清楚的知道热水器的工作状态。
9、手动模式:当温度在上、下限范围之间时,可以按加键手动开启和关闭加热继电器,当水位低平高水位的时可以按减键手动开启和关闭水位继电器加水。
10、可以设置温度上限和温度下限值,设置的参数具有掉电保存功能,保存在STC单片机内部。
11、防水温度传感器,即可以测水温又可以测空气的温度,温度精确到小数点显示。
12、按键具有连加、连减的功能,在设置参数时按键按着不动可以实现连加、连减的功能,设置起来非常方便。
13、温度测量范围:0度到99.9度
三、实物图 四、原理图 五、PCB图 六、Proteus仿真 七、程序源码 八、资料包括 需要完整的资料可以点击下面的名片,找我要资源压缩包的百度网盘下载地址及提取码。
文章目录 介绍配置流程文件介绍安装、配置Ubuntu20.04 Desktop安装/配置tigervnc-serverUbuntu20.04 Desktop使用systemd开机启动 介绍 官网官网下载 配置流程 添加用户映射配置Xvnc选项设置VNC密码启动Tigervnc服务器配置防火墙 文件介绍 官方github介绍需要文件 文件作用/etc/tigervnc/vncserver.users映射桌面与系统用户可以为3个文件中任意1个配置Xvnc选项,下方"config文件"有介绍passwd密码文件,使用"vncpasswd"生成,默认在"~/.vnc/passwd"/lib/systemd/system/vncserver@.servicesystemd服务文件 vncserver.users文件 官方github文件文件内容sudo bash -c "cat >> /etc/tigervnc/vncserver.users" <<'EOF' #第一个桌面即5901端口对应bdidc用户 #第二个桌面即5902端口对应root用户 :1=bdidc :2=root EOF config文件 官方github文件配置文件优先级,越大越优先 优先级文件1/etc/tigervnc/vncserver-config-defaults2$HOME/.vnc/config3/etc/tigervnc/vncserver-config-mandatory 文件内容sudo bash -c "cat >> /etc/tigervnc/vncserver-config-defaults" <<'EOF' # session必选,必须与当前桌面匹配,可以在/usr/share/xsessions目录的文件中查看当前桌面 session=gnome geometry=1024x768 EOF passwd文件 二进制文件,只能使用命令创建,不能查看默认在当前用户家目录的.vnc目录中创建命令vncpasswd vncserver@.service文件 官方github文件文件内容sudo bash -c "cat > /lib/systemd/system/vncserver@.service" <<'EOF' [Unit] Description=Remote desktop service (VNC) After=syslog.target network.target [Service] Type=forking ExecStart=/usr/lib/x86_64-linux-gnu/vncsession-start %i PIDFile=/run/vncsession-%i.pid SELinuxContext=system_u:system_r:vnc_session_t:s0 [Install] WantedBy=multi-user.target EOF sudo systemctl daemon-reload 安装、配置 Ubuntu20.
sizeof() 函数用于获取数据类型或变量所占用的内存字节数,不管这个变量是什么类型,只要是在编译时就能确定其类型的表达式或变量,都可以作为 sizeof() 的参数,例如:
int a = 10;
int arr[10];
printf("%d\n", sizeof(int)); // 输出 4
printf("%d\n", sizeof(a)); // 输出 4
printf("%d\n", sizeof(arr)); // 输出 40
strlen() 函数用于获取一个字符串的长度,即字符串中字符的个数,它只能用于处理以 NULL 结尾的字符串,例如:
char str[] = "hello world";
printf("%d\n", strlen(str)); // 输出 11
需要注意的是,strlen() 函数只计算字符串中的字符个数,不包括字符串末尾的 NULL 字符,因此上面的例子中输出的是 11,而不是 12。
综上所述,sizeof() 和 strlen() 的主要区别在于:
sizeof() 获取数据类型或变量所占用的内存字节数,而 strlen() 获取字符串中字符的个数。sizeof() 可以用于任何数据类型或变量,而 strlen() 只能用于以 NULL 结尾的字符串。
目录
前言
一、List
二、Map
三、Map>,>
四、Map>,>
前言 我们在《SpringBoot properties配置Map、List》文章中介绍了配置Map、List的方式,但是这种方式无法实现热部署,实时更新。所以每次变更配置后,需要重启服务才会生效。
目前大部分项目的配置文件都会放到Apollo里,显然这样的方式就不台合理了,本身用Apollo的初衷就是为了能灵活的修改配置,及时生效。
本文主要介绍Apollo配置List、Map,并实现热部署方式。
一、List Apollo配置
apollo.test.list = "1,2,3" 使用方式
@Value("#{${apollo.test.list}}") private List<String> list; 或者
Apollo配置
apollo.test.list = 1,2,3 使用方式
@Value("#{'${apollo.test.list}'.split(',')}") private List<String> list; 也可以通过split指定分隔符 Apollo配置
apollo.test.list = a&b&c 使用方式
@Value("#{'${apollo.test.list}'.split('&')}") private List<String> list; 二、Map Apollo配置
apollo.test.map = {a:1,b:2} 使用方式
@Value("#{${apollo.test.map}}") private Map<String, Integer> map; 三、Map<String, Map<String, String>> Apollo配置
apollo.test.mapMap = {a:{a_1:"1_1",a_2:"1_2"},b:{b_1:"2_1",b_2:"2_2"}} 使用方式
@Value("#{${apollo.test.mapMap}}") private Map<String, Map<String, String>> mapMap; 四、Map<String, List<String>> Apollo配置
文章目录 kafkakafka概述消息系统kafka简介 kafka基础kafka集群架构kafka工作流程发布 - 订阅消息的工作流程队列消息/用户组的工作流 kafka安装步骤启动zookeeper启动Kafka创建topic查看topic生产数据消费数据关闭zookeeper关闭Kafka kafka kafka中文手册
kafka概述 Kafka专为分布式高吞吐量系统而设计。与其他消息传递系统相比,Kafka具有更好的吞吐量,内置分区,复制和固有的容错能力,这使得它非常适合大规模消息处理应用程序。
消息系统 消息系统负责将数据从一个应用程序传输到另一个应用程序,因此应用程序可以专注于数据,但不担心如何共享它。分布式消息传递基于可靠消息队列的概念。 消息在客户端应用程序和消息传递系统之间异步排队。有两种类型的消息模式可用 - 一种是点对点,另一种是发布 - 订阅(pub-sub)消息系统。 大多数消息模式遵循 pub-sub 。 点对点消息系统
在点对点系统中,消息被保留在队列中。一个或多个消费者可以消耗队列中的消息,但是特定消息只能由最多一个消费者消费。 一旦消费者读取队列中的消息,它就从该队列中消失。 该系统的典型示例是订单处理系统,其中每个订单将由一个订单处理器处理,但多个订单处理器也可以同时工作。 下图描述了结构。
发布 - 订阅消息系统
在发布 - 订阅系统中,消息被保留在主题中。 与点对点系统不同,消费者可以订阅一个或多个主题并使用该主题中的所有消息。 在发布 - 订阅系统中,消息生产者称为发布者,消息使用者称为订阅者。
kafka简介 Apache Kafka是一个分布式发布 - 订阅消息系统和一个强大的队列,可以处理大量的数据,并使您能够将消息从一个端点传递到另一个端点。
Kafka适合离线和在线消息消费。 Kafka消息保留在磁盘上,并在群集内复制以防止数据丢失。 Kafka构建在ZooKeeper同步服务之上。 它与Apache Storm和Spark非常好地集成,用于实时流式数据分析。
好处,以下是Kafka的几个好处 可靠性 - Kafka是分布式,分区,复制和容错的。可扩展性 - Kafka消息传递系统轻松缩放,无需停机。耐用性 - Kafka使用分布式提交日志,这意味着消息会尽可能快地保留在磁盘上,因此它是持久的。性能 - Kafka对于发布和订阅消息都具有高吞吐量。 即使存储了许多TB的消息,它也保持稳定的性能。 用例,Kafka可以在许多用例中使用。 其中一些列出如下 指标 - Kafka通常用于操作监控数据。 这涉及聚合来自分布式应用程序的统计信息,以产生操作数据的集中馈送。日志聚合解决方案 - Kafka可用于跨组织从多个服务收集日志,并使它们以标准格式提供给多个服务器。流处理 - 流行的框架(如Storm和Spark Streaming)从主题中读取数据,对其进行处理,并将处理后的数据写入新主题,供用户和应用程序使用。 Kafka的强耐久性在流处理的上下文中也非常有用。 kafka基础 在深入了解Kafka之前,必须了解主题,经纪人,生产者和消费者等主要术语。 下图说明了主要术语。
由于同时管理多个项目,多种开发语言同步开发,开了好多个Git窗口。今天在提交python某项目的时候不小心在vue的项目中执行了git add、git commit 操作,在push的时候悬崖勒马,于是故事开始了:我先回滚了commit,接着想把add也回滚一下,结果直接回滚到了上次提交的那个节点上,哦豁,新写的代码...它...没了,于是,掏出超级棒棒糖,奇思妙想之后有了接下来的补救操作:
在代码开发编辑器中选择自己修改的项目文件/文件夹->右键
选择“Local History” --> “Show History” 页面展示代码更新记录
选择需要回退的时间序列
右键-->revert
这样代码就恢复到自己想要的操作节点上了。
但如果是之前新建的文件或者目录,被自己的神操作弄没了,也很简单,在编辑器左侧对应的文件夹下创建自己丢失的那个目录/文件,也一样重复上述操作,一样可以找到过往的操作日志(前提是需要知道自己创建和修改的那个文件的名字)
自此,回忆一下下面的知识吧~
git commit后,如何进行撤销commit操作 在我们使用git作为版本控制工具进行代码管理之后,经常性的会碰到一个问题:git commit后,如何撤销commit,下面详细讲一下。
git add newFiles
git commit -m '新增xx页面'
执行commit后,还没执行push时,想要撤销这次的commit,该怎么办?
解决方案:
我们可以使用命令:git reset --soft HEAD^ 这样就成功撤销了commit。
使用git reset --hard HEAD^ 这样连add也撤销了。
*注:reset 命令只能回滚最新的提交,无法满足保留最后一次提交只回滚之前的某次提交。
命令解释:
HEAD^ 表示上一个版本,即上一次的commit,几个^代表几次提交,如果回滚两次就是HEAD^^。 也可以写成HEAD~1,如果进行两次的commit,想要都撤回,可以使用HEAD~2。 --soft 不删除工作空间的改动代码 ,撤销commit,不撤销add --hard 删除工作空间的改动代码,撤销commit且撤销add 如果commit后面的注释写错了,先别急着撤销,可以运行git commit --amend 进入vim编辑模式,修改完保存即可 参考链接:https://blog.csdn.net/logan_LG/article/details/81531796
开始利用ESP8266和usb转串口测试AT指令等均有返回值。连上板子后,像虚拟调试助手连续发送了一系列指令,刚开始还有乱码,每条指令均无响应,怎莫解决呢。
问题 操作环境: VSCode + Python3.10 + PySide6/pyqt5
问题描述: 在写代码时,控件不能弹出 .clicked.connect 补全提示
解决 其他网友解决办法:pip install pyqt5-stubs
根据格式,使用了对应的版本 pip install PySide6-stubs
但安装失败,在搜索py官方文档得知,可以用名为 IceSpringPySideStubs 的插件解决存根问题。
官方地址:https://pypi.org/project/IceSpringPySideStubs-PySide6/
且官方给出了安装的方法:
PySide2: pip install IceSpringPySideStubs-PySide2
PySide6: pip install IceSpringPySideStubs-PySide6
PyQt5: pip install IceSpringPySideStubs-PyQt5
PyQt6: pip install IceSpringPySideStubs-PyQt6
效果 出现其他不能补全提示 .clicked 可以补全提示后,如果还有其他关于pyside库里面不能提示的,可以按照以下思路进行。
当安装 IceSpringPySideStubs 后,写代码时优先进入 IceSpringPySideStubs 的存根查找属性、方法,如果有就立即弹出补全提示,如果没有再进入pyside里面找,IceSpringPySideStubs使用的办法就是提前复写了缺少的属性,利用python后写代码的覆盖特性来实现,因此,我们也可以利用这一点实现某些不能补全提示的属性、方法。
例如,新建一个信号时,调用connect方法并不能补全提示:
解决办法是进入 Signal 定义里面新增
转到定义在类的入口填写 connect = None
注意:如果是属性建议是None,实际上pysid的connect是方法,但这里只是为了提供一个提示,直接作为变量好了,实测不会影响代码运行。也可以使用重写方法
最后得到效果
其他 安装以上插件后,PyCharm依然不能补全提示,原因未知,文档说可以移除PyCharm的pyside框架,但是移除了也不行。
作用域值(Scoped Values)进入孵化阶段
记录模式(Record Patterns)进入第 2 预览阶段
switch 模式匹配(Pattern Matching for switch)进入第 4 预览阶段
外部函数和内存 API (Foreign Function & Memory API)进入第 2 预览阶段
虚拟线程 (Virtual Threads)进入第 2 预览阶段
结构化并发(Structured Concurrency)进入第 2 孵化阶段
向量 API(Vector API)进入第 5 孵化阶段
铁子们,JDK 20 / Java 20 正式发布了,这版本号简直超神了。
JDK 20不仅仅是一个简单的升级。它是一个充满新特性的版本,为Java开发者带来了更多的选择。有了JDK 20,开发者们能够更加轻松地构建复杂的应用程序,同时也能够更好地管理和维护这些应用程序。这个版本不仅包括了一些新的特性,同时还对现有特性进行了改进和优化。
JDK 20 是一个短期维护版本,将获得六个月的支持。也就是说,它将在未来六个月内得到更新和支持。这意味着,如果您正在使用JDK 20,您可以放心地在生产环境中使用它,因为您将得到足够的支持和保障。
根据Java开发计划,下一个LTS版本将于2023年9月发布,即JDK 21。这个版本将是Java的一个重要里程碑,因为它将是一个长期维护版本,将获得长达八年的支持。这意味着,如果您正在寻找一种稳定而可靠的Java版本,JDK 21将是您的不二之选。
此版本包括 7 个 JEP,分别处于不同的孵化和预览阶段。这些 JEP 是 Java Enhancement Proposal 的缩写,它们用于描述 Java SE 平台和 JDK 的增强、新功能和特性。此外,该版本还包括数百个较小的功能增强和数千个错误修复,这些修复涵盖了 Java SE 平台和 JDK 的各个方面。这些增强和修复为 Java 开发者提供了更好的开发体验和更强的稳定性,使得他们能够更加轻松地构建高质量的应用程序: 作用域值(Scoped Values)进入孵化阶段
判断鼠标左右移动的距离 更改backgroundPositionX
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <style> * { padding: 0; margin: 0; } .head { width: 100%; height: 155px; /* background: url('./image/bilibili_head.png'); */ background: url('http://i0.hdslb.com/bfs/archive/5d624c842e091447cf9b679d4cc6ae70d731ea06.png@3840w_360h_1c_90q'); background-position-x: 0px; } </style> <body> <div class="head"></div> </body> <script> var header = document.querySelector('.head') //鼠标移入 header.addEventListener('mouseover', function (event) { var event = event || window.event mouseNumOne = event.clientX }) //鼠标移动 header.addEventListener('mousemove', function (event) { var event = event || window.
文章目录 Linux下Gitea安装和使用 一、本地源码安装1. 准备环境2. 下载源码3. 编译4. 启动5. 站点配置 二、本地源码 + docker mysql 安装1. 源码编译2. 创建gitea_db容器3. 启动和配置 三、docker源码 + docker mysql 安装1. 创建gitea_db容器2. 创建gitea_web容器3. 访问 四、docker-compose 安装1. 准备docker-compose.yml2. 下载3. 启动4. 站点配置5. 迁移(仅适用于同一cpu架构、同一系统) 附 Linux下Gitea安装和使用 一、本地源码安装 1. 准备环境 通过源码编译安装,需要事先安装好
go 1.19 或以上版本node 16 或以上版本,并且安装npmmake:编译工具,一般系统都自带。gcc:c编译工具,一般系统都自带。
其中,node和npm安装参考我另一篇博文:
https://blog.csdn.net/Acegem/article/details/129675519?spm=1001.2014.3001.5502mysql:里面需要创建好一个新库,库名为:gitea 2. 下载源码 下载 https://github.com/go-gitea/gitea 得到gitea-main.zip。
3. 编译 将gitea-main.zip解压后,准备编译。
编译tags可选项:
bindata: bindata: 这个编译选项将会把运行Gitea所需的所有外部资源都打包到可执行文件中,这样部署将非常简单因为除了可执行程序将不再需要任何其他文件。sqlite sqlite_unlock_notify: 这个编译选项将启用SQLite3数据库的支持,建议只在少数人使用时使用这个模式。pam: 这个编译选项将会启用 PAM (Linux Pluggable Authentication Modules) 认证,如果你使用这一认证模式的话需要开启这个选项。 以下为我用的编译方式:
cd gitea-main # 编译 TAGS="
目录
一、介绍常见的操作系统
二、Linux介绍
三、CentOS的安装和配置: 一、介绍常见的操作系统 1、操作系统简介:在编程界中,有数不胜数的操作系统,其中,将主要的几个操作系统在下图中展示出来,其中windows操作系统现在已经更新到了windows11系统。先跟大家介绍什么是操作系统。
2、操作系统定义:操作系统OS(Operating System)是指控制和管理整个计算机系统的硬件和软件资源,并合理地组织调度计算机的工作和资源的分配(从当前层次结构中间往两边看),提供用户和其他软件方便的接口和环境(当前层次结构从下往上看),同时它是计算机系统中最基本的系统软件(层次结构从上往下看)。
3、操作系统四个基本特征:
并发、共享、虚拟、异步。其中并发和共享是最基本的特征,二者互为存在条件。
3.1并发:
两个或多个事件同一时间间隔内发生,这些事件宏观上同时发生,微观上交替发生。
(易混淆概念 并行:指两个或多个事件在同一时刻同时发生)
操作系统的并发性:是指计算机系统中同时存在着多个运行着的程序。
其中在编程界中还有并行这一词,并行和并发这两个词很容易混淆,下面用度娘一张图来给大家解释这两个概念, 并行约会是指:同一时刻同时进行两个约会任务。
并发约会是指:宏观上看,老渣在同时进行两个任务,微观上讲,在某一时刻,老渣最多正在进行一个任务。
3.2共享:
共享即资源共享,是指系统中资源可供内存众多个并发执行的进程共同使用。
3.3虚拟:
虚拟是指把一个物理上的实体变为若干个逻辑上的对应物。物理实体实际存在,而逻辑对应物使用户感受到的
3.4异步:
异步是指多到程序环境下,允许多个程序并发执行,但资源有限,进程的执行不是一贯到底,而是走走停停,以不可预知的速度向前推进,这就是进程的异步性。
二、Linux介绍 1、虚拟机:指通过软件模拟的具有完整硬件系统功能的、运行在一个完全隔离环境中的完整计算机系统。在实体计算机中能够完成的工作在虚拟机中都能实现,在计算机中创建虚拟机时,需要将实体机的部分硬盘和内存容量作为虚拟机的硬盘和内存容量。
2、Linux定义:
Linux是一种自由和开放源码的操作系统,存在着许多不同的Linux版本,但它们都使用了Linux内核。Linux可安装在各种计算机硬件设备中,比如手机、平板电脑、路由器、台式计算机,Linux出现于1991年,是由芬兰赫尔辛基大学学生Linus Torvalds和后来加入的众多爱好者共同开发完成
3、Linux特点:
多用户,多任务,丰富的网络功能,可靠的系统安全,良好的可移植性,具有标准兼容性,良好的用户界面,出色的速度性能去开源。
4、CentOS:
4.1主流:目前的Linux操作系统主要应用于生产环境,主流企业级Linux系统仍旧是 RedHat或者CentOS
4.2免费:RedHat 和CentOS差别不大,基于Red Hat Linux 提供的可自由使用源代 码的企业CentOS是一个级Linux发行版本
4.3更新方便:CentOS独有的yum命令支持在线升级,可以即时更新系统,不像 RedHat 那样需要花钱购买支持服务! 5、安装VMware软件(虚拟机软件):
新建一个英文文件夹,将压缩包放入此文件夹中进行解压,之后就可以进行安装。 三、CentOS的安装和配置: 1、安装步骤:
1.1:要下载一个镜像,当然镜像不是随便下载(接下来会告诉大家下哪一个镜像),CentOS的运行是依赖镜像的。下载之后存储到一个非中文目录之下
1.2:打开VMWARE软件,进行到主界面中,进行创建新的虚拟机
1.3:选择自定义(高级),点击下一步。
1.4:到了安装客户机操作系统时:要选择第二个,这时候选择下载的镜像文件夹
1.5:修改虚拟机的名称和安装路径(此处我没有使用默认的名字和路径)
1.6:处理器配置建议处理器数量为2,内核数量为1,当然这个看个人电脑配置。数量越多,虚拟机的运行速度越快。
1.7:设置虚拟的内存,内存应选择为1024M.
1.8:选择磁盘时就选第一个创建虚拟磁盘。
1.9:指定磁盘的文件一定要新建一个文件夹,千万不能放C盘!!!
1.10:下面会有图示,可按照下面的图示进行安装。
1.1:要下载一个镜像,当然镜像不是随便下载(接下来会告诉大家下哪一个镜像),CentOS的运行是依赖镜像的。下载之后存储到一个非中文目录之下
镜像下载地址:
点击下载就行,注意:一定不要下载到C盘中
1.2:打开VMWARE软件,进行到主界面中,进行创建新的虚拟机
1.3:选择自定义(高级),点击下一步。
1.4:到了安装客户机操作系统时:要选择第二个,这时候选择下载的镜像文件夹
1.5:修改虚拟机的名称和安装路径(此处我没有使用默认的名字和路径)
1.6:处理器配置建议处理器数量为2,内核数量为1,当然这个看个人电脑配置。数量越多,虚拟机的运行速度越快。
1.7:设置虚拟的内存,内存应选择为1024M.
1.8:选择磁盘时就选第一个创建虚拟磁盘。
1.9:指定磁盘的文件一定要新建一个文件夹,千万不能放C盘!!!
2、CentOS配置:
目录
一、介绍stater
1、stater的理念:
2、stater的实现:
3、stater的原理图:
二、 java操作邮件(邮件的使用)
步骤:
1、导入依赖
2、重写yml资源文件
3、写好测试类
4、进行测试
三、邮箱的制作(自定义启动器)
步骤:
1、先导入依赖
2、创建yml文件
获取授权码链接:什么是授权码,它又是如何设置?_QQ邮箱帮助中心
3、创建实体类资源文件
4、定义一个发送接口,并且实现接口
5、进行测试
四、使用邮箱
1、提高邮箱使用灵活性
步骤:
1、导入yml文件注入依赖
2、在resource文件下添加文件
2、将整个项目打包成jar包
3、到之前的项目中导入邮箱依赖(必须使用同一个本地仓库)
4、在测试类中加入注解
5、进行测试:运行成功
五、结合redis实现操作
1、步骤
1、导入操作redis的依赖
2、在applicaion.yml资源文件中加入redis资源
3、将帮助类写入到项目中
4、新建一个实体类和控制类
2、优化邮箱使用
解决方法:
步骤:
一、介绍stater 1、stater的理念: starter会把所有用到的依赖都给包含进来,避免了开发者自己去引入依赖所带来的麻烦。 需要注意的是不同的starter是为了解决不同的依赖,所以它们内部的实现可能会有很大的差异,例如jpa的starter和Redis的starter可能实现就不一样,这是因为starter的本质在于synthesize, 这是一层在逻辑层面的抽象,也许这种理念有点类似于Docker,因为它们都是在做一个“包装”的操作。
2、stater的实现: 虽然不同的starter实现起来各有差异, 但是他们基本上都会使用到两个相同的内容:ConfigurationProperties和AutoConfiguration。 因为SpringBoot坚信“约定大于配置”这一理念,所以我们使用ConfigurationProperties来保存我们的配置, 并且这些配置都可以有一个默认值,即在我们没有主动覆写原始配置的情况下,默认值就会生效,这在很多情况下是非常有用的。除此之外,starter的ConfigurationProperties还使得所有的配置属性被聚集到一个文件中 (一般在resources目录下的application.properties),这样我们就告别了Spring项目中XML地狱。
3、stater的原理图: 注意:其中最关键的是配置文件,用户可以自定义配置文件将自己的邮箱地址写入,以便提高邮箱灵活性
二、 java操作邮件(邮件的使用) 步骤: 1、导入依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> </dependency> 2、重写yml资源文件 spring: application: name: springBoot_06 mail: host: smtp.qq.com username: 自己qq@qq.
#一步一步执行以下命令 sudo apt install git #安装git git --version #查看安装版本号 git config user.name jtr #设置用户名 git config user.email jiangtr@cloudskysec.com #设置邮箱 ssh-keygen -t rsa -C "jiangtr@cloudskysec.com" #生成秘钥,一直往下按回车键就行 出现下图ssh秘钥生成成功。
cat /home/jtr/.ssh/id_rsa.pub # 显示公钥 将公钥拷到gitlab或者GitHub setiing中保存
拉取远端仓库代码
拉取成功
今天先到这,有问题我继续更新。
1、前一段时间想要入手一台笔记本电脑,看了一圈,最后发现淘宝居然有卖二手ThinkPad的商家,价格便宜加上牌子的口碑,我决定试试。考虑重量性能等一系列因素,选择P52S。
2、由于拿回来的电脑只有一块512固态,所以决定加装一块,这样就够用了。
3、经过网上查资料和与商家确认等方式,了解到这个电脑有一个3.5寸硬盘位同时在4g设备位置可以在加装一个2242大小的固态。
4、因为显示已经有了PCIE的固态,我以为空的是3.5寸的位置,然后购入3.5寸硬盘,结果拆开电脑,是这样的
说好的4G位置的固态硬盘呢?瞬间懵逼,最后发现3.5寸硬盘位置已经被改为pcie固态了,并且不是转接的,sata口都没有了,只能将3.5寸硬盘退掉
5、经过深思熟虑决定在4g设备口上加个硬盘,经过网上一堆寻找,找到了西数SN520这个盘。买回来安装,完美运行。如图
总结:ThinkPadP系列还是相当牛逼的,做工很好,有防滚架,这个查保修是澳大利亚那边的,应该是洋垃圾,配置序列号也对的上。希望可以用个五六年,这个应该是改版过,将3.5硬盘拿掉了,如果有相同电脑的同志加硬盘要注意了。
目录
一、SpringBoot介绍
1、定义
2、springBoot简化的配置
3、应用打包
二、springBoot项目搭建
1.新建一个spring initializr项目
2、点击下一步
3、之后一个springBoot项目就构建完成了。
三、自动配置原理与yml注入
1、自动配置原理讲解
1.1 自动配置源码中关键代码
1.2新建一个实体类
1.3在yml文件中,为每个属性名赋值,
2、yml注入
四、多环境配置
1、配置文件讲解:
2、配置文件加载位置
一、SpringBoot介绍 1、定义 Spring Boot是一个广泛用来构建Java微服务的框架,它基于Spring依赖注入框架来进行工作.Spring Boot允许开发人员使用更少的配置来构建微服务,同时框架本身能够尽可能的减少开发人员的冲突.自动化配置,一般情况下都有默认配置提供一组流行的starter依赖,方便开发人员使用简化应用打包自动化配置,一般情况下都有默认配置
2、springBoot简化的配置 在Spring应用中,用户将会使用到不同的技术组件,包括:JDBC数据源(DBCP,Druid)、消息队列(RabbitMQ)、文件系统以及应用缓存(Redis)等.开发人员需要在需要这些功能时,停下来,仔细分析一下自己究竟需要什么?需要的内容属于哪个依赖(“哦,我需要MyBatis依赖”),然后花费大量的时间在依赖组织和排除上.SpringBoot提供了功能(一批jar包依赖)的依赖(starter),它让开发人员声明需要的功能,而不用去关系究竟如何处理依赖关系.
3、应用打包 SpringBoot是一组jar包和符合其约定的配置的构建块,因此它不会运行在现有的应用服务器中,而使用SpringBoot的大多数开发人员更喜欢的是直接运行的这种自包含的jar包。
二、springBoot项目搭建 使用的IDEA版本是2021.3月份的版本,其他版本也是一样的新建项目
1.新建一个spring initializr项目 将服务器url改成start.aliyun.com
2、点击下一步 3、之后一个springBoot项目就构建完成了。 以下是运行项目入口
pom.xml:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.ZJ</groupId> <artifactId>springBoot</artifactId> <version>0.0.1-SNAPSHOT</version> <name>springBoot_01</name> <description>springBoot_01</description> <properties> <java.version>1.8</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <spring-boot.version>2.4.1</spring-boot.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.
路径:
vi /etc/update-motd.d/10-uname 添加内容:
echo "aaa bbb ccc"
下载编译 Index of /releases
以运行调试HTTP库为例,使用vs2010打开samples解决方案(打开解决方案默认是编译32位,添加64位)
添加Foundation项目,并进行编译
修改输出目录..\..\..\bin64
就可以编译运行了
OutPut Directory ,它的值不会直接影响到你文件的输出,但它会间接的影响其他输出,比方说默认值中包含有$(OutDir)
Linker->General->OutPut File,输出文件,虽然填的是exe的路径,但.ilk文件会按这个路径输出.Linker->Debugging->Genrerate Program Database File,输出的pdb文件
发送Http请求
如果需要JSON库,先添加后编译, 同时添加头文件目录 ..\..\..\JSON\include
案例如下,因为工程是unicode编码的
#include "Poco/JSON/Parser.h" #include "Poco/JSON/ParseHandler.h" #include "Poco/JSON/JSONException.h" #include "Poco/StreamCopier.h" #include "Poco/Dynamic/Var.h" #include "Poco/JSON/Query.h" #include "Poco/JSON/PrintHandler.h" #include "Poco/Net/HTTPClientSession.h" #include "Poco/Net/HTTPRequest.h" #include "Poco/Net/HTTPResponse.h" #include "Poco/StreamCopier.h" #include "Poco/Net/NetException.h" #include "Poco/Net/HTMLForm.h" #include "Poco/URI.h" #include <iostream> using namespace Poco::Dynamic; using namespace Poco; using std::string; using namespace Poco::JSON; using namespace Poco::Net; int main() { try { std::string strUrl("
1.unique_ptr
智能指针之unique_ptr(详解)_unique_ptr 函数参数_肥肥胖胖是太阳的博客-CSDN博客
unique_ptr 代表的是专属所有权,即由 unique_ptr 管理的内存,只能被一个对象持有。
所以,unique_ptr 不支持复制和赋值
也不建议让2个unique_ptr指向同一个对象,智能指针释放的时候,会释放2次对象,引起崩溃(会有崩溃):
int *pValue = new int(100); unique_ptr<int> uptrValue(pValue); unique_ptr<int> uptrValue1(pValue); //建议 unique_ptr<int> uptrValue2(new int(100)); std::unique_ptr::release
将智能指针管理的对象释放出去,但是并不删除对象。
unique_ptr作为函数参数(
不可以使用值传递的方式进行函数参数的传递,所以可以将函数定义为
void TestFunc(std::unique_ptr<TestC>& ptrC); 使用引用传递
如果定义为void TestFunc(std::unique_ptr<TestC> ptrC),则使用move来传递参数,如下 #include <stdio.h> #include <memory> using namespace std; #include <iostream> class TestC { public: TestC(int tmpa, int tmpb) :a(tmpa), b(tmpb) { std::cout << "construct TestC " << std::endl; } ~TestC() { std::cout << "destruct TestC " << std::endl; } void print() { std::cout << "
目录
前言:遇到这种问题,从字面意思来讲是因为文件太大,超过了文件的预留长度
一、再现场景:
二、排除错误:
三、解决办法:
1、第一种:修改yml文件中的证书密码:
2、第二种:在依赖中加入maven-resources-plugin组件依赖
前言:遇到这种问题,从字面意思来讲是因为文件太大,超过了文件的预留长度 一、再现场景: 将http请求转变为https请求,再将密钥和yml配置进去之后,启动项目就报错
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled. 2022-07-01 11:59:52.741 ERROR 12360 --- [ main] o.s.boot.SpringApplication : Application run failed org.springframework.context.ApplicationContextException: Failed to start bean 'webServerStartStop'; nested exception is org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat server at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:181) at org.springframework.context.support.DefaultLifecycleProcessor.access$200(DefaultLifecycleProcessor.java:54) at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:356) at java.lang.Iterable.forEach(Iterable.java:75) at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:155) at org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:123) at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:940) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:591) at org.
目录
一、情景再现:
二、分析原因:
三、解决方法: 1、点击启动类编译文件:
2、修改命令行的方式,shorten command line 选项选择 JAR manifest 或者 classpath file 选项,最后apply
3、重新启动即可,运行成功
一、情景再现: 当运行启动类时,报Command line is too long. Shorten command line for xxx or also for Spring Boot default configuration错。
二、分析原因: 主要是命令行太长了,导致项目启动不成功
三、解决方法: 1、点击启动类编译文件: 2、修改命令行的方式,shorten command line 选项选择 JAR manifest 或者 classpath file 选项,最后apply 3、重新启动即可,运行成功
报错信息如下:
npm ERR! code 1 npm ERR! path D:\workspace\exchange\exchange-web\exchange-web-ui\node_modules\node-sass npm ERR! command failed npm ERR! command C:\Windows\system32\cmd.exe /d /s /c node-gyp rebuild npm ERR! gyp info it worked if it ends with ok npm ERR! gyp info using node-gyp@3.8.0 npm ERR! gyp info using node@13.6.0 | win32 | x64 npm ERR! gyp ERR! configure error npm ERR! gyp ERR! stack Error: Can't find Python executable "python", you can set the PYTHON env variable.
方案一、用数据库的超级用户登录数据库,使用查询语句查询 # su - postgres # 这里是切换到操作系统的postgres用户 $ psql # 缺省用户名的情况下,会把当前系统用户名当作数据库登录用户名,数据库的postgres是超级用户 psql (13.2 (Ubuntu 13.2-1.pgdg18.04+1)) Type "help" for help. postgres=# show config_file; -- 查询配置文件所在位置 config_file ----------------------------------------- /etc/postgresql/13/main/postgresql.conf (1 row) postgres=# show data_directory; -- 查询数据储存目录 data_directory -------------------------- /data/postgresql/13/main (1 row) 方案二、使用操作系统root用户查找postgresql进程 # ps -ef|grep postgresql postgres 23746 1 0 Aug31 ? 00:04:40 /usr/lib/postgresql/13/bin/postgres -D /data/postgresql/13/main -c config_file=/etc/postgresql/13/main/postgresql.conf 可以看到-D后面的参数即为数据目录,-c后面的参数即为配置文件所在位置。
转自:https://blog.csdn.net/DongGeGe214/article/details/121489384
数据结构严蔚敏版 第一章笔记 数据结构是什么 数据结构是一门研究非数值计算的程序设 计问题中计算机的操作对象以及它们之间的关系和操作等的学科。
数据结构 (data structure) 是相互之间存在 一 种或多种特定关 系的数据元素的集合。
基本概念和术语 数据 数据 (data) 是对客观事物的符号表示,在计算机科学中是指所有能输入到计算机中 并被计算机程序处理的符号的总称。
数据元素 数据元素 (data element) 是数据的基本单位,在计算机程序中通常作为一个整体进行 考虑和处理。
数据对象 数据对象 (data object) 是性质相同的数据元素的集合,是数据的一个子集。
位 在计算机中表示信息的最小单位是二进制数的一位, 叫做位 bit
结点 元素 以用一个由若干位组合起来形成的一个位串表示一个 数据元素(如用一个字长的位串表示一个整数,用 8 位二进制数表示一个字符等),通常称 这个位串为元素 (j)(element) 或结点 (node) 。
数据域 当数据元素由若干数据项组成时,位串中对应于各个数据项的子位串称为数据域
逻辑结构 结构定义中的“关系”描述的是数据元素之间的逻辑关系
物理结构,存储结构 数据结构在计算机中的表示(又称映像)称为数据的物理结构,又称存储结构
顺序映像 顺序存储 顺序映像的特点是借助 元素在存储器中的相对位置来表示数据元素之间的逻辑关系。
虚拟存储结构 假如我们把 C 语言看成是一个执行 C 指令和 C 数据类型的虚拟处理器,那么本书中讨论的存储结构是数据结构在 C 虚拟处理器中的 表示,不妨称它为 虚拟存储结构 。
数据类型 数据类型 是一个值的集合和定义在这个值集上的一组操作的总称。
4.1 引言 本章将描述文件系统的其他特征和文件的性质。
4.2 函数stat、fstat、fstatat和lstat 4个stat函数:
#include <sys/stat.h> int stat(const char *restrict pathname, struct stat *restrict buf); int fstat(int fd, struct stat *buf); int lstat(const char *restrict pathname, struct stat *restrict buf); int fstatat(int fd, const char *restrict pathname, struct stat *restrict buf, int flag); // 所有4个函数的返回值:若成功,返回0;若出错,返回-1 stat函数返回与pathname命名文件有关的信息结构;fstat函数获得已在描述符fd上打开文件的有关信息;lstat函数类似于stat函数,但在当命名文件是一个符号链接时,返回该符号链接的有关信息,而不是由该符号链接引用的文件的信息;fstatat函数返回一个相当于当前打开目录(fd参数指向)的路径名返回文件统计信息。flag参数控制着是否跟随着一个符号链接,当AT_SYMLINK_NOFOLLOW标志被设置时,fstatat不会跟随符号链接,而是返回符号链接本身的信息,否则,在默认情况下,返回符号链接所指向的实际文件的信息;参数buf是一个stat类型的指针,由函数填充其结构。 4.3 文件类型 UNIX系统的文件类型包括:
普通文件:最常用的类型,包含了某种形式的数据;目录文件:包含了其他文件的名字以及指向与这些文件有关信息的指针;块特殊文件:提供对设备(如磁盘)带缓冲的访问,每次访问以固定长度为单位进行;字符特殊文件:提供对设备不带缓冲的访问,每次访问长度可变;FIFO:用于进程间通信,亦称管道;套接字:用于进程间的网络通信,也可用于在一台宿主机上进程之间的非网络通信;符号链接:指向另一个文件。 文件类型信息包含在stat结构的st_mode成员中,用下表中的宏确定,这些宏的参数为stat成员st_mode。
宏文件类型S_ISREG()普通文件S_ISDIR()目录文件S_ISCHR()字符特殊文件S_ISBLK()块特殊文件S_ISFIFO()管道或FIFOS_ISLNK()符号链接S_ISSOCK()套接字文件 POSIX.1允许实现将进程间通信(IPC)对象说明为文件,下表中的宏可用来从stat结构中确定IPC对象的类型,这些宏的参数为stat结构指针。
宏对象的类型S_TYPEISMQ()消息队列S_TYPEISSEM()信号量S_TYPEISSHM()共享存储对象 4.4 设置用户ID和设置组ID 与每个进程相关联的用户ID和组ID 实际用户ID 标识我们实际上是谁;
在登录时取自口令文件中的登录项;
在登录会话期间不改变,但超级用户可以修改。 实际组ID 有效用户ID 用于文件访问权限检查 有效组ID 附属组ID 保存的设置用户ID 由exec函数保存;
目录
1. 颜色模式
2. 设置颜色
色环允许用户选择一种颜色。颜色的色调、饱和度和值可以分别选择。
长按对象,色环将更改为颜色的下一个参数(色调、饱和度或值)。双击将重置当前参数。
lv_obj_t * lv_colorwheel_create(lv_obj_t * parent, bool knob_recolor); 参数knob_recolor表示是否将旋钮的颜色设置为当前颜色。false和true区别参考下图。
lv_obj_t* wheel = lv_colorwheel_create(lv_scr_act(), false); lv_obj_set_size(wheel, 200, 200); lv_obj_set_align(wheel, LV_ALIGN_CENTER); 1. 颜色模式 颜色有2种方式:RGB或HSV
HSV模式可以 通过lv_colorwheel_set_mode设置
enum { LV_COLORWHEEL_MODE_HUE, LV_COLORWHEEL_MODE_SATURATION, LV_COLORWHEEL_MODE_VALUE }; void lv_colorwheel_set_mode(lv_obj_t * obj, lv_colorwheel_mode_t mode); 可以通过lv_colorwheel_set_mode_fixed固定颜色模式。
void lv_colorwheel_set_mode_fixed(lv_obj_t * obj, bool fixed); 这个模式的设置不太懂什么意思。可以参考:
HSV颜色模型_百度百科 (baidu.com)https://baike.baidu.com/item/HSV%E9%A2%9C%E8%89%B2%E6%A8%A1%E5%9E%8B/21501482?fromtitle=HSV&fromid=547122
2. 设置颜色 根据颜色模式有不同的函数设置颜色,一般应该是用lv_colorwheel_set_rgb
bool lv_colorwheel_set_rgb(lv_obj_t * obj, lv_color_t color); bool lv_colorwheel_set_hsv(lv_obj_t * obj, lv_color_hsv_t hsv);
题目链接总结成绩统计 1. double res2 = (double)b * 100 / n; // int类型的数进行计算需要保留小数时,需要强转为double,否则会直接抹去零头,不会四舍五入 2.四舍五入函数round,头文件cmath 卡片 for (int i = 0; i < 10; i ++) cnt[i] = 2021; // 将数组初始化为某一个非0的数的时候,不能用memset,memset是字节填充,适用于初始化为最大值0x3f3f3f3f,或者初始化为0的情况 购物单 直接计算答案的题目,有大量输入计算,虽然可以通过计算机直接加,但是由于数据太多,容易出错,可以寻找一下数据的规律,写成程序,让计算机来算,可以检查数据输入的正确性,准确率会更高,并且这道题目可以根据将同一个折扣的价格先累加再×同一个折扣,这样减少输入,并且可以快速查询是否有漏乘和多乘的情况。 空间 256MB = 256 * 1024 * 1024 * 8 bit,注意 M是1024 * 1024,而不是10^6,不要搞混了 排序每一趟冒泡排序从左到右,依次扫描,例如:第一趟冒泡排序dcba->cdba->cbda->cbad(第一趟冒泡排序总共交换了3次,依次比较相邻两个数,若逆序,则交换,将序列分成待排序和已有序的两部分,每一趟冒泡排序都能够将待排序部分中最大的那个数移动到有序部分,如果一个长度为n的完全逆序的序列,通过冒泡排序变得有序,需要**(n - 1 + 1) * (n - 1) / 2次交换**;因为第一个数移动到最后一个位置需要n - 1次交换,同理总共需要 n -1 + n - 2 + … + 1次交换。还有一个规律就是,如果一个串完全逆序,例如ihgfedcba,将这个串的第6位 d移动到第一位,串变为dihgfecba,将新的串通过冒泡排序变为有序的交换次数会减少5,并且在所有交换次数减少5的串中,这个新串是字典序最小的那个串。跑步锻炼 日期题目常用模板:int M[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; int getday(int y, int m) //获取某一年的某一个月有多少天 { if (m !
文章目录 激光炸弹空间卡片直线货物摆放时间显示k倍区间 激光炸弹 输入样例:
2 1 0 0 1 1 1 1 输出样例:
1 #include <bits/stdc++.h> using namespace std; const int N=5010; int s[N][N]; int n,m; int main() { int c,r; cin>>c>>r; r=min(5001,r); n=m=r; while(c--) { int x,y,k; cin>>x>>y>>k; x++,y++; n=max(n,x),m=max(m,y); s[x][y]+=k; } //预处理前缀和 for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { s[i][j]+=s[i-1][j]+s[i][j-1]-s[i-1][j-1]; } } int t=0; //枚举全部边长是r的矩形,i,j为右下角 for(int i=r;i<=n;i++) { for(int j=r;j<=m;j++) { t=max(t,s[i][j]-s[i-r][j]-s[i][j-r]+s[i-r][j-r]); } } cout<<t<<endl; return 0; } 空间 本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。
文章目录 前言一、如何查看机器的IP地址二、网卡信息详解1. 网卡名称2. 网络设备状态标识3. IP地址4. MAC地址 三、ifconfig与 ip addr区别 前言 本文记录在linux系统下如何查看ip信息、网卡状态等信息以及简要说明ifconfig命令和if addr命令区别。
一、如何查看机器的IP地址 我们在 Linux 系统查看 IP 地址通常有以下两种方式:
1、ifconfig 命令
2、 ip addr 命令
注:如果在 Windows 系统上,查看 IP 地址的命令是 ipconfig。
这两个命令返回的都是机器的网卡信息,其中包含了网卡的 MAC 地址和 IP 地址,有了这两个地址才能进行网络通信,其中ifconfig命令默认显示当前已启动的网卡信息,而ip addr 会显示当前所有网卡信息,包括已启动和未启动的网卡信息,如果需要显示全部网卡信息需要输入命令ifconfig -a命令。
二、网卡信息详解 1. 网卡名称 ens33 是网卡的名称。
lo 全称是 loopback,又称环回接口,往往会被分配到 127.0.0.1 这个地址。这个地址用于本机通信,经过内核处理后直接返回,不会在任何网络中出现。
一般来说,任何主机都至少有上述2个网卡(或者至少一个lo网卡和以太网卡)。
2. 网络设备状态标识 网卡名称后面为网络设置状态标识,如下图所示
UP 表示网卡处于启动的状态;BROADCAST 表示这个网卡有广播地址,可以发送广播包;MULTICAST 表示网卡可以发送多播包;
以下图片是另外一台服务器的网卡状态标识对比,有UP和RUNNING说明网卡0是处于连接,没有则说明是未启用和连接状态。
3. IP地址 以下这一段代表ipv4 地址信息
inet 192.168.142.130 netmask 255.255.255.0 broadcast 192.168.142.255 4. MAC地址 ether 这一行标识物理mac地址值
题目 输出100 到1000之间的水仙花数。
分析 水仙花数指一个三位数其各位数字的立方和等于该数本身。例如: 153 = 3的三次方+5的三次方+1的三次方。
代码实现 for num in range(100, 500): ge = num % 10 # 个位数 shi = num // 10 % 10 # 十位数 在python中 /与数学计算一样,//表示取整 bai = num // 100 # 百位数 # 判断 if ge ** 3 + shi ** 3 + bai ** 3 == num: print(num) 运行结果 153 370 371 407
目录
一.开发环境
二.主要功能
三.文件结构
四.HDF5写数据到hdf5文件功能实现
五.HDF5读hdf5文件数据到程序中数据结构功能实现
六.头文件Hdf5Function.h
七.工具类
八.主函数测试读写功能
本文基于HDF5官方库,封装了一个简单的常用数据类型的库,HDF5支持的数据类型很多,其中的功能也很强大,但是日常开发中可能常用的包括int、double、string等数据,所以为了简化官方库的使用,自己弄了个小玩意,水平不足,还请见谅。
一.开发环境 Visual Studio2013+配置HDF5环境,也可以直接源码和HDF5库CMake编译。
如何配置HDF5开发环境请参考我的另一篇文章
如何配置HDF5环境
二.主要功能 1.HDF5写int,double,string类型的数据到hdf5文件中;
2.读hdf5文件中int,double,string的数据到程序的数据结构中;
3.写数据生成的hdf5文件名使用当前的时间戳来命名。
三.文件结构 Hdf5Function.hTools.hHdf5WriteValue.cppHdf5ReadValue.cppTools.cpp测试用的主函数main.cpp 四.HDF5写数据到hdf5文件功能实现 创建了类来实现相关功能,完整代码见:
HDF5-ZhaoDaBaoZzz-github.com
#include "Tool.h" #include "Hdf5Function.h" using namespace std; Hdf5WriteValue::Hdf5WriteValue(){}; //构造函数 Hdf5WriteValue::~Hdf5WriteValue(){};//析构函数 /*创建HDF5*/ void Hdf5WriteValue::CreateNewFile() { this->file=H5Fcreate(hdf5_filename().c_str,H5F_ACC_TRUNC,H5P_DEFAULT,H5P_DEFAULT); //H5F_ACC_TRUNC能覆盖,H5F_ACC_EXCL不能覆盖 } /*创建HDF5 String数据维度*/ void Hdf5WriteValue::CreateStringDataspace(const void *data,int rank,int col,int row) { hsize_t dim[2]; dim[0]=row; dim[1]=col; size_t size=sizeof(data)/sizeof(char); this->status=H5Test_size(dtype,size) this->dataspace=H5Screate_simple(rank,dim,NULL); } /*创建HDF5数据维度*/ void Hdf5WriteValue::CreateDataspace(int rank,int col,int row) { hsize_t dim[2]; dim[0]=row; dim[1]=col; this->dataspace=H5Screate_simple(rank,dim,NULL); } /*创建group*/ void Hdf5WriteValue::CreateGroup(string groupName) { this->group=H5Gcreate(this->file,groupName.
Golang 的 datetime 格式化方法并不是其他编程语言中常见的 yyyy-mm-dd hh-mm-ss 类似形式,而是使用 Golang 语言的诞生时间 2006-01-02 15:04:05 -0700 MST 来作为格式化模板。
而在 Golang 的 time 包中,也定义了年、月、日、时、分、秒、周、时区的多种表现形式:
年: 06, 2006月份: 1, 01, Jan, January日: 2, 02, _2时: 3, 03, 15, PM, pm, AM, am分: 4, 04秒: 5, 05周几: Mon, Monday时区: -07, -0700, Z0700, Z07:00, -07:00, MST 参考链接 Golang时间格式化Hugo docs .FormatGolang package time
文章目录 1 下载安装:2 基本折线图3 设置点样式4 Plot Screenshots: Item Demo5 RealtimeDataDemo 1 下载安装: pip install QCustomPlot2 2 基本折线图 效果如下:
#!/usr/bin/env python3 # -*- coding:GBK -*- import os,sys,re from PyQt5.QtWidgets import * from PyQt5.QtCore import Qt,QDateTime from PyQt5.QtGui import QBrush,QPen,QColor import sys,random import QCustomPlot2 from QCustomPlot2 import QCustomPlot,QCP,QCPAxisRect,QCPAxis,QCPGraph class QCustomPlotDemo(QWidget): def __init__(self): super(QCustomPlotDemo, self).__init__() self.resize(600,600) self.setWindowTitle("QCustomPlot折线图Demo") self.layout = QVBoxLayout(self) self.m_plot = QCustomPlot() self.layout.addWidget(self.m_plot) self.x = [ i for i in range(20)] self.
OWOD的代码是基于detectron2库搭建成功的,具体的搭建过程参考Ubuntu下配置detectron2_于大宝0626的博客-CSDN博客过程详细,据此搭建即可。
遇到的问题:
在复现过程中,第一次使用anaconda的镜像建立自己的docker环境,最后运行时出现“path should be string,bytes,os.pathlike or integer,not nonetype”的报错,具体原因是没有CUDA_HOME的路径,试图找到这个路径,得知使用anaconda搭建时相关内容会自动配置,但不可见。第一次复现失败。
第二次使用拉取pytorch镜像的方式搭建docker环境,由于OWOD的git上说明 Python ≥ 3.6,PyTorch ≥ 1.4,所以本次使用的是python3.8,pytorch1.8.0,cuda11.1创建docker环境,最后运行时出现“RuntimeError: radix_sort: failed on 1st step: cudaErrorInvalidDevice: invalid device ordinal”(无效的设备序数)的报错,具体原因是查到可能是pytorch1.8.x的bug,最后使用拉取pytorch/pytorch 1.9.1-cuda11.1-cudnn8-devel镜像搭建docker成功。
获取detectron2时可能会出现命令运行成功却没有找到此文件夹的情况,根本问题还是没下载下来,可以更换官方提供的命令多次尝试。或者网络的问题导致失败。我在下载过程中以上问题均遇到过,耐心尝试即可。(Ubuntu下apt-get方式Git的安装:sudo apt-get update
sudo apt-get install git)
detectron2搭建成功后即可复现OWOD
1.下载OWOD代码。
2.进入项目文件夹(cd OWOD-master),激活环境,输入语句配置detectron
python setup.py build develop 3.下载预训练模型https://github.com/JosephKJ/OWOD/issues/86放在OWOD-master下,找到OWOD-master/configs/OWOD/t1/t1_train.yaml,把预训练模型的文件路径(如果在自己的docker中路径为/workspace_disk/OWOD-master/R-50.pkl,否则报错找不到该文件)替换原文件中weight的内容。
4.下载数据集https://github.com/JosephKJ/OWOD/issues/86(第一行439MB的)
制作数据集:
(1)在OWOD-main中找到datasets文件夹,在这里建VOC2007文件夹
(2)把下载的数据集中的Annotations与JPEGImages文件夹放在VOC2007下(下载的数据集中可能还有其它文件夹,不用管)
(3)在datasets/VOC2007中建ImageSets文件建,在ImageSets中建Main文件夹
(4)将datasets/OWOD_imagesets下的所有文件放到datasets/VOC2007/ImageSets/Main下
5.训练(num-gpus参数可自行调整)
python tools/train_net.py --num-gpus 1 --config-file ./configs/OWOD/t1/t1_train.yaml SOLVER.IMS_PER_BATCH 8 SOLVER.BASE_LR 0.0025 OUTPUT_DIR "./output/t1" 6.后续使用自己的数据集进行训练的过程还会继续记录,未完待续......
其中可能的报错:
(1)ImportError: libGL.so.1: cannot open shared object file: No such file or directory