前言
双非本科,自认为技术水平不差,8月从美图实习离职回学校,各种倒霉的事不断,到现在11月,为了找个好的环境复习,9月又在学校附近租了房,基本是没有面试通知就学不进去,前面由于过于自信,也没拿个保底的offer,也只去湖大跑过一次58到家的宣讲会,各种面试基本二面挂,最惨的一次的就是美团电话一面后,面试官要我去北京现场面(后来才知道原来美团在长沙和武汉都是有面试点的),还一毛钱没给报销,当时**怕不去就没面试机会了,
9.20那天一个人从长沙跑到北京去面试美团,
20号晚上到了北京,差点露宿街头,各种宾馆酒店满人,电话打不通, 凌晨3点钟还在外面找地方住,最后打了个滴滴,司机带着我满城找地方住,最后找到了个破宾馆的三人间(跟厕所一样臭),然后第2天没吃饭就去面试了,面了一轮就被打发回去了,然后当天晚上回武汉已是凌晨2点,
倒霉的又遇到黑车司机(一个穿黑衣的死胖子),50公里多的路居然要收我400多,去北京一趟来回各种花费估计3000左右,这学期学费还没交,基本上秋招花的钱就是用的这期学费,自己都没舍得买点啥,吃点啥。各种武汉长沙来回跑,也跑过广州,真心累。好在最后拿到了字节跳动Offer, 就此做个总结,希望能给学弟学妹们起到一点帮助。
JAVA 相关
1.静态内部类、内部类、匿名内部类,为什么内部类会持有外部类的引用?持有的引用是this?还是其它?
- 静态内部类:使用static修饰的内部类
- 内部类:就是在某个类的内部又定义了一个类,内部类所嵌入的类称为外部类
- 匿名内部类:使用new生成的内部类
- 因为内部类的产生依赖于外部类,持有的引用是类名.this
2.Java中try catch finally的执行顺序
先执行try中代码,如果发生异常执行catch中代码,最后一定会执行finally中代码
3.equals与==的区别:
==是判断两个变量或实例是不是指向同一个内存空间 equals是判断两个变量或实例所指向的内存空间的值是不是相
4.Object有哪些公用方法?
- 方法equals测试的是两个对象是否相等
- 方法clone进行对象拷贝
- 方法getClass返回和当前对象相关的Class对象
- 方法notify,notifyall,wait都是用来对给定对象进行线程同步的
5.String、StringBuffer与StringBuilder的区别
- String 类型和 StringBuffer 类型的主要性能区别其实在于 String 是不可变的对象
- StringBuffer和StringBuilder底层是 char[]数组实现的
- StringBuffer是线程安全的,而StringBuilder是线程不安全的
6.Java的四种引用的区别
-
**强引用:**如果一个对象具有强引用,它就不会被垃圾回收器回收。即使当前内存空间不足,JVM 也不会回收它,而是抛出 OutOfMemoryError 错误,使程序异常终止。如果想中断强引用和某个对象之间的关联,可以显式地将引用赋值为null,这样一来的话,JVM在合适的时间就会回收该对象
-
**软引用:**在使用软引用时,如果内存的空间足够,软引用就能继续被使用,而不会被垃圾回收器回收,只有在内存不足时,软引用才会被垃圾回收器回收。
-
**弱引用:**具有弱引用的对象拥有的生命周期更短暂。因为当 JVM 进行垃圾回收,一旦发现弱引用对象,无论当前内存空间是否充足,都会将弱引用回收。不过由于垃圾回收器是一个优先级较低的线程,所以并不一定能迅速发现弱引用对象
-
**虚引用:**顾名思义,就是形同虚设,如果一个对象仅持有虚引用,那么它相当于没有引用,在任何时候都可能被垃圾回收器回收。
7.介绍垃圾回收机制
-
标记回收法: 遍历对象图并且记录可到达的对象,以便删除不可到达的对象,一般使用单线程工作并且可能产生内存碎片
-
标记-压缩回收法: 前期与第一种方法相同,只是多了一步,将所有的存活对象压缩到内存的一端,这样内存碎片就可以合成一大块可再利用的内存区域,提高了内存利用率
-
复制回收法: 把现有内存空间分成两部分,gc运行时,它把可到达对象复制到另一半空间,再清空正在使用的空间的全部对象。这种方法适用于短生存期的对象,持续复制长生存期的对象则导致效率降低。
-
分代回收发: 把内存空间分为两个或者多个域,如年轻代和老年代,年轻代的特点是对象会很快被回收,因此在年轻代使用效率比较高的算法。当一个对象经过几次回收后依然存活,对象就会被放入称为老年的内存空间,老年代则采取标记-压缩算法
集合、数据结构相关
1.你用过哪些集合类
数据结构中用于存储数据的有哪些
- 数组
数组存储区间是连续的,占用内存严重,故空间复杂的很大。但数组的二分查找时间复杂度小,为O(1);数组的特点是:寻址容易,插入和删除困难;
- 链表
链表存储区间离散,占用内存比较宽松,故空间复杂度很小,但时间复杂度很大,达O(N)。链表的特点是:寻址困难,插入和删除容易。
2.说说hashMap是怎样实现的
哈希表:由数组+链表组成的
当我们往HashMap中put元素的时候,先根据key的hashCode重新计算hash值,根据hash值得到这个元素在数组中的位置(即下标)
如果数组该位置上已经存放有其他元素了,那么在这个位置上的元素将以链表的形式存放,新加入的放在链头,最先加入的放在链尾。
如果数组该位置上没有元素,就直接将该元素放到此数组中的该位置上。
3.ArrayList,LinkedList的区别
-
ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。
-
对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。
-
对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。
4.ArrayList和Vector的主要区别是什么?
ArrayList 和Vector底层是采用数组方式存储数据
-
Vector:
-
线程同步
-
当Vector中的元素超过它的初始大小时,Vector会将它的容量翻倍,
-
-
ArrayList:
-
线程不同步,但性能很好
-
当ArrayList中的元素超过它的初始大小时,ArrayList只增加50%的大小
-
5.HashMap和 HashTable 的区别:
-
HashTable比较老,是基于Dictionary 类实现的,HashTable 则是基于 Map接口实现的
-
HashTable 是线程安全的, HashMap 则是线程不安全的
-
HashMap可以让你将空值作为一个表的条目的key或value
算法相关
1.排序算法和稳定性,快排什么时候情况最坏?
2.给最外层的rootview,把这个根视图下的全部button背景设置成红色,手写代码,不许用递归
算法原理:
-
Android的view视图是按树形结构分布,所以按树形结构遍历
-
循环判断每一层的ViewGroup元素,将其入栈;否则判断当前view是否是Button类实例,是则改写背景色
-
当前ViewGroup检查childView完成后,判断栈是否非空,取出栈顶元素ViewGroup重复步骤2直至栈为空。