12、使用JDBC方式访问HIve,启动客户端时报错java.lang.NoClassDefFoundError: org/apache/tez/dag/api/TezConfiguration...

背景 在启动完成hive服务:hive --service metastore后 启动hive2服务的过程中:hive --service hiveserver2时 报错:java.lang.NoClassDefFoundError: org/apache/tez/dag/api/TezConfiguration 分析 我的hive-site.xml配置文件: <?xml version="1.0"?> <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> <configuration> <!-- jdbc 连接的 URL --> <property> <name>javax.jdo.option.ConnectionURL</name> <value>jdbc:mysql://pc001:3306/metastore?allowPublicKeyRetrieval=true&amp;useSSL=false</value> </property> <!-- jdbc 连接的 Driver--> <property> <name>javax.jdo.option.ConnectionDriverName</name> <value>com.mysql.jdbc.Driver</value> </property> <!-- jdbc 连接的 username--> <property> <name>javax.jdo.option.ConnectionUserName</name> <value>root</value> </property> <!-- jdbc 连接的 password --> <property> <name>javax.jdo.option.ConnectionPassword</name> <value>root</value> </property> <!-- Hive 元数据存储版本的验证 --> <property> <name>hive.metastore.schema.verification</name> <value>false</value> </property> <!--元数据存储授权--> <property> <name>hive.metastore.event.db.notification.api.auth</name> <value>false</value> </property> <!-- Hive 默认在 HDFS 的工作目录 --> <property> <name>hive.

如何解决Chrome禁止发送不安全的内网网络请求(ERR_FAILED)(How to fix Chrome block your insecure private network requests)

chrome更新到94之后,会自动阻止发送不安全的内网请求 比如,你从 http://www.website.com 发送请求到 http://192.168.0.1 的时候,就会被阻止,并且报这样的错: net::ERR_FAILED Network Error (Ensure private network requests are made from secure contexts,其实就是让你把服务改成https的) 解决办法,就是关闭这个新特性,不要让它禁用 ①打开Chrome实验功能 在Chrome浏览器地址栏输入,chrome://flags/ ,访问。 或者在地址栏输入:chrome://flags/#block-insecure-private-network-requests ②找到 Block insecure private network requests. 并且禁用。 ③重启浏览器即可

MySql中NOT IN使用时的注意事项

在MySql中,NOT IN是用来查询不在某个值集的数据。 NOT IN的使用需要注意NULL值判断,如果数据库查询出来的字段值为NULL时,NOT IN是走不通的,如: SELECT name, age FROM USER WHERE age NOT IN(12,13) 上面这个sql语句用于查询user表中age不等于12或13的所有用户,如果有一个用户没有添加age信息,此时数据库中该字段为NULL,那么这条数据是查不出来的,如果想要查出age为NULL的数据,可以判空来解决: SELECT name, age FROM USER WHERE IFNULL(age, '') NOT IN(12,13)

Windows下Fortran语言的编译环境之CodeBlocks配置

Fortran编译环境配置(Windows)——CodeBlocks的下载与安装 安装包的下载最新版本的 CodeBlocks 的下载旧版本的 CodeBlocks 的下载 CodeBlocks的安装CodeBlocks的配置配置openmp配置openmp的第一种方法配置openmp的第二种方法 安装包的下载 CodeBlocks官网(https://www.codeblocks.org/)或者点击直接进入:CodeBlocks官网. 最新版本的 CodeBlocks 的下载 第一步:点击Downloads 第二步:点击Download the binary release 第三步:选择相应的版本,本教程选择windows 第四步:选择图中的 codeblocks-20.03mingw-setup.exe 点击后面的Sourceforge.net 开始下载 第五步:出现这个界面就代表已经开始下载啦~ 旧版本的 CodeBlocks 的下载 出现第五步的页面后,会出现下面这个界面,或者点击直接进入:CodeBlocks之前版本下载.(https://sourceforge.net/projects/codeblocks/) (1)点击Files (2)点击Binaries (3)选择自己想要下载的旧版本就可以下载了~ CodeBlocks的安装 第一步:双击之前下载好的文件 (或者以管理员的身份运行) 第二步:点击next 第三步:点击I agree 第四步:点击next 第五步:修改安装的路径(最好不要安装在C盘),之后点击Install 第六步:静等进度条完成 第七步:点击是:计算机会立即启动CodeBlocks 第八步:点击next 第九步:当出现下面的界面就代表你已经初步安装成功了~🙂,点击finish CodeBlocks的配置 第一步:安装完成之后第一次打开CodeBlocks,会出现以下界面,直接点击OK。本来是应该选择GNU Fortran Compiler,由于显示灰色,所以此处无法选择,我们在CodeBlocks界面里面设置(第三步)。 第二步:选择默认(第一个)就好 第三步:Setting > Compiler > 选择GNU Fortran Compiler > Set as default; Toolchain executables > 选择CodeBlocks的安装路径,找到图中的文件夹 > 打开MinGW的文件夹,查看gfortran.exe 的名字,改成与文件夹中的名字一样。之后点击OK 第四步:创建一个Fortran项目,编译,运行之后的效果。如果不报错,就开始你的Fortran语言的学习之旅了~ 配置openmp 配置openmp之前: 下面的代码,运行之后本应该打印出两行 Hello World! ,但是实际上只打印了一行,原因就是没有配置openmp,在CodeBlocks中添加openmp的方法有两种,建议使用第一种,使用第二种可能会失败(建议重复尝试)。

CentOS7 安装vulhub漏洞测试环境

大家好,这周利用几天学习了Docker和Docker-compose及vulhub漏洞测试环境。因为是初次学习和测试这个环境,首先百度搜索了一些相关资料,通过亲测和反复的实践,跟大家分享一些经验和收获。首先,Docker 需要安装在 CentOS 7 64 位的平台,并且内核版本不低于 3.10。CentOS 7 满足最低内核的要求,但由于 CentOS 7 内核版本比较低,部分功能(如 overlay2 存储层驱动)无法使用,并且部分功能可能不太稳定.需要升级到最新的 CentOS 版本,并且内核也更新到最新的稳定版本。 一、Docker安装步骤: 1、 我的经验是第一步最好更新yum包,执行如下命令: #yum update -y 2、安装驱动依赖,执行如下命令: #yum install -y yum-untils device-mapper-persistent-data lvm2 3、使用阿里云里的docker源,执行如下命令: #yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo #yum makecache fast 4、安装docker(默认版本),执行如下命令: #安装默认版本使用这条命令 #yum -y install docker-ce #默认版本安装 5、验证docker安装是否成功,执行如下命令: #docker version 6、设置国内镜像加速,执行如下命令: #vim /etc/docker/daemon.conf #如果没有就自己创建 { "registry-mirrors": [ "https://dockerhub.azk8s.cn", "https://reg-mirror.qiniu.com", "https://registry.docker-cn.com", "http://hub-mirror.c.163.com", "https://3laho3y3.mirror.aliyuncs.com", "http://f1361db2.m.daocloud.io", "https://mirror.ccs.tencentyun.com" ] } 7、重启docker服务,执行如下命令: #systemctl daemon-reload #systemctl restart docker 二、Docker-composer安装,执行如下命令:

QT 自动化 UI 黑盒测试的挑战及解决

最近有一个需求是对QT UI 程序进行黑盒自动化测试. 目标程序 qt 3.X windows 平台 挑战 使用现有的市面上的测试框架无法捕获到 控件的数据. eg: 文本框、按钮 拿不到数据 无法定位点击.各组件使用spy++ 显示 unname 解决 经过排查后 发现 原因是 QT 自绘组件导致的。 QT 自己渲染出了显示结果在屏幕上。 这种情况似乎在QT上还是挺常见的。 说复杂不复杂,说简单还是需要一点工作量: 现在我们的问题是 句柄拿不到数据. 句柄 <=> 我们的代码 <=> QT的数据 QT的控件基本都是Widget作为父类 . 所以我们要获取 需要操作的控件 的 Widget指针. 句柄 => Widget* => 转特定控件指针 => 操作数据 或者 触发动作 先看一下句柄怎么转Widget ,大致步骤如下: Widget* wg = Widget.find(HANDLE hd); QLabel* ql = (QLabel*)wg; getText = ((*ql)+3) getText(); 之所以用 find 是因为 人家管理了所有的子类的HANDLE。 得到 Widget* 后如何知道它属于哪个控件子类的指针?

矩阵分析L2 线性映射与线性变换

一 . 线性映射和线性映射 1.定义 线性映射体现在一个向量空间中满足两个合向量的映射等于两个向量映射的和,以及数乘后的映射等于映射后的数乘 线性变换是基于线性映射的一种特例,也就是在自身空间的映射。 2.例子 不带乘除的变换 相似变换 微分变换和积分变换 二.同构 同构其实就是特殊化的线性映射,特殊在与其要求一一对应,分析同构要先写出对应关系p。 根据同构的思想我们可以把3D中的线性变换问题转换为坐标运算问题,可以为图形学变换提供直观的表现工具 三.线性映射 1.线性映射的矩阵表示 V(F)到W(F)的映射为V空间坐标基下的向量经过线性映射后再由W坐标基来表示,由于是V中的每一个向量由右边的一组向量基来表示,所以左边应该左乘一个线性映射矩阵,使得V中每一个向量都可由右边的向量组表示;反之,要想用W中的向量组来表示左边的每一个向量,只有将右乘映射矩阵,生成一个包含W空间所有基的向量组 注意这里是A的转置 2.线性映射的坐标计算 注意,线性映射的坐标变换是在基的映射的基础上得到的 3.例题(不同线性空间的线性映射) 注意:黄色部分为R4的基到R3的基的映射矩阵,每一列为R4中基映射到R3中基后对应的表示系数 下图为得到R4中向量到R3中向量的一般表示 下面代入具体的例子 四.线性变换 1.线性变换的矩阵表示 和线性映射唯一的区别在于没有基变换。 2.例题(线性变换矩阵) 首先得到变换的像 然后得到变换矩阵 3.例题(变换矩阵) 注意与映射矩阵的区别 首先得到映射矩阵At 然后根据在基I上的变换方程再利用过渡矩阵将在基I的变换方程得到基II的上变换矩阵。 也可以理解线性映射其实有两步,第一步是变换到基II上,第二步是将映射直接在基II上进行,也就是题目描述 4.线性变换的性质 5.线性变换的运算 注意这里像和核的概念 6.例题(像和核) 也就是线性变换后得到一个新的向量组再进行相关判定 五.线性变换的特征值与特征向量 1.概念 2.线性变换的特征值与特征向量的求法 3.例题(变换矩阵的特征向量和特征值) 4.特征子空间 5.不变子空间 特征子空间是一种不变子空间 可以将一个空间分为多个不变子空间,每个不变子空间有最近的映射矩阵 如果特征子空间为一维,那么得到一个对角矩阵

Android 按键事件流程

#号键 的处理流程 keyCode=18, scanCode=228 1.linux kernel阶段 scanCode=228 0001 00e4 00000000 14*16 224+4=228 内核驱动层发送 输入事件 228 /vendor/etc/remote.tab1 0x96 0x55 #TELECOM_VOICE 添加一个按键 0x96 代表扫描码 0x55 输入事件的值,也是上层的扫描码 2.input 服务 /vendor/usr/keylayout/Vendor_0001_Product_0001.kl #key 228 POUND key 228 CALL 228对应的是 POUND 把228 POUND改为 228 CALL 得到的键值变为 keyCode=5 3.framework的处理 查表 POUND 的键值是 18 static const KeycodeLabel KEYCODES[] = { { "SOFT_LEFT", 1 }, { "SOFT_RIGHT", 2 }, { "HOME", 3 }, { "BACK", 4 }, { "

nvidia-smi Failed to initialize NVML: Driver/library version mismatch

提示:1、不是必须使用本命令,请不要删除现有NVIDIA驱动操作; 2、下面的图片可以忽略不看,仅仅是举例,对着代码傻瓜式操作即可。 一:问题描述二:查看kernel和驱动的版本是否匹配三:删除现有显卡驱动,目标让其与内核版本一致四:安装过程五:查看结果 一:问题描述 刚开始学习GUP教程,书本上说在命令行执行命令nvidia-smi可以管理和监控GPU设备,并允许查询和修改设备状态。 于是我便上机操作,结果显示nvidia-smi无法初始化NVML, 下图所示: 二:查看kernel和驱动的版本是否匹配 执行命令:cat /proc/driver/nvidia/version ,查看内核版本为:460.73.01 ,如下图 执行命令 : sudo dpkg --list | grep nvidia-* ,查看NVIDIA驱动版本为:465,见下图 三:删除现有显卡驱动,目标让其与内核版本一致 1、卸载命令位置/usr/bin/nvidia-uninstall: 执行命令:sudo /usr/bin/nvidia-uninstall 2、清除nvidia相关的软件: 卸载n卡附加驱动:sudo apt-get –purge remove nvidia-* 执行命令2:sudo apt-get autoremove* (重要步骤,系统可能会提示) 四:安装过程 在线更新 1、采用ppa安装方式:sudo add-apt-repository ppa:graphics-drivers/ppa 2、获得最近的软件包的列表:sudo apt-get update 安装适合自己内核的版本,我的是460版本 3、apt install nvidia-utils-460-server 4、apt install nvidia-driver-460-server 因为已经删除了nvidia驱动的数据所以执行nvidia-sim一定无法获取结果,但是会推荐你安装版本,此时找到适合你的内核的版本就好了,我这里随机选择了(下图标红3)的nvidia-utils-460-server版本进行安装,安装完之后又安装了推荐的(下图标红4)nvidia-driver-460-server版本。 网上推荐的安装命令为:sudo apt-get install nvidia-460,出现下面的问题: E: 无法定位软件包 nvidia-460nvidia-smi 五:查看结果 新版本查看:dpkg --list | grep nvidia-* 执行命令:nvidia-smi 成功

MySQL 中 You can‘t specify target table ‘表名‘ for update in FROM clause错误解决办法

这里写自定义目录标题 问题解释:不能在更新或删除的sql里嵌套子查询 错误sql: delete from ent_role_user where (user_code ,role_code, tenant_code ) in ( select user_code ,role_code,tenant_code from ent_role_user where user_code = #{userName} and tenant_code = #{tenantCode} and warehouse_code != '' and warehouse_code is not null and role_code in (select role_code from ent_role where role_type =false ) ) and warehouse_code != '' and warehouse_code is not null 解决办法:中间加一个中间表 delete from ent_role_user WHERE (user_code,role_code,tenant_code) IN ( SELECT a.user_code,a.role_code,a.tenant_code FROM( SELECT user_code,role_code,tenant_code FROM ent_role_user WHERE user_code = #{userName} AND tenant_code = #{tenantCode} AND warehouse_code !

不能将类型“{ title: string; dataIndex: string; width: number; align: string;}分配给类型“(ColumnGroupType<any>“

antd表格中ts报错 不能将类型“({ title: string; dataIndex: string; width: number; align?: undefined; render?: undefined; } | { title: string; width: number; align: string; render: (text: any, records: any) => Element; dataIndex?: undefined; })[]”分配给类型“(ColumnGroupType<any> | ColumnType<any>)[]”。 不能将类型“{ title: string; dataIndex: string; width: number; align?: undefined; render?: undefined; } | { title: string; width: number; align: string; render: (text: any, records: any) => Element; dataIndex?: undefined; }”分配给类型“ColumnGroupType<any> | ColumnType<any>”。 重点:属性“align”的类型不兼容。不能将类型“string”分配给类型“AlignType | undefined”。 修改:

jenkins部署前端react项目(docker)

在docker里运行jenkins: docker run ^ --rm ^ -u root ^ -p 8080:8080 ^ -v jenkins-data:/var/jenkins_home ^ -v /var/run/docker.sock:/var/run/docker.sock ^ -v /D/source/jenkins:/home ^ jenkinsci/blueocean 第一次安装jenkins,需要安装jenkins的要求填写admin的密码,安装推荐的插件,另外还要安装两个插件: Docker、Docker PipeLine。 将前端项目提交到github上。 .dockerignore: node_modules .env.jenkins: // .env.test NODE_ENV=production REACT_APP_MODE=test BUILD_PATH= build app.js: const express = require('express') const { createProxyMiddleware } = require('http-proxy-middleware') const app = express() app.use(express.static('build')) //通过代理解决跨域 app.use( '/api', createProxyMiddleware({ target: 'http://localhost:81', changeOrigin: true, }) ) app.listen(process.env.PORT, () => { console.log(process.env.PORT) }) JenkinsFile: pipeline { agent { docker { image 'node:12' args '-p 3002:3002' } } environment { CI = 'true' } stages { stage('install') { steps { sh 'yarn' } } stage('Build') { steps { sh 'yarn build_jenkins' } } stage('server') { steps { sh 'yarn server' } } } } package.

AttributeError: ‘str‘ object has no attribute ‘open‘

from PIL import Image 开头用了这一句,写了一个函数,其中有句 original_img=Image.open(all_bio_image) 在调用的时候出现了问题,发现是调用的代码中使用了Image同Image.open冲突了,无法识别,所以把同名的换掉。问题解决。

倒计时(比如,距离中秋节还有几天几小时几分钟几秒)

<!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> <body> <h1 id="h"></h1> <script> var date = new Date('2021-9-9 18:0:0') //(输入指定的时间) djs(date) var t = setInterval(function () { djs(date) }, 1000) function djs(date1) { console.log(date1); var date2 = new Date(); // 时间可以求减法 得到的是毫秒数 var gap = parseInt((date1 - date2) / 1000); console.log(gap); var hour = parseInt(gap / 3600); var min = parseInt(gap % 3600 / 60);

移动端适配常见坑

一、iphoneX刘海和底部遮挡 问题:iphoneX的刘海会遮挡页面,底部的滚动条也可能会遮挡页面。横屏时除了左侧和右侧有遮挡,底部也有遮挡。 解决:给被遮挡处留出一小块空白区域。 实现:meta标签里content属性中添加viewport-fit=v=cover, 配合给body加上样式: 二、1px适配方案 三、图片模糊问题 问题:在电脑上1px的像素,呈现到手机时会根据设备像素比变成2px或3px,图片被放大了。 解决:准备不同大小的图片,根据设备像素比进行更换。 实现: 四、遮罩后的背景滚动 问题:在弹窗遮罩上滑动时,遮罩后面的背景在滚动。 解决:在遮罩出现时,给背景添加position:fixed; 高度设置为当前高度 五、键盘唤起时底部fixed的东西会跟着内容滚动 问题:键盘唤起时底部fixed的东西会跟着内容滚动。 解决:给内容添加overflow-y:scroll;限制只有内容滚动而不是整个页面滚动。 实现: 六、webApp操作 七、移动端默认样式 八、flex布局的子元素height不起作用 在iphone6中,发现某个flex子元素的height属性不起作用,元素被挤压。 查看后发现 由于子元素默认有flex-shrink:1;当空间不够时进行收缩,所以仅需要将flex-shrink设置为0,空间不够时不让收缩即可,此时height正常。

LeetCode链表刷题

一、判断是否为环形链表 LeetCode141题:环形链表 解题思路 :快慢指针 设置两个指针,一个每次走一步称为慢指针,另一个每次走两步称为快指针。 当链表无环的时候,快指针会先到达链表末尾。 当链表有环的时候,两个指针走着都会在环里循环的走,终会相遇于某个节点。 代码实现 /** * Definition for singly-linked list. * function ListNode(val) { * this.val = val; * this.next = null; * } */ /** * @param {ListNode} head * @return {boolean} */ var hasCycle = function(head) { if(head == null) { return false; } let fast =head, slow = head; while(fast && fast.next) { slow = slow.next; fast = fast.next.next; if(slow === fast) { return true; } } return false; }; 二、判断是否为环形链表并确定环的起点 LeetCode142题:环形链表II 解题思路:快慢指针 当有环时,

递归与栈刷题

一、化栈为队列 LeetCode03.04题:化栈为队列 解题思路 设置两个栈s1和s2来模拟一个队列,s2负责入队,s1负责出队; 当s1为空时,如果s2不为空,则将s2中的内容出栈,再入栈到s1; 代码实现 // 实现一个栈 class Stack { constructor() { this.stack = [] } push(x) { this.stack.push(x); } pop() { if(this.empty()) return; let top = this.top(); this.stack.pop() return top; } top() { return this.stack[this.size()-1] } empty() { return this.stack.length == 0; } size() { return this.stack.length; } } // 两个栈实现一个队列 /** * Initialize your data structure here. */ var MyQueue = function() { // 创建两个栈 this.s1 = new Stack(); this.

GIS技巧100例20-Excel度分秒转十进制度

今天继续《GIS技巧100例》 GIS技巧100例20-Excel度分秒转十进制度 Excel涉及的公式 =LEFT(B2,FIND("°",B2)-1)*1+MID(B2,FIND("°",B2)+1,2)/60+MID(B2,FIND("'",B2)+1,LEN(B2)-FIND("'",B2)-1)/3600 GIS技巧100例子—20Excel度分秒转十进制度 推荐学习: ArcGIS之模型构建器(ModelBuilder)视频教程 ArcGIS10.X入门实战视频教程(GIS思维) ArcGIS之遥感影像分类及成果应用视频课程 ArcPy结合数据驱动模块的批量制图 ArcGIS之Data Reviewer空间数据质量检查 GIS思维GIS系列技术课程

SQL SERVER 2008R2(provider: SQL 网络接口, error: 25 - 连接字符串无效) (.Net SqlClient Data Provider) 错误处理

最近遇到个奇怪的问题,一般同样的版本,我们以SQL Server 身份验证登录时,服务器名称的写法是: Server Name\Instance Name,登录名:sa,密码:******, 服务器类型:数据库引擎。--这样绝大多时候是按这样格式登录的。 但是这次有台服务器却登录报错: 然而但出现这个问题时,只用计算机名登录即可解决,必须保证相关服务有启动。 注:此方法在是在SQL Server 2008R2 上验证可行,其他发行版本同样值得一试。 --上图中,明显服务器名称就是实际的操作系统显示的"计算机名",后面并没有跟“\实例名”。只有这样才可以登录成功。比较奇怪,不知道是什么原因导致的? --扩展:还有可能遇到下面的错误: 问题详细:连接测试失败!:在与 SQL Server 建立连接时出现与网络相关的或特定于实例的错误。未找到或无法访问服务器。请验证实例名称是否正确并且 SQL Server 已配置为允许远程连接。 (provider: 命名管道提供程序, error: 40 - 无法打开到 SQL Server 的连接)。 本机配置:Win7系统,SQL Server 2008 R2 数据库,在360浏览器测试使用G2服务测试数据库连接。 首先查看了数据库已经允许远程连接,数据库连接字符串也填写正确。PS:连接朋友数据库正常。 在网络上搜索了一些答案。 其中,第一种方法: 运行中输入services.msc,查看SQL有关服务是否全部开启。 启动所有可以启动的SQL相关服务完毕,仍未解决问题。 第二种方法: 设置配置管理器中TCP/IP,端口设置为默认的1433。 结果SQLEXPRESS的协议设置为1433后,重启SQL Server (SQLEXPRESS)出现错误。 然后就不能再启动了。 最后找了相关资料,所做的设置有: 更改SQL Server (SQLEXPRESS)TCP/IP 其中8099是任意设置的端口(后面还要在防火墙设置)也可以是默认的1433端口。 这时可以启动SQL Server (SQLEXPRESS) 在控制面板打开防火墙,点击高级设置。 点击入站规则,新建规则 选择端口,下一步 输入之前的端口8099,下一步 默认允许连接,下一步 默认,下一步 输入名称8099(可任意命名),完成。 回到高级设置界面 数据库测试成功 参考:https://blog.csdn.net/crazygolf/article/details/30248535 https://docs.microsoft.com/zh-cn/troubleshoot/sql/connect/resolving-connectivity-errors#configuring-firewalls

QTextedit获取行数和每行字符

QString qstrAll(""); QString qstrPlainText = ui->editUnit->toPlainText(); QTextDocument* pDocument = ui->editUnit->document(); QTextBlock block = pDocument->begin(); while (block.isValid() && block.layout()) { QString qstrBlock = block.text(); QTextLayout* pLayout = block.layout(); int ctBlockLine = pLayout->lineCount(); for (int i = 0; i < ctBlockLine; ++i) { QTextLine line = pLayout->lineAt(i); int nStart = line.textStart(); int nLen = line.textLength(); QString qstrBlockLine = qstrBlock.mid(nStart, nLen); qstrAll += qstrBlockLine; } block = block.next(); } 参考:https://www.imooc.com/wenda/detail/522220

c++之dll动态调用

以下是小可关于c++动态调用的理解有不对之处希望大家指正 配合测试动态库代码 #ifndef DLLDEMO_H #define DLLDEMO_H #if defined(WIN32) || defined(_WIN32) #ifdef MYDLLEXPORT #define API_DLLEXPORT extern "C" __declspec(dllexport) #else #define API_DLLEXPORT extern "C" __declspec(dllimport) #endif #else #define API_DLLEXPORT extern "C" __attribute__((visibility("default"))) #endif API_DLLEXPORT int sum(int a, int b); #endif // !DLLDEMO_H #define MYDLLEXPORT #include "dlldemo.h" API_DLLEXPORT int sum(int a, int b) { return (a + b); } windows下编译为dlldemo.dll,linux下编译为libdlldemo.so 现在测试库有了就可以写测试代码了。 测试代码 #include <iostream> #define LOG_VAR(a) {std::cout <<(#a)<<": "<< (a)<<"\n";} #include <string> #ifdef _WIN32 #include <windows.

定时任务线程池ScheduledThreadPoolExecutor的使用

1. ScheduledThreadPoolExecutor介绍 ScheduledThreadPoolExecutor继承自ThreadPoolExecutor。它主要用来在给定的延迟之后执行任务,或者定期执行任务。通常使用工厂类Executors来创建。 ScheduledThreadPoolExecutor的功能与Timer类似,但比Timer更强大,更灵活,Timer对应的是单个后台线程,而ScheduledThreadPoolExecutor可以在构造函数中指定多个对应的后台线程数。 2.ScheduledThreadPoolExecutor的两种类型 ScheduledThreadPoolExecutor:执行并行任务也就是多条线程同时执行。 SingleThreadScheduledExecutor:执行单条线程。 2.1. ScheduledThreadPoolExecutor 使用Executors创建ScheduledThreadPoolExecutor的方法构造如下: public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) { return new ScheduledThreadPoolExecutor(corePoolSize); } public static ScheduledExecutorService newScheduledThreadPool( int corePoolSize, ThreadFactory threadFactory) { return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory); } 2.2. SingleThreadScheduledExecutor 使用Executors创建SingleThreadScheduledExecutor的方法构造如下: public static ExecutorService newSingleThreadExecutor() { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>())); } public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), threadFactory)); } 2.

渗透测试之域名搜集方法总结

前言: 在渗透测试项目中,外网的信息收集是至关重要的一个环节,外网打点信息收集全面了,可能会有四两拨千斤效果,直接突破外网边界进入内网。 子域名是域名信息收集的一个重要部分,在防御措施严密情况下我们无法直接拿下主域名,那么就可以采用迂回战术拿下子域名,然后无限靠近主域名。 戳此获取网络安全资源 一、方法原理介绍 1、利用证书透明度收集子域 原理: 引用谷歌的项目介绍:“要向用户提供加密流量,网站必须先向可信的证书授权中心 (CA) 申请证书。然后,当用户尝试访问相应网站时,此证书即会被提供给浏览器以验证该网站。近年来,由于 HTTPS 证书系统存在结构性缺陷,证书以及签发证书的 CA 很容易遭到入侵和操纵。Google 的证书透明度项目旨在通过提供一个用于监测和审核 HTTPS 证书的开放式框架,来保障证书签发流程安全无虞。” 那么,通过这样的证书透明度项目,我们就可以在其中获取一些有价值的域名。 实现方法:访问以下链接搜索需要查询的域名如:tencent.com (1)crtsh:https://crt.sh/ (2)facebook:https://developers.facebook.com/tools/ct (3)entrust:https://www.entrust.com/ct-search/ (4)certspotter:https://sslmate.com/certspotter/api/ (5)spyse:https://spyse.com/search/certificate (6)censys:https://censys.io/certificates (7)google: https://google.com/transparencyreport/https/ct/ 2、常规检查收集子域 2.1 域传送 原理: 域传送操作是指备用服务器向主服务器查询来刷新自己的Zone数据库,保证数据一致性。此操作的目的是为了防止主域名服务器因意外故障变得不可用时影响到全局。正常情况下,只有在网络里存在备用域名 DNS 服务器时,DNS区域传送操作才有必要执行。一旦DNS服务器被错误地配置成任何人发出请求,都向其提供Zone数据库的拷贝,就会被攻击者利用。 实现方法: 1.dig命令 如dig @ns2.xxx.com xxx.com axfr ns2.xxx.com为提供数据的服务器,xxx.com为要传输的关键字,axfr为区域传输选项。 2.python中dns库 xfr = dns.query.xfr(where=server, zone=self.domain, timeout=5.0, lifetime=10.0) zone = dns.zone.from_xfr(xfr) 存在问题: 一般情况下,DNS服务器都配置正确,关闭了dns传输或设置了白名单,漏洞利用成功的概率较低。 2.2 站点配置文件 原理: 信息泄露问题主要就是某域名下的一些文件会存储与其相关的一些域名,如子域名。此类文件包括跨域策略文件crossdomain.xml, sitemap文件。 实现方法: 建立文件列表,拼接域名后直接访问,判断改文件是否存在。若存在则提取数据,若不存在则跳过。 1. crossdomain.xml文件 直接访问crossdomain.xml路径 2. sitemap文件 直接访问sitemap.xml、sitemap.txt、sitemap.html、sitemapindex.xml、sitemapindex.xml路径 存在问题: 文件往往不存在,即使存在,域名信息也不够多不够完全。 2.3 检查内容安全策略

distinct 和 order by 使用时注意事项

distinct 和 order by 使用时注意点: 案例:查询最近登录的2个不同的用户 表中的数据如下 sql语句 按照时间倒序:select a.login_time, a.nike_name from test_data a order by a.login_time desc; 按照上面的结果我们把nick_name去除重复后取出前两条使用limit 2: select DISTINCT a.nike_name from test_data a order by a.login_time desc limit 2; 发现结果不对,应该输出: wangWu, liSi。 分析问题 sql 语句优先级, where > group by > having > order by > select > limit 所以导致该sql select DISTINCT a.nike_name from test_data a order by a.login_time desc limit 2; 取出数据不正确性。 分析sql执行流程 1: 首先查询全表 2: order by a.

Red Hat 7安装社区版MySql

1、查看服务器版本信息 cat /etc/redhat-release cat /proc/version 2、然后根据版本去mysql官网下载安装包 下载地址(点击跳转) 选择这个整体的包 以下操作以:社区办-mysql-5.7.35版本为例 3、解压压缩包 下载完后会得到这样一个tar的压缩包 mysql-5.7.35-1.el7.x86_64.rpm-bundle.tar 使用解压命令解压 tar -vxf mysql-5.7.35-1.el7.x86_64.rpm-bundle.tar -v:可视化输出 -x:解压 -f:指定解压文件 解压后得到多个*rpm文件,文件解释如下: 4、安装时候会提示与已经安装的RPM包有冲突,所以我们先卸载一些RPM包,要卸载哪些呢?我们要卸载的是包含有mariadb关键字的RPM包,执行命令: 有多少就删多少 [chenguo@chenguo local]$ rpm -qa|grep mariadb mariadb-libs-5.5.41-2.el7_0.x86_64 [chenguo@chenguo local]$ su - [root@chenguo ~]# rpm -e mariadb-libs-5.5.41-2.el7_0.x86_64 --nodeps 5、安装命令 sudo yum install mysql-community-{server,client,common}-* mysql-community-libs-5.7.35-* 6、启动 sudo service mysqld start 7、超级用户已经创建,其密码存储在错误日志文件中,使用下面命令获取临时的超级用户密码 sudo grep 'temporary password' /var/log/mysqld.log [root@IT-P-taskDB software]# sudo grep 'temporary password' /var/log/mysqld.log 2021-09-24T07:34:12.558775Z 1 [Note] A temporary password is generated for root@localhost: yok-wlj&q9St 忘记密码的情况

django调试问题django.core.exceptions.ImproperlyConfigured

django项目调试子应用app时提示缺少配置 1、项目的settings文件里面设置的有子app,依旧提示下面问题。 django.core.exceptions.ImproperlyConfigured: Requested setting INSTALLED_APPS, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings. 需要在 子app调试的文件头部 显式的指明配置文件是哪个文件 setdefault 的value 设置你自己项目配置文件的路径 import os import django os.environ.setdefault('DJANGO_SETTING_MODULE', 'djangoProject.settings') django.setup() 2、此时 提示的报错发生了变化。提示 django.core.exceptions.ImproperlyConfigured: Requested setting LOGGING_CONFIG, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings. 可以把当前的setting文件的debug设置为True 即可跳过此项配置 django.setup()要放在修改配置的后面 项目可以正常调试了 3、单独启动子app可能会导致django model找不到app model里面Meta选项

哈工大pyltp库安装的踩坑经历—windows10+python3.8

经过折腾近两天,终于在windows10+ python3.8环境下安装成功! 特此记录一下,希望能给后来人减少一些时间上的浪费。 目录 一、安装后的结果: 1、pip list 显示安装成功 2、分词测试结果: 3、结果分享: 二、安装过程 1、pip直接,失败,各种红字错误 2、源码安装——失败 3、制作安装包 三、最终结果 1、最终结果出来了! 2、结果验证: 一、安装后的结果: 1、pip list 显示安装成功 2、分词测试结果: 3、结果分享: 把最终whl安装包分享给大家, pyltp-0.2.1-cp38-cp38-win_amd64.whl-机器学习文档类资源-CSDN文库 (资源刚上传完,显示等待审核,不知道审核完之后地址会不会改变) 4、版本说明: 虽然资源显示的是0.2.1版本,但是是使用0.4.0源码编译的,对应资源: pyltp 版本:0.4.0LTP 版本:3.4.0模型版本:3.4.0 二、安装过程 最近要做一些NLP分析,于是根据网上的推进信息选择了安装pyltp库,开始动手之前看了一下基本教程感觉不复杂,谁知道真正去安装的时候,才发现坑有点大啊…… 安装期间参考了很多网上能找到的教程,但是基本都是大同小异,就像复制粘贴的…… 最终还是参考:GitHub - HIT-SCIR/pyltp: pyltp: the python extension for LTP 和 GitHub - HIT-SCIR/ltp: Language Technology Platform 进行安装。 所有教程都是基于python3.5和3.6版本的,基本连3.7版本的都很少,3.8的基本没有找到。 1、pip直接,失败,各种红字错误 pip install pyltp 安装vc 14.0之类的也还是没有任何作用,折腾几个小时,放弃了…… 2、源码安装——失败 $ git clone https://github.com/HIT-SCIR/pyltp $ cd pyltp $ git submodule init

【Java自用】集合练习题:TreeSet的自然排序与定制排序

定义一个 Employee 类。 该类包含:private 成员变量 name,age,birthday,其中 birthday 为MyDate 类的对象;并为每一个属性定义 getter, setter 方法;并重写 toString 方法输出 name, age, birthday。 MyDate 类包含: private 成员变量 year,month,day;并为每一个属性定义 getter, setter 方法; 创建该类的 5 个对象,并把这些对象放入 TreeSet 集合中 分别按以下两种方式对集合中的元素进行排序,并遍历输出: 1). 使 Employee 实现 Comparable 接口,并按 name 排序 2). 创建 TreeSet 时传入 Comparator 对象,按生日日期的先后排序。 Employee.java 使 Employee 实现 Comparable 接口,并按 name 排序 package com.atguigu.exer1; /* * * 该类包含:private 成员变量 name,age,birthday,其中 birthday 为MyDate 类的对象; * 并为每一个属性定义 getter, setter 方法; * 并重写 toString 方法输出 name, age, birthday * @author WanZi * @create 2021-09-24 11:45 */ public class Employee implements Comparable{ private String name; private int age; private MyDate birthday; public Employee() { } public Employee(String name, int age, MyDate birthday) { this.

解决ubuntu软件中心无法安装软件的方法

解决ubuntu软件中心无法安装软件的方法 当用ubuntu软件下载中心安装某个软件的时 比如我安装typora的时候报错“unable to install typora: status-code=409 kind=snap-change-conflict message=snap"typora"has "install-snap"change in progress 不用担心,打开终端,查看当前的状态 :~$ snap changes ID Status Spawn Ready Summary 1 Done 2021-02-10 tomorrow at 01:05 CST Initialize system state 3 Error today at 09:39 CST today at 09:49 CST Install "clion" snap from "latest/stable" channel 4 Done today at 09:49 CST today at 09:52 CST 自动刷新 5 个 snap 5 Done today at 09:53 CST today at 10:05 CST Install "

freertos内存pvPortMalloc 和 malloc 区别 ,以及全局变量占用情况

1.FreeRtos占用内存 #define configTOTAL_HEAP_SIZE ( ( size_t ) ( 30 * 1024 ) ) pvPortMalloc是从configTOTAL_HEAP_SIZE中申请内存,作为ZI-data被编译。 malloc是直接从SRAM 堆 中申请内存,是和全局变量一个地位。 2.芯片占用情况 RO-data是 Read Only 只读常量的大小,如const型;RW-data是(Read Write) 初始化了的可读写变量的大小;ZI-data是(Zero Initialize) 没有初始化的可读写变量的大小。ZI-data不会被算做代码里因为不会被初始化; FLASH:Code + RO-Data + RW-Data SRAM: RW-Data + ZI-Data 3.全局变量的占用 定义未初始化未使用 : 不占空间 char a[1000]; int main() { } 定义未初始化并使用: 占用ZI-Data char a[1000]; int main() { memset(a, 0, sizeof(a)); } 定义初始化: 不管用不用,都占用RW-Data char a[1000] = "hello"; int main() { //memset(a, 0, sizeof(a)); }

线程池参数

一、ThreadPoolExecutor核心参数说明 1、corePoolSize:核心线程数 * 核心线程会一直存活,及时没有任务需要执行 * 当线程数小于核心线程数时,即使有线程空闲,线程池也会优先创建新线程处理 * 设置allowCoreThreadTimeout=true(默认false)时,核心线程会超时关闭 2、queueCapacity:任务队列容量(阻塞队列) * 当核心线程数达到最大时,新任务会放在队列中排队等待执行 3、maxPoolSize:最大线程数 * 当线程数>=corePoolSize,且任务队列已满时。线程池会创建新线程来处理任务 * 当线程数=maxPoolSize,且任务队列已满时,线程池会拒绝处理任务而抛出异常 4、 keepAliveTime:线程空闲时间 * 当线程空闲时间达到keepAliveTime时,线程会退出,直到线程数量=corePoolSize * 如果allowCoreThreadTimeout=true,则会直到线程数量=0 5、allowCoreThreadTimeout:允许核心线程超时 6、rejectedExecutionHandler:任务拒绝处理器 * 两种情况会拒绝处理任务: - 当线程数已经达到maxPoolSize,切队列已满,会拒绝新任务 - 当线程池被调用shutdown()后,会等待线程池里的任务执行完毕,再shutdown。如果在调用shutdown()和线程池真正shutdown之间提交任务,会拒绝新任务 * 线程池会调用rejectedExecutionHandler来处理这个任务。如果没有设置默认是AbortPolicy,会抛出异常 * ThreadPoolExecutor类有几个内部实现类来处理这类情况: - AbortPolicy 丢弃任务,抛运行时异常 - CallerRunsPolicy 执行任务 - DiscardPolicy 忽视,什么都不会发生 - DiscardOldestPolicy 从队列中踢出最先进入队列(最后一个执行)的任务 * 实现RejectedExecutionHandler接口,可自定义处理器 二、ThreadPoolExecutor执行顺序 线程池按以下行为执行任务 1. 当线程数小于核心线程数时,创建线程。 2. 当线程数大于等于核心线程数,且任务队列未满时,将任务放入任务队列。 3. 当线程数大于等于核心线程数,且任务队列已满 -1 若线程数小于最大线程数,创建线程 -2 若线程数等于最大线程数,抛出异常,拒绝任务 三、ThreadPoolExecutor如何设置参数 1、默认值 * corePoolSize=1 * queueCapacity=Integer.MAX_VALUE * maxPoolSize=Integer.MAX_VALUE * keepAliveTime=60s * allowCoreThreadTimeout=false * rejectedExecutionHandler=AbortPolicy() 2、如何来设置 * 需要根据几个值来决定 - tasks :每秒的任务数,假设为1000 - taskcost:每个任务花费时间,假设为0.

解决gitclone报错 无法访问‘https://github.com/xxx.git/‘:GnuTLS recv error

由于电脑被我搞坏了,重新安装了ubuntu20.04 所以需要重新下载安装benchmark 第一次gitclone成功了 llxy@llxy-GS65-Stealth-9SD:~/tools$ git clone https://github.com/google/benchmark.git 正克隆到 'benchmark'... remote: Enumerating objects: 6549, done. remote: Counting objects: 100% (805/805), done. remote: Compressing objects: 100% (441/441), done. remote: Total 6549 (delta 460), reused 578 (delta 320), pack-reused 5744 接收对象中: 100% (6549/6549), 2.22 MiB | 33.00 KiB/s, 完成. 处理 delta 中: 100% (4229/4229), 完成. 第二次clone失败 llxy@llxy-GS65-Stealth-9SD:~/tools$ git clone https://github.com/google/googletest.git benchmark/googletest 正克隆到 'benchmark/googletest'... fatal: 无法访问 'https://github.com/google/googletest.git/':GnuTLS recv error (-110): The TLS connection was non-properly terminated.

Java多线程5---线程优化:线程池、锁优化

一、线程池 1、线程池优点 (1)提前创建多个线程放在线程池,使用时直接获取,使用完放回池中待用 避免频繁创建销毁线程的内存资源消耗,实现线程的重复利用。 (2)提高响应速度---减少了创建新线程的时间 (3)便于线程的管理(容器思想) 2、线程池的具体实现--executorService exexutor (1)通过exexutors调用newFixedThreadPool创建固定大小的线程池对象, ExecutorService 类型的对象 (2)通过该对象调用execute()方法,将要启动的线程放入线程池 (3)关闭线程池--shutdown() //1、创建最大线程数为10的线程服务,线程池 ExecutorService threadServices=Executor.newFixedThreadPool(10); //2、执行,添加线程,添加线程数为当前线程池内线程数 threadServices.execute(new MyThread()); threadServices.execute(new MyThread()); threadServices.execute(new MyThread()); //3、关闭连接 threadServices.shutdown(); 【注】 创建线程池的几种方法(静态工厂方法) (1)newFixedThreadPool 固定大小的线程池 ---核心线程数也是最大线程数,不存在空闲线程,阻塞队列:LinkedBlockingQueue【快】 (2)newSingleThreadExecutor 单线程 ---适用于保证顺序执行任务的场景【慢】 (3)newCachedThreadPool 可伸缩线程池---最大线程数为integer最大值(2^31-1),阻塞队列:SynchoronousQueue【最快】 (4)newScheduleThreadPool ---最大线程数为integer最大值,不会回收工作线程,容易出现OOM (5)newworkStealingPool ---jdk8新引入,创建持有足够线程的线程池支持给定的并行度, 通过多个队列减少竞争。 线程池启动线程的两种方式 service.execute(new 线程)----该线程是继承runnable接口的,没有返回值 service.submit(new 线程)----该线程是继承Callable接口的,有返回值 关闭线程池 shutdown---线程池的状态设为SHUTDOWN 中断没有正在执行任务的线程,不中断未完成的线程 shutdownNow--线程状态改为STOP 尝试停止正在执行或暂停任务的线程,并返回等待执行任务列表,中断未完成的线程 3、线程池的核心参数 核心线程数--corePoolSize--目前线程池中存在的线程数(长时间稳定存活的线程数) 线程数超过此数时,会通过线程空闲时间进行线程销毁 工作队列--workQueue--请求>核心线程数部分,放入工作队列等待最大线程数--maxmumPoolSize--线程池允许的最多线程数拒绝策略--handler--当请求量>最大线程数时,拒绝请求,选择合适的拒绝策略线程空闲时间--keep AliveTime---达到某个值被销毁,避免浪费内存资源 当线程数<核心线程数---创建新线程 当请求数>工作队列数--- 创建新线程 当请求数>核心线程数----线程进入阻塞队列 当线程数>核心线程数---按照线程空闲时间销毁线程 4、线程池执行过程 每当有新的任务到线程池时, (1) 先判断线程池中当前线程数量是否达到了corePoolSize,若未达到,则新建线程运行此任务,且任务结束后将该线程保留在线程池中,不做销毁处理,若当前线程数量已达到corePoolSize,则进入下一步; (2) 判断工作队列(workQueue)是否已满,未满则将新的任务提交到工作队列中,满了则进入下一步; (3) 判断线程池中的线程数量是否达到了maxumunPoolSize,如果未达到,则新建一个工作线程来执行这个任务,如果达到了则使用饱和策略来处理这个任务。 【注】

常见游戏外挂分类及原理概述

外挂基本概念 要理解外挂,首先需要理解网络游戏的数据流。这里所说的数据流定义为游戏本地客户端与游戏后台服务器之间的数据流通。一个数据的产生需要玩家做出对应的操作,然后经过网络传输同步到服务器后台,服务器后台再处理过后再通过网络反馈给玩家。 在此基础上,可以将广义上的外挂定义为:非法窜改游戏数据流的方式。非法指的是没有法律许可,而窜改的方式包括增,删,查,改。 狭义上的外挂就是针对数据链路上的节点的修改。比如窜改客户端的“内挂”,窜改网络数据的“脱机挂”,窜改游戏后台服务器的“私服”。 内存挂实现原理 内挂的目标即为数据链路上的第一个节点:游戏客户端(包含客户端所使用的操作系统)。内挂的原理一般通过增,查,改的方式来实现,而所使用到的工具主要有调试工具(如Ollydbg),反汇编工具(如IDA),内存查看工具(如CheateEngine)。制作内挂,不仅要对操作系统有理解,而且还要深入到游戏引擎,游戏逻辑。 1. 增 以使命召唤OL为例。游戏的设定为武器可以装配不同的配件,正常情况下,M4A1只能装配2个配件。 使用调试器调试游戏,分析武器的配件逻辑,可以发现:每次装备配件时,都会调用一个游戏函数,定义为AddWeaponAttachment(作者自己的定义,下同),而这个函数的调用参数通过不断的调试分析可以猜测为插槽Index以及配件ID,即: AddWeaponAttachment(SlotIndex, AttachmentID) 额外调用这个函数,即增加一次游戏逻辑的调用,就可以实现M4A1使用多个配件。 封装一下这个游戏逻辑,增加背包,主武器,副武器的判断,就可以形成一个“卡配件”的外挂。 第二个例子。正常游戏逻辑中,点击一次鼠标会触发一发子弹的射击。而在操作系统层面上,每点击一次鼠标游戏就会发送一次鼠标点击的消息,如果在游戏允许的游戏买卖时间范围内增加鼠标点击消息的发送,那么就可以实现武器的子弹加速,这种效果在霰弹枪上面即为明显,可以实现单发射击的霰弹枪变成连续射击,武器致死率大大提升。 2. 查 查,即读取操作。在游戏中有些信息是不会在界面上直接透露给玩家的,但是玩家一旦掌握这些信息就会获得绝对的优势。 以棋牌类游戏的看牌器为例。 由于游戏逻辑的需要,玩家的底牌会在存放在内存中,而通过内存查看工具不断的变更查看条件,就可以在内存中的找到对应的底牌记录,知道别人的底牌之后,玩法就非常随意了。 以FPS游戏的方框透视为例。 游戏逻辑会记录战局中所有玩家的坐标信息,而通过指定的方法读取到敌人的坐标之后,可以用方框将敌人在屏幕中标记出来,掌握敌人的位置可以率先做出预判,进一步可以做成自瞄辅助工具。 3. 改 改即修改,即修改一切和游戏相关的信息,包括游戏数据,游戏代码,游戏文件,改的方法也就是内挂典型的手段。 以DNF为例子,玩家在攻击的时候会有攻击力的叠加。同样通过调试分析,找到角色攻击函数,定义为Attack(Target, Power),参数表示攻击的对象以及攻击力,外挂可以修改这个Attack函数,使得Target为当前区域内所有怪物,Power为无穷大,那么Attack的效果即为全屏倍攻。 以FPS游戏为例,游戏在渲染图像的时候会使用Windows的DiretX模块(DX游戏)。一般来说,在渲染每一帧的时候游戏逻辑会根据由远到近的顺序将当前屏幕内所展示的图像渲染出来,在最终呈现时会根据物体的遮挡关系真实的反映出当前场景,最终觉得当前所看到的画面。外挂可以修改DirectX的渲染逻辑,强制将遮挡关系修改,那么原本应该被遮挡的物体会在屏幕上显示出来,形成人物透视。 制作内挂需要对游戏逻辑和操作系统有一定的认识,必须有扎实的汇编阅读能力以及丰富的脑洞能力,不断的阅读,不断的猜想,不断的组合才能形成功能强大的外挂。 网络封包挂实现原理 网络封包挂的目标即为数据链路上的第二个节点:网络数据。客户端的每一个处理都会以封包形式通过网络传往网络服务器,因此窜改网络数据和内挂会得到相同的效果。使用到的工具即为封包查看工具(WPE PRO)。网络封包会通过客户端和服务器约定的协议传输。一般来说,游戏协议分为上下行协议,上行协议指的是客户端发往服务器,下行协议指的是服务器发往客户端。 1. 增 以CF为例。通过WPE分析游戏内购买武器的协议,游戏的上行协议是请求游戏商城指定武器,游戏的下行协议是服务器告诉客户端指定武器购买是否成功。 那么伪造一条游戏下行协议,里面包含指定武器购买成功的信息,无中生有,那么个人仓库内会多出对应的武器。 2. 删 删除在网络数据层对应的操作可以定义为拦截。拦截对自己不利的协议。比如在RPG游戏中,会消耗“水”补充体力,那么“消耗”的动作就对应一条消耗的协议,如果拦截这条协议,那么就可以实现不消耗“水”而获得体力的补充。 3. 查 查即查询。再次以RPG游戏为例,在第一次进入某个地图区域时,客户端会向服务器请求这个区域内的所有游戏对象,包括NPC,怪,物品等,这些对象会因为游戏剧本需要不一定能直接被玩家感知。而外挂主动向服务器发送这个请求,直接将所有对象标记出来,帮助玩家做出更优的攻略。 4. 改 改和内挂的改是一致的,直接体现就是修改封包的数据。上述的DNF全屏倍功是通过修改客户端实现,而在封包中也可以直接修改封包数据达到相同的效果。 内挂注重的是游戏逻辑,而网络封包挂注重的是游戏数据。相比而言,游戏的每一次更新都会让逻辑代码发生变化,而游戏协议的变动会很小。因此网络封包挂会比内挂有效性会更长些。 封包挂的另外一个优势就是,如果完全掌握了游戏协议就可以实现脱离客户端---脱机挂,脱机挂完全模拟了游戏客户端的所有操作而不占据系统资源。在RPG游戏中,脱机挂的优势很明显。假设一台PC机运行客户端一个小时可以获取到100游戏币,而同时运行两个客户端消耗系统资源只能获取到180游戏币,而同时运行10个脱机挂,获取的游戏币可以达到1000甚至更多。 私服实现原理 私服针对的就是数据流上的最末节点:游戏后台服务器。私服即非官方的盗版游戏服务器。随便在百度上搜索私服,看到的是内容粗糙,但充满各种“神装”的盗版游戏。但一个私服的出现,意味着游戏客户端,游戏协议,游戏后台服务器处理逻辑,游戏后台数据库完全暴露了。目前没有公开的资料显示如何制作一款游戏的私服,私服的出现往往伴随着游戏代码泄露。 在私服里面,可以体验到前所未有的“上帝”体验。以CS游戏为例子,目前公开的材料中有CS客户端,以及CS后台程序,虽然没有源码,但是可以直接调试分析CS的后台程序,找到逻辑中判断人物生存状态的逻辑,实现无敌模式。

一个简单漂亮的前端聊天界面

一个简单的前端静态聊天界面,实现了聊天的基本功能,目前后台还没做,接下来还会继续更新后台和完善前台样式并更新。 一.Html代码 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>chat</title> <link rel="stylesheet" href="../css/chat.css" type="text/css"> <script type="text/javascript" src="../js/chat.js"></script> </head> <body> <div class="all"> <div class="chat_index"> <!--banner--> <div class="chat_banner"> </div> <div class="chat_body"> <!--在线列表--> <div class="chat_online"> <!--搜索--> <div class="search_online"> <form> <input type="text" placeholder="搜索联系人"> </form> </div> <div class="online_friend"> <ul> <li> <div class="a_friend"> <div class="head_portrait"> <div class="head_text"> 黄 </div> </div> <div class="friend"> <div class="name">天狼星</div> <div class="this_time">4-12-15:10</div> </div> </div> </li> <li> <div class="a_friend"> <div class="head_portrait"> <div class="

Druid连接池-JDBC工具类封装

1、导入相关的jar包和配置文件 注:本文仅提供作者自己查阅使用 导入Druid的jar包和mysql的驱动包 注意:这里有些 配置文件的key不能随便取,随便取的 key 有时候会出现连不上数据库的情况或者是空指针异常 driverClassName=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/dbproduct username=root password=root initialSize=5 maxActive=10 maxWait=3000 maxIdle=8 minIdle=3 2、项目文件 3、代码 JDBCUtils package com.druid.utils; import com.alibaba.druid.pool.DruidDataSourceFactory; import com.mysql.jdbc.PreparedStatement; import javax.sql.DataSource; import java.io.InputStream; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Properties; //Druid连接池工具类 public class JDBCUtils { private static Properties properties = new Properties(); private static DataSource dataSource; static { try { //加载配置文件 InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("druid.properties"); //加载到内存中 properties.load(is); //获取配置文件 dataSource = DruidDataSourceFactory.createDataSource(properties); } catch (Exception e) { e.

讯连科技威力导演20中文版

威力导演也叫做CyberLink PowerDirector,是一款非常专业实用的非线性视频编辑神器,这款软件体积小巧、功能强大,即使是初学者也能够轻松使用,拥有入门初学者和专业工作者所需要的各种功能,能够帮助初学者快速入门,让专业工作者处理起来更加的快速。该软件采用了最先进的编解码工具,用户能够批量打开各种类型常见的视频资源了,并且还支持简单拖放,结合了吸睛文字标题、动画对象、主题背景以及流畅转场特效,让你只要动一动鼠标,依序拖放视频或相片,轻松打造出MV质感创作,让你做出的视频更加的有质感,再加上一键强化色彩功能,优化影像鲜艳度与饱和度,画面更贴近原色,保留最真实视频色彩感受。除此之外,在威力导演20中用户还支持用户自定义形状对象,透过关键帧以及文字自动缩放等功能,轻松应用、编辑并自定义向量形状,多种文字对话窗口与形状提供选择,让视频创作更加精采,更是采用高精准对象跟踪技术,100% 精准逐格跟踪视频中移动的影像对象,完美突显画面中的主要角色,让你的视频更加的出彩。 →软件资源← 注意:如果之前安装了盗版序列号,请将其完全卸载。删除注册表中的所有Cyberlink\PowerDirector20项。 1、下载并解压,得到威力导演20中文源程序和注册文件 2、首先编辑HOSTS文件,添加规则禁止联网,用记事本打开【C:\Windows\System32\drivers\etc\hosts】编写如下代码,将以下行添加到主机文件(默认情况下:C:\Windows\System32\drivers\etc\hosts):保存 127.0.0.1 cap.cyberlink.com 127.0.0.1 activation.cyberlink.com 3、双击文件“PowerDirector_20.0.2106.0_Ultimate.exe”安装软件,默认目录为C:\Program Files\CyberLink\PowerDirector20,直接安装即可 4、成功安装软件后,先不要运行软件,直接双击运行压缩包里的Reg Patch.reg添加注册表 5、然后直接打开软件 6、下一步激活H265编码功能,随便导入一个视频,切换至“制作”标签,选中H265编码,点击开始编码输出视频 7、选择“我目前没有Internet链接”,随便输入11111即可; 8、最后用户就可以免费使用了

c++数据结构之树

目录 前言 一、树的基本概念 1.1树的定义 1.2基本术语 二、二叉树 2.1二叉树的定义 2.2二叉树的性质 2.3二叉树的ADT 三、二叉树的存储表示 3.1二叉树的数组表示 3.2二叉树的链表表示 四、二叉树的遍历 4.1前序遍历 4.2中序遍历 4.3后序遍历 五、常用二叉树 5.1排序二叉树 5.2哈夫曼树 总结 前言 本文主要介绍的数据结构之树型结构的相关知识,树型数据结构是面试官面试的时候非常喜欢考的一种数据结构,树形结构的遍历也是大厂笔试非常喜欢设置的考点,这些内容都会在本篇文章中进行详细的介绍,并且还会介绍一些常用的算法。 一、树的基本概念 层次结构的数据在现实世界中大量存在。例如,一个国家有若干省,一个省有若干市县,一个市县有若干区乡。又如,一本书包含若干章,一章包含若干节,一节包含若干段。例如,下图是数组的层次关系,这种描述树形数据的形式称为倒置的树形表示法。 图1 数组的层次结构 线性数据结构一般不适合用来表示层次数据。为了组织层次数据,需要对树形数据的结构进行研究。 1.1树的定义 在上图1中,我们采用倒置树来描述树状结构。一棵倒置树的顶端是根,根有几个分枝,称为子树,每棵子树再分成几个小分枝,小分枝再分成更小的分枝,每个分枝也都是树,一个结点也是树。由此,我们可以给树下一个递归定义。 树(Tree)是包括n个结点的有限非空集合T,其中,一个特定的结点r称为根(Root),其余结点T-{r}划分成m个互不相交的子集T1,T2,Tm其中,每个子集都是树,称为树根r的子树。 根据树的定义,一个结点的树是仅有根结点的树,这时m=0,这棵树没有子树。 1.2基本术语 图1可以抽象成图2,它形象地反映了树的逻辑结构。下面,参照图2,给出树结构讨论中常用的术语。 图2 树的逻辑结构 树中元素称为结点(Node),如A、B等。 如果某结点到另一结点之间存在着连线,则称此连线为一条边(Edge),如<A,B>、<B,E>等。 如果从某个结点沿着树中的边可到达另一个结点,则称这两个结点间存在一条路径(Path),如结点A到结点J,存在路径{<A,C>,<C,J>}。 如果一个结点有子树,则称该结点为子树的双亲(Parent),子树的根称为该结点的孩子(Child),如结点A是结点B、C、D的双亲,而结点B、C、D是结点A的孩子。具有相同双亲的结点称为兄弟(Sibling),如结点B、C、D是兄弟。 结点拥有的子树数目称为结点的度(Degree),如结点A的度为3,结点D的度为0,结点J的度为0。 度为零的结点称为叶子(Leaf)。 规定根结点的层次为1,树中结点的最大层次称为该树的高度(Hight),如图2所表示的树的高度为3。 如果树中结点的各子树是从左至右有次序的,则称该树为有序树,否则称为无序树。 二、二叉树 树结构和自然界的树一样,具有各种各样的形态,这样就使我们对树结构的研究比较困难。为此,我们首先研究最为常见的二叉树,以及二叉树的性质、存储结构和运算,然后给出二叉树和一般树之间的转换。 2.1二叉树的定义 二叉树(Binary Tree)是由有限个结点组成的集合,它或者为空集合,或者仅含一个根结点,或者由一个根结点和两棵互不相交的左、右子树组成。 上述定义表明,二叉树有如图3所示的五种基本形态。 图3 二叉树的基本形态 必须指出,树定义与二叉树定义稍有区别。首先,树不能是空树,却可以有空二叉树。其次,一般树的子树的不分次序,而二叉树的子树却分左、右子树,即使在仅有一棵子树的情况下也要指明是左子树还是右子树。最后,一般树中结点的度(子树数目)可以大于2,但二叉树中结点的度均不超过2。 2.2二叉树的性质 若二叉树高为h,树的结点总数为2^h-1,称此二叉树为满二叉树。如下图4 eg:如下图:h=3,那么结点总数7(包含根节点) 图4 满二叉树 【性质1】高度为h的二叉树的结点总数n<=2^h-1。 这个性质很容易理解: 证明:对于高度为h的满二叉树,其结点总数为 它是高度为h的二叉树结点总数的最大值,故。 对于高度为h的二叉树,如果第1~h-1层构成满二叉树,而第h层的叶子结点严格按从左至右依次排列,称此二叉树为完全二叉树(如图5(a)所示)。 图5 完全二叉树与非完全二叉树 在图5(b)中,双亲结点C仅有右孩子G无左孩子,故它不是完全二叉树。 【性质2】对于含n(n>=1)个结点的完全二叉树(区分满二叉树),其高度h=[log2(n+1)]。(向上取整) eg:上述图a,n=6,那么h=[log2(6+1)]=log2(8)=3 【性质3】对于一棵非空二叉树,如果度为0的结点数为,度为2的结点数为,则 =+1。 (即零度结点数总比2度结点数大1)

OAuth2第三方登录快速接入

前言:现在很多网站和App都支持第三方登录功能,这里以GitHub第三方登录举例,因为注册应用申请ID比微信和QQ简单。目前市面上主流的第三方登录协议就是 OAuth2.0, 例如 QQ,微信,微博等等。 所以只要搞明白大概流程,那么接入其他供应商的第三方登录也是小菜一碟了。 一、OAuth 2.0授权机制 (1)OAuth 2.0简介 说到第三方登录,不得不提的一个知识点就是 OAuth 2.0。OAuth 2.0 是一种授权机制,主要用来颁发令牌(token)。 OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用。 这个协议在认证和授权的时候涉及到: 服务提供方,例如 GitHub,GitHub上储存了用户的登录名,Email,昵称,头像等信息 用户客户端,例如我的网站就是一个客户端,需要服务方向我提供用户的一些基本信息 OAuth 协议的认证和授权的过程如下: 用户打开我的网站后点击GitHub登录按钮,网站想要通过GitHub获取该用户的基本信息 在转跳到GitHub的授权页面后,用户同意我获取他的基本信息 网站获得GitHub提供的授权码,使用该授权码向GitHub申请一个令牌 GitHub对网站提供的授权码进行验证,验证无误后,发放一个访问令牌给网站 网站使用访问令牌,向GitHub获取用户信息 GitHub 确认访问令牌无误,返回给网站基本的用户信息 (2)授权码模式 授权码模式(authorization code)是功能最完整、流程最严密的OAuth2授权模式。 (A)用户访问客户端,后者将前者导向认证服务器。 (B)用户选择是否给予客户端授权。 (C)假设用户给予授权,认证服务器将用户导向客户端事先指定的"重定向URI"(redirection URI),同时附上一个授权码。 (D)客户端收到授权码,附上早先的"重定向URI",向认证服务器申请令牌。这一步是在客户端的后台的服务器上完成的,对用户不可见。 (E)认证服务器核对了授权码和重定向URI,确认无误后,向客户端发送访问令牌(access token)和更新令牌(refresh token)。 (F)客户端使用令牌,向资源服务器申请获取资源。资源服务器确认令牌无误,同意向客户端开放用户资源 二、GitHub上创建应用 如何使用GitHub提供的 OAuth 服务,首先去GitHub上创建应用 第一步:登陆GitHub官网注册账号登陆后 第二步:创建一个应用并填写信息 注册应用成功后就会有Client ID和 Client Secert 第三步:在前台准备一个按钮用于GitHub账号登陆(或者直接访问后端进行跳转,这样可以保证安全性) <a href="https://github.com/login/oauth/authorize?client_id=对应自己申请的client id &state=STATE&redirect_uri=http://localhost/callback;">github登录</a> 注意:redirect_uri是回调地址,必须和在注册应用时候填写的回调地址一致。 其他步骤就是后端和GitHub对接通信的编码,通过OAuth2授权码模式的方式获取用户在GitHub上的用户信息, 三、GitHub第三方登录总体流程 首先我们申请完应用后会有Client ID和Client Secret 1、通过这两个参数我们去访问:https://github.com/login/oauth/authorize?client_id='你的client id',访问后会返回一个code到我们的创建应用的时候填写的那个callback回调地址。 2、有了code,我们在通过Client ID和Client Secret和code这三个参数去访问:https://github.com/login/oauth/access_token?code=''&client=''&client secret='',这时会返回一个access_token: 3、有了access_token我们在去访问:https://api.github.com/user?access_token='',这时,就能以json格式返回给我们所有的用户信息了,用户的基本信息内容如下所示 有了用户信息,就能插入到数据库了吧,总之,流程就是这样,但是调接口的方法却不尽相同。

2021-09-22

linux防火墙查看状态 操作防火墙的命令: 查看防火墙状态:systemctl status firewalld让防火墙可用:systemctl enable firewalld让防火墙不可用:systemctl disable firewalld开启防火墙:systemctl start firewalld禁用防火墙:systemctl stop firewalld

【Java 基础】枚举(Enum)的使用

文章目录 前言一、枚举1.什么是枚举?2.枚举使用2.1 语法2.2 基本使用2.3 其他使用方法2.4 备注 3.枚举与普通类对比4.阿里巴巴枚举使用规范4.1 命名风格4.2 常量定义 参考 前言 在JDK 5 之前,我们定义常量都是: public static fianl… 。 JDK 5 之后,枚举(Enum)引入了。我们可以使用枚举定义定义常量。 一、枚举 1.什么是枚举? 可以将枚举看成一种特殊的类,他的声明的变量默认就有“public static fianl”修饰。 枚举都是继承自“java.lang.Enum”类。 作用:当需要定义一组常量时,可以使用枚举类型 2.枚举使用 2.1 语法 创建枚举类需要使用“enum”关键字。创建的常量用逗号分隔。 enum 枚举名字 { 枚举体(常量列表) } 2.2 基本使用 例如,定义一组季节(Season)的常量。最常使用这个。 如果需要使用时,只需要“枚举类名.属性名”即可,返回值是常量的名称(也就是属性名)。 public enum SeasonEnum { SPRING, SUMMER, AUTUMN, WINTER } 2.3 其他使用方法 给枚举属性添加一个值,该值表示枚举值为第几个季节。 注意:枚举体(属性)添加了“常量列表”,需要创建一个值,同时给该值一个构造器。 public enum SeasonEnum { SPRING(1), SUMMER(2), AUTUMN(3), WINTER(4); private int ordinal; SeasonEnum(int ordinal) { this.ordinal = ordinal; } /** 获取序数(也就是第几个季节) */ public int getOrdinal() { return ordinal; } } 测试:获取枚举常量名称,枚举的次序,枚举的值。

重载和重写的区别以及应用场景

一、重写(Override) 子类继承父类,子类重写父类中的所有公共方法,覆盖父类的方法并对其重写。 注意事项: 重写前后方法名相同;参数列表相同; 返回值相同 子类重写的方法所抛出的异常必须与父类中的被重写方法的异常一致,或者不能比父类的异常范围更大。 父类的私有方法不能被重写,如果子类非要写这个同名方法,只是定义了一个与父类方法相同的新方法,而并不是重写父类的方法。 子类重写方法的访问权限不能低于父类方法中的访问权限,即子类的访问权限可以>=父类。j举个例子:父类是public 子类也可以是public,但是不可以是private;父类是private,子类可以是public或者private等等,只要比private权限大的都可以。 二、重载 重载是多态性的一种表现。重载是指在一个类中定义了多个同名的方法,但他们的参数列表是不同的,也就是说有不同的参数个数或有不同类型的参数类型。 注意事项: 重载是通过方法中参数的不同来区分的,包含参数个数、参数类型、参数顺序等等。 如果父类方法访问权限为private,那么子类就不能对其进行重载;如果子类写了这个同名的方法,那只是定义了一个与父类方法相同的新方法,并不会得到重载的效果。 三、重载与重写的区别 重写时子类继承父类的方法,涉及到两个类;重载是同一个类方法之间的关系,只是参数或者参数类型不同,在一个类中。 重写的参数列表相同,重载的参数列表不同。 四、重写和重载的应用场景 在类中,要以统一的方式处理不同类型数据的时候,可以用重载。重载是多样性,是多态类型的演示,不修改原方法及源代码的基础上对方法进行扩展或增强时,使用重写。 重写的前提是继承,子类继承父类,子类才可以继承父类中的公有方法,增加新的功能、在原有的代码基础上对方法进行扩展和增强,需要用重写,提高了程序的多样性。重写时,参数列表,返回值得类型不能修改,异常可以减少或者删除,不能抛出新的异常或者比父类异常更广的异常,方法的访问权限可以降低,但是不能比父类权限高。 重载是构造器的重载,构造器重载后,提供多种形参形式的构造器,可以应对不同的业务需求,加强程序的健壮性和可扩展性。重载必须要修改方法(构造器)的形参列表,可修改返回值类型,也可修改访问权限(异常);使用范围是在同一个类中,目的是对构造器进行功能扩展,以应对多业务场景的不同使用需求。

js六种给数组追加元素的方法,你想得到几种?

现在有一个数组arr=[1,2,3,4] 要追加了! 1.push方法 let arr=[1,2,3,4]; arr.push(5); console.log(arr); //得到[1,2,3,4,5] push方法会修改原数组,可以带多个参数,都会一起加到数组末尾 2.unshift方法 let arr=[1,2,3,4]; arr.unshift(5); console.log(arr); //得到[5,1,2,3,4] 类似push,不过会加到开头 3.length属性 可以直接给length位置赋值 let arr=[1,2,3,4]; arr[arr.length]=5; console.log(arr); //得到[1,2,3,4,5] 数组长度会自动+1 4.splice方法 splice既可以删除数组元素,也可以追加数组元组 arrayObject.splice(index,howmany,item1,…,itemX) 其中,index和howmany是必须,后面的item不是必须的 howmany指的是删除元素的个数,是0则为不删除 index是开始修改的索引位置 item是在index处增加元素的列表 //删除 let arr=[1,2,3,4]; arr.splice(1,1); console.log(arr); //得到[1,3,4] //增加 let arr=[1,2,3,4]; arr.splice(1,0,1.5); console.log(arr); //得到[1,1.5,2,3,4] 另外,如果howmany非0的情况下,item不为空,那么会先删掉howmany对应的数组元素,再在index位置追加item let arr=[1,2,3,4]; arr.splice(1,1,9,9,9); console.log(arr); //得到[1,9,9,9,3,4] 5.concat方法 concat方法和push类似,不过会生成新数组,不会修改原数组 let arr = [1,2,3]; console.log(arr.concat(4,5)); //得到[1,2,3,4,5] 也用于数组连接 let arr1 = [1,2,3]; let arr2 = [4,5,6]; console.log(arr1.concat(arr2)); //得到[1,2,3,4,5,6] 6. … …也就是拓展运算符

c++数据结构之栈

一、栈的定义 栈(Stack)是由有限个数据类型相同元素组成的有序集合,对元素的操作只能在栈顶进行,遵循后进先出(Last In,First Out)的原则,其相关运算有创建空栈、判空、判满、入栈、出栈等。 二、栈的ADT 数据: 有限个数据类型相同元素所组成的有序集合,用top纪录栈顶元素的位置。 运算: Create(): 创建一个空栈。 IsEmpty(): 若栈空,则返回1,否则返回0。 IsFull(): 若栈满,则返回1,否则返回0。 Push(): 让某元素入栈。 Pop(): 让栈顶元素出栈。 Display(): 输出栈元素 三、栈的数组实现 栈可以用数组来实现,定义数组data[MaxSize]用来存储栈元素,MaxSize是允许的最大容量,用变量top纪录栈顶元素的位置,top=-1表示空栈,这种栈称为顺序栈(Sequence Stack),用S或其它大写英文字母来表示。 #include<iostream> using namespace std; #define MaxSize 100//栈的最大容量 //顺序栈定义 struct SeqStack { int data[MaxSize];//存放栈元素的数组 int top;//栈顶指针 }; //创建空栈 void Create(SeqStack &S) { S.top = -1; } //判空 int IsEmpty(SeqStack S) { if (S.top == -1) return 1; else return 0; } //判满 int IsFull(SeqStack S) { if (S.

浮点数精度丢失问题详解

请看以下Go代码,会返回 0.7 吗? var num float32 for i := 0; i < 7; i++{ num = num + 0.1 } fmt.Println(num) 答案可能出人意料,是:0.70000005 0.70000005 也许有人会问,是不是Go语言的问题?换其他语言试试? OK,我们换JS试试。 答案依然令人意外。 除此之外,你还可以试试C、C++、Java、PHP等其他语言的float类型相加,看得到的数据是否精确; 还有,除了语言之外,你还可以在MySQL等数据库中试试float类型数据的字段叠加,得到的数据是否精确。 我可以先告诉你答案:只要是float类型的数据相加,无论在任何语言、任何数据库、任何中间件中进行加法(减法乘除法)运算,得到的数据,都不会精确。 这是浮点类型的精度丢失现象。(Loss of significance) 要了解产生这个现象的原因,就要先了解计算机是如何定义和表示float类型的。 不同于正整数类型的表示方法,float类型在计算机中的表示略显复杂,遵循的是IEEE 754标准。 下面,我们就讲一下IEEE 754标准。 我们首先回顾一下整数类型在计算机中的表示。 我们知道:计算机只认识0和1;那么,对于像6一样的这种正整数,我们要做十进制到二进制的转换。 即: 所以,十进制6最终转化为二进制为110。 这很好理解,但是,如何表示 6.1等这类小数呢? 有人说了,可以找个特殊的符号,用来表示小数点.,把6.1中6和1隔开;听起来是个不错的办法。其实IEEE 754还真就是这么做的,只不过思路略有些复杂,总体思路就是:仿照用"科学计数法"! 我们再回顾一下什么是科学计数法。 把一个数表示成a与10的n次幂相乘的形式(1≤|a|<10,a不为分数形式,n为整数),这种记数法叫做科学记数法。 也就是:1.360X10^4 这种计数方式。 我们可以仿照科学计数法,来表示浮点数,把二进制数统一表示成 1.0110101 X 2^n这种形式。 数据层面怎么表示出这种形式呢?根据IEEE 754的标准,将数据分为三部分: 从左到右分别表示:符号位(正负数)、指数位和小数位 以单精度浮点数为例,单精度浮点数一共32位(双精度64位,即平时所说的double类型),具体内部表示为: 1个bit表示符号位8个bit表示指数位23个bit表示小数位 这里有个地方要特别注意:因为数据最终要表示成 1.0110101 X 2^n这种形式,整数位在二进制下,永远都是1,所以在表示float类型的时候,直接把1给去掉了,假如有就占据一个bit的空间,既然那个bit位上永远都是1,所以干脆去掉了。 那么,具体该如何展示呢?例如小数点后的数字怎么表示?6.1能否写成110.1呢?如果能的话小数点后这个1代表什么呢?个数一?那添加几个零的话,能否认为是十、一百、一千?似乎是不可以,因为这样只能满足"视觉效果",逻辑层面直接说不通。 要明白在小数点后的数字代表除以2后的数字,例如二进制下小数点后的第一位1代表 1 / 2等于 0.5,第二位1代表 1/2/2等于 0.

chart.js使用学习——柱状图(1:基本用法)

柱状图属于以长方形的长度为变量的统计图表[1]。chart.js创建图形的方式都类似,先是数据准备,然后在chart构造函数中指定图表类型。 如下列代码及效果图所示,chart类中将类型指定为bar,即可绘制柱状图,可以使用backgroundColor属性赋予一组数据统一的背景色,也可以用颜色数组方式赋予每个数据不同的背景色(详见参考文献2)。 const labels = numbers({count: 7}); const data = { labels: labels, datasets: [{ label: '柱状图', data: [65, 59, 80, 81, 56, 55, 40], borderColor: 'rgb(75, 192, 192)', backgroundColor:'rgb(255, 0,0)' }] }; var barChart = new Chart(ctx, { type: 'bar', data: data }); 如果包含多组数据集,则柱状图中会在每个数据对应位置显示相应数量的长柱。 在此需说明的是,可以设置每个数据集中的stack属性,个人理解算是每个数据集的分组,相同stack值的数据集中的每条数据会被累积绘制在同一长柱中,如下列代码及效果图所示: datasets: [{ label: '柱状图1(group1)', data: [65, 59, 80, 81, 56, 55, 40], borderColor: 'rgb(75, 192, 192)', backgroundColor:'rgba(255, 99, 132, 0.5)', stack:'group1' }, { label: '柱状图2(group1)', data: [85, 79, 100, 101, 76, 75, 60], borderColor: 'rgb(175, 92, 92)', backgroundColor:'rgba(153, 102, 255, 0.

C++语言基础篇学习总结及心得体会(难度极低)

关于C++的语言部分(信息学奥赛一本通),我自己总结了一部分的知识。 因为过于基础,第一部分源代码的简介和使用我就不讲了。 我直接从第二章顺序结构程序设计开始讲。首先,我认为在这一章内只要理解一个因果关系后,这一章大部分都可以运用与理解。一个源代码,开头一个头文件,我比较喜欢用的是 #include<bits/stdc++.h> using namespace std; int main() 。其次便是定义,定义包括了整个源代码的常量和变量,我比较喜欢理解成数学中的未知数,但也不是全部相通。 我举个例子: ​ #include<bits/stdc++.h> using namespace std; int main(){ int a,b; cin>>a>>b; cout<<a+b; return 0; } ​ 上面的代码:是a+b问题;那代码的意思:定义a和b,输入a和b,输出a+b,然后结束语。(在下不解释头文件的作用范围);但要注意,若要定义字符,需用char,如: ​ ​ ​ #include<bits/stdc++.h> using namespace std; int main(){ char a; cin>>a; cout<<" "<<a<<" "<<endl; cout<<a<<" "<<a<<endl; cout<<a<<a<<a<<endl; return 0; } ​ ​ ​ 这样就可以定义符号,要定义单精度浮点数要有float,双进度浮点数用double,需要float时大多可以double替代,但要用double时不可以用float,double作用范围更广,但如果题目要求单精度浮点数时,就最后用float,保险起见。 在第三章程序的控制结构中,主要讲if与switch。其实“if”可以理解为“如果”,而switch更像是在列选项。如: #include<bits/stdc++.h> using namespace std; int main() { int weekday; cin>>weekday; switch(weekday) { case 1:cout<<"Monday"<<endl;break; case 2:cout<<"Tuesday"<<endl;break; case 3:cout<<"

2021-09-21

1002 写出这个数(20分) 读入一个正整数 n,计算其各位数字之和,用汉语拼音写出和的每一位数字。 输入格式: 读入一个正整数 n,计算其各位数字之和,用汉语拼音写出和的每一位数字。 输出格式: 在一行内输出 n 的各位数字之和的每一位,拼音数字间有 1 空格,但一行中最后一个拼音数字后没有空格。 输入样例: 1234567890987654321123456789 输入样例: yi san wu #include<bits/stdc++.h> using namespace std; string s; int num; string x[11] = {"ling", "yi", "er", "san", "si", "wu", "liu", "qi", "ba", "jiu"}; int main(){ cin >> s; for(int i=0; i<s.length(); i++) num += s[i]-'0'; string m = to_string(num); int i; for( i=0; i<m.length()-1; i++) { cout<<x[m[i]-'0']<<" "; } cout<<x[m[i]-'0']; return 0; }

【HNU-CSEE jetson nano 番外篇】jetson nano与显示器的连接

前言 首先需要搞清楚VGA信号和HDMI信号的大致区别。二者都是主机与显示器之间传输图像的协议,但HDMI传输的是图像数字信号,VGA传输的是图像模拟信号,因而两者之间,如果要进行切换的话,需要专门设计的IC芯片进行转换。 而我们本系列的主角,jetson nano 输出图像的接口只有HDMI,因而,如果我们要给nano配置一个显示器,需要注意解决nano 的HDMI 图像信号输出过程中遇到的几个问题。 最好使用双端HDMI口的连接线 由实际经验得出,对于2GB的nano 而言,用双端HDMI连接显示器,或者是使用从淘宝随便淘来的HDMI转VGA转接头,都可以很好的兼容。(比如下图这个,打开购买链接之后,如果你选了最便宜的版本,2GB的nano是可以用的,但是4GB的nano就无法使用,屏幕上会显示:“ no VGA signal from device”) 如果必须要用转接头,就用thinklife转接头 直接京东或者淘宝搜,“thinklife”。 便宜不贵~还好用!

ICCV2021 MIT-IBM沃森开源CrossViT:Transformer走向多分支、多尺度

关注公众号,发现CV技术之美 今日分享 ICCV 2021 论文『CrossViT: Cross-Attention Multi-Scale Vision Transformer for Image Classification』, MIT-IBM 沃森人工智能实验室开源《CrossViT》,Transformer 开始走向多分支、多尺度(附目前多尺度ViT异同点对比)。 详细信息如下: 论文链接:https://arxiv.org/abs/2103.14899 项目链接:https://github.com/IBM/CrossViT 导言: 与卷积神经网络相比,最近出现的视觉Transformer(ViT)在图像分类方面取得了很好的结果。受此启发,在本文中,作者研究了如何学习Transformer模型中的多尺度特征表示来进行图像分类 。为此,作者提出了一种双分支Transformer来组合不同大小的图像patch,以产生更强的图像特征。本文的方法用两个不同计算复杂度的独立分支来处理小patch的token和大patch的token,然后这些token通过attention机制进行多次的交互以更好的融合信息。 此外,为了减少计算量,作者开发了一个简单而有效的基于cross-attention的token融合模块。在每一个分支中,它使用单个token(即 [CLS] token)作为query,与其他分支交换信息。本文提出cross-attention的计算复杂度和显存消耗与输入特征大小呈线性关系 。实验结果表明,本文提出的CrossViT的性能优于其他基于Transformer和CNN的模型。例如,在ImageNet-1K数据集上,CrossViT比DeiT的准确率高了2%,但是FLOPs和模型参数增加的非常有限。 01 Motivation Transformer使NLP任务中序列到序列建模的能力取得了很大的飞跃。Transformer在NLP中的巨大成功激发了其在计算机视觉领域的应用。在ViT之前的一些工作主要将Transformer中的Self-Attention和CNN进行结合。虽然这些结合CNN和Self-Attention方法达到了比较不错的性能,但与纯粹的基于Self-Attention的Transformer相比,它们在计算方面的可拓展性非常有限。 ViT使用一系列embedding式的图像patch作为标准Transformer的输入,这是第一个与CNN模型性能相当的无卷积Transformer网络。然而,ViT需要非常大数据集,如ImageNet21K和JFT300M来进行预训练。之后的DeiT表明,数据增强和模型正则化可以在较少的数据下训练高性能的ViT模型。在此之后,ViT就逐渐成为了CV任务中的主流模型之一。 在这项工作中,作者研究了如何学习Transformer模型中的多尺度特征表示来进行图像识别 。多尺度的特征已经在很多工作中证明了对于CV任务是有效的,但多尺度特征对视觉Transformer的潜在好处仍有待验证。受到多分支CNN架构的启发,作者提出了一个双分支Transformer来组合不同大小的图像patch,以产生更强的视觉特征用于图像分类 。 本文的方法用两个具有不同计算复杂度的独立分支来分别处理大patch的token和小patch的token,这些token多次融合以相互补充信息。本文的重点是研究并设计适合视觉Transformer的多尺度特征融合方法 。在本文中,作者通过一个有效的交叉注意模块来实现这一点,其中每个Transformer分支创建一个non-patch token(即 [CLS] token)作为代理,并通过attention机制与另一个分支交换信息。(由于这里只使用[CLS] token进行信息交互,所以这一步attention的计算复杂度是线性的,而非二次的。) 在ImageNet-1K数据集上,CrossViT比DeiT的准确率高了2%,但是FLOPs和模型参数增加的非常有限(如上图所示)。 02 方法 2.1.Vision Transformer的概述 视觉Transformer(ViT)首先通过将图像按照一定的patch大小划分,然后将图像转换为一个patch的序列,并将每个patch线性投影成embedding。为了执行分类任务,还要在序列中添加了一个额外的分类token(CLS)。此外,由于Transformer编码器中的自注意是与位置无关的,而视觉应用高度需要位置信息,因此ViT向每个token添加了位置embedding,包括CLS token。 然后,将所有token输入到堆叠的Transformer编码器,最后使用CLS token进行分类。Transformer编码器由一系列块组成,其中每个块包含带有FNN和多头自注意(MSA)。FFN在隐藏层上包含具有扩展比为r的两层多层感知器,在第一个线性层后应用一个GELU非线性激活函数。在每个块之前应用Layer normalization(LN),在每个块之后应用残差连接。ViT的输入和第k个块的处理可以表示为: 其中,和分别为CLS和patch token,为位置embedding。N和C分别是patch token的数量和embedding的维度。 值得注意的是,ViT与CNN的一个非常不同的设计是CLS token。在CNN中,最终的embedding通常是通过对所有空间位置的特征进行平均,而ViT使用与每个Transformer编码器上的patch token相互作用的CLS token作为最终的embedding。因此,我们可以认为CLS token是一个总结所有patch token的代理,因此作者提出的模块是基于CLS token设计的双路径多尺度的ViT。 2.2.多尺度Vision Transformer patch大小会影响ViT的准确性和复杂性;使用细粒度的patch大小,ViT性能更好,但会导致更高的FLOPs和显存消耗。例如,patch大小为16的ViT比patch大小为32的ViT好6%,但前者需要更多4×的FLOPs。受此启发,作者提出的方法是利用来自更细粒度的patch大小的优点,同时平衡复杂性。更具体地说,作者首先引入了一个双分支ViT,其中每个分支处理不同patch大小的特征,然后采用一个简单而有效的模块来融合分支之间的信息。 上图展示了交叉注意多尺度视觉Transformer( Cross-Attention Multi-Scale Vision Transformer,CrossViT)的网络结构。模型主要由K个多尺度Transformer编码器组成,其中每个编码器由两个分支组成: L-Branch :大分支利用粗粒度的patch大小(),这个分支有更多的Transformer编码器和更大的embedding维度。 S-Branch :小分支对细粒度的patch大小()进行操作,这个分支具有更少的编码器和更小的embedding维度。

python画只皮卡丘

今天没事敲了一下python发现好久都没用过海龟画图了,今个画了一只简单版的皮卡丘 下附代码: #接下来请欣赏像素风皮卡丘 import turtle as a def wz(x,y):#设置一个以海龟为原点中心位移的地址 a.penup() a.seth(0) a.fd(x) a.left(90) a.fd(y) a.seth(0) a.pendown() def cfx(x,y):#用海龟画一个长方形,x为长,y为宽 a.seth(0) a.fillcolor("black") a.begin_fill() for m in range(0, 2, 1): a.fd(x) a.right(90) a.fd(y) a.right(90) a.end_fill() a.speed(0) a.setup(900,700,400,120)#设置窗口大小 a.bgcolor("yellow")#背景黄色 #画嘴巴 a.pensize(8) a.fillcolor("red")#嘴巴是红色的 a.begin_fill() a.fd(40) a.goto(40,-80) a.goto(-40,-80) a.goto(-40,0) a.goto(0,0) a.end_fill() a.goto(-20,0) a.fillcolor("black") a.begin_fill() a.goto(-20,15) a.goto(20,15) a.goto(20,0) a.goto(-20,0) a.end_fill() #皮卡丘鼻子 a.pensize(4) a.penup() a.goto(-10,70) a.pendown() a.fillcolor("black") a.begin_fill() for i in range(0,4,1): a.fd(20) a.right(90) a.end_fill() #皮卡丘的左眼睛 a.pensize(2) a.

javaparser - java源码分析修改框架

javaparser 包含一组实现具有高级分析功能的 Java 1.0 - Java 15 Parser 的库。 这包括 Java 13 的预览功能,Java 14 预览功能正在进行中。 Analyse: 编写可以遍历 Java 源代码并查找您感兴趣的模式的代码。Transform: 构建的工具不仅可以识别代码模式,还可以更改它们。Generate: 聪明点,不要花时间编写样板,生成它! 使用 demo工程: 从官方demo fork的工程里可以看到大部分使用示例(对应于官方指导文档里使用说明)。 查找指定方法调用所在的行数、函数名、类名 示例代码: public static void main(String[] args) throws Exception { CompilationUnit cu = StaticJavaParser.parse(new FileInputStream(FILE_PATH)); VoidVisitor<Void> methodCallVisitor = new MethodCallPrinter(); methodCallVisitor.visit(cu, null); } private static class MethodCallPrinter extends VoidVisitorAdapter<Void> { @Override public void visit(MethodCallExpr mc, Void arg) { super.visit(mc, arg); Range range = mc.getRange().orElse(Range.range(-1, -1, -1, -1)); int startLine = range.

使用Element-ui导航菜单的问题

今天在使用Element-ui导航菜单时候,点击让菜单折叠时候 本来是这样, 折叠之后 大家可以看出。折叠之后,有两个板块并不是和其他板块的颜色保持一致,而是出现的黄色,经过我仔细阅读Element-ui导航栏组件的API并未发现任何异常,但是我观察,没有在代码中加入Index属性的就会变成黄色 所以最后通过加入Index属性从而使得板块颜色一致。 这是使用侧边栏导航组件时候发生的问题。虽然不是什么大问题,但是记录一下, 希望大家不喜勿喷,谢谢,祝大家步步高升

print,printf,println的区别

2021年9月20日,我在使用Eclipse时,发现print和println都能用,而且没有报错,再联系之前学的C语言中的printf,于是查找资料,找到了它们之间的联系与区别。 一、功能不同 1、print:将信息显示在命令窗口中,输出光标定位在最后一个字符之后。 2、printf:将信息进行格式化显示在命令窗口中,输出光标定位在最后一个字符之后。 3、println:将信息显示在命令窗口中,输出光标换行定位在下一行开头。 二、语法不同 1、print:Print("\n ") = Println(" ")。 2、printf:System.out.println(" b"); 3、println:System.out.print(" ASD\n"); = System.out.println(" ASD")。 三、特点不同 1、print:是需求输出的一系列参数, 其个数务必与式样化字符串所阐明的输出参数个数一样多, 各参数之间用","分开。 2、printf:式样化规定字符, 以"%"开端, 后跟一个或几个规定字符, 用来确定输出内容式样。 3、println:从右到左压栈,然后将先读取放到栈底,最后读取的放在栈顶,处理时候是从栈顶开始的。 笔记1

ubuntu安装dotnet

ubuntu安装.net 使用包安装 将 Microsoft 包签名密钥添加到受信任密钥列表,并添加包存储库。 wget https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb sudo dpkg -i packages-microsoft-prod.deb rm packages-microsoft-prod.deb 安装SDK .NET SDK 使你可以通过 .NET 开发应用。 如果安装 .NET SDK,则无需安装相应的运行时。 若要安装 .NET SDK,请运行以下命令: sudo apt-get update; \ sudo apt-get install -y apt-transport-https && \ sudo apt-get update && \ sudo apt-get install -y dotnet-sdk-3.1 测试 手动安装 下载二进制包 .NET 5.0 下载.NET Core 3.1 下载.NET Core 2.1 下载所有 .NET Core 下载项 配置环境变量 接下来,提取已下载的文件并使用 export 命令将 DOTNET_ROOT 设置为提取文件夹的位置,然后确保 .

OpenFeign的降级配置

OpenFeign的降级配置 前言OpenFeign基本使用OpenFeign设置降级 前言 当我们需要调用其他微服务或者第三方接口时,我们可能会使用Dubbo或者Spring自带的组件RestTemplate,但相对于前面两位来说 我还是比较喜欢使用SpringCloud的组件Feign的,在我看来Feign的使用还是比较灵活的。 OpenFeign基本使用 懒得自己写一个微服务,这里我在网上搜了一个第三方接口: https://api.imjad.cn/cloudmusic/?type=song&id=32785674 以这个接口为例 使用OpenFeign需要的依赖 <dependencies> <!-- SpringBoot的依赖配置--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.5.0</version> <type>pom</type> <scope>import</scope> </dependency> <!--远程接口调用--> <!--openFeign--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <!-- SpringCloud 微服务 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>2020.0.3</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> 这里SpringBoot版本我用的2.5.0 SpringCloud的版本是2020.0.3 编写Feign相关的逻辑 1、首先需要在主方法类上加上 @EnableFeignClients 2、编写feign的接口 import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; @FeignClient(url="https://api.imjad.cn", name = "music") public interface RemoteMusicService { @GetMapping("/cloudmusic") public Object getMusic(@RequestParam("type") String type, @RequestParam("id") String id); } 3、写个controller调用RemoteMusicService

Python数据分析与挖掘——使用Matplotlib绘制直方图

1. 使用hist绘制频数直方图 在Matplotlib中有一个专门绘制直方图的函数hist(),用来显示一组数据的分布情况。 使用hist()函数,无需对数据进行分拣整理,即可自动生成直方图。使用格式如下: plt.hist(x, bins) # 参数名基于官方文档声明 参数x:用于绘制直方图的一维数组,列表或者DataFrame的列向量形式。 参数bins:分两种情况: (1)一个整数,按照数组的最小取值范围(即以数组的最小值和最大值作为区间的两端点)均匀分为若干组。 (2)数字列表,以列表的各个数字作为分组的边界点。 例如,随机生成一个含有1000个元素的服从标准正态分布的数组,绘制直方图,代码如下: # -*- coding: utf-8 -*- import numpy as np import matplotlib.pyplot as plt # 导入图像库 plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签 plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号 plt.figure(figsize=(7,5)) data = np.random.randn(1000) # 1000个服从标准正态分布的随机数 plt.hist(data, 10) # 分成10组,结果如图1 plt.show() # div = [-4, -3.5, -3, ..., 3, 3.5, 4] div = [] x = -4 while x <= 4: div.

无锁队列概述

一、无锁队列原理 1、队列操作模型 队列是一种非常重要的数据结构,其特性是先进先出(FIFO),符合流水线业务流程。在进程间通信、网络通信间经常采用队列做缓存,缓解数据处理压力。 根据操作队列的场景分为:单生产者——单消费者、多生产者——单消费者、单生产者——多消费者、多生产者——多消费者四大模型。根据队列中数据分为:队列中的数据是定长的、队列中的数据是变长的。 (1)单生产者——单消费者 (2)多生产者——单消费者 (3)单生产者——多消费者 (4)多生产者——多消费者 (5)数据定长队列 (6)数据变长队列 2、 无锁队列 生产环境中广泛使用生产者和消费者模型,要求生产者在生产的同时,消费者可以进行消费,通常使用互斥锁保证数据同步。但线程互斥锁的开销仍然比较大,因此在要求高性能、低延时场景中,推荐使用无锁队列。 3、CAS操作 CAS即Compare and Swap,是所有CPU指令都支持CAS的原子操作(X86中CMPXCHG汇编指令),用于实现实现各种无锁(lock free)数据结构。 CAS操作的C语言实现如下: bool compare_and_swap ( int *memory_location, int expected_value, int new_value) { if (*memory_location == expected_value) { *memory_location = new_value; return true; } return false; } CAS用于检查一个内存位置是否包含预期值,如果包含,则把新值复赋值到内存位置。成功返回true,失败返回false。 (1)GCC对CAS支持 GCC4.1+版本中支持CAS原子操作。 bool __sync_bool_compare_and_swap (type *ptr, type oldval type newval, ...); type __sync_val_compare_and_swap (type *ptr, type oldval type newval, ...); (2)Windows对CAS支持 Windows中使用Windows API支持CAS。 LONG InterlockedCompareExchange( LONG volatile *Destination, LONG ExChange, LONG Comperand ); (3)C11对CAS支持

苹果官网查询产品的激活日期教程

PS:本方法支持 iPhone/iPad/iPod/Apple Watch/Mac 等所有苹果产品。 如何通过苹果设备序列号快速查询到设备的激活日期呢?分为以下两种情况: 情况一:设备在保修期内 第一步:进入下方网站,然后输入需要查询的设备的序列号,及验证码。 苹果官网序列号查询 第二步:在查询结果中有一个 预计到期日:2021年2月18日 我们往前推一年,即 2020年2月18日 为设备的激活日期。 情况二:设备已过保修期 可参考以下方法: 苹果已过保产品查询激活日期教程

vmtk c++ vs2019安装过程

写这篇日志是为了记录一下,也希望得到高人指点。 首先根据官网安装了python环境 这是我安装好以后 之后就可以配置在vs里面了 1.新建项目 2.打开项目->项目属性 在包含目录里面添加include\vmtk文件夹 在库目录添加lib文件夹 最后在连接器->输入->附加依赖项添加lib下的以.lib结尾的文件名

【详解】KMP算法——多图,多例子(c语言)

目录 前言 1.KMP算法是什么? 2.为什么需要KMP算法? 2.1主串找字串 2.2暴力求解 3.KMP准备工作 3.1字符串的前后子串 3.2最大前后相等子串 3.3最大前后相等子串练习 4.KMP算法 4.1简看KMP算法 5 Next数组 5.1j该回溯的位置 5.2学会计算Next数组 5.3用数学表示next数组(重点) 5.3.1arr2[k] == arr2[j] 5.3.2 arr2[k] != arr2[j] 5.3.3 k回溯到尽头 6.代码实现KMP 6.1KMP外壳 6.2KMP内核 6.3KMP全部代码 7.结语 前言 KMP算法作为程序员的必修课之一,其抽象的过程让初学者叫苦不迭,但是当你完全理解过后会发现其中蕴含着创造者的无穷智慧。本篇文章我将以大量的例子与图片,为你讲解这个奇妙的算法。 1.KMP算法是什么? KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt提出的,因此人们称它为克努特—莫里斯—普拉特操作(简称KMP算法)。KMP算法的核心是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。具体实现就是通过一个next()函数实现,函数本身包含了模式串的局部匹配信息。KMP算法的时间复杂度O(m+n) [1] 。(来自百度百科) 简而言之就是:减少在主串找子串的过程中回退的次数。(先有个概念就行,后面会仔细讲解) 2.为什么需要KMP算法? 在回答这个问题前我们需要知道先知道两个问题。 什么叫主串找子串? 不用kmp算法,直接暴力求解是怎样的? 2.1主串找字串 现在我们有主串:arr1[] = "abababc",子串:arr2[] = “abc”。那么我们在arr1中找到arr2在其中位置的过程就叫做主串找子串。 2.2暴力求解 在暴力求解中,我们是将子串和主串逐一匹配,如果第一个字符相等就继续匹配第二个字符,直到子串与主串全都匹配成功,就返回子串的位置,一旦其中某两个字符匹配不成功,主串就回到开始匹配字符的下一字符,而子串回到第一字符。 上面的话可能有一点绕,那么看了下面的图片你就会明白暴力求解的思路。 还是这俩字符串,主串:arr1[] = "abababc",子串:arr2[] = “abc”。 (1) 第一次匹配成功,第二次匹配成功,第三次匹配不成功。 (2) 前面匹配失败,第一个字符串回到第二个字符'b',第二个字符串回到第一个字符'a'处。 第一次匹配失败。 (3) 前面匹配失败,第一个字符串回到第三个字符'a',第二个字符串回到第一个字符'a'处。 第一次匹配成功,第二次匹配成功,第三次匹配不成功。 (4) 前面匹配失败,第一个字符串回到第四个字符'b',第二个字符串回到第一个字符'a'处。 第一次匹配失败。 (5) 前面匹配失败,第一个字符串回到第五个字符'a',第二个字符串回到第一个字符'a'处。

遍历Map集合

遍历Map集合 keySet(); 通过map集合得到所有主键对象 values(); 通过map集合得到所有值对象 entrySet(); 通过map集合得到所有记录 (主键 + 值) jdk8.0之后添加了新的遍历方法 map.forEach((k,v) -> System.out.println(k + “” + v));

DFS——深度优先搜索——排列数字

DFS——深度优先搜索——排列数字 题目描述复杂度代码 题目描述 给定一个整数 n,将数字 1∼n 排成一排,将会有很多种排列方法。 现在,请你按照字典序将所有的排列方法输出。 输入格式 共一行,包含一个整数 n。 输出格式 按字典序输出所有排列方案,每个方案占一行。 数据范围 1≤n≤7 输入样例: 3 输出样例: 1 2 3 1 3 2 2 1 3 2 3 1 3 1 2 3 2 1 复杂度 时间复杂度为 O(n*n!)。空间复杂度为 O(n)。 代码 import java.util.*; public class Main{ static int N = 10,n;//需要搜索的个数 static int[] path = new int[N];//path[]用于保存路径 static boolean[] st = new boolean[N]; //用于记录 该步是否已经走过 public static void main(String[] args){ Scanner sc = new Scanner(System.

数据结构——在二叉树中查找指定的节点(Java)

依据二叉树的遍历方式,查找二叉树中的指定的节点,也有三种方式: 按照前序遍历的顺序查找: 正确代码: public Node preOrderSearch(int num) { System.out.println("当前的节点数值为:" + this.num); Node res = null; if (this.num == num) { return this; } if (this.left != null) { res = this.left.preOrderSearch(num); } if (res != null) { return res; } if (this.right != null) { res = this.right.preOrderSearch(num); } return res; } 在刚开始的时候,我认为没必要设置一个res的变量记录this.left.preOrderSearch(num)或者this.right.preOrderSearch(num)的值,思路和前序遍历的一样,只要判断该节点的值是不是要找的那个值即可,但是在运行代码以后,发现了问题。代码中构建的二叉树如下图所示。 (个人觉得:弄清楚递归程序最好的方式就是debug) 假设,要找到值为5的节点 递归程序的运行是这样的:【如果看不下去,可以直接设断点调试】 节点1,判断1和5的值相不相等,结果是不相等,判断左节点不为空,则进入左节点,左节点2与5不相等,则判断节点2有无左节点,节点2没有左节点,这时res=null,判断节点2有没有右节点,节点2没有右节点,所以回退到节点1判断左节点的时候,res的值为null,接着判断节点1的右节点是否为空,右节点不为空,进入右节点3,3不等于5,则继续判断节点3的左节点,节点3的左节点是5,这时,节点5就是我们要找的节点,则会把该节点返回,注意,返回到的节点是节点3的左节点判断语句,这时res被赋值为节点5,跳出if,进入判断res是否为空if语句,这时返回res,返回的值是到了节点1的右节点判断语句,res被赋值为节点5,这时节点1的左节点和右节点都判断完毕了,返回res,就可以输出了。 中序遍历和后序遍历也都是一样的理解方式。 单从要查找节点5这个具体的例子来说,后续遍历能够最快找到。 按照中序遍历的顺序查找 public Node infixOrderSearch(int num) { Node res = null; if (this.

iptables防火墙

目录 前言 一、Linux 防火墙基础 1.netfilter 与 iptables 2.iptables 的表、链结构 3.规则图 4.规则表 5.规则链 二、数据包过滤的匹配流程 1.规则表之间的顺序 2.规则链之间的顺序 3.规则链内部各条防火墙规则之间的顺序 三、编写防火墙规则 1.安装iptables 2.iptables的基本语法 3.数据包的常见控制类型 四、添加、查看、删除规则等基本操作 1.添加新的规则 2.查看规则列表 3.删除、清空规则 4.设置默认策略 五、规则的匹配条件 1.通用匹配 2.隐含匹配 3.显示匹配 总结 前言 在 Internet 中,企业通过各种应用系统来为用户提供各种服务,如 Web 网站、电子邮件系统、FTP 服务器、数据库系统等,那么,如何来保护这些服务器,过滤企业不需要的访问甚至是恶意的入侵呢? 一、Linux 防火墙基础 Linux 的防火墙体系主要工作在网络层,针对 TCP/IP 数据包实施过滤和限制,属于典型的包过滤防火墙(或称为网络层防火墙)。体现在对包内的 IP 地址、端口等信息的处理上。Linux 系统的防火墙基于内核编码实现,具有非常稳定的性能和极高的效率,也因此获得广泛的应用。 1.netfilter 与 iptables netfilter:是内核的一部分,由一些数据包过滤表组成,不以程序文或文件的形式存在;这些表包含内核用来控制数据包过滤处理的规则集;属于“内核态”(Kernel Space,又称为内核空间)的防火墙功能体系。 iptables:是一种用来管理Linux防火墙的命令程序,它使插入、修改和删除数据包过滤表中的规则变得容易,通常位于/sbin/iptables目录;属于“用户态”(User. Space,又称为用户空间) 的防火墙管理体系;iptables是基于内核的防火墙,其中内置了raw、mangle、 nat和filter四个规则表。表中所有规则配置后,立即生效,不需要重启服务。 2.iptables 的表、链结构 iptables的作用是为包过滤机制的实现提供规则(或称为策略),通过各种不同的规则,告诉 netfilter 对来自某些源、前往某些目的或具有某些协议特征的数据包应该如何处理。 每个规则表相当于内核空间的一个容器,根据规则集的不同用途划分为默认的四个表,在每个表容器内又包括不同的规则链,根据处理数据包的不同时机划分为五种链。 决定是否过滤或处理数据包的各种规则,按先后顺序存放在规则链中。 3.规则图 4.规则表 raw表:主要用来决定是否对数据包进行状态跟踪 包含两个规则链,OUTPUT、PREROUTING。 mangle表 : 修改数据包内容,用来做流量整形的,给数据包设置标记。包含五个规则链,INPUT、 OUTPUT、 FORWARD、 PREROUTING、 POSTROUTING。

Spring Cloud 整合 Swagger2 3.0.0 修改 baseURL

环境 Spring Cloud AlibabaNacosSwagger2 3.3.0System 服务 方法 修改 System 服务的 bootstrap.properties,添加以下内容 # swagger2 springfox.documentation.swagger.v2.path=/system/v2/api-docs # swagger3 springfox.documentation.open-api.v3.path=/system/v3/api-docs 说明 Swagger2 查看源码 包名: io.springfox:springfox-swagger2:3.0.0 类名:springfox.documentation.swagger2.web.Swagger2ControllerWebMvc @ApiIgnore @RestController @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) @RequestMapping(SWAGGER2_SPECIFICATION_PATH) @Conditional(OnServletBasedWebApplication.class) @Order(Ordered.HIGHEST_PRECEDENCE) public class Swagger2ControllerWebMvc { public static final String SWAGGER2_SPECIFICATION_PATH = "${springfox.documentation.swagger.v2.path:/v2/api-docs}"; ... } @RequestMapping 注解的值为:SWAGGER2_SPECIFICATION_PATH,该变量会读取 springfox.documentation.swagger.v2.path 配置的值,缺省值为:/v2/api-docs Swagger3 查看源码 包名:io.springfox:springfox-oas:3.0.0 类名:springfox.documentation.oas.web.OpenApiControllerWebMvc @ApiIgnore @RestController @RequestMapping(OPEN_API_SPECIFICATION_PATH) @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) @Conditional(OnServletBasedWebApplication.class) public class OpenApiControllerWebMvc { ... } @RequestMapping 注解的值为:OPEN_API_SPECIFICATION_PATH,该变量会读取 springfox.documentation.open-api.v3.path 配置的值,缺省值为:/v3/api-docs

大数据技术结构层次包含哪些部分

大数据技术结构层次包含哪些部分 大数据领域每年都会涌现出大量新的技术,大数据技术可以挖掘出大规模数据中隐藏的信息和知识,为人类社会经济活动提供依据,提高各领域的运行效率,甚至提高整个社会经济的集约化程度,那么大数据技术结构层次包含哪些部分呢?下面就一起来了解一下。 一、统一数据基础层: 我们通过各种方式采集到的丰富数据,在清洗、结构化后进入统一的ODS数据基础层。其主要功能包括: 1、同步:结构化数据增量或全量同步到数据中台。 2、结构化:非结构化(日志)结构化处理并存储到数据中台。 3、累积历史、清洗:根据数据业务需求及稽核和审计要求保存历史数据、数据清洗 在权责方面,所有数据应该在源头统一,统一所有的数据基础层,并由一个团队负责和管控,其他团队无权复制数据基础层的数据。 二、数据中间层: 我们进行数据建模研发,并处理不因业务特别是组织架构变动而轻易转移的数据中间层。包括DWD明细数据中间层和DWS汇总数据中间层。其主要功能包括: 1、组合相关和相似数据:采用明细宽表,复用关联计算,减少数据扫描。 2、公共指标统一加工:基于OneData体系构建命名规范、口径一致和算法统一的统计指标,为上层数据产-品、应用和服务提供公共指标;建立逻辑汇总宽表。 3、建立一致性维度:建立一致数据分析维度表,降低数据计算口径、算法不统一的风险。 三、数据应用层: 在面向应用提供服务时,业务团队或深入业务线的数据团队有极大的自由度,只要依赖数据公共层,即可自由的建设ADS数据应用层。其主要功能包括: 1、个性化指标加工:不公用性;复杂性(指数型、比值型、排名型指标)。 2、基于应用的数据组装:大宽表集市、横表转纵表、趋势指标串。 关于大数据技术结构层次包含哪些部分,就和您分享到这里了。如果您对大数据工程有浓厚的兴趣,希望这篇文章可以为您提供帮助。

炸裂,pandas实现列转行的几个实用技巧

大家好,我是阳哥。 还是在2017年的时候,分享过这个主题:Pandas中如何将一列中的文本拆分为多行? 由于当时pandas没有直接的方法来处理这种情形,因此当时使用的方法较为周折些。 在 Pandas 版本 0.25版本之后,pandas 提供了 explode 方法来处理这种数据情况。 因此,今天来介绍下 explode 方法的使用,同时也放上以前的处理方法,大家可以对比下。 三种方法: Method 1 (explode) Method 2 Method 3 01数据背景 在数据处理过程中,经常会遇到以下类型的数据: 在同一列中,本该分别填入多行中的数据,被填在一行里了,然而在分析的时候,需要拆分成为多行。 在上图中,列名为 "Country" ,index 为 4 和 5 的单元格内,值为 UK/Australia 和 UK/Netherland 。 今天,我们来介绍将含有多值的内容分拆成多行的几种方法。加载数据如下: import pandas as pd df = pd.DataFrame({'Country':['China','US','Japan','EU','UK/Australia', 'UK/Netherland'], 'Number':[100, 150, 120, 90, 30, 2], 'Value': [1, 2, 3, 4, 5, 6], 'label': list('abcdef')}) df Out[2]: Country Number Value label 0 China 100 1 a 1 US 150 2 b 2 Japan 120 3 c 3 EU 90 4 d 4 UK/Australia 30 5 e 5 UK/Netherland 2 6 f 02Method-1 Method-1 主要是使用 pandas 的 explode 方法来处理。

Git中的submodule操作

环境 windows 10 64-bit github 前言 子模块( submodule )是一个内嵌在 git 仓库(父工程)中的 git 仓库,有点儿拗口。通过子模块,可以将外部的仓库作为子目录放到自己的仓库中,既能方便的管理依赖,又可以保持依赖本身的独立性。 子模块将被记录在一个名叫 .gitmodules 的文件中,其中会记录子模块的相关信息 [submodule "module_name"] # 子模块的名称 path = file_path # 子模块在本仓库中文件的存储路径 url = repo_url # 子模块的远程仓库地址 前文我们介绍 基于YOLOv5和DeepSort的目标跟踪 时,它的代码仓库就是把 yolov5 作为子目录来进行管理 实践 本文在 github 平台上进行操作,其它基于 git 的管理平台也是类似的 新建项目 在 github 上创建一个新项目 gitDemo git submodule 然后,将上面创建好的项目克隆到本地 git clone https://github.com/xugaoxiang/gitDemo.git git submodule 添加子模块 现在开始来添加子模块,这里以 yolov5 为例,将其作为子模块放在 gitDemo 项目里 git submodule add https://github.com/ultralytics/yolov5.git git submodule 这时候的目录结构是这样的 git submodule 通过 git status 查看当前状态

大型数据库(1)--- Hive安装与配置

安装说明 安装环境 虚拟机:VirtualBox-6.1.18 操作系统:Ubuntu16.04LTS 基础软件 JDK:jdk-8u281-linux-x64.tar.gz hadoop:hadoop2.7.3 MySQL:Server version: 5.7.33-0ubuntu0.16.04.1 (Ubuntu) 集群情况: 主机名称Hadoop版本IP地址hadoop-master2.7.3192.168.56.1hadoop-slave12.7.3192.168.56.2hadoop-slave22.7.3192.168.56.3 本次安装的Hive Hive版本:3.1.2 下载地址:apache-hive-3.1.2-bin.tar.gz. 其他:Hive官网 、查看不同版本. 都准备就绪后,我们就接着往下开始安装吧! 不知道怎么准备的,我之前的文章 也许可以给你带来一些参考哦 - - - ☞ 传送门 开始安装 我的两个基础软件Hadoop、Java 分别是在/usr/hadoop 和 /usr/java下 其他的都安装在 ~/Hadoop 的文件夹下 Hive的安装仅在hadoop-master下安装即可,无需在slave机上部署 配置MySQL 没安装的直接用apt install安装即可,一搜一大把 当前是root用户登录mysql 1.创建hadoop用户 grant all on *.* to hadoop@'%' identified by 'hadoop'; grant all on *.* to hadoop@'localhost' identified by 'hadoop'; grant all on *.* to hadoop@'hadoop-master' identified by 'hadoop'; // mysql> grant all on *.

按关键字爬取网页信息

本文目的是简单的在选定浏览器页面,按照关键字爬取自己想要的信息,关键点为跳过反爬网页的反爬机制 。 使用UA伪装 User-Agent 我们使用所爬网站中的User-Agent来进行伪装,让它以为我们是它本身的一部分,从而使得我们能够成功爬取我们需要的信息。 各网站User-Agent查找方法 打开所要爬取的页面,按键盘F12,如下图内容: 代码模块 该代码用例是搜狗网站 import requests if __name__ == '__main__': # UA伪装 header = { 'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36' } # 1.指定url url = "https://www.sogou.com/web?" kw = input("请输入关键字:") param = { 'query' : kw } # 2.发送请求 response = requests.get(url=url,params=param,headers=header) #数据获取 html = response.text print(html) response.encoding = 'utf-8' fileName = kw + '.html' with open(fileName,'w',encoding='utf-8') as f: f.

前端渲染页面(template-web)

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> </head> <body> <ul></ul> <script src="libs/jquery.min.js"></script> <script src="libs/template-web.js"></script> <script type="text/template" id="templateLi"> {{each heroes}} <li><b>{{$value.name}}</b> <span>{{$value.age}}</span></li> {{/each}} </script> <script> $(function(){ const data={ 'heroes':[{ 'name':'王朝', 'age':19 },{ 'name':'马汉', 'age':20 }, { 'name':'张龙', 'age':21 }, { 'name':'赵虎', 'age':22 }] }; $('ul').html(template('templateLi',data)); }) </script> </body> </html>

java.lang.IllegalStateException: Failed to introspect Class

异常内容 [org.springframework.web.context.support.XmlWebApplicationContext] [Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'adminServiceImpl': Lookup method resolution failed; nested exception is java.lang.IllegalStateException: Failed to introspect Class [com.atguigu.crowd.service.impl.AdminServiceImpl] from ClassLoader [ParallelWebappClassLoader context: atcrowdfunding02_admin_webuis_war_exploded delegate: false ----------> Parent Classloader: java.net.URLClassLoader@10e31a9a ]] 错误原因 此异常原因是因为classA中使用了项目没有导入的类,从而导致类加载失败。一般来说如果使用了没有依赖的类应该会报ClassNotFindException的错误,但是如果只是导入却没有使用的使用可能就会报此错误。 通常此错误见与使用maven框架配置了第三方类的scope是provided的情况下。 笔者在使用springSecurity时由于在maven中导入了2个不同版本的jjar包,但是并没有使用,导致此错误。

make: *** /lib/modules/3.10.0-1160.el7.x86_64/build: No such file or directory. Stop.

这个问题应该是系统没有安装内核开发包, [root@localhost /]# cd /lib/modules/3.10.0-1160.el7.x86_64/ [root@localhost 3.10.0-1160.el7.x86_64]# ll total 3308 lrwxrwxrwx. 1 root root 39 Jan 1 09:15 build -> /usr/src/kernels/3.10.0-1160.el7.x86_64 drwxr-xr-x. 3 root root 23 Jan 1 09:16 extra drwxr-xr-x. 12 root root 128 Jan 1 09:15 kernel -rw-r--r--. 1 root root 860326 Jan 1 09:29 modules.alias -rw-r--r--. 1 root root 819744 Jan 1 09:29 modules.alias.bin -rw-r--r--. 1 root root 1333 Oct 20 2020 modules.block -rw-r--r--. 1 root root 7391 Oct 20 2020 modules.

Minio工具类

引入Maven依赖 <dependency> <groupId>io.minio</groupId> <artifactId>minio</artifactId> <version>8.3.0</version> </dependency> 配置文件 ## ====================== ↓↓↓↓↓↓ MinIO文件服务器 ↓↓↓↓↓↓ ====================== minio: url: http://192.168.1.222:7901/ #注意此处端口,并非Minio默认端口,并且不是Minio网页端口 accessKey: minio secretKey: minio@123 bucket: test 配置文件实体类 /** * @author Wang */ @Data @Validated @Component @ConfigurationProperties(prefix = "minio") public class MinioProperties { /** * 服务地址 */ @NotEmpty(message = "minio服务地址不可为空") @URL(message = "minio服务地址格式错误") private String url; /** * 认证账户 */ @NotEmpty(message = "minio认证账户不可为空") private String accessKey; /** * 认证密码 */ @NotEmpty(message = "minio认证密码不可为空") private String secretKey; /** * 桶名称, 优先级最低 */ private String bucket; /** * 桶不在的时候是否新建桶 */ private boolean createBucket = true; /** * 启动的时候检查桶是否存在 */ private boolean checkBucket = true; /** * 设置HTTP连接、写入和读取超时。值为0意味着没有超时 * HTTP连接超时,以毫秒为单位。 */ private long connectTimeout; /** * 设置HTTP连接、写入和读取超时。值为0意味着没有超时 * HTTP写超时,以毫秒为单位。 */ private long writeTimeout; /** * 设置HTTP连接、写入和读取超时。值为0意味着没有超时 * HTTP读取超时,以毫秒为单位。 */ private long readTimeout; } Springboot启动类 /** * 用户启动器 * * @author Chill */ @EnableBladeFeign @SpringCloudApplication @ConditionalOnClass(MinioClient.

在win10和Linux上配置SSH免密登录

服务器SSH免密登录 一、产生SSH公钥私钥对 NOTE: 1. 密钥对在一个机器上的一个用户中只需生成一次,以后不必再生成,可直接跳过此步骤执行公钥上传。 2. 公私钥删除或被覆盖会导致之前配置在远程服务器上的公钥失效,需要重新上传新的公钥。 1、在Linux (或macOS) 上产生SSH公私钥的方法 在本地终端执行命令 ssh-keygen 出现Enter file in which to save the key ,输入Enter保持默认路径若出现id_rsa already exists. Overwrite (y/n)? ,则说明已经生成过Key,可以输入no,直接跳过此步骤,也可以选择yes覆盖之前的Key,但这样做会使得公钥改变,之前配置过的公钥需要重新上传。出现Enter passphrase (empty for no passphrase) ,设置一个使用Key时的口令,若设置则每次使用Key登录依然要输入这个口令,可以不设置,直接输入Enter。出现Enter same passphrase again,依然直接输入Enter。Key生成结束,如下图: 到 /home/xx/.ssh/ 下查看密钥对是否生成。 2、在win10上产生SSH公私钥的方法 1)、检查windows 本地是否安装有ssh 检查方式:键入win+r输入cmd,打开windows powershell,输入ssh命令。已安装则会显示ssh命令提示。 否则先在本地安装openssh 2)、在本地生成SSH密钥对(公钥和私钥),用于和远程服务器取得联系。 输入命令ssh-keygen (过程与Linux生成过程一样) ​ 在提供的默认文件路径下保存密钥文件即可(点回车即可),默认路径:C:\Users\用户名\ .ssh文件夹。 ​3)、进入该文件路径,可以看到该目录下已生成id-rsa(私钥)和id-rsa.pub(公钥)两个文件。 二、上传公钥到远程服务器 NOTE:上述方法产生公钥和私钥后,可以在任意一台服务器中使用该公私钥对,只需要将这里的公钥上传到不同的服务器即可。 ssh-copy-id 命令可以把本地主机的公钥复制到远程主机用户下的.ssh目录中的authorized_keys文件上,ssh-copy-id命令也会给远程主机的用户主目录(home)和~/.ssh, 和~/.ssh/authorized_keys设置合适的权限,无需其他配置。 1、在本地Linux (或macOS) 上使用 ssh-copy-id 的方式上传公钥 1)、确保远程服务器可连接。2)、输入命令:ssh-copy-id 用户名@IP -p 22,输入密码后即可将公钥上传到指定服务器的指定用户下。3)、再次使用ssh登录命令即可使用Key的方式免密登录到服务器中。4)、使用scp命令时要在scp后面加 -P 22(注意大写)。 2、在windows上使用 ssh-copy-id 的方式 1)、win10上无法直接使用ssh-copy-id命令,需要安装Linux子系统,安装方法见windows10安装linux子系统(WSL)。2)、安装成功并创建一个用户后输入命令:cd /mnt/c/Users/xx/.

简要说明对称加密和非对称加密的原理以及区别是什么

对称加密的原理是数据发送方将明文(原始数据)和加密密钥一起经过特殊加密算法处理后,使其变成复杂的加密密文发送出去。接收方收到密文后,若想解读原文,则需要使用加密密钥及相同算法的逆算法对密文进行解密,才能使其恢复成可读明文。 非对称加密的原理是甲方首先生成一对密钥同时将其中的一把作为公开密钥;得到公开密钥的乙方再使用该密钥对需要加密的信息进行加密后再发送给甲方;甲方再使用另一把对应的私有密钥对加密后的信息进行解密,这样就实现了机密数据传输。 对称加密和非对称加密的区别为: **密钥不同、安全性不同、数字签名不同。**一、密钥不同 1、对称加密:对称加密加密和解密使用同一个密钥。 2、非对称加密:非对称加密加密和解密所使用的不是同一个密钥,需要两个密钥来进行加密和解密。 二、安全性不同 1、对称加密:对称加密如果用于通过网络传输加密文件,那么不管使用任何方法将密钥告诉对方,都有可能被窃听。 2、非对称加密:非对称加密因为它包含有两个密钥,且仅有其中的“公钥”是可以被公开的,接收方只需要使用自己已持有的私钥进行解密,这样就可以很好的避免密钥在传输过程中产生的安全问题。 三、数字签名不同 1、对称加密:对称加密不可以用于数字签名和数字鉴别。 2、非对称加密:非对称加密可以用于数字签名和数字鉴别。

爬虫|wallhere壁纸批量下载

大家好,我是36度道,人生苦短,我用python ! 今日目标:批量下载wallhere网站上的壁纸 目标网址:https://wallhere.com/zh/wallpapers 首页图: 按 F12 查看网页源代码,搜索img标签,可以看到现在有120张图片 如果想要更多的图片,需要往下拉,网页会自动往下加载新的图片 为了截这张图,拉了老长了…现在加载到了240张图片 也就是说 只有执行了“下拉”这个操作,才会加载出新的图片。这时,就不能单纯地从网页源代码中采集了,因为它是通过ajax动态加载的数据。 所以要先找到这些加载的新图片是通过什么请求而加载到网页上的 打开“开发者工具”,边往下拉,边看 network 的 Fetch/XHR 里发送了什么请求。 结果发现,新的图片的源代码保存在https://wallhere.com/zh/wallpapers?page=2&format=json这个请求下,该请求返回的是一个json数据,可以通过json()方法获取。其中源代码保存在data 这个key下 找到了图片的存储路径就好办了 现在看下这个请求的请求方式和参数信息 发现是get请求,并且可传入两个参数,分别是page和format page表示页数,每下拉加载新数据时,page就会加1。所以我们可以通过翻页来实现“下拉”的动作 format在这应该表示返回的格式是json吧, 照着写上去就完事,不写可能也行,自行尝试 ok,准备工作已完成,接下来直接上代码 import requests import time from bs4 import BeautifulSoup headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36'} # 用来计数并作为图片名称 count = 0 # 获取前5页的图片 for page in range(1, 6): url = "https://wallhere.com/zh/wallpapers?page=%s&format=json" % page # 使用json()将字符串转化为json格式,并获取源代码 json_data = requests.

ADB使用总结(二):模拟用户手势实现自动化测试【多线程版】

前段时间写了如何用adb的调试命令+PowerShell实现自动化测试的例子(ADB使用总结(一):模拟用户手势实现自动化测试),没想到意外的小火了一把。很多小伙伴也私信我能不能多个手机一起运行,毕竟多线程运行才是真实场景。 这不正好前端时间家里领导换手机了,本着废物利用的原则,研究一下怎么把闲置的这台手机运行一个多机测试版。 目录 PowerShell 系列文章 1. 准备 2. 设置手机 3. 修改之前命令 4. 两个手机同时运行 5. 总结(注意事项) 1. 准备 本人用了两台手机,一台OPPO,一台小米,没办法性价比在那里。 2. 设置手机 检查手机的调试模式是否开启。针对小米手机的检查和开启方法如下: 进入设置->更多设置 看是否有开发者选项,如下: 如果有那么恭喜你已经开启。 如果没有,那么按照下面的方法开启开发者模式: 进入 设置->我的设备->全部参数->(连续点击5次)MIUI版本 好了开启了开发者模式。进入开发者选项再做一点点设置即可。 进入设置->更多设置->开发者选项 打开USB调试和USB调试(安全设置) 如果不设置 USB调试(安全设置)在运行ADB命令的时候可能会出现下面的错误: 然后用USB线连接电脑,选仅充电就行了。第一次打开调试选项连接电脑的时候可能会弹出确认框,确认是否允许调试。点确认就行了。OK手机的准备工作就完成了。至于电脑端的设置可以参考我前一篇博文:ADB使用总结(一):模拟用户手势实现自动化测试 3. 修改之前命令 好了一切都设置好,把两个手机同时连上电脑,见证奇迹的时刻到了。先看一下连接的设备是否都好了,如下所示: adb devices List of devices attached 7d2a68900412 device b0411dd1 device 如果有任何设备显示Unauthorized那就是连上电脑之后没有确认允许调试,把手机拔了重新接上电脑 ,弹出确认框时点确认就可以了。直到状态变成上面的样子,前面的编号是手机的ID,一会儿后面要用到。 然后把之前的命令稍稍改一下: adb -s 7d2a68900412 input swipe 300 600 300 100 # -s 7d2a68900412 就是指定在那一台设备上运行命令。 # 再试试另外一台设备有没有正常的滑动 adb -s b0411dd1 input swipe 300 600 300 100 4.

活文档:与代码共同演进 —— 摘录

让知识容易获取 要将知识从技术人员的大脑传递到非技术人员的大脑,需要将知识变得更易于获取。使知识变得易于获取的另一种情况是使其能被有效地搜索到。—— 1.4 文档是为了传递知识 更喜欢固有文档 存储文档的最佳位置是被记录的事物本身。—— 1.7 固有文档 单一来源发布 每一项知识都只放在一个地方,使其成为权威性知识来源。当文档受众无法直接访问这些知识,而你又必须为他们提供这些知识时,请从该单一知识来源发布文件。不要通过复制和粘贴的方法将知识元素包含到要发布的文档中,而是使用自动化机制直接从单一的权威性知识来源创建需要发布的文档。—— 3.3 单一来源发布 嵌入式学习 在代码中加入更多知识不仅仅是为了编写文档,还能有意识地帮助提高团队工作的技能。在制定你的增强代码策略时,请给它一个机会。代码增强时,想想当你的同事发现这段代码时会做何反应。—— 4.2.3 嵌入式学习 记录决策依据 如果你能马上告诉我你的意图和背景信息,那么只要我是一个熟练的专业人员,我就可能会做出与你相同的决策。但是,如果没有意图和背景信息,你就会想知道 “他们当时在想什么”。—— 4.9 记录你的决策依据 将依据记录作为推动变更的因素 如果你做得一个变更引发了一个被遗忘的问题,而你没有看到这个问题是因为它没有被记录在案,那么可能会在无意中造成伤害。—— 4.9.6 将依据记录作为推动变更的因素 将提交信息作为全面的文档 精心编写的提交信息使每一行代码都有据可查。将文件提交到源代码控制系统中时,添加包含提交信息的有意义的注释是良好实践。人们经常会忽略这个操作,结果就是还要浪费时间打开文件来查找更改的内容。—— 4.11 将提交信息作为全面的文档 为代码提供指引 熟悉代码库的过程可能类似于熟悉城市的过程,然而代码库比大多数城市变化得更快。因此,必须为代码库提供指引,以保证后期只需要做最少的工作就能使其保持最新。—— 5.4 导览和观光地图 活文档 活文档是根据权威性来源的最新知识自动生成的文档。—— 8. 可重构文档 依靠框架编码 当你使用诸如 Spring Boot 之类的的现成框架时,你的代码必须符合框架的要求。你写出来的代码不会太出乎人意料,而且当你熟悉了框架后,就可以理解大多数代码,从知识转移的角度来说这是一件好事。—— 8.2.3 依靠框架编码 不稳定到稳定的依赖关系 引用稳定的内容不会产生很高的成本,因为这种依赖关系不会经常改变,所以不会产生太多影响。反过来,如果引用的是不稳定内容,那么只要依赖关系发生变化,你就必须一直更改。这个理念同时适用于代码和文档。—— 9.3.1 不稳定到稳定的依赖关系 投资稳定知识 稳定知识是一项可以长期收益的投资。学习一个主题是一项昂贵的投资。学习那些过个几年就要更新的技术,我觉得很难。业务领域知识和软件架构的基础知识是常青内容,特别值得学习。—— 9.6 投资稳定知识 在白板上进行对话 人们在白板前一起工作和交谈是最有效的沟通方式,而纸上的交流则是最无效的沟通方式。在大多数情况下,要实现有效的知识共享,最好是通过简单的交谈、提问和回答来完成,而不是通过书面文档。—— 10.1 关于正式文档的对话 文档是一种代码审查方式 文档使产品和开发过程更加透明。因此,文档也是一个有用的反馈工具,可以帮你在应用程序的整个生命周期中进行调整和更正。—— 11.2.2 文档是一种代码审查方式 向上管理 软件开发领域有一个很大的问题,就是管理预算并做出最大决策的人员根本看不到软件的内部质量。这种对内部质量意识的缺失会阻碍这些人做出明智的决定。如果开发人员能够让非技术人员感性地理解代码的内部质量,他们会变得更有说服力。管理层常常会质疑开发人员的意见。相比之下,管理层更能接受工具的输出,因为工具是中立且客观的(或者至少他们认为是这样的)。—— 11.8.2 使用正压清洁内部 我们需要文档 虽然没有明确的文档我们也能活,任何人都可以上手一个未知的系统并让它正常运行。但是让它工作是一个很低的门槛,而让它工作可能需要很长时间。文档可以加快交付速度,因为他可以缩短你重建系统思维模型的时间。另一个作用是尝试记录系统相关的知识是了解系统不正确之处的好办法。—— 我们真的需要文档 从成本考虑 编写文档是进行测试和编写源代码等昂贵成本之前的低成本手段(PS:原话我找不到了,看到的朋友麻烦留个言,我重新去找一下)

[LeetCode刷题] 62.不同路径--Java实现

[LeetCode刷题] 62.不同路径–Java实现 刷题汇总 题目链接 https://leetcode-cn.com/problems/unique-paths/ 题目描述 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。 问总共有多少条不同的路径? 示例 1: 输入:m = 3, n = 7 输出:28 示例 2: 输入:m = 3, n = 2 输出:3 解释: 从左上角开始,总共有 3 条路径可以到达右下角。 向右 -> 向下 -> 向下向下 -> 向下 -> 向右向下 -> 向右 -> 向下 示例 3: 输入:m = 7, n = 3 输出:28 示例 4: 输入:m = 3, n = 3

单页面应用的首屏加载慢的问题

首屏加载太慢的问题 原因:因为第一次要把所有页面组件内容下载下来 解决: 异步延迟加载(脚手架默认选择) 打包时,每个文件打包为单独文件首屏加载时,只强制加载第一个组件的内容,后续组件由底层程序异步加载 优点:不影响首屏加载速度,又能实现单页面应用的效果 缺点:因为即使用户不看其他组件的内容,也会下载其他组件,浪费网络流量 懒加载(可通过配置脚手架实现) 打包时,每个文件打包为单独文件首屏加载时,不会下载其他组件只有当用户切换到其他某个组件时,才临时下载用户想看的组件 优点:省流量 缺点:下载速度比加载本地组件稍慢

nginx代理ftp端口,实现文件传输

1.需求背景 2.安装nginx 查看nginx离线安装 这里补充下:因为代理ftp端口需要用到nginx的stream模块,所以在配置nginx的时候需带上参数: --with-stream 核心配置: stream { upstream ftpServer { server 172.16.2.30:40000 max_fails=3 fail_timeout=5s weight=1; } #转发控制连接请求 server { listen 34000; #监听端口 #失败重试 proxy_next_upstream on; proxy_next_upstream_timeout 0; proxy_next_upstream_tries 0; #超时配置 proxy_connect_timeout 1s; proxy_timeout 10m; #限速配置 proxy_upload_rate 1024k; proxy_download_rate 2048k; #上游服务器 proxy_pass ftpServer; } upstream ftp_pasv1 { server 172.16.2.30:40001 max_fails=3 fail_timeout=5s weight=1; } upstream ftp_pasv2 { server 172.16.2.30:40002 max_fails=3 fail_timeout=5s weight=1; } upstream ftp_pasv3 { server 172.16.2.30:40003 max_fails=3 fail_timeout=5s weight=1; } #转发数据连接请求 server { listen 34001; proxy_pass ftp_pasv1; } server { listen 34002; proxy_pass ftp_pasv2; } server { listen 34003; proxy_pass ftp_pasv3; } } 3.

Java数组实现栈

import java.util.EmptyStackException; public class Stack { /** * 栈顶指针,-1代表空栈 */ private int top = -1; /** * 容量大小默认为10 */ private int capacity = 10; /** * 存放元素的数组 */ private int[] array; /*栈被使用的大小*/ private int size; public Stack() { array = new int[capacity]; } /** * 栈是否为空 */ boolean isEmpty() { return size == 0; } int size() { return size; } /** * data元素入栈 */ void push(int data) { if (array.

RecyclerView的ViewHolder复用错乱问题处理

关于RecyclerView复用错乱问题的处理方法网上大部分是以下几种 1.最简单直接的方法ViewHolder不可复用(尽量不要使用此方法) viewHolder.setIsRecyclable(false) 2.在onBindViewHolder里给View设置展示前,都需要将当前View的状态置为初始状态,其中if里设置的一定要在else里还原。 (注意此处的item为数据模型的字段,尽量使用数据模型内字段来区分要展示) if(item.isChecked){ textView.setText("展示"); }else{ textView.setText("收起"); } 3.通过onBindViewHolder中的position或者viewHolder的getAdapterPosition来判断展示。 4.通过设置Tag来判断展示 5.如果是onBindViewHolder没有被调用,尝试是不是没重写getItemViewType导致。 @Override public int getItemViewType(int position) { return position; } 再没被调用可以尝试调整 RecyclerView 的复用逻辑和方式来解决 onBindViewHolder 没有调用的这个问题。 recyclerView.setItemViewCacheSize(int) 6.以上方法都不管用的话,可以检查下是否在onBindViewHolder使用了异步回调改变View状态,而在异步回来之前Adapter调用了notifyDataSetChanged()等刷新方法导致ViewHolder被刷新复用导致。如果是这种情况,需要保证避免异步回来之前刷新即可解决。

数组--二维数组转为一维数组

a.二维数组转为一维数组: i.reduce() 方法 接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。对空数组是不会执行回调函数的 语法:array.reduce(function(total,currentValuue,currentIndex,arr),initiaValue) let arr = [ [1, 4, 5, 6], [8, 4, 7, 6], [1, 5, 10, 47] ]; let arr1 = arr.reduce((total, currentValue) => { return total.concat(currentValue); }); console.log(arr1); ii.map() map()方法定义在JavaScript的Array中,返回一个新的数组,新返回数组中的每个元素为原始数组的每一个元素分别调用map中的回调函数处理后的值 注意: 不会对空数组进行检测不会改变原始数组(返回新数组)不会为数组中缺少的元素调用回调函数除数组对象外,map()可由具有length属性且具有已按数字编制索引名的任何对象使用(如字符串对象) 语法: array.map(function(currentValue, index, arr), thisIndex) currentValue:必须。当前元素的的值。index:可选。当前元素的索引。arr:可选。当前元素属于的数组对象。thisValue:可选。对象作为该执行回调时使用,传递给函数,用作"this"的值 let arr = [ [1, 4, 5, 6], [8, 4, 7, 6], [1, 5, 10, 47] ]; function flatten(arr) { /** * ...arr ==> 等价于 [1, 4, 5, 6] [8, 4, 7, 6] [1, 5, 10, 47] * currentValue => 等价于 上面的一个个一维数组 */ return [].

Dataframe获取元素值的几种方法

目录 pandas.DataFrame.iat 根据行索引和列索引获取元素值 pandas.DataFrame.loc 样例 选取元素 选取行返回一个series 选取行列返回dataframe pandas.DataFrame.iloc 样例 按索引选取元素 获取行的series pandas.DataFrame.iat 根据行索引和列索引获取元素值 >>> df = pd.DataFrame([[0, 2, 3], [0, 4, 1], [10, 20, 30]], ... columns=['A', 'B', 'C']) >>> df A B C 0 0 2 3 1 0 4 1 2 10 20 30 >>> df.iat[1, 2] 1 >>> df.iloc[0].iat[1] 2 pandas.DataFrame.loc 样例 >>> df = pd.DataFrame([[1, 2], [4, 5], [7, 8]], ... index=['cobra', 'viper', 'sidewinder'],

mvn dependency:copy-dependencies -DoutputDirectory=lib package报错

mvn dependency:copy-dependencies -DoutputDirectory=lib package 报错 根据错误提示,调用 mvn dependency:copy-dependencies -DoutputDirectory=lib package -e -X 发现是因为 Cannot access in offline mode 的问题 解决方案: idea -> setting -> maven 取消勾选 Work offline

google benchmark安装编译测试一条龙服务

google benchmark 首先还是建议大家认真阅读github上的描述,我也是除了很多差错,最后发现还是官网真香 环境:Ubuntu20.04.1 安装编译benchmark 安装git和cmake$ git clone https://github.com/google/benchmark.git$ cd benchmark$ cmake -E make_directory "build"$ cmake -E chdir "build" cmake -DBENCHMARK_DOWNLOAD_DEPENDENCIES=on -DCMAKE_BUILD_TYPE=Release ../$ cmake --build "build" --config Release 测试benchmark 创建demo.cpp文件,如下 #include <benchmark/benchmark.h> #include <iostream> #include <string> using namespace std; void demo() { string str = "hello world"; str.size(); } static void BM_demo(benchmark::State& state) { for (auto _ : state) demo(); } BENCHMARK(BM_demo); BENCHMARK_MAIN(); $ g++ demo demo.cpp -std=c++11 -lbenchmark -lpthread 这里也有可能会报错:

远程登录出现的问题

远程登录 window server 系统,应该是直接在控制面板>系统和安全>系统 这个界面中,打开远程设置。分别勾选容许 和容许较不安全那个选项的连接。 如果是win7 可能需要到 电脑 右键>管理>本地用户组>用户 我只是学习,所以把其他账户删除了,只留了一个Admin和一个Guest 管理员账户我设置了一个密码。 然后应该就可以了,在另外一台电脑,直接在远程登录功能窗口输入账户密码即可。 注销重启,以管理员账户登录后,发现桌面文件消失,这时候到C盘中用户这个目录里面,找到原来的账号,把里面桌面文件夹中的东西copy出来即可。

npm ERR! path blog\node_modules\canvas

问题描述 最近想用gitee搭建一个个人博客,参考的是这篇文章:使用hexo和gitee搭建免费个人博客详细教程 但是在执行命令hexo init blog后提示我缺少一些依赖包,于是我按照提示执行了如下命令: cd blog npm install 结果就产生了如下报错: npm ERR! path D:\Page\blog\node_modules\canvas npm ERR! command failed npm ERR! command C:\WINDOWS\system32\cmd.exe /d /s /c node-gyp rebuild npm ERR! Warning: Missing input files: npm ERR! C:\GTK\bin\libgobject-2.0-0.dll npm ERR! C:\GTK\bin\libpangoft2-1.0-0.dll 解决方案 显然,从报错里我们看到,原因在于canvas包,也就是说我们需要先手动安装canvas包,参考Can’t install canvas提供的解决方案 安装node-gyp npm install -g node-gyp 下载GTK2并解压到C:GTK安装canvas npm install -g canvas 再在blog文件夹下执行: npm install

顺时针是往左还是往右?

顺时针是往左还是往右? 相信大部分和我一样,答案是 往右。 然而,今晚和室友聊天,无意间她表达顺时针是往左😅 我和其他两位室友一脸震惊。 后来她还拧水龙头给我们展示 顺时针是如何往左转的。 她指着水龙头的下方说:你们看,它是不是往左? 另外两个室友看着她的操作,竟一时语塞,怀疑人生……在她反复操作几次后都要动摇自己的观点了😅 我在一旁看不下去了,指着水龙头的上方说 那这里是往左还是往右转呀? 后来思考了一下,我觉得这个好像并不能一口咬定到底是往左还是往右。 于是通过百度百科搜索了一下,顺时针的定义:顺时针方向运行指依从时针移动的方向运行,由右上方向下,然后转向左,再回到上。 因此,看问题的角度不同得到的答案也就不同,每个人都有自己的观点,多与人沟通,交换观点,改掉自己的惯性思维。 还有一点很重要,实践出真理,不要轻信别人的话,要自己动手试一试才能得出适合自己的结论。

对公平席位分配问题的探讨:最大余数法、Q值法和D’Hondt方法及其特例|公平分配原则等

公平席位分配问题 本文研究公平的席位分配问题。对席位分配问题中经典的最大余数法、Q值法和D’Hondt方法进行研究和比较,在提出公平性判断原则的基础上,分析其优缺点。本文使用Matlab搭建三种席位分配模型,并对结果展开讨论。给出最大余数法、Q值法和D’Hondt方法的特例,并提出了一种改进最大余数法的方法,即“调和平均法”。 目 录 1.1 问题背景 1 1.2 待解决的问题 1 2.1 不公平情况的定义 1 2.2 公平分配的原则 1 3.1 最大余数法 2 3.2 Q值法 2 3.3 D’Hondt方法 3 4.1 结果分析 4 4.2 模型评价 4 4.2.1 Q值法不满足原则一的反例 4 4.2.2 D’Hondt方法满足原则一/二吗? 5 4.2.3 我提出的名额分配方法:调和平均法 5 4.2.4 其他公平分配的理想化原则 5 第1章 问题重述 1.1 问题背景 席位分配问题是人类社会生活中相当普遍的一类资源分配问题,是数学在政治领域中的典型应用。其目标是在对各小集体进行某种资源分配时,试图尽可能做到公平合理。比如,美国国会的参议院中各州享有等额议席,而众议院议员的名额按各州人口比例分配,“按人口比例分配议员名额”始终未能找到公平的解决方法。 1.2 待解决的问题 假设在甲、乙、丙三系学生中分配席位,三系学生人数分别为103、63、34。根据日常经验,若按照“比例加惯例”(也被称为最大余数法)分配席位,则在20个席位时,丙分得4席,而当席位数升至21席时,丙分得的席位数却降为3席,显然对丙来说,该席位分配原则并不公平,这个问题称为人口悖论。 本文引用公平席位分配的两个原则,依次验证最大余数法、Q值法和D’Hondt方法在各原则上的表现情况。用Matlab建立模型,在1000名学生(甲系:235,乙系:333,丙系:432)的席位分配问题中,席位数为10和15人的情况下分别运用各模型,并将结果进行比较。在进一步分析中,给出Q值法不满足“原则一”的反例和D’Hondt方法是否满足“原则一/二”的证明。 第2章 模型假设 2.1 不公平情况的定义 2.2 公平分配原则 第2章 模型搭建 3.1 最大余数法 3.2 Q值法 3.3 D’Hondt方法 第四章 结果分析 4.2 模型评价 Q值法不满足原则一的反例 D‘Hondt方法是否满足原则一/二 分配问题的改进和其他理想化原则 Matlab代码 参考文献 转载需注明出处:©️ Sylvan Ding blog.

vs2013配置gdal(含vs2013编译过的gdal文件夹)

一、准备资源 这里准备的是资源是编译过的gdal文件夹,下载解压后如下图所示: 二、配置过程 新建一个名为gdal_text的项目。 在附加选项中选中空项目。 2.1配置附加包含目录 2.2配置附加库目录 2.3配置附加依赖项 2.4配置环境变量 2.4测试 //C: / Users / CHENSHUAISHUAI / Pictures / Saved Pictures / 001.jpg #include "gdal_priv.h" #include<iostream> using namespace std; int main() { const char* pszFile; GDALAllRegister(); pszFile = "C:/Users/CHENSHUAISHUAI/Pictures/Saved Pictures/001.jpg"; GDALDataset *poDataset = (GDALDataset*)GDALOpen(pszFile, GA_ReadOnly); GDALRasterBand *poBand = poDataset->GetRasterBand(1); int xsize = poBand->GetXSize(); int ysize = poBand->GetYSize(); cout << xsize << endl; cout << ysize << endl; system("pause"); return 0; } 说明配置成功。

使用 vue-splitpane 实现页面可拖动改变宽高

安装及注册 vue-splitpane,在main.js 里全局注册 npm install vue-splitpane #import import splitPane from 'vue-splitpane' # use as global component Vue.component('split-pane', splitPane); 页面中使用 <div className="container"> <split-pane :min-percent='0' :default-percent='15' split="vertical"> <template slot="paneL"> <div className="left-container"/> </template> <template slot="paneR"> <split-pane split="horizontal"> <template slot="paneL"> <div className="top-container"/> </template> <template slot="paneR"> <div className="bottom-container"/> </template> </split-pane> </template> </split-pane> </div>