毕业生面试题汇总(一)

毕业生面试题汇总

一、基础知识
1、Java数据类型
  基本数据类型:整数型(byte、short、int、long)
         浮点型(float、double)
         字符型(char)
         布尔型(boolean)
2、面向对象的特征
  面向对象三大特征:封装、继承、多态
  封装:把一个对象的属性和行为私有化,同时也会提供一些可以被外界访问的属性的方法
  继承:继承是用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性的继承父类。
  多态:父类的引用指向子类的对象。
3、重载和重写的区别
  重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性。
   重载:发生在同一个类中,方法名相同参数列表不同,与返回值和访问修饰符无关。
   重写:发生在父类中,方法名相同,参数列表相同,返回值类型小于父类返回值类型,抛出的异常也小于父类抛出的异常,访问修饰符要大于父类。如果父类方法访问修饰符为private则子类中就不是重写。
4、抽象类和接口的区别
抽象类可以有构造方法,接口中不能有构造方法;抽象类中可以有普通成员变量,接口中没有普通成员变量,只能有常量;抽象类中的方法可以被static修饰,接口中的方法不可以被static修饰;抽象类中可以有普通方法和抽象方法,接口中的方法全是抽象方法,一个类只能继承一个抽象类,接口可以被多个实现。
5、==和equals的区别是什么
  ==比较的是两个对象的地址是否相等。即判断两个对象是否为同一个对象。(基本数据类型比较的是值,引用数据类型比较的是内存地址)
  equals比较两个对象是否相等,如果两个对象相等,则hashcode也一定是相同的,两个对象有相同的hashcode值,它们也不一定是相等的
6、关于String
(1)、String是最基本的数据类型吗?
     基本数据类型有8种,不包括String。
(2)、String的常用方法有哪些?
    indexOf():返回指定字符的索引。
    charAt():返回指定索引处的字符。
    replace():字符串替换。
    trim():去除字符串两端空白。
    split():分割字符串,返回一个分割后的字符串数组。
    length():返回字符串长度。
    toLowerCase():将字符串转成小写字母。
    toUpperCase():将字符串转成大写字母。
    substring():截取字符串。
    equals():字符串比较。
(3)、String、StringBuffer、StringBuilder的区别。
    String是线程安全的,String是不可变的,如果要操作少量的数据用String
    StringBuffer是线程安全的(对方法或调用的方法加了同步锁),是可变的,多线程操作字符串缓冲区下操作大量数据用StringBuffer
    StringBuilder是线程不安全的(没有对方法或调用的方法加了同步锁),是可变的,单线程操作字符串缓冲区下操作大量数据用StringBuilder。
(4)、String为什么是不可变的
    String类中使用字符数组保存字符串。
二、集合容器
 1、有哪些集合?
   Java容器分为collection和map两大类
   collection集合主要有List和Set两大接口
    List:一个有序容器(元素存入集合的顺序和取出的顺序一致),元素可以重复,可以插入多个null元素,元素都有索引。常见的实现类都有:ArrayList、LinkedList和vector。
    Set:一个无序容器(存入和取出的顺序可能不一致),不可以存储重复元素,只允许存入一个null元素,必须保证元素唯一性。常用的实现类:HashSet、LinkedHashSet、TreeSet
    map是一个键值对集合,存储键、值和之间的映射。key无序,唯一;value不要求有序,允许重复。map的常用实现类:HashMap、TreeMap、HashTable、LinkedHashMap、ConcurrentHashMap。
 2、集合框架底层数据结构
    collection
     1、List
       ArrayList:数组
       LinkedList:双向循环链表
     2、Set
        HashSet(无序、唯一):基于HashMap实现的,底层采用HashMap来保存元素。
        TreeSet(有序、唯一):红黑树
    map
     HashMap: 数组+链表组成的,数组是HashMap的主体,链表则是主要为了解决哈希冲突而存在的。JDK1.8以后在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为8)时,将链表转化为红黑树,以减少搜索时间
     LinkedHashMap:LinkedHashMap 继承自 HashMap,所以它的底层仍然是由数组和链表或红黑树组成。
     HashTable: 数组+链表组成的,数组是 HashMap 的主体,链表则是主要为了解决哈希冲突而存在的
     TreeMap: 红黑树(自平衡的排序二叉树)
3、arrayList和linkedList的区别
   数据结构实现:ArrayList 是动态数组的数据结构实现,而 LinkedList 是双向链表的数据结构实现。
   线程安全:ArrayList 和 LinkedList 都是不同步的,也就是不保证线程安全;
 4、HashMap 与 HashTable 有什么区别?
    线程安全:HashMap 是非线程安全的,HashTable 是线程安全的。
    扩容机制:创建时如果不指定容量初始值,Hashtable 默认的初始大小为11,之后每次扩充,容量变为原来的2n+1。HashMap 默认的初始化大小为16。之后每次扩充,容量变为原来的2倍。创建时如果给定了容量初始值,那么 Hashtable 会直接使用你给定的大小,而 HashMap 会将其扩充为2的幂次方大小。
    底层数据结构: JDK1.8 以后的 HashMap 在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为8)时,将链表转化为红黑树,以减少搜索时间。Hashtable 没有这样的机制。
三、并发编程
 1、并行和并发有什么区别?
并发:多个任务在同一个 CPU 核上,按细分的时间片轮流(交替)执行,从逻辑上来看那些任务是同时执行。
并行:单位时间内,多个处理器或多核处理器同时处理多个任务,是真正意义上的“同时进行”。
串行:有n个任务,由一个线程按顺序执行。由于任务、方法都在一个线程执行所以不存在线程不安全情况,也就不存在临界区的问题。
  2、进程和线程的区别:进程是操作系统资源分配的基本单位,而线程是处理器任务调度和执行的基本单位.一个进程有多个线程,但至少要有一个进程。
  3、创建线程有哪几种方式?
   创建线程有四种方式:
    继承 Thread 类;
    实现 Runnable 接口;
    实现 Callable 接口;
    使用 Executors 工具类创建线程池
 4、说一下 runnable 和 callable 有什么区别?
   相同点
    都是接口
    都可以编写多线程程序
    都采用Thread.start()启动线程
   主要区别
    Runnable 接口 run 方法无返回值;Callable 接口 call 方法有返回值,是个泛型,和Future、FutureTask配合可以用来获取异步执行的结果
    Runnable 接口 run 方法只能抛出运行时异常,且无法捕获处理;
    Callable 接口 call 方法允许抛出异常,可以获取异常信息
 5、线程的 run()和 start()有什么区别?
   每个线程都是通过某个特定Thread对象所对应的方法run()来完成其操作的,run()方法称为线程体。通过调用Thread类的start()方法来启动一个线程。
   start() 方法用于启动线程,run() 方法用于执行线程的运行时代码。run() 可以重复调用,而 start() 只能调用一次。
   start()方法来启动一个线程,真正实现了多线程运行。调用start()方法无需等待run方法体代码执行完毕,可以直接继续执行其他的代码; 此时线程是处于就绪状态,并没有运行。 然后通过此Thread类调用方法run()来完成其运行状态, run()方法运行结束, 此线程终止。然后CPU再调度其它线程。
   run()方法是在本线程里的,只是线程里的一个函数,而不是多线程的。 如果直接调用run(),其实就相当于是调用了一个普通函数而已,直接待用run()方法必须等待run()方法执行完毕才能执行下面的代码,所以执行路径还是只有一条,根本就没有线程的特征,所以在多线程执行时要使用start()方法而不是run()方法。
 6、线程的状态和基本操作
   说说线程的生命周期及五种基本状态?
    新建(new):新创建了一个线程对象。
    可运行(runnable):线程对象创建后,当调用线程对象的 start()方法,该线程处于就绪状态,等待被线程调度选中,获取cpu的使用权。
    运行(running):可运行状态(runnable)的线程获得了cpu时间片(timeslice),执行程序代码。注:就绪状态是进入到运行状态的唯一入口,也就是说,线程要想进入运行状态执行,首先必须处于就绪状态中;
    阻塞(block):处于运行状态中的线程由于某种原因,暂时放弃对 CPU的使用权,停止执行,此时进入阻塞状态,直到其进入到就绪状态,才 有机会再次被 CPU 调用以进入到运行状态。
     阻塞的情况分三种:
      (一). 等待阻塞:运行状态中的线程执行 wait()方法,JVM会把该线程放入等待队列(waitting queue)中,使本线程进入到等待阻塞状态;
      (二). 同步阻塞:线程在获取 synchronized 同步锁失败(因为锁被其它线程所占用),,则JVM会把该线程放入锁池(lock pool)中,线程会进入同步阻塞状态;
      (三). 其他阻塞: 通过调用线程的 sleep()或 join()或发出了 I/O 请求时,线程会进入到阻塞状态。当 sleep()状态超时、join()等待线程终止或者超时、或者 I/O 处理完毕时,线程重新转入就绪状态。
    死亡(dead):线程run()、main()方法执行结束,或者因异常退出了run()方法,则该线程结束生命周期。死亡的线程不可再次复生
 7、sleep() 和 wait() 有什么区别?
   首先sleep和wait之间没有任何关系
   sleep 是Thread类的方法,指的是当前线程暂停。
   wait 是Object类的方法, 指的占用当前对象的线程临时释放对当前对象的占用,以使得其他线程有机会占用当前对象。 所以调用wait方法一定是在synchronized 中进行
 8、notify() 和 notifyAll() 有什么区别?
   notifyAll() 会唤醒所有的线程,notify() 只会唤醒一个线程。
   notifyAll() 调用后,会将全部线程由等待池移到锁池,然后参与锁的竞争,竞争成功则继续执行,如果不成功则留在锁池等待锁被释放后再次参与竞争。而 notify()只会唤醒一个线程,具体唤醒哪一个线程由虚拟机控制。
 9、synchronized 和 Lock 有什么区别?
   首先synchronized是Java内置关键字,在JVM层面,Lock是个Java类;
   synchronized 可以给类、方法、代码块加锁;而 lock 只能给代码块加锁。
   synchronized 不需要手动获取锁和释放锁,使用简单,发生异常会自动释放锁,不会造成死锁;而 lock 需要自己加锁和释放锁,如果使用不当没有 unLock()去释放锁就会造成死锁。
   通过 Lock 可以知道有没有成功获取锁,而 synchronized 却无法办到。
 10、synchronized 和 ReentrantLock 区别是什么?
   ReentrantLock 使用起来比较灵活,但是必须有释放锁的配合动作;
   ReentrantLock 必须手动获取与释放锁,而 synchronized 不需要手动释放和开启锁;
   ReentrantLock 只适用于代码块锁,而 synchronized 可以修饰类、方法、变量等。
   二者的锁机制其实也是不一样的。ReentrantLock 底层调用的是 Unsafe 的park 方法加锁,synchronized 操作的应该是对象头中 mark word
 11、synchronized 和 volatile 的区别是什么?
   volatile 是变量修饰符;synchronized 可以修饰类、方法、变量。
   volatile 仅能实现变量的修改可见性,不能保证原子性;而 synchronized 则可以保证变量的修改可见性和原子性。
   volatile 不会造成线程的阻塞;synchronized 可能会造成线程的阻塞。
   volatile标记的变量不会被编译器优化;synchronized标记的变量可以被编译器优化。
   volatile关键字是线程同步的轻量级实现,所以volatile性能肯定比synchronized关键字要好。但是volatile关键字只能用于变量而synchronized关键字可以修饰方法以及代码块。synchronized关键字在JavaSE1.6之后进行了主要包括为了减少获得锁和释放锁带来的性能消耗而引入的偏向锁和轻量级锁以及其它各种优化之后执行效率有了显著提升,实际开发中使用 synchronized 关键字的场景还是更多一些。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

m0_53941252

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值