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

使用 continue 自定义 AI 编程环境

        一直在使用github 的 copilot 来编程,确实好用,对编码效率有很大提升。

        但是站在公司角度,因为它只能对接公网(有代码安全问题)。另外,它的扩展能力也不强,无法适配公司特定领域的知识库,无法最大化作用,所以不太能大规模推广,当然,还有成本问题(每月每人70多元,不是个小数目)。

        于是,想尝试选型 开源的Continue插件来试试,是否可以替代github copilot,完成公司内部的AI 编程。试用了一下,总如如下:

一、Continue介绍:

它是一款开源的领先的AI编程助手,主要作用是代码自动生成和在编码中问答。因为是完全开源的,可定制性也非常好,一些企业级的大模型产品,也采用类似的方案。它作为插件,支持VS Code 和 JetBrains 两种较通用的IDE。

主要的功能一览:

1:快速理解选中的代码,为你解释代码。通过问答(解释选中代码)

2:自动补全代码,提供编码的提示。使用 tab 来选择提示的代码。

3:对选定的代码进行重构。问题(可提出重构的要求)

4:针对当前项目/代码库的代码进行提问。使用 @codebase 进行范围限定后的提问。

还有一些默认范围。如:@Git Diff    @Terminal  @Problems 

5:快速引用上下文。针对上下文进行提问。上下文有一些默认值,也可以自行定义。如:@a1.cpp 这是针对代码  @React 代码框架 ……

6:使用 / 快速执行命令,完成固定的任务。预置任务:

/comment 加注释,/edit 编辑修改代码,/share 将代码按指定格式输出用于分享,/cmd 执行命令,/test 生成单元测试。

命令可以自行定义(定义的执行是提示词)

7:进一步解释/解决调试终端中的错误

二、安装初始化:

2.1:Configuration

        配置主要是配使用的聊天模型,补齐代码模型,嵌入式索引算法模型,排序算法模型。

免费试用(在线):

{
  "models": [
    {
      "title": "GPT-4o (trial)",
      "provider": "free-trial",
      "model": "gpt-4o"
    }
  ],
  "tabAutocompleteModel": {
    "title": "Codestral (trial)",
    "provider": "free-trial",
    "model": "AUTODETECT"
  },
  "embeddingsProvider": {
    "provider": "free-trial"
  },
  "reranker": {
    "name": "free-trial"
  }
}

使用的都是公网提供的代理服务,在时间,速度,性能,功能上都是有限制的。所以,对于企业级应用是基本不能用。

最佳配置(在线):

chatting:使用 Claude 3.5

autocomplete:Codestral

embeddings:Voyage AI

remark:Voyage AI

{
  "models": [
    {
      "title": "Claude 3.5 Sonnet",
      "provider": "anthropic",
      "model": "claude-3-5-sonnet-20240620",
      "apiKey": "[ANTHROPIC_API_KEY]"
    }
  ],
  "tabAutocompleteModel": {
    "title": "Codestral",
    "provider": "mistral",
    "model": "codestral-latest",
    "apiKey": "[CODESTRAL_API_KEY]"
  },
  "embeddingsProvider": {
    "provider": "openai",
    "model": "voyage-code-2",
    "apiBase": "https://api.voyageai.com/v1/",
    "apiKey": "[VOYAGE_AI_API_KEY]"
  },
  "reranker": {
    "name": "voyage",
    "params": {
      "apiKey": "[VOYAGE_AI_API_KEY]"
    }
  }
}

这虽然是最佳配置,但因为涉及apikey,所以需要去相应的完成注册。

本地配置(离线):

主要使用ollama来完成本地服务的部署。可以保证使用中不会有什么内容外泄。

  • For chat: ollama pull llama3:8b
  • For autocomplete: ollama pull starcoder2:3b
  • For embeddings: ollama pull nomic-embed-text

{
  "models": [
    {
      "title": "Ollama",
      "provider": "ollama",
      "model": "AUTODETECT"
    }
  ],
  "tabAutocompleteModel": {
    "title": "Starcoder 2 3b",
    "provider": "ollama",
    "model": "starcoder2:3b"
  },
  "embeddingsProvider": {
    "provider": "ollama",
    "model": "nomic-embed-text"
  }
}

注意:为了保证完全私密性,对于VSCode的插件安装需要单独下载后安装。

对于遥测监控功能需要关闭:将 "allowAnonymousTelemetry" 设置为 false。这将阻止 Continue 插件向 PostHog 发送匿名遥测数据。

验权配置:

验权方式:通过apikey

        "apiKey": "xxx"

上下文长度配置:

设置模型的上下文长度,确定了chat时能返回的长度

       "contextLength": 8192

定制对话模板

如果你采用的模型,对于提示词有特殊的要求,可以通过定制对话模板,来统一不同模型造成的差异。这个需要你对采用的模型非常熟悉。

~/.continue/config.ts

function modifyConfig(config: Config): Config {
  const model = config.models.find(
    (model) => model.title === "My Alpaca Model",
  );
  if (model) {
    model.templateMessages = templateAlpacaMessages;
  }
  return config;
}

continue/core/llm/templates/chat.ts at main · continuedev/continue · GitHub

function templateAlpacaMessages(msgs: ChatMessage[]): string {
let prompt = "";

if (msgs[0].role === "system") {
prompt += `${msgs[0].content}\n`;
msgs.pop(0);
}

prompt += "### Instruction:\n";
for (let msg of msgs) {
prompt += `${msg.content}\n`;
}

prompt += "### Response:\n";

return prompt;
}

定制Edit提示词

如果要定制  /edit 的提示词,可以如下配置。(具体如何定义类似/edit,后面会有讲解)

const codellamaEditPrompt = `\`\`\`{{{language}}}
{{{codeToEdit}}}
\`\`\`
[INST] You are an expert programmer and personal assistant. Your task is to rewrite the above code with these instructions: "{{{userInput}}}"

Your answer should be given inside of a code block. It should use the same kind of indentation as above.
[/INST] Sure! Here's the rewritten code you requested:
\`\`\`{{{language}}}`;

function modifyConfig(config: Config): Config {
  config.models[0].promptTemplates["edit"] = codellamaEditPrompt;
  return config;
}

定制对话模型返回:

如果定制自已的简易的大模型来支持输入,可以如下配置:(当然,这样做的可能性很小,一般是不会这么做的)

export function modifyConfig(config: Config): Config {
  config.models.push({
    options: {
      title: "My Custom LLM",
      model: "mistral-7b",
    },
    streamCompletion: async function* (
      prompt: string,
      options: CompletionOptions,
      fetch,
    ) {
      // Make the API call here

      // Then yield each part of the completion as it is streamed
      // This is a toy example that will count to 10
      for (let i = 0; i < 10; i++) {
        yield `- ${i}\n`;
        await new Promise((resolve) => setTimeout(resolve, 1000));
      }
    },
  });
  return config;
}

2.2:Provider Select

Provider,实际上是联系continue和背后模型的一个服务,我们还需要单独说明一下。

自行托管服务

* 本地私有部署——可以选择一些通用的服务,有一大堆。

我们用的是Ollama

* 远程——可以将服务部署到公有云服务,比如AWS,Azure,阿里云。

可以选用一些标准框架,比如:HuggingFace TGI,vLLM,Anyscal Private Ednpoints。

Saas公有云服务

* Open-source models —— 开源社区提供的

* 商业模型 —— 商业公司提供的模型。

也可以使用 OpenRouter来适配上述两种。

2.3:models Select

选择的模型支持,那就是 会话,代码补全,词嵌入(索引)模型了。在config.json文件中配置。

代码补齐,聊天,词嵌入(编码索引),重排序 对应的支持模型

聊天:用于与用户进行自然语言交流,回答编程相关的问题,解释代码,提供编程建议等。

代码补全:在用户编写代码时,实时提供代码补全建议,提高编程效率。

词嵌入:用于生成代码和文档的向量表示,支持相似度计算、代码搜索、推荐等功能。将代码和自然语言转换成高维向量,以便进行各种向量操作,如查找相似代码片段、推荐相关文档等。

重排序:对于多个生成结果或推荐结果进行排序,以提供最优的建议给用户。

Chat:

建议 30B + parameters。

开源LLM——Llama 3,DeepSeek

商用LLM——Claude 3,GPT-4o,Gemini Pro,

AutoComplete:

建议 1-15 B parameters 

开源LLM——DeepSeek,StarCoder

商用LLM——Mistral codestral-latest

Embeddings:

开源LLM——nomic-emded-text

商用LLM——voyage-code-2

三、自定义功能

可以自定义和配置的项目有:

* Models 和 providers (这个在上一章里已经基本讲过了)

* 上下文变量 @

* 快速命令 /

* 其它配置项

3.1:Context Provider

可以通过@快速引用希望引用的代码或文档内容,然后交给LLM去查找答案。

Context 有三种类型:

第一种:normal 就是正常的类型,比如 @ codebase, termial,os之类的,就是直接引用内容。

第二种:query 就是需要查询后的内容,比如 @ Google,  Search 之类的,需要有搜索后得到的内容。

第三种:submenu 就是需要用户再做选择的。比如 @Folder  @issue

系统内置:

@code:可以引用当前工程中的 Function 或者 Class。

@Git Diff:针对需要提交的内容做询问。这个可以在提交前review一下代码。

@Terminal:针对IDE中的Terminal的内容引用。

@Docs:指定具体的文档

@Files / Folder:指定具体的文件或者目录

@Codebase:指定的是当前工程

@URL:指定一个路径文件内容

@Google:基于google搜索的结果,这个是要求在线的。

@Github issues: 针对github 的isuue,这需要配置一下token获得指定工程的授权。

@GitLab MR 针对gitlab 的merge request,这个需要配置一下git lab的服务器。

@jira 这个可以针对jira issue 进行提问,但需要配置许可token。还可以配置一下 issue的query,缩小范围。

@postgres:可以针对某张表内容或者全部表内容。需要进行DB的连接配置。

@database:这个可以针对所有数据库,需要做更多的连接配置

@Locals:针对当前线程的局部变量

@os:针对当前的操作系统

自定义context provider

需要实现 CustomContextProvider

interface CustomContextProvider {title: string;displayTitle?: string;description?: string;renderInlineAs?: string;type?: ContextProviderType;getContextItems(query: string,extras: ContextProviderExtras,): Promise<ContextItem[]>;loadSubmenuItems?: (args: LoadSubmenuItemsArgs,) => Promise<ContextSubmenuItem[]>;
}

最重要就是上下文的名字和内容。

~/.continue/config.ts

const RagContextProvider: CustomContextProvider = {
  title: "rag",
  displayTitle: "RAG",
  description:
    "Retrieve snippets from our vector database of internal documents",

  getContextItems: async (
    query: string,
    extras: ContextProviderExtras,
  ): Promise<ContextItem[]> => {
    const response = await fetch("https://internal_rag_server.com/retrieve", {
      method: "POST",
      body: JSON.stringify({ query }),
    });

    const results = await response.json();

    return results.map((result) => ({
      name: result.title,
      description: result.title,
      content: result.contents,
    }));
  },
};

export function modifyConfig(config: Config): Config {
  if (!config.contextProviders) {
    config.contextProviders = [];
  }
  config.contextProviders.push(RagContextProvider);
  return config;
}

如何实现 submenu 或者  query 呢?

如果是query,需要提供一个输入框,用来辅助生成内容。

type 设置为qury。

如果是submenu,需要将 type 设置为 submenu。需要提供submenu的内容

const ReadMeContextProvider: CustomContextProvider = {
  title: "readme",
  displayTitle: "README",
  description: "Reference README.md files in your workspace",
  type: "submenu",

  getContextItems: async (
    query: string,
    extras: ContextProviderExtras,
  ): Promise<ContextItem[]> => {
    // 'query' is the filepath of the README selected from the dropdown
    const content = await extras.ide.readFile(query);
    return [
      {
        name: getFolder(query),
        description: getFolderAndBasename(query),
        content,
      },
    ];
  },

  loadSubmenuItems: async (
    args: LoadSubmenuItemsArgs,
  ): Promise<ContextSubmenuItem[]> => {
    // Filter all workspace files for READMEs
    const allFiles = await args.ide.listWorkspaceContents();
    const readmes = allFiles.filter((filepath) =>
      filepath.endsWith("README.md"),
    );

    // Return the items that will be shown in the dropdown
    return readmes.map((filepath) => {
      return {
        id: filepath,
        title: getFolder(filepath),
        description: getFolderAndBasename(filepath),
      };
    });
  },
};

export function modifyConfig(config: Config): Config {
  if (!config.contextProviders) {
    config.contextProviders = [];
  }
  config.contextProviders.push(ReadMeContextProvider);
  return config;
}

function getFolder(path: string): string {
  return path.split(/[\/\\]/g).slice(-2)[0];
}

function getFolderAndBasename(path: string): string {
  return path
    .split(/[\/\\]/g)
    .slice(-2)
    .join("/");
}

在实现中,可以引入 Node的其它模块,辅助完成编程。

如果不想使用TypeScript,要使用其它语言,可以使用RestFull接口来适配。

{
  "name": "http",
  "params": {
    "url": "https://myserver.com/context-provider",
    "title": "http",
    "description": "Custom HTTP Context Provider",
    "displayTitle": "My Custom Context"
  }
}

3.2:Slash Commands

用 / 开头的一系列命令,可以指明一些操作的具体内容。

内置命令:

/edit:按照后续的指令,对于当前选中的代码进行编辑。

/comment:对代码加注释

/share:对当前代码按指定要求进行markdown方式的输出,方便share。

/cmd:将结果输出到terminal,像一个shell command。

/commit: 生成一个commit的 message,针对需要提交的代码。

/http: 通过HTTP Restful 接口获取信息。

/issue:提交一个bug,需要做一些连接。可以快速提单。

/so:从 stackOverflow 上获取内容进行询问。

自定义命令:

通过提示词(自然语言)来定义命令:

customCommands=[{
        "name": "check",
        "description": "Check for mistakes in my code",
        "prompt": "{{{ input }}}\n\nPlease read the highlighted code and check for any mistakes. You should look for the following, and be extremely vigilant:\n- Syntax errors\n- Logic errors\n- Security vulnerabilities\n- Performance issues\n- Anything else that looks wrong\n\nOnce you find an error, please explain it as clearly as possible, but without using extra words. For example, instead of saying 'I think there is a syntax error on line 5', you should say 'Syntax error on line 5'. Give your answer as one bullet point per mistake found."
}]

通过程序来实现自定义命令:

export function modifyConfig(config: Config): Config {
  config.slashCommands?.push({
    name: "commit",
    description: "Write a commit message",
    run: async function* (sdk) {
      const diff = await sdk.ide.getDiff();
      for await (const message of sdk.llm.streamComplete(
        `${diff}\n\nWrite a commit message for the above changes. Use no more than 20 tokens to give a brief description in the imperative mood (e.g. 'Add feature' not 'Added feature'):`,
        {
          maxTokens: 20,
        },
      )) {
        yield message;
      }
    },
  });
  return config;
}

四:功能详解

4.1:Chat 功能

        对于chat功能,完全依赖于模型的能力,按道理来说,使用越强的模型,效果越好。和直接使用chatGPT的情况类似。这里不再详细讨论。按目前市面上的情况来看,GPT-4o的能力应该是最强的。对于开源模型,llama3-70b,或者最新的llama3.1-405B(号称多项指标超越 GPT4o)

4.2:Tab Autocomplete

        对于自动补全,是 AI Code 的最重要功能,

        商业的版本,官方推荐的并不是GPT的模型,而是 Mistra的codestral-latest。开源版本,推荐的是 starcode2:16b。如果你觉得运行太慢,可以考虑  deepseek-coder:1.3b-base。如果你有更多的计算资源,可以考虑升级到 deepseek-coder:6.7b-base.

        官方不推荐 GPT和Claude(并不是预算的原因),因为自动补齐在训练时需要有提示词,但这些商业的模型做得并不好。而要做到这一点,10b以下的参数量就能做得很好。类似如下的提示词训练:

// Fill in the middle promptsimport { CompletionOptions } from "..";
import { AutocompleteSnippet } from "./ranking";interface AutocompleteTemplate {template:| string| ((prefix: string,suffix: string,filename: string,reponame: string,snippets: AutocompleteSnippet[],) => string);completionOptions?: Partial<CompletionOptions>;
}// https://huggingface.co/stabilityai/stable-code-3b
const stableCodeFimTemplate: AutocompleteTemplate = {template: "<fim_prefix>{{{prefix}}}<fim_suffix>{{{suffix}}}<fim_middle>",completionOptions: {stop: ["<fim_prefix>", "<fim_suffix>", "<fim_middle>", "<|endoftext|>"],},
};// https://arxiv.org/pdf/2402.19173.pdf section 5.1
const starcoder2FimTemplate: AutocompleteTemplate = {template: (prefix: string,suffix: string,filename: string,reponame: string,snippets: AutocompleteSnippet[],): string => {const otherFiles =snippets.length === 0? "": "<file_sep>" +snippets.map((snippet) => {return snippet.contents;// return `${getBasename(snippet.filepath)}\n${snippet.contents}`;}).join("<file_sep>") +"<file_sep>";let prompt = `${otherFiles}<fim_prefix>${prefix}<fim_suffix>${suffix}<fim_middle>`;return prompt;},completionOptions: {stop: ["<fim_prefix>","<fim_suffix>","<fim_middle>","<|endoftext|>","<file_sep>",],},
};const codeLlamaFimTemplate: AutocompleteTemplate = {template: "<PRE> {{{prefix}}} <SUF>{{{suffix}}} <MID>",completionOptions: { stop: ["<PRE>", "<SUF>", "<MID>", "<EOT>"] },
};// https://huggingface.co/deepseek-ai/deepseek-coder-1.3b-base
const deepseekFimTemplate: AutocompleteTemplate = {template:"<|fim▁begin|>{{{prefix}}}<|fim▁hole|>{{{suffix}}}<|fim▁end|>",completionOptions: {stop: ["<|fim▁begin|>", "<|fim▁hole|>", "<|fim▁end|>", "//"],},
};const deepseekFimTemplateWrongPipeChar: AutocompleteTemplate = {template: "<|fim▁begin|>{{{prefix}}}<|fim▁hole|>{{{suffix}}}<|fim▁end|>",completionOptions: { stop: ["<|fim▁begin|>", "<|fim▁hole|>", "<|fim▁end|>"] },
};const gptAutocompleteTemplate: AutocompleteTemplate = {template: `Your task is to complete the line at the end of this code block:
\`\`\`
{{{prefix}}}
\`\`\`The last line is incomplete, and you should provide the rest of that line. If the line is already complete, just return a new line. Otherwise, DO NOT provide explanation, a code block, or extra whitespace, just the code that should be added to the last line to complete it:`,completionOptions: { stop: ["\n"] },
};export function getTemplateForModel(model: string): AutocompleteTemplate {const lowerCaseModel = model.toLowerCase();// if (lowerCaseModel.includes("starcoder2")) {//   return starcoder2FimTemplate;// }if (lowerCaseModel.includes("starcoder") ||lowerCaseModel.includes("star-coder") ||lowerCaseModel.includes("starchat") ||lowerCaseModel.includes("octocoder") ||lowerCaseModel.includes("stable")) {return stableCodeFimTemplate;}if (lowerCaseModel.includes("codellama")) {return codeLlamaFimTemplate;}if (lowerCaseModel.includes("deepseek")) {return deepseekFimTemplate;}if (lowerCaseModel.includes("gpt")) {return gptAutocompleteTemplate;}return stableCodeFimTemplate;
}

4.3:代码的检索场景

        代码的检索,从表面上并不能看到,但实际上很多功能都和它相关。比如:我们使用的上下文引用,快速命令,都会对大量的内容进行索引,匹配。这需要很好的 Codebase retrival 功能,这就依赖于嵌入式模型,关键字搜索,排序的功能。

        比如:@folder What is the purpose of the utils directory?  这里会检索内容。
当然,并不是所有的检索都会被continue执行,

使用嵌入编码的情况

高层次问题和上下文检索: 当用户提出高层次的问题(例如关于代码库的设计、架构、实现方法等)时,Continue 会使用嵌入编码来对整个代码库进行语义检索。这有助于找到与用户问题最相关的文档和代码片段。

@codebase How is the authentication implemented in this project?

相似代码生成和引用: 当用户要求生成与现有代码相似的新代码时,Continue 会使用嵌入编码来查找相似的代码片段,以便生成新的代码或提供参考。

        @React Generate a new component similar to the existing Button component.

文件夹或特定文件的上下文检索: 当用户针对特定文件夹或文件提出问题时,Continue 会使用嵌入编码来检索相关内容,确保回答与上下文相关。

@folder What is the purpose of the utils directory?

综合文档和代码库检索: 在用户希望检索整个文档和代码库中的相关信息时,嵌入编码有助于在大量文档中找到语义上相关的内容。

@codebase Do we use VS Code's CodeLens feature anywhere?

不使用嵌入编码的情况

直接问题解答: 对于一些直接且具体的问题,Continue 可以直接利用 LLM 中已训练的知识来回答,而不需要进行嵌入编码和检索。

What is the syntax for a for loop in Python?

简单代码生成: 当用户要求生成简单的代码片段或回答不需要复杂的上下文时,Continue 可以直接生成代码,而无需进行嵌入编码和检索。

Write a function to reverse a string in JavaScript.

基础知识和常见问题: 对于基础编程知识和常见问题,Continue 可以直接利用模型中已存在的知识库进行回答,而不需要进行嵌入编码。

What is the difference between a list and a tuple in Python?

决策逻辑

Continue 的决策逻辑大致如下:

  1. 是否需要上下文

    • 如果问题需要上下文信息(如高层次问题、相似代码生成、文件夹或特定文件的上下文),则使用嵌入编码。
    • 如果问题不需要上下文信息(如基础知识、简单代码生成、直接问题解答),则不使用嵌入编码。
  2. 问题的复杂性

    • 对于复杂问题,特别是那些需要结合整个代码库的信息来回答的问题,使用嵌入编码。
    • 对于简单问题,可以直接利用模型中的已训练知识来回答。

4.4:Prompt files

        可以定制  test.prompt 文件,根据提示词,快速完成需要要功能。

temperature: 0.5
maxTokens: 4096
---
<system>
You are an expert programmer
</system>

{{{ input }}}

Write unit tests for the above selected code, following each of these instructions:
- Use `jest`
- Properly set up and tear down
- Include important edge cases
- The tests should be complete and sophisticated
- Give the tests just as chat output, don't edit any file
- Don't explain how to set up `jest`

4.5:Quck Action

        这应该是试用版的功能,我没有试过,说明可以提供一些快捷的功能入口。

"experimental": {
    "quickActions": [
      {
        "title": "Unit test",
        "prompt": "Write a unit test for this code. Do not change anything about the code itself.",
      }
    ]
  }

可以比较快捷的完成一些组合功能。

4.6:功能快捷键

我们来回顾一下,以VS-Code LLinux 版为例 ,有哪些重要的快捷键。

1:选中代码,Ctrl + L,针对选中代码进行快问快答。如果没有选中代码,针对当前编辑框内容进行问答。

2:Tab 针对提示补全的代码,进行确认。

3:选中代码,Ctrl + I,进行 Inline chat,

4:@可以唤起上下文变量,如果该变量有子菜单,回车会显示子内容。

5:/可以添加命令。针对当前内容进行处理。

6:Ctrl + Shift + R 解释终端中的错误内容。

五:总结

        在性能上看,与github copilot 进行比较,可能对接模型的能力原因,代码补全能力是稍弱的。且流畅度会稍差,当然,也可能是我配置的问题。总的来说,基本可用。

        在功能上看,没有太多的差别。

        但是可配置性还是很强的。完全可以利用  @  和  \ 的定制能力,为自已公司的领域开发,提供很多便利性。

        比如:

        * @ 来支持强大的代码库的检索功能。提供三方库,内置库的功能解释。

        * / 定义命令来集成一些开发中的工具,这样更加快捷,比如代码提交前的自查。

        * / 来完成与CI/CD系统的集成,完成一些MR相关的工作。

        * / 来完成与问题单系统进行集成,快速定位和分析错误。

        * 提供单元测试模板,快速生成单元测试。

        * 提供快速生成注释的功能,…… 

        * 针对硬件开发的特点,提供arch file,约束的引用,检查……

相关文章:

使用 continue 自定义 AI 编程环境

一直在使用github 的 copilot 来编程&#xff0c;确实好用&#xff0c;对编码效率有很大提升。 但是站在公司角度&#xff0c;因为它只能对接公网&#xff08;有代码安全问题&#xff09;。另外&#xff0c;它的扩展能力也不强&#xff0c;无法适配公司特定领域的知识库&#x…...

谷粒商城实战笔记-118-全文检索-ElasticSearch-进阶-aggregations聚合分析

文章目录 一&#xff0c;基本概念主要聚合类型 二&#xff0c;实战1&#xff0c;搜索 address 中包含 mill 的所有人的年龄分布以及平均年龄&#xff0c;但不显示这些人的详情2&#xff0c;按照年龄聚合&#xff0c;并且请求每个年龄的平均薪资 Elasticsearch 的聚合&#xff0…...

ansible,laas,pass,sass

ansible是新出现的自动化运维工具&#xff0c;基于Python开发&#xff0c;集合了众多运维工具&#xff08;puppet、chef、func、fabric&#xff09;的优点&#xff0c;实现了批量系统配置、批量程序部署、批量运行命令等功能。ansible是基于 paramiko 开发的,并且基于模块化工作…...

【开源分享】PHP在线提交工单源码|工单管理系统源码 (附源码搭建教程)

一、设备报修工作内容 1.工单管理&#xff1a;设备报修系统可以将设备故障统计为工单并对工单进行汇总管理。将工单数据进行归类&#xff0c;将故障分类进行查看、统计、分析等等。 2.设备状态&#xff1a;工单可通过用户上报设备状态数据进行查看&#xff0c;维修工程师在维…...

【深入探秘Hadoop生态系统】全面解析各组件及其实际应用

深入探秘Hadoop生态系统&#xff1a;全面解析各组件及其实际应用 引言 在大数据时代&#xff0c;如何高效处理和存储海量数据成为企业面临的重大挑战。根据Gartner的统计&#xff0c;到2025年&#xff0c;全球数据量将达到175泽字节&#xff08;ZB&#xff09;&#xff0c;传…...

Flink DataStream API编程入门

目录 什么是数据流 Flink程序的剖析 获取执行环境 加载/创建初始数据 指定对该数据的转换 指定把计算结果放在哪里 触发程序执行 案例 Flink中的数据流(DataStream)程序是在数据流上实现转换(transformations)的常规程序(例如,过滤,更新状态,定义窗口,…...

案例分享|Alluxio在自动驾驶数据闭环中的应用

分享嘉宾&#xff1a; 孙涛 - 中汽创智智驾工具链数据平台开发专家 关于中汽创智&#xff1a; 中汽创智科技有限公司&#xff08;以下简称“中汽创智”&#xff09;由中国一汽、东风公司、南方工业集团、长安汽车和南京江宁经开科技共同出资设立。聚焦智能底盘、新能动力、智…...

为什么选择 Baklib 而不是 Salesforce 进行知识库管理

对于希望管理其产品和服务的在线文档或知识库以支持其客户和员工的组织来说&#xff0c;市场上有太多的平台和工具。知识库通过向客户和员工提供重要信息来帮助组织提高生产力。这大致分为客户关系管理或客户服务。 很少有平台能够为销售、客户服务等提供一套服务。Salesforce…...

【C++11】解锁C++11新纪元:深入探索Lambda表达式的奥秘

&#x1f4dd;个人主页&#x1f339;&#xff1a;Eternity._ ⏩收录专栏⏪&#xff1a;C “ 登神长阶 ” &#x1f921;往期回顾&#x1f921;&#xff1a;C11右值引用 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; ❀C11 &#x1f4d2;1. 可变参数模板…...

c语言排序(2)

前言 在上一篇文章&#xff0c;我们学习了插入排序&#xff0c;选择排序以及交换排序中的冒泡排序&#xff0c;接下来我们继续学习交换排序、归并排序以及非比较排序。 1. 快速排序 快速排序是交换排序的一种&#xff0c;它的基本思想&#xff1a;任取待排序序列中的某元素作…...

vue3+ts+element plus开源框架基础

Vue 3、TypeScript 和 Element Plus 的结合为现代前端应用开发提供了强大的支持。以下是关于这三者结合的基础介绍&#xff1a; 1. Vue 3 Vue 3 是一个流行的开源JavaScript框架&#xff0c;用于构建用户界面和单页面应用。它带来了许多新特性和改进&#xff0c;包括&#xf…...

RabbitMQ快速入门(MQ的概念、安装RabbitMQ、在 SpringBoot 项目中集成 RabbitMQ )

文章目录 1. 补充知识&#xff1a;同步通讯和异步通讯1.1 同步通讯1.2 异步通讯 2. 同步调用的缺点2.1 业务耦合2.2 性能较差2.3 级联失败 3. 什么情况下使用同步调用4. 异步调用5. 异步调用的优点和缺点5.1 异步调用的优点5.1.1 解除耦合&#xff0c;拓展性强5.1.2 无需等待&a…...

Linux文件与目录管理命令 ls cp rm mv使用方法

Linux文件与目录的管理基本上包括&#xff1a;显示属性、复制、删除、移动文件与目录等&#xff0c;由于文件与目录的管理不仅重要而且操作频繁&#xff0c;所以本文列举一些常用的管理命令。 如需了解路径的概念及目录的基本操作&#xff0c;可参考【Linux】路径的概念及目录的…...

KubeSphere 部署的 Kubernetes 集群使用 GlusterFS 存储实战入门

转载&#xff1a;KubeSphere 部署的 Kubernetes 集群使用 GlusterFS 存储实战入门 知识点 定级&#xff1a;入门级 GlusterFS 和 Heketi 简介 GlusterFS 安装部署 Heketi 安装部署 Kubernetes 命令行对接 GlusterFS 实战服务器配置(架构1:1复刻小规模生产环境&#xff0c;…...

elasticsearch源码分析-08Serch查询流程

Serch查询流程 查询请求Rest路由注册也是在actionModule中 //查询操作 registerHandler.accept(new RestSearchAction());Override public List<Route> routes() {return unmodifiableList(asList(new Route(GET, "/_search"),new Route(POST, "/_searc…...

【协作提效 Go - gin ! swagger】

什么是swagger Swagger 是一个用于设计、构建、记录和使用 RESTful Web 服务的工具集。它的主要作用包括&#xff1a; API 文档生成&#xff1a;Swagger 可以自动生成详细的 API 文档&#xff0c;包括每个端点的请求和响应格式、参数、状态码等。这使得开发者和用户可以轻松理…...

栈和队列——3.滑动窗口最大值

力扣题目链接 给定一个数组 nums&#xff0c;有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。返回滑动窗口中的最大值。 示例&#xff1a; 输入&#xff1a;nums[1,3,-1,-3,5,3,6,7],k 3 …...

嵌入式智能手表开发系列文章之开篇

不好意思&#xff0c;朋友们&#xff0c;我回来了。想想已经断更了好久了。在这段断更的日子里。开拓了个新领域&#xff0c;不搞android 产品&#xff0c;而是去搞嵌入式智能手表啦。 接下来我会用几篇文章来介绍下我对这个领域的看法体会&#xff0c;以及我自己所负责领域的…...

24.8.2数据结构|双链表

双链表 1、定义结构&#xff1a;2个指针域、数据域 2、初始化&#xff1a;创建一个含有N个结点的带头结点双链表head &#xff08;双链表头结点的前驱与和尾节点的后继与置为空&#xff09; 3、求表长&#xff1a;返回双链表head的长度 4、取元素&#xff1a;取出双链表head中…...

RabbitMQ高级特性 - 事务消息

文章目录 RabbitMQ 事务消息概述实现原理代码实现不采用事务采用事务 RabbitMQ 事务消息 概述 RabbitMQ 的 AMQP 协议实现了事务机制&#xff0c;允许开发者保证消息的发送和接收时原子性的&#xff0c;也就是说&#xff0c;要么消息全都发送成功&#xff0c;要么全都发送失败…...

leetcode:心算挑战

题目&#xff1a; 心算项目的挑战比赛中&#xff0c;要求选手从N张卡牌中选出cnt张卡牌&#xff0c;若这cnt张卡牌数字总和为偶数&#xff0c;则选手成绩「有效」且得分为cnt张卡牌数字总和。给定数组cards和cnt&#xff0c;其中cards[i]表示第i张卡牌上的数字。 请帮参赛选手计…...

docker部署java项目(war包方式)

场景描述:java项目war包,在开发开电脑上使用dockerfile构建镜像,上传镜像到客户服务器中使用docker加载docker镜像,然后部署。 目录 一、本地环境安装 docker git 二、服务器环境安装 docker 三、构建docker镜像(win系统) 四、注意事项 (1)系统架构 (2)使…...

jsp 自定义taglib

一、简介 我们在javaWeb开发中&#xff0c;经常会用到jsp的taglib标签&#xff0c;有时候并不能满足我们的实际需要&#xff0c;这就需要我们自定义taglib标签&#xff0c; 二、开发步骤 1、编写control方法&#xff0c;继承BodyTagSupport 2、定义zdytaglib.tld标签文件 3、…...

从一到无穷大 #32 TimeCloth,云上的快速 Point-in-Time Recovery

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。 本作品 (李兆龙 博文, 由 李兆龙 创作)&#xff0c;由 李兆龙 确认&#xff0c;转载请注明版权。 文章目录 引言解决方案FAST FINE-GRAINED PITRLog FilterInter-Record Dependency ResolutionL…...

时间序列论文1——Forecasting at Scale

目录 0. AI总结0.1 文章概述0.2 研究背景0.3 研究思路0.4 研究结论与讨论1. Introduction2 Features of Business Time Series3 The Prophet Forecasting Model3.1 The Trend Model3.2 Seasonality3.3 Holidays and Events3.4 Model Fitting3.5 Analyst-in-the-Loop Modeling4 …...

HDFS常用命令

HDFS常用命令 1.HDFS命令介绍1.1基本语法格式1.2常用命令 1.HDFS命令介绍 HDFS 提供了一组命令行工具&#xff0c;用于管理和操作 HDFS 文件系统。 1.1基本语法格式 hdfs dfs -<命令> [选项] <参数>1.2常用命令 1.显示<path>指定的文件的详细信息。 had…...

请问如何做好软件测试工作呢?

一、明确测试目标和范围 理解测试目的&#xff1a;在开始测试之前&#xff0c;首先要明确测试的目标和范围&#xff0c;确保测试计划 与需求相匹配。这有助于测试人员聚焦在关键功能上&#xff0c;避免浪费时间和资源。制定详细的测试计划&#xff1a;根据项目需求&#xff0…...

单片机开发与Linux开发的区别

引言 单片机&#xff08;MCU&#xff09;和Linux开发是嵌入式系统领域的两大主要方向。它们在硬件平台、开发环境、应用场景和开发难度上存在显著区别。本文将系统性地比较单片机开发和Linux开发&#xff0c;探讨它们的主要区别及各自的应用场景和难度体系。 一、基本概念 1…...

【机器学习】回归类算法-相关性分析

一、前言 前面的几篇博客我们学习了分类算法&#xff0c;今天我们来了解一下回归类的算法吧。首先我们来谈谈两者有什么区别&#xff0c;首先是我们在之前的分类算法&#xff0c;这类算法可以将让我们学会如何将不同的数据划分到不同的类里面&#xff0c;输出的是一些离散的值。…...

java基础 之 集合与栈的使用(三)

文章目录 Map接口&#xff08;一&#xff09;实现类&#xff1a;HashMap特点HashMap集合的一些方法 &#xff08;二&#xff09;实现类&#xff1a; TreeMap特点【自然排序】代码【定制排序】代码TreeMap集合的一些方法 HashMap 和 TreeMap的区别 前文回顾&#xff1a; 戳这里 …...

网站建设合同印花税/百度2020新版下载

一、结构public final class ViewTreeObserver extends Objectjava.lang.Objectandroid.view.ViewTreeObserver二、概述用于注册监听的视图树观察者(observer)&#xff0c;在视图树种全局事件改变时得到通知。这个全局事件不仅还包括整个树的布局&#xff0c;从绘画过程开始&am…...

医院做网站需要多少钱/网络营销包括

引入guava包&#xff1a; <dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>11.0.2</version> </dependency> 1、Preconditions 前置校验前置条件适用于当判断与设置的条件不符合时&a…...

专业工厂网站建设/网络整合营销策划书

一、字符串(String)&#xff1a; swift中的String时结构体&#xff0c;OC中的NSString时类。 // 一个字符一个字符的取出来 let str&#xff1a;String "我要去飞了" // NSString 不支持下面的遍历。 for c in str.characters { print(c) } 打印 我 要 去 飞 了 ///…...

提供模板网站制作多少钱/免费外链网

【摘要】虚拟 dom 是相对于浏览器所渲染出来的真实 dom 的&#xff0c;虚拟DOM进行频繁修改&#xff0c;然后一次性比较并修改真实DOM中需要改的部分&#xff0c;最后并在真实DOM中进行排版与重绘&#xff0c;减少过多DOM节点排版与重绘损耗【作者】星星DOM&#xff0c;全称Doc…...

海口模板建站定制网站/搜索引擎大全全搜网

网上查了很多&#xff0c;很多是rtt&#xff0c;&#xff0c;setRenderTarget&#xff08;&#xff09;的不多&#xff0c;借鉴shadowmap例子&#xff0c; 初始化 //创建shadowmap纹理 hr pd3dDevice->CreateTexture( m_TextureSize, m_TextureSize, 1, D3DUSAGE_RENDE…...

如何查看用wordpress建的站点/网站一级域名和二级域名

首先声明我不经常写js代码.对浏览器的兼容性积累经验不够,特别是IE6、7、8的兼容,总结此文章以便自己和大家一起积累,少花不必要的时间。 下面是我的js代码: /**** 保存修改数据* return*/function saveConten(){$.ajax({type:"POST",url:"emp.do?paramUpdat…...