美文网首页
java面试2

java面试2

作者: Coding_Wolf | 来源:发表于2019-01-17 20:55 被阅读0次

1.成员变量和局部变量区别

  • 成员变量可以被访问修饰符和static修饰,而局部变量不可以,final两者都可以修饰
  • 成员变量属于对象,对象存在于堆,而局部变量存在于栈。
  • 成员变量未初始化则会自动以类型的默认值而赋值,局部变量必须初始化,否则报错。

2.构造方法的作用

主要作用是完成对类对象的初始化工作。

3.构造方法有哪些特性

  • 名字与类名相同;
  • 没有返回值,但不能用void声明构造函数;
  • 生成类的对象时自动执行,无需调用。

4.静态方法和实例方法

  • 静态方法无需创建对象直接通过类名.方法名就可以调用,也可以对象名.方法名(阿里编码标准中不推荐这样调用),而实例方法只能通过后者调用。
  • 静态方法在访问本类的成员时,只允许访问静态成员(即静态成员变量和静态方法),而不允许访问实例成员变量和实例方法;实例方法则无此限制。

5.对象的相等与指向他们的引用相等,两者有什么不同?

  • 对象的相等,比的是内存中存放的内容是否相等。
  • 引用相等,比较的是他们指向的内存地址是否相等。

6.老生常谈的 == 和 equals

  1. ==:是判断两个对象的地址是不是相等。'基本数据类型==比较的是值,引用数据类型==比较的是内存地'
  2. equals:也是判断两个对象是否相等。但一般两种类型:
    1.没有覆盖equals() <==> '=='
    2.覆盖了equals():比较的是内容

7.hashCode()和equals()

  • hashCode(): 获取哈希码,也称为散列码,这个哈希码的作用是确定该对象在哈希表中的索引位置。

为什么要有hashCode():
'我们以HashSet 如何检查重复为例子来说明为什么要有 hashCode
当你把对象加入 HashSet 时,HashSet 会先计算对象的 hashcode 值来判断对象加入的位置,同时也会与其他已经加入的对象的 hashcode 值作比较,如果没有相符的hashcode,HashSet会假设对象没有重复出现。但是如果发现有相同 hashcode 值的对象,这时会调用 equals()方法来检查 hashcode 相等的对象是否真的相同。如果两者相同,HashSet 就不会让其加入操作成功。如果不同的话,就会重新散列到其他位置。

结论:

  • 如果两个对象相等,则hashcode一定也是相同的
  • 两个对象相等,对两个对象分别调用equals方法都返回true
  • 两个对象有相同的hashcode值,它们也不一定是相等的
  • 因此,equals 方法被覆盖过,则 hashCode 方法也必须被覆盖
  • hashCode() 的默认行为是对堆上的对象产生独特值。如果没有重写 hashCode(),则该class 的两个对象无论如何都不会相等(即使这两个对象指向相同的数据)

8.程序、线程、进程

  • 程序: 含有指令和数据的文件,被存储在磁盘或其他的数据存储设备中,也就是说程序是静态的代码。
  • 线程: 线程是一个比进程更小的执行单位。
  • 进程: 程序的一次执行过程,是系统运行程序的基本单位,因此进程是动态的。

9.线程有哪些基本状态?

新建、就绪、运行、阻塞、死亡

  • 新建(new):新创建了一个线程对象。
  • 可运行(runnable):线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获 取cpu的使用权。
  • 运行(running):可运行状态(runnable)的线程获得了cpu时间片(timeslice),执行程序代码。
  • 阻塞(block):阻塞状态是指线程因为某种原因放弃了cpu使用权,也即让出了cpu timeslice,暂时停止运行。直到线程进入可运行(runnable)状态,才有 机会再次获得cpu timeslice转到运行(running)状态。
    阻塞的情况分三种
    1. 等待阻塞:运行(running)的线程执行o.wait()方法,JVM会把该线程放 入等待队列(waitting queue)中。
    1. 同步阻塞:运行(running)的线程在获取对象的同步锁时,若该同步锁 被别的线程占用,则JVM会把该线程放入锁池(lock pool)中。
    2. 其他阻塞: 运行(running)的线程执行Thread.sleep(long ms)或t.join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入可运行(runnable)状态。
  • 死亡(dead):线程run()、main()方法执行结束,或者因异常退出了run()方法,则该线程结束生命周期。死亡的线程不可再次复生。

10.final关键字

  • 对于一个final变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。
  • 当用final修饰一个类时,表明这个类不能被继承。
  • 使用final方法的原因有两个。第一个原因是把方法锁定,以防任何继承类修改它的含义;第二个原因是效率。

11.异常处理

  • try 块:用于捕获异常。其后可接零个或多个catch块,如果没有catch块,则必须跟一个finally块。
  • catch 块:用于处理try捕获到的异常。
  • finally 块:无论是否捕获或处理异常,finally块里的语句都会被执行。当在try块或catch块中遇到return语句时,finally语句块将在方法返回之前被执行。

在以下4种特殊情况下,finally块不会被执行:
1.在finally语句块中发生了异常。
2.在前面的代码中用了System.exit()退出程序。
3.程序所在的线程死亡。
4.关闭CPU。

12.获取键盘输入

'Scanner方法'

 Scanner input = new Scanner(System.in);
 String s  = input.nextLine();
 input.close();

'BufferedReader方法'
 BufferedReader input = new BufferedReader(new
 InputStreamReader(System.in)); 
 String s = input.readLine(); 

2019.1.25集合补充

1.List,Set,Map三者的区别及总结

  • List接口存储一组不唯一(可以有多个元素引用相同的对象),有序的对象
  • Set 不允许重复的集合。不会有多个元素引用相同的对象,无序。
  • Map 使用键值对存储。Map会维护与Key有关联的值。两个Key可以引用相同的对象,但Key不能重复,典型的Key是String类型,但也可以是任何对象。

2.Arraylist与LinkedList 区别

  • Arraylist:底层使用的是数组(存读数据效率高,插入删除特定位置效率低)
  • LinkedList:底层使用的是双向循环链表数据结构(插入,删除效率特别高)
    一般数据量不大的都用Arraylist

3.ArrayList与Vector区别
Vector类的所有方法都是同步的。可以由两个线程安全地访问一个Vector对象、但是一个线程访问Vector,代码要在同步操作上耗费大量的时间。Arraylist不是同步的,所以在不需要同步时建议使用Arraylist。

4.HashMap和Hashtable的区别

  • HashMap线程不安全,Hashtable线程安全,基本方法synchronized修饰
  • 因为线程安全的问题,HashMap要比HashTable效率高一点
  • HashMap允许有null值的存在,而在HashTable中put进的键值只要有一个null,直接抛出NullPointerException。

5.HashSet和HashMap区别

  • HashMap实现了Map接口,存键值对,put添加元素,key计算hashcode,使用唯一的key获取对象
  • HashSet实现了Set接口,仅存储对象,add添加元素,成员对象计算hashcode,equals判断对象的相等性
  • 查找速度HashMap更快

6.使用多线程常见的三种方式

  • 继承Thread类,重写run()方法 MyThread t = new MyThread();t.start();
  • 实现Runnable接口
    Runnable r = new Runnable(); Thread t = new Thread(r); t.start();
  • 使用线程池

相关文章

网友评论

      本文标题:java面试2

      本文链接:https://www.haomeiwen.com/subject/hrswdqtx.html