Pelican 踩坑记

劝退忠告:不要入坑 Pelican,生态太弱

我一直用 Hexo 来的,最近又动了折腾的妄念,查到 Pelican 居然是 Python 实现的静态网站生成器,勇敢地尝试了一把。

幸亏我对 Python、jinja2 这些都还了解,自己补了一些坑,不然白费一天功夫,最后还是要换 Hexo。

框架本身基础能力都有,就发现一个小毛病:分类只能有一个,不能像 Hexo 那样嵌套。

核心问题还是生态上,具体地说,就是主题太少,且更新不活跃

https://pelicanthemes.com/ 这是 Pelican 的主题网站,显示只有 85 个构建成功的主题,还有 44 个构建失败的主题。

https://github.com/getpelican/pelican-themes 这是 Pelican 主题集合仓库,可以看到最近更新的主题也都是 2 年前了。

我硬着头皮选了一个好看的,汉化、改页脚、把评论系统改成 Valine,费了好大力气搞定了。最后发现站内搜索功能也是坏的,集成的搜索插件年久失修,建议换成官方插件,而官方插件又一堆依赖,气得我直接把搜索框给干掉了。

这绝不是个别主题的问题,随便浏览几个,就发现主题都没有中文支持,评论系统也都是只支持 Disqus。

技术人还是得学着功利一点,不能凭自己的技术喜好做选择,白花大半天功夫,结果业务丁点儿没展开。

CSAPP 读书笔记-第九章虚拟内存

9.1 物理和虚拟寻址

早期的 PC 使用物理寻址,而且诸如数字信号处理器、嵌入式微控制器以及 Cray 超级计算机这样的系统仍然使用这种寻址方式。然而,现代处理器使用的是一种称为虚拟寻址(virtual addressing)的寻址形式。

使用虚拟寻址,CPU 通过生成一个虚拟地址(Virtual Address,VA)来访问主存,这个虚拟地址在被送到内存之前先转换成适当的物理寻址。将一个虚拟地址转换为物理地址的任务叫做地址翻译(address translation)。就像异常处理一样,地址翻译需要 CPU 硬件和操作系统之间的紧密合作。CPU 芯片上叫做内存管理单元(Memory Management Unit,MMU)的专用硬件,利用存放在主存中的查询表来动态翻译虚拟地址,该表的内容有操作系统管理。

阅读更多

CSAPP 读书笔记-第八章异常控制流

8.1.2 异常的类别

1. 中断

中断是异步发生的,是来自处理器外部的 I/O 设备的信号的结果。硬件中断不是由任何一条专门的指令造成的,从这个意义上来说它是异步的。

剩下的异常类型是同步发生的,是执行当前指令的结果。我们把这类指令叫做故障指令。

2. 陷阱和系统调用

陷阱是有意的异常,是执行一条指令的结果。就像中断处理程序一样,陷阱处理程序将控制返回到下一条指令。陷阱最重要的用途是在用户程序和内核之间提供一个像过程一样的接口,叫做系统调用。

3. 故障

当故障发生时,处理器将控制转移给故障处理程序。如果处理程序能够修正这个错误情况,它就将控制返回到引起故障的指令,从而重新执行它。否则,处理程序返回到内核中的 abort 例程,abort 例程会终止引起故障的应用程序。

4. 终止

终止处理程序从不将控制返回给应用程序。

阅读更多

CSAPP 读书笔记-第七章链接

7.1 编译器驱动程序

大多数编译系统提供编译器驱动程序(compiler driver),它代表用户在需要时调用语言预处理器、编译器、汇编器和链接器。比如,要用 GNU 编译系统构造示例程序,我们就要通过在 shell 中输入下列命令来调用 GCC 驱动程序:

1
gcc -Og -o prog main.c sum.c

驱动程序首先运行 C 预处理器(cpp),它将 C 的源程序 main.c 翻译成一个 ASCII 码的中间文件 main.i

接下来,驱动程序运行 C 编译器(ccl),它将 main.i 翻译成一个 ASCII 汇编语言文件 main.s

然后,驱动程序运行汇编器(as),它将 main.s 翻译成一个可重定位目标文件(relocatable object file)main.o

最后,驱动程序运行链接器程序 ld,将 main.osum.o 以及一些必要的系统目标文件组合起来,创建一个可执行目标文件(executable object file)prog

阅读更多

CSAPP 读书笔记-第六章存储器层次结构

6.1 存储技术

6.1.1 随机访问存储器

  1. 静态 RAM

用来做高速缓存存储器。

SRAM 将每个位存储在一个双稳态的存储器单元里。非常稳定,只有两个状态,正好表达二进制,但是造价高,功耗大。

  1. 动态 RAM

用来做内存。

DRAM 将每个位存储为对一个电容的充电。

DRAM 存储器单元对干扰非常敏感。暴露在光线下会导致电容电压改变。

阅读更多

CSAPP 读书笔记-第五章优化程序性能

十几年前我看不懂、看不下去,没想到现在还是看不懂、看不下去。第五章把常见的(减少函数调用等)、不常见的(循环展开等)优化手段从指令层面做了深度剖析,授人以鱼的同时也授人以渔,写得真的是好!

但是真得是要花大力气才能理解透彻,要不断地实践加深记忆,才能牢牢掌握这些知识。无奈我一个应用(业务)码农,实在是难得有这种机会,所以只做简单的要点摘要作罢。

编写高效程序需要做到以下几点:第一,我们必须选择一组适当的算法和数据结构。第二,我们必须编写出编译器能够有效优化以转换成高效可执行代码的源代码。

5.4 消除循环的低效率

一个循环天然地带有两个反复执行的语句,所以尽量不要在这两个语句中插入耗时的表达式——函数调用等。

阅读更多

CSAPP 读书笔记-第一章计算机系统漫游

第一章是对整书后续章节内容的高度概括。全书以经典的 Hello World 程序开篇,概括了从源码到可执行文件的编译过程;然后深入硬件底层,描述了一台计算机典型的物理构成;最后,抛出抽象的概念,说明是如何通过操作系统、进程、虚拟内存、文件这些抽象概念管理底层硬件的。

1.2 程序被其他程序翻译成不同的格式

1
gcc -o hello hello.c

用此例揭示了编译的四个步骤:

  • 预处理阶段(cpp),hello.c -> hello.i
  • 编译阶段(ccl),hello.i -> hello.s
  • 汇编阶段(as),hello.s -> hello.o
  • 链接阶段(ld),printf.o + hello.o -> hello
阅读更多

我身边的这位“鑫爷”

最近几周接手了一个同事的大量代码,其中不合理的地方多到我实在不吐不快。

这位同事平日里看着兢兢业业,能说会道,常打交道的同事们都喊他一句“鑫爷”。可是我看了他的代码之后,这个“爷”字我是无论如何也是喊不出来了。

阅读更多

一种低成本视频直播(轮播)解决方案

0. 概述

影视剧的直播,有其特殊性:

  1. 直播内容是“静态的”。直播源通常是预制的视频文件,而非实时通过摄像头采集的数据。
  2. 没有主播,所以也就没有主播和观众的互动需求。所以对延时(主播和观众的时间差)要求不高,只要保证所有观众端具有差不多的播放进度即可。

所以相比摄像头开播的直播,影视剧直播的技术方案有可简化的余地:

  1. 把视频文件预先转换成目标格式,避免推流过程中的编解码(当然这里只考虑为观众提供原始码率,不需要转码的情况)。
  2. 把视频文件切割成多个时间长度为几秒钟的小视频文件,依次轮播。当新用户进入时,使其从当前序号的视频文件播放即可——同其它观众的时间差不超过此文件的时长。
阅读更多

使 Sanic 后端支持 CORS

1. 源端消除 Preflight

Preflight(预检请求)是指在跨源发出用户请求前,预先发出一个 OPTIONS 请求,查询服务端是否允许从此源站的请求。

Restful 规范是“罪魁祸首”。因为跨域 fetch 时,application/json 类型的 Content-Type 必然会触发 Preflight。

只有满足简单请求fetch,才不会触发 Preflight:

阅读更多