欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java面试知识点

程序员文章站 2024-03-23 14:58:58
...

1.抽象类和接口

相同点:都不能被实例化,位于继承树的顶端,都包含抽象方法

不同点:1、设计目的:接口体现的一种规范,类似与整个系统的总纲,制订了系统各模块应该遵循的标准,因此接口不应该经常改变,一旦改变对整个系统是辐射性的。

               抽象类作为多个子类的共同父类,体现的是一种模板式设计,可以当作系统实现过程中的中间产品,已经实现了系统部分功能。

            2、使用不同:(1)接口只能包含抽象方法,抽象类可以包含普通方法。

                                   (2)接口里不能定义静态方法,抽象类可以。

                                   (3)接口只能定义静态常量属性不能定义普通属性,抽象类可以。

                                   (4)接口不包含构造器,抽象类可以(不是用于创建对象而是让子类完成初始化)。

                                   (5)接口里不能包含初始化块,抽象类完全可以。

                                   (6)接口多继承,抽象类单继承(只能有一个直接父类)。

总结:接口所有方法全是抽象方法只能 public abstract修饰 (默认public abstract修饰 ),属性默认public static final修饰。

             抽象类除了包含抽象方法外与普通类无区别。

2.Java实现多线程的三种方式及三种方式的区别

  (1)继承Thread类,实现run 方法 (2)实现runnable接口 (3)实现Callable接口

 

  • 实现Runnable接口可以避免Java单继承特性而带来的局限;增强程序的健壮性,代码能够被多个线程共享,代码与数据是独立的;适合多个相同程序代码的线程区处理同一资源的情况。 

  • 继承Thread类和实现Runnable方法启动线程都是使用start方法,然后JVM虚拟机将此线程放到就绪队列中,如果有处理机可用,则执行run方法。 

  • 实现Callable接口要实现call方法,并且线程执行完毕后会有返回值。其他的两种都是重写run方法,没有返回值

3.Java中的NIO,BIO,AIO分别是什么?  

  

  • BIO 

    • 同步并阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善。 

    • BIO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4以前的唯一选择,但程序直观简单易理解。 

  • NIO  

    • 同步非阻塞,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。 

    • NIO方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂,JDK1.4开始支持。 

  • AIO 

    •  异步非阻塞,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理. 

    • AIO方式使用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂,JDK7开始支持。 

3.1 同步 异步,阻塞 非阻塞

     同步和异步是消息的机制(异步有通知信息返回)

 同步:执行一个操作之后,等待结果,然后才继续执行后续的操作。

异步:执行一个操作后,可以去执行其他的操作,然后等待通知再回来执行刚才没执行完的操作。

阻塞 和 非阻塞关注的是程序在等待调用结果时的状态

阻塞:进程给CPU传达一个任务之后,一直等待CPU处理完成,然后才执行后面的操作。

非阻塞:进程给CPU传达任我后,继续处理后续的操作,隔断时间再来询问之前的操作是否完成。这样的过程其实也叫轮询。

4.产生死锁的必要条件

       1.互斥条件,2.占有且申请,3.循环等待,4.不可抢占条件 

     如何预防死锁    

5.如何保证线程安全

   1.对非安全的代码进行加锁控制;2.使用线程安全的类;3.多线程并发情况下,线程共享的变量改为方法级的局部变量。

6.类加载的过程

类从被加载到虚拟机内存中开始,到卸载出内存为止,它的生命周期包括了:加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)、卸载(Unloading)七个阶段,其中验证、准备、解析三个部分统称链接。

 7.Spring AOP(面向切面编程)和IOC(控制反转)(DI 依赖注入)

什么是AOP? 
面向切面编程(AOP)完善spring的依赖注入(DI),面向切面编程在spring中主要表现为两个方面 
1.面向切面编程提供声明式事务管理 
2.spring支持用户自定义的切面 

面向切面编程(aop)是对面向对象编程(oop)的补充, 
面向对象编程将程序分解成各个层次的对象,面向切面编程将程序运行过程分解成各个切面。 
AOP从程序运行角度考虑程序的结构,提取业务处理过程的切面,oop是静态的抽象,aop是动态的抽象, 
是对应用执行过程中的步骤进行抽象,,从而获得步骤之间的逻辑划分。 

aop框架具有的两个特征: 
1.各个步骤之间的良好隔离性 
2.源代码无关性 

 

 

什么是DI机制? 
依赖注入(Dependecy Injection)和控制反转(Inversion of Control)是同一个概念,具体的讲:当某个角色 
需要另外一个角色协助的时候,在传统的程序设计过程中,通常由调用者来创建被调用者的实例。但在spring中 
创建被调用者的工作不再由调用者来完成,因此称为控制反转。创建被调用者的工作由spring来完成,然后注入调用者 
因此也称为依赖注入。 
spring以动态灵活的方式来管理对象 , 注入的两种方式,设置注入和构造注入。 
设置注入的优点:直观,自然 
构造注入的优点:可以在构造器中决定依赖关系的顺序。

Spring 事务

8.finally

finally{}是不管try{}catch{}是否捕获到异常,它始终会被执行。finally{}后的代码也会被执行,前提是上面的语句没有检测到return语句。

9. 类加载器

java面试知识点

10.单例模式

  饿汉模式 懒汉模式 静态内部类 双重校验锁 meij

//饥饿模式
public final class EagerSingleton  
{  
    private static EagerSingleton singObj = new EagerSingleton();  
  
    private EagerSingleton(){  
    }  
  
    public static EagerSingleton getSingleInstance(){  
       return singObj;
    }  
}

饿汉模式不会有线程安全的问题,如果对象很大,会造成潜在的性能问题。

//懒汉模式
public final class LazySingleton  
{  
    private static LazySingleton singObj = null;  
  
    private LazySingleton(){  
    }  
  
    public static LazySingleton getSingleInstance(){  
        if(null == singObj ) singObj = new LazySingleton();
          return singObj;
    }  
}

静态内部类方式

java面试知识点

//双重校验锁
public class Singleton {
    private static Singleton instance;
    private Singleton (){}

    public static Singleton getInstance() {
     if (instance == null) {
       synchronized (Singleton.class) {
            if (instance == null) {                 
             //Double Checked
           instance = new Singleton();
            }
        }
     }
     return instance;
    }
}
  1. 给 instance 分配内存
  2. 调用 Singleton 的构造函数来初始化成员变量
  3. 将instance对象指向分配的内存空间(执行完这步 instance 就为非 null 了)

但是在 JVM 的即时编译器中存在指令重排序的优化。也就是说上面的第二步和第三步的顺序是不能保证的,最终的执行顺序可能是 1-2-3 也可能是 1-3-2。如果是后者,则在 3 执行完毕、2 未执行之前,被线程二抢占了,这时 instance 已经是非 null 了(但却没有初始化),所以线程二会直接返回 instance,然后使用,然后顺理成章地报错。

我们只需要将 instance 变量声明成 volatile 就可以了。

    private volatile static Singleton instance; //声明成 volatile

11.哈希索引

  1. 不支持范围查询
  2. 不支持索引完成排序
  3. 不支持联合索引的最左前缀匹配规则
  4. 以等值查询为主,没有范围查询,没有排序的时候,适合哈希查找    

12.mySql中myIsam和InnoB的区别

  • InnoDB支持事务操作,同时支持外键,myIsam不支持外键。
  • myIsam支持表锁,并且有一个字段存储表的行数,InnoDB支持行锁,不保存表的具体行数
  • Innodb不支持全文索引,而MyISAM支持全文索引,查询效率上MyISAM要高(是因为MyISAM索引和数据是分开的,而且支持索引压缩,内存使用率提高了很多);
  • InnoDB是聚集索引,MyIsam是非聚集索引。
  • 如果创建数据不再进行修改,可以采用MyISAM压缩表
  • InnoDB表的行锁也不是绝对的,如果在执行一个SQL语句时MySQL不能确定要扫描的范围,InnoDB表同样会锁全表,例如update table set num=1 where name like “%aaa%。

13.索引失效的情况

  • 字段类型转换导致索引失效
  • 对索引列运算导致索引失效
  • 使用函数也会导致索引失效
  • 不符合最左匹配原则
  • 字符型字段为数字时在where条件里不添加引号

14.GC root的对象

  • 虚拟机栈中栈帧的局部变量表所引用的对象
  • 本地方法栈JNI(Native)引用的对象
  • 方法区中的静态变量和常量引用的对象

15.jdk18新特性

  • lambda表达式
  • 接口中可以有默认方法和静态方法
  • 支持多重注解

16.java 泛型

  • java泛型是参数化类型
  • Object 和 T 很重要的两点区别,T从一开始就会限定这个类型,(他可以限定类型为Object)。
  • Object是所有类的父类,所以会强制类型转换,而T不需要强制类型转换,因为他一开始就固定了。