Java| 面试题(2)
程序员文章站
2022-05-06 17:49:44
...
文章目录
面试题1:类初始化和实例初始化
以下代码运行结果:
/**
* ClassName: Father
* Date: 2020/2/27 2:10
* author: Oh_MyBug
* version: V1.0
*/
public class Father {
private int i = test();
private static int j = method(); // 父类的静态变量显示赋值代码
static {
System.out.print("(1)"); // 父类的静态代码块
}
Father(){
System.out.print("(2)");
}
{
System.out.print("(3)");
}
public int test(){
System.out.print("(4)");
return 1;
}
public static int method(){
System.out.print("(5)");
return 1;
}
}
/**
* ClassName: Son
* Date: 2020/2/27 2:13
* author: Oh_MyBug
* version: V1.0
*/
public class Son extends Father {
private int i = test();
private static int j =method(); // 子类的静态变量显示赋值代码
static {
System.out.print("(6)"); // 子类的静态代码块
}
Son(){
// super(); // 写或不写都在,在子类构造器中一定会调用父类构造器
System.out.print("(7)");
}
{
System.out.print("(8)");
}
public int test(){
System.out.print("(9)");
return 1;
}
public static int method(){
System.out.print("(10)");
return 1;
}
public static void main(String[] args){
Son s1 = new Son();
System.out.println();
Son s2 = new Son();
}
}
运行结果:
(5)(1)(10)(6)(9)(3)(2)(9)(8)(7)
(9)(3)(2)(9)(8)(7)
考点
- 类初始化过程
- 一个类要创建实例需要先加载并初始化该类
- main方法所在的类需要先加载和初始化
- 一个子类要初始化需要先初始化父类
- 一个类初始化就是执行() 方法
- () 方法由静态类变量显示赋值代码和静态代码块组成
- 类变量显示赋值代码和静态代码块从上到下顺序执行
- () 方法只执行一次
- 一个类要创建实例需要先加载并初始化该类
- 实例初始化过程
- 实例初始化就是执行() 方法
- () 方法可能重载有多个,有几个构造器就有几个() 方法
- () 方法由非静态实例变量显示赋值代码和非静态代码块、对应构造器代码组成
- 非静态实例变量显示赋值代码和非静态代码从上到下顺序执行,而对应构造器的代码最后执行
- 每次创建实例对象,调用对应构造器,执行的就是对应的() 方法
- () 方法的首行是super() 或super(实参列表),即对应父类的() 方法
- 实例初始化就是执行() 方法
- 方法的重写Override
- 哪些方法不可以被重写?
- final方法
- 静态方法
- private等子类中不可见方法
- 对象的多态性
- 子类如果重写了父类的方法,通过子类对象调用的一定是自类重写过的代码
- 非静态方法默认的调用对象是this
- this对象在构造器或者说() 方法中就是正在创建的对象
- 哪些方法不可以被重写?
面试题2:方法的参数传递机制
以下代码运行结果
import java.util.Arrays;
/**
* ClassName: Exam4
* Date: 2020/2/27 10:20
* author: Oh_MyBug
* version: V1.0
*/
public class Exam4 {
public static void main(String[] args) {
int i = 1;
String str = "hello";
Integer num = 2;
int[] arr = {1,2,3,4,5};
MyData my = new MyData();
change(i,str,num,arr,my);
System.out.println("i = " + i);
System.out.println("str = " + str);
System.out.println("num = " + num);
System.out.println("arr = " + Arrays.toString(arr));
System.out.println("my.a = " + my.a);
}
public static void change(int j, String s, Integer n, int[] a, MyData m){
j += 1;
s += "world";
n += 1;
a[0] += 1;
m.a += 1;
}
}
class MyData{
int a = 10;
}
运行结果
i = 1
str = hello
num = 2
arr = [2, 2, 3, 4, 5]
my.a = 11
考点
- 方法的参数传递机制
- String、包装类等对象的不变性
方法的参数传递机制
- 形参是基本数据类型
- 传递数值
- 实参是引用数据类型
- 传递地址值
- 特殊的类型:String、包装类等对象不可变性
面试题3:递归与迭代
编程题:有n步台阶,一次只能上一步或2步,共有多少种走法?
- 递归
- 循环迭代
递归
import org.junit.Test;
/**
* ClassName: TestStep
* Date: 2020/2/27 10:44
* author: Oh_MyBug
* version: V1.0
*/
public class TestStep {
@Test
public void test(){
long start = System.currentTimeMillis();
System.out.println("result = " + f(40));
long end = System.currentTimeMillis();
System.out.println("runtime = " + (end - start));
}
// 实现f(n):求n步台阶,一共有几种走法
public int f(int n){
if (n < 1){
throw new IllegalArgumentException(n + "不能小于1");
}
if (n == 1 || n == 2){
return n;
}
return f(n-2) + f(n-1);
}
}
运行结果
result = 165580141
runtime = 1226
循环迭代
import org.junit.Test;
/**
* ClassName: TestStep1
* Date: 2020/2/27 11:30
* author: Oh_MyBug
* version: V1.0
*/
public class TestStep1 {
@Test
public void test(){
long start = System.currentTimeMillis();
System.out.println("result = " + loop(40));
long end = System.currentTimeMillis();
System.out.println("runtime = " + (end - start));
}
public int loop(int n){
if (n < 1){
throw new IllegalArgumentException(n + "不能小于1");
}
if (n == 1 || n== 2){
return n;
}
int one = 2;
int two = 1;
int sum = 0;
for (int i = 0; i < n - 2; i ++) {
sum = one + two;
two = one;
one = sum;
}
return sum;
}
}
运行结果
result = 165580141
runtime = 30
总结
- 方法调用自身称为递归,利用变量的原值推出新值称为迭代
- 递归
- 优点:大问题转化为小问题,可以减少代码量,同时代码精简,可读性好
- 缺点:递归调用浪费了空间,而且递归太深容易造成堆栈的溢出
- 迭代
- 优点:代码运行效率好,因为时间只因循环次数增加而增加,而且没有额外的空间开销
- 缺点:代码不如递归简洁,可读性好
上一篇: ubuntu下python实现虚拟串口
下一篇: 拓展:Vue.js 面试、常见问题答疑