#741 公共库 CDN

2022-02-19

公共库 CDN,也叫静态资源库。

我想了一下,国内公共库 CDN 全面挂了可能是由于监管压力。
在国内,如果 CDN 提供的静态资源被一些恶意网站引用,会被问责。如果要全面审核使用 CDN 的网站,肯定是会增加太多的管理成本。
感觉这真是太不合理了!

如果是线上项目,不要用公共库 CDN。
小项目自己管理静态资源,大项目可以用付费的 CDN 服务。

BootCDN

https://bootcdn.cn

我之前用的最多的 CDN,但是总是挂,心累。现在开始用字节跳动 CDN 了。

字节跳动 CDN

http://cdn.bytedance.com/

CloudFlare CDN

https://cdnjs.com/

JsDelivr

https://www.jsdelivr.com/

不可用清单

百度 [不可用]

http://cdn.code.baidu.com

已经挂了。

腾讯 [不可用]

https://libs.qq.com/

打不开。

新浪 [不可用]

http://lib.sinaapp.com/

只有很少的资源。

360 [不可用]

http://libs.useso.com/

又拍云 [不可用]

http://jscdn.upai.com/

只有很少的资源。

七牛云 [不可用]

http://www.staticfile.org/

感觉很久没有维护了。一些常用库都非常老了。

参考资料与拓展阅读

#740 数据库排行

2022-02-15

https://db-engines.com/en/ranking
https://db-engines.com/en/ranking_trend

关系型 Relational

https://db-engines.com/en/ranking/relational+dbms

  1. Oracle
  2. Microsoft SQL Server
  3. IBM Db2
  4. Microsoft Azure SQL Database,应该就是 SQL Server 的云版
  5. Snowflake
  6. Microsoft Access
  7. FileMaker 类似 Access 的数据库产品

这几种大型商用数据库就不提了,除了 Access 和 SQL Server 稍微熟悉一点点之外,其他几个碰都没碰过。

开源:

  1. MySQL
  2. PostgreSQL
  3. MariaDB 排 RDBMS 第 8 名
  4. Percona Server for MySQL 排 RDBMS 第 56 名
  5. SQLite
  6. Firebird

文档型 Document

MongoDB 遥遥领先。

键值型 Key-Value

  1. Redis
  2. Memcached
  3. etcd

搜索引擎 Search Engine

排除两个商业服务 Splunk, Algolia。

  1. Elasticsearch
  2. Apache Solr
  3. Sphinx

Elasticsearch 和 Solr 都基于 Apache Lucene

列式存储 Wide Column

熟悉的 RDB 基本上都是行式存储。

Cassandra 遥遥领先, 第二是 HBase。

图 Graph

  1. Neo4j
  2. Microsoft Azure Cosmos DB

时序型 Time Series

  • InfluxDB
  • Kdb+
  • Prometheus
  • Graphite
  • TimescaleDB
  • Apache Druid
  • RRDtool
  • OpenTSDB

参考资料与拓展阅读

#739 setcap

2022-02-08

set file capabilities, 设置文件权限

setcap
usage: setcap [-q] [-v] [-n <rootid>] (-r|-|<caps>) <filename> [ ... (-r|-|<capsN>) <filenameN> ]

 Note <filename> must be a regular (non-symlink) file.

#738 Go 枚举

2022-02-07

编程语言中一般都有枚举类型。可以用来替换代码中的那些有一定范围的常量,减少幻数的使用,提升代码可读性。
有些语言的枚举支持遍历等操作,有一些语言的枚举还支持枚举值和枚举名字的映射。

Go 没有在语言层面实现枚举,只能通过定义一组变量。

比如(src/runtime/time.go):

const (
        timerNoStatus = iota
        timerWaiting
        timerRunning
        timerDeleted
        timerRemoving
        timerRemoved
        timerModifying
        timerModifiedEarlier
        timerModifiedLater
        timerMoving
)

官方代码(src/time/time.go)中有些地方会给这些变量加一个自定义类型:

// A Weekday specifies a day of the week (Sunday = 0, ...).
type Weekday int

const (
        Sunday Weekday = iota
        Monday
        Tuesday
        Wednesday
        Thursday
        Friday
        Saturday
)

参考资料与拓展阅读

#737 OpenWrt 开源路由器

2022-01-31

历史

Linksys WRT54G 系列路由器(2002 年 12 月首次发布)的操作系统是基于 Linux 内核开发。
2003 年,思科旗下的 Linksys 公司面对各方面压力,开源了 WRT54G 源代码。

PS: Linksys 是美国加州的台湾移民创建, 2003 年被思科收购, 2013 年又被 Belkin 收购。2018 年 Belkin 被台湾的富士康收购。

  • 2002 年,开发者基于 WRT54G 开发了 Alchemy 项目,成为相关领域最热门的项目。
  • 2004 年,OpenWrt 项目启动。
  • 2005 年,由于 Alchemy 开发者急于商业化,社区分叉出了 DD-WRT 项目。
    现在依然是一个积极开发中的项目:https://svn.dd-wrt.com/ GitHub
    最后一个稳定版本 24 发布于 2008 年,之后十几年高频度发布 beta 版本:
    https://download1.dd-wrt.com/dd-wrtv2/downloads/betas/
  • 2006 年,Jonathan Zarate 创建 Tomato 项目。
    之前有一个 HyperWRT 项目(2004 - 2006),维护 WRT54G 代码,并支持 Linksys WRT54GS 无线路由器。
    Tomato 项目就是在 HyperWRT 的基础之上继续开发和维护。
    比较独创的是开发了一个 Web 管理界面。
    2014 年之后就没有继续更新,但是有很多子项目,包括现在仍在开发中的 FreshTomato 和 Asuswrt。
  • 2011 年 Asuswrt 项目启动,至今还在积极开发中。
  • 2013 年,Asuswrt-merlin(梅林固件)启动。
    https://www.asuswrt-merlin.net/
    https://github.com/RMerl/asuswrt-merlin
    https://github.com/RMerl/asuswrt-merlin.ng
  • 2016 年,俄罗斯开发者 Padavan 基于华硕固件(Asuswrt)开发 rt-n56u 项目,目标是寻求对华硕路由器设备硬件的绝对控制。
    人们用开发者的名字来当做项目名字 Padavan,俗称“老毛子”。
    和梅林固件专注的是华硕高端机型(封闭的博通芯片)不同,老毛子主要针对的是华硕低端设备(联发科芯片),资源要求低。
  • 2016 年,因为内部分歧,部分核心开发者出走,新起 LEDE 项目(Linux 嵌入式开发环境)。
    两年之后,双方和解,两个项目又合并到一起,采用 LEDE 的制度,继续使用 OpenWrt 品牌。
  • PandoraBox,国内项目,基于 OpenWrt,早期叫做 DreamBox。
    已经很久没有听到相关声音了。

LibreCMC

2014 年,作为 Linux 嵌入式发行版发行。
2015 年,与 LibreWRT 项目(研究项目)合并。
2017 年,基于 LEDE 17。
2020 年,基于 OpenWrt 19。

爱快

iKuai / iKuic (海外)

北京丰台一家网络设备厂商的闭源路由器系统,有商业版和免费版。
https://www.ikuai8.com/component/download

附:List of router firmware projects

  • Linux-based
  • entirely free
    • Endian
    • Floppyfw
    • IPFire
    • LEDE
    • libreCMC
    • OpenWrt
    • VyOS
    • Zeroshell
  • partly proprietary
    • AirOS & EdgeOS
    • Alliedware Plus
    • DD-WRT
    • ExtremeXOS
    • FRITZ!Box
    • RouterOS
    • SmoothWall
    • Tomato
    • Vyatta
  • FreeBSD-based
  • entirely free
    • m0n0wall
    • pfSense
    • OPNsense:pfSense 分叉
  • partly proprietary
    • Junos OS
  • proprietary
  • Cisco IOS
  • ExtremeWare
  • NX-OS
  • TiMOS
  • VRP

参考资料与拓展阅读

#736 Go HTTP 客户端

2022-01-29

原生

之前的文章:Golang HTTP 以及 HTML/XML 解析

package main

import (
    "fmt"
    "io/ioutil"
    "net/http"
)

func main() {
    resp, err := http.Get("https://www.baidu.com")
    if err != nil {
        fmt.Println(err)
        return
    }
    defer resp.Body.Close()
    fmt.Printf("%#v\n", resp.Status)           // string, "200 OK"
    fmt.Printf("%#v\n", resp.StatusCode)       // int, 200
    fmt.Printf("%#v\n", resp.Header)           // http.Header, map[string][]string
    fmt.Printf("%#v\n", resp.Request)          // *http.Request
    fmt.Printf("%#v\n", resp.ContentLength)    // int64
    fmt.Printf("%#v\n", resp.TransferEncoding) // []string(nil)
    fmt.Printf("%#v\n", resp.Trailer)          // http.Header(nil)
    fmt.Printf("%#v\n", resp.Uncompressed)     // bool
    fmt.Printf("%#v\n", resp.TLS)              // *tls.ConnectionState
    fmt.Printf("%#v\n", resp.Body)             // *http.bodyEOFSignal => io.ReadCloser => io.Reader

    body, err := ioutil.ReadAll(resp.Body)
    fmt.Println(string(body))
}

multipart

admin@victus:~$ cd /C/Program\ Files/Go/src/mime/multipart
nosch@victus:/C/Program Files/Go/src/mime/multipart$ grep -ER 'func.+\) [A-Z]\w+' .
./formdata.go:func (r *Reader) ReadForm(maxMemory int64) (*Form, error) {
./formdata.go:func (f *Form) RemoveAll() error {
./formdata.go:func (fh *FileHeader) Open() (File, error) {
./formdata.go:func (rc sectionReadCloser) Close() error {
./formdata_test.go:func testFile(t *testing.T, fh *FileHeader, efn, econtent string) File {
./formdata_test.go:func (r *failOnReadAfterErrorReader) Read(p []byte) (n int, err error) {
./multipart.go:func (p *Part) FormName() string {
./multipart.go:func (p *Part) FileName() string {
./multipart.go:func (r *stickyErrorReader) Read(p []byte) (n int, _ error) {
./multipart.go:func (p *Part) Read(d []byte) (n int, err error) {
./multipart.go:func (pr partReader) Read(d []byte) (int, error) {
./multipart.go:func (p *Part) Close() error {
./multipart.go:func (r *Reader) NextPart() (*Part, error) {
./multipart.go:func (r *Reader) NextRawPart() (*Part, error) {
./multipart_test.go:func (mr *maliciousReader) Read(b []byte) (n int, err error) {
./multipart_test.go:func (s *slowReader) Read(p []byte) (int, error) {
./multipart_test.go:func (s *sentinelReader) Read([]byte) (int, error) {
./writer.go:func (w *Writer) Boundary() string {
./writer.go:func (w *Writer) SetBoundary(boundary string) error {
./writer.go:func (w *Writer) FormDataContentType() string {
./writer.go:func (w *Writer) CreatePart(header textproto.MIMEHeader) (io.Writer, error) {
./writer.go:func (w *Writer) CreateFormFile(fieldname, filename string) (io.Writer, error) {
./writer.go:func (w *Writer) CreateFormField(fieldname string) (io.Writer, error) {
./writer.go:func (w *Writer) WriteField(fieldname, value string) error {
./writer.go:func (w *Writer) Close() error {
./writer.go:func (p *part) Write(d []byte) (n int, err error) {

第三方库

GitHub: http client stars:>1000

  1. go-resty/resty shields.io:github/stars shields.io:github/languages/code-size shields.io:github/commit-activity/w shields.io:github/license
    Simple HTTP and REST client library for Go
  2. parnurzeal/gorequest shields.io:github/stars shields.io:github/languages/code-size shields.io:github/commit-activity/w shields.io:github/license
    GoRequest -- Simplified HTTP client ( inspired by nodejs SuperAgent )
  3. gojek/heimdall shields.io:github/stars shields.io:github/languages/code-size shields.io:github/commit-activity/w shields.io:github/license
    An enhanced HTTP client for Go
  4. imroc/req shields.io:github/stars shields.io:github/languages/code-size shields.io:github/commit-activity/w shields.io:github/license
    Simplified Golang HTTP client library with Black Magic, Less Code and More Efficiency
  5. dghubble/sling shields.io:github/stars shields.io:github/languages/code-size shields.io:github/commit-activity/w shields.io:github/license
    A Go HTTP client library for creating and sending API requests
  6. hashicorp/go-retryablehttp shields.io:github/stars shields.io:github/languages/code-size shields.io:github/commit-activity/w shields.io:github/license
    Retryable HTTP client in Go

简单的了解:

  1. resty 看起来确实不错,链式调用,清晰明了,而且有不错的调试信息。
  2. gorequest 是在原生库上做了一点简单的封装,优化调用体验。有篇中文文档可以参考:gorequest中文文档(非官方)
    需要学习一下他的设计。官方文档说是借鉴 Node.js 的 SuperAgent。
  3. sling 也挺有特色的,使 API 变得结构化,调用变得像普通的 Go 函数一样。
  4. go-retryablehttp 在原生库上加了一个自动重试机制。
  5. heimdall, req, 简单一看,还看不出来有什么特别的地方。

#735 2022 BUG

2022-01-28

前些天应该都看过微软 Exchange Server 开发者跨年改 BUG 的新闻了吧 (相关链接)。

Exchange Server 的邮件过滤器采用了 yymmddHHMM 格式的时间,存储在 long 类型字段中。
PS: 微软的 C++ Compiler 会将 long 当做 32 位 int。

32 位有符号整形能够表达的范围:[$-2^{31}$, $2^{31} - 1$],也就是 [-2147483648, 2147483647]。

到了 2022 年,就会超出范围,比如 2022-01-01 12:00:00, 会被存储为 2201011200,会超出 signed int 的表达范围。

2147483647
2201011200 # 超出

可能有一些系统采用 int 类型存储 yymmdd + 4 位数字做编号的方式,比如 2101011234。
相同的原因,到了 2022 年,就行不通了。

2147483647
2201011234 # 超出

最好的办法是改成 long long, 或者 unsigned int

PS: Linux 下的 C/C++ 编译器——GCC、CLang/LLVM 都是将 long 当做是 64 位。

参考资料与拓展阅读

#734 新东方英语词典备份

2022-01-25

听说沪江英语出于合规的考虑,APP 中下线了中小学英语词书。
我赶紧检查一下我之前的新东方英语词典的脚本, 检查一下,把没有的爬一份。主要是我今年准备全面学习一下英语,从小学阶段开始,要是到时候小学词典都弄不到就 BBQ 了。

#733 OneTab 迁移

2022-01-24

我清理了一些文件之后,发现之前安装的 Microsoft Edge Beta 打不开了。
我就重装了 Microsoft Edge。

不过问题来了,OneTab 中的 8000+ 多个收藏的页面找不回来了,以后会不会有机会看是一回事,找不到了又是一回事。总觉得不太爽。

我先用 --user-data-dir 参数,讲 Edge 的用户数据目录指向老的数据目录,还是无法启动。

经过一点点研究,我用 everything 搜索 OneTab 的 ID chphlpgkkbolifaimnlloiipkdnihall, 找到新旧版本的插件目录。

everything 截图

然后在 Local Extension Settings 下发现了 3M 的 .db 文件,文件大小符合预期。把这个目录覆盖过去试试。结果就好了。

# 旧版本的插件目录
C:\Users\Administrator\AppData\Local\Microsoft\Edge Beta\User Data\Default\Local Extension Settings\chphlpgkkbolifaimnlloiipkdnihall

# 覆盖到新版本的插件目录:
C:\Users\Administrator\AppData\Local\Microsoft\Edge\User Data\Default\Local Extension Settings\chphlpgkkbolifaimnlloiipkdnihall

#732 韦伯望远镜

2022-01-23

img

韦伯望远镜,全名詹姆斯·韦伯太空望远镜,以主持阿波罗计划的 NASA 前局长名字命名,立项于 1996 年,原计划 2007 年发布。
在经过 n 次延期之后,于 2021 年 12 月 25 日——也就是圣诞节那天——发射成功。

现在应该早就到了目标位置——第二拉格朗日点(L2), 然后正在调试各种设备。

img

相关知识点

  1. 至少 344 个单点故障,系统可靠性有待考验
  2. 距离地球非常远,维修和更换零部件的成本可能是无法接受的
  3. 特点是红外波段的探测能力 (哈勃计划主要是可见光波段的探测)
  4. NIRCam 近红外相机
  5. NIRSpec 近红外光谱仪
  6. MIRI 中红外成像-光谱仪
  7. FGS/NIRISS 精细制导传感器、近红外成像仪、无缝隙光谱仪
  8. 一面对准太阳,然后中间隔一层网球场大小的遮阳伞,避免受到光照影响
  9. 口径为 6.5 米 (哈勃的 5 倍不止)

img

附: 中国巡天望远镜

和哈勃望远镜口径接近,成像技术也差不多,不过类型不同。

哈勃擅长拍特写,而我们的巡天望远镜更擅长拍全景(视场是哈勃的 300 倍,所以叫巡天望远镜嘛)。

预计发射时间

2024 年

参考资料与拓展阅读