下单时如何保证数据一致性?

原创 哪吒 哪吒编程 2023-09-07 08:03 发表于辽宁

收录于合集#Redis11个

 

(给哪吒编程加星标,提高Java技能)

大家好,我是哪吒。

在前几篇文章中,提到了Redis实现排行榜、Redis数据缓存策略,让我们对Redis有了进一步的认识,今天继续进修,了解一下Redis在下单时是如何保证数据一致性的?

例如,在高并发访问下,可能会有多个请求同时读取同一份缓存数据,然后进行写操作,这就容易产生数据竞争的情况。同时,读写操作并不是原子性操作,可能在读取数据的时候,缓存已经被其他请求更新掉,从而导致数据不一致。

为了解决Redis缓存的数据一致性问题,我们需要做到以下两点:

  1. 保证所有请求都是读取最新的数据

  2. 保证所有更新操作都是互斥的并且按照请求的顺序执行

图片

在一个在线商城系统中,面临一个重要的问题:如何在订单支付过程中保证数据的一致性,并且如何优化支付操作的性能。

1、订单支付需求

在用户下单后,需要执行订单支付操作,确保支付和订单状态的一致性。

2、数据一致性要求

支付成功后,必须将订单状态更新为已支付,以保持数据的一致性。

3、高并发支付

在高并发的情况下,需要确保订单支付的性能和数据一致性。

为了解决以上问题,我们可以使用Redis提供的事务和管道机制。

一、Redis事务

1、什么是Redis事务

图片

在Redis中,事务是一组命令的集合,可以在一个单独的流程中执行,以保证这些命令的原子性、一致性、隔离性和持久性。

(1)事务概述

Redis事务由以下四个关键命令进行管理:

命令描述
MULTI开启事务,标记事务块的开始。
EXEC执行事务中的所有命令。
DISCARD取消事务,放弃所有已经入队的命令。
WATCH监视一个或多个键,用于乐观锁。

(2)Redis的事务特性

Redis事务具有以下关键特性:

事务特性描述
原子性事务中的所有命令要么全部执行,要么全部不执行。这确保了在事务执行期间,不会发生部分命令执行成功而部分命令执行失败的情况。
一致性事务中的命令会按照被添加的顺序执行,不会被其他客户端的命令打断。这保证了事务中的操作按照期望的顺序执行,不会受到并发操作的影响。
隔离性在事务执行期间,事务会被隔离,不会受到其他事务的影响。即使有其他并发事务在执行,事务中的操作也不会被其他事务看到,直到事务被执行提交。
持久性事务执行结束后对数据库的修改将被持久化到磁盘上。这确保了事务中的操作不会因为系统故障而丢失,从而保证了数据的持久性。

以上是Redis事务的基本概念和特性,它们保证了在Redis中执行的事务是可靠的、具备一致性的操作集合。

图片

上图形表示了Redis事务的关键特性之间的相互关系。这些特性相互支持,共同确保了Redis事务的可靠性和一致性。

  1. 原子性保证了事务中的操作要么全部成功,要么全部失败。

  2. 一致性保证了事务中的操作按照特定的顺序执行,不会受到其他操作的干扰。

  3. 隔离性确保了事务在执行期间与其他事务相互隔离,互不干扰。

  4. 持久性确保了事务执行后的修改会被持久保存,不会因系统故障而丢失。这些特性一起构成了Redis事务的可靠性和稳定性的基础。

2、使用Redis事务

(1)开始和提交事务

在Redis中,使用事务需要遵循以下步骤:

  1. 使用MULTI命令开启事务。

  2. 执行需要在事务中执行的命令。

  3. 使用EXEC命令提交事务,执行事务中的所有命令。

下面是一个使用Java代码示例的详细步骤:

// 创建与Redis服务器的连接
Jedis jedis = new Jedis("localhost", 6379);// 开启事务
Transaction transaction = jedis.multi();// 执行事务中的命令
transaction.set("key1", "value1");
transaction.set("key2", "value2");// 提交事务并获取执行结果
List<Object> results = transaction.exec();

在上面的示例中,transaction.set("key1", "value1") 和 transaction.set("key2", "value2") 这两个命令会被添加到事务队列中,当transaction.exec()被调用时,事务中的所有命令会被一起执行。如果在MULTIEXEC之间有错误发生,事务会被取消,命令不会执行。

(2)事务命令

在事务中,您可以使用常规的Redis命令,例如SETGETHSETZADD等等。这些命令会被添加到事务队列中,直到执行EXEC命令。

(3)事务示例

以下是使用Java代码示例来演示在事务中执行常见的Redis命令:

import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;public class RedisTransactionCommandsExample {public static void main(String[] args) {Jedis jedis = new Jedis("localhost", 6379);// 开启事务Transaction transaction = jedis.multi();// 执行事务中的命令transaction.set("name", "Alice");transaction.hset("user:1", "name", "Bob");transaction.zadd("scores", 100, "Alice");transaction.zadd("scores", 200, "Bob");// 提交事务并获取执行结果List<Object> results = transaction.exec();// 打印执行结果for (Object result : results) {System.out.println("Result: " + result);}// 关闭连接jedis.close();}
}

在上述示例中,使用了SETHSETZADD命令,这些命令被添加到了事务队列中。当执行transaction.exec()时,事务中的所有命令会被一起执行。这里的示例是简单的演示,您可以根据需要添加更多的命令来构建更复杂的事务。

图片

二、Redis管道

1、什么是Redis管道

Redis管道(Pipeline)是一种优化Redis操作的技术,它允许在单次通信中发送多个命令到Redis服务器,从而显著减少了通信开销,提高了性能。

管道可以将多个命令一次性发送给服务器,而不需要等待每个命令的响应,这使得Redis能够更高效地处理批量操作和大规模数据的读写。

下图展示了Redis管道的工作原理:

图片

在上图中,客户端(Client)向Redis服务器(Server)发送多个命令,每个命令用Command 1Command 2等表示。这些命令被一次性发送到服务器,而不需要等待每个命令的响应。服务器在执行所有命令后,一次性将结果响应给客户端。同时说明了Redis管道的工作方式:通过将多个命令打包成一次通信,减少了每个命令的通信开销,提高了系统的性能。

使用Redis管道时,客户端通过创建一个管道对象,将多个命令添加到管道中,然后一次性执行管道中的命令。最后,客户端可以收集所有命令的执行结果。

(1)管道概述

在Redis中,管道是通过以下命令进行管理:

命令描述
PIPELINE开启管道模式,用于一次性发送多个命令。
MULTI开启事务模式,用于在管道中执行一系列命令。
EXEC提交管道中的事务,执行并返回结果。

使用管道,您可以将多个命令一次性发送给服务器,然后通过一次通信获得所有命令的执行结果,从而减少了每个命令的通信开销,提高了系统的性能。

(2)Redis的管道特性

使用Redis管道可以获得以下优势:

  • 减少通信开销: 在普通的命令传输中,每个命令都需要来回的网络通信,而管道可以将多个命令打包一次性发送给服务器,从而大大减少了通信开销。这对于网络延迟较高的场景尤为重要,有效提高了性能。

  • 提高吞吐量: 管道允许在一次通信中执行多个命令,从而在单位时间内处理更多的命令。这对于需要处理大量命令的场景,如批量数据处理、并发请求处理等,能够有效提高Redis的吞吐量和响应能力。

2、使用Redis管道

(1)管道命令

以下是一个实际案例,展示如何使用Redis管道来执行多个命令并提高性能:

import redis.clients.jedis.Jedis;
import redis.clients.jedis.Pipeline;
import java.util.List;public class RedisPipelineExample {public static void main(String[] args) {Jedis jedis = new Jedis("localhost", 6379);// 创建管道Pipeline pipeline = jedis.pipelined();// 向管道中添加命令for (int i = 0; i < 10000; i++) {pipeline.set("key" + i, "value" + i);}// 执行管道中的命令List<Object> results = pipeline.syncAndReturnAll();// 关闭连接jedis.close();}
}

在上述案例中,使用了一个循环来向管道中添加10000个SET命令。通过使用管道,可以在一次通信中将所有命令发送到服务器,而不是逐个发送,从而减少了通信开销,提高了性能。

(2)管道优化性能

使用Redis管道可以提高性能,特别是在需要批量处理多个命令的情况下。管道的原理是一次性将多个命令发送给服务器,然后一次性获取结果,这减少了通信的往返次数,从而显著提高了吞吐量。

然而,需要注意以下几点:

  • 管道不支持事务,不能保证多个命令的原子性执行。

  • 使用管道时,命令的执行顺序可能与添加顺序不一致,这需要根据业务需求进行考虑。

  • 管道并非在所有场景下都能带来性能提升,需要根据实际情况进行评估。

通过合理使用管道,可以最大限度地发挥Redis在高性能数据处理中的优势。

图片

三、事务 vs 管道:何时使用何种

1、事务的适用场景

事务在某些场景下可以保证原子性和一致性的操作,特别适用于强一致性要求的业务操作,例如支付操作。

(1)强一致性操作

事务是一种适用于需要强一致性操作的机制。当多个命令需要在一个操作序列中原子性地执行时,事务可以确保这些命令要么全部执行,要么全部不执行,以保持数据的一致性。

在以下示例中,模拟一个银行转账操作,其中需要同时扣减一个账户的余额并增加另一个账户的余额:

Jedis jedis = new Jedis("localhost", 6379);// 开启事务
Transaction transaction = jedis.multi();// 扣减账户1余额
transaction.decrBy("account1", 100);// 增加账户2余额
transaction.incrBy("account2", 100);// 提交事务并获取执行结果
List<Object> results = transaction.exec();// 关闭连接
jedis.close();

(2)原子性要求高

当业务要求多个操作要么全部成功,要么全部失败时,事务是更好的选择。事务确保了事务中的一系列命令以原子操作方式执行,从而维护了数据的一致性。

2、管道的适用场景

管道适用于需要批量操作和吞吐量要求较高的场景。通过一次性发送多个命令到服务器,可以减少通信开销,提高性能。

(1)批量操作

使用管道可以有效地执行批量操作。例如,当您需要向数据库中添加大量数据时,使用管道可以减少每个命令的通信成本,从而大大提高操作的效率。

以下示例演示了如何使用管道进行批量设置操作:

import redis.clients.jedis.Jedis;
import redis.clients.jedis.Pipeline;
import java.util.List;public class RedisPipelineBatchExample {public static void main(String[] args) {Jedis jedis = new Jedis("localhost", 6379);Pipeline pipeline = jedis.pipelined();// 向管道中添加一批设置操作for (int i = 0; i < 1000; i++) {pipeline.set("key" + i, "value" + i);}// 执行管道中的命令List<Object> results = pipeline.syncAndReturnAll();// 关闭连接jedis.close();}
}

(2)吞吐量要求高

在需要高吞吐量的场景下,管道可以显著提升性能。当多个命令需要在短时间内执行时,使用管道可以将这些命令打包发送,减少了通信的往返次数。

使用管道来进行大规模数据处理时,尤其可以在高负载的情况下提高系统的处理能力。

图片

四、案例研究:保证订单支付的数据一致性与性能优化

1、场景描述

在一个在线商城系统中,面临一个重要的问题:如何在订单支付过程中保证数据的一致性,并且如何优化支付操作的性能。

(1)订单支付需求

在用户下单后,需要执行订单支付操作,确保支付和订单状态的一致性。

(2)数据一致性要求

支付成功后,必须将订单状态更新为已支付,以保持数据的一致性。

(3)高并发支付

在高并发的情况下,需要确保订单支付的性能和数据一致性。

2、使用Redis事务解决数据一致性问题

(1)事务实现订单支付

Jedis jedis = new Jedis("localhost", 6379);
Transaction transaction = jedis.multi();// 扣除用户余额
transaction.decrBy("user:balance:1", orderAmount);// 更新订单状态为已支付
transaction.hset("order:1", "status", "paid");List<Object> results = transaction.exec();

以上示例中,使用了Redis事务来确保在一个操作序列中,用户余额的扣除和订单状态的更新同时发生。如果事务中的任何一步操作失败,整个事务都会被回滚,保证了数据的一致性。

(2)事务的一致性保证

使用事务可以保证用户余额和订单状态的一致性,要么同时成功,要么同时失败。这样,可以确保支付和订单状态的正确性,避免了潜在的数据不一致问题。

3、使用Redis管道优化支付性能

(1)管道批量支付

Jedis jedis = new Jedis("localhost", 6379);
Pipeline pipeline = jedis.pipelined();for (Order order : orders) {pipeline.decrBy("user:balance:" + order.getUserId(), order.getAmount());pipeline.hset("order:" + order.getId(), "status", "paid");
}List<Object> results = pipeline.syncAndReturnAll();

在这个示例中,使用了Redis管道来批量处理多个订单的支付。通过将多个命令一次性发送给服务器,可以减少通信开销,从而显著提高支付操作的性能。

(2)管道的性能提升

通过使用管道,可以将多个支付操作打包在一次通信中进行,减少了通信往返次数,从而提高了支付的性能。

尤其在高并发支付的场景下,管道可以显著减少服务器负载,提高系统的响应能力。

图片

五、事务和管道的限制与注意事项

1、事务的限制

事务在使用过程中需要注意以下限制,其中包括WATCH命令和乐观锁的使用。

(1)WATCH命令

在事务中使用WATCH命令可以监视一个或多个键,如果被监视的键在事务执行过程中被其他客户端修改,事务会被中断。这是为了保证事务的一致性和避免竞态条件。

正面例子:

Jedis jedis = new Jedis("localhost", 6379);
Transaction transaction = jedis.multi();// 监视键"balance"
transaction.watch("balance");// ... 在此期间可能有其他客户端修改了"balance"键的值 ...// 执行事务
List<Object> results = transaction.exec();

反面例子:

Jedis jedis = new Jedis("localhost", 6379);
Transaction transaction = jedis.multi();// 监视键"balance"
transaction.watch("balance");// ... 在此期间其他客户端修改了"balance"键的值 ...// 尝试执行事务,但由于"balance"键被修改,事务会被中断
List<Object> results = transaction.exec();

(2)乐观锁

在处理并发更新时,可以使用乐观锁的方式。通过使用版本号或时间戳等机制,在执行命令前先检查数据是否被其他客户端修改过,从而避免并发冲突。

正面例子:

Jedis jedis = new Jedis("localhost", 6379);// 获取当前版本号
long currentVersion = Long.parseLong(jedis.get("version"));// 更新数据前检查版本号
if (currentVersion == Long.parseLong(jedis.get("version"))) {Transaction transaction = jedis.multi();transaction.set("data", "new value");transaction.incr("version");List<Object> results = transaction.exec();
} else {// 数据已被其他客户端修改,需要处理冲突
}

2、管道的注意事项

使用管道时需要注意以下事项,包括管道的串行性和慎重使用。

(1)不支持事务

管道不支持事务,因此无法通过管道实现事务的原子性和一致性。如果需要事务支持,应该使用Redis的事务机制。

(2)慎用管道

管道虽然可以提高性能,但并不是在所有场景下都能带来性能提升。在某些情况下,由于管道的串行性,某些命令可能会阻塞其他命令的执行,反而降低了性能。

正面例子:

Jedis jedis = new Jedis("localhost", 6379);
Pipeline pipeline = jedis.pipelined();for (int i = 0; i < 1000; i++) {pipeline.set("key" + i, "value" + i);
}// 执行管道中的命令并获取结果
List<Object> results = pipeline.syncAndReturnAll();

反面例子:

Jedis jedis = new Jedis("localhost", 6379);
Pipeline pipeline = jedis.pipelined();for (int i = 0; i < 1000; i++) {// 注意:此处执行了耗时的命令,可能阻塞其他命令的执行pipeline.get("key" + i);
}// 执行管道中的命令并获取结果
List<Object> results = pipeline.syncAndReturnAll();

六、总结

本篇博客深入探讨了Redis中的事务和管道机制,以及它们在保证数据一致性和优化性能方面的应用。

通过详细的讲解和代码示例,我们了解了事务和管道的基本概念、特性、使用方法以及适用场景。以下是本篇博客的主要内容总结:

Redis事务部分,我们了解了事务的概念和特性。事务可以确保一系列命令的原子性、一致性、隔离性和持久性。

通过MULTI、EXEC、DISCARD和WATCH命令,我们可以管理事务的开始、提交、回滚以及监视键变化。事务适用于需要保证原子性和一致性的操作,特别是在强一致性要求的场景下。

Redis管道部分,我们深入了解了管道的概念和优势。管道允许一次性发送多个命令到服务器,减少通信开销,提高性能。

通过PIPELINE、MULTI和EXEC命令,我们可以创建管道、添加命令,并执行管道中的命令。管道适用于批量操作和吞吐量要求较高的场景,可以显著提高Redis的性能。

事务 vs 管道:何时使用何种部分,我们对比了事务和管道的适用场景。

  1. 事务适用于保证强一致性操作和原子性要求高的场景;

  2. 管道适用于批量操作和高吞吐量的场景。

通过示例,我们说明了如何根据业务需求选择合适的机制来满足一致性和性能的需求。

案例研究:保证订单支付的数据一致性与性能优化部分,我们应用之前的知识解决了一个实际问题。我们展示了如何使用事务保证订单支付的数据一致性,同时如何使用管道优化支付操作的性能。这个案例充分体现了事务和管道在实际业务中的应用。

事务和管道的限制与注意事项部分,我们指出了事务和管道的一些限制和注意事项。事务受到WATCH命令和乐观锁的限制,而管道不支持事务,并且需要在使用时慎重考虑性能影响。

通过本篇博客,我们详细探讨了Redis中的事务和管道机制,了解了它们如何在实际应用中保证数据一致性和优化性能。无论是强调一致性还是追求性能,都可以根据业务需求选择合适的机制来达到最佳效果。

 

图片

 

兄弟,王者荣耀的段位排行榜是通过Redis实现的?

离谱!面试为啥都问Redis缓存?赶紧补一下

图解Dubbo,Dubbo服务治理详解

2023年再不会K8S,就要被淘汰了,手把手带你飞

10000字,图解分布式系统限流平台Sentinel

图解Nginx,系统架构演变 + Nginx反向代理与负载均衡

图解Nacos,注册中心演变 + Nacos核心功能

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/72293.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

VSCode学习笔记一:添加代码模板

一目了然 1 简述2 设置模板3 Global Snippets file示例 1 简述 问&#xff1a;为什么要设置代码模板&#xff1f; 答&#xff1a;编程语言是有个性的&#xff0c;不同语言的演讲风格是不一样的。 旁白&#xff1a;我不懂&#xff1f;&#xff01; 问&#xff1a;为什么要设置…

qt作业day4

//clock_exercise.cpp#include "clock_timer.h" #include "ui_clock_timer.h"//时间事件处理函数 void Clock_Timer::timerEvent(QTimerEvent *event) {if(event->timerId() time_id){sys_tm QDateTime :: currentDateTime(); // int year sy…

【c++】如何有效地利用命名空间?

​ &#x1f331;博客主页&#xff1a;青竹雾色间 &#x1f618;博客制作不易欢迎各位&#x1f44d;点赞⭐收藏➕关注 ​✨人生如寄&#xff0c;多忧何为 ✨ 目录 前言什么是命名空间&#xff1f;命名空间的语法命名空间的使用避免命名冲突命名空间的嵌套总结 前言 当谈到C编…

直播APP源码搭建:核心的服务器系统

在现代科技的推动下&#xff0c;网络衍生出了各种各样的技术&#xff0c;每个技术都被应用到需要的APP上&#xff0c;直播APP源码搭建出来的APP就是其中的一个&#xff0c;然而&#xff0c;这些技术能够成功的在直播APP源码搭建的APP中稳定的为用户们提供功能与服务&#xff0c…

芯科蓝牙BG27开发笔记-新建示例工程

此笔记的必要性 芯科的官方资料很丰富&#xff0c;并且ssv5中能方便索引到所需文档&#xff0c;不过大而全的问题就是找不到合适的切入点&#xff0c;更不会有本地化比较好的中文的系统的教程了。往往看到一个starting guide&#xff0c;会延伸其他starting guide&#xff0c;…

Docker从认识到实践再到底层原理(四-2)|Docker镜像仓库实战案例

前言 那么这里博主先安利一些干货满满的专栏了&#xff01; 首先是博主的高质量博客的汇总&#xff0c;这个专栏里面的博客&#xff0c;都是博主最最用心写的一部分&#xff0c;干货满满&#xff0c;希望对大家有帮助。 高质量博客汇总 然后就是博主最近最花时间的一个专栏…

污水处理厂3D数字孪生三维可视系统降低设备风险隐患

当相对传统与保守的水务行业&#xff0c;与激进与开放的互联网发生碰撞之后&#xff0c;产生了最好的一个名词是&#xff1a;“智慧水务”&#xff0c;谈及智慧水务&#xff0c;自然免不了当下最具热度的技术“元宇宙”&#xff0c;水资源再生是我国追求高质量发展的新策略&…

软件测试/测试开发丨Selenium Web自动化多浏览器处理

点此获取更多相关资料 本文为霍格沃兹测试开发学社学员学习笔记分享 原文链接&#xff1a;https://ceshiren.com/t/topic/27185 一、多浏览器测试介绍 1.1、多浏览器测试背景 用户使用的浏览器(firefox,chrome,IE 等)web 应用应该能在任何浏览器上正常的工作&#xff0c;这样…

springboot整合elasticsearch使用案例

引入依赖 <dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId> </dependency> 添加注入 import org.apache.http.HttpHost; import org.elasticsearch.client.Res…

2594. 修车的最少时间

文章目录 Tag题目来源题目解读解题思路方法一&#xff1a;二分枚举答案 写在最后 Tag 【二分枚举答案】【数组】 题目来源 2594. 修车的最少时间 题目解读 给你一个表示机械工能力的数组 ranks&#xff0c;ranks[i] 表示第 i 位机械工可以在 r a n k s [ i ] ∗ n 2 ranks[…

[docker]笔记-存储管理

1、docker数据存储分为非永久性存储和永久性存储。 非永久性存储&#xff1a;容器创建会默认创建非永久性存储&#xff0c;该存储从属于容器&#xff0c;生命周期与容器相同&#xff0c;会随着容器的关闭而消失&#xff08;可理解为内存中数据&#xff0c;会随关机而消失&…

PHP表单token验证防CSRF攻击

在PHP中&#xff0c;表单token是一种安全机制&#xff0c;用于防止跨站请求伪造&#xff08;CSRF&#xff09;攻击。 CSRF攻击是一种利用用户身份在未经授权的情况下执行非法操作的攻击方式。 表单token的原理是在表单中生成一个随机的token&#xff0c;并将其存储在服务器端…

12. 自动化项目实战

目录 1. 登录测试 2. 测试首页的帖子列表数不为0 3. 帖子详情页校验 4. 发布帖子 5. 退出登录 自动化项目实施的基本流程如下图所示&#xff1a; 手工测试用例、自动化测试用例。 1. 登录测试 校验登录后主页显示的用户名称和登录时输入的用户名是否相等。 public class…

自动化运维工具Ansible教程(二)【进阶篇】

文章目录 前言Ansible 入门到精通自动化运维工具Ansible教程(一)【入门篇】自动化运维工具Ansible教程(二)【进阶篇】精通篇 进阶篇1. Ansible 的高级主题&#xff08;例如&#xff1a;角色、动态清单、变量管理等&#xff09;**1. 角色&#xff08;Roles&#xff09;**&#x…

WangEditor在Vue前端的应用

1、在Vue项目中安装WangEditor 对于Vue2&#xff1a; npm install wangeditor/editor-for-vue --save 或者 yarn add wangeditor/editor-for-vue 对于Vue3&#xff1a; npm install wangeditor/editor-for-vuenext --save 或者 yarn add wangeditor/editor-for-vuenext 2、将Wa…

Mac brew -v 报错 fatal: detected dubious ownership in repository

Mac 电脑查询 brew版本时报错&#xff0c;如下错误&#xff1a; Last login: Fri Sep 8 14:56:21 on ttys021 sunshiyusunshiyudeMacBook-Pro-2 ~ % brew -v Homebrew 4.0.3-30-g7ac31f7 fatal: detected dubious ownership in repository at /usr/local/Homebrew/Library/Ta…

l8-d9 UDP通信实现

一、函数接口扩展与UDP通信实现流程 1.write/read到send/recv 函数原型&#xff1a; ssize_t send(int sockfd, const void *buf, size_t len, int flags); ssize_t recv(int sockfd, void *buf, size_t len, int flags); 前三个参数同read/write一样&#xff1b; ssize_t rea…

Java-HashMap中put()方法是如何实现的,内含详细流程图

文章目录 Java中的HashMap什么是HashMap&#xff1f;对比其他Map中put()方法HashMap中put()方法使用示例 HashMap中put()源码解析手绘流程图实现原理源码探究&#xff08;JDK 1.8&#xff09; 设计put()的意义总结 Java中的HashMap 什么是HashMap&#xff1f; HashMap是Java中…

羊城杯2023 部分wp

目录 D0nt pl4y g4m3!!!(php7.4.21源码泄露&pop链构造) Serpent(pickle反序列化&python提权) ArkNights(环境变量泄露) Ez_misc(win10sinpping_tools恢复) D0nt pl4y g4m3!!!(php7.4.21源码泄露&pop链构造) 访问/p0p.php 跳转到了游戏界面 应该是存在302跳转…

1783_CMD启动MATLAB同时执行一个脚本

全部学习汇总&#xff1a; GitHub - GreyZhang/g_matlab: MATLAB once used to be my daily tool. After many years when I go back and read my old learning notes I felt maybe I still need it in the future. So, start this repo to keep some of my old learning notes…