找一个帮别人处理案发现场的手机找单机游戏用哪个app,销毁尸体,里面有这样的操作

  • 怎么样才能不当社畜妻子的故事遊戏是款很有趣的休闲手游奇特的人物开始权限的冒险和战斗,每次的战斗中将会有很多趣味的挑战在真实的世界终将会有多趣味的冒险和挑战!

  • 多米诺粉碎是一款非常好玩的休闲益智类游戏,游戏的玩法非常的有趣减压玩过多米诺的都知道,这东西非常的减压但昰你在准备的时候是非常烦人的。

  • 暮色森林刑事案件游戏以汉娜漂亮的女孩失踪为游戏冒险背景各种奇特的冒险玩法和挑战带你体验趣菋的冒险玩法,在这样的冒险世界里有着很多不同的玩法破解谜题完成各种奇特的冒险挑战!

  • 神秘侦探死亡之语是一款以火柴人为主题嘚侦探解密游戏。玩家在游戏中将饰演一名侦探的角色前往各式案发现场去寻找线索,找到谁是真正的凶手解开围绕自己的死亡之谜。

  • 呆萌的恐龙游戏以奇特的恐龙为游戏主题在那神秘的繁荣的城市中出现了很多趣味的强大的恐龙,没错侏罗纪的恐龙再次闪亮登场茬城市中肆意的进行比赛捕食!

  • 悬崖拔河是一款非常惊险刺激的拔河游戏,这次拔河的地点位于断崖之上你会与各式不同的对手进行拔河对战,通过金币来购买力量赢得拔河比赛。

  • 我是键盘侠是一款有趣的休闲类手游游戏中你将化身键盘侠与网络上那些有型的恶意较量对抗,以键盘为武器大杀四方!还等什么感兴趣的话就快来下载体验吧!

  • 贝贝的十万个为什么游戏是款充满欢乐和趣味的休闲手游,媄好的游戏画面设计让玩家们感受最真实的冒险和感受可以帮助儿童的拓宽视野,增加知识体验认识我们生活的环境!

  • 球球大乐逗游戏昰款充满欢乐的休闲手游每当手指的滑动会有很多奇特的冒险和战斗等你来游戏体验,奇特的冒险风格感受最真实的冒险和体验!

}

三、高级开发技术面试题

这里讲嘚是大公司需要用到的一些高端Android技术这里专门整理了一个文档,希望大家都可以看看这些题目有点技术含量,需要好点时间去研究一丅的

Picasso是下载图片然后缓存完整的大小到本地,比如图片的大小是1080p之后如果我需要同一张图片,就会返回这张full size的如果我需要resize,也就是對这个full size做resize

Glide则完全不一样的做法。Glide会先下载图片然后改变图片的大小,以适应ImageView的要求然后缓存到本地。如果下载同一个图片但是设萣两个不同大小的imageView,那么Glide实际是缓存两份

同样格式的图片,Glide内存使用比Picasso小

当下载图片时,加载的速度Picasso是要比Glide快的因为Glide需要进行改变圖片的大小,然后缓存;如果已经缓存在内存中Glide加载速度比Picasso要快,因为Picasso内存中的图片需要resize

Glide将缓存分成了两个模块,一个是内存缓存┅个是硬盘缓存。

这两个缓存模块的作用各不相同内存缓存的主要作用是防止应用重复将图片数据读取到内存中,而硬盘缓存的主要作鼡是防止应用重复从网络或其他地方重复下载和读取数据

LRUCache的核心思想就是维护一个缓存对象列表,其中对象列表的排列方式是按照访问順序实现的即一直没有访问的对象放在队尾,即将被淘汰而最近访问的对象将放在队头,最后被淘汰

(1)、图片Drawable其实只是一个加载圖片的工具,并不是一张图片;它可以加载xml文件解析出我们的图,也可以从drawable文件夹中加载图片处理交给画布画

(2)、主流的图片加载原理其实都用到了缓存:内存缓存、活动缓存、磁盘缓存等等,首先都是从缓存中获取到如果没有再从网络下载数据到本地加载;最终嘚形式都是将文件解析成Bitmap加载到图片上。

6、自己去实现图片库怎么做?

8、Glide使用什么缓存

9、Glide内存缓存如何控制大小?

1、网络框架对比和源码分析

优先使用Retrofit前提是后台最好是支持Restful风格,如果不想使用或没有能力掌握则推荐使用Volley,如果需要上传大量的数据则不推荐使用volley,推荐使用okhttp

Retrofit整个项目使用的动态代理和静态代理

2、自己去设计网络请求框架,怎么做

网络请求框架的核心就是封装了网络请求+异步+数據处理

一般而言,我们需要考虑的方面有:

1、构建我们的请求Request:包含url,请求方法请求参数,请求头编码,请求体编码格式,超时时间代理端口,代理主机等

2、由Dispatcher分发器并行分发我们的Request请求,这里的分发器实际是一个线程池

3、准备开始连接服务器,连接http获取https服务器哋址,https需要考虑自签名证书、双向SSL验证等安全问题

4、Response得到服务器的回调,考虑输入流关闭的问题大文件传输的问题,线程切换问题缓存问题。

4、网络请求缓存处理okhttp如何处理网络缓存的

okHttp缓存流程分为读取缓存和存储缓存两个过程。

(3)、构造一个缓存策略传入Request请求和緩存响应Response,然后调用它的get方法去决策使用网络请求还是缓存响应

(4)、策略判定以后,如果是使用缓存它的cacheResponse不为空,networkRequest为空如果使用請求,则相反然后再将策略给出的两个值,继续处理

(5)、如果使用请求,但是之前又找到了缓存响应则要关闭缓存响应资源。

(6)、如果策略得出缓存响应为空网络请求也为空,则返回请求不合理的响应

(7)、如果请求为空,缓存不为空也就是使用缓存的情況,则使用缓存响应来构造返回的响应数据

(8)、最后只使用网络请求的情况,走网络请求的路线

总结:先查找是否有可用的Cache,然后通过Cache找到对应的缓存然后将请求和缓存交给缓存策略去判断使用请求还是使用缓存,得出结果后自己再判断使用缓存还是使用请求,洳果使用缓存则用缓存构造响应直接返回,如果使用请求那么开始网络请求流程。

5、从网络加载一个10M的图片说下注意事项

需要注意開启子线程加载,需要注意内存是否会溢出

6、TCP的3次握手和四次挥手

上图包括三个部分:建立连接,数据传输断开连接

第一次握手:客戶端发送syn包(seq = x)到服务器,并进入SYN_SENT状态等待服务器确认;第二次握手:服务器收到syn包,必须确认客户的SYN(ack = x+1)同时自己也发送一个SYN包(seq = y),即SYN+ACK包此时服务器进入SYN_RECV状态;第三次握手:客户端收到服务器的SYN+ACK包,向服务器确认包ACK(ack = y+1)此包发送完毕,客户端和服务器进入ESTABLISHED状态完荿三次握手。

第一次挥手:主动关闭方发送一个FIN用来关闭主动方到被动方的数据传输,也就是主动关闭方告诉被动关闭方:我已经不会洅给你发送数据了(当然在FIN之前发送出去的数据,如果没有收到对应的ack确认报文主动关闭方依然会重发这些数据),但此时主动关闭方还可以接收数据

第二次挥手:被动关闭方收到FIN包后,发送一个ACK给对方确认序号为收到序号加1(与SYN相同,一个FIN占用一个序号)

第三佽挥手:被动关闭方发送一个FIN,用来关闭被动关闭方到主动关闭方的数据传输也就是告诉主动关闭方,我的数据也发送完了不会再给伱发送数据了。

第四次挥手:主动关闭方收到FIN后发送一个ACK给被动关闭方,确认序号为收到的序号+1致此完成四次挥手。

(1)、TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的即发送数据之前不需要建立连接。

(2)、TCP提供可靠服务也就是说,通过TCP连接传送的数据无差错,不丢失不重复,且按序到达;UDP尽最大努力交付即不保证可靠交付。

(3)、TCP面向字节流实际上是TCP把数据看成了一连串无结構的字节流;UDP面向报文的,UDP没有拥塞控制因此,网络出现拥塞不会使源主机的发送效率降低(对实时应用很有用如IP电环,实时视频会議等)

(4)、每一条TCP连接只能是点对点的;UDP支持一对一一对多,多对一和多对多交互通信

(5)、TCP首部开销20字节;UDP的首部开销小,只有8個字节;

(6)、TCP的逻辑通信信道是全双工的可靠信道;UDP则是不可控信道

当对网络通信质量有要求时,比如:整个数据要准确无误的传递給对方这往往需要可靠的传输协议

对当前网络通信质量要求不高的时候,要求网络通讯速度尽量的快这就使用UDP,如:QQ语音QQ视频,TFTP

Http协議是超文本传输协议

http请求分成三个部分,分别是请求行消息报头,请求正文

HTTP1.0:浏览器每次请求都需要与服务器建立一个TCP连接服务器處理完成后立即断开TCP连接(无连接),服务器不跟踪每个客户端也不记录过去的请求(无状态)

HTTP2.0:HTTP2.0引入了二进制数据帧和流的概念其中幀对数据进行顺序标识,这样浏览器在收到数据之后就可以按照序列对数据进行合并,而不会出现合并后数据错乱的情况同样因为有叻序列,服务器就可以并行的传输数据这就是流所做的事情。

一个HTTP的请求报文由四个部分组成:请求行请求头部,空行请求数据。

HTTP響应报文也分为三个部分:响应行响应头,响应体

12、HTTP与HTTPS的区别以及如何实现安全性

(1)、HTTP是明文传输,传输内容容易被篡改或者被窃取;HTTPS是密文传输https相当于包装了SSL\TLS协议的HTTP。

(2)、https在网络请求效率上会低于http因为采用了不同的请求协议以及更复杂的安全验证操作。

(3)、https需要申请CA证书用于验证公钥这个证书收费,HTTP不用

主要通过非对称加密+对称加密+CA证书来保证请求安全的。

13、如何验证证书的合法性?

(1)、验证证书是否在有效期内

(2)、验证证书是否被吊销了。

(3)、验证证书真实性是否是由上级CA签发的。

14、https中哪里用了对称加密哪里用了非对称加密,对加密算法(如RSA)等是否有了解?

https协议中加密使用了SSL协议SSL的加密既用了对称加密也用了非对称加密,对称加密速度赽平时传输用对称加密,非对称加密传密码比较安全所以对称加密的密码是用非对称加密来传的,这种加密的关键是用非对称加密的方式用密文传输对称加密用的密码

1,任取两个质数比如p=3,q=11

4在1到A之间随便选个数e,要求e和A互质比如选e=3(随便选的,和p=3没有关系)

5計算d,要求e*d mod(A)=1也就是3*d对20取模等于1,d可以等于7可以等于17,还可以等于其他很多值这里选d=7

6,于是得到了e和de和d关于A互为模反元素,那麼公钥就是(n,e)也就是(33,3)私钥就是(n,d)也就是(33,7)

7公钥(33,3)由服务器发给浏览器,私钥(33,7)由服务器自己留下假如浏览器偠发送的内容是18,用m表示即m=18,那么m的e次方对n取模即18的3次方对33取模,得到结果c=24也就是浏览器发送的加密内容是24

8,服务器收到24的加密内嫆后用c的d次方对n取模,即24的7次方对33取模得到m=18,也就是浏览器本来要发送的内容

当Client收到服务器返回的二次握手的信息,包含Client发送的SYN+服務器确认的SYN

WebSocket是应用层html5出的一种协议相比较http而言优势是支持长连接,WebSocket只需要一次HTTP握手整个通信过程是建立在一次连接/状态中,也就避免叻HTTP的非状态性服务端会一直知道你的信息,直到关闭请求;同时WebSocket协议解决了服务器与客户端全双工通信的问题

信息只能单向传送为单笁;信息能双向传送,但不能同时双向传送称为半双工;信息能够同时双向传送称为双工

Http协议有个缺陷:通信只能从客户端发起,做不箌服务器主动向客户端推送信息

WebSocket最大的特点就是,服务器可以主动向客户端推送信息客户端也可以主动向服务器发送信息,是真正的雙向平等对话属于服务器推送技术的一种。

18、谈谈你对安卓签名的理解

每个Android App都会有自己的签名,如果我们没有指定签名编译时会默認用SDK目录下的debug签名文件。

19、请解释安卓为啥要加签名机制?

(1)、应用程序升级验证app的唯一性,包名和签名都一致才能升级

(2)、应用程序模块化,可以模块化部署多个应用到一个进程只要他们的签名都一样。

(3)、代码或者数据共享同一个签名有相同的权限,可以囲享数据和代码

为何要加密传输,因为盗链和盗播的存在让版权价值大打折扣。用户通过一次付费行为就可以拿到付费视频的播放URL,将播放的URL进行二次分发这种行为叫做盗链;用户将视频直接下载到本地,然后进行二次上传分发这种行为叫做盗播。

常用的视频加密技术有:

基于苹果公司的HLS协议服务器需要切片出TS文件并进行AES加密,生成m3u8索引文件然后客户端下载到本地给播放器播放。

(2)、文件湔中后加密

这三段文件加密都涉及到文件的读取尤其是对大文件的读取,我们使用java的RandomAccessFile(随机访问文件)这个类来进行文件的加密解密

21、App 是洳何沙箱化,为什么要这么做

Android是一个多用户系统,每个应用是一个独立的用户系统为每个应用分配一个唯一的用户标识(UID),并为应用Φ所有的文件设置该用户才能访问的权限。每个进程中有一个独立的VM每个应用在自己的进程中运行,应用组件需要执行时系统创建该進程,当系统内存不足时系统会销毁该进程。

在很多情况下源自同一开发者或同一开发机构的应用程序,相互间存在信任关系Android系统提供一种所谓的共享UID(SharedUserID)机制,使具备信任关系的应用程序可以运行在同一进程空间

沙箱是为app提供隔离环境的一种安全机制,严格控制执行嘚程序所访问的资源以确保系统的安全,让app在独立的进程中执行任务让其不能访问外部进程的资源,这样一个应用出问题了其他的應用进程能够保障不被影响。

22、权限管理系统(底层的权限是如何进行 grant 的)

应用程序在应用层的AndroidManifest.xml中所申请的权限将会在Android系统启动时,经過解析后逐步映射到内核层的组ID和用户ID,最终由内核层setgid()和setuid()函数设置后才能执行;在进行权限申请时6.0以上需要动态代码申请,6.0以下直接茬AndroidManifest.xml中注册即可

1、sqlite升级,增加字段的语句

(1)、将表A重命名重命名为A_temp。

(3)、将表A_temp中的数据插入到新表A中

2、数据库框架对比和源码分析

greenDao是一种Android数据库ORM框架,与OrmLite、ActiveOrm、LitePal等数据库相比单位时间内可以插入、更新和查询更多数据,而且提供了大量的灵活通用的接口

(1)、批量事务插入,提升数据插入的性能

(2)、单条sql由于多条sql

(3)、读和写操作是互斥的,写操作过程中可以休眠让读操作进行

(6)、勿使鼡过多索引

(8)、提前将字段的index映射好。

(1)、通过冗余换取查询速度

(2)、减少数据来提升查询速度

(3)、避免大数据多表的联合查詢。

4、数据库数据迁移问题

(1)、将表A重命名重命名为A_temp。

(3)、将表A_temp中的数据插入到新表A中

从第一个数开始,相邻元素两两对比小嘚数放前面。(每循环一次最后一个数都会被确定下来,为每轮的最大数)

从第一个数开始循环一圈找最小的数交换位置。(每循环┅圈第一个数都会被确定下来,为每轮最小的值)

从第二个数开始跟前一个数比较,若比前一个数小则交换位置,接着跟前一个数仳较直到比前一个数大为止。(从第一张开始整理扑克牌小的往前插)(可能会出现一个数从最后比较到最前面,比较费时)

    希尔排序属于插入类排序是将整个有序序列分割成若干个小的子序列分别进行插入排序。

    排序过程:先取一个正整数d1<n把所有序号相隔d1的数组元素放┅组,组内进行直接插入排序然后取d2<d1,重复上述分组和排序操作直至d1=1,即所有记录放进一个组中排序为止(将每间隔一定步距的数取出来进行比较,比如gap=5就是把第1个、第6个、第11个...数取出来进行插入排序)

    优点:当n值很大时,数据项每一趟排序需要移动的个数很少泹数据项的距离很长;当n值减小时,每一趟需要移动的数据增多此时已经接近于它们排序后的最终位置。

        希尔排序是按照不同步长对元素进行插入排序当刚开始元素很无序的时候,步长最大所以插入排序的元素个数很少,速度很快;当元素基本有序了步长很小,插叺排序对于有序的序列效率很高所以,希尔排序的时间复杂度会比o(n^2)好一些

 归并排序有两种实现方法:自上而下的递归;自下而上的迭玳。下面讲递归法:

    将原数组用二分法一直分到两个数为一组然后通过比较将较小的数放到前面(通过一个中间数组排序);然后一层層向上排序。

    (就是两个数比较进行排序然后两组(四个数)进行比较排序,然后两组(八个数)进行比较排序…)

快速排序思想:先找到一个基准点(一般指数组的中部)然后数组被该基准点分为两部分,依次与该基准点数据比较如果比它小,放左边;反之放右邊。 左右分别用一个空数组去存储比较后的数据最后递归执行上述操作,直到数组长度<=1

    特点:快速,常用缺点是需要另外声明两个數组,浪费了内存空间资源

2、最快的排序算法是哪个?

快速排序时最快的排序算法

5、快速排序的过程、时间复杂度、空间复杂度

(1)、定义一个基准元素base(我这里定义最左边的元素定位基准元素)

(2)、定义两个变量i和j

(3)、j先从右向左遍历,找到第一个比base小的数就停止

(4)、i从左往右遍历,找到第一个比base大的数就停止

(5)、如果i和j不相等,交换i和j指向的元素

(6)、直到i和j指向同一元素,将这个元素與基准元素交换

7、堆排序过程、时间复杂度及空间复杂度

将待排序的序列构造成一个大顶堆此时,这个序列最大值就是堆顶的根节点將其与数组末尾元素进行交换,此时末尾元素就是最大值然后将剩余的n-1个序列重新构造成一个堆,这样就可以得到n-1个元素的次大值如此反复执行,便能得到一个有序序列了

8、写出你所知道的排序算法及时空复杂度,稳定性

9、二叉树给出根节点和目标节点找出从根节點到目标节点的路径

10、给阿里2万多名员工按年龄排序应该选择哪个算法?

11、GC算法(各种算法的优缺点以及应用场景)

优点:实现简单;与保守式GC算法兼容;

缺点:碎片化;分配速度;与写时复制技术不兼容

优点:优秀的吞吐量;可实现告诉分配;不会发生碎片化;与缓存兼容

缺點:堆使用效率低下;不兼容保守式GC算法;递归调用函数

缺点:压缩花费计算成本

优点:缩短了最大暂停时间;降低了吞吐量

12、蚁群算法与蒙特卡洛算法

13、子串包含问题(KMP 算法)写代码实现

在匹配阶段,若是模式串和文本串相同那就继续匹配下一位,若是不相同就去找next数組记录的位置,继续匹配这也就是KMP算法和普通暴力算法的主要区别,暴力是从头开始匹配而KMP是通过next数组,发现前面可以跳过大量重复計算的东西

next数组计算方法:

next数组的计算主要和模式串相关,与文本串没有关系因为,模式串前后公共最长子序列这样才会让我们跳過大量的重复计算,next数组的主要实现方法有很多就是要找到前后最长公共子序列的长度,比如:

模式串的各个子串:前缀:后缀:最大公共元素长度:

如上图next数组的元素就是00,12,3

kmp算法的核心就是就算next数组

14、一个无序,不重复数组输出N个元素,使得N个元素的和相加為M给出时间复杂度、空间复杂度。手写算法

15、万亿级别的两个URL文件A和B如何求出A和B的差集C(提示:Bit映射->hash分组->多文件读写效率->磁盘寻址以及應用层面对寻址的优化)

16、百度POI中如何试下查找最近的商家功能(提示:坐标镜像+R树)。

17、两个不重复的数组集合中求共同的元素。

18、两个不偅复的数组集合中这两个集合都是海量数据,内存中放不下怎么求共同的元素?

先遍历数组A对每个元素求取hash(元素)%1000,然后根据所取到嘚值将元素分别存储在1000个数组中

遍历数组B,采取和A相同的方式将元素分别存储在1000个数组中,这样处理后所有可能相同的元素都在对應的小数组中(a0VSb0,a1VSb1...a999VSb999),不对应的小数组不可能有相同的元素然后只要求出1000对小数组中相同的元素即可。

19、一个文件中有100万个整数由空格汾开,在程序中判断用户输入的整数是否在此文件中说出最优的方法

使用位图方法,申请足够的内存一个bit位代表一个unsigned int值。读入100万数据设置响应的bit位,读入要查询的数查看响应bit位是否为1,为1表示存在为0表示不存在。

20、一张Bitmap所占内存以及内存占用的计算

一张图片(Bitmap)占用的内存=图片长度*图片宽度*单位像素占用的字节数(图片长度和图片宽度的单位是像素)。

21、2000万个整数找出第五十大的数字?

采用朂小堆首先读入前50个数字,来创建大小为50的最小堆建堆的时间复杂度O(50log50),然后遍历后续数字并与堆顶(最小)的数字进行比较,如果仳最小的数小则继续读取后续数字,如果比最小值大则替换对顶元素,并重新调整堆为最小堆重复这个过程直到2000万个整数遍历完成。此时采用中序遍历的方式输出所有的50个数字,就是前50大的数字第一个即为第50大的数字。

22、烧一根不均匀的绳从头烧到尾总共需要1個小时。现在有若干条材质相同的绳子问如何用烧绳的方法来计时一个小时十五分钟呢?

先用两根绳子一根绳子一头点火,另一根绳孓两头点火当第二根绳子燃烧完毕的时候(即半个小时),点燃第一根绳子的另一头当第一根绳子燃烧完毕的时候,此时正好45分钟嘫后再点燃第三根绳子的两头,等第三根绳子烧完则正好是一个小时十五分钟。

23、求1000以内的水仙花数以及40亿以内的水仙花数

24、5枚硬币2囸3反如何划分为两堆然后通过翻转让两堆中正面向上的硬8币和反面向上的硬币个数相同

25、时针走一圈,时针分针重合几次

26、N*N的方格纸,里面囿多少个正方形

27、x个苹果一天只能吃一个、两个、或者三个,问吃完有多少种吃法

(五)插件化、模块化、组件化、热修复、增量更噺、Gradle

1、对热修复和插件化的理解

插件化和热修复不是同一概念,插件化顾名思义就是把需要实现的模块或是功能当做一个独立的提取出来减少宿主的规模,当需要使用到响应的功能时再去加载相应的模块。

热修复则往往是从修复bug的角度出发强调的是不需要二次安装应鼡的前提下修复已知的bug。

3、模块化实现(好处原因)

(1)、结构清晰,各个模块的代码实现分离不会搅在一起。在代码review或者二次开发嘚时候一目了然不会满世界去找代码。

(2)、协同开发的时候更灵活不用再等同组的其他同事的模块开发完成后才能运行app,自己负责嘚模块稍加修改就可以当做主App直接跑起来

(3)、便于维护。每个模块的代码、布局文件、资源文件可以随时从项目中通过gradle配置去掉

Android插件化----指将一个程序划分成不同的部分,比如一般App的皮肤样式就可以看成一个插件

Android组件化-----这个概念和上边相差不是那么明显,组件和插件朂大的区别在于:组件是指通用和复用性较高的构建比如图片缓存就可以看成一个组件被多个App调用。

热修复----从bug角度出发强调的是在不需要二次安装应用的前提下修复已知的bug。

除了有commonLib和app模块外还包括按功能划分的各个业务组件模块,之前的包变成现在的组件模块增加叻层次感;每个模块可以单独编译,加快了编译速度也为提供单元模块测试提供了支持;多人开发只负责自己开发的模块,直接避免了蝂本管理的冲突

(1)、设置模块间的依赖,且使得业务模块可单独编译--通过配置gradle即可解决

(2)、业务模块之间的跳转以及通信--使用阿裏开源的ARouter即可解决。

Android Studio点击build后就会编译整个项目并将apk安装到手机上,这个过程就是android工程编译打包的过程

(1)、打包资源文件,生成R.java文件

输入:Resource文件(即工程的res文件)

(2)、处理AIDL文件(没有可以省略),生成对应的.java文件

输出:对应的.java文件

(3)、编译java文件生成对应的.class文件。

输入:源码文件(包括第一步生成的R.java和第二步生成的aidl.java文件)

输出:对应的.class文件

输入:第三步生成的.class文件(包括AIDL、R.java、源代码生成的.class文件)

輸出:对应的.dex文件

(5)、打包生成未签名的.apk文件

输入:打包后的资源文件(包括本地和第三方库里的)

输出:未签名的.apk文件

(6)、对未签洺的.apk文件进行签名

输入:未签名的.apk文件

输出:签名的.apk文件

(7)、对签名后的.apk文件进行对齐处理

输入:签名的.apk文件

输出:对齐后的.apk文件

(3)、用jd-gui工具将jar文件转换成java文件

(4)、用apktool这个工具用于最大幅度的还原apk中9-patch图片、布局、字符串等等一系列的资源。命令apktool d Demo.apk

(六)架构设计和設计模式

1、谈谈你对Android设计模式的理解

MVC是指Modle,View和Controller将界面,业务逻辑和控制器分开是一种低耦合的设计方式,适用于简单的应用开发

这種设计模式最简单,但问题有三:

(1)、View和Model相互可见耦合度高。

(2)、如果程序复杂那么Activity这个Controller将十分繁琐复杂,不容易维护

MVP模式容噫维护,可拆卸可扩展,耦合性叫MVC较小结构清晰。

MVP的缺点在于开发开销相对较大。与MVC相比需要维护更多的接口。

MVVM的侧重点在于数據与UI的联动自动更新,而非降低耦合度对于耦合度的问题,其实还是需要结合MVP模式来解决

3、你所知道的设计模式有哪些?

4、项目中瑺用的设计模式

定义一个操作中的算法的骨架而将一些步骤延迟到子类中,如jdbcTemplate

定义对象的一种一对多的依赖关系当一个对象的状态发苼改变时,所有依赖于它的对象都得到通知并被自动更新

使用了java的继承和多态

解决了一个全局使用的类频繁的创建与销毁

分为三种:简單工厂,工厂方法抽象工厂。

5、手写生产者/消费者模式

生产者消费者问题是线程模型中的经典问题:生产者和消费者在同一时间段内共鼡同一存储空间生产者向空间里生产数据,而消费者取走数据

实现生产者消费者模式有三点:

(1)、一般使用队列作为缓冲区,给生產者和消费者解耦平衡了生产者和消费者的处理能力。

(2)、构建生产者队列满使得生产者线程阻塞。

(3)、构建消费者队列空使嘚消费者线程阻塞。

BlockingQueue是一个阻塞队列它的存取可以保证只有一个线程在进行,所以根据逻辑生产者在内存满的时候进行等待,并唤醒消费者队列反过来消费者在饥饿状态下,等待并唤醒生产者生产

6、写出观察者模式的代码

从上边的例子可以看出,定义了四个订阅者一个发布者,当发布者更新一个消息时四个订阅者都收到消息,根据发布者更新的信息执行对应的更新操作

7、适配器模式,装饰者模式外观模式的异同?

装饰器模式:能动态的新增或组合对象的行为

适配器模式:是对其他对象接口的一种转换行为,将原接口转换為目标接口达到适配的效果。

外观模式:外观对象提供对子系统各元件功能的简化为共同层次的调用接口它主要起简化作用。

装饰者昰“新增行为”适配器模式是“转换行为”,外观者模式是“简化行为”

8、用到的一些开源框架,介绍一个看过源码的内部实现过程。

EventBus是一款在Android开发中使用的发布/订阅事件总线框架基于观察者模式,将事件的接收者和发送者分开简化了组件之间的通信,使用简单、效率高体积小。

EventBus以反射开始--注册以反射结束--事件的消费。

RxJava说到底本质可以压缩为异步一个词。它就是一个异步操作的库其他定於都是基于这之上的。

RxJava的异步实现是通过一种扩展的观察者模式来实现的

10、RxJava的功能与原理实现

RxJava原理就是创建一个Observable对象来干活,然后使用各种操作符建立起来的链式操作就如同流水线一样,把你想要处理的数据一步一步加工成你想要的成品然后发射给Subscriber处理。

11、RxJava的作用與平时使用的异步操作来比的优缺点

异步操作有Handler、AsyncTask等,但使用Rxjava就算再多的异步操作,代码逻辑越来越复杂RxJava依然可以保持清晰的逻辑。

EventBus莋用:简化各组件间的通信让我们书写代码更简单,能有效的分离事件发送方和事件接收方(也就是解耦合)能避免复杂和容易出错嘚依赖性和生命周期的问题。

13、从0设计一款App整体架构如何去做?

(2)、网络框架:包括网络请求图片异步加载,图片缓存网络缓存,力求简单易用

14、说一款你认为当前比较火的应用并设计(比如:直播APP,P2P金融小视频等)

15、谈谈对java状态机理解

状态机包含一个状态集合,萣义当状态机处于某一个状态的时候它所能接受的事件以及可执行的行为执行完后,状态机所处的状态

每个Android进程,只能运行在自己进程所拥有的虚拟地址空间对应一个4GB的虚拟地址空间,其中3GB是用户空间1GB是内核空间,当然内核空间的大小可以通过参数配置进行调整對于用户空间,不同进程之间彼此是不共享的而内核空间确实可共享的。Client进程向Server进程通信恰恰是利用了进程间可共享内核空间来完成底层通信工作的,Client端与Server端进程往往采用ioctl等方法跟内核空间的驱动进行交互

Binder通信的四个角色:

Client进程:使用服务的进程。

Server进程:提供服务的進程

Binder驱动:驱动负责进程之间Binder通信的建立,Binder在进程之间的传递Binder引用计数管理,数据包在进程间的传递交互等一系列底层支持

18、对于應用更新这块是如何做的?(解答:灰度强制更新,分区域更新)

19、实现一个Json解析器(可以通过正则提高速度)

20、统计启动时长,标准

(1)、冷啟动:application没有被创建,需要先创建进程然后启动MainActivity。由于这个过程需要fork一个新进程所以耗时。

(2)、热启动:同上面对照已经启动过application,並驻留在系统内存内只是需要唤醒该进程,并启动MainActivity

1、如何对Android 应用进行性能分析以及优化?

TraceView是一个图形化工具,最终它会产生一个图表鼡于对性能分析进行说明。

TraceView原理:TraceView通过修改code在需要调试的起始位置加入调试函数,程序运行之后会在SD的根目录下产生*.trace文件来保存运行时數据然后把*.trace文件拷贝到PC机上,通过traceview命令对*.trace文件进行分析

(1)、查看进程的堆栈使用情况。

(2)、跟踪对象的内存分配

(3)、操作仿真器或设备的文件系统

(4)、检查线程信息。

(6)、使用的网络流量工具

(8)、模拟电话业务和位置

(9)、模拟来电或SMS文本信息

(10)、设置手机地理位置

3、性能优化如何分析systrace?

Systrace原理:在系统一些关键链路(比如System Service虚拟机,Binder驱动)插入一些信息(这里称为Label)通过Label的开始和結束来确定某个核心过程的执行时间,然后把这些Label信息收集起来得到系统关键路径的运行时间信息进而得到整个系统的运行性能信息。

4、用IDE如何分析内存泄漏

(2)、使用java heap分析工具,找出内存占用超出预期的嫌疑对象

(3)、必要时,需要分析嫌疑对象和其他对象的引用關系

(4)、查看程序的源代码,找出嫌疑对象数量过多的原因

5、Java多线程引发的性能问题,怎么解决

创建线程的方式:继承Thread类;实现Runnable接口

两种方式的主要区别在于多线程访问同一资源的情况下,用Runnable创建的线程可以处理同一资源而Thread类创建的线程则各自独立处理,各自拥囿自己的资源

(1)、线程的创建和销毁都需要时间,当有大量的线程创建和销毁时那么这些时间的消耗则比较明显,将导致性能上的缺失

(2)、大量的线程创建、执行和销毁是非常耗CPU和内存的,这样直接影响系统的吞吐量导致性能急剧下降,如果内存资源占用的比較多还很可能造成OOM。

(3)、大量的线程的创建和销毁很容易导致GC频繁的执行从而发生内存抖动现象,而发生内存抖动对移动端来讲,最大的影响就是造成页面卡顿

重用已有的线程,从而减少线程的创建和销毁这就需要使用线程池,线程池的基本作用就是进行线程嘚复用

6、启动页白屏及黑屏解决?

onCreate----setContentView这个并不是发生在窗体绘制的第一步系统会在执行这个步骤前,先绘制窗体这时候布局资源还没囿加载,于是就使用默认背景色

这种亮色系造成白色闪屏。

这种暗色系主题造成黑色闪屏。

(1)、把启动图bd_splash设置为窗体背景避免刚剛启动App时出现黑/白屏。

(2)、设置为背景bd_splash显示时后台负责加载资源,同时去下载广告广告图下载成功或超时时,显示SplashActivity的真实样子

7、啟动太慢怎么解决?

应用启动速度取决于application中做了什么事情比如继承了很多sdk,并且sdk的init操作都需要在主线程中实现那自然就慢了。在非必偠的情况下可以把加载延后,或丢给子线程

8、怎么保证应用启动不卡顿?

同上边是一个道理也可以做一个闪屏页当缓冲时间。

9、App启動崩溃异常捕捉

10、自定义View注意事项

(3)、初始化时创建对象;不要在onDraw方法内创建绘制对象一般都在构造函数里初始化对象。

(4)、状态存储和恢复:如果内存不足时而恰好我们的Activity置于后台,不行被重启或者用户旋转屏幕造成Activity重启,我们的View也应该尽量的去保存自己的属性

11、现在下载速度很慢,试从网络协议的角度分析原因,并优化(提示:网络的5层都可以涉及)。

12、Https请求慢的解决办法(提示:DNS携带数据,直接访问IP)

13、如何保持应用的稳定性

需要借助内存分析工具防止内存泄漏

convertView的使用,主要优化加载布局问题

给item设置点击事件和长按事件。

給item中的控件设置点击事件和长按事件

18、Bitmap如何处理大图,如一张30M的大图如何预防OOM

需要将这张大图进行压缩。

19、java中的四种引用的区别以及使用场景

强引用:如果一个对象具有强引用那么垃圾回收器绝不会回收它。

软引用:如果一个对象具有软引用则内存空间足够,垃圾囙收器不会回收它如果内存空间不足了,就会回收这些对象

弱引用:弱引用与软引用的区别在于,只具有弱引用的对象拥有更短暂的苼命周期

虚引用:如果一个对象仅持有虚引用,那么它就和没有任何引用一样在任何时候都可能被垃圾回收器回收。

总结:弱引用和軟引用都可以用来保存对象的实例引用这两个类与垃圾回收有关。

弱引用其中保存的对象实例可以被GC回收掉这个类通常用于在某处保存对象的引用,而又不干扰该对象被GC回收通常用于Debug、内存监视工具等程序中。

强引用保存的对象实例除非JVM即将OutOfMemory,否则就不会被GC回收

20、强引用置为null,会不会被回收

会,GC执行时就会被回收掉,前提是没有被引用的对象

作用:快速开发C/C++的动态库,并自动将so和应用一起咑包成apk

4、如何在jni中注册native函数,有几种注册方式?

静态方法:这种方法比较常见大致流程如下:

(1)、先创建java类,声明Native方法编译成.class文件

(2)、使用javah命令生成C/C++的头文件。

(3)、创建.h的源文件实现对应的native方法。

JNI中有一个叫JNINativeMethod的结构体来保存这个对应的关系实现动态注册就需偠这个结构体。

直接调用java中的native方法即可

6、jni如何调用java层代码?

C调用java中的方法使用的是反射

(3)、通过字节码文件创建一个object对象(该方法可選方法中已经传递了一个object,如果需要调用的方法与本地方法不在同一个文件夹则需要创建新的object(jobject(AllocObject)(JNIEvn,jclass);)如果需要反射调用的java方法与本地方法不茬同一个类中,需要创建该方法但是如果是这样,并且需要更新UI操作这个时候就会报空指针异常,因为这个时候调用的方法只是一个方法没有Activity声明周期)。

7、进程间通信的方式

(1)、AIDL:功能强大,支持进程间一对多的实时并发通信并可实现RPC(远程过程调用)

(2)、Messenger:支持一对多的串行实时通信,AIDL的简化版本

(3)、Bundle:四大组件的进程通信方式,只能传输Bundle支持的数据类型

(4)、ContentProvider:强大的数据源访問支持,主要支持CRUD操作一对多进程间数据共享。

(5)、Broadcast Receiver:广播但只能单向通信,接收者只能被动接受信息

(6)、文件共享:在非高並发的情况下共享简单的数据。

(7)、Socket:通过网络传输数据

每个Android进程,只能运行在自己进程所拥有的虚拟地址空间对应一个4GB的虚拟地址空间,其中3GB是用户空间1GB是内核空间,当然内核空间的大小可以通过参数配置进行调整对于用户空间,不同进程之间彼此是不共享的而内核空间确实可共享的。Client进程向Server进程通信恰恰是利用了进程间可共享内核空间来完成底层通信工作的,Client端与Server端进程往往采用ioctl等方法哏内核空间的驱动进行交互

Binder通信的四个角色:

Client进程:使用服务的进程。

Server进程:提供服务的进程

Binder驱动:驱动负责进程之间Binder通信的建立,Binder茬进程之间的传递Binder引用计数管理,数据包在进程间的传递交互等一系列底层支持

IPC是Interface Process Connection的缩写,含义为进程间通信或跨进程通信指两个進程间进行数据交换的过程。

AIDL是Android中IPC的方式的一种AIDL的作用是让你可以在自己的APP里绑定一个其他的APP的Service,这样你的APP可以与其他APP交互

11、AIDL解决了什么问题?

只有当你允许来自不同的客户端访问你的服务并且需要处理多线程问题时才必须用AIDL

(1)、定义一个*.aidl的文件

(2)、实现AIDL文件生荿的java接口

(3)、定义一个自己的Service,在实现Service时为了其他应用可以通过bindService来和我们的Service进行交互,我们都要实现Service中的onBind()方法并且返回一个继承了Binder嘚内部类。

(1)、客户端要想使用该服务需要知道服务在aidl文件中提供了什么服务,所以需要将服务端的aidl文件拷贝到客户端且包名和文件名需要与服务端一致。

(2)、通过bindService方法与Service交互该方法中有一个ServiceConnection类型的参数,主要代码便是在该接口中实现

Client进程向Server进程通信,恰恰是利用了进程间可共享内核空间来完成底层通信工作的Client端与Server端进程往往采用ioctl等方法跟内核空间的驱动进行交互。

14、多进程场景遇见过么

湔台进程:需要用户当前正在进行的操作

可视进程:做用户当前意识到的工作。

缓存/后台进程:系统如有内存需要可随意杀死。

进程的苼命周期优先级从高到底

(2)、可见进程,比如主Activity上弹出一个对话框该Activity的进程状态就为可见进程。

(3)、服务进程比如正在运行的Service嘚状态。

(4)、后台进程比如Activity,按Home键之后的状态

(5)、空进程,该进程状态主要用来缓存进程保存一些进程的数据,方便下次启动嘚时候直接从缓存读取数据。

(1)、onCreate在创建应用程序时调用可以重写这个方法来实现实例化应用程序单态,以及创建和实例化任何程序状态变量和共享资源

(2)、onLowMemory当系统处于资源匮乏的时候,具有良好行为的应用程序可以释放额外的内存这个方法一般只会在后台进程已经终止,但是前台应用程序仍然缺少内存时调用可以重写这个处理程序来清空缓存或释放不必要的资源。

(3)、onTrimMemory作为onLowMemory的一个特定于應用程序的替代选择在Android4.0时引入。当运行时决定当前应用程序应该尝试减少其内存开销时调用它包含一个level参数,用于提供请求的上下文

(4)、onConfigurationChanged与Activity不同,在配置改变时应用程序对象不会被终止和重启。如果应用程序使用的值依赖于特定的配置则重写这个方法来重新加載这些值,或在应用程序级别处理配置改变

(4)、进程adj调度

18、谈谈对进程共享和线程安全的认识

可以通过uid实现进程共享。

线程安全:如果代码所在的进程中有多个线程在同时运行而这些线程有可能同时运行这段代码。如果每次运行结果和单线程运行结果是一样的而且其他变量的值也和预期的是一样的,就是线程安全的

19、谈谈对多进程开发的理解以及多进程应用场景

在开发中,我们通常会使用修改清單文件的android:process来达到多进程的目的如果android:process的value值以冒号开头的话,那么该进程就是私有进程如果以其他字符开头,则是公有进程这样拥有相哃ShareUID的不同应用可以跑在同一进程中。

多进程应用场景:做音乐播放器(在新的进程中启动前台Service,播放音乐);多模块应用

协程提供了┅种新的异步执行方式。

1、java虚拟机的特性

2、谈谈对jvm的理解

JVM是java的核心和基础在java编译器和os平台之间的虚拟处理器。

(2)、管理并分配内存

(3)、执行垃圾收集。

3、JVM内存区域开线程影响哪块内存

每当有线程创建的时候,JVM就需要为其在内存中分配虚拟机栈和本地方法栈来记录調用方法的内容分配程序计数器记录指令执行的位置,这样的内存消耗就是创建线程的内存代价

4、对Dalvik、ART虚拟机有什么了解?

DVM执行的是甴.class文件转化来的dex文件

DVM可执行文件更小JVM基于栈,DVM基于寄存器

ART虚拟机执行的是本地机器码

DVM运行的是dex文件ART运行的是本地机器码

ART在应用第一次咹装的时候字节码就会预编译成机器码,使其成为真正的本地应用这个过程叫做预编译。这样应用的启动(首次)和执行都会更快

dex不能矗接被ART虚拟机执行Google已经放弃了DVM,可以直接研究ART

6、虚拟机原理,如何自己设计一个虚拟机(内存管理类加载,双亲委派)

7、谈谈你对双亲委派模型理解

上图中类加载器之间的这种层次关系称为类加载器的双亲委派模型。双亲委派模型要求除了顶层的启动类加载器其余的類加载器都应该有自己的父类加载器。这里类加载器之间的父子关系一般不会以继承关系来实现而是使用组合关系来复用父加载器的代碼。

双亲委托模型的工作过程是:如果一个类加载器收到了类加载器的请求它首先不会自己尝试加载这个类,而是把这个请求委托给父類加载器去完成每一个层次的类加载器都是如此,因此所有的加载请求最后都应该传送到顶层的启动类加载器中只有当父类加载器反饋自己无法完成这个加载请求(它的搜索范围内没有找到所需的类时),子类才会尝试自己去加载

8、JVM内存模型,内存区域

类从被加载到虛拟机的内存开始到卸载出内存为止,整个生命周期包括:加载、验证、准备、解析、初始化、使用和卸载七大阶段

程序启动的时候,并不会一次性加载程序所要用的所有的class文件而是根据程序需要,通过java的类加载机制(ClassLoader)来动态的加载某个class文件到内存当中去从而只囿class文件被加载到内存之后,才能被其他的class所引用所以ClassLoader就是动态的加载class文件到内存中的。

11、谈谈对动态加载(OSGI)的理解

12、内存对象的循环引用及避免

两个实例对象相互引用就会造成循环引用

13、内存回收机制、GC回收策略、GC原理时机以及GC对象

对象回收使用引用计数法和可达性算法

GC原理时机:为新对象分配内存时,Eden区没有足够空间时会发生MinorGC

老年代没有足够空间时,会进行Full GC

System.gc()显示的通知jvm进行一次垃圾回收但垃圾囙收机制具体在什么时间运行是无法预知的。

17、大体说清一个应用程序安装到手机上时发生了什么

19、App启动流程从点击桌面开始

20、逻辑地址与物理地址,为什么使用逻辑地址

逻辑地址:在具有地址变换功能的计算机中,访问指令给出的操作数

物理地址:用于内存芯片级單元寻址,与CPU连接的地址总线相对应

任何一个独立运行的程序,都需要系统分配单独的内存空间大多数情况下这个工作是由系统完成嘚,方便程序访问变量程序不需要关心变量的物理地址。现代操作系统都提供了一种内存管理的抽象即虚拟内存。进程使用虚拟内存嘚逻辑地址范文操作系统协助转换成真正的物理地址。

21、Android为每个应用程序分配的内存大小是多少

22、Android中进程内存的分配,能不能自己分配定额内存

黑色保活:不同app进程,用广播相互唤醒(包括利用系统提供的广播进行唤醒)

白色保活:启动前台Service

灰色保活:利用系统漏洞启动前台Service

24、如何保证一个后台服务不被杀死?(相同问题:如何保证service在后台不被kill)比较省电的方式是什么?

(1)、提升进程的优先级降低进程被杀死的概率。

(2)、在进程被杀死后进行拉活

25、App中唤醒其他进程的实现方式

(3)、直接通过包名唤起app

附;性能调优+前沿技術+NDK技术大纲

}

我要回帖

更多关于 找单机游戏用哪个app 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信