CHERRY 键盘 alt 组合键失灵或开始菜单键失灵

之前电脑一直处于正常运转状态,这次开机后却发现莫名其妙的各种键盘快捷键都失灵了,近期也未曾安装和下载过任何软件,也未更新过软件和系统程序,但是键盘的快捷键却莫名的失效了,日常操作起来超级的不便; 度娘了很久,也尝试了很多办法,起初尝试修改系统内的程序设置,后发现依然无解,故排除了系统故障; 解决办法 CHERRY官网驱动下载 了解一下; 因为现在使用的键盘是 MX BOARD 8.0 最早的版本,后续 CHERRY 官方又迭代了很多新的产品,现使用的键盘驱动从未更新过,此次尝试下载了官网最新的驱动程序并对现有键盘进行了驱动更新的操作,操作简单便捷,稍事片刻更新成功,恩 。。。完美解决! 以上便是此次分享的全部内容,希望能对大家有所帮助!

WHUCTF做题记录-第九题dank-php

markdown用的不好,并且有写的不恰当的地方还请大佬指正,这题主要的知识点是php反序列化和无数字字母执行函数获取webshell <?php include "flag.php"; show_source(__FILE__); class user { var $name; var $pass; var $secret; } if (isset($_GET['id'])) { $id = $_GET['id']; $usr = unserialize($id); if ($usr) { $usr->secret = $flag1; if ($usr->name === "admin" && $usr->pass === $usr->secret) { echo "Congratulation! Here is something for you... " . $usr->pass; if (isset($_GET['caption'])) { $cap = $_GET['caption']; if (strlen($cap) > 45) { die("Naaaah, Take rest now"); } if (preg_match("/[A-Za-z0-9]+/", $cap)) { die("

数据结构 笔记--列表 循位置访问 C++ 语言版 邓俊辉老师

1 链表 列表 链表不是列表。我们所谈的列表更倾向于是针对对象而言的。 或许应该说列表是链表的扩展。他们的物理存储结构都不是连续的,而是依赖于节点指针指向的。所以链表里面的很多算法拿到列表对象上来说,都差不多。 2 向量 列表 向量在物理存储上地址是连续的。所以get()、size()这类静态方法效率高。但是insert()和remove()等动态操作需要线性时间。 列表则相反。

Log4j报错 ERROR StatusLogger No Log4j 2 configuration file found.

报错 java项目使用log4j2日志,配置好依赖的包之后,编译报错,报错信息如下: ERROR StatusLogger No Log4j 2 configuration file found. Using default configuration (logging only errors to the console), or user programmatically provided configurations. Set system property ‘log4j2.debug’ to show Log4j 2 internal initialization logging. See https://logging.apache.org/log4j/2.x/manual/configuration.html for instructions on how to configure Log4j 2 分析 从打印的报错信息,可知缺少配置文件。 解决 在src/main/resources目录下创建log4j2.xml配置文件即可。 样例配置文件如下: <?xml version="1.0" encoding="UTF-8"?> <Configuration status="error"> <Appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="%d %-5p (%F:%L) - %m%n" /> </Console> </Appenders> <Loggers> <logger name="

semget-获取System V信号量集标识符

头文件 #include <sys / types.h> #include <sys / ipc.h> #include <sys / sem.h> 函数 int semget(key_t key ,int nsems ,int semflg ); 关键标识符key:所创建或打开信号量集的键值, key 值可用fork()来创建。 nsems:创建的信号量集中的信号量的个数I(资源是三把伞, 但信号量的个数应设为1),该参数只在创建信号量集时有效。 semflg:调用函数的操作类型,也可用于设置信号量集的访问权限,两者通过or表示. 有IPC_CREAT,IPC_EXCL。 IPC_CREAT如果信号量不存在,则创建一个信号量,否则获取。 IPC_EXCL只有信号量不存在的时候,新的信号量才建立,否则就产生错误. 返回值 成功返回信号量的标识码ID。失败返回-1; 例子 mykey = ftok("key", 1000); if ((sem_id = semget(mykey, 1, IPC_CREAT | 0666)) == -1) { perror("semget failed"); exit(1); }

Ubuntu20.04无法连接wifi的解决方法

Ubuntu20.04无法连接wifi的解决方法 安装最新版的Ubuntu后,无法连接WiFi,解决方法如下: 1.通过有线的方式让电脑连上网,可以插网线或用手机网络,我一般都用手机,将手机与电脑通过数据线连接起来后,在手机上打开USB网络共享功能,“设置”——“个人热点”——“USB网络共享”; 2.终端执行:sudo apt update 3.终端执行:sudo apt-get install bcmwl-kernel-source 4.执行成功后,还显示有线连接,然后需要把有线连接关闭,无线连接才能成功。等一会儿后就会出现正常的WIFI信号标志。

C语言中int *p[n]和int (*p)[n]的区别

int *p[n] 分析: 分析这个问题要先从字符优先级开始,在字符优先级表中,[]的优先级大于*,所以,int *p[n] 就等价于int *(p[n]),这样就清晰多了,再进化一下就是 (int *)(p[n]) ,这样就完整了,显然,(int *)(p[n]) 就是一个数组,是一个以n个整型地址为元素,数组名为p的数组; 举个例子: #include <stdio.h> void main() { int a=1,b=2,c=3,d=4; int *p[4] = {&a,&b,&c,&d}; //1 printf("%d\n",&a); printf("%d\n",&b); printf("%d\n",&c); printf("%d\n",&d); //2 printf("\n"); printf("%d\n",p); printf("%d\n",p+1); printf("%d\n",p+2); printf("%d\n",p+3); //3 printf("\n"); printf("%d\n",*p); printf("%d\n",*(p+1)); printf("%d\n",*(p+2)); printf("%d\n",*(p+3)); //4 printf("\n"); printf("%d\n",**p); printf("%d\n",**(p+1)); printf("%d\n",**(p+2)); printf("%d\n",**(p+3)); } 运行结果: 由代码和运行结果可以看出来: 由1和2分析可知:编译器为整型变量a,b,c,d和数组p分别分配了不同的地址和空间;由1和3分析可知:数组p内的元素正是整型变量a,b,c,d的存储地址;由4分析可知:符号p不仅是数组名,还是一个二重指针,并且本身指向数组首元素(变量a的地址)的存储地址; 所以:int *p[n] 就是一个指针数组,数据类型为int *,元素为地址(变量地址,数组地址,函数地址等); int (*p)[n]分析: 规则同上,先从运算符优先级的角度来分析结构,()和[]具有相同的优先级,但是符号是从左向右,所以可以写成(int)(*p)[n]),数据类型为整型int ,数组内的元素也是整型量,可以默认为这个数组名为p,数组内有n个整型元素,根据数组的知识可知,*p就是数组首元素的地址,所以p在这里也是双重指针,这里可以将p认为是二重数组的数组名; 举个例子: #include <stdio.h> void main() { int a[][4] = {{1,2,3,4},{12,23,34,45},{1234,23456,34567}}; int (*p)[4] = a; /* 这句可以写成: int (*p)[4]; p = a; */ //1 printf("

Python怎么卸载不了?No Python 3.8 installation was detected.

目录 No Python 3.8 installation was detected.1.点击**修复**按钮2.修复中3.修复完成4.点击**卸载**按钮5.卸载中6.卸载完成7.删除在路径**C:\users\123\appdata\roaming\python\python38\site-packages**下安装的Python的库,以免影响新一次安装Python第三方库发生错误。 No Python 3.8 installation was detected. 当我们在卸载Python时,弹出”No Python 3.8 installation was detected.“对话框,可能是卸载程序已经损坏。可以通过先修复Python程序,然后再卸载程序,最后删除在路径C:\users\123\appdata\roaming\python\python38\site-packages下安装的Python的库,以免影响新一次安装Python第三方库发生错误。 1.点击修复按钮 2.修复中 3.修复完成 4.点击卸载按钮 5.卸载中 6.卸载完成 7.删除在路径C:\users\123\appdata\roaming\python\python38\site-packages下安装的Python的库,以免影响新一次安装Python第三方库发生错误。

老卫带你学---leetcode刷题(1096. 花括号展开 II)

1096. 花括号展开 II 问题: 如果你熟悉 Shell 编程,那么一定了解过花括号展开,它可以用来生成任意字符串。 花括号展开的表达式可以看作一个由 花括号、逗号 和 小写英文字母 组成的字符串,定义下面几条语法规则: 如果只给出单一的元素 x,那么表达式表示的字符串就只有 “x”。R(x) = {x} 例如,表达式 {“a”} 表示字符串 “a”。 而表达式 {“w”} 就表示字符串 “w”。 当两个或多个表达式并列,以逗号分隔时,我们取这些表达式中元素的并集。R({e_1,e_2,…}) = R(e_1) ∪ R(e_2) ∪ … 例如,表达式 “{a,b,c}” 表示字符串 “a”,“b”,“c”。 而表达式 “{{a,b},{b,c}}” 也可以表示字符串 “a”,“b”,“c”。 要是两个或多个表达式相接,中间没有隔开时,我们从这些表达式中各取一个元素依次连接形成字符串。R(e_1 + e_2) = {a + b for (a, b) in R(e_1) × R(e_2)} 例如,表达式 “{a,b}{c,d}” 表示字符串 “ac”,“ad”,“bc”,“bd”。 表达式之间允许嵌套,单一元素与表达式的连接也是允许的。 例如,表达式 “a{b,c,d}” 表示字符串 “ab”,“ac”,"ad"​​​​​​。 例如,表达式 “a{b,c}}{{d,e}f{g,h}” 可以表示字符串 “abdfg”, “abdfh”, “abefg”, “abefh”, “acdfg”, “acdfh”, “acefg”, “acefh”。

js隐式转换

js数据类型 基本类型(原始值):Undefined Null String Number Boolean Symbol引用类型(对象值):object (数组Array; 函数Function; 正则RegEXP; 日期Date) 来源 +:运算符既可以是数字相加,也可以是字符串相加==:==不同于===有多不同情况的隐式转换(以前我看一本书书尽量还是多用==,多拥抱js的隐式转换少用===,但是当我用了===,我就回不去了)- * / : 这一些运算符就比较友好了,他们只针对number类型,因而转化的结果只能转换成number类型 转化的方法 将值转为原始值,ToPrimitive() http://www.ecma-international.org/ecma-262/#sec-toprimitive 7.1.1 中有介绍 将值转为数字,ToNumber()将值转为字符串,ToString() 通过ToNumber将值转为数字 参数结果 undefined NaN unll +0 Boolean true转换为1; false转换为0 Number 无需转换 String 由js中的内置对象Number来处理 Object 1.先进行 ToPrimitive(obj, Number)转换得到原始值, 2.在进行ToNumber转换为数字 通过ToString将值转换为字符串 参数 结果 undefined 'undefined' // '1' + undefined = "1undefined" null 'null' Boolean 'true'或'false' Number数字转字符串 // (123).toString() => '123'String字符串无需转换Object 1.先进行 ToPrimitive(obj, String)转换得到原始值, 2.在进行ToString转换为字符串 通过ToPrimitive将值转换为原始值 ToPrimitive(input, PreferredType?) input:是要转换的值

请谈谈你对线程可见性及volatile关键字的理解?

请谈谈你对线程可见性及volatile关键字的理解? 文章目录 请谈谈你对线程可见性及volatile关键字的理解?引言可见性问题基本数据类型的可见性问题引用数据类型可见性问题引用可见性问题成员变量可见性问题 可见性问题总结 Java内存模型CPU与内存之间的爱恨情仇Java内存模型主存与工作内存间的交互规则Volatile变量特殊规则先行发生原则对先行发生原则的理解 volatile的使用保证变量可见性防止指令重排案例解决 引言 工作一段时间的老铁们对这个问题应该都不陌生吧。回想起刚毕业那会儿,我信心满满的拿着简历去面试,面试官问我“请谈谈你对线程可见性及volatile关键字的理解?” 我暗自欣喜,这个问题我可是已经背过好几遍了,于是自信的答道:“可见性是指一个线程所做的修改可以被其他线程观察到,volatile可以保证可见性,还可以防止指令重排序”。面试官可能被我流畅的回答惊呆了,于是愣了几秒钟后说让我回去等通知。回家的路上我回想了一下,觉得这次面试肯定稳了。但是不知道为什么至今那位面试官还没给我打电话。。。。 可见性问题 基本数据类型的可见性问题 public class Test { public static boolean flag = true; public static void main(String[] args) throws InterruptedException { // 启动一个线程,通过flag变量状态进行循环 new Thread(() -> { while (Test.flag) { // do something } }).start(); // 主线程休眠1秒后将flag变量设置为false Thread.sleep(1000); flag = false; System.out.println("主线程运行完毕"); } } 这段程序包含两个线程(一个是main方法所在的主线程、另一个暂时称之为子线程),我们大致能猜出来这段代码的意图是让子线程监测flag状态做点什么事情,然后再通过主线程将flag状态改变,从而停止子线程的工作。然而理想很现实。。。这段程序将会导致子线程进入死循环 引用数据类型可见性问题 引用可见性问题 public class Test { public static Son son ; public static void main(String[] args) throws InterruptedException { // 启动一个线程,监测son变量 new Thread(() -> { while(son==null){ // do something } }).

qt连接数据库

1、新建类 2、在db_connecton.h文件中添加以下代码 #ifndef DB_CONNECTION_H #define DB_CONNECTION_H #include<QMessageBox> #include<QSqlDatabase> #include <qdebug.h> #include <QSqlError> #include <QSqlQuery> #include "QSqlDatabase.h" //创建一个默认的连接,即只有一个连接 static bool createConnection() { QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL"); //数据库类型 db.setHostName("localhost"); //主机名 db.setDatabaseName("test"); //数据库名称 db.setUserName("root"); //用户名 db.setPassword("5oMacE9uQP%x"); //密码 if (!db.open()) { QMessageBox::critical(0, QString::fromLocal8Bit("错误"), QString::fromLocal8Bit("数据库连接失败"), QMessageBox::Cancel); return false; } db.open(); return true; } #endif // DB_CONNECTION_H 如果报错,就打开Qt project setting 选中sql 然后再运行,就可以了 3、在main中添加 如果没有弹出 在这里插入图片描述 那就是正常连接了 如果弹出连接失败,首先看下自己数据库打开了没;管理员身份运行cmd,输入net start mysql,打开数据库; 如果数据库已经打开,确定一下自己的账号密码有没有问题; 如果还是没问题那可能就是安装的时候没装好 可以看看之前的安装教程:点击 4、基本操作: (1)查询: //查询数据库中所有表的名称 QStringList tables = db.

Unity中c#为客户端,c++为服务器端进行socket通信

Unity中c#为客户端,c++为服务器端进行socket通信 1.需求 最近在项目中,要求将unity中虚拟相机的坐标变化等信息用socket传入c++写的处理程序中。相当于用C#写客户端,c++写服务器端。主要参考了一下博客:http://blog.csdn.net/qq_34204419/article/details/82529386 2.注意C#与C++数据类型的对应关系 数据类型不对应,编码方式不一致都可能导致传输结果为乱码。 大佬分别写了一个C#类和c++结构体进行对齐。 c#: [Serializable] //序列化对象 [StructLayout(LayoutKind.Sequential, Pack = 1)] // 按1字节对齐 public class UserMsg { public int messageID; public int clientID; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 200)] //限制200字节 public byte[] message; } c++: typedef struct { int messageID; int clientID; char message[200]; }UserMsg; 3.code 我对大佬代码进行了一点改变,符合我的需求。 Unity,c#,客户端 using System.Collections; using System.Collections.Generic; using UnityEngine; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; using System; using System.Runtime.InteropServices; [Serializable] [StructLayout(LayoutKind.Sequential,Pack=1)] public class UserMsg { //public int messageID; //public int clientID; [MarshalAs(UnmanagedType.

docker搭建proxySql+MHA的读写分离与故障切换的数据库集群

参考文章:https://blog.breezelin.cn/practice-mysql-mha-docker-compose.html 参考文章的git地址:https://github.com/breeze2/mysql-mha-docker/tree/2dcd29996a9ecade0eeda96434180c998368bdfa 我的部署文件:待补充 要搭建一主一备的mysql集群。 proxysql负责读写分离,MHA负责故障切换,如果不担心脑裂的风险,故障切换用keepalived更简单。 一、MHA的搭建 mha包含有mha_manager与mha_node,node部署在每个mysql的机器上。manager管理这些node,并在故障发生时,进行主从的切换。 1.镜像准备 可以自己制作镜像,也可以使用网上已有的镜像,我这里使用的是这两个: docker pull breeze2/mha4mysql-node:0.57 docker pull breeze2/mha4mysql-manager:0.57 2.docker-compose基础目录 准备一个docker-compose的基础目录,以后执行的命令均默认在此目录下 mkdir /home/docker/proxysql-MHA 再创建一个mha子目录,存放mha相关的配置文件与映射目录, 再创建一个scripts目录,存放mha启动相关的便捷脚本 mkdir /home/docker/proxysql-MHA/mha mkdir /home/docker/proxysql-MHA/scripts 3.编排docker-compose.yml文件 在目录/home/docker/proxysql-MHA下,创建文件docker-compose.yml,包含3个容器,一个主库、一个备库,以及一个管理节点。 version: "3" services: mha_master: image: breeze2/mha4mysql-node:0.57 container_name: mha_master restart: always networks: mhanet: ipv4_address: 10.5.0.10 ports: - "3307:3306" volumes: - "/etc/localtime:/etc/localtime:ro" - "./mha/mha_share/:/root/mha_share/" - "./mha/mha_master/data/:/var/lib/mysql/" - "./mha/mha_master/conf/:/etc/mysql/conf.d/" env_file: - ./parameters.env environment: - CONTAINER_NAME=mha_master mha_slave: image: breeze2/mha4mysql-node:0.57 container_name: mha_slave restart: always depends_on: - mha_master networks: mhanet: ipv4_address: 10.

Android APPbarlayout与SwipeRefreshLayout刷新滑动冲突解决

appbarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() { @Override public void onOffsetChanged(AppBarLayout appBarLayout, final int verticalOffset) { mSwipeRefreshLayout.setEnabled(verticalOffset >= 0);//页面滑动到顶部,才可以下拉刷新 } });

Java将JSON对象或JSON数组转list对象

public ResultJson validateInventury(@RequestBody String jsonObject) 第一种对象参数 {"inventoryDTOs":[{ "type": 0, "saleQuantity": 188.0000, "basePrice":1000.00, "salePrice": 3000.00, "inventoryId": 35 }, { "type": 0, "saleQuantity": 949.0000, "basePrice":200.00, "salePrice": 300.00, "inventoryId": 28 },{ "type": 1, "saleQuantity": 94.0000, "basePrice":200.00, "salePrice": 1000.00, "inventoryId": 326 } ]} <dependencies> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> </dependency> 转换: import com.alibaba.fastjson.JSONObject; JSONObject jsonObject = JSONObject.parseObject(jsonObject); String versionInfoStr = jsonObject.getString("inventoryDTOs"); // 数组 List<InventoryDTO> inventoryDTOs = JSON.parseArray(versionInfoStr, InventoryDTO.class); // 对象 InventoryDTO dto =JSON.parseObject(xx,InventoryDTO.class); ================================================================= =================================================================

easycode自定义模板

Easycode是idea的一个插件,可以直接对数据的表生成entity,controller,service,dao,mapper,无需任何编码,简单而强大。 安装教程搜索一下就行,官网自带的模板功能所有欠缺,自定义的一个模板。 注意: 1.增,批量增,删,改,单查,筛选查询 2.lombok实现,如果没有lombok自己更改文件或安装lombok 一、dao.java模板 ##定义初始变量 #set($tableName = $tool.append($tableInfo.name, "Dao")) ##设置回调 $!callback.setFileName($tool.append($tableName, ".java")) $!callback.setSavePath($tool.append($tableInfo.savePath, "/dao")) ##拿到主键 #if(!$tableInfo.pkColumn.isEmpty()) #set($pk = $tableInfo.pkColumn.get(0)) #end #if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}dao; import $!{tableInfo.savePackageName}.entity.$!{tableInfo.name}; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Mapper; import java.util.List; /** * $!{tableInfo.comment}($!{tableInfo.name})表数据库访问层 * @author shenning * @description * @since $!time.currTime() */ @Mapper public interface $!{tableName} { /** * 通过ID查询单条数据 * * @param $!pk.name 主键 * @return 实例对象 */ $!{tableInfo.name} queryById($!pk.shortType $!pk.name); /** * 通过实体作为筛选条件查询 * * @param $!

ElasticSearch: xpack 密码安全验证

背景 在阿里云部署了一台 ElasticSearch 节点,9200 端口直接暴露在了公网下,结果三天两头受到攻击,访问 kibana 老出现 redirect 重定向问题不能访问,查看日志索引都被人删除了,所以怀疑可能是因为被人恶意删除了,由此决定使用 xpack安全组件来保护 ElasticSearch。 ElasticSearch 默认安装后,本身不提供任何安全保障,这也是被人攻击的原因之一我们为了公网可以访问,配置了 server.host 为 0.0.0.0 这也是被人攻击的原因之一 xpack X-Pack 已经作为 Elastic 公司单独的产品线,集成了 Shield, Watcher, Marvel, Graph, 和 reporting 等安全组件,有着非常强大的功能。目前 xpack 已经默认被安装在了 7.0 以上的版本中,并且支持一些功能的免费使用,比如 用户登录权限校验等基础功能。 7.0 之上的版本默认安装了 xpack 组件,无需再次安装。 xpack内置的用户 用户角色elastic超级管理员apm_system为 apm 创建的用户kibana为kinana创建的用户logstash_system为logstash创建的用户beats_system为 beats 创建的用户kiremote_monitoring_userana为 monitoring 创建的用户 xpack默认内置了这些用户,在设置xpack的时候,需要为这些用户设置一个默认值。 启动参数 SettingDescriptionxpack.security.enabled设置为 false 可以关闭 X-Pack security 功能。需要在 elasticsearch.yml 。xpack.monitoring.enabled设置为 false 可以关闭 X-Pack monitoring 功能。 需要在elasticsearch.yml 。xpack.graph.enabled设置为 false 可以关闭 X-Pack graph 功能。 需要在elasticsearch.yml。xpack.watcher.enabled设置为 false 可以关闭 Watcher 功能。 只需要在 elasticsearch.

【ros学习】7.ros依赖安装问题总结

1.The following packages cannot be authenticated! WARNING: The following packages cannot be authenticated! ros-kinetic-dwa-local-planner E: There were unauthenticated packages and -y was used without --allow-unauthenticated ERROR: the following rosdeps failed to install apt: command [apt-get install -y ros-kinetic-dwa-local-planner] failed 警告:以下软件包无法通过身份验证! ros-kinetic-dwa-local-planner E:有未经身份验证的程序包,使用-y时没有–allow-unauthenticated 错误:以下rosdeps安装失败 apt:命令[apt-get install -y ros-kinetic-dwa-local-planner]失败 安装依赖他说没有身份验证,应该是说这个包可能不安全,不让你未经过安全验证自动安装,你可以再开一个命令行,遇到无法验证的依赖包就自己用root身份来安装,具体命令如下: sudo apt-get install dwa-local-planner

kafka:broker、client、spring-kafka版本间的关系

broker、client:(Kafka双向兼容) 在Kafka 0.10.2.0之前,Kafka服务器端和客户端版本之间的兼容性是“单向”的,即高版本的broker可以处理低版本client的请求。反过来,低版本的broker不能处理高版本client的请求。由于升级client要远比升级broker简单得多,因此这个限制给很多用户带来了麻烦,甚至有很多人都不愿意去升级broker版本——毕竟无downtime的情况下正确升级Kafka服务器是个不小的挑战。 自0.10.2.0版本开始,社区对这个问题进行了优化——对于低版本broker + 高版本client(0.10.2.0)的环境而言,现在用户可以运行命令先查看当前broker支持的协议版本,然后再选择broker支持的最高版本封装请求即可。命令格式如下(在client端运行该命令): 左边的图连接的是0.10.2.0版本的broker,可以看到该版本的Kafka服务器支持的FETCH请求版本范围是0到3,默认使用3;而右边的图连入的是0.10.0.1的Kafka,它只支持0~2版本的FETCH请求。因此你在编写客户端程序时需要根据这张表来确认broker支持的请求的最高版本,这样就间接实现了“低broker处理高client请求”的兼容性目标。 考虑到Java版本的client已经被广大用户直接使用了,社区也改写了Java clients底层的网络客户端代码,里面会自动地判断连接的broker端所支持client请求的最高版本,并自动创建合乎标准的请求。因此,对于FETCH请求和PRODUCE请求而言, 用户不用担心需要自己实现这些细节。 总之,自0.10.2.0之后用户可以简单地升级client端代码到这个版本就可以很容易地实现与低版本Kafka服务器的交互了。 broker、client的结论: 安装的kafka_2.11-2.4.1,版本为2.4.1,标准的要是用的client版本为: <dependency> <groupId>org.apache.kafka</groupId> <artifactId>kafka-clients</artifactId> <version>2.4.1</version> </dependency> 可以使用低版本的client去请求,比如使用 也可以选择broker支持的最高版本(这个还没有测试) client、spring-kafka: 比较新的kafka-clients可以与比较老的spring-kafka进行通信,比如: <!-- kafka交互式查询使用的数据库 --> <dependency> <groupId>org.springframework.kafka</groupId> <artifactId>spring-kafka</artifactId> <version>1.1.1.RELEASE</version> </dependency> <dependency> <groupId>org.apache.kafka</groupId> <artifactId>kafka-streams</artifactId> <version>2.2.0</version> </dependency> <dependency> <groupId>org.rocksdb</groupId> <artifactId>rocksdbjni</artifactId> <version>5.9.2</version> </dependency> <dependency> <groupId>org.apache.kafka</groupId> <artifactId>kafka-clients</artifactId> <version>2.2.0</version> </dependency> 备注:我这边安装的kafka_2.11-2.4.1,使用的是上面的配置与kafka进行通信

【动手学MVG】矩阵分解与线性方程组的关系,求解线性方程组实战代码

文章目录 本文解决的问题QR分解投影矩阵分解得到内外参 SVD分解最小二乘问题最小二乘问题的求解方法(列)满秩最小二乘问题正规化方法QR分解方法SVD 分解方法 亏秩最小二乘问题齐次最小二乘问题 数值稳定性问题Ax=0与Ax=b的选择代码实现利用SVD求解非齐次线性方程组Ax=b利用SVD求解齐次线性方程组Ax=0 附录——一些概念参考资料 在MVG(多视图几何)和机器学习领域,求解线性方程组几乎是所有算法的根本,本文旨在帮助读者搞懂矩阵分解与线性方程组的关系,并给出利用SVD求解线性方程组的实战代码。 本文解决的问题 看完本文后,应解决以下问题: 投影矩阵怎么通过QR分解得到相机内外参? 求解非齐次线性方程组Ax=b的方法有哪些? 其他一些方法通用性不大,比如克莱姆法则只用于方阵,这里不考虑。高斯消元法 | 常规方法。主要思路是讲矩阵通过初等行变换,转变为行阶矩形,然后后向代入(或者称为回代算法)可以很容易求解。 根据增系数矩阵A和广矩阵B = (A, b) 的秩可判断解的个数。对于齐次线性方程组Ax=0,用初等行变换将A变为行最简形矩阵A’,即可得到同解方程组A’x=0,然后计算对于非齐次线性方程组Ax=0,用初等行变换将增广矩阵B = (A, b)变为行最简形矩阵A’,即可得到同解方程组A’x=0,然后计算 方程Ax=b ,其中 A 为mxn。 当m >n时,对于这样的方程不能直接利用高斯或者其他的分解法进行求解 , 往往需要把方程转换为另外一种更容易求解的模式,也就是我们常常说的各种分解。当m<n时,有无穷解,高斯消元等常规方法能解,但是如果我们要求使得二范数最小的最小二乘解,还是需要用SVD分解。当m=n时,一般可以用高斯消元等方法解。但是如果秩小于n,此时有无穷解,如果我们要求使得二范数最小的最小二乘解,还是需要用SVD分解。 通过分解,将矩阵分解为特殊的形式,这些形式求逆或者对方程求解比较简单,比如上三角矩阵、下三角矩阵、对角矩阵、正交矩阵(求逆简单,就是其转职)。分解完后,方程可以转换为比较好求解的形式,用常规方法求解即可。常用方法有:LU分解、QR分解、Cholesky分解通过分解,求出矩阵广义逆矩阵 A + A^+ A+ ,则解为 x = A + b x = A^+b x=A+b 。常用方法:正规方程( x = ( A T A ) − 1 A T b x = (A^TA)^{-1}A^Tb x=(ATA)−1ATb)、SVD分解 总结: 参考:知呼 LU需要矩阵A可逆,Cholesky是其特殊情况,Cholesky分解的时间复杂度是 m n 2 + ( 1 / 3 ) n 3 mn^2+(1/3)n^3 mn2+(1/3)n3

67道 Python自动化面试题

1、自动化代码中,用到了哪些设计模式? 单例设计模式工厂模式PO设计模式数据驱动模式面向接口编程设计模式 2、什么是断言( Assert) ? 断言Assert用于在代码中验证实际结果是不是符合预期结果,如果测试用例执行失败会抛出异常并提供断言日志 3、什么是web自动化测试 Web自动化测试是从UI (用户界面)层面进行的自动化测试,测试人员通过编程自动化程序(测试用例脚本)来打开浏览器测试网站的业务逻辑。 4、什么是Selenium? Selenium是一个开源的web自动化测试框架,支持多种编程语言开发自动化测试脚本,支持跨浏览器平台进行测试 5、写出Selenium中你最熟悉的接口或类 WebDriver、InternetExplorerDriver、 FirefoxDriver、 ChromeDriver、 WebElement、WebDriverWait、 By 6、元素定位类型有哪些? By类一共有8种元素定位方式,它们都是静态方法: By.id():By.name():By.tagName():By.className():By.cssSelector():By linkText():By partialLinkText():By.xpath(): 7、Xpath是什么? 它是查找web页面元素的一种方式,相当于元素在dom中间的一个路径,可以采用绝对路径和相对路径的方式进行定位它对于定义动态的页面元素有很大的帮助,同时也需要谨慎使用,因为如果页面结构发生变化,那么定位信息也可能需要变化。 8、findElement()和findElements(方法有什么区别 两个都是查找页面元素的方法findElement():查找一个页面元素,只会返回一个WebElement对象findElements() :查找页面上所有符合匹配的元素,返回元素集合 9、登录按钮除了用click方法进行点击以外还有其他方式吗? 还可以使用submit()方法,前提是input元素的type为submit 10、怎么提高Selenium脚本的执行速度 优化等待时间:使用 WebDriverWait 智能等待来代替线程等待 sleep 和 隐式等待 implicityWait减少不必要的操作:如直接进入某页面代替经过一系列自动化操作进入某页面在服务器允许的情况下,使用多线程实现并发执行测试用例. 11、怎么对含有验证码的功能进行自动化测试的 :图像识别,技术难度大,效果不佳,不推荐 :屏蔽验证码,邀请开发处理,但在预生产环境或者生产环境不推荐 :万能验证码,使用一个复杂的其他人无法猜到的验证码 12、怎么验证复选按钮是不是被选中 可以使用元素的 isSelected() 方法,如果返回的是 true 则说明被选中,否则表明未被选中 13、如何处理alert弹窗? 处理 alert 弹窗首先需要先跳转到 alert 上,然后在点击确定或者取消按钮,Alert alert = driver.switchTo().alert(); //切换到alertalert.accept0; //确定alert.dismiss0; //取消 14、下拉菜单中如何去选择一个菜单项? 如果下拉菜单是select标签,使用方法: selectByValue() 或者 selectByIndex() 或者 selectByVisibleText() 即可如果这个下拉菜单不是通过 select 标签创建,则直接通过 xpath 定位元素然后去点击选择 15、如何模拟浏览器的前进和后退、刷新操作 driver.

给PostgreSQL添加MySQL的unix_timestamp与from_unixtime函数

MySQL的2个常用函数unix_timestamp()与from_unixtime PostgreSQL并不提供,但通过PostgreSQL强大的扩展性可以轻松的解决问题。 话说远在天边,尽在眼前,文档看仔细,问题迎仞解。PostgreSQL 题供extract与date_part取epoch即可 即 unix_timestamp() = round(date_part(’epoch’,now())) from_unixtime(int) = to_timestamp(int) 添加函数unix_timestamp() CREATE FUNCTION unix_timestamp() RETURNS integer AS S E L E C T ( d a t e p a r t ( ’ e p o c h ’ , n o w ( ) ) ) : : i n t e g e r ; SELECT (date_part(’epoch’,now()))::integer; SELECT(datep​art(’epoch’,now()))::integer; LANGUAGE SQL IMMUTABLE; 添加函数from_unixtime() CREATE FUNCTION from_unixtime(int) RETURNS timestamp AS KaTeX parse error: Can't use function '$' in math mode at position 22: …T to_timestamp($̲1)::timestamp; LANGUAGE SQL IMMUTABLE;

TP 面经

Longest Increasing Subsequence Medium 5310 115 Add to List Share Given an unsorted array of integers, find the length of longest increasing subsequence. Example: Input: [10,9,2,5,3,7,101,18] Output: 4 Explanation: The longest increasing subsequence is [2,3,7,101], therefore the length is 4. Note: There may be more than one LIS combination, it is only necessary for you to return the length. Your algorithm should run in O(n2) complexity. Follow up: Could you improve it to O(n log n) time complexity?

合并excel单元格的两种方法

文章目录 一、直接在excel文件上操作二、利用python库-openpyxl自动化合并单元格 工作中我们常常会用到excel单元格的合并,今天说一下合并常用的两种方法 下图是excel数据表(左)和合并单元格后的结果表(右)示例 接下来我们说一下excel单元格合并的方法,即将左表处理成右表形式 一、直接在excel文件上操作 1.wps点选 选择待合并区域,选择“开始” --> “合并居中” --> “合并相同单元格” 2.快捷方式 选择待合并区域,Alt、H、M、S 按顺序按相应的键,可定位到相应的位置,直到最后合并成功 二、利用python库-openpyxl自动化合并单元格 使用openpyxl库前,需先安装,安装方式可参考之前的文章 接下来说明如何使用openpyxl合并单元格 from openpyxl import load_workbook file = 'data.xlsx' wb = load_workbook(file) # 载入文件 # print(ws.sheetnames) # 查看换工作簿中所有的工作表名,数据类型为list ws = wb['Sheet1'] # 选定待合并单元格的工作表 ws.merge_cells('A2:A13') # 选定合并的单元格,待合并的单元格区域 以英文状态冒号连接 ws.merge_cells('A14:A27') # 选定合并的单元格 wb.save('data_new.xlsx') # 写出保存 注意:如果单元格合并为行间合并,合并后数据直接居中;如为列间合并,合并后数据需自定义居中。自定义居中设置方法如下: from openpyxl.styles import Alignment # 主要用于单元格对齐调整 ws['A2'].alignment = Alignment(horizontal='center', vertical='center') # A2为合并单元格中最左侧&首行单元格,此处选择的对齐方式是水平居中,垂直居中 ws['A14'].alignment = Alignment(horizontal='center', vertical='center')

ADC扫描模式理解

举例 用ADC1 规则通道的顺序为CH0,CH1,CH2,CH3 不启动SCAN模式 在单次转换模式下: 启动ADC1,则 1.开始转换CH0(ADC_SQR的第一通道) 2.转换完成后停止,等待ADC的下一次启动,继续从第一步开始转换 在连续转换模式下: 启动ADC1,则 1.开始转换CH0(ADC_SQR的第一通道) 2.转换完成后回到第一步。 启动SCAN模式下 在单次转换模式下: 启动ADC1,则 1.开始转换CH0、 2.转换完成后自动开始转换CH1 3.转换完成后自动开始转换CH2 4.转换完成后自动开始转换CH3 5.转换完成后停止,等待ADC的下一次启动下一次ADC启动后从第一步开始转换 在连续转换模式下: 启动ADC1,则 1.开始转换CH0、 2.转换完成后自动开始转换CH1 3.转换完成后自动开始转换CH2 4.转换完成后自动开始转换CH3 5.转换完成后返回第一步 开启扫描模式后 必须搭配DMA功能才能实现ADC的数据处理 ADC单通道: 要求进行一次ADC转换:配置为单次模式使能,扫描模式失能。这样ADC的这个通道,转换一次后,就停止转换。 要求进行连续ADC转换:配置为连续模式使能,扫描模式失能。这样ADC的这个通道,转换一次后,接着进行下一次转换,不断连续。 ADC多通道: 要求进行一次ADC转换:配置为单次模式使能,扫描模式使能。这样ADC的多个通道,按照配置的顺序依次转换一次后,就停止转换。 要求进行连续ADC转换:配置为连续模式使能,扫描模式使能。这样ADC的多个通道,按照配置的顺序依次转换一次后,接着进行下一次转换,不断连续。 因此,得出结论:扫描模式只在多通道的条件下有效,来使得各个通道按照配置循序依次转换。而单次模式无论在单通道还是多通道下只对这些或者这个通道进行一次转换,连续模式无论是在单通道还是多通道下都对这些或者这个通道不断进行连续的转换。

C++编程实例之翻转01串

问题描述: 给你一个长度为n的01串。现在想让你找出最长的01交替子串(子串可以不连续)比如:1010,0101是01交替的串,1101则不是。现在你可以把某一个连续的区间进行翻转,即0变1,1变0。问修改之后的最大01交替子串的长度是多少 问题分析: 看到题目后,不必使用暴力方法解决,可以从数学的角度出发,找规律。如果长度为n的原串中只有1个00(或11)出现,翻转后可以得到最长n位的交替序列;如果有多个00(或11)出现,统计相邻位不同的数count,可以得到最长count+2位的交替序列。也就是需要遍历字符串记录相邻两位不相同的位数,例如10100010,其中有6位和它的相邻位(前一位)不同,意味着有多个连续的00(或11),那么答案为6+2;例如10101001,翻转最后的01,答案为8,也就是n 代码如下: #include<iostream> #include<string> using namespace std; int main() { int count = 1; int n; cin>> n; string s; cin>> s; for(int i = 0; i < n - 1;i++) if(s[i]!= s[i + 1]) count++; if(count < n - 1) cout<< count + 2 << endl; else cout<< n << endl; return 0; }

RocketMQ系列:rocketmq运维控制台使用详解(全网独家)

搭建好了RocketMQ的console之后,直接在浏览器打开http://{你的ip}:8080 默认会进入到驾驶舱(dashboard)。 总览 整体横向菜单分为八个部分: 运维:主要是设置nameserver和配置vipchannel 驾驶舱:控制台的dashboard,可以分别按broker和主题来查看消息的数量和趋势。 集群:整个RocketMq的集群情况,包括分片,编号,地址,版本,消息生产和消息消费的TPS等,这个在做性能测试的时候可以作为数据指标。 主题:即topic,可以新增/更新topic;也看查看topic的信息,如状态,路由,消费者管理和发送消息等。 消费者:可以在当前broker中查看/新建消费者group,包括消费者信息和消费进度 生产者:可以在当前broker中查看生产组下的生产者group,包生产者信息和生产者状态 消息:可以按照topc,messageID,messageKey分别查询具体的消息 用户中心:切换语言和登陆相关(登陆需要在console的配置中打开对应配置,默认不需要登陆) 其中最常用的是集群,主题,消费者和消息这四部分。 下面分别来看各个部分。 运维 刚才讲到,运维这块儿就两个功能 设置Nameserver打开/关闭vipchannnel 设置nameserver:可以添加多个nameserver地址到输入框内,默认读取的是console启动配置里面的nameserver配置。如果rockermq集群里有加入新的nameserver节点,可以在这里动态配置后更新生效。 打开/关闭vipchannel: 这里默认为false就好,vipchannnel针对的是topic的优先级,相当于在消息处理的时候,有些topic可以走vipchannel,可以优先被处理,这个除了电商场景用的一般不多。 驾驶舱(Dashboard) 驾驶舱消息当前数量和最近的趋势,如图左侧为当前消息总数量,右侧为消息数量趋势。 我们分别解释如下四张图。 1)按broker实例为类目(比如说集群中有3个broker实例)展示当前的消息数 2)按topic为类目(比如说当前所有broker中存在10个topic)展示当前的消息数 3)指定某天和时间段,查询不同broker实例的消息数的趋势 4)指定某天和时间段,查询某topic下消息数的趋势 集群 集群主要展示了集群当前broker的状态,如下是各个字段含义: 分片:指的是数据分片(或者broker),当前rocketmq集群的只有一个数据分片,id为RaftNode00,即所有数据都在这个分片上;rocketmq的消息数据可以分布在多个数据分片上(一般都是多broker集群),后面搭建集群化环境的时候会讲到。 编号:标识了哪些是master(0是master),哪些是slave,master负责直接读写;slave相当于master的副本,定期从master同步数据,如果master挂掉,slave会自动内部选举一个master节点。 地址:即broker的实际ip端口。 版本:rocketmq的版本,这里是最新的4.7.1。 生产消息TPS:即broker中处理消息的TPS(每秒落盘的消息数)。 消费消息TPS:即consumer从broker中收取消息的TPS(每秒接收的消息数) 。 昨日生产总数:昨天落盘的总消息数。 昨日消费总数:昨天消费的总消息数。 今天生产总数:今天落盘的总消息数。 今天消费总数:今天消费的总消息数。 操作: 状态:当前broker中的消息处理和消费的一些属性值 配置:即启动broker时候broker.conf相关的配置项 主题 主题里面有三大类型 普通主题:这里是rocketmq自动创建的一些系统topic,然后用户创建的topic也展示在这里。 重试主题:这里是发送失败时候系统为之创建的topic。 死信主题:这里的topic类似垃圾箱,无法从中生产或者消费消息。 这里以BenchmarkTest为例介绍相关的操作(BenchmarkTest是rocketmq自带压测工具默认指定的topic): 状态 记录了topic中每个队列的起始位置(minOffset)和结束位置(maxOffset),通过累加所有队列的(maxOffset-minOffset)的差值,可以算出消息的总落盘数。 路由 最上面的broker:RaftNode00指的是分片,brokerAddrs指的是分片里的几个broker的地址信息,即该topic存在于这几个broker中。 下面比较有用的是perm,通过修改perm可以使当前broker分别置为只读,只写,和读写状态。当用于运维的时候可以将broker置为只读状态。 下面的队列信息是该topic的属性值。 Consumer管理 这里指的是Topic当前的Consumer的连接信息,没有消费者(consumer)则不显示订阅组。 TOPIC设置 设置topic的相关属性,一般读队列和写队列设置到16或者32就可以了。 发送消息 这里指的是给topic发送生产消息,消息包含msgid(系统自带),tag,key,body,其中tag和key可以用于后面筛选和查找消息。 重置消费点位 这里指的是从头开始消费消息,比如broker某topic有3w条消息,现在消费了2w条,还剩余1w条没有消费,下一条应该是从20001条开始消费;如果点击这个重置消费点位,下一条就会重新从第一条开始消费。 删除 删除本topic(貌似关联关系还在) 新增/更新topic 同topic设置类似 消费者 这里订阅组指的是使用rocketmq的客户端(比如java,cpp,go,python等)进行消费时候使用的group,多个consumer可以使用同一个group进行消费,也可以使用不同的group消费。

redis命令参考

当前命令集未注明统一参考版本 >= 1.x key 格式:DEL key [key …] 时间复杂度: 删N为O ( N ) ,删单个key,为O ( 1 ); 返回值: 受影响的数量 删除单个 key redis> SET name huangz OK redis> DEL name (integer) 1 删除一个不存在的 key redis> EXISTS phone (integer) 0 redis> DEL phone # 失败,没有 key 被删除 (integer) 0 同时删除多个 key redis> SET name "redis" OK redis> SET type "key-value store" OK redis> SET website "redis.com" OK redis> DEL name type website (integer) 3 keys 格式:keys pattern 查找所有符合给定模式 pattern 的 key 。

Guava Cache源码剖析

Guava Cache源码剖析 GuavaCache源码剖析之实现框架 CacheBuilder:类,缓存构建器。构建缓存的入口,指定缓存配置参数并初始化本地缓存。 CacheBuilder在build方法中,会把前面设置的参数,全部传递给LocalCache,它自己实际不参与 任何计算CacheLoader:抽象类。用于从数据源加载数据,定义load、reload、loadAll等操作Cache:接口,定义get、put、invalidate等操作,这里只有缓存增删改的操作,没有数据加载的 操作LoadingCache:接口,继承自Cache。定义get、getUnchecked、getAll等操作,这些操作都会 从数据源load数据LocalCache:类。整个guava cache的核心类,包含了guava cache的数据结构以及基本的缓存的 操作方法LocalManualCache:LocalCache内部静态类,实现Cache接口。其内部的增删改缓存操作全部调 用成员变量localCache(LocalCache类型)的相应方法LocalLoadingCache:LocalCache内部静态类,继承自LocalManualCache类,实现 LoadingCache接口。其所有操作也是调用成员变量localCache(LocalCache类型)的相应方法 LocalCache LoadingCache这些类表示获取Cache的方式,可以有多种方式,但是它们的方法最终调用到 LocalCache的方法,LocalCache是Guava Cache的核心类。 class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> LocalCache为Guava Cache的核心类 LocalCache的数据结构与ConcurrentHashMap很相似,都由多 个segment组成,且各segment相对独立,互不影响,所以能支持并行操作。 //Map的数组 final Segment<K, V>[] segments; //并发量,即segments数组的大小 final int concurrencyLevel; ... //访问后的过期时间,设置了expireAfterAccess就有 final long expireAfterAccessNanos; //写入后的过期时间,设置了expireAfterWrite就有 final long expireAfterWriteNa就有nos; //刷新时间,设置了refreshAfterWrite就有 final long refreshNanos; //removal的事件队列,缓存过期后先放到该队列 final Queue<RemovalNotification<K, V>> removalNotificationQueue; //设置的removalListener final RemovalListener<K, V> removalListener; ... 每个segment由一个table和若干队列组成。缓存数据存储在table中,其类型为 AtomicReferenceArray。 GuavaCache源码剖析之CacheBuilder 缓存构建器。构建缓存的入口,指定缓存配置参数并初始化本地缓存。 主要采用builder的模式,CacheBuilder的每一个方法都返回这个CacheBuilder知道build方法的调用。 注意build方法有重载,带有参数的为构建一个具有数据加载功能的缓存,不带参数的构建一个没有数

anaconda安装tensorflow2.0教程2020

** anaconda安装tensorflow2.0的教程 1.所用软件版本号: anaconda Navigator 1.9.7 tensorflow2.0.0版本安装 2.开始安装 可以先自行安装anaconda 安装完成之后打开Anaconda Prompt <1 更新conda命令行加快conda命令的速度 可以先自行安装anaconda 安装完成之后打开Anaconda Prompt 代码是: conda update -n base -c default conda <2创建tensorflow安装环境 代码是: conda create -n tensorflow(这儿可以改为自己的环境名称) python=3.7 参考论文:https://blog.csdn.net/SUSANLILI/article/details/102867956 python版本号自行选择合适的版本 建议使用命令行创建,这样可以看到运行到哪一步了,我没有更新conda命令就是卡在这一步,这样可以看看自己到底哪个文件安装不了 <3激活tensorfow环境可以在anaconda navigator中进行 打开anaconda navigator->environment中的自己的tensorflow环境 先点击一下tensorflow激活,然后按右边的运行符号选择open terminal 这样就进入了自己创建的tensorflow环境中 <4安装tensorflow 参考论文:https://www.jb51.net/article/180723.htm 进入环境之后使用,命令行 : pip install tensorflow==2.0.0(这里选择自己要下载的版本号) -i https://mirrors.aliyun.com/pypi/simple/ 源文件也可以自行选择 参考论文:https://zhuanlan.zhihu.com/p/122899658 推荐使用阿里云的镜像文件,下载速度快一点 安装完成之后还可以在当前命令行使用 python–进入python环境,然后 impot tensorflow tf.version 检查自己的版本是否正确安装。 <4下载完成 直接回到anaconda navigator–environment–tensorflow点击之后右上角选择uninstall中将ipython , pyder ,jupty勾选,点击appy 安装之后在你的启动栏就有两个spyder,使用spyder(tensorflow)就可以开始你的编程 道路了。 <5关于pycharm配置tensorflow (1)打开PyCharm,点击新建一个工程,然后出现如下界面:

QT 设置第二个界面并从第一个界面跳转到第二个界面

这里写目录标题 新建另一个界面跳转主窗口布局 新建另一个界面 在解决方案资源管理器,右键添加add class Qt 然后一直点下一步就完成了 跳转 从上一次登录界面的按钮,点击跳转 在第一个界面的头文件声明 有报错记得导入头文件 在cpp文件里写 运行 输入相同的密码和账户就可以了跳转页面了 主窗口布局 1、侧面导航栏 添加widget,给他一个背景色; 选择垂直布局 然后添加listWidget,双击他,添加新建项目 点击属性可以修改他各种属性 ,比如水平居中 添加其他组件,用spacer隔开 点击spacer修改属性 将sizeType改为Fixed,然后高度就可以自己调整了 修改样式: *{ color:rgb(255, 255, 255);//改变字体颜色 font: 9pt "Arial";//改变字体 border:none;//去边框 } QListView::item { height:50px;//改变每个选项的上下间距 } 需要添加其他的组件在widget,直接拖进去就好了 然后点击在窗体布局中布局 去掉边距 点击widget,拖到layout,对应的margin内边距改为0; 就可以啦 2、label显示图片 先固定好 然后定样式什么的 代码部分: 在要显示的界面的头文件声明绘画事件 .cpp文件里添加 void QtWidgetsClass::paintEvent(QPaintEvent*){ QImage photo; photo.load("C:/Users/HP/Desktop/timg.jpg"); QPixmap pixmap = QPixmap::fromImage(photo); int PicWidth = ui.label->width(); int PicHeight = ui.label->height(); ui.label->setScaledContents(true); QPixmap fitpixmap = pixmap.

Android图片九宫格控件,微信朋友圈;

注:本文是根据https://github.com/jeasonlzy/NineGridView进行扩展; 类似QQ空间,微信朋友圈,微博主页等,展示图片的九宫格控件; 原作者只有仿朋友圈样式和QQ空间样式,新增平铺样式; 源码在CcMall项目中:https://github.com/CuiChenbo/CcMall/tree/master/ninegridview 什么是平铺样式、效果图如下: 一张图、2或4张图 和多张图; 一张图:两张图: 四张图: 多张图: 效果就是一张图、2或4张图时也铺满屏幕;于是就对该开源框架进行了一下扩展,下面上代码; 一、新增平铺模式; 设置平铺模式的最大高度(也就是一张图时的高度); public static final int MODE_TILE = 2; //平铺网格模式 private int tileMaxHeight = 200; // 平铺模式最大高度 <declare-styleable name="NineGridView"> <attr name="ngv_singleImageSize" format="dimension"/> <attr name="ngv_singleImageRatio" format="float"/> <attr name="ngv_gridSpacing" format="dimension"/> <attr name="ngv_tileMaxHeight" format="dimension"/> <attr name="ngv_maxSize" format="integer"/> <attr name="ngv_mode" format="enum"> <enum name="fill" value="0"/> <enum name="grid" value="1"/> <enum name="tile" value="2"/> </attr> </declare-styleable> 二、设置平铺模式的控件大小 ; 2或4张时图片的高度是单张图片的0.7倍 , 多张图时高度时单张图片的0.5倍 , 当然这个是为了满足我这个项目的需求,这里也可以自定义(固定高度或宽高相等); @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // *** if (mImageInfo !

关于RabbitMQ的几道面试题

1、什么是RabbitMQ?为什么使用RabbitMQ,RabbitMQ好处? RabbitMQ是一款开源的,Erlang编写的,基于AMQP协议的,消息中间件; 可以用它来:解耦、异步、削峰。 好处就是:解耦、异步、削峰。 2、如何保证RabbitMQ不被重复消费? 先说为什么会重复消费:正常情况下,消费者在消费消息的时候,消费完毕后,会发送一个确认消息给消息队列,消息队列就知道该消息被消费了,就会将该消息从消息队列中删除; 但是因为网络传输等等故障,确认信息没有传送到消息队列,导致消息队列不知道自己已经消费过该消息了,再次将消息分发给其他的消费者。 3、如何保证RabbitMQ消息的顺序性? 单线程消费保证消息的顺序性;对消息进行编号,消费者处理消息是根据编号处理消息;

C语言实现维吉尼亚密码加密解密

为了生成密码,需要使用表格法。这一表格包括了26行字母表,每一行都由前一行向左偏移一位得到。具体使用哪一行字母表进行编译是基于密钥进行的,在过程中会不断地变换。 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <malloc.h> typedef struct Node { char data; Node* prior; Node* next; }*SLink; void init(SLink* l) { SLink t, q; *l = (SLink)malloc(sizeof(Node)); q = *l; q->data = 'A'; for (int i = 1; i < 26; i++) { t = (SLink)malloc(sizeof(Node)); t->data = 'A' + i; q->next = t; t->prior = q; q = t; } q->next = *l; (*l)->prior = q; } char encryption(char y,char m, SLink t) { while (t->data !

阻止android应用调用_如何在Android上设置应用时间限制和阻止应用

阻止android应用调用 Khamosh Pathak Khamosh Pathak Spending way too much time on your Android device? Use a digital wellbeing app to track your app usage and set app limits. Want some peace of mind? Block specific apps for a bit with Focus mode. 在您的Android设备上花费太多时间吗? 使用数字健康应用来跟踪您的应用使用情况并设置应用限制。 想要省心吗? 使用“焦点”模式稍微阻止特定的应用程序。 如何在Android 9及更高版本中设置应用计时器 (How to Set An App Timer in Android 9 and Higher) Digital Wellbeing is Google’s screen time management feature. It’s available on Google Pixel phones, Android One devices (that run Android 9 Pie and higher), and a limited number of other phones.

微服务架构讲解之开篇概述

由于微服务涉及的技术及相关框架、组件非常多,抽取其中任何一个东西都可以至少编成一大章节的内容,甚至可以编成一本书。本人没办法一下子全部讲解到位。为了让大家能更快第了解和掌握微服务,我将从这一篇开始逐步介绍微服务相关的东西。后面将会不断发布以“微服务架构讲解之”开头的微服务系列博文。当然,由于本人水平有限,错误疏漏之处欢迎大家斧正。 什么是微服务 简单地说,微服务架构就是把一个大的单体应用按业务边界拆分成一组微小的高内聚低耦合的服务组件,每个微服务组件单独运行,各组件之间通过HTTP这样的轻量级协议,按照REST风格(不限于)用JSON格式进行数据交换,相互协作。这些组件采用自动化部署机制,可以使用不用的语言开发,使用不同的技术进行数据存储。 微服务体现去中心化、天然分布式,是中台战略(中台并不是微服务,中台是一种企业治理思想和方法论,微服务是技术架构方式)落地到IT系统的具体实现方式的技术架构,用来解决企业业务快速发展与创新时面临的系统弹性可扩展、敏捷迭代、技术驱动业务创新等难题。 微服务架构具有以下特征: 应用程序逻辑分解为具有明确定义了职责范围的细粒度组件,这些组件互相协调提供解决方案。每个组件都有一个小的职责领域,并且完全独立部署。微服务应该对业务领域的单个部分负责。此外,一个微服务应该可以跨多个应用程序复用。微服务通信基于一些基本的原则,并采用HTTP和JSON这样的轻量级通信协议,在服务消费者和服务提供者之间进行数据交换。服务的底层采用什么技术并没有什么影响,因为应用程序始终使用技术中立的协议(JSON是最常见的)进行通信。这意味着构建在微服务之上的应用程序能够使用多种编程语言和技术进行构建。微服务利用其小、独立和分布式的性质,使组织拥有明确责任领域的小型开发团队。这些团队可能为同一个目标,如交付一个应用程序,但是每个团队只负责他们在做的服务。 【单体应用架构】 【微服务架构】 为什么要用微服务,有什么挑战 微服务架构的优点 每个微服务都很小,这样能聚焦一个指定的业务功能或业务需求。 微服务能够被小团队单独开发,这个小团队是2到5人的开发人员组成。微服务是松耦合的,是有功能意义的服务,无论是在开发阶段或部署阶段都是独立的。 微服务能使用不同的语言开发。微服务允许容易且灵活的方式集成自动部署,通过持续集成工具,如Jenkins, bamboo 。 一个团队的新成员能够更快投入生产。微服务易于被一个开发人员理解,修改和维护,这样小团队能够更关注自己的工作成果。无需通过合作才能体现价值。 微服务允许你利用融合最新技术。微服务只是业务逻辑的代码,不会和HTML,CSS 或其他界面组件混合。 微服务能够即时被要求扩展。 微服务能部署中低端配置的服务器上。易于和第三方集成。 每个微服务都有自己的存储能力,可以有自己的数据库。也可以有统一数据库。 微服务架构的挑战 以下挑战基本对应后面介绍的核心组件。 单个微服务代码量小,易修改和维护。但是,系统复杂度的总量是不变的,每个服务代码少了,但服务的个数肯定就多了。就跟拼图游戏一样,切的越碎,越难拼出整幅图。一个系统被拆分成零碎的微服务,最后要集成为一个完整的系统,其复杂度肯定比大块的功能集成要高很多。单个微服务数据独立,可独立部署和运行。虽然微服务本身是可以独立部署和运行的,但仍然避免不了业务上的你来我往,这就涉及到要对外通信,当微服务的数量达到一定量级的时候,如何提供一个高效的集群通信机制成为一个问题。单个微服务拥有自己的进程,进程本身就可以动态的启停,为无缝升级的打好了基础,但谁来启动和停止进程,什么时机,选择在哪台设备上做这件事情才是无缝升级的关键。这个能力并不是微服务本身提供的,而是需要背后强大的版本管理和部署能力。多个相同的微服务可以做负载均衡,提高性能和可靠性。正是因为相同微服务可以有多个不同实例,让服务按需动态伸缩成为可能,在高峰期可以启动更多的相同的微服务实例为更多用户服务,以此提高响应速度。同时这种机制也提供了高可靠性,在某个微服务故障后,其他相同的微服务可以接替其工作,对外表现为某个设备故障后业务不中断。同样的道理,微服务本身是不会去关心系统负载的,那么什么时候应该启动更多的微服务,多个微服务的流量应该如何调度和分发,这背后也有一套复杂的负载监控和均衡的系统在起作用。微服务可以独立部署和对外提供服务,微服务的业务上线和下线是动态的,当一个新的微服务上线时,用户是如何访问到这种新的服务?这就需要有一个统一的入口,新的服务可以动态的注册到这个入口上,用户每次访问时可以从这个入口拿到系统所有服务的访问地址。这个统一的系统入口并不是微服务本身的一部分,所以这种能力需要系统单独提供。还有一些企业级关注的系统问题,比如,安全策略如何集中管理?系统故障如何快速审计和跟踪到具体服务?整个系统状态如何监控?服务之间的依赖关系如何管理?等等这些问题都不是单个微服务考虑的范畴,而需要有一个系统性的考虑和设计,让每个微服务都能够按照系统性的要求和约束提供对应的安全性,可靠性,可维护性的能力。 微服务的设计原则 AKF分拆原则 详细参考:《scale cube(伸缩立方/扩展立方)学习 - 草稿》前端后端分离 前后端分离的原则,简单的来讲就是前端和后端代码的分离,我们推荐的模式是最好采用物理分离的办法部署,进一步促使更加彻底的分离,如果继续直接使用服务器端模板技术,如jsp把java,js,html,css都堆到一个页面中,稍微有点复杂一点的页面就没有办法维护了。 好处: 前后端技术分离,可以由各自的专家来对各自的领域进行优化,这样前端用户体验优化效果更好分离模式下,前后端交互界面更清晰,就剩下接口模型,后端的接口简介明了,更容易维护前端多渠道集成场景更容易实现,后端服务器无需变更,采用统一的数据和模型,可以支持多个前端,例如微信H5前端,PC前端,Android前端,IOS前端 无状态服务 一般说来,微服务架构的目的之一,是通过多进程承载高并发,根据并发的压力用多个副本共同承担流量。阻碍单体架构变为分布式架构的关键点就在于状态的处理——如果状态全部保存在本地,无论在内存还是硬盘,都会给架构的横向扩展带来瓶颈,因为这样新启动的进程根本无法处理那些保存在原来进程的用户的数据。所以要将整个架构分成无状态和有状态两个部分,业务逻辑的部分作为无状态的部分,很容易的横向扩展,在用户分发的时候,可以很容易分发到新的进程进行处理;状态保存在后端有状态的中间件中,如缓存、数据库、对象存储、大数据平台、消息队列等,这些中间件设计之初,就考虑了扩容时状态的迁移、复制、同步等机制,不用业务层关心。 参考:《微服务的无状态?》回答,https://www.zhihu.com/question/54437341?sort=created 4. RestFul风格 好处: 无状态协议HTTP,具备先天优势,扩展能力很强,例如需要安全加密,有现有的成熟解决方案HTTPS即可JSON报文序列化,轻量简单,人与机器均可读,学习成本低,搜索引擎友好语言无关,各大热门语言都提供了成熟的RestFul API 框架,相对其他的一些RPC框架生态更加完整。 核心组件 服务注册与发现 主要解决硬编码问题。 详细参考:「Chris Richardson 微服务系列」服务发现的可行方案以及实践案例 配置中心 主要解决分布式集群系统的配置问题。 详细参考:微服务分布式集群之配置中心,为什么要配置中心? 服务限流、降级、熔断 主要解决流量控制问题。 详细参考:服务降级、熔断、限流的区别 服务网关 Service Gateway,系统的入口,封装了应用程序的内部结构,为客户端提供统一服务,一些与业务本身功能无关的公共逻辑可以在这里实现,诸如认证、鉴权、监控、缓存、负载均衡、流量管控、路由转发等等 主要解决一下几个问题: 客户端多次请求不同的微服务,增加客户端的复杂性,认证复杂,每个服务都要进行认证;http请求增加,效率不高;存在跨域请求,比较复杂。 有如下几个优点: 减少客户端与微服务之间的调用次数,提高效率;便于监控,可在网关中监控数据,可以做统一切面任务处理;便于认证,只需要在网关进行认证即可,无需每个微服务都进行认证;降低客户端与服务端的耦合度。 参考:《微服务之服务网关》,https://www.jianshu.com/p/977b291e1247 分布式链路追踪 主要解决问题定位的问题。 详细参考:分布式链路追踪 负载均衡 实现微服务的高并发、高可用。 详细参考:微服务之负载均衡 统一认证与授权 解决多系统之间的统一身份管理、单点登录问题。

想学Swing,入门超详细!

先看第一部分完成的图 1.先做一个界面出来 public class JFrameDemo1 { public static void main(String args[]) { JFrame jf = new JFrame("第一个图形界面"); //加标题 jf.setTitle("第一个图形界面"); //默认坐标是0,0 左上角是原点 jf.setLocation(100, 100); //设置尺寸 jf.setSize(500, 500); //尺寸和坐标可以用一个方法来写 下面这句 //jf.setBounds(100, 100, 500, 500); //前两个是坐标 后两个是页面的大小 //修改窗体图标 //自己下载好图片文件复制到src目录底下,然后再复制到ImageIcon里 jf.setIconImage(new ImageIcon("Login.png").getImage()); //设置关闭窗口关闭虚拟机 jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //设置窗体可见 jf.setVisible(true); } } 2.做适合我们电脑屏幕的窗口(让它在屏幕正中显示) public class JFrameDemo2 { private static final int WIDTH=300;//窗口的宽 private static final int HEIGHT=300;//窗口的高 public static void main(String args[]) { JFrame jf = new JFrame("

python报错处理:AttributeError: ‘DataFrame‘ object has no attribute ‘map‘

当对DataFrame的一列做map或其他可对Series所做的操作时,如出现以下报错:AttributeError: ‘DataFrame’ object has no attribute 原因: 在map操作前,对DataFrame的列进行rename,导致python把两个同名列识别为DataFrame(实际应为Series) 解决办法: 1.rename后的字段与现有字段区分 2.rename前drop掉现有字段 可在rename前后加一个简单的小检验,确保rename后无重复字段 # 示例 import pandas as pd df = pd.DataFrame({'colA':[1,2,3],'colB':['1','2','3'],'colC':['1','2','3']}) ori_col = df.columns df = df.rename(columns={'colC':'colA'}) new_col = df.columns assert len(set(ori_col))==len(set(new_col)), 'rename前后字段数发生变化,请检查是否存在重名字段'

数据结构-单链表操作实践

数据结构-单链表操作实践 1. 编写函数,实现输入一组元素,建立一个带头结点的单链表 #include <iostream> #include <malloc.h> using namespace std; /** * 定义结点类型结构体,有一个data域和一个next域 */ typedef struct LNode { int data; struct LNode* next; }LNode, * LinkList; /** * 初始化,生成带有头结点的单链表 * @param L 引用类型,头指针 */ void InitLinkList(LinkList& L) { L = (LinkList)malloc(sizeof(LNode)); if (L) { //内存分配成功 L->next = NULL; } } /** * 尾插法建立单链表 * @param L 链表L * @param n 需要插入的元素的个数 */ void RailInsert_LinkList(LinkList& L, int n) { LNode* s, * r; //s用于指向新申请的节点空间,r用于始终指向尾结点 r = L; //r初始指向头结点 for (int i = 1; i <= n; ++i) { s = (LNode*)malloc(sizeof(LNode)); if (s) { cin >> s->data; /** * 尾插法的关键步骤 */ r->next = s; //直接让r的next指向新结点s r = s; //再让r重新指向当前的尾结点 } } r->next = NULL; //最后,将r的next置空 } /** * 按顺序输出单链表中元素的值 * @param L 单链表的头指针 */ void Print_LinkList(LinkList L) { LNode* p = L->next; while (p !

U盘量产工具-缩水盘恢复实际容量

2020年9月18日在PDD买了一个U盘,25块64G,今年已经是2020年,其实在Tmall29块已经可以买到64G了。 我想了想25块,应该不是骗人的吧!我还是太单纯了,收到一使用:缩水盘!! 好在店家客服态度还行,缩水盘白送,退钱,是个爽快人。 但是,这何苦呢?这种东西,随意拷贝几个文件就穿帮了呀,不被人投诉才奇怪了? 既然,是缩水盘,那就恢复U盘实际的容量吧: 首先,下载金山U盘卫士,检查是否是缩水盘: 第二,下载ChipGenius,找到主控型号(我这个是比较流行的FC1178) 第三,下载FC1178BC的量产工具。 重要提示:不要相信那些论坛,下载网站的下载,请直接到Club.liangchanba.com找到厂商对应的程序(量产吧现在要收费了??SB!那就到厂家去下载吧,FirstChip官网有最新最全的量产工具!!!) 我就是下载了4,5个地方的软件,量产过程都报错了或者不识别,最后终于在量产吧找到了FirstChip的最新版本,才量产成功的。 FirstChip中要修改的地方不多:主要就是修改以下Bin(改为U盘实际大小,产品设定(感觉不需要修改也可以) 出现上图,表示量产成功了,可以使用了。 最后,提醒大家一句,不要贪小便宜!不是每个卖家都像我遇到的这样好说话!

QT designer设置背景图片拉伸版

QT designer设置背景图片 首先设置背景图 (1)添加图片资源 在Qt designer中打开搜索style,打开styleSheet 复制图片相对地址,并删除里面所有内容: (2)设置背景图片 在你要设置背景图片的那个窗口的.hpp文件中声明 setbackground()是设置背景 resizeEvent()是改变窗口大小 打开对应的.CPP文件 添加代码如下:(demo01改成你自己的) void demo01::setBackground() { /* const QString filePath = QLatin1String(":/demo01/x64/Debug/bgPic.png"); QPixmap pixmap(filePath); QPalette palette = this->palette(); palette.setBrush(backgroundRole(), QBrush(pixmap.scaled(this->size()))); // pixmap.scaled(this->size()) 这里需要注意,它决定了背景是否可拉伸。 setPalette(palette); */ QPalette PAllbackground = this->palette(); QImage ImgAllbackground(":/demo01/x64/Debug/bgPic.png"); QImage fitimgpic = ImgAllbackground.scaled(this->width(), this->height(), Qt::IgnoreAspectRatio); PAllbackground.setBrush(QPalette::Window, QBrush(fitimgpic)); this->setPalette(PAllbackground); } void demo01::resizeEvent(QResizeEvent* event) { this->setBackground(); } 运行成功

ping的整个流程详解(icmp)

原文:ping好几年 ?今天终于把 ping 的原理搞懂了,打算图解教你!_小林coding-CSDN博客 原文的大佬一整个系列都写的非常优秀,转载只为了个人记录 文章目录 前言正文IP协议的助手 —— ICMP 协议查询报文类型差错报文类型网络不可达代码为 0主机不可达代码为 1协议不可达代码为 2端口不可达代码为 3需要进行分片但设置了不分片位代码为 4 ping —— 查询报文类型的使用traceroute —— 差错报文类型的使用 巨人的肩膀读者问答 前言 在日常生活或工作中,我们在判断与对方网络是否畅通,使用的最多的莫过于 ping 命令了。 “那你知道 ping 是如何工作的吗?” —— 来自小林的灵魂拷问 可能有的小伙伴奇怪的问:“我虽然不明白它的工作,但 ping 我也用的贼 6 啊!” 你用的是 6 ,但你在面试官面前,你就 6 不起来了,毕竟他们也爱问。 所以,我们要抱有「知其然,知其所以然」的态度,这样就能避免面试过程中,出门右拐的情况了。 不知道的小伙伴也没关系,今天我们就来搞定它,搞懂它。消除本次的问号,让问号少一点。 正文 IP协议的助手 —— ICMP 协议 ping 是基于 ICMP 协议工作的,所以要明白 ping 的工作,首先我们先来熟悉 ICMP 协议。 ICMP 是什么? ICMP 全称是 Internet Control Message Protocol,也就是互联网控制报文协议。 里面有个关键词 —— 控制,如何控制的呢? 网络包在复杂的网络传输环境里,常常会遇到各种问题。当遇到问题的时候,总不能死的不明不白,没头没脑的作风不是计算机网络的风格。所以需要传出消息,报告遇到了什么问题,这样才可以调整传输策略,以此来控制整个局面。 ICMP 功能都有啥?

java大文件(百M以上)的上传下载讨论

一、 功能性需求与非功能性需求 要求操作便利,一次选择多个文件和文件夹进行上传; 支持PC端全平台操作系统,Windows,Linux,Mac 支持文件和文件夹的批量下载,断点续传。刷新页面后继续传输。关闭浏览器后保留进度信息。 支持文件夹批量上传下载,服务器端保留文件夹层级结构,服务器端文件夹层级结构与本地相同。 支持大文件批量上传(20G)和下载,同时需要保证上传期间用户电脑不出现卡死等体验; 支持文件夹上传,文件夹中的文件数量达到1万个以上,且包含层级结构。 支持断点续传,关闭浏览器或刷新浏览器后仍然能够保留进度。 支持文件夹结构管理,支持新建文件夹,支持文件夹目录导航 交互友好,能够及时反馈上传的进度; 服务端的安全性,不因上传文件功能导致JVM内存溢出影响其他功能使用; 最大限度利用网络上行带宽,提高上传速度; 二、 设计分析 对于大文件的处理,无论是用户端还是服务端,如果一次性进行读取发送、接收都是不可取,很容易导致内存问题。所以对于大文件上传,采用切块分段上传 从上传的效率来看,利用多线程并发上传能够达到最大效率。 三、解决方案: 文件上传页面的前端可以选择使用一些比较好用的上传组件,例如百度的开源组件WebUploader,泽优软件的up6,这些组件基本能满足文件上传的一些日常所需功能,如异步上传文件,文件夹,拖拽式上传,黏贴上传,上传进度监控,文件缩略图,甚至是大文件断点续传,大文件秒传。 在web项目中上传文件夹现在已经成为了一个主流的需求。在OA,或者企业ERP系统中都有类似的需求。上传文件夹并且保留层级结构能够对用户行成很好的引导,用户使用起来也更方便。能够提供更高级的应用支撑。 文件夹数据表结构 CREATE TABLE IF NOT EXISTS `up6_folders` ( `f_id` char(32) NOT NULL , `f_nameLoc` varchar(255) default '', `f_pid` char(32) default '', `f_uid` int(11) default '0', `f_lenLoc` bigint(19) default '0', `f_sizeLoc` varchar(50) default '0', `f_pathLoc` varchar(255) default '', `f_pathSvr` varchar(255) default '', `f_pathRel` varchar(255) default '', `f_folders` int(11) default '0',

8种交叉验证类型的深入解释和可视化介绍

交叉验证(也称为“过采样”技术)是数据科学项目的基本要素。 它是一种重采样过程,用于评估机器学习模型并访问该模型对独立测试数据集的性能。 在本文中,您可以阅读以下大约8种不同的交叉验证技术,各有其优缺点: Leave p out cross-validationLeave one out cross-validationHoldout cross-validationRepeated random subsampling validationk-fold cross-validationStratified k-fold cross-validationTime Series cross-validationNested cross-validation 在介绍交叉验证技术之前,让我们知道为什么在数据科学项目中应使用交叉验证。 为什么交叉验证很重要? 我们经常将数据集随机分为训练数据和测试数据,以开发机器学习模型。 训练数据用于训练ML模型,同一模型在独立的测试数据上进行测试以评估模型的性能。 随着分裂随机状态的变化,模型的准确性也会发生变化,因此我们无法为模型获得固定的准确性。 测试数据应与训练数据无关,以免发生数据泄漏。 在使用训练数据开发ML模型的过程中,需要评估模型的性能。 这就是交叉验证数据的重要性。 数据需要分为: 训练数据:用于模型开发验证数据:用于验证相同模型的性能 简单来说,交叉验证使我们可以更好地利用我们的数据。 1.Leave p-out cross-validation LpOCV是一种详尽的交叉验证技术,涉及使用p观测作为验证数据,而其余数据则用于训练模型。 以所有方式重复此步骤,以在p个观察值的验证集和一个训练集上切割原始样本。 已推荐使用p = 2的LpOCV变体(称为休假配对交叉验证)作为估计二进制分类器ROC曲线下面积的几乎无偏的方法。 2. Leave-one-out cross-validation 留一法交叉验证(LOOCV)是一种详尽的穷尽验证技术。 在p = 1的情况下,它是LpOCV的类别。 对于具有n行的数据集,选择第1行进行验证,其余(n-1)行用于训练模型。对于下一个迭代,选择第2行进行验证,然后重置来训练模型。类似地,这个过程重复进行,直到n步或达到所需的操作次数。 以上两种交叉验证技术都是详尽交叉验证的类型。穷尽性交叉验证方法是交叉验证方法,以所有可能的方式学习和测试。他们有相同的优点和缺点讨论如下: 优点: 简单,易于理解和实施 缺点: 该模型可能会导致较低的偏差、所需的计算时间长 3.Holdout cross-validation 保留技术是一种详尽的交叉验证方法,该方法根据数据分析将数据集随机分为训练数据和测试数据。 在保留交叉验证的情况下,数据集被随机分为训练和验证数据。 通常,训练数据的分割不仅仅是测试数据。 训练数据用于推导模型,而验证数据用于评估模型的性能。 用于训练模型的数据越多,模型越好。 对于保留交叉验证方法,需要从训练中隔离大量数据。 优点:和以前一样,简单,易于理解和实施 缺点: 不适合不平衡数据集、许多数据与训练模型隔离 4. k-fold cross-validation 在k折交叉验证中,原始数据集被平均分为k个子部分或折叠。 从k折或组中,对于每次迭代,选择一组作为验证数据,其余(k-1)个组选择为训练数据。 该过程重复k次,直到将每个组视为验证并保留为训练数据为止。

opencv入门:矩特征,Hu矩

矩特征 比较两个轮廓最简单的方法是比较二者的轮廓矩,轮廓矩代表了一个轮廓,一副图像,一组点集的全局特征,矩信息包含了对应对象不同类型的集合特征,例如大小,位置,角度,形状等,矩特征广泛应用在模式识别,图像识别方面。 矩的计算:moments 函数 retval = cv2.moments( array[, binaryImage] ) 获取图像的 Moments特征,使用轮廓矩可以方便的比较两个轮廓 array 可以是点集 ,也可以是灰度图或二值图。当array 是点集时,函数会把这些点集当作轮廓中的顶点,将整个点集当作一条轮廓,而不是当作独立的点binaryImage True时,array 内所有非零值都处理为1,参数仅在array 是图像时有效。retval 返回的矩特征,主要包括 空间矩,零阶矩 m00 ,一阶矩:m10, m01,二阶矩:m20, m11, m02,三阶矩:m30, m21, m12, m03中心矩,二阶中心矩:mu20, mu11, mu02,三阶中心矩:mu30, mu21, mu12, mu03归一化中心矩,二阶 Hu 矩:nu20, nu11, nu02,三阶 Hu 矩:nu30, nu21, nu12, nu03 阿巴阿巴,,上面的啥矩 都是根据公式计算得到的,大多数矩都是通过数学公式得到的抽象特征,但是很明显,如果两个轮廓的矩一致,那么这两个轮廓就是一致的。m00 的含义就很直观,表示一个轮廓的面积。 cv2.moments 返回的特征值可以用来比较两个轮廓是否相似,例如 不管两个轮廓出现再那个位置,可以通过函数cv2.moments() 的m00 矩来判断面积是否一致。 当轮廓位置改变,虽然面积,周长等特征不会变,但是更高阶的特征会随位置而改变,中心矩通过减去均值而获取平移不变性,从而可以比较不同位置的两个对象是否一致。 归一化中心矩通过除以物体总尺寸而获得缩放不变性,通过计算提取对象的归一化中心矩属性值,该属性值不但拥有平移不变性,还有缩放不变性,也就从缩放前后的图像中提取稳定的特征值来比较轮廓。 再opencv 中cv2.moments() 会同时计算上述三种,,i了i了,Opencv就是为了让你忽略一些细节嘛,,, o = cv2.imread('16.jpg') cv2.imshow("original",o) gray = cv2.cvtColor(o,cv2.COLOR_BGR2GRAY) ret, binary = cv2.threshold(gray,127,255,cv2.THRESH_BINARY) # 转成二值图 contours, hierarchy = cv2.

【总结】Apache Curator入门使用

文章目录 一、Apache Curator简介二、Curator基本操作1. 重试策略2. 连接与关闭Zookeeper3. 创建节点4. 删除和更新节点5. 查询节点以及子节点6. 创建watcher 三、watcher统一配置修改 一、Apache Curator简介 解决了watcher的一次性的问题,注册一个watcher可以触发多次 Api简单易用 可以递归创建节点 提供ZooKeeper各种应用场景(recipe, 比如:分布式锁服务、集群领导选举、共享计数器、缓存机制、分布式队列等)的抽象封装 提供了常用的Zookeeper工具类 提供了一套Fluent风格的操作API 二、Curator基本操作 1. 重试策略 一共有五种重试策略 重试策略ExponentialBackoffRetry,重试N次限制总的重试时间 baseSleepTimeMs:两次重试之间的间隔时间maxRetries:最大重试次数,如果超过次数就放弃maxSleepMs:最大重试时间,如果超过该时间就放弃推荐的使用方式为:RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 5); 重试策略RetryNTimes,重试N次 n:重试的次数sleepMsBetweenRetries:两次重试之间的间隔时间推荐的使用方式为:RetryPolicy retryPolicy = new RetryNTimes(3, 5000); 重试策略RetryOneTime,重试一次 sleepMsBetweenRetry:两次重试之间的间隔时间不推荐使用 重试策略RetryForever,一直在重试 retryIntervalMs:两次重试之间的间隔时间不推荐使用 重试策略RetryUntilElapsed maxElapsedTimeMs:最大重试时间,重试时间超过maxElapsedTimeMs后,就不再重试sleepMsBetweenRetries:两次重试之间的间隔时间推荐使用方式为:RetryPolicy retryPolicy = new RetryUntilElapsed(2000, 3000); 2. 连接与关闭Zookeeper //1 重试策略:初试时间为1s 重试10次 RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 10); //2 通过工厂创建连接 CuratorFramework client = CuratorFrameworkFactory.builder() .connectString("192.168.1.110:2181")//连接地址 .connectionTimeoutMs(3_000)//连接超时时间 .sessionTimeoutMs(30_000)//会话超时时间 .retryPolicy(retryPolicy)//重试策略 .

k8s基础(12)之PV与PVC

k8s基础(12)之PV与PVC 在Kubernetes中,因为deployment默认使用的是hostpath,当我们pod重启或删除pod后数据会丢失。这时候我们就需要一个持久化存储来解决这个问题。 本次介绍的是kubernetes pv与pvc,同时使用nfs作为后端存储进行演示。 当然kubernetes pv 支持不同的volume,为了环境快速构建学习本次以NFS为主 首先我们来了解一下什么是PV和PVC PV的全称是: PersistentVolume (持久化卷),是对底层的共享存储的一种抽象,PV由管理员进行创建和配置,它和具体的底层的共享存储技术的实现方式有关,比如Ceph、GlusterFS、NFS等,都是通过插件机制完成与共享存储的对接 PVC的全称是: PersistenVolumeClaim (持久化卷声明),PVC是用户存储的一种声明,PVC和Pod比较类型,Pod是消耗节点,PVC消耗的是PV资源,Pod可以请求CPU的内存,而PVC可以请求特定的存储空间和访问模式。对于真正存储的用户不需要关心底层的存储实现细节,只需要直接使用PVC即可 但是通过PVC请求一定的存储空间也很有可能不足以满足对于存储设备的各种需求,而且不同的应用程序对于存储性能的要求也能也不尽相同,比如读写速度、并发性能等,为了解决这一问题,Kubernetes又为我们引入了一个新的资源对象: StorageClass,通过StorageClass的定义,管理员可以将存储资源定义为某种类型的资源,比如快速存储、慢速存储等,用户根据StorageClass的描述就可以非常直观的知道各种存储资源特性了,这样就可以根据应用的特性去申请合适的存储资源了 PV和PVC的生命周期 PV可以看作可用的存储资源,PVC则是对存储资源的需求,PV和PVC的互相关系遵循如下图 1.资源供应 (Provisioning) Kubernetes支持两种资源的供应模式:静态模式(Staic)和动态模式(Dynamic)。资源供应的结果就是创建好的PV。 静态模式:集群管理员手工创建许多PV,在定义PV时需要将后端存储的特性进行设置动态模式:集群管理员无须手工创建PV,而是通过StorageClass的设置对后端存储进行描述,标记为某种 “类型(Class)”。此时要求PVC对存储的类型进行声明,系统将自动完成PV的创建及PVC的绑定。PVC可以声明Class为””,说明该PVC禁止使用动态模式 2.资源绑定 (Binding) 在用户定义好PVC后,系统将根据PVC对存储资源的请求 (存储空间和访问模式)在已存在的PV中选择一个满足PVC要求的PV,一旦找到,就将该PV与用户定义的PVC进行绑定,然后用户的应用就可以使用这个PVC了。如果系统中没有满足PVC要求的PV,PVC则会无限期处于Pending状态,直到等到系统管理员创建了一个符合要求的PV。PV一旦绑定在某个PVC上,就被这个PVC独占,不能再与其他PVC进行绑定了。在这种情况下,当PVC申请的存储空间比PV的少时,整个PV的空间都能够为PVC所用,可能会造成资源的浪费。如果资源供应使用的是动态模式,则系统在PVC找到合适的StorageClass后,将会自动创建PV并完成PVC的绑定 3.资源使用 (Using) Pod 使用volume的定义,将PVC挂载到容器内的某个路径进行使用。volume的类型为persistentVoulumeClaim,在容器应用挂载了一个PVC后,就能被持续独占使用。不过,多个Pod可以挂载同一个PVC,应用程序需要考虑多个实例共同访问一块存储空间的问题 4.资源释放 (Releasing) 当用户对存储资源使用哪个完毕后,用户可以删除PVC,与该PVC绑定的PV将会被标记为已释放,但还不能立刻与其他PVC进行绑定。通过之前PVC写入的数据可能还留在存储设备上,只有在清除之后该PV才能继续使用 5.资源回收 (Reclaiming) 对于PV,管理员可以设定回收策略(Reclaim Policy)用于设置与之绑定的PVC释放资源之后,对于遗留数据如何处理。只有PV的存储空间完成回收,才能供新的PVC绑定和使用。 1.静态资源下,通过PV和PVC完成绑定,并供Pod使用的存储管理机制 2.动态资源下,通过StorageClass和PVC完成资源动态绑定 (系统自动生成PV,并供Pod使用的存储管理机制) 使用NFS进行演示 首先我们需要安装NFS服务 #这里我使用单独服务器进行演示,实际上顺便使用一台服务器安装nfs都可以 (建议和kubernetes集群分开,找单独一台机器) [root@nfs ~]# yum install nfs-utils -y rpcbind #接下来设置nfs存储目录 [root@nfs ~]# mkdir /data1/k8s-volume [root@nfs ~]# chmod 755 /data1/k8s-volume/ #编辑nfs配置文件 [root@nfs ~]# cat /etc/exports /data1/k8s-volume *(rw,no_root_squash,sync) #存储目录,*允许所有人连接,rw读写权限,sync文件同时写入硬盘及内存,no_root_squash 使用者root用户自动修改为普通用户 接下来启动rpcbind [root@nfs ~]# systemctl start rpcbind [root@nfs ~]# systemctl enable rpcbind [root@nfs ~]# systemctl status rpcbind ● rpcbind.

k8s基础(3)之RC

k8s基础(3)之RC、Replica Set RC介绍 Replication Controller (简称RC),RC是Kubernetes系统中的核心概念之一,简单来说,它定义了一个期望的场景,即声明某种Pod的副本数量在任意时刻都符合某个预期值 RC定义了如下 1.Pod期待的副本数(replicas) 2.用于筛选目标Pod的Label Seletcor(标签选择器) 3.当Pod的副本小于预期(replicas)时,用于创建新Pod的Pod模板(template) RC主要功能 确保Pod数量: 它会确保Kubernetes中有指定数量的Pod在运行,如果少于指定数量的Pod,RC就会创建新的,反之会删除多余的,保证Pod的副本数量不变确保Pod健康: 当Pod不健康,RC会杀死不健康的Pod,重新创建新的弹性伸缩: 在业务高峰或者低峰的时候,可以用RC来动态调整Pod数量来提供资源的利用率吧,当然也可以使用HPA来实现滚动升级: 滚动升级是一种平滑的升级方式,通过逐步替换的策略,保证整体系统的稳定性 RC例子演示 当我们定义了一个RC并提交到Kubernetes集群中以后,Master节点上的Controller Manager组件就得到通知,定期巡检系统中当前存活的目标Pod,并确保目标Pod实力的数量刚好等于此RC的期望值,如果有过多的Pod副本在运行,系统就会停掉一些Pod,否则系统就会再自动创建一些Pod。 可以说,通过RC,Kubernetes实现了用户应用集群的高可用性,并大大减少了传统IT需要手动的工作 --- apiVersion: v1 kind: ReplicationController metadata: name: rc-demo labels: app: rc spec: replicas: 3 <=========== 配置Pod数量 selector: app: rc template: metadata: labels: app: rc spec: containers: - name: nginx-demo image: nginx ports: - containerPort: 80 查看结果RC数量 [root@abcdocker yaml]# kubectl get rc NAME DESIRED CURRENT READY AGE rc-demo 3 3 3 5m19s DESIRED #rc设置的数量 CURRENT #已经创建的数量 READY #准备好的数量 查看Pod数量及状态