Java2019精选面试题,来自阿里8年程序员总结,步入年薪50W

最新Java面试题大全,最近面试官都会问的面试题,基础中的基础

1

数据类型:Java中的基本数据类型只有8个:byte(8)、short(16)、int(32)、long(64)、float(32)、double(64)、

char(16,2字节,可放一个中文汉字)、boolean(64);除了基本类型(primitive type)和枚举类型

(enumeration type),剩下的都是引用类型(reference type)。

注:eg1: float f=3.4,错误。双精度转单精度,下转型,需强转。float f =(float)3.4; 或者写成float f =3.4F;

eg2: short s1 = 1; s1 = s1 + 1。错误,理由同上。short s1 = 1; s1 += 1。正确,因为s1+= 1;

相当于s1 = (short)(s1 + 1),其中有隐含的强制类型转换。

eg3: long w=12345678901。错误。超出了int类型的取值范围。

eg4: Integer f1 = 100, f2 = 100, f3 = 150, f4 = 150;

System.out.println(f1 == f2);

System.out.println(f3 == f4);

注意上面的变量都是Integer引用,查阅Integer的内部类IntegerCache可知,如果整型字面量的值在-128

到127之间,那么不会new新的Integer对象,而是直接引用常量池中的Integer对象,所以上面的面试题中

f1==f2的结果是true,而f3==f4的结果是false。

2

goto和const都是保留字

3

Math.round(11.5)的返回值是12,Math.round(-11.5)的返回值是-11。四舍五入的原理是在参数上加0.5然后

进行下取整。

4

用最有效率的方法计算2乘以8:2 << 3(左移3位相当于乘以2的3次方,右移3位相当于除以2的3次方)

5

(x.equals(y) == true),但却可有不同的hash code? 错误。如果两个对象相同,hashcode值一定要相同。

6

String 类是final类,不可以被继承。所有的包装类都是final修饰的类,都不能被继承。

7

Java中非静态内部类对象的创建要依赖其外部类对象(this.new 内部类 ; new 外部类.new 内部类).

8

Java 中会存在内存泄漏吗?

理论上Java因为有垃圾回收机制(GC)不会存在内存泄露问题。开发中,可能会存在无用但可达的对象,这些

对象不能被GC回收,因此也会导致内存泄露的发生。例如hibernate的Session(一级缓存)中的对象属于持久

态,垃圾回收器是不会回收这些对象的,然而这些对象中可能存在无用的垃圾对象,如果不及时关闭(close)

或清空(flush)一级缓存就可能导致内存泄露。

9

EJB:包括Session Bean、Entity Bean、Message Driven Bean,基于JNDI、RMI(远程方法调用,详解:http://blog.csdn.net/a19881029/article/details/946566)、JAT(Java基础框架)等技术实现。

SessionBean和EntityBean的区别:对于客户机,SessionBean是一种非持久性对象,它实现某些在服务器上

运行的业务逻辑,可细分为Stateful Session Bean 与 Stateless Session Bean ; EntityBean是一种持久性对象,

它代表一个存储在持久性存储器中的实体的对象视图,或是一个由现有企业应用程序实现的实体。

StatefulBean和StatelessBean的区别:Stateful Session Bean 可以记录呼叫者的状态,每个使用者对应一个

实体,消耗 J2EE Server 较多的内存,可以维持使用者的状态;Stateless Session Bean不负责记录使用者状

态,可能数个使用者对应一个 Bean 的 Instance 在执行。

EJB与JAVA BEAN的区别:Java Bean 是可复用的组件,被容器所创建,Java Bean应具有一个无参的

构造器,还要实现Serializable接口用于实现Bean的持久性,不能被跨进程访问的;Enterprise Java Bean相当

于分布式组件。基于Java的远程方法调用(RMI)技术的,EJB容器是EJB组件的代理, EJB组件由容器所

创建和管理。客户通过容器来访问真正的EJB组件。

10

HashMap和Hashtable的区别:两者皆采用哈希算法。HashMap允许空键值,非线程安全。HashMap把

Hashtable的contains方法去掉了,改成containsvalue和containsKey;Hashtable不允许空键值,线程安全。

11

sleep() 和 wait() 有什么区别:sleep()是Thread的方法,导致线程暂停执行指定时间,给执行机会给其他线程,

监控状态依然保持。调用sleep不会释放对象锁。

wait()是Object的方法,线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法

(或notifyAll)后本线程才进入对象锁定池,准备获得对象锁进入运行状态。

12

Heap [堆]和stack [栈]有什么区别:堆是栈的一个组成元素。栈是一种线形集合,其添加和删除元素的操作应

在同一段完成。栈按照后进先出的方式进行处理。

13.

forward 和redirect的区别:forward是服务器请求资源,服务器直接访问目标地址的URL。浏览器不知道发送

内容从哪来,地址栏不变 ;

redirect就是服务端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址。地址栏改变。

14

JSP中动态INCLUDE与静态INCLUDE的区别:动态INCLUDE用jsp:include动作实现 它总是会检查所含文件中

的变化,适合用于包含动态页面,并且可以带参数;

静态INCLUDE用include伪码实现,定不会检查所含文件的变化,适用于包含静态页面

15

什么时候用assert (断言):常用的调试方式。对程序的一条语句进行检查,保证其为true。若为false,说明程序

处于不正确状态,系统将给出警告或退出。assertion检查通常在开发和测试时开启。为了提高性能, 在软件

发布后,assertion检查通常是关闭的。

16

GC是什么? 为什么要有GC? GC可以自动监测对象是否超过作用域从而达到自动回收内存的目的,Java语言

没有提供释放已分配内存的显示操作方法。对内存堆中已经死亡的或者长时间没有使用的对象进行清除和回收。

调用下面的方法之一:System.gc() 或Runtime.getRuntime().gc() ,但JVM可以屏蔽掉显示的垃圾回收调用。

17

数据连接池的工作机制:J2EE 服务器启动时会建立一定数量的连接置于连接池中,需要时直接从连接池获取,

使用结束时归还连接池而不必关闭连接,从而避免频繁创建和释放连接所造成的开销。浪费了空间存储连接,

但节省了创建和释放连接的时间

为什么需要连接池: 由于创建连接和释放连接都有很大的开销(尤其是数据库服务器不在本地时,每次建立

连接都需要进行TCP的三次握手,释放连接需要进行TCP四次握手,造成的开销是不可忽视的)

18

SpringMVC执行原理:

1.用户向前端控制器(DispatherServlet)发起请求

2.前端控制器(DispatherServlet)解析URL,请求处理映射器(HandlerMapping)。

3.处理映射器(HandlerMapping)返回Handler配置的所有相关对象。

4.前端控制器(DispatherServlet)根据获得的Handler,选择一个合适的HandlerAdapter。

(附注:如果成功获得HandlerAdapter后,此时将开始执行拦截器的preHandler(...)方法)。

5.开始执行Handler(Controller),业务逻辑处理。

6.Handler处理完业务逻辑,返回ModelAndView对象给前端控制器(DispatherServlet)。

7.视图解析器(ViewResolver)返回真正的视图对象(View),前端控制器根据模型数据和视图对象,进行

视图渲染。

8.最后将渲染的试图以(html/json/xml)的形式响应用户。

19

Struts2执行原理:

1.客户端初始化一个指向Servlet容器的请求(HttpServletRequest请求)

2.请求经过一系列过滤器(最先执行ActionContextCleanUp、最后执行FilterDispatcher)

3.FilterDispatcher询问ActionMapper是否需要调用某个Action来处理这个(HttpServlet Request)请求,如果

ActionMapper决定需要调用某个Action,FilterDispatcher则把请求的处理交给ActionProxy。

4.ActionProxy通过Configuration Manager(struts.xml)询问框架的配置文件,找到需要调用的Action类。

5.ActionProxy创建一个ActionInvocation实例。ActionInvocation会根据配置加载相关的拦截器(Interceptor),并

通过代理模式调用Action。

6.Action执行完毕后,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果result。

20

日期和时间:

1.获得年月日、小时分钟秒

Calendar cal = Calendar.getInstance();

System.out.println(cal.get(Calendar.YEAR));

System.out.println(cal.get(Calendar.MONTH)); // 0 - 11

System.out.println(cal.get(Calendar.DATE));

System.out.println(cal.get(Calendar.HOUR_OF_DAY));

System.out.println(cal.get(Calendar.MINUTE));

System.out.println(cal.get(Calendar.SECOND));

2.获得该毫秒数

一下三种方式均可获得毫秒数 :

Calendar.getInstance().getTimeInMillis();

System.currentTimeMillis();

Clock.systemDefaultZone().millis();

3.打印昨天的当前时刻

Calendar cal = Calendar.getInstance();

cal.add(Calendar.DATE, -1);

System.out.println(cal.getTime());

21

递归排序 及 实现字符串的反转:

分治法排序(二分法排序):

static void quick_sort(int s[], int l, int r){

if (l < r){

//Swap(s[l], s[(l + r) / 2]); //将中间的这个数和第一个数交换 参见注1

int i = l, j = r, x = s[l];

while (i < j){

while(i < j && s[j] >= x) // 从右向左找第一个小于x的数

j--;

if(i < j)

s[i++] = s[j];

while(i < j && s[i] < x) // 从左向右找第一个大于等于x的数

i++;

if(i < j)

s[j--] = s[i];

}

s[i] = x;

quick_sort(s, l, i - 1); // 递归调用

quick_sort(s, i + 1, r);

}

}

字符串反转(反转的字符串不能包含特殊字符):

public static String result(String originStr){

for (int i = 0; i < originStr.length()-1; i++) {

originStr=reverse(originStr.substring(1)) + originStr.charAt(0);

}

return originStr;

}

22

怎样将GB2312编码的字符串转换为ISO-8859-1编码的字符串?

String s1 = "你好";

String s2 = new String(s1.getBytes("GB2312"), "ISO-8859-1");

23

如何实现对象的克隆?

有两种方式: 1)实现Cloneable接口,并重写Object类中的clone()函数;

2) 实现Serializable接口,通过对象序列化和反序列化事实现深度克隆。代码如下:

public static <T> T clone(T obj) throws Exception {

ByteArrayOutputStream bout = new ByteArrayOutputStream();

ObjectOutputStream oos = new ObjectOutputStream(bout);

oos.writeObject(obj);

ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());

ObjectInputStream ois = new ObjectInputStream(bin);

return (T) ois.readObject();

// 说明:调用ByteArrayInputStream或ByteArrayOutputStream对象的close方法没有任何意义

// 这两个基于内存的流只要垃圾回收器清理对象就能够释放资源,这一点不同于对外部资源(如文件流)的释放

}

24对ajax的理解:Ajax为异步请求,即局部刷新技术。不需要点击就可以触发事件,可以大量发送ajax请求,

提高前后端交互效率

25

什么是进程,什么是线程?为什么需要多线程编程?

进程: 具有一定独立功能的程序关于某个数据集合上的一次运行活动,是操作系统进行资源分配和调度的

一个独立单位;

线程: 进程的一个实体,是CPU调度和分 派的基本单位,是比进程更小的能独立运行的基本单位。

多线程优缺点:

1.线程的划分尺度小于进程,这使得多线程程序的并发性高;

2.进程在执行时通常拥有独立的内存单元,而线程之间可以共享内存。

3.高性能和用户体验

4.多线程的程序对于其他程序是不友好的,因为它占用了更多的CPU资源

多线程:a)一个进程是一个独立的运行环境,线程是进程的最小单位

b)在多线程程序中,多线程并发可以提高程序的效率,cpu不会因为某个线程等待资源而进入空闲状态,它会

把资源让给其他的线程。

c)用户线程:开发程序是创建的线程;守护线程:系统线程,如JVM虚拟中的GC

e)死锁:至少两个以上线程争取两个以上cpu资源,避免死锁就避免使用嵌套锁,只需要在他们需要同步的

地方加锁和避免无限等待

synchronized 和java.util.concurrent.locks.Lock的异同:

相同点:Lock 能完成synchronized所实现的所有功能

不同点:Lock有更精确的线程语义和更好的性能,且不强制性的要求一定要获得锁。

synchronized会自动释放锁;Lock需要手动释放,并且最好在finally 块中释放(这是释放外部资源的

最好的地方)。

26

单例模式:

饿汉式单例

public class Singleton {

private Singleton(){}

private static Singleton instance = new Singleton();

public static Singleton getInstance(){ return instance; }

}

懒汉式单例

public class Singleton {

private Singleton() {}

private static Singleton instance = null;

public static synchronized Singleton getInstance(){

if (instance == null)

instance = new Singleton();

return instance;

}

}

27

Http的通信机制: 在1.1版本后一次连接中,可处理多个请求,并且多个请求可以重叠进行,不需要等待一个

请求结束后再发送下一个请求。

HTTP连接是一种“短连接”。在请求时需要先建立连接,客户端向服务器发出请求后,服务器端才能回复数据。

若服务器端与客户端建立的是Socket连接,则服务器可以直接将数据传送给客户端;

若建立的是Http连接,服务器需要等客户端发送一次请求后才能将数据传回给客户端。

28

Socket(套接字)的通信机制:Socket是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元,是网络

通信过程中端点的抽象表示。

网络通信必须包含五种信息:连接使用的协议、本地主机IP地址、本地进程的协议端口、远地主机的IP地址、

远地进程的协议端口。

建立Socket连接至少需要一对套接字,分别运行于客户端(ClientSocket)、服务器端(ServerSocket)

套接字之间连接过程分三步:服务器监听、客户端请求、连接确认

29

Hibernate核心: ROM对象关系映射机制。将表之间的操作映射为对象之间的操作。即从数据库中提取的信息会

自动按照你设置的映射要求封装成特定的对象。使得对对象的修改对应数据行的修改。

Hibernate的延迟加载机制:使用虚拟基代理机制实现延迟加载,在数据使用是加载出来。返回的是实体对象的代理。

用户调用getter()s时,就会去数据库加载数据。

Hibernate中Session的load和get方法的区别:

对比条件 get()load()

没有找到符合条件的数据时返回null抛出异常

返回的数据实体类对象实体类对象的代理

Hibernate 3之前只在一级缓存中进行数据查找。如果没有找到对应的数据则越过二级缓存,直接发出SQL语句完成数据读取

Hibernate 3及后续版本不再是对二级缓存只写不读,也可访问二级缓存

Hibernate优化策略:制定合理的缓存策略及Session管理机制、尽量使用延迟加载、

使用基于version的乐观锁代替悲观锁、开启hibernate.show_sql选项查看生成的SQL,完成时关闭。

乐观锁:在不锁定表的情况下,利用业务的控制来解决并发问题。即保证数据的可读性,又保证保存数据的排他性,

保证性能的同时解决了并发带来的脏读数据问题。

30

数据库优化策略:

1)选择存储范围较小的字段,尽可能的设为notnull.

2) 使用关联查询(eg:left join on)代替子查询

3)使用union联合查询时,手动创建临时表

4) 开启事物,当数据库执行多条语句出现错误时,事物会回滚,可以维护数据库的完整性

5) 使用外键保证数据的关联性

6)使用索引索引是提高数据库性能的常用方法。对于max,min,order by查询时,效果更明显

7)sql优化,简练

31

使用流实现文件拷贝:代码如下,两种方案供您参考。

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

import java.nio.ByteBuffer;

import java.nio.channels.FileChannel;

public final class MyUtil {

private MyUtil() {}

public static void fileCopy(String source, String target) throws IOException {

try (InputStream in = new FileInputStream(source)) {

try (OutputStream out = new FileOutputStream(target)) {

byte[] buffer = new byte[4096];

int bytesToRead;

while((bytesToRead = in.read(buffer)) != -1) {

out.write(buffer, 0, bytesToRead);

}

}

}

}

public static void fileCopyNIO(String source, String target) throws IOException {

try (FileInputStream in = new FileInputStream(source)) {

try (FileOutputStream out = new FileOutputStream(target)) {

FileChannel inChannel = in.getChannel();

FileChannel outChannel = out.getChannel();

ByteBuffer buffer = ByteBuffer.allocate(4096);

while(inChannel.read(buffer) != -1) {

buffer.flip();

outChannel.write(buffer);

buffer.clear();

}

}

}

}

32

Webservice与RPC的区别:

RPC: 1)RPC就是从一台机器(客户端)上通过参数传递的方式调用另一台机器(服务器)上的一个函数

或方法(可以统称为服务)并得到返回的结果。

2)RPC 会隐藏底层的通讯细节(不需要直接处理Socket通讯或Http通讯)

3)RPC 是一个请求响应模型。客户端发起请求,服务器返回响应(类似于Http的工作方式)

4)RPC 在使用形式上像调用本地函数(或方法)一样去调用远程的函数(或方法)

WebService: http传输信道、XML的数据格式、SOAP封装格式、WSDL的描述方式、

UDDI,是一种目录服务,企业可以使用它对WebService进行注册和搜索

RMI与RPC 的区别:

1)RPC 不支持对象,采用http协议

2)RMI支持传输对象,采用tcp/ip协议

3)RMI只限于Java语言,RPC跨语言

Webservice与RMI:

RMI是在tcp协议上传递可序列化的java对象,只能用在java虚拟机上,绑定语言,客户端和服务端都必须是java

webservice没有这个限制,webservice是在http协议上传递xml文本文件,与语言和平台无关

33

从一张有500万数据的表中,的第400万条数据,取后面10条数据进行分页:

可以先倒叙取前100万条,再倒叙取前十条数据。

Select (Select * from 表名 where 条件 order by 字段 desc limit 0,1000000) from 表名 where 条件 order by 字段 desc limit 0,10;

34

MySQL 的基本数据类型:

整形:TINYINT、SMALLINT、MEDIUMINT、INT(INTEGER)、BIGINT

浮点型与定点数据类型:FLOAT、DOUBLE、DECIMAL

日期时间:DATETIME、DATE、TIMESTAMP、TIME、YEAR

字符串类型:CHAR、VARCHAR、BINARY、VARBINARY、BLOB、TEXT、ENUM、SET

35

HashMap的初始长度为16,长度必须是 2的幂

因为: index = HashCode(Key) & (length - 1), 如果 length是 2的 幂的话,则 length - 1就是 全是 1的二进制数,比如

16 - 1 = 1111,这样相当于是 坐落在长度为 length的hashMap上的位置只和 HashCode的后四位有关,这只要给出的

HashCode算法本身分布均匀,算出的index就是分布均匀的。。

36

SpringMvc的核心入口类:DispatchServlet;

Struts1的核心入口类:ActionServlet;

Struts2的核心入口类:StrutsPrepareAndExecuteFilter

猜你喜欢

转载自blog.csdn.net/weixin_44941193/article/details/89843694