Hexo插件:移除图片默认 alt 属性
Hexo 生成图片时,若未手动设置 alt,默认使用文件名作为替代文本,可能导致无意义内容。若希望彻底移除所有 <img> 标签的 alt 属性,在主题或者根目录的scripts/remove-img-alt.js里加入以下代码, 1hexo.extend.filter.register('after_render:html', function (str) { return str.replace(/<img(.*?)alt=".*?"(.*?)>/g, '<img$1$2>'); }); 此代码在 HTML 渲染后移除所有 alt。 注意:这会一并删除手动添加的有意义 alt,请按需使用。 scripts这个文件夹需要自己创建,Hexo 的规则是: 只要在 Hexo 根目录或主题目录(和 _config.yml 同一层级)下有 scripts/ 目录,里面放的 .js 文件会在生成站点时自动执行。
Hexo移除图片默认 alt 属性
Hexo 生成图片时,若未手动设置 alt,默认使用文件名作为替代文本,可能导致无意义内容。若希望彻底移除所有 <img> 标签的 alt 属性,在主题或者根目录的scripts/remove-img-alt.js里加入以下代码, 1hexo.extend.filter.register('after_render:html', function (str) { return str.replace(/<img(.*?)alt=".*?"(.*?)>/g, '<img$1$2>'); }); 此代码在 HTML 渲染后移除所有 alt。 注意:这会一并删除手动添加的有意义 alt,请按需使用。 scripts这个文件夹需要自己创建,Hexo 的规则是: 只要在 Hexo 根目录或主题目录(和 _config.yml 同一层级)下有 scripts/ 目录,里面放的 .js 文件会在生成站点时自动执行。
jsDelivr 缓存刷新与版本控制
目前 jsDelivr 是一个免费,开源的加速 CDN 公共服务,可以使用 jsDelivr 来做 CDN 加速。 如果更新了版本,通过jsDelivr的链接是无法马上看到的。jsDelivr 的缓存更新时间是 24 小时。 强制刷新如果你需要刷新cdn内容,可通过以下两种方式手动清除缓存: 直接访问刷新链接 在原链接域名前加上 purge. 前缀。 例如原链接: https://cdn.jsdelivr.net/gh/user/repo/file.css 刷新链接: https://purge.jsdelivr.net/gh/user/repo/file.css 使用官方刷新工具 访问 Purge jsDelivr CDN cache,在页面中输入需要刷新的 URL 并提交。 强制刷新后,由于全球边缘节点同步需要时间,部分节点可能仍未更新,因此刷新后立即访问原链接仍有可能看到旧内容。等待y一段时间后再试通常可解决。 推荐方案:使用版本号控制为彻底避免缓存问题,最可靠的方法是在链接中加入版本号(或 commit hash、标签)。 1https://cdn.j...
从零到一键发布:Obsidian + Hexo + GitHub Pages 个人博客搭建指南
前言我一直使用 Obsidian 管理笔记,它很好地满足了我的写作需求。但我始终渴望拥有一个属于自己的博客——一方面希望将积累的知识分享出去,获得反馈;另一方面,通过维护博客倒逼自己持续写作和总结,提升表达能力。 本文将完整记录我搭建博客的过程,并重点解决从 Obsidian 写作到博客发布的自动化流程。如果你也想打造一个“赛博小窝”,希望我的经验能给你带来一些参考。 搭建方案我的博客基于以下工具组合实现: 写作端: Obsidian,笔记的写作组织工具。 同步插件:Enveloppe:将本地文章同步到GitHub的Obsidian插件。 博客框架: Hexo:博客站点使用的框架。 主题:hexo-theme-matery:简洁美观的响应式主题。 托管平台:GitHub Pages:免费静态网页托管。 由于我不希望公开所有文章的源文件,我创建了两个 GitHub 仓库: 私有仓库 hexo-project – 存放 Hexo 博客配置、主题和文章源文件。 公共仓库 <用户名>.github.io – 存放 Hexo 生成的静态文件,供 GitHub Pages...
解耦复杂业务:基于责任链与上下文的重构实战
起因在版本迭代的过程中发现,订单计算的方法过于复杂,在新增或者修改功能时往往需要通篇将方法通读一遍甚至多遍,不能迅速找到应该修改的地方进行功能的改造,通过分析发现存在以下的缺陷(姑且称之为缺陷) 没有进行逻辑划分,代码行数太长 没有进行有效的封装抽象,虽然将部分代码封装成函数,但是函数放在一个类中,又造成了订单服务这个类变成了大泥球的类 业务逻辑不统一,比如签名校验的逻辑散落在方法的各个地方 业务语义性不强,各种get set遍布,无法体现出业务的含义 重构过程 过程分解对于复杂度较高的代码,无论是进行代码的重构还是在此基础上进行功能的迭代,对于过程的分解是必不可少的。通过通篇阅读代码,整个订单计算的逻辑可以分解为几部分组成 得到上面分解后的逻辑,那么想到的自然是分而治之,根据分解的逻辑将功能抽象到一个方法中,然后在订单计算的方法中进行依次调用即可。这样做虽然能够将订单计算的逻辑整理的相对容易阅读,但是所有的业务代码全都写在订单业务的一个类中,造成类的膨胀,让订单业务类变成一个大泥球的类,影响这个类的可阅读性,而且也不能做到逻辑代码的整体复用。 那么我们就需要将这些业务逻辑...
单元测试的困境与破局:为何我们不愿写,以及如何高效地写
单元测试作为软件质量的重要一环,往往在整个开发流程中被大多数开发人员所忽略,本文旨在分析如何写好单元测试并探索一些测试驱动开发的应用。 单元测试原则在写单元测试前,先要明确什么是单元测试,单元测试的原则是什么?明确这些问题前不妨先参考一下前人总结的单元测试First原则。 在工作过程中经常见到一些无效的单测,通常是启动Spring容器、连接数据库、调用方法,最后控制台输出结果,这种并不能称之为有效的单测。 12345678910111213@RunWith(SpringRunner.class)@SpringBootTestpublic class HelloServiceTest { @Autowired private UserService userService; @Test public void addUserTest() { AddUserRequest addUserRequest = new AddUserRequest("zhangsan", "1886589985...
告别分类焦虑:让笔记自然生长流动
起点:被分类束缚的笔记时光在学生时代,我养成了体系化学习的习惯,这种习惯延伸到笔记管理上,就表现为严格的分类存储——每次创建笔记时,首先思考的是“这个文件应该放在哪个文件夹”。这种基于文件夹分类的组织方式,在整理时确实直观清晰,让我能够快速定位到需要的资料。 困境:当分类遇到复杂知识然而,随着接触的知识领域越来越广,我逐渐发现一个棘手的问题:现实世界中的知识往往是多维交叉的,一份笔记很难被简单地归入单一分类。 遇到的挑战: 同一份笔记既属于A类别,也属于B类别 记录灵感闪念时,难以立即找到合适的分类 创建笔记前的分类思考成了额外的心智负担 知识之间的关联被文件夹结构人为割裂 尝试:标签系统的希望与失望为了解决多分类问题,我开始尝试使用标签系统。理论上,标签能够为笔记提供多维度的分类方式,打破文件夹的线性束缚。 实践结果: ✅ 确实解决了笔记的多分类问题 ❌ 标签数量失控增长 ❌ 部分标签下只有1-2个文件,失去分类意义 ❌ 大量标签反而增加了管理复杂度 ❌ 最终还是陷入了“如何打标签”的新一轮思考负担 标签系统在理论上很美好,但在实践中,我发现自己陷入了...
进制转换与数据编码
进制转换R进制转十进制R进制转十进制使用按权展开法,具体操作是将R进制的每一位数值使用$R^K$的形式表示,K表示该位与小数点的距离,当该位位于小数点左边,K表示该位和小数点之间间隔数字的个数,当该位位于小数点右侧,K是负数,其绝对值是该位与小数点之间数字个数加1 例如:二进制 转 十进制 $$ 10100.01 = 1 \cdot 2^4 + 1 \cdot 2^2 + 1 \cdot 2^{-2} $$七进制 转 十进制 $$ 604.01 = 6\cdot7^2+4\cdot7^0+1\cdot7^{-2} $$ 十进制转R进制十进制转R进制使用短除法例如将94转换成二进制数 123456794 ÷ 2 = 47 余 047 ÷ 2 = 23 余 123 ÷ 2 = 11 余 111 ÷ 2 = 5 余 15 ÷ 2 = 2 余 12 ÷ 2 = 1 余 01 ÷ 2 = 0 余 1 将余数从后往前书写就是对应的二进制 1011110 二进制转八进制二进制的 111 表示 八进制的 7,000表示八进制的0,二进制转换成八进制时,将二...
高并发基石:IO多路复用深度剖析
用户空间-内核空间我们通常将操作系统内核和应用程序运行的空间分为内核空间和用户空间,这是为了提供保护和控制。下面将详细解释这两个概念,并给出它们之间的区别和交互方式。 用户空间(User Space):这是应用程序运行的空间。它只能访问受限的资源,不能直接访问硬件设备等敏感资源。如果应用程序需要执行特权操作(如读写磁盘、发送网络数据包等),它必须通过系统调用(System Call)请求内核代为执行。 内核空间(Kernel Space):这是操作系统内核运行的空间,具有最高的特权级别,可以访问所有硬件资源和内存。内核负责管理进程调度、内存管理、设备驱动、系统安全等。 为什么要有这样的分离? 稳定性与安全性:如果应用程序可以直接访问硬件和内核数据,那么一个应用程序的错误可能导致整个系统崩溃。通过分离,即使应用程序崩溃,也不会影响内核和其他应用程序。 多任务与资源管理:内核可以公平地分配资源给多个应用程序,并防止应用程序之间相互干扰。 虚拟内存:每个进程都有自己的虚拟地址空间,其中一部分映射到内核空间,一部分映射到用户空间。这样,每个进程都认为它独占了整个内存,而实际上...
避免这些编程陷阱:七种让你代码失控的开发风格
散弹枪编程火力覆盖,蒙中就行 “嗯,这个报错……把参数从 false 改成 true 试试?还不行?那把这行注释掉看看?” 开发者使用非常随意的方式对待代码,像持散弹枪般,不加分析地向问题盲目射击,通过随机、反复地修改代码来碰运气,直到错误消失。这是一种极其消极的调试方式,往往在解决一个表面问题的同时,制造了多个隐藏更深的 Bug。 代码被破坏,逻辑变得不可预测,且无人理解为何这样改能“工作”。 撞大运编程迷糊前进,侥幸过关 “这段代码为啥能跑通?我也不太确定,但先别动它!” 比散弹枪编程更温和,但也更常见。程序员对模块的内在逻辑一知半解,依靠直觉和偶然的成功编写代码。一旦出现问题,会面临关键抉择:一是停下来,理解一下程序,找到出错的原因,二是使用散弹枪编程方式开始解决问题。 项目充满了“神秘代码”,后人不敢轻易触碰,形成知识黑洞。 Cargo-Cult 编程Cargo Cults 这个词儿来自二战期间的某些太平洋上小岛里的土著人。在战争期间,美国利用这些小岛作为太平洋战场上的补给站。他们在这些小岛上修建自己的飞机跑道以用来运输战争物资。而那些小岛上的土著人从来没有见过飞机,当他...
如何做好技术面试?
在公司承担技术面试的职责,刚开始的时候可能会感到困惑,不知道如何去面试别人,这里总结了一些技术面试的经验,以及一些在面试过程中的一些思考 技术面试应该要问些什么?技术面试通常是对于候选人的技术能力的评估和相关知识进行评估的面试环节,在技术面试中,面试官通常要评估候选人在以下方面的职责: 技术基础知识和基础:面试官应该要问技术相关职位相关领域的技术知识问题,以验证其对基本概念、原理和技术的了解程度 编程能力:面试官要一定程度上考察候选人的编码能力,包括熟练掌握相应的编程语言、数据结构和算法相应的知识,以及解决问题和实现功能的能力 技术经验:面试官应该要结合候选人简历,沟通项目和工作中涉及的技术栈、开发流程、工具和框架等方面的知识,以评估其实际应用能力和项目经验 系统设计能力:面试官应该要考察候选人在系统设计和架构方面的能力,包括对系统组件、模块化、拓展性、可靠性和安全性等方面的理解和实践 问题解决和沟通能力:面试官有时也应该根据候选人的沟通情况,提出一些实际问题或场景,评估候选人解决问题的能力、思维方式和沟通表达能力 自我学习和技术热情:面试官应该要和候选人沟通学习的知识或者...
Obsidian打造个人知识库
之前都是使用Typora编辑笔记和文档,Markdown写笔记或者文档简直不要太方便,熟练语法后,双手可以不离开键盘,目光始终聚焦再文字上面,写作体验非常流畅。 随着文档的增多,发现文档越来越不好管理,尝试语雀、印象笔记、腾讯文档、飞书文档等软件,功能虽然很多但是总感觉和自己不太搭,而且软件商业化的原因开始绑架免费用户,虽然能够理解但还是很不爽。尝试了Obsidian觉得眼前一亮,颜值是第一吸引力,可以自由搭配的插件以及主题可以解决我的需求。 数据同步身为一名资深的白嫖党,果断拒绝了Obsidian自带的同步功能,可以使用GitHub进行替代,无限容量,私人仓库也是完全免费,用来管理笔记文档简直是降维打击。总的来说就是建立一个git仓库,把笔记都丢进去,将一些文件和目录都忽略掉,然后使用Obsidian打开这个git仓库作为Obsidian的仓库使用。由于Obsidian使用过程中有些自带的文件一直变化,直接忽略掉。 由于国内网络的问题,我使用的是阿里云效的代码仓库进行托管 .gitignore 文件内容 123456789101112## obsidian的工作区配置.ob...







