对过去的两三年作个总结,或许能帮助到些人,或者从中能得一些建议。此次出去面试主要是两个星期的时间,第一个星期主要是投简历,第二个星期主要是面试,一天安排了2-3个面试。
下面是我总结的一些准备面试的Tips以及面试必备的注意事项java
1.准备一份本身的自我介绍,面试的时候根据面试对象适当进行修改(突出重点,突出本身的优点在哪里,切忌流水帐);android
2.注意随身带上本身的成绩单和简历复印件; (有的公司在面试前都会让你交一份成绩单和简历当作面试中的参考。)git
3.若是须要笔试就提早刷一些笔试题,大部分在线笔试的类型是选择题+编程题,有的还会有简答题。(平时空闲时间多的能够刷一下笔试题目(牛客网上有不少),可是不要只刷面试题,不动手code,程序员不是为了考试而存在的。)另外,注意抓重点,由于题目太多了,可是有不少题目几乎次次遇到,像这样的题目必定要搞定。程序员
4.提早准备技术面试。 搞清楚本身面试中可能涉及哪些知识点、那些知识点是重点。面试中哪些问题会被常常问到、本身改如何回答。(强烈不推荐背题)
第一: 经过背这种方式你能记住多少?能记住多久?
第二: 背题的方式的学习很难坚持下去!github
5.面试以前作好定向复习。 也就是专门针对你要面试的公司来复习。好比你在面试以前能够在网上找找有没有你要面试的公司的面经。面试
6.准备好本身的项目介绍。 若是有项目的话,技术面试第一步,面试官通常都是让你本身介绍一下你的项目。你能够从下面几个方向来考虑:算法
①对项目总体设计的一个感觉(面试官可能会让你画系统的架构图;
②在这个项目中你负责了什么、作了什么、担任了什么角色;
③ 从这个项目中你学会了那些东西,使用到了那些技术,学会了那些新技术的使用;
④项目描述中,最好能够体现本身的综合素质,好比你是如何协调项目组成员协同开发的或者在遇到某一个棘手的问题的时候你是如何解决的又或者说你在这个项目用了什么技术实现了什么功能好比:Android Bitmap压缩策略;关于HandlerThread的使用场景以及怎样使用 HandlerThread?
提早知道有哪些技术问题常问: HashMap源码分析、热修复,handler等等问题我以为面试中实在太常见了,好好准备!后面的文章会我会分类详细介绍到那些问题最常问。编程
提早熟悉一些常问的非技术问题: 面试的时候有一些常见的非技术问题好比“面试官问你的优势是什么,应该如何回答?”、“面试官问你的缺点是什么,应该如何回答?”、“若是面试官问"你有什么问题问我吗?"时,你该如何回答”等等,对于这些问题,如何回答本身内心要有个数,别面试的时候出了乱子。设计模式
6.面试以后记得复盘。 面试遭遇失败是很正常的事情,因此善于总结本身的失败缘由才是最重要的。若是失败,不要灰心;若是经过,切勿狂喜。缓存
以上的面试题,主要是Android应用层知识,须要面试以前造造火箭的,还须要平时的耕耘、积累和总结。
Java中引用类型分为四类: 强引用、软引用、弱引用、虚引用。
强引用: 强引用指的是经过new对象建立的引用,垃圾回收器即便是内存不足也不会回收强引用指向的对象。
软引用: 软引用是经过SoftRefrence实现的,它的生命周期比强引用短,在内存不足,抛出OOM以前,垃圾回收器会回收软引用引用的对象。软引用常见的使用场景是存储一些内存敏感的缓存,当内存不足时会被回收。
弱引用: 弱引用是经过WeakRefrence实现的,它的生命周期比软引用还短,GC只要扫描到弱引用的对象就会回收。弱引用常见的使用场景也是存储一些内存敏感的缓存。
虚引用: 虚引用是经过FanttomRefrence实现的,它的生命周期最短,随时可能被回收。若是一个对象只被虚引用引用,咱们没法经过虚引用来访问这个对象的任何属性和方法。它的做用仅仅是保证对象在finalize后,作某些事情。虚引用常见的使用场景是跟踪对象被垃圾回收的活动,当一个虚引用关联的对象被垃圾回收器回收以前会收到一条系统通知。
通常提到volatile,就不得不提到内存模型相关的概念。咱们都知道,在程序运行中,每条指令都是由CPU执行的,而指令的执行过程当中,势必涉及到数据的读取和写入。程序运行中的数据都存放在主存中,这样会有一个问题,因为CPU的执行速度是要远高于主存的读写速度,因此直接从主存中读写数据会下降CPU的效率。为了解决这个问题,就有了高速缓存的概念,在每一个CPU中都有高速缓存,它会事先从主存中读取数据,在CPU运算以后在合适的时候刷新到主存中。
这样的运行模式在单线程中是没有任何问题的,但在多线程中,会致使缓存一致性的问题。举个简单的例子:i=i+1 ,在两个线程中执行这句代码,假设i的初始值为0。咱们指望两个线程运行后获得2,那么有这样的一种状况,两个线程都从主存中读取i到各自的高速缓存中,这时候两个线程中的i都为0。在线程1执行完毕获得i=1,将之刷新到主存后,线程2开始执行,因为线程2中的i是高速缓存中的0,因此在执行完线程2以后刷新到主存的i仍旧是1。
因此这就致使了对共享变量的缓存一致性的问题,那么为了解决这个问题,提出了缓存一致性协议:当CPU在写数据时,若是发现操做的是共享变量,它会通知其余CPU将它们内部的这个共享变量置为无效状态,当其余CPU读取缓存中的共享变量时,发现这个变量是无效的,它会重新从主存中读取最新的值。
在Java的多线程开发中,有三个重要概念:原子性、可见性、有序性。
原子性: 一个或多个操做要么都不执行,要么都执行。
可见性: 一个线程中对共享变量(类中的成员变量或静态变量)的修改,在其余线程当即可见。
有序性: 程序执行的顺序按照代码的顺序执行。
把一个变量声明为volatile,其实就是保证了可见性和有序性。
可见性我上面已经说过了,在多线程开发中是颇有必要的。这个有序性仍是得说一下,为了执行的效率,有时候会发生指令重排,这在单线程中指令重排以后的输出与咱们的代码逻辑输出仍是一致的。但在多线程中就可能发生问题,volatile在必定程度上能够避免指令重排。
volatile的原理是在生成的汇编代码中多了一个lock前缀指令,这个前缀指令至关于一个内存屏障,这个内存屏障有3个做用:
AIDL 、广播、文件、socket、管道
Android中经常使用的性能优化工具包括这些:Android Studio自带的Android Profiler、LeakCanary、BlockCanary
Android自带的Android Profiler其实就很好用,Android Profiler能够检测三个方面的性能问题:CPU、MEMORY、NETWORK。
LeakCanary是一个第三方的检测内存泄漏的库,咱们的项目集成以后LeakCanary会自动检测应用运行期间的内存泄漏,并将之输出给咱们。
BlockCanary也是一个第三方检测UI卡顿的库,项目集成后Block也会自动检测应用运行期间的UI卡顿,并将之输出给咱们。
PathClassLoader,只能加载系统中已经安装过的apk
DexClassLoader,能够加载jar/apk/dex,能够从SD卡中加载未安装的apk
Android中动画大体分为3类: 帧动画、补间动画(View Animation)、属性动画(Object Animation)。
帧动画: 经过xml配置一组图片,动态播放。不多会使用。
补间动画(View Animation): 大体分为旋转、透明、缩放、位移四类操做。不多会使用。
属性动画(Object Animation
): 属性动画是如今使用的最多的一种动画,它比补间动画更增强大。属性动画大体分为两种使用类型,分别是ViewPropertyAnimator
和ObjectAnimator
。前者适合一些通用的动画,好比旋转、位移、缩放和透明,使用方式也很简单经过View.animate()
便可获得ViewPropertyAnimator
,以后进行相应的动画操做便可。后者适合用于为咱们的自定义控件添加动画,固然首先咱们应该在自定义View中添加相应的getXXX()
和setXXX()
相应属性的getter
和setter
方法,这里须要注意的是在setter方法内改变了自定义View中的属性后要调用invalidate()
来刷新View的绘制。以后调用ObjectAnimator.of
属性类型()返回一个ObjectAnimator
,调用start()
方法启动动画便可。
补间动画与属性动画的区别:
说到Handler,就不得不提与之密切相关的这几个类:Message
、MessageQueue
,Looper
。
target
和callback
。target其实就是发送消息的Handler对象,callback是当调用handler.post(runnable)
时传入的Runnable
类型的任务。post事件的本质也是建立了一个Message
,将咱们传入的这个runnable赋值给建立的Message
的callback
这个成员变量。MessageQueue
中的next()
方法,它会返回下一个待处理的消息。Looper.prepare()
建立Looper,以后还得调用Looper.loop()
开启轮询。咱们着重看一下这两个方法。prepare()
。这个方法作了两件事:首先经过ThreadLocal.get()
获取当前线程中的Looper,若是不为空,则会抛出一个RunTimeException,意思是一个线程不能建立2个Looper。若是为null则执行下一步。第二步是建立了一个Looper,并经过ThreadLocal.set(looper)
。将咱们建立的Looper与当前线程绑定。这里须要提一下的是消息队列的建立其实就发生在Looper的构造方法中。
loop()
。这个方法开启了整个事件机制的轮询。它的本质是开启了一个死循环,不断的经过MessageQueue
的next()
方法获取消息。拿到消息后会调用msg.target.dispatchMessage()
来作处理。其实咱们在说到Message的时候提到过,msg.target其实就是发送这个消息的handler。这句代码的本质就是调用handler的dispatchMessage()
。Handler。上面作了这么多铺垫,终于到了最重要的部分。Handler的分析着重在两个部分:发送消息和处理消息
发送消息。其实发送消息除了sendMessage
以外还有sendMessageDelayed
和post以及postDelayed等等不一样的方式。但它们的本质都是调用了sendMessageAtTime
。在sendMessageAtTime
这个方法中调用了enqueueMessage
。在enqueueMessage
这个方法中作了两件事:经过msg.target = this
实现了消息与当前handler的绑定。而后经过queue.enqueueMessage
实现了消息入队。
处理消息。消息处理的核心其实就是dispatchMessage()
这个方法。这个方法里面的逻辑很简单,先判断msg.callback
是否为null,若是不为空则执行这个runnable
。若是为空则会执行咱们的handleMessage
方法。
Android中的性能优化在我看来分为如下几个方面:内存优化、布局优化、网络优化、安装包优化。
内存优化: 下一个问题就是。
布局优化: 布局优化的本质就是减小View的层级。常见的布局优化方案以下
网络优化: 常见的网络优化方案以下
安装包优化: 安装包优化的核心就是减小apk的体积,常见的方案以下
Android的内存优化在我看来分为两点: 避免内存泄漏、扩大内存,其实就是开源节流。
其实内存泄漏的本质就是较长生命周期的对象引用了较短生命周期的对象。
常见的内存泄漏:
扩大内存,为何要扩大咱们的内存呢?有时候咱们实际开发中不可避免的要使用不少第三方商业的SDK,这些SDK其实有好有坏,大厂的SDK可能内存泄漏会少一些,但一些小厂的SDK质量也就不太靠谱一些。那应对这种咱们没法改变的状况,最好的办法就是扩大内存。
扩大内存一般有两种方法:一个是在清单文件中的Application下添加largeHeap=”true”这个属性,另外一个就是同一个应用开启多个进程来扩大一个应用的总内存空间。第二种方法其实就很常见了,比方说我使用过个推的SDK,个推的Service其实就是处在另一个单独的进程中。
Android中的内存优化总的来讲就是开源和节流,开源就是扩大内存,节流就是避免内存泄漏。
在Linux中,为了不一个进程对其余进程的干扰,进程之间是相互独立的。在一个进程中其实还分为用户空间和内核空间。这里的隔离分为两个部分,进程间的隔离和进程内的隔离。
既然进程间存在隔离,那其实也是存在着交互。进程间通讯就是IPC,用户空间和内核空间的通讯就是系统调用。
Linux为了保证独立性和安全性,进程之间不能直接相互访问,Android是基于Linux的,因此也是须要解决进程间通讯的问题。
其实Linux进程间通讯有不少方式,好比管道、socket等等。为何Android进程间通讯采用了Binder而不是Linux已有的方式,主要是有这么两点考虑:性能和安全
性能。在移动设备上对性能要求是比较严苛的。Linux传统的进程间通讯好比管道、socket等等进程间通讯是须要复制两次数据,而Binder则只须要一次。因此Binder在性能上是优于传统进程通讯的。
安全。传统的Linux进程通讯是不包含通讯双方的身份验证的,这样会致使一些安全性问题。而Binder机制自带身份验证,从而有效的提升了安全性。
Binder是基于CS架构的,有四个主要组成部分。
Binder机制主要的流程是这样的:
整体发现整个面试下来,投简历发现今年996的公司还蛮多的,前两年没有这么多。有的人事,boss会直接说是996,要么本身面试过程当中问是否是996,996的公司是拒绝的,压根不想去。面试的过程当中发现本身的信心不够,技术能力也不够、本身也着急。面试想一想这几点要特别注意。
写代码总结如下几点:
1.须要确认需求的,理解有误差的。写代码以前必定要和产品经理沟通交流。宁愿多花时间去和测试的、设计师沟通,也不要去埋头写代码。一样的,认真想一想怎么实现这样一个功能,思路理清了在敲代码。
2.养成良好的编码习惯,风格。多看看Google开源的在github上示例,或者其它知名公司的。
3.六大设计原则、一些经常使用的设计模式理解透牢记于心,多在编码过程当中使用。
4.代码要有思路,写好注释,写的代码不仅仅是本身要看,也是给别人看的。
5.平时学习须要多总结、多体会、代码须要多动手敲。
更多面试内容分析,分享,学习笔记整理,视频整理。核心笔记PDF
https://github.com/xiangjiana...
(点个star。专一分享技术干货/编程资源/求职面试/成长感悟等,关注送983页PDF面试资源,免费下载CSDN资源。领取PDF面试大全,附送CSDN下载资源)
![]()