前言
伪代码是半角式化
、不标准的语言。我们可以通过它将整个算法运行过程的结构用接近自然语言的形式描述出来(这里,你可以使用任何一种你熟悉的文字,中文,英文
等等,关键是你把你程序的意思表达出来)。 借助伪代码, 我们可以更好的表述算法,
而不用拘泥于具体的实现;同样,当我们学习别人的算法时,也不会因C、C++、C#、JAVA等语言语法的差异,而影响我们理解算法的思想。
输入
赋值语句用符号←表示,x←exp表示将exp的值赋给x,其中x是一个变量,exp是一个与x同类型的变量或表达式(该表达式的结果与x同类型);多重赋值i←j←e是将表达式e的值赋给变量i和j,这种表示与j←e和i←e等价。例:
x←20*(y+1) 相当于C语言中的 x =
20*(y+1);
x←y←30 相当于C语言中的x = y = 30;
百度百科上给出了a←3;
变量
变量不需声明,但都相当于是所在函数内部的局部变量,不能不加显示的说明就使用全局变量;
数组
A[j]指示数组A的第j个元素。符号“
…”用来指示数组中值的范围。例如:
A[1…j]表示含元素A[1], A[2], … ,
A[j]的子数组;
程序块
程序块在伪代码程序语句上中表现为一种“缩进”,表示程序中的分支程序结构,同一模块的语句有相同的缩进量,次一级模块的语句相对与其父级模块的语句缩进;
选择结构
选择语句用if-then-else来表示,例:
if (Condition1) then [ Block 1 ]
else if (Condition2) then [ Block 2 ] else [ Block 3 ]
循环结构
while循环:
while c do
s
end
for循环:
for var init to limit by incr
实例:C语言编程题 求100到300之间所有素数
#include <stdio.h> int main(void) { int i,j; for(i = 100;i <= 300; i++) { for(j = 2; j <= i; j++) if(i%j == 0) break; if(j == i) printf("%-4d",i); //-4d是左对齐 } return 0; } 预备计算机知识 汇编语言是最低级的语言,它可以直接与硬件打交道。高级语言有Pascal、Basic、Fortran等等。高级语言的一条语句对应低级语言的很多条语句,任何高级语言编写的程序都要经过编译程序的编译、连接才能成为可以运行的程序。
编译连接的过程也就是把高级语言翻译成机器语言(二进制机器码)的过程,而汇编语言是基本上与机器语言一 一对应的一种语言。这个翻译过程是由编译程序自动完成的。把C语言定为中级语言是有它的道理的,因为C语言既有汇编语言的存取底层硬件的能力,又具有高级语言的许多特点。熟练掌握了C语言,学习其它的各种编程语言应该是很轻松的了。
C语言的书写格式:
1) 一个C语言编写的源程序,必定有一个主程序(称为main()函数,在C语言中子程序称为“函数”(当然,不要理解成为数学里面的“函数”)。但是决不能有一个以上的main函数(即只能有一个)。
2) 函数语句块用‘{’括号开始, 以‘}’反括号结束。这样的花括号必须成对出现。
3) 表达式写在小括号里面,以‘(’括号开始,以‘)’反括号结束。
4) 函数不能嵌套,即函数里面不能再套函数。(每一个函数是完成一个特定功能的函数模块)
C语言的组成:
C语言是由许多函数组成的。其中只有一个主函数(main()函数)。C程序执行时总是从main函数的‘{’处开始,至main函数的反大括号’}'处结束。当然还有其它一些规则,这将在以后的学习中去熟悉它。
C语言的书写规则:
C语言在书写时有它自身的特点:书写格式比较自由,在一行里可以写多条语句,一个语句也可以分写在多行上。虽然如此,在书写源程序时还是要注意哪些可以自由书写,而哪些必须要按照书写规则来书写。
几条规则写在下面:
1) 一行内可以写几个语句,建议一行不超过两条语句;
2) 一条语句可以写在多行上;
3) C语句不需要写行标号;
4) 每条语句及数据定义的后面要写上分号以表示该语句结束;
5) C语言中注释用 //来表示;
6) 建议书写时采用缩进格式;
7) 花括号、小括号都是成对出现的。
#include
#include
#define MAX 10
typedef struct //顺序表存储结构
{
int* elem; //动态分配空间的首地址,
int length; //线性表当前长度
int listsize; //线性表最大长度
}SqList;
int InitList(SqList *L); //构造空线性表L
int DestoryList(SqList* L);//销毁线性表L
int ClearList(SqList* L);//清空线性表L
int ListEmpty(SqList L);//判断线性表是否为空
int Length(SqList L);//求线性表元素个数
int GetElem(SqList L,int i, int *e);//查找位序为i的元素,用e返回
int LocateElem(SqList L, int e);//查找元素e,返回第一次出现的位序
int PriorElem(SqList L, int cur_e,int *pre_e); //用pre_e返回cur_e的前驱
int NextElem(SqList L,int cur_e,int *next_e);//用next_e返回cur_e的后继
int ListInsert(SqList* L,int i, int e); //将元素e插入的位置i;
int ListDelete(SqList* L,int i, int *e);//删除位置i的元素,用e返回其值
参考https://www.cnblogs.com/xxaxx/p/4679480.html
1、PadLeft函数
向已知字符串左边补充字符,使整个字符串到达指定长度
CREATE FUNCTION PadLeft
(
@VarOrgan varchar(10),/原始字符/
@TotalLength int,/总长度/
@Placeholder varchar(1)/占位符/
)
RETURNS varchar(100)
AS
BEGIN
declare @VarNew varchar(100),
@PadLen int
SET @VarNew=@VarOrgan
SET @PadLen=@TotalLength-LEN(@VarOrgan)
while(@PadLen>0)
begin
select @VarNew=@Placeholder+@VarNew
set @PadLen=@PadLen-1
end
return @VarNew
END
2、PadRight
向已知字符串右边补充字符,使整个字符串到达指定长度
CREATE FUNCTION PadRight
(
@VarOrgan varchar(10),/原始字符/
@TotalLength int,/总长度/
@Placeholder varchar(1)/占位符/
)
RETURNS varchar(100)
AS
BEGIN
declare @VarNew varchar(100),
@PadLen int
SET @VarNew=@VarOrgan
SET @PadLen=@TotalLength-LEN(@VarOrgan)
while(@PadLen>0)
begin
select @VarNew=@VarNew+@Placeholder
set @PadLen=@PadLen-1
前言 本文简单地介绍了一下我们平常下载的JDK到底都有些什么内容,这些内容的主要作用又是什么。对于以后我们研究JVM的运行原理会有一定的帮助。
JDK目录说明 安装完jdk之后,切换至jdk的安装根目录,可以看到几个目录:bin、jre、src.zip、db、lib、include。
bin:开发工具。里面可以看到一些我们很熟悉的工具,jar、java、javac、javadoc、javap、jconsole、jhat、jmap、jstack、jstat。jre:Java运行时环境。JRE包括Java虚拟机(JVM),类库和其他支持执行用Java编程语言编写的程序的文件(我们开发过程中经常使用到的核心类库就是在/jre/lib下)。src.zip:Java类库源代码。构成Java核心API的所有类的Java编程语言源文件,(注意不是JVM源码)主要是想帮助开发人员学习和使用Java编程语言。db:Oracle分发的Apache Derby关系数据库。lib:其他库,开发工具所需的其他类库和支持文件,其中就有我们比较熟悉的 dt.jar和tools.jar。include:支持使用Java Native Interface和Java Virtual Machine(JVM)调试器接口进行本机代码编程的C语言头文件。 我们可以重点关注前面三个目录。
javac/java工具 Java源代码(.java文件)需要经过编译后(使用javac命令),产生.Class文件,JVM才能识别并运行(使用java命令)它,只有含有main方法的class文件才能执行。JVM针对每个操作系统开发其对应的解释器,这就是Java能Write once, run anywhere.的原因。
JDK JRE JVM JDK(Java Development ToolKit):包含了Java运行环境(JRE)和开发工具(编译器,调试器,javadoc等)。我们就是依靠JDK来开发和运行Java程序的。
JRE(Java Runtime Environment) :JRE是指java运行环境。光有JVM还不能成class的执行,因为在解释class的时候JVM需要调用解释所需要的类库lib。在JDK的安装目录里你可以找到jre目录,里面有两个文件夹bin和lib,在这里可以认为bin里的就是jvm,lib中则是jvm工作所需要的类库,而jvm和 lib和起来就称为jre。
JVM(Java Virtual Machine):Java虚拟机,在运行时环境,JVM会将Java字节码解释成机器码。机器码和平台相关的(不同硬件环境、不同操作系统,产生的机器码不同),所以JVM在不同平台有不同的实现。
如果仅需要运行Java程序(执行.class文件),只利用jre就能完成(jre里有运行.class的java.exe)。
C/C++ 中的动态链接库 库:库是写好的现有的,成熟的,可以复用的代码。一般分为动态库与静态库。
静态库:在链接阶段,会将汇编生成的目标文件.o与引用到的库一起链接打包到可执行文件中。动态库:动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入。 PS:Windows系统的动态库是DLL文件,Linux系统是so文件,macOS系统的动态库则使用dylib文件作为动态库。
JVM 以什么形式存在 我们知道 JVM 是使用C/C++语言实现,它是以 动态链接 的形式存在于jre中。MAC系统下 /Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/server/libjvm.dylib就是JVM本体了。
java.exe是java class文件的执行程序,但实际上java.exe程序只是一个执行的外壳,它会装载jvm.dll(windows),这个动态连接库才是java虚拟机的实际操作处理所在。
OpenJDK OracleJDK 我们平常在oracle官网下载的JDK,是OracleJDK经过编译之后的Java开发运行工具集合。但是OracleJDK并不开源,如果我们想编译自己的JDK,可以选择下载OpenJDK的源码,然后自己编译,编译完之后就可以像平常在官网下载的JDK一样地使用它。可以大致的理解为,OpenJDK经过编译之后的JDK与OracleJDK基本是一致的。
参考文章: https://blog.csdn.net/weixin_44346035/article/details/90579274https://blog.csdn.net/kingscoming/article/details/78860702https://zhuanlan.zhihu.com/p/25713880https://www.jianshu.com/p/f98c3acd8df8
#include “torch/torch.h” #include “torch/script.h” 报错 C2872 “std“: 不明确符号 简述:经过一番折腾,安装好vs2017,cmake-3.20,Libtorch 1.8.2,cuda 10.1。准备大干一场的时候,发现测试代码跑不通,只要
#include “torch/torch.h”
#include “torch/script.h”
就会 报错 C2872 “std“: 不明确符号。
解决方案 经过多次检查配置项,无果。
后来发现这篇帖子,才提醒粗心的我。
重要的事情说三遍:
设置的问题:项目-》属性-》c/c++》常规》SDL检查:改为否 c/c++》语言》符合模式:选择:否。
记住一定要从项目-属性中进去
记住一定要从项目-属性中进去
记住一定要从项目-属性中进去
不要从Microsoft.Cpp.x64.user进入
不要从Microsoft.Cpp.x64.user进入
不要从Microsoft.Cpp.x64.user进入
快乐分享!
FFmpeg下载 1、下载ffmpeg安装包2、找到适合 你电脑的版本,win3、点击下载ZIP格式的,4、下载之后解压,bin里面可以看到三个安装文件5、配置环境, 点击“系统属性->高级系统设置->环境变量->用户变量”,选择“Path”条目,点击“编辑->新建”,把第一步的bin文件夹路径复制粘贴进去,然后点击确定即可 1、下载ffmpeg安装包 官网:https://www.ffmpeg.org/
2、找到适合 你电脑的版本,win 3、点击下载ZIP格式的, 4、下载之后解压,bin里面可以看到三个安装文件 5、配置环境, 点击“系统属性->高级系统设置->环境变量->用户变量”,选择“Path”条目,点击“编辑->新建”,把第一步的bin文件夹路径复制粘贴进去,然后点击确定即可 注意,此处我设置的是用户变量,仅当前windows用户可以使用,如果需要每个用户都能够使用,需要添加到“系统变量”的“Path”条目中。我们打开cmd命令行窗口,输入命令“ffmpeg –version”。窗口返回ffmpeg的版本信息,证明安装成功。
这里写目录标题 1、redis有关key的操作命令2、redis中关于string类型数据的操作命令3、redis中关于list类型数据的操作命令 单key 多valu有序4、redis中关于set类型数据的操作命令:单key 多value无序 不重复5、redis中关于hash类型数据的操作命令:单key,6、rdis中关于zset类型数据的操作命令 1、redis有关key的操作命令 1)查看数据库中的key:keys pattern ->*:匹配0个后多个字符 ->?:匹配一个字符 ->[]:匹配一个里边的一个字符 例如:keys *:查看数据库中所有的key keys k*:查看数据库中所有一卡头的key keys k?e:查看一k开头,一e结尾的,并且中间只有一个字符的key keys h[cde]llo:查看一h靠头,以o结尾,并且h后边只能在cde中取一个字符的key 2)判断某个key是否存在数据库中:exists key 如果存在,则返回1,否则返回0 exists key key key key 返回值是存在key的数量 3)移动指定的key到指定的数据库实例:move key index(库号) 4)查看指定key的剩余生存时间:ttl key 如果key在当前库不存在,返回2-;如果没有设置生存时间,返回-1 5)给可以设置最大生存时间:expire key seconds 超过时间后自动删除 expire 20; 6)查看指定可以的数据类型:type key 7)重命名key: rename key newkey 8)删除key:del key 删除指定的key,返回值实际删除key的数 2、redis中关于string类型数据的操作命令 1)将string类型的数据类型设置到redis中:set key keyvalue set zsname zhangsan set zsage 20 如果key已经存在了,则后来的value会把以前的value覆盖掉 2)从redis中获取string类型的数据:get key get zsname get zsage 3)追加字符串:append key value 返回追加之后的字符串长度,如果可以不存在,则新建一个key,并把value值设置进去 set phone 149990 append phone 123 4)获取字符串数据的长度:strlen key 5)将字符串数值进行加1运算:incr key |->返回加一后的数据 |->如果key不存在,首先设置一个key,初始值为0,然后ince运算 |->要求:key所表示的value必须是数值,否则报错 6)将字符串数值进行加1运算:decr key |->返回减一后的数据 |->如果key不存在,首先设置一个key,初始值为0,然后ince运算 |->要求:key所表示的value必须是数值,否则报错 7)将字符串数值进行加offset运算:incrby key offset |->返回加offset后的数据 |->如果key不存在,首先设置一个key,初始值为0,然后incrby运算 |->要求:key所表示的value必须是数值,否则报错 incrby zszge 10 8)将字符串数值进行加offset运算:decrby key offset |->返回减offset后的数据 |->如果key不存在,首先设置一个key,初始值为0,然后decrby运算 |->要求:key所表示的value必须是数值,否则报错 decrby zszge 10 9)获取字符串中的子字符串:getrange key startindex endindex 10)覆盖字符串:getrange key startindex value 用value来覆盖startindex下标开始的的字符串 11)设置字符串数据的同时,设置它的最大生命周期:setex key seconds value setex temp 5 1 12)设置string类型的数据value到数据库中,当key不存在时设置成功,否则放弃设置:setnx key value 13)批量将string类型的数据设置到redis中:mset key2 value1 key2 value2 .
int *a指的是定义一个指向int类型数据的指针a,指针
int a指的是定义一个整数变量a,
int* a跟int *a是同样的,只是int *a更严谨,
好比,int *a,b; 只有a是指针变量
int* a,b; 容易让人以为a和b都是指针code
#include void huhuan(int a,int b) {
printf("%d\n", a); //5
printf("%d\n", b); //3
int t;
t = a;
a = b;
b = t;
}
void huhuan_1(int *a, int *b) {
printf("%d\n", a); //a表示是是一个指针 输出的的 7600000
printf("%d\n", b); //7599988
int *t; //t必须是 int * 类型 不然类型不一致
t = a;
a = b;
b = t;
}
import asyncio import requests async def download_image(url): print("开始下载:", url) loop = asyncio.get_event_loop() # awaitable loop.run_in_executor(executor, func, *args) # 参数: executor可以是ThreadPoolExecutor / ProcessPool, 如果是None,则使用默认线程池 # requests模块默认不支持异步操作,所以就使用线程池来配合实现 future = loop.run_in_executor(None, requests.get, url) response = await future print("下载完成") # 把图片保存到本地 file_name = url.rsplit(',')[-1] with open(file_name, mode='wb') as file_object: file_object.write(response.content) if __name__ == '__main__': url_list = [ 'https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=3228549874,2173006364&fm=26&gp=0.jpg', 'https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=1485012388,2380514454&fm=26&gp=0.jpg', 'https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=2496571732,442429806&fm=26&gp=0.jpg', 'https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=1280325423,1024589167&fm=26&gp=0.jpg', ] tasks = [download_image(url) for url in url_list] loop = asyncio.get_event_loop() loop.run_until_complete(asyncio.wait(tasks))
第三章、概率论与数理统计 一、概率论基础1.1 概率论基础1.2 事件与概率1.3 古典概型与几何概型(最简单的概率分布) 二、条件概率2.1 条件概率2.2 全概率公式 三、概率分布与统计量3.1 概率分布类型3.2 期望与方差3.3 高斯分布 四、概率分布进阶4.1 分布函数4.2 均匀分布4.3 指数分布 五、联合分布5.1 二维随机变量及联合概率分布5.2 边缘概率 六、主成分分析法6.1 多维分布与协方差6.2 主成分分析法 一、概率论基础 1.1 概率论基础 1.1.1、概率论与数理统计定义
我们知道,自然界中的现象可化为为如下两类:
确定性现象:条件完全决定结果,比如太阳东升西落随机性现象:条件不完全决定结果(可能出现这样的结果,也可能出现那样的结果,预先无法断言),比如明天是否下雨 进一步,什么是概率论与数理统计呢?简而言之,二者都是对随机性现象进行研究的数学工具,具体来说如下:
随机性现象:具有不确定性与统计规律性概率论:从数量上研究随机现象的统计规律性的科学数理统计:从应用角度研究处理随机性数据,建立有效的统计方法,进行统计推理 1.1.2、随机试验定义
定义:在概率论中,将具有下述三个特点的试验称为随机试验,简称试验。随机试验常用E表示。
试验的可重复性——在相同条件下可重复进行一次试验结果的随机性——一次试验的可能结果不止一个,且试验之前无法确定具体是哪种结果出现全部试验结果的可知性——所有可能的结果是预先可知的,且每次试验有且仅有一个结果出现 例如:
E 1 E_1 E1抛一枚硬币,观察正面 H H H、反面 T T T出现的情况
E 2 E_2 E2掷一颗骰子,观察出现的点数
1.1.3 样本空间与样本点的定义
样本空间:试验的所有可能结果所组成的集合称为试验 E E E的样本空间,记为 Ω \Omega Ω样本点:试验的每一个可能出现的结果(样本空间中的元素)称为试验 E E E的一个样本点,记为 ω \omega ω。 例如:
E 1 E_1 E1:抛一枚硬币,观察正面 H H H、反面 T T T出现的情况; Ω 1 = { H , T } \Omega_1=\{H,T\} Ω1={H,T}
A.1 B.3 C.2 D.4
10. 若有说明和语句:int a=5,b=6;b*=a+1;则b的值为:( )
A.5 B.6 C.31 D.36
11. 设整型变量s,t,c1,c2,c3,c4的值均为2,则执行语句(s=c1==c2)||(t=c3>c4)后,s,t的值为:( )
A.1,2 B.1,1 C.0,1 D.1,0
12. 语句for(a=0,b=0;b!=100&&a<5;a++)scanf(“%d”,&b); scanf最多可执行次数为:( )
A.4 B.6 C.5 D.1
13. 对于for(s=2; ;s++)可以理解为:( )
A. for(s=2;0 ;s++) B. for(s=2;1 ;s++)
C. for(s=2;s<2 ;s++) D. for(s=2;s>2;s++)
14. 若有char h=`a`,g=`f`;int a[6]={1,2,3,4,5,6};则数值为4的表达式为:( )
A.a[g-h] B.a[4] C.a[`d`-`h`] D.a[`h`-`c`]
15. 设:char s[10]={“october”};则printf(“%d\n”,strlen(s));输出是:( )
A.7 B.8 C.10 D.11
16. 若有int a[3][5]={2,2},{2,6},{2,6,2}},则数组a共有个元素:( )
A.8 B.5 C.3 D.15
17. 设int a=5,b,*p=&a,则使b不等于5的语句为: ( )
中间语言 后缀式 图表示法 三地址代码 赋值语句的翻译 下面给出一个以三地址代码为中间语言的赋值语句的S属性文法
那个 || 表示连接上 不是表示或
比如 S->id := E 的语义规则 表示 S的三地址代码是由E的三地址代码再连接上一个 gen函数返回值
gen返回的是一段三地址代码
E.place = newtemp
表示先产生一个临时变量用于存放之后的运算结果,然后存储到E.place中
lookup查找在符号表中是否出现
newtemp 是临时变量,用于存储以后的运算结果
E.place 放的是运算结果的 名字 / 地址
最后 E -> id 表示的是 E的结果单元 E.place 就是 变量 id的结果单元, 单独一个变量,没有三地址代码,所以是 E.code = ’ ’
所以,他的语义动作就是调用 lookup函数,在符号表中查找变量标识符 id , 如果找到了,lookup就返回变量标识符的入口
数组元素引用的翻译 编译程序会对数组名和下标表达式列表进行分析和翻译,在目标程序或中间语言程序插入计算出要访问的数组元素的地址的代码
编译程序会生成两组计算数组元素地址的代码,一部分是红色的可变部分的代码,一部分是蓝色的不变部分的代码
不变部分所涉及的信息在数组声明的时候就确定了
Elist 表示表达式列表,放在 [ ]中,作为下标表达式列表
id[Elist] 叫做数组元素的引用,有时也叫做下表变量
Elist.ndim 表示处理到了第几维
带数组元素的赋值语句的翻译 L.place ’ [ ’ L.offset ’ [ ’ ’ := ’ E.
Linux上安装redis (redia-5.0.2)
第一步:下载redis (redia-5.0.2.tar.gz)
第二部:安装redis
1.在xftp中将redis的包拖拽进去(/home/mytest) 2.解压:tar -zxvf redia-5.0.2.tar.gz -C /usr/local/ 3.编译:make 前提要有gcc,没有的话就安装:yum -y install gcc 执行:gcc -v (查看,有linux版本就说明安装好了) 安装完gcc,执行:make distclean () 然后在:make 4.创建快捷方式:make install (创建后在任何路径下都可以使用redis的命令,不创建也可以,但是就要进入到bin目录下取执行命令) 6.启动redis:前台启动:redis-server 后台启动:redis-server & (*****最好是使用后台启动) 7.关闭redis:redis-cli shutdown
今天我们来给大家讲一下,基于之前我们说的ReadView机制是如何实现Read Committed隔离级别 的,那么当然了,首先就是要先做一些简单的回顾。
这个RC隔离级别,实际上意思就是说你事务运行期间,只要别的事务修改数据还提交了,你就是可以读 到人家修改的数据的,所以是会发生不可重复读的问题,包括幻读的问题,都会有的。
那么所谓的ReadView机制,之前我们讲过,他是基于undo log版本链条实现的一套读视图机制,他意 思就是说你事务生成一个ReadView,然后呢,如果是你事务自己更新的数据,自己是可以读到的,或 者是在你生成ReadView之前提交的事务修改的值,也是可以读取到的。 但是如果是你生成ReadView的时候,就已经活跃的事务,在你生成ReadView之后修改了数据,接着提 交了,此时你是读不到的,或者是你生成ReadView以后再开启的事务修改了数据,还提交了,此时也 是读不到的。 所以上面的那套机制,实际上就是ReadView机制的一个原理。好,那么既然都回顾完了,我们就来看 看,如何基于ReadView机制来实现RC隔离级别呢? 其实这里的一个非常核心的要点在于,当你一个事务设置他处于RC隔离级别的时候,他是每次发起查 询,都重新生成一个ReadView!
大家注意,这点是非常重要的,接着我们通过画图一步一步来给大家演示这个RC隔离级别是怎么做到 的。 首先假设我们的数据库里有一行数据,是事务id=50的一个事务之前就插入进去的,然后现在呢,活跃 着两个事务,一个是事务A(id=60),一个是事务B(id=70),此时如下图所示。
现在的情况就是,事务B发起了一次update操作,更新了这条数据,把这条数据的值修改为了值B,所 以此时数据的trx_id会变为事务B的id=70,同时会生成一条undo log,由roll_pointer来指向,看下图: 这个时候,事务A要发起一次查询操作,此时他一发起查询操作,就会生成一个ReadView,此时 ReadView里的min_trx_id=60,max_trx_id=71,creator_trx_id=60,此时如下图所示。
这个时候事务A发起查询,发现当前这条数据的trx_id是70。也就是说,属于ReadView的事务id范围之 间,说明是他生成ReadView之前就有这个活跃的事务,是这个事务修改了这条数据的值,但是此时这 个事务B还没提交,所以ReadView的m_ids活跃事务列表里,是有[60, 70]两个id的,所以此时根据 ReadView的机制,此时事务A是无法查到事务B修改的值B的。 接着就顺着undo log版本链条往下查找,就会找到一个原始值,发现他的trx_id是50,小于当前 ReadView里的min_trx_id,说明是他生成ReadView之前,就有一个事务插入了这个值并且早就提交 了,因此可以查到这个原始值,如下图。
接着,咱们假设事务B此时就提交了,好了,那么提交了就说明事务B不会活跃于数据库里了,是不是? 可以的,大家一定记住,事务B现在提交了。那么按照RC隔离级别的定义,事务B此时一旦提交了,说 明事务A下次再查询,就可以读到事务B修改过的值了,因为事务B提交了。 那么到底怎么让事务A能够独到提交的事务B修改过的值呢? 很简单,就是让事务A下次发起查询,再次生成一个ReadView。此时再次生成ReadView,数据库内活 跃的事务只有事务A了,因此min_trx_id是60,mac_trx_id是71,但是m_ids这个活跃事务列表里,只 会有一个60了,事务B的id=70不会出现在m_ids活跃事务列表里了,如下图。
此时事务A再次基于这个ReadView去查询,会发现这条数据的trx_id=70,虽然在ReadView的 min_trx_id和max_trx_id范围之间,但是此时并不在m_ids列表内,说明事务B在生成本次ReadView之 前就已经提交了。
那么既然在生成本次ReadView之前,事务B就已经提交了,就说明这次你查询就可以查到事务B修改过 的这个值了,此时事务A就会查到值B,如下图所示。
到此为止,RC隔离级别如何实现的,大家应该就理解了,他的关键点在于每次查询都生成新的 ReadView,那么如果在你这次查询之前,有事务修改了数据还提交了,你这次查询生成的ReadView 里,那个m_ids列表当然不包含这个已经提交的事务了,既然不包含已经提交的事务了,那么当然可以 读到人家修改过的值了。
这就是基于ReadView实现RC隔离级别的原理,希望大家好好仔细去体会,实际上,基于undo log多版 本链条以及ReadView机制实现的多事务并发执行的RC隔离级别、RR隔离级别,就是数据库的MVCC多 版本并发控制机制。 他本质是协调你多个事务并发运行的时候,并发的读写同一批数据,此时应该如何协调互相的可见性。
IDEA中解决<%@ taglib uri=“http://java.sun.com/jsp/jstl/core” prefix=“c”%>报错 使用IDEA做jsp项目时,用到了jstl,但是报错了。
原因是你没有引入相关的依赖。 在pom.xml文件中引入以下两个依赖,即可解决。
dependency> <groupId>org.apache.taglibs</groupId> <artifactId>taglibs-standard-spec</artifactId> <version>1.2.5</version> </dependency> <dependency> <groupId>org.apache.taglibs</groupId> <artifactId>taglibs-standard-impl</artifactId> <version>1.2.5</version> </dependency>
后台
import net.sf.json.JSONArray; try { JSONObject result = new JSONObject(); // 实体类 Arr0302Entity arr0302Entity = new Arr0302Entity(); JSONArray array=JSONArray.fromObject(arr0302Entity); result.put("arr0302Entity", array); response.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=UTF-8"); PrintWriter pw = response.getWriter(); pw.print(result); pw.close(); } catch (IOException e) { e.printStackTrace(); } 前台
$.ajax({ url : url, type : "post", async : false,// 同步执行 dataType : "json", success : function(result) { // ***No $("#***_no").val(result.arr0302Entity[0].***_no); } }, error : function(errorMsg) { alert("请求数据失败"); } }); 参考文档:https://www.cnblogs.com/Revival-of-everything/p/10820809.html
文章目录 php版本切换ubuntu安装VLDwindows安装VLD参考资料 php版本切换 从 PHP 5.x 切换到 PHP 8.x.
$ sudo a2enmod php8.0 #启用8.0版本 $ sudo a2dismod php5.6 #禁用5.6版本 这时候在浏览器查看phpinfo()应该就可以看到8.0版本了,但是命令行cli那里还是5.6,需要执行下面操作: $ sudo update-alternatives --set php /usr/bin/php8.0 $ sudo systemctl restart apache2 #重启服务器 安装PHP : 参考链接,https://learnku.com/php/t/51997
ubuntu安装VLD 查看有无安装VLD扩展,默认没有
php -i | grep “vld”下载vld拓展:wget http://pecl.php.net/get/vld-0.16.0.tgz解压缩:tar zxvf vld-0.16.0.tgz切换目录: cd vld-0.16.0生成configure文件 : phpize-----这个需要php 拓展,apt install php7.0-dev运行配置:./configure编译模块: make && make install
注意拓展路径
添加将扩展加入到php.ini中cd /etc/php/7.1/mods-availabletouch vld.ini #将以下的内容添加到文件中 ; configuration for php VLD module ; ; priority=20 extension=/usr/lib/php/20151012/vld.
原文链接:https://www.code404.icu/561.html
当使用命令 git pull 出现错误信息如下:
server certificate verification failed. CAfile: none CRLfile: none
解决方案:
git config --global http.sslverify false git config --global https.sslverify false git clone报错:“server certificate verification failed. CAfile: /etc/ssl/certs/ca-certificates.crt CRLfile: none”
I can push by clone project using ssh, but it doesn’t work when I clone project with https. it shows message error as below.
server certificate verification failed. CAfile: /etc/ssl/certs/ca-certificates.crt CRLfile: none
解决方案:
Open your terminal and run following command:
我们在做爬虫的过程中经常会遇到这样的情况:最初爬虫正常运行,正常抓取数据, 一切看起来都是那么好,然而 一杯茶的功夫可能就会出现错误,比如 403 Forbidden ;这时候网页上可能会出现“您的 IP 访问频率太高”这样的提示,或者跳出一个验证码让我们输入,之后才可能解封,但是一会之后又出现这种情况。
出现这个现象的原因是网站采取了一些反爬虫的措施。比如,服务器会检测某个 IP 在单位时间内的请求次数,如果超过了某个阈值,那么服务器会直接拒绝服务,返回一些错误信息。这种情况可以称为封 IP ,于是乎网站就成功把我们的爬虫禁掉。
代理的设置 之前介绍了多种请求库,如 requests、urllib、selenium 等。接下来我们来了解一下具体的代理如何使用,首先,我们来梳理一下这些请求库的代理设置方法。
获取代理 在测试之前,我们需要先获取一个可用代理,搜索引擎搜索“代理”关键字,就可以看到许多代理服务网站,网站上会有很多免费代理。但是免费代理大多情况下都是不好用的,所以比较靠谱的方法是购买付费代理。付费代理在很多网站上都有售卖,数量不用多,稳定可用即可,我们可以自行选购。
如果本机有相关代理软件的话,软件一般会在本机创建 HTTP 或 SOCKS 代理服务,本机直接使用此代理也可以。
在这里,我将使用代理:49.82.61.160:9999 来演示代理设置方法,设置代理测试的网址是 http://httpbin.org/get,我们访问该网址可以得到请求的相应信息,其中 origin 字段就是客户端的 IP,我们可以根据它来判断代理是否设置成功。
urllib 代理设置 首先,我们以最基础的 urllib 为例,来看一下代理的设置方法,在这里我们需要使用 ProxyHandler 处理器来设置代理,代码如下所示:
from urllib.request import ProxyHandler,build_opener proxy = '49.82.61.160:9999' proxy_handler = ProxyHandler({ 'http':'http://' + proxy, 'https':'https://' + proxy }) opener = build_opener(proxy_handler) try: response = opener.open('http://httpbin.org/get') print(response.read().decode('utf-8')) except: print('Error') 运行结果如下:
{ "args": {}, "headers": { "