2022最新Android⾯试题总结(三)
Q:webSocket和HTTP,以及Socket的区别
不同点
HTTP是单向数据流,客户端向服务端发送请求,服务端响应并返回数据;Websocket连接后可以实现客户端和服务端双向数据传递。
WebSocket是需要浏览器和服务器握⼿进⾏建⽴连接的。⽽http是浏览器发起向服务器的连接,服务器预先并不知道这个连接
由于是新的协议,HTTP的url使⽤"http//"或"https//"开头;WebSocke通过https协议开始升级⽽来的,那么⼀般是wss://开头,如果是http协议开始升级⽽来的,那么⼀般是ws://开头
相同点
都需要建⽴TCP连接
都是属于七层协议中的应⽤层协议
Socket其实并不是⼀个协议,⽽是为了⽅便使⽤TCP或UDP⽽抽象出来的⼀层,是位于应⽤层和传输控制层之间的⼀组接⼝。
Socket是传输控制层接⼝,WebSocket是应⽤层协议。
WebSocket在建⽴握⼿时,数据是通过HTTP传输的。但是建⽴之后,在真正传输时候是不需要HTTP协议的。
WebSocket连接的过程是:
左腹下方隐痛什么原因
⾸先,客户端发起http请求,经过3次握⼿后,建⽴起TCP连接;http请求⾥存放WebSocket⽀持的版本号等信息,如:Upgrade、Connection、WebSocket-Version等;
然后,服务器收到客户端的握⼿请求后,同样采⽤HTTP协议回馈数据;
最后,客户端收到连接成功的消息后,开始借助于TCP传输信道进⾏全双⼯通信。
Q:加载⼀张超级⼤的图⽚,导致OOM的处理⽅式
(1)将图⽚装化成bigmap,设置Config preferredConfig = Config.RGB_565;不⽀持透明度,如果需要透明度,就替换成
ARGB_8888,但是内存占⽤会增加⼀倍.具体可以参考源码的解释
(2)可以将视频进⾏质量压缩(本地图⽚转化为缩略图加载等)
考上大学祝贺词
(3)可以修改原图⽚的宽⾼为屏幕分辨率或view的宽⾼
a.得到图⽚的宽和⾼
b.得到屏幕的宽和⾼(因为整个屏幕的像素都加载进内存,也不会造成内存溢出)
怎样和孩子沟通c.得到 图⽚的宽和屏幕宽(或控件宽)的⽐值,图⽚⾼和屏幕⾼(或控件⾼)的⽐值,选择⽐值⼤的那个
d.设置 Option的inSampleSize 属性来缩⼩图⽚
imageview.tImageBitmap(decodeSampledBitmapFromResource(getResources(),name[i], 100, 100));
Q:项⽬中如何做性能优化的?
举例说明项⽬注意了哪些⽅⾯的性能优化,如布局优化、绘制优化、内存泄漏优化、 响应速度优化、列表优化、Bitmap 优化、 线程优化......
性能优化⼀
性能优化⼆
Q:了解哪些性能优化的⼯具?
性能优化⼯具
思路:做项⽬时是否使⽤过的系统⾃带的性能优化⼯具?公司是否有⾃⼰的性能优化⼯具?实现原理怎样的?
LeakCanary⼯具
Q:布局上如何优化?
上课睡觉
布局优化的核⼼就是尽量减少布局⽂件的层级,常见的⽅式有:
多嵌套情况下可使⽤RelativeLayout减少嵌套。
布局层级相同的情况下使⽤LinearLayout,它⽐RelativeLayout更⾼效。
使⽤<include>标签重⽤布局、<merge>标签减少层级、<ViewStub>标签懒加载(适合在某些条件显⽰的布局,如:⽹络错误,数据加载失败等)。
Q:内存泄漏是什么?为什么会发⽣?常见哪些内存泄漏的例⼦?都是怎么解决的?
内存泄漏(Memory Leak)是指程序在申请内存后,⽆法释放已申请的内存空间。简单地说,发⽣内存泄漏是由于长周期对象持有对短周期对象的引⽤,使得短周期对象不能被及时回收。常见的⼏个例⼦和解决办法:
单例模式导致的内存泄漏:单例传⼊参数this来⾃Activity,使得持有对Activity的引⽤。
儿童慢性咽炎解决办法:传参ApplicationContext()
Handler导致的内存泄漏:Message持有对Handler的引⽤,⽽⾮静态内部类的Handler⼜隐式持有对外部类Activity的引⽤,使得引⽤关系会保持⾄消息得到处理,从⽽阻⽌了Activity的回收。
染衣服解决办法:使⽤静态内部类+WeakReference弱引⽤;当外部类结束⽣命周期时清空消息队列。
线程导致的内存泄漏:AsyncTask/Runnable以匿名内部类的⽅式存在,会隐式持有对所在Activity的引⽤。
解决办法:将AsyncTask和Runnable设为静态内部类或独⽴出来;在线程内部采⽤弱引⽤保存Context引⽤
资源未关闭导致的内存泄漏:未及时注销资源导致内存泄漏,如BraodcastReceiver、File、Cursor、Stream、Bitmap等。
解决办法:在Activity销毁的时候要及时关闭或者注销。
BraodcastReceiver:调⽤unregisterReceiver()注销;
Cursor,Stream、File:调⽤clo()关闭;
动画:在Destroy()中调⽤Animator.cancel()停⽌动画
引申:谈谈项⽬中是如何注意内存泄漏的问题
内存泄漏和内存溢出的区别
内存泄漏(Memory Leak)是指程序在申请内存后,⽆法释放已申请的内存空间。是造成应⽤程序OOM的主要原因之⼀。
内存溢出(out of memory)是指程序在申请内存时,没有⾜够的内存空间供其使⽤。
Q:什么情况会导致内存溢出?
内存泄漏是导致内存溢出的主要原因;直接加载⼤图⽚也易造成内存溢出
引申:谈谈如何避免内存溢出(如何避免内存泄漏、避免直接加载⼤图⽚)
开源框架(略)
Q:使⽤那些版本控制⼯具?Git和SVN的区别?`
参考回答:Git和SVN的区别有以下⼏点:
Git是分布式的,⽽SVN是集中式的(核⼼区别)
Git按元数据⽅式存储内容,⽽SVN按⽂件存储内容
古代电视剧
在Git上每个⼯作成员可以任意在⾃⼰的本地版本库开启⽆限个分⽀且互不影响,⽽对于SVN分⽀是⼀个完整的⽬录且这个⽬录拥有完整的实际⽂件
Git没有⼀个全局的版本号,⽽SVN有
Git 的内容完整性要优于SVN
在Git中的绝⼤多数操作都只需要访问本地⽂件和资源,不必联⽹就可以看到所有的历史版本记录,⽽SVN 却需要联⽹引申:谈谈两种版本控制⼯具的优缺点:SVN与GIT的优缺点对⽐
Q:了解Git⼯具吗?⽤过哪些命令?解决冲突时git merge和git reba的区别?`
通过图记忆Git常⽤命令,详见Git、GitHub、Stash
参考回答: 常⽤命令见图,源⾃⼀篇⽂章,教你学会Git
合并⽤到的命令git merge与git reba的区别是,git merge会⽣成⼀个新的节点,并将之前的提交分开显⽰;git reba操作不会⽣成新的节点,⽽是将两个分⽀
image.png
融合成⼀个线性的提交。
Q:内存泄漏的场景,Handler内存泄漏的原因以及解决⽅法
原因:使⽤Handler发送⼀条延时消息,然后关闭Activity,在Activity被关闭之后,Message将在消息队列中存在10分钟才能被执⾏到,这个Message持有⼀个对Handler的引⽤,Handler⼜持有⼀个对当前Activity的引⽤,这些引⽤会在Message被执⾏之前⼀直保持,这样当前Activity就不会被垃圾回收机制回收,从⽽导致内存泄漏。
解决⽅法
1.定义⼀个静态的Handler,这样Acitivity就不会被泄漏了,同时让Handler持有⼀个对Activity的弱引⽤,这样就可以
happy的在Handler中调⽤Activity中的资源或者⽅法了。
Q:⼯⼚模式的种类以及区别
简单⼯⼚模式:简单⼯⼚模式不是23种⾥的⼀种,简⽽⾔之,就是有⼀个专门⽣产某个产品的类。
⽐如下图中的⿏标⼯⼚,专业⽣产⿏标,给参数0,⽣产戴尔⿏标,给参数1,⽣产惠普⿏标。
⼯⼚模式:⼯⼚模式也就是⿏标⼯⼚是个⽗类,有⽣产⿏标这个接⼝。
戴尔⿏标⼯⼚,惠普⿏标⼯⼚继承它,可以分别⽣产戴尔⿏标,惠普⿏标。
⽣产哪种⿏标不再由参数决定,⽽是创建⿏标⼯⼚时,由戴尔⿏标⼯⼚创建。
后续直接调⽤⿏标⼯⼚.⽣产⿏标()即可
抽象⼯⼚模式:抽象⼯⼚模式也就是不仅⽣产⿏标,同时⽣产键盘。 也就是PC⼚商是个⽗类,有⽣产⿏标,⽣产键盘两个接⼝。 戴尔⼯⼚,惠普⼯⼚继承它,可以分别⽣产戴尔⿏标+戴尔键盘,和惠普⿏标+惠普键盘。 创建⼯⼚时,由戴尔⼯⼚创建。 后续⼯⼚.⽣产⿏标()则⽣产戴尔⿏标,⼯⼚.⽣产键盘()则⽣产戴尔键盘。
Q:Android第三⽅框架的源码实现原理
Q:数据的存储⽅式与其的应⽤场景,ContentProvider的底层实现,如何保证多进程读写安全
作为⼀个完整的应⽤程序,数据存储操作是必不可少的。因此,Android系统⼀共提供了四种数据存储⽅式。分别是:SharePreference、⽂件存储、SQLite、 ContentProvider。对这⼏种⽅式的不同和应⽤场景整理如下。
第⼀种: 使⽤SharedPreferences存储数据
适⽤范围:保存少量的数据,且这些数据的格式⾮常简单:字符串型、基本类型的值。⽐如应⽤程序的各种配置信息(如是否打开⾳效、是否使⽤震动效果、⼩游戏的玩家积分等),解锁⼝ 令密码等
核⼼原理:保存基于XML⽂件存储的key-value键值对数据,通常⽤来存储⼀些简单的配置信息。通过DDMS的File Explorer⾯板,展开⽂件浏览树,很明显SharedPreferences数据总是存储在/data/data//shared_prefs⽬录下。
SharedPreferences对象本⾝只能获取数据⽽不⽀持存储和修改,存储修改是通过
SharedPreferences对象与SQLite数据库相⽐,免去了创建数据库,创建表,写SQL语句等诸多操作,相对⽽⾔更加⽅便,简洁。但是SharedPreferences也有其⾃⾝缺陷,⽐如其职能存储boolean,int,float,long和String五种简单的数据类型,⽐如其⽆法进⾏条件查询等。所以不论SharedPreferen
ces的数据存储操作是如何简单,它也只能是存储⽅式的⼀种补充,⽽⽆法完全替代如SQLite数据库这样的其他数据存储⽅式。
第⼆种: ⽂件存储数据
可以在设备本⾝的存储设备或者外接的存储设备中创建⽤于保存数据的⽂件。同样在默认的状态下,⽂件是不能在不同的程序间共享。
写⽂件:调⽤Context.openFileOutput()⽅法根据指定的路径和⽂件名来创建⽂件,这个⽅法会返回⼀个
FileOutputStream对象。
兵役体检 读取⽂件:调⽤Context.openFileInput()⽅法通过制定的路径和⽂件名来返回⼀个标准的Java FileInputStream对象。
第三种:SQLite存储数据
SQLite Databa数据库。Android对数据库的⽀持很好,它本⾝集成了SQLite数据库,每个应⽤都可以⽅便的使⽤它,或者更确切的说,Android完全依赖于SQLite数据库,它所有的系统数据和⽤到的
结构化数据都存储在数据库中。 它具有以下优点: a. 效率出众,这是⽆可否认的 b. ⼗分适合存储结构化数据 c. ⽅便在不同的Activity,甚⾄不同的应⽤之间传递数据。
第四种:ContentProvider
Android系统中能实现所有应⽤程序共享的⼀种数据存储⽅式,由于数据通常在各应⽤间的是互相私密的,所以此存储⽅式较少使⽤,但是其⼜是必不可少的⼀种存储⽅式。例如⾳频,视频,图⽚和通讯录,⼀般都可以采⽤此种⽅式进⾏