1.TCP/IP说一下
- TCP/IP是网络协议的总称,包括了TCP\UDP\IP\HTTP\FTP等协议,大概可以分为4层:链路层,网络层,链路层,网络应用层,TCP\UDP都是传输层中的协议。
- TCP全称传输控制协议,传输形式为数据流,是面向连接的协议,也就是说必须与 对方建立连接才能(参考TCP三次握手四次挥手)
- UDP是用户数据报协议,传输形式为数据报,是不面向连接的。
2.HTTP/HTTPS了解多少
- HTTP是网络协议中的网络应用层,全称超文本传输协议,HTTP协议是B/S架构,浏览器作为HTTP客户端通过URL向web服务器发送请求。
- HTTPS可以理解为HTTP+SSL,通过ssl证书来验证服务器的身份,为浏览器和服务器之间的传输加密。
- http因为是明文传输,所以不太安全。https因为SSL涉及加密算法,所以消耗比http多,加载会变慢。
3.HTTP断点传输
- 在请求头中指明Range参数,一般格式Range:(unit=first byte pos)-[last byte pos]
- 响应头中用Content-Range指示了实体的长度,一般格式:Content-Range: bytes (unit first byte pos) - [last byte pos]/[entity legth]
4.多线程下载大文件
首先我们要知道为什么多线程下载速度会更快?理论进程的实时网速=实时可用网络带宽,但再实际中进程拥有的带宽<=实时可用带宽。
TCP拥有一个流量探测机制,一个TCP连接遇到丢包之后速度会骤减,速度升的却很慢。总结就是单个TCP连接不稳定,需要多线程来弥补,当TCP连接更加智能稳定的时候,多线程就没有优势了。
5.HTTP2.0了解多少
目前大多版本是HTTP1.0(1996年)和1.1(1999年)
HTTP2.0有更好的web性能,更低的TCP延迟
体验一下:https://http2.akamai.com/demo
参考:https://segmentfault.com/a/1190000016656529?utm_source=tag-newest
增加的特点:
- 二进制传输
- 多路复用
- Header压缩
- 服务器Push
- 更安全的SSL
5.OkHttp源码看过吗
okhttp是对socket的封装
主要的一些类:OkhttpClient,Request,Response,Call,Dispatcher
- new OkHttpClient()创建client对象
- 通过Builder设置参数
- new Request().Builder().url().builder()创建request对象
- 通过client.newCall()创建call对象,使用call.excute()进行同步请求,call.enqueue()进行异步请求
线程池和请求队列
这里call是一个接口,具体实现在reallCall类中
Dispatcher类维护okhttp的线程池和队列:
readyAsyncCalls:待访问请求队列,里面存储准备执行的请求。
runningAsyncCalls:异步请求队列,里面存储正在执行,包含已经取消但是还没有结束的请求。
runningSyncCalls:同步请求队列,正在执行的请求,包含已经取消但是还没有结束的请求。
ExecutorService:线程池,最小0,最大Max的线程池
executorServiceOrNull = ThreadPoolExecutor(0, Int.MAX_VALUE, 60, TimeUnit.SECONDS, |
虽然线程池设置为MAX,但在调度器中还有其他设置:
@get:Synchronized var maxRequests = 64 |
意思是最大并发数为64,最多开启64线程。
单个Host最多5个请求。
excute和enqueue
- 同步任务:
调用ReallCall.excute()方法,此方法里面会调用client.dispatcher.executed(this)进入Dispatcher类,并向runningSyncCalls添加这个请求 - 异步任务:
调用ReallCall.enqueue()方法,此方法调用client.dispatcher.enqueue(AsyncCall(responseCallback)),向readyAsyncCalls中添加这个请求。
注意这里this是实现了call接口的对象
AsyncCall()是实现了Runable接口的内联函数,参数responseCallback是CallBack接口,CallBack接口中有两个函数是onFailure,onResponse,这两个函数中的参数还是实现了call接口的对象
ConnectionPool连接池
连接池用来管理socket连接,设置每个地址的连接数最大为5,最长为5分钟。
Okhttp中的设计模式:
单例模式:最好用单例模式创建OkHttpClient,因为每个client对象斗管理自己的线程池、队列,如果每个请求都要创建client对象,那内存就要爆掉了
Builder模式:网络配置需要的属性太多,所以使用了建造者模式(将多个简单的对象构建成一个最终对象 )
策略模式:CacheInterceptor实现了数据的选择策略。CacheInterceptor根据这个策略提供者去选择走网络数据还是本地缓存。
6.TCP-三次握手四次挥手
讲道理这个我也不太清楚,通俗的说法
三次握手:
1)Client:嘿,李四,是我,听到了吗?
2)Server:我听到了,你能听到我的吗?
3)Client:好的,我们互相都能听到对方的话,我们的通信可以开始了。
四次挥手:
1)Client:我所有东西都说完了
2)Server:我已经全部听到了,但是等等我,我还没说完
3)Server:好了,我已经说完了
4)Client:好的,那我们的通信结束
7.Glide原理
//Glide使用方式如下: |
1.Glide的缓存
一种是内存缓存:LruCache,一种是磁盘缓存:DiskLruCache
2.Glide三级缓存
LruCache缓存->弱引用缓存->磁盘缓存
读取一张图片时,先从LruCache缓存读取,找到了就放入WeakReference中,如果没有就去WeakReference中找,还没有就去DiskLruCache、网络请求。
3.Glide加载一个很大的图片到100*100尺寸上,会先压缩再加载吗,放到一个300 * 300的view上会怎样,800 * 800呢,图片会很模糊,怎么处理?
gilde的缓存是根据imageview大小,所以imageview大小改变就会从网络重新加载数据,并以此大小重新缓存。
4.Glide加载的过程中,activity突然关闭会造成内存泄漏吗?
不会!Glide在加载资源的时候,如果在activity、fragment上进行的话,会创建一个透明的requestMangerFragment加入到FragmentManger中,感知生命周期,当activity不可见或者销毁时,Glide会停止加载资源。
5.如何设计一个网络图片加载框架
解析-下载-解码-变换-缓存-显示等操作。
具体一点就是:
- 异步加载:线程池
- 线程切换:handler
- 缓存:Lrucache
- 防止OOM:bitmap压缩,合理存储
- 内存泄漏:注意imageview持有
- 事件处理:点击事件,滑动
6.总结下Glide的优点
- 链式加载,使用简单
- 多种图片格式
- 基于生命周期处理
- 高效的缓存策略
参考:https://juejin.im/post/6844903986412126216
https://juejin.im/post/6844904002551808013