1、抽象类和接口的区别?
- 他俩的作用基本上一样,都是在规范类中的代码该如何编写(定义方法而没有实现)
- 类是单继承的,抽象类也如此,无法继承多个类,所以引入接口的概念,来实现“多继承”
- 抽象类可以有构造方法,接口没有构造方法
- 抽象类中可以有普通的成员变量,接口中所有的成员变量都是public static final(公开的静态常量)的
- 抽象类中可以包含静态方法,接口中所有的方法都是public非静态抽象方法
2、什么是多态?特点?
- 不同的对象,经过同一个方法,得到的结果不同
- 实现多态,使用父类引用指向子类对象,子类重写父类的方法
- 父类 x = new 子类();
- 通常父类都会定义成抽象类或接口,因为父类中的方法注定要被子类重写,所以父类的方法写方法体就没有必要了。
- java语言是单继承的,但是可以多实现,通过接口去实现很多不是自身的方法,这就是多态。
3、String,StringBuffer,StringBuilder?
- String:操作少量的数据(变更不频繁,因为String是不可更改的)
- StringBuffer:操作大量频繁变更的数据(适合多线程,线程安全的)
- StringBuilder:操作大量频繁变更的数据(适合单线程,线程非安全的)
4、final,finally,finalize
- final:是java中常用的修饰符号
- 当修饰变量,该变量就是常量,值不能改变
- 当修饰方法,该方法就是最终的方法,不能被重写
- 当修饰类,该类就是最终的类(太监类),不能被继承
- finally:是try-catch语句的一部分,表示无论程序是否发生异常,都必须要执行的代码片段
- finalize:是一个方法的名称
- 这个方法在Object(祖宗类)中定义的,java中所有的类都会自动继承这个方法
- 该方法是GC(垃圾回收机制)中的一员,用来释放对象资源时自动调用的
5、ArrayList,Vector,LinkedList三者区别?
- ArrayList:变长数组,有下标,所有访问元素的效率高,而添加和删除的效率略低
- Vector:和ArrayList几乎一样,只有两点小区别:
- ArrayList:线程非安全,50%增长率
- Vector:线程安全,100%增长率
- LinkedList:双向链表(现实生活中的锁链),访问效率低,而添加和删除的效率高
6、求s=a+aa+aaa+aaaa+aa…a的值,其中a是一个数字。例如2+22+222+2222+22222(此时共有5个数相加),几个数相加有键盘控制
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("请输入一个数字:");
int a = input.nextInt();
System.out.print("请输入位数:");
int n = input.nextInt(); // 几个
int s = a; // 和
int x = a; // 永远是个数数字
for (int i = 1; i < n; i++) {
a = a * 10 + x; // 2*10+2 = 22
s = s + a; // 本次的和 = 上次的和+本次的a
}
System.out.println(s);// 24690
}
7、Comparable 和 Comparator 的区别
Comparable 比较的能力,因此某个类想要排序的话,被比较大小,需要实现这个接口
import java.util.ArrayList;
import java.util.Collections;
public class Test7_1 {
public static void main(String[] args) {
ArrayList<Person> list = new ArrayList<Person>();
list.add(new Person("a",30));
list.add(new Person("b",20));
list.add(new Person("c",50));
list.add(new Person("d",40));
//输出原始数据
list.forEach( p -> System.out.println( p ) );
System.out.println("-----------------------------");
//集合的顶级接口封装了一个排序的方法,我们使用一下
//list中的类必须要实现Comparable接口,才能具备排序的能力,最终才能调用下面的sort方法
Collections.sort(list);
//输出排序后的数据
list.forEach( p -> System.out.println( p ) );
}
}
class Person implements Comparable<Person>{
private String name;
private int age;
public Person(String name , int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public int compareTo(Person o) {
return this.age- o.age;
}
}
Comparator代表的是一种角色,这个角色的功能是对传入的两个元素进行大小的比较
最好定义比较规则时,规则的字段最好是整数(int)
import java.util.ArrayList;
import java.util.Comparator;
public class Test7_2 {
// 既可以身高升序,也可以身高降序,要必须要满足开闭原则,所以格外定义排序的规则类
public static void main(String[] args) {
ArrayList<Student> list = new ArrayList<Student>();
list.add(new Student("西施", 168));
list.add(new Student("貂蝉", 157));
list.add(new Student("杨玉环", 171.2));
list.add(new Student("王昭君", 163));
list.add(new Student("孙国安", 171.5));
// 原始数据
list.forEach(stu -> System.out.println(stu));
System.out.println("----------------------");
System.out.println("升序");
list.sort(new StudentHeightSheng()); // 排序
list.forEach(stu -> System.out.println(stu));
System.out.println("----------------------");
System.out.println("降序");
list.sort(new StudentHeightJiang()); // 排序
list.forEach(stu -> System.out.println(stu));
}
}
//小->大
class StudentHeightSheng implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
double d = o1.getHeight() - o2.getHeight();
int i = (int) Math.floor(d);
return i;
}
}
//大->小
class StudentHeightJiang implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
double d = o2.getHeight() - o1.getHeight();
int i = (int) Math.floor(d);
return i;
}
}
class Student {
private String name;
private double height; // 身高
@Override
public String toString() {
return "Student [name=" + name + ", height=" + height + "]";
}
public Student(String name, double height) {
this.name = name;
this.height = height;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
}
8、冒泡排序
public static void main(String args[]) {
int arr[] = { 2, 3, 5, 1, 4 };
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr.length - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
for (int i : arr) {
System.out.print(i + " ");
}
}
9、单例模式
/**懒汉式*/
public class Sun{
private Sun(){}
private static Sun sun = null;
public static Sun getSingle(){
if(sun == null){
sun = new Sun();
}
return sun;
}
}
/**饿汉式*/
public class Moon{
private Moon(){}
private static Moon m = new Moon();
public static Moon getSingle(){
return m;
}
}
10、一个“.java”源文件中是否可以包括多个类?有什么限制?
- 一个java源文件可以包含N个类,但是public修饰的类只能有一个
- public修饰的类和文件名要一致
11、什么是封装?为什么要用封装?
- 将类的属性进行私有化的过程,就是封装
- 更好的保护类的安全
- 想想人类为什么要盖私人的房子,因为私人的物品要放在房子中保护起来,不让别人随便的看和使用。
12、什么是类?什么是对象?
- 官方的回答:类是实例的抽象,对象是类的具体实现.
- 类就是人类,对象就是自己.
13、java中有几种基本数据类型?
-
整型
- byte -2的7次方 ~ 2的7次方-1
- short -2的15次方 ~ 2的15次方-1
- int -2的31次方 ~ 2的31次方-1
- long -2的63次方 ~ 2的63次方-1
-
浮点型
-
float 32位单精度浮点型,占位8位
-
double 64位双精度浮点型,占位16位
float x1 = 3.123456789123456789f; double x2 = 3.123456789123456789; System.out.println(x1); System.out.println(x2); 结果: 3.1234567 3.123456789123457
-
-
布尔型 boolean
-
字符型 char
14、error和exception有什么区别?
- error:非严重错误,仅靠程序是无法解决的。
- 未成年人,伤人事件
- exception:异常,异常是修改代码是可以解决的。
- 车祸(基本上不会发生,只有特殊情况下才会发生)
15、override和overload有什么区别?
- override重写
- 发生在继承关系中
- 方法名一致,参数要一致,返回值一样或其子类,权限修饰符不能严于父类
- overload重载
- 发生在本类中
- 方法名一致,参数不一致,返回值无关,权限修饰符无关
16、求100~999之间的水仙花数,各个位数的立方和还是本身。 153 = 111 + 555 + 333
public static void main(String[] args) {
for (int i = 100; i <= 999; i++) {
// i = 123
int ge = i % 10; // 123%10 -> 3
int shi = i / 10 % 10; // 123/10 -> 12 %10 -> 2
int bai = i / 100;
if (i == ge * ge * ge + shi * shi * shi + bai * bai * bai) {
System.out.println(i);
}
}
}
17、使用循环计算1+1/2!+1/3!..1/20!
// 1/1*1 + 1/1*2 + 1/1*2*3...
public static void main(String[] args) {
double he = 0; // 和
double temp = 1;// 阶乘
int i = 1; // 开始
int n = 20; // 结束
while (i <= n) {
he = he + temp;
i++;
temp = temp * 1 / i;
}
System.out.println(he);
}
18、斐波那契数列,1、1、2、3、5、8、13、21…按照此规律,输出前20个数字
public static void main(String[] args) {
int a = 1;
int b = 1;
System.out.println(a);
System.out.println(b);
for (int i = 3; i <= 20; i++) {
int c = a + b;
a = b;
b = c;
System.out.println(c);
}
}