一、Elasticsearch基础

什么是Elasticsearch?

Elasticsearch 是基于 Lucene 的 Restful 的分布式实时全文搜索引擎,每个字段都被索引并可被搜索,可以快速存储、搜索、分析海量的数据。
全文检索是指对每一个词建立一个索引,指明该词在文章中出现的次数和位置。当查询时,根据事先建立的索引进行查找,并将查找的结果反馈给用户的检索方式。这个过程类似于通过字典中的检索字表查字的过程。

Es相关名词解释?

映射(Mapping):类比于MySQL中schema和数据库的设计(比如字段类型,长度…),ES中通过mapping定义哪些字段是否可以分词操作,哪些字段是否可以被查询等。
分片(Shards):类比于MySQL的水平分表,作用是容量扩容,提高吞吐量。
副本(Replicas):分片数据的副本,保障数据安全。
分配(allocation):将分片分给某个节点的过程(包括主分片和副本),有master节点完成。

Elasticsearch 中的集群、节点、索引、文档、类型是什么?

集群是一个或多个节点(服务器)的集合,它们共同保存您的整个数据,并提供跨所有节点的联合索引和搜索功能。群集由唯一名 称标识,默认情况下为"elasticsearch"。此名称很重要,因为如果节点设置为按名称加入群集,则该节点只能是群集的一部分。
节点是属于集群一部分的单个服务器。它存储数据并参与群集索引和搜索功能。
索引就像关系数据库中的“数据库”。它有一个定义多种类型的映射。索引是逻辑名称空间,映射到一个或多个主分片,并且可以有零个或多个副本分片。MySQL =>数据库,Elasticsearch=>索引。
文档类似于关系数据库中的一行。不同之处在于索引中的每个文档可以具有不同的结构(字段),但是对于通用字段应该具有相同的数据类型。MySQL => Databases => Tables => Columns / Rows,Elasticsearch=> Indices => Types =>具有属性的文档Doc。
类型是索引的逻辑类别/分区,其语义完全取决于用户。

倒排索引是什么?

倒排索引是搜索引擎的核心。搜索引擎的主要目标是在查找发生搜索条件的文档时提供快速搜索。ES中的倒排索引其实就是 lucene 的倒排索引,区别于传统的正向索引, 倒排索引会再存储数据时将关键词和数据进行关联,保存到倒排表中,然后查询时,将查询内容进行分词后在倒排表中进行查询,最后匹配数据即可。
在搜索引擎中,每个文档都有一个对应的文档 ID,文档内容被表示为一系列关键词的集合。例如,文档 1 经过分词,提取了 20 个关键词,每个关键词都会记录它在文档中出现的次数和出现位置。
那么,倒排索引就是关键词到文档 ID 的映射,每个关键词都对应着一系列的文件,这些文件中都出现了关键词。举例说明:
有以下文档:

对文档进行分词之后,得到以下倒排索引:

另外,实用的倒排索引还可以记录更多的信息,比如文档频率信息,表示在文档集合中有多少个文档包含某个单词。
那么,有了倒排索引,搜索引擎可以很方便地响应用户的查询。比如用户输入查询 Facebook,搜索系统查找倒排索引,从中读出包含这个单词的文档,这些文档就是提供给用户的搜索结果。
要注意倒排索引的两个重要细节:

  • 倒排索引中的所有词项对应一个或多个文档
  • 倒排索引中的词项根据字典顺序升序排列

上面只是一个简单的例子,并没有严格按照字典顺序升序排列。

底层的 lucene 是什么?

lucene 就是一个 jar 包,里面包含了封装好的各种建立倒排索引的算法代码。我们用 Java 开发的时候,引入 lucene jar,然后基于 lucene 的 api 去开发就可以了。
通过 lucene,我们可以将已有的数据建立索引,lucene 会在本地磁盘上面,给我们组织索引的数据结构。

是否了解字典树?

字典树又称单词查找树, Trie 树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高。
Trie 的核心思想是空间换时间,利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的。它有 3 个基本性质:

  1. 根节点不包含字符,除根节点外每一个节点都只包含一个字符。
  2. 从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串。
  3. 每个节点的所有子节点包含的字符都不相同。

对于中文的字典树,每个节点的子节点用一个哈希表存储,这样就不用浪费太大的空间,而且查询速度上可以保留哈希的复杂度 O(1)。

为什么要使用 Elasticsearch?

系统中的数据, 随着业务的发展,时间的推移, 将会非常多, 而业务中往往采用模糊查询进行数据的搜索, 而模糊查询会导致查询引擎放弃索引,导致系统查询数据时都是全表扫描,在百万级别的数据库中,查询效率是非常低下的,而我们使用 ES 做一个全文索引,将经常查询的系统功能的某些字段,比如说电商系统的商品表中商品名,描述、价格还有 id 这些字段我们放入 ES 索引库里,可以提高查询速度。

二、Elasticsearch工作原理

Elasticsearch 写入数据的工作流程是什么?

  1. 客户端选择一个 node 发送请求过去,这个 node 就是 coordinating node(协调节点)。
  2. coordinating node 对 document 进行路由,将请求转发给对应的 node(有 primary shard)。[路由的算法是哈希然后取模]
  3. 实际的 node 上的 primary shard 处理请求,然后将数据同步到 replica node。
  4. coordinating node 如果发现 primary node 和所有 replica node 都搞定之后,就返回响应结果给客户端。

Elasticsearch 主分片写数据的详细流程?


(1)主分片先将数据写入ES的 memory buffer,然后定时(默认1s)将 memory buffer 中的数据写入一个新的 segment 文件中,并进入操作系统缓存 Filesystem cache(同时清空 memory buffer),这个过程就叫做 refresh;每个 segment 文件实际上是一些倒排索引的集合, 只有经历了 refresh 操作之后,这些数据才能变成可检索的。

ES 的近实时性:数据存在 memory buffer 时是搜索不到的,只有数据被 refresh 到 Filesystem cache 之后才能被搜索到,而 refresh 是每秒一次, 所以称 es 是近实时的;可以手动调用 es 的 api 触发一次 refresh 操作,让数据马上可以被搜索到;

(2)由于 memory Buffer 和 Filesystem Cache 都是基于内存,假设服务器宕机,那么数据就会丢失,所以 ES 通过 translog 日志文件来保证数据的可靠性,在数据写入 memory buffer 的同时,将数据也写入 translog 日志文件中,当机器宕机重启时,es 会自动读取 translog 日志文件中的数据,恢复到 memory buffer 和 Filesystem cache 中去。

ES 数据丢失的问题:translog 也是先写入 Filesystem cache,然后默认每隔 5 秒刷一次到磁盘中,所以默认情况下,可能有 5 秒的数据会仅仅停留在 memory buffer 或者 translog 文件的 Filesystem cache中,而不在磁盘上,如果此时机器宕机,会丢失 5 秒钟的数据。也可以将 translog 设置成每次写操作必须是直接 fsync 到磁盘,但是性能会差很多。

(3)flush 操作:不断重复上面的步骤,translog 会变得越来越大,不过 translog 文件默认每30分钟或者 阈值超过 512M 时,就会触发 commit 操作,即 flush操作,将 memory buffer 中所有的数据写入新的 segment 文件中, 并将内存中所有的 segment 文件全部落盘,最后清空 translog 事务日志。

① 将 memory buffer 中的数据 refresh 到 Filesystem Cache 中去,清空 buffer;

② 创建一个新的 commit point(提交点),同时强行将 Filesystem Cache 中目前所有的数据都 fsync 到磁盘文件中;

③ 删除旧的 translog 日志文件并创建一个新的 translog 日志文件,此时 commit 操作完成

Elasticsearch 更新和删除文档的流程?

删除和更新都是写操作,但是由于 Elasticsearch 中的文档是不可变的,因此不能被删除或者改动以展示其变更;所以 ES 利用 .del 文件 标记文档是否被删除,磁盘上的每个段都有一个相应的.del 文件
(1)如果是删除操作,文档其实并没有真的被删除,而是在 .del 文件中被标记为 deleted 状态。该文档依然能匹配查询,但是会在结果中被过滤掉。
(2)如果是更新操作,就是将旧的 doc 标识为 deleted 状态,然后创建一个新的 doc。
memory buffer 每 refresh 一次,就会产生一个 segment 文件 ,所以默认情况下是 1s 生成一个 segment 文件,这样下来 segment 文件会越来越多,此时会定期执行 merge。每次 merge 的时候,会将多个 segment 文件合并成一个,同时这里会将标识为 deleted 的 doc 给物理删除掉,不写入到新的 segment 中,然后将新的 segment 文件写入磁盘,这里会写一个 commit point ,标识所有新的 segment 文件,然后打开 segment 文件供搜索使用,同时删除旧的 segment 文件。

query 和 filter 的区别?

(1)query:查询操作不仅仅会进行查询,还会计算分值,用于确定相关度;
(2)filter:查询操作仅判断是否满足查询条件,不会计算任何分值,也不会关心返回的排序问题,同时,filter 查询的结果可以被缓存,提高性能。

Elasticsearch 查询数据的流程?

搜索被执行成一个两阶段过程,即 Query Then Fetch:
1、Query阶段:
客户端发送请求到 coordinate node,协调节点将搜索请求广播到所有的 primary shard 或 replica,每个分片在本地执行搜索并构建一个匹配文档的大小为 from + size 的优先队列。接着每个分片返回各自优先队列中 所有 docId 和 打分值 给协调节点,由协调节点进行数据的合并、排序、分页等操作,产出最终结果。
2、Fetch阶段:
协调节点根据 Query阶段产生的结果,去各个节点上查询 docId 实际的 document 内容,最后由协调节点返回结果给客户端。

  • coordinate node 对 doc id 进行哈希路由,将请求转发到对应的 node,此时会使用 round-robin 随机轮询算法,在 primary shard 以及其所有 replica 中随机选择一个,让读请求负载均衡。
  • 接收请求的 node 返回 document 给 coordinate node 。
  • coordinate node 返回 document 给客户端。
    Query Then Fetch 的搜索类型在文档相关性打分的时候参考的是本分片的数据,这样在文档数量较少的时候可能不够准确,DFS Query Then Fetch 增加了一个预查询的处理,询问 Term 和 Document frequency,这个评分更准确,但是性能会变差。

Elasticsearch 索引文档的流程?

  1. 协调节点默认使用文档 ID 参与计算(也支持通过 routing),以便为路由提供合适的分片:shard = hash(document_id) % (num_of_primary_shards)
  2. 当分片所在的节点接收到来自协调节点的请求后,会将请求写入到 Memory Buffer,然后定时(默认是每隔 1 秒)写入到 Filesystem Cache,这个从 Memory Buffer 到 Filesystem Cache 的过程就叫做 refresh;
  3. 当然在某些情况下,存在 Momery Buffer 和 Filesystem Cache 的数据可能会丢失, ES 是通过 translog的机制来保证数据的可靠性的。其实现机制是接收到请求后,同时也会写入到 translog 中,当 Filesystemcache 中的数据写入到磁盘中时,才会清除掉,这个过程叫做 flush;
  4. 在 flush 过程中,内存中的缓冲将被清除,内容被写入一个新段,段的 fsync 将创建一个新的提交点,并将内容刷新到磁盘,旧的 translog 将被删除并开始一个新的 translog。
  5. flush 触发的时机是定时触发(默认 30 分钟)或者 translog 变得太大(默认为 512M)时;

Elasticsearch 的分布式原理?

    Elasticsearch 会对存储的数据进行切分,划分到不同的分片上,同时每一个分片会生成多个副本,从而保证分布式环境的高可用。ES集群中的节点是对等的,节点间会选出集群的 Master,由 Master 会负责维护集群状态信息,并同步给其他节点。

Elasticsearch 的性能会不会很低:不会,ES只有建立 index 和 type 时需要经过 Master,而数据的写入有一个简单的 Routing 规则,可以路由到集群中的任意节点,所以数据写入压力是分散在整个集群的。

Elasticsearch 的 master 选举流程?

Elasticsearch的选主是ZenDiscovery模块负责的,主要包含Ping(节点之间通过这个RPC来发现彼此)
和Unicast(单播模块包含-一个主机列表以控制哪些节点需要ping通)这两部分。
第一步:对所有可以成为master的节点(node master: true)根据nodeId字典排序,每次选举每个节点都把自
己所知道节点排一次序,然后选出第一个(第0位)节点,暂且认为它是master节点。
第二步:如果对某个节点的投票数达到一定的值(可以成为master节点数n/2+1)并且该节点自己也选举自己,
那这个节点就是master。否则重新选举一直到满足上述条件。
master节点的职责主要包括集群、节点和索引的管理,不负责文档级别的管理;data节点可以关闭http
功能。

Elasticsearch 集群脑裂问题?

脑裂问题可能的成因:

  1. 网络问题:集群间的网络延迟导致一些节点访问不到master, 认为master 挂掉了从而选举出新的master,并对master上的分片和副本标红,分配新的主分片。
  2. 节点负载:主节点的角色既为master又为data,访问量较大时可能会导致ES停止响应造成大面积延迟,此时其他节点得不到主节点的响应认为主节点挂掉了,会重新选取主节点。
  3. 内存回收:data 节点上的ES进程占用的内存较大,引发JVM的大规模内存回收,造成ES进程失去响应。

脑裂问题解决方案:

  1. 减少误判:discovery.zen ping_ timeout 节点状态的响应时间,默认为3s,可以适当调大,如果master在该响应时间的范围内没有做出响应应答,判断该节点已经挂掉了。调大参数(如6s,discovery.zen.ping_timeout:6),可适当减少误判。
  2. 选举触发:discovery.zen.minimum. master nodes:1,该参數是用于控制选举行为发生的最小集群主节点数量。当备选主节点的个數大于等于该参数的值,且备选主节点中有该参数个节点认为主节点挂了,进行选举。官方建议为(n / 2) +1, n为主节点个数(即有资格成为主节点的节点个数)。
  3. 角色分离:即master节点与data节点分离,限制角色

主节点配置为:node master: true,node data: false
从节点配置为:node master: false,node data: true

Elasticsearch 对于大数据量(上亿量级)的聚合如何实现?

Elasticsearch 提供的首个近似聚合是 cardinality 度量。它提供一个字段的基数,即该字段的 distinct或者 unique 值的数目。它是基于 HLL 算法的。 HLL 会先对我们的输入作哈希运算,然后根据哈希运算的结果中的 bits 做概率估算从而得到基数。其特点是:可配置的精度,用来控制内存的使用(更精确 = 更多内存);小的数据集精度是非常高的;我们可以通过配置参数,来设置去重需要的固定内存使用量。无论数千还是数十亿的唯一值,内存使用量只与你配置的精确度相关。

Elasticsearch 如果保证读写一致?

(1)对于更新操作:可以通过版本号使用乐观并发控制,以确保新版本不会被旧版本覆盖

每个文档都有一个_version 版本号,这个版本号在文档被改变时加一。Elasticsearch使用这个 _version 保证所有修改都被正确排序,当一个旧版本出现在新版本之后,它会被简单的忽略。利用_version的这一优点确保数据不会因为修改冲突而丢失,比如指定文档的version来做更改,如果那个版本号不是现在的,我们的请求就失败了。

(2)对于写操作,一致性级别支持 quorum/one/all,默认为 quorum,即只有当大多数分片可用时才允许写操作。但即使大多数可用,也可能存在因为网络等原因导致写入副本失败,这样该副本被认为故障,副本将会在一个不同的节点上重建。

  • one:写操作只要有一个primary shard是active活跃可用的,就可以执行
  • all:写操作必须所有的primary shard和replica shard都是活跃可用的,才可以执行
  • quorum:默认值,要求ES中大部分的shard是活跃可用的,才可以执行写操作

(3)对于读操作,可以设置 replication 为 sync(默认),这使得操作在主分片和副本分片都完成后才会返回;如果设置replication 为 async 时,也可以通过设置搜索请求参数 _preference 为 primary 来查询主分片,确保文档是最新版本。

三、Elasticsearch性能优化

如何监控 Elasticsearch 集群状态?

elasticsearch-head 插件。
通过 Kibana 监控 Elasticsearch。你可以实时查看你的集群健康状态和性能,也可以分析过去的集群、索引和节点指标

Elasticsearch 在部署时,对 Linux 的设置有哪些优化方法?

  1. 64 GB 内存的机器是非常理想的, 但是 32 GB 和 16 GB 机器也是很常见的。少于 8 GB 会适得其反。
  2. 如果你要在更快的 CPUs 和更多的核心之间选择,选择更多的核心更好。多个内核提供的额外并发远胜过稍微快一点点的时钟频率。
  3. 如果你负担得起 SSD,它将远远超出任何旋转介质。 基于 SSD 的节点,查询和索引性能都有提升。如果你负担得起, SSD 是一个好的选择。
  4. 即使数据中心们近在咫尺,也要避免集群跨越多个数据中心。绝对要避免集群跨越大的地理距离。
  5. 请确保运行你应用程序的 JVM 和服务器的 JVM 是完全一样的。 在 Elasticsearch 的几个地方,使用 Java 的本地序列化。
  6. 通过设置 gateway.recover_after_nodes、 gateway.expected_nodes、 gateway.recover_after_time 可以在集群重启的时候避免过多的分片交换,这可能会让数据恢复从数个小时缩短为几秒钟。
  7. Elasticsearch 默认被配置为使用单播发现,以防止节点无意中加入集群。只有在同一台机器上运行的节点才会自动组成集群。最好使用单播代替组播。
  8. 不要随意修改垃圾回收器(CMS)和各个线程池的大小。
  9. 把你的内存的(少于)一半给 Lucene(但不要超过 32 GB!),通过 ES_HEAP_SIZE 环境变量设置。
  10. 内存交换到磁盘对服务器性能来说是致命的。如果内存交换到磁盘上,一个 100 微秒的操作可能变成 10 毫秒。 再想想那么多 10 微秒的操作时延累加起来。 不难看出 swapping 对于性能是多么可怕。
  11. Lucene 使用了大量的文件。同时, Elasticsearch 在节点和 HTTP 客户端之间进行通信也使用了大量的套接字。 所有这一切都需要足够的文件描述符。你应该增加你的文件描述符,设置一个很大的值,如 64,000。

GC 方面,在使用 Elasticsearch 时要注意什么?

  1. 倒排词典的索引需要常驻内存,无法 GC,需要监控 data node 上 segment memory 增长趋势。
  2. 各类缓存, field cache, filter cache, indexing cache, bulk queue 等等,要设置合理的大小,并且要应该根据最坏的情况来看 heap 是否够用,也就是各类缓存全部占满的时候,还有 heap 空间可以分配给其他任务吗?避免采用 clear cache 等“自欺欺人”的方式来释放内存。
  3. 避免返回大量结果集的搜索与聚合。确实需要大量拉取数据的场景,可以采用 scan & scroll api 来实现。
  4. cluster stats 驻留内存并无法水平扩展,超大规模集群可以考虑分拆成多个集群通过 tribe node 连接。
  5. 想知道 heap 够不够,必须结合实际应用场景,并对集群的 heap 使用情况做持续的监控。

doc_values 的作用是什么?

倒排索引虽然可以提高搜索性能,但也存在缺陷,比如我们需要对数据做排序或聚合等操作时,lucene 会提取所有出现在文档集合的排序字段,然后构建一个排好序的文档集合,而这个步骤是基于内存的,如果排序数据量巨大的话,容易造成内存溢出和性能缓慢。
doc_values 就是 es 在构建倒排索引的同时,会对开启 doc_values 的字段构建一个有序的 “document文档 ==> field value” 的列式存储映射,可以看作是以文档维度,实现了根据指定字段进行排序和聚合的功能,降低对内存的依赖。另外 doc_values 保存在操作系统的磁盘中,当 doc_values 大于节点的可用内存,ES可以从操作系统页缓存中加载或弹出,从而避免发生内存溢出的异常,但如果 docValues 远小于节点的可用内存,操作系统就自然将所有 doc_values 存于内存中(堆外内存),有助于快速访问。

建立索引阶段性能提升方法?

(1)如果是大批量导入,可以设置 index.number_of_replicas: 0 关闭副本,等数据导入完成之后再开启副本
(2)使用批量请求并调整其大小:每次批量数据 5–15 MB 大是个不错的起始点。
(3)如果搜索结果不需要近实时性,可以把每个索引的 index.refresh_interval 改到30s
(4)增加 index.translog.flush_threshold_size 设置,从默认的 512 MB 到更大一些的值,比如 1 GB
(5)使用 SSD 存储介质
(6)段和合并:Elasticsearch 默认值是 20 MB/s。但如果用的是 SSD,可以考虑提高到 100–200 MB/s。如果你在做批量导入,完全不在意搜索,你可以彻底关掉合并限流。

ES的深度分页与滚动搜索scroll

(1)深度分页:
深度分页其实就是搜索的深浅度,比如第1页,第2页,第10页,第20页,是比较浅的;第10000页,第20000页就是很深了。搜索得太深,就会造成性能问题,会耗费内存和占用cpu。而且es为了性能,他不支持超过一万条数据以上的分页查询。那么如何解决深度分页带来的问题,我们应该避免深度分页操作(限制分页页数),比如最多只能提供100页的展示,从第101页开始就没了,毕竟用户也不会搜的那么深。

(2)滚动搜索:
一次性查询1万+数据,往往会造成性能影响,因为数据量太多了。这个时候可以使用滚动搜索,也就是 scroll。 滚动搜索可以先查询出一些数据,然后再紧接着依次往下查询。在第一次查询的时候会有一个滚动id,相当于一个锚标记 ,随后再次滚动搜索会需要上一次搜索滚动id,根据这个进行下一次的搜索请求。每次搜索都是基于一个历史的数据快照,查询数据的期间,如果有数据变更,那么和搜索是没有关系的。

Elasticsearch面试问题汇总相关推荐

  1. Java 面试问题汇总

    面试问题汇总 2019.4月份 ​​ ​​ Java问题汇总 jvm加载类的机制 tomcat /bin/ cat catalina.sh 设置jvm参数 Jvm是通过classLoader来加载ja ...

  2. BaiDu往年面试题目汇总☆WM☆

    BaiDu往年面试题目汇总☆WM☆祝自己明天能取得一个好的面试成绩 题目来源:http://www.cnblogs.com/cutepig/archive/2007/09/14/893552.html ...

  3. Java面试总结汇总

    Java面试总结汇总,整理了包括Java基础知识,集合容器,并发编程,JVM,常用开源框架Spring,MyBatis,数据库,中间件等,包含了作为一个Java工程师在面试中需要用到或者可能用到的绝大 ...

  4. tcp当主动发出syn_一文读懂TCP四次挥手工作原理及面试常见问题汇总

    简述 本文主要介绍TCP四次挥手的工作原理,以及在面试中常见的问题. 字段含义 seq序号:Sequence Number,占32位,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行 ...

  5. npm install 报错 汇总_2020年特岗教师招聘征集志愿人员资格复审、面试公告汇总...

    原标题:2020年特岗教师招聘征集志愿人员资格复审.面试公告汇总 昨天晚上 安徽省2020年特岗教师招聘空缺计划征集志愿拟参加面试人员名单已经公布啦,接下来陆续就是资格复审和面试啦 小可爱们一点要关注 ...

  6. 复旦计算机考研复试要口试吗,2017复旦大学考研复试:英语口语面试常见问题汇总...

    2017复旦大学考研复试:英语口语面试常见问题汇总本站小编 辅仁网/2017-12-29 A magazine publisher is trying to decide how many magaz ...

  7. ElasticSearch面试 - es 生产集群的部署架构是什么?

    ElasticSearch面试 - es 生产集群的部署架构是什么? 面试题 es 生产集群的部署架构是什么?每个索引的数据量大概有多少?每个索引大概有多少个分片? 面试官心理分析 这个问题,包括后面 ...

  8. ElasticSearch面试 - es 写入数据的工作原理是什么啊?

    ElasticSearch面试 - es 写入数据的工作原理是什么啊? 面试题 es 写入数据的工作原理是什么啊?es 查询数据的工作原理是什么啊?底层的 lucene 介绍一下呗?倒排索引了解吗? ...

  9. docker及k8s容器面试精华汇总(一),祝大家顺利通过企业面试!

    docker及k8s容器面试精华汇总,希望可以加深大家对容器的理解,祝大家顺利通过企业面试. 一.如何在 Kubernetes 中实现负载均衡? node中有kube-proxy,他可以提供负载均衡. ...

最新文章

  1. 对于继电器线圈奇怪的H-B曲线的实验测量
  2. 求连通块个数(使用并查集)
  3. 产品认知:说说产品经理的底层思维——用户思维
  4. oracle对象权限 函数,oracle的系统和对象权限
  5. portal认证 只能重定向80和443请求_华为防火墙内置Portal认证报文交互
  6. 庆祝kkkbo出道!
  7. web打印POS小票机代码
  8. SpringBoot_MD5加密工具类
  9. python 角度变弧度_弧度制和角度值怎么转换?
  10. [Bullet3]常见物体和初始化
  11. 悲催:一个80后程序员的爱情故事【视频】-但愿我不是那个陈旭阳!55...
  12. Nginx Rewrite的讲解(从新手村到小有成就7)
  13. nn.Sequential()
  14. SmtpJS发送邮件教程
  15. 当我们与某远程网络连接不上时,就需要跟踪路由查看,以便 了解在网络的什么位置出现了问题,满足该目的的命令是
  16. 触控板失灵的解决方法(synaptics驱动)
  17. 适合编程初学者的 入门级硬件: micro:bit
  18. 数字化采购管理系统开发:精细化采购业务流程管理,赋能企业实现“阳光采购”
  19. 信道容量 Channel capacity
  20. REACT_react生命周期

热门文章

  1. 手机屏幕投影到投影仪_投影机与大屏幕电视:您应该购买哪一个?
  2. 【C语言】之实现质数的判断
  3. 六顶思考帽帮你职场突围
  4. 利用scrap实现发送邮件,一个小实例
  5. osg fbo(一),生成颜色缓冲区图片
  6. 【LR(0)分析】LR(0)算法的分析与设计
  7. C语言 链表输入输出数组
  8. python flask高并发_标志处理高并发性,Flask
  9. 城市“一网统管”平台—智慧平安小区的场景应用
  10. uniapp vue 实现模仿微信支付密码弹窗