5-6月各种补招和散招才是招聘高峰,也是拿offer的高峰,机会多多。
悲观者往往正确,但乐观者往往成功。不要制造焦虑吓自己。
多为面试准备准备,机会多多也要把握住!
以下都是一线互联网大厂最常见的几个问题,如果是面试Android高级工程师岗,那几乎是必问面试真题:
面试题一、子线程中能不能直接new一个Handler,为什么主线程可以
因为在主线程中,Activity 内部包含一个 Looper 对象,它会自动管理 Looper,处理子线程中发送过来的消息。而对于子线程而言,没有任何对象帮助我们维护 Looper 对象,所以需要我们自己手动维护。所以要在子线程开启 Handler 要先创建 Looper,并开启 Looper 循环
面试题二、Handler导致的内存泄露原因及其解决方案
原因:在Activity内将Handler声明成非静态内部类或者匿名内部类,这样Handle默认持有外部类Activity的引用。如果Activity在销毁时,Handler还有未执行完或者正在执行的Message,而Handler又持有Activity的引用,导致GC无法回收Activity,导致内存泄漏
解决方案:1、静态内部类 + 弱引用
2、如果将Handler声明成可能导致内存泄漏的情况,在Activity销毁时,可清空Handler中未执行或正在执行的Callback以及Message:
3:非静态内部类 + 弱引用,在activity要回收时清除引用
面试题三、一个线程可以有几个Handler,几个Looper,几个MessageQueue对象
一个线程可以有多个Handler,只有一个Looper对象,只有一个MessageQueue对象。Looper.prepare()函数中知道,在Looper的prepare方法中创建了Looper对象,并放入到ThreadLocal中,并通过ThreadLocal来获取looper的对象, ThreadLocal的内部维护了一个ThreadLocalMap类,ThreadLocalMap是以当前thread做为key的,因此可以得知,一个线程最多只能有一个Looper对象, 在Looper的构造方法中创建了MessageQueue对象,并赋值给mQueue字段。因为Looper对象只有一个,那么Messagequeue对象肯定只有一个
面试题四、Message对象创建的方式有哪些区别
1.Message msg = new Message();每次需要Message对象的时候都创建一个新的对象,每次都要去堆内存开辟对象存储空间
2.Message msg = Message.obtain();obtainMessage能避免重复Message创建对象。它先判断消息池是不是为空,如果非空的话就从消息池表头的Message取走,再把表头指向 next。如果消息池为空的话说明还没有Message被放进去,那么就new出来一个Message对象。消息池使用 Message 链表结构实现,消息池默认最大值 50。消息在loop中被handler分发消费之后会执行回收的操作,将该消息内部数据清空并添加到消息链表的表头。
3.Message msg = handler.obtainMessage(); 其内部也是调用的obtain()方法
这些常问的面试题。如果你是面试者,你会如何回答,能回答多少呢?
由于文章篇幅有限,只能展示部分面试题,有需要完整文档的可以点击此处 即可免费领取!
部分面试题:
1.Java中的==、equals和hashCode的区别
2.int和integer的区别
3.String、StringBuffer和StringBuilder的区别
4.什么是内部类?内部类的作用是什么?
5.进程与线程的区别
6.final、finally、finalize的区别
7.Serializable和Parcelable的区别
8.静态属性和静态方法是否可以被继承?是否可以被重写?
9.成员内部类、静态内部类、局部内部类、和匿名内部类的理解
10.Java的垃圾回收机制及其在何时会被触发
11.Java中的代理是什么?静态代理和动态代理的区别是什么?
12.Java中实现多态的机制是什么?
13.Java中反射的相关理解
14.Java中注解的相关理解
15.对Java中String类的理解
16.对Java中字符串常量池的理解
17.Java中为什么String类要设计成不可变的
18.Java中Hash码(哈希码)的理解
19.Object类的equal方法和hashcode方法的重写
20.Java常用集合List与Set,以及Map的区别
21.ArrayMap和HashMap的区别
22.HashMap和HashTable的区别
23.HashMap和HashSet的区别
24.ArrayList和LinkedList的区别
25.数组和链表的区别
26.Java中多线程实现的三种方式
27.Java中创建线程的三种方式
28.线程和进程的区别
29.Java中的线程的run( )方法和start()方法的区别
31.Java中wait和sleep方法的不同
32.对Java中wait/notify关键字的理解
33.什么是线程阻塞?线程该如何关闭?
34.如何保证线程的安全
35.实现线程同步的方式
36.Java中Synchronized关键字的用法,以及对象锁、方法锁、类锁的理解
37.Java中锁与同步的相关知识
38.Synchronized和volatile关键字的区别
39.Java的原子性、可见性、有序性的理解
40.ReentrantLock、Synchronized、Volatile关键字
41.Java中死锁的概念,其产生的四个必要条件
42.Java中堆和栈的理解
43.理解线程间通信
44.线程中的join()方法的理解,及如何让多个线程按顺序执行
45.工作者线程(workerThread)与主线程(UI线程)的理解
46.AsyncTask(异步任务)的工作原理
47.并发和并行的区别及理解
48.同步和异步的区别、阻塞和非阻塞的区别的理解
49.Java中任务调度的理解
50.Java中进程的详细概念
51.线程的详细概念
52.Android中的性能优化相关问题
53.内存泄漏的相关原因
54.通过Handler在线程间通信的原理
55.Android中动画的类型:
55.理解Activity、View、Window三者之间的关系
56.Android中Context详解:
57.Java中double和float类型的区别
58.Android常用的数据存储方式(4种)
59.ANR的了解及优化
60.Android垃圾回收机制和程序优化System.gc( )
61.Android平台的优势和不足
62.其他讲解:
- Activity组件
- Service组件
- BoradcastReceiver组件
- ContentProvider(内容提供者)组件
- Fragment
- ViewPager
- Android的事件传递(分发)机制
- Bitmap的使用及内存优化
- 使用View绘制视图
- Android内存泄漏及管理
- Android设计模式之MVC
- JVM运行原理详解
- Android平台的虚拟机Dalvik
- Java的内存分配
- Android中的Binder机制
- Android中的缓存机制
- Android 中图片的三级缓存策略