本书分为算法和数据结构两大部分,又细分了十五个章节,详细讲解了刷 LeetCode 时常用的技巧。
把题目精简到了101道,一是呼应了本书的标题,二是不想让读者阅读和练习时间过长。
这么做不太好的一点是,如果只练习这101 道题,读者可能对算法和数据结构的掌握不够扎实。因此在每一章节的末尾,我都加上了一些推荐的练习题,并给出了一些解法提示,希望读者在理解每一章节后把练习题也完成。
笔记总览: 由于笔记的内容实在太多,下面就只以截图展示部分内容了。有想获取完整版笔记的小伙伴:一键三连(点赞+收藏+关注) 后,添加微信:mxm9843 即可免费获取到
内容展示 内容太多,就不一一截图展示了。有想获取完整版笔记的小伙伴:一键三连(点赞+收藏+关注) 后,添加微信:mxm9843 即可免费获取到
英伟达® DeepStream软件开发工具包(SDK)是一个用于构建智能视频分析(IVA)管道的加速人工智能框架。DeepStream 可运行在 NVIDIA T4、NVIDIA Ampere 和 NVIDIA® Jetson™ Nano、NVIDIA® Jetson AGX Xavier™、NVIDIA® Jetson Xavier NX™、 NVIDIA® Jetson™ TX1 和 TX2。
1. 安装 Jetson 在安装 DeepStream SDK 之前,本节介绍如何准备 Jetson。
1.1. 安装 Jetson SDK 组件 从下面链接安装 NVIDIA SDK 管理器: https://developer.nvidia.com/embedded/jetpack,您将使用此安装JetPack 4.5.1 GA(对应于L4T 32.5.1版本)。
NVIDIA SDK 管理器是一个图形化的应用程序,它可以闪烁并安装JetPack包。闪烁过程大约需要10-30分钟,具体取决于主机系统。 如果您使用的是 Jetson Nano 或 Jetson Xavier NX developer kit,则可以从下载 SD 卡映像https://developer.nvidia.com/embedded/jetpack。这些内容与 CUDA、TensorRT 和 cuDNN 一起打包发布。
1.2. 安装依赖项 输入以下命令以安装必备软件包:
$ sudo apt install \ libssl1.0.0 \ libgstreamer1.
目录
一 SpringBoot配置HTTPS
二 自己生成CSR
1 解压已下载的证书压缩包,获得“xxx.pem”文件和xxx.key文件
2 使用OpenSSL工具,将pem格式证书转换为PFX格式证书,得到“server.pfx”文件
3 使用Keytool工具,将PFX格式证书文件转换成JKS格式,得到“xxx.jks”文件
三 在SpringBoot中配置
1 将xxx.jks放入resources文件夹下
2 启动测试
四 同时配置http和https都能访问
1 新加配置
2 在SpringBoot启动类中添加
五 参考资料
一 SpringBoot配置HTTPS 在工作中时长会遇到配置https,SpringBoot自带的是tomcat服务器一般使用的.jks文件配置SSL加密。
过程中会用到两个工具:OpenSSL,Keytool工具。
OpenSSL:下载地址:http://slproweb.com/products/Win32OpenSSL.html
keytool工具,这是jdk自带的工具,在jdk的/bin目录下可以找到。
二 自己生成CSR https供应商不会直接提供.jks文件。所以,我们就需要将加密文件转换成所需要的jks文件。
1 解压已下载的证书压缩包,获得“xxx.pem”文件和xxx.key文件 “server.pem”文件包括两段证书代码“-----BEGIN CERTIFICATE-----”和“-----END CERTIFICATE-----”,分别为服务器证书和中级CA证书。
2 使用OpenSSL工具,将pem格式证书转换为PFX格式证书,得到“server.pfx”文件 找到openssl的bin目录,找到openssl.exe文件,单击右键以管理员身份运行,打开命令行,输入命令:
pkcs12 -export -out D:\xxx.pfx -in D:\xxx.pem -inkey D:\xxx.key 按照要求输入两次密码,这时在d盘生成了xxx.pfx文件 请牢记此处输入的PFX证书密码。后续设置JKS密码需要与此处设置的PFX密码保持一致,否则可能会导致Tomcat启动失败。
3 使用Keytool工具,将PFX格式证书文件转换成JKS格式,得到“xxx.jks”文件 keytool -importkeystore -srckeystore D:\xxx.pfx -destkeystore D:\xxx.jks -srcstoretype PKCS12 -deststoretype JKS 按照提示输入2次JKS证书密码
第三次提示输入源密钥库口令: 输入生成xxx.pfx中设置PFX证书密码
查看D盘下是否生成 xxx.jks
首先声明下,对Linux也是刚入门。没系统的学习过Linux。
首先附上能编译通过的hello world程序。
//#ifndef __KERNEL__
//#define __KERNEL__
//#endif //见别人的程序里出现过 注释掉也能通过。
#ifndef MODULE
#define MODULE
#endif
#include MODULE_LICENSE("GPL");
int init_module(void){
printk("<0>Hello World!");
return 0;
}
void cleanup_module(void){
printk("<0>Goodbye World!");
}
编译程序可能会出现的问题:
若直接用命令gcc -c hello.c编译(声明下文件名为hello.c),则可能会出现以下提示:
hello.o: kernel-module version mismatch
hello.o was compiled for kernel version 2.4.20
while this kernel is version 2.4.20-8.
解决办法: 加-I选项即:gcc -I/usr/src/Linux-2.4.20-8/include/ -c hello.c -o hello.o
程序里还需要有这么一句 MODULE_LICENSE("GPL");否则出现以下警告信息,但模块已经加载
Warning: loading modt.o will taint the kernel: no license
See http://www.
1. 液晶屏的基本概念 像素:
屏幕上显示颜色的最小单位,英文叫 pixel。注意,位图(如jpg、bmp等格式的常见图片)也是由一个个的像素点构成的,跟屏幕的像素点的概念一样。原理上讲,将一张位图显示到屏幕上,就是将图片上的像素点一个个复制到屏幕像素点上。 分辨率: 宽、高两个维度上的像素点数目。分辨率越高,所需要的显存越大。 色深: 每个像素所对应的内存字节数,一般有8位、16位、24位或32位GEC6818开发板的屏幕的色深是32位的32位色深的屏幕一般被称为真彩屏,或1600万色屏。 色深决定了一个像素点所能表达的颜色的丰富程度,色深越大,色彩表现力越强。
2. 内存映射基本原理 虽然LCD设备本质上也可以看作是一个文件,在文件系统中有其对应的设备节点,可以像普通文件一样对其进行读写操作(read/write),但由于对字符设备的读写操作是以字节流的方式进行的,因此除非操作的图像尺寸刚好与屏幕尺寸完全一致,如下图所示,图片的宽高与LCD的宽高完全一致,否则将会画面会乱。
以下是一段直接写设备节点的“不好”的示例代码:
void bad_display() { // 打开LCD设备 int lcd = open("/dev/fb0", O_RDWR); // 从JPG图片中获取ARGB数据 char *argbbuf; int argbsize; argbsize = jpg2rgb("dogs.jpg", &argbbuf); // 将RGB数据直接线性灌入LCD设备节点 write(lcd, argbbuf, argbsize); // ... } 像上述代码这样,直接将数据通过设备节点 /dev/fb0 写入的话,这些数据会自动地从LCD映射内存的入口处(对应LCD屏幕的左上角)开始呈现,并且会以线性的字节流形式逐个字节往后填充,除非图像尺寸与显示器刚好完全一致,否则显示是失败的。
一般而言,图像的尺寸大小是随机的,因此更方便的做法是为LCD做内存映射,将屏幕的每一个像素点跟映射内存一一对应,而映射内存可以是二维数组,因此就可以非常方便地通过操作二维数组中的任意元素,来操作屏幕中的任意像素点了。这里的映射内存,有时被称为显存。
如上图所示,将一块内存与LCD的像素一一对应:
LCD上面显示的图像色彩,由其对应的内存的数据决定映射内存的大小至少得等于LCD的真实尺寸大小映射内存的大小可以大于LCD的真实尺寸,有利于优化动态画面(视频)体验 下面是屏幕显示为红色的示例代码:
#include <stdio.h> #include <sys/mman.h> #include <string.h> #include <fcntl.h> int main() { // 打开液晶屏文件 int lcd = open("/dev/fb0", O_RDWR); // 给LCD设备映射一块内存(或称显存) char *p = mmap(NULL, 800*480*4, PROT_WRITE, MAP_SHARED, lcd, 0); // 通过映射内存,将LCD屏幕的每一个像素点涂成红色 int red = 0x00FF0000; for(int i=0; i<800*480; i++) memcpy(p+i*4, &red, 4); // 解除映射 munmap(p, 800*480*4); return 0; } 注意,上述代码存在诸多假设,比如屏幕的尺寸是800×480、屏幕色深是4个字节、每个像素内部的颜色分量是ARGB等等,这些信息都是“生搬硬凑”的,只能适用于某一款特定的LCD屏,如果屏幕的这些参数变了,上述代码就无法正常运行了,要想让程序在其他规格尺寸的屏幕下也能正常工作,就得让程序自动获取这些硬件参数信息。
注意 2020 版的发布说明,请参阅英特尔® Distribution of OpenVINO™ toolkit 2020 版的发布说明。 简介 英特尔® Distribution of OpenVINO™ toolkit 用于快速开发应用程序和解决方案,以解决各种任务(例如:模拟人类视觉、自动语音识别、自然语言处理和推荐系统等)。该工具套件基于最新一代的人工神经网络,包括卷积神经网络 (CNN)、递归网络和基于注意力的网络,可扩展跨英特尔® 硬件的计算机视觉和非视觉工作负载,从而最大限度地提高性能。它通过从边缘到云部署的高性能、人工智能和深度学习推理来为应用程序加速。
英特尔® Distribution of OpenVINO™ toolkit
支持从边缘到云的深度学习推理。借助英特尔® CPU、英特尔® 集成显卡、英特尔® Gaussian & Neural Accelerator、英特尔® 神经电脑棒 2、搭载英特尔® Movidius™ 视觉处理器的英特尔® Vision Accelerator Design 的通用 API,支持跨英特尔加速器的异构执行。通过一套易用的计算机视觉功能库和预优化内核库来加速上市时间。包括针对 CV 标准进行的调用优化,包括 OpenCV* 和 OpenCL™。 第 3 版发布中的更新和更改 主要功能和改进 升级到最新版本以获取新功能和性能改进。引入了条件编译的预览(可在开源发行版中获得),该预览可以显著减少特定模型的运行时组件(链接到应用程序的推理引擎)的二进制占用。推出针对第三代英特尔® 至强® 可扩展平台(代号 Ice Lake)的支持,可实现高级性能、安全性、效率和内置人工智能加速,以处理独特的工作负载和更强大的人工智能。全新预训练模型和对公共模型的支持,以简化开发: 预先训练的模型:机器翻译、人/车/自行车检测、文本识别和文本语音转换。公共模型:aclnet-int8 (sound_classification)、deblurgan-v2 (image_processing)、fastseg-small 和 fastseg-large(语义分割)等。 现在可以在 Windows*、Linux* 和 macOS*上使用 pip install openvino-dev,以 Python wheel 包的形式提供开发人员工具,轻松进行软件包的安装和升级。
支持变更和弃用通知 工具套件组件弃用通知:英特尔® Media SDK
海思的芯片定位大多是监控,所以基本不需要待机,这我了解。目前我们用Hi3518EV200在可穿戴设备VR上,但是貌似SDK自带的Linux 系统没有做待机和唤醒这块,
我输入命令使系统待机后又自动被唤醒了。。。
~ # echo standby > /sys/power/state
[ 26.931698] PM: suspend entry 1970-01-01 00:00:26.717853360 UTC
[ 26.937628] PM: Syncing filesystems ... done.
[ 26.949561] Freezing user space processes ... (elapsed 0.01 seconds) done.
[ 27.140839] PM: suspend of devices complete after 167.357 msecs
[ 27.147212] PM: late suspend of devices complete after 0.429 msecs
[ 27.153882] PM: noirq suspend of devices complete after 0.442 msecs
[ 27.160660] PM: noirq resume of devices complete after 0.
磁盘信息[root@www ~]# fdisk -l
Disk /dev/hda: 41.1 GB, 41174138880 bytes
255 heads, 63 sectors/track, 5005 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Device Boot Start End Blocks Id System
/dev/hda1 * 1 13 104391 83 Linux
/dev/hda2 14 1288 10241437+ 83 Linux
/dev/hda3 1289 1925 5116702+ 83 Linux
/dev/hda4 1926 5005 24740100 5 Extended
/dev/hda5 1926 2052 1020096 82 Linux swap / Solaris
/dev/hda6 2053 2235 1469916 8e Linux LVM
整个缺页异常的处理过程非常复杂,我们这里只简单介绍一下缺页涉及到的内核函数。
当CPU产生一个异常时,将会跳转到异常处理的整个处理流程中。对于缺页异常,CPU将跳转到page_fault异常处理程序中,该异常处理程序会调用do_page_fault()函数,该函数通过读取CR2寄存器获得引起缺页的线性地址,通过各种条件判断以便确定一个合适的方案来处理这个异常。
do_page_fault()该函数通过各种条件来检测当前发生异常的情况,但至少do_page_fault()会区分出引发缺页的两种情况:由编程错误引发异常,以及由进程地址空间中还未分配物理内存的线性地址引发。对于后一种情况,通常还分为用户空间所引发的缺页异常和内核空间引发的缺页异常。内核引发的异常是由vmalloc()产生的,它只用于内核空间内存的分配。我们这里需要关注的是用户空间所引发的异常情况。这部分工作从do_page_fault()中的good_area标号处开始执行,主要通过handle_mm_fault()完成。
handle_mm_fault()该函数的主要功能是为引发缺页的进程分配一个物理页框,它先确定与引发缺页的线性地址对应的各级页目录项是否存在,如何不存在则分进行分配。具体如何分配这个页框是通过调用handle_pte_fault()完成的。
handle_pte_fault()该函数根据页表项pte所描述的物理页框是否在物理内存中,分为两大类:请求调页:被访问的页框不再主存中,那么此时必须分配一个页框。写时复制:被访问的页存在,但是该页是只读的,内核需要对该页进行写操作,此时内核将这个已存在的只读页中的数据复制到一个新的页框中。用户进程访问由malloc()分配的内存空间属于第一种情况。对于请求调页,handle_pte_fault()仍然将其细分为三种情况:
1.如果页表项确实为空(pte_none(entry)),那么必须分配页框。如果当前进程实现了vma操作函数集合中的fault钩子函数,那么这种情况属于基于文件的内存映射,它调用do_linear_fault()进行分配物理页框。否则,内核将调用针对匿名映射分配物理页框的函数do_anonymous_page()。
2.如果检测出该页表项为非线性映射(pte_file(entry)),则调用do_nonlinear_fault()分配物理页。
3.如果页框事先被分配,但是此刻已经由主存换出到了外存,则调用do_swap_page()完成页框分配。
在以上三个函数中缺页异常处理函数通过alloc_zeroed_user_highpage_movable()来完成物理页的分配过程。alloc_zeroed_user_highpage_movable()函数最终调用了alloc_pages()。 经过这样一个复杂的过程,用户进程所访问的线性地址终于对应到了一块物理内存。
参考:
linux下硬盘检测工具: smartmontools
Smartmontools for SCSI硬盘: http://smartmontools.sourceforge.net/smartmontools_scsi.html
smartctl命令参数列表:
The following options are currently available for SCSI disks and tape drives unless otherwise noted:
* -a | --all : equivalent to the combination -i -H -A -l error -l selftest options invoked in that order.
* -A | --attributes : outputs the current device temperature, trip temperature, the number of elements in the grown defect list (GLIST) and data from the start-stop log page.
点击上方蓝字关注我吧
最近项目中用到了光敏电阻。搜索资料,发现很多人都使用光敏电阻,只是用了AD读取了电压值,或者算出了电阻值,就发送给上位机或者服务器,美其名曰获取了光照度。
搜索一番,也没找到用光敏电阻计算Lux的方法,于是自己做了一些研究,分享一下。
计算光敏电阻值
相信STM32的ADC读者应该会用,教程也一抓一大把,在此不表。接下来先计算电阻值。我的光敏电阻电路图如下:
其中PA6接单片机AD采集引脚,它最大只能输入3.6V电压,而光敏电阻的供电为5V,所以设计了R1与R2两个分压电阻,确保PA6的电压不超过3.6V。
设光敏电阻的阻值为xΩ,PA6的电压为y,可得以下公式: y/1500=5/(x+2500)
STM32的ADC精度为12位,则最大值为4096。采集到的AD值与电压成线性对应关系,系统中最高的电压值为3.3V的电源电压,它与4096对应。假设PA6感受到的电压y对应的AD值为z,则:
y/z=3.3/4096
联立两式,消去y,得到关于x的表达式:
x=10240000/(1.1×z)-2500
使用ADC得到z以后,就可以根据上式算出光敏电阻的值了。
我的代码使用了DMA获取多通道AD值,并且取100个数据求算数平均值滤波,然后打印电阻值的代码如下:
//main.c main() while (1) { if(DMA_Flag) { for(int i=0;i<ADC_CHANNEL_CNT;i++) printf("CH%d value = %d \n",i+2,ADC1_AVG_Buf[i] ); uint32_t PhotoResistor = (uint32_t)(10240000/(1.1*ADC1_AVG_Buf[4]) - 2500); //串口打印采样结果 printf("The AD value is %d,the PhotoResistor is %d .\r\n",ADC1_AVG_Buf[4],PhotoResistor); printf("The DMA count is %d .\r\n",DMA_CNT); DMA_Flag = 0; } } 现象是能够打印出光敏电阻值。
从电阻值到光照度
之前已经算出来了光敏电阻的电阻值,并且能够分出光照强度的等级,但是仍然无法计算出光照强度。光照强度是指单位面积上所接受可见光的能量,简称照度,单位勒克斯(Lux或lx)。常见环境的光照强度值如表
场所/环境
光照强度(lux)
场所/环境
光照强度(lux)
晴天室内
100~1000
办公室/教室
300~500
阴天室内
5~50
介绍 Spring REST Docs官网的介绍如下
大概意思就是说通过Spring REST Docs是用Asciidoctor编写的手写文档和Spring MVC Test生成的自动生成的代码片段
结合帮助我们生成RESTful服务的接口文档。
与Swagger的对比 如果有使用自动生成接口文档工具的同学,应该对Swagger不陌生。那Spring REST docs跟Swagger有哪些差异?
对比如下:
Spring REST DocsSwagger代码侵入性零侵入高,
需要往代码内增加@Api、@ApiOperation等注解易用性较低,
需要先生成代码片段文件后,
再编辑adoc格式的文件进行生成html,
进行查看高,
直接可生成,无需其他操作扩展性高,
最终的生成的接口文档界面可自己定义。
界面样式可自定义较低,
生成的接口界面为固定。无法修改 如何使用 本文以spingboot 2.3.10.RELEASE、Spring REST Docs 2.0.5.RELEASE为例。
新建工程 访问 https://start.spring.io/,新一个spring-rest-docs-demo的工程,并选择添加依赖。
如下图所示,点击GENERATE生成代码。将生成的代码导入IDE内。
打开pom文件添加FastJson相关jar,后面使用。完整的pom.xml文件内容如下:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.10.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.example</groupId> <artifactId>spring-rest-docs-demo</artifactId> <version>0.0.1-SNAPSHOT</version> <name>spring-rest-docs-demo</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.
执行以下sql SELECT CONCAT('ALTER TABLE `', table_name, '` MODIFY `', column_name, '` ', DATA_TYPE, '(', CHARACTER_MAXIMUM_LENGTH, ') CHARACTER SET UTF8 COLLATE utf8_unicode_ci', (CASE WHEN IS_NULLABLE = 'NO' THEN ' NOT NULL' ELSE '' END), ';') FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'database' AND DATA_TYPE = 'varchar' AND ( CHARACTER_SET_NAME != 'utf8' OR COLLATION_NAME != 'utf8_unicode_ci' ); 然后再执行这条sql查询出来的结果内容即可
花了一天多的时间去踩坑 今天终于搞好了 记录一下 也分享给后面踩坑的同学,因为技术总监是个比较严谨的人 项目打包需要配置测试环境,本地环境,生产环境 因为之前没做过 就是一个环境 突然间要配置多个环境 有点懵逼,刚开始是真的没听懂,第一步
第一步就是在public中加一个.config.json文件,然后里面写上域名这样子打包的时候就会把这个脚本文件打包到项目里面 如下图
当需要修改域名的时候告知部署服务器的那个人修改一下.config.json文件里面的域名就好了 这样就避免多次打包 只需修改域名即可 理论上这样就已经可以了 但是有可能会有缓存 导致修改的域名不成功,
实施方法如下 动态加载的uri 给定随版本变更的的动态随机码即可在配置文件中引用域名哪里配置动态加载使用axios或者其他ajax插件get
因为我们引用的域名配置在这里 所以就需要动态加载一次域名
赋值给baseURL
下面是telnet命令怎么看端口通不通:
1.同时按下键盘快捷键win+r,打开运行界面,输入cmd,回车确定。
2.在命令提示符界面输入“telnet+空格+ip”确定就可查询端口是否连通。
如何看端口通不通,情况下面的提示:
如果端口关闭或无法连接,则表明无法打开与主机的链接,并且链接失败;如果端口打开,则链接成功,然后进入telnet页面(全黑)以证明该端口可用。
Telnet 客户端命常用命令:
open : 使用 openhostname 可以建立到主机的 Telnet 连接。
close : 使用命令 close 命令可以关闭现有的 Telnet 连接。
display : 使用 display 命令可以查看 Telnet 客户端的当前设置。
send : 使用 send 命令可以向 Telnet 服务器发送命令。支持以下命令:
ao : 放弃输出命令。
ayt : “Are you there”命令。
esc : 发送当前的转义字符。
ip : 中断进程命令。
synch : 执行 Telnet 同步操作。
brk : 发送信号。
上述图文讲解telnet命令怎么看端口通不通。
前言: 最近要开发react-native项目,环境搭建遇到各种问题,特此记录一下。
开发平台:MacBook Pro (13-inch, M1, 2020) 芯片: Apple M1
react-native:0.64
x-code:12.5
Android studio :4.1.3
react-native环境搭建(官网)
1.运行创建项目 npx react-native init AwesomeProject 2.运行 "cd ./AwesomeProject/ios && pod install". 一、遇到的问题(ios) 1.error Error: Failed to install CocoaPods dependencies for iOS project, which is required by this template.
大概意思:
错误:无法安装此模板所需的iOS项目的CocoaPods依赖项。
解决方案:
1.切换国内源 cocopods安装及换源
2.fatal: unable to access 'https://github.com/google/glog.git/': LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to github.com:443 大概意思:
致命:无法访问'https://github.com/google/glog.git/':LibreSSL SSL\u connect:SSL\u ERROR\u SYSCALL连接到github.com:443
解决方案:
运行这个
用途说明
date命令可以用来显示和修改系统日期时间,注意不是time命令。
常用参数
格式:date
显示当前日期时间。
格式:date mmddHHMM # 简而言之,就是“月日时分”
格式:date mmddHHMMYYYY
格式:date mmddHHMM.SS
格式:date mmddHHMMYYYY.SS
设置当前日期时间,只有root用户才能执行,执行完之后还要执行 clock -w 来同步到硬件时钟。
mm为月份,dd为日期,HH为小时数,MM为分钟数,YYYY为年份,SS为秒数。
格式:date +FORMAT
根据指定格式显示当前时间。比如 date +%Y-%m-%d 就是以 YYYY-mm-dd 的形式显示当前日期,其中YYYY是年份,mm为月份,dd为日期。
常用FORMAT
复制代码代码如下:
%Y YYYY格式的年份(Year)
%m mm格式的月份(),01-12
%d dd格式的日期(day of month),01-31
%H HH格式的小时数(),00-23
%M MM格式的分钟数(),00-59
%S SS格式的秒数(),00-59
%F YYYY-mm-dd格式的完整日期(Full date),同%Y-%m-%d
%T HH-MM-SS格式的时间(Time),同%H:%M:%S
%s 自1970年以来的秒数。C函数time(&t) 或者Java中 System.currentTimeMillis()/1000, new Date().getTime()/1000
%w 星期几,0-6,0表示星期天
%u 星期几,1-7,7表示星期天
注意以上格式是可以任意组合的,还可以包括非格式串,比如 date “+今天是%Y-%d-%m,现在是$H:%M:%S”
更多格式 man date 或 info date
格式:date -d STRING
WINEPREFIX=~/.deepinwine/Deepin-QQ deepin-wine winecfg
这种写法的格式相当于:变量名=变量值 要执行的命令
赋值语句和要执行的命令中间用空格隔开,而不是用分号 ;。
这种格式的写法表示,定义一个变量,且只影响被执行命令的shell环境,不影响当前的shell环境。
具体说明可以查看 GNU bash 的在线帮助链接 http://www.gnu.org/software/b...,第 “3.7.1 Simple Command Expansion” 小节有如下说明:
When a simple command is executed, the shell performs the following expansions, assignments, and redirections, from left to right.
The words that the parser has marked as variable assignments (those preceding the command name) and redirections are saved for later processing.
If no command name results, the variable assignments affect the current shell environment.
21篇测试必备的Linux常用命令,每天敲一篇,每次敲三遍,每月一循环,全都可记住!!
创建文件,你知道有哪几个命令 ?(写出至少两种方式)
首先,touch
创建一个文件
touch yyTest.ini
同时创建两个文件
touch test1.txt test2.txt
批量创建文件(如创建2000个文件)
touch test{0001..2000}.txt
更改文件 yyTest.ini时间为当前时间(yyTest.ini已存在)
touch yyTest.ini
vi和vim
这里就不展开说明vi和vim了,后续会补充博文
vitest.txt
vimtouch.txt
使用>、>>
>
直接覆盖原文件,不会有任何提示
>>
追加在原文件末尾,不会覆盖原文件的内容
直接用>创建空文件
> test.ini
ls 创建文件(将结果写入文件)
ls >test.inils >> test.ini
grep 创建文件(将结果写入文件)
ps -ef | grep java >test.inips -ef | grep java >>test.ini
echo 创建文件(将结果写入文件)
echo $PATH >test.iniecho $PATH >> test.ini
使用cp创建文件
使用cat创建文件
简单使用>、>>
cat >test.inicat >> test.ini
其实用的也是 > 和 >> ,但是有一点不一样的是,敲完上述命令会进入 test.
文章目录 一些定义范式的关系范式的确定关系和范式相关的定义规范化过程部分自己理解的阐述闭包的运算结尾 一些定义 平凡函数依赖和非平凡函数依赖; X→Y,但Y⊈X则称X→Y是非平凡的函数依赖。 X→Y,但Y⊆X 则称X→Y是平凡的函数依赖 注意:平凡函数依赖都是必然成立的 不反应新的语义 若不特别声明,我们总是讨论非平凡函数依赖 数据依赖; 1、是一个关系内部属性与属性之间的一种约束关系 2、通过属性间值的相等与否体现出来的数据间相互联系 3、是现实世界属性间相互联系的抽象 4、是数据内在的性质 5、是语义的体现 数据依赖分为;函数依赖和多值依赖。 范式的关系 范式的关系为:从第一范式->第五范式范围逐渐缩小,也就是如下的关系
在我们确定范式的时候最初始也是最简单的办法就是从范围开始递推,也就是从左往右确定,确定到最高级别那么就找到了属于的 范式。
范式的确定关系 2NF:若关系模式R∈1NF,并且每一个非主属性都完全函数依赖于任何一个候选码,则R∈2NF 3NF:设关系模式R<U,F>∈1NF,若R中不存在这样的码X、属性组Y及非主属性Z (Y⊇ Z), 使得X→Y,Y→Z成立,Y ↛ X不成立,则称R<U,F> ∈ 3NF。 BCNF: 设关系模式R<U,F>∈1NF,若X →Y且Y ⊆ X时X必含有码,则R<U,F>∈BCNF。 换言之,在关系模式R<U,F>中,如果每一个决定属性集都包含候选码,则R∈BCNF。 4NF:定义: 关系模式R<U,F>∈1NF,如果对于R的每个非平凡多值依赖X→→Y(Y ⊈ X),X都含有码,则R<U,F>∈4NF。 和范式相关的定义 候选码:设K为R<U,F>中的属性或属性组合。若K可以完全确定U则K称为R的一个候选码(Candidate Key)。这里和我们的候选码确定就有一些联系,我们求得都是最小长度的候选码,否则就成了超码, 超码:如果U部分函数依赖于K,即K → U,则K称为超码。 主码:若关系模式R有多个候选码,则选定其中的一个做为主码(Primary key)。 主属性 非主属性:包含在任何一个候选码中的属性 ,称为主属性,不包含在任何码中的属性称为非主属性。(需要说的是比如我们候选码为(a,b,c),那么拆开也算超码,就是只要是子集就行)。 全码:整个属性组是码,称为全码(All-key) 规范化过程 部分自己理解的阐述 1、第二范式其实就是看有无部分函数依赖。 2、第三范式就是看是否存在函数传递(只要开始的是候选码,终止的是非主属性码就行,中间的没有约束)。 3、BCNF范式就是看最左边的确定因素是不是都包含码。 4、对于候选码的确定我们可以使用子集 5、对于BCNF则不能看子集,只能看整体。 闭包的运算 闭包(记作X+ )就是由一个属性直接或间接推导出的所有属性的集合。
对于给定的关系R(A1,A2,…An)和函数依赖集F,可将其属性分为4类:
L类 仅出现在函数依赖左部的属性。
R 类 仅出现在函数依赖右部的属性。
场景
如果只是临时有一个命令需要长时间运行,什么方法能最简便的保证它在后台稳定运行呢?
使用linux终端时,有些命令希望在后台运行,不占用终端界面。例如耗时长的任务,或者守护进程等。
&
在命令后面加上& 实现后台运行,例如
1sh test.sh &
如果放在后台运行的作业会产生大量的输出,可以输出重定向到某个文件中:
1command > out.file 2>&1 &
当你成功地提交进程以后,就会显示出一个进程号,可以用它来监控该进程,或杀死它。
1
2
3ps -ef | grep 8153
kill -9 8153
nohup
当用户注销(logout)或者网络断开时,终端会收到 HUP(hangup)信号从而关闭其所有子进程。因此,可以让进程忽略 HUP 信号。
nohup与&区别
使用&命令后,作业被提交到后台运行,一但把当前控制台关掉(退出帐户时),作业就会停止运行。
nohup命令可以在你退出帐户之后继续运行相应的进程。
nohup就是不挂起的意思( no hang up)。
使用方法输入命令:
1nohup command &
回车,使终端回到shell命令行;
输入exit命令退出终端:exit
nohup命令可以让你的shell命令忽略SIGHUP信号,即可以使之脱离终端运行;
“&”可以让你的命令在后台运行
可以输出重定向
1nohup command > myout.file 2>&1 &
注意
使用了nohup之后,有可能在当前账户非正常退出或者结束的时候,命令还是自己结束了。
所以在使用nohup命令后台运行命令之后,需要使用exit正常退出当前账户,这样才能保证命令一直在后台运行
ctrl+z, ctrl+c
ctrl+z
可以将一个正在前台执行的命令放到后台,并且处于暂停状态。
ctrl+c
终止前台命令
jobs
查看当前有多少在后台运行的命令
jobs -l选项可显示所有任务的PID
本次操作演示系统为 CentOS 6.2
修改默认目录
成功安装Apache之后,可能出于安全和其他原因的考虑,我们通常修改Apache默认的站点目录。
将默认目录 “/var/www/html” 修改为 “/home/htdocs”
进入home目录并创建相应htdocs目录
cd /home 进入home目录
mkdir htdocs 创建htdocs目录
chmod -R 755 /home/htdocs 设置htdocs目录权限
修改apache配置文件
目录创建完成后,需要修改apache配置文件(httpd.conf),将默认目录修改为/home/htdocs
vi /etc/httpd/conf/httpd.conf 使用vi编辑器打开配置文件
使用查找功能,查找DocuemntRoot关键字;注意:需要修改两个位置,如图所示
vi编辑器命令
/关键字 向下查找关键字,按 “n” 可继续查找,找到对应位置之后按“a”进入插入模式即可编辑,编辑成功后输入“:wq” 保存并退出。
重启apache服务
执行命令:# service httpd restart 重启apache服务器
删除/重命名welcome.conf文件
以上操作完成后,访问apache服务器依然访问了默认站点目录。这时需要删除或重命名/etc/httpd/conf.d/welcome.conf 文件。
删除:rm /etc/httpd/conf.d/welcome.conf
mv /etc/httpd/conf.d/welcome.conf /etc/httpd/conf.d/welcome.conf.bak
禁止访问目录列表
apache访问目录列表,对开发人员来说还是非常有用的,因为可以一目了然的看出目录结构,但是一旦发布到互联网上,为了提高网站安全性,目录列表就必须禁止访问。
将httpd.conf配置文件中Options Indexs FollowSymLinks 修改为 Options FollowSymLinks 也就是把Indexs去掉
修改默认页面
修改httpd.conf配置文件中DirectoryIndex后面的值,允许多个,其先后顺序为优先级,既没有找到第一个文件会使用第二个以此类推
设置开机自启动
设置Apache服务随系统启动:chkconfig httpd on
检查Apache服务自启动: chkconfig --list httpd
2-5显示on说明自启动设置成功
1.物联网的定义:通过信息传感设备,按照约定协议,把任何物品与互联网连接起来,进行信息交换和通信,以实现智能化识别、定位、跟踪、监控和管理。是互联网的延伸扩展。
2.物联网的特征:感知透彻性、互联广泛性、应用智能性
3.互联网秩序:立言、立德、立法
4.物联网连接场景
5.四层物联网结构
6.物联网三层结构模型示意图:
7.物联网四要素:
8.物联网数据使用流程:
9.物联网技术体系:
10.物联网中终端平台技术体系:
11.物联网中台通用解决方案:
springboot spring security 接口403 自定义处理 需要解决的问题需要实现的样式查找过程最后得到的处理方案---针对修改弹窗提示参考的文章链接 需要解决的问题 在弹出页面中有调用接口,当当前登录用户没有该权限时,就会小弹窗报错,不过报错的提示是FORBIDDEN对用户不友好,考虑将FORBIDDEN改成:无权限,请联系管理员这个问题
需要实现的样式 查找过程 我先设想 弹窗报错应该是是前端框架EASYUI的事,所以就是后端调用接口时检查登录人员无接口权限触发报错。前端收到错误信息 弹出显示错误信息
除此之外看本地代码没啥思绪,嘿嘿百度大法好,搜索 spring boot 自定义处理403(实际用这个搜索的结果收获很小)然后找到类似再疯狂查看推荐的博客最后得到理清了处理这个问题的思绪。---------》
111在idp的resources->static->error文件夹下添加 403.html(这个文件是框架默认的自定义显示错误页面的。例如,该文件夹下没有自定义的403.html页面,出现403错误的页面会显示上图所示,如果该文件夹下有403.html,403.html就会替代掉上图。如下图)
222 上面111是说页面出现403时自定义处理,222来讲调用接口出现403(即弹出显示403权限不足提示)。需要实现403权限不足处理类AccessDeniedHandler
最后得到的处理方案—针对修改弹窗提示 1先写实现处理类【最开始使用的是msg方式,不会显示FORBIDDEN,可是也不显示权限不足,错误弹窗页面一片空白//然后改成message弹窗提示就对了】
下面这个是第2种写法亲测都可以成功
2修改配置【方框框起的是实现自动注入,圆框是配置】
3到此就运行成功,以下是代码【其实代码也是照抄别人的博客的,参考链接放在最后,可以看看】
/** * <p> * 自定义权限不足处理程序 * </p> * * @author:lll * @date:Created in 2021/4/28 9:17 */ //@Component //public class MyAccessDeniedHandler implements AccessDeniedHandler { // // @Override // public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e) throws IOException, ServletException { // httpServletResponse.setStatus(HttpServletResponse.SC_FORBIDDEN); httpServletResponse.setHeader("Content-Type","application/json;charset=utf-8") ; // PrintWriter out = httpServletResponse.
下面用不同的方式只列出所有你今天创建或修改的文件(直接或间接)。
1、 使用 ls 命令,只列出你的 home 文件夹中今天的文件。
# ls -al --time-style=+%D | grep 'date +%D'
其中:
-a - 列出所有文件,包括隐藏文件
-l - 启用长列表格式
--time-style=FORMAT - 显示指定 FORMAT 的时间
+%D - 以 %m/%d/%y (月/日/年)格式显示或使用日期
在Linux中找出最近的文件
此外,你使用可以 -X 标志来按字母顺序对结果排序:
# ls -alX --time-style=+%D | grep 'date +%D'
你也可以使用 -S 标志来基于大小(由大到小)来排序:
# ls -alS --time-style=+%D | grep 'date +%D'
2、 另外,使用 find 命令会更灵活,并且提供比 ls 更多的选项,可以实现相同的目的。
-maxdepth 级别用于指定在搜索操作的起点下(在这个情况下为当前目录)的搜索层级(子目录层级数)。
-newerXY,用于所寻找的文件的时间戳 X 比参照文件的时间戳 Y 更新一些的文件。 X 和 Y 表示以下任何字母: - a - 参照文件的访问时间 - B - 参照文件的创建时间 - c - 参照文件的 inode 状态改变时间 - m - 参照文件的修改时间 - t - 直接指定一个绝对时间
1) Linux下查看硬盘及分区信息
linuxidc@Ubuntu:~# fdisk -l
以上表明这是一块 100GB 的硬盘
2)检查文件系统的磁盘空间占用情况
3)查看某目录的大小
linuxidc@ubuntu:~$ du -sh
/usr/local 41M /usr/local
查看某目录下占用空间最多的文件或目录。取前10个。需要先进入该目录下。
linuxidc@ubuntu:~$ du -cks * | sort -rn | head -n 10
1723156 总用量
877944 softs
674396 workspace
102884 Documents
67848 Downloads
36 tforder20160314.txt
12 examples.desktop
8 Desktop
4 Videos
4 variablesAndContainers.dat
一、设计任务
目标:用Python设计一个数据抓取程序,达到以下基本要求:
数据抓取任务自拟,如电子商务交易数据、客户评论、新闻、图片等。获取的数据存储为数据文件,或sqlite数据库。 程序有适当的注释,有完整的说明文件。
二、数据来源
本爬虫程序爬取的数据均来自于中国天气网城市首页的72小时天气预报(日期、天气现象、气温及空气质量)及某时刻实时天气实况,具体网址如下:
http://www.weather.com.cn/weather1d/101280101.shtml#dingzhi_first%EF%BC%89
打开网址,查询:甘肃-酒泉-酒泉,可得如下界面:
我的设想,就是从这个界面中,爬取酒泉72小时天气预报(日期、天气现象、气温及空气质量)及某时刻实时天气实况。
三、爬取工具和环境配置
Python环境安装配置:安装Python所需要的环境,使用python3.9版本.
需要使用到的库:urllib.request、csv以及BeautifulSoup
BeautifulSoup库需要手动安装,BeautifulSoup是一个网页解析库,它支持很多解析器,不过最主流的有两个。一个是python标准库,一个是lxml HTML 解析器。两者的使用方法相似:
from bs4 import BeautifulSoup
# Python的标准库
BeautifulSoup(html, 'html.parser')
# lxml
BeautifulSoup(html, 'lxml')
四、分析过程
1.查看网页源代码
下面我给出了网页源代码的头部,我们需要分析的关键信息是找出想爬取信息对应的代码。
<!DOCTYPE html>
<html>
<head>
<link rel="dns-prefetch" href="http://i.tq121.com.cn">
<meta charset="utf-8" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>酒泉天气预报,酒泉7天天气预报,酒泉15天天气预报,酒泉天气查询 - 中国天气网</title>
<meta http-equiv="Content-Language" content="zh-cn">
<meta name="keywords" content="酒泉天气预报,jqtq,酒泉今日天气,酒泉周末天气,酒泉一周天气预报,酒泉15日天气预报,酒泉40日天气预报" />
<meta name="description" content="酒泉天气预报,及时准确发布中央气象台天气信息,便捷查询北京今日天气,酒泉周末天气,酒泉一周天气预报,酒泉15日天气预报,酒泉40日天气预报,酒泉天气预报还提供酒泉各区县的生活指数、健康指数、交通指数、旅游指数,及时发布酒泉气象预警信号、各类气象资讯。" />
<!-- 城市对比上线
<link type="text/css" rel="stylesheet" href="http://c.i8tq.com/cityListCmp/cityListCmp.css?20191230" />
<link type="text/css" rel="stylesheet" href="
在使用IBM SPSS Statistics进行数据分析时,我们需要根据数据类型选择合适的检验方法,卡方检验就是一种较为常用的数据检验手段。
为此小编整理了一份SPSS卡方检验的基础教程供大家参考。
一、概述
图1:卡方检验位置
卡方检验是检验统计样本的实际观测值与理论推断值之间偏离程度的一种方法,偏离程度以检验得出的卡方值相关,卡方值越大,二者偏差程度越大;反之则越小;卡方值为0时,则表示理论值完全符合。
卡方检验是一种非参数检验,主要用于分类变量是二项或多项分布的总体分布的一致性检验。
在“分析”——“非参数检验”——“旧对话框”——“卡方检验”,可打开卡方检验窗口。
二、操作
卡方检验可以用来检验数据的适合度,即某一分类变量的实际观测次数与其理论次数是否一致,包括各水平机会均等和机会不等的情况。
1.各水平机会均等
(1)数据样本
图2:数据页
上图是小编选择的一份数据样本,其中各机会出现的可能性是相等的,即三个机会出现的概率相等且概率和为1,都是三分之一,所以理论上这几个元素在调查得到的样本中出现的次数也应当是均等的。
(2)数据加权
图3:个案加权
由于已有数据显示的是个数,所以在开始检验之前我们还需要对其进行加权:点击“数据”——“个案加权”,选择“个案加权依据”,将“个数”变量添加到“频率变量”中,点击确定。
(3)卡方检验
依照1所示方法打开卡方检验窗口。
图4:卡方检验窗口
将“机会”变量添加到“检验变量列表”中,选择“所有类别相等”。
(4)精确检验
图5:精确检验
点击卡方检验窗口右上角的“精确”,进入精确检验设置窗口。这里为用户提供了三种方法,一般来说选择默认的“仅渐进法”就可以满足需求了,如果得出的显著性水平大于0.05、或者频数过低时,可以考虑使用后两种方法进行检验。
(5)结果输出
图6:卡方检验结果
从结果可以看出,结果和预期存在显著性差异,在“可能”和“不可能”意向上更突出。
2.各水平机会不等
(1)数据
图7:数据
这是某项调查中显示的性别比例,男女比大概为1比4,我们可以通过卡方检验来验证这个比例的适合度。
(2)检验
检验前也需要进行个案加权操作(参考图3)。
图8:卡方检验
打开卡方检验窗口后,进行如上图所示的设置。
在“值”处按升序输入变量中分类所占的比例,小编这里1表示男性,2表示女性,所以依次添加0.2和0.8两个值。
精确检验依旧选择仅渐进法。
(3)结果
图9:检验结果
从检验结果来看,本次实际观测数据和理论数据1:4是符合的。
三、小结
本文中小编为大家介绍了卡方检验是什么以及如何使用IBM SPSS Statistics的卡方检验来检验实际数据和理论数据的适合度,适合度的检验有机会均等和机会不等两种情况,我们根据数据样本的特征灵活选择即可。
更多软件资讯和案例分享欢迎进入IBM SPSS Statistics中文网站查看。
病毒容易发生变异。某种病毒可以通过突变产生若干变异的毒株,而这些变异的病毒又可能被诱发突变产生第二代变异,如此继续不断变化。
现给定一些病毒之间的变异关系,要求你找出其中最长的一条变异链。
在此假设给出的变异都是由突变引起的,不考虑复杂的基因重组变异问题 —— 即每一种病毒都是由唯一的一种病毒突变而来,并且不存在循环变异的情况。
输入格式:
输入在第一行中给出一个正整数 N(≤10
4
),即病毒种类的总数。于是我们将所有病毒从 0 到 N−1 进行编号。
随后 N 行,每行按以下格式描述一种病毒的变异情况:
k 变异株1 …… 变异株k
其中 k 是该病毒产生的变异毒株的种类数,后面跟着每种变异株的编号。第 i 行对应编号为 i 的病毒(0≤i<N)。题目保证病毒源头有且仅有一个。
输出格式:
首先输出从源头开始最长变异链的长度。
在第二行中输出从源头开始最长的一条变异链,编号间以 1 个空格分隔,行首尾不得有多余空格。如果最长链不唯一,则输出最小序列。
注:我们称序列 { a1 ,⋯,an } 比序列 { b1 ,⋯,bn } “小”,如果存在 1≤k≤n 满足 ai =bi 对所有 i<k 成立,且 ak <bk 。
输入样例:
10 3 6 4 8 0 0 0 2 5 9 0 1 7 1 2 0 2 3 1 输出样例:
• 监控指标(Grafana)
由grafana组件实现
• 网格可视化(Kiali)
由kiali组件实现。
• 调用链跟踪(Jaeger)
由istio-tracing 组件实现。
默认情况下,此三个组件都是内部访问,没有暴露处理,我们可以编辑配置文件将期暴露出来
[root@master istio-1.4.2]# cat monitor-gateway.yaml --- # 监控指标 apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: grafana-gateway spec: selector: istio: ingressgateway servers: - port: number: 80 name: http protocol: HTTP hosts: - "*" --- apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: grafana spec: hosts: - "grafana.liaochao.com" gateways: - grafana-gateway http: - route: - destination: host: grafana port: number: 3000 --- # 网格可视化 Kiali apiVersion: networking.
文 | 张俊林@知乎
对比学习(Contrastive Learning)最近一年比较火,各路大神比如Hinton、Yann LeCun、Kaiming He及一流研究机构比如Facebook、Google、DeepMind,都投入其中并快速提出各种改进模型:Moco系列、SimCLR系列、BYOL、SwAV…..,各种方法相互借鉴,又各有创新,俨然一场机器学习领域的军备竞赛。对比学习属于无监督或者自监督学习,但是目前多个模型的效果已超过了有监督模型,这样的结果很令人振奋。
我想,NLP领域的Bert模型,对于这波图像领域的对比学习热潮,是具有启发和推动作用的。我们知道,Bert预训练模型,通过MLM任务的自监督学习,充分挖掘了模型从海量无标注文本中学习通用知识的能力。而图像领域的预训练,往往是有监督的,就是用ImageNet来进行预训练,但是在下游任务中Fine-tuning的效果,跟Bert在NLP下游任务中带来的性能提升,是没法比的。
“但是,既然NLP这样做(自监督,无需标注数据)成功了,图像领域难道就不能成功吗?”我相信,追寻这个问题的答案,应该是促使很多人,从图像领域的有监督预训练,向自监督预训练转向的重要心理支撑。目前看,虽然说不太容易,但也算曙光乍现,而这道曙光,正是对比学习。
有监督预训练的典型问题,我们知道,就是标注数据总是有限的,就算ImageNet已经很大,但是很难更大,那么它的天花板就摆在那,就是有限的数据总量。NLP领域目前的经验应该是:自监督预训练使用的数据量越大,模型越复杂,那么模型能够吸收的知识越多,对下游任务效果来说越好。这可能是自从Bert出现以来,一再被反复证明的真理,如果它不是唯一的真理,那也肯定是最大的真理。图像领域如果技术想要有质的提升,可能也必须得走这条路,就是:充分使用越来越大量的无标注数据,使用越来越复杂的模型,采用自监督预训练模式,来从中吸取图像本身的先验知识分布,在下游任务中通过Fine-tuning,来把预训练过程习得的知识,迁移给并提升下游任务的效果。
那对比学习是要干什么呢?从目标来说,对比学习就是要干NLP领域类似Bert预训练的事情,也即是上面那几句话。
对比学习是自监督学习的一种,也就是说,不依赖标注数据,要从无标注图像中自己学习知识。我们知道,自监督学习其实在图像领域里已经被探索了很久了。总体而言,图像领域里的自监督可以分为两种类型:生成式自监督学习,判别式自监督学习。VAE和GAN是生成式自监督学习的两类典型方法,即它要求模型重建图像或者图像的一部分,这类型的任务难度相对比较高,要求像素级的重构,中间的图像编码必须包含很多细节信息。对比学习则是典型的判别式自监督学习,相对生成式自监督学习,对比学习的任务难度要低一些。目前,对比学习貌似处于“无明确定义、有指导原则”的状态,它的指导原则是:通过自动构造相似实例和不相似实例,要求习得一个表示学习模型,通过这个模型,使得相似的实例在投影空间中比较接近,而不相似的实例在投影空间中距离比较远。而如何构造相似实例,以及不相似实例,如何构造能够遵循上述指导原则的表示学习模型结构,以及如何防止模型坍塌(Model Collapse),这几个点是其中的关键。
目前出现的对比学习方法已有很多,如果从防止模型坍塌的不同方法角度,我们可大致把现有方法划分为:基于负例的对比学习方法、基于对比聚类的方法、基于不对称网络结构的方法,以及基于冗余消除损失函数的方法。除了介绍上述几种类型的对比学习模型外,本文后面内容,还会回答下述两个问题:目前存在诸多对比学习模型,到底哪些方法效果更好?目前的对比学习模型仍然存在哪些问题?
基于负例的对比学习:以SimCLR为例 我们首先以SimCLR为例来介绍一个比较“标准”的对比学习模型,其实,在SimCLR之前已经提出不少对比学习模型,比如Moco V1出现就比SimCLR早。我们之所以首先选择SimCLR来介绍,一方面是SimCLR的效果相对它提出之前的模型,效果好得比较明显;另外一方面SimCLR采取对称结构,整体相对简洁清晰,也比较容易说清楚。而且,它奠定的结构,已成为其它对比学习模型的标准构成部分,搞明白了SimCLR,再理解其它模型,相对而言会更容易一些。
前面说过,对比学习是自监督学习,我们没有标注数据,所以需要自己构造相似数据(正例)以及不相似数据(负例),那么SimCLR如何构造正例和负例呢?
正例构造方法如上图所示。对于某张图片,我们从可能的增强操作集合 中,随机抽取两种: 及 ,分别作用在原始图像上,形成两张经过增强的新图像 , ,两者互为正例。训练时,Batch内任意其它图像,都可做为 或 的负例。这样,对比学习希望习得某个表示模型,它能够将图片映射到某个投影空间,并在这个空间内拉近正例的距离,推远负例距离。也就是说,迫使表示模型能够忽略表面因素,学习图像的内在一致结构信息,即学会某些类型的不变性,比如遮挡不变性、旋转不变性、颜色不变性等。SimCLR证明了,如果能够同时融合多种图像增强操作,增加对比学习模型任务难度,对于对比学习效果有明显提升作用。
有了正例和负例,接下来需要做的是:构造一个表示学习系统,通过它将训练数据投影到某个表示空间内,并采取一定的方法,使得正例距离能够比较近,负例距离比较远。在这个对比学习的指导原则下,我们来看SimCLR是如何构造表示学习系统的。
上图展示了SimCLR模型的整体结构。它由对称的上下两个分枝(Branch)构成,搞搜索、NLP和推荐的同学对这种结构应该不陌生。对,它来了,它来了,双塔模型又来了,它就是我们俗称的双塔结构。不过图像领域不这么叫,一般叫Branch,所以我们下文遵循这种惯用叫法。
我们随机从无标训练数据中取N个构成一个Batch,对于Batch里的任意图像,根据上述方法构造正例,形成两个图像增强视图:Aug1和Aug2。Aug1 和Aug2各自包含N个增强数据,并分别经过上下两个分枝,对增强图像做非线性变换,这两个分枝就是SimCLR设计出的表示学习所需的投影函数,负责将图像数据投影到某个表示空间。
因为上下分枝是对称的,所以我们仅以增强视图Aug1所经过的上分枝来介绍投影过程。Aug1首先经过特征编码器Encoder(一般采用ResNet做为模型结构,这里以函数 θ 代表),经CNN转换成对应的特征表示 。紧随其后,是另外一个非线性变换结构Projector(由[FC->BN->ReLU->FC]两层MLP构成,这里以函数 θ 代表),进一步将特征表示 映射成另外一个空间里的向量 。这样,增强图像经过 θ θ 两次非线性变换,就将增强图像投影到了表示空间,下分枝的Aug2过程类似。这会引发一个问题:为什么这种投影操作,要做两次非线性变换,而不是直接在Encoder后,只经过一次变换即可呢?这个问题的答案,稍后我们会给出解释。
对于Batch内某张图像 来说,在Aug1和Aug2里的对应的增强后图像分别是 和 ,那么数据对 , 互为正例,而 和Aug1及Aug2里除 之外的其它任意2N-2个图像都互为负例。在经过 θ θ 变换后,增强图像被投影到表示空间。在表示空间内,我们希望正例距离较近,负例距离较远。如果希望达成这一点,一般通过定义合适的损失函数来实现。在介绍损失函数前,我们首先需要一个度量函数,以判断两个向量在投影空间里的距离远近,一般采用相似性函数来作为距离度量标准。具体而言,相似性计算函数采取对表示向量L2正则后的点积或者表示向量间的Cosine相似性:
至于为何对比学习的相似性计算一定要做L2正则,这有背后的道理,后文会讲述原因。损失函数很关键,SimCLR的损失函数采用InfoNCE Loss,某个例子对应的InfoNCE损失为:
其中, , 代表两个正例相应的表示向量。从InfoNCE可以看出,这个函数的分子部分鼓励正例相似度越高越好,也就是在表示空间内距离越近越好;而分母部分,则鼓励任意负例之间的向量相似度越低越好,也就是距离越远越好。这样,在优化过程中,通过InfoNCE损失函数指引,就能训练模型,以达成我们期望的目标。
上面介绍了SimCLR的关键做法,本身这个过程,其实是标准的预训练模式;利用海量的无标注图像数据,根据对比学习指导原则,学习出好的Encoder模型以及它对应产生的特征表示。所谓好的Encoder,就是说输入图像,它能学会并抽取出关键特征,这个过程跟Bert模型通过MLM自监督预训练其实目的相同,只是做法有差异。学好Encoder后,可以在解决下游具体任务的时候,用学到的参数初始化Encoder中的ResNet模型,用下游任务标注数据来Fine-tuning模型参数,期待预训练阶段学到的知识对下游任务有迁移作用。由此可见,SimCLR看着有很多构件,比如Encoder、Projector、图像增强、InfoNCE损失函数,其实我们最后要的,只是Encoder,而其它所有构件以及损失函数,只是用于训练出高质量Encoder的辅助结构。目前所有对比学习模型都是如此,这点还请注意。
上面在介绍SimCLR时遗留了个问题:在将增强图像投影到表示空间过程中,我们做了两次非线性映射,分别是Encoder 和Projector,为什么要做两次投影变换呢?看上去貌似没有道理,这其实是个经验结果。Moco在做特征表示投影时只有基于ResNet 的Encoder,并未后跟Projector,其实这么做才是符合直觉的做法,而Projector是在后续的SimCLR模型中提出的。实验证明,加上这个Projector对于提升模型效果改进很明显,这从经验角度说明两次投影变换是必须的。
SimCLR论文中,对于Projector和Encoder的编码差异进行了对比实验,结论是:Encoder后的特征表示,会有更多包含图像增强信息在内的细节特征,而这些细节信息经过Projector后,很多被过滤掉了。虽然为何需要两次非线性变换,目前只有实验结果,并未有理论解释。我个人猜测,可能是如下原因:我们知道,一般的特征抽取器,在做特征提取的时候,底层偏向抽取通用的低层特征,往往与任务无关,通用性强;接近比如分类任务的高层网络结构,更倾向编码任务相关的高阶特征信息。想来,Encoder和Projector也应该如此,也就是说,在接近任务的高层网络,也就是Projector,会编码更多跟对比学习任务相关的信息,低层就是Encoder,会编码更多跟任务无关的通用细节信息。对于下游任务,这种对比学习训练任务相关的特征,可能会带来负面影响。如果映射网络只包含Encoder的话,那么特征表示里会有很多预训练任务相关特征,会影响下游任务效果;而加上Projector,等于增加了网络层深,这些任务相关特征就聚集在Projector,此时Encoder则不再包含预训练任务相关特征,只包含更通用的细节特征。这是为何需要两次映射过程,我猜大致是这个原因,但也纯属无依据猜测,不保证正确性。
要说SimCLR最大的贡献,我个人觉得有两个:一个是证明了复合图像增强很重要;另外一个就是这个Projector结构。这两者结合,给对比学习系统带来很大的性能提升,将对比学习性能提升到或者超过了有监督模型,在此之后的对比学习模型,基本都采取了Encoder+Projector的两次映射结构,以及复合图像增强方法。
上面是以SimCLR为代表的典型负例对比学习系统的要点,在介绍其它对比学习模型之前,我们下面先更深入地理解对比学习工作机理,这样能更透彻了解其它对比学习系统。
秘境召唤:对比学习到底在干什么 前文有述,对比学习在做特征表示相似性计算时,要先对表示向量做L2正则,之后再做点积计算,或者直接采用Cosine相似性,为什么要这么做呢?现在很多研究表明,把特征表示 θ θ 映射到单位超球面上,有很多好处。这里有两个关键,一个是单位长度,一个是超球面。首先,相比带有向量长度信息的点积,在去掉长度信息后的单位长度向量 θ θ θ θ 上操作,能增加深度学习模型的训练稳定性。另外,当表示向量 θ θ 被映射到超球面上,如果模型的表示能力足够好,能够把相似的例子(比如带有相同类标号的数据)在超球面上聚集到较近区域,那么很容易使用线性分类器把某类和其它类区分开(参考上图)。在对比学习模型里,对学习到的表示向量 θ θ 进行L2正则,或者采用Cosine相似性,就等价于将表示向量 θ θ 投影到了单位超球面上进行相互比较。很多对比学习模型相关实验也证明了:对表示向量进行L2正则能提升模型效果。这是为何一般要对表示向量进行L2正则操作的原因。
1. 什么是supervisor superviosr是一个Linux/Unix系统上的进程监控工具,他/她upervisor是一个Python开发的通用的进程管理程序,可以管理和监控Linux上面的进程,能将一个普通的命令行进程变为后台daemon,并监控进程状态,异常退出时能自动重启。不过同daemontools一样,它不能监控daemon进程。
各个微服务的开发过程中,都是使用 Flask 自带的 server 来运行应用。在正式部署的时候,需要使用性能更好的专业 WSGI 容器来运行应用。所以选择superviosr,在每个服务的 app 里已经添加了使用 gevent 的 WSGIServer 来运行应用的代码。
2. 为什么用supervisor 使用简单
supervisor提供了一种统一的方式来start、stop、monitor你的进程, 进程可以单独控制,也可以成组的控制。你可以在本地或者远程命令行或者web接口来配置Supervisor。
在linux下的很多程序通常都是一直运行着的,一般来说都需要自己编写一个能够实现进程start/stop/restart/reload功能的脚本,然后放到/etc/init.d/下面。但这样做也有很多弊端,第一我们要为每个程序编写一个类似脚本,第二,当这个进程挂掉的时候,linux不会自动重启它的,想要自动重启的话,我们还要自己写一个监控重启脚本。
而supervisor则可以完美的解决这些问题。supervisor管理进程,就是通过fork/exec的方式把这些被管理的进程,当作supervisor的子进程来启动。这样的话,我们只要在supervisor的配置文件中,把要管理的进程的可执行文件的路径写进去就OK了。第二,被管理进程作为supervisor的子进程,当子进程挂掉的时候,父进程可以准确获取子进程挂掉的信息的,所以当然也就可以对挂掉的子进程进行自动重启,当然重启还是不重启,也要看你的配置文件里面有木有设置autostart=true了。
supervisor通过INI格式配置文件进行配置,很容易掌握,它为每个进程提供了很多配置选项,可以使你很容易的重启进程或者自动的轮转日志。
集中管理
supervisor管理的进程,进程组信息,全部都写在一个ini格式的文件里就OK了。而且,我们管理supervisor的时候的可以在本地进行管理,也可以远程管理,而且supervisor提供了一个web界面,我们可以在web界面上监控,管理进程。 当然了,本地,远程和web管理的时候,需要调用supervisor的xml_rpc接口,这个也是后话。
supervisor可以对进程组统一管理,也就是说咱们可以把需要管理的进程写到一个组里面,然后我们把这个组作为一个对象进行管理,如启动,停止,重启等等操作。而linux系统则是没有这种功能的,我们想要停止一个进程,只能一个一个的去停止,要么就自己写个脚本去批量停止
3. supervisor组件 supervisord
主进程,负责管理进程的server,它会根据配置文件创建指定数量的应用程序的子进程,管理子进程的整个生命周期,对crash的进程重启,对进程变化发送事件通知等。同时内置web server和XML-RPC Interface,轻松实现进程管理。。该服务的配置文件在/etc/supervisor/supervisord.conf。
supervisorctl
客户端的命令行工具,提供一个类似shell的操作接口,通过它你可以连接到不同的supervisord进程上来管理它们各自的子程序,命令通过UNIX socket或者TCP来和服务通讯。用户通过命令行发送消息给supervisord,可以查看进程状态,加载配置文件,启停进程,查看进程标准输出和错误输出,远程操作等。服务端也可以要求客户端提供身份验证之后才能进行操作。
Web Server
superviosr提供了web server功能,可通过web控制进程(需要设置[inethttpserver]配置项)。
XML-RPC Interface
XML-RPC接口, 就像HTTP提供WEB UI一样,用来控制supervisor和由它运行的程序。
4. 安装、配置、使用 supervisor是python编写的,可以用easy_install、pip都可以安装,比如在我的centos机器下,安装命令如下:
yum install python-setuptools easy_install pip pip install superviso 在这里我使用pip安装之后,在创建配置文件的时候出错,所以我又选择了使用easy_install supervisor的安装方法
当然也可以下载源码进行安装,比如:
wget https://pypi.python.org/packages/source/s/supervisor/supervisor-3.1.3.tar.gz --no-check-certificat tar -zxvf supervisor-3.1.3.tar.gz cd supervisor-3.1.3 sudo python setup.
目前看到大多数博客几乎都是说是没有在应用设置回调地址锁引起的,但是我再三确认我的回调地址已填写,并且跳转连接中的地址与其一直,就像下面
页面上的调用地址为:
https://api.weibo.com/oauth2/authorize?client_id=2121452623&response_type=code&redirect_uri=http://auth.mymall.com/oauth2.0/weibo/success 但是一直返回出错结果:错误码:21322 重定向地址不匹配
有时候浏览器中显示的地址是编码过的,不容易判断回调地址是否设置的正确无误
并且提供了一个 在线url转换工具在线URL编码解码工具-UrlEncode编码-UrlDecode解码在线工具 (jsons.cn),可以把浏览器中的地址转换成正常的形式,或者把原地址转为浏览器编码后的格式
我的原地址是 : http://auth.mymall.com/oauth2.0/weibo/success 转换后是:http%3A%2F%2Fauth.mymall.com%2Foauth2.0%2Fweibo%2Fsuccess https://api.weibo.com/oauth2/authorize?client_id=2121452623&response_type=code&redirect_uri=http%3A%2F%2Fauth.mymall.com%2Foauth2.0%2Fweibo%2Fsuccess 然后再次点击,成功出现以下页面
MySQL军规适应的业务场景
互联网前台业务数据量较大并发量较大 在适应业务场景之下,系统
响应时间,吞吐量,扩展性优先数据库往往最容易成为系统瓶颈 解放数据库,降数据库磁盘IO,将数据库CPU成为架构设计的核心方向之一
如何降低数据库磁盘IO
读多写少用缓存前台与后台分离架构最优质的SQL只让数据库做它擅长的事情:存储和索引,少干其它事情大对象,原则上不要存储在数据库里 如何降低数据库CPU计算
数据库非必须的CPU计算,尽量挪到服务处去处理禁止使用外键约束,由服务保障完整性禁止使用存储过程,视图,触发器,event 如何降低磁盘IO+CPU计算
尽量不使用join,如果要用,必须保证字符集属性类型与长度相同,并且要建立索引禁止负向查询,与%开头的模糊查询字段类型,与查询字段赋值类型必须相同禁止在列上进行函数或表达式计算字段必须定义为not null,并提供默认值联合索引,区分度最高的放在最左边联合索引,列个数不要超过5个 以上是MySQL军规的主要内容,还有部分知识点,没有列出来。这个是针对MySQL的军规,实际上在oracle、postgresql等关系型数据库中都有一定的通用性,所以记录下来。希望对看到的你有所帮助。
灰度发布(金丝雀发布) 只升级部分服务,即让一部分用户继续用老版本,一 部分用户开始用新版本,如果用户对新版本没有什么 意见,那么逐步扩大范围,把所有用户都迁移到新版 本上面来。
特点:
• 保证整体系统稳定性
• 用户无感知,平滑过渡
缺点:
• 自动化要求高
灰度发布(A/B Test) 灰度发布的一种方式,主要对特定用户采样后,对收 集到的反馈数据做相关对比,然后根据比对结果作出 决策。用来测试应用功能表现的方法,侧重应用的可 用性,受欢迎程度等,最后决定是否升级。
这种发布方式主要是面向业务功能侧的发布,比如部分用户能进行新版本体验等。
Istio 实现灰度发布 实现灰度发布前,我们先熟悉虚拟服务(VirtualService),目标规则(destination rule),deployment/service,之间的标签指向联系,如下所示:
1、其中VirtualService配置中的“host:reviews”对应destination rule配置中的“host:reviews”,
2、其中VirtualService配置中的“subset:v1"对应destination rule配置中的"subsets: -name:v1",他对应destination rule中的服务子集,有了subset就会用到DestinationRule。
3、其中destination rule配置中的“host:reviews”对应k8s中k8s中的service “reviews”,对应的是规则作用的istio注册表中的服务(svc)
4、destination rule配置中的"labels: version:v1"对应k8s中的deployment中的”- version:v1"。对应的subset1,将流量转发到具有标签version:v1的deployment对应的服务上。
基于权重的路由(灰度发布) 任务1:流量全部发送到reviews v1版本(不带五角星)
任务2:将90%的流量发送到reviews v1版本,另外10%的流 量发送到reviews v2版本(5个黑色五角星),最后完 全切换到v2版本
任务3:将50%的流量发送到v2版本,另外50%的流量发送到 v3版本(5个红色五角星)
任务1 流量全部发送到reviews v1版本(不带五角星)
1、查看虚拟服务VirtualService配置文件
[root@master networking]# cat virtual-service-all-v1.yaml apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: productpage spec: hosts: - productpage http: - route: - destination: host: productpage subset: v1 --- apiVersion: networking.
idea 取消拼写检查 2021版 file -> Settings… -> proofreading -> typo -> 取消勾选 -> apply
文章目录 安装opencv安装完后,把libfacedetection项目下载下来编译安装下载模型 测试树莓派上面使用问题 安装opencv 版本要求>=4.5.1
opencv安装教程
在安装完后,一定要进行最后一步
实验一下自己的摄像头是否能够正常工作
安装完后,把libfacedetection项目下载下来 项目链接
下载链接
或者你在项目上用git拉下来也是可以的
编译安装 将下载好的包解压进入目录
mkdir buildcd buildcmake .. -DCMAKE_INSTALL_PREFIX=install -- DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=Release -DDEMO=OFFcmake --build . --config Releasecmake --build . --config Release --target install进入示例文件目录cd example/opencv_dnn/cpp/
mkdir buildcd buildcmake .. -DDEMO=ON -DOpenCV_DIR='/usr/local/lib'cd ..make
到这一步就编译完成了 下载模型 下载链接
然后将其放在cpp那个文件下面
测试 通过命令
./detect-camera 0 ./YuFaceDetectNet.onnx
树莓派上面使用 树莓派上面使用的时候,步骤和上述一样(在树莓派上面编译),只不过只在于有个错误需要注意
就是在编译libfacedetection库的时候需要将
然后正常使用后续步骤即可
问题 在aarch64的ARM处理器上编译NEON程序,出现如下错误:
编译加入选项-mfpu=neon
arm平台将这个打开
【问题描述】 从键盘上输入2个正整数,计算这两个正整数的最小公倍数或者最大公约数。其中输入1时,输出两个正整数的最大公约数;如果输入是2,输出两个正整数的最小公倍数。
【输入形式】 第一行,两个正整数,中间用空格隔开。第二行一个整数,表述选择项。
【输出形式】 一个整数,表示输入数据的最小公倍数或者最大公约数。
【样例输入】 12 18 2 【样例输出】 36 【题目代码】 #include<bits/stdc++.h> using namespace std; int i=1,j=1; void f2(int a,int b) { if(a*i==b*j) cout<<a*i; else if(a*i>b*j) { j++; f2(a,b); } if(a*i<b*j) { i++; f2(a,b); } } void f1(int a,int b) { int i,n; n=min(a,b); for(i=n;i>0;i--) { if(b%i==0&&a%i==0) { cout<<i; break; } } } int main() { int n,a,b; cin>>a>>b>>n; if(n==1) f1(a,b); else f2(a,b); return 0; }
先引入jquery.signature.js (css样式代码就没贴了) 数据库保存字段是:mediumtext类型
<script src="jquery/1.11.0/jquery.min.js"></script> <script src="jq-signature.js"></script> //前端页面代码 <div class="signature_con"> <div class="signature" id="signatureId" style="width:400px; height:200px;"></div> </div> <div class="signaturebutton_con"> <button type="button" name="btnSignatureClear" id="btnSignatureClear" onclick="doSignatureClear(); return false;">清空签名板</button> </div> //js代码 //初始化签名板 var signature= $("#signatureId").jSignature({height:"200px",width:"400px"}); var signatureImgContent = $("#editForm input[id='signatureImgContent']").val(); if (!_isEmpty(signatureImgContent)){ signature.jSignature("setData",signatureImgContent); } //清空画布 function doSignatureClear() { signature.jSignature('reset'); } //验证签名是否为空 function isBlank(signatureData) { var blank= $("#blankId").jSignature({height:"200px",width:"400px"}); return signatureData == blank.jSignature('getData', 'default');//比较值相等则为空 } if (isBlank(signature.jSignature("getData", 'default'))) { showPopBox(0, "入库人签名不能为空!", function() {}); return false; } //获取画布里面的值并赋值 var dataImg = signature.
如图,后端传来的数据是0,1 我们需要把数组展示为 ‘是’,‘否’
关键代码(html):
<el-table-column prop="sf" label="是否参数代理" align="center"> <template slot-scope="scope">{{ scope.row.sf | csdlFilter }}</template> </el-table-column> (js):
filters: { csdlFilter(val){ if(val == '0'){ return '否' }else if(val == '1'){ return '是' }else{ return '-' } } }
使用flink on yarn方式提交Flink sql,抛出如下异常
org.apache.flink.client.program.ProgramInvocationException: The main method caused an error: Unable to instantiate java compiler at org.apache.flink.client.program.PackagedProgram.callMainMethod(PackagedProgram.java:335) at org.apache.flink.client.program.PackagedProgram.invokeInteractiveModeForExecution(PackagedProgram.java:205) at org.apache.flink.client.ClientUtils.executeProgram(ClientUtils.java:138) at org.apache.flink.client.cli.CliFrontend.executeProgram(CliFrontend.java:664) at org.apache.flink.client.cli.CliFrontend.run(CliFrontend.java:213) at org.apache.flink.client.cli.CliFrontend.parseParameters(CliFrontend.java:895) at org.apache.flink.client.cli.CliFrontend.lambda$main$10(CliFrontend.java:968) at java.security.AccessController.doPrivileged(Native Method) at javax.security.auth.Subject.doAs(Subject.java:422) at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1628) at org.apache.flink.runtime.security.HadoopSecurityContext.runSecured(HadoopSecurityContext.java:41) at org.apache.flink.client.cli.CliFrontend.main(CliFrontend.java:968) Caused by: java.lang.IllegalStateException: Unable to instantiate java compiler at org.apache.calcite.rel.metadata.JaninoRelMetadataProvider.compile(JaninoRelMetadataProvider.java:434) at org.apache.calcite.rel.metadata.JaninoRelMetadataProvider.load3(JaninoRelMetadataProvider.java:375) at org.apache.calcite.rel.metadata.JaninoRelMetadataProvider.lambda$static$0(JaninoRelMetadataProvider.java:109) at org.apache.flink.calcite.shaded.com.google.common.cache.CacheLoader$FunctionToCacheLoader.load(CacheLoader.java:149) at org.apache.flink.calcite.shaded.com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3542) at org.apache.flink.calcite.shaded.com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2323) at org.apache.flink.calcite.shaded.com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2286) at org.apache.flink.calcite.shaded.com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2201) at org.apache.flink.calcite.shaded.com.google.common.cache.LocalCache.get(LocalCache.java:3953) at org.apache.flink.calcite.shaded.com.google.common.cache.LocalCache.getOrLoad(LocalCache.java:3957) at org.
做的专栏已经积累几百的收益了,去除掉csdn 的分成就剩下一点了。开始做博客只是为了记录,后面有目的的去分享,中间真的帮助了一些人,对于额外剩余的这部分收益准备做点公益了,国内的组织就算了,不太敢信。个人每年都会想联合国儿童基金会捐,感觉更加靠谱一些,并且也有中国的项目,钱也算用在了同胞手里。
先提现100 捐掉,后面不定时的继续将所有收益都捐到这个基金会。
性能测试的结果统计时我们一定会关注TPS,TPS代表的是每秒事务数,每个事务对应的是我们的请求。虽然JMeter能够帮我们把每个请求统计成一个事务,但有时候我们希望把多个操作统计成一个事务,JMeter也考虑到了这种需求,我们可以用个逻辑控制器中的事务控制器来完成。
一、添加事务控制器 二、事务控制器参数说明 Generate parent sample:如果事务控制器下有多个取样器,勾选它,那么在“擦看结果树”中我们不仅可以看到事务控制器,还可以看到每个取样器,并且事务控制器定义的事务是否成功取决于子事务是否都成功,子事务其中任何一个失败即代表整个事务失败。 Include duration of timer and pre-post processors in generated sample:是否包括定时器、预处理和后期处理延迟的时间 三、运用事务控制器 运行时,需要将要控制的取样器放在事务控制器之下
一 pom.xml配置如下: <profiles> <profile> <id>dev</id> <properties> <spring.profiles.active>dev</spring.profiles.active> </properties> <activation> <activeByDefault>true</activeByDefault> </activation> </profile> <profile> <id>prd</id> <properties> <spring.profiles.active>prd</spring.profiles.active> </properties> </profile> </profiles> 二 配置application.yml application.yml中先配置一些公共的部分,然后配置需要分开的部分:
spring: profiles: active: @spring.profiles.active@ logging: config: "classpath:logback-@spring.profiles.active@.xml" file: "logs/wsc-super-miner.log" pattern: console: "[%d{yyyy-MM-dd HH:mm:ss.SSS}] %-5level [%t] [%logger - %line]: %m%n" file: "[%d{yyyy-MM-dd HH:mm:ss.SSS}] %-5level [%t] [%logger - %line]: %m%n" level: root: INFO 三 创建不同的配置文件 现在profile环境有dev和prd,需要创建文件 application-dev.yml、application-prd.yml和日志配置文件logback-dev.xml、logback-prd.xml,springboot的配置我需要分开的有mysql、redis还有端口,所以application-dev.yml如下:
spring: redis: host: 127.0.0.1 port: 6379 password: lettuce: pool: max-active: 16 max-idle: 16 min-idle: 1 # mysql datasource: url: "
发布项目到服务器并访问 创建Web项目,开发静态页面
部署到服务器Tomcat
启动服务器Tomcat
不同用户通过浏览器来访问Web项目
Web项目和Java项目的区别 Web项目需要JavaEE的类库
Web项目中还可以存放静态网页和动态网页
开发目录和部署目录的区别 开发目录(工作空间)
部署目录(运行目录)(Tomcat服务器)
理解示意图 TomCat 打印日志控制台乱码 https://www.cnblogs.com/yanglichen/p/11435628.html
404错误: [1] 项目没有发布到服务器上
[2] 项目发布了,但是服务器没有启动/控制台报错
[3] 访问路径写错了
获得服务器时间和浏览器时间 <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'time.jsp' starting page</title> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> <!--js方式获得时间是浏览器客户端的时间 --> <script type="text/javascript"> function getTime(){ var date=new Date(); var time =date.
在OpenCV中保存视频使用的是VedioWriter对象,在其中指定输出文件的名称,如下所示:
1.创建视频写入的对象 out = cv2.VideoWriter(filename,fourcc, fps, frameSize) 参数:
filename:视频保存的位置fourcc:指定视频编解码器的4字节代码fps:帧率frameSize:帧大小 2.设置视频的编解码器,如下所示, retval = cv2.VideoWriter_fourcc( c1, c2, c3, c4 ) 参数:
c1,c2,c3,c4: 是视频编解码器的4字节代码,在fourcc.org中找到可用代码列表,与平台紧密相关,常用的有:
在Windows中:DIVX(.avi)在OS中:MJPG(.mp4),DIVX(.avi),X264(.mkv)。 3.获取摄像头 利用cap.read()获取摄像头中的每一帧图像,并使用out.write()将某一帧图像写入视频中。
4.释放资源 使用cap.release()和out.release()释放资源。
import cv2 as cv # 1. 读取摄像头 cap = cv.VideoCapture(0) # 2. 获取图像的属性(宽和高,),并将其转换为整数 frame_width = int(cap.get(3)) frame_height = int(cap.get(4)) # 3. 创建保存视频的对象,设置编码格式,帧率,图像的宽高等 out = cv.VideoWriter('outpy.avi', cv.VideoWriter_fourcc('M', 'J', 'P', 'G'), 10, (frame_width, frame_height)) # 保存视频 while(True): # 4.获取视频中的每一帧图像 ret, frame = cap.read() if ret == True: # 5.
快速复制一行 快捷键: shift+alt+ 下箭头(上箭头) 或者 ctrl+c 然后 ctrl+v
选定多个相同的单词 快捷键: ctrl + d
先双击选定一个单词,然后按下 ctrl + d 可以往下依次选择相同的单词。 这样同时修改相同的单词就非常方便
添加多个光标 快捷键: Ctrl + Alt + 上箭头(下箭头)
全局替换某写单词 当我们一个页面需要修改大量相同的文字的时候,我们一个的修改超级麻烦,此时我们可以使用全局替换
快捷键: ctrl + h 注意选择全部替换即可
快速定位到某一行 当我们页面比较长的时候,上下滚动页面布方便,其实我们可以利用快捷键,快速的调到指定的行数上。
快捷键: ctrl + g
选择某个区块 可以选择一个区块进行操作
快捷键: 按住shift + alt 然后拖动鼠标
放大缩小整个编辑器界面 快捷键: ctrl + + / - ctrl + 加号或者减号
自定义快捷键 有些快捷键,我们使用不习惯,其实我们可以自定义快捷键的。
比如js 的多行注释是 shift + alt + a ,我们想修改为 ctrl + shfit + /
【前言】:MySQL本地环境有2个库,mydb和mysql;其中mydb中有tb1和tb2,为父子关系。在mydb的上下文环境下,试玩RENAME TABLE的时候,意在将mydb的tb1移到mysql中,SQL语句如下:
RENAME TABLE tb1 TO mysql.tb1; 在检查成功移到mysql后,无意间将tb1删除了。。。
在事先没有通过navicat手动备份(稳妥姿势如下图)的前提下,如何还原tb1及数据,保持测试父级数据在后续过程使用的便捷性,成了当下一个头痛的问题。这也就成了我后续写这边博客的初心。
【数据恢复方式】:
当数据丢失后,已知恢复方式有2种:
#1. 从备份的数据中恢复;
在探究Navicat GUI备份本质的时候,我们不难通过下图提取出来的用于备份的SQL中看出脚本的3个过程:
a. 删除现存的表 (数据随之被删除);
b. 创建备份的表;
c. 插入备份数据;
#2. 从binlog中恢复;
结合本文的背景,接下来将通过DEMO重点介绍通过binlog恢复的过程。
【实战演练】:
案例设计与过程:在mydb中创建test_binlog表 -> 插入4条记录 -> 删除表 -> 表与数据恢复。
/* 数据恢复实操210426 */ -- ***** 01. 预处理 ***** -- -- 查看数据库是否开启binlog日志及所在位置 show variables like '%log_bin%'; -- 查看所有二进制日志列表 show master logs; -- 结束当前日志,开启一个新的日志并查看正在使用的二进制日志 flush logs; show master status; -- - satrt position /* LAPTOP-6301VV5L-bin.000005 155 */ -- ***** 02.
Centos8已经不支持NTP服务改用chrony服务 1.配置时间同步服务器地址 vim /etc/chrony.conf # Use public servers from the pool.ntp.org project. # Please consider joining the pool (http://www.pool.ntp.org/join.html). #pool 2.centos.pool.ntp.org iburst server ntp.api.bz iburst server ntp.aliyun.com iburst # Record the rate at which the system clock gains/losses time. driftfile /var/lib/chrony/drift #注释默认的时间同步服务器pool 2.centos.pool.ntp.org iburst, #添加新的时间同步服务器server ntp.api.bz iburst server ntp.aliyun.com iburst 2.重启chrony服务,查看状态 systemctl restart chronyd chronyc sources -v timedatectl status 3.设置chrony开机自启 systemctl enable chronyd