this.request = request;
}
@Override
public Request request() {
return request;
}
@Override
public Response proceed(Request request) throws IOException {
RealInterceptorChain next = new RealInterceptorChain(interceptors, index + 1, request);
//next传到当前节点,当前节点处理好request后就可以通过next执行proceed方法,将request传递到下一节点
Interceptor interceptor = interceptors.get(index);
Response response = interceptor.intercept(next);
return response;
}
}
拦截器
public class BridgeInterceptor implements Interceptor{
@Override
public Response intercept(Chain chain) throws IOException {
Log.e(“TAG”,“BridgeInterceptor”);
Request request = chain.request();
// 添加一些请求头
request.header(“Connection”,“keep-alive”);
// 做一些其他处理
if(request.requestBody()!=null){
RequestBody requestBody = request.requestBody();
request.header(“Content-Type”,requestBody.getContentType());
request.header(“Content-Length”,Long.toString(requestBody.getContentLength()));
}
Response response = chain.proceed(request);//这里的chain就是传进来的next,next的index已经加1
return response;
}
}
RealCall中excute()方法
protected void execute() {
final Request request = orignalRequest;
try {
List interceptors = new ArrayList<>();
interceptors.add(new BridgeInterceptor());
interceptors.add(new CacheInterceptor());
interceptors.add(new CallServerInterceptor());
Interceptor.Chain chain = new RealInterceptorChain(interceptors,0,orignalRequest);
Response response = chain.proceed(request);
callback.onResponse(RealCall.this,response);
} catch (IOException e) {
callback.onFailure(RealCall.this,e);
}
}
算法
1.反转单链表
=======
class Node{
private int data;
private Node next;
public Node(int data,Node next){
this.data=data;
this.next=next;
}
}
Node node4 = new Node(4, null);
Node node3 = new Node(3, node4);
Node node2 = new Node(2, node3);
Node node1 = new Node(1, node2);
Node pHead = node1;//头结点
这组链表从1到4排序,要求反转后4到1
public static Node reverseList(Node pHead) {
Node pReversedHead = null; //反转过后的单链表存储头结点
Node pNode = pHead; //当前节点
Node pPrev = null; //前一结点
while (pNode != null) {
//1.记录next,下一步:更新当前节点的上一节点和本身。最后移动一位
Node pNext = pNode.next;
if (pNext == null) {
//到了尾节点
pReversedHead = pNode;
}
pNode.next = pPrev;
pPrev = pNode;
pNode = pNext;
}
return pReversedHead;
}
//递归方式反转(node1->node2->node3->node4->node5)
public static ListNode reverseR(Node head){
//空链表和一个结点的链表无需反转
if(head == null || head.next == null){
return head;
}
//递归到node4(head)时回溯时,reverseR(node4.next)直接返回node5
Node res = reverseR(head.next);
//递归回溯时,此时head指向node4,将node4的next(node5)的next指向node4(head)
head.next.next = head;
//将node4.next指向null
head.next = null;
return res;
}
输出
pHead = reverseList(pHead);//反转之后头结点
while (pHead != null) {
System.out.println(pHead.key);
pHead = pHead.next;
}
2.LRU算法(最近最少使用算法)
=================
-
可以在存储不足时移除掉最近最少使用的数据
-
使用哈希链表(LinkedHashMap)把数据按照最后使用时间来排序。最新使用的数据插入(移到)链表最前端
其他
1.Https
=======
-
使用对称密钥:加密和解密使用的是同一个密钥。弊端:最开始的时候怎么将这个对称密钥发送出去呢?如果对称密钥在发送的时候就已经被拦截,那么发送的信息还是会被篡改和窥视
-
使用非对称密钥:双方必须协商一对密钥,一个私钥一个公钥。用私钥加密的数据,只有对应的公钥才能解密,用公钥加密的数据, 只有对应的私钥才能解密。A将自己的公钥发给B,B以后给A发消息时候用公钥加密后发送,A收到消息后用自己的私钥解密。弊端:非对称密钥(RSA)加密和解密速度慢
-
非对称密钥+对称密钥:A将自己的公钥发给B,B用公钥将对称密钥加密发给B,这样双方就安全地传递了对称加密的密钥,既解决了密钥的传递问题, 又解决了RSA速度慢的问题。弊端:第一次传递公钥时有风险
-
数字证书。假如一开始A将自己的公钥发给B时,中间被拦截,拦截者替换成自己的公钥,这样还是会有安全问题。解决办法:数字证书
2.三次握手
======
其实就是指建立一个TCP连接时,需要客户端和服务器总共发送3个包。进行三次握手的主要作用就是为了确认双方的接收能力和发送能力是否正常。
-
第一次握手:客户端发送网络包,服务端收到了。 这样服务端就能得出结论:客户端的发送能力、服务端的接收能力是正常的。
-
第二次握手:服务端发包,客户端收到了。 这样客户端就能得出结论:服务端的接收、发送能力,客户端的接收、发送能力是正常的。不过此时服务器并不能确认客户端的接收能力是否正常。
-
第三次握手:客户端发包,服务端收到了。 这样服务端就能得出结论:客户端的接收、发送能力正常,服务器自己的发送、接收能力也正常。
因此,需要三次握手才能确认双方的接收与发送能力是否正常。
3.OAuth 2.0
===========
用一个短期的令牌(token)允许用户让第三方应用访问他在某一网站上存储的私密的资源,而不需要用户名和密码
app登录成功后服务器返回一个token,下次app就通过这个token来直接登录,token如果过期就需要跳到登录页面重新登录
令牌(token)与密码(password)的作用是一样的,都可以进入系统,但是有三点差异
-
令牌是有时间限制,到期会自动失效。密码一般长期有效,除非用户修改。
-
令牌可以被数据所有者撤销,会立即失效。以上例而言,屋主可以随时取消快递员的令牌。密码一般不允许被他人撤销。