Android面试
2019-04-28 12:45:31 1 举报
AI智能生成
android面试题
作者其他创作
大纲/内容
算法
Java基础<br>
StringBuilder StringBuffer区别
StringBuffer 字符串变量(线程安全)<br>StringBuilder 字符串变量(非线程安全)<br>三者在执行速度方面的比较:StringBuilder > StringBuffer > String
HashMap和Hashtable的区别
HashMap是Hashtable的轻量级实现(非线程安全的实现)<br>他们都完成了Map接口,主要区别在于HashMap允许空(null)键值(key)<br>由于非线程安全,效率上可能高于Hashtable。
HashMap 是线程安全的吗,<br>为什么不是线程安全的(最好画图说明多线程环境下不安全)?
List 和 Set 的区别
set 元素不重复<br>list 元素可重复
HashSet 是如何保证不重复的
加入Set的元素必须定义equals()方法以确保对象的唯一性,<br>存入HashSet的对象必须定义hashCode(),<br>通过不同的hashCode来保证不重复
HashMap 的扩容过程
final finally finalize
final用于声明属性,方法和类,分别表示属性不可交变,方法不可覆盖,类不可继承。<br>finally是异常处理语句结构的一部分,表示总是执行。<br>finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,<br>供垃圾收集时的其他资源回收,例如关闭文件等
强引用 、软引用、 弱引用、虚引用
强引用:只要引用存在,垃圾回收器永远不会回收<br>软引用:GC会在内存不足的时候清理引用的对象<br>弱引用:GC线程会直接清理弱引用对象,不管内存是否够用<br>虚引用:垃圾回收时回收,无法通过引用取到对象值,主要用于检测对象是否已经从内存中删除
Arrays.sort 实现原理和 Collection 实现原理
Collection底层也是调用了Arrays.sort,最终实现是TimSort,是归并排序还插入排序的一种<br>
LinkedHashMap的应用
cloneable接口实现原理
作用于Object的clone方法,标记该类是可以被clone的,同时子类也要覆盖clone方法,并将可见性设置为public<br>
异常分类以及处理机制
wait和sleep的区别
调用sleep方法的线程不会释放对象锁,而调用wait() 方法会释放对象锁<br>sleep用于线程中等待一定时间后继续执行<br>wait用于不同线程之间的同步操作
数组在内存中如何分配<br>
Java的垃圾回收机制,垃圾回收算法
机制:<br>引用计数法 引用数为0时清除<br>可达性分析法<br>该方法的基本思想是通过一系列的“GC Roots”对象作为起点进行搜索,<br>如果在“GC Roots”和一个对象之间没有可达路径,则称该对象是不可达的,<br>不过要注意的是被判定为不可达的对象不一定就会成为可回收对象。<br>被判定为不可达的对象要成为可回收对象必须至少经历两次标记过程,<br>如果在这两次标记过程中仍然没有逃脱成为可回收对象的可能性,则基本上就真的成为可回收对象了<br>算法:<br>标记-清除<br>这是最基础的垃圾回收算法,之所以说它是最基础的是因为它最容易实现,<br>思想也是最简单的。<br>标记-清除算法分为两个阶段:标记阶段和清除阶段。<br>标记阶段的任务是标记出所有需要被回收的对象,清除阶段就是回收被标记的对象所占用的空间。<br>标记-清除算法实现起来比较容易,但是有一个比较严重的问题就是容易产生内存碎片,<br>碎片太多可能会导致后续过程中需要为大对象分配空间时无法找到足够的空间<br>而提前触发新的一次垃圾收集动作<br><br>复制<br>为了解决Mark-Sweep算法的缺陷,Copying算法就被提了出来。<br>它将可用内存按容量划分为大小相等的两块,每次只使用其中的一块。<br>当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,<br>然后再把已使用的内存空间一次清理掉,这样一来就不容易出现内存碎片的问题<br>这种算法虽然实现简单,运行高效且不容易产生内存碎片,但是却对内存空间的使用做出了高昂的代价,因为能够使用的内存缩减到原来的一半。<br>很显然,Copying算法的效率跟存活对象的数目多少有很大的关系,<br>如果存活对象很多,那么Copying算法的效率将会大大降低<br><br>标记-整理<br>为了解决Copying算法的缺陷,充分利用内存空间,<br>提出了Mark-Compact算法。该算法标记阶段和Mark-Sweep一样,<br>但是在完成标记之后,它不是直接清理可回收对象,<br>而是将存活对象都向一端移动,然后清理掉端边界以外的内存<br><br>分代收集<br>分代收集算法是目前大部分JVM的垃圾收集器采用的算法。<br>它的核心思想是根据对象存活的生命周期将内存划分为若干个不同的区域。<br>一般情况下将堆区划分为老年代(Tenured Generation)和新生代(Young Generation),<br>老年代的特点是每次垃圾收集时只有少量对象需要被回收,<br>而新生代的特点是每次垃圾回收时都有大量的对象需要被回收,<br>那么就可以根据不同代的特点采取最适合的收集算法
数据库知识<br>
网络基础<br>
数据存储<br>
修改SharedPreferences后两种提交方式有什么区别?
commit 同步操作,会阻塞调用它的线程,并且会返回boolean值告知保存是否成功
apply 异步操作
UI
动画类型<br>
补间动画
旋转
平移
缩放
渐变
逐帧动画
顺序播放事先做好的图片,和gif类似<br>
属性动画<br>
通过改变控件的某些属性来完成动画<br>
Activity生命周期<br>
onCreate
onStart
onResume
onPause
onStop
onDestory
Fragment生命周期<br>
onAttach
onCreate
onCreateView
onViewCreated
activity.onCreate
onActivityCreated
activity.onStatrt
onStart
activity.onResume
onResume
onPause
activity.onPause
onStop
activity.onStop
onDestoryView
onDestory
onDetach
ListView和RecyclerView的区别
RecyclerView自带ViewHolder,ListView需要自己写 <br>RecyclerView可以使用LayoutManager切换不同的样式,ListView没有<br>RecyclerView可以使用ItemAnimator自定义切换动画,Listview没有<br>RecyclerView通过实现NestedScrollingChild来实现滚动嵌套<br>ListView自带OnItemClickListener ,可以方便的响应点击事件,RecyclerView没有<br>ListView有HeaderView 与 FooterView,RecyclerView没有
ListView的优化
复用convertView<br>缓存item条目的引用,减少findViewbyId—>ViewHolder<br>数据的 分页/分批 加载:对大量的数据进行分页展示,对不同的滚动状态进行分别处理,在快速滑动状态不加载数据<br>图片的缓存,需要解决图片错位问题—>推荐使用成熟框架Glide或Picasso<br>根据列表的滑动状态来控制任务的执行频率(在快速滑动时不要加载图片)<br>可以开启硬件加速使ListView更加流畅(android:hardwareAccelerated="true")<br>将ListView的scrollingCache和animateCache这两个属性设置为false(默认是true);<br>避免GC(可以从LOGCAT查看有无GC的LOG);<br>尽可能减少List Item的Layout层次(如可以使用RelativeLayout替换LinearLayout,<br>或使用自定的View代替组合嵌套使用的Layout)
CardView特性<br>
边框圆角<br>有阴影Shadow
Handle的工作原理和工作过程
Handler用于发送和处理消息<br>Looper用于管理MessageQueue,启动死循环不断查询MessageQueue里是否有消息,有就处理<br>MessageQueue 消息队列<br>Message 消息,每个消息都会持有handler对象放在变量target中,<br>Looper处理消息时调用Message的handler对象处理消息
ThreadLocal
ThreadLocal是线程中保存数据的泛型类,可以让每个线程可以独立访问变量<br>
Service
Service保活<br>
https://blog.csdn.net/guojin08/article/details/79623311?utm_source=blogxgwz0
api>18和小于18都有区别 setForground
内存泄露<br>
静态变量
线程持有activity对象导致activity无法释放回收<br>
匿名内部类生命周期比外部类长,导致外部类无法释放<br>
context使用不当,某些生命周期很长的变量持有activity的context,导致activity无法被释放<br>
handler使用不当,等待执行的消息太多的时候,由于消息持有handler,handler持有activity,导致activity无法被释放<br>
注册监听器泄露,没有在onDestory中释放监听器导致监听器长期持有activity,而导致activity无法被释放<br>
Curser、stream没有及时close<br>
集合对象没有及时清理<br>
adapter没有使用convertView<br>
Bitmap对象不在使用时调用recycle()释放内存
优化
渲染优化<br>
减少layout层级(include、viewstub、merge)<br>
内存优化<br>
减少内存泄露<br>
内存抖动<br>
内存抖动是因为在短时间内大量的对象呗创建又马上被释放<br>
耗电量优化<br>
减少频繁的网络操作,将网络操作合并为批量执行的操作<br>
数据库优化<br>
增加索引<br>
插入多个数据时使用事物<br>
ListView的优化
使用ViewHolder重复使用View<br>不在主线程做一些复杂逻辑操作,只做数据显示
进程优先级<br>
前台进程
即与用户正在交互的Activity或者Activity用到的Service等,如果系统内存不足时前台进程是最晚被杀死的
可见进程
可以是处于暂停状态(onPause)的Activity或者绑定在其上的Service,即被用户可见,但由于失了焦点而不能与用户交互
服务进程
其中运行着使用startService方法启动的Service,虽然不被用户可见,但是却是用户关心的,例如用户正在非音乐界面听的音乐或者正在非下载页面下载的文件等;当系统要空间运行,前两者进程才会被终止
后台进程
其中运行着执行onStop方法而停止的程序,但是却不是用户当前关心的,例如后台挂着的QQ,这时的进程系统一旦没了有内存就首先被杀死
空进程
0 条评论
下一页