【Go】-倒排索引的简单实现
目录
什么是倒排索引
定义
基本结构和原理
分词在倒排索引中的重要性
简单倒排索引的实现
接口定义
简单数据库的实现
倒排索引
正排索引
测试
总结
什么是倒排索引
定义
-
倒排索引(Inverted Index)是一种索引数据结构,它是文档检索系统中最常用的数据结构之一。在信息检索领域,它用于快速地定位包含给定查询词的文档。与正向索引(Forward Index)相对,正向索引是从文档到词汇的映射,而倒排索引是从词汇到文档的映射。
基本结构和原理
-
倒排索引主要由两部分组成:词汇表(Vocabulary)和倒排记录表(Postings List)。
-
词汇表:包含了文档集合中出现的所有不同的词汇(或词条)。每个词汇都有一个指向其对应的倒排记录表的指针。例如,在一个包含多篇新闻文章的文档集合中,词汇表可能包含 “经济”“政治”“科技” 等词汇。
-
倒排记录表:对于词汇表中的每个词汇,倒排记录表记录了包含该词汇的所有文档的标识符(Document ID)以及可能的其他相关信息,如词汇在文档中的位置、出现的频率等。比如,对于词汇 “科技”,其倒排记录表可能包含文档 ID 为 1、3、5 的记录,表示这三篇文档中都出现了 “科技” 这个词汇。
-
假如现在有三份数据文档,内容分别是:
Doc 1:Java is the best programming languageDoc 2:PHP is the best programming languageDoc 3:Javascript is the best programming language为了创建索引,通过分词器将每个文档的内容拆成单独的词,再将这些词条创建成不含重复词条的排序列表,然后列出每个词条出现在哪个文档,结果如下:
term Doc 1 Doc 2 Doc 3 Java √ is √ √ √ the √ √ √ best √ √ √ programming √ √ √ language √ √ √ PHP √ √ Javascript √ √ 这种结构由文档中所有不重复的词的列表构成,对于其中每个词都有至少一个文档与与之关联。这种由属性值来确定记录的位置的结构就是倒排索引,带有倒排索引的文件被称为倒排文件。
将上表转为更直观的图片来展示倒排索引:

-
分词在倒排索引中的重要性
-
建立索引基础:倒排索引是一种用于快速检索的数据结构。它的核心是将文档中的关键词提取出来,建立关键词到文档的映射关系。分词就是这个提取关键词的过程,只有通过分词,才能将文本内容分解为一个个有意义的词汇单元,为建立倒排索引提供基础。例如,对于一篇文档 “我爱自然语言处理技术”,如果不分词,这个文档就会被当作一个整体,很难进行有效的关键词检索;而通过分词得到 “我”“爱”“自然语言处理”“技术” 这些词汇后,就可以分别建立它们与该文档的索引关系。
-
提高检索效率和准确性:当用户进行查询时,倒排索引会根据用户输入的关键词来查找相关文档。精确的分词可以确保查询词和索引中的词汇准确匹配,提高检索的准确性。例如,在搜索引擎中,如果用户输入 “自然语言处理”,经过良好分词的倒排索引能够快速定位到包含这个词汇的文档,而不会因为没有正确分词而错过相关文档。同时,合理的分词还可以减少索引的大小,提高检索效率。如果将一些无意义的组合词也作为索引词,会增加索引的复杂度和存储量,而通过分词去除不必要的组合,只保留有意义的词汇,可以使索引更加紧凑,检索速度更快。
中文分词面临的挑战:
-
词汇的复杂性
-
词的歧义性:中文中存在大量的歧义现象。例如 “下雨天留客天留我不留”,不同的断句(分词)方式会产生不同的意思。可以是 “下雨天,留客天,留我不?留。” 也可以是 “下雨天留客,天留,我不留。” 这种歧义给中文分词带来了很大的困难。
-
新词不断涌现:随着社会的发展和科技的进步,新的词汇不断出现,如 “区块链”“人工智能”“元宇宙” 等。对于分词系统来说,需要及时识别这些新词,才能保证分词的准确性和完整性。
-
-
缺乏明显的分隔符:与英文等语言不同,中文句子中词与词之间没有明显的分隔符(如英文中的空格)。这使得计算机很难直观地判断一个词的起始和结束位置,需要通过复杂的算法和规则来进行分词。
-
语言的灵活性和多样性:中文有丰富的表达方式,包括成语、俗语、古诗词等。这些特殊的语言形式也给分词带来了挑战。例如,成语 “胸有成竹” 如果被错误地分割为 “胸有”“成竹”,就会失去原有的语义,影响分词的质量。
常用的中文分词库
-
jieba 分词库
-
特点:jieba 是一个非常流行的中文分词库,它具有多种分词模式,包括精确模式、全模式和搜索引擎模式。精确模式试图将句子最精确地切开,适合文本分析等场景;全模式把句子中所有的可以成词的词语都扫描出来,速度快但可能会产生冗余;搜索引擎模式在精确模式的基础上,对长词再次切分,提高搜索引擎召回率。例如,对于句子 “中华人民共和国”,精确模式会分为 “中华人民共和国”,全模式会分为 “中华”“华人”“人民”“共和”“共和国” 等,搜索引擎模式会在精确模式的基础上对 “中华人民共和国” 进一步切分,以适应搜索引擎的需求。
-
应用场景:广泛应用于文本挖掘、信息检索、机器翻译等领域。例如,在文本挖掘中,可以使用 jieba 对文本进行分词,然后进行词频统计等分析。
-
-
THULAC(清华大学自然语言处理与社会人文计算实验室)
-
特点:它是由清华大学开发的中文词法分析工具包,具有较高的分词准确性。它提供了词性标注等功能,不仅可以分词,还可以标注每个词的词性,如名词、动词、形容词等。例如,对于句子 “他高兴地跑了”,除了将句子分为 “他”“高兴”“地”“跑”“了”,还可以标注出 “他” 是代词,“高兴” 是形容词,“地” 是助词,“跑” 是动词,“了” 是语气词。
-
应用场景:在自然语言处理研究和需要词性标注的应用场景中使用较多,如情感分析中,结合词性标注可以更好地分析句子的情感倾向。
-
简单倒排索引的实现
接口定义
定义三个接口,分别是 数据库,正排索引,倒排索引;规定都要实现Get和Add功能
// DB接口定义了数据库的基本操作,用于获取和添加数据。type DB interface {Get(string) []stringAdd(string)}// ForwardIndexer 用于根据给定的文档ID列表获取对应的原始字符串内容。type ForwardIndexer interface {Get([]int64) []stringAdd(int64, string)}// InvertedIndexer 用于根据给定的字符串获取对应的文档ID列表以及添加倒排索引数据。type InvertedIndexer interface {Get(string) []int64Add(string, int64)}
简单数据库的实现
定义简单数据库结构体,由id,正排索引和倒排索引组成。
Get方法是先通过倒排索引由字符串找出id,然后在通过正排索引由id找出匹配的字符串
Add方法把字符串存入倒排和正排
// SimpleDatabase结构体实现了DB接口,内部整合了正向索引和倒排索引来管理数据。type SimpleDatabase struct {id int64fi ForwardIndexerii InvertedIndexer}// NewSimpleDatabase创建一个新的SimpleDatabase实例,初始化其正向索引和倒排索引相关组件。func NewSimpleDatabase() DB {return &SimpleDatabase{id: 0, // 递增文档IDfi: NewForwardIndex(),ii: NewSimpleInverted(),}}func (sd *SimpleDatabase) Get(s string) []string {// 先通过倒排索引根据输入字符串获取对应的文档ID列表ids := sd.ii.Get(s)// 再通过正排索引根据获取到的文档ID列表查找对应的原字符串return sd.fi.Get(ids)}func (sd *SimpleDatabase) Add(s string) {atomic.AddInt64(&sd.id, 1)id := sd.idaddToIndexes(sd.fi, sd.ii, id, s)}func addToIndexes(fi ForwardIndexer, ii InvertedIndexer, id int64, s string) {// 倒排存入ii.Add(s, id)// 正排存入fi.Add(id, s)}
倒排索引
倒排索引结构由读写锁,分词器和map组成
Get方法查找data返回id数组
Add先分词,然后把分词后的结构以及对应id存入map,ES中的分词器一般会大写转小写,但是这里我偷个懒就直接存了
// SimpleInverted结构体实现了InvertedIndexer接口,用于管理倒排索引数据。type SimpleInverted struct {sync.RWMutexdata map[string][]int64analyzer Analyzer}// NewSimpleInverted创建一个新的SimpleInverted实例,初始化倒排索引数据存储结构和分析器。func NewSimpleInverted() InvertedIndexer {return &SimpleInverted{data: make(map[string][]int64),analyzer: NewSimpleAnalyzer(),}}func (si *SimpleInverted) Get(s string) []int64 {si.RLock()result := si.data[s]si.RUnlock()return result}func (si *SimpleInverted) Add(s string, id int64) {words := si.analyzer.Analyze(s)si.Lock()for _, word := range words {si.data[word] = append(si.data[word], id)}si.Unlock()}
分词器
这里分词器的实现比较简单,直接逐个拆开来存了,在实际中分词器比这更加复杂和优雅,往往伴随着一些分词的算法
这里用使用了两层嵌套的 for 循环来生成输入字符串的所有可能子串,并将这些子串作为键存入一个 map 类型的变量 word 中。外层循环控制起始位置 i,内层循环控制结束位置 j,通过切片操作 su[i:j] 取出从位置 i 到位置 j(不包含 j)的子串,然后将其转换为字符串作为 map 的键,对应的值使用了空结构体 struct{}{}。
这样做虽然能实现分词,但是非常暴力而且浪费空间。因为中文分词不像英文,可以使用空格或者,进行简单切分,一般的中文分词器都会采用词典分词,因为我们是简单实现,所以这里就采用了这种暴力写法(其实是太菜了不会更好的分词方法)
// Analyzer接口定义了文本分析(例如分词等操作)的基本操作方法。type Analyzer interface {Analyze(s string) []string}// SimpleAnalyzer结构体实现了Analyzer接口,简单地进行字符串分析(示例中较简单的逻辑,可优化)。type SimpleAnalyzer struct{}// NewSimpleAnalyzer创建一个新的SimpleAnalyzer实例。func NewSimpleAnalyzer() Analyzer {return &SimpleAnalyzer{}}func (l *SimpleAnalyzer) Analyze(s string) (re []string) {// 转为rune可以有效处理中英文字符的字节大小问题su := []rune(s)sl := len(su)word := make(map[string]struct{})for i := 0; i < sl; i++ {for j := i + 1; j <= sl; j++ {word[string(su[i:j])] = struct{}{}}}re = make([]string, len(word))num := 0for index := range word {re[num] = indexnum++}return}
正排索引
这个比起倒排简单很多,没啥好讲的
// forwardIndex结构体实现了ForwardIndexer接口,用于管理正向索引数据。type forwardIndex struct {sync.RWMutexdata map[int64]string}// NewForwardIndex创建一个新的forwardIndex实例,初始化正向索引数据存储结构。func NewForwardIndex() ForwardIndexer {return &forwardIndex{data: make(map[int64]string),}}func (fi *forwardIndex) Get(ids []int64) (re []string) {re = make([]string, len(ids))fi.RLock()for k, v := range ids {re[k] = fi.data[v]}fi.RUnlock()return}func (fi *forwardIndex) Add(id int64, s string) {fi.Lock()fi.data[id] = sfi.Unlock()}
测试
单元测试代码如下,一首《春江花月夜》来试试效果
func TestSimpleDatabaseWithChunJiangHuaYueYe(t *testing.T) {// 创建数据库实例db := NewSimpleDatabase()// 添加《春江花月夜》的诗句(假设逐句添加)lines := []string{"春江潮水连海平,海上明月共潮生。","江流宛转绕芳甸,月照花林皆似霰。","空里流霜不觉飞,汀上白沙看不见。","江天一色无纤尘,皎皎空中孤月轮。","江畔何人初见月?江月何年初照人?","人生代代无穷已,江月年年望相似。","不知江月待何人,但见长江送流水。","白云一片去悠悠,青枫浦上不胜愁。","谁家今夜扁舟子?何处相思明月楼?","可怜楼上月徘徊,应照离人妆镜台。","玉户帘中卷不去,捣衣砧上拂还来。","此时相望不相闻,愿逐月华流照君。","鸿雁长飞光不度,鱼龙潜跃水成文。","昨夜闲潭梦落花,可怜春半不还家。","江水流春去欲尽,江潭落月复西斜。","斜月沉沉藏海雾,碣石潇湘无限路。","不知乘月几人归,落月摇情满江树。",}for _, line := range lines {db.Add(line)}// 测试获取包含“江”字的字符串expectedJiang := []string{"春江潮水连海平,海上明月共潮生。","江流宛转绕芳甸,月照花林皆似霰。","江天一色无纤尘,皎皎空中孤月轮。","江畔何人初见月?江月何年初照人?","人生代代无穷已,江月年年望相似。","不知江月待何人,但见长江送流水。","江水流春去欲尽,江潭落月复西斜。","不知乘月几人归,落月摇情满江树。",}actualJiang := db.Get("江")if !reflect.DeepEqual(actualJiang, expectedJiang) {t.Errorf("Get for '江' failed. Expected: %v, Got: %v", expectedJiang, actualJiang)} else {fmt.Println("========江=========")for _, s := range actualJiang {fmt.Println(s)}}// 测试获取包含“月”字的字符串expectedYue := []string{"春江潮水连海平,海上明月共潮生。","江流宛转绕芳甸,月照花林皆似霰。","江天一色无纤尘,皎皎空中孤月轮。","江畔何人初见月?江月何年初照人?","人生代代无穷已,江月年年望相似。","不知江月待何人,但见长江送流水。","谁家今夜扁舟子?何处相思明月楼?","可怜楼上月徘徊,应照离人妆镜台。","此时相望不相闻,愿逐月华流照君。","江水流春去欲尽,江潭落月复西斜。","斜月沉沉藏海雾,碣石潇湘无限路。","不知乘月几人归,落月摇情满江树。",}actualYue := db.Get("月")if !reflect.DeepEqual(actualYue, expectedYue) {t.Errorf("Get for '月' failed. Expected: %v, Got: %v", expectedYue, actualYue)} else {fmt.Println("========月=========")for _, s := range actualYue {fmt.Println(s)}}// 测试获取包含“花”字的字符串expectedHua := []string{"江流宛转绕芳甸,月照花林皆似霰。","昨夜闲潭梦落花,可怜春半不还家。",}actualHua := db.Get("花")if !reflect.DeepEqual(actualHua, expectedHua) {t.Errorf("Get for '花' failed. Expected: %v, Got: %v", expectedHua, actualHua)} else {fmt.Println("========花=========")for _, s := range actualHua {fmt.Println(s)}}// 测试获取包含“海”字的字符串expectedHai := []string{"春江潮水连海平,海上明月共潮生。","斜月沉沉藏海雾,碣石潇湘无限路。",}actualHai := db.Get("海")if !reflect.DeepEqual(actualHai, expectedHai) {t.Errorf("Get for '海' failed. Expected: %v, Got: %v", expectedHai, actualHai)} else {fmt.Println("========海=========")for _, s := range actualHai {fmt.Println(s)}}}
测试结果通过,可喜可贺

总结
Go简单实现了一下倒排索引,感觉分词还是很重要的,直接决定了整个倒排索引的表现,还是要多学习一些厉害的分词器是怎么实现的~
相关文章:
【Go】-倒排索引的简单实现
目录 什么是倒排索引 定义 基本结构和原理 分词在倒排索引中的重要性 简单倒排索引的实现 接口定义 简单数据库的实现 倒排索引 正排索引 测试 总结 什么是倒排索引 定义 倒排索引(Inverted Index)是一种索引数据结构,它是文档检…...
Python:基于PyCharm的简单程序创建及运行-HelloWorld
1. 新建项目 2. 设置文件位置,并创建项目 文件位置由“目录项目名称”组成,如:D:\PycharmProjects\HelloWorld,“HelloWorld”则是项目名称。 3. 创建Python文件 4. 定义文件名称,如HelloWorld。双击【Python 文件】完…...
设置HP条UI
概述 设置常见的生命值条, 实现过程 设置UI/image作为形状 设置UI/Image作为背景 设置UI/image(healthfill)作为填充图片,层数低于背景 设置heathfill的imagetype为filled fillmethod为horizontal [SerializeField] private Im…...
开源分布式系统追踪-03-CNCF jaeger-02-快速开始
分布式跟踪系列 CAT cat monitor 分布式监控 CAT-是什么? cat monitor-02-分布式监控 CAT埋点 cat monitor-03-深度剖析开源分布式监控CAT cat monitor-04-cat 服务端部署实战 cat monitor-05-cat 客户端集成实战 cat monitor-06-cat 消息存储 skywalking …...
手机实时提取SIM卡打电话的信令声音--社会价值(一、方案解决了什么问题)
手机实时提取SIM卡打电话的信令声音 --社会价值(一、方案解决了什么问题) 一、前言 这段时间,我们在技术范围之外陷入了一个自证或者说下定义的怪圈,即要怎么样去介绍或者描述:我们是一个什么样的产品。它在当前这个世界上,处于…...
FFmpeg功能使用
步骤:1,安装FFmpeg Download FFmpeg 在这里点击->Windows builds from gyan.dev;如下图 会跳到另外的下载界面: 在里面下拉选择点击ffmpeg-7.1-essentials_build.zip: 即可下载到FFmpeg; 使用&#…...
Windows安装WSL子系统及docker,以及WSL和docker配置、使用及问题解决
在Windows操作系统中,Ubuntu子系统(也称为Windows Subsystem for Linux, WSL)为开发者提供了一个在Windows环境下运行Linux环境的平台。然而,有时用户在按照Ubuntu子系统或者使用WSL时,可能会遇到各种问题,下面总结一下解决方式。 想要在Windows上安装Docker(实际上是基…...
飞牛 fnos docker镜像部署OpenSpeedtest宽带网速测试教程
penSpeedTest是一个跨平台的网络测速应用,支持不同操作系统的浏览器,无需安装额外软件或插件。您可以在iPhone、iPad、Android设备、Windows和Linux系统的电脑、手机和平板上直接测试设备与NAS之间的宽带速度。 通过这个可以排查出设备与NAS之间的传输速…...
【kubernetes】资源管理方式
目录 1. 说明2. 命令式对象管理3. 命令式对象配置4. 声明式对象配置5. 三种方式的对比 1. 说明 1.在Kubernetes(k8s)中,资源管理是一个核心功能,它允许用户通过操作资源来管理Kubernetes集群。2.Kubernetes将所有的内容都抽象为资…...
chromedriver可运行的docker环境
以常见的linux x86服务器为例 chrome driver 官网:https://googlechromelabs.github.io/chrome-for-testing/ 下载chrome linux64位:https://storage.googleapis.com/chrome-for-testing-public/131.0.6778.85/xxx 下载chrome driver linux64位&#x…...
【YashanDB知识库】如何将mysql含有group by的SQL转换成崖山支持的SQL
本文内容来自YashanDB官网,原文内容请见 https://www.yashandb.com/newsinfo/7610112.html?templateId1718516 问题现象 以下SQL在MYSQL下均能执行成功,在崖山下执行报错。 SELECT Sname,Ssex, min(Sage) FROM Student group by Ssex;SELECT Sname,c…...
希迪智驾持续亏损8.2亿:毛利率下滑,冲刺“自动驾驶矿卡第一股”
《港湾商业观察》黄懿 近日,希迪智驾(湖南)股份有限公司(下称“希迪智驾”)向港交所主板递交上市申请,联席保荐人为中金公司、中信建投国际、中国平安资本(香港)。 资料显示&#…...
部署GitLab服务器
文章目录 环境准备GitLab部署GitLab服务器GitLab中主要的概念客户端上传代码到gitlab服务器CI-CD概述软件程序上线流程安装Jenkins服务器 配置jenkins软件版本管理配置jenkins访问gitlab远程仓库下载到子目录部署代码到web服务器自动化部署流程 配置共享服务器配置jenkins把git…...
利用cnocr库完成中文扫描pdf文件的文字识别
很多pdf文件文字识别软件都会收费,免费的网页版可能会带来信息泄露,还有一些类似于腾讯AI和百度AI的接口都有调用次数限制,因此,利用识别正确率极高且免费的cnocr库来自己动手做个pdf文件文字识别程序就是一个很不错的选择。以下程…...
pythonselenium自动化初始配置
基础配置 更新pip: 在Terminal中使用命令‘python -m pip install --upgrade pip’就可以安装pip最新版本。 python -m pip install --upgrade pip -i https://pypi.tuna.tsinghua.edu.cn/simple 常用的镜像源: 清华: https://pypi.tuna.tsinghua.edu.cn/simpl…...
【C++】数的性质问题分析与优化
博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 💯前言💯题目解析与分析题目描述题目分析 💯我的解法与详细解读初始代码实现解法分析 💯老师解法与其改进思路老师代码实现改进与优势 💯对比分析…...
ASP.NET Core WebAPI中使用Jwt实现鉴权授权-System.IdentityModel.Tokens.Jwt
使用 System.IdentityModel.Tokens.Jwt 直接实现基于 JWT 的鉴权和授权,可以在 ASP.NET Core 中手动生成、解析、验证 JWT Token。System.IdentityModel.Tokens.Jwt 提供了 JWT 的生成和解析的 API。以下是如何使用该库实现鉴权授权的详细步骤。 步骤 1: 安装 NuGe…...
【iOS】OC高级编程 iOS多线程与内存管理阅读笔记——自动引用计数(四)
目录 ARC规则 规则 对象型变量不能作为C语言结构体的成员 显式转换id和void* 属性 数组 ARC规则 规则 在ARC有效的情况下编译源代码必须遵守一定的规则: 主要解释一下最后两条 对象型变量不能作为C语言结构体的成员 要把对象型变量加入到结构体成员中时&a…...
嵌入式软考学习笔记(1)超详细!!!
目录 第一章计算机系统基础知识 1、逻辑运算 2、数的表示 3、总线系统 5、流水线 6、存储器 7、可靠性、校验码 第一章计算机系统基础知识 1、逻辑运算 与:有0则0,全1才1 或:有1则1,全0才0 异或:相同为0…...
【数据分享】2013-2023年我国省市县三级的逐年CO数据(免费获取\excel\shp格式)
空气质量数据是在我们日常研究中经常使用的数据!之前我们给大家分享了2000-2023年的省市县三级的逐年PM2.5数据、2000-2023年的省市县三级的逐年PM10数据、2013-2023年的省市县三级的逐年SO2数据、2000-2023年省市县三级的逐年O3数据和2008-2023年我国省市县三级的逐…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...
为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?
在建筑行业,项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升,传统的管理模式已经难以满足现代工程的需求。过去,许多企业依赖手工记录、口头沟通和分散的信息管理,导致效率低下、成本失控、风险频发。例如&#…...
Linux简单的操作
ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...
BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...
深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...
安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖
在Vuzix M400 AR智能眼镜的助力下,卢森堡罗伯特舒曼医院(the Robert Schuman Hospitals, HRS)凭借在无菌制剂生产流程中引入增强现实技术(AR)创新项目,荣获了2024年6月7日由卢森堡医院药剂师协会࿰…...
解决:Android studio 编译后报错\app\src\main\cpp\CMakeLists.txt‘ to exist
现象: android studio报错: [CXX1409] D:\GitLab\xxxxx\app.cxx\Debug\3f3w4y1i\arm64-v8a\android_gradle_build.json : expected buildFiles file ‘D:\GitLab\xxxxx\app\src\main\cpp\CMakeLists.txt’ to exist 解决: 不要动CMakeLists.…...
破解路内监管盲区:免布线低位视频桩重塑停车管理新标准
城市路内停车管理常因行道树遮挡、高位设备盲区等问题,导致车牌识别率低、逃费率高,传统模式在复杂路段束手无策。免布线低位视频桩凭借超低视角部署与智能算法,正成为破局关键。该设备安装于车位侧方0.5-0.7米高度,直接规避树枝遮…...
【安全篇】金刚不坏之身:整合 Spring Security + JWT 实现无状态认证与授权
摘要 本文是《Spring Boot 实战派》系列的第四篇。我们将直面所有 Web 应用都无法回避的核心问题:安全。文章将详细阐述认证(Authentication) 与授权(Authorization的核心概念,对比传统 Session-Cookie 与现代 JWT(JS…...
