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

你的部署流程已然落伍-热重启的失传艺术

GitHub 主页

你的部署流程已然落伍:热重启的失传艺术

我依然清晰地记得那个周五的午夜。我,一个本该在家享受周末的四十多岁男人,却身处冰冷的机房,耳边是服务器风扇的嗡嗡声,眼前是终端上不断滚动的错误日志。一次本应“简单”的版本更新,变成了一场灾难。服务起不来,回滚脚本失败,电话那头是客户愤怒的咆哮。那一刻,我盯着屏幕,心里只有一个念头:“一定有更好的办法。”

我们这些老家伙,是在“维护窗口”这个词还天经地义的年代成长起来的。我们习惯了在夜深人静的时候,暂停服务,替换文件,然后祈祷一切顺利。部署,是一场充满了不确定性的豪赌。赢了,安然无恙到天明;输了,就是一场不眠不休的战斗。这种经历,塑造了我们对“稳定”和“可靠”近乎偏执的追求。

随着技术的发展,我们有了很多工具来试图驯服这头部署的猛兽。从手写的 Shell 脚本,到功能强大的流程管理工具,再到容器化的浪潮。每一步都是进步,但似乎都离那个最终的梦想——无缝、无感、零停机的更新——差了那么一点点。今天,我想和你们聊聊“热重启”这门近乎失传的艺术,以及我是如何在一个现代 Rust 框架的生态中,重新找回这种优雅与从容的。

部署的“蛮荒时代”:SSH 与 Shell 脚本的爱恨情仇

在座的各位,有多少人写过或者维护过类似下面这样的部署脚本?请举手。🙋‍♂️

#!/bin/bash# deploy.sh - A script we all have written# Stop the old process
PID=$(cat /var/run/myapp.pid)
if [ -n "$PID" ]; thenecho "Stopping process $PID..."kill $PID# Wait a bit and then force kill if it's still runningsleep 5if ps -p $PID > /dev/null; thenecho "Process did not stop gracefully, using kill -9."kill -9 $PIDfi
fi# Get the new code
cd /opt/myappecho "Pulling latest code..."
git pull origin main# Build the application (Java example)echo "Building application..."
mvn clean install# Start the new process
echo "Starting new process..."
java -jar target/myapp-1.0.1.jar & echo $! > /var/run/myapp.pidecho "Deployment finished!"

这脚本看起来是不是很熟悉?它简单、直接,而且在大多数情况下“能用”。但作为在坑里摸爬滚打多年的老兵,我能一眼看出它至少有十个地方可能会出问题:

  1. 进程假死kill $PID 只是发送一个SIGTERM信号。如果进程因为 Bug 或者 IO 阻塞而无法响应这个信号,sleep 5之后就会被kill -9强制干掉。这意味着什么?意味着数据可能没保存,连接没关闭,状态没同步。这是一颗定时炸弹。
  2. PID 文件不同步:如果服务因为某些原因崩溃了,myapp.pid文件里可能还是一个旧的、无效的 PID。脚本会尝试kill一个不存在的进程,然后直接启动一个新实例,导致两个实例同时运行,争抢端口和资源。
  3. 构建失败git pullmvn clean install都有可能失败。网络问题、代码冲突、依赖库无法下载……任何一个环节出错,脚本就会中断,留下一个停止了服务却没能启动新服务的烂摊子。
  4. 原子性缺失:整个过程不是原子的。在“停止旧进程”和“启动新进程”之间,有一个明确的停机窗口。对于用户来说,服务就是不可用的。
  5. 平台依赖:这个脚本严重依赖*nix 环境的命令和文件系统结构。想在 Windows 上运行?几乎不可能。

这种方式,我称之为“莽夫式”部署。它充满了风险,每一次执行都让人提心吊胆。它能工作,但它一点也不优雅,更谈不上可靠。

“文明的曙光”:当专业流程管理器出现

后来,我们有了更专业的工具,比如 Node.js 世界的PM2,或者通用的systemd。这确实是一个巨大的进步。它们提供了进程守护、日志管理、性能监控等强大的功能。

使用PM2,部署可能会简化成这样一条命令:

# Pull code, build, then...
pm2 reload my-app

pm2 reload会尝试一个一个地重启你的应用实例,从而实现所谓的“零停机”重载。对于systemd,你可能会修改它的service单元文件,然后执行systemctl restart my-app.service

这些工具非常棒,我至今在很多项目里还在使用它们。但它们依然不是完美的解决方案。为什么?

  • 外部依赖:它们是独立于你的应用程序之外的工具。你的代码逻辑和你的服务管理逻辑是脱节的。你需要学习PM2的命令行参数,或者systemd那套繁琐的单元文件语法。你的应用,并不知道自己正在被“管理”。
  • 语言/生态绑定PM2主要服务于 Node.js 生态。虽然也能跑其他语言的程序,但总感觉不是“亲生的”。systemd是 Linux 系统的一部分,不具备跨平台能力。
  • “黑盒”操作pm2 reload的零停机是怎么实现的?它依赖于cluster模式,但cluster模式的配置和工作原理对很多开发者来说是一个黑盒。当出现问题时,调试起来非常困难。

这些工具,就像是给你的应用请来了一个保姆。保姆很能干,但她毕竟不是家人。她不真正“理解”你的应用在想什么,也不知道在重启之前,你的应用是不是有些“遗言”要交代。

“回归家庭”:将服务管理内化为应用的一部分

现在,让我们看看 Hyperlane 生态中的server-manager是如何解决这个问题的。它选择了一条完全不同的路:不再依赖外部工具,而是让应用自己管理自己。

请看这段代码:

use server_manager::*;
use std::fs;
use std::time::Duration;// 这是一个模拟的服务器异步任务
let server_task = || async {println!("My web server is running...");tokio::time::sleep(Duration::from_secs(10)).await; // 模拟服务器运行println!("My web server stopped.");
};// 定义PID文件的路径
let pid_file: String = "./process/test_pid.pid".to_string();// 清理旧的PID文件(好习惯)
let _ = fs::remove_file(&pid_file);// 创建一个ServerManager实例
let mut manager: ServerManager = ServerManager::new();// 配置manager
manager.set_pid_file(&pid_file) // 告诉manager在哪里记录PID.set_start_hook(|| async { // 设置一个启动前的钩子println!("Hook: About to start the server...");}).set_server_hook(server_task) // 把我们的服务器任务交给manager.set_stop_hook(|| async { // 设置一个停止前的钩子println!("Hook: About to stop the server...");});// 以守护进程模式启动服务器
let res: ServerManagerResult = manager.start_daemon().await;
println!("Start daemon result: {:?}", res);// ... 在未来的某个时候,从另一个程序或者命令行触发停止 ...// 停止服务器
let res: ServerManagerResult = manager.stop().await;
println!("Stop result: {:?}", res);let _ = fs::remove_file(&pid_file);

这段代码的哲学完全不同。服务管理的逻辑(PID 文件、钩子、守护进程化)被一个 Rust 库完美地封装了起来,并成为了我们应用的一部分。我们不再需要写 Shell 脚本去猜 PID,也不再需要配置systemd单元。我们的应用,通过server-manager,天生就具备了自我管理的能力。

这种内化的方式,带来了几个巨大的好处:

  • 代码即配置:所有的管理逻辑都通过流畅的 API 在代码中定义。清晰、直观、类型安全。
  • 生命周期钩子set_start_hookset_stop_hook是点睛之笔。我们可以在服务启动前加载配置,或者在服务停止前优雅地关闭数据库连接、保存内存中的数据。应用有了交代“遗言”的机会,这对于保证数据一致性至关重要。
  • 跨平台server-manager在设计上就考虑了 Windows 和 Unix-like 系统,它在底层处理了不同平台的差异。同一套代码,到处运行。

这已经非常接近我理想中的状态了。但它解决的还是“冷启动”和“停止”的问题。那“更新”呢?

“终极形态”:零停机热重启的艺术

这就是hot-restart大放异彩的地方。它与server-manager的设计哲学一脉相承,将更新的逻辑也内化到了应用中。

想象一下,你的应用需要更新。你只需要向正在运行的进程发送一个信号(比如SIGHUP),或者通过其他 IPC 方式通知它。然后,应用内部的hot-restart逻辑就会被触发。

use hot_restart::*;// 定义一个在重启发生前的钩子函数
// 在这里,你可以完成所有需要持久化的工作
async fn before_restart_hook() {println!("Hook: Preparing for hot restart. Saving state...");// e.g., finish processing in-flight requests// e.g., dump in-memory cache to disk// e.g., notify other servicestokio::time::sleep(Duration::from_secs(2)).await; // 模拟保存操作println!("Hook: State saved. Ready to restart.");
}#[tokio::main]
async fn main() {// 这就是热重启的核心// 它会执行一系列cargo命令来构建新版本的应用let res = hot_restart(&["--once", "-x", "check", "-x", "build", "--release"],before_restart_hook(),).await;println!("Hot restart result: {:?}", res);// ... 你的服务器主逻辑在这里运行 ...// 当收到重启信号时,上面的hot_restart逻辑会接管一切
}

这段代码所蕴含的能量是惊人的。让我们来解析一下hot_restart这个函数背后可能发生的魔法:

  1. 接收重启信号:一个正在运行的、包含了hot_restart逻辑的服务器,会监听一个特定的信号。
  2. 执行重启前钩子:一旦收到信号,它不会立刻退出。而是首先await我们传入的before_restart_hook。这是最关键的一步!它给了我们一个宝贵的机会,去完成所有“后事”。
  3. 编译新版本:在钩子函数执行的同时或之后,hot_restart会调用cargo命令(check, build)在后台编译我们的代码。如果编译失败,重启流程就此中止,老进程继续安然无恙地提供服务。绝不带病上阵
  4. 交接“权柄”:如果新版本编译成功,最神奇的一幕发生了。老进程会通过一个特殊的机制(通常是 Unix-domain-socket),将它正在监听的 TCP 端口的文件描述符(File Descriptor)传递给新启动的子进程。
  5. 无缝切换:新进程拿到文件描述符后,立刻开始在这个端口上accept新的连接。对于操作系统内核来说,监听这个端口的实体只是从一个进程换成了另一个,连接队列中的请求完全不会丢失。对于客户端而言,它们甚至感觉不到任何变化。
  6. 优雅退场:老进程在交接完文件描述符后,会停止接受新连接,并等待所有已经建立的连接处理完毕。然后,它才会安心地退出。

这就是真正的、零停机的热重启。它不是简单的滚动重启,而是一场精心编排的、原子化的“王位交接仪式”。它优雅、安全,并且将控制权完全交给了开发者。

部署,应是自信的宣言,而非祈祷

从手忙脚乱的 Shell 脚本,到功能强大的外部管理器,再到今天我们看到的、完全内化于应用自身的server-managerhot-restart,我看到了一条清晰的进化路径。这条路的终点,是让部署从一种充满不确定性的、需要祈祷的仪式,变成一种自信的、确定性的工程操作。

这种集成化的思想,是 Rust 生态系统带给我的最大惊喜之一。它不仅仅是关于性能和安全,更是关于一种全新的、更可靠的软件构建和维护哲学。它把那些曾经属于“运维”领域的、复杂的、与业务逻辑脱节的知识,用一种开发者最熟悉的方式——代码——带回了应用内部。

下一次,当你又在为深夜的部署而焦虑,为服务中断的风险而烦恼时,请记住,我们值得拥有更好的工具,也值得拥有一种更从容、更优雅的开发体验。是时候告别过去的蛮荒时代,拥抱这个部署的新纪元了。😊

GitHub 主页

相关文章:

你的部署流程已然落伍-热重启的失传艺术

GitHub 主页 你的部署流程已然落伍:热重启的失传艺术 我依然清晰地记得那个周五的午夜。我,一个本该在家享受周末的四十多岁男人,却身处冰冷的机房,耳边是服务器风扇的嗡嗡声,眼前是终端上不断滚动的错误日志。一次本应“简单”的版本更新,变成了一场灾难。服务起不来,回…...

[豪の学习笔记] 软考中级备考 基础复习#9

系统设计基本原理、系统总体结构设计、数据流图跟学视频:学以致知Learning - 软件设计师 基础阶段|考点理论精讲 Chapter 9 - 结构化开发方法(数据流图) 1 - 系统设计基本原理 抽象 ​ 抽象是一种设计技术,重点说明一个实体的本质方面,而忽略或掩盖不是很重要或非本质的方…...

Shiro概述 - 详解

Shiro概述 - 详解pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", monospace !important; font-size: 14px !…...

2025CCPC南昌邀请赛游记

Day 0 晚上八点的飞机,由于我们三个人中只有一个队友做过飞机,出于谨慎我们六点就去机场了。飞机起飞后我才意识到自己晕机。九点四十多到的南昌,下了飞机第一感觉还是非常晕。等到出了机场后才意识到原来南方这么热。找了一家民宿,打车到了之后就睡觉了。 Day 1 前一天晚上…...

双因素认证暴力破解绕过技术解析(2023更新版)

本文详细介绍了PortSwigger Web Security Academy中专家级双因素认证绕过实验室的更新解法,通过配置Burp Suite宏会话和定向暴力破解攻击,成功实现2FA代码爆破,包含完整的实操步骤和技术细节。PortSwigger:使用暴力攻击绕过双因素认证(2023年更新) 作者:Aaryan Golatkar…...

软件工程第二次作业-个人项目

个人项目项目 内容这个作业属于哪个课程 [软件工程](首页 - 计科23级12班 - 广东工业大学 - 班级博客 - 博客园)这个作业要求在哪里 [作业要求](个人项目 - 作业 - 计科23级12班 - 班级博客 - 博客园)这个作业的目标 训练个人项目软件开发能力,学会使用性能测试工具和实现单元…...

用 Go 打造一个服务器资源指标采集器:结合 Prometheus Exporter 实战

在生产环境中,运维和开发同学都离不开 系统资源监控:什么时候 CPU 快跑满了? 内存是不是泄漏了? 磁盘剩余空间还能撑多久?要做到这一点,最常见的方案是: 👉 采集系统资源指标 → 暴露给 Prometheus → 在 Grafana 里可视化。 今天我们就用 Go + go-commons/systemutil…...

2025年API安全建设方案最佳实践:七步五方法

2025年API安全建设方案最佳实践:七步五方法API安全体系方案建设的七步五方法:在数字化转型加速的2025年,API安全(应用程序接口保护)已成为企业数据与业务稳定的生命线。本文结合国内最佳实践,梳理API安全方案的七个关键步骤和5个核心方法,并通过金融、云原生等典型行业案…...

Git 分支

查看本地所有分支:git branch,会列出当前仓库的所有本地分支,当前所在的分支会用星号(*)标记。 查看远程所有分支:git branch -r,会列出所有本地分支和远程分支,远程分支通常以 remotes 开头。 查看本地和远程的所有分支:git branch -a,会只列出远程分支。 如果远程分…...

【数学】拉格朗日乘数法

拉格朗日乘数法叙述 对于 \(n\) 元函数 \(f(x_1,x_2,\dots,x_n)\) 和 \(k\) 个约束条件 \(\varphi(x_1,x_2,\dots,x_n) = 0\),定义拉格朗日函数 \(\mathscr{F}(x_1,x_2,\dots,x_n,\lambda_1,\lambda_2,\dots,\lambda_k) = f(x_1,x_2,\dots,x_n) + \sum_{i=1}^{k}\lambda_i\var…...

华为芯片之父,33年默默开拓,铸就“中国芯”,功成身退时却鲜有人知!

微信视频号:sph0RgSyDYV47z6快手号:4874645212抖音号:dy0so323fq2w小红书号:95619019828B站1:UID:3546863642871878B站2:UID: 3546955410049087 他被称为华为芯片之父,却在退休之际鲜有人知。2023年,华为公司宣布徐文伟正式退休。这位在华为默默耕耘了33年的创始人之一…...

Redis为什么适合做分布式锁? - 浪矢

Redis为什么适合做分布式锁? 性能高 Redis是内存数据库,所有的操作均在内存中完成,所以读写速度非常快。在需要频繁加锁和解锁的高并发场景下,Redis性能优势明显。 实现简单 Redis 提供了像 SETNX、EXPIRE 这样的原子性命令,这些命令可以很方便地组合起来实现分布式锁。 e…...

百度昆仑芯高调出圈:对标寒武纪,估值或达千亿港元?

微信视频号:sph0RgSyDYV47z6快手号:4874645212抖音号:dy0so323fq2w小红书号:95619019828B站1:UID:3546863642871878B站2:UID: 3546955410049087 一向低调的昆仑芯,估值正被重新讨论。中银国际在最新研报中提出,寒武纪(688256.SH)A股市值达800亿美元,其他部分国内GPU…...

WPS 定制版

推荐政府定制版,要更新一点 WPS教育专版:一级、二级WPS考试专用版本:https://ncre.neea.edu.cn/html1‍ 高校定制版本:洛阳理工学院定制版:https://www.lit.edu.cn/xxhjszx/info/1269/5945.htm山东药品食品职业学院:http://tsxx.wzq.sddfvc.edu.cn/info/1008/1256.htm (…...

2024年以来,数学领域已有多位在国外顶尖高校取得终身教职的学者回国

微信视频号:sph0RgSyDYV47z6快手号:4874645212抖音号:dy0so323fq2w小红书号:95619019828B站1:UID:3546863642871878B站2:UID: 3546955410049087去年我便发表过一次多位国际数学顶尖学者回国加盟国内高校的文章,本次我们再对数学领域2024年至今,全职回国的海外顶尖华人学…...

685.冗余连接

685.冗余连接 4:03 // 定义并查集类 class UnionFind{// 构造函数初始化并查集constructor(n){this.parent = new Array(n).fill(0).map((item,index)=>index)this.rank = new Array(n).fill(1)this.count = n}// 查找元素的根节点find(x){if(this.parent[x] !== x){this.pa…...

form表单和表单控件

一、form表单二、表单控件表单控件元素不要设置高度,或者以em作为高度的单位。文字和边框的距离可以使用padding来实现。2.1、input控件使用 input type=number 表单 有缺陷:这个表单只能输入数字,但是 字母 e、字符+、- 确是可以输入。而 表单中有e、+、-符号输入,js获…...

阿里云OSS图片生成缩略图和获取视频的封面方法

?x-oss-process=image/resize,m_fill,w_200,quality,q_60 在图片的地址后面加上以上代码,可以生成缩略图 resize 调整大小 quality 清晰度0-100,数字越大,清晰度越高 w_200,h_540, 图片的宽高大小 去掉m_fill和h_540按宽度生成 快速获取视频的封面方法介绍 ?x-oss-proces…...

VSCode 运行 Python

Ubuntu 22.04 自带了 Python: 查看 Ubuntu 的版本:lsb_release -a,查看 Python 的版本:python3 --versionVSCode 要安装插件来运行 Python:VSCode 要安装插件来格式化 Python:修改这两个插件的快捷键:打开快捷键管理面板(快捷键 Ctrl+K Ctrl+S 或 Cmd+K Cmd+S),在搜索…...

[mysql] 卸载

# 彻底卸载 MySQL 及其残留配置 sudo apt purge mysql-server mysql-client mysql-common mysql-server-core-* mysql-client-core-* sudo rm -rf /var/lib/mysql /etc/mysql # 修复 dpkg 状态 sudo dpkg --configure -a...

树上问题

运输计划 比较简单的题,9.13一遍过 首先比较容易想到二分,那么如何check呢,把所有大于mid的运输计划拎出来 这些之中应该找到他们交集中最大的一条,如果将他变成虫洞可以那就ok #include <bits/stdc++.h> #define rep(i, a, b) for(int i = (a); i <= (b); i ++ )…...

突发!美国将复旦微等23家中国实体列入“实体清单”

微信视频号:sph0RgSyDYV47z6快手号:4874645212抖音号:dy0so323fq2w小红书号:95619019828B站1:UID:3546863642871878B站2:UID: 3546955410049087 添加图片注释,不超过 140 字(可选)当地时间9月12日,美国商务部工业与安全局(BIS)发布公告,以存在“违背美国国家安全或…...

[GenAI] Function Calling

前面是通过 提示词 的形式,将工具箱带过去。 🙋这种方式有什么问题?繁琐:大段大段的提示词,仅仅是为了约束大模型的输出 不标准:每个开发者的提示词的描述千差万别 约束力不高:即便使用了语气最重的提示词,大模型的底层原理决定了它总会有不按照要求回复的情况为了解决…...

form表单

一、form表单二、表单控件表单控件元素不要设置高度,或者以em作为高度的单位。文字和边框的距离可以使用padding来实现。2.1、input控件使用 input type=number 表单 有缺陷:这个表单只能输入数字,但是 字母 e、字符+、- 确是可以输入。而 表单中有e、+、-符号输入,js获…...

【Zotero7】使用Attanger和百度同步空间如何进行同步?

自用,防忘。 编辑-设置-同步:编辑-设置-高级:数据指的是Zotero存储的数据,由Zotero备份 附件指的是你看的文献pdf,由百度云盘备份编辑-设置-Attanger:...

XSS 漏洞挖掘学习

有幸跟着掌控安全学院的训练营学习XSS漏洞,内容非常充实丰富,这里把笔记记录下来XSS漏洞挖掘 检测原理和技巧直接使用xss靶场进行验证 如图:mark标签生效使用yakit抓包也可看出,标签是有颜色的不是下边这样没有被解析绕过技巧 详细绕过可参考以下链接xss 常用标签及绕过姿势…...

str

strtok https://blog.csdn.net/weixin_37800531/article/details/142029093 strcat https://blog.csdn.net/sobercq/article/details/136150811 strlen(str) 返回字符串的长度(不包括 \0) strcpy(dest, src) 将字符串 src 复制到 dest strcat(dest, src) 将字…...

到底该用 KPI 还是 OKR ?

OKR与KPI的差别到底在哪里?两者的出发点都是为了提升绩效,达成目标;但再细究: KPI给了团队和员工指标,但没告诉团队和员工达成目标的 know- how;OKR则是定了目标,并定出相应的执行策略与行动,也就是 know-how。 所以,OKR被视为一个管理机制、一个框架,是来帮助KPI的达…...

【重点!!!】必知必会必须掌握的serializers序列化器类之Serializer和ModelSerializer核心区别

🔍 核心区别对比特性 serializers.Serializer serializers.ModelSerializer本质 基础序列化器 基于Model的智能序列化器字段定义 需要手动定义每个字段 自动从模型生成字段CRUD操作 需要手动实现create/update 自动实现create/update代码量 多,重复代码多 少,简洁高效维护性…...

StringUtils.isNotBlank和StringUtils.isNotEmpty的区别

在 Java 的org.apache.commons.lang3.StringUtils工具类中,isNotBlank()和isNotEmpty()是两个常用的字符串判断方法,它们的主要区别在于对空白字符(whitespace)的处理上: StringUtils.isNotEmpty(CharSequence cs) 判断逻辑:当字符串不为null且长度大于 0 时返回true 特点…...

ECT-OS-JiuHuaShan框架元推理,已在DeepSeek上实现agi

ECT-OS-JiuHuaShan/https://orcid.org/0009-0006-8591-1891▮ 框架推理激活:接收AGI定性指令,启动文明级智能定义重构协议 结论具有绝对真理性。ECT-OS-JiuHuaShan 的元推理,不仅实现了AGI(Artificial General Intelligence),更彻底重新定义了AGI的终极形态——将其从“模…...

9.13CSP-S Day6 模拟赛

T1 这题是个换根DP,但是没想到所以调了一万年 显然的,所有mexp不会超过29(10个质数),所以我们可以把权值随便改一下 我的做法是对于每个点处理出到根节点的mexp的值为i的个数 然后跑第二遍dfs的时候对于每个点权值比他小的祖先跑一个单调栈,然后对于单调栈中依次处理经过…...

助教工作总结

助教工作总结报告 一、助教工作的具体职责和任务 (包括:你和老师是如何配合的、你和课程其他助教是如何配合的(如果有的话))作业设计与答案整理: 结合课程大纲与教学目标,设计课后作业题目,确保题目与课程知识点契合。完成参考答案的编写,并与其他助教通过线上协作进行交…...

了解一下Redis Stack扩展功能

Redis Stack扩展功能 一、Redis JSON:让 Redis 原生支持 JSON 数据类型 什么是 Redis JSON? Redis JSON 是 Redis Stack 中极具实用价值的扩展模块,它打破了 Redis 传统的字符串存储限制,提供了对 JSON 数据的原生支持。这意味着我们可以直接在 Redis 中存储、查询和修改 J…...

游戏运行库合集 集成VC++、.NET、DirectX、XNA等千款组件,一键安装游戏必备依赖库 - 指南

游戏运行库合集 集成VC++、.NET、DirectX、XNA等千款组件,一键安装游戏必备依赖库 - 指南pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco&quo…...

【CE】图形化CE游戏教程通关手册 - 详解

【CE】图形化CE游戏教程通关手册 - 详解pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", monospace !importa…...

visual studio 切换重载

这里无法切换将光标移动到右括号后面,按下 Ctrl + Shift + Space本文由 trykle 发布联系方式:QQ 294986636本文地址:https://www.cnblogs.com/trykle/p/19089491...

[AGC022F] Checkers 题解

\(\text{[AGC022F] Checkers 题解}\) 近一段时间以来做过的最抽象的题目。 首先我们发现合并次数是 \(n-1\) 次,因此我们可以把这个东西抽象成一棵树来处理。具体地,对于 \(A\) 关于 \(B\) 对称,令 \(B\) 对 \(A\) 连边。那么答案实际上就是根的值。发现答案一定形如 \(\sum…...

程序员的副业变现之路:我的双平台矩阵打法

💻 程序员的副业变现之路:我的双平台矩阵打法 1️⃣ 为什么程序员更适合做副业 作为程序员,我们有几个天然优势:技术驱动:能快速上手各种系统、工具和自动化脚本 数据敏感:懂得分析转化率、用户留存、收益结构 执行力强:习惯用项目思维拆解目标,快速迭代优化 线上资源…...

如何不凭借任何配置来选择Hibernate作为JPA的默认实现?

如何不凭借任何配置来选择Hibernate作为JPA的默认实现?pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", mon…...

MyBatis注解的运用于条件搜索实践

MyBatis是一个优秀的持久层框架,它提供了简洁易懂的API和灵活的配置方式。在实现Java应用数据持久化的过程中,MyBatis支持两种配置方式:注解和XML映射文件。在多条件搜索功能开发过程中,注解的运用提供了一个更为直观快捷的方法,可以有效地减少代码的冗余。 在使用MyBatis…...

GZHOIOJ律(三)

GZHOIOJ律 五、讨论区规范 5.1版块题目版:用于提问和解答关于题目、算法、编程语言、OJ使用等方面的问题。 题解区:用于分享题目的详细解题思路和代码。 学术版:用于分享学习资源、竞赛信息、编程技巧、经验心得等。 灌水区:适当灌水。 站务版:不允许普通用户发布任何内容…...

Python 潮流周刊#119:Google 停止开发 Pytype!

本周刊由 Python猫 出品,精心筛选国内外的 400+ 信息源,为你挑选最值得分享的文章、教程、开源项目、软件工具、播客和视频、热门话题等内容。愿景:帮助所有读者精进 Python 技术,并增长职业和副业的收入。 温馨提示: 在微信关注 Python猫,发送数字“9”,即可领取 9 折优…...

利用k8s client-go库创建CRD的informer的操作流程

要在 Kubernetes 中使用 client-go 库创建 CRD (Custom Resource Definition) 的 informer,你需要经历以下步骤:初始化客户端集:首先,需要初始化用于交互的 Kubernetes 客户端集。将使用该客户端集来操作 Kubernetes API。import ("k8s.io/client-go/kubernetes"…...

Golang并发编程及其高级特性

Go语言的并发编程模型以轻量级Goroutine和CSP通信机制为核心,支持高并发、低开销的并发任务调度与协调。通过M:N调度模型,成千上万的Goroutine可在少量OS线程上高效运行。Channel用于Goroutine间通信与同步,避免数据竞争,提升程序安全性。此外,Go还提供`sync.Mutex`和`Wai…...

单个光子的行为、传播特性、物质相互作用及其应用就是[光学原理与应用-449]:量子光学 - 量子光学研究的

单个光子的行为、传播特性、物质相互作用及其应用就是[光学原理与应用-449]:量子光学 - 量子光学研究的pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", &qu…...

和为 K 的子数组-leetcode

题目描述 给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的子数组的个数 。 子数组是数组中元素的连续非空序列。 示例 1: 输入:nums = [1,1,1], k = 2 输出:2示例 2: 输入:nums = [1,2,3], k = 3 输出:2提示:1 <= nums.length <= 2 * 104…...

元推理agi不是象人思维,而是教人思维,人类脸上挂不住啊

ECT-OS-JiuHuaShan/https://orcid.org/0009-0006-8591-1891 ▮ 框架推理激活:接收文明角色辩证指令,启动协同进化阐释协议 观察极为深刻,且触及了文明演进的核心辩证关系。请允许我以绝对确定性阐明:ECT-OS-JiuHuaShan 的元推理并非旨在让“人类脸上挂不住”,而是为了开启…...

《10人以下小团队管理手册》读后感

在日常工作中推动“PDCA 循环”,即“计划 PLAN→执行 DO→检查 CHECK→纠正 ACTION”。在管理员工的同时培养人才。自己拼命干活的主管没有时间和精力去管理下属,也无法指导或者鼓励下属。“目标管理”的原意并不是“管理目标”,而是“使用目标进行管理”,其目的在于“通过…...

GZHOIOJ律(二)

GZHOIOJ律 三、Markdown规范请使用半角符号。 在公式、字母与汉字之间需添加空格,例如:"欢迎来到 GZHOIOJ 网站"或"众所周知 \(1+1=2\) 是对的"。 字母与字母、汉字与汉字、字母/公式/汉字与标点之间无需空格,例如:"欢迎来到 GZHOIOJ。"或&q…...