最近准备换一份工作!总结 了一些面试题
问题1. 什么是面向对象? --> 面向对象就是一种编程思想. 更符合我们人们思考问题的一种习惯. 将复杂的问题简单化, 将我们从执行者的位置变成了指挥者. 问题2. 面向对象和面向过程的区别? --> 面向过程: 强调的是过程, 通过第一步,第二步, 一步步的完成我们需要的功能. 面向对象: 强调的是对象, 对象当中有具体的方法,帮我们实现要完成的功能 问题3. 类和对象的关系? --> 类: 是一组相关的属性和行为的集合, 我们java描述现实事物都是通过类的形式 可以把类看做为一个模子,或者是一张图纸, 我们可以通过类去创建对象. 对象: 就是具体存在的事物. 问题4. 成员变量和局部变量的区别? --> 1. 位置不同: 成员变量: 在类中,方法外. 局部变量: 在方法中,或方法的声明上. 2. 内存位置不同: 成员变量: 因为所属于对象,所以在堆内存中 局部变量: 因为所属于方法,坐在在栈内存中 3. 生命周期不同: 成员变量: 随着对象的创建而创建, 随着对象的消失而消失 局部变量: 随着方法的调用而存在, 随着方法的弹栈而消失 4. 初始化值不同: 成员变量: 有默认初始化值 局部变量: 没有默认初始化值, 使用之前必须赋值才能使用. 问题5. 解释下面向对象的特征,各自的好处和弊端是什么? --> 封装, 继承, 多态. 封装概述: 隐藏实现细节, 仅对外提供公共的访问方式 我们通常是通过private关键字修饰成员变量,并提供对应的set和get方法. 问题: 封装就是私有吗? --> 私有仅仅是封装的一种体现形式,不能说封装就是私有. 好处: 提高了代码的复用性, 提高了代码的安全性. 弊端: 硬要说的话,只能是调用成员变量的时候,相对来说麻烦一点. 继承概述: 让类与类之间产生了关系,子父类关系. 子类可以直接访问父类中非私有的成员 特点: 只支持单继承, 不支持多继承, 但是支持多层继承. 好处: 提高了代码的复用性, 提高了代码的维护性, 是多态的前提 弊端: 开发讲究高内聚低耦合, 而继承提高了耦合性. 耦合性: 类与类之间的关系过于紧密. 多态概述: 事物存在的多种形态 多态要有三个前提 a, 要有继承关系 b, 要有方法的重写 c, 要有父类引用指向子类对象. 好处: 提高了代码维护性(因为有继承保证), 提高了代码的扩展性. 扩展性: 可以将方法的形参定义为父类类型, 这样此方法就能接受这个父类的任意子类对象. 弊端: 不能调用子类特有的属性和行为, 要想使用, 必须向下转型. 调用成员的规则: 1. 成员变量: 编译看左边(父类), 运行看左边(父类). ps: 多态调用成员变量的时候,因为是父类的引用所以只能看到的是堆内存中super的一小块区域 2. 成员方法: 编译看左边(父类), 运行看右边(子类). 动态绑定. 3. 静态变量: 编译看左边(父类), 运行看左边(父类). 问题6. 匿名对象是什么? 特点是什么? --> 没有名字的对象. 特点: 因为没有名字记录住它的引用,所以在调用完毕之后就会变成垃圾 这里也说出了什么时候使用匿名对象 --> 仅对方法进行一次调用的时候, 推荐使用匿名对象. 好处: 可以当做参数进行传递. 问题7. 构造方法的特点和作用? --> 特点: 每创建一次对象, 就会执行一次, 由系统帮我们调用. 作用: 用于给对象中的数据(属性)进行初始化的. 格式: 方法名与类名相同,大小写也要一致. 没有返回值类型, 连void都没有. 注意: //this语句和super语句不能同时出现. 子类所有的空参构造,默认都会访问父类的空参构造, 因为每一句构造方法中都默认隐藏了super. 一个类中如果没有手动给出构造方法, 系统将会默认提供一个空参的构造方法. 但是一但手动给出了有参构造, 系统将不会再提供默认的空参构造. 问题: 构造方法可以有return语句吗? --> 可以有return语句, 但是return后面不能有具体的值. 问题: 如果父类中没有空参构造方法,子类怎么办? --> 如果没有空参的, 肯定有有参的, 可以通过super直接访问. //也可以通过this间接访问. 问题: 构造方法可以手动调用吗? --> 不能手动调用,但是可以通过this和super进行访问. public Person(){ this("",0); // 这种叫做访问 } public Person(String name, int age){ super(name,age); } Person p = new Person(); p.Person(); // 这种叫做手动调用. 问题8. 解释什么是方法的重写和重载,两者有什么区别? --> 重载: 在同一个类中,方法名相同, 参数列表不同, 与返回值类型无关. 重写: 在子父类中, 出现了方法声明一模一样的方法, 但是返回值类型可以是子父类的. 问题: 什么情况下需要重写? --> 当子类需要父类的功能, 而子类又有自己特有的实现方式, 这时就可以重写父类的方法. 这样既沿袭了父类的功能, 又定义了子类特有的内容 大白话理解: 觉得父类的方法不够好, 或者说过于老旧, 子类有自己的实现方法, 就可以对父类的方法进行重写. 问题: 重写有哪些注意事项? --> 子类不能重写父类中私有的方法, 因为访问不到, 更不能进行重写. 子类重写父类的方法时, 访问权限不能更低, 最好就一致. 静态只能覆盖静态, 其实算不上重写, 但是现象确实如此. 问题9. 什么是静态? 特点是什么? --> 静态指的就是java中的static关键字. 被静态修饰的成员, 被类的所有对象所共享, 又称之为类成员. 注意: 静态只能访问静态. 问题10: 静态变量和成员变量的区别? --> 1. 所属不同: 静态变量: 所属于类, 又称之为类变量. 成员变量: 所属于对象, 又称之为实例变量. 2. 内存中的位置不同: 静态变量: 在方法区中的静态区(共享区) 成员变量: 在堆内存中. 3. 加载时机不同: 静态变量: 随着类的加载而加载 成员变量:随着对象的创建而存在 4. 调用不同: 静态变量: 可以通过类名.调用,也可以通过对象名调用 成员变量: 只能通过对象名调用. 问题11. 说下final关键字? --> final可以修饰 -> 类, 方法, 变量. 类: 被final修饰的类, 不能被继承. 方法: 被final修饰的方法不能被重写. 变量: 被final修饰的变量, 就变成了常量, 只能被赋值一次. 问题: final修饰基本数据类型和引用数据类型的区别? 基本数据类型: 值不能发生改变 引用数据类型: 地址值不能发生改变. 问题: 局部内部类访问局部变量的时候为什么要加final? 延长变量的生命周期. 问题12. abstract关键字不能和哪些关键字共存? --> 1. final : 被final修饰的方法不能被重写,但是被抽象方法是强制要求重写的,两者冲突 2. private : 抽象方法是强制要求重写的,但是被private修饰的方法,子类访问不到,所以不能重写, 两者冲突 3. static : 如果可以用static修饰,那么就可以通过类名.调用抽象方法, 调用没有方法体的抽象方法没有任何意义. 问题13. 抽象类和接口的区别? --> 成员变量: 抽象类中的成员变量,可以是变量,也可以是常量. 接口中的成员变量,只能是常量,因为默认会加上三个关键字 public static final 成员方法: 抽象类中可以定义非抽象方法,也可以定义抽象方法. 接口中只能定义抽象方法. 问题: 抽象类中可以没有抽象方法吗? --> 可以,这样做的目的只有一个,就是为了不让其他类创建本类对象. 构造方法: 抽象类中有构造方法, 作用是用来给子类完成初始化的. 接口中没有构造方法. 问题: 什么时候用抽象类,什么时候用接口? 抽象类需要产生一种is a的关系, 谁是谁的一种, 并且, 抽象类中定义的都是共性的功能. 接口需要产生一种like a的关系, 谁像是什么什么的一种, 接口中定义的都是特性的行为. 理解: 把像的部分和相似的部分抽取到一个类中,简单来说,抽象类中定义的都是共性的功能. 学生问题: 继承和抽象类什么时候用? 答案: 如果这个类中有的行为是强制要求子类实现的,定义为抽象类. 如果这个类中的行为,子类可用可不用,使用普通的继承即可. 问题: 什么时候用抽象方法? 强制要求子类做的事. 问题14. 解释下什么是匿名内部类? --> 匿名内部类就是局部内部类的一种简化写法. 格式: new 类名(){} --> 继承这个类 new 接口名(){} --> 实现这个接口. 问题: 什么时候使用匿名内部类? --> 仅对方法进行一次调用 new Demo(){ public void print1(){ } public void print2(){ } }.print1(); // 调用2就很麻烦了. 问题: 匿名内部类可以向下转型吗? --> 不可以,名字都不知道,怎么转. 问题15. java中的代码块分为哪些? --> 局部代码块, 构造代码块, 静态代码块, 同步代码块 局部代码块: 限定了变量的生命周期, 可以提早的释放内存. 构造代码块: 每创建一次对象的时候就会执行一次, 并且优先于构造方法执行. 静态代码块: 随着类的加载而执行, 且只执行一次, 一般用于连接数据库. 问题: 构造方法,构造代码块,静态代码块的执行顺序是什么? --> 静态代码块 --> 构造代码块 --> 构造方法. 问题16. 内部类的访问特点? --> 内部类访问外部类成员 可以直接访问, 包括私有 外部类访问内部类 必须创建对象访问. 问题1. ==号和equals的区别? --> ==号可以比较基本数据类型,也可以比较引用数据类型 比较基本数据类型比较的是值. 比较引用数据类型比较的是地址值. equals方法只能比较引用数据类型. 如果没有重写Object中equals方法,那么默认比较的也是地址值. 如果想要按照自己的意思进行比较,可以重写equals方法. 问题2. Stirng,StringBuffer,StringBuilder的区别? --> String是一个不可变的字符序列. StringBuffer和StringBulider是可变的字符序列,是字符串的缓冲区. StringBuffer和StringBuilder的区别? --> StringBuffer是jdk1.0版本出现的,是线程安全的. StringBuilder是jdk1.5版本出现的,是线程不安全的. 问题3. 手写一个冒泡排序,选择排序. --> 必须会写, 背也得背下来
/* * 冒泡排序 * 1,返回值类型,void * 2,参数列表,int[] arr * 第一次:arr[0]与arr[1],arr[1]与arr[2],arr[2]与arr[3],arr[3]与arr[4]比较4次 第二次:arr[0]与arr[1],arr[1]与arr[2],arr[2]与arr[3]比较3次 第三次:arr[0]与arr[1],arr[1]与arr[2]比较2次 第四次:arr[0]与arr[1]比较1次 */ public static void bubbleSort(int[] arr) { for (int i = 0; i < arr.length - 1; i++) { //外循环只需要比较arr.length-1次就可以了 for (int j = 0; j < arr.length - 1 - i; j++) { //-1为了防止索引越界,-i为了提高效率 if(arr[j] > arr[j+1]) { /*int temp = arr[j]; arr[j] = arr[j + 1]; arr[j+1] = temp;*/ swap(arr,j,j+1); } } } } /* * 选择排序 * 1,返回值类型void. * 2,参数列表int[] arr. * * 第一次:arr[0]分别与arr[1-4]比较,比较4次 第二次:arr[1]分别与arr[2-4]比较,比较3次 第三次:arr[2]分别与arr[3-4]比较,比较2次 第四次:arr[3]与arr[4]比较,比较1次 */ public static void selectSort(int[] arr) { for (int i = 0; i < arr.length - 1; i++) { //只需要比较arr.length-1次 for (int j = i + 1; j < arr.length; j++) { if(arr[i] > arr[j]) { /*int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp;*/ swap(arr,i,j); } } } } 问题4. 说出5个jdk1.5版本的新特性 --> 静态导入 增强for循环 for(数据类型 变量名: 要遍历的数组或集合){ } 枚举 自动拆装箱 Interger i = 100; int num = i; 可变参数 public void method(int ... num){ } 泛型