当前位置: 首页 > news >正文

一文精通MVCC机制

MVCC(Multi-Version Concurrency Control)多版本并发控制机制

使用串行化隔离级别时,mysql会将所有的操作加锁互斥,来保证并发安全。这种方式必然降低并发性能。mysql在读已提交可重复读隔离级别下,对一行数据的读和写两个操作默认是不会通过加锁互斥来保证隔离性,避免了频繁加锁互斥。那么具体是如何实现的呢?首先要了解两个概念。

准备

建表语句

CREATE TABLE `product` ( `id` int NOT NULL AUTO_INCREMENT, `name` varchar(255) DEFAULT NULL, `price` int DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8;

undo日志版本链

  1. 我们向product表插入一条数据

INSERT INTO mysql_demo.product (id, name, price) VALUES (1, 'apple', 10);

此时mysql会同时向undo日志里写入一条记录。 trx_id为插入操作的事务id。这里随便写了一个80,意思一下。 roll_pointer后面再说。

  1. 这时候又来了一个事务,对数据进行了修改。比如事务id 300,修改price为20。此时mysql同样会在undo日志里写入一条记录。并且roll_pointer会指向前一条记录

  1. 以此类推,后续又有新的事务来操作这条记录,就会形成一条版本链,这条链就是undo日志版本链

每条数据对应着有一个undo日志版本链。

对于insert和update操作,mysql会向undo日志里添加一条记录。select操作不会产生记录。

对于删除的情况可以认为是update的特殊情况,会将版本链上最新的数据复制一份,然后将trx_id修改成删除操作的trx_id,同时在该条记录的头信息(record header)里的(deleted_flag)标记位写上true,来表示当前记录已经被删除,在查询时按照上面的规则查到对应的记录如果delete_flag标记位为true,意味着记录已被删除,则不返回数据。

在来看下什么是read view。

一致性试图read view机制

read view的生成

  • 可重复读隔离级别:事务开启后,首次执行任何select时会生成当前事务的read-view,在事务结束前不会变化。

  • 读已提交隔离级别:事务开启后,每次执行select时都会重新生成read-view。

read view的组成

这个视图由执行查询时所有未提交事务id数组(数组里最小的id为min_id)已创建的最大事务id(max_id)组成。

我们来举个例子。

  1. Transaction 80: 开启事务,插入一条记录。并且commit;

  1. Transaction 100:开启事务,执行update。生成事务id 100。这里需要注意begin和select不会生成事务id,所以加了一条无关的update,生成事务id。update内容可以忽略。

begin/start transaction 命令并不是一个事务的起点,在执行到它们之后的第一个修改操作InnoDB表的语句,事务才真正启动,才会向mysql申请事务id

mysql内部是严格按照事务的启动顺序来分配事务id的

  1. Transaction 200:同上

  1. Transaction 300:把价格修改成20了。并且commit了。

  1. select 1: select 不生成事务id。 事务开启后,首次执行任何select时会生成当前事务的read-view。

  1. Transaction 400:把价格修改成18了。

read view的组成 = 未提交事务id数组(数组里最小的id为min_id) + 已创建的最大事务id(max_id)组成

此时未提交事务id有100,200(80 已经提交了)。最小的id为100。 已创建的最大事务id为300。(注意read view 是在第5步生成的,此时还没有Transaction 400)

因此 read view为[100,200],300 min_id为100 ,max_id为300。 [100,200] 为视图数组。

此时对应的undo日志版本链如下

那么read view 的作用是什么呢?

read view的作用

根据上面的结果,我们可以将事务进行分类。因为事务的id是有序递增的。所以我们可以得出以下结论

  • 因为未提交事务的最小id(min_id)为100,所以小于100的事务都是已提交的。( Transaction 80)

  • 因为已创建的最大事务id(max_id)为300,所以大于300的区域都是未开启事务。 (Transaction 400) 未开启理解为在执行select的时候没有开启。

  • 介于min_id和max_id之间的事务,包含了未提交和已提交的事务。 (Transaction 100,200,300)

那么mysql是如何通过read view和undo日志版本链实现并发事务之间的隔离的呢?那就需要看下版本链比对规则了。

版本链比对规则

事务里的每一条select都需要从对应版本链里的最新数据开始逐条跟read-view做比对,按照比对规则得到最终的快照结果。下面我们来看下版本链比对规则。

  1. 如果 row 的 trx_id 落在绿色部分( trx_id

  1. 如果 row 的 trx_id 落在灰色部分( trx_id>max_id ),表示这个版本是由将来启动的事务生成的

  1. row 的 trx_id 就是当前自己的事务是可见的;

  1. 否则不可见;

  1. 如果 row 的 trx_id 落在黄色部分(min_id <=trx_id<= max_id),那就包括两种情况

  1. 若 row 的 trx_id 在视图数组中,表示这个版本是由还没提交的事务生成的,

  1. 若 row 的 trx_id 就是当前自己的事务是可见的

  1. 否则不可见;

  1. 若 row 的 trx_id 不在视图数组中,表示这个版本是已经提交了的事务生成的,可见。

知道了版本链的比对规则,下面我们通过实例来看下,mysql的MVCC机制是如何工作的。

实战演练

可重复读Repeatable-Read(RR)

我们先以可重复读Repeatable-Read(RR)为例

可重复读隔离级别:事务开启后,首次执行任何select时会生成当前事务的read-view,在事务结束前不会变化。

案例一

我们先以上面的情况为例来进行分析。此时的情况如下:

  • read view为 [100,200],300

  • undo日志版本链如下

  • 套用版本链比对规则

  1. 首先在版本链中找到最新数据。

  1. Transaction 300,trx_id = max_id。此时继续比对, trx_id 不在视图数组中,可见

  1. 返回Transaction 300记录的数据信息。price = 20;

案例二

Transaction 400,在第10行执行了一次update。

Transaction 100,在第11,12行执行了两次update。然后select 1 13行执行了一次select。 我们来分析下这个select。

  • 因为RR隔离级别首次执行任何select时会生成当前事务的read-view,在事务结束前不会变化。所以read view为 [100,200],300。没有变化。

  • undo日志版本链如下

  • 套用版本链比对规则

  1. 首先在版本链中找到最新数据。

  1. Transaction 100,trx_id = min_id。继续分析 trx_id 在视图数组中,表示这个版本是由还没提交的事务生成的,不可见。

  1. 第二行Transaction 100,分析同上

  1. 第三行Transaction 400, trx_id > max_id,不可见。

  1. Transaction 300,trx_id = max_id。此时继续比对,trx_id 不在视图数组中,可见

  1. 返回Transaction 300记录的数据信息。price = 20;

案例三

继续向下Transaction 100,在第15行commit。Transaction 200,在第15,16行执行了两次update。然后select1 17行执行了一次select。 我们来分析下这个select。

  • 因为RR隔离级别首次执行任何select时会生成当前事务的read-view,在事务结束前不会变化。所以read view为 [100,200],300。没有变化。

  • undo日志版本链如下

  • 套用版本链比对规则

  1. 首先在版本链中找到最新数据。

  1. Transaction 200,min_id < trx_id < max_id。继续分析 trx_id 在视图数组中,表示这个版本是由还没提交的事务生成的,不可见。

  1. 下一行Transaction 200,分析同上.

  1. Transaction 100,trx_id = min_id。继续分析 trx_id 在视图数组中,表示这个版本是由还没提交的事务生成的,不可见。

  1. 下一行Transaction 100,分析同上。

  1. 下一行Transaction 400, trx_id > max_id,不可见。

  1. Transaction 300,trx_id = max_id。此时继续比对,trx_id 不在视图数组中,可见

  1. 返回Transaction 300记录的数据信息。price = 20;

案例四

继续select2 17行执行了一次select。 我们来分析下这个select。

  • RR隔离级别首次执行任何select时会生成当前事务的read-view。read view为 [200,400],400。

  • undo日志版本链如下

  • 套用版本链比对规则

  1. 首先在版本链中找到最新数据。

  1. Transaction 200,trx_id = min_id。继续分析 trx_id 在视图数组中,表示这个版本是由还没提交的事务生成的,不可见。

  1. 下一行Transaction 200,分析同上.

  1. Transaction 100,trx_id < min_id。表示这个版本是已提交的事务生成的,这个数据是可见的;

  1. 返回 price = 16。

案例五

我们再来看一下如果select1 如果有update操作(update操作会创建事务id,我们假设是 500)。Transaction 500 此时是如何读取到更新后的数据的。

来分析下15行。

  • RR隔离级别首次执行任何select时会生成当前事务的read-view,在事务结束前不会变化。read view为 [100,200],300。

  • undo日志版本链如下

  • 套用版本链比对规则

  1. 首先在版本链中找到最新数据。

  1. Transaction 400,trx_id > max_id(read view是第一次select时生成的,此时max_id仍然是 300)。表示这个版本是由将来启动的事务生成的,是不可见的

  1. Transaction 500,trx_id > max_id。表示这个版本是由将来启动的事务生成的,但row 的 trx_id 就是当前自己的事务是可见的;所以可见

  1. 返回 price = 8。

结论:通过以上案例,我们可以知道。 MVCC机制在RR中首次查询时会固定read view。后续和其他事务隔离开了,其他事务对数据的操作不会影响到当前事务。

读已提交Read-Committed(RC)

我们再以读已提交Read-Committed(RC)为例

读已提交隔离级别:事务开启后,每次执行select时都会重新生成read-view。

案例一

第9行没有变化,我们来看第13行。

read view的组成 = 未提交事务id数组(数组里最小的id为min_id) + 已创建的最大事务id(max_id)组成

未提交事务id数组 100,200,400 ; min_id 100 ; max_id 400

  • read view为 [100,200,400],400。

  • undo日志版本链如下

  • 套用版本链比对规则

  1. 首先在版本链中找到最新数据。

  1. Transaction 100,trx_id = min_id。继续分析 trx_id 在视图数组中,表示这个版本是由还没提交的事务生成的,不可见。

  1. 下一行Transaction 100,分析同上.

  1. Transaction 400, trx_id = max_id。继续分析 trx_id 在视图数组中,表示这个版本是由还没提交的事务生成的,不可见。

  1. Transaction 300,min_id < trx_id< max_id。不在视图数组中,表示这个版本是已经提交了的事务生成的,可见。

  1. 返回 price = 20。

案例二

来看第17行。

read view的组成 = 未提交事务id数组(数组里最小的id为min_id) + 已创建的最大事务id(max_id)组成

未提交事务id数组 200,400 ; min_id 200 ; max_id 400

  • read view为 [200,400],400。

  • undo日志版本链如下

  • 套用版本链比对规则

  1. 首先在版本链中找到最新数据。

  1. Transaction 200, trx_id = min_id。继续分析 trx_id 在视图数组中,表示这个版本是由还没提交的事务生成的,不可见。

  1. 同上

  1. Transaction 100, trx_id

  1. 返回 price = 16。

OK,就分析到这里吧。希望对你有所帮助!

读已提交Read-Committed(RC)

我们再以读已提交Read-Committed(RC)为例

读已提交隔离级别:事务开启后,每次执行select时都会重新生成read-view。

案例一

第9行没有变化,我们来看第13行。

read view的组成 = 未提交事务id数组(数组里最小的id为min_id) + 已创建的最大事务id(max_id)组成

未提交事务id数组 100,200,400 ; min_id 100 ; max_id 400

  • read view为 [100,200,400],400。

  • undo日志版本链如下

  • 套用版本链比对规则

  1. 首先在版本链中找到最新数据。

  1. Transaction 100,trx_id = min_id。继续分析 trx_id 在视图数组中,表示这个版本是由还没提交的事务生成的,不可见。

  1. 下一行Transaction 100,分析同上.

  1. Transaction 400, trx_id = max_id。继续分析 trx_id 在视图数组中,表示这个版本是由还没提交的事务生成的,不可见。

  1. Transaction 300,min_id < trx_id< max_id。不在视图数组中,表示这个版本是已经提交了的事务生成的,可见。

  1. 返回 price = 20。

案例二

来看第17行。

read view的组成 = 未提交事务id数组(数组里最小的id为min_id) + 已创建的最大事务id(max_id)组成

未提交事务id数组 200,400 ; min_id 200 ; max_id 400

  • read view为 [200,400],400。

  • undo日志版本链如下

  • 套用版本链比对规则

  1. 首先在版本链中找到最新数据。

  1. Transaction 200, trx_id = min_id。继续分析 trx_id 在视图数组中,表示这个版本是由还没提交的事务生成的,不可见。

  1. 同上

  1. Transaction 100, trx_id

  1. 返回 price = 16。

OK,就分析到这里吧。希望对你有所帮助!

相关文章:

一文精通MVCC机制

MVCC(Multi-Version Concurrency Control)多版本并发控制机制使用串行化隔离级别时&#xff0c;mysql会将所有的操作加锁互斥&#xff0c;来保证并发安全。这种方式必然降低并发性能。mysql在读已提交和可重复读隔离级别下&#xff0c;对一行数据的读和写两个操作默认是不会通过…...

商用ESP32协议采集器源码分享开篇

这是一个关于chatGPT帮助嵌入式程序员开发商业项目的故事. 在开发这个项目的过程中,chatGPT发布了,在它的帮助下,项目开发量减少了10%,所以这个专栏,既是一个关于Micropython开发ESP32的专栏,也是一个程序员在AI的帮助下,提升效率,加速挣钱的案例. 看完之后,你将知道如何用mic…...

代码随想录算法训练营第三十四天 | 860.柠檬水找零,406.根据身高重建队列,452. 用最少数量的箭引爆气球

一、参考资料柠檬水找零https://programmercarl.com/0860.%E6%9F%A0%E6%AA%AC%E6%B0%B4%E6%89%BE%E9%9B%B6.html 根据身高重建队列 https://programmercarl.com/0406.%E6%A0%B9%E6%8D%AE%E8%BA%AB%E9%AB%98%E9%87%8D%E5%BB%BA%E9%98%9F%E5%88%97.html 用最少数量的箭引爆气球ht…...

DDR4介绍01

DDR4&#xff08;第四代双倍数据率同步动态随机存储器SDRAM&#xff09; 关于内存方面知识&#xff0c;大部分人、包括我自己也不是很懂&#xff0c;希望此篇文章能起到点作用&#xff0c;做硬件的就得把相关专业知识学牢了&#xff0c;尤其是专业术语。 下面是DDR4知识做一次…...

扫地机器人行业投资逻辑:国内以价换量元年,海外需求企稳回升

1、国内以价换量元年,投资逻辑由产品迭代转向行业的渗透率提升 2019-2022 年国内扫地机行业主要的投资逻辑是产品迭代的价增带动销额增长。 2019-2022 年国内热销的扫地机产品从单机向自清洁扫地机、全能基站扫地机持续迭 代升级,产品功能日益完善、瞄准用户痛点更新,真正实…...

(考研湖科大教书匠计算机网络)第四章网络层-第七节:IPv4数据报首部格式

获取pdf&#xff1a;密码7281专栏目录首页&#xff1a;【专栏必读】考研湖科大教书匠计算机网络笔记导航 文章目录一&#xff1a;IP数据报首部格式概述二&#xff1a;各字段作用概述&#xff08;1&#xff09;版本&#xff08;2&#xff09;首部长度和可选字段&#xff08;3&am…...

每天10个前端小知识 【Day 18】

前端面试基础知识题 1.如何实现单行&#xff0f;多行文本溢出的省略样式&#xff1f; 在日常开发展示页面&#xff0c;如果一段文本的数量过长&#xff0c;受制于元素宽度的因素&#xff0c;有可能不能完全显示&#xff0c;为了提高用户的使用体验&#xff0c;这个时候就需要…...

【Java集合类】ArrayList

内部结构 ArrayList内部核心是一个Object数组elementDataObject数组的长度&#xff08;length&#xff09;视为ArrayList当前的容量&#xff08;capacity&#xff09;size对象表示ArrayList当前的元素个数 类上的重要注释 内部是Object数组 允许put null值,会自动扩容 size、…...

页面置换算法

页面置换算法 在进程运行过程中&#xff0c;若需要访问的物理块不在内存中&#xff0c;就需要通过一定的方式来将页面载入内存&#xff0c;而此时内存很可能已无空闲空间&#xff0c;因此就需要一定的算法来选择内存中要被置换的页面&#xff0c;这种算法就被称为页面置换算法…...

算法导论【在线算法】—The Ski-Rental Problem、The Lost Cow Problem、The Secretary Problem

算法导论【在线算法】The Ski-Rental Problem问题描述在线算法证明The Lost Cow Problem问题描述在线算法类似问题—寻宝藏The Secretary Problem问题描述在线算法The Best Possible kThe Ski-Rental Problem 问题描述 假设你正在上滑雪课。每节课结束后&#xff0c;你决定&a…...

linux 下怎样给pdf 文件加书签

linux 下怎样给pdf 文件加书签 对于没有书签的pdf文件,怎样给pdf加标签呢? 以方便阅读. 以前总是要借助windows下pdf 工具, 叫什么来者? 忘了 记得是编辑一个用tab表示目录级别的文本文件, 有一种直观的感觉,大目录下嵌套着小目录 ..., 然后导入到文件中 linux 下有没有这种…...

[软件工程导论(第六版)]第2章 可行性研究(课后习题详解)

文章目录1. 在软件开发的早期阶段为什么要进行可行性研究&#xff1f;应该从哪些方面研究目标系统的可行性&#xff1f;2. 为方便储户&#xff0c;某银行拟开发计算机储蓄系统。储户填写的存款单或取款单由业务员输入系统&#xff0c;如果是存款&#xff0c;系统记录存款人姓名…...

[软件工程导论(第六版)]第3章 需求分析(课后习题详解)

文章目录1. 为什么要进行需求分析&#xff1f;通常对软件系统有哪些需求&#xff1f;2. 怎样与用户有效地沟通以获取用户的真实需求&#xff1f;3. 银行计算机储蓄系统的工作过程大致如下&#xff1a;储户填写的存款单或取款单由业务员输入系统&#xff0c;如果是存款则系统记录…...

基于分布鲁棒联合机会约束的能源和储备调度(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜…...

ETL和数据建模

一、什么是ETL ETL是数据抽取&#xff08;Extract&#xff09;、转换&#xff08;Transform&#xff09;、加载&#xff08;Load &#xff09;的简写&#xff0c;它是将OLTP系统中的数据经过抽取&#xff0c;并将不同数据源的数据进行转换、整合&#xff0c;得出一致性的数据&…...

ccc-pytorch-回归问题(1)

文章目录1.简单回归实战&#xff1a;2.手写数据识别1.简单回归实战&#xff1a; 用 线性回归拟合二维平面中的100个点 公式&#xff1a;ywxbywxbywxb 损失函数&#xff1a;∑(yreally−y)2\sum(y_{really}-y)^2∑(yreally​−y)2 迭代方法&#xff1a;梯度下降法&#xff0c;…...

【JAVA八股文】框架相关

框架相关1. Spring refresh 流程2. Spring bean 生命周期3. Spring bean 循环依赖解决 set 循环依赖的原理4. Spring 事务失效5. Spring MVC 执行流程6. Spring 注解7. SpringBoot 自动配置原理8. Spring 中的设计模式1. Spring refresh 流程 Spring refresh 概述 refresh 是…...

二叉树的相关列题!!

对于二叉树&#xff0c;很难&#xff0c;很难&#xff01;笔者也是感觉很难&#xff01;虽然能听懂课程&#xff0c;但是&#xff0c;对于大部分的练习题并不能做出来&#xff01;所以感觉很尴尬&#xff01;&#xff01;因此&#xff0c;笔者经过先前的那篇博客&#xff0c;已…...

Java设计模式 - 原型模式

简介 原型模式&#xff08;Prototype Pattern&#xff09;是用于创建重复的对象&#xff0c;同时又能保证性能。这种类型的设计模式属于创建型模式&#xff0c;它提供了一种创建对象的最佳方式。 这种模式是实现了一个原型接口&#xff0c;该接口用于创建当前对象的克隆。当直…...

深度学习中的 “Hello World“

Here’s an interesting fact—Each month, there are 186.000 Google searches for the keyword “deep learning.” 大家好✨,这里是bio🦖。每月有超18万的人使用谷歌搜索深度学习这一关键词,是什么让人们对深度学习如此感兴趣?接下来请跟随我来揭开深度学习的神秘面纱。…...

购买WMS系统前,有搞清楚与ERP仓库模块的区别吗

经常有朋友在后台询问我们关于WMS系统的问题&#xff0c;他们自己也有ERP系统&#xff0c;但是总觉得好像还差了点什么&#xff0c;不知道是什么。今天&#xff0c;我想通过本文&#xff0c;来向您简要地阐述ERP与WMS系统在仓储管理上的不同之处。 ERP仓库是以财务为导向的&…...

一文吃透 Spring 中的IOC和DI

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…...

分布式任务处理:XXL-JOB分布式任务调度框架

文章目录1.业务场景与任务调度2.任务调度的基本实现2.1 多线程方式实现2.2 Timer方式实现2.3 ScheduledExecutor方式实现2.4 第三方Quartz方式实现3.分布式任务调度4.XXL-JOB介绍5.搭建XXL-JOB —— 调度中心5.1 下载与查看XXL-JOB5.2 创建数据库表5.3 修改默认的配置信息5.4 启…...

【源码解析】Ribbon和Feign实现不同服务不同的配置

Ribbon服务实现不同服务&#xff0c;不同配置是通过RibbonClient和RibbonClients两个注解来实现的。RibbonClient注册的某个Client配置类。RibbonClients注册的全局默认配置类。 Feign实现不同服务&#xff0c;不同配置&#xff0c;是根据FeignClient来获取自定义的配置。 示…...

【webpack5】一些常见优化配置及原理介绍(二)

这里写目录标题介绍sourcemap定位报错热模块替换&#xff08;或热替换&#xff0c;HMR&#xff09;oneOf精准解析指定或排除编译开启缓存多进程打包移除未引用代码配置babel&#xff0c;减小代码体积代码分割&#xff08;Code Split&#xff09;介绍预获取/预加载(prefetch/pre…...

力扣sql简单篇练习(十九)

力扣sql简单篇练习(十九) 1 查询结果的质量和占比 1.1 题目内容 1.1.1 基本题目信息 1.1.2 示例输入输出 1.2 示例sql语句 # 用count是不会统计为null的数据的 SELECT query_name,ROUND(AVG(rating/position),2) quality,ROUND(count(IF(rating<3,rating,null))/count(r…...

线段树c++

前言 在谈论到种种算法知识与数据结构的时候,线段树无疑总是与“简单”和“平常”联系起来的。而这些特征意味着,线段树作为一种常用的数据结构,有常用性,基础性和易用性等诸多特点。因此,今天我来讲一讲关于线段树的话题。 定义 首先,线段树是一棵“树”,而且是一棵…...

HTML+CSS+JavaScript学习笔记~ 从入门到精通!

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录前言一、HTML1. 什么是HTML&#xff1f;一个完整的页面&#xff1a;<!DOCTYPE> 声明中文编码2.HTML基础①标签头部元素标题段落注释水平线文本格式化②属性3.H…...

LeetCode 430. 扁平化多级双向链表

原题链接 难度&#xff1a;middle\color{orange}{middle}middle 题目描述 你会得到一个双链表&#xff0c;其中包含的节点有一个下一个指针、一个前一个指针和一个额外的 子指针 。这个子指针可能指向一个单独的双向链表&#xff0c;也包含这些特殊的节点。这些子列表可以有一…...

2.5|iot|第1章嵌入式系统概论|操作系统概述|嵌入式操作系统

目录 第1章&#xff1a; 嵌入式系统概论 1.嵌入式系统发展史 2.嵌入式系统定义* 3.嵌入式系统特点* 4.嵌入式处理器的特点 5.嵌入式处理分类 6.嵌入式系统的应用领域及嵌入式系统的发展趋势 第8章&#xff1a;Linux内核配置 1.内核概述 2.内核代码结构 第1章&#xf…...

东莞企业怎么做网站建设/汕头seo托管

对于一般的List的排序可以使用java.util.Collections.sort(List, Comparator super T>)這樣簡單易用的方法。但是經常看到有人在問如何對元素的多字段排序。這個問題就像SQL語句裏面的‘Order By’語句&#xff0c;後面可以跟若干個排序條件。譬如對於元素Foo排序&#xff1…...

如何自己做资源类网站/百度seo优化推广公司

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2020年T电梯修理考试及T电梯修理操作证考试&#xff0c;包含T电梯修理考试答案和解析及T电梯修理操作证考试练习。由安全生产模拟考试一点通公众号结合国家T电梯修理考试最新大纲及T电梯修理考试真题汇总&#xff0c;…...

wordpress商业主题分享/武汉关键词seo排名

主要内容 线程概念 创建线程的两个方法 实现runnable()接口 重写Thread类中方法 两种方法的区别创建线程与方法调用区别 停止线程的两个方法 interrupt()强制打断 引入变量boolean flag 控制Thread类常用方法 sleep() interrupt() join() yield() setPriority(int newPriority)…...

单页网站如何优化/保定百度推广优化排名

这篇文章主要介绍了如何用phpExcel将Excel导入到Mysql数据库 &#xff0c;有一定的参考价值&#xff0c;感兴趣的朋友可以看看。1、http://phpexcel.codeplex.com/下载phpExcel2、代码如下&#xff1a;<?require_once PHPExcel.php;require_once PHPExcel/IOFactory.php;re…...

wordpress需要哪些插件/无锡网络推广平台

实用过创维酷开智能电视“电视派”功能的用户&#xff0c;大部分都可能会觉得很好用。不过&#xff0c;也有部分网友表示&#xff0c;在实际使用中碰到过&#xff0c;电视派控制设备连接wifi总是失败的现象。那么&#xff0c;出现这样的情况&#xff0c;我们用户又该如何处理呢…...

wordpress ssl设置/北京首页关键词优化

参考&#xff1a;https://blog.csdn.net/weixin_29432775/article/details/113018226 方法一 1、赋予脚本可执行权限(/opt/script/autostart.sh是你的脚本路径) chmod x /opt/script/autostart.sh 1 2、打开/etc/rc.d/rc/local文件&#xff0c;在末尾增加如下内容 /opt/sc…...