Elasticsearch Search API之(Request Body Search 查询主体)

  • sentence

句子,使用Java的BreakIterator确定的下一个句子边界处的突出显示片段。您可以使用boundary_scanner_locale指定要使用的区域设置。unified highlighter高亮器默认行为。

  • word

单词,由Java的BreakIterator确定的下一个单词边界处高亮显示的片段。

  • boundary_scanner_locale

区域设置。该参数采用语言标记的形式,例如。“en - us”、“- fr”、“ja-JP”。更多信息可以在Locale语言标记文档中找到。默认值是local . root。

  • encoder

指示代码段是否应该编码为HTML:默认(无编码)或HTML (HTML-转义代码段文本,然后插入高亮标记)。

  • fields

指定要检索高亮显示的字段,支持通配符。例如,您可以指定comment_*来获得以comment_开头的所有文本和关键字字段的高亮显示。

注意:当您使用通配符时,只会匹配text、keyword类型字段。

  • force_source

是否强制从_source高亮显示,默认为false。其实默认情况就是根据源字段内容(_source)内容高亮显示,即使字段是单独存储的。

  • fragmenter

指定如何在高亮显示代码片段中拆分文本:可选值为simple、span。仅适用于Plain highlighting。默认为span。

  • simple

将文本分成大小相同的片段。

  • span

将文本分割成大小相同的片段,但尽量避免在突出显示的术语之间分割文本。这在查询短语时很有用。

  • fragment_offset

控制开始高亮显示的margin(空白),仅适用于fast vector highlighter。

  • fragment_size

高亮显示的片段,默认100。

  • highlight_query

高亮显示匹配搜索查询以外的查询。如果您使用rescore查询,这尤其有用,因为默认情况下高亮显示并不会考虑这些查询。通常,应该将搜索查询包含在highlight_query中。

  • matched_fields

组合多个字段上的匹配项以突出显示单个字段。对于以不同方式分析相同字符串的多个字段,这是最直观的。所有matched_fields必须将term_vector设置为with_positions_offset,但是只加载匹配项组合到的字段,所以建议该字段store设置为true。只适用于fast vector highlighter荧光笔。

  • no_match_size

如果没有要高亮显示的匹配片段,则希望从字段开头返回的文本数量。默认值为0(不返回任何内容)。

  • number_of_fragments

返回的高亮显示片段的最大数量。如果片段的数量设置为0,则不返回片段。默认为5。

  • order

该值默认为none,按照字段的顺序返回高亮文档,可以设置为score(按相关性排序)。

  • phrase_limit

控制要考虑的文档中匹配短语的数量。防止fast vector highlighter分析太多的短语和消耗太多的内存。在使用matched_fields时,将考虑每个匹配字段的phrase_limit短语。提高限制会增加查询时间并消耗更多内存。只支持fast vector highlighter。默认为256。

  • pre_tags

用于高亮显示HTML标签,与post_tags一起使用,默认用_高亮显示文本_。

  • post_tags

用于高亮显示HTML标签,与pre_tags一起使用,默认用_高亮显示文本_。

  • require_field_match

默认情况下,只有包含查询匹配的字段才会高亮显示。将require_field_match设置为false以突出显示所有字段。默认值为true。

  • tags_schema

定义高亮显示样式,例如_。_

  • type

指定高亮显示器,可选值:unified、plain、fvh。默认值为unified。

7.4 高亮显示demo

public static void testSearch_highlighting() {

RestHighLevelClient client = EsClient.getClient();

try {

SearchRequest searchRequest = new SearchRequest();

searchRequest.indices(“map_highlighting_01”);

SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

sourceBuilder.query(

// QueryBuilders.matchAllQuery()

QueryBuilders.termQuery(“context”, “身份证”)

);

HighlightBuilder highlightBuilder = new HighlightBuilder();

highlightBuilder.field(“context”);

sourceBuilder.highlighter(highlightBuilder);

searchRequest.source(sourceBuilder);

System.out.println(client.search(searchRequest, RequestOptions.DEFAULT));

} catch (Exception e) {

// TODO: handle exception

}

}

其返回值如下:

{

“took”:2,

“timed_out”:false,

“_shards”:{

“total”:5,

“successful”:5,

“skipped”:0,

“failed”:0

},

“hits”:{

“total”:1,

“max_score”:0.2876821,

“hits”:[

{

“_index”:“map_highlighting_01”,

“_type”:“_doc”,

“_id”:“erYsbmcBeEynCj5VqVTI”,

“_score”:0.2876821,

“_source”:{

“context”:“城中西路可以受理外地二代身份证的办理。”

},

“highlight”:{ // @1

“context”:[

“城中西路可以受理外地二代身份证的办理。”

]

}

}

]

}

}

这里主要对highlight再做一次说明,其中每一个字段返回的内容是对应原始数据的子集,最多fragmentSize个待关键字的匹配条目,通常,在页面上显示文本时,应该用该字段取代原始值,这样才能有高亮显示的效果。

8、Rescoring

重打分机制。一个查询首先使用高效的算法查找文档,然后对返回结果的top n 文档运用另外的查询算法,通常这些算法效率低效但能提供匹配精度。

resoring查询与原始查询分数的合计方式如下:

  • total

两个评分相加

  • multiply

将原始分数乘以rescore查询分数。用于函数查询重定向。

  • avg

取平均数

  • max

取最大值

  • min

取最小值。

9、Search Type

查询类型,可选值:QUERY_THEN_FETCH、QUERY_AND_FETCH、DFS_QUERY_THEN_FETCH。默认值:query_then_fetch。

  • QUERY_THEN_FETCH:首先根据路由算法向相关分片(多个)发送请求,此时只返回documentId与一些必要信息(例如用于排序等),然后对各个分片的结果进行汇聚,排序,然后选取客户端指定需要获取的数据条数(top n),然后根据documentId再向各个分片请求具体的文档信息。

  • QUERY_AND_FETCH:在5.4.x版本开始废弃,是直接向各个分片节点请求数据,每个分片返回客户端请求数量的文档信息,然后汇聚全部返回给客户端,返回的数据为客户端请求数量size * (路由后的分片数量)。

  • DFS_QUERY_THEN_FETCH:在开始向各个节点发送请求之前,会进行一次词频、相关性的计算,后续流程与QUERY_THEN_FETCH相同,可以看出,该查询类型的文档相关性会更高,但性能比QUERY_THEN_FETCH要差。

10、scroll

滚动查询。es另外一种分页方式。虽然搜索请求返回结果的单个“页面”,但scroll API可以用于从单个搜索请求检索大量结果(甚至所有结果),这与在传统数据库上使用游标的方式非常相似。scroll api不用于实时用户请求,而是用于处理大量数据,例如为了将一个索引的内容重新索引到具有不同配置的新索引中。

10.1 如何使用scroll API

scroll API使用分为两步:

1、第一步,首先通过scroll参数,指定该滚动查询(类似于数据库的游标的存活时间)

POST /twitter/_search?scroll=1m

{

“size”: 100,

“query”: {

“match” : {

“title” : “elasticsearch”

}

}

}

该方法会返回一个重要的参数:scrollId。

2、第二步,使用该scrollId去es服务器拉取下一批(下一页数据)

POST /_search/scroll

{

“scroll” : “1m”,

“scroll_id” : “DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAD4WYm9laVYtZndUQlNsdDcwakFMNjU1QQ==”

}

循环第三步,可以循环批量处理数据。

3、第三步,清除scrollId,类似于清除数据库游标,快速释放资源。

DELETE /_search/scroll

{

“scroll_id” : “DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAD4WYm9laVYtZndUQlNsdDcwakFMNjU1QQ==”

}

下面给出scoll api的java版本示例程序:

public static void testScoll() {

RestHighLevelClient client = EsClient.getClient();

String scrollId = null;

try {

System.out.println("step 1 start ");

// step 1 start

SearchRequest searchRequest = new SearchRequest();

searchRequest.indices(“map_highlighting_01”);

SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

sourceBuilder.query(

QueryBuilders.termQuery(“context”, “身份证”)

);

searchRequest.source(sourceBuilder);

searchRequest.scroll(TimeValue.timeValueMinutes(1));

SearchResponse result = client.search(searchRequest, RequestOptions.DEFAULT);

scrollId = result.getScrollId();

// step 1 end

// step 2 start

if(!StringUtils.isEmpty(scrollId)) {

System.out.println("step 2 start ");

SearchScrollRequest scrollRequest = new SearchScrollRequest(scrollId);

scrollRequest.scroll(TimeValue.timeValueMinutes(1));

while(true) { //循环遍历

SearchResponse scollResponse = client.scroll(scrollRequest, RequestOptions.DEFAULT);

if(scollResponse.getHits().getHits() == null ||

scollResponse.getHits().getHits().length < 1) {

break;

}

scrollId = scollResponse.getScrollId();

// 处理文档

scrollRequest.scrollId(scrollId);

}

// step 2 end

}

System.out.println(result);

} catch (Exception e) {

e.printStackTrace();

} finally {

if(!StringUtils.isEmpty(scrollId)) {

System.out.println("step 3 start ");

// step 3 start

ClearScrollRequest clearScrollRequest = new ClearScrollRequest();

clearScrollRequest.addScrollId(scrollId);

try {

client.clearScroll(clearScrollRequest, RequestOptions.DEFAULT);

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

// step 3 end

}

}

}

这里重点阐述一下第一次查询时,不仅返回scrollId,也会返回第一批数据。

10.2 Keeping the search context alive

scroll参数(传递给搜索请求和每个滚动请求)告诉Elasticsearch它应该保持搜索上下文活动多长时间。它的值(例如1m,参见Time unitsedit)不需要足够长的时间来处理所有数据——它只需要足够长的时间来处理前一批结果。每个scroll请求(带有scroll参数)设置一个新的过期时间。如果scroll请求没有传入scroll,那么搜索上下文将作为scroll请求的一部分被释放。scroll其内部实现类似于快照,当第一次收到一个scroll请求时,就会为该搜索上下文所匹配的结果创建一个快照,随后文档的变化并不会反映到该API的结果。

10.3 sliced scroll

对于返回大量文档的scroll查询,可以将滚动分割为多个可以独立使用的片,通过slice指定。

例如:

GET /twitter/_search?scroll=1m // @1

{

“slice”: { // @11

“id”: 0, // @12

“max”: 2 // @13

},

“query”: {

“match” : {

“title” : “elasticsearch”

}

}

}

GET /twitter/_search?scroll=1m // @2

{

“slice”: {

“id”: 1,

“max”: 2

},

“query”: {

“match” : {

“title” : “elasticsearch”

}

}

}

@1,@2两个并列的查询,按分片去查询。

@11:通过slice定义分片查询。

@12:该分片查询的ID。

@13:本次查询总片数。

这个机制非常适合多线程处理数据。

具体分片机制是,首先将请求转发到各分片节点,然后在每个节点使用匹配到的文档(hashcode(_uid)%slice片数),然后各分片节点返回数据到协调节点。也就是默认情况下,分片是根据文档的_uid,为了提高分片过程,可以通过如下方式进行优化,并指定分片字段。

  • 分片字段类型为数值型。

  • 字段的doc_values设置为true。

  • 每个文档中都索引了该字段。

  • 该字段值只在创建时赋值,并不会更新。

  • 字段的基数应该很高(相当于数据库索引选择度),这样能确保每个片返回的数据相当,数据分布较均匀。

注意,默认slice片数最大为1024,可以通过索引设置项index.max_slices_per_scroll来改变默认值。

例如:

GET /twitter/_search?scroll=1m

{

“slice”: {

“field”: “date”,

“id”: 0,

“max”: 10

},

“query”: {

“match” : {

“title” : “elasticsearch”

}

}

}

11、preference

查询选择副本分片的倾向性(即在一个复制组中选择副本的分片值。默认情况下,Elasticsearch以未指定的顺序从可用的碎片副本中进行选择,副本之间的路由将在集群章节更加详细的介绍 。可以通过该字段指定分片倾向与选择哪个副本。

preference可选值:

  • _primary

只在节点上执行,在6.1.0版本后废弃,将在7.x版本移除。

  • _primary_first

优先在主节点上执行。在6.1.0版本后废弃,将在7.x版本移除。

  • _replica

操作只在副本分片上执行,如果有多个副本,其顺序随机。在6.1.0版本后废弃,将在7.x版本移除。

  • _replica_first

优先在副本分片上执行,如果有多个副本,其顺序随机。在6.1.0版本后废弃,将在7.x版本移除。

  • _only_local

操作将只在分配给本地节点的分片上执行。_only_local选项保证只在本地节点上使用碎片副本,这对于故障排除有时很有用。所有其他选项不能完全保证在搜索中使用任何特定的碎片副本,而且在索引更改时,这可能意味着如果在处于不同刷新状态的不同碎片副本上执行重复搜索,则可能产生不同的结果。

  • _local

优先在本地分片上执行。

  • _prefer_nodes:abc,xyz

优先在指定节点ID的分片上执行,示例中的节点ID为abc、xyz。

  • _shards:2,3

将操作限制到指定的分片上执行。(这里是2和3)这个首选项可以与其他首选项组合,但必须首先出现:_shards:2,3|_local。

  • _only_nodes:abc*,x*yz,…

根据节点ID进行限制。

  • Custom (string) value

自定义字符串,其路由为 hashcode(该值)%赋值组内节点数。例如在web应用中通常以sessionId为倾向值。

12、explain

是否解释各分数是如何计算的。

GET /_search

{

“explain”: true,

“query” : {

“term” : { “user” : “kimchy” }

}

}

13、version

如果设置为true,则返回每个命中文档的当前版本号。

GET /_search

{

“version”: true,

“query” : {

“term” : { “user” : “kimchy” }

}

}

14、Index Boost

当搜索多个索引时,允许为每个索引配置不同的boost级别。当来自一个索引的点击率比来自另一个索引的点击率更重要时,该属性则非常方便。

使用示例如下:

GET /_search

{

“indices_boost” : [

{ “alias1” : 1.4 },

{ “index*” : 1.3 }

]

}

15、min_score

指定返回文档的最小评分,如果文档的评分低于该值,则不返回。

GET /_search

{

“min_score”: 0.5,

“query” : {

“term” : { “user” : “kimchy” }

}

}

16、Named Queries

每个过滤器和查询都可以在其顶级定义中接受_name。搜索响应中每个匹配文档中会增加matched_queries结构体,记录该文档匹配的查询名称。查询和筛选器的标记只对bool查询有意义。

java示例如下:

public static void testNamesQuery() {

RestHighLevelClient client = EsClient.getClient();

try {

SearchRequest searchRequest = new SearchRequest();

searchRequest.indices(“esdemo”);

SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

sourceBuilder.query(

QueryBuilders.boolQuery()

.should(QueryBuilders.termQuery(“context”, “fox”).queryName(“q1”))

.should(QueryBuilders.termQuery(“context”, “brown”).queryName(“q2”))

);

searchRequest.source(sourceBuilder);

SearchResponse result = client.search(searchRequest, RequestOptions.DEFAULT);

System.out.println(result);

} catch (Throwable e) {

e.printStackTrace();

} finally {

EsClient.close(client);

}

}

返回结果如下:

{

“took”:4,

“timed_out”:false,

“_shards”:{

“total”:5,

“successful”:5,

“skipped”:0,

“failed”:0

},

“hits”:{

“total”:2,

“max_score”:0.5753642,

“hits”:[

{

“_index”:“esdemo”,

“_type”:“matchquerydemo”,

“_id”:“2”,

“_score”:0.5753642,

“_source”:{

“context”:“My quick brown as fox eats rabbits on a regular basis.”,

“title”:“Keeping pets healthy”

},

“matched_queries”:[

“q1”,

“q2”

]

},

{

“_index”:“esdemo”,

“_type”:“matchquerydemo”,

“_id”:“1”,

“_score”:0.39556286,

“_source”:{

“context”:“Brown rabbits are commonly seen brown.”,

“title”:“Quick brown rabbits”

},

“matched_queries”:[

“q2”

]

}

]

}

}

正如上面所说,每个匹配文档中都包含matched_queries,表明该文档匹配的是哪个查询条件。

17、Inner hits

用于定义内部嵌套层的返回规则,其inner hits支持如下选项:

  • from 用于内部匹配的分页。

  • size 用于内部匹配的分页,size。

  • sort 排序策略。

  • name 为内部嵌套层定义的名称。

该部分示例将在下节重点阐述。

18、field collapsing(字段折叠)

允许根据字段值折叠搜索结果。折叠是通过在每个折叠键上只选择排序最高的文档来完成的。有点类似于聚合分组,其效果类似于按字段进行分组,默认命中的文档列表第一层由该字段的第一条信息,也可以通过允许根据字段值折叠搜索结果。折叠是通过在每个折叠键上只选择排序最高的文档来完成的。例如,下面的查询为每个用户检索最佳tweet,并按喜欢的数量对它们进行排序。

下面首先通过示例进行展示field collapsing的使用。

1)首先查询发的推特内容中包含elasticsearch的推文:

GET /twitter/_search

{

“query”: {

“match”: {

“message”: “elasticsearch”

}

},

“collapse” : {

“field” : “user”

},

“sort”: [“likes”]

}

返回结果:

{

“took”:8,

“timed_out”:false,

“_shards”:{

“total”:5,

“successful”:5,

“skipped”:0,

“failed”:0

},

“hits”:{

“total”:5,

“max_score”:null,

“hits”:[

{

“_index”:“mapping_field_collapsing_twitter”,

“_type”:“_doc”,

“_id”:“OYnecmcB-IBeb8B-bF2X”,

“_score”:null,

“_source”:{

“message”:“to be a elasticsearch”,

“user”:“user2”,

“likes”:3

},

“sort”:[

3

]

},

{

“_index”:“mapping_field_collapsing_twitter”,

“_type”:“_doc”,

“_id”:“OonecmcB-IBeb8B-bF2q”,

“_score”:null,

“_source”:{

“message”:“to be elasticsearch”,

“user”:“user2”,

“likes”:3

},

“sort”:[

3

]

},

{

“_index”:“mapping_field_collapsing_twitter”,

“_type”:“_doc”,

“_id”:“OInecmcB-IBeb8B-bF2G”,

“_score”:null,

“_source”:{

“message”:“elasticsearch is very high”,

“user”:“user1”,

“likes”:3

},

“sort”:[

3

]

},

{

“_index”:“mapping_field_collapsing_twitter”,

“_type”:“_doc”,

“_id”:“O4njcmcB-IBeb8B-Rl2H”,

“_score”:null,

“_source”:{

“message”:“elasticsearch is high db”,

“user”:“user1”,

“likes”:1

},

“sort”:[

1

]

},

{

“_index”:“mapping_field_collapsing_twitter”,

“_type”:“_doc”,

“_id”:“N4necmcB-IBeb8B-bF0n”,

“_score”:null,

“_source”:{

“message”:“very likes elasticsearch”,

“user”:“user1”,

“likes”:1

},

“sort”:[

1

]

}

]

}

}

首先上述会列出所有用户的推特,如果只想每个用户只显示一条推文,并且点赞率最高,或者每个用户只显示2条推文呢?

这个时候,按字段折叠就闪亮登场了。

java demo如下:

public static void search_field_collapsing() {

RestHighLevelClient client = EsClient.getClient();

try {

SearchRequest searchRequest = new SearchRequest();

searchRequest.indices(“mapping_field_collapsing_twitter”);

SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

sourceBuilder.query(

QueryBuilders.matchQuery(“message”,“elasticsearch”)

);

sourceBuilder.sort(“likes”, SortOrder.DESC);

CollapseBuilder collapseBuilder = new CollapseBuilder(“user”);

sourceBuilder.collapse(collapseBuilder);

searchRequest.source(sourceBuilder);

SearchResponse result = client.search(searchRequest, RequestOptions.DEFAULT);

System.out.println(result);

} catch (Throwable e) {

e.printStackTrace();

} finally {

EsClient.close(client);

}

}

其结果如下:

{

“took”:22,

“timed_out”:false,

“_shards”:{

“total”:5,

“successful”:5,

“skipped”:0,

“failed”:0

},

“hits”:{

“total”:5,

“max_score”:null,

“hits”:[

{

“_index”:“mapping_field_collapsing_twitter”,

“_type”:“_doc”,

“_id”:“OYnecmcB-IBeb8B-bF2X”,

“_score”:null,

“_source”:{

“message”:“to be a elasticsearch”,

“user”:“user2”,

“likes”:3

},

“fields”:{

“user”:[

“user2”

]

},

“sort”:[

3

]

},

{

“_index”:“mapping_field_collapsing_twitter”,

“_type”:“_doc”,

“_id”:“OInecmcB-IBeb8B-bF2G”,

“_score”:null,

“_source”:{

“message”:“elasticsearch is very high”,

“user”:“user1”,

“likes”:3

},

“fields”:{

“user”:[

“user1”

]

},

“sort”:[

3

]

}

]

}

}

上面的示例只返回了每个用户的第一条数据,如果需要每个用户返回2条数据呢?可以通过inner_hit来设置。

public static void search_field_collapsing() {

RestHighLevelClient client = EsClient.getClient();

try {

SearchRequest searchRequest = new SearchRequest();

searchRequest.indices(“mapping_field_collapsing_twitter”);

SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

sourceBuilder.query(

QueryBuilders.matchQuery(“message”,“elasticsearch”)

);

sourceBuilder.sort(“likes”, SortOrder.DESC);

CollapseBuilder collapseBuilder = new CollapseBuilder(“user”);

InnerHitBuilder collapseHitBuilder = new InnerHitBuilder(“collapse_inner_hit”);

collapseHitBuilder.setSize(2);

collapseBuilder.setInnerHits(collapseHitBuilder);

sourceBuilder.collapse(collapseBuilder);

searchRequest.source(sourceBuilder);

SearchResponse result = client.search(searchRequest, RequestOptions.DEFAULT);

System.out.println(result);

} catch (Throwable e) {

e.printStackTrace();

} finally {

EsClient.close(client);

}

}

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

总结

总体来说,如果你想转行从事程序员的工作,Java开发一定可以作为你的第一选择。但是不管你选择什么编程语言,提升自己的硬件实力才是拿高薪的唯一手段。

如果你以这份学习路线来学习,你会有一个比较系统化的知识网络,也不至于把知识学习得很零散。我个人是完全不建议刚开始就看《Java编程思想》、《Java核心技术》这些书籍,看完你肯定会放弃学习。建议可以看一些视频来学习,当自己能上手再买这些书看又是非常有收获的事了。


《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
_hit");

collapseHitBuilder.setSize(2);

collapseBuilder.setInnerHits(collapseHitBuilder);

sourceBuilder.collapse(collapseBuilder);

searchRequest.source(sourceBuilder);

SearchResponse result = client.search(searchRequest, RequestOptions.DEFAULT);

System.out.println(result);

} catch (Throwable e) {

e.printStackTrace();

} finally {

EsClient.close(client);

}

}

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。[外链图片转存中…(img-pE9Wwq08-1712571070642)]

[外链图片转存中…(img-LaIoFJFZ-1712571070642)]

[外链图片转存中…(img-Km8UoZE3-1712571070643)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

总结

总体来说,如果你想转行从事程序员的工作,Java开发一定可以作为你的第一选择。但是不管你选择什么编程语言,提升自己的硬件实力才是拿高薪的唯一手段。

如果你以这份学习路线来学习,你会有一个比较系统化的知识网络,也不至于把知识学习得很零散。我个人是完全不建议刚开始就看《Java编程思想》、《Java核心技术》这些书籍,看完你肯定会放弃学习。建议可以看一些视频来学习,当自己能上手再买这些书看又是非常有收获的事了。

[外链图片转存中…(img-7mLX0roJ-1712571070643)]
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 19
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值