机器翻译基础与模型 之三:基于自注意力的模型
基于RNN和CNN的翻译模型,在处理文字序列时有个问题:它们对序列中不同位置之间的依赖关系的建模并不直接。以CNN的为例,如果要对长距离依赖进行描述,需要多层卷积操作,而且不同层之间信息传递也可能有损失,这些都限制了模型的能力。
为了更好地描述文字序列,研究人员提出了一种新的模型 Transformer。 Transformer 并不依赖任何循环单元或者卷积单元,而是使用一种被称作自注意力网络的结构来对序列进行表示。自注意力可以非常高效的描述任意距离之间的依赖关系,因此非常适合处理语言文字序列。
Transformer 一经提出就受到了广泛关注,现在已经成为了机器翻译中最先进的架构之一。
一、自注意力机制
在RNN中处理文字序列,如果想建立wm 和 w1 之间的关系,需要 m−1 次信息传递。对于长序列来说,词汇之间信息传递距离过长会导致信息在传递过程中丢失,同时这种按顺序建模的方式也使得系统对序列的处理十分缓慢。
自注意力机制直接建立单词 wm与前 m−1 个单词之间的关系,即 wm 与序列中所有其他单词的距
离都是 1。这种方式很好地解决了长距离依赖问题,同时由于单词之间的联系都是相互独立的,因此也大大提高了模型的并行度。
自注意力机制也可以被看作是一个序列表示模型。
比如,对于每个目标位置 j,都生成一个与之对应的源语言句子表示,它的形式如下:
Cj = Sum(αi,jhi) 。其中,hi 为源语言句子每个位置的表示结果, αi,j 是目标位置 j 对 hi 的注意力权重。
以源语言句子为例,自注意力机制将序列中每个位置的表示 hi 看作 query(查询),并且将所有位置的表示看作 key(键)和 value (值)。自注意力模型通过计算当前位置与所有位置的匹配程度,也就是在注意力机制中提到的注意力权重,来对各个位置的 value 进行加权求和。得到的结果可以被看作是在这个句子中当前位置的抽象表示。
这个过程,可以叠加多次,形成多层注意力模型,对输入序列中各个位置进行更深层的表示。
在自注意力机制中,并不是使用类似RNN的记忆能力去访问历史信息。序列中所有单词之间的信息都是通过同一种操作(query 和 key 的相关度)进行处理。这样,表示结果 h˜(他) 在包含“他”这个单词的信息的同时,也包含了序列中其他词的信息。
也就是,序列中每一个位置的表示结果中,都包含了其他位置的信息。从这个角度说, h˜(他) 已经不再是单词“他”自身的表示结果,而是一种在单词“他”的位置上的全局信息的表示。
通常,也把生成 h˜(wi) 的过程看作特征提取,而实现这个过程的模型被称为特征提取器。
二、Transformer架构
2.1 Transformer优势
Transformer 模型仅仅使用自注意力机制和标准的前馈神经网络,完全不依赖任何循环单元或者卷积操作。很好地解决了单词间长距离依赖的问题。自注意力机制非常适合在 GPU 上进行并行化,因此模型训练的速度更快。
Transformer 也可以当作一种表示模型,被大量地使用在NLP的其他领域,甚至图像处理和语音处理中也能看到它的影子。比如,目前非常流行的 BERT 等预训练模型就是基于 Transformer。
Transformer 在 WMT英德和英法机器翻译任务上的性能。它能用更少的计算量(FLOPs)达到比其他模型更好的翻译品质。
Transformer 并不简单等同于自注意力机制。 Transformer 模型还包含了很多优秀的技术,比如:多头注意力、新的训练学习率调整策略等等。这些因素一起组成了真正的 Transformer。
2.2 总体结构
自注意力子层(Self-Attention Sub-layer):使用自注意力机制对输入的序列进行新的表示;
前馈神经网络子层(Feed-Forward Sub-layer):使用全连接的前馈神经网络对输入向量序列进行进一步变换;
残差连接(标记为“Add”):对于自注意力子层和前馈神经网络子层,都有一个从输入直接到输出的额外连接,也就是一个跨子层的直连。残差连接可以使深层网络的信息传递更为有效;
层标准化(Layer Normalization):自注意力子层和前馈神经网络子层进行最终输出之前,会对输出的向量进行层标准化,规范结果向量取值范围,这样易于后面进一步的处理。
以上操作就构成了 Transformer 的一层,各个模块执行的顺序可以简单描述为:
Self-Attention → Residual Connection → Layer Normalization → Feed Forward Network → Residual Connection → Layer Normalization。
解码器中引入了一个额外的编码-解码注意力子层(EncoderDecoder Attention Sub-layer)。这个新的子层,可以帮助模型使用源语言句子的表示信息生成目标语言不同位置的表示。编码-解码注意力子层仍然基于自注意力机制,因此它和自注意力子层的结构是相同的,只是 query、 key、 value 的定义不同。
2.3 位置编码
采用自注意力机制对源语言和目标语言序列进行处理时,直接对当前位置和序列中的任意位置进行建模,忽略了词之间的顺序关系。为了解决这个问题,Transformer 在原有的词向量输入基础上引入了位置编码,来表示单词之间的顺序关系。它是Transformer 成功的一个重要因素。
位置编码的计算方式有很多种, Transformer 使用不同频率的正余弦函数,式中 PE(·) 表示位置编码的函数, pos 表示单词的位置, i 代表位置编码向量中的第几维, dmodel 是 Transformer 的一个基础参数,表示每个位置的隐层大小。
在Transformer 中,位置编码的维度和词嵌入向量的维度相同(均为 dmodel),模型通过
将二者相加作为模型输入。
为什么通过这种计算方式可以很好的表示位置信息?有几方面原因。
首先,正余弦函数是具有上下界的周期函数,用正余弦函数可将长度不同的序列的位置编
码的范围都固定到 [−1,1],这样在与词的编码进行相加时,不至于产生太大差距。
另外位置编码的不同维度对应不同的正余弦曲线,这为多维的表示空间赋予一定意义。
最后,根据三角函数的性质,对于任意固定的偏移量 k, PE(pos + k) 能被表示成 PE(pos) 的线性函数,换句话说,位置编码可以表示词之间的距离。
在实践中发现,位置编码对 Transformer 系统的性能有很大影响。对其进行改进也会带来进一步的性能提升。
2.4 基于点乘的多头注意力机制
Transformer 模型摒弃了循环单元和卷积等结构,完全基于注意力机制来构造模型,其中包含着大量的注意力计算。比如,可以通过自注意力机制对源语言和目标语言序列进行信息提取,并通过编码-解码注意力对双语句对之间的关系进行建模。而这些模块都是由基于点乘的多头注意力机制实现的。
2.4.1 点乘注意力机制
自注意力机制中至关重要的是获取相关性系数,也就是在融合不同位置的表示向量时各位置的权重。 Transformer 模型采用了一种基于点乘的方法来计算相关性系数。这种方法也称为缩放的点乘注意力(Scaled Dot-product Attention)机制。
在注意力机制的计算过程中,包含三个重要的参数,分别是 query,key 和 value。将目标语言每个位置的表示视为编码-解码注意力机制的 Q,源语言句子的表示视为 K 和V。在得到 Q, K 和 V 后,便可以进行注意力的运算,这个过程可以被形式化为:
通过对 Q 和 K 的转置进行矩阵乘法操作,计算得到一个维度大小为 L × L 的相关性矩阵,即 QK_T,它表示一个序列上任意两个位置的相关性。再通过系数 1/√dk进行放缩操作,放缩可以减少相关性矩阵的方差,具体体现在运算过程中实数矩阵中的数值不会过大,有利于模型训练。在此基础上,通过对相关性矩阵累加一个掩码矩阵 Mask,来屏蔽掉矩阵中的无用信息。
然后使用 Softmax 函数对相关性矩阵在行的维度上进行归一化操作,这可以理解为对第 i 行进行归一化,结果对应了 V 中不同位置上向量的注意力权重。对于 value的加权求和,可以直接用相关性系数和 V 进行矩阵乘法得到,即 Softmax(√QKdkT +Mask)和 V 进行矩阵乘。最终得到自注意力的输出,它和输入的 V 的大小是一模一样的。
2.4.2 多头注意力机制 (Multi-head Attention)
“多头”可以理解成将原来的 Q、 K、 V 按照隐层维度平均切分成多份。假设切分 h份,那么最终会得到 Q = {Q1,...,Qh}, K = {K1,...,Kh}, V = {V1,...,Vh}。多头注意力就是用每一个切分得到的 Q, K, V 独立的进行注意力计算,即第 i 个头的注意力计算结果 headi = Attention(Qi,Ki,Vi)。
多头注意力的计算过程:
多头注意力机制的好处是允许模型在不同的表示子空间里学习。在很多实验中发现,不同表示空间的头捕获的信息是不同的,比如,在使用 Transformer 处理自然语言时,有的头可以捕捉句法信息,有的头可以捕捉词法信息。
2.4.3 掩码操作
掩码(Mask)的目的是对向量中某些值进行掩盖,避免无关位置的数值对运算造成影响。 Transformer 中的掩码主要应用在注意力机制中的相关性系数计算,具体方式是在相关性系数矩阵上累加一个掩码矩阵。该矩阵在需要掩码的位置的值为负无穷 −inf(具体实现时是一个非常小的数,比如 −1e9),其余位置为 0,这样在进行了 Softmax 归一化操作之后,被掩码掉的位置计算得到的权重便近似为 0,也就是说对无用信息分配的权重为 0,从而避免了其对结果产生影响。
Transformer 包含两种掩码:
a.句长补全掩码(Padding Mask)
训练样本中每个批次内序列的长度不一样,为了方便对批次内序列进行矩阵表示,需要进行对齐操作,即在较短的序列后面填充 0 来占位(padding 操作)。
b.未来信息掩码(Future Mask)
对于解码器来说,由于在预测的时候是自左向右进行的,即第 t 时刻解码器的输出只能依赖于 t 时刻之前的输出。且为了保证训练解码一致,避免在训练过程中观测到目标语言端每个位置未来的信息,因此需要对未来信息进行屏蔽。
具体的做法是:构造一个上三角值全为-inf 的 Mask矩阵。即在解码器计算中,在当前位置,通过未来信息掩码把序列之后的信息屏蔽掉了,避免了 t 时刻之后的位置对当前的计算产生影响。
2.5 残差网络和层标准化
在 Transformer 的训练过程中,为了避免产生梯度爆炸或者消失,引入了残差操作,将前面所有层的输出加到一起。但为了避免不同层(或子层)的结果之间的差异性较大,造成训练过程不稳定、训练时间较长,在每层中加入了层标准化操作。
在 Transformer 中经常使用的层标准化操作有两种结构,分别是后标准化(Post norm)和前标准化(Pre-norm)。后标准化中先进行残差连接再进行层标准化,而前标准化则是在子层输入之前进行层标准化操作。在很多实践中已经发现,前标准化的方式更有利于信息传递,因此适合训练深层的 Transformer 模型。
2.6 前馈全连接网络子层
Transformer 全连接网络的作用主要体现在将经过注意力操作之后的表示映射到新的空间中,新的空间会有利于接下来的非线性变换等操作。实验证明,去掉全连接网络会对模型的性能造成很大影响。 Transformer 的全连接前馈神经网络包含两次线性变换和一次非线性变换(ReLU 激活函数:ReLU(x) = max(0,x)),每层的前馈神经网络参数不共享。
通常情况下,前馈神经网络的隐层维度要比注意力部分的隐层维度大,而且研究人员发现这种设置对 Transformer 是至关重要的。比如,注意力部分的隐层维度为 512,前馈神经网络部分的隐层维度为 2048。继续增大前馈神经网络的隐层大小,比如设为 4096,甚至 8192,还可以带来性能的增益,但是前馈部分的存储消耗较大,需要更大规模 GPU 设备的支持。因此在具体实现时,往往需要在翻译准确性和存储/速度之间找到一个平衡。
2.7 训练
2.7.1 训练优化器配置
在训练优化器方面,需要注意以下几点:
• Transformer 使用 Adam 优化器优化参数,并设置 β1 = 0.9, β2 = 0.98, ϵ = 10−9
• Transformer 在学习率中同样应用了学习率预热(Warmup)策略。
• 小批量训练(Mini-batch Training):每次从样本中选择一小部分数据进行训练。这种方法的收敛较快,同时易于提高设备的利用率。批次大小通常设置为 2048 或 4096。每一个批次中的句子并不是随机选择的,模型通常会根据句子长度进行排序,选取长度相近的句子组成一个批次。这样做可以减少 padding 数量,提高训练效率。
• Dropout:为了避免过拟合,Transformer 加入了 Dropout 操作。这四个地方用到了Dropout:词嵌入和位置编码、残差连接、注意力操作和前馈神经网络。 Dropout比例通常设置为 0.1。
• 标签平滑(Label Smoothing):简单的说就是给正确答案以外的类别分配一定的概率,而不是采用非 0 即 1 的概率。这样,可以学习一个比较平滑的概率分布,从而提升泛化能力。
2.7.2 模型具体配置
常见的 Transformer 模型有 TransformerBase、 Transformer Big 和 Transformer Deep,具体设置如下:
• Transformer Base:标准的 Transformer 结构,解码器编码器均包含 6 层,隐层维度为 512,前馈神经网络维度为 2048,多头注意力机制为 8 头, Dropout 设为 0.1。
• Transformer Big:为了提升网络的容量,使用更宽的网络。在 Base 的基础上增大隐层维度至 1024,前馈神经网络的维度变为 4096,多头注意力机制为 16 头,Dropout 设为 0.3。
• Transformer Deep:加深编码器网络层数可以进一步提升网络的性能,它的参数设置与 Transformer Base 基本一致,但是层数增加到 48 层,同时使用 Pre-Norm作为层标准化的结构。
2.8 推断
Transformer 解码器生成译文词序列的过程和其它神经机器翻译系统类似,都是从左往右生成,且下一个单词的预测依赖已经生成的单词。
Transformer 在推断阶段无法对所有位置进行并行化操作,因为对于每一个目标语言单词都需要对前面所有单词进行注意力操作,因此它推断速度非常慢。可以采用的加速手段有: Cache(缓存需要重复计算的变量)、低精度计算、共享注意力网络等。
相关文章:
机器翻译基础与模型 之三:基于自注意力的模型
基于RNN和CNN的翻译模型,在处理文字序列时有个问题:它们对序列中不同位置之间的依赖关系的建模并不直接。以CNN的为例,如果要对长距离依赖进行描述,需要多层卷积操作,而且不同层之间信息传递也可能有损失,这…...
如何使用PCL处理ROS Bag文件中的点云数据并重新保存 ubuntu20.04
如何使用PCL处理ROS Bag文件中的点云数据并重新保存 要精确地处理ROS bag中的点云数据并使用PCL进行处理,再将处理后的数据保存回新的ROS bag文件,以下方案提供了详细、专业和严谨的步骤。 步骤 1: 环境设置 确保安装了ROS和PCL,并配置好环…...
背包问题(动态规划)
背包问题是一种组合优化的问题,它有多种变体,但最常见的两种是0/1背包问题和完全背包问题。 0/1背包问题 问题描述: 假设你有一个背包,背包的容量为W(可以是重量或者体积等度量),同时有n个物品…...
从0开始学习机器学习--Day26--聚类算法
无监督学习(Unsupervised learning and introduction) 监督学习问题的样本 无监督学习样本 如图,可以看到两者的区别在于无监督学习的样本是没有标签的,换言之就是无监督学习不会赋予主观上的判断,需要算法自己去探寻区别,第二张…...
Vue3插槽v-slot使用方式
在 Vue 3 中,v-slot 是用来定义和使用插槽的指令。插槽是 Vue 的一个功能,允许你在组件内部定义占位内容,便于在父组件中提供动态内容。以下是 v-slot 的详细使用方法: 1. 基础使用 <template><BaseComponent><te…...
Axure二级菜单下拉交互实例
1.使用boxlabe进行基础布局 2.设置鼠标悬浮和选中状态 3.转换为动态面板 选中所有二级菜单,进行按钮组转换 选中所有二级菜单,进行动态面板转换 4.给用户管理增加显示/隐藏事件 1)选择toggle代表上拉和下拉切换加载 2)勾选Bring to Front,并选择Push/Pull Widgets代表收缩时…...
华为VPN技术
1.启动设备 2.配置IP地址 [FW1]int g1/0/0 [FW1-GigabitEthernet1/0/0]ip add 192.168.1.254 24 [FW1-GigabitEthernet1/0/0]int g1/0/1 [FW1-GigabitEthernet1/0/1]ip add 100.1.1.1 24 [FW1-GigabitEthernet1/0/1]service-manage ping permit [FW2]int g1/0/0 [FW2-Gi…...
CommonsBeanutils与Shiro发序列化利用的学习
一、前言 前面的学习中,过了一遍cc1-cc7的利用链,在CC2的利用链中,学习了 java.util.PriorityQueue,它在Java中是一个优先队列,队列中每一个元素都有自己的优先级。在反序列化这个对象时,为了保证队列顺序…...
运维云计算SRE-第2周
1. 总结学过的权限,属性及ACL相关命令及选项,示例。 一、Linux安全模型 (一)资源分派 Authentication(认证):验证用户身份,确保登录系统的用户是合法的。 Authorization(…...
React Native 全栈开发实战班 - 用户界面进阶之响应式设计实践
在移动应用开发中,响应式设计 是确保应用在不同设备、屏幕尺寸和方向下都能提供良好用户体验的关键。React Native 提供了多种工具和技巧来实现响应式设计,包括 Flexbox 布局、动态样式、屏幕尺寸适配等。本章节将详细介绍如何在 React Native 中进行响应…...
SlickGrid点击/双击事件
分析 SlickGrid提供了点击事件方法grid.onClick和grid.onDblClick用于捕获用户对表格列的点击,捕获到点击事件之后,修改表格数据,然后使用grid.updateRow方法将修改后的数据更新到表格中。 展示 代码 创建grid(HTML)…...
一文详细深入总结服务器选型
1. 题记: 服务器选型工作是项目规划检讨的一项非常重要的工作,本文详细深入总结服务器选型。 2. 服务器基础知识概览 2.1 服务器的定义与功能 2.1 .1 定义 服务器是一种高性能计算机,其设计目的是在网络中提供服务。它可以处理来自多个客…...
一、Nginx反向代理(七层代理)二、Nginx的TCP/UDP调度器(四层代理)
一、Nginx反向代理(七层代理) 实验要求 使用Nginx实现Web反向代理功能,实现如下功能: 后端Web服务器两台,可以使用httpd实现Nginx采用轮询的方式调用后端Web服务器两台Web服务器的权重要求设置为不同的值最大失败次数为…...
CSS+JQuery 实现弹力球效果,碰到屏幕边框弹回
实现弹力球效果,碰到屏幕边框弹回,效果如下 代码如下: <img src"../image/ball.png" alt"" class"ball"> <style>.ball {position: fixed;top: 50vh;left: 50vw;width: 15vw;height: 15vw;border…...
shell编程规范和脚本变量
什么是shell 人和计算机内核之间的中介: 计算机的语言是二进制,把人类的语言翻译成计算机能够识别的语言,然后让内核来处理 内核完成之后要把结果反馈给用户,要把计算机的翻译成人类能够识别的语言 命令解释器,pyc…...
jspm美容院管理系统
摘要 首先,论文一开始便是清楚的论述了系统的研究内容。其次,剖析系统需求分析,弄明白“做什么”,分析包括业务分析和业务流程的分析以及用例分析,更进一步明确系统的需求。然后在明白了系统的需求基础上需要进一步地设计系统,主要包罗软件架构模式、整体功能模块、数据库设计…...
Prometheus结合K8s(二)使用
上一篇介绍了如何搭建 Prometheus结合K8s(一)搭建-CSDN博客,这章介绍使用 页面访问 kubectl get svc -n prom 看promeheus和granfana的端口访问页面 Prometheus 点击status—target,可以看到metrics的数据来源,即各…...
【虚幻引擎】UE5数字人开发实战教程
本套课程将会交大家如何去开发属于自己的数字人,包含大模型接入,流式输出,语音识别,语音合成,口型驱动,动画蓝图,语音唤醒等功能。 课程介绍视频如下: 【虚幻引擎】UE5 历时一个多月…...
深入分析:固定参考框架在RViz中的作用与对数据可视化的影响 ros ubuntu20.04
深入分析:固定参考框架在RViz中的作用与对数据可视化的影响 RViz (Robot Visualization) 是 ROS (Robot Operating System) 中一种重要的三维可视化工具,主要用于实时观察和分析传感器数据、机器人状态信息以及环境模型。RViz的核心功能之一是固定参考框…...
Android:时间选择器(最下面有效果图)
1.创建DateUtil类 /*** Created by wangshuai on 2024/11/19.*/ public class DateUtil {public final static String PATTERN_ALL"yyyy-MM-dd HH:mm:ss";public final static String PATTERN_DEFAULT"yyyy-MM-dd";/*** 获取当前时间* return yyyy-MM-dd*…...
第十六届蓝桥杯模拟赛(第一期)-c++/c
c/c蓝桥杯模拟赛题解,非常详细 质因数 1、填空题 【问题描述】 如果一个数 p 是个质数,同时又是整数 a 的约数,则 p 称为 a 的一个质因数。 请问 2024 有多少个质因数。 【答案提交】 这是一道结果填空的题,你只需要算出结果后提…...
如何挑选路由器?需要看哪些参数?
挑选路由器时,选择合适的型号和参数对于确保家庭或办公网络的速度、稳定性和覆盖范围至关重要。以下是挑选路由器时需要考虑的关键参数和因素: 1. 无线标准 (Wi-Fi标准) 无线标准是衡量路由器性能的核心指标。不同的无线标准提供不同的速率、范围和技术…...
mysql-备份(二)
前章介绍了MySQL的内部数据结构btree,这章讲述mysql的备份 1:环境 ubuntu22.04 LST mysql5.7.42 or win10 mysql5.7.44 (这里图简单直接windows部署) download:https://downloads.mysql.com/archives/community/ 2:install 1> unzip mysql-5.7.44-w…...
Tailwind CSS 和 UnoCSS简单比较
UnoCSS 和 Tailwind CSS 都是流行的原子化 CSS 框架,但它们在设计理念、性能和使用方式上有一些重要的区别。下面是对它们的详细对比: 1. 概述 Tailwind CSS:Tailwind 是一个原子化的 CSS 框架,提供了大量的预定义类(…...
unity3d————范围检测
目录 知识点一:什么是范围检测 知识点二:如何进行范围检测 问题: Physics.queriesHitTriggers 怎么查看是不是true? QueryTriggerInteraction.UseGlobal 参数意味着是否检测触发器将依据全局设置 Physics.queriesHitTrigge…...
修改this.$confirm的按钮位置、图标、文字及标题
在Vue.js项目中,this.$confirm 通常是基于某些UI库(如Element UI或Ant Design Vue)的对话框确认方法。 以下是基于Element UI的this.$confirm的用法示例。 在此之前,你的项目要已经安装了Element UI,如果没安装话就打…...
SQL MID() 函数详解
SQL MID() 函数详解 SQL 中的 MID() 函数是一个非常有用的字符串处理工具,它允许用户从字符串中提取特定位置的子字符串。这个函数在数据库查询和报告中特别有用,尤其是在需要从较长的文本字段中提取特定信息时。本文将详细介绍 MID() 函数的用法、参数…...
【蓝桥杯备赛】123(前缀和的复杂应用)
5. 前缀和的复杂应用 5.1. 123(4 星) 5.1.1. 题目解析 这道题仍然是求一段区间的和,很容易能够想到前缀和找规律: 1------------------1 号块 1 2----------------2 号块 1 2 3--------------3 号块 1 2 3 4------------4 号…...
MINES
MINES (m)6A (I)dentification Using (N)anopor(E) (S)equencing Tombo(v1.4) 命令在 MINES 之前执行: (仅在 fast5 文件中尚未包含 fastq 时需要) tombo preprocess annotate_raw_with_fastqs --fast5-basedir /fast5_dir/ --fastq-file…...
H.265流媒体播放器EasyPlayer.js H5流媒体播放器关于如何查看手机端的日志信息并保存下来
现今流媒体播放器的发展趋势将更加多元化和个性化。人工智能的应用将深入内容创作、用户体验优化等多个方面,带来前所未有的个性化体验。 EasyPlayer.js H.265流媒体播放器属于一款高效、精炼、稳定且免费的流媒体播放器,可支持多种流媒体协议播放&#…...
查询网站日流量/产品推广方案模板
1.选择器 2.样式属性 3.布局 4.浏览器原理 以妓会友,评赞走起 转载于:https://www.cnblogs.com/lgyong/p/8617044.html...
永康建设网站/今天的新闻是什么
前言最近公司外包给别人做的一个APP项目上线了,拿到源码一看那代码质量真是一言难尽啊!刚上线用户比较少倒也没出啥问题,不过随着用户慢慢变多,问题逐渐暴露出来了。最严重的问题就是我们的APP与服务器的通信接口没有加密处理被人…...
建设银行网站适用浏览器/厦门seo全网营销
Java中的set是一个不包含重复元素的集合,确切地说,是不包含e1.equals(e2)的元素对。Set中允许添加null。Set不能保证集合里元素的顺序。 在往set中添加元素时,如果指定元素不存在,则添加成功。也就是说,如果set中不存在…...
住房城乡建设委 房管局 官方网站/微信crm
http://store.raspberrypi.com/projects?page3&categorygames...
太原做网站 小程序/seo实战密码电子版
2019独角兽企业重金招聘Python工程师标准>>> 可以打包各种格式 http://www.freefontconverter.com/ 转载于:https://my.oschina.net/linsk1998/blog/2874297...
上海网站建设网页设计/舆情系统
有木有小伙伴经常纳闷,为什么明明大家拿到的都是同样的数据,但是别人做出来的图表就是特别好看呢?有时候绞尽脑汁花了好长时间做出来的图表还不如别人花三分钟做出来的图表,太挫败了有木有!别急!小编今天就…...