作者归档:runyu

Bash

在 Bash 中,快捷键可以显著提高命令行操作的效率。以下是一些常用的 Bash 快捷键:

光标移动

  • Ctrl + A: 移动到行首。
  • Ctrl + E: 移动到行尾。
  • Alt + B: 向后移动一个单词。
  • Alt + F: 向前移动一个单词。
  • Ctrl + B: 向后移动一个字符。
  • Ctrl + F: 向前移动一个字符。

编辑命令

  • Ctrl + W: 删除光标前的一个单词。
  • Alt + D: 删除光标后的一个单词。
  • Ctrl + U: 删除光标前的所有内容(从光标到行首)。
  • Ctrl + K: 删除光标后的所有内容(从光标到行尾)。
  • Ctrl + T: 交换光标前的两个字符。
  • Alt + T: 交换光标前的两个单词。
  • Ctrl + Y: 粘贴之前删除的内容。

历史命令

  • Ctrl + P: 上一条命令(等同于向上箭头)。
  • Ctrl + N: 下一条命令(等同于向下箭头)。
  • Ctrl + R: 反向搜索历史命令。
  • Ctrl + G: 退出历史搜索模式。

进程控制

  • Ctrl + C: 终止当前进程。
  • Ctrl + Z: 暂停当前进程(可以使用 fg 恢复)。
  • Ctrl + L: 清屏(等同于 clear 命令)。
  • Ctrl + D: 退出当前 Shell(等同于 exit 命令)。

其他

  • Ctrl + S: 暂停屏幕输出(可以使用 Ctrl + Q 恢复)。
  • Ctrl + Q: 恢复屏幕输出。
  • Ctrl + X + E: 使用默认编辑器编辑当前命令。

补全

  • Tab: 自动补全命令或文件名。
  • Alt + .: 插入上一个命令的最后一个参数。

这些快捷键可以帮助你更高效地使用 Bash,减少重复操作和提高工作效率。

Terminal

在终端中,如果你想清空已经输入但尚未执行的命令或内容,可以使用以下几种方法:


1. 使用 Ctrl + C

  • 按下 Ctrl + C 会中断当前输入的命令,并清空当前行。
  • 如果光标在命令行的任意位置,按下 Ctrl + C 会将整行内容清空,并返回到新的提示符。

2. 使用 Ctrl + U

  • 按下 Ctrl + U 会清空从光标位置到行首的内容。
  • 如果光标在行尾,则会清空整行。

3. 使用 Ctrl + W

  • 按下 Ctrl + W 会删除从光标位置到前一个空格或单词分隔符的内容。
  • 可以多次按 Ctrl + W 逐步删除前面的单词。

4. 使用 Esc + Backspace(或 Alt + Backspace

  • 按下 Esc 后按 Backspace(或直接按 Alt + Backspace)会删除光标前面的一个单词。

5. 使用 Ctrl + L

  • 按下 Ctrl + L 会清空整个终端屏幕,但不会删除已经输入的命令。
  • 如果你想清屏并保留当前输入的命令,可以使用这个方法。

6. 使用 Ctrl + ACtrl + K

  • 按下 Ctrl + A 将光标移动到行首。
  • 然后按下 Ctrl + K 删除从光标位置到行尾的内容。
  • 这样可以将整行内容清空。

7. 使用 reset 命令

  • 如果你已经执行了命令,但终端显示混乱,可以输入 reset 命令来重置终端状态。
  • 注意:reset 会清空整个终端屏幕和缓冲区。

总结

  • 清空当前行:Ctrl + UCtrl + C
  • 清空屏幕:Ctrl + L
  • 删除单词:Ctrl + WAlt + Backspace
  • 重置终端:reset

自动驾驶

自动驾驶的决策方面涉及多个关键领域和技术,以下是一些速成知识:

  1. 感知(Perception)
    • 自动驾驶汽车依靠传感器(如摄像头、雷达、激光雷达)收集环境信息。
    • 感知系统识别周围的物体(行人、车辆、交通标志等)和环境特征。
  2. 定位(Localization)
    • 通过GPS和高精度地图,车辆确定自身在环境中的位置。
    • 需要与感知数据结合,以提高精度。
  3. 预测(Prediction)
    • 预测其他道路使用者(如行人和车辆)的未来行为。
    • 使用机器学习模型分析历史数据和实时信息进行动态预测。
  4. 规划(Planning)
    • 生成安全的行驶路径,包括选择车道、转弯、避让障碍物等。
    • 规划过程通常分为全局规划(长远目标)和局部规划(短期决策)。
  5. 控制(Control)
    • 根据规划的路径,自动驾驶系统控制车辆的加速、刹车和转向。
    • 需要快速反应以适应实时变化的环境。
  6. 决策框架
    • 常用的决策模型包括基于规则的系统、马尔可夫决策过程(MDP)和强化学习。
    • 决策的复杂性体现在多目标优化和不确定性管理上。
  7. 安全与伦理
    • 自动驾驶必须考虑伦理决策,如在紧急情况下如何选择行动。
    • 安全性和可靠性是设计决策系统的重要因素。

这些要素共同构成了自动驾驶汽车的决策能力,确保它们在复杂环境中安全、有效地导航。

杂项

# 文件开头的 \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历史记录。