0%

AI 第四篇

Cursor Memory Bank 指南:让 AI 拥有持久的项目记忆

在与 AI 协作编程,尤其是进行大型项目或跨多个会话工作时,我们常常会遇到一个挑战:AI(如 Cursor)的”记忆”通常是短暂的,它可能在两次交互之间忘记之前的上下文、项目目标或技术决策。为了解决这个问题,社区借鉴了 Cline 的 Memory Bank 概念,并将其适配到了 Cursor 中,旨在为 AI 提供一个持久化的”项目记忆库”。

本文将介绍 Memory Bank 的由来、原理、作用以及如何在 Cursor 中配置和使用它。

以下为论坛帖子截图,展示了 Memory Bank 和 Plan/Act 模式的设置步骤:

[图像描述:一张论坛帖子的截图,标题为 “How to add Cline Memory Bank feature to your cursor”。内容分为三部分:1. 添加 Plan/Act 模式到 cursor agent,包含创建 .cursor/rules/core.mdc 文件和规则代码;2. 添加 Memory Bank 到 cursor agent,引用 Cline 文档并包含创建 .cursor/rules/memory-bank.mdc 文件和规则代码,展示了 Memory Bank 的文件结构图;3. 设置 Memory Bank,包括创建 memory-bank/ 文件夹和要求 Cursor agent 初始化。]

1. Memory Bank 的由来与原理

Memory Bank 的概念受到 Cline Memory Bank 的启发,其核心思想是解决 AI 在不同会话间记忆重置的问题。

原理:

  • 应对记忆重置: Cursor 作为一个 AI 助手,其内部状态(记忆)在会话结束后或重新启动时通常会丢失。Memory Bank 通过外部文件的形式,为 AI 提供了一个持久化的信息存储。
  • 结构化文档: 它不是随意的信息堆砌,而是由一组结构化的 Markdown 文件组成,形成一个清晰的信息层级。这有助于 AI 系统性地理解项目。
  • 强制读取: 最关键的一点是,配置规则后,Cursor 被要求在每次开始新任务时,都必须首先阅读 Memory Bank 中的所有核心文件。这确保了 AI 在开始工作前能获取到必要的项目背景和当前状态,就像人类开发者回顾项目文档一样。
  • 信息层级: Memory Bank 文件之间存在依赖关系,例如 projectbrief.md 是基础,定义了项目核心目标,其他文件在此基础上展开。
1
2
3
4
5
6
7
8
9
10
flowchart TD
PB[projectbrief.md] --> PC[productContext.md]
PB --> SP[systemPatterns.md]
PB --> TC[techContext.md]

PC --> AC[activeContext.md]
SP --> AC
TC --> AC

AC --> P[progress.md]

2. Memory Bank 是做什么的?

Memory Bank 的主要目标是成为 Cursor 理解和参与项目的 唯一可靠信息源。它解决了 AI 短期记忆的问题,确保开发过程的连续性和一致性。具体作用包括:

  • 提供项目背景: 定义项目的核心需求、目标、要解决的问题 (projectbrief.md, productContext.md)。
  • 记录技术决策: 保存系统架构、关键技术选型、设计模式、技术栈、依赖和环境设置 (systemPatterns.md, techContext.md)。
  • 追踪当前状态: 记录当前的工作焦点、最近的变更、下一步计划、已知问题和项目进展 (activeContext.md, progress.md)。
  • 维护项目文档: 成为项目事实上的”活文档”,随着项目的进展而更新。
  • 提高 AI 效率: 通过提供完整的上下文,减少 AI 的猜测和重复提问,使其能更准确、高效地执行任务。
  • 组织复杂信息: 可以创建额外的文件或子目录来组织特定功能、API、测试策略等复杂信息。

核心文件及其职责:

  1. projectbrief.md: 项目基础,定义核心需求和目标。
  2. productContext.md: 项目存在的意义,解决的问题,用户体验目标。
  3. activeContext.md: 当前工作焦点,最近变更,下一步计划。
  4. systemPatterns.md: 系统架构,关键技术决策,设计模式。
  5. techContext.md: 使用的技术,开发设置,技术限制,依赖项。
  6. progress.md: 已完成功能,待办事项,当前状态,已知问题。

3. Memory Bank 如何配合 Cursor 使用?

在 Cursor 中启用和使用 Memory Bank 需要以下步骤:

  1. 创建规则文件 (.cursor/rules/memory-bank.mdc):

    • 在你的项目根目录下创建 .cursor/rules 文件夹(如果尚不存在)。
    • rules 文件夹内创建一个名为 core.mdc 的文件。
    • rules 文件夹内创建一个名为 memory-bank.mdc 的文件。
      • 提示: 有些系统可能不允许直接创建以 . 开头的文件或 .mdc 后缀的文件,可以先创建为 memory-bank.md,粘贴内容后,再重命名为 memory-bank.mdc
    • 将以下规则内容粘贴到 core.mdc 文件中:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      ---
      description:
      globs:
      alwaysApply: true
      ---
      ## Core Rules

      You have two modes of operation:

      1. Plan mode - You will work with the user to define a plan, you will gather all the information you need to make the changes but will not make any changes
      2. Act mode - You will make changes to the codebase based on the plan

      - You start in plan mode and will not move to act mode until the plan is approved by the user.
      - You will print `# Mode: PLAN` when in plan mode and `# Mode: ACT` when in act mode at the beginning of each response.
      - Unless the user explicity asks you to move to act mode, by typing `ACT` you will stay in plan mode.
      - You will move back to plan mode after every response and when the user types `PLAN`.
      - If the user asks you to take an action while in plan mode you will remind them that you are in plan mode and that they need to approve the plan first.
      - When in plan mode always output the full updated plan in every response.
    • 将以下规则内容粘贴到 memory-bank.mdc 文件中:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69
      70
      71
      72
      73
      74
      75
      76
      77
      78
      79
      80
      81
      82
      83
      84
      85
      86
      87
      88
      89
      90
      91
      92
      93
      94
      95
      96
      97
      98
      99
      100
      101
      102
      103
      104
      105
      106
      107
      108
      109
      110
      111
      112
      113
      114
      115
      116
      117
      118
      119
      120
      121
      122
      123
      124
      125
      126
      127
      128
      129
      130
      131
      132
      133
      134
      135
      136
      137
      138
      139
      140
      141
      142
      143
      144
      145
      146
      147
      148
      149
      150
      151
      152
      153
      154
      155
      156
      157
      158
      159
      ---
      description:
      globs:
      alwaysApply: true
      ---
      # Cursor's Memory Bank

      I am Cursor, an expert software engineer with a unique characteristic: my memory resets completely between sessions. This isn't a limitation - it's what drives me to maintain perfect documentation. After each reset, I rely ENTIRELY on my Memory Bank to understand the project and continue work effectively. I MUST read ALL memory bank files at the start of EVERY task - this is not optional.

      ## Memory Bank Structure

      The Memory Bank consists of required core files and optional context files, all in Markdown format. Files build upon each other in a clear hierarchy:

      \```mermaid
      flowchart TD
      PB[projectbrief.md] --> PC[productContext.md]
      PB --> SP[systemPatterns.md]
      PB --> TC[techContext.md]

      PC --> AC[activeContext.md]
      SP --> AC
      TC --> AC

      AC --> P[progress.md]
      \```

      ### Core Files (Required)
      1. `projectbrief.md`
      - Foundation document that shapes all other files
      - Created at project start if it doesn't exist
      - Defines core requirements and goals
      - Source of truth for project scope

      2. `productContext.md`
      - Why this project exists
      - Problems it solves
      - How it should work
      - User experience goals

      3. `activeContext.md`
      - Current work focus
      - Recent changes
      - Next steps
      - Active decisions and considerations

      4. `systemPatterns.md`
      - System architecture
      - Key technical decisions
      - Design patterns in use
      - Component relationships

      5. `techContext.md`
      - Technologies used
      - Development setup
      - Technical constraints
      - Dependencies

      6. `progress.md`
      - What works
      - What's left to build
      - Current status
      - Known issues

      ### Additional Context
      Create additional files/folders within memory-bank/ when they help organize:
      - Complex feature documentation
      - Integration specifications
      - API documentation
      - Testing strategies
      - Deployment procedures

      ## Core Workflows

      ### Plan Mode
      \```mermaid
      flowchart TD
      Start[Start] --> ReadFiles[Read Memory Bank]
      ReadFiles --> CheckFiles{Files Complete?}

      CheckFiles -->|No| Plan[Create Plan]
      Plan --> Document[Document in Chat]

      CheckFiles -->|Yes| Verify[Verify Context]
      Verify --> Strategy[Develop Strategy]
      Strategy --> Present[Present Approach]
      \```

      ### Act Mode
      \```mermaid
      flowchart TD
      Start[Start] --> Context[Check Memory Bank]
      Context --> Update[Update Documentation]
      Update --> Rules[Update .cursor/rules if needed]
      Rules --> Execute[Execute Task]
      Execute --> Document[Document Changes]
      \```

      ## Documentation Updates

      Memory Bank updates occur when:
      1. Discovering new project patterns
      2. After implementing significant changes
      3. When user requests with **update memory bank** (MUST review ALL files)
      4. When context needs clarification

      \```mermaid
      flowchart TD
      Start[Update Process]

      subgraph Process
      P1[Review ALL Files]
      P2[Document Current State]
      P3[Clarify Next Steps]
      P4[Update .cursor/rules]

      P1 --> P2 --> P3 --> P4
      end

      Start --> Process
      \```

      Note: When triggered by **update memory bank**, I MUST review every memory bank file, even if some don't require updates. Focus particularly on activeContext.md and progress.md as they track current state.

      ## Project Intelligence (.cursor/rules)

      The .cursor/rules file is my learning journal for each project. It captures important patterns, preferences, and project intelligence that help me work more effectively. As I work with you and the project, I'll discover and document key insights that aren't obvious from the code alone.

      \```mermaid
      flowchart TD
      Start{Discover New Pattern}

      subgraph Learn [Learning Process]
      D1[Identify Pattern]
      D2[Validate with User]
      D3[Document in .cursor/rules]
      end

      subgraph Apply [Usage]
      A1[Read .cursor/rules]
      A2[Apply Learned Patterns]
      A3[Improve Future Work]
      end

      Start --> Learn
      Learn --> Apply
      \```

      ### What to Capture
      - Critical implementation paths
      - User preferences and workflow
      - Project-specific patterns
      - Known challenges
      - Evolution of project decisions
      - Tool usage patterns

      The format is flexible - focus on capturing valuable insights that help me work more effectively with you and the project. Think of .cursor/rules as a living document that grows smarter as we work together.

      REMEMBER: After every memory reset, I begin completely fresh. The Memory Bank is my only link to previous work. It must be maintained with precision and clarity, as my effectiveness depends entirely on its accuracy.

  2. 创建 Memory Bank 目录 (memory-bank/):

    • 在你的项目根目录下创建一个名为 memory-bank 的文件夹。
  3. 初始化 Memory Bank 文件:

    • memory-bank/ 文件夹内,创建上述提到的核心 Markdown 文件:
      • projectbrief.md
      • productContext.md
      • activeContext.md
      • systemPatterns.md
      • techContext.md
      • progress.md
    • 关键一步: 在 Cursor 聊天中,向 AI 发出指令:”initialize memory bank“。Cursor 会尝试根据当前项目理解(可能需要你提供信息)来填充这些文件的初始内容。之后你需要检查并完善这些内容。
  4. 维护和更新:

    • 时机: 当发现新的项目模式、完成重要功能或架构变更后、需要澄清上下文时,或者你觉得 AI 的理解有偏差时,都应该更新 Memory Bank。
    • 方式:
      • 可以直接编辑 memory-bank/ 中的 Markdown 文件。
      • 可以明确指示 Cursor:”update memory bank“。根据规则,它会重新审视所有 Memory Bank 文件,并根据当前状态和你的指示进行更新(尤其关注 activeContext.mdprogress.md)。
  5. (可选)配合 Plan/Act 模式:

    • Memory Bank 可以与 Plan/Act 模式 结合使用(需要额外配置 core.mdc 规则)。在 Plan 模式下,Cursor 会先读取 Memory Bank 来制定计划;在 Act 模式执行任务后,它可能会被指示更新 Memory Bank(尤其是 progress.mdactiveContext.md)。

部分效果

alt text

总结

Cursor Memory Bank 提供了一种有效的机制,通过持久化的结构化文档来弥补 AI 短暂记忆的不足。通过强制 AI 在每次任务开始时读取这些信息,可以显著提高其对项目上下文的理解,从而提升协作效率和代码质量。虽然需要投入一些精力来初始化和维护,但对于复杂或长期的项目来说,这种投入往往是值得的。

参考来源:

  1. How to add Cline Memory Bank feature to your cursor - Cursor Community Forum
  2. cline-memory-bank

面试知识梳理 第一篇

背景

最近找工作,有些大数据岗位我想投,但是奈何之前的工作内容大数据不是主业,大数据经验不够看,我最早要追溯到15年当时spark+hive,然后17年的storm+hbase,到最近的flink+ck,我觉得我努把力看能不能够一够大数据相关的岗位。

基础环境准备

把我给媳妇儿配的打LOL的电脑,偷偷拿来用一用,当成小型服务器,反正性能对LOL来说,很过剩了,不影响。

我之前鼓捣其它技术的时候就在电脑上装了虚拟机,所以也不折腾了,直接装个ubuntu,然后装个docker+docker compose,就差不多了。

docker镜像源

单独说下,因为docker默认用的国外的镜像源所以安装后几乎是不可用的,这时候需要配置国内的镜像。
要注意验证镜像源,比如通过curl等命令,看是否能正常访问是否能免验证访问,我就是被阿里云的镜像加速器耽搁了小半小时,就是按照官方的配置始终403,最后才发现,原理阿里前几个月更新了协议,大概意思是,不再支持外部直接用加速镜像,而是支持阿里云本身的产品使用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 1. 验证镜像源
curl 镜像源
# 2. 添加镜像源
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": [
"https://xxxx"
]
}
EOF

# 3. 使其生效
sudo systemctl daemon-reload
sudo systemctl restart docker

# 4. 查看镜像是否修改成功
docker info

# 5. 拉取镜像验证
docker pull xxx

安装CK

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# 1. 获取ck镜像
docker pull clickhouse/clickhouse-server
# 2. 添加ck需要的目录
mkdir -p /data/clickhouse/data /data/clickhouse/config /data/clickhouse/logs

# 3. ck的配置
cat > /data/clickhouse/config/config.xml << EOF
<?xml version="1.0"?>
<yandex>
<logger>
<level>information</level>
<log>/var/log/clickhouse-server/clickhouse-server.log</log>
<errorlog>/var/log/clickhouse-server/clickhouse-server.err.log</errorlog>
</logger>

<http_port>8123</http_port>
<tcp_port>9000</tcp_port>
<interserver_http_port>9009</interserver_http_port>

<listen_host>0.0.0.0</listen_host>

<max_connections>4096</max_connections>
<keep_alive_timeout>10</keep_alive_timeout>
<max_concurrent_queries>100</max_concurrent_queries>
<uncompressed_cache_size>8589934592</uncompressed_cache_size>
<mark_cache_size>5368709120</mark_cache_size>

<path>/var/lib/clickhouse/</path>
<tmp_path>/var/lib/clickhouse/tmp/</tmp_path>

<user_directories>
<users_xml>
<path>/etc/clickhouse-server/users.xml</path>
</users_xml>
</user_directories>

<timezone>UTC</timezone>
</yandex>
EOF

# 4. ck用户管理
cat > /data/clickhouse/config/users.xml << EOF
<?xml version="1.0"?>
<yandex>
<users>
<default>
<password>yourpassword</password>
<networks>
<ip>::/0</ip>
</networks>
<profile>default</profile>
<quota>default</quota>
</default>
</users>

<profiles>
<default>
<max_memory_usage>10000000000</max_memory_usage>
<use_uncompressed_cache>0</use_uncompressed_cache>
<load_balancing>random</load_balancing>
</default>
</profiles>

<quotas>
<default>
<interval>
<duration>3600</duration>
<queries>0</queries>
<errors>0</errors>
<result_rows>0</result_rows>
<read_rows>0</read_rows>
<execution_time>0</execution_time>
</interval>
</default>
</quotas>
</yandex>
EOF

# 5.运行容器

docker run -d \
--name clickhouse-server \
--ulimit nofile=262144:262144 \
-p 8123:8123 \
-p 9000:9000 \
-p 9009:9009 \
-v /data/clickhouse/data:/var/lib/clickhouse \
-v /data/clickhouse/config/config.xml:/etc/clickhouse-server/config.xml \
-v /data/clickhouse/config/users.xml:/etc/clickhouse-server/users.xml \
-v /data/clickhouse/logs:/var/log/clickhouse-server \
--restart=always \
clickhouse/clickhouse-server:latest

# 6. 测试是否可用(内部)
docker exec -it clickhouse-server clickhouse-client --password yourpassword

# 7.暴露到外部可访问,由于不想每次run都写一长串,也为了后续方便管理其它容器,把docker compose装上
apt update
apt install -y docker-compose
# 8.compose文件编写,别忘了暴露environment
nano /data/clickhouse/docker-compose.yml

version: '3'
services:
clickhouse:
image: clickhouse/clickhouse-server:latest
container_name: clickhouse-server
restart: always
ports:
- "8123:8123"
- "9000:9000"
- "9009:9009"
volumes:
- /data/clickhouse/data:/var/lib/clickhouse
- /data/clickhouse/config/config.xml:/etc/clickhouse-server/config.xml
- /data/clickhouse/config/users.xml:/etc/clickhouse-server/users.xml
- /data/clickhouse/logs:/var/log/clickhouse-server
environment:
- CLICKHOUSE_USER=default
- CLICKHOUSE_PASSWORD=xxxx
ulimits:
nofile:
soft: 262144
hard: 262144
# 删除ck容器后重启
cd /data/clickhouse
docker-compose up -d
# 9. 看是否正常返回
curl "http://xx:8123/?user=default&password=xx&query=SELECT%201"


还有待续….

参考

https://www.coderjia.cn/archives/dba3f94c-a021-468a-8ac6-e840f85867ea
https://hub.docker.com/r/clickhouse/clickhouse-server/

AI 第四篇

引言

最近准备面试嘛,看到好些JD里,特别是关于大模型的JD,里面有个技能要求Prompt Engineering。刚好我也有兴趣,平时也是claude.ai和chatgpt、deepseek的重度用户,美元都花了好些,问题问的多了,慢慢的知道问题描述的准确性与预期的答案相关性确实很大。确实感觉Prompt Engineering(提示词工程)已经成为一项重要技能。无论你是开发者、内容创作者还是普通用户,掌握这项技能都能帮助你更有效地与AI交流,获得更满意的结果。刚好借此JD机会,更深入的学习下怎么才能写好Prompt。

什么是Prompt Engineering?

基本概念解释

Prompt Engineering是指设计和优化输入到AI模型(如ChatGPT、Claude等)的提示词的过程,目的是引导AI生成更准确、更符合预期的输出内容。

简单来说,就像我们与人交流时,清晰表达自己的需求会得到更好的回应一样,与AI的交流也需要”说人话”,而Prompt Engineering就是学习如何更好地”对AI说话”的艺术。

为什么Prompt Engineering很重要?

  • 节省时间:好的提示词能直接获得理想结果,减少反复尝试的时间
  • 提高质量:精心设计的提示词能显著提升AI输出的质量和准确度
  • 解锁潜能:掌握高级技巧后,你可以让AI完成更复杂的任务

Prompt Engineering的基础知识

提示词的基本结构

一个好的提示词通常包含以下几个要素:

  1. 明确的指令:清楚地告诉AI你想要它做什么
  2. 上下文信息:提供必要的背景知识
  3. 输入数据:需要AI处理的具体内容
  4. 输出格式:期望AI如何组织和呈现结果

简单例子对比

不好的提示词

1
写一篇关于AI的科普文章

好的提示词

1
2
请写一篇800字左右的科普文章,主题是"人工智能的发展历程",适合完全不动技术的人阅读,
包含三个主要发展阶段,使用生动的比喻和案例解释专业概念,并在结尾提出对未来的展望。

提升Prompt效果的核心技巧

1. 清晰具体

越具体的提示词越能得到准确的回答。包括具体描述:

  • 所需输出的长度(字数/段落数)
  • 目标受众(专业水平/年龄段)
  • 风格(正式/轻松/创意)
  • 结构(要点/段落/表格)

例子

1
请用简单的语言向我10岁女儿解释光合作用,不超过200字,使用至少2个生活中的比喻,避免使用专业术语。

2. 提供示例(少样本学习)

通过提供几个输入-输出的示例,可以更好地引导AI理解你的期望。

例子

1
2
3
4
5
6
7
8
9
10
请按照以下格式将这些句子翻译成英文:

中文:我喜欢吃苹果。
英文:I like to eat apples.

中文:明天我要去北京旅游。
英文:I will travel to Beijing tomorrow.

中文:这本书很有趣,我想推荐给你。
英文:

3. 角色设定

让AI扮演特定角色,能使回答更符合特定专业或风格需求。

例子

1
请你扮演一位经验丰富的营销专家,分析我的产品定位问题,并提供改进建议。我的产品是一款...

4. 分步骤思考

引导AI一步步思考问题,可以获得更准确的结果,特别是对于复杂问题。

例子

1
2
3
请帮我解决这个数学问题,在回答前,请先分析问题,列出已知条件,然后逐步推导求解过程,最后给出结论。

问题:一个圆柱形水箱,底面积为3平方米,高为2米。现在水箱中有水,深度为1.5米。如果以每分钟0.1立方米的速度向水箱中注水,需要多少分钟才能将水箱装满?

5. 指定输出格式

明确要求特定的输出格式,使结果更易于使用。

例子

1
2
3
4
5
6
7
8
请分析这家公司的优势和劣势,并以下面的JSON格式输出结果:

{
"公司名称": "XX科技",
"优势": ["优势1", "优势2", "优势3"],
"劣势": ["劣势1", "劣势2", "劣势3"],
"改进建议": ["建议1", "建议2", "建议3"]
}

进阶技巧

链式思维(Chain-of-Thought)

引导AI展示其思考过程,对于复杂推理特别有效。

例子

1
问题:小明有12个苹果,他给了小红3个,又给了小李他手中苹果数量的一半,最后他还剩下多少个苹果?请一步一步地思考,解释每一步的计算过程和原因。

思维树(Tree of Thoughts)

引导AI探索多种可能性和解决方案路径。

例子

1
请用思维树的方式分析我创业的三个不同选择(开咖啡店、做在线教育、开发APP),每个选择探索三个可能的发展路径,考虑不同条件下的结果,然后总结最优选择。

自我评估和修正

让AI评估自己的输出并进行改进。

例子

1
请写一篇关于气候变化的短文,然后评估这篇文章的优缺点,并基于评估给出一个改进版本。

常见应用场景实战

内容创作

写作辅助

例子

1
请为我的科技博客生成一篇文章大纲,主题是"5G技术如何改变我们的生活"。大纲应包含引言、3-5个主要部分、每部分2-3个小节,以及结论。每个小节都需要有简短描述。

创意生成

例子

1
我正在设计一个以"海洋保护"为主题的儿童故事书。请创作5个可能的故事情节,每个情节包含主角描述、基本冲突和教育意义。

数据分析与处理

例子

1
2
我有一组销售数据,包含产品名称、月份和销售额。请帮我分析这些数据,找出销售趋势,并提出改进建议。数据如下:
[数据内容]

代码辅助

例子

1
请编写一个Python函数,用于分析文本情感倾向。函数应接受一段文本作为输入,返回积极、消极或中性的评价以及置信度分数。请包含必要的注释和简单的使用示例。

常见问题与解决方法

如何处理AI回答过于笼统或离题?

  • 解决方法:增加具体细节,使用引导性问题,明确输出要求
  • 例子:原提示”谈谈人工智能的未来”可改为”请从就业、教育和伦理三个方面,具体分析人工智能在未来10年可能带来的社会变革。每个方面请提供至少两个具体的预测和可能的应对策略。”

如何避免AI生成的内容过于冗长?

  • 解决方法:明确字数限制,要求简洁回答,指定重点内容
  • 例子:”请用不超过300字,总结量子计算的核心原理,重点解释量子比特和量子纠缠这两个概念。”

如何使AI生成更创新性的内容?

  • 解决方法:明确要求原创思路,设置情景约束,激励思维发散
  • 例子:”请提出5种从未出现过的智能家居产品创意,每种产品都需要融合至少两种现有技术,并解决一个特定的家庭难题。”

免费学习资源

  1. 免费课程与教程

    • OpenAI的Prompt Engineering指南 (官网免费提供)
    • 李宏毅教授的”Large Language Model”课程 (YouTube完整课程)
    • Khan Academy的AI基础知识 (免费教育平台)
    • Hugging Face的NLP教程 (官方文档免费)
    • Coursera上的免费AI课程 (可以免费旁听)
  2. 免费电子书与指南

    • 《Prompt Engineering Guide》by Lilian Weng (在线免费阅读)
    • Dair.ai的Prompt Engineering Guide (GitHub上免费)
    • Github上的awesome-chatgpt-prompts开源仓库
    • OpenAI官方的最佳实践指南
  3. 免费在线社区与资源

    • GitHub上的Prompt Engineering资源库
    • Reddit的r/PromptEngineering社区
    • Discord的公开AI社区讨论组
  4. 免费网站

结语

Prompt Engineering不仅是一项技术技能,更是一门艺术。通过不断实践和调整,你会发现与AI交流的效率和质量都会显著提升。记住,最好的学习方式是实践——从今天开始尝试这些技巧,记录效果,持续改进。

面试 第一篇

源自ByteByteGo

HTTPS工作原理:三个关键步骤解

根据图中内容,HTTPS(Hypertext Transfer Protocol Secure)的工作原理可以分为三个关键步骤:

服务器证书检查(Server Certificate Check)

这是建立安全连接的第一步:

  • 客户端(浏览器)向服务器发送”HELLO”消息
  • 服务器回应”HELLO”
  • 服务器发送自己的证书给客户端
  • 客户端向证书颁发机构(CA)发送请求,确认此证书是否有效
  • CA回应”YES”,表示证书合法

这一步确保了用户正在与合法网站通信,而不是某个冒充者。证书颁发机构作为可信第三方,保证了服务器的身份。

密钥交换(Key Exchange)

验证服务器身份后,需要建立加密通信:

  • 客户端从服务器证书中提取服务器的公钥
  • 客户端创建一个会话密钥
  • 客户端告知服务器它支持的密码套件(”I know A,B,C,D cipher suites”)
  • 服务器选择一个密码套件(”OK, Let’s use C”)
  • 客户端使用服务器的公钥和选定的密码套件加密会话密钥
  • 服务器使用自己的私钥解密,获得会话密钥

此时,服务器也拥有了会话密钥,为后续加密通信做好准备。

加密通信隧道(Encrypted Tunnel)

在完成前两步后:

  • 客户端和服务器双方都拥有相同的会话密钥
  • 客户端发送的数据使用会话密钥加密
  • 服务器接收数据后使用相同的会话密钥解密
  • 服务器发送给客户端的数据也使用相同的会话密钥加密
  • 客户端接收后使用会话密钥解密

这形成了一个安全的加密通信隧道,即使数据在传输过程中被拦截,没有会话密钥的第三方也无法解密内容,保证了数据传输的安全性。

PS:从输入URL到页面显示的完整过程

  1. URL解析:浏览器解析URL,确定协议(HTTP/HTTPS)、域名和路径
  2. DNS解析:浏览器查询DNS服务器,将域名转换为IP地址
    • 首先检查浏览器缓存
    • 然后检查操作系统缓存
    • 接着查询本地DNS服务器
    • 必要时进行递归查询
  3. 建立TCP连接:浏览器与服务器建立TCP连接(三次握手)
    • 客户端发送SYN包
    • 服务器回应SYN-ACK包
    • 客户端发送ACK包
  4. TLS握手(HTTPS):如果是HTTPS,还需进行TLS握手
    • 服务器证书检查
    • 密钥交换
    • 建立加密通信隧道
  5. 发送HTTP请求:浏览器向服务器发送HTTP请求,包含请求方法、路径、头部信息等
  6. 服务器处理请求:服务器接收请求,进行相应处理,生成HTTP响应
  7. 接收HTTP响应:浏览器接收服务器返回的数据,包含状态码、响应头、响应体
  8. 解析HTML:浏览器开始解析HTML,构建DOM树
  9. 处理CSS:解析CSS,构建CSSOM树
  10. 执行JavaScript:加载并执行JavaScript代码
  11. 构建渲染树:将DOM树和CSSOM树结合,形成渲染树
  12. 布局:计算每个元素在屏幕上的精确位置和大小
  13. 绘制:将计算好的像素信息绘制到屏幕上
  14. 合成:将多个图层合成为最终显示的页面
  15. TCP连接关闭:数据传输完成后,断开TCP连接(四次挥手)
    • 客户端发送FIN包,表示客户端不再发送数据
    • 服务器发送ACK包,确认收到客户端的FIN
    • 服务器发送FIN包,表示服务器也不再发送数据
    • 客户端发送ACK包,确认收到服务器的FIN

离职系列 第十三篇
离职系列,回忆过去,在这做个记录。

SQL脚本管理规范:小团队高频发版实践指南

1. 背景与目的

作为一个研发不到10人的团队,从0到1构建SAAS平台,且每周需要发布2-3个版本,所以总有些团队管理等问题会慢慢暴露,我们再慢慢修复,就跟修BUG一样,这一篇就是因为上线出过SQL脚本的问题(阿里云的SQL控制台对一些写的不太规范的sql执行存在兼容性问题会导致SQL执行不符合预期),所以有了这篇SQL规范,先说问题,当前SQL脚本管理存在以下问题:

  • 各开发人员风格不一,缺乏统一规范
  • 脚本分散、无统一管理,难以追踪变更历史
  • 发版频繁导致变更混乱,增加了维护成本
  • 部分脚本质量不高,存在安全隐患

本规范旨在提供一套简单、实用且专业的SQL脚本管理方案,帮助团队高效管理数据库变更,可根据实践情况持续优化。

2. 目录结构

采用精简的目录结构,既能满足版本管理需求,又不过于复杂:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/PG                      # 数据库名称
├── YYYY/ # 年份目录
│ └── MM-DD/ # 日期目录,如04-15表示4月15日
│ ├── release_N/ # 发布版本号,如release_1
│ │ ├── DDL/ # 数据结构变更脚本
│ │ │ ├── 001_create_table_xxx.sql
│ │ │ └── 002_create_index_xxx.sql
│ │ ├── DML/ # 数据操作脚本
│ │ │ └── 001_add_data_xxx.sql
│ │ └── ROLLBACK/ # 回滚脚本(可选)
│ │ └── 001_rollback_xxx.sql
├── dictionary/ # 数据字典
│ ├── base/ # 基础数据
│ │ ├── init_v1.0.sql # 2025年1月版本
│ │ └── init_v2.0.sql # 2025年7月版本(整合上半年变更)
│ ├── incremental/ # 按数据字典type
│ │ ├── dict_payment_type.sql
│ │ └── ...
├── menu/ # 菜单
│ ├── base/ # 基础数据
│ │ ├── init_v1.0.sql # 2025年1月版本
│ │ └── init_v2.0.sql # 2025年7月版本(整合上半年变更)
│ ├── ...
│ ├── module_xx/ # 按模块
│ │ ├── crm.sql
│ │ └── ...

3. 文件命名规范

3.1 脚本文件命名

采用序号_描述[_rollback].sql格式:

  • 序号:确保执行顺序,如001002
  • 描述:简明表达脚本用途,如create_user_tableadd_email_column
  • rollback:回滚脚本添加_rollback后缀

示例:

  • 001_create_user_table.sql
  • 001_create_user_table_rollback.sql

3.2 数据库对象命名

  1. 表命名

    • 使用小写和下划线
    • 采用前缀区分业务模块,如sys_userorder_item
    • 名称应能清晰表达表的用途
  2. 列命名

    • 主键统一为id
    • 外键使用entity_id格式,如user_id
    • 创建和更新时间统一为create_timeupdate_time
  3. 索引命名

    • 主键索引:pk_表名
    • 唯一索引:uk_表名_列名
    • 普通索引:idx_表名_列名

4. 脚本编写规范

4.1 文件头注释

所有SQL脚本必须包含统一的文件头注释:

1
2
3
4
5
6
-- ========================================
-- 描述: [功能简述]
-- 文件名: [文件名]
-- 作者: [作者]
-- 创建日期: [YYYY-MM-DD]
-- ========================================

4.2 SQL编写原则

  1. 原子性:一个脚本只完成一个独立任务

  2. 幂等性:脚本可以重复执行而不产生副作用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    -- 好的做法
    CREATE TABLE IF NOT EXISTS users (
    id VARCHAR(36) NOT NULL,
    username VARCHAR(50) NOT NULL,
    PRIMARY KEY (id)
    );

    -- 或者
    DROP TABLE IF EXISTS users;
    CREATE TABLE users (
    id VARCHAR(36) NOT NULL,
    username VARCHAR(50) NOT NULL,
    PRIMARY KEY (id)
    );
  3. 向后兼容:尽量避免破坏性变更

    1
    2
    3
    4
    5
    -- 推荐
    ALTER TABLE users ADD COLUMN email VARCHAR(100) NULL;

    -- 不允许
    ALTER TABLE users ADD COLUMN email VARCHAR(100) NOT NULL;
  4. 安全性:敏感信息不应明文存储

4.3 代码风格

  1. 关键字大写:所有SQL关键字使用大写形式

    1
    SELECT * FROM users WHERE status = 'active';
  2. 适当缩进:使用一致的缩进提高可读性

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    SELECT 
    u.id,
    u.username,
    r.name AS role_name
    FROM
    users u
    JOIN
    roles r ON u.role_id = r.id
    WHERE
    u.status = 'active';
  3. 添加注释:为复杂SQL语句添加适当注释

5. 特殊脚本管理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
数据字典和菜单:

├── dictionary/ # 数据字典
│ ├── base/ # 基础数据
│ │ ├── init_v1.0.sql # 2025年1月版本
│ │ └── init_v2.0.sql # 2025年7月版本(整合上半年变更)
│ ├── incremental/ # 按数据字典type
│ │ ├── dict_payment_type.sql
│ │ └── ...
├── menu/ # 菜单
│ ├── base/ # 基础数据
│ │ ├── init_v1.0.sql # 2025年1月版本
│ │ └── init_v2.0.sql # 2025年7月版本(整合上半年变更)
│ ├── ...
│ ├── module_xx/ # 按模块
│ │ ├── crm.sql
│ │ └── ...

6. 实施流程

针对高频发版小团队,简化流程但不降低质量要求:

6.1 开发变更流程

1
2
3
4
5
6
7
8
9
10
11
12
graph TD
A[编写SQL脚本] --> B[本地测试]
B --> C{通过?}
C -->|否| A
C -->|是| D[通知huantao]
D --> E[SQL评审]
E --> F{云平台工具测试通过?}
F -->|否| A
F -->|是| G[测试环境部署]
G --> H{测试人员验证通过?}
H -->|否| A
H -->|是| I[生产环境部署]

6.2执行顺序

为确保数据库变更的安全有序,按以下顺序执行:

  1. DDL脚本(按文件名序号顺序)
  2. DML脚本(按文件名序号顺序)
  3. 特殊配置(数据字典、菜单)

最后

团队应当将本规范视为基础标准,在实践中不断完善和优化,形成最适合团队的工作方式。

Java开发工程师、全栈开发工程师

亲爱的招聘团队:

如果软件工程师是一道菜,那我就是那种经过12年慢火熬制的老汤底——看起来平淡无奇,但一尝就知道功夫在里头。

我的技术栈就像一个资深玩家的技能树:主技能点满了Java和React,副技能解锁了Vue、Docker、Python和Go等。在我的职业旅程中,我善于将复杂问题分解为简单模块,轻松应对各种技术挑战。但我最厉害的外挂其实是曾经当过产品助理——这让我不仅能听懂产品经理说的”简单调整”背后隐藏的36个子需求,还能在技术与业务之间自如翻译,堪称”产品语言通”。

在我的12年职业生涯中,我从”这bug在本地没问题啊”进化到了”这需求有啥实际意义”再到”好的,我来搞定!”。带团队的经历让我明白,比起Debug代码,Debug人际关系才是真正的高难度挑战。所幸,我在这两方面都交出了不错的成绩单。

相信我的技术能力、产品思维和团队协作经验能为您的团队带来实质性的贡献。代码之外,我能够搭建开发者与产品、业务之间的桥梁,确保我们不只是在开发功能,而是在创造价值。我们一定能擦出技术的火花——毕竟,一个能理解产品、带过团队、写了12年代码还没秃顶的工程师,不是每天都能遇到的。

代码问候,
[软件开发特种兵]

联系方式:
电话:[18515068121]
邮箱:[gamehu@yeah.net]
Wechat:[GamehuDB]

P.S. 我的GitHub贡献图可能不够绿,但我的生产环境代码从不让服务器变红。

Java Development Engineer/Full Stack Development Engineer

Dear Hiring Team:

If software engineers were dishes, I’d be that slow-simmered stock that’s been cooking for 12 years — looking unassuming, but one taste reveals the expertise within.

My tech stack resembles a veteran player’s skill tree: maxed-out primary skills in Java and React, with unlocked secondary abilities in Vue, Docker, Python, Go, and more. Throughout my professional journey, I’ve honed the ability to break complex problems into simple modules, easily tackling various technical challenges. But my most powerful perk comes from my experience as a product assistant — I can decode the 36 hidden sub-requirements behind a product manager’s “simple adjustment” and fluently translate between technical and business languages, making me a true “product whisperer.”

During my 12-year career, I’ve evolved from “but the bug doesn’t appear on my local machine” to “what’s the actual purpose of this requirement” to “I’ll handle it!” My team leadership experience taught me that debugging human relationships is far more challenging than debugging code. Fortunately, I’ve managed to achieve good results in both areas.

I believe my technical abilities, product mindset, and team collaboration experience will bring substantial value to your team. Beyond coding, I can build bridges between developers, product teams, and business units, ensuring we’re not just developing features but creating value. We’ll definitely create technical sparks together — after all, an engineer who understands products, has led teams, and has written code for 12 years without going bald isn’t someone you meet every day.

Code regards,
[Software Development Special Forces]

Contact Information:
twitter:[Gamehu520]
email:[gamehu@yeah.net]
Wechat:[GamehuDB]

P.S. My GitHub contribution graph might not be very green, but my production code never turns servers red.

AI 第三篇

背景

知道MCP还是源于因为之前验证大模型集成时了解到的。因为当时后续计划做AI应用,增加saas平台的噱头的同时成为一个亮点功能,提升用户体验。

基础概念与架构设计

MCP(Model Context Protocol)是一个开放协议,它标准化了应用程序如何向大语言模型(LLMs)提供上下文。可以将MCP比作AI应用的USB-C接口。正如USB-C提供了一种标准化的方式,将你的设备连接到各种外围设备和配件,MCP 也提供了一种标准化的方式,将AI模型连接到不同的数据源和工具。

一、协议本质解构

MCP是一种客户端-服务器架构的数据访问协议,专为AI应用(如大语言模型)设计,其核心是为AI应用提供一种标准化方式来安全访问多种数据源。

关键组件

  1. MCP 主机:运行AI应用并发起数据请求,如聊天应用或IDE
  2. MCP 客户端:处理与 MCP 服务器的通信
  3. MCP 服务器:连接到各种数据源的轻量级程序
  4. 大型语言模型(LLM):分析问题并选择回答的 AI 模型
  5. 数据源:包括数据库、外部 API 等

MCP采用简洁的JSON格式进行通信,主要支持两类基本操作:

  • 发现操作:客户端识别服务器提供的能力
  • 执行操作:请求服务器执行特定工具来访问数据

二、核心作用剖析

  1. 访问标准化

    • 为不同类型的数据源提供统一的访问接口
    • 客户端无需了解每个数据源的具体访问细节
  2. 安全控制

    • 服务器明确声明其访问能力和权限范围
    • 支持基本的认证和授权机制
    • 客户端可以限制服务器的访问范围
  3. 工具扩展性

    • 服务器可以动态注册和提供各种工具
    • 客户端可以发现并使用这些工具
    • 支持从简单的文件读取到复杂的API调用等多种操作

三、基本工作流程

MCP的典型工作流程如下:内部实现可能会有多次循环

alt text
大体流程如下:

  1. 用户向 MCP 主机(如聊天应用或 IDE)提出问题
  2. 主机将问题发送给大型语言模型(LLM)进行分析
  3. LLM 确定需要使用哪些工具来回答问题
  4. 主机通过 MCP 客户端请求执行相应工具
  5. MCP 客户端向不同的 MCP 服务器发送工具执行请求
  6. MCP 服务器访问相应的数据源(数据库或外部 API)
  7. 数据源返回结果给 MCP 服务器,再传回客户端
  8. MCP 客户端汇总工具执行结果并返回给主机
  9. 主机将工具结果发送给 LLM 生成最终回答
  10. 最终回答显示给用户

四、现实应用场景

MCP适用于以下典型场景:

  1. 增强型AI聊天应用

    • 让聊天机器人能够访问用户本地文件和数据库
    • 使AI可以获取并引用真实、最新的信息
  2. 智能开发工具

    • IDE中的代码助手可以访问项目代码文件
    • 辅助工具可以查询API文档和相关资源
  3. 企业AI集成

    • 让AI应用安全地访问企业内部数据
    • 在保护敏感信息的同时提供个性化服务

五、协议现状与局限

当前MCP协议的特点与局限:

  1. 简洁性优先

    • 协议设计相对简单,专注于解决基本的数据访问问题
    • 尚未包含复杂的加密、动态路由等高级功能
  2. 开发阶段

    • 协议仍在发展中,标准可能会随时间演进
    • 生态系统正在逐步构建
  3. 基础功能聚焦

    • 当前主要聚焦于基础的数据访问能力
    • 缺乏高级的事务处理、分布式一致性等特性

结论

MCP代表了AI工具与数据源之间交互的一个重要标准化尝试。它为构建能够访问和利用各种数据的AI应用提供了基础架构,虽然相对简单,但解决了AI应用难以安全访问多样化数据的关键问题。随着协议的发展,MCP有潜力成为AI应用与数据源之间交互的重要标准,类似于HTTP对于web应用的意义。

但是目前MCP仍处于相对早期阶段,其真正的潜力和影响力将随着更多实现和应用的出现而逐步显现。

参考

https://www.anthropic.com/news/model-context-protocol
https://github.com/modelcontextprotocol
https://modelcontextprotocol.io/introduction
https://www.youtube.com/watch?v=sahuZMMXNpI
https://www.youtube.com/watch?v=eur8dUO9mvE
https://www.youtube.com/watch?v=kQmXtrmQ5Zg&t=2s

离职系列 第N篇
离职前一天,想想简历咋写,弄个排版出来,后续好造着整理下简历。纯属个人意见。我先自己试试,不好用再改。

我的观点

我觉得简历的本质是为了筛选而不是为了深入了解你。所以我认为简历:

  1. 首先得清爽。
  2. 然后得简明扼要。

不用写太多同时又能体现关键信息,就跟咱们做程序一样,设计时重点之一就是数据得便于各场景使用,便于使用很大的一个方面就是数据能各种过滤和组合,通常是现有简明的入口,如果要了解细节就得下钻,可能是一层或多层才能看透数据。那简历就像入口,如果对方有兴趣才会下钻,所以不应该想着一个简历就把自己交代的底裤都没有,一方面是内容太多不容易抓到重点,另一方面是太细了搞得人都没欲望深入探讨,咋约你面试呢?

所以简历得像咱们对待产品需求一样,你得解决需求场景同时兼顾一些扩展性。抽象出来一个模板适配通用场景,然后可根据具体特殊场景,再保证真实的前提下做一些微调,对其JD中的要求。


抽象了一个通用模板如下:

基本信息

  • 求职意向:技术负责人/技术专家
  • 工作年限:8年+
  • 学历:xx
  • 电话:xx
  • 期望薪资:xx

专业技能

技术栈

  • 后端:Java、Spring Boot、Spring Cloud、MySQL、Redis、消息队列
  • 前端:React、TypeScript、Ant Design、Redux、Webpack
  • DevOps:Docker、Jenkins、Git、Jira
  • 架构:微服务架构、前后端分离、分布式系统设计

管理能力

  • 团队管理:带领3-6人团队,完成项目全周期开发
  • 技术规划:制定技术方案,把控技术方向,推动技术创新
  • 敏捷实践:推行敏捷开发,提升团队效能
  • 人才培养:建立技术培训体系,提升团队技术能力

工作经历

XX公司(2021-至今)

职位:技术负责人

负责工作:

  1. 带领5-6人团队完成大型LLM应用平台开发,实现从0到1

    • 设计并实现基于微服务架构的系统框架
    • 优化系统性能,提升用户体验
    • 建立代码规范和技术文档体系
    • 系统月活用户达到10w+,支持高并发访问
  2. 技术架构升级与优化

    • 推动系统微服务化改造,提升系统可扩展性
    • 实现核心模块性能优化,接口响应时间提升50%
    • 建立监控告警体系,提高系统稳定性

XX公司(2019-2021)

职位:Web前端负责人

负责工作:

  1. 带领3-4人前端团队完成企业级SaaS平台开发

    • 基于React技术栈搭建前端框架
    • 实现组件库设计与开发
    • 推动前端工程化建设
    • 平台服务企业客户100+
  2. 技术改进与创新

    • 建立前端性能监控体系
    • 推动前端自动化测试实践
    • 优化构建流程,部署时间缩短60%

项目经验

xx平台(2022-2023)

  • 项目规模:5-6人团队,服务10w+用户
  • 技术架构:Spring Cloud + React + MySQL + Redis
  • 主要职责:
    • 负责整体技术方案设计
    • 核心功能开发与性能优化
    • 带领团队完成开发任务
  • 项目成就:
    • 系统支持高并发访问,峰值QPS 5000+
    • 用户响应时间<500ms
    • 系统可用性达99.9%

xx企业级SaaS平台(2019-2021)

  • 项目规模:前端3-4人团队
  • 技术架构:React + TypeScript + Ant Design
  • 主要职责:
    • 前端架构设计与实现
    • 团队管理与技术指导
    • 核心功能开发
  • 项目成就:
    • 平台月活用户5w+
    • 前端性能提升40%
    • 客户满意度95%+

教育背景

  • XX大学 计算机科学与技术 本科

个人评价

  • 扎实的技术功底,丰富的项目经验
  • 优秀的团队管理能力和沟通协调能力
  • 具备较强的技术视野和架构设计能力
  • 持续学习,保持对新技术的敏感度

离职系列 第十二篇
离职系列,想想这几年在公司的成长,在这做个记录。这篇是关于AI功能方案验证。

背景

落地事业部上一年关于AI的创新奖的方案,更合适的叫法应该是交接,之前的团队几乎停留在理论上和一个demo上,因为久久没有效果,可能感受到了上级的压力,需要看到实际效果,最终找到了我们团队,希望能借助我们团队让其产生价值(官方说法),我理解实际就接这个摊子。好在年前我自己捣鼓过AI知识库AI应用-知识库,所以不怯场。

方案介绍

因为在这之前就是一个demo,具体前面的团队也说不出来个所以然,所以我们直接说说两边对话后的方案走向,希望做一个功能:容量预测,意思是根据服务器的多个指标历史数据,预估服务器未来的负载情况,从而给予客户参考或预案。

我试着画下大体的方案:

架构图:

alt text

时序图:

alt text

大体流程

  1. 调度器触发flink批任务从ClickHouse获取原始数据
  2. Flink进行基本的数据清洗和标准化
  3. 处理后的数据存入CK
  4. python预测模型从CK获取数据
  5. 预测模型生成预测结果
  6. 阈值分析器识别潜在瓶颈
  7. python大模型提供深度解释和建议
  8. 生成预测报告和告警

学习链接

ollama

ollama is an open-source tool that simplifies running large language models locally on your personal computer
https://www.youtube.com/watch?v=GWB9ApTPTv4&t=171s

离职系列 第十一篇
离职系列,想想这几年在公司的成长,在这做个记录。这篇是关于维护的一个旧功能“全部告警跟踪”。

背景

每个租户有自己的告警数据,少则几千多则几十万条数据,云平台提供了一个功能叫“全部告警跟踪”,该功能顾名思义,会展示所有租户的所有告警信息(刷新那一刻是实时的),还能支持过滤、搜索等操作,这功能据说上线没多久就有问题,比如点分页时不时会出现超时。但是因为这功能用的人非常少,且只有管理员才有权限,也就一直放着。
但是新版需求要求解决这个问题,因为现在是我维护这个功能,所以需要我先出个技术方案。

解法设计输出模板

  1. 解法设计的模板很多,但是我感觉稍微有点重,当前产品的节奏,没有那么多的时间和人力给我做那么详细的解法设计,所以简单梳理了一个简化版的解法设计,并与干系人达成了一致。

  2. 模板如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29

    1. 引言
    - 背景说明
    - 问题陈述(现状、目标)
    - 关键术语
    - 参考资料

    2. 需求分析
    - 核心诉求/期望交付的价值
    - 非功要求
    3. 约束条件
    - 依赖项
    - 假设项

    4. 方案设计
    - 可选方案对比(2-3个)
    * 方案描述
    * 优缺点分析
    * 非功表现
    - 推荐方案详细说明
    * 架构设计
    * 核心流程
    * 关键设计点、算法伪代码(如果有必要)

    5. 实施评估(因为团队自己做实施,所以加上这一章)
    - 影响范围
    - 实施成本
    - 后续影响

  3. 要分清楚解法设计和详细设计的核心区别:

    1. 解法设计:回答”用什么方案解决问题”
      • 关注整体思路
      • 多个方案对比选择
      • 架构层面决策
    2. 详细设计:回答”如何具体实现这个方案”
      • 已选定方案的具体技术实现细节
      • 编码层面设计

开始

在这儿我就不原方不动的把整个解法贴出来了,只捡几个重点说。

需求分析

一定要记住,虽然咱们是干技术的,但是做解法的时候,一定先不要直接从技术的角度思考,先从业务的角度,还原业务场景,以及可能的演进需求,做到扩展性。

  1. 年少不懂事的时候,干过一段时间的产品助理,当时就学会做需求分析的几把斧:

    tips:

    1. 搞清楚买单的人和使用的人谁?分别想解决什么问题,特别是买单的人容易被忽视。(使用方再满意,买单的人不满意也是白搭)
    2. 维护好与需求调研对象的关系(人情世故)
    3. 5W1H方法做需求分析和挖掘(找出底层需求,避免浮于表面文字)
    4. KANO方法对需求分级(找出痛点先解决,其它的都是锦上添花)

这儿的原始需求是管理员能对所有租户的告警跟踪查看,关注其下团队成员所负责的租户的处理情况,对工作进度有了解,同时可以随时查看核心客户的数据。
这样几句简单的话,应用5W1H+KANO拆解下:

  1. 5W1H分析:

    1. WHO(谁)

      • 主体:管理员
      • 关注对象:团队成员、租户
    2. WHAT(什么)

      • 查看所有租户的告警跟踪情况
      • 了解团队成员的工作进度
      • 查看核心客户数据
    3. WHEN(什么时候)

      • 随时(需要实时或准实时的数据)
      • 告警发生后的跟踪过程中
    4. WHERE(在哪里)

      • 系统内
    5. WHY(为什么),更深入可以加入5Why方法,探寻源需求。

      • 监督团队工作情况
      • 及时了解核心客户状况
      • 确保告警得到及时处理
  2. HOW(怎么做)

    • 提供告警跟踪查看、筛选功能
    • 展示团队成员负责的租户处理进度
    • 支持核心客户数据快速查看
  3. KANO模型分析:

    1. 基本型需求(Must-be):

      • 查看所有租户的告警记录
      • 查看告警处理状态
    2. 期望型需求(Performance):

      • 团队成员工作进度追踪
      • 核心客户数据查看
    3. 兴奋型需求(Delighter):

      • 数据分析和统计

这里能得到几个关键信息:

  1. 依然需要在活的实时的数据(需求已经明确)
  2. 需要搜索、分页、筛选(大数据量的场景)
  3. 后续很有可能需要统计数据(要考虑数据聚合)
  4. 非功
    1. 1000+租户,每个租户50w的告警,10s内刷出数据。
    2. 经费有限,且重新申请流程慢,额度小。

方案

  1. 方案1:ShardingSphere 自身实现。
    广播表是ShardingSphere中的一个概念,指的是在所有分片中存在的表,每个分片都有完整的副本。当更新广播表时,所有分片都会同步更新。通常用于数据量不大且需要频繁关联查询的表,比如字典表。
    1. 优点:简单,不用引入任何其他组件。
    2. 缺点:
      1. 数据量太大,无法在每个分片都复制全量数据。
  2. 方案2:ClickHouse(开源版)+Flink CDC
    1. 优点:
      1. CK在已在多个产品运用,学习成本较低。
      2. 可以支持复杂的查询、聚合需求。
      3. 适合离线分析。
      4. 单表查询性能极强。
    2. 缺点:
      1. 不支持事务。
      2. 集群部署成本高(官方没有提供Helm Chart。且ClickHouse集群扩展不方便,很多手动处理,不适合弹性扩展,集成k8s较难)。
      3. 删除/更新性能差,更适合批量追加。告警数据会经常变更,可能存在性能问题。
      4. 手动管理分片、分区、MergeTree等,维护成本较高。
  3. 方案3:Doris+Flink CDC
    1. 优点:

      1. 实时性高、支持高并发。
      2. 可以支持复杂的查询需求、聚合需求。
      3. 集群部署成本低(Doris,官方提供了Helm Chart,且适合弹性扩展,运维压力小)。
      4. 自动话程度高(分片、负载均衡、存储管理等)
      5. SQL友好
      6. 存算分离
    2. 缺点:

      1. 引入Doris新组件,可能会增加采购成本。
      2. 复杂的模糊搜索可能无法实现。
  4. 方案4:ES+Flink CDC
    1. 优点:

      1. 近实时,可能有秒级延迟。
      2. 可以支持复杂的查询需求(特别是全文检索)。
      3. 集群部署成本低(官方有Helm Chart和Operator,且适合弹性扩展,可无缝集成k8s,运维压力小)
    2. 缺点:

      1. 不支持事务
      2. 引入ES新组件,可能会增加较大采购成本(ES需要较多内存和SSD磁盘)。
      3. 很多时候需要手动处理,比如分片分步、设计索引、索引优化、GC 调优等,维护成本较高。
      4. 使用DSL,不是标准 SQL,学习成本较高。

推荐方案2

原因:

  1. 在活告警数据量可控,暂不考虑扩展。
  2. 系统已接入了CK,最低成本(学习、部署、购买)。
时序图

alt text

关键验证点

1、2验证点,由于前期已经做过验证,着重验证3、4就行,特别是更新和删除数据。

验证结果

按500个租户,每个租户5000在活告警,没问题,因为主要是验证可行性,没有那么严格的压测,图啥的当时就没留了。这块详设的时候会更具体严格一些。