音视频学习笔记——设计模式

✊✊✊🌈大家好!本篇文章主要记录自己在进行音视频学习中,整理的包括单例模式、工厂模式、策略模式、观察者模式等6种相关的设计模式和4种准则的内容重点😇。

音视频学习笔记——设计模式


本专栏知识点是通过<零声教育>的音视频流媒体高级开发课程进行系统学习,按照学习重点梳理总结后写下文章,对音视频相关内容感兴趣的读者,可以点击观看课程网址:零声教育


🎡导航小助手🎡

  • 音视频学习笔记——设计模式
    • 1.单例模式
    • 2.简单工厂模式
    • 3.策略模式
    • 4.观察者模式
    • 5.组合模式
    • 6.责任链模式
    • 7. 四个准则
      • 单一职责原则
      • 开放――封闭原则
      • 里氏代换原则
      • 依赖倒转原则
    • 8.总结

1.单例模式

保证一个类仅有一个实例,并提供一个访问它的全局访问点

让类自身负责保护它的唯一实例,这个类可以保证没有其他实例可以被创建,并且他可以提供一个访问该实例的方法。
单例模式结构图
Singelton类,定义GetSingel操作,允许客户访问它的唯一实例。
GetSingel为静态方法,主要负责创建自己的唯一实例。

  • 优点:Singleton类封装它的唯一实例,这样可以严格控制客户怎样访问它以及何时访问它。简单来说,对唯一实例的受控访问。

示例代码:

	#include <iostream>
	#include <string>
	#include <vector>
	using namespace std;
	class Singelton{
	private:
		Singelton(){} //构造方法令其私有,堵死外界利用new创建此类实例的可能
		static Singelton* singel; 
	public:
		static Singelton* GetSingel(){//此方法是获得本类实例的唯一全局访问点
			if(singel == NULL){  //若实例不存在,new一个实例,否则返回已有实例
				singel = new Singelton();
			}
			return singel;
		}
	};
	Singelton* Singelton::singel = NULL;//注意静态变量类外初始化

客户端:

	int main(){
		Singelton* s1=Singelton::GetSingel();
		Singelton* s2=Singelton::GetSingel();
		if(s1 == s2)//两次实例化后对象结果是,实力相同,返回ok
			cout<<"ok"<<endl;
		else
			cout<<"no"<<endl;
		return 0;
	}

2.简单工厂模式

主要用于创建对象。新添加类时,不影响以前的系统代码。
核心思想:用一个工厂来根据输入的条件产生不同的类,然后根据不同类的virtual函数得到不同的结果。

注意:面向对象的编程,并不是类越多越好,类的划分是为了封装,但分类的基础是抽象,具有相同属性和功能的对象的抽象集合才是类。

在这里插入图片描述

  • 优点: 适应于不同情况创建不同的类时,容易维护、扩展、复用
  • 不足:客户端必须要知道基类和工厂类,耦合性差

活字印刷:

  1. 可维护:要改,只需改要改之字
  2. 可复用:用完之后,可以在之后的印刷中重复使用
  3. 可扩展:若要加字,只需另刻字
  4. 灵活性好:将活字移动就可满足各种排列需求

示例代码:

	//基类
	class COperation{
	public:
		int m_nFirst;
		int m_nSecond;
		virtual double GetResult(){
			double dResult=0;
			return dResult;
		}
	};
	//加法类,继承基类
	class AddOperation : public COperation{
	public:
		virtual double GetResult(){
			return m_nFirst+m_nSecond;
		}
	};
	//减法类,继承基类
	class SubOperation : public COperation{
	public:
		virtual double GetResult(){
		return m_nFirst-m_nSecond;
		}
	};
	
	//工厂类
	class CCalculatorFactory{
	public:
		static COperation* Create(char cOperator);
	};
	
	COperation* CCalculatorFactory::Create(char cOperator)
	{
		COperation *oper = NULL;
		//在 C# 中可以用反射来取消判断时用的 switch ,在 C++ 中用什么呢? RTTI
		switch (cOperator){
		case '+':
			oper=new AddOperation();
			break;
		case '-':
			oper=new SubOperation();
			break;
		default:
			oper=new AddOperation();
			break;
		}
		return oper;
	}

客户端:

	int main()
	{
		int a,b;
		cin>>a>>b;
		COperation * op=CCalculatorFactory::Create('-');
		op->m_nFirst=a;
		op->m_nSecond=b;
		cout<<op->GetResult()<<endl;
		return 0;
	}

3.策略模式

定义算法家族,分别封装起来,让它们之间可以互相替换,让算法变化,不会影响到用户
例如商城收银时如何促销,用打折还是返利,其实都是一些算法,用工厂来生成算法对象,并没有错,但算法本身只是一种策略,最重要的时这些算法是随时都可能互相替代的,这就是变化点,封装变化点就是策略模式的重点。
在这里插入图片描述

  • 优点:适合类中的成员以方法为主,算法经常变动;简化了单元测试(因为每个算法都有自己的类,可以通过自己的接口单独测试。
    • 策略模式和简单工厂基本相同,但简单工厂模式只能解决对象创建问题,对于经常变动的算法应使用策略模式。
  • 不足:客户端要做出判断

简单工厂模式只是解决对象的创建问题,每次维护或者扩展都需要改动工厂,以至于代码需要重新编译部署,面对算法的市场变动,简单工厂模式不是最好的办法,这时就需要采用策略模式。

示例代码:

	//策略基类
	class COperation{
	public:
		int m_nFirst;
		int m_nSecond;
		virtual double GetResult(){
			double dResult=0;
			return dResult;
		}
	};
	//AddOperation,封装了具体的算法或者行为,继承于COperation
	//策略具体类—加法类
	class AddOperation : public COperation{
	public:
		AddOperation(int a,int b){
			m_nFirst=a;
			m_nSecond=b;
		}
		virtual double GetResult(){
			return m_n First+m_nSecond;
		}
	};
	//策略具体类—减法类
	class SubOperation : public COperation{
	public:
		AddOperation(int a,int b){
			m_nFirst=a;
			m_nSecond=b;
		}
		virtual double GetResult(){
			return m_n First-m_nSecond;
		}
	};
	//Context,用Operation来进行配置,维护对temp对象的引用。
	class Context{
	private:
		COperation* op;//
	public:
		Context(COperation* temp){
			op=temp;
		}
		double GetResult(){
			return op->GetResult();
		}
	};

客户端:

	int main(){
		int a,b;
		char c;
		cin>>a>>b;
		cout<< 请输入运算符:
		cin>>c;
		switch(c){
			case '+':
				Context * context =new Context(new AddOperation(a,b));
				cout<< context->GetResult()<<endl;
				break;
			case '-':
				Context * context =new Context(new SubOperation(a,b));
				cout<< context->GetResult()<<endl;
				break;
			default:
				break;
		}
		return 0;
	}

策略和工厂结合
优点:客户端只需访问Context类,而不用知道其他任何类信息,实现了低耦合。
将上例的Context类和main函数进行如下修改:
示例代码:

	class Context{
	private:
		COperation* op = NULL;//声明一个op对象
	public:
		Context(char cType){ //参数一个字符,表示具体算法
			switch (cType){
				case '+':
					op=new AddOperation(3,8);
					break;
				case '-':
					op=new SubOperation(5,2);
					break;
				default:
					op=new AddOperation();
					break;
			}
		}//将实例化具体策略的过程由客户端转移到Context中,简单工厂的应用
		double GetResult(){
			return op->GetResult();
		}
	};

	int main(){

		char c;
		cin>>c;
		Context *test=new Context(c);//将输入字符'c'传给Context的对象中
		cout<<test->GetResult()<<endl;
		return 0;
	}

简单工厂和策略工厂客户端代码对比(重点)
简单工厂模式需要让客户端认识多个类;
策略模式与简单工厂模式结合,客户端只需要认识一个Context类就可,耦合降低。

4.观察者模式

观察者模式又叫做发布-订阅(Publish/Sub)模式
定义了一种一对多的关系,让多个观察对象(公司员工)同时监听一个主题对象(秘书),主题对象状态发生变化时,会通知所有的观察者,使它们能够更新自己。
在这里插入图片描述
示例代码:

	#include <string>
	#include <iostream>
	#include <vector>
	using namespace std;
	class Secretary;
	//看股票的同事类(观察对象,观察者)
	class StockObserver{
	private:
		string name;
		Secretary* sub;
	public:
		StockObserver(string strname,Secretary* strsub){
			name=strname;
			sub=strsub;
		}
		void Update();
	};
	//秘书类(主题对象,通知者)
	class Secretary{
	private:
		//同事列表
		vector<StockObserver> observers;
	public:
		string action;
		//请前台帮忙的同事,都需要添加进集合
		void Add(StockObserver ob){
		observers.push_back(ob);
		}
		//通知
		void Notify(){
			vector<StockObserver>::iterator p = observers.begin();
			while (p!=observers.end()){
				(*p).Update();
				p++;
			};
		void StockObserver::Update(){
			cout<<name<<":"<<sub->action<< "不要玩股票了,要开始工作了"<<end;
		}
	}

客户端:

	int main(){
		Secretary *p=new Secretary(); // 创建通知者
		//观察者
		StockObserver *s1= new StockObserver("小李",p);
		StockObserver *s2 = new StockObserver("小赵",p);
		//加入通知队列
		p->Add(*s1);
		p->Add(*s2);
		//事件
		p->action="老板来了";
		//通知
		p->Notify();
		return 0;
	}

在这里插入图片描述

CObserverBase类,抽象观察者,为所有具体观察者定义了一个接口,在得到主题的通知时更新自己。这个接口叫做更新接口。
抽象观察者一般用一个抽象类或者一个接口实现,更新接口通常包含一个Update()方法,这个方法叫做更新方法。

	#include <string>
	#include <iostream>
	#include <vector>
	using namespace std;
	class SecretaryBase;
	//抽象观察者
	class CObserverBase{
	protected:
		string name;
		SecretaryBase* sub;
	public:
		CObserverBase(string strname,SecretaryBase* strsub){
			name=strname;
			sub=strsub;
		}
		virtual void Update()=0;
	};

StockObserver类,具体观察者,实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态相协调。具体观察者角色可以保存一个指向具体主题对象的引用。具体观察者角色通常用一个具体子类实现。

	//具体的观察者,看股票的
	class StockObserver : public CObserverBase{
	public:
		StockObserver(string strname,SecretaryBase* strsub):CObserverBase(strname,strsub){
		}
		virtual void Update();
	};
	//具体观察者,看 NBA 的
	class NBAObserver : public CObserverBase{
	public:
		NBAObserver(string strname,SecretaryBase* strsub):CObserverBase(strname,strsub){
		}
		virtual void Update();
	};

SecretaryBase类,可翻译为主题或抽象通知者,一般用一个抽象类或一个接口实现。它把所有观察者对象的引用保存在一个集合里,每个主题都能有任意数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象。

	//抽象通知者
	class SecretaryBase{
	public:
		string action;
		vector<CObserverBase*> observers;
	public:
		virtual void Attach(CObserverBase* observer)=0;
		virtual void Notify()=0;
	};

Secretary类,具体主题或者具体通知者,在具体内部状态改变时,给所有登记过的观察者发出通知。具体主题角色通常用一个具体子类实现。

	//具体通知者
	class Secretary:public SecretaryBase{
	public:
		void Attach(CObserverBase* ob){
			observers.push_back(ob);
		}
		void Notify(){
			vector<CObserverBase*>::iterator p = observers.begin();
			while (p!=observers.end()){
				(*p)->Update();
				p++;
			}
		}
	};
	void StockObserver::Update(){
		cout<<name<<":"<<sub->"不要玩股票了,要开始工作了"<<endl;
	}
	void NBAObserver::Update(){
		cout<<name<<":"<<sub->"不要看 NBA 了,老板来了"<<endl;
	}

客户端:

	int main(){
		SecretaryBase *p=new Secretary(); // 创建观察者
		//被观察的对象
		CObserverBase *s1= new NBAObserver("小李",p);
		CObserverBase *s2 = new StockObserver("小赵",p);
		//加入观察队列
		p->Attach(s1);
		p->Attach(s2);
		//事件
		p->action="老板来了";
		//通知
		p->Notify();
		return 0;
	}

观察者模式特点:

  • 目的:将一个系统分割成一系列相互协作的类,需要维护相关对象间的一致性。观察者模式可以解除各类耦合,便于维护、扩展和重用。
  • 使用时机:当一个对象改变需要同时改变其他对象,且它不知道具体有多少对象需要改变时。观察者模式可以将两者封装在独立的对象中使它们各自独立地改变和复用。
  • 总结:观察者模式所做的工作其实就是在解除耦合,让耦合的双方都依赖于抽象,而不是依赖与具体。从而使得各自的变化都不会影响另一边的变化。

5.组合模式

将对象组合成树形结构以表示’部分-整体’的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性
整体和部分可以被一致对待(如 WORD 中复制一个文字、一段文字、一篇文章都是一样的操作)
在这里插入图片描述

  • 优点:用户不用关系到底是处理一个叶节点还是处理一个组合组件,也就用不着定义组合而写一些选择判断语句了。简单来说,组合模式让客户可以一致地使用组合结构和单个对象。

示例代码:
Component类,为组合中的对象声明接口,适当情况下,实现所有类共有接口的默认行为。声明一个接口用于访问和管理Component的子部件。

	#include <iostream>
	#include <string>
	#include <vector>
	using namespace std;
	class Component{
	public:
		string m_strName;
		Component(string strName){
			m_strName = strName;
		}
		virtual void Add(Component* com)=0;
		virtual void Display(int nDepth)=0;
	};

Leaf在组合中表示叶节点对象,叶节点没有子节点。

	class Leaf : public Component{
	public:
		Leaf(string strNam e): Component(strName){}
		//叶子没有增加分支和树叶,所以Add方法实现没有意义。
		//但是这样可以消除叶节点和枝节点对象在抽象层次的区别,具有完全一致的接口
		virtual void Add(Component* com){
			cout<<"leaf can't add"<<endl;
		}
		//叶节点具体方法,显示名称和级别
		virtual void Display(int nDepth){
			string strtemp;
			for(int i = 0; i < nDepth; i++){
				strtemp += "-";	
			}
			strtemp += m_strName;
			cout<<strtemp<<endl
		}
	};

Component类,定义枝节点行为,用来存储子部件,在Component接口中实现与子部件有关的操作,比如增加Add或者删除。

	class Composite : public Component{
	private:
		vector<Component*> m_component;//一个子对象集合存储其下属的枝节点和叶结点
	public:
		Composite(string strName) : Component(strName){}
		virtual void Add(Component* com){
			m_component.push_back(com);
		}
		virtual void Display(int nDepth){//显示枝节点名称,并对其下级进行遍历
			string strtemp;
			for(int i=0; i < nDepth; i++){
				strtemp+="-"}
			strtemp += m_strName;
			cout<<strtemp<<endl;
		
			vector<Component*>::iterator p=m_component.begin();
			while (p!=m_component.end()){
				(*p)->Display(nDepth+2);
				p++;
			}
		}
	};

客户端:

	#include "Model.h"
	int main(){
		//树根p
		Composite* p=new Composite("小王");
		p->Add(new Leaf("小李"));
		p->Add(new Leaf("小赵"));
		//跟上长出分支p1
		Composite* p1 = new Composite("小小五");
		p1->Add(new Leaf("大三"));
		p->Add(p1);
		
		p->Display(1);//显示大叔的样子
		return 0;
	}

结果:

	-小王
	---小李
	---小赵
	---小小王
	-----大三

组合模式特点:

  • 使用时机:需求中是体现部分与整体层次的结构时,以及希望用户可以忽略组合对象与单个对象的不同,统一地使用组合结构中的所有对象时,应该考虑组合模式。

6.责任链模式

使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理为止
在这里插入图片描述

  • 优点:随时地增加或修改处理一个请求的结构,增强了给对象指派职责的灵活性。
  • 不足:一个请求极有可能到了链的末端都得不到处理,或者因为没有有正确配置而得不到处理。

接收者和发送者都没有对方的明确信息,且链中对象自己也不知道链的机构。结果是职责链可简化对象的相互连接,仅需保持一个指向其后继者的引用,而不需要保持它所有的候选接受者的引用,大大降低了耦合度。

示例:
在这里插入图片描述
示例代码:

	#include <iostream>
	#include <string>
	#include <vector>
	using namespace std;
	//请求
	class Request{
	public:
		string m_strContent;
		int m_nNumber;
	};
//管理者
class Manager{
protected:
	Manager* manager;//管理者的上级
	string name;
public:
	Manager(string temp){
		name = temp;
	}
	//设置管理者的上级
	void SetSuccessor(Manager* temp){
		manager = temp;
	}
	//申请请求
	virtual void GetRequest(Request* request) = 0;
};

经理类和总监类可以继承“管理者”类,只需重写“申请请求”的方法。

//经理
class CommonManager : public Manager{
public:
	CommonManager(string strTemp) : Manager(strTemp){}
	
	virtual void GetRequest(Request* request){
		if ( request->m_nNumber>=0 && request->m_nNumber<10{
			cout<<name<<" 处理了 "<<request->m_nNumber<<"个请求"<<endl;
		}
		else{
			manager->GetRequest(request); //其余的申请转到上级
		}
	}
};
//总监
class MajorDomo : public Manager{
public:
	MajorDomo(string strTemp) : Manager(strTemp){}
	
	virtual void GetRequest(Request* request){
		if ( request->m_nNumber>=10{
			cout<<name<<" 处理了 "<<request->m_nNumber<<"个请求"<<endl;
		}
		else{
			manager->GetRequest(request); //其余的申请转到上级
		}
	}
};

客户端:

int main()
{
	Manager * common = new CommonManager("张经理");
	Manager * major = new MajorDomo("李总监");
	
	common->SetSuccessor(major);//设置上级
	
	Request* req = new Request();
	req->m_nNumber = 33;
	common->GetRequest(req);
	
	req->m_nNumber = 3;
	common->GetRequest(req);
	return 0;
}

7. 四个准则

单一职责原则

  • 就一个类而言,应该仅有一个引起它变化的原因。

  • 如果一个类承担的职责过多,就等于把这些职责耦合在一起,一个职责的变化可能会削弱或者抑制这个类完成其它职责能力。这种耦合会导制脆弱的设计,当变化发生时,设计会遭受到意想不到的破坏。

  • 如果你能够想到多于一个的动机去改变一个类,那么这个类就具有多于一个的职责。

开放――封闭原则

  • 软件实体可以扩展,但是不可修改。即对于扩展是开放的,对于修改是封闭的。面对需求,对程序的改动是通过增加代码来完成的,而不是改动现有的代码。
  • 当变化发生时,我们就创建抽象来隔离以后发生同类的变化。
  • 开放――封闭原则是面向对象的核心所在。开发人员应该对程序中呈现出频繁变化的那部分做出抽象,拒绝对任何部分都刻意抽象及不成熟的抽象。

里氏代换原则

  • 一个软件实体如果使用的是一个父类的话,那么一定适用其子类。而且它察觉不出父类对象和子类对象的区别。也就是说:在软件里面,把父类替换成子类,程序的行为没有变化。
  • 子类型必须能够替换掉它们的父类型。

依赖倒转原则

  • 抽象不应该依赖细节,细节应该依赖抽象。即针对接口编程,不要对实现编程。 高层模块不能依赖低层模块,两者都应依赖抽象。
  • 依赖倒转原则是面向对象的标志,用哪种语言编写程序不重要,如果编写时考虑的是如何针对抽象编程而不是针对细节编程,即程序的所有依赖关系都终止于抽象类或接口。那就是面向对象设计,反之那就是过程化设计。

8.总结

介绍了音视频学习中需重点把握的6个设计模式,简单介绍相关的4个准则。
这6种设计模式都是必须要掌握的,下表列出了各个模式的优点:

模式优点
单例模式严格控制客户怎样访问它以及何时访问它。简单来说,对唯一实例的受控访问。
工厂模式适应于不同情况创建不同的类时,容易维护、扩展、复用
策略模式适合类中的成员以方法为主,算法经常变动;简化了单元测试(因为每个算法都有自己的类,可以通过自己的接口单独测试。
观察者模式解除各类耦合,便于维护、扩展和重用
组合模式让客户可以一致地使用组合结构和单个对象
责任链模式随时地增加或修改处理一个请求的结构,增强了给对象指派职责的灵活性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/430235.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

12-Java享元模式 ( Flyweight Pattern )

Java享元模式 摘要实现范例 享元模式&#xff08;Flyweight Pattern&#xff09;主要用于减少创建对象的数量&#xff0c;以减少内存占用和提高性能 享元模式尝试重用现有的同类对象&#xff0c;如果未找到匹配的对象&#xff0c;则创建新对象 享元模式属于结构型模式&…

5分钟速成渐变色css

色彩的分支——渐变色定义&#xff1a;按照一定规律做阶段性变化的色彩&#xff08;抽象&#xff01;&#xff01;&#xff01;&#xff09; 我们可以将图片分为两块 以中心线为参考&#xff0c;再来看渐变色的定义&#xff1a;按照一定规律做阶段性变化的色彩 既然是按一定的…

【格与代数系统】偏序关系、偏序集与全序集

关系&#xff1a;X,Y是两个非空集合, 记若则称R是X到Y的一个二元关系&#xff0c;简称关系。 若,记。 当时&#xff0c;称是上的一个关系。 目录 偏序关系 偏序集 可比性 全序集 最值与上下界 上下确界 偏序关系 设是上的一个关系&#xff0c;若满足&#xff1a; (1)自…

水库大坝位移监测方法的探索与实践

一、概述&#xff1a;水库大坝位移监测&#xff0c;作为当前工程领域的研究热点&#xff0c;对于确保大坝安全具有重要意义。当前&#xff0c;水平位移与垂直位移监测是两大核心方法。本文旨在通过实际工程案例&#xff0c;深入探讨如何有效结合这两种监测方法&#xff0c;提升…

Vue.js+SpringBoot开发高校学院网站

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 学院院系模块2.2 竞赛报名模块2.3 教育教学模块2.4 招生就业模块2.5 实时信息模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 学院院系表3.2.2 竞赛报名表3.2.3 教育教学表3.2.4 招生就业表3.2.5 实时信息表 四、系…

Typescript 哲学 morn on funtion

函数重载 overload 有一些编程语言&#xff08;eg&#xff1a;java&#xff09;允许不同的函数参数&#xff0c;对应不同的函数实现。但是&#xff0c;JavaScript 函数只能有一个实现&#xff0c;必须在这个实现当中&#xff0c;处理不同的参数。因此&#xff0c;函数体内部就…

iOS-系统弹窗调用,

代码&#xff1a; UIAlertController *alertViewController [UIAlertController alertControllerWithTitle:"请选择方式" message:nil preferredStyle:UIAlertControllerStyleActionSheet];// style 为 sheet UIAlertAction *cancle [UIAlertAction actionWithTit…

消息队列-Kafka-基础架构

基础架构 官网地址 上面这张图类比RocketMQ 相当于对一个主题进行了分区&#xff08;类似于RockeMQ 消息队列&#xff09;&#xff0c;每个分区存储到不同的Broker。在发送消息的时候都是发送到主分区。如果一台Broker由于其它节点备份了挂掉节点的数据&#xff0c;所以可以…

demo型xss初级靶场

一、环境 XSS Game - Ma Spaghet! | PwnFunction 二、开始闯关 第一关 看看代码 试一下直接写 明显进来了为什么不执行看看官方文档吧 你不执行那我就更改单标签去使用呗 ?somebody<img%20src1%20onerror"alert(1)"> 防御&#xff1a; innerText 第二关…

TS项目实战三:Express实现登录注册功能后端

使用express实现用户登录注册功能&#xff0c;使用ts进行代码开发&#xff0c;使用mysql作为数据库&#xff0c;实现用户登录、登录状态检测、验证码获取接口及用户注册相关接口功能的实现。 源码下载&#xff1a;[点击下载] (https://download.csdn.net/download/m0_37631110/…

【论文阅读】《Graph Neural Prompting with Large Language Models》

文章目录 0、基本信息1、研究动机2、创新点3、准备3.1、知识图谱3.2、多项选择问答3.3、提示词工程&#xff08;prompt engineering&#xff09; 4、具体实现4.1、提示LLMs用于问答4.2、子图检索4.3、Graph Neural Prompting4.3.1、GNN Encoder4.3.2、Cross-modality Pooling4.…

UE4升级UE5 蓝图节点变更汇总(4.26/27-5.2/5.3)

一、删除部分 Ploygon Editing删除 Polygon Editing这个在4.26、4.27中的插件&#xff0c;在5.1后彻底失效。 相关的蓝图&#xff0c;如编辑器蓝图 Generate mapping UVs等&#xff0c;均失效。 如需相关功能&#xff0c;请改成Dynamic Mesh下的方法。 GetSupportedClass删…

Vue项目性能分析工具: vue-cli-plugin-webpack-bundle-analyzer

在优化项目的时候&#xff0c;每次打包后只知道包文件大&#xff0c;却不知道那个文件大&#xff0c;那个文件还有优化的空间&#xff0c;所以&#xff0c;推荐一款工具&#xff0c;只要在项目中安装配置一下&#xff0c;便可以一目了然的呈现出打包后资源所占的比例&#xff0…

企业招聘信息二维码,如何制作?其优势在哪里?

伴随着三月的春风和细雨&#xff0c;招聘和求职市场也正在回暖。招聘网站的广告攻占了各大社交平台和遍布城市的广告牌&#xff0c;求职者忙着四处打探招聘信息、投简历&#xff0c;公司也在为招聘工作、寻找合适的人才而忙得不可开交。 今天我们要分享的是&#xff0c;如何制…

基于springboot的抗疫物资管理系统论文

目 录 摘 要 1 前 言 2 第1章 概述 2 1.1 研究背景 3 1.2 研究目的 3 1.3 研究内容 4 第二章 开发技术介绍 5 2.1相关技术 5 2.2 Java技术 6 2.3 MySQL数据库 6 2.4 Tomcat介绍 7 2.5 Spring Boot框架 8 第三章 系统分析 9 3.1 可行性分析 9 3.1.1 技术可行性 9 3.1.2 经济可行…

世界最强AI大模型易主了?昨晚,Claude 3系列模型发布,GPT-4时代终结?

3 月 4 日&#xff0c;被称为 OpenAI 最强竞争对手的大模型公司 Anthropic 宣布推出 Claude3 系列模型&#xff0c;与 Gemini 类似&#xff0c;模型按照大小分为三个&#xff1a;Claude 3 Haiku、Claude 3 Sonnet 和 Claude 3 Opus。Opus 目前在官方发布的测试成绩中全方位超越…

Ajax与JQuery

一、认识Ajax 1.1 web2.0的特点 用户贡献内容内容聚合RSS更丰富的用户体验 1.2 Ajax的优势 无刷新&#xff1a;不刷新整个业务&#xff0c;只刷新局部 无刷新的好处&#xff1a; 只更新部分页面&#xff0c;有效利用带宽提供连续的用户体验提供类似C/S的交互效果&#xff…

产品推荐 - GX-SOPC-5CEFA5-M484 FPGA核心开发板

● 核心板采用8层板精心设计 ● FPGA&#xff1a;采用Intel&#xff08;ALTERA&#xff09; Cyclone V 5CEFA5&#xff0c;Les为77K&#xff0c;内嵌存储器为4460Kb&#xff0c;硬件乘法器为300个&#xff0c;最大等效门数约2300万门&#xff1b;新增DSP Block&#xff08;150…

【C语言】Leetcode 876. 链表的中间节点

主页&#xff1a;17_Kevin-CSDN博客 专栏&#xff1a;《Leetcode》 题目 通过题目的要求可以判断出有两种示例要解决&#xff0c;一种是偶数节点的链表&#xff0c;一种是奇数节点的链表&#xff0c;应对这两种情况我们需要使程序对二者都可以兼容。 解决思路 struct ListNode…

UBOOT和LINUX 调试等级设置

比较好的网页 UBOOT LINUX 设置相关 方法1&#xff1a; echo 5 > /proc/sys/kernel/printk 缺点&#xff1a;方法1无法修改在内核启动时的输出信息 方法2&#xff1a; 通过uboot的环境变量bootargs传递打印级别的参数 set bootargs root/dev/nfs init/linuxrc nfsroot19…