C++中实现雪花算法来在秒级以及毫秒及时间内生成唯一id

在这里插入图片描述

1、雪花算法原理

雪花算法(Snowflake Algorithm)是一种用于生成唯一ID的算法,通常用于分布式系统中,以确保生成的ID在整个分布式系统中具有唯一性。它的名称来源于雪花的形状,因为生成的ID通常是64位的整数,其二进制结构看起来像雪花。

雪花算法(Snowflake Algorithm)的实现原理相对简单,主要通过将一个64位的整数分成不同的部分来确保生成的ID在分布式系统中具有唯一性和有序性。以下是雪花算法的主要实现原理:
在这里插入图片描述

  • 时间戳部分(41位): 雪花算法使用了41位来表示时间戳。这些位用于存储自"雪花纪元"(一个自定义的固定时间点,通常是系统首次启动的时间)以来的毫秒数。由于使用41位来表示时间戳,因此可以表示的时间范围大约为69年。

    • 雪花算法的时间戳部分是算法中非常重要的一部分,它用于确保生成的唯一ID在分布式系统中具有一定的有序性。以下是雪花算法时间戳部分的原理:

    • 时间戳的起始点(雪花纪元): 雪花算法中的时间戳是以一个自定义的起始时间点为基准的。这个起始时间点通常称为"雪花纪元"(Snowflake Epoch),它是一个固定的时间点,作为时间戳的起始值。通常情况下,雪花纪元是一个可配置的值,可以根据需要设置。例如,可以将雪花纪元设置为系统首次启动的时间点或其他特定时间。

    • 毫秒级时间戳: 雪花算法使用毫秒级别的时间戳来表示从雪花纪元开始的时间流逝。这个时间戳是一个整数值,通常占据41位。这意味着,从雪花纪元开始计算,可以表示的时间范围大约为69年,因为 2^41 毫秒大约等于69年。

    • 时间戳的递增: 时间戳部分的值在每次生成唯一ID时都会递增。这是确保生成的ID在一定程度上具有有序性的关键因素。在同一毫秒内生成的ID,时间戳部分的值相同;而在不同毫秒生成的ID,时间戳部分的值会递增。

    • 时钟同步和时钟回拨处理: 为了保持时间戳的准确性,分布式系统中的机器需要进行时钟同步,以确保它们的系统时钟是一致的。此外,雪花算法还包括时钟回拨处理,以防止系统时钟回拨。如果检测到时钟回拨,算法会等待,直到时钟回拨结束为止。

    • 总之,雪花算法的时间戳部分是基于一个自定义的起始时间点(雪花纪元)开始计算的,使用毫秒级别的时间戳表示时间的流逝。通过递增时间戳部分的值,确保在分布式系统中生成的唯一ID具有一定的有序性。时钟同步和时钟回拨处理也是算法中的重要部分,用于维护时间戳的准确性。这种设计使得雪花算法适用于大规模分布式系统中生成唯一ID的需求。

  • 数据中心ID(5位): 数据中心ID用于区分不同的数据中心。这部分通常在多数据中心的环境中使用,以确保每个数据中心分配的机器具有不同的标识。数据中心ID的范围是0到31(5位二进制)。

  • 工作机器ID(5位): 工作机器ID用于区分同一数据中心内的不同机器。这确保了在同一数据中心中的多台机器生成的ID不会冲突。工作机器ID的范围也是0到31(5位二进制)。

  • 序列号部分(12位): 序列号部分用于处理同一毫秒内生成多个ID的情况,以防止ID冲突。通过使用12位的序列号,可以在同一毫秒内生成4096个不同的ID。

  • 位移和运算: 在生成唯一ID时,将各个部分的值左移位并执行逻辑或(OR)运算,将它们组合成一个64位的整数。

  • 唯一性和有序性: 通过使用不同的数据中心ID、工作机器ID和序列号来区分不同的机器和请求,并通过时间戳部分确保ID的有序性。时间戳部分在生成ID时递增,确保较新生成的ID总是大于较旧的ID。

  • 时钟回拨处理: 雪花算法还包括时钟回拨处理,以防止时钟回拨(即系统时间向后调整)。如果检测到时钟回拨,算法会等待,直到时钟回拨结束为止。

    • 在雪花算法的实际应用中,时钟同步和时钟回拨通常需要由系统管理员或开发人员来实现和处理。雪花算法本身并没有提供内置的时钟同步和时钟回拨处理机制,而是依赖于系统环境来确保时钟的准确性。

    • 以下是关于时钟同步和时钟回拨处理的一些考虑和实现方式:

      • 时钟同步: 在分布式系统中,确保各个机器的系统时钟保持同步非常重要。一种常见的做法是使用网络时间协议(NTP)或类似的时间同步服务,使所有机器的时钟与网络时间服务器保持一致。这可以通过配置操作系统来实现。

      • 时钟回拨处理: 时钟回拨是指系统时钟突然向后调整,可能导致已经生成的ID比新生成的ID时间戳更早。为了处理时钟回拨,可以采用以下策略之一:

      • 等待策略: 如果检测到时钟回拨,可以等待一段时间,直到时钟回拨结束,然后再继续生成ID。这样可以确保生成的ID仍然是递增的。

      • 拒绝策略: 另一种策略是拒绝生成ID,直到时钟回拨结束。这样可以避免生成不正确的ID。

      • 时钟漂移修复策略: 在一些情况下,可以通过检测时钟回拨并调整已生成的ID来修复时钟漂移。这需要更复杂的逻辑和持久化存储。

    • 具体的实现方式取决于应用的需求和系统环境。时钟同步和时钟回拨处理是确保雪花算法正常运行的重要考虑因素,需要根据实际情况来配置和实施。一般来说,建议使用可靠的时钟同步服务来减小时钟回拨的可能性,并根据应用的要求选择合适的时钟回拨处理策略。

  • 时间回拨是指系统时钟在某个时刻向后调整,导致系统时间突然变小,相当于时间"倒流"了一段时间。这种情况可能发生在计算机系统中,通常是由于以下原因之一引起的:

    • 时钟同步服务: 许多操作系统和计算机网络使用时钟同步服务(如NTP,Network Time Protocol)来保持系统时钟与外部时间源同步。如果时钟同步服务检测到系统时钟与外部时间源之间的时间差距太大,它可能会尝试通过调整系统时钟来将其与外部时间源同步。这种情况下,系统时钟会向后调整,以使其与外部时间源保持一致。

    • 手动时钟调整: 系统管理员或用户可能会手动调整系统时钟,导致时间回拨。这通常发生在需要纠正时钟错误或同步系统时钟的情况下。

    • 时间回拨可能会对系统和应用程序造成问题,特别是对于依赖时间顺序的应用程序,例如日志记录、数据同步和分布式系统中的唯一ID生成(如雪花算法)。在时间回拨发生时,应用程序可能会出现以下问题:

    • 事件顺序混乱:如果应用程序依赖于时间顺序来处理事件,时间回拨可能导致事件的顺序混乱。

    • 数据一致性问题:在分布式系统中,时间回拨可能导致数据不一致或冲突。

    • 唯一ID冲突:某些ID生成算法,如雪花算法,可能会在时间回拨时生成相同的ID,导致ID冲突。

  • 为了处理时间回拨,应用程序通常需要实施一些策略,例如等待、拒绝或纠正事件,以确保系统的稳定性和一致性。时钟同步服务的配置和监控也是减少时间回拨影响的重要措施。
    在这里插入图片描述

总的来说,雪花算法的实现原理是将时间戳、数据中心ID、工作机器ID和序列号等信息合并在一起,确保生成的ID在分布式系统中具有唯一性和有序性。通过适当的配置和时钟同步,它可以在分布式环境中生成高性能的唯一ID。

2、雪花算法实现使用当前时间

以下是一个基于 C++ 的雪花算法使用秒级当前时间示例,用于生成唯一ID:

  • 时间戳左移22位,左边添加22个零,10位机器位左移12位,左边添加12个零,最后的序号位无需左移。
    在这里插入图片描述
#include <iostream>
#include <cstdint>
#include <ctime>class Snowflake {
public:Snowflake(uint16_t datacenterId, uint16_t workerId): datacenterId_(datacenterId), workerId_(workerId), sequence_(0), lastTimestamp_(0) {if (datacenterId_ > maxDatacenterId_ || workerId_ > maxWorkerId_) {throw std::invalid_argument("Invalid datacenter or worker ID");}}uint64_t generateUniqueId() {uint64_t timestamp = currentTimestamp();if (timestamp < lastTimestamp_) {throw std::runtime_error("Clock moved backwards");}//时间戳原理:获取当前时间戳如果等于上次时间戳(同一毫秒内),咋序列号加一。否则序列号设置为0,从0开始if (timestamp == lastTimestamp_) {sequence_ = (sequence_ + 1) & sequenceMask_;if (sequence_ == 0) {timestamp = waitNextMillis(lastTimestamp_);}} else {sequence_ = 0;}lastTimestamp_ = timestamp;return ((timestamp - twepoch_) << timestampLeftShift_) |((datacenterId_ & maxDatacenterId_) << datacenterIdShift_) |((workerId_ & maxWorkerId_) << workerIdShift_) |(sequence_ & sequenceMask_);}private:uint64_t currentTimestamp() const {return std::time(nullptr) * 1000;}uint64_t waitNextMillis(uint64_t lastTimestamp) {uint64_t timestamp = currentTimestamp();while (timestamp <= lastTimestamp) {timestamp = currentTimestamp();}return timestamp;}//const uint64_t twepoch_ = 1609459200000ULL;  // 2021-01-01 00:00:00 UTCconst uint64_t unixEpoch_ = 0ULL;  // Unix时间戳起点:1970-01-01 00:00:00 UTCconst uint64_t workerIdBits_ = 5;const uint64_t datacenterIdBits_ = 5;const uint64_t maxWorkerId_ = (1ULL << workerIdBits_) - 1;const uint64_t maxDatacenterId_ = (1ULL << datacenterIdBits_) - 1;const uint64_t sequenceBits_ = 12;const uint64_t workerIdShift_ = sequenceBits_;const uint64_t datacenterIdShift_ = sequenceBits_ + workerIdBits_;const uint64_t timestampLeftShift_ = sequenceBits_ + workerIdBits_ + datacenterIdBits_;const uint64_t sequenceMask_ = (1ULL << sequenceBits_) - 1;uint16_t datacenterId_;uint16_t workerId_;uint64_t sequence_;uint64_t lastTimestamp_;
};int main() {// 在这里设置你的数据中心ID和工作机器IDuint16_t datacenterId = 1;uint16_t workerId = 1;Snowflake snowflake(datacenterId, workerId);for (int i = 0; i < 10; ++i) {uint64_t uniqueId = snowflake.generateUniqueId();std::cout << "Generated unique ID: " << uniqueId << std::endl;}return 0;
}

在这个示例中,我们创建了一个 Snowflake 类来实现雪花算法。它能够生成唯一的ID,其中包括时间戳、数据中心ID、工作机器ID和序列号。在 main 函数中,我们设置了数据中心ID和工作机器ID,并使用 generateUniqueId 方法生成10个唯一ID,然后将它们打印到控制台。

请注意,这个示例的时间戳部分使用了当前时间,但在实际应用中,你可能需要更精确的时间戳机制,以确保在同一毫秒内生成的ID也具有唯一性。此外,确保在分布式环境中正确设置数据中心ID和工作机器ID,以避免ID冲突。这个示例是一个简单的演示,用于理解雪花算法的工作原理。
在这里插入图片描述
雪花算法核心实现:

return ((timestamp - twepoch_) << timestampLeftShift_) |((datacenterId_ & maxDatacenterId_) << datacenterIdShift_) |((workerId_ & maxWorkerId_) << workerIdShift_) |(sequence_ & sequenceMask_)
  • 这行代码是雪花算法中用于生成唯一ID的核心部分,它将各个组成部分组合在一起,形成一个64位的整数,作为最终生成的唯一ID。让我解释这行代码的各个部分的含义:

    • ((timestamp - twepoch_) << timestampLeftShift_):这部分计算时间戳的值。首先,它从当前时间戳中减去雪花纪元(twepoch_),以获取自雪花纪元以来的毫秒数。然后,将这个毫秒数左移 timestampLeftShift_ 位,将时间戳占据ID的相应位数。这个部分的目的是确保生成的ID中包含时间戳信息,以保持ID的有序性。

    • ((datacenterId_ & maxDatacenterId_) << datacenterIdShift_):这部分计算数据中心ID的值。首先,它使用位与运算符 & 将数据中心ID与最大数据中心ID进行按位与操作,以确保数据中心ID的值不超过其所占据的位数。然后,将结果左移 datacenterIdShift_ 位,将数据中心ID占据ID的相应位数。这个部分的目的是确保生成的ID中包含数据中心ID信息,以确保不同数据中心的机器生成的ID是唯一的。

    • ((workerId_ & maxWorkerId_) << workerIdShift_):这部分计算工作机器ID的值,原理与数据中心ID类似。首先,使用位与运算符 & 将工作机器ID与最大工作机器ID进行按位与操作,以确保工作机器ID的值不超过其所占据的位数。然后,将结果左移 workerIdShift_ 位,将工作机器ID占据ID的相应位数。这个部分的目的是确保生成的ID中包含工作机器ID信息,以确保同一数据中心内不同机器生成的ID是唯一的。

    • (sequence_ & sequenceMask_):这部分计算序列号的值。它使用位与运算符 & 将当前序列号与序列号掩码 sequenceMask_ 进行按位与操作,以确保序列号的值不超过其所占据的位数。序列号占据ID的相应位数,以确保在同一毫秒内生成多个ID时,它们的序列号不会冲突。

  • 最终,这些部分的值通过按位或运算符 | 进行组合,形成了一个64位的整数,作为生成的唯一ID。这个ID包含了时间戳、数据中心ID、工作机器ID和序列号等信息,确保了生成的ID在分布式系统中是唯一且有序的。这种组合方式使得每个部分的信息都能够被提取和分析,同时也保持了整体ID的唯一性和有序性。

3、雪花算法实现使用毫秒时间

当多个请求在同一毫秒内生成唯一ID时,雪花算法通过使用序列号部分来确保ID的唯一性。以下是一个示例,演示了如何处理同一毫秒内生成多个唯一ID的情况:

  • 时间戳左移22位,左边添加22个零,10位机器位左移12位,左边添加12个零,最后的序号位无需左移。
    在这里插入图片描述
#include <iostream>
#include <cstdint>
#include <ctime>
#include <mutex>class Snowflake {
public:Snowflake(uint16_t datacenterId, uint16_t workerId): datacenterId_(datacenterId), workerId_(workerId), sequence_(0), lastTimestamp_(0) {if (datacenterId_ > maxDatacenterId_ || workerId_ > maxWorkerId_) {throw std::invalid_argument("Invalid datacenter or worker ID");}}uint64_t generateUniqueId() {std::unique_lock<std::mutex> lock(mutex_);uint64_t timestamp = currentTimestamp();if (timestamp < lastTimestamp_) {throw std::runtime_error("Clock moved backwards");}//时间戳原理:获取当前时间戳如果等于上次时间戳(同一毫秒内),咋序列号加一。否则序列号设置为0,从0开始if (timestamp == lastTimestamp_) {sequence_ = (sequence_ + 1) & sequenceMask_;if (sequence_ == 0) {timestamp = waitNextMillis(lastTimestamp_);}} else {sequence_ = 0;}lastTimestamp_ = timestamp;return ((timestamp - twepoch_) << timestampLeftShift_) |((datacenterId_ & maxDatacenterId_) << datacenterIdShift_) |((workerId_ & maxWorkerId_) << workerIdShift_) |(sequence_ & sequenceMask_);}private:uint64_t currentTimestamp() const {return std::time(nullptr) * 1000;}uint64_t waitNextMillis(uint64_t lastTimestamp) {uint64_t timestamp = currentTimestamp();while (timestamp <= lastTimestamp) {timestamp = currentTimestamp();}return timestamp;}//const uint64_t twepoch_ = 1609459200000ULL;  // 2021-01-01 00:00:00 UTCconst uint64_t unixEpoch_ = 0ULL;  // Unix时间戳起点:1970-01-01 00:00:00 UTCconst uint64_t workerIdBits_ = 5;const uint64_t datacenterIdBits_ = 5;const uint64_t maxWorkerId_ = (1ULL << workerIdBits_) - 1;const uint64_t maxDatacenterId_ = (1ULL << datacenterIdBits_) - 1;const uint64_t sequenceBits_ = 12;const uint64_t workerIdShift_ = sequenceBits_;const uint64_t datacenterIdShift_ = sequenceBits_ + workerIdBits_;const uint64_t timestampLeftShift_ = sequenceBits_ + workerIdBits_ + datacenterIdBits_;const uint64_t sequenceMask_ = (1ULL << sequenceBits_) - 1;uint16_t datacenterId_;uint16_t workerId_;uint64_t sequence_;uint64_t lastTimestamp_;std::mutex mutex_;
};int main() {// 在这里设置你的数据中心ID和工作机器IDuint16_t datacenterId = 1;uint16_t workerId = 1;Snowflake snowflake(datacenterId, workerId);for (int i = 0; i < 10; ++i) {uint64_t uniqueId = snowflake.generateUniqueId();std::cout << "Generated unique ID: " << uniqueId << std::endl;}return 0;
}

在这里插入图片描述

在这个示例中,我们添加了一个互斥锁 (std::mutex) 来确保在同一毫秒内生成多个唯一ID时,只有一个线程能够访问 generateUniqueId 方法。这样可以避免并发生成ID时的冲突。

雪花算法核心实现:

return ((timestamp - twepoch_) << timestampLeftShift_) |((datacenterId_ & maxDatacenterId_) << datacenterIdShift_) |((workerId_ & maxWorkerId_) << workerIdShift_) |(sequence_ & sequenceMask_)
  • 这行代码是雪花算法中用于生成唯一ID的核心部分,它将各个组成部分组合在一起,形成一个64位的整数,作为最终生成的唯一ID。让我解释这行代码的各个部分的含义:

    • ((timestamp - twepoch_) << timestampLeftShift_):这部分计算时间戳的值。首先,它从当前时间戳中减去雪花纪元(twepoch_),以获取自雪花纪元以来的毫秒数。然后,将这个毫秒数左移 timestampLeftShift_ 位,将时间戳占据ID的相应位数。这个部分的目的是确保生成的ID中包含时间戳信息,以保持ID的有序性。

    • ((datacenterId_ & maxDatacenterId_) << datacenterIdShift_):这部分计算数据中心ID的值。首先,它使用位与运算符 & 将数据中心ID与最大数据中心ID进行按位与操作,以确保数据中心ID的值不超过其所占据的位数。然后,将结果左移 datacenterIdShift_ 位,将数据中心ID占据ID的相应位数。这个部分的目的是确保生成的ID中包含数据中心ID信息,以确保不同数据中心的机器生成的ID是唯一的。

    • ((workerId_ & maxWorkerId_) << workerIdShift_):这部分计算工作机器ID的值,原理与数据中心ID类似。首先,使用位与运算符 & 将工作机器ID与最大工作机器ID进行按位与操作,以确保工作机器ID的值不超过其所占据的位数。然后,将结果左移 workerIdShift_ 位,将工作机器ID占据ID的相应位数。这个部分的目的是确保生成的ID中包含工作机器ID信息,以确保同一数据中心内不同机器生成的ID是唯一的。

    • (sequence_ & sequenceMask_):这部分计算序列号的值。它使用位与运算符 & 将当前序列号与序列号掩码 sequenceMask_ 进行按位与操作,以确保序列号的值不超过其所占据的位数。序列号占据ID的相应位数,以确保在同一毫秒内生成多个ID时,它们的序列号不会冲突。

  • 最终,这些部分的值通过按位或运算符 | 进行组合,形成了一个64位的整数,作为生成的唯一ID。这个ID包含了时间戳、数据中心ID、工作机器ID和序列号等信息,确保了生成的ID在分布式系统中是唯一且有序的。这种组合方式使得每个部分的信息都能够被提取和分析,同时也保持了整体ID的唯一性和有序性。

4、雪花算法实现原理

SnowFlake 中文意思为雪花,故称为雪花算法。最早是 Twitter 公司在其内部用于分布式环境下生成唯一 ID。在2014年开源 scala 语言版本。世界上没有两片相同的雪花噢。 因此命名雪花算法来标识不同的uuid。
在这里插入图片描述
雪花算法的原理就是生成一个的 64 位比特位的 long 类型的唯一 id。

  • 最高 1 位固定值 0,因为生成的 id 是正整数,如果是 1 就是负数了。
  • 接下来 41 位存储毫秒级时间戳,2^41/(1000606024365)=69,大概可以使用 69 年。
  • 再接下 10 位存储机器码,包括 5 位 datacenterId 和 5 位 workerId。最多可以部署 2^10=1024 台机器。
  • 最后 12 位存储序列号。同一毫秒时间戳时,通过这个递增的序列号来区分。即对于同一台机器而言,同一毫秒时间戳下,可以生成 2^12=4096 个不重复 id。

可以将雪花算法作为一个单独的服务进行部署,然后需要全局唯一 id 的系统,请求雪花算法服务获取 id 即可。

对于每一个雪花算法服务,需要先指定 10 位的机器码,这个根据自身业务进行设定即可。例如机房号+机器号,机器号+服务号,或者是其他可区别标识的 10 位比特位的整数值都行。

5、雪花算法优缺点

  • 雪花算法有以下几个优点:

    • 高并发分布式环境下生成不重复 id,每秒可生成百万个不重复 id。
    • 基于时间戳,以及同一时间戳下序列号自增,基本保证 id 有序递增。
    • 不依赖第三方库或者中间件。
    • 算法简单,在内存中进行,效率高。
  • 雪花算法有如下缺点:

    • 依赖服务器时间,服务器时钟回拨时可能会生成重复 id。算法中可通过记录最后一个生成 id 时的时间戳来解决,每次生成 id 之前比较当前服务器时钟是否被回拨,避免生成重复 id。

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Prometheus-Rules 实战

文章目录 1 node rules2 nginx rule2.1 Nginx 4xx 错误率太多2.2 Nginx 5xx 错误率太多2.3 Nginx 延迟高 3 mysql rule3.1 MySQL 宕机3.2 实例连接数过多3.3 MySQL高线程运行3.4 MySQL 从服务器 IO 线程没有运行3.5 MySQL 从服务器 SQL 线程没有运行3.6 MySQL复制滞后3.7 慢查询…

作为SiteGPT替代品,HelpLook的优势是什么?

在当今快节奏的数字化世界中&#xff0c;企业不断寻求创新方式来简化运营并增强客户体验。由于聊天机器人能够自动化任务、提供快速响应并提供个性化互动&#xff0c;它们在业务运营中的使用变得非常重要。因此&#xff0c;企业越来越意识到像SiteGPT和HelpLook这样高效的聊天机…

I/O

IO 流简介 IO 即 Input/Output&#xff0c;输入和输出。数据输入到计算机内存的过程即输入&#xff0c;反之输出到外部存储&#xff08;比如数据库&#xff0c;文件&#xff0c;远程主机&#xff09;的过程即输出。IO 流在 Java 中分为输入流和输出流&#xff0c;而根据数据的…

Spring事务不生效的场景的解决方案

一、前言 在Java Web开发中&#xff0c;使用Spring框架可以大大简化开发人员的工作。其中&#xff0c;事务管理是Spring框架中的一个重要功能&#xff0c;它可以确保多个数据库操作要么全部成功&#xff0c;要么全部失败。但是&#xff0c;在实际开发中&#xff0c;我们可能会…

基于微信小程序的明星应援小程序设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言系统主要功能&#xff1a;具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计…

浅谈研发与制造运营双端之间的数字化探索

一、传统中小型制造企业的发展变革与信息化建设背景 以往&#xff0c;传统的中小型制造企业常以大批量、重复性生产制造为主&#xff0c;依赖于人力设备&#xff0c;通过扩大产能发展壮大&#xff0c;信息化能力弱。伴随市场环境的变化及厂商竞争压力&#xff0c;企业谋生存求…

【网络八股】TCP八股

网络八股 请简述TCP/IP模型中每层的作用&#xff0c;典型协议和典型设备介绍一下三次握手的过程介绍一下四次挥手的过程必须三次握手吗&#xff0c;两次不行吗&#xff1f;为什么ACK数据包消耗TCP的序号吗三次握手中可以携带应用层数据吗四次挥手时&#xff0c;可以携带应用层数…

UE蓝图学习(从Unity3D而来)

一、UE组件对比Unity3D&#xff0c;从Unity3D过渡来学的角度出发&#xff0c;可以理解为在 空物体下放置子物体。UE没有U3D那种可以将组件挂在自身空物体上面。 二、UE 蓝图的情境提示&#xff0c;必须先找到相应的类型&#xff0c;对象对象、事件事件&#xff0c;才能找到相应…

Vue iconfont-阿里巴巴矢量图标库用法

一、vue使用 选择心仪的图标 加入购物车 点击右上角购物车&#xff0c;点击添加至项目 在资源管理 可以看到我的项目 进入项目设置勾选彩色 点击下载到本地 解压压缩包 在main.js文件内导入css文件 import "/assets/font_icon/iconfont.css"; 使用&#xff1a; 复…

Hive 数据仓库介绍

目录 ​编辑 一、Hive 概述 1.1 Hive产生的原因 1.2 Hive是什么&#xff1f; 1.3 Hive 特点 1.4 Hive生态链关系 二、Hive架构 2.1 架构图 2.2 架构组件说明 2.2.1 Interface 2.2.1.1 CLI 2.2.1.2 JDBC/ODBC 2.2.1.3 WebUI 2.2.2 MetaData 2.2.3 MetaStore 2.2…

postman怎么进行参数化?

一、先准备好参数化数据 &#xff08;参数化数据可以使用Excel或者txt的文件。 注意如果使用的是txt的文件&#xff0c;一定要使用英文的逗号&#xff0c;不然的话会报错&#xff01;&#xff09; 注意&#xff1a;填写好的数据后&#xff0c;保存的时候需要另存为&#xff0c…

PayPal面经

文章目录 初战AI Infra团队广泛收集信息&#xff0c;增加对面试相关团队的了解Paypal的AI infra Engineer 极客时间演讲视频&#xff1a;AI在金融应用HR面试首面 zhang chao首先让我介绍自己和项目基础知识出题 lettcode 1and0s 二面 luwen没有让我重复介绍自己那好&#xff0c…

如何快速重置模型原点

1、什么是模型原点&#xff1f; 模型原点是三维建模中的概念&#xff0c;它是指在一个虚拟三维空间中确定的参考点。模型原点通常位于模型的几何中心或基本组件的中心位置。如图所示&#xff1a; 可以看到模型的原点在模型的几何中心 2、模型原点的作用 知道了什么是模型原点&…

LCR 101. 分割等和子集——力扣——背包问题、动态规矩

问题描述 代码展示 class Solution:def canPartition(self, nums: List[int]) -> bool:if len(nums) < 1:return Falsetotal_sum sum(nums)if total_sum % 2 ! 0: # 总和为奇数&#xff0c;无法分成两个相等的子集return Falsetarget_sum total_sum // 2dp [[False]…

myArm 全新七轴桌面型机械臂

引言 在不断演进的科技世界中&#xff0c;我们始终追求创新和卓越&#xff0c;以满足客户的需求并超越他们的期望。今天&#xff0c;我们很高兴地宣布我们的最新产品——myArm 300 Pi&#xff0c;一款七轴的桌面型机械臂。这款产品的独特之处在于其灵活性和可编程性&#xff0c…

Docker——容器生命周期管理(下篇)

Docker 一、run1、options说明2、-p的三种写法3、实例14、实例25、实例36、实例47、实例58、实例69、实例78、实例89、退出容器 二、start/stop/restart1、语法格式2、stop/restart 命令的 options 三、kill1、重点2、说明3、实例 四、rm1、说明2、实例 五、create实例 六、exe…

天眼查询企业信息API接口

"天眼"一般是指"天眼查"&#xff0c;这是一个提供全国企业信息查询的API接口。天眼查以"天眼"作为用户logo&#xff0c;基于人工智能算法的数据采集和分析技术&#xff0c;为企业和个人提供全量、精准、实时、权威的企业信息查询服务。 天眼查A…

美容店预约小程序搭建流程

随着科技的不断发展&#xff0c;小程序已经成为了人们生活中不可或缺的一部分。对于美容店来说&#xff0c;搭建一个预约小程序不仅可以提高工作效率&#xff0c;还可以增加客户数量、提高服务质量。那么&#xff0c;如何搭建一个美容店预约小程序呢&#xff1f;本文将为你详细…

Dockerfile 语法详解:构建定制化容器镜像的基石

Docker 已经成为现代应用程序开发和部署的关键工具之一。在 Docker 的世界中&#xff0c;Dockerfile 是一个至关重要的文件&#xff0c;它定义了如何构建容器镜像的步骤和配置。本文将深入探讨 Dockerfile 的语法&#xff0c;为您提供构建定制化容器镜像的基础知识。 Dockerfil…

React 全栈体系(十六)

第八章 React 扩展 五、Context 1. 代码 /* index.jsx */ import React, { Component } from react import ./index.css//创建Context对象 const MyContext React.createContext() const {Provider,Consumer} MyContext export default class A extends Component {state …