leetcode295 一道题认识大顶堆和小顶堆

LC295:数据流的中位数 简单来说就是计算中位数。 这里采用大顶堆和小顶堆来分别存储中位数的两边。 1 堆排序 堆排序(Heap Sort)是利用堆这种数据结构所设计的一种排序算法。 堆:是一棵完全二叉树的结构,并且满足堆积的性质:每个节点(叶节点除外)的值都大于等于(或都小于等于)它的子节点。 堆排序先按从上到下、从左到右的顺序将待排序列表中的元素构造成一棵完全二叉树,然后对完全二叉树进行调整,使其满足: 堆积的性质:每个节点(叶节点除外)的值都大于等于(或都小于等于)它的子节点。 构建出堆后,将堆顶与堆尾进行交换,然后将堆尾从堆中取出来,取出来的数据就是最大(或最小)的数据。重复构建堆并将堆顶和堆尾进行交换,取出堆尾的数据,直到堆中的数据全部被取出,列表排序完成。 堆结构分为大顶堆和小顶堆: 大顶堆:每个节点(叶节点除外)的值都大于等于其子节点的值,根节点的值是所有节点中最大的,所以叫大顶堆,在堆排序算法中用于升序排列(因为尾部取出,从小的开始)。 小顶堆:每个节点(叶节点除外)的值都小于等于其子节点的值,根节点的值是所有节点中最小的,所以叫小顶堆,在堆排序算法中用于降序排列。 2 大顶/小顶堆创建和排序 python.heapq创建小顶堆 使用heapq库创建小顶堆。 创建函数有两个,heapq.heappush和heapq.heapify。前者逐个构建,后者一次性构建。 # coding=utf-8 import heapq array = [10, 17, 50, 7, 30, 24, 27, 45, 15, 5, 36, 21] heap = [] for num in array: heapq.heappush(heap, num) print("array:", array) print("heap1: ", heap) heapq.heapify(array) print("heap2:", array) 得到: array: [10, 17, 50, 7, 30, 24, 27, 45, 15, 5, 36, 21] heap1: [5, 7, 21, 15, 10, 24, 27, 45, 17, 30, 36, 50] heap2: [5, 7, 21, 10, 17, 24, 27, 45, 15, 30, 36, 50] heap1:

git pull指令报错:error: You have not concluded your merge (MERGE_HEAD exists).

使用git pull 指令时报错:error: You have not concluded your merge (MERGE_HEAD exists). 直接翻译上面的报错信息可知: 错误:您尚未结束合并(merge_HEAD存在)。 提示:请在合并之前提交您的更改。 致命:由于未完成合并而退出。 通过上面的信息多少知道了自己错误的根源。 首先我本地是有一些已经commit的代码,但是还没有push到远程。 我在git pull指令执行之后,从远程拉取代码到本地,会自动执行一个merge操作,如果有冲突,就会merge失败,正常情况下,第一次pull会显示merge失败的文件,然后让你手动去修改。 但是我看冲突文件有点多,就执行了放弃所有更改,大概就是git checkout . 指令,清除了本地冲突的文件,这时候应该还是在merge的过程中,也就是当前merge还未结束,结果再次git pull的时候就报错了。 解决方法:放弃本次merge操作,然后重新pull代码,手动修改冲突代码,合并上传。 git merge --abort // 终止合并 git reset --merge // 重置合并 git pull // 重新拉取代码 建议: 大家在使用git pull的时候,本地不要有修改的代码且未提交,如果修改的代码就是不需要提交的代码,可以使用git stash暂存起来,等执行完git操作且没有问题后,使用git stash apply还原到本地即可。

Springboot中数据库连接

Springboot中数据库连接 一.jdbc的方式连接 1.配置jdbc连接文件 spring: datasource: username: root password: 123123 url: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8 driver-class-name: com.mysql.jdbc.Driver 2.直接controller操作crud package com.springboot.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import java.util.List; import java.util.Map; /** * @author panglili * @create 2022-07-10-10:27 */ @Controller public class JdbcController { @Autowired(required = false) JdbcTemplate jdbcTemplate; @GetMapping("/sql") @ResponseBody public List<Map<String,Object>> mapList(){ String sql="select * from user"; List<Map<String, Object>> queryForList = jdbcTemplate.queryForList(sql); return queryForList; } } 二.mybatis连接 1.导入依赖 <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.

进入centos7 紧急模式重置root密码

实战场景 公司一台centos7系统,忘记root密码了,需要快速把root密码修改为zhaogeHYZ,找回root身份。 重置步骤 重启系统,出现如下界面,选择第一项,并按E键进行编辑; 在显示内容中,找到 ro 并修改为 rw init=/sysroot/bin/sh 修改后 改完之后,按下Ctrl+X进入紧急模式;(原理:启动一个shell环境,系统并没有真正的启动) 在紧急模式下,输入如下命令,进行root密码重置; chroot /sysroot #chroot命令用来在指定的根目录下运行指令 passwd #修改密码 Changing password for user root. New password : zhaogeHYZ #重置并输入新密码,输入时并不显示密码 Retype new password : zhaogeHYZ #再次输入重置的新密码,输入时并不显示密码 passwd : all authentication tokens updated successfully. #提示成功 touch /.autorelabel #更新系统信息,否则重启之后密码修改不会生效 exit #退出当前根目录 reboot #重启系统 6. 利用重置后的新密码成功登录系统; 拓展说明 如果系统的selinux开启着,则需要执行命令: touch /.autorelabel 在不知道系统是否开启selinux时,默认还是直接执行此命令。 END!

Maven打包报错:[WARNING] The POM for xxx is missing, no dependency inform

1.问题出现 使用Maven创建的一个多模块项目,一个service_activity模块,一个service_user模块,一个service_client模块,service_activity模块依赖于service_client模块,且他们都是parent的子模块。 其中service_activity模块远程调用service_user模块,service_user模块采用service_client模块委托接口,service_activity模块在pom中引入依赖service_user_client service_activity模块在pom中引入依赖 出现问题:The POM for com.mxc:service_user_client:jar:1.0-SNAPSHOT is missing, no dependency information available 解决: 原因是因为maven工程注入时没有更新引入,可以将被引入依赖的子模块的父模块重新安装(install)如下图---》 重新安装service_client模块的maven依赖后,再对service_activity模块重新安装(install),此时如果正常运行就解决问题,如果还是不行,则把总项目再重新安装一次,若还不行,重启idea(重启大法好!),重复上述操作,99%的情况就可以了··==~~ 有帮助的话,麻烦点个赞哦~~~~~~~完结撒花~~~

【JAVA基础】两种文件读写方法

前言 按读写方法,对文件的读写操作方法有以下几种类型: 1、以字节方式读写,适合所有文件类型; 2、以字符方式单个或按行读写,适合文本文件。 目录 一、FileInputStream和FileOutputStream用法 这里仅介绍使用2种常用的文件读写方法:字节方式读写和按行读写:FileInputStream、FileOutputStream 一、FileInputStream和FileOutputStream用法 1、新建工程:FileOperation 2、新建包: 3、创建文件读写的工具类:FileOperation 代码如下: package com.my.file; import java.io.*; /** * 文件读写操作类 */ public class FileOperation { /** * 根据输入的文件路径读取文件内容,仅支持读取文本文件。 * @param filePath * @return */ public static String readFromFile(String filePath){ //输入检查:如果输入的文件不存在则返回空字符串 File file = new File(filePath); if (!file.isFile()){ return ""; } //开始读取文件 String result = ""; //读文件的缓存 byte[] temp = new byte[1024]; try { FileInputStream fis = new FileInputStream(file); // 使用 循环读取, FileInputStream的read方法,会一次读取内容放到temp。 // 读取内容的多少根据temp定义的大小而定。如果没有数据可读了,read方法会返回-1.

socket.io介绍

Socket.IO 是一个库,可以在客户端和服务器之间实现低延迟、双向和基于事件的通信。它建立在 WebSocket 协议之上,并提供额外的保证,例如回退到 HTTP 长轮询或自动重新连接。 几种可用的 Socket.IO 服务器实现: Java:https://github.com/mrniko/netty-socketio Java:https://github.com/trinopoty/socket.io-server-java Python:https://github.com/miguelgrinberg/python-socketio Golang:https://github.com/googollee/go-socket.io 客户端实现: Java:https://github.com/socketio/socket.io-client-java C++:https://github.com/socketio/socket.io-client-cpp swift:https://github.com/socketio/socket.io-client-swift Python:https://github.com/miguelgrinberg/python-socketio .Net:https://github.com/doghappy/socket.io-client-csharp Server (based on websocket的例子): import { WebSocketServer } from "ws"; const server = new WebSocketServer({ port: 3000 }); server.on("connection", (socket) => { // send a message to the client socket.send(JSON.stringify({ type: "hello from server", content: [ 1, "2" ] })); // receive a message from the client socket.on("message", (data) => { const packet = JSON.

用for循环实现delay延时原理

void Delay10ms(unsigned int c) //误差 0us { unsigned char a,b; for(; c>0; c--) //c可以不用初始化,因为默认传的参数即为初始化 for(b=38; b>0; b--) for(a=130; a>0; a--); //最后一个for循环别忘记有分号 } Delay10ms(100);/表示100个10ms=1s //计算方法:c*38*130 us 以12MHZ的晶振为例,一个for循环2个指令周期,一个指令周期1us,二个指令周期2us。

ElasticSearch 搜索引擎

简称es,是类似于mysql但是专注于搜索的一种数据库。在elastic stack中占据重要地位。 倒排索引: 我们的数据库都是正向索引,比如根据id查询数据,那么倒排索引是将关键字进行分词,然后将词条和id保存在一张表中,不同数据分词后有相同的词条的话,就会记录在同一条数据中,并且把id放在一个字段,搜索的时候根据词条先搜索出符合的id,然后根据id查询数据。 分词器: 下载地址:GitHub - medcl/elasticsearch-analysis-ik: The IK Analysis plugin integrates Lucene IK analyzer into elasticsearch, support customized dictionary. 进去之后点击右边的版本,就能进去下载, #因为启动es时候 已经做好的目录挂载 容器内部:/usr/share/elasticsearch/plugins 宿主机:/mydata/elasticsearch/plugins 所以只需要将文件复制到/mydata/elasticsearch/plugins 目录下即可 然后重启es docker restart elasticsearch 分词器也就是分词的规则,es中有默认的细粒度分词(ik_max_word)和粗粒度分词(ik_smart),细粒度分词比较多,粗粒度分词比较少。 我们也可以自定义我们想要分出来的词和不想被分出来的词,比如我们自己创建的一个品牌名,就可以自己定义一个分词字典,同样的,不想分词的也会有一个字典。 想要分出的词就可以写在我们配置文件中的ext.dic字典,不想分出来的就修改sropword.dic字典。 mapping 属性 mapping属性实际上就是我们mysql中的一个表结构,比如某个字段是什么类型的啊,有什么约束条件啊什么的。 每创建一个字段都要想下图中的几个条件,什么类型的,是否参与搜索(根据这个判断是否创建倒排索引,默认index为true),使用什么分词器,该字段有没有子字段。 索引: 索引其实对应的就是mysql中的表,es说要创建个索引,就相当于mysql说,要创建一个表。 创建索引示例: 查看和删除索引: 修改索引库: 实际上es是不支持修改索引库的,因为带来的影响比较大,尤其是生产环境下。 但是,虽然不支持修改索引库,但是支持添加一个字段 文档: 文档,实际上就相当于mysql中的数据。添加文档就是mysql中的添加数据 这里要说一下,mysql中写的语句叫做sql语句,es中写的语句叫做DSL语句。 新增文档: 查看和删除文档: 修改文档: 修改文档实际上有两种方法,一种是全量修改,一种就是新增一个文档: 方式一:他会根据id先找到这个文档,然后删除,再添加新文档 方式二, 这个就是修改指定的字段,我们可以看到上面的_doc变成了_update ,所以这里就是对某个字段进行修改了 es查询语句: 查询所有: 这里的查询类型,之后可以根据自己的条件的不断变化,更换不同的查询类型,这里的math_all就是查询所有,所有里面不需要跟条件 全文检索查询: 设定的场景就是我们常见的搜索框,根据输入的字段查询匹配的数据。 match是查询某一个字段中是否包含输入的信息,multi_match是同时查询几个字段中是否包含输入的信息。 注意:搜索字段越多,查询效率越低,所以我们尽量用一个字段查,之后会学到copy_to,查询一个字段也可以实现多个字段的效果。 精确查询: 这里指的就是不被分词的字段,进行精确匹配 ,也就是keyword 包括term和range: range中gte是大于等于,lte是小于等于 greate/less than equals 地理查询:

Linux共享文件夹的建立和使用

共享文件夹作用建立window和linux之间的通道,保证文件双方都可以使用 在window当中建立文件夹对象,例如 WH2208 在Vmware当中设置共享文件数据 测试共享文件夹 首先在共享文件夹里面新建一个txt文本,然后在虚拟机中输入cd /mnt/hgfs/wh2208/ 进入共享文件夹,用ls命令显示里面的内容即可,表示共享文件夹创建成功。文件内容的使用

使用dbcc工具根据dbc文件生成CAN报文解析c代码

dbcc工具在github上的地址: https://github.com/howerj/dbcc 仓库地址: git@github.com:howerj/dbcc.git 源码下载到Ubuntu后,使用gcc编译即可,编译完成后,就可以在源码当前目录生成dbcc可执行程序。 编译方法: make CC=gcc dbcc工具使用方法: 可以先使用./dbcc -h看下使用帮助说明。 基本的使用方法是,在dbcc参数中跟上dbc文件即可。例如:./dbcc DBC_FILE 示例dbc文件(片段): BO_ 2F8 DATE_TIME_SZ: 8 Host SG_ DISP_MILLISEC : 0|44@1+ (1,0) [0|3298534883327] "ms" Vector__XXX BO_ 330 LICENSE: 8 Host SG_ LICENSE_NUMBER : 24|16@1+ (1,0) [0|65535] "" Vector__XXX SG_ LICENSE_EXT : 40|16@1+ (1,0) [0|65535] "" Vector__XXX SG_ LICENSE_CITY : 16|8@1+ (1,0) [0|255] "" Vector__XXX SG_ LICENSE_PROV : 0|16@1+ (1,0) [0|65535] "" Vector__XXX BO_ 19A VEH_INFO: 8 Host SG_ VEH_TYPE : 8|8@1+ (1,0) [0|255] "

vue2项目构建过程

VUE项目自定义构建教程 一、vue create demo //初始化项目 下箭头选中Manually select features(手动选择功能),敲击回车。 Default Vue3 // 默认创建Vue3版本的项目 Default Vue2 // 默认创建Vue2版本的项目 二、为你的vue项目添加功能 Check the features needed for your project 译:检查项目所需的功能 (Press < space > to select, < a > to toggle all, < i > to invert selection, and < enter > to proceed) 译:按空格选择,按a全选,按i反选,按回车继续 注:键盘上下箭头切换,空格进行选择或取消(实心点代表已选择) Babel // ES6转ES5 TypeScript // 使用TypeScript语法(不用选,除非你会TS) Progressive Web App (PWA) Support // 渐进式Web应用(添加一些webapp支持、可离线支持,可不选) Router // 路由功能(必选) Vuex // 状态管理(必选)

4、键盘输入10个数,存到数组中,打印奇数位元素的值 注意:如果数组是{10,11,12,13,14,15},则奇数位元素是10,12,14

public class demo02 { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int a = 0; for (int i = 1; i <=10 ; i++) { System.out.println("请输入第"+i+"整数"); int b = sc.nextInt(); if (b%2!=0){ a=a-1; }else{ System.out.println("------------"); System.out.println("该数字为"+b+"是奇数"); } } System.out.println("-------------"); System.out.println("该数字为"+a); sc.close(); } }

package-lock.json冲突及问题排查

在合并分支的时候会遇到package-lock.json的冲突,本来刚开始没有在意,认为也没什么。但是直到package-lock.json出现了一大片的冲突时,我才觉得问题是真的有点大。 问题排查:很大概率是node版本和npm版本的问题。然后问各组员大家的npm版本,发现有两个同事是6.x版本的,而我自己的是7.x版本的npm。经过自己的测试,使用npm i 安装,发现6.x版本的npm安装依赖(package-lock.json)如下: 但是7.x版本的npm安装的依赖会是有一个packages的东西,这里会把之前安装的依赖都包在这个packages里面。 所以,如果一个同事安装了一个新的插件,我们用不同版本的npm去安装依赖的话,由于安装的npm版本不同,所以写入的package-lock.json内容也会不同,就会导致package-lock.json文件很多的冲突。 解决方法: 1.统一node版本和npm版本(至少统一一个大的版本),且在需要重新安装依赖的时候,使用npm ci的命令去安装。(强烈推荐,npm ci指的是根据package-lock.json去安装对应的版本,不对这个文件做改动) 2.使用git忽略package-lock.json(不推荐,这样子会导致不能根据安装依赖路径去安装包了) 补充-npm i 和 npm ci的区别: npm i ● npm i 将创建node_modules 文件夹并安装所有 package.json 中的依赖。 ● npm i 会更新 package-lock.json 文件(也就是这一步,导致了package-lock-json的冲突,因为npm版本的不同,导致了写入方式不同)。 适用场景:安装新依赖或者升级已有依赖。 npm ci ● npm ci 将删除 node_modules 文件夹以确保干净的环境。 ● npm ci 会依照 package-lock.json 里的依赖版本精准安装。 ● npm ci 强依赖于 package-lock.json,如果 package-lock.json 不存在,npm ci 将不会工作。 适用场景:在 CI/CD 场景中使用 npm ci 更为合适,一方面,由于 npm ci 依赖于 package-lock.json,依赖版本确保一致,不会出现线上版本和开发版本不一致而引发的问题;另一方面,首次安装时,使用 npm ci 将比 npm i 更加迅速,原因是由于 package-lock.

ContextCapture(CC)/Smart3D集群搭建笔记

ContextCapture/Smart3D集群处理 1 前言 本文主要记录本人搭建CC集群的过程,以及在搭建过程中遇到的各种麻烦。 主要参考的文章及资料如下: (1)ContextCaptureMaster/Smart3D 集群处理详解 (2)CC(smart3D)内业工作站集群的搭建方法与操作步骤 很详细的工作站搭建步骤,包括硬件设备的选择及搭配等,但仍未解决我的问题 0_0 (3)ContextCaptureMaster/Smart3D集群设置经验分享 (4)访问权限解决 设备情况: 两台电脑(一台主机A,一台节点机B),一个交换机,两条网线(本次处于实验过程中,使用八口千兆交换机,六类网线)。 在实际建模过程中,由主机A来建立工程,节点机B只需要保证Engine的运行即可,因此以下内容主要针对主机A进行描述,节点机的操作与主机类似。 2 文件共享的设置(局域网搭建) 主要遇到的问题: (1)已经完成文件夹及磁盘的共享,但没有权限进行访问; (2)完成共享后,在“网络”文件夹下无法查看到共享的文件,因此无法判断是否共享成功; (3)如何将共享文件设置为“网络位置”,便于快速进入。 2.1 检查SMB1.0是否启用 解决主要问题(2)时,进行了此处的设置,但并没解决问题,因此暂时并不知道此步骤的具体影响,但建议进行设置。 2.2 磁盘及文件夹安全权限设置 主要解决了问题(1) 本人CC的工程文件及模型的输出目录均存放在主机A的D盘中,航摄像片存放在节点机B的D盘中,因此需要对A、B两台电脑的D盘实现共享; 主机A装入CC时,任务序列装在了C盘,C盘的安全权限开启较为麻烦,因此只对任务序列所在的文件夹进行共享。 以上图片步骤解决共享(建立局域网)后访问权限的问题。 在需要进行共享的磁盘(或文件夹)的属性中,选择“安全”选项卡,然后依照图片步骤进行设置(在第9步后点应用,会有根据文件量有一段时间的等待)。 2.3 网络共享设置 利用交换机及网线连接好主机A与节点机B之后,进行网络共享权限的设置。 根据上图进行设置,然后保存更改即可。 2.4 局域网IP设置 搭建局域网时,需要主机与节点机在同一个网段下,可将主机网段编号为1,节点机从2开始依次往后编号。 以下是主机IP设置的步骤,主机IP地址设置为192.168.1.1,子网掩码设置为255.255.255.0(节点机除IP地址最后一位进行更改外,其余与主机保持一致) 确定后即完成主机A的IP地址设置,节点机B的IP地址设置为192.168.1.2,其余与主机A保持一致。 完成IP地址的更改后,可根据CC(smart3D)内业工作站集群的搭建方法与操作步骤中的2.2更改主机与节点机名称,方便识别。 2.5 磁盘(文件夹)共享设置 如果在第5步时已经有了Everyone的选项,则直接跳到第11步,无需再次添加Everyone。 根据以上步骤,完成对主机A和主机B的磁盘D的共享设置,以及完成主机A中任务序列文件夹的共享。 2.6 文件共享查看(检查共享状态) 根据参考资料中博主的方法,本人并没有成功观察到共享状态,因此选择另外的方式进行查看。 (1)利用“Windows+R”的组合键,调出“运行”窗口; (2)在“运行”窗口中输入目标电脑的IP地址,比如主机A为“\192.168.1.1”,注意“\”的输入。 之后便可进入主机A查看共享的磁盘及文件夹了。 换IP后可进入节点机B查看共享的磁盘及文件夹。 若此时提示无访问权限,则需要返回步骤2.2进行安全权限的设置。 若能访问A、B共享的磁盘及文件,则成功完成共享。 2.7 网络位置的设置 每次使用“运行”台加IP地址的方式进行访问会十分繁琐,因此需要将网络位置固定在窗口上,便于访问。 注意在第4步的时候,需要具体到被共享的磁盘或文件夹。 完成后在“网络位置”的栏目中会出现共享的磁盘及文件夹,可以快速进行访问。 以上步骤完成了共享文件(局域网)的设置,之后可利用CC进行集群计算了。 3 ContextCapture集群设置 主要设置为任务序列的位置、工程文件的位置、影像读取的位置,需要注意的是,以上位置均要使用网络位置 3.1 ContextCapture Center Settings设置 主机A与节点机B中均需要进行此项设置,且输入的路径一致。 复制网络路径后,粘贴到本节第二张图片中的红框位置即可。

垃圾回收器CMS和G1

文章目录 CMS与三色标记算法CMS收集器三色标记算法(重点)结语 G1收集器G1的堆内存算法G1回收流程G1的GC模式 CMS与三色标记算法 CMS(Concurrent Mark Sweep)是一款里程碑式的垃圾收集器,为什么这么说呢?因为在它之前,GC线程和用户线程是无法同时工作的,即使是Parallel Scavenge,也不过是GC时开启多个线程并行回收而已,GC的整个过程依然要暂停用户线程,即Stop The World。这带来的后果就是Java程序运行一段时间就会卡顿一会,降低应用的响应速度,这对于运行在服务端的程序是不能被接收的。 GC时为什么要暂停用户线程? 首先,如果不暂停用户线程,就意味着期间会不断有垃圾产生,永远也清理不干净。 其次,用户线程的运行必然会导致对象的引用关系发生改变,这就会导致两种情况:漏标和错标。 漏标 原本不是垃圾,但是GC的过程中,用户线程将其引用关系修改,导致GC Roots不可达,成为了垃圾。这种情况还好一点,无非就是产生了一些浮动垃圾,下次GC再清理就好了。 错标 原本是垃圾,但是GC的过程中,用户线程将引用重新指向了它,这时如果GC一旦将其回收,将会导致程序运行错误。 针对这些问题,CMS是如何解决的呢?它是如何做到GC线程和用户线程并发工作的呢? CMS收集器 CMS收集器是⼀种以获取最短回收停顿时间为⽬标的收集器。它⽽⾮常符合在注重⽤户体验的应⽤上使⽤。 CMS收集器是HotSpot虚拟机第⼀款真正意义上的并发收集器,它第⼀次实现了让垃圾收集线程与⽤户线程(基本上)同时⼯作。 Concurrent Mark Sweep,从名字上就可以看出来,这是一款采用「标记清除」算法的垃圾收集器,它运行的示意图大概如下: 大概可分为四个主要步骤: 1、初始标记 初始标记仅仅只是标记一下GC Roots能直接关联到的对象,速度很快。初始标记的过程是需要触发STW的,不过这个过程非常快,而且初试标记的耗时不会因为堆空间的变大而变慢,是可控的,因此可以忽略这个过程导致的短暂停顿。 2、并发标记 并发标记就是将初始标记的对象进行深度遍历,以这些对象为根,遍历整个对象图,这个过程耗时较长,而且标记的时间会随着堆空间的变大而变长。不过好在这个过程是不会触发STW的,用户线程仍然可以工作,程序依然可以响应,只是程序的性能会受到一点影响。因为GC线程会占用一定的CPU和系统资源,对处理器比较敏感。CMS默认开启的GC线程数是:(CPU核心数+3)/4,当CPU核心数超过4个时,GC线程会占用不到25%的CPU资源,如果CPU数不足4个,GC线程对程序的影响就会非常大,导致程序的性能大幅降低。 3、重新标记 由于并发标记时,用户线程仍在运行,这意味着并发标记期间,用户线程有可能改变了对象间的引用关系,可能会发生两种情况:一种是原本不能被回收的对象,现在可以被回收了,另一种是原本可以被回收的对象,现在不能被回收了。针对这两种情况,CMS需要暂停用户线程,进行一次重新标记。 4、并发清理 重新标记完成后,就可以并发清理了。这个过程耗时也比较长,且清理的开销会随着堆空间的变大而变大。不过好在这个过程也是不需要STW的,用户线程依然可以正常运行,程序不会卡顿,不过和并发标记一样,清理时GC线程依然要占用一定的CPU和系统资源,会导致程序的性能降低。 CMS收集器的优缺点: 尽管CMS是一款里程碑式的垃圾收集器,开启了GC线程和用户线程同时工作的先河,但是不管是哪个JDK版本,CMS从来都不是默认的垃圾收集器,究其原因,还是因为CMS不太完美,存在一些缺点。 1、对处理器敏感 并发标记、并发清理阶段,虽然CMS不会触发STW,但是标记和清理需要GC线程介入处理,GC线程会占用一定的CPU资源,进而导致程序的性能下降,程序响应速度变慢。CPU核心数多的话还稍微好一点,CPU资源紧张的情况下,GC线程对程序的性能影响非常大。 2、浮动垃圾 并发清理阶段,由于用户线程仍在运行,在此期间用户线程制造的垃圾就被称为“浮动垃圾”,浮动垃圾本次GC无法清理,只能留到下次GC时再清理。 3、并发失败 由于浮动垃圾的存在,因此CMS必须预留一部分空间来装载这些新产生的垃圾。CMS不能像Serial Old收集器那样,等到Old区填满了再来清理。在JDK5时,CMS会在老年代使用了68%的空间时激活,预留了32%的空间来装载浮动垃圾,这是一个比较偏保守的配置。如果实际引用中,老年代增长的不是太快,可以通过-XX:CMSInitiatingOccupancyFraction参数适当调高这个值。到了JDK6,触发的阈值就被提升至92%,只预留了8%的空间来装载浮动垃圾。 如果CMS预留的内存无法容纳浮动垃圾,那么就会导致「并发失败」,这时JVM不得不触发预备方案,启用Serial Old收集器来回收Old区,这时停顿时间就变得更长了。 4、内存碎片 由于CMS采用的是「标记清除」算法,这就意味这清理完成后会在堆中产生大量的内存碎片。内存碎片过多会带来很多麻烦,其一就是很难为大对象分配内存。导致的后果就是:堆空间明明还有很多,但就是找不到一块连续的内存区域为大对象分配内存,而不得不触发一次Full GC,这样GC的停顿时间又会变得更长。 针对这种情况,CMS提供了一种备选方案,通过-XX:CMSFullGCsBeforeCompaction参数设置,当CMS由于内存碎片导致触发了N次Full GC后,下次进入Full GC前先整理内存碎片,不过这个参数在JDK9被弃用了。 三色标记算法(重点) 介绍完CMS垃圾收集器后,我们有必要了解一下,为什么CMS的GC线程可以和用户线程一起工作。 JVM判断对象是否可以被回收,绝大多数采用的都是「可达性分析」算法,关于这个算法,可以查看笔者以前的文章:大白话理解可达性分析算法。 从GC Roots开始遍历,可达的就是存活,不可达的就回收。 CMS将对象标记为三种颜色: 标记的过程大致如下: 刚开始,所有的对象都是白色,没有被访问。将GC Roots直接关联的对象置为灰色。遍历灰色对象的所有引用,灰色对象本身置为黑色,引用置为灰色。重复步骤3,直到没有灰色对象为止。结束时,黑色对象存活,白色对象回收。 这个过程正确执行的前提是没有其他线程改变对象间的引用关系,然而,并发标记的过程中,用户线程仍在运行,因此就会产生漏标和错标的情况。 漏标 假设GC已经在遍历对象B了,而此时用户线程执行了A.B=null的操作,切断了A到B的引用。 本来执行了A.B=null之后,B、D、E都可以被回收了,但是由于B已经变为灰色,它仍会被当做存活对象,继续遍历下去。 最终的结果就是本轮GC不会回收B、D、E,留到下次GC时回收,也算是浮动垃圾的一部分。 实际上,这个问题依然可以通过「写屏障」来解决,只要在A写B的时候加入写屏障,记录下B被切断的记录,重新标记时可以再把他们标为白色即可。 错标 假设GC线程已经遍历到B了,此时用户线程执行了以下操作:

小程序自定义导航栏,胶囊对齐解决方案

小程序胶囊高度组成 获取小程序状态栏,胶囊,导航栏 高度 // 获取状态栏信息 getMenuButtonBound() { let stateHeight = 0; // 接收状态栏高度 const navHeight = wx.getMenuButtonBoundingClientRect().height; // 获取胶囊高度 let top = 0; wx.getSystemInfo({ success(res) { stateHeight = res.statusBarHeight; }, }); top = wx.getMenuButtonBoundingClientRect().top - stateHeight; // 获取top值 console.log('navHeight', navHeight); console.log('top', top); this.setData({ // navHeight: navHeight + top * 2, // 导航栏高度 navHeight, // 导航栏高度 stateHeight: stateHeight + top, // 状态栏高度 }); }, 这个获取单位是px,之前换算的rpx,不同设备对rpx换算的比率不一样,导致高度有偏差 wxml代码 <image class="backgroundtopimage" style=" margin-top: {{stateHeight}}px; height: {{navHeight}}px;line-height: {{navHeight}}px;text-align: center; "

centos双网口绑定

本文使用得是vmware,centos7.4系统,系统默认是单网卡,需要在开启系统之前添加第二个网卡 1、关闭网络管理服务 关闭 NetworkManager 是成功的必要条件 [root@node-1 ~]# service NetworkManager stop [root@node-1 ~]# systemctl disable NetworkManager 2、修改服务器网卡配置 创建bond0文件,写入以下配置 注:在虚拟机环境中,如果网卡1宕掉后不能切到网卡2, 则将配置文件中 BONDING_OPTS=“mode=6 miimon=100” 改写为 BONDING_OPTS=“mode=6 miimon=100 fail_over_mac=1” fail_over_mac 参数是bond0使用当前活跃网卡mac地址 [root@node-1 ~]# vi /etc/sysconfig/network-scripts/ifcfg-bond0 TYPE="bond" BOOTPROTO="none" NAME="bond0" DEVICE="bond0" IPADDR="192.168.1.100" NETMASK="255.255.255.0" GATEWAY="192.168.1.1" DNS1="8.8.8.8" ONBOOT="yes" BONDING_OPTS="mode=6 miimon=100" #mode=6为适配器负载均衡模式,也用过mode=1主备模式 修改eth0配置文件,网卡配置文件名称,是eth,还是em结尾 [root@node-1 ~]# vi /etc/sysconfig/network-scripts/ifcfg-eth0 TYPE="Ethernet" BOOTPROTO="none" NAME="eth0" DEVICE="eth0" MASTER="bond0" SLAVE="yes" ONBOOT="yes" 修改eth1配置文件,网卡配置文件名称,是eth,还是em结尾 [root@node-1 ~]# vi /etc/sysconfig/network-scripts/ifcfg-eth1 TYPE="Ethernet" BOOTPROTO="none" NAME="eth1" DEVICE="eth1" MASTER="bond0" SLAVE="yes" ONBOOT="yes" 3、重启网卡 [root@node-1 ~]# service network restart 此时会断网几秒钟

redis集群

1、Redis_主从复制 前期准备 1.官网下载最新redis-7.0.2.tar.gz 2.创建目录mkdir opt 把安装包放在这个文件夹底下 3.解压tar -zxvf redis-7.0.2.tar.gz 4.复制redis-7.0.2文件夹里面的redis.conf 5.创建文件夹myredis并把redis.conf复制过来 6.修改vi redis.conf 后台启动设置daemonize no改成yes (1)主从复制是什么 主机数据更新后根据配置和策略, 自动同步到备机的master/slaver机制,Master以写为主,Slave以读为主 (2)怎么玩:主从复制 1.我们创建三个配置文件:redis6379.conf、redis6380.conf、redis6381.conf 文件内容以redis6379.conf为例 include /myredis/redis.conf pidfile /var/run/redis_6379.pid port 6379 dbfilename dump6379.rdb 其他文件配置一样,注意修改里面的端口一一对应上 :%s/6379/6380这个命令是全局替换。 2.启动三台redis服务器 3.查看系统进程,看看三台服务器是否启动 4.查看三台主机运行情况 info replication 打印主从复制的相关信息 下面可以知道全部都是主还没有配置 5.配从(库)不配主(库) slaveof 在6380和6381上执行: slaveof 127.0.0.1 6379 配置完毕需要注意的事项: 在主机上写,在从机上可以读取数据 在从机上写数据报错 主机挂掉,重启就行,一切如初 从机重启需重设:slaveof 127.0.0.1 6379 (3)常用三招 1.一主二仆 2. 薪火相传 3. 反客为主(自动版哨兵模式(sentinel)) (4)复制原理  Slave启动成功连接到master后会发送一个sync命令  Master接到命令启动后台的存盘进程,同时收集所有接收到的用于修改数据集命令, 在后台进程执行完毕之后,master将传送整个数据文件到slave,以完成一次完全同步  全量复制:而slave服务在接收到数据库文件数据后,将其存盘并加载到内存中。  增量复制:Master继续将新的所有收集到的修改命令依次传给slave,完成同步  但是只要是重新连接master,一次完全同步(全量复制)将被自动执行

金蝶部署项目

金蝶部署重要概念 1、域 金蝶部署过程中,将domains下的文件夹叫做域,一个域代表一个端口号,一个域只能配置一个端口号,如图所示:(配置域端口的文件:apusic.conf) 2、应用基础上下文 应用基础上下文用于配置全局的访问路径。 以项目为例: 项目部署文件名为:web-1.0.0, 在启动金蝶成功后,访问后台接口的路径为:172.31.19.23:8081/web-1.0.0/doc.html。此时,swagger页面能够看到,但接口无法访问 需要将基础上下文配置成:/再次访问时,后台就可以访问了: 以上两个配置是根据配置文件进行修改的 application-dev.yml: 项目的war包部署在金蝶中间件相关操作 金蝶服务器的安装路径在“/opt/AAS”,金蝶中间件的安装是由金蝶公司的维护人员进行安装的。 程序包的部署: 【步骤1】:将pom.xml的打包方改为war,打包后会出现两种包,一个是文件夹的方式,一个是.War。文件夹方式便于修改配置文件,因此本文采用文件夹方式部署 【步骤2】:将war包放在金蝶的域目录下,路径为 “/opt/AAS/domains/ZC/applications”。需要将域端口成后台端口,如图所示: 【步骤3】:找到“/opt/AAS/domains/ZC/bin”该路径在终端中打开,进行金蝶的启动命令“./startapsic”。 【步骤4】:第一次部署需要金蝶密码。部署过程可能会有报错。需要根据控制台的提示解决。如果没有报错会显示:成功启动,服务器就绪。 vnc以及金蝶登录。 点击vnc以如图所示配置,点击连接出现麒麟可视化界面。 VNC 账户:xxx 密码:xxxx 金蝶中间件 地址:172.31.xx.xxxx:8081/admin 本地部署 选择应用管理,点击部署应用可实现上传式部署。其中可选择本地应用包部署和服务器应用部署。如下图: 其中本地应用部署只支持war包的形式。服务器应用部署支持war包和文件夹形式。 参数修改 先点击web-1.0.0.war的“参数配置”。 修改应用基础上下文:/ 点击保存一次即可,等待金蝶重启页面会自动弹出配置成功!然后修改html的参数配置,提示更新成功即可访问8081端口看是否能够登录! 击完成,war包会自动启动。控制台会显示后台启动的信息。 遇到的问题 1、找不到snakeyaml依赖包 定位:打包文件中包含snakeyaml包,但在上传文件的过程中丢失了。 解决方案:将snakeyaml包放到“域文件下的lib文件夹”中。这个lib是金蝶自带的,提供放依赖包的地方,只对当前domains下的应用起作用. 2、上下文冲突 原因:一个端口只能配置一个/访问目录 解决方案: (1)部署到其他域 (2)修改代码,包括后台swagger,前台访问后台的代码

python 数据结构篇

在众多编程语言里,数据结构与算法都可以说是至关重要的基础。但是对于python而言,因为其本身就是用C实现的,其速度和效率本身较低,因而pyhon没有像其他语言那样那么重视数据结构与算法(python最引以为傲的应该是其功能强大而丰富的各种库和模块)。对于很多像我一样的新手小白,时间复杂度似乎也不是硬要求,实现功能就行了。本节我们主要介绍用python实现数据结构。 对于数据结构,我们将采用以下的思路进行学习: 一、定义对象、节点 1.线性结构: 数组、链表、队列、栈 2.非线性结构: 树、堆、图 二、实现节点之间的互联 在节点属性中增加指针 三、对象由某一节点处开始的遍历 1.线性结构 1)单向遍历 2)双向遍历 2.非线性结构 1)DFS(深度优先搜索) 2)BFS(广度优先搜索) 四、基本操作方法 1.增加节点 2.返回节点数量 3.由遍历结果构建对象 目录 一、线性数据结构(一对一) 1.数组 1)构造一个数组对象 2)查找数组信息 3)删除操作 4)添加操作 5)转换操作 6)文件操作 7)排序 2.链表 1)单向链表 2)双向链表 3)双向循环链表 3.队列(queue模块) 队列方法:(适用于所有的队列) 1)FIFO先入先出队列--Queue 2)LIFO后入先出队列(栈) 3)优先级队列 4)双端队列 二、非线性数据结构 1.树(一对多) 1)二叉树 联动:二叉树与优先级队列--堆 2)树 3)森林 2.图(多对多) 1)图的分类 2)图的实现 邻接矩阵 邻接表 十字链表 邻接多重表 3)图的算法 遍历 最小生成树 最短路径 一、线性数据结构(一对一) 1.数组 数组 python使用其内置的模块array实现数组,python的数组就和C语言一样精简而高效。 1)构造一个数组对象 array.array(typecode[, initializer]) # 例:构造一个空的int类型数组 arr = array('i') arr = array('i', [0, 1, 2, 3, 4, 6, 7, 8, 9, 100]) 由于python没有对于变量声明的要求,所以在创建数组时需要一个类型代码字符标识该数组的数据类型,这样数组才能像C语言里的数组一样操作。

一些常用的文章写作使用方法和技巧

H2O is是液体。 210 运算结果是 1024. 插入链接与图片 链接: link. 图片: 带尺寸的图片: 居中的图片: 居中并且带尺寸的图片: 当然,我们为了让用户更加便捷,我们增加了图片拖拽功能。 如何插入一段漂亮的代码片 去博客设置页面,选择一款你喜欢的代码片高亮样式,下面展示同样高亮的 代码片. // An highlighted block var foo = 'bar'; 生成一个适合你的列表 项目 项目 项目 项目1项目2项目3 计划任务 完成任务 创建一个表格 一个简单的表格是这么创建的: 项目Value电脑$1600手机$12导管$1 设定内容居中、居左、居右 使用:---------:居中 使用:----------居左 使用----------:居右 第一列第二列第三列第一列文本居中第二列文本居右第三列文本居左 SmartyPants SmartyPants将ASCII标点字符转换为“智能”印刷标点HTML实体。例如: TYPEASCIIHTMLSingle backticks'Isn't this fun?'‘Isn’t this fun?’Quotes"Isn't this fun?"“Isn’t this fun?”Dashes-- is en-dash, --- is em-dash– is en-dash, — is em-dash 创建一个自定义列表 Markdown Text-to- HTML conversion tool Authors John Luke 如何创建一个注脚 一个具有注脚的文本。1

Ubuntu 20.04 (LTS)安装Docker—且配置阿里镜像加速(使用阿里云文档方式添加)

首先报上官网地址当然一下顺序也是大体按照官网方式进行的 Ubuntu安装Docker Docs 环境条件: Ubuntu Impish 21.10Ubuntu Hirsute 21.04Ubuntu Focal 20.04 (LTS)Ubuntu Bionic 18.04 (LTS) Docker Engine is supported on x86_64 (or amd64), armhf, arm64, and s390x architectures. 卸载旧版本 sudo apt-get remove docker docker-engine docker.io containerd runc 如果apt-get报告没有安装这些软件包,没关系。 # 以下是没有安装这些软件包的报告 root@azang405:~# sudo apt-get remove docker docker-engine docker.io containerd runc Reading package lists... Done Building dependency tree Reading state information... Done E: Unable to locate package docker E: Unable to locate package docker-engine E: Unable to locate package docker.

Android 系统升级遇到的问题

1. 状态栏高度 发现 Android 11 上 targetSdkVersion 是30时获取状态栏高度为0,低于30获取值正常。。。因此需要使用WindowMetrics适配一下,仅此记录,暂未发现异常 public static int getStatusBarHeight(Context context) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); WindowMetrics windowMetrics = wm.getCurrentWindowMetrics(); WindowInsets windowInsets = windowMetrics.getWindowInsets(); Insets insets = windowInsets.getInsetsIgnoringVisibility(WindowInsets.Type.statusBars() | WindowInsets.Type.displayCutout()); return insets.top; } .... } WindowMetrics 是 Android11 新增的类,用于获取窗口边界,同样可以用来获取导航栏高度。

【记录爬虫实战过程】入门学习详细过程·用爬虫实现小说爬取2

文章目录 前言我的扩展1.添加了请求头(headers):一个/随机2.设置爬取时间间隔3.添加异常处理机制4.多线程爬虫:提高效率5. 补充资料 总结爬取小说的大致步骤1.确定爬取的url地址(分析网页性质<静态/动态>)2.发送请求3.数据解析,得到目标数据3.1 解析目录3.2解析内容3.3 处理内容 4.遇到的问题 前言 要做一个项目,所以先学习熟练应用爬虫。 在此记录学习过程,供他人参考,也督促自己坚持学习。 大致路线: 模仿他人自己练习总结 这是用爬虫实现小说爬取的第一部分,主要是根据别人的例子进行模仿和练习。 这篇为第二和三部分:自己练习+总结,在原来的基础上进行扩展:添加了请求头、设置爬取时间间隔、添加异常处理机制 背景: 已掌握一些基础的相关知识,运行环境为vs code 需要安装一些爬虫所用的库文件:可以使用pip获取,例如获取request库文件:pip install request (如果不知道如何在vscode里面导入python的库可以参考这篇文章 在vscode环境里导入python库(三种方法) | 详细过程) 我的扩展 1.添加了请求头(headers):一个/随机 可以通过添加请求头来防反爬,如果不写请求头headers有可能会被封IP。 在初始化里面加上 self.headers #防反爬 self.headers={ 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.204 Safari/537.36', 'content-type':'charst=uft8' #设置接收数据的编码格式 } 这里我只写了一个headers来抓到信息,一般来讲,一个请求头就行。 如果不能,我们可以升级一下,写n个请求头,然后通过随机模块来随机选择一个headers。 当然,这个做法比较笨。在查阅资料后,我发现python有一个专门的库fake_useragent来生成随机headers(相关资料) 关于如何在vscode里面导入python的库可以参考这篇文章 在vscode环境里导入python库(三种方法) | 详细过程 #生成随机headers from fake_useragent import UserAgent 导入库后: self.headers={ 'User-Agent':UserAgent().random, 'content-type':'charst=uft8' #设置接收数据的编码格式 } 2.设置爬取时间间隔 很多网站的反爬虫机制都设置了访问间隔时间,一个IP如果短时间内超过了指定的次数就会进入“冷却CD”。 所以除了轮换IP和user_agent,还可以通过设置访问的时间间隔,比如每抓取一个页面休眠一个随机时间。(不过这个只用来爬小说好像用处不大,这里进行扩展主要是方便以后用于其他爬虫项目) 需要导入time库 #设置爬取时间间隔 import time import random #可以设置随机睡眠时间 在主函数的下载部分添加time.

定时备份数据库

定时备份数据库 Linux下定时备份数据库 linux下使用crontab定时备份MYSQL数据库的方法 只需按照下面3步做,一切都在你的掌控之下: 第一步:在服务器上配置备份目录代码: mkdir /home/bootdo/mysqlbackup && cd /home/bootdo/mysqlbackup 第二步:编写备份脚本代码: vi dbbackup.sh ##粘帖以下代码,务必更改其中的username,password和dbname。 #!/bin/sh CURRENT_DIR=$( cd "$(dirname "$0")" pwd ) docker run -v $PWD:/home -e MYSQL_ROOT_PASSWORD=123456 -it --rm mysql:5.7.23 bash -c "mysqldump -uroot -pCobbler1234! -h 192.168.0.229 -P 43306 bootdo | gzip > /home/bootdo-$(date "+%Y-%m-%d-%H:%M:%S").sql.gz" cd $CURRENT_DIR rm -rf find . -name '*.sql.gz' -mtime 20 #删除20天前的备份文件 第三步:更改备份脚本权限 chmod +x dbbackup.sh 第四步:用crontab定时执行备份脚本代码: crontab -e 若每天晚上凌晨1点备份,添加如下代码 0 1 * * * /home/bootdo/mysqlbackup/dbbackup.

STM32F103DAC输出直流、锯齿波、三角波,正弦波

一、DAC基本原则原理 二、 各波形输出及cubeMx设置 1、直流信号 cubeMx配置: 伪代码: int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_DAC_Init(); HAL_DAC_SetValue(&hdac,DAC_CHANNEL_1,DAC_ALIGN_12_R,248);//248/4096*3.3=0.2V //开启DAC通道1 if(HAL_DAC_Start(&hdac,DAC_CHANNEL_1)!=HAL_OK) { Error_Handler(); } } while(1) { } 实测结果:(手持示波器) 2、锯齿波 cubeMx配置与上一题一致。 伪代码: int main() { int dacValue; HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_DAC_Init(); while(1) { for(dacValue=o;dacValue<20;dacValue++)//循环次数和波的阶梯化相关,循环次数越多波越光滑 { HAL_DAC_SetValue(&hdac,DAC_CHANNEL_1,DAC_ALIGN_12_R,124*dacValue);//最高2480/4096*3.3=1V //开启DAC通道1 if(HAL_DAC_Start(&hdac,DAC_CHANNEL_1)!=HAL_OK) { Error_Handler(); } HAL_Delay(1);//频率和延时时间以及阶梯数有关 ] } 实测结果:(Vpp有些误差) 3、定时器2触发DAC产生三角波 型号: Timer2在 APB1总线上 cubeMx配置: 伪代码: int main() { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_TIM2_Init(); HAL_TIM_Base_Start(&htim2);//在定时器厨师话函数中添加也可以 MX_DAC_Init(); //配置DHR12RD寄存器,对应波形的最低电压 if(HAL_DAC_SetValue(&hdac,DAC_CHANNEL_1,DAC_ALIGN_12B_R,0x0)!=HAL_OK) {Error_Handler();} //开启DAC通道一 if(HAL_DAC_Start(&hdac,DAC_CHANNEL_1)!

git 撤销代码

git如何撤销和回滚 由于也是刚接触git版本管理工具不久,对git使用不熟练,在项目开发中也是磕磕碰碰,于 是决定好好熟悉一下git版本管理工具,其中git的撤销和回滚在项目当中还是应用的比较多 因此做了一下总结,列出常见的撤销命令。 1 git commit 之前撤销命令 下图是我未添加到暂存区的文件(也就是没有执行git add这个命令) 这种撤销可以直接执行git checkout -- 文件名 看一下代码示例吧(一定要加要注意 - - ) 刚刚是有两个文件,执行了git checkout -- 文件名命令之后 ,只剩一个文件了,另一个文件被撤销了。 撤销多个文件 git checkout -- . 即可撤销多个文件 2.添加到暂存区(执行了git add 命令)该怎么撤销呢? 一起来看看吧 下图是我将文件git add .之后,已经添加到暂存区的状态(Changes to be committed) 现在我将添加到暂存区的文件给撤销 这里我用了命令git reset HEAD <file> file是文件名 我又查看了一下状态 git status 此时显示我还未添加到暂存区,若我想把add到暂存区的文件全部撤销,则可以执行git reset HEAD命令。 第二大情况就是 git commit 之后。此时已经提交了,只是没有推送到远程仓库 此时commit提交后想撤销的话,需要revert命令。git revert 命令是撤销某次操作,而在此次操作之前和之后的提交记录都会保留。 我先用git log查看一下提交记录,算了,我嫌git log打印的太多,直接用这个命令git log --pretty=oneline 下面直接出现了我近期提交的记录,而这前面黄色的一大串,则是我提交的commit id(版本号) 现在我将它回退到提交之前 刚刚执行的命令是 git revert 版本号

KITTI数据集简介与使用

点击上方“小白学视觉”,选择加"星标"或“置顶” 重磅干货,第一时间送达 摘要:本文融合了Are we ready for Autonomous Driving? The KITTI Vision Benchmark Suite和Vision meets Robotics: The KITTI Dataset两篇论文的内容,主要介绍KITTI数据集概述,数据采集平台,数据集详细描述,评价准则以及具体使用案例。本文对KITTI数据集提供一个较为详细全面的介绍,重点关注利用KITTI数据集进行各项研究与实验。 KITTI数据集概述 KITTI数据集由德国卡尔斯鲁厄理工学院和丰田美国技术研究院联合创办,是目前国际上最大的自动驾驶场景下的计算机视觉算法评测数据集。该数据集用于评测立体图像(stereo),光流(optical flow),视觉测距(visual odometry),3D物体检测(object detection)和3D跟踪(tracking)等计算机视觉技术在车载环境下的性能。KITTI包含市区、乡村和高速公路等场景采集的真实图像数据,每张图像中最多达15辆车和30个行人,还有各种程度的遮挡与截断。整个数据集由389对立体图像和光流图,39.2 km视觉测距序列以及超过200k 3D标注物体的图像组成[1] ,以10Hz的频率采样及同步。总体上看,原始数据集被分类为’Road’, ’City’, ’Residential’, ’Campus’ 和 ’Person’。对于3D物体检测,label细分为car, van, truck, pedestrian, pedestrian(sitting), cyclist, tram以及misc组成。 数据采集平台 如图-1所示,KITTI数据集的数据采集平台装配有2个灰度摄像机,2个彩色摄像机,一个Velodyne 64线3D激光雷达,4个光学镜头,以及1个GPS导航系统。具体的传感器参数如下[2] : • 2 × PointGray Flea2 grayscale cameras (FL2-14S3M-C), 1.4 Megapixels, 1/2” Sony ICX267 CCD, global shutter • 2 × PointGray Flea2 color cameras (FL2-14S3C-C), 1.4 Megapixels, 1/2” Sony ICX267 CCD, global shutter

将激光点云数据投影到二维图像及对三维点云上色

最近在做一些毕设的东西,做到这里写个笔记记录以下,也为大家提供一点参考。 本次所用的数据是16线的激光点云数据和1080p的usb图像信息,内容涉及到标定,投影两个部分,参考网上大部分都是ros下方进行进一步开发,这里写一个不一样的。 1、相机和激光雷达标定 相机和激光雷达标定使用的是autoware的标定包。需要标定的话可以参考大佬们的博客,内容相差不大,里面有工具安装步骤和标定方法。 https://blog.csdn.net/AdamShan/article/details/81670732 https://blog.csdn.net/zbr794866300/article/details/107109186 2、矩阵参数转置 autoware构建出来的矩阵不能拿来直接使用,原因我就不仔细在这里介绍了。可以参考大佬们的博客。直通车!!!(飞机票) 3、激光和相机之间的投影 这里就直接上全部代码了,关键部分的代码解读,参考这行的飞机票。python版本的点这个链接。 #include<iostream> #include<opencv2/opencv.hpp> #include<string> #include<pcl/io/pcd_io.h> #include<pcl/common/transforms.h> #include<pcl/console/parse.h> #include<pcl/visualization/range_image_visualizer.h> #include<pcl/common/common_headers.h> #include<pcl/visualization/pcl_visualizer.h> #include<pcl/visualization/cloud_viewer.h> using namespace std; struct fileArg { cv::Mat extrinsic_mat, camera_mat,dist_coeff; //外参矩阵,内参矩阵,畸变矩阵 cv::Mat rotate_mat,transform_vec; //旋转矩阵,平移向量 }; struct calcuArg { cv::Mat rotate_mat; cv::Mat transform_vec; cv::Mat rotate_vec; }; void getMatrixFromFile(cv::String filePath, fileArg& filearg, calcuArg& calarg) { cv::FileStorage fs(filePath, cv::FileStorage::READ); //打开标定结果文件 if(!fs.isOpened()) cout<< "open failed"<<endl; fs["CameraExtrinsicMat"] >> filearg.extrinsic_mat; //从文件里读取4x4外参矩阵 fs["CameraMat"] >>filearg.camera_mat; //从文件里读取3x3相机内参矩阵 fs["DistCoeff"] >> filearg.

【Java实现】合并两个有序链表

🎈目录🎈 问题描述🔒 输入输出示例: 解题分析🔑 代码实现🔓 题目入口📌:合并两个有序链表 问题描述 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 输入输出示例: 解题分析 合并链表跟合并数组差不多,合并两个数组,是分别比较两个数组中元素的大小,然后放入新数组中。对于链表来说,我们不需要准备新的链表,我们可以直接在原有链表的基础上进行修改。 对我们来说,合并链表后的头结点难以确定,如果 链表list1 的头结点 小于 链表list2的头结点,那么合并后的链表的 头结点就是 list1的头结点,反之就是 list2的头结点。这样判断头结点,有点过于复杂,我们可以新开辟一个傀儡结点(虚拟节点)newHead,然后 newHead 的val值赋为-1,同时创建一个 tmp指针指向newHead 结点。 这样我们就可以省去头结点的确认,因为newHead.next 就是合并后链表的头结点。 tmp: 便于我们合并链表 接下来就是合并list1 和 list2 两个链表了,不断比较 list1 和 list2 所指向结点的val 值大小 如下图,list1.val 小于 list2.val,所以便把 list1 的地址传给 tmp.next,list1和tmp都向后移一步,list2保持不动。当list1.val 大于 list2.val,具体操作类似。 在判断两个链表是个多次的比较过程,所以我们要放到循环里面,那循环结束的条件我们还没确定。如下图,当 list2 指向null时,我们就要结束比较了,因为在比较下去编译器就会报出空指针异常。 所以一这段的代码我们可以写为: while(list1 != null && list2 != null){ if(list1.val < list2.val){ tmp.next = list1; list1 = list1.next; tmp = tmp.next; }else{ tmp.

coreldraw2022新版本新功能介绍cdr2022

CorelDRAW 2022基于CDR功能打造的一款实用色矢量图形设计及制作软件,相比于其他版本它更加面向于大众,更加适合业余爱好者和家庭企业的图形设计用户。为用户提供了还提供了强大的图形设计布局功能,其矢量图和页面布局工具可以在程序中轻而易举的找到,还可一键分享你的设计结果。 coreldraw2022最新版是一款由Corel推出的面向个人用户的图形设计软件,软件主要用于矢量图形的设计制作,它为用户们提供了强大的图像处理功能以及一套完整的视觉沟通解决方案,不管是矢量绘图或版面设计,还是网站制作或位图编辑,用户始终哦都可以通过这款软件得心应手地进行各种设计创作。 推出新版本2022的重新设计了操作页面,可以让您根据自己的工作习惯选择您的工作空间。 如果您习惯使用ps 或 AI,则可以将 CorelDRAW 的新界面设置为与上述软件类似。 新版本还提供了几个用于优化工作流程的新工作区,并支持高分辨率和多显示器,允许您在多个屏幕上移动项目。 CorelDraw-CorelDRAW2022正式版介绍 coreldraw2022最新版是一款由Corel公司推出的面向个人用户的图形设计软件,软件主要用于矢量图形的设计制作,它为用户们提供了强大的图像处理功能以及一套完整的视觉沟通解决方案,不管是矢量绘图或版面设计,还是网站制作或位图编辑,用户始终哦都可以通过这款软件得心应手地进行各种设计创作。 推出新版本2022的重新设计了操作页面,可以让您根据自己的工作习惯选择您的工作空间。 如果您习惯使用ps 或 AI,则可以将 CorelDRAW 的新界面设置为与上述软件类似。 新版本还提供了几个用于优化工作流程的新工作区,并支持高分辨率和多显示器,允许您在多个屏幕上移动项目。 软件名称:CorelDRAW Graphics Suite 订阅版简介: CorelDRAW Graphics Suite 订阅版拥有配备齐全的专业设计工具包,可以通过非常高的效率提供令人惊艳的矢量插图、布局、照片编辑和排版项目。价格实惠的订阅就能获得令人难以置信的持续价值,即时、有保障地获得独家的新功能和内容、一流的性能,以及对最新技术的支持。获得 CorelDRAW Graphics Suite 订阅奖励,您将可以畅享其他版本无法享受的专属新功能和内容。 功能介绍: 更快速的照片编辑功能 借助新的、无损的可堆叠调整预置和全新的“调整”泊坞窗,获得令人难以置信的创意,速度比以前快 10 倍。尽享为常用照片编辑功能添加的许多受用户启发的增强功能,以及带有新工具、快捷方式和命令的更新的“调整”菜单。 受客户启发的功能 尽享根据忠实用户的直接建议推出的许多丰富功能,从省时的“多页”视图和“页面”改进到有价值的图像编辑和导出增强功能,都囊括其中。在出现想法时提交您自己的想法,并对他人的想法进行投票,为 CorelDRAW Graphics Suite 的设计和开发贡献自己的力量,从而助力我们实现这一目标! 动态资产管理 通过跨项目和团队共享符号,以及在您或其他人进行更改时同步更新,为设计资产创建单一的真实来源。 省时排版 在 Corel Font Manager 中,通过直接访问一千多种 Google Fonts 字体系列,省去了从头开始创建版式的步骤。 协作改进 得益于简化的登录过程和性能增强功能,更快地保存、打开和共享云设计,体验真正高效的协作工作流。 矢量插图 使用 CorelDRAW 强大的矢量插图工具将简单的线条和形状变成复杂的艺术品。借助多种通用形状和绘图工具创建曲线。使用轮廓、封套、渐变和网状填充等效果工具,为您的矢量插图添加创意效果。 页面布局 找到为小册子、多页文档等创建布局您需要的所有工具。可以在单页编辑和多页编辑之间切换,让您以自己想要的方式自由创作。 排版 使用一整套完整的版式工具,排列精美字体布局。为图块阴影和轮廓等文本添加效果,通过可变字体支持响应性地微调字体,为文本适配路径等。 字体管理 通过直观易用的 Corel Font Manager 组织并管理您的字体库,无需安装即可直接使用自己喜欢的字体。使用网络存储功能更快地处理字体,直接访问 1,000 多种 Google Fonts 字体系列。

变量的命名规则十二条

一般规则 规则一 直观可以拼读,望文得知意,便于记忆,采用英文单词或组合,不建议使用拼音,英文单词也不要太复杂,建议使用简写 规则二 变量长度符合“min_length && max_information”,比如Max_value替换maxvalueuntiloverflow,较长的单词可以去掉元音形成缩写 规则三 当标识符号由多个词组成时,每个词的第一个字母要大写,其余全部小写 例如 int CurrentVal; //看起来清楚易懂 规则四 尽量避免名字中出现数字编号,例如我之前命名很喜欢用value1,value2,value3等等,除非逻辑上的确需要,像驱动开发和引脚之类的,加编号更易使用 规则五 在对多个文件之间共同使用的全局变量或函数一定要加范围限定符号,(建议使用模块缩写作为范围限定符) 规则六 符号命名有两部分,规范标识符前缀(后缀)+含义标识,全局变量以g或g+模块缩写(大写)作前缀,后面跟第一个字母大写的变量名。C中全局变量是不稳定因素,要保持警惕,用前缀显式标识变量为全局,能起到提示作用。名称前加上模块的缩写,可以在多模块集成链接时,避免模块间全局变量重名。 局部变量中,循环计数/数组下标可用i,j,k,m依次表示。除此以外,其它变量加前缀表示变量类型,前缀没有统一规范,p代表指针,pf指向函数的指针,f单精度浮点,db双精度浮点,u,s分别代表无符号与有符号数,即unsigned与signed。这样可以从变量名看出其类型,并避免一些bug 模板:模块名缩写_作用域前缀|数据类型前缀|【指针前缀】|含义标识|数组/结构后缀 规则七 作用域前缀命名规则 标识符类型作用域前缀全局变量g文件局部变量n函数局部变量f局部作用域变量a全局函数g静态函数n 规则八 数据类型前缀命名规则 前缀后缀数据类型备注btbitbooleanboolean charchar iintsshrot[int]llong[int]uunsigned[int]dduobleffloatppointer指针前缀vvoidstenumststructstunionfpfunction point_aarray of_sttypedef enum/struct/union 规则九 变量含义标识符构成:目的词+动词(过去分词)+状语+目标 例如:DataDeletedFromSD 函数含义标识符构成: 动词(一般现在时)+目标词+状语+目标 对了,同时安利一波现在真正看的语法视频 英语语法精讲合集 (全面, 通俗, 有趣 | 从零打造系统语法体系)_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1XY411J7aG?p=8&vd_source=8e3e569f698756c0f7529e30f2af56ee 规则十 所有宏定义,枚举常数,只读变量全部用大写字母命名,用下划线分割单词。 例如 const int MAX_LENGTH = 100; #define FILE_PATH “/usr/tmp” 规则十一 定义变量时不要忘记了初始化。定义变量时编译器并不一定清空这块内存,它的值可能是无效的数据。 规则十二 考虑到习惯问题,局部变量中可采用通用的命名方式,仅限于n,i,j等作为循环变量使用。 2022年7月5日21:26:07 行政楼

IO流之字节流与常见编码

IO流 1.流的概念和分类 IO流核心组成 核心组成:一个类(File)、一个接口(Serializable)、四个抽象类(InputStream/OutputStream、Reader/Writer) 什么是流 流:内存与存储设备之间传输数据的通道 流的分类 按方向 输入流:将<存储设备>中的内容读到<内存>中输出流:将<内存>中的内容写到<存储设备>中 按单位 字节流:以字节为单位,可以读写所有数据字符流:以字符为单位,只能读写文本数据 按功能 节点流:具有实际传输数据的读写功能过滤流:在节点流的基础之上增强功能 2.字节流 2.1字节流抽象类 InputStream 此抽象类是表示字节输入流的所有类的父类。InputSteam是一个抽象类,它不可以实例化。数据的读取需要由它的子类来实现。根据节点的不同,它派生了不同的节点流子类。继承自InputSteam的流都是用于向程序中输入数据,且数据的单位为字节(8 bit)常用方法: public int read(){}:读取一个字节的数据,并将字节的值作为int类型返回(0-255之间的一个值)。如果未读出字节则返回-1(返回值为-1表示读取结束)。while((data=fis.read())!=-1)来判断读取文件是否结束。 public int read(byte[] b){} :从该输入流读取最多 b.length个字节的数据,并把读取的数据存放到b这个字符数组里面 public int read(byte[] b, int off, int len){} OutputStream 此抽象类是表示字节输出流的所有类的父类。输出流接收输出字节并将这些字节发送到某个目的地 public void write(int n):向目的地中写入一个字节 public void write(byte[] b){} : 将 b.length个字节从指定的字节数组写入此文件输出流。 public void write(byte[] b, int off, int len){} 2.2文件字节流 FileInputStream: public int read(byte[] b) // 从流中读取多个字节,将读到内容存入 b 数组,返回实际读到的字节数;如果达到文件的尾部,则返回 -1 FileOutputStream: public void write(byte[] b) // 一次写多个字节,将 b 数组中所有字节,写入输出流 2.

关于地址请求在WebView中的跳转问题

转自:微点阅读 https://www.weidianyuedu.com 在实际项目开发中,我们用到WebView的场景,大多是在对接协议、第三方应用或网页时出现。对于页面加载,WebView没有自带等待效果。所以,需要我们去自定义各种带进度条的WebView,网上相关的例子也是不胜枚举,今天我们就来谈谈一条地址请求在WebView中的跳转问题: WebView中有两个工具类负责管理网页各种行为:WebChromeClient 和 WebViewClient。分别通过 setWebChromeClient() 和 setWebViewClient() 来实例化。 WebChromeClient: Chrome一词表明这个类和webView的网页内容管理有关,它的成员方法帮助WebView处理Javascript的弹框、网站图标、网站title、加载进度等。最常用的方法如下: onJsConfirm():页面选择框; onJsAlert():页面提示框; onJsPrompt():页面确认框; onProgressChanged():加载进度; 当网页出现上述操作时,便会触发方法。其中 onProgressChanged() 方法通常用来设计成线性进度条的样式。当然这个工具类不是本次内容的主角。 WebViewClient WebViewClient(本篇重点): 帮助WebView处理各种通知、请求事件、记录页面加载过程的。 其中就包括URL地址,我们可以通过它来监控到地址的调用过程。 我们需要用到的相关的方法有: shouldOverrideUrlLoading(): onPageStarted(): onPageFinished(): 网页加载分析 触发加载网页的行为主要有两种方式: (A)点击页面,触发 (B)调用WebView的loadUrl()方法。 这两种方法都会发出一条地址,区别就在于这条地址是目的地址还是重定向地址。 我们以访问 http://www.baidu.com 百度的页面来测试一下方法的执行顺序。我事先在 shouldOverrideUrlLoading(),onPageStarted(),onPageFinished() 中添加的log输出,我们观察一下log日志: 1、 在代码中通过loadUrl加载百度的首页,此时的行为属于(B)方式: Log如下: 2、在首页,我们点击一下“hao123”,跳转到 www.hao123.com 的主页上来,此时的行为属于(A)方式,Log如下: 3、点击“影视”,进入到影视页面,此时的行为属于(A)方式,Log如下: 4、然后,我们点击“影视列表”,此时的行为属于(A)方式,Log如下: 5、我们重新发起一次loadUrl(),这次访问一下CSDN,此时的行为属于(B)方式,Log如下: 通过上述范例,我们可以得出以下结论: 在A行为方式(点击页面,触发)下: 1、如果是目的地址,那么方法的执行顺序是: shouldOverrideUrlLoading() -> onPageStarted() -> onPageFinished() shouldOverrideUrlLoading()由于它要提供给APP选择加载网页环境的机会,所以只要是网页上地址请求,都会获取到。 2、如果是重定向地址,在跳转到目的地址之前会进行不断的地址定位,每一次地址定位都会由以下执行顺序体现出来: onPageStarted()->shouldOverrideUrlLoading()->onPageFinished() 我们暂且设定这种执行顺序叫:fixed position 那么一个正常的重定向地址,方法的执行顺序就是: shouldOverrideUrlLoading()->fixed position -> … -> fixed position ->onPageStarted()->onPageFinished() 在B行为方式(调用WebView的loadUrl()方法)下:

前端上传大文件的解决方案

最近遇见一个需要上传超大大文件的需求,调研了七牛和腾讯云的切片分段上传功能,因此在此整理前端大文件上传相关功能的实现。 在某些业务中,大文件上传是一个比较重要的交互场景,如上传入库比较大的Excel表格数据、上传影音文件等。如果文件体积比较大,或者网络条件不好时,上传的时间会比较长(要传输更多的报文,丢包重传的概率也更大),用户不能刷新页面,只能耐心等待请求完成。 下面从文件上传方式入手,整理大文件上传的思路,并给出了相关实例代码,由于PHP内置了比较方便的文件拆分和拼接方法,因此服务端代码使用PHP进行示例编写。 本文相关示例代码位于github上,主要参考 聊聊大文件上传 大文件切割上传 文件上传的几种方式 首先我们来看看文件上传的几种方式。 普通表单上传 使用PHP来展示常规的表单上传是一个不错的选择。首先构建文件上传的表单,并指定表单的提交内容类型为enctype="multipart/form-data",表明表单需要上传二进制数据。 然后编写index.php上传文件接收代码,使用move_uploaded_file方法即可(php大法好…) form表单上传大文件时,很容易遇见服务器超时的问题。通过xhr,前端也可以进行异步上传文件的操作,一般由两个思路。 文件编码上传 第一个思路是将文件进行编码,然后在服务端进行解码,之前写过一篇在前端实现图片压缩上传的博客,其主要实现原理就是将图片转换成base64进行传递 varimgURL = URL.createObjectURL(file); ctx.drawImage(imgURL, 0, 0); // 获取图片的编码,然后将图片当做是一个很长的字符串进行传递 vardata= canvas.toDataURL( "image/jpeg", 0.5); 在服务端需要做的事情也比较简单,首先解码base64,然后保存图片即可 $imgData = $_REQUEST[ 'imgData']; $base64 = explode( ',', $imgData)[ 1]; $img = base64_decode($base64); $url = './test.jpg'; if(file_put_contents($url, $img)) { exit(json_encode( array( url => $url ))); } base64编码的缺点在于其体积比原图片更大(因为Base64将三个字节转化成四个字节,因此编码后的文本,会比原文本大出三分之一左右),对于体积很大的文件来说,上传和解析的时间会明显增加。 更多关于base64的知识,可以参考Base64笔记。 除了进行base64编码,还可以在前端直接读取文件内容后以二进制格式上传 // 读取二进制文件 functionreadBinary(text){ vardata = newArrayBuffer(text.length); varui8a = newUint8Array(data, 0); for( vari = 0; i < text.

UWB超宽带定位技术,实时厘米级高精度定位应用,超宽带传输技术

无论移动在室内还是室外环境下,快速准确地获得移动终端的位置信息和提供位置服务的需求变得日益迫切。 利用无线通信和参数测量确定移动终端位置,而定位信息又可以用来支持位置业务和优化网络管理,提高位置服务质量和网络性能。 UWB超宽带技术是一种与传统通信技术有极大差异的通信新技术。超宽带技术可以应用于室内静止或者移动物体以及人的定位跟踪与导航。 它不需要使用传统通信体制中的载波,而是通过发送和接收具有纳秒或纳秒级以下的极窄脉冲来传输数据,从而具有GHz量级的带宽。 在万物互联的当下,室内精准定位正在成为刚需,大型商场超市希望能够借助室内定位技术为前来购物的消费者提供实时导引服务,同时基于位置提供对应的营销服务。 医院希望对医疗设备进行实时定位,便于需要时快速调用;希望能对特殊病患进行定位监护,防止其发生意外。 UWB定位技术精度已可实现5-10厘米的高精度定位,具有对信道衰落不敏感、发射信号功率谱密度低、低截获能力、系统复杂度低、能提供数厘米的定位精度等优点。 超宽带技术具有GHz量级的带宽,因此穿透力强、抗干扰效果好、安全性高、系统复杂度低、能提供高精度定位,前景相当广阔。 机场人员、货物、运载机器精准定位,快速找到货物,提高管理效率;物流仓储跟踪条码阅读器和叉车,减少检查环节,使仓储管理变得灵活。 医疗实时跟踪病人,进行照顾和管理,方便人力资源管理;危险环境定位个人和资源,安全位置紧急搜索,人员监控,优化管理过程,做到安全有效。 重点安保区域人员的进出管理、实时位置查询、禁区监管、隔离距离控制、人员调度,能对人员路线、距离、速度进行监控和统计。 体育活动实时跟踪与计算运动员的方向和速度等,详细的性能分析,记录队伍比赛,包括控球时间、射门速度、持球速度等数据一目了然...... 利用通信技术把传感器、控制器、机器、人员和物等通过新的方式联在一起,实现了人与物、物与物之间的通讯,也真真切切让我们从感官上体验到了位置数据。 UWB超宽带技术有着低功耗、对信道衰落(如多径、非视距等信道)不敏感、抗干扰能力强、不会对同一环境下的其他设备产生干扰、穿透性较强(能在穿透一堵砖墙的环境进行定位)的优点。 在室内或者建筑物比较密集的场合可以获得良好的定位效果,同时在进行测距、定位、跟踪时也能达到更高的精度,应用于静止或者移动物体以及人的定位跟踪,能提供很高的定位准确度和定位精度。 UWB精准定位技术,可实现实时定位、人员资产分布、历史轨迹回放、电子围栏报警、物资管理、物资盘点等功能。 可广泛应用于隧道管廊、司法监狱、大型工厂、石油化工、养老医院、仓储物流、智能楼宇、机场车站等对人员和资产有定位管理需求的场景。

YOLOX训练报错TypeError: evaluate() got an unexpected keyword argument ‘return_outputs‘

训练YOLOX的时候,每次评估均会报错停止,报错信息如下: 2022-07-02 17:51:57 | INFO | yolox.core.trainer:253 - epoch: 10/300, iter: 10/36, mem: 5854Mb, iter_time: 0.220s, data_time: 0.001s, total_loss: 6.4, i ou_loss: 2.7, l1_loss: 0.0, conf_loss: 3.1, cls_loss: 0.6, lr: 1.248e-03, size: 608, ETA: 0:53:54 2022-07-02 17:52:00 | INFO | yolox.core.trainer:253 - epoch: 10/300, iter: 20/36, mem: 5854Mb, iter_time: 0.225s, data_time: 0.001s, total_loss: 6.3, i ou_loss: 2.8, l1_loss: 0.0, conf_loss: 2.9, cls_loss: 0.7, lr: 1.247e-03, size: 480, ETA: 0:53:26 2022-07-02 17:52:02 | INFO | yolox.

也算是学习中的小总结

#以下代码都是在jupyter notebook中运行的 import torch c=torch.arange(20).reshape(2,5,2) c,c.sum(axis=0) #(2,5,2)第一个2消失,两个(5,2)相加 #运行结果 (tensor([[[ 0, 1], [ 2, 3], [ 4, 5], [ 6, 7], [ 8, 9]], [[10, 11], [12, 13], [14, 15], [16, 17], [18, 19]]]), tensor([[10, 12], [14, 16], [18, 20], [22, 24], [26, 28]])) c=torch.arange(20).reshape(2,5,2) c,c.sum(axis=1) #(2,5,2)第二个5消失,两个(5,2)变成(1,2)再相加 #运行结果 (tensor([[[ 0, 1], [ 2, 3], [ 4, 5], [ 6, 7], [ 8, 9]], [[10, 11], [12, 13], [14, 15], [16, 17], [18, 19]]]), tensor([[20, 25], [70, 75]])) c=torch.

训练yolo时报错RuntimeError: result type Float can‘t be cast to the desired output type __int64个人解决方案

运行YOLOv5 6.1和yolor的时候,训练都没能正常运行,均出现了如下错误: AutoAnchor: 5.00 anchors/target, 1.000 Best Possible Recall (BPR). Current anchors are a good fit to dataset Image sizes 640 train, 640 val Using 0 dataloader workers Logging results to runs\train\exp14 Starting training for 300 epochs... Epoch gpu_mem box obj cls labels img_size 0%| | 0/8 [00:03<?, ?it/s] Traceback (most recent call last): File "train.py", line 634, in main(opt) File "train.py", line 525, in main train(opt.hyp, opt, device, callbacks) File "

YOLOX报错FileNotFoundError: [Errno 2] No such file or directory: ‘xxx.xml‘个人解决方案

在训练YOLOX的时候,每训练10次,进行模型评估的时候,会报错停止,完整报错信息如下: 2022-07-05 16:19:49 | ERROR | yolox.core.launch:98 - An error has been caught in function 'launch', process 'MainProcess' (17800), thread 'MainThread' ( 26892): Traceback (most recent call last): File "E:\Study\DeepLearn\DPlearn\YOLO\YOLOX\tools\train.py", line 134, in <module> launch( └ <function launch at 0x00000270311B3310> > File "C:\ProgramData\Anaconda3\lib\site-packages\yolox-0.3.0-py3.9.egg\yolox\core\launch.py", line 98, in launch main_func(*args) │ └ (╒═══════════════════╤═══════════════════════════════════════════════════════════════════════════════════════════════════════... └ <function main at 0x0000027031C8FE50> File "E:\Study\DeepLearn\DPlearn\YOLO\YOLOX\tools\train.py", line 118, in main trainer.train() │ └ <function Trainer.train at 0x0000027034191280> └ <yolox.

基础容器知识-POD

• pod是k8s系统中的最小部署单元 • pod是由一个或多个容器组成。 • 一个pod中容器共享网络命名空间 • 每个pod都有一个根容器(pause容器)用来管理pod中的用户业务容器 • 创建容器使用docker,一个docker对应一个应用程序,一个容器运行一个应用程序 • Pod是多进程设计,运行多个应用程序 • 一个pod有多个容器,一个容器里面运行一个应用程序 • Pod存在未了亲密性应用 • 两个应用直接进行校核 • 网络之间调用 • 两个应用需要频繁调用 由于容器本身之间相互隔离,通过linux namespace、group组实现隔离。那么space用于隔离文件系统,进程和网络。 (1) 文件系统隔离:每个容器都有自己的root文件系统 (2) 进程隔离:每个容器都运行在自己的进程环境 (3) 网络隔离:容器间的虚拟网络接口和IP都是分开的 (4) pod要实现共享网络机制,需要具备同一个pod里面的容器共享namespace

Kuboard【k8s图形化界面管理】安装全过程

文章目录 前言一、Kuboard是什么二、安装步骤 1.安装Kuboard-Spray2.进入Kuboard总结 前言 说Kuboard之前我们得先了解一下Kubernetes,Kubernetes是一个可以移植、可扩展的开源平台,使用 声明式的配置 并依据配置信息自动地执行容器化应用程序的管理。在所有的容器编排工具中(类似的还有 docker swarm / mesos等),Kubernetes的生态系统更大、增长更快,有更多的支持、服务和工具可供用户选择。 一、Kuboard是什么 Kuboad便是能够在Kubernetes中快速落实微服务,简便Kubernetes的操作,使初学者能够更快地上手Kubernetes的管理。 二、安装步骤 1.安装Kuboard-Spray Kuboard-Spray 是一款可以在图形界面引导下完成 Kubernetes 高可用集群离线安装的工具 取一台服务器或虚拟机,执行一条命令,即可完成 Kuboard-Spray 的安装。 对这台服务器的最低要求为: 1核2G不少于 10G 磁盘空余空间已经安装好 docker docker run -d \ --privileged \ --restart=unless-stopped \ --name=kuboard-spray \ -p 80:80/tcp \ -v /var/run/docker.sock:/var/run/docker.sock \ -v ~/kuboard-spray-data:/data \ eipwork/kuboard-spray:latest-amd64 # 如果抓不到这个镜像,可以尝试一下这个备用地址: # swr.cn-east-2.myhuaweicloud.com/kuboard/kuboard-spray:latest-amd64 这个命令一般是在命令行执行,等待执行完成后 在浏览器打开地址 http://这台机器的IP,输入用户名 admin,默认密码 Kuboard123,即可登录 Kuboard-Spray 界面。 进入界面后,我们选择系统设置这个选项,然后再选择其中的资源包管理,因为我们下载的是最新版本的所以和图示有点差别,但是我们随便选择哪一个都不影响结果。 点击 导入 按钮,在界面的引导下完成资源包的加载。 重要 权限问题 导入资源包时,可能会碰到 no such file or directory 或者 permission denied 之类的错误提示,通常是因为您开启了 SELinux,导致 kuboard-spray 不能读取映射到容器 /data 的路径离线导入 如果您处在内网环境,上图中的列表默认将是空的,请注意其中的 离线加载资源包 按钮,它可以引导您轻松完成资源包的离线加载过程。 在下载的过程中,会有一个命令提示你在命令行中查看进度,可以试一下。下载完成后我们进入集群管理这个界面。

云上有AI,让地球科学研究更省力

简介:达摩院发布AI Earth地球科学云平台,将免费向科研人员开放,助力云上地球科学研究。 对于遥感卫星,我们并不陌生,一颗颗遥感卫星,就是人类安放在近地轨道和外太空的眼睛,他们准确、勤恳、不知疲倦地帮我们观察着地球。 但卫星收集回来的数据,却不会像1+1=2这样简单浅显地呈现出来,要把卫星遥感数据翻译成可供我们使用的有效信息,按照传统方式,一般分为三步走: 向卫星数据运营机构申请获取数据,或者下载行业公开数据; 将数据在本地计算机进行存储配置; 对本地的数据进行处理、分析和研究。 而分析环节对机器的计算和存储资源要求非常高,普通计算机难以胜任分析大规模的影像数据。另一方面,针对海量卫星遥感数据的分析,传统方法自动化程度低、成本高、解译效率低的难题一直未能解决。 达摩院AI Earth地球科学云平台,一个解决上述问题的综合功能平台应运而生。 AI Earth地球科学云平台基于达摩院在深度学习、计算机视觉、地理空间分析等方向上的技术积累,结合阿里云强大算力支撑,提供遥感、气象等多源对地观测数据的云计算分析服务,用数据感知地球世界,让AI助力科学研究。 如果您有以下使用需求: 个人用户,需要便捷获取海量公开遥感数据,并进行高效云上处理分析。 政企用户,需要基于自身业务场景,验证遥感AI能力,打造线下专有云系统。 欢迎体验AI Earth地球科学云平台,目前平台已支持多种公开数据在线检索、遥感影像在线分析以及相关数据管理功能。 多源数据检索 目前平台已上线Landsat 5、Landsa 7、Landsa 8、Landsa 9、Sentinel-1、Sentinel-2、MODIS等公开数据集,更多专题数据正在更新中,详细数据规格信息请参见数据集介绍页面。 平台支持四种方式确定检索区域:1.通过POI信息检索;2.通过行政区划检索;3.在地图上圈画区域检索;4.上传包含地理信息的矢量文件检索。确定检索区域范围后,继续筛选数据采集时间、数据类型、云量等信息,点击检索按钮即可得到所需数据列表。 在线数据处理 平台以达摩院遥感AI能力为优势,针对高分数据,支持地物分类、变化检测、建筑物提取、地块提取等多种遥感AI在线解译工具,针对Sentinel-1等雷达数据,上线了SAR数据AI水体提取功能。 此外,平台还提供了指数计算、镶嵌裁切、波段融合、坐标转换、栅格重采样、图斑优化、时序图制作等八类通用型栅格、矢量基础处理工具,更多遥感数据处理原子能力正在持续上云。 云GIS工作空间 平台基于GIS专业软件工作视角,以图层叠加方式呈现各类遥感数据,通过工具箱模式归类各种遥感数据处理算子,实现便捷高效的栅格和矢量数据在线处理。 对于数据处理流程,平台目前采用无代码低门槛的GUI操作链路,后期版本已规划支持基于JavaScript和Python的开发者模式,满足更多开发者用户使用需求。 多源数据管理 平台支持用户在线管理收藏的公开数据、自主上传的高分数据以及经平台分析处理后的成果数据。 近期,平台将持续完善公开数据集和数据处理原子能力,支持用户在云上完成各类遥感数据分析处理工作,免去各类原始数据查找下载的繁琐链路,数据成果可以直接云端应用或下载到本地。 模型训练 平台支持用户在线模型训练、模型管理、样本标注、以及样本库管理。 岁末年初达摩院发布了2022十大科技趋势,AI Earth就是十大趋势之首——AI for Science的实例应用。 千百年来,实验科学和理论科学是科学界的两大基础范式。“人”发现科学规律,然后运用;“人”再从大量的实验数据中,总结科学规律。 如今人工智能正在催生新的科研范式,AI可以自主发现科学规律。换言之,是AI从大量的数据中发现新规律,然后交给人类来运用。 开放的地球科学云平台,不仅带来效率的显著提升,让研究者从繁杂的数据获取分析步骤中解放出来;更科技、更高效、更便捷的AI正在伴随人类一起对母星地球探测出更深入的认知。 AI Earth 地球科学云平台(https://engine-aiearth.aliyun.com) 原文链接:https://developer.aliyun.com/article/982052? 版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

用python删除pdf文件的特定页码

#pip install PyPDF2模块 #代码文件写好源文件和目标文件完整路径 #调用函数,参数写好要删除的页码即可 from PyPDF2 import PdfFileWriter,PdfFileReader fn1=r'C:\Users\asus\Desktop\s\零起点PYTHON机器学习快速入门2.pdf' fn2=r'C:\Users\asus\Desktop\s\零起点PYTHON机器学习快速入门3.pdf' def PDF_delete(index): #参数是一个整数列表,列表里是要删除的页码 output = PdfFileWriter() # 声明一个用于输出PDF的实例 input1 = PdfFileReader(open(fn1, "rb")) # 读取本地PDF文件 pages = input1.getNumPages() # 读取文档的页数 for i in range(pages): if i + 1 in index: continue # 待删除的页面 output.addPage(input1.getPage(i)) # 读取PDF的第i页,添加到输出Output实例中 outputStream = open(fn2, "wb") output.write(outputStream) # 把编辑后的文档保存到本地 PDF_delete(list(range(2)))

【java】ArrayList,LinkedList晚自习整理

Array和ArrayList的区别是什么? Array是数组,ArrayList是类 Array是定长的(需要手动扩容),ArrayList长度可变(使用过程中自动扩容) ArrayList的底层是Array ArrayList和LinkedList的区别是什么? 1.底层数据结构的实现:ArrayList底层数据结构是动态数组,而LinkedList的底层数据结构是双向链表 2.随机访问(即读)效率:ArrayList比LinkedList在随机访问的时候效率要高,因为ArrayList底层是数组,可以通过索引号快速访问,LinkedList是通过二分查找法遍历链表节点进行查找的 3.增加和删除效率:在非首尾的增加和删除操作,LinkedList要比ArrayList效率要高,因为ArrayList增删操作需要大量的前移或后移,在这个过程中涉及到大量的赋值操作比较耗时,LinkedList只需要修改节点对象的左右指针即可。 4.内存占用空间:LinkedList比ArrayList更占内存,因为LinkedList的节点除了存储数据,还存储了两个引用,一个指向前一个元素,一个指向后一个元素 5.总和来说,在需要频繁读取集合中元素的时候,更推荐使用ArrayList,而在插入和删除操作较多时推荐使用LinkedList 你知道几种遍历ArrayList的方式? 遍历ArrayList和LinkedList的几种方式: 普通for循环增强型for循环forEach循环迭代器 ArrayList<String> list=new ArrayList<>(); list.add("张飞"); list.add("关羽"); list.add("马超"); list.add("赵云"); list.add("黄忠"); System.out.println("********遍历方式一:普通for循环********"); for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i)); } System.out.println("********遍历方式二:增强型for循环********"); //1.增强型for循环中不需要写循环四要素 //2.不需要手动执行list.get()操作了 for (String item : list) {//每循环一次会自动从list中取出元素赋给临时变量,直到没有下一个元素自动退出 System.out.println(item); } System.out.println("********遍历方式三:forEach循环********"); //list调用forEach函数 //forEach函数的参数是一个箭头函数 //箭头函数的语法是(参数名)->{} //隐式循环forEach函数中循环 //forEach函数会遍历list,取出每一个值后,会回调你的箭头函数,把参数传给箭头函数的参数 list.forEach((item)->{ System.out.println(item); }); list.forEach((item)-> System.out.println(item)); System.out.println("********遍历方式四:迭代器********"); //调用iterator()方法,取出一个迭代器对象 //使用iterator类声明一个迭代器指针,迭代器的泛型必须与list的泛型一致 Iterator<String> iterator=list.iterator(); //迭代器的hasNext可以判断是否还有下一个元素 while (iterator.hasNext()){ //迭代器的next方法可以取出下一个元素 String item=iterator.next(); System.out.println(item); }

mysql中thread_id,processlistid,os_id等详解

perforamance_schema.threads表中:THREAD_ID,PROCESSLIST_ID,THREAD_OS_ID information_schema.innodb_trx表中: trx_mysql_thread_id, trx_id thread_id: 仅在perforamance_schema中使用,是其内部自动增长的计数器,前台和后台线程均有这个id,且thread_id和thread_os_id相关联。 processlistid: 一般在mysql层使用,跟前台登录会话相关联,是真正的线程ID。 processlistid和前台用户直接相关,每创建一个登录会话,就会新增一个processlistid。 在performance_schema.threads表中,后台线程没有processlistID的值,这个值是NULL,这是因为后台线程不是登录用户所创建的,但是前后台线程都会有thread_os_id和thread_id的值,因为所有线程最终都要依赖OS线程执行,thread_id和thread_os_id有一定的对应关系。 **thread_os_id:**系统内部分配的线程ID,与ps -ef 出来的mysql线程号相同,top -H -p mysqld_pid,当然,OS不会为每一个会话创建os_id。 **trx_mysql_thread_id:**这个参数的值和processlistid相同,即执行事务的前台线程id,也即会话ID。 trx_mysql_thread_id: 即show processlist结果中的ID,也就是performance_schema.thread表中的processlistid; **trx_id:**事务使用 因此:一般情况下thread_id和thread_os_id不需要关注,只是用来性能库和后台使用。 一个事务的trx_id会关联一个trx_mysql_thread_id,而trx_mysql_thread_id的值又等同于processlistid(也是session id),通过processlistid去performance_schema.threads表可找到thread_id和thread_os_id 。 当需要kill掉一个事务时,不能直接kill thread_os_id,这样会导致数据库重启,且重启后事务会继续执行,因为事务具有原子性;如果直接执行kill processlistid或kill trx_mysql_thread_id或kill session_id,这也是我们常用的操作,这会使事务对应的trx_mysql_thread_id置为0,事务会rollback。 参考链接(https://www.likecs.com/show-204561278.html)

STM32相关手册使用记录

目录 一、概述二、手册获取2.1 芯片手册2.2 库手册和官方DEMO 三、手册内容3.1 数据手册3.1.1 查看外设挂载哪条总线 3.2 参考手册3.2.1 查看芯片flash页大小,最小存储单位3.2.2 STM32G0写flash的八字节对齐3.3.3 STM32唯一序列号UID 3.3 编程手册3.4 勘误手册 一、概述 当选用一款MCU后,进行开发前肯定要先拿到对应的手册。做固件开发,和硬件芯片选型的关注点是不一样的。除了基本的电气特性、片上资源外设情况,还要关注具体寄存器、标准库/HAL库的接口等。 本文主要是记录下STM32开发过程中,相关手册的使用。 随着手册查阅情况,陆续更新到各小节的笔记。 二、手册获取 2.1 芯片手册 这个肯定直接去官网下载了。直接搜索ST官网进入: 进入官网以后,直接在搜索框输入自己的芯片型号。英文不是很好,可以在右上角切换为中文。随着输入,下方会列出相关型号,以STM32F103RCT6为例: 搜索结果如下图,选择文件一栏,会给出提供的文档列表。按需下载即可: 2.2 库手册和官方DEMO STM32标准库官网下载方法。STM32 HAL库手册获取和查阅方法以及查看官方例程。 三、手册内容 3.1 数据手册 这个手册最为简洁明了。主要是芯片的电气物理特性,也可快速查看外设情况、空间资源、管脚定义等。 3.1.1 查看外设挂载哪条总线 使用STM32CubeMX生成工程时,并没有显示出CAN挂载在APB1还是APB2上: 打开芯片手册《stm32f103rc.pdf》,查看时钟树上也是没有标出的: 翻来翻去,结果就在时钟树的上一页。有点一叶障目不见泰山的意思: 3.2 参考手册 参考手册是RMXXXX开头: 下载后查看,可以看到RM即Reference Manual: 这个详细说明了芯片外设的特性和使用方法,包括寄存器定义说明。以ADC为例,目录如下: 通常有中文版本。 3.2.1 查看芯片flash页大小,最小存储单位 在编程过程中,对flash进行操作是必不可少的,比如参数存储、boot升级等。这时就需要确定flash的页大小以便进行擦除等操作。 可以看到同为STM32F1系列,不同容量,页的大小是不一样的。那么在分配参数空间时,就需要具体考虑。 也可以查看闪存编程手册(本文3.3编程手册中提供),里面有对flash更详细的描述。 3.2.2 STM32G0写flash的八字节对齐 //2022.2.9 在做boot程序过程中发现,不管是rtthread的drv_flash_g0.c和drv_flash_f1.c,还是裸机下的g0和f1,写flash存在差异: 左边是f1,右边是g0。从代码上看,g0要求地址8字节对齐,且以doubleword写入。而读flash是一致的: 翻看手册查找下依据。查看STM32G0编程手册: 在STM32F1的参考手册中可以看到: 参考链接:STM32L4系列内部FLASH双字编程示例。 3.3.3 STM32唯一序列号UID STM32唯一序列号UID–HAL_GetUIDw0详解。 3.3 编程手册 这里编程手册提供了两个: 闪存编程手册,对flash有更详细的描述。 3.4 勘误手册 STm32一次擦除多少页 资源大小

html2canvas+jsPDF实现横向打印iframe中的内容

需要用到的插件:html2canvas jsPDF.debug.js jquery html2canvas github地址:https://github.com/niklasvh/html2canvas jsPDF和html2canvas插件已上传到我的阿里云网盘(需要自取),地址: https://www.aliyundrive.com/s/auACtPpkw4w 效果预览 html2暂时不支持IE内核浏览器 //判断浏览器内核是否是IE if(!!window.ActiveXObject || "ActiveXObject" in window){ alert('截图打印暂不支持IE内核浏览器,请更换火狐或谷歌chrome内核浏览器,360等双核浏览器请切换至极速模式'); return; } //获取iframe var shareContent = document.getElementById('form_iframe'); //滚动iframe到顶部,如果不在顶部会截不完整 shareContent.contentWindow.scrollTo(0,0); //获取iframe的宽高 var width = shareContent.contentWindow.document.documentElement.scrollWidth; var height = shareContent.contentWindow.document.documentElement.scrollHeight; var canvas = document.createElement("canvas"); //创建一个canvas节点 //定义任意放大倍数 支持小数,表单内容过多,请尽量往小了调。目前测试,打印3页chrome下会出现崩溃 var scale = 1.5; canvas.width = width * scale; //定义canvas 宽度 * 缩放 canvas.height = height * scale ; //定义canvas高度 *缩放 canvas.style.width = width * scale + "px"; canvas.

前端CI/CD,从零开始,彻底弄懂前端自动化构建和部署

实现思路 1.程序员在本地进行开发 2.程序员将修改后的代码提交到gitlab代码仓库 3.gitlab收到代码后通过webhook通知jenkins进行构建 4.jenkins构建好了以后将构建好以后的代码发布的到线上服务器 优势 gitlab、jenkins、生产服务器这三个服务都可以分布在不同的服务器, 所以大大提高了可配置性也降低了耦合 环境准备 gitlab代码仓库(可以在线上, 也可以在本地)jenkins服务(可以跟gitlab不在同一个服务器上, 但是这里没有必要, 我把gitlab和jenkins都部署在本地服务器)生产环境 gitlab和jenkins服务我都是通过docker-compose进行安装的, 这个具体我就不多说了, 下面我贴一下docker-compose.yml文件 # gitlab的docker-compose.yml文件 version: "3" services: gitlab: image: twang2218/gitlab-ce-zh container_name: gitlab restart: always privileged: true hostname: '192.168.4.2' environment: TZ: 'Asia/Shanghai' GITLAB_OMNIBUS_CONFIG: | external_url "http://192.168.4.2:82" gitlab_rails['time_zone'] = 'Asia/Shanghai' gitlab_rails['gitlab_shell_ssh_port'] = 2222 gitlab_rails['gitlab_email_enabled'] = true gitlab_rails['gitlab_email_from'] = 'liaoxubao@aliyun.com' gitlab_rails['gitlab_email_display_name'] = 'liaoo' gitlab_rails['smtp_enable'] = true gitlab_rails['smtp_address'] = "smtp.aliyun.com" gitlab_rails['smtp_port'] = 465 gitlab_rails['smtp_user_name'] = "liaoxubao@aliyun.com" gitlab_rails['smtp_password'] = "jhudkir123" gitlab_rails['smtp_domain'] = "