一.大厂更重注那些?
之前有人请叫我,问过这样类似的问题“谈一谈大厂给你的感觉,面试大厂面试官更注重那些方面?”
在我看来大厂更重注的有这么几点:
1.基础知识
大厂更注重你的基础知识,你面对问题的时候,是否有自己的思路。思考问题的高度是否以一个工程师的角度去全面的思考问题,因为大厂不确认,需要的是那种能全方位思考问题的人
2.数据结构和算法,设计模式
①数据结构和算法
数据结构和算法其实是分开的东西,我们需要先掌握各种数据结构,再去加深算法,数据结构和算法其实也属于基础,但是它现在越来越重要,所以我就单独拿出来说了。数据结构怎么深入同样我也推荐大家去看清华或者浙大《数据结构》公开课,特别是清华的,值得反复研究。至于算法,首先要做的就是动手,LeetCode上直接干!第二阶段就是要总结各种算法的思想和套路,像递归、动态规划等这些算法都是有套路的,在LeetCode上也有按数据结构和算法分类的筛选,大家可以针对性练习和总结。当然,对于一个Android程序员,能做到每天在LeetCode上刷题就非常不错了,所以一定要坚持,等你坚持到一定的时间,你会发现你越来越游刃有余,我从15年底开始在LeetCode上刷题,目前已经刷了200多道了,小米的面试也非常注重算法,还要能写。而且对一些特别注重算法的公司,算法这块的考核非常严苛,对,就是严苛,而不是严格。
不会简单的考你排序,查找这种考验层面的东西小厂的话大概是因为需要即插即用,也没有很好的导师类资源,更看重你的自我学习能力和一个自我学习的过程,以及实际开发的能力
②设计模式
设计模式中包括了设计原则,其实对于Android开发人员来说,设计模式就那23种,知道并了解这些设计模式是第一个阶段,仅仅是到这个阶段是不够的,一般面试也不会问你某个设计模式的概念,而会让你具体的说说你对某一种设计模式的深入了解和使用,它的优缺点,所以,第二阶段就是要运用它们,其次要和Android源码中运用到设计模式地方进行结合学习。例如建造者模式,Andoird中的Dialog创建就使用到了,还有像单例模式、适配器模式、观察者模式等等都是在Android中非常常用的设计模式,也是在面试中出现频率很高的。
二.中型.大厂面试题【整理总结】
1. 四大组件相关问题
①如果假设A是Standard,B是SingleTop,C是SingleTask,D是SingleInstance的启动模式,那么以A->B->C->D->A->B->C->D这种情况开启Activity,分析一下最后的工作栈是怎样的情况?(大厂)
此题在理解启动模式的情况下解答。
0000.jpg
②Service的两种启动方式简要介绍一下吧?(大厂、小厂)
- 组件通过调用 Context 的 StartService()方法启动一个服务,回调服务中的onStartCommand()。如果该服务还没有被创建,则回调的顺序为 onCreate()->onStartCommand()。服务被启动后会一直保存运行的状态,直到 StopService()或者 StopSelf() 方法被调用,服务停止并回调 onDestroy()。无论调用多少次StartService()只需要调用一次 StopService() 就能终止服务
- 组件通过调用 Context 的 bindService() 可以绑定一个服务,回调服务中的onBind() 方法。类似地,如果该服务之前还没创建,那么回调的顺序是onCreate()->onBind()。之后调用方可以获取到 onBind() 方法里返回的IBinder 对象的实例,从而实现和服务的通信。直到调用了 unBindService() 方法使服务终止,回调顺序 onUnBind()->onDestroy()
③Service 如何和 Activity 进行通信?(中厂)
- 通过绑定服务的方式。在绑定的服务中声明一个Binder类,并创建一个Binder对象,在onBind()函数中返回这个对象,并让Activity实现ServiceConnection接口,在OnServiceConnected方法中获取到Service提供的这个Binder对象,通过这个对象的各种自定义的方法就能完成Service与Activity的通信。
- 通过Intent的方式,在StartService()中需要传入一个Intent对象作为参数,通过这个Intent实例对象进行实现通信。
- 通过Callback和Handler的方式,在绑定的服务中声明一个Binder类,并创建一个Binder对象,在onBind()函数中返回这个对象,让Activity实现ServiceConnection接口,并且在OnserviceConnected方法中实例化Service中的CallBack接口,并且实现OnDataChange()方法,其中的实质是一段Handler代码,可以在其中完成耗时操作,以这种方式完成通信。
2.Android 消息机制
①子线程中使用 Handler 需要注意什么?(中厂)
和在主线程中直接 new 一个 Handler 不同,由于子线程的 Looper 需要手动去创建,需要手动编写 Looper.loop() 与 Looper.prepare() 方法。
@Override
public void run() {
Looper.prepare();//调用Looper.prepare()
new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
}
};
Looper.loop(); //调用Looper.loop()
}
}).start();
②Hanlder 的 postDealy()调用后消息队列会发生什么变化?(中厂)
post delay 的 Message 并不是先等待一定时间再放入到 MessageQueue 中,而是直接进入并阻塞当前线程,然后将其 delay 的时间和队头的进行比较,按照触发时间进行排序,如果触发时间更近则放入队头,保证队头的时间最小、队尾的时间最大。此时,如果队头的 Message 正是被 delay 的,则将当前线程堵塞一段时间,直到等待足够时间再唤醒执行该 Message,否则唤醒后直接执行。
③简要解释一下 ANR?为什么会发生 ANR?如何避免发生 ANR?如何定位 ANR?那你还了解哪些线程间切换的类?简要选一个进行一下阐述吧?(大厂)
这是一连串的提问,涉及到性能优化->ANR问题定位->消息传递->实现原理,所以在面试的时候你尽量不要选择他问一个你答一句话,你可以把你有把握,之前有所准备的内容,按照一个条理跟面试官阐述清楚,他大概会好感度UP。当然必须要对你所说的东西保证充分的熟悉,因为他基本都会抓着你所说的继续跟你深入探讨下去。当然实习僧不会问的特别深入,但是你如果能把原理、机制都跟他说的很清晰有条理且有结构的话。会让面试官对你的好感有一定的上升(我猜的但应该没猜错)。也就是我们开题的时候所说的用工程师的眼光看待问题。什么问题?为什么发生问题?怎么定位并解决问题?
- 以下是我对这道题的回答,只是参考,如果有错误希望指正:
- ANR(Application Not Responding,应用程序无响应):当操作在一段时间内系统无法处理时,譬如:应用在5秒内未相应用户的输入事件。广播接收器10秒内未完成相关的处理。服务20秒内无法处理完成,那么会在系统层面会弹出应用程序无响应的对话框
- 所以为了避免发生ANR,我们尽量使用多线程,不要在主线程做耗时操作,而是通过开子线程,把耗时的工作放在工作线程中处理。所使用的方法比如继承自Thread类、实现Runnable接口、使用AsyncTask、IntentService、HandlerThread等机制
- 如果发生了ANR则可以通过data/anr找到traces.txt文件确定ANR发生的原因。
- 关于上面说的这些多线程机制,如果您感兴趣的话我可以简要的跟你阐述其中的一个或几个机制的具体内容。比如AsyncTask机制,AsyncTask机制底层封装了线程池和Handler,便于执行后台任务以及在子线程中进行UI操作。使用AsyncTask要理解3个泛型参数和4个方法
3. View 及其他控件的使用和优化
①ListView 和 RecyclerView的选择?为什么?(中厂)
- 布局效果:RecyclerView支持线性布局、网格布局、瀑布布局,可以控制横向纵向滚动,从布局效果上来看完爆ListView。
- 基础使用:ListView需要继承重写BaseAdapter类,自定义ViewHolder和重用ConvertView完成优化工作。
RecyclerView继承重写RecyclerView.Adapter和RecyclerView.ViewHolder,设置布局管理器,控制整体布局。规范化了ViewHolder,复用item也不需要像ListView一样SetTag。- 空数据处理:ListView提供了setEmptyView这个API来处理Adapter中数据为空的情况,RecyclerView没提供相应API。
- HeaderFooter:ListView提供了Add\RemoveHeaderView方法解决,RecyclerView没有提供。
- 局部刷新:ListView刷新notifyDataSetChanged()方法,局部刷新需要自己实现。RecyclerView.Adapter则提供了notifyItemChanged()拥有更新单个itemView的刷新。
- 动画效果:Recycler轻松实现,listview需要自己写属性动画,或者调用第三方库
- 监听item事件:ListView专门提供了用于监听item的回调接口,RecyclerView提供的是addOnItemTouchListener
4.四. Java 基础和计网基础
①HashMap 线程安全吗?那如何保证其线程安全呢?(中厂)
可以简单谈谈,使用 Hashtable 或者 ConcurrentHashMap。它们都可以用于多线程的环境,但是当 Hashtable 的大小增加到一定的时候,性能会急剧下降,因为迭代时需要被锁定很长的时间。而 ConcurrentHashMap 引入了分割(segmentation),不论它变得多么大,仅仅需要锁定 map 的某个部分,而其它的线程不需要等到迭代完成才能访问 map。简而言之,在迭代的过程中,ConcurrentHashMap 仅仅锁定 map 的某个部分,而 Hashtable 则会锁定整个map。在 jdk1.8 之后,取消了segments 的方式,而是使用了transient volatile HashEntry[] table 的方式保存数据,将数组元素作为锁,对每一行数据进行加锁,减少了并发冲突的概率。由数组+单向链表变为了数组+单向链表+红黑树,将查询的时间复杂度降至了O(logn)改进了一些性能
②HashMap 有序吗?如何实现有序呢?(中厂)
HashMap 是无序的,而 LinkedHashMap 是有序的 HashMap,默认为插入顺序,还可以是访问顺序,基本原理是其内部通过 Entry 维护了一个双向链表,负责维护 Map的迭代顺序。甚至可以深入的去谈谈 LinkHashMap 的底层实现机制。
由于文章过长,暂且分文2部分讲解,下部讲解
对于项目相关问题的看法
对于注解的理解【有视频】
反射机制
数据结构和算法丶设计模式相关问题
三.写在最后
在最后,我整理了一份资料,如果有需要学习的同学可以联系我免费分享出来的,希望在学习的道路少走弯路,共勉之
领取方式:交流3群820655513
网友评论