java面试
一、springMVC是什么?
springmvc首先是一个MVC框架,通过把model、view、controller分离,把较为复杂的web应用分成逻辑清晰的几部分,是为了简化开发,
减少出错。同时也是为了组内开发人员的配合,是一种分层工作的办法。它拥有spring依赖注入的特性。
二、springMVC的执行流程是什么?
1.用户发布请求到前端控制器DispatchServlet。
2.DispatchServlet收到请求调用HandlerMapping处理器映射器。
3.处理器映射器根据请求的URL找到具体的处理器,生成处理器对象及处理器拦截器,并返回给DispatchServlet。
4.DispatchServlet通过HandlerAdapter处理器适配器调用处理器。
5.执行处理器(Controller层,也叫后端控制器)。
6.Controller执行完成返回数据和视图(ModelAndView)。
7.HandlerAdapter将Controller的执行结果ModelAndView返回给DispatchServlet。
8.DispatchServlet将ModelAndView传给ViewReslover视图解析器。
9.ViewReslover解析器返回具体的View视图。
10.DispatcherServlet对View进行渲染视图
11.DispatcherServlet响应用户,用户看到界面和数据。
三、什么是I/O流
1.i/o流体系:
根据处理数据的不同可以分为:字节流和字符流(字节流分为:InputStream和OutputStream,字符流分为Reader和Writer)
根据数据流向不同可以分为:输入流和输出流
只要是处理纯文本的输出,就优先使用字符流。除此之外使用字节流。
输入流只能进行读操作,输出流只能进行写操作,程序中需要根据待传输数据的不同特性而使用不同的流。
输入字节流InputStream
- InputStream是所有输入字节流的父类
-
ByteArrayInputStream、StringBufferInputStream、FileInputStream是三种基本的介质流,分别从byte数组、stringbuffer和本地文件中读取数据。
输出字节流OutputStream
- OutputStream是所有输出字节流的父类
ByteArrayOutputStream
、FileOutputStream
是两种基本的介质流,它们分别向Byte 数组
、和本地文件
中写入数据。
四、进程和线程的区别
1、进程:保存在硬盘上的软件运行以后,会在内存空间中形成一个独立的内存体,这个内存体有自己独立的地址空间,有自己的堆,上级挂靠单位是操作系统。操作系统会以进程为单位,分配系统资源(CPU时间片、内存等资源),进程是资源分配的最小单位。
2、线程:有时候被称之为轻量级进程,是操作系统调度(CPU调度)执行的最小单位。
总结:一个进程中可以有多个线程,最少为一个线程。线程依赖进程。
五、SQL优化
- 合理使用索引。
- 避免select * 这种写法,应该查询具体的表。
- 尽量减少子查询,使用关联查询(left join,right join,inner join)代替。
- 减少使用in或者not in,使用exists,not exists或者关联查询语句代替。
- 对于多张大数据量表(几百条数据就算大)的表join,要先分页再join,否则逻辑度会很高,性能很差。
- 一张表的索引最好不要超过6个,如果索引过多,就要考虑那些不常使用到的列上建的索引是否有必要。
6、深入理解 JVM 垃圾回收机制及其实现原理
在java世界中,几乎所有的对象实例都在堆中存放,所以垃圾回收主要是针对堆进行的。在jvm的眼中,垃圾就是指在堆中存在,并且已经不会被任何途径所使用的对象。
如何确定一个对象是存活还是死亡?这就需要使用垃圾判断算法,其中主要包括引用计数法和可达性分析法。
引用计数法:
在这种算法中,假设堆中每个对象(不是引用)都有一个引用计数器。当一个对象被创建并且初始化赋值后,该对象的计数器的值就设置为 1,每当有一个地方引用它时,计数器的值就加 1,例如将对象 b 赋值给对象 a,那么 b 被引用,则将 b 引用对象的计数器累加 1。反之,当引用失效时,例如一个对象的某个引用超过了生命周期(出作用域后)或者被设置为一个新值时,则之前被引用的对象的计数器的值就减 1。而那些引用计数为 0 的对象,就可以称之为垃圾,可以被收集。特别地,当一个对象被当做垃圾收集时,它引用的任何对象的计数器的值都减 1。
- 优点:引用计数法实现起来比较简单,对程序不被长时间打断的实时环境比较有利。
- 缺点:需要额外的空间来存储计数器,难以检测出对象之间的循环引用。
可达性分析法:
可达性分析法也被称之为根搜索法,可达性是指,如果一个对象会被至少一个在程序中的变量通过直接或间接的方式被其他可达的对象引用,则称该对象就是可达的。
更准确的说,一个对象只有满足下述两个条件之一,就会被判断为可达的:
- 对象是属于根集中的对象
- 对象被一个可达的对象引用
在这里,我们引出了一个专有名词,即根集,其是指正在执行的 Java 程序可以访问的引用变量(注意,不是对象)的集合,程序可以使用引用变量访问对象的属性和调用对象的方法。
在 JVM 中,会将以下对象标记为根集中的对象,具体包括:
- 虚拟机栈(栈帧中的本地变量表)中引用的对象
- 方法区中的常量引用的对象
- 方法区中的类静态属性引用的对象
- 本地方法栈中 JNI(Native 方法)的引用对象
- 活跃线程(已启动且未停止的 Java 线程)
根集中的对象称之为GC Roots
,也就是根对象。可达性分析法的基本思路是:将一系列的根对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,如果一个对象到根对象没有任何引用链相连,那么这个对象就不是可达的,也称之为不可达对象。
编程题:
给定一句话:i am a student , i like study.将这句话中的标点符号去掉,然后再反转为:study like i , student a am i .
package com.company; import com.sun.deploy.util.StringUtils; import java.util.*; public class Math { public static void main(String[] args) { String s = "i am a student ,i like study."; //去掉字符串中的标点符号 String ss = s.replaceAll("\\p{P}",""); System.out.println("去掉标点符号之后的数组===>"+ss); //以空格切割字符串,并将字符串放在数组中 String[] str = ss.split(" "); //遍历数组 // for (int i = 0; i < str.length; i++) { // System.out.print("查看切割后的数组===>"+str[i]); // } //将字符串转变为list集合 List<String> list = Arrays.asList(str); System.out.println("list集合===>"+list); //将list集合进行反转 Collections.reverse(list); //将集合转变为字符串 String strings = StringUtils.join(list,","); //去掉字符串中的符号 String s1 = strings.replaceAll("\\p{P}", " "); System.out.println(s1); } }