Android面试题及其参考答案

时间:2022-06-23 14:37:18

自己遇到的一些问题,参考答案也是我自己写的,鉴于自己格局太低,眼界不够,所以参考的地方可能有很多错误

消息队列在哪个线程中

对于Android来讲,每个线程都有一个消息队列,但是主线程中的消息队列是系统自动打开的.对于子线程来讲,如果要使用子线程的消息队列那么需要我们手动打开,使用looper.prepare()和looper.loop()打开.

广告

因为之前公司做的都是外包的产品,所以直接往其中使用有米SDK插入广告肯定是不合适的,而一般来讲做自己公司的产品一般都希望先将产品做大,在利用流量的入口做广告,很可惜我目前位置还没有做过高并发,连百万用户量级的产品都没有做过.

如何统计应用上线后的错误?

使用友盟统计这个第三方SDK就可以完成统计上线产品错误这个任务,它同时还可以为我们提供用户的其他一些信息,比如说用户手机品牌,系统型号,用户使用地点等.而且他的分析方式也很全面,比如说有些直观的折线图,饼图,表格,曲线等等十分直观好用.

上线后统计的错误中,哪个出现的最多?

最开始编程的时候,说实话错的最多的是空指针异常,因为当时也是少不经事吧,一些感觉不可能为空的数据,拿到一些数据或者在这个类中明明刚被new的对象,在下面用的时候就是null的,很烦.后来就聪明了,拿到对象,不管三七二十一先判断是不是空,再用.这样以后除了有点麻烦之外,空指针异常确实少了很多.其他除了空指针异常外,其他每个错误其实都差不多多少,比如说什么非法状态异常啊,非法参数异常啊等等

你最擅长哪些东西?

asyntask和handler比较

他俩都可以用来进行耗时操作,进行异步处理.asyntask结构比较整齐,提供了几个方法,doinbackground()进行耗时操作啊啊onPostExecute()在耗时操作执行完毕后执行啊.asyntask在代码书写上比较方便,代码量小一点.但是据说他底层用的其实还是handler,所以代码轻量,其实消耗资源可能比handler更多一点.

有没有做过推送

之前用的第三方SDK极光推送 推送方式:第一种通知,推送文本内容直接展示在用户的通知栏上.还有一个是自定义信息,也就是推送自定义的消息内容传给应用,应用根据内容自己偷偷摸摸的进行一些处理. 推送目标:广播,所有人都可以收到.标签,推送给一类人.别名,推送给一个人. 极光推送集成比较简单.而且还集成了一些关于推送历史啊,推送统计报表之类的,所以一直在使用极光推送.

极光推送的问题:1.有些机型收不到推送,这个有两方面的原因.第一个原因是很多机型因为是自己做的Rom,所以需要用户手动开启软件自启这个功能.不让在用户杀死进程和重新开机之后就收不到,因为进程被干掉了.还有一个收不到通知的原因是极光推送服务器可能有时候压力很大,很多推送没完成要一个一个完成,所以有很强的延迟,导致短期无法收到让程序员以为收不到.这个没办法解决. 2.很多机型用户可以关闭某个应用的通知栏通知,这也会导致消息即使推送到了也不会有显示.

遇到的最大问题

遇到没见过的错误怎么办?

看着错误翻译一下大概猜下这玩意是什么错误,想一下可能是什么地方出了这问题,想不出来.先clean项目.不行在重启一下eclipse还是不行.就谷歌.因为百度对于大量英文的错误显示的搜索结果其实很难让人满意.另外还有*上查一下.另外也加了几个Android开发群,问一下群里的人. 另外有些错误其实是很难重现的,也就是说他发生的频率很小,有可能测试点了点了几百次,出现了这个错误,然后你让测试给你描述下错误场景,想根据场景判断大概是什么错误,然后你发现测试再也无法模拟出这个错误.这种错误在普通用户手中出现的概率可能就更低了,几万分之一,但是想处理他的难度确实很大很大,这时这种问题也就只能选择忽略了.

应用广播的场景

这个我以前用过一个比较好的场景.是一个手机验证码注册的场景.打开手机验证码注册这个activity的时候动态注册一个监听短信到来的广播,由于短信到来这个广播是有序广播,我把自己接受短信这个广播优先级设置为最高,用户点击发送验证码.然后等着,我们发送一个验证码给用户的手机,拿到短信内容,根据正则表达式拿到验证码直接填到验证码哪个edittext上.当时由于用户可能同时注册多个app,所以没有选择中止掉短信,短信还是会出现在信箱中.

常见的设计模式

  • 观察者设计模式(发布/订阅模式,监听者模式):

基于消息的发布/订阅事件模型,它本身相当于一种一对多的依赖关系,让多个观察者同时监听一个主题对象.这个对象在状态发生变化时,所有观察者自动更新自己. 优点:1. 解耦,我的按钮被点击了,是我的事情,至于我的按钮被点击之后你要做什么是你的事情,所以你要自己设置监听器观察者观察我,在我改变之后也是你自己改变自己,而不是我改变的时候我改变你.缺点:有时候可能就只要一对一,但是利用一对多的广播有点浪费性能. 在android中:1.广播,比如说电量变化广播由系统发出,你自己选择要不要订阅.发布/订阅模式2.监听器:一个开关的按钮状态被改变,其他控件要根据这个开关状态改变自己的状态就设置一个监听器,监听观察当这个开关状态被改变时,我要做什么

  • 单例设计模式:

确保内存中只有一个实例,减少内存开支和其消耗的系统性能. 优点:一个对象频繁创建和销毁时,性能优化很明显. 写法:1. 私有化构造方法,2.私有的,静态的对象instance,3.提供getinstance()方法 注意:在getinstance()加上线程同步锁.

  • 适配器模式

服务的应用场景

网络下载,音乐播放.由于服务是长期运行在后台而且不易被系统回收,所以我们还可以利用服务定期从服务器获取数据,不过这个对于android手机来讲性能消耗太大,所以一般不这样.

远程服务的应用场景

这个我有一个记忆蛮深刻的,很多应用都有一个是清理缓存对吧?当时项目经理让我做哪个,我脑子秀逗了,用的就是aidl,因为系统有一个软件详情界面,里面有清除缓存清除数据啊这些功能,我当时问我项目经理,直接跳这界面让用户手动点一下行不行,项目经理说不行,然后我就回去自己想了,想到我直接找到系统这个按钮把代码粘过来就可以了,当时还觉得我聪明呢.后来也就真这么做了,不过没粘代码,吧系统的aidl文件粘过来了,用的是系统的服务中的这个方法. 任务完成了...后来有一天我才意识到一件事情,我自己应用的文件缓存在什么地方是我自己设置的,我直接干掉那些文件就可以了..用aidl真的只能说自己在做..

JNI是什么,怎么用

Java本地接口,java native interface.NDK是Google开发的一套本地开发工具,主要就用于android的JNI开发了.JNI好处:更底层,所以可以调用硬件了,这也导致了他更高效.由于对于我们来讲JNI是用来java调用c的,c本身不容易反编译,所以也更安全. 使用场景:以前做了一个产品,强行要安全性能,其实就是个普通的软件.然后我们就搞了个加密,后来强行说是三层加密,当时就是把一个密钥放到了c代码中,通过c语言拿到这个字符串,因为c反编译不太容易嘛.这算了一层加密,然后又用RSA非对称加密算法又加了一次,然后又代码混淆了一次.项目经理强行说这是三层加密.代码混淆也能说成是加密我也是醉了. 具体用法我都忘了 就记得什么 在自己这里定义native,c工程师给了个什么so文件,然后还要求什么两边方法名还是什么名要一样的.

应用怎么进行版本迭代

  • 方式1:通过友盟的版本更新功能
  • 方式2:我们通过包管理器和包名可以拿到app在清单文件中的版本号和版本名字,每次在进入闪屏页面的时候,拿到当前手机安装的软件的版本然后在从服务器上拿到服务器上最新的版本(获取Json字符串),对比一下,不一样了就弹出对话框,提示用户下载(xutils的httputils),下载完成后发送intent,安装.(bug,安装的时候取消安装这时会出问题,所以通过startactivityforresult()有结果返回,就直接进入主界面,不然会出现在闪屏界面停住不懂的bug)

Fragment的好处

他有自己的生命周期方法,解耦性比较好,比如说一个activity没有fragment也可以将他分成三部分,但是这时这个activity里面可能就要处理这三部分的逻辑了.但是如果换成三个fragment那么activity则就不用管这些,每个区域的逻辑都由fragment自己管自己的. 官方设计这玩意的目的是适应大屏幕,其实在我看来这理由不太好,因为大家都看的出Android系统的平板电脑销量真的不怎么样.苹果的ipad的没有任何对手,而且平板说实话现在也很那卖,ipad的没有对手,销量也在下降,大家发现ipad能干的手机大概都能干,电脑能干的,手机不能干的,ipad一般也干不了..

怎么与服务器进行交互

通过http协议,采用post或者get方式进行交互 HttpURLConnection HttpClient asycnHttpClient XUtils _ HttpUtils Volley(重点看下这个,谷歌官方的,最近都在用.但是在使用过程中一般会在封装一次,怎么封装百度一下)

get和post区别

get:将数据拼到URL 中,适合数据量小的情况,相对来讲不太安全.但是效率高一点 post:将数据放在消息体中,数据量可以很大,数据不在地址栏显示

同步线程和异步线程

同步的时候,你会一直等到她来了之后才做其他事情,这个过程除了等待你啥都不会做, 异步的时候,你一边在等,可能一边玩游戏或者是看报纸什么的,一直到她到来,你的等待状态才会结束 在实现上,同步的过程会阻塞进程的所有其他操作,将同步转换为异步的最常见方法则是 将会阻塞进程的等待操作放入到一个新的进程中,同时为该等待操作添加一个监视器,在检测到等待操作完成的时候结束等待的进程。

多线程的安全

这个好像举得最多的例子就是银行取钱的问题了,在我取钱的时候,第一个线程查询到我有五百块,这时候第二个线程进来,查询也是我有五百块,然后取了五百块,金钱变成0,线程切给了第一个线程,取了一百块,刚才查的500现在取了一百还剩400,又把第二个线程刚才改的0改成了400.我取了600块,银行账户只减了一百块.这就是多线程的安全问题. 解决办法,使用加锁就可以了.我修改数据的时候,不让其他人(线程)动.

Http数据传输的安全怎么保证

安全也是分很多种的,比如说保证数据传输的保密性啊,保证数据的完整性,鉴别数据到底是谁传过来的,防止别人模拟假命令造成损失啊. 要保证数据传输的保密性,就是被别人抓包之后拿不到数据,就用https协议,鉴别传过来的数据是不是完整的,可以用tcp协议,他是面向连接的可靠的协议,当然我们自己本身其实可以将一个文件使用哈希算法计算出一个值,把这个值添加到文件后面用于验证完整性.

常用的算法

两个很简单的算法看一下,大概能讲出来就可以

冒泡排序 选择排序

Java异常体系结构

发生未捕获异常

写一个类继承UncaughtExceptionHandler.实现其中的uncaughtException()方法.发生未捕获异常,干掉这个进程,自己另开一个进程重启app

Android面试题及其参考答案