java 基础必看

小凯   |     |   面试题   |   19分钟   |   219浏览  

java集合篇

1、List、Set、Map的区别

List: 集合内允许存在重复元素、内部有序
Set: 集合内不允许存在重复元素,内部无序(有特殊)
Map: 是一种键值对形式无序(有特殊)集合。其中key不允许重复且不能为关键字,value没有限制。

2、常用的List、Set以及Map的实现类,以及他们的底层实现和特点

List的实现类:

  • ArrayList:

    1、底层为动态数组
    2、有序集合、
    3、支持随机访问查询快,数组的内存划分是一块,可以通过索引直接访问,时间复杂度为O1)、
    4、增删慢删除时会遍历寻找,操作元素位于数组中间时,会影响前后元素索引,时间复杂度为On)、
    5、占用空间 >= 元素个数,
    6、初始容量为10,
    7、扩容倍数为1.5倍(每次增加0.5)
    8、元素可重复
    参考:https://www.bilibili.com/video/BV1Gy4y1u7Gr
    p=1&vd_source=a754d9ef602dc1c465a7f73cca0146f9

  • LinkedList:

    1、底层为双向链表
    2、有序集合、
    3、不支持随机访问(查询慢,需要从头或尾遍历链表,不能直接访问,时间复杂度为On)
    4、增删快(删除时会遍历寻找,操作元素不影响其他元素,时间复杂度为O1)
    5、占用空间 == 元素个数,
    6、初始容量为0,
    7、随元素增多而增大容量
    8、元素可以重复
    参考:https://www.bilibili.com/video/BV1Gy4y1u7Gr
    p=1&vd_source=a754d9ef602dc1c465a7f73cca0146f9
    Map的实现类:

  • HashMap:

    1、底层为数组+链表 + 红黑树(jdk1.8后)
    2、无序集合,
    3、支持随机访问(查询快,时间复杂度O1)、
    4、增删慢(底层为数组,原因类比ArrayList)、
    5、允许key为null、
    6、允许value为null、
    7、线程不安全、
    8、初始容量 1 << 4,
    9、扩容倍数为2倍(扩容因子为0.75f,达到阈值时进行扩容)

  • LinkedHashMap:

    1、底层为HashMap+双向链表(仅为保证顺序)
    2、有序集合(分为插入顺序、访问顺序【put、get后的元素会将已存在的entry元素先删除、再插入的方式放到链表末端】)
    3、线程不安全、
    4、其他和HashMap一致

  • TreeMap:

    1、底层为红黑树
    2、有序集合,
    3、支持随机访问(查询快,时间复杂度On)、
    4、增删慢(底层为红黑树,操作元素时会进行旋转【左旋、右旋】操作元素影响其他元素,时间复杂度On)、
    5、不允许key为null、
    6、允许value为null、
    7、线程不安全、
    8、初始容量为0,
    9、随元素增多而增大容量

  • HashTable:

    1、底层为数组+链表
    2、无序集合,
    3、支持随机访问(查询快,时间复杂度为O1)、
    4、增删慢(底层为数组,原因类比ArrayList)、
    5、不允许key为null、
    6、不允许value为null、
    7、线程安全、
    8、初始容量为11、
    9、扩容倍数为2倍+1(扩容因子为0.75,达到阈值时进行扩容)
    Set的实现类:

  • HashSet:

    1、底层为HashMap
    2、无序集合
    3、元素不重复、
    4、线程不安全、
    5、不支持随机访问(未提供get方法)、
    6、初始容量1 << 4(与HashMap同步)
    7、扩容倍数为2倍(与HashMap同步)
    8、可以为null

  • LinkedHashSet:

    1、底层为HashSet
    2、有序集合
    3、线程不安全,
    4、元素不重复
    5、可以存储null
    6、效果类比LinkedHashMap

lambda篇

1、常用的lambda表达式

filter(过滤)、distinct(去重)、map(类型转换)、foreach(循环)、collect(收集)、sorted(排序)、reduce(累计计算)、count(计数)、max(最大值)、min(最小值)、limit(限制长度)、anyMatch(是否任何匹配)、allMatch(是否所有匹配)、noneMatch(是否都不匹配)、findFirst(找出第一个)

2、创建stream的四种方式

1、单链集合: 对象.stream()
Stream stream = arrayList.stream();
2、双链集合: 先转成单链集合,再使用单链集合的方式
Set set = hashMap.keySet();//取出单链集合
Stream stream = arrayList.stream();//单链集合获取流
3、数组: Arrays.stream(数组)
Stream stream = Arrays.stream(intArray);
4、工具类: Stream.of(元素)
Stream stream = Stream.of(10,20,30);

线程篇

1、java如何创建线程

方法一:继承thread类,重写run方法。调用start()方法。
方法二:实现runable接口,重写run方法;作为参数创建thread对象。调用start()方法。
方法三:实现callable接口,重写call方法,作为参数创建FutureTask对象,作为参数创建thread对象。调用start()方法。

2、java如何创建线程池

方法一:通过java原生线程池对象ThreadPoolExecutor。通过execute方法执行线程。
ThreadPoolExecutor executor = new ThreadPoolExecutor(核心线程数, 最大线程数, 非核心线程空闲时间, 时间单位, 任务阻塞队列, 线程创建工厂, 拒绝策略)
拒绝策略:
ThreadPoolExecutor.AbortPolicy: 丢弃任务并抛出RejectedExecutionException异常。
ThreadPoolExecutor.DiscardPolicy:直接丢弃任务,但是不抛出异常(什么都不做)。
ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务。调用被拒绝任务的run方法
方法二:通过Executor对象创建封装好的线程池(不建议)。
本质上是对方法一的方式进行封装,但是内置的线程池方式有局限性(容易导致OOM内存溢出)

//todo 创建固定线程池       LinkedBlockingQueue任务队列为无边界,容易导致OOM
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(5);
//todo 创建缓存线程池       SynchronousQueue任务队列无影响; 最大线程数为Integer.MAX_VALUE, 容易导致OOM
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
//todo 创建单线程的线程池     LinkedBlockingQueue任务队列为无边界,容易导致OOM
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
//todo 创建延迟定时线程池       DelayedWorkQueue任务队列为无边界优先级队列,容易导致OOM; 最大线程数为Integer.MAX_VALUE,容易导致OOM
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(5);

概念篇

1、什么是OOP思想?OOP思想的核心要点?

OOP(面向对象编程)是模拟现实世界的对象以及对象之间的关系的一种编程思维。把世间万物抽象成独立的类(class),不同的类定义了不同的属性(field)和行为(method),类有不同实例对象(object),不同对象属性和行为可能不同。
OOP思想核心要点:
封装:将对象的核心数据和方法封装在对象中,只将必要的接口暴露外部访问。
继承:允许类可以从另一个类中继承属性和方法,这样得到了代码的复用,更方便维护。
多态:允许对象可以在多个类中切换身份,在运行时可以动态决定对象使用哪个类的方法。

2、什么是泛型?简要概述一下。

泛型基于多态的思想,可以定义通用的类型作为参数进行编程。避免了编写多余重复的代码。泛型出错会在编译时报错,能够避免在运行时出现转换异常。

3、OOM是什么?导致原因?如何避免解决?

OOM(内存溢出)是指JVM在运行时需要足够的运行空间,当运行空间不足时会出现OOM错误。
导致原因大致有:
1、长时间未使用的对象未被回收,可以理解为一个短生命周期的对象拥有长生命周期的对象属性;
2、递归调用深度过大,会消耗大量的栈空间;
3、代码设计不合理,内存中操作的数据过大,严重占用JVM内存;
避免解决:
1、优化代码,比如在处理大数据时,可以采用分页处理的方式。
2、增加JVM内存

4、初始化块、静态代码块、构造方法的加载顺序?

1、先执行静态代码块(父类->子类)
2、执行父类(初始化块->构造方法)
3、执行子类(初始化块->构造方法)
总结:静态代码块->初始化块->构造方法

如果你觉得文章对你有帮助,那就请作者喝杯咖啡吧☕
微信
支付宝
  条评论