阿里电话面试
最近有看什么书:
以后想深入了解哪一行,不只是工作。
1.排序的分类,冒泡排序和快排的实现
2.快排的最差情况:
经典快排总拿第一个数进行划分,这样在数组有序的情况下,每次划分都得到最坏的结果,都是左边 n-1个数,右边0个数,每次划分都只能减少一个数,T(n) = T(n-1) + 1;快排将退化成冒泡排序。
解决办法是:随机化算法,随机选取一个元素作为划分点,这样,虽然在最坏情况下仍然是O(n^2),但是最坏的情况就不再依赖初始数据状况了,而是取决于随机元的选取。
int num = (int)(Math.Random()*(high - low + 1) + low);
3.怎么判断一个数组是有序的:
4.图相关的问题:判断有向图中是否形成环
对于图的问题,一般选择DFS或BFS进行遍历
1.拓扑排序的方法:找到入度为0的点,删除,并且删除以它为出发点的边,一直重复上面的步骤,然后当没有顶点时或者没有入度为0的点时,停止循环。没有定点的情况是没有环,另外一种是有环。
2.另一种方法是利用BFS深度优先遍历,然后用一个数组进行记录是否遍历过,如果有遍历了两次的顶点,则含有环,否则不含环。(使用邻接矩阵)
5.hashmap
底层的数据结构:桶数组+链表+红黑树
操作的平均时间复杂度O(1)
1.计算hash值,得到index位置
2.在桶数组中找到index的位置,得到链表或红黑树
3.遍历链表或红黑树,取出相应的键值对
4.从键值对中取出value
设计优秀的hash算法,以减少hash冲突,这样使得链表的长度尽可能的短,当理想状态下,链表长度为1时,时间复杂度就是O(1)
为什么链表切换成红黑树:当链表长度超过8时,转化为红黑树,利用红黑树快速增删改查的特点提高HashMap的性能
有没有可以替代红黑树的数据结构:回答的是AVL树,B树。
6.B树和红黑树的区别,与应用场景
平衡二叉树:
AVL树:最早的平衡二叉树,windows对进程地址空间的管理用到了AVL树,平衡性最好,查询的复杂度是O(logn)
红黑树:HashMap中用到了
这些树都是用在内存中的数据结构,因为要保持平衡,数据要不停的搬来搬去,如果换做磁盘中,开销就会很大。
B/B+树(多路查找树):用在磁盘文件组织,数据索引和数据库索引中
每个结点有更多的孩子,新值可以插入在已有的结点里,而不需要改变树高度,从而大量减少重新平衡和数据迁移的次数,这样非常适合做数据库索引,这种需要持久化在磁盘,同时需要大量查询和插入操作的应用。
磁盘的查找存取的次数一般是由树的高度决定的,选用多路查找树,可以使树保持较低的高度,从而有效的避免频繁的查找存取的操作,从而提高查找效率。(每增加一层深度,要多一次IO,每次IO时,应该尽量多拿一些数据出来,避免多次IO,耗时)
Trie树(字典树):用在统计和排序大量字符串。
7.java虚拟机
判断一个对象可不可以回收
1.引用计数法
2.可达性分析:通过GC roots对象作为起始点,从结点向下开始搜索,搜索过得路径组成引用链,当一个对象没有与引用链相连时,(不可达),那证明这个对象是不可用的。
可作为GC roots的对象:
1.栈中的对象
2.方法区中的静态属性和常量引用的对象
3.本地方法区中native引用的对象
8.触发回收条件:
Minor GC(年轻代):
当Eden区满时,触发Minor GC,非常频繁。
Full GC(老年代):
1.调用System.gc时,只是系统建议Full GC,但不一定执行
2.老年代内存不足
3.方法区空间不足
4.MinorGC之后,放入老年代的平均大小大于老年代的可用内存
5.有Eden区,fron space区向 to space复制时,对象大小大于to space 的可用内存,把它转入老年代,此时老年代的可用内存小于该对象的大小。
9.什么时间进入老年代
1.优先分配到Eden区
2.大对象直接放到老年代
3.长期存活的对象进入老年代(15此)
4.空间分配担保
10.数据库的聚簇索引和非聚簇索引区别
11.在表中存在联合索引时,id name age 三个字段建立联合索引,查询时 select * from user where id=1 会用到索引吗?
1.如果查询条件只出现了联合索引的第一列,或者全部,则能利用联合索引
2.条件列中只要条件相连在一起,无论前后,都会用上联合索引
3.查询条件中没有出现联合索引的第一列,而出现了联合索引的第二列,或第三列,则不会用联合索引查询。
单一列索引:只要条件列中出现索引列,无论在什么位置,都能利用索引查询。
参考https://blog.csdn.net/lingzhm/article/details/78020812
12.操作系统中进程与线程的区别
1.进程是执行着的应用程序,是操作系统进行资源分配和调度的基本单位,它是有自己独立的内存空间,通信比较困难,但是它有比较固定的入口和执行顺序和出口。
2.线程是进行的一个序列,是CPU调度和分配的最小单元,而且线程之间是共享内存的,通信方便,不过线程的调用是通过进程控制的。
13.数据库中的乐观锁和悲观锁分别是什么,应用的场景
乐观锁:读操作
悲观锁:写操作
14.从10w个大小不同,无序的整数,从其中找到最大的三个数。(提示:对比比赛中的淘汰制度。类似于二分法)