2024年安卓最全Android面试题(数据存储、view篇)(3),40岁程序员面试

总结

【Android 详细知识点思维脑图(技能树)】

image

其实Android开发的知识点就那么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。

虽然 Android 没有前几年火热了,已经过去了会四大组件就能找到高薪职位的时代了。这只能说明 Android 中级以下的岗位饱和了,现在高级工程师还是比较缺少的,很多高级职位给的薪资真的特别高(钱多也不一定能找到合适的),所以努力让自己成为高级工程师才是最重要的。

这里附上上述的面试题相关的几十套字节跳动,京东,小米,腾讯、头条、阿里、美团等公司19年的面试题。把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节。

由于篇幅有限,这里以图片的形式给大家展示一小部分。

网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

2、

/**

  • 在其内部完成平滑滚动的逻辑 。在整个后续的平滑滚动过程中,computeScroll()方法是会一直被调用的,

  • 我们需要不断调用Scroller的computeScrollOffset()方法来进行判断滚动操作是否已经完成了

  • 如果还没完成的话,那就继续调用scrollTo()方法,并把Scroller的curX和curY坐标传入,然后刷新界面从而完成平滑滚动的操作。

*/

@Override

public void computeScroll() {

if (mScroller.computeScrollOffset()) {

scrollTo(mScroller.getCurrX(), mScroller.getCurrY());

invalidate();

}

}

Q:谈一谈View的事件分发机制?

https://blog.youkuaiyun.com/mountain_hua/article/details/81545490

Q:如何解决View的滑动冲突?

外部拦截:可以在父布局中将onInterceptTouchEvent的返回值设为true进行拦截

内部拦截:类似反射的方式进行拦截,稍显复杂。需要配合requestDisallowInterceptTouchEvent进行拦截

Q:谈一谈View的工作原理?

https://www.cnblogs.com/cr330326/p/6340973.html

View的工作流程

View的工作流程主要是指measure、layout、draw这三大流程,即测量、布局、绘制,其中measure确定View的测量宽/高,layout确定View的最终宽/高和四个顶点的位置,而draw则将View绘制到屏幕上。

measure过程

measure过程要分情况来看,如果是一个原始的View,那么通过measure方法就完成了其测量过程,如果是一个ViewGroup,除了完成自己的测量过程外,还会遍历去调用所有子元素的measure方法,各个子元素再递归去执行这个流程。

Layout过程

Layout的作用是ViewGroup用来确定子元素的位置,当ViewGroup的位置被确定后,它在onLayout中会遍历所有的子元素并调用其layout方法,在layout方法中onLayout方法又会被调用。

draw过程

draw过程就比较简单了,它的作用是将View绘制到屏幕上面,View的绘制过程循序以下几步:

绘制背景background.draw(canvas)

绘制自己(onDraw)

绘制children(dispatchDraw)

绘制装饰(onDrawScrollBars)

Q:MeasureSpec是什么?有什么作用?

https://www.jianshu.com/p/647913c11673

https://blog.youkuaiyun.com/xxdw1992/article/details/81128900

总结

View的measureSpec由其父容器的measureSpec及自身的LayoutParams共同决定

若子View为具体的大小(如100px),则不管其父容器的specMode为哪种,子View对应的specMode均为EXACTLY,specSize均为childSize

若子View的LayoutParams中的宽或高为wrap_content,则不管其父容器的specMode为哪种,子View对应的specMode均为AT_MOST,specSize均为parentLeftSize

子View的前期measure过程实际上在其父容器的onMeasure中就基本完成了,父容器会把计算好的measureSpec传递给子View,子View在自己的onMeasure中可以得到这些值,子View可以根据这些值设置自己的大小,当然也可以不参考它们。最终在onMeasure方法通过调用

setMeasuredDimension方法设置view的最终measureSize。但View的真实大小是在Layout阶段才确定下来的,通过child.layout(left,top,right,bottom).View的measure size与 layout size不必相等,但绝大多数情况下是相等的。

总的来说就是计算出来的父View的MeasureSpec不断往子View传递,结合子View的LayoutParams 一起再算出子View的MeasureSpec,然后继续传给子View,不断计算每个View的MeasureSpec,子View有了MeasureSpec才能更测量自己和自己的子View。

Q:自定义View/ViewGroup需要注意什么?

https://blog.youkuaiyun.com/myth13141314/article/details/81449109

自定义View的分类:

继承View重写onDraw方法

主要用于实现不规则的效果,即这种效果不方便通过布局的组合方式来实现。相当于就是得自己“画”了。采用这种方式需要自己支持wrap_content,padding也需要自己处理

继承ViewGroup派生特殊的Layout

主要用于实现自定义的布局,看起来很像几种View组合在一起的时候,可以使用这种方式。这种方式需要合适地处理ViewGroup的测量和布局,并同时处理子元素的测量和布局过程。比如自定义一个自动换行的LinerLayout等。

继承特定的View,比如TextView

这种方法主要是用于扩展某种已有的View,增加一些特定的功能。这种方法比较简单,也不需要自己支持wrap_content和padding。

继承特定的ViewGroup,比如LinearLayout

这种方式也比较常见,和上面的第2种方法比较类似,第2种方法更佳接近View的底层。

自定义View需要注意的地方:

让View支持wrap_content

直接继承View和ViewGroup的控件需要在onMeasure方法中处理wrap_content的方法。处理方法是在wrap_content的情况下设置一个固定的尺寸

让View支持padding

直接继承View的控件需要在onDraw方法中处理padding,否则用户设置padding属性就不会起作用。直接继承ViewGroup的控件需要在onMeasure和onLayout中考虑padding和子元素的margin对其造成的影响,不然将导致padding和子元素的margin失效。

尽量不要在View中使用Handler

View中已经提供了post系列方法,完全可以替代Handler的作用。

View中如果有线程或者动画,需要及时停止

在View的onDetachedFromWindow方法可以停止线程和动画,因为当View被remove或是包含此View的Activity退出时,就会调用View的onDetachedFromWindow方法。如果不处理的话很可能会导致内存泄漏

View带有滑动嵌套时,需要处理好滑动冲突问题

在View的onDraw方法中不要创建太多的临时对象,也就是new出来的对象。因为onDraw方法会被频繁调用,如果有大量的临时对象,就会引起内存抖动,影响View的效果

Q:onTouch()、onTouchEvent()和onClick()关系?

public boolean dispatchTouchEvent(MotionEvent event) {

if (mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED &&

mOnTouchListener.onTouch(this, event)) {

return true;

}

return onTouchEvent(event);

}

从源码中可以看出,这两个方法都是在View的dispatchTouchEvent中调用的,onTouch优先于onTouchEvent执行。如果在onTouch方法中通过返回true将事件消费掉,onTouchEvent将不会再执行。

另外需要注意的是,onTouch能够得到执行需要两个前提条件,第一mOnTouchListener的值不能为空,第二当前点击的控件必须是enable的。因此如果你有一个控件是非enable的,那么给它注册onTouch事件将永远得不到执行。对于这一类控件,如果我们想要监听它的touch事件,就必须通过在该控件中重写onTouchEvent方法来实现。

onTouch()中的ACTION_UP执行之后,会执行onClick()方法。onClick()方法在onTouchEvent()里面执行。

Q:SurfaceView和View的区别?

https://www.cnblogs.com/dubo-/p/6638094.html

view在UI线程去更新自己;而SurfaceView则在一个子线程中去更新自己

surfaceView是在一个新起的单独线程中可以重新绘制画面,而View必须在UI的主线程中更新画面

在UI的主线程中更新动画,时间一旦太长就会出现问题

surfaceView 在新的线程中更新画面所以不会阻塞你的UI主线程,但是涉及到线程同步,需要surfaceView中 thread处理,一般就需要有一个event queue的设计来保存touch event

Q:invalidate()和postInvalidate()的区别?

invalidate()用于在主线程中更新UI,postInvalidate()用与在子线程中更新UI,其内部也是使用了handler。

Bitmap

======

Q:加载图片的时候需要注意什么?

https://blog.youkuaiyun.com/caoxiao90/article/details/51545560

https://blog.youkuaiyun.com/mountain_hua/article/details/82696065

尽量不要使用setImageBitmap或setImageResource或BitmapFactory.decodeResource来设置一张大图,

因为这些函数在完成decode后,最终都是通过java层的createBitmap来完成的,需要消耗更多内存。

因此,改用先通过BitmapFactory.decodeStream方法,创建出一个bitmap,再将其设为ImageView的 source,

decodeStream最大的秘密在于其直接调用JNI>>nativeDecodeAsset()来完成decode,

无需再使用java层的createBitmap,从而节省了java层的空间。

Q:LRU算法的原理?

LRU全称是Least Recently Used,即最近最久未使用的意思。

LRU算法的设计原则是:如果一个数据在最近一段时间没有被访问到,那么在将来它被访问的可能性也很小。也就是说,当限定的空间已存满数据时,应当把最久没有被访问到的数据淘汰。也是利用了程序的局部性原理。

Q:Android中缓存更新策略?

https://blog.youkuaiyun.com/u014732103/article/details/78592476

目前常用的一种缓存算法是Least Recently Used,简称:LRU,LRU是近期最少使用算法,它的核心机制是当缓存控件满时,会优先淘汰那些近期最少使用的缓存对象。采用LRU算法的缓存有:LruCache以及DiskLruCache,LruCache用于实现内存缓存,DiskLruCache用于实现存储设备缓存,因此通过这二者的结合使用,就可以很方便地实现一个高效的ImageLoader。

Animation

=========

Q:Android中有哪几种类型的动画?

View动画,帧动画,属性动画。

Q:帧动画在使用时需要注意什么?

帧动画使用比较简单,但比较容易引起OOM,因此在使用帧动画时要尽量避免使用过多尺寸过大的图片。

Q:View动画和属性动画的区别?

View动画不能真正改变View的位置,而属性动画可以

结尾

好了,今天的分享就到这里,如果你对在面试中遇到的问题,或者刚毕业及工作几年迷茫不知道该如何准备面试并突破现状提升自己,对于自己的未来还不够了解不知道给如何规划,可以来看看同行们都是如何突破现状,怎么学习的,来吸收他们的面试以及工作经验完善自己的之后的面试计划及职业规划。

这里放上一部分我工作以来以及参与过的大大小小的面试收集总结出来的一套进阶学习的视频及面试专题资料包,主要还是希望大家在如今大环境不好的情况下面试能够顺利一点,希望可以帮助到大家~

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

集总结出来的一套进阶学习的视频及面试专题资料包,主要还是希望大家在如今大环境不好的情况下面试能够顺利一点,希望可以帮助到大家~

[外链图片转存中…(img-eNnjWqVg-1715745078493)]

[外链图片转存中…(img-lFcL2o7r-1715745078493)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值