计算机如何将输入文字显示出来的?渲染Image rendering

news2024/12/23 22:23:55

1.文字渲染的简单理解

渲染图像,可以理解为用cpu/gpu构造出原本不存在的图像。比如输入计算机的英文字符都是ASCII码,而我们在屏幕上看到显示的字符对应的应该是RGB/YUV的像素。计算机把ASCII字符转化成像素的过程就是文字渲染。又比如我们GPU用多个2D图片渲染出3D图片,图片亮度根据时间自动调整阳光的强度,阴影等。原图像中不存在的信息,这个是GPU的渲染。

渲染图像和sonser直接采样进来的RGB/YUV图像帧显示是不一样的。

cpu/gpu要显示字符需要以下的信息:

  1. 从键盘采样ASCII码
  2. 应用程序(word,terminal等)设定的字体属性 包括 字体,颜色,大小,背景
  3. 字符显示的位置----来自输入时候的光标指定的位置

cpu/gpu根据上面的信息,渲染出一个RGB帧,然后把这帧图像送给DISPALY做叠加显示

 2.计算机系统是如何显示一个字符的

经过上面的简单描述,我们接下来详细描述文字渲染的过程。以下内容摘自知乎大神们的回答。

两位答主侧重点不同,乌鸦侧重于在Linux+Xorg系统下整个处理流程;孙笑凡侧重于字体与字符的编码

原问题链接为:

计算机系统是如何显示一个字符的? - 知乎


2.1知乎“乌鸦大神的回答”

作者:乌鸦
链接:https://www.zhihu.com/question/24340504/answer/28902204
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

我来就 Linux + Xorg 系统回答一下吧。我不知道,也没办法知道 Windows 上的情况是怎么样的。我的回答在细节方面可能不会太详细,一方面是因为细节并不影响理解,另一方面也是因为我对一些细节的了解也不是那么深。

从按键到字符在屏幕上显示,其实是一个很复杂的过程……我粗略估计了一下,这个过程中执行的指令,对应到源代码,可能要超过10万行。

那,就从按下键开始讲起吧。当你按下键后,一个电信号从键盘通过 USB 接口或者 PS/2 接口送到了总线,然后引起了一个中断。如果是在老机子上,管理中断的可能是8259A 芯片,新的机子上则可能是 APIC 。CPU 收到中断之后,会暂停当前的程序的执行,调用事先设定好的中断处理过程。Linux系统的中断处理一般分为两个部分,Top half 和 bottom half。其中直接响应中断的是 top half,因为系统不能在中断处理过程中停太久,所以 top half 只是记录中断的发生,真正中断处理过程是在 bottom half 中完成的。

bottom half 在 top half 之后执行,具体执行取决于进程调度。在 bottom half 中内核会找来负责的驱动,比如说 USB HID 驱动,处理键盘输入。这个键盘输入会反映在 /dev 下面某一个字符设备中,比如说 /dev/input/event0 。Xorg 为了获取键盘输入,会对这个设备进行 select() 。select 这个系统调用会将进程 block ,直到有可用输入。在内核中的反应就是,内核会将进程的状态设为 TASK_INTERRUPTIBLE ,然后调用 schedule() 将运行权让给别的进程。当键盘输入到来的时候,内核会查看是否有进程正在 select /dev/input/event0 这个设备,如果有,内核会将对应的进程从select 中唤醒,以便处理这个输入。

于是Xorg就被唤醒了,我们也终于从 kernel space 里逃了出来,来到了 user space 。Xorg 会从 /dev/input/event0 读出一组数据。这组数据的定义如下:

struct input_event {
	struct timeval time;
	unsigned short type;
	unsigned short code;
	unsigned int value;
};

time 是事件发生的时间,type 是事件类型,对应键盘就是 EV_KEY ,code 在这种情况下是一个 key code,value 则代表是按下键还是放开键。

Xorg 在读到事件之后,还需要将来自 kernel 的 key code 翻译成 Xorg 自己的 key code 。完成这个的是 libxkb ,键盘布局也是在这个阶段起作用的。然后,Xorg 会找出当前焦点所在的窗口,然后将事件发给它——这是简单的情况。如果你运行着一个窗口管理器的话,这个事件很可能还需要在窗口管理器中过一遍,并且由窗口管理器决定是否要发给窗口。如果接受按键的程序支持输入法,这个按键可能还要在输入法里走一圈。这个过程中的事件发送/接受都是通过 socket ,使用的协议是 Xorg 的协议,使用的库(归根结底)一般是 xlib 或者 libxcb 。

(补充一段关于编码的)

应用程序在接到 Xorg 发来的事件之后,就会对事件作出反应。比如说一个文本编辑器,在接到按下‘X’的事件之后,需要在文件中插入一个‘X’。那么这个‘X’是怎样在文件中表示的呢?你应该知道,内存也好硬盘也好,是用二进制来保存数据的。要表示一个‘X’,我们必须先给它分配一个对应的数字。幸好,早在近60年前,就有人帮我们把这件事办好了。这就是所谓的 ASCII 码。‘X’在其中对应的数字是120。

但是,如果我通过我的输入法,输入了一个中文字的话怎么办?当然,我们还是用一样的办法,给每个中文字一个编号。这个编号,在中国的国标码中被称作区位码,在 unicode 中被称作一个code point。比如说,国标码给“啊”字编的号就是1601。

虽然现在我们给中文字也编上了号,我们还不知道应该怎么把它存到文件中去。你可能会觉得这很简单,直接把编号存进去不就是了?比如1601就存两个字节0x06和0x41。但是这会造成一个问题。假如你的文本编辑器同时支持ASCII码和我们设计的这个中文编码,它要怎样才能知道某个文件是按什么编码的?0x16和0x41在 ASCII 中都是合法编码,这样就会造成一个文件存在歧义。不过幸好,ASCII 只使用了0~127来编码字符,所以只要我们只用128~255,就可以和ASCII区分开来。比如说,我们可以将编号按7位二进制分段,然后在第一位添上一个1:

1601 -> 11001000001 -> 0001100/1000001 -> 10001100 11000001 -> 0x8c 0xc1

在国标码里,这个编码后的结果就是这个字符的内码,注意内码和区位码的区别。而 unicode 和 UTF8,UTF16 也是类似。unicode 是一种给字符编号的方法,UTF8、UTF16则是把这个编号记录到文件里的方法。

到这里,我们的旅程才完成了一半。而且是比较简单的一半。

现在你的输入已经跑完前半程,终于到达应用程序了,不过等等——这个程序,是什么程序?是一个终端虚拟器,文本编辑器,还是chrome里头的某个文本框?取决于对这个问题的回答,后半程的路线会非常不一样。

假如说这个程序是 xterm ,它会通过 X core font API ,将这个字符直接送给 Xorg ,由 Xorg 来完成字体渲染(当然现在 xterm 也支持 libXft 了,不过先不管这个)。Xorg 拿到应用程序送来的请求之后,会在字体中检索每个字对应的字形,然后渲染出来。这个检索过程中用到的索引,就是我们之前给字符编上的号。如果要指定字体,需要向Xorg提供一个长得像这样:“-adobe-times-medium-r-normal--12-120-75-75-p-64-iso8859-1” 的字符串来指定字体。当然,这样渲染出来的字体不会很好看,像这样:

(我不是很清楚 X core font 是否有反锯齿一类的能力,应该是没有,欢迎纠正。)

如果这个应用程序是 gedit,那么它就会选择自己渲染字体,然后将渲染结果直接发给 Xorg,由 Xorg 呈现。在 Linux 下,你想用这种方式渲染字体,有两个库你是逃不过的:fontconfig 和 FreeType2 。大致上来说,fontconfig 让你能通过一个字体名找到对应的字体,FreeType2 则进行具体的渲染。

那么字体是怎么被渲染的呢?不管你用的字体是TrueType还是OpenType还是什么格式,从根本上来说,(除掉点阵字体)都是一些矢量图的集合。渲染字体,只是把矢量图画出来而已——说的轻松!

渲染文字是个复杂的工作,我也不能说我对此了解很深,只能大致讲讲。

字体如果是显示在屏幕上,因为屏幕的dpi和纸张没法比,所以必须反锯齿,否则就会这样:

这只是通过灰度进行反锯齿,我们还可以做的更好。如果你是在使用LCD显示器的话,你屏幕上的像素,长的可能是这个样子的(图片来源,wikipedia):

灰度反锯齿只是在整个像素尺度上进行的,但是既然像素中还可以分为更小的成分,那么我们为什么不通过这更小的单位进行反锯齿?这种方法就叫做 Subpixel Rendering,或者一个更被人熟知的叫法:ClearType。下面是两种反锯齿的比较,图还是来自 Wiki :

可以看到 subpixel 渲染的结果会让边缘带一点色彩。一般来说 subpixel 渲染可以字体看起来更清晰一点,你可在自己的系统上开启/关闭 subpixel redenering 比较一下。

人们为了让字体在屏幕上看起来能清晰一点,真是用尽了心思。因为反锯齿会让字体的边缘变得模糊,让人觉得字体看起来不是那么“锐利”,人们又想出来要给字体做Hinting(不知道如何翻译)。Hinting将字体微调,让横和竖都对齐像素,来尽量减少反锯齿带来的模糊。下面是个(应该一下就能看明白的)例子(图还是来自 Wiki):

Hinting 的具体实现是很复杂的。因为不同字体需要不同的 Hinting 对策,所以字体中会存一些 Hinting 数据来指导 Hinting。而这些数据,每一个都是一个用特定汇编语言写成的小程序!FreeType2中则包含了一个虚拟机,来运行这些程序,来将字体对齐到像素。

当然也有些字体会不带 Hinting 数据,但是 FreeType2 还是可以进行 Hinting ,也就是 Auto-hinting。具体的算法我就不清楚了。

值得一提的是,因为 Apple 拿着很多有关 Hinting 的专利,FreeType2 默认是关闭 Hinting 的,而只使用 Auto-hinting 。直到2011年这些专利全都过期之后,FreeType2才默认支持 Hinting 。

好了,不管你是让Xorg进行字体渲染,还是让应用程序自己进行渲染,最后的结果都是一小块比特图。我们要怎么把这块图显示在屏幕上呢?

Xorg 之中,有一个部件叫做 EXA,是用来提供硬件加速的2D渲染的。EXA的历史很长,最早可以追溯到1996年 Harm Hanemaayer 给 Xorg 实现的 XAA。XAA 后来被 EXA 所接替。现在 EXA 又开始要被 UXA 取代。这些部件虽然都有同样的目的,但是实现都有所不同。具体的区别在这里就不展开了。总的来说,他们的功能是,在显卡驱动的帮助下,将二维图形显示在屏幕上。

到这里,好像就结束了。但其实还没有。2011年的光棍节,Glamor诞生了。Glamor试图将2D的渲染也用 OpenGL 来完成。一张二维图,大概会被转变成 OpenGL 的贴图,然后渲染在屏幕上。目前这个项目还在开发中,性能(在大部分情况下)还不如EXA。

如果所有的渲染都由 OpenGL 也就罢了。如果你还在用 EXA,但是你的某个程序(比如说Chrome)非想用 OpenGL 来显示文字怎么办?显然的办法可以是让程序把所有的 OpenGL 请求都发给 Xorg,让 Xorg 代理。这种方法就叫做间接渲染(Indirect rendering),Xorg 的一个扩展:AIGLX,就是用来完成这个工作的。

有一个额外的中介大概是会影响性能。虽然我没有具体的数据来证明这一点,不过既然后来 DRI 的出现大概是一个佐证。DRI 是 Direct Rendering Infrastructure 的缩写,分为两个部分,分别存在于内核与 Xorg 中。内核的部分叫做 DRM,用来协调多个程序对 GPU 的访问;Xorg 的部分则是一个驱动,也叫 DRI 。程序想要使用 OpenGL ,先要通过 DRI 向 Xorg 申请一块缓冲区,然后通过 DRM 访问 GPU 向这个缓冲区进行渲染。当然这些事不会直接让程序去做,都是通过 Mesa 这个 GL 库完成的。

到这里,还是没有结束。

万一你不幸有个带 NVIDIA® Optimus™ 的本子怎么办?使用 Optimus 技术的独显不会直接和显示器连接,所以想要直接让独显渲染是不行的。现有的解决方案是 BumbleBee,就是之前那个删了用户 /usr 目录,出了点小名的那个。BumbleBee 的做法是再启动一个独立的、跑在独显上的 Xorg,然后用它进行渲染。但是独显没法输出到屏幕,怎么办呢——只好把渲染结果在两个 Xorg 之间传来传去了。BumbleBee 用了 VirtualGL 来完成这个任务。

另外一个还在开发中的解决方案叫做 Prime(开发者就是喜欢和变形金刚过不去)。Prime 利用的是一个还在开发中的内核功能:DMA-BUF,让两个硬件共享一块内存区域。我不清楚具体的原理,不过大概是让一块显卡渲染完之后,DMA 写到内存里,再让连接显示器的显卡 DMA 读出,输出到屏幕吧。

用来 Optimus 以后,感觉本来的长跑,直接就变成了马拉松……

以上差不多就是全部了。不知道你们是不是还有兴趣,要是把场景换成 Wayland ,还有很多可以讲。

2.2知乎大神“孙笑凡”的回答

作者:孙笑凡
链接:https://www.zhihu.com/question/24340504/answer/29927340
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
 

正巧,今天下午我也遇到了难缠的编码问题,既然前面乌鸦朋友已经介绍的非常详细的计算机底层原理,我就从另一个侧面谈谈计算机编码及乱码问题产生的根源。今天写了这样一段文章,就拿出来和大家分享。

从编码问题的产生说起

我们知道,计算机是美国人发明的,人家的英语体系总从来就只有26个英文字母和一些数字、特殊字符等,为了储存文字信息,于是使用了最早的ascii码进行字符编码。而后来由于计算机的普及,多国语言文字变得重要起来,于是多语言的特性成为了计算机的必备,各国进行各国的国家标准编码,中国的便是GB2312(1980年),而后1995年又颁布了《汉字编码扩展规范》(GBK),GBK与GB2312相兼容,但又增加了一些兼容汉字,方便了和Big5码等进行转换。这套GBK编码,逐渐成为了中国计算机的主流编码。

Unicode字符集和UTF-8编码

随着计算机的发展,往往一款软件不但要兼容一个国家的语言,还要兼容许多国家的语言,尤其是亚洲国家中日韩三国,光中文常用字符就有7000,所以要解决这么多文字的编码问题,就需要用更多规模的表示,Unicode是一个巨大的字符集,囊括了世界各地的语言,这样编码就更为统一和方便了。但Unicode并没有规定这些字符具体应该怎么样在计算机中存储,虽然字符集是全的,但计算机中要兼顾效率和方便等问题,UCS-2是其中的一种常用方案,采用两个字节来编码一个字符,这和ascii码不兼容,而且还有一个大问题,UCS-2并不能表示全部的汉字,汉字的简繁体加起来总共有六七万,UCS-2只有65536个编码,根本存不下,所以只收入了大部分常用字。也有表示所有汉字的方案UCS-4,不过4个字节用来存储汉字,效率就较为低下。

UTF是“UCS Transformation Format”的缩写,是Unicode字符集的一类高效实现方式。

UTF-8是我个人比较喜欢的一种编码方式,它是一种针对Unicode的可变长度字符编码,又称为万国码。它使用1-6个字节进行编码,最前面128个编码内容和ascii码兼容,所以我们用UTF-8编写纯英文文本是和ascii码几乎一样的。(注意我说的是几乎)。

如果UNICODE字符由2个字节表示,则编码成UTF-8很可能需要3个字节。而如果UNICODE字符由4个字节表示,则编码成UTF-8可能需要6个字节。用4个或6个字节去编码一个UNICODE字符可能太多了,但这样的UNICODE字符往往是生僻字,极为少见。

这种编码的思想和哈夫曼编码是类似的,将高频字符缩短,低频字符变长,使得整体的编码效率更优。

我以前有段时间,就经常将Unicode和UTF-8搞混了,Unicode是字符集,网上不严格的情况也指Unicode字符集的常用编码UCS-2,也就是用两个字节编码的Unicode码。

一些常见系统的编码:

VC 6.0 Ascii码

VS2008 - 2013 UCS-2(开启Unicode后)

Windows中文版 GBK

Linux(andorid) UTF-8

Mac OX UTF-8

JAVA UCS-2

Python2 ascii (byte)

Python3 UCS-2

注:操作系统所述都是默认编码,这三种主流操作系统的系统编码都是可以更改的。

MBCS(Multi-Byte Character Set)和内码表(codepage)

再介绍两个字符集中较为深入的概念,MBCS和CodePage。

MBCS(Multi-Byte Chactacter System,即多字节字符系统),是所有多字节编码方案的总称,MBCS 编程主要用于为国际市场编写的应用程序。由于往往是针对一国市场只有一种文字,那么为了节约资源,往往将这些文字用双字节或尽量少的字节的方式进行保存。

因为这些双字节文字和ANSI是混和在一起的,为了加以区别,Windows将这些字符的最高位置为1(即这些双字节文字的每个字节都>=127),所以这种表示法可以表示 127x127 约一万多种非ANSI文字 ,其本上可以表示任何一种语言的常用文字了。于是,Windows为每一个区域版本,都制定了分别独立的文字编码,这就是MBCS(多字节码)。

而这些分页后的编码方式,都被保存成了不同的CodePage(内码表,这里内码的意思是机器内部编码,相对于外码,外部输入文字用的编码,例如拼音、五笔、郑码等),例如中文就是大家熟知的CP936。要注意,这种编码方式是早期windows独有的,由于使用较早,应用也十分广泛,而CP936和GB2312-80在编码上则是几乎一样的(此处见Wiki百科——汉字内码扩展规范),后来扩展GBK后,CP936也进行了同样的扩展。

此技术的使用最早追溯到MS-DOS3.3(1987年4月发行)向IBMPC用户引进了内码表的概念,Windows也使用此概念。

这是微软官网上给的10081页的CodePage

内码表成为了系统进行多语言编码及转换的重要工具。当然,Unicode码也被收入CodePage中。

说白了,MBCS和CodePage就是计算机解决多字节编码问题的通用手段,各种区域编码可以在其中找到对应编码的映射的,Unicode和UTF-8也是可以在其中找到对应的映射的。

常见的CodePage

932 —日文

936 —简体中文(GBK)

949 —韩文

950 —繁体中文(大五码)

1200 —UCS-2LE Unicode 小端序

1201 —UCS-2BE Unicode 大端序

1252 —西欧拉丁字母ISO-8859-1.

65000 — UTF-7 Unicode

65001 — UTF-8 Unicode

计算机是如何显示文字的呢?

计算机要对文字进行存储后就需要显示出来,而我们的液晶屏都是一个个的像素点组成的,这就必须要对文字进行渲染绘制,发送到显卡中进行栅格化和显示等操作。

Dos下最简单,利用主板BIOS就能对ascii码进行点阵化输出。简单的我们就不再多谈,windows下是如何对文字进行绘制显示的呢?

字库


 

我们都知道,显示字体除了要有文字的编码,还需要有显示用的字的样式,这就是 字库,windows下的fonts文件夹大家应该都十分熟悉,更改或删除字库就是就是文件的移动而已。而字库实际上也有不同的种类的,构建原理也不都相同。

最早的字库是点阵字库,这种字库看起来和黑白图片貌似没有什么大区别,就是记录像素是黑还是白,我们用windows自带的字库编辑程序,就可以处理这种字库。

这种字库的缺点也是显而易见的,首先是缩放不易,在小字体和大字体显示时都容易失真走样,而且占用空间较大。

矢量轮廓字库,这种字库是用的矢量图原理进行存储的,将外部边界抽象成数学上的矢量线段,可以方便的缩放旋转等操作。缺点则是连续性不好,放大后就变出行了折痕,效果不够理想。

曲线轮廓字库,这是通过直线和曲线段共同构造文字的方法,往往使用Bezier曲线对轮廓进行拟合,效果非常好,字体平滑美工,但惟独就是计算较为费时间。

TrueType字形技术

TrueType采用几何学中二次B样条曲线及直线来描述字体的外形轮廓。由一些数学算法进行对应大小字体的生成,无论放大或缩小,字符总是光滑的。

TrueType字体与PostScript字体、OpenType字体是主要的三种计算机矢量字体(又称轮廓字体、描边字体),后缀.ttf。

虽然计算较快,但相比于PostScript字体,质量要差一些,特别是文字太小时,不够清晰。

所以字库一般会对小字体和常用打印字号制作对应的点阵字库,保证其精度,其他情况则使用TrueType字体。

WOFF–WebOpen Font Format (.woff)

WOFF(Web开发字体格式)是一种专门为了Web而设计的字体格式标准,实际上是对于TrueType/OpenType等字体格式的封装,每个字体文件中含有字体以及针对字体的元数据(Metadata),字体文件被压缩,以便于网络传输。

其实大家就会发现了,网络上很火的图标字体,实际上就是根据最基础的字库技术生成出来的。


 

字体的显示流程

介绍到这里,大家应该对整个字体的绘制过程有个整体的认识了,首先是经过字符编解码,将硬盘中存储的有对应编码的文本文件进行加载,例如Java的文件IO,变成内存中的字符串对象,也就是符合本语言字符串存储特性的数据,(当然如果你愿意,也可以当做二进制读入,然后再手段转换编码,也是可以的),绘制时则首先调用对应的CodePage进行编码的索引查找,找到对应的字体字形索引,然后根据字形索引获取到字库中的数据,根据系统提供的绘制曲线绘制样条线的方法进行图形渲染,这样就能得到显示器上的图像了。而更高级的就是对字体进行反走样,锐化,等更为细节的操作了。

本文好多内容是基于我自己的理解写成,如有疏漏错误,还请指正。

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

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

相关文章

全同态加密生态项目盘点:FHE技术的崛起以及应用

撰文:Chris,Techub News 在当今数字化的时代,隐私保护已成为一个全球性的焦点话题,特别是在加密货币和区块链技术快速发展的背景下。虽然当前的隐私技术在保护数据安全方面多有欠缺,引发了广泛的关注和批评&#xff0c…

如何彻底搞懂装饰器(Decorator)设计模式?

对于任何一个软件系统而言,往现有对象中添加新功能是一种不可避免的实现场景,但这一实现过程对现有系统的影响可大可小。从架构设计上讲,我们也知道存在一个开闭原则(Open-Closed Principle,OCP)&#xff0…

中文信息期刊投稿邮箱

《中文信息》杂志是国家新闻出版总署批准的国家级刊物(月刊),国内外公开发行,大十六开印刷。本刊主要反映我国中文信息处理的学术水平,重点刊登科技、经济、教育等领域的基础理论、科研与应用技术的学术论文&#xff0…

使用Coding部署项目

coding概述:提供一站式开发协作工具,帮助研发团队快速落地敏捷开发与 DevOps 开发方式,实现研发效能升级 一、创建项目 省略 详细文档:https://g-mnbk6665.coding.net/quickstart 二、SSH连接 关于ssh相关命令 重启SSH服务 s…

2023蓝桥杯大赛软件类省赛Java大学B组G题 买二增一 队列的简单应用

用队列 Queue package Dduo; //Bhu Bigdata 1421 //Eslipse IDE 2020-08 //JDK 1.8 //2024/5/19 import java.util.Scanner; import java.math.BigInteger; import java.util.Arrays; import java.util.LinkedList; import java.util.Queue;public class Main {public static v…

【openlayers系统学习】1.6下载要素,将要素数据序列化为 GeoJSON并下载

六、下载要素 下载要素 上传数据并编辑后&#xff0c;我们想让用户下载结果。为此&#xff0c;我们将要素数据序列化为 GeoJSON&#xff0c;并创建一个带有 download​ 属性的 <a>​ 元素&#xff0c;该属性会触发浏览器的文件保存对话框。同时&#xff0c;我们将在地图…

二叉树顺序结构及链式结构

一.二叉树的顺序结构 1.定义&#xff1a;使用数组存储数据&#xff0c;一般使用数组只适合表示完全二叉树&#xff0c;此时不会有空间的浪费 注&#xff1a;二叉树的顺序存储在逻辑上是一颗二叉树&#xff0c;但是在物理上是一个数组&#xff0c;此时需要程序员自己想清楚调整…

GPT-4o: 未来的智能助手

GPT-4o: 未来的智能助手 在这个信息爆炸的时代&#xff0c;人工智能&#xff08;AI&#xff09;已经成为我们生活中不可或缺的一部分。作为OpenAI最新推出的语言模型&#xff0c;GPT-4o不仅继承了前几代模型的优点&#xff0c;还在多个方面进行了显著的提升。本文将带你深入了解…

C++:vector基础讲解

hello&#xff0c;各位小伙伴&#xff0c;本篇文章跟大家一起学习《C&#xff1a;vector基础讲解》&#xff0c;感谢大家对我上一篇的支持&#xff0c;如有什么问题&#xff0c;还请多多指教 &#xff01; 如果本篇文章对你有帮助&#xff0c;还请各位点点赞&#xff01;&#…

网络编程day7

思维导图 数据库编程实现学生管理系统 #include <header.h> #define ID 1 #define NAME 2 #define AGE 3 #define SCORE 4 int do_add(sqlite3 *ppdb) {int add_numb;char add_name[20];int add_age;double add_score;printf("enter student id:");scanf(&quo…

1076: 判断给定有向图是否存在回路

解法&#xff1a; 直观的方法用邻接矩阵dfs,这是错误的代码 #include<iostream> #include<vector> using namespace std; int arr[100][100]; int f 0; void dfs(vector<int>& a, int u) {a[u] 1;for (int i 0; i < a.size(); i) {if (arr[u][i]…

绝缘监测系统在1kV 及以下低压配电系统的应用

安科瑞电气股份有限公司 祁洁 acrelqj 一、系统概述 Acrel-2000L/A 绝缘监测系统设备适用于 1kV 及以下低压配电系统。该设备可以集中采集监测显示绝缘监测仪的数据&#xff0c;实现最多 8 个绝缘监测仪的数据&#xff0c;并且实时记录告警信息和曲线查询。匹配的绝缘监测仪…

bootstrap入门

官方网站&#xff1a;全局 CSS 样式 Bootstrap v3 中文文档 | Bootstrap 中文网 里面各种可以直接用的组件 不全的话可以网上搜索Boostrap常用的按钮样式_btn-large-dim-CSDN博客 怎么在vue项目中使用呢 npm install bootstrap 下载下来然后在main.js加上红框三句后&#…

SpringCloudAlibaba:6.2RocketMQ的普通消息的使用

简介 普通消息也叫并发消息&#xff0c;是发送效率最高&#xff0c;使用最多的一种 依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSch…

1701java药品进销存管理系统Myeclipse开发sqlserver数据库web结构java编程计算机网页项目

一、源码特点 java web药品进销存管理系统是一套完善的java web信息管理系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境 为 TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为s…

解决vue3 vite打包报Root file specified for compilation问题

解决方法&#xff1a; 修改package.json打包命令 把 "build": "vue-tsc --noEmit && vite build" 修改为 "build": "vite build" 就可以了 另外关于allowJs这个问题&#xff0c;在tsconfig.json文件中配置"allowJs&qu…

重学java 39.多线程 — 线程安全

逐渐成为一个情绪稳定且安静成长的人 ——24.5.24 线程安全 什么时候发生&#xff1f; 当多个线程访问同一个资源时&#xff0c;导致了数据有问题&#xff0c;出现并发问题&#xff0c;数据不能及时更新&#xff0c;导致数据发生错误&#xff0c;出现线程安全问题 多线程安全问…

【不太正常的题】LeetCode.232:用栈的函数接口实现队列

&#x1f381;个人主页&#xff1a;我们的五年 &#x1f50d;系列专栏&#xff1a;初阶数据结构刷题 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 &#x1f697; 1.问题描述&#xff1a; 题目中说了只能使用两个栈实现队列&#xff0c;并且只能使用…

【Crypto】password

文章目录 password解题感悟 password 试试flag{zs19900315} 提交成功 解题感悟 这题有点大病

软考--软件设计师--试题六--工厂方法模式(Factory Method)

工厂方法模式(Factory Method) 1、意图 定义一个用于创建对象的接口&#xff0c;让子类决定实例化哪儿一个类&#xff0c;factory method使一个类的实例化延迟到其子类。 2、结构 3、适用性 a、当一个类不知道它所必须创建的对象的类的时候。 b、当一个类希望由它的子类来指定…