#283 PEP

2018-11-22

主要是了解一下 PEP(Python Enhancement Proposal)的状态和类型。

#282 PHP 5.2 与 PHP 5.3+ 的几处差异

2018-11-22

修改一个我之前开发的一个 Discuz 插件对于 PHP 5.2 的支持(当时插件开发环境是 PHP 5.6.37),发现以下几处需要注意的地方:

#281 Web 保存数据的特殊方案

2018-11-08

将数据通过编码存在图片里面,实现导出导入功能。
虽然我不知道什么场景下需要使用这个方案,但这个想法特有意思。

#280 程序员字体

2018-11-01

纯英文:

  • Apple Monaco
  • Courier New
  • Consolas
  • DejaVu Sans Mono <>
  • JetBrains Mono
  • Source Code Pro
  • Ubuntu Mono
  • Inconsolata
  • Fira Code

中文:

  • 思源黑体(Source Han Sans)
  • YaHei Consolas Hybrid
  • Google Noto Mono

#279 Mongo 基础

2018-09-05

版本

以下是几个大版本和发布时间,作为一个大概的时间线吧:

2009/12 1.2
2010/03 1.4
2010/08 1.6 分片(支持水平拓展)
2011/03 1.8
2011/09 2.0 GridFS
2012/08 2.2 Aggregation Framework
2013/03 2.4 全文搜索
2014/04 2.6 WiredTiger 存储引擎
2015/03 3.0
2015/12 3.2 Change Streams
2016/11 3.4 多文档事务
2017/11 3.6
2018/06 4.0
2019/08 4.2
2020/07 4.4
2021/07 5.0 时间序列 + 聚簇索引(Clustered Indexing)+ 实时重分片 (Live Resharding) + 版本化 API (Versioned API)
2022/07 6.0
2023/08 7.0 可查询加密技术(Queryable Encryption)
2024/10 8.0
2025/09 8.2 功能完善与性能提升

当前最新版本 8 月发布的 4.0.2

Update @ 2021/06/07:
之后主版本号就一直停在了 4,2020 年之后甚至一直停在了 4.4(2019 年 4.2,2020 年 4.4),这也意味着功能组件稳定下来了。

#278 短信的原理

2018-09-04
  • Short Message, 短信
  • SMS, Short Message Service, 短信服务
  • MO, Mobile Originate, 发短信
  • MT, Mobile Terminate, 收短信
Terminal 终端
SMC      短信中心
SMS GW   短信网关

重要协议

编码方案

  • 7bit ASCII
  • 8bit ASCII
  • UCS2 (早期的 Unicode 方案,2 Bytes 表示一个字)

长度

受协议限制,短信内容最大 140 字节,所以:

采用 8bit 编码的话,最长 140 字符。
采用 7bit 编码的话,最长 160 字符(正好)。
采用 UCS2 编码的话,最长 70 字符。

如果涉及长短信切割,根据通行的拓展协议,需要采用头三个字节存储相关信息。

采用 8bit 编码的话,每段最长 137 字符。
采用 7bit 编码的话,每段最长 156 字符(最后剩余 4 bits 空着)。
采用 UCS2 编码的话,每段最长 67 字符。

长短信分割

参考 GSM 03.40 9.2.3.24 TP-User Data (TP-UD) 部分,一般有两种方案:

\x05        剩余协议头长度
\x00        短信标识 GSM 03.40
\x03        剩余短信标识长度
随机字节(1 字节)
总包数
包序号(1 开始)

还有一种没有怎么见过的方案,就是采用两个字节做随机标识,然后头三字节改成 \x06\x08\x04

第二字节叫做 The Information Element Identifier(信息元素标识符),上面的 \x00\x08 分别标识 1 字节,2 字节随机标识方案。其他值可以参考文档。

#277 tornado: yield

2018-08-05
from tornado import gen, ioloop

@gen.coroutine
def dosth():
    yield gen.sleep(1)
    print('slept for 1 second')

ioloop.IOLoop.current().run_sync(dosth)
from tornado import gen, ioloop

@gen.coroutine
def dosth():
    print('dosth 222222222222222222222')
    yield gen.sleep(1)
    print('slept for 1 second 22222222')
    print('dosth over 2222222222222222')

@gen.coroutine
def test():
    print('test 111111111111111')
    dosth()
    print('test over 1111111111')

print('start')
ioloop.IOLoop.current().run_sync(test)
print('over')

# start
# test 111111111111111
# dosth 222222222222222222222
# test over 1111111111
# over

# start
# test 111111111111111
# dosth 222222222222222222222
# test over 1111111111
# slept for 1 second 22222222
# dosth over 2222222222222222
# over

#276 Git 补丁包

2018-08-01
  • git diff 对应 diff 命令
  • git apply 对应 patch 命令
git diff v1.2.1 v1.2.2 > v1.2.1_v1.2.2.patch

git apply --check v1.2.1_v1.2.2.patch

git apply -v --whitespace=warn v1.2.1_v1.2.2.patch

有部分文档中说 git applypatch 在一些细节上实现不一致,需要留意。但我轻量级使用,没有遇到过什么问题。

#275 电子邮件是如何传输的?

2018-07-22

假设:

  1. A 要发一封邮件给 B、C。
  2. A 的地址是 aaa@163.com,B 的邮箱地址是 bbb@163.com,C 的邮箱地址是 ccc@qq.com

那么:

  1. A 先在自己的客户端 Thunderbird 上(WebMail 后面是怎么处理的就取决于各个邮件服务提供商了)将邮件编辑并发送出去。
  2. 邮件经过 SMTP(需要验证身份),到了网易的邮件发送服务 smtp.163.com
  3. 网易邮件发送服务检查了两个收信地址,发现:
    B 地址所在域和自己一致,就直接投给了自己的用户邮箱
    C 地址所在域和自己不一致,就检查 C 域的 MX 记录,得到 mx.qq.com,然后将邮件投递过去(SMTP)。
  4. B 通过客户端 Foxmail,从配置的 pop3.163.com 下载了邮件(POP3),手机自带的邮件客户端配的 imap.163.com,那就走 IMAP 协议。
  5. QQ 的 mx 服务器是没有身份验证的,但是会通过一系列手段验证 163 的连接是可靠的,才会接收这封邮件。
  6. QQ 收到邮件之后,将邮件投进 C 的收件箱。
  7. C 则在 Web 上浏览邮件,这时候 WebMail 通过某种技术,从 QQ 邮箱服务拉取到了邮件列表,C 就发现这封邮件,然后点开看到了 WebMail 获取到的邮件内容。
  QQ 163  
SMTP smtp.qq.com 465/587 smtp.163.com 25, 465/587
POP3 pop.qq.com 995 pop.163.com 110, 995
IMAP imap.qq.com 993 imap.163.com 143, 993

玩概念

可以看到各种 MxA:

  • MUA: user 用户代理,也就是邮件客户端
  • WebMail 或者 Foxmail、Thunderbird 这样的工具。
  • MSA: submission 发送代理
  • 比如 smtp.163.com 这样的收信服务
  • MTA: transfer 传送代理,或者说交换代理,又叫 Mail Exchanger 或 MX Host
  • 接收别的邮件服务转过来的邮件
  • 和 MSA 的区别是没有身份认证,但是有对投递者(服务器)身份信息的检验
  • Postfix 服务器
  • MDA: delivery 投递代理
  • 主要是对 MSA/MTA 收到的邮件进行过滤处理:
    • 检查和过滤垃圾邮件、病毒邮件等,
    • 然后外部地址的邮件就交换出去,
    • 内部地址的邮件就存储起来
  • MRA: retrieval,receive 接收/检索代理
  • POP,IMAP 协议
  • Dovecot 服务器

#274 在 Markdown 中使用数学公式

2018-07-21

vscode 或者 Typora 或这其他的一些编辑器都支持在 Markdown 中使用数学公式,直接预览就行了。

但是如果是自己做 Markdown 转换,生成 HTML 页面,就必须做点额外的工作。

我发现 Mathjax 挺好用的,只需加入三行:

<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
<script
  src="https://cdn.jsdelivr.net/npm/mathjax@3.0.1/es5/tex-mml-chtml.js"
  async
></script>
<script>
  MathJax = {
    tex: {
      inlineMath: [
        ["$", "$"],
        ["\\(", "\\)"],
      ],
    },
  };
</script>

Katex 据说不错,以后如果发现 Mathjax 有不足之处再试试。

Update @ 2022-05-27: 根据 May 19, 2022 的博客 Render mathematical expressions in Markdown, GitHub 开始采用 Mathjax 渲染数学公式。

关于数学公式

数学公式的语法都是参考 LaTeX(2019/07/21, LaTeX)。