Skip to content

Commit 1859593

Browse files
committed
【更新】阿里字节一套高效的iOS面试题(LRU参考代码实现&&抓包原理细化)
1 parent 14e8b97 commit 1859593

File tree

1 file changed

+95
-6
lines changed

1 file changed

+95
-6
lines changed

interview-iOS/20阿里字节一套高效的iOS面试题2020年2月.md

Lines changed: 95 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1759,12 +1759,94 @@ dispatch_source_cancel(self.disTimer);
17591759
- 替换:当Cache已满时,将新的数据项插到双链表头部,并删除双链表的尾结点即可
17601760
- 查找:每次数据项被查询到时,都将此数据项移动到链表头部
17611761
1762-
> [参考YYCache](https://github.com/ibireme/YYCache)
1763-
1764-
- YYMemoryCache
1762+
- YYCache YYMemoryCache
17651763
- _YYLinkedMapNode
17661764
- _YYLinkedMap
17671765
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+
```
17681850
</details>
17691851
17701852
### 如何设计一个git diff
@@ -2074,9 +2156,16 @@ dispatch_source_cancel(self.disTimer);
20742156
<details>
20752157
<summary> 参考内容 </summary>
20762158
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 自己做加密、解密操作玩罢了。
20802169
20812170
- 4G网络如何抓包
20822171
- iphone安装stream

0 commit comments

Comments
 (0)