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

MongoDB索引介绍

索引简述

  1. 索引是什么
    索引在数据库技术体系中占据了非常重要的位置,其主要表现为一种目录式的数据结构,用来实现快速的数据查询。通常在实现上,索引是对数据库表(集合)中的某些字段进行抽取、排列之后,形成的一种非常易于遍历读取的数据集合。目前绝大多数的数据库对于索引技术都有非常强大且稳定的支持。
    索引的作用非常类似于一本书的目录。

  2. 索引的分类

    • 按照索引包含的字段数量,可以分为单键索引和组合索引(或复合索引)。
    • 按照索引字段的类型,可以分为主键索引和非主键索引。
    • 按照索引节点与物理记录的对应方式来分,可以分为聚簇索引和非聚簇索引,其中聚簇索引是指索引节点上直接包含了数据记录,而后者则仅仅包含了一个指向数据记录的指针。
    • 按照索引的特性不同,又可以分为唯一索引、稀疏索引、文本索引、地理空间索引等。

单键、复合索引

在MongoDB中,我们可以对集合中的某个字段或某几个字段创建索引,以book实体为例:

{"_id" : ObjectId("67ab68cbf47317cf01307b3b"),"title" : "book-0","type" : "technology","favCount" : 93,"tags":['popular'],"author" : {"name" : "zale"}
}
  • 单字段索引
    如果经常使用title这个字段进行搜索,可以为它创建一个单字段的索引

    > db.book.bookCollection.ensureIndex({title:1})
    {"createdCollectionAutomatically" : true,"numIndexesBefore" : 1,"numIndexesAfter" : 2,"ok" : 1
    }
    

    这里的“title:1”中的1表示所有采用的是升序排列。然而,在单字段的索引中,使用升序和降序并没有什么区别。
    我们也可以对内嵌的文档字段创建索引:db.book.bookCollection.ensureIndex({auth.name:1})

  • 复合索引
    复合索引是多个字段组合而成的索引,其性质和单字段索引类似。但不同的是,复合索引中字段的顺序、字段的升降序对查询性能有直接的影响,因此在设计复合索引时需要考虑不同的查询场景。
    例如,如果需要频繁地查询某分类下地book文档排名,可以按照分类,收藏数量创建一个复合索引,
    db.book.bookCollection.ensureIndex({type:1,favCount:1})

数组索引

数组索引也被称为多值索引,当我们对数组型地字段创建索引时,这个索引就是多值的。多值索引在使用上与普通索引并没有什么不同,只是索引键上会同时产生多个值。

db.book.bookCollection.ensureIndex({tags:1})

多值索引很容易与复合索引产生混淆,复合索引时多个字段的组合,而多值索引则仅仅是在一个字段上出现了多值。而实际上,多值索引也可以出现在复合索引上,例如:db.book.bookCollection.ensureIndex({type:1,tags:1})。然而,mongodb并不支持一个复合索引中同时出现多个数组字段。

地理空间索引

在移动互联网时代,基于地理位置的检索功能几乎时所有应用系统的标配。
mongodb为地理空间检索提供了非常方便的功能。地理空间索引就是专门用于实现位置检索的一种特殊索引。

db.store.insertOne({location:{type:"Point",coordinates:[-122.158574,37.449157]}})   
db.store.ensureIndex({ location: "2dsphere" });
db.store.find({location:{$near:{$geometry:{type:"Point",coordinates:[-122.158,37.449]},$maxDistance:5000}}})> { "_id" : ObjectId("67ab829c2cee149b47c1e30e"), "location" : { "type" : "Point", "coordinates" : [ -122.158574, 37.449157 ] } }

这里使用$near查询操作符,用于实现附近商家的检索,返回的数据结果会按距离排序

注意:mongodb的地理空间检索基于WGS84坐标系,在与一些地图平台集成时需要注意转换。

唯一性约束

在创建索引时,通过指定unique=true选项可以将其声明为唯一性索引,代码如下:

db.book.ensureIndex({title:1},{unique:true})

此后,如果尝试写入2个拥有相同标题的book文档,则会报错;另外,对于指定的字段已经存在重复记录的集合,如果尝试创建唯一性约束的索引,也会提示报错。

  1. 复合索引的唯一性
    除了单字段索引,还可以为复合索引使用唯一约束。例如,如果只是希望分类下的书籍标题保持唯一性,那么可以建立复合式的唯一索引。

    db.book.ensureIndex({type:1,title:1},{unique:true})
    
  2. 嵌套文档的唯一性
    唯一性约束同样可以用于嵌套文档的某个字段,这和普通索引没有什么区别,比如:

    db.book.ensureIndex({author.name:1},{unique:true})
    

    但如果希望将整个嵌套文档作为唯一性的保证,那么在使用时可能会造成困扰,比如:

    db.book.ensureIndex({author:1},{unique:true})
    

    嵌套文档的唯一性约束是严格按照写入顺序进行比较的,如下代码所示,尽管写入的文档内容是一样的,但由于字段的顺序不一致,mongodb仍然认为这是不同的文档。为了避免困扰,尽量少用这种写法。

    db.book.insert({author:{age:20,name:"Lwy"}})
    db.book.insert({author:{name:"Lwy",age:20}})
    
  3. 数组的唯一性
    如果对数组索引使用唯一性约束,那么可以保证所有的文档之间不会存在重叠的数组元素,代码如下:

    db.book.ensureIndex({tags:1},{unique:true})
    db.book.insert({tags:["t1","t2"]})
    db.book.insert({tags:["t1","t3","t3"]})//插入失败
    

    但是,数组索引上的唯一性约束并无法保证同一个文档中包含重复的元素,如下面的语句是可以写入成功的:

    db.book.insert({tags:['t1','t3','t1']})
    

    注意:如果数组中的元素是嵌套的文档,那么同样会遇到字段次序的问题。

  4. 使用约束

    • 唯一性索引对于文档中缺失的字段,会使用null值代替,因此不允许存在多个文档缺失索引字段的情况。
    • 对于分片的集合,唯一性约束必须匹配分片规则。换句话说,为了保证全局的唯一性,分片键必须作为唯一性索引的前缀字段。

TTL索引

在一般的应用系统中,并非所有的数据都需要永久存储。例如一些系统事件、用户消息等,这些数据随着事件的推移,其重要程度逐渐降低。更重要的是,储存这些大量的历史数据需要花费较高的成本,因此项目中通常会对过期且不再使用的数据进行老化处理。
通常的做法如下:

  • 为每一个数据记录一个时间戳,应用侧开启一个定时器,按时间戳定期删除过期的数据。
  • 数据按日期进行分表,同一天的数据归档到同一张表,同样使用定时器删除过期的表。

对于数据老化,mongodb提供了一种更加便捷的做法:TTL索引。TTL索引需要声明在一个日期类型的字段中,假定写入的文档数据如下:

db.systemlog.insert({createdDate:new Date(),type:"warning"})
db.systemlog.ensureIndex({createdDate:1},{expireAfterSeconds:3600})//1小时后过期

对于集合创建TTL索引之后,mongodb会在周期性运行的后台线程中对该集合进行检查以及数据清理工作。除了数据老化功能,TTL索引具有普通索引的功能,同样可以用于加速数据的查询。

  1. 可变的过期时间
    TTL索引在创建之后,仍然可以对过期时间进行修改。

    db.runCommand({collMod:"systemlog",index:{KeyPattern:{createdDate:1},expireAfterSeconds:7200}})
    

    另一种情形也比较常见,如每个文档可能拥有各自的存活时长,即老化策略不同。
    比如,在systemlog集合中,不同的事件类型的老化周期是不一样的,对于此类场景的解决方法是可以使用一个单独的字段expiredDate,用于表示每个文档的过期时间点,那么TTL索引创建的规则为:

    db.systemlog.ensureIndex({expiredDate:1},{expireAfterSeconds:0})
    
  2. 使用约束
    TTL索引的确可以减少开发量,而且通过数据库自动清理的方式会更加高效、可靠,但是在使用TTL索引时需要注意以下的限制:

    • TTL索引只能支持单个字段,并且必须是非_id字段。
    • TTL索引不能用于固定集合。
    • TTL索引无法保证及时的数据老化,mongodb会通过后台的TTL Monitor定时器来清理老化数据,如果在数据库负载过高的情况下,TTL的行为则会进一步收到影响。
    • TTL索引对于数据的清理仅仅使用了remove命令,这种方式并不是很高效。因此TTL Monitor在运行期间对系统CPU、磁盘都会造成一定的压力。相比之下,按日期分表的方式操作会更加高效。

条件索引

条件索引允许对部分文档建立索引。例如,仅对业务上最常用于查询的数据集创建索引,可以节省一些空间。

db.store.createIndex({cuisine:1,name:1},{partialFilterExpression:{rating:{$gt:5}}})

只对评分高于5分的餐馆信息进行索引。

稀疏索引

对于某个索引字段来说,可能某些文档中并不存在该字段,但是mongodb索引会将不存在字段的情况等同于null值处理。稀疏索引则具备这样的特性:只对存在字段的文档进行索引(包括字段值为null的文档)。

> db.test.insert({x:1})
WriteResult({ "nInserted" : 1 })
> db.test.insert({x:2,z:null})
WriteResult({ "nInserted" : 1 })
> db.test.find({z:null})
{ "_id" : ObjectId("63fedb6ae658b76ec2b3d9f1"), "name" : "test" }
{ "_id" : ObjectId("63fee0eab09131f29d9a4ace"), "sdsd" : 12 }
{ "_id" : ObjectId("63fee0f7b09131f29d9a4acf"), "sdsd" : 12 }
{ "_id" : ObjectId("63fee113b09131f29d9a4ad0"), "sdsd" : 12 }
{ "_id" : ObjectId("63fee118b09131f29d9a4ad1"), "sdsd" : 12 }
{ "_id" : ObjectId("63fee241b09131f29d9a4ad2"), "name" : undefined }
{ "_id" : ObjectId("63fee281b09131f29d9a4ad3"), "name" : undefined }
{ "_id" : ObjectId("63fee2d0b09131f29d9a4ad4"), "name" : undefined }
{ "_id" : ObjectId("67af62c2cebb0af2ca2a680e"), "x" : 1 }
{ "_id" : ObjectId("67af62cecebb0af2ca2a680f"), "x" : 2, "z" : null }
> db.test.createIndex({z:1},{sparse:true})
> db.test.find({z:null}).hint({"z":1})
{ "_id" : ObjectId("67af62cecebb0af2ca2a680f"), "x" : 2, "z" : null }

文本索引

mongodb支持文本检索功能,可通过建立文本索引来实现简易的分词检索。不过该功能目前支持英文分词,并未提供中文分词的功能。

> db.systemlog.insert({title:"the monkey's hair",summary:"the story about monkey"})
WriteResult({ "nInserted" : 1 })
> db.systemlog.insert({title:"two stars",summary:"long long hair in the sky"})        
WriteResult({ "nInserted" : 1 })
> db.store.find()
{ "_id" : ObjectId("67ab829c2cee149b47c1e30e"), "location" : { "type" : "Point", "coordinates" : [ -122.158574, 37.449157 ] } }
> db.systemlog.find()                                                         
{ "_id" : ObjectId("67af661ccebb0af2ca2a6810"), "title" : "the monkey's hair", "summary" : "the story about monkey" }
{ "_id" : ObjectId("67af663dcebb0af2ca2a6811"), "title" : "two stars", "summary" : "long long hair in the sky" }
> db.systemlog.createIndex({title:"text",summary:"text"})
{"createdCollectionAutomatically" : false,"numIndexesBefore" : 2,"numIndexesAfter" : 3,"ok" : 1
}
> db.systemlog.find({$text:{$search:"monkey sky"}})//会检索出含有monkey或sky关键词的文档
{ "_id" : ObjectId("67af661ccebb0af2ca2a6810"), "title" : "the monkey's hair", "summary" : "the story about monkey" }
{ "_id" : ObjectId("67af663dcebb0af2ca2a6811"), "title" : "two stars", "summary" : "long long hair in the sky" }
> db.systemlog.find({$text:{$search:"sky"}})       
{ "_id" : ObjectId("67af663dcebb0af2ca2a6811"), "title" : "two stars", "summary" : "long long hair in the sky" }
> db.systemlog.find({$text:{$search:"stars"}})
{ "_id" : ObjectId("67af663dcebb0af2ca2a6811"), "title" : "two stars", "summary" : "long long hair in the sky" }
>

$text操作符会将search文本进行分词再检索。

模糊索引

模糊索引可以建立再一些不可预知的字段上,一次实现查询的加速。该功能是mongodb4.2版本才推出的新特性。

db.goods.insert({name:"wallet",attributes:{color:"red"}})
db.good.insert({name:"chair",attributes:{height:120}})

其中,attributes作为嵌套文档存放了商品的多个属性,而不同商品所具有的属性可能是不一样的。接下来创建一个模糊索引:

db.goods.createIndex({"attributes.$**":1})

attributes.$**表示该索引将匹配以attributes字段作为开始路径的任何一个字段。

使用explain命令验证优化(查询计划)

db.systemlog.find({$text:{$search:"monkey sky"}}).explain("executionStats")

通过该命令我们可以验证下加了索引前后的查询差异。

如果有多个索引可以同时匹配当前的查询条件,那么mongodb就会在它们之中做出选择。又或者,整个查询过程并没有索引的介入而执行了全表扫描。
一个查询具体如何被执行的过程称为查询计划。通过explain命令我们可以清楚地看到查询计划地许多细节。这包括我们关心地一些问题:

  • 查询是否使用了索引。
  • 索引命中地情况是不是最佳的。
  • 查询是否需要扫描大量的记录。

explain命令除提供查询计划的信息外,还可以模拟计划的执行并提供更多的过程信息。总的来说,explain有3种执行模式。

  • queryPlanner:默认的模式,仅进行查询计划分析,输出计划种的阶段信息。
  • executionStats:执行模式,在查询计划分析后,将按照winningPlan执行查询并统计过程信息。
  • allPlansExecution:全计划执行模式,将执行所有计划(包括winningPlan和rejectPlans),并返回全部的过程统计信息。

合理使用索引

通过上面的知识,我们知道了mongodb所支持的各种索引分类以及基本操作。然而,仅有这些可能还不够,在日常开发中,或许经常会遇到这样的问题:

  • 什么时候应该使用索引
  • 怎么创建索引才是最高效的,有没有可遵循的一些原则
  • 索引是怎么提升性能的,是不是索引越多越好呢

索引检索原理

  1. 全表扫描带来的问题
    在没有任何索引辅助的情况下,数据库查找数据只能通过遍历所有文档,并逐一过滤,直到数据查找完成。全表扫描是线性查找的方式,其时间复杂度为O(n)。尤其是遇到数据量大的时候,一个查询可能要花费几十秒甚至几分钟的时间,除此之外,在其整个扫描过程中,还会加载大量的磁盘数据到内存中,导致mongodb用于提供快速查询的“热数据缓存”被大量换出,进而又影响整体的性能以及稳定性。

  2. B+树索引
    既然全表扫描的问题在于扫描的条目太多,那么索引的优化就在于如何缩短检索数据所需要经历的路径。从mongodb3.2版本开始,其采用了wiredTiger作为默认的引擎,在索引和集合的检索上则借鉴了B+树的结构。B+树索引是一个m阶平衡树的结构,其查询复杂度是O(logm n),其中,m是节点最大的分支数量,n是总体的节点数。以1亿的表为例,转换为平衡树结构(m阶)之后,假设m=10,那么整个树只有8层,一次检索只需经过8次节点扫描就可以完成。

  3. 二级索引
    二级索引也叫非聚簇索引,另一个相对的概念叫做聚簇索引,这两者的区别如下:

    • 聚簇索引的叶子节点存储了正真的数据记录。
    • 二级索引的叶子节点仅仅存放了索引值以及指向数据记录的指针或主键。

因此,二级索引在检索数据的过程中往往需要更多的查找次数,其中第二次查找真正数据记录的过程中常常被称为“回表”。在mongodb集合中,除了_id外的其他索引都是二级索引。

覆盖索引

覆盖索引指的是一种查询优化的行为。在一棵二级索引的B+树上,索引的值存在于叶子节点。因此,如果希望查询的字段被包含在索引中,则直接查找二级索引树就可以获得,而不需要再次通过_id索引查找出原始的文档。相比“非覆盖式”的查找,覆盖索引的这种行为可以减少一次对最终文档数据的检索操作(回表)。大部分情况下,二级索引树常驻在内存中,覆盖式的查询可以保证一次检索行为仅仅发生在内存中,既避免了对磁盘的I/O的操作。

> db.test.find({name:/as/},{name:1,_id:0})
{ "name" : "as9238Ji" }
> db.test.find({name:/as/},{name:1,_id:0}).explain()//_id:0是必须提供的,否则数据库会将_id字段也一起返回,这样会导致使用覆盖索引行为失效。
{"queryPlanner" : {"plannerVersion" : 1,"namespace" : "test.test","indexFilterSet" : false,"parsedQuery" : {"name" : {"$regex" : "as"}},"winningPlan" : {"stage" : "PROJECTION","transformBy" : {"name" : 1,"_id" : 0},"inputStage" : {"stage" : "IXSCAN","filter" : {"name" : {"$regex" : "as"}},"keyPattern" : {"name" : 1},"indexName" : "name_1","isMultiKey" : false,"multiKeyPaths" : {"name" : [ ]},"isUnique" : false,"isSparse" : true,"isPartial" : false,"indexVersion" : 2,"direction" : "forward","indexBounds" : {"name" : ["[\"\", {})","[/as/, /as/]"]}}},"rejectedPlans" : [ ]},"serverInfo" : {"host" : "DESKTOP-5433197","port" : 27017,"version" : "4.0.14-rc1","gitVersion" : "1622021384533dade8b3c89ed3ecd80e1142c132"},"ok" : 1
}
> db.test.find({name:/as/},{name:1}).explain()      
{"queryPlanner" : {"plannerVersion" : 1,"namespace" : "test.test","indexFilterSet" : false,"parsedQuery" : {"name" : {"$regex" : "as"}},"winningPlan" : {"stage" : "PROJECTION","transformBy" : {"name" : 1},"inputStage" : {"stage" : "FETCH","inputStage" : {"stage" : "IXSCAN","filter" : {"name" : {"$regex" : "as"}},"keyPattern" : {"name" : 1},"indexName" : "name_1","isMultiKey" : false,"multiKeyPaths" : {"name" : [ ]},"isUnique" : false,"isSparse" : true,"isPartial" : false,"indexVersion" : 2,"direction" : "forward","indexBounds" : {"name" : ["[\"\", {})","[/as/, /as/]"]}}}},"rejectedPlans" : [ ]},"serverInfo" : {"host" : "DESKTOP-5433197","port" : 27017,"version" : "4.0.14-rc1","gitVersion" : "1622021384533dade8b3c89ed3ecd80e1142c132"},"ok" : 1
}
>

我们可以对比二者查询的查询计划,使用覆盖索引并不存在FETCH阶段。
最终,在使用覆盖索引是需要记住下面两点:

  • 覆盖索引的前提是二级索引,并且检索条件,返回字段都必须严格被索引覆盖到
  • 对于嵌套的数组字段,无法使用覆盖索引查询。

强制命中

  • 使用hint方法
    hint方法实现了对查询计划机制的干预,在查询计划中使用hint语句可以让mongodb忽略查询优化器的结果,从而直接使用指定的索引。
    比如下面这种做法:

    db.test.find().hint({name:1}) //强制使用{name:1}这个索引。
    db.test.find().hint("name_1") //可以传入索引的定义对象,也可以是索引的名称。
    
  • 使用IndexFilter方法

    db.runCommand({planCacheSetFilter:"test",query:{a:3,b:4},indexs:[{b:1}]})
    

    执行planCacheSetFilter命令会在test集合中增加了一个IndexFilter对象,该对象将会自动关联到同时包含a字段和b字段的等值查询,并引导查询优化器使用{b:1}这个索引。
    其中,查询模型会忽略查询条件中具体的数值,因此下面的查询时适用的:

    db.test.find({a:99,b:-1})
    

    但是,如果使用了非等值查询(如ge、lt),或者排序(sort)、投射(projection)发生了变化,就会导致匹配失效。
    indexFilter时内存台的,如果重启了mongodb,则会自动失效。另外,可以使用planCacheClearFilters进行擦除,代码如下:

    db.runCommand({planCacheClearFilters:"test"})
    

indexFilter方法优先级高于hint,如果查询优化器发现了关联的indexFilter,则一定会忽略hint语句。但是,indexFilter并不能保证查询优化器最终一定会选择对应的索引,事实上优化器会将这些索引于全表扫描一并进行评估,再抉择出最终的结果。在最坏的情况下,如果我们指定了不存在的索引,就会导致全表扫描。

注意:mongodb的查询优化器已经足够强大,无论是hint方法还是indexfilter,都会改变默认的查询优化行为,尽量少用。

优化原则

  1. 在适当的时机使用索引
    索引的作用在于提高查询效率。当返回结果集只是全部文档的一小部分时,增加合适的索引才能获得不错的性价比。
  2. 使用前缀匹配

相关文章:

MongoDB索引介绍

索引简述 索引是什么 索引在数据库技术体系中占据了非常重要的位置,其主要表现为一种目录式的数据结构,用来实现快速的数据查询。通常在实现上,索引是对数据库表(集合)中的某些字段进行抽取、排列之后,形成的一种非常易于遍历读取…...

编程速递-庆祝Delphi诞生30周年!

庆祝Delphi 30周年纪念是一个特别的时刻。 回到1995年,也就是30年前,在微软Windows和互联网时代的曙光初现之时,Borland Delphi的创建者们无法想象,当时使用Borland Delphi构建的应用程序至今仍在运行——为全世界数十亿人服务。…...

YOLOv11-ultralytics-8.3.67部分代码阅读笔记-tuner.py

tuner.py ultralytics\utils\tuner.py 目录 tuner.py 1.所需的库和模块 2.def run_ray_tune(model, space: dict None, grace_period: int 10, gpu_per_trial: int None, max_samples: int 10, **train_args,): 1.所需的库和模块 # Ultralytics 🚀 AGPL-…...

一文说清楚什么是Token以及项目中使用Token延伸的问题

首先可以参考我的往期文章,我这里说清楚了Cookie,Seesion,Token以及JWT是什么 其实Token你就可以理解成这是一个认证令牌就好了 详细分清Session,Cookie和Token之间的区别,以及JWT是什么东西_还分不清 cookie、sessi…...

VueRouter 实例

分析下列代码 const router new VueRouter({mode:history,routes }) 1.const router new VueRouter({ ... })用来创建一个 Vue Router 实例,用于管理 Vue.js 应用的路由。2.mode: history: 作用:启用 HTML5 History 模式,去除…...

【算法工程】解决linux下Aspose.slides提示No usable version of libssl found以及强化推理模型的短板

1. 背景 构建ubuntu镜像,然后使用Aspose.slides解析PPTX文档,发现一直提示“No usable version of libssl found”。 2. 尝试 使用deepseek R1、kimi1.5、chatgpt o3,并且都带上联网能力,居然还是没有一个能够真正解决&#xf…...

解析浏览器中JavaScript与Native交互原理:以WebGPU为例

引言 随着Web应用复杂度的提升,开发者对浏览器访问本地硬件能力的需求日益增长。然而,浏览器必须在开放性与安全性之间找到平衡——既不能放任JavaScript(JS)随意操作系统资源,又要为高性能计算、图形渲染等场景提供支…...

小火车理论

格助词...

深度学习框架探秘|Keras 应用案例解析以及 Keras vs TensorFlow vs PyTorch

引言 上一篇文章《深度学习框架探秘|Keras:深度学习的魔法钥匙》 我们初步学习了 Keras,包括它是什么、具备哪些优势(简洁易用的 API、强大的兼容性、广泛的应用领域),以及基本使用方法。本文,…...

【01 背包】

01 背包解题思路: 有n件物品和一个最多能背重量为w 的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。每件物品只能用一次,求解将哪些物品装入背包里物品价值总和最大。 这是标准的背包问题,每一件物品其实只有两个状…...

算法10-二分查找算法

一、二分查找算法概念 二分查找(Binary Search)是一种高效的查找算法,适用于在有序数组中快速查找目标值。它的核心思想是通过不断缩小查找范围,将时间复杂度从线性查找的 O(n) 优化到 O(log n)。 二、二分查找的流程图 以下是二…...

变相提高大模型上下文长度-RAG文档压缩-3.优化map-reduce(reranker过滤+社区聚类)

我遇到的业务问题实际上是RAG需要处理很多同一对象的日常报告,不像常识类问题,它的相关Document更多而且更分散,日常报告代表数据库里有很多它的内容,而且对象可能只在段落中的几句话提及到。top-k数量受限于大模型长度&#xff0…...

算法11-分治算法

一、分治算法概念 分治算法(Divide and Conquer)是一种重要的算法设计思想,通过将问题分解为多个子问题,分别解决后再合并结果,从而解决原问题。分治算法的核心思想是“分而治之”,通常包含三个步骤&#…...

Golang internals

To be continued... time.Time golang的时区和神奇的time.Parse context.Context Go Context的踩坑经历 sync.Pool sync.Pool workflow in Go 1.12 new shared pools in Go 1.13 什么是cpu cache理解 Go 1.13 中 sync.Pool 的设计与实现Go: Understand the Design of Sync.Pool…...

Flask中获取请求参数的一些方式总结

在 Flask 中,可以从 request 对象中获取各种类型的参数。以下是全面整理的获取参数的方式及示例代码。 1. 获取 URL 查询参数(Query String Parameters) URL 中的查询参数通过 ?keyvalue&key2value2 的形式传递,使用 reques…...

vscode/cursor 写注释时候出现框框解决办法

一、问题描述 用vscode/cursor写注释出现如图的框框,看着十分难受,用pycharm就没有 二、解决办法 以下两种,哪个好用改那个 (1)Unicode Highlight:Ambiguous Characters Unicode Highlight:Ambiguous Characters &a…...

11-跳跃游戏

给你一个非负整数数组 nums ,你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标,如果可以,返回 true ;否则,返回 false 。 贪心算法思路分析 在遍…...

TestHubo基础教程-创建项目

TestHubo是一款国产开源一站式测试工具,涵盖功能测试、接口测试、性能测试,以及 Web 和 App 测试,可以满足不同类型项目的测试需求。本文将介绍如何快速创建第一个项目,以快速入门上手。 1、创建项目 在 TestHubo 中,…...

GHOST重装后DEF盘丢失的全面解析与数据恢复实战指南

GHOST作为一款经典的系统备份与还原工具,因其高效便捷的特性被广泛应用于系统重装和数据恢复场景。然而,许多用户在使用GHOST重装系统后,发现DEF盘(即D盘、E盘、F盘等非系统盘)突然丢失,导致重要数据无法访…...

soular基础教程-使用指南

soular是TikLab DevOps工具链的统一帐号中心,今天来介绍如何使用 soular 配置你的组织、工作台,快速入门上手。  1. 账号管理 可以对账号信息进行多方面管理,包括分配不同的部门、用户组等,从而确保账号权限和职责…...

刷题记录(回顾)HOT100 二叉树-10: ​199. 二叉树的右视图

题目:199. 二叉树的右视图 难度:中等 给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。 有效 二叉搜索树定义如下: 节点的左 子树 只包含 小于 当前节点的数。节点的右子树只包含 大于 当前节点的数。所有左…...

【Java学习】类和对象

目录 一、选择取块解 二、类变量 三、似复刻变量 四、类变量的指向对象 五、变量的解引用访问 1.new 类变量(参) 2.this(参) 3.类变量/似复刻变量. 六、代码块 七、复制变量的赋值顺序 八、访问限定符 1.private 2.default 九、导类 一、选择取块解 解引用都有可以…...

安卓基础(Adapter)

想象一下,你有一堆玩具(数据),这些玩具很特别,每个玩具都是不同的,可能有汽车、飞机、积木等。现在,你想把这些玩具摆放到一个展示柜(显示的界面)里,给大家看…...

mybatis-lombok工具包介绍

Lombok是一个实用的]ava类库,能通过注解的形式自动生成构造器、getter/setter、equals、hashcode、toString等方法,并可以自动化生成日志变量,简化java开发、提高效率。 使用前要加入Lombok依赖...

React - 高阶函数-函数柯里化

在 JavaScript 和 React 中,高阶函数是指能够接收其它函数作为参数,或者返回一个函数的函数。柯里化是一种将函数的多个参数转化为一系列嵌套函数的技术,通常用于简化函数的使用和提高其可组合性。 使用前: import React,{Compo…...

数据守护者:备份文件的重要性及自动化备份实践

在信息化社会,数据已成为企业运营和个人生活的重要组成部分。无论是企业的核心业务数据,还是个人的珍贵照片、重要文档,数据的丢失或损坏都可能带来无法估量的损失。因此,备份文件的重要性愈发凸显,它不仅是数据安全的…...

【kafka系列】消费者重平衡

目录 流程 1. 消费者组重平衡(Rebalance)的流程逻辑分析 阶段一:触发重平衡 阶段二:消费者组协调 阶段三:重平衡完成 关键设计思想 2. Mermaid 流程代码 关键点总结 重平衡的影响 1. 重平衡期间的消费行为 2…...

光谱相机在天文学领域的应用

天体成分分析 恒星成分研究:恒星的光谱包含了其大气中各种元素的吸收和发射线特征。通过光谱相机精确测量这些谱线,天文学家能确定恒星大气中氢、氦、碳、氮、氧等元素的含量。如对太阳的光谱分析发现,太阳大气中氢元素占比约 71%&#xff0…...

Java 基于 SpringBoot+Vue 的家政服务管理平台设计与实现

博主介绍:✌程序员徐师兄、8年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战*✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅&#x1f447…...

ABC393E/F简要题解

ABC393E 给定数组 A A A,求包含元素 A i A_i Ai​的大小为 k k k的子集中最大的最大公约数。 题解: 首先思考对于整个数组所有包含 k k k个元素的子集中最大的GCD是多少,可以怎么求。 我们发现,如果一个数 x x x,数组中如果存在至少 k k …...

什么是Mustache

Mustache 是一种轻量级模板引擎,用于将变量插入到模板中生成最终的文本输出。它的设计简单且易于使用,适用于多种编程语言,包括 JavaScript、Python、Ruby、Java 等。 Mustache 的模板语法使用双大括号 {{}} 包裹变量或表达式,用…...

GGUF格式的DeepSeek-R1-Distill-Qwen-1.5B模型的字段解析

在将GGUF文件转换为PyTorch格式之前,先要读取文件并了解模型中都有什么字段,会遇到了各种参数不匹配的问题。现在,我们先读取GGUF文件的元数据字段,并希望将这些字段中的内存映射(mmap)数据转换为字符串显示…...

Java和SQL测试、性能监控中常用工具

下面我会详细列举一些在Java和SQL测试、调试、性能监控中常用的工具,并结合项目中提到的各个技术点说明如何选择合适的工具和方法。 一、Java项目常用的测试、调试与性能监控工具 单元测试与集成测试: JUnit/TestNG: 用于编写单元测试和集成测…...

CAS单点登录(第7版)13.票务

如有疑问,请看视频:CAS单点登录(第7版) 票务 概述 票务 有两个核心的可配置工单组件: TicketRegistry - 提供持久票证存储。ExpirationPolicy - 提供票证过期语义的策略框架。 工单注册 部署环境和技术专业知识…...

大语言模型入门

大语言模型入门 1 大语言模型步骤1.1 pre-training 预训练1.1.1 从网上爬数据1.1.2 tokenization1.1.2.1 tokenization using byte pair encoding 1.3 预训练1.3.1 context1.3.2 training1.3.3 输出 1.2 post-training1.2.1 token 1.2 SFT监督微调1.3 人类反馈强化学习1.3.1 人…...

从ARM官方获取自己想要的gcc交叉编译工具链接(Arm GNU Toolchain),并在Ubuntu系统中进行配置

前言 本文是博文 https://blog.csdn.net/wenhao_ir/article/details/145547974 的分支博文。 在本博文中我们完成gcc交叉编译工具gcc-arm-9.2-2019.12-x86_64-arm-none-linux-gnueabihf.tar.xz的下载、配置、测试。 下载自己想要的gcc交叉编译工具的源码 目标文件的名字及说…...

LDR6500:重塑充电与数据传输的新篇章

在当今快速发展的数字时代,电子设备对充电速度、数据传输效率和兼容性提出了更高要求。LDR6500,作为一款专为USB Type-C Bridge设备设计的USB-C DRP(Dual Role Port,双角色端口)接口USB PD(Power Delivery&…...

Matlab 机器人 雅可比矩阵

工业机器人运动学与Matlab正逆解算法学习笔记(用心总结一文全会)(四)——雅可比矩阵_staubli机器人正逆向运动学实例验证matlab-CSDN博客 matlab求雅可比矩阵_六轴机械臂 矢量积法求解雅可比矩阵-CSDN博客 (63 封私信 / 80 条消息…...

网络安全防护:开源WAF雷池SafeLine本地部署与配置全流程

文章目录 前言1.关于SafeLine2.安装Docker3.本地部署SafeLine4.使用SafeLine5.cpolar内网穿透工具安装6.创建远程连接公网地址7.固定Uptime Kuma公网地址 前言 对于建站新手来说,无论你选择创建的是个人博客、企业官网还是各类应用平台来推广自己的内容或是产品&am…...

vue框架生命周期详细解析

Vue.js 的生命周期钩子函数是理解 Vue 组件行为的关键。每个 Vue 实例在创建、更新和销毁过程中都会经历一系列的生命周期阶段,每个阶段都有对应的钩子函数,开发者可以在这些钩子函数中执行特定的操作。 Vue 生命周期概述 Vue 的生命周期可以分为以下几…...

Ollama 安装使用指南

rootdeepseek-1:/home/zgq/.ollama# lsof -i :11434 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME ollama 29005 root 3u IPv4 47359 0t0 TCP localhost:11434 (LISTEN) 从以上提供的 lsof 输出来看,Ollama 服务正在监听 localhost:11434…...

力扣 38. 外观数列 打表 迭代 阅读理解

Problem: 38. 外观数列 &#x1f9d1;‍&#x1f3eb; 参考题目补充说明 &#x1f9d1;‍&#x1f3eb; 参考题解 迭代法 class Solution {public String countAndSay(int n) {String str "1";for (int i 2; i < n; i) {StringBuilder sb new StringBuild…...

文心一言4月起全面免费,6月底开源新模型:AI竞争进入新阶段?

名人说&#xff1a;莫听穿林打叶声&#xff0c;何妨吟啸且徐行。—— 苏轼 Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 目录 一、文心一言免费化的背后&#xff1a;AI成本与应用的双重驱动1️⃣成本下降&#xff0c;推动文心一言普及2…...

基于LSTM+前向均值滤波后处理的癫痫发作检测(包含数据集)

引言 癫痫是一种常见的神经系统疾病&#xff0c;患者会经历反复的癫痫发作。早期检测和预警对于改善患者的生活质量至关重要。近年来&#xff0c;深度学习技术&#xff0c;尤其是长短期记忆网络&#xff08;LSTM&#xff09;&#xff0c;在时间序列数据分析中表现出色&#xf…...

Window下Redis的安装和部署详细图文教程(Redis的安装和可视化工具的使用)

文章目录 Redis下载地址&#xff1a;一、zip压缩包方式下载安装 1、下载Redis压缩包2、解压到文件夹3、启动Redis服务4、打开Redis客户端进行连接5、使用一些基础操作来测试 二、msi安装包方式下载安装 1、下载Redis安装包2、进行安装3、进行配置4、启动服务5、测试能否正常工…...

什么是交叉熵

交叉熵 定义公式 针对离散变量x的概率分布 p ( x ) p(x) p(x) , q ( x ) q(x) q(x) x 1 x_1 x1​ x 2 x_2 x2​ x 3 x_3 x3​ x 4 x_4 x4​… x n x_n xn​p( x 1 x_1 x1​)p( x 2 x_2 x2​)p( x 3 x_3 x3​)p( x 4 x_4 x4​)…p( x n x_n xn​)q( x 1 x_1 x1​)q( x 2 x_2 …...

虚拟机安装k8s集群

环境准备 - 主节点&#xff08;Master Node&#xff09;: IP地址: 192.168.40.100主机名: k8s-master - 工作节点&#xff08;Worker Node&#xff09;: IP地址: 192.168.40.101主机名: k8s-node1 步骤 1: 配置虚拟机环境 1.1 设置主机名 在每台虚拟机上设置唯一的主机名…...

【mysql部署】在ubuntu22.04上安装和配置mysql教程

一.安装mysql 1. 更新软件包列表: sudo apt-get update2.安装 MySQL 服务器&#xff1a; sudo apt-get install mysql-server3.设置 MySQL 安全性&#xff1a; sudo mysql_secure_installation按照提示输入相关问题的回答&#xff0c;例如删除匿名用户、禁止 root 远程登录…...

机器学习实战(3):线性回归——预测连续变量

第3集&#xff1a;线性回归——预测连续变量 在机器学习的世界中&#xff0c;线性回归是最基础、最直观的算法之一。它用于解决回归问题&#xff0c;即预测连续变量&#xff08;如房价、销售额等&#xff09;。尽管简单&#xff0c;但线性回归却是许多复杂模型的基石。今天我们…...

烧结银在 DeepSeek 中的关键作用与应用前景

烧结银在 DeepSeek 中的关键作用与应用前景 在科技飞速发展的当下&#xff0c;DeepSeek 作为前沿科技领域的重要参与者&#xff0c;正以其独特的技术和创新的应用&#xff0c;在众多行业掀起变革的浪潮。而在 DeepSeek 的核心技术体系中&#xff0c;烧结银这一材料的应用&#…...