0%

主题是 Hugo-theme-next,有一些修改。虽然支持夜间模式,但是不太会调色,有一些自定义的样式在夜间模式下效果不好。所有颜色都是保证在日间模式下易读而选择的,如果夜间模式难以阅读可以切换回来。因为动画速率太慢,调快也觉得晃眼,就关掉了。

  • 2025.10.3 验证需要用 Release v0.143.1 · gohugoio/hugo 来渲染。已验证到 v0.146.x 开始不可用,v150.0 可用。参考 New template system in Hugo v0.146.0
  • 2025.10.4 通过将一些模板中的 partials/ 前缀去除,兼容 v0.146.x,但是 achives/ 无法显示列表了。魔改了旧主题还没适配,目前暂时使用 hugo v0.143.1,不做调整。

✨ 一些改动

  1. 改变了左侧 TOC 的行距,使得多行标题能够更容易被区分开。
  2. 增加了 GitHub 风格警告支持。以前使用脚本支持,现在使用钩子重写。
  3. 为 Compiler Explorer 链接启用代码预览,把鼠标悬停在链接上就能看到代码文本。
  4. Markdown 相对路径链接(其他文章或图片)。以前使用 404.html 支持,现在使用钩子重写。新增 Obsidian 风格的 [| width] 宽度标记支持。
  5. 按照顶级元素数量来摘取文章在首页的总结。

💥 Hugo 写作的坑

YAML Front Matter 的类别要使用 categories 而不是 category,而且类型一定要是字符串的列表,而不是单个字符串(不然有些 html 模板不能正确处理)。

文本高亮(==文本== 渲染成 <mark>文本</mark>

这是 2024 年 5 月更新的功能,升级 Hugo-extended 到 0.126.0 以上的版本并修改配置即可。

揭秘linux系统启动流程,面试官问起来再也不怕了-阿里云开发者社区

BIOS -> MBR -> Boot Loader (e.g. GRUB) -> kernel -> mount initramfs as / -> /init
                 /             \                    /                         |
UEFI -> GPT ----+               +----> initramfs --+                          |
                                       (memory)                               V
                                                                1 load drivers
                                         run /sbin/init   <---  2 mount root
                                                                3 switch root
  1. 运行 BIOS(现代系统是 UEFI)。
  2. 进行开机自检(POST,即 Power-On Self-Test)。
  3. 寻找启动设备,依次检查存储设备,如果前 512 字节最后两个字节是 0x55 和 0xaa,那么这个块就是 MBR(主引导记录,Master Boot Record),这个存储设备就含有操作系统。然后根据 MBR 的信息找到 Boot Loader 位置,将其加载并运行。如果是 UEFI,UEFI 固件会读取磁盘上的 GPT (GUID Partition Table)。GPT 中有一个特殊的 EFI 系统分区 (ESP, EFI System Partition),通常格式化为 FAT32。UEFI 固件会直接在该分区中查找并执行引导加载程序文件(通常是 .efi 文件,例如 \EFI\ubuntu\grubx64.efi 或 \EFI\BOOT\BOOTX64.EFI)。它不依赖 MBR 的 0x55AA 签名来启动。
  4. Linux 常见的 Boot Loader 是 GRUB。Boot Loader 能理解文件系统,能显示操作系统选择菜单和加载 Linux 内核。
  5. GRUB 加载 (load) 内核 (vmlinuz-…) 和 initrd/initramfs 文件 到内存。加载完成后,GRUB 将执行控制权转交给已加载到内存中的内核然后,内核会找到内存中的 initrd/initramfs 镜像,并将其解压(如果是压缩格式,如 gzip, xz),然后将其挂载为一个 临时的根文件系统 (rootfs)
  6. 内核执行位于 initramfs 根目录下的 /init 程序 (通常是一个脚本或小程序,如 dracut 或 mkinitcpio 生成的),这个程序会加载必要的驱动模块,找到真正的根设备(可能是 /dev/sda2,或者 /dev/nvme0n1p3 等),将真正的根设备挂到临时路径如 /sysroot 上,然后切换根目录并释放 initramfs 的内存。
  7. 现在根目录已经切换好了,运行 /sbin/init 成为系统的第一个进程。内核引导阶段结束,用户空间初始化开始。

阶段

  • 静态编辑
  • 动态加载
  • 延迟绑定

一、静态编辑

链接器(ld)在生成可执行文件时,会记录可执行文件所依赖的共享库的名称以及需要的符号,并将这些信息存储在特定的段中(例如 .dynamic 段)。同时,它会创建 PLT(Procedure Linkage Table,过程链接表)和 GOT(Global Offset Table,全局偏移表)作为占位符,用于后续的动态链接过程。GOT 表初始时包含的是用于延迟绑定的地址,而非实际的函数地址。

二、动态加载

加载可执行文件时,从其 .interp 字段找到解释器(也就是 loader,一般是 /lib64/ld-linux-x86-64.so.2,可以用 ldd <prog> 或者 readelf -l <prog> | grep "interp" 来检查)。让解释器来加载它。

动态链接器会从 搜索路径(例如 LD_LIBRARY_PATH 环境变量、/etc/ld.so.conf 配置的路径、默认系统路径 /lib, /usr/lib 等)搜索可执行文件所依赖的共享库,并将这些库映射到进程的虚拟地址空间中。在开启了 -fPIC 编译的情况下,动态链接器会解析全局变量和函数的地址,并将解析后的地址填充到 GOT 表中。如果程序编译时使用了 -fno-plt 选项,则所有函数调用都将直接通过 GOT 表进行,而不再依赖 PLT。在这种情况下,所有函数的 GOT 表项在加载时都会被解析并填充实际地址。

如果没有开启 -fPIC 编译,则动态链接器在加载进程时会直接修改 .text 段中的地址,导致 .text 变得私有而不在系统范围内共享。

LaTeX hyperref CJK 中文短语链接可点击范围只有其高度的一半。但凡其中加入了非 CJK 字符,可点击范围就会恢复正常。用 \vphantom 没有效果,大概是因为不会真正改变 baseline。有一种方法是强制 CJK 字符和其他字符的基线对齐,但是我觉得对齐之后肯定不好看。

我想到真正去渲染一个白色字符(可以改成透明颜色),然后再用 \hspace 减去其长度。最后结果勉强能看,缺点是复制的时候会多出来一个字符(用来打印和阅读的话问题不大)。

% https://tex.stackexchange.com/a/412555/
\newcommand{\nhphantom}[1]{\sbox0{#1}\hspace{-\the\wd0}}

\newcommand{\overlay}[1]{{#1}\nhphantom{#1}}
% \Url 命令是模板原先就有的命令,现在加上了一个 \overlay 来保证对中文的支持
\NewDocumentCommand{\Url}{mm}
{
  \href{#1}{
    {
        \CJKunderline{#2}
        \overlay{\textcolor{white}{.}}
    }
  }
}

2025 年 3 月 5 日:今天投递简历发现很多网站会从 PDF 中抽取文字,这导致抽出来的文字多了一个 .,所以还是尽可能在链接显示文本中包含拉丁字符作为权宜之计 😂。

其实是在问哪些类型有 hash 函数和重载了 < 比较操作符。因为说的是 STL,所以不考虑内建类型。

可哈希和 == 比较

常见的可以哈希和 == 比较的集合类型有(以下省略 std 命名空间):

  • string / string_view
  • bitset
  • unique_ptr / shared_ptr

这样的标准库模板类其实非常少!通常,可以用于 hash 和相等的类型都能用于 < 比较

注意 map 和 set 通常不可哈希!包括:

--remerge-diff 选项在 git loggit show 命令中都存在。它用更容易阅读的方式显示一个合并结点相对于两个 parent 的变化。

下图是一个例子(来源在这里)。没用这个选项的时候会显示三路的差异,有三种颜色。只看绿色部分就是最终解决了冲突后的代码,但是看红色还得看红色是来自哪一个 parent,不够方便。

用了这个选项之后修改被整合在了不同的代码段中,只使用一栏标志(就不用再从左边去寻找代码来自哪个 parent,只需要看它属于哪一个代码块)。将红色的部分视为注释,只看正常颜色的字体,就可以得知冲突解决后的结果是:

继承 std::enable_shared_from_this 模板类之后就多了一个弱指针(_M_weak_this)。同时还多了一个 __enable_shared_from_this_base 方法,创建共享指针时该方法能被 ADL 找到,以关联和共享控制块。该方法是私有的,不过 __shared_ptr<typename, typename> 是友元类,因此能访问它。

共享指针模板类 __shared_ptr 有个私有方法 _M_enable_shared_from_this_with,它能通过 SFINAE 判断元素类型是否是继承自 enable_shared_from_this 的 CRTP 类,如果是则将自己的控制块关联给 enable_shared_from_this 中的弱指针。

按照这个逻辑,在创建共享指针的时候,_M_enable_shared_from_this_with 应该会被调用。这一点确实可以被验证(下面还有一些构造函数,就不展示了):

问题

发现是 mmc.exe 不工作了,“.msc 文件打开方式”的系统注册项是正常的。

sfc/dism/chkdsk 三件套,无果

sfc.exe /scannow
DISM.exe /Online /Cleanup-image /scanhealth
DISM.exe /Online /Cleanup-image /checkhealth
DISM.exe /Online /Cleanup-image /restorehealth

确实是显示发现了问题并修复,但是结果还是打不开。

chkdsk /f /r

如题,买的是 Nuphy Air75 V2 越橘轴,感觉按久了之后有几颗轴松松垮垮的,和其他轴体的紧致感是完全不一样的,而且有问题的轴体在小键上面还能听到剐蹭的声音。可惜包装里面送的是四种轴体各一个,而不是同一种轴体 4 个,不能方便替换(包装里面有一个越橘轴我已经拿来替换过了)。

我敲 ctrl 可能是要比其他按键稍微重一点,我的另一把键盘 ctrl 轴体没问题,定位板下陷了。但总不能因为我按 ctrl 键稍微重一点就导致轴体出问题吧,轴体本来从设计上就是要承受按压的。

2025 年 1 月 18 日补充:发现 I 字母对应的轴回弹慢一拍,有点像油导致的粘滞,又有点像回弹的时候剐蹭的摩擦力太大,难受了。