<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>文章 on Kerolt's Note</title><link>https://kerolt.github.io/post/</link><description>Recent content in 文章 on Kerolt's Note</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Mon, 05 Oct 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://kerolt.github.io/post/index.xml" rel="self" type="application/rss+xml"/><item><title>Pi 远程 SSH 图片剪贴板插件配置与踩坑</title><link>https://kerolt.github.io/p/pi-%E8%BF%9C%E7%A8%8B-ssh-%E5%9B%BE%E7%89%87%E5%89%AA%E8%B4%B4%E6%9D%BF%E6%8F%92%E4%BB%B6%E9%85%8D%E7%BD%AE%E4%B8%8E%E8%B8%A9%E5%9D%91/</link><pubDate>Mon, 05 Oct 2026 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/pi-%E8%BF%9C%E7%A8%8B-ssh-%E5%9B%BE%E7%89%87%E5%89%AA%E8%B4%B4%E6%9D%BF%E6%8F%92%E4%BB%B6%E9%85%8D%E7%BD%AE%E4%B8%8E%E8%B8%A9%E5%9D%91/</guid><description>&lt;h2 id="前言"&gt;前言&lt;/h2&gt;
&lt;p&gt;在 Mac 上通过 VS Code Remote SSH 连到远端无图形界面的 Fedora 开发机使用 Pi 时，按 &lt;code&gt;Ctrl+V&lt;/code&gt; 默认读不到 Mac 本地的剪贴板图片。&lt;/p&gt;
&lt;p&gt;解决思路很简单：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Mac 端&lt;/strong&gt;：通过 &lt;code&gt;pngpaste&lt;/code&gt; 导出剪贴板图片，用 &lt;code&gt;launchd&lt;/code&gt; 监听端口（inetd 模式按需调用）；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;传输层&lt;/strong&gt;：通过 SSH 反向隧道（&lt;code&gt;RemoteForward&lt;/code&gt;）把 Mac 本地的服务暴露给 Fedora 的 &lt;code&gt;127.0.0.1:7779&lt;/code&gt;；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Fedora 端&lt;/strong&gt;：安装 &lt;a href="https://github.com/kerolt/pi-ssh-image-clipboard"&gt;&lt;code&gt;pi-ssh-image-clipboard&lt;/code&gt;&lt;/a&gt; 插件（fork 自 &lt;a href="https://github.com/pasky/pi-ssh-image-clipboard"&gt;pasky/pi-ssh-image-clipboard&lt;/a&gt;），拦截 &lt;code&gt;Ctrl+V&lt;/code&gt;，从 &lt;code&gt;127.0.0.1:7779&lt;/code&gt; 读取图片写入 &lt;code&gt;/tmp/&lt;/code&gt;，并将文件路径填入 Pi 输入框。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="mermaid" style="visibility:hidden"&gt;flowchart LR
A[Mac 剪贴板] --&gt; B[launchd + pngpaste
127.0.0.1:7779]
B --&gt;|SSH RemoteForward| C[Fedora
127.0.0.1:7779]
C --&gt; D[pi-ssh-image-clipboard]
D --&gt; E[`/tmp/pi-clipboard-UUID.png`]
E --&gt; F[Pi 输入框]&lt;/pre&gt;
&lt;p&gt;整个链路不复杂，但配置时最容易踩的坑是：&lt;strong&gt;以为在 &lt;code&gt;~/.ssh/config&lt;/code&gt; 里写了 &lt;code&gt;RemoteForward&lt;/code&gt; 就完事了，实际当前已有的 VS Code SSH 连接或 ControlMaster 并不会动态补上新转发&lt;/strong&gt;。&lt;/p&gt;</description></item><item><title>Headless Server Portal 认证与远程桌面排障全记录</title><link>https://kerolt.github.io/p/headless-server-portal-%E8%AE%A4%E8%AF%81%E4%B8%8E%E8%BF%9C%E7%A8%8B%E6%A1%8C%E9%9D%A2%E6%8E%92%E9%9A%9C%E5%85%A8%E8%AE%B0%E5%BD%95/</link><pubDate>Sat, 05 Sep 2026 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/headless-server-portal-%E8%AE%A4%E8%AF%81%E4%B8%8E%E8%BF%9C%E7%A8%8B%E6%A1%8C%E9%9D%A2%E6%8E%92%E9%9A%9C%E5%85%A8%E8%AE%B0%E5%BD%95/</guid><description>&lt;h2 id="背景与网络拓扑"&gt;背景与网络拓扑&lt;/h2&gt;
&lt;p&gt;在一台运行 &lt;strong&gt;Fedora 44 Server&lt;/strong&gt; 的无显示器（Headless）高性能计算服务器上，机器同时接入了多套网络。其中，校园有线网需要通过 &lt;strong&gt;Dr.COM Web Portal&lt;/strong&gt; 进行网页登录认证。由于服务器未安装默认图形界面，且存在多网卡出口路由竞争，无法直接弹窗认证。&lt;/p&gt;</description></item><item><title>Hermes Session 管理：飞书/微信/CLI 统一会话模型</title><link>https://kerolt.github.io/p/hermes-session-%E7%AE%A1%E7%90%86%E9%A3%9E%E4%B9%A6-%E5%BE%AE%E4%BF%A1-cli-%E7%BB%9F%E4%B8%80%E4%BC%9A%E8%AF%9D%E6%A8%A1%E5%9E%8B/</link><pubDate>Tue, 25 Aug 2026 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/hermes-session-%E7%AE%A1%E7%90%86%E9%A3%9E%E4%B9%A6-%E5%BE%AE%E4%BF%A1-cli-%E7%BB%9F%E4%B8%80%E4%BC%9A%E8%AF%9D%E6%A8%A1%E5%9E%8B/</guid><description>&lt;h2 id="背景"&gt;背景&lt;/h2&gt;
&lt;p&gt;Hermes 把 CLI、TUI、桌面 app、几十种 messaging 平台（飞书/微信/Telegram/Discord/Slack…）接到同一份&amp;quot;agent core&amp;quot;上。理解它的 session 模型，是理解为什么&amp;quot;我换个入口跟它说话&amp;quot;和&amp;quot;我在同个地方继续说&amp;quot;行为完全不同的关键。&lt;/p&gt;</description></item><item><title>Hugo content 目录的页面类型与组织方式</title><link>https://kerolt.github.io/p/hugo-content-%E7%9B%AE%E5%BD%95%E7%9A%84%E9%A1%B5%E9%9D%A2%E7%B1%BB%E5%9E%8B%E4%B8%8E%E7%BB%84%E7%BB%87%E6%96%B9%E5%BC%8F/</link><pubDate>Sun, 09 Aug 2026 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/hugo-content-%E7%9B%AE%E5%BD%95%E7%9A%84%E9%A1%B5%E9%9D%A2%E7%B1%BB%E5%9E%8B%E4%B8%8E%E7%BB%84%E7%BB%87%E6%96%B9%E5%BC%8F/</guid><description>&lt;h2 id="核心结论"&gt;核心结论&lt;/h2&gt;
&lt;p&gt;Hugo 的 &lt;code&gt;content&lt;/code&gt; 目录不是简单的 Markdown 文件仓库，而是一棵 Page Tree。目录层级和特殊文件名会决定页面的 &lt;code&gt;Kind&lt;/code&gt;、&lt;code&gt;Section&lt;/code&gt;、&lt;code&gt;Type&lt;/code&gt;、Bundle 类型、模板选择、资源归属以及默认 URL。&lt;/p&gt;</description></item><item><title>Hugo Theme Stack 对默认 Taxonomy 的处理</title><link>https://kerolt.github.io/p/hugo-theme-stack-%E5%AF%B9%E9%BB%98%E8%AE%A4-taxonomy-%E7%9A%84%E5%A4%84%E7%90%86/</link><pubDate>Sun, 09 Aug 2026 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/hugo-theme-stack-%E5%AF%B9%E9%BB%98%E8%AE%A4-taxonomy-%E7%9A%84%E5%A4%84%E7%90%86/</guid><description>&lt;h2 id="核心结论"&gt;核心结论&lt;/h2&gt;
&lt;p&gt;Stack 没有重新实现 Taxonomy 系统。Hugo 负责读取文章 Front Matter、建立 Taxonomy 与 Term 的关联、生成页面对象和 URL；Stack 负责调用 Hugo 提供的 &lt;code&gt;.Site.Taxonomies&lt;/code&gt;、&lt;code&gt;.GetTerms&lt;/code&gt; 和 &lt;code&gt;.Pages&lt;/code&gt;，将这些数据展示为分类徽章、文章标签、侧栏 Widget、归档入口以及列表页面。&lt;/p&gt;</description></item><item><title>Git Submodule 版本锁定</title><link>https://kerolt.github.io/p/git-submodule-%E7%89%88%E6%9C%AC%E9%94%81%E5%AE%9A/</link><pubDate>Thu, 06 Aug 2026 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/git-submodule-%E7%89%88%E6%9C%AC%E9%94%81%E5%AE%9A/</guid><description>&lt;h2 id="核心本质submodule-是什么"&gt;核心本质：Submodule 是什么？&lt;/h2&gt;
&lt;p&gt;Git Submodule 并不是简单的“文件夹克隆”，它是父仓库中指向子仓库某个&lt;strong&gt;特定提交（Commit ID）&lt;/strong&gt; 的指针。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;.gitmodules&lt;/code&gt; 文件&lt;/strong&gt;：账本。记录子模块的远程仓库地址（URL）和本地存放路径（Path）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Gitlink (160000 模式)&lt;/strong&gt;：锁。父仓库索引中记录的一个 40 位哈希值。它确保了无论子仓库如何更新，父仓库始终锁定在特定的版本。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="版本锁定如何固定到-tag-如-v022"&gt;版本锁定：如何固定到 Tag (如 v0.2.2)？&lt;/h2&gt;
&lt;p&gt;在 Git 中，锁定版本&lt;strong&gt;不是修改文本文件&lt;/strong&gt;，而是&lt;strong&gt;移动指针&lt;/strong&gt;。&lt;/p&gt;</description></item><item><title>nmcli 快速参考</title><link>https://kerolt.github.io/p/nmcli-%E5%BF%AB%E9%80%9F%E5%8F%82%E8%80%83/</link><pubDate>Sun, 28 Jun 2026 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/nmcli-%E5%BF%AB%E9%80%9F%E5%8F%82%E8%80%83/</guid><description>&lt;h2 id="基本结构"&gt;基本结构&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;nmcli [对象] [动作] [参数]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;主要对象：&lt;code&gt;con&lt;/code&gt;（连接）、&lt;code&gt;dev&lt;/code&gt;（设备）、&lt;code&gt;gen&lt;/code&gt;（通用）&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="常用命令"&gt;常用命令&lt;/h2&gt;
&lt;h3 id="查看"&gt;查看&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 列出所有连接&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nmcli con show
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 列出活跃连接&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nmcli con show --active
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 查看连接详情&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nmcli con show &lt;span class="s2"&gt;&amp;#34;连接名&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 查看设备状态&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nmcli dev status
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 查看设备详情（IP、MAC 等）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nmcli dev show enp171s0
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="创建连接"&gt;创建连接&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nmcli con add &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; con-name &lt;span class="s2"&gt;&amp;#34;连接名&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;type&lt;/span&gt; ethernet &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ifname enp171s0 &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ipv4.addresses 192.168.100.2/24 &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ipv4.method manual &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ipv4.gateway &lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ipv4.dns &lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ipv4.never-default yes &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; connection.autoconnect yes
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;参数说明：&lt;/p&gt;</description></item><item><title>搭建EasyTier中继服务器并进行组网</title><link>https://kerolt.github.io/p/%E6%90%AD%E5%BB%BAeasytier%E4%B8%AD%E7%BB%A7%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%B9%B6%E8%BF%9B%E8%A1%8C%E7%BB%84%E7%BD%91/</link><pubDate>Wed, 24 Jun 2026 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/%E6%90%AD%E5%BB%BAeasytier%E4%B8%AD%E7%BB%A7%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%B9%B6%E8%BF%9B%E8%A1%8C%E7%BB%84%E7%BD%91/</guid><description>&lt;h2 id="搭建中继服务器"&gt;搭建中继服务器&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;虽说是搭建中继服务器，但其实 easytier 是点对点去中心化的组网方式，所谓中继服务器就是一个&lt;strong&gt;有公网 ip 的节点&lt;/strong&gt;，用于让其他没有公网 ip 的主机通过它进行中继转发，从而实现异地组网。&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>Clash-Fake-IP模式下Git-SSH连接失败</title><link>https://kerolt.github.io/p/clash-fake-ip%E6%A8%A1%E5%BC%8F%E4%B8%8Bgit-ssh%E8%BF%9E%E6%8E%A5%E5%A4%B1%E8%B4%A5/</link><pubDate>Sat, 13 Jun 2026 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/clash-fake-ip%E6%A8%A1%E5%BC%8F%E4%B8%8Bgit-ssh%E8%BF%9E%E6%8E%A5%E5%A4%B1%E8%B4%A5/</guid><description>&lt;h2 id="问题现象"&gt;问题现象&lt;/h2&gt;
&lt;p&gt;执行 &lt;code&gt;git fetch --all&lt;/code&gt; 报错：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Connection closed by 198.18.0.35 port &lt;span class="m"&gt;22&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;fatal: Could not &lt;span class="nb"&gt;read&lt;/span&gt; from remote repository.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="排查过程"&gt;排查过程&lt;/h2&gt;
&lt;h3 id="1-确认-remote-地址"&gt;1. 确认 remote 地址&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git remote -v
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# origin git@github.com:xxx/yyy.git&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;使用的是 SSH 协议。&lt;/p&gt;
&lt;h3 id="2-排查-dns-解析"&gt;2. 排查 DNS 解析&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nslookup github.com
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Name: github.com&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Address: 198.18.0.35&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;198.18.0.35&lt;/code&gt; 不是 GitHub 真实 IP，属于 &lt;code&gt;198.18.0.0/15&lt;/code&gt; 保留段。这是 &lt;strong&gt;Clash Fake-IP 模式&lt;/strong&gt; 的特征，即 DNS 返回虚拟 IP，由 Clash 透明代理接管流量。&lt;/p&gt;</description></item><item><title>零拷贝技术</title><link>https://kerolt.github.io/p/%E9%9B%B6%E6%8B%B7%E8%B4%9D%E6%8A%80%E6%9C%AF/</link><pubDate>Mon, 18 May 2026 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/%E9%9B%B6%E6%8B%B7%E8%B4%9D%E6%8A%80%E6%9C%AF/</guid><description>&lt;p&gt;一句话概括：零拷贝技术让数据在 &lt;strong&gt;磁盘 → 内核缓冲区 → 网卡&lt;/strong&gt; 之间直接传输，避免用户态与内核态之间的冗余数据拷贝，核心是消除 CPU 参与的数据搬移。&lt;/p&gt;
&lt;h2 id="传统-io-路径4-次拷贝2-次-cpu-参与"&gt;传统 IO 路径（4 次拷贝，2 次 CPU 参与）&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;磁盘 → &lt;span class="o"&gt;[&lt;/span&gt;DMA&lt;span class="o"&gt;]&lt;/span&gt; → Page Cache &lt;span class="o"&gt;(&lt;/span&gt;内核&lt;span class="o"&gt;)&lt;/span&gt; → &lt;span class="o"&gt;[&lt;/span&gt;CPU&lt;span class="o"&gt;]&lt;/span&gt; → 用户 Buffer → &lt;span class="o"&gt;[&lt;/span&gt;CPU&lt;span class="o"&gt;]&lt;/span&gt; → Socket Buffer &lt;span class="o"&gt;(&lt;/span&gt;内核&lt;span class="o"&gt;)&lt;/span&gt; → &lt;span class="o"&gt;[&lt;/span&gt;DMA&lt;span class="o"&gt;]&lt;/span&gt; → NIC
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ① ② ③ ④
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;① DMA 读磁盘到 page cache&lt;/li&gt;
&lt;li&gt;② CPU 把 page cache 拷到用户态 buffer（read）&lt;/li&gt;
&lt;li&gt;③ CPU 把用户态 buffer 拷到 socket buffer（send）&lt;/li&gt;
&lt;li&gt;④ DMA 从 socket buffer 发送到网卡&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;零拷贝的目标：去掉 ② 和 ③ 这两步 CPU 拷贝。&lt;/p&gt;</description></item><item><title>【译】从零开始用 Go 构建容器：现代命名空间 + cgroup v2</title><link>https://kerolt.github.io/p/%E8%AF%91%E4%BB%8E%E9%9B%B6%E5%BC%80%E5%A7%8B%E7%94%A8-go-%E6%9E%84%E5%BB%BA%E5%AE%B9%E5%99%A8%E7%8E%B0%E4%BB%A3%E5%91%BD%E5%90%8D%E7%A9%BA%E9%97%B4--cgroup-v2/</link><pubDate>Wed, 13 May 2026 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/%E8%AF%91%E4%BB%8E%E9%9B%B6%E5%BC%80%E5%A7%8B%E7%94%A8-go-%E6%9E%84%E5%BB%BA%E5%AE%B9%E5%99%A8%E7%8E%B0%E4%BB%A3%E5%91%BD%E5%90%8D%E7%A9%BA%E9%97%B4--cgroup-v2/</guid><description>&lt;blockquote&gt;
&lt;p&gt;本文是对 &lt;a href="https://dev.to/faizanfirdousi/build-a-container-from-scratch-in-go-modern-namespaces-cgroup-v2-5556?utm_source=dormosheio&amp;amp;utm_campaign=dormosheio"&gt;Build a Container from Scratch in Go (Modern Namespaces + cgroup v2)&lt;/a&gt; 这篇文章的翻译，以下是正文&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;ul&gt;
&lt;li&gt;作者：&lt;a href="https://dev.to/faizanfirdousi"&gt;Faizan Firdousi&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;发布时间：2026 年 2 月 18 日&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;我用 Go 从零构建了一个容器，代码行数尽可能少，并在过程中了解了容器内部通常发生的各种事情——也就是 Docker 抽象掉的那些细节。&lt;/p&gt;</description></item><item><title>Go 与汇编</title><link>https://kerolt.github.io/p/go-%E4%B8%8E%E6%B1%87%E7%BC%96/</link><pubDate>Mon, 11 May 2026 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/go-%E4%B8%8E%E6%B1%87%E7%BC%96/</guid><description>&lt;h2 id="1-为什么-go-需要汇编"&gt;1. 为什么 Go 需要汇编&lt;/h2&gt;
&lt;p&gt;Go 在以下场景允许直接嵌入汇编：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;性能热点&lt;/strong&gt;：手写 SIMD 指令、避免编译器优化不足&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;系统调用&lt;/strong&gt;：部分 runtime 代码（如 &lt;code&gt;runtime·sys_linux_amd64.s&lt;/code&gt;）直接发起 syscall&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;引导/启动&lt;/strong&gt;：&lt;code&gt;rt0_linux_amd64.s&lt;/code&gt; 等启动代码必须在汇编层面完成栈和寄存器初始化&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;密码学&lt;/strong&gt;：&lt;code&gt;crypto/aes&lt;/code&gt;, &lt;code&gt;crypto/sha256&lt;/code&gt; 等标准库大量使用汇编加速&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Go 使用 &lt;strong&gt;Plan 9 汇编语法&lt;/strong&gt;，与 AT&amp;amp;T / Intel 语法都不同。&lt;/p&gt;</description></item><item><title>defer、panic与recover</title><link>https://kerolt.github.io/p/deferpanic%E4%B8%8Erecover/</link><pubDate>Fri, 08 May 2026 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/deferpanic%E4%B8%8Erecover/</guid><description>&lt;blockquote&gt;
&lt;p&gt;既然都 &lt;code&gt;panic&lt;/code&gt; 了，不就是想让程序崩溃吗？为什么还要“恢复”它？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;panic&lt;/code&gt; 不一定是“程序该死”，更多时候是“当前请求/任务该死”。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;我们可以把程序分为两种崩溃模式：&lt;/p&gt;</description></item><item><title>Go中fmt的常见用法总结</title><link>https://kerolt.github.io/p/go%E4%B8%ADfmt%E7%9A%84%E5%B8%B8%E8%A7%81%E7%94%A8%E6%B3%95%E6%80%BB%E7%BB%93/</link><pubDate>Fri, 08 May 2026 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/go%E4%B8%ADfmt%E7%9A%84%E5%B8%B8%E8%A7%81%E7%94%A8%E6%B3%95%E6%80%BB%E7%BB%93/</guid><description>&lt;h2 id="一常用输出函数按输出目标分类"&gt;一、常用输出函数（按输出目标分类）&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;函数&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;th&gt;示例&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Print&lt;/code&gt; / &lt;code&gt;Println&lt;/code&gt; / &lt;code&gt;Printf&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;输出到标准输出&lt;/td&gt;
&lt;td&gt;&lt;code&gt;fmt.Println(&amp;quot;Hello&amp;quot;)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Fprint&lt;/code&gt; / &lt;code&gt;Fprintln&lt;/code&gt; / &lt;code&gt;Fprintf&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;输出到任意 &lt;code&gt;io.Writer&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;fmt.Fprintf(os.Stderr, &amp;quot;err: %v&amp;quot;, err)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Sprint&lt;/code&gt; / &lt;code&gt;Sprintln&lt;/code&gt; / &lt;code&gt;Sprintf&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;格式化结果返回字符串（不打印）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;s := fmt.Sprintf(&amp;quot;age=%d&amp;quot;, 20)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Errorf&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;格式化后返回 &lt;code&gt;error&lt;/code&gt; 类型&lt;/td&gt;
&lt;td&gt;&lt;code&gt;return fmt.Errorf(&amp;quot;invalid: %v&amp;quot;, val)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;Println&lt;/code&gt;/&lt;code&gt;Sprintln&lt;/code&gt;/&lt;code&gt;Fprintln&lt;/code&gt; 会自动在末尾加换行，&lt;code&gt;Print&lt;/code&gt; 不加；&lt;code&gt;Printf&lt;/code&gt; 需要显式写 &lt;code&gt;\n&lt;/code&gt;。&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>如何理解sys-fs-bpf</title><link>https://kerolt.github.io/p/%E5%A6%82%E4%BD%95%E7%90%86%E8%A7%A3sys-fs-bpf/</link><pubDate>Tue, 10 Mar 2026 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/%E5%A6%82%E4%BD%95%E7%90%86%E8%A7%A3sys-fs-bpf/</guid><description>&lt;p&gt;&lt;code&gt;/sys/fs/bpf&lt;/code&gt; 是 Linux 内核中 &lt;strong&gt;BPF 文件系统&lt;/strong&gt; 的挂载点。简单来说，它是 &lt;strong&gt;BPF 对象（如 Maps 和 Programs）在用户空间文件系统中的“家”&lt;/strong&gt;。&lt;/p&gt;
&lt;h2 id="持久化与命名空间化"&gt;持久化与命名空间化&lt;/h2&gt;
&lt;p&gt;在 BPF 文件系统出现之前，BPF 程序和 Map 的生命周期完全依赖于持有其文件描述符的进程。如果创建 BPF Map 的进程退出了，Map 也就随之销毁了。&lt;/p&gt;</description></item><item><title>Kind 与 Minikube 配置代理</title><link>https://kerolt.github.io/p/kind-%E4%B8%8E-minikube-%E9%85%8D%E7%BD%AE%E4%BB%A3%E7%90%86/</link><pubDate>Thu, 05 Mar 2026 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/kind-%E4%B8%8E-minikube-%E9%85%8D%E7%BD%AE%E4%BB%A3%E7%90%86/</guid><description>&lt;h2 id="what"&gt;What&lt;/h2&gt;
&lt;p&gt;本地的 kind / minikube 集群拉取镜像时，总是报同一个错误：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;spec.containers&lt;span class="o"&gt;{&lt;/span&gt;nginx&lt;span class="o"&gt;}&lt;/span&gt;: Failed to pull image &lt;span class="s2"&gt;&amp;#34;nginx:alpine&amp;#34;&lt;/span&gt;: failed to pull and unpack image &lt;span class="s2"&gt;&amp;#34;docker.io/library/nginx:alpine&amp;#34;&lt;/span&gt;: failed to resolve reference &lt;span class="s2"&gt;&amp;#34;docker.io/library/nginx:alpine&amp;#34;&lt;/span&gt;: failed to &lt;span class="k"&gt;do&lt;/span&gt; request: Head &lt;span class="s2"&gt;&amp;#34;https://registry-1.docker.io/v2/library/nginx/manifests/alpine &amp;#34;&lt;/span&gt;: proxyconnect tcp: dial tcp 127.0.0.1:7890: connect: connection refused
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;明明宿主机上已经开着代理（Clash，7890 端口），为什么容器里还是连不上？&lt;/p&gt;</description></item><item><title>Service与Endpoint</title><link>https://kerolt.github.io/p/service%E4%B8%8Eendpoint/</link><pubDate>Sun, 01 Mar 2026 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/service%E4%B8%8Eendpoint/</guid><description>&lt;p&gt;在 Kubernetes 中，&lt;strong&gt;Service&lt;/strong&gt;、&lt;strong&gt;Endpoint&lt;/strong&gt;（或 &lt;strong&gt;EndpointSlice&lt;/strong&gt;）和 &lt;strong&gt;kube-proxy&lt;/strong&gt; 是协同实现服务发现与负载均衡的核心组件。它们的关系可以简单理解为：&lt;strong&gt;Service 定义了访问规则，Endpoint 维护了实际后端 Pod 的地址列表，而 kube-proxy 负责将规则落地到每个节点，实现流量转发&lt;/strong&gt;。下面从概念到实例逐一说明。&lt;/p&gt;</description></item><item><title>RingBuffer与PerfBuffer</title><link>https://kerolt.github.io/p/ringbuffer%E4%B8%8Eperfbuffer/</link><pubDate>Wed, 25 Feb 2026 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/ringbuffer%E4%B8%8Eperfbuffer/</guid><description>&lt;blockquote&gt;
&lt;p&gt;本篇文章由 AI 辅助完成&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;在 eBPF（extended Berkeley Packet Filter）生态中，&lt;strong&gt;Ring Buffer&lt;/strong&gt; 和 &lt;strong&gt;Perf Buffer&lt;/strong&gt; 都是用于将内核态采集的数据高效传递到用户态的机制。但从 Linux 5.8 开始引入的 &lt;strong&gt;Ring Buffer&lt;/strong&gt; 被认为在多数场景下优于传统的 &lt;strong&gt;Perf Buffer&lt;/strong&gt;，主要原因包括以下几点：&lt;/p&gt;</description></item><item><title>k8s中的Informer</title><link>https://kerolt.github.io/p/k8s%E4%B8%AD%E7%9A%84informer/</link><pubDate>Sun, 22 Feb 2026 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/k8s%E4%B8%AD%E7%9A%84informer/</guid><description>&lt;blockquote&gt;
&lt;p&gt;本篇文章由 AI 辅助完成&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Informer 就是一个带“自动更新”功能的本地缓存（Local Cache）。&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="直观理解订阅模式-vs-轮询模式"&gt;直观理解：订阅模式 vs. 轮询模式&lt;/h2&gt;
&lt;p&gt;想象你要==&lt;strong&gt;监控集群里的 Pod 状态&lt;/strong&gt;==：&lt;/p&gt;</description></item><item><title>更适合eBPF程序宝宝体质的clangd配置</title><link>https://kerolt.github.io/p/%E6%9B%B4%E9%80%82%E5%90%88ebpf%E7%A8%8B%E5%BA%8F%E5%AE%9D%E5%AE%9D%E4%BD%93%E8%B4%A8%E7%9A%84clangd%E9%85%8D%E7%BD%AE/</link><pubDate>Sun, 15 Feb 2026 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/%E6%9B%B4%E9%80%82%E5%90%88ebpf%E7%A8%8B%E5%BA%8F%E5%AE%9D%E5%AE%9D%E4%BD%93%E8%B4%A8%E7%9A%84clangd%E9%85%8D%E7%BD%AE/</guid><description>&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;span class="lnt"&gt;30
&lt;/span&gt;&lt;span class="lnt"&gt;31
&lt;/span&gt;&lt;span class="lnt"&gt;32
&lt;/span&gt;&lt;span class="lnt"&gt;33
&lt;/span&gt;&lt;span class="lnt"&gt;34
&lt;/span&gt;&lt;span class="lnt"&gt;35
&lt;/span&gt;&lt;span class="lnt"&gt;36
&lt;/span&gt;&lt;span class="lnt"&gt;37
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# 1. 扩大匹配范围，确保头文件也能享受 BPF 配置&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;If&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;PathMatch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="l"&gt;.*\.bpf\.c, .*/bpf/.*\.c, .*\.h]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 增加对 .h 的支持&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;CompileFlags&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;-target&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;bpf&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;-x&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;c&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;-std=gnu11&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;-D__BPF_TRACING__&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;-D__TARGET_ARCH_x86&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 必须指定架构，否则 vmlinux.h 内部的部分条件编译会失效&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;-I.&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 确保当前目录的头文件优先级最高&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;-I/usr/include/bpf&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 指向 libbpf 头文件路径&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;-Wno-unknown-attributes&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 忽略不认识的属性&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;-ferror-limit=0&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 即使错误再多也不要停止解析，这对补全很重要&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;Remove&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;-std=c++*&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;-fexceptions&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;Diagnostics&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 2. 针对 vmlinux.h 的重定义问题进行精准打击&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;Suppress&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;redefinition&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 抑制所有的符号重定义&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;typedef_redefinition&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 特别针对 typedef 的冲突&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;too_many_errors&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 彻底关掉那个烦人的警告&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;err_expected_identifer&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 针对 vmlinux 内部属性解析失败的补救&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# 3. 针对特定的 vmlinux.h 文件彻底关闭检查&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;If&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;PathMatch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;.*vmlinux\.h&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;Diagnostics&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;Suppress&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;*&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;</description></item><item><title>使用nmcli管理Wi-Fi连接</title><link>https://kerolt.github.io/p/%E4%BD%BF%E7%94%A8nmcli%E7%AE%A1%E7%90%86wi-fi%E8%BF%9E%E6%8E%A5/</link><pubDate>Thu, 12 Feb 2026 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/%E4%BD%BF%E7%94%A8nmcli%E7%AE%A1%E7%90%86wi-fi%E8%BF%9E%E6%8E%A5/</guid><description>&lt;p&gt;环境：Fedora 43，NetworkManager 管理网络，基于 &lt;code&gt;nmcli&lt;/code&gt;（NetworkManager Command Line Interface）操作。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="wifi-连接全流程"&gt;WiFi 连接全流程&lt;/h2&gt;
&lt;h3 id="1-确认网卡状态"&gt;1. 确认网卡状态&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nmcli device status
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;输出示例：&lt;/p&gt;</description></item><item><title>更改Go的默认安装位置</title><link>https://kerolt.github.io/p/%E6%9B%B4%E6%94%B9go%E7%9A%84%E9%BB%98%E8%AE%A4%E5%AE%89%E8%A3%85%E4%BD%8D%E7%BD%AE/</link><pubDate>Wed, 11 Feb 2026 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/%E6%9B%B4%E6%94%B9go%E7%9A%84%E9%BB%98%E8%AE%A4%E5%AE%89%E8%A3%85%E4%BD%8D%E7%BD%AE/</guid><description>&lt;blockquote&gt;
&lt;p&gt;将 Go 的默认工作 Go 目录从 &lt;code&gt;$HOME/go&lt;/code&gt; 改为 &lt;code&gt;$HOME/.go&lt;/code&gt; ，这个行为由环境变量 &lt;code&gt;GOPATH&lt;/code&gt; 控制&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="核心原理gopath-与现代-go-的关系"&gt;核心原理：&lt;code&gt;GOPATH&lt;/code&gt; 与现代 Go 的关系&lt;/h2&gt;
&lt;p&gt;自 Go 1.11 引入 &lt;strong&gt;Go Modules&lt;/strong&gt; 后，项目源码不再强制依赖 &lt;code&gt;GOPATH/src&lt;/code&gt;，但以下内容仍受 &lt;code&gt;GOPATH&lt;/code&gt; 影响：&lt;/p&gt;</description></item><item><title>Linux SSH免密登陆</title><link>https://kerolt.github.io/p/linux-ssh%E5%85%8D%E5%AF%86%E7%99%BB%E9%99%86/</link><pubDate>Tue, 10 Feb 2026 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/linux-ssh%E5%85%8D%E5%AF%86%E7%99%BB%E9%99%86/</guid><description>&lt;h2 id="一生成-ssh-密钥对在本地机器上"&gt;一、生成 SSH 密钥对（在本地机器上）&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;打开终端（Linux/macOS）或使用 PowerShell/WSL（Windows）。&lt;/li&gt;
&lt;li&gt;执行以下命令生成密钥对：&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh-keygen -t rsa -b &lt;span class="m"&gt;4096&lt;/span&gt; -C &lt;span class="s2"&gt;&amp;#34;your_email@example.com&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-t rsa&lt;/code&gt;：指定密钥类型为 RSA（也可以使用 &lt;code&gt;-t ed25519&lt;/code&gt; 更安全）。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-b 4096&lt;/code&gt;：密钥长度（RSA 推荐 4096 位）。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-C&lt;/code&gt;：添加注释（通常是邮箱，可选）。&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="3"&gt;
&lt;li&gt;按提示操作：
&lt;ul&gt;
&lt;li&gt;保存路径：直接回车使用默认路径 &lt;code&gt;~/.ssh/id_rsa&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;设置密码（passphrase）：可选，增强安全性。如果希望完全免密，直接回车留空。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;生成后会在 &lt;code&gt;~/.ssh/&lt;/code&gt; 目录下创建两个文件：&lt;/p&gt;</description></item><item><title>利用eBPF与perf_event构建一个profiling工具</title><link>https://kerolt.github.io/p/%E5%88%A9%E7%94%A8ebpf%E4%B8%8Eperf_event%E6%9E%84%E5%BB%BA%E4%B8%80%E4%B8%AAprofiling%E5%B7%A5%E5%85%B7/</link><pubDate>Thu, 29 Jan 2026 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/%E5%88%A9%E7%94%A8ebpf%E4%B8%8Eperf_event%E6%9E%84%E5%BB%BA%E4%B8%80%E4%B8%AAprofiling%E5%B7%A5%E5%85%B7/</guid><description>&lt;h2 id="引言"&gt;引言&lt;/h2&gt;
&lt;p&gt;在性能分析和系统调优中，了解应用程序在运行时的调用栈信息至关重要。在 &lt;a href="https://eunomia.dev/zh/tutorials/12-profile/"&gt;【eBPF 入门实践教程十二：使用 eBPF 程序 profile 进行性能分析】&lt;/a&gt; 这篇文章中，其利用 Rust + eBPF 构建了一个 profiler 工具，抱着学习的目的，我使用 C++ 实现了相同的功能，并将所学知识总结成本文。&lt;/p&gt;</description></item><item><title>为Hugo PaperMod添加mermaid渲染</title><link>https://kerolt.github.io/p/%E4%B8%BAhugo-papermod%E6%B7%BB%E5%8A%A0mermaid%E6%B8%B2%E6%9F%93/</link><pubDate>Thu, 29 Jan 2026 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/%E4%B8%BAhugo-papermod%E6%B7%BB%E5%8A%A0mermaid%E6%B8%B2%E6%9F%93/</guid><description>&lt;p&gt;首先在 &lt;code&gt;layouts/partials&lt;/code&gt; 下添加 &lt;code&gt;mermaid.html&lt;/code&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;module&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;mermaid&lt;/span&gt; &lt;span class="nx"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;mermaid&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;startOnLoad&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// Replace mermaid pre.code to div
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getElementsByClassName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;language-mermaid&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parentElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;outerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sb"&gt;`&amp;lt;div class=&amp;#34;mermaid&amp;#34;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;&amp;lt;/div&amp;gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;style&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c"&gt;/* Set svg to center */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;mermaid&lt;/span&gt; &lt;span class="nt"&gt;svg&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;block&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;style&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;然后在 &lt;code&gt;layouts/partials/_default&lt;/code&gt; 下的 &lt;code&gt;single.html&lt;/code&gt; 中添加 mermaid 组件的引入：&lt;/p&gt;</description></item><item><title>在 Docker Compose 中为项目启用 IPv6 并可通过 IPv6 可访问</title><link>https://kerolt.github.io/p/%E5%9C%A8-docker-compose-%E4%B8%AD%E4%B8%BA%E9%A1%B9%E7%9B%AE%E5%90%AF%E7%94%A8-ipv6-%E5%B9%B6%E5%8F%AF%E9%80%9A%E8%BF%87-ipv6-%E5%8F%AF%E8%AE%BF%E9%97%AE/</link><pubDate>Wed, 28 Jan 2026 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/%E5%9C%A8-docker-compose-%E4%B8%AD%E4%B8%BA%E9%A1%B9%E7%9B%AE%E5%90%AF%E7%94%A8-ipv6-%E5%B9%B6%E5%8F%AF%E9%80%9A%E8%BF%87-ipv6-%E5%8F%AF%E8%AE%BF%E9%97%AE/</guid><description>&lt;p&gt;&lt;strong&gt;需求&lt;/strong&gt;：在 Docker 环境下启用 IPv6，使基于 nginx 的容器服务可通过 IPv6 访问。&lt;/p&gt;
&lt;h2 id="为网络启用-ipv6"&gt;为网络启用 IPv6&lt;/h2&gt;
&lt;p&gt;添加 &lt;code&gt;enable_ipv6: true&lt;/code&gt; 并配置 &lt;code&gt;ipam&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;设置子网前缀为 &lt;code&gt;fd00:abcd::/64&lt;/code&gt;。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;networks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;my-network&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;bridge&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;enable_ipv6&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ipam&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;default&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;subnet&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;fd00:abcd::/64&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;在项目前端的 nginx 配置中，增加 IPv6 监听：&lt;/p&gt;</description></item><item><title>RockyLinux启用EPEL软件仓库</title><link>https://kerolt.github.io/p/rockylinux%E5%90%AF%E7%94%A8epel%E8%BD%AF%E4%BB%B6%E4%BB%93%E5%BA%93/</link><pubDate>Mon, 26 Jan 2026 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/rockylinux%E5%90%AF%E7%94%A8epel%E8%BD%AF%E4%BB%B6%E4%BB%93%E5%BA%93/</guid><description>&lt;p&gt;&lt;code&gt;epel-release&lt;/code&gt; 是一个 &lt;code&gt;RPM&lt;/code&gt; 软件包，用于在基于 &lt;code&gt;Red Hat&lt;/code&gt; 的 &lt;code&gt;Linux&lt;/code&gt; 发行版（如 &lt;code&gt;RHEL、CentOS、Rocky Linux、AlmaLinux 和 Oracle Linux&lt;/code&gt;）上启用 &lt;code&gt;EPEL（Extra Packages for Enterprise Linux&lt;/code&gt;） 软件仓库。&lt;/p&gt;</description></item><item><title>CMake与Conan协同工作理解</title><link>https://kerolt.github.io/p/cmake%E4%B8%8Econan%E5%8D%8F%E5%90%8C%E5%B7%A5%E4%BD%9C%E7%90%86%E8%A7%A3/</link><pubDate>Thu, 22 Jan 2026 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/cmake%E4%B8%8Econan%E5%8D%8F%E5%90%8C%E5%B7%A5%E4%BD%9C%E7%90%86%E8%A7%A3/</guid><description>&lt;h2 id="背景"&gt;背景&lt;/h2&gt;
&lt;p&gt;最近根据 &lt;a href="https://eunomia.dev/zh/tutorials/12-profile/"&gt;【eBPF 入门实践教程十二：使用 eBPF 程序 profile 进行性能分析】&lt;/a&gt; 这篇文章，写了一个性能分析的小工具。不过文章中的实现是 rust，但我还不怎么熟悉 rust，因而打算参考其代码使用 c++ 来实现相同的功能。项目地址：&lt;a href="https://github.com/kerolt/profiler"&gt;profiler&lt;/a&gt;。&lt;/p&gt;</description></item><item><title>如何在CMake工程中使用Rust库blazesym</title><link>https://kerolt.github.io/p/%E5%A6%82%E4%BD%95%E5%9C%A8cmake%E5%B7%A5%E7%A8%8B%E4%B8%AD%E4%BD%BF%E7%94%A8rust%E5%BA%93blazesym/</link><pubDate>Thu, 22 Jan 2026 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/%E5%A6%82%E4%BD%95%E5%9C%A8cmake%E5%B7%A5%E7%A8%8B%E4%B8%AD%E4%BD%BF%E7%94%A8rust%E5%BA%93blazesym/</guid><description>&lt;p&gt;在 &lt;a href="https://eunomia.dev/zh/tutorials/12-profile/"&gt;【eBPF 入门实践教程十二：使用 eBPF 程序 profile 进行性能分析】&lt;/a&gt; 这篇文章中， profiler 工具的实现是使用了 rust 编写的 &lt;code&gt;blazesym&lt;/code&gt; 库，而我现在打算使用 C++ 实现，还好这个库提供了 C API，但是需要我们将这个 Rust 库的构建集成到 CMake 中。&lt;/p&gt;</description></item><item><title>C++对Rust中Result的简单模仿</title><link>https://kerolt.github.io/p/c-%E5%AF%B9rust%E4%B8%ADresult%E7%9A%84%E7%AE%80%E5%8D%95%E6%A8%A1%E4%BB%BF/</link><pubDate>Tue, 20 Jan 2026 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/c-%E5%AF%B9rust%E4%B8%ADresult%E7%9A%84%E7%AE%80%E5%8D%95%E6%A8%A1%E4%BB%BF/</guid><description>&lt;blockquote&gt;
&lt;p&gt;[!note] 注意！
以下代码需要支持 C++23 的编译器&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这里利用 &lt;code&gt;std::expected&lt;/code&gt; 和 &lt;code&gt;std::unexpected&lt;/code&gt; 进行模仿：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;span class="lnt"&gt;30
&lt;/span&gt;&lt;span class="lnt"&gt;31
&lt;/span&gt;&lt;span class="lnt"&gt;32
&lt;/span&gt;&lt;span class="lnt"&gt;33
&lt;/span&gt;&lt;span class="lnt"&gt;34
&lt;/span&gt;&lt;span class="lnt"&gt;35
&lt;/span&gt;&lt;span class="lnt"&gt;36
&lt;/span&gt;&lt;span class="lnt"&gt;37
&lt;/span&gt;&lt;span class="lnt"&gt;38
&lt;/span&gt;&lt;span class="lnt"&gt;39
&lt;/span&gt;&lt;span class="lnt"&gt;40
&lt;/span&gt;&lt;span class="lnt"&gt;41
&lt;/span&gt;&lt;span class="lnt"&gt;42
&lt;/span&gt;&lt;span class="lnt"&gt;43
&lt;/span&gt;&lt;span class="lnt"&gt;44
&lt;/span&gt;&lt;span class="lnt"&gt;45
&lt;/span&gt;&lt;span class="lnt"&gt;46
&lt;/span&gt;&lt;span class="lnt"&gt;47
&lt;/span&gt;&lt;span class="lnt"&gt;48
&lt;/span&gt;&lt;span class="lnt"&gt;49
&lt;/span&gt;&lt;span class="lnt"&gt;50
&lt;/span&gt;&lt;span class="lnt"&gt;51
&lt;/span&gt;&lt;span class="lnt"&gt;52
&lt;/span&gt;&lt;span class="lnt"&gt;53
&lt;/span&gt;&lt;span class="lnt"&gt;54
&lt;/span&gt;&lt;span class="lnt"&gt;55
&lt;/span&gt;&lt;span class="lnt"&gt;56
&lt;/span&gt;&lt;span class="lnt"&gt;57
&lt;/span&gt;&lt;span class="lnt"&gt;58
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;print&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;expected&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;template&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typename&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="n"&gt;Err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;unexpected&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;template&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typename&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;typename&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="n"&gt;Result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;expected&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Inner&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;X&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;i_&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;X()&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;i_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;~X() delete inner obj&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;delete&lt;/span&gt; &lt;span class="n"&gt;i_&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;auto&lt;/span&gt; &lt;span class="nf"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;flag&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;flag&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Err&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Flag is false!&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;main--1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;main--2&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;auto&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;main--3&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;main--4&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;auto&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Error message is: {}&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;main--5&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;main--6&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;输出为：&lt;/p&gt;</description></item><item><title>Windows 个人装机配置</title><link>https://kerolt.github.io/p/windows-%E4%B8%AA%E4%BA%BA%E8%A3%85%E6%9C%BA%E9%85%8D%E7%BD%AE/</link><pubDate>Tue, 06 Jan 2026 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/windows-%E4%B8%AA%E4%BA%BA%E8%A3%85%E6%9C%BA%E9%85%8D%E7%BD%AE/</guid><description>&lt;h2 id="1windhawk"&gt;1、Windhawk&lt;/h2&gt;
&lt;p&gt;通过一些插件来改善体验。&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://obsidian-image-oss.oss-cn-shanghai.aliyuncs.com/Pasted%20image%2020260106152210.png"&gt;&lt;/p&gt;
&lt;p&gt;其中“Disable grouping on the taskbar”非常有用，可以让一个应用开多个窗口时任务栏图标不会堆叠，而是每个窗口一个图标。&lt;/p&gt;</description></item><item><title>【Nginx】location与proxy_pass配置中的斜杠差异</title><link>https://kerolt.github.io/p/nginxlocation%E4%B8%8Eproxy_pass%E9%85%8D%E7%BD%AE%E4%B8%AD%E7%9A%84%E6%96%9C%E6%9D%A0%E5%B7%AE%E5%BC%82/</link><pubDate>Mon, 05 Jan 2026 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/nginxlocation%E4%B8%8Eproxy_pass%E9%85%8D%E7%BD%AE%E4%B8%AD%E7%9A%84%E6%96%9C%E6%9D%A0%E5%B7%AE%E5%BC%82/</guid><description>&lt;p&gt;Nginx 作为反向代理服务器，需要精确匹配客户端请求路径，并将请求转发到后端服务。在这个过程中：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;location&lt;/code&gt; 指令&lt;/strong&gt;：决定哪些请求会被当前配置块处理&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;proxy_pass&lt;/code&gt; 指令&lt;/strong&gt;：决定如何将请求转发到后端&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;而斜杠在这两个指令中的不同位置，会改变 Nginx 的匹配逻辑和路径传递行为，配置不当可能导致 404 错误、路径污染或安全风险。&lt;/p&gt;</description></item><item><title>Linux修改IP</title><link>https://kerolt.github.io/p/linux%E4%BF%AE%E6%94%B9ip/</link><pubDate>Sun, 09 Nov 2025 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/linux%E4%BF%AE%E6%94%B9ip/</guid><description>&lt;p&gt;首先确定网络是用什么工具管理：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ systemctl is-active NetworkManager
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;active
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;说明 &lt;strong&gt;网络由 NetworkManager 管理&lt;/strong&gt;，这种情况修改 IP 通常使用 &lt;code&gt;nmcli&lt;/code&gt;：&lt;/p&gt;
&lt;h2 id="修改静态-ip"&gt;修改静态 IP&lt;/h2&gt;
&lt;h3 id="看当前连接名"&gt;看当前连接名&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nmcli connection show
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;输出类似：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;NAME UUID TYPE DEVICE
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Wired connection &lt;span class="m"&gt;1&lt;/span&gt; 2d3e1f6a-4e87-4a76-8f23-2f459c8c112b ethernet enp60s0
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这里的 &lt;code&gt;NAME&lt;/code&gt;（如 &lt;code&gt;Wired connection 1&lt;/code&gt;）就是连接名，后面命令要用到。&lt;/p&gt;</description></item><item><title>Linux中的veth与bridge</title><link>https://kerolt.github.io/p/linux%E4%B8%AD%E7%9A%84veth%E4%B8%8Ebridge/</link><pubDate>Sat, 08 Nov 2025 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/linux%E4%B8%AD%E7%9A%84veth%E4%B8%8Ebridge/</guid><description>&lt;p&gt;容器网络最典型的基础模型 —— &lt;strong&gt;两个不同的命名空间通过 bridge 通信&lt;/strong&gt; 。&lt;/p&gt;
&lt;p&gt;Docker 默认的 bridge 模式就是基于此原理,创建 &lt;code&gt;docker0&lt;/code&gt; bridge，容器 veth 对一端连接容器，一端连接 docker0，提供 NAT 功能让容器可以访问外网。&lt;/p&gt;</description></item><item><title>Linux校准时间</title><link>https://kerolt.github.io/p/linux%E6%A0%A1%E5%87%86%E6%97%B6%E9%97%B4/</link><pubDate>Fri, 07 Nov 2025 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/linux%E6%A0%A1%E5%87%86%E6%97%B6%E9%97%B4/</guid><description>&lt;p&gt;服务器是用旧笔记本装的 Debian13，然后用 ddns-go 做动态域名解析，但是装好之后貌似由于时钟没有校准因此 ddns-go 无法更新域名解析（使用的 aliyun），以下是解决方法。&lt;/p&gt;</description></item><item><title>如何理解内核态与用户态切换的上下文开销</title><link>https://kerolt.github.io/p/%E5%A6%82%E4%BD%95%E7%90%86%E8%A7%A3%E5%86%85%E6%A0%B8%E6%80%81%E4%B8%8E%E7%94%A8%E6%88%B7%E6%80%81%E5%88%87%E6%8D%A2%E7%9A%84%E4%B8%8A%E4%B8%8B%E6%96%87%E5%BC%80%E9%94%80/</link><pubDate>Thu, 06 Nov 2025 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/%E5%A6%82%E4%BD%95%E7%90%86%E8%A7%A3%E5%86%85%E6%A0%B8%E6%80%81%E4%B8%8E%E7%94%A8%E6%88%B7%E6%80%81%E5%88%87%E6%8D%A2%E7%9A%84%E4%B8%8A%E4%B8%8B%E6%96%87%E5%BC%80%E9%94%80/</guid><description>&lt;h2 id="一什么是用户态和内核态"&gt;一、什么是“用户态”和“内核态”&lt;/h2&gt;
&lt;p&gt;CPU 有不同的 &lt;strong&gt;特权级（Privilege Level）&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;用户态（User Mode）&lt;/strong&gt;：
应用程序在这里运行，权限受限，比如不能直接访问硬件、不能修改页表等。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;内核态（Kernel Mode）&lt;/strong&gt;：
操作系统内核运行在这里，拥有完全的访问权限，可以管理内存、设备、中断等。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>在开发一个CNI插件时需要定义的几个配置文件</title><link>https://kerolt.github.io/p/%E5%9C%A8%E5%BC%80%E5%8F%91%E4%B8%80%E4%B8%AAcni%E6%8F%92%E4%BB%B6%E6%97%B6%E9%9C%80%E8%A6%81%E5%AE%9A%E4%B9%89%E7%9A%84%E5%87%A0%E4%B8%AA%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6/</link><pubDate>Tue, 04 Nov 2025 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/%E5%9C%A8%E5%BC%80%E5%8F%91%E4%B8%80%E4%B8%AAcni%E6%8F%92%E4%BB%B6%E6%97%B6%E9%9C%80%E8%A6%81%E5%AE%9A%E4%B9%89%E7%9A%84%E5%87%A0%E4%B8%AA%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6/</guid><description>&lt;p&gt;在开发一个 &lt;strong&gt;CNI（Container Network Interface）插件&lt;/strong&gt; 时，一般需要定义几个&lt;strong&gt;关键配置文件&lt;/strong&gt;，它们共同决定插件的行为、网络配置方式、以及与 Kubernetes 的集成。&lt;/p&gt;</description></item><item><title>K8s中的单一职责和对象组合</title><link>https://kerolt.github.io/p/k8s%E4%B8%AD%E7%9A%84%E5%8D%95%E4%B8%80%E8%81%8C%E8%B4%A3%E5%92%8C%E5%AF%B9%E8%B1%A1%E7%BB%84%E5%90%88/</link><pubDate>Sat, 01 Nov 2025 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/k8s%E4%B8%AD%E7%9A%84%E5%8D%95%E4%B8%80%E8%81%8C%E8%B4%A3%E5%92%8C%E5%AF%B9%E8%B1%A1%E7%BB%84%E5%90%88/</guid><description>&lt;blockquote&gt;
&lt;p&gt;Kubernetes 的设计理念是：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;用单一职责的组件，通过对象组合的方式，构建出复杂且可扩展的分布式系统。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="什么是单一职责和对象组合"&gt;什么是“单一职责”和“对象组合”？&lt;/h2&gt;
&lt;p&gt;这两个概念来自软件设计原则（尤其是微服务与面向对象设计），Kubernetes 只是将它们贯彻得非常彻底：&lt;/p&gt;</description></item><item><title>利用kubeadm搭建集群</title><link>https://kerolt.github.io/p/%E5%88%A9%E7%94%A8kubeadm%E6%90%AD%E5%BB%BA%E9%9B%86%E7%BE%A4/</link><pubDate>Fri, 31 Oct 2025 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/%E5%88%A9%E7%94%A8kubeadm%E6%90%AD%E5%BB%BA%E9%9B%86%E7%BE%A4/</guid><description>&lt;blockquote&gt;
&lt;p&gt;环境：在 VMWare 上，启动了两个 Ubuntu 24.04.3 LTS，配置都为 2C2G。一台作为 master，一台作为 worker，&lt;strong&gt;需要为两台机器设置不同的 hostname&lt;/strong&gt;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="prepare"&gt;Prepare&lt;/h2&gt;
&lt;p&gt;安装好 Docker 后，设置一下 cgroup 的驱动：&lt;/p&gt;</description></item><item><title>eBPF中何时使用字节序转换函数</title><link>https://kerolt.github.io/p/ebpf%E4%B8%AD%E4%BD%95%E6%97%B6%E4%BD%BF%E7%94%A8%E5%AD%97%E8%8A%82%E5%BA%8F%E8%BD%AC%E6%8D%A2%E5%87%BD%E6%95%B0/</link><pubDate>Thu, 23 Oct 2025 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/ebpf%E4%B8%AD%E4%BD%95%E6%97%B6%E4%BD%BF%E7%94%A8%E5%AD%97%E8%8A%82%E5%BA%8F%E8%BD%AC%E6%8D%A2%E5%87%BD%E6%95%B0/</guid><description>&lt;blockquote&gt;
&lt;p&gt;在 eBPF 中，什么时候应该用 bpf_htons、bpf_htonl、bpf_ntohs、bpf_ntohl？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这些 &lt;code&gt;bpf_*&lt;/code&gt; 函数是 eBPF 程序中用于&lt;strong&gt;字节序转换&lt;/strong&gt;的辅助函数。它们的作用与标准的 C 库中的 &lt;code&gt;htons&lt;/code&gt;、&lt;code&gt;htonl&lt;/code&gt;、&lt;code&gt;ntohs&lt;/code&gt;、&lt;code&gt;ntohl&lt;/code&gt; 类似，但针对 BPF 环境进行了优化或封装。它们用于在&lt;strong&gt;主机字节序&lt;/strong&gt;（Host Byte Order）和&lt;strong&gt;网络字节序&lt;/strong&gt;（Network Byte Order）之间进行转换。&lt;/p&gt;</description></item><item><title>eBPF增强Nginx负载均衡</title><link>https://kerolt.github.io/p/ebpf%E5%A2%9E%E5%BC%BAnginx%E8%B4%9F%E8%BD%BD%E5%9D%87%E8%A1%A1/</link><pubDate>Tue, 21 Oct 2025 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/ebpf%E5%A2%9E%E5%BC%BAnginx%E8%B4%9F%E8%BD%BD%E5%9D%87%E8%A1%A1/</guid><description>&lt;h2 id="nginx-负载均衡基准测试"&gt;Nginx 负载均衡基准测试&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;span class="lnt"&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/ &lt;span class="c1"&gt;# wrk -c100 &amp;#34;http://172.17.0.5&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Running 10s &lt;span class="nb"&gt;test&lt;/span&gt; @ http://172.17.0.5
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="m"&gt;2&lt;/span&gt; threads and &lt;span class="m"&gt;100&lt;/span&gt; connections
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Thread Stats Avg Stdev Max +/- Stdev
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Latency 12.31ms 12.66ms 84.49ms 82.31%
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Req/Sec 5.71k 4.96k 12.98k 63.00%
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="m"&gt;113583&lt;/span&gt; requests in 10.04s, 17.87MB &lt;span class="nb"&gt;read&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Requests/sec: 11313.86
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Transfer/sec: 1.78MB
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Latency（延迟）&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Avg 12.31ms&lt;/strong&gt;：平均每个请求的响应时间为 &lt;strong&gt;12.31 毫秒&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Stdev 12.66ms&lt;/strong&gt;：标准差说明响应时间波动较大&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Max 84.49ms&lt;/strong&gt;：最长请求花了 84.49 毫秒&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;82.31% +/- Stdev&lt;/strong&gt;：82% 的请求延迟在 ±1 标准差范围内（说明大部分请求分布较广）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Req/Sec（每秒请求数）&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Avg 5.71k&lt;/strong&gt;：平均每个线程每秒发出约 &lt;strong&gt;5710 个请求&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Stdev 4.96k&lt;/strong&gt;：标准差说明不同时间点吞吐波动较大&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Max 12.98k&lt;/strong&gt;：单个线程的最高瞬时请求速率为 12.98k/s&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;63.00% +/- Stdev&lt;/strong&gt;：约 63% 的样本在这个范围内&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;</description></item><item><title>Vue3路由与Vite的base</title><link>https://kerolt.github.io/p/vue3%E8%B7%AF%E7%94%B1%E4%B8%8Evite%E7%9A%84base/</link><pubDate>Thu, 16 Oct 2025 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/vue3%E8%B7%AF%E7%94%B1%E4%B8%8Evite%E7%9A%84base/</guid><description>&lt;p&gt;前端&lt;/p&gt;
&lt;p&gt;虽然我不是一个专门搞前端的，但也会写点点 Vue。最近实验室项目写完后需要部署一下，这里我就使用了 Docker Compose 来部署。由于前端项目有前台用户端访问和后台管理端两个，而老师申请的服务器只开了 80 端口，因此我就打算使用 nginx 来反向代理：&lt;/p&gt;</description></item><item><title>国内安装Docker CE</title><link>https://kerolt.github.io/p/%E5%9B%BD%E5%86%85%E5%AE%89%E8%A3%85docker-ce/</link><pubDate>Mon, 13 Oct 2025 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/%E5%9B%BD%E5%86%85%E5%AE%89%E8%A3%85docker-ce/</guid><description>&lt;h2 id="添加软件仓库"&gt;添加软件仓库&lt;/h2&gt;
&lt;h3 id="debian12"&gt;Debian12&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1. 添加阿里的 Docker 镜像仓库证书；这里具体的url根据自身修改&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl -fsSL https://mirrors.aliyun.com/docker-ce/debian/ubuntu/gpg &lt;span class="p"&gt;|&lt;/span&gt; sudo gpg --dearmor -o /etc/apt/keyrings/aliyun-docker.gpg
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 2. 添加仓库&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;deb [arch=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;dpkg --print-architecture&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt; signed-by=/etc/apt/keyrings/aliyun-docker.gpg] https://mirrors.aliyun.com/docker-ce/linux/debian \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;lsb_release -cs&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt; stable&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; sudo tee /etc/apt/sources.list.d/docker.list &amp;gt; /dev/null
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 3. 安装&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt-get update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="docky-linux-10"&gt;Docky Linux 10&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo dnf config-manager --add-repo&lt;span class="o"&gt;=&lt;/span&gt;https://download.docker.com/linux/centos/docker-ce.repo
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/rhel/docker-ce.repo
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo dnf install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="加入-docker-用户组"&gt;加入 docker 用户组&lt;/h2&gt;
&lt;p&gt;安装完成后，通常我们要将自己加入 docker 用户组：&lt;/p&gt;</description></item><item><title>Linux NAPI机制知识点总结</title><link>https://kerolt.github.io/p/linux-napi%E6%9C%BA%E5%88%B6%E7%9F%A5%E8%AF%86%E7%82%B9%E6%80%BB%E7%BB%93/</link><pubDate>Wed, 17 Sep 2025 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/linux-napi%E6%9C%BA%E5%88%B6%E7%9F%A5%E8%AF%86%E7%82%B9%E6%80%BB%E7%BB%93/</guid><description>&lt;blockquote&gt;
&lt;p&gt;对 &lt;a href="https://docs.kernel.org/networking/napi.html"&gt;https://docs.kernel.org/networking/napi.html&lt;/a&gt; 的总结&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;NAPI (New API，但现已无特定含义) 是 Linux 内核中用于高效处理网络数据包的一种机制，旨在减少高负载下的中断开销。&lt;/p&gt;
&lt;p&gt;其​目的​​是为了解决传统基于中断的包处理在高流量下的性能问题（“中断活锁”）。通过混合​&lt;strong&gt;​中断​&lt;/strong&gt;​和​&lt;strong&gt;​轮询​&lt;/strong&gt;​模式，在低负载时使用中断保证低延迟，在高负载时切换到轮询保证高吞吐量。&lt;/p&gt;</description></item><item><title>【k8s】什么是Service</title><link>https://kerolt.github.io/p/k8s%E4%BB%80%E4%B9%88%E6%98%AFservice/</link><pubDate>Sun, 07 Sep 2025 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/k8s%E4%BB%80%E4%B9%88%E6%98%AFservice/</guid><description>&lt;p&gt;在 Kubernetes（K8s）中，&lt;strong&gt;Service（服务）&lt;/strong&gt; 是一个非常核心、关键的抽象概念。它的主要作用是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;✅ &lt;strong&gt;为一组 Pod 提供稳定的网络访问入口（IP + Port），实现服务发现和负载均衡。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>【问题记录】ddns-go与IPv6网络配置</title><link>https://kerolt.github.io/p/%E9%97%AE%E9%A2%98%E8%AE%B0%E5%BD%95ddns-go%E4%B8%8Eipv6%E7%BD%91%E7%BB%9C%E9%85%8D%E7%BD%AE/</link><pubDate>Fri, 29 Aug 2025 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/%E9%97%AE%E9%A2%98%E8%AE%B0%E5%BD%95ddns-go%E4%B8%8Eipv6%E7%BD%91%E7%BB%9C%E9%85%8D%E7%BD%AE/</guid><description>&lt;p&gt;在完成 &lt;a href="https://zhuanlan.zhihu.com/p/1943305270387275457"&gt;Rustdesk 自建服务器&lt;/a&gt; 的搭建后，我又想到：由于实验室服务器的公网 &lt;strong&gt;IPv6 地址&lt;/strong&gt; 并非永久不变，直接使用 IP 进行远程连接（如 SSH 或 Rustdesk）并不现实，如何确保远程访问的稳定性和便利性呢。为了解决这一痛点，我决定利用 &lt;strong&gt;动态域名解析（DDNS）&lt;/strong&gt; 技术，配合 &lt;strong&gt;ddns-go&lt;/strong&gt; 和 &lt;strong&gt;阿里云 DNS&lt;/strong&gt; 服务，将服务器的动态 IP 地址实时绑定到一个易于记忆的域名上。&lt;/p&gt;</description></item><item><title>Rustdesk自建服务器</title><link>https://kerolt.github.io/p/rustdesk%E8%87%AA%E5%BB%BA%E6%9C%8D%E5%8A%A1%E5%99%A8/</link><pubDate>Mon, 25 Aug 2025 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/rustdesk%E8%87%AA%E5%BB%BA%E6%9C%8D%E5%8A%A1%E5%99%A8/</guid><description>&lt;p&gt;对于现在常见的远程控制软件，例如 ToDesk、向日葵，其免费版本总有诸多限制（帧率低、分辨率低、控制时间有限制），而 RustDesk 的公共服务器现在在国内也不可用，因此我就想到了 RustDesk 的自建服务器。现在我们实验室有几台空闲的电脑，并且这些电脑都有 &lt;strong&gt;IPv6&lt;/strong&gt;，这就省去了我购买云服务器的花费，可以实现零成本搭建远程服务😁&lt;/p&gt;</description></item><item><title>C&amp;C++类型双关转换</title><link>https://kerolt.github.io/p/cc-%E7%B1%BB%E5%9E%8B%E5%8F%8C%E5%85%B3%E8%BD%AC%E6%8D%A2/</link><pubDate>Thu, 21 Aug 2025 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/cc-%E7%B1%BB%E5%9E%8B%E5%8F%8C%E5%85%B3%E8%BD%AC%E6%8D%A2/</guid><description>&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;span class="lnt"&gt;30
&lt;/span&gt;&lt;span class="lnt"&gt;31
&lt;/span&gt;&lt;span class="lnt"&gt;32
&lt;/span&gt;&lt;span class="lnt"&gt;33
&lt;/span&gt;&lt;span class="lnt"&gt;34
&lt;/span&gt;&lt;span class="lnt"&gt;35
&lt;/span&gt;&lt;span class="lnt"&gt;36
&lt;/span&gt;&lt;span class="lnt"&gt;37
&lt;/span&gt;&lt;span class="lnt"&gt;38
&lt;/span&gt;&lt;span class="lnt"&gt;39
&lt;/span&gt;&lt;span class="lnt"&gt;40
&lt;/span&gt;&lt;span class="lnt"&gt;41
&lt;/span&gt;&lt;span class="lnt"&gt;42
&lt;/span&gt;&lt;span class="lnt"&gt;43
&lt;/span&gt;&lt;span class="lnt"&gt;44
&lt;/span&gt;&lt;span class="lnt"&gt;45
&lt;/span&gt;&lt;span class="lnt"&gt;46
&lt;/span&gt;&lt;span class="lnt"&gt;47
&lt;/span&gt;&lt;span class="lnt"&gt;48
&lt;/span&gt;&lt;span class="lnt"&gt;49
&lt;/span&gt;&lt;span class="lnt"&gt;50
&lt;/span&gt;&lt;span class="lnt"&gt;51
&lt;/span&gt;&lt;span class="lnt"&gt;52
&lt;/span&gt;&lt;span class="lnt"&gt;53
&lt;/span&gt;&lt;span class="lnt"&gt;54
&lt;/span&gt;&lt;span class="lnt"&gt;55
&lt;/span&gt;&lt;span class="lnt"&gt;56
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;auto&lt;/span&gt; &lt;span class="nf"&gt;ASSERT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;flag&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;flag&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cerr&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// READ: 枚举类型 &amp;lt;https://zh.cppreference.com/w/cpp/language/enum&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// `enum` 是 C 的兼容类型，本质上其对应类型的常量。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 在 `enum` 中定义标识符等价于定义 constexpr 常量，
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 这些标识符不需要前缀，可以直接引用。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 因此 `enum` 定义会污染命名空间。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="nc"&gt;ColorEnum&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;COLOR_RED&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;COLOR_GREEN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;COLOR_YELLOW&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;COLOR_BLUE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 有作用域枚举型是 C++ 引入的类型安全枚举。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 其内部标识符需要带前缀引用，如 `Color::Red`。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 作用域枚举型可以避免命名空间污染，并提供类型安全保证。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Color&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Red&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;COLOR_RED&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Green&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Yellow&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Blue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;ColorEnum&lt;/span&gt; &lt;span class="nf"&gt;convert_by_pun&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Color&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// READ: &amp;lt;https://zh.cppreference.com/w/cpp/language/union&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// `union` 表示在同一内存位置存储的不同类型的值。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 其常见用法是实现类型双关转换，即将一种类型的值转换为另一种无关类型的值。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 但这种写法实际上仅在 C 语言良定义，在 C++ 中是未定义行为。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 这是比较少见的 C++ 不与 C 保持兼容的特性。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// READ: 类型双关 &amp;lt;https://tttapa.github.io/Pages/Programming/Cpp/Practices/type-punning.html&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;union&lt;/span&gt; &lt;span class="nc"&gt;TypePun&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ColorEnum&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Color&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;TypePun&lt;/span&gt; &lt;span class="n"&gt;pun&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;pun&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;pun&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ASSERT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;convert_by_pun&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Color&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Red&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;COLOR_RED&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Type punning conversion&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ASSERT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;convert_by_pun&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Color&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Green&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;COLOR_GREEN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Type punning conversion&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ASSERT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;convert_by_pun&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Color&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Yellow&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;COLOR_YELLOW&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Type punning conversion&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ASSERT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;convert_by_pun&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Color&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Blue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;COLOR_BLUE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Type punning conversion&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;</description></item><item><title>Git中文件换行符都使用LF</title><link>https://kerolt.github.io/p/git%E4%B8%AD%E6%96%87%E4%BB%B6%E6%8D%A2%E8%A1%8C%E7%AC%A6%E9%83%BD%E4%BD%BF%E7%94%A8lf/</link><pubDate>Thu, 21 Aug 2025 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/git%E4%B8%AD%E6%96%87%E4%BB%B6%E6%8D%A2%E8%A1%8C%E7%AC%A6%E9%83%BD%E4%BD%BF%E7%94%A8lf/</guid><description>&lt;p&gt;有时候我们会在多个平台上编辑文件、代码，此时我们希望所有文件，包括你在 Windows 上编辑的文件（Windows 采用的是 CRLF），都使用 LF 换行符，那么可以修改 &lt;code&gt;.gitattributes&lt;/code&gt; 文件来强制执行这个规则：&lt;/p&gt;</description></item><item><title>关于内存对齐、位域的思考</title><link>https://kerolt.github.io/p/%E5%85%B3%E4%BA%8E%E5%86%85%E5%AD%98%E5%AF%B9%E9%BD%90%E4%BD%8D%E5%9F%9F%E7%9A%84%E6%80%9D%E8%80%83/</link><pubDate>Tue, 22 Jul 2025 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/%E5%85%B3%E4%BA%8E%E5%86%85%E5%AD%98%E5%AF%B9%E9%BD%90%E4%BD%8D%E5%9F%9F%E7%9A%84%E6%80%9D%E8%80%83/</guid><description>&lt;h2 id="什么是内存对齐为什么需要它"&gt;什么是内存对齐？为什么需要它？&lt;/h2&gt;
&lt;p&gt;内存对齐（Memory Alignment）是计算机系统中数据在内存中存储的一种规则：​&lt;strong&gt;​数据在内存中的起始地址必须是其自身大小的整数倍​&lt;/strong&gt;​。例如，一个 4 字节的整型变量（&lt;code&gt;int&lt;/code&gt;），其起始地址必须是 4 的倍数（如地址 0x0000、0x0004、0x0008 等）。&lt;/p&gt;</description></item><item><title>eBPF Map中的数据成员类型的宏定义</title><link>https://kerolt.github.io/p/ebpf-map%E4%B8%AD%E7%9A%84%E6%95%B0%E6%8D%AE%E6%88%90%E5%91%98%E7%B1%BB%E5%9E%8B%E7%9A%84%E5%AE%8F%E5%AE%9A%E4%B9%89/</link><pubDate>Mon, 07 Jul 2025 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/ebpf-map%E4%B8%AD%E7%9A%84%E6%95%B0%E6%8D%AE%E6%88%90%E5%91%98%E7%B1%BB%E5%9E%8B%E7%9A%84%E5%AE%8F%E5%AE%9A%E4%B9%89/</guid><description>&lt;p&gt;&lt;code&gt;__uint&lt;/code&gt;, &lt;code&gt;__type&lt;/code&gt;, &lt;code&gt;__array&lt;/code&gt;, &lt;code&gt;__ulong&lt;/code&gt; 这些宏主要用于 &lt;strong&gt;eBPF Map 的定义&lt;/strong&gt; 中，帮助 LLVM 编译器和 BPF CO-RE (Compile Once – Run Everywhere) 理解和提取 eBPF Map 的元数据信息。它们通常与 &lt;code&gt;BPF_MAP_DEF&lt;/code&gt; 或 &lt;code&gt;struct&lt;/code&gt; 配合使用，在 eBPF 程序中用于告诉内核如何创建 BPF map。&lt;/p&gt;</description></item><item><title>CO-RE机制与vmlinux.h</title><link>https://kerolt.github.io/p/co-re%E6%9C%BA%E5%88%B6%E4%B8%8Evmlinux.h/</link><pubDate>Tue, 01 Jul 2025 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/co-re%E6%9C%BA%E5%88%B6%E4%B8%8Evmlinux.h/</guid><description>&lt;p&gt;通过解耦编译时依赖和运行时重定位，实现 BPF 程序对内核版本与配置差异的自动适配。vmlinux.h 之所以无需严格匹配你的内核配置或版本，关键在于以下机制：&lt;/p&gt;</description></item><item><title>Curl使用</title><link>https://kerolt.github.io/p/curl%E4%BD%BF%E7%94%A8/</link><pubDate>Tue, 01 Jul 2025 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/curl%E4%BD%BF%E7%94%A8/</guid><description>&lt;p&gt;curl 是一个强大的命令行工具，用于传输数据，支持多种协议（HTTP、HTTPS、FTP 等）。以下是 curl 的基本使用方法和常见示例。&lt;/p&gt;
&lt;h2 id="基本语法"&gt;基本语法&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;curl [options] [URL...]
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="常用选项"&gt;常用选项&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;选项&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-X&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;指定 HTTP 请求方法 (GET, POST, PUT, DELETE 等)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-H&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;添加请求头&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-d&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;发送 POST 请求数据&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-F&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;发送表单数据 (multipart/form-data)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-G&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;将 -d 数据作为 GET 请求的查询参数&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-o&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;将输出保存到文件&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-O&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;将输出保存到文件，使用远程文件名&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-L&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;跟随重定向&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-v&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;显示详细输出 (verbose)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-u&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;指定用户名和密码&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-A&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;设置 User-Agent&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-k&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;允许不安全的 SSL 连接&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-I&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;只获取响应头&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-s&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;静默模式 (不显示进度或错误信息)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;--data-urlencode&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;URL 编码 POST 数据&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="常见用法示例"&gt;常见用法示例&lt;/h2&gt;
&lt;h3 id="1-发送-get-请求"&gt;1. 发送 GET 请求&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;curl https://example.com
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="2-发送-post-请求"&gt;2. 发送 POST 请求&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;curl -X POST https://example.com/api -d &amp;#39;name=value&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="3-发送-json-数据"&gt;3. 发送 JSON 数据&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;curl -X POST https://example.com/api \
-H &amp;#34;Content-Type: application/json&amp;#34; \
-d &amp;#39;{&amp;#34;key1&amp;#34;:&amp;#34;value1&amp;#34;, &amp;#34;key2&amp;#34;:&amp;#34;value2&amp;#34;}&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="4-发送表单数据"&gt;4. 发送表单数据&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;curl -X POST https://example.com/form \
-d &amp;#39;username=admin&amp;#39; \
-d &amp;#39;password=123456&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="5-上传文件"&gt;5. 上传文件&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;curl -X POST https://example.com/upload \
-F &amp;#34;file=@/path/to/file.txt&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="6-设置请求头"&gt;6. 设置请求头&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;curl -H &amp;#34;Authorization: Bearer token&amp;#34; \
-H &amp;#34;Content-Type: application/json&amp;#34; \
https://example.com/api
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="7-下载文件"&gt;7. 下载文件&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;curl -O https://example.com/file.zip
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="8-跟随重定向"&gt;8. 跟随重定向&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;curl -L https://example.com/redirect
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="9-使用基本认证"&gt;9. 使用基本认证&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;curl -u username:password https://example.com
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="10-保存-cookie-并发送"&gt;10. 保存 cookie 并发送&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;# 保存 cookie
curl -c cookies.txt https://example.com/login -d &amp;#34;user=name&amp;amp;pass=123&amp;#34;
# 使用 cookie
curl -b cookies.txt https://example.com/dashboard
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="11-测试-api-响应时间"&gt;11. 测试 API 响应时间&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;curl -o /dev/null -s -w &amp;#39;Total: %{time_total}s\n&amp;#39; https://example.com
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="12-限制下载速度"&gt;12. 限制下载速度&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;curl --limit-rate 100K -O https://example.com/largefile.zip
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="高级用法"&gt;高级用法&lt;/h2&gt;
&lt;h3 id="发送多部分请求"&gt;发送多部分请求&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;curl -X POST https://example.com/upload \
-F &amp;#34;file=@image.jpg&amp;#34; \
-F &amp;#34;description=My image&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="使用代理"&gt;使用代理&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;curl -x http://proxy.example.com:8080 https://example.com
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="调试请求"&gt;调试请求&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;curl -v https://example.com
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="只获取响应头"&gt;只获取响应头&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;curl -I https://example.com
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="使用自定义-user-agent"&gt;使用自定义 User-Agent&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;curl -A &amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64)&amp;#34; https://example.com
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="注意事项"&gt;注意事项&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;在脚本中使用 curl 时，考虑添加 &lt;code&gt;-s&lt;/code&gt; 或 &lt;code&gt;-sS&lt;/code&gt; 选项（-S 显示错误）&lt;/li&gt;
&lt;li&gt;处理 JSON 数据时，可以使用 &lt;code&gt;jq&lt;/code&gt; 工具进行格式化&lt;/li&gt;
&lt;li&gt;对于复杂的 API 调用，考虑将请求保存为文件并使用 &lt;code&gt;-K&lt;/code&gt; 选项&lt;/li&gt;
&lt;li&gt;在 Windows 上，使用双引号 &lt;code&gt;&amp;quot;&lt;/code&gt; 而不是单引号 &lt;code&gt;'&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>【eBPF学习】使用fentry跟踪tcp连接</title><link>https://kerolt.github.io/p/ebpf%E5%AD%A6%E4%B9%A0%E4%BD%BF%E7%94%A8fentry%E8%B7%9F%E8%B8%AAtcp%E8%BF%9E%E6%8E%A5/</link><pubDate>Sun, 22 Jun 2025 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/ebpf%E5%AD%A6%E4%B9%A0%E4%BD%BF%E7%94%A8fentry%E8%B7%9F%E8%B8%AAtcp%E8%BF%9E%E6%8E%A5/</guid><description>&lt;blockquote&gt;
&lt;p&gt;本文是对 &lt;a href="https://github.com/cilium/ebpf/tree/main/examples/fentry"&gt;cilium/ebpf examples: fentry &lt;/a&gt;的一个学习记录&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;在这里，我们将会利用 ebpf 监控并记录系统上所有新发起的 IPv4 TCP 连接，其工作流程如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;挂载点&lt;/strong&gt;：程序使用 &lt;code&gt;fentry&lt;/code&gt; 机制把自己附加到内核函数 &lt;code&gt;tcp_connect&lt;/code&gt; 的入口。每当系统中有任何一个进程尝试发起一个 TCP 连接时，这个内核函数就会被调用，从而触发我们的 eBPF 程序。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;过滤&lt;/strong&gt;：程序首先检查连接的地址族是否为 &lt;code&gt;AF_INET&lt;/code&gt;，即 IPv4。如果不是（例如是 IPv6），程序会直接退出，不做任何处理。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数据提取&lt;/strong&gt;：对于 IPv4 连接，程序会从传递给 &lt;code&gt;tcp_connect&lt;/code&gt; 函数的 &lt;code&gt;struct sock&lt;/code&gt; 参数中提取以下关键信息：
&lt;ul&gt;
&lt;li&gt;源 IP 地址 (&lt;code&gt;saddr&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;目标 IP 地址 (&lt;code&gt;daddr&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;目标端口 (&lt;code&gt;dport&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;源端口 (&lt;code&gt;sport&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;获取进程信息&lt;/strong&gt;：使用 &lt;code&gt;bpf_get_current_comm()&lt;/code&gt; 辅助函数获取当前发起连接的进程名（例如 &lt;code&gt;curl&lt;/code&gt;, &lt;code&gt;ssh&lt;/code&gt; 等）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数据发送&lt;/strong&gt;：程序将收集到的所有信息（IP 地址、端口、进程名）打包成一个 &lt;code&gt;struct event&lt;/code&gt; 结构体，并通过一个高效的 &lt;code&gt;ringbuf&lt;/code&gt; 映射发送到用户空间。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="什么是-fentry"&gt;什么是 fentry&lt;/h2&gt;
&lt;p&gt;fentry 是 eBPF 中的一种程序附加类型，全称为 &amp;ldquo;function entry&amp;rdquo;（函数入口）。它是现代 Linux 内核中用于跟踪和性能分析的高效机制。&lt;/p&gt;</description></item><item><title>C++透明运算符</title><link>https://kerolt.github.io/p/c-%E9%80%8F%E6%98%8E%E8%BF%90%E7%AE%97%E7%AC%A6/</link><pubDate>Fri, 20 Jun 2025 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/c-%E9%80%8F%E6%98%8E%E8%BF%90%E7%AE%97%E7%AC%A6/</guid><description>&lt;h2 id="透明运算符的概念与价值"&gt;透明运算符的概念与价值&lt;/h2&gt;
&lt;p&gt;在 C++ 编程中，当编写泛型代码时，不同类型的比较或操作可能导致&lt;strong&gt;意外的类型转换&lt;/strong&gt;或&lt;strong&gt;精度损失&lt;/strong&gt;。假设有一个 &lt;code&gt;std::vector&amp;lt;uint32_t&amp;gt;&lt;/code&gt;，使用自定义仿函数进行排序，一切运行正常。但当你将容器改为 &lt;code&gt;std::vector&amp;lt;uint64_t&amp;gt;&lt;/code&gt; 却忘记修改仿函数的实现时，编译器不会报错，但数据可能在比较前被&lt;strong&gt;静默截断&lt;/strong&gt;，导致排序结果完全错误。而 C++14 引入透明运算符可以帮助我们避免这种 bug。&lt;/p&gt;</description></item><item><title>【eBPF学习】使用kprobe监测捕获unlink系统调用</title><link>https://kerolt.github.io/p/ebpf%E5%AD%A6%E4%B9%A0%E4%BD%BF%E7%94%A8kprobe%E7%9B%91%E6%B5%8B%E6%8D%95%E8%8E%B7unlink%E7%B3%BB%E7%BB%9F%E8%B0%83%E7%94%A8/</link><pubDate>Tue, 10 Jun 2025 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/ebpf%E5%AD%A6%E4%B9%A0%E4%BD%BF%E7%94%A8kprobe%E7%9B%91%E6%B5%8B%E6%8D%95%E8%8E%B7unlink%E7%B3%BB%E7%BB%9F%E8%B0%83%E7%94%A8/</guid><description>&lt;blockquote&gt;
&lt;p&gt;本文是对于 &lt;a href="https://eunomia.dev/zh/tutorials/2-kprobe-unlink/"&gt;Eunomia Tutorials 2&lt;/a&gt; 的一个学习记录&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="什么是-kprobe"&gt;什么是 kprobe&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Kprobe​&lt;/strong&gt;​（Kernel Probe）是 Linux 内核提供的一项强大功能，它允许开发者和系统管理员在不​&lt;strong&gt;​修改内核源代码​&lt;/strong&gt;​或重启系统的前提下，在任意内核函数处动态插入“探针”：&lt;/p&gt;</description></item><item><title>Git使用</title><link>https://kerolt.github.io/p/git%E4%BD%BF%E7%94%A8/</link><pubDate>Sun, 18 May 2025 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/git%E4%BD%BF%E7%94%A8/</guid><description>&lt;h2 id="如何修改上次的-commit"&gt;如何修改上次的 commit&lt;/h2&gt;
&lt;p&gt;比如有的时候 commit 漏掉了文件、commit 信息写错了，可以这么做：&lt;/p&gt;
&lt;p&gt;你要指定一个有效的编辑器作为 Git 的默认编辑器，可以使 Vim 或者 VSCode：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git config --global core.editor &lt;span class="s2"&gt;&amp;#34;vim&amp;#34;&lt;/span&gt; &lt;span class="c1"&gt;# 使用 VSCode 的话就用 code&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;然后将上次忘记提交的修改先 &lt;code&gt;git add&lt;/code&gt; （如果有的话），接着：&lt;/p&gt;</description></item><item><title>【CMU15-445 Fall2023】Project4 Concurrency Control 小结</title><link>https://kerolt.github.io/p/cmu15-445-fall2023project4-concurrency-control-%E5%B0%8F%E7%BB%93/</link><pubDate>Tue, 06 May 2025 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/cmu15-445-fall2023project4-concurrency-control-%E5%B0%8F%E7%BB%93/</guid><description>&lt;p&gt;这个 project 主要是希望我们理解 MVCC 的一些相关知识。MVCC 的设计目标是通过维护多个版本的元组（tuple），使得不同的事务能够访问到与其时间戳一致的数据版本，而无需通过锁机制完全阻塞其他事务的操作。具体来说：&lt;/p&gt;</description></item><item><title>C++折叠表达式</title><link>https://kerolt.github.io/p/c-%E6%8A%98%E5%8F%A0%E8%A1%A8%E8%BE%BE%E5%BC%8F/</link><pubDate>Tue, 06 May 2025 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/c-%E6%8A%98%E5%8F%A0%E8%A1%A8%E8%BE%BE%E5%BC%8F/</guid><description>&lt;p&gt;C++17 为模板元编程带来了一个非常有用的特性：&lt;strong&gt;折叠表达式（fold expressions）&lt;/strong&gt;。它的出现让变参模板函数的编写变得更加简洁、清晰和直观。&lt;/p&gt;
&lt;h2 id="1-如何处理变长参数包"&gt;1. 如何处理变长参数包&lt;/h2&gt;
&lt;p&gt;在 C++11/14 中，如果我们要处理变长参数包（parameter pack），通常需要递归展开，例如：&lt;/p&gt;</description></item><item><title>使用 Concept 替代基于虚函数的接口</title><link>https://kerolt.github.io/p/%E4%BD%BF%E7%94%A8-concept-%E6%9B%BF%E4%BB%A3%E5%9F%BA%E4%BA%8E%E8%99%9A%E5%87%BD%E6%95%B0%E7%9A%84%E6%8E%A5%E5%8F%A3/</link><pubDate>Mon, 28 Apr 2025 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/%E4%BD%BF%E7%94%A8-concept-%E6%9B%BF%E4%BB%A3%E5%9F%BA%E4%BA%8E%E8%99%9A%E5%87%BD%E6%95%B0%E7%9A%84%E6%8E%A5%E5%8F%A3/</guid><description>&lt;p&gt;在 C++20 及更高版本中，可以使用 Concepts 来替代传统的基于虚函数的接口设计，这种方式提供了更好的编译时检查、更高效的代码生成和更灵活的接口约束。&lt;/p&gt;
&lt;p&gt;在之前，可能是这样的：&lt;/p&gt;</description></item><item><title>【解决】Fedora42升级启动时显示kernel panic</title><link>https://kerolt.github.io/p/%E8%A7%A3%E5%86%B3fedora42%E5%8D%87%E7%BA%A7%E5%90%AF%E5%8A%A8%E6%97%B6%E6%98%BE%E7%A4%BAkernel-panic/</link><pubDate>Sun, 27 Apr 2025 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/%E8%A7%A3%E5%86%B3fedora42%E5%8D%87%E7%BA%A7%E5%90%AF%E5%8A%A8%E6%97%B6%E6%98%BE%E7%A4%BAkernel-panic/</guid><description>&lt;p&gt;最近 Fedora42 更新了，因此我打算升级一下玩玩。在执行完下面的命令后：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo dnf upgrade --refresh
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo dnf system-upgrade download --releasever&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;42&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo dnf system-upgrade reboot
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;重启开机成了这样:(&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy"&gt;&lt;/p&gt;
&lt;p&gt;在网上搜索一圈后，执行以下命令系统就 ok 了：&lt;/p&gt;</description></item><item><title>C++何时会阻止默认的特殊成员函数的生成</title><link>https://kerolt.github.io/p/c-%E4%BD%95%E6%97%B6%E4%BC%9A%E9%98%BB%E6%AD%A2%E9%BB%98%E8%AE%A4%E7%9A%84%E7%89%B9%E6%AE%8A%E6%88%90%E5%91%98%E5%87%BD%E6%95%B0%E7%9A%84%E7%94%9F%E6%88%90/</link><pubDate>Thu, 13 Mar 2025 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/c-%E4%BD%95%E6%97%B6%E4%BC%9A%E9%98%BB%E6%AD%A2%E9%BB%98%E8%AE%A4%E7%9A%84%E7%89%B9%E6%AE%8A%E6%88%90%E5%91%98%E5%87%BD%E6%95%B0%E7%9A%84%E7%94%9F%E6%88%90/</guid><description>&lt;p&gt;在C++中，编译器会根据类的定义情况自动决定是否生成默认的特殊成员函数（如构造函数、拷贝/移动操作、析构函数）。&lt;/p&gt;
&lt;h2 id="1-用户显式声明相关成员函数"&gt;1. 用户显式声明相关成员函数&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;显式声明或删除某个函数&lt;/strong&gt;：&lt;/p&gt;
&lt;p&gt;如果用户显式声明（即使使用 &lt;code&gt;=default&lt;/code&gt; 或 &lt;code&gt;=delete&lt;/code&gt;）某个特殊成员函数，编译器将&lt;strong&gt;不再生成默认版本&lt;/strong&gt;。例如：&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>【CMU15-445 Fall2023】Project3 Query Execution 小结</title><link>https://kerolt.github.io/p/cmu15-445-fall2023project3-query-execution-%E5%B0%8F%E7%BB%93/</link><pubDate>Tue, 11 Mar 2025 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/cmu15-445-fall2023project3-query-execution-%E5%B0%8F%E7%BB%93/</guid><description>&lt;blockquote&gt;
&lt;p&gt;该系列博客只是为了记录自己在写 Lab 时的思路，按照课程要求不会在 Github 和博客中公开源代码。欢迎与我一起讨论交流！&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这个 project 和之前就不一样了，开始深入数据库内核的实现了。需要理清楚一条 sql 语句是如何被执行的，方才能写出代码。&lt;/p&gt;</description></item><item><title>Hugo配置Github Actions</title><link>https://kerolt.github.io/p/hugo%E9%85%8D%E7%BD%AEgithub-actions/</link><pubDate>Fri, 07 Feb 2025 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/hugo%E9%85%8D%E7%BD%AEgithub-actions/</guid><description>&lt;p&gt;最近把博客的构建工具从 Hexo 换成了 Hugo，感觉 Hugo 配置和使用起来更简洁方便。&lt;/p&gt;
&lt;p&gt;由于我的博客总体来说有两个仓库，一个私有仓库是放置建站工具的目录，其中包含博客 Markdown 内容、一些配置还有主题；另一个就是通过 GitHub Pages 来访问公共仓库。为了方便，之前在使用 Hexo 的使用使用了 Github Actions 来一键部署博客，换成 Hugo 后这个 actions 需要修改一下。&lt;/p&gt;</description></item><item><title>Linux下微信无法使用中文输入法问题解决</title><link>https://kerolt.github.io/p/linux%E4%B8%8B%E5%BE%AE%E4%BF%A1%E6%97%A0%E6%B3%95%E4%BD%BF%E7%94%A8%E4%B8%AD%E6%96%87%E8%BE%93%E5%85%A5%E6%B3%95%E9%97%AE%E9%A2%98%E8%A7%A3%E5%86%B3/</link><pubDate>Tue, 31 Dec 2024 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/linux%E4%B8%8B%E5%BE%AE%E4%BF%A1%E6%97%A0%E6%B3%95%E4%BD%BF%E7%94%A8%E4%B8%AD%E6%96%87%E8%BE%93%E5%85%A5%E6%B3%95%E9%97%AE%E9%A2%98%E8%A7%A3%E5%86%B3/</guid><description>&lt;p&gt;微信在不久前终于有了 Linux 原生版本，我的电脑是 Fedora41，之前安装的是 flatpak 打包的微信，现在在官网下载 rpm 包后运行发现无法使用 fcitx 的中文输入法，找了一下是环境遍历的问题。&lt;/p&gt;</description></item><item><title>【MIT6.S081】Lab10 mmap</title><link>https://kerolt.github.io/p/mit6.s081lab10-mmap/</link><pubDate>Fri, 22 Nov 2024 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/mit6.s081lab10-mmap/</guid><description>&lt;h2 id="什么是mmap"&gt;什么是mmap？&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;mmap&lt;/code&gt; 是一种用于将文件或设备与进程的地址空间关联起来的内存映射技术。通过 &lt;code&gt;mmap&lt;/code&gt;，可以将文件的内容直接映射到进程的虚拟内存地址空间，使得文件的内容可以像操作普通内存一样进行读取和写入。&lt;/p&gt;</description></item><item><title>【MIT6.S081】Lab9 file system</title><link>https://kerolt.github.io/p/mit6.s081lab9-file-system/</link><pubDate>Tue, 19 Nov 2024 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/mit6.s081lab9-file-system/</guid><description>&lt;h2 id="intro"&gt;Intro&lt;/h2&gt;
&lt;p&gt;在这个实验中，我们需要让xv6支持更大的文件和软链接。实验总体不是特别难，不过需要我们理解好文件系统是如何工作的。&lt;code&gt;Lab8 lock&lt;/code&gt;中的Buffer Cache也是文件系统的一部分，不过它位于文件系统的下层，这里我们需要处理的更多在上层，偏应用层。&lt;/p&gt;</description></item><item><title>【MIT6.S081】Lab8 lock</title><link>https://kerolt.github.io/p/mit6.s081lab8-lock/</link><pubDate>Sun, 17 Nov 2024 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/mit6.s081lab8-lock/</guid><description>&lt;h2 id="intro"&gt;Intro&lt;/h2&gt;
&lt;p&gt;这个实验个人感觉挺难的，需要我们重新设计数据结构，还要考虑在并发（并行）情况下对于锁的操作，以减少多核情况下对于锁的竞争。其中主要涉及内存分配和IO缓冲块分配，在这个lab之前，xv6对于这两个分配都是使用的全局对象，并只有一把全局锁进行操作，这样的话在并行情况下锁的竞争是很激烈的，我们的任务就是重新设计这两个分配器，它们的重构思路并不完全一致，需要具体问题具体分析。&lt;/p&gt;</description></item><item><title>【MIT6.S081】xv6进程调度分析</title><link>https://kerolt.github.io/p/mit6.s081xv6%E8%BF%9B%E7%A8%8B%E8%B0%83%E5%BA%A6%E5%88%86%E6%9E%90/</link><pubDate>Sat, 16 Nov 2024 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/mit6.s081xv6%E8%BF%9B%E7%A8%8B%E8%B0%83%E5%BA%A6%E5%88%86%E6%9E%90/</guid><description>&lt;p&gt;在做thread lab的时候，阅读xv6的源码后对于进程调度的实现有了大致的了解，但是其中锁的获取与释放顺序让我困惑了好久：在yield函数中，不是先获取了进程p的锁吗，那么之后在调度器中又获取p的锁，那不是会死锁吗？在调度器内使用swtch发生进程切换后，又会跳转到哪里？&lt;/p&gt;
&lt;p&gt;而在我观摩大佬的一些博客和视频后，发现我之前的想法有很大的问题，归根结底是没有弄明白xv6何时发生了切换，切换后应该从哪里开始运行。这篇笔记就是对于分析xv6进程调度的总结。&lt;/p&gt;</description></item><item><title>【MIT6.S081】Lab6 multithreading</title><link>https://kerolt.github.io/p/mit6.s081lab6-multithreading/</link><pubDate>Fri, 15 Nov 2024 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/mit6.s081lab6-multithreading/</guid><description>&lt;p&gt;本次的实验总体都不是很难，第一个练习让我们在用户态模拟了线程的切换，这里重要的就是进程/线程上下文的保存与恢复；第二三个练习则是让我们跳出了xv6，去熟悉pthread库和线程的同步互斥。&lt;/p&gt;</description></item><item><title>【CMU15-445 Fall2023】Project2 Extendible Hash Index 小结</title><link>https://kerolt.github.io/p/cmu15-445-fall2023project2-extendible-hash-index-%E5%B0%8F%E7%BB%93/</link><pubDate>Tue, 12 Nov 2024 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/cmu15-445-fall2023project2-extendible-hash-index-%E5%B0%8F%E7%BB%93/</guid><description>&lt;blockquote&gt;
&lt;p&gt;该系列博客只是为了记录自己在写Lab时的思路，按照课程要求不会在Github和博客中公开源代码。欢迎与我一起讨论交流！&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;太菜了，从没打过这么艰难的仗QAQ。由于课程的要求不能公开源代码，所以网上的资源会少很多，平台上的测试案例比较全面，有的还比较刁钻，需要考虑到可拓展哈希的实现细节。在自认为写完了后，提交了近40来次总有几个测试集过不了，还好没有崩溃，在看了几篇博客的方法后，加上自己画图理解，最后终于过了😭。不过回头写博客的时候再去看代码，也没有特别的复杂，还是得明白其中的算法逻辑是如何实现的。&lt;/p&gt;</description></item><item><title>【MIT6.S081】Lab5 copy-on-write fork</title><link>https://kerolt.github.io/p/mit6.s081lab5-copy-on-write-fork/</link><pubDate>Tue, 12 Nov 2024 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/mit6.s081lab5-copy-on-write-fork/</guid><description>&lt;h2 id="为什么我们需要copy-on-write"&gt;为什么我们需要copy on write&lt;/h2&gt;
&lt;p&gt;通过xv6的实验指导书，我们可以知道：&lt;/p&gt;
&lt;p&gt;xv6中的&lt;code&gt;fork()&lt;/code&gt;系统调用将父进程的所有用户空间内存复制到子进程中。如果父进程所使用的页数很大，复制可能需要很长时间，而这样的复制操作经常是没有用的：&lt;code&gt;fork()&lt;/code&gt;之后通常是子进程中的&lt;code&gt;exec()&lt;/code&gt;，这会丢弃复制的内存而不是使用它们。&lt;/p&gt;
&lt;p&gt;那么，我们是不是可以在子进程刚创建时将其页表的映射到父进程的物理页，而在其需要对内存进行写操作时再重新分配内存呢？没错，这就是通过copy on write（写时复制）技术来进行优化。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;该实验的代码实现见：&lt;a href="https://github.com/kerolt/xv6-labs-2023/commit/68fd833dc03a681c04a647ed6aae2108a1e43fbb"&gt;仓库commit&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>【MIT6.S081】Lab4 trap backtrace</title><link>https://kerolt.github.io/p/mit6.s081lab4-trap-backtrace/</link><pubDate>Sun, 10 Nov 2024 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/mit6.s081lab4-trap-backtrace/</guid><description>&lt;p&gt;backtrace这个lab非常有意思，虽然实现的代码量不多，但是能让我们更好地理解栈、栈帧、指针、gdb的一些知识。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;该实验的代码实现见：&lt;a href="https://github.com/kerolt/xv6-labs-2023/commit/d1dba8ae4a1a71604e8bb6df5238f8cac1771683"&gt;仓库commit&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>【MIT6.S081】Lab4 trap alarm</title><link>https://kerolt.github.io/p/mit6.s081lab4-trap-alarm/</link><pubDate>Thu, 07 Nov 2024 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/mit6.s081lab4-trap-alarm/</guid><description>&lt;p&gt;Alarm综合了该lab中前几个练习的知识点：系统调用、中断、寄存器等，我们需要对trap机制有比较好的认识才能理解。Alarm的任务是需要我们完成一个定时器的实现：&lt;code&gt;sigalarm(interval, handler)&lt;/code&gt;，当调用&lt;code&gt;sigalarm(n, fn)&lt;/code&gt;时，内核会每n个时间间隔（tick）执行fn函数。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;该实验的代码实现见：&lt;a href="https://github.com/kerolt/xv6-labs-2023/commit/0f70ef7d68ab1273262b8d43a2deaf7345a87698"&gt;仓库commit&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>【MIT6.S081】Lab3 page tables（上）</title><link>https://kerolt.github.io/p/mit6.s081lab3-page-tables%E4%B8%8A/</link><pubDate>Tue, 05 Nov 2024 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/mit6.s081lab3-page-tables%E4%B8%8A/</guid><description>&lt;h2 id="前言"&gt;前言&lt;/h2&gt;
&lt;p&gt;页表是最常用的机制，操作系统通过它为每个进程提供自己的私有地址空间和内存。页表决定了内存地址的含义，以及可以访问物理内存的哪些部分。在本文中，记录了&lt;code&gt;Lab: page tables&lt;/code&gt;的前两个实验：加速系统调用和打印页表。&lt;/p&gt;</description></item><item><title>【MIT6.S081】Lab3 page tables（下）</title><link>https://kerolt.github.io/p/mit6.s081lab3-page-tables%E4%B8%8B/</link><pubDate>Tue, 05 Nov 2024 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/mit6.s081lab3-page-tables%E4%B8%8B/</guid><description>&lt;p&gt;本关的任务为“Detect which pages have been accessed”，需要实现一个新的系统调用&lt;code&gt;pgaccess&lt;/code&gt;，它指出访问了哪些页面被访问了（读、写等）。系统调用需要三个参数：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;第一个用户页面的起始虚拟地址&lt;/li&gt;
&lt;li&gt;需要检查页数&lt;/li&gt;
&lt;li&gt;一个存储每一页是否被访问的掩码&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;该lab的所有代码：&lt;a href="https://github.com/kerolt/xv6-labs-2023/commit/87373230877d27d7f60c39696688863210c41133"&gt;Github&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>【MIT6.S081】Lab2 system calls</title><link>https://kerolt.github.io/p/mit6.s081lab2-system-calls/</link><pubDate>Mon, 28 Oct 2024 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/mit6.s081lab2-system-calls/</guid><description>&lt;h2 id="前言"&gt;前言&lt;/h2&gt;
&lt;p&gt;这个lab开始我们就正式进入了xv6的世界了，这一次我们可以了解到内核中系统调用的注册和运行原理，这可以说是之后lab的一个基石。&lt;/p&gt;</description></item><item><title>【MIT6.S081】Lab1 utilities</title><link>https://kerolt.github.io/p/mit6.s081lab1-utilities/</link><pubDate>Sun, 27 Oct 2024 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/mit6.s081lab1-utilities/</guid><description>&lt;h2 id="前言"&gt;前言&lt;/h2&gt;
&lt;p&gt;该Lab通过实现几个命令来熟悉 xv6 及其系统调用&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;sleep&lt;/li&gt;
&lt;li&gt;pingpong&lt;/li&gt;
&lt;li&gt;primes&lt;/li&gt;
&lt;li&gt;find&lt;/li&gt;
&lt;li&gt;xargs&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;官方实验指导：&lt;a href="https://pdos.csail.mit.edu/6.S081/2021/labs/util.html"&gt;https://pdos.csail.mit.edu/6.S081/2021/labs/util.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;个人代码实现仓库：&lt;a href="https://github.com/kerolt/xv6-labs-2023/"&gt;https://github.com/kerolt/xv6-labs-2023&lt;/a&gt;&lt;/p&gt;</description></item><item><title>【CMU15-445 Fall2023】Project1 Buffer Pool 小结</title><link>https://kerolt.github.io/p/cmu15-445-fall2023project1-buffer-pool-%E5%B0%8F%E7%BB%93/</link><pubDate>Sat, 12 Oct 2024 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/cmu15-445-fall2023project1-buffer-pool-%E5%B0%8F%E7%BB%93/</guid><description>&lt;blockquote&gt;
&lt;p&gt;该系列博客只是为了记录自己在写Lab时的思路，按照课程要求不会在Github和博客中公开源代码。欢迎与我一起讨论交流！&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这个Project需要我们实现一个缓存池，减少对于磁盘的频繁IO。开始慢慢上强度了，细节拉满！&lt;/p&gt;</description></item><item><title>【CMU15-445 Fall2023】Project0 C++ Primer 小结</title><link>https://kerolt.github.io/p/cmu15-445-fall2023project0-c-primer-%E5%B0%8F%E7%BB%93/</link><pubDate>Sun, 06 Oct 2024 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/cmu15-445-fall2023project0-c-primer-%E5%B0%8F%E7%BB%93/</guid><description>&lt;blockquote&gt;
&lt;p&gt;该系列博客只是为了记录自己在写Lab时的思路，按照课程要求不会在Github和博客中公开源代码。欢迎与我一起讨论交流！&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;project0只在task4中浅浅涉及了一点BusTub的内容，其他都是检测我们对于C++的一个掌握，主要涉及智能指针和C++的常用特性（dynamic_cast、std::move、并发与锁等）。&lt;/p&gt;</description></item><item><title>【动手写协程库 5】常用IO函数的HOOK功能</title><link>https://kerolt.github.io/p/%E5%8A%A8%E6%89%8B%E5%86%99%E5%8D%8F%E7%A8%8B%E5%BA%93-5%E5%B8%B8%E7%94%A8io%E5%87%BD%E6%95%B0%E7%9A%84hook%E5%8A%9F%E8%83%BD/</link><pubDate>Mon, 30 Sep 2024 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/%E5%8A%A8%E6%89%8B%E5%86%99%E5%8D%8F%E7%A8%8B%E5%BA%93-5%E5%B8%B8%E7%94%A8io%E5%87%BD%E6%95%B0%E7%9A%84hook%E5%8A%9F%E8%83%BD/</guid><description>&lt;blockquote&gt;
&lt;p&gt;【动手写协程库】系列笔记是学习 sylar 的协程库时的记录，参考了 &lt;a href="https://www.midlane.top/wiki/pages/viewpage.action?pageId=10060952"&gt;从零开始重写sylar C++高性能分布式服务器框架&lt;/a&gt; 和代码随想录中的 &lt;a href="https://www.programmercarl.com/other/project_coroutine.html#%E4%B8%8B%E8%BD%BD%E6%96%B9%E5%BC%8F"&gt;文档&lt;/a&gt;。文章并不是对所有代码的详细解释，而是为了自己理解一些片段所做的笔记。&lt;/p&gt;
&lt;p&gt;hook 函数的具体定义实现可以在这里查看：&lt;a href="https://github.com/kerolt/coroutine-lib/blob/master/src/hook.cpp"&gt;Github: src/hook.cpp&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;该协程库框架的目标并不是做成类似 goroutine 那样，而是希望能够通过协程来提高 IO 处理的效率。因此，对于每个文件描述符 fd，我们都希望它有一个读写 IO 的超时时间。&lt;/p&gt;
&lt;p&gt;hook 的目的是在不重新编写代码的情况下，把老代码中的 socket IO 相关的 API 都&lt;strong&gt;转成异步&lt;/strong&gt;，以提高性能。&lt;/p&gt;</description></item><item><title>【动手写协程库 4】IO协程调度器</title><link>https://kerolt.github.io/p/%E5%8A%A8%E6%89%8B%E5%86%99%E5%8D%8F%E7%A8%8B%E5%BA%93-4io%E5%8D%8F%E7%A8%8B%E8%B0%83%E5%BA%A6%E5%99%A8/</link><pubDate>Sun, 29 Sep 2024 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/%E5%8A%A8%E6%89%8B%E5%86%99%E5%8D%8F%E7%A8%8B%E5%BA%93-4io%E5%8D%8F%E7%A8%8B%E8%B0%83%E5%BA%A6%E5%99%A8/</guid><description>&lt;blockquote&gt;
&lt;p&gt;【动手写协程库】系列笔记是学习 sylar 的协程库时的记录，参考了 &lt;a href="https://www.midlane.top/wiki/pages/viewpage.action?pageId=10060952"&gt;从零开始重写sylar C++高性能分布式服务器框架&lt;/a&gt; 和代码随想录中的 &lt;a href="https://www.programmercarl.com/other/project_coroutine.html#%E4%B8%8B%E8%BD%BD%E6%96%B9%E5%BC%8F"&gt;文档&lt;/a&gt;。文章并不是对所有代码的详细解释，而是为了自己理解一些片段所做的笔记。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;IOManager&lt;/code&gt; 类中具体定义实现可以在这里查看：&lt;a href="https://github.com/kerolt/coroutine-lib/blob/master/src/iomanager.cpp"&gt;Github: src/iomanager.cpp&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;之前实现的协程调度器的功能其实非常简单，当添加任务后调度器只是单纯的从任务队列中取出任务交给协程去执行。sylar 的协程库的关注对象是网络 IO，如果采用这么简单的调度就根本没有用到协程的精髓。&lt;/p&gt;
&lt;p&gt;sylar 的 IO 协程调度解决了之前调度器在 idle 状态下忙等待导致 CPU 占用率高的问题。IO 协程调度器使用一对管道 fd 来 tickle 调度协程，当调度器空闲时，idle 协程通过 epoll_wait 阻塞在管道的读描述符上，等管道的可读事件。添加新任务时，tickle 方法写管道，idle 协程检测到管道可读后退出，调度器执行调度。&lt;/p&gt;</description></item><item><title>【动手写协程库 3】定时器</title><link>https://kerolt.github.io/p/%E5%8A%A8%E6%89%8B%E5%86%99%E5%8D%8F%E7%A8%8B%E5%BA%93-3%E5%AE%9A%E6%97%B6%E5%99%A8/</link><pubDate>Sat, 28 Sep 2024 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/%E5%8A%A8%E6%89%8B%E5%86%99%E5%8D%8F%E7%A8%8B%E5%BA%93-3%E5%AE%9A%E6%97%B6%E5%99%A8/</guid><description>&lt;blockquote&gt;
&lt;p&gt;【动手写协程库】系列笔记是学习 sylar 的协程库时的记录，参考了 &lt;a href="https://www.midlane.top/wiki/pages/viewpage.action?pageId=10060952"&gt;从零开始重写sylar C++高性能分布式服务器框架&lt;/a&gt; 和代码随想录中的 &lt;a href="https://www.programmercarl.com/other/project_coroutine.html#%E4%B8%8B%E8%BD%BD%E6%96%B9%E5%BC%8F"&gt;文档&lt;/a&gt;。文章并不是对所有代码的详细解释，而是为了自己理解一些片段所做的笔记。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;TimerManager&lt;/code&gt; 类中具体定义实现可以在这里查看：&lt;a href="https://github.com/kerolt/coroutine-lib/blob/master/src/timer.cpp"&gt;Github: src/timer.cpp&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;通过定时器，我们可以实现给服务器注册定时事件。sylar 的定时器采用最小堆设计，所有定时器根据绝对的超时时间点（也就是超时到期的具体时间戳）进行排序，每次取出离当前时间&lt;strong&gt;最近的一个超时时间点&lt;/strong&gt;，计算出超时需要等待的时间，然后等待超时。超时时间到后，获取当前的绝对时间点，然后&lt;strong&gt;把最小堆里超时时间点小于这个时间点的定时器都收集起来&lt;/strong&gt;，执行它们的回调函数。&lt;/p&gt;</description></item><item><title>函数防抖</title><link>https://kerolt.github.io/p/%E5%87%BD%E6%95%B0%E9%98%B2%E6%8A%96/</link><pubDate>Sun, 22 Sep 2024 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/%E5%87%BD%E6%95%B0%E9%98%B2%E6%8A%96/</guid><description>&lt;p&gt;最近的练手项目web-terminal中（也就是一个网页终端，可执行一些命令），在按下键盘后会显示可能匹配的命令列表（假设对应的函数是&lt;code&gt;setHintList&lt;/code&gt;），这不仅是按下字母按键会触发，按下删除键、tab键都会触发。那就不得不考虑一个问题，如果我们手速太快，那么&lt;code&gt;setHintList&lt;/code&gt;就会频繁触发，但我们只需要响应用户最后一次输入的命令即可，虽然在这个小项目中没啥问题，但是由此可以引出一些对于以后大项目的考虑：如何减小这种多次频繁执行函数带来的性能开销问题？那就是函数防抖~&lt;/p&gt;</description></item><item><title>enable_shared_from_this的作用</title><link>https://kerolt.github.io/p/enable_shared_from_this%E7%9A%84%E4%BD%9C%E7%94%A8/</link><pubDate>Mon, 16 Sep 2024 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/enable_shared_from_this%E7%9A%84%E4%BD%9C%E7%94%A8/</guid><description>&lt;p&gt;C++ 中，&lt;code&gt;std::enable_shared_from_this&lt;/code&gt;类模板和&lt;code&gt;shared_from_this&lt;/code&gt;成员函数主要用于在一个类的成员函数中安全地获取指向自身的&lt;code&gt;std::shared_ptr&lt;/code&gt;。它们的作用更多是为了确保资源正确管理。&lt;/p&gt;</description></item><item><title>【动手写协程库 2】协程调度器</title><link>https://kerolt.github.io/p/%E5%8A%A8%E6%89%8B%E5%86%99%E5%8D%8F%E7%A8%8B%E5%BA%93-2%E5%8D%8F%E7%A8%8B%E8%B0%83%E5%BA%A6%E5%99%A8/</link><pubDate>Wed, 11 Sep 2024 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/%E5%8A%A8%E6%89%8B%E5%86%99%E5%8D%8F%E7%A8%8B%E5%BA%93-2%E5%8D%8F%E7%A8%8B%E8%B0%83%E5%BA%A6%E5%99%A8/</guid><description>&lt;blockquote&gt;
&lt;p&gt;【动手写协程库】系列笔记是学习 sylar 的协程库时的记录，参考了 &lt;a href="https://www.midlane.top/wiki/pages/viewpage.action?pageId=10060952"&gt;从零开始重写sylar C++高性能分布式服务器框架&lt;/a&gt; 和代码随想录中的 &lt;a href="https://www.programmercarl.com/other/project_coroutine.html#%E4%B8%8B%E8%BD%BD%E6%96%B9%E5%BC%8F"&gt;文档&lt;/a&gt;。文章并不是对所有代码的详细解释，而是为了自己理解一些片段所做的笔记。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Scheduler&lt;/code&gt; 类中其他函数的定义可以在这里查看：&lt;a href="https://github.com/kerolt/coroutine-lib/blob/master/src/scheduler.cpp"&gt;Github: src/scheduler.cpp&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Sylar 的协程调度器是一个 N-M 模型，意味着 N 个线程可以运行 M 个协程，协程能够在线程之间进行切换，也可以被绑定到特定的线程上执行。&lt;/p&gt;
&lt;p&gt;调度器可以由应用程序中的任何线程创建，但创建它的线程（称为 caller 线程）可以选择是否参与协程的调度。如果 caller 线程参与调度，那么调度器的线程数会相应减少一个，因为 caller 线程本身也会作为一个调度线程。&lt;/p&gt;</description></item><item><title>【动手写协程库 1】协程定义</title><link>https://kerolt.github.io/p/%E5%8A%A8%E6%89%8B%E5%86%99%E5%8D%8F%E7%A8%8B%E5%BA%93-1%E5%8D%8F%E7%A8%8B%E5%AE%9A%E4%B9%89/</link><pubDate>Tue, 10 Sep 2024 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/%E5%8A%A8%E6%89%8B%E5%86%99%E5%8D%8F%E7%A8%8B%E5%BA%93-1%E5%8D%8F%E7%A8%8B%E5%AE%9A%E4%B9%89/</guid><description>&lt;blockquote&gt;
&lt;p&gt;【动手写协程库】系列笔记是学习 sylar 的协程库时的记录，参考了 &lt;a href="https://www.midlane.top/wiki/pages/viewpage.action?pageId=10060952"&gt;从零开始重写sylar C++高性能分布式服务器框架&lt;/a&gt; 和代码随想录中的 &lt;a href="https://www.programmercarl.com/other/project_coroutine.html#%E4%B8%8B%E8%BD%BD%E6%96%B9%E5%BC%8F"&gt;文档&lt;/a&gt;。文章并不是对所有代码的详细解释，而是为了自己理解一些片段所做的笔记。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Coroutine&lt;/code&gt; 类中其他函数的定义可以在这里查看：&lt;a href="https://github.com/kerolt/coroutine-lib/blob/master/src/coroutine.cpp"&gt;Github: src/coroutine.cpp&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;对于什么是协程，为什么要使用协程，可以看看之前的笔记：&lt;a href="https://kerolt.github.io/posts/f663291a/"&gt;【协程】C++20协程初体验&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;对于我们自己来实现协程，其实在之前 Xv6 的 Lab 中就有做过：&lt;a href="https://kerolt.github.io/posts/cb4e63bc/#Uthread-switching-between-threads"&gt;【MIT6.S081】Lab6 multithreading&lt;/a&gt;，当初做这个 lab 的时候没有意识到这就是协程。协程的切换最重要的就是要保存和恢复上下文，在这个 lab 中，我们通过保存每个协程在切换之前的寄存器的值，以此可用来恢复原来的执行流。&lt;/p&gt;</description></item><item><title>解决X11下窗口拖动撕裂的一个方法</title><link>https://kerolt.github.io/p/%E8%A7%A3%E5%86%B3x11%E4%B8%8B%E7%AA%97%E5%8F%A3%E6%8B%96%E5%8A%A8%E6%92%95%E8%A3%82%E7%9A%84%E4%B8%80%E4%B8%AA%E6%96%B9%E6%B3%95/</link><pubDate>Tue, 03 Sep 2024 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/%E8%A7%A3%E5%86%B3x11%E4%B8%8B%E7%AA%97%E5%8F%A3%E6%8B%96%E5%8A%A8%E6%92%95%E8%A3%82%E7%9A%84%E4%B8%80%E4%B8%AA%E6%96%B9%E6%B3%95/</guid><description>&lt;blockquote&gt;
&lt;p&gt;Debian 系 Linux 安装 N 卡驱动参考这篇 &lt;a href="https://www.if-not-true-then-false.com/2021/debian-ubuntu-linux-mint-nvidia-guide/"&gt;博客&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;最近 Debian 终于是装好 nvidia 的驱动了，但是只能用在 X11 上，并且相比于不用 n 卡驱动时的 Wayland，X11 下的窗口拖动和视频播放会有比较明显的撕裂感，以下是解决的一个方法。&lt;/p&gt;</description></item><item><title>【协程】C++是如何通过SFINAE来检查promise_type的</title><link>https://kerolt.github.io/p/%E5%8D%8F%E7%A8%8Bc-%E6%98%AF%E5%A6%82%E4%BD%95%E9%80%9A%E8%BF%87sfinae%E6%9D%A5%E6%A3%80%E6%9F%A5promise_type%E7%9A%84/</link><pubDate>Sun, 01 Sep 2024 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/%E5%8D%8F%E7%A8%8Bc-%E6%98%AF%E5%A6%82%E4%BD%95%E9%80%9A%E8%BF%87sfinae%E6%9D%A5%E6%A3%80%E6%9F%A5promise_type%E7%9A%84/</guid><description>&lt;p&gt;我们知道在C++20的协程中，自己实现的Coroutine中必须包含一个&lt;code&gt;Promise&lt;/code&gt;，并且这个&lt;code&gt;Promise&lt;/code&gt;必须要实现：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;get_return_object()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;initial_suspend()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;final_suspend()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;unhandled_exception()&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;少了其中任何一个，编译器都会报错。那这是怎么实现的呢？如果是像java那样是一个接口而没有对应的实现从而报错还能理解，但是我们的代码中的&lt;code&gt;Promise&lt;/code&gt;完完全全是我们自己写的，也没有使用继承，编译器你怎么知道我在实现协程时少了什么东西呢？&lt;/p&gt;
&lt;p&gt;答案就是：&lt;strong&gt;SFINAE&lt;/strong&gt;（Substitution Failure Is Not An Error，替换失败不是错误）。&lt;/p&gt;</description></item><item><title>记一次项目构建部署的总结</title><link>https://kerolt.github.io/p/%E8%AE%B0%E4%B8%80%E6%AC%A1%E9%A1%B9%E7%9B%AE%E6%9E%84%E5%BB%BA%E9%83%A8%E7%BD%B2%E7%9A%84%E6%80%BB%E7%BB%93/</link><pubDate>Fri, 30 Aug 2024 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/%E8%AE%B0%E4%B8%80%E6%AC%A1%E9%A1%B9%E7%9B%AE%E6%9E%84%E5%BB%BA%E9%83%A8%E7%BD%B2%E7%9A%84%E6%80%BB%E7%BB%93/</guid><description>&lt;h2 id="前言"&gt;前言&lt;/h2&gt;
&lt;p&gt;暑假里跟着鱼皮的&lt;code&gt;yuindex&lt;/code&gt;项目写了个web终端的小玩具，完成的终端命令不多，但是大体上成型了。由于我打算做一个纯前端的项目，并没有写后端api，这样也方便我最终直接部署到&lt;strong&gt;Github Pages&lt;/strong&gt;上（这样就不用花钱了hh）。&lt;/p&gt;
&lt;p&gt;项目使用vite构建，并使用了ts。在构建部署时遇到了一些问题，由于是第一次将前端项目发布到github pages上，这里记录下。&lt;/p&gt;</description></item><item><title>写一个简单的浏览器脚本来屏蔽CSDN</title><link>https://kerolt.github.io/p/%E5%86%99%E4%B8%80%E4%B8%AA%E7%AE%80%E5%8D%95%E7%9A%84%E6%B5%8F%E8%A7%88%E5%99%A8%E8%84%9A%E6%9C%AC%E6%9D%A5%E5%B1%8F%E8%94%BDcsdn/</link><pubDate>Thu, 29 Aug 2024 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/%E5%86%99%E4%B8%80%E4%B8%AA%E7%AE%80%E5%8D%95%E7%9A%84%E6%B5%8F%E8%A7%88%E5%99%A8%E8%84%9A%E6%9C%AC%E6%9D%A5%E5%B1%8F%E8%94%BDcsdn/</guid><description>&lt;p&gt;在使用手机浏览器搜索时为了免于CSDN垃圾信息的影响，我们可以使用Bing（其他搜索引擎也有类似的功能，但是国内不借助其他方法的情况下体验感最好的也只有Bing了）的“&lt;code&gt;-site:*.csdn.net&lt;/code&gt;”来屏蔽CSDN，但是每次输入搜索内容后还要加这么一个字符串真是太麻烦了，因此可以写一个浏览器脚本来完成这一操作。&lt;/p&gt;</description></item><item><title>C++中如何使用lambda实现递归</title><link>https://kerolt.github.io/p/c-%E4%B8%AD%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8lambda%E5%AE%9E%E7%8E%B0%E9%80%92%E5%BD%92/</link><pubDate>Tue, 27 Aug 2024 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/c-%E4%B8%AD%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8lambda%E5%AE%9E%E7%8E%B0%E9%80%92%E5%BD%92/</guid><description>&lt;p&gt;在用C++刷leetcode时，我希望把一个递归函数像js、python那样写在运行函数内部，那么可以使用&lt;code&gt;function&lt;/code&gt;和&lt;code&gt;lambda表达式&lt;/code&gt;来实现。但如果这个递归函数的参数比较多，那么function的模板参数同样需要写很多，能不能用&lt;code&gt;auto&lt;/code&gt;来实现得简单一点呢？&lt;/p&gt;</description></item><item><title>【协程】C++20协程初体验</title><link>https://kerolt.github.io/p/%E5%8D%8F%E7%A8%8Bc-20%E5%8D%8F%E7%A8%8B%E5%88%9D%E4%BD%93%E9%AA%8C/</link><pubDate>Sun, 18 Aug 2024 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/%E5%8D%8F%E7%A8%8Bc-20%E5%8D%8F%E7%A8%8B%E5%88%9D%E4%BD%93%E9%AA%8C/</guid><description>&lt;h2 id="为什么我们需要协程"&gt;为什么我们需要协程？&lt;/h2&gt;
&lt;p&gt;为什么我们有了线程还需要协程呢？（其实这个问题不应该这么问，协程的出现在线程之前）在一个进程中虽然我们可以创建多个线程，但是在一个进程中能创建的线程数量是有限制的，并且线程的调度仍然受操作系统控制，也就是说线程何时抢占、何时被抢占对于开发者来说都是透明的，并且在调度的过程中还可能涉及到用户态和内核态的切换开销。&lt;/p&gt;</description></item><item><title>用uni-cli创建项目后使用eslint</title><link>https://kerolt.github.io/p/%E7%94%A8uni-cli%E5%88%9B%E5%BB%BA%E9%A1%B9%E7%9B%AE%E5%90%8E%E4%BD%BF%E7%94%A8eslint/</link><pubDate>Sat, 08 Jun 2024 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/%E7%94%A8uni-cli%E5%88%9B%E5%BB%BA%E9%A1%B9%E7%9B%AE%E5%90%8E%E4%BD%BF%E7%94%A8eslint/</guid><description>&lt;p&gt;记录一下如何配置eslint（其实是怕下一次又被折磨）。&lt;/p&gt;</description></item><item><title>VMware17.5.2启动踩坑</title><link>https://kerolt.github.io/p/vmware17.5.2%E5%90%AF%E5%8A%A8%E8%B8%A9%E5%9D%91/</link><pubDate>Mon, 27 May 2024 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/vmware17.5.2%E5%90%AF%E5%8A%A8%E8%B8%A9%E5%9D%91/</guid><description>&lt;p&gt;起因是我想在 Linux 上想用 Uniapp，用 wine 的体验不是很好，故打算用虚拟机跑 Windows。安装好 VMware17.5.2 后，配置好 windows 镜像后，点击启动，却报了这样的错：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Could not open /dev/vmmon: ?????????. Please make sure that the kernel module `vmmon&amp;rsquo; is loaded.&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>避免cout线程不安全的一个做法</title><link>https://kerolt.github.io/p/%E9%81%BF%E5%85%8Dcout%E7%BA%BF%E7%A8%8B%E4%B8%8D%E5%AE%89%E5%85%A8%E7%9A%84%E4%B8%80%E4%B8%AA%E5%81%9A%E6%B3%95/</link><pubDate>Wed, 21 Feb 2024 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/%E9%81%BF%E5%85%8Dcout%E7%BA%BF%E7%A8%8B%E4%B8%8D%E5%AE%89%E5%85%A8%E7%9A%84%E4%B8%80%E4%B8%AA%E5%81%9A%E6%B3%95/</guid><description>&lt;h2 id="前言"&gt;前言&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;std::cout&lt;/code&gt;重载了&lt;code&gt;&amp;lt;&amp;lt;&lt;/code&gt;运算符，这使得写一些很短的代码时很方便。但是如果在多线程的条件下，cout并不是线程安全的。&lt;/p&gt;</description></item><item><title>纠正一下对cpp移动语义的错误理解</title><link>https://kerolt.github.io/p/%E7%BA%A0%E6%AD%A3%E4%B8%80%E4%B8%8B%E5%AF%B9cpp%E7%A7%BB%E5%8A%A8%E8%AF%AD%E4%B9%89%E7%9A%84%E9%94%99%E8%AF%AF%E7%90%86%E8%A7%A3/</link><pubDate>Sun, 18 Feb 2024 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/%E7%BA%A0%E6%AD%A3%E4%B8%80%E4%B8%8B%E5%AF%B9cpp%E7%A7%BB%E5%8A%A8%E8%AF%AD%E4%B9%89%E7%9A%84%E9%94%99%E8%AF%AF%E7%90%86%E8%A7%A3/</guid><description>&lt;p&gt;之前对于移动语义的理解就是使用std::move将一个对象所占有的资源的所有权转移给另一个对象，但是只要使用std::move就足够了吗？这显然是错误的。&lt;/p&gt;</description></item><item><title>C++中lambda与priority_queue一起使用</title><link>https://kerolt.github.io/p/c-%E4%B8%ADlambda%E4%B8%8Epriority_queue%E4%B8%80%E8%B5%B7%E4%BD%BF%E7%94%A8/</link><pubDate>Wed, 14 Feb 2024 21:00:14 +0000</pubDate><guid>https://kerolt.github.io/p/c-%E4%B8%ADlambda%E4%B8%8Epriority_queue%E4%B8%80%E8%B5%B7%E4%BD%BF%E7%94%A8/</guid><description>&lt;p&gt;想写这篇博客的原因是在刷力扣的 &lt;a href="https://leetcode.cn/problems/top-k-frequent-elements/"&gt;347. 前 K 个高频元素&lt;/a&gt; 一题时，需要使用到优先队列&lt;code&gt;priority_queue&lt;/code&gt;，其定义如下：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Container&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Compare&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;less&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typename&lt;/span&gt; &lt;span class="n"&gt;Container&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;value_type&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;priority_queue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;第三个参数是一个可以自定义的比较类型，其必须满足&lt;a href="https://zh.cppreference.com/w/cpp/named_req/BinaryPredicate"&gt;二元谓词&lt;/a&gt;，通常可以使用如下两种方法：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;使用自定义的函数对象&lt;/li&gt;
&lt;li&gt;lambda表达式&lt;/li&gt;
&lt;li&gt;使用&lt;code&gt;std::greater&lt;/code&gt;或&lt;code&gt;std::less&lt;/code&gt;（这里就不介绍这种方法了）&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>muduo网络库的安装</title><link>https://kerolt.github.io/p/muduo%E7%BD%91%E7%BB%9C%E5%BA%93%E7%9A%84%E5%AE%89%E8%A3%85/</link><pubDate>Sat, 20 Jan 2024 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/muduo%E7%BD%91%E7%BB%9C%E5%BA%93%E7%9A%84%E5%AE%89%E8%A3%85/</guid><description>&lt;h2 id="下载源码"&gt;下载源码&lt;/h2&gt;
&lt;p&gt;链接：&lt;a href="https://github.com/chenshuo/muduo/releases/tag/v2.0.2"&gt;https://github.com/chenshuo/muduo/releases/tag/v2.0.2&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Vue3封装el-upload</title><link>https://kerolt.github.io/p/vue3%E5%B0%81%E8%A3%85el-upload/</link><pubDate>Sun, 10 Dec 2023 00:00:00 +0000</pubDate><guid>https://kerolt.github.io/p/vue3%E5%B0%81%E8%A3%85el-upload/</guid><description>&lt;h2 id="前言"&gt;前言&lt;/h2&gt;
&lt;p&gt;在Vue3项目中，如果我们想上传图片一般可以利用element-ui中的&lt;code&gt;el-upload&lt;/code&gt;，为了避免代码的重复，我们可以自己封装一个图片上传组件。&lt;/p&gt;
&lt;p&gt;其中，主要实现思想为前端利用el-upload组件选择上传的图片，并利用其&lt;code&gt;http-request&lt;/code&gt;属性来自定义函数来实现文件上传请求：该请求函数使用七牛云的对象存储，在通过后端得到的上传凭证token后来实现文件上传。&lt;/p&gt;</description></item></channel></rss>