问题描述:JDK1.8编译时提示程序包com.sun.image.codec.jpeg不存在。
原因:由于jdk1.6以后jre中删除rt.jar,jce.jar,所以会出现以上问题。
解决办法:在pom文件中build下的plugins标签中添加如下内容
<plugin> <artifactId>maven-compiler-plugin</artifactId> <configuration> <encoding>UTF-8</encoding> <compilerArguments> <verbose /> <bootclasspath>${java.home}\lib\rt.jar${path.separator}${java.home}\lib\jce.jar${path.separator}</bootclasspath> </compilerArguments> </configuration> </plugin>
在 https://editor.csdn.net/md/?articleId=106170316中跟着github中的说明进行了初体验。但是发现并不是每个模块都会用到.
github说明 后端service准备 两个version的myapp备用,并配好对应的service ame: myappsvc Namespace: default Labels: <none> Annotations: Selector: app=myapp Type: ClusterIP IP: 10.96.66.66 Port: <unset> 80/TCP TargetPort: 80/TCP Endpoints: 10.244.2.215:80,10.244.2.216:80,10.244.2.217:80 + 2 more... Session Affinity: None Events: <none> Name: myappsvc2 Namespace: default Labels: <none> Annotations: Selector: app=myappsec Type: ClusterIP IP: 10.96.55.55 Port: <unset> 80/TCP TargetPort: 80/TCP Endpoints: 10.244.2.225:80,10.244.2.226:80,10.244.2.227:80 + 2 more... Session Affinity: None 部署ingress.yaml ingress.yaml 配置
[root@test ~]# cat ingress.yaml apiVersion: extensions/v1beta1 kind: Ingress metadata: name: ingressmyapp namespace: ingress-nginx spec: rules: - host: pphqq.
网络安全实验3 前言Kali 常用指令工具教程ettercap 基本使用 一、口令破解John the ripper 破解 linux 密码l0phtcrack7 破解 windows 密码John 破解 zip 压缩包的密码 二、ARP 欺骗、DNS 劫持arpspoof 实现 ARP 欺骗ettercap 进行 DNS 劫持ettercap 进行 ARP 欺骗HTTP&HTTPS账号密码获取 三、Python 编写 arpspoof环境准备ARP 报文结构编写代码测试脚本 四、SQL注入自己部署的网站环境准备:SQL 注入简单了解:开始实战SQL 注入的预防方法为什么预编译语句可以防SQL注入? VmVare 问题汇总桥接模式没有网 安全贴士如何知道自己是否被 ARP欺骗攻击了? 前言 本人深感网络安全实验有点麻烦,花了一个晚上弄了部分,特此将笔记贡献造福后人,个人能力有限,还会继续更新。。。
汇报题目:15分钟教你用 Python 写一个 arpspoof(课件准备ing,如果弄完后续补上)
第一次网络安全实验(密码学)也是我做的,这里先放个自制工具:Java实现密码学工具,集成了对称加密算法DES,AES,IDEA,公开加密算法RSA,ECC,散列算法MD5,SHA1,CRC32,以及RSA,DSA,ECDSA数字签名验证示例。,具体报告有时间上传一下。。
后续准备:将工具教程与实战模块分离。。。
Kali 常用指令 切换系统语言: sudo dpkg-reconfigure locales
获取 root 权限:sudo -s,输入密码
查看 ip 地址:ipconfig
查看网关地址:route -n
查找文件:lication xxx
放大命令行字体:ctrl + shift + +
可以使用HttpServletRequest获取客户端的请求参数,相关方法如下:
String getParameter(String name):通过指定名称获取参数值(已知参数名,单值参数的接收);String[] getParameterValues(String name):通过指定名称获取参数值数组,有可能一个名字对应多个值,例如表单中的多个复选框使用相同的name时;(已知参数名,多值参数的接收)Enumeration getParameterNames():获取所有参数的名字,获取到的是一个Enumeration的枚举类型;Map getParameterMap():获取所有参数对应的Map,其中key为参数名,value为参数值。 Enumeration取值
Enumeration<String> paraNames=request.getParameterNames(); for(Enumeration e=paraNames;e.hasMoreElements();){ String thisName=e.nextElement().toString(); String thisValue=request.getParameter(thisName); System.out.println(thisName+"--------------"+thisValue); } http请求中携带的各种参数的获取方法:
getProtocol():获取请求使用的通信协议,如http/1.1等 getServletPath():获取请求的JSP也面所在的目录。 getContentLength():获取HTTP请求的长度。 getMethod():获取表单提交信息的方式,如POST或者GET。 getHeader(String s):获取请求中头的值。一般来说,S参数可取的头名有accept,referrer、accept-language、content-type、accept-encoding、user-agent、host、cookie等,比如,S取值user-agent将获得用户的浏览器的版本号等信息。 getHeaderNames():获取头名字的一个枚举。 getHeaders(String s):获取头的全部值的一个枚举。 getRemoteAddr():获取客户的IP地址。 getRemoteHost():获取客户机的名称(如果获取不到,就获取IP地址)。 getServerName():获取服务器的名称。 getServePort():获取服务器的端口。 getPaeameterNames():获取表单提交的信息体部分中name参数值的一个枚举
最近看到公式就头疼,深深感受到数学不好就意味着被降维打击。。
在Deep Learning里,因为操作的对象是高维向量,所以很多paper里的公式都喜欢用矩阵乘来表达公式,这样的优点是公式表达更简洁(一个矩阵乘同时包含了乘法和加法),缺点就是菜的人可能一时半会反应不过来,比如说我!
假设有两个 n n n 维向量 x , y x,y x,y , x = ( x 1 , x 2 , . . . , x n ) , y = ( y 1 , y 2 , . . . , y n ) x=(x_1, x_2, ..., x _n), y=(y_1, y_2, ..., y _n) x=(x1,x2,...,xn),y=(y1,y2,...,yn)
欧式距离 欧式距离就是所谓的向量的二范式,论文里通常是这么写的 ℓ 2 ( x , y ) = ∥ x − y ∥ 2 \ell_{2}(\mathbf{x}, \mathbf{y})=\|\mathbf{x}-\mathbf{y}\|_{2} ℓ2(x,y)=∥x−y∥2,相比欧式距离,我感觉人们更喜欢用范式来表达(可能是因为范式更抽象?)
☀效果图
1、选择待加【下拉选项】的单元格,依次点击数据 - 数据有效性(小三角▼)- 数据有效性
2、在弹出框中【设置】栏【允许】下拉框中选择“序列”
3、在【来源】输入框中输入下拉选项,各个选项必须以[英文逗号,]隔开
例如本例中性别下拉选项为男、女,则来源输入框中输入的是【男,女】,然后点击确定即可。
4、回到刚才选择的单元格,单击单元格,会发现单元格右侧出现下拉选项▼
点击▼出现所设置的下拉选项
点击任一选项,单元格被选择的选项填充。
5、【信息提示模式】
有时候需要在单元格中只输入数字,但不同数字代表不同含义,就需要在选择的时候进行提示:
(1)回到第3步,在来源中输入序号1,2,3,4
(2)在【输入信息】栏的【输入信息】框里,输入提示信息,然后点击确定
(3)回到单元格,单击单元格,可看到除了之前的下拉选项▼,还有相应的提示,同样点击▼进行选项填充即可。
另外: 如果要对整列增加下拉选项:
(1)将鼠标移动至目标列列号处,待鼠标变成↓箭头时单击一下,此时选中全列
(2)然后像上述操作单个单元格步骤一样进行操作,完成后,所选中列的每个单元格都有下拉选项了。
(3)一般表头为标题,如果经过整列赋予下拉选项的又想去除表头那个单元格的下拉选项的话,可进行操作:
单击表头单元格 - 数据 - 数据有效性-数据有效性
在【设置】栏【允许下拉框】选择“任何值”,然后确定即可除去下拉选项属性。
1、adb install <package_name> —— 用于安装(在此程序的包的具体目录下面执行此命令,可以是电脑盘某个目录下,也可以是手机某个目录下)
2、adb uninstall <package_name> ——用于卸载
3、adb uninstall -k <package_name> —— 用于卸载;可选参数-k的作用为卸载软件但是保留配置和缓存文件
4、adb shell pm list packages ——查看系统所有应用的包名
5、adb shell pm list users —— 查询当前手机用户列表
6、adb shell pm list packages—— 查询系统所有apk安装包
7、adb shell pm list packages | findstr hwid —— 查询包含某几个字的包名 (注意windows里面是findstr;linux系统里面是grep)
8、adb shell pm path com.huawei.hwid —— 查询某个包的完整按照路径(需要知道完整包名)
9、adb shell pm clear 包名 —— 清除某个app缓存与数据
=====================================================================
1、adb install <package_name> —— 用于安装(在此程序的包的具体目录下面执行此命令,可以是电脑盘某个目录下,也可以是手机某个目录下)
安装成功,返回成功提示 "Success";
安装失败,会返回以下:INSTALL_FAILED_ALREADY_EXISTS——————此时需要用 -r 参数来重新安装。
目录 前言1. PyTorch 训练时在第一个 epoch 的最后一个 batch 卡死- 问题描述- 可能的原因- 解决方法 2. 使用命令行运行时,卡在第一个 epoch- 问题描述- 原因分析- 解决方法 前言 在实际训练中遇到了各种各样的卡住问题,在此总结一下,PyTorch 训练时遇到的卡住停住等问题可以从以下几个方面根据情况具体分析 (参考PyTorch训练时,Dataloader卡死、挂起,跑一个epoch停了,问题解决方案):
前一进程还未处理完,又进入下一个导致互锁:在每个Epoch后,或每个 batch 后暂停一下: time.sleep(0.003);内存问题:使用开关,pin_memory=True/False多进程导致互锁问题:减少进程数或者不用,num_workers=0/1OpenCV与Pytorch互锁;batch size 的设置; 1. PyTorch 训练时在第一个 epoch 的最后一个 batch 卡死 - 问题描述 使用 PyTorch 框架训练模型,训练第一个 epoch 时,在最后一个 batch 处卡死,卡了一天都没有动弹,而 CPU 和 GPU 都处于正常运行的状态,程序也没有报错,并且之前训练一直都是正常的。最终,只能通过 Ctrl+C 强制性暂停。如下图所示。
- 可能的原因 搜索文章发现,有人出现这种问题是和 cv2.imread 有关,用 OpenCV 的接口进行数据读取,而没有用 PIL,导致出现 OpenCV与Pytorch互锁的问题,关闭OpenCV的多线程即可解决问题1 2。但是我们的代码中并没有使用 OpenCV,通过 Debug 发现,出现问题的时候,最后一个 batch =1,而我们使用的是四块 GPU 进行训练,原因就在此。 - 解决方法 Pytorch 的多 GPU 处理接口是 torch.
1.(单选题)3线-8线译码器74138,当输入时,输出有效的是哪路信号
A. B. C. D. 您的答案: B
2.(单选题)用74161计数器实现十进制计数器,置数端的输入信号为?
A. B. C. D. 您的答案: A
3.(单选题)电路中74194的控制信号输入表达式为?
A. B. C. D. 您的答案: C
4.(单选题)本实验电路的控制对象是什么?
A. 步进电机。
B. 交流电机。
C. 伺服电机。
D. 直流电机。
您的答案: A
5.(单选题)本实验视频中设计电路用了那些集成芯片完成?
A. 74LS161,74LS138,74LS194, 74LS 190
B. 74LS151,74LS138,74LS175 ,74LS190
C. 74LS151,74LS138,74LS175 ,74LS194
D. 74LS151,74LS138,74LS194,74LS190
您的答案: xx
6.(单选题)74LS194的功能是什么?
A. 4选1选择器。
B. 4位计数器。
C. 4-2编码器。
D. 4位通用双向移位寄存器。
您的答案: D
7.(单选题)本实验视频中74LS161与74LS194的时钟频率一样吗?是否同一个时钟源?
A. 相同,同一个时钟源。
B. 不同,不同时钟源。
C. 相同,不同时钟源。
D. 不同,同一个时钟源
您的答案: D
CSS3选择器 基本选择器 子元素选择器
1、概念:只能选择某元素的子元素
2、语法格式:父元素>子元素 (father>children) – 只能是儿子,孙子辈以下都不可以
3、兼容性:Ie8+、firefox、chrome、opera、safari
相邻兄弟元素选择器 – 直接兄弟
1、概念:可以选择 紧接 在另一个元素后的元素,而且他们具有一个相同的父元素
2、语法:元素+兄弟相邻元素
3、兼容:ie8+ chrome safari opera Firefox
通用兄弟选择器
1、概念:某元素后面的所有兄弟,而且他们具有一个相同的父元素
2、语法:元素~后面所有兄弟元素
3、兼容:ie8+ chrome safari opera Firefox
群组选择器 ,
1、概念:具有相同样式的元素分组在一起,每一个选择器之间用逗号, 分隔开
2、语法:元素1,元素2,。。。。元素n
3、兼容:ie6+ chrome safari opera Firefox
属性选择器 1、概念:对带有指定属性的HTML元素设置样式,你可以指定元素的某个属性,或者你也可以同时同时指定属性名和属性值
2、语法:元素[属性attribute]
3、兼容:ie8+ chrome safari opera Firefox
元素[属性=“属性值”]
1、概念:属性名=属性值
2、兼容:ie8+ chrome safari opera Firefox
元素[属性~=“属性值”]
1、概念:属性名包含属性值(value值必须是一个独立的单词)的元素
2、兼容:ie8+ chrome safari opera Firefox
元素[属性^=“属性值”]
1、概念:属性名以属性值开头的所有的元素
2、兼容:ie8+ chrome safari opera Firefox
元素[属性$=“属性值”]
目录 1 定义1.1 描述1.2 语法格式 2 实战2.1 参数为空情况2.2 单个分隔符情况2.2.1 以空格作为分隔符2.2.2 以其他字符作为分隔符2.2.3 字符串首尾出现分隔符2.2.4 字符串中间出现分隔符2.2.5 指定分割次数 2.3 多个分隔符情况2.3.1 多个分隔符例子2.3.2 首尾、中间出现分隔符 3 拓展与strip()函数区别 4 附录 1 定义 1.1 描述 Python中split() 方法通过指定分隔符对字符串进行切片并返回一个列表。
1.2 语法格式 string.split(str="", num=string.count(str)) 参数说明:
1. str: 分隔符,默认为所有的空字符,
包括 空格、换行(\n)、水平制表符(\t)、 垂直制表符(\v)、 换页(\f)、回车(\r);(python中转义字符表看附)
2. num: 分割次数。默认为 -1, 即分隔所有。
如果参数 num 有指定值,则分隔 num+1 个子字符串
2 实战 2.1 参数为空情况 分隔符str 默认为所有的空字符,包括 空格、换行(\n)、水平制表符(\t)、 垂直制表符(\v)、 换页(\f)、回车(\r)。
(有些同志博客只提到了空格、换行\t、制表\t、实则还包括\v \f \r)
string = 'abcd efg\nopq\trst\vuvw x\fyz' print(string) print('======切分后=========') stringlist = string.
题目请戳:洛谷P1824 进击的奶牛
题目描述 Farmer John建造了一个有N(2<=N<=100,000)个隔间的牛棚,这些隔间分布在一条直线上,坐标是x1,…,xN (0<=xi<=1,000,000,000)。
他的C(2<=C<=N)头牛不满于隔间的位置分布,它们为牛棚里其他的牛的存在而愤怒。为了防止牛之间的互相打斗,Farmer John想把这些牛安置在指定的隔间,所有牛中相邻两头的最近距离越大越好。那么,这个最大的最近距离是多少呢?
输入格式 第1行:两个用空格隔开的数字N和C。
第2~N+1行:每行一个整数,表示每个隔间的坐标。
输出格式 输出只有一行,即相邻两头牛最大的最近距离。
输入输出样例 输入 5 3 1 2 8 4 9 输出 3 解题思路 首先牛棚的分布是x1,...,xN (0<=xi<=1,000,000,000), 1 0 10 10^{10} 1010 < 1 0 8 10^8 108 暴力肯定会TLE
那么我们如何减少时间复杂度呢。枚举每一种可行解是不大可行了。但是如果给出一个猜测解,去验证这个解是否可行就容易得多。也就是我们先在范围x1~xN内随便猜一个可能的间隔mid,然后验证如果每两头牛之间至少相邻mid个牛棚是否可行。
如果这个mid可行,则不用考虑比它小的解了(比mid小的解可能可行,但题目要求的是最大的可行mid)如果我们取的mid位于可行区间中点左右的位置,一下就排除了一半!!(雨巨:“是不是很快乐!!” ๑乛◡乛๑)
而如果当前猜测的mid不可行,则比它大的解也不用考虑了(因为一定不可行)
于是我们的思路从枚举寻找两头最近牛之间的最大距离,变成了给一个距离判断这个距离是否可行。
(好啦二分的思路讲完啦)
简单地说,就是每次取一个临近中点的点,判断这个点的值是否满足条件。是则取这个点的右半边继续上述过程。否则取这个点的左半边继续上述过程。
接下来上代码:
#include<iostream> #include<algorithm> #include<map> using namespace std; int n,a[100005],c; int check(int low, int high){ int dis; while(low <= high){ int cow = c - 1;//第一头牛已放入第一个隔间 dis = low + (high - low) / 2;//二分设定距离 这种写法防爆int if( dis == low ) break; //与low相等,说明该数据已经测试过可行且无法再找到更优解 int i = 0, flag = 1,tar; while(cow){ tar = a[i] + dis; if( a[n-1] < tar){ flag = 0; break; } while(a[i] < tar && i < n) //找到下一个满足距离的隔间 i++; cow--; } if(flag) //更新可行解的区间[low,high) low = dis; else high = dis; } return dis; } int main(){ cin>>n>>c; for(int i = 0; i < n; i++) cin>>a[i]; sort(a, a + n); cout<<check(1, a[n - 1] - a[0]); return 0; } 其实check和二分是可以分开的看起来清楚一些。我直接混在一起写了一个函数。
-----------grep命令-----------
说明:
grep命令是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹 配的行打印出来。grep全称是Global Regular Expression Print,表示全局正则表达式版本,它的使用权限是所有用户。
主要参数: -c:只输出匹配行的计数。 -I:不区分大 小写(只适用于单字符)。 -h:查询多文件时不显示文件名。 -l:查询多文件时只输出包含匹配字符的文件名。 -n:显示匹配行及 行号。 -s:不显示不存在或无匹配文本的错误信息。 -v:显示不包含匹配文本的所有行。 pattern正则表达式主要参数: \: 忽略正则表达式中特殊字符的原有含义。 ^:匹配正则表达式的开始行。 $: 匹配正则表达式的结束行。 \<:从匹配正则表达 式的行开始。 \>:到匹配正则表达式的行结束。 [ ]:单个字符,如[A]即A符合要求 。 [ - ]:范围,如[A-Z],即A、B、C一直到Z都符合要求 。 。:所有的单个字符。 * :有字符,长度可以为0。 1.例:
grep -c 'root' 1.txt #显示含有root的行的数量。 grep -n 'root' 1.txt #显示root匹配的行和行号。 grep -o 'root' 1.txt |wc -l #显示文本中含有root的个数。 grep -v 'root' 1.txt #显示不包含root的行。 grep -A2 -n 'root' 1.txt #显示包含root的行和行号,并显示其包含行下面的两行。 grep -B2 -n 'root' 1.
public class WebClientEx : WebClient { private CookieContainer cookie = new CookieContainer(); protected override WebRequest GetWebRequest(Uri address) { WebRequest request = base.GetWebRequest(address); if (request is HttpWebRequest) { (request as HttpWebRequest).CookieContainer = cookie; } return request; } } NameValueCollection postValues = new NameValueCollection(); postValues.Add("Email", info.username); postValues.Add("Pwd", info.userpwd); WebClientEx client = new WebClientEx(); client.Headers.Add("Content-Type", "application/x-www-form-urlencoded"); Encoding enc = Encoding.GetEncoding("UTF-8"); client.UploadValues(login, "POST", postValues); client.DownloadFile(file, path);
1、mAP介绍
mAP是mean Average
Precision的缩写,用于评价目标检测与分类的效果。AP是指一个类别的平均精度,它表示模型在某一个类别上的效果。mAP是所有类别AP的平均值,表示模型在所有类别上的整体效果。
2、精度和召回率
3、实例绘制PR图
假设我们的任务是“猫狗二分类”,下面来计算“猫”这一类别的AP。假设测试集共有8个样本(8张图片img1-img8),共预测出15只猫(15个预测框bbox1-bbox15)。
下表为按照置信度(预测分数)排序后的结果:
上表对应的PR图如下所示:
4、AP的计算方法
此处参考PASCAL VOC挑战赛的计算方法。有两种方法,分别是2010年之前的方法和2010年之后的方法。
2010年之前的方法:
第一步,事先设定一组阈值[0, 0.1, 0.2, … , 0.9, 1]。
第二步,recall值大于每一个阈值(如0.2)都可以得到一个最大precision,这样我们就得到了11个最大precision,AP就是这11个最大precision的平均值。
2010年之后的方法:
第一步,不事先设定阈值了,而是所有recall值都作为阈值,比如有M个正例就会有M个recall值即M个阈值(1/M, 2/M, …, M/M),本文中的例子将会有6个阈值[1/6, 2/6, 3/6, 4/6, 5/6, 6/6]。
第二步,recall值大于每一个阈值(如3/M)都可以得到一个最大precision,这样我们就得到了M个最大precision,AP就是这M个最大precision的平均值。
本文实例对应的计算参考下图:
相应的PR图,如下所示:
5、附matplotlib画图代码
用户画像 简介 用户画像,作为一种勾画目标用户、联系用户诉求与设计方向的有效工具,用户画像在各领域得到了广泛的应用。
用户画像最初是在电商领域得到应用的,在大数据时代背景下,用户信息充斥在网络中,将用户的每个具体信息抽象成标签,利用这些标签将用户形象具体化,从而为用户提供有针对性的服务。
还记得年底收到的支付宝年度消费账单吗?帮助客户回顾一年的消费细节,包括消费能力、消费去向、信用额度等等,再根据每位客户的消费习惯,量身定制商品推荐列表……这一活动,将数据这个量化的词以形象生动的表现手法推到了大众面前。
这就是用户画像在电商领域的一个应用,随着我国电子商务的高速发展,越来越多的人注意到数据信息对于电商市场的推动作用。基于数据分析的精准营销方式,可以最大限度的挖掘并留住潜在客户,数据统计与分析为电商市场带来的突破不可估量。在大数据时代,一切皆可“量化”,看似普通的小小数字背后,蕴藏着无限商机,也正在被越来越多的企业所洞悉。
如何从大数据中挖掘商机?建立用户画像和精准化分析是关键。
用户画像可以使产品的服务对象更加聚焦,更加的专注。在行业里,我们经常看到这样一种现象:做一个产品,期望目标用户能涵盖所有人,男人女人、老人小孩、专家小白、文青屌丝...... 通常这样的产品会走向消亡,因为每一个产品都是为特定目标群的共同标准而服务的,当目标群的基数越大,这个标准就越低。换言之, 如果这个产品是适合每一个人的,那么其实它是为最低的标准服务的,这样的产品要么毫无特色,要么过于简陋。
纵览成功的产品案例,他们服务的目标用户通常都非常清晰,特征明显,体现在产品上就是专注、极致,能解决核心问题。比如苹果的产品,一直都为有态度、追求品质、特立独行的人群服务,赢得了很好的用户口碑及市场份额。又比如豆瓣,专注文艺事业十多年,只为文艺青年服务,用户粘性非常高,文艺青年在这里能找到知音,找到归宿。所以,给特定群体提供专注的服务,远比给广泛人群提供低标准的服务更接近成功。 其次,用户画像可以在一定程度上避免产品设计人员草率的代表用户。代替用户发声是在产品设计中常出现的现象,产品设计人员经常不自觉的认为用户的期望跟他们是一致的,并且还总打着“为用户服务”的旗号。这样的后果往往是:我们精心设计的服务,用户并不买账,甚至觉得很糟糕。
在产品研发和营销过程中,确定目标用户是首要任务。不同类型的用户往往有不同甚至相冲突的需求,企业不可能做出一个满足所有用户的产品和营销。因此,通过大数据建立用户画像是必不可少的。
这只是用户画像在电商领域的应用,事实上用户画像已经不知不觉的渗透到了各个领域,在当前最火的抖音,直播等领域,推荐系统在大数据时代到来以后,用户的一切行为都是可以追溯分析的。
步骤 什么是用户画像?用户画像是根据市场研究和数据,创建的理想中客户虚构的表示。创建用户画像,这将有助于理解现实生活中的目标受众。企业创建的人物角色画像,具体到针对他们的目标和需求,并解决他们的问题,同时,这将帮助企业更加直观的转化客户。
用户画像最重要的一个步骤就是对用户标签化,我们要明确要分析用户的各种维度,才能确定如何对用户进行画像。
在建立用户画像上,有很多个步骤:
首先,基础数据收集,电商领域大致分为行为数据、内容偏好数据、交易数据,如浏览量、访问时长、家具偏好、回头率等等。而金融领域又有贷款信息,信用卡,各种征信信息等等。
然后,当我们对用户画像所需要的基础数据收集完毕后,需要对这些资料进行分析和加工,提炼关键要素,构建可视化模型。对收集到的数据进行行为建模,抽象出用户的标签。电商领域可能是把用户的基本属性、购买能力、行为特征、兴趣爱好、心理特征、社交网络大致的标签化,而金融风控领域则是更关注用户的基本信息,风险信息,财务信息等等。
随后,要利用大数据的整体架构对标签化的过程进行开发实现,对数据进行加工,将标签管理化。同时将标签计算的结果进行计算。这个过程中需要依靠Hive,Hbase等大数据技术,为了提高数据的实时性,还要用到Flink,Kafka等实时计算技术。
最后,也是最关键的一步,要将我们的计算结果,数据,接口等等,形成服务。比如,图表展示,可视化展示,
事实上,在构建用户画像过程中,注重提取数据的多元性而不是单一性,譬如针对不同类型的客户提取不同的数据,又或者针对线上线下的客户分析其中差异。总而言之,保证数据的丰富性、多样性、科学性,是建立精准用户画像的前提。
当用户画像基本成型后,接下来就可以对其进行形象化、精准化的分析。此时一般是针对群体的分析,如可以根据用户价值来细分出核心用户、评估某一群体的潜在价值空间,以此作出针对性的产品结构、经营策略、客户引导的调整。因此,突出研发和展示此类型的产品,又在家具的整体搭配展示中进行相关的主题设计,以此吸引目标人群的关注和购买。
毫无疑问,大数据在商业市场中的运用效果已经突显,在竞争激烈的各个行业,谁能抓住大数据带来的优势,谁才更有机会引领行业的未来。
实时用户画像 现在大数据应用比较火爆的领域,比如推荐系统在实践之初受技术所限,可能要一分钟,一小时,甚至更久对用户进行推荐,这远远不能满足需要,我们需要更快的完成对数据的处理,而不是进行离线的批处理。
现在企业对于数据的实时要求越来越高,已经不满足于T+1的方式,有些场景下不可能间隔一天才反馈出结果。特别是推荐,风控等领域,需要小时,分钟,甚至秒级别的实时数据响应。而且这种秒级别响应的不只是简单的数据流,而且经过与离线计算一样的,复杂的聚合分析之后的结果,这种难度其实非常大。
幸好实时计算框架的崛起足够我们解决这些问题,近年来Flink,Kafka等实时计算技术的框架与技术越来越稳定,足够我们支撑这些使用场景。
在实时用户画像的构建中,通过对实时数据的不断迭代计算,逐渐的不断完善出用户画像的全貌,这也正符合数据传输的本质,这整体架构中,淡化离线计算在之前特别重的作用,只留做归档和历史查询使用,更多的数据通过实时计算进行输出,最终达到对用户画像的目的。
在实时计算的过程需要对数据实时聚合计算,而复杂的标签也需要实时的进行机器学习,难度巨大,但是最终对于画像的实时性有着重大的意义。
本文介绍了用户画像的简介与实时用户画像的重要意义,但是用什么技术架构可以支撑这些想法的实现呢?
下一章,我们将探讨项目整体架构的设计与实现,未完待续~
参考文献
《用户画像:方法论与工程化解决方案》
更多实时数据分析相关博文与科技资讯,欢迎关注 “实时流式计算”
1.列表展开之前,如图:
2.列表展开之后,如图
3.某一项内容展开之后,如图
4.收起展开效果可绑定class,判断状态之后,选择特定的css样式;其中数据是循环出来,模拟动态数据;代码如下:
<template> <div class="analysisMajor-wrap"> <!-- 列表--> <div class="first-level-heading"> <div :class="[showAllCourseInfo?'':'min-height-flag']"> <div :class="[showAllCourseInfo?'unfold-height':'fold-height']"> <ul class="course"> <li class="first-head"> <p class="th1">列表1</p> <p class="th2">列表2</p> </li> <li v-for="(item,index) in courseDataList" :key="index" class="inner-text"> <div class="course-all"> <p class="course-name">{{ item.title }}</p> <p class="course-type"> <span>{{ item.type }}</span> <van-icon name="arrow-down" class="first-i" @click="showCourseInfoList($event)" /> </p> </div> <div v-for="(it,index) in item.courseDetails" :key="index" class="td-details"> <p> <span>内容1:</span> <span>{{ it.knowledgeNum }}</span> </p> <p> <span>内容1:</span> <span>{{ it.courseType }}</span> </p> <p class="claim-major"> <span>内容1:</span> <span>{{ it.
文章目录 1. 关系型数据库介绍1.1 数据结构模型1.2 RDBMS专业名词1.3 关系型数据库的常见组件1.4 SQL语句 2. mysql安装与配置2.1 mysql安装2.2 mysql配置 3. mysql的程序组成3.1 mysql工具使用3.2 服务器监听的两种socket地址 4. mysql数据库操作4.1 DDL操作4.1.1 数据库操作4.1.2 表操作4.1.3 用户操作4.1.4 查看命令SHOW4.1.5 获取帮助 4.2 DML操作4.2.1 INSERT语句4.2.2 SELECT语句4.2.3 update语句4.2.4 delete语句4.2.5 truncate语句 4.3 DCL操作4.3.1 创建授权grant4.3.2 查看授权4.3.3 取消授权REVOKE 5.4实例 1. 关系型数据库介绍 1.1 数据结构模型 数据结构模型主要有:
层次模型网状结构关系模型 关系模型:
二维关系:row,column
数据库管理系统:DBMS
关系:Relational,RDBMS
1.2 RDBMS专业名词 常见的关系型数据库管理系统:
MySQL:MySQL,MariaDB,Percona-ServerPostgreSQL:简称为pgsqlOracleMSSQL SQL:Structure Query Language,结构化查询语言
约束:constraint,向数据表提供的数据要遵守的限制
主键约束:一个或多个字段的组合,填入的数据必须能在本表中唯一标识本行。且必须提供数据,不能为空(NOT NULL)。
一个表只能存在一个惟一键约束:一个或多个字段的组合,填入的数据必须能在本表中唯一标识本行。允许为空(NULL)
一个表可以存在多个外键约束:一个表中的某字段可填入数据取决于另一个表的主键已有的数据检查性约束
索引:将表中的一个或多个字段中的数据复制一份另存,并且这些数据需要按特定次序排序存储 1.3 关系型数据库的常见组件 关系型数据库的常见组件有:
数据库:database表:table,由行(row)和列(column)组成索引:index视图:view用户:user权限:privilege存储过程:procedure存储函数:function触发器:trigger事件调度器:event scheduler 1.4 SQL语句 SQL语句有三种类型:
DDL:Data Defination Language,数据定义语言DML:Data Manipulation Language,数据操纵语言DCL:Data Control Language,数据控制语言 SQL语句类型对应操作DDLCREATE:创建
前端传到后端的json数据的key有大写字母开头,后端接收不到数据 前端json { "P": "3.1415926" } 后端接收参数对象 public class Path { /** 加上该注解可解决问题 */ @JsonProperty private String P; ...省略getter, setter方法 } 后端接口 public void test (@RequestBody Path path) { System.out.println(path.getP()); }
1、同一个服务器下复制文件或文件夹 1.1 复制文件 复制文件:把1.txt 复制到根目录下的sbin目录
cp +文件名(可带路径)+目标路径(带路径) 如:cp 1.txt ~/sbin/ 1,2 复制目录 复制目录:把release 复制到根目录下的nfs目录下
(1).【cp】 +【-r】+【目录名(可带路径)】+【目标路径(带路径)】 -r 表示复制目录下所有子目录以及文件
如:cp -r release ~/nfs/ (2).【cp】 +【目录名/*】+【目标路径(带路径)】 /*表示目录下所有文件和目录 *是通配符
如: cp release/* ~/nfs/ 2、 跨服务器拷贝文件或者文件夹 scp是secure copy的简写,用于在Linux下进行远程拷贝文件的命令,和它类似的命令有cp,不过cp只是在本机进行拷贝不能跨服务器,而且scp传输是加密的。当你服务器硬盘变为只读 read only system时,用scp可以帮你把文件移出来。
2.1 命令格式: scp [参数] [原路径] [目标路径] 2.2 使用说明 从本地服务器复制到远程服务器
2.2.1 复制文件: $scp local_file remote_username@remote_ip:remote_folder $scp local_file remote_username@remote_ip:remote_file $scp local_file remote_ip:remote_folder $scp local_file remote_ip:remote_file 指定了用户名,命令执行后需要输入用户密码;如果不指定用户名,命令执行后需要输入用户名和密码; 2.2.2 复制目录: $scp -r local_folder remote_username@remote_ip:remote_folder $scp -r local_folder remote_ip:remote_folder 第1个指定了用户名,命令执行后需要输入用户密码;第2个没有指定用户名,命令执行后需要输入用户名和密码;
复制粘贴其他请求中的userName和accessToken时发现请求到后台一致无参数,删除后重新录入后就好了
MySQL 1. MySQL的程序组成2. MySQL数据库操作2.1 DLL操作2.1.1 数据库操作2.1.2 表操作2.1.3 用户操作2.1.4 查看命令show2.1.5 获取帮助 2.2 DML操作2.2.1 INSERT语句2.2.2 SELECT语句2.2.3 update语句2.2.4 delete语句2.2.5 truncate语句 2.3 DCL操作2.3.1 创建授权grant2.3.2 查看授权2.3.3 取消授权REVOKE 2.4 Group By用法2.4.1 简单求和Group By2.4.2 Group By和Order By2.4.3 Group By与聚合函数2.4.4 Having与Where的区别 3.实例 1. MySQL的程序组成 mysql程序分客户端和服务器端两种:
客户端
mysql:CLI交互式客户端程序mysql_secure_installation:安全初始化mysqldump:mysql备份工具mysqladmin:执行管理操作,可以用来检查服务器的配置和当前状态、创建和删除数据库等 服务器端
mysqld:通过开启此程序,开启mysql mysql工具用法:
语法:mysql [OPTIONS] [databases]
常用的OPTIONS: -uUSERNAME 指定用户名,默认为root -hHOST 指定服务器主机,默认为localhost -pPASSWORD 指定用户的密码 -P# 指定数据监听的端口,#需用实际的端口号代替 -V 查看当前使用的mysql版本 -e 不登录mysql执行sql语句后退出 登录mysql:mysql -uroot -p123456 -h127.0.0.1 服务器监听的两种socket地址:
ip socket 默认监听在tcp3306端口,支持远程通信unix sock 监听在sock文件(/tmp/mysql.sock,/var/lib/mysql/mysql.sock)上,仅支持本地通信,server地址只能为localhost,127.0.01 2. MySQL数据库操作 2.
大数据——四种数据库(MySQL,HBase,MongoDB,Redis)操作实例 问题描述: Student学生表
1. 根据上面给出的表格,用Hbase Shell模式设计student学生表格。
a) 设计完后,用scan指令浏览表的相关信息,给出截图。
b) 查询zhangsan 的Computer成绩,给出截图。
c) 修改lisi的Math成绩,改为95,给出截图。
2. 根据上面已经设计出的student,用Hbase API编程。
a) 添加数据:English:45 Math:89 Computer:100
b) 获取scofield的English成绩信息
解决问题: 1. 根据上面给出的表格,用Hbase Shell模式设计student学生表格。 设计表代码:(复制粘贴代码时,要删除注释部分,下同)
$ ssh localhost //检测自己的ssh服务器设置
$ cd /usr/local/hadoop
$ ./sbin/start-dfs.sh //启动Hadoop
$ jps 注:用以查看hadoop是否启动成功
$ cd /usr/local/hbase
$ bin/start-hbase.sh //启动hbase
$ jps 注:用以查看hbase是否启动成功
$ bin/hbase shell //打开hbase的shell操作
hbase(main):006:0> create 'student','score' //创建student,其包含一个列族score
hbase(main):007:0> put 'student','zhangsan','score:English','69' //添加行健,列限定符和写入单元格数据
hbase(main):008:0> put 'student','zhangsan','score:Math','86'
hbase(main):009:0> put 'student','zhangsan','score:Computer','77'
hbase(main):010:0> put 'student','lisi','score:English','55'
//朴素 class Solution0 { public int maxArea(int[] nums) { int result = 0;//围成的面积 for (int i=0;i<nums.length-1;i++){//左指针遍历数组 for (int j=i+1;j<nums.length;j++){//右指针遍历数组 result = Math.max(result,(j-i)*Math.min(nums[i],nums[j]));//打擂法找最大值 } } return result; } } //朴素双指针 class Solution1 { public int maxArea(int[] a) { int result = 0,l=0,r=a.length-1;//面积,左指针,右指针 while(l<r){//左指针未遇到右指针 result=Math.max(result,(r-l)*Math.min(a[r],a[l]));//更新最大值 if (a[l]<a[r])//如果左边更短 l++;//移动左指针,期待找到个更长的 else//如果右边更短 r--;//移动右指针 } return result; } } //进阶双指针 class Solution { public int maxArea(int[] a) { int result=0,l=0,r=a.length-1;//面积,左指针,右指针 while(l<r){//左指针未遇到右指针 result=Math.max(result,(r-l)*Math.min(a[r],a[l]));//更新面积最大值 int l0=a[l],r0=a[r];//保存当前左右指针所对应的高度l0,r0 if(l0<r0)//如果左边短 while(a[l]<=l0&&l<r) l++;//左指针所对应的高度小于等于上面保存的值,左指针右移 else//如果右边短 while(a[r]<=r0&&l<r) r--;//右指针所对应的高度小于等于上面保存的值,右指针左移 } return result; } }
目录 导入数据对数据进行初步认识电极定位移除无用电极重参考重采样滤波分段和基线校正插值坏导ICA剔除ICA成分剔除坏段目视检查法保存数据 本分享为脑机学习者Rose整理发表于公众号:脑机接口社区 QQ交流群:941473018
感谢简书ID:亚内士多德 授权分享
EEG脑电数据预处理-操作篇
关于EEG数据预处理的原理,前面已经介绍过了,大家可以查看《手把手教你EEG脑电数据预处理-原理篇》。下面是亚内士多德分享的操作篇。
导入数据 选择要导入的数据格式
接下来会弹出一个对话框,是否要对数据进行选择性导入,一般都是全部导入,直接点OK即可。
接下来又会再弹出一个对话框,是否要对数据进行命名。基本上在EEGLAB的每一步操作之后都会弹出这样的对话框,询问你是否需要对新产生的数据进行命名,根据自己需要选择即可。
对数据进行初步认识 channel per frame:64 指导入的数据有64个通道
frames per epoch:一段数据的总长度,是439880采样点
epochs:指当前数据的段数,原始数据还没有进行分段,因此显示只有一段
events:检测到当前数据一共有202个events
sampling rate(HZ):数据的采样率为1000HZ
epoch start和epoch end: 这个的分段是从0秒开始,到439.879秒结束。还没有进行分段所以看这个数值没有意义
reference: 指数据的参考点,重参考后会显示重参考的电极点,或者average,目前还没有进行重参考所以是unknown
channel locations:是否有对通道进行定位,目前显示没有,定位后会显示为yes
ICA weights:是否对数据进行了ICA独立主成分分析,分析后会显示yes
dataset size:数据的大小
电极定位 默认文件是standard-10-5-cap385.elp,点击确定即可
点击OK之后可以进入下一步查看数据
如果检查到某个电极点的坐标信息为空白(如上图所示),可能是该通道的名称在加载的模板文件中找不到,那么
如果确定该通道是根据国际排布系统来确定的,那可以修改label名称后再点击下方的look up locs来更新通道位置信息,比如上图的VEO改为VEOG,然后更新位置信息之后就可以看到了
如果不是国际排布系统,可以向厂家要电极的坐标位置信息
如果知道该电极点的精确坐标,可以手动输入
双侧乳突的电极点位置可能会根据脑电系统的不同而不同,比如TP9 TP10,A1 A2, M1 M2这三对都是指双侧乳突
移除无用电极 此处我们要移除掉两个眼电数据
重参考 此处要将数据转换为双侧乳突平均参考,即TP9,TP10
重采样 不一定每个数据都需要进行重采样,可根据需要进行。
滤波 此处选择默认的滤波器进行0.1-30Hz的滤波
依次在第一框中填入0.1和第二个框中填入30进行计算,两个一起填代表进行带通滤波,建议分开进行
分段和基线校正 点击OK后会弹出下一个要求基线校正的对话框,默认是event前的数据作为基线来进行校正,点击OK即可。
插值坏导 对数据进行检查,如果发现某个通道的数据坏了,可以用插值的方式来进行校正,此处要校正的通道为FC3,选择插值的通道为它周围的四个电极点,F3,FC1,C3,FC5
第一种方法是代码操作
EEG.data(a,:,:) = mean(EEG.data([b c d],:,:)) ; 其中a代表坏掉的电极点数值,b c d 代表要进行插值平均的电极点数值
转载来源 :超实用的shell脚本–一键获取进程所有信息 :http://www.safebase.cn/article-257427-1.html
摘要: 概述有时我们想只是通过一个进程PID就可以输出该进程的相关信息,可以怎么处理呢?下面用shell脚本来实现这个需求。根据PID过滤进程所有信息#! /bin/bash# copyright by hwb# Function: 根据用户输入的PID,过滤出该PID所有的信息read -p "请输入要查询的PID: " Pn=`ps -aux| awk …
概述 有时我们想只是通过一个进程PID就可以输出该进程的相关信息,可以怎么处理呢?下面用shell脚本来实现这个需求。
根据PID过滤进程所有信息 #! /bin/bash # copyright by hwb # Function: 根据用户输入的PID,过滤出该PID所有的信息 read -p "请输入要查询的PID: " P n=`ps -aux| awk '$2~/^'$P'$/{print $11}'|wc -l` if [ $n -eq 0 ];then echo "该PID不存在!!" exit fi echo "--------------------------------" echo "进程PID: $P" echo "进程命令:`ps -aux| awk '$2~/^'$P'$/{print $11}'`" echo "进程所属用户: `ps -aux| awk '$2~/^'$P'$/{print $1}'`" echo "
STM32CubeMX->FreeRTOS+USART接收不定长数据 由于本人做的一个项目功能相对复杂,要求使用操作系统,且项目工程中有很多需要串口操作的外设,所以需要对串口设计不定长的收发功能,裸机跑惯了的孩子就是比较野,一天瞎吉尔弄,现在是不是GG,这里先批评一下自己。为了解决这一问题并做个笔记,就有了这篇博客。
实现思路:
使用串口、定时器记录接收到的数据,每5ms进入一次处理函数(一条数据处理完毕)
使用一个计数位、一个标志位、一个暂存buff
标志位置1则认为数据处理完成,将数据打印出来
使用硬件功能:串口3及中断,定时器7及中断
使用操作系统元素:一个互斥量
使能RTOS后会RTOS会强制调用系统时钟,所以在使能了操作系统之后需要将系统时钟换为定时器TIM1
操作步骤 启动STM32CubeMX并对芯片选型
主要设置
串口3及中断使能,115200,8,None,1定时器7及中断使能,预分频9000-1,自动重载50-1(时钟树APB1、2为90MHz)SYS时钟源设为定时器1使能FreeRTOS,创建1个串口任务、创建1个互斥量使能两个GPIO输出驱动LED
以上都清楚的大佬转到代码功能实现继续 使能RCC时钟源为外部时钟
3. 设置SYS调试方式为串口,时钟源改为定时器1
4. 设置时钟树,是APB1、2为90MHz,或者自行设定,在后面定时器工作会用到
5. 使能串口3,并启用串口3中断,串口3设置为115200,8Bit,None,1(不知道什么意思的就没有必要看下去了)
6. 使能定时器7,并使能中断,定时器预分频系数与之前的90MHz相关,需要通过预分频系数和自动重载值将定时时间设为5ms【200Hz】,不会算的看我定时器博客(这里我用了一个不常用的定时器,用哪个都可以,只要注意好定时器隶属哪根时钟线就行)
7. 使能FreeRTOS并创建一个串口任务和一个二值量(二值信号量用于串口数据接收完成后进入串口任务)
8. 设置两个IO输出作为一个可视化依据
9. 项目命名、选择使用的程序编辑软件我的是MDK_ARM V5、分离.c.h文件,点击右上角GENERATE CODE生成工程
打开项目,先编译没有错误之后再进行修改 代码功能实现 首先在usart.c文件对串口3进行printf函数重定义,使串口3可用printf函数输出
内容加入到/* USER CODE BEGIN 0 */框架内
/* USER CODE BEGIN 0 */ /********************************************************************************/ #include "stdio.h" //加入以下代码,支持printf函数,而不需要选择use MicroLIB //#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) #if 1 #pragma import(__use_no_semihosting) //标准库需要的支持函数 struct __FILE { int handle; }; FILE __stdout; //定义_sys_exit()以避免使用半主机模式 void _sys_exit(int x) { x = x; } //重定义fputc函数 int fputc(int ch, FILE *f) { while((USART3->SR&0X40)==0);//循环发送,直到发送完毕 USART3->DR = (uint8_t) ch; return ch; } #endif /********************************************************************************/ /* USER CODE END 0 */ 定义串口使用的变量
1、初始化是设置emptyText参数。
constructor(props){
super(props);
this.state = {
emptyText:"暂无数据"
}
}
2、table里设置 locale={this.state.emptyText}。
<Table locale={{emptyText: this.state.emptyText}} columns={this.getColumns()} dataSource={this.getData()} />
3、获取数据时,可以按照不同返回值显示不同的中文内容,那就可以在getData里设置emptyText显示的内容。
何为format format是python2.6新增的一个格式化字符串的方法,相对与旧版的%它有很多优点
format的优点 1.不需要理会数据类型的问题,在%方法中%s只能替代字符串类型
2.单个参数可以多次输出,参数顺序可以不相同
3.填充方式十分灵活,对齐方式十分强大
4.官方推荐用的方式,%方式将会在后面的版本被淘汰
format的使用 基本 填充
(1)顺序填充
与%类似,通过{ }占位然后顺序填充
print("Hello,My name is {}, and i am from {}.".format("Yz","China")) Output: Hello,My name is Yz, and i am from China. (2)下标填充
我们在{ }中填充逻辑顺序来对应之后format中的字符串
print("Hello,My name is {1}, and i am from {0}.".format("China","Yz")) Output: Hello,My name is Yz, and i am from China. 值得注意的是:在此种填充中,必须在每个{ }都标上序号,包括下面将会看到的在填充空白字段那里,如果使用了下标,则必须全部标上,即要标全标,要不标都不标,否则会报错
错误示范:
print("Hello,My name is {1}, and i am from {}.".format("China","Yz"))#第一个空标了,但第2个空未标 Output: Traceback (most recent call last): File "
文章目录 1. ftp简介2. ftp架构3. ftp数据连接模式4. 用户认证5. vsftpd5.1 vsftpd安装5.2 vsftpd配置5.3 vsftpd匿名用户配置5.4 vsftpd虚拟用户配置5.5 vsftpd系统用户配置 1. ftp简介 网络文件共享服务主流的主要有三种,分别是ftp、nfs、samba。
FTP是File Transfer Protocol(文件传输协议)的简称,用于internet上的控制文件的双向传输。
FTP也是一个应用程序,基于不同的操作系统有不同的FTP应用程序,而所有这些应用程序都遵守同一种协议以传输文件。
在FTP的使用当中,用户经常遇到两种概念:下载和上传
下载(Download)上传(Upload)从远程主机拷贝文件至自己的计算机上将文件从自己的计算机上拷贝至远程主机上 2. ftp架构 FTP工作于应用层,监听于tcp的21号端口,是一种C/S架构的应用程序。其有多种客户端和服务端的应用程序,下面来简单介绍一下
客户端工具服务端软件ftp
lftp,lftpget
wget,curl
filezilla
gftp(Linux GUI)
商业软件
(flashfxp,cuteftp)wu-ftpd
proftpd(提供web接口的一种ftp服务端程序)
pureftp
vsftpd(Very Secure)
ServU(windows平台的一种强大ftp服务端程序) 3. ftp数据连接模式 ftp有2种数据连接模式:命令连接和数据连接
命令连接:是指文件管理类命令,始终在线的持久性连接,直到用户退出登录为止数据连接:是指数据传输,按需创建及关闭的连接
其中数据连接需要关注的有2点,一是数据传输格式,二是数据传输模式 数据传输格式有以下两种:
文件传输二进制传输 数据传输模式也有2种:
主动模式:由服务器端创建数据连接被动模式:由客户端创建数据连接 两种数据传输模式的建立过程:
传输模式建立过程主动模式命令连接:
Client(1025)–> Server(21)
客户端以一个随机端口(大于1023)来连服务器端的21号端口
数据连接:
Server(20/tcp) --> Client(1025+1)
服务器端以自己的20号端口去连客户端创建命令连接时使用的随机端口+1的端口号被动模式命令连接:
Client(1110) --> Server(21)
客户端以一个随机端口来连成服务器端的21号端口
数据连接:
Client(1110+1) --> Server(随机端口)
客户端以创建命令连接的端口+1的端口号去连服务器端通过命令连接告知自己的一个随机端口号来创建数据连接 主动模式有个弊端,因为客户端的端口是随机的,客户端如果开了防火墙,
则服务器端去连客户端创建数据连接时可能会被拒绝
4. 用户认证 ftp的用户主要有三种:
1024G 嵌入式资源大放送!包括但不限于C/C++、单片机、Linux等。关注微信公众号【嵌入式大杂烩】,回复1024,即可免费获取!
常规打印方法 在STM32的应用中,我们常常对printf进行重定向的方式来把打印信息printf到我们的串口助手。
在MDK环境中,我们常常使用MicroLIB+fputc的方式实现串口打印功能,即:
要实现fputc函数的原因是:printf函数依赖于fputc函数,重新实现fputc内部从串口发送数据即可间接地实现printf打印输出数据到串口。
不知道大家有没有看过正点原子裸机串口相关的例程,他们的串口例程里不使用MicroLIB,而是使用标准库+fputc的方式。相关代码如:
#if 1 #pragma import(__use_no_semihosting) //标准库需要的支持函数 struct __FILE { int handle; }; FILE __stdout; /** * @brief 定义_sys_exit()以避免使用半主机模式 * @param void * @return void */ void _sys_exit(int x) { x = x; } int fputc(int ch, FILE *f) { while((USART1->ISR & 0X40) == 0); //循环发送,直到发送完毕 USART1->TDR = (u8) ch; return ch; } #endif 关于这两种方法的一些说明可以查看Mculover666兄的《重定向printf函数到串口输出的多种方法》这篇文章。这篇文章中不仅包含上面的两种方法,而且也包含着在GCC中使用标准库重定向printf的方法。
自己实现一个打印函数 以上的几种方法基本上是改造C库的printf函数来实现串口打印的功能。其实我们也可以自己实现一个串口打印的功能。
printf本身就是一个变参函数,其原型为:
int printf (const char *__format, ...); 所以,我们要重新封装的一个串口打印函数自然也应该是一个变参函数。具体实现如下:
t-SNE可视化图像特征 easy sample(使用sklearn包):Scatter图Grid图Example参考资料 t-SNE(t-Distributed Stochastic Neighbor Embedding)是一种非线性降维技术,主要用途为对高维数据进行可视化。 easy sample(使用sklearn包): from matplotlib.offsetbox import OffsetImage, AnnotationBbox from sklearn.manifold import TSNE import cv2 import numpy as np import matplotlib.pyplot as plt # 传入图像的embedding特征和对应的图像路径 def draw_tsne(features, imgs): """ Args: feature: [n_samples embed_dim], full data embedding of test samples. imgs: list [n_samples], list of datapaths corresponding to <feature> """ #print(imgs) # 初始化一个TSNE模型,这里的参数设置可以查看SKlearn的官网 tsne = TSNE(n_components=2, init='pca', perplexity=30) # Y是降成两维后的数据 Y = tsne.fit_transform(features) fig, ax = plt.
定义[] js集合 注: 以隐藏域形式传入后端,这样可以解决多个id值拼接传参问题后端String 类型封装数据,mybatis转成数组的形式便于foreach
var rows = $("#bootstrap-table").bootstrapTable('getSelections'); var rlmcArray = [],clnfArray = [],fdjxhArray= [],cxmcArray=[]; if(rows && rows.length > 0){ for(var index in rows){ if(rows[index].rlmc){ if(!rlmcArray[rows[index].rlmc]){ rlmcArray.push(rows[index].rlmc) } } if(rows[index].clnf){ if(!clnfArray[rows[index].clnf]){ clnfArray.push(rows[index].clnf) } } if(rows[index].cxmc){ if(!cxmcArray[rows[index].cxmc]){ cxmcArray.push(rows[index].cxmc) } } if(rows[index].fdjxh){ if(!cxmcArray[rows[index].fdjxh]){ fdjxhArray.push(rows[index].fdjxh) } } } } $("#fdjxhString").val(fdjxhArray.join(",")); mybaits sql 如下
js 对象 前端如何json形式传参 var lld = {}; //领料单 lld.list = datas; lld.lldid = $("#bizId").val(); lld.lldh = $("#lldh").val(); lld.llrid = $("
可以直接在串口输入以下命令实现: logcat -v time -f /data/logcat.log | cat /proc/kmsg | tee /data/kernel_dmesg.log 说明:logcat打印输出到data目录的logcat.log文件,dmesg打印,也就是kernel内核的打印会在data目录的kernel_dmesg.log文件中。
logcat 输出日志信息到文件中 – "-f"选项 : 该选项后面跟着输入日志的文件, 使用adb logcat -f /sdcard/log.txt 命令, 注意这个log文件是输出到手机上,需要指定合适的路径。
gtt92e:/ # logcat -f /sdcard/log.txt 这个参数对不能一直用电脑连着手机收集日志的场景非常有用,其实android shell下也有一个相同参数的logcat命令。使用如下命令可以执行后断开PC和手机持续收集LOG。
gtt92e:/ # logcat -f /sdcard/log.txt & #这里的&符号表示后台执行,记住一定要添加。
注意合适的时候需要停止掉以上命令,否则再次使用相同命令的时候,就会有两个logcat写同一个文件
停止方法(串口执行): kill -9 <logcat_pid> 其中logcat_pid通过如下命令获取 ps | grep logcat – ">"输出 : “>” 后面跟着要输出的日志文件, 可以将 logcat 日志输出到文件中, 使用adb logcat > log 命令, 使用more log 命令查看日志信息;
举例说明:
130|gtt92e:/ # logcat -f /sdcard/log.
QTextBrowser QTextBrowser类为富文本浏览器提供了超文本导航,通常用作程序日志的输出窗口,默认只读。
但只是默认,后期可以自行修改
# -*- coding: utf-8 -*- """ Created on Sat May 9 17:14:37 2020 @author: Giyn """ import sys from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QTextBrowser, QVBoxLayout, QHBoxLayout, QMessageBox from PyQt5.QtGui import QIcon class Simple_Window(QWidget): def __init__(self): super(Simple_Window, self).__init__() # 使用super函数可以实现子类使用父类的方法 self.setWindowTitle("记事本") self.setWindowIcon(QIcon('NoteBook.png')) # 设置窗口图标 self.resize(412, 412) self.text_browser = QTextBrowser(self) # 实例化一个QTextBrowser对象 self.text_browser.setText("<h1>Hello World!</h1>") # 设置编辑框初始化时显示的文本 # self.text_browser.setReadOnly(False) # 调用setReadOnly方法并传入False参数即可编辑文本浏览框(编辑框也可以变成只读) self.save_button = QPushButton("Save", self) self.clear_button = QPushButton("Clear", self) self.
电脑壁纸2K+Win10实用快捷键 适用于:2K屏幕,1920*1080屏幕
PS:
壁纸会持续更新,可定期前往网盘查看最新壁纸。
如果你有好的壁纸,也可以联系我,分享给更多的朋友。
仅展示部分,原图获取见文末。
更多精美壁纸,原图免费获取: 主营:纯天然蜂蜜,电脑软硬件服务,其他等。
卷积网络的运算过程以及参数计算过程 写这篇文章是因为发现自己这么久以来把卷积核的计算过程理解错了,一直到和师兄交流的时候才发现,抓紧写一篇博客记录一下。
1. 卷积神经网络的计算过程 以上图为例,假设输入的图片是32 × \times × 32 × \times × 3大小,也就是我们所说的输入为32 × \times × 32大小的RGB图像。我一直理解错的就是这幅图像与卷积核计算的过程,具体怎么错的就不误解大家了。
假设现在我们要用一个5 × \times × 5 × \times × 3的卷积核来提取图片中的特征,首先需要注意的一点,我们一般在描述时通常就将这个卷积核称为5 × \times × 5的卷积核,而忽略掉后面这个3,而卷积核的这个宽度必须与输入的图像的宽度一致,也就是说都是3,当它们的宽度一致时卷积核才可以像我们说的在图像上面滑动。
这时大家可能会有疑问,如果宽度是3,那提取的特征不就一直是3个吗?
如果你有这个问题说明你还是没有理解其计算过程,实际上我们说的5 × \times × 5 × \times × 3就是一个卷积核,如果需要提取输入图像的10个特征,那么我们就需要10个这样的卷积核,在论文中通常会把这个卷积部分的大小描述为5 × \times × 5 × \times × 10,会省略这个3的书写。这也就是大家理解容易出错的地方。
在这张图片中我们可以看到这个5 × \times × 5 × \times × 3的卷积核提取特征的过程,也就是这个卷积块核图像中一个一样大小的块相乘(dot也就是点乘)再加上偏置项,再使用一个激活函数得到最终的特征提取结果。其运算过程也可以结合下图理解:
一个RGB图像大小为 6 × 6 6\times 6 6×6,三个通道,中间这一个部分表示是用了两个卷积核,每个卷积核的大小也是 3 × 3 3\times 3 3×3,与输入图像通道数一致,因此卷积核的通道数也是3个。每个卷积核在图像上滑动以后得到的特征图的大小是 4 × 4 4\times 4 4×4,两个卷积核得到的特征图就是 4 × 4 × 2 4\times 4 \times 2 4×4×2。
一、vue-cli4.0版本部署上线跨域问题:
vue-cli4.0项目打包后,在本地vue.config.js配置的反向代理不起作用:
module.exports = { runtimeCompiler: true, publicPath: '[{[ .StaticURL ]}]', // publicPath: '/static', lintOnSave: false, devServer: { proxy: { '/netapi': { /*target是你要进行跨域的目标地址*/ target: 'http://xxx.xxx.xxx.com:86/', changeOrigin: true, pathRewrite: { '^/netapi': '' } } } } } 后来发现,项目打包上线后需要在nginx配置代理,方可请求到目标接口:
server { listen 8080; server_name localhost; charset utf-8; access_log logs/host.access.log main; location / { /*1、发现设置根路径为打包后的路径时,nginx配置的跨域不起作用*/ # root C:\mpro\ser\frontend\dist; index index.html index.htm; /*2、所以干脆就使用proxy_pass代理到本地解决*/ proxy_pass http://localhost:8080/; } location /netapi/ { /*3、我是代理的请求地址哦*/ proxy_pass http://xxx.xxx.xxx.com:86/; client_max_body_size 10M; } /* 因为我项目本地已创建baseURL.
简介 DoraemonKit 是一个功能集合面板,能够让每一个 App 快速接入一些常用的或者你没有实现的一些辅助开发工具、测试效率工具、视觉辅助工具,其中包括常用的内存、cpu、帧率、卡顿检测和crash等等,而且能够完美在 Doraemon 面板中接入你已经实现的与业务紧密耦合的一些非通有的辅助工具,功能强大,接入方便,便于扩展。
接入步骤只需在app的build.gradle中添加:
debugImplementation "com.didichuxing.doraemonkit:doraemonkit:3.1.5" releaseImplementation "com.didichuxing.doraemonkit:doraemonkit-no-op:3.1.5" 在Application中添加初始化即可完成。
DoraemonKit.install(this); 界面如下:
DoraemonKit具有哪些功能 1.【App信息查看】快速查看手机信息,App信息,权限信息的渠道,避免去手机设置查找或者查看项目源代码的麻烦。
2.【沙盒浏览】App内部文件浏览的功能,并且能通过airDrop或者其他分享方式上传到PC中,进行更加细致的操作。
3.【MockGPS】App能定位到全国各地,支持地图地位和手动输入经纬度。
4.【H5任意门】开发测试同学可以快速输入H5页面地址,查看该页面效果。
5.【日志显示】每一条日志信息,都在在App的界面中显示出来,再也不需要导出日志这么麻烦。
6.【帧率监控】App 帧率信息提供波形图查看功能,让帧率监控的趋势更加明显。
7.【CPU监控】App CPU使用率信息提供波形图查看功能,让CPU监控的趋势更加形象。
8.【内存监控】App 内存使用量信息提供波形图查看功能,让内存监控的趋势更加鲜明。
9.【流量监控】拦截App内部流量信息,提供波形图展示、流量概要展示、流量列表展示、流量筛选、流量详情,对流量信息统一拦截,成为我们app中自带的“Charles”。
10.【自定义监控】可以选择你要监控的选项,包括FPS、CPU、内存、流量。监控完毕之后,把数据保存到本地,也可以导出来做更加细致的分析。
11.【颜色吸管】方便设计师UI捉虫的时候,查看每一个组件的颜色值是否设置正确。
12.【组件检查】可以抓取任意一个UI控件,查看它们的详细信息,包括控件名称、控件位置、背景色、字体颜色、字体大小。
13.【对齐标尺】参考Android系统自带测试工具,能够实时捕获屏幕坐标,并且可以查看组件是否对齐。
参考:
链接: https://github.com/didi/DoraemonKit
插件化 1.前言2.插件化的实现3.类加载3.1 ClassLoader的实现类3.2 加载原理3.3 插件化原理总结3.4 插件化代码总结 1.前言 插件化技术最初源于免安装运行 apk 的想法,这个免安装的 apk 就可以理解为插件,而支持插件的 app 我们一般叫宿主。宿主可以在运行时加载和运行插件,这样便可以将 app 中一些不常用的功能模块做成插件,一方面减小 了安装包的大小,另一方面可以实现 app 功能的动态扩展。
2.插件化的实现 我们如何去实现一个插件化呢?
首先我们要知道,插件apk是没有安装的,那我们怎么加载它呢?不知道。。。
一个 apk 主要就是由代码和资源组成,所以上面的问题我们可以变为:如何加载插件的类?如何加载插件的资源?这样的话是不是就有眉目了。
然后我们还需要解决类的调用的问题,这个地方主要是四大组件的调用问题。我们都知道,四大组件是需要注册 的,而插件的四大组件显然没有注册,那我们怎么去调用呢?
所以我们接下来就是解决这三个问题,从而实现插件化
如何加载插件的类? 如何加载插件的资源? 如何调用插件类 3.类加载 我们在学 java 的时候知道,java 源码文件编译后会生成一个 class 文件,而在 Android 中,将代码编译后会生成一个 apk 文件,将 apk 文件解压后就可以看到其中有一个或多个 classes.dex 文件,它就是安卓把所有 class 文件进行合并,优化后生成的。java 中 JVM 加载的是 class 文件,而安卓中 DVM 和 ART 加载的是 dex 文件,虽然二者都是用的 ClassLoader 加载的,但因为加载的文件类型不同,还是有些区别的,所以接下来我们主要介绍安卓的 ClassLoader 是如何加载dex 文件的。 3.1 ClassLoader的实现类 ClassLoader是一个抽象类,实现类主要分为两种类型:系统类加载器和自定义加载器。 其中系统类加载器主要包括三种:
BootClassLoader 用于加载Android Framework层class文件。PathClassLoader 用于Android应用程序类加载器。可以加载指定的dex,以及jar、zip、apk中的classes.
DMA(Direct Memory Access)
直接内存访问,是一种无需CPU的参与就可以让外设与系统内存之间进行双向数据传输的硬件机制。使用DMA可以使系统CPU从实际的I/O数据传输过程中摆脱出来,从而大大提高系统的吞吐率。DMA方式的数据传输由DMA控制器(DMAC)控制,在传输期间,CPU可以并发的执行其他任务。当DMA结束后,DMAC通过中断通知CPU数据传输已经结束,由CPU执行相应的中断服务程序进行后续处理。
与CPU copy的区别
当程序或者操作者对CPU发出指令,这些指令和数据暂存在内存里,在CPU空闲时传送给CPU,CPU处理后把结果输出到输出设备上,输出设备就是显示器,打印机等。在没有显示完之前,这些数据也保存在内存里,如果内存不足,那么系统自动从硬盘上划分一部分空间作为虚拟内存来用。但写入和读取的速度 跟物理内存差的很远很远,所以,在内存不足的时候,会感到机器反应很慢,硬盘一直在响。CPU对数据进行判断以及逻辑处理,本身不能存储数据,这时cpu从内存取数据进行逻辑计算,如果内存没有数据,才会从硬盘读取数据。要把外设的数据读入内存或把内存的数据传送到外设,一般都要通过CPU控制完成,如CPU程序查询或中断方式。利用中断进行数据传送,可以大大提高CPU的利用率。
但是采用中断传送有它的缺点,对于一个高速I/O设备,以及批量交换数据的情况,只能采用DMA方式,才能解决效率和速度问题。DMA在外设与内存间直接进行数据交换,而不通过CPU,这样数据传送的速度就取决于存储器和外设的工作速度。
通常系统的总线是由CPU管理的。在DMA方式时,就希望CPU把这些总线让出来,即CPU连到这些总线上的线处于第三态–高阻状态,而由DMA控制器接管,控制传送的字节数,判断DMA是否结束,以及发出DMA结束信号。DMA控制器必须有以下功能:
1. 能向CPU发出系统保持(HOLD)信号,提出总线接管请求;
2. 当CPU发出允许接管信号后,负责对总线的控制,进入DMA方式;
3. 能对存储器寻址及能修改地址指针,实现对内存的读写操作;
4. 能决定本次DMA传送的字节数,判断DMA传送是否结束 ;
5. 发出DMA结束信号,使CPU恢复正常工作状态。
静态路由原理与配置
实验案例一:在华为ensp软件上手动配置静态IP
实验环境
如图所示,在华为ensp软件上将三个路由器进行环形连接,手动配置静态ip,各端口ip如图所示,回环地址这里为虚拟地址。
需求描述
将上述过程通过实验再现出来。
在华为ensp虚拟环境进行试验,
推荐步骤
新建一个拓扑图如下所示,
手动配置各个路由器端口的ip地址
配置其环回地址
设置下一跳地址 使其顺时针正常通信
在各个路由器上ping其余两个能够正常通信
具体如下:这里的ip地址已经标识在拓扑图里了
1、第一步,也是非常重要的一步就是连线以及端口号,要配清楚,不然实验做到一半自己被自己搞蒙了;各路由器的端口ip以及回环地址如下图所示
2、这里就简写了,具体步骤如下:
sys 进入系统视图
sysname r1 将路由器的名字改为r1
interface g0/0/0 进入g0/0/0口配置
ip add+地址 配置其端口ip地址
如下图所示,配置r1的g0/0/0口
这里要强调一下设置完成后要记得undo shutdow 将端口打开!!!!!!!!!!!!!!!!!!
2、依次将各个端口的ip地址配置好,这里推荐个小技巧
dis this 查看此端口的配置信息,避免出错
3、以此类推
4、这里涉及到一个回环地址
int loo 0:进入到回环接口模式
ip add 1.1.1.1:将此接口设置为1.1.1.1
剩下就以此类推,照搬就可以了
这里设置r2的回环地址
5、这里设置下一跳地址,如图所示,因为是顺时针通信,r1无论是与r2还是r3通信 都是要经过g0/0/0口,也就是192.168.20.2,这里要睁大你的双眼 注意,这是今天的重头戏!!!!!这里首先要弄清楚下一跳是什么意思,静态路由是什么意思,不然做起来脑子里没有框架很难受,
ip route-static 3.3.3.3 192.168.20.2
这里的3.3.3.3是路由的回环地址,192.168.20.2就是下一跳的地址,回到图一自己看下,下一跳地址,不懂得话百度先去看下,
6、这里拿r3pingr1和r2都ping通了 说明是可以与其通信的,如果不能就很麻烦了,需要一步步排障,这里先不多介绍了,我的实验还是比较成功的,一次性到位,希望你也是
到这里就已经成功了==
如果有帮到你的话记得点赞评论加关注哦
没毛病老铁~
如今科技发展日新月异,随着机器人、AR/VR等人工智能领域的不断发展,视觉SLAM也取得了惊人的发展。本文就视觉SLAM的定义、研究分类、模块、工作原理及应用方向等方面做一个视觉SLAM的技术简述。
视觉SLAM是什么?
SLAM的英文全称是Simultaneous Localization and Mapping,中文称作「即时定位与地图创建」,而视觉SLAM就是用摄像头来完成环境的感知工作。
当一个自主移动的机器人处在一个未知的环境,它要通过摄像头获取的信息数据对自身以及周围环境进行一个预估,在机器人移动过程中根据位置估计和摄像头对感知的数据进行自身的定位,同时不断地建造和更新地图并且规划自身的路径。
视觉SLAM研究分类
视觉SLAM研究主要分为三大类:单目、双目、RGBD。
单目SLAM只用一支摄像头就可以完成SLAM。最大的优点是传感器简单且成本低,但同时也有个大问题,就是不能通过单张图片得到深度信息(距离),存在尺寸不确定的现象,比如丢失深度信息的相片中,我们能见到“手捏太阳”“借位拍照”这样的现象。
单目相机无法依靠一张图像获得图像中物体离自己的相对距离。为了估计这个相对深度,只能利用移动相机之后进行三角化,测量像素的距离。即是说,它的轨迹和地图,只有在相机运动之后才能收敛,如果相机不进行运动时,就无法得知像素的位置。同时,相机运动还不能是纯粹的旋转,这就给单目SLAM的应用带来了一些麻烦。
双目SLAM利用左右目的视差计算像素的距离,从而实现自身的定位。立体视觉既可以在运动时估计深度,亦可在静止时估计,消除了单目视觉的无法得到深度信息的麻烦。目前市面常见的双目相机包括INDEMIND双目视觉惯性模组等。不过通过双目图像计算像素距离,计算量大,而且在特征少的白墙或暗光环境易丢失目标。
RGBD相机是2010年左右新兴的一种相机,它最大的特点是可以通过红外结构光或Time-of-Flight原理,直接测出图像中各像素离相机的距离。因此,它比传统相机能够提供更丰富的信息,也不必像单目或双目那样费时费力地计算深度。目前常用的RGBD相机包括Kinect/Kinect V2等。不过,现在多数RGBD相机还存在测量范围窄、噪声大、视野小等诸多问题。出于量程的限制,主要用于室内SLAM。
视觉SLAM框架解读
一般的视觉SLAM系统分为五个模块:传感器数据、视觉里程计、后端、建图、回环检测。
1.传感器数据
在视觉SLAM中主要为相机图像信息的读取和预处理。如果在机器人中,还可能有码盘,惯性传感器等信息的读取和同步。
2.视觉里程计
视觉里程计(VO)也称前端。它根据相邻图像的信息,估计出粗略的相机运动,给后端提供较好的 初始值。VO 的实现方法,按是否需要提取特征,分为特征点法的前端以及不提特征的直 接法前端。基于特征点法的前端,长久以来(直到现在)被认为是视觉里程计的主流方法。 它运行稳定,对光照、动态物体不敏感,是目前比较成熟的解决方案。
3.后端优化
后端优化主要是处理slam过程中噪声的问题。任何传感器都有噪声,所以除了要处理“如何从图像中估计出相机运动”,还要关心这个估计带有多大的噪声。
前端给后端提供待优化的数据,以及这些数据的初始值,而后端负责整体的优化过程,它往往面对的只有数据,不必关系这些数据来自哪里。在视觉slam中,前端和计算接视觉研究领域更为相关,比如图像的特征提取与匹配等,后端则主要是滤波和非线性优化算法。
4.回环检测
回环检测也可以称为闭环检测,是指机器人识别曾到达场景的能力。回环检测提供了当前数据与所有历史数据的关联,在跟踪算法丢失之后,我们还可以利用回环检测进行重定位。因此,回环检测对整个SLAM系统精度与鲁棒性的提升,是非常明显的。
5.建图
建图主要是根据估计的轨迹建立与任务要求对应的地图,在机器人学中,地图的表示主要有栅格地图、直接表征法、拓扑地图以及特征点地图这4种。而特征点地图是用有关的几何特征(如点、直线、面)表示环境,常见于视觉SLAM技术中。
视觉SLAM工作原理
大多数视觉SLAM系统的工作方式是通过连续的相机帧,跟踪设置关键点,以三角算法定位其3D位置,同时使用此信息来逼近推测相机自己的姿态。简单来说,这些系统的目标是绘制与自身位置相关的环境地图。这个地图可以用于机器人系统在该环境中导航作用。与其他形式的SLAM技术不同,只需一个3D视觉摄像头,就可以做到这一点。
通过跟踪摄像头视频帧中足够数量的关键点,可以快速了解传感器的方向和周围物理环境的结构。所有视觉SLAM系统都在不断的工作,以使重新投影误差(Reprojection Error)或投影点与实际点之间的差异最小化,通常是通过一种称为Bundle Adjustment(BA)的算法解决方案。VSLAM系统需要实时操作,这涉及到大量的运算,因此位置数据和映射数据经常分别进行Bundle Adjustment,但同时进行,便于在最终合并之前加快处理速度。
目前,视觉SLAM主要被运用于无人机、无人驾驶、机器人、AR、智能家居等领域,同时涌现出了一大批视觉SLAM优秀的公司和产品。如百度的自动驾驶软件、仙途智能的智能环卫车、科沃斯的扫地机器人、INDEMIND的机器人视觉导航定位解决方案、穿戴计算解决方案等等。
随着城市物联网和智能系统的完善,视觉SLAM的前景是非常广阔的。尤其是视觉SLAM得天独厚的语义地图优势,能很好地满足人与人工智能之间的交互,非常符合人工智能的发展趋势。
虽然目前视觉SLAM技术方面还存在着一些问题,但这些都会随着消费刺激和产业链的发展逐步解决、趋于完善。
参考文献
《视觉SLAM十四讲》高翔
通过对图片数组的length取余,便捷实现无限切换,控制一个变量
两边切换按钮++ | --
点击图片 修改为当前index
JS
<div class="works_pic" v-show="video_pic_tab == 'pic'"> <img class="works_pic_big" v-for="(item, index) in worksPic" :key="index" :src="item" v-show="index == Math.abs(worksPicIndex)% worksPic.length"> <div class="pic_control" v-if="worksPic.length"> <span class="pic_left" @click="worksPicIndex--"></span> <div class="works_pic_list"> <img :class="index == Math.abs(worksPicIndex)% worksPic.length? 'works_pic_small active' : 'works_pic_small'" v-for="(item, index) in worksPic" :key="index" :src="item" @click="worksPicIndex = index"> </div> <span class="pic_right" @click="worksPicIndex++"></span> </div> </div> CSS
.video_pic .works_pic { display: flex; flex-direction: column; justify-content: center; align-items: center; padding: 15px; } .
gradle和git
在最后几天,我问自己如何从git的commit / tag消息中获得的信息生成发行说明。 决定 我的第一种方法是直接从提交消息创建更改列表,但是这种方法有很多缺点。 提交消息必须写得非常严格 需要一个标记来收集属于发行版的消息(通常的标记就足够了) 提交消息的内容必须遵循约定,以便功能 , 错误修正和更改可以收集并在一个块中显示。 因此,我选择了带注释的标签,该标签必须提供带有标签的消息。 使用git创建它们相当容易 git tag -a v.1.0.0 -m "This is an annotated tag" 旁注:这种标记有一个不错的补充,它允许检查哪些提交属于特定标记。 下一个决定是关于消息应使用的标记语言。 因为我是markdown的粉丝,所以决定这么做。 这将导致人类可读的消息以及众所周知且有效的解析。 重要提示 Git通常将#解释为注释的开始。 如果您要使用的头标和头标更多,则必须使用选项–cleanup = verbatim创建带注释的标签,以禁止使用此功能。 通过这一决定,我开始在gradle中实现一个小示例,该示例在构建过程中创建发行说明。 在下一节中,我向您展示所需的代码 实作 先决条件 因为我也想要发行说明的漂亮版本,所以我决定将markdown直接转换为html页面。 为此,我将PegDown用作Markdown处理器,并使用带有bootswatch主题的twitter bootstrap来对输出进行样式设置。 初始构建脚本 buildscript { repositories { mavenCentral() mavenLocal() } dependencies { classpath 'org.pegdown:pegdown:1.4.1' } } import org.pegdown.PegDownProcessor import groovy.text.SimpleTemplateEngine 实施逻辑 我们从控制控件生成发行说明的过程开始 task releaseNotes() { def releaseNotes = new File('releaseNotes.md') releaseNotes.delete() def versions = "
他们说一块岩石会引起雪崩。 最近,我的一位同事Marcin Radoszewski给了我一块岩石。 您可能永远都不会猜测它是什么,但是有机会在许多Web应用程序中使用它。 请允许我向您介绍这块石头。 您可能很清楚发布模式后的重定向 。 使用Spring Framework,您有几种方法来实现它,让我们专注于其中一种, 将目标URL作为带有redirect: prefix的String返回 。 假设我们有使用这种重定向方法的控制器,并且在重定向期间必须传递一些参数,例如,让它成为某些实体ID: @RequestMapping(method = RequestMethod.POST) public String onPost(...) { ... return "redirect:form.html?entityId=" + entityId; } 如您所见,我们的岩石看上去并不危险,甚至看上去都不可疑–这到底是怎么了? –您可能会问。 好了,要解释一下,我们必须看看Spring Framework如何处理您返回的值的方式。 您可以从阅读Spring Framework文档中的解析视图开始,然后仔细查看AbstractCachingViewResolver的源代码,它是Spring中许多不同的视图解析器的基类,包括:JSP,FreeMarker,Velocity,Jasper Reports,Tiles和XSLT视图解析器。 当resolveViewName方法被调用AbstractCachingViewResolver的它采用了基于HashMap的视图缓存加快鉴于在未来的呼叫解决,和缓存关键是使用视图名称和当前语言环境中创建的默认。 现在,当您使用上述重定向方法时, Spring Framework将从控制器的方法返回的整个String用作视图名称,包括目标URL中包含的所有参数。 每次执行重定向时,参数可能会有所不同,因此这种重定向将在AbstractCachingViewResolver的视图缓存中留下一个额外的条目,从而导致内存泄漏。 多久会终止我的申请? –您可能会问。 这取决于分配给JVM的内存量以及执行的重定向次数–我已经使用-Xmx64M选项进行了一些测试,仅通过一个控制器即可构建简单的应用程序-请参见本示例 。 大约76400重定向后,应用程序因OutOfMemoryError:Java heap space终止。 参考: Spring的Web MVC –在Warlock's Thoughts博客上从我们的JCG合作伙伴 Michal Jastak 重定向到Memory Leak 。 翻译自: https://www.javacodegeeks.com/2012/12/springs-web-mvc-redirect-to-the-memory-leak.html
从transformer开始,nlp的模型渐渐开始成为了transformer一族的天下,所以想写一个系列聊一聊在nlp中那些运用transformer的模型。
作为这个系列的第一篇,就从大名鼎鼎的transformer结构开始。
一、编码器(encoder)与解码器(decoder) 最早提出transformer的文章是attention is all you need,研究的nlp的任务是翻译,自然而然就借鉴了seq2seq的翻译结构,有了编码器(encoder)和解码器(decoder)。
正如下面的图所展示的那样,一个完整的transformer结构是由六个解码器和六个解码器组成,其中六个编码器堆叠而成,最后一层的编码器会将输出输入到每个解码器中。
解码器的输入有两部分组成:上一层的解码器的输入(如果是第一层解码器的话是之前翻译的token的embedding)& 最后一层编码器的输入编码器的输入就是上一层的编码器的输出(如果是第一层的编码器的话就是embedding)
1、编码器的结构 六个编码器的结构都是一样的,主要是由:
多头自注意力机制(multi-head self-attention mechanism)(下图左框橘色)全连接前馈层(feed forward)(下图左框蓝色)残差网络以及每层都有的层标准化(下图左框黄色) 后面会一个个来介绍。
2、解码器的结构 六个解码器的结构都是一样的,主要是由:
多头自注意力机制(multi-head self-attention mechanism)(下图左框橘色),解码器会有两种多头自注意力机制,一种是有masked,一种是没有masked全连接前馈层(feed forward)(下图左框蓝色)残差网络以及每层都有的层标准化(下图左框黄色)
二、注意力机制 从上面的介绍可以直观看到,整个transformer模型中,大量出现了一个结构:多头自注意力机制(multi-head attention),为什么叫他“多头”呢,因为他是由很多相似结构的scaled dot-product attention 拼接起来的,直观的展开如下图。
1、scaled dot-product attention 首先,我们来介绍最基本的组成单元:scaled dot-product attention。这部分的输入会有三个:q (query),k (key),v (value)。
假设我们的任务是将 亚热带(中文) 翻译成 아열대 (韩文),scaled dot-product attention的计算流程如下:
第一个框:首先,经过embedding的部分,可以得到“亚热带”三个词对应的embedding,一个seq_length X embedding_dim的矩阵,这里的话就是3X5的矩阵。第二个框:seq_length X embedding_dim的矩阵,分别乘以三个映射(project)矩阵(三个灰色的矩阵WVi,WKi,WQi),三个矩阵分别对应了三个输入k,v,q(在我们的例子中k,q,v都是同一个东西,即第一个框的输出)。结果是得到映射后的表示矩阵,维度分别是:seq_length X dv,seq_length X dk,seq_length X dk。(图里的dmodel就是embedding_dim)第三个框:映射后的k矩阵和q矩阵相乘,得到一个 seq_length X seq_length 的矩阵,通过除以 d k \sqrt{dk} dk 和softmax进行归一,这里要注意的是,softmax之前有一个可选的操作mask,也就是之前说的解码器会有的特别的masked多头自注意力层有的机制,目的是将还没预测的序列的信息mask掉。可以看到,这里的矩阵是 seq_length X seq_length ,我们可以将之近似看作是 输入的sequence的所有token之间相关关联系数的矩阵,更准确的说该矩阵的Aij可以理解为是对i对应的token,第j个对应token的权重。第四个框:将第三个框的结果与第二个框中v的映射相乘,简单理解的话,就是基于token和token之间的权重来重新计算这个token投射后的新表征。之前有说法说bert可以学习到基于上下文的单词表征,应该主要也是因为这个结构。 将整个过程用公式表示的话,如下:
一、前言 前后端分离的开发方式,我们以接口为标准来进行推动,定义好接口,各自开发自己的功能,最后进行联调整合。无论是开发原生的APP还是webapp还是PC端的软件,只要是前后端分离的模式,就避免不了调用后端提供的接口来进行业务交互。
网页或者app,只要抓下包就可以清楚的知道这个请求获取到的数据,这样的接口对爬虫工程师来说是一种福音,要抓你的数据简直轻而易举。
数据的安全性非常重要,特别是用户相关的信息,稍有不慎就会被不法分子盗用,所以我们对这块要非常重视,容不得马虎。
二、如何保证API调用时数据的安全性? 1、通信使用https
2、请求签名,防止参数被篡改
3、身份确认机制,每次请求都要验证是否合法
4、APP中使用ssl pinning防止抓包操作
5、对所有请求和响应都进行加解密操作
6、等等方案…….
三、对所有请求和响应都进行加解密操作 方案有很多种,当你做的越多,也就意味着安全性更高,今天我跟大家来介绍一下对所有请求和响应都进行加解密操作的方案,即使能抓包,即使能调用我的接口,但是我返回的数据是加密的,只要加密算法够安全,你得到了我的加密内容也对我没什么影响。
像这种工作最好做成统一处理的,你不能让每个开发都去关注这件事情,如果让每个开发去关注这件事情就很麻烦了,返回数据时还得手动调用下加密的方法,接收数据后还得调用下解密的方法。
为此,我基于Spring Boot封装了一个Starter, 内置了AES加密算法。GitHub地址如下:
https://github.com/yinjihuan/spring-boot-starter-encrypt
先来看看怎么使用,可以下载源码,然后引入即可,然后在启动类上增加@EnableEncrypt注解开启加解密操作:
增加加密的key配置:
spring.encrypt.key:加密key,必须是16位
spring.encrypt.debug:是否开启调试模式,默认为false,如果为true则不启用加解密操作
为了考虑通用性,不会对所有请求都执行加解密,基于注解来做控制
响应数据需要加密的话,就在Controller的方法上加@Encrypt注解即可。
当我们访问/list接口时,返回的数据就是加密之后base64编码的格式。
还有一种操作就是前段提交的数据,分为2种情况,一种是get请求,这种暂时没处理,后面再考虑,目前只处理的post请求,基于json格式提交的方式,也就是说后台需要用@RequestBody接收数据才行, 需要解密的操作我们加上@Decrypt注解即可。
加了@Decrypt注解后,前端提交的数据需要按照AES加密算法,进行加密,然后提交到后端,后端这边会自动解密,然后再映射到参数对象中。
上面讲解的都是后端的代码,前端使用的话我们以js来讲解,当然你也能用别的语言来做,如果是原生的安卓app也是用java代码来处理。
前端需要做的就2件事情:
1、统一处理数据的响应,在渲染到页面之前进行解密操作
2、当有POST请求的数据发出时,统一加密
js加密文件请参考我GitHub中encrypt中的aes.js,crypto-js.js,pad-zeropadding.js
我们以axios来作为请求数据的框架,用axios的拦截器来统一处理加密解密操作
首先还是要封装一个js加解密的类,需要注意的是加密的key需要和后台的对上,不然无法相互解密,代码如下:
axios拦截器中统一处理代码:
到此为止,我们就为整个前后端交互的通信做了一个加密的操作,只要加密的key不泄露,别人得到你的数据也没用,问题是如何保证key不泄露呢?
服务端的安全性较高,可以存储在数据库中或者配置文件中,毕竟在我们自己的服务器上,最危险的其实就时前端了,app还好,可以打包,但是要防止反编译等等问题。
如果是webapp则可以依赖于js加密来实现,下面我给大家介绍一种动态获取加密key的方式,只不过实现起来比较复杂,我们不上代码,只讲思路:
加密算法有对称加密和非对称加密,AES是对称加密,RSA是非对称加密。之所以用AES加密数据是因为效率高,RSA运行速度慢,可以用于签名操作。
我们可以用这2种算法互补,来保证安全性,用RSA来加密传输AES的秘钥,用AES来加密数据,两者相互结合,优势互补。
其实大家理解了HTTPS的原理的话对于下面的内容应该是一看就懂的,HTTPS比HTTP慢的原因都是因为需要让客户端与服务器端安全地协商出一个对称加密算法。剩下的就是通信时双方使用这个对称加密算法进行加密解密。
1、客户端启动,发送请求到服务端,服务端用RSA算法生成一对公钥和私钥,我们简称为pubkey1,prikey1,将公钥pubkey1返回给客户端。
2、客户端拿到服务端返回的公钥pubkey1后,自己用RSA算法生成一对公钥和私钥,我们简称为pubkey2,prikey2,并将公钥pubkey2通过公钥pubkey1加密,加密之后传输给服务端。
3、此时服务端收到客户端传输的密文,用私钥prikey1进行解密,因为数据是用公钥pubkey1加密的,通过解密就可以得到客户端生成的公钥pubkey2
4、然后自己在生成对称加密,也就是我们的AES,其实也就是相对于我们配置中的那个16的长度的加密key,生成了这个key之后我们就用公钥pubkey2进行加密,返回给客户端,因为只有客户端有pubkey2对应的私钥prikey2,只有客户端才能解密,客户端得到数据之后,用prikey2进行解密操作,得到AES的加密key,最后就用加密key进行数据传输的加密,至此整个流程结束。
四、spring-boot-starter-encrypt原理 最后我们来简单的介绍下spring-boot-starter-encrypt的原理吧,也让大家能够理解为什么Spring Boot这么方便,只需要简单的配置一下就可以实现很多功能。
启动类上的@EnableEncrypt注解是用来开启功能的,通过@Import导入自动配置类
EncryptAutoConfiguration中配置请求和响应的处理类,用的是Spring中的RequestBodyAdvice和ResponseBodyAdvice,在Spring中对请求进行统计处理比较方便。如果还要更底层去封装那就要从servlet那块去处理了。
通过RequestBodyAdvice和ResponseBodyAdvice就可以对请求响应做处理了,大概的原理就是这么多了。
本文转发于 https://blog.csdn.net/bntx2jsqfehy7/article/details/80649786 用来尽心总结记录
文章目录 一、pod的容器分类1.1、Pod 特点1.2、Pod的容器分类 二、镜像拉取策略 (image PullPolicy)2.1、尝试编辑一个pod并指定拉取策略 三、搭建 k8s 的私有仓库 一、pod的容器分类 1.1、Pod 特点 最小部署单元一组容器的集合一个Pod中的容器共享网络命名空间Pod是短暂的,有自己的生命周期。 1.2、Pod的容器分类 1、infrastructure container:基础容器
维护整个pod网络空间:可以在node节点操作查看容器的网络
[root@localhost ~]# cat /opt/kubernetes/cfg/kubelet 2、initcontainers:初始化容器
先于业务容器开始执行,原先pod中容器是并行开启,现在进行了改进 3、container:业务容器
业务容器就是我们创建的pod资源内的容器服务,业务容器也叫APP容器,并行启动 二、镜像拉取策略 (image PullPolicy) IfNotPresent:默认值,镜像在宿主机上不存在时才拉取。
Always:每次创建Pod都会重新拉取一次镜像,可以保证都是最新版本镜像。
Never:Pod 永远不会主动拉取这个镜像
查看镜像拉取策略(master节点查看):
[root@master1 demo]# kubectl get pod NAME READY STATUS RESTARTS AGE nginx-deployment-d55b94fd-hbnkr 0/1 Pending 0 2m52s nginx-deployment-d55b94fd-qdj27 0/1 Pending 0 2m51s nginx-deployment-d55b94fd-x5zd7 0/1 Pending 0 2m52s [root@master1 demo]# kubectl edit deploy/nginx-deployment #编辑Pod资源查看策略 2.1、尝试编辑一个pod并指定拉取策略 [root@localhost ~]# cd demo/ [root@localhost demo]# vim pod1.
问题:
近期使用anaconda安装PY3.6时报错:
An HTTP error occurred when trying to retrieve this URL. HTTP errors are often intermittent, and a simple retry will get you on your way. 查了网上发现,以上错误提示都是网络问题,导致安装失败。Anaconda默认的镜像源大部分都在国外,国内很多网络环境下,访问不稳定,下载速率慢,有时根本连接不上,另外国内也有镜像源,可以修改Anaconda的镜像源为国内的。
解决办法:
改用清华大学提供的镜像
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/ - https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/bioconda/ 添加位置为C:\Users\用户名
目录下找到并打开 .condarc 文件加上如下内容(记事本打开或者代码专用记事本)
channels: -(*****)(原始文件自有) - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/ - https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/bioconda/ - defaults - show_channel_urls: true 由于-defaults有时候还是会引起出错,请删除,即
channels: - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/ - https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/bioconda/ show_channel_urls: true 然后打开anaconda,重新下载相关内容即可。
(P.S.速度还比以前快N倍,即限国内)