无头浏览器识别
0x00 常规测试
0x00 Chrome Headless User Agent
Chrome无头版本的UA中含有HeadlessChrome字样,示例:
1Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/60.0.3112.50 Safari/537.36
0x01 WebDriver
基于Selenium WebDriver驱动的无头浏览器会在js中生成一个window.navigator.webdriver对象,正常的浏览器中是没有这个对象的。
0x02 WebDriver Advanced
在浏览器中执行如下js:
1navigator.webdriver = false
在正常的浏览器中,执行上述js后再次访问navigator.webdriver的值,其值为false,但在无头浏览器中,其值仍然为true。
0x03 Chrome Test
在Chrome无头模式的js环境中访问window.chrome的值为undefined。
0x04 Perm ...
Java 基础汇总
0x00 equals、hashCode和==的关系
==对于基本数据类型比较的是值,对于对象,比较的是对象的堆地址是否相等。Object类中equals()方法底层依赖的是==,默认的Object类中使用equals方法也是对比的对象的堆地址是否相等。hashCode是计算的对象的散列值。三者关系如下:
两个对象的hashcode相同,对象不一定是同一个对象。
两个对象的hashcode不同,那一定不是同一个对象。
如果两个对象的equals相同,那么hashcode一定相同。
有关String对象的特殊说明,看下面的代码:
123456String a = "ab";String b = "ab";System.out.println(a == b);String c = "a";String d = c + "b";System.out.println(a == d);
第一个输出为true,因为"ab"为字符串直接量,同样的字符串直接量将被存储为一个实例,所以a和b都指向一个 ...
PCA
0x00 数学基础
0x00 全体方差和样本方差
全体方差:
σ2=(x1−μ)2+(x2−μ)2+...+(xn−μ)2n\sigma^{2}= \frac{ (x_{1}-\mu) ^{2}+(x_{2}-\mu) ^{2}+...+(x_{n}-\mu) ^{2} } {n}
σ2=n(x1−μ)2+(x2−μ)2+...+(xn−μ)2
样本方差:
s2=(x1−xˉ)2+(x2−xˉ)2+...+(xn−xˉ)2n−1s^{2}= \frac{ (x_{1}-\bar{x}) ^{2}+(x_{2}-\bar{x}) ^{2}+...+(x_{n}-\bar{x}) ^{2} } {n-1}
s2=n−1(x1−xˉ)2+(x2−xˉ)2+...+(xn−xˉ)2
全体方差和样本方差的区别只有样本方差的分母是n-1而全体方差的分母则是n,为什么会这样呢?
我们首先要明白一点,全体方差描述的是客观事实,样本方差描述的则是一个估算,或者说预测。
样本方差的分母上,这个减了1的n被称为贝塞尔校正。因为我们发现当样本量较小的时候,偏差影响比较明显,样本方差比全体方 ...
评价体系
评价体系
聚/分类算法
我们先来明确一个基本的概念,什么是聚类(Clustering)和什么是分类(Classification or Categorization)。
首先,二者最大的区别就是聚类是无标签的,而分类是有标签的。换句话说,聚类没有一个初始的客观的判断对错的标准,而分类是有一个初始的判断对错的标准的。分类是向事物分配标签,而聚类是将相似的事物放在一起。
如下图,分类就是有给定的标签,有一定的客观事实作为依据,我开局就给分类引擎一个带有标签的训练集,告诉它什么样的是鸡,什么样的是狗,什么样的是其他动物,然后他就会对这些动物进行分类,对于分类的结果,鸡是鸡,狗是狗,狗的图片分到鸡的那一类下,那就是不对,那就是错的。
而聚类是无标签的,我开局就给聚类引擎一些没有标签的数据集,告诉它这是一堆动物的图片,你想办法给我从中找出他们之间的共性来,并按照相似的共性给我分成K类。如下图所示的聚类算法就是按照左边是2条腿的动物,右边是4条腿的动物进行聚类,这是对的,同样,如果按照动物头上有没有角进行聚类,也是对的。因为没有初始给定的判断结果对错的标准。
亦因如此,聚类是无监督的学习,分类是 ...
精确率 、 准确率和召回率
0x00 TP、FN、FP、TN
TP: True Positive 被正确分类的正例
FN: False Negative 被错误分类的负例(本来是正例,错分为负例)
TN: True Negative 被正确分类的负例
FP: False Positive 被错误分类的正例(本来是负例,错分为正例)
总结就是第一个字母代表了是否被正确分类,第二个字母代表被预测为了什么样的例子,比如FN就是错误地预测为了负例,即为原先是正例,被错分为负例。或者一图以蔽之:
0x01 精确率、准确率和召回率
精确率、准确率和召回率就是从上面四个特性中延续出来的新的统计指标。
准确率(Accuracy):准确率是预测正确的所占总体的比例,如下:
Accuracy=TP+TNTP+FN+FP+TN\text{Accuracy}=\frac{\text{TP+TN}}{\text{TP+FN+FP+TN}}
Accuracy=TP+FN+FP+TNTP+TN
精确率(Precision):精确率是针对预测结果而言的,表示预测为正的样本中,有多少预测正确了。或者说你认为的正样本中,有多少猜对了。如下:
P ...
crontab
0x00 时间表示规则
因为工作需要,经常使用crontab的定时任务规则来执行任务,遂整理其相关规则及使用方式,以作备忘。
其整体的规则符合:
12345678* * * * *- - - - -| | | | || | | | +----- 星期中星期几 (0 - 7) (星期天为0/7均可)| | | +---------- 月份 (1 - 12) | | +--------------- 一个月中的第几天 (1 - 31)| +-------------------- 小时 (0 - 23)+------------------------- 分钟 (0 - 59)
*:代表所有可能的值,假设说在月份上置一个*,则表示满足其它所有可能的条件后每月都会执行,再比如规则* * * * *则表示每分钟都执行一次。
,:逗号用于隔开一个列表范围,比如规则* * * 2,4,6 *表示在每年的2月4月6月的每分钟都执行一次。
-:介于两个整数之间,用于界定一 ...
Git SSH
0x00 Git配置ssh登陆
记录一下Git配置ssh登陆的方式,以便备忘。
首先我们需要使用ssh-keygen来生成一对公私钥:
1ssh-keygen -t rsa -C shaoqunliu@sogou-inc.com -b 4096
输入命令之后,程序会提示你输入密钥密码和密钥存放地址信息。然后你就可以在你所设置的目录下找到一个没有扩展名的私钥文件(默认名称为id_rsa),以及一个扩展名为pub的公钥文件。
此后我们需要使用ssh-add命令将生成的私钥文件添加到ssh:
1ssh-add H:/workspace/_keys/id_rsa
如上所示,后面的路径即为私钥文件的地址。
TL;DR
如果你在执行上述命令的时候,遇到如下错误信息:
1Could not open a connection to your authentication agent.
可以试着执行一下下面这个命令,成功后错误即可消除:
1eval ssh-agent bash
此后,我们再将公钥信息通过网页端添加至GitHub或者GitLab,添加完成后,我们就可以使用git clone命令来c ...
Ubuntu 安装 OpenCV
0x00 Ubuntu安装OpenCV for C++
首先安装OpenCV所需的库:
123sudo apt-get install build-essentialsudo apt-get install cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-devsudo apt-get install python-dev python-numpy libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev libjasper-dev libdc1394-22-dev
如果出现错误unable to locate libjasper-dev,则使用如下命令:
123sudo add-apt-repository "deb http://security.ubuntu.com/ubuntu xenial-security main"sudo apt updatesudo apt install libjasper1 ...
Caffe 初上手
0x00 Caffe的安装
Caffe的安装是非常费劲的,我在曾花了2天时间查阅了无数的资料修改了无数的错误才在win 10上使用Visual Studio成功编译了一个GPU版本的Caffe,所以极其不建议大家自己编译安装Caffe,建议使用docker,GPU版本请使用nvidia-docker。nvidia-docker的安装可以参考其GitHub上的描述,还是非常轻松的。这是Caffe在docker hub上的镜像仓库:
1https://hub.docker.com/r/bvlc/caffe
最新版本的nvidia-docker已经停用了nvidia-docker这个命令,取而代之的是docker run --gpus,通过参数--gpus来指定启用GPU支持和具体连接哪一块GPU,一般后面跟参数all用来指定连接所有的GPU。
当然,你也可以使用device参数来指定连接某一块具体的GPU:
12docker run -it --rm --gpus device=GPU-3a23c669-1f69-c64e-cf85-44e9b07e7a2a ubuntu nvidia-s ...
Spring 基础汇总
0x00 Spring AOP
0x00 基本概念
AOP即面向切面编程,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其名为“Aspect”,即切面。简单地说,就是将那些与业务无关,却为业务模块所共同调用的逻辑封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。Spring中AOP代理由Spring的IOC容器负责生成、管理,其依赖关系也由IOC容器负责管理。因此,AOP代理可以直接使用容器中的其它bean实例作为目标,这种关系可由IOC容器的依赖注入提供。
AOP的关键单元是切面,或者说关注点,即为我们想实现特定业务功能的方法。一些切面可能有集中的代码,但是有些可能被分散或者混杂在一起,例如日志或者事务。这些分散的切面被称为横切关注点。横切关注点是贯穿整个应用程序的关注点。像日志、安全和数据转换。
AOP的最大意义其实就是在不改变原来代码的前提下,也不对源代码做任何协议接口要求。而实现了类似插件的方式,来修改源代码,给源代码插入新的执行代码。
0x01 通知类型
通知(advice)是切面的具体逻辑实现。有以下5种 ...