2024年Web前端最新写给程序员的 Unicode 入门介绍(1),2024年最新数据结构与算法面试题答案

css

1,盒模型
2,如何实现一个最大的正方形
3,一行水平居中,多行居左
4,水平垂直居中
5,两栏布局,左边固定,右边自适应,左右不重叠
6,如何实现左右等高布局
7,画三角形
8,link @import导入css
9,BFC理解

js

1,判断 js 类型的方式
2,ES5 和 ES6 分别几种方式声明变量
3,闭包的概念?优缺点?
4,浅拷贝和深拷贝
5,数组去重的方法
6,DOM 事件有哪些阶段?谈谈对事件代理的理解
7,js 执行机制、事件循环
8,介绍下 promise.all
9,async 和 await,
10,ES6 的 class 和构造函数的区别
11,transform、translate、transition 分别是什么属性?CSS 中常用的实现动画方式,
12,介绍一下rAF(requestAnimationFrame)
13,javascript 的垃圾回收机制讲一下,
14,对前端性能优化有什么了解?一般都通过那几个方面去优化的?

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

你可以看到,绝大多书样本文本都分布在 BMP 中,有些零散的使用来自1-2 号面。最大的异常是 emoji,它点亮了 1 号面最底下那的几个小方块。

编码

我们知道 Unicode 编码点,通过它们在编码空间中的下标来定义,范围从 U+0000 到 U+10FFFF。但是在内存或文件中编码点如何用字节表示呢?

对计算机友好的最省事方式是用 32 位整数来存储编码点下标。这样做是可行,但是每个字符用 4 个字节有点浪费。当你处理大量文本的时候,使用 32 位整数存储 Unicode 会占用大量额外存储、内存、带宽等。

于是,Unicode 有了几个紧凑的编码 。32 位整数编码被称作 UTF-32(UTF=”Unicode Transformation Format”),但是很少被用来存储。顶多作为临时内部表示出现,用来检查或操作字符串中的编码点。

最常见的是,你会看到 Unicode 文本被编码为 UTF-8 或 UTF-16。这些都是可变长度编码,分别由 8-bit 或 16-bit 为一个单元组成。这些方案中,下标值较小的编码点占用的字节数也少,会节省不少内存。这样做的代价是处理 UTF-8/16 需要以编程的方式来处理,会慢一些。

UTF-8

在 UTF-8 中,每个编码点依据下标值,被存储为 1 到 4 个字节。

UTF-8 使用二进制前缀系统,在此系统中每个字符的最高位的几个比特表明它是否是单个字节,多字节序列的开始,或中间字节;剩余的比特连接起来表示编码点的下标。下面的表格展示了UTF-8 是如何编码的:

| UTF-8 (二进制) | 编码点 (二进制) | 范围 |

| — | — | — |

| 0xxxxxxx | xxxxxxx | U+0000–U+007F |

| 110xxxxx 10yyyyyy | xxxxxyyyyyy | U+0080–U+07FF |

| 1110xxxx 10yyyyyy 10zzzzzz | xxxxyyyyyyzzzzzz | U+0800–U+FFFF |

| 11110xxx 10yyyyyy 10zzzzzz 10wwwwww | xxxyyyyyyzzzzzzwwwwww | U+10000–U+10FFFF |

UTF-8 有一个方便的属性,即最开始128 个字符(ASCII字符)被编码为单个字节,所有的非 ASCII 字符被编码为 128-255。这产生了两个好处。首先,任何已经是 ASCII 编码的字符串和文件无需转换就可以被 UTF-8 识别。其次,大量的广泛使用的编程惯例——比如 NULL 结尾,分隔符(n,t,’,’,”)等——在 UTF-8 中也是可用的。ASCII 字节不会出现在非 ASCII 编码点中,所以搜索以 NULL 结尾或分隔符结尾的字符串是可以的。

多亏了这个便利,使扩展遗留 ASCII 程序和 API 来处理 UTF-8 字符变得简单。UTF-8 被广泛运用在 Unix、Linux 和网络世界中,还有许多程序员主张 UTF-8 应该作为任何地方的默认编码。

然而,UTF-8 还不能全面替代 ASCII。例如,遍历字符串中的 “字符” 的代码需要解码 UTF-8 并遍历编码点(或字位簇(grapheme cluster)——后面会讲到),而不是字节。当你测量字符串 “长度” 时,你得考虑是要字节长度,还是编码点长度,还是文本渲染的宽度为单位的长度还是其它长度。

UTF-16

你可能遇到的另一个编码是 UTF-16。它使用 16-bit 字,每个字符被存储为 1 个或 2 个字。

和 UTF-8 一样,我们可以用二进制前缀的形式表示 UTF-16 的编码规则:

| UTF-16 (二进制) | 编码点 (二进制) | 范围 |

| — | — | — |

| xxxxxxxxxxxxxxxx | xxxxxxxxxxxxxxxx | U+0000–U+FFFF |

| 110110xxxxxxxxxx 110111yyyyyyyyyy | xxxxxxxxxxyyyyyyyyyy | 0x10000U+10000–U+10FFFF |

但是,通常人们谈到 UTF-16是因为它涉及到了一个在编码点术语中被称作“代理(surrogate)”的东西。所有在范围 U+D800-U+DFFF(或在其他范围) 中的编码点,这些和上表中二进制前缀 110110 和 110111 匹配的编码点——是 UTF-16 中的保留区域,它们自身不表示任何有效的字符。它们仅用于上面 2 个字的编码模式中,被称作“代理对(surrogate pair)”,代理编码点在任何其他情况下都是非法的!它们不能出现在 UTF-8 和 UTF-32 中。

在过去,UTF-16 是1996 年之前的 Unicode 版本的派生物,那时只有 65536 个编码点。初衷是不应有不同的编码,Unicode 应该是简单的16-bit 字符集。后来,编码空间被扩充用来表示不常用的(仍然重要)的汉字字符,这是 Unicode 设计者之前没计划的。代理区在那时被引进,直说了吧,作为拼凑,允许16-bit 编码访问新的编码点。

如今,Javascript 使用 UTF-16 作为其标准的字符串表示:如果你问一个字符串的长度,或遍历它等,结果都以 16-bit 的字为单位,同时任何 BMP 之外的编码点都用代理对表示。UTF-16 也被微软 WIN32 API 使用;尽管 Win32 同时支持 8-bit 和 16-bit 字符串,但是 8-bit 版本仍然莫名其妙地不支持 UTF-8——只支持使用旧编码的代码,像 ANSI。这使得 UTF-16 成为在 Windows 上获得 Unicode 支持的唯一方法。

顺便说一下,UTF-16 字符可以大端存储,也可以小端存储。Unicode 在这个问题上没有说明,虽然它确实鼓励一个惯例,即把 U+FEFF 零宽无间断间隔这个字符放到 UTF-16 文件开头作为字节序标识,来消除字节序问题。(如果文件和系统的字节序不同,BOM(ByteOrderMark) 会被解码为 U-FFFE,这不是一个有效的编码点。)

组合标记

目前为止,我们一直在讨论编码点。但是 Unicode 中,字符比单独的编码点更复杂!

Unicode 包含一个系统,可以合并多个编码点,动态组合字符。此系统用各种方式增加灵活性,而不引起编码点的巨大组合膨胀。

例如,在欧洲语言中,组合标记出现在变音符和字母的使用中。 Unicode 支持各种各样的变音符号,包括尖音符号的和重音符号、元音变音符号、变音符号等等。所有这些变音符可以被使用在任何字母表的字母中。事实上,多个变音符号可以被使用在一个字母上。

如果 Unicode 试图为每个字母组合或变音符组合分配一个独立的编码点,事情会变得无法控制。相反,动态组合系统可以让你构造你想要的任何字符,通过以一个基础编码点(字母)开始然后附加额外的编码点,被称作“组合标识”,来指定变音符。当一个文字渲染器看到字符串中有这样的序列时,它会自动堆叠变音符到基础字母的上面或下面来造出一个组合字符。

例如,带重音的字符“Á” 会被表示成由两个编码点组成的字符串:U+0041 “A” 拉丁大写字母 a 加上 U+0301 “◌́”组合尖音符号。这个字符串自动被渲染成单个字符:“Á”。

如今,Unicode 还包含许多 “预设的” 编码点,每个表示一个被使用过的组合,例如 U+00C1 “Á” 带锐音符的拉丁大写字母A 或 U+1EC7 “ệ” 带扬抑符和下点的小写拉丁字母 e。我怀疑这些大多继承自融入 Unicode 的旧编码,来保证兼容性。实际上,对于欧洲语言中的大多数常见的带变音符号的字母都有预设,所以文本中动态组合用的不多。

可是,组合标志系统确实允许任意数量的变音符号被叠加到任何基础字符上。使用归谬法的 Zalgo 文本,它通过随机叠加任意数量的变音符号在每个字母上,让它溢出行距,产生混乱现象。(如下图)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Unicode 中出现动态组合字符的其他地区:

  • 天成体(梵文),这种文字被用在印度北部,梵文和其他南亚语言中,用组合标记标识特定元音的附加到辅音字母上。例如,“ह” + “ि” = “हि” (“h” + “i” = “hi”)

  • 表示音节的朝鲜字符,但是它被称作Jamo ,用来表示音节中的元音和辅音。当然也有为朝鲜文预制的编码点,同时也可以动态组合它们的 jamo。例如,“ᄒ” + “ᅡ” + “ᆫ” = “한” (“h” + “a” + “n” = “han”)

    • 阿拉伯文和希伯来文中的元音标记 。这些语言中,单词通常由元音拼写。它们有变音符号标记元音(用在字典,语言教学材料,儿童教材,等地方)。这些变音符号用组合标记表示。

| 说明 | 样例 |

| — | — |

| 希伯来文(带注音符号) | אֶת דַלְתִּי הֵזִיז הֵנִיעַ, קֶטֶב לִשְׁכַּתִּי יָשׁוֹד |

| 正常文本(不带注音符号) | את דלתי הזיז הניע, קטב לשכתי ישוד |

规范等价性

Unicode 中,预设字符和动态组合系统并存。后果就是有多种方法表示同一个字符串——不同编码点序列产生相同用户可感知的字符。例如,我们之前看到的,表示字符 “Á”,我们可以用一个编码点 U+00C1 ,也可以用两个编码点 U+0041 和U+0301。

另一个歧义来源是一个字符中的多个注音符号。当两个注音符号作用在同意个基本字符上面时,注音符号的顺序很重要,例如,都在上面:”ǡ“ (点然后长音符)和 ”ā̇“ (长音符然后点)是不一样的。 然而,当音节运用在不同边时,例如。一个在上边一个在下边,编码点的顺序不会影响渲染。此外,一个有多个音节的字符,它可能会由一个预制的编码点再加其余的编码点来表示。

例如,越南字母“ệ” 可以用以下五种方式表示:

● 完全预设:U+1EC7 “ệ”

● 部分预设:U+1EB9 “ẹ” + U+0302 “◌̂”

● 部分预设:U+00EA “ê” + U+0323 “◌̣”

● 完全分解:U+0065 “e” + U+0323 “◌̣” + U+0302 “◌̂”

● 完全分解: U+0065 “e” + U+0302 “◌̂” + U+0323 “◌̣”

Unicode 把这样的字符串集合称作 “规范等价”字符。在搜索、排序、渲染、文本选择等操作中,规范等价字符应该被同等对待。这影响到了你如何实现文本的操作。例如,假设你的程序有“查找”操作,用户搜索 “ệ”,理论上应当找到如上所有出现的所有版本的 “ệ”!

形式正规化

要解决如何处理等值字符串的问题,Unicode 定义了几种正规形式:是几种把字符串转化成规范形式的方法,这样它们就可以被逐点比较(或按字节比较)。

“NFD” 正规化方法,完全分解每个字符到基本部件和组合标记,去掉字符串中任何预制的编码点。还会按渲染位置排列每个组合标记,举个例子,在字母底下的注音符号要比在上边的靠前。(不会重排有相同渲染位置的注音符号,因为它们的位置关系是可视的,前面提到过。)

“NFC” 正规化方法,反过来,尽可能的把编码点替换成预制编码点。如果使用了不常用的注音符号组合,可能不会有任何预制的编码点,这种情况下 NFC 仍然替换它可以替换的,然后留下组合标志(和 NFD一样,还是会按渲染顺序重新排序)。

还有一些方法被称作 NFKD 和NFKC。 这里的 “K” 指的是兼容性分解,它包含了某种程度上“相似”但是视觉上不同的字符。但我不打算讲这些。

字位簇

如上所见,Unicode 包含多种情况,用户认为的一个“字符” 事实上底下可能由多个编码点组成。Unicode 使用「字位簇」的概念来表示这种情况。一个由一个或多个编码点组成的字符串构成一个 “用户感知的字符”。

这里分享一份由字节前端面试官整理的「2021大厂前端面试手册」,内容囊括Html、CSS、Javascript、Vue、HTTP、浏览器面试题、数据结构与算法。全部整理在下方文档中,共计111道

HTML

  • HTML5有哪些新特性?

  • Doctype作⽤? 严格模式与混杂模式如何区分?它们有何意义?

  • 如何实现浏览器内多个标签页之间的通信?

  • ⾏内元素有哪些?块级元素有哪些? 空(void)元素有那些?⾏内元 素和块级元素有什么区别?

  • 简述⼀下src与href的区别?

  • cookies,sessionStorage,localStorage 的区别?

  • HTML5 的离线储存的使用和原理?

  • 怎样处理 移动端 1px 被 渲染成 2px 问题?

  • iframe 的优缺点?

  • Canvas 和 SVG 图形的区别是什么?

JavaScript

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

  • 问:0.1 + 0.2 === 0.3 嘛?为什么?

  • JS 数据类型

  • 写代码:实现函数能够深度克隆基本类型

  • 事件流

  • 事件是如何实现的?

  • new 一个函数发生了什么

  • 什么是作用域?

  • JS 隐式转换,显示转换

  • 了解 this 嘛,bind,call,apply 具体指什么

  • 手写 bind、apply、call

  • setTimeout(fn, 0)多久才执行,Event Loop

  • 手写题:Promise 原理

  • 说一下原型链和原型链的继承吧

  • 数组能够调用的函数有那些?

  • PWA使用过吗?serviceWorker的使用原理是啥?

  • ES6 之前使用 prototype 实现继承

  • 箭头函数和普通函数有啥区别?箭头函数能当构造函数吗?

  • 事件循环机制 (Event Loop)

ind、apply、call

  • setTimeout(fn, 0)多久才执行,Event Loop

  • 手写题:Promise 原理

  • 说一下原型链和原型链的继承吧

  • 数组能够调用的函数有那些?

  • PWA使用过吗?serviceWorker的使用原理是啥?

  • ES6 之前使用 prototype 实现继承

  • 箭头函数和普通函数有啥区别?箭头函数能当构造函数吗?

  • 事件循环机制 (Event Loop)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值