Bi-LSTM-CRF实现中文命名实体识别工具(TensorFlow)
项目源码获取方式见文章末尾! 回复暗号:13,免费获取600多个深度学习项目资料,快来加入社群一起学习吧。
**《------往期经典推荐------》**
项目名称
1.【MobileNetV2实现实时口罩检测tensorflow】
2.【卫星图像道路检测DeepLabV3Plus模型】
3.【GAN模型实现二次元头像生成】
4.【CNN模型实现mnist手写数字识别】
5.【fasterRCNN模型实现飞机类目标检测】
6.【CNN-LSTM住宅用电量预测】
7.【VGG16模型实现新冠肺炎图片多分类】
8.【AlexNet模型实现鸟类识别】
9.【DIN模型实现推荐算法】
10.【FiBiNET模型实现推荐算法】
11.【钢板表面缺陷检测基于HRNET模型】
…
更多干货内容持续更新中…
1. 项目简介
本项目旨在开发一个基于深度学习的中文命名实体识别(Named Entity Recognition, NER)系统。命名实体识别是自然语言处理(Natural Language Processing, NLP)领域的重要任务之一,广泛应用于信息提取、文本分类、知识图谱构建等多个场景中。项目采用了双向长短时记忆网络(BiLSTM)与条件随机场(CRF)模型相结合的架构,通过深度学习模型自动学习文本中的实体边界和类型。该模型能够识别出三种类型的命名实体:人名、地名和组织名,并基于TensorFlow框架实现。中文NER具有独特的挑战,如缺乏显式的词边界以及实体上下文依赖较强,本项目通过对上下文信息的捕捉以及序列标注的优化来提升识别的准确性。最终目标是开发一个性能稳定、可扩展、易于部署的中文命名实体识别系统,为中文信息处理提供可靠的基础模块。
2.技术创新点摘要
- BiLSTM-CRF 模型架构的优化:项目采用了双向长短时记忆网络(BiLSTM)与条件随机场(CRF)相结合的模型架构。BiLSTM用于捕捉输入文本的上下文信息,使模型能够更好地理解中文字符间的依赖关系,而CRF则在输出层进行序列标注的全局优化,确保每个实体标注的逻辑连贯性,避免标注错误。该架构在命名实体识别任务中比传统的LSTM和CNN模型表现更好,能够捕捉更复杂的上下文模式。
- 嵌入层的灵活配置与更新策略:在嵌入层设计上,本项目允许选择使用预训练的字符嵌入(embedding)或随机初始化的嵌入向量,并提供了更新嵌入的选项(
update_embedding),使得模型能够动态调整嵌入向量以适应具体任务场景。这种灵活的嵌入策略使得模型能够更好地处理不同来源的文本数据,适应不同的应用场景。 - 梯度裁剪与自适应学习率策略:模型训练过程中使用了梯度裁剪(
gradient clipping)策略,有效避免了梯度爆炸问题,确保了模型的训练稳定性。同时,项目提供了多种优化器(如Adam、SGD等)的选择,并在学习率上采用了自适应调整策略(learning rate scheduling),能够根据训练过程中损失的变化动态调整学习率,提高模型的收敛速度。 - 基于序列长度的动态批量处理:模型在输入层使用了动态批量(
batch dynamic)设计,根据每个输入序列的实际长度进行填充处理,确保了模型能够高效处理不同长度的句子,降低了不必要的计算量,提高了训练和预测的效率。

3. 数据集与预处理
本项目使用的中文命名实体识别数据集主要来自公开的CoNLL-2003标准数据格式。数据集中的每个句子都被标注为三种命名实体类别:人名(PER)、地名(LOC)和组织名(ORG),并且遵循BIO标注格式,即实体前标有“B-”表示实体的开始,“I-”表示实体的中间部分,“O”则表示非实体部分。数据集中每个标注行包含了词汇和对应的标签,整体数据分为训练集、验证集和测试集。
数据集特点:
- 数据中存在多种字符类型(汉字、英文字符、数字等),需要处理多种类型混合的文本。
- 命名实体边界较难区分,尤其是在多种语言混杂或字符类型交替时,模型难以精准定位实体的起止位置。
- 不同实体类型的标签分布不均衡,特别是组织名(ORG)标签数量较少,模型可能出现类别不平衡问题。
数据预处理流程:
- 数据清洗与分词:首先,对原始文本进行数据清洗,去除无效字符和标点符号,并使用自定义分词工具对文本进行分词处理。分词后,每个词会被转换为唯一的词ID以便输入模型。
- 字典构建与标签转换:在数据清洗和分词后,项目根据所有出现的词汇生成词汇表(Vocabulary),并为每个标签创建对应的标签索引(tag2label)。所有句子中的词汇将根据该词汇表转换为词索引,标签也会被转换为标签ID。
- 特征工程与填充处理:针对中文文本中的词汇信息,本项目还引入了词嵌入(Word Embeddings)作为附加特征,以提升模型对不同字符含义的理解。同时,针对不同长度的句子,使用了序列填充(Padding)处理,使其能够统一输入到模型中进行训练。
- 数据集划分与增强:将原始数据集分为训练集、验证集和测试集,并通过数据增广技术(如随机替换同义词或删除非必要词语)来提升模型的泛化能力。
4. 模型架构
本项目采用了基于 双向长短时记忆网络(BiLSTM)和条件随机场(CRF) 的命名实体识别模型架构。其核心组件包括以下几个模块:
-
输入嵌入层(Embedding Layer) :
- 该层将输入的词汇序列转换为词向量表示,并利用词嵌入矩阵对每个词进行查找。
- 数学表示: E = W embedding [ X ] E = W_{\text{embedding}}[X] E=Wembedding[X] 其中,Wembedding 是预训练或随机初始化的嵌入矩阵,X 为输入的词序列,E 为对应的嵌入矩阵表示。
-
BiLSTM 层:
- 使用了双向 LSTM 单元(前向 LSTM 和后向 LSTM)来捕捉序列的上下文信息。BiLSTM 层能够同时处理前后依赖关系,以获得每个词的更完整表示。
- 数学表示:
-
$$\overrightarrow{h_t} = \text{LSTM}_{\text{fw}}(E_t, \overrightarrow{h_{t-1}})$$ - h t ← = LSTM bw ( E t , h t + 1 ← ) \overleftarrow{h_t} = \text{LSTM}_{\text{bw}}(E_t, \overleftarrow{h_{t+1}}) ht=LSTMbw(Et,ht+1)
- H t = [ h t → ; h t ← ] H_t = [\overrightarrow{h_t}; \overleftarrow{h_t}] Ht=[ht;ht]
- 其中, h t → \overrightarrow{h_t} ht 和 h t ← \overleftarrow{h_t} ht 分别为前向和后向 LSTM 的隐状态,Ht 是 BiLSTM 层的输出。
-
投影层(Projection Layer) :
- 该层将 BiLSTM 层输出的隐状态进行线性变换,以得到每个时间步上对所有标签的打分值(logits)。
- 数学表示: P t = H t × W + b P_t = H_t \times W + b Pt=Ht×W+b 其中,W 为权重矩阵,b 为偏置项,Pt 为每个时间步上对标签的打分结果。
-
条件随机场层(CRF Layer) :
- 用于处理序列标注任务中的标注依赖关系。通过对整个序列的打分来选择全局最优路径,确保输出标签之间的逻辑一致性。
- 目标函数(损失函数): log_likelihood = ∑ i = 1 N ( S ( X , y ) − log ∑ y ′ e S ( X , y ′ ) ) \text{log\_likelihood} = \sum_{i=1}^{N} \left( S(X, y) - \log \sum_{y'} e^{S(X, y')} \right) log_likelihood=i=1∑N S(X,y)−logy′∑eS(X,y′) 其中,S(X,y) 为输入序列 X 和标签序列 y 的评分函数,N 为序列总数。
-
模型训练流程:
- 输入准备:将文本数据转换为索引表示,并进行序列填充和标签转换。
- 构建图计算模型:通过
add_placeholders()创建输入占位符,再依次执行嵌入层(lookup_layer_op())、BiLSTM 层(biLSTM_layer_op())、投影层和 CRF 层的操作。 - 前向传播:计算输入序列经过 BiLSTM 和投影层后的输出(logits)。
- 损失计算:使用 CRF 的
crf_log_likelihood方法计算真实标签与预测标签的差距,并优化损失。 - 梯度裁剪与优化:采用指定的优化器(如 Adam)进行参数更新,并使用梯度裁剪(gradient clipping)避免梯度爆炸。
- 模型保存与验证:每轮训练结束后进行模型验证,并根据验证集的损失值保存模型。
-
评估指标:
- 准确率(Accuracy) :评估模型对实体边界及类别预测的准确程度。
- 精确率(Precision)、召回率(Recall)与 F1 值:在多标签分类任务中,使用 F1 值作为模型性能的主要衡量标准。
-
$$\text{Precision} = \frac{TP}{TP + FP}$$ - Recall = T P T P + F N \text{Recall} = \frac{TP}{TP + FN} Recall=TP+FNTP
- F 1 = 2 × Precision × Recall Precision + Recall F1 = \frac{2 \times \text{Precision} \times \text{Recall}}{\text{Precision} + \text{Recall}} F1=Precision+Recall2×Precision×Recall
- 通过
conlleval脚本对命名实体识别的结果进行详细分析,生成最终的评价报告
5. 核心代码详细讲解
代码段:
parser.add_argument('--train_data', type=str, default='data_path', help='train data source')
parser.add_argument('--epoch', type=int, default=40, help='#epoch of training')
parser.add_argument('--update_embedding', type=str2bool, default=True, help='update embedding during training')
parser.add_argument('--pretrain_embedding', type=str, default='random', help='use pretrained char embedding or init it randomly')
解释:
-
这些参数用于模型的初始化和数据处理:
--train_data: 定义训练数据的路径,便于后续读取数据文件。--epoch: 训练的迭代次数,默认为40次。--update_embedding: 是否在训练过程中更新嵌入矩阵。--pretrain_embedding: 指定使用预训练的词向量或随机初始化的嵌入矩阵。
代码段:
word2id = read_dictionary(os.path.join('.', args.train_data, 'word2id.pkl'))
if args.pretrain_embedding == 'random':embeddings = random_embedding(word2id, args.embedding_dim)
解释:
read_dictionary函数用于读取词汇表,将每个词映射到对应的词ID,并生成word2id字典。- 如果参数
pretrain_embedding设置为random,则会使用random_embedding函数来生成随机的词嵌入矩阵(随机分配每个词的向量表示)。
代码段:
def build_graph(self):self.add_placeholders()self.lookup_layer_op()self.biLSTM_layer_op()self.softmax_pred_op()self.loss_op()self.trainstep_op()
解释:
-
该函数是模型的核心架构构建函数,依次调用各层模块,完成计算图的搭建。
add_placeholders(): 创建输入、标签、序列长度等占位符。lookup_layer_op(): 执行词嵌入查找,将输入转换为嵌入表示。biLSTM_layer_op(): 使用双向 LSTM 处理序列输入,提取上下文特征。softmax_pred_op(): 执行标签的 Softmax 预测(仅在未使用 CRF 时)。loss_op(): 定义损失函数(CRF 损失或 Softmax 损失)。trainstep_op(): 设置优化器和训练步骤。
代码段:
def biLSTM_layer_op(self):with tf.variable_scope("bi-lstm"):cell_fw = LSTMCell(self.hidden_dim)cell_bw = LSTMCell(self.hidden_dim)(output_fw_seq, output_bw_seq), _ = tf.nn.bidirectional_dynamic_rnn(cell_fw=cell_fw,cell_bw=cell_bw,inputs=self.word_embeddings,sequence_length=self.sequence_lengths,dtype=tf.float32)output = tf.concat([output_fw_seq, output_bw_seq], axis=-1)output = tf.nn.dropout(output, self.dropout_pl)
解释:
-
biLSTM_layer_op是模型的双向 LSTM 层,用于提取序列上下文特征。cell_fw和cell_bw分别为前向和后向的 LSTM 单元。tf.nn.bidirectional_dynamic_rnn: 处理输入嵌入矩阵self.word_embeddings,根据序列长度sequence_length动态调整 LSTM 单元的计算。- 最后将前向和后向输出的隐状态拼接起来
tf.concat,并应用 Dropout 操作防止过拟合。
代码段:
def loss_op(self):if self.CRF:log_likelihood, self.transition_params = crf_log_likelihood(inputs=self.logits,tag_indices=self.labels,sequence_lengths=self.sequence_lengths)self.loss = -tf.reduce_mean(log_likelihood)else:losses = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=self.logits,labels=self.labels)mask = tf.sequence_mask(self.sequence_lengths)losses = tf.boolean_mask(losses, mask)self.loss = tf.reduce_mean(losses)tf.summary.scalar("loss", self.loss)
解释:
-
loss_op函数用于定义模型的损失计算方法。- 如果使用 CRF 层:调用
crf_log_likelihood函数计算条件随机场的对数似然,并返回转移参数self.transition_params和对数似然值。 - 如果不使用 CRF:采用
sparse_softmax_cross_entropy_with_logits计算交叉熵损失,并对序列长度进行掩码处理(sequence_mask)。 - 最终通过
tf.reduce_mean求均值,得到整体的损失值。
- 如果使用 CRF 层:调用
代码段:
def trainstep_op(self):with tf.variable_scope("train_step"):self.global_step = tf.Variable(0, name="global_step", trainable=False)optim = tf.train.AdamOptimizer(learning_rate=self.lr_pl)grads_and_vars = optim.compute_gradients(self.loss)grads_and_vars_clip = [[tf.clip_by_value(g, -self.clip_grad, self.clip_grad), v] for g, v in grads_and_vars]self.train_op = optim.apply_gradients(grads_and_vars_clip, global_step=self.global_step)
解释:
-
trainstep_op定义了模型的训练步骤:- 使用
tf.train.AdamOptimizer定义 Adam 优化器,并基于损失函数self.loss计算梯度。 - 进行梯度裁剪(
clip_by_value)以防止梯度爆炸。 optim.apply_gradients将优化后的梯度应用于模型参数,并更新全局步骤global_step。
- 使用
代码段:
def train(self, train, dev):saver = tf.train.Saver(tf.global_variables())with tf.Session(config=self.config) as sess:sess.run(self.init_op)self.add_summary(sess)for epoch in range(self.epoch_num):self.run_one_epoch(sess, train, dev, self.tag2label, epoch, saver)
解释:
-
train函数是模型的核心训练流程:- 使用
tf.Session启动 TensorFlow 会话,并运行self.init_op进行变量初始化。 - 调用
run_one_epoch函数,进行每一轮训练(每个 epoch 处理一次完整的训练集)。
- 使用
6. 模型优缺点评价
模型优点:
- BiLSTM + CRF 的高效结合:模型通过双向 LSTM 提取文本上下文信息,并利用 CRF 层进行全局标注优化,能够有效解决实体边界和标签依赖问题。尤其在处理长文本和复杂依赖关系时,能够提供更高的精度和召回率。
- 灵活的嵌入层配置:模型允许使用预训练的词向量或随机初始化的嵌入矩阵,并提供了更新嵌入选项,适应不同类型的数据和任务需求,提高了模型的泛化能力。
- 动态序列处理与梯度裁剪:模型通过动态批处理的方式处理不同长度的输入序列,并使用梯度裁剪避免梯度爆炸,确保了训练的稳定性。
- 丰富的超参数配置选项:如优化器选择、学习率调整、Dropout 比例、CRF 使用与否等,用户能够根据任务需求灵活配置,进一步提升模型性能。
模型缺点:
- 模型训练时间较长:由于 BiLSTM 需要同时处理前向和后向序列,训练和推理时间相对较长,尤其在大规模数据集上,计算开销较大。
- 对标签分布不均衡敏感:当某些标签类别样本较少时,模型可能会偏向于预测频率更高的类别,导致少数类别的识别效果不佳。
- 模型参数较多,容易过拟合:模型引入了多个层次的 LSTM 和 CRF 参数,若数据量不足或正则化不足,容易导致过拟合。
改进方向:
- 模型结构优化:可尝试引入自注意力机制(Self-Attention)或 Transformer 层,进一步增强对长距离依赖的捕捉能力,并提高训练效率。
- 超参数优化:采用超参数搜索(如 Grid Search 或 Bayesian Optimization)来自动选择最佳的学习率、LSTM 隐层维度等超参数。
- 数据增强方法:增加同义词替换、随机删除等数据增强策略,提升模型对数据多样性的适应能力,从而提高模型的泛化效果。
↓↓↓更多热门推荐:
基于opencv答题卡识别判卷
👍感谢小伙伴们点赞、关注! 如有其他项目需求的,可以在评论区留言,抽空制作更新!
✌粉丝福利:点击下方名片↓↓↓ , 回复暗号:13,免费获取600多个深度学习项目资料,快来加入社群一起学习吧。
相关文章:
Bi-LSTM-CRF实现中文命名实体识别工具(TensorFlow)
项目源码获取方式见文章末尾! 回复暗号:13,免费获取600多个深度学习项目资料,快来加入社群一起学习吧。 **《------往期经典推荐------》**项目名称 1.【MobileNetV2实现实时口罩检测tensorflow】 2.【卫星图像道路检测DeepLabV3P…...
从JDK 17 到 JDK 21:Java 新特性
JDK17 密封类 概念:密封类允许开发者控制哪些类可以继承或实现特定的类或接口。通过这种方式,密封类为类的继承提供了更高的安全性和可维护性。 定义:使用sealed代表该类为密封类,并用permits限制哪些类可以继承。 public sea…...
【计算机网络 - 基础问题】每日 3 题(五十七)
✍个人博客:https://blog.csdn.net/Newin2020?typeblog 📣专栏地址:http://t.csdnimg.cn/fYaBd 📚专栏简介:在这个专栏中,我将会分享 C 面试中常见的面试题给大家~ ❤️如果有收获的话,欢迎点赞…...
第十二章 章节练习created的应用
目录 一、引言 二、运行效果图 三、完整代码 一、引言 构建一个新闻的页面,页面在响应式数据准备好之后(即created),就向后台接口请求获取新闻数据列表,然后赋值给Vue实例中的list列表,这个请求逻辑我…...
Unity 游戏性能优化实践:内存管理与帧率提升技巧
1. 引言 随着移动设备性能的逐步提升,游戏玩家对画质和流畅度的要求越来越高。优化 Unity 游戏性能不仅可以提升用户体验,还能降低设备的功耗,延长电池寿命。这篇文章将深入探讨如何在 Unity 中优化游戏的内存管理与帧率,通过多方…...
C++游戏开发详解
C 是一种广泛使用的编程语言,尤其在游戏开发领域有着不可替代的地位。它提供了对底层硬件的直接访问能力,允许开发者优化性能,这对于追求高帧率和低延迟的游戏来说至关重要。本文将详细介绍使用 C 进行游戏开发的基础知识和技术要点ÿ…...
三、大模型(LLMs)微调面
本文精心汇总了多家顶尖互联网公司在大模型基础知识考核中的核心考点,并针对这些考点提供了详尽的解答。并提供电子版本,见于文末百度云盘链接中,供读者查阅。 一、大模型微调 • 1 如果想要在某个模型基础上做全参数微调,究竟需要…...
Flutter升级与降级
升级 版本升级 // 升级到指定版本flutter upgrade 版本号// 升级到最新版本flutter upgrade 降级 1.需要先确定想要降级的版本号。 2.切换到系统安装Flutter的目录 3.在https://github.com/flutter/flutter,找到要回退的版本号对应的commit序号(具…...
分布式并发场景的核心问题与解决方案
文章目录 分布式并发场景的核心问题与解决方案一、核心问题分析1. 分布式事务问题2. 数据一致性问题3. 并发控制问题4. 分布式锁失效问题 二、解决方案1. 分布式事务解决方案1.1 可靠消息最终一致性方案1.2 TCC方案实现 2. 缓存一致性解决方案2.1 延迟双删策略2.2 Canal方案 3.…...
D - Many Segments 2(ABC377)
题意:给定n和m,给定n个区间li,ri,求出满足区间lr不完全包含区间liri的个数 分析:用优先队列对区间r进行排序,i表示左区间,每次找到右区间加入即可。 代码: #include<bits/stdc…...
数组指针和指针数组的区别
数组指针和指针数组的区别 根据我个人的理解如下: 数组指针:指向数组的指针。着重点在于最后的指针两个字。 指针数组: 所有元素都是指针的数组。着重点在于最后的数组两个字。 另外来看助手的回答: Kimi: 1. **数组指针(Ar…...
【VUE点击父组件按钮,跳转到子组件】
要实现在Vue中,父组件通过点击按钮进入子组件的 <el-dialog> 弹窗,并在弹窗中嵌套 <el-table> 表格,可以按照以下步骤进行编写代码: 在父组件中,定义一个数据属性用于控制子组件弹窗的显示与隐藏。 data…...
Java列表排序:方法与实践
在Java编程中,列表排序是一个常见且重要的任务。本文将介绍Java中对列表进行排序的几种方法,包括使用Collections.sort()、List.sort()以及自定义排序规则。 1. 使用Collections.sort() Collections.sort()是Java提供的一个静态方法,用于对…...
哈希及其封装实现unordermap和set
哈希 直接定址法 哈希和之前的红黑树的区别就是,它是通过映射关系来找到目标的,可以把它想象成之前排序的计数排序,那其实就是哈希的一种方法,叫做直接定址法。 对于比较集中的数据,它只需要开一段区间,…...
在 AMD GPU 上构建解码器 Transformer 模型
Building a decoder transformer model on AMD GPU(s) — ROCm Blogs 2024年3月12日 作者 Phillip Dang. 在这篇博客中,我们展示了如何使用 PyTorch 2.0 和 ROCm 在单个节点上的单个和多个 AMD GPU 上运行Andrej Karpathy’s beautiful PyTorch re-implementation …...
Canvas简历编辑器-选中绘制与拖拽多选交互设计
Canvas简历编辑器-选中绘制与拖拽多选交互设计 在之前我们聊了聊如何基于Canvas与基本事件组合实现了轻量级DOM,并且在此基础上实现了如何进行管理事件以及多层级渲染的能力设计。那么此时我们就依然在轻量级DOM的基础上,关注于实现选中绘制与拖拽多选交…...
简单工厂(Simple Factory)
简单工厂(Simple Factory) 在创建一个对象时不向客户暴露内部细节,并提供一个创建对象的通用接口。 说明: 简单工厂把实例化的操作单独放到一个类中,这个类就成为简单工厂类,让简单工厂类来决定应该用哪…...
ffmpeg拉流分段存储到文件-笔记
通过ffmpeg可以从rtsp网络流拉取数据并存储到本地文件里,如下命令。做个笔记 ffmpeg -rtsp_transport tcp -i rtsp://192.168.1.168:6880/live -c copy -f segment -segment_time 60 stream_piece_%d.mp4这条 ffmpeg 命令的作用是从一个 RTSP 流中捕获视频ÿ…...
Java 实习工资大概是多少?——解读影响薪资的因素
文章目录 1. 城市因素:一线、二线的差距2. 公司类型:互联网公司、外企和传统企业的差别3. 个人能力:经验、技术栈的重要性4. 其他影响因素:学历和实习时间总结推荐阅读文章 Java 开发作为广泛应用的职业方向,实习工资的…...
【Linux】万字详解:Linux文件系统与软硬链接
🌈 个人主页:Zfox_ 🔥 系列专栏:Linux 目录 🚀 前言 一: 🔥 磁盘的物理结构二: 🔥 磁盘的存储结构 三: 🔥 磁盘的逻辑结构 四: &#…...
Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动
一、前言说明 在2011版本的gb28181协议中,拉取视频流只要求udp方式,从2016开始要求新增支持tcp被动和tcp主动两种方式,udp理论上会丢包的,所以实际使用过程可能会出现画面花屏的情况,而tcp肯定不丢包,起码…...
基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容
基于 UniApp + WebSocket实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...
【位运算】消失的两个数字(hard)
消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...
关于nvm与node.js
1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...
AtCoder 第409场初级竞赛 A~E题解
A Conflict 【题目链接】 原题链接:A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串,只有在同时为 o 时输出 Yes 并结束程序,否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...
UDP(Echoserver)
网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法:netstat [选项] 功能:查看网络状态 常用选项: n 拒绝显示别名&#…...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...
css3笔记 (1) 自用
outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size:0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格ÿ…...
Docker 本地安装 mysql 数据库
Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker ;并安装。 基础操作不再赘述。 打开 macOS 终端,开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...
20个超级好用的 CSS 动画库
分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码,而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库,可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画,可以包含在你的网页或应用项目中。 3.An…...
