1.什么是Java虚拟机?为什么Java被称作是“平台无关的编程语言”?
java虚拟机是一个可以执行java字节码的虚拟机进程。java源文件被编译成能被java虚拟机执行的字节码文件。Java被设计成允许应用程序可以运行在任意的平台,而不需要程序员为每一个平台重写或者重新编译。java虚拟机让这个变为可能,因为它知道底层硬件平台的指令长度和其它特性。
java的跨平台不是java源程序的跨平台 ,如果是这样,那么所以语言都是跨平台的, java源程序先经过javac编译器编译成二进制的.class字节码文件(java的跨平台指的就是.class字节码文件的跨平台,.class字节码文件是与平台无关的),.class文件再运行在jvm上,java解释器(jvm的一部分)会将其解释成对应平台的机器码执行,所以java所谓的跨平台就是在不同平台上安装了不同的jvm,而在不同平台上生成的.class文件都是一样的,而.class文件再由对应平台的jvm解释成对应平台的机器码执行。
2.JDK和JRE的区别是什么?
java运行时环境(JRE),它包括java虚拟机、java核心类库和支持文件,但不包含开发工具(JDK)---编译器、调试器和其他工具
java开发工具包(JDK)是完整的java软件开发包,包含了JRE,编译器和其他的工具(比如:javaDoc,java调试器),可以让开发者开发、编译。执行java应用程序。
3.”static”关键字是什么意思?Java中是否可以覆盖(override)一个private或者是static的方法?
“static”关键字表明一个成员变量或者是成员方法可以在没有所属的类的实例变量的情况下被访问。Java中static方法不能被覆盖,因为方法覆盖是基于运行时动态绑定的,而static方法是编译时静态绑定的。static方法跟类的任何实例都不相关,所以概念上不适用。java中也不可以覆盖private的方法,因为private修饰的变量和方法只能在当前类中使用,如果是其他的类继承当前类是不能访问到private变量或方法的,当然也不能覆盖。
Static表示静态的意思,可用于修饰成员变量和成员函数,被静态修饰的成员函数只能访问静态成员,不可以访问非静态成员。静态是随着类的加载而加载的,因此可以直接用类进行访问。 重写是子类中的方法和子类继承的父类中的方法一样(函数名,参数,参数类型,反回值类型),但是子类中的访问权限要不低于父类中的访问权限。重写的前提是必须要继承,private修饰不支持继承,因此被私有的方法不可以被重写。静态方法形式上可以被重写,即子类中可以重写父类中静态的方法。但是实际上从内存的角度上静态方法不可以被重写。
首先是static关键字,static原意是“静态的”。
①static可以修饰内部类,但是不能修饰普通类。静态内部类的话可以直接调用静态构造器(不用对象)。
②static修饰方法,static方法就是没有this的方法。在static方法内部不能调用非静态方法,反过来是可以的。而且可以在没有创建任何对象的前提下,仅仅通过类本身来调用static方法。这实际上正是static方法的主要用途。方便在没有创建对象的情况下来进行调用(方法/变量)。
最常见的static方法就是main,因为所有对象都是在该方法里面实例化的,而main是程序入口,所以要通过类名来调用。还有就是main中需要经常访问随类加载的成员变量。
③static修饰变量,就变成了静态变量,随类加载一次,可以被多个对象共享。
④static修饰代码块,形成静态代码块,用来优化程序性能,将需要加载一次的代码设置成随类加载,静态代码块可以有多个。
Java中static方法不能被覆盖,因为方法覆盖是基于运行时动态绑定的,而static方法是编译时静态绑定的。
还有私有的方法不能被继承,子类就没有访问权限,肯定也是不能别覆盖的。
4.是否可以在static环境中访问非static变量?
static变量在Java中是属于类的,它在所有的实例中的值是一样的。当类被Java虚拟机载入的时候,会对static变量进行初始化。如果你的代码尝试不用实例来访问非static的变量,编译器会报错,因为这些变量还没有被创建出来,还没有跟任何实例关联上。
因为静态的成员属于类,随着类的加载而加载到静态方法区内存,当类加载时,此时不一定有实例创建,没有实例,就不可以访问非静态的成员。
在static环静中,不可以访问非static。因为静态的成员属于类,随着类的加载而加载到静态方法区内存,当类加载时,此时不一定有实例创建,没有实例,就不可以访问非静态的成员。类的加载先于实例的创建,因此静态环境中,不可以访问非静态!
5.Java支持的数据类型有哪些?什么是自动拆装箱?
Java语言支持的8种基本数据类型是:byte,short,int,long,float,double,boolean,char
自动装箱是指java编译器在基本数据类型和对应的对象包装类型之间做一个转化,比如:把int转化成Integer,double转化成Double。
Java支持的数据类型包括两种:一种是基本数据类型,包含byte,char,short, boolean ,int , long, float,double;另一种是引用类型:如String等,其实是对象的引用,JVM中虚拟栈中存的是对象的地址,创建的对象实质在堆中,通过地址来找到堆中的对象的过程,即为引用类型。自动装箱就是Java编译器在基本数据类型和对应的对象包装类型间的转化,即int转化为Integer,自动拆箱是Integer调用其方法将其转化为int的过程
6.Java中的方法覆盖(Overriding)和方法重载(Overloading)是什么意思?
Java中的方法重载发生在同一个类里面两个或者是多个方法的方法名相同但是参数不同的情况。与此相对,方法覆盖是说子类重新定义了父类的方法。方法覆盖必须有相同的方法名,参数列表和返回类型。覆盖者可能不会限制它所覆盖的方法的访问。
方法重写的原则:
重写方法的方法名称、参数列表必须与原方法的相同,返回类型可以相同也可以是原类型的子类型(从Java SE5开始支持)。
重写方法不能比原方法访问性差(即访问权限不允许缩小)。
重写方法不能比原方法抛出更多的异常。
被重写的方法不能是final类型,因为final修饰的方法是无法重写的。
被重写的方法不能为private,否则在其子类中只是新定义了一个方法,并没有对其进行重写。
被重写的方法不能为static。如果父类中的方法为静态的,而子类中的方法不是静态的,但是两个方法除了这一点外其他都满足重写条件,那么会发生编译错误;反之亦然。即使父类和子类中的方法都是静态的,并且满足重写条件,但是仍然不会发生重写,因为静态方法是在编译的时候把静态方法和类的引用类型进行匹配。
重写是发生在运行时的,因为编译期编译器不知道并且没办法确定该去调用哪个方法,JVM会在代码运行的时候作出决定。
方法重载的原则:
方法名称必须相同。
参数列表必须不同(个数不同、或类型不同、参数类型排列顺序不同等)。
方法的返回类型可以相同也可以不相同。
仅仅返回类型不同不足以成为方法的重载。
重载是发生在编译时的,因为编译器可以根据参数的类型来选择使用哪个方法。
重写和重载的不同:
方法重写要求参数列表必须一致,而方法重载要求参数列表必须不一致。
方法重写要求返回类型必须一致(或为其子类型),方法重载对此没有要求。
方法重写只能用于子类重写父类的方法,方法重载用于同一个类中的所有方法。
方法重写对方法的访问权限和抛出的异常有特殊的要求,而方法重载在这方面没有任何限制。
父类的一个方法只能被子类重写一次,而一个方法可以在所有的类中可以被重载多次。
重载是编译时多态,重写是运行时多态。
7.Java中,什么是构造方法?什么是构造方法重载?什么是复制构造方法?
当新对象被创建的时候,构造方法会被调用。每一个类都有构造方法。在程序员没有给类提供构造方法的情况下,Java编译器会为这个类创建一个默认的构造方法。Java中构造方法重载和方法重载很相似。可以为一个类创建多个构造方法。每一个构造方法必须有它自己唯一的参数列表。Java不支持像C++中那样的复制构造方法,这个不同点是因为如果你不自己写构造方法的情况下,Java不会创建默认的复制构造方法。
8.Java支持多继承么?
Java中类不支持多继承,只支持单继承(即一个类只有一个父类)。但是java中的接口支持多继承,即一个子接口可以有多个父接口(接口的作用是来扩展对象的功能,一个子接口继承多个父接口,说明子接口扩展了多个功能,当实现接口时,类就扩展了相应的功能)
9.接口和抽象类的区别是什么?
(1)接口中所有的方法隐含的都是抽象的。而抽象类则可以同时包含抽象和非抽象的方法
(2)类可以实现很多个接口,但是只能继承一个抽象类
(3)类可以不实现抽象类和接口声明的所有方法,当然,在这种情况下,类也必须得声明成是抽象的
(4)抽象类可以在不提供接口方法实现的情况下实现接口
(5)Java接口中声明的变量默认都是final的。抽象类可以包含非final的变量
(6)Java接口中的成员函数默认是public的。抽象类的成员函数可以是private,protected或者是public
(7)接口是绝对抽象的,不可以被实例化。抽象类也不可以被实例化,但是,如果它包含main方法的话是可以被调用的
从设计层面来说,抽象是对类的抽象,是一种模板设计,接口是行为的抽象,是一种行为的规范
10.什么是值传递和引用传递?
值传递是对基本型变量而言的,传递的是该变量的一个副本,改变副本不影响原变量;引用传递一般是对于对象型基本变量而言的,传递是该对象地址的一个副本,并不是原对象本身;一般认为java内的传递都是值传递,java中实例对象的传递都是引用传递
例如:public void add(int a) { int b = a; } 这个可以看作是值传递,a是基本数据类型,他把他的值传给了bpublic void add(Object obj) { Object objTest = obj; }这个可以看作是址传递,obj是引用数据类型,是把他栈中指向堆中的对象的地址值赋值给了objTest.这时候就同时有两个引用指向了堆中的某个Object对象 其实这样看来,java应该只有值传递的。如果是基本数据类型,传递的就是实际的值. 如果是引用数据类型,传递的就是该引用的地址值.
11.进程和线程的区别是什么?
进程是执行着的应用程序,而线程是进程内部的一个执行序列。一个进程可以有多个线程,线程又叫做轻量级进程,线程的划分小于进程,线程隶属于某个进程。进程是程序的一种动态形式,是CPU、内存等资源占用的基本单位,而线程是不能占有这些资源的。 进程之间相互独立,通信比较困难,而线程之间共享一块内存区域,通信比较方便。 进程在执行的过程中,包含比较固定的入口,执行顺序,出口,而线程的这些过程会被应用程序所控制
线程与进程的区别归纳:
a.地址空间和其它资源:进程间相互独立,同一进程的各线程间共享。某进程内的线程在其它进程不可见。
b.通信:进程间通信IPC,线程间可以直接读写进程数据段(如全局变量)来进行通信——需要进程同步和互斥手段的辅助,以保证数据的一致性。
c.调度和切换:线程上下文切换比进程上下文切换要快得多。
d.在多线程OS中,进程不是一个可执行的实体。
12.创建线程有几种不同的方式?你喜欢哪一种?为什么?
创建线程的方式有4种:继承Thread类;实现Runnable接口;应用程序可以使用Executor框架来创建线程池;实现Callable接口
实现Runnable接口这种方式更受欢迎,因为这不需要继承Thread类,在应用设计中已经继承了别的对象的情况下,这需要多继承(而Java不支持多继承),只能实现接口。同时,线程池也是非常高效的,很容易实现和使用。
①继承Thread类(真正意义上的线程类),是Runnable接口的实现。
②实现Runnable接口,并重写里面的run方法。
③使用Executor框架创建线程池。Executor框架是juc里提供的线程池的实现。
调用线程的start():启动此线程;调用相应的run()方法
继承于Thread类的线程类,可以直接调用start方法启动线程(使用static也可以实现资源共享).一个线程(对象)只能够执行一次start(),而且不能通过Thread实现类对象的run()去启动一个线程。
实现Runnable接口的类需要再次用Thread类包装后才能调用start方法。(三个Thread对象包装一个类对象,就实现了资源共享)。
线程的使用的话,注意锁和同步的使用。(多线程访问共享资源容易出现线程安全问题)
一般情况下,常见的是第二种。
* Runnable接口有如下好处:
*①避免点继承的局限,一个类可以继承多个接口。
*②适合于资源的共享
/*
* Thread的常用方法:
* 1.start():启动线程并执行相应的run()方法
* 2.run():子线程要执行的代码放入run()方法中
* 3.currentThread():静态的,调取当前的线程
* 4.getName():获取此线程的名字
* 5.setName():设置此线程的名字
* 6.yield():调用此方法的线程释放当前CPU的执行权(很可能自己再次抢到资源)
* 7.join():在A线程中调用B线程的join()方法,表示:当执行到此方法,A线程停止执行,直至B线程执行完毕,
* A线程再接着join()之后的代码执行
* 8.isAlive():判断当前线程是否还存活
* 9.sleep(long l):显式的让当前线程睡眠l毫秒 (只能捕获异常,因为父类run方法没有抛异常)
* 10.线程通信(方法在Object类中):wait()
notify() notifyAll()
*设置线程的优先级(非绝对,只是相对几率大些)
* getPriority():返回线程优先值
* setPriority(int newPriority):改变线程的优先级
*/
13.概括的解释下线程的几种可用状态
14.什么是Servlet?
Servlet是用来处理客户端请求并产生动态网页内容的java类。Servlet主要是用来处理或者是存储HTML表单提交的数据,产生动态内容,再无状态HTTP协议下管理状态信息
15.说一下Servlet的体系结构
所有的Servlet都必须要实现的核心的接口是javax.servlet.Servlet.每一个Servlet都必须要直接或者是间接实现这个接口,或者是继承javax.servlet.GenericServlet或者javax.servlet.http.HTTPServlet。最后,Servlet使用多线程可以并行的为多个请求服务
16.Applet和Servlet有什么区别
Applet试运行在客户端主机的浏览器上的客户端java程序。而Servlet是运行在web服务器上的服务端的组件。Applet可以使用用户界面类,而servlet没有用户界面,相反Servlet是等待客户端的HTTP请求,然后为请求产生响应。
17.解释下Servlet的生命周期
对每一个客户端的请求,Servlet引擎载入servlet,调用它的init()方法,完成Servlet的初始化。然后,Servlet对象通过为每一个请求单独调用service()方法来处理所有随后来自客户端的请求,最后,调用Servlet.
18.doGet()方法和doPost()方法有什么区别?
doGet():GET方法会把名值对追加在请求的URL后面。因为URL对字符数目有限制,进而限制了用在客户端请求的参数值的数目,并且请求中的参数值是可见的,因此敏感信息不能用这种方式传递
doPost():POST方法通过把请求参数值放在请求体中来克服GET方法的限制,因此,可以发送的参数的数目是没有限制的。最后,通过POST请求传递的敏感信息对外部客户端是不可见的
19.什么是Web应用程序?
Web应用程序是对Web或者是应用服务器的动态扩展,有两种类型的Web应用:面向表现和面向服务的。面向表现的Web应用程序会产生包含了很多标记语言和动态内容的交互的web页面作为对请求的响应。而面向服务的Web应用实现了Web服务的端点,一般来说,一个Web应用可以看成是一组安装在服务器URL名称空间的特定自己下面的Servlet的集合。
20.什么是cookie?session和cookie有什么区别?
cookie是Web服务器发送给浏览器的一块信息。浏览器会在本地文件中给每一个Web服务器存储cookie。以后浏览器在给特定的Web服务器发请求的时候,同时会发送所有为该服务器存储的cookie。
session和cookie的区别:
无论客户端浏览器做怎么样的设置,session都应该能正常工作。客户端可以禁用cookie,但是session仍然能够工作的,因为客户端无法禁止服务端的session。
在存储的数据量方面session和cookie也是不一样的。session能够存储任意的java对象,cookie只能存储String类型的对象
21.sendRedirect()和forward()方法有什么区别?
sendRedirect()方法会创建一个新的请求,而forward()方法只是把请求转发到一个新的目标上。重定向(redirect)以后,之前请求作用于范围以内的对象就失败了,因为会产生一个新的请求,而转发(forwarding)以后,之前请求作用于范围以内的对象 还是能访问的。一般 认为sendRedict()要比forward()慢
22.什么是JSP页面
JSP页面是一种包含了静态数据和JSP元素两种类型的文本的文本文档。静态数据可以用任何基于文本的格式来表示,比如:HTML或者XML。JSP是一种混合了静态内容和动态产生的内容的技术
23.JSP请求是如何被处理的?
浏览器首先要请求一个以.jsp扩展名结尾的页面,发起JSP请求,然后web服务器会读取这个请求,使用jsp编译器把jsp页面转化成一个servlet类。需要注意的是,只有第一次请求页面或者是JSP文件发生改变的时候JSP文件才会被编译,然后服务器调用Servlet类,处理浏览器的请求。一旦请求执行结束,servlet会把响应发送给客户端。
24.JSP有什么优点?
下面列出了使用JSP的优点:
JSP页面是被动态编译成Servlet的,因此,开发者可以很容易的更新展现代码。
JSP页面可以被预编译。
JSP页面可以很容易的和静态模板结合,包括:HTML或者XML,也可以很容易的和产生动态内容的代码结合起来。
开发者可以提供让页面设计者以类XML格式来访问的自定义的JSP标签库。
开发者可以在组件层做逻辑上的改变,而不需要编辑单独使用了应用层逻辑的页面。
25.抽象的定义?抽象和封装的不同点?
抽象是把想法从具体的实例中分离出来的步骤,因此,要根据他们的功能而不是实现细节来创建类,java支持创建只暴露接口而不包含方法实现的抽象的类,这种抽象技术的主要目的是把类的行为和实现细节分离开
抽象和封装是互补的概念。一方面,抽象关注对象的行为。另一方面,封装关注对象行为的细节。一般是通过隐藏对象内部状态信息做到封装,因此,封装可以看成是用来提供抽象的一种策略。
26.继承的定义?
继承给对象提供了从基类获取字段和方法的能力。继承提供了代码的重用性,也可以在不修改类的情况下给现存的类添加新特性。
27.多态的定义?
多态是编程语言给不同的底层数据类型做相同的借口展示的一种能力。一个多态类型桑的错做可以应用到其他类型的值上面。
28.封装的定义和好处有哪些?
封装给对象提供了隐藏内部特性和行为的能力。对象提供一些能被其他对象访问的方法来改变它内部的数值。在java当中 ,有3总修饰符:public,private,protected.每一种修饰符给其他的位于同一个包或者不同包下面对象赋予了不同的访问权限。
封装的一些好处:
通过隐藏对象的属性来保护对象内部的状态;提高了diamante的可用性和可维护性,因为对象的行为可以被单独的改变或者是扩展;禁止对象之间的不良交互提高模块化
或者
一是用private把类的细节与外界隔离起来,从而实现数据项和方法的隐藏,而要访问这些数据项和方法唯一的途径就是通过类本身,类才有资格调用它所拥有的资源(方法,数据项属性等等)。所以第一个好处就是数据的安全性提高了。
二是通过隐藏隔离,只允许外部对类做有限的访问,开发者可以自由的改变类的内部实现,而无需修改使用该类的那些程序。只要那些在类外部就能被调用的方法保持其外部特征不变,内部代码就可以自由改变,各取所需,利于分工。
三就是提高了代码的重用性,封装成工具类以后能够减少很多繁琐的步骤。
29.面向对象软件开发的优点有哪些?
代码开发模块化,更易于维护和修改;代码复用;增强代码的可靠性和灵活性;增加代码的可理解性;面向对象编程有很多重要的特性,比如:封装,继承,多态和抽象。
28.隐含对象是什么意思?有哪些隐含对象?
jsp隐含对象是页面中的一些java对象,jsp容器让这些java对象可以为开发者所利用。开发者不用明确的声明就可以直接使用它们。jsp隐含对象也叫做预定义变量,下面列出了jsp页面中的隐含对象:
application;page;request;response;session;exception;out;config;pageContext;
29.什么是表达式(Expression)?
列表很长,可以分上,中,下发布,jsp表达式是Web服务器把脚本语言表达式的值转化成一个String 对象,插入到返回给客户端的数据流中。表达式是在<%=和%>这两个标签之间定义的。
30.声明(Decalaration)在哪里?
声明跟java中的变量的声明很相似,它用来声明随后被表达式或者scriptlet使用的变量。添加的声明必须要用开始和结束标签包起来。
31.什么是Scriptlets?
JSP技术中,scriptlet是嵌入在JSP页面中的一段Java代码。scriptlet是位于标签内部的所有的东西,在标签与标签之间,用户可以添加任意有效的scriplet。
32.什么是JSP动作(JSP action)?
JSP动作以XML语法的结构来控制Servlet引擎的行为。当JSP页面被请求的时候,JSP动作会被执行,它们可以被动态的插入到文件中,重用JavaBean组件,转发用户到其他的页面,或者是给java插件产生HTML代码,下面列出了可用的动作:
jsp:include----当JSP页面被请求的时候包含一个文件
jsp:useBean------找出或者是初始化JavaBean
jsp:setProperty------设置JavaBean的属性
jsp:getProperty--------获取JavaBean的属性
jsp:forward--------把请求转发到新的页面
jsp:plugin------产生特定浏览器的代码
33.什么是JSP指令(Directive)?JSP中有哪些不同类型的指令?
Directive是jsp页面被编译成servlet的时候,jsp引擎要处理的指令。Directive用来设置页面级别的指令,从外部插入数据,指定自定义的标签库。Directive是定义在<%@和%>之间的,下面列出了不同类型的Directive:
包含指令(include directive):用来包含文件和合并文件内容到当前的页面
页面指令(page directive):用来定义jsp页面中特定的属性,比如错误页面和缓冲区
Taglib指令:用来声明页面中使用的自定义的标签库
34.作用域public,private,protected以及不写时的区别
35.Anonymous Inner Class (匿名内部类)是否可以extends(继承)其它类,是否可以implements(实现)interface(接口)
匿名的内部类是没有名字的内部类,不能继承其他类,但是一个内部类可以作为一个接口,由另一个内部类实现
36.静态内部类意味着:创建一个static内部类的对象,不需要一个而外部类对象;不能从一个static内部类的一个对象访问一个外部类对象
37.&是位运算符,表示按位与运算;&&是逻辑运算符,表示逻辑与(and);
对于&不管怎样,都会执行&符号左右两边的程序;对于&&,只有&&左边的程序为真(true)后,才会执行&&右边的程序
&:只要左右两边有一个为false,则为false;只有全部为true,结果为true;
&&:只要符号左边为false,则结果九尾false;当左边为true,同时右边为true,则结果为true
38.Collection和Collections的区别
Collection是集合类的上级接口,继承于他的接口主要有Set、List
Collections是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索、排序、现成安全化等操作
39.什么时候使用assert?
assertion(断言)在软件开发中是一种常用的调试方式,很多开发语言中都支持这种机制;在实现中,assertion就是在程序中的一条语句,它对一个boolean表达式进行检查,一个正确程序必须保证这个boolean表达式的值为true;如果该值为false,说明程序已经处于不正确的状态下,系统将给出警告或退出。一般来说,assertion用于保证程序最基本、关键的正确性。assertion检查通常在开发和测试时开启。为了提高性能,在软件发布后,assertion检查通常是关闭的
40.String s = new String("xyz");创建了几个String Object,他们之间有什么区别?
创建了两个String Object 。
这个跟常量池没有关系,只要是new,都是重新分配堆空间,如果不区分栈和堆,这里创建了1个String Object。
如果是从jvm角度来说的话,它是创建了两个对象,String s是在栈里创建了一个变量,new String("xyz")是在堆里创建了一个对象并被s引用到。
String str = "aaa" + new String("bbb")创建了几个String对象?
"aa"一个对象; new String("bbb") 一个对象;
41.Math.round(11.5)等於多少? Math.round(-11.5)等於多少?
Math.round(11.5)==12;Math.round(-11.5)==-11;round方法返回与参数最接近的长整数,参数加1/2后求其floor
42.short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错?
short s1 = 1; s1 = s1 + 1;(s1+1运算结果是int型,需要强制转换类型)short s1 = 1; s1 += 1;(可以正确编译)
java语言规范中关于复合赋值的解释是这样的:E1 op=E2等价于E1=(T)(E1 op E2),这里的T是E1的数据类型; 原来这个复合赋值是自带了隐式的强制类型转换的
43.java中有goto保留字,现在没有在java中使用
44.数组和字符串的区别
(1)数组没有length()这个方法,有length属性;String有length()这个方法