当前位置: 首页 > news >正文

极兔一面:10亿级ES海量搜索狂飙10倍,该怎么办?

背景说明:

ES高性能全文索引,如果不会用,或者没有用过,在面试中,会非常吃亏。

所以ES的实操和底层原理,大家要好好准备。

另外,ES调优是一个非常、非常核心的面试知识点,大家要非常重视。

在40岁老架构师 尼恩的读者交流群(50+)中,其ES相关面试题是一个非常、非常高频的交流话题。

近段时间,有小伙伴面试极兔,说遇到一个ES 海量数据 调优的面试题:

ES在承载海量数据,在查询时会存在什么问题?如何优化?

社群中,还遇到过大概的变种:

形式1:10亿级 ES 索引单次查询在5-10s,要调优10倍?怎么办?

形式2:ES 海量索引单次查询速度太慢?如何调优?

形式3:ES 在数据量很大的情况下(数十亿级别)如何提高查询效率?

形式4:后面的变种,应该有很多变种…,具体可以在尼恩社群交流。

这里,对这个面试题系列,尼恩给大家 做一下系统化、体系化的梳理,使得大家可以充分展示一下大家雄厚的 “技术肌肉”,

让面试官爱到 “不能自已、口水直流”

同时,也一并把这个 题目以及参考答案,收入咱们的《尼恩Java面试宝典》 V48版,供后面的小伙伴参考,提升大家的 3高 架构、设计、开发水平,实现技术自由。

注:本文以 PDF 持续更新,最新尼恩 架构笔记、面试题 的PDF文件,请从这里获取:码云

首先说一下自己对ES性能的认识

首先可以说明一下自己的使用经验:ES 性能并没有想象中那么好的。

下面是一个权威数据,腾讯云的ES集群性能数据:3个节点性能测试,吞吐量中位数 50qps。

ES集群吞吐量的测试数据

参见:Elasticsearch Service 8核32G 3节点集群性能测试 - 产品简介 - 文档中心 - 腾讯云 (tencent.com)

所以,很多时候ES数据量大了,特别是有几亿条数据的时候,实际上性能很差。

在这事上,尼恩就有切实体会。

在2017、2018年左右,尼恩维护一个30个节点的集群架构,亿级文档。 数据规模大概1亿doc, 1TB的容量。

在那个集群上,有的慢搜索,最长rt在5-10s。

你可能会蒙? 怎么那么久, 5~10s?

记得当时候,17年的时候,尼恩为30个节点的es集群做优化,吞吐量 从 5qps 优化到 100qps, 竟然,耗费了1个月

当然,最终,尼恩借用秒杀理论搞定 并发场景的 性能问题,实现了 在 瞬间高并发 流量(1W用户同时访问)的情况下,用户的rt在2秒以内

特别说明,尼恩的秒杀不是一般的秒杀,至少抽取了3个大型项目的工业实操,具体请参考尼恩的秒杀架构。

总之,ES 性能优化,是一个很大的难题。

在解决的时候,不要期待着随手调一个参数、两个参数,就可以万能的应对所有的性能慢的场景。

解决这个问题,要系统化、体系化、全面化思考。

那么:要做到数十亿数据查询,毫秒级响应,有哪些措施呢?

措施一:调大内存,缓存越大越好

调大内存,缓存越大越好,主要指的是Filesystem Cache越大越好。

ES的内存在构成上比较复杂,具体请参考 尼恩3高笔记中的:Data Node 内存溢出的快速恢复方案

为啥要调大Filesystem Cache呢?

ES查询的时候,会有大量的mmap操作,在mmap操作的时候,OS会将磁盘文件里的segment数据,加载到 Filesystem Cache 缓存里面去。

完整Filesystem Cache 的内容,请参见尼恩的葵花宝典,对这部分难点内容的介绍,非常系统和全面。

总之,ES严重依赖于底层的 filesystem cache,你如果给 filesystem cache 更多的内存,尽量让内存可以容纳所有的 idx segment file 索引数据文件,

那么在搜索的时候,就基本都是走内存的,性能会非常高。

具体来说:性能差距究竟可以有多大?

我们之前很多的测试和压测,如果通过磁盘IO完成搜索,一般秒级返回,可能是,1秒、5秒、10秒。

但如果是走 filesystem cache,那么一般来说性能比走磁盘IO要快一个数量级,基本上就是10ms、50ms、100ms、几百毫秒不等。

这里,还可以给面试官说点真实的数据。

假设一套 es 节点有 3 台机器,每台机器,64G内存,总内存就是 64 * 3 = 192G。

每台机器给 es jvm heap 是 32G,留给 filesystem cache 是 32G,

总共集群里给 filesystem cache 的就是 32 * 3 = 96G 内存。

而此时,整个磁盘上索引数据文件,假设在 3 台机器上一共占用了 1T 的磁盘容量,es 数据量是 1T,那么每台机器的数据量是 300G。

此时:

  • filesystem cache 的内存才 100G,
  • es 数据量是 1T

十分之一的数据可以放内存,十分之9的数据,在查询命中的时候,需要进行临时的磁盘加载。

结论是:十分之9的搜索操作,性能在 秒级。

提升性能的策略是,提升内存命中的比例,两个思路:

  1. 拼命调大内存。
  2. 减少索引index 索引大小。

所以:亿级索引、海量索引的调优措施之一,简单来讲,希望全部命中在内存,而不是在磁盘。

或者说:如果 缓存不了全部数据,那就至少可以容纳你的总数据量的一半。

比如:索引数据控制在 100G,如果内存留给 filesystem cache 的是 100G,这样的话,数据几乎全部走内存来搜索,性能非常之高,一般可以在 1 秒以内。

问题是,增大内存是高成本的措施,很多公司,不一定舍得这份投入。

怎么办?

措施二:缩容,缩小index 索引

如果第一点做不到,怎么办呢?

没有必要在一个点死耗,条条道路同罗马,东方不亮西方亮。

增大内存搞不定的话,可以逆向思考。就是:减少索引index 索引大小。

目标就一个:还是把索引加载到内存,或者至少能加载一半。

比如有一行数据,id,name,age … 30 个字段。而搜索的时候,只需要根据 name,age 2个字段来搜索。

这样搜索的时候,其余的28个字段是和搜索无关的,占了90%以上。结果这部分搜索无关数据,硬是占据了 es 机器上的 filesystem cache 的空间,单条数据的数据量越大,就会导致 filesystem cahce 能缓存的数据就越少。

所以,优化的策略就是,减少索引index 数据量。

仅仅写入 es 中要用来检索的少数几个字段就可以了,比如说就写入id,name,age 三个字段。

那么问题来了:在哪里存放全量数据呢?

一般是建议用 es + hbase 架构。es中保存hbase的key, 根据key 去habse取全量数据。

hbase 的特点是适用于海量数据的在线存储,就是对 hbase 可以写入海量数据,但是不要做复杂的搜索。

当然,在hbase中做很简单的一些根据 rowkey或者范围进行查询的这么一个操作就可以了。

用 es + hbase 架构,从 es 中根据 name 和 age 去搜索,拿到的结果可能就 20 个 rowkey,然后根据rowkey(doc id)到 hbase 里去查询每个 doc id 对应的完整的数据,给查出来,再返回给前端。

关于完整 es + hbase 架构, 非常重要,也非常精彩,是一个大大的简历亮点, 关于这个实操,尼恩后面会进行详细介绍,具体请关注群消息。

优化的结果:

然后你从 es 检索可能就花费 100ms,然后再根据 es 返回的 id 去 hbase 里查询,查 20 条数据,可能也就耗费个 100ms,

  • 架构整改之前,1T 数据都放 es,会每次查询都是 5~10s
  • 架构整改之后,现在可能性能就会很高,每次查询就是 200ms。

结论:性能提升50倍多。

措施三:冷热分离

如果索引的数据量,还是减不下来,怎么办。

比如说,无论怎么进行索引的瘦身,无论怎么进行索引的缩容,索引还是远大于内存。

比如,索引瘦身之后,还是有300G,而 filesystem cache 只有100G,索引大小,远远大于内存大小,怎么办?

条条道路同罗马,东方不亮西方,办法总比问题多。

方法之一:冷热分离

方式之2:数据预热

方式之3:…

怎么做冷热分离呢?

  • 冷数据:将大量的访问很少、频率很低的数据,单独写一个索引
  • 热数据:将大量的访问很大、频率很高的数据,单独写一个索引

目标还是一个:搜索的时候进行内存IO,而不是磁盘IO。

为啥磁盘IO慢,请参见尼恩的葵花宝典。

这样可以确保热数据在被加载到filesystem os cache 之后.

怎么能保证冷索引,不把热索引从内存寄出去呢?

这个主要是 Linux 内核的 LRU内存淘汰算法导致的,当系统内存不足时,Memcached 和 Redis 都是使用 LRU算法 来淘汰内存的。

尼恩提示,这里很容易出现连环炮面试题: 内存淘汰算法 相关的试题。

LRU(Least Recently Used) 中文翻译是 最近最少使用 的意思,其原理就是:当内存不足时,淘汰系统中最少使用的内存,这样对系统性能的损耗是最小的。用过 Memcached 或者 Redis 的同学应该都了解过 LRU算法。

有关内存淘汰算法,请看尼恩的 caffeine 底层源码和实操,

里边介绍了lru、lfu、window-tiny-lfu三大内存淘汰算法,非常细致。

足以秒晕面试官。

一般来说,由于热数据频繁访问,一般就会比较高的概率留在 filesystem os cache 里,不会让冷数据给冲刷掉。

假设有 6 台机器,2 个索引,一个放冷数据,一个放热数据,每个索引 3 个 shard。

大量的时间是在访问热数据 index,热数据可能就占总数据量的 10%,此时数据量很少,几乎全都驻留 filesystem cache 里面了,就可以通过内存IO完成,而不是磁盘IO,从而实现性能优化。

少量的冷数据访问,可能大量数据是在磁盘上的,此时性能差点,也无所谓了。

冷热分离之后,保障了90%的请求在1s以内。

措施四:数据预热

冷热分离之后,如何确保热数据,一直处于 filesystem cache 里?

有效的措施是:数据预热

怎么预热呢?

简单的说,就是提前访问一下,让数据进入 filesystem cache 里面去。

复杂点的措施,就是做一个专门的缓存预热子系统,就是对热数据每隔一段时间,访问一下,让数据进入 filesystem cache 里面去。

那么,那些是热点数据呢?怎识别热点数据呢?

比如电商秒杀,你可以将平时查看最多的一些商品,比如说 iphone 8,可以提前访问一次,刷到 filesystem cache 里去。搜索的时候,直接从内存里搜索了,没有走磁盘IO,速度很快。

有些热点数据是可以提前预知的,但是更多的热点数据,不实时产生的的,老天爷都不知道什么时候到了,怎么办?

这里涉及到 热点探测系统。

有了,缓存预热子系统可以和热点探测子系统结合,进行 动态的缓存预热。

热点探测子系统和缓存预热子系统怎么结合?具体请参考 尼恩的 《100W级qps 三级缓存架构与实操》架构笔记

提前预热之后,数据已经到了缓存,这样下次别人访问的时候,性能一定会好很多。

举个例子,拿微博来说,一些大V数据,或者一下其他的平时看的人很多的数据,就是使用 热点探测子系统和缓存预热子系统结合的路子,每隔一会儿, 探测到热点数据之后,预热子系统就去搜索一下热数据,刷到 filesystem cache 里去。

后面用户去搜索大V,实际他们就是直接从内存里搜索了,没有走磁盘IO,速度很快。

比如电商秒杀,对于一下未知的热点商品,通过热点探测之后,存预热子系统可以主动访问一次,刷到 filesystem cache 里去。

总之,热点探测子系统和缓存预热子系统的架构,非常重要, 具体请参考 尼恩的 《100W级qps 三级缓存架构与实操》 架构笔记

措施五:索引模型优化

在ES的优化中,索引模型优化、或者说索引结构优化,也很重要。

es 能支持的操作就那么多,很多操作性能低,不要在搜索的时候,执行各种复杂的乱七八糟的操作。

换句话说,对索引进行优化的时候,直接索引最终的结果数据,而不是过程数据、中间数据。

最好是先在 Java 系统里就完成数据的处理,比如说数据的关联,将关联好的数据直接写入 es 中。

搜索的时候,就不需要利用 es 的搜索语法来完成 join 之类的关联搜索了。

对于一些太复杂的操作,比如 join/nested/parent-child 搜索都要尽量避免,性能都很差的。

如果真的有那种操作,尽量在 document 模型设计的时候,写入的时候就完成。

另外对于一些太复杂的操作,比如 join/nested/parent-child 搜索都要尽量避免,性能都很差的。

关于索引结构的优化,有非常多的优化手段,根据自己的场景去定制化使用:

  • 字段拉平**:**将复合字段拆分为多个不同字段,查询时减少查询的字段个数。
  • 提前建立 mapping:预先建立 mapping,而不是让 ES 自动生成数据类型,加速检索**。**
  • 使用 keyword 代替 int/long/numeric

为啥使用 keyword 代替 int/long/numeric

对于keyword类型的term query,ES使用的是倒排索引。但是numeric类型为了能有效的支持范围查询,它的存储结构并不是倒排索引。

倒排索引在内存里维护了词典 (Term Dictionary)和文档列表(Postings List)的映射关系,倒排索引本身对于精确匹配查询是非常快的,直接从字典表找到term,然后就直接找到了posting list。

措施六:查询优化

查询优化的措施太多,随便说几点,面试官基本就满意了:

  • 分页性能优化
  • 能用term就不用match_phrase
  • 使用过滤器优化查询

然后告诉面试官,这些都要根据业务场景,具体分析。

查询优化1:分页性能优化

es 的分页是较坑的,为啥呢?

举个例子吧,假如每页是 100 条数据,现在要查询第 10页, 分页的时候,总共需要查到 1000条,再截取一个page,

如果有个 3 个 shard,实际上是会把每个 shard 上存储的前 1000 条数据,都查到一个协调节点上,

那么协调节点就有3000 条数据,接着协调节点对这 3000 条数据进行一些合并、处理,再获取到最终第 10 页的 10 条数据。

ES必须得从每个 shard 都查 1000 条数据过来,然后根据你的需求进行排序、筛选等等操作,最后再次分页,拿到里面第 10 页的数据。

翻页的时候,翻的越深,比如 1000,每个 shard 返回的数据就越多,而且协调节点处理的时间越长。

用 es 作分页,前几页就几十毫秒,翻到 10 页或者几十页的时候,基本上就要 5~10 秒才能查出来一页数据了。

那么怎么做分页性能优化?

简单的措施:就是限制翻页的数量,不让翻到很大的page。

为啥可以这么处理呢?实际上,搜索引擎返回的结果,都是模糊匹配的,越到后面,结果越模糊, 对用户的价值不大。

一般情况下,追求前几页,提供给用户价值大的结果。

很多搜索系统,不提供大页码的翻页。

面试官来一个连环炮?业务要求,一定要深度翻页,改怎么处理。

请参见 《尼恩Java面试宝典》的另一个面试题答案:《es 深度翻页的三大绝招》

查询优化2:能用term就不用match_phrase

The Lucene nightly benchmarks show that a simple term query is about 10 times as fast as a phrase query, and about 20 times as fast as a proximity query (a phrase query with slop).

官方说:

  • term查询比match_phrase性能要快10倍,
  • term查比带slop的match_phrase(proximity——match)快20倍。

能用term就不用match_phrase,举个简单例子

GET /my_index/my_type/_search
{"query": {"match_phrase": {"title": "quick fox"}}
}变为GET /my_index/my_type/_search
{"query": {"term": {"title": "quick fox"}}
}

match_phrase的执行流程如下?

match_phrase查询首先解析查询字符串,产生一个词条列表。

然后会搜索所有的词条,但只保留包含了所有搜索词条的文档,并且词条的位置要邻接。

比如,搜索 quick fox时,如果没有文档含有邻接在一起的quick和fox词条, 一个针对短语quick fox的查询不会匹配我们的任何文档。

proximity match: slop参数告诉match_phrase查询词条能够相隔多远时仍然将文档视为匹配。

我们以一个简单的例子来阐述这个概念。

为了让查询quick fox能够匹配含有quick brown fox的文档,我们需要slop的值为1.

match和match_phrase的区别

match:

只要简单的匹配到了一个term,就会将term对应的文档作为结果返回,扫描倒排索引,扫描到了就完事

match_phrase:

首先要扫描到所有term的文档列表,找到包含所有term的文档列表,然后对每个文档都计算每个term的position,是否符合指定的范围,需要进行复杂的运算,才能判断能否通过slop移动,匹配到这个文档。

match和match_phrase的性能比较

match 的性能比match_phrase和proximity match(有slop的match_phrase)要高得多。

因为后两者都需要计算position的距离

match query比natch_phrase的性能要高10倍,比proximity match(有slop的match phrase)要高20倍。

但是Elasticsearch性能是很强大的,基本都在毫秒级。

match可能是几毫秒,match phrase和proximity match也基本在几十毫秒和几百毫秒之前。

那么,如何对match和match_phrase的性能优化?

具体的措施是:先缩小范围,再打分。

具体来说,优化match_phrase和proximity match的性能,一般就是减少要进行proximity match搜索的文档的数量。

主要的思路就是用match query先过滤出需要的数据,然后在用proximity match来根据term距离提高文档的分数,同时proximity match只针对每个shard的分数排名前n个文档起作用,来重新调整它们的分数,这个过程称之为重打分rescoring。

主要是因为一般用户只会分页查询,只会看前几页的数据,所以不需要对所有的结果进行proximity match操作。也就是使用match + proximity match同时实现召回率和精准度。

默认情况下,match也许匹配了1000个文档,proximity match需要对每个doc进行一遍运算,判断能否slop移动匹配上,然后去贡献自己的分数。

但是很多情况下,match出来也许是1000个文档,其实用户大部分情况下都是分页查询的,可以就看前5页,每页就10条数据,也就50个文档。

所以,proximity match只要对前50个doc进行slop移动去匹配,去贡献自己的分数即可,不需要对全部1000个doc都去进行计算和贡献分数。

这个时候通过window_size这个参数即可实现限制重打分rescoring的文档数量。示例:

GET /test_index/_search
{"query": {"match": {"test_field": "java spark"}},"rescore": {"query": {"rescore_query": {"match_phrase": {"test_field": {"query": "java spark","slop": 10}}}},"window_size": 50}
}

查询优化3:使用过滤器优化查询

elasticsearch提供了一种特殊的缓存,即过滤器缓存(filter cache),用来储存过滤器的结果.

被缓存的过滤器不需要消耗过多的内存,因为他们只储存了哪些文档能与过滤器相匹配的相关信息,而且可供后续所有与之相关的查询重复使用,从而极大的提高了查询性能

执行下面这个查询

{"query":{"bool":{"must":[{"term":{"name":"joe"}    },{"term":{"year":1981}}]}}
}

该查询能查询出满足指定姓名和出生年代条件的足球运动员,只有同时满足两个条件的查询才可以被缓存起来。

优化这个查询

人名有太多可能性,它不是完美的缓存候选对象,而年代是,我们使用另一种查询方法,该查询组合了查询类型与过滤器:

{"query":{"filtered":{"query":{"term"{"name":"joe"}},"filter":{"term":{"year":1981}}}}
}

第一次执行该查询以后,过滤器会被es缓存起来,如果后续的其他查询也要使用该过滤器,则她会被重复使用,避免es重复加载相关数据

40岁老架构师尼恩提示

问题回答到这里,已经30分钟过去了,面试官已经爱到 “不能自已、口水直流” 啦。

注:本文以 PDF 持续更新,最新尼恩 架构笔记、面试题 的PDF文件,请从这里获取:码云

参考文献:

《尼恩的10Wqps秒杀架构笔记》

《尼恩的100Wqps三级缓存架构笔记》

《横扫全网ElasticSeach高可用实操架构笔记》

https://blog.csdn.net/whzhaochao/article/details/49126037

https://blog.csdn.net/wuzhangweiss/article/details/101156910

https://blog.csdn.net/Jerome_s/article/details/44992549

推荐阅读:

《响应式圣经:10W字,实现Spring响应式编程自由》

《全链路异步,让你的 SpringCloud 性能优化10倍+》

《Linux命令大全:2W多字,一次实现Linux自由》

《阿里一面:你做过哪些代码优化?来一个人人可以用的极品案例》

《网易二面:CPU狂飙900%,该怎么处理?》

《阿里二面:千万级、亿级数据,如何性能优化? 教科书级 答案来了》

《峰值21WQps、亿级DAU,小游戏《羊了个羊》是怎么架构的?》

《场景题:假设10W人突访,你的系统如何做到不 雪崩?》

《2个大厂 100亿级 超大流量 红包 架构方案》

《Nginx面试题(史上最全 + 持续更新)》

《K8S面试题(史上最全 + 持续更新)》

《操作系统面试题(史上最全、持续更新)》

《Docker面试题(史上最全 + 持续更新)》

《Springcloud gateway 底层原理、核心实战 (史上最全)》

《Flux、Mono、Reactor 实战(史上最全)》

《sentinel (史上最全)》

《Nacos (史上最全)》

《TCP协议详解 (史上最全)》

《分库分表 Sharding-JDBC 底层原理、核心实战(史上最全)》

《clickhouse 超底层原理 + 高可用实操 (史上最全)》

《nacos高可用(图解+秒懂+史上最全)》

《队列之王: Disruptor 原理、架构、源码 一文穿透》

《环形队列、 条带环形队列 Striped-RingBuffer (史上最全)》

《一文搞定:SpringBoot、SLF4j、Log4j、Logback、Netty之间混乱关系(史上最全)》

《单例模式(史上最全)》

《红黑树( 图解 + 秒懂 + 史上最全)》

《分布式事务 (秒懂)》

《缓存之王:Caffeine 源码、架构、原理(史上最全,10W字 超级长文)》

《缓存之王:Caffeine 的使用(史上最全)》

《Java Agent 探针、字节码增强 ByteBuddy(史上最全)》

《Docker原理(图解+秒懂+史上最全)》

《Redis分布式锁(图解 - 秒懂 - 史上最全)》

《Zookeeper 分布式锁 - 图解 - 秒懂》

《Zookeeper Curator 事件监听 - 10分钟看懂》

《Netty 粘包 拆包 | 史上最全解读》

《Netty 100万级高并发服务器配置》

《Springcloud 高并发 配置 (一文全懂)》

相关文章:

极兔一面:10亿级ES海量搜索狂飙10倍,该怎么办?

背景说明: ES高性能全文索引,如果不会用,或者没有用过,在面试中,会非常吃亏。 所以ES的实操和底层原理,大家要好好准备。 另外,ES调优是一个非常、非常核心的面试知识点,大家要非…...

【Mysql基础 —— SQL语句(一)】

文章目录概述使用启动/停止mysql服务连接mysql客户端数据模型SQLSQL语句分类DDL数据库操作表操作查询创建数据类型修改删除DML添加数据修改数据删除数据DQL基础查询条件查询聚合函数分组查询排序查询分页查询执行顺序DCL管理用户权限控制概述 数据库(Database&#…...

华为OD机试 - 新员工座位安排系统(Python) | 机试题算法思路

最近更新的博客 华为OD机试 - 招聘(Python) | 备考思路,刷题要点,答疑 【新解法】华为OD机试 - 五键键盘 | 备考思路,刷题要点,答疑 【新解法】华为OD机试 - 热点网络统计 | 备考思路,刷题要点,答疑 【新解法】华为OD机试 - 路灯照明 | 备考思路,刷题要点,答疑 【新解…...

MySQL - 介绍

前言 本篇介绍认识MySQL,重装mysql操作 如有错误,请在评论区指正,让我们一起交流,共同进步! 本文开始 1.什么是数据库? 数据库: 一种通过SQL语言操作管理数据的软件; 重装数据库的卸载数据库步骤 : ① 停止MySQL服…...

ChatGPT国内镜像站初体验:聊天、Python代码生成等

ChatGPT国内镜像站初体验,聊天、Python代码生成。 (本文获得CSDN质量评分【92】)【学习的细节是欢悦的历程】Python 官网:https://www.python.org/ Free:大咖免费“圣经”教程《 python 完全自学教程》,不仅仅是基础那么简单………...

SAP数据导入工具(LSMW) 超级详细教程(批量导入内部订单)

目录 第一步:记录批导步骤编辑数据源对应字段 第二步:维护数据源 第三步:维护数据源对应字段(重要) 第四步:维护数据源关系。 第五步:维护数据源与导入字段的对应关系。 第六步&#xff0…...

第9天-商品服务(电商核心概念,属性分组开发及分类和品牌的级联更新)

1.电商核心概念 1.1.SPU与SKU SPU:Standard Product Unit(标准化产品单元) 是商品信息聚合的最小单位,是一组可复用、易检索的标准化信息的集合,该集合描述了一个 产品的特性。 决定商品属性的值 SKU:Stock…...

动漫人物眼睛画法

本期的动漫绘画课程教大家来学习动漫人物眼睛画法,结合板绘软件从草稿开始一步步教你画出动漫人物眼睛,不用报动漫培训班也能学会,快来跟着本期的动漫人物眼睛画法教程试试吧! 动漫人物眼睛画法步骤教程: 注意&#x…...

张晨光-JAVA零基础保姆式JDBC技术教程

JDBC文档 JDBC概述 JDBC概述 Java DataBase Connectivity Java 数据库连接技术 JDBC的作用 通过Java语言操作数据库,操作表中的数据 SUN公司为**了简化、**统一对数据库的操作,定义了一套Java操作数据库的规范,称之为JDBC JDBC的本质 是官方…...

华为OD机试 - 最多提取子串数目(Python)

最多提取子串数目 题目 给定由 [a-z] 26 个英文小写字母组成的字符串 A 和 B,其中 A 中可能存在重复字母,B 中不会存在重复字母 现从字符串 A 中按规则挑选一些字母,可以组成字符串 B。 挑选规则如下: 1) 同一个位置的字母只能被挑选一次 2) 被挑选字母的相对先后顺序不…...

LeetCode-1237. 找出给定方程的正整数解【双指针,二分查找】

LeetCode-1237. 找出给定方程的正整数解【双指针&#xff0c;二分查找】题目描述&#xff1a;解题思路一&#xff1a;双指针。首先我们不管f是什么&#xff0c;即function_id等于什么不管。但是我们可以调用customfunction中的f函数&#xff0c;然后我们遍历x,y(1 < x, y &l…...

广度优先搜索算法 - 迷宫找路

广度优先搜索算法1 思考问题1.1 这个迷宫需不需要指定入口和出口&#xff1f;2 先粗略实现2.1 源码2.2 源码解释3 优化代码3.1 优化读取文件部分3.2 增加错误处理4 再优化-让程序变得更加灵活4.1 用户外部可以循环输入入口和出口5 完整代码这是一个提问者的提出的问题&#xff…...

泡脚材料简记

文章目录一般条件中药包&#xff08;药粉&#xff09;泡脚丸中药包&#xff08;药材&#xff09;艾叶生姜益母草藏红花食盐花椒白醋柠檬藿香泡脚私方紫苏叶、白术、白芍、黄芪、青皮、柴胡、夜交藤、丹参、当归&#xff0c;每种各10g艾叶、花椒、肉桂、桂枝、红花干姜30克、小茴…...

【计算机网络】因特网概述

文章目录因特网概述网络、互联网和因特网互联网历史与ISP标准化与RFC因特网的组成三种交换方式电路交换分组交换和报文交换三种交换方式的对比与总结计算机网络的定义和分类计算机网络的定义计算机网络的分类计算机网络的性能指标速率带宽吞吐量时延时延带宽积往返时间利用率丢…...

STC单片机 VS/HX1838红外接收和发送实验

STC单片机 VS/HX1838红外接收和发送实验 📌相关篇《STC单片机获取红外解码从串口输出》🔨所使用的红外接收头VS1838 📋VS1838引脚定义🌿5MM发射头,940nm红外发射二极管 红外遥控发射头。(外观看起来和普通的发光二极管没有什么差异,购买时需要注意确认)。 🔰采用的…...

前端开发常用案例(一)

前端开发常用案例1.实现三角形百度热榜样式分页效果小米商城自动轮播图效果二级下拉菜单效果时间轴效果展示音乐排行榜效果鼠标移入文字加载动画鼠标悬停缩放效果1.实现三角形 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8…...

Linux 日志查找常用命令

1.1 cat、zcat cat -n app.log | grep "error"&#xff1a;查询日志中含有某个关键字error的信息&#xff0c;显示行号。 cat -n app.log | grep "error" --color&#xff1a;查询日志中含有某个关键字error的信息&#xff0c;显示行号&#xff0c;带颜色…...

CleanMyMac4.12.5最新版安装下载教程

告别硬盘空间不足&#xff0c;让您的Mac极速如新CleanMyMac是一款强大的 Mac 清理、加速工具和健康卫士&#xff0c;让您的 Mac 加快启动速度。CleanMyMac是一款专业的Mac清理软件&#xff0c;可智能清理mac磁盘垃圾和多余语言安装包&#xff0c;快速释放电脑内存&#xff0c;轻…...

RFID射频识别技术(四) RFID高频电路基础|课堂笔记|10月11日

2022年10月11日 week7 ​​​​​​​ 目录 ​​​​​​​ 第四讲: RFID高频电路基础 一、RLC(串联)电路的阻抗...

数据库系统是什么?它由哪几部分组成?

数据库系统&#xff08;Database System&#xff0c;DBS&#xff09;由硬件和软件共同构成。硬件主要用于存储数据库中的数据&#xff0c;包括计算机、存储设备等。软件部分主要包括数据库管理系统、支持数据库管理系统运行的操作系统&#xff0c;以及支持多种语言进行应用开发…...

华为OD机试题 - 任务混部(JavaScript)

最近更新的博客 2023新华为OD机试题 - 斗地主(JavaScript)2023新华为OD机试题 - 箱子之形摆放(JavaScript)2023新华为OD机试题 - 考古学家(JavaScript)2023新华为OD机试题 - 相同数字的积木游戏 1(JavaScript)2023新华为OD机试题 - 最多等和不相交连续子序列(JavaScri…...

键盘输入a,到屏幕显示,操作系统做了什么

首先&#xff0c;假定操作系统有中断系统。 等待的键盘写入的时候&#xff0c;txt进程被read函数阻塞。输入a之后&#xff0c;首先控制器&#xff0c;把扫描到的a放入到了控制器的寄存器中。触发硬中断通知cpu—> 中断IO控制方式&#xff0c;由硬件触发的。键盘读入中断cpu…...

Python机器学习入门笔记(2)—— 分类算法

目录 转换器&#xff08;transformer&#xff09;和估计器&#xff08;estimator&#xff09; K-近邻&#xff08;K-Nearest Neighbors&#xff0c;简称KNN&#xff09;算法 模型选择与调优 交叉验证&#xff08;Cross-validation&#xff09; GridSearchCV API 朴素贝叶…...

Docker镜像发布到阿里云和私有库

目录 一、Docker镜像 &#xff08;一&#xff09;概述 &#xff08;二&#xff09;Docker镜像加载原理 &#xff08;三&#xff09;镜像分层结构优势 &#xff08;四&#xff09;重点理解 &#xff08;五&#xff09;docker commit操作实例 &#xff08;六&#xff09;总…...

初识CSS,美化HTML

CSS称为&#xff1a;层叠样式表&#xff08;Cascading style sheets&#xff09;美化HTML即给页面种的HTML标签设置样式CSS语法规则css要写在head标签的里边&#xff0c;title标签的下面&#xff0c;用style标签框住<head> <title>...</title> <style>…...

华为OD机试 - 二维矩阵的最大值(Python)

题目二维矩阵的最大值 给定一个仅包含0和1的n*n二维矩阵 请计算二维矩阵的最大值 计算规则如下 每行元素按下标顺序组成一个二进制数(下标越大约排在低位), 二进制数的值就是该行的值,矩阵各行之和为矩阵的值允许通过向左或向右整体循环移动每个元素来改变元素在行中的位置 …...

华为OD机试 - 快递业务站(Python)

快递业务站 题目 快递业务范围有 N 个站点,A 站点与 B 站点可以中转快递,则认为 A-B 站可达, 如果 A-B 可达,B-C 可达,则 A-C 可达。 现在给 N 个站点编号 0、1、…n-1,用 s[i][j]表示 i-j 是否可达, s[i][j] = 1表示 i-j可达,s[i][j] = 0表示 i-j 不可达。 现用二维…...

百度沈抖:文心一言将通过百度智能云对外提供服务

2月17日&#xff0c;在2023 AI工业互联网高峰论坛上&#xff0c;百度智能云宣布“文心一言”将通过百度智能云对外提供服务&#xff0c;为产业带来AI普惠。 百度集团执行副总裁、百度智能云事业群总裁沈抖表示&#xff0c;“文心一言”是基于百度智能云技术打造出来的大模型&a…...

cmd 窗口、记事本打开后一片空白且几秒钟后闪退的问题解决方案汇总

前言 前段时间&#xff0c;电脑忽然出现了问题&#xff0c;首先是通过 微软应用商店 Microsoft Store 下载安装的 Snipaste 截图软件崩溃&#xff0c;不过将其卸载后&#xff0c;通过电脑管家下载后又可以正常使用了。 之后就是突然发现&#xff0c;记事本文本文档不能使用了…...

Linux 安装 SNMP服务

从安装盘IOS中导入安装SNMP. --挂载系统安装盘 [rootnb /]# mount -o loop -t iso9660 /software/radhat.iso /media mount: /dev/loop0 is write-protected, mounting read-only --导入安装包 [rootnb /]# rm -f /etc/yum.repos.d/*.repo [rootnbubackup /]# cat >/etc/yu…...

如何快速自己做网站/品牌营销的四大策略

一&#xff09;概念pendingIntent字面意义&#xff1a;延迟的intent&#xff0c;等待的&#xff0c;未决定的Intent。 主要用来在某个事件完成后执行特定的Action。 pendingIntent是一种特殊的Intent。 主要的区别在于Intent的执行是立刻的&#xff0c; 而pendingIntent的执行不…...

网站建设的步骤/今日头条官网

如果要给C11颁一个“最令人困惑新词”奖&#xff0c;constexpr十有八九会折桂。当用于对象上面&#xff0c;它本质上就是const的加强形式&#xff0c;但是当它用于函数上&#xff0c;意思就大不相同了。有必要消除困惑&#xff0c;因为你绝对会用它的&#xff0c;特别是当你发现…...

做网站的专业叫啥/关键词优化seo排名

一、约束条件约束类型关键字默认约束default 值非空约束not null唯一约束unique key自增长约束auto_increment主键约束primary key外键约束foreign key1.1 默认约束(default 默认值)初始值设置&#xff0c;插入记录时&#xff0c;如果没有明确为字段赋值&#xff0c;则自动赋予…...

大学生个人网站怎么做/网站备案查询

安装环境准备 1.安装 jdk 2.安装Maven 依赖关系如下&#xff1a; 因为没有现成的安装包&#xff0c;需要使用Maven对Github上的源码进行编译。所以安装的Jdk版本取决于你的Maven版本。至于Maven版本的选择就选择最新的。 以下是我安装的版本&#xff1a; 具体安装步骤…...

唐山网站快速排名提升/百度云电脑版网站入口

网关(Gateway)又称网间连接器、协议转换器。网关在传输层上以实现网络互连&#xff0c;是最复杂的网络互连设备&#xff0c;仅用于两个高层协议不同的网络互连。网关的结构也和路由器类似&#xff0c;不同的是互连层。网关既可以用于广域网互连&#xff0c;也可以用于局域网互连…...

wordpress 做论坛/百度刷自己网站的关键词

我试图写出一些文本&#xff0c;并在可能的情况下将其编码为utf-8&#xff0c;使用以下代码&#xff1a;outf.write((lang_name "," (script_name or "") "\n").encode("utf-8", errorsreplace))我得到以下错误&#xff1a;^{pr2}$…...