AI自动生成Git提交信息-git AI Commit

在现代软件开发中,编写清晰且一致的Git提交信息对于维护项目历史和促进团队协作至关重要。然而,为每次变更手动撰写描述性提交信息可能耗时,尤其是处理复杂差异或大型项目时。AI Commit 是一个利用AI分析Git差异并生成符合Conventional Commits规范的提交信息的Python脚本。本文将介绍其工作原理、核心功能以及如何优化您的开发流程。
在这里插入图片描述

什么是AI Commit?

AI Commit 是一个Python工具,通过分析暂存的Git变更(git diff --cached)并利用大型语言模型(LLM)生成简洁、上下文相关的提交信息。它集成了外部API(如阿里云的Qwen模型),能够识别代码变更类型(功能添加、错误修复、重构等),并生成符合规范的提交信息,确保项目历史清晰易懂。

核心功能

1. 智能差异分析

脚本解析Git差异,提取关键信息:

  • 文件变更:识别新增、修改和删除的文件。
  • 变更类型:检测重构、功能添加、错误修复、文档更新或配置变更。
  • 优先文件分析:重点关注重要文件类型(如.py.js.java)。
  • 变更范围:判断变更影响单个文件、模块或多个项目部分。

对于大型差异或多文件项目,AI Commit生成简洁摘要,保留关键细节。

2. 上下文感知的提交信息

AI Commit根据变更类型生成符合Conventional Commits规范的提交信息,例如:

  • 文档更新:使用docs:前缀(例:docs: 更新README中的安装说明)。
  • 测试变更:使用test:前缀(例:test: 添加用户认证单元测试)。
  • 错误修复:使用fix:前缀(例:fix: 修复数据解析中的空指针异常)。
  • 新功能:使用feat:前缀(例:feat: 实现用户配置文件API端点)。
  • 代码重构:使用refactor:前缀(例:refactor: 将工具函数提取到独立模块)。
  • 配置变更:使用chore:config:前缀(例:chore: 更新package.json中的依赖)。

这确保提交信息与工具如semantic-release兼容,便于生成变更日志。

3. 支持新项目初始化

脚本能检测新项目的初始提交(例如包含README.mdpackage.json.gitignore等文件),生成类似init: 初始化项目结构的提交信息。

4. 处理大型差异

对于超过8000字符或涉及10个以上文件的差异,AI Commit通过以下方式进行智能处理:

  • 按文件类型分组(例:5个.py文件,2个.js文件)。
  • 提取关键变更,如函数或类定义。
  • 提供分层摘要,包含变更类型、主要语言和范围。

5. 健壮的错误处理

脚本处理多种错误情况,包括:

  • Git命令缺失或无效。
  • API请求失败(如超时或HTTP错误)。
  • 环境变量(如QWEN_API)缺失。
  • 无效或空差异。

提供清晰的错误信息,便于开发者排查问题。

工作流程

以下是脚本的工作流程图,使用Mermaid展示:

git diff --cached
大型差异
小型差异
成功
失败
获取Git暂存差异
差异是否有效?
输出无暂存更改提示
分析差异
提取文件变更和模式
生成摘要
提取关键变更
生成上下文感知提示
调用LLM API
提取提交信息
输出错误信息
执行git commit
提交成功
  1. 获取差异:运行git diff --cached获取暂存变更。
  2. 分析差异:解析文件变更、添加/删除行数及模式。
  3. 摘要生成:对于大型差异,生成简洁摘要或提取关键变更。
  4. 生成提示:根据变更类型创建上下文感知的提示。
  5. 调用API:将差异或摘要发送至LLM API生成提交信息。
  6. 执行提交:使用git commit -m <message>提交。

示例代码

以下是核心代码片段,展示如何分析差异并生成提交信息:

def analyze_diff(diff):"""分析diff内容,返回文件变更摘要"""lines = diff.split('\n')files_info = {'new_files': [],'modified_files': [],'deleted_files': [],'total_additions': 0,'total_deletions': 0}current_file = Nonefor line in lines:if line.startswith('diff --git'):match = re.search(r'a/(.*?) b/(.*?)$', line)if match:current_file = match.group(2)elif line.startswith('new file mode'):if current_file:files_info['new_files'].append(current_file)elif line.startswith('deleted file mode'):if current_file:files_info['deleted_files'].append(current_file)elif line.startswith('index') and current_file:if current_file not in files_info['new_files'] and current_file not in files_info['deleted_files']:files_info['modified_files'].append(current_file)elif line.startswith('+') and not line.startswith('+++'):files_info['total_additions'] += 1elif line.startswith('-') and not line.startswith('---'):files_info['total_deletions'] += 1return files_infodef get_commit_message(request_body):"""调用 API 生成提交信息"""headers = {"Authorization": f"Bearer {API_KEY}","Content-Type": "application/json"}try:response = requests.post(API_URL, headers=headers, json=request_body, timeout=REQUEST_TIMEOUT)response.raise_for_status()return response.json()except requests.exceptions.Timeout:print(f"[ERROR] API 请求超时 ({REQUEST_TIMEOUT} 秒)。")return None

示例使用

假设您在一个Python项目中暂存了变更并运行脚本,输出可能如下:

[INFO] 请求体内容:
{"model": "qwen-plus-latest","temperature": 0.3,"messages": [{"role": "system","content": "你是一个专业程序员。这是新功能相关的变更,请生成符合 conventional commits 规范的提交信息,使用 'feat:' 前缀。仅返回一行,不要解释。"},{"role": "user","content": "新增文件: src/api.py, tests/test_api.py; +50 -0 行"}]
}[INFO] 生成的提交信息:feat: 添加用户认证API端点
[OK] 已提交。

生成的提交信息清晰、规范,准确反映变更内容。

开始使用

依赖

  • Python 3.6+。
  • Git安装并在PATH中可用。
  • 兼容的LLM服务API密钥(如阿里云Qwen)。
  • 设置环境变量QWEN_API

安装

  1. 保存脚本为ai_commit.py
  2. 设置API密钥:export QWEN_API=your_api_key
  3. 暂存变更:git add .
  4. 运行脚本:python ai_commit.py

配置

  • API_URL:默认https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions
  • MODEL_NAME:默认qwen-plus-latest
  • MAX_DIFF_SIZE:限制差异大小为8000字符。
  • PRIORITY_FILE_EXTENSIONS:优先处理的文件类型(如.py.js)。

实用小工具

App Store 截图生成器、应用图标生成器 、在线图片压缩和 Chrome插件-强制开启复制-护眼模式-网页乱码设置编码
乖猫记账,AI智能分类的聊天记账。


完整代码

# coding: utf-8
import os
import subprocess
import requests
import json
import re
from collections import defaultdict# ==================== 配置常量 ====================
API_KEY = os.environ.get("QWEN_API")
if not API_KEY:print("[ERROR] QWEN_API environment variable not set. Please set it before running the script.")exit(1)API_URL = "https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions"
MODEL_NAME = "qwen-plus-latest"
REQUEST_TIMEOUT = 15
MAX_DIFF_SIZE = 8000
MAX_FILES_FOR_DETAIL = 10# 优先分析的文件类型
PRIORITY_FILE_EXTENSIONS = ['.py', '.js', '.ts', '.jsx', '.tsx', '.vue', '.dart','.java', '.cpp', '.c', '.go', '.rs', '.php', '.rb'
]# 语言映射
LANGUAGE_MAP = {'.py': 'Python', '.js': 'JavaScript', '.ts': 'TypeScript','.jsx': 'React', '.tsx': 'TypeScript React', '.vue': 'Vue','.java': 'Java', '.cpp': 'C++', '.c': 'C', '.go': 'Go','.rs': 'Rust', '.php': 'PHP', '.rb': 'Ruby', '.dart': 'Dart'
}# ==================== Git 操作函数 ====================
def get_git_diff():"""获取 Git staged 变更"""try:result = subprocess.run(['git', 'diff', '--cached'],stdin=subprocess.DEVNULL,stdout=subprocess.PIPE,stderr=subprocess.PIPE,text=True,encoding='utf-8',check=True)return result.stdoutexcept subprocess.CalledProcessError as e:print(f"[ERROR] 获取 Git diff 失败: {e}")if e.stderr:print(f"[ERROR] Stderr: {e.stderr.strip()}")return Noneexcept FileNotFoundError:print("[ERROR] Git 命令未找到。请确保 Git 已安装并在您的 PATH 中。")return Nonedef git_commit(message):"""执行 Git 提交"""try:subprocess.run(['git', 'commit', '-m', message], encoding='utf-8', check=True)print("[OK] 已提交。")except subprocess.CalledProcessError as e:print(f"[ERROR] Git commit 失败: {e}")if e.stderr:print(f"[ERROR] Stderr: {e.stderr.strip()}")if e.stdout:print(f"[ERROR] Stdout: {e.stdout.strip()}")except FileNotFoundError:print("[ERROR] Git 命令未找到。请确保 Git 已安装并在您的 PATH 中。")# ==================== Diff 分析函数 ====================
def analyze_diff(diff):"""分析diff内容,返回文件变更摘要"""lines = diff.split('\n')files_info = {'new_files': [],'modified_files': [],'deleted_files': [],'total_additions': 0,'total_deletions': 0}current_file = Nonefor line in lines:if line.startswith('diff --git'):match = re.search(r'a/(.*?) b/(.*?)$', line)if match:current_file = match.group(2)elif line.startswith('new file mode'):if current_file:files_info['new_files'].append(current_file)elif line.startswith('deleted file mode'):if current_file:files_info['deleted_files'].append(current_file)elif line.startswith('index') and current_file:if current_file not in files_info['new_files'] and current_file not in files_info['deleted_files']:files_info['modified_files'].append(current_file)elif line.startswith('+') and not line.startswith('+++'):files_info['total_additions'] += 1elif line.startswith('-') and not line.startswith('---'):files_info['total_deletions'] += 1return files_infodef extract_key_changes(diff):"""提取diff中的关键变更,优先保留重要文件和函数签名"""lines = diff.split('\n')key_sections = []current_section = []current_file = Noneis_priority_file = Falsefunction_changes = []for line in lines:if line.startswith('diff --git'):if current_section and is_priority_file:key_sections.extend(current_section[:50])current_section = [line]match = re.search(r'b/(.*?)$', line)if match:current_file = match.group(1)file_ext = os.path.splitext(current_file)[1]is_priority_file = file_ext in PRIORITY_FILE_EXTENSIONSelif line.startswith('@@'):current_section.append(line)elif is_priority_file:current_section.append(line)if line.startswith(('+', '-')):if re.search(r'(def |function |class |interface |struct |enum )', line):function_changes.append(f"{current_file}: {line.strip()}")if current_section and is_priority_file:key_sections.extend(current_section[:50])key_diff = '\n'.join(key_sections)if len(key_diff) > MAX_DIFF_SIZE:return '\n'.join(key_sections[:100] + function_changes)return key_diffdef analyze_change_patterns(files_info, diff):"""分析变更模式,识别重构、功能添加、bug修复等"""patterns = {'is_refactoring': False,'is_feature': False,'is_bugfix': False,'is_docs': False,'is_config': False,'is_test': False,'main_language': None,'change_scope': 'multiple'}all_files = files_info['new_files'] + files_info['modified_files'] + files_info['deleted_files']# 分析文件类型分布file_types = defaultdict(int)for file in all_files:ext = os.path.splitext(file)[1].lower()file_types[ext] += 1# 确定主要编程语言if file_types:main_ext = max(file_types.items(), key=lambda x: x[1])[0]patterns['main_language'] = LANGUAGE_MAP.get(main_ext, main_ext)# 分析变更类型doc_extensions = ['.md', '.txt', '.rst']config_extensions = ['.json', '.yaml', '.yml', '.toml', '.ini', '.conf']doc_files = [f for f in all_files if any(f.lower().endswith(ext) for ext in doc_extensions) or 'readme' in f.lower()]test_files = [f for f in all_files if 'test' in f.lower() or f.endswith(('_test.py', '.test.js', '.spec.js'))]config_files = [f for f in all_files if any(f.endswith(ext) for ext in config_extensions)]total_files = len(all_files)if total_files > 0:if len(doc_files) / total_files > 0.5:patterns['is_docs'] = Trueif len(test_files) > 0:patterns['is_test'] = Trueif len(config_files) / total_files > 0.3:patterns['is_config'] = True# 通过diff内容分析变更类型if diff:diff_lower = diff.lower()refactor_keywords = ['rename', 'move', 'extract', 'refactor', 'reorganize']feature_keywords = ['add', 'new', 'implement', 'feature', 'support']bugfix_keywords = ['fix', 'bug', 'error', 'issue', 'problem', 'correct']if any(keyword in diff_lower for keyword in refactor_keywords):patterns['is_refactoring'] = Trueif any(keyword in diff_lower for keyword in feature_keywords) and files_info['new_files']:patterns['is_feature'] = Trueif any(keyword in diff_lower for keyword in bugfix_keywords):patterns['is_bugfix'] = True# 确定变更范围if len(all_files) == 1:patterns['change_scope'] = 'single'elif len(set(os.path.dirname(f) for f in all_files)) == 1:patterns['change_scope'] = 'module'else:patterns['change_scope'] = 'multiple'return patterns# ==================== 项目检测和摘要生成 ====================
def is_new_project_init(files_info):"""检测是否为新项目的初始提交"""total_files = len(files_info['new_files'])if (total_files >= 5 and len(files_info['modified_files']) == 0 and len(files_info['deleted_files']) == 0):new_files_str = ' '.join(files_info['new_files']).lower()project_indicators = ['readme', 'package.json', 'requirements.txt', 'cargo.toml','pom.xml', 'build.gradle', '.gitignore', 'main.', 'index.']return any(indicator in new_files_str for indicator in project_indicators)return Falsedef create_diff_summary(files_info):"""为大型diff创建摘要"""summary_parts = []if files_info['new_files']:if len(files_info['new_files']) > 5:file_types = {}for file in files_info['new_files']:ext = os.path.splitext(file)[1] or 'no_ext'file_types[ext] = file_types.get(ext, 0) + 1type_summary = ', '.join([f"{count} {ext} files" for ext, count in file_types.items()])summary_parts.append(f"新增文件: {type_summary} (共{len(files_info['new_files'])}个文件)")else:summary_parts.append(f"新增文件: {', '.join(files_info['new_files'])}")if files_info['modified_files']:if len(files_info['modified_files']) > 5:summary_parts.append(f"修改文件: {len(files_info['modified_files'])}个文件")else:summary_parts.append(f"修改文件: {', '.join(files_info['modified_files'])}")if files_info['deleted_files']:summary_parts.append(f"删除文件: {', '.join(files_info['deleted_files'])}")summary_parts.append(f"+{files_info['total_additions']} -{files_info['total_deletions']} 行")return '; '.join(summary_parts)def create_layered_summary(files_info, patterns):"""创建分层的变更摘要"""summary_parts = []# 第一层:变更类型change_types = []type_mapping = {'is_feature': "新功能",'is_bugfix': "错误修复",'is_refactoring': "代码重构",'is_docs': "文档更新",'is_config': "配置变更",'is_test': "测试相关"}for key, label in type_mapping.items():if patterns[key]:change_types.append(label)if change_types:summary_parts.append(f"变更类型: {', '.join(change_types)}")# 第二层:主要语言和范围if patterns['main_language']:summary_parts.append(f"主要语言: {patterns['main_language']}")summary_parts.append(f"影响范围: {patterns['change_scope']}")# 第三层:具体文件变更file_summary = create_diff_summary(files_info)summary_parts.append(file_summary)return '\n'.join(summary_parts)# ==================== 提示词生成 ====================
def get_context_aware_prompt(patterns, files_info):"""根据变更模式生成上下文感知的提示词"""base_prompt = "你是一个专业程序员。"prompt_mapping = {'is_docs': f"{base_prompt}这是文档相关的变更,请生成符合 conventional commits 规范的提交信息,使用 'docs:' 前缀。仅返回一行,不要解释。",'is_test': f"{base_prompt}这是测试相关的变更,请生成符合 conventional commits 规范的提交信息,使用 'test:' 前缀。仅返回一行,不要解释。",'is_config': f"{base_prompt}这是配置文件相关的变更,请生成符合 conventional commits 规范的提交信息,使用 'chore:' 或 'config:' 前缀。仅返回一行,不要解释。",'is_refactoring': f"{base_prompt}这是代码重构相关的变更,请生成符合 conventional commits 规范的提交信息,使用 'refactor:' 前缀。仅返回一行,不要解释。",'is_bugfix': f"{base_prompt}这是错误修复相关的变更,请生成符合 conventional commits 规范的提交信息,使用 'fix:' 前缀。仅返回一行,不要解释。",}for pattern_type, prompt in prompt_mapping.items():if patterns[pattern_type]:return prompt# 特征检测if patterns['is_feature'] or len(files_info['new_files']) > len(files_info['modified_files']):return f"{base_prompt}这是新功能相关的变更,请生成符合 conventional commits 规范的提交信息,使用 'feat:' 前缀。仅返回一行,不要解释。"return f"{base_prompt}请为以下代码变更生成一条简洁、符合 conventional commits 规范的提交信息,仅返回一行,不要解释。"# ==================== API 调用函数 ====================
def build_request_body(diff):"""构建API请求体"""files_info = analyze_diff(diff)total_files = len(files_info['new_files']) + len(files_info['modified_files']) + len(files_info['deleted_files'])patterns = analyze_change_patterns(files_info, diff)use_summary = len(diff) > MAX_DIFF_SIZE or total_files > MAX_FILES_FOR_DETAILif use_summary:print(f"[INFO] Diff过大({len(diff)}字符) 或文件过多({total_files}个),使用智能摘要模式")if is_new_project_init(files_info):content = f"新项目初始化提交,包含以下变更:\n{create_diff_summary(files_info)}"system_prompt = "你是一个专业程序员。这是一个新项目的初始提交,请生成一条符合 conventional commits 规范的提交信息,通常使用 'feat: ' 或 'init: ' 开头。仅返回一行,不要解释。"else:content = create_layered_summary(files_info, patterns)system_prompt = get_context_aware_prompt(patterns, files_info)else:if len(diff) > MAX_DIFF_SIZE // 2:print(f"[INFO] 使用智能diff提取,原始大小: {len(diff)}字符")content = extract_key_changes(diff)print(f"[INFO] 提取后大小: {len(content)}字符")else:content = diffsystem_prompt = get_context_aware_prompt(patterns, files_info)return {"model": MODEL_NAME,"temperature": 0.3,"messages": [{"role": "system", "content": system_prompt},{"role": "user", "content": content}]}def get_commit_message(request_body):"""调用 API 生成提交信息"""headers = {"Authorization": f"Bearer {API_KEY}","Content-Type": "application/json"}try:response = requests.post(API_URL, headers=headers, json=request_body, timeout=REQUEST_TIMEOUT)response.raise_for_status()return response.json()except requests.exceptions.Timeout:print(f"[ERROR] API 请求超时 ({REQUEST_TIMEOUT} 秒)。")return Noneexcept requests.exceptions.HTTPError as e:print(f"[ERROR] API 请求失败,HTTP 状态码: {e.response.status_code}")try:print(f"[ERROR] API 响应内容: {e.response.text}")except Exception:passreturn Noneexcept requests.exceptions.RequestException as e:print(f"[ERROR] API 请求发生错误: {e}")return Noneexcept json.JSONDecodeError:print(f"[ERROR] 解码 API 响应失败。状态码: {response.status_code if 'response' in locals() else 'N/A'}")return Nonedef extract_commit_message(response_data):"""提取提交信息"""if not response_data:return Nonetry:return response_data['choices'][0]['message']['content']except (KeyError, IndexError, TypeError) as e:print(f"[ERROR] 无法提取提交信息。错误: {e}。响应内容:")print(json.dumps(response_data, indent=2, ensure_ascii=False))return None# ==================== 主程序 ====================
def main():"""主程序入口"""diff = get_git_diff()if not diff:if diff is not None:print("[INFO] 没有暂存更改,请先运行 git add。")returnrequest_body = build_request_body(diff)print("[INFO] 请求体内容:")print(json.dumps(request_body, indent=2, ensure_ascii=False))api_response = get_commit_message(request_body)if not api_response:returnmessage = extract_commit_message(api_response)if not message:returnprint("\n[INFO] 生成的提交信息:")print(f"  {message}")git_commit(message)if __name__ == "__main__":main()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/85572.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/85572.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【三大前端语言之一】样式:CSS详解

【三大前端语言之一】样式&#xff1a;CSS详解 在了解完HTML的有关知识后&#xff0c;我们应该知道&#xff0c;一个网页光有框架还不行&#xff0c;必须还得有装饰它的样式。就好比房子的结构搭好了&#xff0c;但如果没有油漆、没有窗帘、没有家具&#xff0c;就无法真正展现…

Spring AI 聊天记忆功能实战(一):从接口设计到生产实践

Spring AI 聊天记忆功能实战&#xff08;一&#xff09;&#xff1a;从接口设计到生产实践 在构建AI对话应用时&#xff0c;聊天记忆管理及存储是实现连贯上下文交互的关键组件。而大模型&#xff08;LLM&#xff09;本质上是无状态的&#xff0c;这意味着它们不会保留历史交互…

Element Plus 对话框 el-dialog 和 抽屉 el-drawer 的使用注意项(使用 div 包裹)

总结&#xff1a;使用 div 包裹&#xff01;&#xff01;&#xff01; 详细说明&#xff1a; 对话框 el-dialog 或 抽屉 el-drawer 样式的设置说明&#xff1a; 要想有效设置 el-dialog 或 el-drawer 的样式&#xff0c;需确保 el-dialog 或 el-drawer 的上层不是template&am…

【python】简单演示 gateway、service、client的工作原理

gateway 看起来主要是做协议转换的A gateway is a network node that acts as an entrance and exit point, connecting two networks that use different protocols. It allows data to flow between these networks, essentially acting as a translator between different c…

数据仓库面试题合集⑥

实时指标体系设计 + Flink 优化实战:面试高频问题 + 项目答题模板 面试中不仅会问“你做过实时处理吗?”,更会追问:“实时指标体系是怎么搭建的?”、“你们的 Flink 稳定性怎么保证?” 本篇聚焦实时指标体系设计与 Flink 优化场景,帮你答出架构设计力,也答出调优实战感…

Vue + AbortController 请求取消弹窗 hook 封装

背景 实际业务开发场景中&#xff0c;往往存在有些大数据请求的需求&#xff0c;一旦请求发起加载遮罩后用户就无法操作了&#xff0c;直接尬住&#xff0c;所以提供一个支持取消查询的功能还是很有必要的&#xff0c;为了在全业务接口都能使用封装一个hook。 ✋为什么要用 A…

数据结构相关

1 问题 如何辨析数据对象和数据结构&#xff1f;如何设计多种储存结构以及他们特性有什么&#xff1f;内存条和硬盘的区别&#xff1f; 2 方法 明晰俩者的定义数据对象是性质相同的有限个数据元素的集合&#xff0c;他是数据的一个子集。数据结构是指所涉及的数据元素的集合以及…

MacOS内存管理-删除冗余系统数据System Data

文章目录 一、问题复现二、解决思路三、解决流程四、附录 一、问题复现 以题主的的 Mac 为例&#xff0c;我们可以看到System Data所占数据高达77.08GB&#xff0c;远远超出系统所占内存 二、解决思路 占据大量空间的是分散在系统中各个位置Cache数据&#xff1b; 其中容量最…

纯视觉SOTA!华科小米推出ReCogDrive:结合VLM和强化学习的端到端自动驾驶框架

摘要 端到端自动驾驶的研究目前越来越火热&#xff0c;现有方法通过视觉语言模型&#xff08;VLM&#xff09;来解决其在长尾场景中性能降低的问题&#xff0c;但是仍然存在一些局限性。本文提出了ReCogDrive&#xff0c;它将VLM与基于扩散的轨迹规划器相结合&#xff0c;并且采…

MySQL慢SQL优化全攻略:从诊断到调优

目录 慢SQL日志分析与诊断 开启慢查询日志 慢查询日志分析工具 慢SQL优化策略 1. 避免SELECT * 查询 2. 创建高效索引 索引选择原则 索引使用注意事项 3. 使用EXPLAIN分析执行计划 4. 优化排序操作 5. 解决深分页问题 6. 避免全表扫描 7. 优化JOIN操作 8. 合理使用…

OPENPPP2 VMUX 技术探秘(高级指南)

&#x1f680; VMUX技术分析&#xff1a;OPENPPP2中的虚拟多路复用技术 &#x1f31f; 一、技术目标 &#x1f517; 连接多路复用 通过单个或多个物理链路&#xff0c;承载多个逻辑TCP连接。 &#x1f680; 高性能传输 支持数据包乱序重组实现动态流量控制&#xff08;拥塞检测…

Linux系统时间不对导致mysql初始化失败:Data Dictionary initialization failed.(数据字典版本验证失败)

文章目录 问题描述分析**问题原因分析****解决方案****1. 修正系统时间****2. 检查数据目录完整性****3. 重新初始化数据目录****4. 调整 MySQL 配置** **验证与后续步骤****注意事项** 其他说明 问题描述 mysql数据初始化失败&#xff0c;发现系统时间是1970年&#xff0c;我…

有趣的python程序Part1:如何根据记忆曲线使用python编写一个单词记忆默写程序

目录 前言 1. 数据管理模块 2. 记忆算法实现 3. 持久化存储 4. 用户界面实现 5.整合与测试 前言 此篇文章为“有趣的python程序”专栏的第一篇文章&#xff0c;本专栏致力于分享一些有趣的编程作品&#xff0c;如果能够使您产生兴趣&#xff0c;不妨来动手改编使之成为更好…

【案例】性能优化在持续集成与持续交付中的应用

【案例】性能优化在持续集成与持续交付中的应用 为了更好地理解性能优化在CI/CD流程中的实际应用&#xff0c;本节将结合一个典型案例&#xff0c;从代码提交到部署上线的完整流程中&#xff0c;讲解如何嵌入性能检测与自动化优化机制&#xff0c;并使用结构化流程图直观展示关…

P7 QT项目----会学天气预报(完结)

7.8 QMap 在 Qt 中&#xff0c;如果你想要将 JSON 数据解析到一个 QMap 中&#xff0c;你可以遍历 JSON 对象的所有键值对&#xff0c;并将它们添加到 QMap 里。这个方法特别适合于当你的 JSON 对象是一个简单的键值对集合时。以下是一个如何实现这一点的示例。 示例&#…

操作系统笔记(关于进程引入和状态的切换)

1.前言 今天下午结束了英语的四六级考试&#xff0c;终于是结束了&#xff0c;最近的这个考试太密集&#xff0c;周四的专业基础课考试&#xff0c;周五的这个线性代数的考试和这个周六的英语四六级考试&#xff0c;吧我都要烤焦了&#xff0c;最近也是疲于应对这个考试&#…

M1芯片macOS安装Xinference部署大模型

如果你看的是官方手册&#xff1a;安装 — Xinference 千万不要直接运行&#xff1a; pip install "xinference[all]" 会遇到几个问题&#xff1a; 1&#xff09;Python版本如果太新可能安装失败 2&#xff09;全量安装会失败 3&#xff09;未科学上网可能会time…

【ONNX量化实战】使用ONNX Runtime进行静态量化

目录 什么是量化量化实现的原理实战准备数据执行量化 验证量化结语 什么是量化 量化是一种常见的深度学习技术&#xff0c;其目的在于将原始的深度神经网络权重从高位原始位数被动态缩放至低位目标尾数。例如从FP32&#xff08;32位浮点&#xff09;量化值INT8&#xff08;8位…

【量子计算】格罗弗算法

文章目录 &#x1f50d; 一、算法原理与工作机制⚡ 二、性能优势&#xff1a;二次加速的体现&#x1f310; 三、应用场景⚠️ 四、局限性与挑战&#x1f52e; 五、未来展望&#x1f48e; 总结 格罗弗算法&#xff08;Grover’s algorithm&#xff09;是量子计算领域的核心算法之…

C++ 互斥量

在 C 中&#xff0c;互斥量&#xff08;std::mutex&#xff09;是一种用于多线程编程中保护共享资源的机制&#xff0c;防止多个线程同时访问某个资源&#xff0c;从而避免数据竞争&#xff08;data race&#xff09;和不一致的问题。 &#x1f512; 一、基础用法&#xff1a;s…