您的位置:首页 > 编程语言 > Java开发

Java基础知识积累2

2017-03-29 23:30 211 查看
switch语句后的控制表达式只能是short、char、int、long整数类型和枚举类型,不能是float,double和boolean类型。String类型是java7开始支持。

Java程序的种类有:

(a)内嵌于Web文件中,由浏览器来观看的_Applet

(b)可独立运行的 Application

(c)服务器端的 Servlets

A 显然是错误的,Java一律采用Unicode编码方式,每个字符无论中文还是英文字符都占用2个字节。

B 也是不正确的,不同的编码之间是可以转换的,通常流程如下:

将字符串S以其自身编码方式分解为字节数组,再将字节数组以你想要输出的编码方式重新编码为字符串。

例:String newUTF8Str = new String(oldGBKStr.getBytes(“GBK”), “UTF8”);

C 是正确的。Java虚拟机中通常使用UTF-16的方式保存一个字符

D 也是正确的。ResourceBundle能够依据Local的不同,选择性的读取与Local对应后缀的properties文件,以达到国际化的目的。

数据类型的转换,分为自动转换和强制转换。自动转换是程序在执行过程中 “ 悄然 ” 进行的转换,不需要用户提前声明,一般是从位数低的类型向位数高的类型转换;强制类型转换则必须在代码中声明,转换顺序不受限制。

自动数据类型转换

自动转换按从低到高的顺序转换。不同类型数据间的优先关系如下:

低 ———————————————> 高

byte,short,char-> int -> long -> float -> double

异常通常指,你的代码可能在编译时没有错误,可是运行时会出现异常。比如常见的空指针异常。

也可能是程序可能出现无法预料的异常,比如你要从一个文件读信息,可这个文件不存在,

程序无法运行下去了,故程序要抓这些异常,通过异常处理机制来抛出这些异常,

程序员就可以通过抛出的异常来修改代码。try{}catch{}finally{}try块中放入可能会出现异常的代码,

catch块负责捕获异常,finally块负责处理一些必须执行的代码,比较关闭流等。

描述一下JVM加载class文件的原理机制?

答:JVM中类的装载是由类加载器(ClassLoader)和它的子类来实现的,Java中的类加载器是一个重要的Java运行时系统组件,它负责在运行时查找和装入类文件中的类。

由于Java的跨平台性,经过编译的Java源程序并不是一个可执行程序,而是一个或多个类文件。当Java程序需要使用某个类时,

JVM会确保这个类已经被加载、连接(验证、准备和解析)和初始化。类的加载是指把类的.class文件中的数据读入到内存中,

通常是创建一个字节数组读入.class文件,然后产生与所加载类对应的Class对象。加载完成后,Class对象还不完整,所以此时的类还不可用。

当类被加载后就进入连接阶段,这一阶段包括验证、准备(为静态变量分配内存并设置默认的初始值)和解析(将符号引用替换为直接引用)三个步骤。

最后JVM对类进行初始化,包括:1)如果类存在直接的父类并且这个类还没有被初始化,那么就先初始化父类;2)如果类中存在初始化语句,就依次执行这些初始化语句。

类的加载是由类加载器完成的,类加载器包括:根加载器(BootStrap)、扩展加载器(Extension)、系统加载器(System)和用户自定义类加载器(java.lang.ClassLoader的子类)。从Java 2(JDK 1.2)开始,类加载过程采取了父亲委托机制(PDM)。PDM更好的保证了Java平台的安全性,在该机制中,JVM自带的Bootstrap是根加载器,其他的加载器都有且仅有一个父类加载器。类的加载首先请求父类加载器加载,父类加载器无能为力时才由其子类加载器自行加载。JVM不会向Java程序提供对Bootstrap的引用。下面是关于几个类加载器的说明:

Bootstrap:一般用本地代码实现,负责加载JVM基础核心类库(rt.jar);

Extension:从java.ext.dirs系统属性所指定的目录中加载类库,它的父加载器是Bootstrap;

System:又叫应用类加载器,其父类是Extension。它是应用最广泛的类加载器。

它从环境变量classpath或者系统属性java.class.path所指定的目录中记载类,

是用户自定义加载器的默认父加载器。

阐述静态变量和实例变量的区别。

答:静态变量是被static修饰符修饰的变量,也称为类变量,它属于类,不属于类的任何一个对象,一个类不管创建多少个对象,静态变量在内存中有且仅有一个拷贝;

实例变量必须依存于某一实例,需要先创建对象然后通过对象才能访问到它。静态变量可以实现让多个对象共享内存。

静态嵌套类(Static Nested Class)和内部类(Inner Class)的不同?

答:Static Nested Class是被声明为静态(static)的内部类,它可以不依赖于外部类实例被实例化。而通常的内部类需要在外部类实例化后才能实例化

抽象的(abstract)方法是否可同时是静态的(static),是否可同时是本地方法(native),是否可同时被synchronized修饰?

答:都不能。抽象方法需要子类重写,而静态的方法是无法被重写的,因此二者是矛盾的。本地方法是由本地代码(如C代码)实现的方法,而抽象方法是没有实现的,也是矛盾的。

synchronized和方法的实现细节有关,抽象方法不涉及实现细节,因此也是相互矛盾的。

是否可以从一个静态(static)方法内部发出对非静态(non-static)方法的调用?

答:不可以,静态方法只能访问静态成员,因为非静态方法的调用要先创建对象,在调用静态方法时可能对象并没有被初始化。

如何实现对象克隆?

答:有两种方式:

  1). 实现Cloneable接口并重写Object类中的clone()方法;

  2). 实现Serializable接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆

Java 中的final关键字有哪些用法?

答:(1)修饰类:表示该类不能被继承;(2)修饰方法:表示方法不能被重写;(3)修饰变量:表示变量只能一次赋值以后值不能被修改(常量)。

创建对象时构造器的调用顺序是:先初始化静态成员,然后调用父类构造器,再初始化非静态成员,最后调用自身构造器。

如何实现字符串的反转及替换?

答:方法很多,可以自己写实现也可以使用String或StringBuffer/StringBuilder中的方法。有一道很常见的面试题是用递归实现字符串反转,代码如下所示:

public static String reverse(String originStr) {

if(originStr == null || originStr.length() <= 1)

return originStr;

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

}

Java语言如何进行异常处理,关键字:throws、throw、try、catch、finally分别如何使用?

答:Java通过面向对象的方法进行异常处理,把各种不同的异常进行分类,并提供了良好的接口。在Java中,每个异常都是一个对象,它是Throwable类或其子类的实例。

当一个方法出现异常后便抛出一个异常对象,该对象中包含有异常信息,调用这个对象的方法可以捕获到这个异常并可以对其进行处理。

Java的异常处理是通过5个关键词来实现的:try、catch、throw、throws和finally。一般情况下是用try来执行一段程序,如果系统会抛出(throw)一个异常对象,

可以通过它的类型来捕获(catch)它,或通过总是执行代码块(finally)来处理;try用来指定一块预防所有异常的程序;catch子句紧跟在try块后面,

用来指定你想要捕获的异常的类型;throw语句用来明确地抛出一个异常;throws用来声明一个方法可能抛出的各种异常(当然声明异常时允许无病呻吟);

finally为确保一段代码不管发生什么异常状况都要被执行;try语句可以嵌套,每当遇到一个try语句,异常的结构就会被放入异常栈中,直到所有的try语句都完成。

如果下一级的try语句没有对某种异常进行处理,异常栈就会执行出栈操作,直到遇到有处理这种异常的try语句或者最终将异常抛给JVM。

阐述final、finally、finalize的区别。

答:

- final:修饰符(关键字)有三种用法:如果一个类被声明为final,意味着它不能再派生出新的子类,即不能被继承,因此它和abstract是反义词。

将变量声明为final,可以保证它们在使用中不被改变,被声明为final的变量必须在声明时给定初值,而在以后的引用中只能读取不可修改。

被声明为final的方法也同样只能使用,不能在子类中被重写。

- finally:通常放在try…catch…的后面构造总是执行代码块,这就意味着程序无论正常执行还是发生异常,这里的代码只要JVM不关闭都能执行,

可以将释放外部资源的代码写在finally块中。

- finalize:Object类中定义的方法,Java中允许使用finalize()方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。

这个方法是由垃圾收集器在销毁对象时调用的,通过重写finalize()方法可以整理系统资源或者执行其他清理工作。

Thread类的sleep()方法和对象的wait()方法都可以让线程暂停执行,它们有什么区别?

答:sleep()方法(休眠)是线程类(Thread)的静态方法,调用此方法会让当前线程暂停执行指定的时间,将执行机会(CPU)让给其他线程,但是对象的锁依然保持,

因此休眠时间结束后会自动恢复(线程回到就绪状态,请参考第66题中的线程状态转换图)。wait()是Object类的方法,

调用对象的wait()方法导致当前线程放弃对象的锁(线程暂停执行),进入对象的等待池(wait pool),只有调用对象的notify()方法(或notifyAll()方法)

时才能唤醒等待池中的线程进入等锁池(lock pool),如果线程重新获得对象的锁就可以进入就绪状态。

线程的sleep()方法和yield()方法有什么区别?

答:

① sleep()方法给其他线程运行机会时不考虑线程的优先级,因此会给低优先级的线程以运行的机会;yield()方法只会给相同优先级或更高优先级的线程以运行的机会;

② 线程执行sleep()方法后转入阻塞(blocked)状态,而执行yield()方法后转入就绪(ready)状态;

③ sleep()方法声明抛出InterruptedException,而yield()方法没有声明任何异常;

④ sleep()方法比yield()方法(跟操作系统CPU调度相关)具有更好的可移植性。

阐述JDBC操作数据库的步骤。

答:下面的代码以连接本机的Oracle数据库为例,演示JDBC操作数据库的步骤。

加载驱动。

Class.forName(“oracle.jdbc.driver.OracleDriver”);

创建连接。

Connection con = DriverManager.getConnection(“jdbc:oracle:thin:@localhost:1521:orcl”, “scott”, “tiger”);

创建语句。

PreparedStatement ps = con.prepareStatement(“select * from emp where sal between ? and ?”);

ps.setInt(1, 1000);

ps.setInt(2, 3000);

执行语句。

ResultSet rs = ps.executeQuery();

处理结果。

while(rs.next()) {

System.out.println(rs.getInt(“empno”) + ” - ” + rs.getString(“ename”));

}

关闭资源。

finally {

if(con != null) {

try {

con.close();

} catch (SQLException e) {

e.printStackTrace();

}

}

}

提示:关闭外部资源的顺序应该和打开的顺序相反,也就是说先关闭ResultSet、再关闭Statement、在关闭Connection。上面的代码只关闭了Connection(连接),

虽然通常情况下在关闭连接时,连接上创建的语句和打开的游标也会关闭,但不能保证总是如此,因此应该按照刚才说的顺序分别关闭。

此外,第一步加载驱动在JDBC 4.0中是可以省略的(自动从类路径中加载驱动),但是我们建议保留。

JSP有哪些内置对象?作用分别是什么?

答:JSP有9个内置对象:

- request:封装客户端的请求,其中包含来自GET或POST请求的参数;

- response:封装服务器对客户端的响应;

- pageContext:通过该对象可以获取其他对象;

- session:封装用户会话的对象;

- application:封装服务器运行环境的对象;

- out:输出服务器响应的输出流对象;

- config:Web应用的配置对象;

- page:JSP页面本身(相当于Java程序中的this);

- exception:封装页面抛出异常的对象。

web.xml文件中可以配置哪些内容?

答:web.xml用于配置Web应用的相关信息,如:监听器(listener)、过滤器(filter)、 Servlet、

相关参数、会话超时时间、安全验证方式、错误页面等,下面是一些开发中常见的配置

自定义JSP标签包括以下几个步骤:

- 编写一个Java类实现实现Tag/BodyTag/IterationTag接口(开发中通常不直接实现这些接口而是继承TagSupport/BodyTagSupport/SimpleTagSupport类,这是对缺省适配模式的应用),重写doStartTag()、doEndTag()等方法,定义标签要完成的功能

- 编写扩展名为tld的标签描述文件对自定义标签进行部署,tld文件通常放在WEB-INF文件夹下或其子目录中

- 在JSP页面中使用taglib指令引用该标签库

如何设置请求的编码以及响应内容的类型?

答:通过请求对象(ServletRequest)的setCharacterEncoding(String)方法可以设置请求的编码,

其实要彻底解决乱码问题就应该让页面、服务器、请求和响应、Java程序都使用统一的编码,最好的选择当然是UTF-8;

通过响应对象(ServletResponse)的setContentType(String)方法可以设置响应内容的类型,

当然也可以通过HttpServletResponsed对象的setHeader(String, String)方法来设置。

什么是ORM?

答:对象关系映射(Object-Relational Mapping,简称ORM)是一种为了解决程序的面向对象模型与数据库的关系模型互不匹配问题的技术;

简单的说,ORM是通过使用描述对象和数据库之间映射的元数据(在Java中可以用XML或者是注解),

选择使用Spring框架的原因(Spring框架为企业级开发带来的好处有哪些)?

答:可以从以下几个方面作答:

- 非侵入式:支持基于POJO的编程模式,不强制性的要求实现Spring框架中的接口或继承Spring框架中的类。

- IoC容器:IoC容器帮助应用程序管理对象以及对象之间的依赖关系,对象之间的依赖关系如果发生了改变只需要修改配置文件而不是修改代码,因为代码的修改可能意味着项目的重新构建和完整的回归测试。有了IoC容器,程序员再也不需要自己编写工厂、单例,这一点特别符合Spring的精神”不要重复的发明轮子”。

- AOP(面向切面编程):将所有的横切关注功能封装到切面(aspect)中,通过配置的方式将横切关注功能动态添加到目标代码上,进一步实现了业务逻辑和系统服务之间的分离。另一方面,有了AOP程序员可以省去很多自己写代理类的工作。

- MVC:Spring的MVC框架是非常优秀的,从各个方面都可以甩Struts 2几条街,为Web表示层提供了更好的解决方案。

- 事务管理:Spring以宽广的胸怀接纳多种持久层技术,并且为其提供了声明式的事务管理,在不需要任何一行代码的情况下就能够完成事务管理。

- 其他:选择Spring框架的原因还远不止于此,Spring为Java企业级开发提供了一站式选择,你可以在需要的时候使用它的部分和全部,更重要的是,你甚至可以在感觉不到Spring存在的情况下,在你的项目中使用Spring提供的各种优秀的功能。

阐述Spring框架中Bean的生命周期?

答:

① Spring IoC容器找到关于Bean的定义并实例化该Bean。

② Spring IoC容器对Bean进行依赖注入。

③ 如果Bean实现了BeanNameAware接口,则将该Bean的id传给setBeanName方法。

④ 如果Bean实现了BeanFactoryAware接口,则将BeanFactory对象传给setBeanFactory方法。

⑤ 如果Bean实现了BeanPostProcessor接口,则调用其postProcessBeforeInitialization方法。

⑥ 如果Bean实现了InitializingBean接口,则调用其afterPropertySet方法。

⑦ 如果有和Bean关联的BeanPostProcessors对象,则这些对象的postProcessAfterInitialization方法被调用。

⑧ 当销毁Bean实例时,如果Bean实现了DisposableBean接口,则调用其destroy方法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java