作者归档:runyu

杂项

# 文件开头的 \ufeff 是字节顺序标记(BOM, Byte Order Mark),通常出现在 UTF-8 编码的文件中。BOM 是一个 Unicode 字符(U+FEFF),在某些文本编辑器或编码工具中会自动添加到文件的开头,以指示文件的编码类型。

C++

这里使用了std::prev函数,它返回给定迭代器的前一个迭代器,而不改变原始迭代器。这是C++11标准引入的方法,用于在不改变原始迭代器的情况下获取前一个迭代器。

在C++17中,条件初始化语句(”Conditionally-Scoped Init Statement”)是对if和switch语句的一种扩展,使它们可以在条件判断中包含初始化语句。这一特性增强了代码的可读性和简洁性,特别是在需要在条件判断中进行变量初始化的场景下。具体来说,这种语法允许你在if或switch语句中引入一个新的变量,该变量的作用域仅限于该语句块内。

#include <iostream>

int main() {
    if (int x = 42; x > 0) {
        std::cout << "x is positive and equals " << x << std::endl;
    } else {
        std::cout << "x is non-positive" << std::endl;
    }
    // x 的作用域在此结束
    return 0;
}
#include <iostream>

int main() {
    switch (int x = 42; x) {
        case 0:
            std::cout << "x is zero" << std::endl;
            break;
        case 42:
            std::cout << "x is 42" << std::endl;
            break;
        default:
            std::cout << "x is something else" << std::endl;
            break;
    }
    // x 的作用域在此结束
    return 0;
}

mAP50 和 mAP50-95


mAP50 和 mAP50-95 是用来评估目标检测模型(如图像中物体检测)性能的两种指标,常用在计算机视觉领域。这些指标主要用来衡量模型识别物体的准确性。下面是这两个指标的具体含义:

  1. mAP50 (mean Average Precision at 50% IOU)
    • 这是平均精确度均值(mean Average Precision,mAP)的一种形式,其中采用50%的交并比(Intersection over Union, IOU)作为阈值。
    • IOU是一个衡量预测框(模型对物体位置的预测)与真实框(物体实际位置)之间重叠程度的指标。
    • 当IOU至少为50%,即预测框和真实框至少有50%的重叠时,预测才被认为是正确的。
    • mAP50计算的是在此IOU阈值下,模型在所有类别和所有检测难度上的平均性能。
  2. mAP50-95
    • 这个指标是在多个不同的IOU阈值(通常是从50%到95%,间隔5%)下计算mAP,然后取这些mAP值的平均。
    • 它提供了一个更全面的评估,因为它不仅考虑到较容易的情况(例如50%的IOU),也考虑到更严格的情况(例如95%的IOU)。
    • 这种方法更加严格,能更好地衡量模型对物体位置精确预测的能力。

简而言之,mAP50 主要关注模型在较低准确度阈值下的表现,而 mAP50-95 则提供了一个在从较低到较高准确度阈值全范围内模型表现的综合评估。这使得mAP50-95成为一个更全面严格的性能评估指标。

Docker

docker exportdocker save这两个Docker命令都用于导出Docker容器和镜像,但它们的作用和使用场景有显著的区别。下面我将详细解释这两者之间的主要差异:

1. 导出的对象

  • docker export
  • 这个命令用于导出一个运行中的容器的文件系统。它创建一个包含容器中所有文件和文件夹的快照,但不包括容器运行时的元数据或历史。
  • 使用命令:docker export <container_id> > container.tar
  • docker save
  • 这个命令用于导出一个或多个Docker镜像,包括其所有的历史和元数据(如标签、层信息等)。
  • 使用命令:docker save -o image.tar image_name:tag

2. 输出内容

  • docker export
  • 输出是一个包含容器文件系统的tar文件。它不包括容器的元数据,如环境变量、命令历史或Dockerfile中定义的配置。
  • 结果是一个基本的文件系统快照,适用于需要文件级访问的场景。
  • docker save
  • 输出是一个tar文件,其中包含镜像的所有层、配置文件和元数据。这个文件可以用来重新创建镜像的完整记录,包括其历史和属性。
  • 这使得docker save成为在不同环境之间迁移镜像的理想选择,因为它保留了镜像构建的所有方面。

3. 使用场景

  • docker export
  • 如果你需要快速提取运行中的容器的文件系统状态,无论是为了调试还是为了快速迁移某些数据,docker export是一个很好的选择。
  • 注意,由于它不包含容器的元数据,你可能需要手动配置新容器的运行环境。
  • docker save
  • 当你需要完整地备份或迁移Docker镜像时,docker save是最合适的工具。它确保了镜像的所有层和配置都被保存下来,可以在任何安装了Docker的机器上重现。
  • 它是在团队或多环境部署中共享镜像的理想选择,因为它包含了创建镜像时所需的全部信息。

4. 还原方法

  • docker export 导出的容器可以通过docker import命令导入,但导入后只是一个镜像,不保留原容器的运行状态或配置。
  • docker save 导出的镜像可以通过docker load命令完全还原。

这些差异使得docker exportdocker save各自适用于不同的应用场景,根据需要备份的内容和目的选择使用哪一个命令。

PEP 3119 – Introducing Abstract Base Classes

PEP 3119, 标题为“引入抽象基类”,是Python增强提案的一部分,由Guido van Rossum, Talin, 和Phillip J. Eby于2007年提出。该PEP的目标是在Python中引入一种机制,允许创建抽象基类(ABCs)。这些类作为其他类的基类,定义了一组基本方法和属性,子类应当实现或继承这些方法和属性,从而遵循一个特定的接口或者继承某些实现。

主要内容和目标包括:

  • 抽象基类的引入:提供了一种标准方式来定义抽象基类。这些基类不能被实例化,只能被其他类继承。它们用来定义一个或多个抽象方法,即至少有一个方法是声明性的,而没有实现(使用@abstractmethod装饰器)。
  • 标准库的支持:PEP 3119还提议对Python标准库进行改进,以利用抽象基类。例如,通过创建诸如ContainerIterableSized等抽象基类,来为集合和其他容器提供一套统一的接口。
  • 类型检查:虽然Python是一种动态类型语言,PEP 3119通过抽象基类提供了一种机制,允许进行更严格的类型检查。这意味着开发者可以通过检查某个类是否为特定抽象基类的子类,来确认该类是否实现了必需的方法和属性。
  • 注册机制:PEP 3119引入了一种注册机制,允许将任意类标记为特定抽象基类的虚拟子类。这使得即使类没有从抽象基类继承,也可以被认为是满足接口要求的,只要它实现了必要的方法。

通过这些特性,PEP 3119旨在鼓励更加清晰和结构化的代码设计,促进接口和实现的明确分离,以及提高Python代码的可维护性和可重用性。

跨域请求

跨域请求(Cross-Origin Resource Sharing, CORS)是一种机制,它允许网页上的脚本能够向另一个与其原始来源不同的域请求资源。这种机制是由浏览器的同源策略(Same-Origin Policy)所约束的,该策略默认情况下禁止网页请求非同源的服务器资源,以保护用户免受恶意网站的攻击。

同源策略

同源策略是Web安全的基石之一,它限制了一个源中加载的文档或脚本如何与另一个源的资源进行交互。这有助于防止恶意网站读取另一个网站上的敏感数据。两个URL的协议、域名和端口号都必须相同,才被认为是同源的。

跨域请求的工作原理

当你尝试从一个源的网页上通过JavaScript发起对另一个源(域名、协议或端口号不同)的资源请求时,浏览器会自动应用同源策略,阻止这种跨域请求。为了使这些请求成功,目标资源的服务器必须通过发送适当的CORS头部来明确允许请求来源的域访问该资源。

例如,如果一个来自https://example.com的网页试图请求https://api.example.org/data的资源,那么api.example.org服务器必须在响应中包含一个Access-Control-Allow-Origin头部,指定https://example.com(或*代表任意域)可以访问该资源。

CORS请求类型

  • 简单请求(Simple Requests):使用GET、HEAD或POST方法(POST请求的Content-Type只能是application/x-www-form-urlencodedmultipart/form-datatext/plain)的请求。这些请求不会先发送预检请求。
  • 预检请求(Preflight Requests):对于那些可能对服务器数据产生副作用的HTTP请求方法(如PUT、DELETE或含有除简单请求之外的头部的POST请求),浏览器会先发送一个OPTIONS请求,询问目标资源是否愿意接受来自源应用程序的请求。

解决跨域问题

  • CORS响应头:服务器可以通过设置CORS响应头(如Access-Control-Allow-Origin)允许特定的外部域访问其资源。
  • JSONP(已过时):通过动态添加<script>标签的方式绕过同源策略限制,仅限于GET请求。
  • 代理服务器:通过在同源策略限制下的服务器上设置代理服务器转发请求到目标服务器,从而绕过浏览器的同源策略限制。

跨域请求机制是现代Web开发中非常重要的一部分,特别是在构建单页面应用(SPA)和使用各种Web API时。正确理解和应用CORS可以帮助开发者安全地实现跨域资源共享。

git note

变基的风险

呃,奇妙的变基也并非完美无缺,要用它得遵守一条准则:

如果提交存在于你的仓库之外,而别人可能基于这些提交进行开发,那么不要执行变基。

如果你遵循这条金科玉律,就不会出差错。 否则,人民群众会仇恨你,你的朋友和家人也会嘲笑你,唾弃你。

变基操作的实质是丢弃一些现有的提交,然后相应地新建一些内容一样但实际上不同的提交。 如果你已经将提交推送至某个仓库,而其他人也已经从该仓库拉取提交并进行了后续工作,此时,如果你用 git rebase 命令重新整理了提交并再次推送,你的同伴因此将不得不再次将他们手头的工作与你的提交进行整合,如果接下来你还要拉取并整合他们修改过的提交,事情就会变得一团糟。


git stash
是 Git 版本控制系统中的一个命令,用于临时保存工作目录和暂存区的改动,让你能够拥有一个干净的工作状态。这个命令在你需要切换分支处理其他任务,但当前分支的工作尚未完成到一个可以提交的状态时非常有用。使用 git stash 时,你的修改会被保存在一个未完成改动的栈中,可以在之后任何时候重新应用。

Fast-forward mergeSquash merge 都是Git中合并分支的方法,但它们在处理分支历史方面有显著的不同。

Fast-forward Merge

  • 当你的当前分支完全落后于要合并的分支时,Git可以执行快进合并(fast-forward merge)。这意味着没有在当前分支上而在其他分支上进行的提交,所以Git仅仅是将HEAD指针移到最新提交上,实际上就是“追上”了变更历史。
  • 快进合并不会创建一个新的合并提交,这使得历史记录看起来非常线性。
  • 这种类型的合并保留了项目历史的实际发展路径,但如果你想保留特定分支的历史记录,这可能不是最佳选择。

Squash Merge

  • 在执行Squash合并时,Git会将所有从分支开始以来的提交压缩成一个新的提交到目标分支上。这意味着不管有多少个提交,最终只会在目标分支上创建一个新的提交。
  • Squash合并使得历史记录更加整洁,因为它将所有的变更压缩到一个提交中,这对于保持一个干净的主分支(如master或main)历史记录非常有用。
  • 使用squash合并,原始分支的详细提交信息可能会丢失,因为所有的变更都被压缩到一个提交中。
  • Squash合并不会自动删除源分支,因此在合并后需要手动删除分支来保持分支清晰。

使用场景

  • Fast-forward Merge 更适合小规模的、频繁的更新,尤其是当你希望保留详细的分支合并历史时。
  • Squash Merge 适合在将特性分支合并回长期分支(如main或master)之前,保持历史记录的简洁。它特别适用于大型特性开发,其中包含了许多中间提交,这些提交的历史记录对于最终的代码库可能不是很重要。

选择哪种合并策略取决于你的项目需求以及你想如何管理你的Git历史记录。

Python Dict

Fredrik Lundh 曾经建议以下一组规则来重构 lambda 的使用:

  1. 写一个 lambda 函数。
  2. 写一句注释来说明这个 lambda 究竟干了什么。
  3. 研究一会这个注释,然后想出一个抓住注释本质的名字。
  4. 用这个名字,把这个 lambda 改写成 def 语句。
  5. 把注释去掉。

“超类”是指一个类的父类或基类。一个类可以从一个或多个超类继承属性和方法。继承是面向对象编程中的一个重要概念,它允许你创建一个新类,该类可以重用一个或多个已存在类的属性和方法。

在Python中,你可以使用以下方式定义一个类的超类:

class Superclass:
    # 属性和方法

class Subclass(Superclass):
    # Subclass继承了Superclass的属性和方法
    # 可以在这里添加新的属性和方法,或者覆盖父类的方法

子类化是指创建一个新的类,该类从一个或多个已存在的类中继承属性和方法。新创建的类称为子类,而被继承的类称为父类或超类。子类可以继承父类的特性,并且可以通过添加新的属性和方法来扩展或修改其行为。

在Python中,你可以使用以下语法进行子类化:

class ParentClass:
    # 父类的属性和方法

class ChildClass(ParentClass):
    # 子类继承了父类的属性和方法
    # 可以在这里添加新的属性和方法,或者覆盖父类的方法

Python 切片语法是一种便捷的方法,用于从序列(如列表、元组、字符串等)中提取部分元素。Python 的切片操作非常灵活,基本语法如下:

arduino

Copy code

序列[start:stop:step]

这里,startstopstep 分别表示切片的起始位置、终止位置和步长。下面是具体的介绍:

  1. start: 切片的开始索引,序列从这里开始提取。如果不指定,默认从序列的开始处提取。
  2. stop: 切片的结束索引,序列在这里结束提取,但不包括此索引指向的元素。如果不指定,默认提取到序列的末尾。
  3. step: 步长决定了从startstop间提取元素的间隔。如果不指定,默认步长为1,即连续提取。步长可以是负数,这时会逆向提取元素。

示例

  • 基本切片:pythonCopy codelst = [0, 1, 2, 3, 4, 5] print(lst[1:4]) # 输出: [1, 2, 3]
  • 省略开始或结束索引:pythonCopy codeprint(lst[:3]) # 输出: [0, 1, 2] print(lst[3:]) # 输出: [3, 4, 5]
  • 负数索引:pythonCopy codeprint(lst[-4:-1]) # 输出: [2, 3, 4]
  • 步长使用:pythonCopy codeprint(lst[0:5:2]) # 输出: [0, 2, 4] print(lst[::-1]) # 输出: [5, 4, 3, 2, 1, 0], 逆序列表

注意点

  • 如果startstop指定的索引超出了序列的范围,Python 会自动将其调整到序列的边界。
  • 切片操作返回一个新的序列,不影响原始序列。

切片是处理数据时非常有用的工具,能够简洁地表达复杂的序列操作。在数据处理、机器学习等领域中非常常见。

English

Thus far he wasn’t boasting about results.

but rest assured Nuitka stands out from the rest!

underlying principles 基本原则

but be aware that you may hit roadblocks along the way and will need to be comfortable debugging them.

utilities utility utils