@@ -1759,12 +1759,94 @@ dispatch_source_cancel(self.disTimer);
1759
1759
- 替换:当Cache已满时,将新的数据项插到双链表头部,并删除双链表的尾结点即可
1760
1760
- 查找:每次数据项被查询到时,都将此数据项移动到链表头部
1761
1761
1762
- > [参考YYCache](https://github.com/ibireme/YYCache)
1763
-
1764
- - YYMemoryCache
1762
+ - YYCache YYMemoryCache
1765
1763
- _YYLinkedMapNode
1766
1764
- _YYLinkedMap
1767
1765
1766
+ - LRU 参考代码
1767
+
1768
+ ```
1769
+ type LRUCache struct {
1770
+ size,capacity int
1771
+ cache map[ int] * LinkedNode
1772
+ head,tail * LinkedNode
1773
+ }
1774
+ type LinkedNode struct {
1775
+ key, value int
1776
+ prev, next * LinkedNode
1777
+ }
1778
+
1779
+ func initLinkedNode(key, value int)* LinkedNode {
1780
+ return &LinkedNode {
1781
+ key: key ,
1782
+ value: value ,
1783
+ }
1784
+ }
1785
+
1786
+ func Construct(capacity int)LRUCache {
1787
+ l := LRUCache {
1788
+ size: 0,
1789
+ capacity: capacity ,
1790
+ cache: map [ int] * LinkedNode {},
1791
+ head: initLinkedNode (0,0),
1792
+ tail: initLinkedNode (0,0)
1793
+ }
1794
+ l.head.next = l.tail
1795
+ l.tail.prev = l.head
1796
+ return l
1797
+ }
1798
+
1799
+ func (this * LRUCache)removeNode(node * LinkedNode){
1800
+ node.prev.next = node.next
1801
+ node.next.prev = node.prev
1802
+ }
1803
+
1804
+ func (this * LRUCache)addTohead(node * LinkedNode){
1805
+ node.prev = this.head
1806
+ node.next = this.head.next
1807
+ this.head.next.prev = node
1808
+ this.head.next = node
1809
+ }
1810
+
1811
+ func (this * LRUCache)moveTohead(node * LinkedNode){
1812
+ this.removeNode(node)
1813
+ this.addTohead(node)
1814
+ }
1815
+
1816
+ func (this * LRUCache) Get(ket int)int {
1817
+ if _ ,ok := this.cache[ key] ; !ok {
1818
+ return -1;
1819
+ }
1820
+ node := this.cache[ key]
1821
+ this.moveTohead(node)
1822
+ return node.value
1823
+ }
1824
+
1825
+ func (this * LRUCache) removeTail() * LinkedNode{
1826
+ node := this.tail.prev
1827
+ this.removeNode(node)
1828
+ return node
1829
+ }
1830
+
1831
+ func (this * LRUCache) put(key, value int){
1832
+ if _ ,ok := this.cache[ key] ; !ok{
1833
+ node := initLinkedNode(key,value);
1834
+ this.cache[ key] = node
1835
+ this.addTohead(node)
1836
+ this.size++
1837
+ if this.size > this.capacity {
1838
+ removed := this.removeTail()
1839
+ delete(this.cache, remove.key)
1840
+ this.size--
1841
+ }
1842
+ } else {
1843
+ node := this.cache[ key]
1844
+ node.value = value
1845
+ this.moveTohead(node)
1846
+ }
1847
+ }
1848
+
1849
+ ```
1768
1850
</details>
1769
1851
1770
1852
### 如何设计一个git diff
@@ -2074,9 +2156,16 @@ dispatch_source_cancel(self.disTimer);
2074
2156
<details>
2075
2157
<summary> 参考内容 </summary>
2076
2158
2077
- - 中间人攻击原理
2078
- - 截获真实客户端的HTTPS请求,伪装客户端向真实服务端发送HTTPS请求
2079
- - 接受真实服务器响应,用Charles自己的证书伪装服务端向真实客户端发送数据内容
2159
+ #### 中间人攻击原理
2160
+
2161
+ > 截获真实客户端的HTTPS请求,伪装客户端向真实服务端发送HTTPS请求
2162
+
2163
+ > 接受真实服务器响应,用Charles自己的证书伪装服务端向真实客户端发送数据内容
2164
+
2165
+ - 中间人对于客户端来说就是一个"服务端";而对于服务端则就是"客户端"角色;
2166
+ - 客户端将请求发送给中间人,中间人原封不动的把请求递交给服务端;服务端 response 给中间人,中间人在原封不动地将数据回给客户端,此刻中间人不过是个代理,仅仅只是充当了一个递交、转发的角色;
2167
+ - 对于 HTTP 明文传输,中间人自然可以查看,顺便说一句 DNS 查询时候,自然也是可以截获修改的,TCP/UDP 这种协议无法保证安全性;而对于 HTTPS 中间人就无法查看加密数据,因为客户端和服务端通信时候数据都是加密的(对称加密),密钥协商阶段是非对称加密;
2168
+ - 像 Charles/Fiddler 抓包原理实际上就是客户端要信任它们的证书(这个是自签的根证书,有兴趣可以看下自建CA 为服务器部署https),现在Charles 会为客户端访问的每个域名都用上面的根证书颁发一个证书,当客户端和 Charles 通信时,先 TCP 三次握手建立连接,然后 SSL 四次握手阶段密钥协商,因为 Charles 自签的根证书已经被信任,所以它颁发的那些域名证书自然也是被信任的(有兴趣自己打开 chrome 的证书管理,确实 Charles 根证书在抓包时为每个域名都颁发了一个证书),所以在密钥协商阶段中的证书校验也是 OK 的,客户端和 Charles 实际上也是通信加密了,但是由于对称密钥就是 Charles 和客户端协商得到的,Charles 自己做加密、解密操作玩罢了。
2080
2169
2081
2170
- 4G网络如何抓包
2082
2171
- iphone安装stream
0 commit comments