Java八股文面试题
1.为什么用线程池?解释下线程池参数?
- 降低资源消耗,降低创建和销毁线程的消耗
- 提升响应速度,直接有线程可用可执行
- 提高线程的可管理性;
- corePloolSize代表核心线程数,这些线程创建后并不会消除
- maxinumPoolSize代表的最大线程数
- AliveTime、unjt表示超出核心线程数之外的线程的空闲存活时间
- workQueue:用来存放待执行的任务,假设我们现在核心线程都已被使用
- Handler:任务拒绝策略,两种,第一种shundown等方法关闭线程池,第二种,当达到最大线程数,线程池已没有能力机械处理新提交的任务时
2.简述线程池处理流程
根据拒绝策略处理任务
3.线程池中阻塞队列的作用?为什么是先添加队列而不是先创建最大线程
- 普通队列保证作为一个有限长度的缓冲区,阻塞队列通过阻塞可以保留住当前想要继续入队的任务。阻塞队列可以保证任务队列中没有任务时阻塞获取任务的线程,使得线程进入wait状态,释放cpu资源
- 在创建新线程的时候,是要获取全局锁的,这个时候其他的就得阻塞,影响了整体效率。
4.线程池中线程复用原理
- 线程池将线程和任务进行解耦,线程是线程,任务是任务,拜托了之前通过Thread创建线程时的一个线程必须对应一个任务的限制。
- 在线程池中,同一个线程可以从阻塞队列中不断获取新任务来执行,其核心原理在于线程池对Thread进行了封装,并不是每次执行任务都会调用Thread.start()来创建新线程,而是让每个线程去执行一个“循环任务”,在这个循环任务中不停检查是否有任务需要被执行,如果有则直接执行,也就是调用任务中的run方法,将run方法当成一个普通的方法执行,通过这种方式只使用固定的线程将所有任务的run方法串联起来。
5.spring是什么?
- 轻量级的开源的J2EE框架,它是一个容器框架,用来装javabean(java对象),中间层框架(万能胶)可以起一个连接作用,比如把Sruts和hibernate粘合在一起运用,可以让我们的企业开发更快、更简洁
- -从大小与开销两方面而言Spring都是轻量级的。
- -通过控制反转(IoC)和面向切面(AOP)的容器框架
- -提供了面向切面编程的丰富支持,允许通过分离应用的业务逻辑与系统级服务进行内聚性的开发
- -包含并管理应用对象(Bean)的配置和生命周期,这个意义是一个容器
- -将简单的组件配置、组合成为复杂的应用,这个意义是一个框架。
6.AOP的理解
- 在OOP设计中,它导致了大量代码的重复,而不利于各个模块的重用。
- AOP:将程序中的交叉业务逻辑(比如安全,日志,事务等),封装成一个切面,然后注入到目标对象(具体业务逻辑)中去。AOP可以对某个对象或某些对象的功能进行增强,比如对象的方法进行增强,可以执行某个方法之前额外做一些事情,在某个方法执行之后额外的做一些事情
7.IOC的理解
- 容器概念,控制反转,依赖注入
- ioc容器:实际上就是个map(key,value),里面存的是各种对象(在xml里配置的bean节点、@repository、@Service、@controller、@component),在项目启动的时候会读取配置文件里面的bean节点,根据全限定类名的使用反射创建对象放到map里、扫描到打上上述注解的类还是通过反射创建对象放到map里。这个时候map里就有各种对象了,接下来我们在代码里需要用到里面的对象时,再通过DI注入(autowired、resource等注解,xml里bean节点内的ref属性,项目启动的时候会读取xml节点ref属性根据id注入,也会扫描这些注解,根据类型或id注入;id就是对象名)。
- 控制反转:
对象A和对象B之间失去了直接联系,当对象A运行到需要对象B的时候,IOC容器会主动创建一个对象B注入到对象A需要的地方。对象A获得依赖对象B的过程由主动变为了被动行为,控制权颠倒过来了。 - 依赖注入:
实现控制反转,就是由IOC容器在运行期间,动态地将某种依赖关系注入到对象之中。
8.BeanFactory和ApplicationConetext有什么区别?
- ApplicationContext是BeanFactory的子接口
- ApplicationContext提供了更加完整地功能
1.继承MessageSource,因此支持国际化
2.统一地资源文件访问方式
3.提供在监听器中注册bean地事件。
4.同时加载多个配置文件
5.载入多个(有继承关系)上下文,使得每一个上下文都专注于一个特定地层次,比如应用的web层。 - BeanFactory采用延时加载形式注入Bean,在使用某一个Bean时调用,发现异常需要在调用时才发现
- ApplicationContext它是在启动容器时,一次创建所有的bean,这样在容器启动时,就可以发现Spring中存在的配置错误。
- ApplicationContext启动相较于BeanFactory较慢。
- BeanFactory编程的方式被创建,ApplicationContext还能以声明的方式创建,如使用ContextLoader.
9.SpringBean的生命周期
- 解析类得到BeanDefinition
- 如果有多个构造方法,则要推断构造方法
- 确定好多个构造方法后,进行实例化得到一个对象
- 对对象中的加了@Autowired注解的属性进行属性填充
- 回调Aware方法,比如BeanNameAware,BeanFactoryAware
- 调用BeanPostProcessor的初始化前的方法
- 调用初始化方法
- 调用BeanPostProcessor的初始化后的方法,在这里会进行AOP
- 如果当前创建的bean是单例的则会把bean放入单例池
- 使用bean
- Spring容器关闭时调用DisposableBean中destory()方法
10.解释Spring支持的几种bean的作用域
- singleton:默认,每个容器中只有一个bean的实例,单例的模式由BeanFactory自身来维护。该对象的生命周期与Spring ioc的容器一致的(但是在第一次被注入时才会创建)。
- prototype:为每一个bean请求提供一个实例,在每一次注入时都会创建一个新对象
- reques:bean被定义为在每个HTTP请求中创建一个单例对象,也就是说在单个请求中都会复用这一个单例对象,
- session:与request范围类似,确保每个session中有一个Bean的实例,在session过期后,bean会随之失效
- application:bean被定义为在ServletContext的生命周期中复用一个单例对象。
- websocket:bean被定义为websocket的生命周期中复用一个单例对象。
11.Spring框架中的单例Bean是线程安全的吗?
- 默认是Bean是单例模式,不是线程安全的,框架没有对bean进行多线程的封装处理
- 有状态就是数据存储功能
- 无状态就是不会保存数据
12.Spring框架中都用到哪些设计模式
- 简单工厂:由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类
- Spring中的BeanFactory就是简单工厂模式的体现,根据传入一个唯一的标识来获取Bean的对象,但是否是在传入参数后创建还是传入参数前创建这个要根据具体情况来实现。
- 工厂方法:
- 实现了FactoryBean接口的bean是一类叫做factory的bean。其特点是,spring会在使用getBean()调用获得该bean时,会自动调用该Bean的getObject()方法,所以返回的不是factory这个bean,而是这个bean.getObject()方法的返回值
- 单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点
- Spring对单例的实现:spring中的单例模式完成了后半句话,提供了全局访问点BeanFactory,但是没有从构造器级别去控制单例,这是因为spring管理的是任意的java对象
- 适配器模式:
- Spring定义了一个适配接口,使得每一种Controller有一种对应的适配器实现类,让适配器代替controller执行相应的方法,这样在扩展Controller,只需要增加一个适配器类就完成了SpringMVC的扩展。
- 动态代理:
切面在应用运行的时刻被织入,一般情况下,在织入切面时,AOP容器会为目标对象创建动态的创建一个代理对象。SpringAOP就是这种方式织入切面的。
13.mybatis的优缺点
优点:1.与JDBC相比,减少50%以上的代码量,消除JDBC大量冗余的代码
2.sql语句写在XML里,解除sql与代码程序的耦合,便于统一管理
3.能够与Spring很好的集成;
缺点:
1.sql语句依赖于数据库,导致数据库可移植性较差,不能随意更换数据库
2.编写工作量大,尤其当字段多,关联表多的时候,对开发人员编写SQL语句的功底有一定的要求。
一、 java基础
14.一个对象和一个过程的区别
- 面向过程: 面向过程性能比面向对象高,因为调用类时需要实例化,开销比较大,比较消耗资源。当性能为重要考量依据时,如单片机,嵌入式开发的Linux/Unix等,一个整体一个整体过程没有一个对象容易维护、容易扩展
- 面向对象:一个对象有易维护、易扩展的特性,因为对象有继承,多态和封装的特性。洞察力对象性能比过程低
15.Java语言有哪些特点?
- 面向对象(继承,封装,多态)
- 与平台性无关(Java虚拟机实现平台无关性)
- 安全性
- 可靠性
- 支持多线程
- 编译与解析并存
关于JVM JDK和JRE最详细通俗的解答
JVM
java虚拟机(JVM)是运行Java字节码的虚拟机,JVM有针对不同系统的特定实现(windows,Linux,macOS),目的是使用相同的字节码,他们都会给出相同的结果。字节码和不同系统的JVM实现是Java语言“一次编译,随处可以运行”的关键所在。JDK和JRE
JDK是Java Development Kit,他说功能齐全的Java SDK。它拥有JRE所拥有的一切,还有编译器(javac)和工具(javadoc和jdbc),他能够创建和编译程序。JRE是Java运行时环境,它是运行已编译Java程序所需的所有集合,包括Java虚拟机(JVM),Java类库,java命令和其他的一些基础构件。但是,它不能用于创建新程序。
17.Java和C++的区别
- 相同点:都是面向对象的语言,都支持封装,基础,多态
- Java不提供指针来直接访问内存,程序内存更加安全
- Java的类是单继承的,C++支持多重继承;虽然Java的类不可以多重继承,但是Java的接口可以实现多重继承
- 字符型常量和字符串常量的区别?
- 形式上:字符型常量:‘一个字符’,字符串常量:“若干个字符”
- 含义上:字符常量相当于整型值(ASCLL)值,可以进行表达式运算,字符串常量代表一个地址值
- 字符常量占用2个字节,字符串常量占用若干个(char在Java中占两个字节)
19.构造器Constructor是否可被override?
- Constructor不能被override(重写),但是可以overload(重载),所以你可以看到一个类中有多个构造函数的情况。
19.重载和重写的区别
- 重载:就是同样一个方法能够根据输入数据的不同,做出不同的处理
- 重写:当子类继承父类相同方法,输入数据一样,但是做出有别于父类的响应时,你就要覆盖父类的方法。(子类对父类方法的重新改造,外部样子不变,内部逻辑可以改变)
20.实现ioc容器的基本思路
- 主要完成两件事情
- 进行解析
- 实现赋值
- 配置文件的方式
1.解析XML-->Dom4j
2.调用方法,实现注入(反射) - 注解的方式
1.解析类:这个类是归Spring管理,获取到类的注解信息和属性的注解信息(反射)
2.赋值:- 自定义注解 @Controller @Service - 开发注解的解析类
- 配置文件的方式
- 使用方式:
配置方式: <bean> <args></args> </bean> 注解方式: @Controller class UserController{ @Autowrie private IUserService userService; } @Service class UserService1 implements IUserService{}