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

web前端算法简介之链表

  • 链表
    • 链表 VS 数组
    • 链表类型
    • 链表基本操作
      • 创建链表
      • 插入操作
      • 删除操作
      • 查找操作
      • 显示/打印链表
      • 反转链表
      • 合并两个有序链表
      • 链表基本操作示例
  • JavaScript中,instanceof
  • 环形链表
    • 判断是否存在环: – 快慢指针
    • 找出环的入口点
    • 计算环长
  • 关于链表的前端算法题
    • 141. 环形链表
    • 237. 删除链表中的节点
    • 83. 删除排序链表中的重复元素
    • 206. 反转链表

链表

Javascript的原型链就是一个链表

链表是一种线性数据结构,它通过 指针(在某些编程语言中可能是引用)将一系列的节点(元素)链接起来。

每个节点除了包含 数据 外,还包含一个指向下一个节点的指针,这样就形成了一个链式存储结构。

链表 VS 数组

相比于数组:

链表在内存中并 不需要是连续的空间,这使得它在插入和删除操作上具有一定的优势,尤其是在大数据量且频繁进行插入、删除操作的场景下。

访问链表中的元素(例如获取第k个节点的数据)通常比数组慢,因为链表需要从头节点开始逐个遍历

链表和数组是两种基本且重要的数据结构,它们各自有各自的优点和适用场景:

数组

  • 存储方式:数组是在内存中连续存放的一系列元素,每个元素可以通过索引(下标)直接访问。
  • 访问速度:由于数组的内存空间是连续的,因此可以使用索引在常量时间内(O(1)复杂度)随机访问任何位置的元素。
  • 插入与删除:如果要在数组中间插入或删除元素,通常需要移动后续元素以保持连续性,这可能需要 O(n) 的时间复杂度,尤其是在最坏情况下(例如在数组头部插入或尾部删除时不需要移动其他元素)。
  • 空间效率:数组预先分配了固定大小的空间,不灵活但通常比较节省空间,特别是当元素填充率高时。

链表

  • 存储方式:链表中的元素不必连续存储,每个节点包含数据和指向下一个节点的指针。
  • 访问速度:链表访问任意元素的时间复杂度通常是线性的 O(n),因为必须从头节点开始逐个遍历到目标节点。
  • 插入与删除:链表可以在常量时间内(O(1)复杂度)进行插入和删除操作,只需要改变相应节点的指针即可。特别是在链表头部和尾部进行插入和删除操作时非常高效。
  • 空间效率:链表在内存分配上较为灵活,可以根据需要动态添加或删除节点,但相比数组会额外消耗一些存储空间来保存指针信息。

总结来说:

  • 如果程序需要频繁的查找操作或者对随机访问性能要求较高,数组是一个更好的选择。
  • 当需要频繁执行插入和删除操作,尤其是列表结构变化较大时,链表由于其高效的插入删除特性更为合适。
  • 在考虑缓存友好的场景下,数组由于其连续存储的特性更容易利用CPU缓存机制提高访问效率。

链表类型

链表主要分为以下几种类型:

  1. 单向链表:每个节点只有一个指针指向下一个节点。
  2. 双向链表:每个节点有两个指针,一个指向前一个节点,另一个指向后一个节点。
  3. 循环链表:单向或双向链表的最后一个节点的指针指向头节点,形成一个环状结构。
  4. 静态链表:在数组的基础上模拟实现链表,用数组下标表示前后节点的关系。

链表常用于实现各种高级数据结构,如栈、队列、哈希表等。

链表基本操作

链表的基本操作主要包括以下几种:

创建链表
  • 初始化一个空链表,即创建一个头节点(可能不存储数据,仅作为起点),并将其next指针设置为NULL(在C语言中)或None(在Python等语言中)。
插入操作
  • 在链表头部插入:创建新节点,将新节点的next指向原头节点,然后更新头节点为新节点。
  • 在链表尾部插入:找到链表的尾节点(通过遍历或者维护尾指针实现),然后将尾节点的next指向新节点。
  • 在链表中间插入:找到要插入位置的前一个节点,然后修改其next指针,使其指向新节点,新节点的next指针再指向原后继节点。
删除操作
  • 删除头节点:找到头节点的下一个节点,并将头节点更新为此节点。
  • 删除尾节点:找到倒数第二个节点,将其next指针设置为NULL/None。
  • 删除中间节点:找到待删除节点的前一个节点,将其next指针直接指向待删除节点的后继节点。
查找操作
  • 查找特定值:从头节点开始,逐个比较节点中的数据,直到找到匹配项或遍历完所有节点。
显示/打印链表
  • 从头节点开始,通过递归或循环遍历整个链表,并打印每个节点的数据。
反转链表
  • 可以通过迭代或递归的方式改变每个节点的next指针方向,使得链表反向。
合并两个有序链表
  • 创建一个新的头节点,然后依次比较两个链表的当前节点,将较小者添加到结果链表中,并移动对应的指针到下一个节点,直到某一个链表为空,再将另一个链表剩余部分连接到结果链表末尾。

以上是链表基本操作的主要内容,每种操作的具体实现会因编程语言和链表类型(单向、双向、循环链表)的不同而有所差异。

链表基本操作示例

在JavaScript中,链表的基本操作可以通过定义链表节点类(Node)和链表类(LinkedList)来实现。以下是一些基本操作的示例:

<script type="text/javascript">
let a = {key:'aaa'};
let b = {key:'bbb'};
let c = {key:'ccc'};
let d = {key:'ddd'};a.next = b;
b.next = c; 
c.next = d;
d.next = null;console.log( a ); //遍历链表
let obj = a;
while( obj && obj.key ){console.log( obj.key );obj = obj.next;
}//链表中插入某个元素
let m = {key:'mmmmm'};
c.next = m;
m.next = d;
console.log( a );//删除操作
c.next = d; 
</script>

定义链表节点类(Node)

class Node {constructor(element) { // 创建一个新节点,传入元素值this.element = element; // 节点存储的数据this.next = null; // 指向下一个节点的指针,默认为空}
}

定义链表类(LinkedList)

class LinkedList {constructor() {this.head = null; // 头节点,默认为空}// 基本操作方法:// 在链表头部插入节点insertAtBeginning(element) {const newNode = new Node(element);newNode.next = this.head;this.head = newNode;}// 在链表尾部插入节点append(element) {let currentNode = this.head;if (!currentNode) {this.head = new Node(element);return;}while (currentNode.next !== null) {currentNode = currentNode.next;}currentNode.next = new Node(element);}// 查找特定值的节点find(element) {let currentNode = this.head;while (currentNode !== null) {if (currentNode.element === element) {return currentNode;}currentNode = currentNode.next;}return null; // 如果未找到则返回null}// 删除指定值的节点remove(element) {if (!this.head) return false; // 如果链表为空,直接返回if (this.head.element === element) {this.head = this.head.next;return true;}let prevNode = this.head;let currentNode = this.head.next;while (currentNode !== null) {if (currentNode.element === element) {prevNode.next = currentNode.next;return true;}prevNode = currentNode;currentNode = currentNode.next;}return false; // 如果未找到匹配项,则返回false}// 打印链表所有节点printList() {let currentNode = this.head;while (currentNode) {console.log(currentNode.element);currentNode = currentNode.next;}}
}

以上代码涵盖了链表的基本操作,包括创建链表、在头尾插入节点、查找节点、删除节点以及打印链表内容等。

根据需要,还可以扩展更多的链表操作方法,如反转链表、获取链表长度等。

更多详细内容,请微信搜索“前端爱好者戳我 查看

JavaScript中,instanceof

在JavaScript中,instanceof 是一个运算符,用于检测某个对象是否是某个构造函数的实例。其基本语法如下:

object instanceof constructor
  • object: 一个具体的对象实例。
  • constructor: 构造函数(类)。

这个运算符的工作原理是检查给定的对象在其原型链(prototype chain)上是否存在指定构造函数的 prototype 属性。

如果 constructor.prototypeobject 的原型链上,则返回 true,否则返回 false

例如:

function Animal(name) {this.name = name;
}let dog = new Animal('Rex');console.log(dog instanceof Animal); // 输出: true
console.log(dog instanceof Object); // 输出: true// 因为所有的对象都继承自Object,所以所有实例都会在其原型链上找到Object.prototype

在这个例子中,dog 是通过 Animal 构造函数创建的,因此它是一个 Animal 类型的实例,并且因为 JavaScript 中的所有对象最终都会继承自 Object,所以 dog 同样也是 Object 的实例。

js实现

const instanceofs = (target,obj)=>{let p = target;while( p ){if( p == obj.prototype ){return true;}p = p.__proto__;}return false;
}console.log( instanceofs( [1,2,3] , Object ) )

环形链表

环形链表(Circular Linked List)是一种特殊的链表结构,它与普通链表的主要区别在于最后一个节点的指针不再指向 nullNone(在不同编程语言中表示空引用的方式不同),而是指向链表中的某个节点,形成一个闭环。

这种结构可以是 单向环形链表双向环形链表

在环形链表中,如果从头节点开始沿着next指针一直遍历下去,将会无限循环地访问链表的节点,除非有一个机制来中断这个过程。

对于环形链表的操作,比如判断是否有环、找出环的入口点以及计算环长等,常常会用到如下的算法:

判断是否存在环: – 快慢指针

可以使用快慢指针(也称Floyd判圈法)

设置两个指针,一个每次走一步(慢指针),另一个每次走两步(快指针)。如果链表中存在环,则快指针最终将追上慢指针;若不存在环,快指针将先到达终点(NULL)。

找出环的入口点

在确认存在环之后,可以通过以下方法找到环的入口:

当快慢指针相遇时,让其中一个指针保持不动,另一个指针重新回到头节点并以相同的速度前进,再次相遇的位置即为环的入口点。

计算环长

计算环长可以在确定了环的入口点后进行,也可以在快慢指针第一次相遇后,通过令它们按照一定的速度差继续移动,并记录下走过的步数直到再次相遇,所走的步数除以速度差即可得到环的长度。

环形链表的应用场景相对较少但也有其特点,例如在某些同步原语和数据结构实现中可能有用武之地。

关于链表的前端算法题

141. 环形链表

leetcode地址:https://leetcode.cn/problems/linked-list-cycle/description/

给你一个链表的头节点 head ,判断链表中是否有环。

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。

如果链表中存在环 ,则返回 true 。 否则,返回 false 。

示例 1:

输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。 

示例 2:

输入:head = [1,2], pos = 0
输出:true
解释:链表中有一个环,其尾部连接到第一个节点。

示例 3:

输入:head = [1], pos = -1
输出:false
解释:链表中没有环。

提示:

链表中节点的数目范围是 [0, 104]
-105 <= Node.val <= 105
pos 为 -1 或者链表中的一个 有效索引 。

进阶:你能用 O(1)(即,常量)内存解决此问题吗?

js代码实现

/*** Definition for singly-linked list.* function ListNode(val) {*     this.val = val;*     this.next = null;* }*//*** @param {ListNode} head* @return {boolean}*/
var hasCycle = function(head) {let fast = slow = headwhile(fast && fast.next){fast = fast.next.nextslow = slow.nextif(fast === slow){return true}  }return false
};

237. 删除链表中的节点

leetcode地址: https://leetcode.cn/problems/delete-node-in-a-linked-list/description/

有一个单链表的 head,我们想删除它其中的一个节点 node。

给你一个需要删除的节点 node 。你将 无法访问 第一个节点 head。

链表的所有值都是 唯一的,并且保证给定的节点 node 不是链表中的最后一个节点。

删除给定的节点。注意,删除节点并不是指从内存中删除它。这里的意思是:

给定节点的值不应该存在于链表中。
链表中的节点数应该减少 1。
node 前面的所有值顺序相同。
node 后面的所有值顺序相同。

自定义测试:

对于输入,你应该提供整个链表 head 和要给出的节点 node。node 不应该是链表的最后一个节点,而应该是链表中的一个实际节点。
我们将构建链表,并将节点传递给你的函数。
输出将是调用你函数后的整个链表。

示例 1:

输入:head = [4,5,1,9], node = 5
输出:[4,1,9]
解释:指定链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9

示例 2:

输入:head = [4,5,1,9], node = 1
输出:[4,5,9]
解释:指定链表中值为 1 的第三个节点,那么在调用了你的函数之后,该链表应变为 4 -> 5 -> 9

提示:

链表中节点的数目范围是 [2, 1000]
-1000 <= Node.val <= 1000
链表中每个节点的值都是 唯一 的
需要删除的节点 node 是 链表中的节点 ,且 不是末尾节点

分析

比如删掉 b 节点

{val:'a',next:{val:'b',next:{val:'c',next:{val:'d',next:null}}}
}

变成

{val:'a',next:{val:'c',next:{val:'d',next:null}}
}

js 实现源码

/*** Definition for singly-linked list.* function ListNode(val) {*     this.val = val;*     this.next = null;* }*/
/*** @param {ListNode} node* @return {void} Do not return anything, modify node in-place instead.*/
var deleteNode = function(node) {// 原理是覆盖,后一个覆盖前一个node.val = node.next.valnode.next= node.next.next
};

83. 删除排序链表中的重复元素

leetcode地址:https://leetcode.cn/problems/remove-duplicates-from-sorted-list/description/

给定一个已排序的链表的头 head , 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。

示例 1:

输入:head = [1,1,2]
输出:[1,2]  

示例 2:

输入:head = [1,1,2,3,3]
输出:[1,2,3]

提示:

链表中节点数目在范围 [0, 300] 内
-100 <= Node.val <= 100
题目数据保证链表已经按升序 排列

js实现源码

/*** Definition for singly-linked list.* function ListNode(val, next) {*     this.val = (val===undefined ? 0 : val)*     this.next = (next===undefined ? null : next)* }*/
/*** @param {ListNode} head* @return {ListNode}*/
var deleteDuplicates = function(head) {if(!head){return head}// 把当前的定义为一个变量let cur = headwhile(cur.next){// 如果当前值和后面值相同,则整个队列前移if(cur.val == cur.next.val){cur.next = cur.next.next} else {// 当前元素,继续向后移动cur = cur.next}}return head
};

206. 反转链表

leetcode地址:https://leetcode.cn/problems/reverse-linked-list/description/

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

示例 1:

输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]

示例 2:

输入:head = [1,2]
输出:[2,1]

示例 3:

输入:head = []
输出:[]

提示:

链表中节点的数目范围是 [0, 5000]
-5000 <= Node.val <= 5000

进阶:链表可以选用迭代或递归方式完成反转。你能否用两种方法解决这道题?

js实现代码

/*** Definition for singly-linked list.* function ListNode(val, next) {*     this.val = (val===undefined ? 0 : val)*     this.next = (next===undefined ? null : next)* }*/
/*** @param {ListNode} head* @return {ListNode}*/
var reverseList = function (head) {// 定义头部和尾部let prev = nulllet cur = headwhile (cur) {const next = cur.next // 暂存后继节点 cur.nextcur.next = prev //  修改 next 引用指向prev = cur // pre 暂存 curcur = next // cur 访问下一节点}return prev
};

相关文章:

web前端算法简介之链表

链表 链表 VS 数组链表类型链表基本操作 创建链表&#xff1a;插入操作&#xff1a;删除操作&#xff1a;查找操作&#xff1a;显示/打印链表&#xff1a;反转链表&#xff1a;合并两个有序链表&#xff1a;链表基本操作示例 JavaScript中&#xff0c;instanceof环形链表 判断…...

C++函数对象

任何定义了函数调用操作符的对象都是函数对象。C 支持创建、操作新的函数对象&#xff0c;同时也提供了许多内置的函数对象。 函数包装器 std::function 提供存储任意类型函数对象的支持。 function (C11) 包装具有指定函数调用签名的任意类型的可调用对象 (类模板) bad_funct…...

插件化简单介绍

关于作者&#xff1a;CSDN内容合伙人、技术专家&#xff0c; 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 &#xff0c;擅长java后端、移动开发、商业变现、人工智能等&#xff0c;希望大家多多支持。 未经允许不得转载 目录 一、导读二、概览三、常见的插件化方案…...

[Beego]1.Beego简介以及beego环境搭建,bee脚手架的使用,创建,运行项目

一.Beego介绍 Beego是一个开源的基于Golang的MVC框架&#xff0c;主要用于Golang Web开发,Beego可以用来快速开发API、Web、后端服务等各种应用。 Golang 的Web开发框架有很多,从 github star 数量来看Gin>Beego>lris>Echo>Revel>Buffalo 目前国内用的比较多的就…...

Tomcat 静态资源访问与项目根路径设置(AI问答)

一个静态文件&#xff0c;放在Tomcat中&#xff0c;希望能够通过网络访问&#xff0c;应该放在哪里&#xff1f; 在Apache Tomcat中&#xff0c;如果想要部署静态文件&#xff08;例如HTML、CSS、JavaScript、图片等&#xff09;并能通过网络访问&#xff0c;通常需要将这些文…...

Docker实战09|使用AUFS包装busybox

前几篇文章中&#xff0c;重点讲解了如何实现构建容器&#xff0c;需要回顾的小伙伴可以看以下文章&#xff1a; 《Docker实战06&#xff5c;深入剖析Docker Run命令》《Docker实战07&#xff5c;Docker增加容器资源限制》《Docker实战08&#xff5c;Docker管道及环境变量识别…...

什么是uni.request()?如何使用它?

uni.request()是uni-app提供的一个用于发起网络请求的API。 使用uni.request()的步骤如下&#xff1a; 在需要发起网络请求的页面中引入uni.request()方法。 调用uni.request()方法&#xff0c;并传入相应的参数&#xff0c;包括请求地址、请求方法、请求头部和请求数据等。 …...

用React给XXL-JOB开发一个新皮肤(一):环境搭建和项目初始化

目录 一. 简述二. Fork 项目三. 搭建开发环境四. 初始化皮肤项目五. 添加相关依赖六. 预览 一. 简述 大名鼎鼎的 xxl-job 任务调度中心我们应该都使用过&#xff0c;项目地址&#xff1a;xxl-job。它是一个分布式任务调度平台&#xff0c;其核心设计目标是开发迅速、学习简单…...

华为常用的命令——display,记得点赞收藏!

华为设备提供了多条display命令用于查看硬件部件、接口及软件的状态信息。通常这些状态信息可以为用户故障处理提供定位思路。 常用的故障信息搜集的命令如下&#xff1a; 路由器常用维护命令表 交换机常用的故障信息搜集 关注 工 仲 好&#xff1a;IT运维大本营&#xff0c;获…...

Costco攻入山姆大本营

01 Costco深圳店开业火爆 “我今天不去Costco&#xff0c;早上还没开业&#xff0c;路上就已经堵车了&#xff0c;看来今天人很多&#xff0c;过几天再去”&#xff0c;原本计划在Costco开业当天去逛逛的张芸&#xff08;化名&#xff09;无奈只能放弃。 家住在Costco深圳店旁…...

什么是常量?如何区分常量和变量?

一、问题 什么是常量&#xff0c;什么是变量&#xff1f;怎样区分⼆者&#xff1f; 二、解答 1. 常量与变量 &#xff08;1&#xff09;常量即其值在程序运⾏的过程中是不可以改变的&#xff0c;如123&#xff0c;-4567 为数值常量&#xff1b; &#xff08;2&#xff09;变量…...

uniapp返回上一页并刷新数据

在uniapp中&#xff0c;返回页面时onLoad是不会触发的 如果只需要在特定情况下返回上一页才需要刷新数据 可以使用$emit和$no去解决 例如&#xff1a;注册完成后返回到首页并隐藏注册按钮&#xff0c;register.vue和index.vue register.vue <template><view clic…...

LeetCode 0083.删除排序链表中的重复元素:模拟

【LetMeFly】83.删除排序链表中的重复元素&#xff1a;模拟 力扣题目链接&#xff1a;https://leetcode.cn/problems/remove-duplicates-from-sorted-list/ 给定一个已排序的链表的头 head &#xff0c; 删除所有重复的元素&#xff0c;使每个元素只出现一次 。返回 已排序的…...

Javaweb之SpringBootWeb案例新增部门的详细解析

2.3 删除部门 查询部门的功能我们搞定了&#xff0c;下面我们开始完成删除部门的功能开发。 2.3.1 需求 点击部门列表后面操作栏的 "删除" 按钮&#xff0c;就可以删除该部门信息。 此时&#xff0c;前端只需要给服务端传递一个ID参数就可以了。 我们从接口文档中也…...

基于微信小程序的音乐平台 开源项目

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、系统展示 四、核心代码4.1 查询单首音乐4.2 新增音乐4.3 新增音乐订单4.4 查询音乐订单4.5 新增音乐收藏 五、免责说明 一、摘要 1.1 项目介绍 基于微信小程序JAVAVueSpringBootMySQL的音乐平台&#xff0c;包含了音乐…...

uniapp 微信小程序跳转外部链接

一、背景&#xff1a; 开发小程序时&#xff0c;跳转到内部路径通常会使用&#xff1a;uni.navigateTo&#xff0c;uni.redirectTo&#xff0c;uni.reLaunch&#xff0c;uni.switchTab等方法&#xff0c;可以跳转到pages.json中已经注册的页面 uni.navigateTo(OBJECT) | uni-…...

【STM32】FLASH闪存

1 FLASH闪存简介 本节所指STM32内部闪存&#xff0c;即下载程序的时候&#xff0c;程序存储的地方。&#xff08;非易失性&#xff09; STM32F1系列的FLASH包含程序存储器、系统存储器&#xff08;bootloader&#xff0c;不允许修改&#xff09;和选项字节三个部分&#xff0…...

滴水内存地址堆栈

两个十六进制数 刚好是一个字节刚好 DC这的一个字节数据为E4 一个内存地址 后面表示四个字节的数据 所以有八个十六进制的数 BASE是高地址 所以放入一个四字节后就 -4...

Laravel中的lockForUpdate悲观锁

lockForUpdate 是悲观锁&#xff0c;测试就不写了 注意的事项 lockForUpdate 必须在事务中lockForUpdate 被阻塞的查询必须是同样添加了lockForUpdate的语句查询语句走索引&#xff0c;则使用行锁&#xff0c;否则使用表锁 现在举例说明第一项和第二项 开启事务并添加锁 pub…...

BikeDNA(八)外在分析:OSM 与参考数据的比较2

BikeDNA&#xff08;八&#xff09;外在分析&#xff1a;OSM 与参考数据的比较2 1.数据完整性 见链接 2.网络拓扑结构 见链接 3.网络组件 本节仔细研究两个数据集的网络组件特征。 断开连接的组件不共享任何元素&#xff08;节点/边&#xff09;。 换句话说&#xff0c;…...

【杂谈】-递归进化:人工智能的自我改进与监管挑战

递归进化&#xff1a;人工智能的自我改进与监管挑战 文章目录 递归进化&#xff1a;人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管&#xff1f;3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

【力扣数据库知识手册笔记】索引

索引 索引的优缺点 优点1. 通过创建唯一性索引&#xff0c;可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度&#xff08;创建索引的主要原因&#xff09;。3. 可以加速表和表之间的连接&#xff0c;实现数据的参考完整性。4. 可以在查询过程中&#xff0c;…...

Python爬虫(二):爬虫完整流程

爬虫完整流程详解&#xff08;7大核心步骤实战技巧&#xff09; 一、爬虫完整工作流程 以下是爬虫开发的完整流程&#xff0c;我将结合具体技术点和实战经验展开说明&#xff1a; 1. 目标分析与前期准备 网站技术分析&#xff1a; 使用浏览器开发者工具&#xff08;F12&…...

【Go】3、Go语言进阶与依赖管理

前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课&#xff0c;做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程&#xff0c;它的核心机制是 Goroutine 协程、Channel 通道&#xff0c;并基于CSP&#xff08;Communicating Sequential Processes&#xff0…...

如何在网页里填写 PDF 表格?

有时候&#xff0c;你可能希望用户能在你的网站上填写 PDF 表单。然而&#xff0c;这件事并不简单&#xff0c;因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件&#xff0c;但原生并不支持编辑或填写它们。更糟的是&#xff0c;如果你想收集表单数据&#xff…...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!

简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求&#xff0c;并检查收到的响应。它以以下模式之一…...

VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP

编辑-虚拟网络编辑器-更改设置 选择桥接模式&#xff0c;然后找到相应的网卡&#xff08;可以查看自己本机的网络连接&#xff09; windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置&#xff0c;选择刚才配置的桥接模式 静态ip设置&#xff1a; 我用的ubuntu24桌…...

Windows安装Miniconda

一、下载 https://www.anaconda.com/download/success 二、安装 三、配置镜像源 Anaconda/Miniconda pip 配置清华镜像源_anaconda配置清华源-CSDN博客 四、常用操作命令 Anaconda/Miniconda 基本操作命令_miniconda创建环境命令-CSDN博客...

适应性Java用于现代 API:REST、GraphQL 和事件驱动

在快速发展的软件开发领域&#xff0c;REST、GraphQL 和事件驱动架构等新的 API 标准对于构建可扩展、高效的系统至关重要。Java 在现代 API 方面以其在企业应用中的稳定性而闻名&#xff0c;不断适应这些现代范式的需求。随着不断发展的生态系统&#xff0c;Java 在现代 API 方…...

在树莓派上添加音频输入设备的几种方法

在树莓派上添加音频输入设备可以通过以下步骤完成&#xff0c;具体方法取决于设备类型&#xff08;如USB麦克风、3.5mm接口麦克风或HDMI音频输入&#xff09;。以下是详细指南&#xff1a; 1. 连接音频输入设备 USB麦克风/声卡&#xff1a;直接插入树莓派的USB接口。3.5mm麦克…...