网络
应用层,Http
传输层,TCP和UDP,端对端
网络层,IP,路由
链路层,ISO,二进制
TCP
面向连接、可靠、字节流
三次握手,确认连接
数据丢失重传
临时缓存实现。全双工
流量和拥塞控制
头部开销大
-
- 源和目的端口
- seq包序号,解决乱序
- ack确认,解决不丢包
- SYN状态位,ACK回复,FIN 结束
- 窗口大小
UDP
面向无连接,不可靠,数据包
不需要三次握手
宁可丢包,也不卡顿
单播,多播,广播
数据包不分组和排序
头部开销小
-
- 源和目的端口
- 报文长度
- 报文检验和
URL到浏览器
输入URL获取IP,DNS解析
TCP连接,SSL握手
Socket连接服务器,输出流发送字符串
服务器处理后,返回响应字符串
根据响应头Content-Type,显示或下载
keep-alive保持连接,否则四次挥手
三次握手
- 客户端syn包,syn =1,seq = x,进入SYN_SENT
- 服务器回复syn+ack包,ack=x +1,syn = 1,seq = Y,进入SYN_RECV
- 客户端回复ack包,ack=Y+1 seq = Z,完成
确定双方读写完成
第一次,服务端知道可连,客户端不知道
第二次,客户端确定可连
第三次,服务端确定连接有效,避免回复失效报文
四次挥手
- 主动关闭方发送,FIN = 1,seq = X
- 被动关闭回复,seq = Z,ack = X+1
- 被动关闭方再发送,FIN = 1,seq = Y,ack = X
- 主动关闭方回复,seq = X,ack = Y
被动关闭方可能还要发送数据
Http , 超文本传输协议
80端口
明文发送数据
Https, 超文本传输安全协议
443端口
客户端验证服务器数字证书
SSL加密
SSL握手
1.ClientHello携带
-
- 一组协议版本
- 客户端随机数
- 一组加密和压缩方式
2.SeverHello回应
-
- 加密协议版本
- 服务器随机数
- 确认加密和压缩方式
- 服务器证书
3.客户端,验证服务器证书取公钥
-
- 公钥加密随机数,用商定加密方法发送
- 客户端握手结束,发送之前内容hash值给服务器,校验
- 结束时有三个随机数,用商定加密方法,生成会话密钥
4.服务端,收到第三个随机数,计算会话密钥
-
-
服务器握手结束,发送之前内容hash值给客户端,校验
-
GET和POST
-
GET只能urlEncode编码,POST多种编码
-
GET参数用URL,POST用body
-
GET有长度限制,POST没有
-
TCP无区别,GET可加body,POST可带url参数,不合规范
强制缓存
第一次请求,服务器在响应头加过期时间(Cache-Control)
客户端再次请求,先计算是否过期,没有用缓存
服务器收到新请求,更新过期时间
协商缓存
强制缓存失效后
判断响应头,资源唯一标识(Etag)
有,请求头带If-None-Match服务器决定
没有,判断响应头,资源最后修改时间Last-Modified
有,请求头带If-Modified-Since服务器决定
200更新资源,304缓存
断点续传
在请求头Rangebytes=x-,服务器返回的文件从第x字节开始
RandomAccessFile的seek方法在指定位置写入数据
HTTP/1.1
- 长连接
- 管道
- 压缩部分Body
缺点:
- 请求 / 响应头,无压缩
- 服务器队头阻塞
- 无优先级
- 只能客户端请求服务器响应
HTTP 2.0
- SSL
- 头部压缩
一样消除重复
HPACK算法生成头信息表
- 二进制格式
- 并发传输
TCP包含Stream
Stream ID客户端奇数,服务器偶数
Stream包含Message
Message包含Frame
不同Stream 帧可乱序发送
- 服务器可推送消息
缺点:
队头阻塞
HTTP 3.0
- QUIC可靠传输UDP
- 无队头阻塞
- 1 RTT完成连接与密钥协商
- 连接ID标记两端,IP变化复用原连接
缺点:
网络设备可丢掉UDP包,普及慢
WebSocket
三次握手后,header头携带
Connection: Upgrade
Upgrade: WebSocket
随机base64 码
服务器支持,响应头带上相同数据
客户端验证通过,WebSocket全双工通讯
设计模式
创建型
如何创建对象
单例
保证一个类仅有一个全局实例
饿汉式,静态属性
懒汉式,静态内部类
DCL双重校验锁,jd8不用volatile,JVM保证new原子性
工厂方法
公共产品接口,子类实现具体产品
公共抽象工厂,子类实现具体工厂,没有是简单工厂
Java实现:
抽象工厂Iterable,子类ArrayList
抽象产品Iterator,子类ArrayList内部类
建造者
一步步创建复杂对象
管理属性,指定顺序解决相互依赖
Android实现:AlertDialog
结构型
根据业务,解耦类或模块,再组合或关联
享元
对象池,解决大量重复对象
Android实现,Meassge.obtin()
代理
不改变原始类接口,定义代理类控制访问
原始类无法更改,外部类继承
原始类可更改,内部类实现统一接口
用于非功能性需求,监控、统计、日志等
Android实现,Retrofit,插件
装饰
不改变原始类接口,增强功能,替代继承
在项目前期设计,代理可用于任何阶段
适配器
后期补救,不兼容接口转兼容接口
类适配器,继承实现
对象适配器,组合实现
Android实现,RecyclerView.Adapter更像桥接
桥接
依赖倒置,接口和实现分离,可独立改变
行为型
类或对象分配职责,粒度比结构型小
观察者
被观察者变化时,通知观察者
被观察者的订阅和通知,放在发布订阅中心
Android实现,事件监听,EventBus
责任链
接收对象沿着链传递请求,直到链上某个对象能处理
Android实现,允许中断事件分发、有序广播、不中断OKhttp
中介者
中介对象,封装对象间交互,通常结合观察者(星状连接图)
策略
封装每个算法,实现可互换
、不同对象,同一行为,有不同的结果(Java多态)
其他:
- 模板方法:各种base
- 访问者:AMS访问者,浏览字节码
- 解释器模式:LayoutInflater
- 迭代器模式:Java iterator
- 备忘录:Canvas(save/restore)
- 状态:等同策略
JAVA
抽象类和接口
抽象类is-a代码复用
接口has-a行为约束
重载和重写
重载,同类同名方法,参数不同
重写,子类重写父类方法
静态和非静态内部类
非静态内部类,持有外部类对象,使用外部类创建
静态内部类只能访问静态成员
方法 参数传递
基本和引用类型都是值传递
equals和==
==基本类型比较值,引用类型地址
equals是Object方法,字符串重写,比较内容
finally一定执行吗
守护线程或System.exit,不执行
try中有return,值存到局部变量表
执行finally块,从局部变量表,取return值返回
try和finally都有return,忽略try
Exception与Error
Throwable可抛出类,子类Error和Exception
Error发生时终止线程的严重错误,发生时终止线程,JVM错误,OOM等
Exception是可处理异常
- 运行时异常,编译时不报错
- 非运行时异常,必须throw到上层或try-catch
Parcelable和Serializable
序列化将对象转换为存储或传输的形式
Serializable是Java序列化标识
对象输出流,写入文件
引用成员,也需实现
不需要的属性transient
版本Id,反序列化时不一致失败
Parcelable是Android序列化接口
支持基本类型和实现Parcelable的引用
Parcel数据载体,写入共享内存
其他进程从共享内存,读反序列化
内存选Parcelable,储存选Serializable
Kotlin
优势
- 扩展函数
- 空安全
- 类型推断
- 数据类:不需要get/set,hashCode、toString和equals
- 协程
属性
var可变,val 常量
get/set重写,使用field,直接用属性名无限递归
默认public,private修饰不生成get/set
kt文件声明,全局属性/函数,编译后加static
类
主构造函数init初始化
次构造函数,默认调用,主构造函数
构造函数,形参加var/val,自动转为成员变量
默认final,可继承open
类中直接写嵌套类,编译后加static final
内部类inner,可访问外部类成员
object,恶汉单例或匿名内部类
Companion object,静态内部类,Java用Companion访问
数据类,主构造函数至少一个参数,只能实现接口
密封类sealed,确保编译时类型安全,子类都继承密封类
内联类inline,数据被内联到用法中,跳过对象实例化
函数
fun 函数名(形参) : 返回类型(Unit可省略,vararg可变参数)
支持作为参数或返回值,::将函数作为实参传递
Lambda
"{}" 包裹内容
"->"连接参数和代码块,无参可省略
最后一行默认return
扩展函数,用类对象组合各种操作
.let判空
.also返回对象本身,链式调用
.apply对象初始化,链式调用
内联函数inline,直接复制被调用方,避免生成对象和压栈出栈
委托
类委托,by 委托类(实现委托的接口)
属性委托,by 基础对象(赋值)
观察属性,by Delegates.observable(值变化后回调)
by map(key字段名/value值)
延迟委托,by lazy
懒加载结果,记录到背域,再调用直接返回
泛型
不确定的数据类型
java
伪泛型,编译时泛型擦除,变成Object
extends T,T或T子类,上界生产者,只能读
写时,因泛型擦除,无法确定子类
super T,T或T父类,下界消费者,只能写
读时,获取到父类不合理
kotlin
不变,具体类型,既是生产又是消费者
out,协变,上界生产者,只能读
in,逆变,下界消费者,只能写