Android知识点总结

1. 四大组件及特点

activity、service、content provider、broadcast receive(广播接收者)
(1)Activity生命周期的方法是成对出现的
onCreate() & onDestory()
onStart() & onStop()
onResume() & onPause()
(2)service是在一段不定的时间运行在后台,不和用户交互应用组件
和多场合的应用中使用,比如播放多媒体的时候用户启动了其他Activity这个时候程序要在后台继续播放
每个Service必须在manifest中通过来声明。可以通过contect.startservice和contect.bindserverice来启动。
Service和其他的应用组件一样,运行在进程的主线程中。这就是说如果service需要很多耗时或者阻塞的操作,需要在其子线程中实现。
(3)Broadcast Receiver
是一个全局的监听器,作用是监听 / 接收 应用 App 发出的广播消息,并 做出响应。
应用场景为
1、Android不同组件间的通信
2、多线程通信
3、与Android系统在特定情况下的通信
(4)ContentProvider(内容提供者)是Android中的四大组件之一。主要用于对外共享数据,也就是通过ContentProvider把应用中的数据共享给其他应用访问,其他应用可以通过ContentProvider对指定应用中的数据进行操作。

2. Activity的四种启动模式

先列出这四种模式:
(1)standard 标准的启动模式,每次启动这个activity的组件的时候, 都会去新创建 activity实例,然后放到任务栈中去。
(2)singleTop 单一栈顶模式,在启动某个具体的activity 的时候, 系统会去检查当前的任务栈中是否处于栈顶的当前的activity的实例,如果是, 那么就不新创建. 如果处于栈顶不是当前的activity的实例,那么仍然会新创建实例。
(3)singleTask 单一任务栈模式,在启动activity的时候, 如果发现当前的任务栈中已经有这个activity的实例了, 那么就不会新创建这个activity的实例了,并且会将处于这个activity 之上的activity的实例给弹栈,如果一个activity的实例创建的过程中,占用的内存比较大, 消耗了挺多资源,那么 这个activity的启动模式通常就会设置成 单一任务栈模式.
例如浏览器使用的是SingTask,浏览器中有js的解析器,CSS的解析器等等,设置成Singtask会节约内存
(4)singleInstance 单一实例模式,如果某个activity的启动模式设置成单一实例模式, 那么整个手机系统中, 就只能有一个这个activity的实例了,并且这个activity的实例会在一个单独的任务栈中.这种启动一般很少用.除了系统级别的一些应用程序会用,其他的应用程序很少用.
如果某个activity 要显示的界面在整个手机中 只有一个 的话,那么 这个activity就会设置成singleInstance

3. 线程的状态

1,新建状态(New):新创建了一个线程对象。
2、**就绪状态(Runnable):**线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于“可运行线程池”中,变得可运行,只等待获取CPU的使用权。即在就绪状态的进程除CPU之外,其它的运行所需资源都已全部获得。
3、运行状态(Running):就绪状态的线程获取了CPU,执行程序代码。
4、阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。
阻塞的情况分三种:
(1)、等待阻塞:运行的线程执行wait()方法,该线程会释放占用的所有资源,JVM会把该线程放入“等待池”中。进入这个状态后,是不能自动唤醒的,必须依靠其他线程调用notify()或notifyAll()方法才能被唤醒,
(2)、同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入“锁池”中。
(3)、其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
5、死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。

4. 链表的反转

5. 安卓系统架构

Android 系统架构共分为五层。应用层,应用框架层,系统运行库层 ,硬件抽象层和Linux内核层

6. http和https的区别

超文本传输协议HTTP协议被用于在Web浏览器和网站服务器之间传递信息,HTTP协议以明文方式发送内容,不提供任何方式的数据加密,如果攻击者截取了Web浏览器和网站服务器之间的传输报文,就可以直接读懂其中的信息,因此,HTTP协议不适合传输一些敏感信息,比如:信用卡号、密码等支付信息。

为了解决HTTP协议的这一缺陷,需要使用另一种协议:安全套接字层超文本传输协议HTTPS,为了数据传输的安全,HTTPS在HTTP的基础上加入了SSL协议,SSL依靠证书来验证服务器的身份,并为浏览器和服务器之间的通信加密。

7. tcp的三次握手

为什么连接的时候是三次握手,关闭的时候却是四次握手
答:因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,“你发的FIN报文我收到了”。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。

8. udp的适用场景:音频·和多媒体

9. mvc和三层架构

MVC和三层架构有什么区别就是MVC是最流行的三层架构中的一种框架,就是模型-视图-控制器三者分离。

MVC模式(Model–view–controller)是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model)、视图(View)和控制器(Controller)

10. 响应码的意思:200,302,404

200 - 确定。客户端请求已成功
302 - 临时移动转移,请求的内容已临时移动新的位置
404 - 未找到文件或目录
500 - 服务器内部错误

11. SpringBoot

其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置.
SpringBoot所具备的特征有
(1)可以创建独立的Spring应用程序,并且基于其Maven或Gradle插件,可以创建可执行的JARs和WARs;
(2)内嵌Tomcat或Jetty等Servlet容器;
(3)提供自动配置的“starter”项目对象模型(POMS)以简化Maven配置;
(4)尽可能自动配置Spring容器;
(5)提供准备好的特性,如指标、健康检查和外部化配置;
(6)绝对没有代码生成,不需要XML配置

12. lua、C#

13. Java中的几种集合的区别及适用场景

list与Set、Map区别及适用场景
文章链接:https://www.cnblogs.com/wangenxian/p/11064652.html

课堂笔记

Binder知识点:

1.多线程使用场景:推送,保活,插件化,内存不够,webview
2.输入,闹钟,电话----跨进程
3.多进程优点:解决安全,内存不够导致OOM问题
4.虚拟机为每个进程分配内存。
5.进程间怎么通信:socket(拷贝两次,依赖上层协议,访问接入点是开放的,不安全),共享内存(不需要拷贝),信号量,管道,文件,信号。
6.安卓里进程通信还有:广播,binder(binder增加的原因:要拷贝一次(只一次是用到了MMAP内存映射),基于c/s(客户端,服务端)架构易用性高,为每个app分配uid同时支持实名和匿名。
7**.binder的使用**:用AIDL(安卓接口定义语言,简化调用Binder的流程)。

  • 1.bindservice系统如何处理—》OnServiceConnected()(系统服务之间有一个servicemanager)
    Client客服端进站口出站口—》proxy
    Service服务端进站口出站口—》stub
    ActivityManagerNative.getDefault()AMS IBinder
    C:App
    S:AMS—ActivityManagerService
  • 2.如何通过binder拿到aidl
  • 3.拿到aidl怎么访问服务端

面试知识点整理

1. Java中的switch是如何支持string的?

java中switch支持String,是利用String的hash值,本质上是switch-int结构。并且利用到了equals方法来防止hash冲突的问题。最后利用switch-byte结构,精确匹配。

2. 请采用至少3种方式实现单例模式。

单例模式定义:设计模式当中比较常见的一个软件设计模式。通过单例模式可以保证系统中,应用该模式的类一个类只有一个实例。即一个类在整个系统当中只有一个对象实例。在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例。多线程的线程池的设计一般也是采用单例模式。
实现方式

  1. 静态内部类
    Android知识点总结_第1张图片

    1. 枚举类实现方式
      Android知识点总结_第2张图片

    2. 饿汉模式
      Android知识点总结_第3张图片

    3. 懒汉模式
      Android知识点总结_第4张图片

    5.双重锁定:Double CheckLock实现单例:DCL也就是双重锁判断机制(由于JVM底层模型原因,偶尔会出问题,不建议使用)。

3. Activity中声明handle的内部类,内存泄漏风险,是为什么,怎么解决

泄漏原因:
handler发送的消息在当前handler的消息队列中,如果此时activity finish掉了,那么消息队列的消息依旧会由handler进行处理,若此时handler声明为内部类(非静态内部类),我们知道内部类天然持有外部类的实例引用,那么就会导致activity无法回收,进而导致activity泄露。
解决方法:

  • 1.使用static 修饰的handler,但是一般会弱引用activity对象,因为要使用activity对象中的成员
  • 2.单独定义handler,同样可以弱引用activity
  • 3.使用内部类的handler,在onDestroy方法中removeCallbacksAndMessages

4. 为了在view可见之后及时获取它的宽高信息,有哪些方法?

在onCreate中获取View宽高的三种方法
view.post()方法:
Android知识点总结_第5张图片

	onWindowFocusChanged()方法:

Android知识点总结_第6张图片

ViewTreeObserver注册OnGlobalLayoutListener接口
Android知识点总结_第7张图片

5. Shared preference有什么优缺点,有什么替代方案?

优点:

  1. 轻量级,以键值对的方式进行存储,使用方便,易于理解。
    2.采用的是 XML 文件形式存储在本地,程序卸载后会也会一并被清除,不会残留信息。
    缺点:
    1.由于是对文件 IO 读取,因此在 IO 上的瓶颈是个大问题。
    2.多线程场景下效率比较低,因为 get 操作的时候,会锁定 SharedPreferencesImpl 里面的对象,互斥其他操作,而当 put、commit() 和 apply() 操作的时候都会锁住 Editor 的对象,这样的情况下,效率会降低。
    3.不支持跨进程通讯。
    4.由于每次都会把整个文件加载到内存中,因此,如果 SharedPreferences 文件过大,或者在其中的键值对是大对象的 json 数据则会占用大量内存,读取较慢是一方面,同时也会引发程序频繁GC,导致的界面卡顿。
    替代:
    MMKV 是基于 mmap 内存映射的移动端通用 key-value 组件,底层序列化/反序列化使用 protobuf 实现,性能高,稳定性强。

6. 简述kotlin的协程与线程差别?

关系
子线程和主线程的频繁切换;使用kotlin协程来实现子线程和主线程的切换;
kotlin协程相较于线程的优势
1.在不使用回调的前提下完成来线程的切换,代码看上亲也是干净整洁很多。
2.因为线程没有上下文,不能控制线程执行完成后应该回到哪里,但是协程完全帮我们实现自动化,执行完毕自动回到上下文线程中,一般情况下是主线程,可以通过设置来决定要回到哪个线程中。
3.协程可以通过suspend关键字来标志耗时操作,通过编译器来帮助我们避免一些性能上的问题。
区别
线程直接链接到相应OS(操作系统)中的本机线程,并消耗大量资源。 特别是,它为堆栈消耗了大量内存。 这就是为什么您不能仅创建100k线程的原因。 您可能会用完内存。 线程之间的切换涉及OS内核调度程序,就消耗的CPU周期而言,这是一项非常昂贵的操作。
另一方面,协程纯粹是用户级别的语言抽象。 它不绑定任何本机资源,在最简单的情况下,它仅在JVM堆中使用一个相对较小的对象。 这就是为什么创建100k协程很容易的原因。 在协程之间切换根本不涉及OS内核。 它可以像调用常规函数一样便宜。

7. 实现app自动更新功能方案?

8. 用类图描述mvc,mvp,mvvm

Android知识点总结_第8张图片
左边部分为MVC, 右边部分为MVP, 下面为MVVM
其中Model 部分(Board) 是不变的,负责数据的处理

1.MVC
V: XML 布局文件充当VIEW 角色 (UI)
C: Activity 充当Controller角色,负责初始化View,也负责View 和Model 之间的通信,持有Model 引用,调用Model处理数据并更新UI.
缺点: 由此看出来,随着需求的变化,Activity的逻辑会越加越多, 变得相当复杂. Model 的耦合性极强 。
2. MVP
针对MVC 的缺点, MVP 做了改进,把与Model 交互的部分 从Activity中抽离出来,放到Presenter处理,即Activity 充当View 了。
同时把针对数据更新后需要进行的View操作,抽象成接口,由Activity 去实现这个接口, Presenter 调用这个接口即可以更新UI 操作。因此, 降低了模块之间的耦合性。
但是还是有个缺点: 在数据(Model) 变化后,还是需要在Activity中进行更新UI 的操作,这块逻辑还是会随着需求的变化越加越臃肿。
3. MVVM
针对MVP 的缺点, MVVM 又做了改进, 使用了ViewModel 代替了Presenter, 并且直接在布局文件中直接根据ViewModel 的变化动态更新UI (通过Databinding 给UI 绑定数据)。 这样子Activity 更新UI的操作,交给了ViewModel 去处理,使得了Activity的功能更加简单(职责单一)。
可见,MVVM 降低各模块的耦合性,但是也有其缺点: 不好调试,以及会造成内存泄漏

9. 针对线上存在内存泄漏,需要收集相关信息进行问题排查,给出方案?

找出问题(GC、CPU、磁盘、内存、网络),定位问题(使用第三方工具分析dump文件等),解决问题。

10. Content,content.context

	Context字面意思上下文,位于framework package的android.content.Context中,

比如说Toast的第一个参数就是Context,一般在Activity中我们直接用this代替,
在android中context可以作很多操作,但是最主要的功能是加载和访问资源。

11. Arrarylist<>

ArrayList和LinkedList,前者是数组队列,相当于动态数组;后者为双向链表结构,也可当作堆栈、队列、双端队列。
当随机访问List时(get和set操作),ArrayList比LinkedList的效率更高,因为LinkedList是线性的数据存储方式,所以需要移动指针从前往后依次查找。
当对数据进行增加和删除的操作时(add和remove操作),LinkedList比ArrayList的效率更高,因为ArrayList是数组,所以在其中进行增删操作时,会对操作点之后所有数据的下标索引造成影响,需要进行数据的移动。

12. Ssm源码

SSM三大框架的运行流程、原理、核心技术:
链接:https://blog.csdn.net/Song_JiangTao/article/details/82252852
(1)Spring部分
Spring的原理:spring是一个容器框架,它可以接管web层,业务层,dao层,持久层的各个组件,并且可以配置各种bean, 并可以维护bean与bean的关系,当我们需要使用某个bean的时候,我们可以直接getBean(id),使用即可
Spring目的:就是让对象与对象(模块与模块)之间的关系没有通过代码来关联,都是通过配置类说明管理的(Spring根据这些配置 内部通过反射去动态的组装对象) ,Spring是一个容器,凡是在容器里的对象才会有Spring所提供的这些服务和功能。
(2)Spring MVC部分
框架执行流程(面试必问)
1、用户发送请求至前端控制器DispatcherServlet
2、DispatcherServlet收到请求调用HandlerMapping处理器映射器。
3、处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。
4、DispatcherServlet通过HandlerAdapter处理器适配器调用处理器
5、执行处理器(Controller,也叫后端控制器)。
6、Controller执行完成返回ModelAndView
7、HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet
8、DispatcherServlet将ModelAndView传给ViewResolver视图解析器
9、ViewResolver解析后返回具体View
10、DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)。
11、DispatcherServlet响应用户
springmvc是spring框架的一个模块,springmvc和spring无需通过中间整合层进行整合。
springmvc是一个基于mvc的web框架。
(3)Mybatis部分
mybatis专注sql本身,需要程序员自己编写sql语句,sql修改、优化比较方便。mybatis是一个不完全 的ORM框架,虽然程序员自己写sql,mybatis 也可以实现映射(输入映射、输出映射)。
mybatis是一个持久层的框架,是apache下的顶级项目。
mybatis托管到goolecode下,后来托管到github下:mybatis Github地址
mybatis让程序将主要精力放在sql上,通过mybatis提供的映射方式,自由灵活生成(半自动化,大部分需要程序员编写sql)满足需要sql语句。
mybatis可以将向 preparedStatement中的输入参数自动进行输入映射,将查询结果集灵活映射成java对象。(输出映射)

13. MySQL事物原理

	事务想要做到的效果可靠性以及并发处理。实现事务功能的三个技术,分别是日志文件(redo log 和 undo log),锁技术以及MVCC。
	MVCC的全称是多版本并发控制。MVCC使得InnoDB的事务隔离级别下执行一致性读操作有了保证。简单说就是为了查询一些正在被另一个事务更新的行,并且可以看到它们被更新之前的值。这是一个用来增强并发性的强大技术,可以使得查询不用等待另一个事务释放锁。

14. AsyncTask(实现多线程,异步通信、消息传递)

	AsyncTask是Android提供的一个助手类,它对Thread和Handler进行了封装,方便我们使用。在Android中我们可以通过Thread+Handler实现多线程通信。
AsyncTask有四个重要的回调方法,分别是:onPreExecute、doInBackground, onProgressUpdate 和 onPostExecute。这四个方法会在AsyncTask的不同时期进行自动调用,我们只需要实现这几个方法的内部逻辑即可。这四个方法的一些参数和返回值都是基于泛型的,而且泛型的类型还不一样,所以在AsyncTask的使用中会遇到三种泛型参数:Params, Progress 和 Result。

Params表示用于AsyncTask执行任务的参数的类型
Progress表示在后台线程处理的过程中,可以阶段性地发布结果的数据类型
Result表示任务全部完成后所返回的数据类型
我们通过调用AsyncTask的execute()方法传入参数并执行任务。
链接:https://www.jianshu.com/p/ee1342fcf5e7

15. Implements,append()

implements实现的意思。在Java中是实现接口时使用implements。
append()方法 相当于"+"。
StringBuffer buf=new StringBuffer("Hard “);
String aString = “Waxworks”;
buf.append(aString,3,4);
说明:这个操作表示aString的索引位置从3开始的找4个字符追加到StringBuffer对象buf中。然后buf对象就会包含字符 串"Hard work”。

16. Json数据解析

链接:https://blog.csdn.net/oman001/article/details/79063278
链接:https://www.jianshu.com/p/6096e6740ac9

17. BaseAdapter

adapter是view和数据的桥梁。在一个ListView或者GridView中,你不可能手动给每一个格子都新建一个view,所以这时候就需要Adapter的帮忙,它会帮你自动绘制view并且填充数据。
BaseAdapter是什么
从英文就可以知道了,最基础的Adapter,也就是说,它可以做所有的事情。所以为什么说最实用最常用,原因就在于它的全能性,不会像ArrayAdapter等的封装好的类有那么多局限性,但是这样的话,使用起来自然会更加麻烦一点。
学会BaseAdapter其实只需要掌握四个方法:getCount, getItem, getItemId, getView。
getCount : 要绑定的条目的数目,比如格子的数量
getItem : 根据一个索引(位置)获得该位置的对象
getItemId : 获取条目的id
getView : 获取该条目要显示的界面
链接:https://www.jianshu.com/p/24833a2cffd1

18. 动态规划

首先递归应该是我们解决动态规划问题最常用的方法,帅,速度不算太慢
那么递归到动规的一般转化方法为:
如果该递归函数有n个参数,那么就定义一个n维数组,数组下标是递归函数参数的取值范围(也就是数组每一维的大小).数组元素的值就是递归函数的返回值(初始化为一个标志值,表明还未被填充),这样就可以从边界值开始逐步的填充数组,相当于计算递归函数的逆过程(这和前面所说的推导过程应该是相同的).
原文链接:https://blog.csdn.net/ailaojie/article/details/83014821

19. OKHttp

android网络框架之OKhttp一个处理网络请求的开源项目,是安卓端最火热的轻量级框架。
功能:get,post请求,文件的上传下载 ,加载图片(内部会图片大小自动压缩) ,请求回调,直接返回对象、对象集合 ,支持session的保持。

你可能感兴趣的:(android)