agent利用知识来做规划:《KnowAgent: Knowledge-Augmented Planning for LLM-Based Agents》笔记
文章目录
- 简介
- KnowAgent思路
- 准备知识
- Action Knowledge的定义
- Planning Path Generation with Action Knowledge
- Planning Path Refinement via Knowledgeable Self-Learning
- KnowAgent的实验结果
- 总结
- 参考资料
简介
《KnowAgent: Knowledge-Augmented Planning for LLM-Based Agents》是2024年03月出的一篇论文。
论文要解决的问题:LLM与环境交互生成执行动作时的规划幻觉(planning hallucination),即模型会生成不必要的或者冲突的动作序列。如"attempting to look up information without performing a search operation"或"trying to pick an apple from a table without verifying the presence of both the table and the apple"
下图是KnowAgent的概览图。
knowAgent的框架如下图,后面的动图(来自论文GitHub)演示了knowAgent框架的步骤示意。
KnowAgent思路
准备知识
KnowAgent是在ReAct提出的规划轨迹格式的基础上来训练和评估的。
如果用数学语言来定义ReAct,轨迹 τ \tau τ由Thought-Action-Observation三元组( T , A , O \mathcal{T},\mathcal{A},\mathcal{O} T,A,O)表示,其中 T \mathcal{T} T表示agent的想法, A \mathcal{A} A表示可执行动作, O \mathcal{O} O表示从环境获得的反馈信息。
在时刻t的历史轨迹为:
H t = ( T 0 , A 0 , O 0 , T 1 , ⋯ , T t − 1 , A t − 1 , O t − 1 ) \mathcal{H}_t = (\mathcal{T}_0, \mathcal{A}_0, \mathcal{O}_0, \mathcal{T}_1, \cdots,\mathcal{T}_{t-1}, \mathcal{A}_{t-1}, \mathcal{O}_{t-1}) Ht=(T0,A0,O0,T1,⋯,Tt−1,At−1,Ot−1)
基于历史轨迹,agent将生成新的想法和动作。给定参数为 θ \theta θ的模型agent π \pi π,根据历史轨迹生成 T t \mathcal{T}_t Tt可表示为下式,式中的 T t i \mathcal{T}_t^i Tti 和 ∣ T t ∣ |\mathcal{T}_t| ∣Tt∣分别是 T t \mathcal{T}_t Tt的第i个token及长度。
p ( T t ∣ H t ) = ∏ i = 1 ∣ T t ∣ π θ ( T t i ∣ H t , T t < i ) p\left(\mathcal{T}_t \mid \mathcal{H}_t\right)=\prod_{i=1}^{\left|\mathcal{T}_t\right|} \pi_\theta\left(\mathcal{T}_t^i \mid \mathcal{H}_t, \mathcal{T}_t^{<i}\right) p(Tt∣Ht)=i=1∏∣Tt∣πθ(Tti∣Ht,Tt<i)
接着,动作 A t \mathcal{A}_t At将由 T t \mathcal{T}_t Tt和 H t \mathcal{H}_t Ht来决定,式中的 A t j \mathcal{A}_t^j Atj 和 ∣ A t ∣ |\mathcal{A}_t| ∣At∣分别是 A t \mathcal{A}_t At的第j个token及长度:
p ( A t ∣ H t , T t ) = ∏ j = 1 ∣ A t ∣ π θ ( A t j ∣ H t , T t , A t < j ) p\left(\mathcal{A}_t \mid \mathcal{H}_t, \mathcal{T}_t\right)=\prod_{j=1}^{\left|\mathcal{A}_t\right|} \pi_\theta\left(\mathcal{A}_t^j \mid \mathcal{H}_t, \mathcal{T}_t, \mathcal{A}_t^{<j}\right) p(At∣Ht,Tt)=j=1∏∣At∣πθ(Atj∣Ht,Tt,At<j)
最后,动作 A t \mathcal{A}_t At的得到的反馈结果被当做观察 O \mathcal{O} O并添加到轨迹中得到 H t + 1 \mathcal{H}_{t+1} Ht+1。
注:在论文后面将动作集称为 E a E_a Ea,里面的动作 a i a_i ai与 A i \mathcal{A}_i Ai是一样的。
Action Knowledge的定义
动作Action: E a = a 1 , ⋯ , a N − 1 E_a = {a_1, \cdots, a_{N-1}} Ea=a1,⋯,aN−1表示动作集合,LLM为了完成特定任务需要执行的离散动作。
动作规则Action Rules: R = r 1 , ⋯ , r N − 1 \mathcal{R} = {r_1, \cdots, r_{N-1}} R=r1,⋯,rN−1定义了动作转换的逻辑和顺序。 r k : a i → a j r_k: a_i \rightarrow a_j rk:ai→aj 定义了可行的动作转换。
动作知识Action Knowledge:表示为 ( E a , R ) (E_a, \mathcal{R}) (Ea,R),由动作集合 E a E_a Ea和规则集 R \mathcal{R} R组成,不同任务的动作知识构成了动作知识库(Action KB)
提取动作知识的策略:人工构建耗时且费力,所以使用GPT-4进行初始构建后进行人工校正。
Planning Path Generation with Action Knowledge
使用动作知识来规划路径生成的第一步是将动作知识转换成文本(Action knowledge to text),比如Search: (Search, Retrieve, Lookup, Finish), 表示Search后面的动作可以是Search, Retrieve, Lookup, Finish中的任一个。
第二步是根据动作知识来进行路径生成(Path Generation), 作者们设计了一个如上面图片右侧的prompt,prompt由四部分构成:
- 动作知识库的概述来定义基本概念和规则
- 定义每一个动作的含义、操作详情
- 定义规划路径生成的原则,用来约束输出过程
- 提供几个实际规划路径的例子
在HotpotQA上使用的prompt举例(Table 4):
"""
Your task is to answer a question using a specific graph-based method. You must navigate from the "Start" node to the "Finish" node by following the paths outlined in the graph. The correct path is a series of actions that will lead you to the answer.
The decision graph is constructed upon a set of principles known as "Action Knowledge", outlined as follows: Start:(Search, Retrieve)Retrieve:(Retrieve, Search, Lookup, Finish) Search:(Search, Retrieve, Lookup, Finish)Lookup:(Lookup, Search, Retrieve, Finish)Finish:()
Here's how to interpret the graph's Action Knowledge: From "Start", you can initiate with either a "Search" or a "Retrieve" action. At the "Retrieve" node, you have the options to persist with "Retrieve", shift to "Search", experiment with "Lookup", or advance to "Finish". At the "Search" node, you can repeat "Search", switch to "Retrieve" or "Lookup", or proceed to "Finish". At the "Lookup" node, you have the choice to keep using "Lookup", switch to "Search" or "Retrieve", or complete the task by going to "Finish". The "Finish" node is the final action where you provide the answer and the task is completed. Each node action is defined as follows: (1) Retrieve[entity]: Retrieve the exact entity on Wikipedia and return the first paragraph if it exists. If not, return some similar entities for searching. (2) Search[topic]: Use Bing Search to find relevant information on a specified topic, question, or term.(3) Lookup[keyword]: Return the next sentence that contains the keyword in the last passage successfully found by Search or Retrieve. (4) Finish[answer]: Return the answer and conclude the task.
As you solve the question using the above graph structure, interleave ActionPath, Thought, Action, and Observation steps. ActionPath documents the sequence of nodes you have traversed within the graph. Thought analyzes the current node to reveal potential next steps and reasons for the current situation.
You may take as many steps as necessary.
Here are some examples:
{examples}
(END OF EXAMPLES)
Question: {question}{scratchpad}"""
论文在ALFWorld 上执行Pick任务使用的prompt举例(Table 5):
"""
Interact with a household to solve a task by following the structured "Action Knowledge". The guidelines are:
Goto(receptacle) -> Open(receptacle)
[Goto(receptacle), Open(receptacle)] -> Take(object, from: receptacle)
Take(object, from: receptacle) -> Goto(receptacle)
[Goto(receptacle), Take(object, from: receptacle)] -> Put(object, in/on: receptacle) Here's how to interpret the Action Knowledge:
Before you open a receptacle, you must first go to it. This rule applies when the receptacle is closed. To take an object from a receptacle, you either need to be at the receptacle's location, or if it's closed, you need to open it first.
Before you go to the new receptacle where the object is to be placed, you should take it. Putting an object in or on a receptacle can follow either going to the location of the receptacle or after taking an object with you.The actions are as follows:
1) go to receptacle
2) take object from receptacle
3) put object in/on receptacle
4) open receptacleAs you tackle the question with Action Knowledge, utilize both the ActionPath and Think steps. ActionPath records the series of actions you've taken, and the Think step understands the current situation and guides your next moves.
Here are two examples.
{examples}
Here is the task.
"""
路径(path)和轨迹(trajectory)的区别如下:
-
路径是指agent采取的一系列动作
-
轨迹包括模型在解决问题过程中的完整输出,所以路径是轨迹的一部分。
如果像在准备知识一样用数学语言来定义knowAgent,轨迹 τ \tau τ由四元组( P , T , A , O \mathcal{P},\mathcal{T},\mathcal{A},\mathcal{O} P,T,A,O)表示,其中 P \mathcal{P} P表示动作路径, T \mathcal{T} T表示agent的想法, A \mathcal{A} A表示可执行动作, O \mathcal{O} O表示从环境获得的反馈信息。在时刻t的历史轨迹为:
H t = ( P 0 , T 0 , A 0 , O 0 , ⋯ , P t − 1 , T t − 1 , A t − 1 , O t − 1 ) \mathcal{H}_t = (\mathcal{P}_0,\mathcal{T}_0, \mathcal{A}_0, \mathcal{O}_0, \cdots,\mathcal{P}_{t-1},\mathcal{T}_{t-1}, \mathcal{A}_{t-1}, \mathcal{O}_{t-1}) Ht=(P0,T0,A0,O0,⋯,Pt−1,Tt−1,At−1,Ot−1)
基于历史轨迹,agent将生成新的动作路径、想法和动作。给定参数为 θ \theta θ的模型agent π \pi π,根据历史轨迹生成接下来的动作路径 P t \mathcal{P}_t Pt可表示为下式,式中的 P t k \mathcal{P}_t^k Ptk 和 ∣ P t ∣ |\mathcal{P}_t| ∣Pt∣分别是 P t \mathcal{P}_t Pt的第k个token及长度。
p ( P t ∣ H t ) = ∏ k = 1 ∣ P t ∣ π θ ( P t k ∣ H t , P t < k ) p\left(\mathcal{P}_t \mid \mathcal{H}_t\right)=\prod_{k=1}^{\left|\mathcal{P}_t\right|} \pi_\theta\left(\mathcal{P}_t^k \mid \mathcal{H}_t, \mathcal{P}_t^{<k}\right) p(Pt∣Ht)=k=1∏∣Pt∣πθ(Ptk∣Ht,Pt<k)
与前面准备知识中提到的React思路一样,后续想法和动作的生成可以表示为下面的式子:
p ( T t ∣ H t , P t ) = ∏ i = 1 ∣ T t ∣ π θ ( T t i ∣ H t , P t , T t < i ) p ( A t ∣ H t , P t , T t ) = ∏ j = 1 ∣ A t ∣ π θ ( A t j ∣ H t , P t , T t , A t < j ) p\left(\mathcal{T}_t \mid \mathcal{H}_t, \mathcal{P}_t\right)=\prod_{i=1}^{\left|\mathcal{T}_t\right|} \pi_\theta\left(\mathcal{T}_t^i \mid \mathcal{H}_t, \mathcal{P}_t, \mathcal{T}_t^{<i}\right) \\ p\left(\mathcal{A}_t \mid \mathcal{H}_t, \mathcal{P}_t, \mathcal{T}_t\right)=\prod_{j=1}^{\left|\mathcal{A}_t\right|} \pi_\theta\left(\mathcal{A}_t^j \mid \mathcal{H}_t,\mathcal{P}_t, \mathcal{T}_t, \mathcal{A}_t^{<j}\right) p(Tt∣Ht,Pt)=i=1∏∣Tt∣πθ(Tti∣Ht,Pt,Tt<i)p(At∣Ht,Pt,Tt)=j=1∏∣At∣πθ(Atj∣Ht,Pt,Tt,At<j)
Planning Path Refinement via Knowledgeable Self-Learning
Knowledgeable Self-Learning的目标是通过迭代微调使得模型更好的理解动作知识,其算法如下图所示:
具体来说,算法过程如下:
-
Knowledgeable Self-Learning的输入为初始训练集 D 0 D_0 D0、动作知识 A K m AK_m AKm、未训练模型 M 0 M_0 M0,由模型生成初始轨迹集合 T 0 = { τ 1 , τ 2 , ⋯ , τ n } T_0=\{\tau_1, \tau_2, \cdots, \tau_n\} T0={τ1,τ2,⋯,τn},将 T 0 T_0 T0过滤后微调模型 M 0 M_0 M0后得到模型 M 1 M_1 M1。
-
模型 M 1 M_1 M1在 D 0 D_0 D0上评估得到新的轨迹集合 T 1 = { τ 1 ′ , τ 2 ′ , ⋯ , τ n ′ } T_1=\{\tau_1^{\prime}, \tau_2^{\prime}, \cdots, \tau_n^{\prime}\} T1={τ1′,τ2′,⋯,τn′}, 将 T 1 T_1 T1与 T 0 T_0 T0经过滤和合并(merging)操作后用来微调模型 M 1 M_1 M1后得到模型 M 2 M_2 M2。
-
一直重复第二步直到模型在测试集 D t e s t D_{test} Dtest上的提升变得非常小。
其中,
- 过滤Filtering:先根据生成结果选择正确的轨迹 T c o r r e c t T_{correct} Tcorrect,然后根据动作知识库 A K m AK_m AKm来去掉未与其对齐的轨迹,主要是invalid动作和misordered的动作序列。
- invalid动作是指不符合动作规则的动作
- misordered序列是指动作的逻辑顺序与动作知识库不一样
- 合并merging:合并不同迭代轮次里的轨迹,对于解决同一任务的多条轨迹,保留更高效(更短)的轨迹。
KnowAgent的实验结果
在HotpotQA和ALFWorld上来评估KnowAgent,使用Llama2-{7,13,70}b-chat模型作为基础模型,同时测试了Vicuna和Mistral模型的效果。
与KnowAgent比较的基准有:CoT、ReAct、Reflexion、FiReAct。结果如下图
错误分析:knowagent难以有效蒸馏关键信息,经常无法给出准确回复。主要原因在于处理长上下文窗口时推理能力和记忆能力的不足。
总结
knowAgent在ReAct的基础上新增了路径(path)概念,通过构建一个动作知识库来指导agent更好的规划任务,减少规划幻觉(planning hallucination)。个人觉得动作知识库的引入与RAG减少幻觉的思路是类似的,knowAgent复杂的prompt也是方法不可忽视的一点。
knowAgent另一个很重要的思路是自学习,使用迭代的思路不断微调模型使模型更好的理解动作知识。
论文中的几个数学公式主要是用来表示生成过程的,即使不理解公式也没有关系,个人觉得即使论文中不添加那些公式表示也不影响思路的完整性。
参考资料
- Zhu, Yuqi, Shuofei Qiao, Yixin Ou, Shumin Deng, Ningyu Zhang, Shiwei Lyu, Yue Shen, et al. n.d. “KnowAgent: Knowledge-Augmented Planning for LLM-Based Agents.”
- KnowAgent github
相关文章:

agent利用知识来做规划:《KnowAgent: Knowledge-Augmented Planning for LLM-Based Agents》笔记
文章目录 简介KnowAgent思路准备知识Action Knowledge的定义Planning Path Generation with Action KnowledgePlanning Path Refinement via Knowledgeable Self-LearningKnowAgent的实验结果 总结参考资料 简介 《KnowAgent: Knowledge-Augmented Planning for LLM-Based Age…...

01 React新建开发环境
https://create-react-app.dev/docs/getting-started npx create-react-app my-appJSX使用表达式嵌入 function App() {const count 100;function getSelfName() {return "SelfName"}return (<div>Hello World!<div>{This is Javascript message~!}&l…...

nginx--解决响应头带Set-Cookie导致的验证失败
解决响应头带Set-Cookie导致的验证失败 前言给nginx.conf 设置Secure配置完成后会发现cookie就不会发生变化了 前言 在用nginx做代理的时候,会发现nginx在访问不同ip请求的时候会带setCookie 导致后端就是放开cookie验证,在访问玩这个链接他更新了cooki…...

InstructGPT的流程介绍
1. Step1:SFT,Supervised Fine-Tuning,有监督微调。顾名思义,它是在有监督(有标注)数据上微调训练得到的。这里的监督数据其实就是输入Prompt,输出相应的回复,只不过这里的回复是人工…...

docker容器下部署hbase并在springboot中通过jdbc连接
我在windows的docker中部署了一个hbase服务,然后用springboot连接到此服务并访问数据。 详情可参考项目中的README.md。项目中提供了用于构建镜像的dockerfile,以及测试代码。 项目连接: https://gitee.com/forgot940629/hbase_phoenix_sprin…...

Qt——智能指针实战
目录 前言正文一、理论介绍1、QPointer2、QScopedPoint3、QSharedPoint4、QWeakPoint 二、实战演练1、QPoint2、QScopedPoint3、QSharedPointa、示例一b、示例二 4、QWeakPoint END、总结的知识与问题 参考 前言 智能指针的使用,对很多程序员来说,都算是…...

Unity Mobile Notifications推送问题
1.在部分机型点击通知弹窗进不去游戏 把这里改成自己的Activity 2.推送的时候没有横幅跟icon红点 主要是第一句话 注册的时候选项可以选择 defaultNotificationChannel new AndroidNotificationChannel(“default_channel”, “Default Channel”, “For Generic notifica…...

C++_回文串
目录 回文子串 最长回文子串 分割回文串 IV 分割回文串 II 最长回文子序列 让字符串成为回文串的最少插入次数 回文子串 647. 回文子串 思路,i j表示改范围内是否为回文串, ②倒着遍历是为了取出dp[i 1][j - 1] ③i j 只有一对,不会重复…...

【阅读论文】When Large Language Models Meet Vector Databases: A Survey
摘要 本调查探讨了大型语言模型(LLM)和向量数据库(VecDB)之间的协同潜力,这是一个新兴但迅速发展的研究领域。随着LLM的广泛应用,出现了许多挑战,包括产生虚构内容、知识过时、商业应用成本高昂…...

兼职副业大揭秘:六个潜力满满的赚钱途径
亲爱的朋友,你对兼职副业充满好奇与期待,这非常好!在此,我将为你分享一些能够助你赚取额外收入的兼职副业建议。以下是六个颇具潜力的兼职副业方向,希望能为你的探索之路提供些许启发。 1,网络调查与市场洞…...

C++ Qt开发:QUdpSocket实现组播通信
Qt 是一个跨平台C图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍如何运用QUdpSocket组件实现基于UDP的组播通信…...

excel 表中有图片并在筛选特定行时,只显示该行的图片
建议:选中excel 表中某张图片,CtrlA,选中所有图片。再右键,在菜单中选设置对象格式 在属性里按下图设置, 生效之后,筛选某个产品的时候,就不会显示其他的不符合筛选条件的产品的图片了。...

【QA】MySQL多表查询详解
文章目录 前言关系型数据库中数据表之间的关系数据准备数据内容表间关系 基础查询 | 全部查询多表查询分类1 | 连接查询内连接外连接 | 左外连接外连接 | 右外连接自连接 | 自连接自连接 | 联合查询 分类2 | 子查询返回结果分类 | 标量子查询返回结果分类 | 列子查询返回结果分…...

【Entity Framework】 EF三种开发模式
【Entity Framework】 EF三种开发模式 文章目录 【Entity Framework】 EF三种开发模式一、概述二、DataBase First2.1 DataBase First简介2.2 DataBase First应用步骤2.3 DataBase First总结 三、Model First3.1 Model First简介3.2 Model First实现步骤 四、Code First4.1 Cod…...

数据分析---SQL(5)
目录 子查询单行子查询多行子查询视图(View)创建视图使用视图更新视图视图的优缺点存储过程存储过程的创建存储过程的参数存储过程的优缺点可能导致性能问题避免存储过程引入性能问题子查询 子查询是指在一个查询语句中嵌套另一个查询语句,内部的查询语句称为子查询,外部的…...

《剑指 Offer》专项突破版 - 面试题 93 : 最长斐波那契数列(C++ 实现)
题目链接:最长斐波那契数列 题目: 输入一个没有重复数字的单调递增的数组,数组中至少有 3 个数字,请问数组中最长的斐波那契数列的长度是多少?例如,如果输入的数组是 [1, 2, 3, 4, 5, 6, 7, 8]࿰…...

代码随想录算法训练营第五十五天|583. 两个字符串的删除操作、72. 编辑距离
583. 两个字符串的删除操作 刷题https://leetcode.cn/problems/delete-operation-for-two-strings/description/文章讲解https://programmercarl.com/0583.%E4%B8%A4%E4%B8%AA%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%9A%84%E5%88%A0%E9%99%A4%E6%93%8D%E4%BD%9C.html视频讲解https://…...

StringRedisTemplate Autowired注入为空解决
如下注入方式报空指针异常: java.lang.NullPointerException: null Autowiredprivate StringRedisTemplate redisTemplate; 解决办法:查看该类上有没有加注解,如Component等,没加的话加上。 还有一种是在工具类中使用,…...

c语言:文件操作
1. 为什么使⽤⽂件? 如果没有⽂件,我们写的程序的数据是存储在电脑的内存中,如果程序退出,内存回收,数据就丢失 了,等再次运⾏程序,是看不到上次程序的数据的,如果要将数据进⾏持久…...

C#事件实例详解
一、什么是事件? 在C#中,事件(event)是一种特殊的类成员,它允许类或对象通知其他类或对象发生了某些事情。 从语法上看,事件的声明类似于字段,但它们在功能和行为上有一些重要的区别。 从技术角度来说,事件实际上是一个封装了事件订阅和取消订阅功能的委托字段。…...

零基础机器学习(3)之机器学习的一般过程
文章目录 一、机器学习一般过程1.数据获取2.特征提取3.数据预处理①去除唯一属性②缺失值处理A. 均值插补法B. 同类均值插补法 ③重复值处理④异常值⑤数据定量化 4.数据标准化①min-max标准化(归一化)②z-score标准化(规范化) 5.…...

用java做一个双色球彩票系统
代码如下: import java.util.Random; public class HelloWorld{public static void main(String[] args){//1、生成中奖号码 int[] arrcreateNumber();for (int i 0;i<arr.length;i) {System.out.print(arr[i]" ");}}public static int[] createNu…...

某对象存储元数据集群改造流水账
软件产品:某厂商提供的不便具名的对象存储产品,核心底层技术源自HDFS和Amazon S3,元数据集群采用了基于MongoDB的NOSQL数据库产品和MySQL数据库产品相结合。 该产品的元数据逻辑示意图如下: 业务集群现状:当前第3期建…...

前端理论总结(js)——filter、foearch、for in 、for of 、for的区别以及返回值
Filter: 用途:用于筛选数组中符合条件的元素,返回一个新数组。 返回值:返回一个新数组,包含经过筛选的元素。 Foreach: 用途:遍历数组中的每个元素,执行回调函数。 返回值&#x…...

【JavaEE初阶系列】——多线程案例一——单例模式 (“饿汉模式“和“懒汉模式“以及解决线程安全问题)
目录 🚩单例模式 🎈饿汉模式 🎈懒汉模式 ❗线程安全问题 📝加锁 📝执行效率提高 📝指令重排序 🍭总结 单例模式,非常经典的设计模式,也是一个重要的学科&#x…...

革新水库大坝监测:传统软件与云平台之比较
在水库大坝的监测管理领域,传统监测软件虽然曾发挥了重要作用,但在多方面显示出了其局限性。传统解决方案通常伴随着高昂的运维成本,需要大量的硬件支持和人员维护,且软件整合和升级困难,限制了其灵活性和扩展性。 点击…...

C++模版(基础)
目录 C泛型编程思想 C模版 模版介绍 模版使用 函数模版 函数模版基础语法 函数模版原理 函数模版实例化 模版参数匹配规则 类模版 类模版基础语法 C泛型编程思想 泛型编程:编写与类型无关的通用代码,是代码复用的一种手段。 模板是泛型编程…...

MySQL驱动Add Batch优化实现
MySQL 驱动 Add Batch 优化实现 MySQL 驱动会在 JDBC URL 添加 rewriteBatchedStatements 参数时,对 batch 操作进行优化。本文测试各种参数组合的行为,并结合驱动代码简单分析。 batch参数组合行为 useServerPrepStmts 参数 PreparedStatement psmt…...

手撕算法-数组中的第K个最大元素
描述 分析 使用小根堆,堆元素控制在k个,遍历数组构建堆,最后堆顶就是第K个最大的元素。 代码 class Solution {public int findKthLargest(int[] nums, int k) {// 小根堆PriorityQueue<Integer> queue new PriorityQueue<>…...

【vue】computed和watch的区别和应用场景
Computed 和 Watch 是 Vue.js 中用于监视数据变化的两个不同特性,它们各自有不同的应用场景和功能。 Computed: 计算属性(Computed properties)用于声明基于其他数据属性的计算值。它具有缓存功能,只有在依赖的数…...