长春市宽城区建设局网站,wordpress 优化,做视频网站版权怎么解决,一般通过人体的电流超过多大Java 基础
Java 中的序列化和反序列化是什么#xff1f;
序列化是将 Java 对象转换为字节流的过程#xff0c;以便可以将其存储在文件中或通过网络进行传输。反序列化则是将字节流恢复为 Java 对象的过程。通过实现 Serializable 接口#xff0c;Java 对象可以支持序列化。…Java 基础
Java 中的序列化和反序列化是什么
序列化是将 Java 对象转换为字节流的过程以便可以将其存储在文件中或通过网络进行传输。反序列化则是将字节流恢复为 Java 对象的过程。通过实现 Serializable 接口Java 对象可以支持序列化。
什么是 Java 中的不可变类
不可变类是指其对象一旦创建就不能被修改的类。Java 中的 String 类是一个典型的不可变类。不可变类通常通过
所有字段使用 final 修饰。没有 setter 方法。返回对象的属性时返回深拷贝。
Java 中 Exception 和 Error 有什么区别 Exception 和 Error 都是 Throwable 类的子类但它们有不同的含义
Exception 是可捕获的异常表示程序可以处理的异常情况。Error 是严重的错误通常是 JVM 级别的错误如内存不足程序无法恢复。比如
你认为 Java 的优势是什么
Java 的优势包括
跨平台性依赖 JVM 的“编译一次运行多处”。丰富的类库提供了丰富的标准库和第三方库支持。强大的社区支持有活跃的开发者社区。自动内存管理垃圾回收机制减少了内存泄漏问题。安全性内置的安全机制防止内存泄露和非法操作。
什么是 Java 的多态特性
多态是指同一个方法或对象在不同的上下文中表现出不同的行为。Java 支持两种多态
编译时多态方法重载。运行时多态通过继承与接口实现动态绑定。
Java 中的参数传递是按值还是按引用 Java 中的参数传递是按值传递的。对于基本数据类型传递的是数值的副本对于对象传递的是对象引用的副本但不影响原对象的引用地址。
public static void main(String[] args) {User user new User().setId(0L);long id 123L;System.out.println(user.getId());// 0setId(user, id);System.out.println(user.getId());// 123L
}private static void setId(User user, long id){user.setId(user, id);
}为什么 Java 不支持多重继承
Java 不支持类的多重继承因为它会导致“钻石问题”即多个父类具有相同的方法时子类无法决定调用哪一个方法。Java 通过接口解决了这一问题允许类实现多个接口。
Java 面向对象编程与面向过程编程的区别是什么
面向对象编程 (OOP)基于对象的概念强调封装、继承和多态通过对象交互来设计程序。面向过程编程以过程函数为中心强调任务的顺序和步骤。
Java 方法重载和方法重写之间的区别是什么
方法重载同一个类中定义多个同名方法但参数列表不同属于编译时多态。方法重写子类重新定义父类的方法方法签名相同属于运行时多态。
什么是 Java 内部类它有什么作用
内部类是在一个类的内部定义的类分为成员内部类、局部内部类、匿名内部类和静态内部类。作用包括
增加封装性。能够访问外部类的成员。实现接口时可以通过匿名内部类快速实现。
JDK8 有哪些新特性
JDK8 引入了多个重要的新特性
Lambda 表达式简化函数式编程。Stream API简化集合操作的功能。默认方法接口中可以包含有默认实现的方法。Optional 类避免 null 引发的 NullPointerException。
Java 中 String、StringBuffer 和 StringBuilder 的区别是什么
String不可变类每次修改都会创建新对象。StringBuffer可变类线程安全适用于多线程环境。StringBuilder可变类非线程安全适用于单线程环境性能优于 StringBuffer。
Java 的 StringBuilder 是怎么实现的
StringBuilder 是通过内部的可变字符数组实现的它通过动态扩展数组的大小来提高字符串拼接的效率。它的操作是非线程安全的因此适用于单线程环境。
Java 中包装类型和基本类型的区别是什么
基本类型是 Java 提供的内置类型例如 int、char直接存储数据值。包装类型是对应的类例如 Integer、Character用于封装基本类型并提供额外的功能。
接口和抽象类有什么区别
接口所有方法默认为抽象方法类可以实现多个接口。抽象类可以有具体实现的方法类只能继承一个抽象类。
JDK 和 JRE 有什么区别
JDKJava Development Kit是用于开发 Java 应用程序的工具包包含了编译器、调试工具等。JREJava Runtime Environment是用于运行 Java 程序的环境包含了 JVM 和运行库。
你使用过哪些 JDK 提供的工具
常用的 JDK 工具包括
javacJava 编译器。java运行 Java 应用程序的工具。javadoc生成 Java 文档的工具。jstack用于查看线程堆栈的工具。jmap用于生成堆转储的工具。
Java 中 hashCode 和 equals 方法是什么它们与 操作符有什么区别
hashCode返回对象的哈希值用于哈希表等数据结构。equals判断两个对象是否“逻辑上”相等。比较变量在栈中的值对象类型的值为引用地址。
Java 中的 hashCode 和 equals 方法之间有什么关系
在 Java 中两个对象如果通过 equals 方法判断相等那么它们的 hashCode 值必须相同。否则在使用哈希表时会出现问题。
什么是 Java 中的动态代理
动态代理允许在运行时为接口生成代理类并为代理类的方法调用提供自定义的处理逻辑。JDK 提供了 Proxy 类来实现动态代理。
JDK 动态代理和 CGLIB 动态代理有什么区别
JDK 动态代理只能为接口生成代理类。CGLIB 动态代理基于继承能够为类生成代理但不能代理 final 方法。
Java 中的注解原理是什么
Java 的注解是一种元数据注解通过反射在运行时被解析和处理。注解可以通过自定义注解和反射机制来实现自定义功能。
你使用过 Java 的反射机制吗如何应用反射
是的反射允许在运行时获取类的信息并操作类的字段和方法。常用于框架和库中例如对象的动态创建和方法调用。通过 Class、Method 等类来实现反射。
什么是 Java 的 SPIService Provider Interface机制
SPI 是 Java 提供的一种服务发现机制通过在 META-INF/services 目录下的配置文件声明服务接口的实现类允许模块化应用程序动态加载服务提供者。
Java 泛型的作用是什么
泛型允许类、接口和方法能够操作任意类型的数据提供了编译时类型检查并避免了强制类型转换。
Java 泛型擦除是什么
泛型擦除是指 Java 在编译时会移除泛型类型信息在运行时泛型类型信息不再存在。这是为了保持向后兼容性。
什么是 Java 泛型的上下界限定符
上界限定符使用 ? extends T 表示泛型类型必须是 T 或 T 的子类。下界限定符使用 ? super T 表示泛型类型必须是 T 或 T 的父类。
Java 中的深拷贝和浅拷贝有什么区别
浅拷贝复制对象的引用修改副本会影响原对象。深拷贝复制对象及其所有子对象完全独立。
什么是 Java 的 Integer 缓存池
Java 为了优化 Integer 对象的使用缓存了 -128 到 127 之间的 Integer 对象。当这些范围内的 Integer 被创建时会从缓存中返回对象而不是创建新对象。
Java 的类加载过程是怎样的
Java 的类加载过程包括以下阶段
加载将 .class 文件加载到 JVM 中。链接验证、准备和解析类。初始化执行静态初始化块和静态变量赋值。
什么是 Java 的 BigDecimal
BigDecimal 是 Java 提供的用于处理高精度计算的
类通常用于金融计算中。它能够处理任意精度的小数运算避免浮点数精度丢失问题。
使用 new String(“yupi”) 语句在 Java 中会创建多少个对象
会创建两个对象
字符串常量池中的 yupi。堆中的 String 对象。
Java 中 final、finally 和 finalize 各有什么区别
final用于修饰类、方法或变量表示不可变或不可继承。finally用于 try-catch 语句中确保无论是否有异常都会执行其中的代码。finalize在对象被垃圾回收前由 JVM 调用的方法。
为什么在 Java 中编写代码时会遇到乱码问题
Java 在处理字符集时如果源文件的编码格式与系统或运行时的编码不一致可能会导致乱码问题尤其是在跨平台开发时。
为什么 JDK 9 中将 String 的 char 数组改为 byte 数组
为了节省内存JDK 9 中将 String 的底层实现由 char[] 改为 byte[]并引入了 Compact Strings根据实际字符集选择合适的编码。
如何在 Java 中调用外部可执行程序或系统命令
可以通过 Runtime.getRuntime().exec() 或 ProcessBuilder 来执行外部可执行程序或系统命令。
如果一个线程在 Java 中被两次调用 start() 方法会发生什么
会抛出 IllegalThreadStateException 异常因为线程只能启动一次。
栈和队列在 Java 中的区别是什么
栈后进先出LIFO常用的实现是 Stack 类。队列先进先出FIFO常用的实现是 Queue 接口及其子类。
Java 的 Optional 类是什么它有什么用
Optional 是 JDK 8 引入的类用来避免 null 引发的 NullPointerException。通过 Optional可以显式地表示值的存在或缺失。
Java 的 I/O 流是什么
Java 的 I/O 流用于读取和写入数据。按处理数据类型分为字节流InputStream 和 OutputStream和字符流Reader 和 Writer。
什么是 Java 的网络编程
Java 提供了 java.net 包用于网络编程通过 Socket 和 ServerSocket 实现 TCP/IP 通信通过 DatagramSocket 实现 UDP 通信。
Java 中的基本数据类型有哪些
Java 提供了 8 种基本数据类型byte、short、int、long、float、double、char 和 boolean。
什么是 Java 中的自动装箱和拆箱
自动装箱是指将基本数据类型自动转换为相应的包装类型拆箱是指将包装类型转换为基本数据类型。
什么是 Java 中的迭代器Iterator
Iterator 是用于遍历集合元素的接口。通过 Iterator 可以安全地在遍历时移除元素。
Java 运行时异常和编译时异常之间的区别是什么
编译时异常在编译阶段被捕获必须处理如 IOException。运行时异常在程序运行时抛出不强制要求处理如 NullPointerException。
什么是 Java 中的继承机制
继承机制允许一个类继承另一个类的属性和方法从而实现代码复用。子类可以重写父类的方法。
什么是 Java 的封装特性
封装是面向对象编程的基本特性之一通过将对象的属性和行为隐藏起来并提供公共的访问方法控制对数据的访问和修改。
Java 中的访问修饰符有哪些
Java 中的访问修饰符包括
public对所有类可见。protected对同包类和子类可见。default对同包类可见。private仅对本类可见。
Java 中静态方法和实例方法的区别是什么
静态方法属于类而不属于对象可以通过类名调用。实例方法属于对象必须通过对象调用。
Java 中 for 循环与 foreach 循环的区别是什么
for 循环可以自定义循环条件和步进灵活性强。foreach 循环简化集合或数组的遍历但无法获取索引。foreach 是通过迭代器Itr implements Iterator实现的语法糖它只允许通过当前Itr对集合进行修改。
什么是 Java 中的双亲委派模型
双亲委派模型是一种类加载机制每个类加载器在加载类时首先会请求其父加载器进行加载只有当父加载器找不到时才会尝试自己加载。
Java 中 wait() 和 sleep() 的区别
wait()释放锁线程进入等待状态需通过 notify() 或 notifyAll() 唤醒。sleep()不释放锁线程暂停指定时间后自动恢复。
Java 和 Go 的区别
Java是一种面向对象的跨平台语言拥有丰富的生态系统依赖 JVM 运行。Go是一种面向系统编程的语言简洁高效支持并发编译成本地代码运行。
Java Object 类中有什么方法有什么作用
Object 类是所有类的父类提供了 equals()、hashCode()、toString()、clone() 等方法用于比较、哈希、输出对象信息、克隆对象等操作。
Java 中的字节码是什么
Java 字节码是由 Java 编译器生成的中间代码存储在 .class 文件中。字节码可以在任何支持 JVM 的平台上执行由 JVM 解释或编译为机器码运行。
Java 集合
说说 Java 中 HashMap 的原理
HashMap 是基于散列表哈希表实现的它通过 key 的 hashCode() 值来快速定位存储值的位置。HashMap 使用数组来存储键值对数组中的每个元素称为一个“桶”bucket。当多个键的 hashCode 值相同时它们会被存储在同一个桶中形成一个链表在 JDK 1.8 中当链表长度超过一定阈值时会将链表转换为红黑树。当插入、删除、查找元素时通过计算键的哈希值来快速确定存储位置。
使用 HashMap 时有哪些提升性能的技巧
设置合理的初始容量如果可以预估存储的元素数量设置合理的初始容量可以减少 HashMap 的扩容次数提升性能。适当调整负载因子默认负载因子为 0.75表示当 HashMap 达到容量的 75% 时会扩容。如果对性能要求较高且存储空间充足可以减小负载因子减少哈希冲突。避免使用复杂的 key 对象key 的 hashCode() 方法和 equals() 方法的效率会影响性能复杂对象的计算可能会导致性能瓶颈。选择合适的哈希函数确保 hashCode() 方法能够生成良好的哈希分布以避免哈希碰撞。
什么是 Hash 碰撞怎么解决哈希碰撞
Hash 碰撞 是指不同的键通过哈希函数计算后得到相同的哈希值这种情况下会将多个键值对存储在同一个桶中。在 Java 的 HashMap 中通常通过链地址法链表或红黑树来解决碰撞问题。当冲突过多时会将链表结构转换为红黑树以优化查找效率。
Java 的 CopyOnWriteArrayList 和 Collections.synchronizedList 有什么区别分别有什么优缺点
CopyOnWriteArrayList 和 Collections.synchronizedList 都是线程安全的列表实现但实现方式不同
CopyOnWriteArrayList每次对列表进行修改时都会创建列表的副本。优点是读操作不需要加锁性能高缺点是修改操作开销大不适合频繁修改的场景。Collections.synchronizedList使用同步锁实现线程安全所有读写操作都会被同步。优点是修改操作性能较好缺点是读操作也需要加锁导致性能下降。
Java 中有哪些集合类请简单介绍
List有序、可重复的集合如 ArrayList、LinkedList。Set无序、不可重复的集合如 HashSet、TreeSet。Map键值对形式的集合如 HashMap、TreeMap。Queue先进先出的队列集合如 LinkedList、PriorityQueue。Deque双端队列如 ArrayDeque。
数组和链表在 Java 中的区别是什么
数组支持快速随机访问查找效率高但增删操作效率低需要移动元素。链表不支持随机访问但插入和删除操作效率高只需改变节点指针。
Java 中的 List 接口有哪些实现类
List 接口的常见实现类有
ArrayListLinkedListVectorCopyOnWriteArrayList
Java 中 ArrayList 和 LinkedList 有什么区别
ArrayList基于数组实现支持快速随机访问但插入和删除元素时可能需要移动大量元素增删操作效率较低。LinkedList基于链表实现增删元素效率较高但不支持快速随机访问查找效率较低。
Java ArrayList 的扩容机制是什么
ArrayList 在容量不够时会自动扩容默认扩容策略是将容量增加为原来的 1.5 倍即 newCapacity oldCapacity (oldCapacity 1)。
Java 中的 HashMap 和 Hashtable 有什么区别
HashMap 是线程不安全的而 Hashtable 是线程安全的。HashMap 允许 null 键和值而 Hashtable 不允许 null 键和值。HashMap 性能更高因为它不需要同步机制。
Java 中的 HashSet 和 HashMap 有什么区别
HashSet 是基于 HashMap 实现的HashSet 内部使用 HashMap 来存储元素。HashSet 只存储元素而 HashMap 存储键值对。
Java 中 HashMap 的扩容机制是怎样的
HashMap 的扩容机制是当元素数量超过阈值容量 * 负载因子时数组会扩展到原来的两倍并重新分配桶中元素的位置。
为什么 HashMap 在 Java 中扩容时采用 2 的 n 次方倍
因为扩容为 2 的幂次方能够保证哈希值取模操作可以通过位运算 操作快速计算从而提高效率。
为什么 Java 中 HashMap 的默认负载因子是 0.75
负载因子 0.75 是性能与空间之间的折中选择它在保证查找性能的同时减少了哈希碰撞的概率并且在容量利用率上比较理想。
为什么 JDK 1.8 对 HashMap 进行了红黑树的改动
在 JDK 1.8 中当链表长度超过 8 时会将链表转换为红黑树以避免链表过长导致的查找性能下降。
JDK 1.8 对 HashMap 除了红黑树还进行了哪些改动
JDK 1.8 中HashMap 的桶不再是数组链表的单一形式改为了链表红黑树。同时重新优化了哈希分布算法以减少哈希碰撞。
Java 中的 LinkedHashMap 是什么
LinkedHashMap 是 HashMap 的子类它保留了元素的插入顺序或访问顺序通过双向链表来维护这种顺序。
Java 中的 TreeMap 是什么
TreeMap 是基于红黑树实现的有序 Map它按照键的自然顺序或自定义顺序对元素进行排序。
Java 中的 IdentityHashMap 是什么
IdentityHashMap 是一种特殊的 Map它使用 而不是 equals() 来比较键的相等性适用于需要严格区分对象引用的场景。
Java 中的 WeakHashMap 是什么
WeakHashMap 使用弱引用作为键当键不再被引用时键值对会被自动回收适用于缓存等场景。
Java 中 ConcurrentHashMap 1.7 和 1.8 之间有哪些区别
在 JDK 1.7 中ConcurrentHashMap 使用了分段锁机制而在 JDK 1.8 中改为使用 CAS 和 synchronized 来提高并发性能并引入了红黑树来优化冲突严重时的查找效率。
Java 中 ConcurrentHashMap 的 get 方法是否需要加锁
ConcurrentHashMap 的 get 方法是无锁的因为它是通过 volatile 变量和 CAS 实现的并不需要加锁。
为什么 Java 的 ConcurrentHashMap 不支持 key 或 value 为 null
ConcurrentHashMap 不支持 null 键值的原因是null 会导致在并发环境下无法判断返回的结果是 null 还是键不存在可能会引起歧义和错误。
Java 中的 CopyOnWriteArrayList 是什么
CopyOnWriteArrayList 是线程安全的 List 实现它在修改时会复制整个数组适用于读操作远多于写操作的场景。
你遇到过 ConcurrentModificationException 错误吗它是如何产生的
ConcurrentModificationException 是在迭代集合时如果其他线程对集合进行了结构性修改如增删元素会抛出的异常。
Java 并发
新值从而实现原子操作。
说说 AQS 吧
AQSAbstractQueuedSynchronizer是 Java 中的一个框架用于构建锁和同步器。它通过一个 FIFO 队列来管理线程的访问请求提供了重入锁、读写锁等多种实现。
Java 中 ReentrantLock 的实现原理是什么
ReentrantLock 是基于 AQS 实现的可重入锁支持公平和非公平两种策略。它使用一个整数标志来记录锁的重入次数并维护一个等待线程的队列。
Java 的 synchronized 是怎么实现的
synchronized 是通过对象监视器实现的底层使用 monitor 机制进行同步。进入 synchronized 方法或代码块时线程会获取对象的锁离开时释放锁。
Java 中的 synchronized 轻量级锁是否会进行自旋
轻量级锁在竞争发生时会进行自旋以减少线程上下文切换的开销直到锁被成功获取或升级为重量级锁。
当 Java 的 synchronized 升级到重量级锁后所有线程都释放锁了此时它还是重量级锁吗
一旦升级到重量级锁锁对象会保持重量级锁的状态直到所有持有锁的线程释放锁为止。
什么是 Java 中的锁自适应自旋
锁自适应自旋是指在获取锁时JVM 会根据线程竞争的情况自动决定自旋的时间长度以减少上下文切换带来的开销。
Synchronized 和 ReentrantLock 有什么区别
实现方式synchronized 是 JVM 实现的ReentrantLock 是通过 AQS 实现的。功能ReentrantLock 提供了更多的功能如可重入、可中断和公平锁等。性能在高竞争情况下ReentrantLock 性能更优因为它可以使用自旋锁。
如何优化 Java 中的锁的使用
优化锁的使用可以采取以下方法
减小临界区尽量缩小加锁范围。使用读写锁对于读多写少的场景使用读写锁提高并发性能。减少锁的粒度避免对整个对象加锁尽可能细化锁定的对象。使用非阻塞算法例如 CAS 操作。
你了解 Java 中的读写锁吗
读写锁是 ReentrantReadWriteLock 实现的一种锁允许多个线程同时读取共享数据但在写线程访问时禁止其他读写线程访问。适用于读多写少的场景。
什么是 Java 内存模型JMM
Java 内存模型JMM定义了 Java 程序中线程如何与内存交互的规则确保线程之间的可见性和有序性帮助开发者理解多线程编程中的行为。
什么是 Java 中的原子性、可见性和有序性
原子性保证操作的不可分割性要么全部成功要么全部失败。可见性一个线程对共享变量的修改能够及时被其他线程看到。有序性保证程序执行顺序的一致性避免指令重排导致的错误。
什么是 Java 的 happens-before 规则
Happens-before 规则是一组确定性规则用于保证一个操作的结果对另一个操作可见确保多线程环境中的可见性。
什么是 Java 中的指令重排
指令重排是编译器或 CPU 为优化性能而改变指令执行顺序的过程。虽然可能影响程序的执行顺序但 Java 内存模型确保了在正确的 happens-before 关系下程序结果的一致性。
Java 中的 final 关键字是否能保证变量的可见性
final 关键字可以保证对象的初始化安全但不能单独保证对非 final 变量的可见性。
为什么在 Java 中需要使用 ThreadLocal
ThreadLocal 提供了每个线程独立的变量副本避免了共享数据引发的线程安全问题常用于实现用户会话、数据库连接等。
Java 中的 ThreadLocal 是如何实现线程资源隔离的
ThreadLocal 通过内部维护一个以当前线程为 key 的 Map存储每个线程独立的变量确保不同线程之间的数据隔离。
为什么 Java 中的 ThreadLocal 对 key 的引用为弱引用
为了避免内存泄漏ThreadLocal 的 key 使用弱引用这样在没有其他强引用指向 ThreadLocal 对象时可以被垃圾回收确保资源的及时释放。
Java 中使用 ThreadLocal 的最佳实践是什么
最佳实践包括
仅在必要时使用 ThreadLocal。在线程结束时显式清理 ThreadLocal防止内存泄漏。对 ThreadLocal 变量进行封装避免直接暴露给外部。
Java 中的 InheritableThreadLocal 是什么
InheritableThreadLocal 是 ThreadLocal 的子类允许子线程继承父线程的值适合需要在线程间共享数据的场景。
ThreadLocal 的缺点
缺点包括
可能导致内存泄漏特别是在长时间运行的应用中。对于大量线程可能导致内存占用增加。使用不当可能导致难以追踪的 bug。
为什么 Netty 不使用 ThreadLocal 而是自定义了一个 FastThreadLocal
Netty 自定义 FastThreadLocal 主要是为了提高性能和减少内存开销FastThreadLocal 通过减少数组长度和降低锁竞争来实现更高效的线程本地存储。
什么是 Java 的 TransmittableThreadLocal
TransmittableThreadLocal 是一种扩展自 ThreadLocal 的类支持在线程上下文之间传递值适合用于异步调用场景。
Java 中 Thread.sleep 和 Thread.yield 的区别
Thread.sleep(long millis)让当前线程暂停执行指定时间进入阻塞状态。Thread.yield()建议 JVM 暂停当前线程允许其他同优先级线程获得执行机会但不保证立即生效。
Java 中 Thread.sleep(0) 的作用是什么
Thread.sleep(0) 通常用于让出 CPU 执行权允许其他线程执行但没有明确的时间限制。
Java 中的 wait、notify 和 notifyAll 方法有什么作用
wait()使当前线程等待并释放锁直到被其他线程唤醒。notify()随机唤醒一个等待该对象锁的线程。notifyAll()唤醒所有等待该对象锁的线程。
Java 中什么情况会导致死锁如何避免
死锁发生在两个或多个线程相互等待对方释放持有的锁。避免死锁的方法包括
避免嵌套锁定。采用定时锁。按照固定顺序加锁。
Java 中 volatile 关键字的作用是什么
volatile 关键字用于修饰变量确保变量在多个线程间的可见性禁止指令重排但不保证原子性。
什么是 Java 中的 ABA 问题
ABA 问题是指在执行 CAS 操作时某个变量在比较后被其他线程修改然后又被修改回原值导致 CAS 操作成功但实际状态已被改变。
在 Java 中主线程如何知晓创建的子线程是否执行成功
主线程可以通过 Thread 的 join() 方法等待子线程执行完毕并通过子线程中的共享变量或返回值获取执行结果。
Java 虚拟机
Java 中有哪些垃圾回收算法
Java 中常见的垃圾回收算法主要包括
标记-清除算法通过标记活跃对象然后清除未标记的对象。简单但容易产生内存碎片。标记-整理算法与标记-清除类似但在清除后整理存活对象避免内存碎片。复制算法将内存分为两个相同的区域每次只使用一个区域回收时将存活对象复制到另一个区域。分代收集算法将堆内存分为新生代和老年代根据对象存活时间不同选择不同的收集算法。
JVM 的 TLABThread-Local Allocation Buffer是什么
TLAB 是每个线程在 Java 堆中分配的一块小内存区域用于提高对象的分配效率。每当线程需要分配新对象时会首先尝试在自己的 TLAB 中分配空间避免了竞争和加锁的开销。
Java 是如何实现跨平台的
Java 的跨平台能力主要通过 Java 虚拟机JVM 来实现。Java 程序首先编译成平台无关的字节码.class 文件然后由 JVM 在具体的操作系统上执行。不同平台上可以有不同实现的 JVM使得同一份 Java 代码可以在多个平台上运行。
编译执行与解释执行的区别是什么JVM 使用哪种方式
编译执行将整个源代码编译成机器码然后直接执行速度较快。C 语言编译为可执行文件即为此方式。解释执行逐行读取源代码并执行速度较慢但便于调试。Python 是典型的解释型语言。
JVM 采用 混合模式既使用编译JIT 编译来提升性能也使用解释执行来提高灵活性。
JVM 的内存区域是如何划分的
JVM 的内存区域主要划分为以下几个部分
方法区存储类信息、常量、静态变量等。堆区用于存储对象实例是 Java 中最大的内存区域。栈区每个线程独立的栈用于存储局部变量、方法调用等。本地方法栈存储本地方法的栈帧。程序计数器每个线程的执行位置指示器。
Java 中堆和栈的区别是什么
堆用于动态分配内存存储对象实例生命周期由垃圾回收器管理。栈用于存储基本数据类型的局部变量和方法调用具有严格的后进先出LIFO特性内存由 JVM 自动管理。
什么是 Java 中的直接内存
直接内存是 Java 中不属于堆或栈的内存通常是通过 ByteBuffer 直接分配的。直接内存的访问速度快适用于 I/O 操作但管理较为复杂容易引发内存泄漏。
什么是 Java 中的常量池
常量池是 JVM 为了提高性能而维护的一块内存区域存储编译时生成的常量如字符串、数值等。常量池分为 类常量池 和 运行时常量池前者存储类的静态常量后者存储动态生成的常量。
你了解 Java 的类加载器吗
Java 的类加载器负责加载类文件到 JVM 中主要分为以下几种
引导类加载器Bootstrap ClassLoader加载 Java 核心类库。扩展类加载器Extension ClassLoader加载 JDK 扩展库。应用类加载器Application ClassLoader加载用户类路径下的类。
什么是 Java 中的 JITJust-In-Time?
JIT 是一种动态编译技术JVM 在执行 Java 字节码时将热点代码编译为本地机器码缓存以便后续快速执行从而提升性能。
什么是 Java 的 AOTAhead-Of-Time
AOT 是一种编译技术在应用程序运行之前将 Java 字节码编译为本地机器码减少了运行时编译的开销通常用于提升启动时间和整体性能。
你了解 Java 的逃逸分析吗
逃逸分析是 JIT 编译器的一种优化技术通过分析对象的作用域决定是否将对象分配在栈上而不是堆上从而降低 GC 开销提高性能。
Java 中的强引用、软引用、弱引用和虚引用分别是什么
强引用强引用是最常用的引用GC 时不会回收。软引用用于缓存的引用当内存不足时会被回收。弱引用只能在 GC 时被回收适合用于监听器等。虚引用与对象的生存周期没有直接关系用于跟踪对象的回收情况。
Java 中常见的垃圾收集器有哪些
Serial 垃圾收集器单线程适合小型应用。Parallel 垃圾收集器多线程适合大规模应用。CMSConcurrent Mark-Sweep垃圾收集器并发收集减少停顿时间。G1Garbage-First垃圾收集器适合大堆内存旨在减少停顿时间。ZGCZ Garbage Collector低延迟高吞吐量的垃圾收集器。
Java 中如何判断对象是否是垃圾不同垃圾回收方法有何区别
Java 垃圾收集器通常使用 可达性分析 来判断对象是否是垃圾即通过 GC 根如栈中的引用进行遍历判断哪些对象是可达的。未被访问到的对象被视为垃圾。
不同的垃圾回收方法在算法和实现上有所不同例如标记-清除、复制算法和分代收集等这些方法会影响内存回收的效率和停顿时间。
为什么 Java 的垃圾收集器将堆分为老年代和新生代
将堆分为老年代和新生代是为了根据对象的生命周期特性进行优化。新生代中的对象生命周期较短适合使用复制算法而老年代中的对象生命周期较长适合使用标记-清除算法。
为什么 Java 8 移除了永久代PermGen并引入了元空间Metaspace
Java 8 移除永久代的原因是它的大小是固定的容易导致 OutOfMemoryError。元空间则是基于本地内存的大小可动态调整避免了这一问题。
为什么 Java 新生代被划分为 S0、S1 和 Eden 区
新生代被划分为三个区域是为了优化垃圾收集效率。Eden 区用于存储新创建的对象而 S0 和 S1 是 Survivor 区域存储经过一次垃圾收集后仍然存活的对象从而可以减少内存的复制开销。
什么是三色标记算法
三色标记算法是一种用于垃圾回收的标记算法将对象分为三种状态
白色未被标记的对象可能是垃圾。灰色已标记但尚未处理的对象。黑色已标记并处理完的对象。
Java 中的 young GC、old GC、full GC 和 mixed GC 的区别是什么
young GC针对新生代的垃圾收集通常使用复制算法。old GC针对老年代的垃圾收集通常使用标记-清除算法。full GC对整个堆进行垃圾收集包括新生代和老年代。mixed GC对新生代和部分老年代进行垃圾收集适用于 G1 垃圾收集器。
什么条件会触发 Java 的 young GC
当新生代Eden 区中的对象数量达到阈值时会触发 young GC以回收未存活的对象。
什么情况下会触发 Java 的 Full GC
Full GC 会在以下情况下触发
老年代内存不足。显示调用 System.gc()。JVM 内存配置调整。
什么是 Java 的 PLAB
PLABPer-Thread Local Allocation Buffer是每个线程的本地分配缓冲区类似于 TLAB旨在减少线程之间的竞争提升对象分配的效率。
JVM 垃圾回收时产生的 concurrent mode failure 的原因是什么
Concurrent Mode Failure 发生在 CMS
收集过程中若内存不够无法为活跃对象分配空间导致需要转为 Full GC。这通常由于老年代空间不足导致。
为什么 Java 中 CMS 垃圾收集器在发生 Concurrent Mode Failure 时的 Full GC 是单线程的
在发生 Concurrent Mode Failure 时CMS 切换为 Full GC 是单线程的因为该过程需要暂停所有用户线程避免多线程并发造成的资源竞争和不一致性。
为什么 Java 中某些新生代和老年代的垃圾收集器不能组合使用比如 ParNew 和 Parallel Old
因为一些垃圾收集器在实现上不兼容不能同时使用。比如 ParNew 依赖于多线程的复制而 Parallel Old 依赖于单线程的标记-清除二者在设计上存在冲突。
JVM 新生代垃圾回收如何避免全堆扫描
JVM 新生代垃圾回收通过分代收集的策略只针对新生代的对象进行回收避免了全堆扫描从而提升了回收效率。
Java 的 CMS 垃圾回收器和 G1 垃圾回收器在记忆集的维护上有什么不同
CMS 使用 记忆集 来记录对象的引用支持并发回收但需要额外维护。G1 则通过将堆分成多个区域使用分区方式更为灵活减少了记忆集的管理复杂性。
为什么 G1 垃圾收集器不维护年轻代到老年代的记忆集
G1 垃圾收集器不维护年轻代到老年代的记忆集因为它通过分区管理来追踪对象的存活状态避免了维护复杂的引用关系提高了回收效率。
Java 中的 CMS 和 G1 垃圾收集器如何维持并发的正确性
CMS 和 G1 都通过标记和拷贝过程维护并发的正确性使用锁或无锁机制确保在垃圾回收期间存活对象的引用不会被修改。
什么是 Java 中的 logging write barrier
Logging Write Barrier 是一种用于记录对象写操作的机制确保在对象被修改后能够正确更新记忆集以便在 GC 时维护对象的正确性。
Java 的 G1 垃圾回收流程是怎样的
G1 垃圾回收的流程如下
标记阶段标记活跃对象。整理阶段根据存活对象的数量选择合适的区域进行回收。清理阶段清除未标记的对象回收内存。
Java 的 CMS 垃圾回收流程是怎样的
CMS 垃圾回收的流程如下
初始标记标记 GC Roots 可达的对象暂停用户线程。并发标记标记存活对象用户线程并发执行。重新标记对初始标记和并发标记进行整合暂停用户线程。并发清除清除未标记的对象用户线程并发执行。
你了解 Java 的 ZGCZ Garbage Collector吗
ZGC 是一种低延迟、高吞吐量的垃圾收集器支持大堆内存采用 分代回收 和 记忆集 的管理方式减少停顿时间。其主要目标是实现 不超过 10ms 的停顿。
JVM 垃圾回收调优的主要目标是什么
JVM 垃圾回收调优的主要目标是降低垃圾收集的停顿时间提高应用程序的响应性同时提高内存使用效率和吞吐量。
如何对 Java 的垃圾回收进行调优
对 Java 垃圾回收的调优通常涉及以下方面
选择合适的垃圾收集器如 G1、CMS。调整堆内存大小、老年代和新生代比例。监控和分析 GC 日志识别瓶颈。调整 GC 的参数如 -Xmx、-Xms、-XX:NewRatio 等。
常用的 JVM 配置参数有哪些
常用的 JVM 配置参数包括
-Xms设置初始堆内存大小。-Xmx设置最大堆内存大小。-XX:NewRatio设置新生代与老年代的比例。-XX:UseG1GC启用 G1 垃圾收集器。-XX:UseConcMarkSweepGC启用 CMS 垃圾收集器。
你常用哪些工具来分析 JVM 性能
常用的 JVM 性能分析工具包括
JVisualVM可视化监控和分析工具。JConsole用于监控和管理 Java 应用程序。Java Mission Control用于性能监控和分析。YourKit功能强大的性能分析工具。
如何在 Java 中进行内存泄漏分析
内存泄漏分析通常通过以下步骤进行
使用内存分析工具如 Eclipse MAT、VisualVM查看内存快照。识别未被回收的对象及其引用链。分析对象的生命周期找到泄漏的原因。通过代码审查、优化数据结构或移除不必要的引用来解决问题。
MySQL
MySQL 中的数据排序是怎么实现的
MySQL 中的数据排序主要通过 ORDER BY 子句实现。在执行查询时数据库会根据指定的列进行排序。排序算法通常使用的有快速排序Quick Sort和归并排序Merge Sort。在选择排序算法时MySQL 会根据数据量、索引情况及排序字段的数据类型来选择最优的排序算法。对于使用索引的情况MySQL 可以直接利用索引中的顺序来加速排序操作。
MySQL 的 Change Buffer 是什么它有什么作用
Change Buffer 是 InnoDB 存储引擎的一个特性主要用于优化对二级索引的写入操作。当对索引进行插入、更新或删除时这些修改会被暂时存储在内存中的 Change Buffer 中而不是立即写入磁盘。这样可以减少对磁盘的随机写入从而提高性能。稍后后台线程会将 Change Buffer 中的变更合并到实际的索引结构中。
详细描述一条 SQL 语句在 MySQL 中的执行过程。
解析阶段首先MySQL 会解析 SQL 语句检查语法和语义错误并生成一个解析树。优化阶段生成的解析树会被优化器优化优化器会选择最佳的执行计划包括选择合适的索引和连接顺序。执行阶段根据优化后的执行计划MySQL 会逐步执行 SQL 语句访问数据、进行计算和返回结果。结果返回最后执行的结果会被返回给客户端。
MySQL 的存储引擎有哪些它们之间有什么区别
MySQL 主要有以下几种存储引擎
InnoDB支持事务、行级锁和外键适合高并发的 OLTP 应用。MyISAM不支持事务和外键使用表级锁适合读密集型应用。MEMORY将数据存储在内存中访问速度快但数据持久性差。CSV以逗号分隔的文件格式存储数据适合导入导出。ARCHIVE适合存储大量的归档数据不支持索引。
MySQL 的索引类型有哪些
MySQL 中的索引类型主要包括
普通索引最基本的索引类型。唯一索引索引中的值必须唯一。主键索引唯一索引的一种不能有 NULL 值。全文索引用于在文本中进行复杂的搜索。组合索引由多个列组成的索引。
MySQL InnoDB 引擎中的聚簇索引和非聚簇索引有什么区别
聚簇索引数据表的实际数据存储与索引结构是结合在一起的。每个表只能有一个聚簇索引通常是主键索引数据按照主键顺序存储。非聚簇索引索引和数据存储是分开的非聚簇索引的每一条索引记录都包含一个指向数据行的指针。一个表可以有多个非聚簇索引。
MySQL 中的回表是什么
回表是指在使用非聚簇索引查询数据时首先通过索引找到对应的记录再通过索引中的指针去主表中查找实际数据的过程。这个过程增加了查询的时间开销尤其在选择的字段没有被索引时。
MySQL 索引的最左前缀匹配原则是什么
MySQL 的最左前缀匹配原则指的是在组合索引中只有从最左侧的列开始的索引才会被有效利用。例如如果有一个组合索引 (a, b, c)那么可以使用索引进行的有效查询包括
WHERE a ?WHERE a ? AND b ?WHERE a ? AND b ? AND c ? 但不能只使用 b 或 c。
MySQL 的覆盖索引是什么
覆盖索引是指查询时只需访问索引而不需回表就可以获得所有查询字段的数据。这样的查询能显著提高性能因为不需要读取实际数据行。
MySQL 的索引下推是什么
索引下推是 MySQL 5.6 引入的一项优化特性。在执行某些查询时MySQL 可以在索引扫描过程中提前过滤掉不满足条件的行减少需要回表的数据行数量从而提高查询效率。
在 MySQL 中建索引时需要注意哪些事项
选择合适的列索引应该建立在经常用于查询条件的列上。避免过多索引每增加一个索引都会影响写入性能。监控索引的使用情况使用 EXPLAIN 分析索引的使用效果避免无效索引。考虑字段的数据分布高基数的列更适合建立索引。
MySQL 中使用索引一定有效吗如何排查索引效果
不一定有效。某些情况下如小表的全表扫描、条件不适合索引、或索引列的基数低索引可能不会提高性能。可以使用 EXPLAIN 语句来分析查询的执行计划查看是否使用了索引及其对性能的影响。
MySQL 中的索引数量是否越多越好为什么
索引数量并不是越多越好。虽然索引可以加速查询但过多的索引会导致
写入性能下降因为每次插入、更新或删除都需要维护索引。占用更多的存储空间。 因此应该根据实际的查询需求合理建立索引。
请详细描述 MySQL 的 B 树中查询数据的全过程
查找根节点从根节点开始根据查询的键值逐层查找。向下查找在每一层中查找子节点直到到达叶子节点。定位数据在叶子节点中找到对应的记录或指针获取实际数据。
为什么 MySQL 选择使用 B 树作为索引结构
MySQL 选择 B 树作为索引结构是因为它具有
高效的查找速度B 树的深度较小查找速度快。良好的插入和删除性能B 树能保持平衡确保高效的插入和删除操作。范围查询高效B 树的叶子节点按顺序连接方便范围查询。
MySQL 是如何实现事务的
MySQL 使用 InnoDB 存储引擎实现事务遵循 ACID 原则。具体实现包括
原子性通过日志记录确保事务的操作是一个整体要么全部成功要么全部失败。一致性事务在执行前后数据库的状态必须是有效的。隔离性通过锁机制或 MVCC 实现事务之间的隔离。持久性通过日志和数据的持久化确保一旦提交的数据不会丢失。
MySQL 中长事务可能会导致哪些问题
长事务可能导致以下问题
锁竞争长时间占用锁导致其他事务无法执行降低并发性能。事务日志膨胀长事务需要维护更多的日志增加磁盘空间使用。数据不一致长事务在某些情况下可能导致数据的读取与写入不一致。
MySQL 中的 MVCC 是什么
MVCC多版本并发控制是一种用于控制并发访问的机制它允许多个事务并行运行而不互相阻塞。InnoDB 通过为每一行数据维护多个版本来实现 MVCC从而允许读取旧版本的数据确保读操作不被写操作阻塞。
如果 MySQL 中没有 MVCC会有什么影响
如果没有 MVCC事务的并发性能将大幅下降多个事务可能会相互阻塞从而导致性能瓶颈。读操作可能需要等待写操作完成造成响应时间延长整体数据库性能降低。
MySQL 中的事务隔离级别有哪些
MySQL 提供以下事务隔离级别
读未提交READ UNCOMMITTED事务可以读取未提交的数据。读已提交READ COMMITTED事务只能读取已提交的数据。可重复读REPEATABLE READ在一个事务中多次读取相同数据时结果一致。串行化SERIALIZABLE完全隔离事务串行执行。
MySQL 默认的事务隔离级别是什么为什么
选择这个级别 MySQL 默认的事务隔离级别是可重复读REPEATABLE READ。选择这个级别的原因是
性能较高相较于串行化允许更高的并发。避免脏读和不可重复读能有效避免脏读并且在大多数应用场景中确保数据一致性。
数据库的脏读、不可重复读和幻读分别是什么
脏读一个事务读取到另一个未提交事务的数据。不可重复读一个事务在执行过程中读取到的数据在后续查询中被其他事务修改。幻读一个事务在读取一系列数据时另一事务插入或删除了某些行导致原事务再次读取时结果不同。
MySQL 中有哪些锁类型
MySQL 中主要有以下几种锁
共享锁S锁允许多个事务并发读取但不允许修改。排他锁X锁一个事务获得后其他事务无法读取或修改。意向锁用于表级锁和行级锁之间的协调。自动锁如 MySQL 的表级锁和行级锁。
MySQL 的乐观锁和悲观锁是什么
悲观锁在操作数据时假设会发生冲突因此在操作前加锁确保数据的一致性。乐观锁在操作数据时假设不会发生冲突因此不加锁而是在提交时检查数据版本。
MySQL 中如果发生死锁应该如何解决
MySQL 会自动检测死锁并进行处理。通常情况下InnoDB 会选择一个事务回滚以解除死锁。应用程序也可以通过捕获异常并重试操作来处理死锁。
如何使用 MySQL 的 EXPLAIN 语句进行查询分析
通过在查询前加上 EXPLAIN可以获取查询的执行计划包括使用的索引、行数估算、连接类型等信息从而帮助分析查询性能问题。例如
EXPLAIN SELECT * FROM table WHERE id 1;通过分析输出结果确定查询的效率是否合理使用了索引。
MySQL 中 count(*)、count(1) 和 count(字段名) 有什么区别
count(*)计算结果集中所有行数包括 NULL 值。count(1)与 count(*) 类似计算结果集中的所有行但不关心列的具体值。count(字段名)仅计算该字段非 NULL 值的行数。
MySQL 中 int(11) 的 11 表示什么
int(11) 中的 11 表示该整数字段在某些情况下的显示宽度不影响存储的范围。该宽度仅在使用 ZEROFILL 属性时有效用于在输出时填充零。
MySQL 中 varchar 和 char 有什么区别
char固定长度字符串存储时会填充空格适合存储长度固定的数据。varchar可变长度字符串节省存储空间适合存储长度不固定的数据。
MySQL 中如何进行 SQL 调优
SQL 调优的方法包括
使用索引为查询创建适当的索引。简化查询避免复杂的子查询和联接。使用 EXPLAIN分析执行计划找出性能瓶颈。合理使用缓存如查询缓存和连接池。
如何在 MySQL 中避免单点故障
可以通过以下方式避免单点故障
主从复制实现数据的备份与冗余。负载均衡使用负载均衡器分散请求。数据备份定期备份数据确保数据安全。
如何在 MySQL 中实现读写分离
读写分离可以通过以下方式实现
主从复制将写操作发送到主库将读操作发送到从库。负载均衡器使用负载均衡器将请求分发到不同的数据库实例。
什么是 MySQL 的主从同步机制它是如何实现的
主从同步机制是指一个主数据库主库将数据变更同步到一个或多个从数据库从库。实现方式包括
二进制日志binlog主库记录所有数据变更到二进制日志从库通过读取该日志来更新数据。I/O 线程从库的 I/O 线程连接主库拉取 binlog。
如何处理 MySQL 的主从同步延迟
处理主从同步延迟的方法包括
优化主库的性能减少写入延迟。监控和调整 I/O 线程确保从库及时拉取 binlog。定期检查和清理 binlog避免过多的日志影响性能。
什么是分库分表分库分表有哪些类型或策略
分库分表是将一个大表或数据库拆分成多个小表或数据库的技术。类型包括
垂直分库将不同的表分到不同的数据库中。水平分库将相同表的数据划分到不同的数据库中。分片对大表按某个条件进行划分。
如果组长要求你主导项目中的分库分表大致的实施流程是
需求分析了解系统的业务需求确定分库分表的必要性。设计分库分表策略选择合适的分库分表方案。数据库设计设计新的数据库结构和表结构。实现数据迁移编写迁移脚本将数据迁移到新数据库中。更新应用代码调整应用程序以支持新的数据库结构。测试和上线进行充分的测试确保分库分表的稳定性。
对数据库进行分库分表可能会引发哪些问题
复杂性增加应用逻辑变复杂需要处理多个数据库的情况。跨库事务问题事务跨多个数据库可能会面临一致性问题。数据查询困难需要更复杂的查询逻辑来处理分散的数据。
从 MySQL 获取数据是从磁盘读取的吗
MySQL 中的数据获取通常是从内存中的缓存中读取只有当数据不在内存中时才会从磁盘读取。InnoDB 会将数据页缓存在缓冲池中以减少磁盘 I/O 操作。
MySQL 的 Doublewrite Buffer 是什么它有什么作用
Doublewrite Buffer 是 InnoDB 的一种数据保护机制。在写入数据页之前数据会先写入到 Doublewrite Buffer 中确保在崩溃恢复时不会丢失数据避免了部分页写入的情况。
MySQL 中的 Log Buffer 是什么它有什么作用
Log Buffer 是 InnoDB 用于暂存事务日志的内存区域。当事务提交时日志首先被写入 Log Buffer随后再批量写入磁盘提升写入性能。
为什么在 MySQL 中不推荐使用多表 JOIN
多表 JOIN 会导致性能下降特别是在数据量大的情况下查询复杂性增加可能导致全表扫描影响查询效率。此外多个表的 JOIN 可能会增加内存消耗和 CPU 负载。
MySQL 中如何解决深度分页的问题
深度分页可以通过以下方法解决
使用索引优化确保分页查询的字段有索引。避免深度分页通过缓存或其他方式减少需要分页的数据量。使用关键字搜索结合搜索功能减少分页的需求。
如何在 MySQL 中监控和优化慢 SQL
开启慢查询日志记录执行时间超过指定阈值的 SQL 语句。使用 EXPLAIN 分析查看查询计划找出性能瓶颈。优化查询对慢 SQL 进行索引优化、简化逻辑。
MySQL 中 DELETE、DROP 和 TRUNCATE 的区别是什么
DELETE删除表中的行可以添加 WHERE 子句删除时会逐行记录日志慢。DROP删除整个表和表结构数据不可恢复。TRUNCATE快速清空表中所有数据不记录日志重置自增值。
MySQL 中 INNER JOIN、LEFT JOIN 和 RIGHT JOIN 的区别是什么
INNER JOIN只返回两个表中匹配的记录。LEFT JOIN返回左表的所有记录以及右表中匹配的记录不匹配的部分为 NULL。RIGHT JOIN返回右表的所有记录以及左表中匹配的记录不匹配的部分为 NULL。
MySQL 中 LIMIT 100000
000, 10和LIMIT 10 的执行速度是否相同 不相同。LIMIT 100000000, 10需要扫描前 1 亿条记录才会返回 10 条数据性能非常低下而LIMIT 10 则直接返回前 10 条记录速度更快。
MySQL 中 DATETIME 和 TIMESTAMP 类型的区别是什么
DATETIME范围从 1000-01-01 到 9999-12-31存储大小为 8 字节未受时区影响。TIMESTAMP范围从 1970-01-01 00:00:01 UTC 到 2038-01-19 03:14:07 UTC存储大小为 4 字节受时区影响。
数据库的三大范式是什么
第一范式1NF每个字段只存储原子值不能有重复的列。第二范式2NF符合 1NF且每个非主属性完全依赖于主键。第三范式3NF符合 2NF且没有非主属性依赖于其他非主属性。
在 MySQL 中你使用过哪些函数
常用函数包括
聚合函数如 SUM()、AVG()、COUNT()。字符串函数如 CONCAT()、SUBSTRING()。日期函数如 NOW()、DATE_ADD()。
MySQL 中 TEXT 类型最大可以存储多长的文本
TEXT 类型最大可以存储 65,535 字节的文本。
MySQL 中 AUTO_INCREMENT 列达到最大值时会发生什么
当 AUTO_INCREMENT 列达到最大值时会返回错误无法插入新的行除非重置值或更改字段类型。
在 MySQL 中存储金额数据应该使用什么数据类型
在 MySQL 中存储金额数据通常使用 DECIMAL 类型以避免浮点数运算带来的精度问题。通常定义为 DECIMAL(10,2)其中 10 是总位数2 是小数位数。
什么是数据库的视图
视图是一个虚拟表它是基于查询的结果集。视图可以简化复杂查询提供数据安全性限制用户对底层表的访问。
什么是数据库的游标
游标是一个数据库对象用于逐行处理查询结果。游标允许应用程序对查询结果进行循环操作。
为什么不推荐在 MySQL 中直接存储图片、音频、视频等大容量内容
直接存储大容量内容会导致数据库体积膨胀影响性能。推荐将文件存储在文件系统中并在数据库中保存文件路径。
相比于 OracleMySQL 的优势有哪些
开源和免费MySQL 是开源的使用成本低。易于使用用户界面友好社区支持活跃。性能优化在某些场景下MySQL 性能更优。
MySQL 中 VARCHAR(100) 和 VARCHAR(10) 的区别是什么
VARCHAR(100) 表示可以存储长度最长为 100 的可变长度字符串而 VARCHAR(10) 只支持长度最长为 10 的字符串。存储空间根据实际使用长度而定。
在什么情况下不推荐为数据库建立索引
数据变化频繁频繁更新、删除操作会导致索引维护开销大。表数据量较小小表的查询性能差异不大索引反而增加了复杂性。查询不频繁索引的维护成本不值得。
MySQL 中 EXISTS 和 IN 的区别是什么
EXISTS用于检查子查询是否返回结果通常在子查询中使用效率较高。IN用于检查某个值是否在一个列表或子查询的结果集中性能相对较低。
什么是 Write-Ahead Logging (WAL) 技术它的优点是什么MySQL 中是否用到了 WAL
WAL 是一种确保数据一致性的技术在修改数据之前先将操作记录到日志中。优点包括提高系统的可靠性和恢复能力。MySQL 的 InnoDB 引擎在事务日志中使用了类似的机制。
你们生产环境的 MySQL 中使用了什么事务隔离级别为什么
通常使用可重复读REPEATABLE READ因为它能有效避免脏读和不可重复读同时在性能上能满足大部分业务需求。
为什么阿里巴巴的 Java 手册不推荐使用存储过程
存储过程难以维护调试困难且与应用逻辑耦合较高。此外存储过程的可移植性差不利于在不同数据库之间的迁移。
如何实现数据库的不停服迁移
可以通过以下步骤实现
双写机制在新旧数据库中同时写入数据。数据同步在后台将旧数据库的数据逐步迁移到新数据库。流量切换测试完成后逐步切换流量到新数据库。监控与回滚确保新数据库稳定运行后再彻底停止旧数据库服务。
MySQL 数据库的性能优化方法有哪些
优化查询使用索引、减少子查询。配置优化根据负载调整 MySQL 的配置参数。使用缓存应用层和数据库层缓存减少不必要的数据库访问。
MySQL 中 InnoDB 存储引擎与 MyISAM 存储引擎的区别是什么
事务支持InnoDB 支持事务MyISAM 不支持。数据安全性InnoDB 使用外键约束MyISAM 不支持。锁机制InnoDB 支持行级锁MyISAM 只支持表级锁。
MySQL 的查询优化器如何选择执行计划
查询优化器会分析 SQL 语句考虑表的统计信息、可用索引和连接方式等选择成本最低的执行计划来优化查询性能。
什么是数据库的逻辑删除数据库的物理删除和逻辑删除有什么区别
逻辑删除通过更新标志位如 is_deleted 字段来标识数据已删除数据仍然存在于表中。物理删除直接从数据库中删除数据数据不再存在。
逻辑删除保留了数据的完整性适用于需要保留历史记录的场景而物理删除则彻底清除了数据适用于数据不再需要的情况。
Redis
1. Redis 主从复制的实现原理是什么
Redis 的主从复制Master-Slave Replication是通过将数据从主节点复制到一个或多个从节点来实现的。主节点处理写请求并将这些写请求的变更以追加的方式记录到复制缓冲区replication buffer。从节点在启动时会通过发送 PSYNC 命令向主节点请求数据主节点则将当前的数据快照RDB 文件传送给从节点。此后从节点会通过增量复制使用二进制日志获取主节点的新变更。主从复制使得读取请求可以分散到从节点上增强了系统的可扩展性和容错能力。
2. Redis 集群的实现原理是什么
Redis 集群通过分片sharding将数据分布在多个节点上。每个节点负责一部分键的存储这样可以实现水平扩展。Redis 集群采用的是一种无中心化的架构每个节点都是对等的节点之间通过 gossip 协议来交换状态信息以维护集群的健康状况和自动发现节点。在数据请求时客户端首先会向任一节点发起请求节点根据哈希槽hash slot机制来确定目标节点。如果目标节点不可用集群会自动进行故障转移。
3. Redis 通常应用于哪些场景
Redis 由于其高性能和灵活的数据结构通常应用于以下场景
缓存通过缓存热点数据减少数据库压力。会话存储存储用户会话信息支持快速读取和更新。实时分析用于实时数据分析、统计和计数如访问量统计。排行榜和计数器支持快速的增减操作。消息队列通过列表结构实现消息的生产和消费。分布式锁实现对共享资源的互斥访问。
4. Redis 为什么这么快
Redis 之所以快速主要是由于以下几个因素
内存存储数据完全存储在内存中读写速度极快。单线程模型通过单线程避免了多线程的上下文切换和锁竞争。高效的数据结构使用高效的底层数据结构如跳表、字典等优化了数据的存取性能。异步IO在处理请求时采用非阻塞 IO允许多个请求并发执行。
5. 为什么 Redis 设计为单线程6.0 版本为何引入多线程
Redis 采用单线程设计是为了简化编程模型避免多线程环境下的复杂性如锁竞争。单线程可以确保操作的原子性从而避免数据不一致的问题。然而这并不妨碍 Redis 在处理 IO 请求时使用异步方式。
在 Redis 6.0 中引入了多线程主要是为了提高网络 I/O 的处理效率。多线程用于处理客户端请求和网络 I/O特别是在处理大量并发连接时可以显著提高性能。同时Redis 仍然保持了核心数据结构的操作为单线程以确保数据的一致性和安全性。
6. Redis 中常见的数据类型有哪些
Redis 支持多种数据类型主要包括
字符串String最基本的数据类型可以存储任意类型的数据如文本、二进制数据。哈希Hash用于存储对象包含多个键值对。列表List有序的字符串集合支持插入、删除等操作。集合Set无序的字符串集合支持交集、并集等操作。有序集合Sorted Set每个元素都有一个分数自动按分数排序。位图Bitmap、超日志HyperLogLog、**地理空间Geo**等高级数据结构。
7. Redis 中跳表的实现原理是什么
跳表Skip List是一种多层链表结构每一层都是对下一层的有序集合的简化允许快速的插入、删除和查找操作。Redis 中使用跳表来实现有序集合Sorted Set。跳表通过在底层链表的基础上添加多层索引使得查找时间复杂度降低到 O(log n)插入和删除操作也能保持在 O(log n) 的复杂度。
8. Redis 的 hash 是什么
Redis 的哈希Hash是一种数据结构用于存储键值对的集合。每个哈希可以包含多个字段每个字段都可以映射到一个值。哈希特别适合存储对象或实体例如用户信息等。它允许对单个字段的操作而不需要对整个哈希进行操作从而提高性能和效率。
9. Redis 和 Memcached 有哪些区别
Redis 和 Memcached 的主要区别包括
数据结构Redis 支持多种数据结构如字符串、哈希、列表、集合等而 Memcached 主要支持键值对。持久化Redis 提供数据持久化机制RDB 和 AOF而 Memcached 是纯内存存储重启后数据会丢失。功能Redis 支持更多功能如发布订阅、事务、Lua 脚本等而 Memcached 功能相对较少。内存管理Redis 具有更复杂的内存管理机制支持内存淘汰策略而 Memcached 主要采用 LRU 策略。
10. Redis 支持事务吗如何实现
Redis 支持事务但与传统关系数据库的事务不同。Redis 的事务通过 MULTI、EXEC、DISCARD 和 WATCH 命令来实现
MULTI标记事务的开始。EXEC执行事务中的所有命令。DISCARD放弃事务。WATCH监视一个或多个键当监视的键被修改时事务会失败。
Redis 的事务不支持回滚功能。
11. Redis 数据过期后的删除策略是什么
Redis 数据过期后的删除策略主要有两种
定期删除Redis 在每个周期内随机检查一部分键删除已过期的键。惰性删除当访问某个键时如果发现该键已过期则立即将其删除。
这种组合策略确保了在大多数情况下能够及时删除过期数据同时减少了不必要的性能开销。
12. Redis 中有哪些内存淘汰策略
Redis 提供多种内存淘汰策略以应对内存不足的情况主要包括
noeviction不淘汰任何数据返回错误。allkeys-lru从所有键中按 LRU最少使用策略淘汰。volatile-lru仅从设置了过期时间的键中按 LRU 淘汰。allkeys-random随机淘汰所有键中的任意一个。volatile-random随机淘汰设置了过期时间的键。volatile-ttl优先淘汰即将过期的键。
13. Redis 的 Lua 脚本功能是什么如何使用
Redis 的 Lua 脚本功能允许用户通过 Lua 脚本执行一系列命令从而确保操作的原子性。Lua 脚本可以通过 EVAL 命令执行语法如下
EVAL 脚本内容 numkeys key1 key2 ... arg1 arg2 ...其中numkeys 指定键的数量key1、key2 等是需要操作的键arg1、arg2 等是传递给脚本的参数。
14. Redis 的 Pipeline 功能是什么
Redis 的 Pipeline 功能允许客户端一次性发送多条命令而无需等待每条命令的响应。这可以减少网络延迟提高性能。使用 Pipeline 时客户端将所有命令打包后一次性发送最后再读取所有响应。这对于需要大量命令执行的场景非常有效。
15. Redis 中的 Big Key 问题是什么如何解决
Big Key 问题指的是在 Redis 中存储非常大的键或值这会导致性能下降和内存浪费。大键的操作如序列化、反序列化等会增加 CPU 使用率导致性能瓶颈。解决方案包括
避免存储大对象将大对象拆分成多个小对象。使用合适的数据结构根据数据访问模式选择合适的数据结构避免冗余数据。监控和优化使用 Redis 提供的工具监控键的大小和性能及时调整。
16. 如何解决 Redis 中的热点 key 问题
热点 key 问题
指的是某个键被大量请求导致性能下降。解决方案包括
数据分片将热点数据分散到多个键中。使用过期策略对热点数据设置合理的过期时间平衡访问。增加缓存层在 Redis 之上增加一层缓存如 Memcached以减少对 Redis 的压力。异步更新将对热点数据的写入操作改为异步方式减轻即时压力。
17. Redis 的持久化机制有哪些
Redis 提供了两种持久化机制
RDB快照定期将内存数据快照保存到磁盘适合大规模数据的恢复。AOF追加文件将所有写操作追加到日志文件中支持数据恢复。AOF 文件可以配置为每次写入后立即保存或者按时间间隔保存。
用户可以根据需求选择合适的持久化方式甚至可以同时使用 RDB 和 AOF。
18. Redis 在生成 RDB 文件时如何处理请求
在生成 RDB 文件时Redis 会使用 fork 创建一个子进程。主进程会继续处理客户端请求而子进程负责将内存中的数据快照写入 RDB 文件。这样可以避免在持久化过程中阻塞主进程确保服务的高可用性。
19. Redis 的哨兵机制是什么
Redis 的哨兵Sentinel机制用于监控 Redis 服务器的状态并实现高可用性。哨兵可以自动检测主节点的故障并在故障发生时进行故障转移Failover将某个从节点提升为主节点。此外哨兵还负责通知客户端新的主节点地址以便客户端能继续访问服务。哨兵模式使得 Redis 能够在不干预的情况下自动恢复服务。
20. Redis 集群会出现脑裂问题吗
Redis 集群在某些情况下确实可能出现脑裂问题尤其是在网络分区或节点失联的情况下。当集群中的节点无法确定哪个节点是主节点时可能会出现两个主节点并同时接受写请求导致数据不一致。为了解决这个问题Redis 集群采用了投票机制和故障转移策略通过实现 quorum法定人数原则来避免脑裂现象。
21. Redis 的订阅发布功能是什么你了解吗
Redis 的订阅发布Pub/Sub功能是一种消息通信模式允许消息的发布者Publisher将消息发布到一个或多个频道Channel而订阅者Subscriber可以订阅这些频道以接收消息。当消息被发布时所有订阅了该频道的客户端都会接收到消息。Pub/Sub 适用于实时聊天、通知系统等场景。
22. Redis 中如何实现分布式锁
在 Redis 中实现分布式锁通常采用 SETNX 命令该命令只在键不存在时设置键的值。例如
客户端使用 SETNX lock_key unique_lock_id 尝试获取锁。成功后执行临界区代码。最后使用 DEL lock_key 释放锁。
为了防止死锁通常会设置一个超时时间确保在超时后锁自动释放。
23. 分布式锁在未完成逻辑前过期怎么办
如果分布式锁在未完成逻辑前过期可以考虑以下解决方案
延长锁的有效期在执行操作时定期更新锁的过期时间。使用 Redisson 或 Zookeeper使用这些成熟的分布式锁实现提供更可靠的锁机制。设计合理的超时时间根据业务逻辑合理设置锁的超时时间确保在完成逻辑时不会过期。
24. Redis 的 Red Lock 是什么你了解吗
Red Lock 是一种分布式锁算法由 Redis 创始人 Antirez 提出。其原理是通过在多个 Redis 节点上获取锁来确保安全性算法步骤如下
客户端向多个 Redis 实例请求锁。只有在大多数节点上成功设置锁后客户端才能确认获得锁。锁的过期时间要比操作的最大时间长以确保其他节点能够正确地处理锁。
这种机制可以在分布式环境中提供高可靠性的锁。
25. Redis 实现分布式锁时可能遇到的问题有哪些
在 Redis 实现分布式锁时可能遇到的问题包括
网络故障导致客户端无法获取锁或释放锁。锁超时业务逻辑处理时间过长导致锁意外失效。重复锁同一客户端在未释放锁的情况下重复请求导致其他客户端无法获取锁。分布式环境中的数据一致性问题确保所有节点状态一致以避免数据冲突。
26. Redis 中的缓存击穿、缓存穿透和缓存雪崩是什么
缓存击穿指的是热点数据在缓存中不存在时导致大量请求直击数据库造成瞬间压力过大。解决方案包括使用互斥锁避免同一时间多个请求去查询数据库。缓存穿透指的是查询一个一定不存在的数据导致每次请求都直接到达数据库造成压力。可以通过布隆过滤器等方式拦截不合法请求。缓存雪崩指的是大量缓存同时过期导致瞬间请求全部打到数据库造成崩溃。可以通过随机过期时间等手段来避免。
27. Redis 中如何保证缓存与数据库的数据一致性
保证缓存与数据库的一致性通常采用以下策略
写入时更新每次对数据库进行写操作时同时更新缓存。失效策略对缓存设置合理的过期时间避免数据长期不一致。双写一致性在高并发环境下采用分布式事务保证数据的一致性。异步更新在某些场景下可以使用消息队列异步更新缓存。
28. Redis String 类型的底层实现是什么
Redis 的字符串String类型底层实现使用了简单动态字符串SDSSimple Dynamic Strings。SDS 是一种比 C 风格字符串更安全和高效的字符串实现具备以下特点
长度信息SDS 记录字符串的实际长度避免重复计算。空间优化采用二次分配策略减少内存的频繁分配和释放。安全性防止缓冲区溢出避免内存安全问题。
29. 如何使用 Redis 快速实现排行榜
Redis 提供了有序集合Sorted Set来实现排行榜。使用有序集合的分数score来代表用户的分数用户的 ID 作为元素member。实现步骤如下
使用 ZADD 命令添加用户及其分数。使用 ZRANGE 或 ZREVRANGE 命令获取排行榜前 N 名用户。使用 ZINCRBY 命令更新用户分数。
30. 如何使用 Redis 快速实现布隆过滤器
布隆过滤器是一种空间效率高的概率数据结构可以快速判断某个元素是否存在。Redis 提供了 BF.ADD 和 BF.EXISTS 等命令来实现布隆过滤器。实现步骤如下
使用 BF.RESERVE 创建布隆过滤器并设置期望插入数量和误判率。使用 BF.ADD 插入元素。使用 BF.EXISTS 检查元素是否存在。
31. 如何使用 Redis 统计大量用户唯一访问量UV
可以使用 Redis 的 HyperLogLog 数据结构来高效统计唯一用户访问量UV。实现步骤如下
使用 PFADD 命令将每个用户的标识符添加到 HyperLogLog。使用 PFCOUNT 命令获取唯一用户的数量。
HyperLogLog 的空间效率非常高适合于大规模数据的统计。
32. Redis 中的 Geo 数据结构是什么
Redis 的 Geo 数据结构用于存储和查询地理位置信息。它支持根据经纬度进行范围查询和距离计算。实现步骤如下
使用 GEOADD 命令添加地理位置信息。使用 GEODIST 命令计算两点之间的距离。使用 GEORADIUS 命令根据半径范围查找附近的点。
33. 你在项目中使用的 Redis 客户端是什么
我在项目中使用的 Redis 客户端是 Jedis它是一个流行的 Java 客户端提供了简单的 API 接口适合与 Redis 进行交互。另一个常用的客户端是 Lettuce它是基于异步和反应式编程的。
34. Redis 字符串
类型的最大值大小是多少 Redis 中字符串类型的最大值大小为 512MB。这使得 Redis 能够存储较大的数据对象例如图像或文件内容。
35. Redis 性能瓶颈时如何处理
当 Redis 出现性能瓶颈时可以考虑以下优化方案
水平扩展通过增加更多 Redis 节点来分散负载。优化数据结构根据访问模式优化数据存储结构例如使用更合适的数据类型。合理设置过期时间定期清理过期数据保持内存的高效利用。监控和分析使用 Redis 监控工具如 Redis Monitor、Redis Insight监控性能瓶颈找出热点和慢查询。
36. Redis 中 EMBSTR 对象的阈值设置为何为 44其调整历史是什么
EMBSTREmbedding String是 Redis 中的一种优化字符串存储方式当字符串长度小于等于 44 字节时Redis 会将字符串与其元数据一起存储在同一内存块中以减少内存分配的开销。这个阈值的历史变化是为了在性能与内存占用之间取得平衡经过多次优化后最终设定为 44 字节以适应大部分字符串的存储需求。
37. Redis 中原生批处理命令MSET、MGET与 Pipeline 的区别是什么
MSET/MGET这两个命令用于批量设置和获取键值对Redis 会在一个请求中处理所有操作适合于较小的批量操作。Pipeline允许客户端在一个请求中发送多个命令而无需等待每个命令的响应从而减少网络延迟。适合于大量命令的执行性能更优。
38. Redis 主从复制的常见拓扑结构有哪些
Redis 主从复制的常见拓扑结构包括
主从结构一个主节点对应多个从节点从节点异步复制主节点的数据。链式复制一个从节点同时作为其他从节点的主节点形成链状结构。多主结构多个主节点相互复制数据适用于高可用性和负载均衡。
39. Redis List 类型的常见操作命令有哪些
Redis List 类型的常见操作命令包括
LPUSH在列表左侧插入元素。RPUSH在列表右侧插入元素。LPOP从列表左侧弹出元素。RPOP从列表右侧弹出元素。LRANGE获取列表中指定范围的元素。
40. 如何在 Redis 中实现队列和栈数据结构
队列使用 List 类型的 LPUSH 和 RPOP 命令实现先进先出FIFO的队列。栈使用 List 类型的 LPUSH 和 LPOP 命令实现后进先出LIFO的栈。
41. Redis 中的 Ziplist 和 Quicklist 数据结构的特点是什么
Ziplist一种紧凑的内存数据结构适用于小规模列表和哈希。通过压缩相邻元素来节省内存。Quicklist结合了双向链表和 ziplist 的优点支持高效的插入和删除操作适合大规模列表。适用于多种场景并具备较好的性能。
42. Redis 复制延迟的常见原因有哪些
Redis 复制延迟的常见原因包括
网络延迟主节点与从节点之间的网络不稳定。从节点负载过重从节点处理请求的能力不足导致延迟。慢查询从节点执行复杂查询时造成响应时间延长。大数据量如果主节点有大量数据变动从节点需要时间进行同步。
43. Redis 事务与关系型数据库事务的主要区别是什么
Redis 事务与关系型数据库事务的主要区别包括
原子性Redis 事务采用 MULTI/EXEC 命令块实现原子性但不支持回滚关系型数据库支持回滚机制。隔离性Redis 事务不支持事务隔离级别而关系型数据库提供多种隔离级别。执行方式Redis 事务是顺序执行不支持并发而关系型数据库可以并发执行。
44. Redis Cluster 模式与 Sentinel 模式的区别是什么
Cluster 模式Redis Cluster 提供数据分片和高可用性支持水平扩展通过自动分片机制实现节点之间的负载均衡。Sentinel 模式主要用于监控和故障转移不支持数据分片适用于单一主节点的高可用性场景。
45. Redis 的 ListPack 数据结构是什么
ListPack 是 Redis 为 List 和 Hash 类型引入的一种新数据结构旨在提高内存利用率和访问速度。它结合了压缩存储和快速访问的优势适合于存储较小的列表和哈希数据。
46. Redis 中的内存碎片化是什么如何进行优化
内存碎片化是指内存中存在大量未被使用的小块空间导致内存利用率降低。优化方法包括
定期重启 Redis 实例释放碎片化内存。使用 Redis 的内存管理工具如 MEMORY PURGE 命令释放未使用的内存。调整 Redis 的内存配置根据需求合理配置内存策略。
47. Redis 的虚拟内存VM机制是什么
Redis 的虚拟内存VM机制是一种将数据从内存转移到磁盘的方式。通过将不常用的数据移出内存可以保持内存使用的高效性。但 Redis 2.0 后虚拟内存机制被弃用Redis 推荐使用更高效的持久化策略如 RDB 和 AOF。
48. 在 Redis 集群中如何根据键定位到对应的节点
在 Redis 集群中键通过哈希槽hash slot定位到对应的节点。Redis 使用 CRC16 哈希算法将键映射到 0-16383 的槽中槽与节点一一对应。具体步骤为
计算键的哈希值。通过哈希值确定对应的哈希槽。根据槽找到对应的节点进行操作。
49. Redis 源码中有哪些巧妙的设计举几个典型的例子
Redis 源码中的巧妙设计包括
单线程模型使用事件循环机制避免上下文切换提高性能。多种数据结构的选择如 ziplist、quicklist 和 hashtable 等根据数据大小动态选择最优结构。简单而高效的持久化机制结合 RDB 和 AOF 提供灵活的数据持久化方案。
50. 说说 Redisson 分布式锁的原理?
Redisson 是一个 Java 客户端提供了分布式锁的实现。其原理基于 Redis 的 SETNX 命令结合了一些优化策略如
使用 tryLock 和 unlock 方法提供锁的获取和释放。利用 Redis 的过期时间确保锁在业务处理失败时能够自动释放。在高并发环境下采用重入锁的机制确保同一线程可以多次获取锁而不会造成死锁。
Spring
什么是循环依赖常问
循环依赖是指在对象创建过程中两个或多个对象相互依赖形成了一个闭环。例如类 A 依赖于类 B类 B 又依赖于类 A。这样在实例化时就会导致无法完成对象的创建因为每个对象都在等待另一个对象的创建完成。
Spring 如何解决循环依赖
Spring 通过使用三级缓存来解决循环依赖的问题
一级缓存singletonObjects存放已创建的单例 Bean。二级缓存earlySingletonObjects存放尚未完全初始化但已创建的单例 Bean。这些 Bean 处于“半成品”状态可以通过依赖注入使用。三级缓存singletonFactoryObjects存放 Bean 的 Factory允许通过 ObjectFactory 获取未完成的 Bean 实例。
当 Spring 容器遇到循环依赖时会首先将 Bean 注册到二级缓存中以便在另一个 Bean 中注入时可以使用。
为什么 Spring 循环依赖需要三级缓存二级不够吗
二级缓存不能完全解决循环依赖问题因为它仅仅存储已创建但未完全初始化的 Bean。在某些情况下Bean 需要完全初始化后才能使用其依赖项因此三级缓存提供了额外的灵活性使得可以在依赖注入过程中允许获取到“半成品” Bean。
看过源码吗说下 Spring 由哪些重要的模块组成
Spring 框架由多个重要模块组成主要包括
Core Container提供基本的功能如 BeanFactory、ApplicationContext 等。AOP提供面向切面编程的支持。Data Access/Integration支持 JDBC、ORM、JPA 等数据库访问技术。Web提供与 Web 应用相关的功能包括 Spring MVC。Security提供安全管理的支持。Test支持单元测试的模块。
什么是 Spring IOC
Spring IOC控制反转是一种设计模式它通过将对象的创建和依赖管理从应用程序代码中抽离出来交由 Spring 容器来管理。开发者只需通过配置如 XML 文件、注解等定义 Bean 及其依赖关系Spring 容器会负责创建和注入这些依赖。
Spring IOC 有什么好处
解耦减少了类与类之间的依赖关系使得代码更易于维护和测试。可配置性可以通过外部配置轻松地更改对象的行为。生命周期管理Spring 负责管理 Bean 的生命周期包括初始化和销毁。便于测试可以通过 Mock 对象轻松进行单元测试。
Spring 中的 DI 是什么
DI依赖注入是实现 IOC 的一种方式。它通过构造函数、setter 方法或接口将依赖的对象传递给目标对象使得目标对象不需要自己去创建依赖对象而是由容器负责管理。
什么是 Spring Bean
Spring Bean 是由 Spring 容器管理的对象通常是应用程序中用到的服务、组件或数据访问对象。Bean 的生命周期由 Spring 容器控制。
Spring 中的 BeanFactory 是什么
BeanFactory 是 Spring 的基础容器接口负责 Bean 的创建和管理。它延迟加载 Bean即只有在需要时才会创建 Bean适用于资源有限的环境。
Spring 中的 FactoryBean 是什么
FactoryBean 是一种特殊的 Bean允许用户自定义 Bean 的创建逻辑。实现了 FactoryBean 接口的类可以返回一个新实例而不是简单的 Bean 实例。
Spring 中的 ObjectFactory 是什么
ObjectFactory 是 Spring 提供的一个接口用于获取一个对象的实例。它通常用于实现懒加载和解决循环依赖。
Spring 中的 ApplicationContext 是什么
ApplicationContext 是 Spring 的高级容器继承了 BeanFactory 的功能提供更多的功能例如事件传播、国际化支持等。它是一个完整的 Spring IoC 容器。
Spring Bean 一共有几种作用域
Spring Bean 主要有五种作用域
singleton单例整个应用程序中只创建一个 Bean 实例。prototype原型每次请求都会创建一个新的 Bean 实例。request请求作用域仅在 HTTP 请求内有效Web 环境。session会话作用域绑定到 HTTP 会话Web 环境。globalSession全局会话绑定到全局 HTTP 会话用于 portlet 应用。
Spring 一共有几种注入方式
Spring 主要有三种注入方式
构造器注入通过构造函数传递依赖。setter 注入通过 setter 方法设置依赖。接口注入通过实现特定接口设置依赖。
什么是 AOP
AOP面向切面编程是一种编程范式它通过定义切面Aspect将横切关注点如事务管理、日志记录等从业务逻辑中分离出来从而增强代码的模块性。
Spring AOP 默认用的是什么动态代理两者的区别
Spring AOP 默认使用 JDK 动态代理和 CGLIB 代理
JDK 动态代理只能代理实现了接口的类。CGLIB可以代理任何类不要求实现接口。
能说说 Spring 拦截链的实现吗
Spring 拦截链通常是通过 AOP 机制实现的拦截器可以在方法执行前后插入自定义逻辑。拦截器链中的每个拦截器都可以决定是否继续执行下一个拦截器。Spring 中的 HandlerInterceptor 和 Filter 也可以实现类似功能。
Spring AOP 和 AspectJ 有什么区别
实现方式 Spring AOP基于代理主要使用 JDK 动态代理和 CGLIB。AspectJ是一个独立的框架通过字节码增强技术在编译时或运行时进行切面处理。 功能 Spring AOP适合简单的切面需求。AspectJ提供更强大的切面编程能力支持更复杂的切点表达式。
说下 Spring Bean 的生命周期
Spring Bean 的生命周期主要包括以下几个阶段
实例化容器创建 Bean 实例。属性填充注入 Bean 的依赖。初始化调用 PostConstruct 方法和 InitializingBean 接口的 afterPropertiesSet 方法。使用Bean 进入正常使用阶段。销毁调用 PreDestroy 方法和 DisposableBean 接口的 destroy 方法。
说下对 Spring MVC 的理解
Spring MVC 是一种基于 MVC模型-视图-控制器设计模式的 Web 框架。它通过 DispatcherServlet 作为前端控制器处理请求并将其分发到相应的处理器Controller实现请求和响应的分离。
Spring MVC 具体的工作原理
请求到达 DispatcherServlet所有请求都由 DispatcherServlet 处理。请求映射DispatcherServlet 查找匹配的处理器。调用处理器找到合适的 Controller调用相应的方法处理请求。返回视图处理完成后返回视图名DispatcherServlet 根据视图解析器将视图解析为具体视图对象。渲染视图最终将视图渲染到客户端。
SpringMVC 父子容器是什么知道吗
在 Spring MVC 中父子容器模式允许创建一个父 ApplicationContext子 ApplicationContext 可以继承父容器中的 Bean 定义。这样可以实现模块化便于管理和维护。
你了解的 Spring 都用到哪些设计模式
Spring 框架中使用了多种设计模式主要包括
单例模式Bean 默认是单例。工厂模式通过 FactoryBean 创建对象。代理模式AOP 使用的代理机制。观察者模式事件机制的实现。模板方法模式JdbcTemplate 等实现。
Spring 事务有几个隔离级别
Spring 事务提供了以下四种隔离级别
DEFAULT使用底层数据库的默认隔离级别。READ_UNCOMMITTED允许脏读。READ_COMMITTED禁止脏读允许不可重复读。REPEATABLE_READ禁止脏读和不可重复读允许幻读。SERIALIZABLE完全隔离避免所有并发问题
。
Spring 有哪几种事务传播行为
Spring 事务的传播行为主要包括
REQUIRED默认传播行为支持当前事务如果没有则新建。REQUIRES_NEW新建一个事务暂停当前事务。NESTED如果当前事务存在则创建一个嵌套事务。SUPPORTS支持当前事务如果没有则以非事务方式执行。MANDATORY当前必须存在事务否则抛出异常。NEVER以非事务方式执行如果当前存在事务则抛出异常。NOT_SUPPORTED以非事务方式执行如果存在事务则挂起当前事务。
Spring 事务传播行为有什么用
事务传播行为控制了事务在方法调用之间的传播方式决定了在不同方法调用之间如何处理事务以确保数据的一致性和完整性。例如REQUIRED 可以避免重复开启事务而 REQUIRES_NEW 可以在某些情况下强制新建事务。
Spring 的优点
灵活性通过 IoC 和 AOP 提供灵活的开发方式。易于集成与多种框架和技术如 Hibernate、JPA 等兼容。广泛的社区支持拥有大量的文档和社区支持。模块化清晰的模块化设计提高了代码的可维护性。
Spring AOP 相关术语都有哪些
切面Aspect横切关注点的模块化。连接点Join Point可以插入切面的程序点。切点Pointcut定义在哪些连接点应用切面。通知Advice切面在连接点处的具体操作。目标对象Target Object被代理的对象。代理Proxy实现了切面逻辑的对象。
Spring 通知有哪些类型
Spring 通知主要包括
前置通知Before在目标方法执行前执行。后置通知After在目标方法执行后执行。返回通知After Returning在目标方法成功返回后执行。异常通知After Throwing在目标方法抛出异常后执行。环绕通知Around在目标方法执行前后都执行的通知。
Spring IOC 容器初始化过程
读取配置加载 XML 文件或注解配置。创建 BeanDefinition将配置转化为 BeanDefinition。注册 BeanDefinition将 BeanDefinition 注册到容器中。实例化 Bean根据 BeanDefinition 创建 Bean 实例。依赖注入填充 Bean 的属性和依赖。
Spring Bean 注册到容器有哪些方式
XML 配置在 XML 文件中定义 Bean。注解配置使用 Component、Service 等注解自动注册。Java 配置使用 Configuration 和 Bean 注解定义 Bean。
Spring 自动装配的方式有哪些
Spring 提供了几种自动装配的方式
按类型自动装配Autowired。按名称自动装配。Qualifier 注解结合 Autowired 指定具体 Bean。Primary 注解标记首选 Bean。
Qualifier 注解有什么作用
Qualifier 注解用于指定在自动装配时所需的具体 Bean当存在多个同类型的 Bean 时可以通过该注解精确指定所需的 Bean。
Bean和Component有什么区别
Bean用于方法上表明该方法返回的对象是一个 Bean。Component用于类上表明该类是一个 Bean由 Spring 自动检测。
Component、Controller、Repository和Service 的区别
Component通用的组件标识。Controller用于表示控制器类通常与 Spring MVC 一起使用。Repository用于数据访问层提供持久化支持。Service用于服务层表示业务逻辑。
Spring 事务在什么情况下会失效
Spring 事务可能在以下情况下失效
调用同一类中的另一个事务方法因为 Spring 默认使用 AOP 代理会导致事务无法生效。非 Spring 管理的对象调用如果事务方法在非 Spring 管理的对象中调用事务将失效。方法抛出 RuntimeException 以外的异常默认情况下事务只对 RuntimeException 进行回滚。
说说 Spring 启动过程
Spring 启动过程主要包括以下步骤
加载 Spring 配置文件如 XML 或注解配置。初始化 ApplicationContext创建 Spring 容器。创建和初始化 Bean根据配置实例化 Bean。处理依赖注入填充 Bean 的属性。启动上下文完成 Bean 的初始化准备服务。
Spring 的单例 Bean 是否有并发安全问题
Spring 的单例 Bean 默认是线程安全的因为 Spring 会在创建时将其初始化并缓存。但开发者需要确保在 Bean 内部的状态是不可变的或使用适当的同步机制处理共享状态。
Spring中的Primary注解的作用是什么
Primary 注解用于指示在自动装配时优先选择标记为 Primary 的 Bean尤其是在存在多个同类型的 Bean 时。
Spring中的Value注解的作用是什么
Value 注解用于注入外部配置如属性文件中的值到 Spring Bean 的字段中可以注入基本数据类型、字符串和表达式等。
Spring 中的 Profile 注解的作用是什么
Profile 注解用于定义 Bean 的作用域指定在特定的配置文件或环境下启用的 Bean例如开发环境和生产环境的不同 Bean 配置。
Spring 中的 PostConstruct 和 PreDestroy 注解的作用是什么
PostConstruct在 Bean 初始化后执行的方法。PreDestroy在 Bean 销毁前执行的方法用于释放资源。
Spring 中的 RequestBody 和 ResponseBody 注解的作用是什么
RequestBody将 HTTP 请求体中的内容转换为 Java 对象。ResponseBody将 Java 对象转换为 HTTP 响应体的内容。
Spring 中的 PathVariable 注解的作用是什么
PathVariable 注解用于从请求 URL 中提取路径变量并将其映射到方法参数上。
Spring中的 ModelAttribute 注解的作用是什么
ModelAttribute 注解用于将请求参数绑定到方法参数或模型属性上通常用于处理表单提交。
Spring 中的 ExceptionHandler 注解的作用是什么
ExceptionHandler 注解用于定义处理特定异常的方法以便在控制器层统一处理异常。
Spring 中的 ResponseStatus 注解的作用是什么
ResponseStatus 注解用于定义 HTTP 响应的状态码常用于异常处理时设置响应状态。
Spring 中的 RequestHeader 和 CookieValue 注解的作用是什么
RequestHeader用于绑定请求头信息到方法参数。CookieValue用于绑定 Cookie 值到方法参数。
Spring 中的 SessionAttribute 注解的作用是什么
SessionAttribute 注解用于将模型属性存储在 HTTP 会话中以便跨多个请求访问。
Spring 中的 Validated 和 Valid 注解有什么区别
Valid由 JSR-303 提供进行对象验证。Validated是 Spring 的扩展支持分组验证。
Spring 中的 Scheduled 注解的作用是什么
Scheduled 注解用于定义定时任务可以指定任务的执行频率和时间间隔。
Spring 中的 Cacheable 和 CacheEvict 注解的作用是什么
Cacheable用于标记方法的返回值应缓存。CacheEvict用于从缓存中移除某个数据。
Spring 中的 Conditional 注解的作用是什么
Conditional 注解用于根据特定条件决定是否创建 Bean可以用于环境配置或特定条件下的 Bean 加载。
Spring 中的 Lazy 注解的作用是什么
Lazy 注解用于指定 Bean 采用懒加载的方式只有在实际需要时才会创建 Bean。
Spring 中的 PropertySource 注解的作用是什么
PropertySource 注解用于加载外部属性文件允许通过 ${} 语法访问属性。
Spring 中的 EventListener 注解的作用是什么
EventListener 注解用于定义事件监听器当特定事件发布时触发相应的方法。
Spring 和 Spring MVC 的关系是什么
Spring 是一个广泛的框架提供了 Io
C、AOP 等功能而 Spring MVC 是 Spring 的一个模块专注于构建基于 MVC 设计模式的 Web 应用程序。
Spring WebFlux 是什么它与 Spring MVC 有何不同
Spring WebFlux 是 Spring 5 引入的响应式编程框架支持非阻塞式 Web 应用。而 Spring MVC 是传统的阻塞式模型。WebFlux 适合处理高并发场景。
介绍下 Spring MVC 的核心组件
Spring MVC 的核心组件包括
DispatcherServlet前端控制器负责请求的分发和处理。Controller处理请求的核心组件返回 ModelAndView。ViewResolver根据逻辑视图名解析到具体视图。HandlerMapping将请求映射到相应的 Controller。Interceptor用于处理请求的拦截逻辑。
什么是 Restful 风格的接口
Restful 风格的接口遵循 RESTRepresentational State Transfer架构风格使用 HTTP 协议利用 HTTP 方法如 GET、POST、PUT、DELETE进行资源的操作。
Spring MVC中的Controller是什么如何定义一个Controller
Controller 是处理请求的组件通常通过 Controller 注解定义。定义方式如下
Controller
public class MyController {RequestMapping(/hello)public String hello() {return hello;}
}Spring MVC 中如何处理表单提交
Spring MVC 通过 RequestMapping 处理表单提交将表单数据绑定到 Java 对象中。
Spring MVC 中的视图解析器有什么作用
视图解析器用于将控制器返回的视图名解析为具体的视图实现如 JSP 页面。
Spring MVC 中的拦截器是什么如何定义一个拦截器
拦截器用于处理请求的前后逻辑如权限验证。定义拦截器需实现 HandlerInterceptor 接口并注册到 WebMvcConfigurer 中。
Spring MVC 中的国际化支持是如何实现的
Spring MVC 通过 MessageSource 和 LocaleResolver 提供国际化支持可以根据用户的语言和地区加载不同的消息。
Spring MVC 中如何处理异常
Spring MVC 通过 ExceptionHandler 注解处理异常或者使用 ControllerAdvice 来统一处理异常。
Spring 中的 JPA 和 Hibernate 有什么区别
JPAJava Persistence API是一个规范定义了数据持久化的接口。Hibernate是实现 JPA 规范的具体框架提供 ORM 功能。
这些问题和答案涵盖了 Spring 框架的多个重要方面希望能帮助你更深入地理解 Spring 及其核心概念。
SpringBoot
以下是关于 Spring Boot 的详细解答
说说 Springboot 的启动流程
Spring Boot 的启动流程可以概括为以下几个步骤
引导类Main Class Spring Boot 应用程序以一个 SpringBootApplication 注解的类为入口该类通常包含 main 方法。 创建 Spring 应用上下文 在 main 方法中调用 SpringApplication.run() 来启动应用。这会创建一个 SpringApplication 实例并在其内部初始化一个 ApplicationContext通常是 AnnotationConfigApplicationContext 或 WebApplicationContext。 加载环境配置 Spring Boot 会加载 application.properties 或 application.yml 等配置文件并解析环境变量及命令行参数。 自动配置 Spring Boot 根据项目的类路径和配置文件自动配置相关的 Spring 组件使用 EnableAutoConfiguration 注解来实现。 创建 Bean 解析配置后Spring Boot 创建应用所需的 Bean扫描并注册由 Component, Service, Controller 等注解标识的类。 启动嵌入式服务器 如果是 Web 应用Spring Boot 会启动嵌入式 Web 服务器如 Tomcat、Jetty 或 Undertow并将应用注册到该服务器上。 事件发布 Spring Boot 会发布 ApplicationReadyEvent 事件通知所有的监听器应用已经准备好。
什么是 Spring Boot
Spring Boot 是一个基于 Spring 框架的开源 Java 应用程序框架旨在简化 Spring 应用程序的开发和配置。它通过提供一系列约定优于配置的默认设置帮助开发者快速搭建和部署应用程序。Spring Boot 还集成了嵌入式服务器使得开发者可以不需要外部服务器就能运行 Web 应用。
Spring Boot 的核心特性有哪些
Spring Boot 的核心特性包括
自动配置根据项目的类路径和 Bean 定义自动配置 Spring 应用程序。起步依赖Starter Dependencies简化 Maven 依赖管理提供一系列预配置的依赖集。嵌入式服务器支持嵌入式 Tomcat、Jetty 和 Undertow简化 Web 应用的部署和运行。生产就绪功能内置健康检查、度量监控和审计功能通过 Spring Actuator 提供。简化的配置通过 application.properties 或 application.yml 文件进行集中管理。
Spring Boot 是如何通过 main 方法启动 web 项目的
Spring Boot 通过在 main 方法中调用 SpringApplication.run() 方法来启动 Web 项目。该方法会
初始化 SpringApplication 实例。创建和刷新 ApplicationContext。启动嵌入式 Web 服务器如 Tomcat。扫描并注册应用中的 Spring Bean。发布应用准备完成事件。
SpringBoot 是如何实现自动配置的
Spring Boot 的自动配置依赖于 spring-boot-autoconfigure 模块。它通过 EnableAutoConfiguration 注解触发扫描应用的类路径自动推断所需的 Bean并根据配置文件提供的属性进行相应配置。每个自动配置类通常使用 Conditional 注解来控制是否生效从而确保仅在所需的条件下进行配置。
Spring Boot 支持哪些嵌入 Web 容器
Spring Boot 支持以下嵌入式 Web 容器
Tomcat默认嵌入式容器。Jetty轻量级的 Servlet 容器。Undertow高性能的 Web 服务器和 Servlet 容器。
开发者可以通过 Maven 或 Gradle 配置来选择所需的容器。
Spring Boot 中 application.properties 和 application.yml 的区别是什么
格式application.properties 是基于键值对的格式而 application.yml 使用 YAML 格式支持更复杂的层次结构。可读性YAML 格式通常更易读适合复杂配置。支持两者都被 Spring Boot 支持开发者可根据个人偏好选择使用。
如何在 Spring Boot 中定义和读取自定义配置
定义配置 在 application.properties 或 application.yml 中定义自定义属性例如
my.custom.propertyvalue读取配置 使用 Value 注解注入自定义配置
Value(${my.custom.property})
private String myProperty;- 或者通过 ConfigurationProperties 创建一个配置类ConfigurationProperties(prefix my.custom)
public class MyConfig {private String property;
}Spring Boot 配置文件加载优先级你知道吗
Spring Boot 配置文件的加载优先级从高到低依次为
命令行参数通过命令行启动时传入的参数。Java 系统属性使用 -D 参数传入的系统属性。环境变量操作系统的环境变量。application.properties** 和 **application.yml在 classpath 中的配置文件。默认值在代码中定义的默认值。
Spring Boot 打成的 jar 和普通的 jar 有什么区别 ?
Spring Boot 打包的 JAR 文件具有以下特点
可执行 JAR包含了嵌入式的 Web 容器和所有依赖允许直接通过 java -jar 命令运行。重组结构打包时会重新组织 JAR 文件的结构确保所有依赖项正确加载。META-INF/MANIFEST.MF包含了 Spring Boot 特有的启动配置。
Spring Boot 是否可以使用 XML 配置 ?
Spring Boot 支持使用 XML 配置但不推荐这样做。它的设计理念是“约定优于配置”鼓励使用 Java 注解和属性文件来配置应用程序。如果需要 XML 配置可以通过添加 ImportResource 注解来导入 XML 配置文件。
SpringBoot 默认同时可以处理的最大连接数是多少
Spring Boot 默认的最大连接数取决于所使用的嵌入式 Web 容器。对于 Tomcat默认最大连接数是 200通常可以通过在 application.properties 中配置来调整
server.tomcat.max-connections300如何理解 Spring Boot 中的 starter
Spring Boot 中的 Starter 是一组预先配置好的 Maven 依赖可以简化项目配置。通过引入特定的 Starter开发者可以快速获得相关功能而不必手动配置每个依赖。例如spring-boot-starter-web 提供了构建 Web 应用所需的所有依赖。
Spring Boot 如何处理跨域请求CORS
Spring Boot 通过 CrossOrigin 注解处理跨域请求。可以在控制器类或方法上添加该注解指定允许跨域的源、请求方法等属性。例如
CrossOrigin(origins http://example.com)
RestController
public class MyController {// ...
}也可以通过配置类全局设置 CORS 策略
Configuration
public class WebConfig implements WebMvcConfigurer {Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping(/**).allowedOrigins(http://example.com);}
}在 Spring Boot 中你是怎么使用拦截器的
在 Spring Boot 中使用拦截器的步骤如下
创建拦截器类实现 HandlerInterceptor 接口。
public class MyInterceptor implements HandlerInterceptor {Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 处理请求前逻辑return true; // 返回 true 继续处理请求}
}注册拦截器在配置类中实现 WebMvcConfigurer 接口
Configuration
public class WebConfig implements WebMvcConfigurer {Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new MyInterceptor()).addPathPatterns(/**);}
}SpringBoot 中如何实现定时任务 ?
Spring Boot 通过 Scheduled 注解来实现定时任务。步骤如下
启用定时任务在主类上添加 EnableScheduling 注解。
SpringBootApplication
EnableScheduling
public class MyApplication {public static void main(String[] args) {SpringApplication.run(MyApplication.class, args);}
}定义定时任务使用
Scheduled 注解的方法
Scheduled(fixedRate 5000) // 每 5 秒执行一次
public void task() {// 定时执行的逻辑
}什么是 Spring Actuator它有什么优势
Spring Actuator 是 Spring Boot 提供的一个功能模块用于监控和管理 Spring Boot 应用。它提供了一系列的 REST API 端点可以获取应用的健康状况、度量数据、环境信息等。其优势包括
健康检查可以快速检查应用的运行状态。度量监控提供应用性能指标和统计信息。自定义端点可以轻松添加自定义的管理端点。
Spring Boot 2.x 与 1.x 版本有哪些主要的改进和区别
性能提升2.x 在性能方面进行了优化。依赖管理更新了依赖版本更好地支持最新的 Spring 生态系统。配置简化增强了自动配置的功能和灵活性。新的特性引入了诸如 WebFlux 和响应式编程的支持。
Spring Boot 3.x 与 2.x 版本有哪些主要的改进和区别
Java 17 支持3.x 版本要求最低 Java 17。模块化重构了某些模块提供更好的性能和可维护性。新的特性引入了 Spring Native 支持增强了对 GraalVM 的支持。不再支持某些过时的特性例如移除了对 Spring Security 的一些老旧功能支持。
说说你对 Spring Boot 事件机制的了解
Spring Boot 的事件机制基于 Spring 的事件发布/订阅模型。主要包括
事件定义一个事件类继承 ApplicationEvent。监听器创建一个监听器类使用 EventListener 注解或实现 ApplicationListener 接口来处理事件。发布事件使用 ApplicationEventPublisher 发布事件。
示例
public class MyEvent extends ApplicationEvent {public MyEvent(Object source) {super(source);}
}Component
public class MyEventListener {EventListenerpublic void handleMyEvent(MyEvent event) {// 处理事件逻辑}
}在 Spring Boot 中如何实现多数据源配置
在 Spring Boot 中实现多数据源配置的步骤
定义数据源配置类分别为每个数据源创建配置
Configuration
public class DataSourceConfig {Bean(name dataSource1)PrimaryConfigurationProperties(prefix spring.datasource1)public DataSource dataSource1() {return DataSourceBuilder.create().build();}Bean(name dataSource2)ConfigurationProperties(prefix spring.datasource2)public DataSource dataSource2() {return DataSourceBuilder.create().build();}
}配置属性在 application.yml 中定义多个数据源
spring:datasource1:url: jdbc:mysql://localhost:3306/db1username: user1password: pass1datasource2:url: jdbc:mysql://localhost:3306/db2username: user2password: pass2使用数据源在 DAO 或 Repository 中使用 Qualifier 注解来指定使用哪个数据源
Autowired
Qualifier(dataSource1)
private DataSource dataSource;Spring Boot 中如何实现异步处理
在 Spring Boot 中实现异步处理的步骤
启用异步支持在主类上添加 EnableAsync 注解。
SpringBootApplication
EnableAsync
public class MyApplication {// ...
}定义异步方法使用 Async 注解标记
Async
public CompletableFutureString asyncMethod() {// 异步执行的逻辑return CompletableFuture.completedFuture(result);
}调用异步方法直接调用该方法它会在新的线程中执行。
如何在 SpringBoot 启动时执行特定代码有哪些方式
在 Spring Boot 启动时执行特定代码可以使用以下方式
CommandLineRunner实现 CommandLineRunner 接口的方法会在 Spring 应用启动后执行。
Component
public class MyRunner implements CommandLineRunner {Overridepublic void run(String... args) {// 启动时执行的逻辑}
}ApplicationRunner类似于 CommandLineRunner但可以获取应用上下文的信息。
Component
public class MyRunner implements ApplicationRunner {Overridepublic void run(ApplicationArguments args) {// 启动时执行的逻辑}
}PostConstruct 注解在 Bean 初始化完成后执行的方法。
Component
public class MyComponent {PostConstructpublic void init() {// 启动时执行的逻辑}
}SpringBootSpring中为什么不推荐使用 Autowired
在 Spring Boot 中虽然 Autowired 是常用的依赖注入方式但不推荐过度使用主要是因为
构造器注入的优势构造器注入是更推荐的方式因为它可以使依赖关系显式化增强代码的可测试性和可读性。避免循环依赖使用构造器注入可以更好地防止循环依赖问题。简化测试构造器注入便于使用模拟对象进行单元测试避免在测试中引入 Spring 上下文。
因此在类中使用构造器注入而非字段注入是一种更佳的实践。
SpringCloud
什么是配置中心有哪些常见的配置中心
配置中心是一种集中管理应用程序配置的工具允许开发人员和运维人员动态地更新和管理配置避免硬编码和配置文件的分散管理。常见的配置中心包括
Spring Cloud Config为 Spring 应用程序提供的集中配置管理解决方案。Nacos阿里巴巴开源的动态服务发现、配置管理和服务管理平台。ConsulHashiCorp 开发的用于服务发现和配置的工具支持健康检查和负载均衡。ZookeeperApache 提供的开源分布式协调服务广泛用于配置管理和服务发现。
你知道 Nacos 配置中心的实现原理吗
Nacos 的实现原理主要包括以下几个方面
配置管理Nacos 将配置信息存储在内存和持久化存储中可以通过 REST API 或 SDK 来进行配置的管理和发布。动态更新支持动态配置更新应用在运行时可以自动获取最新的配置。命名空间通过命名空间来隔离不同环境的配置。健康监测内置健康监测功能确保服务的可用性。
为什么需要服务注册发现
服务注册发现是微服务架构中的重要组成部分其主要作用是
动态服务定位服务实例可以随时上线和下线服务注册中心可以动态更新服务列表。负载均衡通过服务注册中心可以实现服务的负载均衡提升系统的稳定性和性能。降低耦合服务之间通过服务名而非具体地址进行调用降低了服务之间的耦合度。
为什么需要在微服务中使用链路追踪Spring Cloud 可以选择哪些微服务链路追踪方案
链路追踪用于监控请求在微服务架构中的流转路径主要原因包括
性能监控能够快速定位性能瓶颈。故障排查帮助开发人员理解问题发生的具体位置和原因。用户体验优化通过监控请求延迟优化用户体验。
Spring Cloud 可以选择的链路追踪方案有
Spring Cloud Sleuth集成链路追踪功能自动为请求生成唯一的跟踪 ID。Zipkin开源的链路追踪系统支持数据存储和分析。Jaeger另一种开源的分布式追踪系统适用于大规模分布式系统。
Spring Cloud 的优缺点有哪些
优点
灵活性高提供了丰富的组件可以根据需求选择使用。社区支持活跃的开源社区和文档支持广泛。与 Spring 生态兼容与 Spring Boot 紧密集成简化配置和开发流程。
缺点
学习曲线陡峭微服务架构和相关技术的复杂性可能增加学习成本。运维复杂性需要额外的运维工作来管理服务的部署、监控和健康检查。性能开销引入多个服务之间的网络通信可能增加性能开销。
Spring Boot 和 Spring Cloud 之间的区别
Spring Boot是一个用于简化 Spring 应用程序开发的框架主要关注快速构建独立的、生产级别的 Spring 应用。Spring Cloud是一个微服务开发的框架提供了分布式系统中的通用功能如服务注册与发现、负载均衡、配置管理等主要在 Spring Boot 的基础上扩展功能。
Spring Cloud 由什么组成
Spring Cloud 主要由以下几个核心组件组成
服务发现如 Eureka、Consul、Zookeeper。配置管理如 Spring Cloud Config、Nacos。负载均衡如 Ribbon、Feign。断路器如 Hystrix、Sentinel。API 网关如 Zuul、Spring Cloud Gateway。消息总线如 Spring Cloud Bus。
你是怎么理解微服务的
微服务是一种架构风格强调将应用程序分解成小的、独立的服务。每个服务负责特定的功能可以独立部署和扩展。微服务架构的主要特点包括
模块化服务之间松耦合便于维护和扩展。独立部署每个服务可以独立部署和升级。多技术栈支持不同服务可以使用不同的技术栈适应不同的需求。
单体应用、SOA、微服务架构有什么区别
单体应用将所有功能集成在一个应用中耦合度高难以维护和扩展。SOA面向服务架构将应用拆分为多个服务服务间通过网络通信仍然依赖于大型企业级服务总线耦合度较高。微服务架构强调小型、独立的服务服务之间通过轻量级的通信机制如 HTTP/REST、消息队列进行交互支持快速开发和灵活扩展。
Spring Cloud Config 是什么
Spring Cloud Config 是 Spring Cloud 提供的一个集中化配置管理工具支持将配置存储在 Git、SVN 等版本控制系统中提供 RESTful API 来读取和更新配置。它可以实现对多个微服务的统一管理使得配置更新能够实时生效。
什么情况下需要使用分布式事务有哪些方案
需要使用分布式事务的场景包括
跨服务的数据一致性多个服务需要在同一操作中更新数据需要确保数据的一致性。复杂业务流程如金融、电商等行业涉及多个系统的协调。
常见的分布式事务方案包括
两阶段提交2PC保证事务的原子性但性能较低。可靠消息服务TCC、SAGA通过将事务分解为多个小事务来实现适合大多数业务场景。基于补偿的事务通过补偿操作来回滚之前的操作适合网络延迟和失败的场景。
你们的服务是怎么做日志收集的
服务日志收集通常使用以下几种方式
集中式日志管理使用 ELKElasticsearch、Logstash、Kibana或 EFKElasticsearch、Fluentd、Kibana等栈进行日志收集和分析。分布式追踪集成链路追踪工具如 Zipkin、Jaeger来收集和分析请求的执行路径。日志代理使用日志代理如 Fluentd、Filebeat将日志从多个服务收集并发送到集中式存储。
说一下你对于 DDD 的了解
领域驱动设计DDD是一种软件设计方法论强调将软件设计与业务需求紧密结合。DDD 的核心概念包括
领域业务所关心的核心概念。限界上下文定义一个具体的模型和业务范围。实体具有唯一标识的业务对象。值对象无唯一标识的对象用于表示属性或特征。聚合一组相关的实体和值对象围绕一个根实体进行管理。
什么是 Seata
Seata 是一款开源的分布式事务解决方案旨在为微服务架构提供事务支持。它通过各种模式如 AT、TCC、SAGA来实现分布式事务的一致性。
Seata 支持哪些模式的分布式事务
Seata 支持以下分布式事务模式
AT自动提交模式适合大多数业务场景通过自动化的方式管理事务。TCCTry-Confirm-Cancel模式适合对资源控制要求较高的场景提供更大的灵活性。SAGA 模式适合长时间运行的事务通过编排或补偿方式来管理事务。
了解 Seata 的实现原理吗
Seata 的实现原理主要包括以下几个部分
事务协调者负责管理和协调各个参与者的事务。资源管理器管理具体的资源如数据库事务并与事务协调者进行通信。分支事务参与者在执行业务逻辑时向协调者报告事务状态协调者根据状态决定事务的提交或回滚。
Seata 的事务回滚是怎么实现的
Seata 的事务回滚主要通过以下步骤实现
当分支事务执行失败时参与者将失败状态报告给事务协调者。
事务协调者通过补偿或回滚操作将所有已提交的分支事务回滚到初始状态确保数据一致性。
分布式和微服务有什么区别
分布式系统是指在多个物理或虚拟计算机上运行的系统通常包括多台服务器、网络等。可以是单体应用的分布式部署也可以是微服务架构。微服务是一种特定的分布式系统架构风格强调将应用程序分解为小型、独立的服务。微服务具有更高的灵活性、可扩展性和可维护性。
Spring Cloud 有哪些注册中心
Spring Cloud 支持以下注册中心
EurekaNetflix 提供的服务注册与发现组件。ConsulHashiCorp 的服务发现与配置工具。ZookeeperApache 的分布式协调服务广泛应用于注册和发现。
什么是 Eureka?
Eureka 是由 Netflix 开发的一个服务注册与发现组件允许微服务在运行时注册自身并查询其他服务的地址。
Eureka 的实现原理说一下
Eureka 的实现原理包括以下几个部分
服务注册服务启动时向 Eureka 服务器注册自身信息包括服务名称、IP 地址和端口号。服务发现服务查询时向 Eureka 服务器请求已注册的服务列表获取其他服务的地址。心跳机制注册的服务定期向 Eureka 发送心跳维护其在注册表中的有效性如果长时间未发送心跳Eureka 将移除该服务。
Spring Cloud 如何实现服务注册
Spring Cloud 通过 Eureka 客户端库使用注解如 EnableEurekaClient和配置文件如 application.yml来实现服务注册。服务在启动时向 Eureka 服务器注册自身信息并可以通过服务名称查询其他服务。
Consul 是什么
Consul 是 HashiCorp 开发的一款开源工具用于服务发现和配置管理支持健康检查、负载均衡等功能。它提供了 HTTP API 和 DNS 接口易于集成。
Eureka、Zookeeper、Nacos、Consul 的区别
Eureka主要用于服务注册与发现提供丰富的集成和灵活的负载均衡但没有强大的配置管理功能。Zookeeper用于分布式协调支持服务注册与发现但主要用于需要严格一致性和高可用性的场景。Nacos集成了服务发现和配置管理支持动态配置和服务管理使用更为简单。Consul支持服务发现、健康检查、负载均衡和配置管理使用较为灵活但相对复杂。
Nacos 中的 Namespace 是什么
Nacos 中的 Namespace 用于将配置和服务进行隔离允许在同一个 Nacos 实例中管理多个环境如开发、测试、生产的配置和服务。每个 Namespace 具有独立的配置和服务列表。
为什么需要负载均衡
负载均衡的主要目的是
提高可用性将请求分散到多个服务器避免单点故障。提升性能通过合理分配请求降低单台服务器的负载提高响应速度。弹性扩展能够根据流量自动增加或减少服务器实例灵活应对流量变化。
负载均衡的实现方式有哪些
负载均衡的实现方式包括
硬件负载均衡使用专用设备如 F5、阿里云 SLB进行流量分发。软件负载均衡使用开源软件如 Nginx、HAProxy进行流量调度。DNS 负载均衡通过 DNS 轮询将请求分发到不同的服务器。
负载均衡算法有哪些
常见的负载均衡算法包括
轮询按照顺序将请求分发到每个服务器。加权轮询根据服务器的权重分配请求。最少连接将请求发送到当前连接数最少的服务器。IP 哈希根据请求的 IP 地址进行哈希确保相同用户的请求被发送到同一台服务器。
HTTP 与 RPC 之间的区别
HTTP一种无状态的请求-响应协议适用于 Web 应用和 RESTful API通常基于文本格式进行数据传输。RPC远程过程调用允许在网络上调用远程计算机上的函数或过程通常使用二进制协议进行数据传输效率更高支持更复杂的操作。
什么是 Feign
Feign 是一个声明式的 Web 服务客户端简化了服务间的调用允许通过注解方式定义 HTTP 请求自动实现请求的封装和调用。
Feign 是如何实现负载均衡的
Feign 可以与 Ribbon 集成通过 Ribbon 提供的负载均衡功能实现服务调用时的负载均衡。Feign 客户端通过配置和注解定义调用的服务Ribbon 会在请求时选择合适的服务实例。
为什么 Feign 第一次调用耗时很长
Feign 第一次调用耗时长的原因通常包括
服务注册发现延迟第一次调用时需要从注册中心查询服务实例可能导致延迟。网络延迟第一次网络请求可能面临 DNS 解析或网络连接的延迟。连接建立时间TCP 连接建立和 SSL 握手也会增加初始调用的耗时。
Feign 和 OpenFeign 的区别
Feign是 Netflix 提供的一个声明式 HTTP 客户端库支持与 Ribbon 的集成。OpenFeign是 Feign 的开源版本增加了 Spring Cloud 的支持可以与 Spring Boot 生态无缝集成简化配置和使用。
Feign 和 Dubbo 的区别
Feign主要用于基于 HTTP 的 RESTful 服务调用适用于微服务架构。Dubbo是 Alibaba 开发的 RPC 框架支持高性能的远程调用适用于需要高效、复杂的服务调用场景。
什么是熔断器为什么需要熔断器
熔断器是一种用于保护服务的设计模式当某个服务出现故障时熔断器会暂时阻止对该服务的调用以避免连锁反应保护系统的整体可用性。熔断器的主要目的是
防止服务雪崩避免故障服务影响到正常服务。提高系统稳定性快速返回错误信息减少不必要的延迟。
什么是 Hystrix
Hystrix 是由 Netflix 提供的一个熔断器库帮助开发者控制服务的延迟和故障提供熔断、降级、隔离等功能增强系统的健壮性。
什么是服务雪崩
服务雪崩是指某个服务故障导致大量依赖于该服务的其他服务也出现故障从而引发连锁反应最终导致整个系统崩溃的现象。
什么是服务降级
服务降级是一种保护机制当某个服务的性能下降或不可用时系统可以自动转向其他服务或返回默认值以保持系统的稳定性。
什么是服务熔断
服务熔断是指在一定条件下如超时、失败率过高自动停止对某个服务的调用避免对故障服务的持续调用保护系统的整体可用性。
什么是服务限流
服务限流是指限制服务的访问频率以防止因过多请求导致服务崩溃。限流可以通过令牌桶、漏斗等算法实现。
什么是降级熔断为什么需要熔断降级
降级熔断是指在服务发生故障时系统能够自动将请求转发到降级逻辑返回友好的错误信息或默认值。需要熔断降级的原因包括
提高用户体验即使在部分服务故障时用户也能获得合理的反馈。保护系统稳定性避免故障蔓延确保其他正常服务不受影响。
熔断降级有哪些实现方案
熔断降级的实现方案包括
Hystrix提供熔断和降级功能通过注解或 API 定义降级逻辑。Sentinel通过规则配置实现熔断降级支持复杂的流量控制和监控。自定义熔断器根据业务需求实现自定义的熔断器逻辑。
Hystrix 是怎么实现服务容错的
Hystrix 通过以下方式实现服务容错
熔断机制监控服务调用的成功率和响应时间当超过设定阈值时自动
开启熔断防止对故障服务的持续调用。
隔离策略通过线程池和信号量隔离不同服务的调用确保某个服务的故障不会影响到其他服务。降级策略允许开发者定义当服务故障时的降级逻辑返回友好的错误信息。
Sentinel 是怎么实现限流的
Sentinel 通过配置限流规则如 QPS、并发线程数对请求进行限制。其核心组件包括
流量控制根据设定规则动态限流。熔断降级监控服务的运行状态自动进行熔断和降级处理。集群限流支持跨实例的流量控制确保系统整体的稳定性。
Sentinel 与 Hystrix 的区别是什么
功能重点Sentinel 强调流量控制、熔断降级和系统保护而 Hystrix 更侧重于服务容错和隔离。实现方式Sentinel 采用规则驱动的设计支持动态调整Hystrix 主要通过注解和配置实现。架构设计Sentinel 设计更为灵活支持复杂的流量控制场景而 Hystrix 在高并发下可能面临性能瓶颈。
Sentinel 是怎么实现集群限流的
Sentinel 通过共享控制面板控制台配置限流规则所有实例通过网络同步限流状态确保在集群中实现一致的限流策略。每个实例会根据规则动态调整请求处理能力。
什么是服务网格
服务网格是一种基础设施层提供服务间的通信管理包括负载均衡、服务发现、熔断、监控等功能。服务网格允许开发者专注于业务逻辑而将通用的服务通信问题交给网格处理。
什么是灰度发布、金丝雀部署以及蓝绿部署
灰度发布逐步将新版本发布给一小部分用户观察其表现后再逐步扩展。金丝雀部署类似于灰度发布但通常是将新版本部署到一小部分实例上确保新版本在真实环境中的稳定性。蓝绿部署维护两套相同环境蓝、绿在新版本上线时切换流量到新的环境确保无缝切换。
什么是微服务网关为什么需要服务网关
微服务网关是一个入口点负责接收所有外部请求并将其路由到后端服务。服务网关的作用包括
请求路由根据请求路径将请求转发到相应的微服务。负载均衡实现对后端服务的负载均衡。安全性提供认证和授权机制保护后端服务。
Spring Cloud 可以选择哪些 API 网关
Spring Cloud 支持以下 API 网关
Spring Cloud Zuul提供动态路由、负载均衡和过滤器功能。Spring Cloud Gateway基于 Spring 5 的反应式网关支持更灵活的路由和过滤功能。
什么是 Spring Cloud Zuul
Spring Cloud Zuul 是一个 API 网关服务提供路由、负载均衡、监控等功能。Zuul 可以作为微服务架构的入口点处理所有外部请求。
什么是 Spring Cloud Gateway
Spring Cloud Gateway 是一种反应式 API 网关基于 Spring 5 和 Project Reactor提供路由、过滤、限流等功能支持对微服务的高效管理。
说一下 Spring Cloud Gateway 的核心概念
Spring Cloud Gateway 的核心概念包括
路由通过定义路由规则将请求转发到后端服务。过滤器在请求到达目标服务之前或之后进行处理可以用于请求修改、限流、监控等。负载均衡支持对后端服务的负载均衡提升系统的可靠性。
你项目里为什么选择 Gateway 作为网关
选择 Spring Cloud Gateway 作为网关的原因可能包括
性能基于反应式编程模型处理高并发请求时性能优越。灵活性支持动态路由和复杂的过滤逻辑易于扩展。易集成性与 Spring 生态系统的其他组件无缝集成减少了开发成本。
Spring Cloud Gateway 与 Zuul 有什么区别
架构设计Spring Cloud Gateway 是基于反应式架构支持高并发和非阻塞请求而 Zuul 是基于 Servlet API性能上可能受到限制。功能扩展Gateway 提供了更丰富的过滤器和路由功能灵活性更高。易用性Gateway 的配置和使用更为简洁与 Spring Boot 的集成更为紧密。
说说什么是 API 网关它有什么作用
API 网关是微服务架构中的入口点负责所有客户端请求的路由和管理。其作用包括
集中管理将所有服务的调用集中在一个网关中简化外部调用。安全性提供统一的认证和授权机制保护微服务。监控可以对流量进行监控和分析提供运行时指标和日志。
Dubbo 和 Spring Cloud Gateway 有什么区别
架构定位Dubbo 是一个高性能的 RPC 框架专注于服务间的调用而 Spring Cloud Gateway 是 API 网关负责请求的路由和管理。传输协议Dubbo 支持多种协议如 RPC而 Gateway 主要处理 HTTP 请求。使用场景Dubbo 适合高性能服务调用Gateway 则适用于外部接口管理。
什么是令牌桶算法工作原理是什么使用它有哪些优点和注意事项
令牌桶算法是一种流量控制算法工作原理如下
令牌生成以固定的速率向桶中添加令牌。请求处理每次请求需要从桶中取出一个令牌如果桶中没有令牌请求被拒绝或延迟。控制流量通过令牌的生成速率和桶的容量控制请求的速率。
优点
平滑流量可以平滑控制请求速率防止突发流量。灵活性可以根据需求调整令牌生成速率和桶的容量。
注意事项
桶的大小设置合适的桶大小以避免请求被过度拒绝。生成速率根据业务需求合理配置令牌生成速率。
MQ
说一下 RocketMQ 中关于事务消息的实现
RocketMQ 中的事务消息支持在消息发送和处理的过程中保持消息的一致性。其实现过程包括三个步骤
发送准备消息事务消息首先发送一条准备消息到 Broker状态为“待提交”。执行本地事务生产者随后执行本地事务成功后提交本地事务失败则回滚。提交或回滚在准备消息中RocketMQ 会根据本地事务的执行结果向 Broker 提交确认或回滚消息。通过事务状态检查的机制确保消息的最终一致性。
什么是消息队列
消息队列是一种异步通信的方式允许应用程序之间通过消息传递进行解耦。生产者将消息发送到队列中消费者从队列中读取消息。消息队列通常用于处理高并发、异步任务和分布式系统中的数据传输。
为什么需要消息队列
解耦生产者和消费者之间不需要直接交互提高系统的灵活性。异步处理可以在后台处理请求提高系统的响应速度。流量削峰能够平滑处理高峰期的请求避免系统过载。可靠性能够在消息持久化后即使系统故障也能恢复消息。
说一下消息队列的模型有哪些
消息队列的模型主要有以下几种
点对点模型P2P每条消息只能被一个消费者处理。发布/订阅模型Pub/Sub每条消息可以被多个订阅者接收适合广播场景。
简述下消息队列核心的一些术语
消息在消息队列中传递的数据单元。队列存储消息的地方按照先进先出FIFO原则处理消息。生产者发送消息的应用程序。消费者接收并处理消息的应用程序。Broker消息队列的服务器负责消息的存储和传递。
如何保证消息不丢失
持久化将消息持久化存储到磁盘。确认机制消费者在处理完消息后发送确认未确认的消息可以重新发送。消息重试机制对未成功处理的消息进行重试。高可用性架构通过集群和副本机制避免单点故障。
如何处理重复消息
去重机制可以为每条消息分配唯一 ID消费者在处理消息时检查是否已经处理过。幂等性设计确保多次处理相同消息的结果一致。
如何保证消息的有序性
分区设计将消息按某种规则如用户 ID分到同一个分区以确保同一分区内的消息顺序。顺序消费限制消费者的数量确保消息顺序处理。
如何处理消息堆积
扩展消费者增加消费者实例提高消费速度。优化消息处理逻辑简化处理流程减少处理时间。流量控制对生产者进行限流避免过快地产生消息。
消息队列设计成推消息还是拉消息推拉模式的优缺点
推模式 优点减少延迟适合实时场景。缺点可能导致网络拥堵消费者处理能力不足时可能造成消息丢失。 拉模式 优点消费者可控地请求消息避免网络拥堵。缺点可能引入延迟需要定时轮询。
RocketMQ 的事务消息有什么缺点你还了解过别的事务消息实现吗
缺点
复杂性实现和管理事务消息的逻辑复杂。性能损耗由于需要检查和确认事务状态可能引入额外的延迟。
其他实现Apache Kafka 的事务消息实现它使用一种基于两个阶段提交协议2PC的机制确保消息的原子性。
说一下 Kafka 中关于事务消息的实现
Kafka 的事务消息实现基于分区和消费者组的机制。其核心思想是使用事务 ID和事务日志来管理消息的生产和消费。通过启用事务生产者Kafka 允许生产者在一个事务中发送多条消息然后在整个事务成功或失败时原子性地提交或回滚。
你了解 Kafka 中的时间轮实现吗?
Kafka 使用时间轮来处理延迟队列和超时消息。时间轮是一种高效的数据结构能够在 O(1) 的时间复杂度内实现定时任务的调度。Kafka 利用时间轮来定期检查过期的消息并进行处理避免了频繁的遍历操作。
Kafka的索引设计有什么亮点
Kafka 的索引设计采用了稀疏索引机制。每个分区都有一个索引文件其中记录了偏移量和对应的文件位置。通过稀疏索引Kafka 只记录特定的偏移量减少了索引的大小提高了查找效率。
看过源码那说说 Kafka 控制器事件处理全流程
Kafka 控制器负责管理集群的元数据和分区的副本。其事件处理流程如下
接收事件控制器从 Zookeeper 接收分区状态变化事件。更新元数据根据事件更新内部元数据结构。执行操作在需要时重新分配分区副本或迁移数据。通知 Broker将更新后的元数据广播给其他 Broker。
Kafka 中 Zookeeper 的作用
Zookeeper 在 Kafka 中主要负责以下功能
元数据管理存储主题、分区、副本等元数据。集群管理管理 Broker 的注册和状态。领导者选举在分区副本中选举领导者 Broker。
Kafka为什么要抛弃 Zookeeper
Kafka 计划抛弃 Zookeeper 是为了提高性能和简化架构。Zookeeper 的引入会增加系统复杂性尤其是在处理高并发时可能成为性能瓶颈。因此Kafka 正在开发自己的元数据管理方案减少对 Zookeeper 的依赖。
看过源码那说说 Kafka 处理请求的全流程
Kafka 处理请求的全流程如下
接收请求Broker 接收到生产者或消费者的请求。解析请求根据请求类型解析请求参数。执行操作对于生产者写入消息对于消费者读取消息。返回结果将处理结果返回给客户端。
RabbitMQ 中无法路由的消息会去到哪里
RabbitMQ 中无法路由的消息会被发送到一个名为 死信交换机Dead Letter Exchange, DLX 的交换机通常这些消息会被丢弃或者进行特定的处理。
RabbitMQ 中消息什么时候会进入死信交换机
消息会进入死信交换机的情形包括
消息被拒绝且未重新排队。消息超时。消息的 TTL存活时间到期。
说一下 AMQP 协议
AMQPAdvanced Message Queuing Protocol是一种开放标准的消息队列协议提供消息的发送、接收、路由和确认等功能。AMQP 定义了消息的格式、传输过程以及各种消息队列服务的交互方式旨在实现跨平台的消息中间件互操作性。
说一下 RabbitMQ 的事务机制
RabbitMQ 支持事务机制可以通过 tx.select 和 tx.commit 方法来管理事务。在事务模式下消息在被确认之前可以被回滚。然而使用事务机制会降低性能通常推荐使用确认机制acknowledgment替代。
RabbitMQ 中主要有哪几个角色或者说概念
RabbitMQ 的主要角色和概念包括
生产者发送消息的应用。消费者接收消息的应用。队列存储消息的缓冲区。交换机路由消息到一个或多个队列。
RabbitMQ 的 routing key 和 binding key 的最大长度是多少字节
RabbitMQ 的 routing key 和 binding key 的最大长度为 255 字节。
RabbitMQ 中如何保证消息的顺序性
RabbitMQ 保证消息顺序性的方式包括
单个消费者确保每个队列只有一个消费者避免消息乱序。使用优先级队列根据优先级处理消息。
说说 RabbitMQ 的工作模式
RabbitMQ 的工作模式包括
发布/订阅模式生产者将消息发送到交换机消费者订阅特定的队列。工作队列模式多个生产者和消费者平衡负载。
说一下 RabbitMQ 的缺点
RabbitMQ 的缺点包括
性能瓶颈在高负载场景下可能出现性能瓶颈。复杂的配置对于初学者来说配置和调优较为复杂。消息持久性持久化消息会引入一定的性能开销。
简单说一下 RabbitMQ 发送消息的过程
RabbitMQ 发送消息的过程如下
生产者连接到 RabbitMQ 服务器。生产者发送消息到指定的交换机。交换机根据 routing key 将消息路由到相应的队列。消息被消费者消费。
RabbitMQ 如何避免消息的重复投递以及重复消费
RabbitMQ 可以通过以下方式避免重复投递和消费
唯一标识符为每条消息生成唯一的 ID消费者在处理前检查 ID。消息确认使用 ack 确认机制未确认的消息将被重新投递。
RabbitMQ 中如何保证消息的持久化
RabbitMQ 保证消息持久化的方法
将队列标记为持久化创建队列时设置持久化选项。将消息标记为持久化发送消息时设置持久化属性。
RabbitMQ 中的 Channel 你有了解过吗
RabbitMQ 中的 Channel 是与 Broker 之间进行通信的虚拟连接。一个连接可以有多个 Channel每个 Channel 都可以独立处理消息、创建队列和交换机。
RabbitMQ 中消息是如何进行路由的
RabbitMQ 中消息的路由通过交换机和 routing key 实现。生产者将消息发送到交换机交换机根据 routing key 和绑定关系决定将消息路由到哪个队列。
RabbitMQ 上一个 Queue 最多能存放多少条消息
RabbitMQ 上一个队列理论上可以存放无限条消息实际存放数量受限于服务器的内存和存储能力。
RabbitMQ 如何保证高可用
RabbitMQ 通过以下方式确保高可用
镜像队列在多个节点之间复制队列实现冗余。集群将多个 RabbitMQ 实例组成集群增强故障容错能力。
RocketMQ 有什么优缺点
优点
高吞吐量支持高并发消息处理。事务支持内置事务消息处理。分布式特性优秀的扩展性和负载均衡。
缺点
学习曲线相对复杂需掌握较多概念。生态较小与其他成熟消息队列相比社区支持和插件生态不够丰富。
为什么 RocketMQ 不使用 Zookeeper 作为注册中心呢而选择自己实现 NameServer
RocketMQ 选择自定义 NameServer 是为了降低对 Zookeeper 的依赖减少系统复杂性并提高性能。自定义的 NameServer 旨在提供更快速的元数据访问和更新。
说一下 Kafka 为什么性能高
Kafka 性能高的原因主要有
顺序写入采用顺序写入和文件系统的特性。批量处理支持批量消息的发送和接收降低网络开销。零拷贝技术使用零拷贝减少数据复制提高吞吐量。
说一下 Kafka 的应用场景
Kafka 的应用场景包括
实时数据处理如流数据处理和 ETL 任务。日志收集集中管理和分析日志。监控和指标收集实时监控应用性能。
RabbitMQ 怎么实现延迟队列
RabbitMQ 实现延迟队列的方式通常有
使用 TTL设置队列中消息的存活时间TTL超时后转入另一个队列。利用插件使用 RabbitMQ 延迟消息插件rabbitmq-delayed-message-exchange来实现。
Elasticsearch
1. 如何在 Elasticsearch 中设计和实现数据的多层次缓存机制
在 Elasticsearch 中可以通过以下几种方式设计和实现多层次缓存机制
查询缓存Elasticsearch 默认启用查询缓存以提高相同查询的响应速度。可以通过设置 index.requests.cache.enable 来启用或禁用查询缓存。字段数据缓存Fielddata当字段被用作聚合或排序时会加载到内存中。可以通过设置 indices.fielddata.cache 来调整字段数据的缓存策略。结果缓存Elasticsearch 会缓存查询结果尤其是对相同的聚合查询。可以通过设置 search.cache 来管理结果缓存。使用外部缓存结合 Redis 或 Memcached 等外部缓存系统缓存频繁访问的数据进一步降低 Elasticsearch 的负载。
2. 如何通过 Elasticsearch 实现分布式事务
Elasticsearch 本身不支持传统意义上的分布式事务但可以通过以下方法模拟分布式事务
使用乐观锁通过版本控制来避免并发写入的冲突。在文档更新时指定文档的版本号如果版本不匹配则重试。跨服务协调使用分布式事务协调器如 Saga 模式来管理事务的状态确保最终一致性。外部事务管理在应用层管理数据的一致性和完整性通过将相关操作放在同一个事务中进行处理。
3. 什么是 FST在 Elasticsearch 中有哪些应用场景
FSTFinite State Transducer是一种高效的数据结构主要用于存储和搜索字典中的字符串。它在 Elasticsearch 中的应用包括
词典压缩FST 可以用于高效压缩词典减少内存占用和磁盘空间。文本分析在分词时FST 可用于快速查找匹配的词。自动补全FST 支持前缀查找适用于实现自动补全功能。
4. Elasticsearch 中的 Fielddata 是什么如何优化其性能
Fielddata 是 Elasticsearch 为了在内存中加载字段数据而提供的一种机制。它通常用于排序、聚合和脚本。优化其性能的方法包括
限制 Fielddata 使用避免对高基数字段使用 Fielddata尤其是大量唯一值的字段。使用 Doc Values为字段启用 Doc Values以便在磁盘上存储并在需要时加载到内存中。内存监控定期监控 JVM 内存使用情况避免内存溢出。
5. 如何实现 Elasticsearch 集群的滚动升级
滚动升级是指在不中断服务的情况下逐步升级集群中的节点。具体步骤包括
升级前准备检查当前版本与目标版本之间的兼容性。升级 Master 节点首先升级 Master 节点确保集群能正常运行。逐个升级数据节点在升级每个数据节点之前先将其从集群中移除。升级后再将节点添加回集群。监控集群状态在每次升级后监控集群的健康状态和性能。
6. 如何使用 Elasticsearch 实现机器学习模型的推理
在 Elasticsearch 中实现机器学习模型的推理可通过以下方式
使用 Elasticsearch 的 Machine Learning 插件该插件提供了内置的模型训练和推理功能可以分析数据并生成预测。集成外部模型将训练好的机器学习模型通过 REST API 接口与 Elasticsearch 集成通过外部服务进行推理。
7. 什么是倒排表的 FOR 和 RBM 压缩算法工作原理分别是什么
FORFast Object Retrieval是一种针对倒排索引的压缩技术主要通过压缩存储的文档 ID 列表来减少存储空间。通过使用变长编码和选择性压缩策略来提高压缩比。RBMRun Length Encoding with Bit Mapping通过将相同的值连续存储为一段从而减少重复数据的存储。适用于高度重复的文档 ID 列表。
8. 如何在确保数据一致性的前提下更新 Elasticsearch 的倒排索引
在更新 Elasticsearch 的倒排索引时可以采用以下策略
使用版本控制通过文档版本号来确保更新的原子性。使用 Bulk API将多个更新操作合并到一个请求中减少因频繁更新而导致的一致性问题。使用 Refresh 操作确保在查询之前执行 refresh 操作使新数据可见。
9. 如何解决 Elasticsearch 集群中的双 Master 问题
双 Master 问题通常是由于网络分区或配置错误导致的。解决方案包括
确保合适的集群设置设置合适的 discovery.zen.minimum_master_nodes以确保集群在分区时不会产生多个 Master。监控和报警监控集群状态并在出现异常时进行报警及时处理。
10. 什么是 Elasticsearch 的 Posting List 倒排列表
Posting List 是倒排索引的核心组成部分记录了每个词条在文档中的出现位置和相关信息。每个词条对应的 Posting List 包含文档 ID、位置和其他元数据。
11. 如何利用 Elasticsearch 实现大数据量上亿量级的聚合查询
实现大数据量聚合查询的方法包括
使用合适的数据建模对索引进行合理的设计以支持高效的聚合。分片与副本根据数据量设置合理的分片和副本数提高并发处理能力。利用聚合管道使用管道聚合将多个聚合结果合并提高查询效率。
12. Elasticsearch 集群架构有哪些调优策略
调优策略包括
节点角色分配根据节点的角色如主节点、数据节点、协调节点进行合理分配。内存和 JVM 设置调整 JVM 参数和内存使用策略优化性能。监控和调整索引设置根据查询和写入负载监控集群状态动态调整索引设置。
13. 如何在 Lucene 中实现倒排索引
在 Lucene 中倒排索引的实现主要通过以下步骤
文档解析将文档内容解析为词项Term。建立词典记录每个词项及其出现的文档 ID。构建 Posting List为每个词项创建 Posting List记录文档 ID 和位置信息。索引写入将构建的索引写入磁盘形成可查询的倒排索引。
14. 如何优化 Elasticsearch 的 GC 来提升整体性能
优化 Elasticsearch 的垃圾回收GC可以通过以下方式实现
选择合适的 GC 策略根据使用场景选择合适的 GC 策略如 G1 GC 或 CMS。调整 JVM 内存参数设置合适的堆内存大小以减少 GC 的频率和停顿时间。监控 GC 行为定期监控 GC 日志调整参数以优化性能。
15. 如何优化 Elasticsearch 的写入性能以应对大数据量
优化写入性能的方法包括
使用 Bulk API批量写入数据减少请求次数。禁用自动刷新在大批量写入时可以临时禁用索引的自动刷新降低写入延迟。合理配置分片根据数据量调整分片数量避免单个分片负载过高。
16. Elasticsearch 集群什么情况下会出现脑裂如何解决脑裂
脑裂问题通常发生在网络分区导致的 Master 节点不同步解决方案包括
**设置 **discovery.zen.minimum_master_nodes确保只有当大多数 Master 节点在线时才选举新 Master。使用 Zookeeper使用 Zookeeper 作为集群的协调工具增强集群的稳定性。
17. 如何对 Elasticsearch 的 JVM 进行调优以提升性能
对 JVM 进行调优的策略包括
堆内存配置合理配置堆内存通常设置为物理内存的 50% 且不超过 32GB。选择合适的 GC根据负载选择适合的垃圾回收器调整参数以减少停顿时间。监控 JMX 性能指标使用 JMX 监控 JVM 性能动态调整参数。
18. Elasticsearch 底层是如何实现数据存储的比如数据的存储流程和管理
。
Elasticsearch 使用 Lucene 库作为底层存储引擎其数据存储流程如下
文档接收接收来自用户的文档请求。索引过程将文档解析为词项并构建倒排索引。分片存储将索引数据分布到不同的分片中分片可以在不同的节点上。数据持久化使用事务日志和数据段文件将数据写入磁盘确保数据的持久性。
19. Elasticsearch 在分布式环境下如何保证数据的最终一致性
在分布式环境中Elasticsearch 保证数据最终一致性的方法包括
副本机制每个主分片都有多个副本副本负责在主分片不可用时提供服务。版本控制每个文档都有版本号通过版本控制来确保更新操作的顺序。定期一致性检查定期对集群状态进行一致性检查确保数据的一致性。
20. 如何使用 Elasticsearch 实现高可用架构
实现 Elasticsearch 的高可用架构可以采用以下策略
多节点部署部署多个节点确保即使部分节点故障集群仍可正常运行。数据副本为每个主分片配置副本确保数据在节点故障时仍然可用。负载均衡使用负载均衡器将请求分发到不同节点提升系统的吞吐量和可用性。
计算机操作系统
什么是用户态和内核态
用户态和内核态是操作系统中两个不同的执行环境。
用户态在此模式下应用程序运行时受到限制不能直接访问硬件资源和系统内核的核心数据结构。用户态下的进程运行在受限环境中保护系统安全和稳定性。若应用程序需要进行特权操作如文件读写、网络通信必须通过系统调用请求内核的服务。内核态这是操作系统内核执行的模式具有完全的访问权限。内核态下的代码可以直接访问硬件和系统资源并且可以执行所有指令。内核态通常用于处理硬件中断、进程调度和管理内存等操作。
进程之间的通信方式有哪些
进程间通信IPC是指不同进程之间交换数据的机制。常见的IPC方式包括
管道Pipe提供单向通信通常用于父子进程间。命名管道FIFO类似于管道但可以在无亲缘关系的进程之间使用。消息队列允许进程以消息的形式交换数据消息可以是无结构的或有结构的。共享内存允许多个进程访问同一块内存区域速度较快但需要进行同步。信号用于通知进程某个事件发生。套接字Socket常用于网络通信也可以用于同一台计算机上的进程间通信。信号量Semaphore用于控制多个进程对共享资源的访问起到同步作用。
进程有哪几种状态
进程的状态通常分为以下几种
就绪Ready进程已准备好执行但由于CPU资源未分配正在等待调度。运行Running进程正在CPU上执行。阻塞Blocked进程因等待某些事件如I/O操作完成而暂时停止执行。终止Terminated进程已经执行完毕或被强制终止不再占用系统资源。
进程的调度算法你知道吗
进程调度算法是操作系统用来决定进程何时运行的策略常见的调度算法包括
先来先服务FCFS按照进程到达的顺序进行调度。最短作业优先SJF选择下一个最短执行时间的进程进行调度。时间片轮转RR为每个进程分配一个时间片轮流执行。优先级调度根据优先级高低选择进程执行高优先级的进程先执行。多级队列调度将进程分为多个队列每个队列采用不同的调度策略。
什么是软中断、什么是硬中断
中断是硬件或软件向CPU发出的信号请求处理某些事件。
软中断Software Interrupt由程序通过特定指令主动触发的中断例如系统调用时发出的中断。软中断用于实现用户程序与操作系统内核的交互。硬中断Hardware Interrupt由外部设备如键盘、鼠标、网络适配器生成的中断CPU在执行过程中被外部事件打断迫使其暂时停止当前操作转而执行中断处理程序。
什么是分段、什么是分页
**分段Segmentation和分页Paging**是内存管理的两种方式。
分段将程序和数据逻辑上划分为不同的段如代码段、数据段、堆栈段每个段有一个段号和段基地址。分段允许更灵活的内存管理支持共享和保护。分页将内存分为固定大小的页面程序逻辑空间也划分为同样大小的页。页表用于映射逻辑地址到物理地址。分页消除了外部碎片但可能产生内部碎片。
说下你常用的 Linux 命令
在Linux中常用的命令包括
ls列出目录内容。cd改变当前工作目录。pwd显示当前工作目录的完整路径。cp复制文件或目录。mv移动文件或目录或重命名。rm删除文件或目录。touch创建空文件或更新文件的时间戳。chmod更改文件或目录的权限。chown更改文件或目录的所有者。grep在文件中查找匹配的文本。find查找文件。ps查看当前运行的进程。top动态显示系统中进程的资源使用情况。df查看文件系统的磁盘空间使用情况。du查看目录或文件的磁盘使用情况。
I/O到底是什么?
**I/O输入/输出**指的是计算机系统与外部环境如用户、其他计算机、设备之间的信息交换过程。I/O操作包括从外部设备读取数据输入和将数据发送到外部设备输出。I/O是计算机程序与外界交互的主要方式。
为什么网络 I/O 会被阻塞
网络 I/O 被阻塞通常是因为
等待数据在进行网络读操作时如果没有可用的数据调用该操作的进程会被阻塞直到数据到达。缓冲区满在进行网络写操作时如果对方的接收缓冲区已满进程会被阻塞直到缓冲区有空间。网络延迟由于网络的传输延迟数据未能及时到达导致I/O操作被阻塞。
I/O模型有哪些
I/O模型用于描述不同的输入/输出操作方式主要包括
阻塞I/O进程在I/O操作时会被阻塞直到操作完成。非阻塞I/O进程在I/O操作时不会被阻塞如果操作无法立即完成进程可以继续执行其他任务。异步I/O进程发起I/O操作后可以继续执行其他任务I/O操作完成后通过回调或信号通知进程。同步I/O进程发起I/O操作并等待操作完成然后再继续执行。
同步和异步的区别
同步和异步的主要区别在于任务的执行和等待方式
同步任务发起后调用者必须等待任务完成才能继续执行。适用于对结果顺序要求较高的场景。异步任务发起后调用者可以立即继续执行其他任务无需等待任务完成通常通过回调或事件处理机制来获取结果。
阻塞和非阻塞的区别
阻塞和非阻塞的区别在于对进程执行的影响
阻塞在进行I/O操作时进程会被挂起直到操作完成无法继续执行其他任务。非阻塞在进行I/O操作时进程不会被挂起如果操作无法立即完成进程可以继续执行其他任务。
同步、异步、阻塞、非阻塞的I/O的区别
同步阻塞I/O进程在发起I/O请求时被挂起等待I/O操作完成。同步非阻塞I/O进程在发起I/O请求时不会被挂起如果操作无法完成进程会立即返回继续执行其他任务。异步阻塞I/O进程发起I/O请求后继续执行但在需要结果时会被阻塞直到结果可用。异步非阻塞I/O进程发起I/O请求后立即返回且不需要等待结果通常通过回调函数来处理结果。
什么是 BIO、NIO、AIO
BIOBlocking I/O传统的阻塞I/O模型I/O操作是阻塞的进程在等待I/O操作时被挂起。NIONon-blocking I/O非阻塞I/O模型进程可以在发起I/O请求后继续执行其他任务可以通过轮询或回调机制来检查I/O操作的完成状态。**A
IOAsynchronous I/O**异步I/O模型进程发起I/O请求后可以立即返回当I/O操作完成时通过回调或信号通知进程。
什么是 Channel
Channel 是 NIO 中的一个重要概念代表一个可以进行 I/O 操作的通道。Channel 可以用来读写数据具有类似于流Stream的特性但支持异步和非阻塞 I/O。常用的 Channel 包括 FileChannel文件通道、SocketChannel套接字通道等。
什么是 Buffer
Buffer 是 NIO 中的一个数据容器用于在 Channel 读写数据时暂时存储数据。Buffer 有不同的数据类型如 ByteBuffer、CharBuffer 等并且在读写操作中需要管理位置position、限制limit和容量capacity等属性。
什么是 Selector
Selector 是 NIO 中的一个组件用于处理多个 Channel 的 I/O 操作。通过 Selector单个线程可以监视多个 Channel 的状态进行非阻塞 I/O 操作适合高并发场景。它允许程序在没有数据可读或可写时继续处理其他任务。
到底什么是 Reactor
Reactor 是一种事件驱动的设计模式通常用于网络应用程序中。它通过使用 Selector 和多个 Handler 处理事件。Reactor 模式的核心思想是将 I/O 事件的处理与具体的业务逻辑解耦当有 I/O 事件发生时Reactor 会将事件分发给相应的处理器进行处理从而实现高效的非阻塞 I/O。
Select、Poll、Epoll 之间有什么区别
Select早期的 I/O 多路复用机制支持的文件描述符数量有限通常为1024需要遍历整个文件描述符集性能较低。Poll类似于 Select但没有文件描述符数量的限制使用链表存储文件描述符性能较 Select 有所提升但在大量文件描述符时依然效率低下。EpollLinux 特有的高效 I/O 多路复用机制支持大量并发连接使用事件驱动模型只有当文件描述符有事件发生时才会返回效率较高。
什么是物理地址什么是逻辑地址
物理地址实际内存单元的地址表示数据在物理内存中的存储位置。它是硬件级别的地址由内存管理单元MMU生成。逻辑地址程序使用的地址也称为虚拟地址。逻辑地址由程序生成经过内存管理单元的转换后映射到物理地址。逻辑地址提供了对物理内存的抽象使程序员无需关心实际物理内存的布局。
线程和进程有什么区别
进程是操作系统分配资源的基本单位每个进程有自己的内存空间和系统资源进程之间相互独立。线程是进程中的执行单元同一进程内的线程共享内存和资源可以提高程序的并发性和效率。线程的创建和销毁开销相对较小切换速度也快于进程。
总体来说线程和进程都是操作系统中的重要概念但它们在资源管理和执行单元的独立性上存在显著区别。
计算机网络
常见的 HTTP 状态码有哪些
HTTP 状态码用于指示服务器对客户端请求的处理结果。常见的 HTTP 状态码包括
200 OK请求成功服务器返回所请求的数据。201 Created请求成功并且服务器创建了新的资源。204 No Content请求成功但没有返回内容。301 Moved Permanently请求的资源已被永久移动到新 URI。302 Found请求的资源临时移动到新 URI。400 Bad Request客户端请求的语法错误。401 Unauthorized请求未授权需提供身份验证。403 Forbidden服务器拒绝请求用户无权访问资源。404 Not Found请求的资源未找到。500 Internal Server Error服务器内部错误无法完成请求。503 Service Unavailable服务器暂时无法处理请求。
HTTP 请求包含哪些内容请求头和请求体有哪些类型
HTTP 请求由以下部分组成
请求行包括请求方法如 GET、POST、请求的 URI 和 HTTP 版本。请求头包含客户端信息和请求的额外信息。常见的请求头有 Host请求的主机名。User-Agent客户端软件信息。Accept客户端可处理的媒体类型。Content-Type请求体内容类型如 application/json、application/x-www-form-urlencoded。 请求体通常用于 POST 或 PUT 请求包含要发送的数据数据类型可能是 JSON、XML、表单数据等。
除了四次挥手还有什么方法断开连接
除了四次挥手TCP 连接可以通过以下方式断开
重置连接RST当一方检测到连接异常时可以发送一个 RST 数据包来强制关闭连接立即断开。应用层关闭应用程序可以通过关闭套接字的方式通知操作系统关闭连接。
HTTP 1.0 和 2.0 有什么区别
HTTP/1.0 和 HTTP/2.0 的主要区别包括
多路复用HTTP/2.0 支持多路复用可以在一个连接中并发处理多个请求和响应HTTP/1.0 则需要为每个请求建立独立的连接。头部压缩HTTP/2.0 使用 HPACK 算法对请求和响应头部进行压缩减少网络带宽的使用。二进制分帧HTTP/2.0 将数据转换为二进制格式使用帧的方式传输提高了效率和可扩展性。优先级HTTP/2.0 支持请求的优先级处理可以优化资源的获取顺序。
HTTP 2.0 和 3.0 有什么区别
HTTP/2.0 和 HTTP/3.0 之间的主要区别包括
传输协议HTTP/2.0 基于 TCP而 HTTP/3.0 基于 QUICQuick UDP Internet ConnectionsQUIC 使用 UDP 以减少延迟和提高连接速度。连接管理HTTP/3.0 的连接建立更快支持快速恢复和迁移减少了丢包的影响。内置加密HTTP/3.0 默认使用加密TLS提供了更强的安全性。
到底什么是 TCP 连接
TCP传输控制协议连接是通过三次握手过程建立的保证了数据在网络中的可靠传输。TCP 连接具有以下特性
面向连接在数据传输之前必须先建立连接。可靠性确保数据按顺序传输并且在传输过程中不会丢失。流量控制防止发送方发送数据过快而导致接收方缓冲区溢出。拥塞控制避免网络拥堵确保网络的高效利用。
HTTP 和 HTTPS 有什么区别
HTTP超文本传输协议和 HTTPS安全超文本传输协议的主要区别在于
安全性HTTPS 在 HTTP 的基础上通过 SSL/TLS 协议进行加密确保数据在传输过程中的安全性防止中间人攻击。端口HTTP 通常使用端口 80而 HTTPS 使用端口 443。性能虽然 HTTPS 加密增加了一些开销但现代优化使其在许多情况下比 HTTP 更快。
TCP 是用来解决什么问题
TCP 主要用于解决以下问题
可靠性通过确认和重传机制确保数据包的可靠传输。顺序性确保数据包按发送顺序到达接收方。流量控制通过滑动窗口机制控制数据发送速度防止接收方被淹没。拥塞控制动态调整发送速率以应对网络拥塞。
TCP 和 UDP 有什么区别
TCP 和 UDP 的主要区别包括
连接性TCP 是面向连接的协议而 UDP 是无连接的协议。可靠性TCP 提供可靠的数据传输而 UDP 不保证数据的可靠性。顺序性TCP 确保数据按顺序到达而 UDP 不保证顺序。开销TCP 有更多的开销如握手、确认等而 UDP 开销较小适合实时应用。
为什么要 TCPIP 层实现控制不行么
TCP 提供了许多 IP 层无法实现的功能例如
可靠性IP 协议仅提供数据包的传输而 TCP 提供了确认、重传和错误检测等机制确保数据的可靠性。流量控制和拥塞控制TCP 可以动态调整数据流量防止网络拥塞而 IP 不具备这些功能。顺序传输TCP 确保数据包按正确顺序到达而 IP 只关注数据的传输不关心顺序。
TCP 的粘包和拆包能说说吗
粘包和拆包是 TCP 通信中出现的问题主要是由于 TCP 是流式传输数据是以字节流的形式发送的
粘包多个发送的数据包在接收端被合并为一个包接收方无法判断边界。拆包一个发送的数据包在接收端被拆分成多个包接收方接收到的不是完整的数据。
解决这两个问题的方法包括使用自定义的协议头标识数据包的长度和序号。
说说 TCP 的三次握手
TCP 的三次握手过程用于建立连接具体步骤如下
SYN客户端发送一个 SYN 数据包同步序列编号到服务器请求建立连接。SYN-ACK服务器接收到 SYN 后发送一个 SYN-ACK 数据包作为应答确认接收到的请求。ACK客户端收到 SYN-ACK 后发送一个 ACK 数据包确认连接建立。
三次握手确保了双方都可以发送和接收数据。
TCP 初始序列号 ISN 怎么取值的
TCP 初始序列号ISN通常是通过以下方式生成的
随机生成ISN 应该是随机生成的以防止序列号预测攻击。时间戳可以使用系统时间或其他算法来确保序列号的唯一性。
TCP 三次握手时发送 SYN 之后就宕机了会怎么样
如果在发送 SYN 后客户端宕机
服务器在规定时间内没有收到 ACK则会认为连接建立失败并释放相关资源。客户端在重新启动后可能会再次尝试建立连接。
什么是 SYN Flood 攻击
SYN Flood 攻击是一种拒绝服务DoS攻击攻击者发送大量 SYN 请求而不完成握手过程导致目标服务器的连接队列耗尽从而无法响应合法用户的请求。
说说 TCP 的四次挥手
TCP 的四次挥手过程用于断开连接具体步骤如下
FIN主动关闭连接的一方发送 FIN 数据包表示希望断开连接。ACK接收方收到 FIN 后发送 ACK 确认数据包。FIN接收方发送自己的 FIN 数据包表示也准备断开连接。ACK主动关闭连接的一方发送 ACK 确认接收到的 FIN。
为什么 TCP 挥手需要有 TIME_WAIT 状态?
TIME_WAIT 状态用于确保
确认确保最后的 ACK 数据包能够被接收方收到。如果接收方没有收到可能会重新发送 FIN。旧连接的安全防止由于网络延迟导致的旧数据
包混淆新连接。
TCP 超时重传机制是为了解决什么问题
TCP 超时重传机制用于确保数据的可靠传输。当发送方发送数据包后如果在指定时间内没有收到 ACK发送方会重传该数据包解决数据丢失或延迟的问题。
TCP 有超时重传为什么还需要快速重传机制
快速重传机制用于提高数据传输的效率。即使数据包没有超时发送方如果接收到三个重复的 ACK说明数据包可能丢失立即进行重传而不必等待超时减少延迟。
TCP 的 SACK 的引入是为了解决什么问题
SACKSelective Acknowledgment用于解决 TCP 中的重复确认问题。它允许接收方告知发送方哪些数据包已经成功接收哪些还未接收从而提高重传的效率避免不必要的数据重传。
TCP 滑动窗口的作用是什么
TCP 滑动窗口机制用于流量控制。它允许接收方告知发送方可以接收的最大字节数从而限制发送方的发送速率确保接收方的缓冲区不会溢出。
说说 TCP 拥塞控制的步骤
TCP 拥塞控制通常包括以下步骤
慢启动初始窗口大小较小随着每次 ACK 的接收而指数增长。拥塞避免达到阈值后窗口大小线性增长以避免网络拥堵。快速重传接收到三个重复 ACK 时立即重传丢失的数据包。快速恢复在快速重传后重新调整阈值继续传输。
ARP 和 RARP 分别是什么有什么区别
ARPAddress Resolution Protocol用于将网络层的 IP 地址转换为链路层的 MAC 地址。RARPReverse Address Resolution Protocol用于将链路层的 MAC 地址转换为网络层的 IP 地址。
主要区别在于 ARP 是从 IP 到 MAC 的转换而 RARP 是反向转换。
TCP/IP 四层模型是什么
TCP/IP 四层模型包括
应用层为应用程序提供网络服务如 HTTP、FTP。传输层负责端到端的通信如 TCP、UDP。网络层负责数据包的转发如 IP。链路层处理直接相连的网络的传输如 Ethernet。
OSI 七层模型是什么
OSI 七层模型包括
物理层传输原始比特流。数据链路层提供节点到节点的数据传输。网络层提供数据包转发。传输层提供端到端的通信。会话层管理会话和控制。表示层数据格式转换和加密。应用层为应用程序提供网络服务。
Cookie、Session、Token 之间有什么区别
Cookie由服务器发送到客户端的少量数据存储在客户端浏览器中用于识别用户状态。Session在服务器端存储用户信息通过 Session ID 识别通常与 Cookie 一起使用。Token一种自包含的令牌通常用于身份验证客户端携带服务器根据 Token 验证用户身份。
JWT Token 能说说吗
JWTJSON Web Token是一种用于身份验证和信息交换的开放标准。JWT 包含三部分
头部描述了 Token 的类型和所使用的加密算法。有效载荷存储用户的相关信息如用户 ID、权限等。签名用于验证信息未被篡改。
JWT 的优点包括可扩展性、无状态性和跨域支持。
简单谈谈你对 DNS 的理解
DNS域名系统是将域名解析为 IP 地址的系统。用户输入域名时DNS 服务器将其转换为相应的 IP 地址从而帮助浏览器找到目标服务器。DNS 采用分布式结构可以有效处理大量请求确保域名的可用性和可靠性。
简单谈谈你对 CDN 的理解
CDN内容分发网络是一个由多个分布在不同地理位置的服务器组成的网络旨在加速用户访问网站和应用程序的速度。通过将静态资源缓存到离用户更近的边缘服务器上CDN 减少了延迟和带宽消耗提高了用户体验和网站性能。
从网络角度来看用户从输入网址到网页显示期间发生了什么
用户输入网址后发生的主要步骤包括
DNS 查询浏览器通过 DNS 将域名解析为 IP 地址。TCP 连接浏览器与服务器建立 TCP 连接完成三次握手。HTTP 请求浏览器向服务器发送 HTTP 请求请求所需资源。服务器响应服务器处理请求并返回 HTTP 响应包含所请求的资源。数据传输通过 TCP 传输数据确保数据的可靠性和顺序。网页渲染浏览器接收到数据后解析 HTML、CSS 和 JavaScript并将网页渲染出来。