写点什么

四年 Android 面试遇到的问题整理,Android 培训那里好

用户头像
Android架构
关注
发布于: 刚刚

}});}}打印截图:


3.RecyclerView 相比 ListView 有哪些优势


解析:


首先需要解释下 RecyclerView 的这个名字了,从它类名上看,RecyclerView 代表的意义是,我只管 Recycler View,也就是说 RecyclerView 只管回收与复用 View,其他的你可以


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


自己去设置。可以看出其高度的解耦,给予你充分的定制自由(所以你才可以轻松的通过这个控件实现 ListView,GirdView,瀑布流等效果)


其次 RecyclerView 提供了添加、删除 item 的动画 效果,而且可以自定义


RecyclerView 相比 ListView 优势在于可以轻松实现:


ListView 的功能 GridView 的功能横向 ListView 的功能横向 ScrollView 的功能瀑布流效果便于添加 Item 增加和移除动画


不过一个挺郁闷的地方就是,系统没有提供 ClickListener 和 LongClickListener。?不过我们也可以自己去添加,只是会多了些代码而已。?实现的方式比较多,你可以通过 mRecyclerView.addOnItemTouchListener 去监听然后去判断手势,?


当然你也可以通过 adapter 中自己去提供回调


参考


http://jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/1118/2004.html


http://blog.csdn.net/lmj623565791/article/details/45059587


http://www.360doc.com/content/16/0808/14/9200790_581676933.shtml


4.谈一谈 Proguard 混淆技术


答案:


Proguard 技术有如下功能:


压缩 --检查并移除代码中无用的类优化--对字节码的优化,移除无用的字节码混淆--混淆定义的名称,避免反编译


预监测--在 java 平台对处理后的代码再次进行检测


代码混淆只在上线时才会用到,debug 模式下会关闭,是一种可选的技术。


那么为什么要使用代码混淆呢?


因为 Java 是一种跨平台的解释性开发语言,而 java 的源代码会被编译成字节码文件,存储在.class 文件中,由于跨平台的需要,java 的字节码中包含了很多源代码信息,诸如变量名、方法名等等。并且通过这些名称来访问变量和方法,这些变量很多是无意义的,但是又很容易反编译成 java 源代码,为了防止这种现象,我们就需要通过 proguard 来对 java 的字节码进行混淆,混淆就是对发布的程序进行重新组织和处理,使得处理后的代码与处理前的代码有相同的功能,和不同的代码展示,即使被反编译也很难读懂代码的含义,哪些混淆过的代码仍能按照之前的逻辑执行得到一样的结果。


但是,某些 java 类是不能被混淆的,比如实现了序列化的 java 类是不能被混淆的,否则反序列化时会出问题。


下面这类代码混淆的时候要注意保留,不能混淆。Android 系统组件,系统组件有固定的方法被系统调用。被 Android Resource 文件引用到的。名字已经固定,也不能混淆,比如自定义的 View 。Android Parcelable ,需要使用 android 序列化的。其他 Anroid 官方建议 不混淆的,如 android.app.backup.BackupAgentHelperandroid.preference.Preferencecom.android.vending.licensing.ILicensingServiceJava 序列化方法,系统序列化需要固定的方法。枚举 ,系统需要处理枚举的固定方法。本地方法,不能修改本地方法名 annotations 注释数据库驱动有些 resource 文件


用到反射的地方


5.ANR 出现的场景及解决方案


在 Android 中,应用的响应性被活动管理器(Activity Manager)和窗口管理器(Window Manager)这两个系统服务所监视。当用户触发了输入事件(如键盘输入,点击按钮等),如果应用 5 秒内没有响应用户的输入事件,那么,Android 会认为该应用无响应,便弹出 ANR 对话框。而弹出 ANR 异常,也主要是为了提升用户体验。


解决方案是对于耗时的操作,比如访问网络、访问数据库等操作,需要开辟子线程,在子线程处理耗时的操作,主线程主要实现 UI 的操作


6.HTTPS 中 SSL 证书认证的过程


7.简述 Android 的 Activity 的内部机制


8.对 Android Framework 层的某一个模块(或者 System App)做简要介绍


9.Android Handler 的机制和原理


主线程使用 Handler 的过程


首先在主线程创建一个 Handler 对象 ,并重写 handleMessage()方法。然后当在子线程中需要进行更新 UI 的操作,我们就创建一个 Message 对象,并通过 handler 发送这条消息出去。之后这条消息被加入到 MessageQueue 队列中等待被处理,通过 Looper 对象会一直尝试从 Message Queue 中取出待处理的消息,最后分发会 Handler 的 handler Message()方法中。


参考?http://blog.csdn.net/u012827296/article/details/51236614


10.线程间通信和进程间通信有什么不同,Android 开发过程中是怎么实现的


https://www.cnblogs.com/yangtao1995/p/6079067.html


11.简述项目中对于内存优化的几个细节点


答案:


1.当查询完数据库之后,及时关闭 Cursor 对象。2.记得在 Activity 的 onPause 方法中调用 unregisterReceiver()方法,反注册广播 3.避免 Content 内存泄漏,比如在 4.0.1 之前的版本上不要讲 Drawer 对象置为 static。当一个 Drawable 绑定到了 View 上,实际上这个 View 对象就会成为这个 Drawable 的一个 callback 成员变量,上面的例子中静态的 sBackground 持有 TextView 对象 lable 的引用,而 lable 只有 Activity 的引用,而 Activity 会持有其他更多对象的引用。sBackground 生命周期要长于 Activity。当屏幕旋转时,Activity 无法被销毁,这样就产生了内存泄露问题。4.尽量不要在 Activity 中使用非静态内部类,因为非静态内部类会隐式持有外部类实例的引用,当非静态内部类的引用的声明周期长于 Activity 的声明周期时,会导致 Activity 无法被 GC 正常回收掉。5.谨慎使用线程 Thread!!这条是很多人会犯的错误: Java 中的 Thread 有一个特点就是她们都是直接被 GC Root 所引用,也就是说 Dalvik 虚拟机对所有被激活状态的线程都是持有强引用,导致 GC 永远都无法回收掉这些线程对象,除非线程被手动停止并置为 null 或者用户直接 kill 进程操作。所以当使用线程时,一定要考虑在 Activity 退出时,及时将线程也停止并释放掉 6.使用 Handler 时,要么是放在单独的类文件中,要么就是使用静态内部类。因为静态的内部类不会持有外部类的引用,所以不会导致外部类实例的内存泄露


12.简述 Android 的视图层级优化,简述自定义 View 或者自定义 ViewGroup 的步骤


个人的理解是,Android 视图渲染必须经过 measure、layout、draw 三个步骤,measure 过程是在一个树形结构中不断遍历的,如果 UI 层级嵌套很深,必将花费大量的时间,所以应该尽量减少层级嵌套,保证树的结构扁平,并移除不需要渲染的 views


自定义 view 步骤:


Android 自定义 View 的一般步骤


13.选取一个常用的第三方开源库,简述其接入步骤


Volley 教程?http://blog.csdn.net/jdfkldjlkjdl/article/details/79074259


14.TCP 和 UPD 的区别以及使用场景


TCP 与 UDP 基本区别 1.基于连接与无连接 2.TCP 要求系统资源较多,UDP 较少;?3.UDP 程序结构较简单?4.流模式(TCP)与数据报模式(UDP);?5.TCP 保证数据正确性,UDP 可能丢包?6.TCP 保证数据顺序,UDP 不保证?


UDP 应用场景:1.面向数据报方式 2.网络数据大多为短消息?3.拥有大量 Client4.对数据安全性无特殊要求 5.网络负担非常重,但对响应速度要求高


15.简述一个设计模式的概念,并简要谈谈 framework 层哪些地方用到了什么设计模式


单例模式:单例模式是一种对象创建模式,它用于产生一个对象的具体实例,它可以确保系统中一个类只产生一个实例。


适配器模式:将一个接口转换成客户希望的另一个接口,适配器模式使接口不兼容的那些类可以一起工作,其别名为包装器(Wrapper)


装饰模式:动态地给一个对象增加一些额外的职责,就增加对象功能来说,装饰模式比生成子类实现更为灵活。装饰模式是一种对象结构型模式。


使用场景:1.在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。2.当不能采用继承的方式对系统进行扩展或者采用继承不利于系统扩展和维护时可以使用装饰模式。优点:1.对于扩展一个对象的功能,装饰模式比继承更加灵活,不会导致类的个数急剧增加。2.可以通过一种动态地方式来扩展一个对象的功能。3.可以对一个对象进行多次装饰,通过使用不同的具体装饰类以及这些装饰类的排列组合。实际运用:Android 中 Context 类的实现


外观模式:主要目的在于让外部减少与子系统内部多个模块的交互,从而让外部能够更简单得使用子系统。它负责把客户端的请求转发给子系统内部的各个模块进行处理。


使用场景:1.当你要为一个复杂的子系统提供一个简单的接口时 2.客户程序与抽象类的实现部分之前存在着很大的依赖性 3.当你需要构建一个层次结构的子系统时


组合模式:将对象以树形结构组织起来,以达成”部分--整体”的层次结构,使得客户端对单个对象和组合对象的使用具有一致性。


使用场景:1.需要表示一个对象整体或部分 层次 2.让客户端能够忽略不同对象层次的变化优点:1.高层模块调用简单 2.节点自由增加


模板方法:是通过一个算法骨架,而将算法中的步骤延迟到子类,这样子类就可以复写这些步骤的实现来实现特定的算法。它的使用场景:


1.多个子类有公有的方法,并且逻辑基本相同 2.重要、复杂的算法,可以把核心算法设计为模板方法


3.重构时,模板方法模式是一个经常使用的模式


观察者模式:定义对象之间一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。其使用场景:


1.一个抽象模型有两个方面,其中一个方面依赖于另一个方面 2.一个对象的改变将导致一个或多个其他对象也 发生改变


3.需要在 系统中创建一个 触发链


具体应用:


比如回调模式中,实现了抽象类/接口的实例实现了父类提供的抽象方法后,将该方法交还给父类来处理 Listview 中的 notifyDataSetChanged


RxJava 中的观察者模式


责任链模式:是一个请求有多个对象来处理,这些对象是一条链,但具体由哪个对象来处理,根据条件判断来确定,如果不能处理会传递给该链条中的下一个对象,直到有对象处理它为止。


使用场景:1.有多个对象可以处理同一个请求,具体哪个对象处理该请求待运行时再确定 2.在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。


实际运用:Try...catch 语句 OrderedBroadcastMotionEvent:actionDwon actionMove actionUp 事件分发机制三个重要方法:dispatchTouchEvent. onInterceptTouchEvent. onTouchEvent


策略模式:定义一系列的算法,把它们一个个封装起来,并且使他们可互相替换。本模式使得算法可独立于使用它的客户而变化。策略模式的使用场景:一个类定义了多种行为,并且这些行为在这个类的方法中以多个条件语句的形式出现,那么可以使用策略模式避免在类中使用大量的条件语句。


使用场景:一个类定义了多种行为,并且这些行为在这个类的方法中以多个条件语句的形式出现,那么可以使用策略模式避免在类中使用大量的条件语句。优点:1.上下文 Context 和具体策略 ConcreateStrategy 是松耦合关系 2.策略模式满足 开-闭原则具体应用:HttpStack


Volley 框架


16.字节流和字符流的区别


字节流操作的基本单元为字节;字符流操作的基本单元为 Unicode 码元(2 个字节)。字节流默认不使用缓冲区;字符流使用缓冲区。


字节流通常用于处理二进制数据,实际上它可以处理任意类型的数据,但它不支持直接写入或读取 Unicode 码元;字符流通常处理文本数据,它支持写入及读取 Unicode 码元。


参考?理解 Java 中字符流与字节流的区别


17.View 的绘制流程,是先测量父 View 还是先测量子 View


View 和 ViewGroup 的基本绘制流程


18.OOM 异常是否可以被 try...catch 捕获(或者可否用 try-catch 捕获 Out Of Memory Error 以避免其发生?)


只有在一种情况下,这样做是可行的:在 try 语句中声明了很大的对象,导致 OOM,并且可以确认 OOM 是由 try 语句中的对象声明导致的,那么在 catch 语句中,可以释放掉这些对象,解决 OOM 的问题,继续执行剩余语句。


但是这通常不是合适的做法。Java 中管理内存除了显式地 catch OOM 之外还有更多有效的方法:比如 SoftReference, WeakReference, 硬盘缓存等。在 JVM 用光内存之前,会多次触发 GC,这些 GC 会降低程序运行的效率。如果 OOM 的原因不是 try 语句中的对象(比如内存泄漏),那么在 catch 语句中会继续抛出 OOM


19.WeakReference 和 SoftReference 的区别


Java 的 StrongReference, SoftReference, WeakReference, PhantomReference 的区别


20.请计算一张 100 像素*100 像素的图片所占用内存


http://blog.csdn.net/u010652002/article/details/72676723


21.okHttp 实现的原理


22.okHttp 有哪些拦截器


23.计算 1+2!+3!+4!+5!+...+20!的结果,用代码实现


24.写出单例模式,哪些是线程安全的,为什么是线程安全的


25.Retrofit 实现原理


26.android 图片有哪些格式


答案:http://blog.csdn.net/xmc281141947/article/details/72768175


27.sqlite 可以执行多线程操作吗?如何保证多线程操作数据库的安全性

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
四年Android面试遇到的问题整理,Android培训那里好