JavaSE面试题(倒背如流版)

1、Float在JVM的表达方式及使用陷阱

//请写出本题的执行结果,并说明原因
float d1  = 423432423f;
float d2 = d1+1;
if(d1==d2){
    System.out.println("d1 == d2");
}else{
    Syetem.out.println("d1 != d2");
}

答案:为相等的,因为单精度的float浮点型在JVM内存中是以科学计数法进行表示的,
4.2343242E7,只保留到了小数点后的七位,那么d1与d2同样都是4.2343242E7
因此高精度的用double类型保存,尤其是在银行业务中,最好使用BigDecimal类进行加减乘除的运算。

2、随机生成30~100之间的整数

两种方法:
1)利用Math类的random()方法
2)java.util包下Random类的nextInt()方法

    /**
     * 利用java.util包下的Random类的nextInt()方法,参数设置上限,下限默认为0
     * @return 30~70随机整数
     */
    public Integer randomInt1() {
        int min = 30;
        int max = 100;
        int result = new Random().nextInt(max - min) + min;
        return result;
    }

    /**
     * Math工具类的random()方法,生成0~1的小数,手动扩大范围
     * @return 30~70随机整数
     */
    public Integer randomInt2() {
        int min = 30;
        int max = 100;
        //先生成0~1的随机小数,×70 : 0~70 随机小数; +30 : 30~70随机小数;
        int result = (int) (Math.random() * (max - min)) + min;
        return result;
    }

3、 列出1-1000的质数

    public static void main(String[] args) {
        for (int i = 2; i <= 1000; i++) {
            boolean flag = true;
            for (int j = 2; j < i; j++) {
                if(i%j == 0){
                    flag = false;
                    break;
                }

            }
            if (flag) {
                System.out.println(i);
            }
        }
    }

4、 静态和实例变量(方法)的区别

  • 实例变量属于某个对象的属性,只有使用new关键字实例化对象后才能使用;
    静态变量属于类本身。
  • 静态变量在JVM加载类字节码时创建,实例变量在实例化对象时创建。
  • 静态变量无法被垃圾回收释放,实例变量不再使用后会被回收
  • 静态变量存储在方法区中、实例变量存储在对象堆的内存中
  • 开发时推荐优先使用实例变量而减少静态变量的使用

5、类的加载顺序

原则:

1. 静态优先
2. 父类优先
3. 非静态块优先于构造函数

//请写出程序输出结果
//1. 静态优先
//2. 父类优先
//3. 非静态块优先于构造函数
public class ExecutionSequence {
    public static void main(String[] args) {
        new GeneralClass();
    }
}
class ParentClass{
    static {
        System.out.println("①我是父类静态块");
    }

    {
        System.out.println("②我是父类非静态块");
    }
    public ParentClass(){
        System.out.println("③我是父类构造函数");
    }
}

class GeneralClass extends ParentClass{
    static{
        System.out.println("④我是子类静态块");
    }

    {
        System.out.println("⑤我是子类非静态块");
    }

    public GeneralClass(){
        System.out.println("⑥我是子类构造函数");
    }

结果:

①我是父类静态块
④我是子类静态块
②我是父类非静态块
③我是父类构造函数
⑤我是子类非静态块
⑥我是子类构造函数

5、Java异常体系

图片说明

图片说明

  • Exception必须进行强制处理,try..catch..或者抛出
  • RuntimeException代表应用程序运行过程中产生的异常,它及它的子类并不需要显示处理,在编码阶段不要求强制进行处理。

6、String与字符串常量池

图片说明

  • true
  • true
  • false (s2是引用类型的,编译器在编译期间无法确定它的数值,这就意味着无法使用编译器对其进行优化,只有在运行时才能确定s2具体的值,因此即便s2+"def"等于"abcdef",也会产生一个新的内存地址,同时分配给s5,那么s4与s5的内存地址不再相等,于是返回false)
  • true (String类的equals方法比较的是字符串的内容)
  • false (s1的"adc"会存储在常量池中,而s6的new String("abc")不会在常量池中保存)

7、 String、StringBuffer、StringBuilder的区别

图片说明

  • String : 数据存放在常量池中,且由final修饰,每一个String创建后便不再发生变化。
  • StringBuffer: 使用sychronize关键字修饰,实现了线程同步。

8、面向对象的三大特征

- 继承
1) 面向对象最显著的特征
2)从已有的类中派生出新的类,新的类可以吸收已有类的属性和行为,并扩展新的功能
3)Java中并不支持多继承,单继承使得Java的继承关系很简单,一个类只能有一个父类,易于管理
4)父类也是子类的抽象化,子类是父类的具体化
5)在使用的过程中,继承主要的作用主要应用在对代码的抽象上,比如一个类的功能是向表A插入数据,另一个类是向表B插入数据,而向数据表插入数据前都需要获得数据库的连接,那么此时可以对这两个类抽象出一个父类,对获取数据库连接的方法进行抽象,这样子类只需要关注对具体的数据插入的操作就可以了,而获取连接的工作就交给它的父类自动完成。
继承的好处:
减少程序开发的重复度,同时增加了程序的健壮性

- 封装
1)将同一类事务的特征和功能包装到一起,只暴露对外调用的接口
2)封装也称为信息的隐藏,封装最典型的体现就是定义接口,接口中没有功能的实现,只有抽象的方法声明,作用就是每一个接口的实现类对接口进行实现,但是调用的时候通常是面对接口进行调用,对于使用者来说,只需要知道接口定义了哪些方法,这些方法是做什么的就可以了。对于接口内部的执行的操作不需要了解。
封装的好处:
1> 实现专业的分工,使用者与开发者分工明确
2> 减少代码的耦合,面向接口
3> 类内部的结构可以自由修改,只要接口的定义没有变化,使用者是无法感知到的
接口与抽象类的异同
图片说明
抽象类就是父类
注意:JDK8以上版本,接口可以有default方法,包含方法的实现

- 多态
1)最重要的操作
2)多态是同一个行为具有多个不同表现形式或形态的能力
3)多态是同一个接口,使用不同的实例而执行不同操作(例如有一个导出的接口,在这个接口下有两个实现类,一个是导出Excel一个是导出txt文本)

=============集合框架===============

1、请说明List与Set的区别

图片说明
List按照插入时的顺序依次保存,而Set无序或者需要自定义排序规则
ArrayList与LinkedList的区别
图片说明
Arraylist数据之间紧密相连
HashSet与TreeSet的区别
图片说明

  • Hash值的生成具有不确定性,故不能保证前后顺序
  • TreeSet在创建时可以设置一个排序规则

2、熟练使用Collection.sort()方法对List进行排序(实现Comparetor接口,实现其compare()方法,可基于Lambda表达式与泛型简化代码)

3、熟练使用两种方法对TreeSet进行排序

1)Java Bean 实现 compareble接口,这种又被称为自然排序

public class Employee implements Comparable<Employee>{

    //TreeSet采用红黑树进行实现,compareTo方法如果返回-1,则代表把传入至参数中的Employee对象放在红黑树的左子树,降序排列;返回1则代表升序排列,放在红黑树的右侧。
    @Override
    public int compareTo (Employee o){
        // 当前对象比传参对象的age属性大,返回1;
        // 小则返回-1;
        // 相等返回0,取前面的元素
        return this.getAge().compareTo(o.getAge());
    }


}

2) 在实例化TreeSet时实现Comparator接口,自定义排序规则

TreeSet<Employee> emps = new TreeSet<Employee>(new Comparator<Employee>(
        @Override
        public int compare(Employee o1 , Employee o2){
            return (int)(o1.getSalary() - o2.getSalary());
        }
));

Object类hashCode()和equals()的区别

1)equals()方法用来判断两个对象是否 “相同”
2)hashCode()返回一个int,代表“将该对象内存中的地址”,不同的对象也可能产生相同的哈希值
图片说明

全部评论

相关推荐

11-15 18:39
已编辑
西安交通大学 Java
全村最靓的仔仔:卧槽,佬啥bg呢,本也是西交么
点赞 评论 收藏
分享
评论
点赞
1
分享
牛客网
牛客企业服务