Transformers学习笔记1. 一些基本概念和编码器、字典

news2024/11/24 19:12:14

Transformers学习笔记1. 一些基本概念和编码器、字典

  • 一、基本概念
    • 1. Hugging Face简介
    • 2. Transformers
      • (1)简介
      • (1)预定义模型
      • (2)使用方法
    • 3. Datasets
      • 查看有哪些公开数据集
        • 方法1: 使用datasets包的list_datasets方法
        • 方法2:到网站查看
  • 二、一些编码器知识
    • 1. BPE算法
    • 2. WordPiece算法
    • 3. SentencePiece
    • 4. tokenizer
      • (1)spaCy
      • (2)Moses
    • 2. transformers编码规则
    • 3. 使用tokenizer编解码
      • (1)使用encode编码函数
      • (2)使用增强编码函数
      • (3)批量编码、解码句子
    • 4. 字典操作

在这里插入图片描述

一、基本概念

1. Hugging Face简介

Hugging Face是一家纽约的聊天机器人初创服务商,他们开源了Transformers库,并在开源社区大火起来,其官网地址: https://huggingface.co/

在这里插入图片描述
Hugging Face的主要模型可以大致分为几类:

  • 自回归:GPT2, Transfoer-XL, XLNet
  • 自编码:BERT, ALBERT, RoBERTa, ELECTRA
  • Sequence to Sequence: BART, Pegasus, T5

2. Transformers

(1)简介

Transformers是一个NLP自然语言处理库。
开源地址:
https://github.com/huggingface/transformers
文档地址:
https://huggingface.co/docs/transformers/index
教程地址:
https://huggingface.co/transformers/v3.0.2/quicktour.html

安装Transforms可以使用pip:

pip install transformers

(1)预定义模型

Transformers默认框架为PyTorch,也支持TensorFlow,内置了以下神经网络:

  • T5 model
  • DistilBERT model
  • ALBERT model
  • CamemBERT model
  • XLM-RoBERTa model
  • Longformer model
  • RoBERTa model
  • Reformer model
  • Bert model
  • OpenAI GPT model
  • OpenAI GPT-2 model
  • Transformer-XL model
  • XLNet model
  • XLM model
  • CTRL model
  • Flaubert model
  • ELECTRA model

每种模型至少一个预训练模型,在下面这个网址可以找到预训练模型:
https://huggingface.co/models
示例:bert-base-chinese 模型说明界面:
在这里插入图片描述

每种模型会围绕三种类型的类构建:

  1. 模型类 model
  2. 配置类 configuration
  3. 编码解码等 tokenizer 类

这些类实例化后,有两种方法在本地保存:

  1. from_pretrained():
  2. save_pretrained()

(2)使用方法

使用Transformers有三种方法:

  • 使用pipeline
  • 指定预训练模型
  • 使用AutoModels 加载预训练模型
    本文主要介绍pipeline。

3. Datasets

Hugging Face的数据集。

pip install datasets

加载数据集示例:

from datasets import load_dataset
datasets = load_dataset("madao33/new-title-chinese")
print(datasets)

查看有哪些公开数据集

方法1: 使用datasets包的list_datasets方法

from datasets import list_datasets
list_datasets()[:10]
# 打印值:
['acronym_identification', 'ade_corpus_v2', 'adversarial_qa', 'aeslc', 'afrikaans_ner_corpus', 'ag_news', 'ai2_arc', 'air_dialogue', 'ajgt_twitter_ar', 'allegro_reviews']

方法2:到网站查看

https://huggingface.co/datasets

二、一些编码器知识

1. BPE算法

全称是byte pair encoder,字节对编码。可以理解为一种压缩算法,把出现频繁最高的字符对用新的字符替换,反复迭代,这样可以减少语料库的数量。

2. WordPiece算法

与BPE算法类似,但在合并时会引入概率计算,选择可以最大化训练数据可能性的组合 ,从而进一步优化合并结果。

3. SentencePiece

SentencePiece是一个无监督的文本标记器和去标记器,主要用于基于神经网络的文本生成系统,它是一个谷歌开发的开源工具。开源地址:
https://github.com/google/sentencepiece

4. tokenizer

tokenizer称为编码器或分词器。自然语言处理中,首先要把句子分词转化为唯一编码。
spaCy和Moses是两个较流行的基于规则的tokenizer。

(1)spaCy

在其官网: https://spacy.io/usage/spacy-101
可以直接在线运行一个demo。
在这里插入图片描述
示例中对句子:
Apple is looking at buying U.K. startup for $1 billion进行分析,并输出单词的属性。其中pos_可以大致理解为单词是形容词、副词、动词之类属性, dep_更复杂一些,后面有时间再详细讲解。

Apple PROPN nsubj
is AUX aux
looking VERB ROOT
at ADP prep
buying VERB pcomp
U.K. PROPN dobj
startup NOUN dobj
for ADP prep
$ SYM quantmod
1 NUM compound
billion NUM pobj

(2)Moses

官网:http://www2.statmt.org/moses/
Moses 是一个统计机器翻译系统。

2. transformers编码规则

transformers 模型对语句采用了词级切分和字符级切分的混合,称为子词(subword)切分。该算法依赖这样一种原则 :

  • 常用词不应该被拆分
  • 非常用词应被切分为更有意义的词。
    子词切分是在模型维护的词汇量、保持单词语义方面的一种折衷。

3. 使用tokenizer编解码

(1)使用encode编码函数

from transformers import BertTokenizer

# 定义模型、语料
tokenizer = BertTokenizer.from_pretrained(
	# 预加载模型
    pretrained_model_name_or_path='bert-base-chinese',
    cache_dir=None,
    force_download=False
)

sents = [
    '今天是星期一。',
    '今天天气很好',
    '今天电脑运行有点故障',
    '电脑硬盘好像坏了,读不出数据。'
]

print(tokenizer)
# 打印结果
PreTrainedTokenizer(name_or_path='bert-base-chinese', vocab_size=21128, model_max_len=512, is_fast=False, padding_side='right', truncation_side='right', special_tokens={'unk_token': '[UNK]', 'sep_token': '[SEP]', 'pad_token': '[PAD]', 'cls_token': '[CLS]', 'mask_token': '[MASK]'})

out = tokenizer.encode(
	# 输入的语料
    text=sents[0],
    # 可以输入两条语料
    text_pair=sents[1],
    # 句子长度大于下面的max_length时,是否截断
    truncation=True,
    # 长度不到max_length时,是不是补pad
    padding='max_length',
    
    add_special_tokens=True,
    # 最大长度
    max_length=30,
    # 返回的数据类型不指定,默认为list
    return_tensors=None
)

print(out)
# 打印的结果
[101, 791, 1921, 3221, 3215, 3309, 671, 511, 102, 791, 1921, 1921, 3698, 2523, 1962, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

decodeTxt = tokenizer.decode(out)
print(decodeTxt)
# 打印的结果
[CLS] 今 天 是 星 期 一 。 [SEP] 今 天 天 气 很 好 [SEP] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD]

Tokenizer对中文的处理比较简单,每个汉字都作为一个词。

(2)使用增强编码函数

from transformers import BertTokenizer

tokenizer = BertTokenizer.from_pretrained(
    pretrained_model_name_or_path='bert-base-chinese',
    cache_dir=None,
    force_download=False
)

sents = [
    '今天是星期一。',
    '今天天气很好',
    '今天电脑运行有点故障',
    '电脑硬盘好像坏了,读不出数据。'
]

print(tokenizer, sents)

out = tokenizer.encode_plus(
    text=sents[0],
    text_pair=sents[1],
    truncation=True,
    padding='max_length',
    add_special_tokens=True,
    max_length=30,
    # 返回类型,可以是tf(tensorflow),pt(pytorch),np(numpy),默认返回list
    return_tensors=None,
    # 是否返回token_type_ids,结果第一个句子和特殊符号的位置是0,第二个句子的位置是1
    return_token_type_ids=True,
    # 是否返回attention_mask,pad的位置是0,其它位置是1
    return_attention_mask=True,
    # 是否返回special_tokens_mask,特殊符号的位置是1,其它位置是0
    return_special_tokens_mask=True,
    # 返回 length 标识的长度
    return_length=True
)
for k, v in out.items():
    print(k, ':', v)

tokenizer.decode(out['input_ids'])

# 输出结果:
PreTrainedTokenizer(name_or_path='bert-base-chinese', vocab_size=21128, model_max_len=512, is_fast=False, padding_side='right', truncation_side='right', special_tokens={'unk_token': '[UNK]', 'sep_token': '[SEP]', 'pad_token': '[PAD]', 'cls_token': '[CLS]', 'mask_token': '[MASK]'}) ['今天是星期一。', '今天天气很好', '今天电脑运行有点故障', '电脑硬盘好像坏了,读不出数据。']
# 和简单编码结果一样
input_ids : [101, 791, 1921, 3221, 3215, 3309, 671, 511, 102, 791, 1921, 1921, 3698, 2523, 1962, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
# 第2个句子的位置是1
token_type_ids : [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
# 特殊符号位置是1
special_tokens_mask : [1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
# pad位置是0,其它是1
attention_mask : [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
# 句子的长度
length : 30

(3)批量编码、解码句子

from transformers import BertTokenizer

tokenizer = BertTokenizer.from_pretrained(
    pretrained_model_name_or_path='bert-base-chinese',
    cache_dir=None,
    force_download=False
)

sents = [
    '今天是星期一。',
    '今天天气很好',
    '今天电脑运行有点故障',
    '电脑硬盘好像坏了,读不出数据。'
]

print(tokenizer, sents)

out = tokenizer.batch_encode_plus(
    batch_text_or_text_pairs=[sents[0], sents[1]],
    truncation=True,
    padding='max_length',
    add_special_tokens=True,
    max_length=30,
    # 返回类型,可以是tf(tensorflow),pt(pytorch),np(numpy),默认返回list
    return_tensors=None,
    # 是否返回token_type_ids,结果第一个句子和特殊符号的位置是0,第二个句子的位置是1
    return_token_type_ids=True,
    # 是否返回attention_mask,pad的位置是0,其它位置是1
    return_attention_mask=True,
    # 是否返回special_tokens_mask,特殊符号的位置是1,其它位置是0
    return_special_tokens_mask=True,
    # 返回 length 标识的长度
    return_length=True
)
for k, v in out.items():
    print(k, ':', v)

print(tokenizer.batch_decode(out['input_ids']))

输出结果:

PreTrainedTokenizer(name_or_path='bert-base-chinese', vocab_size=21128, model_max_len=512, is_fast=False, padding_side='right', truncation_side='right', special_tokens={'unk_token': '[UNK]', 'sep_token': '[SEP]', 'pad_token': '[PAD]', 'cls_token': '[CLS]', 'mask_token': '[MASK]'}) ['今天是星期一。', '今天天气很好', '今天电脑运行有点故障', '电脑硬盘好像坏了,读不出数据。']
input_ids : [[101, 791, 1921, 3221, 3215, 3309, 671, 511, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [101, 791, 1921, 1921, 3698, 2523, 1962, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
token_type_ids : [[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, 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]]
special_tokens_mask : [[1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]
length : [9, 8]
attention_mask : [[1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
['[CLS] 今 天 是 星 期 一 。 [SEP] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD]', '[CLS] 今 天 天 气 很 好 [SEP] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD]']

4. 字典操作

from transformers import BertTokenizer

tokenizer = BertTokenizer.from_pretrained(
    pretrained_model_name_or_path='bert-base-chinese',
    cache_dir=None,
    force_download=False
)

sents = [
    '今天是星期一。',
    '今天天气很好',
    '今天电脑运行有点故障',
    '电脑硬盘好像坏了,读不出数据。'
]

print(tokenizer, sents)

# 定义字典
dict = tokenizer.get_vocab()
print(type(dict), len(dict), '天气' in dict)

# 添加新词
tokenizer.add_tokens(new_tokens=['今天', '天气', '星期一'])
dict = tokenizer.get_vocab()
print(type(dict), len(dict), '天气' in dict)
# 添加新符号
tokenizer.add_special_tokens({'eos_token':'[EOS]'})
dict = tokenizer.get_vocab()
print(type(dict), len(dict), '天气' in dict)


out = tokenizer.batch_encode_plus(
    batch_text_or_text_pairs=[(sents[0], sents[1])],
    truncation=True,
    padding='max_length',
    add_special_tokens=True,
    max_length=30,
    # 返回类型,可以是tf(tensorflow),pt(pytorch),np(numpy),默认返回list
    return_tensors=None,
    # 是否返回token_type_ids,结果第一个句子和特殊符号的位置是0,第二个句子的位置是1
    return_token_type_ids=True,
    # 是否返回attention_mask,pad的位置是0,其它位置是1
    return_attention_mask=True,
    # 是否返回special_tokens_mask,特殊符号的位置是1,其它位置是0
    return_special_tokens_mask=True,
    # 返回 length 标识的长度
    return_length=True
)
for k, v in out.items():
    print(k, ':', v)

print(tokenizer.batch_decode(out['input_ids']))

输出结果:

PreTrainedTokenizer(name_or_path='bert-base-chinese', vocab_size=21128, model_max_len=512, is_fast=False, padding_side='right', truncation_side='right', special_tokens={'unk_token': '[UNK]', 'sep_token': '[SEP]', 'pad_token': '[PAD]', 'cls_token': '[CLS]', 'mask_token': '[MASK]'}) ['今天是星期一。', '今天天气很好', '今天电脑运行有点故障', '电脑硬盘好像坏了,读不出数据。']
<class 'dict'> 21128 False
<class 'dict'> 21131 True
<class 'dict'> 21132 True
input_ids : [[101, 21128, 3221, 21130, 511, 102, 21128, 21129, 2523, 1962, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
token_type_ids : [[0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
special_tokens_mask : [[1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]
length : [11]
attention_mask : [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
['[CLS] 今天 是 星期一 。 [SEP] 今天 天气 很 好 [SEP] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD]']

重新编码的结果里,今天、天气、星期一已经当成词语进行了编码。

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

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

相关文章

深入分析JVM执行引擎

程序和机器沟通的桥梁 一、闲聊 相信很多朋友在出国旅游&#xff0c;或者与外国友人沟通的过程中&#xff0c;都会遇到语言不通的烦恼。这时候我们就需要掌握对应的外语或者拥有一部翻译机。而笔者只会中文&#xff0c;所以需要借助一部翻译器才能与不懂中文的外国友人交流。咱…

Android入门第51天-使用Android的SharedPreference存取信息

简介 上一篇我们介绍了在android里如何读写本地文件。我们有一种场景&#xff0c;类似网页的cookie&#xff0c;要把用户的一些储如上一次登录、使用的痕迹等信息保存下来以便于每次不需要做重复“填表单”的操作&#xff0c;当在这种场景下我们如果也使用本地文件读写的话显然…

关于Unity使用Aspose.Words创建表格单元格垂直合并不生效情况说明

文章目录&#x1f449;一、前言&#x1f449;二、问题重现1、首先看一下我用下面两段代码创建的表格&#xff1a;2、被这个问题折磨的心路历程&#x1f449;三、分析原因&#x1f449;四、解决方法&#x1f449;一、前言 最近在使用Aspose.Words.dll实现创建表格功能时&#x…

Google Earth Engine APP(GEE)——用一个选择器选择不同城市的应用

我们很多时候在进行应用制作的时候,都会用到选择器用于添加不同的城市,从而进一步选择不同的区域进行分析,本文就将准备一个包含有城市的矢量数据,按照名字进行筛选,最终展示不同城市的所在范围,从而实现简单的select选择器的调用。本文最主要的就是这个回调函数。 具体…

C语言基础—指针(地址引用、指针数组、二次指针)

本章主要讲解指针的基本定义和指针的传递、偏移。后面继续讲解指针数组和多维指针、二级指针等 知识点&#xff1a; 指针的定义和指针分类各类指针的字节长度取决于系统位数指针的传递&#xff08;值传递和引用(地址传递)&#xff09;指针的偏移&#xff08;自增自减号&#x…

动态优化解决方案空间中的最小支持(Matlab代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f389;3 参考文献 &#x1f468;‍&#x1f4bb;4 Matlab代码 &#x1f4a5;1 概述 相对于求解函数极值这类静态问题&#xff0c;许多存在于真实世界的优化问题都是在动态变化的&#xff0c;这一类问题被称为动态…

201732-35-6,H2N-AFP-pNA

AFP-pNA&#xff0c;来自牙周病原体牙龈卟啉单胞菌和黑普氏菌的脯氨酸三肽基氨基肽酶的底物。 编号: 189876中文名称: 三肽Xaa-Xaa-Pro tripeptidylpeptidase substrateCAS号: 201732-35-6单字母: H2N-AFP-pNA三字母: H2N-Ala-Phe-Pro-pNA氨基酸个数: 3分子式: C23H27N5O5平均分…

React 入门:脚手架代理配置

文章目录React AjaxAxios在 React 中使用 Axios脚手架代理配置React Ajax 理解 React 本身只关注于界面&#xff0c;并不包含发送 ajax 请求的代码。前端应用需要通过 ajax 请求与后台进行交互&#xff08;json 数据&#xff09;。React 应用中需要继承第三方 ajax 库&#xff…

C++ · 入门 | 准备知识

啊我摔倒了..有没有人扶我起来学习.... &#x1f471;个人主页&#xff1a;《CGod的个人主页》\color{Darkorange}{《CGod的个人主页》}《CGod的个人主页》交个朋友叭~ &#x1f492;个人社区&#xff1a;《编程成神技术交流社区》\color{Darkorange}{《编程成神技术交流社区》…

uniapp实现楼层导航 ,滚动定位,锚点导航

uniapp实现楼层导航的核心技术要点&#xff1a; 1、scroll-view作为视图容器&#xff0c; 2、用其属性scroll-into-view,用于完成点击联动 3、uni.createSelectorQuery().selectAll();获取右侧所有元素信息&#xff0c;获取top值存入数组&#xff0c;用于计算滑动时需要的联动…

Vue-cli工程中每个文件夹和文件的用处

dist 文件夹&#xff1a;默认 npm run build 命令打包生成的静态资源文件&#xff0c;用于生产部署 node_modules&#xff1a;存放npm命令下载的开发环境和生产环境的依赖包 public&#xff1a;有的叫assets&#xff1a;存放项目中需要用到的资源文件&#xff0c;css、js、im…

【Linux】软件包管理器yum

​&#x1f320; 作者&#xff1a;阿亮joy. &#x1f386;专栏&#xff1a;《学会Linux》 &#x1f387; 座右铭&#xff1a;每个优秀的人都有一段沉默的时光&#xff0c;那段时光是付出了很多努力却得不到结果的日子&#xff0c;我们把它叫做扎根 目录&#x1f449;Linux软件…

未来已来,光伏产业将走向何方?十大趋势待揭晓!

碳中和大背景下&#xff0c;光伏已经成为发展最迅猛的热门产业之一。在能源产业变革中&#xff0c;光伏将成为未来最大的绿电来源。 据预测&#xff0c;到2030年&#xff0c;全球可再生能源的占比将超过50%。届时&#xff0c;光伏发电和风电将成为全球可再生能源的主力军。根据…

Android入门第50天-读写本地文件

简介 为了这个系列&#xff0c;我的代码已经准备到了第150天了。接下来的内容会越来越精彩&#xff0c;我们也越来越开始进入Android的一些高级功能上的编程了。今天我们就要讲Android中对本地文件进行读写的全过程。 课程目标 输入文件名、输入文件内容后按【保存到SD卡】&a…

毕业设计 - 基于SSH的任务调度系统的设计与实现 【源码+论文】

文章目录前言一、项目设计1. 模块设计2. 实现效果二、部分源码项目源码前言 今天学长向大家分享一个 Java web 毕业设计项目: 基于SSH的任务调度系统的设计与实现 一、项目设计 1. 模块设计 根据需求调研结果确定本任务调度系统的功能结构&#xff0c;最终系统实现的系统将…

Django

文章目录基础知识创建项目启动项目创建超级用户创建项目构建个人博客网站简单构建开启本地虚拟环境初步创建blog应用常用的模板标签和过滤器注&#xff1a;常用的模板标签注&#xff1a;常用的过滤器模板嵌套全局模板文件夹模板文件设置建议使用css美化页面导航栏页面美化css框…

捋一捋什么是MySQL插入意向锁?

Insert Intention Lock&#xff0c;中文我们也称之为插入意向锁。 这个可以算是对我们之前所讲的 Gap Lock 的一个补充&#xff0c;关于 Gap Lock&#xff0c;如果还有小伙伴不懂&#xff0c;可以参考&#xff1a;聊一聊MySQL的记录锁、间隙锁与 Next-Key Lock。 1. 为什么需…

Java基础之《netty(14)—异步模型》

一、基本介绍 1、异步的概念和同步相对。当一个异步过程调用发出后&#xff0c;调用者不能立刻得到结果。实际处理这个调用的组件在完成后&#xff0c;通过状态、通知和回调来通知调用者。 2、netty中的I/O操作是异步的&#xff0c;包括Bind、Write、Connect等操作会简单的返…

【云原生 | 47】etcdctl客户端的使用方法详解

&#x1f341;博主简介&#xff1a; &#x1f3c5;云计算领域优质创作者 &#x1f3c5;2022年CSDN新星计划python赛道第一名 &#x1f3c5;2022年CSDN原力计划优质作者 &#x1f3c5;阿里云ACE认证高级工程师 &#x1f3c5;阿里云开发者社区专…

后台基础权限框架搭建实现[木字楠博客]

文章目录1、项目整合SpringSecurity1.1、引入SpringSecurity依赖1.2、启动测试1.3、自定义实体类继承UserDetails1.4、自定义配制文件1.5、重写loadUserByUsername方法1.6、自定义匿名访问注解1.8、编写SpringSecurity配制类后台权限框架搭建&#xff1a;本项目权限主要依赖Spr…