Qwen2在Java项目中如何实现优雅的Function_Call工具调用
在当今AI技术飞速发展的背景下,大语言模型如Qwen2和GLM-4凭借其强大的语言处理能力,在诸多领域展现出了巨大的潜力。然而,大模型并非全知全能,它们在处理特定任务时,尤其是在需要与外部系统交互或执行具体功能时,会遇到一定的局限性。这主要是因为大模型通常被设计为封闭的文本生成系统,缺乏直接调用外部工具或API的能力。这种局限性凸显了工具调用在实际应用中的必要性,它能够扩展模型的功能边界,使其能够在真实世界场景中执行更加复杂和具体的操作。
工具调用的必要性
尽管大模型在自然语言理解和生成上取得了显著进步,但它们往往受限于训练数据的内容,无法直接访问网络资源、执行代码或操作数据库等。这意味着在解决实际问题时,模型可能无法提供直接、即时且准确的解决方案,尤其是那些需要实时数据处理或特定功能执行的任务。因此,通过工具调用来增强大模型的功能,成为提升其实用性和灵活性的关键。
在此背景下,ChatGLM3以及最近的GLM-4原生就已经支持了工具调用,这就非常方便,通过直接与外部工具交互,减少了中间环节,提高了响应速度和效率。
tools = [{"name": "track","description": "追踪指定股票的实时价格","parameters": {"type": "object","properties": {"symbol": {"description": "需要追踪的股票代码"}},"required": ['symbol']}},{"name": "text-to-speech","description": "将文本转换为语音","parameters": {"type": "object","properties": {"text": {"description": "需要转换成语音的文本"},"voice": {"description": "要使用的语音类型(男声、女声等)"},"speed": {"description": "语音的速度(快、中等、慢等)"}},"required": ['text']}}
]
system_info = {"role": "system", "content": "Answer the following questions as best as you can. You have access to the following tools:", "tools": tools}
但是Qwen1.5以及Qwen2并不具备原生的工具调用功能,得借助于其Qwen-Agent框架或者langChain框架。那不借助Python框架,我就要使用Java实现该怎么做呢?
使用Java实现Qwen2工具调用
首先,我们需要自定义两个注解FunctionDef
和FunctionParam
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface FunctionDef {/*** 函数名称* @return 函数名称*/String name() default "";/*** 函数描述* @return 函数描述*/String description();
}@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PARAMETER})
public @interface FunctionParam {/*** 参数名称* @return 参数名称*/String name();/*** 参数描述* @return 参数描述*/String description();/*** 参数枚举* @return 参数枚举*/String[] enums() default {};/*** 是否必填* @return 必填*/boolean required() default false;
}
然后,我们可以根据自己的需求,创建几个工具插件。下面是我创建的一个查询天气的插件:
public class WeatherTool {/*** 查询天气* @param city 城市* @return 天气信息*/@FunctionDef(name = "getWeatherInfo", description = "get the weather info")public static String getWeatherInfo(@FunctionParam(name = "city", description = "the city name") String city) {if (city == null || city.isEmpty()) {throw new IllegalArgumentException("City name must not be null or empty");}OkHttpClient client = new OkHttpClient.Builder().connectTimeout(60, TimeUnit.SECONDS).writeTimeout(60, TimeUnit.SECONDS).readTimeout(60, TimeUnit.SECONDS).build();try {Map<String, String> headers = new HashMap<>(16);headers.put("Content-Type", "application/json");Request.Builder builder = new Request.Builder().url("https://query.asilu.com/weather/baidu/?city="+city);builder.headers(Headers.of(headers));builder.method("GET", null);Request request = builder.build();Response response = client.newCall(request).execute();if (response.isSuccessful()) {ResponseBody responseBody = response.body();JSONObject jsonObject = JSONObject.parseObject(responseBody.string());return jsonObject.toString();} else {throw new OpenAIChatException("Failed with status code %d. messages: %s", response.code(), response.message());}} catch (IOException e) {e.printStackTrace();return "Error encountered while fetching weather data!";}}
}
再然后,我们把所有的工具插件都交给大模型,让它判断要满足用户的提问,应该选择哪个工具插件:
public String getToolResult(String sessionId,String prompt, List<Function> baseTools){String class2Json = buildClass2Json(new BaseFunction());String finalPrompt = String.format("你是一个AI助手,我会给你一个工具对象集合,工具对象包括name(工具名)、description(工具描述)、clazz(工具类名)、parameters(工具参数)。" +"你可以结合工具对象,从用户的问句中提取到关键词,确定要实现用户的任务应该选择哪个工具对象和工具的参数。" +"【工具集合】:%s。" +"【用户提问】:%s?" +"您的响应结果必须为JSON格式,并且不要返回任何不必要的解释,只提供遵循此格式的符合RFC8259的JSON响应。以下是输出必须遵守的JSON Schema实例:```%s```",JSON.toJSONString(baseTools),prompt,class2Json);String funcParams = chat(sessionId,finalPrompt);funcParams = JSON.parseObject(funcParams, OpenAIChatResponse.class).getChoices().get(0).getMessage().getContent();funcParams = funcParams.substring(funcParams.indexOf("{"), funcParams.lastIndexOf("}")+1);return LoadFunctions.load(JSON.parseObject(funcParams, BaseFunction.class));}
确定哪个工具插件后,再使用LoadFunctions.load加载执行这个工具插件:
public static String load(BaseFunction baseFunction){String className = baseFunction.getClazz();String methodName = baseFunction.getFunctionName();Map<String,String> arg = baseFunction.getParams();List<String> params = new ArrayList<>();String result = "";try {// 加载类Class<?> clazz = Class.forName(className);//可以使用arg.size确定几个参数,我为了演示方便,这里就默认只有一个参数了//int size = arg.size();Method method = clazz.getMethod(methodName,String.class);Parameter[] parameters = method.getParameters();// 如果方法有参数,并且参数类型已知(例如只有一个String类型的参数)for (int i = 0; i < parameters.length; i++){params.add(arg.values().stream().skip(i).findFirst().orElse(null));}// 创建类的实例,如果CarBean有一个无参构造函数Object instance = clazz.newInstance();result = method.invoke(instance,params.toArray()).toString();} catch (ClassNotFoundException e) {LOG.error("类未找到: {}" , className);} catch (NoSuchMethodException e) {LOG.error("找不到方法: {}" , methodName);} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {LOG.error("无法调用方法: {}" , e.getMessage());}return result;}
最后,我们就可以拿到工具执行的结果,然后把工具执行结果直接给到大模型,让它组织语言回答用户提问就可以了
public Flux<String> streamChatWithTools(String sessionId, String prompt, List<Function> baseTools) {//获取工具结果String toolResult = getToolResult(null,prompt, baseTools);LOG.info("工具调用结果为:{}",toolResult);String promptFormat = String.format("基于工具查询的结果:{%s}。请回答:%s?", toolResult, prompt);return streamChat(sessionId, promptFormat);}
到这里,我们就完成了像Qwen2这种没有原生支持Function_call的大模型的工具调用的功能了。
改进优化
在最初的版本中,我们是把普通问答和工具调用的问答分开设计的,这样的设计虽然能实现各种不同的功能,但是对于用户并不友好,“我怎么知道什么时候该使用工具模式呢?”。
因此,我们打算将普通问答模式和工具调用问答模式进行合并。这样,用户只需要专注于自己的问题即可,不用在纠结该选择哪个模式。
首先,我们定义一个返回空字符串的工具插件:
/*** 返回一个空字符串* @return 归属地*/@FunctionDef(name = "getEmptyResult", description = "get a empty result")public static String getEmptyResult() {return "";}
然后,也需要修改一下大模型选择工具插件的提示词,“如果用户提问内容与除了getEmptyResult之外的其他所有的工具都不相关,就返回getEmptyResult”:
public String getToolResult(String sessionId,String prompt, List<Function> baseTools){String class2Json = buildClass2Json(new BaseFunction());String finalPrompt = String.format("你是一个AI助手,我会给你一个工具对象集合,工具对象包括name(工具名)、description(工具描述)、clazz(工具类名)、parameters(工具参数)。" +"你可以结合工具对象,从用户的问句中提取到关键词,确定要实现用户的任务应该选择哪个工具对象和工具的参数。" +"【工具集合】:%s。" +"【用户提问】:%s?" +"如果用户提问内容与除了getEmptyResult之外的其他所有的工具都不相关,则你需要响应getEmptyResult工具即可。"+"您的响应结果必须为JSON格式,并且不要返回任何不必要的解释,只提供遵循此格式的符合RFC8259的JSON响应。以下是输出必须遵守的JSON Schema实例:```%s```",JSON.toJSONString(baseTools),prompt,class2Json);String funcParams = chat(sessionId,finalPrompt);funcParams = JSON.parseObject(funcParams, OpenAIChatResponse.class).getChoices().get(0).getMessage().getContent();funcParams = funcParams.substring(funcParams.indexOf("{"), funcParams.lastIndexOf("}")+1);return LoadFunctions.load(JSON.parseObject(funcParams, BaseFunction.class));}
这样,如果我如果输入一个问题,如地球的直径是多少。大模型识别这个问题与所有的工具插件都不相关,它就返回一个空字符串,也就是不用基于查询的知识进行回答。
public Flux<String> streamChatWithTools(String sessionId, String prompt, List<Function> baseTools) {//获取工具结果String toolResult = getToolResult(null,prompt, baseTools);LOG.info("工具调用结果为:{}",toolResult);String promptFormat = StringUtils.isEmpty(toolResult) ? String.format("请回答:%s?", prompt):String.format("基于工具查询的结果:{%s}。请回答:%s?", toolResult, prompt);return streamChat(sessionId, promptFormat);}
这样,我们就实现了使用一个接口,同时处理用户的通识问答和需要进行工具调用的问答。
相关文章:
![](https://img-blog.csdnimg.cn/direct/e4f870b331714f2099182d6f203204dd.png)
Qwen2在Java项目中如何实现优雅的Function_Call工具调用
在当今AI技术飞速发展的背景下,大语言模型如Qwen2和GLM-4凭借其强大的语言处理能力,在诸多领域展现出了巨大的潜力。然而,大模型并非全知全能,它们在处理特定任务时,尤其是在需要与外部系统交互或执行具体功能时&#…...
![](https://img-blog.csdnimg.cn/img_convert/039844a82f63a5bb4efcff7956b21ead.png)
【SPIE独立出版 | 往届均已完成EI检索】2024云计算、性能计算与深度学习国际学术会议(CCPCDL 2024)
2024云计算、性能计算与深度学习国际学术会议(CCPCDL 2024) 2024 International conference on Cloud Computing, Performance Computing and Deep Learning *CCPCDL往届均已完成EI检索,最快会后4个半月完成! 一、重要信息 大会官网:www…...
![](https://img-blog.csdnimg.cn/direct/a73b25a5f5914889a7969d6141730bba.png)
MYSQL 四、mysql进阶 4(索引的数据结构)
一、为什么使用索引 以及 索引的优缺点 1.为什么使用索引 索引是存储引擎用于快速找到数据记录的一种数据结构,就好比一本教科书的目录部分,通过目录中找到对应文章的页码,便可快速定位到需要的文章。Mysql中也是一样的道理,进行数…...
![](https://img-blog.csdnimg.cn/direct/9663204c54574ca891b78f638443355e.jpeg)
360vr党建线上主题展立体化呈现企业的文化理念和品牌形象
在现代科技的引领下,艺术与VR虚拟现实技术相融合必将成为趋势,深圳VR公司华锐视点荣幸地推出VR艺术品虚拟展厅,为您带来前所未有的艺术观赏体验。体验者足不出户即可置身于一个充满创意与灵感的虚拟艺术空间。 我们深入了解每一位客户的需求与…...
![](https://img-blog.csdnimg.cn/direct/722656c9342f42b6a3b5beea3fe7c91b.png)
docker通过容器id查看运行命令;Portainer监控管理docker容器
1、docker通过容器id查看运行命令 参考:https://blog.csdn.net/a772304419/article/details/138732138 docker inspect 运行镜像id“Cmd”: [ “–model”, “/qwen-7b”, “–port”, “10860”, “–max-model-len”, “4096”, “–trust-remote-code”, “–t…...
![](https://img-blog.csdnimg.cn/img_convert/cb879f953b16214249df322a7f2875df.png)
XMind 2024软件最新版下载及详细安装教程
人所共知的是XMind 在公司和教育领域都有很广泛的应用,在公司中它能够用来进行会议管理、项目管理、信息管理、计划和XMind 被认为是一种新一代演示软件的模式。也就是说XMind不仅能够绘制思维导图,还能够绘制鱼骨图、二维图、树形图、逻辑图、组织结构…...
![](https://www.ngui.cc/images/no-images.jpg)
代码随想录算法训练营第四十四天 | 322. 零钱兑换、279.完全平方数、139.单词拆分、多重背包理论基础、背包问题总结
322. 零钱兑换 题目链接:https://leetcode.cn/problems/coin-change/ 文档讲解:https://programmercarl.com/0322.%E9%9B%B6%E9%92%B1%E5%85%91%E6%8D%A2.html 视频讲解:https://www.bilibili.com/video/BV14K411R7yv/ 思路 确定dp数组以及下…...
![](https://img-blog.csdnimg.cn/direct/f075b3cc90e241528d5b9103109bf1c0.png)
开源AGV调度系统OpenTCS中的路由器(router)详解
OpenTCS中的任务分派器router详解 1. 引言2. 路由器(router)2.1 代价计算函数(Cost functions)2.2 2.1 Routing groups2.1 默认的停车位置选择2.2 可选停车位置属性2.3 默认的充电位置选择2.4 即时运输订单分配 3. 默认任务分派器的配置项4. 参考资料与源…...
![](https://www.ngui.cc/images/no-images.jpg)
关于下载 IDEA、WebStorm 的一些心得感想
背景 实习第一天的时候,睿哥便吩咐我下载一些软件,这些软件以后在写项目的时候会用到,他叫我先装IDEA,WebStorm,微信开发者工具,git,还有Navicat。 这些软件能够被我们正常使用,无非就通过三步…...
![](https://img-blog.csdnimg.cn/direct/2ecf014a489f4b26bfeb60ee737b5fb0.jpeg)
C#使用Scoket实现服务器和客户端互发信息
20240616 By wdhuag 目录 前言: 参考: 一、服务器端: 1、服务器端口绑定: 2、服务器关闭: 二、客户端: 1、客户端连接: 2、客户端断开: 三、通讯: 1、接收信…...
![](https://www.ngui.cc/images/no-images.jpg)
【经验分享】SpringCloud + MyBatis Plus 配置 MySQL,TDengine 双数据源
概述 因为项目中采集工厂中的设备码点的数据量比较大,需要集成TDengine时序数据库,所以需要设置双数据源 操作步骤 导入依赖 <!-- 多数据源支持 --><dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-s…...
![](https://www.ngui.cc/images/no-images.jpg)
Pycharm 忽略文件
安装 .ignore插件 规则示例 罗列一些常遇到.getignore忽略规则的使用示例: 1. 在已忽略文件夹中不忽略指定文件夹: /libs/* !/libs/extend/ 2. 在已忽略文件夹中不忽略指定文件 /libs/* !/libs/extend/fastjson.jar 3.只忽略libs目录…...
![](https://img-blog.csdnimg.cn/direct/16c1a267ff3c4fd39ba3680ab123b606.png)
爬虫学习。。。。
爬虫的概念: 爬虫是一种自动化信息采集程序或脚本,用于从互联网上抓取信息。 它通过模拟浏览器请求站点的行为,获取资源后分析并提取有用数据,这些数据可以是HTML代码、JSON数据或二进制数据(如图片、视频)…...
![](https://img-blog.csdnimg.cn/direct/88078b5fce7e4ca7b252785b840c58e6.jpeg)
美国铁路客运巨头Amtrak泄漏旅客数据,数据销毁 硬盘销毁 文件销毁
旅客的Guest Rewards常旅客积分账户的个人信息被大量窃取。 美国国家客运铁路公司(Amtrak)近日披露了一起数据泄露事件,旅客的Guest Rewards常旅客积分账户的个人信息被大量窃取。 根据Amtrak向马萨诸塞州提交的泄露通知,5月15日…...
![](https://img-blog.csdnimg.cn/img_convert/4c429504b7492308e8abcd002cab47e8.png)
LabVIEW与Matlab联合编程的途径及比较
LabVIEW和Matlab联合编程可以通过多种途径实现,包括调用Matlab脚本节点、使用LabVIEW MathScript RT模块、利用ActiveX和COM接口,以及通过文件读写实现数据交换。每种方法都有其独特的优势和适用场景。本文将详细比较这些方法,帮助开发者…...
![](https://img-blog.csdnimg.cn/direct/84f4e601e5eb44c0902ffe902443bfa3.png)
秋招突击——6/16——复习{(单调队列优化DP)——最大子序和,背包模型——宠物小精灵收服问题}——新作{二叉树的后序遍历}
文章目录 引言复习(单调队列优化DP)——最大子序和单调队列的基本实现思路——求可移动窗口中的最值总结 背包模型——宠物小精灵收服问题思路分析参考思路分析 新作二叉树的后续遍历加指针调换 总结 引言 复习 (单调队列优化DP)…...
![](https://img-blog.csdnimg.cn/direct/31abfbc50d3c4bd09ce2dffae6cdeaca.png)
SAR动目标检测系列:【4】动目标二维速度估计
在三大类杂波抑制技术(ATI、DPCA和STAP)中,STAP技术利用杂波与动目标在二维空时谱的差异,以信噪比最优为准则,对地杂波抑制的同时有效保留动目标后向散射能量,有效提高运动目标的检测概率和动目标信号输出信杂比,提供理…...
![](https://img-blog.csdnimg.cn/direct/c943572ba5984664a99ee73f3d18b519.png)
JavaEE多线程(2)
文章目录 1..多线程的安全1.1出现多线程不安全的原因1.2解决多线程不安全的⽅法1.3三种典型死锁场景1.4如何避免死锁问题2.线程等待通知机制2.1等待通知的作用2.2等待通知的方法——wait2.3唤醒wait的方法——notify 1…多线程的安全 1.1出现多线程不安全的原因 线程在系统中…...
![](https://img-blog.csdnimg.cn/img_convert/8b3d8a989ff49fcf6c503c87e821f06c.jpeg)
中新赛克两款数据安全产品成功获得“可信数安”评估测试证书
6月19日,2024数据智能大会在北京盛大召开。 会上,中国2024年上半年度“可信数安”评估测试证书正式颁发。中新赛克两款参评产品凭借过硬的技术水准和卓越的应用效果,成功获得专项测试证书。 2024年上半年度“可信数安”评估测试通过名单 中新…...
![](https://img-blog.csdnimg.cn/direct/0584ce142d664d68a0e7bd4a0eef5b5e.png)
代码随想录——分割回文串(Leetcode 131)
题目链接 回溯 class Solution {List<List<String>> res new ArrayList<List<String>>();List<String> list new ArrayList<String>();public List<List<String>> partition(String s) {backtracking(s, 0);return res;}p…...
![](https://www.ngui.cc/images/no-images.jpg)
Rust 学习方法及学习路线汇总
Rust 学习方法及学习路线汇总 Rust 是一种系统编程语言,旨在提供安全性、并发性和高性能。它是由 Mozilla 公司开发的,于 2010 年首次发布。Rust 能够帮助开发者编写可靠和高效的软件,因此受到了广泛的关注和认可。 如果你有兴趣学习 Rust&…...
![](https://img-blog.csdnimg.cn/img_convert/0185fb9ff867c929e49a813c41046464.jpeg)
一名女DBA的感谢信,到底发生了什么?
昨日我们收到这样一通来电 “早上九点刚上班便收到业务投诉电话,系统卡顿,接口失败率大增,怀疑数据库问题。打开运维平台发现是国产库,生无可恋,第一次生产环境遇到国产库性能问题,没什么排查经验…...
![](https://img-blog.csdnimg.cn/img_convert/aa2581dee9e4761d31f2389eaeac1932.png)
群晖NAS本地部署并运行一个基于大语言模型Llama2的个人本地聊天机器人
前言 本文主要分享如何在群晖 NAS 本地部署并运行一个基于大语言模型 Llama 2 的个人本地聊天机器人并结合内网穿透工具发布到公网远程访问。本地部署对设备配置要求高一些,如果想要拥有比较好的体验,可以使用高配置的服务器设备. 目前大部分大语言模型的产品都是基于网络线上…...
![](https://img-blog.csdnimg.cn/direct/dc8db1bd3e9e40a2b510e10f69cf8341.png)
HarmonyOS模拟器(phone-x86-api9)一直卡顿的解决方法
在DevEco Studio 3.1.1 Release版本中的Device Manager中创建本地的模拟器,创建phone-x86-api9模拟器成功,但是启动该新建的模拟器一直显示"HarmonyOS"logo图片,然后一直卡在这里,运行结果如下所示: 检查模…...
![](https://www.ngui.cc/images/no-images.jpg)
排序题目:有序数组的平方
文章目录 题目标题和出处难度题目描述要求示例数据范围进阶 解法一思路和算法代码复杂度分析 解法二思路和算法代码复杂度分析 题目 标题和出处 标题:有序数组的平方 出处:977. 有序数组的平方 难度 2 级 题目描述 要求 给定按非递减顺序排序的整…...
![](https://img-blog.csdnimg.cn/direct/fcacf79a44e14ba79e14607054a75f15.png)
PPT可以转换成Word吗?归纳了三种转换方式
PPT可以转换成Word吗?在当今快节奏的工作和学习环境中,不同格式文件之间的转换变得日益重要。PPT作为演示文稿制作的首选工具,广泛应用于会议演讲、教育培训等多个场景,而Word则是文档编辑与编排的基石。为了便于进一步编辑、分享…...
![](https://img-blog.csdnimg.cn/direct/49411b52d03f4b7cab8ca8a02bdde340.png)
分布式锁三种方案
基于数据库的分布式锁(基于主键id和唯一索引) 1基于主键实现分布式锁 2基于唯一索引实现分布式锁 其实原理一致,都是采用一个唯一的标识进行判断是否加锁。 原理:通过主键或者唯一索性两者都是唯一的特性,如果多个…...
![](https://img-blog.csdnimg.cn/direct/6f9fdb7f000f40dba055fb02f4f2148c.png)
【HarmonyOS NEXT】har 包的构建生成过程
Har模块文件结构 构建HAR 打包规则 开源HAR除了默认不需要打包的文件(build、node_modules、oh_modules、.cxx、.previewer、.hvigor、.gitignore、.ohpmignore)和.gitignore/.ohpmignore中配置的文件,cpp工程的CMakeLists.txt,…...
![](https://www.ngui.cc/images/no-images.jpg)
从0开发一个Chrome插件:项目实战——翻译插件(附带申请谷歌翻译、百度翻译教程)
前言 这是《从0开发一个Chrome插件》系列的第十八篇文章,本系列教你如何从0去开发一个Chrome插件,每篇文章都会好好打磨,写清楚我在开发过程遇到的问题,还有开发经验和技巧。 专栏: 从0开发一个Chrome插件:什么是Chrome插件?从0开发一个Chrome插件:开发Chrome插件的必…...
![](https://img-blog.csdnimg.cn/img_convert/46c6725b910e5a2dc2806b0427440ff1.webp?x-oss-process=image/format,png)
查看nginx安装/配置路径,一个服务器启动两个nginx
查看nginx安装/配置路径 查看nginx的pid: ps -ef | grep nginx查看pid对应服务的启动路径 ll /proc/2320/exe使用检查配置文件命令,查看配置文件位置 /usr/local/nginx/sbin/nginx -t一个服务启动两个nginx 拷贝一份程序,cpbin是我自己创…...
![](/images/no-images.jpg)
外贸网站模板免费下载/徐汇网站建设
解 决 无 法 修 改 my .ini 文 件 的 问 题 my. i ni —— 》 右 键 “ 属 性 ” —— 》 “ 安 全 ” —— 》 点 击 “ 编 辑 ” —— 》 选 择 你 现 在 登录的账号 —— 》 修 改 你 的 操 作 权 限 ,其 中 包 括 :完 全 控 制 ,修 改 &a…...
![](https://img2018.cnblogs.com/blog/1425384/201812/1425384-20181218141838711-1829067290.png)
帮人做空间网站怎么赚钱/洛阳seo网络推广
如图重启时找不到rabbitmq, 解决办法: rabbitmqctl stop :停止rabbitmq rabbitmq-server restart : 重启rabbitmq 这两步就可以完成重启服务。 转载于:https://www.cnblogs.com/PrayzzZ/p/10136869.html...
![](/images/no-images.jpg)
深圳做app网站建设/网络推广方式有哪些
package study; //多态性的向上转类型:子类->父类 class A{public void fun1() {System.out.println("父类的fun1方法");}public void fun2() {System.out.println("父类的fun2方法");} }class B extends A{public void fun1() {System.out.println(&qu…...
![](/images/no-images.jpg)
站长号查询入口站长工具/外国网站开放的浏览器
python 连接mysql数据建立表并插入数据详解,夜行者基地原创...转载请保留原创链接http://www.scpman.com/forum.php?modviewthread&tid144&page1&extra#pid218红色表示报错信息 黑色是解说 绿色是解决方法1、要想用python连接mysql首先要有mysql模块&a…...
![](/images/no-images.jpg)
做网站多少钱google/搜索引擎推广方案
在vue中methods互相调用的方法 转载于:https://www.cnblogs.com/macT/p/10212878.html...
![](/images/no-images.jpg)
青海公司网站建设哪家快/网站搜索引擎
移动前端第一弹:viewport详解前言这次想聊聊移动开发相关的事。是的,你没有看错,一句话就可以开始你的移动前端开发。你心里一定在想,什么话这么酷,能够瞬间带入到移动前端开发的世界。但其实它一点也不新奇࿰…...