Java 面试题,
Java 面试题,
第一章 Java 语言基础
1.1 Java 语言基本知识
1.1.1 基本概念
【1】Java语言具有哪些特点?
Java为解释型语言,编译器会把Java代码变成“中间代码”,然后在JVM(Java Virtual Machine,Java 虚拟机)上解释执行。由于中间代码与平台无关,因此 Java 语言可以跨平台执行,具有很好的可移植性。
类库简化了开发人员的程序设计工作,同时缩短了项目的开发时间。Java 语言提供了对多线程和网络通信的支持,提供了垃圾回收器,使开发人员从对内存的管理中解脱出来。
Applet、Servlet 和 JSP 可以用来开发 Web 应用程序,Socket、RMI 可以用来开发分布式应用程序。
Java 语言经常被用在网络环境中,为了增强程序的安全性,Java 语言提供了一个防止恶意代码攻击的安全机制(数组边界检测和 byte code校验等)。
Java 的强类型机制、垃圾回收器、异常处理和安全检查机制使得使用 Java 语言编写的程序有很好的健壮性。
Java 语言去除了 C++语言中难以理解、容易混淆的特性,例如头文件、指针、结构、单元、运算符重载、虚拟基础类、多重继承等。
【2】Java 整型的字节序是( )。
A.Little-Endian(小端) B.Big-Endian(大端)
C.由运行程序的 CPU 决定 D.由编译程序的 CPU 决定
Java 是一种跨平台的语言,Java 字节序指的是在 Java 虚拟机中多字节类型数据的存放顺序,Java 字节序是 Big-Endian(大端)。
字节序是指多字节数据在计算机内存中存储或者网络传输时各字节的存储顺序。通常有 Little-Endian(小端)与 Big-Endian(大端)两种方式。
- Little-Endian(小端)是指低位字节存放在内存的低地址端,高位字节存放在内存的高地址端。
- Big-Endian(大端)是指高位字节存放在内存的低地址端,低位字节存放在内存的高地址端。
Java 提供了一个类库可以用来获取 CPU 是大端还是小端:java.nio.ByteOrder.nativeOrder()。
在计算机系统中,所有的存储都是以字节(一个字节占用 8 bit)为单位进行存储的。在大部分编程语言中,除了占 1 个字节的 char 数据类型外,还有占多个字节的其他数据类型。既可以使用大端的方式存储,也可以使用小端的方式来存储占用多个字节的数据。不同的编程语言,不同的处理器可能会采用不同的存储方式。
【3】下面关于 Java 语言的描述中,正确的是( )。
A.可以使用 goto 跳出循环 B.关键字 final 修饰的类无法被继承
C.String 对象的内容是无法修改的 D.Java 类可以实现多个接口
在 Java 语言中,goto 是保留关键字,没有 goto 语句,也没有任何使用 goto 关键字的地方。在特定情况下,通过特定的手段,也是可以实现 goto 功能的。
被 final 修饰的类是不能被继承的。
String 是不可变量,其内容是不能被修改的。
Java 语言不支持多重继承,但是可以通过实现多个接口的方式间接地实现多重继承。
【4】以下不是 Object 类的方法的是( )。
A.hashCode() B.finalize() C.notify() D.hasNext()
Object 类是类层次结构的根,在 Java 语言中,所有的类从根本上而言都继承自这个类。Object 类是 Java 语言中唯一没有父类的类,而其他所有的类,包括标准容器类,都继承了 Object 类。
Object 类源码:
package java.lang;
public class Object {
private static native void registerNatives();
static {
registerNatives();
}
public final native Class<?> getClass();
public native int hashCode();
public boolean equals(Object obj) {
return (this == obj);
}
protected native Object clone() throws CloneNotSupportedException;
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
public final native void notify();
public final native void notifyAll();
public final native void wait(long timeout) throws InterruptedException;
public final void wait(long timeout, int nanos) throws InterruptedException {
if (timeout < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (nanos < 0 || nanos > 999999) {
throw new IllegalArgumentException( "nanosecond timeout value out of range");
}
if (nanos > 0) {
timeout++;
}
wait(timeout);
}
public final void wait() throws InterruptedException {
wait(0);
}
protected void finalize() throws Throwable { }
}
【5】Math.round(12.5)的返回值等于( ),Math.round(12.5)的返回值等于( )。
Math 类主要提供了下面 5 个与取整相关的方法:
Math 类源码:
package java.lang;
import java.util.Random;
import sun.misc.FloatConsts;
import sun.misc.DoubleConsts;
public final class Math {
private Math() {}
public static final double E = 2.7182818284590452354;
public static final double PI = 3.14159265358979323846;
public static double sin(double a) {
return StrictMath.sin(a); // default impl. delegates to StrictMath
}
public static double cos(double a) {
return StrictMath.cos(a); // default impl. delegates to StrictMath
}
public static double tan(double a) {
return StrictMath.tan(a); // default impl. delegates to StrictMath
}
public static double asin(double a) {
return StrictMath.asin(a); // default impl. delegates to StrictMath
}
public static double acos(double a) {
return StrictMath.acos(a); // default impl. delegates to StrictMath
}
public static double atan(double a) {
return StrictMath.atan(a); // default impl. delegates to StrictMath
}
public static double toRadians(double angdeg) {
return angdeg / 180.0 * PI;
}
public static double toDegrees(double angrad) {
return angrad * 180.0 / PI;
}
public static double exp(double a) {
return StrictMath.exp(a); // default impl. delegates to StrictMath
}
public static double log(double a) {
return StrictMath.log(a); // default impl. delegates to StrictMath
}
public static double log10(double a) {
return StrictMath.log10(a); // default impl. delegates to StrictMath
}
public static double sqrt(double a) {
return StrictMath.sqrt(a);
}
public static double cbrt(double a) {
return StrictMath.cbrt(a);
}
public static double IEEEremainder(double f1, double f2) {
return StrictMath.IEEEremainder(f1, f2); // delegate to StrictMath
}
public static double ceil(double a) {
return StrictMath.ceil(a); // default impl. delegates to StrictMath
}
public static double floor(double a) {
return StrictMath.floor(a); // default impl. delegates to StrictMath
}
public static double rint(double a) {
return StrictMath.rint(a); // default impl. delegates to StrictMath
}
public static double atan2(double y, double x) {
return StrictMath.atan2(y, x); // default impl. delegates to StrictMath
}
public static double pow(double a, double b) {
return StrictMath.pow(a, b); // default impl. delegates to StrictMath
}
public static int round(float a) {
int intBits = Float.floatToRawIntBits(a);
int biasedExp = (intBits & FloatConsts.EXP_BIT_MASK) >> (FloatConsts.SIGNIFICAND_WIDTH - 1);
int shift = (FloatConsts.SIGNIFICAND_WIDTH - 2 + FloatConsts.EXP_BIAS) - biasedExp;
if ((shift & -32) == 0) {
int r = ((intBits & FloatConsts.SIGNIF_BIT_MASK) | (FloatConsts.SIGNIF_BIT_MASK + 1));
if (intBits < 0) {
r = -r;
}
return ((r >> shift) + 1) >> 1;
} else {
return (int) a;
}
}
public static long round(double a) {
long longBits = Double.doubleToRawLongBits(a);
long biasedExp = (longBits & DoubleConsts.EXP_BIT_MASK) >> (DoubleConsts.SIGNIFICAND_WIDTH - 1);
long shift = (DoubleConsts.SIGNIFICAND_WIDTH - 2 + DoubleConsts.EXP_BIAS) - biasedExp;
if ((shift & -64) == 0) {
long r = ((longBits & DoubleConsts.SIGNIF_BIT_MASK) | (DoubleConsts.SIGNIF_BIT_MASK + 1));
if (longBits < 0) {
r = -r;
}
return ((r >> shift) + 1) >> 1;
} else {
return (long) a;
}
}
private static final class RandomNumberGeneratorHolder {
static final Random randomNumberGenerator = new Random();
}
public static double random() {
return RandomNumberGeneratorHolder.randomNumberGenerator.nextDouble();
}
public static int addExact(int x, int y) {
int r = x + y;
if (((x ^ r) & (y ^ r)) < 0) {
throw new ArithmeticException("integer overflow");
}
return r;
}
public static long addExact(long x, long y) {
long r = x + y;
if (((x ^ r) & (y ^ r)) < 0) {
throw new ArithmeticException("long overflow");
}
return r;
}
public static int subtractExact(int x, int y) {
int r = x - y;
if (((x ^ y) & (x ^ r)) < 0) {
throw new ArithmeticException("integer overflow");
}
return r;
}
public static long subtractExact(long x, long y) {
long r = x - y;
if (((x ^ y) & (x ^ r)) < 0) {
throw new ArithmeticException("long overflow");
}
return r;
}
public static int multiplyExact(int x, int y) {
long r = (long)x * (long)y;
if ((int)r != r) {
throw new ArithmeticException("integer overflow");
}
return (int)r;
}
public static long multiplyExact(long x, long y) {
long r = x * y;
long ax = Math.abs(x);
long ay = Math.abs(y);
if (((ax | ay) >>> 31 != 0)) {
if (((y != 0) && (r / y != x)) ||
(x == Long.MIN_VALUE && y == -1)) {
throw new ArithmeticException("long overflow");
}
}
return r;
}
public static int incrementExact(int a) {
if (a == Integer.MAX_VALUE) {
throw new ArithmeticException("integer overflow");
}
return a + 1;
}
public static long incrementExact(long a) {
if (a == Long.MAX_VALUE) {
throw new ArithmeticException("long overflow");
}
return a + 1L;
}
public static int decrementExact(int a) {
if (a == Integer.MIN_VALUE) {
throw new ArithmeticException("integer overflow");
}
return a - 1;
}
public static long decrementExact(long a) {
if (a == Long.MIN_VALUE) {
throw new ArithmeticException("long overflow");
}
return a - 1L;
}
public static int negateExact(int a) {
if (a == Integer.MIN_VALUE) {
throw new ArithmeticException("integer overflow");
}
return -a;
}
public static long negateExact(long a) {
if (a == Long.MIN_VALUE) {
throw new ArithmeticException("long overflow");
}
return -a;
}
public static int toIntExact(long value) {
if ((int)value != value) {
throw new ArithmeticException("integer overflow");
}
return (int)value;
}
public static int floorDiv(int x, int y) {
int r = x / y;
if ((x ^ y) < 0 && (r * y != x)) {
r--;
}
return r;
}
public static long floorDiv(long x, long y) {
long r = x / y;
if ((x ^ y) < 0 && (r * y != x)) {
r--;
}
return r;
}
public static int floorMod(int x, int y) {
int r = x - floorDiv(x, y) * y;
return r;
}
public static long floorMod(long x, long y) {
return x - floorDiv(x, y) * y;
}
public static int abs(int a) {
return (a < 0) ? -a : a;
}
public static long abs(long a) {
return (a < 0) ? -a : a;
}
public static float abs(float a) {
return (a <= 0.0F) ? 0.0F - a : a;
}
public static double abs(double a) {
return (a <= 0.0D) ? 0.0D - a : a;
}
public static int max(int a, int b) {
return (a >= b) ? a : b;
}
public static long max(long a, long b) {
return (a >= b) ? a : b;
}
private static long negativeZeroFloatBits = Float.floatToRawIntBits(-0.0f);
private static long negativeZeroDoubleBits = Double.doubleToRawLongBits(-0.0d);
public static float max(float a, float b) {
if (a != a)
return a; // a is NaN
if ((a == 0.0f) &&
(b == 0.0f) &&
(Float.floatToRawIntBits(a) == negativeZeroFloatBits)) {
return b;
}
return (a >= b) ? a : b;
}
public static double max(double a, double b) {
if (a != a)
return a; // a is NaN
if ((a == 0.0d) &&
(b == 0.0d) &&
(Double.doubleToRawLongBits(a) == negativeZeroDoubleBits)) {
return b;
}
return (a >= b) ? a : b;
}
public static int min(int a, int b) {
return (a <= b) ? a : b;
}
public static long min(long a, long b) {
return (a <= b) ? a : b;
}
public static float min(float a, float b) {
if (a != a)
return a; // a is NaN
if ((a == 0.0f) &&
(b == 0.0f) &&
(Float.floatToRawIntBits(b) == negativeZeroFloatBits)) {
return b;
}
return (a <= b) ? a : b;
}
public static double min(double a, double b) {
if (a != a)
return a; // a is NaN
if ((a == 0.0d) &&
(b == 0.0d) &&
(Double.doubleToRawLongBits(b) == negativeZeroDoubleBits)) {
return b;
}
return (a <= b) ? a : b;
}
public static double ulp(double d) {
int exp = getExponent(d);
switch(exp) {
case DoubleConsts.MAX_EXPONENT+1: // NaN or infinity
return Math.abs(d);
case DoubleConsts.MIN_EXPONENT-1: // zero or subnormal
return Double.MIN_VALUE;
default:
assert exp <= DoubleConsts.MAX_EXPONENT && exp >= DoubleConsts.MIN_EXPONENT;
exp = exp - (DoubleConsts.SIGNIFICAND_WIDTH-1);
if (exp >= DoubleConsts.MIN_EXPONENT) {
return powerOfTwoD(exp);
}
else {
return Double.longBitsToDouble(1L <<
(exp - (DoubleConsts.MIN_EXPONENT - (DoubleConsts.SIGNIFICAND_WIDTH-1)) ));
}
}
}
public static float ulp(float f) {
int exp = getExponent(f);
switch(exp) {
case FloatConsts.MAX_EXPONENT+1: // NaN or infinity
return Math.abs(f);
case FloatConsts.MIN_EXPONENT-1: // zero or subnormal
return FloatConsts.MIN_VALUE;
default:
assert exp <= FloatConsts.MAX_EXPONENT && exp >= FloatConsts.MIN_EXPONENT;
exp = exp - (FloatConsts.SIGNIFICAND_WIDTH-1);
if (exp >= FloatConsts.MIN_EXPONENT) {
return powerOfTwoF(exp);
}
else {
return Float.intBitsToFloat(1 <<
(exp - (FloatConsts.MIN_EXPONENT - (FloatConsts.SIGNIFICAND_WIDTH-1)) ));
}
}
}
public static double signum(double d) {
return (d == 0.0 || Double.isNaN(d))?d:copySign(1.0, d);
}
public static float signum(float f) {
return (f == 0.0f || Float.isNaN(f))?f:copySign(1.0f, f);
}
public static double sinh(double x) {
return StrictMath.sinh(x);
}
public static double cosh(double x) {
return StrictMath.cosh(x);
}
public static double tanh(double x) {
return StrictMath.tanh(x);
}
public static double hypot(double x, double y) {
return StrictMath.hypot(x, y);
}
public static double expm1(double x) {
return StrictMath.expm1(x);
}
public static double log1p(double x) {
return StrictMath.log1p(x);
}
public static double copySign(double magnitude, double sign) {
return Double.longBitsToDouble((Double.doubleToRawLongBits(sign) & (DoubleConsts.SIGN_BIT_MASK)) | (Double.doubleToRawLongBits(magnitude) & (DoubleConsts.EXP_BIT_MASK | DoubleConsts.SIGNIF_BIT_MASK)));
}
public static float copySign(float magnitude, float sign) {
return Float.intBitsToFloat((Float.floatToRawIntBits(sign) & (FloatConsts.SIGN_BIT_MASK)) | (Float.floatToRawIntBits(magnitude) & (FloatConsts.EXP_BIT_MASK | FloatConsts.SIGNIF_BIT_MASK)));
}
public static int getExponent(float f) {
return ((Float.floatToRawIntBits(f) & FloatConsts.EXP_BIT_MASK) >> (FloatConsts.SIGNIFICAND_WIDTH - 1)) - FloatConsts.EXP_BIAS;
}
public static int getExponent(double d) {
return (int)(((Double.doubleToRawLongBits(d) & DoubleConsts.EXP_BIT_MASK) >> (DoubleConsts.SIGNIFICAND_WIDTH - 1)) - DoubleConsts.EXP_BIAS);
}
public static double nextAfter(double start, double direction) {
if (Double.isNaN(start) || Double.isNaN(direction)) {
return start + direction;
} else if (start == direction) {
return direction;
} else {
long transducer = Double.doubleToRawLongBits(start + 0.0d);
if (direction > start) { // Calculate next greater value
transducer = transducer + (transducer >= 0L ? 1L:-1L);
} else { // Calculate next lesser value
assert direction < start;
if (transducer > 0L)
--transducer;
else
if (transducer < 0L )
++transducer;
else
transducer = DoubleConsts.SIGN_BIT_MASK | 1L;
}
return Double.longBitsToDouble(transducer);
}
}
public static float nextAfter(float start, double direction) {
if (Float.isNaN(start) || Double.isNaN(direction)) {
return start + (float)direction;
} else if (start == direction) {
return (float)direction;
} else {
int transducer = Float.floatToRawIntBits(start + 0.0f);
if (direction > start) {// Calculate next greater value
transducer = transducer + (transducer >= 0 ? 1:-1);
} else { // Calculate next lesser value
assert direction < start;
if (transducer > 0)
--transducer;
else
if (transducer < 0 )
++transducer;
else
transducer = FloatConsts.SIGN_BIT_MASK | 1;
}
return Float.intBitsToFloat(transducer);
}
}
public static double nextUp(double d) {
if( Double.isNaN(d) || d == Double.POSITIVE_INFINITY)
return d;
else {
d += 0.0d;
return Double.longBitsToDouble(Double.doubleToRawLongBits(d) + ((d >= 0.0d)?+1L:-1L));
}
}
public static float nextUp(float f) {
if( Float.isNaN(f) || f == FloatConsts.POSITIVE_INFINITY)
return f;
else {
f += 0.0f;
return Float.intBitsToFloat(Float.floatToRawIntBits(f) + ((f >= 0.0f)?+1:-1));
}
}
public static double nextDown(double d) {
if (Double.isNaN(d) || d == Double.NEGATIVE_INFINITY)
return d;
else {
if (d == 0.0)
return -Double.MIN_VALUE;
else
return Double.longBitsToDouble(Double.doubleToRawLongBits(d) + ((d > 0.0d)?-1L:+1L));
}
}
public static float nextDown(float f) {
if (Float.isNaN(f) || f == Float.NEGATIVE_INFINITY)
return f;
else {
if (f == 0.0f)
return -Float.MIN_VALUE;
else
return Float.intBitsToFloat(Float.floatToRawIntBits(f) + ((f > 0.0f)?-1:+1));
}
}
public static double scalb(double d, int scaleFactor) {
final int MAX_SCALE = DoubleConsts.MAX_EXPONENT + -DoubleConsts.MIN_EXPONENT + DoubleConsts.SIGNIFICAND_WIDTH + 1;
int exp_adjust = 0;
int scale_increment = 0;
double exp_delta = Double.NaN;
if(scaleFactor < 0) {
scaleFactor = Math.max(scaleFactor, -MAX_SCALE);
scale_increment = -512;
exp_delta = twoToTheDoubleScaleDown;
}
else {
scaleFactor = Math.min(scaleFactor, MAX_SCALE);
scale_increment = 512;
exp_delta = twoToTheDoubleScaleUp;
}
int t = (scaleFactor >> 9-1) >>> 32 - 9;
exp_adjust = ((scaleFactor + t) & (512 -1)) - t;
d *= powerOfTwoD(exp_adjust);
scaleFactor -= exp_adjust;
while(scaleFactor != 0) {
d *= exp_delta;
scaleFactor -= scale_increment;
}
return d;
}
public static float scalb(float f, int scaleFactor) {
final int MAX_SCALE = FloatConsts.MAX_EXPONENT + -FloatConsts.MIN_EXPONENT + FloatConsts.SIGNIFICAND_WIDTH + 1;
scaleFactor = Math.max(Math.min(scaleFactor, MAX_SCALE), -MAX_SCALE);
return (float)((double)f*powerOfTwoD(scaleFactor));
}
static double twoToTheDoubleScaleUp = powerOfTwoD(512);
static double twoToTheDoubleScaleDown = powerOfTwoD(-512);
static double powerOfTwoD(int n) {
assert(n >= DoubleConsts.MIN_EXPONENT && n <= DoubleConsts.MAX_EXPONENT);
return Double.longBitsToDouble((((long)n + (long)DoubleConsts.EXP_BIAS) << (DoubleConsts.SIGNIFICAND_WIDTH-1)) & DoubleConsts.EXP_BIT_MASK);
}
static float powerOfTwoF(int n) {
assert(n >= FloatConsts.MIN_EXPONENT && n <= FloatConsts.MAX_EXPONENT);
return Float.intBitsToFloat(((n + FloatConsts.EXP_BIAS) << (FloatConsts.SIGNIFICAND_WIDTH-1))& FloatConsts.EXP_BIT_MASK);
}
}
【6】下列关于 Java 语言基础知识的描述中,正确的是( )。
A.类是方法和变量的集合体 B.抽象类或接口可以被实例化
C.数组是无序数据的集合 D.类成员数据必须是公有的
类可以被理解为变量和方法的集合体。
抽象类和接口都不能被实例化。只有实现了抽象类的具体类和实现了接口方法的类才能被实例化。
数组是一些相同类型数据的集合。
类的数据类型可以是公开的,也可以是私有的,由于面向对象封装的特点,一般会把成员数据设计为私有的,然后提供公有的方法对其访问。
【7】
【8】下列描述中,正确的是( )。
A.Java 程序经编译后会产生 Machine Code(机器码)
B.Java 程序经编译后会产生 Byte Code(字节码)
C.Java 程序经编译后会产生 DLL(动态链接库)
D.以上描述都不正确
Java 语言为解释性语言,运行的过程为:源代码经过 Java 编译器编译成字节码(Byte Code),然后由 JVM(Java Virtual Machine,Java 虚拟机)解释执行。而 C/C++语言为编译型语言,源代码经过编译和链接后生成可执行的二进制代码。因此,Java 语言的执行速度比 C/C++语言慢,但是 Java 语言能够跨平台执行,而 C/C++语言不能够跨平台执行。
【9】Java 语言是从( )语言改进重新设计 。
A.BASIC B.C++ C.Pascal D.Ada
- BASIC 语言是一种为了让用户容易控制计算机开发的语言,其特点是简单易懂,且可以用解释和编译两种方法执行。
- C++语言是一种静态数据类型检查的、支持多重编程范式的通用程序设计语言,支持过程化程序设计、数据抽象、面向对象程序设计、泛型程序设计等多种程序设计风格。
- Pascal 语言是为提倡结构化编程而发明的语言。
- Ada 语言是美国军方为了整合不同语言开发的系统而发明的一种语言,其最大的特点是实时性,在 ADA95 中已加入面向对象内容。
- Java 语言是一种面向对象语言,从语法结构上看,与 C++语言类似。
【10】下列关于 Java 语言的描述中,正确的是( )。
A.Java 语言容许单独的过程与函数存在 B. Java 语言容许单独的方法存在
C.Java 语言中的方法属于类中的成员 D.Java语言中的方法必定隶属于某一类(对象)
Java 语言是纯面向对象的语言,任何变量与方法都必须定义在类中,方法与变量不能脱离类的定义而单独存在。在 Java 语言中,方法有两种:静态方法(类的方法)与非静态方法(实例的方法)。变量有两种:静态变量(类的变量)与非静态变量(实例的变量)。
【11】
【12】
【13】
相关文章
- 暂无相关文章
用户点评