函数提升+上下文+内存清理及释放
文章目录
- 函数提升+上下文
- 函数释放
- 拓展-垃圾回收机制
- 垃圾回收之触发应用
函数提升+上下文
-
函数提升(Hoisting)
- 概念:在JavaScript中,函数声明会被提升到当前作用域的顶部。这意味着可以在函数声明之前调用函数。例如:
sayHello(); function sayHello() {console.log("Hello!"); }
- 原理:当JavaScript引擎在执行代码时,会首先扫描整个作用域(例如全局作用域或者函数作用域),找到所有的函数声明,并将它们“提升”到作用域的顶部。但需要注意的是,函数表达式不会提升。例如:
// 这会报错,因为函数表达式不会提升 sayHi(); var sayHi = function() {console.log("Hi!"); };
- 在上面的代码中,
var sayHi
这个变量声明会被提升,但是赋值(也就是函数表达式部分)不会提升。所以在调用sayHi
的时候,它的值是undefined
,调用就会出错。
-
函数执行上下文(Execution Context)
- 概念:执行上下文是JavaScript中一个非常重要的概念,它定义了函数执行时的环境。当一个函数被调用时,就会创建一个新的执行上下文。这个执行上下文包括变量对象(VO)、作用域链和
this
的值。 - 创建阶段:
- 变量对象(VO):在执行上下文的创建阶段,会创建变量对象。对于函数执行上下文,参数会作为变量对象的属性,函数内部声明的变量也会添加到变量对象中。例如:
在function add(num1, num2) {var result;result = num1 + num2;return result; } add(3, 5);
add
函数的执行上下文中,变量对象在创建阶段会有num1
、num2
和result
这几个属性,其中num1
和num2
会被初始化为传入的参数值(3和5),result
会被初始化为undefined
。- 作用域链(Scope Chain):作用域链是由当前执行上下文的变量对象和它外层执行上下文的变量对象组成的一个链表。它用于查找变量的值。例如,在一个嵌套函数中:
在var globalVar = 10; function outer() {var outerVar = 20;function inner() {var innerVar = 30;console.log(globalVar + outerVar + innerVar);}inner(); } outer();
inner
函数的执行上下文中,作用域链首先会查找自己的变量对象中的innerVar
,然后查找outer
函数执行上下文的变量对象中的outerVar
,最后查找全局变量对象中的globalVar
。- this值:
this
的值取决于函数的调用方式。在全局环境中,this
指向window
(在浏览器环境下)。在对象方法中,this
指向调用该方法的对象。例如:
var obj = {name: "John",sayName: function() {console.log(this.name);} }; obj.sayName(); // 输出 "John"
- 执行阶段:在执行阶段,JavaScript引擎会逐行执行函数中的代码,对变量进行赋值操作,执行函数调用等。
- 概念:执行上下文是JavaScript中一个非常重要的概念,它定义了函数执行时的环境。当一个函数被调用时,就会创建一个新的执行上下文。这个执行上下文包括变量对象(VO)、作用域链和
-
函数内部使用的对象
- 函数参数作为对象:函数可以接收对象作为参数,然后在函数内部对这个对象进行操作。例如:
function updateObject(obj) {obj.property = "new value";return obj; } var myObject = {property: "original value" }; var updatedObject = updateObject(myObject); console.log(updatedObject.property); // 输出 "new value"
- 在函数内部创建对象:可以在函数内部使用
new
关键字创建对象(如果是构造函数的话),或者使用对象字面量来创建对象。例如:
function createObject() {var newObject = {name: "New Object",description: "This is a newly created object."};return newObject; } var createdObject = createObject(); console.log(createdObject.name); // 输出 "New Object"
-
监听事件清除释放
- 在DOM中清除事件监听器:在浏览器环境下,当给DOM元素添加事件监听器后,需要在适当的时候清除它,以避免内存泄漏等问题。如果使用
addEventListener
添加事件监听器,可以使用removeEventListener
来清除。例如:
var button = document.getElementById("myButton"); function handleClick() {console.log("Button clicked!"); } button.addEventListener("click", handleClick); // 之后想要清除事件监听器 button.removeEventListener("click", handleClick);
- 注意事项:在使用
removeEventListener
时,传递的函数必须是和添加监听器时完全相同的函数引用。如果是使用匿名函数添加的监听器,想要清除就会比较复杂。例如,下面这种情况就很难正确地清除监听器:
button.addEventListener("click", function() {console.log("Anonymous function click!"); });
- 一种解决方法是将匿名函数赋值给一个变量,然后在
removeEventListener
中使用这个变量:
var anonymousClickHandler = function() {console.log("Anonymous function click!"); }; button.addEventListener("click", anonymousClickHandler); // 清除监听器 button.removeEventListener("click", anonymousClickHandler);
- 在DOM中清除事件监听器:在浏览器环境下,当给DOM元素添加事件监听器后,需要在适当的时候清除它,以避免内存泄漏等问题。如果使用
函数释放
-
JavaScript的内存管理基础
- 在JavaScript中,内存管理主要是由垃圾回收器(Garbage Collector,GC)来自动完成的。垃圾回收器会定期扫描内存,找出那些不再被使用的对象,并释放它们所占用的内存空间。
- 当一个对象没有任何引用指向它时,就会被垃圾回收器认为是“垃圾”,从而被回收。例如,在下面的代码中:
function createObject() {let myObject = {name: "Example"};return myObject; } let newObject = createObject(); // 此时myObject对象仍然被newObject引用,不会被回收 newObject = null; // 现在没有引用指向myObject对象了,它会在下次垃圾回收时被回收
-
函数内部局部变量的释放
- 手动设置为
null
:- 在函数内部,如果有一些比较占用内存的对象,如大型数组、复杂的对象等,可以在函数执行结束前手动将它们设置为
null
。例如:
function processData() {let largeArray = new Array(1000000).fill(0);// 对大型数组进行一些操作...// 操作完成后,手动将其设置为nulllargeArray = null; }
- 当把
largeArray
设置为null
后,就切断了对这个大型数组对象的引用。这样,在下一次垃圾回收时,这个数组对象占用的内存就有更大的机会被回收。不过,需要注意的是,设置为null
并不意味着立即释放内存,只是告诉垃圾回收器这个对象可以被回收了。
- 在函数内部,如果有一些比较占用内存的对象,如大型数组、复杂的对象等,可以在函数执行结束前手动将它们设置为
- 让变量超出作用域:
- 函数内部的局部变量在函数执行结束后会自动超出作用域。例如:
function limitedScope() {let localVariable = "This is a local variable";console.log(localVariable); } limitedScope(); // 在这里,localVariable已经超出了作用域,它所占用的内存会由垃圾回收器来管理
- 当函数
limitedScope
执行完毕后,localVariable
就不再存在于当前的执行上下文中,它所占用的内存会在适当的时候被垃圾回收器回收。但是,如果这个变量所引用的对象还被其他地方(如全局变量或者闭包)引用,那么它不会被回收。
- 手动设置为
-
闭包中的内存释放
- 理解闭包对内存的影响:
- 闭包是指有权访问另一个函数内部变量的函数。当一个函数返回一个闭包时,这个闭包会保留对其外部函数的变量的引用,即使外部函数已经执行完毕。例如:
function outerFunction() {let outerVariable = "I'm from outer function";return function innerFunction() {console.log(outerVariable);}; } let closureFunction = outerFunction(); closureFunction(); // 此时,即使outerFunction已经执行完毕, // outerVariable仍然被closureFunction引用,不会被回收
- 释放闭包中的内存:
- 要释放闭包中引用的内存,可以通过将闭包函数设置为
null
来切断引用。例如:
closureFunction = null; // 现在没有引用指向outerVariable了,它会在下次垃圾回收时被回收
- 另外,如果闭包中的变量是一个比较复杂的对象,也可以在闭包内部手动将其设置为
null
来帮助垃圾回收。
- 要释放闭包中引用的内存,可以通过将闭包函数设置为
- 理解闭包对内存的影响:
-
处理事件监听器和定时器对内存的影响
- 事件监听器:
- 在函数内部添加的事件监听器,如果没有正确移除,会导致内存泄漏。例如,在一个函数中给DOM元素添加了一个点击事件监听器:
function addEventListenerFunction() {let button = document.getElementById("myButton");button.addEventListener("click", function() {console.log("Button clicked");}); } addEventListenerFunction();
- 每次调用这个函数,都会添加一个新的点击事件监听器,但是这些监听器不会自动被移除。要释放内存,需要在合适的时候(如组件卸载或者不再需要监听事件时)使用
removeEventListener
来移除事件监听器。
- 定时器:
- 类似地,在函数内部设置的定时器(如
setTimeout
或setInterval
)也可能会导致内存问题。例如:
function setTimerFunction() {let timerId = setTimeout(function() {console.log("Timer expired");}, 1000); } setTimerFunction();
- 要释放定时器占用的资源,可以使用
clearTimeout
(对于setTimeout
)或者clearInterval
(对于setInterval
)来取消定时器。例如:
function cancelTimerFunction() {let timerId = setTimeout(function() {console.log("Timer expired");}, 1000);clearTimeout(timerId); } cancelTimerFunction();
- 类似地,在函数内部设置的定时器(如
- 事件监听器:
拓展-垃圾回收机制
-
垃圾回收的概念和重要性
- 概念:垃圾回收(Garbage Collection,GC)是一种自动内存管理机制,用于回收程序中不再使用的内存。在JavaScript等高级编程语言中,开发人员不需要手动分配和释放内存来存储对象和数据,垃圾回收器会自动处理这些事情。这大大简化了编程工作,但也需要开发人员理解其基本原理,以避免潜在的内存泄漏等问题。
- 重要性:如果没有垃圾回收机制,随着程序的运行,内存中会积累大量不再被使用的对象,导致内存泄漏。内存泄漏会逐渐耗尽系统的内存资源,最终可能使程序崩溃或者系统运行缓慢。例如,在一个长期运行的Web应用程序中,如果存在内存泄漏,用户在浏览页面时会发现页面越来越卡顿,甚至浏览器可能会因为内存耗尽而无响应。
-
引用计数垃圾回收算法
- 原理:
- 引用计数算法是一种比较简单的垃圾回收算法。它的基本思想是为每个对象维护一个引用计数。当一个对象被创建并赋值给一个变量时,它的引用计数为1;当有新的变量引用这个对象时,引用计数加1;当一个引用该对象的变量不再使用(例如,变量被重新赋值或者超出了作用域),引用计数减1。当一个对象的引用计数为0时,就表示这个对象不再被使用,可以被回收。
- 例如,在下面的代码中:
let a = {name: 'objectA' }; let b = a; // 此时对象a的引用计数为2 a = null; // 引用计数减1,变为1 b = null; // 引用计数变为0,对象a可以被垃圾回收
- 局限性:
- 循环引用问题是引用计数算法的主要缺陷。当两个或多个对象相互引用形成一个循环时,它们的引用计数永远不会为0,即使这些对象从程序的其他部分无法访问。例如:
function createCycle() {let obj1 = {};let obj2 = {};obj1.other = obj2;obj2.other = obj1; } createCycle();
- 在这个例子中,
obj1
和obj2
相互引用,它们的引用计数都为2(自身的引用和对方的引用)。即使createCycle
函数执行完毕,这两个对象在引用计数算法下也不会被回收,从而导致内存泄漏。
- 原理:
-
标记 - 清除垃圾回收算法
- 原理:
- 标记 - 清除算法是现代JavaScript引擎中常用的垃圾回收算法之一。它的基本过程包括两个阶段:标记阶段和清除阶段。
- 在标记阶段,垃圾回收器从一组被称为“根”(roots)的对象开始,这些根对象通常包括全局对象(在浏览器环境中是
window
对象)、当前执行栈中的变量等。然后,沿着对象之间的引用关系进行遍历,标记所有从根对象可达的对象。 - 在清除阶段,垃圾回收器遍历整个堆内存,回收那些没有被标记的对象,即将它们所占用的内存释放掉。例如,在一个简单的JavaScript程序中,假设全局变量
globalObj
引用了一个对象,这个对象又引用了其他对象,垃圾回收器会从globalObj
开始标记所有可达的对象,然后清除那些不可达的对象。
- 与引用计数算法对比:
- 标记 - 清除算法能够很好地解决循环引用的问题。在上面的循环引用示例中,虽然
obj1
和obj2
相互引用,但如果它们无法从根对象到达,那么在标记 - 清除算法下,它们会在清除阶段被回收。 - 不过,标记 - 清除算法也有一些缺点。它在标记和清除过程中需要暂停程序的执行(称为“STW”,Stop - The - World),这可能会导致短暂的性能卡顿。而且,清除后的内存空间是不连续的,可能会产生内存碎片,影响后续内存分配的效率。
- 标记 - 清除算法能够很好地解决循环引用的问题。在上面的循环引用示例中,虽然
- 原理:
-
标记 - 整理垃圾回收算法
- 原理:
- 标记 - 整理算法是在标记 - 清除算法的基础上发展而来的。它同样包括标记阶段,标记从根对象可达的对象。在清除阶段,它不是简单地回收未标记的对象,而是将所有存活的(被标记的)对象向一端移动,然后将剩余的内存空间一次性清理掉。这样就解决了标记 - 清除算法产生内存碎片的问题。
- 性能考虑:
- 标记 - 整理算法虽然解决了内存碎片问题,但在移动对象的过程中也需要消耗更多的时间和资源。因此,不同的JavaScript引擎会根据具体的应用场景和性能需求,选择合适的垃圾回收算法或者结合使用多种算法。例如,V8引擎在新生代(对象刚创建时所处的内存区域)主要使用复制算法(一种特殊的高效的内存回收算法,通过将存活对象复制到新的内存空间来实现回收),在老生代(对象经过一段时间后,从新生代晋升到的内存区域)可能会结合使用标记 - 清除和标记 - 整理算法。
- 原理:
-
分代垃圾回收(以V8引擎为例)
- 新生代和老生代的划分:
- V8引擎将内存分为新生代和老生代两个区域。新生代主要用于存储新创建的对象,通常这些对象的生命周期较短。老生代用于存储经过多次垃圾回收后仍然存活的对象,这些对象的生命周期较长。
- 新生代内存空间相对较小,一般采用更高效的复制算法进行垃圾回收。在复制算法中,新生代内存被划分为两个等大小的区域,称为From空间和To空间。当进行垃圾回收时,将From空间中存活的对象复制到To空间,然后清空From空间,最后将From空间和To空间的角色互换。
- 对象晋升:
- 当一个对象在新生代中经过多次垃圾回收后仍然存活,它会被晋升到老生代。晋升的条件可能包括对象的存活时间达到一定阈值、对象的大小超过一定限制等。老生代的垃圾回收相对复杂,因为其中的对象数量较多且生命周期较长,通常会结合使用标记 - 清除和标记 - 整理算法。
- 新生代和老生代的划分:
垃圾回收之触发应用
-
垃圾回收器运行的情况
- 内存达到一定阈值:
- 不同的JavaScript引擎(如V8引擎等)有自己的内存管理策略。当内存占用达到一定的阈值时,垃圾回收器就会自动启动。这个阈值是由JavaScript引擎内部设定的,目的是平衡性能和内存使用。例如,在浏览器环境中,V8引擎会监控堆内存(用于存储对象等数据)的使用情况。当堆内存的占用接近其容量上限时,垃圾回收器就会被触发,开始清理那些不可达的对象,释放内存空间。
- 程序空闲时段:
- 为了尽量减少垃圾回收对程序性能的影响,JavaScript引擎通常会选择在程序相对空闲的时段运行垃圾回收。比如,当事件循环(Event Loop)中的任务队列暂时为空,没有正在执行的JavaScript代码,且浏览器没有其他高优先级的任务(如页面渲染)时,垃圾回收器就可能会启动。这就像是在打扫房间,选择在房间没人活动的时候进行打扫,以避免干扰正常的活动。
- 全局变量或对象的生命周期结束(理论情况):
- 在一个理想的模型中,如果一个全局变量所引用的对象不再被需要,且这个全局变量被重新赋值或者删除,那么垃圾回收器应该回收这个对象。例如,在一个简单的脚本中:
let globalObject = {property: 'value' }; // 使用globalObject进行一些操作... globalObject = null; // 理论上,此时这个对象应该在之后被垃圾回收
- 不过,在实际情况中,由于JavaScript引擎的复杂性和各种优化策略,即使这样设置为
null
,垃圾回收器也不一定会立即运行,而是会根据上述提到的内存阈值和空闲时间等因素来决定何时运行。
- 内存达到一定阈值:
-
无法主动触发垃圾回收机制(在标准JavaScript中):
- 在标准的JavaScript规范中,没有提供直接触发垃圾回收的方法。这是因为垃圾回收是一个复杂的过程,由JavaScript引擎自动管理,目的是确保内存的高效利用和程序的性能稳定。如果允许随意触发垃圾回收,可能会导致性能问题,例如,频繁地触发垃圾回收可能会打断程序的正常执行,导致程序卡顿。
- 虽然不能直接触发,但可以通过优化代码来间接地影响垃圾回收的效果。例如,及时释放不再使用的对象引用(如将变量设置为
null
),避免创建不必要的全局变量,以及正确地管理闭包等,这些做法可以让垃圾回收器更容易识别出哪些对象是不可达的,从而更高效地回收内存。
相关文章:
函数提升+上下文+内存清理及释放
文章目录 函数提升上下文函数释放拓展-垃圾回收机制垃圾回收之触发应用 函数提升上下文 函数提升(Hoisting) 概念:在JavaScript中,函数声明会被提升到当前作用域的顶部。这意味着可以在函数声明之前调用函数。例如: sa…...
计算机网络之---计算机网络的性能评估
计算机网络的性能评估是指通过各种标准和指标来衡量网络的工作效率和质量,进而对网络进行优化和改进的过程。评估的目标是确保网络能够满足预期的服务质量(QoS)和性能需求。常见的计算机网络性能评估指标包括带宽、延迟、吞吐量、丢包率等。 …...

Unity学习之UGUI进阶
一、事件监听接口 1、作用 用于实现类型长按、双击、拖拽等基础控件无法实现的功能 所有控件都能够添加更多的事件监听来处理对应的逻辑 2、事件监听接口类型 (1)常用事件接口 (2)不常用事件接口 3、使用事件监听接口 &#…...

深度学习领域创新黑马!频域特征融合新突破
最近,FreqFusion引起了广泛关注,这是一种创新的频率感知特征融合方法,可以提升数据处理的准确性和效率,尤其在语义分割、目标检测、实例分割和全景分割等任务中表现卓越。 通过结合频域分析与特征融合技术,FreqFusion…...

路由器的转发表
【4-24】 已知路由器R₁ 的转发表如表T-4-24 所示。 表T-4-24 习题4-24中路由器R₁的转发表 前缀匹配 下一跳地址 路由器接口 140.5.12.64/26 180.15.2.5 m2 130.5.8/24 190.16.6.2 ml 110.71/16 ----- m0 180.15/16 ----- m2 190.16/16 ----- ml 默认 11…...

用Cline打造你的智能搜索助手:Tavily Search MCP集成指南
引言 本文将详细介绍如何在Cline编辑器中集成Tavily Search智能搜索功能。我们将从MCP(Model Context Protocol)协议基础开始,深入探讨Tavily Search MCP服务器的安装配置、使用方法,以及进阶的二次开发技巧。无论你是AI开发者还…...

HTML+CSS+JS制作中华传统美食主题网站(内附源码,含5个页面)
一、作品介绍 HTMLCSSJS制作一个中华传统文化主题网站,包含首页、菜系页、食材页、名厨页、美食故事页等5个静态页面。其中每个页面都包含一个导航栏、一个主要区域和一个底部区域。 二、页面结构 1. 顶部横幅导航区 包含网站Logo、搜索栏、主导航菜单࿰…...

黄仁勋CES 2025演讲重点内容
黄仁勋CES 2025演讲重点内容 硬件产品发布 GeForce RTX 50系列GPU: 架构与性能提升:正式发布的新一代GeForce RTX 50系列GPU采用英伟达旗舰的Blackwell架构,这是自25年前引入可编程着色技术以来计算机图形领域最重大的创新。该系列显卡在图形…...

TVbox 手机、智能电视节目一网打尽
文章目录 一、简要介绍二、优点三、下载地址 一、简要介绍 TVbox是目前最火爆的多端、多源的电视影音工具,是一款开源的自定义添加站源的影音工具。TVBox,支持电视频道直播。一款TV端影视工具,软件本身不具有任何影视资源,但可以…...

sys.dm_exec_connections:查询与 SQL Server 实例建立的连接有关的信息以及每个连接的详细信息(客户端ip)
文章目录 引言I 基于dm_exec_connections查询客户端ip权限物理联接时间范围dm_exec_connections表see also: 监视SQL Server 内存使用量资源信号灯 DMV sys.dm_exec_query_resource_semaphores( 确定查询执行内存的等待)引言 查询历史数据库客户端ip应用场景: 安全分析缺乏…...

kubesphere前端源码运行
一、下载源码 源码是react,下载地址是 GitHub - kubesphere/console at v3.3.2 然后直接用git下拉就可以了 下拉完成后差不多是这样一个目录结构,记得切分支到3.3.2 二、下载依赖 1、node & yurn 想要运行源码首先需要node,使用刚才…...

分布式主键ID生成方式-snowflake雪花算法
这里写自定义目录标题 一、业务场景二、技术选型1、UUID方案2、Leaf方案-美团(基于数据库自增id)3、Snowflake雪花算法方案 总结 一、业务场景 大量的业务数据需要保存到数据库中,原来的单库单表的方式扛不住大数据量、高并发,需…...
深入理解感知机(Perceptron)算法
深入理解感知机(Perceptron)算法 1. 引言 感知机是神经网络和深度学习的基石,由Frank Rosenblatt在1957年提出。它模拟了生物神经元的基本特征,是一个简单但重要的二分类线性分类器。本文将从数学原理到实际应用,全面介绍感知机算法。 2. 数学基础 2.1 定义 感知机是一…...

操作系统——死锁与饥饿
死锁的概念 死锁产生的条件 前三种条件可能会产生死锁,第四种条件(环路)可能会产生死锁 机器检测是否死锁是——检测是否有环路 解决死锁 以上预防死锁的方法不太实用,低效 银行家算法 P2运行完后可用队列就变成了 6 2 3…...

【算法】字符串算法技巧系列
阿华代码,不是逆风,就是我疯 你们的点赞收藏是我前进最大的动力!! 希望本文内容能够帮助到你!! 目录 引入:字符串相关算法技巧 1:字符串转数组 2:子字符串 3ÿ…...

Vue中el-tree结合vuedraggable实现跨组件元素拖拽
实现效果: 左侧el-tree: <template><el-treeclass"filter-tree":data"treeData":props"defaultProps":filter-node-method"filterNode"node-key"id"draggable:allow-drop"allowDrop"node-dr…...

湘潭大学人机交互复习
老师没给题型也没划重点,随便看看复习了 什么是人机交互 人机交互(Human-Computer Interaction,HCI)是关于设计、评价和实现供人们使用的交互式计算机系统,并围绕相关的主要现象进行研究的学科。 人机交互研究内容 …...

基于ADAS 与关键点特征金字塔网络融合的3D LiDAR目标检测原理与算法实现
一、概述 3D LiDAR目标检测是一种在三维空间中识别和定位感兴趣目标的技术。在自动驾驶系统和先进的空间分析中,目标检测方法的不断演进至关重要。3D LiDAR目标检测作为一种变革性的技术,在环境感知方面提供了前所未有的准确性和深度信息. 在这里&…...
Kivy App开发之UX控件DropDown下拉列表
怎样在kivy中实现下拉列表的功能? 在kivy中,下拉列表的定位是自动的,即列表展开的位置根据上下方是否有控件自动调整,且可以包含其他控件,如按钮,图片等。 在应用中,需要使用base包下的runTouchApp类,用于触发下拉框。 DropDown控件常见的属性如下 属性相关说明auto_…...

机器学习模型评估指标
模型的评估指标是衡量一个模型应用于对应任务的契合程度,常见的指标有: 准确率(Accuracy): 正确预测的样本数占总样本数的比例。适用于类别分布均衡的数据集。 精确率(Precision): 在所有被预测为正类的样…...
进程地址空间(比特课总结)
一、进程地址空间 1. 环境变量 1 )⽤户级环境变量与系统级环境变量 全局属性:环境变量具有全局属性,会被⼦进程继承。例如当bash启动⼦进程时,环 境变量会⾃动传递给⼦进程。 本地变量限制:本地变量只在当前进程(ba…...

推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...

使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...
动态 Web 开发技术入门篇
一、HTTP 协议核心 1.1 HTTP 基础 协议全称 :HyperText Transfer Protocol(超文本传输协议) 默认端口 :HTTP 使用 80 端口,HTTPS 使用 443 端口。 请求方法 : GET :用于获取资源,…...

免费PDF转图片工具
免费PDF转图片工具 一款简单易用的PDF转图片工具,可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件,也不需要在线上传文件,保护您的隐私。 工具截图 主要特点 🚀 快速转换:本地转换,无需等待上…...
SpringAI实战:ChatModel智能对话全解
一、引言:Spring AI 与 Chat Model 的核心价值 🚀 在 Java 生态中集成大模型能力,Spring AI 提供了高效的解决方案 🤖。其中 Chat Model 作为核心交互组件,通过标准化接口简化了与大语言模型(LLM࿰…...

Vue3 PC端 UI组件库我更推荐Naive UI
一、Vue3生态现状与UI库选择的重要性 随着Vue3的稳定发布和Composition API的广泛采用,前端开发者面临着UI组件库的重新选择。一个好的UI库不仅能提升开发效率,还能确保项目的长期可维护性。本文将对比三大主流Vue3 UI库(Naive UI、Element …...
Java并发编程实战 Day 11:并发设计模式
【Java并发编程实战 Day 11】并发设计模式 开篇 这是"Java并发编程实战"系列的第11天,今天我们聚焦于并发设计模式。并发设计模式是解决多线程环境下常见问题的经典解决方案,它们不仅提供了优雅的设计思路,还能显著提升系统的性能…...
Neo4j 完全指南:从入门到精通
第1章:Neo4j简介与图数据库基础 1.1 图数据库概述 传统关系型数据库与图数据库的对比图数据库的核心优势图数据库的应用场景 1.2 Neo4j的发展历史 Neo4j的起源与演进Neo4j的版本迭代Neo4j在图数据库领域的地位 1.3 图数据库的基本概念 节点(Node)与关系(Relat…...

第2课 SiC MOSFET与 Si IGBT 静态特性对比
2.1 输出特性对比 2.2 转移特性对比 2.1 输出特性对比 器件的输出特性描述了当温度和栅源电压(栅射电压)为某一具体数值时,漏极电流(集电极电流...