switch能否用string做参数
object有哪些公用方法:equals和==,hashcode,clone,wait,notify等
String、StringBuffer与StringBuilder的区别。
try catch finally,try里有return,finally还执行么?
Excption与Error包结构。
Override和Overload的含义与区别。
Interface与abstract类的区别。
Static class 与non static class的区别。
foreach与正常for循环效率对比。
反射机制
String类内部实现,能否改变String对象内容,String源码
Java1.7与1.8新特性。
java集合框架的结构
list,set,map接口
哪些是线程安全,哪些不安全
hashmap能否用null作为键或值
hashmap源码
快速失败与安全失败
arraylist,linkedlist底层实现区别,如何扩容
treemap,hashmap,linkedhashmap区别和特点,底层实现的区别
如何解决不安全的集合的安全性问题
强软弱虚四种引用
java内存分区
java的个内存分区在什么情况下内存溢出
java垃圾回收机制,垃圾收集算法特点及工作在哪一代,分代收集策略,如何判断一个对象该被回收了,java对象实现如何自救,java的垃圾收集器,内存分配与回收及分配担保
java的类加载机制,类加载的5个步骤,类加载器
线程生命周期
java如何使用多线程(runnable和Thread)
stop,resume,suspend的缺点
终止线程有哪些方法
守护线程
synchronize关键字和wait,notify,notifyAll
lock与condition,Java中的几种不同锁
线程死锁情景
消费者生产者模型
volatile关键字,是否保证原子性,优缺点
ThreadLocal的特点和使用
单例模式和多线程
SimpleDateFormat的安全性问题
java的并发容器包Concurrent。阻塞队列,CopyOnWriteList等
ConcurrentHashMap的源理
java的线程池原理和自带的四大线程池
Executor框架
五种布局的特点和效率对比
Activity的生命周期和缓存
Fragment的生命周期
Service的两种启动方式,如何保证一个Service不被杀死
广播注册的两种方式的区别
如何安全的退出一个已经开启多个activity的APP
Android的进程优先级
Asset目录与res目录的区别
ANR问题,force close问题,activity,service,broadcast各自超过多少秒报ANR
Activity启动模式,intent匹配规则
Android反编译
JNI和native方法
Android系统的有哪些安全机制
Android新特性有哪些(5.0 6.0 7.0)
Dalvik和ART区别
Android屏幕适配有哪些方法
View事件体系,滑动冲突
View绘制原理,性能问题(view绘制间隔16ms,60fps),measure,layout,draw三大过程
如何避免overdraw
自定义View相关知识,下拉刷新的实现
Android动画分类和各自特点
View和SurfaceView的区别
APK瘦身的办法
ListView的源码和如何优化Listview
Android如何获取Crash信息
ANR日志分析
Android动态加载,如何解决方法数越界
Android怎么加速启动Activity
Android内存泄漏问题,内存泄漏分析工具
Android内存溢出问题,图片的三级缓存
Android系统开机过程
Zygote和System进程的启动过程
Activity的启动过程
Android的消息机制,Handler原理
AsyncTask源码,优缺点
HandlerThread和IntentService的原理和特点
Android的IPC机制
AIDL原理
Binder机制原理
ActivityManagerService
项目各个细节熟练,熟悉项目用到的框架源码
Volley
xUtils
okHttp
UniversalImageLoader
RxJava
本人面的Android岗位。由于基本都是内推的,所以没有刷过那些变态的笔试题。也算比较幸运
准备阶段:在校招开始之前,刷了一个月的Leetcode,看了一周的计算机网络,一周的操作系统,一周的Java编程思想,一周Android相关的知识。自己之前有专门整理过项目遇到的坑,所以这一块没怎么花时间。
具体用书:
操作系统:《现代操作系统》、《Operating Systems: ThreeEasyPieces》
计算机网络:《TCP/IP卷一》、王道考研的计算机网络分册
Android:《Android小工》、《Android开发艺术探索》
Java:《Java编程思想》、《effective java》
背景交代完毕。就开始面试啦
校招最开始的就是百度啦
一面
总共面了四道算法
3sum & 3sum-closet
Search Insert Position
Trapping Rain Water 这一道题卡住了,面试官就让我先写个快排压压惊,然后压完继续这个题。蛋疼
辛亏最后写出来了。一面就这样过去了
二面
面试官看我简历写了C++,就先开始问我C++了
指针和引用的区别
STL 内存分配方式
仿函数有什么用,和函数指针有什么不同,哪个效率高
虚函数的作用,优点
进程线程的区别
select和epoll区别,select为什么慢
TCP UDP的不同 TCP三次握手
接着就是聊Android项目遇到的坑了~
三面是总监面就问了两个问题
一个如何维持一个长连接
如何实现进程保活
腾讯
一面
一开始就让写了个快速排序
Recover Binary Search Tree(Leetcode)
项目中有没有见过内存泄漏?为什么会产生?怎么解决的?
Handler的原理
Binder的原理
String、StringBuilder、StringBuffer
二面
Binder的原理
Binder里面引用计数的原理
Binder底层为什么用红黑树,红黑树的原理知道吗
JVM分区,分别解释
垃圾回收器的分类及优缺点
Retrofit的原理,为什么不用volley
为什么选用Glide,原理?
LruCache的原理
网易
一面
TCP/IP分层
Android系统框架
synchronized和锁区别
handler和asyncTast的区别,然后让我自己设计线程池怎么做
Fragment好处,碰到过什么bug,怎么解决的
java的四种引用的区别
最后让写了一个约瑟夫环问题的代码
二面
为什么选用Realm,原理是什么
Binder的原理
HashMap && HashTable && ConcurrentHashMap
红黑树的原理
如何设计一个网络加载框架
volatile关键字的原理
华为
一面
Android四大组件的理解(这个扯了十多分钟)
ContentProvider的启动过程
Activity的四种启动模式,用过哪一种,为什么要用
Service和InentService的区别
View的事件分发和绘制原理
如何解决滑动冲突
基础无外乎几部分:语言(C/C++或java),操作系统,TCP/IP,数据结构与算法,再加上你所熟悉的领域。这里面其实有很多东西,各大面试宝典都有列举。
在这只列举了Android客户端所需要的和我面试中所遇到的知识点,尽量做到全面,如果你掌握了以下知识点,去面android客户端应该得心应手。
J2SE基础
1.九种基本数据类型的大小,以及他们的封装类。
2.Switch能否用string做参数?
3.equals与==的区别。
4.Object有哪些公用方法?
5.Java的四种引用,强弱软虚,用到的场景。
6.Hashcode的作用。
7.ArrayList、LinkedList、Vector的区别。
8.String、StringBuffer与StringBuilder的区别。
9.Map、Set、List、Queue、Stack的特点与用法。
10.HashMap和HashTable的区别。
11.HashMap和ConcurrentHashMap的区别,HashMap的底层源码。
12.TreeMap、HashMap、LindedHashMap的区别。
13.Collection包结构,与Collections的区别。
14.try catch finally,try里有return,finally还执行么?
15.Excption与Error包结构。OOM你遇到过哪些情况,SOF你遇到过哪些情况。
16.Java面向对象的三个特征与含义。
17.Override和Overload的含义去区别。
18.Interface与abstract类的区别。
19.Static class 与non static class的区别。
20.java多态的实现原理。
21.实现多线程的两种方法:Thread与Runable。
22.线程同步的方法:sychronized、lock、reentrantLock等。
23.锁的等级:方法锁、对象锁、类锁。
24.写出生产者消费者模式。
25.ThreadLocal的设计理念与作用。
26.ThreadPool用法与优势。
27.Concurrent包里的其他东西:ArrayBlockingQueue、CountDownLatch等等。
28.wait()和sleep()的区别。
29.foreach与正常for循环效率对比。
30.Java IO与NIO。
31.反射的作用于原理。
32.泛型常用特点,List
33.解析XML的几种方式的原理与特点:DOM、SAX、PULL。
34.Java与C++对比。
35.Java1.7与1.8新特性。
36.设计模式:单例、工厂、适配器、责任链、观察者等等。
37.JNI的使用。
Java里有很多很杂的东西,有时候需要你阅读源码,大多数可能书里面讲的不是太清楚,需要你在网上寻找答案。
推荐书籍:《java核心技术卷I》《Thinking in java》《java并发编程》《effictive java》《大话设计模式》
JVM
1.内存模型以及分区,需要详细到每个区放什么。
2.堆里面的分区:Eden,survival from to,老年代,各自的特点。
3.对象创建方法,对象的内存分配,对象的访问定位。
4.GC的两种判定方法:引用计数与引用链。
5.GC的三种收集方法:标记清除、标记整理、复制算法的原理与特点,分别用在什么地方,如果让你优化收集方法,有什么思路?
6.GC收集器有哪些?CMS收集器与G1收集器的特点。
7.Minor GC与Full GC分别在什么时候发生?
8.几种常用的内存调试工具:jmap、jstack、jconsole。
9.类加载的五个过程:加载、验证、准备、解析、初始化。
10.双亲委派模型:Bootstrap ClassLoader、Extension ClassLoader、ApplicationClassLoader。
11.分派:静态分派与动态分派。
JVM过去过来就问了这么些问题,没怎么变,内存模型和GC算法这块问得比较多,可以在网上多找几篇博客来看看。
推荐书籍:《深入理解java虚拟机》
操作系统
1.进程和线程的区别。
2.死锁的必要条件,怎么处理死锁。
3.Window内存管理方式:段存储,页存储,段页存储。
4.进程的几种状态。
5.IPC几种通信方式。
6.什么是虚拟内存。
7.虚拟地址、逻辑地址、线性地址、物理地址的区别。
因为是做android的这一块问得比较少一点,还有可能上我简历上没有写操作系统的原因。
推荐书籍:《深入理解现代操作系统》
TCP/IP
1.OSI与TCP/IP各层的结构与功能,都有哪些协议。
2.TCP与UDP的区别。
3.TCP报文结构。
4.TCP的三次握手与四次挥手过程,各个状态名称与含义,TIMEWAIT的作用。
5.TCP拥塞控制。
6.TCP滑动窗口与回退N针协议。
7.Http的报文结构。
8.Http的状态码含义。
9.Http request的几种类型。
10.Http1.1和Http1.0的区别
11.Http怎么处理长连接。
12.Cookie与Session的作用于原理。
13.电脑上访问一个网页,整个过程是怎么样的:DNS、HTTP、TCP、OSPF、IP、ARP。
14.Ping的整个过程。ICMP报文是什么。
15.C/S模式下使用socket通信,几个关键函数。
16.IP地址分类。
17.路由器与交换机区别。
网络其实大体分为两块,一个TCP协议,一个HTTP协议,只要把这两块以及相关协议搞清楚,一般问题不大。
推荐书籍:《TCP/IP协议族》
数据结构与算法
1.链表与数组。
2.队列和栈,出栈与入栈。
3.链表的删除、插入、反向。
4.字符串操作。
5.Hash表的hash函数,冲突解决方法有哪些。
6.各种排序:冒泡、选择、插入、希尔、归并、快排、堆排、桶排、基数的原理、平均时间复杂度、最坏时间复杂度、空间复杂度、是否稳定。
7.快排的partition函数与归并的Merge函数。
8.对冒泡与快排的改进。
9.二分查找,与变种二分查找。
10.二叉树、B+树、AVL树、红黑树、哈夫曼树。
11.二叉树的前中后续遍历:递归与非递归写法,层序遍历算法。
12.图的BFS与DFS算法,最小生成树prim算法与最短路径Dijkstra算法。
13.KMP算法。
14.排列组合问题。
15.动态规划、贪心算法、分治算法。(一般不会问到)
16.大数据处理:类似10亿条数据找出最大的1000个数.........等等
算法的话其实是个重点,因为最后都是要你写代码,所以算法还是需要花不少时间准备,这里有太多算法题,写不全,我的建议是没事多在OJ上刷刷题(牛客网、leetcode等),剑指offer上的算法要能理解并自己写出来,编程之美也推荐看一看。
推荐书籍:《大话数据结构》《剑指offer》《编程之美》
Android
1.Activity与Fragment的生命周期。
2.Acitivty的四中启动模式与特点。
3.Activity缓存方法。
4.Service的生命周期,两种启动方法,有什么区别。
5.怎么保证service不被杀死。
6.广播的两种注册方法,有什么区别。
7.Intent的使用方法,可以传递哪些数据类型。
8.ContentProvider使用方法。
9.Thread、AsycTask、IntentService的使用场景与特点。
10.五种布局:FrameLayout、LinearLayout、AbsoluteLayout、RelativeLayout、TableLayout各自特点及绘制效率对比。
11.Android的数据存储形式。
12.Sqlite的基本操作。
13.Android中的MVC模式。
14.Merge、ViewStub的作用。
15.Json有什么优劣势。
16.动画有哪两类,各有什么特点?
17.Handler、Loop消息队列模型,各部分的作用。
18.怎样退出终止App。
19.Asset目录与res目录的区别。
20.Android怎么加速启动Activity。
21.Android内存优化方法:ListView优化,及时关闭资源,图片缓存等等。
22.Android中弱引用与软引用的应用场景。
23.Bitmap的四中属性,与每种属性队形的大小。
24.View与View Group分类。自定义View过程:onMeasure()、onLayout()、onDraw()。
25.Touch事件分发机制。
26.Android长连接,怎么处理心跳机制。
27.Zygote的启动过程。
28.Android IPC:Binder原理。
29.你用过什么框架,是否看过源码,是否知道底层原理。
30.Android5.0、6.0新特性。
Android的话,多是一些项目中的实践,使用多了,自然就知道了,还有就是多逛逛一些名人的博客,书上能讲到的东西不多。另外android底层的东西,有时间的话可以多了解一下,加分项。
推荐书籍:《疯狂android讲义》《深入理解android》
其他综合性的书籍也需要阅读,推荐:《程序员面试笔试宝典》《程序员面试金典》。另外“牛客网www.newcoder.com”是个好地方,里面有各种面试笔试题,也有自己在线的OJ,强烈推荐,还有左程云老师的算法视屏课(已经出书了),反正我看了之后对我帮助很大(这不是植入广告)。
三、项目
关于项目,这部分每个人的所做的项目不同,所以不能具体的讲。项目不再与好与不好,在于你会不会包装,有时候一个很low的项目也能包装成比较高大上的项目,多用一些专业名词,突出关键字,能使面试官能比较容易抓住重点。在聊项目的过程中,其实你的整个介绍应该是有一个大体的逻辑,这个时候是在考验你的表达与叙述能力,所以好好准备很重要。
面试官喜欢问的问题无非就几个点:
1.XXX(某个比较重要的点)是怎么实现的?
2.你在项目中遇到的最大的困难是什么,怎么解决的?
3.项目某个部分考虑的不够全面,如果XXXX,你怎么优化?
4.XXX(一个新功能)需要实现,你有什么思路?
其实你应该能够预料到面试官要问的地方,请提前准备好,如果被问到没有准备到的地方,也不要紧张,一定要说出自己的想法,对不对都不是关键,主要是有自己的想法,另外,你应该对你的项目整体框架和你做的部分足够熟悉。
四、其他
你应该问的问题
面试里,最后面完之后一般面试官都会问你,你有没有什么要问他的。其实这个问题是有考究的,问好了其实是有加分的,一般不要问薪资,主要应该是:关于公司的、技术和自身成长的。
以下是我常问的几个问题,如果需要可以参考:
1.贵公司一向以XXX著称,能不能说明一下公司这方面的特点?
2.贵公司XXX业务发展很好,这是公司发展的重点么?
3.对技术和业务怎么看?
4.贵公司一般的团队是多大,几个人负责一个产品或者业务?
5.贵公司的开发中是否会使用到一些最新技术?
6.对新人有没有什么培训,会不会安排导师?
7.对Full Stack怎么看?
8.你觉得我有哪些需要提高的地方?
CVTE:
一面:
1. 自我介绍
2. 项目点为什么要用view不用fragment?同样fragment可以解决缓存(用了view,并且设了map作为缓存,为了模拟activity栈重制了新的栈来实现相同的回退功能,需要处理连续点击和多次点击的问题,还需要解决连续点view,缓存增大而oom)
3. 用了什么设计模式?为什么要这么用?(举例了观察者+工厂)
4. 谈一下Collection包:hashmap底层实现,用了什么方法解决hash冲突(基于jdk版本),具体是如何实现(jdk1.5链表头插还是尾插),为什么不安全?如何变得安全(concurrent包下集合类),concurrentHashmap实现原理是?
5. Executor框架说说你的理解?
6. 结束一条Thread有什么方法?interrupt底层实现有看过吗?线程的状态是怎么样的?如果给你实现会怎么样做?
7. Io和nio有没有了解?
8. 现在需要在四大组件中传数据?如何传,方法有哪些(需要自己再具体说什么情况)?
9. 缓存算法除了lru还认识哪种?
10. Java中有内存泄露吗?是怎么样的情景?为什么不用循环计数?
11. ANR产生原因?怎么定位?
12. ContextImpl的源码使用的设计模式?为什么你认为其中有外观?
13. 评价一下我的表现?有什么技术点需要补充?
二面:
1. 上次一面的时间是什么时候了?(半个月前)
2. 做的最深的项目?解决了什么问题?
3. 情景题,在一个app中,只有在一张activity,所有功能业务逻辑在里面实现,现在报ANR,你会怎么做?(代码层面:耗时操作(UI、网络、数据库),工具层面:trace和crashHandle)
4. 不停在new一个很大数组,初始化它,然后又把reference设null,这样子手机会不会卡?(这个问题还没很深研究,当时答了内存抖动+stop the world)
5. Jvm 自动内存管理、如何实现对象的自我救赎?
6. Android系统启动流程?
7. 有没有看过业界APK反编译源码?
8. 平时看什么书?
9. 评价一下我,技术团队有用到什么开源框架?有没有自己放出开源?
三面HR:
1. 有点起了我老底的味道,我还以为是来查水表。
四面(现场,这是唯一一次有3个面试官来面,其中一个是一面的面试官):
1. 描述项目,当时是用了什么架构?还认识哪些架构?如何改造?
2. 当时为什么要用Observer?
3. obverser,uml类图+代码实现,原生jdk中观察者模式有哪些缺陷?
4. 还有用了哪些设计模式?(工厂)
5. 有见过其他的设计模式吗?(当时说了一个责任链和重说一面的contextimple)
6. 实现一个链表的插入(4分钟计时)
7. 判断链表有环
8. 单例模式DCL,violate起什么作用?为什么要sync .class而不是this?(3分钟计时)
网易杭研:
一面:
1. 自我介绍
2. Android中ClassLoader和java中有什么关系和区别?
3. 熟不熟jvm,说一下Jvm的自动内存管理?
4. 语言基础,String类可以被继承吗?为什么?
5. Final能修饰什么?(当时我说class、field、method,他说还有吗?然后又叫我不要在意,后来回想起,应该是问到我在参数里面要不要用final,接下来是因为匿名内部类)
6. Java中有内存泄露吗?(先说本质,再结合handler+匿名内部类)当时如何分析的?
7. 描述下Aidl?觉得aidl有什么缺陷(这里在这个问题上回答有欠缺)
8. 评价一下我,如果顺利进网易,需要往技术栈加什么点尽快投入业务?
二面:
1. 用过什么开源,举一个例子?(volley)
2. Activity生命周期?情景:现在在一张act1点了新的act2,周期如何?
3. Act的launchMode,有没有结合项目用过(自己的程序锁和微信的PC端登陆对比,不过我现在又发现,应该大约估计可能是动态加载的一个缺陷,如果有找到相关信息,请务必跟我说。具体问题就是,当在PC端登录时,Android终端的微信会跳出,即使wechat的task不是在fore,当按下确认,返回的是wechat,而不是自己先前的app)
4. View的绘制原理,有没有用canvas自己画过ui?
5. 以后想做Android什么方向?(中间件+SDK)
6. 怎么看待前端和后端?
7. 如果学前端会如何学?
8. 优缺点?兴趣?
9. 想不想来杭州?
10. 评价一下我?往技术栈加什么?
三面HR:常规问题(10分钟,这个男hr是最爽快的)
1. 为什么想来网易?
2. 有投其他公司吗?
3. 网易最吸引你的是什么?
4. 想来杭州吗?
5. 评价一下我?
腾讯(被挂)
一面:
1. 自我介绍
2. 项目描述
3. 如何保证资金流安全?(这里没答好,直接把我挂了,先前并没有考虑过这个问题,面了这么多次也没有被问这个点,导致雪崩)
4. Oom是如何解决?
5. 除了软引用还知道什么引用?
6. Jvm自动内存管理(什么时候触发gc)?
7. 有什么要补充:(跟他讲了动态加载还有一个底层源码)
8. 根据面试过程,有什么建议给我?(我当时就觉得很有可能就挂了,所以就问建议)
二面(一面之后当晚我查到被挂,心态没有调整好,但是2天后又把我复活了,然后又挂了):
1. 自我介绍
2. 你是怎么准备面试的?
3. 做过什么项目?项目思路是?
4. 平时有什么兴趣?
5. 自己写的工具类和uil相比,如何?
6. 后续就是讲了他自己对移动端发展的看法,受教很多。
7. 现在有个机会可以对刚毕业的自己说些话,你会跟他说什么?
腾讯SNG:
一面:
1. 自我介绍
2. 动态加载主要问题
3. 插件化
4. Assetmanager获取资源原理和资源获取原理
5. 项目Oom异常解决方案+用户体验优化方案
6. Touch传递机制+listview滑动冲突
7. Volley底层实现
8. 为什么不能用volley请求大数据
9. 后续流程如何走?
二面:
1. 自我介绍
2. android学习时间
3. 为什么不考研
4. Smali语句学习情况+反编译
5. 如何捕获插屏广告?如果广告是嵌入在应用主流程内如何处理(只讲了如何捕获launch下的activity,嵌套在主流程逻辑内的想不到,问了提示也没回答)
6. Jvm的自动内存管理
7. Jvm中软、虚引用的区别
8. Java nio的认识
9. Tcp三次握手,tcp与udp的区别
10. Volley底层实现+设计模式理解
11. Imageloader缓存策略
12. 后续流程如何走?
13. sng目前在android端遇到什么问题?(他回答是机型适配问题)
14. 对我的建议是?
HR面:
1. 之前参加校招吗?
2. 这个月又如何准备?
3. 谈谈优势?
4. 腾讯哪里吸引你?
5. 以后会在什么部门?是不是一二面面试官带我?
唯品会:
一面:
1. 项目如何解决oom?响应速度是怎么优化?电量消耗如何优化?
2. 描述一下Aidl和android ipc?(binder机制没跟他讲得很深)
3. 屏幕适配使用的方案?有没有辅助的工具帮助?(hyviewer)
4. 如何分析内存泄露?(代码+工具traceview+mat)
5. 那ANR呢?(我忘记了trace)
6. View树绘制?如何优化布局?
7. 事件传递原理?
8. uil的框架如何设计?有没有用过glide?(结合了fresco的分析)
9. Volley和okhttp底层实现(也讲了okio),为什么说okhttp高效?
10. Listview的优化(同一布局,左为bm,右为text)?
11. Apk瘦身可以关注什么点?(这里忘记了说so库,然而他也不会)
12. 评价一下我
二面:
1. 这里的项目的描述的xml,你项目不是native的?
2. 有没有接触hybrid和webapp?怎么看待?
3. 有用到什么设计模式吗?开源框架呢?
4. HotFix和Xposed的一些小应用(没有深入,只是讲了动态加载原理和需要解决的问题,也说了dynamicloadApk和multi分包还有Xposed中的hook)
5. 以后想如何发展?
6. 唯品会会如何培养新人?是不是由你带我?目前唯品会用到什么技术点跟我技术栈相关?
三面HR(50+年纪面试官,素质差,不尊重面试者,具体可以搜知乎):
1. 对公司的看法?
2. 为什么主页不设搜索栏?
百度:
一面:
1. 自我介绍
2. 讲一下动态加载技术点?
3. 对目前移动圈的看法?
4. 学android的开始时间?
5. 适配优化屏幕适配接触到什么方法?
6. Binder机制(只深入到framework)
7. View树绘制+事件分发
8. 海量字符串(他给我的样例如下:ABCDE,ACD,BCDF,EF),如何插入数据库使冗余度最低?Trie树+不知道什么遍历,第一次见,数据库存的是3个字段,字母,该字母第一次遍历的序号,该字母第二次遍历的序号。可以做到时间复杂度O(N),至今都没想出来……如果有人看过类似的题请务必告诉我。)
二面:
1. 不用除号实现除法(一开始需要考虑小数,后来面试官说降低难度先整数,然后优化大数的情况,确认了两次思路)
2. Contextimpl源码,几种context的区别
3. 如何实现通讯?Binder机制(我只将了aidl和framework层面,面试官把/dev/binder也讲了,受教,被人教做大人,后来吹比发现他是做C驱动开发)
4. 一个数组,找出只重复一次的元素,并且返回下标是最小的。时间复杂度要求O(N)+O(1)(一开始只想到了O(N)+O(N),后来问了提示,可以实现到O(N)+O(1),但是空间复杂度上去了,然后他给出最优解)。
三面:
1. 高校教育和培训班看法?
2. C++和java的区别?后来我转到面向过程和面向对象,结合uil
3. Ios有接触过吗?学习成本问题吗?
4. Android项目简单描述非技术角度?(动态加载)动态加载的优点,面向开发者和面向用户角度?其中我答到了65535方法会爆,然后他说小伙子太年轻,naive!
5. 以后有什么规划?
6. 高级工程师所需责任?
7. 了解android什么新技术?(hybrid,这里答得不好,应该往移动端统一角度来答)
8. N根绳子,质量不均匀,并且燃烧速度不均,但是每一条烧1h,现在需要测量出1H+15min。(cracking改题)
9. 优缺点
10. 兴趣
11. 最后给我看了一下他对65535方法数的研究,我也是醉了。
12. 个人点评?负责哪个部门?是不是以后你带我?
13. 百度200亿O2O你觉得前景如何?会对你带的部门产品线有什么影响?
14. 如何看待今年互联网的资本寒冬?
蘑菇街:
一面:
1. 自我介绍
2. 在项目中为什么要用动态加载?最大的问题是什么?怎么解决资源管理问题(这里我一直以为AssetManager是服务,然后又被面试官教做大人,简单来说就是装逼然后失败了)
3. Binder机制说一下(由application到framework到kernel基本讲了一下要点,但是电面实在是很影响表述没有画图,他最后也听得很蛋疼)
4. Android源码看了多少G?说一下(举了contextimpl)
5. 屏幕适配接触到什么方法?
6. java内存泄露是怎么样的?(本质+handler例子)
7. Handler机制?
8. 情景题,把handler设static,里面需要对一个view更新,会不会内存泄露?(可达性分析)
9. UI接触得多吗?有没有用过canvas画过图?
10. 事件分发?如果有一个interr,会……(这里我听不是很清楚,电话信号,然后我就把整个事件分发原理说了一下,然后他说我讲错,我也是醉)
11. 个人评价?会不会有下一面?(问这个因为觉得装逼失败,非常有可能被刷,他告诉我可能一周后,结果二面就马上国庆1号面)
二面:
1. 自我介绍
2. 学android多久?
3. 怎么学习?
4. 项目里面遇到什么难题,选一个讲一下?(动态加载,还有一面被教人教做大人的过程)
5. 平时有什么兴趣?
6. Volley底层实现?(okhttp没问)
7. 自己写的图片加载工具类谈一下?(结合uil谈了一下)
8. 有没有了解新技术?了解到哪些?讲一下?(hybrid+react+个人看法)
9. 动态加载还遇到什么困难?(结合了dexposed 和其他一些热补丁聊了一下)
10. 个人点评
11. 蘑菇街目前android团队架构
12. 目前有哪些android技术难题所遇到过?
13. 目前用了哪些开源?我还需要接触哪些?(hotpatch + xposed,个人认为主要还是受手淘影响,估计内部框架也是比较类似)
14. 怎么培训新人,以后是不是你来带我?
三面:(个人感觉是真的专业HR)
1. 自己介绍面向非技术
2. 谈一下优缺点,为什么有这个优点?如何体现?
3. 为什么想来蘑菇街?
4. 目前手头有多少offer?薪资?
5. 蘑菇街跟百度网易对比最吸引你?地点杭州有没有问题?
6. 蘑菇街offer会不会调岗?
7. 怎么带新人?mentor制?
应对策略:
非技术准备:
1、广度容易量化,深度难以量化;广度:写过爬虫之类,项目里面有用到某个技术;深度,针对面试官或者公司整体来进行评估难以量化。如“熟悉TCP/IP协议簇”、“熟悉JVM”,“熟悉”一词难以针对各公司统一衡量,有的是GC算法的原理,有的公司却需要手写GC算法的伪代码实现
2、本科生和研究生,要求一样;没有优劣势。
3、电话面试有一定的影响,一是普通话流利清晰程度,第二就是不能画图说明。
4、技术(Android研发)角度和自身经历,技术难度:明星创业公司>BAT+360>一线互联网>=一线工业公司>创业公司(没有面过华为中兴和国企)。
5、内推,不等于走后门,不会降低要求,只是公司提前抢人。(公司内高级别的员工内推就除外,学院也有这个资源)。
6、笔试分数是淘汰工具,面基础水平还有面试官的评价,才是择优,对后面的面试影响会比较大
7、分配好体力和精力,坚持锻炼
8、校园学生组织经历不重要(面向技术)
技术准备:
1、CS基础:网络,操作系统,数据库,编译原理,C/C++
2、算法和数据结构,需要刷题;
3、语言基础(擅长的语言的特性,例如java的io,并发,集合);
4、Android机制体系(其他研发类岗位我觉得也是相同);
5、竞赛准备(算法比赛里的奖牌,ACM,Topcoder ,蓝桥杯,阿里天池,编程之美,还有几个算法网站的排名,leetcode)和实习经历(一线公司实习经验)
在 Java 7 之前, switch 只能支持 byte 、 short 、 char 、 int 或者其对应的封装类以及 Enum 类型。在 Java 7 中, String 支持被加上了。
==是判断两个变量或实例是不是指向同一个内存空间 equals是判断两个变量或实例所指向的内存空间的值是不是相同
利用软引用和弱引用解决OOM问题:用一个HashMap来保存图片的路径和相应图片对象关联的软引用之间的映射关系,在内存不足时,JVM会自动回收这些缓存图片对象所占用的空间,从而有效地避免了OOM的问题 通过软可及对象重获方法实现Java对象的高速缓存:比如我们创建了一Employee的类,如果每次需要查询一个雇员的信息。哪怕是几秒中之前刚刚查询过的,都要重新构建一个实例,这是需要消耗很多时间的。我们可以通过软引用和 HashMap 的结合,先是保存引用方面:以软引用的方式对一个Employee对象的实例进行引用并保存该引用到HashMap 上,key 为此雇员的 id,value为这个对象的软引用,另一方面是取出引用,缓存中是否有该Employee实例的软引用,如果有,从软引用中取得。如果没有软引用,或者从软引用中得到的实例是null,重新构建一个实例,并保存对这个新建实例的软引用
同样用于鉴定2个对象是否相等的,java集合中有 list 和 set 两类,其中 set不允许元素重复实现,那个这个不允许重复实现的方法,如果用 equal 去比较的话,如果存在1000个元素,你 new 一个新的元素出来,需要去调用1000次 equal 去逐个和他们比较是否是同一个对象,这样会大大降低效率。hashcode实际上是返回对象的存储地址,如果这个位置上没有元素,就把元素直接存储在上面,如果这个位置上已经存在元素,这个时候才去调用equal方法与新元素进行比较,相同的话就不存了,散列到其他地址上
String 类型和 StringBuffer 类型的主要性能区别其实在于 String 是不可变的对象 StringBuffer和StringBuilder底层是 char[]数组实现的 StringBuffer是线程安全的,而StringBuilder是线程不安全的
Overload顾名思义是重新加载,它可以表现类的多态性,可以是函数里面可以有相同的函数名但是参数名、返回值、类型不能相同;或者说可以改变参数、类型、返回值但是函数名字依然不变。 Override顾名思义就是ride(重写)的意思,在子类继承父类的时候子类中可以定义某方法与其父类有相同的名称和参数,当子类在调用这一函数时自动调用子类的方法,而父类相当于被覆盖(重写)了。
一个类只能继承单个类,但是可以实现多个接口 接口强调特定功能的实现,而抽象类强调所属关系 抽象类中的所有方法并不一定要是抽象的,你可以选择在抽象类中实现一些基本的方法。而接口要求所有的方法都必须是抽象的
抽象的来讲,多态的意思就是同一消息可以根据发送对象的不同而采用多种不同的行为方式。(发送消息就是函数调用) 实现的原理是动态绑定,程序调用的方法在运行期才动态绑定,追溯源码可以发现,JVM 通过参数的自动转型来找到合适的办法。
就是释放那些不再持有引用的对象的内存
答:线程池的基本思想还是一种对象池的思想,开辟一块内存空间,里面存放了众多(未死亡)的线程,池中线程执行调度由池管理器来处理。当有线程任务时,从池中取一个,执行完成后线程对象归池,这样可以避免反复创建线程对象所带来的性能开销,节省了系统的资源。就好比原来去食堂打饭是每个人看谁抢的赢,谁先抢到谁先吃,有了线程吃之后,就是排好队形,今天我跟你关系好,你先来吃饭。比如:一个应用要和网络打交道,有很多步骤需要访问网络,为了不阻塞主线程,每个步骤都创建个线程,在线程中和网络交互,用线程池就变的简单,线程池是对线程的一种封装,让线程用起来更加简便,只需要创一个线程池,把这些步骤像任务一样放进线程池,在程序销毁时只要调用线程池的销毁函数即可。
单个线程的弊端:a. 每次new Thread新建对象性能差b. 线程缺乏统一管理,可能无限制新建线程,相互之间竞争,及可能占用过多系统资源导致死机或者OOM,c. 缺乏更多功能,如定时执行、定期执行、线程中断。
java提供的四种线程池的好处在于:a. 重用存在的线程,减少对象创建、消亡的开销,性能佳。b. 可有效控制最大并发线程数,提高系统资源的使用率,同时避免过多资源竞争,避免堵塞。c. 提供定时执行、定期执行、单线程、并发数控制等功能。
2、Java 线程池
Java通过Executors提供四种线程池,分别为:
newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
(1). newCachedThreadPool
创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。线程池为无限大,当执行第二个任务时第一个任务已经完成,会复用执行第一个任务的线程,而不用每次新建线程。
(2). newFixedThreadPool
创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
(3) newScheduledThreadPool
创建一个定长线程池,支持定时及周期性任务执行。ScheduledExecutorService比Timer更安全,功能更强大
(4)、newSingleThreadExecutor
创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行
Activity的 onSaveInstanceState() 和 onRestoreInstanceState()并不是生命周期方法,它们不同于 onCreate()、onPause()等生命周期方法,它们并不一定会被触发。当应用遇到意外情况(如:内存不足、用户直接按Home键)由系统销毁一个Activity,onSaveInstanceState() 会被调用。但是当用户主动去销毁一个Activity时,例如在应用中按返回键,onSaveInstanceState()就不会被调用。除非该activity是被用户主动销毁的,通常onSaveInstanceState()只适合用于保存一些临时性的状态,而onPause()适合用于数据的持久化保存。
系统不知道你按下HOME后要运行多少其他的程序,自然也不知道activity A是否会被销毁,因此系统都会调用onSaveInstanceState(),让用户有机会保存某些非永久性的数据。以下几种情况的分析都遵循该原则
Service还是运行在主线程当中的,所以如果需要执行一些复杂的逻辑操作,最好在服务的内部手动创建子线程进行处理,否则会出现UI线程被阻塞的问题
方法一:
方法二 通过BroadCast(广播)的形式 当我们的进度发生变化的时候我们发送一条广播,然后在Activity的注册广播接收器,接收到广播之后更新视图
IntentService是Service的子类,是一个异步的,会自动停止的服务,很好解决了传统的Service中处理完耗时操作忘记停止并销毁Service的问题
重用converView: 通过复用converview来减少不必要的view的创建,另外Infalte操作会把xml文件实例化成相应的View实例,属于IO操作,是耗时操作。
减少findViewById()操作: 将xml文件中的元素封装成viewholder静态类,通过converview的setTag和getTag方法将view与相应的holder对象绑定在一起,避免不必要的findviewbyid操作
避免在 getView 方法中做耗时的操作: 例如加载本地 Image 需要载入内存以及解析 Bitmap ,都是比较耗时的操作,如果用户快速滑动listview,会因为getview逻辑过于复杂耗时而造成滑动卡顿现象。用户滑动时候不要加载图片,待滑动完成再加载,可以使用这个第三方库glide
Item的布局层次结构尽量简单,避免布局太深或者不必要的重绘
尽量能保证 Adapter 的 hasStableIds() 返回 true 这样在 notifyDataSetChanged() 的时候,如果item内容并没有变化,ListView 将不会重新绘制这个 View,达到优化的目的
在一些场景中,ScollView内会包含多个ListView,可以把listview的高度写死固定下来。 由于ScollView在快速滑动过程中需要大量计算每一个listview的高度,阻塞了UI线程导致卡顿现象出现,如果我们每一个item的高度都是均匀的,可以通过计算把listview的高度确定下来,避免卡顿现象出现
使用 RecycleView 代替listview: 每个item内容的变动,listview都需要去调用notifyDataSetChanged来更新全部的item,太浪费性能了。RecycleView可以实现当个item的局部刷新,并且引入了增加和删除的动态效果,在性能上和定制上都有很大的改善
ListView 中元素避免半透明: 半透明绘制需要大量乘法计算,在滑动时不停重绘会造成大量的计算,在比较差的机子上会比较卡。 在设计上能不半透明就不不半透明。实在要弄就把在滑动的时候把半透明设置成不透明,滑动完再重新设置成半透明。
尽量开启硬件加速: 硬件加速提升巨大,避免使用一些不支持的函数导致含泪关闭某个地方的硬件加速。当然这一条不只是对 ListView。
JAVA中声明native 方法如private native String printJNI(String inputStr);
使用javah工具生成.h头文件这时候头文件中就会自动生成对应的函数JNIEXPORT jstring JNICALL Java_com_wenming_HelloWorld_printJNI
实现JNI原生函数源文件,新建HelloWorld.c文件,对刚才自动生成的函数进行具体的逻辑书写,例如返回一个java叫做HelloWorld的字符串等
编译生成动态链接so文件**
Java中调用Sysytem.load方法把刚才的so库加载进来,就可以调用native方法了
Java的String和C++的string是不能对等起来的,所以当我们拿到.h文件下面的jstring对象,会做一次转换我们把jstring转换为C下面的char*类型, 获取值
constchar* str;
str = env->GetStringUTFChars(prompt,false);
赋予值
char* tmpstr ="return string succeeded";
jstring rtstr = env->NewStringUTF(tmpstr);
OOM全称是Out Of Merrory,Android系统的每一个应用程序都设置一个硬性的Dalvik Heap Size最大限制阈值,如果申请的内存资源超过这个限制,系统就会抛出OOM错误
类的静态变量持有大数据对象 静态变量长期维持到大数据对象的引用,阻止垃圾回收。
非静态内部类存在静态实例 非静态内部类会维持一个到外部类实例的引用,如果非静态内部类的实例是静态的,就会间接长期维持着外部类的引用,阻止被回收掉。
资源对象未关闭 资源性对象比如(Cursor,File文件等)往往都用了一些缓冲,我们在不使用的时候,应该及时关闭它们, 以便它们的缓冲及时回收内存。它们的缓冲不仅存在于java虚拟机内,还存在于java虚拟机外。 如果我们仅仅是把它的引用设置为null,而不关闭它们,往往会造成内存泄露。 解决办法: 比如SQLiteCursor(在析构函数finalize(),如果我们没有关闭它,它自己会调close()关闭), 如果我们没有关闭它,系统在回收它时也会关闭它,但是这样的效率太低了。 因此对于资源性对象在不使用的时候,应该调用它的close()函数,将其关闭掉,然后才置为null. 在我们的程序退出时一定要确保我们的资源性对象已经关闭。 程序中经常会进行查询数据库的操作,但是经常会有使用完毕Cursor后没有关闭的情况。如果我们的查询结果集比较小, 对内存的消耗不容易被发现,只有在常时间大量操作的情况下才会复现内存问题,这样就会给以后的测试和问题排查带来困难和风险,记得try catch后,在finally方法中关闭连接
Handler内存泄漏 Handler作为内部类存在于Activity中,但是Handler生命周期与Activity生命周期往往并不是相同的,比如当Handler对象有Message在排队,则无法释放,进而导致本该释放的Acitivity也没有办法进行回收。 解决办法:
如果内部类实在需要用到外部类的对象,可在其内部声明一个弱引用引用外部类。
public class MainActivity extends Activity {
private CustomHandler mHandler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mHandler = new CustomHandler(this);
}
static class CustomHandlerextends Handler {
// 内部声明一个弱引用,引用外部类
private WeakReference activityWeakReference;
public MyHandler(MyActivity activity) {
activityWeakReference= new WeakReference(activity);
}
// ... ...
}
}
在Activity onStop或者onDestroy的时候,取消掉该Handler对象的Message和Runnable
Override
public void onDestroy() {
// If null, all callbacks and messages will be removed.
mHandler.removeCallbacksAndMessages(null);
}
一些不良代码习惯 有些代码并不造成内存泄露,但是他们的资源没有得到重用,频繁的申请内存和销毁内存,消耗CPU资源的同时,也引起内存抖动 解决方案 如果需要频繁的申请内存对象和和释放对象,可以考虑使用对象池来增加对象的复用。 例如ListView便是采用这种思想,通过复用converview来避免频繁的GC
1. 使用更加轻量的数据结构 例如,我们可以考虑使用ArrayMap/SparseArray而不是HashMap等传统数据结构。通常的HashMap的实现方式更加消耗内存,因为它需要一个额外的实例对象来记录Mapping操作。另外,SparseArray更加高效,在于他们避免了对key与value的自动装箱(autoboxing),并且避免了装箱后的解箱。
2. 避免在Android里面使用Enum Android官方培训课程提到过“Enums often require more than twice as much memory as static constants. You should strictly avoid using enums on Android.”,具体原理请参考《Android性能优化典范(三)》,所以请避免在Android里面使用到枚举。
3. 减小Bitmap对象的内存占用 Bitmap是一个极容易消耗内存的大胖子,减小创建出来的Bitmap的内存占用可谓是重中之重,,通常来说有以下2个措施:inSampleSize:缩放比例,在把图片载入内存之前,我们需要先计算出一个合适的缩放比例,避免不必要的大图载入。 decode format:解码格式,选择ARGB_6666/RBG_545/ARGB_4444/ALPHA_6,存在很大差异
4.Bitmap对象的复用 缩小Bitmap的同时,也需要提高BitMap对象的复用率,避免频繁创建BitMap对象,复用的方法有以下2个措施 LRUCache : “最近最少使用算法”在Android中有极其普遍的应用。ListView与GridView等显示大量图片的控件里,就是使用LRU的机制来缓存处理好的Bitmap,把近期最少使用的数据从缓存中移除,保留使用最频繁的数据, inBitMap高级特性:利用inBitmap的高级特性提高Android系统在Bitmap分配与释放执行效率。使用inBitmap属性可以告知Bitmap解码器去尝试使用已经存在的内存区域,新解码的Bitmap会尝试去使用之前那张Bitmap在Heap中所占据的pixel data内存区域,而不是去问内存重新申请一块区域来存放Bitmap。利用这种特性,即使是上千张的图片,也只会仅仅只需要占用屏幕所能够显示的图片数量的内存大小
4. 使用更小的图片 在涉及给到资源图片时,我们需要特别留意这张图片是否存在可以压缩的空间,是否可以使用更小的图片。尽量使用更小的图片不仅可以减少内存的使用,还能避免出现大量的InflationException。假设有一张很大的图片被XML文件直接引用,很有可能在初始化视图时会因为内存不足而发生InflationException,这个问题的根本原因其实是发生了OOM。
5.StringBuilder 在有些时候,代码中会需要使用到大量的字符串拼接的操作,这种时候有必要考虑使用StringBuilder来替代频繁的“+”。
4.避免在onDraw方法里面执行对象的创建 类似onDraw等频繁调用的方法,一定需要注意避免在这里做创建对象的操作,因为他会迅速增加内存的使用,而且很容易引起频繁的gc,甚至是内存抖动。
5. 避免对象的内存泄露 android中内存泄漏的场景以及解决办法,参考上一问
ANR全称Application Not Responding,意思就是程序未响应。如果一个应用无法响应用户的输入,系统就会弹出一个ANR对话框,用户可以自行选择继续等待亦或者是停止当前程序。一旦出现下面两种情况,则弹出ANR对话框
基本思路就是把一些耗时操作放到子线程中处理
使用AsyncTask处理耗时IO操作。
降低子线程优先级使用Thread或者HandlerThread时,调用Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND)设置优先级,否则仍然会降低程序响应,因为默认Thread的优先级和主线程相同。
使用Handler处理子线程结果,而不是使用Thread.wait()或者Thread.sleep()来阻塞主线程。
Activity的onCreate和onResume回调中尽量避免耗时的代码
BroadcastReceiver中onReceive代码也要尽量减少耗时操作建议使用IntentService处理。IntentService是一个异步的,会自动停止的服务,很好解决了传统的Service中处理完耗时操作忘记停止并销毁Service的问题
最核心的还是线程安全问题,多个子线程同时运行,会产生状态不一致的问题。所以要务必保证只能够执行一次
当一个App旋转时,整个Activity会被销毁和重建。当Activity重启时,AsyncTask中对该Activity的引用是无效的,因此onPostExecute()就不会起作用,若AsynTask正在执行,折会报 view not attached to window manager 异常
同样也是生命周期的问题,在 Activity 的onDestory()方法中调用Asyntask.cancal方法,让二者的生命周期同步
还是屏幕旋转这个例子,在重建Activity的时候,会回掉Activity.onRetainNonConfigurationInstance()重新传递一个新的对象给AsyncTask,完成引用的更新
(1) 事件从Activity.dispatchTouchEvent()开始传递,只要没有被停止或拦截,从最上层的View(ViewGroup)开始一直往下(子View)传递。子View可以通过onTouchEvent()对事件进行处理。
(2) 事件由父View(ViewGroup)传递给子View,ViewGroup可以通过onInterceptTouchEvent()对事件做拦截,停止其往下传递。
(3) 如果事件从上往下传递过程中一直没有被停止,且最底层子View没有消费事件,事件会反向往上传递,这时父View(ViewGroup)可以进行消费,如果还是没有被消费的话,最后会到Activity的onTouchEvent()函数。
(4) 如果View没有对ACTION_DOWN进行消费,之后的其他事件不会传递过来。
(5) OnTouchListener优先于onTouchEvent()对事件进行消费。
上面的消费即表示相应函数返回值为true。
追溯到View的dispatchTouchEvent源码查看,有这么一段代码
public boolean dispatchTouchEvent(MotionEvent event) {
if (!onFilterTouchEventForSecurity(event)) {
return false;
}
if (mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED &&
mOnTouchListener.onTouch(this, event)) {
return true;
}
return onTouchEvent(event);
}
当以下三个条件任意一个不成立时,
函数会执行到onTouchEvent。在这里我们可以看到,首先执行的是mOnTouchListener.onTouch的方法,然后是onTouchEvent方法
继续追溯源码,到onTouchEvent()观察,发现在处理ACTION_UP事件里有这么一段代码
if (!post(mPerformClick)) {
performClick();
}
此时可知,onClick方法也在最后得到了执行
所以三者的顺序是:
Dalvik虚拟机是Android平台的核心。它可以支持.dex格式的程序的运行,.dex格式是专为Dalvik设计的一种压缩格式,可以减少整体文件尺寸,提高I/O操作的速度,适合内存和处理器速度有限的系统。
Dalvik虚拟机主要是完成对象生命周期管理,内存回收,堆栈管理,线程管理,安全和异常管理等等重要功能。
对明确指出了目标组件名称的Intent,我们称之为“显式Intent”。 对于没有明确指出目标组件名称的Intent,则称之为“隐式 Intent”。
对于隐式意图,在定义Activity时,指定一个intent-filter,当一个隐式意图对象被一个意图过滤器进行匹配时,将有三个方面会被参考到:
逐帧动画(Drawable Animation): 加载一系列Drawable资源来创建动画,简单来说就是播放一系列的图片来实现动画效果,可以自定义每张图片的持续时间
补间动画(Tween Animation): Tween可以对View对象实现一系列简单的动画效果,比如位移,缩放,旋转,透明度等等。但是它并不会改变View属性的值,只是改变了View的绘制的位置,比如,一个按钮在动画过后,不在原来的位置,但是触发点击事件的仍然是原来的坐标。
属性动画(Property Animation): 动画的对象除了传统的View对象,还可以是Object对象,动画结束后,Object对象的属性值被实实在在的改变了
measure()方法,layout(),draw()三个方法主要存放了一些标识符,来判断每个View是否需要再重新测量,布局或者绘制,主要的绘制过程还是在onMeasure,onLayout,onDraw这个三个方法中
1.onMesarue() 为整个View树计算实际的大小,即设置实际的高(对应属性:mMeasuredHeight)和宽(对应属性: mMeasureWidth),每个View的控件的实际宽高都是由父视图和本身视图决定的。
2.onLayout() 为将整个根据子视图的大小以及布局参数将View树放到合适的位置上。
3. onDraw() 开始绘制图像,绘制的流程如下
文件存储: 通过java.io.FileInputStream和java.io.FileOutputStream这两个类来实现对文件的读写,java.io.File类则用来构造一个具体指向某个文件或者文件夹的对象。
SharedPreferences: SharedPreferences是一种轻量级的数据存储机制,他将一些简单的数据类型的数据,包括boolean类型,int类型,float类型,long类型以及String类型的数据,以键值对的形式存储在应用程序的私有Preferences目录(/data/data/<包名>/shared_prefs/)中,这种Preferences机制广泛应用于存储应用程序中的配置信息。
SQLite数据库: 当应用程序需要处理的数据量比较大时,为了更加合理地存储、管理、查询数据,我们往往使用关系数据库来存储数据。Android系统的很多用户数据,如联系人信息,通话记录,短信息等,都是存储在SQLite数据库当中的,所以利用操作SQLite数据库的API可以同样方便的访问和修改这些数据。
ContentProvider: 主要用于在不同的应用程序之间实现数据共享的功能,不同于sharepreference和文件存储中的两种全局可读写操作模式,内容提供其可以选择只对哪一部分数据进行共享,从而保证我们程序中的隐私数据不会有泄漏的风险
Service设置成START_STICKY kill 后会被重启(等待5秒左右),重传Intent,保持与重启前一样
通过 startForeground将进程设置为前台进程, 做前台服务,优先级和前台应用一个级别,除非在系统内存非常缺,否则此进程不会被 kill
双进程Service: 让2个进程互相保护**,其中一个Service被清理后,另外没被清理的进程可以立即重启进程
QQ黑科技: 在应用退到后台后,另起一个只有 1 像素的页面停留在桌面上,让自己保持前台状态,保护自己不被后台清理工具杀死
在已经root的设备下,修改相应的权限文件,将App伪装成系统级的应用 Android4.0系列的一个漏洞,已经确认可行
在NDK环境中将1中编写的C代码编译打包成可执行文件(BUILD_EXECUTABLE)。主进程启动时将守护进程放入私有目录下,赋予可执行权限,启动它即可。
联系厂商,加入白名单
Application的Context是一个全局静态变量,SDK的说明是只有当你引用这个context的生命周期超过了当前activity的生命周期,而和整个应用的生命周期挂钩时,才去使用这个application的context。
在android中context可以作很多操作,但是最主要的功能是加载和访问资源。在android中有两种context,一种是 application context,一种是activity context,通常我们在各种类和方法间传递的是activity context。
数据结构与算法部分:
操作系统部分:
Java对象的引用方法
Java GC机制
HashMap && HashTable && ConcurrentHashMap
多线程同步
Synchronized && Reentrantlock
Activity启动模式
两个应用能使用同一个任务栈么?
Binder机制
Volley源码的实现
大图加载
Http && Https
常用的加密算法,对称加密和非对称加密
Android里的序列化
Android里的内存泄漏
求100内的素数--筛素数法
Android里的设计模式
二面有些问题记不住了。。。。
两个应用间Binder通信的原理
OkHttp如何对链接进行复用
如何设计锁
内存泄漏如何发现(用什么工具)
1、一面
首先是自我介绍,然后开始问基础的,项目有问,但是不多,都是针对简历中项目描述的知识点零散的问,这次面试始终没有问到(网络协议和算法)的知识
Java相关:
(1)线程池有几种用法?newFixedThreadPool是怎么执行的?--coreSize与maxSize
(2)内存泄漏和内存溢出
Android相关:
(1)有用过什么框架,看过他们的源码没?
(2)平时有用过什么开源项目?
(3)AnsycTask的原理?(我的简历里提到过AnsycTask)
(4)在纸上写了个Activity,然后在类里面定义了一个Handler,问我这个会有警告,怎么解决?--static、软引用
(5)Service的保活
一面我感觉自己太紧张了,好多问题明明都知道,也可以答深入一点的,但是当时脑子却像卡了壳似的,回答不上来,看来找工作也要多面面,次数多了就有经验了。我感觉自己一面回答的很不好,感谢我的面试官高抬贵手给了我进二面的机会。。。
2、二面:(问的基本都是项目)
(1)首先自我介绍一下,着重介绍一下你的项目的难点以及你在项目里主要负责的部分、
(2)你的listView是怎么用的,在纸上给我画一下吧?---你简历上写的优化listView你是怎么优化的?---RecyclerView和ListView的区别?
说技术点的途中提到了LRU缓存算法,他说正好我不太懂,你给我说一下原理
(3)用过什么设计模式?在纸上写一个你最熟悉的设计模式,要求功能完备不能出错---我写的Double-Check的单例模式(注意volatile的使用及线程并发控制)
(4)除了handler,子线程与UI线程还有几种通信方式?(runOnUIThread、post)
(4)启动Service的两种方式?startService和bindService的区别?对Binder的了解(这个问题我回答的比较深入,因为我看过底层Binder驱动的源码,研一的时候也研究过,答到了transaction函数这里,可惜太久没回顾当时有点忘了,事后仔细捋了捋,觉得可以将流程给他细化一点)
(5)提到另一个项目时面试官似乎觉得不太难,我“强行”给他说了一些这个项目的难点以及我遇见的问题是怎么解决的,听完以后他似乎更满意了,看来机会还是要自己争取,哈哈
(6)最后问我有没有什么问题要问他的?
一面:
1.上来直接让写个堆排,算法还可以,无压写出
2.Handler机制,Handler除了线程通信还有什么作用,这个我说通知吧,因为Android是消息驱动的,不是特别明白面试官要问哪点,难道是延时?
3.Activity的启动模式,每种启动模式的使用场景,singletop中回调onNewIntent和finish掉之后onCreate()有什么不同?,这个4种的使用场景中,我singletop回答不是特别好,应该是那种频繁接受消息的activity需要使用,
4.设计模式,适配器模式,画出类图,这个怪我,面试官说设计模式熟悉吗,我就说23种随便问(因为我也没那个特别熟悉),结果问了个适配者模式,我画出个不是特别标准的UML类图,然后面试官问我,有几种类图结构,自然不知道
5.Fragment的生命周期,栈管理,和commit()类似的方法还有哪个,commit类似的那个之前真没注意,应该是commitAllowingStateLoss(),区别是是否能在activity保存之后调用
6.单例模式,单例和静态方法有什么不同,区别分析的不全面
7.实现一个文件夹列表,面试官要求5000个文件的时候才从ViewGroup转到ListView
一面有些糟糕,每个问题的基础全部答出了,但深入拓展回答的不是很好
二面:
1.Rxjava在使用的时候和传统代码有什么区别
2.强引用和弱引用同时引用一个对象是否会被回收
3.ART和Dalvik的区别
4.java内存分区,垃圾回收机制
5.主键和唯一的区别,回答是否能为空,是否能做外键
6.批量插入50条联系人,比较高效的方法,ContentProvider是否了解原理,这个问题没有回答出来
7.自旋锁和syn关键字的区别
8.volatile关键字的原理,我画了个工作内存和主内存的图
9.启动一个APP的流程
10.手写一个工厂模式,我就写了个最简单的
11.方法加syn和syn一个对象有什么区别
二面比一面感觉好一些,批量插入联系人和自旋锁(我忘了它就是Lock了)那2个问题没回答好,其他还可以
HR面:
1.说下你做的APP
2.工作中遇到的难点
3.工作地点要求
4.期望薪资
5.问题
1.项目
说下你觉得你做的最好的一个项目,画一下整体架构,就是哪部分代码负责哪部分功能
说下你了解的设计模式,在你的项目里用到了哪些设计模式,具体用到的地方?
2.java
java学了多久?
说下接口和抽象类的区别,在你项目中哪些地方用到了接口和抽象类?
说下泛型,用到的集合类,说的hashMap,说一下底层的实现,如果你要往hashMap插入一个数,详细说一下插入的具体流程,如果出现hash冲突,怎么解决?
java多线程用的多么?怎么加锁?怎样停止一个线程?
3.你学习的方式是什么样的?
4.Android
android学了多久?广播分为几种?实现原理,工作原理,广播接收器有几种?
ipc的方式
AIDL怎么用?
一面: 1.项目介绍
2.MVP的介绍
3.设计一个游戏物品栏
4.算法题目:一个数字字符串,长度为m,在其中添加n个加号,使其和最小,想了3分钟,说了下思路,其实就是dp,时间复杂度O(m*n),空间复杂度O(m),应该没问题
5.说了下Android事件的分发机制
1.聊我的ImageLoader项目 问我如何计算一个图片所占内存,我这个之前还真没注意(绝对基础) 问我如果需要网络的任务占满线程池,而网络状态不好,那么后来有缓存的任务就拿不到线程执行,应当如何优化,这个没想出来
2.问我关注的开源项目,我简单说了下rxjava 我又说了下mvp架构,然后问我Mvp架构的缺点,我说项目小的时候会导致项目冗余,然后他问10个activity每个500行会使用mvp吗,我说,如果是我的话会使用
3.让我说了下单例模式,我这边把单例的演变流程说了下,他问我你的项目中使用哪一种单例,我说我使用内部类那种
4.有什么问题,和他探讨了一些插件化的东西
一面效果不是特别理想,主要是那个计算图片内存的基础问题没回答出来 稍等了一下之后 二面面试官过来
二面 1.让我介绍项目,然后我介绍了一遍,问我项目中遇到的问题
2.让我说下ConcurrentHashMap,好像那天脑袋短路了,忘了这个分段锁了,就说没看过,让实现只说了读写分离
3.讲了一下Binder的原理,这个还是比较简单,理论上的东西
4.让我讲了下NDK/JNI,我简单说了一些应用,他说如果多线程调用JNI会出现什么问题,做过吗,我说没有,他说Ok,流程已经讲的比较清楚了,可以下去了解下多线程调用JNI这块
一面:电话面
大概25分钟,感觉面试官气场很足,主要关注了其中一个 个人开源项目
1、自我介绍
2、说说你做的这个项目
当时谈到使用到了开源框架xtuil中的dbxutil和httptuil,然后让分析这俩个模块源码;其中详细问了httputil实现原理(主要是线程池,封装的是httpclient)
使用到了slidingmenu_library开源控件,让分析这个开源框架的源码;
tips:项目中使用到的开源框架一定要了解个大概,给出一个比较不错的学习连接http://a.codekk.com/
3、说说你做过最复杂的控件
有点不好说,扯到开机动画,追问如何实现,然后又追问了animation 和animator的区别
干净利索没有太多的废话,直接就说“好,面试结束”直接就挂电话了 。同学问我面的咋样,我都直接说跪了没戏
二面:杭州网易现场面 (当然报销来回动车路费)
面了将近1小时15分钟吧
过了一个星期接到hr电话说一面过了,需要现场面,去杭州面试确实艰苦,14个小时动车到杭州已经是半夜11点了,找个小旅馆睡下,下午俩点去面试
面试官不关注我app项目,直接抛出大问题,慢慢讨论
1、说说推送
扯到长连接,心跳包,直接被面试官打断,这个我们都知道,说说保持一个长连接很简单,为什么长连接会带来很多麻烦,还提示从耗电量,微信分析
(这个问题后来做了总结,确实是个好问题可以参考我的这篇博客http://blog.csdn.net/xsf50717/article/details/48519135)
2、从协议栈角度分析一下推送的过程
看了我LTE协议栈项目(本人通信专业)问的,感觉有点不搭边
3、项目使用开源框架的源码分析讨论
主要还是集中在httputil源码实现、讨论了线程池设计,阻塞队列;
由于httputil封装了httpclient,然后让比较 httpclient和httpurlclient区别;
扯到了http协议,问了http与https区别,(当时我在分析直接被打断,“这个我们都知道,简介概括”,然后我我直接说https=http+ssl+加密算法);
加密算法是对称还是非对称的,,商量秘钥的过程是对称还是非对称
3、android消息处理机制
handler+loop分析;
loop线程与普通线程区别;
asynctask源码分析(这里有个线程池几个关键参数5,128,使用的阻塞队列,补充讲了asynctask缺陷)
如何改进asynctask造成的内存泄露的问题,从而延伸到 jvm虚拟机四种引用
4、说说androi 使用卡顿是什么造成的,给出优化
主要回答了ui overdraw避免,
面试官追问:再从底层分析;(其实就是 16ms和60fps的追求了)
再结合GPU操作分析一下UI过程;
然后说到了大图加载问题,提到UIL框架,让分析内部源码(我主要从uil的缓存策略和线程池机制分析)
5、忽然扯到并发,让分析concurrenthashmap,答了分段锁仍不满意,要求再分析一下size操作是如何做的
6、材料设计
从listview优化谈到recyclerview,深入分析一下recyclerview特点
然后引申到瀑布流如何实现,不使用recyclerview如何实现瀑布流
7、属性动画
8、touch事件分发机制
9、android开机过程(主要讨论了zygote)
10、让你设计一个游戏人物,如何设计
主要讲了抽象类+接口+mvc和mvp模式
1.为什么用Git做代码托管,rebase用过没(rebase没用过),fetch命令和pull啥区别?这个竟然不知道(真后悔吧这个卸载简历上)
2.C++中的虚函数是怎么实现的?我讲了一下Java的虚函数,invkevirtual查找过程以及虚函数表优化
3.什么是多态?easy
4.Java反射怎么使用?讲到类加载的Class怎么调用类的所有属性和方法,Android里面通过反射调用私有api。
5.Android中的几种Context什么区别?这个问题我回答的不好,简单说了一下生命周期和Context的继承关系,以及注意事项弹对话框不能使用applicatuion的上下文
6.Android中的内存泄露遇到过没?我讲了Handler持有Activity泄露以及google建议的嵌套类、弱引用的解决方案、Drawable的setCallback,耗时的线程可能会持有Activity,Bitmap调用recycle,因为以前bitmap在native分配,所以要调用recycle释放,现在不用了因为在堆分配,由GC回收,他问我是几点几版本开始的,我说是3.0版本。
7.接着问我bitmap能否复用?这个我没弄懂意思,就回答不知道,最后查了一下,也是3.0以后的有个Option的inbitmap字段可以复用http://yhz61010.iteye.com/blog/1850232
8.平时遇到过OOM没?遇到过,主要是图片加载很常见,我讲了BitmapFactory的解析Options的in...bound参数先读取图片信息进行必要的缩放,还有缓存,讲了DiskLruCache、LruCache缓存策略,以及可以加入软引用,讲了底层的LinkedHashMap实现。
9.用过外观模式?(表示没听过)这是Android中的知识吗?面试官告诉我,是一种设计模式,我说,哦,没有,我知道的有单例模式、工厂模式、代理模式、观察者模式、装饰者模式、迭代器模式。然后让我讲一下代理模式,我就大概说了一下,然后说在Android中使用AIDL产生的的代码中当查不到本地的Binder时asInterface返回的就是一个代理对象,然后面试官说,那就是你使用过bindService调用过Service了?恩。
10.FrameWork层看过那些源码?Java源码呢?讲了一下看过的框架层源码和java集合,没有具体讲。
11.自定义控件做过哪些,需要注意什么?处理wrap_content的情况,ondraw不能耗时,刷新率16ms等,然后让我讲了一下圆角矩形的图片控件怎么做,降到了画笔的xferm...方法进行图面交叠。
12.平时看不看技术文章?看,自己也经常写,简历上有博客地址,问我一般写什么文章,我说Android主要是研究Framework层源码的内容。然而。。。他的那个简历上并没有。。他又重新下载了一下pdf还是没有,我解释了一下应该是牛客网自动生成的简历,不是我自己写的那个简历。
// 补充一个,还问到我Android动态加载了解不?我没用过,但之前看到过通过DexClassLoader使用接口实现的一种插件形式,具体不太了解。
一面:
二面
网易内推后笔试,过了笔试后去杭州面试 ps:报销来回车费 报销上限是600元 这个回来没记 可能不全
一面:
二面:
一面
4月13日 16:30-16:54 电面
1. 网络框架实现,volley原理
2. 线程池原理,java提供了哪些线程池
3. 一个activity只能有一个进程么【对进程的理解】
4. activity任务栈,启动模式相关,四种启动模式
5. 夜间主题的实现方式
6. 动态加载原理,classloader理解
7. listview实现item左滑需要考虑的问题
8. view的事件分发与渲染流程
9. LruCache的理解,原理,以及还有哪些方式实现缓存调度
10. GC原理,实现方式,能否手动去控制GC回收
11. OOM,内存泄漏的问题有没有遇到过,如何处理
总结:
问的挺广的,基本整个android包括view,到进程线程理解都问了一遍,不过只是到原理层,还没更深入到更底层源码,自己还是可以轻松应付过来的,面试官问的水平也挺棒的,挺好交流的。
结束的时候问了面试官对360撤出美股的看法,以及360是否会成为中国第四,哈,挺有趣的说,期待二面。
二面
4月15日 10:00 45分钟 电面
1. mvp与mvc的区别,实现,原理
2. volley原理,发送五个请求(相同以及不同)时,内部所做处理?如何根据发送请求结束后,剔除相同的等待请求?
3. 图片缓存技术的实现,如何结合volley实现,volley自带缓存管理还是需要自己去实现,缓存的底层实现
4. listview原理,adapter与view是如何绑定的,如何自己设计一个类似listview的自定义view,子item复用,管理以及getView的实现
5. android线程模型,looper,messageQueue一套机制
6. 线程实现方式,thread+asynctask+handlerThread+intentService,彼此的应用场景以及原理
7. asynctask底层实现原理,为何不能在非主线程中实例化,其实还是跟onPre and onPost在当前线程实现有关
总结:
问的其实还是比较基本的,没有特别难的问题,只要对相关的源码有一定的熟悉就能够很好回答了,看google官方的文档还是给了自己很大的帮助的,还有任玉刚的《android开发艺术探索》讲的都特别到位,啃完那本其实就能应答如流了。
2016/4/10 上午,面试时间为1小时,喜来登酒店
面试官信息:从事Android底层网络框架开发
2016/4/12 一小时 喜来登酒店
1. http请求,响应头内容,格式规范
2. tcp报头,ip报头,dns实质
3. lrucache原理实现,linkedhashmap底层,手写代码实现lrucache,对相关的bitmap进行管理
4. 线程池构造函数传参意义,手写代码实现线程池,继承方式,不能用现成的
5. 异步接口实现,实现跨线程通信,不能用handler,looper那一套机制
6. socket编程实现http请求,手写代码实现
7. volley原理实现
一面:(年轻的人问的,问的挺基础的)(3月15日)
1. Android事件分发
2. scrollview特点
3. 处理listview图片错位方式
4. hashmap底层实现原理,如何处理溢出
5. Mvp与mvc区别,实现,架构表示
6. android缓存实现
7. 二分查找算法
二面:(3月15日)
1. Java线程 run与start区别,原理实现
2. 打包混淆原理
3. volley原理,实现
4. jar封装的private方法能否在外部调用
5. 反编译方式工具及其原理
6. 网络请求方面如何处理
7. jni使用及其原理
8. 对称加密与非对称加密
9. 单例模式为什么要使用同步关键字,原理
10. 数学题:知道正n变形的半径,求周长,算法实现
11. 使用图片缓存但是服务器改了实际的图片,但url一样,如何在客户端区别
一面(4月6日)
1. 线程间通信,进程间通信,binder原理
2. sharepreference原理
3. 事件分发原理
4. 设计模式,延迟加载实现单例模式,内部类来解决,加锁也不稳
5. mvp与mvc
6. 线程池调度实现,不能用executor(当时居然以为blockingqueue存线程呢=_=)
7. 动态加载,dex分包,热修复
8. 缓存原理实现,内存如何分配
9. 如何减小apk体积
10. 性能优化从哪几方面考虑(内存,cpu,fps,ddms灵活dump)
笔试(阿里游戏)(3月16日)
1. 基础数据结构与算法知识
2. looper,handler等原理
3. activity的启动模式
4. 与运算符
5. listview与recycleView的区别与优缺点
5. 设计模式与设计原则
设计模式:—
设计原则:
1)单一功能:对象仅具有一种单一功能概念
2)开闭原则:软件提对于拓展开放,但是对于修改封闭
3)里氏替换:程序中对象可以在不改变程序正确性的前提下被它的子类所替换的
4)接口隔离:多个特定客户端需要有宽泛用途的接口
5)依赖反转:依赖于抽象而不是一个实例
6. A向B发送消息,A能实时看到B的阅读时间,问A实现方式
阿里内推一面:(3月18日1个小时)
1. volley层次结构,原理,为什么选用volley,不用其他开源框架,对开源框架的看法
2. MVC与MVP的区别,activity,fragment扮演的角色,presentor之间的通信问题。
3. 进程间的通信,binder的原理,intent与aidl的应用场景及相关比较
4. 图片如何缓存处理,如何处理oom
5. 自定义view实现,注意事项
阿里内推二面:(3月18日1个多小时)
1. 发出的请求是否可以终止请求,pc网页刷新与停止的原理,跟移动浏览器的区别
2. 加载图片请求的超时时间设置,多少秒合适,原因,大图如何加载。
3. 线程间的通信,并发问题解决方案。
4. 快速排序为什么叫做快排,其算法复杂度,及其实现原理
5. 应用签名是为了什么,签名原理是什么
6. root之后有什么重大的变化,开发者可以操作什么
7. 给出九游android客户端程序,解释下相应的布局,listView做大面积的嵌套,下拉刷新的实现
8. 渠道提示不合法的问题,为何系统能识别渠道非法
阿里巴巴一面(2016.3.17)