JAVA面试中常会问到的问题总结

final,finally,finalize的区别

final 修饰符(关键字)如果一个类被申明为final,意味着它不能再派生出新的子类,因此一个类不能既被声明为abstract的,又被声明为final的。将变量和方法声明为final变量的,可以保证它们在使用中不被改变。对于一个final变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象,但是它指向的对象的内容是可变的。被申明为final的方法也同样只能使用不能重写。

finally 在异常处理时提供finally块来执行任何清除操作。如果抛出一个异常,那么相匹配的 catch 子句就会执行,然后控制就会进入finally块(如果有的话)。

finalize 方法名。它是在object类中定义的,因此所有的类都继承了它。这个方法是由垃圾收集器在确定这个对象没有被引用的情况下对这个对象的调用。

Java程序中如何检测死锁(可以使用jconsole工具)

(1)输入 jps 命令,可以看到 java 的进程 id 列表。
(2)再输入 jstack + 进程ID,可以看到所有的线程栈
(3)栈列表最下方,可以看到Found one Java-level deadlock既是发生死锁的线程。

序列化和反序列化的原理

Java序列化是指把Java对象转换为字节序列的过程,而Java反序列化是指把字节序列恢复为Java对象的过程。

为什么需要序列化与反序列化?

Java序列化的好处。其好处一是实现了数据的持久化,通过序列化可以把数据永久地保存到硬盘上(通常存放在文件里),二是,利用序列化实现远程通信,即在网络上传送对象的字节序列。

总的来说可以归结为以下几点:

(1)永久性保存对象,保存对象的字节序列到本地文件或者数据库中;(持久性
(2)通过序列化以字节流的形式使对象在网络中进行传递和接收;(可传输,网络)
(3)通过序列化在进程间传递对象;(可传输,进程)

只有实现了Serializable或Externalizable接口的类的对象才能被序列化,否则抛出异常。
(1)java.io.ObjectOutputStream:表示对象输出流;
它的writeObject(Object obj)方法可以对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中;
(2)java.io.ObjectInputStream:表示对象输入流;
它的readObject()方法源输入流中读取字节序列,再把它们反序列化成为一个对象,并将其返回;

Tomcat集群如何同步

集群的具体同步机制,tomcat共提供了两种。一种是集群增量会话管理器,另一种是集群备份会话管理器
(1)集群增量会话管理器
这是tomcat默认的集群会话管理器,它主要用于集群中各个节点之间会话状态的同步维护。这是一种全节点复制模式,全节点复制指的是集群中一个节点发生改变后会同步到其余全部节点。(那么非全节点复制,顾名思义,指的是集群中一个节点发生改变后,只同步到其余一个或部分节点。)
除了这一特点,集群增量会话管理器还具有只同步会话增量的特点,增量是以一个完整请求为周期,也就是说会在一个请求被响应之前同步到其余节点上。
(2)集群备份会话管理器
全节点复制模式存在的一个很大的问题就是用于备份的网络流量会随着节点数的增加而急速增加,这也就是无法构建较大规模集群的原因。为了解决这个问题,tomcat提出了集群备份会话管理器,每个会话只有一个备份,且备份与原件不会保存在同一个节点上。这样就可构建大规模的集群。

Java后端技术

服务框架:Dubbo,zookeeper,Rest服务
缓存:redis,memcache
消息中间件:ActiveMQ,kafka
负责均衡:Nginx
分布式文件:FastDFS
安全框架:Apache shiro
任务调度:quartz
持久层框架:mybatis
日志:log4j
项目基础搭建:spring,springmvc,
开发工具:eclipse、idea、svn、maven等
服务器:tomcat,jetty,Resin、JBoss、WebSphere、WebLogic等。
Web服务器是运行及发布Web应用的容器,只有将开发的Web项目放置到该容器中,才能使网络中的所有用户通过浏览器进行访问。同时还包括了Java应用服务器。
(1)Tomcat 服务器
  目前最为流行的Tomcat服务器是Apache开源项目中的一个子项目,是一个小型、轻量级的支持JSP和Servlet 技术的Web服务器,也是初学者学习开发JSP应用的首选。
(2)Jetty
Jetty 目前的是一个比较被看好的 Servlet 引擎,它的架构比较简单,也是一个可扩展性和非常灵活的应用服务器。
虽然 Jetty 正常成长为一个优秀的 Servlet 引擎,但是目前的 Tomcat 的地位仍然难以撼动。相比较来看,它们都有各自的优点与缺点。
①从架构上来说,显然 Jetty 比 Tomcat 更加简单。
②Tomcat 在处理少数非常繁忙的连接(连接的生命周期短)上更有优势。而 Jetty 刚好相反,Jetty 可以同时处理大量连接而且可以长时间保持这些连接。
(3)Resin 服务器
  Resin是一个非常流行的支持Servlet和JSP的服务器,速度非常快。Resin本身包含了一个支持HTML的Web服务器,这使它不仅可以显示动态内容,而且显示静态内容的能力也毫不逊色,因此许多网站都是使用Resin服务器构建。
(4)JBoss服务器
  Jboss作为Java EE应用服务器,它不但是Servlet容器,而且是EJB(Enterprise java bean)容器,速度慢一些,不适合开发阶段,可以用于真实运行环境(免费)。从而受到企业级开发人员的欢迎,从而弥补了Tomcat只是一个Servlet容器的缺憾。
(5)WebSphere 服务器
  WebSphere是IBM公司的产品,可进一步细分为 WebSphere Performance Pack、Cache Manager 和WebSphere Application Server等系列,其中WebSphere Application Server 是基于Java 的应用环境,可以运行于 Sun Solaris、Windows NT 等多种操作系统平台,用于建立、部署和管理Internet和Intranet Web应用程序。
(6)WebLogic 服务器
  WebLogic 可进一步细分为 WebLogic Server、WebLogic Enterprise 和 WebLogic Portal 等系列,其中 WebLogic Server 的功能特别强大。WebLogic 支持企业级的、多层次的和完全分布式的Web应用,并且服务器的配置简单、界面友好。对于那些正在寻求能够提供Java平台所拥有的一切应用服务器的用户来说,WebLogic是一个十分理想的选择。不适合开发阶段,太慢了,适合于运行环境(收费)。
apache 和 nginx的比较:
Apache Nginx
发展到现在,模块超多,成熟稳定 设计高度模块化,编写模块相对简单,轻量级,占用更少的内存和资源
 apache 则是阻塞型的,容易出现进程数飙升,从而拒绝服务的现象 处理请求是异步非阻塞的,负载能力比 apache 高很多
处理动态请求有优势 处理静态网页上表现的更好(简单、占资源少)
只是web容器 作为负载均衡服务器,支持 7 层负载均衡

Object类详解

Java.lang.Object 类是所有Java类的最高层次父类,该类中没有定义任何属性,只有几个方法。
(1)hashCode( )方法
   public int hashCode ( ) 返回当前对象的哈希值(哈希码可理解为系统为每一个Java对象自动创建的整型编号,而且此编号唯一),默认实现是将该对象的内部地址转换成一个整数返回。
(2)equals( )方法

(3)toString( )方法

(4)finalize( )方法
 Java运行环境中的垃圾收集器在销毁一个对象之前,会自动判断该对象是否有必要执行 finalize() 方法(当对象没有覆盖finalize()方法或者方法已经被虚拟机执行过则不需要执行),且最多执行一次。如果判定一个对象有必要执行 finalize()方法,那么则会把这个对象放置在F-Queue队列中,稍后 GC 会对 F-Queue 中的对象进行第二次小规模的标记,如果对象要完成自我救赎只需要与引用链上的对象建立关联即可。
(5)clone( )方法
拷贝一个现有的对象,得到一个新对象(和现有对象拥有完全相同的属性值信息),之后二者使用互不干预。
(6)wait( )方法和notify( )方法
主要用于多线程之间的同步。

Maven相关的知识

Maven 依赖原则
(1)路径最短优先原则
(2)pom文件中申明顺序优先
(3)覆写优先(子pom内声明的优先于父pom中的依赖)

解决 jar 冲突
遇到冲突的时候第一步要找到maven加载的是什么版本的jar包,通过们mvn dependency:tree查看依赖树,通过maven的依赖原则来调整依赖在pom文件的申明顺序。

接口和抽象类的区别 

语法层面上的区别
1)抽象类可以含有非抽象方法,而接口中只能存在public abstract 方法;
2)抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final类型的
3)抽象类可以有静态代码块和静态方法,接口中不能含有静态代码块以及静态方法
4)一个类只能继承一个抽象类,而一个类却可以实现多个接口。

设计层面上的区别
1)抽象类体现的是一种继承关系,父类和子类在概念上是一致的,是“is-a”的关系;接口并不要求实现者和接口在概念上是一致的,仅仅是实现了接口的契约而已,是“like-a”的关系。
2)抽象类是自底向上抽象而来的,接口是自顶向下设计出来的。
3)抽象类的设计目的,是代码复用。比如男人、女人可以抽象出人的公有属性和特征;接口是对类的行为进行约束,约束了行为的有无,但是不对行为的实现进行限制,比如吃饭这个动作,但是可以站着吃,坐着吃等。

Java 异常机制

在java中,所有的异常都有一个共同的祖先 Throwable类。Throwable类有两个子类,一个是Error类,一个是Exception。在java中能通过代码处理的我们叫做异常,而我们不能处理的才叫做错误。错误指的是:JVM运行错误,栈空间用尽,类定义错误等等非常严重的问题。Exception主要负责处理类似:空指针、除数为零、数组越界这类问题。
(1)RunTimeException表示那些逻辑性错误,可以避免。
NullPointerException(空指针异常)、IndexOutOfBoundsException(下标越界异常)。在我们编写代码的时候,我们从来不会希望编写出有空指针或者下标越界的代码,因为这是错误的,在java中,这些逻辑上的,因为我们大意而造成的错误都叫做运行时错误。
六个常见的运行时异常:
NullPointerException(空指针异常)
IndexOutOfBoundsException(数组越界异常),ArrayIndexOutOfBoundsException
ClassCastException(类转换异常)
NumberFormatException  数字格式异常
IllegalArgumentException  传递非法参数异常          
ArrayStoreException(数据存储异常,操作数组时类型不一致)
(2)非运行时异常表示有可能发生的异常,我们需要声明。
为了防止代码在运行时出现问题,java强制规定:非运行时异常必须被处理。
运行异常是程序逻辑错误,无法预料,改正就可以,无需抛出或处理。非运行时异常是显然可能存在的错误,我们被强制必须抛出或处理来保证程序的安全性。

comparable接口和comparator的区别

①、Comparable位于包java.lang下,而Comparator位于包java.util下。
②、Comparable接口将比较代码(重写compareTo(T t)方法)嵌入需要进行比较的类的自身代码中,而Comparator接口在一个独立的类中实现比较(重写compare(T t1, T t2)方法)
③、Comparable接口强行对实现它的每个类的对象进行整体排序(自然排序),而Comparator接口不强制进行自然排序,可以指定排序顺序。
④、如果前期类的设计没有考虑到类的Compare问题而没有实现Comparable接口,后期可以通过Comparator接口来实现比较算法进行排序。
其中Comparator接口相当于策略模式的抽象接口,具体的比较器实现类是具体的策略实现,集合操作类相当于Context ,在Context中使用具体策略进行大小比较。

 Arrays.sort() 的实现

基本数据类型数组的操作,使用经过优化的快速排序算法,当数组的规模较小时(jdk1.8中小于47)使用直接插入排序。
引用数据类型数组的排序,在jdk1.7之前使用经过优化的归并排序算法,当数组规模较小时,使用直接插入排序。

现在使用的是TimSort算法,就是找到已经排好序数据的子序列,然后对剩余部分排序,然后合并起来。

Java对象的创建步骤

无限循环 for(;;) 与 while(true) 的区别

在Java中都是优化成 goto 指令没区别;

对于早期的C语言,两种写法性能会不一样,for语句编译器会优化成一条汇编指令,而while判断则编译器会生成好几条汇编指令。

应用程序变慢如何定位?

第一步:登录后台服务器,查看系统资源是否达到上限,例如:CPU、内存、磁盘、I/O、网络带宽等,如果是这些问题,先将这些问题逐一解决:

如果是CPU的问题,则需要查看一下CPU占比比较高的进程,然后使用jstack命令生成进程的堆栈信息,看是否发生频繁Full GC,如果是的话,还需要看一下内存快照,分析一下内存情况(可以使用java自带的或第三方工具);如果是磁盘空间满了,及时清理磁盘;

第二步:检查应用服务器(Jboss/Tomcat)的线程池配置是否合理,看一下请求的排队现象是否严重,如果严重则需要重新设置合理的线程池。同样,检查一下数据库的连接池设置是否合理,增大连接池设置,同时检查一下是否有慢sql,如果有慢sql,则进行优化(优化方案是查看执行计划,设置合理的索引等)。

第三步:查看访问慢的服务的调用链,查看一下调用链中的每一步响应时间是否合理,如果不合理,则联系相关系统的负责人进行排查和解决。

第四步:检查web服务器的请求日志,看一下是否存在Doss攻击,如果有Doss攻击,则将攻击者的IP添加到防火墙的黑名单里。

java8的新特性

1、接口中的默认方法和静态方法
默认方法就像一个普通Java方法,只是方法用default关键字修饰,其目的是为了解决接口的修改与已有的实现不兼容的问题。
静态方法就像一个普通Java静态方法,但方法的权限修饰只能是public或者不写。默认方法和静态方法使Java的功能更加丰富。
2、函数式接口和Lambda表达式
函数式接口是为Java 8中的lambda而设计的,lambda表达式的方法体其实就是函数接口的实现。“lambda表达式”是一段可以传递的代码,因为他可以被执行一次或多次。

3、移除了永久带,取而代之的是metaSpace(元空间)。
4、Stream API
一个Stream表面上与一个集合很类似,允许你改变和获取数据,但实际上却有很大区别:
(1)Stream自己不会存储元素。元素可能被存储在底层的集合中,或者根据需要产生出来。
(2)Stream操作符不会改变源对象。相反,他们返回一个持有新结果的Stream。

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值