JAVA工程师面试题

1、简单讲一下java的跨平台原理
    Java源程序通过编译器(也就是Java平台)编译成Class文件(字节码文件),然后通过Java虚拟机(JVM)翻译成为对应的OS指令;可以让不同的系统都可以去执行此文件。

2、String和StringBuilder的区别, StringBuffer 和 StringBuilder 的区别
    1)String、StringBuffer、StringBuilder它们三个都是来表示和操作字符串的
    2)String是内容不可变的字符串,Stirng底层使用了一个不可变的字符数组(final char[]);而StringBuilder和StringBuffer是内容可以改变的字符串,StringBuilder和StringBuffer底层使用的是可变数组(没有使用final来修饰)----char value[]
    3)拼接字符串的方式不同:String用cancat或者+号拼接;而StringBuffer与StringBuilder用append来进行追加
    4)StringBuilder是线程不安全的,效率较高,而StringBuffer是线程安全的,效率较低(F安D不)
    5)由以上得知:String:适用于少量的字符串操作的情况;StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况;StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况

3、List和Set区别?Set集合去重规则?
    List,Set都是继承自Collection接口
    1)List集合特点:元素放入有序,元素可重复 ,可以存储空值且可以重复空
    2)Set集合特点:元素放入无序,元素不可重复(重复元素会覆盖掉),可以存储空值当时不能重复
    3)如果添加对象,一般都需要实现equals和hashcode方法,Set集合去重规则
        3.1、根据equals和hashCode来判断是否是同一个元素
        3.2、向Set集合中添加一个元素;如果equals返回false->添加成功;如果返回true->再去判断它的hashcode是否相同;如果不相同则添加成功;否则添加失败。

4、ArrayList和LinkedList区别
    ArrayList和LinkedList都实现了List接口
    1)ArrayList特点:是基于索引的数据接口,它的底层是数组;所以查询速度快
    2)LinkedList特点:是以元素列表的形式存储它的数据,底层实现是链表;所以插入、删除操作速度更快,因为当元素被添加到集合任意位置的时候,不需要像数组那样重新计算大小或者是更新索引。
    3)LinkedList比ArrayList更占内存,因为LinkedList为每一个节点存储了两个引用,一个指向前一个元素,一个指向下一个元素。

5、HashMap和HashTable区别
    1)它们都属于Map接口的类,实现了将惟一键映射到特定的值上。
    2)对外提供的接口不同: Hashtable比HashMap多提供了elments() 和contains() 两个方法。
    3)对Null key 和Null value的支持不同 :HashMap 类没有分类或者排序。它允许一个 null 键和多个 null 值;而Hashtable 类似于 HashMap,但是既不支持Null key也不支持Null value。
    4)线程安全性不同 :HashMap线程不安全;Hashtable线程安全
    5) 初始大小和每次扩充容量大小的不同 :Hashtable默认的初始大小为11,之后每次扩充,容量变为原来的2n+1。HashMap默认的初始化大小为16。之后每次扩充,容量变为原来的2倍。
    6)速度不同:因为关系到是否空值和线程安全性的关系;所以Hashtable速度比HashMap速度慢;所以Hashtable很少用。

6、ArrayList和Vector有何异同点
    1)Vector的方法都是同步的(Synchronized),是线程安全的(thread-safe),而ArrayList的方法不是,由于线程的同步必然要影响性能,因此,ArrayList的性能比Vector好。
    2) 当Vector或ArrayList中的元素超过它的初始大小时,Vector会将它的容量翻倍,而ArrayList只增加50%的大小,这样,ArrayList就有利于节约内存空间。

7、队列和栈是什么,列出它们的区别
    1)规则不同
        1.1、 队列:先进先出(First In First Out)FIFO
        1.2、栈:先进后出(First In Last Out )FILO
    2)对插入和删除操作的限定不同
        2.1、队列:只能在表的一端进行插入,并在表的另一端进行删除;
        2.2、栈:只能在表的一端插入和删除。
    3)遍历数据速度不同
        3.1、队列:基于地址指针进行遍历,而且可以从头部或者尾部进行遍历,但不能同时遍历,无需开辟空间,因为在遍历的过程中不影响数据结构,所以遍历速度要快。
        3.2、栈:只能从顶部取数据,也就是说最先进入栈底的,需要遍历整个栈才能取出来,而且在遍历数据的同时需要为数据开辟临时空间,保持数据在遍历前的一致性。

8、Iterater和ListIterator之间有什么区别
    (1)我们可以使用Iterator来遍历Set和List集合,而ListIterator只能遍历List。
    (2)Iterator只可以向前遍历,而LIstIterator可以双向遍历。
    (3)ListIterator从Iterator接口继承,然后添加了一些额外的功能,比如添加一个元素、替换一个元素、获取前面或后面元素的索引位置。

9、哪些集合类是线程安全的?为何Map接口不继承Collection接口?
    1)Vector?、HashTable、ConcurrentHashMap、Statck
    2)尽管Map接口和它的实现也是集合框架的一部分,但Map不是集合,集合也不是Map。因此,Map继承Collection毫无意义,反之亦然。如果Map继承Collection接口,那么元素去哪儿?Map包含key-value对,它提供抽取key或value列表集合的方法,但是它不适合“一组对象”规范。

10、遍历一个List、Map有哪些不同的方式
    1)List泛型只有一个;而Map有两个;是以键值对的形式出现的
    遍历一个List:1、使用Iterator或者ListIterator来遍历
             2、因为List底层是数组;所以可以利用普通for循环通过List大小(List.size())来逐个遍历。
             3、使用foreach来遍历
    遍历一个Map:1、同时得到key与value的值使用EntrySet方式
                2、使用KeySet,遍历key,然后通过map.get(key)获得对应的value
                  3、如果只需要value,可以:
            1. 使用EntrySet遍历value,同上面的方法一
            2. 通过keySet遍历key,然后通过map.get(key)得到value,同上面的方法二
            3. 通过Map对象“点”values直接遍历value

11、HashSet内部实现机制?HashMap内部实现机制?
    1)对于HashSet而言,它是基于HashMap实现的,(HashSet底层使用HashMap来保存所有元素,因此HashSet的实现比较简单,相关HashSet的操作),基本上都是直接调用底层HashMap的相关方法来完成。
    2)HashMap基于hashing原理,我们通过put()和get()方法储存和获取对象。当我们将键值对传递给put()方法时,它调用键对象的hashCode()方法来计算hashcode,让后找到bucket位置来储存值对象。当获取对象时,通过键对象的equals()方法找到正确的键值对,然后返回值对象。

12、集合排序方式(不同的集合类型排序方式)
    1)第一种称为自然排序,参与排序的对象需实现comparable接口,重写其compareTo()方法,方法体中实现对象的比较大小规则.
    2)第二种叫定制排序,或自定义排序,需编写匿名内部类,先new一个Comparator接口的比较器对象c,同时实现compare()其方法;?

13、多线程的几种实现方式,什么是线程安全
    1)继承Thread类创建线程
    2)实现Runnable接口创建线程
    3)实现Callable接口通过FutureTask包装器来创建Thread线程
    4)线程安全理解:线程安全就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其他线程不能进行访问直到该线程读取完,其他线程才可使用。不会出现数据不一致或者数据污染。

14、线程的生命周期和各种状态变化
    1)多线程理解:当线程被创建并启动以后,它既不是一启动就进入了执行状态,也不是一直处于执行状态。在线程的生命周期中,它要经过新建(New)、就绪(Runnable)、运行(Running)、阻塞(Blocked)和死亡(Dead)5种状态。尤其是当线程启动以后,它不可能一直"霸占"着CPU独自运行,所以CPU需要在多条线程之间切换,于是线程状态也会多次在运行、阻塞之间切换。
    2)各种状态之间变化:
        1、 新建状态:当程序使用new关键字创建了一个线程之后,该线程就处于新建状态,此时仅由JVM为其分配内存,并初始化其成员变量的值
        2、就绪状态:当线程对象调用了start()方法之后,该线程处于就绪状态。Java虚拟机会为其创建方法调用栈和程序计数器,等待调度运行
        3、运行状态:如果处于就绪状态的线程获得了CPU,开始执行run()方法的线程执行体,则该线程处于运行状态
        4、阻塞状态:当处于运行状态的线程失去所占用资源之后,便进入阻塞状态
            4.1、当占用CPU的时间片刻用完(Thread.yield()),线程进入到阻塞状态;需要再一次被选中调度才能再次进入就绪状态。
            4.2、当遇到了synchronized线程进入阻塞状态,需要拿到对象所标记才能再次进入就绪状态。
            4.3、当线程调用了某个对象的wait()方法时;也会使线程进入阻塞状态;需要用notify()或者notifyall()方法来唤醒。
            4.4、一个线程调用了另一个线程的join()方法时,当前线程进入阻塞状态。等新加入的线程运行结束后会结束阻塞状态,进入就绪状态。
            4.5、调用了Thread的sleep(long millis)。线程睡眠时间到了会自动进入就绪状态。
            4.6、当遇到用户输入时候也会进入阻塞状态;要等待用户结束才能再次就绪状态。
            4.7、线程从阻塞状态只能进入就绪状态,而不能直接进入运行状态,即结束阻塞的线程需要重新进入可运行池中,等待系统的调度。
        5、死亡状态:线程的run()方法正常执行完毕或者线程抛出一个未捕获的异常(Exception)、错误(Error),线程就进入死亡状态。一旦进入死亡状态,线程将不再拥有运行的资格,也不能转换为其他状态。

15、sleep 和 wait 的区别
    1)代表意思不一样:sleep是线程休眠,在调用sleep()方法的过程中,线程不会释放对象锁;时间结束就可以使线程进入运行状态;wait是线程等待,线程会放弃对象锁;需要用notify()或者notifyall()方法去唤醒使线程进入。
    2)所属地方不同:sleep是Thread类的静态方法;而wait是Object的方法。

16、用过线程池吗?它的作用?newCache 和 newFixed 有什么区别
    1)作用:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值