面试题2

1. int 与Integer区别

  1. 无论如何,Integer与new Integer不会相等。不会经历拆箱过程,i3的引用指向堆,而i4指向专门存放他的内存(常量池),他们的内存地址不一样,所以为false
  2. 两个都是非new出来的Integer,如果数在-128到127之间,则是true,否则为false
    java在编译Integer i2 = 128的时候,被翻译成-> Integer i2 = Integer.valueOf(128);而valueOf()函数会对-128到127之间的数进行缓存
  3. 两个都是new出来的,都为false
  4. int和integer(无论new否)比,都为true,因为会把Integer自动拆箱为int再去比
    转载:https://www.cnblogs.com/liuling/archive/2013/05/05/intAndInteger.html
    int占用内存比integer要小,integer是对象类型,需要储存对象元数

JVM JRE JDK JIT之间的区别

2.java虚拟机(JVM)
使用java编程语言的主要优势就是平台的独立性。你曾经想知道过java怎么实现平台的独立性吗?对,就是虚拟机,它抽象化了硬件设备,开发者和他们的程序的得以操作系统。虚拟机的职责就是处理和操作系统的交流。java不同的接口规范对任何平台都有良好的支持,因为jvm很好的实现了每个平台的规范。jvm可以理解伪代码字节码,在用户和操作系统之间建立了一层枢纽。

java运行时环境(JRE)
java运行时环境是JVM的一个超集。JVM对于一个平台或者操作系统是明确的,而JRE确实一个一般的概念,他代表了完整的运行时环境。我们在jre文件夹中看到的所有的jar文件和可执行文件都会变成运行时的一部分。事实上,运行时JRE变成了JVM。所以对于一般情况时候使用JRE,对于明确的操作系统来说使用JVM。当你下载了JRE的时候,也就自动下载了JVM。

java开发工具箱(JDK)
java开发工具箱指的是编写一个java应用所需要的所有jar文件和可执行文件。事实上,JRE是JKD的一部分。如果你下载了JDK,你会看到一个名叫JRE的文件夹在里面。JDK中要被牢记的jar文件就是tools.jar,它包含了用于执行java文档的类还有用于类签名的jar包。

即时编译器(JIT)
即时编译器是种特殊的编译器,它通过有效的把字节码变成机器码来提高JVM的效率。JIT这种功效很特殊,因为他把检测到的相似的字节码编译成单一运行的机器码,从而节省了CPU的使用。这和其他的字节码编译器不同,因为他是运行时(第一类执行的编译?)the firs of its kind to perform the compilation(从字节码到机器码)而不是在程序运行之前。正是因为这些,动态编译这个词汇才和JIT有那么紧密的关系。
转载:https://blog.csdn.net/orangleliu/article/details/38309407

3.抽象类和接口区别

  1. 抽象类中可以包含非抽象的普通方法,而接口中所有的方法必须是抽象的,不能有非抽象的普通方法。
  2. 一个类可以实现多个接口,但只能继承一个抽象类。
  3. 抽象类里可以有构造方法,而接口内不能有构造方法。
  4. 抽象类中的抽象方法的访问类型可以是public ,protected和默认类型,但接口中的抽象方法只能是public类型的,并且默认即为public abstract类型。
  5. 抽象类中可以包含静态方法,接口内不能包含静态方法。
  6. 抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但接口中定义的变量只能是public static final类型,并且默认为public static final类型。
  7. 抽象类中可以有普通成员变量,而接口中不能有普通成员变量。

4.用SQL查找表中多余的重复记录,重复记录根据单个字段(ID)来判断

_20180506110351.png

4.对线程的理解

1).线程是进程的子集,一个进程可有多个线程
2).是cup执行的基本单位,拥有代理的寄存器和栈
3).同一进程下,线程共享地址和内存空间
4).线程的状态:新建,就绪(等待cup使用权),运行,堵塞(暂时放弃cup使用权,等待资源)

5.SpringMVC执行流程

  1. 客户端发起请求到DispatcherServlet(前端控制器)
  2. 前端控制器请求HandlerMapping(处理器映射器)查找 Handle根据xml配置、注解进行查找
  3. HandlerMapping(处理器映射器)向DispatcherServlet(前端控器)返回Handler
  4. DispatcherServlet(前端控制器)调用HandlerAdapter(处理器适配器)去执行Handler
  5. HandlerAdapter(处理器适配器)去执行Handler
  6. Handler执行完成给HandlerAdapter(处理器适配器)返回ModelAndView
  7. HandlerAdapter(处理器适配器)向前端控制器返ModelAndView
  8. 前端控制器请求ResolverView(视图解析器)去进行视图解析根据逻辑视图名解析成真正的视图(jsp)
  9. ResolverView(视图解析器)向DispatcherServlet(前端控制器)返回View
  10. DispatcherServlet(前端控制器)进行视图渲染
    视图渲染将模型数据(在ModelAndView对象中)填充到request域
    最后DispatcherServlet(前端控制器)向用户响应(response)结果

6.struts2执行流程

  1. 用户发送请求;
  2. 这个请求经过一系列的过滤器(Filter)(这些过滤器中有一个叫做ActionContextCleanUp的可选过滤器,这个过滤器对于Struts2和其他框架的集成很有帮助,例如:SiteMesh Plugin)
  3. 接着FilterDispatcher被调用,FilterDispatcher询问ActionMapper来决定这个请求是否需要调用某个Action ;
  4. 如果需要处理,ActionMapper会通知FilterDispatcher,需要处理这个请求,FilterDispatcher会停止过滤器链以后的部分,(这也就是为什么,FilterDispatcher应该出现在过滤器链的最后的原因)。FilterDispatcher把请求的处理交给ActionProxy ;
  5. ActionProxy通过Configuration Manager询问框架的配置文件struts.xml,找到需要调用的Action类 。(在服务器启动的时候,ConfigurationManager就会把struts.xml中的所有信息读到内存里,并缓存,当ActionProxy带着URL向他询问要运行哪个Action的时候,就可以直接匹配、查找并回答了)
  6. ActionProxy创建一个ActionInvocation的实例。
  7. ActionInvocation实例使用命名模式来调用,在调用Action的过程前后,涉及到一系列相关拦截器(Intercepter)的调用。
  8. 一旦Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果。返回结果通常是(但不总是,也可 能是另外的一个Action链)一个需要被表示的JSP或者FreeMarker的模版。在表示的过程中可以使用Struts2 框架中继承的标签。
  9. 最后,ActionInvocation对象倒序执行拦截器。
    10.ActionInvocation对象执行完毕后,响应用户。

7.如何解决高并发

  1. 尽量使用缓存技术来做。用户缓存、页面缓存等一切缓存,使用特定的机制进行刷新。利用消耗内存空间来换取用户的效率。同时减少数据库的访问次数。
  2. 把数据库的查询语句进行优化,一般复杂的SQL语句就不要使用ORM框架自带的做法来写,采用自己来写SQL,例如hibernate的hql中的复杂语句,就会很耗时
  3. 优化数据库表的结构,在关键字、主键、访问率极高的字段中加入索引。但尽量只是在数字类型上面加。因为使用 字段 is null的时候,索引的效果会失效
  4. 报表统计的模块,尽量采用定时任务执行,如果非得要实时进行刷新,那么可以采用缓存来做数据。
  5. 可以使用静态页面的地方,使用静态页面,减少页面解析时间,同时由于页面中有许多图片的这种,可以考虑一下把图片做成一个服务器,这样可以减少业务服务器的压力。
  6. 使用集群的方式来解决,单台服务器性能的问题。
  7. 把项目,拆分成为多个应用小型服务器形式,来进行分布式部署。采用数据同步机制(可以使用数据库同步形式来做)达到数据一致性。
  8. 使用负载均衡模式,来让每一个服务器资源进行合理的利用。
  9. 缓存机制中,可以使用redis来做内存数据库缓存起来。也可以使用镜像分担,这样可以让两台服务器进行访问,提高服务器的访问量

8.数据库优化

  1. 避免在WHERE子句中使用in,not in,or 或者having。
    可以使用 exist 和not exist代替 in和not in。
    可以使用表链接代替 exist。
    Having可以用where代替,如果无法代替可以分两步处理。
    例子
    SELECT * FROM ORDERS WHERE CUSTOMER_NAME NOT IN
    (SELECT CUSTOMER_NAME FROM CUSTOMER)
    优化:
    SELECT * FROM ORDERS WHERE CUSTOMER_NAME not exist
    (SELECT CUSTOMER_NAME FROM CUSTOMER)
  1. 不要在建立的索引的数据列上进行下列操作:

(1)避免对索引字段进行计算操作
(2)避免在索引字段上使用not,<>,!=
(3)避免在索引列上使用IS NULL和IS NOT NULL
(4)避免在索引列上出现数据类型转换
(5)避免在索引字段上使用函数

你可能感兴趣的:(面试题2)