mmap 内存映射详解

目录 mmap基础概念 mmap内存映射原理 mmap示例代码 mmap和常规文件操作的区别 mmap使用的细节 前言 原文对 mmap 内存映射已经表述的很清楚了,我只是在原文的基础上,附上了 mmap 代码实例。 mmap基础概念 mmap是一种内存映射的方法,这一功能可以用在文件的处理上,即将一个文件或者其它对象映射到进程的地址空间,实现文件磁盘地址和进程虚拟地址空间中一段虚拟地址的一一对映关系。在编程时可以使某个磁盘文件的内容看起来像是内存中的一个数组。如果文件由记录组成,而这些记录又能够用结构体来描述的话,可以通过访问结构数组来更新文件的内容。 实现这样的映射关系后,进程就可以采用指针的方式读写操作这一段内存,而系统会自动回写脏页面到对应的文件磁盘上,即完成了对文件的操作而不必再调用read,write等系统调用函数。内核空间对这段区域的修改也直接反映用户空间,从而可以实现不同进程间的文件共享。如图所示: 进程的虚拟地址空间,由多个虚拟内存区域构成。虚拟内存区域是进程的虚拟地址空间中的一个同质区间,即具有同样特性的连续地址范围。上图中所示的text数据段(代码段)、初始数据段、BSS数据段、堆、栈和内存映射,都是一个独立的虚拟内存区域。而为内存映射服务的地址空间处在堆栈之间的空余部分。 内核为系统中的每个进程维护一个单独的任务结构(task_struct)。任务结构中的元素包含或者指向内核运行该进程所需的所有信息(PID、指向用户栈的指针、可执行目标文件的名字、程序计数器等)。Linux内核使用vm_area_struct结构来表示一个独立的虚拟内存区域,由于每个不同质的虚拟内存区域功能和内部机制都不同,因此一个进程使用多个vm_area_struct结构来分别表示不同类型的虚拟内存区域。各个vm_area_struct结构使用链表或者树形结构链接,方便进程快速访问,如下图所示: vm_area_struct结构中包含区域起始和终止地址以及其他相关信息,同时也包含一个vm_ops指针,其内部可引出所有针对这个区域可以使用的系统调用函数。这样,进程对某一虚拟内存区域的任何操作需要用要的信息,都可以从vm_area_struct中获得。mmap函数就是要创建一个新的vm_area_struct结构,并将其与文件的物理磁盘地址相连。 mm_struct:描述了虚拟内存的当前状态。pgd指向一级页表的基址(当内核运行这个进程时, pgd会被存放在CR3控制寄存器,也就是页表基址寄存器中),mmap指向一个vm_area_structs 的链表,其中每个vm_area_structs都描述了当前虚拟地址空间的一个区域。 vm_starts 指向这个区域的起始处。 vm_end 指向这个区域的结束处。 vm_prot 描述这个区域内包含的所有页的读写许可权限。 vm_flags 描述这个区域内的页面是与其他进程共享的,还是这个进程私有的以及一些其他信息。 vm_next 指向链表的下一个区域结构。 mmap内存映射原理 mmap内存映射的实现过程,总的来说可以分为三个阶段: (一)进程启动映射过程,并在虚拟地址空间中为映射创建虚拟映射区域 1. 进程在用户空间调用库函数mmap,原型:void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset); 2. 在当前进程的虚拟地址空间中,寻找一段空闲的满足要求的连续的虚拟地址。 3. 为此虚拟区分配一个vm_area_struct结构,接着对这个结构的各个域进行了初始化。 4. 将新建的虚拟区结构(vm_area_struct)插入进程的虚拟地址区域链表或树中。 (二)调用内核空间的系统调用函数mmap(不同于用户空间函数),实现文件物理地址和进程虚拟地址的一一映射关系 5. 为映射分配了新的虚拟地址区域后,通过待映射的文件指针,在文件描述符表中找到对应的文件描述符,通过文件描述符,链接到内核“已打开文件集”中该文件的文件结构体(struct file),每个文件结构体维护着和这个已打开文件相关各项信息。 6. 通过该文件的文件结构体,链接到file_operations模块,调用内核函数mmap,其原型为:int mmap(struct file *filp, struct vm_area_struct *vma),不同于用户空间库函数。 7. 内核mmap函数通过虚拟文件系统inode模块定位到文件磁盘物理地址。 8. 通过remap_pfn_range函数建立页表,即实现了文件地址和虚拟地址区域的映射关系。此时,这片虚拟地址并没有任何数据关联到主存中。

单细胞分析R包monocle3服务器安装教程

单细胞分析R包monocle3服务器安装教程(全程踩坑) 跟着官网教程走,可很多意外发现 运行程序安装BiocManager=3.10版本,必须为该版本,否则会出现问题 if (!requireNamespace("BiocManager", quietly = TRUE)) install.packages("BiocManager") BiocManager::install(version = "3.10") 经过漫长的等待,终于安装完成。这步还好,没啥比较坑的地方。 接着利用BiocManager安装相应的依赖包,由于这些包的特殊性,所以不要切换到国内Bio_Mirror镜像,否则会找不到,如果一次不成功,缺啥补啥即可。 BiocManager::install(c('BiocGenerics', 'DelayedArray', 'DelayedMatrixStats', 'limma', 'S4Vectors', 'SingleCellExperiment', 'SummarizedExperiment', 'batchelor', 'Matrix.utils')) monocle3的安装是通过cole-trapnell-lab安装的,该包挂在github上,需要通过github先安装leidenbase包,需要提前安装devtools包下载工具。 install.packages("devtools") 安装github的R包时,可能提示下载失败,因为网络经常会断流,稍后多试几次即可。 安装过程最大的问题是安装sf依赖包gdal库的依赖问题。由于centos7系统yum只能安装到低版本gdal,而monocle3依赖包需要 gdal>2 版本,从gdal官网下载2.4.4版本编译安装。 如果gdal找不到,则将 /usr/local/lib 追加到 /etc/ld.so.conf.d/libgdal-x86_64.conf 配置文件中。 #echo "/usr/local/lib" >> /etc/ld.so.conf.d/libgdal-x86_64.conf 运行 ldconfig #ldconfig 但是又会有新的报错,缺乏prog库,通过yum安装prog库即可解决。 确保系统上安装了GEOS、GDAL和PROJ。 #yum install proj.x86_64 proj-devel.x86_64 proj-epsg.x86_64 proj-nad.x86_64 geos* 安装sf包 install.packages("sf") 经过这么多预备工作,终于到了我们的安装主角monocle3。同样,是利用github安装。 devtools::install_github('cole-trapnell-lab/monocle3') 至此,monocle3安装成功。

VS2019配置QT5.12.3

新手VS2019配置QT采坑记录 1、QT下载 推荐下载Qt5.12.3版本(5.12为LTS长期支持版本),官方下载速度较慢,建议采用镜像源下载:https://mirrors.tuna.tsinghua.edu.cn/qt/archive/qt/5.12/5.12.3/; 2、QT安装 下载完成后进行安装,注意一开始提示需要注册qt账号。 此外,需要勾选一些常用的组件: 然后是漫长的等待过程,大约10分钟左右。 3、安装VS2019插件 在VS2019中配置插件:拓展->管理拓展->联机->搜索Qt,下载并安装。注意安装完成后需要重启VS。 如果因为网络原因,插件下载不了,也可以去微软官方下载: https://marketplace.visualstudio.com/items?itemName=TheQtCompany.QtVisualStudioTools2019 在安装插件时如果出现以下报错,检查自己的vs2019是否是更新暂停状态!!! 4、配置qt插件 进人vs2019后,在扩展下面选择Qt VS Tools->Qt Options,然后进行qt配置: 5、大功告成 然后就可以使用qt了: 备注:后面会出一遍简单的教程实现vs2019+qt完成开发简单页面。

最长单调递增子序列——动态规划算法

题目简介 最长单调递增子序列是一个很经典的问题,他所需要的就是要在整个序列中(序列一般来讲应该是无序的)寻找出一个最长的升序子序列,这个子序列中的所有元素都必须来自这个原序列,它们可以在原序列中是不相邻的,但是它们之间的相对位置是不可以改动的。比如一个序列: (1, 7, 3, 5, 9, 4, 8) 它有一些上升子序列,如(1, 7), (3, 4, 8)等等。在这些子序列中,长度最长的子序列的长度为4,比如(1,3,5,9)或者(1,3,5,8),这两个都是最长的升序子序列,所以对于一个给定的序列,它的最长升序子序列可能不唯一,在本题目中我们不考虑列举出所有的最长升序子序列,我们只考虑如何找出最长升序子序列的长度。 穷举法?过于复杂 没错,很多问题在穷举法面前都能做到实现,穷举法最强大的优点就在于它实在是太普适了,我们完全可以用穷举法把所有的升序子序列全部找出来,然后找到元素最多的子序列,将长度进行输出,但是这么做带来的弊端就是太过于复杂,如果原序列本身就是一个严格单调递增的子序列,那用穷举法所需要的的时间就是2^n,这个速度有些拉跨,或者说过于拉胯。 转化为最长公共子序列问题?是个妙招 关于最长公共子序列的问题我再之后会继续更新博客,现在我们只是将它看作一个已经写好的算法,这个算法的本质就是寻找两个序列A,B它们之间最长的公共子序列,这个公共子序列的每一个元素必须既存在于A,也存在与B,它们之间可以不相邻,但是他们的相对顺序不能改变,这些要求都和最长公共子序列的要求基本一致,只是没有升序的要求,那么我们怎么把升序的要求加到这个公共子序列算法中呢? 没错,我们可以先把原序列进行排序。存储到B序列中,A序列(原序列)和B序列(排序后的序列)这两个序列再进行最长公共子序列问题的求解,这样求解出来的最长公共子序列就是原序列的最长递增子序列了。 单独考虑-动态规划 其实最长公共子序列的本质我们也是根据动态规划的想法进行计算的。在这里我们只考虑单调递增子序列的独立问题求解方法。 我们可以发现这个问题具有最优子结构性质,也就是说我们可以把这个问题拆分成若干个存在重复情况的子问题进行求解。 如果我们想查找序列1,7,3,5,9,4,8的最长公共子序列,可以划分为寻找1,7,3,5,9,4的最长公共子序列(在这里称作子问题1),末尾再加上8,看前面的子问题1中获得的最长公共子序列答案最后一个元素是否小于8,如果小于8,那么原问题的解就是子问题1的解后面加上8,如果子问题1的解最后一个元素大于8,那么原问题的解就是子问题1的解。如果存在两个相同长度的解,并且一个最后元素大于8,一个小于8,那么我们便选择小于8的解最后在加上8即可。 状态转移方程如下(dp[i]代表以第i个元素结尾的升序序列长度为多少): dp[i] = dp[j]+1(如果存在i前面的一个j,满足src[j] < src[i] 且 dp[j] > dp[i]-1) dp[i] = dp[i] (如果前面存在一个j,满足src[j] < src[i] 但是 dp[j] <= dp[i]-1) dp[i] = 1 (如果前面所有的元素都大于第i个元素,以及初始化数据) 最后由于我们并不知道真正的最长子序列是以哪个元素结尾的,所以我们要找出dp数组中的最大值。 好了,思路大致如上,下面给出代码: //program: finding the longest monotone increasing subsequence //author: William.L lbb@hnu.edu.cn //version: v1.0 #include <iostream> using namespace std; int main(){ int len; cin >> len; int src[len]; for (int i = 0;i < len; i++){ cin >> src[i]; } int endw[len] = {1}; for (int i = 0;i < len; i++){ for (int j = 0; j < i; j++){ if ((src[j] < src[i]) && (endw[j] + 1 > endw[i])){ endw[i] = endw[j] + 1; } } } int maxlen = 1; for (int i = 0;i < len; i++){ if (endw[i] > maxlen){ maxlen = endw[i]; } } cout << maxlen << endl; return 0; }

UART通信协议

硬件连接:通常有三根线,分别为TXD,RXD,GND。通用异步收发传输器(Universal Asynchronous Receiver/Transmitter),通常称作UART。UART通信在工作中相当常见,项目中需要生成uart信号,在博客中记录下。uart是异步通信,因为它只有一根线就可以数据的通信。不像SPI,I2C等同步传输信号。所以串口的传输速度和其它协议的速度相比是比较慢的。下面具体讲解一些uart协议以及是如何通信的。 上图是uart协议传输一个”A”字符通过示波器的uart解码而得到的波形示意图。根据此图来介绍一下uart的一些基本参数。 波特率:此参数容易和比特率混淆,其实他们是由区别的。具体可以百度更清楚。但是我认为uart中的波特率就可以认为是比特率,即每秒传输的位数(bit)。一般选波特率都会有9600,19200,115200等选项。其实意思就是每秒传输这么多个比特位数(bit) 起始位:先发出一个逻辑”0”的信号,表示传输数据的开始。 数据位:可以选择的值有5,6,7,8这四个值,可以传输这么多个值为0或者1的bit位。这个参数最好为8,因为如果此值为其他的值时当你传输的是ASCII值时一般解析肯定会出问题。理由很简单,一个ASCII字符值为8位,如果一帧的数据位为7,那么还有一位就是不确定的值,这样就会出错。 校验位:数据位加上这一位后,使得“1”的位数应为偶数(偶校验)或奇数(奇校验),以此来校验数据传送的正确性。就比如传输“A”(01000001)为例。 1、当为奇数校验:”A”字符的8个bit位中有两个1,那么奇偶校验位为1才能满足1的个数为奇数(奇校验)。图-1的波形就是这种情况。 2、当为偶数校验:”A”字符的8个bit位中有两个1,那么奇偶校验位为0才能满足1的个数为偶数(偶校验)。 此位还可以去除,即不需要奇偶校验位。 停止位:它是一帧数据的结束标志。可以是1bit、1.5bit、2bit的空闲电平。可能大家会觉得很奇怪,怎么会有1.5位~没错,确实有的。所以我在生产此uart信号时用两个波形点来表示一个bit。这个可以不必深究。。。 空闲位:没有数据传输时线路上的电平状态。为逻辑1。 传输方向:即数据是从高位(MSB)开始传输还是从低位(LSB)开始传输。比如传输“A”如果是MSB那么就是01000001(如图-2),如果是LSB那么就是10000010(如下图的图-4) uart传输数据的顺序就是:刚开始传输一个起始位,接着传输数据位,接着传输校验位(可不需要此位),最后传输停止位。这样一帧的数据就传输完了。接下来接着像这样一直传送。在这里还要说一个参数。 帧间隔:即传送数据的帧与帧之间的间隔大小,可以以位为计量也可以用时间(知道波特率那么位数和时间可以换算)。比如传送”A”完后,这为一帧数据,再传”B”,那么A与B之间的间隔即为帧间隔。 两图和下两图传送的数据和波特率都是一样的,但是有几个参数是故意设置反了从而形成对比。有助于更深入的理解UART。

创建临时文件夹

// 创建临时文件夹 String tmpPath = Files.createTempDirectory("pdf-").toString(); System.out.println(tmpPath); File file = new File(tmpPath + File.separator + "new_work_order.pdf"); tmpPath = URLEncoder.encode(tmpPath, "utf-8"); tmpPath = tmpPath.replace("%2F", "%3F");

5G NR协议栈

一、无线协议栈 NR无线协议栈分为两个平面:用户面和控制面。用户面(User Plane, UP)协议栈即用户数据传输采用的协议簇,控制面(Control Plane, CP)协议栈即系统的控制信令传输采用的协议簇。5G NR(New Radio,新空口),基于OFDM(正交频分复用)的全新空口设计的全球性5G标准,也是下一代非常重要的蜂窝移动技术基础,5G技术将实现超低时延、高可靠性。 1.1 用户面 NR用户平面相比LTE协议栈多了一层SDAP层,用户面协议从上到下依次是: SDAP层:Service Data Adaptation ProtocolPDCP层:Packet Data Convergence ProtocolRLC层:Radio Link ControlMAC层:Medium Access ControlPHY层:Physical 1.2 控制面 NR控制面协议几乎与LTE协议栈一模一样,从上到下依次为: NAS层:Non-Access StratumRRC层:Radio Resource ControlPDCP层:Packet Data Convergence ProtocolRLC层:Radio Link ControlMAC层:Medium Access ControlPHY层:Physical UE所有的协议栈都位于UE内。在网络侧,NAS层不位于基站gNB上,而是在核心网的AMF (Access and Mobility Management Function)实体上。控制面协议栈不包含SDAP层。 二、层2功能介绍 NR层2包含SDAP、PDCP、RLC和MAC层。 2.1 MAC层 1、服务和功能 逻辑信道与传输信道之间的映射。复用、解复用。将来自一个或多个逻辑信道的MAC SDU复用到一个传输块并传递给PHY,将从物理层传来的传输块解复用成多个MAC SDU并传递给一个或多个逻辑信道报告调度信息。通过HARQ进行错误纠正。在载波聚合中,每个载波对应一个HARQ实体通过动态调度管理用户间的优先级。逻辑信道优先级管理。填充。 2、逻辑信道 逻辑信道根据传输信息的类型来区分。逻辑信道主要分为两类:控制信道和业务信道。 控制信道用于传输控制平面的信息,包含以下逻辑信道: Broadcast Control Channel (BCCH):用于广播系统控制信息的下行信道Paging Control Channel (PCCH):用于转发寻呼消息和系统信息变更的下行信道Common Control Channel (CCCH):当UE与网络没有建立RRC Connection时,UE与网络间传输控制信息的信道Dedicated Control Channel (DCCH):当UE与网络已经建立RRC Connection时,UE与网络间传输控制信息的一对一信道 业务信道用于传输用户平面的信息,包含以下逻辑信道:

冒泡排序之改进版——C与C++实现

题目:随机产生10个0-9的整数,用冒泡排序改进版对10个数进行排序。(升序) 程序分析: 对于冒泡排序法,如果输入六个数,则需要5趟排序。如果在第3趟排序之后就完成排序,则后2趟排序就没有任何意义。因此,对冒泡排序法进行改进。设置一个标志变量flag,并规定:flag=1时,表示本趟排序中有元素交换;flag=0时,表示本趟排序中没有元素交换。在每一趟排序之前将flag置为0,如果该趟出现元素交换flag置为1,反之flag值不变。这样,便可根据flag的值决定是否要进行 下一趟排序 。 C代码: #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<time.h> void BubbleSort(int a[], int n) { int flag = 1;//flag=1表示未完成排序,flag=0表示已完成排序 for (int i = 0; i < n - 1; i++) { flag = 0; for (int j = 0; j < n - i - 1; j++) { if (a[j] > a[j + 1]) { flag = 1; int temp = a[j]; a[j] = a[j + 1]; a[j + 1] = temp; } } } } void PrintArray(int a[], int n) { for (int j = 0; j < n; j++) { printf("

IDL矢量/掩膜裁剪影像(ENVI API编程)

目录 一、 矢量裁剪1、问题描述2、重定义空间范围2.1定义范围2.2转换到到新的空间范围 3、矢量裁剪实例 二、 掩膜裁剪1、问题描述2、创建掩膜3、裁剪影像4、掩膜裁剪实例 一、 矢量裁剪 1、问题描述 当我们想要用一个矢量文件去裁剪影像时,可以使用ENVIVectorMaskRaster函数。 maskedRaster = ENVIVectorMaskRaster(raster, shp_file) 图中标记红圈处是我们裁剪出的影像,非常小的一块。但是却发现用ENVI-IDL裁剪出的影像仍然保留着原来影像的行列数,并不像ENVI中Subset Data from ROIs工具一样可以自行适应较小矢量文件的行列数。 那么这个时候就需要我们重新定义影像的空间范围。 2、重定义空间范围 2.1定义范围 Grid = ENVIGridDefinition(CoordSys, $ PIXEL_SIZE=[9.186D,9.186D], $ TIE_POINT_PIXEL=[0.0D,0.0D], $ TIE_POINT_MAP=[3075299.7946D,1246937.9905D], $ NROWS=Raster.NROWS, $ NCOLUMNS=Raster.NCOLUMNS) CoordSys:栅格或矢量的坐标系信息。 PIXEL_SIZE:像元大小。 TIE_POINT_PIXEL:Specify a two-element array with the map coordinates of the TIE_POINT_PIXEL location, as follows:[xmin, ymax]。 即指定MAP坐标的xmin和ymax If you set this property, you must also specify NROWS, NCOLUMNS, and PIXEL_SIZE. 如果设定了[xmin, ymax]则还要指定影像的行列数,像元大小。 NROWS:影像行数。 NCOLUMNS:影像列数。

(MATLAB 牛顿迭代法)

(MATLAB 牛顿迭代法) syms x; %定义变量x f(x)=x3+4*x2-10; g(x)=diff(f(x)); %求导 x0=1.5 x1=x0-f(x0)/g(x0); %迭代公式 vpa(x1,6) i=0; %迭代次数 while abs(x1-x0)>=0.001 & i<100 %判断条件(0.001)于最大循环次数 i=i+1; x0=x1; %替换 x1=x0-f(x0)/g(x0); vpa(x1,6) end if i==101 disp(‘不收敛’) end vpa(f(x1)) %最终f(x1)的值 运行结果

sql-labs通关记录(7-10)

less-7 先测试单引号,会报错。 发现,报错信息没有像之前一样,输出一些有用的信息/ 对id参数(闭合语句的条件)进行一波测试 从以上两条信息可以推断出,单引号是闭合语句的条件之一 接着带着单引号进行测试。 单引号加括号:index.php?id=1’)%23 单引号加两个括号:index.php?id=1’))%23 ok,这里我们测试出了正确的闭合语句,可以推断后端查询语句为: select * from users where id =(('$id')) 这里为什么是直接推断单引号后面跟上括号呢? 因为php脚本语言的原因,能识别的解析变量的字符就那几个,单引号、双引号、括号等。 页面提示: You are in… Use outfile… 关键词outfile 我们知道,select查询可以对文档有操作: 读取文档:load_file() 导出文档:into outfile() 所以,这里应该是想让我们利用outfile的文档来查看回显,也可以选择outfile一句话木马来getshell。 接下来我们需要知道物理路径,但是这在第七关,有些麻烦,因为我们这道题相当于盲注 并且我们无法利用Mysql来爆php进程的物理路径 所以,我们可通过盲注来获取users表的信息。但是题目要求outfile,那我们自己就给自己一个物理路径。 由于我用的是phpstudy搭建的环境,所以我直接在我本机取一个目录就好 D:\phpstudy_pro\Extensions\MySQL8.0.12\data 构造payload: index.php?id=1')) union select 1,2,3 into outfile "D:\\phpstudy_pro\\Extensions\\MySQL8.0.12\\data\\out1.php"%23 报错,查询结果应该显示在out1.php中,不知道为什么没有。这题先放这里吧。 less-8 经过测试,发现是字符型的注入。 并且是盲注,可以参考less-5,less-6. 先试试报错注入, ?id=-1'and extractvalue(1,(select database()))--+)) 发现没有返回任何数据,说明无法使用报错注入,只能和less-5一样,结合bp,使用截断函数爆。 先猜测数据库长度,这里就不演示了, zai再猜数据库名 ?id=1'and substr((select database()),1,1)='a'--+ 后面的就不做演示了,只构造payload 爆表(我这里是一张一张的爆,一起爆破的话数据整理起来太麻烦了) ?id=1'and substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),1,1)='a'--+ 爆列

两台(或多台)电脑怎么实现文件共享

关于文件共享,总结了几种实现方式,大家可以根据自己的需求选择合适的共享方式 一、在同一个局域网内(无论是连接的WiFi还是网线),工作的需要,需要共享一些文件: 1、找到需要共享的文件夹(或者文件)位置,如下图,比如需要共享“我的电脑的C盘” 2、在对应的文件夹,也就是桌面文件夹,右键鼠标,点击属性 3、进入属性面板后,选择共享,然后点击高级共享 4、进入高级共享后,勾选“共享此文件夹”,原来不可点击的权限变成可以点击的状态 5、点击权限,给制定用户赋予权限,这里为了说明,直接选择everyone,也就是任何人都可以访问 6、点击确定,应用后,回到属性界面,复制网络路径,发给准备共享的人A 7、在另外一台机器上(用户A)的“文件资源管理地址”中(或者WINDOWS+R:输入“\\地址名称”)粘贴后,回车,即可看到分享的文件了 (1)方式一 (2)方式二: 以上,为其中一种操作步骤,A用户可以随时通过“资源管理器”中“网络”查看局域网中其他同事共享的文件(如图), 同时,共享者,也可以查看自己哪些文件共享到局域网状态(显示一个共享标志,如下图所示): 二、方式二:设置自己的IP网络地址 按“Windows”+“R”,打开运行窗口,输入“control”点击确定。 点击“网络和internet”,再点击“网络和共享中心” 点击相关网络,选择“属性”,双击“Internet协议版本4”,勾选“使用下面的IP地址”。 在“IP地址”和“子网掩码”中分别输入“192.168.1.55”(此地址最后一个字段可以自由设置)和“255.255.255.0”。 在另一台电脑上重复以上1-4操作,再次按“Windows”+“R”,打开运行窗口,输入“control”点击确定。 找到“系统和安全”,点击“Windows防火墙”。 找到左边的“启用或关闭Windows防火墙”,勾选“关闭Windows防火墙”。 确定后,点击一个文件,右键单击“属性”,选择“共享栏”点击“共享”。(此时,重复“一”中第六条往后即可) 注:如以上两种方法均查看不到局域网共享文件,按以下方式进行操作 1、找到“网络和internet连接“在自己的本地电脑的右下角有一个上网连接的标志,点击它,会弹出一个菜单,选择“网络和internet连接”并点击它。 2、进入网络和internet连接的界面。在左边的菜单栏中,有以太网的设置,和vpn以及代理等上网的设置。 此时在搜索栏输入“共享”,然后点击“管理高级共享设置” 点击开启。 在共享选项设置里面,找到“网络发现”和“文件和打印机共享”,将两个的“启用网络发现”开关都打开,然后点击确定。

聊聊Hive的那些事儿

本文仅仅从宏观上去聊聊Hive中的一些常见问题。文末我整理了几篇其他人的文章,个人感觉对自己的学习起到了作用。有兴趣的同学可以点过去阅读。 1. Hive是什么? Hive是基于Hadoop的一个数据仓库工具,用来进行数据提取、转化、加载,这是一种可以存储、查询和分析存储在Hadoop中的大规模数据的机制。hive数据仓库工具能将结构化的数据文件映射为一张数据库表,并提供SQL查询功能,能将SQL语句转变成MapReduce任务来执行。 2. Hive的优缺点 优点: (1)操作接口采用类SQL语法,提供快速开发的能力(简单、容易上手)。 (2)避免了去写MapReduce,减少开发人员的学习成本。 (3)Hive支持用户自定义函数,用户可以根据自己的需求来实现自己的函数。 缺点: (1)Hive不支持记录级别的增删改操作; (2)Hive的查询延时很严重; (3)Hive不支持事务。 3. Hive与数据库的区别 1、Hive 和关系数据库存储文件的系统不同,Hive 使用的是 Hadoop 的HDFS(Hadoop的分布式文件系统),关系数据库则是服务器本地的文件系统; 2、Hive 使用的计算模型是 MapReduce,而关系数据库则是自己设计的计算模型; 3、关系数据库都是为实时查询的业务进行设计的,而 Hive 则是为海量数据做数据挖掘设计的,实时性很差,因为用到了Map-Reduce的计算模型;实时性的区别导致 Hive 的应用场景和关系数据库有很大的不同; 4、Hive 很容易扩展自己的存储能力和计算能力,这个是继承 Hadoop 的,而关系数据库在这个方面要差很多。 4. 内部表和外部表的区别 (1)建表语法的区别: 外部表在创建的时候需要加上external关键字; 创建内部表时,会将数据移动到数据仓库指向的路径;若创建外部表,仅记录数据所在的路径, 不对数据的位置做任何改变。 (2)删除表之后的区别: 内部表删除后,表的元数据和真实数据都被删除了; 外部表删除后,仅仅只是把该表的元数据删除了,真实数据还在,后期还是可以恢复出来。 这样外部表相对来说更加安全些,数据组织也更加灵活,方便共享源数据。 提示:内部表与外部表的区别一定要掌握,通常情况下我们都会使用外部表保证数据安全性,但是像中间表,结果表这种我们就会考虑使用内部表(管理表)。 5. Hive分区的定义?静态分区和动态分区的概念。 在hive中,表中的一个分区对应于表下的一个目录,所有的分区的数据都存储在对应的目录中。 静态分区 SP(static partition): 1、静态分区是在编译期间指定的指定分区名 2、支持load和insert两种插入方式 2.1load方式 1)会将分区字段的值全部修改为指定的内容 2)一般是确定该分区内容是一致的时候才会使用 2.2insert方式 1)必须先将数据放在一个没有设置分区的普通表中 2)该方式可以在一个分区内存储一个范围的内容 3)从普通表中选出的字段不能包含分区字段 3、适用于分区数少,分区名可以明确的数据 动态分区 DP(dynamic partition): 1、根据分区字段的实际值,动态进行分区 2、是在sql执行的时候进行分区 3、需要先将动态分区设置打开(set hive.exec.dynamic.partition.mode=nonstrict ) 4、只能用insert方式

vue-cli3.0(@vue/cli)设置网站标题时找不到index.html问题解决

需求 使用Vue做课程设计,需要更改一下网站的题目和图标。 默认效果 想要实现的效果 背景颜色不同是由于上面的浏览器开了暗色模式。 问题 根据在网上查找,很容易得知对于标题只需要很简单的修改index.html里的一行代码即可。对于图标,除了需要修改index.html的代码,还需要在app.vue中添加几行代码。 但是index.html在哪里?网上的所有相关博客都说“在项目根目录中找到index.html,修改内容即可”。可是问题是,我的项目的根目录下根本就没有index.html标签。 项目根目录如图所示。其中的vue.config.js是由于项目需要手动创建的。 问题分析 在vue-cli更新到3.0版本(即@vue/cli)后,生成的项目框架的结构发生了极大改变。这也就是包括本文所说问题在内的大部分文件找不到问题的原因。 问题解决 查阅Vue Cli文档,在HTML与静态资源一节可以看到index.html被移入到了public目录下。 在public目录下,我们果然找到了index.html,在其中设置title就可以完成标题的修改。 对于图标的修改方法,网上博客比比皆是,这里粘贴一个最简单的。 参考资料 https://blog.csdn.net/qq_41638468/article/details/101025810 其他 在@vue/cli中,生成项目框架的结构发生了大幅度调整。比如vue.config.js变成了需要开发者手动添加。新入门的开发者很容易发现自己的项目和网上教程有明显差别又百度不到解释,可以优先考虑去Vue Cli的官网寻找相关内容。本文设置的标题和图标都是全局性的,对于想要在不同界面设置不同标题和图标的需求,网上相关技术博客非常多,此处不再赘述。关于index.html和App.vue的关系,网上相关解释非常多,此处不再赘述。

拿offer必须掌握的最全SpringCloud面试题(含答案)

今天公司的项目比较忙,远程开会和办公的沟通效率总是差那么一点,为了节约点时间,就不介绍SpringCloud了,我想只要是一名Java开发程序员,提到微服务,一定对SpringCloud的大名如雷贯耳,我们直接来看它的高频面试题吧。 1、什么是Spring Cloud? Spring cloud 流应用程序启动器是基于 Spring Boot 的 Spring 集成应用程序,提供与外部系统的集成,更专注于服务治理。Spring cloud Task,一个生命周期短暂的微服务框架,用于快速构建执行有限数据处理的应用程序。 2、Spring Cloud和Dubbo的区别 Dubbo关注的领域是Spring Cloud的一个子集。Dubbo专注于服务治理,其在服务治理、灰度发布、流量分发方面比Spring Cloud更全面。Spring Cloud覆盖整个微服务架构领域。 Dubbo使用RPC调用效率高一些,Spring Cloud使用HTTP调用效率低,使用更简单。 3、REST和RPC的区别 REST风格的系统交互更方便,RPC调用服务提供方和调用方式之间依赖太强。 REST调用系统性能较低,RPC调用效率比REST高。 REST的灵活性可以跨系统跨语言调用,RPC只能在同语言内调用。 REST可以和Swagger等工具整合,自动输出接口API文档。 4、SpringCloud如何实现服务的注册和发现 服务在发布时 指定对应的服务名(服务名包括了IP地址和端口) 将服务注册到注册中心(eureka或者zookeeper)。 这一过程是springcloud自动实现 只需要在main方法添加@EnableDisscoveryClient 同一个服务修改端口就可以启动多个实例。 调用方法:传递服务名称通过注册中心获取所有的可用实例 通过负载均衡策略调用(ribbon和feign)对应的服务。 5、什么是服务熔断和服务降级? 熔断机制是应对雪崩效应的一种微服务链路保护机制。当某个微服务不可用或者响应时间太长时,会进行服务降级,进而熔断该节点微服务的调用,快速返回“错误”的响应信息。当检测到该节点微服务调用响应正常后恢复调用链路。在SpringCloud框架里熔断机制通过Hystrix实现,Hystrix会监控微服务间调用的状况,当失败的调用到一定阈值,缺省是5秒内调用20次,如果失败,就会启动熔断机制。 服务降级,一般是从整体负荷考虑。就是当某个服务熔断之后,服务器将不再被调用,此时客户端可以自己准备一个本地的fallback回调,返回一个缺省值。这样做,虽然会出现局部的错误,但可以避免因为一个服务挂机,而影响到整个架构的稳定性。 Hystrix相关注解: @EnableHystrix:开启熔断 @HystrixCommand(fallbackMethod=”XXX”):声明一个失败回滚处理函数XXX,当被注解的方法执行超时(默认是1000毫秒),就会执行fallback函数,返回错误提示。 6、什么是Hystrix?它如何实现容错? Hystrix是一个延迟和容错库,旨在隔离远程系统,服务和第三方库的访问点,当出现故障是不可避免的故障时,停止级联故障并在复杂的分布式系统中实现弹性。 通常对于使用微服务架构开发的系统,涉及到许多微服务。这些微服务彼此协作。 思考以下微服务 假设如果上图中的微服务9失败了,那么使用传统方法我们将传播一个异常。但这仍然会导致整个系统崩溃。 随着微服务数量的增加,这个问题变得更加复杂。微服务的数量可以高达1000.这是hystrix出现的地方 我们将使用Hystrix在这种情况下的Fallback方法功能。我们有两个服务employee-consumer使用由employee-consumer公开的服务。 简化图如下所示 现在假设由于某种原因,employee-producer公开的服务会抛出异常。我们在这种情况下使用Hystrix定义了一个回退方法。这种后备方法应该具有与公开服务相同的返回类型。如果暴露服务中出现异常,则回退方法将返回一些值。 7、什么是Hystrix断路器?我们需要它吗? 由于某些原因,employee-consumer公开服务会引发异常。在这种情况下使用Hystrix我们定义了一个回退方法。如果在公开服务中发生异常,则回退方法返回一些默认值。 如果firstPage method() 中的异常继续发生,则Hystrix电路将中断,并且员工使用者将一起跳过firtsPage方法,并直接调用回退方法。断路器的目的是给第一页方法或第一页方法可能调用的其他方法留出时间,并导致异常恢复。可能发生的情况是,在负载较小的情况下,导致异常的问题有更好的恢复机会 。 8、项目中zuul常用的功能 提供动态路由 提供安全、鉴权处理 跨域处理 全局动态路由的hystrix(熔断、降级、限流)处理 9、服务网关的作用 简化客户端调用复杂度,统一处理外部请求。 数据裁剪以及聚合,根据不同的接口需求,对数据加工后对外。 多渠道支持,针对不同的客户端提供不同的网关支持。 遗留系统的微服务化改造,可以作为新老系统的中转组件。 统一处理调用过程中的安全、权限问题。 Spring Cloud中的网关有:Zuul和Spring Cloud Gateway,最新版本中推荐使用后者。

vant的Uploader 上传问题

vant的uploader组件的交互是点击上传之后才会触发一系列回调函数,如果想要实现点击uploader的时候先出现弹框提示,选择了确定之后才进行文件上传这该怎么做到呢? 大致是,给uploader组件外面包裹一层元素,然后给组件设为禁用模式,当外层的元素状态改变时,就改变组件的disabled值,再使用vant提供的chooseFile通过 ref 可以获取到 Uploader 实例并调用实例的方法重新调起文件选择。 主要的步骤如下: 首先,我们可以在uploader组件外面包裹一层div <span @click="handleClick" v-if="isconfirm" class="message" ></span> <van-uploader v-model="fileList" :after-read="afterRead" :disabled="isconfirm" ref="uploadImg" /> 然后在data以及methods中进行定义 data() { return { fileList: [], isconfirm: true }; methods: { handleClick() { this.$dialog .confirm({ message: "test,test,test" }) .then(() => { this.isconfirm = false; this.$refs.uploadImg.chooseFile(); }) .catch(() => { this.isconfirm = true; }); }, } 看到这里要注意chooseFile这个方法支持的版本是v2.5.6以上的,如果出现了没有效果的话,先检查一下自己安装的版本是否是符合要求的。 检查之后,版本也符合要求,但是this.$refs.uploadImg.chooseFile()就是没有效果,这是怎么一回事呢? 原来跟浏览器执行机制event loop有关,每当执行到choosefile的时候,组件仍为禁用模式,无法调起,其实isconfirm状态还没有进行改变,所以调起文件选择看不见效果,可以使用一个setTimeout或者是vue中的this.$nextTick()进行解决。 setTimeout(() => { this.$refs.uploadImg.chooseFile(); }, 0); this.$nextTick(() => { this.$refs.uploadImg.chooseFile(); });

MySOL基础

1:什么是数据库? 2:安装,链接,分类 3:mysql的架构 4:服务器,数据库,表关系 5:库操作,表操作 6:表的约束 注:centos7.5的环境 一:什么是数据库? 数据库是以一定方式储存在一起、能与多个用户共享、具有尽可能小的冗余度、与应用程序彼此独立的数据集合,可视为电子化的文件柜——存储电子文件的处所,用户可以对文件中的数据进行新增、查询、更新、删除等操作。(来源于百度百科) 二:mysql的基本使用 1:linux下安装mysql及配置 安装方法 2:链接服务器 mysql -h ip -p -port -u root -p eg: mysql -h 0.0.0.0 -p 8888 -u root -p 若是在本机使用,mysql -u root -p 即可 3:SQL语言的分类 DDL:定义数据库, DML:对数据库进行增删查改 DQL:数据查找 DCL:数据库控制语句 三:mysql的架构 mysql也是采用了分层的机制,其客户端将命令传送到服务端,服务端,将其分为链接层,处理层,引擎层 1:链接层: a:检查客户端是否合法 b:判断链接协议Tcp/ip 或 进程间通信(本机) c:创建一个线程,每一个线程对一个客户端 2:sql层(处理层) a:语法检查 b:语义检查,权限等 c:解析预处理,出多种方案 d:优化器,选择一个最优方案,告诉存储引擎你应该在那个地方读取数据 注:mysql还有下面两个 查找缓存,但是现在是补常用的;因为我们并不会连续访问一个数据,导致存储缓存并没有起到作用,但是每次都需要更新,这样就降低了效率。 记录日志:记录操作 3:引擎层 负责存储查找,删除。。 四:服务器,数据库,表关系 1:罗辑关系: 数据库中的存储有两个层级库和表,如何把文件系统极性类比的话,库对应的就是文件夹,表对应的就是文件。 我们可以使用 # vim /etc/my.cn 查看mysql的配置文件 然后我们看到datadir,这对应的就是库所存储的位置 [root@VM_0_11_centos mysql]# cd /var/lib/mysql/ [root@VM_0_11_centos mysql]# ls aria_log.

[!] Unable to add a source with url `https://github.com/CocoaPods/Specs.git` named `cocoapods`.- Dev

对项目执行 pod install 的时候遇到了如下异常: Cloning spec repo `cocoapods` from `https://github.com/CocoaPods/Specs.git` [!] Unable to add a source with url `https://github.com/CocoaPods/Specs.git` named `cocoapods`. You can try adding it manually in `/Users/fyhsurvivors/.cocoapods/repos` or via `pod repo add`. 解决办法 首先,因 CocoaPods 的库文件较大 https://github.com/CocoaPods/Specs.git 的方式很容易中断,建议尝试切换为 ssh 的方式进行 clone 操作 git@github.com:CocoaPods/Specs.git 其次,终端中输入如下命令,处理 cocoapods 的 repos; rm -rf ~/.cocoapods mkdir -p ~/.cocoapods/repos cd ~/.cocoapods/repos git clone git@github.com:CocoaPods/Specs.git 注:如上操 clone 时对网络环境要求较高 若成功,则可以尝试在对应的项目中执行 pod install 即可 若失败,则会出现如下异常: fyhsurvivors@survivors-deMacBook-Pro repos % git clone https://github.

[计算机网络]-网络层-1

网络层基础 在参考模型中网络层位于传输层之下,链路层之上。 网络层的功能主要是将源端产生的数据包/分组,送达至目的机 完成这项工作需要: 封装源数据识别目的机找到一条好的路径(路由) 可能遭遇的问题: 地址不够用丢包拥塞 网络层主要内容 被路由协议:IP协议 IP地址:定位目的机IP分组:解决信息封装IPv6:新一代IP协议 路由选择协议:找到目的机和源机之间的最优路径 距离矢量路由选择协议(RIP)链路状态路由选择协议(OSPF) 其他方面: ARPICMPCIDRNAT 源和目的机之间的网络分为: 数据报网络: 提供无连接的服务 虚电路网络: 提供面向连接的服务 比较项目数据报子网(无连接服务)虚电路子网(面向连接服务)建立电路不需要要求地址信息每个分组含完整的SA和DA每个VC包含一个很短的VC号码状态信息路由器不保留任何连接状态信息每个VC都要求路由器建立表项路由每个分组独立选择路由每个分组沿建立VC时确定的路由路由器失效影响没有,只有系统崩溃时丢失分组所有经过失效R的VC都终止服务质量,拥塞控制很难实现总资源(带宽、缓存)足够的情况下,采用提前给每个VC分配资源的方法,很容易实现 IP地址 IP(Internet Protocol) 互联网协议,是TCP/IP协议栈的核心之一 IP任务: 提供一种尽力而为(best-effort),把数据从源端运输到目的机的方法,IP就像是胶水,将整个互联网络连接起来 IP为路由提供路由所需要的信息,所以IP也被称为被路由协议 包含两方面的内容,一方面包含IP地址,IP地址的作用就在于标识收发的数据机。另一方面是IP分组/数据报,这是信息封装的格式 IP地址 由32位二进制数表示,包含2^{32}\approx43*10^8即43亿个IP地址。缺点在于难于记忆。所以我们经常将IP地址的32位均等分为4组,中间用点分号隔开,每组八位用十进制表示,就形成了常见的IP地址格式 10000100100110010000110011000101 10000100.10011001.00001100.11000101 132.153.12.197 IP地址具有层次结构 各个地址之间可能具有一定的从属关系 这得益于IP地址天生就由两部分组成,IP地址中一部分表示网络部分,一部分表示主机部分,至于各部分占多少位,在不同类型的IP地址中有不同规定 A类地址 前一个字节标识网络部分,后三个字节都标识主机部分, 由于第一个字节的第一位固定用0标识,所以这个网络公有从(0000000-1111111)也就是0~127组网络,每个网络能容纳2^{24}-2台主机,具有A类网络特征的网络有128个,属于大型网络 0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx网络部分主机部分主机部分主机部分 B类地址 前两个字节用来标识网络部分,后两个字节用来标识主机部分,开头两位固定为10,所以这个网络第一字节从(10000000-10111111)也就是第一字节从128-191的网络,每个网络能容纳2^{16}-2台主机,具有B类特征的网络有2^{14}个,属于中型网络 10xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx网络部分网络部分主机部分主机部分 C类地址 前三个字节标识网络部分,最后一个字节用来标识主机部分,开头三位固定为110,第一字节从11000000~11011111也就是192-223范围内的网络,每个网络能容纳254台主机,具有C类地址特征的网络总数为2^{21}个。属于小型网络 110xxxxxxxxxxxxxxxxxxxxxxxxxxxxx网络部分网络部分网络部分主机部分 保留IP地址 D类地址:用作组播 E类地址:用作科研 网络地址:主机部分全部为0的地址 广播地址:主机部分全部为1的地址 32位全为0:0.0.0.0,标识这个主机,这个网络。路由表中默认路由的默认地址 32位全为1:255.255.255.255,泛洪广播地址,指代互联网所有机器,如果一个分组目的地址是泛洪广播地址,它将发送给互联网上所有主机,但这种行为实际非常可怕,他可能引起很严重的广播风暴,所以这个广播地址实际退化成了本地广播地址,路由器在截获这个地址后,不会再转发这种地址 环回地址:以127开头的地址,例如127.0.0.1代表本地主机 非正常地址:169.254.x.x,不能与外界正常通信 IP地址的分配 IP地址的分配是一种层级分配,全球的IP地址和域名分配,由ICANN负责,其下有诸多地区网络中心,如APNIC亚太地址网络信息中心,再往下就是各个国家网络中心,例如中国网络中心就从属于APNIC,国家网络中心下还有诸多运营商网络中心,普通用户就是从运营商处获取IP地址 子网规划 局域网不断发展,日益庞大以至于难以管理,所以必须要将庞大的局域网进行分割,分割成为不同的子网 一个局域网虽然被分割成几部分(子网),但在外界看来,还是在一个局域网内,这是由于这些局域网对应的外部路由器仍然只有一条 同时允许不同的子网在一个组织内部连接起来 主/边界路由器 负责与外部进行联系,从外部收到分组,向内部分组转发,路由器识别选择子网的方式通过子网掩码实现。 子网掩码 一种了解网络规模的机制 可以用点分十进制(连续的0和连续的1)表示,例如:11111111111111111111111111100000(255.255.255.224),其中1表示网络位,0表示主机位。 还可以用/+网络位数+子网位数 表示,例如上文中的27个1和5个0表示的点分十进制形式的子网掩码还可以用 /27 表示

本地播放哔哩哔哩弹幕+视频

本地播放哔哩哔哩弹幕+视频 1.打开你喜欢或者收藏的视频播放页面2.下载视频方法1:一劳永逸的下载工具: IDM方法2:利用浏览器插件的嗅探[^1]工具(不太推荐,感兴趣的可以百度学习一下)方法3:这还用说......哔哩哔哩有pc版的方法4:在线链接下载 3.下载弹幕!方法1:Crawler(爪巴 虫)方法2:当然是直接右键另存为。。 4.视频音频弹幕组合播放最后在本地就可以做到和在线看一样的效果啦!Nice!愉快地看视频吧!! 1.打开你喜欢或者收藏的视频播放页面 首先我们在哔哩哔哩寻找喜欢的视频,这里以君名与哔哩哔哩排行榜#513的视频为例。 2.下载视频 方法1:一劳永逸的下载工具: IDM 注:IDM是目前主流的下载工具之一,可在IDM官网下载(付费使用),也可自行百度,此处不详细介绍其安装配置过程,实在找不到可以去IDM贴吧或者私信我。 我们可以看到在这里显示了5个文件,一般来说第1个文件为当前画质视频文件(无音频),第2、3个文件为音频文件(选择其中一个下载即可),其余文件可忽略,不用担心下载的视频文件无声的问题(后面会说到,额,不会让你们看哑剧的。。) 方法2:利用浏览器插件的嗅探1工具(不太推荐,感兴趣的可以百度学习一下) 嗅探器的原理即是获取网络上流经的数据包。这将带来较之令人难受的困难: 当需要的数据很大时,嗅探器一时间无法接收完所有数据包,导致页面必须一直处于开启状态(嗅探时若中途退出则嗅探将终止,毕竟算是抓包,网页都关了抓个捶捶)。由于在不同网页得到的数据包类型太多,导致不易直接批量下载(虽然可以过滤类型名,但是直接下不是更快乐?)对于视频文件是一个整体的还好说,但如果是被分成了很多片的视频呢? 答案是:你将会得到一堆可能有序可能无序的.mp4或者.ts文件,你还要费心思把文件拼起来?那可能还要下一个拼接软件,或者学习写一段代码,我想没有人下个视频工作量这么大。。 方法3:这还用说…哔哩哔哩有pc版的 找到Windows自带的Microsoft Store,搜索哔哩哔哩下载第一个即可。 然后就可以选择自己喜欢的视频进行下载了。 方法4:在线链接下载 哔哩哔哩唧唧 或者在bilibili.com的.com前加jj => bilibilijj.com即可。 硕鼠下载 复制哔站视频链接致硕鼠即可(好像硕鼠更新了,要下载客户端或者下一个其他程序才能提供哔站视频下载) 确保上述无误,那么这时候我们拿到如下视频啦!(此处使用IDM): 3.下载弹幕! 以哔哩哔哩排行榜#513视频为例。 首先我们需要知道将获取的视频的cid的,注意不是aid。 1. 使用f12打开开发者工具—>Network 2.加载视频(开始播放)在Network中找到heartbeat并点击 3. 点击heartbeat—>Headers—>Form Data—>cid,找到cid为180279063 4. 跳转弹幕xml页面:https://comment.bilibili.com/+cid+.xml,此处为:https://comment.bilibili.com/180279063.xml 5.下面开始获取弹幕! 方法1:Crawler(爪巴 虫) 注:爬虫虽好,但且注意版权问题以及不要爬取国家网站,否则将会涉嫌犯法! 在xml界面按f12得到如下结构: 图像可以看出该页面的结构单一(//div[@id=“webkit-xml-viewer-source-xml”]),且只需获取i标签的内容即可(get_elements_by_tag_name()),此处爪巴虫代码不再赘述。 方法2:当然是直接右键另存为。。 弹幕.xml文件GET! 4.视频音频弹幕组合播放 虽说我们由步骤3得到了弹幕.xml文件,但是xml文件是不可以在播放视频时自动加载的!但视频可以加载字幕,于是我们想到将其转为字幕文件。 1. 使用xml转字幕软件Danmu2Ass1.1将其转换为字幕.ass文件。 2. 下载完成解压安装后,可以在快捷栏->发送到…->转换为ASS字幕文件将其转换为ASS。 3. 转换完成后需重命名并移动至视频文件夹以让视频自动匹配字幕,音频也是同样的道理,重命名为相同名字后视频会自动匹配。 最后在本地就可以做到和在线看一样的效果啦!Nice! 我用MPC-HC(x64)打开的,因其兼容性比较好 愉快地看视频吧!! @date: 2020.4.21 @author: zkinglin (完) 嗅探-百度百科 ↩︎

Window7激活 电话激活小记;

1、先随便找个秘钥输入上去,激活不了,然后进入第二步; 2、选择使用自动的电话激活来激活,国家选择中国; 3、电话: 普通话 1 、产品 2 、其它 1 , 然后让你输入9组ID,全部输入后会返回给你8组ID;输入后就可以激活了; 本人花了15大洋在某宝上买的教程!!!

Django实践——用户登录

Django默认提供了一个用户认证系统,但主要面向admin应用中用户对各种实体类的增删改查权限,比较复杂,本项目实现一个较简单的用户登录功能。 第1步:创建项目及应用 django-admin startproject DjangoLoginDemo cd DjangoLoginDemo python manage.py startapp login 将login应用添加到设置文件中,在DjangoLoginDemo/settings.py的INSTALLED_APPS中添加一行'login.apps.LoginConfig' 第2步:创建模型(实体类) ①在login/models.py中创建User类: import hashlib from django.db import models class User(models.Model): """用户实体类""" username = models.CharField(max_length=32, unique=True) password = models.CharField(max_length=40) def __str__(self): return self.username @classmethod def encrypt_password(cls, password): """使用SHA-1加密密码,返回长度为40的加密后的字符串。""" return hashlib.sha1(password.encode()).hexdigest() 其中用户密码使用SHA-1加密并转换为十六进制字符串,长度为40个字符。 ②将模型应用到数据库中(数据库使用默认的SQLite): python manage.py makemigrations login python manage.py migrate 等待执行完后就在数据库中创建了一个对应的表login_user(除此之外还创建了Django认证系统相关的表,与本项目无关) 第3步:创建HTML模板 在login目录下创建templates目录,在templates目录下再创建一个login目录,在其中创建base.html, index.html, register.html, login.html四个文件。base.html作为基模板被其他模板继承,内容如下;另外三个分别作为主页、注册页面和登录页面,内容暂时为空。 <!DOCTYPE html> <html lang="zh-hans"> <head> <meta charset="UTF-8"> <title>{% block title %}{% endblock %}</title> {% block script %}{% endblock %} </head> <body> <div id="

AD16按照选择对象定义板子形状出现问题

问题 按照对象定义板子形状后,板子形状只剩下里面的一部分 解决方法 第一步:选中一条边后,按住shift键,分别选中其他三条边,四条边全部选中 第二步:设计->板子形状->按照对象定义板子

springboot集成easypoi并使用其模板导出功能和遇到的坑

1.背景 最近在做个使用poi导出excel的需求,由于所需要的excel较为复杂,所以我准备使用easypoi的模板导出功能去实现 2.使用 2.1 集成 <!--excel--> <!--这里如果直接引入easypoi集成springboot的包即easypoi-spring-boot-starter, 那么启动需要spring-boot-starter-web,而不是spring-boot-starter--> <dependency> <groupId>cn.afterturn</groupId> <artifactId>easypoi-spring-boot-starter</artifactId> <version>4.1.2</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> 使用起来很简单,我就使用测试数据来说明我遇到的坑: 模板如下图所示 数据回显: 3 .坑 3.1 文档上说使用$fe循环时,可以定义item的名称,但是我实际操作发现,这是不行的,不能去定义t,或者将其命名为其他字符,否则展示不出来,下图就是错误的师范 正确写法:只能写成如下所示的写法: 3.2 写循环的时候注意只能单行或单列,不能合并单元格,否则效果不会是你想要的 如下图:合并了纵向的单元格 出来的效果是: 即只有遍历的第一行和最后一行格式正确,中间的都不正确,中间的都是按照单行去遍历的 合并列也是一样的:模板如下 出来的格式: 即只有第一行正确,其他行都是按照单列去处理的 所以在遍历时一定要注意不要去合并单元格,如果你就是想合并单元格,那继续往下看 3.3 遍历的列中不能有空单元格 这样就是错误的,如果你真不想有内容,就使用&NULL&去代替。如下图 3.4 遍历合并单元格 那遍历完后如果我想合并单元格怎么做呢?使用 PoiMergeCellUtil这个类的方法即可,通过mergeCells(合并行单元格)或addMergedRegion(合并列单元格或合并某个区域)方法去合并单元格 3.5 遍历中使用常量 如果在遍历中你想有一列是固定的某些字符串,那么你就需要使用单引号,如下图所示: 注意:在单元格中输入单引号时,一定要在第一个单引号前使用一下空格键,如果不使用空格键,保存后虽然上面的文本中有单引号,但是单元格中的就只剩后面一个单引号了,这就是有问题的。 4.多层循环的bug 使用模板多层循环的功能时,发现有一个bug: 我的模板如下: h是一个list集合,装有map对象,然后map里面有3个key,in1,in2,in3,循环出来后的结果: 其他行都是正确的,唯独第一行,不知道为什么就少了,我看数据也没有问题,所以这个问题我是没有解决的 但是我发现使用fe或!fe去遍历数据是对的,但是又会有一个问题,如果你的list数据下还存在数据,那么就会被覆盖,如下图所示: 可以看到,上面的第三行直接被覆盖了,这肯定就有问题了,所以使用这种方法的话,前提是你要能确定这个list到底有多少行,然后,在 下面去添加其他的数据,如我知道这个list就到10行,那么我将数据写到第11行的位置: 这时候我再遍历就没问题了 但是这种办法显然没啥用,因为在遍历时,很难在模板中去确定list有多少行数据 ,所以能解决的朋友,分享下解决方法咯 5.代码 @Test public void a () throws Exception{ Map<String, Object> map = new HashMap<>(); map.

有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出圈子。——C与C++实现

说明:本篇对标题所阐述的内容进行了两个方面的解答,分别为: (1)将退出顺序依次输出。 (2)将最后一个人的序号进行输出。 读者在阅读时一定要注意while循环里的表达式!!! 题目1:有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,将退出顺序依次输出。 C代码: #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> int main() { int n, array[50], loop; //输入总人数 printf("Input total number(n<=50):"); scanf("%d", &n); //编号 for (int i = 0; i < n; i++) { array[i] = i + 1; } int k=0;//报数 int m=0;//退出人数 int *array_end, *p; array_end = array + n;//数组最后一个元素的下一个位置 p = array; while (m < n) { //当前指针未到array_end的位置且其指向的元素不为0 if ((p != array_end)&&(*p != 0)) { k++; } if (k == 3) { k = 0; printf("

密钥套件

加密套件 一、定义 Cipher Suite,加密套件,即密码套件。是TLS/SSL网络协议中的一个概念。指在ssl通信中,服务器和客户端所使用的加密算法的组合。 二、使用流程 在ssl握手初期,客户端将自身支持的加密套件列表发送给服务器,服务器根据自己的配置从中尽可能的选出一个套件,作为之后所要使用的加密方式。 三、例子 如下为客户端发送给服务器的一组密码套件: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f) TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030) TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (0xc028) TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014) TLS_RSA_WITH_AES_256_GCM_SHA384 (0x9d) TLS_RSA_WITH_AES_256_CBC_SHA256 (0x3d) TLS_RSA_WITH_AES_256_CBC_SHA (0x35) TLS_RSA_WITH_CAMELLIA_256_CBC_SHA (0x84) TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xc027) TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (0xc013) TLS_RSA_WITH_AES_128_GCM_SHA256 (0x9c) TLS_RSA_WITH_AES_128_CBC_SHA256 (0x3c) TLS_RSA_WITH_AES_128_CBC_SHA (0x2f) TLS_RSA_WITH_CAMELLIA_128_CBC_SHA (0x41) TLS_RSA_WITH_3DES_EDE_CBC_SHA (0xa) TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA (0xc012) 每一条表示一个密码套件。以第一条为例解读内容: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f) TLS:表示基于TLS协议。ECDHE:TLS/SSL 的 Handshake 阶段使用ECDHE 交换对称密钥。RSA:TLS/SSL 的 Authentication 使用RSA 验证证书签名。AES_128_GCM:TLS/SSL 的 Encryption 使用AES in GCM,长度128。HA256:Hasning 使用SHA256,常见到有SHA384, SHA512。0xc02f:加密套件的标识。每个加密套件是有唯一数字作为标识的。用openssl来表示的话就是TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 参考文献 https://www.trustasia.com/jmtjssl 加密套件 https://baike.baidu.com/item/%E5%AF%86%E7%A0%81%E5%A5%97%E4%BB%B6/22657345?fr=aladdin 密码套件 https://blog.csdn.net/hxg117/article/details/90665260 HTTPS 密码套件组成部分

log4j2配置文件解读

https://logging.apache.org/log4j/2.x/ log4j2是对log4j的升级版,参考了logback的一些优秀的设计,并且修复了一些问题,因此带来了一些重大的提升 异常处理 : 在logback中,Appender中的异常不会被应用感知到,但是在log4j2中,提供了一些异常处理机制性能提升 : log4j2相较于log4j和logback都具有很明显的性能提升自动重载配置 : 参考了logback的设计,当然会提供自动刷新参数配置,最实用的就是我们在生产上可以动态的修改日志的级别而不需要重启应用无垃圾机制 : log4j2在大部分情况下,都可以使用其设计的一套无垃圾机制,避免频繁的日志收集导致的jvm gc 1 log4j2日志门面+日志实现 <!-- Log4j2 门面API--> <!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-api --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.13.1</version> </dependency> <!-- Log4j2 日志实现 --> <!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.13.1</version> </dependency> public class Log4j2Test { // 定义日志记录器对象 // org.apache.logging.log4j.LogManager // org.apache.logging.log4j.Logger public static final Logger LOGGER = LogManager.getLogger(Log4j2Test.class); @Test public void testQuick()throws Exception{ // 日志消息输出 LOGGER.fatal("fatal"); LOGGER.error("error"); //默认 LOGGER.warn("warn"); LOGGER.info("inf"); LOGGER.debug("debug"); LOGGER.trace("trace"); } log4j2.

org.apache.catalina.connector.ClientAbortException: java.io.IOException: 您的主机中的软件中止了一个已建立的连接。

问题 org.apache.catalina.connector.ClientAbortException: java.io.IOException: 您的主机中的软件中止了一个已建立的连接。 org.apache.catalina.connector.ClientAbortException: java.net.SocketException: Software caused connection abort: socket write error at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:410) at org.apache.tomcat.util.buf.ByteChunk.append(ByteChunk.java:371) at org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:435) at org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:423) at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:91) at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:84) at org.apache.commons.io.IOUtils.write(IOUtils.java:631) at com.wei.utils.CreateZipAndDownload.CreateZipAndDownload(CreateZipAndDownload.java:68) at com.wei.service.impl.ArticleServiceImpl.download(ArticleServiceImpl.java:128) at com.wei.web.servlet.ArticleServlet.download(ArticleServlet.java:70) at com.wei.web.servlet.ArticleServlet.doGet(ArticleServlet.java:61) at com.wei.web.servlet.ArticleServlet.doPost(ArticleServlet.java:180) at javax.servlet.http.HttpServlet.service(HttpServlet.java:650) at javax.servlet.http.HttpServlet.service(HttpServlet.java:731) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) at com.wei.web.filter.EncodingFilter.doFilter(EncodingFilter.java:29) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:218) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103) at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:956) at org.

IDEA 快速生成增强 for 循环

目录 IDEA 快速生成增强 for 循环1. 数组2. 集合 IDEA 快速生成增强 for 循环 可以使用 IDEA 的内置方法:数组或集合名.for + 回车快速生成增强 for 循环。 1. 数组 对象数组 objects.for: 基本数据类型数组 ints.for: 2. 集合 数组列表 arrayList.for: 原文链接:https://qwert.blog.csdn.net/article/details/105609153

Error: EACCES: permission denied 错误解决方法

1、问题描述 系统:苹果最新系统(macOS 10.15.4) 动作:npm全局安装软件 结果:安装过程中需要读写文件或创建文件夹时报:Error: EACCES: permission denied 2、原因分析 2.1、系统方面 因为苹果最新系统升级了文件读写权限的安全级别,如SIP(System Integrity Protection),Rootless等,及时是root用户也没有权限修改像etc、usr文件夹下的文件。 当然也可以关闭这功能: 关闭SIP:启动电脑>>按住command+R>>进入恢复模式>>实用工具>>终端>>输入csrutil disable 回车(开启是enable) 2.2、npm方面 引用自:https://segmentfault.com/q/1010000019365121/ npm 出于安全考虑不支持以 root 用户运行,即使你用 root 用户身份运行了,npm 会自动转成一个叫 nobody 的用户来运行,而这个用户几乎没有任何权限。这样的话如果你脚本里有一些需要权限的操作,比如写文件(尤其是写 /root/.node-gyp),就会崩掉了。 为了避免这种情况,要么按照 npm 的规矩来,专门建一个用于运行 npm 的高权限用户;要么加 --unsafe-perm 参数,这样就不会切换到 nobody 上,运行时是哪个用户就是哪个用户,即使是 root。 3、解决方法 正如2.2中说到的,在用npm安装时,加上 --unsafe-perm 参数,如: #一般加上sudo npm install -g node-sass --unsafe-perm 4、遇到的另一个问题 安装node-sass时一直出现: Cannot download "https://github.com/sass/node-sass/releases/download/v4.13.1/darwin-x64-72_binding.node" 这个原因很简单,网络问题或被墙了 解决方法(使用淘宝镜像): npm i node-sass --sass_binary_site=https://npm.taobao.org/mirrors/node-sass/ 出现上面的问题可执行下面这条指令: sudo npm i node-sass --unsafe-perm --sass_binary_site=https://npm.taobao.org/mirrors/node-sass/

gorm调用原生sql语句

框架:gin 语言:golang 需求:使用gorm的原生sql语句实现增删改查。 备注:具体配置gorm的不再赘述。 数据库数据如下图所示: 定义数据库结构体如下: type User struct { Model UserId int `json:"user_id" gorm:"index"` CompCd string `json:"comp_cd"` UserCd string `json:"user_cd"` UserName string `json:"user_name"` UserPwd string `json:"user_pwd"` UserType string `json:"user_type"` UserPhone string `json:"user_phone"` UserEmail string `json:"user_email"` DelFlag string `json:"del_flag"` } 1.查询 根据条件查询,问号即为占位符 如下图所示 具体代码如下: //测试查询功能 func TestSelect(userId int) (userList []User) { db.Raw("select * from tsys_user where user_id > ?", userId).Scan(&userList) return } 调用并打印返回体如下: 2.新增 新增一条数据,此处调用了Exec去执行sql语句,如下图: 具体代码如下: //测试新增功能 func TestAdd(compCd, userCd, userName, usePwd, userType, userPhone, userEmail string) bool { db.

python 从字符串内取两个符号之间的内容 两个相同符号之间的内容

网上很多方法取两个不同符号之间的内容 如果确定字符串里用相同符号(或字符串)分隔,怎么取相同符号(或字符串)之间的内容? import re str = "### strat 'something' end ###" result = re.findall(".*strat(.*)end.*", str) for x in result: print x # 'something' start 和 end 可以是相同字符 正则表达式相关知识点: x* 匹配0次或者多次 x 字符。 (x) 一般情况下表示一个记忆组 (remembered group)。你可以利用 re.search 函数返回对象的 groups() 函数获取它的值。 点号.匹配任意单字符

构建推荐系统:用 Netflix 电影评价数据集练练手

By 超神经 内容概要:我们每天都在接触视频平台的「猜你喜欢」、「为你推荐」,这背后的算法是怎样获得的,需要用到怎样的数据集? 关键词:Netflix 推荐系统 算法 Netflix:让推荐算法商业化的鼻祖 Netflix 是美国的著名流媒体平台,它从租赁 DVD 起家,当下的主要业务是提供视频流播服务和影片发行制作。 Netflix 视频资源丰富 全美 36% 的家庭已订阅 Netflix 2019 年 Netflix 全球订阅用户数达到 1.58 亿, 其平台的一大特色就是「智能推荐」,即依据用户以往的观看视频类型,借助算法为用户进行视频推荐。 虽然「猜你喜欢」对于现在的很多视频平台来说,早已经算不上新鲜事,但实际上早在 2006 年,Netflix 就已经非常重视推荐算法,并为此举办了奖金高达 100 万美元的 Netflix Prize。 Netflix Prize 副产:电影评价数据集 Netflix Prize 在推荐系统领域具有极其重要的意义,它以极高的奖金额度,吸引了大量 AI 开发者投身于推荐系统相关研究,同时也开辟了「推荐算法」商业化的先河,让这项技术真正从学界进入了商界,并被后来的视频流媒体平台争相模仿。 即使是与当下的数据科学竞赛相比 Netflix Prize 的奖金也极具吸引力 Netflix 电影评价数据集包含来自 48 万用户对 1.7 万部电影的评价数据,评价数超过 100 万条,数据采集的时间段为 1998.10 – 2005.11。 Netflix 电影评价数据集 包含数量:超过100 万条数据 数据格式:TXT 数据大小:665.24 MB 采集时间:1998.10 – 2005.11 发布时间:2006 年 包含内容:用户编号、电影名、评分时间以及评分 下载地址:hyper.ai/datasets/5687

高等数学——积分中值定理

本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是高等数学专题的第12篇,我们继续来看定积分。 之前在讲微分求导内容的时候,介绍过一系列微分中值定理的推导。既然有微分中值定理,那么自然也有积分中值定理,我们下面就来看看积分中值定理的定义。 极值定理 极值定理也叫最大最小值定理,它的含义非常直观:如果函数f(x)在区间[a,b]上连续的函数,必然存在最大值和最小值,并且取到最大值和最小值至少一次。 这是一个非常有名的定理,定理的内容很直观,也不难理解。但是证明它不太容易,是由区间套定理与B-M定理等多个定理推导得到的,这段证明过程比较复杂,由于篇幅和水平的限制,本文当中只能跳过这部分,感兴趣的同学可以自行了解。 我们假设m和M分别是区间[a, b]上函数f(x)的最小值和最大值,那么根据极值定理,可以得到以下式子成立: m ( b − a ) ≤ ∫ a b f ( x ) d x ≤ M ( b − a ) m(b-a) \leq \int_a^bf(x)dx \leq M(b-a) m(b−a)≤∫ab​f(x)dx≤M(b−a) 这个式子光看可能会觉得有些复杂,但是我们把图画出来之后非常简单: 上图当中灰色阴影部分就是定积分的结果,蓝色的矩形面积是m(b-a),大的矩形面积是M(b-a)。 通过几何面积的关系我们可以很容易证明结论。 数学证明也很简单,由于m和M分别是最小值和最大值,所以我们可以得到 m ≤ f ( x ) ≤ M m \leq f(x) \leq M m≤f(x)≤M。我们把常数也看成是函数,进行积分,于是可以得到: ∫ a b m d x ≤ ∫ a b f ( x ) d x ≤ ∫ a b M d x \int_a^bm dx \leq \int_a^b f(x)dx \leq \int_a^bMdx ∫ab​mdx≤∫ab​f(x)dx≤∫ab​Mdx

React Native ------记录调起iOS支付宝的两种方法

本文记录React Native 实现的iOS App,如何用iOS调起支付宝App??? 两种方法: 方法一:使用支付宝sdk方法:payOrder; 方法二:使用React Native 提供的Linking.openURL(url)方法。 方法一: iOS集成支付宝 https://opendocs.alipay.com/open/204/105295/ 然后React Native通过桥接方法调用原生iOS支付宝sdk; 请求支付宝的url格式:这种格式ios和Android sdk 都能调起支付宝App alipay_sdk=alipay-sdk-java- dynamicVersionNo&app_id=2018012302041306&biz_content=%7B%22out_trade_no%22%3A%22200 410ZpAKFY5852%22%2C%22product_code%22%3A%22QUICK_MSECURITY_PAY%22%2C%22subject%22%3 A%22%E9%87%91%E6%A6%9C%E9%A2%98%E5%90%8D%E5%A4%A7%E7%A4%BC%E5%8C%85%22%2C%22timeout _express%22%3A%2230m%22%2C%22total_amount%22%3A%220.01%22%7D&charset=UTF- 8&format=json&method=alipay.trade.app.pay&notify_url=http%3A%2F%2F221.226.157.194%3 A18011%2Forder%2Falipay%2FasynCallback&sign=B4bXla2KNpa9hVMM0ByujPHsKITuV6Cy8hZ%2Bc YaoDjgUrtb8CZjSFEOZB1wYBAVICIfYwlKxfCiq%2FeuanElO7O7p9FaP1BGSfO3UkVV%2FACXAFc2aQS64 Xeppx88yZalegLZiFRRpzdxZ6Nx5vQYwfu1LaUr46Hmz2KzyAolQZt4Ogwx90r4S3M4PYtNQgJ30Iv8NFzw emfaoljyVGsJAMjIdjRPCDYyw6as7lj7gjCfGhYmk9S%2BUwYAH72d3ImG9uPrIjTdvoprKbbFIi34pXqQ% 2Fb1TOcz2%2BF%2Fqhhuq917ZhQZbXRHeeiNbDod49gz4LlF1CUhczKucSA%2FFMB3u7Cw%3D%3D&sign_t ype=RSA2&timestamp=2020-04-17+15%3A11%3A07&version=1.0 方法二: 基本上面的方法已经可以完成所用的支付了,但是有需求要在webview中调起原生支付宝这种情况。 下图:支付宝H5页面:https://mclient.alipay.com/cashier/mobilepay.htm。。。。。 在webview加载支付宝H5页面的时候 会给你发送下面支付信息 "alipay://alipayclient/?%7B%22requestType%22%3A%22SafePay%22%2C%22fromAppUrlScheme%22%3A%22alipays%22%2C%22 dataString%22%3A%22h5_route_token%3D%5C%22RZ54yFXFqXTIiVTyBnFDk4YFvhngbimobilecashierRZ54%5C%22%26is_h5_route%3D%5C%22true%5C%22%22%7D" 解码后格式:(方便查看,使用时不用解码) "alipay://alipayclient/?{"requestType":"SafePay","fromAppUrlScheme":"alipays"," dataString":"h5_route_token=\"RZ54yFXFqXTIiVTyBnFDk4YFvhngbimobilecashierRZ54\"&is_h5_route=\"true\""}" 注意其中的"fromAppUrlScheme":"alipays" 首先重写React Native webview的 onShouldStartLoadWithRequest 方法:拦截支付信息 onShouldStartLoadWithRequest(req) { var url=req.url if(url.indexOf("alipay://alipayclient")!=-1 || url.indexOf("alipays://alipayclient")!=-1){ //去支付宝 this.goAlipay(url) } //一定要拦截非http链接,否则会有警告 if(url.indexOf("http")!=-1||url.indexOf("https")!=-1){ return true; } //不加载该请求 return false; } goAlipay(payInfo){ Linking.canOpenURL(payInfo).then(supported => { if (!

email 安装报错 No module named 'cStringIO'

python 自动发送邮件需要用到 email,但是python3 在安装email包的时候出现了难以解决的问题。 问题: pip install email Collecting email Using cached https://files.pythonhosted.org/packages/71/e7/816030d3b0426c130040bd068be62b9213357ed02896f5d9badcf46d1b5f/email-4.0.2.tar.gz ERROR: Command errored out with exit status 1: command: 'D:\anaconda\python.exe' -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'C:\\Users\\Administrator\\AppData\\Local\\Temp\\pip-install-ucmeohfy\\email\\setup.py'"'"'; __file__='"'"'C:\\Users\\Administrator\\AppData\\Local\\Temp\\pip-install-ucmeohfy\\email\\setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base pip-egg-info cwd: C:\Users\Administrator\AppData\Local\Temp\pip-install-ucmeohfy\email\ Complete output (11 lines): Traceback (most recent call last): File "<string>", line 1, in <module> File "D:\anaconda\lib\site-packages\setuptools\__init__.py", line 18, in <module> import setuptools.version File "D:\anaconda\lib\site-packages\setuptools\version.py", line 1, in <module> import pkg_resources File "

ifstream的使用

fstream提供了三个类,用来实现c++对文件的操作。(文件的创建、读、写)。 ifstream – 从已有的文件读入 ofstream – 向文件写内容 fstream - 打开文件供读写 文件打开模式: ios::in 只读 ios::out 只写 ios::app 从文件末尾开始写,防止丢失文件中原来就有的内容 ios::binary 二进制模式 ios::nocreate 打开一个文件时,如果文件不存在,不创建文件 ios::noreplace 打开一个文件时,如果文件不存在,创建该文件 ios::trunc 打开一个文件,然后清空内容 ios::ate 打开一个文件时,将位置移动到文件尾 文件指针位置在c++中的用法: ios::beg 文件头 ios::end 文件尾 ios::cur 当前位置 例子: file.seekg(0,ios::beg); //让文件指针定位到文件开头 file.seekg(0,ios::end); //让文件指针定位到文件末尾 file.seekg(10,ios::cur); //让文件指针从当前位置向文件末方向移动10个字节 file.seekg(-10,ios::cur); //让文件指针从当前位置向文件开始方向移动10个字节 file.seekg(10,ios::beg); //让文件指针定位到离文件开头10个字节的位置 注意:移动的单位是字节,而不是行。 常用的错误判断方法: good() 如果文件打开成功 bad() 打开文件时发生错误 eof() 到达文件尾 #include <vector> #include <string> #include <fstream> #include <iostream> using namespace std; int main() { ifstream myfile("G:\\C++ project\\Read\\hello.

nginx代理web服务后如何获取客户端的真实ip

nginx代理web服务后如何获取客户端的真实ip 问题描述 如果用户直接访问web服务,可以通过如下方式获取到客户端ip: String clientIp1 = request.getRemoteAddr(); 如果使用nginx代理web服务,通过上述方式获取到的IP地址为nginx的地址。 解决办法 nginx配置修改 在nginx中添加如下配置: proxy_set_header X-Real-IP $remote_addr; jsp代码修改 在jsp中使用以下方式,即可获取到客户端的实际ip: String clientIp2 = request.getHeader("X-Real-IP"); 修改后,可以通过nginx获取到客户端的真实ip: 完整代码 nginx配置 # test-nginx-config upstream ip_server { ip_hash; server 127.0.0.1:8080; } server { listen 9001; #listen localhost:8080; #server_name somename alias another.alias; location /ip/{ proxy_pass http://ip_server; #Proxy Settings proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_connect_timeout 60; proxy_read_timeout 60; proxy_send_timeout 60; } } jsp代码 <%@ page language="

LPDDR4协议规范之 (一)地址映射和容量计算

文章目录 LPDDR4协议规范之 (一)地址映射和容量计算 LPDDR4 结构 LPDDR4 地址映射 LPDDR4协议规范之 (一)地址映射和容量计算 LPDDR4 结构 LPDDR4采用了全新的双通道设计,每个裸片包含两个Channnel,每个Channel包含8个Bank,16Bit位宽,16n预读取(DDR4的2倍),每个Die的最高存储容量可以达到32Gb。对于标准的容量的LPDDR4器件,每个Channel的列是固定的(Page页是固定的),容量越大,行越多。 LPDDR4器件地址分配 LPDDR4 地址映射 LPDDR4规范中对地址映射的规定 注1:较低的两列地址(C0-C1)被假定为“零”,并且不在CA总线上传输。 注2:CA总线上未用于特定密度的行和列地址值应处于有效逻辑电平。 注3:对于非二进制内存密度,只有四分之一的行地址空间无效。 当MSB地址位为“高”时,则MSB-1地址位必须为“低”。 注4:违反此表中注3所述限制的行地址输入可能会导致未定义或特定于供应商的行为。 请咨询内存供应商以获取更多信息。 根据LPDDR4规范可以看到,LPDDR4每个Channel内的列寻址为C0-C9共10Bit,也就是Page页的大小为102416Bit(X16 Device),由于LPDDR4采用BL16突发模式,因此列寻址后的突发大小是1616Bit。因此列寻址边界可以从C4开始寻址,C3-C0可以固定为0。手册中列获取边界为64,刚好对应我们需要寻址的边界,64*16=1024。在BL16突发模式下,这种寻址方式就可以获取LPDDR4中的所有物理地址。 而行数,在针对不同大小的器件,具有不同的行。 ———————————————— 版权声明:本文为CSDN博主「YJFeiii」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/YJFeiii/article/details/105469366

有一个已经排好序的数组,现输入一个数,要求按原来的规律将它插入数组中。——C与C++实现

题目:一个已经排好序的数组,现输入一个数,要求按原来的规律将它插入数组中。(本例中输入的是一个升序的数组) 程序分析: (1)判断输入的数是否大于数组中最后一个元素,如果成立,将输入的数插入数组的末尾,反之执行(2)。 (2)通过循环,将输入的数插入第一个比之大的元素前边,之后的元素一次向后移动。 C实现: #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> int main() { int a[5] = { 1,4,8,13 }; int end, temp1, temp2; printf("已经拍好序的数组为:"); for (int i = 0; i < 4; i++) { printf("%d ", a[i]); } printf("\n"); int number; printf("请输入一个数:"); scanf("%d", &number); end = a[3]; if (number > end) { a[4] = number; } else { for (int i = 0; i < 4; i++) { if (a[i] > number) { temp1 = a[i]; a[i] = number; for (int j = i + 1; j < 5; j++) { temp2 = a[j]; a[j] = temp1; temp1 = temp2; } break; } } } printf("

Tomcat入门学习

什么是Tomcat 什么是tomcat?在我们学习javaweb的时候就已经认识了这个老家伙,并且不出意外会伴随你的整个javaweb生涯,所以认真的了解tomcat还是有很大的必要的,简单的说tomcat是一个可以运行Servlet和JSP的容器,实现了对于Servlet 、JSP 和EL 等特性的支持,我们编写的servlet程序可以通过tomcat来实现web页面的访问 Tomcat是如何工作的 用户通过客户端浏览器(Chrome,FireFox,IE浏览器)发起请求通过DNS域名解析服务解析到对应服务器的IP地址,并且请求到绑定端口(比如8080端口)的tomcattomcat根据请求路径找到对应的webApp以及对应的Servlet(url-mapping)对应的Servlet通过请求过来的request执行用户编写的servlet实现,返回response用户浏览器收到response后,渲染页面 Tomcat的目录 如上是tomcat9的目录,其中 bin目录,主要存放一些可执行文件,比如常用到的startup.bat,shutdown.bat等等conf目录,主要存放一些配置文件,server.xml,tomcat-users.xml,context.xml 其中最重要的server.xml,主要设置tomcat的端口,编码等等lib目录,主要存放tomcat运行依赖的共有的jar包,比如大家很熟悉的servlet-api等等logs目录,主要是存放tomcat运行期间产生的日志信息,包括异常信息temp目录,主要存放tomcat运行时的一些临时文件webapps目录,这个目录很重要,里面每一个目录都是一个项目,我们平常写的项目也都是放在这个目录下面,默认这个目录自带了ROOT,manager,host-manager,examples,docs这几个项目其中ROOT目录是直接映射请求,比如localhost:8080/index.html 就是直接请求的ROOT目录的项目,localhost:8080/manager/test, 请求的是manager这个项目,localhost:8080/examples/test,请求的是examples这个目录,依次类推我们自己的项目请求路径work目录,主要存放一些jsp文件编译后生成的.class文件,可以删除改目录,下次启动会自动生成,有时候jsp修改不生效,可能就是这个目录生成的class未更新导致的,可删除改目录来解决 自己写一个WEBAPP来访问 在webapps目录下面新建一个testApp目录,在testApp目录下新建一个index.html文件,记住index.html扩展名是.html,不要新建成了index.html.txt,可以通过调整文件夹选项来识别 WIN10 可通过 查看->选项 来设置,去掉 隐藏已知文件类型的扩展名即可 启动tomcat,进入tomcat的bin目录,双击startup.bat,出现dos命令框即可 如上显示 startup in *** milliseconds 即表示启动成功,由于我是下载的tomcat是默认配置,所以直接访问 localhost:8080/testApp/index.html 即可 常用的配置修改 常用的配置都存放在conf目录,在conf目录我们可能会用到的修改,主要包含如下几个配置文件 logging.properties ,该配置文件主要用来修改tomcat运行时的日志打印配置,设置tomcat日志打印的级别,编码,以及对应的日志处理器 server.xml ,核心配置项,覆盖了tomcat运行时需要的核心组件,比如协议支持,IO更改,引擎,连接器,运行端口,线程池大小,连接超时,访问用户组配置等等,如修改端口,直接修改port数值即可,这里不做多介绍,有兴趣可以看下tomcat架构解析这本书,可以对tomcat有更深入的了解 <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> tomcat启动端口8080 <Server port="8005" shutdown="SHUTDOWN"> tomcat关闭监听端口 tomcat-users.xml ,主要可以通过该配置文件为tomcat添加管理员权限的登录用户,当启动tomcat后访问manager项目可以直接对tomcat中运行的项目进行关闭重启等等,但是manager项目是需要登录才能够进行操作的,登录就需要涉及到用户权限配置,tomcat-users.xml就是用来配置这个用户的,当然也可以配置其他的应用

HTML文件如何静态引入scss文件

理论上html是不能引入scss文件的,只能引入css文件,所以在使用scss 时,可以动态监听scss,更改后翻译为css文件,将css文件静态引入html中。 具体方法如下:(比较原始,不依赖于ide工具) 安装sass工具,可以局部安装,也可以全局安装;方法是打开cmd命令行工具,在有npm(或者其他工具,如yarn)的前提下,npm install sass -g (全局安装 带 -g,局部不用); 在scss文件保存目录中,使用命令 sass – watch test.scss : test.css (test为临时文件名,个人可按实际情况更改); 将css文件引入html中; 按照上面的步骤操作后,即可在写样式表的时候,使用scss文件进行开发,cmd会自动生成css样式文件,从而即时查看效果。

Android O/P/Q SELinux avc dennied权限问题分析与解决

Android O/P/Q SELinux avc dennied权限问题分析与解决 1.概述2.确认SELinux问题3.案例分析案例1案例2案例3案例4 4.万能公式5.归纳6.第三方进程改新增全新的te文件并赋予权限6.1新设备节点增加访问权限6.2新文件/目录增加访问权限 1.概述 Android SELinux是Google从android L 开始,强制引入的一套非常严格的权限管理机制,主要用于增强系统的安全性。 然而,在开发中,特别是手机开发中,我们经常会遇到由于SELinux造成的各种权限不足,即使拥有“万能的root权限”,也不能获取全部的权限。本文旨在结合具体案例,讲解如何根据log来快速解决90%的SELinux权限问题。 2.确认SELinux问题 为了澄清是否因为SELinux导致的问题,可先执行: setenforce 0 (临时禁用掉SELinux,在项目初始阶段经常使用该方式,以免权限问题影响开发进度) getenforce (得到结果为Permissive) 如果问题消失了,基本可以确认是SELinux造成的权限问题,需要通过正规的方式来解决权限问题。 遇到权限问题,在logcat或者kernel的log中一定会打印avc denied提示缺少什么权限,可以通过命令过滤出所有的avc denied,再根据这些log各个击破: k79v1_64_tee_ven_p:/ #cat /dev/kmsg |grep avc 或 k79v1_64_tee_ven_p:/ #logcat |grep avc 例如: audit(0.0:67): avc: denied { write } for path="/dev/block/vold/93:96" dev=“tmpfs” ino=1263 scontext=u:r:kernel:s0 tcontext=u:object_r:block_device:s0 tclass=blk_file permissive=0 可以看到有avc denied,且最后有permissive=0,表示不允许。 3.案例分析 解决原则是:缺什么权限补什么,一步一步补到没有avc denied为止。 解决权限问题需要修改的权限文件如下位置,以.te结尾 such as: device/mediatek/mt6779/sepolicy/bsp/*.te 下面给出四个案例: 案例1 audit(0.0:67): avc: denied { write } for path="/dev/block/vold/93:96" dev="tmpfs" ino=/1263 scontext=u:r:kernel:s0 tcontext=u:object_r:block_device:s0 tclass=blk_file permissive=0 分析过程:

Amazon EC2创建快照计划任务

文章目录 概述说明生命周期管理方式创建生命周期策略监控快照生命周期 Cloudwatch规则配置补充信息参考信息 概述说明 在生产环境中,我们经常需要为业务系统进行数据备份防止各种突发的异常问题。创建快照是最方便的一种数据安全手段,它有两种方式来进行快照创建。参考如下: 生命周期管理器Cloudwatch规则配置 生命周期管理方式 您可以使用 Amazon 数据生命周期管理器 来自动创建、保留和删除为备份 Amazon EBS 卷而制作的快照。自动化快照管理可以帮助您: 通过实施定期备份计划来保护重要数据。按照审核员的要求或内部合规性保留备份。通过删除过时的备份来降低存储成本。 与 Amazon CloudWatch Events 和 AWS CloudTrail 的监控功能结合使用,Amazon 数据生命周期管理器 可为 EBS 卷提供完整备份解决方案,而无需额外费用。 ※ 这里指的无需额外费用指Amazon CloudWatch Events 与 AWS CloudTrail 等组件组合运用免费,而不是指备份快照所产生的存储空间等免费。 创建生命周期策略 菜单导航:服务 > EC2 > ELASTIC BLOCK STORE > 生命周期管理 生命周期策略需提供以下信息: Description (描述) – 策略的描述。资源类型 – 要备份的资源的类型。使用 VOLUME 创建单个卷的快照,或使用 INSTANCE 从实例的卷创建多卷快照。Target with these tags (具有这些标签的目标) – 标识要备份的卷或实例的资源标签。Lifecycle policy tags (生命周期策略标签) – 生命周期策略的标签。Schedule name (计划名称) – 计划的名称。Run policy every n Hours (每 n 小时运行一次策略) – 运行两次策略间隔的小时数。支持的值为 1、2、3、4、6、8、12 和 24。Starting at hh:mm UTC (开始时间 - 小时:分钟 UTC) – 计划开始运行策略的时间。第一次策略运行在计划时间之后的一小时内开始。它是以UTC时间为计算起点,而非当地时间为计算起点!保留 – 您可以基于快照的总计数或每个快照的存在时间保留快照。 对于基于计数的保留,范围是 1 到 1000。在达到最大计数后,将在创建新快照时删除最早的快照。对于基于存在时间的保留,范围是 1 天到 100 年。在每个快照的保留期过期后,将删除它。保留期应大于或等于创建间隔。 Cross Region copy (跨区域复制) – 您可以将每个快照复制到最多三个其他区域。对于每个区域,您可以选择不同的保留策略,以及是复制所有标签还是不复制任何标签。如果源快照已加密或默认启用加密,则会加密快照副本。如果源快照未加密,您可以启用加密。如果未指定 CMK,则会在每个目标区域中使用 EBS 加密的默认密钥对快照进行加密。您必须确保没有超过每个区域的并发快照副本数。Tagging information (标记信息) – 选择是否将源卷上的所有用户定义的标签复制到该策略创建的快照。除了 Amazon 数据生命周期管理器 应用的标签以外,您还可以为快照指定其他标签。如果资源类型为 INSTANCE,则可以选择使用以下变量标签来自动标记快照:instance-id 和 timestamp。变量标签的值在添加标签时确定。Fast snapshot restore (快速快照还原) – 选择是否启用快速快照还原以及在哪个可用区中启用。您还可以指定可启用快速快照还原的最大快照数。此选项将会产生额外费用,普通EBS Snapshots约$0.

数据流图的画法,如何画数据流图

1.数据流图的定义: 数据流图是结构化分析方法中使用的工具,它以图形的方式描绘数据在系统中流动和处理的过程,由于它只反映系统必须完成的逻辑功能,所以它是一种功能模型。 数据流图英文缩写DFD(Data Flow Diagram)它是描绘信息流和数据从输入移动到输出的过程中所经受的变换。数据流图从数据传递和加工的角度,以图形的方式刻画数据流从输入到输出的移动变换过程。 2.数据流图的基本图形元素有: (1)数据流 (2)加工(处理) (3)文件(数据存储) (4)数据池(数据源或终点) 数据流是一组数据。在数据流图中数据流用带箭头的线表示,在其线旁标注数据流名。在数据流图中应该描绘所有可能的数据流向,而不应该描绘出现某个数据流的条件。 加工(处理) 在数据流图中加工用圆圈表示,在圆圈内写上加工名。一个处理框可以代表一系列程序、单个程序或者程序的一个模块。 文件(数据存储) 是按照某种规则组织起来的、长度不限的数据。在数据流图中文件用一直线表示,在线段旁注上文件名。一个数据存储也并不等同于一个文件,它可以表示一个文件、文件的一部分、数据库的元素或记录的一部分等; 数据池(源点和终点) 在数据流图中用方框表示,在框内写上相应的名称。 3.数据流图的四种基本图形符号: -->:箭头,表示数据流; 〇:圆或椭圆,表示加工; = :双杠,表示数据存储; □:方框,表示数据的源点或终点。 4.画数据流图所使用的工具:visio 5.数据流图的画法步骤: 1)确定系统的输入输出 由于系统究竟包括哪些功能可能一时难于弄清楚,可使范围尽量大一些,把可能有的内容全部都包括进去。此时,应该向用户了解“系统从外界接受什么数据”、“系统向外界送出什么数据”等信息,然后,根据用户的答复画出数据流图的外围。 2)由外向里画系统的顶层数据流图 首先,将系统的输人数据和输出数据用一连串的加工连接起来。在数据流的值发生变化的地方就是一个加工。接着,给各个加工命名。然后,给加工之间的数据命名。最后,给文件命名。 顶层流图只包含一个加工,用以表示被开发的系统,然后考虑该系统有哪些输入数据、输出数据流。顶层图的作用在于表明被开发系统的范围以及它和周围环境的数据交换关系。 3)自顶向下逐层分解,绘出分层数据流图 对于大型的系统,为了控制复杂性,便于理解,需要采用自顶向下逐层分解的方法进行,即用分层的方法将一个数据流图分解成几个数据流图来分别表示。 分层:一般将层号从0开始编号,采用自顶向下,由外向内的原则。画0层数据流图时,分解顶层流图的系统为若干子系统,决定每个子系统间的数据接口和活动关系。编号:如果一张数据流图中的某个加工分解成另一张数据流图时,则上层图为父图,直接下层图为子图。子图及其所有的加工都应编号。父图与子图的平衡:子图的输入输出数据流同父图相应加工的输入输出数据流必须一致,此即父图与子图的平衡。局部数据存储。当某层数据流图中的数据存储不是父图中相应加工的外部接口,而只是本图中某些加工之间的数据接口,则称这些数据存储为局部数据存储。提高数据流图的易懂性。注意合理分解,要把一个加工分解成几个功能相对独立的子加工,这样可以减少加工之间输入、输出数据流的数目,增加数据流图的可理解性 例题: 假设一家工厂的采购部门每天需要一张定货报表。报表按零件编号排序,表中列出所有需要再次定货的零件。对于每个需要再次定货的零件应该列出下述数据:零件编号、零件名称、定货数量、目前价格、主要供应商、次要供应商。零件入库或出席称为事务,通过放在仓库中的CRT终端把事务报告给定货系统。当某种零件的库存数量少于库存临界值时就应该再次定货。 逐步分解地画出数据流图 第一步,画出最概括的系统模型。因为任何系统实质上都是由若干个数据源点/终点以及一个处理组成。这个处理就代表了系统对数据加工变换的基本功能。 对上图进行细化 再细化一点 勾画出边界 命名的方法 1)为数据流(或数据存储)命名 A.名字应该代表整个数据流(或数据存储)的内容; B.不要使用空洞的、缺乏具体含义的名字(如“数据”、“输入”); C.如果为某个数据流(或数据存储)起名字时遇到困难,则很可能是因为对数据流图的分解不恰当造成的,应该试试重新分解数据流图; 2)为处理命名 A.通常先为数据流命名,然后再为与之相关联的处理命名; B.名字应该反映整个处理的功能; C.应该尽量避免空洞笼统的动词做名字,如“处理”、“加工”; D.通常用一个动词命名,如果必须用两个动词才能描述整个处理的功能,则可能要把这个处理分解成两个处理更恰当; E.如果在为某个处理命名时遇到困难,则很可能是发现了分解不当的情况,应考虑重新分解。 3)为数据源点/终点命名 通常,为“数据源点/终点”命名时,采用它们在问题域中习惯使用的名字(如“仓库管理员”、“采购员”)。

力扣第601题:体育馆的人流量(延伸:获取连续登陆天数、连续签到天数等)

一、力扣原题:体育馆的人流量 题目来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/human-traffic-of-stadium 以下是力扣原题: X 市建了一个新的体育馆,每日人流量信息被记录在这三列信息中:序号 (id)、日期 (visit_date)、 人流量 (people)。 请编写一个查询语句,找出人流量的高峰期。高峰期时,至少连续三行记录中的人流量不少于100。 例如,表 stadium: 对于上面的示例数据,输出为: 提示: 每天只有一行记录,日期随着 id 的增加而增加。 题解: 方法:使用 JOIN 和 WHERE 子句。 思路: 在表 stadium 中查询人流量超过 100 的记录,将查询结果与其自身的临时表连接,再使用 WHERE 子句获得满足条件的记录。 a,b 和 c 相同,重点是需要考虑添加哪些条件能够得到想要的结果。以 a为例,它有可能是高峰期的第 1 天,第 2 天,或第 3 天。 用排列的方式的话有6个条件 (1、a是高峰期第1天,b是高峰期第2天,c是高峰期第3天; 2、a是高峰期第1天,b是高峰期第3天,c是高峰期第2天; 3、a是高峰期第2天,b是高峰期第1天,c是高峰期第3天; 4、a是高峰期第2天,b是高峰期第3天,c是高峰期第1天; 5、a是高峰期第3天,b是高峰期第1天,c是高峰期第2天; 6、a是高峰期第3天,b是高峰期第2天,c是高峰期第1天;) 根据上面的思路给出SQL语句如下: select distinct a.* from stadium a,stadium b,stadium c where a.people>=100 and b.people>=100 and c.people>=100 and ((a.id = b.id - 1 and b.