【UEFI实战】UEFI图形显示(字符输出)

news2024/7/31 20:55:58

HII Font

接下来介绍EFI_HII_FONT_PROTOCOL,它在UEFI代码中完成了字符到像素的转换,本节主要介绍这个转换关系,它的实现代码在edk2\MdeModulePkg\Universal\HiiDatabaseDxe\HiiDatabaseDxe.inf中,除了EFI_HII_FONT_PROTOCOL,这个模块还实现了很多其它的Protocol,后面用到的时候也会介绍,所以HiiDatabaseDxe.inf这个模块并不仅仅是字体的基础,而是UEFI的人机接口(Human Interface Infrastructure)的基础模块。

结构体组织

下图是HII数据库基础中字体相关的结构体:

在这里插入图片描述

从图中可以看出,字体分为两种,一种是普通版本另一种是简化版本,本节将分别介绍。

最左边的结构体HII_DATABASE_PRIVATE_DATA是HII数据库模块的基础结构体,对应字体部分:

HII_DATABASE_PRIVATE_DATA  mPrivate = {
  // 前略
  LIST_ENTRY                             DatabaseList;	// 所有HII资源都放在这个列表中,其中就包括字体和简单字体
  // 前略
  {
    HiiStringToImage,
    HiiStringIdToImage,
    HiiGetGlyph,
    HiiGetFontInfo
  },
  // 中略
  LIST_ENTRY                             FontInfoList; // global font info list
  // 后略
};

其中包含有一个Protocol,对应的是EFI_HII_FONT_PROTOCOL,其接口:

///
/// The protocol provides the service to retrieve the font informations.
///
struct _EFI_HII_FONT_PROTOCOL {
  EFI_HII_STRING_TO_IMAGE       StringToImage;
  EFI_HII_STRING_ID_TO_IMAGE    StringIdToImage;
  EFI_HII_GET_GLYPH             GetGlyph;
  EFI_HII_GET_FONT_INFO         GetFontInfo;
};

这个将在后面介绍。

还包含一个数据库列表DatabaseList,它包含了所有HII的资源,其中就包括注册了的字体部分内容。以及一个字体信息列表FontInfoList,指向额外的结构体HII_GLOBAL_FONT_INFO,它包含了普通字体需要使用到的数据,而简单字体并不需要这部分。因为是一个列表,所以表示UEFI可以支持多种字体信息。

HII_GLOBAL_FONT_INFO结构体如下:

typedef struct _HII_GLOBAL_FONT_INFO {
  UINTN                        Signature;
  LIST_ENTRY                   Entry;
  HII_FONT_PACKAGE_INSTANCE    *FontPackage;
  UINTN                        FontInfoSize;
  EFI_FONT_INFO                *FontInfo;
} HII_GLOBAL_FONT_INFO;

重要的是后面的三个成员,表示两类信息,FontPackageFontInfo。其中包含的字体和字形的所有信息。关于字体(Font)和字形(Glyph)需要特别说明:

  • 字体是所有字符的整体表现形式,比如楷体、宋体等,表示的是一个整体的概念。
  • 字形是每个字符的样子,会真正涉及到UEFI下如何绘制一个字符。
  • 所有的字形组成了一种字体样式。

下面对字体信息相关的结构体做简单的介绍。首先是描述字体本身的结构体:

typedef struct {
  EFI_HII_FONT_STYLE    FontStyle;  ///< 一个枚举值,表示的是粗体、斜体等
  UINT16                FontSize;   ///< character cell height in pixels
  CHAR16                FontName[1];///< 字体名,这个在文本编辑器里面更容易看到
} EFI_FONT_INFO;

当前支持的字体类型(对应FontStyle):

//
// Value for font style
//
#define EFI_HII_FONT_STYLE_NORMAL     0x00000000
#define EFI_HII_FONT_STYLE_BOLD       0x00000001
#define EFI_HII_FONT_STYLE_ITALIC     0x00000002
#define EFI_HII_FONT_STYLE_EMBOSS     0x00010000
#define EFI_HII_FONT_STYLE_OUTLINE    0x00020000
#define EFI_HII_FONT_STYLE_SHADOW     0x00040000
#define EFI_HII_FONT_STYLE_UNDERLINE  0x00080000
#define EFI_HII_FONT_STYLE_DBL_UNDER  0x00100000

然后是单个字形的结构体:

typedef struct _HII_GLYPH_INFO {
  UINTN                 Signature;
  LIST_ENTRY            Entry;
  CHAR16                CharId;
  EFI_HII_GLYPH_INFO    Cell;
} HII_GLYPH_INFO;

这里有一个列表Entry是因为字形本来就需要有很多个,CharId表示的是字符编码值,通过一个CHAR16理论上能够覆盖所有常用语言的字符,最后的Cell结构体如下:

typedef struct _EFI_HII_GLYPH_INFO {
  UINT16    Width;
  UINT16    Height;
  INT16     OffsetX;
  INT16     OffsetY;
  INT16     AdvanceX;
} EFI_HII_GLYPH_INFO;

这些值与字符的对应关系图如下所示:

在这里插入图片描述

剩下的结构体EFI_HII_FONT_PACKAGE_HDRHII_FONT_PACKAGE_INSTANCE主要也是上述字体和字形结构体的组织形式的描述。

需要注意,到这里为止仅仅是描述了字体和字形相关的结构,并没有涉及到真实地描述从字符到EFI_GRAPHICS_OUTPUT_PROTOCOL能够显示的图形之间的数据转换模型,这部分内容隐藏在前面的某个结构体成员中,主要是GlyphBlock,作为结构体成员它只是一个指针,通过它我们可以找到某个字符对应的图像显示数据,所以对于它的设计是比较重要的,因为我们需要快速地找到字符对应的图像。

实际上由于使用的限制,字体和字形的应用在UEFI下并不是很重要,UEFI只要能够清楚地表示字符就可以了,为此就有了简化版本的字体,它的结构相当简单,重要的是下面的结构体:

///
/// A simplified font package consists of a font header
/// followed by a series of glyph structures.
///
typedef struct _EFI_HII_SIMPLE_FONT_PACKAGE_HDR {
  EFI_HII_PACKAGE_HEADER    Header;
  UINT16                    NumberOfNarrowGlyphs;
  UINT16                    NumberOfWideGlyphs;
  // EFI_NARROW_GLYPH       NarrowGlyphs[];
  // EFI_WIDE_GLYPH         WideGlyphs[];
} EFI_HII_SIMPLE_FONT_PACKAGE_HDR;

虽然结构体中包含了HDR的字样,但是从上面的代码中也可以看出来,它之后直接就接了所有的数据,通过这些数据可以直接将字符转换成可输出的图形。后续的数据包含两个部分,分别对应窄体字符和宽体字符,实际就是对应8x19和16x19两种形式,以窄体为例,一个字符对应到的数据如下:

typedef struct {
  CHAR16                 UnicodeWeight;
  UINT8                  Attributes;
  UINT8                  GlyphCol1[EFI_GLYPH_HEIGHT];	// EFI_GLYPH_HEIGHT = 19
} EFI_NARROW_GLYPH;

UnicodeWeight对应到字符的计算机表示,Attributes表示字符的属性,目前支持的值:

///
/// Contents of EFI_NARROW_GLYPH.Attributes.
///@{
#define EFI_GLYPH_NON_SPACING  0x01
#define EFI_GLYPH_WIDE         0x02
#define EFI_GLYPH_HEIGHT       19
#define EFI_GLYPH_WIDTH        8
///@}

GlyphCol1实际上是一个位图,每一个比特位表示了是否需要绘制该像素。在【UEFI实战】UEFI图形显示(从像素到字符)的代码示例中,使用了一个二维数组来表示是否需要绘制对应像素:

  UINT8 BltIndex[NARROW_HEIGHT * NARROW_WIDTH] = {
    0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 1, 0, 0, 0, 0,
    0, 0, 1, 1, 1, 0, 0, 0,
    0, 1, 1, 0, 1, 1, 0, 0,
    1, 1, 0, 0, 0, 1, 1, 0,
    1, 1, 0, 0, 0, 1, 1, 0,
    1, 1, 0, 0, 0, 1, 1, 0,
    1, 1, 0, 0, 0, 1, 1, 0,
    1, 1, 1, 1, 1, 1, 1, 0,
    1, 1, 0, 0, 0, 1, 1, 0,
    1, 1, 0, 0, 0, 1, 1, 0,
    1, 1, 0, 0, 0, 1, 1, 0,
    1, 1, 0, 0, 0, 1, 1, 0,
    0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0
  };

显然这里的方式比上面的代码更加的简单和紧凑。

开源的EDK代码就是使用了这种简化的字体形式来表示字符。

字符到字形的表示

注册字符到字形的描述数据,涉及到HiiDataBase的一个接口:

///
/// Database manager for HII-related data structures.
///
struct _EFI_HII_DATABASE_PROTOCOL {
  EFI_HII_DATABASE_NEW_PACK             NewPackageList;
  // 后略
};

这里不写它的函数原型,而是直接关注对于字体来说其实现中最重要的的部分,其调用流程如下:

HiiNewPackageList
AddPackages
InsertFontPackage
InsertSimpleFontPackage

字体注册数据的位置在前面介绍过的GraphicsConsoleDxe模块中:

  //
  // Add 4 bytes to the header for entire length for HiiAddPackages use only.
  //
  //    +--------------------------------+ <-- Package
  //    |                                |
  //    |    PackageLength(4 bytes)      |
  //    |                                |
  //    |--------------------------------| <-- SimplifiedFont
  //    |                                |
  //    |EFI_HII_SIMPLE_FONT_PACKAGE_HDR |
  //    |                                |
  //    |--------------------------------| <-- Location
  //    |                                |
  //    |     gUsStdNarrowGlyphData      |
  //    |                                |
  //    +--------------------------------+

  PackageLength = sizeof (EFI_HII_SIMPLE_FONT_PACKAGE_HDR) + mNarrowFontSize + 4;
  Package       = AllocateZeroPool (PackageLength);
  ASSERT (Package != NULL);

  WriteUnaligned32 ((UINT32 *)Package, PackageLength);
  SimplifiedFont                       = (EFI_HII_SIMPLE_FONT_PACKAGE_HDR *)(Package + 4);
  SimplifiedFont->Header.Length        = (UINT32)(PackageLength - 4);
  SimplifiedFont->Header.Type          = EFI_HII_PACKAGE_SIMPLE_FONTS;
  SimplifiedFont->NumberOfNarrowGlyphs = (UINT16)(mNarrowFontSize / sizeof (EFI_NARROW_GLYPH));

  Location = (UINT8 *)(&SimplifiedFont->NumberOfWideGlyphs + 1);
  CopyMem (Location, gUsStdNarrowGlyphData, mNarrowFontSize);

  //
  // Add this simplified font package to a package list then install it.
  //
  mHiiHandle = HiiAddPackages (
                 &mFontPackageListGuid,
                 NULL,
                 Package,
                 NULL
                 );
  ASSERT (mHiiHandle != NULL);
  FreePool (Package);

具体的数据全部存放在数组gUsStdNarrowGlyphData中,它位于一个独立的文件edk2\MdeModulePkg\Universal\Console\GraphicsConsoleDxe\LaffStd.c中:

EFI_NARROW_GLYPH  gUsStdNarrowGlyphData[] = {
  //
  // Unicode glyphs from 0x20 to 0x7e are the same as ASCII characters 0x20 to 0x7e
  //
  { 0x0020,                                     0x00, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
  },
  { 0x0021,                                     0x00, { 0x00, 0x00, 0x00, 0x18, 0x3C, 0x3C, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00 }
  },
  // 后面还有很多的数据

实际上因为英文只需要支持ASCII就可以了,再加上一些特定的图形,所以最终的数据也不会太多。

EFI_HII_FONT_PROTOCOL

下面介绍字体的操作函数,对应的就是EFI_HII_FONT_PROTOCOL,其形式如下:

///
/// The protocol provides the service to retrieve the font informations.
///
struct _EFI_HII_FONT_PROTOCOL {
  EFI_HII_STRING_TO_IMAGE       StringToImage;
  EFI_HII_STRING_ID_TO_IMAGE    StringIdToImage;
  EFI_HII_GET_GLYPH             GetGlyph;
  EFI_HII_GET_FONT_INFO         GetFontInfo;
};

前面两个都是直接的显示函数,不同的是StringToImage直接输出字符串,而StringIdToImage根据uni文件创建的数据,通过StringId来找到字符串并输出。后两个函数则获取字体和字形的信息。【UEFI实战】UEFI图形显示(从像素到字符)的例子中,通过手动构建字形的方式写出了一个A,而这里就可以通过GetGlyph()来得到字形并输出,不再需要手动构建,下面是一个示例:

VOID
ShowB (
  IN  EFI_HII_FONT_PROTOCOL         *HiiFont,
  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL  *Gop
  )
{
  EFI_STATUS        Status = EFI_ABORTED;
  EFI_IMAGE_OUTPUT  *Blt = NULL;

  Status = HiiFont->GetGlyph (
                      HiiFont,
                      L'B',
                      NULL,
                      &Blt,
                      NULL
                      );
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "[%a][%d] Failed. - %r\n", __FUNCTION__, __LINE__, Status));
  } else {
    Gop->Blt (
          Gop,
          Blt->Image.Bitmap,
          EfiBltBufferToVideo,
          0,
          0,
          0,
          0,
          Blt->Width,
          Blt->Height,
          0
          );
  }
}

输出的结果:

在这里插入图片描述

汉字输出

前面介绍了如何输出英文,这里简单说明如何在UEFI下使用汉字。对于该问题,其实原理本身是比较简单的,输出英文使用的是窄体字,即一个8x19的像素,而对于汉字显然是不够的,所以UEFI规范中还定义了宽体字:

///
/// The EFI_WIDE_GLYPH has a preferred dimension (w x h) of 16 x 19 pixels, which is large enough
/// to accommodate logographic characters.
///
typedef struct {
  ///
  /// The Unicode representation of the glyph. The term weight is the
  /// technical term for a character code.
  ///
  CHAR16    UnicodeWeight;
  ///
  /// The data element containing the glyph definitions.
  ///
  UINT8     Attributes;
  ///
  /// The column major glyph representation of the character. Bits
  /// with values of one indicate that the corresponding pixel is to be
  /// on when normally displayed; those with zero are off.
  ///
  UINT8     GlyphCol1[EFI_GLYPH_HEIGHT];
  ///
  /// The column major glyph representation of the character. Bits
  /// with values of one indicate that the corresponding pixel is to be
  /// on when normally displayed; those with zero are off.
  ///
  UINT8     GlyphCol2[EFI_GLYPH_HEIGHT];
  ///
  /// Ensures that sizeof (EFI_WIDE_GLYPH) is twice the
  /// sizeof (EFI_NARROW_GLYPH). The contents of Pad must
  /// be zero.
  ///
  UINT8     Pad[3];
} EFI_WIDE_GLYPH;

相比于窄体字,重点在于通过两个8x19的像素,每一个输出半个汉字,最终就组成了完整的汉字。而之后的重点就是一个汉字的像素该如何构建,这个在uefi-programming/book/GUIbasics/font/SimpleFont/createdata.html at master · zhenghuadai/uefi-programming · GitHub已经给出了工具,可以创建完整的EFI_WIDE_GLYPH数组来表示所有的汉字(由于很多字体是有版权的,所以使用的时候需要注意,最好自己参照免费的字体构造),这里直接使用该工具得到数组,然后再使用跟注册窄体字一样的方式来注册汉字,对应的代码:

  //
  // Reference:
  // edk2\MdeModulePkg\Universal\Console\GraphicsConsoleDxe\GraphicsConsole.c
  //
  PackageLength = sizeof (EFI_HII_SIMPLE_FONT_PACKAGE_HDR) + mWideFontSize + 4;
  Package       = AllocateZeroPool (PackageLength);
  if (NULL == Package) {
    DEBUG ((EFI_D_ERROR, "[%a][%d] Out of memory\n", __FUNCTION__, __LINE__));
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Without this code, system will hang.
  //
  WriteUnaligned32 ((UINT32 *)Package, PackageLength);

  SimplifiedFont                       = (EFI_HII_SIMPLE_FONT_PACKAGE_HDR *)(Package + 4);
  SimplifiedFont->Header.Length        = (UINT32)(PackageLength - 4);
  SimplifiedFont->Header.Type          = EFI_HII_PACKAGE_SIMPLE_FONTS;
  SimplifiedFont->NumberOfNarrowGlyphs = 0;
  SimplifiedFont->NumberOfWideGlyphs = (UINT16) (mWideFontSize / sizeof (EFI_WIDE_GLYPH));

  Location = (UINT8 *)(&SimplifiedFont->NumberOfWideGlyphs + 1);
  CopyMem (Location, gWideGlyphData, mWideFontSize);

  mHiiHandle = HiiAddPackages (
                &mFontPackageListGuid,
                NULL,
                Package,
                NULL
                );
  if (NULL == mHiiHandle) {
    DEBUG ((EFI_D_ERROR, "[%a][%d] NULL == mHiiHandle\n", __FUNCTION__, __LINE__));
    Status = EFI_NOT_READY;
  } else {
    DEBUG ((EFI_D_ERROR, "HanFont added\n"));
  }

  FreePool (Package);

gWideGlyphData中存放了所有的汉字字形表示,由于数据太多这里不再列出,只要注册了之后就可以直接使用了,下面是一个代码示例:

Print (L"*********************** 图形和字体测试 ***********************\r\n");

得到的结果:

在这里插入图片描述

不过需要注意编译的时候要保证对应的c文件使用GBK(或者其它汉字的编码格式)的编码格式,否则会编译失败:

SearchString: Error while processing file

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

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

相关文章

【Axure教程】多选树穿梭选择器

多选树在有分层的领域是经常用到的&#xff0c;例如不同城市下的门店、不同部门的员工等等&#xff0c;用多选树就可以让我们在不同层级快速挑选到对应的对象。 今天作者就教大家在Axure中如何制作多选树穿梭选择器的原型模板&#xff0c;我们会以不同部门之间挑选员工位案例。…

leetcode极速复习版-第二章链表

目录 链表 203.移除链表元素 707.设计链表 206.反转链表 24. 两两交换链表中的节点 19.删除链表的倒数第N个节点 面试题 02.07. 链表相交 链表部分总结 链表 203.移除链表元素 题意&#xff1a;删除链表中等于给定值 val 的所有节点。 示例 1&#xff1a; 输入&a…

基于Java在线电影评价系统设计实现(源码+lw+部署文档+讲解等)

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

【Linux】十分钟理解软硬链接

目录 1.磁盘的物理结构2.磁盘的物理存储结构3.文件系统4.硬链接4.14.2 5.软链接6.三种时间 1.磁盘的物理结构 盘片&#xff1a;一片两面&#xff0c;有一摞盘片。磁头&#xff1a;一面一个磁头&#xff0c;一个磁头负责一面的读取&#xff08;磁头是一起动的&#xff09;。马达…

二叉树 — 返回二叉树最大距离

题目&#xff1a; 给定二叉树头结点head&#xff0c;任何两个节点之间都有距离&#xff0c;求整棵二叉树最大距离。 二叉树如下图所示&#xff0c;假设从x到b&#xff0c;中间节点只能走一次&#xff0c;我们人为规定距离就是整条路径的节点数量&#xff0c;所以距离是3&#x…

Spring Boot 中的 Spring Cloud Gateway

Spring Boot 中的 Spring Cloud Gateway Spring Cloud Gateway 是一个基于 Spring Boot 的网关框架&#xff0c;它提供了一种统一的入口&#xff0c;将所有的请求路由到不同的后端服务中。Spring Cloud Gateway 采用了 Reactive 编程模型&#xff0c;可以处理大量并发请求&…

idea闪退,端口占用处理

1、idea --> Terminal 2、 输入命令 jps 查看进程 3、找到对应的进程&#xff0c;使用 taskkill /pid 端口号 /f 4、 重启项目 &#xff0c;即可

Golang快速鸟瞰

文章目录 引子知识图谱包代理设置关键字数据类型变量struct 和 interface控制语句字符串单引号、双引号、反引号数组与切片字典make和newjson与yaml基本语法指针Channeldeferinit函数类error, panic, recoverchannel与协程调试热加载Gin的热加载Iris的热加载 常用Golang框架常用…

数据库基础作业(linux系统)

数据库作业 在linux系统下的MySQL 创建数据库 使用数据库 查询当前默认的数据库以及使用的编码方式校验规则 查询创建数据的语句 删除数据库 创建数据表 定义多个字段,用上所有数据类型 mysql> SHOW CREATE TABLE multi_tb; -----------------------------------------…

重新理解z-index

一&#xff0c;前言 今天遇到一个布局兼容问题&#xff0c;调试了一番&#xff0c;发现z-index的表现和自己的认知不相符&#xff0c;才知道自己对z-index的认知有错误&#xff0c;于是写篇文章总结下这个z-index的具体使用。有基础的朋友可以直接看第四节。 二&#xff0c;标…

Android 内存治理之线程

1、 前言 当我们在应用程序中启动一个线程的时候&#xff0c;也是有可能发生OOM错误的。当我们看到以下log的时候&#xff0c;就说明系统分配线程栈失败了。 java.lang.OutOfMemoryError: pthread_create (1040KB stack) failed: Out of memory这种情况可能是两种原因导致的。…

行业追踪,2023-07-06,市场反馈平平

自动复盘 2023-07-06 成交额超过 100 亿 排名靠前&#xff0c;macd柱由绿转红 成交量要大于均线 有必要给每个行业加一个上级的归类&#xff0c;这样更能体现主流方向 rps 有时候比较滞后&#xff0c;但不少是欲杨先抑&#xff0c; 应该持续跟踪&#xff0c;等 macd 反转时参与…

rust 从转移说起

Rust 专门提出了所有权和转移的概念&#xff0c;第一次接触总感觉晦涩&#xff0c;不属于正常思维&#xff0c;但还是得耐下性子&#xff0c;观摩观摩 Rust 所谓的转移。 Rust 中&#xff0c;对大多数类型而言&#xff0c;给变量赋值、给函数传值或者从函数返回值&#xff0c;…

Eclipse显示层级目录结构(像IDEA一样)

有的小伙伴使用IDEA习惯了&#xff0c;可能进入公司里面要求使用eclipse&#xff0c;但是eclipse默认目录是并列显示&#xff0c;而不是层级显示。部分人用起来感觉十分不方便。我们可以更改一下设置。 1、打开eclipse&#xff0c;找到这里 2、选择PackagePresentation 3、选…

支持跨语言、人声狗吠互换,仅利用最近邻的简单语音转换模型有多神奇

AI 语音转换真的越复杂越好吗&#xff1f;本文就提出了一个方法简单但同样强大的语言转换模型&#xff0c;与基线方法相比自然度和清晰度毫不逊色&#xff0c;相似度更是大大提升。 AI 参与的语音世界真神奇&#xff0c;既可以将一个人的语音换成任何其他人的语音&#xff0c;…

express框架中间件

1.介绍 说明&#xff1a;Express框架中间件是指在处理HTTP请求前或后对请求和响应进行处理的函数。具体而言&#xff0c;中间件可以&#xff1a; 执行一些公共的逻辑&#xff0c;比如身份验证、日志记录、错误处理等。修改请求和响应&#xff0c;比如缓存、压缩等。控制请求流…

ModaHub魔搭社区:基于 Amazon EKS 搭建开源向量数据库 Milvus

目录 01 前言 02 架构说明 03 先决条件 04 创建 EKS 集群 05 部署 Milvus 数据库 06 优化 Milvus 配置 07 测试 Milvus 集群 08 总结 01 前言 生成式 AI&#xff08;Generative AI&#xff09;的火爆引发了广泛的关注&#xff0c;也彻底点燃了向量数据库&…

Ubuntu中删除LibreOffice方法

目录 删除LibreOffice套件 删除所有与LibreOffice相关的软件包 删除与LibreOffice相关的配置文件 删除LibreOffice套件 1、打开终端。您可以使用快捷键Ctrl Alt T来打开终端。 2、输入以下命令以卸载LibreOffice套件&#xff1a; sudo apt-get remove libreoffice* 删…

[管理与领导-7]:新任管理第1课:管理转身--从技术业务走向管理 - 管理常识1

目录 第1章 管理基本概念 1.1 什么是管理&#xff1f; 1.2 管理的要素与职能 第2章 管理是什么&#xff1f; 2.1 以终为始 2.2 资源的优化配置 2.3 分而治之&#xff1a;分目标、分任务、分权力、分利益 2.4 目标明确 2.5 优先级 2.6 知人善用&#xff0c;人尽其才 …

【零基础入门学习Python---Python与其他技术的整合之快速入门实践】

&#x1f680; 零基础入门学习Python&#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜…