hexo-start
摘要内容……
摘要内容……
经常刷 LeetCode 的读者肯定知道鼎鼎有名的 twoSum 问题,我们的旧文 Two Sum 问题的核心思想 对 twoSum 的几个变种做了解析。
但是除了 twoSum 问题,LeetCode 上面还有 3Sum,4Sum 问题,我估计以后出个 5Sum,6Sum 也不是不可能。
那么,对于这种问题有没有什么好办法用套路解决呢?本文就由浅入深,层层推进,用一个函数来解决所有 nSum 类型的问题。
[leetcode1](1. 两数之和 - 力扣(LeetCode) (leetcode-cn.com))
力扣上的 twoSum 问题,题目要求返回的是索引,这里我来编一道 twoSum 题目,不要返回索引,返回元素的值:
如果假设输入一个数组 nums 和一个目标和 target,请你返回 nums 中能够凑出 target 的两个元素的值,比如输入 nums = [5,3,1,6], target = 9,那么算法返回两个元素 [3,6]。可以假设只有且仅有一对儿元素可以凑出 target。
我们可以先对 nums 排序,然后利用前文「双指针技巧汇总」写过的左右双指针技巧,从两端相向而行就行了:
1 | vector<int> twoSum(vector<int>& nums, int target) { |
这样就可以解决这个问题,不过我们要继续魔改题目,把这个题目变得更泛化,更困难一点:
nums 中可能有多对儿元素之和都等于 target,请你的算法返回所有和为 target 的元素对儿,其中不能出现重复。
函数签名如下:
1 | vector<vector<int>> twoSumTarget(vector<int>& nums, int target); |
比如说输入为 nums = [1,3,1,2,2,3], target = 4,那么算法返回的结果就是:[[1,3],[2,2]]。
对于修改后的问题,关键难点是现在可能有多个和为 target 的数对儿,还不能重复,比如上述例子中 [1,3] 和 [3,1] 就算重复,只能算一次。
首先,基本思路肯定还是排序加双指针:
1 | vector<vector<int>> twoSumTarget(vector<int>& nums, int target { |
但是,这样实现会造成重复的结果,比如说 nums = [1,1,1,2,2,3,3], target = 4,得到的结果中 [1,3] 肯定会重复。
出问题的地方在于 sum == target 条件的 if 分支,当给 res 加入一次结果后,lo 和 hi 不应该改变 1 的同时,还应该跳过所有重复的元素:

1 | while (lo < hi) { |
这样就可以保证一个答案只被添加一次,重复的结果都会被跳过,可以得到正确的答案。不过,受这个思路的启发,其实前两个 if 分支也是可以做一点效率优化,跳过相同的元素:
1 | vector<vector<int>> twoSumTarget(vector<int>& nums, int target) { |
这样,一个通用化的 twoSum 函数就写出来了,请确保你理解了该算法的逻辑,我们后面解决 3Sum 和 4Sum 的时候会复用这个函数。
这个函数的时间复杂度非常容易看出来,双指针操作的部分虽然有那么多 while 循环,但是时间复杂度还是 O(N),而排序的时间复杂度是 O(NlogN),所以这个函数的时间复杂度是 O(NlogN)。
这是力扣第 15 题「三数之和」:

题目就是让我们找 nums 中和为 0 的三个元素,返回所有可能的三元组(triple),函数签名如下:
1 | vector<vector<int>> threeSum(vector<int>& nums); |
这样,我们再泛化一下题目,不要光和为 0 的三元组了,计算和为 target 的三元组吧,同上面的 twoSum 一样,也不允许重复的结果:
1 | vector<vector<int>> threeSum(vector<int>& nums) { |
这个问题怎么解决呢?很简单,穷举呗。现在我们想找和为 target 的三个数字,那么对于第一个数字,可能是什么?nums 中的每一个元素 nums[i] 都有可能!
那么,确定了第一个数字之后,剩下的两个数字可以是什么呢?其实就是和为 target - nums[i] 的两个数字呗,那不就是 twoSum 函数解决的问题么🤔
可以直接写代码了,需要把 twoSum 函数稍作修改即可复用:
1 | /* 从 nums[start] 开始,计算有序数组 |
需要注意的是,类似 twoSum,3Sum 的结果也可能重复,比如输入是 nums = [1,1,1,2,3], target = 6,结果就会重复。
关键点在于,不能让第一个数重复,至于后面的两个数,我们复用的 twoSum 函数会保证它们不重复。所以代码中必须用一个 while 循环来保证 3Sum 中第一个元素不重复。
至此,3Sum 问题就解决了,时间复杂度不难算,排序的复杂度为 O(NlogN),twoSumTarget 函数中的双指针操作为 O(N),threeSumTarget 函数在 for 循环中调用 twoSumTarget 所以总的时间复杂度就是 O(NlogN + N^2) = O(N^2)。
这是力扣第 18 题「四数之和」:

函数签名如下:
1 | vector<vector<int>> fourSum(vector<int>& nums, int target); |
都到这份上了,4Sum 完全就可以用相同的思路:穷举第一个数字,然后调用 3Sum 函数计算剩下三个数,最后组合出和为 target 的四元组。
1 | vector<vector<int>> fourSum(vector<int>& nums, int target) { |
这样,按照相同的套路,4Sum 问题就解决了,时间复杂度的分析和之前类似,for 循环中调用了 threeSumTarget 函数,所以总的时间复杂度就是 O(N^3)。
在 LeetCode 上,4Sum 就到头了,但是回想刚才写 3Sum 和 4Sum 的过程,实际上是遵循相同的模式的。我相信你只要稍微修改一下 4Sum 的函数就可以复用并解决 5Sum 问题,然后解决 6Sum 问题……
那么,如果我让你求 100Sum 问题,怎么办呢?其实我们可以观察上面这些解法,统一出一个 nSum 函数:
1 | /* 注意:调用这个函数之前一定要先给 nums 排序 */ |
嗯,看起来很长,实际上就是把之前的题目解法合并起来了,n == 2 时是 twoSum 的双指针解法,n > 2 时就是穷举第一个数字,然后递归调用计算 (n-1)Sum,组装答案。
需要注意的是,调用这个 nSum 函数之前一定要先给 nums 数组排序,因为 nSum 是一个递归函数,如果在 nSum 函数里调用排序函数,那么每次递归都会进行没有必要的排序,效率会非常低。
比如说现在我们写 LeetCode 上的 4Sum 问题:
1 | vector<vector<int>> fourSum(vector<int>& nums, int target) { |
再比如 LeetCode 的 3Sum 问题,找 target == 0 的三元组:
1 | vector<vector<int>> threeSum(vector<int>& nums) { |
那么,如果让你计算 100Sum 问题,直接调用这个函数就完事儿了。
当你阅读这篇文章时,你正在见证历史。过去五十年间,科技和互联网的功能发生了翻天覆地的变化,如今已成为我们日常生活中便捷的系统。
但正如你可能已经猜到的那样,互联网并非一直都是现在这个样子,也并非一直如此流行。事实上,在2000年,只有52%的美国成年人表示他们使用互联网;但到了2018年,这个数字跃升至82%[1]。
从最初让你来到这里的问题:“互联网是如何运作的?”到网上购物、与家人朋友交流,互联网彻底改变了我们的生活、协作和学习方式。但这一切是如何开始的?互联网又是如何演变成我们今天所熟知的无处不在的系统呢?

要充分了解互联网的运作方式以及我们是如何走到今天的,我们需要从头开始。
1969 年 10 月 29 日,一个名为 ARPANET(高级研究计划署)的组织启动了互联网的第一个版本(也称为 ARPANET),连接了犹他大学、加州大学圣巴巴拉分校、加州大学洛杉矶分校和斯坦福研究所的四台主要计算机 [2]。
当这个计算机网络连接起来后,大学就可以从一个组织到另一个组织以及在内部访问文件和传输信息。
随着研究人员不断完善系统,他们持续连接其他大学的计算机,包括麻省理工学院、哈佛大学和卡内基梅隆大学。最终,ARPANET 更名为“互联网”。
互联网早期只有计算机专家、科学家、工程师和图书管理员使用,他们必须学习复杂的系统才能使用它,但随着技术的进步和消费者的适应,它成为了世界各地人们必不可少的工具。
20世纪70年代是互联网发展的重要转型时期。电子邮件于1972年问世,全国各地的图书馆实现了互联互通,最重要的是,由于传输控制协议和互联网协议(TCP/IP)架构的出现,信息交换变得更加顺畅。
这些协议的发明有助于规范通过网络发送和接收信息的方式,使信息传输更加一致,无论你在哪里或以何种方式访问互联网。
1986年,美国国家科学基金会通过资助NSFNET(一个遍布全国的超级计算机网络),将互联网的发展推向了新的高度。
这些超级计算机为个人计算奠定了基础,弥合了仅用于学术目的的计算机和用于执行日常任务的计算机之间的差距。
1991年,明尼苏达大学开发了第一个用户友好的互联网界面,使用户能够更便捷地访问校园文件和信息。内华达大学里诺分校在此基础上继续完善这一易用界面,并引入了搜索功能和索引功能。
随着互联网的发展不断演变和重点转移,美国国家科学基金会于 1995 年 5 月停止了对互联网骨干网 (NSFNET) 的赞助。
这一变革取消了互联网商业用途的所有限制,并最终促成了互联网的多元化发展和快速增长。此后不久,AOL、CompuServe 和 Prodigy 也加入了 Delphi 的行列,开始向消费者提供商业互联网服务。
上世纪九十年代末, WiFi和 Windows 98的问世标志着科技行业致力于发展互联网的商业化。这一举措使微软等公司得以接触到新的受众群体——消费者(比如您)。
快进到今天。据估计,现在有 30 亿人使用互联网,其中许多人每天都使用互联网来帮助他们从 A 点到达 B 点、与亲人联系、在工作中协作,或者了解更多重要问题,例如互联网是如何运作的?[3]
随着科技的进步和互联网渗透到我们生活的方方面面,预计会有更多人使用互联网。研究人员预测,到 2030 年,互联网用户将达到 75 亿,连接到互联网的设备将达到 5000 亿台 [4]。
现在你已经对互联网的发展历程有了一些了解,让我们来探讨一下当前的问题:“互联网是如何运作的?”
互联网是一个全球性的计算机网络,它通过互连的设备传输各种数据和媒体。它的工作原理是使用数据包路由网络,该网络遵循互联网协议 (IP) 和传输控制协议 (TCP) [5]。
TCP 和 IP 协同工作,确保无论你使用什么设备或在哪里使用,互联网上的数据传输都是一致且可靠的。
数据通过互联网传输时,是以消息和数据包的形式进行的。通过互联网发送的数据称为消息,但在发送消息之前,消息会被分解成更小的部分,称为数据包。
这些消息和数据包使用互联网协议 (IP) 和传输控制协议 (TCP) 从一台计算机传输到另一台计算机。IP 是一套规则系统,用于管理信息如何通过互联网连接从一台计算机发送到另一台计算机。
通过数字地址(IP 地址),IP 系统接收有关如何传输数据的进一步指令。
传输控制协议 (TCP) 与 IP 协同工作,确保数据传输的可靠性和稳定性。这有助于防止数据包丢失,确保数据包按正确顺序重组,并避免因延迟而对数据质量产生负面影响。
想知道从浏览器启动到搜索结果,互联网是如何运作的吗?让我们一步一步地了解这个过程[7][8][9]。
步骤 1:您的电脑或设备通过调制解调器或路由器连接到互联网。这些设备共同使您能够连接到全球其他网络 [6]。
您的路由器使多台计算机能够加入同一网络,而调制解调器则连接到您的 ISP(互联网服务提供商),ISP 为您提供有线或 DSL 互联网服务。
步骤二:输入网址,也称为URL(统一资源定位符)。每个网站都有其唯一的URL,它会告诉你的网络服务提供商(ISP)你想访问哪个网站。
步骤 3:您的查询被推送至您的 ISP,ISP 连接到多个服务器,这些服务器存储和发送数据,例如 NAP 服务器(网络访问保护)和 DNS(域名服务器)。
接下来,你的浏览器会通过 DNS 查找你在搜索引擎中输入的域名对应的 IP 地址。DNS 会将你在浏览器中输入的文本域名转换成数字 IP 地址。
步骤 4:您的浏览器向目标服务器发送超文本传输协议 (HTTP) 请求,以使用 TCP/IP 将网站的副本发送到客户端。
第五步:服务器批准请求后,会向您的计算机发送“200 OK”消息。然后,服务器以数据包的形式将网站文件发送到浏览器。
步骤 6:当浏览器重新组装数据包时,网站加载完毕,您可以学习、购物、浏览和互动。
第七步:尽情享受搜索结果吧!
无论您是在查找有关互联网如何运作的信息、在线观看您最喜欢的电影,还是在网上浏览旅游优惠,不可否认的是,互联网带我们去了很多地方,而且它还将继续这样做!
虽然现在互联网似乎没有发生什么变化,但很有可能,当我们回顾过去,看到我们走了多远,我们使用这项技术的方式发生了多大的变化,最终,我们会发现,我们自己也是互联网历史的一部分。
[1] 皮尤互联网研究中心;互联网/宽带概况介绍
[2] 沃尔特·豪;《互联网简史》
[3] 资金;以下是互联网用户数量
[4] 思科;物联网
[5] Lifewire;TCP(传输控制协议)详解
[6] Mozilla;网络如何运作
[7] 事物是如何运作的;互联网是如何运作的?
[8] 如何成为极客;互联网是如何运作的?
[9] Medium,《互联网是如何运作的》
几个世纪以来,哲学家和作家们一直在构想一个共享的世界知识库。我们今天所知的互联网是如何形成的?
互联网是一个全球性的计算机网络,它通过互联设备传输各种数据和媒体。它的工作原理是利用数据包路由网络,该网络遵循互联网协议(IP)和传输控制协议(TCP)。[5]
步骤 1:您的电脑或设备通过调制解调器或路由器连接到互联网,从而可以连接到全球其他网络。[6]
路由器允许多台计算机加入同一网络,而调制解调器连接到您的互联网服务提供商 (ISP),ISP 提供有线或 DSL 互联网。
你的个人电脑被称为客户端,而不是服务器。
步骤二:输入网址,也称为URL。URL是统一资源定位符的缩写。
步骤 3:您的查询将被处理并推送至您的 ISP。您的 ISP 拥有多个服务器,用于存储和发送数据,例如 NAP 服务器(网络访问保护)和 DNS(域名服务器)。
您的浏览器会通过 DNS 查找您在浏览器中输入的域名对应的 IP 地址。
步骤 4:浏览器向目标服务器发送超文本传输协议 (HTTP) 请求,以使用 TCP/IP 将网站的副本发送给客户端。
步骤五:服务器批准请求并向客户端计算机发送“200 OK”消息。然后,服务器以数据包的形式将网页文件发送到浏览器。
步骤 6:浏览器重新组装数据包,网页加载。
第七步:尽情上网吧![7][8][9]
在本节中,我们将通过一个完整的网络流量示例,逐步演示计算机在通过计算机网络进行通信时将经历哪些步骤。本示例将整合其他章节中的大量信息,是一个全面而完整的示例。
大多数人都会惊讶地发现,计算机发送一个简单的数据包竟然需要这么多步骤,而且其中有很多步骤对于普通用户来说是完全隐藏的,除非你事先知道,否则你永远不会知道。
如果您已经浏览过本网站的大部分内容,那么您可能已经对本教程可能包含的步骤数量有所了解。
下面的示例展示了一个小型家庭网络,其中一台计算机刚刚启动。该计算机已手动配置了 IP 地址,但尚未与网络通信。用户坐在计算机旁,打开 Web 浏览器并尝试访问 www.iis.se。
首先,我们来看一下整体情况。这张图展示了示例中的网络拓扑结构。在接下来的很多步骤中,我们会放大查看网络中最相关的部分,以避免每次都绘制完整的网络拓扑图。

现在让我们从交通示例讲解开始!
一台连接到家庭网络的计算机刚刚启动。该计算机已手动配置了 IP 地址、子网掩码、DNS 服务器和默认网关。DNS 服务器和默认网关地址都指向家庭路由器的局域网 IP 地址。
计算机用户打开网页浏览器并访问www.iis.se
首先,Web浏览器会指示计算机上的操作系统建立计算机与www.iis.se之间的通信。

这部分又细分为许多子步骤。
计算机操作系统会检查其 DNS 缓存,以确定是否已知道www.iis.se的 IP 地址。由于计算机刚刚启动,之前从未访问过www.iis.se,因此 DNS 缓存为空。

现在计算机必须向其 DNS 服务器查询www.iis.se的 IP 地址。
计算机将构建一个 DNS 查询,并将其发送到它配置使用的 DNS 服务器 192.168.1.1。
DNS 查询的目标地址是 192.168.1.1,源 IP 地址是计算机自身的 IP 地址,即 192.168.1.5。
DNS 使用 UDP 作为传输协议。DNS 查询的目标端口是 53/UDP。当 DNS 查询到达 DNS 服务器时,服务器可以通过查看目标端口 53/UDP 来判断该消息是发往 DNS 服务器程序的,并将消息转发给正在运行的 DNS 程序。
计算机操作系统还必须随机化一个源端口,该端口也会写入消息中。

但是,当计算机将 DNS 查询组合起来时,它注意到必须检查应该将数据包发送到哪个目标 MAC 地址。
所以目前,操作系统会将数据包放入内存中的一个队列中,然后开始确定要使用的目标 MAC 地址。
计算机现在将检查其 ARP 表,看看它是否知道与路由器 IP 地址 192.168.1.1 关联的 MAC 地址。
但由于计算机刚刚启动,尚未学习任何 ARP 条目,因此其 ARP 表完全为空。

现在,计算机必须向网络中的其他设备构建一个 ARP 请求。该请求将被发送到目标 MAC 地址 FF:FF:FF:FF:FF:FF,即广播地址。结果是,局域网上的所有其他计算机和设备都将收到该请求并读取其内容。

家用路由器收到ARP请求并读取消息,因为该请求发送到了广播MAC地址FF:FF:FF:FF:FF:FF。
家用路由器可以从消息中看到计算机正在请求 IP 地址为 192.168.1.1 的设备。由于路由器配置为使用该 IP 地址,因此家用路由器将通过构建 ARP 应答并将其发送回计算机来响应此消息。
当计算机收到 ARP 回复时,操作系统会读取该回复。它会将回复添加到 ARP 表中,以便在几分钟内记住与 192.168.1.1 关联的 MAC 地址。

现在计算机终于收集到了发送 DNS 消息所需的所有信息。
现在,计算机将向 DNS 服务器发送 DNS 查询,该服务器作为一项服务运行在家庭路由器 192.168.1.1 上。
家用路由器收到查询后,发现这是一个针对路由器自身 IP 地址和 MAC 地址的 DNS 查询,并意识到它必须处理这个 DNS 查询并发送一个答案。

家用路由器本身就是一个DNS服务器,但它也依赖于互联网上的其他DNS服务器。家用路由器不可能知道互联网上每一个DNS地址。因此,它会根据需要向负责不同域名(例如example.com)的DNS服务器发出请求。
家用路由器也像电脑一样配备了DNS缓存。每次家用路由器处理来自电脑的DNS查询时,它都会将DNS回复保存在自身的DNS缓存中一段时间。这样做是为了避免重复处理相同的DNS查询,从而加快响应速度。

在这种情况下,家用路由器很久没有收到关于www.iis.se 的查询,因此路由器的 DNS 缓存中不存在该域名。所以,路由器必须向其配置的互联网 DNS 服务器请求解析此 DNS 查询。
现在,路由器准备向其 DNS 服务器发送 DNS 查询。路由器在首次启动并从互联网服务提供商 (ISP) 获取公网 IP 地址时,通过 DHCP 从 ISP 获知了可用的 DNS 服务器。
因此,家用路由器会准备一个DNS查询,方法是将查询信息封装在一个UDP消息中,目标端口为53/UDP,源端口为随机UDP端口。然后,它会将该消息封装到一个IP数据包中。该IP数据包会从家用路由器的公网IP地址发送到DNS服务器地址。

当家用路由器准备好数据包并准备发送时,它会查看路由表以确定发送路径。路由表显示,到达内部局域网 192.168.1.0 的最佳路径是通过 LAN 端口,但此数据包需要发送到互联网上的另一个 IP 网络。因此,家用路由器选择 WAN 端口作为最佳目标地址。
在此阶段,家用路由器可能需要执行 ARP 请求来查找下一跳路由器 115.20.97.113 的 MAC 地址,但我们假设家用路由器已经在其 ARP 缓存中获得了此信息。
这里的一些步骤已经过简化和缩短。
互联网上每个接收到 DNS 请求的路由器都会执行以下操作:

最终,数据包到达 DNS 服务器,DNS 服务器将处理该数据包并准备响应。
就像普通电脑一样,服务器也有IP地址、子网掩码和默认网关。因此,它的工作方式与普通电脑非常相似。

现在,在收到来自 DNS 服务器的 DNS 回复后,家用路由器终于可以创建 DNS 回复并将其发送到计算机,以便让计算机知道www.iis.se的 IP 地址。

在这个阶段,很多事情同时发生。
计算机主要会启动一个名为“TCP 三次握手”的过程,这是 TCP 通信的建立阶段,包含计算机和服务器之间的三条消息。在使用 TCP 时(例如网页浏览),TCP 会尽力确保一切运行正常,包括通过握手建立会话。这样做是为了让服务器做好接收会话的准备,并确定通信应使用的端口。
TCP 三次握手由三条消息组成:
计算机的ARP缓存中已经存储了家庭路由器IP地址的正确ARP信息。因此,计算机可以通过家庭路由器向互联网发送任何数据包,而无需事先进行ARP查找。
但这也是本例中计算机首次尝试直接与路由器之外的物体通信。TCP 三次握手将在计算机和互联网上的 Web 服务器之间直接进行。
在之前的DNS查找过程中,计算机只是与家用路由器通信。家用路由器再与互联网上的DNS服务器通信。但计算机与互联网上的任何IP地址之间并没有直接通信。
区别在于,现在计算机想要直接与互联网上的某些内容通信,那么家用路由器就必须对流量执行地址转换。
接下来,我们将仔细研究计算机通过初始化 TCP 三次握手来建立 TCP 会话时发生的情况。
为此,计算机操作系统会随机生成一个用于通信的 TCP 源端口。然后,它会组装 TCP SYN 消息并将其发送到 Web 服务器。该 TCP 消息不包含任何其他数据,它只是一个空的 TCP 消息。
当 TCP SYN 消息通过路由器时,路由器会对该消息执行 NAT 转换。路由器还会将执行的 NAT 转换信息保存在其 NAT 表中,以便跟踪会话并对任何回复执行反向 NAT 转换。

图片显示的是从计算机到Web服务器的TCP SYN数据包。
这里可以看到 Web 服务器返回给计算机的 TCP SYN-ACK 响应:

该数据包与路由器上的 NAT 表条目匹配,以便路由器能够看到应该将数据包转发到哪个 LAN 计算机以及如何对数据包执行 NAT。
最后,计算机向Web服务器发送TCP ACK确认包。

只要计算机和服务器持续通信,它们就会一直使用同一个会话进行通信。这包括使用相同的TCP端口,这样沿途的所有设备都能跟踪会话、地址转换等信息。
会话可能只持续足够长的时间以下载网页,或者网络服务器和计算机可以选择保持会话更长时间,以防用户想要继续浏览网页。
一旦操作系统建立了 TCP 会话,操作系统就会通知 Web 浏览器现在可以开始与 Web 服务器通信了。
网络浏览器会使用HTTP协议来实现这一点,HTTP协议是互联网上传输网页的标准协议。

这也意味着我们已经完成了示例,其中包括建立通信的大部分步骤。从现在开始,计算机和服务器可以相互通信以传输网页,直到传输完成。然后,它们可以选择发送所谓的 TCP RESET 消息来结束会话,该消息会通知所有设备会话已结束。
网络的基本概念


IP地址是IP协议提供的一种统一的地址格式,它为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物理地址(每个机器都有一个编码,如MAC上就有一个叫MAC地址的东西)的差异。是32位二进制数据,通常以十进制表示,并以“.”分隔。IP地址是一种逻辑地地址,用来标识网络中一个个主机,在本地局域网上是惟一的。

IP(网络之间互连的协议)它是能使连接到网上的所有计算机网络实现相互通信的一套规则,规定了计算机在因特网上进行通信时应当遵守的规则。任何厂家生产的计算机系统,只要遵守IP协议就可以与因特网互连互通。IP地址有唯一性,即每台机器的IP地址在全世界是唯一的。这里指的是网络上的真实IP它是通过本机IP地址和子网掩码的”与”运算然后再通过各种处理算出来的(要遵守TCP协议还要加报文及端口什么的,我没有细追究,现在还用不上,反正暂时知道被处理过的就行了),顺便教大家查自己真实IP的方法:


要想理解什么是子网掩码,就不能不了解IP地址的构成。互联网是由许多小型网络构成的,每个网络上都有许多主机,这样便构成了一个有层次的结构。IP地址在设计时就考虑到地址分配的层次特点,将每个IP地址都分割成网络号和主机号两部分,以便于IP地址的寻址操作。
IP地址的网络号和主机号各是多少位呢?如果不指定,就不知道哪些位是网络号、哪些是主机号,这就需要通过子网掩码来实现。什么是子网掩码子网掩码不能单独存在,它必须结合IP地址一起使用。子网掩码只有一个作用,就是将某个IP地址划分成网络地址和主机地址两部分子网掩码的设定必须遵循一定的规则。与IP地址相同,子网掩码的长度也是32位,左边是网络位,用二进制数字“1”表示;右边是主机位,用二进制数字“0”表示。假设IP地址为“192.168.1.1”子网掩码为“255.255.255.0”。其中,“1”有24个,代表与此相对应的IP地址左边24位是网络号;“0”有8个,代表与此相对应的IP地址右边8位是主机号。这样,子网掩码就确定了一个IP地址的32位二进制数字中哪些是网络号、哪些是主机号。这对于采用TCP/IP协议的网络来说非常重要,只有通过子网掩码,才能表明一台主机所在的子网与其他子网的关系,使网络正常工作。常用的子网掩码有数百种,这里只介绍最常用的两种子网掩码。
子网掩码是“255.255.255.0”的网络:
最后面一个数字可以在0~255范围内任意变化,因此可以提供256个IP地址。但是实际可用的IP地址数量是256-2,即254个,因为主机号不能全是“0”或全是“1”。
子网掩码是“255.255.0.0”的网络:
后面两个数字可以在0~255范围内任意变化,可以提供255²个IP地址。但是实际可用的IP地址数量是255²-2,即65023个。
IP地址的子网掩码设置不是任意的。如果将子网掩码设置过大,也就是说子网范围扩大,那么,根据子网寻径规则,很可能发往和本地主机不在同一子网内的目标主机的数据,会因为错误的判断而认为目标主机是在同一子网内,那么,数据包将在本子网内循环,直到超时并抛弃,使数据不能正确到达目标主机,导致网络传输错误;如果将子网掩码设置得过小,那么就会将本来属于同一子网内的机器之间的通信当做是跨子网传输,数据包都交给缺省网关处理,这样势必增加缺省网关(文章下方有解释)的负担,造成网络效率下降。因此,子网掩码应该根据网络的规模进行设置。如果一个网络的规模不超过254台电脑,采用“255.255.255.0”作为子网掩码就可以了,现在大多数局域网都不会超过这个数字,因此“255.255.255.0”是最常用的IP地址子网掩码;假如在一所大学具有1500多台电脑,这种规模的局域网可以使用“255.255.0.0”。
网关实质上是一个网络通向其他网络的IP地址。比如有网络A和网络B,网络A的IP地址范围为“192.168.1.1
192.168.1.254”,子网掩码为255.255.255.0;网络B的IP地址范围为“192.168.2.1192.168.2.254”,子网掩码为255.255.255.0。在没有路由器的情况下,两个网络之间是不能进行TCP/IP通信的,即使是两个网络连接在同一台交换机(或集线器)上,TCP/IP协议也会根据子网掩码(255.255.255.0)判定两个网络中的主机处在不同的网络里。而要实现这两个网络之间的通信,则必须通过网关。如果网络A中的主机发现数据包的目标主机不在本地网络中,就把数据包转发给它自己的网关,再由网关转发给网络B的网关,网络B的网关再转发给网络B的某个主机。网络B向网络A转发数据包的过程也是如此 所以说,只有设置好网关的IP地址,TCP/IP协议才能实现不同网络之间的相互通信。那么这个IP地址是哪台机器的IP地址呢?网关的IP地址是具有路由功能的设备的IP地址,具有路由功能的设备有路由器、启用了路由协议的服务器(实质上相当于一台路由器)、代理服务器(也相当于一台路由器)。
如果搞清了什么是网关,默认网关也就好理解了。就好像一个房间可以有多扇门一样,一台主机可以有多个网关。默认网关的意思是一台主机如果找不到可用的网关,就把数据包发给默认指定的网关,由这个网关来处理数据包。现在主机使用的网关,一般指的是默认网关。
下方是百度百科给出的解释

如何设置默认网关 一台电脑的默认网关是不可以随随便便指定的,必须正确地指定,否则一台电脑就会将数据包发给不是网关的电脑,从而无法与其他网络的电脑通信。默认网关的设定有手动设置和自动设置两种方式。
缺省网关(Default Gateway)是计算机网络中一个如何将数据包转发到其他网络中的节点。在一个典型的TCP / IP网络,节点(如服务器、工作站和网络设备)都有一个定义的默认路由设置(指向默认网关)。可以在没有特定路由的情况下,明确出发送数据包的下一跳IP地址。
下方是百度百科给出的解释:

可以看出缺省网关就是默认网关,那么有人会说既然有一样为什么又凭空多出来一个缺省网关,我的理解是这样的,应该说默认网关是缺省网关的一个子集。缺省网关有一个定义的默认路由设置(指向默认网关),缺省网关就相当于一个代理服务器暂时管理发送的数据包,当发送到目标主机时先由目标主机的缺省网关接收再找到对应的默认网关,就相当于缺省网关是父类,默认网关是子类~~
域名服务器(Domain Name Server)。在Internet上域名与IP地址之间是一一对应的,域名虽然便于人们记忆,但机器之间只能互相认识IP地址,它们之间的转换工作称为域名解析,域名解析需要由专门的域名解析服务器来完成,DNS就是进行域名解析的服务器 。
DHCP指的是由服务器控制一段IP地址范围,客户机登录服务器时就可以自动获得服务器分配的IP地址和子网掩码。提升地址的使用率。
MAC地址就如同我们身份证上的身份证号码,具有全球唯一性。(知道这个就行了,不用往下看了)
MAC(Media Access Control,介质访问控制)地址
也就是说,在网络底层的物理传输过程中,是通过物理地址来识别主机的,它一定是全球唯一的。比如,著名的以太网卡,其物理地址是48bit(比特位)的整数,如:44-45-53-54-00-00,以机器可读的方式存入主机接口中。以太网地址管理机构(除了管这个外还管别的)(IEEE)(IEEE:电气和电子工程师协会)将以太网地址,也就是48比特的不同组合,分为若干独立的连续地址组,生产以太网网卡的厂家就购买其中一组,具体生产时,逐个将唯一地址赋予以太网卡。
在一个稳定的网络中,IP地址和MAC地址是成对出现的。如果一台计算机要和网络中另一外计算机通信,那么要配置这两台计算机的IP地址,MAC地址是网卡出厂时设定的,这样配置的IP地址就和MAC地址形成了一种对应关系。在数据通信时,IP地址负责表示计算机的网络层地址,网络层设备(如路由器)根据IP地址来进行操作;MAC地址负责表示计算机的数据链路层地址,数据链路层设备(如交换机)根据MAC地址来进行操作。IP和MAC地址这种映射关系由ARP(Address Resolution Protocol,地址解析协议)协议完成。
端口包括物理端口和逻辑端口。物理端口是用于连接物理设备之间的接口,逻辑端口是逻辑上用于区分服务的端口。TCP/IP协议中的端口就是逻辑端口,通过不同的逻辑端口来区分不同的服务。
端口有什么用呢?我们知道,一台拥有IP地址的主机可以提供许多服务,比如Web服务、FTP服务、SMTP服务等,这些服务完全可以通过1个IP地址来实现。那么,主机是怎样区分不同的网络服务呢?显然不能只靠IP地址,因为IP 地址与网络服务的关系是一对多的关系。实际上是通过“IP地址+端口号”来区 分不同的服务的。
1 | VIM多光标插件,提供vim/nvim快速操作多光标编辑的能力 |
顺便在这里附上我自己的nvim配置仓库地址 yaocccc/nvim
1 | 推荐使用vim-plug安装 |
1 | " 贴上本人的配置 |
!!!重要!!!
!!!重要!!!
!!!重要!!!
1 | 简单来说该插件提供三种模式: |
1 | 当前有以下文本,试完成以下案例 原始光标初始位置在第1行的l位置 |
1 | 案例2: 将 124行的 let 改成 const |
1 | 案例3: 将文本内容改成 |
1 | 建议将列出的按键配置都自己试一遍 |
GT系列当前包括BLE60 、 Omega45 、 Farad69、Omega50四款键盘,四款键盘均采用的LotKB开源固件进行驱动,功能按键等设定基本一致:
休眠按键:P – 同时按下Lshift+Rshift时按此键可以手动进入休眠模式,按任意键可以唤醒。(此功能按键修改配列不会改变)
关机按钮:ESC或~ – 同时按下Lshift+Rshift时按此键可以手动进入关机模式,关机后需要按背部的Bootloader按钮才可重新开机。长期不用或携带外出建议关机。
切换蓝牙设备:Q/W/E – 同时按下Lshift+Rshift时按Q/W/E可以在已绑定的蓝牙设备之间进行切换。
重新开启蓝牙广播:R – 同时按下Lshift+Rshift时按R可以重新开启蓝牙广播,用于切换设备后进行绑定。
显示蓝牙键盘状态灯:L 或 ? – 在电池供电情况下,状态灯会自动熄灭,如要显示当前状态灯,同时按下Lshift+Rshift时按L或?,将显示状态灯5秒。
锁定WIN键:G – 同时按下Lshift+Rshift时按此键,将锁定WIN键,再次同时按下Lshift+Rshift时按此键,将恢复WIN键,重启将自动恢复WIN键。
切换连接模式按键:M – 在通过USB和蓝牙同时连接一台设备(也可通过USB连接一台设备、蓝牙连接另一台设备)的情况下,同时按下Lshift+Rshift时按此键可以切换连接模式。如未同时使用USB模式和蓝牙模式,此按键无效。
进入DFU刷机模式:B – 同时按下Lshift+Rshift时按此键可以重启到DFU刷机模式。也可在唤醒的同时按Space+B进入DFU刷机模式。
清空当前设备蓝牙绑定信息按键:O – 同时按下Lshift+Rshift时按此键可以清空当前蓝牙绑定信息。仅清空当前设备,其余绑定设备不会清空。
重置键盘:I – 同时按下Lshift+Rshift时按此键可以重置键盘。重置键盘会清空所有的蓝牙绑定信息、自定义的配列、存储的键盘配置信息。
RGB灯效控制:调整颜色: A/S/D/F/C/V – 同时按下Lshift+Rshift时按A/S/D/F/C/V,分别是增加饱和度、降低饱和度、增加亮度、降低亮度、增加色调、降低色调。
RGB灯效控制:调整模式:Z – 同时按下Lshift+Rshift时按Z,循环灯效。
RGB灯效控制:开关RGB:X – 同时按下Lshift+Rshift时按X,切换RGB灯的开关。
PCB背部多功能按钮 – 背部按钮属于多功能按钮。键盘正常模式下,按下一秒后松手键盘关机;按下三秒后松手键盘进入DFU刷机模式;按下10秒后松手,键盘将重置。在断电状态,按下背部按钮不放,同时按下键盘第一行首个按键或最后一个按键,然后通电,将强制进入DFU模式。
如果要绑定并切换多设备,按以下步骤操作:
1、键盘上按下双Shift+Q,然后再按下双shift+R,在需要绑定键盘的设备上搜索蓝牙键盘,在搜索到相应蓝牙键盘名称后,将第一个设备绑定到键盘Q键上;
2、键盘上按下双Shift+W,然后再按下双shift+R,然后绑定第二个设备到键盘W键;;
3、键盘上按下双Shift+E,然后再按下双shift+R,然后绑定第三个设备到键盘E键;
4、通过双shift+Q/W/E进行输入设备的切换
状态提示灯说明
GT系列蓝牙键盘状态灯一般为3颗,以Omega45为例:

如要更换某个设备的绑定,如要新绑定一个设备到W键上。
1、将W键绑定设备上的蓝牙键盘进行删除(如windows系统进入系统设备删除蓝牙键盘;Android系统进入设置-蓝牙后删除蓝牙键盘);
2、键盘上按下双Shift+W,切换到W设备;
3、然后键盘上再按下双shift+O,删除W上绑定的设备,绑定新的设备到键盘W键上;
相关参数的设定 – 考虑到耗电问题,正常键盘扫描按键输入为10ms一次,回报率为100Mhz;如果15秒不按键转入慢速扫描,100ms一次,当有按键按下,又自动转入正常扫描速度10ms一次;如果20分钟无按键行为将自动转入休眠模式,此时要重新启用键盘,只需要按任意键就可唤醒,唤醒动作后约1-2s可以正常输入。
在线编译
通过在线编辑,可以可视化配置按键配列、生成固件。
通过此网站 :lotkb.glab.online 或 访问导航中“在线编译” 。可以可视化修改按键,更改按键更加方便;可以更改一些参数设定,如自动休眠时间、RGB灯数量等。
LotKB采用的低功耗蓝牙:Bluetooth Low Energy,并且是5.0版本,可向下兼容蓝牙4.0,但不支持蓝牙3.0及以下。由于采用的较新的协议,需要较新的系统才能支持。如:
iOS 6以上;Android 4.3以上;Windows 8.1以上;Windows Phone 8.1;较新的MacOS。
除了操作系统以外,也需要硬件设备支持,至少要硬件设备支持蓝牙4.0以上才行。从时间上来说,可能要2011年以后的设备才能支持蓝牙4.0,也才可能使用此键盘的蓝牙功能
本页面最后修改时间2025-06-09
GT系列三模键盘PCB没有硬件电源开关,只需要接入电池或插入USB通电后,键盘就会自动开机。
软关机后,可以插入USB线 / 按击一下背部多功能按钮 / 按下旋钮中键 实现开机。
按下背部多功能按钮1秒以上后(不超过3秒)松手 或 系统功能按键Lshift+Rshift+Backspace或~进入关机状态。
插入 USB 时,无法关机(关机后马上会被唤醒)。
在一定时间不敲击按键后,键盘将自动进入睡眠模式以便省电。进入自动睡眠的时间可以自由设定。
自动睡眠后,按任意键可唤醒键盘重新工作。
插入 USB 后,由 USB 供电,自动睡眠功能不会启用,如处于睡眠状态也将自动唤醒。
同时按下Lshift+Rshift+P可以手动进入睡眠模式
手动睡眠后,按任意键可唤醒键盘重新工作。
如果启用了唤醒按键功能,手动睡眠后唤醒时需要按Space+U才能唤醒键盘。
插入 USB 后,将直接唤醒键盘重新工作,并且无法手动睡眠。
如需通过 蓝牙连接 进行输入,确保键盘处于蓝牙连接模式,并完成 配对蓝牙设备 的过程。
如需通过 2.4G无线 进行输入,确保键盘处于2.4G无线连接模式,将 2.4G接收器 插入设备的USB口,并完成2.4G接收器配对。
直接将 USB 线缆插入到键盘的 USB 接口,键盘即自动切换至 USB 模式,使用 USB 输入。
将 USB 线缆插入到键盘的 USB 接口,将键盘2.4G无线模式切换至 2.4G接收模式,此时当前键盘可作为其他2.4G键盘的接收器使用。
同时按下Lshift+Rshift+M可以在USB / 无线 状态之间切换,如未插入USB线,此切换功能无效。
USB连接状态下,可通过Lshift+Rshift+Q/W/E直接跳转到对应蓝牙或2.4G通道。
在没有接入 USB 电源的情况下,为提升续航,键盘处于省电模式。
在省电模式下,所有的指示灯仅在变化后亮起 5 秒,然后熄灭。键盘在无操作 15 秒后转入慢速扫描模式,无操作 600 秒后自动睡眠。(前述三个时间均支持通过配置工具自定义)
慢速扫描模式下,按键检测将可能略有延迟。在慢速扫描模式下按任意按键即可恢复到快速扫描模式。
自动睡眠后,按下键盘的任意按键可唤醒键盘。
电量百分比仅供参考
由于测量数据是根据电压估算,显示电量和实际可能存在误差,损耗较大的电池电量百分比可能无法达到 100%。
在新版本的 iOS、安卓和 Windows 上,应该能够正常的显示蓝牙设备的电量百分比。
对于安卓手机,如果没有正常的显示电量,可以尝试下载 BatON 软件来获取蓝牙设备电量。
如USB与2.4G无线连接状态,或其他无法显示电量的情况,可以通过Lshift+Rshift+H输出电量
通过Lshift+Rshift+H输出电量时,N代表未能检测到数值,F代表电池电量满,数值代表电量百分比。
新版固件支持通过键盘控制面板显示电量
此键盘支持 NKRO(全键无冲)模式。USB、蓝牙、2.4G模式均支持全键无冲模式。
启用唤醒按键功能后,手动睡眠后唤醒需按Space+U唤醒键盘。
自动睡眠时,不需要按唤醒按键,可任意键唤醒。
默认不启用唤醒按键功能,可通过Lshift+Rshift+I启用或禁用。
说明
采用nRF52810/nRF52811芯片的键盘,由于空间不足不支持DFU模式,请采用线刷方式更新固件
DFU模式为键盘内置的蓝牙刷机模式,在通过手机nRF Connect程序升级时,必须确保在蓝牙通讯模式,并进入DFU模式。
同时按下Lshift+Rshift+B可以重启到DFU刷机模式。也可长按PCB背部多功能按钮4秒以上后(不超过9秒)松手重启到DFU刷机模式。
USB ISP 模式为USB芯片的烧录模式,在更新USB固件时需要先进入USB ISP模式。
短接PCB背部K1位置两个焊盘,并插入USB线可手动进入USP ISP模式;
用烧录工具烧录USB固件时,烧录工具会自动跳转USB ISP模式,无需手动短接K1。
键盘控制面板是一个网页应用程序,可通过网页程序控制键盘的各种功能。
包括获取键盘各种信息、控制键盘功能、更改灯光和层级、更改输出模式等。
键盘需2024年12月7日后固件支持接入键盘控制面板,接收器需2025年1月4日后固件支持接入键盘控制面板。
键盘控制面板支持作为网页程序进行安装,安装后支持离线使用。
轴灯版PCB采用键盘主控直接驱动RGB灯,所以无复杂灯效,仅有单色常亮、单色呼吸和彩虹循环,可手动调色,可视为单色轴灯的增强版本。
轴灯分为轴灯模式和指示灯模式,出厂默认为指示灯模式,可通过Lshift+Rshift+L 或 通过配置工具设置一颗状态灯开关按键 在指示灯模式和轴灯模式之间切换。
指示灯模式时,不可控制,以不同颜色指示不同状态,详细参考 状态提示灯说明
要控制轴灯,请先切换到轴灯模式。轴灯模式时,采用Lshift+Rshift+Z X C V等RGB控制功能调整轴灯。
RGB轴灯版PCB采用WS2812 RGB灯,支持各种丰富绚丽的灯效(同QMK灯效),支持键盘状态指示灯、USB与蓝牙状态指示灯。
可采用Lshift+Rshift+Z X C V等RGB控制功能调整RGB轴灯。
或 接入配置工具,找到 灯光 功能,将RGB阵列相关按键设定到你指定的按键上控制RGB灯光。
RGB轴灯同时兼容指示灯,指示灯可通过配置工具设置一颗状态灯开关按键进行开关
指示灯支持独立运行,建议在使用电池时,关闭RGB轴灯,开启指示灯,指示灯将可自动关闭节能
| 功能 | 按键 | 功能说明 |
|---|---|---|
| 睡眠 | Lshift+Rshift+P | 手动进入睡眠模式,按任意键可以唤醒。 |
| 关机 | Lshift+Rshift+~或Backspace | 手动进入关机模式。新版固件将ESC更换成了Backspace。 关机后需要插入USB线 或 短按背部多功能按钮开机。 长期不用或携带外出建议关机。 |
| 重启 | Lshift+Rshift+N | 手动重启键盘,用于遇到部分故障后重启修正。 |
| 有线/无线状态切换 | Lshift+Rshift+M | 在USB有线和无线同时工作时,可以切换有线/无线连接模式。 如未同时使用USB有线和无线,按键无效。 |
| 无线模式切换 | Lshift+Rshift+U | 在键盘支持BLE5.0与2.4G无线两种无线模式时,在两种模式之间切换。 |
| 无线收发模式切换 | Lshift+Rshift+J | 最新固件中,当处于2.4G无线模式时,可在2.4G接收 [接收器] 和2.4G发送 [键盘] 两种2.4G无线模式之间切换。 |
| 切换蓝牙设备/无线接收器 | Lshift+Rshift+Q/W/E | 可以在已配对的蓝牙设备/无线接收器之间进行切换,Q/W/E代表不同蓝牙连接通道/无线接收器 |
| 重启蓝牙广播 2.4G无线配对 | Lshift+Rshift+R | 蓝牙模式:重新开启蓝牙广播,用于手动进行连接或切换设备后配对。 2.4G无线模式:发起配对通讯,与2.4G接收器进行配对。 |
| 进入DFU | Lshift+Rshift+B | 重启到DFU刷机模式。 也可长按PCB背部多功能按钮4秒以上后松手重启到DFU刷机模式。 |
| 清空当前配对 | Lshift+Rshift+O | 蓝牙模式:清空当前蓝牙设备配对信息。仅清空当前设备,其余配对设备不会清空。 2.4G无线模式:解除与当前2.4G接收器的配对 |
| 输出电量 | Lshift+Rshift+H | 通过键盘输出当前键盘剩余电量。输出N为检测未稳定,F为满电,数字为电量百分比。 |
| 状态灯开关 | Lshift+Rshift+L | 无轴灯PCB/RGB轴灯PCB:开启或关闭状态指示灯显示(注:不包括键盘大小写等)。 轴灯版PCB:使轴灯在轴灯模式和指示灯模式之间切换 |
| 多功能按钮 | PCB背部按钮属于多功能按钮。 | 键盘正常模式下,按下1秒以上后(不超过3秒)松手键盘关机; 按下4秒以上后(不超过9秒)松手键盘进入DFU刷机模式; 按下10秒以上后松手,键盘将重置。 关机状态短按一下开机。 |
| 唤醒按键 | Space+U | 启用唤醒按键功能后,手动睡眠后唤醒需按Space+U唤醒键盘。 自动睡眠时,不需要按唤醒按键,可任意键唤醒。 |
| 切换唤醒按键 | Lshift+Rshift+I | 启用或禁用唤醒按键功能。 启用唤醒按键功能后,手动睡眠后唤醒需按Space+U唤醒键盘 |
| 切换默认层 | Lshift+Rshift+数字键 | Lshift+Rshift+1切换默认层到第2层。 Lshift+Rshift+0切换默认层到第1层。 睡眠或关机后唤醒自动恢复第1层为默认层 |
| RGB调整颜色 | A/S/D/F/C/V | 轴灯版(轴灯模式下)为控制轴灯;非轴灯版为控制底灯 同时按下Lshift+Rshift时按A/S/D/F/C/V, 分别是增加饱和度、降低饱和度、增加亮度、降低亮度、增加色调、降低色调。 |
| RGB灯效循环 | Lshift+Rshift+Z | RGB轴灯版为控制RGB轴灯在灯效之间循环 轴灯版(轴灯模式下)为控制轴灯在常亮、呼吸、多彩变换之间循环 非轴灯版为控制底灯在32种灯效之间循环 |
| RGB灯开关 | Lshift+Rshift+X | RGB轴灯版为RGB轴灯开关 轴灯版(轴灯模式下)为轴灯开关 非轴灯版为RGB底灯开关 |
如需更换某个设备的配对,例:要重新配对一个设备到蓝牙通道2️⃣(W键 )。
Tip
上述切换蓝牙通道及删除配对设备等,也可通过BT 1 / BT 2 / BT 3 / 无线 解除配对 等按键进行操作
采用BT 1 / BT 2 / BT 3按键切换蓝牙通道后,需要按下无线 广播配对手动开启蓝牙广播
Tip
配对前请确保键盘固件更新到支持三模固件的版本,并确保接收器和键盘的固件版本对应。
GT系列无线键盘无灯版指示灯一般为3颗,每个键盘指示灯的位置稍有不同,但是指示逻辑基本一致:
GT系列无线键盘单色RGB轴灯版默认采用轴灯作为指示,不同颜色代表不同状态:
GT系列无线键盘炫彩RGB轴灯版默认采用某颗轴灯作为指示,不同颜色代表不同状态:
状态灯开关按键进行开关硬件上采用nRF52系列芯片+CH55x芯片协同实现的USB、蓝牙、2.4G无线功能
本页面最后修改时间2025-06-09
本页面操作说明全系列键盘通用,所有内容基于最新版固件,如与当前键盘实际不符,建议升级固件 更多键盘专有说明可以访问键盘产品信息页面
gg: 跳转到文件第一行。G(Shift+g) : 跳转到文件最后一行。nG(如10G) : 跳转到第n行。:n(如:10+ 回车) : 跳转到第𝑛行。H/ M/L : 跳转到当前屏幕的最高行(High)、中间行(Middle)、最低行(Low)。0(数字零) : 跳转到当前行行首。^(Shift+6) : 跳转到当前行第一个非空字符。$(Shift+4) : 跳转到当前行行尾。Ctrl+o: 返回到跳转前的位置。%: 跳转到与之匹配的括号行vim-multiple-cursors插件在Vim 中实现了类似Sublime Text/VS Code 的多光标编辑功能。核心在于使用Ctrl-n选择下一个匹配项,Ctrl-p跳回上一个,Ctrl-x跳过当前项。进入多光标模式后,可使用c(修改)、I(行首插入)、A(行尾插入) 等命令批量编辑。
核心快捷键(Normal/Visual 模式)
<C-n>(Ctrl+n) : 启动多光标模式并选择当前光标下的单词,或选择下一个匹配项。<C-p>(Ctrl+p) : 移除上一个光标,撤销上一次的Ctrl-n操作。<C-x>(Ctrl+x) : 跳过当前匹配的单词。<C-g>(Ctrl+g) : 退出多光标模式,返回到单个光标。使用流程
<C-n>选中该单词。<C-n>选中接下来的匹配项。c(修改), i(插入), a(追加) 等模式键进入编辑模式。<Esc>退出多光标编辑模式。可视模式(Visual Mode)使用
在可视模式下选中一段文本,然后按<C-n>,该插件会在选中的每一行行尾添加光标,方便批量操作。
常见问题与技巧
<C-g>取消。<C-n>映射为其他键,以防与插件快捷键冲突。Ctrl + w + w:在所有窗口间循环切换Ctrl + w + h/j/k/l:向左/下/上/右切换窗口t:在新标签页打开文件(NERDTree 中)T:在后台标签页打开文件i:在水平分割窗口中打开s:在垂直分割窗口中打开如果 NERDTree 在左侧,当前编辑文件在右侧:
Ctrl + w + l:从 NERDTree 切换到右侧窗口q:关闭 NERDTree 窗口:NERDTreeToggle 或 :NERDTreeFocus.vimrc 中)vimrc
1 | " 使用 Ctrl+n 切换 NERDTree |
最简单的方式:直接按 Ctrl + w + w 即可在 NERDTree 和编辑窗口间切换。
https://makifx.com/boutique-software)
本人自建 音乐服(音海拾贝)| 有声书服(悦耳声阅)
通知频道:https://t.me/yinhai_notify
【悦耳声阅】有声书分享频道:https://t.me/YueErFM
DS Cloud
https://apps.apple.com/app/id6476057278
维克音乐
https://apps.apple.com/us/app/offline-music-player-wake/id6544783918?platform=iphone
LMP
https://apps.apple.com/us/app/lmp-a-better-music-player/id6451009326
音流
https://github.com/gitbobobo/StreamMusic
Cinetry
https://github.com/gstory0404/Cinetry
LMP 音乐{TF}
https://testflight.apple.com/join/H0qG853j
DS Cloud
https://apps.apple.com/app/id6476057278
维克音乐
https://apps.apple.com/us/app/offline-music-player-wake/id6544783918?platform=iphone
FeiShin
https://github.com/jeffvli/feishin
Pure Music (棉花音乐)
https://github.com/pure-music/PureMusic/releases
Cinetry
https://github.com/gstory0404/Cinetry
DS Cloud
https://apps.apple.com/app/id6476057278
维克音乐
https://apps.apple.com/us/app/offline-music-player-wake/id6544783918?platform=iphone
LMP
https://apps.apple.com/us/app/lmp-a-better-music-player/id6451009326
FeiShin
https://github.com/jeffvli/feishin
音流
https://github.com/gitbobobo/StreamMusic
Pure Music (棉花音乐)
https://github.com/pure-music/PureMusic/releases
Cinetry
https://github.com/gstory0404/Cinetry
DS One(DS Cloud)
https://play.google.com/store/apps/details?id=com.cz.player.dsone
音流
https://github.com/gitbobobo/StreamMusic
tempus
https://github.com/eddyizm/tempus
tempo
https://github.com/CappielloAntonio/tempo/releases
Cinetry
https://github.com/gstory0404/Cinetry
Symfonium
Pure Music (棉花音乐)
https://github.com/pure-music/PureMusic/releases
Musicfree(需配合插件使用)
https://github.com/CTZZG/MusicFree/releases 插件地址:
1 | https://gitee.com/Rrance/WP/raw/master/音海拾贝.js |
音流
https://github.com/gitbobobo/StreamMusic
Symfonium
Pure Music (棉花音乐)
https://github.com/pure-music/PureMusic/releases
FeiShin
https://github.com/jeffvli/feishin
Pure Music (棉花音乐)
https://github.com/pure-music/PureMusic/releases
Cinetry
https://github.com/gstory0404/Cinetry
Audiobookshelf:
https://testflight.apple.com/join/wiic7QIW
Tonspur:
https://testflight.apple.com/join/E92V6bRM
Prologue:
https://testflight.apple.com/join/zTWS6ahB
Cinetry
https://github.com/gstory0404/Cinetry
AudioBooth:
https://testflight.apple.com/join/cAG6dVeN
dscloud:
https://apps.apple.com/app/id6476057278
SoundLeaf:
https://github.com/SoundLeaf/SoundLeafApp
ShelfPlayer:
https://apps.apple.com/us/app/shelfplayer/id6475221163
audiobookshelf:
https://play.google.com/store/apps/details?id=com.audiobookshelf.app
DS One(DS Cloud)
https://play.google.com/store/apps/details?id=com.cz.player.dsone
Cinetry
https://github.com/gstory0404/Cinetry
Lissen:
https://github.com/GrakovNe/lissen-android
LitLyric:
https://github.com/shane9b3/LitLyric---Beta
Kitzi:
https://github.com/bennybar/kitzi_abs_player
Buchable:
https://github.com/Vito0912/abs_flutter
musicfree(需配合插件使用):
https://github.com/CTZZG/MusicFreeDesktop-1/releases
插件地址:
1 | https://gitee.com/Rrance/WP/raw/master/audiobookshelf.js |
Cinetry
https://github.com/gstory0404/Cinetry
Buchable:
https://github.com/Vito0912/abs_flutter
Cinetry
准备一个U盘,安装包一般大小都在12G以上,所以建议至少16G,或者直接使用移动硬盘。
插入U盘,打开Mac的磁盘工具
选择U盘-抹掉
名称:随意
格式:格式Mac OS扩展(日志式)
方案:GUID分区图

抹掉完成之后,再对U盘进行分区用于制作Mac OS安装盘,点击+号,增加新的分区
分区信息:
名称:UOS
格式:Mac OS扩展(日志式)
大小:必须大于你的安装包,我这里直接分了16G
新增分区之后,就可以准备制作Mac OS安装盘了。
下载好的Mac OS安装包默认放在应用程序中按照一下方式进行安装盘制作:
sudo”(无引号)createinstallmedia”到终端(文件位置在“安装macOS Ventura.app”-右键-显示包文件-Contents-Resources里)--volume”(无引号)--nointeraction”(无引号)以上步骤综合为这么一串代码,请根据自己系统版本和U盘名字对应修改:
1 | sudo /Applications/Install\ macOS\ Ventura.app/Contents/Resources/createinstallmedia --volume /Volumes/UOS --nointeraction |
整个制作过程如下,到最后显示出这个就表示安装盘制作完成。
1 | sudo /Applications/Install\ macOS\ Ventura.app/Contents/Resources/createinstallmedia --volume /Volumes/Install\ macOS\ Ventura --nointeraction |
到这里,如果你的引导没有屏蔽多余的启动项,在启动中已经可以看到这个安装盘了,选择既可以使用。
安装盘制作完成之后,为了可以以后将U盘作为启动盘从BIOS的启动界面启动安装盘,就需要将自己配置好的引导文件EFI文件放到EFI分区中。
使用工具挂载EFI分区,比如用OpenCore Configurator 或者Hackintool 或者 OCAuxiliaryTools都可以,挂载U盘的EFI分区之后,将自己的配置好的EFI文件放进去,就成为了自己黑苹果的专用安装盘了。
那如果需要用于不同的机器来安装黑苹果,或者调试的时候修改EFI文件,总是需要挂载EFI分区,就比较麻烦了。
我们可以在引导分区之外,新建一个公开的引导分区。
打开磁盘工具,选择U盘,点分区,选择之前制作Mac OS安装盘剩下没有使用的部分,点+号,增加新的分区。
分区信息:
名称:MAC_EFI(随意,不能有中文)
格式:MS-DOS (FAT32)
大小:1G(引导文件很小,一般大于200M即可)

这个新建的引导分区同样也可以放黑苹果的EFI引导文件,而且是无需挂载的,适合频繁修改调试引导配置和更换文件。
按照上面的方式同样新增一个分区
分区信息:
名称:WINPE(随意,同样不能有中文)
格式:MS-DOS (FAT32)
大小:大于你的PE文件
新增分区完成之后,这里就需要一个支持UEFI启动的WinPE,一般PE主流格式都是exe格式,不符合我们的需要,所以需要在Window系统下先将PE制作成iso文件。
这里推荐老毛桃PE,功能比较多,可以联网,适合大多数PE需求。
然后在Mac下,打开iso文件,将里面的文件复制到新增的WINPE分区中。
这样,一个Mac OS的安装盘和PE盘二合一的U盘就制作好了,剩下还有多余空间,可以当做正常存储U盘使用。