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

Java集合框架面试指南

Java集合框架面试指南

文章目录

  • Java集合框架面试指南
    • ArrayList特点:
    • LinkedList特点:
    • ArrayDeque特点:
    • PriorityQueue特点:
    • HashMap特点:
    • HashSet特点:
    • LinkedHashMap特点
      • LinkedHashMap经典用法
    • TreeMap特点
    • ConcurrentHashMap
      • JDK7中的ConcurrentHashMap是怎么保证并发安全的?
      • JDK7中的ConcurrentHashMap的底层原理
      • JDK8中的ConcurrentHashMap是怎么保证并发安全的?
      • JDK7和JDK8中的ConcurrentHashMap的不同点

人生的艰难困苦无法选择,但是可以自己无坚不摧,星光不问赶路人,时间不复有心人

Java集合类之间的关系

Collection接口

  • 是List,Set,Queue接口的父接口
  • 常用方法:添加对象add(),删除对象remove(),清空容器clear(),判断容易是否为空isEmpty()等

常见的一些集合类

ArrayList特点:

1. 底层是数组,数组里面是object对象,可以通过数组下标随机查重,是顺序容器,允许null元素
2. **非线程安全** ,建议在单线程中使用ArrayList,而在多线程中选择Vector或者CopyOnWriteArrayList
3. 是动态数组,可以实现动态增长,默认初始容量为10,每次扩容都是原来的1.5倍,数组扩容时会将老数组的元素重新拷贝到新的数组中
4. ArrayList没有push_back()方法,对应的方法是add(E e),ArrayList也没有insert()方法,对应的方法是add(int index, E e),set(int index, E element)对数组指定位置赋值。get(int index)获取指定位置的值。
5. remove()方法也有两个版本,一个是remove(int index)删除指定位置的元素,另一个是remove(Object o)删除第一个满足o.equals(elementData[index])的元素。
6. indexOf(Object o)获取元素的第一次出现的index,lastIndexOf(Object o)获取元素的最后一次出现的index

LinkedList特点:

1. 底层结构是**链表**,增删速度快
2. **非线程安全**
3. 是一个**双向**链表,也可以被当作堆栈、队列或双端队列,关于栈和队列首选ArrayDeque
4. 包含一个非常重要的内部类 Node<E>,是双向链表节点所对应的数据结构,其包括的属性有『当前节点所包含的值』、『上一个节点』、『下一个节点』
5. getFrist() 和 getLast() 获取第一个元素和获取最后一个元素
6. removeFrist() ,removeLast(),romove(e) ,remove(index) remove()方法也有两个版本,一个是删除跟指定元素相等的第一个元素remove(Object o),另一个是删除指定下标处的元素remove(int index)。
7. add() 一个是add(E e),该方法在LinkedList的末尾插入元素,因为有last指向链表末尾,在末尾插入元素的花费是常数时间。只需要简单修改几个相关引用即可;另一个是add(int index, E element),该方法是在指定下表处插入元素,需要先通过线性查找找到具体位置,然后修改相关引用完成插入操作。
8. indexOf(Object o)查找第一次出现的index, 如果找不到返回-1;

ArrayDeque特点:

1. ArrayDeque底层是通过循环数组实现的,非线程安全的,该容器不能放入null元素
2. addFirst(E e)的作用是在Deque的首端插入元素,也就是在head的前面插入元素,扩容函数doubleCapacity(),其逻辑是申请一个更大的数组(原数组的两倍),然后将原数组复制过去,addLast(E e)的作用是在Deque的尾端插入元素,也就是在tail的位置插入元素。
3. pollFirst()的作用是删除并返回Deque首端元素,也即是head位置处的元素。pollLast()的作用是删除并返回Deque尾端元素,也即是tail位置前面的那个元素。
4. peekFirst()的作用是返回但不删除Deque首端元素,也即是head位置处的元素,peekLast()的作用是返回但不删除Deque尾端元素,也即是tail位置前面的那个元素。

PriorityQueue特点:

1. 优先队列的作用是能保证每次取出的元素都是队列中权值最小的(Java的优先队列每次取最小元素,C++的优先队列每次取最大元素)。
2. <font style="color:rgb(44, 62, 80);">不</font>允许放入null元素;其通过堆实现,具体说是通过完全二叉树(complete binary tree)实现的小顶堆(任意一个非叶子节点的权值,都不大于其左右子节点的权值),**通过数组来作为PriorityQueue的底层实现。**
3. leftNo = parentNo*2+1	rightNo = parentNo*2+2	parentNo = (nodeNo-1)/2
4. PriorityQueue的peek()和element操作是常数时间,add(), offer(), 无参数的remove()以及poll()方法的时间复杂度都是log(N)。
5. add(E e)和offer(E e)的语义相同,都是向优先队列中插入元素,只是Queue接口规定二者对插入失败时的处理不同,前者在插入失败时抛出异常,后则则会返回false,新加入的元素x可能会破坏小顶堆的性质,因此需要进行调整。调整的过程为: 从k指定的位置开始,将x逐层与当前点的parent进行比较并交换,直到满足x >= queue[parent]为止。
6. element()和peek()的语义完全相同,都是获取但不删除队首元素,也就是队列中权值最小的那个元素,二者唯一的区别是当方法失败时前者抛出异常,后者返回null。根据小顶堆的性质,堆顶那个元素就是全局最小的那个;由于堆用数组表示,根据下标关系,0下标处的那个元素既是堆顶元素。**所以直接返回数组0下标处的那个元素即可。**
7. remove()和poll()方法的语义也完全相同,都是获取并删除队首元素,区别是当方法失败时前者抛出异常,后者返回null。由于删除操作会改变队列的结构,为维护小顶堆的性质,需要进行必要的调整,**从k指定的位置开始,将x逐层向下与当前点的左右孩子中较小的那个交换,直到x小于或等于左右孩子中的任何一个为止。**

HashMap特点:

1. 实现了Map、Cloneable(能被克隆)、Serializable(支持序列化)接口,**无序,**非线程安全,允许存在一个**为null的key和任意个为null的value**
2. 采用**链表和红黑树**实现,初始容量为16,填充因子默认是0.75 , 扩容时是当前容量翻倍,当链表长度大于8会树化,当树的节点小于6会进行链表化
3. get(object key) 首先通过hash() 函数得到对应的bucket的下标,然后通过key.equals(k) 方法判断是否是想要找的那个entry
4. put(K key, V value) 该方法首先会对map做一次查找,看是否包含该元组,如果已经包含则直接覆盖,如果是树节点则调用树的插入,否则遍历链表,**尾插法**,之后判断链表长度是否大于8,大于8则直接树化
5. 数组扩容,resize() 方法用于初始化数组或数组扩容,每次扩容后,容量为原来的 2 倍,并进行数据迁移。

HashSet特点:

1. HashSet是基于HasMap实现的,**是一个没有重复元素的集合,不保证元素的顺序,而且HashSet允许使用null元素,非同步的**
2. Set只使用到了HashMap的key,所以定义一个静态的常量Object类,来充当HashMap的value 
3. add(E e) 添加指定元素,clear() 移除set中所有的元素 clone() 返回HashSet实例的浅表副本,并没有复制这些元素本身  contains(Object o) 若此set包含指定元素则返回true  isEmpty() set若为空则返回true iterator() set中元素的迭代器  remove(Object o) 移除指定元素  size() 返回set元素的数量

LinkedHashMap特点

1. LinkedHashMap实现了Map接口,即允许放入key为null的元素,也允许插入value为null的元素。从名字上可以看出该容器是linked list和HashMap的混合体
2. 直接继承HashMap,唯一的区别是在HashMap的基础上,采用双向链表,将所有的entry连接起来了,保证元素的迭代顺序就是entry的插入顺序
3. put(K key,V value) 1. 从table的角度看,新的entry需要插入到对应的bucket里,当有哈希冲突时,采用头插法将新的entry插入到冲突链表的头部。2. 从header的角度看,新的entry需要插入到双向链表的尾部。
4. romove()1. 从table的角度看,需要将该entry从对应的bucket里删除,如果对应的冲突链表不空,需要修改冲突链表的相应引用。2. 从header的角度来看,需要将该entry从双向链表中删除,同时修改链表中前面以及后面元素的相应引用。

LinkedHashMap经典用法

LinkedHashMap除了可以保证迭代顺序外,还有一个非常有用的用法: 可以轻松实现一个采用了LRUCache替换策略的缓存。具体说来,LinkedHashMap有一个子类方法protected boolean removeEldestEntry(Map.Entry<K,V> eldest),该方法的作用是告诉Map是否要删除“最老”的Entry,所谓最老就是当前Map中最早插入的Entry,如果该方法返回true,最老的那个元素就会被删除。在每次插入新元素的之后LinkedHashMap会自动询问removeEldestEntry()是否要删除最老的元素。这样只需要在子类中重载该方法,当元素个数超过一定数量时让removeEldestEntry()返回true,就能够实现一个固定大小的LRUCache策略的缓存。示例代码如下:

class LRUCache extends LinkedHashMap {private int cap;public LRUCache(int capacity) {super(capacity,0.75f,true);cap = capacity;}public int get(int key) {return (int) super.getOrDefault(key,-1);}public void put(int key, int value) {super.put(key,value);}@Overrideprotected boolean removeEldestEntry(Map.Entry eldest) {return size()>cap;}
}

TreeMap特点

  • 是SortedMap接口的实现类
  • 有序,根据key对节点进行排序
  • 支持两种排序方法:自然排序定制排序。前者所有key必须实现Comparable接口且所有key应该是一个类的对象;后者通过传入一个Comparator接口对象负责对多有key进行排序。
  • 非线程安全
  • 采用红黑树的数据结构

ConcurrentHashMap

JDK7中的ConcurrentHashMap是怎么保证并发安全的?

主要利用Unsafe操作+ReentrantLock+分段思想。主要使用了Unsafe操作中的:

  1. compareAndSwapObject: 通过cas的方式修改对象的属性2 . putOrderedObject:并发安全的给数组的某个位置赋值3 . getObjectVolatile:并发安全的获取数组某个位置的元素分段思想是为了提高ConcurrentHashMap的并发量,

分段数越高则支持的最大并发量越高,程序员可以通过concurrencyLevel参数来指定并发量ConcurrentHashMap的内部类Segment就是用来表示某一个段的。每个Segment就是一个小型的HashMap的, 当调用ConcurrentHashMap的put方法是,最终会调用到Segment的put方法, 而Segment类继承了ReentrantLock, 所以Segment自带可重入锁, 当调用到Segment的put方法时,会先利用可重入锁加锁, 加锁成功后再将待插入的key ,value插入到小型HashMap中,插入完成后解锁。

JDK7中的ConcurrentHashMap的底层原理

ConcurrentHashMap底层是由两层嵌套数组来实现的:1. ConcurrentHashMap对象中有一个属性segments, 类型为Segment[];

2 . Segment对象中有一个属性table, 类型为HashEntry[];

当调用ConcurrentHashMap的put方法时,先根据key计算出对应的Segment[]的数组下标j,确定好当前key ,value应该插入到哪个Segment对象中,如果segments[j]为空,则利用自旋锁的方式在j位置生成一个 Segment对象。然后调用Segment对象的put方法。

Segment对象的put方法会先加锁, 然后也根据key计算出对应的HashEntry[]的数组下标i,然后将 key ,value封装为HashEntry对象放入该位置, 此过程和JDK7的HashMap的put方法一样, 然后解锁。 在加锁的过程中逻辑比较复杂, 先通过自旋加锁, 如果超过一 定次数就会直接阻塞等等加锁。

JDK8中的ConcurrentHashMap是怎么保证并发安全的?

主要利用Unsafe操作+synchronized关键字。Unsafe操作的使用仍然和JDK7中的类似,主要负责并发安全的修改对象的属性或数组某个位置的值。

synchronized主要负责在需要操作某个位置时进行加锁 (该位置不为空) , 比如向某个位置的链表进行插入结点,向某个位置的红黑树插入结点。JDK8中其实仍然有分段锁的思想,只不过JDK7中段数是可以控制的,而JDK8中是数组的每一个位置都有 一把锁。

当向ConcurrentHashMap中put一 个key ,value时,

1.首先根据key计算对应的数组下标i, 如果该位置没有元素, 则通过自旋的方法去向该位置赋值。

2.如果该位置有元素, 则synchronized会加锁

3.加锁成功之后, 在判断该元素的类型a. 如果是链表节点则进行添加节点到链表中b. 如果是红黑树则添加节点到红黑树

4.添加成功后,判断是否需要进行树化

5.addCount,这个方法的意思是ConcurrentHashMap的元素个数加1, 但是这个操作也是需要并发安全的,并且元素个数加1成功后,会继续判断是否要进行扩容, 如果需要,则会进行扩容,所以这个方法很重要。

6 . 同时一个线程在put时如果发现当前ConcurrentHashMap正在进行扩容则会去帮助扩容。

JDK7和JDK8中的ConcurrentHashMap的不同点

这两个的不同点太多了 . . ., 既包括了HashMap中的不同点, 也有其他不同点, 比如:

  1. JDK8中没有分段锁了, 而是使用synchronized来进行控制

2 . JDK8中的扩容性能更高, 支持多线程同时扩容, 实际上JDK7中也支持多线程扩容, 因为JDK7中的扩 容是针对每个Segment的, 所以也可能多线程扩容, 但是性能没有JDK8高, 因为JDK8中对于任意一个线程都可以去帮助扩容

3 . JDK8中的元素个数统计的实现也不一 样了, JDK8中增加了CounterCell来帮助计数, 而JDK7中没有, JDK7中是put的时候每个Segment内部计数, 统计的时候是遍历每个Segment对象加锁统计。

推荐阅读:Java7/8 中的 HashMap 和 ConcurrentHashMap 全解析

整理一下:

相关文章:

Java集合框架面试指南

Java集合框架面试指南 文章目录 Java集合框架面试指南ArrayList特点&#xff1a;LinkedList特点&#xff1a;ArrayDeque特点&#xff1a;PriorityQueue特点&#xff1a;HashMap特点&#xff1a;HashSet特点&#xff1a;LinkedHashMap特点LinkedHashMap经典用法 TreeMap特点Conc…...

八、MapReduce 大规模数据处理深度剖析与实战指南

MapReduce 大规模数据处理深度剖析与实战指南 一、绪论 在当今的大数据时代背景下&#xff0c;海量数据的处理已然成为企业及科研机构所面临的重大挑战。MapReduce 作为一种高效的分布式计算模型&#xff0c;在大规模数据处理领域中发挥着至关重要的作用。本文将深入阐释 MapR…...

开源免费的API网关介绍与选型

api网关的主要作用 API网关在现代微服务架构中扮演着至关重要的角色&#xff0c;它作为内外部系统通信的桥梁&#xff0c;不仅简化了服务调用过程&#xff0c;还增强了系统的安全性与可管理性。例如&#xff0c;当企业希望将内部的服务开放给外部合作伙伴使用时&#xff0c;直…...

OpenCV视觉分析之目标跟踪(5)目标跟踪类TrackerMIL的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 MIL 算法以在线方式训练分类器&#xff0c;以将目标从背景中分离出来。多重实例学习&#xff08;Multiple Instance Learning&#xff09;通过在…...

二级列表联动

介绍 本示例主要介绍了List组件实现二级联动&#xff08;Cascading List&#xff09;的场景。 该场景多用于商品种类的选择、照片不同类型选择等场景。 效果图 使用说明&#xff1a; 滑动二级列表侧控件&#xff08;点击没用&#xff09;&#xff0c;一级列表随之滚动。&…...

「C/C++」C++ 标准库 之 #include<sstream> 字符串流库

✨博客主页何曾参静谧的博客&#x1f4cc;文章专栏「C/C」C/C程序设计&#x1f4da;全部专栏「VS」Visual Studio「C/C」C/C程序设计「UG/NX」BlockUI集合「Win」Windows程序设计「DSA」数据结构与算法「UG/NX」NX二次开发「QT」QT5程序设计「File」数据文件格式「PK」Parasoli…...

深入理解跨域资源共享(CORS)安全问题原理及解决思路

目录 引言 CORS 基础 CORS 安全问题原理 解决思路 结论 引言 跨域资源共享&#xff08;CORS, Cross-Origin Resource Sharing&#xff09;是现代Web应用中不可或缺的一部分&#xff0c;特别是在前后端分离的架构中。CORS允许一个域上的Web应用请求另一个域上的资源&#…...

【汽车租聘管理与推荐】Python+Django网页界面+推荐算法+管理系统网站

一、介绍 汽车租聘管理与推荐系统。本系统使用Python作为主要编程语言&#xff0c;前端采用HTML、CSS、BootStrap等技术搭建前端界面&#xff0c;后端采用Django框架处理用户的请求。创新点&#xff1a;使用协同过滤推荐算法实现对当前用户个性化推荐。 其主要功能如下&#…...

Linux常见指令大全(必要+知识点)

目录 ls 指令☑️ 在Windows中会自动显示当前目录当中的所有子目录与文件&#xff0c;但是在Linux中要用到ls指令。 语法&#xff1a; ls [选项][目录或文件] 功能&#xff1a;对于目录&#xff0c;该命令列出该目录下的所有子目录与文件。对于文件&#xff0c;将列出文件名以…...

iOS用rime且导入自制输入方案

iPhone 16 的 cantonese 只能打传统汉字&#xff0c;没有繁简转换&#xff0c;m d sh d。考虑用「仓」输入法 [1] 使用 Rime 打字&#xff0c;且希望导入自制方案 [2]。 仓输入法有几种导入方案的方法&#xff0c;见 [3]&#xff0c;此处记录 wifi 上传法。准备工作&#xff1…...

Linux 进程终止 进程等待

目录 进程终止 退出码 错误码 代码异常终止(信号详解) exit _exit 进程等待 概念 等待的原因 wait 函数原型 参数 返回值 监控脚本 waitpid 概念 函数原型 参数 返回值 WIFEXITED(status) WEXITSTATUS(status) 问题 为什么不用全局变量获得子进程的退出信…...

VBA 64位API声明语句第003讲

跟我学VBA&#xff0c;我这里专注VBA, 授人以渔。我98年开始&#xff0c;从源码接触VBA已经20余年了&#xff0c;随着年龄的增长&#xff0c;越来越觉得有必要把这项技能传递给需要这项技术的职场人员。希望职场和数据打交道的朋友&#xff0c;都来学习VBA,利用VBA,起码可以提高…...

【问题记录】解决VMware虚拟机中鼠标侧键无法使用的问题

前言 有项目需要在Linux系统中开发&#xff0c;因为要测试Linux中相关功能&#xff0c;要用到shell&#xff0c;在Windows中开发太麻烦了&#xff0c;因此我选择使用UbuntuXfce4桌面来开发&#xff0c;这里我用到了Linux版本的IDEA&#xff0c;除了快捷键经常和系统快捷键冲突…...

Naive UI 级联选择器 Cascader的:render-lable怎么使用(Vue3 + TS)(鼠标悬停该条数据的时候展示全部内容)

项目场景&#xff1a; 在渲染Cascader级联选择器后&#xff0c;当文字过长的时候&#xff0c;多出来的部分会显示成省略号&#xff0c;这使我们不能很清晰的看到该条数据的完整信息&#xff0c;就需要加一个鼠标悬停展示完整内容。 解决方案&#xff1a; vue&#xff1a; &l…...

vue元素里面的 js对象中,:style后面里属性名不支持这种带-的写法(background-color)

首先要知道&#xff0c;在这个:style里面&#xff0c;虽然可以用 {属性: 属性值 , 属性: 属性值} 这种方方式来写很多属性&#xff0c;但也仅限于width这种普通属性&#xff0c;像background-color这种带-的特殊标签是不支持直接写的&#xff1b; <div class"box&quo…...

Git 常用命令与开发流程总结

引言 在我之前面试过程中&#xff0c;经常会问到关于公司使用什么代码版本管理工具。 无非是考察咱们是否用过 Git和SVN。 现在公司选择的工具直接影响到项目的开发流程和协作效率。当前市面上&#xff0c;Git 和 SVN&#xff08;Subversion&#xff09;是两种流行的版本控制系…...

链表中插入新的节点

/* 节点结构体定义 */ struct xLIST_ITEM {TickType_t xItemValue; /* 辅助值&#xff0c;用于帮助节点做顺序排列 */ struct xLIST_ITEM * pxNext; /* 指向链表下一个节点 */ struct xLIST_ITEM * pxPrevious; /* 指向链表前一个节点 */ void * pvOw…...

AUTOSAR从入门到精通-BswM模块(二)

目录 前言 算法原理 BswM接口端口 BswM功能描述 模式仲裁 仲裁规则(Arbitration Rules) 模式仲裁来源 模式仲裁过程 模式条件(ModeCondition) 逻辑表达式(LogicExpressions) 模式控制 模式处理 操作执行 模式控制过程 模式控制基本流程 BswM Interfaces and …...

Spring DispatcherServlet详解

文章目录 Spring DispatcherServlet详解一、引言二、DispatcherServlet的初始化与工作流程1、DispatcherServlet的初始化1.1、加载配置和建立WebApplicationContext1.2、初始化策略 2、DispatcherServlet的工作流程2.1、请求分发2.2、代码示例 三、总结 Spring DispatcherServl…...

JS | 软件制作的流程是什么?

目录 一、 需求分析 二、 系统设计 三、 编码实现 四、 测试验证 五、 部署上线 六、 维护更新 软件制作的流程主要包含需求分析、系统设计、编码实现、测试验证、部署上线和维护更新。其中&#xff0c;需求分析是基础&#xff0c;它决定了软件的功能和性能&#xff1b;通…...

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站&#xff0c;会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后&#xff0c;网站没有变化的情况。 不熟悉siteground主机的新手&#xff0c;遇到这个问题&#xff0c;就很抓狂&#xff0c;明明是哪都没操作错误&#x…...

零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?

一、核心优势&#xff1a;专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发&#xff0c;是一款收费低廉但功能全面的Windows NAS工具&#xff0c;主打“无学习成本部署” 。与其他NAS软件相比&#xff0c;其优势在于&#xff1a; 无需硬件改造&#xff1a;将任意W…...

label-studio的使用教程(导入本地路径)

文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...

FFmpeg 低延迟同屏方案

引言 在实时互动需求激增的当下&#xff0c;无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作&#xff0c;还是游戏直播的画面实时传输&#xff0c;低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架&#xff0c;凭借其灵活的编解码、数据…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八

现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet&#xff0c;点击确认后如下提示 最终上报fail 解决方法 内核升级导致&#xff0c;需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

线程与协程

1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指&#xff1a;像函数调用/返回一样轻量地完成任务切换。 举例说明&#xff1a; 当你在程序中写一个函数调用&#xff1a; funcA() 然后 funcA 执行完后返回&…...

UE5 学习系列(三)创建和移动物体

这篇博客是该系列的第三篇&#xff0c;是在之前两篇博客的基础上展开&#xff0c;主要介绍如何在操作界面中创建和拖动物体&#xff0c;这篇博客跟随的视频链接如下&#xff1a; B 站视频&#xff1a;s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...

基于Uniapp开发HarmonyOS 5.0旅游应用技术实践

一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架&#xff0c;支持"一次开发&#xff0c;多端部署"&#xff0c;可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务&#xff0c;为旅游应用带来&#xf…...

如何为服务器生成TLS证书

TLS&#xff08;Transport Layer Security&#xff09;证书是确保网络通信安全的重要手段&#xff0c;它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书&#xff0c;可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...

Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!

一、引言 在数据驱动的背景下&#xff0c;知识图谱凭借其高效的信息组织能力&#xff0c;正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合&#xff0c;探讨知识图谱开发的实现细节&#xff0c;帮助读者掌握该技术栈在实际项目中的落地方法。 …...