前言:
我去年11月份,从杭州一家医疗外包的小公司离职了。因为疫情原因,失业很难找到适合的工作,于是我开始了海投。秉着大量撒鱼总会有适合工作的心态。其中就包括了字节跳动,让我很意外的是;居然收到了大厂的offer。
本身自己从事Android开发已经3年多了技术也还行,上家公司很小也是差点没进去,因为自己面试涉及到的问题有的会做但不会叙述;不知道大家有没有这样的问题哈。后面因为复试才进了。
关于我是怎么拿到offer的?
一开始我大量海投后,我就从网上看面试题,和一些拿到offer的人了解面试经验。
可能也有运气部分,字节跳动面试安排在五天后:然后自己海投前面就占据了4个面试邀请。通过前面一系列面试,也收到2个offer,但因为薪资待遇不合适就没去。
也就是因为自己前面这几轮面试,让我的面试经验和面试的问题,丰富起来。以至于进入大厂。
面试问题总结:
面试有三轮,我这里主要讲一下技术问题的面试。
面试官第一题:
两个Activity之间跳转时必然会执行的是哪几个方法 ?
- 两个Activity之间跳转必然会执行的是下面几个方法。
- onCreate()//在Activity生命周期开始时调用。
- onRestoreInstanceState()//用来恢复UI状态。
- onRestart()//当Activity重新启动时调用。
- onStart()//当Activity对用户即将可见时调用。
- onResume()//当Activity与用户交互时,绘制界面。
- onSaveInstanceState()//即将移出栈顶保留UI状态时调用。
- onPause()//暂停当前活动Activity,提交持久数据的改变,停止动画或其他占用GPU资源的东西,由于下一个Activity在这个方法返回之前不会resume,所以这个方法的代码执行要快。
- onStop()//Activity不再可见时调用。
- onDestroy()//Activity销毁栈时被调用的最后一个方法。
面试官第二题:
什么时候使用Service?
比如播放多媒体的时候,用户启动了其他Activity,这个时候程序要在后台继续播放,比如检测SD卡上文件的变化,再或者在后台记录你的地理信息位置的改变等等。
面试官第三题:
请介绍下Android中常用的五种布局?
最常用的布局方式为Absolute Layout、Relative Layout、Linear Layout、FrameLayout、TableLayout。其中Linear Layout和Relative Layout是最常用的方式,他们可以通过在xml配置文件或者代码中进行布局。
- Frame Layout是最简单的布局方式,放置的控件都只能罗列到左上角,控件会有重叠,不能进行复杂的布局。
- Linear Layout可以通过orientation属性设置线性排列的方向是垂直还是纵向的,每行或每列只有一个元素,可以进行复杂的布局。
- Absolute Layout可以让子元素指定准确的x、y坐标值,并显示在屏幕上。Absolute Layout没有页边框,允许元素之间相互重叠。它是绝对坐标,所以在实际中不提倡使用。
- Relative Layout允许子元素制定他们相对于其他元素或父元素的位置(通过ID制定)。因此,你可以以右对齐,或上下,或置于屏幕中央的形式来排列两个元素。元素按顺序排列,因此如果第一个元素在屏幕的中央,那么相对于这个元素的其他元素将以屏幕中央的相对位置来排列。这个是相对于Absolute Layout的,采用相对坐标,所以在实际中比较常用。
- Table Layout将以子元素的位置分配到行或列。一个Table Layout由许多的Table Row组成,每个Table Row都会定义一个row。Table Layout容器不会显示row、column或者cell的边线框。每个row拥有0个或多个的cell;和html中的table差不多。在实际中也经常使用。
面试官第四题:
Android UI中View如何刷新的?
Android中对View的更新方式有很多种,使用时要区分不同的应用场合。要分清的是:多线程和双缓冲。
- 不使用多线程和双缓冲
- 这种情况最简单,一般只希望View在发生改变时对UI进行重绘。你只需要Activity中显式调用View对象中的invalidate()方法即可。系统会自动调用View的onDraw()方法。
- 使用多线程和不使用双缓冲
- 这种情况下需要开启新的线程,新开的线程就不好访问View对象了。强行访问的话会报错:android.view.ViewRoot$ CalledFromWrongThreadException: only theoriginal thread that created a view hierarchy can touch its views。
- 这时候你需要创建一个继承了android.os.handler的子类,并重写handleMessage方法。Android.os.Handle是能发送和处理消息的,你需要在Activity中发出更新UI的消息,然后再你的Handler(可以使用匿名内部类)中处理消息(因为匿名内部类可以访问父类变量,你可以直接调用View对象中的invalidate()方法。也就是说:在新线程中创建并发送一个Message,然后在主线程中捕获、处理该消息。
- 使用多线程和双缓冲
- Android的SurfaceView是View的子类,她同时也实现了双缓冲。你可以定义一个她的子类并实现Surfaceholder.Callback接口。由于SurfaceHolder.Callback接口,新线程就不要android.os.Handler帮忙了。SurfaceHolder中lockCanvas()方法可以锁定画布,绘制完新的图像后调用unlockCanvasand Post解锁。
面试官第五题:
Android中的Context, Activity,Appliction有什么区别?
相同的:Activity和Application都是Context的子类。
Context从字面上理解就是上下文的意思,在实际应用中它也确实是起到了管理上下文环境中各个参数和变量的总用,方便我们可以简单的访问到各种资源。
区别: 维护的生命周期不同。Context维护的是当前的Activity的生命周期,Application维护的是整个项目的生命周期。
使用context的时候,小心内存泄露,防止内存泄露,注意一下几个方面:
不要让生命周期长的对象引用activity context,即保证引用activity的对象要与activity本身生命周期是一样的。
对于生命周期长的对象,可以使用application,context。
避免非静态的内部类,尽量使用静态类,避免生命周期问题,注意内部类对外部对象引用导致的生命周期变化。
面试官第六题:
ListView卡顿的原因与性能优化 ?
- 重用converView:通过复用converview来减少不必要的view的创建,另外Infalte操作会把xml文件实例化成相应的View实例,属于IO操作,是耗时操作。
- 减少findViewById()操作: 将xml文件中的元素封装成viewholder静态类,通过converview的setTag和getTag方法将view与相应的holder对象绑定在一起,避免不必要的findviewbyid操作。
- 避免在 getView 方法中做耗时的操作: 例如加载本地 Image 需要载入内存以及解析 Bitmap ,都是比较耗时的操作,如果用户快速滑动listview,会因为getview逻辑过于复杂耗时而造成滑动卡顿现象。用户滑动时候不要加载图片,待滑动完成再加载,可以使用这个第三方库glideItem的布局层次结构尽量简单,避免布局太深或者不必要的重绘。
- 尽量能保证 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。
面试官第七题:
Android 的权限规则是?
- 默认 apk 生成的数据对外是不可见的
- AndroidManifest.xml 中的显式权限声明
- Android 中的 apk 必须签名
- 基于 UserID 的进程级别的安全机制
面试官第八题:
- 如果后台的Activity由于某原因被系统回收了,如何在被系统回收之前保存 当前状态?
- 重写onSaveInstanceState()方法,在此方法中保存需要保存的数据,该方法将会在 activity被回收之前调用。通过重写onRestoreInstanceState()方法可以从中提取保存好的数据
- 面试官第九题:
谈谈Android的IPC(进程间通信)机制?
- IPC 是内部进程通信的简称,是共享"命名管道"的资源。
- Android 中的 IPC 机制是为了 让 Activity 和 Service 之间可以随时的进行交互,故在 Android 中该机制,只适用于 Activity 和 Service 之间的通信,类似于远程方法调用,类似于 C/S 模式的访问。
- 通过定义 AIDL 接 口文件来定义 IPC 接口。Servier 端实现 IPC 接口,Client 端调用 IPC 接口本地代理。
面试官第十题:
这里就是问一个算法的问题;这里我也记不清楚了。就不多做解释了。
结尾:
关于我面试的问题重点就这么多?面试官的问题肯定是五花八门但是都是一个题库里。
正所谓,面试造原子弹;实战项目去搬砖!可以说是面试重中之重啊。有关更多面经、核心技术笔记;自己也是从事Android开发5年有余了;整理了一些Android开发技术核心笔记和面经题纲
我今天就分享到这,下次见!