java高级工程师面试题目总结

1. 集合框架

Collection接口:

                       List接口:

                                        ArrayList实现类

                                        LinkList实现类

                                        Vector实现类

                       Set接口:

                                        HashSet实现类

                                        TreeSet实现类

                       Queue接口:

 问一:List、Set和Queue的区别:

      List是有序的,可以重复的;

     Set是无序的,不可以重复的;

     Queue是一个单向的数据管道,这边进,另一边出。

问二:ArrayList、LinkList和Vector的区别:

      ArrayList基于数组,存储慢(需要扩容和复制),访问快,需要分配连续的内存空间;

      LinkList基于链表,存储快,访问慢,存储空间可以碎片化。

      Vector也是基于数组,几乎和ArrayList一致,但是Vector是线程安全的,目测用Synchronized重写里面的方法了。

问三:HashSet和TreeSet的区别:

      都是基于HashMap的key来实现的,但是后者支持排序;

问四:链表的实现原理:

     有一个对象,它持有下一个对象的存储地址,可以根据该地址找到下一个对象时,就构成了单向链表。同理,如果该对象同时持有上一个对象的地址,可以根据该地址找到上一个对象时,就构成了双向链表。

问五:链表为什么增删快,查询慢:

    因为链表中的对象不是连续存储的,需要一次遍历链表中的每个对象才能最终找到想要的结果对象;但是增删时,只要把要删除对象的前后对象指向的对象地址做修改就可以了。而数组需要重新计算容量来扩容并复制全部元素到新的数组里。

Map接口:

              HashTable实现类(线程安全,但已弃用)

              HashMap实现类(可用ConcurrentHashMap来实现线程安全,用ConcurrentSkipListMap(跳表Map)实现线程安全同时可排序)

              TreeMap实现类(支持排序)

问一:Collection和Map的区别:

      Collection是单列的;

      Map是双链的;

问二:Map的实现原理:

     用数组来存储经过计算后的key(即存储地址),用链表来存储value。查找时,根据该key重新计算,并在数组中找到对应的存储地址,然后根据存储地址找链表中的value。

2. io框架

   BIO:阻塞式io,一个连接就需要分配一个线程去处理。

   NIO:非阻塞式io,一个有效连接分配一个线程去处理。

   AIO:异步io,一个有效请求分配一个线程去处理。

   打个比方吧:幼儿园放学了,每个孩子都需要自己的家长来接就是BIO,放学后校车每隔一段时间出发一趟送孩子回家就是NIO。但是NIO带来的问题是如果每个孩子回家的时间不一致,校车一趟趟跑。AIO就是干这个的,有孩子要回家才发一辆车。

问一:TCP和UDP的区别:

  TCP是面向连接的,需要三次握手,保证了数据的准确性。

  UDP是无连接的,不关心对方有没有收到。

问二:TCP三次握手和四次挥手:

   3. 多线程

问一:多线程的概念:

      当一个任务进入阻塞时,为了不影响其他任务的进行,引入了多线程的概念。

问二:线程的生命周期:

     创建->可执行->执行-(阻塞)->销毁。

问三:线程的创建方式:

    (1)实现Runnable接口:比较通用

    (2)继承Thread类:

              好处:Thread类是Runnable的一个实现类,内存封装了很多东西,我们不需要再关注部分细节。

              缺点:JAVA不支持多继承(可以用内部类来间接实现);

     (3)用callable和future接口组合实现,再用一个线程去启动:

              好处:可以有返回值,而且是异步的,已经大量用于AIO编程。

问四:Thread的start()方法和Runnable的run()方法有啥区别?

           Thread重写了Runnable的run方法,线程不会再执行start()时就执行,而是等到CPU资源可用时才会启动此线程,比较友好。如果继承了Thread类后用run()方法启动,就没有这种效果了。

问五:怎么保证多个线程有序访问同一个对象?

         加锁(Synchronized)或用lock手动实现。它俩的区别是:

        Synchronized是JVM级别的锁,不需要我们关注细节;Lock锁是需要在代码中手动控制加锁和释放锁的,对开发人员的要求较高。不释放lock锁会带来一系列灾难性的问题。

问六:多线程中怎么保证多个任务都执行完成?

     引入线程计数器(CountDownLatch) ,然后让主线程进入等待中。

4. 线程池

 问一:线程池的类型:

    固定容量线程池,可变容量线程池,单一线程线程池,定时任务线程池。

问二:线程池使用调优?

   (1)合理分配线程数量(楼主的经验,windows下一百个线程同时不停歇的跑,系统很快就崩了);

   (2)合理使用线程池策略,比如设置没有工作线程是线程池的存活时间和空闲线程的存活时间。

5. 缓存(Redis,Mongodb,Memcached)的比较

   Redis:单线程的内存型数据库,支持丰富的数据类型(String,list,set,zset,hash),支持重启恢复,因为redis会在合适的时间将数据写入磁盘。

  Mongodb:文档型数据库,支持丰富的数据类型,而且容易扩展。但是会受限于计算机io能力。理论上来说,如果不考虑io带来的性能瓶颈,Mongodb是最容易支持分布式扩展的。

 Memcached:老牌内存型数据库,不支持数据恢复,而且数据类型单一,只支持键值对存储。随着计算机存储能力的提高,基本上现在都用直接在map中存储的方式替代了。

6. Aop、静态代理和动态代理

问一:什么是Aop?

  Aop是指,在合适的时机,对业务进行横向切面的过程。基于Aop,我们可以完成日志统计,权限校验等功能,从而减少代码的冗余。

问二:静态代理和动态代理的区别是什么?

  基于静态代理,我们要给每个被代理的对象编写代理类,非常不利于程序的开发,动态代理解决了这一问题。

问三:JDK动态代理和Cglib动态代理的区别:

  JDK动态代理基于接口, 不支持对普通java类的代理。因为在底层实现的时候,JDK动态代理需要让代理对象继承Proxy类,而java不支持多继承。

 Cglib动态代理重写了底层字节码,所以支持对普通java 类的动态代理。

 Spring中大量使用了动态代理的模式,在默认情况下,使用JDK动态代理,在无法满足使用时,自动切换到Cglib动态代理。

问四:说说你对注解的理解:

  注解让我们的开发变得标准化,我们需要按照注解要求的格式编程。对于java底层来说,注解就是一个接口。声明的注解自后会成为该类的父接口,而注解参数则成为常量值保存到内存中。

 7. IOC

问一:为什么要引入ioc:

     传统编程中,我们需要创建大量的对象,使用后又需要被销毁,这个过程是需要消耗CPU资源的。之所以引入ioc,就是为了解决这一问题,我们把创建对象的权力交给了框架,专注于业务开发。

问二:Spring加载bean的过程:

   在系统启动过程中,扫描系统中所有文件,将xml中配置的bean,@Component注解和@Bean声明的bean都以BeanDefine的方式保存起来。到了合适的时机,再把他们统一转化为bean对象存储起来,按需加载。需要注意的是,有一部分bean是BeanFactory生产出来的。

 8. JVM

问一:堆和栈

在jvm中,内存被分为堆和栈。堆是用来存放数据块的,栈是用来存储程序运行时的一些信息的(也会存放一些比较小的数据,比如基本数据类型)。程序运行期间,遇到函数调用需要传递参数的时候,传递的其实是堆中的对象地址。

问二:垃圾回收

在jvm中,存在四种不同的引用类型:强引用、软引用、弱引用和虚引用。垃圾回收其实就是对这些不同对象的回收。

强引用:只要程序依然运行,强引用对象永远不会回收掉。

软引用:会在内存溢出前回收掉。

弱引用:垃圾回收时主要回收的东西。

虚引用:它的存在与否对对象本身不会有任何影响,存在的意义只是在垃圾回收该对象时产生一个系统通知。

问三:垃圾回收算法:

标记:从根节点开始,对当前被引用的对象进行标记,然后全局扫描清除没有被标记的对象;

复制:将内存分为两块区域,内存溢出时就将当前被引用的对象复制到另一边,从而清除了没有被引用的对象。

标记-整理:先清理掉没有被标记的对象后,再进行复制。

分代回收:

9. mysql

1. mysql选型:

(1)MyISAM:超高插入和查询速度,不支持事务和外键;

(2)InnoDB:支持事务和外键;

(3)MEMORY:基于内存,访问极快,不可恢复;

(4)MERGE:MyISAM表的组合

2.sql优化: 

 加索引、分表、避免全表扫描

 

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值