一、说说和的区别?作为运算符 将二进制的每一位进行与运算作为逻辑运算符两者都是与 如果左边为假则终止右边运算即短路运算。 则需要把两边的比较执行完二、int和Integer的区别int是Java的基本数据类型而Integer是int的包装类int直接存储整数值而Integer是一个对象包含了一些额外的方法和功能int的默认值是0而Integer的默认值是null扩展那么我们在判断这两个类型是否相等的时候有什么要注意的呢int 和 int 类型的比较可以直接用 判断int 和 Integer 类型的比较时也可以用 、 Integer会自动拆箱为 intInteger 和 Integer 类型的比较中。如果数值范围在[-128,127]之间可以用 。其他范围只能用 equals 方法、原因是JVM会维护这个范围内的缓存比如第一个Integer是127会存放在缓存中在创建第二个Integer时会直接返回缓存的127所以两者是相等的三、接口和抽象类的区别1.语法层面抽象类可以提供成员方法的实现细节而接口中只能存在public abstract 隐式声明方法(JDK8默认方法)抽象类中的成员变量可以是各种类型的而接口中的成员变量只能是public static final隐式声明类型的必须在声明时赋值接口中不能含有静态代码块以及静态方法而抽象类可以有静态代码块和静态方法一个类只能继承一个抽象类而一个类却可以实现多个接口。2.设计层面抽象类是对整个类进行抽象包括属性行为方法那么一定是抽象类的种类拥有同一种属性或行为的类接口是对行为行为的抽象抽象类是一种模板设计。接口是一种规范。3.怎么选择如果拥有一些方法并想让他们中的一些有默认的具体实现请选择抽象类如果想实现多重继承那么请使用接口由于java不支持多继承子类不能继承多个类但一个类可以实现多个接口因此可以使用接口来解决。如果基本功能在不断变化那么就使用抽象类如果使用接口那么每次变更都需要相应的去改变实现该接口的所有类。4.JDK8中为什么会提供默认方法目的用来减少抽象类和接口的差异可以在接口中提供默认的实现方法并实现该接口的类不用强制去实现这个方法。JDK8中接口的静态方法只能通过接口名直接去调用接口中的默认方法因为不是abstract的所以可重写也可以不重写。四、谈谈你对树Tree的理解(数据结构)?1、树的由来数组检索效率高链表添加删除效率高树综合检索和操作的效率2、树的分类根据不同的分类方式树可以分为不同的类型根据树分支的数量限制可以分为二叉树和多叉树。二叉树最多只有两个子节点而多叉树一个节点可以有多于两个的子节点。根据树节点的有序性可以分为查找树和无序树。查找树的基本特征为任意一个节点所包含的键值大于等于左孩子的键值小于等于右孩子的键值。无序树则没有特定的键值大小关系。根据具体用途和特征例如红黑树、AVL树、平衡二叉树、平衡二叉搜索树等。红黑树是一种自平衡二叉查找树AVL树也是一种自平衡二叉查找树它要求任何节点的两个子树的高度差最大为1。平衡二叉树和平衡二叉搜索树则是为了平衡树的左右子树的高度差。根据树的完整性和是否包含空值可以分为完全二叉树、满二叉树、完全二叉搜索树、满二叉搜索树等。完全二叉树和满二叉树是包含所有节点的二叉树而完全二叉搜索树和满二叉搜索树则是所有节点都按照一定顺序排列的二叉搜索树。3、常见树的特点普通二叉查找树倾斜的问题AVL自平衡左旋右旋开销问题红黑树黑节点平衡、深度问题、二叉。作为内存中数据存储B树和B树多路查找、深度比较少、一般用于大规模数据存储、索引4、TreeMap和HashMap的区别HashMap的综合效率为什么比TreeMap高什么我们工作中常用HashMap而不用TreeMapTreeMap本质就是红黑树的实现HashMap以jdk8为例。就是通过 数组链表红黑树算法实现的通过上面的实现也可以看到HashMap综合的读写效率要比TreeMap高了五、HashMap面试汇总1. jdk8为什么引入了红黑树因为链表长度增加后检索的效率急剧降低复杂度是 O(n) [https://blog.csdn.net/heihei2017/article/details/102775283]2.解决hash冲突。为什么不直接用红黑树?因为红黑树需要进行左旋右旋变色这些操作来保持平衡而单链表不需要。当元素小于 8 个的时候此时做查询操作链表结构已经能保证查询性能。当元素大于 8 个的时候 红黑树搜索时间复杂度是O(logn)而链表是 O(n)此时需要红黑树来加快查询速度但是新增节点的效率变慢了。因此如果一开始就用红黑树结构元素太少新增效率又比较慢无疑这是浪费性能的。3.为什么链表改为红黑树的阈值是 8首先和hashcode碰撞次数的泊松分布有关主要是为了寻找一种时间和空间的平衡。在负载因子0.75HashMap默认的情况下单个hash槽内元素个数为8的概率小于百万分之一将7作为一个分水岭等于7时不做转换大于等于8才转红黑树小于等于6才转链表。链表中元素个数为8时的概率已经非常小再多的就更少了所以原作者在选择链表元素个数时选择了8是根据概率统计而选择的。4. 默认加载因子为什么是0.75这个是从时间和空间的角度综合得出的。如果是1.0 当数组的值全部填充了才会发生扩容此时Hash冲突是避免不了的。链表的操作或者红黑树的操作会牺牲时间来保证空间的利用率如果是0.5 当数组中一半的数据利用了之后就会开始扩容。这时填充的数据少。hash冲突也会减少底层的链表和红黑树的高度也会降低。查询效率增加。但是这时还有太多的空间没有利用。空间资源浪费了。所以0.75是综合考虑得出的5.为什么要右移16位其实是为了减少碰撞进一步降低hash冲突的几率。int类型的数值是4个字节的右移16位异或可以同时保留高16位于低16位的特征当数组的长度很短时只有低位数的hashcode值能参与运算。而让高16位参与运算可以更好的均匀散列减少碰撞进一步降低hash冲突的几率。并且使得高16位和低16位的信息都被保留了。在HashMap的put方法里面是通过Key的hash值与数组的长度取模计算得到数组的位置。而在绝大部分的情况下n的值一般都会小于2^16次方也就是65536。所以也就意味着i的值 始终是使用hash值的低16位与(n-1)进行取模运算这个是由与运算符的特性决定的。这样就会造成key的散列度不高导致大量的key集中存储在固定的几个数组位置很显然会影响到数据查找性能。6.为什么Hash值要与length-1相与把 hash 值对数组长度取模运算模运算的消耗很大没有位运算快。 当 length 总是 2 的n次方时h (length-1) 运算等价于对length取模也就是 h%length但是 比 % 具有更高的效率。7.介绍下put方法的流程首先根据 key 的值计算 hash 值找到该元素在数组中存储的下标如果数组是空的则调用 resize 进行初始化如果没有哈希冲突直接放在对应的数组下标里如果冲突了且 key 已经存在就覆盖掉 value如果冲突后发现该节点是红黑树就将这个节点挂在树上如果冲突后是链表判断该链表是否大于 8 如果大于 8 并且数组容量小于 64就进行扩容如果链表节点大于 8 并且数组的容量大于 64则将这个结构转换为红黑树否则链表插入键值对若 key 存在就覆盖掉 value。