java面试
周瑜 Lv2

1Java基础.

Java语言的特点:

简单易学

面向对象

可以跨平台

可靠性

安全性

支持多线程

支持网络编程并且很方便

编译与解释并存

JVM

Java虚拟机是运行Java字节码的虚拟机。JVM有针对不同系统的特定实现,目的是使用相同的字节码,它们都会给出相同的结果

Java程序从源代码到运行一般有以下三步

JDK先将.java的源文件编译成JVM虚拟机可识别的.class字节码文件,然后我们的JVM在将.class字节码文件转成我们的计算机可识别的二进制文件

JDK和JRE

JDK是功能齐全的Java SDK 它拥有JRE所拥有的一切,它能够创建和编译程序

JRE是Java运行时的环境,他是运行已编译Java程序所需的所有内容的集合,但是他不能用于创建新程序

Java和C++的区别

  • 都是面向对象的语言,都支持封装继承和多态

  • Java不提供指针来直接访问内存,程序内存更加安全

  • Java的类是单继承的,C++支持多重继承,虽然Java的类不可以多继承,但是接口可以多继承

  • Java有自动内存管理垃圾回收机制,不需要程序员手动释放无用内存

  • 在C语言中,字符串或字符数组最后都会有一个额外的字符‘\0’来表示结束,但是Java语言中没有结束符这个概念

泛型

用来定义规范

==和equals的区别

  • ==它的作用是判断两个对象的地址是否相等,就算判断两个对象是不是同一个对象 对基本数据类型比较的是值 对引用类型比较的是内存地址

  • equals 他的作用也是判断两个对象是否相等,他不能用于比较基本类型的变量数据

重载和重写

  • 重载就是同一个类中多个同名方法根据不同的传参来执行不同的逻辑处理

  • 重写就算子类对父类方法的重写改造,外部样子都不能改变,但是内部的逻辑可以随意编写

方法的四种类型

  • 无参数无返回值的方法

  • 有参数无返回值的方法

  • 有返回值无参数的方法

  • 有返回值有参数的方法

面向过程和面向对象的区别

  • 面向过程性能比面向对象高

  • 面向对象易维护,易复用,易扩展

构造器不能被重写 但是可以被重载

构造方法有哪些特性

  • 名字与类命相同
  • 没有返回值,但不能用void声明构造函数
  • 生成类的对象时自动执行,无需调用

String StringBuffer StringBuilder

  • String 是final修饰的,不可变,每次操作都会产生新的String对象
  • StringBuffer 和 StringBulider读都是在原对象上操作的
  • String Buffer方法都是用synchronized修饰的,stringBuffer是线程安全的,StringBulilder是线程不安全的
  • 性能 :StringBulider>StringBuffer>string
  • 经常需要改变字符串内容用StringBuffer和StringBulider,优先使用StringBulider,多线程使用共享变量是用StringBuffer

重载和重写的区别

  • 重载是发生在同一个类中,方法名必须相同,参数类型不同,个数不同,顺序不同,方法返回值和访问修饰符可以不同,发生在编译时
  • 重写是发生在父子类中,方法名,参数列表必须相同,方法里面的业务逻辑可以不同,返回值范围小于等于父类,抛出异常范围小于等于父类,访问修饰符范围大于等于父类,如果父类方法访问修饰符为private则子类不能重写该方法

接口和抽象类的区别:

  • 抽象类中可以写普通的方法,而接口中只能写抽象方法
  • 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final类型
  • 抽象类只能继承一个 但是接口可以实现多个

list和set的区别:

  • list是有序的,按对象进入的顺序保存对象,可重复,允许有多个null元素对象,可以使用迭代器取出所有元素,在逐一遍历,还可以使用get获取指定下标的元素
  • set是无序的,不可重复,最多允许有一个null元素对象,取元素时只能用迭代器接口获取所有元素,在逐一遍历

ArrayList和Linked List的区别

ArrayList基于动态数组,他的内存存储是连续的,适合下标访问,因为数组长度固定,超出长度时需要新建数组然后将老数组的数据拷贝到新数组,如果不是尾部插入数据还会涉及到元素的移动,使用尾插法并指定初始容量可极大提升性能,甚至超过linkedList。

LinkedList基于链表,可以存储在分散的内存中,适合做数据插入及删除操作,不适合查询:需要逐一遍历,遍历LinkedList必须使用迭代器不能使用for循环,因为每次for循环体内通过get(i)取得某一元素时都要对Linkedlist重新遍历,性能消耗极大,

HashMap和HashTable的区别

HashMap方法没有synchronized修饰,是线程非安全的,HashTable是线程安全的;

HashMap允许key和value为null,而HashTable不允许

如何实现一个IOC容器

  1. 配置文件中指定需要扫描的路径
  2. 从配置文件中获取需要扫描的包路径,然后将当前路径下所有以.class结尾的文件添加到一个set集合中进行存储
  3. 遍历这个集合,获取在类上有指定注解的类,并将其交给IOC容器,定义一个安全的Map用来存储这些对象
  4. 遍历这个IOC容器获取到每一个类的实例,判断里面是否有依赖其他类的实例,然后将依赖递归注入

采用字节码的好处

Java语言通过字节码的方式,在一定程度上解决了传统解释型语言执行效率低的问题,同时又保留了解释型语言可移植的特点,所有Java程序在运行时比较高效,而且由于字节码并不专一对一种特定的机器,因此Java程序无须重新编译便可在多种不同的计算机上运行

Java中的异常体系

Java所有的异常都来自父类Throwable

Throwable下有两个子类Exception和error

error市程序无法处理的错误,一旦出现这个错误,则程序将被迫停止运行

exception不会导致程序停止,又分为两个部分RunTimeException运行时异常和CheckedException检查异常

线程的生命周期,线程有哪些状态

线程的生命周期和状态分为五种状态:创建、就绪、运行、阻塞和死亡状态

  1. 新建状态:新创建了一个对象
  2. 就绪状态:线程对象创建后,其他线程就调用该对象的start方法,该状态的线程位于可运行线程池中,变得可运行,等待获取CPU的使用权
  3. 运行状态:就绪状态的线程获取了CPU,执行程序代码
  4. 阻塞状态:阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行,直到线程进入就绪状态,才有机会转到运行状态
  5. 死亡状态:线程执行完了或者异常退出了run方法,该线程结束生命周期

并发的三大特性

  • 原子性
  • 可见性
  • 有序性

为什么用线程池

  • 降低资源消耗,提高线程利用率,降低创建和销毁线程的消耗
  • 提高响应速度,任务来了,直接有线程可用可执行,而不是先创建线程在执行
  • 提高线程的可管理性,线程是稀缺资源,使用线程池也可以统一分配调优监控

2.spring框架

spring是什么

spring是一个轻量级的开源的J2EE框架,他是一个容器框架,中间层框架,可以起到一个连接的作用,比如它可以把spring MVC 和Mybatis整合在一起使用,可以让我们的企业开发更快、更简洁,它的特性有ioc和aop,ioc可以达到解耦合的目的

谈谈你对AOP的理解

就算在运行时,动态地将代码切入到类的指定方法、指定位置上的编程思想就是面向切面的编程。

ioc的理解

ioc即控制反转,他不是技术而是一种设计思想,就是将你设计好的对象交给ioc容器控制,然后由ioc帮我们查找和注入依赖对象,对象只要被动的接受依赖就行了

bean的自动装配

  • byName-根据bean的属性名称进行自动装配
  • byType-根据bean类型进行自动装配
  • @Autowired注解自动装配

SpringBoot、SpringMVC、Spring的区别

spring是一个IOC容器,用来管理bean,使用依赖注入实现控制反转,可以很方便的整合各种框架

springmvc是spring对web框架的一个解决方案,提供了一个总的前端控制器servlet用来接受请求,然后将handle结果使用视图解析技术生成视图展现给前端

springboot是spring提供的一个快速开发工具包,让程序员能更方便、更快速的开发spring+springmvc应用,简化了配置,整合了一系列的解决方案,很多框架都可以开箱即用

SpringMVC的工作流程

  1. 用户发送请求到前端控制器dispatcherServlet
  2. dispatcherServlet收到请求调用HandlerMapping处理映射器
  3. 处理映射器根据请求url映射到具体的处理器controller
  4. controller执行完成后返回一个modelandview
  5. 待解析器将modelandview解析后返回给dispatchServlet
  6. 最后dispatchServlet将数据响应给用户

springBoot自动配置原理

如何理解SpringBoot中的Starter

使用spring+springMVC项目,如果要使用mybatis等框架,需要到xml中定义mybatis需要的bean

spring boot中的starter就是定义一个starter的jar包,写一个@Configuration配置类,将这些bean定义在里面,然后在starter包的META-INF/spring.factories中写入该配置类,springboot会按照约定来加载该配置类

开发人员只需要将相应的starter包依赖进应用,进行相应的属性配置(使用默认配置时,不需要配置),就可以直接进行代码开发,使用对应的功能了,比如,mybatis-spring-boot-starter,spring-boot-starter-redis

为什么要使用嵌入式服务器

节省了下载安装tomcat,应用也不需要再打war包,然后放到webapp目录下在运行

只需要一个安装了Java的虚拟机,就可以直接在上面部署应用程序了

springboot已经内置了tomcat.jar,运行main方法时会去启动tomcat,并利用tomcat的spi机制加载springmvc

3.Mybatis框架及数据库

mybatis的优缺点

优点:

  • 基于sql语句编程,相当灵活
  • sql写在xml里,解除sql与程序代码的耦合,便于统一管理
  • 提供xml标签,支持编写动态sql语句,并可重用
  • 消除了jdbc大量冗余的代码,不需要手动开关连接
  • 与spring能很好的集成
  • 提供映射标签,支持对象与数据库的orm字段关系映射

缺点

  • 编写sql语句时工作量很大,尤其是多字段,关联表多时
  • sql语句依赖于数据库,导致数据库移植性差,不能更换数据库
  • 二级缓存机制不佳

#{}和${}的区别

#是预编译处理,是占位符,$是字符串替换,是拼接符

mybatis在处理#时,会将sql里的#{}替换为?号,而处理$时,就会直接把${}替换为变量的值

使用#可以有效的防止sql注入,提高系统安全性

索引的基本原理

索引用来快速地寻找那些具有特定值的记录。如果没有索引,一般来说执行查询时遍历整张表。

索引的原理:就算把无序的数据变成有序的查询

步骤:

  1. 把创建了索引的列的内容进行排序
  2. 对排序结果生成倒排表
  3. 在倒排表内容上拼上数据地址链
  4. 在查询的时候,先拿到倒排表内容,再取出数据地址链,从而拿到具体数据

索引设计的原则

查询更快,占用空间更小

  • Post title:java面试
  • Post author:周瑜
  • Create time:2021-04-06 18:59:06
  • Post link:https://xinblog.github.io/2021/04/06/java面试-md/
  • Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.
 Comments