#50 Windows 11

2021-10-15

https://www.microsoft.com/zh-cn/windows/windows-11-specifications

主要的变化

  1. 新的 UI 设计
    根据网上流传的图片,还挺好看的,令人耳目一心
  2. 支持 Android App

其他:

  1. 新的应用商城
  2. 整合了微软的 Teams 作聊天功能
  3. 游戏相关的功能
  4. DirectX 12 Ultimate
  5. DirectStorage
  6. Auto HDR
  7. XBox 相关整合

硬件要求

CPU (1GHz,双核),内存 (4G),磁盘 (64G)

  1. CPU: 1GHz,双核
  2. 内存: 4G
  3. 磁盘: 64G
  4. UEFI 安全启动
  5. TPM 2.0
  6. 显卡:支持 DirectX 12, WDDM 2.0 驱动

CPU, 内存, 磁盘方面的要求,主流的配置应该都能满足。
UEFI 安全启动

检测工具

MS 官方工具只能给出一个是否的答复,太弱了(正在开发新的监测工具)。

社区有提供一个检测工具:WhyNotWin11.exe (GitHub 下载)

第一次检测:

WhyNotWin11 Result Before

  1. 引导方式:Legacy
  2. CPU 兼容性:不支持
  3. 硬盘分区形式:分区形式不是 GPT
  4. 安全启动:禁用或未检测到
  5. TPM 版本:不存在 TPM 模块或 BIOS 禁用

除了 CPU 之外,其他几项都可以在 BIOS 中设置。
TPM:如果是 Intel 就找一下 Platform Trust Technology, AMD 可能是 fTPM。

WhyNotWin11 Result After

我的 CPU 是六代 i5,这就真的没办法了,i5 的话,最低要求是八代 (完整的 CPU 要求清单:Windows 11 supported Intel processors

抛弃才发布六年(2015/09)的六代 CPU 绝壁是一个愚蠢的决定,希望微软耗子喂汁!

Tiny11(2023-02-07)

根据微信公众号高效程序员文章《Win11 极限精简版发布:2G内存就能流畅运行!》中的信息,有人基于 Windows 11 Pro 22H2 打造了 Tiny11,不需要 TPM 和安全启动。

#49 DedeCMS 开始割韭菜了

2021-09-29

织梦官网放出上面这张公告:除了 “个人非盈利” 网站,其他没有拿到正式授权的织梦网站需要交 5800 授权费。

他们可能已经把清单列好了,律师团队也准备好了,正磨刀霍霍向着小站长们。

这可能就是中国特色开源协议的正确使用方式。

PS: 虽然我觉得 织梦CMS 是个垃圾,但我也不知道为啥,据说很多小站都是用的这个系统。

#48 URI

2021-09-24

URI 与 URL

                    hierarchical part
        ┌───────────────────┴─────────────────────┐
                    authority               path
        ┌───────────────┴───────────────┐┌───┴────┐
  abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
  └┬┘   └───────┬───────┘ └────┬────┘ └┬┘           └─────────┬─────────┘ └──┬──┘
scheme  user information     host     port                  query         fragment

  urn:example:mammal:monotreme:echidna
  └┬┘ └──────────────┬───────────────┘
scheme              path

URI

URI (统一资源标识符),标识一个资源主要有两种方法,根据名称(URN),根据路径(URL)。

URI 语法:

URL Syntax

有一个问题就是注册的 URI scheme 基本上都可以认为是用于资源定位,所以 URI 和 URL 的概念就比较模糊了。

有的 scheme,比如说 data:<mediatype>[;base64],<data>,既不算 URL,也不算 URI。
有的 scheme,比如说 sms:<phone number>?<action>,我觉得是属于名称标识,但是不符合 URN 的定义(必须 urn:)。

而且实际上,就比如说 URL http://example.com/user/create,我们用来创建一个用户,如果套用万维网创建时的学院派设想,我们只能把创建这个动作理解成一个资源了。所以,我认为深入讨论这几个 “统一资源” 的概念之间到底存在什么差异没有什么意义,大致知道他们的渊源就够了:先随着 WWW 出来了 URL 的概念,然后又有人整出来一个 URN,再后来统一为 URI 标准,这几个概念本来就是混乱的,这就是现实生活,泾渭分明的概念只存在于那些教授们的理想中。
如果感兴趣可以参考 RFC 3305,这是一个 Infomational RFC,就是试图解释这几个概念,并向社区作出使用建议。

URL

URL (统一资源定位符) = 协议://认证信息@主机名:端口号/路径?查询字符串#片段

协议必须是在 IANA 注册的合法 URI scheme。

我们最熟悉的是 HTTP URL,协议是 http 或者 https,除此之外还有其他的 IANA 批准的协议,比如:

  • mailto:<address>[?<header1>=<value1>[&<header2>=<value2>]]
  • imap://[<user>[;AUTH=<type>]@]<host>[:<port>]/<command>
  • git://github.com/user/project-name.git
  • file://[host]/path or file:[//host]/path
  • view-source:<absolute-URI>

URN

URN (统一资源名称) is 资源名称(唯一标识),格式:urn:<NID>:<NSS>

  1. urn 就是 IANA 注册的众多 URI scheme 之一。
  2. 这个命名空间标识 NID 也需要在 IANA 注册。

  3. urn:isbn:0451450523

  4. urn:ietf:rfc:2648

实际上,我好像没有见过什么地方在使用 URN,更别提设想中的统一资源属性 URC 了。

就好比上面提到的两个例子,ISBN: 0451450523,RFC 2648,直接这么写就是了,按照 RFC 定义写成标准的那一串实在是没见过。

总结

URL 是 URI 中的因特网部分,用来指示网络资源位置。

Python 示例

import urllib.parse

a = urllib.parse.urlunparse('http', 'user:pass@example.com:8080', '/path', 'param1=a', 'a=1&b=2', 'Title')
# 'http://user:pass@example.com:8080/path;param1=a?a=1&b=2#Title'

b = urllib.parse.urlparse(a)
b.scheme    # 0 'http'
b.netloc    # 1 'user:pass@example.com:8080'
b.path      # 2 '/path'
b.params    # 3 'param1=a'
b.query     # 4 'a=1&b=2'
b.fragment  # 5 'Title'
b.username  #   'user'
b.password  #   'pass'
b.hostname  #   'example.com'
b.port      #   8080

print(b[2]) # '/path'

b = urllib.parse.urlparse(('pymysql+mysql://root:111111@1.1.1.1:3306/xiaorui_master?charset=utf8mb4'))
print(repr((b.scheme, b.netloc, b.path, b.params, b.query, b.fragment, b.username, b.password, b.hostname, b.port)))
('pymysql+mysql', 'root:111111@1.1.1.1:3306', '/xiaorui_master', '', 'charset=utf8mb4', '', 'root', '111111', '1.1.1.1', 3306)

参考资料与拓展阅读

#47 GitHub 上那些徽章是怎么弄出来的?

2021-09-19

比如:Tornado 框架的 stars 数量:,再比如说这种:

外国人真是会玩,总有这样的好点子,在有限的环境(Markdown)中也能弄的丰富多彩的。

上面都是用的 shields.io 提供的服务,它内置了很多种类的图标,GitHub 关注数、Fork 数、Star 数、协议,Twitter 关注数、NPM 包大小、PyPI 下载数量等等,这些看他们官网提供的示例,照着用就是了。

还有一种,就是用户定制接口,格式:

  1. Static:URLPath https://img.shields.io/badge/<LABEL>-<MESSAGE>-<COLOR>
  2. Static:QueryString https://img.shields.io/static/v1?label=<LABEL>&message=<MESSAGE>&color=<COLOR>
  3. Endpoint https://img.shields.io/endpoint?url=<URL>&style<STYLE>
  4. Dynamic https://img.shields.io/badge/dynamic/json?url=<URL>&label=<LABEL>&query=<$.DATA.SUBDATA>&color=<COLOR>&prefix=<PREFIX>&suffix=<SUFFIX>

还有好多更加细致的规则,用来定制自己的图标,就不细说了,自己看文档就行。

其实我用的多的还是上面的第一种接口,因为它比较简单,只要把 label 和 message 修改就可以了。

https://img.shields.io/badge/site-markjour.com-brightgreen.svg?style=plastic&logo=nginx

https://img.shields.io/badge/-doing-green

参考资料与拓展阅读

#45 不简单的绝对值

2021-09-17

这篇文章讲到了绝对值计算的问题:One does not simply calculate the absolute value

IEEE 754

三个特殊值:

  1. 如果指数是0并且尾数的小数部分是0,这个数 ±0(和符号位相关)
  2. 如果指数 = 2^e - 1 并且尾数的小数部分是 0,这个数是 ±∞(同样和符号位相关)
  3. 如果指数 = 2^e - 1 并且尾数的小数部分非 0,这个数表示为非数(NaN)。

abs 的实现

class Test {
    public static double abs(double value) {
        if (value < 0) {
            return -value;
        }
        return value;
    }
    public static void main(String[] args) {
        double x = -0.0;
        if (1 / abs(x) < 0) {
            System.out.println("oops");
        }
    }
}

if 中加上条件:value == -0.0 是行不通的,因为 +0.0 == -0.0,可以使用 JDK 中的 Double.compare:

public static double abs(double value) {
    if (value < 0 || Double.compare(value, -0.0) == 0) {
        return -value;
    }
    return value;
}

这样确实有效,不过效率上可能会受到影响,abs 的复杂性就上了一个台阶。

JDK 17 中的实现

java/lang/Double.java

public static int compare(double d1, double d2) {
    if (d1 < d2)
        return -1;           // Neither val is NaN, thisVal is smaller
    if (d1 > d2)
        return 1;            // Neither val is NaN, thisVal is larger

    // Cannot use doubleToRawLongBits because of possibility of NaNs.
    long thisBits    = Double.doubleToLongBits(d1);
    long anotherBits = Double.doubleToLongBits(d2);

    return (thisBits == anotherBits ?  0 : // Values are equal
            (thisBits < anotherBits ? -1 : // (-0.0, 0.0) or (!NaN, NaN)
             1));                          // (0.0, -0.0) or (NaN, !NaN)
}

重新实现

参考 JDK 中的实现,重写 abs

private static final long MINUS_ZERO_LONG_BITS = Double.doubleToLongBits(-0.0);
public static double abs(double value) {
    if (value < 0 || Double.doubleToLongBits(value) == MINUS_ZERO_LONG_BITS) {
        return -value;
    }
    return value;
}

新的问题:NaN 的处理,处理方法:把 doubleToLongBits 改成 doubleToRawLongBits

private static final long MINUS_ZERO_LONG_BITS = Double.doubleToRawLongBits(-0.0);
public static double abs(double value) {
    if (value < 0 || Double.doubleToRawLongBits(value) == MINUS_ZERO_LONG_BITS) {
        return -value;
    }
    return value;
}

JVM 的 JIT 会替换这次调用为底层的 CPU 寄存器操作,效率非常可观。

PS:如果可以省去这个分支的判断逻辑,JVM 可以给我们更好的性能优化?

  1. 中间涉及 CPU 分支预测(branch predictor),如果预测错误,可能会付出相对昂贵的代码。

    We know that branches are bad. If the CPU branch predictor guesses incorrectly, they can be very expensive.

  2. 有传言说,这个调用(doubleToRawLongBits)会导致浮点数寄存器转换到通用集成器。

    Although there are rumors saying that this call may still lead to a transfer from a floating-point register to a general-purpose register. Still it's very fast.

进一步优化

采用 0 减负数等于正数,并且 0 - -0 = 0 的规则:

public static double abs(double value) {
    if (value <= 0) {
        return 0.0 - value;
    }
    return value;
}

这就是长期以来(直到最新的 Java 17),JDK 使用的方法(return (a <= 0.0D) ? 0.0D - a : a;)。

参考:JDK 17 中的的实现:java/lang/Math.java

再进一步

有人提出了意见,认为目前官方的实现 too slow(6506405: Math.abs(float) is slow #4711)。

这就是 jdk-18+6 中引入的新方案(java/lang/Math.java#L1600~L1604):

public static double abs(double a) {
    return Double.longBitsToDouble(Double.doubleToRawLongBits(a) & DoubleConsts.MAG_BIT_MASK);
}

DoubleConsts.MAG_BIT_MASK 就是 0x7fffffffffffffffL, 0 + 63 个 1。

原理就是,通过位运算,清除符号位(使之为 0)。

参考资料与拓展阅读

#44 GitHub 上的一些备选方案

2021-09-13

内容管理系统 / CMS

cms stars:>10000 在 GitHub 上搜索,再经过一些筛选,剩下以下项目:

  1. hugo shields.io, 静态网站生成
  2. wagtail shields.io, Django
  3. grav shields.io
  4. django-cms shields.io
  5. netlify-cms, NodeJS, MIT 静态网站生成,Git-based
  6. Keystone shields.io, NodeJS
  7. Strapi shields.io, NodeJS, headless CMS
  8. Ghost shields.io, NodeJS
  9. October shields.io, PHP, Laravel

论坛 / BBS / Forum

forum stars:>2000 在 GitHub 上搜索,再经过一些筛选,剩下以下项目:

比较知名的项目:NodeBB,Flarum,phpBB,

  1. answerdev/answer Go shields.io:github/stars shields.io:github/languages/code-size shields.io:github/commit-activity/w shields.io:github/license
    An open-source knowledge-based community software. You can use it quickly to build Q&A community for your products, customers, teams, and more.
  2. NodeBB/NodeBB Node.js shields.io:github/stars shields.io:github/languages/code-size shields.io:github/commit-activity/w shields.io:github/license
    Node.js based forum software built for the modern web
  3. flarum/flarum PHP Symfony shields.io:github/stars shields.io:github/languages/code-size shields.io:github/commit-activity/w shields.io:github/license
    Simple forum software for building great communities.
  4. phpbb/phpbb PHP shields.io:github/stars shields.io:github/languages/code-size shields.io:github/commit-activity/w shields.io:github/license
    phpBB Development: phpBB is a popular open-source bulletin board written in PHP. This repository also contains the history of version 2.
  5. flaskbb/flaskbb Python Flask shields.io:github/stars shields.io:github/languages/code-size shields.io:github/commit-activity/w
    A classic Forum Software in Python using Flask.
  6. rafalp/Misago Python Django DRF shields.io:github/stars shields.io:github/languages/code-size shields.io:github/commit-activity/w shields.io:github/license
    Misago is fully featured modern forum application that is fast, scalable and responsive.
  7. discourse/discourse Ruby On Rails shields.io:github/stars shields.io:github/languages/code-size shields.io:github/commit-activity/w shields.io:github/license
    A platform for community discussion. Free, open, simple.

SNS / MicroBlogging

  1. rocboss/paopao-ce Go shields.io:github/stars shields.io:github/languages/code-size shields.io:github/commit-activity/w shields.io:github/license
    🔥A artistic "twitter like" community built on gin+zinc+vue+ts 清新文艺微社区
  2. humhub PHP shields.io:github/stars shields.io:github/languages/code-size shields.io:github/commit-activity/w AGPL 3.0
    HumHub is an Open Source Enterprise Social Network. Easy to install, intuitive to use and extendable with countless freely available modules.

框架 / Web Framwork / RESTful API (Python)

  • Django shields.io
  • django-rest-framework shields.io
  • Flask shields.io
  • Sanic shields.io
  • Falcon shields.io
  • FastAPI shields.io
  • APIStar shields.io
  • Pyramid shields.io
  • Tornado shields.io
  • Twisted shields.io
  • daphne shields.io - A HTTP, HTTP2 and WebSocket protocol server for ASGI and ASGI-HTTP.
  • uvicorn shields.io - A lightning-fast ASGI server implementation, using uvloop and httptools.
  • bjoern shields.io - Asynchronous, very fast and written in C.
  • gunicorn shields.io - Pre-forked, ported from Ruby's Unicorn project.
  • uWSGI shields.io - A project aims at developing a full stack for building hosting services, written in C.
  • waitress shields.io - Multi-threaded, powers Pyramid.
  • werkzeug shields.io - A WSGI utility library for Python that powers Flask and can easily be embedded into your own projects.
  • uvloop shields.io - Ultra fast asyncio event loop.

数据校验 / Data Validation

  • Cerberus shields.io - A lightweight and extensible data validation library.
  • colander shields.io - Validating and deserializing data obtained via XML, JSON, an HTML form post.
  • jsonschema shields.io - An implementation of JSON Schema for Python.
  • schema shields.io - A library for validating Python data structures.
  • Schematics shields.io - Data Structure Validation.
  • valideer shields.io - Lightweight extensible data validation and adaptation library.
  • voluptuous shields.io - A Python data validation library.

#42 UMIDIGI 与 GPL 协议

2021-09-01

最近发生的一件事情挺有意思的,在得到 “上门自取” 的回复之后,有位美女替外国程序员依照 GPL 协议上门向国内的一家厂商索要内核代码。

深圳公司 UMIDIGI 生产安卓手机(联发科 Mediatek),面向海外用户。

波兰开发者 Patrycja (@ptrcnull) 想将移植 postmarketOS (基于 Alphine Linux) 到 UMIDIGI 的一款设备上,结果发现缺少 ft8719_dsi_fhdplus 屏幕驱动。

Patrycja 尝试联系 UMIDIGI,得到了以下回复:

Twitter

就是说,如果你要的话,你可以上门来取。我们可以认为这是想让 Patrycja 知难而退。

可是 Patrycja 八月 17 号在 Twitter 上抱怨之后,深圳科技博主 Naomi Wu 机械妖姬(@RealSexyCyborg,混 Youtube)主动提供帮忙,表示愿意代替 Patrycja 上门索取源代码。

然后机械妖姬 08/20 就拿着自拍杆勇闯 UMIDIGI 公司。
UMIDIGI 行政人员表示需要之前发邮件的 BEN 已经离职(我觉得很可能就坐在旁边看美女),然后提供源代码的事情需要先向老板请示,之后在相对友好的氛围下,机械妖姬离开了。

机械妖姬前往 UMIDIGI 公司

随后:

  • 08/25 UMIDIGI 向机械妖姬提供了相关文件。
  • 08/26 Patrcja 完成了系统移植,并向机械妖姬和 UMIDIGI 表示感谢。

这件事件我的评价是:

UMIDIGI 之前的邮件回复十分愚蠢,直接向法务部门咨询之后,通过合法的途径(可能涉及联发科的知识产权)将代码提供给他不就好了吗?
不过,如果不是事情闹大了,UMIDIGI 会不会提供源代码呢?这就不知道了,我们也不能以恶意揣度之。只能就事论事,在这次事件中,各方的表现都非常好。

#41 vCard (.vcf)

2021-09-01

VCF 是 Virtual Contact File 的简写,虚拟通讯录文件
PS:.vcf 后缀还有一个含义是 Variant Call Format,用在基因生物学方面。