Ollama 本地GUI客户端:为DeepSeek用户量身定制的智能模型管理与交互工具

Ollama 本地GUI客户端:为DeepSeek用户量身定制的智能模型管理与交互工具

相关资源文件已经打包成EXE文件,可双击直接运行程序,且文章末尾已附上相关源码,以供大家学习交流,博主主页还有更多Python相关程序案例,秉着开源精神的想法,望大家喜欢,点个关注不迷路!!!

1. 简介:

在人工智能领域,如何高效地管理、下载和与模型进行交互是每个开发者面临的挑战。DeepSeek:Ollama 本地客户端 是一款专为开发者设计的工具,它使得智能模型的管理和交互变得前所未有的简单与高效。无论是下载本地模型,还是实时与 AI 模型互动,DeepSeek 都能够提供直观、流畅的用户体验,助力开发者在人工智能的世界中快速前行。

为了更便捷地使用DeepSeek-R1并进行本地部署,我安装了官方的ollama软件并通过命令行进行操作。然而,由于命令行操作的使用习惯问题,我决定开发一个简单的图形客户端来简化这一过程。该图形客户端的使用需要先安装官方的ollama软件,安装完成后即可通过该客户端进行操作,从而提供了一个更为直观和易用的图形化界面,减少了对命令行的依赖。

具体来说,用户需要访问ollama官网下载并安装ollama软件,之后运行我开发的图形客户端(ollama_gui)。通过这个客户端,用户可以更加轻松地进行操作,不需要直接通过命令行输入复杂的指令。这一做法大大提升了使用的便捷性和效率。

2. 功能亮点:

1. 简洁直观的用户界面

采用 Tkinter 开发的图形界面,用户可以轻松地管理模型,进行下载、删除等操作,完全不需要依赖复杂的命令行操作。通过简单的点击即可完成所有操作,适合各类开发者使用。

2. 全面的模型管理功能

下载模型: DeepSeek 支持用户从 Ollama API 下载所需的模型,下载进度条会实时更新,用户可以清晰地看到下载进度和速度。
删除模型: 支持一键删除本地模型,保持系统整洁,避免存储空间的浪费。
实时智能对话功能
用户选择模型后,能够直接向模型发送问题并获得实时反馈。对话内容在聊天框中即时显示,支持多轮交互,开发者可以迅速获取所需答案,提升工作效率。

3. 下载速度与进度监控

在下载过程中,DeepSeek 会实时显示下载的速度和总进度。无论模型的大小如何,用户都能实时了解进度,并根据反馈调整操作,提升体验。

4. 代码块高亮与一键复制

响应中的代码块会自动高亮显示,用户可直接复制代码,方便二次使用。无论是复制单段代码,还是复制整个对话记录,DeepSeek 都能提供简洁的操作方式。

5. 灵活的文本交互功能

聊天框和输入框都支持直观的文本操作,用户可以右键点击复制或粘贴内容,提升交互流畅度。此外,聊天内容中的代码块也能轻松复制,方便进行后续处理。

3.运行效果:

原CMD窗口界面:–>>>>

在这里插入图片描述

GUI客户端交互界面–>>>>

在这里插入图片描述

4. 总结:

Ollama 本地客户端 是一款针对开发者的强大工具,它不仅提供了易于操作的图形界面,还集成了强大的模型管理与交互功能。通过这款工具,开发者能够轻松获取、管理并与本地模型进行高效互动。对于那些希望简化 AI 模型操作、提升开发效率的用户来说,这款客户端无疑是一个值得尝试的利器。

随着人工智能技术的不断发展,Ollama 本地客户端将继续更新和优化,带来更多的功能和更好的用户体验。无论是新手开发者,还是资深专家,都能在这款工具中找到适合自己的功能,提升工作效率,专注于更具创意的开发工作。

5. 相关源码:

import tkinter as tk
from tkinter import ttk, messagebox
import requests
import threading
import json
import webbrowser
from tkinter import scrolledtext
import time
import tkinter.font as font# Ollama API 地址
OLLAMA_API_URL = "http://localhost:11434/api"# 定义颜色常量,使用多彩颜色方案
BG_COLOR = "#f5f5f5"  # 背景色
FG_COLOR = "#333333"  # 前景色
BUTTON_BG_COLORS = ["#00C2FE", "#6CE264", "#FF3A48", "#FF8A30","#84BDFE"]  # 按钮背景色数组
BUTTON_HOVER_BG_COLORS = ["#0087B1", "#1E7F18", "#B7000D", "#BE5200","#0059BE"]  # 按钮悬停背景色数组
BUTTON_FG_COLOR = "white"  # 按钮前景色
LABEL_BG_COLOR = "#e0e0e0"  # 标签背景色
CODE_BG_COLOR = "#f8f9fa"  # 代码块背景色class OllamaClient:def __init__(self, root):self.root = rootself.root.title("Ollama GUI 客户端")self.root.configure(bg=BG_COLOR)# 使窗口在桌面居中self.center_window()# 创建界面组件self.create_widgets()# 初始化模型列表self.update_model_list()# 下载取消标志位self.cancel_download = False# 关闭程序标志位self.cancel_APP = False# 绑定窗口关闭事件self.root.protocol("WM_DELETE_WINDOW", self.on_close)def center_window(self):# 获取屏幕宽度和高度screen_width = self.root.winfo_screenwidth()screen_height = self.root.winfo_screenheight()# 窗口宽度和高度window_width = 800window_height = 600# 计算窗口左上角的坐标x = (screen_width - window_width) // 2y = (screen_height - window_height) // 2# 设置窗口的位置和大小self.root.geometry(f"{window_width}x{window_height}+{x}+{y}")def create_widgets(self):# 使用 grid 布局管理器self.root.columnconfigure(0, weight=1)self.root.rowconfigure(1, weight=1)# 顶部框架,用于放置模型选择和下载相关组件top_frame = tk.Frame(self.root, bg=BG_COLOR)top_frame.grid(row=0, column=0, padx=10, pady=10, sticky="ew")top_frame.columnconfigure(0, weight=1)# 模型选择下拉框self.model_combobox = ttk.Combobox(top_frame, background=LABEL_BG_COLOR)self.model_combobox.grid(row=0, column=0, padx=10, sticky="w")# 打开模型库按钮open_library_button = tk.Button(top_frame, text="打开模型库", command=self.open_model_library,bg=BUTTON_BG_COLORS[0], fg=BUTTON_FG_COLOR,width=10, height=1)open_library_button.grid(row=0, column=1, padx=10)open_library_button.bind("<Enter>", lambda e: e.widget.config(bg=BUTTON_HOVER_BG_COLORS[0]))open_library_button.bind("<Leave>", lambda e: e.widget.config(bg=BUTTON_BG_COLORS[0]))# 下载模型按钮self.download_button = tk.Button(top_frame, text="下载模型", command=self.download_model,bg=BUTTON_BG_COLORS[1], fg=BUTTON_FG_COLOR,width=10, height=1)self.download_button.grid(row=0, column=2, padx=10)self.download_button.bind("<Enter>", lambda e: e.widget.config(bg=BUTTON_HOVER_BG_COLORS[1]))self.download_button.bind("<Leave>", lambda e: e.widget.config(bg=BUTTON_BG_COLORS[1]))# 删除模型按钮self.delete_button = tk.Button(top_frame, text="删除模型", command=self.delete_model,bg=BUTTON_BG_COLORS[2], fg=BUTTON_FG_COLOR,width=10, height=1)self.delete_button.grid(row=0, column=3, padx=10)self.delete_button.bind("<Enter>", lambda e: e.widget.config(bg=BUTTON_HOVER_BG_COLORS[2]))self.delete_button.bind("<Leave>", lambda e: e.widget.config(bg=BUTTON_BG_COLORS[2]))# 下载进度条及相关信息框架self.download_frame = tk.Frame(self.root, bg=BG_COLOR)self.download_frame.grid(row=2, column=0, padx=10, pady=5, sticky="ew")self.download_frame.grid_forget()self.download_progress = ttk.Progressbar(self.download_frame, orient="horizontal", length=300, mode="determinate")self.download_progress.pack(side=tk.LEFT, padx=10)self.download_info_label = tk.Label(self.download_frame, text="", bg=LABEL_BG_COLOR, fg=FG_COLOR)self.download_info_label.pack(side=tk.LEFT, padx=10)# 创建字体对象title_font = font.Font(family="黑体", size=12)# 聊天记录显示框,使用 scrolledtext 增加滚动条self.chat_text = scrolledtext.ScrolledText(self.root, width=80, height=20, bg=LABEL_BG_COLOR, fg=FG_COLOR)self.chat_text.grid(row=1, column=0, padx=10, pady=10, sticky="nsew")self.chat_text.bind("<Button-3>", self.show_chat_context_menu)self.chat_text.tag_configure("title", font=title_font)self.chat_text.tag_configure("code", background=CODE_BG_COLOR)# 输入框使用 scrolledtextself.input_text = scrolledtext.ScrolledText(self.root, width=80, height=5, bg=LABEL_BG_COLOR, fg=FG_COLOR)self.input_text.grid(row=3, column=0, padx=10, pady=10, sticky="ew")self.input_text.bind("<Button-3>", self.show_input_context_menu)# 创建一个新的框架来放置发送按钮和清除按钮button_frame = tk.Frame(self.root, bg=BG_COLOR)button_frame.grid(row=4, column=0, padx=10, pady=10, sticky="e")# 发送按钮self.send_button = tk.Button(button_frame, text="发送", command=self.send_message,bg=BUTTON_BG_COLORS[3], fg=BUTTON_FG_COLOR,width=10, height=1)self.send_button.grid(row=0, column=0, padx=10)self.send_button.bind("<Enter>", lambda e: e.widget.config(bg=BUTTON_HOVER_BG_COLORS[3]))self.send_button.bind("<Leave>", lambda e: e.widget.config(bg=BUTTON_BG_COLORS[3]))# 清空聊天记录按钮self.clear_button = tk.Button(button_frame, text="清空聊天", command=self.clear_chat,bg=BUTTON_BG_COLORS[4], fg=BUTTON_FG_COLOR,width=10, height=1)self.clear_button.grid(row=0, column=1, padx=10)self.clear_button.bind("<Enter>", lambda e: e.widget.config(bg=BUTTON_HOVER_BG_COLORS[4]))self.clear_button.bind("<Leave>", lambda e: e.widget.config(bg=BUTTON_BG_COLORS[4]))def update_model_list(self):try:response = requests.get(f"{OLLAMA_API_URL}/tags")if response.status_code == 200:models = [model["name"] for model in response.json().get("models", [])]self.model_combobox['values'] = modelsif models:self.model_combobox.set(models[0])except Exception as e:messagebox.showerror("错误", f"获取模型列表失败: {str(e)}")def open_model_library(self):webbrowser.open("https://ollama.com/library")def download_model(self):# 创建自定义输入对话框并居中显示dialog = tk.Toplevel(self.root)dialog.title("下载模型")dialog.geometry("300x150")dialog.configure(bg=BG_COLOR)dialog.attributes("-topmost", True)# 使对话框居中dialog.update_idletasks()width = dialog.winfo_width()height = dialog.winfo_height()x = (self.root.winfo_screenwidth() // 2) - (width // 2)y = (self.root.winfo_screenheight() // 2) - (height // 2)dialog.geometry(f"{width}x{height}+{x}+{y}")tk.Label(dialog, text="请输入要下载的模型名称:", bg=BG_COLOR, fg=FG_COLOR).pack(pady=20)model_entry = tk.Entry(dialog, bg=LABEL_BG_COLOR, fg=FG_COLOR)model_entry.pack(pady=10)def start_download():model_name = model_entry.get()if model_name:dialog.destroy()self.download_frame.grid()self.cancel_download = False  # 重置取消标志位threading.Thread(target=self._download_model_thread, args=(model_name,)).start()download_btn = tk.Button(dialog, text="开始下载", command=start_download,bg=BUTTON_BG_COLORS[1], fg=BUTTON_FG_COLOR)download_btn.pack(pady=10)download_btn.bind("<Enter>", lambda e: e.widget.config(bg=BUTTON_HOVER_BG_COLORS[1]))download_btn.bind("<Leave>", lambda e: e.widget.config(bg=BUTTON_BG_COLORS[1]))def on_close(self):# 设置下载取消标志self.cancel_download = Trueself.cancel_APP = True# 关闭主窗口self.root.destroy()def _download_model_thread(self, model_name):try:data = {"name": model_name}response = requests.post(f"{OLLAMA_API_URL}/pull", json=data, stream=True)if response.status_code == 200:total_size = Nonedownloaded_size = 0start_time = time.time()prev_downloaded = 0prev_progress = 0prev_time = start_timeself.download_progress['value'] = 0for line in response.iter_lines():if self.cancel_download:  # 检查取消标志位messagebox.showinfo("提示", "下载已取消")breakif line:try:chunk = line.decode('utf-8')data = json.loads(chunk)if 'total' in data:total_size = data['total']if 'completed' in data:downloaded_size = data['completed']if total_size:progress = (downloaded_size / total_size) * 100current_time = time.time()# 设置进度更新阈值和时间间隔if progress - prev_progress >= 1 or current_time - prev_time >= 0.5:elapsed_time = current_time - start_timeif elapsed_time > 0:speed = (downloaded_size - prev_downloaded) / elapsed_time / 1024# 根据文件大小动态调整单位if total_size / (1024 * 1024 * 1024) >= 1:total_size_gb = total_size / (1024 * 1024 * 1024)downloaded_size_gb = downloaded_size / (1024 * 1024 * 1024)info_text = f"速度: {speed:.2f} KB/s, 已下载: {downloaded_size_gb:.2f} GB, 总大小: {total_size_gb:.2f} GB, 进度: {progress:.2f}%"else:total_size_kb = total_size / 1024downloaded_size_kb = downloaded_size / 1024info_text = f"速度: {speed:.2f} KB/s, 已下载: {downloaded_size_kb:.2f} KB, 总大小: {total_size_kb:.2f} KB, 进度: {progress:.2f}%"self.download_info_label.config(text=info_text)prev_downloaded = downloaded_sizeself.download_progress['value'] = progressself.root.update_idletasks()prev_progress = progressprev_time = current_timeexcept Exception as e:messagebox.showerror("错误", f"解析下载进度出错: {str(e)}")if not self.cancel_download:messagebox.showinfo("成功", "模型下载成功")self.update_model_list()else:messagebox.showerror("错误", f"模型下载失败: {response.text}")except Exception as e:messagebox.showerror("错误", f"发生异常: {str(e)}")finally:self.download_frame.grid_forget()def delete_model(self):model_name = self.model_combobox.get()if model_name:try:data = {"model": model_name}print(f"尝试删除模型: {model_name}")  # 打印要删除的模型名称response = requests.delete(f"{OLLAMA_API_URL}/delete", json=data)print(f"请求响应状态码: {response.status_code}")  # 打印响应状态码print(f"请求响应内容: {response.text}")  # 打印响应内容if response.status_code == 200:messagebox.showinfo("成功", "模型删除成功")self.update_model_list()else:messagebox.showerror("错误", f"模型删除失败: {response.text}")except Exception as e:messagebox.showerror("错误", f"发生异常: {str(e)}")else:messagebox.showwarning("警告", "请选择要删除的模型")# 在 OllamaClient 类中修改 send_message 方法def send_message(self):message = self.input_text.get(1.0, tk.END).strip()if message:model_name = self.model_combobox.get()if model_name:# 使用线程来执行推理任务threading.Thread(target=self._send_message_thread, args=(message, model_name)).start()else:messagebox.showwarning("警告", "请选择要使用的模型")def _send_message_thread(self, message, model_name):try:start_time = time.time()  # 记录开始时间data = {"model": model_name,"prompt": message}# 使用 stream=True 开启流式响应response = requests.post(f"{OLLAMA_API_URL}/generate", json=data, stream=True)if response.status_code == 200:self.chat_text.insert(tk.END, f"问题: {message}\n","title")end_time = time.time()  # 记录结束时间inference_time = end_time - start_time  # 计算推理时间self.chat_text.insert(tk.END, f"\n思考时间: {inference_time:.2f} 秒\n",)self.root.update_idletasks()  # 更新界面full_response = ""chunk_count = 0for line in response.iter_lines():if self.cancel_APP:  # 检查取消标志位breakif line:try:chunk = line.decode('utf-8')data = json.loads(chunk)part = data.get("response", "")part = part.replace("<think>", "").replace("</think>", "")full_response += partself.chat_text.insert(tk.END, part)chunk_count += 1if chunk_count % 10 == 0:  # 每接收 10 个数据块更新一次界面self.root.update_idletasks()except Exception as e:messagebox.showerror("错误", f"解析响应数据出错: {str(e)}")self.root.update_idletasks()  # 确保最后一次更新界面self.input_text.delete(1.0, tk.END)self.highlight_code()else:messagebox.showerror("错误", f"请求失败: {response.text}")except Exception as e:messagebox.showerror("错误", f"发生异常: {str(e)}")def clear_chat(self):self.chat_text.delete(1.0, tk.END)def show_chat_context_menu(self, event):context_menu = tk.Menu(self.root, tearoff=0)context_menu.add_command(label="复制", command=lambda: self.copy_chat_text())# 获取点击位置的标签tags = self.chat_text.tag_names(tk.CURRENT)if "code" in tags:context_menu.add_command(label="复制当前代码块", command=lambda: self.copy_current_code_block())context_menu.add_command(label="复制所有代码块", command=lambda: self.copy_code_block())context_menu.post(event.x_root, event.y_root)def copy_chat_text(self):selected_text = self.chat_text.get(tk.SEL_FIRST, tk.SEL_LAST)if selected_text:self.root.clipboard_clear()self.root.clipboard_append(selected_text)def copy_code_block(self):tag_ranges = self.chat_text.tag_ranges("code")if tag_ranges:code_text = ""for i in range(0, len(tag_ranges), 2):start = tag_ranges[i]end = tag_ranges[i + 1]code_text += self.chat_text.get(start, end)self.root.clipboard_clear()self.root.clipboard_append(code_text)def copy_current_code_block(self):tag_ranges = self.chat_text.tag_ranges("code")current_pos = self.chat_text.index(tk.CURRENT)print(f"当前鼠标位置: {current_pos}")  # 打印当前鼠标位置用于调试code_text = None  # 初始化 code_text 为 Nonefor i in range(0, len(tag_ranges), 2):start = str(tag_ranges[i])  # 将 _tkinter.Tcl_Obj 转换为字符串end = str(tag_ranges[i + 1])  # 将 _tkinter.Tcl_Obj 转换为字符串print(f"代码块范围: {start} - {end}")  # 打印代码块范围用于调试if start <= current_pos <= end:code_text = self.chat_text.get(start, end)breakif code_text is not None:try:self.root.clipboard_clear()self.root.clipboard_append(code_text)print("代码块复制成功")except tk.TclError as e:print(f"剪贴板操作失败: {e}")else:print("未找到包含当前位置的代码块")def show_input_context_menu(self, event):context_menu = tk.Menu(self.root, tearoff=0)context_menu.add_command(label="复制", command=lambda: self.copy_input_text())context_menu.add_command(label="粘贴", command=lambda: self.paste_input_text())context_menu.post(event.x_root, event.y_root)def copy_input_text(self):selected_text = self.input_text.get(tk.SEL_FIRST, tk.SEL_LAST)if selected_text:self.root.clipboard_clear()self.root.clipboard_append(selected_text)def paste_input_text(self):clipboard_text = self.root.clipboard_get()if clipboard_text:self.input_text.insert(tk.INSERT, clipboard_text)def highlight_code(self):content = self.chat_text.get(1.0, tk.END)start_index = 0while True:start = content.find("===", start_index)if start == -1:breakend = content.find("===", start + 3)if end == -1:breakstart_tag = f"1.0+{start}c"end_tag = f"1.0+{end + 3}c"self.chat_text.tag_add("code", start_tag, end_tag)print(f"代码块范围: {start_tag} - {end_tag}")  # 调试信息,打印代码块范围start_index = end + 3if __name__ == "__main__":root = tk.Tk()client = OllamaClient(root)root.mainloop()

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

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

相关文章

OpenMv识别色块通过串口发给STM32

硬件连接 1、Openmv端 这里OpenMV端仅作为数据的发送端,所以只需要共地,以及OpenMV的TX(P4)与开发板的RX端连接即可。 2、STM32端 将开发板连接STM芯片RX端与转串口TX端的跳帽取下,再将OpenMV的TX端(P4)与STM的RX连接。如果使用USB转TTL则将TTL的RX端与STM的TX端连接…

以太网交换基础(涵盖二层转发原理和MAC表的学习)

在当今的网络世界中&#xff0c;以太网交换技术是局域网&#xff08;LAN&#xff09;的核心组成部分。无论是企业网络、学校网络还是家庭网络&#xff0c;以太网交换机都扮演着至关重要的角色。本文将详细介绍以太网交换的基础知识&#xff0c;包括以太网协议、帧格式、MAC地址…

菜鸟之路Day15一一IO流(一)

菜鸟之路Day15一一IO流&#xff08;一&#xff09; 作者&#xff1a;blue 时间&#xff1a;2025.2.8 文章目录 菜鸟之路Day15一一IO流&#xff08;一&#xff09;0.概述1.初识IO流1.1.什么是IO流&#xff1f;1.2.IO流的作用1.3.IO流的分类 2.IO流的体系结构3.字节输出流的基本…

汽车零部件开发应该具备哪些编程思维?

目录 1、功能安全思维 2、实时性与确定性思维 3、可靠性和冗余思维 4、硬件软件协同思维 5、CAN总线通信思维 6、故障诊断和自诊断思维 7、功耗优化思维 8、软件更新和版本管理思维 9、用户体验与安全性思维 汽车零部件开发中&#xff0c;嵌入式软件在车辆系统中的作用…

idea拉取合并后的分支

文章目录 远程拉取代码.更新本地库拉取后本地库就有了合并后的代码 远程拉取代码.更新本地库 拉取后本地库就有了合并后的代码

1-18 GIT设置公钥

1-1 GIT如何设置公钥 1.0 注册账号 这个应该都是会的&#xff0c;就不做介绍了 2.0 设置公钥 PWD的作用是查看文件的路径 ssh-keygen -t ed25519 -C "Gitee SSH Key" 读取公钥文件&#xff1a; cat ~/.ssh/id_ed25519.pub 3.0 测试 查看绑定的用户名和邮箱&#xff1…

【MySQL】 常见数据类型

MySQL常见数据类型 1.整数类型2.浮点数类型3.定点数类型4.bit类型5.字符串类型 5.1char和varchar类型5.2日期类型和时间类型5.3enum和set类型 1.整数类型 整数类型默认都是有符号整数 类型名称 字节数 类型说明 tinyint 1 带符号的范围-128127&#xff0c;无符号范围…

DeepSeek 部署中的常见问题及解决方案

DeepSeek 作为一款智能语义搜索框架&#xff0c;其本地化部署在实际操作中可能因环境配置、权限管理、硬件资源等因素遇到多种问题。本文结合当前市面上的实践经验&#xff0c;整合了部署中的常见问题及解决方案&#xff0c;帮助用户高效排查和优化部署流程。 一、权限不足问题…

《机器学习数学基础》补充资料:求解线性方程组的克拉默法则

《机器学习数学基础》中并没有将解线性方程组作为重点&#xff0c;只是在第2章2.4.2节做了比较完整的概述。这是因为&#xff0c;如果用程序求解线性方程组&#xff0c;相对于高等数学教材中强调的手工求解&#xff0c;要简单得多了。 本文是关于线性方程组的拓展&#xff0c;供…

Jenkins介绍

什么是Jenkins Jenkins 是一个开源的自动化服务器&#xff0c;主要用于持续集成和持续交付&#xff08;CI/CD&#xff09;。它帮助开发团队自动化构建、测试和部署软件&#xff0c;从而提高开发效率和软件质量。 如果一个系统是前后端分离的开发模式&#xff0c;在集成阶段会需…

module ‘cv2.dnn‘ has no attribute ‘DictValue‘解决办法

module ‘cv2.dnn‘ has no attribute ‘DictValue‘解决办法 pip install opencv-python4.7.0.72 -i https://pypi.tuna.tsinghua.edu.cn/simple 测试&#xff1a; python -c"import cv2"

【全栈】SprintBoot+vue3迷你商城-细节解析(2):分页

【全栈】SprintBootvue3迷你商城-细节解析&#xff08;2&#xff09;&#xff1a;分页 往期的文章都在这里啦&#xff0c;大家有兴趣可以看一下 后端部分&#xff1a; 【全栈】SprintBootvue3迷你商城&#xff08;1&#xff09; 【全栈】SprintBootvue3迷你商城&#xff08;…

kubeadm拉起的k8s集群证书过期的做法集群已奔溃也可以解决

kubeadm拉起的k8s集群证书过期的做法 这个是很久之前遇到的了&#xff0c;今天有空&#xff08;心血来潮&#xff09;就都回忆回忆写在这里为爱发光&#xff0c;部分内容来自arch先生&#xff08;死党&#xff09;的帮助。有时候有很多部门提了建k8s的需求&#xff0c;有些是临…

Webpack 基础入门

一、Webpack 是什么 Webpack 是一款现代 JavaScript 应用程序的静态模块打包工具。在 Web 开发中&#xff0c;我们的项目会包含各种类型的文件&#xff0c;如 JavaScript、CSS、图片等。Webpack 可以将这些文件打包成一个或多个文件&#xff0c;以便在浏览器中高效加载。它就像…

torchsparse安装过程的问题

1、项目要求torchsparse githttps://github.com/mit-han-lab/torchsparse.gitv1.4.0 2、torch1.8.1cu111 nvcc--version&#xff1a;11.1 这个版本的cuda匹配的gcc、g经常是7.5。设置为7.5. &#xff08;这个gcc、g版本修改不一定&#xff0c;可以先进行后面的&#xff0c…

嵌入式音视频开发(二)ffmpeg音视频同步

系列文章目录 嵌入式音视频开发&#xff08;零&#xff09;移植ffmpeg及推流测试 嵌入式音视频开发&#xff08;一&#xff09;ffmpeg框架及内核解析 嵌入式音视频开发&#xff08;二&#xff09;ffmpeg音视频同步 嵌入式音视频开发&#xff08;三&#xff09;直播协议及编码器…

iOS App的启动与优化

App的启动流程 App启动分为冷启动和热启动 冷启动&#xff1a;从0开始启动App热启动&#xff1a;App已经在内存中&#xff0c;但是后台还挂着&#xff0c;再次点击图标启动App。 一般对App启动的优化都是针对冷启动。 App冷启动可分为三个阶段&#xff1a; dyld&#xff1a…

oppo,汤臣倍健,康冠科技25届春招内推

oppo&#xff0c;汤臣倍健&#xff0c;康冠科技25届春招内推 ①康冠科技25届春招 【职位】算法、软件、硬件、技术&#xff0c;结构设计&#xff0c;供应链&#xff0c;产品&#xff0c;职能&#xff0c;商务 【一键内推】https://sourl.cn/2Mm9Lk 【内推码】EVBM88 ②汤臣倍健…

centos 9 时间同步服务

在 CentOS 9 中&#xff0c;默认的时间同步服务是 chrony&#xff0c;而不是传统的 ntpd。 因此&#xff0c;建议使用 chrony 来配置和管理时间同步。 以下是使用 chrony 配置 NTP 服务的步骤&#xff1a; 1. 安装 chrony 首先&#xff0c;确保系统已安装 chrony。 在 CentOS…

解锁 Python 导入系统:从基础到进阶的深度指南

本文全面解读 Python 导入系统&#xff0c;从导入机制的基础概念&#xff0c;如模块、包的导入方式&#xff0c;到查找、加载模块的详细过程&#xff0c;再到导入系统的高级特性和应用场景&#xff0c;通过丰富示例、直观图表和对比分析&#xff0c;助你深入理解并熟练运用导入…