java面试真题&附参考答案【上册】

tips:下面简述题为java面试真题,阅读本文且感兴趣的,还有将要面试的小伙伴有条件的准备一下笔和纸,将之转述出来成为自己的知识,希望接下来的面试好运连连

目录

1.Java中的四种访问权限分别是什么?它们分别可以修饰什么?

2.Java中的接口和抽象类有什么区别?

3.说一下Java中的多态,以及它的实现方式。

4.什么是多线程,什么是线程安全?什么时候出现线程安全问题?如何保证线程安全?

5.简述Spring框架的核心功能,包括IOC和AOP。

6.MyBatis框架中的Mapper是什么?如何使用?

7.经常使用框架有什么好处?

8.synchronized和Renntrantlock的区别?后者怎么实现的?

9.什么是aqs?

10.请简单介绍一下MySQL数据库,并说明其特点和优劣。


1.Java中的四种访问权限分别是什么?它们分别可以修饰什么?

    四种访问权限分别是:public:protected:default:private:
    public:公共的 所修饰的类、变量、方法,在内外包均具有访问权限;
    protected:受保护的 这种权限是为继承而设计的,protected所修饰的成员,对所有子类是可访问的,对同包的类是可访问的,但对外包的非子类是不可以访问;
    default:包访问权限 只有同包的类有访问权限;
    private:私有的 只对本类的方法可以使用(可以多说两句private能不能修饰类)

2.Java中的接口和抽象类有什么区别?

1)从基础知识方面来讲(拓展学习)
Java中接口和抽象类的定义语法分别为interface与abstract关键字。
抽象类:在Java中被abstract关键字修饰的类称为抽象类,被abstract关键字修饰的方法称为抽象方法,抽象方法只有方法的声明,没有方法体。
抽象类的特点:
a、抽象类不能被实例化,只能被继承;
b、包含抽象方法的一定是抽象类,但是抽象类不一定含有抽象方法;
c、抽象类中的抽象方法的修饰符只能为public或者protected,默认为public;
d、一个子类继承一个抽象类,则子类必须实现父类抽象方法,否则子类也必须定义为抽象类;
e、抽象类可以包含属性、方法、构造方法,但是构造方法不能用于实例化,主要用途是被子类调用。
接口:Java中接口使用interface关键字修饰,特点为:
a、接口可以包含变量、方法;变量被隐式指定为public static final,方法被隐式指定为public abstract(JDK1.8之前);
b、接口支持多继承,即一个接口可以implements多个接口,间接的解决了Java中类的单继承问题;
c、一个类可以实现多个接口;
d、JDK1.8中对接口增加了新的特性:(1)默认方法(default method):JDK 1.8允许给接口添加非抽象的方法实现,但必须使用default关键字修饰;定义了default的方法可以不被实现子类所实现,但只能被实现子类的对象调用;如果子类实现了多个接口,并且这些接口包含一样的默认方法,则子类必须重写默认方法;(2)静态方法(static method):JDK 1.8中允许使用static关键字修饰一个方法,并提供实现,称为接口静态方法。接口静态方法只能通过接口调用(接口名.静态方法名)。
如下例子所示:

public interface Person{
  public static final int a=10;
  //JDK1.8
    default void sayHello(){
        System.out.println("Hello World");
    }
    public void say();
}
public abstract class Person{
  public abstract void say();
  public void eat(){};
}

如上述代码所示:

接口只能是功能的定义,而抽象类既可以为功能的定义也可以为功能的实现。

2)从面试角度:接口与抽象类的区别
相同点:
(1)都不能被实例化 (2)接口的实现类或抽象类的子类都只有实现了接口或抽象类中的方法后才能实例化。
不同点:
(1)接口只有定义,不能有方法的实现,java 1.8中可以定义default方法体,而抽象类可以有定义与实现,方法可在抽象类中实现。
(2)实现接口的关键字为implements,继承抽象类的关键字为extends。一个类可以实现多个接口,但一个类只能继承一个抽象类。所以,使用接口可以间接地实现多重继承。
(3)接口强调特定功能的实现,而抽象类强调所属关系。
(4)接口成员变量默认为public static final,必须赋初值,不能被修改;其所有的成员方法都是public、abstract的。抽象类中成员变量默认default,可在子类中被重新定义,也可被重新赋值;抽象方法被abstract修饰,不能被private、static、synchronized和native等修饰,必须以分号结尾,不带花括号。

3.说一下Java中的多态,以及它的实现方式。


    java面向对象三大特征:封装 继承 多态
    多态:同一个类型的行为具有多个不同表现形式或形态的能力,Java允许把一个子类对象直接赋给一个父类引用变量,无须任何类型转换,或者被称为向上转型,向上转型由编译器自动完成。
    多态的必要条件:1.要有继承(or接口的实现)2.要有重写 3.父类引用指向子类对象
    多态优点:1、实现代码的复用,避免代码的冗余;2、减少代码之间的关联性,即耦合度,方便后期对代码的修改,功能的改善,不必牵一发而动全身,减少不必要的麻烦;3、能够通过重写子类的方法,使不同的对象具有不同的功能,扩展了功能。
    类方法实现多态:
        1.重载(参数个数,顺序,类型不同)
        2.方法重写(父类与子类方法名一致)
        3.父类引用指向子类对象(编译期看父类,运行期看子类)
        4.对静态成员方法、成员变量:编译和运行都看左边

        Animal x = new Cat();//向上转型
        x只能调用父类方法,调用子类方法会报错
        Animal x = new Cat();
        Cat s = (Cat)x;//向下转型
        s可以调用子类和父类方法


4.什么是多线程,什么是线程安全?什么时候出现线程安全问题?如何保证线程安全?


    多线程:Java多线程是指在Java编程语言中同时执行多个线程的能力。线程是程序的执行单元,可以同时执行多个任务,提高程序的并发性和效率。
        在Java中,可以通过创建Thread类的实例来创建和管理线程。可以使用Thread类的start()方法启动线程的执行。此外,还可以实现Runnable接口,并将其传递给Thread类的构造函数来创建线程。
多线程编程可以实现以下几个目的:
提高程序的响应性:可以在后台执行耗时的任务,同时保持程序的交互性。
提高系统资源利用率:通过同时执行多个任务,充分利用CPU资源。
实现并行计算:将任务拆分为多个子任务,分配给不同的线程并行执行,加快计算速度。
然而,多线程编程也需要注意线程安全性、竞态条件、死锁等问题,需要合理地设计和同步线程来避免这些问题。
    线程安全:线程安全是多线程编程时的计算机程序代码中的一个概念。在拥有共享数据的多条线程并行执行的程序中,线程安全的代码会通过同步机制保证各个线程都可以正常且正确的执行,不会出现数据污染等意外情况。
    线程安全问题:线程安全问题在多线程编程中可能会出现,具体取决于以下几个因素:

        共享数据:当多个线程同时访问和修改共享数据时,可能会导致线程安全问题。例如,多个线程同时对同一个变量进行写操作,可能导致数据不一致或丢失。

        竞态条件:当多个线程在执行过程中的结果依赖于彼此的执行顺序时,可能会产生竞态条件。例如,两个线程同时对同一个变量进行读写操作,由于执行顺序的不确定性,可能导致意外的结果。

        不正确的同步:如果在多线程环境下没有正确地使用同步机制,可能会导致线程安全问题。例如,没有正确地使用锁或其他同步工具来保护共享数据,可能导致数据的不一致性。

        死锁:当多个线程互相等待对方释放资源时,可能会发生死锁。这种情况下,所有的线程都无法继续执行,导致程序无法正常运行。

        线程安全问题的出现是由于多线程并发执行引起的,当多个线程同时访问和修改共享资源时,需要正确地使用同步机制来保证数据的一致性和正确性。
    如何保证线程安全:
        原子类(JUC):JDK从1.5开始提供了java.util.concurrent.atomic包,这个包中的原子操作类提供了一种用法简单、性能高效、线程安全地更新一个变量的方式。在atomic包里一共提供了17个类,按功能可以归纳为4种类型的原子更新方式,分别是原子更新基本类型、原子更新引用类型、原子更新属性、原子更新数组。无论原子更新哪种类型,都要遵循“比较和替换”规则,即比较要更新的值是否等于期望值,如果是则更新,如果不是则失败。
        volatile:是轻量级的synchronized,它在多处理器开发中保证了共享变量的“可见性”以及防止指令重排序,从而可以保证单个变量读写时的线程安全。可见性问题是由处理器核心的缓存导致的,每个核心均有各自的缓存,而这些缓存均要与内存进行同步。volatile具有如下的内存语义:当写一个volatile变量时,该线程本地内存中的共享变量的值会被立刻刷新到主内存;当读一个volatile变量时,该线程本地内存会被置为无效,迫使线程直接从主内存中读取共享变量。
        :原子类和volatile只能保证单个共享变量的线程安全,锁则可以保证临界区内的多个共享变量的线程安全,Java中加锁的方式有两种,分别是synchronized关键字和Lock接口。synchronized是比较早期的API,在设计之初没有考虑到超时机制、非阻塞形式,以及多个条件变量。若想通过升级的方式让它支持这些相对复杂的功能,则需要大改它的语法结构,不利于兼容旧代码。因此,JDK的开发团队在1.5新增了Lock接口,并通过Lock支持了上述的功能,即:支持响应中断、支持超时机制、支持以非阻塞的方式获取锁、支持多个条件变量(阻塞队列)。


5.简述Spring框架的核心功能,包括IOC和AOP。


    spring框架是一款轻量级框架,核心是ioc控制翻转和aop面向切面编程;
    IOC:Spring IOC容器管理对象,IoC不是一种技术,只是一种思想,一个重要的面向对象编程的法则,它能指导我们如何设计出松耦合、更优良的程序。传统应用程序都是由我们在类内部主动创建依赖对象,从而导致类与类之间高耦合,难于测试;有了IoC容器后,把创建和查找依赖对象的控制权交给了容器,由容器进行注入组合对象,所以对象与对象之间是松散耦合,这样也方便测试,利于功能复用,更重要的是使得程序的整个体系结构变得非常灵活。
    AOP:面向切面编程,aop是一种思想,是面向对象(oop)编程的一种补充。面向对象编程将程序抽成个各层次的对象,而面向切面编程是将程序抽象成各个切面。
SpringMVC框架中,控制器的作用是什么?怎样配置控制器?
    1.控制器复杂提供访问应用程序的行为,通常通过接口定义或注解定义两种方法实现。2.控制器负责解析用户的请求并将其转换为一个模型。3.在Spring MVC中一个控制器类可以包含多个方法,在Spring MVC中,对于Controller的配置方式有很多种。


6.MyBatis框架中的Mapper是什么?如何使用?


    在MyBatis框架中,Mapper是一个接口,用于定义数据库操作的方法。Mapper接口定义了与数据库交互的SQL语句,以及映射数据库结果集到Java对象的规则。

        Mapper接口中的方法通常对应于数据库的CRUD操作(增删改查),例如插入数据、更新数据、删除数据以及查询数据等。MyBatis框架会根据Mapper接口的方法名和参数来动态生成相应的SQL语句,并执行数据库操作。

        Mapper接口的实现是由MyBatis框架自动生成的,无需手动编写实现类。在MyBatis的配置文件中,需要将Mapper接口与相应的映射文件(XML文件)进行关联,映射文件中定义了SQL语句的具体实现以及与Java对象之间的映射规则。

        通过Mapper接口的方法,我们可以方便地进行数据库操作,而无需编写繁琐的SQL语句和结果集映射代码。这使得数据库操作更加简洁和易于维护。


7.经常使用框架有什么好处?


使用框架有以下几个好处:

  • 提高开发效率:框架提供了一系列的工具、组件和规范,能够简化开发过程,减少重复性的代码编写。开发者可以直接使用框架提供的功能,而无需从头开始构建应用程序的基础结构,从而节省了开发时间和精力。
  • 提供标准化和规范化:框架通常遵循一系列的设计原则、最佳实践和标准化规范,使得代码结构更加清晰、可维护性更高。开发者可以基于框架进行开发,遵循框架的规范,提高代码的可读性和可维护性。
  • 提供高性能和优化:框架通常经过优化和测试,能够提供高性能的运行效果。框架在底层实现了一些复杂的算法和数据结构,以提高应用程序的性能和效率。
  • 提供丰富的功能扩展:框架通常提供了丰富的功能扩展机制,可以根据需要选择性地扩展和定制功能。开发者可以通过插件、模块、扩展点等方式,将自己的代码与框架集成,实现更多的功能和业务需求。
  • 提供良好的文档和社区支持:常见的框架通常拥有完善的文档和活跃的社区支持,开发者可以通过官方文档、教程、示例代码等获取帮助和解决问题。社区中的其他开发者也可以共享经验和提供支持,加快问题的解决和学习的进程。

        综上所述,使用框架可以提高开发效率、标准化代码、提供高性能和丰富的功能扩展,同时还能够获取文档和社区支持,使得开发过程更加便捷和高效。


8.synchronized和Renntrantlock的区别?后者怎么实现的?


        synchronized是可重用锁,他有俩种使用方式,方法或者代码块。加锁的话是传入一个人对象或者一个静态类,其实是对对象头进行一个操作,会把线程的id存储到对象头里面,线程在第二次调用这把锁的时候,他去判断这个id是不是锁里面的id,如果是的话他就可以直接操作。因为是jvm自己管理的,所以锁释放的话,当run方法执行完,也会直接释放。

        ReentrantLock需要手动加锁和释放,首先我们要加锁,并在finally里面进行释放。和synchronized相比,ReentrantLock用起来会复杂一些。在基本的加锁和解锁上,两者是一样的,所以无特殊情况下,推荐使用synchronized。ReentrantLock的优势在于它更灵活、更强大,增加了轮训、超时、中断等高级功能

ReentrantLock是Java中的一个可重入锁:

        它的实现原理是基于AQS(AbstractQueuedSynchronizer)实现的。AQS是一个抽象的同步器,它提供了一种基于FIFO等待队列的同步机制,可以用来实现各种同步器,如锁、信号量、倒计时器等。

        ReentrantLock内部维护了一个state变量,用来表示锁的状态。当state为时,表示锁是未锁定状态;当state为1时,表示锁是锁定状态。当一个线程请求锁时,如果state为,表示锁是未锁定状态,那么该线程就可以获得锁,并将state设置为1;如果state为1,表示锁已经被其他线程锁定了,那么该线程就会被加入到等待队列中,等待其他线程释放锁。

        ReentrantLock还支持可重入性,即同一个线程可以多次获得同一个锁,而不会被阻塞。这是通过维护一个owner变量来实现的,owner变量记录了当前持有锁的线程。当一个线程再次请求锁时,如果它是当前持有锁的线程,那么它可以直接获得锁,而不会被阻塞。当线程释放锁时,它会将state减1,如果state变为,表示锁已经完全释放,那么它会唤醒等待队列中的一个线程,让它获得锁。

        总之,ReentrantLock的实现原理是基于AQS实现的,它通过维护一个state变量和一个等待队列来实现锁的功能,同时支持可重入性,保证同一个线程可以多次获得同一个锁。


9.什么是aqs?


        AQS是英文单词AbstractQueuedSynchronizer的缩写,翻译过来就是队列同步器。
它是构建锁或者其他同步组件的基础框架(如ReentrantLock、ReentrantReadWriteLock、Semaphore等),JUC并发包的作者(Doug Lea)期望它能够成为实现大部分同步需求的基础。它是JUC并发包中的核心基础组件。
        AQS的主要使用方式是继承,子类通过继承同步器并实现它的抽象方法来管理同步状态。


10.请简单介绍一下MySQL数据库,并说明其特点和优劣。


        MySQL是一个 关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于  Oracle 旗下产品。MySQL 是最流行的 关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的  RDBMS (Relational Database Management System,关系数据库管理系统) 应用软件。
        优点:

  • 体积小、速度快、总体拥有成本低,开源,提供的接口支持多种语言连接操作
  • MySQL 的核心程序采用完全的多线程编程。线程是轻量级的进程,它可以灵活地为用户提供服务,而不过多的系统资源。用多线程和C语言实现的MySQL ,充分利用CPU资源
  • 有一个非常灵活而且安全的权限和口令系统。当客户与MySQL 服务器连接时,他们之间所有的口令传送被加密,而且MySQL 支持主机认证
  • 支持大型的数据库, 可以方便地支持上千万条记录的数据库。作为一个开放源代码的数据库,可以针对不同的应用进行相应的修改
  • 支持多种操作系统,如Linux、Windows、AIX、FreeBSD、HP-UX、MacOS、NovellNetware、OpenBSD、OS/2 Wrap、Solaris等
  • 提供多语言支持,常见的编码如GB2312、BIG5、UTF8

        缺点:

  • 不支持热备份
  • 不支持自定义数据类型
  • 对存储过程和触发器支持不够友好
  • MySQL最大的缺点是其安全系统,主要是复杂而非标准,另外只有到调用mysqladmin来重读用户权限时才发生改变

猜你喜欢

转载自blog.csdn.net/weixin_56800176/article/details/131815167