java后端开发实习生-常见面试题
1)JDK,JRE,JVM的关系
- JDK = JRE + java开发工具
- JRE = JVM + java核心类库
2)String类的常用方法
1.关于字符串获取方面
- length 获取长度
- charAt 获取指定索引的字符
- indexOf 获取字符所在的索引位置
- lastIndexOf 获取字符所在的最后一个索引
- subString 截取指定位置的字符串
2.关于判断方面
- equals 判断字符串是否相等
- isEmpty 判断是否为空
- contains 判断是否包含该字符串
3.关于转换方面
- toCharArray 转换成字符数组
- String.valueOf 字符数组转为字符串
- toLowerCase toUpperCase 转大小写
4.其他方法
- trim 去除两段空格
- contact 拼接字符串
- replace 替换字符串
- split 分割字符串
- compareTo 比较字符串大小
- format 格式化字符串
3)String类为什么不能被继承
在java中,String类的声明是带有final关键字的,final的特性决定了不能被继承,不能有子类去重写覆盖,这就保证了String类的不可变性。
4)为什么String类不是基本数据类型
1.存储方式不同
String是引用类型,是一个指向堆区中某个实例的指针。
基本数据类型是存储在栈中的,Java虚拟机会在在栈中分配实际占用的内存空间
2.可变性
string类不可变,而基本数据类型可以实现赋值操作
3.数据存储
基本数据类型数据存储相对简单,运行效率较高
String类有许多属性和方法
5)final finally finalize区别
- final可以用来修饰类,方法,变量,修饰类保证不被继承,修饰方法保证不被重写,修饰变量保证不被重新赋值
- finally用于异常抛出机制,一般来说,不管是否捕捉到了异常,代码块内的内容一定会被执行,除了在try或者catch中用到了system.exit()方法,就不会执行
- finalize是Object类的一个方法,是系统自动执行的垃圾回收处理。
6)String Stringbuffer StringBuilder
1.可变性
String 是一个不可变的字符串类,主要是因为在string的属性value数组是被final修饰的,所以不可以被修改。
Sting Buffer和StringBuilder非常相似,均代表可变的字符串序列,均继承Abstract StringBuilder这个父类,并且均实现了序列化
2.性能
String效率最低,因为它的不可变性导致在做字符串拼接和修改时,需要重新创建新的对象和分配新的内存。
String Builder比StringBuffrr性能高,因为String Buffer加了同步锁
3.线程安全
String是不可变类,所以线程安全
String Buffer是线程安全的,每个方法都加了synchronized同步关键字,常用于多线程环境
String Builder的方法没有使用synchronized关键字,没有做互斥的处理,所以只能在单线程的情况下使用。
7)OOP的理解,类和对象的区别
面向对象:对于Java,简单来说oop就是将某种现实生活中的东西用编程语言来描述(即变成类)。
对象:现实生活中客观存在的,万物皆可为对象,是类对应的实体。
类:是将现实中的对象抽象成java代码世界中的类(建模),用来封装对象的相关数据和处理这些数据的方法
区别:
1.类是抽象的,概念的,代表一类事务,比如人类,猫类,即它是数据类型
2.对象是具体的,实际的,代表一个事务,即实例
3.类是对象的模板,对象是类的一个个体
8)java的优点
1.面向对象
继承,继承其实是父类对子类的共性的抽取, 实现代码的复用。
封装,将属性和相关方法封装在一个对象中,对外隐藏内部细节,外界只需根据提供的接口去使用
多态,同一个方法,不同对象不同行为,体现在方法重载不同类型、向上转型(父类引用子类对象)
进行程序设计,从对象和行为抽象出软件系统。
2.跨平台性
JVM虚拟机屏蔽了底层运行平台的区别,实现“一次编译,到处运行”
3.健壮性
在内存管理上,对比C和C++,需手动分配和释放所有动态内存,java有垃圾回收功能,自动管理内存的分配和释放
4.安全性
java舍去了指针,而以引用去取代,指针容易数组越界,可随便指向一个内容区域,有泄露数据的奉献。java的自带垃圾回收机制、异常处理机制、强制类型转换规则可以保证代码的安全性。
5.多线程 高并发
9)三大特性封装、继承、多态
1.封装:
将类的某些信息隐藏在类的内部,不允许外部直接访问,而是通过该类提供的方法来对隐藏的信息进行操作和访问
设计思想:“高内聚,低耦合”
作用:安全性及复用性
体现:属性私有化,公共方法;单例模式(构造器私有化)
2.继承:
从已有的类中派生出新的类,新的类能吸收已有类的属性和行为,俗称子类继承父类
作用:复用性,子类功能拓展,多态性前提
注意:一个类可以被多个子类继承,一个子类只能有一个父类(Java单继承性)
3.多态:
父类或接口定义的引用变量可以指向子类或具体实现类的实例对象。
表现在:
●方法多态:重写
●对象多态:父类引用执行子类对象(向上转型)
Person p = new Student() (编译看左,执行看右)
10)抽象类和接口区别
1.定义上
抽象类是一种有abstract声明的不能被实例化的类,它定义了一组抽象方法和非抽象方法,其中抽象方法没有具体的实现,需要子类来实现。
抽象类主要用于定义对象共有的属性和行为,并作为子类的基类
接口是一种抽象类型,用interface表示,用于封装一些没有实现的抽象方法。
2.继承和实现的对象
一个类可以实现多个接口,
但只能继承一个抽象类,且必须实现抽象类的所有抽象方法
11)重写(Overload)和重载(Override区别
1.重写
子类继承父类,对父类已有方法重写
目的:对父类方法拓展
要求:父类方法必须公开;
重写的方法一模一样(修饰符,返回值,方法名,参数)
2.重载
同一类中,定义多个同方法名,不同的参数列表区分方法,调用时,JVM会根据不同参数选择合适方法执行
12)Java异常处理机制
Java 异常是 Java 提供的一种识别及响应错误的一致性机制。对于受检异常和非受检异常一般的处异常处理机制都有两种处理方式
●try catch finally 语句块进行捕获异常,处理异常
●在函数签名中使用throws 声明交给函数调用者去解决。
程序员还可以手动编写异常类,使用throw语句手动抛出异常。throw语句必须写在函数中
Error和Exception都是继承Throwable类
- Error表示程序底层或硬件有关的错误,与程序本身无关,不需要检查,比如OOM异常(Java内存溢出错误,jvm虚拟机内存不够用)是非受检异常(编译的时候不需要强制检查的异常,不需要显示去捕捉)
- Exception表示程序中的异常,可能是由于程序不严谨导致的,其中子类RuntimeException是非受检异常,包括:NullPointerException(空指针异常),数组越界是(运行时异常),而其他子类是受检异常(编译的时候需要强制检查的异常,需要显示去捕捉),包括IO异常和SQL异常
13)finally里的语句一定会执行吗?
finally语句块通常是与try catch语句块一起使用的,通常情况下,不管有没有触发异常,finally里面的语句是一定会执行的,所以我们通常会把资源的释放或者业务的日志打印放在finally语句块里面。
但是有一种情况finally里的语句不会执行,就是若在try或catch语句中写了System.exit(0),会导致jvm直接退出,也就不会执行finally里的代码了
14)ArrayList和LinkedList区别
ArrayList和LinkedList之间的区别就是数组与链表之间的区别,
ArrayList底层是可变数组,支持随机访问,查改的效率高,插入删除效率低,而且占用内存比LinkedList少,不需要存储额外的指针信息
LinkedList底层是双向链表,增删效率较高。
两者都线程不安全,没有实现同步,而Vector线程安全,方法带有synchronized
15)介绍一下Spring
Spring 是一个轻量级应用框架,它提供了 loC (控制反转和 AOP(面向切面 这两个核心的功能。
它的核心目的是为了简化企业级应用程序的开发,使得开发者只需要关心业务需求,不需要关心 Bean 的管理,以及通过切面增强功能减少代码的侵入性。
从 Spring 本身的特性来看,我认为有几个关键点是我们选择 Spring 框架的原因:
- 轻量: Spring 是轻量的,基本的版本大约2MB。
- IOC / DI : Spring 通过 IOC 容器实现了 Bean 的生命周期的管理,以及通过 DI 实现依赖注入,从而实现了对象依赖的松耦合管理。
- 面向切面的编程( AOP ): Spring 支持面向切面的编程,从而把应用业务逻辑和系统服务分开。
16)SpringMVC的理解及执行流程
SpringMVC是一种基于Java开发的轻量级Web框架,采用了MVC架构的思想,
将Web职责解藕,分层Model,View Controller
其中Model层代表的是模型,View层代表视图Controller层代表控制器
Spring MVC 的工作流程可以分为几个步骤:
1.用户发起请求,请求先被 Servlet 拦截转发给 Spring MVC 框架
2. Spring MVC 里面的 DispatcherSerlvet 核心控制器,会接收到请求并转发给 HandlerMapping
3. HandlerMapping 负责解析请求,根据请求信息和配置信息找到匹配的 Controller 类,不过这里如果有配置拦截器,就会按照顺序执行拦截器里面的 preHandle 方法
4.找到匹配的 Controller 以后,把请求参数传递给 Controller 里面的方法
5.Controller中的方法执行完以后,会返回一个 ModeAndView ,这里面会包括视图名称和需要传递给视图的模型数据
6.视图解析器根据名称找到视图,然后把数据模型填充到视图里面再渲染成 Html 内容返回给客户端
17)SpringBoot的优点
springboot是一个全新框架,用来简化spring程序的创建和开发过程。在以往我们通过SpringMVC+Spring+Mybatis框架进行开发的时候,我们需要配置web.xml,spring配置,mybatis配置,然后整合在一起,
而springboot抛弃了繁琐的xml配置过程,而是 采用自动配置、起步依赖,让开发人员专注于核心业务代码的开发。
18)MyBatis相比传统的JDBC,它的优点
- Mybatis是java中常用的ORM(对象关系映射)框架,不必与底层的sql语句打交道,而是面向对象的方式操作实体类对象。
- 消除了几乎所有jdbc代码和参数的手工配置以及对结果集的检索封装
- MyBatis是基于XML或注解方式进行数据库操作的持久化框架,它提供了简单的CRUD操作及动态SQL生成等功能
19)MyBatis的三种映射方式
1.纯映射文件方式
2.映射接口+SQL注解方式
3.映射接口(未使用注解)+映射文件混合方式
20)MyBatis常见的设计模式
大致按照模式的应用目标分类,设计模式可以分为创建型模式、结构型模式和行为型模式。
- 创建型模式,是对对象创建过程的各种问题和解决方案的总结,包括各种工厂模式、单例模式、构建器模式、原型模式。
- 结构型模式,是针对软件设计结构的总结,关注于类、对象继承、组合方式的实践经验。常见的结构型模式,包括桥接模式、适配器模式、装饰者模式、代理模式、组合模式、外观模式、享元模式等。
- 行为型模式,是从类或对象之间交互、职责划分等角度总结的模式。比较常见的行为型模式有策略模式、解释器模式、命令模式、观察者模式、迭代器模式、模板方法模式、访问者模式。
21)MyBatis-plus对比MyBatis
MyBatis-Plus相比于MyBatis提供了很多额外的功能,例如像条件构造器、代码生成器、分页插件、性能分析拦截器等实用的组件,使得开发者可以轻松快速完成业务逻辑的开发。
MyBatis的编程风格更加传统,需要定义mapper.xml文件并根据传入的参数使用相应的SQL查询语句,需要实现 Mybatis 提供的各种方法;而MyBatis-Plus具有许多针对CRUD进行的简化方法,通过继承BaseMapper以及使用Lambda表达式,可以类似于接口编程的方式,直接调用内置的CRUD方法。
22)单例模式的了解及两种方式
类的单例模式是指,采取一定方法保证在整个系统开发中,该类只能产生一个实例化对象
有两种方式:
●饿汉式
指在类加载时,就创建了对象实例。存在浪费资源的可能
●懒汉式
只有在使用创建对象的方法时,才创建对象实例
23)线程的状态转换
1.新建->就绪
调用线程的start方法,该线程就进入了可运行线程池中,此时,线程不会立即执行run方法,需要等待获取CPU资源。
2.就绪->运行
线程获取到了CPU时间片后,就会进入运行状态,开始执行run方法
3.运行->就绪
当时间片用完了或调用了yield方法
4.运行->阻塞
调用sleep,join,wait或发送了I/O请求,
5.阻塞->就绪
sleep,join,wait,I/O请求结束
6.运行->结束
线程执行结束,或异常退出run方法
24)介绍事务的ACID特性
事物是一个不可分割的数据库操作序列,他会把所有的操作请求作为一个整体,一起向系统提交或撤销操作,即这些操作要么同时成功,要么同时失败
四大特性:
●原子性Atomicity:事物是不可分割的最小操作单元,要么同时成功,要么同时失败
●一致性Consistency:事务完成时,必须使所有的数据都保持一致状态
●隔离性Isolation:保证事物在不受外部并发操作的影响下,在独立的环境运行
●持久性Durability:只要事务一旦提交或回滚.那么它对数据库的改变一定是永久的
25)对Redis的了解及优点
首先Redis是一个高性能的,基于key-value存储的nosql开源数据库。
它是分布式缓存,相对于Java自带的map(本地缓存),在多实例的情况下,各实例共用缓存为,缓存具有一致性。并且在高性能和高并发上,能够提高数据的检索效率 。
他在市面上之所以流行,主要是基于以下几个特点
●它是基于内存储存的.读写性能高
●提供了丰富的数据存储结构。(string hash list set map)
●Redis作为一个高性能的数据库,适用场景很多:缓存存储访问量大的热点数据、构建消息队列处理大量实时消息、还高效存储用户的会话记录。
所以在企业开发中,除了用MySQL存储数据,一般会通过Redis缓存高访问的数据,来提高效率。