面试集锦(六)数据结构(1)

357 阅读5分钟

java集合框架

collection和map

collection子类:

1.list 元素有序可重复

实现:arraylist类似动态数组,长度可变,默认10

不是线程安全的,可用vector代替

linkedlist.类似于双向链表.适合增删,不是线程安全的

arraylist,适用于查找

2.set 元素无序不可重复(根据hashcode确定位置)

实现:hashset,底层基于hashmap实现

linkedhashset.基于linkedhashmap实现,与hashset区别是增加了链式表结构

treeset:是一种二叉排序树

3.queue

实现:queue+list - > linkedlist

map

键值对形式,key不能重复,value允许为空

实现类:hashmap

线程安全的map:currenthashmap, 不仅线程安全而且效率高(底层红黑树查询效率较高)

数组和链表的区别

1.数组固定长度,容易浪费或不足,链表可以动态分配

2.数组是在栈中(除了new出来的)分配,方便但是自由度差,链表是在堆中分配,自由度大但是管理麻烦

3.数组用下标进行访问,速度快,链表必须从头访问,速度慢

4.链表适合增删

hashmap和hashtable的区别

1.hashmap是线程不安全的,hashtable是线程安全的

2.hashmap键,值都允许null存在,hashtable则不允许

3.线程原因,hashmap效率相对较高

hashmap的实现机制

1。维护一个每个元素都是一个链表的数组,链表中的每个节点是一个entry【】键值对的数组

2.实现了数组+链表的特性,所以增删查改都很快

3.每个新加入的节点放在链表首,然后该新加入的节点指向原链表首

4.对于每个key,对应的数组索引下标示int i = hash(key,hashcode)& (len - 1)

堆,栈,队列的区别

栈 用来存放局部变量,形参或者计算的中间结果,变量所处的作用域一旦结束就立即释放,先进后出

堆 用来存放数组和new的对象或者成员变量,凡是new出来的都存在堆中(新建对象),不自动回收,用户不能访问

队列 线性结构,先进先出(实现树的层次遍历)

string,stringbuffer和stringbuild区别

string每次操作字符串时都会生成新的对象

stringbuffer不会生成新对象,而且是线程安全的

stringbuilder是线程不安全的(推荐常用)

算法思想

1.贪心算法(局部最优解)

2.分治算法(将规模为n的问题分为k个小问题,每个问题相互独立且性质相同,求出小问题的解即得原问题的解)

3.动态规划算法(与分治法类似,前一问题为后一问题提供信息,根据可能的解保留最优解,丢弃其他局部解)

4.回溯算法(搜索尝试的过程,当不满足条件时回溯返回)

5.递归算法(对重复问题分解为子问题,有一个递归终止条件)

抽象类和接口的区别

1.继承方面:一个类只可以继承一个类,可以实现多个接口

2.抽象方法方面:接口中全是抽象方法,抽象类中即可以有抽象方法,又可以有方法体

3.构造方法方面:接口中无构造方法。抽象类中有构造方法

4.实例化方面:抽象类不可以被实例化,接口不可以被继承

5.修饰符方面:抽象类中方法可以用除了private以外的修饰符,接口中默认是public的

6.实现速度方面:抽象类比接口速度快

7.添加新方法时:抽象类不需要更改当前代码,但是接口需要更改实现该接口的类

object类的公用方法

1.equals判断是否相等

2.clone克隆对象

3.tostring

4.hashcode方法

5.线程同步的方法

6.getclass获取和当前类有关的信息

jdk1.8新特性

1.允许接口添加一个非抽象的方法实现,只需要使用default关键字即可

2.lambda表达式(允许把一个函数作为一个方法的参数传递进方法中)

4.Date time api加强对时间和日期的处理

5.optinal类,用来解决空指针异常

如何实现对树的层次遍历--->队列

链表(更改指针)

链表面试常见类型

结构:数据域+下一个节点的指针域

作用:数据的存储按照一定的顺序存放,可以在任意节点增加,删除

类型:单向链表,双向链表,循环链表

优点:顺序结构,适合增删

缺点:有指针域,占用空间大;只知道头节点的地址,查找麻烦

1.链表反转:定义三个指针,分别记录当前遍历到的结点,它的前一个结点以及后一个结点,然后依次遍历,将当前结点的指针指向上一个结点

2.从尾到头打印链表(反转顺序第一时间想到栈)

3.合并有序链表

4.判断链表是否有环:定义两个指针,我们用两个指针去遍历:first指针每次走一步,second指针每次走两步,如果first指针和second指针相遇,说明有环。

5.求链表的倒数第k个结点

我们定义两个指针,第一个指针从链表的头指针开始遍历向前走k-1步,第二个指针保持不动:从第k步开始,第二个指针也开始从链表的头指针开始遍历,由于两个指针的距离保持在k-1,当第一个(走在前面的)指针到达链表的尾结点时,第二个指针(走在后面的)指针正好是倒数第k个结点.。