leetCode-hot100-链表专题
leetCode-hot100-链表专题
- 链表简介
- 单链表
- 单链表的使用
- 例题
- 206.反转链表
- 19.删除链表的倒数第N个结点
- 24.两两交换链表中的节点
- 25.K个一组翻转链表
- 双向链表
- 双向链表的使用
- 循环链表
- 61.旋转链表
- 141.环形链表
- 142.环形链表Ⅱ
- LinkedList
- LinkedList的使用
链表简介
参考博客:java数据结构之链表。
链表是一种常见的基础数据结构,它由一系列节点组成,每个节点包含数据域和一个或多个指针域,用于指向其它节点。链表不像数组那样在内存中连续存储,它的节点可以分散地存储在内存中,通过指针连接起来。
链表的主要优点是它对插入和删除操作的效率很高,尤其是当链表的长度变化很大时。在链表中进行插入和删除操作,只需要改变相应节点的指针,而不需要像数组那样进行大量元素的移动。而需要频繁查找元素的场景适合使用顺序表。
链表的主要类型包括:
- 单向链表:每个节点只包含一个指向下一个节点的指针。
- 双向链表:每个节点包含两个指针,一个指向前一个节点,一个指向下一个节点。
- 循环链表:链表中最后一个节点的指针指向第一个节点,形成一个环。
- 双向循环链表:是双向链表和循环链表的结合,每个节点有两个指针,分别指向前一个节点和后一个节点,并且最后一个节点的指针指向第一个节点。
需要理解的点:
关于连续?
链表在逻辑上是连续的,但是物理上并不一定是连续的,链表的结点一般都是从堆上申请,由于每次都是按照一定的分配策略,所以两次申请到的结点可能连续,可能不连续。
关于“头”
链表中的头节点的data域中是空的,一般编码设置头节点都是为了方便后续的操作,不需要进行特殊处理,而且可以简化链表的操作,关于头节点,看到的博文中有个很形象的比喻:带不带头可以简单理解为有人驾驶的列车和无人驾驶的列车,有人驾驶的列车不能在火车头前面加车厢,第一节车厢永远是驾驶室;而无人驾驶的列车则可以在最前面加车厢,哪节车厢在最前面哪节就是头。即head只是用来标识。java数据结构之链表。(这篇博文讲解了链表操作的底层逻辑,文章的内容也是以此为参考,很不戳!建议大家都去读读)
关于“循环”
判断是不是循环就看最后一个结点的next域存放的是null还是第一个结点的地址。
单链表
单链表的使用
| 方法 | 备注 |
|---|---|
addFirst(int data) | 将data插入链表头部 |
addLast(int data) | 将data插入链表尾部 |
addIndex(int index,int data) | 在下标为index位置插入data,第一个数据节点为0号下标 |
contains(int key) | 查找关键字key是否在单链表当中 |
remove(int key) | 删除第一次出现关键字为key的节点 |
removeAllKey(int key) | 删除所有值为key的节点 |
size() | 得到单链表的长度 |
clear() | 清空链表 |
display() | 从头结点开始遍历,若该结点不等于null就打印输出该结点的元素 |
例题
206.反转链表
思路:
本题是25.K个一组翻转链表,25题中需要对分段的链表进行翻转,而本题翻转整个链表,直接翻转即可,步骤如下:
- 初始化两个指针,
pre和cur。pre开始时为null,因为它需要指向当前节点cur之前的一个节点,而反转开始前没有这样的节点。cur初始化为链表的头部head。 - 进入一个循环,只要
cur不是null,就执行循环体。这意味着只要当前节点不是链表的最后一个节点,就继续反转。 - 在循环内部,首先使用一个临时节点
next保存cur的下一个节点。这是必要的,因为一旦cur.next被修改指向pre,我们就失去了对原始下一个节点的引用。 - 接下来,将
cur.next指向pre,这是反转节点的关键步骤。 - 然后,将
pre移动到它的新位置,即当前的cur节点。 - 最后,将
cur移动到下一个节点,即之前保存在next中的节点。
当cur变为null时,循环结束,此时pre是新的头节点,因为它指向原始链表的最后一个节点。
时间复杂度:
这个算法的时间复杂度是O(n),其中n是链表的长度。这是因为算法会遍历整个链表一次,每个节点都会被访问一次以进行反转。
代码实现:
class Solution {public ListNode reverseList(ListNode head) {ListNode pre = null;ListNode cur = head;while(cur != null){ListNode next = cur.next;cur.next = pre;pre = cur;cur = next;}return pre;}
}
19.删除链表的倒数第N个结点
思路1:
本题采用快慢指针来解决,让快指针比慢指针先走n步,当快指针到达链表尾部时,慢指针所指向的下一个结点就是需要删除的倒数第n个结点,在做链表相关的题目时一般需要在头节点的前面设置一个虚拟的结点,方便边界的判断。详细的视频讲解点击视频讲解-删除链表的倒数第N个结点。

时间复杂度:
时间复杂度为O(n),其中n是链表的长度。代码中有一个循环,循环的次数是链表的长度n,因此时间复杂度为O(n)。
代码实现:
class Solution {public ListNode removeNthFromEnd(ListNode head, int n) {ListNode dummy = new ListNode(0);ListNode slow = dummy;ListNode fast = dummy;dummy.next = head;//让快指针先向前走n步for(int i = 0;i < n;i++){fast=fast.next;}while(fast.next != null){slow = slow.next;fast = fast.next;}//删除慢指针的下一个结点,即需要删除的结点slow.next = slow.next.next;return dummy.next;}
}
思路2:
删除链表的第n个节点比较简单,所以我们可以先将链表翻转,然后删除第n个节点后再次翻转即可,其中翻转节点的操作在25.K个一组翻转链表以及206.反转链表中都有用到,具体的步骤解释详细见206题的解析。
时间复杂度:
时间复杂度为O(n),其中n为链表长度。
代码实现:
class Solution {public ListNode removeNthFromEnd(ListNode head, int n) {ListNode dummy = new ListNode(0);//翻转链表,删除第n个节点dummy.next = reserve(head);ListNode cur = dummy;//循环找到要删除节点的前一个节点for(int i = 0; i < n - 1; i++){cur = cur.next;}//删除第n个节点cur.next = cur.next.next;//翻转链表,得到删除倒数第n个节点的链表dummy.next = reserve(dummy.next);return dummy.next;}//翻转链表private ListNode reserve(ListNode head){ListNode pre = null;ListNode cur = head;while(cur != null){ListNode next = cur.next;cur.next = pre;pre = cur;cur = next;}return pre;}
}
24.两两交换链表中的节点
思路:
本题采用三指针来解决,首先需要新建一个虚拟头节点,方便操作,然后分别新建三个指针指向虚拟头节点和头节点以及头节点的下一个节点,通过操作三个指针使得节点互换位置,然后将指针整体后移,相同的操作。详细的讲解点击视频讲解-两两交换链表中的节点。

时间复杂度:
时间复杂度为O(n),其中n是链表的长度。
代码实现:
class Solution {public ListNode swapPairs(ListNode head) {ListNode dummy = new ListNode(0);dummy.next = head;//定义两个指针分别指向虚拟头节点dummy和其下一个节点ListNode pre = dummy;ListNode cur = dummy.next;while(cur != null && cur.next != null){//定义第三个指针ListNode next = cur.next;pre.next = next;cur.next = next.next;next.next = cur;pre = cur;cur = cur.next;}return dummy.next;}
}
25.K个一组翻转链表
思路:
本题采用的思路是,先将链表按K个节点一组分割,然后单独对每一组进行翻转,最后再拼接起来即可,翻转函数逻辑比较简单,就是采用三个指针,每次让中间的指针(刚开始指向头节点)指向其前一个指针并整体后移,重复操作。分割和拼接的操作其实也很简单,如果看代码不太明白,可以画个链表跟着操作走一遍,就会明白每一步的含义,代码里有注释,希望对你有用,详细的视频讲解点击视频讲解-K个一组翻转链表。
时间复杂度:
时间复杂度为O(n),其中n是链表的长度。代码中有一个while循环,每次循环都会处理k个节点(反转、拼接),所以循环的次数最多为n/k。在循环中,反转操作的时间复杂度为O(k),拼接操作的时间复杂度为O(1)。因此,总的时间复杂度可以近似为O(n)。
代码实现:
class Solution {public ListNode reverseKGroup(ListNode head, int k) {ListNode dummy = new ListNode(0);dummy.next = head;//定义首尾指针指向dummyListNode start = dummy;ListNode end = dummy;//按K个一组分割链表while(true){for(int i = 0 ;i < k && end != null;i++) end = end.next;if(end == null) break;//分割后的链表的头节点ListNode startNext = start.next;//分割后的剩余链表的头节点ListNode endNext = end.next;//分割前K个节点end.next = null;//对前K个节点的链表进行翻转start.next = reverse(start.next);//将翻转后的链表的与剩余的节点拼接到一起startNext.next = endNext;//更新头尾节点,开始下一轮的翻转start = end = startNext;}return dummy.next;}//定义反转函数private ListNode reverse(ListNode head){ListNode cur = head;ListNode pre = null;while(cur != null){ListNode next = cur.next;//每次cur指针指向前一个节点,达到翻转的目的,然后将三个指针后移,重复操作,直到cur为空cur.next = pre;pre = cur;cur = next;}return pre;}
}
双向链表
双向链表相当于是单链表中的一种改进,在单链表的基础上增加了一个前驱结点来存放前一个结点的位置,这使得某些操作会更加简单。
双向链表的使用
双向链表的使用和单链表基本相同。
| 方法 | 备注 |
|---|---|
addFirst(int data) | 将data插入链表头部 |
addLast(int data) | 将data插入链表尾部 |
addIndex(int index,int data) | 在下标为index位置插入data,第一个数据节点为0号下标 |
contains(int key) | 查找关键字key是否在单链表当中 |
remove(int key) | 删除第一次出现关键字为key的节点 |
removeAllKey(int key) | 删除所有值为key的节点 |
size() | 得到单链表的长度 |
clear() | 清空链表 |
display() | 从头结点开始遍历,若该结点不等于null就打印输出该结点的元素 |
循环链表
1.循环链表的表尾节点指针next指向头结点
2.循环链表从一个节点出发可以找到其他任意一个节点
3.循环链表的判空操作和普通单链表的判空方法基本相同,不同之处在于循环链表的判空是判断头结点的指针是否指向头结点,而普通单链表的判空是判断头结点的指针是否指向null
4.判断节点n是否为循环单链表的表尾节点和普通单链表的判断方法基本相同,不同之处在于循环链表的判空是判断n节点的指针是否指向头结点,而普通单链表的判空是判断n节点的指针是否指向null。
61.旋转链表
思路:
(1)成环:
- 首先检查链表是否为空,如果为空,则直接返回
null。 - 定义一个指针
cur,初始指向头节点head。 - 遍历链表,计算链表的长度
n,并将链表的最后一个节点指向头节点,使链表形成一个环。
(2)找到需要分段的节点:
- 再次遍历链表,这次是为了找到新的头节点位置。由于旋转次数
k可能大于链表长度n,因此使用k % n来获取实际需要旋转的次数。 - 循环
n - k % n次,找到旋转后链表的头节点的前一个节点,即cur。
(3)改变头节点的位置,断开环:
- 将
cur.next设置为新的头节点head。 - 将
cur.next设置为null,断开环,使链表恢复为线性结构。
(4)返回头节点:
最后返回新的头节点head,此时链表已经完成了旋转操作。视频讲解点击视频讲解-旋转链表。

时间复杂度:
时间复杂度为O(n),其中n为链表的长度。
代码实现:
class Solution {public ListNode rotateRight(ListNode head, int k) {if(head == null) return null;//1.成环ListNode cur = new ListNode();cur = head;int n = 1;while(cur.next != null){cur = cur.next;n++;}cur.next = head;//2.找到需要分段的节点for(int i = 0;i < n - k % n;i++){cur = cur.next;}//3.改变头节点的位置,断开环head = cur.next;cur.next = null;return head;}
}
141.环形链表
思路:
本题主要是下面两个思想:
快慢指针: 通过使用两个速度不同的指针在链表中遍历,可以有效地检测环的存在。慢指针每次走一步,快指针每次走两步。
相遇点: 如果链表中有环,快指针会在环中追上慢指针,最终导致两者相遇。如果没有环,快指针会在到达链表末尾时终止。
为什么快指针不能每次移动三步或者更多呢?快指针每次移动两步,慢指针每次移动一步。这种配置保证了快指针的速度是慢指针的两倍。这样,在最坏的情况下,当链表中存在环时,快指针和慢指针将在环中相遇,在这种情况下,相遇所需的步数最多是环长度的两倍。
如果快指针每次移动三步或更多步,相遇的模式变得更复杂,需要更多的步骤来分析和证明算法的正确性。同时,更快的速度可能会跳过慢指针,特别是在环比较小的情况下,增加了算法的复杂性。视频讲解点击视频讲解-环形链表。
时间复杂度:
时间复杂度为O(n),其中n为链表长度。
代码实现:
public class Solution {public boolean hasCycle(ListNode head) {ListNode fast = head;ListNode slow = head;while(fast != null && fast.next != null){slow = slow.next;fast = fast.next.next;if(slow == fast){return true;}}return false;}
}
142.环形链表Ⅱ
思路:
算法思想:
(1)初始化:
- 使用两个指针
fast和slow,它们都从链表的头节点head开始。
(2)检测环的存在:
- 在一个
while循环中,fast指针每次移动两步,slow指针每次移动一步。 - 如果链表中存在环,
fast和slow指针最终会在环内相遇(相同的节点)。
(3)寻找环的起点:
- 一旦
fast和slow指针相遇,将slow指针重新指向链表的头节点,同时保持fast指针在相遇点。 - 这时,
slow和fast指针每次都移动一步。当它们再次相遇时,相遇点就是环的起始节点。
证明:

由上面的证明可知,当slow和fast第一次相遇时,此时让slow回到head,fast从第一次相遇的点同步出发,最终二者会在环的入点相遇(fast回到head,slow在第一次相遇点出发是同样的效果)。
视频讲解点击视频讲解-环形链表Ⅱ。
时间复杂度:
时间复杂度为O(m+n),其中m为链表非环部分的长度,n为环的长度,无论链表的非环部分和环的长度如何,算法的运行时间都与环的长度成线性关系,所以时间复杂度可以简化为 O(n)。
代码实现:
public class Solution {public ListNode detectCycle(ListNode head) {ListNode fast = head;ListNode slow = head;while(fast != null && fast.next != null){slow = slow.next;fast = fast.next.next;//第一次相遇,将slow置为头节点if(slow == fast){slow = head;while(slow != fast){slow = slow.next;fast = fast.next;}return slow;}}return null;}
}
LinkedList
LinkedList底层使用了双向链表并实现了List接口,不支持随机访问,但是在任意位置插入和删除元素的效率很高,适合需要频繁插入和删除元素的场景。
LinkedList的使用
//创建一个空的LinkedList
List<Integer> list = new LinkedList<>()
常用方法:
| 方法 | 备注 |
|---|---|
add(e) | 在尾部插入e |
add(int index, e) | 将e插入index位置 |
addAll(C) | 将C中的元素全部插入尾部 |
remove(int index) | 删除 index 位置元素 |
remove(Object o) | 删除遇到的第一个 o |
get(int index) | 获取下标 index 位置元素 |
set(int index, e) | 将下标 index 位置元素设置为 e |
clear() | 清空 |
contains(Object o) | 判断 o 是否在线性表中 |
indexOf(Object o) | 返回第一个 o 所在下标 |
lastIndexOf(Object o) | 返回最后一个 o 的下标 |
subList(int fromIndex, int toIndex) | 截取部分 list |
三种遍历方法:
//使用forEach遍历
for(int item : list){System.out.print(e + " ");
}
//使用迭代器遍历-正向
ListIterator<Integer> i1 = list.listIterator();
while(i1.hasNext()){System.out.print(i1.next+" ");
}
//使用迭代器遍历-反向
ListIterator<Integer> i2 = list.listIterator(list.size());
while (i2.hasPrevious()) {System.out.print(i2.previous()+" ");
}
相关文章:
leetCode-hot100-链表专题
leetCode-hot100-链表专题 链表简介单链表单链表的使用例题206.反转链表19.删除链表的倒数第N个结点24.两两交换链表中的节点25.K个一组翻转链表 双向链表双向链表的使用 循环链表61.旋转链表141.环形链表142.环形链表Ⅱ LinkedListLinkedList的使用 链表简介 参考博客&#x…...
【ai】tx2-nx:配置tritonserver2.17.0-jetpack4.6 环境并运行例子
2.17.0 for jetpack 4.6运行需要 如果在jetson上构建Triton : Note: When building Triton on Jetson, you will require a newer version of cmake. We recommend using cmake 3.21.0. Below is a script to upgrade your cmake version to 3.21.0. You can use cmake 3.18.4…...
Spring和Spring Boot常用注解介绍及使用
Spring和Spring Boot框架通过丰富的注解集简化了Java开发,使得配置更加简洁且易于理解。 下面是一些常用的Spring和Spring Boot注解及其使用方式的简介: 目录 1. Component 2. Service 3. Repository 4. Controller 5. RestController 6. Autowire…...
【计算机毕业设计】211校园约拍微信小程序
🙊作者简介:拥有多年开发工作经验,分享技术代码帮助学生学习,独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。🌹赠送计算机毕业设计600个选题excel文件,帮助大学选题。赠送开题报告模板ÿ…...
笨蛋学算法之LeetCodeHot100_1_两数之和(Java)
package com.lsy.leetcodehot100;public class _Hot1_两数之和 {//自写方法public static int[] twoSum1(int[] nums, int target) {//定义存放返回变量的数组int[] arr new int[2];//遍历整个数组for (int i 0; i < nums.length; i) {//从第二个数开始相加判断for (int j…...
用ip link add link命令创建vlan子设备
用ip link add link命令创建vlan子设备 ip link add link 命令用于在 Linux 系统中创建网络设备,其中可以用它来创建 VLAN (Virtual Local Area Network) 子接口,这是一个典型的用法。 VLAN是一种在二层网络(即数据链路层)上区分…...
AD复用布局布线
在用AD软件绘制PCB时,如果有多个部分布线相同,则可以使用复用布局布线功能,加快并且方便PCB的绘制。 一、创建Room 1、绘制好的电路图创建Room 2、需要拷贝的电路图创建Room 二、PCB List操作 1、PCB List内设置 2、复制绘制完的线路图 3、…...
【深度学习驱动流体力学】采集OpenFOAM仿真的流体力学数据送入到强化学习DQN模型训练
目录 技术原理1. 数据准备与环境构建2. DQN模型的设计与训练3. 训练过程中的监控与可视化训练记录参考技术原理 1. 数据准备与环境构建 首先,数据从VTK文件中读取并处理,这些文件包含流体速度场数据。通过PyVista库提取速度场信息,并将其存储在NumPy数组中。数据集随后被划…...
国内公开数据
以下是一些关于国内政府部门公布的数据或互联网上开放数据的资源,包括CSV、JSON和Parquet格式: 国内政府部门公开数据 中国政府数据开放平台 链接: 数据开放平台概要: 提供来自中国各级政府的公开数据集,数据格式包括CSV、JSON等。 上海市公…...
QT QByteArray 的用法
QByteArray 是 Qt 中用于处理原始字节数据的类,类似于标准库中的 std::vector<char> 或 std::string,但具有更多适合Qt框架的功能。它可以用来处理文本和二进制数据,并提供了一些方便的方法进行数据操作。下面是一些常见的用法示例&…...
InPixio Photo Cutter v10 解锁版安装教程 (懒人抠图工具)
前言 InPixio Photo Cutter是一款懒人抠图工具,采用了增强的算法切割技术,可以在不影响图像质量的情况下,允许用户从照片中删除任何物体或人物,并且保持其完整的质量。你只需点击几下鼠标,便可从照片中剪下任何细节、…...
Java17 --- SpringSecurity之OAuth2
一、OAuth2 1.1、使用github以授权码方式 1.1.1、注册应用程序 1.1.2、测试代码 pom依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-oauth2-client</artifactId></dependency> spring…...
服务器上线的一些事
最近不少人在上线上遇到问题 对于最近的上戏 进行一个坑或操作步骤的总结 以及遇到这些之后如何做 关于选项的选择 1 对于是否要在一个小时前释放 这个是看个人的 2 对于选择一台服务器还是两台呢?这个是最后限制 一台 这个免费的服务器 是有一个两百的额度的 选择…...
OceanBase-docker安装、连接数据库、修改mysql用户密码
OceanBase-docker安装、连接数据库、修改mysql用户密码 安装拉取镜像开启容器验证 连接数据库1.直接连接的方式修改数据库密码2.先进入镜像再连接数据库的方式进入镜像无密码有秘密 本人使用docker安装的oceanbase 安装 拉取镜像 docker pull oceanbase/oceanbase-ce:3.1.4 …...
浪潮(Inspur)服务器硬件监控指标解读
随着企业业务的快速发展,服务器的稳定运行成为保障业务连续性的关键。浪潮(Inspur)服务器以其卓越的性能和稳定性,在数据中心中扮演着重要角色。 为了确保服务器的稳定运行,监控易作为一款专业的IT基础设施监控软件&am…...
极简opencv操作xml文件
目标 修改xml文件,先产生一个临时文件,拷贝,修改,改名,使用opencv 非常简单地就可以搞定配置xml文件 code #include <opencv2/opencv.hpp> #include <iostream> #include <opencv2/core/utils/files…...
更换域名流程记录
华为云的服务器,阿里云购买的域名。 1.购买域名 2.在域名服务商绑定服务器ip(以阿里云为例) 控制台->域名控制台->域名列表->点击域名->域名解析->添加记录 记录类型填A , 主机记录“”或“www”,记录值填服务器i…...
CSS 实现电影信息卡片
CSS 实现电影信息卡片 效果展示 CSS 知识点 CSS 综合知识运用 页面整体布局 <div class"card"><div class"poster"><img src"./poster.jpg" /></div><div class"details"><img src"./avtar…...
Skype机器人
这段代码是一个Skype机器人,它使用OpenAI的GPT模型来回答与基督教相关的问题。机器人会读取最近的聊天历史,生成一个回复,并发送给用户。以下是对代码每一部分的详细解释: 导入模块 import json import http.client from skpy import SkypeEventLoop, SkypeNewMessageEve…...
海外仓系统能解决海外仓哪些难题?海外仓标准化管理实用指南
海外仓管理问题常常导致业务流程变慢,根据我们的调查显示,至少有48%的海外仓每周都会出现一些“小意外”。甚至这些小问题每天都在发生,问题的出现已经严重影响到了海外仓业务的进行。今天我们将重点分析海外仓比较常见的一些问题,…...
装饰模式(Decorator Pattern)重构java邮件发奖系统实战
前言 现在我们有个如下的需求,设计一个邮件发奖的小系统, 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其…...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...
相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了: 这一篇我们开始讲: 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下: 一、场景操作步骤 操作步…...
CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...
JVM 内存结构 详解
内存结构 运行时数据区: Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器: 线程私有,程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 每个线程都有一个程序计数…...
手机平板能效生态设计指令EU 2023/1670标准解读
手机平板能效生态设计指令EU 2023/1670标准解读 以下是针对欧盟《手机和平板电脑生态设计法规》(EU) 2023/1670 的核心解读,综合法规核心要求、最新修正及企业合规要点: 一、法规背景与目标 生效与强制时间 发布于2023年8月31日(OJ公报&…...
嵌入式学习之系统编程(九)OSI模型、TCP/IP模型、UDP协议网络相关编程(6.3)
目录 一、网络编程--OSI模型 二、网络编程--TCP/IP模型 三、网络接口 四、UDP网络相关编程及主要函数 编辑编辑 UDP的特征 socke函数 bind函数 recvfrom函数(接收函数) sendto函数(发送函数) 五、网络编程之 UDP 用…...
使用SSE解决获取状态不一致问题
使用SSE解决获取状态不一致问题 1. 问题描述2. SSE介绍2.1 SSE 的工作原理2.2 SSE 的事件格式规范2.3 SSE与其他技术对比2.4 SSE 的优缺点 3. 实战代码 1. 问题描述 目前做的一个功能是上传多个文件,这个上传文件是整体功能的一部分,文件在上传的过程中…...
绕过 Xcode?使用 Appuploader和主流工具实现 iOS 上架自动化
iOS 应用的发布流程一直是开发链路中最“苹果味”的环节:强依赖 Xcode、必须使用 macOS、各种证书和描述文件配置……对很多跨平台开发者来说,这一套流程并不友好。 特别是当你的项目主要在 Windows 或 Linux 下开发(例如 Flutter、React Na…...
倒装芯片凸点成型工艺
UBM(Under Bump Metallization)与Bump(焊球)形成工艺流程。我们可以将整张流程图分为三大阶段来理解: 🔧 一、UBM(Under Bump Metallization)工艺流程(黄色区域ÿ…...
