面试大厂,那就是考察你技术方向的一些专业技能,如果你面试 Android 岗位,那 Android 方向的专业技能就是考察很重要的一个方向。
但是话说回来,即便这条是所有人都知道的共识,也不是所有人都能搞得定。有些人就是觉得自己基础不好,然后就知难而退,要么就是没有决心啃下这块硬骨头,这时候就体现出每个人面对困难的方式了。
再退一步讲,即便你不想加入大厂,在 IT 领域,如果你想吃技术这碗饭,长久来看,专业技能也会制约一个人的上限,等到工作时间越长,年龄越来越大,专业技能的熟练程度就会让你和别的程序员之间差距越来越明显。
而面试是测试一个人能力最直接的方式,我这两个月前前后后面了 10 家公司,下面就放上我遇到的所有面试题以及我的建议,并且提供一些简历的写作和面试技巧给各位即将面试的同志们。
基本信息
- 简历不要太花哨, 你是应聘的技术, 不是设计师 简历把一些基本信息要说清楚(无关的不要写, 比如头像之类的)有个人博客, 跟 GitHub 地写上, 若没有内容那就算了 应届毕业生需写上相关证书之类的, 有经验的可不写 简历控制在两页 A4 纸
项目经验
- 一般写 2, 3 个代表性的项目就好,优先写本职工作相关的 时间为倒序 说明你在项目当中的职责作用 项目模块需要了解大概逻辑与思路,以及一些关键的技术点,以防面试官问到 没有项目经验的也要模仿一两个小 Demo
- 自己亲自做的东西一定要明白, 如果不是自己亲自做的, 请慎重骗面试官 问的时候会问一些知识点相关的话题,比如你的数据是需要 api 交互的,那可能会问 http 相关,json 数据解析相关,缓存相关,图片加载相关等 对用到的知识点虽用不着一定要看源码的地步,但是最好要懂原理,比如图片加载一定要知道二级缓存,一些常见的缓存算法
不同的城市肯定工资水平不一样的,这里仅以一线城市为例,而且不同的公司、个人能力的高低都会造成工资差异化,这里只是一个大概。
这个是我在 BOSS 招聘截取的图片大家可以进行参考。
注意事项
- 去面试前一定要花点时间了解下你面试的这家公司 (本身有自己产品的下载体验一下,以防面试过程中问到,或者可以给产品提点意见) 面试的时候态度要谦虚点 学习能力很重要 (一定要让面试官感受到你是一个好学的人) 个人兴趣 (不要提什么打游戏, 唱歌之类的, 可以说一下业余时间提下自己经常上一些技术社区, 看一些技术博客之类的) 除了基本的知识点, 面试官通常都会问一些比较深的领域 (可能你没有接触过, 但不要气馁, 面试官在考察下你的技术的深度, 这些领域一般包括设计模式, 虚拟机, 插件化, React Native 之类的)
一、启动优化有哪些容易忽略的注意点?
- cpu time 与 wall time 注意延迟初始化的优化 介绍下黑科技
首先,在 CPU Profiler 和 Systrace 中有两个很重要的指标,即 cpu time 与 wall time,我们必须清楚 cpu time 与 wall time 之间的区别,wall time 指的是代码执行的时间,而 cpu time 指的是代码消耗 CPU 的时间,锁冲突会造成两者时间差距过大。我们需要以 cpu time 来作为我们优化的一个方向。
其次,我们不仅只追求启动速度上的一个提升,也需要注意延迟初始化的一个优化,对于延迟初始化,通常的做法是在界面显示之后才去进行加载,但是如果此时界面需要进行滑动等与用户交互的一系列操作,就会有很严重的卡顿现象,因此我们使用了 idealHandler 来实现 cpu 空闲时间来执行耗时任务,这极大地提升了用户的体验,避免了因启动耗时任务而导致的页面卡顿现象。
最后,对于启动优化,还有一些黑科技,首先,就是我们采用了类预先加载的方式,我们在 MultiDex.install 方法之后起了一个线程,然后用 Class.forName 的方式来预先触发类的加载,然后当我们这个类真正被使用的时候,就不用再进行类加载的过程了。同时,我们再看 Systrace 图的时候,有一部分手机其实并没有给我们应用去跑满 cpu,比如说它有 8 核,但是却只给了我们 4 核等这些情况,然后,有些应用对此做了一些黑科技,它会将 cpu 的核心数以及 cpu 的频率在启动的时候去进行一个暴力的提升。
二、如何检测所有不合理的地方?
比如说大图片的检测,我们最初的一个方案是通过继承 ImageView,重写它的 onDraw 方法来实现。但是,我们在推广它的过程中,发现很多开发人员并不接受,因为很多 ImageView 之前已经写过了,你现在让他去替换,工作成本是比较高的。所以说,后来我们就想,有没有一种方案可以免替换,最终我们就找到了 ARTHook 这样一个 Hook 的方案。
三、做完布局优化有哪些成果产出?
- 1、首先,我们建立了一个体系化的监控手段,这里的体系还指的是线上加线下的一个综合方案,针对线下,我们使用 AOP 或者 ARTHook,可以很方便地获取到每一个布局的加载耗时以及每一个控件的加载耗时。针对线上,我们通过 Choreographer.getInstance().postFrameCallback 的方式收集到了 FPS,这样我们可以知道用户在哪些界面出现了丢帧的情况。2、然后,对于布局监控方面,我们设立了 FPS、布局加载时间、布局层级等一系列指标。3、最后,在每一个版本上线之前,我们都会对我们的核心路径进行一次 Review,确保我们的 FPS、布局加载时间、布局层级等达到一个合理的状态。
四、你们做了哪些稳定性方面的优化?
随着项目的逐渐成熟,用户基数逐渐增多,DAU 持续升高,我们遇到了很多稳定性方面的问题,对于我们技术同学遇到了很多的挑战,用户经常使用我们的 App 卡顿或者是功能不可用,因此我们就针对稳定性开启了专项的优化,我们主要优化了三项:
- Crash 专项优化(=>2) 性能稳定性优化(=>2) 业务稳定性优化(=>3)
通过这三方面的优化我们搭建了移动端的高可用平台。同时,也做了很多的措施来让 App 真正地实现了高可用。
五、如果发生了异常情况,怎么快速止损?
- 功能开关 统跳中心 动态修复:热修复、资源包更新 自主修复:安全模式
首先,需要让 App 具备一些高级的能力,我们对于任何要上线的新功能,要加上一个功能的开关,通过配置中心下发的开关呢,来决定是否要显示新功能的入口。如果有异常情况,可以紧急关闭新功能的入口,那就可以让这个 App 处于可控的状态了。
然后,我们需要给 App 设立路由跳转,所有的界面跳转都需要通过路由来分发,如果我们匹配到需要跳转到有 bug 的这样一个新功能时,那我们就不跳转了,或者是跳转到统一的异常正处理中的界面。如果这两种方式都不可以,那就可以考虑通过热修复的方式来动态修复,目前热修复的方案其实已经比较成熟了,我们完全可以低成本地在我们的项目中添加热修复的能力,当然,如果有些功能是由 RN 或 WeeX 来实现就更好了,那就可以通过更新资源包的方式来实现动态更新。而这些如果都不可以的话呢,那就可以考虑自己去给应用加上一个自主修复的能力,如果 App 启动多次的话,那就可以考虑清空所有的缓存数据,将 App 重置到安装的状态,到了最严重的等级呢,可以阻塞主线程,此时一定要等 App 热修复成功之后才允许用户进入。
六、如何优化自定义 View?
1、自定义 view 的 onTouchEvent 事件中不要多次调用 surper.onTouchEvent 这样滑动时候会卡顿。
@0verride public boolean onTouchEvent (MotionEvent e) {super. onTouchEvent (e); return super. onTouchEvent (e): }
代码看起来很蠢,一般也不会有人这样写,但是有的时候不经意会打印一条日志然后,正好就调用了这句话。然后就会导致页面卡顿。去找原因的时候又很难发现。所以,注意:在写代码的时候 onTouchEvent 事件中不要多次调用 surper.onTouchEvent
七、mmap + native 日志优化?
传统日志打印有两个性能问题,一个是反复操作文件描述符表,一个是反复进入内核态。所以需要使用 mmap 的方式去直接读写内存。
八、ACTION_CANCEL 什么时候触发,触摸 button 然后滑动到外部抬起会触发点击事件吗,再滑动回去抬起会么?
首先看一下官方的解释:
/** * Constant for {@link #getActionMasked}: The current gesture has been aborted. * You will not receive any more points in it. You should treat this as * an up event, but not perform any action that you normally would. */ public static final int ACTION_CANCEL= 3;
说人话就是:当前的手势被中止了,你不会再收到任何事件了,你可以把它当做一个 ACTION_UP 事件,但是不要执行正常情况下的逻辑。
然后我的理解就是:滑出 view 范围后,如果父 view 没有拦截事件,则会继续受到 ACTION_MOVE 和 ACTION_UP 等事件。
一旦滑出 view 范围,view 会被移除 PRESSED 标记,这个是不可逆的,然后在 ACTION_UP 中不会执行 performClick() 等逻辑。
九、点击事件被拦截,但是想传到下面的 View,如何操作?
重写子类的 requestDisallowInterceptTouchEvent() 方法返回 true 就不会执行父类的 onInterceptTouchEvent(),即可将点击事件传到下面的 View。
十、1、什么是 ANR 如何避免它?
答:在 Android 上,如果你的应用程序有一段时间响应不够灵敏,系统会向用户显示一个对话框,这个对话框称作应 用程序无响应(ANR:Application NotResponding)对话框。用户可以选择让程序继续运行,但是,他们在使用你的 应用程序时,并不希望每次都要处理这个对话框。因此,在程序里对响应性能的设计很重要这样,这样系统就不会显 示 ANR 给用户。
不同的组件发生 ANR 的时间不一样,Activity 是 5 秒,BroadCastReceiver 是 10 秒,Service 是 20 秒(均为前台)。
如果开发机器上出现问题,我们可以通过查看 /data/anr/traces.txt 即可,最新的 ANR 信息在最开始部分。
- 主线程被 IO 操作(从 4.0 之后网络 IO 不允许在主线程中)阻塞。主线程中存在耗时的计算 主线程中错误的操作,比如 Thread.wait 或者 Thread.sleep 等 Android 系统会监控程序的响应状况,一旦出现下面两种情况,则弹出 ANR 对话框 应用在 5 秒内未响应用户的输入事件(如按键或者触摸)BroadcastReceiver 未在 10 秒内完成相关的处理 Service 在特定的时间内无法处理完成 20 秒
修正:
1、使用 AsyncTask 处理耗时 IO 操作。
2、使用 Thread 或者 HandlerThread 时,调用 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND) 设置优先级,否则仍然会降低程序响应,因为默认 Thread 的优先级和主线程相同。
3、使用 Handler 处理工作线程结果,而不是使用 Thread.wait() 或者 Thread.sleep() 来阻塞主线程。
4、Activity 的 onCreate 和 onResume 回调中尽量避免耗时的代码。BroadcastReceiver 中 onReceive 代码也要尽量减少耗时,建议使用 IntentService 处理。
解决方案:
将所有耗时操作,比如访问网络,Socket 通信,查询大 量 SQL 语句,复杂逻辑计算等都放在子线程中去,然 后通过 handler.sendMessage、runonUIThread、AsyncTask、RxJava 等方式更新 UI。无论如何都要确保用户界面的流畅 度。如果耗时操作需要让用户等待,那么可以在界面上显示度条。
十一、Bunder 传递对象为什么需要序列化?Serialzable 和 Parcelable 的区别?
因为 bundle 传递数据时只支持基本数据类型,所以在传递对象时需要序列化转换成可存储或可传输的本质状态(字节流)。序列化后的对象可以在网络、IPC(比如启动另一个进程的 Activity、Service 和 Reciver)之间进行传输,也可以存储到本地。
大公司 VS 小公司
1、大公司提供给你的只是一个基层岗位,薪资待遇也一般,但公司名气明摆着,说出去更好听。
2、创业小公司提供给你的是一个充满挑战的岗位,承诺的待遇很让人心动,但是要冒风险,在亲朋好友面前说起来貌似也不够体面。
选择同样是非常重要的,选择的首要前提是你要有很多机会,不然你都没机会怎么选择,在很多机会摆在你面的时候,一定要认真思考,不要冲动,想好自己需要的,多听别人的意见,最后自己决定。我们不能保证每一次选择都是正确的,但是能保证我们是不后悔的,遇事要冷静,多思考。
这里说的选择不仅仅是选择去哪个公司,从事什么方向,还有与什么样的同事工作,甚至是生活中的事情,网上说一个人要有一些成就,需要具备下面几点,我觉得非常的对:
生活与工作
其实这个话题对我来说有一些困惑,“工作是为了更好的生活”,这句话是非常正确的,但是生活,是一种经历,也是一种体验;生活是一种感受,也是一种积累。生活没有答案,生活不需要答案。当生活即将不属于你时,你才会发现:生活仅仅是一个过程,而这个过程无论多么复杂,最终结局都是一样的。生活注重的是过程,而不是结局。最后你也要知道世上没有一件工作不辛苦,没有一处人事不复杂,如果命中注定是打工,便应该打好它,你要相信,七十二行,行行可出状元。
原文链接:http://www.5ityx.com/cate100/159433.html