当前位置: 首页 > news >正文

玩转MCP:用百度热搜采集案例快速上手并接入cline

MCP的大火,让MCP服务器开发也变得热门,上一篇文章: 手搓MCP客户端&服务端:从零到实战极速了解MCP是什么?

手搓了一个极其简单的小场景的MCP实战案例,详细的安装环境及操作步骤已经讲过了,本文不在重复讲,今天带领大家手搓一个稍微带点复杂度的案例:百度热榜新闻采集MCP服务器并接入cline。

一、MCP的最少必要知识

一)MCP是什么?

MCP(Model Context Protocol,模型上下文协议) ,2024年11月底,由 Anthropic 推出的一种开放标准,旨在统一大型语言模型(LLM)与外部数据源和工具之间的通信协议。

二)它解决了什么问题?

MCP 的主要意义在于解决当前 AI 模型因数据孤岛限制而无法充分发挥潜力的难题,MCP 使得 AI 应用能够安全地访问和操作本地及远程数据,为 AI 应用提供了连接万物的接口。

二、开发一个百度热搜榜采集

一)初始化项目环境

# 初始化项目
uv init mcp-baidu-hot-news-sdtio# 进入目录
cd .\mcp-baidu-hot-news-sdtio\# 安装python 3.11.11 的pyton环境
uv venv --python 3.11.11# 激活(进入)虚拟环境
.venv\Scripts\activate

二)安装项目所需依赖

使用uv安装项目所需依赖,所有依赖就只安装到当前项目下,便于打包和分发项目

# 在虚拟环境中安装依赖
uv add mcp openai python-dotenv playwright

三)编写MCP客户端

上一篇文章: 手搓MCP客户端&服务端:从零到实战极速了解MCP是什么?

已经带大家做过一个MCP客户端,这里基本的MCP客户端基本上一篇的保持一致;

1、创建env文件

BASE_URL=https://api.deepseek.com
MODEL=deepseek-chat
API_KEY="你的API_KEY"

2、MCP客户端

在项目根目录下,创建一个 client.py 文件

客户端就做了一下几个事情:

  • 启动并初始化 MCP 客户端
  • 连接到 MCP 服务器
  • 列出 MCP 服务器上的工具
  • 与用户进行交互式对话
import asyncio
import os
from openai import OpenAI
from dotenv import load_dotenv
from contextlib import AsyncExitStack
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
import json# 加载 .env 文件
load_dotenv()class MCPClient:def __init__(self):"""初始化 MCP 客户端"""self.exit_stack = AsyncExitStack()self.openai_api_key = os.getenv("API_KEY")  # 读取 OpenAI API Keyself.base_url = os.getenv("BASE_URL")  # 读取 BASE URLself.model = os.getenv("MODEL")  # 读取 modelif not self.openai_api_key:raise ValueError("未找到 API KEY. 请在.env文件中配置API_KEY")self.client = OpenAI(api_key=self.openai_api_key,base_url=self.base_url)async def process_query(self, query: str) -> str:"""调用大模型处理用户输入"""messages = [{"role": "user", "content": query}]response = await self.session.list_tools()print('服务端工具列表', response.tools)available_tools = [{"type": "function","function": {"name": tool.name,"description": tool.description,"input_schema": tool.inputSchema}} for tool in response.tools]response = self.client.chat.completions.create(model=self.model,messages=messages,tools=available_tools)print('大模型返回', response)# 处理返回的内容content = response.choices[0]print('大模型返回内容', content)if content.finish_reason == "tool_calls":# 如何发现要使用工具,就执行工具tool_call = content.message.tool_calls[0]tool_name = tool_call.function.nametool_args = json.loads(tool_call.function.arguments)# 执行工具result = await self.session.call_tool(tool_name, tool_args)print(f"\n\n[Calling tool {tool_name} with args {tool_args}]\n\n")# 将模型返回的原始消息和工具执行的结果都添加到messages中messages.append(content.message.model_dump())messages.append({"role": "tool","content": result.content[0].text,"tool_call_id": tool_call.id,})# 将上面的结果再返回给大模型生产最终的结果response = self.client.chat.completions.create(model=self.model,messages=messages,)return response.choices[0].message.contentreturn content.message.contentasync def chat_loop(self):"""运行交互式聊天循环"""print("MCP 客户端已启动!输入 'exit' 退出")while True:try:query = input("问: ").strip()if query.lower() == 'exit':breakresponse = await self.process_query(query)print(f"AI回复: {response}")except Exception as e:print(f"发生错误: {str(e)}")async def clean(self):"""清理资源"""await self.exit_stack.aclose()async def connect_to_server(self, server_script_path: str):"""连接到 MCP 服务器"""is_python = server_script_path.endswith('.py')is_js = server_script_path.endswith('.js')if not (is_python or is_js):raise ValueError("不支持的文件类型")command = "python" if is_python else "node"server_params = StdioServerParameters(command=command,args=[server_script_path],env=None)# 启动 MCP 服务器并建立通信stdio_transport = await self.exit_stack.enter_async_context(stdio_client(server_params))self.stdio, self.write = stdio_transportself.session = await self.exit_stack.enter_async_context(ClientSession(self.stdio, self.write))await self.session.initialize()async def list_tools(self):"""列出所有工具"""# 列出 MCP 服务器上的工具response = await self.session.list_tools()tools = response.toolsprint("已连接到服务器,server支持以下工具:", [tool.name for tool in tools])async def main():# 启动并初始化 MCP 客户端client = MCPClient()try:# 连接到 MCP 服务器await client.connect_to_server('server.py')# 列出 MCP 服务器上的工具await client.list_tools()# 运行交互式聊天循环,处理用户对话await client.chat_loop()finally:# 清理资源await client.clean()if __name__ == "__main__":asyncio.run(main())

四)创建MCP服务端

1、采集百度热榜

1)百度热榜页面

我们采集的元素只有三个:标题,热搜指数,链接

2)采集热榜脚本

采集数据的工具:playwright

采集方法:无头模式采集(不打开浏览器)

创建热榜采集脚本 : baidu_hot_news.py

from playwright.async_api import async_playwright
import time
import json
import logging
import os
import asyncio# 确保日志目录存在
log_dir = "logs"
if not os.path.exists(log_dir):os.makedirs(log_dir)# 创建一个专门的日志处理器
file_handler = logging.FileHandler(os.path.join(log_dir, 'baidu_hot_news.log'),encoding='utf-8')
file_handler.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'))logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
logger.addHandler(file_handler)class BaiduHotNews:def __init__(self):logger.info("初始化 BaiduHotNews 实例")self.browser = Noneself.context = Noneself.page = Noneself.playwright = None# 同步上下文管理器def __enter__(self):return selfdef __exit__(self, exc_type, exc_val, exc_tb):if self.browser:self.browser.close()if self.playwright:self.playwright.stop()# 异步上下文管理器async def __aenter__(self):return selfasync def __aexit__(self, exc_type, exc_val, exc_tb):if self.browser:await self.browser.close()if self.playwright:await self.playwright.stop()async def init_browser(self):"""初始化浏览器"""try:logger.info("开始初始化浏览器...")self.playwright = await async_playwright().start()logger.info("Playwright 启动成功")self.browser = await self.playwright.chromium.launch(headless=True,args=['--disable-gpu', '--disable-dev-shm-usage', '--no-sandbox','--disable-setuid-sandbox'])logger.info("浏览器启动成功")self.context = await self.browser.new_context(viewport={'width': 1920,'height': 1080},user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36')self.page = await self.context.new_page()logger.info("页面创建成功")except Exception as e:logger.error(f"浏览器初始化失败: {str(e)}", exc_info=True)raiseasync def scrape(self):"""抓取百度热搜原始数据Returns:list: 包含热搜信息的列表,格式为 [{"title": str, "link": str, "hot_index": int}]"""try:await self.init_browser()# 访问百度热搜页面await self.page.goto('https://top.baidu.com/board?tab=realtime')# 等待页面加载完成await self.page.wait_for_load_state('networkidle')await self.page.wait_for_selector('xpath=//div[contains(@class, "category-wrap_")]')await asyncio.sleep(2)# 获取热搜列表hot_items = await self.page.query_selector_all('xpath=//div[contains(@class, "category-wrap_")]')hot_news_list = []for item in hot_items:try:# 获取标题title_element = await item.query_selector('xpath=.//div[contains(@class, "c-single-text-ellipsis")]')if not title_element:continuetitle = await title_element.inner_text()title = title.strip()# 获取热搜指数并转换为整数index_element = await item.query_selector('xpath=.//div[contains(@class, "hot-index_")]')hot_index = 0  # 默认值if index_element:try:# 移除非数字字符并转换为整数hot_index_str = await index_element.inner_text()hot_index = int(''.join(filter(str.isdigit, hot_index_str.strip())))except ValueError:hot_index = 0# 获取链接link_element = await item.query_selector('xpath=.//a[contains(@class, "title_")]')link = await link_element.get_attribute('href') if link_element else ""if title:  # 只添加有标题的条目hot_news_list.append({'title': title,'link': link,'hot_index': hot_index})logger.info(f"成功解析: {title}")except Exception as e:logger.error(f"解析条目出错: {str(e)}")continuereturn hot_news_listexcept Exception as e:logger.error(f"抓取过程出错: {str(e)}")return []finally:if self.browser:await self.browser.close()async def get_hot_news(self):"""获取百度热搜Returns:str: JSON字符串,包含百度热搜列表和错误信息"""try:results = await self.scrape()if not results:return json.dumps({"error": "未获取到热搜数据","data": []},ensure_ascii=False)return json.dumps({"error": None,"data": results},ensure_ascii=False)except Exception as e:return json.dumps({"error": f"获取热搜失败: {str(e)}","data": []},ensure_ascii=False)if __name__ == '__main__':# 使用示例async def main():async with BaiduHotNews() as scraper:result = await scraper.get_hot_news()data = json.loads(result)if data["error"]:print(f"错误: {data['error']}")else:print("\n今日热搜:")for idx, item in enumerate(data["data"], 1):print(f"\n{idx}. {item['title']}")print(f"热搜指数: {item['hot_index']}")print(f"链接: {item['link']}")asyncio.run(main())
3)测试采集脚本

运行以下命令:

python .\baidu_hot_news.py

2、编写MCP客户端

1)服务端脚本

客户端核心逻辑如下:

  • 运行 baidu_hot_news.py 的采集逻辑
  • 将获取的结果并序列化返回给客户端

创建 server.py 文件:

import logging
import json
import os
from mcp.server.fastmcp import FastMCP
from baidu_hot_news import BaiduHotNews# 确保日志目录存在
log_dir = "logs"
if not os.path.exists(log_dir):os.makedirs(log_dir)# 配置日志 - 只输出到文件
logging.basicConfig(level=logging.DEBUG,  # 使用 DEBUG 级别以获取更多信息format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',handlers=[logging.FileHandler(os.path.join(log_dir, 'mcp_server.log'),encoding='utf-8'),])
logger = logging.getLogger(__name__)# 初始化FastMCP服务器
mcp = FastMCP("baidu_hot_news")@mcp.tool()
async def baidu_hot_news() -> str:"""获取百度热搜:return: 百度热搜列表"""logger.info("开始执行百度热搜抓取...")try:scraper = BaiduHotNews()async with scraper:result = await scraper.get_hot_news()logger.info(f"获取到原始结果: {result[:100]}...")data = json.loads(result)logger.info(f"解析JSON成功,数据条数: {len(data.get('data', []))}")return dataexcept Exception as e:error_msg = f"执行出错: {str(e)}"logger.error(error_msg, exc_info=True)return {"error": error_msg, "data": []}if __name__ == "__main__":# 以标准 I/O 方式运行 MCP 服务器mcp.run(transport="stdio")
2)运行MCP服务

运行如下命令:

uv run .\server.py

五)MCP客户端&服务端联调

1、运行客户端

从上一步的服务端终端切换到client终端,并重命名,如下图:

2、测试

三、将MCP服务器添加到Cline客户端

一)前置条件

1、下载并安装vscode

cline是vscode的一个插件,所以安装cline之前需要先安装vscode,这个就不在赘言了,没有安装的去官网下载安装即可:

vscode官网:https://code.visualstudio.com/

2、获取deepseek的api key

deepseek的api key 需要付费,不过价格是白菜价,10块钱都够你用一阵子了

充值地址:https://platform.deepseek.com/top_up

二)安装cline

1、搜索安装

2、进入cline

三)配置deepseek

将自己的的deepseek的API_KEY配置进来,如下图:

四)配置MCP服务器

① 点击进入cline

② 添加MCP服务器

③ 选择 installed

④ 点击配置MCP服务器

⑤ 填写PC服务器配置

{"mcpServers": {"baidu_hot_news": {"autoApprove": ["baidu_hot_news"],"disabled": false,"timeout": 60,"command": "uv","args": ["--directory","D:/wample/coding/me/yedong_vip/mcp/mcp-baidu-hot-news-sdtio","run","server.py"],"transportType": "stdio"}}
}

⑥ 千万别忘记点击打开服务器按钮

⑦ 点击确定,mcp服务器配置完成

五)测试

四、MCP能否替代传统RPA?

一)核心区别

  • RPA:是一种规则驱动的自动化工具,通过 UI 交互或 API 执行重复性任务。它按预设脚本运行,没有推理能力,输出是固定的,适合固定流程、重复性高的任务
  • MCP:是基于 MCP 协议的服务器,为 AI(如 LLM)提供动态数据、执行能力和推理模板。它服务于 AI 的灵活需求,支持动态响应和智能交互,适合需要 AI 智能处理和动态响应的场景。

二)功能对比

  • RPA

    • 功能:模拟人工操作(如点击、填写表单),调用 API 或脚本执行任务,处理结构化数据。
    • 特点:固定流程,无需理解任务,输出直接可用。
    • 适用场景:任务固定、重复性高的场景,如数据抓取、简单任务执行。
  • MCP

    • 功能:提供动态数据(Resources)、执行任务(Tools)、推理模板(Prompts)。
    • 特点:动态响应,服务于 AI 的灵活需求,输出需 AI 处理
    • 适用场景:需要 AI 智能处理和动态响应的场景,如情感分析、实时数据抓取。

三)MCP 与 RPA 的互补性

  • MCP 能替代的部分

    • 简单数据抓取:RPA 可以抓取网页数据并存为文件,类似 MCP 的基本功能。
    • 固定任务:RPA 按脚本批量处理任务,类似 MCP 的某些工具功能。
  • MCP 无法替代的部分

    • 智能交互性:MCP 支持 AI 动态推理,而 RPA 没有推理能力,只能按脚本运行。
    • 协议标准化:MCP 使用统一的 MCP 协议,与 AI 生态无缝协作,而 RPA 没有标准协议,需要额外接口。
    • 动态性与灵活性:MCP 支持实时抓取和动态调整,而 RPA 流程固定,需求变更需要重写脚本。

MCP 无法完全替代 RPA,但两者可以结合使用,例如 MCP 提供动态数据和推理支持,RPA 执行固定任务,共同实现更复杂的自动化流程。

相关文章:

玩转MCP:用百度热搜采集案例快速上手并接入cline

MCP的大火,让MCP服务器开发也变得热门,上一篇文章: 手搓MCP客户端&服务端:从零到实战极速了解MCP是什么? 手搓了一个极其简单的小场景的MCP实战案例,详细的安装环境及操作步骤已经讲过了,本文不在重复…...

003集——《利用 C# 与 AutoCAD API 开发 WPF 随机圆生成插件》(侧栏菜单+WPF窗体和控件+MVVM)

本案例聚焦于开发一款特色鲜明的 AutoCAD 插件。其核心功能在于,用户在精心设计的 WPF 控件界面中输入期望生成圆的数量,完成输入后,当用户点击 “生成” 按钮,一系列联动操作随即展开。通过数据绑定与命令绑定这一精妙机制&#…...

设计模式简述(十)责任链模式

责任链模式 描述基本使用使用 描述 如果一个请求要经过多个类似或相关处理器的处理。 可以考虑将这些处理器添加到一个链上,让请求逐个经过这些处理器进行处理。 通常,在一个业务场景下会对整个责任链进行初始化,确定这个链上有哪些Handler…...

分组(二分查找)

#include <bits/stdc.h> using namespace std; const int N1e55; int a[N]; int n,k;bool f(int x){int num1;int ma[1];for(int i2;i<n;i){if(a[i]-m>x){ // 当前元素加入当前组会超过极差 xnum; // 新开一组ma[i]; // 新组的最小值设为当前元素}}r…...

vue的主要核心文件介绍

1.package.json 查看依赖包的版本 项目基本信息记录 项目标识&#xff1a;记录项目名称&#xff08;name 字段&#xff09;、版本号&#xff08;version 字段&#xff09;、描述&#xff08;description 字段&#xff09;等基础信息&#xff0c;方便识别和管理项目。例如&…...

从奖励到最优决策:动作价值函数与价值学习

从奖励到最优决策&#xff1a;动作价值函数与价值学习 价值学习动作价值函数对 U t U_t Ut​求期望得到动作价值函数动作价值函数的意义最优动作价值函数(Optimal Action-Value Function)如何理解 Q ∗ Q^* Q∗函数 价值学习的基本思想Deep Q-Network(DQN)DQN玩游戏的具体流程如…...

DApp实战篇:先用前端起个项目

前言 本篇将使用vue框架quasar起一个项目,为了防止大家不会使用quasar,本篇详细讲解一下quasar如何使用。 quasar 如果你不想深入了解quasar,其实你完全可以将quasar当成一个vue的组件库即可,它是一个类谷歌Material风格的UI组件库,但同时它又是一个基于vue的强大框架。…...

论文阅读11——V2V-LLM:采用多模式大型语言模型的车对车协同自动驾驶

原文地址&#xff1a; 2502.09980https://arxiv.org/pdf/2502.09980 论文翻译&#xff1a; V2V-LLM: Vehicle-to-Vehicle Cooperative Autonomous Driving with Multi-Modal Large Language Models V2V-LLM&#xff1a;采用多模式大型语言模型的车对车协同自动驾驶 摘要&#…...

NLP 梳理01 — 文本预处理和分词

文章目录 一、说明二、文本预处理概述2.1 为什么要预处理文本&#xff1f;2.2 文本预处理的常见步骤2.3 什么是令牌化&#xff1f;2.4 为什么令牌化很重要&#xff1f; 三、分词类型四、用于分词化的工具和库五、实际实施六、编写函数以对文本进行标记七、结论 一、说明 本文总…...

Windows11 优雅的停止更新、禁止更新

网上有很多关闭自动更新的方法&#xff0c;改注册表、修改组策略编辑器、禁用Windows Update等等&#xff0c;大同小异&#xff0c;但最后奏效的寥寥无几&#xff0c;今天给大家带来另一种关闭win11自动更新的方法&#xff0c;亲测有效&#xff01; 1、winR 打开运行窗口&…...

Kafka 中的 offset 提交问题

手动提交和自动提交 我们来一次性理清楚&#xff1a;Kafka 中的自动提交 vs 手动提交&#xff0c;到底区别在哪&#xff0c;怎么用&#xff0c;什么场景适合用哪个&#x1f447; &#x1f9e0; 一句话总结 ✅ 自动提交&#xff1a;Kafka 每隔一段时间自动提交 offset ✅ 手动…...

PowerBI窗口函数与视觉计算

文章目录 一、 窗口函数1.1 OFFSET&#xff08;动态查询、求连续值&#xff09;1.1.1 不使用orderBy1.1.2 使用orderBy1.1.3 统计连续值的最大出现次数&#xff08;待补&#xff09; 1.2 INDEX&#xff08;静态查询&#xff09;1.3 WINDOW&#xff08;滚动求和、累计求和、帕累…...

代码随想录算法训练营Day22

回溯知识 力扣77.组合【medium】 一、回溯知识 1、定义 回溯法也可以叫做回溯搜索法&#xff0c;它是一种搜索的方式。回溯是递归的副产品&#xff0c;只要有递归就会有回溯。 2、回溯法的效率 回溯的本质是穷举&#xff0c;穷举所有可能&#xff0c;然后选出我们想要的答案…...

几种常见的HTTP方法之GET和POST

如大家所了解的&#xff0c;每条 HTTP 请求报文都必须包含一个请求方法&#xff0c;这个方法会告诉服务器要执行什么操作&#xff08;例如获取一个 Web 页面、运行一个网关程序、删除一个文件等&#xff09;。常见的几种 HTTP 方法如下&#xff1a; GET&#xff1a; 请求指定的…...

Nginx之https重定向为http

为了将Nginx中443端口的请求重定向到80端口&#xff0c;你可以按照以下步骤进行操作&#xff1a; ‌确认Nginx已经正确安装并运行‌&#xff1a; 确保Nginx服务已经在你的系统上安装并运行。你可以通过运行以下命令来检查Nginx的状态&#xff08;具体命令可能因操作系统而异&a…...

落地DevOps文化:运维变革的正确打开方式

落地DevOps文化:运维变革的正确打开方式 DevOps,这个近年来被谈论得沸沸扬扬的概念,是企业数字化转型的一把钥匙。然而,很多公司虽然喊着“要上DevOps”,却苦于如何真正落地。而DevOps不仅仅是技术工具的堆砌,更是一种文化的重塑。从我的经历来看,DevOps实施的核心在于…...

《C++后端开发最全面试题-从入门到Offer》目录

当今科技行业对C++开发者的需求持续高涨,从金融科技到游戏开发,从嵌入式系统到高性能计算,C++凭借其卓越的性能和灵活性始终占据着关键地位。然而,成为一名优秀的C++工程师并非易事,不仅需要扎实的语言基础,还要掌握现代C++特性、设计模式、性能优化技巧以及各种工业级开…...

24统计建模国奖论文写作框架2(机器学习+自然语言处理类)(附原文《高校负面舆情成因与演化路径研究》)

一、引言 研究背景及意义 文献综述 研究内容与创新点 二、高校负面舆情热点现状分析 案例数据的获取与处理 高效负面舆情热点词频分析 高效负面舆情热点变化趋势分析 三、高校负面舆情成因分析 高校负面舆情变量的选取与赋值 基于QCA方法的高校负面舆情成因分析 四、…...

论文阅读笔记——Deformable Radial Kernel Splatting

DRK 论文 DRK&#xff08;可变形径向核&#xff09;的核心创新正是通过极坐标参数化与切平面投影&#xff0c;对传统3D高斯泼溅&#xff08;3D-GS&#xff09;进行了多维度的优化。 传统 3DGS 依赖径向对称的高斯核&#xff0c;只能表示平滑、各向同性的形状&#xff08;球体、…...

网络编程—TCP/IP模型(IP协议)

上篇文章&#xff1a; 网络编程—TCP/IP模型&#xff08;TCP协议&#xff09;https://blog.csdn.net/sniper_fandc/article/details/147011479?fromshareblogdetail&sharetypeblogdetail&sharerId147011479&sharereferPC&sharesourcesniper_fandc&sharef…...

Android NDK C/C++交叉编译脚本

以下是 ​​Android (arm64-v8a) 交叉编译 C/C 项目的完整脚本模板​​&#xff0c;基于 NDK 工具链&#xff0c;支持自定义源文件编译为静态库/动态库/可执行文件&#xff1a; 1. 基础交叉编译脚本 (build_android.sh) bash 复制 #!/bin/bash# Android 交叉编译脚本 (arm64-…...

IS-IS-单区域的配置

一、IS-IS的概念 IS-IS&#xff08;Intermediate System to Intermediate System&#xff0c;中间系统到中间系统&#xff09;是一种‌链路状态路由协议‌&#xff0c;最初设计用于‌OSI&#xff08;Open Systems Interconnection&#xff09;参考模型‌的网络层&#xff08;CL…...

Java EE期末总结(第四章)

目录 一、ORM框架 二、MyBatis与Hibernate 1、 概念与设计理念 2、SQL 控制 3、学习成本 4、开发效率 三、MyBatisAPI 1、SqlSessionFactoryBuilder 2、SqlSessionFactory 3、SqlSession 四、MyBatis配置 1、核心依赖与日志依赖 2、建立.XML映射文件 3、建立映射…...

Kafka 的选举机制

Kafka 的选举机制在 Zookeeper 模式 和 KRaft 模式 下有所不同&#xff0c;主要体现在 领导选举 和 集群元数据管理 的方式上。下面详细介绍这两种模式下 Kafka 如何进行选举机制。 1. Zookeeper 模式下的选举机制 在早期的 Kafka 架构中&#xff0c;集群的元数据管理和选举机…...

FreeRTOS移植笔记:让操作系统在你的硬件上跑起来

一、为什么需要移植&#xff1f; FreeRTOS就像一套"操作系统积木"&#xff0c;但不同硬件平台&#xff08;如STM32、ESP32、AVR等&#xff09;的CPU架构和外设差异大&#xff0c;需要针对目标硬件做适配配置。移植工作就是让FreeRTOS能正确管理你的硬件资源。 二、…...

设计模式简述(十二)策略模式

策略模式 描述基本使用使用传统策略模式的缺陷以及规避方法 枚举策略描述基本使用使用 描述 定义一组策略&#xff0c;并将其封装起来到一个策略上下文中。 由调用者决定应该使用哪种策略&#xff0c;并且可以动态替换 基本使用 定义策略接口 public interface IStrategy {…...

如何在idea中快速搭建一个Spring Boot项目?

文章目录 前言1、创建项目名称2、勾选需要的依赖3、在setting中检查maven4、编写数据源5、开启热启动&#xff08;热部署&#xff09;结语 前言 Spring Boot 凭借其便捷的开发特性&#xff0c;极大提升了开发效率&#xff0c;为 Java 开发工作带来诸多便利。许多大伙伴希望快速…...

【注解简化配置的原理是什么】

注解&#xff08;Annotation&#xff09;简化配置的核心原理是将原本分散在外部文件&#xff08;如XML、properties&#xff09;中的元数据直接内嵌到代码中&#xff0c;通过声明式编程让框架或工具自动处理这些元数据&#xff0c;从而减少手动配置的复杂度。以下是其实现原理的…...

Livox-Mid-70雷达使用------livox_mapping建图

1.ubuntu20.04 和Livox mid 70 的IP设置 连接好Livox-Mid-70雷达,然后进行局域网配置 1.1 Livox mid 70的IP是已知的&#xff0c;即192.168.1.1XX, XX表示mid 70广播码的后两位 1.2 ubuntu 20.04的IP设置 a.查看本机IP名 ifconfig b.设置本机IP地址 sudo ifconfig enx00e04…...

Django中使用不同种类缓存的完整案例

Django中使用不同种类缓存的完整案例 推荐超级课程: 本地离线DeepSeek AI方案部署实战教程【完全版】Docker快速入门到精通Kubernetes入门到大师通关课AWS云服务快速入门实战目录 Django中使用不同种类缓存的完整案例步骤1:设置Django项目步骤2:设置URL路由步骤3:视图级别…...

代码随想录算法训练营Day32| 完全背包问题(二维数组 滚动数组)、LeetCode 518 零钱兑换 II、377 组合总数 IV、爬楼梯(进阶)

理论基础 完全背包问题 在完全背包问题中&#xff0c;每种物品都有无限个&#xff0c;我们可以选择任意个数&#xff08;包括不选&#xff09;&#xff0c;放入一个容量为 W W W 的背包中。我们希望在不超过容量的情况下&#xff0c;最大化背包内物品的总价值。 完全背包&a…...

Django SaaS案例:构建一个多租户博客应用

Django SaaS案例:构建一个多租户博客应用 推荐超级课程: 本地离线DeepSeek AI方案部署实战教程【完全版】Docker快速入门到精通Kubernetes入门到大师通关课AWS云服务快速入门实战目录 Django SaaS案例:构建一个多租户博客应用如果你正在从事一个SaaS(软件即服务)项目或一…...

静态库与动态库

静态库&#xff08;Static Library&#xff09; 定义&#xff1a;静态库&#xff08;如 .a 文件或 .lib 文件&#xff09;是编译时直接链接到可执行文件中的库。其代码和数据会被完整复制到最终的可执行文件中。 特点&#xff1a; 独立部署&#xff1a;无需依赖外部库文件。 …...

优选算法的妙思之流:分治——归并专题

专栏&#xff1a;算法的魔法世界 个人主页&#xff1a;手握风云 目录 一、归并排序 二、例题讲解 2.1. 排序数组 2.2. 交易逆序对的总数 2.3. 计算右侧小于当前元素的个数 2.4. 翻转对 一、归并排序 归并排序也是采用了分治的思想&#xff0c;将数组划分为多个长度为1的子…...

PDFBox渲染生成pdf文档

使用PDFBox可以渲染生成pdf文档&#xff0c;并且自定义程度高&#xff0c;只是比较麻烦&#xff0c;pdf的内容位置都需要手动设置x&#xff08;横向&#xff09;和y&#xff08;纵向&#xff09;绝对位置&#xff0c;但是每个企业的单据都是不一样的&#xff0c;一般来说都会设…...

flutter dio网络请求与json数据解析

在Flutter中&#xff0c;Dio 是一个功能强大且易于使用的网络请求库&#xff0c;用于处理HTTP请求和响应。与 http 包相比&#xff0c;Dio 提供了更多高级功能&#xff0c;例如拦截器、文件上传/下载、请求取消等。结合 json_serializable 或手动解析 JSON 数据&#xff0c;可以…...

7. RabbitMQ 消息队列——延时队列(Spring Boot + 安装message_exchange“延迟插件“ 的详细配置说明)的详细讲解

7. RabbitMQ 消息队列——延时队列(Spring Boot 安装message_exchange"延迟插件" 的详细配置说明)的详细讲解 文章目录 7. RabbitMQ 消息队列——延时队列(Spring Boot 安装message_exchange"延迟插件" 的详细配置说明)的详细讲解1. RabbitMQ 延时队列概…...

使用 MyBatis-Plus 实现高效的 Spring Boot 数据访问层

在开发 Spring Boot 应用时&#xff0c;数据访问是不可或缺的部分。为了提高开发效率并减少样板代码&#xff0c;MyBatis-Plus 提供了强大的功能&#xff0c;能够简化与数据库交互的操作。本文将详细介绍如何在 Spring Boot 中使用 MyBatis-Plus&#xff0c;并结合具体代码示例…...

Linux学习笔记——零基础详解:什么是Bootloader?U-Boot启动流程全解析!

零基础详解&#xff1a;什么是Bootloader&#xff1f;U-Boot启动流程全解析&#xff01; 一、什么是Bootloader&#xff1f;&#x1f4cc; 举个例子&#xff1a; 二、U-Boot 是什么&#xff1f;三、U-Boot启动过程&#xff1a;分为两个阶段&#x1f539; 第一阶段&#xff08;汇…...

网络初识 - Java

网络发展史&#xff1a; 单机时代&#xff08;独立模式&#xff09; -> 局域网时代 -> 广域网时代 -> 移动互联网时代 网络互联&#xff1a;将多台计算机链接再一起&#xff0c;完成数据共享。 数据共享的本质是网络数据传输&#xff0c;即计算机之间通过网络来传输数…...

(51单片机)独立按键控制流水灯LED流向(独立按键教程)(LED使用教程)

源代码 如上图将7个文放在Keli5 中即可&#xff0c;然后烧录在单片机中就行了 烧录软件用的是STC-ISP&#xff0c;不知道怎么安装的可以去看江科大的视频&#xff1a; 【51单片机入门教程-2020版 程序全程纯手打 从零开始入门】https://www.bilibili.com/video/BV1Mb411e7re?…...

QML输入控件: TextArea的应用(带行号的编辑器)

目录 引言&#x1f4da; 相关阅读&#x1f528;BUG修复实现思路代码解析主窗口代码自定义TextAreaItem组件行号显示部分文本编辑区域滚动同步 关键功能解析1. 动态更新行号2. 属性映射3. 外观定制 运行效果总结工程下载 引言 在开发Qt/QML应用程序时&#xff0c;文本编辑功能是…...

kafka 的存储文件结构

Kafka 的存储文件结构是其高吞吐量和高效性能的关键部分。Kafka 的存储结构是围绕 日志&#xff08;Log&#xff09; 的设计展开的&#xff0c;而每个 Kafka 分区&#xff08;Partition&#xff09; 都会以日志文件的形式存储。Kafka 采用了顺序写入、分段存储和索引文件的机制…...

FAISS原理深度剖析与LLM检索分割难题创新解决方案

一、FAISS核心技术解构&#xff1a;突破传统检索的次元壁 1.1 高维空间的降维艺术 FAISS&#xff08;Facebook AI Similarity Search&#xff09;通过独创的Product Quantization&#xff08;乘积量化&#xff09;技术&#xff0c;将高维向量空间切割为多个正交子空间。每个子…...

Windows操作系统安全配置(一)

1.操作系统和数据库系统管理用户身份标识应具有不易被冒用的特点&#xff0c;口令应有复杂度要求并定期更换 配置方法&#xff1a;运行“gpedit.msc”计算机配置->Windows设置->安全设置>帐户策略->密码策略: 密码必须符合复杂性要求->启用 密码长度最小值->…...

JavaScript promise实例——通过XHR获取省份列表

文章目录 需求和步骤代码示例效果 需求和步骤 代码示例 <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><!-- 确保IE浏览器使用最新的渲染引擎 --><meta http-equiv"X-UA-Compatible" conten…...

【力扣hot100题】(065)搜索旋转排序数组

难点在于情况真的很多需要逐一判断&#xff0c;画个走向图再写判断条件就行了。 还有处理边界条件也比较麻烦。 class Solution { public:int search(vector<int>& nums, int target) {int left0;int rightnums.size()-1;while(left<right){int mid(leftright)/…...

毕设论文的分类号与UDC查询的网站

毕业论文分类号 中图分类号查询链接 找到自己的细分类&#xff0c;一个一个点就好&#xff0c;然后就找到了 毕业论文UDC UDC查询...

pyqt5实现多个窗口互相调用

使用以下代码可以实现多窗口之间的相互调用&#xff1a; import sys from PyQt5.QtWidgets import QApplication, QMainWindow import win0, win1, win2, win3 # 分别包含 Ui_win0 和 Ui_win1class Win0Window(QMainWindow, win0.Ui_win0):def __init__(self, x, parentNone)…...

Python基于Django的企业it资产管理系统(附源码,文档说明)

博主介绍&#xff1a;✌IT徐师兄、7年大厂程序员经历。全网粉丝15W、csdn博客专家、掘金/华为云//InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&#x1f3…...