2024金三银四JAVA面试题和部分答案

445 阅读1小时+

多线程&并发面试题

Java中实现多线程有几种方法

实现runnable接口(匿名内部类、直接实现接口)

// 比较推荐匿名内部类的方式 
public class MyRunnable1 {

    public static void main(String[] args) {
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("MyRunnable1 running...");
            }
        });
        t.start();
    }
}


// 直接实现Runnable接口
public class MyRunnable2 implements Runnable {
    public void run() {
        System.out.println("MyRunnable running...");
    }

    public static void main(String[] args) {
        Thread t = new Thread(new MyRunnable2());
        t.start();
    }
}

继承thread类

public class MyThread extends Thread {
    public void run() {
        System.out.println("MyThread running...");
    }

    public static void main(String[] args) {
        MyThread t = new MyThread();
        t.start();
    }
}

实现Callable接口,搭配FutureTask可以获取异步执行任务结果

public class MyCallable implements Callable<Integer> {
    public Integer call() throws Exception {
        System.out.println("MyCallable running...");
        // 模拟耗时操作
        Thread.sleep(2000);
        return 123;
    }

    public static void main(String[] args) {
        MyCallable callable = new MyCallable();
        FutureTask<Integer> futureTask = new FutureTask<>(callable);

        Thread t = new Thread(futureTask);
        t.start();

        try {
            // 获取任务执行结果
            Integer result = futureTask.get();
            System.out.println("Result: " + result);
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
    }
}

线程池

不推荐使用Executors创建线程容易OOM
推荐使用new ThreadPoolExecutor()的方式,根据服务器核心数自定义线程参数

@Bean("myExecutor")
    public ExecutorService myExecutor() {
        ExecutorService ex = new ThreadPoolExecutor(
                2,
                2,
                0L,
                TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<>(100),// 指定任务数量
                new CustomThreadFactory(),
                (r, e) -> log.error("异常"));
        return ex;
    }

Executors.newFixedThreadPool(指定工作线程数量的线程池)
Executors.newCachedThreadPool
Executors.newSingleThreadExecutor
Executors.newScheduleThreadPool

如何停止一个正在运行的线程

  1. stop()方法会导致线程突然停止(不安全且已经被废弃)
  2. 通过设置标识位:
    可以通过设置一个标识位来通知线程退出执行。线程在执行任务时,可以周期性地检查这个标识位,如果标识位为 true,则线程自行退出执行。
class MyRunnable implements Runnable {
    private volatile boolean flag = true;

    public void run() {
        while (flag) {
            // 线程执行的任务
        }
    }

    public void stopThread() {
        flag = false; // 设置标识位为 false,通知线程退出
    }
}
  1. 通过 interrupt() 方法:
    可以调用线程的 interrupt() 方法来中断线程的执行。在线程的执行逻辑中,需要经常检查线程是否被中断,并根据情况做出处理。
class MyRunnable implements Runnable {
    public void run() {
        while (!Thread.currentThread().isInterrupted()) {
        // 线程执行的任务
        }
    }
}

// 在其他地方中断线程
Thread thread = new Thread(new MyRunnable());
thread.start();
// 中断线程
thread.interrupt();

参考 blog.csdn.net/wuhuayangs/…

notify和notifyAll有什么区别

notify() 方法用于唤醒在对象监视器上等待的单个线程(任意一个)。如果有多个线程在等待,那么只有其中一个线程会被唤醒,但具体唤醒哪个线程是不确定的。
notifyAll() 方法用于唤醒在对象监视器上等待的所有线程。当调用 notifyAll() 后,所有等待的线程都会被唤醒,然后开始竞争对象锁。

sleep和wait有什么区别

调用位置不同:sleep() 是 Thread 类的静态方法,可以在任何地方使用;而 wait() 是 Object 类的方法,只能用于同步块或同步方法中。
锁的释放情况不同:sleep() 方法不会释放对象锁,线程休眠期间仍然持有该对象锁,其他线程无法访问该对象;而 wait() 方法会释放对象锁,线程进入等待状态后,会释放当前对象锁,其他线程可以继续访问该对象。
被唤醒方式不同:sleep() 方法在指定的时间过后会自动唤醒,或者通过其他线程中断它来提前唤醒;而 wait() 方法则需要等待其他线程调用该对象的 notify() 或 notifyAll() 方法来被唤醒。

volatile是什么?可以保证有序性吗?

volatile 是 Java 中一种修饰符,当一个变量被声明为 volatile 时,表示它可能会被多个线程同时访问并修改。volatile 主要具有两个作用:
可见性(Visibility):使用 volatile 关键字修饰的变量在多线程环境下,当一个线程修改了这个变量的值,其他线程能够立即看到最新的值。这是因为在每次访问 volatile 变量时,都会强制从主内存中读取最新的值,而不是使用线程私有的缓存。
禁止重排序(Prevents Reordering):使用 volatile 关键字修饰的变量前后的指令不会被重排序,即保证了相关指令的执行顺序不会发生变化。
虽然 volatile 关键字可以保证可见性和禁止重排序,但它并不能保证 原子性 (比如i++的操作就不行,可以用AtomicInteger或者synchronized)

Thread类中的start和run方法有什么区别?

start() 方法用于启动一个新线程并执行线程的任务,而 run() 方法仅仅是一个普通的方法调用(只是包含了线程要执行的任务代码),不会创建新线程

为什么wait, notify和notifyAll这些方法不在thread类里面?

这些方法是用于实现线程间的协作和同步,在多个线程之间共享同一个对象的锁来进行通信和控制

为什么wait和notify方法要在同步块中调用?

调用wait()就是释放锁,释放锁的前提是必须要先获得锁,先获得锁才能释放锁。

notify(),notifyAll()是将锁交给含有wait()方法的线程,让其继续执行下去,如果自身没有锁,怎么叫把锁交给其他线程呢;(本质是让处于入口队列的线程竞争锁)

Java中interrupted和isInterrupted方法的区别?

interrupted() 是一个静态方法,用于检查当前线程的中断状态,而 isInterrupted() 是一个实例方法,用于检查指定线程对象的中断状态。
interrupted() 方法会清除当前线程的中断状态,而 isInterrupted() 方法不会。

Java中synchronized和ReentrantLock有什么不同?

用法不同:synchronized 可以用来修饰普通方法、静态方法和代码块,而 ReentrantLock 只能用于代码块。
获取锁和释放锁的机制不同:synchronized 是自动加锁和释放锁的,而 ReentrantLock 需要手动加锁和释放锁。
锁类型不同:synchronized 是非公平锁,而 ReentrantLock 默认为非公平锁,也可以手动指定为公平锁。
响应中断不同:ReentrantLock 可以响应中断,解决死锁的问题,而 synchronized 不能响应中断。
底层实现不同:synchronized 是 JVM 层面通过监视器实现的,而 ReentrantLock 是基于 AQS 实现的。
参考 blog.csdn.net/m0_69860228…

(公平锁是有个等待队列,线程会先进入等待队列,按顺序获取锁,非公平锁是不用进入等待队列,获取锁的顺序不确定)

有三个线程T1,T2,T3,如何保证顺序执行?

用CountDownLatch 执行完一个调countDown(),未执行完保持await()

import java.util.concurrent.CountDownLatch;

public class SequentialExecution {
    public static void main(String[] args) {
        CountDownLatch latch1 = new CountDownLatch(1);
        CountDownLatch latch2 = new CountDownLatch(1);

        Thread t1 = new Thread(() -> {
            // 线程 T1 的任务
            System.out.println("Thread T1 is running");
            latch1.countDown();
        });

        Thread t2 = new Thread(() -> {
            try {
                latch1.await();
                // 线程 T2 的任务
                System.out.println("Thread T2 is running");
                latch2.countDown();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        Thread t3 = new Thread(() -> {
            try {
                latch2.await();
                // 线程 T3 的任务
                System.out.println("Thread T3 is running");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        t1.start();
        t2.start();
        t3.start();
    }
}

SynchronizedMap和ConcurrentHashMap有什么区别?

SynchronizedMap 和 ConcurrentHashMap 都是用于实现多线程环境下的并发访问的数据结构,但它们在实现方式和性能特点上有一些区别。
线程安全性:
SynchronizedMap 是通过使用 synchronized 关键字来实现线程安全的。它对整个 Map 对象加锁,保证每次只有一个线程能够执行修改操作,其他线程需要等待锁释放才能继续操作。
ConcurrentHashMap 则是通过分段锁(Segment-Level Locking)来实现线程安全。它将整个 Map 分成多个小的段(Segment),每个段都有自己的锁。不同的线程可以同时修改不同的段,从而提高并发性能。
性能:
由于 SynchronizedMap 对整个 Map 加锁,因此在高并发环境下,会导致大量线程竞争同一个锁,可能造成性能瓶颈。
ConcurrentHashMap 的分段锁机制可以使得多个线程同时修改不同的段,从而减少了竞争,提高了并发性能。

什么是线程安全

线程安全指的是在多线程环境下,对共享数据的操作不会导致数据出现不确定的状态或者结果。换句话说,当多个线程同时访问某个对象或资源时,不会出现数据损坏、状态异常或者不一致的情况。

Thread类中的yield方法有什么作用?

Thread 类中的 yield() 方法用于提示调度器当前线程愿意让出 CPU 执行时间,让其他具有相同优先级的线程有机会执行。当调用 yield() 方法时,当前线程将从运行状态转为就绪状态,然后调度器可以选择其他就绪状态的线程来执行。

Java线程池中submit和execute方法有什么区别?

都是用于将任务提交给线程池执行
submit是提交一个callable或者runnable任务到线程池,并且通过Furture get()方法可以获取执行结果
execute()是提交一个runnable对象,不返回执行结果

说一说自己对于synchronized关键字的了解

synchronized关键字是Java中实现互斥同步最基本的手段,它是一种悲观锁,是一种可重入锁(通过锁计数器是否为0判定对象持有或者释放锁的状态)。
过多的使用会导致线程阻塞
synchronized关键字的工作原理:
在同步语句块时,synchronized关键字经过编译之后,会在同步块的前后形成monitorenter和monitorexit两个字节码指令,代表对象实例或者Class对象作为线程要持有的锁。

说说自己是怎么使用synchronized关键字,在项目中用到了吗synchronized关键字最主要的三种使用方式?

项目中雪花算法初始化的时候有用到

1.同步代码块:

Object lock = new Object();
synchronized (lock) {
    // 同步的代码块
}

2.同步方法:

public synchronized void synchronizedMethod() {
    // 同步的方法
}

3.静态同步方法:

public static synchronized void staticSynchronizedMethod() {
    // 静态同步的方法
}

什么是线程安全? Vector是一个线程安全类吗?

是的 用的synchronized实现线程安全
需要线程安全性,也可以选择如 CopyOnWriteArrayList、ConcurrentLinkedQueue 等

volatile关键字的作用?

跟前面那题差不多

简述一下你对线程池的理解

方便线程的管理、减少线程创建和销毁的开销
核心组件有 任务队列、工作线程、线程池管理器

线程生命周期(状态)

新建、就绪、运行、阻塞、等待、终止

JVM面试题

参考 blog.csdn.net/dingjianmin…

垃圾收集器

Serial垃圾收集器(单线程、复制算法)

ParNew垃圾收集器(Serial+ 多线程)

Parallel Scavenge收集器(多线程复制算法、高效)

Serial Old收集器(单线程标记整理算法)

Parallel Old收集器(多线程标记整理算法)

CMS收集器(多线程标记清除算法)

G1收集器(分区算法)

JVM类加载机制

跟下面那个一样

类加载器

jdk9之前
启动类加载器、扩展类加载器、应用程序类加载器、自定义类加载器
jdk9之后
启动类加载器、平台类加载器、应用程序类加载器、自定义类加载器\

引导类加载器:定义核心Java SE和JDK模块。
平台类加载器:定义部分Java SE和JDK模块。
应用或系统类加载器:定义CLASSPATH上的类和模块路径中的模块。
参考 blog.csdn.net/chengqiumin…

双亲委派

双亲委派(Parent Delegation)是Java类加载器的一种工作机制,其核心思想是当一个类加载器需要加载某个类时,它会先委托给其父类加载器来尝试加载,只有在父类加载器无法完成加载时,子类加载器才会尝试自行加载。这种机制可以确保类的唯一性,避免同一个类被不同的类加载器加载多次,并且能够保证类加载的安全性。

OSGI (动态模型系统)

OSGi(Open Service Gateway Initiative)是一个面向 Java 平台的动态模块化系统框架,它定义了一套标准,用于在 Java 应用程序中实现模块化开发和动态部署。OSGi 的核心思想是将应用程序拆分为多个独立的模块(Bundle),每个模块可以包含自己的 Java 类、资源文件和配置信息,并且模块之间可以进行动态的安装、卸载、启动和停止。

动态改变构造

OSGi 服务平台提供在多种网络设备上无需重启的动态改变构造的功能。为了最小化耦合度和促使

这些耦合度可管理,OSGi 技术提供一种面向服务的架构,它能使这些组件动态地发现对方。

模块化编程与热插拔

OSGi 旨在为实现 Java 程序的模块化编程提供基础条件,基于 OSGi 的程序很可能可以实现模块级

的热插拔功能,当程序升级更新时,可以只停用、重新安装然后启动程序的其中一部分,这对企

业级程序开发来说是非常具有诱惑力的特性。

OSGi 描绘了一个很美好的模块化开发目标,而且定义了实现这个目标的所需要服务与架构,同时

也有成熟的框架进行实现支持。但并非所有的应用都适合采用 OSGi 作为基础架构,它在提供强大

功能同时,也引入了额外的复杂度,因为它不遵守了类加载的双亲委托模型。

JVM内存模型

线程共享的 堆、方法区(元空间)
线程独有的 本地方法栈、程序计数器、虚拟机栈

分代回收

分代回收(Generational Garbage Collection)是一种垃圾回收策略,主要用于管理堆内存中的对象。它基于一个观察:大多数对象在其生命周期中很快变得不可达,即没有被其他对象引用。基于这个观察,分代回收将堆内存划分为不同的代(Generation),并针对每个代应用不同的回收策略。

通常,分代回收将堆内存划分为三代:年轻代(Young Generation)、年老代(Old Generation)和持久代(Permanent Generation)。

年轻代:年轻代是新创建的对象的分配区域,其中包含了刚刚被分配的对象。年轻代通常分为 Eden 区和两个 Survivor 区。当 Eden 区满时,会触发一次年轻代的垃圾回收,将仍然存活的对象拷贝到 Survivor 区。如果对象经过多次垃圾回收后仍然存活,则会被移动到年老代。

年老代:年老代是存活时间较长的对象的分配区域。年老代中的对象经历了多次年轻代的垃圾回收,仍然存活下来的对象会被移动到年老代中。年老代的垃圾回收相对较少,以免影响程序的性能。

持久代:持久代主要用于存放类信息、常量池等对象。在最新的 JDK 版本中,持久代已经被移除,取而代之的是元空间(Metaspace)。

堆和栈的区别

存储内容:

堆(Heap):堆是用于动态分配内存的一种内存区域。在堆中存储的数据通常是由程序员进行手动分配和释放的,用于存储对象、数组等动态分配的数据结构。
栈(Stack):栈是一种具有后进先出(LIFO)特性的内存区域,用于存储方法调用、局部变量、方法参数等。栈中的数据会随着方法的调用和返回而动态地压栈和弹栈。 管理方式:

堆(Heap):堆内存的分配和释放由程序员手动控制,需要显式地调用 new 和 delete 等操作符进行内存的分配和释放。
栈(Stack):栈内存的管理由编程语言和运行时系统自动处理,方法的调用和返回会自动在栈上进行压栈和弹栈操作,无需程序员手动管理。 空间大小:

堆(Heap):堆的大小通常比栈大,堆的空间可以动态地增长或缩小,但可能会导致内存碎片化。
栈(Stack):栈的大小固定,通常在编译时就已经确定,栈的空间有限且连续,存储在栈中的数据大小和生命周期受到限制。 数据访问速度:

堆(Heap):由于堆的动态分配和释放需要更复杂的管理机制,因此堆的访问速度比栈慢一些。
栈(Stack):由于栈的数据结构简单、紧凑且连续,因此访问速度相对较快。

什么时候会触发FullGC

老年代空间不足
要分配一个较大的对象,而堆内存不足时
手动调了system.gc()

什么是Java虚拟机?为什么Java被称作是“平台无关的编程语言”?

JVM提供了内存管理、垃圾回收、安全性检查等功能,使得Java程序能够在不同的操作系统和硬件平台上实现跨平台的特性。

被称作是“平台无关的编程语言”是因为其源代码经过编译后生成的字节码可以在任何支持Java虚拟机的系统上运行

对象分配规则

为新对象分配内存是一个非常严谨和复杂的任务,JVM的设计者们不仅需要考虑内存如何分配、在哪里分配等问题,并且由于内存分配算法与内存回收算法密切相关,所以还需要考虑GC执行完内存回收是否会在内存空间中产生内存碎片。

对象优先分配在Eden区,如果Eden区没有足够的空间时,虚拟机执行一次Minor GC。

大对象直接进入老年代(大对象是指需要大量连续内存空间的对象)。这样做的目的是避免在Eden区和两个Survivor区之间发生大量的内存拷贝(新生代采用复制算法收集内存)。

当Eden区空间填满时,程序又需要创建对象,JVM的垃圾回收器将对Eden区进行垃圾回收,将Eden区中不再被其他对象引用的对象进行销毁。再加载新的对象放到Eden区。

然后将Eden的剩余对象移动到幸存者0区。如果再次触发垃圾回收,此时将幸存者0区,没有回收的放到幸存者1区。如果再次垃圾回收,就会再去幸存者0区,接着再去幸存者1区。

长期存活的对象进入老年代。虚拟机为每个对象定义了一个年龄计数器,如果对象经过了1次Minor GC那么对象会进入Survivor区,之后每经过一次Minor GC那么对象的年龄加1,直到达到阀值对象15次进入老年区。

动态判断对象的年龄。如果Survivor区中相同年龄的所有对象大小的总和大于Survivor空间的一半,年龄大于或等于该年龄的对象可以直接进入老年代。

空间分配担保。每次进行Minor GC时,JVM会计算Survivor区移至老年区的对象的平均大小,如果这个值大于老年区的剩余值大小则进行一次Full GC,如果小于检查HandlePromotionFailure设置,如果true则只进行Monitor GC,如果false则进行Full GC

描述一下JVM加载class文件的原理机制?

加载:JVM首先会尝试从文件系统中加载class文件。这通常通过调用类加载器(ClassLoader)的findClass方法来完成,该方法会尝试从类路径(Classpath)或自定义的路径中加载class文件。
验证:一旦class文件被加载,JVM会对它进行验证。这包括检查class文件的签名,确保它与当前版本匹配,以及检查是否包含了必要的指令。如果发现任何问题,JVM将抛出异常。
准备:在这个阶段,字节码被转换为可以被Java虚拟机直接操作的本地代码。这个过程也被称为“内联”(inlining)或“链接”(linking)。
解析:解析阶段涉及将常量池中的符号引用转换为直接引用。这可以防止在程序运行期间修改class文件。
初始化:最后,当类被加载到内存中时,它的静态变量会被初始化,并且所有静态初始化块和初始化方法都会被执行。 在JVM中,有两种主要的类加载器:
启动类加载器(Bootstrap ClassLoader):这是JVM的最内层,负责加载核心库。
扩展类加载器(Extension ClassLoader)和系统类加载器(System ClassLoader):它们负责加载Java EE或标准库。当应用程序需要使用这些库时,这些类加载器会负责加载相应的class文件。

Java对象创建过程

检查类是否已加载、为新生对象分配内存、把分配内存区域初始化零值、设置对象头、调用构造函数初始化对象资源

Java中的IO与NIO面试题:

Java中IO流?

在 Java 中,IO(Input/Output)流是用于处理输入和输出操作的机制。Java 提供了丰富的 IO 类库,可以方便地进行文件操作、网络通信等任务。IO 流主要分为输入流和输出流,根据数据流向的不同又可以分为字节流和字符流。

字节流(Byte Streams):

字节流以字节为单位进行读写操作,适用于处理二进制数据或字节流数据。常见的字节 流类有:

InputStream 和 OutputStream:抽象类,用于读取和写入字节流。
FileInputStream 和 FileOutputStream:用于读写文件的字节流。
BufferedInputStream 和 BufferedOutputStream:带缓冲功能的字节流,提高IO性能。

字符流(Character Streams):

字符流以字符为单位进行读写操作,适用于处理文本数据。字符流使用编码集来处理字符数据。常见的字符流类有:

Reader 和 Writer:抽象类,用于读取和写入字符流。
FileReader 和 FileWriter:用于读写文件的字符流。
BufferedReader 和 BufferedWriter:带缓冲功能的字符流,提高IO性能。

Java IO与NIO的区别

阻塞 vs 非阻塞:Java IO 是阻塞式的,而 NIO 是非阻塞式的。
流式处理 vs 缓冲区和通道:Java IO 是基于流的处理模型,而 NIO 是基于缓冲区和通道的处理模型。
多路复用:NIO 支持多路复用,可以有效地管理多个通道的 IO 操作。

常用io类有哪些

字节流类(Byte Streams):
InputStream 和 OutputStream:抽象类,用于读取和写入字节流。
FileInputStream 和 FileOutputStream:用于读写文件的字节流。

字符流类(Character Streams): Reader 和 Writer:抽象类,用于读取和写入字符流。
FileReader 和 FileWriter:用于读写文件的字符流。
StringReader 和 StringWriter:用于读写字符串的字符流。
BufferedReader 和 BufferedWriter:带缓冲功能的字符流,提高 IO 性能。

对象流类(Object Streams):
ObjectInputStream 和 ObjectOutputStream:用于读写对象的流,支持对象的序列化和反序列化。

输入输出流类(Input/Output Streams):
PipedInputStream 和 PipedOutputStream:用于线程间的管道通信,一个线程将数据写入管道,另一个线程从管道中读取数据。

转换流类(Conversion Streams):
InputStreamReader 和 OutputStreamWriter:用于字节流和字符流之间的转换,支持指定字符集编码。

字节流与字符流的区别

阻塞IO模型

非阻塞IO模型

多路复用IO模型

信号驱动IO模型

异步IO模型

JAVA NIO

NIO 主要有三大核心部分:Channel(通道),Buffer(缓冲区), Selector

NIO的缓冲区

NIO的非阻塞

Channel

Buffer

Mysql面试题:

分库分表之后,id主键如何处理

雪花算法

存储过程(特定功能的SQL语句集)

存储过程优化思路

触发器(一段能自动执行的程序)

数据库并发策略

事务隔离级别、锁机制、连接池、索引等等

MySQL中有哪几种锁?

按数据库操作 行锁、表锁、页级锁 按共享策略 共享锁、排他锁、意向共享锁、意向排他锁 按加锁策略 乐观锁、悲观锁

MySQL中有哪些不同的表格?

常用的就MyISAM、InnoDB

简述在MySQL数据库中MyISAM和InnoDB的区别

在MySQL数据库中,MyISAM和InnoDB是两种常见的存储引擎,它们在功能和特性上有一些区别:

事务支持:

MyISAM:不支持事务。MyISAM表级锁定,因此在高并发的情况下可能会出现性能瓶颈。 InnoDB:支持事务。InnoDB使用行级锁定,提供更好的并发性能和事务处理能力。 外键约束:

MyISAM:不支持外键约束。 InnoDB:支持外键约束,确保数据的完整性,可以定义外键关系。 行级锁定:

MyISAM:表级锁定,即对整个表进行锁定,容易导致并发性能问题。 InnoDB:行级锁定,只锁定需要操作的行,提供更好的并发控制和性能。 索引:

MyISAM:只缓存索引,不缓存实际数据。 InnoDB:主键索引和数据是紧密集成的,支持覆盖索引,辅助索引也包含了主键列,因此查询效率更高。 崩溃恢复:

MyISAM:不具备崩溃恢复功能,容易出现数据损坏。 InnoDB:支持事务,具有崩溃恢复功能,可以保证数据的一致性。 空间占用:

MyISAM:通常占用的磁盘空间较小。 InnoDB:由于支持事务和行级锁定,通常会占用更多的磁盘空间。 总的来说,InnoDB是MySQL中更常用的存储引擎,特别适合需要事务支持、外键约束和高并发处理的应用场景。而MyISAM适用于一些简单的应用,不需要事务支持和复杂查询的情况下。选择合适的存储引擎取决于项目的需求和特点,可以根据具体情况进行选择和优化。

MySQL中InnoDB支持的四种事务隔离级别名称,以及逐级之间的区别?

读未提交 允许一个事务读到另一个事务未提交的数据(脏读)
读已提交 保证一个事务只能读取到其他事务已经提交的数据(避免了脏读,可能出现不可重复读和幻读)
可重复读 保证了多次读取同一条数据时,结果始终一致(innodb默认的隔离级别,可能出现幻读问题) 串行话 最高隔离级别(避免了所有脏读、不可重复读、幻读等问题)

CHAR和VARCHAR的区别?

在MySQL中,CHAR和VARCHAR都是用于存储字符串类型的字段,它们之间的主要区别在于存储方式和使用场景:

CHAR:

CHAR是一种固定长度的字符串类型,当创建CHAR字段时,需要指定固定的字符长度,例如CHAR(10)。
CHAR类型的数据存储是靠右对齐的,如果实际存储的字符串长度小于指定的长度,则会在右侧用空格进行填充。
由于是固定长度,所以CHAR类型的字段在存储时会占用固定的存储空间,不会因为实际存储的字符串长度而变化。

VARCHAR:

VARCHAR是一种可变长度的字符串类型,当创建VARCHAR字段时,同样需要指定最大字符长度,例如VARCHAR(255)。
VARCHAR类型的数据存储是动态变化的,它只会占用实际存储的字符串长度加上一定的长度用于存储长度信息。
由于是可变长度,所以VARCHAR类型的字段在存储时可以节省空间,特别是对于较长的字符串字段。

主键和候选键有什么区别?

主键是用来唯一标识表中记录的字段或字段组合,每张表只能有一个主键;而候选键是可以作为主键备选的字段或字段组合,表中可以有多个候选键。

myisamchk是用来做什么的?

myisamchk是一个用于检查、维护和修复MyISAM表格的命令行工具

MyISAM Static 和MyISAM Dynamic有什么区别?

如果一个表有一列定义为TIMESTAMP,将发生什么?

勾选根据当前时间戳更新的话
每当行被更改时,时间戳字段将获取当前时间戳。

你怎么看到为表格定义的所有索引?

SHOW INDEX FROM your_table_name;

LIKE声明中的%和_是什么意思?

在SQL中,LIKE语句用于在查询中匹配模式的字符串。在LIKE语句中,%和_是通配符,用于表示任意字符或特定字符的占位符。

百分号(%):在LIKE语句中,%表示零个或多个字符的通配符。例如,如果你使用'abc%',它将匹配以"abc"开头的任何字符串,例如"abcdef"、"abc123"等。

下划线(_):在LIKE语句中,下划线_表示单个字符的通配符。例如,如果你使用'a_c',它将匹配"a1c"、"abc"等三个字符长度的字符串,但不会匹配"abcd"等长度不符合的字符串。

列对比运算符是什么?

=、<> !=、>、<这些

BLOB和TEXT有什么区别?

blob 存储二进制数据 可以存储图片

text 存储字符数据 只能存储文本文件

MySQL fetch. array 和MySQL fetch object 的区别是什么?

MyISAM表格将在哪里存储,并且还提供其存储格式?

MySQL如何优化DISTINCT?

索引优化 查询出来的列尽量索引覆盖

如何显示前50名?

limit

可以使用多少列创建索引?

NOW () 和CURRENT_ DATE () 有什么区别?

now 年月日时分秒 currentdate 年月日

什么是非标准字符串类型?

uuid json xml这些

什么是通用SQL函数?

通用 SQL 函数是指在几乎所有的 SQL 数据库管理系统(DBMS)中都可以使用的函数
一些常见的通用 SQL 函数包括:

聚合函数:如 SUM、AVG、COUNT、MAX、MIN 等,用于对数据进行计算和统计。 字符串函数:如 CONCAT、SUBSTRING、UPPER、LOWER 等,用于处理和操作字符串数据。
日期和时间函数:如 NOW、DATE_FORMAT、DATE_ADD、DATEDIFF 等,用于处理日期和时间数据。
数学函数:如 ABS、ROUND、CEIL、FLOOR 等,用于执行数学运算。
逻辑函数:如 IF、CASE 等,用于实现逻辑判断和条件控制。
类型转换函数:如 CAST、CONVERT 等,用于数据类型之间的转换。
NULL 函数:如 IS NULL、COALESCE 等,用于处理 NULL 值。

MySQL支持事务吗?

支持

Redis面试题:

Redis是单进程单线程的?

嗯,它使用单个进程来处理客户端请求,并且在同一时刻只能执行一个操作。尽管 Redis 采用单线程模型,但它通过非阻塞 I/O 和事件驱动的方式来实现高性能和并发处理能力。

一个字符串类型的智能存储最大容量是多少?

512M

Redis持久化机制

AOF RDB

缓存雪崩、缓存穿透、缓存预热、缓存更新、缓存降级等问题

缓存雪崩 瞬间大量key失效
缓存穿透 某个key查数据库没有,所有请求一直进行查缓存、查数据库的操作,导致大了请求直接打到了数据库
缓存预热 提前将热点数据加载到缓存中
缓存更新 需要定时去更新缓存中数据,来保证缓存数据和数据库数据的一致性
缓存降级 指缓存失效或者缓存服务器挂掉的情况下,不去访问数据库,直接返回默认数据或者访问服务的内存数据。

热点数据和冷数据是什么

热点数据就是经常访问的数据

冷数据就是长期没有访问的

单线程的redis为什么这么快

基于内存 数据结构 非阻塞IO

redis的数据类型,以及每种数据类型的使用场景

string 分布式锁
list 有序 任务队列
set 无序不重复 标签
zset 有序不重复 排行榜
hash 键值对 门店信息

redis的过期策略以及内存淘汰机制

过期策略 定时删除、惰性删除 内存淘汰机制 内存空间快满时,需要根据一定策略淘汰部分键释放内存空间
LRU(Least Recently Used): 淘汰最近最少使用的键。

LFU(Least Frequently Used): 淘汰最不经常使用的键。

随机淘汰(Random): 随机选择要淘汰的键。

定期淘汰(TTL-based): 淘汰剩余生存时间最短的键。

自定义淘汰策略: 用户可以编写自定义的淘汰算法来满足特定的需求。

Redis常见性能问题和解决方案?

网络问题 有时候发现访问redis很慢,一般需要检查网络
持久化影响性能 最好不要在master做持久化 用slave从节点
特别大的数据最好分批次读取

为什么Redis的操作是原子性的,怎么保证原子性的?

单线程的

Redis事务

Redis 事务是一种将多个命令打包成一个执行单元,要么全部执行成功,要么全部失败回滚的机制。在 Redis 中,可以使用 MULTI、EXEC、DISCARD 和 WATCH 等命令来实现事务操作。

下面是 Redis 事务的基本使用方式:

MULTI: 使用 MULTI 命令开始一个事务,表示接下来的命令将被包含在事务中。

在 MULTI 和 EXEC 之间输入的多个命令会被放入一个队列中,但不会立即执行。

EXEC: 使用 EXEC 命令执行事务中的所有命令。如果在 EXEC 执行之前发生了错误,整个事务将会被放弃,不会有任何命令被执行。

DISCARD: 使用 DISCARD 命令取消事务,清空事务队列,放弃事务中的所有命令。

WATCH: 使用 WATCH 命令可以对指定的键进行监视,如果在事务执行之前被修改,事务将会被打断。

Redis的持久化机制是什么?各自的优缺点?

Redis 提供了两种持久化机制:RDB (Redis Database Backup) 和 AOF (Append Only File)。

RDB 持久化机制:

优点:
RDB 持久化机制通过将数据集的快照保存到磁盘上,能够提供非常高效的数据恢复性能。
对于大规模的数据集来说,在进行备份时比 AOF 快很多。
由于是在单个文件上执行同步操作,因此 RDB 在保存时对磁盘的 I/O 消耗相对较低。
缺点:
如果系统在保存 RDB 文件时出现故障,可能会导致部分数据丢失。
RDB 持久化机制并不适合需要实时持久化的场景,因为它是周期性的持久化操作,可能会导致在最后一次持久化之后的数据丢失。
RDB 文件的恢复过程比 AOF 更加缓慢。
AOF 持久化机制:

优点:
AOF 以追加的方式记录服务器接收到的写命令,因此可以保证极低的数据丢失率。
AOF 文件以易读易写的文本格式保存,便于人工查看和修复。
AOF 文件可以通过 fsync 策略来调整持久化频率,可以更灵活地控制数据的持久化程度。
缺点:
AOF 文件通常比 RDB 文件大,因此在恢复时需要更长的时间。
AOF 持久化机制的写入性能通常比 RDB 差,并且对磁盘的 I/O 消耗相对较高。
AOF 文件可能会因为过大而影响系统的启动速度。

Redis常见性能问题和解决方案:

上面有

redis过期键的删除策略?

惰性 定时

Redis的回收策略(海汰策略) ?

上面有

为什么redis需要把所有数据放到内存中?

Redis的同步机制了解么?

复制(主从复制) 持久化

Pipeline有什么好处,为什么要用pipeline?

Redis Pipeline管道 是一种用于优化 Redis 命令批量执行性能的技术。它可以在客户端发送多个请求到 Redis 服务器时,将这些请求打包成一个批量请求一起发送给 Redis 服务器,从而减少了网络通信的次数和时间开销,提高了 Redis 命令的执行效率。

是否使用过Redis集群,集群的原理是什么?

Redis集群方案什么情况下会导致整个集群不可用?

大规模节点故障 资源耗尽

Redis支持的Java客户端都有哪些?官方推荐用哪个?

Jedis
优点:以 Redis 命令作为方法名称,学习成本低廉,简单且实用
缺点:Jedis 的实例是线程不安全的,在多线程的环境下需要基于线程池来使用

lettuce(spring 官方默认)基于 Netty 实现的,支持同步、异步和响应式编程方式,并且是线程安全的。支持 Redis 的哨兵模式、集群模式、管道模式

Redisson(适用于分布式的环境)基于 Redis 实现的分布式、可伸缩的 Java 数据结构的集合。包含 Map、Queue、Lock、Semaphore、AtomicLong等强大的功能

Jedis与Redisson对比有什么优缺点?

Redis如何设置密码及验证密码?

在配置文件里面改 改完重启下

MyBatis 面试题:

通常一个Xml映射文件,都会写一个Dao接口与之对应,请问,这个Dao接口的工作原理是什么? Dao接口里的方法,参数不同时,方法能重载吗?

Dao接口的工作原理是JDK动态代理,MyBatis运行时会使用JDK动态代理为Dao接口生产代理proxy对象,代理对象会拦截接口方法,转而执行MappedStatement所代表的sql,然后将sql执行结果返回。

不能 会有各种各样的问题应该是

如何获取自动生成的(主)键值?

插入数据时设置 useGeneratedKeys="true"

在mapper 中如何传递多个参数?

@Param

Mybatis 动态sql有什么用?执行原理?有哪些动态sql?

动态 SQL 的执行原理是在进行 SQL 解析和执行之前,通过解析 Mapper XML 中的动态 SQL 语句,根据条件判断动态地拼接 SQL 语句。在运行时,根据传入的参数值判断是否应该包含特定的 SQL 片段。这样可以根据不同的条件生成不同的 SQL 语句,以满足各种复杂的业务需求。

if foreach

Xml映射文件中,除了常见的selectlinsertlupdaeldelete标签之外,还有哪些标签?

sql include resultmap

Mybatis 的Xml映射文件中,不同的Xml映射文件,id 是否可以重复?

不行

为什么说Mybatis是半自动ORM映射工具?它与全自动的区别在哪里?

需要手动写sql

一对一、一对多的关联查询?

MyBatis 实现一对一有几种方式?具体怎么操作的?

联合查询是几个表联合查询,只查询一次, 通过在resultMap 里面配置 association 节点配置一对一的类就可以完成;

MyBatis 实现-对多有几种方式,怎么操作的?

Mybatis 是否支持延迟加载?如果支持,它的实现原理是什么?

Mybatis 仅支持 association 关联对象和 collection 关联集合对象的延迟加载,association 指的就是一对一,collection 指的就是一对多查询。在 Mybatis配置文件中,可以配置是否启用延迟加载 lazyLoadingEnabled=true|false。它的原理是,使用 CGLIB 创建目标对象的代理对象,当调用目标方法时,进入拦截器方法,比如调用 a.getB().getName(),拦截器 invoke()方法发现 a.getB()是null 值,那么就会单独发送事先保存好的查询关联 B 对象的 sql,把 B 查询上来,然后调用 a.setB(b),于是 a 的对象 b 属性就有值了,接着完成 a.getB().getName()方法的调用。这就是延迟加载的基本原理。
当然了,不光是 Mybatis,几乎所有的包括 Hibernate,支持延迟加载的原理都 是一样的。

Mybatis 的一级、二级缓存

一级缓存是 SqlSession 级别的缓存,生命周期短暂但可以提高单个 SqlSession 中的查询性能;而二级缓存是多个 SqlSession 共享的缓存,可以跨 SqlSession 进行数据共享,但需要注意缓存数据的一致性

一级缓存:SqlSession级别的缓存,缓存的数据只在SqlSession内有效。

二级缓存:mapper级别的缓存,同一个namespace公用这一个缓存,所以对SqlSession是共享的,二级缓存需要我们手动开启。

什么是MyBatis的接口绑定?有哪些实现方式?

MyBatis 的接口绑定是指将 Mapper 接口与对应的 SQL 映射关系进行绑定

在 MyBatis 中,有以下几种实现接口绑定的方式:

XML 配置方式:

最早的 MyBatis 版本中,通常使用 XML 配置文件来定义 Mapper 接口与 SQL 语句的映射关系。在 XML 配置文件中,使用 <mapper> 标签定义 Mapper 接口,并在其中通过 <select>、<insert>、<update>、<delete> 等标签配置对应的 SQL 语句。然后,在 MyBatis 的配置文件中引入这个 XML 配置文件,使其生效。 注解方式:

自从 MyBatis 3.0 版本开始,支持使用注解方式来进行接口绑定。通过在 Mapper 接口的方法上添加对应的注解,如 @Select、@Insert、@Update、@Delete 等,直接在注解中定义 SQL 语句。这样,无需额外的 XML 配置文件,即可实现接口与 SQL 语句的映射。 基于 Java 动态代理:

MyBatis 在运行时会根据 Mapper 接口的定义,使用 Java 动态代理技术动态生成接口的实现类。在动态代理中,实现类会根据接口方法名找到对应的 SQL 语句进行执行,将执行结果返回给调用方。这种方式是 MyBatis 默认的接口绑定实现方式。

使用MyBatis的mapper接口调用时有哪些要求?

Mapper 编写有哪几种方式?

简述Mybatis的插件运行原理,以及如何编写一个插件。

MyBatis实现一对一有几种方式?具体怎么操作的?

Spring面试题:

Spring AOP and AspectU AOP有什么区别?

实现方式:

Spring AOP 是基于代理的 AOP 实现,它通过动态代理来实现 AOP 功能。Spring AOP 只能针对 Spring 管理的 Bean 进行 AOP 增强。
AspectJ AOP 是基于字节码的 AOP 实现,它通过在编译阶段或运行时修改类的字节码来实现 AOP 功能。AspectJ AOP 可以支持任何普通的 Java 对象,不依赖于 Spring 容器。 粒度:

Spring AOP 主要关注于方法级别的切面(method-level),可以很方便地对方法进行拦截、增强。
AspectJ AOP 支持更细粒度的切面,可以在字段、构造函数、静态代码块等更多的地方进行切面操作,提供了更灵活的切面功能。

Spring AOP 和 AspectJ AOP 的主要区别在于它们的实现方式、性能和功能。

首先,Spring AOP 是基于动态代理技术实现的,它可以在运行时动态地生成代理对象,从而实现 AOP。这种方式的优点是可以在不改变原有代码的情况下实现 AOP,但是它只能代理接口,而不能代理类,因此它的功能比 AspectJ AOP 有所限制。 相反,AspectJ AOP 是一个更加强大和灵活的 AOP 框架,它使用静态织入技术,在编译阶段将 AOP 代码织入到目标类中。这种方式可以代理类和接口,并且可以支持更加细粒度的切面,例如可以对类的具体方法进行切面。但是这种方式需要使用特定的编译器和工具,对项目的侵入性比较大。

其次,Spring AOP 在性能上要比 AspectJ AOP 更高效,因为它使用的是动态代理技术,可以在运行时动态生成代理对象,而 AspectJ AOP 则需要在编译阶段将切面织入到目标类中,这样会增加一定的启动时间和内存开销。

最后,AspectJ AOP 拥有更加丰富的切入点表达式,支持更加灵活的切面定义。同时它也提供了更多的通知类型,如前置通知、后置通知、环绕通知、抛出异常通知等,能够更加细粒度地控制 AOP 的逻辑。

如何理解Spring中的代理?

参考 blog.csdn.net/NZC2237/art…

什么是编织(Weaving) ?

Spring MVC框架有什么用?

Spring MVC 框架是 Spring Framework 中的一个模块,用于构建 Web 应用程序。它提供了一种基于 MVC(Model-View-Controller)设计模式的方式来开发 Web 应用,将应用程序的逻辑分离成不同的部分,使得代码更加清晰、灵活和易于维护。

以下是 Spring MVC 框架的一些主要作用和功能:

MVC 设计模式:Spring MVC 遵循经典的 MVC 设计模式,将应用程序分为模型(Model)、视图(View)、控制器(Controller)三个部分,实现业务逻辑、用户界面和请求处理之间的松耦合,提高代码的可维护性和可扩展性。

请求处理:Spring MVC 提供了强大的请求处理机制,可以根据 URL 映射到对应的控制器方法,并支持各种参数绑定、数据验证等功能,简化了请求的处理过程。

灵活的视图解析:Spring MVC 支持多种视图解析器,可以方便地渲染不同类型的视图,如 JSP、Thymeleaf、FreeMarker 等,使开发者能够根据需求选择合适的视图技术。

拦截器:Spring MVC 提供了拦截器(Interceptor)机制,可以在请求处理前后执行一些额外的逻辑,如权限验证、日志记录等,增强了应用程序的灵活性和可定制性。

数据绑定和验证:Spring MVC 支持将请求参数自动绑定到方法参数或对象属性上,并提供了数据验证功能,可以通过注解或配置来验证输入数据的合法性,减少了开发人员的工作量。

RESTful 支持:Spring MVC 对 RESTful 风格的 Web 服务提供了良好的支持,可以轻松地创建 RESTful API,并实现资源的 CRUD 操作。

描述一下DispatcherServlet的工作流程

前端控制器
其实也就是springmvc原理 待补充

介绍一下WebApplicationContext

WebApplicationContext 是 Spring 框架中的一个特殊类型的 ApplicationContext,用于在 Web 应用程序中加载和管理 Spring Bean。

什么是spring?

Spring 框架的核心特性包括:

IoC(Inverse of Control,控制反转)容器:
Spring 提供了一个 IoC 容器,负责管理应用程序中的对象(Bean),以及它们之间的依赖关系。通过 IoC 容器,开发者可以将对象的创建、配置和生命周期管理交由 Spring 框架来负责,从而实现松耦合和可维护的代码编写。

AOP(Aspect-Oriented Programming,面向切面编程)支持:
Spring 提供了 AOP 的功能,允许开发者通过切面(Aspect)来实现对横切关注点的模块化,例如日志记录、事务管理等。使用 Spring AOP,开发者能够更好地分离关注点,并在不同模块之间实现复用和解耦。

使用Spring框架的好处是什么?

模块化 好扩展

Spring由哪些模块组成?

Spring Core Container\

spring aop
spring web
spring test

Spring的IOC和AOP机制

Spring中Autowired和Resource关键字的区别

autowired spring提供的 可以用在字段、构造方法、Setter 方法上

resourse java提供的 可以在非spring的框架中使用 只能用在字段上

依赖注入的方式有几种,各是什么?

构造器注入 setter方法注入 字段注入(@Autowire)

讲一下什么是Spring

Spring MVC流程

springMVC是什么

跟上面那个差不多

SpringMVC怎么样设定重定向和转发的?

SpringMVC常用的注解有哪些

RestController、RequestMapping、GetMapping、RequestBody、ResponseBody

Spring的AOP理解

在 Spring 中,AOP(面向切面编程)是一种编程范式,它允许将横切关注点(cross-cutting concerns)从应用程序的主业务逻辑中分离出来。横切关注点指的是那些在应用程序中多个模块中都存在的功能,比如日志记录、事务管理、安全控制等。

AOP 的核心思想是通过定义切面(Aspect),将这些横切关注点封装成可重用的模块,并在需要的时候将其织入到应用程序的特定连接点(join point)中。连接点可以是方法执行、异常抛出、类初始化等事件,切面定义了在连接点处执行的操作(advice)。

在 Spring 中,AOP 实现主要依赖于以下几个概念:

切面(Aspect):切面是一个模块化单元,它封装了横切关注点以及定义在这些关注点上执行的操作。切面通常包括切点、通知和引入。

连接点(Join Point):连接点是在应用程序执行期间可以插入切面的点,比如方法执行时、异常抛出时等。

切点(Pointcut):切点指定了在哪些连接点上应用切面的逻辑。通过表达式或者其他方式定义切点,以匹配连接点。

通知(Advice):通知定义了在连接点上执行的操作。Spring 支持多种类型的通知,包括前置通知(@Before)、后置通知(@After)、环绕通知(@Around)、异常通知(@AfterThrowing)和返回通知(@AfterReturning)等。

切面织入(Weaving):织入是将切面与应用程序的目标对象连接起来创建代理对象的过程。Spring 支持多种织入方式,包括编译时织入、类加载时织入、运行时织入等。

通过 AOP,可以实现诸如日志记录、性能监控、事务管理等横切关注点的重用,提高了代码的模块化程度和可重用性。Spring 提供了强大的 AOP 支持,使得开发人员可以轻松地实现横切关注点的管理和维护,同时将核心业务逻辑和横切关注点有效地解耦。

Spring的IOC理解

在 Spring 框架中,IOC(Inverse of Control,控制反转)是一种设计原则和编程模式,它通过将对象的创建、依赖关系的管理和对象的生命周期等任务交给容器来完成,从而实现了对象之间的松耦合和可维护性。

传统的编程方式中,对象的创建和管理通常由开发人员手动完成,对象之间的依赖关系也需要开发人员显式地进行维护。而在 Spring 的 IOC 容器中,对象的创建和管理完全由容器负责,开发人员只需描述对象之间的依赖关系,将对象的创建和依赖注入的工作交给容器处理。

IOC 容器在 Spring 中的核心实现是 BeanFactory 接口,它负责创建和管理对象,以及处理对象之间的依赖关系。开发人员可以通过配置文件(如 XML 文件)或者注解的方式告诉 IOC 容器需要创建哪些对象、对象之间的依赖关系以及其他的配置信息。

IOC 的优势在于:

松耦合:IOC 将对象之间的依赖关系交给容器管理,对象只需要关注自身的业务逻辑,不需要关心如何创建和获取依赖对象,从而降低了对象之间的耦合度。

可维护性:通过使用 IOC 容器,可以将对象的创建、依赖关系的管理和配置信息集中在容器中,使得代码更加易于维护和扩展。

可测试性:IOC 可以方便地进行单元测试,因为依赖对象可以通过模拟或者替代实现来进行注入。

重用性:IOC 容器可以管理对象的生命周期,并提供对象的池化机制,从而提高对象的重用性和性能。

总之,IOC 是一种通过将对象的创建和依赖关系的管理交给容器来实现松耦合和可维护性的编程模式。Spring 的 IOC 容器为开发人员提供了方便的对象管理和依赖注入机制,使得开发更加简单、灵活和高效。

解释一下spring bean的生命周期

Spring 中的 Bean 生命周期包括实例化、属性注入、初始化、使用和销毁等阶段。下面是 Spring Bean 的生命周期的详细解释:

实例化(Instantiation):在这个阶段,容器会根据配置信息或者注解创建 Bean 的实例。这个阶段可能涉及到构造函数的调用或者工厂方法的调用来创建对象。

属性注入(Populate Properties):在实例化之后,容器会对 Bean 的属性进行注入。这包括使用构造函数注入、Setter 方法注入或者字段注入等方式来设置 Bean 的属性值。

初始化(Initialization):在属性注入完成之后,容器会调用 Bean 的初始化方法来执行一些额外的初始化操作。初始化方法可以通过实现 InitializingBean 接口、添加 @PostConstruct 注解或者在配置文件中指定初始化方法来定义。

使用(In Use):在初始化完成之后,Bean 就可以被容器使用了,它可以处理业务逻辑、响应请求等。

销毁(Destruction):在 Bean 不再需要的时候,容器会调用 Bean 的销毁方法来执行一些清理操作。销毁方法可以通过实现 DisposableBean 接口、添加 @PreDestroy 注解或者在配置文件中指定销毁方法来定义。

Spring 容器负责管理 Bean 的整个生命周期,开发人员可以通过配置文件或者注解来定义 Bean 的初始化方法和销毁方法,以及其他的配置信息。这种生命周期管理机制使得 Bean 的创建、初始化和销毁过程更加灵活和可控,同时也方便了开发人员对 Bean 的管理和维护。

总之,Spring Bean 的生命周期包括实例化、属性注入、初始化、使用和销毁等阶段,容器负责管理 Bean 的整个生命周期,开发人员可以通过配置文件或者注解来定义 Bean 的初始化方法和销毁方法。

解释Spring支持的几种bean的作用域。

Spring框架支持以下五种bean的作用域:

1.singleton :bean在每个Spring ioc 容器中只有一个实例。

2.prototype:一个bean的定义可以有多个实例。

3.request:每次http请求都会创建一个bean,该作用域仅在基于web的Spring ApplicationContext情形下有效。

4.session:在一个HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。

5.global-session:在一个全局的HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。

简要回答:
1.singleton(单例模式)
2.prototype(原型模式)
3.request(HTTP请求)
4.session(会话)
5.global-session(全局会话)

Spring基于xml注入bean的几种方式

在 Spring 中,可以使用 XML 配置文件来定义和注入 Bean。以下是基于 XML 注入 Bean 的几种方式:

构造函数注入:

使用 <constructor-arg> 元素在 XML 配置文件中指定构造函数参数。

<bean id="myBean" class="com.example.MyBean">
    <constructor-arg value="parameterValue" />
</bean>

属性注入:

使用 <property> 元素在 XML 配置文件中指定属性值。

<bean id="myBean" class="com.example.MyBean">
    <property name="propertyName" value="propertyValue" />
</bean>

集合注入:

使用 <list>、<set>、<map> 等元素在 XML 配置文件中指定集合类型的属性值。

<bean id="myBean" class="com.example.MyBean">
    <property name="propertyName">
        <list>
            <value>value1</value>
            <value>value2</value>
        </list>
    </property>
</bean>

引用注入:

使用 <ref> 元素在 XML 配置文件中指定对其他 Bean 的引用。

<bean id="myBean1" class="com.example.MyBean1" />

<bean id="myBean2" class="com.example.MyBean2">
    <property name="otherBean" ref="myBean1" />
</bean>

自动装配注入:

使用 <bean> 元素的 autowire 属性来启用自动装配功能。

<bean id="myBean1" class="com.example.MyBean1" autowire="byName" />

<bean id="myBean2" class="com.example.MyBean2" autowire="byType" />

Spring框架中都用到了哪些设计模式

工厂模式(Factory Pattern):

Spring 使用工厂模式来管理 Bean 的创建和调用,通过工厂模式可以将对象的创建与使用解耦,实现了松耦合。

单例模式(Singleton Pattern):

Spring 默认情况下管理的 Bean 是单例的,即每个 Bean 在容器中只有一个实例,这种方式可以减少资源消耗。

代理模式(Proxy Pattern):

Spring AOP(面向切面编程)中使用代理模式来实现横切关注点的功能,如事务管理、日志记录等。

观察者模式(Observer Pattern):

Spring 的事件机制基于观察者模式,通过 ApplicationEvent 和 ApplicationListener 来实现事件的发布和监听。

模板模式(Template Pattern):

Spring 中的 JdbcTemplate、RestTemplate 等都使用了模板模式,定义了算法的骨架,具体实现由子类完成。

策略模式(Strategy Pattern):

Spring 中的资源访问策略、事务管理策略等功能使用了策略模式,允许在运行时选择算法。

建造者模式(Builder Pattern):

在 Spring 中,通过建造者模式来构建复杂的对象或配置,如使用 BeanDefinitionBuilder 构建 Bean 定义。

适配器模式(Adapter Pattern):

Spring 中的适配器模式用于连接不同接口的组件,如 HandlerAdapter 用于适配不同类型的 Controller。

依赖注入模式(Dependency Injection Pattern):

Spring 的核心特性之一就是依赖注入,通过依赖注入实现了对象之间的解耦,降低了组件之间的耦合度。

核心容器(应用上下文)模块

这是基本的Spring 模块,提供spring框架的基础功能,BeanFactory是任何以spring为基础的应用的核心。Spring 框架建立在此模块之上,它使Spring成为一个容器

BeanFactory 接口:

BeanFactory 是 Spring 框架中最基本的接口,提供了访问 Bean 的方法。它定义了获取 Bean、判断 Bean 是否存在等操作。

ApplicationContext 接口:

ApplicationContext 是 BeanFactory 接口的子接口,也是 Spring 框架中最重要的接口之一。它提供了更多的功能,如国际化支持、事件发布、资源加载等。

BeanFactory - BeanFactory实现举例。

XML BeanFactory

解释AOP模块

Spring Boot面试题:

我们能否在spring-boot-starter-web中用jetty代替tomcat?

SpringBoot允许您很容易地切换和配置不同的内嵌式 Servlet 容器

如何使用Spring Boot生成一个WAR文件?

1 修改打包方式
war

2 需要继承 SpringBootServletInitializer 类并覆写其 configure(SpringApplicationBuilder application) 方法,通过该方法指定 @SpringBootApplication 所在类。

@SpringBootApplication
public class DemoApplication extends SpringBootServletInitializer{

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application){
        //指定 @SpringBootApplication 所在类
        return application.sources(DemoApplication.class);
    }
}

3 进行构建 mvn clean package

参考 springdoc.cn/spring-boot…

如何使用Spring Boot部署到不同的服务器?

RequestMapping和GetMapping的不同之处在哪里?

为什么我们不建议在实际的应用程序中使用Spring Data Rest?

在Spring Initializer中,如何改变-个项目的包名字?

可以配置application.propertierde的完整的属性列表在哪里可以找到?

JPA 和Hibernate有哪些区别?

使用Spring Boot启动连接到内存数据库H2的JPA应用程序需!要哪些依赖项?

如何不通过任何配置来选择Hibernate作为JPA的默认实现?

指定的数据库连接信息在哪里?它是如何知道自动连接至H2的?

我们如何连接一个像MSSQL或者orcale一样的外部数据库?

Spring Boot配置的默认H2数据库的名字是上面?为什么默认的数据库名字是testdb?

如果H2不在类路径里面,会出现上面情况?

你能否举一个以ReadOnly为事务管理的例子?

发布Spring Boot用户应用程序自定义配置的最好方法是什么?

配置文件的需求是什么?

如何使用配置文件通过Spring Boot配置特定环境的配置?

我们如何使用Maven设置Spring Boot应用程序?

如何禁用特定的自动配置?

Spring boot支持哪些外部配置?

如何对Spring Boot应用进行测试?

Spring Boot Actuator有什么用?

实现对程序运行监控
可以反应应用健康状况、性能指标、日志信息等

SpringBoot 中静态首页默认位置可以放在哪里?

src/main/resources/static/:在 Spring Boot 项目中,可以将静态资源文件(如 HTML、CSS、JavaScript 文件)放置在 src/main/resources/static/ 目录下。如果您将 index.html 放置在这个目录下,Spring Boot 将会将其作为默认的首页。

src/main/resources/public/:类似于 src/main/resources/static/,您也可以将静态资源文件放置在 src/main/resources/public/ 目录下。同样地,如果将 index.html 放置在这个目录下,Spring Boot 也会将其作为默认的首页。

src/main/resources/META-INF/resources/:在 Spring Boot 2.0 及更高版本中,您还可以将静态资源文件放置在 src/main/resources/META-INF/resources/ 目录下。同样地,将 index.html 放置在这个目录下,Spring Boot 会将其作为默认的首页。

SpringBoot中静态资源直接映射的优先级是怎样的?

Spring Cloud面试题:

SpringBoot和SpringCloud的区别?

定位不同: Spring Boot旨在简化单个Spring应用程序的开发和部署,而Spring Cloud则专注于构建和管理分布式系统中的各种微服务。

功能不同: Spring Boot主要提供了简化配置和快速开发的功能,而Spring Cloud则提供了服务注册与发现、负载均衡、断路器等微服务架构中需要的功能。

什么是Hystrix断路器?我们需要它吗

Hystrix 断路器的主要作用是在服务调用过程中监控服务的状态,并根据设定的条件来判断是否打开断路器。当服务出现故障或响应时间过长时,断路器会自动打开,之后所有对该服务的请求都会被短路,不再发起实际的服务调用。同时,断路器还会定期尝试关闭,以检测服务是否恢复正常。如果服务恢复正常,则断路器会自动关闭,请求重新发起。

使用 Hystrix 断路器的好处包括:

故障容错:当某个服务不可用或响应延迟过高时,断路器可以快速短路请求,防止故障扩散到整个系统,提高系统的稳定性和可靠性。

服务降级:当服务出现问题时,可以通过断路器的配置返回一个备选的默认值或执行备选的逻辑,以保证系统的可用性。

实时监控:通过 Hystrix 提供的实时监控功能,可以了解服务的健康状态、错误率、响应时间等指标,方便进行系统调优和故障排查。

说说RPC的实现原理

主要有以下几个步骤:

1、建立通信

首先要解决通讯的问题:即A机器想要调用B机器,首先得建立起通信连接。主要是通过在客户端和服务器之间建立TCP连接,远程过程调用的所有相关的数据都在这个连接里面进行传输交换。

通常这个连接可以是按需连接(需要调用的时候就先建立连接,调用结束后就立马断掉),也可以是长连接(客户端和服务器建立起连接之后保持长期持有,不管此时有无数据包的发送,可以配合心跳检测机制定期检测建立的连接是否存活有效),多个远程过程调用共享同一个连接。

2、服务寻址

解决寻址的问题:即A机器上的应用A要调用B机器上的应用B,那么此时对于A来说如何告知底层的RPC框架所要调用的服务具体在哪里呢?

通常情况下我们需要提供B机器(主机名或IP地址)以及特定的端口,然后指定调用的方法或者函数的名称以及入参出参等信息,这样才能完成服务的一个调用。比如基于Web服务协议栈的RPC,就需要提供一个endpoint URI,或者是从UDDI服务上进行查找。如果是RMI调用的话,还需要一个RMI Registry来注册服务的地址。

3、网络传输

3.1、序列化

当A机器上的应用发起一个RPC调用时,调用方法和其入参等信息需要通过底层的网络协议如TCP传输到B机器,由于网络协议是基于二进制的,所有我们传输的参数数据都需要先进行序列化(Serialize)或者编组(marshal)成二进制的形式才能在网络中进行传输。然后通过寻址操作和网络传输将序列化或者编组之后的二进制数据发送给B机器。

3.2、反序列化

当B机器接收到A机器的应用发来的请求之后,又需要对接收到的参数等信息进行反序列化操作(序列化的逆操作),即将二进制信息恢复为内存中的表达方式,然后再找到对应的方法(寻址的一部分)进行本地调用(一般是通过生成代理Proxy去调用, 通常会有JDK动态代理、CGLIB动态代理、Javassist生成字节码技术等),之后得到调用的返回值。

4、服务调用

B机器进行本地调用(通过代理Proxy)之后得到了返回值,此时还需要再把返回值发送回A机器,同样也需要经过序列化操作,然后再经过网络传输将二进制数据发送回A机器,而当A机器接收到这些返回值之后,则再次进行反序列化操作,恢复为内存中的表达方式,最后再交给A机器上的应用进行相关处理(一般是业务逻辑处理操作)。

通常,经过以上四个步骤之后,一次完整的RPC调用算是完成了,另外可能因为网络抖动等原因需要重试等。

参考 blog.csdn.net/qq_18671415…

微服务的优点缺点?说下开发项目中遇到的坑?

优点:

松耦合,聚焦单一业务功能,无关开发语言,团队规模降低。在开发中,不需要了解多有业务, 只专注于当前功能,便利集中,功能小而精。微服务一个功能受损,对其他功能影响并不是太大,可以快速定位问题。 微服务只专注于当前业务逻辑代码,不会和 html、css 或其他界面进行混合。可以灵活搭配技术,独立性比较舒服。

缺点:

随着服务数量增加,管理复杂,部署复杂,服务器需要增多,服务通信和调用压力增大,运维工程师压力增大, 人力资源增多,系统依赖增强,数据一致性,性能监控。

坑: 需要注意发版顺序,不同服务的版本管理和升级需要考虑兼容性和影响范围

服务通信问题:不同服务之间的通信需要考虑各种情况,如超时、重试、熔断等

spring cloud 和dubbo区别?

REST和RPC对比

你所知道的微服务技术栈?

微服务之间是如何独立通讯的?

springcloud如何实现服务的注册?

Eureka和Zookeeper区别

cap c一致性 a可用性 p分区容错性

eureka自我保护机制是什么?

如果 Eureka 服务器在一定时间内没有收到实例的心跳信息,它不会立即将该实例从服务列表中剔除,而是进入自我保护模式。自我保护模式下,Eureka 服务器会认为服务仍然可用,不会将其标记为失效。

什么是Ribbon?

负载均衡:Ribbon 可以根据配置的负载均衡策略(如轮询、加权轮询、随机等)自动将请求分发到多个服务提供者实例上,从而实现客户端的负载均衡。

什么是feigin?它的优点是什么?

Ribbon和Feign的区别?

feign内置了ribbon

什么是Spring Cloud Bus?

springcloud断路器作用?

Spring Cloud Gateway?

作为服务注册中心,Eureka比Zookeeper好在哪里?

什么是Ribbon负载均衡?

主要提供了负载均衡算法
消费者端加入@LoadBalanced\

@Bean
	@LoadBalanced
	public RestTemplate getRestTemplate() {
		return new RestTemplate();
	}

Ribbon负载均衡能干什么?

Ribbon 是 Netflix 开源的负载均衡组件,主要用于在微服务架构中实现客户端负载均衡。通过 Ribbon,可以将客户端的请求动态地分发到多个后端服务实例上,以提高系统的性能、可用性和扩展性。以下是 Ribbon 负载均衡能够实现的功能:

负载均衡:Ribbon 可以根据配置的负载均衡策略(如轮询、随机、加权轮询、加权随机等)自动将请求分发到多个后端服务实例上,实现负载均衡。

容错处理:Ribbon 支持容错处理,当某个服务实例出现故障或不可用时,可以自动切换到其他可用的服务实例,确保系统的稳定性和可靠性。

重试机制:Ribbon 支持请求重试机制,在发生请求失败或超时时,可以自动重试请求,减少因网络波动或服务不稳定性导致的问题。

性能监控:Ribbon 可以集成监控系统,实时监控各个服务实例的性能指标和状态,帮助开发人员及时发现问题并采取措施。

自定义策略:Ribbon 允许开发人员自定义负载均衡策略和规则,根据实际需求调整负载均衡的行为。

集成性:Ribbon 能够与各种微服务架构和服务注册中心(如 Eureka、Consul 等)无缝集成,实现更灵活、可扩展的微服务架构。

什么是zuul路由网关

Zuul 路由网关主要用于服务转发、负载均衡、认证、安全等功能,是微服务架构中的一个重要组件

分布式配置中心能干嘛?

集中管理配置
动态更新配置
管理配置版本
配置共享
环境隔离
安全

微服务 面试题:

Container在微服务中的用途是什么?

指的是容器化部署
隔离环境
部署简化
弹性伸缩
资源利用
持续交付

什么是微服务架构中的DRY?

“DRY” 是指 “Don't Repeat Yourself”,即不要重复自己。这是一项软件开发原则,旨在避免在系统中重复相同的逻辑或信息,以减少代码重复、降低维护成本并提高系统的可维护性。

什么是消费者驱动的合同(CDC) ?

Web, RESTful API在微服务中的作用是什么?

前后端分离
服务暴露访问
接口标准化
等等

您对微服务架构中的语义监控有何了解?

我们如何进行跨功能测试?

我们如何在测试中消除非决定论?

Mock或Stub有什么区别?

您对Mike Cohn的测试金字塔了解多少?

Docker的目的是什么?

实现快速灵活的部署
方便保持环境一致
实现资源隔离和安全性

什么是金丝雀释放?

金丝雀释放(Canary Release)是一种软件部署和发布策略,通过逐步将新版本的应用程序或功能引入生产环境

什么是持续集成(CI) ?

持续集成(Continuous Integration,CI)是一种软件开发实践,旨在通过频繁地将代码变更集成到共享存储库中,并自动进行构建和测试,以便尽早地发现和解决集成问题。持续集成的主要目标是加快软件开发周期,减少集成问题,提高软件质量。
在持续集成过程中,开发人员会频繁地将代码提交到版本控制系统中(如Git),然后触发自动化构建工具(如Jenkins、Travis CI等)来自动构建整个应用程序,并运行各种自动化测试(单元测试、集成测试等)。如果构建或测试失败,团队将立即收到通知,可以及时定位和修复问题。

什么是持续监测?

架构师在微服务架构中的角色是什么?

我们可以用微服务创建状态机吗?

什么是微服务中的反应性扩展?

数据结构面试题:

栈(stack)

先进后出

队列(queue)

先进先出

链表(Link)

链表是一种常见的线性数据结构,它由一系列节点组成,每个节点包含数据项和指向下一个节点的引用(指针)。链表可以分为单向链表和双向链表两种类型。

散列表(Hash Table)

排序二叉树

前缨树

红黑树

自平衡的二叉树

B-TREE

平衡的多路搜索树

位图bitmap

位图(Bitmap)是一种用于表示图像的二维栅格图形,也称为点阵图像。在位图图像中,图像被分割为一个个小的像素(或称为点),每个像素都有自己的颜色值,用来描述该点的颜色和位置信息。

算法面试题:

数据里有{1,2,3,4,5,6,7,8,9}. 请随机打乱顺序,生成一个新的数组(请以代码实现)

Collections.shuffle(list);

写出代码判断一个整数是不是2的阶次方(请代码实现,谢绝调用API方法)

    return (num & (num - 1)) == 0;

假设今日是2015年3月1日,星期日,请算出13个月及6天后是星期几,距离现在多少天(请用代码实现,谢绝调用API方法)

有两个篮子,分别为A和B,篮子A里装有鸡蛋,篮子B里装有苹果,请用面向对象的思想实现两个篮子里的物品交换(请用代码实现)

二分查找

冒泡排序算法

插入排序算法

快速排序算法

希尔排序算法

归并排序算法

桶排序算法

基数排序算法

剪枝算法

回溯算法

最短路径算法

最小生成树算法

AES

RSA

CRC

MD5

更多算法练习

Kafka 面试题:

Consumer Group

在消息队列系统中,Consumer Group(消费者组)是一种组织结构,用于协调和管理消息消费者的工作。Consumer Group 可以包含多个消费者实例,这些实例共同消费同一个主题(topic)下的消息。

如何获取topic主题的列表

./kafka-topics.sh --list --zookeeper <zk_host>:<zk_port>

其中 <zk_host> 和 <zk_port> 是 Zookeeper 的主机名和端口号,用于管理 Kafka 集群的元数据信息。

生产者和消费者的命令行是什么?

生产者发送消息到指定主题:

./kafka-console-producer.sh --broker-list <broker_host>:<broker_port> --topic <topic_name>

<broker_host> 和 <broker_port> 是 Kafka 集群中 Broker 的主机名和端口号。
<topic_name> 是要发送消息的目标主题名称。

消费者订阅指定主题接收消息:

./kafka-console-consumer.sh --bootstrap-server <broker_host>:<broker_port> --topic <topic_name> --from-beginning

<broker_host> 和 <broker_port> 是 Kafka 集群中 Broker 的主机名和端口号。
<topic_name> 是要消费消息的主题名称。
--from-beginning 参数表示从该主题的起始位置开始消费消息。

consumer是推还是拉?

在 Apache Kafka 中,消费者可以使用拉(pull)或推(push)的方式来获取消息,取决于消费者的实现方式。

Kafka 提供了两种主要的消费者模型:

拉(Pull)模式:

在拉模式中,消费者根据自己的节奏从 Kafka 集群中主动拉取消息。
消费者通过定期轮询 Kafka 主题的分区来获取消息,并控制拉取消息的速率。
这种模式下,消费者可以根据自身处理能力和需求来灵活控制消息的获取速度。\

推(Push)模式:

在推模式中,Kafka 服务器会将消息推送给消费者,消费者不需要主动请求获取消息。
Kafka 0.9 版本引入了基于消费者组(Consumer Group)的推模式,消费者加入消费者组后,Kafka 服务器会将消息均匀地推送给各个消费者。
消费者组内的消费者之间会协调处理消息分配,确保每条消息只被消费者组内的一个消费者处理。
综上所述,Kafka 的消费者既支持拉模式也支持推模式,可以根据实际需求选择合适的消费者模式。通常情况下,消费者组使用推模式,而单个消费者可以使用拉模式来控制消息的获取速率。

讲讲kafka维护消费状态跟踪的方法

讲一下主从同步

为什么需要消息系统,mysql 不能满足需求吗?

消息系统可以实现异步、解耦合

Zookeeper对于Kafka的作用是什么?

在 Apache Kafka 中,ZooKeeper 扮演着关键的角色,主要用于以下几个方面:

协调服务:

ZooKeeper 作为分布式协调服务,帮助 Kafka 集群中的各个节点进行协调和通信。
Kafka 使用 ZooKeeper 来进行领导者选举、分区分配、偏移量管理等关键操作。\

集群元数据存储:

Kafka 的集群元数据(包括主题、分区、副本配置等)会被存储在 ZooKeeper 中。
消费者通过 ZooKeeper 获取集群元数据信息,以便正确地连接到 Kafka 集群并进行消费。
偏移量管理:

消费者组的偏移量信息也会被存储在 ZooKeeper 中。
消费者会定期将偏移量提交到 ZooKeeper,以便在需要时恢复消费者的状态。 故障检测和恢复:

ZooKeeper 可以帮助 Kafka 集群检测节点的故障,并协助进行故障恢复操作。
当 Kafka 节点发生故障或重启时,ZooKeeper 可以协助集群进行自动的恢复过程。 总的来说,ZooKeeper 在 Kafka 中扮演着类似于分布式协调器和元数据存储的角色,帮助 Kafka 集群实现高可用性、容错性和可靠性。Kafka 依赖于 ZooKeeper 来管理集群状态、元数据信息和偏移量,确保整个系统的稳定运行。

Kafka判断一个节点是否还过着有那两个条件?

Kafka与传统MQ消息系统之间有三个关键区别

Kafka 与传统消息队列(MQ)系统之间的三个关键区别包括:

存储机制:

传统 MQ:传统的消息队列系统通常采用内存存储消息,因此对于瞬时性的消息传递有很好的性能,但对于长期存储和回溯能力有限。 Kafka:Kafka 则采用基于磁盘的持久化存储机制,允许大规模数据的持久化存储和高效的消息回溯,适用于构建实时流处理和大规模数据分发系统。 消费者模型:

传统 MQ:传统消息队列通常采用拉取(pull)模式,消费者需要主动从队列中拉取消息来进行处理。 Kafka:Kafka 引入了发布-订阅(publish-subscribe)模式,允许多个消费者以并行的方式订阅同一个主题,消费者之间可以共享消息处理的负载,提高了消息处理的并发性能。 数据处理:

传统 MQ:传统消息队列通常用于异步通信、解耦系统组件等场景,适合于实时性较强的消息传递和处理。 Kafka:Kafka 更注重流式处理和数据持久化,可以支持大规模数据的实时流处理、数据分发和数据回溯,适用于构建实时数据管道和流式处理平台。 综上所述,Kafka 与传统消息队列在存储机制、消费者模型和数据处理方面存在明显的区别。Kafka 更适合于构建实时流处理平台、大规模数据分发系统以及数据回溯场景,而传统消息队列则更适合于一些对实时性要求较高的异步通信、解耦系统组件等场景。根据具体的业务需求和系统架构设计,可以选择合适的消息系统来满足不同的需求。

讲一讲kafka的ack的三种机制

在 Kafka 中,生产者发送消息到 Kafka 时,可以通过设置不同的 ACK(Acknowledgment)机制来控制消息的可靠性和吞吐量。Kafka 支持三种主要的 ACK 机制,分别是:

acks=0:

生产者在发送消息后不会等待任何来自服务器的响应,直接将消息发送到主题的分区中。 这种模式下,生产者不会知道消息是否成功写入 Kafka,存在丢失消息的风险,适用于对消息丢失要求不高的场景。 acks=1:

生产者在发送消息后会等待 Leader 分区确认消息的写入成功,然后继续发送下一条消息。 当 Leader 分区确认消息已写入成功后,生产者会收到响应,表示消息已经得到了处理。 这种模式下,如果 Leader 分区写入成功但 Followers 尚未同步完成,可能存在消息丢失的风险。 acks=all(或 acks=-1):

生产者在发送消息后会等待 Leader 分区以及所有 Followers 分区都确认消息的写入成功,才会继续发送下一条消息。 只有当所有副本都成功写入消息后,生产者才会收到成功的响应。 这种模式下,具有最高的数据完整性保证,但会影响生产者的吞吐量。 选择合适的 ACK 机制取决于业务需求和对消息可靠性的要求。如果对消息的可靠性要求不高,可以选择 acks=0;如果需要较高的可靠性但可以容忍部分消息丢失,可以选择 acks=1;如果要求最高的数据完整性和不允许任何消息丢失,可以选择 acks=all。根据业务场景和需求,灵活选择合适的 ACK 机制可以有效平衡消息传输的可靠性和性能。

消费者如何不自动提交偏移量,由应用提交?

消费者故障,出现过锁问题如何解决?

如何控制消费的位置

Elasticsearch 面试题

Elasticsearch 在部署时,对Linux的设置有哪些优化方法

ucence内部结构是什么?

Elasticsearch 是如何实现Master选举的?

Elasticsearch中的节点(比如共20个),其中的10个选

个master, 另外10个选了另一个master, 怎么办?

客户端在和集群连接时,如何选择特定的节点执行请求的?

详细描述一下Elasticsearch索引文档的过程。

详细描述一下Elasticsearch 更新和删除文档的过程。

详细描述一 下Elasticsearch 搜索的过程

在Elasticsearch中,是怎么根据一个词找到对应的倒排索

Elasticsearch在部署时,对Linux的设置有哪些优化方法?

对于GC方面,在使用Elasticsearch时要注意什么?

Elasticsearch对于大数据量( 上亿量级)的聚合如何实现?

在并发情况下,Elasticsearch 如何保证读写一致?

如何监控Elasticsearch集群状态?

介绍下你们电商搜索的整体技术架构

介绍一下你们的个性化搜索方案?

是否了解字典树?

拼写纠错是如何实现的?

MongoDB面试题:

当更新-个正在被迁移的块(Chunk). 上的文档时会发生什么?

MongoDB在A:(B,C}上建立索引,查询A:{B,C]和A:{C,B)都会使用索引吗?

如果一个分片(Shard) 停止或很慢的时候,发起一个查询会怎样?

MongoDB支持存储过程吗?如果支持的话,怎么用?

如何理解MongoDB中的GridFS机制,MongoDB为何使用GridFS来存储文件?

什么是NoSQL数据库? NoSQL和RDBMS有什么区别?在哪些情况下使用和不使用NoSQL数据库?

MongoDB支持存储过程吗?如果支持的话,怎么用?

如何理解MongoDB中的GridFS机制,MongoDB为何使用GridFS来存储文件?

为什么MongoDB的数据文件很大?

当更新-个正在被迁移的块(Chunk) 上的文档时会发生什么?

MongoDB在A:(B,C}上建立索引,查询A:{B,C]和A:{C,B)都会使用索引吗?

如果一个分片(Shard) 停止或很慢的时候,发起一个查询会怎样

分析器在MongoDB中的作用是什么?

如果用户移除对象的属性,该属性是否从存储层中删除?

能否使用日志特征进行安全备份?

更新操作立刻fsync到磁盘?

如何执行事务/加锁?

什么是master或primary?

getLasterror的作用

分片(sharding) 和复制(replication) 是怎样工作的?

数据在什么时候才会扩展到多个分片(shard) 里?

当我试图更新 一个正在被迁移的块(chunk) 上的文档时会发生什么?