NOR FLASH介绍

参考

http://t.csdnimg.cn/gHcrG

一、NOR FLASH简介

XIP技术:https://blog.csdn.net/ffdia/article/details/87437872?fromshare=blogdetail
在这里插入图片描述

在这里插入图片描述

NOR Flash 和 NAND Flash 的特点和应用举例:
NOR Flash:
特点:
支持随机访问,可以直接像读取内存一样通过独立的地址线和数据线进行字节级读取,不需要额外的解码电路。
提供快速的读取速度,通常比NAND Flash快,特别适合于执行代码(XIP,eXecute-In-Place)的场合。
擦除和写入是以区块(sector)为单位,但也可以支持单个字节的编程。
通常没有坏块管理问题,出厂时质量较为均匀。
容量相对较小,成本相对较高。

应用举例:
存储程序代码,例如微控制器的Bootloader、嵌入式系统的固件、计算机BIOS等。
快速读取要求较高的小型存储应用,如无线通信模块、工业控制设备中的程序存储。

NAND Flash:
特点:

不支持随机访问,读取操作需要通过I/O口间接进行,地址和数据共用总线。
读取速度略低于NOR Flash,但写入和擦除速度较快,尤其是以页(page)为单位的大批量操作。
通常以较大的块(block)为擦除单位,且存在坏块管理问题,需要专门的管理机制。
成本较低,容量较大,体积紧凑,适合大规模数据存储。

应用举例:
大容量存储设备,如嵌入式系统的文件系统、消费类电子产品中的数据存储、SSD(固态硬盘)。
移动设备的内置存储,如智能手机和平板电脑的eMMC(Embedded MultiMedia Card)。
U盘、存储卡等便携式存储设备。

二、NM25Q128简介

在这里插入图片描述
在这里插入图片描述
NM25Q128是一款128Mb(16MB)容量的NOR型串行闪存芯片,专为需要高速、可靠数据存储的应用而设计。该器件通过SPI(Serial Peripheral Interface)接口与主控设备通信,提供了一种节省引脚、易于集成到系统中的存储方案。

特点概述:
容量:128Mb,即16,777,216比特(约2MB)。
擦写次数:具有很高的耐用性,可承受至少10万次的擦写周期。
数据保存期长:数据可保存长达20年以上,体现了NOR Flash优异的数据保留性能。
SPI接口:支持SPI模式0(CPOL=0, CPHA=0)和模式3(CPOL=1, CPHA=1),适用于多种工作环境和系统设计需求。
数据格式:采用8位数据宽度传输,遵循先发高位(MSB)再发低位(LSB)的传输规则。
传输速度:标准模式下支持高达104M bit/s的数据传输速率,具有高效的读写性能。

接口信号说明:
CS(Chip Select):片选信号输入,用于选择NM25Q128作为SPI总线上的活动设备。
HOLD:暂停通讯信号,当该信号为低电平时,暂时停止SPI通信。
SO(Serial Output):数据输出引脚,从NM25Q128向主控设备传送数据。
CLK(Clock):时钟输入引脚,为主设备与NM25Q128之间的数据传输提供同步时钟信号。
WP(Write Protect):写保护功能引脚,用于禁止或允许对闪存进行写入操作。
SI(Serial Input):数据输入引脚,用于将数据从主设备写入NM25Q128。

总的来说,NM25Q128因其高密度、高速度、易用性和耐用性等特点,被广泛应用于嵌入式系统、固件存储、微控制器的代码存储、数据记录等多种场合。

三、NM25Q128存储结构

在这里插入图片描述
在这里插入图片描述

NM25Q128的存储结构按照地址范围、页、扇区和块进行组织,其具体划分如下:

**地址范围:**NM25Q128的地址范围是从0x00000000到0x00FFFFFF,共计16,777,216个地址,对应128Mbit(16,777,216比特)或16MByte(16,777,216字节)的存储容量。

存储单元划分:
Page:NM25Q128的一个页面(Page)大小为256字节(1byte * 256)。
Sector:一个扇区(Sector)由16个连续的页面组成,因此一个扇区的大小为16 * 256字节 = 4096字节。
Block:一个块(Block)由16个连续的扇区组成,所以一个块的大小为16 * 4096字节 = 65,536字节(即64KB)。

**整体结构:**整个NM25Q128由256个这样的块组成,因此其总容量为256 * 65,536字节 = 16,777,216字节(即16MByte)。

这种分层结构使得NM25Q128在进行数据管理和维护时具有良好的灵活性,最小擦除单位为一个扇区,数据读写则以字节为单位。在进行擦除操作时,必须以扇区为单位进行,这样有助于提升使用寿命并简化固件升级等操作。

四、NM25Q128常用指令

在这里插入图片描述
在这里插入图片描述
NM25Q128或者其他NOR Flash常用的指令还包括但不限于以下几种:
指令(十六进制):0x06
名称:写使能(Write Enable)
作用:在对NOR Flash进行任何写入操作(包括页写和擦除)之前,必须先发送这条指令,使得NOR Flash进入写入允许状态。

指令(十六进制):0x05
名称:读状态寄存器1(Read Status Register 1)
作用:用于读取NOR Flash的状态寄存器1,确认NOR Flash是否处于空闲状态,是否准备好进行下一步操作,特别是擦除操作之前需要确认设备是否已完成上一次操作。

指令(十六进制):0x03
名称:读数据(Read Data)
作用:用于从NOR Flash中读取数据,通过指定地址读取连续的数据流。

指令(十六进制):0x02
名称:页编程(Page Program)
作用:用于向NOR Flash的指定地址开始的连续256字节区域写入数据。注意,写入数据必须按照页的边界进行,不能跨越页的边界。

指令(十六进制):0x20
名称:扇区擦除(Sector Erase)
作用:对NOR Flash中最小擦除单位(扇区)进行擦除操作,通常NM25Q128的一个扇区大小为4096字节(4KB)。

除此之外,还有其他的指令,例如:

指令(十六进制):0xD8
名称:块擦除(Bulk Erase)
作用:擦除整个芯片的所有数据,对于NM25Q128来说,一次性擦除所有256个块。

指令(十六进制):0xB0~0xBF
名称:读取标识符(Read Manufacturer and Device ID)
作用:读取制造商ID和设备ID,用于验证和识别具体的NOR Flash型号。

指令(十六进制):0x04
名称:写禁止(Write Disable)
作用:结束写入操作序列,防止意外的写入动作发生,使NOR Flash退出写入允许状态。

五、NM25Q128 读/擦除/写 步骤

在这里插入图片描述

NM25Q128的读、擦除、写操作时序如下:
1.写使能(Write Enable)
发送指令:0x06H
作用:在执行写操作(如页写或擦除)之前,必须先发送该指令,使NOR Flash进入可写状态。

2.读状态寄存器1(Read Status Register 1)
发送指令:0x05H
作用:读取NOR Flash的状态寄存器1,检查设备是否处于就绪状态,以便进行下一步操作。

3.读数据时序(Read Data Bytes)
发送指令:0x03H
时序步骤:
发送读指令(0x03H);
发送要读取数据的起始地址;
从数据线(SO)接收数据;
循环上述步骤直到读取所需的所有数据。

4.页写时序(Page Program)
发送指令:0x02H
时序步骤:
发送写使能指令(0x06H);
发送页写指令(0x02H);
发送要写入数据的目标地址;
将最多256字节的数据通过数据线(SI)发送到NOR Flash;
等待写操作完成,可通过读状态寄存器来确认。

5.扇区擦除时序(Sector Erase)
发送指令:0x20H
时序步骤:
发送写使能指令(0x06H);
发送扇区擦除指令(0x20H);
发送要擦除扇区的起始地址(地址应对齐到扇区边界);
等待擦除操作完成,可通过读状态寄存器来确认。

在实际操作过程中,还需注意地址和数据的传输格式以及相关的时钟同步,确保严格按照器件数据手册的要求进行操作。此外,某些操作完成后,建议发送写禁止指令(0x04H)以防止意外的写操作。

在这里插入图片描述
在执行诸如Page Program(页写)、Sector Erase(扇区擦除)、Block Erase(块擦除)和Chip Erase(整片擦除)以及Write Status Register(写状态寄存器)等操作之前,必须先向NOR Flash发送Write Enable(写使能)指令(0x06H)。这个指令的作用是让NOR Flash进入可写状态,只有在写使能之后,才能进行后续的写入或擦除操作。

当写使能指令发出后,NOR Flash内部的相关控制位会被设置,允许接下来的写入或擦除指令被执行。完成相应的写入或擦除操作后,通常需要发送Write Disable(写禁止)指令以取消写使能状态,防止在不需要写入的时候误操作导致数据损坏。写禁止指令通常为0x04H。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
NM25Q128的读操作步骤可以细化如下:

1.发送读命令
向SPI总线的MOSI(数据输入)线上发送0x03H(读数据指令)。

2.发送地址
NM25Q128地址范围是0x000000到0xFFFFFF,总共24位。
地址需要按照小端模式(Least Significant Bit First,LSB)分三次发送,每次8位。例如,要读取地址0x123456,则应按以下顺序发送地址字节:
第一次发送最低8位(0x56)。
第二次发送中间8位(0x34)。
第三次发送最高8位(0x12)。

3.读取数据
在地址发送完毕后,发送一个无效数据字节(通常是0xFF)到SPI总线的MOSI线上,此时NM25Q128开始在MISO(数据输出)线上输出请求地址处的数据。
接收从NM25Q128返回的第一个数据字节,并且只要保持SPI时钟(SCK)的持续脉冲,就可以连续读取数据,直至所需数据全部读取完毕。

总之,NM25Q128的读操作流程是先发送读指令,接着发送目标地址,然后通过发送无效数据字节触发并连续读取存储器中的数据。在整个读取过程中,务必确保时钟信号的正确同步,以保证数据的准确传输。
在这里插入图片描述
NM25Q128擦除扇区的具体步骤如下:

1.发送写使能命令
向SPI总线的MOSI(数据输入)线上发送0x06H(写使能命令),使NOR Flash进入可写状态。

2.等待空闲
读取并检查状态寄存器(通常通过发送0x05H指令读取),确保NOR Flash已经完成之前的任何操作,并且处于空闲状态。只有在空闲状态下,才能进行下一步的擦除操作。

3.发送擦除扇区命令
向SPI总线的MOSI线上发送0x20H(扇区擦除命令),通知NOR Flash即将进行扇区擦除操作。

4.发送地址
根据要擦除的扇区地址,将24位地址按照小端模式(LSB优先)分三次发送到SPI总线的MOSI线上。地址应对齐到扇区边界,即扇区的起始地址。

5.等待空闲
在发送完擦除命令和地址后,需要再次等待NOR Flash完成擦除操作并回到空闲状态。通常通过轮询读取状态寄存器来判断是否完成,状态寄存器中的相应位变为适当状态时,表示擦除操作完成。

需要注意的是,整个擦除操作期间需要确保时钟信号SCK的正确同步,并且在擦除操作结束后,最好发送写禁止命令(0x04H)以避免意外的写操作。此外,在实际应用中,请参照NM25Q128的具体数据手册,遵循正确的时序和操作规范。
在这里插入图片描述
NM25Q128写操作步骤(此处假设目标区域已经经过擦除):

1.擦除扇区(20H)
在写入数据前,需要确保目标地址所在的扇区已经被擦除。如果目标地址的数据尚未擦除,可参照之前提供的擦除扇区步骤进行操作。

2.发送写使能命令
向SPI总线的MOSI(数据输入)线上发送0x06H(写使能命令),使NOR Flash进入可写状态。

3.发送页写命令
向SPI总线的MOSI线上发送0x02H(页写命令),通知NOR Flash即将进行页写操作。

4.发送地址
根据要写入数据的目标地址,将24位地址按照小端模式(LSB优先)分三次发送到SPI总线的MOSI线上。

5.发送数据
在发送完地址后,立即通过SPI总线的MOSI线将最多256字节的数据写入到NOR Flash中。注意数据应按照字节顺序逐个发送,且必须连续写入整个一页。

6.等待空闲
在发送完所有数据后,需要等待NOR Flash完成写入操作并返回到空闲状态。可以通过轮询读取状态寄存器来判断写入是否完成,当状态寄存器中的相应位变为适当状态时,表示写入操作完成。

在实际应用中,一定要确保写入数据前目标区域已被擦除,并且在写入操作结束后,推荐发送写禁止命令(0x04H)以避免不必要的写操作。同时,严格遵守NM25Q128的数据手册中规定的时序要求。

六、NOR FLASH基本驱动步骤

在这里插入图片描述
在这里插入图片描述
NOR FLASH基于SPI接口的基本驱动步骤可以概括为以下几点:

1.SPI工作参数配置初始化
使用HAL_SPI_Init()函数对SPI外设进行初始化,设置工作模式(CPOL和CPHA)、时钟速度、数据帧格式(8位、16位等)、NSS管理方式等参数。

2.使能SPI时钟和初始化相关引脚
首先,通过__HAL_RCC_SPIx_CLK_ENABLE()函数启用SPI外设的时钟。
其次,对于STM32等微控制器,需要配置SPI接口相关的GPIO引脚为复用推挽输出模式或其他合适的模式,这部分操作通常不在HAL_SPI_MspInit()函数内完成,而是在初始化SPI之前手动配置GPIO的AF(Alternate Function)寄存器。

// 示例代码(伪代码)
GPIO_InitStruct.Pin = GPIO_PIN_...; // 设置SPI对应引脚
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; // 设置为复用推挽输出模式
GPIO_InitStruct.Pull = GPIO_NOPULL; // 如果不需要上下拉电阻,设置为无上拉下拉
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; // 设置GPIO速度
GPIO_InitStruct.Alternate = GPIO_AF_SPIx; // 设置对应SPI外设的复用功能
HAL_GPIO_Init(GPIOx, &GPIO_InitStruct); // 初始化GPIO引脚

3.使能SPI
使用__HAL_SPI_ENABLE(&hspi)函数使能SPI外设,这里的hspi是指向SPI_HandleTypeDef结构体的指针。

4.SPI传输数据
发送数据:使用HAL_SPI_Transmit(&hspi, tx_buffer, size, timeout)函数发送数据,tx_buffer是发送缓冲区,size是发送数据的长度,timeout是超时时间。
接收数据:使用HAL_SPI_Receive(&hspi, rx_buffer, size, timeout)函数接收数据,rx_buffer是接收缓冲区。
同时发送和接收:使用HAL_SPI_TransmitReceive(&hspi, tx_buffer, rx_buffer, size, timeout)函数执行全双工传输。

5.设置SPI传输速度
根据系统要求,操作SPI_CR1寄存器(或相关的时钟配置寄存器)中的波特率控制位来设置SPI通信的时钟频率。在HAL库中,通常在HAL_SPI_Init()函数里通过配置SPI_InitTypeDef结构体中的BaudRatePrescaler字段来间接设置SPI时钟速度。

在这里插入图片描述
NM25Q128 NOR Flash的驱动步骤可以归纳为以下详细步骤:
1.初始化片选引脚与SPI接口

配置NM25Q128对应的片选引脚为GPIO输出模式,并将其设置为高电平(通常意味着SPI处于非选通状态)。
初始化SPI接口:
配置SPI的工作模式(根据NM25Q128支持的SPI模式0或模式3)。
设置数据传输位数(通常是8位)。
分配SPI时钟源并设置分频系数以得到合适的SPI时钟频率。
根据需求设置数据传输顺序(MSB或LSB优先)。
使用HAL库函数如HAL_SPI_Init()进行初始化。

2.NM25Q128 读取
发送读取指令(0x03)。
发送24位地址(地址对齐到读取粒度)。
通过SPI接口读取数据,可以循环读取直到需要的数据量接收完毕。

3.NM25Q128 扇区擦除
发送写使能指令(0x06)。
确保设备处于空闲状态,可以通过读取状态寄存器来判断。
发送扇区擦除指令(0x20)。
发送24位地址(地址对齐到扇区边界)。
等待设备完成擦除操作并返回空闲状态。

4.NM25Q128 写入
可选:如果目标地址所在的扇区尚未擦除,则先执行扇区擦除。
发送写使能指令(0x06)。
发送页写指令(0x02)。
发送24位地址(地址对齐到页边界)。
发送要写入的数据,每次最多256字节(一个页)。
确保所有数据发送完毕,并等待设备返回空闲状态。

NOR FLASH驱动注意事项:
**1.是否需要擦除:**在向NOR Flash写入数据前,必须确保目标地址所在的区域已经被擦除,因为NOR Flash只能向已擦除的区域写入数据,且是以块(扇区/页)为单位进行擦除操作。
2.写入数据:
**换页:**如果需要写入的数据跨越了页的边界,必须分开多次写入操作,每次写入不超过一个页的数据量。
换扇区:同样的,如果跨越了扇区边界,也需确保对相邻扇区做相应的擦除操作。
**3.遵循读、改、写的原则:**在修改已存在的数据时,通常需要先读取原始数据,更改需要改变的部分,然后覆盖写入整个块(或页)。这是因为在NOR Flash中不能直接修改已写入的数据,只能通过擦除后再写入的方式更新数据。
在实际应用中,应根据NM25Q128的数据手册和所使用的HAL库函数来精确实施上述步骤。

七、编程实战

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【ROS2】节点

文章目录 ROS2 节点示例:创建并运行成功一个节点1. 创建功能包2. 编写源文件、CMakeLists.txt、package.xml3. 编译功能包4. 设置环境变量5. 运行节点6. 查看节点 参考链接 ROS2 节点 机器人的每一项功能,都被称为是一个节点。 每个节点都是一个独立的…

@PostConstruct

PostConstruct initializeBean方法–> PostProcessor.postProcessBeforeInitialization–> InitDestroyAnnotationBeanPostProcessor.postProcessBeforeDestruction 被PostConstruct注解的方法会在Bean初始化的时候被调用,如下图: 继承关系如下…

json-server 模拟接口服务

前端开发经常需要模拟接口请求,可以通过 json-server 实现。 1. 安装 json-server 在前端项目的终端命令行中执行 npm i json-server2. 创建数据源 在项目中新建文件 db.json ,与 package.json 同级,内容为模拟的数据 注意 json 文件对格式…

基于SSM的“网约车用户服务平台”的设计与实现(源码+数据库+文档)

基于SSM的“网约车用户服务平台”的设计与实现(源码数据库文档) 开发语言:Java 数据库:MySQL 技术:SSM 工具:IDEA/Ecilpse、Navicat、Maven 系统展示 系统功能 首页 站内新闻浏览 打车信息查询功能 在线打车功能…

Docker尚硅谷_高级篇

Docker尚硅谷 高级篇一、Dockerfile1.1 Dockerfile1.2 构建过程1.3 Dockerfile保留字1.3 构建镜像1.4 虚悬镜像 二、Docker发布微服务2.1 搭建SpringBoot项目2.2 发布微服务项目到Docker容器 三、Docker网络3.1 Docker网络3.2 docker网络命令3.3 Docker网络模式3.4 docker03.5 …

离散化(算法竞赛)

Ⅰ 离散化简介 离散化:把无限空间中有限的个体映射到有限的空间中去,以此提高算法的时空效率。通俗的说,离散化是在不改变数据相对大小的条件下,对数据进行相应的缩小。 适用范围:数组中元素值域很大,但个…

面试八股之Redis篇2——redis分布式锁

🌈hello,你好鸭,我是Ethan,一名不断学习的码农,很高兴你能来阅读。 ✔️目前博客主要更新Java系列、项目案例、计算机必学四件套等。 🏃人生之义,在于追求,不在成败,勤通…

C语言——文件相关操作补充

一、文件读取结束的判定 当我们使用例如fgetc、fgets、fscanf、fread等函数来读取文件内容时,我们可能遇到需要判断文件读取的结束,一般情况下都是通过这些函数的返回值来判断文件读取是否结束。 1、fgetc 返回读取的字符的ASCII值,如果读…

攻防世界-web-fileclude(二)

题目 解题 题目源码 WRONG WAY! <?php include("flag.php"); highlight_file(__FILE__); if(isset($_GET["file1"]) && isset($_GET["file2"])) {$file1 $_GET["file1"];$file2 $_GET["file2"];if(!empty($…

10分钟入门pandas(一)

pandas 是基于python语言的数据分析处理库,使用广泛。本文主要参考pandas的官方入门指导,并结合自己入门使用的一些常用操作进行说明。 pandas通常和numpy结合使用,一般通过如下语句导入numpy和pandas库。 import numpy as np import pandas as pd一. pandas 数据结构 pan…

一个全栈SpringBoot项目-Book Social Network

一个全栈SpringBoot项目-Book Social Network BSN是一个会员之间交换图书的社交网络平台。图书社交网络是一个全栈应用程序&#xff0c;使用户能够管理他们的图书收藏并与图书爱好者社区互动。它提供的功能包括用户注册、安全电子邮件验证、图书管理&#xff08;包括创建、更新…

6818Linux内核开发移植

Linux内核开发移植 Linux内核版本变迁及其获得 Linux是最受欢迎的自由电脑操作系统内核&#xff0c; 是一个用C语言写成&#xff0c; 并且符合POSIX标准的类Unix操作系统 Linux是由芬兰黑客Linus Torvalds开发的&#xff0c; 目的是尝试在英特尔x86架构上提供自由免费的类Un…

Linux day4 _vim及其相关指令

wc命令 做数量统计 可以通过wc命令统计文件的行数&#xff0c;单词数量等 语法&#xff1a;wc [-c -m -l -w] 文件路径 选项 -c&#xff0c;统计bytes数量 -m&#xff0c;统计字符数量 -l&#xff0c;统计行数 -w统计单词数量 参数&#xff0c;文件路径&#xff0c;被统…

MySQL表死锁查询语句

步骤1&#xff1a;查询表死锁的sql语句&#xff1a; SELECT * FROM information_schema.PROCESSLIST where length(info) >0 ; 或 SELECT * FROM information_schema.INNODB_TRX; 步骤2&#xff1a;删除 kill "对应的线程id"

COM741-S,FCU713-S浙大中控

COM741-S,FCU713-S浙大中控。安装过程中需要选择SQL SERVER数据服务器&#xff0c;并且需要身份验证&#xff0c;选择Local服务器&#xff0c;Windows 身份验证&#xff0c;然后点击开始&#xff0c;COM741-S,FCU713-S浙大中控。数据库复制成功后&#xff0c;会弹出如下对话框&…

中霖教育:税务师考试可以申请免试吗?

符合下列相应条件之一的&#xff0c;可报名参加税务师职业资格考试&#xff1a; 1.取得经济学、法学、管理学学科门类大学本科及以上学历(学位);或者取得其他学科门类大学本科学历&#xff0c;从事经济、法律相关工作满1年。 2.取得经济学、法学、管理学学科门类大学专科学历…

Spring STOMP-消息处理流程

一旦STOMP的接口被公布&#xff0c;Spring应用程序就成为连接客户端的STOMP代理。本节描述服务端消息处理的流程。 spring-messaging模块包含消息类应用的基础功能&#xff0c;这些功能起源于Spring Integration项目。并且&#xff0c;后来被提取整合到Spring框架&#xff0c;…

自定义实现 Java17+SpringBoot3+OpenAPI+Knife4j Starter

文章目录 前言正文1 创建starter项目1.1 依赖文件1.2 配置信息 2 自定义starer代码开发2.1 配置字段的定义2.2 自动配置类 3 验证starter3.1 测试项目的配置3.2 功能配置 application.yml3.3 测试代码3.3.1 实体类3.3.2 控制器13.3.2 控制器2 4 效果展示4.1 主页4.2 实体类列表…

RuoYi-Vue-Plus (SpringCache、CacheManager、@Cacheable、缓存雪崩、击穿、穿透)

一、概述 1、SpringCache是Spring提供的一个缓存框架&#xff0c;在Spring3.1版本开始支持将缓存添加到现有的spring应用程序中&#xff0c;在4.1开始&#xff0c;缓存已支持JSR-107注释和更多自定义的选项。 2、SpringCache利用了AOP&#xff0c;实现了基于注解的缓存功能&…

LeetCode 题目 120:三角形最小路径和

作者介绍&#xff1a;10年大厂数据\经营分析经验&#xff0c;现任字节跳动数据部门负责人。 会一些的技术&#xff1a;数据分析、算法、SQL、大数据相关、python&#xff0c;欢迎探讨交流 欢迎加入社区&#xff1a;码上找工作 作者专栏每日更新&#xff1a; LeetCode解锁1000题…