# 后端经典面试题 by 爽爽学编程

本文作者:爽爽学编程 (opens new window)

本站地址:https://code-wss.com (opens new window)

# JDK 和 JRE 和 JVM 分别是什么,有什么区别?

JDK、JRE和JVM是Java编程语言中的核心组件,它们在Java开发和运行环境中扮演着不同的角色:

JDK(Java Development Kit)

  • JDK是Java开发工具包,它包含了编写Java程序所需的所有工具,包括Java编译器javac、Java运行时环境JRE以及一些其他的开发工具,如调试器、Java文档生成器javadoc
  • JDK是面向Java开发者的,它提供了开发Java应用程序所需的完整环境

JRE(Java Runtime Environment)

  • JRE是Java运行时环境,它包含了Java虚拟机JVM和Java核心类库,但不包含开发工具
  • JRE是面向最终用户的,它允许用户运行Java程序,但不支持开发

JVM(Java Virtual Machine)

  • JVM是Java虚拟机,它是一个可以执行Java字节码的虚拟计算机。JVM为Java程序提供了一个抽象的计算机环境,使得Java程序可以在不同的操作系统和硬件平台上运行
  • JVM负责加载Java类、执行字节码,并提供自动内存管理等功能

区别

  • 功能范围:JDK包含了JRE的所有功能,同时还提供了开发工具。JRE只包含运行Java程序所需的环境,而JVM是JRE的核心部分,负责执行Java字节码
  • 目标用户:JDK主要面向开发者,JRE面向最终用户,JVM则是运行Java程序的底层平台
  • 包含内容:JDK > JRE > JVM,JDK包含了JRE和JVM,JRE包含了JVM

# 什么是字节码?采用字节码的最大好处是什么?

字节码是一种中间状态的代码,它是编译器将高级语言编写的源代码编译成机器可以执行的指令之前的一个步骤。对于Java语言来说,字节码是编译器将Java源代码(.java文件)编译成的一种中间形式(.class文件),这种代码不是直接在硬件上执行的机器码,而是需要通过Java虚拟机(JVM)来解释执行

采用字节码的最大好处包括:

  • 平台无关性(Write Once, Run Anywhere, WORA)
    • Java语言的一个核心特性就是跨平台性。字节码可以在任何安装了JVM的平台上运行,而不需要针对不同的操作系统重新编译。这使得Java程序具有很好的移植性
  • 安全性
    • JVM在执行字节码之前会进行一系列的安全检查,比如类型检查、数组越界检查等,这有助于防止恶意代码的执行和系统崩溃
  • 优化执行
    • JVM可以在运行时对字节码进行即时编译(JIT, Just-In-Time compilation),将热点代码(频繁执行的代码)编译成机器码并缓存,从而提高程序的执行效率
  • 内存管理
    • JVM提供了自动垃圾回收机制,可以自动管理内存,释放不再使用的内存空间,减轻了程序员的负担,同时减少了内存泄漏的风险
  • 多线程支持
    • JVM支持多线程的实现,使得Java程序能够更好地利用多核处理器的优势,提高程序的并发性能
  • 异常处理
    • Java的异常处理机制允许程序更加健壮,能够优雅地处理运行时错误,而不会直接导致程序崩溃
  • 动态性
    • JVM支持动态加载和链接类,可以在运行时动态地添加类和资源,这为动态语言特性和插件架构提供了支持

# Java 和 C++、Go 语言的区别,各自的优缺点?

Java

优点:

  • 跨平台性:Java的"一次编写,到处运行"(WORA)特性,使得Java程序可以在任何支持JVM的平台上运行
  • 内存管理:Java有自动垃圾回收机制,减轻了内存管理的负担
  • 面向对象:Java是一种纯面向对象的语言,支持封装、继承和多态
  • 丰富的API:Java拥有大量的类库和框架,适用于各种应用开发
  • 社区支持:Java有着庞大的开发者社区,提供了大量的资源和支持

缺点:

  • 性能:Java程序通常比C++慢,因为JVM的存在和自动内存管理
  • 内存消耗:Java程序可能比其他语言消耗更多的内存。
  • 学习曲线:对于初学者来说,Java的面向对象特性可能需要一些时间来适应

C++

优点:

  • 性能:C++提供了接近硬件级别的控制,因此性能通常优于Java
  • 内存管理:C++允许手动内存管理,提供了更高的灵活性
  • 多范式编程:C++支持过程式、面向对象和泛型编程
  • 广泛的应用:C++被广泛应用于系统软件、游戏开发、嵌入式系统等领域

缺点:

  • 复杂性:C++语言的复杂性较高,学习曲线陡峭
  • 内存安全:手动内存管理可能导致内存泄漏和野指针等问题
  • 跨平台性:C++程序需要针对不同的平台进行编译,跨平台性不如Java

Go

优点:

  • 简洁性:Go语言设计简洁,语法清晰,易于学习
  • 并发支持:Go内置了并发编程的支持,使用goroutine和channel简化了并发编程
  • 编译速度:Go的编译速度快,有助于快速开发
  • 内存管理:Go有自动垃圾回收机制,同时提供了一些手动内存管理的机制
  • 现代工具链:Go拥有现代化的工具链,包括格式化工具、文档生成器等

缺点:

  • 泛型:Go直到最近的版本才引入泛型,这可能限制了某些类型的编程
  • 类型系统:Go的类型系统相对简单,可能不如Java或C++灵活
  • 运行时性能:虽然Go的性能很好,但通常不如C++

总结

  • Java:适合需要跨平台、高性能、内存管理自动化的大型企业级应用
  • C++:适合需要极致性能和精细控制内存的应用,如游戏开发、嵌入式系统
  • Go:适合需要快速开发、高效并发处理的网络服务和分布式系统

# JDK 动态代理和 CGLIB 动态代理的区别是什么?

JDK动态代理和CGLIB动态代理是Java中两种常用的动态代理实现方式,它们各自有不同的特点和使用场景

JDK动态代理是基于接口实现的代理模式。它使用Java的反射机制,在运行时通过Proxy类和InvocationHandler接口来创建代理类,代理类实现了指定的接口,并且所有的方法调用都会被转发到InvocationHandlerinvoke方法中处理3。这种方式的优点是实现简单,最小化依赖关系,缺点是只能为实现了接口的类创建代理

CGLIB动态代理(Code Generation Library)则是一种基于继承的代理方式,它可以为任何类创建代理,无论这个类是否实现了接口,甚至可以代理final类的方法(除了privatestatic方法)16。CGLIB通过使用ASM字节码生成框架,在运行时动态生成目标类的子类,并重写方法来实现代理16。CGLIB的优点是性能较高,因为它使用了FastClass机制直接调用方法,而不是通过反射1。但它的缺点是使用上相对复杂,且不能代理final修饰的方法

# Java 中 final 关键字有什么用?

  • final变量(常量)
    • 当一个变量被声明为final,它的值在初始化之后就不能被再次修改。这意味着final变量成为了一个常量。通常,常量的名字会使用全大写字母来表示,单词间用下划线分隔
    • 局部变量(方法内定义的变量)如果不需要修改,也可以被声明为final,以明确表示它们是不可变的
  • final方法
    • 声明为final的方法不能被子类重写。这可以用来限制该方法的进一步扩展,确保在类的整个继承链中,该方法的行为不会被改变
    • final方法可以提高性能,因为JVM可能对final方法进行优化,如内联
  • final类
    • 被声明为final的类不能被继承。这通常用于工具类或者那些不希望被扩展的类
    • final类中的所有成员方法默认都是final的,因为没有办法重写它们
  • final参数
    • 将方法参数声明为final可以防止方法内部修改传入的参数值。这是一种保护参数不被修改的做法,有助于方法的安全性
  • final在匿名内部类中的使用
    • 在匿名内部类中,如果需要使用外部类的局部变量,该变量必须被声明为final,即使实际上没有打算修改它
  • final与多态
    • 当使用多态调用一个方法时,如果该方法是final的,那么将调用实际对象类中的实现,而不是父类中的实现
  • final与反射
    • 即使方法被声明为final,反射(Reflection)仍然可以调用它。但是,不能通过反射改变访问控制,即不能通过反射使final方法变为可重写

# Java 中 hashCode 和 equals 方法是什么?它们与 == 操作符有什么区别?

在Java中,hashCodeequals是两个在Object类中定义的方法,它们在对象的比较和哈希表(如HashMapHashSet等)的使用中有重要的作用

hashCode方法

  • hashCode方法返回对象的哈希码,这是一个整数值,用于在哈希表中确定对象的存储位置
  • 不同对象的哈希码可以相同,但相同哈希码的对象不一定是相等的
  • 一个好的哈希函数应该尽量减少哈希冲突,即尽量使不同对象的哈希码不同

equals方法

  • equals方法用于比较两个对象是否相等。默认情况下,它比较对象的内存地址,但通常需要重写以比较对象的逻辑状态或内容
  • 如果两个对象通过equals方法比较结果为true,则它们的哈希码也应该相同

hashCode与equals的一致性

  • 根据Java的官方文档,hashCode方法必须和equals方法保持一致性,即如果两个对象通过equals方法比较结果为true,那么调用这两个对象的hashCode方法也应该返回相同的哈希码
  • 违反这个一致性原则可能会导致哈希表的行为异常

==操作符

  • ==操作符用于比较对象的内存地址,即比较两个对象是否是同一个实例
  • 对于原始数据类型(如int、double等),==操作符比较的是值

hashCode与equals的区别

  • hashCode是一个整数,用于快速比较和索引哈希表,而equals是一个方法,用于比较对象的逻辑等价性
  • hashCodeequals的补充,用于提高性能,特别是在哈希表的实现中
  • hashCode可能发生冲突,即不同的对象可能有相同的hashCode,但equals则不会,如果两个对象equals返回true,它们一定是同一个对象

实践中的注意事项

  • 当你重写equals方法时,通常也需要重写hashCode方法,以保持一致性
  • 如果对象的逻辑等价性不包含所有参与hashCode计算的字段,那么不应该重写hashCode方法,以避免违反一致性原则

# 什么是反射机制?说说反射机制的优缺点、应用场景?

反射机制是Java语言提供的一种能力,允许程序在运行时查询、访问和修改它自身的属性和行为。它是Java核心库的一部分,由java.lang.reflect包提供支持

反射机制的主要特点:

  • 动态获取类信息:可以获取到所有对象的运行时类(getClass()方法)
  • 动态创建对象:可以创建任意类的实例,即使该类是私有的构造函数(Constructor类的newInstance()方法)
  • 动态访问对象的属性:可以获取和设置对象的属性值,不论访问修饰符是什么(Field类)
  • 动态调用方法:可以调用对象的方法,无论访问修饰符是什么(Method类)
  • 动态获取接口实现:可以获取一个类实现了哪些接口(Class类的getInterfaces()方法)

反射机制的优点:

  • 提高灵活性:可以在运行时动态地创建对象和调用方法,使程序更加灵活
  • 解耦代码:可以在不修改源代码的情况下,通过配置文件来改变程序的行为
  • 框架开发:许多流行的Java框架(如Spring、Hibernate)都大量使用反射机制来实现依赖注入、ORM映射等
  • 简化代码编写:可以编写通用的代码来处理不同类型的对象,减少样板代码

反射机制的缺点:

  • 性能开销:反射操作通常比直接的方法调用慢,因为它需要额外的类型检查和动态解析
  • 安全问题:反射可以访问和修改私有的属性和方法,这可能会破坏封装性,导致安全问题
  • 代码可读性降低:过度使用反射可能会使代码难以理解和维护
  • 可能导致错误:由于反射允许执行一些非正常的操作,如访问不可见的属性和方法,这可能导致运行时错误

应用场景:

  • 框架开发:如上所述,许多Java框架依赖反射来实现核心功能
  • 动态代理:JDK动态代理就是基于反射机制实现的
  • 单元测试:测试框架(如JUnit)使用反射来访问私有方法和属性,以便进行测试
  • 配置文件解析:使用反射可以根据配置文件动态创建对象和调用方法
  • 类浏览器和IDE:集成开发环境(IDE)通常使用反射来显示类的信息和成员

# Java 访问修饰符 public、private、protected,以及无修饰符(默认)的区别

Java中的访问修饰符决定了类、接口、方法、构造函数和变量的访问级别。主要有四种访问修饰符:publicprivateprotected,以及不使用修饰符的情况(默认访问级别)。下面是它们各自的特性和区别:

  • public(公共的)
    • public是访问级别最高的修饰符。声明为public的类、接口、方法或变量可以被任何其他类访问,不受限制
    • 例如,public class MyClass可以在任何地方被实例化
  • private(私有的)
    • private是访问级别最低的修饰符。声明为private的成员只能在其所在的类内部访问,不能被外部类访问
    • private方法或变量不能被子类继承,也不能被同一个包中的其他类访问
    • 例如,private void myMethod()只能在声明它的类内部调用
  • protected(受保护的)
    • protected成员可以在其所在的类、同一个包中的其他类以及子类中访问,不论子类是否在同一个包中
    • protected的访问级别低于public,但高于private
    • 例如,protected int myValue可以在声明它的类、同一个包中的其他类和任何子类中访问
  • 无修饰符(默认)
    • 如果没有指定访问修饰符,那么类成员的访问级别是包级私有的,也就是说,只有同一个包中的其他类可以访问它们
    • 这种访问级别通常被称为“默认”或“包”访问级别
    • 例如,一个没有修饰符的类成员只能在同一个包中的其他类中访问

访问级别的比较:

  • public > protected > default > private
  • public类或成员:无限制访问
  • protected类或成员:可以被子类以及同一个包中的其他类访问
  • default(无修饰符)类或成员:只能被同一个包中的其他类访问
  • private类或成员:只能在声明它的类内部访问

使用场景:

  • public:当你希望某个类或成员可以被任何其他类访问时使用
  • private:当你希望隐藏类的实现细节,确保类成员只能在类内部访问时使用
  • protected:当你希望允许子类访问父类的某些成员,但不希望这些成员对同一个包中的非子类可见时使用
  • default:当你希望限制类成员的访问范围仅在包内时使用

# String 和 StringBuffer、StringBuilder 的区别是什么?

StringStringBufferStringBuilder是Java中常用的三种操作字符串的工具,它们各自有不同的特性和用途:

  • String
    • String是不可变的字符串,一旦创建,其内容就不能被修改
    • 每次对String类型进行修改操作时,实际上都会生成一个新的String对象
    • String适合用于不需要频繁修改的字符串场景
  • StringBuffer
    • StringBuffer是可变的字符串缓冲区,可以对它进行添加、删除和替换等操作
    • StringBuffer是线程安全的,因为它的所有公开方法都是同步的,可以在多线程环境中使用
    • 由于线程安全的特性,StringBuffer在单线程环境下的性能比StringBuilder稍差
  • StringBuilder
    • StringBuilder也是可变的字符串缓冲区,与StringBuffer类似,可以进行修改操作
    • StringBuilder不是线程安全的,因为它的方法不是同步的,因此在单线程环境下性能更优
    • 由于不是线程安全的,StringBuilder在多线程环境下使用时需要谨慎

主要区别:

  • 不变性String是不可变的,而StringBufferStringBuilder是可变的
  • 线程安全String是不可变的,因此是线程安全的;StringBuffer是线程安全的;StringBuilder不是线程安全的
  • 性能:在单线程环境下,StringBuilder由于没有同步的开销,通常比StringBuffer性能更好;在多线程环境下,StringBuffer由于其线程安全性,可能更适合使用

使用场景:

  • String:当你需要一个不可变的字符串,或者字符串创建后不需要修改时使用
  • StringBuffer:在多线程环境中,需要对字符串进行修改时使用,例如,多个线程需要共享同一个字符串缓冲区
  • StringBuilder:在单线程环境中,需要对字符串进行频繁修改时使用,以获得更好的性能

代码示例:

String str = "Hello";
str = str + " World!"; // 实际上创建了一个新的String对象

StringBuffer sb = new StringBuffer("Hello");
sb.append(" World!"); // 在原有对象上修改

StringBuilder sb = new StringBuilder("Hello");
sb.append(" World!"); // 在原有对象上修改
1
2
3
4
5
6
7
8

在Java 9之后,StringBufferStringBuilder都位于java.lang包中,不再需要单独导入。此外,StringBuilder通常是处理字符串的首选,除非你确定需要线程安全的字符串缓冲区,在这种情况下,才使用StringBuffer

# 什么是 Java 内部类? 内部类的分类有哪些 ?内部类有哪些优点和应用场景?

Java内部类是指定义在另一个类内部的类,它是Java语言中一个重要的特性,提供了一种新的类定义方式和作用域规则。内部类可以访问外部类的所有成员,包括私有成员,但反之则不行

内部类的分类:

  • 成员内部类
    • 成员内部类是定义在外部类的一个成员位置的类,它与外部类其他成员(属性和方法)处于同一级别
    • 它不能包含静态成员(除了静态内部类外)
  • 局部内部类
    • 局部内部类是定义在一个方法内部的类,其作用域限定在该方法内
    • 它通常用于匿名内部类的定义
  • 匿名内部类
    • 匿名内部类是没有名字的内部类,常用于实现回调或者事件处理器
    • 它主要用于实现接口或继承抽象类,并且只用于一个方法调用
  • 静态内部类
    • 静态内部类是定义在外部类内部,但使用static修饰的类
    • 它可以有静态成员,并且不依赖于外部类的实例,即它不持有对外部类实例的引用
  • 内部枚举和内部接口
    • Java也允许在类内部定义枚举和接口

内部类的优点:

  • 增强封装性:内部类可以访问外部类的所有成员,但外部类不能直接访问内部类的成员
  • 代码组织:内部类允许将逻辑相关的类组织在一起,使代码更加清晰
  • 名称空间复用:内部类可以有与外部类相同的成员名称,避免了名称冲突
  • 多态性:内部类可以覆盖外部类的同名方法,实现多态
  • 易于使用:局部内部类和匿名内部类可以非常方便地在需要的地方快速定义和使用

应用场景:

  • 实现回调:使用匿名内部类实现监听器或回调接口
  • 构建代理:使用内部类创建代理类,实现装饰者模式或代理模式
  • 组织逻辑相关的类:将功能相关的类组织在一起,提高代码的可读性
  • 实现多重继承:由于Java不支持多重继承,可以使用内部类实现类似功能
  • 创建线程:使用内部类创建线程,因为它可以访问外部类的私有成员

代码示例:

public class OuterClass {
    private int outerVar = 0;

    // 成员内部类
    class InnerClass {
        void accessOuterVar() {
            outerVar = 10;
        }
    }

    // 静态内部类
    static class StaticInnerClass {
        void accessOuterVar() {
            OuterClass obj = new OuterClass();
            obj.outerVar = 10; // 需要通过外部类实例访问
        }
    }

    // 局部内部类
    void method() {
        class LocalInnerClass {
            void display() {
                System.out.println("I am a local inner class");
            }
        }
        LocalInnerClass loc = new LocalInnerClass();
        loc.display();
    }

    // 匿名内部类
    interface MyInterface {
        void sayHello();
    }

    void useInterface() {
        MyInterface obj = new MyInterface() {
            public void sayHello() {
                System.out.println("Hello from anonymous inner class");
            }
        };
        obj.sayHello();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

内部类提供了一种灵活的代码组织方式,使得代码更加模块化,但同时也增加了复杂性,因此在使用时需要权衡利弊

# 什么是数据库事务?讲一下事务的 ACID 特性?

数据库事务是一系列操作,这些操作作为一个整体被执行,以确保数据库的状态从一个一致的状态转移到另一个一致的状态。如果事务中的所有操作都成功完成,那么事务将被提交,所有的更改将被永久保存到数据库中。如果事务中的任何一个操作失败,整个事务将被回滚,所有的更改都会被撤销,数据库将返回到事务开始之前的状态

事务的ACID特性:

  • 原子性(Atomicity)
    • 事务中的所有操作要么全部完成,要么全部不完成,不会结束在中间某个点。这意味着事务中的操作具有原子性,它们被捆绑在一起,作为一个不可分割的单元
  • 一致性(Consistency)
    • 事务必须保证数据库从一个一致的状态转移到另一个一致的状态。一致性确保了数据库的完整性约束在事务执行前后保持一致
  • 隔离性(Isolation)
    • 并发执行的事务之间不会互相影响。每个事务都与其他事务隔离开来,好像它是在独立的数据库副本上操作一样。不同的隔离级别可以防止脏读、不可重复读和幻读等问题
  • 持久性(Durability)
    • 一旦事务提交,它对数据库的改变就是永久性的,即使系统发生故障也不会丢失。持久性保证事务提交后的结果能够被保存,不会因为系统崩溃、电源故障或其他问题而丢失

应用场景:

  • 银行交易:在银行系统中,事务被用来确保转账操作的原子性和一致性。如果转账过程中任何一步失败,整个交易将回滚,以保证账户余额的正确性
  • 库存管理:在库存系统中,事务用来确保库存数量的一致性。例如,当一个商品被购买时,库存数量需要相应减少,这个过程需要在一个事务中完成
  • 订单处理:在电子商务中,订单处理涉及到多个步骤,如用户信息验证、库存检查、支付处理等,这些步骤需要在一个事务中完成,以保证订单的一致性

事务管理:

  • 数据库管理系统(DBMS)通常提供了事务管理的机制,允许用户定义事务的边界(开始和结束),并确保ACID特性得到满足
  • 在编程中,可以通过特定的API或框架来管理事务,如JDBC的setAutoCommit(false)commit()方法,或者Spring框架的声明式事务管理

事务是数据库操作的基石,确保了数据的完整性和一致性,是现代数据库系统不可或缺的一部分

# MySQL 日志有了解过吗?binlog、redolog、undolog 分别有什么作用、有什么区别?

# 数据库索引是什么,有什么作用,什么场景适合使用索引?

# 你是怎么做 MySQL 数据备份的?比如怎么恢复半个月前的数据?

# 一条 SQL 语句在 MySQL 中的执行过程是怎样的?

# MySQL 中的索引是怎么实现的?B+ 树是什么,B 树和 B+ 树的区别,为什么 MySQL 要用 B+ 树?

# MySQL 事务有哪些隔离级别、分别有什么特点,以及 MySQL 的默认隔离级别是什么?

# 意向锁是什么?有什么作用?它是表级锁还是行级锁?

# MVCC 是什么?InnoDB 是如何实现 MVCC 机制的?

# 覆盖索引和联合索引是什么?讲一下索引的最左前缀匹配原则。

# 什么是 MySQL 执行计划?如何获取执行计划并对其进行分析?

# MySQL 支持哪些存储引擎?默认使用哪个?MyISAM 和 InnoDB 引擎有什么区别,如何选择?

# Spring 框架是什么?使用 Spring 框架有哪些好处?

# Spring 的两大核心概念是什么?简单讲一下你对它们的理解

# 什么是 IOC,简单讲一下 Spring IOC 的实现机制?

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

# Spring、SpringMVC、SpringBoot 三者之间是什么关系?

# 有哪些注解可以注入 Bean?@Autowired 和 @Resource 的区别?

# Spring 如何处理线程并发问题,ThreadLocal 你了解过吗?

# Spring 中的 BeanFactory 和 ApplicationContext 有什么区别和联系?

# 讲一讲 Spring 框架中 Bean 的生命周期?

# Spring 支持哪几种事务管理类型,Spring 的事务实现方式和实现原理是?

# 什么是 Spring 的依赖注入,依赖注入的基本原则以及好处?

# 什么是 AOP?有哪些实现 AOP 的方式?Spring AOP 和 AspectJ AOP 有什么区别?

# 什么是 Redis?Redis 有哪些特点?Redis 有哪些常见的应用场景?

# 讲一下 Redis 的单线程模型,IO 多路复用是什么?

# Redis 基础类型中的 String 底层实现是什么?

# 如何使用 Redis 实现一个排行榜?

# Redis 的持久化机制有哪些?说说各自的优缺点和应用场景?

# 如何用 Redis 实现分布式 Session?

# 讲一下 Redis 中的内存淘汰机制、有哪些内存淘汰策略?

# Redis 6.0 之后为何引入了多线程?6.0 之前为什么不使用多线程?

# Redis 有哪些数据类型?基础数据结构有几种?你还知道哪些 Redis 的高级数据结构?

# Redis 为什么快?

# 如何使用 Redis 实现分布式锁?

# 如何用 Redis 中的 HyperLogLog 统计页面 UV?

# 简述计算机网络七层模型和各自的作用?

# HTTP 是哪一层的协议?简述它的作用?

# HTTP 有哪些常见的状态码?

# TCP 和 UDP 协议有什么区别,分别适用于什么场景?

# HTTP 协议中 GET 和 POST 有什么区别?分别适用于什么场景?

# 简述 TCP 三次握手、四次挥手的流程?为什么需要三次握手?为什么需要四次挥手?

# 什么是进程和线程?它们有哪些区别和联系?

# 死锁是什么?如何预防和避免死锁?

# 线程间有哪些通信方式?

# 什么是零拷贝?说一说你对零拷贝的理解?

# 什么是分布式?为什么需要分布式?

# 什么是网关,网关有哪些作用?

# Dubbo 是什么?是否了解过它的架构设计?

# 什么是分布式的 CAP 理论?

# 什么是 RPC?目前有哪些常见的 RPC 框架?实现 RPC 框架的核心原理是什么?

# 什么是注册中心?如何实现一个注册中心?

# 什么是分布式的 BASE 理论,它与 CAP 理论有什么联系?

# 什么是消息队列?消息队列有哪些应用场景?

# 有哪些主流的消息队列,它们分别有什么优缺点、各自的适用场景是什么?

# 有哪些常见的消息队列模型?分别适用于什么场景?

# 设计模式是什么?为什么要学习和使用设计模式?

# 什么是单例模式?使用单例模式有什么好处?有哪些常用的单例模式实现方式?各自的应用场景是什么?

# 设计模式可以分为哪几类?一共有多少种主流的设计模式?

# 什么是工厂模式?使用工厂模式有什么好处?工厂模式有哪些分类?各自的应用场景是什么?

# 并发和并行有什么区别?同步和异步有什么区别?

# 什么是 BIO、NIO、AIO?

# 线程的生命周期是什么,线程有几种状态,什么是上下文切换?

# synchronized 关键字是什么,有什么作用?

# 如何设计一个点赞系统?

# 如何在 10 亿个数据中找到最大的 1 万个?

# 有几台机器存储着几亿的淘宝搜索日志,假设你只有一台 2g 的电脑,如何选出搜索热度最高的十个关键词?

# 请你介绍下 JVM 内存模型,分为哪些区域?各区域的作用是什么?

# 常见的垃圾回收算法有几种类型?他们对应的优缺点是什么?

# 什么是 Git 的 fork 命令?它和 clone 命令有什么区别?

# 什么是 Git 的 cherry-pick?

# Linux 中的硬链接和软连接是什么,二者有什么区别?

# CC 攻击是什么?什么叫 DDOS 攻击?什么是网站数据库注入?

# 如何在 Linux 中查看系统资源使用情况?比如内存、CPU、网络端口。

# Nginx 是什么?它有哪些应用场景?

# 什么是正向代理和反向代理,如何使用 Nginx 做反向代理?

# 如何用 Nginx 做限流,有几种限流算法,分别如何实现?

# 什么是云原生?它有哪些优缺点?

# 你是否了解过新版本的 Java 特性?对 Java 未来的发展有什么看法?

后端经典面试题 by 爽爽学编程

爽爽学编程   |