JavaOOP 面试题 48 题(含答案),大厂 Java 高级多套面试专题整理集合
关闭资源
62、在使用 jdbc 的时候,如何防止出现 sql 注入的问题。
使用 PreparedStatement 类,而不是使用 Statement 类
使用 CallableStatement
数据库连接是非常消耗资源的,影响到程序的性能指标。连接池是用来分配、管理、释放数据库连接的,可以使应用程序重复使用同一个数据库连接,而不是每次都创建一个新的数据库连接。通过释放空闲时间较长的数据库连接避免数据库因为创建太多的连接而造成的连接遗漏问题,提高了程序性能。
============================================================================================
Dbcp,c3p0 等,用的最多还是 c3p0,因为 c3p0 比 dbcp 更加稳定,安全;通过配置文件的形式来维护数据库信息,而不是通过硬编码。当连接的数据库信息发生改变时,不需要再更改程序代码就实现了数据库信息的更新。
&是位运算符。&&是布尔逻辑运算符,在进行逻辑判断时用 &处理的前面为 false 后面的内容仍需处理,用 &&处理的前面为 false 不再处理后面的内容。
定义在类内部的静态类,就是静态内部类。
静态内部类可以访问外部类所有的静态变量和方法,即使是 private 的也一样。
静态内部类和一般类一致,可以定义静态变量、方法,构造方法等。
其它类使用静态内部类需要使用“外部类.静态内部类”方式,如下所示:Out.Inner inner = new Out.Inner();inner.print();
Java 集合类 HashMap 内部就有一个静态内部类 Entry。Entry 是 HashMap 存放元素的抽象,HashMap 内部维护 Entry 数组用了存放元素,但是 Entry 对使用者是透明的。像这种和外部类关系密切的,且不依赖外部类实例的,都可以使用静态内部类。
定义在类内部的非静态类,就是成员内部类。成员内部类不能定义静态方法和变量(final 修饰的除外)。这是因为成员内部类是非静态的,
类初始化的时候先初始化静态成员,如果允许成员内部类定义静态变量,那么成员内部类的静态变量初始化顺序是有歧义的。实例:
69、Static Nested Class 和 Inner Class 的不同
Nested Class (一般是 C++的说法),Inner Class (一般是 JAVA 的说法)。Java 内部类与 C++嵌套类最大的不同就在于是否有指向外部的引用上。注: 静态内部类(Inner Class)意味着 1 创建一个 static 内部类的对象,不需要一个外部类对象,2 不能从一个 static 内部类的一个对象访问一个外部类对象
assertion(断言)在软件开发中是一种常用的调试方式,很多开发语言中都支持这种机制。在实现中,assertion 就是在程序中的一条语句,它对一个 boolean 表达式进行检查,一个正确程序必须保证这个 boolean 表达式的值为 true;如果该值为 false,说明程序已经处于不正确的状态下,系统将给出警告或退出。一般来说,assertion 用于保证程序最基本、关键的正确性。assertion 检查通常在开发和测试时开启。为了提高性能,在软件发布后,assertion 检查通常是关闭的
java 中的保留字,现在没有在 java 中使用
72、数组有没有 length()这个方法? String 有没有 length()这个方法
数组没有 length()这个方法,有 length 的属性。String 有有 length()这个方法
2 << 3
=========================================================================================
不正确。精度不准确,应该用强制类型转换,如下所示:
float f=(float)3.4
排序的方法有:插入排序(直接插入排序、希尔排序),交换排序(冒泡排序、快速排序),选择排序(直接选择排序、堆排序),归并排序,分配排序(箱排序、基数排序)快速排序的伪代码。/ /使用快速排序方法对 a[ 0 :n- 1 ]排序从 a[ 0 :n- 1 ]中选择一个元素作为 m i d d le,该元素为支点把余下的元素分割为两段 left 和 r i g h t,使得 l e f t 中的元素都小于等于支点,而 right 中的元素都大于等于支点递归地使用快速排序方法对 left 进行排序递归地使用快速排序方法对 right 进行排序所得结果为 l e f t + m i d d l e + r i g h t
static i = 10; //常量 class A a; a.i =10;//可变
常用的类:BufferedReader BufferedWriter FileReader FileWirter String Integer 常用的包:java.lang java.awt java.io java.util java.sql 常用的接口:Remote List Map Document NodeList
78、a.hashCode() 有什么用?与 a.equals(b) 有什么关系?
hashCode() 方法是相应对象整型的 hash 值。它常用于基于 hash 的集合类,如 Hashtable、HashMap、LinkedHashMap 等等。它与 equals() 方法关系特别紧密。根据 Java 规范,两个使用 equal() 方法来判断相等的对象,必须具有相同的 hash code。
公共静态不可变(public static final )变量也就是我们所说的编译期常量,这里的 public 可选的。实际上这些变量在编译时会被替换掉,因为编译器知道这些变量的值,并且知道这些变量在运行时不能改变。这种方式存在的一个问题是你使用了一个内部的或第三方库中的公有编译时常量,但是这个值后面被其他人改变了,但是你的客户端仍然在使用老的值,甚至你已经部署了一个新的 jar。为了避免这种情况,当你在更新依赖 JAR 文件时,确保重新编译你的程序
在最外层循环前加一个标记如 A,然后用 break A;可以跳出多重循环。(Java 中支持带标签的 break 和 continue 语句,作用有点类似于 C
和 C++中的 goto 语句,但是就像要避免使用 goto 一样,应该避免使用带标签的 break 和 continue,因为它不会让你的程序变得更优雅,
很多时候甚至有相反的作用,所以这种语法其实不知道更好)
81、构造器(constructor)是否可被重写(override)?
构造器不能被继承,因此不能被重写,但可以被重载。
82、两个对象值相同(x.equals(y) == true),但却可有不同的 hash code,这句话对不对?
不对,如果两个对象 x 和 y 满足 x.equals(y) == true,它们的哈希码(hash code)应当相同。Java 对于 eqauls 方法和 hashCode 方法是这样规定的:
(1)如果两个 对象相同(equals 方法返回 true),那么它们的 hashCode 值一定要相同;
(2)如果两个对象的 hashCode 相同,它们并不一定相同。当然,你未必要按照要求去做,但是如果你违背了上述原则就会发现在使用容器时,相同的对象可以出现在 Set 集合中,同时增加新元素的效率会大大下降(对于使用哈希存储的系统,如果哈希码频繁的冲突将会造成存取性能急剧下降)。
--
String 类是 final 类,不可以被继承,继承 String 本身就是一个错误的行为,对 String 类型最好的重用方式是关联关系(Has-A)和依赖关系(Use-A)而不是继承关系(Is-A)。
84、当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?
是值传递。Java 语言的方法调用只支持参数的值传递。当一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象的引用。对象的属性可以在被调用过程中被改变,但对对象引用的改变是不会影响到调用者的。C++和 C#中可以通过传引用或传输出参数来改变传入的参数的值。在 C#中可以编写如下所示的代码,但是在 Java 中却做不到。
说明:Java 中没有传引用实在是非常的不方便,这一点在 Java 8 中仍然没有得到改进,正是如此在 Java 编写的代码中才会出现大量的 Wrapper 类(将需要通过方法调用修改的引用置于一个 Wrapper 类中,再将 Wrapper 对象传入方法),这样的做法只会让代码变得臃肿,尤其是让从 C 和 C++转型为 Java 程序员的开发者无法容忍。
85、String 和 StringBuilder、StringBuffer 的区别?
Java 平台提供了两种类型的字符串:String 和 StringBuffer/StringBuilder,它们可以储存和操作字符串。其中 String 是只读字符串,也就意味着 String 引用的字符串内容是不能被改变的。而 StringBuffer/StringBuilder 类表示的字符串对象可以直接进行修改。StringBuilder 是 Java 5 中引入的,它和 StringBuffer 的方法完全相同,区别在于它是在单线程环境下使用的,因为它的所有方面都没有被 synchronized 修饰,因此它的效率也比 StringBuffer 要高。
86、重载(Overload)和重写(Override)的区别。重载的方法能否根据返回类型进行区分?
方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性。重载发生在一个类中,同名的方法如果有不同的参数列表(参数类型不同、参数个数不同或者二者都不同)则视为重载;重写发生在子类与父类之间,重写要求子类被重写方法与父类被重写方法有相同的返回类型,比父类被重写方法更好访问,不能比父类被重写方法声明更多的异常(里氏代换原则)。重载对返回类型没有特殊的要求。
char 类型可以存储一个中文汉字,因为 Java 中使用的编码是 Unicode(不选择任何特定的编码,直接使用字符在字符集中的编号,这是统一的唯一方法),一个 char 类型占 2 个字节(16 比特),所以放一个中文是没问题的。
补充:使用 Unicode 意味着字符在 JVM 内部和外部有不同的表现形式,在 JVM 内部都是 Unicode,当这个字符被从 JVM 内部转移到外部时(例如存入文件系统中),需要进行编码转换。所以 Java 中有字节流和字符流,以及在字符流和字节流之间进行转换的转换流,如 InputStreamReader 和 OutputStreamReader,这两个类是字节流和字符流之间的适配器类,承担了编码转换的任务;对于 C 程序员来说,要完成这样的编码转换恐怕要依赖于 union(联合体/共用体)共享内存的特征来实现了。
88、抽象类(abstract class)和接口(interface)有什么异同 ?
抽象类和接口都不能够实例化,但可以定义抽象类和接口类型的引用。一个类如果继承了某个抽象类或者实现了某个接口都需要对其中的抽象方法全部进行实现,否则该类仍然需要被声明为抽象类。接口比抽象更加抽象,因为抽象类中可以定义构造器,可以有抽象方法和具体方法,而接口中不能定义构造器而且其中的方法全部都是抽象方法。抽象类中的成员可以是 private、默认、protected、public 的,而接口中的成员全都是 public 的。抽象类中可以定义成员变量,而接口中定义的成员变量实际上都是常量。有抽象方法的类必须被声明为抽象类,而抽象类未必要有抽象方法。
89、静态嵌套类(Static Nested Class)和内部类(Inner Class)的不同?
Static Nested Class 是被声明为静态(static)的内部类,它可以不依赖于外部类实例被实例化。而通常的内部类需要在外部类实例化后才
能实例化,其语法看起来挺诡异的,如下所示
理论 上 Java 因为 有垃 圾回 收机 制( GC)不 会存 在内 存泄 露问 题( 这也 是 Java 被广泛 使用 于服 务器 端编 程的 一个 重要 原因 );然而 在实 际开 发中 ,可 能会 存在 无用但 可达 的对 象,这些 对象 不能 被 GC 回收 ,因此 也会 导致 内存 泄露 的发 生 。 例 如 Hibernate 的 Session( 一级 缓存 )中的 对象 属于 持久 态,垃圾 回收 器是 不会 回收这些 对象 的,然而 这些 对象 中可 能存 在无用的 垃圾 对象 ,如果 不及 时关 闭(close)或清 空( flush)一 级缓 存就 可能 导致 内存 泄露 。下 面例 子中 的代 码也 会导 致内 存泄露
上面的代码实现了一个栈(先进后出(FILO))结构,乍看之下似乎没有什么明显的问题,它甚至可以通过你编写的各种单元测试。然而其中的 pop 方法却存在内存泄露的问题,当我们用 pop 方法弹出栈中的对象时,该对象不会被当作垃圾回收,即使使用栈的程序不再引用这些对象,因为栈内部维护着对这些对象的过期引用(obsolete reference)。在支持垃圾回收的语言中,内存泄露是很隐蔽的,这种内存泄露其实就是无意识的对象保持。如果一个对象引用被无意识的保留起来了,那么垃圾回收器不会处理这个对象,也不会处理该对象引用的其他对象,即使这样的对象只有少数几个,也可能会导致很多的对象被排除在垃圾回收之外,从而对性能造成重大影响,极端情况下会引发 Disk Paging(物理内存与硬盘的虚拟内存交换数据),甚至造成 OutOfMemoryError。
91、抽象的(abstract)方法是否可同时是静态的(static),是否可同时是本地方法(native),是否可同时被 synchronized 修饰?
都不能。抽象方法需要子类重写,而静态的方法是无法被重写的,因此二者是矛盾的。本地方法是由本地代码(如 C 代码)实现的方法,而
抽象方法是没有实现的,也是矛盾的。synchronized 和方法的实现细节有关,抽象方法不涉及实现细节,因此也是相互矛盾的。
92、是否可以从一个静态(static)方法内部发出对非静态(non-static)方法的调用?
不可以,静态方法只能访问静态成员,因为非静态方法的调用要先创建对象,在调用静态方法时可能对象并没有被初始化。
有两种方式:
1). 实现 Cloneable 接口并重写 Object 类中的 clone()方法;
2). 实现 Serializable 接口,通过对象的序列化和反序列化实现克隆,可以实现真
正的深度克隆,代码如下。
测试代码:
注意:基于 序列 化和 反序 列化 实现 的克 隆不 仅仅 是深 度克 隆, 更重 要的 是通 过泛型限 定, 可以 检查 出要 克隆 的对 象是 否支 持 序 列化 ,这 项检 查是 编译 器完 成的 ,不是 在运 行时 抛出 异常 ,这种 是方 案明 显优 于使 用 Object 类的 clone 方法 克隆 对象。 让问题在 编译 的时 候暴 露出 来总 是好 过把 问题 留到 运行 时。
94、接口是否可继承(extends)接口?抽象类是否可实(implements)接口?抽象类是否可继承具体类(concreteclass)?
=======================================================================================================================================
接 口 可 以 继 承 接 口 , 而 且 支 持 多 重 继 承 。 抽 象 类 可 以 实 现 (implements)接 口 , 抽 象 类 可 继 承 具 体 类 也 可 以 继 承 抽 象 类 。
95、一个”.java”源文件中是否可以包含多个类(不是内部类)?有什么限制?
可以,但一个源文件中最多只能有一个公开类(public class)而且文件名必须和公开类的类名完全保持一致。
96、Anonymous Inner Class(匿名内部类)是否可以继承其它类?是否可以实现接口?
评论