下面文章内容转自 fnky 将英文内容翻译成中文以下内容为中文翻译内容ANSI 转义序列标准的转义码以前缀 Escape 开头：Ctrl-键：^[八进制：\033Unicode：\u001b十六进制：\x1B十进制：27其后跟随命令，有时用左方括号 ([) 分隔，称为控制序列引导符 (CSI)，可选地后跟参数和命令本身。参数用分号 (;) 分隔。例如：\x1b[1;31m # 设置样式为粗体，红色前景。序列ESC - 以 ESC (\x1B) 开头的序列CSI - 控制序列引导符：以 ESC [ 或 CSI (\x9B) 开头的序列DCS - 设备控制字符串：以 ESC P 或 DCS (\x90) 开头的序列OSC - 操作系统命令：以 ESC ] 或 OSC (\x9D) 开头的序列序列和参数之间的任何空格都应被忽略。它们的存在是为了提高可读性。通用 ASCII 码名称十进制八进制十六进制C-转义Ctrl-键描述BEL70070x07\a^G终端铃声BS80100x08\b^H退格HT90110x09\t^I水平制表符LF100120x0A\n^J换行 (新行)VT110130x0B\v^K垂直制表符FF120140x0C\f^L换页 (也称：新页 NP)CR130150x0D\r^M回车ESC270330x1B\e*^[转义字符DEL1271770x7F<none><none>删除字符注意： 一些控制转义序列，例如 \e 代表 ESC，并不能保证在所有语言和编译器中都有效。建议使用十进制、八进制或十六进制表示作为转义码。注意： Ctrl-键 表示法只是将 ASCII 码 1 开始的不可打印字符与 ASCII 码 65 ("A") 开始的可打印（字母）字符相关联。ASCII 码 1 将是 ^A (Ctrl-A)，而 ASCII 码 7 (BEL) 将是 ^G (Ctrl-G)。这是一种常见的表示法（和输入方法），历史上源于 VT 系列终端之一。光标控制ESC 码序列描述ESC[H将光标移动到起始位置 (0, 0)ESC[{行};{列}H ESC[{行};{列}f将光标移动到指定行号、列号ESC[#A将光标向上移动 # 行ESC[#B将光标向下移动 # 行ESC[#C将光标向右移动 # 列ESC[#D将光标向左移动 # 列ESC[#E将光标移动到下一行的开头，向下 # 行ESC[#F将光标移动到上一行的开头，向上 # 行ESC[#G将光标移动到指定列 #ESC[6n请求光标位置 (报告为 ESC[#;#R)ESC M将光标向上移动一行，如果需要则滚动ESC 7保存光标位置 (DEC)ESC 8将光标恢复到上次保存的位置 (DEC)ESC[s保存光标位置 (SCO)ESC[u将光标恢复到上次保存的位置 (SCO)注意： 一些序列，例如保存和恢复光标，是私有序列，并未标准化。虽然一些终端模拟器（例如 xterm 及其衍生版本）同时支持 SCO 和 DEC 序列，但它们的功能可能不同。因此，建议使用 DEC 序列。清除功能ESC 码序列描述ESC[J清除显示内容 (等同于 ESC[0J)ESC[0J从光标位置清除到屏幕末尾ESC[1J从光标位置清除到屏幕开头ESC[2J清除整个屏幕ESC[3J清除已保存的行ESC[K清除行内内容 (等同于 ESC[0K)ESC[0K从光标位置清除到行尾ESC[1K从行首清除到光标位置ESC[2K清除整行注意：清除行不会移动光标，这意味着光标将停留在清除行之前的最后位置。你可以在清除行后使用 \r 将光标返回到当前行的开头。颜色 / 图形模式ESC 码序列重置序列描述ESC[1;34;{...}m 设置单元格的图形模式，用分号 (;) 分隔。ESC[0m 重置所有模式 (样式和颜色)ESC[1mESC[22m设置粗体模式。ESC[2mESC[22m设置暗淡/浅色模式。ESC[3mESC[23m设置斜体模式。ESC[4mESC[24m设置下划线模式。ESC[5mESC[25m设置闪烁模式ESC[7mESC[27m设置反相/反转模式ESC[8mESC[28m设置隐藏/不可见模式ESC[9mESC[29m设置删除线模式。注意： 某些终端可能不支持上面列出的某些图形模式序列。注意： 暗淡和粗体模式都使用 ESC[22m 序列重置。ESC[21m 序列是双下划线模式的非指定序列，仅在某些终端中有效，并使用 ESC[24m 重置。颜色代码大多数终端支持 8 色和 16 色，以及 256 色 (8 位)。这些颜色由用户设置，但具有通常定义的含义。8-16 色颜色名称前景色代码背景色代码黑色3040红色3141绿色3242黄色3343蓝色3444洋红色3545青色3646白色3747默认3949除了基本的 8 种颜色外，大多数终端还支持“亮色”或“粗体”颜色。它们有自己的一组代码，与普通颜色类似，但在其代码中附加了一个 ;1：# 设置样式为粗体，红色前景。 \x1b[1;31mHello # 设置样式为暗淡的白色前景和红色背景。 \x1b[2;37;41mWorld支持 aixterm 规范 的终端提供 ISO 颜色的亮色版本，无需使用粗体修饰符：颜色名称前景色代码背景色代码亮黑色90100亮红色91101亮绿色92102亮黄色93103亮蓝色94104亮洋红色95105亮青色96106亮白色97107256 色以下转义码告诉终端使用给定的颜色 ID：ESC 码序列描述ESC[38;5;{ID}m设置前景色。ESC[48;5;{ID}m设置背景色。其中 {ID} 应替换为以下颜色表中 0 到 255 的颜色索引：0-7: 标准颜色 (如 ESC [ 30–37 m)8–15: 高强度颜色 (如 ESC [ 90–97 m)16-231: 6 × 6 × 6 立方体 (216 种颜色): 16 + 36 × r + 6 × g + b (0 ≤ r, g, b ≤ 5)一些模拟器将这些步骤解释为所有三个通道上的线性增量 (256 / 24)，而其他模拟器可能明确定义这些值。232-255: 从暗到亮的 24 级灰度。RGB 颜色更现代的终端支持 真彩色 (24 位 RGB)，允许您使用 RGB 设置前景和背景颜色。这些转义序列通常没有详细的文档记录。ESC 码序列描述ESC[38;2;{r};{g};{b}m将前景色设置为 RGB。ESC[48;2;{r};{g};{b}m将背景色设置为 RGB。注意，;38 和 ;48 对应于 16 色序列，并由终端解释为分别设置前景和背景颜色。而 ;2 和 ;5 设置颜色格式。屏幕模式设置模式ESC 码序列描述ESC[={值}h将屏幕宽度或类型更改为值指定的模式。ESC[=0h40 x 25 单色 (文本)ESC[=1h40 x 25 彩色 (文本)ESC[=2h80 x 25 单色 (文本)ESC[=3h80 x 25 彩色 (文本)ESC[=4h320 x 200 4色 (图形)ESC[=5h320 x 200 单色 (图形)ESC[=6h640 x 200 单色 (图形)ESC[=7h启用换行ESC[=13h320 x 200 彩色 (图形)ESC[=14h640 x 200 彩色 (16色图形)ESC[=15h640 x 350 单色 (2色图形)ESC[=16h640 x 350 彩色 (16色图形)ESC[=17h640 x 480 单色 (2色图形)ESC[=18h640 x 480 彩色 (16色图形)ESC[=19h320 x 200 彩色 (256色图形)ESC[={值}l使用与设置模式相同的值重置模式，但 7 除外，它禁用换行。此转义序列中的最后一个字符是小写 L。常见的私有模式这些是一些私有模式的示例，它们没有被规范定义，但在大多数终端中都已实现。ESC 码序列描述ESC[?25l使光标不可见ESC[?25h使光标可见ESC[?47l恢复屏幕ESC[?47h保存屏幕ESC[?1049h启用备用缓冲区ESC[?1049l禁用备用缓冲区有关 XTerm 定义的更深入的私有模式列表，请参阅 XTerm 控制序列。注意：虽然这些模式可能受大多数终端支持，但有些可能无法在 tmux 等多路复用器中工作。键盘字符串ESC[{代码};{字符串};{...}p将键盘按键重新定义为指定的字符串。此转义序列的参数定义如下：代码 是下表中列出的一个或多个值。这些值表示键盘按键和组合键。在命令中使用这些值时，除了转义序列所需的分号外，还必须键入此表中显示的分号。括号中的代码在某些键盘上不可用。除非您在 ANSI.SYS 的 DEVICE 命令中指定 /X 开关，否则 ANSI.SYS 不会解释这些键盘的括号中的代码。字符串 是单个字符的 ASCII 码或包含在引号中的字符串。例如，65 和 "A" 都可以用来表示大写 A。重要提示： 下表中的某些值并非对所有计算机都有效。请查阅您计算机的文档以获取不同的值。键盘字符串列表按键代码SHIFT+代码CTRL+代码ALT+代码F10;590;840;940;104F20;600;850;950;105F30;610;860;960;106F40;620;870;970;107F50;630;880;980;108F60;640;890;990;109F70;650;900;1000;110F80;660;910;1010;111F90;670;920;1020;112F100;680;930;1030;113F110;1330;1350;1370;139F120;1340;1360;1380;140HOME (数字键盘)0;71550;119--UP ARROW (数字键盘)0;7256(0;141)--PAGE UP (数字键盘)0;73570;132--LEFT ARROW (数字键盘)0;75520;115--RIGHT ARROW (数字键盘)0;77540;116--END (数字键盘)0;79490;117--DOWN ARROW (数字键盘)0;8050(0;145)--PAGE DOWN (数字键盘)0;81510;118--INSERT (数字键盘)0;8248(0;146)--DELETE (数字键盘)0;8346(0;147)--HOME(224;71)(224;71)(224;119)(224;151)UP ARROW(224;72)(224;72)(224;141)(224;152)PAGE UP(224;73)(224;73)(224;132)(224;153)LEFT ARROW(224;75)(224;75)(224;115)(224;155)RIGHT ARROW(224;77)(224;77)(224;116)(224;157)END(224;79)(224;79)(224;117)(224;159)DOWN ARROW(224;80)(224;80)(224;145)(224;154)PAGE DOWN(224;81)(224;81)(224;118)(224;161)INSERT(224;82)(224;82)(224;146)(224;162)DELETE(224;83)(224;83)(224;147)(224;163)PRINT SCREEN----0;114--PAUSE/BREAK----0;0--BACKSPACE88127(0)ENTER13--10(0TAB90;15(0;148)(0;165)NULL0;3------A976510;30B986620;48C996630;46D1006840;32E1016950;18F1027060;33G1037170;34H1047280;35I1057390;23J10674100;36K10775110;37L10876120;38M10977130;50N11078140;49O11179150;24P11280160;25Q11381170;16R11482180;19S11583190;31T11684200;20U11785210;22V11886220;47W11987230;17X12088240;45Y12189250;21Z12290260;4414933--0;1202506400;12135135--0;12245236--0;12355337--0;12465494300;12575538--0;12685642--0;12695740--0;12704841--0;129-4595310;130=6143---0;131[91123270;26]93125290;27 92124280;43;5958--0;39'3934--0;40,4460--0;51.4662--0;52/4763--0;53`96126--(0;41)ENTER (小键盘)13--10(0;166)/ (小键盘)4747(0;142)(0;74)* (小键盘)42(0;144)(0;78)--- (小键盘)4545(0;149)(0;164)+ (小键盘)4343(0;150)(0;55)5 (小键盘)(0;76)53(0;143)--资源维基百科：ANSI 转义码使用 ANSI 转义码构建您自己的命令行ascii-table: ANSI 转义序列bluesock: ansi codesbash-hackers: 终端代码 (ANSI/VT100) 简介XTerm 控制序列VT100 – 各种终端手册xterm.js – 支持的终端序列
下面是官方给的github项目，也有详细的安装Fast MCP 的步骤 Fast MCP 在此之前需要安装uv的包管理工具，这里提供 PowerShell 的安装方法，安装完成后可通过输入命令uv查看是否安装成功。irm https://astral.sh/uv/install.ps1 | iex注意：这里如果你通过uv add添加包时候提示如下内容，代表未运行uv init命令初始化Python项目。1.创建一个目录，并初始化项目创建完成后会在目录生成几个文件2.添加mcp相关依赖uv add mcp[cli]安装完成后就可以在目录使用Python开发MCP Server了3.写一个简单的加法方法from mcp.server.fastmcp import FastMCP mcp = FastMCP("wb-mcp") @mcp.tool(description="Add two numbers together") def add(a: int, b: int) -> int: """ Add two numbers together :param a: The first number :param b: The second number :return: The sum of the two numbers """ return a + b def main(): print("Hello from wb-mcp!") mcp.run() if __name__ == "__main__": main() 4.添加到 Roo 等大模型工具中在新的Roo Code版本更新了全局和项目的mcp环境配置，这里配置全局环境。在mcpServer中配置，这里名称根据自己的mcp名称修改 "we-mcp": { "command": "uv", "args": [ "run", "main.py" ] }MCP Server 运行正常可以使用大模型调用mcp测试一下，查看结果是否正确，这里使用Roo Code 插件，服务商是阿里云的百炼的API调用DeepSeek-R1模型
最近 AI 使用 MCP Server 比较热门，下面是介绍如何在 Window 系统上的 VSCode 中配置 MCP 服务 的方法。插件安装如果你还没有安装 Cline/Roo Code 拓展，根据下述流程可以安装。首先在 VSCode 左侧菜单点击拓展在搜索框搜索 Cline 或 Roo Code （原名 Roo Cline）下面使用 Roo Code 作为演示搜索后右下角会有蓝色安装(Install)按钮，点击安装安装完成后左边菜单栏会多一个火箭图标，代表拓展安装完成！MCP Server 安装点击左侧拓展图标后弹出下面的页面，点击图中红色框的按钮来配置MCP Server,Cline为第二张图。跳出界面后点击图中[1]的编辑MCP配置(Configure MCP Servers)按钮，右侧[2]处会弹出配置文件，下面所有的插件都在这个 mcpServers 中进行配置。官方有社区提供的MCP Server 点击下面的跳转 GitHub 官方MCP Server Sequential Thinking MCP Server这里我安装 Sequential Thinking 作为演示，在提供的社区MCP Server中找到 Sequential Thinking并点击蓝色链接。文章下方会有给出的配置 JSON 这里将 npx 配置方式复制到 VSCode 打开的配置文件中。如下所示{ "mcpServers": { "sequential-thinking": { "command": "npx", "args": [ "-y", "@modelcontextprotocol/server-sequential-thinking" ] } } }这里因为时 Window 需要修改一下配置，将 command 改为 cmd ， args 中添加 /c 和 npx 后保存。{ "mcpServers": { "sequential-thinking": { "command": "cmd", "args": [ "/c", "npx", "-y", "@modelcontextprotocol/server-sequential-thinking" ] } } }保存后右侧就会显示刚刚写好的配置项。如有报错请点击左侧文章标题跳转至安装错误修复安装完成后右侧会显示个小绿灯。自此 MCP Server 安装完成，你可以在项目中使用。filesystem MCP Server如果位置找不到请看第一个 MCP 安装方法走网站上复制安装json，这里注意一下json中的 /Users/username/Desktop 和 /path/to/other/allowed/dir 代表插件可以操作的目录，根据自己的要求进行配置截图中是我配置的。如有报错请点击左侧文章标题跳转至安装错误修复 "filesystem": { "command": "cmd", "args": [ "/c", "npx", "-y", "@modelcontextprotocol/server-filesystem", "/Users/username/Desktop", "/path/to/other/allowed/dir" ] },安装错误修复看一眼下面tips ::(喷) ::(喷) ::(喷) {message type="info" content="这里安装其他MCP Server也碰到除了下面的各种各样的npx问题，有点玄学。。。在操作重装VSCode(应该不是这个问题)，Node.js重装后不需要在命令中 设置 set APPDATA 就能运行了,其他的尝试执行一下问题1 的解决方法看看有没有用 。"/}问题1执行的时候提示没有这个命令（这个乱码意思）解决方法npx 清除一下缓存可能需要安装npx clear-npx-cache问题2如果你安装的时候出现了类似 ${APPDATA} 找不到路径可用下面方法解决。解决方法原因可能是环境原因导致的在配置项中指明 APPDATA，这里Admin需要换成你的用户名，具体可到C:\User\中查看。这里的set要加npx的上面，其他MCP遇到此问题也是一样的。{ "mcpServers": { "sequential-thinking": { "command": "cmd", "args": [ "/c", "set APPDATA=C:\\Users\\Admin\\AppData\\Roaming&&", "npx", "-y", "@modelcontextprotocol/server-sequential-thinking" ] } } }
Chrome 拓展开发网页呼出Popup类似在网页中需要插件登录、授权等操作的时候呼出Popup 来做进一步的操作。需要通过拓展中的Content Script进行中转。1.一个是网页（触发操作），通过window中的postMessage 发送一个操作如下。document.getElementById('loginButton').addEventListener('click', () => { // 向 Content Script 发送消息 window.postMessage({ type: 'EXTENSION_REQUEST', action: 'showAuthPopup' }, '*'); });你需要创建一个 content-script 的插入脚本 在 manifest 文件中配置。例如 "content_scripts": [ { "matches": ["*://example.com/*"], "js": ["content.js"], "css": ["example.css"], "run_at": "document_idle" } ],在文件中写入 以下内容，这里可以通过event.data拿到网页发送的所有数据，这里根据业务需求可以做过滤，也可以只作为一个转发功能拿到data后直接发送。// content-script.js window.addEventListener('message', (event) => { if (event.data.type === 'EXTENSION_REQUEST') { // 调用扩展的 API 向 Background Script 发送消息 chrome.runtime.sendMessage({ action: 'showAuthPopup' }, (response) => { console.log('扩展响应:', response); }); } });你需要创建一个 background-script 的worker脚本 在 manifest 文件中配置。例如 "background": { "service_worker": "/background.js" },在 Background Script 中接收 Content Script 发来的内容，这里使用 chrome.action.openPopup(); 来呼出 Popupchrome.runtime.onMessage.addListener((request, sender, sendResponse) => { if (request.action === 'showAuthPopup') { // 尝试打开扩展的 popup chrome.action.openPopup(); // 需要用户已配置图标或快捷键 // 如果失败，提示用户手动操作 if (!chrome.action.openPopup()) { chrome.notifications.create({ type: 'basic', iconUrl: 'icon.png', title: '授权请求', message: '请单击插件图标进行授权登录' }); } sendResponse({ success: true }); } });
基础概念{dotted startColor="#ff6c6c" endColor="#1989fa"/}:@(高兴) 简单来说 数据 是 所有信息的总称 ，而 数据元素 、 数据项 和 数据对象 则是对 数据 进行 组织和分类 的 不同层次的概念 。 从微观到宏观的角度来看： 数据元素 是 最小单位 数据项 是 数据元素的组合 数据对象 是 数据项的集合 而这一切都构成了广义上的数据。下面的是单个的字段解释。 {dotted startColor="#ff6c6c" endColor="#1989fa"/}数据（Data）数据是指所有可以被收集、存储、处理和传播的信息的集合。它可以是数字、文字、图像、声音等任何形式的信息。数据是信息的基础，未经加工的数据本身并不携带意义。数据元素（Data Element）数据元素是数据的基本单位，它是数据集中最小的、不可再分的数据单元。例如，在一个学生信息表中，“姓名”、“年龄”、“性别”等都是数据元素。数据项（Data Item）数据项有时也称为字段或属性，它是一个或一组值，通常用来描述某个实体的一个特定方面。数据项可以由一个或多个数据元素组成。例如，在记录一个学生的成绩时，“数学成绩”就是一个数据项，它可能包含具体的分数值。数据对象（Data Object）数据对象是一组相关的数据元素的集合，这些数据元素共同描述了一个实体的状态。数据对象可以看作是现实世界中某个具体事物的抽象表示。例如，一个学生的全部信息（包括姓名、年龄、性别、成绩等）可以被看作是一个数据对象。{dotted startColor="#ff6c6c" endColor="#1989fa"/}:@(高兴) 好，在上面的四个概念的内容后，下面将引入数据结构这个概念，简单来讲数据结构就是多个数据对象之间存在的关系的集合，是计算机中组织、管理和存储数据的方式，以便高效地访问和修改。多个数据对象之间，如A、B、C、D 可以用不同的结构进行表示，具体选择哪种结构取决于应用场景和需求。下面的是单个的字段解释。{dotted startColor="#ff6c6c" endColor="#1989fa"/}数据结构（Data Structure）一种数据组织、管理和存储的格式。它是相互之间存在一种或多种特定关系的数据元素的集合。通常情况下，精心选择的数据结构可以带来更高的运行或者存储效率。数据结构往往同高效的检索算法和索引技术相关。{dotted startColor="#ff6c6c" endColor="#1989fa"/}在数据结构中分逻辑结构和存储结构逻辑结构中分为以下四种结构：集合结构、线性结构、树结构、图结构/网状结构这里通过数据元素之间的关系进行区分类型集合结构：一个或多个数据元素是否属于某个集合，只有属于或不属于的关系。线性结构：一个数据元素和一个数据元素存在一对一的关联关系。更准确的表达数据元素之间存在一对一的前驱和后继关系，即每个元素（除第一个和最后一个外）都有一个唯一的前驱和一个唯一的后继。树结构：一个数据元素和多个数据元素存在一对多的关联关系。图结构/网状结构：多个数据元素和数据元素之间存在多对多的关联关系。此外在此基础上这四个结构还分为线性结构和非线性结构线性非线性线性结构集合结构、树结构、图结构/网状结构和它的名字一样除了线性结构其他都是非线性 ::(狂汗) 在这四个结构基础上可以分为这几类线性结构线性结构只有线性表一个分支，在线性表下分为三类：一般线性、特殊线性和线性表的推广一般线性一般线性表是最基础的线性结构，其中每个元素（除了第一个和最后一个）都有唯一的一个直接前驱和一个直接后继。线性表中的元素可以是任意类型的，如整数、字符等。常见的操作包括插入、删除、查找等。特殊线性特殊线性通常是指在线性表基础上添加了某些特定条件或限制的一类线性结构。例如：栈（Stack）：一种只能在一端进行插入或删除的线性表，遵循后进先出（LIFO）的原则。队列（Queue）：一种只能在表的一端进行插入而在另一端进行删除的线性表，遵循先进先出（FIFO）的原则。循环队列：通过首尾相接形成环状结构的队列，用于解决传统队列空间利用率不高的问题。双端队列（Deque）：允许两端进行插入和删除操作的队列。线性表的推广线性表的推广是指对传统线性表概念的扩展，以适应更复杂的数据组织需求。这类结构可能不再严格保持一对一的关系，但在某种程度上仍然保留了线性表的基本特性。例如：多重链表：每个节点可以有多个链接指向其他节点，这些链接可能指向同一层的不同节点或者不同层的节点，适用于表示多维数组或树形结构的一部分。双向链表：每个节点不仅包含指向下一个节点的指针，还包含指向前一个节点的指针，使得遍历方向更加灵活。跳表（Skip List）：一种可以在平均O(log n)时间内完成插入、删除和查找操作的数据结构，通过增加额外的层次来加速搜索过程。非线性结构在非线性下分为了三个分支：树结构、图结构、集合树结构树是一种非线性的数据结构，由一组节点组成，这些节点通过边连接起来，形成一个层次结构。树具有以下特点：根节点：树中唯一的没有前驱的节点。叶子节点：没有后继的节点。子树：除了根节点外，任何一个节点及其所有后代构成的树。路径：从一个节点到另一个节点的序列。深度：从根节点到某个节点的最长路径上的边数。高度：树中最长路径上的节点数。可以分为树和二叉树，两者最大的区别在于二叉树是一种特殊的树结构，其中每个节点最多有两个子节点，通常称为左子节点和右子节点，但是树每个节点可以有任意数量的子节点。图结构图结构是一种更通用的非线性数据结构，它由一组节点（顶点）和连接这些节点的边组成。图结构可以分为：无向图：边没有方向，即两个节点之间的边是双向的。有向图：边有方向，即从一个节点到另一个节点的边是单向的。在此基础上还可以对边加上权重，来表示距离、成本等参数。集合集合是一种抽象的数据类型，用于存储不重复的元素。集合的特点包括无序性：集合中的元素没有固定的顺序。唯一性：集合中的元素不能重复。动态性：集合可以动态地添加和删除元素。存储结构数据的逻辑结构在计算机中的存储方式，它是实现数据结构的基础，直接影响着数据的访问和修改效率。根据不同的应用场景和需求，存储结构可以分为以下两种主要类型顺序存储结构顺序存储结构是最直观的存储方式之一，它通过将数据元素存储在连续的内存空间中来实现。优点：支持随机访问，即可以通过数组下标直接访问任一元素，访问速度极快；存储密度大，因为每个元素占用的内存空间都是有效的。缺点：插入和删除操作效率较低，因为这两个操作通常需要移动大量元素以保持数组的连续性；此外，顺序存储结构的大小在创建时需要预先确定，不便于动态调整。链式存储结构链式存储结构通过指针将数据元素链接起来，每个元素（节点）不仅包含数据信息，还包含指向下一个元素的指针。优点：插入和删除操作效率高，因为这些操作只需要更改指针，而不需要移动元素；支持动态增长，可以根据需要随时添加或删除节点。缺点：不支持随机访问，必须从头节点开始逐个访问节点；存储密度较小，因为每个节点都需要额外的空间来存储指针。{dotted startColor="#ff6c6c" endColor="#1989fa"/}
安装MySQL首先在使用前，先安装MYSQL下载可通过下方链接https://dev.mysql.com/downloads/mysql/mysql-8.4.0 Linux通用https://cdn.mysql.com//Downloads/MySQL-8.4/mysql-community-server-8.4.0-1.el7.x86_64.rpm https://cdn.mysql.com//Downloads/MySQL-8.4/mysql-community-client-8.4.0-1.el7.x86_64.rpm https://cdn.mysql.com//Downloads/MySQL-8.4/mysql-community-libs-8.4.0-1.el7.x86_64.rpm https://cdn.mysql.com//Downloads/MySQL-8.4/mysql-community-common-8.4.0-1.el7.x86_64.rpmshow variables like '%skip_network%'create user 'repl'@'%' identified by '321654qaz.Q';GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';在从数据库中设置mysql 8.0之前和之后使用的命令不一样，例如8.0之前使用CHANGE MASTER TO MASTER_HOST='192.168.37.100',MASTER_PORT=3306,MASTER_USER='repl',MASTER_PASSWORD='321654qaz.Q';8.0之后使用CHANGE REPLICATION SOURCE TO SOURCE_HOST='192.168.37.100',SOURCE_PORT=3306,SOURCE_USER='repl',SOURCE_PASSWORD='321654. ![lwukeq09.png](https://blog.dfcraft.cn/usr/uploads/2024/05/1265215117.png) ';START REPLICASHOW REPLICA STATUS G;
CLI提示：CLI命令界面在使用前需要管理员权限命令查看服务状态/获取个人网络IDzerotier-cli status加入退出网络/获取网络列表加入网络，需要提供十六位网络IDzerotier-cli join 网络ID退出网络，需要提供十六位网络IDzerotier-cli leave 网络ID获取本地zerotier网络列表zerotier-cli listnetworks在通过查看网络列表时会带上网络连接状态网络状态码状态解释OK成功连接到网络REQUESTING_CONFIGURATION连接网络控制器进行协商NOT_FOUND未找到当前网络ACCESS_DENIED拒绝访问，需网络授权才可访问PORT_ERROR连接出错，可以通过文档排查
接口文档获取时间区间内的订单数据http请求方式：POST请求地址：http://IP:8999/dataVisualization/selectOrderInfo请求参数：字段说明类型是否必填startTime开始时间String是endTime结束时间String是请求格式：{ "startTime":"2020-01-01 00:00:00", "endTime":"2020-12-30 00:00:00" }返回参数： id : 主键 finalTotalAmount ：总金额 outTradeNo ：订单交易编号（第三方支付用) provinceName ：省名称 regionName ：地区名称 userName : 用户名 请求成功:{ "msg": "操作成功", "code": 200, "data": [ { "id": 78506, "finalTotalAmount": 305062.00, "outTradeNo": "756847726439369", "provinceName": "北京", "regionName": "华北", "userName": "华馥" }, { "id": 78559, "finalTotalAmount": 6111.00, "outTradeNo": "341957455961748", "provinceName": "北京", "regionName": "华北", "userName": "罗菊兰" }, { "id": 78568, "finalTotalAmount": 84610.00, "outTradeNo": "489992944636772", "provinceName": "北京", "regionName": "华北", "userName": "毛岚" }, … ] } 查询每年上架的商品http请求方式：POST请求地址：http://IP:8999/dataVisualization/selectGoodsInfo请求参数:字段说明类型是否必填无---返回参数： id : 编号 price ：总金额 skuName ：商品名称 year ：年份 请求成功：{ "msg": "操作成功", "code": 200, "data": [ { "id": 1, "price": 2220, "skuName": "荣耀10青春版 幻彩渐变 2400万AI自拍 全网通版4GB+64GB 渐变蓝 移动联通电信4G全面屏手机 双卡双待", "year": "2019" }, { "id": 2, "price": 3321, "skuName": "TCL 55A950C 55英寸32核人工智能 HDR曲面超薄4K电视金属机身（枪色）", "year": "2019" }, { "id": 3, "price": 3100, "skuName": "小米（MI）电视 55英寸曲面4K智能WiFi网络液晶电视机4S L55M5-AQ 小米电视4S 55英寸 曲面", "year": "2019" }, ... ] }前置这里定义了一个 request 方法来获取数据数据async request(callback){ var _this = this; var myHeaders = new Headers(); myHeaders.append("Content-Type", "application/json"); var raw = JSON.stringify({ "startTime": "2020-01-01 00:00:00", "endTime": "2020-12-30 00:00:00" }); var requestOptions = { method: 'POST', headers: myHeaders, body: raw, redirect: 'follow' }; await fetch("http://localhost:3000/api/dataVisualization/selectOrderInfo", requestOptions) .then(response => response.json()) .then(result => { _this.OrderInfo = result["data"] }) .catch(error => console.log('error', error)); await fetch("http://localhost:3000/api/dataVisualization/selectGoodsInfo", requestOptions) .then(response => response.json()) .then(result => { _this.GoodsInfo = result["data"] }) .catch(error => console.log('error', error)); }题目任务一：用柱状图展示消费额最高的省份编写Vue工程代码，根据接口，用柱状图展示2020年消费额最高的5个省份，同时将用于图表展示的数据结构在浏览器的console中进行打印输出，将图表可视化结果和浏览器console打印结果分别截图并粘贴至对应报告中。代码 task1(){ var pc = echarts.init(document.getElementsByClassName("ec")[0]) var ls = [] var data = [] this.OrderInfo.forEach(ele=>{ var index = ls.indexOf(ele["provinceName"]) if(index == -1){ ls.push(ele["provinceName"]) data.push({ provinceName:ele["provinceName"], finalTotalAmount:ele["finalTotalAmount"] }) }else{ data[index]["finalTotalAmount"] += ele["finalTotalAmount"] } }) let top5 = data.sort((a,b)=>b["finalTotalAmount"]-a["finalTotalAmount"]).slice(0,5) let abb = [[],[]] top5.forEach(res=>{ abb[0].push(res["provinceName"]) abb[1].push(res["finalTotalAmount"]) }) console.log("===========第一题==========") console.log(abb[0]) console.log(abb[1]) var option = { title:{ text:"任务一：用柱状图展示消费额最高的省份" }, xAxis:{ data:abb[0] }, yAxis:{}, series:[ { type:"bar", data:abb[1] } ] } pc.setOption(option) },结果任务二：用饼状图展示各地区消费能力编写Vue工程代码，根据接口，用饼状图展示2020年各地区的消费总额占比，同时将用于图表展示的数据结构在浏览器的console中进行打印输出，将图表可视化结果和浏览器console打印结果分别截图并粘贴至对应报告中。代码 task2(){ var pc = echarts.init(document.getElementsByClassName("ec")[1]) var ls = [] var data = [] var total = 0 this.OrderInfo.forEach(ele=>{ var index = ls.indexOf(ele["regionName"]) if(index == -1){ ls.push(ele["regionName"]) data.push({ name:ele["regionName"], value:ele["finalTotalAmount"] }) total += ele["finalTotalAmount"] }else{ data[index]["value"] += ele["finalTotalAmount"] total += ele["finalTotalAmount"] } }) data.forEach((item,key)=>{ data[key]["value"] = data[key]["value"] / total * 100 }) console.log("===========第二题==========") console.log(data) var option = { title:{ text:"任务二：用饼状图展示各地区消费能力" }, series:[ { type:"pie", data:data } ] } pc.setOption(option) },结果任务三：用散点图展示每年上架商品数量的变化编写Vue工程代码，根据接口，用基础散点图展示每年上架商品数量的变化情况，同时将用于图表展示的数据结构在浏览器的console中进行打印输出，将图表可视化结果和浏览器console打印结果分别截图并粘贴至对应报告中。代码 task3(){ var pc = echarts.init(document.getElementsByClassName("ec")[2]) var ls = [] var data = [] this.GoodsInfo.forEach(ele=>{ var index = ls.indexOf(ele["year"]) if(index == -1){ ls.push(ele["year"]); data.push([ele["year"],1]); }else{ data[index][1] += 1; } }) console.log("===========第三题==========") console.log(data) var option = { title:{ text:"任务三：用散点图展示每年上架商品数量的变化" }, xAxis:{type:"value",name: '年份',min:2000}, yAxis:{type:"value",name: '数量',}, series:[ { symbolSize: (size)=>{ if(size[1]<1000){ return 20 }else{ return size[1] *= 0.009 } }, type:"scatter", data:data } ] } pc.setOption(option) },结果任务四：用条形图展示平均消费额最高的省份编写Vue工程代码，根据接口，用条形图展示2020年平均消费额（四舍五入保留两位小数）最高的5个省份，同时将用于图表展示的数据结构在浏览器的console中进行打印输出，将图表可视化结果和浏览器console打印结果分别截图并粘贴至对应报告中。代码 task4(){ var pc = echarts.init(document.getElementsByClassName("ec")[3]) var ls = [] var data = [] this.OrderInfo.forEach(ele=>{ var index = ls.indexOf(ele["provinceName"]) if(index == -1){ ls.push(ele["provinceName"]); data.push([ele["provinceName"],ele["finalTotalAmount"],1]); }else{ data[index][2] += 1; data[index][1] += ele["finalTotalAmount"]; } }) var li = [] data.forEach(it=>{ li.push([it[0],(it[1]/it[2]).toFixed(2)*1]) }) var als = [[],[]] li.sort((a,b)=>b[1]-a[1]) li.slice(0,5).forEach(it=>{ als[0].push(it[0]) als[1].push(it[1]) }) console.log("===========第四题==========") console.log(als[0]) console.log(als[1]) var option = { title:{ text:"任务四：用条形图展示平均消费额最高的省份" }, xAxis:{type:"value"}, yAxis:{data:als[0]}, series:[ { type:"bar", data:als[1] } ] } pc.setOption(option) },结果任务五：用折柱混合图展示省份平均消费额和地区平均消费额编写Vue工程代码，根据接口，用折柱混合图展示2020年各省份平均消费额（四舍五入保留两位小数）和地区平均消费额（四舍五入保留两位小数）的对比情况，柱状图展示平均消费额最高的5个省份，折线图展示这5个省所在的地区的平均消费额变化，同时将用于图表展示的数据结构在浏览器的console中进行打印输出，将图表可视化结果和浏览器console打印结果分别截图并粘贴至对应报告中。代码 task5(){ var pc = echarts.init(document.getElementsByClassName("ec")[4]) var ls = [] var data = [] // 省份平均消费额 this.OrderInfo.forEach(ele=>{ var index = ls.indexOf(ele["provinceName"]) if(index == -1){ ls.push(ele["provinceName"]); data.push([ele["provinceName"],ele["finalTotalAmount"],1,ele["regionName"]]); }else{ data[index][2] += 1; data[index][1] += ele["finalTotalAmount"]; } }) var li = [] data.forEach(it=>{ li.push([it[0],(it[1]/it[2]).toFixed(2)*1,it[3]]) }) var als = [[],[],[]] li.sort((a,b)=>b[1]-a[1]) li.slice(0,5).forEach(it=>{ als[0].push(it[0]) als[1].push(it[1]) als[2].push(it[2]) }) // 地区平均消费额 var a1 = [] var a2 = {} this.OrderInfo.forEach(ele=>{ var index = a1.indexOf(ele["regionName"]) if(index == -1){ a1.push(ele["regionName"]) a2[ele["regionName"]] = { finalTotalAmount:ele["finalTotalAmount"], total:1 } }else{ a2[ele["regionName"]]["finalTotalAmount"] += ele["finalTotalAmount"] a2[ele["regionName"]]["total"] += 1 } }) let a3 = [] als[2].forEach(res=>{ a3.push((a2[res]["finalTotalAmount"] / a2[res]["total"]).toFixed(2)*1) }) console.log("===========第五题==========") console.log(als[0]) console.log(als[1]) console.log(a3) var option = { title:{ text:"任务五：用折柱混合图展示省份平均消费额和地区平均消费额" }, xAxis:{data:als[0]}, yAxis:{type:"value"}, series:[ { type:"bar", data:als[1] }, { type:"line", data:a3 }, ] } pc.setOption(option) },结果任务六：用折线图展示每年上架商品数量的变化编写Vue工程代码，根据接口，用折线图展示每年上架商品数量的变化情况，同时将用于图表展示的数据结构在浏览器的console中进行打印输出，将图表可视化结果和浏览器console打印结果分别截图并粘贴至对应报告中。代码 task6(){ var pc = echarts.init(document.getElementsByClassName("ec")[5]) var ls = [] var data = [] this.GoodsInfo.forEach(ele=>{ var index = ls.indexOf(ele["year"]) if(index == -1){ ls.push(ele["year"]); data.push(1); }else{ data[index] += 1; } }) console.log("===========第六题==========") console.log(ls) console.log(data) var option = { title:{ text:"任务六：用折线图展示每年上架商品数量的变化" }, xAxis:{data:ls}, yAxis:{type:"value"}, series:[ { type:"line", data:data } ] } pc.setOption(option) },结果任务七：用条形图展示消费额最高的地区编写Vue工程代码，根据接口，用条形图展示2020年消费额最高的5个地区，同时将用于图表展示的数据结构在浏览器的console中进行打印输出，将图表可视化结果和浏览器console打印结果分别截图并粘贴至对应报告中。代码 task7(){ var pc = echarts.init(document.getElementsByClassName("ec")[6]) var ls = [] var data = [] this.OrderInfo.forEach(ele=>{ var index = ls.indexOf(ele["regionName"]) if(index == -1){ ls.push(ele["regionName"]); data.push({ name:ele["regionName"], value:ele["finalTotalAmount"] }); }else{ data[index]["value"] += ele["finalTotalAmount"]; } }) data.sort((a,b)=>b["value"] - a["value"]) var a1 = [[],[]] data.slice(0,5).forEach(res=>{ a1[0].push(res["name"]) a1[1].push(res["value"]) }) console.log("===========第七题==========") console.log(a1[0]) console.log(a1[1]) var option = { title:{ text:"任务七：用条形图展示消费额最高的地区" }, xAxis:{type:"value"}, yAxis:{data:a1[0]}, series:[ { type:"bar", data:a1[1] } ] } pc.setOption(option) },结果任务八：用散点图展示省份平均消费额编写Vue工程代码，根据接口，用基础散点图展示2020年最高10个省份平均消费额（四舍五入保留两位小数），同时将用于图表展示的数据结构在浏览器的console中进行打印输出，将图表可视化结果和浏览器console打印结果分别截图并粘贴至对应报告中。代码 task8(){ var pc = echarts.init(document.getElementsByClassName("ec")[7]) var ls = [] var data = [] this.OrderInfo.forEach(ele=>{ var index = ls.indexOf(ele["provinceName"]) if(index == -1){ ls.push(ele["provinceName"]); data.push({ name:ele["provinceName"], value:ele["finalTotalAmount"], total:1 }); }else{ data[index]["value"] += ele["finalTotalAmount"]; data[index]["total"] += 1; } }) data.sort((a,b)=>b["value"] - a["value"]) var a1 = [] data.forEach(res=>{ a1.push([res["name"],(res["value"]/res["total"]).toFixed(2)*1]) }) a1.sort((a,b)=>b[1]-a[1]) var a2 = [[],[]] a1.forEach(re=>{ a2[0].push(re[0]) a2[1].push(re[1]) }) console.log("===========第八题==========") console.log(a2[0].slice(0,10)) console.log(a2[1].slice(0,10)) var option = { title:{ text:"任务八：用散点图展示省份平均消费额" }, xAxis:{data:a2[0].slice(0,10)}, yAxis:{type:"value"}, series:[ { symbolSize:20, type:"scatter", data:a2[1].slice(0,10) } ] } pc.setOption(option) }, 结果任务九：用柱状图展示消费额最高的地区编写Vue工程代码，根据接口，用柱状图展示2020年消费额最高的5个地区，同时将用于图表展示的数据结构在浏览器的console中进行打印输出，将图表可视化结果和浏览器console打印结果分别截图并粘贴至对应报告中。代码 task9(){ var pc = echarts.init(document.getElementsByClassName("ec")[8]) var ls = [] var data = [] this.OrderInfo.forEach(ele=>{ var index = ls.indexOf(ele["regionName"]) if(index == -1){ ls.push(ele["regionName"]); data.push({ name:ele["regionName"], value:ele["finalTotalAmount"] }); }else{ data[index]["value"] += ele["finalTotalAmount"]; } }) data.sort((a,b)=>b["value"] - a["value"]) var a1 = [[],[]] data.slice(0,5).forEach(res=>{ a1[0].push(res["name"]) a1[1].push(res["value"]) }) console.log("===========第九题==========") console.log(a1[0]) console.log(a1[1]) var option = { title:{ text:"任务九：用柱状图展示消费额最高的地区" }, xAxis:{data:a1[0]}, yAxis:{type:"value"}, series:[ { symbolSize:20, type:"bar", data:a1[1] } ] } pc.setOption(option) }, 结果任务十：用条形图展示平均消费额最高的地区编写Vue工程代码，根据接口，用条形图展示2020年平均消费额（四舍五入保留两位小数）最高的5个地区，同时将用于图表展示的数据结构在浏览器的console中进行打印输出，将图表可视化结果和浏览器console打印结果分别截图并粘贴至对应报告中。代码 task10(){ var pc = echarts.init(document.getElementsByClassName("ec")[9]) var ls = [] var data = [] this.OrderInfo.forEach(ele=>{ var index = ls.indexOf(ele["regionName"]) if(index == -1){ ls.push(ele["regionName"]); data.push({ name:ele["regionName"], value:ele["finalTotalAmount"], total:1 }); }else{ data[index]["value"] += ele["finalTotalAmount"]; data[index]["total"] += 1; } }) var a1 = [] data.forEach(res=>{ a1.push({ name:res["name"], avg:(res["value"] /res["total"]).toFixed(2)*1 }) }) a1.sort((a,b)=>b["avg"] - a["avg"]) var a2 = [[],[]] a1.forEach(res=>{ a2[0].push(res["name"]) a2[1].push(res["avg"]) }) console.log("===========第十题==========") console.log(a2[0].slice(0,5)) console.log(a2[1].slice(0,5)) var option = { title:{ text:"任务十：用条形图展示平均消费额最高的地区" }, xAxis:{type:"value"}, yAxis:{data:a2[0].slice(0,5)}, series:[ { symbolSize:20, type:"bar", data:a2[1].slice(0,5) } ] } pc.setOption(option) }, 结果任务十一：用柱状图展示消费额最高的用户编写Vue工程代码，根据接口，用柱状图展示2020年消费额最高的5个用户，同时将用于图表展示的数据结构在浏览器的console中进行打印输出，将图表可视化结果和浏览器console打印结果分别截图并粘贴至对应报告中。代码 task11(){ var pc = echarts.init(document.getElementsByClassName("ec")[10]) var ls = [] var data = [] this.OrderInfo.forEach(ele=>{ var index = ls.indexOf(ele["userName"]) if(ele["userName"] != null){ if(index == -1){ ls.push(ele["userName"]); data.push({ name:ele["userName"], value:ele["finalTotalAmount"] }); }else{ data[index]["value"] += ele["finalTotalAmount"]; } } }) data = data.sort((a,b)=>b["value"]-a["value"]).slice(0,5) var l = [[],[]] data.forEach(res=>{ l[0].push(res["name"]) l[1].push(res["value"]) }) console.log("===========第十一题==========") console.log(l[0]) console.log(l[1]) var option = { title:{ text:"任务十一：用柱状图展示消费额最高的用户" }, xAxis:{data:l[0]}, yAxis:{type:"value"}, series:[ { symbolSize:20, type:"bar", data:l[1] } ] } pc.setOption(option) }, 结果任务十二：用玫瑰图展示各地区消费能力编写Vue工程代码，根据接口，用基础南丁格尔玫瑰图展示2020年各地区的消费总额占比，同时将用于图表展示的数据结构在浏览器的console中进行打印输出，将图表可视化结果和浏览器console打印结果分别截图并粘贴至对应报告中。代码 task12(){ var pc = echarts.init(document.getElementsByClassName("ec")[11]) var ls = [] var data = [] var total = 0 this.OrderInfo.forEach(ele=>{ var index = ls.indexOf(ele["regionName"]) if(index == -1){ ls.push(ele["regionName"]) data.push({ name:ele["regionName"], value:ele["finalTotalAmount"] }) total += ele["finalTotalAmount"] }else{ data[index]["value"] += ele["finalTotalAmount"] total += ele["finalTotalAmount"] } }) data.forEach((item,key)=>{ data[key]["value"] = data[key]["value"] / total * 100 }) console.log("===========第十二题==========") console.log(data) var option = { title:{ text:"任务十二：用玫瑰图展示各地区消费能力" }, series:[ { symbolSize:20, type:"pie", roseType: 'radius', data:data } ] } pc.setOption(option) }, 结果任务十三：用条形图展示消费总额最高的省份编写Vue工程代码，根据接口，用条形图展示2020年消费总额最高的10个省份，同时将用于图表展示的数据结构在浏览器的console中进行打印输出，将图表可视化结果和浏览器console打印结果分别截图并粘贴至对应报告中。代码 task13(){ var pc = echarts.init(document.getElementsByClassName("ec")[12]) var ls = [] var data = [] this.OrderInfo.forEach(ele=>{ var index = ls.indexOf(ele["provinceName"]) if(index == -1){ ls.push(ele["provinceName"]) data.push({ name:ele["provinceName"], value:ele["finalTotalAmount"] }) }else{ data[index]["value"] += ele["finalTotalAmount"] } }) data = data.sort((a,b)=>b["value"]-a["value"]).slice(0,10) var a1 = [[],[]] data.forEach(res=>{ a1[0].push(res["name"]) a1[1].push(res["value"]) }) console.log("===========第十三题==========") console.log(a1[0]) console.log(a1[1]) var option = { title:{ text:"任务十三：用条形图展示消费总额最高的省份" }, xAxis:{type:"value"}, yAxis:{data:a1[0]}, series:[ { type:"bar", data:a1[1] } ] } pc.setOption(option) }, 结果
maven安装解压解压maven压缩包tar -zxvf /opt/software/hudi-0.12.0.src.tgz -C /opt/module/配置本地库vim conf/settings.xml配置系统变量vim /etc/profileexport MAVEN_HOME=/opt/module/apache-maven-3.6.3 export PATH=$PATH:$MAVEN_HOME/bin查看环境配置结果hudi 安装解压tar -zxvf /opt/software/hudi-0.12.0.src.tgz -C /opt/module/编译mvn clean package -DskipTests -Dmaven.test.skip=true -Dspark3.1 -Dscala-2.12编译完成后将spark jar包复制出来cp /opt/module/hudi-0.12.0/packaging/hudi-spark-bundle/target/hudi-spark3.1-bundle_2.12-0.12.0.jar /opt/module/spark-3.1.1-bin-hadoop3.2/jars/运行在 spark-shell 运行案例spark-shell --jars /opt/module/hudi-spark3.1-bundle_2.12-0.12.0.jar --conf 'spark.serializer=org.apache.spark.serializer.KryoSerializer' --conf 'spark.sql.extensions=org.apache.spark.sql.hudi.HoodieSparkSessionExtension'在里面粘贴代码import org.apache.hudi.QuickstartUtils._ import scala.collection.JavaConversions._ import org.apache.spark.sql.SaveMode._ import org.apache.hudi.DataSourceReadOptions._ import org.apache.hudi.DataSourceWriteOptions._ import org.apache.hudi.config.HoodieWriteConfig._ import org.apache.hudi.common.model.HoodieRecord val tableName = "hudi_trips_cow" val basePath = "file:///tmp/hudi_trips_cow" val dataGen = new DataGenerator val inserts = convertToStringList(dataGen.generateInserts(10)) val df = spark.read.json(spark.sparkContext.parallelize(inserts, 2)) df.write.format("hudi"). options(getQuickstartWriteConfigs). option(PRECOMBINE_FIELD_OPT_KEY, "ts"). option(RECORDKEY_FIELD_OPT_KEY, "uuid"). option(PARTITIONPATH_FIELD_OPT_KEY, "partitionpath"). option(TABLE_NAME, tableName). mode(Overwrite). save(basePath) val tripsSnapshotDF = spark.read.format("hudi").load(basePath + "/*/*/*/*") tripsSnapshotDF.createOrReplaceTempView("hudi_trips_snapshot") spark.sql("select fare, begin_lon, begin_lat, ts from hudi_trips_snapshot where fare > 20.0").show()
安装解压安装包解压Clickhouse四个压缩包,到/opt/module/clickhouse下tar -zxvf /opt/software/clickhouse-server-21.9.4.35.tgz -C /opt/module/clickhouse tar -zxvf /opt/software/clickhouse-common-static-21.9.4.35.tgz -C /opt/module/clickhouse tar -zxvf /opt/software/clickhouse-common-static-dbg-21.9.4.35.tgz -C /opt/module/clickhouse tar -zxvf /opt/software/clickhouse-client-21.9.4.35.tgz -C /opt/module/clickhouse运行脚本运行每个文件夹下install/doinst.sh脚本./clickhouse-server-21.9.4.35/install/doinst.sh ./clickhouse-client-21.9.4.35/install/doinst.sh ./clickhouse-common-static-21.9.4.35/install/doinst.sh ./clickhouse-common-static-dbg-21.9.4.35/install/doinst.sh在安装clickhouse-server的时候会提示设置默认密码，无密码直接回车即可修改配置文件默认Hadoop已经占用9000端口了，这里将Clickhouse 的tcp_port 改为 9001配置文件在/etc/clickhouse-server下cd /etc/clickhouse-server如果config.d有默认 listen.xml 文件则需要删除listen.xml没有就不用删rm /etc/clickhouse-server/config.d/listen.xml修改根目录的config.xml文件，修改配置项tcp_port（82行）<tcp_port>9001</tcp_port>修改根目录的config.xml文件，修改配置项listen_host（157行）添加或去除注释<listen_host>0.0.0.0</listen_host>修改完成后保存退出运行启动clickhouse-serversystemctl start clickhouse-server查看clickhouse-server状态systemctl status clickhouse-server客户端连接运行clickhouse client(有密码输入密码)clickhouse client --port 9001 clickhouse-client --port 9001