Android面试-熟悉计算机网络、设计模式、JAVA、Kotlin

102 阅读9分钟

网络

应用层,Http

传输层,TCP和UDP,端对端

网络层,IP,路由

链路层,ISO,二进制

TCP

面向连接、可靠、字节流

三次握手,确认连接

数据丢失重传

临时缓存实现。全双工

流量和拥塞控制

头部开销大

    • 源和目的端口
    • seq包序号,解决乱序
    • ack确认,解决不丢包
    • SYN状态位,ACK回复,FIN 结束
    • 窗口大小

UDP

面向无连接,不可靠,数据包

不需要三次握手

宁可丢包,也不卡顿

单播,多播,广播

数据包不分组和排序

头部开销小

    • 源和目的端口
    • 报文长度
    • 报文检验和

URL到浏览器

输入URL获取IP,DNS解析

TCP连接,SSL握手

Socket连接服务器,输出流发送字符串

服务器处理后,返回响应字符串

根据响应头Content-Type,显示或下载

keep-alive保持连接,否则四次挥手

三次握手

  1. 客户端syn包,syn =1,seq = x,进入SYN_SENT
  2. 服务器回复syn+ack包,ack=x +1,syn = 1,seq = Y,进入SYN_RECV
  3. 客户端回复ack包,ack=Y+1 seq = Z,完成

确定双方读写完成

第一次,服务端知道可连,客户端不知道

第二次,客户端确定可连

第三次,服务端确定连接有效,避免回复失效报文

四次挥手

  1. 主动关闭方发送,FIN = 1,seq = X
  2. 被动关闭回复,seq = Z,ack = X+1
  3. 被动关闭方再发送,FIN = 1,seq = Y,ack = X
  4. 主动关闭方回复,seq = X,ack = Y

被动关闭方可能还要发送数据

Http 超文本传输协议

80端口

明文发送数据

Https, 超文本传输安全协议

443端口

客户端验证服务器数字证书

SSL加密

SSL握手

1.ClientHello携带

    1. 一组协议版本
    2. 客户端随机数
    3. 一组加密和压缩方式

2.SeverHello回应

    1. 加密协议版本
    2. 服务器随机数
    3. 确认加密和压缩方式
    4. 服务器证书

3.客户端,验证服务器证书取公钥

    1. 公钥加密随机数,用商定加密方法发送
    2. 客户端握手结束,发送之前内容hash值给服务器,校验
    3. 结束时有三个随机数,用商定加密方法,生成会话密钥

4.服务端,收到第三个随机数,计算会话密钥

    1. 服务器握手结束,发送之前内容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多态)

其他:

  1. 模板方法:各种base
  2. 访问者:AMS访问者,浏览字节码
  3. 解释器模式:LayoutInflater
  4. 迭代器模式:Java iterator
  5. 备忘录:Canvas(save/restore)
  6. 状态:等同策略

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,逆变,下界消费者,只能写