用户身份认证
认证使用者的身份
密码: 本人知道的字符串信息
动态令牌:仅限本人持有的设备内显示的一次性密码
数字证书: CA
生物认证: 指纹,虹膜
IC卡
HTTP认证
BASIC 认证(基本认证)
DIGEST 认证 (摘要认证)
SSL 客户端认证
FormBase 认证(基于表单的认证)
BASIC认证 – 账号密码向服务器发送req后,服务器会向客户端发送一个authorization验证
用户输入账号密码,账号密码通过BASE64编码成一个字符串放到报文中发送给服务器
如此以来,服务器吧URI发送给客户端
DIGEST认证 – 验证码质询/响应(challenge/response)
一开始一方会发送认证要求给另一方,接着使用另一方那里接受到的质询码计算生成响应码,最后将响应码返回给对方进行认证的方式
SSL客户端认证 – 一坨使用证书 – 产生费用
详细见上一章HTTPS
基于表单认证(大多数) – 邮箱认证这个方法不是在HTTP协议中定义的
安全等级高
总结、浪费我时间,建议直接跳过
HTTPS
HTTP缺点
通信使用明文(不加密),内容可能被窃听
不验证通信方的身份,有可能遭遇伪装
无法证明报文的完整性,有可能遭遇篡改
TCP/IP是可能被窃听的网络,通信内容在所有的通信线路上都有可能遭到窥视(抓包)
加密
通信加密
HTTP没有加密机制,可以通过SSL(Secure Socket Layer,安全套接层)或TLS(Transport Layer Security)安全层传输协议的组合使用
HTTP+SSL=HTTPS
内容加密
报文首部未进行加密处理,报文主体会进行加密处理
为了有效的内容加密,需要客户端和服务器同时具有加密和解密的机制
主要应用在Web服务中
HTTPS = HTTP + 加密 + 认证 + 完整性保护HTTPS不是新协议,只是在HTTP通信接口部分用SSL和TLS协议代替了
相当于多了个中间件
例如原先HTTP直接和TCP通信,而HTTPS是HTTP先和SSL通信,再由SSL与TCP通信
加密加密方法中加密算法是公开的,密钥是保密,由此来保持加密方法的安全性
因此谁有了密钥,谁就能解密
共享密钥加密 ...
HTTP首部字段
HTTP报文首部按类型分为 请求报文和响应首部
报文首部按组成分为 请求/响应首部字段 通用首部字段 实体首部字段
使用首部字段是为了给浏览器和服务器提供报文主体大小,所使用的语言,认证信息等内容
首部字段有HTTP/1.1和非HTTP/1.1的区别,后者主要是为了补充,使用频率高,例如cookie
首部字段结构:
首部字段名 : 字段值
例如: Content-Type : text/html
HTTP通用首部报文
Cache-Control缓存控制
指令
参数
说明
no-cache
无
防止从缓存中获取过期的资源,客户端不接受缓存过的响应,缓存服务器不能对资源进行缓存
no-store
无
一般报文中含有机密信息,规定不能在本地存储请求或响应的任何一部分
max-age = [秒]
必需
指定缓存的期限,要与min-fresh区分,这个是在指定时间内都使用有效的缓存资源,超出指定时间就是过期了
max-stale (= [秒] )
可省略
指定客户端愿意接受过期资源的最长时间,哪怕是m ...
代理,网关,隧道
单台虚拟主机实现多个域名
一个服务器可以搭建多个Web站点,虽然他们的IP地址是一样的,但是却有多个域名,就像你只有一个名字但是有多个绰号一样,通过DNS解析,绰号就会变成本名,可以解析
在发送HTTP请求时,必须在Host首部内完整指定主机名或域名URI
通信数据转化程序
代理 网关 隧道
都是应用程序,也是一个服务器
都是用来转化通信数据的
代理(淘宝代理)
作为服务器和客户端的中间人的角色,可以加快资源转运的速度
客户端发送URL给代理服务器
代理服务器将相同的URL发给服务器
服务器响应发给代理服务器
代理服务器讲响应发给客户端
特点
客户端和服务器都不知道彼此;
代理不改变请求的URI
从客户端到代理服务器,从代理服务器到服务器,它们之间使用的通讯协议相同;
代理服务器解析请求,重新封装后发给服务器;然后对服务器的响应进行解析,经重新封装后发给客户端。
代理有过滤作用,有利于保障网络安全
在发送报文的时候会指明到底时哪个代理经手过,可以有多个代理proxy 1,proxy 2
网关与代理相似,作用就是对两个网络段中的使用不同传输协议的数据进行互相翻译转 ...
反转链表
反转链表给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
示例 1:
12输入:head = [1,2,3,4,5]输出:[5,4,3,2,1]
示例 2:
12输入:head = [1,2]输出:[2,1]
示例 3:
12输入:head = []输出:[]
提示:
链表中节点的数目范围是 [0, 5000]
-5000 <= Node.val <= 5000
进阶:链表可以选用迭代或递归方式完成反转。你能否用两种方法解决这道题?
方法1:双指针12345678910func reverseList(head *ListNode) *ListNode{ pre := &ListNode{} //先定义一个空 cur := head for cur!=nil{ temp := cur.Next cur.Next = pre pre = cur cur = temp }}
思路
(nil)- ...
状态码
分类
状态码 = 三位数字+原因短语
数字的第一位指定了响应类别,后两位没有分类
类别
原因短语
1XX
Informational(信息性状态码)
接受的请求正在处理
2XX
Success(成功状态码)
请求正常处理完毕
3XX
Redirection(重定向状态码)
需要进行附加操作以完成请求
4XX
Client Error(客户端错误状态码)
服务器无法处理请求
5XX
Server Error(服务器错误状态码)
服务器处理请求出错
只要第一个数字对,可以自创状态码
2XX 成功
200 OK正常处理
204 No Content请求处理成功,没有资源返回
206 Partial Content范围请求,是对资源某一部分的请求
3XX 重定向
301 Moved Permanently请求资源URL更改,需要将新的URL重新保存
302 Found资源是临时性质的被移动
303 See Other希望客户端能用GET重定向到另一个URI中,实现效果和302差不多
304 Not Modified资源找到,不符合条件请求 ...
HTTP报文1
报文分为 请求报文和响应报文
报文结构
HTTP报文组成分为 报文首部 和 报文主体 两块,两者用空行(CR+LF)划分,通常不一定要有报文主体
报文首部
空行(CR+LF)
报文主体
请求报文的报文首部组成
请求行
请求首部字段
通用首部字段
实体首部字段
其他
响应报文的报文首部组成
状态行
响应首部字段
通用首部字段
实体首部字段
其他
案例
HTTP/1.1 200 OK 请求行/状态行
Host: hackr.jp 首部字段
User-Agent: Mozilla….. 首部字段
空行(CR+LF)
<htm xmlns=”….”…… 报文主体
编码提升传输速率
编码
报文主体报文主体用于传输请求或响应的实体主体
实体主体实体主体是请求或响应的有效载荷被传输,由实体首部和实体主体组成
通常情况下报文实体等于实体实体
但是如果进行编码后,报文主体传输的实体主体被编译发生变化,因此报文主体这部分 ...
简单的HTTP协议
客户端向服务端发起请求,服务端进行响应,如果响应了,就说明请求执行了
HTTP是不保存状态的协议协议本身不保留之前一切的请求或响应报文的信息
请求报文
GET(方法) /index.htm(URI) HTTP/1.1(协议版本)
Host:hackr.jp (请求字段首部)
name=hehe (内容实体)
响应报文
HTTP/1.1(协议版本) 200(状态码) OK(状态原因短语)
Date: Tue, 10 Jul 2012 03:50:15 GMT (时间)
Content-Length: 362
Content-Type: text/html (首部字段的属性)
(空一行)
。。。。 (实体主体)
方法
GET获取资源
POST传输实体主体
功能与GET很相似,但是主要目的不是获取响应的主体内容
put传输文件
安全性问题,一般需要配合Web引用程序的验证机制
HEAD获得报文首部
用来确认URI的有效性及资源更新的日期时间
DELETE删除文件
与PUT类似,具有安全性问题
需要配合Web应用程 ...
设计链表
今天发了几个小时就看了这么一道题目,深深感受到了链表中的临界思维的恶心之处,和一些我以前有一些误区的地方和之前没学习到的知识点,记录一下,狗屎
题目
你可以选择使用单链表或者双链表,设计并实现自己的链表。我使用的是单链表
单链表中的节点应该具备两个属性:val 和 next 。val 是当前节点的值,next 是指向下一个节点的指针/引用。
如果是双向链表,则还需要属性 prev 以指示链表中的上一个节点。假设链表中的所有节点下标从 0 开始。
实现 MyLinkedList 类:
MyLinkedList() 初始化 MyLinkedList 对象。
int get(int index) 获取链表中下标为 index 的节点的值。如果下标无效,则返回 -1 。
void addAtHead(int val) 将一个值为 val 的节点插入到链表中第一个元素之前。在插入完成后,新节点会成为链表的第一个节点。
void addAtTail(int val) 将一个值为 val 的节点追加到链表中作为链表的最后一个元素。
void addAtIndex(int index, i ...
链表
定义
1234type LinkNode struct{ Val int Next *LinkNode struct}
移除链表元素
给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。
示例 1:
12输入:head = [1,2,6,3,4,5,6], val = 6输出:[1,2,3,4,5]
示例 2:
12输入:head = [], val = 1输出:[]
示例 3:
12输入:head = [7,7,7,7], val = 7输出:[]
我的答案:我是设置了p,q两个指针,一前一后
比较的时候要用后面的指针进行比较,因为删除操作要跳跃一个元素
因为删除元素的地方要分为 头部,中间,尾部三个地方,所以我特地分了三种情况(看了标准答案后发现我是傻逼,因为某个写法跟我很相似,但是能囊括三种情况)
整体代码有冗余,还很长,看一下标准版本的
12345678910111213141516171819202122232425262728293031func remov ...