web前端算法简介之链表
- 链表
- 链表 VS 数组
- 链表类型
- 链表基本操作
- 创建链表:
- 插入操作:
- 删除操作:
- 查找操作:
- 显示/打印链表:
- 反转链表:
- 合并两个有序链表:
- 链表基本操作示例
- JavaScript中,instanceof
- 环形链表
- 判断是否存在环: – 快慢指针
- 找出环的入口点:
- 计算环长:
- 关于链表的前端算法题
- 141. 环形链表
- 237. 删除链表中的节点
- 83. 删除排序链表中的重复元素
- 206. 反转链表
链表
Javascript的原型链就是一个链表
链表是一种线性数据结构,它通过 指针(在某些编程语言中可能是引用)将一系列的节点(元素)链接起来。
每个节点除了包含 数据 外,还包含一个指向下一个节点的指针,这样就形成了一个链式存储结构。
链表 VS 数组
相比于数组:
链表在内存中并 不需要是连续的空间,这使得它在插入和删除操作上具有一定的优势,尤其是在大数据量且频繁进行插入、删除操作的场景下。
访问链表中的元素(例如获取第k个节点的数据)通常比数组慢,因为链表需要从头节点开始逐个遍历。
链表和数组是两种基本且重要的数据结构,它们各自有各自的优点和适用场景:
数组:
- 存储方式:数组是在内存中连续存放的一系列元素,每个元素可以通过索引(下标)直接访问。
- 访问速度:由于数组的内存空间是连续的,因此可以使用索引在常量时间内(O(1)复杂度)随机访问任何位置的元素。
- 插入与删除:如果要在数组中间插入或删除元素,通常需要移动后续元素以保持连续性,这可能需要 O(n) 的时间复杂度,尤其是在最坏情况下(例如在数组头部插入或尾部删除时不需要移动其他元素)。
- 空间效率:数组预先分配了固定大小的空间,不灵活但通常比较节省空间,特别是当元素填充率高时。
链表:
- 存储方式:链表中的元素不必连续存储,每个节点包含数据和指向下一个节点的指针。
- 访问速度:链表访问任意元素的时间复杂度通常是线性的 O(n),因为必须从头节点开始逐个遍历到目标节点。
- 插入与删除:链表可以在常量时间内(O(1)复杂度)进行插入和删除操作,只需要改变相应节点的指针即可。特别是在链表头部和尾部进行插入和删除操作时非常高效。
- 空间效率:链表在内存分配上较为灵活,可以根据需要动态添加或删除节点,但相比数组会额外消耗一些存储空间来保存指针信息。
总结来说:
- 如果程序需要频繁的查找操作或者对随机访问性能要求较高,数组是一个更好的选择。
- 当需要频繁执行插入和删除操作,尤其是列表结构变化较大时,链表由于其高效的插入删除特性更为合适。
- 在考虑缓存友好的场景下,数组由于其连续存储的特性更容易利用CPU缓存机制提高访问效率。
链表类型
链表主要分为以下几种类型:
- 单向链表:每个节点只有一个指针指向下一个节点。
- 双向链表:每个节点有两个指针,一个指向前一个节点,另一个指向后一个节点。
- 循环链表:单向或双向链表的最后一个节点的指针指向头节点,形成一个环状结构。
- 静态链表:在数组的基础上模拟实现链表,用数组下标表示前后节点的关系。
链表常用于实现各种高级数据结构,如栈、队列、哈希表等。
链表基本操作
链表的基本操作主要包括以下几种:
创建链表:
- 初始化一个空链表,即创建一个头节点(可能不存储数据,仅作为起点),并将其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.prototype
在 object
的原型链上,则返回 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)是一种特殊的链表结构,它与普通链表的主要区别在于最后一个节点的指针不再指向 null
或 None
(在不同编程语言中表示空引用的方式不同),而是指向链表中的某个节点,形成一个闭环。
这种结构可以是 单向环形链表或 双向环形链表。
在环形链表中,如果从头节点开始沿着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 数组链表类型链表基本操作 创建链表:插入操作:删除操作:查找操作:显示/打印链表:反转链表:合并两个有序链表:链表基本操作示例 JavaScript中,instanceof环形链表 判断…...
C++函数对象
任何定义了函数调用操作符的对象都是函数对象。C 支持创建、操作新的函数对象,同时也提供了许多内置的函数对象。 函数包装器 std::function 提供存储任意类型函数对象的支持。 function (C11) 包装具有指定函数调用签名的任意类型的可调用对象 (类模板) bad_funct…...

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

[Beego]1.Beego简介以及beego环境搭建,bee脚手架的使用,创建,运行项目
一.Beego介绍 Beego是一个开源的基于Golang的MVC框架,主要用于Golang Web开发,Beego可以用来快速开发API、Web、后端服务等各种应用。 Golang 的Web开发框架有很多,从 github star 数量来看Gin>Beego>lris>Echo>Revel>Buffalo 目前国内用的比较多的就…...
Tomcat 静态资源访问与项目根路径设置(AI问答)
一个静态文件,放在Tomcat中,希望能够通过网络访问,应该放在哪里? 在Apache Tomcat中,如果想要部署静态文件(例如HTML、CSS、JavaScript、图片等)并能通过网络访问,通常需要将这些文…...

Docker实战09|使用AUFS包装busybox
前几篇文章中,重点讲解了如何实现构建容器,需要回顾的小伙伴可以看以下文章: 《Docker实战06|深入剖析Docker Run命令》《Docker实战07|Docker增加容器资源限制》《Docker实战08|Docker管道及环境变量识别…...
什么是uni.request()?如何使用它?
uni.request()是uni-app提供的一个用于发起网络请求的API。 使用uni.request()的步骤如下: 在需要发起网络请求的页面中引入uni.request()方法。 调用uni.request()方法,并传入相应的参数,包括请求地址、请求方法、请求头部和请求数据等。 …...

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

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

Costco攻入山姆大本营
01 Costco深圳店开业火爆 “我今天不去Costco,早上还没开业,路上就已经堵车了,看来今天人很多,过几天再去”,原本计划在Costco开业当天去逛逛的张芸(化名)无奈只能放弃。 家住在Costco深圳店旁…...
什么是常量?如何区分常量和变量?
一、问题 什么是常量,什么是变量?怎样区分⼆者? 二、解答 1. 常量与变量 (1)常量即其值在程序运⾏的过程中是不可以改变的,如123,-4567 为数值常量; (2)变量…...
uniapp返回上一页并刷新数据
在uniapp中,返回页面时onLoad是不会触发的 如果只需要在特定情况下返回上一页才需要刷新数据 可以使用$emit和$no去解决 例如:注册完成后返回到首页并隐藏注册按钮,register.vue和index.vue register.vue <template><view clic…...

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

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

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

uniapp 微信小程序跳转外部链接
一、背景: 开发小程序时,跳转到内部路径通常会使用:uni.navigateTo,uni.redirectTo,uni.reLaunch,uni.switchTab等方法,可以跳转到pages.json中已经注册的页面 uni.navigateTo(OBJECT) | uni-…...

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

滴水内存地址堆栈
两个十六进制数 刚好是一个字节刚好 DC这的一个字节数据为E4 一个内存地址 后面表示四个字节的数据 所以有八个十六进制的数 BASE是高地址 所以放入一个四字节后就 -4...
Laravel中的lockForUpdate悲观锁
lockForUpdate 是悲观锁,测试就不写了 注意的事项 lockForUpdate 必须在事务中lockForUpdate 被阻塞的查询必须是同样添加了lockForUpdate的语句查询语句走索引,则使用行锁,否则使用表锁 现在举例说明第一项和第二项 开启事务并添加锁 pub…...

BikeDNA(八)外在分析:OSM 与参考数据的比较2
BikeDNA(八)外在分析:OSM 与参考数据的比较2 1.数据完整性 见链接 2.网络拓扑结构 见链接 3.网络组件 本节仔细研究两个数据集的网络组件特征。 断开连接的组件不共享任何元素(节点/边)。 换句话说,…...
【杂谈】-递归进化:人工智能的自我改进与监管挑战
递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

【力扣数据库知识手册笔记】索引
索引 索引的优缺点 优点1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度(创建索引的主要原因)。3. 可以加速表和表之间的连接,实现数据的参考完整性。4. 可以在查询过程中,…...
Python爬虫(二):爬虫完整流程
爬虫完整流程详解(7大核心步骤实战技巧) 一、爬虫完整工作流程 以下是爬虫开发的完整流程,我将结合具体技术点和实战经验展开说明: 1. 目标分析与前期准备 网站技术分析: 使用浏览器开发者工具(F12&…...
【Go】3、Go语言进阶与依赖管理
前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课,做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程,它的核心机制是 Goroutine 协程、Channel 通道,并基于CSP(Communicating Sequential Processes࿰…...

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

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

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

Windows安装Miniconda
一、下载 https://www.anaconda.com/download/success 二、安装 三、配置镜像源 Anaconda/Miniconda pip 配置清华镜像源_anaconda配置清华源-CSDN博客 四、常用操作命令 Anaconda/Miniconda 基本操作命令_miniconda创建环境命令-CSDN博客...
适应性Java用于现代 API:REST、GraphQL 和事件驱动
在快速发展的软件开发领域,REST、GraphQL 和事件驱动架构等新的 API 标准对于构建可扩展、高效的系统至关重要。Java 在现代 API 方面以其在企业应用中的稳定性而闻名,不断适应这些现代范式的需求。随着不断发展的生态系统,Java 在现代 API 方…...
在树莓派上添加音频输入设备的几种方法
在树莓派上添加音频输入设备可以通过以下步骤完成,具体方法取决于设备类型(如USB麦克风、3.5mm接口麦克风或HDMI音频输入)。以下是详细指南: 1. 连接音频输入设备 USB麦克风/声卡:直接插入树莓派的USB接口。3.5mm麦克…...