使用向量数据库pinecone构建应用04:混合搜索 Hybrid Search

news2024/9/19 8:03:20

Building Applications with Vector Databases

下面是这门课的学习笔记:https://www.deeplearning.ai/short-courses/building-applications-vector-databases/

Learn to create six exciting applications of vector databases and implement them using Pinecone.

Build a hybrid search app that combines both text and images for improved multimodal search results.

Learn how to build an app that measures and ranks facial similarity.

文章目录

  • Building Applications with Vector Databases
  • Lesson 4 - Hybrid Search
      • Import the Needed Packages
      • Setup Pinecone
      • Load the Dataset
      • Create the Sparse Vector Using BM25
      • Create the Dense Vector Using CLIP
      • Create Embeddings Using Sparse and Dense
      • Run Your Query
      • Scaling the Hybrid Search
      • 1. More Dense
      • 2. More Sparse
      • More Dense or More Sparse?

Lesson 4 - Hybrid Search

参考:https://docs.pinecone.io/docs/hybrid-search

混合查询是一种在搜索过程中同时结合语义搜索(semantic search)和关键词搜索(keyword search)的方法。在这种查询中,搜索引擎会同时考虑文本的语义信息以及关键词的匹配程度,以提供更相关的搜索结果。

具体来说,在混合查询中,语义搜索通常使用文本的语义信息来计算相似度,例如使用文本嵌入向量(dense embeddings)来表示文本的语义信息。这种方法可以捕获文本之间的语义相似度,即使查询文本与文档之间没有直接的关键词匹配,也能够找到相关的结果。但是,对于领域外的查询(out-of-domain queries),语义搜索的结果可能不够准确或不够相关。

为了提高搜索结果的相关性,混合查询还结合了关键词搜索的结果。关键词搜索通常根据关键词的匹配程度来进行检索,例如使用词频-逆文档频率(TF-IDF)等方法。这种方法可以捕获文本中关键词的匹配程度,即使文本之间的语义相似度较低,但如果它们包含相同的关键词,则可能被认为是相关的。

通过在查询过程中同时使用语义搜索和关键词搜索,混合查询可以更全面地考虑文本的相关性,从而提供更相关的搜索结果。这种方法特别适用于处理领域外查询或文本之间语义相似度较低的情况,可以改善搜索结果的质量和相关性。

在这里插入图片描述

Import the Needed Packages

import warnings
warnings.filterwarnings('ignore')
from datasets import load_dataset
from pinecone_text.sparse import BM25Encoder
from pinecone import Pinecone, ServerlessSpec
from DLAIUtils import Utils

from sentence_transformers import SentenceTransformer
from tqdm.auto import tqdm
import torch
import os
utils = Utils()
PINECONE_API_KEY = utils.get_pinecone_api_key()

Setup Pinecone

device = 'cuda' if torch.cuda.is_available() else 'cpu'
print(device)

utils = Utils()
INDEX_NAME = utils.create_dlai_index_name('dl-ai')

pinecone = Pinecone(api_key=PINECONE_API_KEY)

if INDEX_NAME in [index.name for index in pinecone.list_indexes()]:
  pinecone.delete_index(INDEX_NAME)
pinecone.create_index(
  INDEX_NAME,
  dimension=512,
  metric="dotproduct",
  spec=ServerlessSpec(cloud='aws', region='us-west-2')
)
index = pinecone.Index(INDEX_NAME)

其中Utils的包如下

import os
import sys
from dotenv import load_dotenv, find_dotenv

class Utils:
  def __init__(self):
    pass
  
  def create_dlai_index_name(self, index_name):
    openai_key = ''
    if self.is_colab(): # google colab
      from google.colab import userdata
      openai_key = userdata.get("OPENAI_API_KEY")
    else: # jupyter notebook
      openai_key = os.getenv("OPENAI_API_KEY")
    return f'{index_name}-{openai_key[-36:].lower().replace("_", "-")}'
    
  def is_colab(self):
    return 'google.colab' in sys.modules

  def get_openai_api_key(self):
    _ = load_dotenv(find_dotenv())
    return os.getenv("OPENAI_API_KEY")
    
  def get_pinecone_api_key(self):
    _ = load_dotenv(find_dotenv())
    return os.getenv("PINECONE_API_KEY")

Load the Dataset

从huggingface上下载数据集

fashion = load_dataset(
    "ashraq/fashion-product-images-small",
    split="train"
)
fashion

在这段代码中,split 参数用于指定加载数据集的哪个部分。在机器学习中,数据集通常被分为几个不同的部分,比如训练集(train)、验证集(validation)和测试集(test)。这些部分用于不同的目的,例如训练模型、调整超参数以及评估模型性能。

在这个特定的例子中,split="train" 表示加载数据集中的训练集部分。这意味着加载的数据集将包含用于训练模型的数据样本。通常,训练集用于拟合模型的参数,使其能够从数据中学习并进行预测。

Output

Dataset({
    features: ['id', 'gender', 'masterCategory', 'subCategory', 'articleType', 'baseColour', 'season', 'year', 'usage', 'productDisplayName', 'image'],
    num_rows: 44072
})

输出image图片测试一下

images = fashion['image']
metadata = fashion.remove_columns('image') # 去掉image列
images[900]

Output

在这里插入图片描述

展示metadata的前五行:

metadata = metadata.to_pandas()
metadata.head() # 用于返回数据集的前几行,默认情况下是前五行

Output

在这里插入图片描述

Create the Sparse Vector Using BM25

在这里插入图片描述

chatGPT对BM25的介绍

BM25(Best Matching 25)是一种用于信息检索的概率模型,是根据概率论原理和统计学原理设计的。它是 BM 系列算法中的一种,通常用于在大规模文本数据集中执行全文搜索和相关性排序。BM25 最初是由Robertson 等人于 1994 年提出的,并且被广泛应用于搜索引擎和文档检索系统中。

BM25 的主要思想是衡量查询词与文档之间的相关性,并根据相关性对文档进行排序。它考虑了查询词的频率、文档的长度以及文档集合中包含查询词的文档数量等因素,从而更好地衡量文档的相关性。与传统的向量空间模型(如 TF-IDF)相比,BM25 能够更好地处理长文档、稀疏查询以及文档长度不均匀的情况。

BM25 模型的计算公式包括多个参数,如查询词频率、文档长度、文档集合的平均长度等。这些参数可以根据具体的应用场景和数据集进行调整,以获得更好的搜索性能。

总的来说,BM25 是一种用于信息检索的强大模型,广泛应用于各种搜索引擎和文档检索系统中,能够有效地提高搜索结果的质量和相关性。

bm25 = BM25Encoder()
bm25.fit(metadata['productDisplayName'])
metadata['productDisplayName'][0]

Output

'Turtle Check Men Navy Blue Shirt'
bm25.encode_queries(metadata['productDisplayName'][0])
bm25.encode_documents(metadata['productDisplayName'][0])

在这段代码中,bm25.encode_queries(metadata['productDisplayName'][0])bm25.encode_documents(metadata['productDisplayName'][0]) 是使用 BM25 编码器对查询和文档进行编码的操作。

具体来说:

  • bm25.encode_queries(metadata['productDisplayName'][0]):这个方法用于对查询进行编码。在信息检索任务中,查询通常是用户输入的搜索词或短语。这个方法将输入的查询文本编码成 BM25 编码器所能理解的形式,以便后续可以与已编码的文档进行比较,找到与查询最相关的文档。

  • bm25.encode_documents(metadata['productDisplayName'][0]):这个方法用于对文档进行编码。在信息检索任务中,文档通常是待检索的数据项,例如产品描述、文章内容等。这个方法将输入的文档文本编码成 BM25 编码器所能理解的形式,以便后续可以与已编码的查询进行比较,找到与查询最相关的文档。

总的来说,这两个方法都是将文本数据使用 BM25 编码器进行编码的操作,以便在信息检索任务中进行相关性匹配和排序。encode_queries() 方法用于对查询进行编码,而 encode_documents() 方法用于对文档进行编码。

Output

{'indices': [23789636,
  1830646559,
  632192512,
  931643408,
  3905155331,
  3828986392],
 'values': [0.4449638258432887,
  0.4449638258432887,
  0.4449638258432887,
  0.4449638258432887,
  0.4449638258432887,
  0.4449638258432887]}

Create the Dense Vector Using CLIP

在这里插入图片描述

model = SentenceTransformer('sentence-transformers/clip-ViT-B-32', 
    device=device)
model
dense_vec = model.encode([metadata['productDisplayName'][0]])
dense_vec.shape

Output

(1, 512)

len(fashion)

Output

44072

Create Embeddings Using Sparse and Dense

在这里插入图片描述

(Note: fashion_data_num = 1000): In this lab, we've initially set fashion_data_num to 1000 for speedier results, allowing you to observe the outcomes faster. Once you've done an initial run, consider increasing this value. You'll likely notice better and more relevant results.

batch_size = 100
fashion_data_num = 1000

for i in tqdm(range(0, min(fashion_data_num,len(fashion)), batch_size)):
    # find end of batch
    i_end = min(i+batch_size, len(fashion))
    # extract metadata batch
    meta_batch = metadata.iloc[i:i_end]
    meta_dict = meta_batch.to_dict(orient="records")
    # concatinate all metadata field except for id and year to form a single string
    # 这句话的理解请看下面的解释
    meta_batch = [" ".join(x) for x in meta_batch.loc[:, ~meta_batch.columns.isin(['id', 'year'])].values.tolist()]
    # extract image batch
    img_batch = images[i:i_end]
    # create sparse BM25 vectors
    sparse_embeds = bm25.encode_documents([text for text in meta_batch])
    # create dense vectors
    dense_embeds = model.encode(img_batch).tolist()
    # create unique IDs
    ids = [str(x) for x in range(i, i_end)]

    upserts = []
    # loop through the data and create dictionaries for uploading documents to pinecone index
    for _id, sparse, dense, meta in zip(ids, sparse_embeds, dense_embeds, meta_dict):
        upserts.append({
            'id': _id,
            'sparse_values': sparse,
            'values': dense,
            'metadata': meta
        })
    # upload the documents to the new hybrid index
    index.upsert(upserts)

# show index description after uploading the documents
index.describe_index_stats()

上述代码的解释

meta_batch.loc[:, ~meta_batch.columns.isin(['id', 'year'])]:这部分代码首先使用 .loc[] 方法从 DataFrame 中选择所有行和除了’id’和’year’列以外的其他列。~meta_batch.columns.isin(['id', 'year']) 用于创建一个布尔值的 Series,表示除了’id’和’year’列以外的其他列。然后,meta_batch.loc[:, ~meta_batch.columns.isin(['id', 'year'])] 使用这个布尔值的 Series 进行列的选择。

在这个上下文中,~ 是按位取反运算符。在 Pandas 中,它用于对布尔值 Series 或条件表达式的结果进行逐元素取反。

具体来说,~meta_batch.columns.isin(['id', 'year']) 创建了一个布尔值 Series,其中包含了与 DataFrame 列名是否包含在 [‘id’, ‘year’] 列表中相对应的布尔值。然后,~ 运算符对这个布尔值 Series 进行逐元素取反,即将 True 变为 False,将 False 变为 True。这样,最终得到的布尔值 Series 中,对于原始 DataFrame 中的列名中包含在 [‘id’, ‘year’] 中的列,其值为 False,否则为 True。这就实现了对除了’id’和’year’列以外的其他列进行选择。

Output

{'dimension': 512,
 'index_fullness': 0.0,
 'namespaces': {'': {'vector_count': 900}},
 'total_vector_count': 900}

Run Your Query

query data参考:https://docs.pinecone.io/docs/query-data

参考:

query = "dark blue french connection jeans for men"

sparse = bm25.encode_queries(query)
dense = model.encode(query).tolist() 

result = index.query(
    top_k=14,
    vector=dense,
    sparse_vector=sparse,
    include_metadata=True
)

imgs = [images[int(r["id"])] for r in result["matches"]]
imgs

在这段代码中:

  • vector 参数:表示稠密向量(dense vector),通常用于传递由模型生成的文本嵌入向量(dense embeddings)。在这里,dense 变量包含了模型对查询文本 query 生成的稠密嵌入向量。

  • sparse_vector 参数:表示稀疏向量(sparse vector),通常用于传递由 BM25 编码器生成的查询编码(query encoding)。在这里,sparse 变量包含了 BM25 编码器对查询文本 query 生成的稀疏编码。这种编码形式通常用于在基于 BM25 的索引中执行检索操作。

综合起来,这两个参数分别用于传递模型生成的稠密嵌入向量和 BM25 编码器生成的稀疏编码,以便于在索引中执行检索操作,并返回与查询文本相关的最相关的文档。

Output

[<PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=60x80>,
 <PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=60x80>,
 <PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=60x80>,
 <PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=60x80>,
 <PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=60x80>,
 <PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=60x80>,
 <PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=60x80>,
 <PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=60x80>,
 <PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=60x80>,
 <PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=60x80>]

display结果

from IPython.core.display import HTML
from io import BytesIO
from base64 import b64encode

# function to display product images
def display_result(image_batch):
    figures = []
    for img in image_batch:
        b = BytesIO()
        img.save(b, format='png')
        figures.append(f'''
            <figure style="margin: 5px !important;">
              <img src="data:image/png;base64,{b64encode(b.getvalue()).decode('utf-8')}" style="width: 90px; height: 120px" >
            </figure>
        ''')
    return HTML(data=f'''
        <div style="display: flex; flex-flow: row wrap; text-align: center;">
        {''.join(figures)}
        </div>
    ''')
display_result(imgs)

Output

在这里插入图片描述

Scaling the Hybrid Search

def hybrid_scale(dense, sparse, alpha: float):
    """Hybrid vector scaling using a convex combination

    alpha * dense + (1 - alpha) * sparse

    Args:
        dense: Array of floats representing
        sparse: a dict of `indices` and `values`
        alpha: float between 0 and 1 where 0 == sparse only
               and 1 == dense only
    """
    if alpha < 0 or alpha > 1:
        raise ValueError("Alpha must be between 0 and 1")
    # scale sparse and dense vectors to create hybrid search vecs
    hsparse = {
        'indices': sparse['indices'],
        'values':  [v * (1 - alpha) for v in sparse['values']]
    }
    hdense = [v * alpha for v in dense]
    return hdense, hsparse

1. More Dense

question = "dark blue french connection jeans for men"
#Closer to 0==more sparse, closer to 1==more dense
hdense, hsparse = hybrid_scale(dense, sparse, alpha=1)
result = index.query(
    top_k=6,
    vector=hdense,
    sparse_vector=hsparse,
    include_metadata=True
)
imgs = [images[int(r["id"])] for r in result["matches"]]
display_result(imgs)


Output

在这里插入图片描述

for x in result["matches"]:
    print(x["metadata"]['productDisplayName'])

Output

Peter England Men Party Blue Jeans
John Miller Men Reglur Black Trousers
Lee Men Blue Chicago Fit Jeans
Locomotive Men Washed Blue Jeans
Lee Men Blue Chicago Fit Jeans
Gini and Jony Boys Solid Black Jeans
Peter England Men Black Jeans
Tokyo Talkies Women Navy Slim Fit Jeans
Jealous 21 Women's Aaren Black Jegging
John Miller Men Solid Type Black Trousers

2. More Sparse

question = "dark blue french connection jeans for men"
#Closer to 0==more sparse, closer to 1==more dense
hdense, hsparse = hybrid_scale(dense, sparse, alpha=0)
result = index.query(
    top_k=6,
    vector=hdense,
    sparse_vector=hsparse,
    include_metadata=True
)
imgs = [images[int(r["id"])] for r in result["matches"]]
display_result(imgs)

Output

在这里插入图片描述

for x in result["matches"]:
    print(x["metadata"]['productDisplayName'])

Output

French Connection Men Maroon T-shirt
Lee Men Blue Chicago Fit Jeans
Peter England Men Party Blue Jeans
Lee Men Blue Chicago Fit Jeans
Denizen Women Blue Jeans
French Connection Women Beige Handbag
Jealous 21 Women Washed Blue Jeans
Peter England Men Black Jeans
Peter England Men Party Black Jeans
Gini and Jony Boys Solid Black Jeans

More Dense or More Sparse?

question = "dark blue french connection jeans for men"
#Closer to 0==more sparse, closer to 1==more dense
hdense, hsparse = hybrid_scale(dense, sparse, alpha=0.5)
result = index.query(
    top_k=6,
    vector=hdense,
    sparse_vector=hsparse,
    include_metadata=True
)
imgs = [images[int(r["id"])] for r in result["matches"]]
display_result(imgs)

Output

在这里插入图片描述

for x in result["matches"]:
    print(x["metadata"]['productDisplayName'])

Output

Peter England Men Party Blue Jeans
John Miller Men Reglur Black Trousers
Lee Men Blue Chicago Fit Jeans
Locomotive Men Washed Blue Jeans
Lee Men Blue Chicago Fit Jeans
Gini and Jony Boys Solid Black Jeans
Peter England Men Black Jeans
Tokyo Talkies Women Navy Slim Fit Jeans
Jealous 21 Women's Aaren Black Jegging
John Miller Men Solid Type Black Trousers

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1471530.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

啤酒:精酿啤酒与烧烤的热烈碰撞

在夏日的傍晚&#xff0c;烧烤与啤酒总是绝配。当Fendi Club啤酒遇上烧烤&#xff0c;它们将为我们带来一场热烈的美味碰撞。 Fendi Club啤酒&#xff0c;以其醇厚的口感和淡淡的麦芽香气而著称。这款啤酒在酿造过程中采用了特别的工艺&#xff0c;使得酒体呈现出诱人的金黄色&…

【JVM】线上一次fullGC排查思路

fullGC问题背景 监控告警发现&#xff0c;今天开始我们线上应用频繁出现fullGC&#xff0c;并且每次出现后磁盘都会被占满 查看监控 查看监控发现FULLGC的机器均为同一个机房的集器&#xff0c;并且该机房有线上error报错&#xff0c;数据库监控对应的时间点也有异常&#x…

如何在Linux搭建MinIO服务并实现无公网ip远程访问内网管理界面

文章目录 前言1. Docker 部署MinIO2. 本地访问MinIO3. Linux安装Cpolar4. 配置MinIO公网地址5. 远程访问MinIO管理界面6. 固定MinIO公网地址 前言 MinIO是一个开源的对象存储服务器&#xff0c;可以在各种环境中运行&#xff0c;例如本地、Docker容器、Kubernetes集群等。它兼…

Linux系统中前后端分离项目部署指南

目录 一.nginx安装以及字启动 解压nginx 一键安装4个依赖 安装nginx 启动 nginx 服务 开放端口号 并且在外部访问 设置nginx自启动 二.配置负载均衡 1.配置一个tomact 修改端口号 8081端口号 2.配置负载均衡 ​编辑 三.部署前后端分离项目 1.项目部署后端 ​编辑…

上海亚商投顾:沪指8连阳重新站上3000点 全市场逾百股涨停

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 一.市场情绪 沪指2月23日继续反弹&#xff0c;成功收复3000点大关&#xff0c;录得8连阳走势。AI概念持续活跃&#xff0c…

springboot219基于SpringBoot的网络海鲜市场系统的设计与实现

网络海鲜市场系统的设计与实现 摘 要 计算机网络发展到现在已经好几十年了&#xff0c;在理论上面已经有了很丰富的基础&#xff0c;并且在现实生活中也到处都在使用&#xff0c;可以说&#xff0c;经过几十年的发展&#xff0c;互联网技术已经把地域信息的隔阂给消除了&…

日志系统项目(2)项目实现(实用工具类、日志等级类、日志消息类、日志格式化输出类)

前面的文章中我们讲述了日志系统项目的前置知识点&#xff0c;再本文中我们将开始日志项目的细节实现。 日志系统框架设计 本项目实现的是一个多日志器日志系统&#xff0c;主要实现的功能是让程序员能够轻松的将程序运行日志信息落地到指定的位置&#xff0c;且支持同步与异…

20240223-2092.查找所有有秘密的人

题目要求 给你一个整数 n&#xff0c;表示有 n 个人&#xff0c;编号从 0 到 n - 1。你还给你一个 0 索引的二维整数数组 meetings&#xff0c;其中 meetings[i] [xi, yi, timei] 表示 xi 和 yi 在 timei 有一个会议。一个人可以同时参加多个会议。最后&#xff0c;给你一个整…

【Flutter/Android】运行到安卓手机上一直卡在 Running Gradle task ‘assembleDebug‘... 的终极解决办法

方法步骤简要 查看你的Flutter项目需要什么版本的 Gradle 插件&#xff1a; 下载这个插件&#xff1a; 方法一&#xff1a;浏览器输入&#xff1a;https://services.gradle.org/distributions/gradle-7.6.3-all.zip 方法二&#xff1a;去Gradle官网找对应的版本&#xff1a;h…

个人机器人课程中最棘手的问题

爱好 22年&#xff0c;观点。当然现在自动驾驶研究路径已经不是22年的模式了。 23年&#xff0c;观点&#xff1a; 一个热爱自动驾驶但妥妥外行之人的思考-2023-CSDN博客 前篇 不合格机器人工程讲师为何不分享成功的案例-CSDN博客 在这篇文章中&#xff0c;有一段&#x…

Maya笔记 设置工作目录

Maya会把素材场景等自动保存在工作目录里&#xff0c;我们可以自己定义工作目录 步骤1 创建workspace.mel文件 文件/设置项目 ——>选择一个文件夹&#xff0c;点击设置——>创建默认工作区 这一个后&#xff0c;可以在文件夹里看到.mel文件 步骤2 自动创建文件夹…

进程的学习

进程基本概念: 1.进程: 程序&#xff1a;存放在外存中的一段数据组成的文件 进程&#xff1a;是一个程序动态执行的过程,包括进程的创建、进程的调度、进程的消亡 2.进程相关命令: 1.top 动态查看当前系统中的所有进程信息&#xff08;根据CPU占用率排序&#xf…

python中那些双下划线开头得函数和变量

嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! python更多源码/资料/解答/教程等 点击此处跳转文末名片免费获取 Python中下划线—完全解读 Python 用下划线作为变量前缀和后缀指定特殊变量 _xxx 不能用from module import *导入 __xxx__ 系统定义名字 __xxx 类中的私有变量…

PC蓝牙通信

一、基本概念 蓝牙用于不同设备之间建立联系。利用无线电波在短距离间发送数据&#xff0c;wifi是在路由器跟设备间传输数据。蓝牙是在设备之间。蓝牙跟wifi同在2.4GHz频率下工作。蓝牙信号比wifi信号弱很多功率仅为1mW。传输距离有限。最初的1.0版本传输距离只有10m。现在5.0…

快速启动-后台管理系统

目录 Gitee人人开源 后端快速启动 1.clone仓库到本地 2.初始化数据库 3.更改数据库连接 4.启动项目验证 前端快速启动 1.克隆仓库 2.vsCode打开 3.控制台npm install 4.验证测试 时代已然不同&#xff0c;后台管理也可以使用脚手架方式快速启动。 Gitee人人开源 地…

JavaWeb——006MYSQL(DDLDML)

这里写目录标题 数据库开发-MySQL首先来了解一下什么是数据库。1. MySQL概述1.1 安装1.1.1 版本1.1.2 安装1.1.3 连接1.1.4 企业使用方式(了解) 1.2 数据模型1.3 SQL简介1.3.1 SQL通用语法1.3.2 分类 2. 数据库设计-DDL2.1 项目开发流程2.2 数据库操作2.2.1 查询数据库2.2.2 创…

Linux编程 1.2 系统文件IO- 使用

系统文件IO使用 1、open函数 #include<sys/types.h> #include<sys/stat.h> #include<fcntl.h> int open(const char* pathname,int flags); int open(const char* pathname,int flags,mode_t mode); 返回&#xff1a;若成功为文件描述符&#xff0c;若出错…

操作系统——处理机调度

文章目录 进程调度0.概念1.调度分类高级调度低级调度中级调度七状态模型调度对比 2.进程调度进程调度的时机进程调度的方式进程的切换方式调度器/调度程序闲逛进程 3. 调度算法的评价指标CPU利用率系统吞吐量周转时间等待时间响应时间 4. 调度算法先来先服务(FCFS)短作业优先(S…

微服务基础环境搭建

一.创建父工程 用于聚合其他微服务模块 1 新建 Maven 项目 JDK8Maven 项目Web 2 项目设置 编码的选择 UTF8JDK 版本的选择 3 删除 src 目录 4 配置父级 pom.xml SpringBoot&#xff1a;模块探究之spring-boot-dependencies-CSDN博客 子模块能够依赖当前父级 pom.xml 配置 【My…

LDR6020双盲插音频随便插充电听歌随便插

随着智能手机的普及和功能的日益丰富&#xff0c;手机已经成为我们日常生活中不可或缺的一部分。音乐、电影、游戏等娱乐内容更是丰富了手机的使用体验。而在这其中&#xff0c;音频转接器的作用愈发凸显&#xff0c;特别是在边听边充的场景下&#xff0c;一款高效且便捷的手机…