1.MDN 的记录自动完成搜索是如何实现的
2.365源码网发展历程
3.信号量(Semaphore)从入门到源码精通
MDN 的自动完成搜索是如何实现的
上个月,我和 Gregor Weber 为 MDN Web Docs 添加了 自动完成搜索(autocomplete search)功能,源码有了这个功能,统计你可以通过输入文档的代码部分标题来快速查找并跳转到想查看的文档。这篇文章我会介绍这个功能是记录如何实现的。如果你坚持看到文章末尾,源码亨源码头我还会分享一个 “彩蛋” 功能,统计一旦你学会使用它,代码你一定会成为派对上最靓的记录仔。不过,源码或许你只是统计想比普通人更快的浏览 MDN。
简单来说,代码输入框上有一个onkeypress 事件监听器 用于过滤 (每个地区的记录)完整的文档标题列表。在我写这篇文章时,源码English US 有 ,统计 个不同的文档标题和对应的 URL。你可以打开 developer.mozilla.org/e... 来预览这些文档。没错,这个文件很大,但还没大到无法被全部放进内存。毕竟,执行搜索逻辑的代码只会在发现用户要输入某些内容时,该文件才会被加载。nginx c源码而提到文件大小,由于文该件通过 Brotli 算法进行了压缩,所以在网络上该文件大小仅为 KB。
实现细节:默认情况下,加载的 JavaScript 代码 只有一小段 shim 代码,用于设定监听 搜索框的 onmouseover 和 onfocus 。还有一个绑定在 document 上用于监听输入特定按键的事件监听器。在任何地方输入 /,和你用鼠标把焦点放在 是一样的。一旦 focus 事件被触发,首先会 下载两个 JavaScript 包 来将 转变为更高级的东西。简单来说(通过伪代码),就是这样的:
而这里加载的/static/js/autocomplete.js 才是最神奇的。通过伪代码我来深入解释一下:
正如你看到的,这是对实际工作原理的过度简化,但现在还不是深入这些细节的时候。下一步 就是展示匹配项。我们使用 (TypeScript) React 来实现,但是下面的伪代码应该更容易理解:
然后通过一些 CSS,我们会把这些匹配项变成一个浮层,然后简单放在 下方。手势控制源码除此之外,我们还会根据 inputValue 突出展示每个文档标题,当通过上下按键浏览时,各个事件监听器会突出展示你正在浏览的行。
好的,我们再深入一下实现细节:我们只创建了一次FlexSearch 索引,并在每一次新的键击出现时复用它。由于用户在等待网络响应时,可能会输入更多东西,所以当全部的 JavaScript 和 JSON XHR 都加载完毕,才会执行实质上的搜索。
在我们深入FlexSearch 是什么之前,我想先说一下我们实际上是如何展示搜索结果的。我们使用了一个 React 库 downshift 来处理交互、展示 并确保搜索结果具有可访问性(Accessible,译者注:无障碍相关,国外页面对于 让残障人士更加便利的访问 比较重视)。 downshift 是一个很成熟的库,解决了我们在构建这个小组件时遇到的很多挑战,尤其是让搜索结果具有可访问性。
那么,小康买卖源码 FlexSearch 是一个怎样的库呢?它是我们引入的另一个第三方库,确保在标题上的搜索是以自然语言为基础的。它将自己描述为 “Web 上最快,内存最灵活 的 零依赖 全文搜索库”,它比简单的在字符串中搜索要准确高效很多。
决定优先展示哪些结果:有一说一,假设用户输入了foreac ,从 ,+ 的文档标题列表找到那些标题包含 foreac 的项 并不困难,在这之后我们需要决定优先展示哪些结果。我们根据 PV 数据来实现这一点。我们会记录每一个 MDN URL,如果一个页面获得很多的 PV ,那可能它是 “受欢迎” 的。大多数人选择访问的文档就是受欢迎的,也最有可能是用户想要搜索的。
我们在生成search-index.json 文件的 构建阶段 可以知道每个 URL 的 PV 量。我们实际上并不关心绝对数字,我们真正关心的是其中的相对差异。例如,我们知道 Array.prototype.forEach() (文档标题之一)比 TypedArray.prototype.forEach() 更受欢迎,我们就会利用这一点,汽车美容 源码在 search-index.json 中对条目进行排序。现在,通过 FlexSearch 进行简化,我们利用数组的 “自然顺序” 来为用户提供他们可能在搜索的文档。这实际上和我们在全站搜索中使用的 Elasticsearch 是相同的技术。详见: How MDN’s site-search works 。
彩蛋:如何通过 URL 搜索:事实上,这个彩蛋可不是闹着玩的,而是一个功能,利用自动完成用来帮助我们的内容创作者。当你创作 MDN 中的内容 时,你会启动一个本地的 “预览服务器”,它是所有文档的完整拷贝,但运行在本地,作为一个静态站点 运行于 http://localhost: 。在那里,你不会希望依赖于服务器来进行搜索。内容创作者们需要快速的在文档间切换,这就是自动完成搜索完全实现在客户端的主要原因。
像是 VSCode 和 Atom IDE 这样的工具中 通常会实现 “模糊搜索”,这个功能可以帮助你通过简单的输入文件路径的一部分来查找和打开文件。例如,搜索whmlemvo 就能找到 files/web/html/element/video 这个文件。你也可以在 MDN 的自动完成搜索中做同样的事情。你可以以 / 为第一个字符来开启这个功能。
如果你知道 URL 但不想完整写出来,你可以通过这种方式非常快速的直接跳转到对应的文档。
事实上,还有另一种导航方式,你可以在浏览 MDN 时先输入/ 激活自动完成搜索,然后在输入 /,接下来就轮到你了!
如何真正地深入实现细节:我上面提到的全部所有代码都在 Yari 的 repo 中,Yari 是构建和预览全部 MDN 内容 的一个项目。可以点击 client/src/search.tsx 来访问源代码,你会找到所有实现 懒加载,搜索,预加载 和 显示自动完成搜索结果的代码。
源码网发展历程
年月1日,源码网开启了它的运营历程,以提供全面的源码服务。在初始阶段,网站就获得了显著的关注,同年1月1日,"百度"和"google"等主流搜索引擎已收录其内容,为其带来了初步的可见度。
随着口碑的积累,源码网在业界建立了良好的合作关系。在年3月日,它与国内知名网站源码之家等大型站点实现了友好的合作,共享资源,共同进步。
随后,网站的流量和影响力持续增长。5月日,源码网的域名PR值提升至2,每日独立访问用户数突破万,日均页面浏览量(PV)达到了1万,显示出强劲的发展势头。
在这一年中,源码网不断寻求与业界领先者的合作。6月日,它与国内著名的CMS程序公司携手,共同推广优秀程序,并进行了一次改版,以提升用户体验和内容质量。
改版后的源码网在7月1日正式上线,标志着其发展进入了一个新的阶段。自那时起,源码网以其快速且稳健的发展步伐,持续为用户提供优质的源码资源,至今仍保持着强劲的发展态势。
信号量(Semaphore)从入门到源码精通
Semaphore是一个用于同步的工具类,在并发编程中扮演重要角色。PV操作是Semaphore的核心操作,P代表获取许可,V代表释放许可。P操作会检查许可是否可用,若可用则获取并返回,否则阻塞直到许可可用;V操作则释放一个许可。
Semaphore的使用场景主要涉及线程间的同步,比如在资源有限的情况下控制多个线程对资源的访问。例如,当一个队列只允许一定数量的线程同时访问时,可以使用Semaphore来限制队列访问的线程数量。
使用Semaphore的方式是通过构造方法创建实例,然后使用acquire和release方法来控制许可的获取和释放。acquire方法接受一个参数,表示需要获取的许可数量,默认为1,如果当前可用许可数不足,线程将阻塞直到许可可用。release方法则释放指定数量的许可,通常为1。
要深入理解Semaphore源码,建议从AQS(AbstractQueuedSynchronizer)的基础开始。AQS提供了对同步器的基本抽象,Semaphore正是基于AQS实现的一种同步工具。
对于具体源码分析,可以重点关注Semaphore的构造方法、获取锁方法(acquire)以及释放锁方法(release)。在源码中,acquire方法通过调用tryAcquireShared方法尝试获取许可,如果成功则返回true,否则阻塞直到许可可用。release方法则简单地调用releaseShared方法释放一个许可。
深入学习Semaphore和并发编程,可以参考内核技术中文网的相关资源。该网站提供了一些学习资料和交流社区,包括Linux内核源码学习路线、视频教程、电子书以及实战项目和代码等。此外,网站还定期更新内核技术资料包,供学习者免费获取。