Java简单面试题

1、重载和重写的区别
重载是同一个类中可以声明多个名字相同,但是参数列表不同的方法或者构造器;
重写是子类在继承父类以后,对于父类中声明的某些方法进行覆盖操作;

2、多态时运行时行为还是编译时行为?如何证明

3、final、finally、finalize的区别

4、==和equals的区别
==:运算符
①如果比较的是基本数据类型变量,不比较数据类型,仅仅比较数值大小是否相等
②如果比较的是引用数据类型变量,比较对象的地址值是否相等,即两个引用是否指向同一个对象实体

equals:方法
①equals只能是引用数据类型来进行使用
②Object类中equals的定义,是和==相同的
③String、Date、File、包装类等都重写了equals方法,重写后比较的不再是两个变量的地址值,而是对象的实体内容是否相同

5、下面两个的输出结果分别为多少

//题一
Object o1 = true ? new Integer(1) : new Double(2.0);
System.out.println(o1);

//题二
Object o2;
if(true) {
	o2 = new Integer(1);
}else {
	o2 = new Double(2.0);
}
System.out.println(o2);

题一结果为1.0:再编译过程中,三目运算符后两个数据必须要统一,那么Integer就要转化为Double,所以结果为1.0
题二结果为1

6.下面三个的输出结果是

Integer i = new Integer(1);
Integer j = new Integer(1);
System.out.println(i == j);
		
Integer m = 1;
Integer n = 1;
System.out.println(m == n);
		
Integer x = 128;
Integer y = 128;
System.out.println(x == y);

第一个是false,第二个是true,第三个是false
Integer内部定义了一个IntegerCache结构,IntegerCache中定义了Integer[],保存了从-128–127的整数,如果使用自动装箱的方法,Integer赋值的范围如果在-128~127时,可以直接使用数组中的元素,不用重新new一个。

7.抽象类和接口有哪些异同?
相同点:都不能实例化,都可以被继承
不同点:
抽象类有构造器,接口没有构造器;接口可以多继承,抽象类不能多继承

8.常见的异常有哪些?

9.throw和throws的区别?
throw是抛出一个异常类的对象,生成异常对象的过程,声明在方法体内
throws属于异常处理的一种方式,声明在方法的声明处

10.synchronized和lock的异同?
相同点:都可以解决线程安全问题
不同点:synchronized是隐式锁,在执行完相应的代码后,会自动释放同步监视器;
Lock是显式锁,需要手动启动同步(lock()),并且结束同步也需要手动实现(unlock());
使用Lock,JVM花费更少的时间调度线程,性能更好。具有更好的扩展性

11.如何解决线程安全问题?
synchronized和lock

12、sleep()和wait()的异同?
相同点:都可以使得线程进入阻塞状态
不同点:
sleep()不能够释放锁(同步监视器),wait()能够释放锁(同步监视器);
sleep()声明在Thread类中,wait()声明在Object类中;
sleep()可以在任何场景下调用,wait()只能在同步代码块和同步方法中;

13、生产者/消费者问题
生产者(Productor)将产品交给店员(Clerk),而消费者(Customer)从店员处取走产品,店员一次只能持有固定数量的产品(比如说20),如果生产者试图生产更多产品,店员会叫生产者停一下,如果店中有空位放产品了再通知生产者继续生产;如果店中没有产品了,店员会告诉消费者等一下,如果店中有产品了再通知消费者来取走产品。
可能出现的两个问题:
生产者比消费者快时,消费者会漏掉一些数据没有取到;
消费者比生产者快时,消费者会取相同的数据。

class Clerk{

    private int productCount = 0;

    //生产产品
    public synchronized void produceProduct() {
        if (productCount < 20) {
            productCount++;
            System.out.println(Thread.currentThread().getName() + " 开始生产第" + productCount + "个产品。");

            notify();
        }else{
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    //消费产品
    public synchronized void consumeProduct() {
        if (productCount > 0) {
            System.out.println(Thread.currentThread().getName() + " 开始消费第" + productCount + "个产品。");
            productCount--;

            notify();
        }else{
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

class Productor implements Runnable{

    private Clerk clerk;

    public Productor(Clerk clerk){
        this.clerk = clerk;
    }

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + " 开始生产产品……");
        while (true) {
            clerk.produceProduct();
        }
    }
}

class Customer implements Runnable{

    private Clerk clerk;

    public Customer(Clerk clerk){
        this.clerk = clerk;
    }

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + " 开始购买产品……");
        while (true) {
            clerk.consumeProduct();
        }
    }
}

public class ProductTest {

    public static void main(String[] args) {
        Clerk clerk = new Clerk();
        Productor productor = new Productor(clerk);
        Thread p1 = new Thread(productor);
        p1.setName("生产者1");

        Customer customer = new Customer(clerk);
        Thread c1 = new Thread(customer);
        c1.setName("消费者1");

        p1.start();
        c1.start();
    }
}

14、获得两个字符串中最大相同字串
str1 = “abcwerthelloyuiodef”,str2 = “cvhellobnm”
提示:将短的字符串进行长度依次递减的字串与较长的字符串比较

①只有一个最大相同字串

public class CommonString {

    public String getCommonString(String str1, String str2){
        if (str1 != null && str2 != null){
            //先获得两个字符串中一大一小的两个字符串,分别装入maxStr、minStr
            String maxStr = (str1.length() >= str2.length()) ? str1 : str2;
            String minStr = (str1.length() < str2.length()) ? str1 : str2;
            int length = minStr.length();

            //一共有较短字符串长度的大分类
            for (int i = 0; i < length; i++){

                //每次小分类都是从开头开始、慢慢向末尾移动判断
                for (int x = 0,y = length - i; y <= length; x++,y++){
                    String str = minStr.substring(x,y);

                    if (maxStr.contains(str)){
                        return str;
                    }
                }
            }
        }
        return null;
    }

    @Test
    public void demo(){
        String str1 = "abcwerthelloyuiodef";
        String str2 = "cvhellobnm";
        System.out.println(getCommonString(str1, str2));
    }
}

②有多个最大相同字串

public class CommonString {

    public String[] getCommonString(String str1, String str2){
        if (str1 != null && str2 != null){
            StringBuffer sBuffer = new StringBuffer();

            //先获得两个字符串中一大一小的两个字符串,分别装入maxStr、minStr
            String maxStr = (str1.length() >= str2.length()) ? str1 : str2;
            String minStr = (str1.length() < str2.length()) ? str1 : str2;
            int length = minStr.length();

            //一共有较短字符串长度的大分类
            for (int i = 0; i < length; i++){

                //每次小分类都是从开头开始、慢慢向末尾移动判断
                for (int x = 0,y = length - i; y <= length; x++,y++){
                    String str = minStr.substring(x,y);

                    if (maxStr.contains(str)){
                        sBuffer.append(str + ",");
                    }
                }
                //如果找到了最大相同字符串就停止下一轮的寻找
                if (sBuffer.length() != 0){
                    break;
                }
            }
            String[] split = sBuffer.toString().replaceAll(",$","").split("//,");
            return split;
        }
        return null;
    }

    @Test
    public void demo(){
        String str1 = "abcwerthelloyuiodefabcdf";
        String str2 = "cvhellobnmabcdf";
        String[] result = getCommonString(str1, str2);
        System.out.println(Arrays.toString(result));
    }
}

15、从XXXX-XX-XX到XXXX-XX-XX的总天数?
方式一:分别获得两个时间的时间戳,然后相减,获得总的毫秒数,然后除以一天的毫秒数,再加上一;
方式二:将总的天数分为两个时间段,一个是整年的时间段,另一个是一年中该日期的天数;

16、ArrayList、LinkedList、Vector三者的异同?
相同点:三者都是List接口的实现类;存储数据的特点都是有序、可重复;
不同点:
ArrayList:作为List接口的主要实现类;线程不安全,效率高;底层使用Object[] elementData存储;
LinkedList:在进行增、删操作时效率比ArrayList高;底层使用双向链表存储
Vector:作为List最古老的实现类;线程安全,效率低;Object[] elementData存储;

ArrayList源码分析:
JDK7.0版本:
ArrayList实例化:空参构造器:初始化一个长度为10的Object数组elementData
ArrayList添加操作:add(123):创建一个包装类Integer(123),放入Object[]数组中
数组容量满了:默认情况下,新数组扩容为原来的1.5倍(原有的数组长度>>1),将原来数组中的数据放到新的数组中;

JDK8.0版本:
ArrayList实例化:空参构造器:初始化Object[] elementData为{},并没有直接赋予长度
ArrayList添加操作:add(123):第一次调用时,才创建了长度为10的数组,并将数据放入数组中
数组容量满了:默认情况下,新数组扩容为原来的1.5倍(原有的数组长度>>1),将原来数组中的数据放到新的数组中

LinkedList源码分析:
LinkedList实例化:空参构造器:在内部声明一个Node类型的first、last变量以及int类型的size变量
LinkedList添加操作:add(123):新建一个Node类型的实体变量,将last变量放入Node的头节点,null放入尾节点,数据放入element中

HashSet:Set接口主要实现类;线程不安全;可以存储null值
LinkedHashSet:HashSet子类;遍历内部数据时,可以按照添加顺序遍历;频繁的遍历操作,LinkedHashSet效率高于HashSet
TreeSet:可以按照添加对象的指定属性,进行排序

17、看以下的代码输出

HashSet set = new HashSet();
Person p1 = new Person(1001, "AA");
Person p2 = new Person(1002, "BB");

set.add(p1);
set.add(p2);

p1.name = "CC";
set.remove(p1);
System.out.println(set);

set.add(new Person(1001, "CC"));
System.out.println(set);

set.add(new Person(1001, "AA"));
System.out.println(set);

第一个输出是[Person{id=1002, name='BB'}, Person{id=1001, name='CC'}]
首先根据p1、p2的属性值来算出哈希值,放入对应的位置,p1.name = "CC"将p1的哈希值改变了,那么当set调用remove()方法的时候查找的时候是按照改变后的哈希值来查找,那么就找不到原来存放"AA"的位置,那么就p1删除失败
在这里插入图片描述
第二个输出是[Person{id=1002, name='BB'}, Person{id=1001, name='CC'}, Person{id=1001, name='CC'}]
按上图,原来存放改变后哈希值的地方并没有存放数据,所以判断没有相同,所以放入

第三个输出是[Person{id=1002, name='BB'}, Person{id=1001, name='CC'}, Person{id=1001, name='CC'}, Person{id=1001, name='AA'}]
原来存放"AA"的位置上判断两个对象不相等,所以可以加进去

18、HashMap的底层实现原理?

19、HashMap和Hashtable的异同?

20、谈谈你对HashMap中put/get方法的认识?如果了解再谈谈HashMap的扩容机制?默认大小是多少?什么是负载因子(或填充比)?什么是吞吐临界值(或阈值、threshold)?

21、Collection和Collections的区别?

22、

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1 按照某种格式输出系统时间:自学java中的时间。自学Date类(java.util.Date)和SimpleDateFormat类,用程序输出“当前时间是XXXX年XX月XX日XX时XX分XX秒(第XX周,周X)” 2 比较String与StringBuffer、StringBuilder的自增速度。方法:在自增前记录系统时间,进行5000次自增,然后再记录系统时间,可以得出自增的速度。获取系统时间的方法是java.lang.System.currentTimeMillis() ,见JDK API。 3 定义点类,圆是由圆心(点)和半径组成的,请完成圆类,注意“派”为常量,取3.14。圆类具有judge函数可以判断两圆的关系:相离、相交(包括相切)、嵌套、重合。设计static成员用以求所有圆对象的平均面积。(static、final) 4 图形间的关系可以下图用来表现。所有的图形中都可以称为Shape。由这个类可以派生出二维图形TwoDimensionalShape和三维图形ThreeDimensionalShape类。每个TwoDimensionalShape类应包括成员函数getArea以计算二维图形的面积。每个ThreeDimensionalShape类包含成员函数getArea和getVolume,分别计算三维图形的表面积和体积。编写一个程序,用一个数组乘放各种图形类对象(包括二维和三维的),并输出对象得相应信息。如果某个图形是TwoDimensionalShape就显示其面积,如果某个图形是ThreeDimenionalShape,则显示其面积和体积。请完成图中所有的类并在主函数中做测试。(继承与多态)

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值