#575 BIMI

2021-07-22

看到新闻,谷歌正式开始在 Gmail 中启用 BIMI,显示经过验证的图标。
BIMI 全名 Brand Indicators for Message Identification,可能是邮件品牌标识的意思,作用就是在邮件中显示一个图标,用来标识邮件是否是品牌邮件。
当然这个 BIMI 就需要邮件能够通过一些手段的检测,比如 SPF, DKIM, DMARC,来保证其可靠性。

#574 使用 utterances 开源评论框

2021-07-22

本站的评论框(Disqus)不知道为啥死活打不开(net::ERR_SSL_PROTOCOL_ERROR),不知道是被某种特殊力量给控制住了,还是别的什么原因。
不想折腾它了,直接切到 utterances 算了。
我本来想,反正也没有人评论,无所谓啦。但时间一长,总在心里挂念这件事,万一有个热心读者想要评论呢!

utterances 是一款依托 GitHub Issue 的开源评论框,所有评论数据都在 GitHub 上。
然后这个仓库是我的,数据当然完全掌握在自己手上,用的放心。

我写博客好些年了,评论框换过好多次,总是垮,最后换 Disque 就是图稳定,但还是不让人省心,这回换到 GitHub 上来了,应该绝对不会有问题了吧!

第一步:安装

utterances app,应该是允许它访问我的某个仓库,读写 Issue。

第二步:<script> 标签

从官网点几个选择框,然后就可以复制出来,粘贴到需要显示评论框的地方(会在那个后面插入一个 iframe)。

<script
  src="https://utteranc.es/client.js"
  repo="markjour/markjour.com"
  issue-term="pathname"
  theme="github-light"
  crossorigin="anonymous"
  async
></script>

不完美的地方:框子太窄

好在是根据最外围的 div 控制的,直接加一行:

div.utterances {
  max-width: none !important;
}

补充

wget https://utteranc.es/client.js -O static/utteranc/client.js
wget https://utteranc.es/client.js.map -O static/utteranc/client.js.map

#573 排列与组合

2021-07-22

吐槽:现在网上各种讲解,不要太贴心。
要是我读书那会儿有这么多资源,我能上清华(手动狗头)。

#572 使用 nohup 的一个小问题

2021-07-22
function fq () {
    # ...
    nohup qv2ray &>> /tmp/qv2ray.log &
    # ...
}

每次关闭终端,qv2 就一起崩溃了。

然后我改成:

nohup sh -c "qv2ray &>> /tmp/qv2ray.log &"

就好了。

分析:可能是后面日志和改后台运行的部分被 nohup 拿走的缘故吧。

#571 转载:如何将 Numpy 加速 700 倍?用 CuPy 呀

2021-07-21

作为 Python 语言的一个扩展程序库,Numpy 支持大量的维度数组与矩阵运算,为 Python 社区带来了很多帮助。借助于 Numpy,数据科学家、机器学习实践者和统计学家能够以一种简单高效的方式处理大量的矩阵数据。那么 Numpy 速度还能提升吗?本文介绍了如何利用 CuPy 库来加速 Numpy 运算速度。
就其自身来说,Numpy 的速度已经较 Python 有了很大的提升。当你发现 Python 代码运行较慢,尤其出现大量的 for-loops 循环时,通常可以将数据处理移入 Numpy 并实现其向量化最高速度处理。
但有一点,上述 Numpy 加速只是在 CPU 上实现的。由于消费级 CPU 通常只有 8 个核心或更少,所以并行处理数量以及可以实现的加速是有限的。
这就催生了新的加速工具——CuPy 库。

#570 思考:八进制的应用场景

2021-07-21

常见的进制:

  • 二进制, Binary /ˈbaɪnəri/, bin /bɪn/
    除了苏联设计过的一种计算机系统采用了平衡三进制(-1, 0, 1), 所有计算机系统都是采用的二进制, 二进制计算是程序员的一种必备技能, 其重要性不言而喻。
    常见的数字 16(四位), 256(八位), 1024(十位)等。
  • 八进制, Octal /ˈɒktl/, oct /ɒkt/
  • 十进制, Decimal /ˈdesɪm(ə)l/, dec /dek/
    十进制普遍认为是基于人类手指数量来设计的, 其深深的影响了我们的计算方式, 已经作为人类基本的数学认知。
  • 十六进制, Hexadecimal /ˌheksəˈdesɪml/, hex /heks/
    二进制计算机系统中, 一个字节定义为八位, 那么通常的选择是采用两个十六进制数来表示, 在记忆成本和便捷性方面达到一个最好的平衡。
    CPU 位数、地址总线宽度等, 通常是 4 的倍数, 比如:16 位的 8086 / 8088 有 20 位地址总线, 32 位的 386 / 486 / 奔腾 有 32 位地址总线, 64 位酷睿系列有 64 位地址总线。

那么,八进制用来干嘛?

刚才在维基百科上找到了答案:

Octal became widely used in computing when systems such as the UNIVAC 1050, PDP-8, ICL 1900 and IBM mainframes employed 6-bit, 12-bit, 24-bit or 36-bit words.

就是说早期大量机器采用了 6 位,12 位,24 位,36 位的实现,都是 3 的倍数,所以取八进制(3 位二进制数一组)来表示比较通用。

#569 Python 源码学习 04: int

2021-07-20

经过源码分析,可以得知,所有类型的定义都是通过 object.c 中的 INIT_TYPE 语句,比如 INIT_TYPE(&PyLong_Type, "int");

然后,可能是通过 SETBUILTIN("int", &PyLong_Type); 设置成内置方法。

int 类型最后就指向了一个叫做 PyLong_TypePyTypeObject 类型变量。

PyTypeObject

Objects/longobject.c

PyTypeObject PyLong_Type = {
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
    "int",                                      /* tp_name */
    offsetof(PyLongObject, ob_digit),           /* tp_basicsize */
    sizeof(digit),                              /* tp_itemsize */
    0,                                          /* tp_dealloc */
    0,                                          /* tp_vectorcall_offset */
    0,                                          /* tp_getattr */
    0,                                          /* tp_setattr */
    0,                                          /* tp_as_async */
    long_to_decimal_string,                     /* tp_repr */
    &long_as_number,                            /* tp_as_number */
    0,                                          /* tp_as_sequence */
    0,                                          /* tp_as_mapping */
    (hashfunc)long_hash,                        /* tp_hash */
    0,                                          /* tp_call */
    0,                                          /* tp_str */
    PyObject_GenericGetAttr,                    /* tp_getattro */
    0,                                          /* tp_setattro */
    0,                                          /* tp_as_buffer */
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
        Py_TPFLAGS_LONG_SUBCLASS,               /* tp_flags */
    long_doc,                                   /* tp_doc */
    0,                                          /* tp_traverse */
    0,                                          /* tp_clear */
    long_richcompare,                           /* tp_richcompare */
    0,                                          /* tp_weaklistoffset */
    0,                                          /* tp_iter */
    0,                                          /* tp_iternext */
    long_methods,                               /* tp_methods */
    0,                                          /* tp_members */
    long_getset,                                /* tp_getset */
    0,                                          /* tp_base */
    0,                                          /* tp_dict */
    0,                                          /* tp_descr_get */
    0,                                          /* tp_descr_set */
    0,                                          /* tp_dictoffset */
    0,                                          /* tp_init */
    0,                                          /* tp_alloc */
    long_new,                                   /* tp_new */
    PyObject_Del,                               /* tp_free */
};

其中所有的方法就在 PyMethodDef long_methodsPyNumberMethods long_as_number 中。
尤其是 long_as_number 可能就是那些重载操作符的基础。

long_newlong_new_impl

可能是 int 方法对应的实现。

#568 OpenStack 实验环境的快速搭建

2021-07-19

部署方式汇总

  1. 手动部署
  2. 部署脚本,也就是将手动部署的过程转化为脚本
  3. 使用自动化工具部署

而工具又有很多,比如:

  • openstack-chef shields.io
  • openstack-ansible shields.io
    简称 osa
  • puppet
  • Fuel 很早的一个解决方案,
  • Kolla shields.io
    采用 k8s 技术
  • DevStack shields.io
  • PackStack shields.io
    来自红帽的 rdo 项目,用于 OpenStack 在 RHEL 系统上的部署。

以最新的 wallaby 为例。

通过 DevStack 来弄。

就体验来说,在 devstack 的使用上,有需要改进的地方:

  1. 离线安装(提前准备好安装包和仓库)
  2. 出现异常的重试
  3. 日志还是写到文件中去的好
  4. 进度不友好

如果要开发有一定规模的相关项目,还是自己维护一组脚本,或者定制某个部署工具比较合适。

#567 我不喜欢通过视频学习

2021-07-19

最近看了腾讯课堂和开课吧的几个 IT 方面的教学课程,都是视频 + 资料分享,可能还有课后作业之类的。

最后我的感受就是,这种学习方法非常不适合我,有可能是不适合大多数人。

如果我看书,当然,应该是合适的书,效率会更高。我浏览目录就可以知道应该重点看哪里,而跳过我知道的,或者对我帮助不大的地方,而现在的视频却很难做到通过一个大纲来实现跳转。更要命的是培训方希望教学能够覆盖更多的人,往往在一些基础知识方面花费太大力气,而直播又无法跳过,简直是谋财害命。更更要命的是,经常在深入之后,对正式的专业知识的讲解,进度又拉的很快,几句话带过(可能体验课也就只能这样吧)。

我也看到有一些课程是类似抖音短视频的风格,一个短视频一个知识点,然后通过播放列表可以实现跳转,我觉得这种方式会好的多。

经过反复思考,我觉得适合我的学习方式,还是先整理出一个大纲,然后找到合适的资料,一边看资料,一边敲代码。
如果有第三方组织真的有真材实料,然后可以给我合理的建议,设计出恰当的学习计划,给我做答疑和指导,我会付费,价格合理的话。
在自学方面,往往会摸索很久才会找到一条合适的路,如果可以得到正确的引导,那么效率就会提升很多。

#566 requests 遇到的错误:Failed to parse

2021-07-15

今天使用 requests 时发现居然报错:Failed to parse: http://xxxxx

重要的是我不是直接是用 requests,而是使用另一个工具库,然后它来使用 requests 发起网络请求,所以我就完全没有想到着一层。更重要的是代码之前运行的好好的,没有任何问题。而且 requests 这样一个通用的库,谁能想到它会有问题呢?

我怀疑了好多情况,比如防火墙,代理,网络环境等等,但是没有找到原因。最后开始看工具库的源码,看到头都大了,也没有一点发现。

最后还是在 StackOverflow 上看到有人提醒,可能是 requests 下面的 urllib3 依赖里面有点什么问题,建议先升级一下看看。一试果然好了。

我没有仔细分析其具体原因,留给记录,下次遇到类似问题要小心。