日常疑难杂症(一)
HACKs are acceptable...
前言
本文收录了一些自己遇到的日常(简单)疑难杂症及对应处理,暂时命名为 1,后续如果收录的过多会考虑出 2 等;按每 10 条一则吧。
本文收录的大多数问题可能都比较蠢,但是 debug 确实还是挺有意思的。
与 Python/深度学习相关的 HACK 被单独收录在了Python开发疑难杂症汇总,方便查阅。
【Web 开发】视口到底有多大?
描述
该问题出现在一个被设计为沉浸式单页应用的移动端页面上。旧方案下页面采用 height: 100vh; overflow: hidden; 布局,旨在完全占满屏幕并严格禁止滚动。页面内容包含由 JS 动态生成的持续下落动画元素,在设计上离开屏幕时该元素被移除。
错误现象: 在移动端浏览器中,JS 生成的动画元素溢出了屏幕,页面右侧出现了意外的滚动条。这表明 overflow: hidden 声明失效,JS 生成的动画元素被视为可滚动内容。
此外,此问题在桌面设备(Windows)上无法复现。这是因为桌面模拟器仅能调整视口尺寸,无法真实模拟移动端浏览器 UI(地址栏、工具栏)的动态显隐行为和其对大视口单位 (100vh) 的精确影响。该问题也长期被 Chromium 等官方项目视为 vh 单位定义的预期行为,而非 Bug。标准化的 svh, lvh, dvh 单位直到后来才出现,旨在解决此痛点,但在本项目中效果不佳。
处理
为根除此问题,采用了overflow: clip,来替代原有的 overflow: hidden,通过更严格的裁剪行为彻底禁止任何滚动并更有效地处理溢出内容。通过这一替换,无需依赖 dvh 等现代单位或复杂的 JS 视口高度计算,直接、并非优雅地解决了由视口单位与动态 UI 交互引发的布局溢出问题。
【域名/自定页面】由自定义域名配置引发的依赖崩溃
描述
自己有了域名,将 GitHub Pages 上的 Jekyll 博客从默认子目录迁移至独立子域名时,构建流程意外中断,导致站点无法部署。
错误现象: GitHub Actions 工作流在执行 bundle install 步骤时失败,核心错误是尝试 Gem 安装 sass-embedded (1.93.3) 时,构建原生扩展失败。
核心错误日志片段:
1
2
3
4
5
6
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
...
rake aborted!
NameError: uninitialized constant JSON::Fragment
...
An error occurred while installing sass-embedded (1.93.3), and Bundler cannot continue.
原因分析:
- 旧环境的容忍度: 在使用默认 GitHub Pages 部署或未更新依赖时,构建环境可能使用的是旧版、预编译好的 Sass 依赖,或官方支持的 Jekyll/Sass 版本,从而避免了原生扩展构建。
- 新配置的触发: 更改
_config.yml中的url/baseurl或 GitHub Pages 设置,强制触发了 GitHub Actions 重新运行完整的依赖解析和安装(即bundle install)。 - 冲突暴露: 依赖解析器拉取了最新版本的
sass-embedded(1.93.3)。该版本在尝试构建其所需的原生扩展时,其 Rakefile 代码引用了JSON::Fragment这一常量。 - 版本不兼容: 构建环境使用的 Ruby 版本为 3.1.6,在该版本的标准库中,
JSON::Fragment未定义或无法被正确加载,从而导致NameError和 Gem 安装失败。
处理
升级 GitHub Actions 中的 Ruby 版本。
定位到项目仓库中的 GitHub Actions Workflow 文件(通常是
.github/workflows/jekyll.yml)。修改设置 Ruby 版本的步骤,将其升级到已知兼容且更新的稳定版本:
1 2 3 4 5
- name: Set up Ruby uses: ruby/setup-ruby@v1 with: ruby-version: "3.3" # 将 Ruby 版本从 3.1 升级到 3.3 bundler-cache: true
在 Ruby 3.3 环境中,sass-embedded 成功安装,不再报告 JSON::Fragment 错误。站点构建和部署成功完成,article.akutazehy.xyz 恢复正常访问。
【Windows】由 Windows MPO 机制引发的浏览器画面撕裂
描述
在 Windows 11 环境下,使用 Chromium 系浏览器(Chrome / Edge)进行网页滚动或播放 1080p 视频时,出现明显的卡顿、撕裂、闪烁甚至短暂黑屏现象;问题在多任务切换、窗口化 VRR / G-Sync 场景下更易触发。
原因分析:
多平面叠加 (MPO) 是 Windows 的一项功能,旨在通过对多个显示层(例如视频、桌面和应用程序窗口)使用硬件加速合成来提升图形性能。然而,它被频繁汇报会导致一些问题,例如画面卡顿、闪烁、黑屏、GPU 驱动程序崩溃以及浏览器延迟——尤其是在 AMD 和 NVIDIA GPU 上。在某些硬件配置下(尤其是 AMD RX 5000/6000/7000 和 NVIDIA RTX 2000/3000/4000 系列),由于对叠加平面处理不当,MPO 可能会导致系统不稳定,尤其是在上下文切换或低帧率场景下。
处理
禁用 Windows 的 Multiplane Overlay,使显示管线回退到稳定的 DWM 合成模式:
在注册表路径HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Dwm中,创建一个名为OverlayTestMode的DWORD值,将其值设置为00000005并重启电脑。
系统不再使用存在缺陷的 Overlay 显示路径,浏览器帧统一经 DWM 合成并受 VSync 约束,画面撕裂与闪烁问题消失或显著缓解,显示行为恢复稳定。
【Windows/Docker】Docker 占用 C 盘
参见知乎的这一则教程,或更原始的StackOverflow的回答。
背景:
在 Windows 系统中安装 Docker Desktop 时,是无法选择安装的位置的,程序默认将 Docker 安装到了 C 盘。在使用 Docker 的过程中,我们会下载镜像文件,而一个镜像文件动辄 10 几 G,都会被放到 C 盘里存储 Docker 数据的磁盘映像文件.vhdx中。由于 vhdx 文件的特性,即使在 Docker 中删除掉不用的镜像文件,vhdx 文件也不会释放存储空间,这样电脑的 C 盘很快就会被占满。
Windows 的 Docker Desktop 基于 WSL2 来运行,所有的 image、container 数据都会被放到 WSL2 的虚拟磁盘文件(vhdx)中。而 WSL2 的 vhdx 具有“动态”特性,即当磁盘文件创建时,初始化一个最大的上限容量(默认是 1T),当里面数据增加时,vhdx 所占的空间随之增加,直到上限,但当里面的数据被移除时,vhdx 所占的空间并不会随之减小。这就是为什么即使在 Docker 中删除了镜像文件,也无法释放电脑的存储空间。
使用 mklink 策略(符号链接)解决 Docker 占用 C 盘的问题
- 退出 Docker;
- Docker Desktop 的数据文件,默认存放在
C:\Users\<Username>\AppData\Local\Docker,使用剪贴-粘贴将其转移到一个其他目录中; - 打开 cmd,执行
mklink /J "C:\Users\<Username>\AppData\Local\Docker" "<path_to_new_location>",其中mklink [[/d] | [/h] | [/j]] <link> <target>中的<link>不能已存在(即执行前不应该存在C:\Users\<Username>\AppData\Local\Docker这个文件夹); - 重启 Docker。
压缩 vhdx 文件
- 退出 Docker;
- 打开 cmd,执行
wsl --shutdown,来关闭所有正在 wsl 上运行的服务,并通过wsl -l -v来确认所有的服务已关闭。 - 用管理员模式打开命令行窗口,执行
diskpart,进入 diskpart 程序; - 在 diskpart 里面输入
DISKPART> select vdisk file=<vhdx path> - 输入
DISKPART> compact vdisk,压缩 vhdx 文件; - 输入
DISKPART> exit,退出 diskpart 程序。 - 重启 Docker。
【Windows】安装MSI文件出现”错误代码2502、2503”
描述
在 Windows 10/11 环境下,尝试通过双击运行 .msi 安装包时,安装向导刚启动便立即报错退出,提示”错误代码 2502”或”错误代码 2503”。
错误现象:
- 双击 MSI 文件后,安装界面闪退或停留在进度条初始阶段;
- 弹窗提示类似:
安装程序遇到错误,代码 2503和安装程序遇到错误,代码 2502; - 右键菜单中没有”以管理员身份运行”选项,无法通过常规方式提权;
- 问题多发生于第三方软件、企业内网插件、或老旧系统集成包的安装场景。
原因分析
- 权限继承断裂:
C:\Windows\Temp是 Windows Installer 服务执行解压、缓存、校验等操作的临时工作目录。若当前用户对该文件夹缺乏”完全控制”权限,Installer 无法写入临时文件,进而抛出 2502/2503 错误。 - UAC 与 MSI 的”历史遗留问题”:不同于
.exe安装程序,MSI 文件在资源管理器中默认不暴露”以管理员身份运行”入口,导致用户难以主动提权。 - 系统策略限制:部分企业环境或精简版系统可能通过组策略禁用了 Installer 的自动提权行为,进一步加剧了权限冲突。
注意:此处的
Temp文件夹特指C:\Windows\Temp,并非用户目录下的AppData\Local\Temp。两者路径不同、权限模型独立,切勿混淆。
处理
一些可以尝试的处理如下:
临时方案:通过任务管理器提权
Ctrl + Shift + Esc打开任务管理器;- 点击 文件 → 运行新任务;
- 勾选 “以系统管理权限创建此任务”;
- 浏览或粘贴 MSI 文件完整路径(如
C:\Downloads\plugin.msi),回车执行。
临时方案:使用管理员 CMD + msiexec 命令
- 搜索
cmd→ 右键 “以管理员身份运行”; 输入以下命令(注意空格与引号):
msiexec /package "C:\Path\To\Your\Installer.msi"小技巧:可直接将 MSI 文件拖拽进 CMD 窗口,自动填充完整路径。
- 回车后,安装程序将以完整系统权限启动。
这两种临时处理通常可以成功安装,但下次仍需类似操作,比较繁琐。
一劳永逸的修复方案:
步骤1:手动修复 C:\Windows\Temp 权限(需管理员)
- 以管理员身份打开文件资源管理器,导航至
C:\Windows\Temp; - 右键
Temp文件夹 → 属性 → 安全 → 编辑; - 选中当前登录用户(或
Users组),勾选 “完全控制” 与 “修改” 权限; - 应用并确认,重试安装。
若提示”拒绝访问”无法修改权限,可尝试先取得文件夹所有权(高级 → 所有者 → 更改为当前用户),再重复上述步骤。
步骤2:组策略永久启用”提升权限安装”
Win + R输入gpedit.msc打开本地组策略编辑器;- 依次展开:
计算机配置→管理模板→Windows 组件→Windows Installer
→ 启用 “始终以提升的权限进行安装”; - 同样路径在
用户配置下再操作一遍; gpupdate /force刷新策略,或重启生效。
家庭版 Windows 默认不包含
gpedit.msc,可考虑使用方案三作为替代,或通过脚本启用组策略组件。