分类目录归档:技术

code 1076536 640

Jest 如何将复杂的判断条件中的具体问题暴露出来?

在写测试的时候,如果你需要对大量的数据进行 compare 处理的时候,你大概率不会把所有需要对比的对象都列出来,而是选择直接循环处理。

在测试中如果有循环处理的时候,很有可能会出现的一个问题是你可能无法在测试无法通过时快速定位道具体是循环中的哪一个元素出现的问题。这个时候的定位就会比较麻烦。

一个比较好的办法是,可以在 Jest 中加入 try/catch 中来处理错误,这样可以在出现错误的时候,打印一些辅助信息来快速定位,比如

it('test-error-catch-example',() => {

   let needTestData = [1,2,3,4]

   needTestData.foreach( item => {
       let result = doSomething(item)
       // 这里开始是新增的
       try{
          expect(result).toBe(true)
       }catch(e){
          console.log("error key",item)
          throw e;
       }
       // 新增的错误处理结束
   })

})
Code language: JavaScript (javascript)

通过添加一个自定义的 try catch ,可以在出现问题的时候,一方面将 Error 按照常规的方式抛出,等待 Jest 处理,另一方面,可以在 catch 时输出自定义的信息,方便我们进行排查和修复。

453a454bb03ba4e4f74b2034b7327759

截图、修图、管理图片 - Capto 与图片管理工作流

TL;DR

Capto 牛逼,买它!购买地址直达链接

除了直接购买 Capto,你还可以以更低的费用购买 Setapp 会员,享用更多软件

正文

如果你日常会有编写操作教程,或有大量编写图文混合文章、PowerPoint的时候,你一定会有以下几个困扰:

  1. 如何截图:虽然 Windows 和 macOS 都自带了截图的功能,但因为基本是系统自带的功能,所以大部分只有「全屏幕截图」这一个功能,或者需要按下十分复杂的组合键来完成图片的截取。
  2. 如何添加标注:为了确保图片的读者能够找到正确的位置,我们往往会在图片中加入一些标注,帮助读者能够在第一时间找到重点,或帮助用户涂抹掉不需要关注的部分,仅保留核心区域的内容。
  3. 如何管理截图:图片被截取完成后,我们应该如何管理这些图片?我们应该如何管理已经标注好的图片?我们如何阻止这些截图?这些都是在管理截图的时候遇见的问题。

而如果你也遇见了这样的问题,这篇文章就是为你准备的,接下来,且听我为你介绍我的截图管理历史。

截图工具演变史

刀耕火种:系统自带截图工具时期

第一个时期,我采用的是最为笨拙的截图方式方法,在 Windows 和 macOS 系统都提供了默认的截图工具。

在 Windows 当中,只需要按下 Win + Printscreen 键,就可以将你当前的屏幕截取,并保存在系统的「图片\屏幕截图」目录中。

知乎《Windows10 自带截屏快捷键》

在 macOS 当中,只需要同时按住以下三个按键:Shift、Command 和3,就会拍摄截图。

Apple《在 Mac 上拍摄截屏》

无论是 Windows 还是 macOS ,都提供了基本的截图工具,但在实际使用的时候,你会发现,你产出的图片(如图1)大多数的时候是这样的:图片中元素极多无关主题的元素无法被隐藏、桌面背景是你自己自定义的背景等一系列小瑕疵。

fe939468620860309f23e5d6ef07ef93
图1: macOS 自带的截图产出的截图

此外,不同设备上的不同按键让我们在切换设备的时候产生迷惑(特别是你从 Windows 切换到 macOS 或反过来切换时),此外,图片的批注也十分的麻烦,必须借助一些第三方的图片编辑软件(比如画图、Adobe Photoshop)来进行图片的编辑和标注。

有没有一个工具,可以帮助我用非常简单的方式完成截图,最好能在截图的时候可以完成图片的批注?

短兵相接:聊天工具内置截图软件 / 第三方截图工具时期

随着时代的发展,截图的功能开始被更多的软件关注到,我们开始可以在聊天工具当中截图。

常见的比如使用 QQ 进行截图、使用微信进行截图、使用飞书进行截图(如图2)等。这些聊天工具所提供的更加易用但又更加强大的截图功能逐渐替代了系统自带的截图功能,此外,其提供的诸如批注、圈选、提示等功能,也让截图的批注变得更加简单。

d2b5ca33bd970f64a6301fa75ae2eb22 2
图2:飞书提供的截图功能

此外,因为这些功能是集成在聊天软件当中,所以往往会在截图完成后,自动将图片放置在你的剪贴板中,你可以直接在聊天软件当中粘贴图片,并发送给其他的人,完成协作和信息的传递。

甚至,因为这些工具做得足够好用,腾讯甚至还将截图这个功能独立出来,开发出了一个单独的截图软件 —— 截图(Jietu)

d2b5ca33bd970f64a6301fa75ae2eb22 3
图3: 截图(Jietu) 的 App Store 页面

不过,因为这个场景过于小众,商业化的空间也比较小,最终,截图还是停止了维护,如今我们在 App Store 虽然还能够下载到本地,但在实际的使用过程中,会发现相应的功能已经失效无法再使用了(测试系统为 macOS Big Sur)。

此外,在这个时代当中,也涌现出了不少非常有特色的截图 & 批注软件,比如支持截图、长截图、滚动截图、贴图、取色功能的 iShot (图4);

d2b5ca33bd970f64a6301fa75ae2eb22 4
图4: iShot 的 App Store 宣传图

比如提供了非常有优雅的分步骤说明功能和图片云托管功能的 Teampaper Snap(图5) ,也是一个不错的选择。

d2b5ca33bd970f64a6301fa75ae2eb22 6
图5: Teampaper Snap 的分步骤解说图

得益于基础设施的进步,这些专门做工具软件的开发者们也能够依赖自己开发的工具收获相应的价值回报(Teampaper Snap 年付 30 元人民币,支持从截图中使用 OCR 提取文字;),也使得开发者们有动力不断的去迭代自己的工具,让我们获得越发好用的截图和批注工具。

自然,腾讯公司推出的截图(Jietu)因为 ROI 计算起来并不划算而被暂停。同一时期还有一些其他截图软件值得大家尝试,诸如 Xnip,如果你感兴趣,也可以自己下载下来尝试一下。

这些截图和批注工具完美的解决了我们想要截图和对图片进行修改的诉求,我们可以借助他们快速的完成图片的截图和基础的修改问题。

但随着工作的复杂度提升,需要处理的图片量变大以后,一定会遇到另外一个问题:图片管理问题。你在截图对这些图片做的修改被直接写死在图片当中,导出的时候直接导出无法撤回修改的 JPG、PNG 图片,一旦使用图片的人发现图片中有一些错误,就不得不重新进行完整的截图,重新批注,时间成本极高。

这个时候,你或许会思考,有没有一款软件,既可以满足我图片截取和批注的诉求,同时,还能解决我图片管理的诉求,让我小微改动不要重头再来,节省时间?

数字化赋能:截图管理工具时期

当你有大量的截图要管理以后,你就会发现之前的截图工具还是不够用。这些工具往往集中在「工具」的视野中, 将工具这一属性做到了极致,你可以在这个工具当中完成任何你需要的截图和批注的能力,但一旦你完成了当前的工作流,你就不得不为你的所有工作打上了一个句号,后续倘若你要反悔,是断然没有可能的。

而在当下我看来,最为推荐的便是 Capto 这款软件。

和其他的截图工具相比,Capto 是一个更加具备工程化的截图和截图管理工具

首先,在概念层面,Capto 当中,图片可以分为「资源库」 — 「文件夹」 — 「图片」三个层级。每一张图片都归属于某一个资源库(图6),在资源库内你可以将图片分配在不同的文件夹中。

d2b5ca33bd970f64a6301fa75ae2eb22 11
图6:Capto的资源库文件

其次,在具体的使用层面,Capto 也提供了丰富的功能,以满足你的需求。

针对截图,Capto 提供了基本的屏幕截图、窗口截图、区域截图功能,还在截图的基础之上提供了动态的录屏功能,帮助你在 Capto 内完成你几乎所有涉及到录屏的需求,你可以直接用 Capto 完成你的截图工作,并在完成截图后,使用 Capto 提供的图片批注功能,进行图片的编辑和处理。

在 Capto 的图片批注界面(图7),你可以清晰的将界面分为截图录屏区、图片批注区、图片预览区、图片信息区和图片管理区。

d2b5ca33bd970f64a6301fa75ae2eb22 7
图7: Capto 的图片编辑界面

得益于独立资源库的设计,Capto 的图片批注功能实现了类似 Photoshop 的图层能力,你的每一个批注都是独立的一个个体,你可以随时添加 & 移除它。也正是这样的能力,赋予了用户可以多次修改一个图片的可能,你可以放心大胆的批注图片,哪怕有些许错位,后续微调即可,再也不用重新截图了。

而在 Capto 的图片管理界面(图8),你可以更加深刻的感受到 Capto 的图片管理功能,左侧提供的筛选功能,则可以让你更加快速的完成大量的图片管理功能,你可以在左侧的库快速的筛选出你需要的图片

d2b5ca33bd970f64a6301fa75ae2eb22 8
图8: Capto 的图片管理界面

也可以根据某些特定的筛选规则(图9),筛选出某些特定属性的图片,方便你在后续使用的时候快速筛选。

d2b5ca33bd970f64a6301fa75ae2eb22 9
图9:智能收藏集的筛选功能

此外, 对于不同的项目你甚至可以采用不同的资源库的方式,来切换不同的上下文,从而实现不同项目之间的隔离,更好地管理你的所有图片。

d2b5ca33bd970f64a6301fa75ae2eb22 10
图9:Capto 的库设置页面

借助于 Capto ,你可以使用其自带的截图工具,先根据需求截取出合适的图片,并在 Capto 中进行图片的批注和处理;在完成批注和处理后,你可以根据需求,将图片导出为合适的格式(图10),即可完成图片的整个处理过程。

d2b5ca33bd970f64a6301fa75ae2eb22 12
图10:Capto 的图片保存选项

基于 Capto 的截图管理工作流

当你看完了上述的内容,对于 Capto 有了基础的了解后,接下来我为你介绍我自己的截图管理工作流:

  1. 打开 Capto ,创建一个资源库:因为我只需要为自己截图,因此,无需创建不同的资源库。这里有一个注意的点:你可以将你的资源库创建在同步盘上,这样就可以在不同设备之间同步你的资源库,从而实现在不同的设备上编辑同一套资源库。比如我自己用的就是 iCloud 来同步资源库。
  2. 根据需求,创建不同的收藏集:根据实际的需求,创建不同的收藏集,用于后续的图片分类,如果你有多个项目同时进行,也可以一次性创建多个目录。这样后续就可以批量选中图片进行分类了。
  3. 创建智能筛选集:我在实际工作过程中,也不会一次性创建多个目录,因为我可能并不能很好的分类,所以早期我更多是先大量把要截取的图片进行截取,然后创建一个智能筛选集(规则见图11),将所有未分类的图片筛选出来,并进行筛选和处理。
  4. 编辑图片,并导出:完成了所有的图片的截取后,将所有的图片进行逐个地分类和修改,并导出,用在对应的文档当中。
d2b5ca33bd970f64a6301fa75ae2eb22 13
图11:智能筛选集的规则

总结

Capto 作为一个专注做截图的功能,相比于现有市场上的其他工具,提供了截图之上的管理功能,让截图这件事从一个更高的层面重新思考,让我们重新思考图片的管理能力,并用其提供的能力,简化了我们管理图片的难度释放了我们的生产力,让我们可以把更少的精力放在截图、做图上,让我们有更多的时间和精力,去关注内容本身。

除了直接购买 Capto,你还可以以更低的费用购买 Setapp 会员,享用更多软件

b29692084bbb

WordPress 的静态化缓存和动态化缓存应该如何选择?

在我发出了 为 WordPress 加入 Redis 缓存提升访问性能 的文章后,有不少朋友给了建议,主要有以下几个:

  1. 可以在前面套一层 CDN ,使用 CDN 来完成缓存。
  2. 可以配置 Nginx 缓存。
  3. 可以给文章生成静态的。

在我看来,这些都是很好的建议,对于很多新人的博客主而言,都是不错的选择。不过就我自己的需求而言,这个并不是好的选择。

从网站性能的提升而言,他们所提供的建议确实是不错的,通过对网站进行静态化处理,从而实现访问的提速,用户直接访问静态的缓存是不错的选择。

不过,对于我来说,倒也不仅仅是给读者一个更加舒服的阅读体验,对于我自己而言,更加舒适的写作体验也是极为重要的。

引入了 Redis 作为缓存后,所有的 MySQL 查询会进行一定的缓存,从而让网站的整体使用体验变得更好,对于我来说,是一个更好的选择。

0dbb4980acb58d4396e9a2055bf2176e

为 WordPress 加入 Redis 缓存优化访问性能

在之前的文章我是如何优化博客的本站在用的一些WordPress插件中我提到,我是使用了 WP-Optimize这个插件来进行博客优化的。

d2b5ca33bd970f64a6301fa75ae2eb22 11
WP Optimize

WP-Optimize 为用户提供了开箱即用的缓存方式,可以将你的 WordPress 文章加入文件缓存,从而减少在 MySQL 中查询的次数。

不过,文件缓存的问题是性能受限于你所使用的磁盘,而我使用的是阿里云的标准云磁盘,性能一般,所以访问速度并不能算快。

过去在我还愿意折腾 WordPress 的时候,我是会在 WordPress 上加入一些别的缓存的,比如 Redis、Memcached。不过,随着时间的流逝,我折腾的意愿变得越来越弱,就远离了这些。

直到最近刚好有空,于是开始研究起了 Redis 缓存。

其实在古早时代(比如我刚开始折腾个人博客的时候,2012年),WordPress 的 Redis 功能并不是特别好用,需要自己手动下载 object-cache.php 放在对应目录中,然后修改配置文件手动来开启,甚至还需要替换掉 index.php 文件来让请求通过缓存进行。

这次的折腾,让我感受到,时代在进步,配置缓存也变得简单了许多。

Requirements

在这篇博客中我并不打算介绍 Redis Server 的安装和调试过程,你可以在搜索引擎中找到各种各样的教程引导你如何完成安装的过程,因此,请自行完成 Redis Server 的安装,后续的各项操作会默认你已经完成了 Redis Server 的安装调试。

需要注意的是,如果你不打算修改配置文件,则需要在安装 Redis 之后,设置为空密码。而空密码是不安全的,建议你通过 iptables、安全组策略等方式,屏蔽掉 6379 端口的外部请求,只允许本地请求。

安装 Redis 缓存

我这次安装 Redis 缓存选择了 Redis Object Cache 这个插件。

d2b5ca33bd970f64a6301fa75ae2eb22 12
Redis Object Cache

和你在别的网站上看到的教程相比,这个插件提供了一个可视化的查看和管理的方式,对于懒得手动操作和编辑代码的人来说,更加友好。

安装插件后,启用插件,你可以在设置中的「Redis」设置页面找到如下的界面:

d2b5ca33bd970f64a6301fa75ae2eb22 13
设置页面

点击 Enable Object Cache,就会开启 Redis 的 Object Cache 。

如果你已经在之前配置好了 Redis Server,则会直接看到如下左图的界面。但如果你的 Redis Server 还没有配置或配置了密码,就会显示如下右图的界面,就需要你检查你的 Redis Server 是否配置成功。

d2b5ca33bd970f64a6301fa75ae2eb22 15
配置成功的情况
d2b5ca33bd970f64a6301fa75ae2eb22 14
配置失败的情况

当你看到如上左图的界面后,就说明你已经开启了 Redis 的 Object Cache 了,后续涉及到文章内容、菜单等各项基本配置的查询时,会优先使用 Redis 的缓存,而不是查询 MySQL,从而降低了 MySQL 的查询压力,提升了查询的诉求。

至此,你的 Redis 就配置好了,可以打开你的网站首页,享受飞一样的速度。

d2b5ca33bd970f64a6301fa75ae2eb22 17
开启前的 TTFB 为 2.29 秒
d2b5ca33bd970f64a6301fa75ae2eb22 16
开启后的 TTFB 为 673.49 毫秒

FAQ

1. 如何使用非本地 Redis Server 或如何使用带密码鉴权的 Redis Server?

如果你需要使用非本地的 Redis Server(比如云 Redis),那么你需要在你的 wp-config.php 中加入如下代码来进行配置。

define( 'WP_REDIS_HOST', '127.0.0.1' );
define( 'WP_REDIS_PORT', 6379 );
// define( 'WP_REDIS_PASSWORD', 'secret' );
define( 'WP_REDIS_TIMEOUT', 1 );
Code language: JavaScript (javascript)

2. 如果我一个服务器上有多个 Redis ,如何配置使数据不会混淆呢?

有两种方式,

第一种方式是可以给你的不同站点配置不同的 Redis DB,只需要在你的 wp-config.php 文件中加入如下的配置,即可实现不同的站点使用不同的 Redis 数据库,你可以从 0 开始,向上递增设定不同的 Redis 数据库。

define( 'WP_REDIS_DATABASE', 0 );
Code language: JavaScript (javascript)

第二种方式是你无法控制 Redis,必须使用同一个数据库,那么你可以通过给其添加不同的 salt 来实现即使使用同一个数据库,数据也不会产生混淆。

define('WP_CACHE_KEY_SALT', 'www_ixiqin_com_');
Code language: JavaScript (javascript)

3. Metrics 怎么理解?

在 Redis 设置页面,你可以看到另外有一个 Metrics Tab,这个 Tab 你可以看到你的插件的工作情况,方便你随时进行查询 & Debug。

第一个 Time 是指 Redis Object Cache 和 Redis 沟通,获取数据所需的时间,可以看到,我这里的查询时间大概是在 12ms,耗时不多。需要注意,你第一次看可能会注意到,这里有一个 Object Cache Pro ,灰色的 Object Cache Pro 其实是官方在推广其自家的付费插件,付费插件 $99/月,可以提供更好的 Redis 查询性能。

d2b5ca33bd970f64a6301fa75ae2eb22 18

第二个 Bytes 则是 Redis Object Cache 从 Redis 获取到数据的大小,当有人访问你的文章的时候,这个数据就会出现一个增长,访问结束后就会消失。

d2b5ca33bd970f64a6301fa75ae2eb22 19

第三个 Ratio 则是缓存的命中率,基本上保持在 99% + ,说明缓存的命中率还不错。

d2b5ca33bd970f64a6301fa75ae2eb22 20

最后一个 Calls 则是调用次数,免费版不会批量获取数据,因此,调用次数会很高,而在付费版,会一次性拿多个数据,从而获得更少的查询次数。不过我目前对于这个速度已经很满意了,就不再购买付费的版本了。

d2b5ca33bd970f64a6301fa75ae2eb22 21

延展阅读

b29692084bbb

WordPress 5.9 + 2022 主题,如何修改主题代码?

如果你使用了最新的 WordPress 5.9 以及其自带的 WordPress 2022 主题,你会发现有个问题:

修改主题代码去哪了?

d2b5ca33bd970f64a6301fa75ae2eb22 9

虽然提供的编辑器可以满足绝大多数需求,但对于一些特定场景下的开发需求(比如在 functions.php 中加入特定的逻辑,依然是需要修改代码的。

在当前的 5.9 版本中,主题的代码编辑器和插件的代码编辑器入口被移动到了「工具」当中,你需要到「工具」当中寻找对应的功能。

d2b5ca33bd970f64a6301fa75ae2eb22 10
b29692084bbb

对 WordPress 2012 主题的一些改动

在上一篇文章当中,我介绍了我为什么要迁移到 2012 这个主题,在这篇文章中,我将会向你介绍一下我对其做的一些修改。

加入广告信息

之前我接受了来自芦笋的广告赞助,作为权益,我答应为芦笋提供相应的广告展出,因此,我需要通过一些代码的修改,来实现对这部分内容的修改。

具体的修改方式是修改了 WordPress 2012 主题中的 content.php 这个文件,在合适的位置加入如下的代码

<!-- ads code start -->
<?php if(is_single()){ ?>
<a target="_blank" href="https://lusun.com/invite/20143" style="padding-bottom:10px"><img src="http://ixiqin.test/wp-content/uploads/2022/01/800498db4ecc3ecade82c7dfb0aaded5.png" class="wp-block-image" alt="白宦成邀请你注册芦笋,并赠送你 30 天高级版特权" style="max-width:100%"></img></a>
<?php }?>
<!-- ads code end -->
Code language: HTML, XML (xml)

文章页面的广告便是如此加上去的。

而侧边栏中的广告代码,则是通过 WordPress 自带的「小工具」功能来实现的,插入图片,并加入对应的链接即可。

首页显示摘要,而非全文

从阅读体验上来讲,在列表页面能看完所有内容自然是不错的,不过因为我的文章比较喜欢插入代码和图片,如果直接在文章页面展示所有内容,会导致页面看起来非常的混乱,所以我修改了对应的代码,将其调整为在首页展示摘要,而在内容详情页展示全文。

这里 2012 主题并未加入相对应的功能的开关,因此需要自行代码实现相应的功能。

原代码如下:

<?php if ( is_search() ) : // Only display excerpts for search. ?>
<div class="entry-summary">
	<?php the_excerpt(); ?>
</div><!-- .entry-summary -->
<?php else : ?>
<div class="entry-content">
	<?php the_content( __( 'Continue reading <span class="meta-nav">&rarr;</span>', 'twentytwelve' ) ); ?>
	<?php
	wp_link_pages(
		array(
			'before' => '<div class="page-links">' . __( 'Pages:', 'twentytwelve' ),
			'after'  => '</div>',
		)
	);
	?>
</div><!-- .entry-content -->
<?php endif; ?>
Code language: HTML, XML (xml)

新的代码如下:

<?php if (is_search()): // Only display excerpts for search.
?>
        <div class="entry-summary">
            <?php the_excerpt(); ?>
        </div><!-- .entry-summary -->
        <?php
else: ?>
        <?php if (is_single()): ?>
    <div class="entry-content">
            <?php the_content(__('Continue reading <span class="meta-nav">&rarr;</span>', 'twentytwelve')); ?>
            <?php
        wp_link_pages(array('before' => '<div class="page-links">' . __('Pages:', 'twentytwelve'), 'after' => '</div>',));
?>
        </div><!-- .entry-content -->
<?php
    else: ?>
<div class="entry-summary">
            <?php the_excerpt(); ?>
        </div><!-- .entry-summary -->
<?php
    endif; // is_single()
?>
        <?php
endif; ?>
Code language: HTML, XML (xml)

通过上述的代码实现,来控制了在首页 & 列表页面只显示摘要,而在具体的内容页面,展示全部内容。

摘要显示超过默认长度的数量

WordPress 默认的摘要长度是 55 ,而我写的内容如果只是默认的 55 ,可能看起来会比较奇怪,所以我会通过代码,将其调整为 100

function custom_excerpt_length( $length ) {
    return 100;
}
add_filter( 'excerpt_length', 'custom_excerpt_length', 999 );
Code language: PHP (php)

加入面包屑展示

加入面包屑展示,有助于读者更好的在站内进行不同的导航,因此,借助于 All in One SEO 插件自带的面包屑功能,加入了面包屑。

<div id="aioseo_breadcrumbs" style="padding: 10px 0px;">
<?php if( function_exists( 'aioseo_breadcrumbs' ) ) aioseo_breadcrumbs(); ?>
</div>
Code language: HTML, XML (xml)
person writing on white paper

项目外包可以使用的合同

作为软件工程师,不可避免会遇到需要做项目外包的时候,在这时候,一个合同可以有效的保护软件工程师的利益(当然,也会保护发包方的利益),从这个角度来看,一个好的合同是必要的

这里我提供一个科技部的合同范本,如果你要进行外包项目,那么这个工具是你不可缺少的。

6f55d09cbd449555c7bb3cd371925e7a

Tencent OS 3.1 如何安装 Docker 并开启信息隔离

我最近在将主机从阿里云迁移到我的老东家腾讯云。

由于对于 Ubuntu/Debian/CentOS 用烦了,想试点新东西,就使用了腾讯云自带的 Tencent OS Linux 3.1 来配置环境。

和标准的发行版相比,Tencent OS Linux 针对 Docker 进行了定向的优化,因此,便刚好试一试腾讯的优化。

d2b5ca33bd970f64a6301fa75ae2eb22 4
腾讯针对标准版 Docker 优化,来源

如果你想要享受对应的优化,则需要定向安装腾讯云提供的 Docker 软件,具体安装方法也很简单,执行如下两行代码即可。

yum -y install tencentos-release-docker-ce
yum -y install docker-ce

如何开启信息隔离

根据官方文档说明,只需要执行如下代码即可完成信息隔离的开启:

sysctl -w kernel.stats_isolated=1

配置腾讯云 Docker 镜像

Docker 官方镜像在海外,在国内下载的速度体验一直不佳,在这种情况下,可以考虑配置腾讯云官方的内网镜像,提升镜像下载速度。

cat << EOF > /etc/docker/daemon.json
{
    "registry-mirrors": [
        "https://mirror.ccs.tencentyun.com"
    ]
}
EOF
Code language: JavaScript (javascript)

执行完成后,再执行 systemctl restart docker 来重启 docker 即可使用镜像。

flat screen monitor

推荐两款 WordPress 插件

我的博客写了很久,但是一直以来,有两个问题是我没有处理太好的,也正是因为没有处理好,过去的我的博客往往比较朴素。但是最近我发现了两个插件,可以完美解决我的问题,也分享给你。

对象存储对接: USS Upyun

d2b5ca33bd970f64a6301fa75ae2eb22

USS Upyun 是来自于沈唁开发的又拍云存储插件,安装使用后,你的附件会在通过 WordPress 插件中上传后,自动上传至又拍云。

由于我一直以来都是使用又拍云作为图床,并配合我电脑上的 iPic 来使用,所以,配合他的插件可以让我免于使用 iPic 来上传文件,直接通过 WordPress 上传即可,大大提升了我的写作舒适度。

此外,如果你使用的其他家的云存储,也没有问题,这个作者也开发了其他几家常见云存储的插件,你可以直接使用他开发的插件来完成功能,因为是同一个人开发的,所以功能方面不会有太大的差距。

d2b5ca33bd970f64a6301fa75ae2eb22 1

插图获取:Instant Images

d2b5ca33bd970f64a6301fa75ae2eb22 2

Instant Image 是用来找插图的,当你在写文章的时候需要一张插图,就可以在选择图片的时候,直接从 Pixabay 或 Unsplash 上搜索并选择合适的图片,选中后,就会自动将图片下载到你本地让你使用(配合上面的又拍云插件,可以直接将图片存在对象存储上)。

Surface laptop on a round straw foot rest in an office with Christmas decorations in the background
随手选择了一张图

插入的界面也是融合在媒体库当中的,非常符合 WordPress 的使用体验。

d2b5ca33bd970f64a6301fa75ae2eb22 3

总结

有了这两个插件,我以后大概会在写文章的时候大量配图,因为插图不再是我的痛点,那就可以多插一些符合场景的图片,来降低读者阅读文章的压力。

Hello World text

2021 年还在写 PHP 的人

PHP 是世界上最好的语言

这是技术圈的一个梗。只要你希望一个社区吵起来,只要抛出 XX 是最好的语言,就可以吵起来。而在这个鄙视链里,最底层的就是 PHP。

为什么会是 PHP?

应运而生的 PHP

PHP 其实是一门非常辉煌的语言,关于他有多辉煌。从 WordPress 的荣耀就可以看出来。 WordPress 这样一个被广泛应用的 CMS 系统便是 PHP 写就的。就连这个博客,也同样是基于 PHP 写成的。

在 PHP 盛行的时代,我们看到了大量的个人站长出现,他们使用一些开源 or 免费提供的 PHP 项目,开发出了一个个网站。我们所熟悉的 Discuz、WordPress、Drupal 、PHPBB等一系列 CMS,都是使用 PHP 开发者的。

这些 PHP 应用程序的诞生,使得 PHP 得以长盛不衰。可以说,只要 WordPress、Discuz、Drupal、PHPBB 这一类程序还在持续迭代,PHP 本身就不会消逝。

Web 友好的 PHP

PHP 之所以被众多开源项目选择,得益于其语言设计。

在其官网的标题中,明确指出,“PHP 是一个 Hypertext Preprocessor”。

更是在官网的显著位置,标注了如下的内容。

PHP is a popular general-purpose scripting language that is especially suited to web development.

Fast, flexible and pragmatic, PHP powers everything from your blog to the most popular websites in the world.

来源: php.net 

PHP  从设计之初,便是一门用于 Web 研发的编程语言,在 Web 2.0 时代,Web 网站大爆发的时代,PHP 自然也因此而大红大火。

PHP 作为一个面向模板输出的语言,在过去的二十多年里,造就了大量的 Web 应用。

LAMP 的助攻

PHP 能流行开来,和他的易于部署也不无关系。LAMP(Linux + Apache + MySQL + PHP)的流行,使得 PHP 的部署十分的简单,一个不太懂 Linux 的人,也可以参考一些简单的教程或使用一些现成的脚本,完成项目的部署。

而更进一步催生 PHP 发扬光大的,则是 cPanel、DirectAdmin、Plesk 等一系列虚拟主机管理系统,他们将 PHP 的易用性进一步提升。用户无需管理服务器,就可以直接部署 PHP 程序,让更多的人开始使用 PHP 所编写的程序。

培训班的热潮

PHP 被广泛应用,自然也被培训班看到,随之而来的,是培训班的介入,大量的非计算机专业的人涌入,通过 PHP,开始了他们的编程之旅。

一方面,客观的增加了 PHP 的开发者,使得 PHP 的市场份额进一步扩大。

另一方面,也降低了整体水平,使得 PHP 的开发者有一部分人真的就只是搬砖。

培训班的涌入所带来的后果,就是其他语言开始鄙视 PHP,觉得 PHP 是一门垃圾语言。然鹅,没有垃圾语言,只有垃圾的用语言的人。

为什么不是 PHP

上述的众多原因,让 PHP 成为一个时代的潮流,也成为鄙视链的底层。

但真正意义上让 PHP 失去生命活力的,是单页应用、MEAN Stack 和云原生的到来。

单页应用

单页应用的到来,使得 PHP 这种以服务端渲染为主流的应用开始慢慢从人们的视野中消失。

大家开始习惯了前后端分离,由前端在浏览器层面进行渲染。

PHP 自带的模板系统就失去了其先天的优势。

MEAN Stack

MEAN(MongoDB、Express、Angular、Node.js)这种架构,彻底让人们看到了 Node.js 的可能性。

前后端统一语言的诱惑自然很难让人拒绝,大家开始选择使用 Node.js 来构建服务端。或使用 Node.js 来完成 BFF 层,这让 PHP 进一步失去其价值。

云原生

云原生的出现,让 Golang 彻底成为一门热门语言,大家开始发现 Golang 这门语言的优势。

相比于 PHP,golang 同样容易上手。此外,作为一门编译型语言,与脚本语言的 PHP 有着无法比拟的性能优势。

Golang,成为培训班的新宠。

为什么 2021 年,还在用 PHP?

我可以同时写 JS、Golang、PHP,所以对于我来说,其实语言并不是问题。

但为什么还是选择 PHP 呢?

原因很明确

  1. 我还在用 WordPress:在 WP 没有完全被替代之前,我大概率会保留一定的 PHP 维护技能(毕竟挂了要自己修)
  2. 生态还算活跃,历史的 package 能用:我一直不是很喜欢 Rails 的原因就是他的生态并不算完善(我是指和中文相关的),这意味着我们做同样的事,需要花费更多的精力。同样,这也是我为什么喜欢 Node.js 的原因。
  3. 方便快捷:PHP 生态发展的足够久,拥有大量各种不同类型的脚手架,你可以快速完成一个项目的开发,这个目前在 Node 和 Golang 之中,还是有一定差距的。

总体来说,我还会继续使用 PHP 的原因很简单,它可以帮助我快速落地项目,让我的想法变为现实。