Fivk博客 - 代码笔记
type: channel
link: https://blog.fivk.cn/category/daima/
items: 【Docker】使用 Docker 安装 PostgreSQL + pgvector 向量数据库（基于 pgvector/pgvector:pg16）
items: 【Pyenv使用教程】轻松管理Python版本的入门与进阶指南
items: 【知识总结】常用Linux应用安装
items: Python源码安装与卸载指南
items: 【MySQL】深入实践：10个提升MySQL生产力的高阶技巧
items: 【Git】Fork仓库与原仓库同步指南：告别代码冲突的终极解决方案
items: 【Linux】深入了解 Linux 中的crontab命令：定时任务的好帮手
items: 【Git】使用Git和GitHub进行团队协作和版本控制
items: 【Git】代理设置
items: 【Java】动态代理

【Docker】使用 Docker 安装 PostgreSQL + pgvector 向量数据库（基于 pgvector/pgvector:pg16）
type: item
date: 2025-06-30T21:57:00+08:00
description: 随着大模型（LLM）和向量检索（RAG、Embedding）应用兴起，向量数据库变得越来越重要。其中，PostgreSQL + pgvector 成为非常流行的一种组合方案，既能保留关系数据库的强大特性，又能高效地进行向量检索。本篇文章将手把手教你如何 使用 Docker + Docker Compose 部署 PostgreSQL 16 + pgvector 插件。1. 创建项目目录与配置文件我们建议将项目文件组织在一个单独目录下：mkdir pgvector-demo && cd pgvector-demo然后在其中创建一个 docker-compose.yml 文件，内容如下：version: '3.8' services: db: image: pgvector/pgvector:pg16 container_name: pgvector-db environment: POSTGRES_USER: myuser POSTGRES_PASSWORD: mypassword POSTGRES_DB: mydb ports: - "5432:5432" volumes: - pgdata:/var/lib/postgresql/data volumes: pgdata:说明：使用 pgvector/pgvector:pg16 镜像，内置 PostgreSQL 16 + pgvector 插件。数据保存在 Docker 卷 pgdata 中，重启不会丢失。监听宿主机端口 5432，可用本地工具如 pgAdmin, DBeaver, psql 连接。2. 启动服务在 docker-compose.yml 所在目录下运行：docker-compose up -d查看容器状态：docker ps输出应包含一个名为 pgvector-db 的容器，状态为 Up。3. 验证 pgvector 安装成功进入 PostgreSQL 容器：docker exec -it pgvector-db psql -U myuser -d mydb启用 pgvector 插件：CREATE EXTENSION IF NOT EXISTS vector; \dx你应该能看到如下输出： List of installed extensions Name | Version | Schema | Description ----------+---------+------------+---------------------------------------------- vector | 0.X | public | vector data type and distance functions (1 row)4. 插入并查询向量数据（示例）-- 创建表，包含一个向量字段（维度为3） CREATE TABLE items ( id SERIAL PRIMARY KEY, embedding vector(3) ); -- 插入向量数据 INSERT INTO items (embedding) VALUES ('[1,1,1]'), ('[2,2,2]'), ('[1,0,0]'); -- 查询与 [1,1,1] 最接近的向量（基于欧几里得距离） SELECT id, embedding FROM items ORDER BY embedding <-> '[1,1,1]' LIMIT 3;5. 常用 Docker 管理命令功能命令启动服务docker-compose up -d停止并移除容器docker-compose down查看日志docker-compose logs -f进入容器终端docker exec -it pgvector-db bash进入 psqldocker exec -it pgvector-db psql -U myuser -d mydb6. 延伸建议可以在此基础上结合 OpenAI、HuggingFace、LangChain 等工具，将 Embedding 数据写入 vector 字段。推荐使用 pgvector-py（Python SDK）或 psycopg 操作数据库。可加入 pgAdmin4 服务进行可视化管理。总结通过本教程完成了：在 Ubuntu 上使用 Docker 安装 PostgreSQL + pgvector；使用 docker-compose.yml 实现服务编排和数据持久化；插入和查询向量数据，验证向量检索功能。这个方案适用于开发环境、测试向量检索应用，甚至可在生产环境中扩展为向量增强的知识库（RAG 系统）或语义搜索平台。

【Pyenv使用教程】轻松管理Python版本的入门与进阶指南
type: item
date: 2025-03-20T11:35:00+08:00
description: [scode type="blue" size="simple"]在日常开发中，我们往往需要在同一台机器上安装和切换多个 Python 版本。pyenv 正是为此而生的一款工具，它能帮助我们方便地安装、管理和切换 Python 版本，让开发环境更加灵活。本文将详细介绍 pyenv 的安装、配置、常用命令及注意事项，帮助你快速上手并高效使用 pyenv。[/scode]1. 什么是 pyenv？pyenv 是一个轻量级的 Python 版本管理工具，它允许用户在同一台机器上安装和管理多个 Python 版本。无论你是要切换全局版本，还是为项目设置局部版本，pyenv 都能轻松实现。通过简单的命令，你可以：查看已安装的 Python 版本列表安装新版本的 Python设置全局或局部的默认 Python 版本快速切换不同项目的 Python 环境2. 安装 pyenv自动安装最便捷的安装方式是使用官方推荐的自动安装脚本。打开终端，运行以下命令：curl https://pyenv.run | bash该脚本会自动下载并安装 pyenv 以及相关插件（如 pyenv-virtualenv、pyenv-update 等）。手动安装如果你更倾向于手动安装，可以按照以下步骤操作：克隆 pyenv 仓库到本地（假设安装在 ~/.pyenv）：git clone https://github.com/pyenv/pyenv.git ~/.pyenv根据需要安装其他插件，比如 pyenv-virtualenv：git clone https://github.com/pyenv/pyenv-virtualenv.git ~/.pyenv/plugins/pyenv-virtualenv3. 环境配置安装完成后，需要将 pyenv 的可执行文件添加到系统 PATH 中，并在 shell 初始化时加载 pyenv。以 bash 为例，可以在 ~/.bashrc 或 ~/.bash_profile 文件中添加如下配置：# 将 pyenv 添加到 PATH export PATH="$HOME/.pyenv/bin:$PATH" # 初始化 pyenv eval "$(pyenv init --path)" eval "$(pyenv init -)"如果你使用 zsh，则需要在 ~/.zshrc 中做相同的配置。完成后，重新加载配置文件或重启终端即可。4. 使用 pyenv 安装 Python 版本安装好 pyenv 后，就可以开始安装所需的 Python 版本了。查看可用的 Python 版本列表：pyenv install --list安装特定版本，例如安装 Python 3.9.2：pyenv install 3.9.2安装过程可能需要一些编译依赖，请根据提示安装相应的依赖库。如果遇到问题，请参考官方文档中的依赖说明。5. 切换与管理 Python 版本设置全局默认版本安装完成后，可以使用 pyenv global 命令设置全局默认的 Python 版本：pyenv global 3.9.2这会让所有未单独指定 Python 版本的终端会话默认使用 3.9.2。设置局部版本在项目目录下，你可以使用 pyenv local 命令为该目录（及其子目录）指定特定的 Python 版本：pyenv local 3.8.10这会在项目目录中生成一个 .python-version 文件，记录当前目录使用的 Python 版本。列出已安装的版本使用以下命令查看当前已安装的所有 Python 版本：pyenv versions快速切换你可以临时使用特定版本运行 Python 脚本，而无需改变全局或局部设置：pyenv shell 3.7.9 python --version6. 常见问题及解决方案依赖问题在安装某些 Python 版本时，可能会提示缺少编译依赖。请参考系统的包管理工具安装缺少的依赖项（如 libssl-dev、zlib1g-dev 等）。命令未生效如果在配置了环境变量后仍无法使用 pyenv，请确认配置文件已正确加载，并尝试重启终端或执行 source ~/.bashrc。权限问题如果安装或运行过程中遇到权限问题，建议检查当前用户是否有足够的权限来修改相应目录，或者考虑使用 sudo 安装相关依赖，但一般不建议对 pyenv 本身使用 sudo。7. 总结pyenv 为 Python 开发者提供了一个便捷的版本管理工具，通过简单的命令可以轻松安装、切换和管理多个 Python 版本。无论你是在开发不同项目，还是需要测试不同版本的兼容性，pyenv 都能大大简化你的工作流程。希望这篇教程能帮助你快速上手，享受灵活高效的 Python 开发体验。更…

【知识总结】常用Linux应用安装
type: item
date: 2025-03-20T11:23:00+08:00
description: [post cid="6607" cover="" size=""/][post cid="6611" cover="" size=""/]

Python源码安装与卸载指南
type: item
date: 2025-03-20T11:18:00+08:00
description: [scode type="blue" size="simple"]在开发和运维过程中，我们经常需要在不同的 Linux 发行版上安装特定版本的 Python。由于各发行版的包管理器及依赖名称不同，直接利用系统自带的软件包有时无法满足需求。本文介绍一种通用的方法：通过源码编译安装 Python，同时附上卸载步骤。这种方式基本适用于 CentOS 和 Ubuntu，并能支持大部分 Python 版本（无论是 2.x 还是 3.x），只要对应版本的源码可用。[/scode]1. 为什么选择源码安装？通用性高：源码编译的方式独立于系统自带包管理器，适用于大多数 Linux 发行版；版本自由：无论你需要最新版本还是历史版本，都可以从 Python 官方网站或镜像站点获取源码；定制性强：可通过编译选项进行优化、定制安装目录，避免干扰系统默认的 Python 环境。提示： 如果你对编译过程不是很熟悉，也可以考虑 pyenv 来管理多个 Python 版本，但本文将重点介绍源码编译方法。2. 环境准备不同系统的依赖包名称有所不同，下面分别列出 CentOS 和 Ubuntu 的依赖安装步骤。在 Ubuntu 上执行以下命令安装编译所需依赖：sudo apt-get update sudo apt-get upgrade sudo apt-get install build-essential libssl-dev libffi-dev zlib1g-dev \ libncurses5-dev libncursesw5-dev libreadline-dev libsqlite3-dev \ libgdbm-dev libdb5.3-dev libbz2-dev libexpat1-dev liblzma-dev tk-dev在 CentOS 上对于 CentOS 系统，首先安装开发工具组及常用依赖：sudo yum groupinstall "Development Tools" sudo yum install openssl-devel bzip2-devel libffi-devel zlib-devel ncurses-devel \ readline-devel sqlite-devel gdbm-devel db4-devel libpcap-devel xz-devel tk-devel注意：依赖包名称可能因 CentOS 版本而略有差异，请根据实际情况调整。3. 下载与编译 Python1.下载源码从 Python 官方下载页面 或国内镜像站下载你需要安装的 Python 源码包。例如，下载 Python 3.7.17：wget https://www.python.org/ftp/python/3.7.17/Python-3.7.17.tgz2.解压源码包tar -xf Python-3.7.12.tgz cd Python-3.7.123.配置与编译配置时建议指定安装目录，并开启优化选项。为了避免覆盖系统默认 Python，使用 altinstall：./configure --prefix=/usr/local/python3.7.17 --enable-optimizations make -j$(nproc) sudo make altinstall[collapse status="false" title="【点击展开】make install与make altinstall的区别"] 在 Linux 系统上使用 make altinstall代替make install 主要是为了避免覆盖系统默认的 Python 版本。make install vs. make altinstallmake install默认会安装 Python，并创建或覆盖 /usr/bin/python 这个符号链接（symlink）。可能会影响系统的默认 Python 版本，从而导致某些系统工具（如 yum、dnf 等）出问题。make altinstall不会创建 /usr/bin/python 符号链接。只会安装 pythonX.Y（比如 python3.9），但不会覆盖 python 的默认版本。适用于多版本共存，比如安装 Python 3.9，但仍然保留 Python 2.7 作为默认版本。示例./configure --enable-optimizations make -j$(nproc) sudo make altinstall执行后：python3.9 可用（如果编译的是 3.9）。python 仍指向系统默认的 Python 版本（如 2.7 或 3.6）。如何切换 Python 版本如果需要使用新安装的 Python…

【MySQL】深入实践：10个提升MySQL生产力的高阶技巧
type: item
date: 2025-03-07T09:27:00+08:00
description: [scode type="blue" size="simple"]在日常开发中，SQL语句的优化和高效使用往往是提升数据库性能的关键。本文将分享10个容易被忽视但极具实用价值的MySQL技巧，涵盖从函数使用到查询优化的多个层面。[/scode]1. 字符处理的精准控制测试数据准备CREATE TABLE text_samples ( id INT PRIMARY KEY, content VARCHAR(100) ); INSERT INTO text_samples VALUES (1, 'Hello World'), (2, '数据库'), (3, ' 前后空格 ');对比函数演示SELECT id, content, LENGTH(content) AS byte_len, -- 字节长度 CHAR_LENGTH(content) AS char_len, -- 字符个数 TRIM(content) AS trimmed, -- 去前后空格 LENGTH(TRIM(content)) AS trimmed_byte_len FROM text_samples;执行结果idcontentbyte_lenchar_lentrimmedtrimmed_byte_len1Hello World1111Hello World112数据库93数据库93前后空格128前后空格8关键点：处理多字节字符时，CHAR_LENGTH() 比 LENGTH() 更准确反映实际字符数2. 窗口函数实战：销售分析测试数据准备CREATE TABLE sales ( sale_date DATE, product VARCHAR(50), amount DECIMAL(10,2) ); INSERT INTO sales VALUES ('2023-01-05', '手机', 5000), ('2023-01-05', '耳机', 300), ('2023-01-06', '手机', 4800), ('2023-01-07', '平板', 2500);复杂窗口函数应用SELECT sale_date, product, amount, SUM(amount) OVER(PARTITION BY product ORDER BY sale_date) AS product_total, RANK() OVER(ORDER BY amount DESC) AS amount_rank, LAG(amount, 1) OVER(PARTITION BY product ORDER BY sale_date) AS prev_amount FROM sales;执行结果sale_dateproductamountproduct_totalamount_rankprev_amount2023-01-05手机500050001NULL2023-01-06手机48009800250002023-01-07平板250025003NULL2023-01-05耳机3003004NULL业务价值：无需临时表即可实现：按产品累计销售额全品类销售额排名同类产品上次销售金额3. 递归CTE实战：企业组织架构全展开与优化本文将通过完整可执行的集团组织架构案例，深入演示递归CTE的进阶应用，涵盖：多级部门展开、层级路径生成、循环检测、性能优化等关键场景。所有示例基于MySQL 8.0+验证通过。3.1 测试环境搭建（含循环数据）部门表结构设计-- 创建带深度限制的部门表 CREATE TABLE departments ( dept_id INT PRIMARY KEY, dept_name VARCHAR(50) NOT NULL, parent_id INT DEFAULT NULL, hierarchy_level TINYINT NOT NULL DEFAULT 1, INDEX idx_parent (parent_id), CONSTRAINT fk_parent FOREIGN KEY (parent_id) REFERENCES departments(dept_id) ON DELETE CASCADE ) ENGINE=InnoDB; -- 插入测试数据（含循环风险数据） INSERT INTO departments VALUES (1, '集团公司', NULL, 1), (2, '华东事业部', 1, 2), (3, '上海分公司', 2, 3), (4, '技术研发中心', 3, 4), (5, '前端开发部', 4, 5), (6, '后端开发部', 4, 5), (7, 'HR共享中心', 1, 2), (8, '财务审计部', 1, 2), (9,…

【Git】Fork仓库与原仓库同步指南：告别代码冲突的终极解决方案
type: item
date: 2025-03-01T15:39:00+08:00
description: 引言：每个开发者都会遇到的困境[scode type="blue" size="simple"]当你满怀信心地提交PR时，突然发现原仓库早已更新迭代，这种"代码时差"的尴尬场景相信很多开发者都经历过。本文将手把手教你搭建自动化同步通道，让你fork的仓库与原仓库实时保持同步，从此告别合并冲突的烦恼。[/scode]一、建立双通道通信（配置远程仓库）1.1 诊断当前连接状态git remote -v # 典型输出示例 # origin https://github.com/yourname/repo.git (fetch) # origin https://github.com/yourname/repo.git (push)1.2 配置上游通道# 格式：git remote add upstream 原仓库地址 git remote add upstream https://github.com/original/repo.git # 验证配置 git remote -v # 现在应该看到两个remote： # origin https://github.com/yourname/repo.git (fetch) # origin https://github.com/yourname/repo.git (push) # upstream https://github.com/original/repo.git (fetch) # upstream https://github.com/original/repo.git (push)技术贴士：upstream是约定俗成的命名，但你可以自定义任何名称，保持团队统一即可二、构建同步流水线（代码同步操作）2.1 获取上游更新git fetch upstream # 输出示例： # remote: Enumerating objects: 75, done. # remote: Counting objects: 100% (75/75), done. # remote: Compressing objects: 100% (32/32), done. # remote: Total 43 (delta 28), reused 34 (delta 19) # Receiving objects: 100% (43/43), 8.21 KiB | 8.21 MiB/s, done. # Resolving deltas: 100% (28/28), completed with 12 local objects.2.2 切换主战场git checkout main # 或 master，根据仓库分支命名 # 成功提示：Switched to branch 'main' # Your branch is up to date with 'origin/main'.2.3 智能合并策略git merge upstream/main # 成功合并提示： # Updating a1b2c3d..e4f5g6h # Fast-forward # README.md | 2 +- # 1 file changed, 1 insertion(+), 1 deletion(-)高级技巧：推荐使用git rebase upstream/main保持提交历史线性三、冲突解决锦囊当看到以下提示时：CONFLICT (content): Merge conflict in file.txt Automatic merge failed; fix conflicts and then commit the result.3.1 四步解决法：使用git status定位冲突文件在编辑器中手动解决冲突（VSCode用户推荐使用内置的合并工具）标记已解决：git add <file>完成合并：git commit -m "Merge upstream changes"四、同步到你的fork仓库git push origin main # 输出示例： # Enumerating objects: 15, done. # Counting objects: 100% (15/15), done. # Delta compression using up to 8 threads # Compressing objects: 100% (8/8), done. # Writing objects: 100% (8/8), 1.01 KiB | 1.01 MiB/s, done. # Total 8 (delta 6), reused 0 (delta 0) # remote: Resolving deltas: 100% …

【Linux】深入了解 Linux 中的crontab命令：定时任务的好帮手
type: item
date: 2024-10-02T03:37:00+08:00
description: [scode type="blue" size="simple"]在 Linux 系统中，crontab 是一个强大的工具，用于设置和管理定时任务。它允许用户在特定的时间或时间间隔自动执行命令或脚本，这在自动化维护、备份、数据处理等方面非常有用。本文将深入介绍 crontab 命令的用法及其各种参数。[/scode]什么是 crontab？crontab 是 "cron table" 的缩写，表示“定时任务表”。它是一个文件，记录了用户希望在特定时间执行的任务。cron 是一个后台服务，负责按照预定时间执行这些任务。crontab 命令的基本用法crontab 的基本命令格式如下：crontab [选项]常用选项包括：-e：编辑当前用户的 crontab 文件。-l：列出当前用户的 crontab 内容。-r：删除当前用户的 crontab 文件。-i：在删除前进行确认。定时任务的时间格式crontab 中的时间格式包括五个字段，依次为分钟、小时、日期、月份和星期几，格式如下：* * * * * | | | | | | | | | +----- 星期几 (0 - 7) (星期天为0或7) | | | +------- 月份 (1 - 12) | | +--------- 日期 (1 - 31) | +----------- 小时 (0 - 23) +------------- 分钟 (0 - 59)每个字段可以是数字、通配符（如 * 代表任意值）或特定的数值范围。示例用法每小时执行：0 * * * * /path/to/command该任务将在每个小时的整点执行。每天中午12点执行：0 12 * * * /path/to/command每天中午12点执行指定的命令。每周一凌晨1点执行：0 1 * * 1 /path/to/command每周一的凌晨1点执行。每月1日的凌晨0点执行：0 0 1 * * /path/to/command每个月的1号凌晨0点执行。每5分钟执行一次：*/5 * * * * /path/to/command每5分钟执行一次任务。如何编辑和管理 crontab编辑 crontab：使用命令 crontab -e 进入编辑模式，可以添加、修改或删除任务。列出任务：使用命令 crontab -l 可以查看当前用户的所有定时任务。删除任务：使用命令 crontab -r 可以删除当前用户的所有任务。使用 -i 选项可以在删除前进行确认。注意事项在编辑 crontab 时，请确保任务命令的路径和权限设置正确。可以将命令输出重定向到文件，以便于调试和查看执行结果：0 12 * * * /path/to/command >> /path/to/logfile 2>&1如果 crontab 任务没有按预期执行，检查系统的 cron 服务是否运行。结语crontab 是 Linux 系统中不可或缺的工具，能够帮助用户轻松实现任务的自动化管理。无论是定时备份、数据处理，还是其他维护工作，合理使用 crontab 可以大大提高工作效率。如果你有更多关于 crontab 的问题或使用经验，欢迎分享讨论！

【Git】使用Git和GitHub进行团队协作和版本控制
type: item
date: 2024-01-25T15:05:00+08:00
description: [scode type="blue" size="simple"]引言：在软件开发和团队协作中，有效的版本控制和协作工具至关重要。Git和GitHub是目前最流行的版本控制系统和代码托管平台，它们提供了强大的功能和便捷的协作方式。本文将介绍Git和GitHub的基本概念和工作原理，并通过一个完整的案例演示如何使用Git和GitHub进行团队协作和版本控制。[/scode]一、Git的基本概念和工作原理版本控制系统：介绍版本控制系统的概念和作用，以及Git作为分布式版本控制系统的优势。Git的基本概念：解释Git中的常用概念，如仓库（repository）、提交（commit）、分支（branch）、标签（tag）等。Git的工作原理：详细说明Git是如何跟踪文件的变化、记录提交历史，并支持分支和合并操作的。二、GitHub的基本概念和功能代码托管平台：介绍代码托管平台的概念和作用，以及GitHub作为最受欢迎的代码托管平台的特点。GitHub的基本概念：解释GitHub中的常用概念，如仓库（repository）、分支（branch）、拉取请求（pull request）等。协作和社交功能：介绍GitHub提供的协作和社交功能，如问题追踪、讨论区、团队协作等。三、使用Git和GitHub进行团队协作和版本控制的完整案例几乎所有的版本控制系统都以某种形式支持分支。 使用分支意味着你可以把你的工作从开发主线上分离开来进行重大的Bug修改、开发新的功能，以免影响开发主线。在开发中，一般有如下分支使用原则与流程：master （生产） 分支线上分支，主分支，中小规模项目作为线上运行的应用对应的分支。develop（开发）分支是从master创建的分支，一般作为开发部门的主要开发分支，如果没有其他并行开发不同期上线要求，都可以在此版本进行开发，阶段开发完成后，需要是合并到master分支,准备上线。feature/xxxx分支从develop创建的分支，一般是同期并行开发，但不同期上线时创建的分支，分支上的研发任务完成后合并到develop分支。hotfix/xxxx分支，从master派生的分支，一般作为线上bug修复使用，修复完成后需要合并到master、test、develop分支。还有一些其他分支，在此不再详述，例如test分支（用于代码测试）、pre分支（预上线分支）等等。假设我们有一个名为"ProjectX"的项目，现在我们来演示一个使用Git和GitHub进行团队协作和版本控制的完整案例。创建项目仓库：在GitHub上创建一个新的项目仓库，命名为"ProjectX"。添加项目描述、许可证等相关信息。克隆仓库：在本地的开发环境中执行以下命令，将项目仓库克隆到本地：git clone <仓库URL>创建并切换到develop分支：在本地仓库中创建并切换到develop分支，作为主要开发分支：git checkout -b develop开发新功能：在develop分支上进行新功能的开发，例如添加一个登录页面。提交代码并推送到远程仓库：git add . git commit -m "Add login page" git push origin develop创建并切换到feature分支：为了并行开发其他功能，从develop分支创建一个名为feature/login的分支，并切换到该分支：git checkout -b feature/login develop在feature分支上开发：在feature/login分支上进行登录功能的开发。提交代码并推送到远程仓库：git add . git commit -m "Implement login functionality" git push origin feature/login合并feature分支到develop分支：开发完成后，将feature/login分支上的代码合并到develop分支，并删除feature分支：git checkout develop git merge feature/login git branch -d feature/login创建并切换到hotfix分支：发现线上有一个紧急的bug，从master分支创建一个名为hotfix/bug-fix的分支，并切换到该分支：git checkout -b hotfix/bug-fix master修复bug并合并到master分支：在hotfix/bug-fix分支上修复bug，并将修复的代码合并到master分支：git add . git commit -m "Fix critical bug" git checkout master git merge hotfix/bug-fix发…

【Git】代理设置
type: item
date: 2024-01-19T16:52:21+08:00
description: 今天出现了一个错误 Failed to connect to github.com port 443 after 21046 ms: Couldn't connect to server提示连接不上，配置代理成功了配置socks5代理git config --global http.proxy socks5 127.0.0.1:7890 git config --global https.proxy socks5 127.0.0.1:7890配置http代理git config --global http.proxy 127.0.0.1:7890 git config --global https.proxy 127.0.0.1:7890查看代理命令git config --global --get http.proxy git config --global --get https.proxy取消代理命令git config --global --unset http.proxy git config --global --unset https.proxy

【Java】动态代理
type: item
date: 2024-01-18T11:14:47+08:00
description: [scode type="share" size="simple"]在Java中，动态代理是一种机制，允许在运行时创建代理对象来代替原始对象。代理对象可以拦截并处理原始对象的方法调用，以实现额外的逻辑或行为。[/scode]动态代理主要依赖于Java的反射机制。通过动态代理，我们可以在不修改原始对象的情况下，对其方法进行增强或拦截。这对于实现横切关注点（cross-cutting concerns）非常有用，如日志记录、性能监控、事务管理等。在Java中，动态代理通常涉及两个主要角色：接口（Interface）：定义了原始对象和代理对象之间的公共方法。InvocationHandler接口：定义了代理对象的调用处理程序。它包含一个invoke()方法，该方法在代理对象上调用方法时被调用。在invoke()方法中，可以实现对原始方法的增强逻辑。使用动态代理时，我们需要以下步骤：定义接口：定义原始对象和代理对象之间的公共方法。创建InvocationHandler实现类：实现InvocationHandler接口，并在invoke()方法中编写对原始方法的增强逻辑。使用Proxy类创建代理对象：使用Proxy类的静态方法newProxyInstance()，传入ClassLoader、接口数组和InvocationHandler对象，来创建代理对象。调用代理对象的方法：通过代理对象调用方法时，将会触发InvocationHandler的invoke()方法，从而执行增强逻辑。动态代理在Java中被广泛应用于AOP（面向切面编程）等场景，它提供了一种灵活的方式来实现横切关注点的功能。下面是一个简单的案例来演示Java中的动态代理：假设我们有一个接口 Calculator，定义了一个计算器的基本功能，包括加法、减法、乘法和除法：public interface Calculator { int add(int a, int b); int subtract(int a, int b); int multiply(int a, int b); int divide(int a, int b); }现在，我们希望在每次调用这些方法时记录日志。我们可以使用动态代理来实现这个功能。首先，我们创建一个实现 InvocationHandler 接口的类 CalculatorInvocationHandler：import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class CalculatorInvocationHandler implements InvocationHandler { private Calculator target; public CalculatorInvocationHandler(Calculator target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("调用方法：" + method.getName()); Object result = method.invoke(target, args); System.out.println("方法调用结果：" + result); return result; } }然后，我们使用 Proxy 类的 newProxyInstance() 方法来创建代理对象：import java.lang.reflect.Proxy; public class Main { public static void main(String[] args) { Calculator calculator = new BasicCalculator(); CalculatorInvocationHandler invocationHandler = new CalculatorInvocationHandler(calculator); Calculator proxy = (Calculator) Proxy.newProxyInstance( calculator.getClass().getClassLoader(), calculator.getClass().getInterfaces(), invocationHandler); // 使用代理对象调用方法 int sum = proxy.add(2, 3); int differen…