面试题1234

第一天

1.Java内部类有哪些,特征是什么?

成员内部类(Member Inner Class):定义在一个类的内部,并且与外部类的成员变量和方法具有相同的访问权限。成员内部类可以访问外部类的所有成员,包括私有成员。
局部内部类(Local Inner Class):定义在一个方法或代码块的内部,作用范围仅限于所在的方法或代码块。局部内部类可以访问外部类的成员,但只能访问final或有效final的局部变量。

静态内部类(Static Inner Class):定义在一个类的内部,并且被static修饰。静态内部类与外部类的实例无关,可以直接通过外部类的类名访问静态内部类的静态成员。静态内部类可以访问外部类的静态成员,但不能直接访问外部类的非静态成员。
匿名内部类(Anonymous Inner Class):没有显式的类名,直接通过new关键字创建。匿名内部类通常用于创建实现某个接口或继承某个类的对象,并重写其方法。匿名内部类可以访问外部类的成员,但只能访问final或有效final的局部变量。
特征:
内部类可以访问外部类的成员,包括私有成员。
内部类可以拥有自己的成员变量和方法。
内部类可以被private、protected、public和default修饰。
内部类可以访问外部类的this关键字,用于区分内部类和外部类的成员。
内部类可以用于实现多重继承,一个类可以实现多个接口,每个接口可以有自己的内部类实现。
内部类可以访问外部类的静态成员,但外部类不能直接访问内部类的成员,需要通过创建内部类的对象来访问。

2.数据库的垂直切分和水平切分两种  他们的区别是什么?

数据库的垂直切分(Vertical Partitioning)和水平切分(Horizontal Partitioning)是两种常用的数据库分片技术,它们的区别如下:
垂直切分:
垂直切分是将一个数据库表按照列的方式进行切分,将不同的列划分到不同的表中。
垂直切分可以将数据按照功能或者访问频率进行划分,将不同的列存储在不同的表中,从而提高查询性能和减少数据冗余。
垂直切分可以实现更好的数据隔离和安全性,因为不同的表可以设置不同的权限和访问控制。
垂直切分的缺点是可能会导致多表关联查询的复杂性增加,需要进行额外的表连接操作。
水平切分:
水平切分是将一个数据库表按照行的方式进行切分,将不同的行划分到不同的表或者不同的数据库中。
水平切分可以将数据按照某个字段的值进行划分,例如将用户按照地域或者按照用户ID的范围进行划分。
水平切分可以实现更好的负载均衡,因为不同的行可以存储在不同的表或者不同的数据库中,从而分散了查询和写入的压力。
水平切分的缺点是可能会导致跨节点查询的复杂性增加,需要进行额外的数据合并和查询操作。
总的来说,垂直切分适用于将不同的功能或者访问频率较低的列划分到不同的表中,而水平切分适用于将数据按照某个字段的值进行划分,实现负载均衡和分散压力。垂直切分和水平切分也可以结合使用,根据实际需求选择合适的切分策略。

3.手写一个冒泡排序

public class BubbleSort {
    public static void bubbleSort(int[] arr) {
        int n = arr.length;
        for (int i = 0; i < n - 1; i++) {
            for (int j = 0; j < n - i - 1; j++) {
                if (arr[j] > arr[j + 1]) {
                    // 交换arr[j]和arr[j+1]
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
    }
public static void main(String[] args) {
        int[] arr = {64, 34, 25, 12, 22, 11, 90};
        bubbleSort(arr);
        System.out.println("排序后的数组:");
        for (int num : arr) {
            System.out.print(num + " "); //11 12 22 25 34 64 90
        }
    }
}

4.谈谈你对HTTP协议的认识?

HTTP协议是一种用于传输超文本的应用层协议,它是Web的基础,是Web应用程序的基础。HTTP协议是客户端和服务器之间通信的标准协议,客户端发送请求,服务器返回响应。HTTP协议基于TCP/IP协议,通过TCP协议传输数据,使用URL作为定位网络资源的标识符,支持多种请求方法,如GET、POST、PUT、DELETE等,支持多种数据格式,如HTML、XML、JSON等。HTTP协议的主要特点是简单、灵活、可扩展、无状态。HTTP协议的简单性使得它易于实现和使用,灵活性和可扩展性使得它适用于各种不同的应用场景,无状态使得它可以处理大量的请求。HTTP协议的缺点是安全性较差,数据传输不加密,容易被攻击者截获和篡改。为了提高安全性,现在常用的是HTTPS协议,它在HTTP协议的基础上增加了SSL/TLS加密技术,保证数据传输的安全性。

5.谈谈你对TCP三次握手/四次挥手

CP三次握手是TCP协议在建立连接时的一种机制。它的过程如下:

  1. 客户端向服务器发送SYN包,表示请求建立连接。
  2. 服务器收到SYN包后,向客户端发送SYN+ACK包,表示确认收到请求并同意建立连接。
  3. 客户端收到SYN+ACK包后,向服务器发送ACK包,表示确认收到确认,并建立连接。

TCP四次挥手是TCP协议在断开连接时的一种机制。它的过程如下:

  1. 客户端向服务器发送FIN包,表示请求断开连接。
  2. 服务器收到FIN包后,向客户端发送ACK包,表示确认收到请求。
  3. 服务器向客户端发送FIN包,表示请求断开连接。
  4. 客户端收到FIN包后,向服务器发送ACK包,表示确认收到请求,断开连接。

三次握手和四次挥手是TCP协议中非常重要的机制,它们保证了数据传输的可靠性和完整性。在实际的网络通信中,它们被广泛应用于各种应用场景中,如网页浏览、文件传输、邮件发送等。

6.rabbitMq在项目中的作用?

RabbitMQ是一个开源的消息队列中间件,它在项目中有以下几个作用:

  1. 解耦:RabbitMQ可以将消息的发送者和接收者解耦,发送者只需要将消息发送到消息队列中,而不需要直接与接收者进行交互。这样可以降低系统之间的耦合度,提高系统的可维护性和可扩展性。

  2. 异步处理:RabbitMQ可以实现异步处理,发送者将消息发送到消息队列后,就可以继续处理其他任务,而不需要等待接收者的响应。这样可以提高系统的并发能力和响应速度。

  3. 削峰填谷:在高并发的情况下,如果直接将请求发送给接收者,可能会导致接收者无法处理过多的请求而崩溃。而使用RabbitMQ可以将请求发送到消息队列中,然后由多个接收者进行消费,从而平均分摊请求压力,避免系统崩溃。

  4. 消息持久化:RabbitMQ支持消息的持久化,即将消息存储到磁盘上,即使在RabbitMQ重启后也不会丢失消息。这对于一些重要的消息来说非常重要,可以确保消息的可靠性传输。

  5. 顺序性:RabbitMQ可以保证消息的顺序性,即发送的消息按照发送的顺序被接收者消费。这对于一些需要按照顺序处理的任务来说非常重要。

总之,RabbitMQ在项目中的作用非常广泛,可以提高系统的可靠性、可扩展性和性能,并且能够解决分布式系统中的一些常见问题。

7.说说什么叫做微服务的服务治理?

微服务的服务治理是指在微服务架构中,对服务进行管理和控制的一系列机制和策略。它主要包括以下几个方面:

  1. 服务注册与发现:微服务架构中的每个服务都需要向服务注册中心注册自己的信息,包括服务的地址、端口等。同时,其他服务可以通过服务注册中心来发现和获取需要调用的服务的信息,实现服务之间的解耦。

  2. 负载均衡:微服务架构中的服务可能会有多个实例,负载均衡机制可以根据一定的策略将请求均匀地分发到各个实例上,从而实现负载的均衡,提高系统的性能和可扩展性。

  3. 故障熔断与容错:在微服务架构中,一个服务的故障可能会影响到其他服务的正常运行。服务治理可以通过故障熔断和容错机制来保护系统的稳定性。当一个服务发生故障时,可以及时地将请求转发到备用服务上,避免故障的扩散。

  4. 隔离与限流:在微服务架构中,不同的服务可能具有不同的性能和资源消耗。服务治理可以通过隔离和限流机制,对不同的服务进行资源的划分和调度,保证资源的合理利用和系统的稳定性。

  5. 监控与追踪:微服务架构中的每个服务都需要进行监控和追踪,以便及时发现和解决问题。服务治理可以提供监控和追踪的功能,对服务的运行状态进行实时监控,并记录和分析服务的调用链路,以便进行故障排查和性能优化。

综上所述,微服务的服务治理是对微服务架构中的服务进行管理和控制的一系列机制和策略,它能够提高系统的可靠性、可扩展性和性能,并且能够解决分布式系统中的一些常见问题。

第二天

1.jvm中常见的垃圾清除算法有哪些?

  1. 标记-清除(Mark and Sweep)算法:该算法分为两个阶段。首先,从根对象开始,标记所有可达对象。然后,在清除阶段,清除未标记的对象,回收它们所占用的内存空间。标记-清除算法会产生内存碎片,可能会导致内存分配效率降低。

  2. 复制(Copying)算法:该算法将堆内存分为两个区域,一半为活动对象区域,一半为空闲区域。首先,将活动对象从一个区域复制到另一个区域,然后清除整个区域。复制算法解决了内存碎片问题,但需要额外的空间来存储复制过程中的对象。

  3. 标记-整理(Mark and Compact)算法:该算法结合了标记-清除和复制算法的优点。首先,标记所有可达对象。然后,将所有存活的对象向一端移动,然后清除剩余的空间。标记-整理算法可以解决内存碎片问题,并且不需要额外的空间。

  4. 分代(Generational)算法:该算法基于一个观察:大部分对象的生命周期较短。因此,堆内存被划分为几个代(Generation),每个代有不同的生命周期。通常将新对象分配在年轻代,而较长生命周期的对象则分配在老年代。不同的代可以使用不同的垃圾清除算法,如年轻代使用复制算法,老年代使用标记-整理算法。

这些垃圾清除算法在不同的情况下有不同的优势和劣势。JVM通常会根据堆内存的特征和应用程序的行为动态选择和调整垃圾清除算法,以达到最佳的性能和内存利用率。

2.java中引用类型分别是什么,有什么特征?

  1. 强引用(Strong Reference):强引用是最常见的引用类型。当一个对象被强引用引用时,它不会被垃圾回收器回收,即使内存空间紧张。只有当没有任何强引用指向一个对象时,该对象才会被认为是不可达的,从而可以被垃圾回收。

  2. 软引用(Soft Reference):软引用是一种相对较弱的引用类型。当内存空间紧张时,垃圾回收器可能会回收软引用指向的对象。软引用通常用于实现内存敏感的缓存,当内存不足时,可以回收一些缓存对象来释放内存。

  3. 弱引用(Weak Reference):弱引用是一种更弱的引用类型。垃圾回收器会更容易回收弱引用指向的对象,即使内存空间不紧张。弱引用通常用于实现辅助数据结构,如WeakHashMap,当对象的弱引用被回收时,相关的数据也可以被清理。

  4. 虚引用(Phantom Reference):虚引用是最弱的引用类型。虚引用主要用于跟踪对象被垃圾回收的状态。虚引用不能直接访问对象,也不能通过虚引用获取对象的值。它通常与引用队列(ReferenceQueue)一起使用,当对象被垃圾回收时,会将虚引用加入到引用队列中,从而可以在对象被回收时进行一些特定的处理操作。

这些引用类型的特点如下:

  • 强引用:强引用是默认的引用类型,它们在程序中随处可见,并且可以直接访问对象。
  • 软引用:软引用是一种在内存不足时可以被回收的引用,适用于缓存等场景。
  • 弱引用:弱引用是一种更弱的引用类型,垃圾回收器更容易回收弱引用指向的对象。
  • 虚引用:虚引用是一种最弱的引用类型,主要用于跟踪对象被垃圾回收的状态,不能直接访问对象。

引用类型的选择取决于具体的应用场景和需求。

3.ArrayList和LinkList的区别有哪些?

  1. 底层实现:ArrayList是基于数组实现的,LinkedList是基于双向链表实现的。

  2. 访问效率:ArrayList的访问效率比LinkedList高,因为ArrayList是基于数组实现的,可以通过索引直接访问元素,时间复杂度为O(1);而LinkedList需要从头或尾开始遍历链表,时间复杂度为O(n)。

  3. 插入和删除效率:LinkedList的插入和删除效率比ArrayList高,因为LinkedList是基于链表实现的,插入和删除元素只需要改变相邻节点的指针,时间复杂度为O(1);而ArrayList需要移动元素,时间复杂度为O(n)。【ArrayList查询快  增删慢  LinkedList查询慢 增删快】

  4. 内存占用:ArrayList的内存占用比LinkedList高,因为ArrayList需要预分配一段连续的内存空间,而LinkedList只需要为每个节点分配内存。【ArrayList内存占用高 LinkedList内存占用低】

  5. 随机访问和顺序访问:ArrayList适合随机访问,可以通过索引快速访问任意位置的元素;LinkedList适合顺序访问,可以高效地在头部或尾部插入和删除元素。

综上所述,如果需要频繁进行随机访问操作,或者对内存占用有要求,可以选择ArrayList;如果需要频繁进行插入和删除操作,或者对访问效率要求不高,可以选择LinkedList。

4.Set中如何使用equals()与hashCode()的?

在Set中使用equals()和hashCode()的目的是为了确保Set中的元素是唯一的。当向Set中添加元素时,Set会首先调用元素的hashCode()方法来获取元素的哈希码值,然后根据哈希码值判断元素是否已经存在于Set中。如果哈希码值相同,Set会继续调用元素的equals()方法来比较元素是否相等。只有当哈希码值相等且equals()方法返回true时,Set才会认为元素已经存在于Set中,不会将其重复添加。

5.多线程中start与run区别?

  1. start()方法:

    • 用于启动一个新线程,并让该线程执行run()方法中的代码。
    • 在调用start()方法后,会创建一个新的线程,并使其处于就绪状态,等待CPU调度执行。
    • start()方法会立即返回,并不会等待线程执行完毕。
  2. run()方法:

    • 是Thread类中的一个普通方法,用于定义线程的执行逻辑。
    • 在start()方法启动的新线程中,会自动调用run()方法,并执行其中的代码。
    • run()方法的执行是在当前线程中进行的,而不是在新线程中执行。
    • run()方法会按照顺序依次执行,直到方法结束或线程被中断。

总结:

  • start()方法用于启动一个新线程,让新线程执行run()方法中的代码。
  • run()方法是线程的执行逻辑,会在新线程中自动调用,也可以在当前线程中手动调用。
  • 在多线程编程中,应该使用start()方法来启动线程,而不是直接调用run()方法。因为直接调用run()方法不会创建新线程,而是在当前线程中执行,无法实现多线程的并发执行。

6.什么是乐观锁(版本锁)。什么是悲观锁(行锁)  [不知道如何回答]

乐观锁:在数据库中查询数据后会得到一个版本号 然后对数据进行修改 修改完成之后 会查看数据库此时的数据的版本号是否发生了改变,如果没有,则将修改之后的数据放入数据库;如果改了,则再次查询数据库的版本号,重复上次操作,直到未更改为止,最好将版本号加一。

悲观锁:在查询数据库中,当他修改数据库时后给这个查询加上锁(?),其他人无法访问这个数据库,只有修改完之后,解锁了才可以访问。悲观锁使用表锁和行锁,易死锁

7.java中的反射机制是指什么,常用api有哪些?

csdn的博客: Java反射常用API-CSDN博客

Java中的反射机制是指在运行时动态地获取类的信息,并能够操作类或对象的属性、方法、构造方法等。通过反射机制,可以在程序运行时动态地创建对象、调用方法、获取属性值等,而不需要在编译时确定。

常用的反射API包括:

  1. Class类:表示一个类或接口,在运行时可以通过该类获取类的信息,如类名、父类、接口、构造方法、成员变量、方法等。

  2. Constructor类:表示一个构造方法,在运行时可以通过该类创建对象。

  3. Method类:表示一个方法,在运行时可以通过该类调用方法。

  4. Field类:表示一个成员变量,在运行时可以通过该类获取和设置成员变量的值。

  5. Modifier类:用于获取成员变量、方法、构造方法的修饰符信息。

通过反射机制,可以实现很多动态化的功能,如动态代理、IOC容器、ORM框架等。但是由于反射机制需要在运行时进行类型检查和方法调用,因此会带来一定的性能损失,同时也会降低代码的可读性和可维护性,因此在使用反射机制时需要谨慎。

获取反射的三种方式如下:

        1.通过对象的getClass()方法获取反射&#x

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值