前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java 常见面试题

Java 常见面试题

作者头像
说故事的五公子
发布2022-05-09 15:41:38
2820
发布2022-05-09 15:41:38
举报

一、搜索

1、什么是Solr

Solr是一个Java开发的基于Lucene的 企业级 开源 全文搜索 平台。 它采用的是反向索引,即从关键字到文档的映射过程。 Solr的资源以Document为对象进行存储,每个文档由一系列的 Field 构成,每个Field 表示资源的一个属性。 文档的Field可以被索引, 以提工高性能的搜索效率。 一般情况下文档都包含一个能唯一表示该文档的id字段。

2、什么是Lucene

Lucene是apache软件基金会发布的一个开放源代码的全文检索引擎工具包,Lucene是根据关健字来搜索的文本搜索工具,只能在某个网站内部搜索文本内容,不能跨网站搜索

3、Solr的倒排索引

倒排索引就是从文档内容到文档序号的过程,将文档内容用solr自带分词器进行分词,然后作为索引,用二分法将关键字与排序号的索引进行匹配,进而查找到对应文档。倒排索引相对于正排而言,正排是从key查询value的一个过程,而倒排索引则是根据value查询key的一个过程,solr首先将数据进行分析,然后创建索引,将创建好的索引存储起来,查询时利用二分法去查询value,这个value对应一个Key,然后将这个Key返回。

4、 Solr和elasticsearch的区别?

https://www.cnblogs.com/jajian/p/9801154.html

共同点:solr和elasticsearch都是基于Lucene实现的!

不同点:

A. solr利用zookeeper进行分布式管理,而elasticsearch自身带有分布式协调管理功能;

B. solr比elasticsearch实现更加全面,solr官方提供的功能更多,而elasticsearch本身更注 重于核心功能,高级功能多由第三方插件提供;

C. solr在传统的搜索应用中表现好于elasticsearch,而elasticsearch在实时搜索应用方面比solr表现好!

二、Java基础知识

1、native关键字:

https://www.cnblogs.com/qian123/p/5702574.html

2、Java异常:

https://www.cnblogs.com/Qian123/p/5715402.html

3、static,final,this,super关键字总结:

https://gitee.com/SnailClimb/JavaGuide/blob/master/docs/java/basic/final,static,this,super.md

4、集合总结

https://www.cnblogs.com/skywang12345/p/3323085.html

1、fail-fast机制

ArrayList在用Iterator遍历数据时会产生fail-fast,导致异常,这是因为ArrayList遍历时会检查当前List的预期值和实际值是否相同,如果相同,则遍历,如果不同则产生异常

解决方案:

使用CopyOnWriteArrayList,他没有继承AbstractList,而是重写了iterator方法,遍历时新建一个数组,然后保存当前数据,由于是新数组,所以不会产生不一样的情况,自然不会有异常

2、HashMap详解:

https://zhuanlan.zhihu.com/p/21673805

3、我对于集合的理解

(1)、集合工具类Arrays

https://blog.csdn.net/samjustin1/article/details/52661862

代码语言:javascript
复制
//asList方法可以将数据转化为List
        List<String> list = Arrays.asList("壮壮", "小马","小六");
        for (String s : list) {
            System.out.println(s);
        }

        //binarySearch可以在数组中查找是否存在某个元素,存在则返回该元素的下标
        int[] arr = new int[]{1, 3, 4,56,4,5,1, 56, 67};
        int index = Arrays.binarySearch(arr, 3,6,4);
        System.out.println(index);

        //sort可以将数组中元素排序
        //toString可以将数组元素打印输出 
        String[] names = {"Eric", "John", "Alan", "Liz"};
        Arrays.sort(names);
        System.out.println(Arrays.toString(names));

        int[][] stuGrades = { { 80, 81, 82 }, { 84, 85, 86 }, { 87, 88, 89 } };
        System.out.println(Arrays.deepToString(stuGrades));

        //fill可以将数组中的元素填充为指定元素
        int[] arr2 = new int[8];
        Arrays.fill(arr, 78);
        System.out.println(Arrays.toString(arr));

(2)、集合工具类Collections

https://www.cnblogs.com/nayitian/p/3269585.html

(3)、ArrayList

继承关系:

代码语言:javascript
复制
java.lang.Object
   ↳     java.util.AbstractCollection<E>
         ↳     java.util.AbstractList<E>
               ↳     java.util.ArrayList<E>

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable {}

特点:底层是数组实现,查找快,增删慢,它是线程不安全的,如果需要线程安全,则可以使用Vector

定义:它继承于AbstractList,实现了List, RandomAccess, Cloneable

ArrayList包含了两个重要的对象:elementData 和 size。

(01) elementData 是"Object[]类型的数组",它保存了添加到ArrayList中的元素。实际上,elementData是个动态数组,我们能通过构造函数 ArrayList(int initialCapacity)来执行它的初始容量为initialCapacity;如果通过不含参数的构造函数ArrayList()来创建ArrayList,则elementData的容量默认是10。elementData数组的大小会根据ArrayList容量的增长而动态的增长,具体的增长方式,请参考源码分析中的ensureCapacity()函数。

(02) size 则是动态数组的实际大小。

遍历:

遍历ArrayList时,使用随机访问(即,通过索引序号访问)效率最高,而使用迭代器的效率最低!

代码语言:javascript
复制
//随机访问
Integer value = null;
int size = list.size();
for (int i=0; i<size; i++) {
    value = (Integer)list.get(i);        
}

(4)、LinkedList

继承关系:

代码语言:javascript
复制
java.lang.Object
   ↳     java.util.AbstractCollection<E>
         ↳     java.util.AbstractList<E>
               ↳     java.util.AbstractSequentialList<E>
                     ↳     java.util.LinkedList<E>

public class LinkedList<E>
    extends AbstractSequentialList<E>
    implements List<E>, Deque<E>, Cloneable, java.io.Serializable {}

特点:

底层是链表实现的,增删快,查找慢

简介:

LinkedList 是一个继承于AbstractSequentialList的双向链表。它也可以被当作堆栈、队列或双端队列进行操作。 LinkedList 实现 List 接口,能对它进行队列操作。 LinkedList 实现 Deque 接口,即能将LinkedList当作双端队列使用。 LinkedList 实现了Cloneable接口,即覆盖了函数clone(),能克隆。 LinkedList 实现java.io.Serializable接口,这意味着LinkedList支持序列化,能通过序列化去传输。 LinkedList 是非同步的。

定义:

LinkedList的本质是双向链表。 (01) LinkedList继承于AbstractSequentialList,并且实现了Dequeue接口。 (02) LinkedList包含两个重要的成员:header 和 size。   header是双向链表的表头,它是双向链表节点所对应的类Entry的实例。Entry中包含成员变量: previous, next, element。其中,previous是该节点的上一个节点,next是该节点的下一个节点,element是该节点所包含的值。   size是双向链表中节点的个数。

遍历:

遍历LinkedList时,使用removeFist()或removeLast()效率最高。但用它们遍历时,会删除原始数据;若单纯只读取,而不删除,应该使用第3种遍历方式。 无论如何,千万不要通过随机访问去遍历LinkedList!

代码语言:javascript
复制
//随机访问效率最慢
int size = list.size();
for (int i=0; i<size; i++) {
    list.get(i);        
}

(5)、vector

Vector简介

Vector 是矢量队列,它是JDK1.0版本添加的类。继承于AbstractList,实现了List, RandomAccess, Cloneable这些接口。 Vector 继承了AbstractList,实现了List;所以,它是一个队列,支持相关的添加、删除、修改、遍历等功能。 Vector 实现了RandmoAccess接口,即提供了随机访问功能。RandmoAccess是java中用来被List实现,为List提供快速访问功能的。在Vector中,我们即可以通过元素的序号快速获取元素对象;这就是快速随机访问。 Vector 实现了Cloneable接口,即实现clone()函数。它能被克隆。

和ArrayList不同,Vector中的操作是线程安全的

特点:底层是数组实现,是线程安全的,Vector里面的方法加上了synchronized关键字

继承关系:

代码语言:javascript
复制
java.lang.Object
   ↳     java.util.AbstractCollection<E>
         ↳     java.util.AbstractList<E>
               ↳     java.util.Vector<E>

public class Vector<E>
    extends AbstractList<E>
    implements List<E>, RandomAccess, Cloneable, java.io.Serializable {}

Vector的数据结构和ArrayList差不多,它包含了3个成员变量:elementData , elementCount, capacityIncrement。

(01) elementData 是"Object[]类型的数组",它保存了添加到Vector中的元素。elementData是个动态数组,如果初始化Vector时,没指定动态数组的>大小,则使用默认大小10。随着Vector中元素的增加,Vector的容量也会动态增长,capacityIncrement是与容量增长相关的增长系数,具体的增长方式,请参考源码分析中的ensureCapacity()函数。

(02) elementCount 是动态数组的实际大小。

(03) capacityIncrement 是动态数组的增长系数。如果在创建Vector时,指定了capacityIncrement的大小;则,每次当Vector中动态数组容量增加时>,增加的大小都是capacityIncrement。

遍历:

遍历Vector使用索引的方式随机访问最快,使用迭代器最慢

(6)HashMap

HashMap简介

HashMap 是一个散列表,它存储的内容是键值对(key-value)映射。 HashMap 继承于AbstractMap,实现了Map、Cloneable、java.io.Serializable接口。 HashMap 的实现不是同步的,这意味着它不是线程安全的。它的key、value都可以为null。此外,HashMap中的映射不是有序的。

HashMap 的实例有两个参数影响其性能:“初始容量” 和 “加载因子”。容量 是哈希表中桶的数量,初始容量 只是哈希表在创建时的容量。加载因子 是哈希表在其容量自动增加之前可以达到多满的一种尺度。当哈希表中的条目数超出了加载因子与当前容量的乘积时,则要对该哈希表进行 rehash 操作(即重建内部数据结构),从而哈希表将具有大约两倍的桶数。 通常,默认加载因子是 0.75, 这是在时间和空间成本上寻求一种折衷。加载因子过高虽然减少了空间开销,但同时也增加了查询成本(在大多数 HashMap 类的操作中,包括 get 和 put 操作,都反映了这一点)。在设置初始容量时应该考虑到映射中所需的条目数及其加载因子,以便最大限度地减少 rehash 操作次数。如果初始容量大于最大条目数除以加载因子,则不会发生 rehash 操作。

继承关系:

代码语言:javascript
复制
java.lang.Object
   ↳     java.util.AbstractMap<K, V>
         ↳     java.util.HashMap<K, V>

public class HashMap<K,V>
    extends AbstractMap<K,V>
    implements Map<K,V>, Cloneable, Serializable { }

特点:

HashMap是数组加链表的方式实现的,首先根据hash值计算出元素存储的位置,如果该位置上已经有元素,则判断key是否相同,如果相同则覆盖,如果不同则在该节点创建链表,当链表长度超过8时,将链表改为红黑树

(7)、HashTable

特点:线程安全

(8)、TreeMap

特点:有序的key-value集合,它是通过红黑树实现的

(9)、set

set和list集合相同,但是set集合中不允许有重复的元素

HashSet:无序集合

TreeSet:有序集合

5、多线程

(1)、创建多线程
代码语言:javascript
复制
//创建多线程有两种方法
//第一种 实现Runnable接口
class MyThread implements Runnable{
    @Override//重写run方法
    public void run() {
        for (int i = 0; i < 50; i++) {
            System.out.println(Thread.currentThread().getName()+i);
        }
    }
}

//第二种方法 继承Thread类
class MyThread extends Thread{
    //Thread的底层也是通过实现Runnable接口来实现多线程,并且Thread类的run方法调用的是接口的方法,因此继承Thread也需要实现run方法
    @Override//重写run方法
    public void run() {
        for (int i = 0; i < 50; i++) {
            System.out.println(Thread.currentThread().getName()+i);
        }
    }
}
(2)、Join方法

join()方法可以让一个线程强制运行

代码语言:javascript
复制
MyThread thread = new MyThread();
        Thread t = new Thread(thread);
        t.start();
        for (int i = 0; i < 50; i++) {
            if (i > 10) {
                try {
                    t.join();  //程序开始时,t线程和main线程交替运行,当i>10时,main停止运行,当t线程运行完成后,main线程才可以接着运行,Join()方法就是一个线程强制运行直至其死亡
                } catch (InterruptedException e) {
                }

            }
            System.out.println("Main线程开始运行"+i);
        }
(3)、线程的状态

1、创建状态

Thread thread=new Thread(); 当程序new Thread(),说明该线程处于创建状态

2、就绪状态

t.start当线程调用start方法时,该线程则处于就绪状态,等待着CPU的调度

3、运行状态

线程获得了CPU和相应资源,开始运行run方法

4、阻塞状态

线程由于某种原因暂时停止运行,sleep(),suspend(),wait()等方法都可以让线程处于阻塞状态

5、死亡状态

线程运行完毕,或者线程调用stop方法,则该线程处于死亡状态

(4)、几个常用方法

1、join方法 强制线程运行

在线程操作中,可以使用 join() 方法让一个线程强制运行,线程强制运行期间,其他线程无法运行,必须等待此线程完成之后才可以继续执行。

2、sleep方法 休眠线程

在程序中允许一个线程进行暂时的休眠,直接使用 Thread.sleep() 即可实现休眠。

3、interrupt方法 中断线程

当一个线程运行时,另外一个线程可以直接通过interrupt()方法中断其运行状态。

4、setDaemon方法 后台线程

在 Java 程序中,只要前台有一个线程在运行,则整个 Java 进程都不会消失,所以此时可以设置一个后台线程,这样即使 Java 线程结束了,此后台线程依然会继续执行,要想实现这样的操作,直接使用 setDaemon() 方法即可。

5、setPriority方法

设置线程优先级 值分别为Thread.MIN_PRIORITY Thread.MAX_PRIORITY Thread.NORM_PRIORITY 范围1-10

6、yield方法 线程礼让

在线程操作中,也可以使用 yield() 方法将一个线程的操作暂时让给其他线程执行

(5)、start()和run()区别
代码语言:javascript
复制
//这里调用run方法并没有新建线程,而是直接用当前线程
thread.run();
//start方法则新建了一个线程来调用run
thread.start();

// Demo.java 的源码
class MyThread extends Thread{  
    public MyThread(String name) {
        super(name);
    }

    public void run(){
        System.out.println(Thread.currentThread().getName()+" is running");
    } 
}; 

public class Demo {  
    public static void main(String[] args) {  
        Thread mythread=new MyThread("mythread");

        System.out.println(Thread.currentThread().getName()+" call mythread.run()");
        mythread.run();

        System.out.println(Thread.currentThread().getName()+" call mythread.start()");
        mythread.start();
    }  
}

结果:
main call mythread.run()
main is running
main call mythread.start()
mythread is running
(6)、synchronized

一、原理:

在java中,每一个对象有且仅有一个同步锁。这也意味着,同步锁是依赖于对象而存在。 当我们调用某对象的synchronized方法时,就获取了该对象的同步锁。例如,synchronized(obj)就获取了“obj这个对象”的同步锁。 不同线程对同步锁的访问是互斥的。也就是说,某时间点,对象的同步锁只能被一个线程获取到!通过同步锁,我们就能在多线程中,实现对“对象/方法”的互斥访问。 例如,现在有两个线程A和线程B,它们都会访问“对象obj的同步锁”。假设,在某一时刻,线程A获取到“obj的同步锁”并在执行一些操作;而此时,线程B也企图获取“obj的同步锁” —— 线程B会获取失败,它必须等待,直到线程A释放了“该对象的同步锁”之后线程B才能获取到“obj的同步锁”从而才可以运行。

二、sychronized使用规则

我们将synchronized的基本规则总结为下面3条,并通过实例对它们进行说明。 第一条: 当一个线程访问“某对象”的“synchronized方法”或者“synchronized代码块”时,其他线程对“该对象”的该“synchronized方法”或者“synchronized代码块”的访问将被阻塞。 第二条: 当一个线程访问“某对象”的“synchronized方法”或者“synchronized代码块”时,其他线程仍然可以访问“该对象”的非同步代码块。 第三条: 当一个线程访问“某对象”的“synchronized方法”或者“synchronized代码块”时,其他线程对“该对象”的其他的“synchronized方法”或者“synchronized代码块”的访问将被阻塞。

三、实例锁和全局锁(对象锁和类锁)

实例锁:当时使用synchronized方法或者sychronized代码块时,如果不加上static的话,那么这个锁就是实例锁(对象锁),也就是说同一个对象共享同一个实例锁,不同的对象享受不同的实例锁,互不干涉。 全局锁:当使用static synchronized实现同步时,那么就是全局锁,即同一个类共享一个锁,不管有多少对象,只要他们属于同一个类,那么这些对象都共享一个锁

(7)、wait和notify

一、介绍

在Object.java中,定义了wait(), notify()和notifyAll()等接口。wait()的作用是让当前线程进入等待状态,同时,wait()也会让当前线程释放它所持有的锁。而notify()和notifyAll()的作用,则是唤醒当前对象上的等待线程;notify()是唤醒单个线程,而notifyAll()是唤醒所有的线程。 Object类中关于等待/唤醒的API详细信息如下: notify() -- 唤醒在此对象监视器上等待的单个线程。 notifyAll() -- 唤醒在此对象监视器上等待的所有线程。 wait() -- 让当前线程处于“等待(阻塞)状态”,“直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法”,当前线程被唤醒(进入“就绪状态”)。 wait(long timeout) -- 让当前线程处于“等待(阻塞)状态”,“直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者超过指定的时间量”,当前线程被唤醒(进入“就绪状态”)。 wait(long timeout, int nanos) -- 让当前线程处于“等待(阻塞)状态”,“直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量”,当前线程被唤醒(进入“就绪状态”)。

二、注意点:

  1. wait()方法的作用是让当前线程等待,当调用wait方法后,当前线程释放同步锁,其他线程可以获取该同步锁执行
  2. 只有和持有该对象同步锁的线程执行了notify()方法并且释放了同步锁以后,wait线程才可以获取锁继续执行

三、示例:

代码语言:javascript
复制
// WaitTest.java的源码
class ThreadA extends Thread{

    public ThreadA(String name) {
        super(name);
    }

    public void run() {
        synchronized (this) {
            System.out.println(Thread.currentThread().getName()+" call notify()");
            // 唤醒当前的wait线程
            notify();
        }
    }
}

public class WaitTest {

    public static void main(String[] args) {

        ThreadA t1 = new ThreadA("t1");

        synchronized(t1) {
            try {
                // 启动“线程t1”
                System.out.println(Thread.currentThread().getName()+" start t1");
                t1.start();

                // 主线程等待t1通过notify()唤醒。
                System.out.println(Thread.currentThread().getName()+" wait()");
                t1.wait();

                System.out.println(Thread.currentThread().getName()+" continue");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

/**
结果:
main start t1
main wait()
t1 call notify()
main continue

结果说明:
如下图,说明了“主线程”和“线程t1”的流程。

(01) 注意,图中"主线程" 代表“主线程main”。"线程t1" 代表WaitTest中启动的“线程t1”。 而“锁” 代表“t1这个对象的同步锁”。
(02) “主线程”通过 new ThreadA("t1") 新建“线程t1”。随后通过synchronized(t1)获取“t1对象的同步锁”。然后调用t1.start()启动“线程t1”。
(03) “主线程”执行t1.wait() 释放“t1对象的锁”并且进入“等待(阻塞)状态”。等待t1对象上的线程通过notify() 或 notifyAll()将其唤醒。
(04) “线程t1”运行之后,通过synchronized(this)获取“当前对象的锁”;接着调用notify()唤醒“当前对象上的等待线程”,也就是唤醒“主线程”。
(05) “线程t1”运行完毕之后,释放“当前对象的锁”。紧接着,“主线程”获取“t1对象的锁”,然后接着运行。
*/
(8)、线程优先级

一、定义

用户线程:用户线程一般用于执行用户任务 守护线程:守护线程一般用于执行后台任务 当用户线程全部执行完毕后,守护线程也会自动结束。 我们可以用isDaemon()方法判断线程是否为守护线程,当isDaemon()返回false时,表明该线程为用户线程,可以用setDaemon()方法将一个线程设为守护线程

二、线程优先级

线程优先级范围1-10,数字越大,说明线程优先级越高,默认这个数字为5。优先级高的优先于优先级低执行

三、算法

1、链表:

Java链表的实现:https://blog.csdn.net/jianyuerensheng/article/details/51200274

tips:双指针法,快慢指针(一个指针速度慢,一个指针速度快)

eg1:查找链表中间元素

fast指针每次往后走两步,slow每次向后走一步,这样当fast走到链表结尾时,slow刚好走到链表的中间位置

代码语言:javascript
复制
class Solution {
public:
    ListNode* getKthFromEnd(ListNode* head, int k) {
        ListNode *p = head, *q = head; //初始化
        while(k--) {   //将 p指针移动 k 次
            p = p->next;
        }
        while(p != nullptr) {//同时移动,直到 p == nullptr
            p = p->next;
            q = q->next;
        }
        return q;
    }
};

eg2:倒数第k个元素问题

先来看"倒数第k个元素的问题"。设有两个指针 p 和 q,初始时均指向头结点。首先,先让 p 沿着 next 移动 k 次。此时,p 指向第 k+1个结点,q 指向头节点,两个指针的距离为 k 。然后,同时移动 p 和 q,直到 p 指向空,此时 p 即指向倒数第 k 个结点

代码语言:javascript
复制
public:
    ListNode* middleNode(ListNode* head) {
        ListNode *p = head, *q = head;
        while(q != nullptr && q->next != nullptr) {
            p = p->next;
            q = q->next->next;
        }
        return p;
    } 
};

eg3:链表是否存在环

类似于两个人在操场上跑步,其中一个快,一个慢,那么最终快和慢的一定会相遇

代码语言:javascript
复制
public:
    bool hasCycle(ListNode *head) {
        ListNode *slow = head;
        ListNode *fast = head;
        while(fast != nullptr) {
            fast = fast->next;
            if(fast != nullptr) {
                fast = fast->next;
            }
            if(fast == slow) {
                return true;
            }
            slow = slow->next;
        }
        return nullptr;
    }
};

四:Redis

1、Redis持久化:

RDB和AOF

2、Redis事务

MULTI:开启事务 EXEC:提交事务 DISCARD:放弃事务

开启事务后,所有操作命令都会加入到队列中,并不会立即执行,等到执行EXEC时再统一执行命令

1、正常执行:当所有命令正常执行时,提交事务时会将所有在队列中的命令正常提交,然后执行 2、放弃事务:执行DISCARD命令则放弃本次事务 3、全体连坐:有一个出错,全部都不提交 4、Watch监控:Watch监控时如果有其他人修改了数据,那么此次事务提交失败,需要获取到最新的数据才能继续

五、网络

TCP三次握手

1、首先客户端发送一个SYN=1和seq=x包给服务器

2、服务器确认收到后,发送给客户端SYN=1,ack=x+1,seq=y(这个是服务器端的序列号)

3、客户端收到服务器端的通知后发送ACK=1,seq=x+1,ack=y+1

TCP四次挥手

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-03-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、搜索
    • 1、什么是Solr
      • 2、什么是Lucene
        • 3、Solr的倒排索引
          • 4、 Solr和elasticsearch的区别?
          • 二、Java基础知识
            • 1、native关键字:
              • 2、Java异常:
                • 3、static,final,this,super关键字总结:
                  • 4、集合总结
                    • 1、fail-fast机制
                    • 2、HashMap详解:
                    • 3、我对于集合的理解
                  • 5、多线程
                    • (1)、创建多线程
                    • (2)、Join方法
                    • (3)、线程的状态
                    • (4)、几个常用方法
                    • (5)、start()和run()区别
                    • (6)、synchronized
                    • (7)、wait和notify
                    • (8)、线程优先级
                • 三、算法
                  • 1、链表:
                  • 四:Redis
                  • 五、网络
                  相关产品与服务
                  Elasticsearch Service
                  腾讯云 Elasticsearch Service(ES)是云端全托管海量数据检索分析服务,拥有高性能自研内核,集成X-Pack。ES 支持通过自治索引、存算分离、集群巡检等特性轻松管理集群,也支持免运维、自动弹性、按需使用的 Serverless 模式。使用 ES 您可以高效构建信息检索、日志分析、运维监控等服务,它独特的向量检索还可助您构建基于语义、图像的AI深度应用。
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档