最高频的五个面试题

目录

1.JavaSE阶段:谈谈啥是多态

2.数据结构阶段:谈谈哈希表

3.数据库阶段:谈谈事务 

4.操作系统阶段:谈谈进程和线程的区别联系

5.网络阶段:TCP三次握手和四次挥手


1.JavaSE阶段:谈谈啥是多态

多态(Polymorphism)是面向对象编程中的一个重要概念,它允许不同类的对象对同一个消息(方法调用)作出不同的响应。多态性是面向对象编程的四大基本特性之一,其他三个是封装(Encapsulation)、继承(Inheritance)和抽象(Abstraction)。

多态有两种主要形式:

  1. 编译时多态(Compile-time Polymorphism):也称为静态多态性或早期绑定(Early Binding),发生在编译阶段。它是通过函数重载和运算符重载来实现的,编译器在编译时确定要调用的函数或操作符。编译时多态是在编译期间确定方法或函数的具体实现,通常用于函数重载。

  2. 运行时多态(Runtime Polymorphism):也称为动态多态性或晚期绑定(Late Binding),发生在程序运行时。它是通过方法重写(方法覆盖)和接口实现来实现的,允许在运行时根据实际对象类型来调用方法。运行时多态允许不同的子类实现相同的方法,并根据对象的实际类型选择调用哪个方法。

以下是一个用Java语言的示例来说明多态的概念:

class Animal {
    void makeSound() {
        System.out.println("动物发出声音");
    }
}

class Dog extends Animal {
    @Override
    void makeSound() {
        System.out.println("狗发出汪汪声");
    }
}

class Cat extends Animal {
    @Override
    void makeSound() {
        System.out.println("猫发出喵喵声");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal myAnimal;
        
        myAnimal = new Dog();
        myAnimal.makeSound(); // 调用的是Dog类的makeSound方法
        
        myAnimal = new Cat();
        myAnimal.makeSound(); // 调用的是Cat类的makeSound方法
    }
}

在上面的示例中,Animal 类有一个 makeSound 方法,然后 DogCat 类都继承自 Animal 类并覆盖了 makeSound 方法。在 main 方法中,我们创建了一个 myAnimal 变量,然后分别将它指向 DogCat 类的对象。当调用 myAnimal.makeSound() 时,根据对象的实际类型(是 Dog 还是 Cat),会调用相应子类的 makeSound 方法,实现了运行时多态性。这使得我们可以通过同样的方法调用来实现不同的行为,这是多态的一个关键特征。

如果没有多态,我们的代码是怎么写的~~

class Animal {
    void makeAnimalSound() {
        System.out.println("动物发出声音");
    }
}

class Dog extends Animal {
    void makeDogSound() {
        System.out.println("狗发出汪汪声");
    }
}

class Cat extends Animal {
    void makeCatSound() {
        System.out.println("猫发出喵喵声");
    }
}

public class Main {
    public static void main(String[] args) {
        Dog myDog = new Dog();
        Cat myCat = new Cat();
        
        myDog.makeDogSound();
        myCat.makeCatSound();
    }
}

在这个没有多态的示例中,每个派生类都有一个不同的方法来描述其声音,分别是 makeDogSoundmakeCatSound。这导致了代码的冗余,如果有更多的动物类,就需要为每个动物类编写一个不同的方法名。

使用多态性可以更优雅地处理这种情况,通过统一的方法名 makeSound 来访问不同的子类实现,这可以使代码更加灵活和可维护。

2.数据结构阶段:谈谈哈希表

哈希表(Hash Table),也称为散列表,是一种用于存储键-值对的数据结构。哈希表通过使用哈希函数将键映射到数组索引来实现快速的数据检索和插入操作。它是一种高效的数据结构,通常用于需要快速查找、插入和删除数据的应用程序中,例如字典、集合、数据库索引等。

以下是关于哈希表的一些重要概念和特点:

1. **哈希函数**:哈希表的核心是哈希函数,它接受一个键作为输入并返回一个索引,该索引用于在数组中存储或检索相应的值。一个好的哈希函数应该尽可能均匀地将键映射到索引,以避免冲突(多个键映射到同一个索引)。

2. **数组**:哈希表通常使用一个数组来存储数据。数组的大小通常是根据预期的数据量来确定的,但它可能会动态调整大小以应对数据的变化。

3. **冲突处理**:由于哈希函数的限制,可能会出现多个键映射到同一个索引的情况,这称为哈希冲突。哈希表需要一种方法来解决冲突,常见的方法包括链地址法(使用链表或其他数据结构来存储相同索引上的多个键-值对)和开放地址法(寻找下一个可用的索引位置)。

4. **快速检索**:哈希表允许在平均情况下以常数时间复杂度(O(1))进行查找、插入和删除操作。这使得它在大多数情况下比线性数据结构(如数组或链表)更快速。

5. **不保证有序性**:哈希表通常不保证元素的有序性。元素的顺序与它们在哈希表中的存储位置相关,而不是它们的键的顺序。

6. **适用场景**:哈希表适用于需要快速查找的场景,尤其是当数据集很大时。它经常用于编程语言中的字典(或映射)数据结构,用于缓存实现,数据库索引以及许多其他应用。

哈希表、数组、链表和二叉树是常见的数据结构,它们在不同的方面具有各自的优点和缺点。以下是它们在一些方面的比较:

1. **查找速度**:

   - 哈希表:在平均情况下,哈希表提供了常数时间复杂度(O(1))的查找速度,因为它使用哈希函数将键映射到索引,无需遍历数据集。
   - 数组:数组提供了O(1)的常数时间复杂度的查找速度,但需要知道要访问的元素的索引。
   - 链表:链表的查找速度为O(n),需要遍历链表来找到目标元素。
   - 二叉树:二叉搜索树提供了O(log n)的查找速度,但在最坏情况下可能会达到O(n)。

2. **插入和删除操作**:

   - 哈希表:插入和删除操作通常也是常数时间复杂度,但在解决冲突时可能需要更多的时间。
   - 数组:在已知索引的情况下,插入和删除操作也是O(1),但在数组的中间插入或删除元素时,可能需要移动其他元素,导致O(n)的复杂度。
   - 链表:插入和删除元素是链表的强项,通常是O(1)的时间复杂度,但需要遍历链表来找到要操作的位置。
   - 二叉树:插入和删除操作通常是O(log n),但在不平衡树的情况下可能会达到O(n)。

3. **空间复杂度**:

   - 哈希表:空间复杂度取决于数据集的大小和哈希函数的效率。通常,它的空间复杂度较高,因为需要足够大的数组来存储数据。
   - 数组:空间复杂度固定为O(n),与数据集的大小成正比。
   - 链表:空间复杂度也是O(n),与数据集的大小成正比。
   - 二叉树:空间复杂度取决于树的平衡性,通常是O(n)。

4. **有序性**:

   - 哈希表:通常不保证有序性,元素的顺序与哈希函数的输出相关。
   - 数组:保持元素的有序性,索引与元素的顺序一一对应。
   - 链表:可以是有序的,但需要额外的操作来维护有序性。
   - 二叉树:通常是有序的,可以支持快速的查找和遍历。

总的来说,哈希表在查找和插入操作方面具有很高的效率,但它们对空间的需求较高,并且不保证有序性。数组在有序性和空间复杂度方面表现出色,但对插入和删除操作的支持相对有限。链表适用于频繁插入和删除操作,但查找速度相对较慢。二叉树在有序性和查找方面表现良好,但在不平衡的情况下可能性能下降。选择适当的数据结构取决于应用程序的需求和性能优化目标。

想了解更多哈希表的问题,可以看看Java基础面试题精选:深入探讨哈希表、链表和接口等-CSDN博客 这篇博客

3.数据库阶段:谈谈事务 

事务是数据库管理系统中的一个关键概念,用于确保数据的一致性和完整性。事务是一组数据库操作(SQL语句),这些操作要么全部成功执行,要么全部失败,没有中间状态。以下是关于事务的一些重要概念以及与事务相关的常见并发问题:

**事务的四个特性(ACID):**

1. **原子性(Atomicity)**:事务被视为不可分割的单位,要么全部执行成功,要么全部失败。如果在事务执行过程中发生错误,数据库必须将数据回滚到事务开始前的状态。

2. **一致性(Consistency)**:事务在执行前后,数据库的完整性约束必须得到维护。这意味着事务的执行不会破坏数据库的完整性,数据库始终处于一致的状态。

3. **隔离性(Isolation)**:事务的执行应该与其他事务隔离开来,一个事务的操作不应该对其他事务产生影响,直到事务完成。这是为了防止并发事务之间的数据冲突。

4. **持久性(Durability)**:一旦事务成功提交,它对数据库的更改应该是永久性的,即使发生系统故障,也不应该丢失。

**常见的并发问题:**

1. **脏读(Dirty Read)**:脏读发生在一个事务读取了另一个事务未提交的数据。如果后者在后续被回滚,读取的数据就是无效的。

2. **不可重复读(Non-Repeatable Read)**:不可重复读发生在一个事务内的两次读取操作之间,另一个事务修改了相同的数据,导致两次读取的结果不一致。

3. **幻读(Phantom Read)**:幻读发生在一个事务内的两次查询之间,另一个事务插入或删除了满足查询条件的数据,导致两次查询结果不一致。

4. **丢失更新(Lost Update)**:多个事务同时尝试更新相同的数据,但只有一个事务的更改会生效,其他事务的更改被覆盖。

为了解决这些并发问题,数据库系统提供了不同的隔离级别(如读未提交、读已提交、可重复读和串行化),开发人员可以根据应用程序的需求选择适当的隔离级别。更高的隔离级别通常会导致更多的锁和性能开销,因此需要在数据一致性和性能之间进行权衡。

除了隔离级别,数据库系统还提供了锁机制(如行级锁和表级锁)、乐观并发控制、事务日志等技术来管理并发问题。正确的事务管理是确保数据库系统稳定性和数据完整性的重要部分。

如果想了解更多关于事务的知识点,可以看看MySQL索引、事务与隔离级别探究-CSDN博客 这篇博客~~

4.操作系统阶段:谈谈进程和线程的区别联系

进程(Process)和线程(Thread)是操作系统中用于执行程序的两个核心概念,它们之间有许多区别和联系。以下是它们的主要区别和联系:

区别:

1. 定义:
   - 进程:是操作系统进行资源分配的最小单元,拥有自己的内存空间、文件句柄和系统资源。
   - 线程:线程是操作系统进行运算调度的最小单元,共享进程的内存和资源。

2. 资源占用:
   - 进程:每个进程有独立的内存空间,需要更多的系统资源,如内存和文件句柄。
   - 线程:线程共享相同的内存空间和资源,因此需要较少的系统资源。

3. 创建和销毁成本:
   - 进程:创建和销毁进程通常比较昂贵,因为涉及到分配和释放独立的内存空间和资源。
   - 线程:创建和销毁线程通常较为轻量,因为它们共享相同的资源。

4. 通信和同步:
   - 进程:进程之间的通信通常需要复杂的机制,如进程间通信(IPC)。
   - 线程:线程之间可以通过共享内存轻松通信,但需要考虑同步和竞争条件问题。

联系:

1. 属于同一进程:线程是进程内的执行单元,多个线程属于同一个进程。

2. 共享资源:线程可以共享相同的内存空间和资源,这使得线程之间的数据共享更加方便。

3. 并发执行:进程中的多个线程可以并发执行,这有助于提高多核处理器上的性能。

4. 协同工作:线程可以协同工作来完成进程的任务,例如,一个线程负责用户界面,另一个线程负责后台数据处理。

5.网络阶段:TCP三次握手和四次挥手

过程:

三次握手(Three-Way Handshake)

  1. 第一次握手(SYN):客户端向服务器发送一个包含SYN(同步序列编号)标志的TCP报文段,请求建立连接。此时客户端选择一个初始序列号(ISN)。

  2. 第二次握手(SYN-ACK):服务器接收到客户端的请求后,会发送一个带有SYN和ACK(确认)标志的报文段,表示接受连接请求,并分配自己的初始序列号。

  3. 第三次握手(ACK):客户端接收到服务器的响应后,会发送一个带有ACK标志的报文段,确认服务器的确认。此时连接建立成功,双方可以开始进行数据传输。

四次挥手(Four-Way Handshake)

  1. 第一次挥手(FIN):当客户端决定终止连接时,它发送一个带有FIN标志的报文段,表示不再有数据要发送,但仍愿意接收数据。

  2. 第二次挥手(ACK):服务器接收到客户端的FIN后,会发送一个带有ACK标志的报文段,确认接收到客户端的终止请求。

  3. 第三次挥手(FIN):当服务器也没有数据要发送时,它发送一个带有FIN标志的报文段,表示服务器也愿意终止连接。

  4. 第四次挥手(ACK):客户端接收到服务器的FIN后,会发送一个带有ACK标志的报文段,确认接收到服务器的终止请求。此时连接被完全终止。

如果想了解更多关于三次握手和四次挥手的知识点,可以看看

网络原理之TCP_IP_发呆的百香果子的博客-CSDN博客

这篇博客~~ 

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

发呆的百香果子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值